1 /* $OpenBSD: tokeninit.c,v 1.7 2008/07/09 19:58:28 sobrado 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/param.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 <string.h> 47 #include <readpassphrase.h> 48 49 #include "token.h" 50 #include "tokendb.h" 51 52 static char *prompt_for_secret(int, char*); 53 static int parse_secret(int, char *, unsigned char *); 54 55 int 56 main(int argc, char **argv) 57 { 58 unsigned int cmd = TOKEN_INITUSER; 59 int c; 60 int errors = 0; 61 int verbose = 0; 62 int hexformat = 0; 63 int modes = 0; 64 char seed[80]; 65 unsigned char secret[9]; 66 char *optstr; 67 char *p = 0; 68 69 struct rlimit cds; 70 71 (void)signal(SIGQUIT, SIG_IGN); 72 (void)signal(SIGINT, SIG_IGN); 73 (void)setpriority(PRIO_PROCESS, 0, 0); 74 75 openlog(NULL, LOG_ODELAY, LOG_AUTH); 76 77 cds.rlim_cur = 0; 78 cds.rlim_max = 0; 79 if (setrlimit(RLIMIT_CORE, &cds) < 0) 80 syslog(LOG_ERR, "couldn't set core dump size to 0: %m"); 81 82 if (token_init(argv[0]) < 0) { 83 syslog(LOG_ERR, "unknown token type"); 84 errx(1, "unknown token type"); 85 } 86 87 if (tt->options & TOKEN_HEXINIT) 88 optstr = "fhm:sv"; 89 else 90 optstr = "fm:sv"; 91 92 while ((c = getopt(argc, argv, optstr)) != -1) 93 switch (c) { 94 case 'f': /* force initialize existing user account */ 95 cmd |= TOKEN_FORCEINIT; 96 break; 97 98 case 'h': 99 hexformat++; 100 break; 101 102 case 'm': 103 if ((c = token_mode(optarg))) 104 modes |= c; 105 else 106 errx(1, "unknown mode"); 107 break; 108 109 case 's': /* generate seed during initialization */ 110 cmd |= TOKEN_GENSECRET; 111 break; 112 113 case 'v': /* verbose */ 114 verbose++; 115 break; 116 default: 117 fprintf(stderr, 118 "usage: %sinit [-f%ssv] [-m mode] user ...\n", 119 tt->name, (tt->options & TOKEN_HEXINIT) ? "h" : ""); 120 exit(1); 121 } 122 123 if ((modes & ~TOKEN_RIM) == 0) 124 modes |= tt->defmode; 125 126 argc -= optind; 127 argv = &argv[optind]; 128 129 while (argc--) { 130 if (verbose) { 131 printf("Adding %s to %s database\n", *argv, tt->proper); 132 fflush(stdout); 133 } 134 if (!(cmd & TOKEN_GENSECRET)) { 135 p = prompt_for_secret(hexformat, *argv); 136 if (!readpassphrase(p, seed, sizeof(seed), RPP_ECHO_ON) || 137 seed[0] == '\0') { 138 fprintf(stderr, 139 "%sinit: No seed supplied for token.\n", 140 tt->name); 141 exit(1); 142 } 143 memset(secret, 0, sizeof(secret)); 144 if (parse_secret(hexformat, seed, secret)) { 145 fprintf(stderr, 146 "%sinit: Invalid secret entered.\n", 147 tt->name); 148 exit(1); 149 } 150 } 151 switch (tokenuserinit(cmd, *argv, secret, modes)) { 152 case 0: 153 syslog(LOG_INFO, "User %s initialized in %s database", 154 *argv, tt->proper); 155 break; 156 case 1: 157 warnx("%s already exists in %s database!", 158 *argv, tt->proper); 159 syslog(LOG_INFO, "%s already exists in %s database", 160 *argv, tt->proper); 161 errors++; 162 break; 163 case -1: 164 warnx("Error initializing user %s in %s database.", 165 *argv, tt->proper); 166 syslog(LOG_INFO, 167 "Error initializing user %s in %s database: %m", 168 *argv, tt->proper); 169 errors++; 170 } 171 argv++; 172 } 173 exit(errors); 174 } 175 176 /* 177 * Parse the 8 octal numbers or a 16 digit hex string into a token secret 178 */ 179 180 static int 181 parse_secret(int hexformat, char *seed, unsigned char *secret) 182 { 183 int i; 184 unsigned int tmp[8]; 185 186 if (hexformat) { 187 if ((i = sscanf(seed, "%02x %02x %02x %02x %02x %02x %02x %02x", 188 &tmp[0], &tmp[1], &tmp[2], &tmp[3], 189 &tmp[4], &tmp[5], &tmp[6], &tmp[7])) != 8) 190 return (-1); 191 } else { 192 if ((i = sscanf(seed, "%o %o %o %o %o %o %o %o", 193 &tmp[0], &tmp[1], &tmp[2], &tmp[3], 194 &tmp[4], &tmp[5], &tmp[6], &tmp[7])) != 8) 195 return (-1); 196 } 197 for (i=0; i < 8; i++) 198 secret[i] = tmp[i] & 0xff; 199 200 return (0); 201 } 202 203 /* 204 * Prompt user for seed for token 205 */ 206 207 static char * 208 prompt_for_secret(int hexformat, char* username) 209 { 210 static char prompt[1024]; 211 if (hexformat) 212 snprintf(prompt, sizeof prompt, 213 "Enter a 16 digit hexidecimal number " 214 "as a seed for %s\'s token:\n", username); 215 else 216 snprintf(prompt, sizeof prompt, 217 "Enter a series of 8 3-digit octal numbers " 218 "as a seed for %s\'s token:\n", username); 219 return prompt; 220 } 221