Merge from vendor branch PKGSRC:
[netbsd-mini2440.git] / usr.bin / skey / skey.c
blobc0317060519d1b8fc4100d90533c7fda36942055
1 /* $NetBSD: skey.c,v 1.16 2004/01/05 23:23:36 jmmv Exp $ */
3 /*
4 * S/KEY v1.1b (skey.c)
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>
13 * Stand-alone program for computing responses to S/Key challenges.
14 * Takes the iteration count and seed as command line args, prompts
15 * for the user's key, and produces both word and hex format responses.
17 * Usage example:
18 * >skey 88 ka9q2
19 * Enter password:
20 * OMEN US HORN OMIT BACK AHOY
21 * >
24 #include <sys/cdefs.h>
25 #ifndef lint
26 __RCSID("$NetBSD: skey.c,v 1.16 2004/01/05 23:23:36 jmmv Exp $");
27 #endif
29 #include <ctype.h>
30 #include <err.h>
31 #include <fcntl.h>
32 #include <stdio.h>
33 #include <skey.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
38 int main(int, char **);
39 void usage(char *);
41 int
42 main(int argc, char **argv)
44 int n, cnt, i, pass = 0, hexmode = 0;
45 char passwd[SKEY_MAX_PW_LEN+1], key[SKEY_BINKEY_SIZE];
46 char buf[33], *seed, *slash, *t;
48 cnt = 1;
50 while ((i = getopt(argc, argv, "fn:p:t:x")) != -1) {
51 switch (i) {
52 case 'f':
53 /* this option is ignored now */
54 break;
55 case 'n':
56 cnt = atoi(optarg);
57 break;
58 case 'p':
59 if (strlcpy(passwd, optarg, sizeof(passwd)) >=
60 sizeof(passwd))
61 errx(1, "Password too long");
62 pass = 1;
63 break;
64 case 't':
65 if (skey_set_algorithm(optarg) == NULL) {
66 errx(1, "Unknown hash algorithm %s", optarg);
68 break;
69 case 'x':
70 hexmode = 1;
71 break;
72 default:
73 usage(argv[0]);
74 break;
78 /* could be in the form <number>/<seed> */
79 if (argc <= optind + 1) {
80 /* look for / in it */
81 if (argc <= optind)
82 usage(argv[0]);
83 slash = strchr(argv[optind], '/');
84 if (slash == NULL)
85 usage(argv[0]);
86 *slash++ = '\0';
87 seed = slash;
89 if ((n = atoi(argv[optind])) < 0) {
90 fprintf(stderr, "%s not positive\n", argv[optind]);
91 usage(argv[0]);
92 } else if (n > SKEY_MAX_SEQ) {
93 warnx("%d is larger than max (%d)", n, SKEY_MAX_SEQ);
94 usage(argv[0]);
96 } else {
98 if ((n = atoi(argv[optind])) < 0) {
99 fprintf(stderr, "%s not positive\n", argv[optind]);
100 usage(argv[0]);
101 } else if (n > SKEY_MAX_SEQ) {
102 warnx("%d is larger than max (%d)", n, SKEY_MAX_SEQ);
103 usage(argv[0]);
105 seed = argv[++optind];
108 for(t = seed; *t; t++) {
109 if(!isalnum((unsigned char)*t))
110 errx(1, "seed must be alphanumeric");
113 if(!*seed || strlen(seed) > SKEY_MAX_SEED_LEN)
114 errx(1, "seed must be between 1 and %d long", SKEY_MAX_SEED_LEN);
116 /* Get user's secret password */
117 if (!pass) {
118 (void)fputs("Reminder - Do not use this program while "
119 "logged in via telnet or rlogin.\n", stderr);
120 fprintf(stderr, "Enter secret password: ");
121 readpass(passwd, sizeof(passwd));
122 if (passwd[0] == '\0')
123 exit(1);
126 if (strlen(passwd) < SKEY_MIN_PW_LEN)
127 warnx(
128 "password should be at least %d characters long according to RFC2289",
129 SKEY_MIN_PW_LEN);
131 /* Crunch seed and password into starting key */
132 if (keycrunch(key, seed, passwd) != 0)
133 errx(1, "key crunch failed");
135 if (cnt == 1) {
136 while (n-- != 0)
137 f(key);
138 (void)puts(hexmode ? put8(buf, key) : btoe(buf, key));
139 } else {
140 for (i = 0; i <= n - cnt; i++)
141 f(key);
142 for (; i <= n; i++) {
143 (void)printf("%3d: %-29s", i, btoe(buf, key));
144 if (hexmode)
145 (void)printf("\t%s", put8(buf, key));
146 puts("");
147 f(key);
150 exit(0);
153 void
154 usage(char *s)
157 fprintf(stderr,
158 "usage: %s [-n count] [-p password] [-t hash] [-x] sequence# [/] key\n",
160 exit(1);