Annotation of src/usr.bin/lock/lock.c, Revision 1.5
1.5 ! deraadt 1: /* $OpenBSD: lock.c,v 1.4 1996/07/25 01:54:39 deraadt Exp $ */
1.2 deraadt 2: /* $NetBSD: lock.c,v 1.8 1996/05/07 18:32:31 jtc Exp $ */
1.1 deraadt 3:
4: /*
5: * Copyright (c) 1980, 1987, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * This code is derived from software contributed to Berkeley by
9: * Bob Toxen.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the University of
22: * California, Berkeley and its contributors.
23: * 4. Neither the name of the University nor the names of its contributors
24: * may be used to endorse or promote products derived from this software
25: * without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37: * SUCH DAMAGE.
38: */
39:
40: #ifndef lint
41: static char copyright[] =
42: "@(#) Copyright (c) 1980, 1987, 1993\n\
43: The Regents of the University of California. All rights reserved.\n";
44: #endif /* not lint */
45:
46: #ifndef lint
47: #if 0
48: static char sccsid[] = "@(#)lock.c 8.1 (Berkeley) 6/6/93";
49: #endif
1.5 ! deraadt 50: static char rcsid[] = "$OpenBSD: lock.c,v 1.4 1996/07/25 01:54:39 deraadt Exp $";
1.1 deraadt 51: #endif /* not lint */
52:
53: /*
54: * Lock a terminal up until the given key is entered, until the root
55: * password is entered, or the given interval times out.
56: *
57: * Timeout interval is by default TIMEOUT, it can be changed with
58: * an argument of the form -time where time is in minutes
59: */
60:
61: #include <sys/param.h>
62: #include <sys/stat.h>
63: #include <sys/time.h>
64: #include <signal.h>
65:
66: #include <ctype.h>
67: #include <err.h>
68: #include <pwd.h>
69: #include <stdio.h>
1.2 deraadt 70: #include <stdlib.h>
1.1 deraadt 71: #include <string.h>
72: #include <termios.h>
1.2 deraadt 73: #include <unistd.h>
1.1 deraadt 74:
75: #define TIMEOUT 15
76:
77: void quit(), bye(), hi();
78:
79: struct timeval timeout;
80: struct timeval zerotime;
81: struct termios tty, ntty;
82: long nexttime; /* keep the timeout time */
83:
84: /*ARGSUSED*/
85: main(argc, argv)
86: int argc;
87: char **argv;
88: {
89: extern char *optarg;
90: struct passwd *pw;
91: struct timeval timval;
92: struct itimerval ntimer, otimer;
93: struct tm *timp;
94: time_t curtime;
95: int ch, sectimeout, usemine;
96: char *ap, *mypw, *ttynam, *tzn;
97: char hostname[MAXHOSTNAMELEN], s[BUFSIZ], s1[BUFSIZ];
1.2 deraadt 98: char *crypt();
1.1 deraadt 99:
100: sectimeout = TIMEOUT;
101: mypw = NULL;
102: usemine = 0;
103:
104: if (!(pw = getpwuid(getuid())))
105: errx(1, "unknown uid %d.", getuid());
106:
107: while ((ch = getopt(argc, argv, "pt:")) != EOF)
108: switch((char)ch) {
109: case 't':
110: if ((sectimeout = atoi(optarg)) <= 0)
111: errx(1, "illegal timeout value: %s", optarg);
112: break;
113: case 'p':
114: usemine = 1;
115: mypw = strdup(pw->pw_passwd);
116: break;
117: case '?':
118: default:
1.4 deraadt 119: fprintf(stderr, "usage: lock [-p] [-t timeout]\n");
1.1 deraadt 120: exit(1);
121: }
122: timeout.tv_sec = sectimeout * 60;
123:
124: setuid(getuid()); /* discard privs */
125:
126: if (tcgetattr(0, &tty) < 0) /* get information for header */
127: exit(1);
128: gethostname(hostname, sizeof(hostname));
129: if (!(ttynam = ttyname(0)))
130: errx(1, "not a terminal?");
131: if (gettimeofday(&timval, (struct timezone *)NULL))
132: err(1, "gettimeofday");
133: curtime = timval.tv_sec;
134: nexttime = timval.tv_sec + (sectimeout * 60);
135: timp = localtime(&curtime);
136: ap = asctime(timp);
137: tzn = timp->tm_zone;
138:
139: (void)signal(SIGINT, quit);
140: (void)signal(SIGQUIT, quit);
141: ntty = tty; ntty.c_lflag &= ~ECHO;
142: (void)tcsetattr(0, TCSADRAIN, &ntty);
143:
144: if (!mypw) {
145: /* get key and check again */
1.4 deraadt 146: printf("Key: ");
1.1 deraadt 147: if (!fgets(s, sizeof(s), stdin) || *s == '\n')
148: quit();
1.4 deraadt 149: printf("\nAgain: ");
1.1 deraadt 150: /*
151: * Don't need EOF test here, if we get EOF, then s1 != s
152: * and the right things will happen.
153: */
154: (void)fgets(s1, sizeof(s1), stdin);
155: (void)putchar('\n');
156: if (strcmp(s1, s)) {
157: (void)printf("\alock: passwords didn't match.\n");
158: (void)tcsetattr(0, TCSADRAIN, &tty);
159: exit(1);
160: }
1.5 ! deraadt 161: s[0] = '\0';
1.1 deraadt 162: mypw = s1;
163: }
164:
165: /* set signal handlers */
166: (void)signal(SIGINT, hi);
167: (void)signal(SIGQUIT, hi);
168: (void)signal(SIGTSTP, hi);
169: (void)signal(SIGALRM, bye);
170:
171: ntimer.it_interval = zerotime;
172: ntimer.it_value = timeout;
173: setitimer(ITIMER_REAL, &ntimer, &otimer);
174:
175: /* header info */
1.4 deraadt 176: printf("lock: %s on %s. timeout in %d minutes\ntime now is %.20s%s%s",
1.1 deraadt 177: ttynam, hostname, sectimeout, ap, tzn, ap + 19);
178:
179: for (;;) {
1.4 deraadt 180: printf("Key: ");
1.1 deraadt 181: if (!fgets(s, sizeof(s), stdin)) {
182: clearerr(stdin);
183: hi();
184: continue;
185: }
186: if (usemine) {
187: s[strlen(s) - 1] = '\0';
188: #ifdef SKEY
189: if (strcasecmp(s, "s/key") == 0) {
190: if (skey_auth(pw->pw_name))
191: break;
192: }
193: #endif
194: if (!strcmp(mypw, crypt(s, mypw)))
195: break;
196: }
197: else if (!strcmp(s, s1))
198: break;
1.4 deraadt 199: printf("\a\n");
1.1 deraadt 200: if (tcsetattr(0, TCSADRAIN, &ntty) < 0)
201: exit(1);
202: }
203: quit();
204: }
205:
206: #ifdef SKEY
207: /*
208: * We can't use libskey's skey_authenticate() since it
209: * handles signals in a way that's inappropriate
210: * for our needs. Instead we roll our own.
211: */
212: int
1.5 ! deraadt 213: skey_auth(user)
! 214: char *user;
1.1 deraadt 215: {
216: char s[128], *ask, *skey_keyinfo __P((char *name));
217: int ret = 0;
218:
219: if (!skey_haskey(user) && (ask = skey_keyinfo(user))) {
220: printf("\n[%s]\nResponse: ", ask);
221: if (!fgets(s, sizeof(s), stdin) || *s == '\n')
222: clearerr(stdin);
223: else {
224: s[strlen(s) - 1] = '\0';
225: if (skey_passcheck(user, s) != -1)
226: ret = 1;
227: }
228: } else
229: printf("Sorry, you have no s/key.\n");
230: return ret;
231: }
232: #endif
233:
234: void
235: hi()
236: {
237: struct timeval timval;
238:
239: if (!gettimeofday(&timval, (struct timezone *)NULL))
1.4 deraadt 240: printf("lock: type in the unlock key. timeout in %ld:%ld minutes\n",
1.1 deraadt 241: (nexttime - timval.tv_sec) / 60, (nexttime - timval.tv_sec) % 60);
242: }
243:
244: void
245: quit()
246: {
1.4 deraadt 247: putchar('\n');
1.1 deraadt 248: (void)tcsetattr(0, TCSADRAIN, &tty);
249: exit(0);
250: }
251:
252: void
253: bye()
254: {
255: (void)tcsetattr(0, TCSADRAIN, &tty);
1.4 deraadt 256: printf("lock: timeout\n");
1.1 deraadt 257: exit(1);
258: }