Annotation of src/usr.bin/skeyinit/skeyinit.c, Revision 1.6
1.6 ! millert 1: /* $OpenBSD: skeyinit.c,v 1.5 1996/09/28 00:04:44 millert 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>
1.6 ! millert 26: #include <utmp.h>
1.1 deraadt 27: #include <ctype.h>
1.4 millert 28: #include <skey.h>
1.1 deraadt 29:
1.4 millert 30: #ifndef SKEY_MAXSEQ
31: #define SKEY_MAXSEQ 10000
32: #endif
33: #ifndef SKEY_NAMELEN
34: #define SKEY_NAMELEN 4
35: #endif
36: #ifndef SKEY_MIN_PW_LEN
37: #define SKEY_MIN_PW_LEN 4
38: #endif
1.1 deraadt 39:
40: int
41: main(argc, argv)
42: int argc;
43: char *argv[];
44: {
1.4 millert 45: int rval, n, nn, i, l, md=0, defaultsetup=1, zerokey=0, hexmode=0;
1.1 deraadt 46: time_t now;
47: char hostname[MAXHOSTNAMELEN];
48: char seed[18], tmp[80], key[8], defaultseed[17];
49: char passwd[256], passwd2[256], tbuf[27], buf[60];
1.6 ! millert 50: char lastc, me[UT_NAMESIZE], *salt, *p, *pw;
1.1 deraadt 51: struct skey skey;
52: struct passwd *pp;
53: struct tm *tm;
54:
1.4 millert 55: if (geteuid() != 0)
56: errx(1, "must be setuid root.");
57:
58: (void)time(&now);
1.5 millert 59: (void)sprintf(tbuf, "%05ld", (long) (now % 100000));
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: }