1 |
|
|
/* $OpenBSD: tokeninit.c,v 1.13 2017/05/03 09:51:39 mestre Exp $ */ |
2 |
|
|
|
3 |
|
|
/*- |
4 |
|
|
* Copyright (c) 1995 Migration Associates Corp. All Rights Reserved |
5 |
|
|
* |
6 |
|
|
* Redistribution and use in source and binary forms, with or without |
7 |
|
|
* modification, are permitted provided that the following conditions |
8 |
|
|
* are met: |
9 |
|
|
* 1. Redistributions of source code must retain the above copyright |
10 |
|
|
* notice, this list of conditions and the following disclaimer. |
11 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
12 |
|
|
* notice, this list of conditions and the following disclaimer in the |
13 |
|
|
* documentation and/or other materials provided with the distribution. |
14 |
|
|
* 3. All advertising materials mentioning features or use of this software |
15 |
|
|
* must display the following acknowledgement: |
16 |
|
|
* This product includes software developed by Berkeley Software Design, |
17 |
|
|
* Inc. |
18 |
|
|
* 4. The name of Berkeley Software Design, Inc. may not be used to endorse |
19 |
|
|
* or promote products derived from this software without specific prior |
20 |
|
|
* written permission. |
21 |
|
|
* |
22 |
|
|
* THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND |
23 |
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
24 |
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
25 |
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE |
26 |
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
27 |
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
28 |
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
29 |
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
30 |
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
31 |
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
32 |
|
|
* SUCH DAMAGE. |
33 |
|
|
* |
34 |
|
|
* BSDI $From: tokeninit.c,v 1.1 1996/08/26 20:27:28 prb Exp |
35 |
|
|
*/ |
36 |
|
|
|
37 |
|
|
#include <sys/signal.h> |
38 |
|
|
#include <sys/resource.h> |
39 |
|
|
#include <sys/time.h> |
40 |
|
|
|
41 |
|
|
#include <err.h> |
42 |
|
|
#include <stdio.h> |
43 |
|
|
#include <syslog.h> |
44 |
|
|
#include <stdlib.h> |
45 |
|
|
#include <unistd.h> |
46 |
|
|
#include <limits.h> |
47 |
|
|
#include <string.h> |
48 |
|
|
#include <readpassphrase.h> |
49 |
|
|
|
50 |
|
|
#include "token.h" |
51 |
|
|
#include "tokendb.h" |
52 |
|
|
|
53 |
|
|
static char *prompt_for_secret(int, char*); |
54 |
|
|
static int parse_secret(int, char *, unsigned char *); |
55 |
|
|
|
56 |
|
|
int |
57 |
|
|
main(int argc, char **argv) |
58 |
|
|
{ |
59 |
|
|
unsigned int cmd = TOKEN_INITUSER; |
60 |
|
|
int c; |
61 |
|
|
int errors = 0; |
62 |
|
|
int verbose = 0; |
63 |
|
|
int hexformat = 0; |
64 |
|
|
int modes = 0; |
65 |
|
|
char seed[80]; |
66 |
|
|
unsigned char secret[9]; |
67 |
|
|
char *optstr; |
68 |
|
|
char *p = NULL; |
69 |
|
|
|
70 |
|
|
struct rlimit cds; |
71 |
|
|
|
72 |
|
|
(void)signal(SIGQUIT, SIG_IGN); |
73 |
|
|
(void)signal(SIGINT, SIG_IGN); |
74 |
|
|
(void)setpriority(PRIO_PROCESS, 0, 0); |
75 |
|
|
|
76 |
|
|
openlog(NULL, LOG_ODELAY, LOG_AUTH); |
77 |
|
|
|
78 |
|
|
/* |
79 |
|
|
* Make sure we never dump core as we might have a |
80 |
|
|
* valid user shared-secret in memory. |
81 |
|
|
*/ |
82 |
|
|
|
83 |
|
|
cds.rlim_cur = 0; |
84 |
|
|
cds.rlim_max = 0; |
85 |
|
|
if (setrlimit(RLIMIT_CORE, &cds) < 0) |
86 |
|
|
syslog(LOG_ERR, "couldn't set core dump size to 0: %m"); |
87 |
|
|
|
88 |
|
|
if (pledge("stdio rpath wpath cpath fattr flock getpw tty", NULL) == -1) |
89 |
|
|
err(1, "pledge"); |
90 |
|
|
|
91 |
|
|
if (token_init(argv[0]) < 0) { |
92 |
|
|
syslog(LOG_ERR, "unknown token type"); |
93 |
|
|
errx(1, "unknown token type"); |
94 |
|
|
} |
95 |
|
|
|
96 |
|
|
if (tt->options & TOKEN_HEXINIT) |
97 |
|
|
optstr = "fhm:sv"; |
98 |
|
|
else |
99 |
|
|
optstr = "fm:sv"; |
100 |
|
|
|
101 |
|
|
while ((c = getopt(argc, argv, optstr)) != -1) |
102 |
|
|
switch (c) { |
103 |
|
|
case 'f': /* force initialize existing user account */ |
104 |
|
|
cmd |= TOKEN_FORCEINIT; |
105 |
|
|
break; |
106 |
|
|
|
107 |
|
|
case 'h': |
108 |
|
|
hexformat = 1; |
109 |
|
|
break; |
110 |
|
|
|
111 |
|
|
case 'm': |
112 |
|
|
if ((c = token_mode(optarg))) |
113 |
|
|
modes |= c; |
114 |
|
|
else |
115 |
|
|
errx(1, "unknown mode"); |
116 |
|
|
break; |
117 |
|
|
|
118 |
|
|
case 's': /* generate seed during initialization */ |
119 |
|
|
cmd |= TOKEN_GENSECRET; |
120 |
|
|
break; |
121 |
|
|
|
122 |
|
|
case 'v': /* verbose */ |
123 |
|
|
verbose = 1; |
124 |
|
|
break; |
125 |
|
|
default: |
126 |
|
|
fprintf(stderr, |
127 |
|
|
"usage: %sinit [-f%ssv] [-m mode] user ...\n", |
128 |
|
|
tt->name, (tt->options & TOKEN_HEXINIT) ? "h" : ""); |
129 |
|
|
exit(1); |
130 |
|
|
} |
131 |
|
|
|
132 |
|
|
if ((modes & ~TOKEN_RIM) == 0) |
133 |
|
|
modes |= tt->defmode; |
134 |
|
|
|
135 |
|
|
argc -= optind; |
136 |
|
|
argv = &argv[optind]; |
137 |
|
|
|
138 |
|
|
while (argc--) { |
139 |
|
|
if (verbose) { |
140 |
|
|
printf("Adding %s to %s database\n", *argv, tt->proper); |
141 |
|
|
fflush(stdout); |
142 |
|
|
} |
143 |
|
|
if (!(cmd & TOKEN_GENSECRET)) { |
144 |
|
|
p = prompt_for_secret(hexformat, *argv); |
145 |
|
|
if (!readpassphrase(p, seed, sizeof(seed), RPP_ECHO_ON) || |
146 |
|
|
seed[0] == '\0') { |
147 |
|
|
fprintf(stderr, |
148 |
|
|
"%sinit: No seed supplied for token.\n", |
149 |
|
|
tt->name); |
150 |
|
|
exit(1); |
151 |
|
|
} |
152 |
|
|
explicit_bzero(secret, sizeof(secret)); |
153 |
|
|
if (parse_secret(hexformat, seed, secret)) { |
154 |
|
|
fprintf(stderr, |
155 |
|
|
"%sinit: Invalid secret entered.\n", |
156 |
|
|
tt->name); |
157 |
|
|
exit(1); |
158 |
|
|
} |
159 |
|
|
} |
160 |
|
|
switch (tokenuserinit(cmd, *argv, secret, modes)) { |
161 |
|
|
case 0: |
162 |
|
|
syslog(LOG_INFO, "User %s initialized in %s database", |
163 |
|
|
*argv, tt->proper); |
164 |
|
|
break; |
165 |
|
|
case 1: |
166 |
|
|
warnx("%s already exists in %s database!", |
167 |
|
|
*argv, tt->proper); |
168 |
|
|
syslog(LOG_INFO, "%s already exists in %s database", |
169 |
|
|
*argv, tt->proper); |
170 |
|
|
errors++; |
171 |
|
|
break; |
172 |
|
|
case -1: |
173 |
|
|
warnx("Error initializing user %s in %s database.", |
174 |
|
|
*argv, tt->proper); |
175 |
|
|
syslog(LOG_INFO, |
176 |
|
|
"Error initializing user %s in %s database: %m", |
177 |
|
|
*argv, tt->proper); |
178 |
|
|
errors++; |
179 |
|
|
} |
180 |
|
|
argv++; |
181 |
|
|
} |
182 |
|
|
exit(errors); |
183 |
|
|
} |
184 |
|
|
|
185 |
|
|
/* |
186 |
|
|
* Parse the 8 octal numbers or a 16 digit hex string into a token secret |
187 |
|
|
*/ |
188 |
|
|
|
189 |
|
|
static int |
190 |
|
|
parse_secret(int hexformat, char *seed, unsigned char *secret) |
191 |
|
|
{ |
192 |
|
|
int i; |
193 |
|
|
unsigned int tmp[8]; |
194 |
|
|
|
195 |
|
|
if (hexformat) { |
196 |
|
|
if ((i = sscanf(seed, "%02x %02x %02x %02x %02x %02x %02x %02x", |
197 |
|
|
&tmp[0], &tmp[1], &tmp[2], &tmp[3], |
198 |
|
|
&tmp[4], &tmp[5], &tmp[6], &tmp[7])) != 8) |
199 |
|
|
return (-1); |
200 |
|
|
} else { |
201 |
|
|
if ((i = sscanf(seed, "%o %o %o %o %o %o %o %o", |
202 |
|
|
&tmp[0], &tmp[1], &tmp[2], &tmp[3], |
203 |
|
|
&tmp[4], &tmp[5], &tmp[6], &tmp[7])) != 8) |
204 |
|
|
return (-1); |
205 |
|
|
} |
206 |
|
|
for (i=0; i < 8; i++) |
207 |
|
|
secret[i] = tmp[i] & 0xff; |
208 |
|
|
|
209 |
|
|
return (0); |
210 |
|
|
} |
211 |
|
|
|
212 |
|
|
/* |
213 |
|
|
* Prompt user for seed for token |
214 |
|
|
*/ |
215 |
|
|
|
216 |
|
|
static char * |
217 |
|
|
prompt_for_secret(int hexformat, char* username) |
218 |
|
|
{ |
219 |
|
|
static char prompt[1024]; |
220 |
|
|
if (hexformat) |
221 |
|
|
snprintf(prompt, sizeof prompt, |
222 |
|
|
"Enter a 16 digit hexadecimal number " |
223 |
|
|
"as a seed for %s\'s token:\n", username); |
224 |
|
|
else |
225 |
|
|
snprintf(prompt, sizeof prompt, |
226 |
|
|
"Enter a series of 8 3-digit octal numbers " |
227 |
|
|
"as a seed for %s\'s token:\n", username); |
228 |
|
|
return prompt; |
229 |
|
|
} |