version 1.36, 2015/01/04 02:28:26 |
version 1.37, 2015/01/05 14:07:12 |
|
|
extern char *__progname; |
extern char *__progname; |
|
|
void usage(void); |
void usage(void); |
int ideal_rounds(void); |
|
void print_passwd(char *, int, void *); |
|
|
|
#define DO_BLF 0 |
#define DO_BLF 0 |
|
|
|
|
exit(1); |
exit(1); |
} |
} |
|
|
/* |
static void |
* Time how long 8 rounds takes to measure this system's performance. |
print_passwd(char *string, int operation, char *extra) |
* We are aiming for something that takes between 0.25 and 0.5 seconds. |
|
*/ |
|
int |
|
ideal_rounds(void) |
|
{ |
{ |
clock_t before, after; |
|
int r = 8; |
|
char buf[_PASSWORD_LEN]; |
|
int duration; |
|
|
|
strlcpy(buf, bcrypt_gensalt(r), _PASSWORD_LEN); |
|
before = clock(); |
|
crypt("testpassword", buf); |
|
after = clock(); |
|
|
|
duration = after - before; |
|
|
|
/* too quick? slow it down. */ |
|
while (r < 16 && duration <= CLOCKS_PER_SEC / 4) { |
|
r += 1; |
|
duration *= 2; |
|
} |
|
/* too slow? speed it up. */ |
|
while (r > 4 && duration > CLOCKS_PER_SEC / 2) { |
|
r -= 1; |
|
duration /= 2; |
|
} |
|
|
|
return r; |
|
} |
|
|
|
|
|
void |
|
print_passwd(char *string, int operation, void *extra) |
|
{ |
|
char buffer[_PASSWORD_LEN]; |
char buffer[_PASSWORD_LEN]; |
|
const char *pref; |
|
char prefbuf[16]; |
|
|
if (operation == DO_BLF) { |
if (operation == DO_BLF) { |
int rounds = *(int *)extra; |
snprintf(prefbuf, sizeof(prefbuf), "blowfish,%s", extra); |
if (bcrypt_newhash(string, rounds, buffer, sizeof(buffer)) != 0) |
pref = prefbuf; |
errx(1, "bcrypt newhash failed"); |
|
fputs(buffer, stdout); |
|
return; |
|
} else { |
} else { |
login_cap_t *lc; |
login_cap_t *lc; |
const char *pref; |
|
|
|
if ((lc = login_getclass(extra)) == NULL) |
if ((lc = login_getclass(extra)) == NULL) |
errx(1, "unable to get login class `%s'", |
errx(1, "unable to get login class `%s'", |
extra ? (char *)extra : "default"); |
extra ? (char *)extra : "default"); |
pref = login_getcapstr(lc, "localcipher", NULL, NULL); |
pref = login_getcapstr(lc, "localcipher", NULL, NULL); |
if (crypt_newhash(string, pref, buffer, sizeof(buffer)) != 0) |
|
errx(1, "can't generate hash"); |
|
} |
} |
|
if (crypt_newhash(string, pref, buffer, sizeof(buffer)) != 0) |
|
errx(1, "can't generate hash"); |
|
|
fputs(buffer, stdout); |
fputs(buffer, stdout); |
} |
} |
|
|
int operation = -1; |
int operation = -1; |
int prompt = 0; |
int prompt = 0; |
int rounds; |
int rounds; |
void *extra = NULL; /* Store salt or number of rounds */ |
char *extra = NULL; /* Store salt or number of rounds */ |
const char *errstr; |
const char *errstr; |
|
|
while ((opt = getopt(argc, argv, "pb:c:")) != -1) { |
while ((opt = getopt(argc, argv, "pb:c:")) != -1) { |
|
|
if (operation != -1) |
if (operation != -1) |
usage(); |
usage(); |
operation = DO_BLF; |
operation = DO_BLF; |
if (strcmp(optarg, "a") == 0) |
if (strcmp(optarg, "a") != 0) { |
rounds = ideal_rounds(); |
(void)strtonum(optarg, 4, 31, &errstr); |
else { |
|
rounds = strtonum(optarg, 1, INT_MAX, &errstr); |
|
if (errstr != NULL) |
if (errstr != NULL) |
errx(1, "%s: %s", errstr, optarg); |
errx(1, "rounds is %s: %s", errstr, optarg); |
} |
} |
extra = &rounds; |
extra = optarg; |
break; |
break; |
case 'c': /* user login class */ |
case 'c': /* user login class */ |
extra = optarg; |
extra = optarg; |