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*/
main(argc,argv)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
hi()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
quit()184 quit()
185 {
186 (void)putchar('\n');
187 (void)ioctl(0, TIOCSETP, &tty);
188 exit(0);
189 }
190
191 void
bye()192 bye()
193 {
194 (void)ioctl(0, TIOCSETP, &tty);
195 (void)printf("lock: timeout\n");
196 exit(1);
197 }
198