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