diff options
author | Niels Provos <provos@cvs.openbsd.org> | 1997-02-14 23:27:32 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 1997-02-14 23:27:32 +0000 |
commit | bc67c24008245b45280ece1e36e3bed71ecfcaa2 (patch) | |
tree | 2d295c2f5188587731e118a54e6f4be90479b381 /usr.bin/passwd/pwd_gensalt.c | |
parent | 49242de308863aac07db6561a9cafa1e7cdeeec9 (diff) |
include blowfish cipher - free config of which cipher to use
Diffstat (limited to 'usr.bin/passwd/pwd_gensalt.c')
-rw-r--r-- | usr.bin/passwd/pwd_gensalt.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/usr.bin/passwd/pwd_gensalt.c b/usr.bin/passwd/pwd_gensalt.c new file mode 100644 index 00000000000..9f84b47e886 --- /dev/null +++ b/usr.bin/passwd/pwd_gensalt.c @@ -0,0 +1,201 @@ +/* + * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Theo de Raadt. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <string.h> +#include <err.h> +#include <pwd.h> + + +#define NUM_OPTIONS 2 /* Number of hardcoded defaults */ +#define LINE_MAX 100 /* Max. length of one config file */ + +static const char options[NUM_OPTIONS][2][80] = +{ + {"local_cipher", "blowfish,4"}, + {"yp_cipher", "old"} +}; +/* Read lines and removes trailers. */ + +static int +read_line(fp, line, max) + FILE *fp; + char *line; + int max; +{ + char *p, *c; + /* Read one line of config */ + if (fgets(line, max, fp) == 0) + return 0; + if (!(p = strchr(line, '\n'))) { + warnx("line too long"); + return 0; + } + *p = '\0'; + + /* Remove comments */ + if ((p = strchr(line, '#'))) + *p = '\0'; + + /* Remove trailing spaces */ + p = line; + while (isspace(*p)) + p++; + memcpy(line, p, strlen(p) + 1); + + p = line + strlen(line) - 1; + while (isspace(*p)) + p--; + *(p + 1) = '\0'; + return 1; +} + + +static const char * +pwd_default(option) + char *option; +{ + int i; + for (i = 0; i < NUM_OPTIONS; i++) + if (!strcasecmp(options[i][0], option)) + return options[i][1]; + return NULL; +} + +void +pwd_gettype(data, max, key, option) + char *data; + int max; + char *key; + char *option; +{ + FILE *fp; + char line[LINE_MAX]; + static char result[LINE_MAX]; + int defaultw; + int keyw; + int got; + result[0] = '\0'; + if ((fp = fopen(_PATH_PASSWDCONF, "r")) == NULL) { + strncpy(data, pwd_default(option), max - 1); + data[max - 1] = '\0'; + return; + } + defaultw = 0; + keyw = 0; + got = 0; + while (!keyw && (got || read_line(fp, line, LINE_MAX))) { + got = 0; + if (!strcmp("default:", line)) + defaultw = 1; + if (!strncmp(key, line, strlen(key)) && + line[strlen(key)] == ':') + keyw = 1; + + /* Now we found default or specified key */ + if (defaultw || keyw) { + while (read_line(fp, line, LINE_MAX)) { + /* Leaving key field */ + if (strchr(line, ':')) { + got = 1; + break; + } + if (!strncmp(line, option, strlen(option)) && + line[strlen(option)] == '=') { + char *p; + p = line + strlen(option) + 1; + while (isspace(*p)) + p++; + strcpy(result, p); + break; + } + } + if (keyw) + break; + defaultw = 0; + } + } + fclose(fp); + if (!strlen(result)) { + strncpy(data, pwd_default(option), max - 1); + data[max - 1] = '\0'; + return; + } + strncpy(data, result, max - 1); + data[max - 1] = '\0'; +} + +void +pwd_gensalt(salt, max, pwd, type) + char *salt; + int max; + struct passwd *pwd; + char type; +{ + char *bcrypt_gensalt __P((u_int8_t)); + char option[LINE_MAX]; + char *next, *now; + *salt = '\0'; + if (max < 10) + return; + + switch (type) { + case 'y': + pwd_gettype(option, LINE_MAX, pwd->pw_name, "yp_cipher"); + break; + case 'l': + default: + pwd_gettype(option, LINE_MAX, pwd->pw_name, "local_cipher"); + break; + } + + next = option; + now = strsep(&next, ","); + if (!strcmp(now, "old")) { + (void) srandom((int) time((time_t *) NULL)); + to64(&salt[0], random(), 2); + } else + if (!strcmp(now, "newsalt")) { + (void) srandom((int) time((time_t *) NULL)); + salt[0] = _PASSWORD_EFMT1; + to64(&salt[1], (long) (29 * 25), 4); + to64(&salt[5], random(), 4); + } else + if (!strcmp(now, "blowfish")) { + int rounds = atoi(next); + if (rounds < 4) + rounds = 4; + strncpy(salt, bcrypt_gensalt(rounds), max - 1); + salt[max - 1] = 0; + } else { + strcpy(salt, ":"); + warnx("Unkown option %s.", now); + } +} |