version 1.1, 1997/02/14 23:27:29 |
version 1.2, 1997/02/16 20:08:59 |
|
|
* documentation and/or other materials provided with the distribution. |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* must display the following acknowledgement: |
* This product includes software developed by Theo de Raadt. |
* This product includes software developed by Niels Provos. |
* 4. The name of the author may not be used to endorse or promote products |
* 4. The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* derived from this software without specific prior written permission. |
* |
* |
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
*/ |
|
|
|
#include <sys/syslimits.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <string.h> |
#include <string.h> |
#include <err.h> |
#include <err.h> |
#include <pwd.h> |
#include <pwd.h> |
|
#include <util.h> |
|
|
|
void to64( char *, long, int n); |
|
|
#define NUM_OPTIONS 2 /* Number of hardcoded defaults */ |
int |
#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) |
pwd_gensalt(salt, max, pwd, type) |
char *salt; |
char *salt; |
int max; |
int max; |
|
|
char option[LINE_MAX]; |
char option[LINE_MAX]; |
char *next, *now; |
char *next, *now; |
*salt = '\0'; |
*salt = '\0'; |
if (max < 10) |
|
return; |
|
|
|
switch (type) { |
switch (type) { |
case 'y': |
case 'y': |
pwd_gettype(option, LINE_MAX, pwd->pw_name, "yp_cipher"); |
pw_getconf(option, LINE_MAX, pwd->pw_name, "ypcipher"); |
break; |
break; |
case 'l': |
case 'l': |
default: |
default: |
pwd_gettype(option, LINE_MAX, pwd->pw_name, "local_cipher"); |
pw_getconf(option, LINE_MAX, pwd->pw_name, "localcipher"); |
break; |
break; |
} |
} |
|
|
next = option; |
next = option; |
now = strsep(&next, ","); |
now = strsep(&next, ","); |
if (!strcmp(now, "old")) { |
if (!strcmp(now, "old")) { |
|
if( max < 3 ) |
|
return 0; |
(void) srandom((int) time((time_t *) NULL)); |
(void) srandom((int) time((time_t *) NULL)); |
to64(&salt[0], random(), 2); |
to64(&salt[0], random(), 2); |
|
salt[2] = '\0'; |
} else |
} else |
if (!strcmp(now, "newsalt")) { |
if (!strcmp(now, "newsalt")) { |
|
if( max < 10 ) |
|
return 0; |
(void) srandom((int) time((time_t *) NULL)); |
(void) srandom((int) time((time_t *) NULL)); |
salt[0] = _PASSWORD_EFMT1; |
salt[0] = _PASSWORD_EFMT1; |
to64(&salt[1], (long) (29 * 25), 4); |
to64(&salt[1], (long) (29 * 25), 4); |
to64(&salt[5], random(), 4); |
to64(&salt[5], random(), 4); |
|
salt[9] = '\0'; |
} else |
} else |
if (!strcmp(now, "blowfish")) { |
if (!strcmp(now, "blowfish")) { |
int rounds = atoi(next); |
int rounds = atoi(next); |
|
|
strcpy(salt, ":"); |
strcpy(salt, ":"); |
warnx("Unkown option %s.", now); |
warnx("Unkown option %s.", now); |
} |
} |
|
return 1; |
|
} |
|
|
|
static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ |
|
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; |
|
|
|
void to64(s, v, n) |
|
register char *s; |
|
register long v; |
|
register int n; |
|
{ |
|
while (--n >= 0) { |
|
*s++ = itoa64[v&0x3f]; |
|
v >>= 6; |
|
} |
} |
} |