1 /* 2 * Copyright (c) 1980, 1987 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 char copyright[] = 20 "@(#) Copyright (c) 1980, 1987 Regents of the University of California.\n\ 21 All rights reserved.\n"; 22 #endif /* not lint */ 23 24 #ifndef lint 25 static char sccsid[] = "@(#)lock.c 5.7 (Berkeley) 12/05/88"; 26 #endif /* not lint */ 27 28 /* 29 * Lock a terminal up until the given key is entered, until the root 30 * password is entered, or the given interval times out. 31 * 32 * Timeout interval is by default TIMEOUT, it can be changed with 33 * an argument of the form -time where time is in minutes 34 */ 35 36 #include <sys/param.h> 37 #include <sys/stat.h> 38 #include <sys/time.h> 39 #include <sys/signal.h> 40 #include <pwd.h> 41 #include <sgtty.h> 42 #include <stdio.h> 43 #include <ctype.h> 44 45 #define TIMEOUT 15 46 47 int quit(), bye(), hi(); 48 49 struct timeval timeout; 50 struct timeval zerotime; 51 struct sgttyb tty, ntty; 52 long nexttime; /* keep the timeout time */ 53 54 /*ARGSUSED*/ 55 main(argc, argv) 56 int argc; 57 char **argv; 58 { 59 extern char *optarg; 60 extern int optind; 61 struct passwd *root_pwd, *my_pwd; 62 struct timeval timval; 63 struct itimerval ntimer, otimer; 64 struct tm *timp; 65 int ch, sectimeout, use_mine; 66 char *ttynam, *ap, *tzn; 67 char hostname[MAXHOSTNAMELEN], s[BUFSIZ], s1[BUFSIZ]; 68 char *crypt(), *index(), *ttyname(); 69 70 use_mine = 0; 71 sectimeout = TIMEOUT; 72 while ((ch = getopt(argc, argv, "pt:")) != EOF) 73 switch((char)ch) { 74 case 't': 75 if ((sectimeout = atoi(optarg)) <= 0) 76 exit(0); 77 break; 78 case 'p': 79 use_mine = 1; 80 break; 81 case '?': 82 default: 83 fputs("usage: lock [-p] [-t timeout]\n", stderr); 84 exit(1); 85 } 86 timeout.tv_sec = sectimeout * 60; 87 88 /* get information for header */ 89 if (ioctl(0, TIOCGETP, &tty)) 90 exit(1); 91 gethostname(hostname, sizeof(hostname)); 92 if (!(ttynam = ttyname(0))) { 93 puts("lock: not a terminal?"); 94 exit(1); 95 } 96 if (gettimeofday(&timval, (struct timezone *)NULL)) { 97 perror("gettimeofday"); 98 exit(1); 99 } 100 nexttime = timval.tv_sec + (sectimeout * 60); 101 timp = localtime(&timval.tv_sec); 102 ap = asctime(timp); 103 tzn = timp->tm_zone; 104 105 (void)signal(SIGINT, quit); 106 (void)signal(SIGQUIT, quit); 107 ntty = tty; ntty.sg_flags &= ~ECHO; 108 (void)ioctl(0, TIOCSETP, &ntty); 109 110 if (!use_mine) { 111 /* get key and check again */ 112 fputs("Key: ", stdout); 113 if (!gets(s, sizeof(s))) 114 quit(); 115 fputs("\nAgain: ", stdout); 116 /* 117 * Don't need EOF test here, if we get EOF, then s1 != s 118 * and the right things will happen. 119 */ 120 (void)gets(s1, sizeof(s1)); 121 putchar('\n'); 122 if (strcmp(s1, s)) { 123 puts("\07lock: passwords didn't match."); 124 ioctl(0, TIOCSETP, &tty); 125 exit(1); 126 } 127 s[0] = NULL; 128 } 129 130 /* set signal handlers */ 131 (void)signal(SIGINT, hi); 132 (void)signal(SIGQUIT, hi); 133 (void)signal(SIGTSTP, hi); 134 (void)signal(SIGALRM, bye); 135 136 ntimer.it_interval = zerotime; 137 ntimer.it_value = timeout; 138 setitimer(ITIMER_REAL, &ntimer, &otimer); 139 140 /* header info */ 141 printf ("lock: %s on %s. timeout in %d minutes\ntime now is %.20s%s%s", 142 ttynam, hostname, sectimeout, ap, tzn, ap + 19); 143 144 /* wait */ 145 root_pwd = getpwuid(0); 146 if (use_mine) 147 my_pwd = getpwuid(getuid()); 148 for (;;) { 149 fputs("Key: ", stdout); 150 if (!gets(s, sizeof(s))) { 151 clearerr(stdin); 152 hi(); 153 continue; 154 } 155 if (use_mine) { 156 if (!my_pwd || !*my_pwd->pw_passwd || !strcmp(my_pwd->pw_passwd, crypt(s, my_pwd->pw_passwd))) 157 break; 158 } 159 else if (!strcmp(s1, s)) 160 break; 161 if (!root_pwd || !*root_pwd->pw_passwd || !strcmp(root_pwd->pw_passwd, crypt(s, root_pwd->pw_passwd))) 162 break; 163 puts("\07"); 164 if (ioctl(0, TIOCGETP, &ntty)) 165 exit(1); 166 } 167 putchar('\n'); 168 quit(); 169 } 170 171 static 172 hi() 173 { 174 struct timeval timval; 175 176 if (!gettimeofday(&timval, (struct timezone *)NULL)) 177 printf("lock: type in the unlock key. timeout in %ld:%ld minutes\n", 178 (nexttime - timval.tv_sec) / 60, (nexttime - timval.tv_sec) % 60); 179 } 180 181 static 182 quit() 183 { 184 (void)ioctl(0, TIOCSETP, &tty); 185 exit(0); 186 } 187 188 static 189 bye() 190 { 191 (void)ioctl(0, TIOCSETP, &tty); 192 puts("lock: timeout"); 193 exit(1); 194 } 195