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