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