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