Changeset View
Changeset View
Standalone View
Standalone View
head/lib/libcrypt/crypt.c
Show All 40 Lines | |||||
* | * | ||||
* The default algorithm is the last entry in the list (second-to-last | * The default algorithm is the last entry in the list (second-to-last | ||||
* array element since the last is a sentinel). The reason for placing | * array element since the last is a sentinel). The reason for placing | ||||
* the default last rather than first is that DES needs to be at the | * the default last rather than first is that DES needs to be at the | ||||
* bottom for the algorithm guessing logic in crypt(3) to work correctly, | * bottom for the algorithm guessing logic in crypt(3) to work correctly, | ||||
* and it needs to be the default for backward compatibility. | * and it needs to be the default for backward compatibility. | ||||
*/ | */ | ||||
static const struct crypt_format { | static const struct crypt_format { | ||||
const char *const name; | const char *name; | ||||
char *(*const func)(const char *, const char *); | int (*func)(const char *, const char *, char *); | ||||
const char *const magic; | const char *magic; | ||||
} crypt_formats[] = { | } crypt_formats[] = { | ||||
{ "md5", crypt_md5, "$1$" }, | { "md5", crypt_md5, "$1$" }, | ||||
#ifdef HAS_BLOWFISH | #ifdef HAS_BLOWFISH | ||||
{ "blf", crypt_blowfish, "$2" }, | { "blf", crypt_blowfish, "$2" }, | ||||
#endif | #endif | ||||
{ "nth", crypt_nthash, "$3$" }, | { "nth", crypt_nthash, "$3$" }, | ||||
{ "sha256", crypt_sha256, "$5$" }, | { "sha256", crypt_sha256, "$5$" }, | ||||
{ "sha512", crypt_sha512, "$6$" }, | { "sha512", crypt_sha512, "$6$" }, | ||||
Show All 39 Lines | |||||
} | } | ||||
/* | /* | ||||
* Hash the given password with the given salt. If the salt begins with a | * Hash the given password with the given salt. If the salt begins with a | ||||
* magic string (e.g. "$6$" for sha512), the corresponding format is used; | * magic string (e.g. "$6$" for sha512), the corresponding format is used; | ||||
* otherwise, the currently selected format is used. | * otherwise, the currently selected format is used. | ||||
*/ | */ | ||||
char * | char * | ||||
crypt(const char *passwd, const char *salt) | crypt_r(const char *passwd, const char *salt, struct crypt_data *data) | ||||
{ | { | ||||
const struct crypt_format *cf; | const struct crypt_format *cf; | ||||
int (*func)(const char *, const char *, char *); | |||||
#ifdef HAS_DES | #ifdef HAS_DES | ||||
int len; | int len; | ||||
#endif | #endif | ||||
for (cf = crypt_formats; cf->name != NULL; ++cf) | for (cf = crypt_formats; cf->name != NULL; ++cf) | ||||
if (cf->magic != NULL && strstr(salt, cf->magic) == salt) | if (cf->magic != NULL && strstr(salt, cf->magic) == salt) { | ||||
return (cf->func(passwd, salt)); | func = cf->func; | ||||
goto match; | |||||
} | |||||
#ifdef HAS_DES | #ifdef HAS_DES | ||||
len = strlen(salt); | len = strlen(salt); | ||||
if ((len == 13 || len == 2) && strspn(salt, DES_SALT_ALPHABET) == len) | if ((len == 13 || len == 2) && strspn(salt, DES_SALT_ALPHABET) == len) { | ||||
return (crypt_des(passwd, salt)); | func = crypt_des; | ||||
goto match; | |||||
} | |||||
#endif | #endif | ||||
return (crypt_format->func(passwd, salt)); | func = crypt_format->func; | ||||
match: | |||||
if (func(passwd, salt, data->__buf) != 0) | |||||
return (NULL); | |||||
return (data->__buf); | |||||
} | |||||
char * | |||||
crypt(const char *passwd, const char *salt) | |||||
{ | |||||
static struct crypt_data data; | |||||
return (crypt_r(passwd, salt, &data)); | |||||
} | } |