Annotation of src/usr.bin/skeyinit/skeyinit.c, Revision 1.4
1.4 ! millert 1: /* $OpenBSD: skeyinit.c,v 1.3 1996/06/26 05:39:24 deraadt Exp $ */
1.1 deraadt 2: /* $NetBSD: skeyinit.c,v 1.6 1995/06/05 19:50:48 pk Exp $ */
3:
4: /* S/KEY v1.1b (skeyinit.c)
5: *
6: * Authors:
7: * Neil M. Haller <nmh@thumper.bellcore.com>
8: * Philip R. Karn <karn@chicago.qualcomm.com>
9: * John S. Walden <jsw@thumper.bellcore.com>
10: * Scott Chasin <chasin@crimelab.com>
11: *
12: * S/KEY initialization and seed update
13: */
14:
15: #include <sys/param.h>
16: #include <sys/time.h>
17: #include <sys/resource.h>
18:
19: #include <stdio.h>
20: #include <stdlib.h>
21: #include <string.h>
22: #include <err.h>
23: #include <pwd.h>
24: #include <unistd.h>
25: #include <time.h>
26: #include <ctype.h>
1.4 ! millert 27: #include <skey.h>
1.1 deraadt 28:
1.4 ! millert 29: #ifndef SKEY_MAXSEQ
! 30: #define SKEY_MAXSEQ 10000
! 31: #endif
! 32: #ifndef SKEY_NAMELEN
! 33: #define SKEY_NAMELEN 4
! 34: #endif
! 35: #ifndef SKEY_MIN_PW_LEN
! 36: #define SKEY_MIN_PW_LEN 4
! 37: #endif
1.1 deraadt 38:
39: int
40: main(argc, argv)
41: int argc;
42: char *argv[];
43: {
1.4 ! millert 44: int rval, n, nn, i, l, md=0, defaultsetup=1, zerokey=0, hexmode=0;
1.1 deraadt 45: time_t now;
46: char hostname[MAXHOSTNAMELEN];
47: char seed[18], tmp[80], key[8], defaultseed[17];
48: char passwd[256], passwd2[256], tbuf[27], buf[60];
1.4 ! millert 49: char lastc, me[80], *salt, *p, *pw;
1.1 deraadt 50: struct skey skey;
51: struct passwd *pp;
52: struct tm *tm;
53:
1.4 ! millert 54: if (geteuid() != 0)
! 55: errx(1, "must be setuid root.");
! 56:
! 57: (void)time(&now);
1.1 deraadt 58: tm = localtime(&now);
1.4 ! millert 59: (void)strftime(tbuf, sizeof(tbuf), "%M%j", tm);
1.1 deraadt 60:
61: if (gethostname(hostname, sizeof(hostname)) < 0)
62: err(1, "gethostname");
1.4 ! millert 63: (void)strncpy(defaultseed, hostname, sizeof(defaultseed) - 1);
! 64: defaultseed[SKEY_NAMELEN] = '\0';
! 65: (void)strncat(defaultseed, tbuf, sizeof(defaultseed) - 5);
1.1 deraadt 66:
67: if ((pp = getpwuid(getuid())) == NULL)
68: err(1, "no user with uid %d", getuid());
1.4 ! millert 69: (void)strcpy(me, pp->pw_name);
1.1 deraadt 70:
71: if ((pp = getpwnam(me)) == NULL)
72: err(1, "Who are you?");
73:
1.4 ! millert 74: while ((i = getopt(argc, argv, "sxz45")) != EOF) {
! 75: switch (i) {
! 76: case 's':
! 77: defaultsetup = 0;
! 78: break;
! 79: case 'x':
! 80: hexmode = 1;
! 81: break;
! 82: case 'z':
! 83: zerokey = 1;
! 84: break;
! 85: case '4':
! 86: md = 4;
! 87: break;
! 88: case '5':
! 89: md = 5;
! 90: break;
1.2 deraadt 91: }
1.1 deraadt 92: }
1.4 ! millert 93: if (argc - optind > 1) {
! 94: (void)fprintf(stderr,
! 95: "Usage: %s [-s] [-x] [-z] [-4|-5] [user]\n", argv[0]);
! 96: exit(1);
! 97: } else if (argv[optind]) {
! 98: if ((pp = getpwnam(argv[optind])) == NULL)
! 99: err(1, "User unknown");
! 100:
! 101: if (strcmp(pp->pw_name, me) != 0) {
! 102: if (getuid() != 0) {
! 103: /* Only root can change other's passwds */
! 104: errx(1, "Permission denied.");
! 105: }
1.1 deraadt 106: }
107: }
108: salt = pp->pw_passwd;
109:
1.4 ! millert 110: (void)setpriority(PRIO_PROCESS, 0, -4);
1.1 deraadt 111:
112: if (getuid() != 0) {
1.4 ! millert 113: (void)setpriority(PRIO_PROCESS, 0, -4);
1.1 deraadt 114:
115: pw = getpass("Password:");
116: p = crypt(pw, salt);
117:
1.4 ! millert 118: (void)setpriority(PRIO_PROCESS, 0, 0);
1.1 deraadt 119:
1.4 ! millert 120: if (pp && strcmp(p, pp->pw_passwd))
! 121: errx(1, "Password incorrect.");
1.1 deraadt 122: }
1.4 ! millert 123:
1.1 deraadt 124: rval = skeylookup(&skey, pp->pw_name);
125: switch (rval) {
1.4 ! millert 126: case -1:
! 127: err(1, "cannot open database");
! 128: case 0:
! 129: /* comment out user if asked to */
! 130: if (zerokey)
! 131: exit(skeyzero(&skey, pp->pw_name));
! 132:
! 133: (void)printf("[Updating %s]\n", pp->pw_name);
! 134: (void)printf("Old key: %s\n", skey.seed);
! 135:
! 136: /*
! 137: * Lets be nice if they have a skey.seed that
! 138: * ends in 0-8 just add one
! 139: */
! 140: l = strlen(skey.seed);
! 141: if (l > 0) {
! 142: lastc = skey.seed[l - 1];
! 143: if (isdigit(lastc) && lastc != '9') {
! 144: (void)strcpy(defaultseed, skey.seed);
! 145: defaultseed[l - 1] = lastc + 1;
! 146: }
! 147: if (isdigit(lastc) && lastc == '9' && l < 16) {
! 148: (void)strcpy(defaultseed, skey.seed);
! 149: defaultseed[l - 1] = '0';
! 150: defaultseed[l] = '0';
! 151: defaultseed[l + 1] = '\0';
! 152: }
1.1 deraadt 153: }
1.4 ! millert 154: break;
! 155: case 1:
! 156: if (zerokey)
! 157: errx(1, "You have no entry to zero.");
! 158: (void)printf("[Adding %s]\n", pp->pw_name);
! 159: break;
1.1 deraadt 160: }
161: n = 99;
162:
1.4 ! millert 163: /* Set MDX (currently 4 or 5) if given the option */
! 164: if (md)
! 165: skey_set_MDX(md);
! 166:
1.1 deraadt 167: if (!defaultsetup) {
1.4 ! millert 168: (void)printf("You need the 6 english words generated from the \"skey\" command.\n");
1.1 deraadt 169: for (i = 0;; i++) {
170: if (i >= 2)
171: exit(1);
1.4 ! millert 172: (void)printf("Enter sequence count from 1 to %d: ",
! 173: SKEY_MAXSEQ);
! 174: (void)fgets(tmp, sizeof(tmp), stdin);
1.1 deraadt 175: n = atoi(tmp);
1.4 ! millert 176: if (n > 0 && n < SKEY_MAXSEQ)
1.1 deraadt 177: break; /* Valid range */
1.4 ! millert 178: (void)printf("\n Error: Count must be > 0 and < %d\n",
! 179: SKEY_MAXSEQ);
1.1 deraadt 180: }
1.4 ! millert 181:
! 182: (void)printf("Enter new key [default %s]: ", defaultseed);
! 183: (void)fflush(stdout);
! 184: (void)fgets(seed, sizeof(seed), stdin);
1.1 deraadt 185: rip(seed);
186: if (strlen(seed) > 16) {
1.4 ! millert 187: (void)puts("Notice: Seed truncated to 16 characters.");
1.1 deraadt 188: seed[16] = '\0';
189: }
190: if (seed[0] == '\0')
1.4 ! millert 191: (void)strcpy(seed, defaultseed);
1.1 deraadt 192:
193: for (i = 0;; i++) {
194: if (i >= 2)
195: exit(1);
196:
1.4 ! millert 197: (void)printf("s/key %d %s\ns/key access password: ",
! 198: n, seed);
! 199: (void)fgets(tmp, sizeof(tmp), stdin);
1.1 deraadt 200: rip(tmp);
201: backspace(tmp);
202:
203: if (tmp[0] == '?') {
1.4 ! millert 204: (void)puts("Enter 6 English words from secure S/Key calculation.");
1.1 deraadt 205: continue;
1.4 ! millert 206: } else if (tmp[0] == '\0')
1.1 deraadt 207: exit(1);
208: if (etob(key, tmp) == 1 || atob8(key, tmp) == 0)
209: break; /* Valid format */
1.4 ! millert 210: (void)puts("Invalid format - try again with 6 English words.");
1.1 deraadt 211: }
212: } else {
213: /* Get user's secret password */
1.4 ! millert 214: fputs("Reminder - Only use this method if you are directly connected\n or have an encrypted channel. If you are using telnet\n or rlogin, exit with no password and use keyinit -s.\n", stderr);
! 215:
1.1 deraadt 216: for (i = 0;; i++) {
1.4 ! millert 217: if (i > 2)
1.1 deraadt 218: exit(1);
219:
1.4 ! millert 220: (void)fputs("Enter secret password: ", stderr);
1.1 deraadt 221: readpass(passwd, sizeof(passwd));
222: if (passwd[0] == '\0')
223: exit(1);
224:
1.4 ! millert 225: if (strlen(passwd) < SKEY_MIN_PW_LEN) {
! 226: (void)fputs("Your password must be longer.\n",
! 227: stderr);
! 228: continue;
! 229: }
! 230:
! 231: (void)fputs("Again secret password: ", stderr);
1.1 deraadt 232: readpass(passwd2, sizeof(passwd));
233: if (passwd2[0] == '\0')
234: exit(1);
235:
236: if (strcmp(passwd, passwd2) == 0)
237: break;
238:
1.4 ! millert 239: (void)fputs("Passwords do not match.\n", stderr);
1.1 deraadt 240: }
241:
242: /* Crunch seed and password into starting key */
1.4 ! millert 243: (void)strcpy(seed, defaultseed);
1.1 deraadt 244: if (keycrunch(key, seed, passwd) != 0)
245: err(2, "key crunch failed");
1.4 ! millert 246:
1.1 deraadt 247: nn = n;
248: while (nn-- != 0)
249: f(key);
250: }
1.4 ! millert 251: (void)time(&now);
1.1 deraadt 252: tm = localtime(&now);
1.4 ! millert 253: (void)strftime(tbuf, sizeof(tbuf), " %b %d,%Y %T", tm);
1.1 deraadt 254:
1.4 ! millert 255: if ((skey.val = (char *)malloc(16 + 1)) == NULL)
! 256: err(1, "Can't allocate memory");
1.1 deraadt 257:
258: btoa8(skey.val, key);
259:
1.4 ! millert 260: (void)fprintf(skey.keyfile, "%s MD%d %04d %-16s %s %-21s\n",
! 261: pp->pw_name, skey_get_MDX(), n, seed, skey.val, tbuf);
! 262: (void)fclose(skey.keyfile);
! 263: (void)printf("\nID %s s/key is %d %s\n", pp->pw_name, n, seed);
! 264: (void)printf("Next login password: %s\n", hexmode ? put8(buf, key) : btoe(buf, key));
1.1 deraadt 265:
1.4 ! millert 266: exit(0);
1.1 deraadt 267: }