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.10 (Berkeley) 03/26/89"; 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 <sgtty.h> 41 #include <pwd.h> 42 #include <stdio.h> 43 #include <ctype.h> 44 #include <strings.h> 45 46 #define TIMEOUT 15 47 48 int quit(), bye(), hi(); 49 50 struct timeval timeout; 51 struct timeval zerotime; 52 struct sgttyb tty, ntty; 53 long nexttime; /* keep the timeout time */ 54 55 /*ARGSUSED*/ 56 main(argc, argv) 57 int argc; 58 char **argv; 59 { 60 extern char *optarg; 61 extern int errno, optind; 62 struct passwd *pw; 63 struct timeval timval; 64 struct itimerval ntimer, otimer; 65 struct tm *timp; 66 int ch, sectimeout, usemine; 67 char *ap, *mypw, *ttynam, *tzn; 68 char hostname[MAXHOSTNAMELEN], s[BUFSIZ], s1[BUFSIZ]; 69 char *crypt(), *ttyname(); 70 71 sectimeout = TIMEOUT; 72 mypw = NULL; 73 usemine = 0; 74 while ((ch = getopt(argc, argv, "pt:")) != EOF) 75 switch((char)ch) { 76 case 't': 77 if ((sectimeout = atoi(optarg)) <= 0) 78 exit(1); 79 break; 80 case 'p': 81 usemine = 1; 82 if (!(pw = getpwuid(getuid()))) { 83 fprintf(stderr, "lock: unknown uid %d.\n", 84 getuid()); 85 exit(1); 86 } 87 mypw = strdup(pw->pw_passwd); 88 break; 89 case '?': 90 default: 91 fprintf(stderr, "usage: lock [-p] [-t timeout]\n"); 92 exit(1); 93 } 94 timeout.tv_sec = sectimeout * 60; 95 96 setuid(getuid()); /* discard privs */ 97 98 if (ioctl(0, TIOCGETP, &tty)) /* get information for header */ 99 exit(1); 100 gethostname(hostname, sizeof(hostname)); 101 if (!(ttynam = ttyname(0))) { 102 printf("lock: not a terminal?\n"); 103 exit(1); 104 } 105 if (gettimeofday(&timval, (struct timezone *)NULL)) { 106 fprintf(stderr, "lock: gettimeofday: %s\n", strerror(errno)); 107 exit(1); 108 } 109 nexttime = timval.tv_sec + (sectimeout * 60); 110 timp = localtime(&timval.tv_sec); 111 ap = asctime(timp); 112 tzn = timp->tm_zone; 113 114 (void)signal(SIGINT, quit); 115 (void)signal(SIGQUIT, quit); 116 ntty = tty; ntty.sg_flags &= ~ECHO; 117 (void)ioctl(0, TIOCSETP, &ntty); 118 119 if (!mypw) { 120 /* get key and check again */ 121 printf("Key: "); 122 if (!fgets(s, sizeof(s), stdin) || *s == '\n') 123 quit(); 124 printf("\nAgain: "); 125 /* 126 * Don't need EOF test here, if we get EOF, then s1 != s 127 * and the right things will happen. 128 */ 129 (void)fgets(s1, sizeof(s1), stdin); 130 putchar('\n'); 131 if (strcmp(s1, s)) { 132 printf("\07lock: passwords didn't match.\n"); 133 ioctl(0, TIOCSETP, &tty); 134 exit(1); 135 } 136 s[0] = NULL; 137 mypw = s1; 138 } 139 140 /* set signal handlers */ 141 (void)signal(SIGINT, hi); 142 (void)signal(SIGQUIT, hi); 143 (void)signal(SIGTSTP, hi); 144 (void)signal(SIGALRM, bye); 145 146 ntimer.it_interval = zerotime; 147 ntimer.it_value = timeout; 148 setitimer(ITIMER_REAL, &ntimer, &otimer); 149 150 /* header info */ 151 printf ("lock: %s on %s. timeout in %d minutes\ntime now is %.20s%s%s", 152 ttynam, hostname, sectimeout, ap, tzn, ap + 19); 153 154 for (;;) { 155 printf("Key: "); 156 if (!fgets(s, sizeof(s), stdin)) { 157 clearerr(stdin); 158 hi(); 159 continue; 160 } 161 if (usemine) { 162 s[strlen(s) - 1] = '\0'; 163 if (!strcmp(mypw, crypt(s, mypw))) 164 break; 165 } 166 else if (!strcmp(s, s1)) 167 break; 168 printf("\07\n"); 169 if (ioctl(0, TIOCGETP, &ntty)) 170 exit(1); 171 } 172 quit(); 173 } 174 175 static 176 hi() 177 { 178 struct timeval timval; 179 180 if (!gettimeofday(&timval, (struct timezone *)NULL)) 181 printf("lock: type in the unlock key. timeout in %ld:%ld minutes\n", 182 (nexttime - timval.tv_sec) / 60, (nexttime - timval.tv_sec) % 60); 183 } 184 185 static 186 quit() 187 { 188 putchar('\n'); 189 (void)ioctl(0, TIOCSETP, &tty); 190 exit(0); 191 } 192 193 static 194 bye() 195 { 196 (void)ioctl(0, TIOCSETP, &tty); 197 printf("lock: timeout\n"); 198 exit(1); 199 } 200