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