From: Sergey Kitov Date: Mon, 2 Oct 2017 10:25:42 +0000 (+0300) Subject: auth: global rounds parameter replaced with argument to password_generate() X-Git-Tag: 2.3.0.rc1~952 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=605c40c77fc3851cb2845da1c5319e32c791592a;p=thirdparty%2Fdovecot%2Fcore.git auth: global rounds parameter replaced with argument to password_generate() username and rounds parameter moved to a single password_generate_params structure. --- diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c index 6dc2705a23..ea8b68750a 100644 --- a/src/auth/auth-request.c +++ b/src/auth/auth-request.c @@ -535,6 +535,8 @@ static void auth_request_save_cache(struct auth_request *request, struct auth_passdb *passdb = request->passdb; const char *encoded_password; string_t *str; + struct password_generate_params gen_params = {.user = request->user, + .rounds = 0 }; switch (result) { case PASSDB_RESULT_USER_UNKNOWN: @@ -576,9 +578,9 @@ static void auth_request_save_cache(struct auth_request *request, strdup() it so that mech_password doesn't get cleared too early. */ if (!password_generate_encoded(request->mech_password, - request->user, - CACHED_PASSWORD_SCHEME, - &encoded_password)) + &gen_params, + CACHED_PASSWORD_SCHEME, + &encoded_password)) i_unreached(); request->passdb_password = p_strconcat(request->pool, "{"CACHED_PASSWORD_SCHEME"}", @@ -2390,7 +2392,8 @@ void auth_request_proxy_finish_failure(struct auth_request *request) static void log_password_failure(struct auth_request *request, const char *plain_password, const char *crypted_password, - const char *scheme, const char *user, + const char *scheme, + const struct password_generate_params *params, const char *subsystem) { static bool scheme_ok = FALSE; @@ -2404,7 +2407,7 @@ static void log_password_failure(struct auth_request *request, /* perhaps the scheme is wrong - see if we can find a working one */ working_scheme = password_scheme_detect(plain_password, - crypted_password, user); + crypted_password, params); if (working_scheme != NULL) { str_printfa(str, ", try %s scheme instead", working_scheme); @@ -2504,6 +2507,8 @@ int auth_request_password_verify_log(struct auth_request *request, size_t raw_password_size; const char *error; int ret; + struct password_generate_params gen_params = {.user = request->original_username, + .rounds = 0}; if (request->skip_password_check) { /* passdb continue* rule after a successful authentication */ @@ -2538,7 +2543,7 @@ int auth_request_password_verify_log(struct auth_request *request, /* Use original_username since it may be important for some password schemes (eg. digest-md5). Otherwise the username is used only for logging purposes. */ - ret = password_verify(plain_password, request->original_username, + ret = password_verify(plain_password, &gen_params, scheme, raw_password, raw_password_size, &error); if (ret < 0) { const char *password_str = request->set->debug_passwords ? @@ -2553,7 +2558,7 @@ int auth_request_password_verify_log(struct auth_request *request, if (ret <= 0 && request->set->debug_passwords) T_BEGIN { log_password_failure(request, plain_password, crypted_password, scheme, - request->original_username, + &gen_params, subsystem); } T_END; return ret; diff --git a/src/auth/passdb.c b/src/auth/passdb.c index 293dbf68e9..3078bf832b 100644 --- a/src/auth/passdb.c +++ b/src/auth/passdb.c @@ -61,8 +61,9 @@ bool passdb_get_credentials(struct auth_request *auth_request, const unsigned char **credentials_r, size_t *size_r) { const char *wanted_scheme = auth_request->credentials_scheme; - const char *plaintext, *username, *error; + const char *plaintext, *error; int ret; + struct password_generate_params pwd_gen_params; if (auth_request->prefer_plain_credentials && password_scheme_is_alias(input_scheme, "PLAIN")) { @@ -109,19 +110,20 @@ bool passdb_get_credentials(struct auth_request *auth_request, /* we can generate anything out of plaintext passwords */ plaintext = t_strndup(*credentials_r, *size_r); - username = auth_request->original_username; + i_zero(&pwd_gen_params); + pwd_gen_params.user = auth_request->original_username; if (!auth_request->domain_is_realm && - strchr(username, '@') != NULL) { + strchr(pwd_gen_params.user, '@') != NULL) { /* domain must not be used as realm. add the @realm. */ - username = t_strconcat(username, "@", + pwd_gen_params.user = t_strconcat(pwd_gen_params.user, "@", auth_request->realm, NULL); } if (auth_request->set->debug_passwords) { auth_request_log_debug(auth_request, AUTH_SUBSYS_DB, "Generating %s from user '%s', password '%s'", - wanted_scheme, username, plaintext); + wanted_scheme, pwd_gen_params.user, plaintext); } - if (!password_generate(plaintext, username, + if (!password_generate(plaintext, &pwd_gen_params, wanted_scheme, credentials_r, size_r)) { auth_request_log_error(auth_request, AUTH_SUBSYS_DB, "Requested unknown scheme %s", wanted_scheme); diff --git a/src/auth/password-scheme-crypt.c b/src/auth/password-scheme-crypt.c index 1bc2730fc7..4624f9e48c 100644 --- a/src/auth/password-scheme-crypt.c +++ b/src/auth/password-scheme-crypt.c @@ -14,17 +14,8 @@ #define CRYPT_SHA2_ROUNDS_MAX 999999999 #define CRYPT_SHA2_SALT_LEN 16 -unsigned int password_scheme_encryption_rounds = 0; - -void password_set_encryption_rounds(unsigned int rounds) -{ - /* just take the new value. crypt_generate_*() will enforce their - limits. */ - password_scheme_encryption_rounds = rounds; -} - static void -crypt_generate_des(const char *plaintext, const char *user ATTR_UNUSED, +crypt_generate_des(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { #define CRYPT_SALT_LEN 2 @@ -37,11 +28,11 @@ crypt_generate_des(const char *plaintext, const char *user ATTR_UNUSED, } static void -crypt_generate_blowfisch(const char *plaintext, const char *user ATTR_UNUSED, +crypt_generate_blowfisch(const char *plaintext, const struct password_generate_params *params, const unsigned char **raw_password_r, size_t *size_r) { const char *password, *salt, *magic_salt; - unsigned int rounds = password_scheme_encryption_rounds; + unsigned int rounds = params->rounds; if (rounds == 0) rounds = CRYPT_BLF_ROUNDS_DEFAULT; @@ -58,11 +49,11 @@ crypt_generate_blowfisch(const char *plaintext, const char *user ATTR_UNUSED, } static void -crypt_generate_sha256(const char *plaintext, const char *user ATTR_UNUSED, +crypt_generate_sha256(const char *plaintext, const struct password_generate_params *params, const unsigned char **raw_password_r, size_t *size_r) { const char *password, *salt, *magic_salt; - unsigned int rounds = password_scheme_encryption_rounds; + unsigned int rounds = params->rounds; if (rounds == 0) rounds = CRYPT_SHA2_ROUNDS_DEFAULT; @@ -82,11 +73,11 @@ crypt_generate_sha256(const char *plaintext, const char *user ATTR_UNUSED, } static void -crypt_generate_sha512(const char *plaintext, const char *user ATTR_UNUSED, +crypt_generate_sha512(const char *plaintext, const struct password_generate_params *params, const unsigned char **raw_password_r, size_t *size_r) { const char *password, *salt, *magic_salt; - unsigned int rounds = password_scheme_encryption_rounds; + unsigned int rounds = params->rounds; if (rounds == 0) rounds = CRYPT_SHA2_ROUNDS_DEFAULT; diff --git a/src/auth/password-scheme-pbkdf2.c b/src/auth/password-scheme-pbkdf2.c index 098bf2d0e7..e78a5c102c 100644 --- a/src/auth/password-scheme-pbkdf2.c +++ b/src/auth/password-scheme-pbkdf2.c @@ -27,13 +27,13 @@ pbkdf_run(const char *plaintext, const char *salt, rounds, PBKDF2_KEY_SIZE_SHA1, &buf); } -void pbkdf2_generate(const char *plaintext, const char *user ATTR_UNUSED, +void pbkdf2_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { unsigned char key[PBKDF2_KEY_SIZE_SHA1]; const char *salt; string_t *str = t_str_new(64); - unsigned int rounds = password_scheme_encryption_rounds; + unsigned int rounds = params->rounds; if (rounds == 0) rounds = PBKDF2_ROUNDS_DEFAULT; @@ -47,7 +47,7 @@ void pbkdf2_generate(const char *plaintext, const char *user ATTR_UNUSED, *size_r = str_len(str); } -int pbkdf2_verify(const char *plaintext, const char *user ATTR_UNUSED, +int pbkdf2_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r) { diff --git a/src/auth/password-scheme-scram.c b/src/auth/password-scheme-scram.c index b0ec001682..f5aa55ff8b 100644 --- a/src/auth/password-scheme-scram.c +++ b/src/auth/password-scheme-scram.c @@ -90,7 +90,7 @@ int scram_sha1_scheme_parse(const unsigned char *credentials, size_t size, return 0; } -int scram_sha1_verify(const char *plaintext, const char *user ATTR_UNUSED, +int scram_sha1_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r) { @@ -135,7 +135,7 @@ int scram_sha1_verify(const char *plaintext, const char *user ATTR_UNUSED, return ret; } -void scram_sha1_generate(const char *plaintext, const char *user ATTR_UNUSED, +void scram_sha1_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { string_t *str; diff --git a/src/auth/password-scheme.c b/src/auth/password-scheme.c index 3e050287d4..10ca0fbc3a 100644 --- a/src/auth/password-scheme.c +++ b/src/auth/password-scheme.c @@ -62,9 +62,10 @@ password_scheme_lookup(const char *name, enum password_encoding *encoding_r) return scheme; } -int password_verify(const char *plaintext, const char *user, const char *scheme, - const unsigned char *raw_password, size_t size, - const char **error_r) +int password_verify(const char *plaintext, + const struct password_generate_params *params, + const char *scheme, const unsigned char *raw_password, + size_t size, const char **error_r) { const struct password_scheme *s; enum password_encoding encoding; @@ -79,12 +80,12 @@ int password_verify(const char *plaintext, const char *user, const char *scheme, } if (s->password_verify != NULL) { - ret = s->password_verify(plaintext, user, raw_password, size, + ret = s->password_verify(plaintext, params, raw_password, size, error_r); } else { /* generic verification handler: generate the password and compare it to the one in database */ - s->password_generate(plaintext, user, + s->password_generate(plaintext, params, &generated, &generated_size); ret = size != generated_size ? 0 : mem_equals_timing_safe(generated, raw_password, size) ? 1 : 0; @@ -200,7 +201,7 @@ int password_decode(const char *password, const char *scheme, return 1; } -bool password_generate(const char *plaintext, const char *user, +bool password_generate(const char *plaintext, const struct password_generate_params *params, const char *scheme, const unsigned char **raw_password_r, size_t *size_r) { @@ -211,11 +212,11 @@ bool password_generate(const char *plaintext, const char *user, if (s == NULL) return FALSE; - s->password_generate(plaintext, user, raw_password_r, size_r); + s->password_generate(plaintext, params, raw_password_r, size_r); return TRUE; } -bool password_generate_encoded(const char *plaintext, const char *user, +bool password_generate_encoded(const char *plaintext, const struct password_generate_params *params, const char *scheme, const char **password_r) { const struct password_scheme *s; @@ -228,7 +229,7 @@ bool password_generate_encoded(const char *plaintext, const char *user, if (s == NULL) return FALSE; - s->password_generate(plaintext, user, &raw_password, &size); + s->password_generate(plaintext, params, &raw_password, &size); switch (encoding) { case PW_ENCODING_NONE: *password_r = t_strndup(raw_password, size); @@ -281,7 +282,7 @@ bool password_scheme_is_alias(const char *scheme1, const char *scheme2) const char * password_scheme_detect(const char *plain_password, const char *crypted_password, - const char *user) + const struct password_generate_params *params) { struct hash_iterate_context *ctx; const char *key; @@ -297,7 +298,7 @@ password_scheme_detect(const char *plain_password, const char *crypted_password, &error) <= 0) continue; - if (password_verify(plain_password, user, scheme->name, + if (password_verify(plain_password, params, scheme->name, raw_password, raw_password_size, &error) > 0) break; @@ -306,7 +307,7 @@ password_scheme_detect(const char *plain_password, const char *crypted_password, return key; } -int crypt_verify(const char *plaintext, const char *user ATTR_UNUSED, +int crypt_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r) { @@ -329,7 +330,7 @@ int crypt_verify(const char *plaintext, const char *user ATTR_UNUSED, } static int -md5_verify(const char *plaintext, const char *user, +md5_verify(const char *plaintext, const struct password_generate_params *params, const unsigned char *raw_password, size_t size, const char **error_r) { const char *password, *str, *error; @@ -346,13 +347,13 @@ md5_verify(const char *plaintext, const char *user, *error_r = "Not a valid MD5-CRYPT or PLAIN-MD5 password"; return -1; } else { - return password_verify(plaintext, user, "PLAIN-MD5", + return password_verify(plaintext, params, "PLAIN-MD5", md5_password, md5_size, error_r); } } static int -md5_crypt_verify(const char *plaintext, const char *user ATTR_UNUSED, +md5_crypt_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r ATTR_UNUSED) { @@ -364,7 +365,7 @@ md5_crypt_verify(const char *plaintext, const char *user ATTR_UNUSED, } static void -md5_crypt_generate(const char *plaintext, const char *user ATTR_UNUSED, +md5_crypt_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { const char *password; @@ -382,7 +383,7 @@ md5_crypt_generate(const char *plaintext, const char *user ATTR_UNUSED, } static void -sha1_generate(const char *plaintext, const char *user ATTR_UNUSED, +sha1_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { unsigned char *digest; @@ -395,7 +396,7 @@ sha1_generate(const char *plaintext, const char *user ATTR_UNUSED, } static void -sha256_generate(const char *plaintext, const char *user ATTR_UNUSED, +sha256_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { unsigned char *digest; @@ -408,7 +409,7 @@ sha256_generate(const char *plaintext, const char *user ATTR_UNUSED, } static void -sha512_generate(const char *plaintext, const char *user ATTR_UNUSED, +sha512_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { unsigned char *digest; @@ -421,7 +422,7 @@ sha512_generate(const char *plaintext, const char *user ATTR_UNUSED, } static void -ssha_generate(const char *plaintext, const char *user ATTR_UNUSED, +ssha_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { #define SSHA_SALT_LEN 4 @@ -441,7 +442,7 @@ ssha_generate(const char *plaintext, const char *user ATTR_UNUSED, *size_r = SHA1_RESULTLEN + SSHA_SALT_LEN; } -static int ssha_verify(const char *plaintext, const char *user ATTR_UNUSED, +static int ssha_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r) { @@ -462,7 +463,7 @@ static int ssha_verify(const char *plaintext, const char *user ATTR_UNUSED, } static void -ssha256_generate(const char *plaintext, const char *user ATTR_UNUSED, +ssha256_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { #define SSHA256_SALT_LEN 4 @@ -482,7 +483,7 @@ ssha256_generate(const char *plaintext, const char *user ATTR_UNUSED, *size_r = SHA256_RESULTLEN + SSHA256_SALT_LEN; } -static int ssha256_verify(const char *plaintext, const char *user ATTR_UNUSED, +static int ssha256_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r) { @@ -505,7 +506,7 @@ static int ssha256_verify(const char *plaintext, const char *user ATTR_UNUSED, } static void -ssha512_generate(const char *plaintext, const char *user ATTR_UNUSED, +ssha512_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { #define SSHA512_SALT_LEN 4 @@ -525,7 +526,7 @@ ssha512_generate(const char *plaintext, const char *user ATTR_UNUSED, *size_r = SHA512_RESULTLEN + SSHA512_SALT_LEN; } -static int ssha512_verify(const char *plaintext, const char *user ATTR_UNUSED, +static int ssha512_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r) { @@ -548,7 +549,7 @@ static int ssha512_verify(const char *plaintext, const char *user ATTR_UNUSED, } static void -smd5_generate(const char *plaintext, const char *user ATTR_UNUSED, +smd5_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { #define SMD5_SALT_LEN 4 @@ -568,7 +569,7 @@ smd5_generate(const char *plaintext, const char *user ATTR_UNUSED, *size_r = MD5_RESULTLEN + SMD5_SALT_LEN; } -static int smd5_verify(const char *plaintext, const char *user ATTR_UNUSED, +static int smd5_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r) { @@ -589,7 +590,7 @@ static int smd5_verify(const char *plaintext, const char *user ATTR_UNUSED, } static void -plain_generate(const char *plaintext, const char *user ATTR_UNUSED, +plain_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { *raw_password_r = (const unsigned char *)plaintext, @@ -597,7 +598,7 @@ plain_generate(const char *plaintext, const char *user ATTR_UNUSED, } static int -plain_verify(const char *plaintext, const char *user ATTR_UNUSED, +plain_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r ATTR_UNUSED) { @@ -609,7 +610,7 @@ plain_verify(const char *plaintext, const char *user ATTR_UNUSED, } static int -plain_trunc_verify(const char *plaintext, const char *user ATTR_UNUSED, +plain_trunc_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r) { @@ -639,7 +640,7 @@ plain_trunc_verify(const char *plaintext, const char *user ATTR_UNUSED, } static void -cram_md5_generate(const char *plaintext, const char *user ATTR_UNUSED, +cram_md5_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { struct hmac_context ctx; @@ -655,15 +656,17 @@ cram_md5_generate(const char *plaintext, const char *user ATTR_UNUSED, } static void -digest_md5_generate(const char *plaintext, const char *user, +digest_md5_generate(const char *plaintext, const struct password_generate_params *params, const unsigned char **raw_password_r, size_t *size_r) { - const char *realm, *str; + const char *realm, *str, *user; unsigned char *digest; - if (user == NULL) + if (params->user == NULL) i_fatal("digest_md5_generate(): username not given"); + user = params->user; + /* assume user@realm format for username. If user@domain is wanted in the username, allow also user@domain@realm. */ @@ -685,7 +688,7 @@ digest_md5_generate(const char *plaintext, const char *user, } static void -plain_md4_generate(const char *plaintext, const char *user ATTR_UNUSED, +plain_md4_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { unsigned char *digest; @@ -698,7 +701,7 @@ plain_md4_generate(const char *plaintext, const char *user ATTR_UNUSED, } static void -plain_md5_generate(const char *plaintext, const char *user ATTR_UNUSED, +plain_md5_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { unsigned char *digest; @@ -711,7 +714,7 @@ plain_md5_generate(const char *plaintext, const char *user ATTR_UNUSED, } static void -lm_generate(const char *plaintext, const char *user ATTR_UNUSED, +lm_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { unsigned char *digest; @@ -724,7 +727,7 @@ lm_generate(const char *plaintext, const char *user ATTR_UNUSED, } static void -ntlm_generate(const char *plaintext, const char *user ATTR_UNUSED, +ntlm_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { unsigned char *digest; @@ -736,7 +739,7 @@ ntlm_generate(const char *plaintext, const char *user ATTR_UNUSED, *size_r = NTLMSSP_HASH_SIZE; } -static int otp_verify(const char *plaintext, const char *user ATTR_UNUSED, +static int otp_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r) { @@ -752,7 +755,7 @@ static int otp_verify(const char *plaintext, const char *user ATTR_UNUSED, } static void -otp_generate(const char *plaintext, const char *user ATTR_UNUSED, +otp_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { const char *password; @@ -764,7 +767,7 @@ otp_generate(const char *plaintext, const char *user ATTR_UNUSED, } static void -skey_generate(const char *plaintext, const char *user ATTR_UNUSED, +skey_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { const char *password; @@ -776,7 +779,7 @@ skey_generate(const char *plaintext, const char *user ATTR_UNUSED, } static void -rpa_generate(const char *plaintext, const char *user ATTR_UNUSED, +rpa_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r) { unsigned char *digest; diff --git a/src/auth/password-scheme.h b/src/auth/password-scheme.h index 0f1a8cc485..6c94dd6d0d 100644 --- a/src/auth/password-scheme.h +++ b/src/auth/password-scheme.h @@ -7,6 +7,11 @@ enum password_encoding { PW_ENCODING_HEX }; +struct password_generate_params { + const char *user; + unsigned int rounds; +}; + struct password_scheme { const char *name; enum password_encoding default_encoding; @@ -15,10 +20,10 @@ struct password_scheme { hex and base64 encoded passwords. */ unsigned int raw_password_len; - int (*password_verify)(const char *plaintext, const char *user, + int (*password_verify)(const char *plaintext, const struct password_generate_params *params, const unsigned char *raw_password, size_t size, const char **error_r); - void (*password_generate)(const char *plaintext, const char *user, + void (*password_generate)(const char *plaintext, const struct password_generate_params *params, const unsigned char **raw_password_r, size_t *size_r); }; @@ -29,8 +34,8 @@ extern unsigned int password_scheme_encryption_rounds; /* Returns 1 = matched, 0 = didn't match, -1 = unknown scheme or invalid raw_password */ -int password_verify(const char *plaintext, const char *user, const char *scheme, - const unsigned char *raw_password, size_t size, +int password_verify(const char *plaintext, const struct password_generate_params *params, + const char *scheme, const unsigned char *raw_password, size_t size, const char **error_r); /* Extracts scheme from password, or returns NULL if it isn't found. @@ -46,13 +51,13 @@ int password_decode(const char *password, const char *scheme, /* Create password with wanted scheme out of plaintext password and username. Potential base64/hex directives are ignored in scheme. Returns FALSE if the scheme is unknown. */ -bool password_generate(const char *plaintext, const char *user, +bool password_generate(const char *plaintext, const struct password_generate_params *params, const char *scheme, const unsigned char **raw_password_r, size_t *size_r); /* Like above, but generate encoded passwords. If hex/base64 directive isn't specified in the scheme, the default encoding for the scheme is used. Returns FALSE if the scheme is unknown. */ -bool password_generate_encoded(const char *plaintext, const char *user, +bool password_generate_encoded(const char *plaintext, const struct password_generate_params *params, const char *scheme, const char **password_r); /* Returns TRUE if schemes are equivalent. */ @@ -62,7 +67,7 @@ bool password_scheme_is_alias(const char *scheme1, const char *scheme2); or NULL if nothing was found. */ const char * password_scheme_detect(const char *plain_password, const char *crypted_password, - const char *user); + const struct password_generate_params *params); void password_scheme_register(const struct password_scheme *scheme); void password_scheme_unregister(const struct password_scheme *scheme); @@ -82,7 +87,7 @@ int password_generate_otp(const char *pw, const char *state_data, ATTR_NULL(2); void password_generate_rpa(const char *pw, unsigned char result[]); -int crypt_verify(const char *plaintext, const char *user, +int crypt_verify(const char *plaintext, const struct password_generate_params *params, const unsigned char *raw_password, size_t size, const char **error_r); @@ -90,14 +95,14 @@ int scram_sha1_scheme_parse(const unsigned char *credentials, size_t size, unsigned int *iter_count_r, const char **salt_r, unsigned char stored_key_r[], unsigned char server_key_r[], const char **error_r); -int scram_sha1_verify(const char *plaintext, const char *user ATTR_UNUSED, +int scram_sha1_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r ATTR_UNUSED); -void scram_sha1_generate(const char *plaintext, const char *user ATTR_UNUSED, +void scram_sha1_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r); -void pbkdf2_generate(const char *plaintext, const char *user ATTR_UNUSED, +void pbkdf2_generate(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char **raw_password_r, size_t *size_r); -int pbkdf2_verify(const char *plaintext, const char *user ATTR_UNUSED, +int pbkdf2_verify(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, const unsigned char *raw_password, size_t size, const char **error_r); diff --git a/src/doveadm/doveadm-pw.c b/src/doveadm/doveadm-pw.c index c1c0f90bfc..70e69fd25c 100644 --- a/src/doveadm/doveadm-pw.c +++ b/src/doveadm/doveadm-pw.c @@ -20,14 +20,14 @@ static struct module *modules = NULL; static void cmd_pw(int argc, char *argv[]) { const char *hash = NULL; - const char *user = NULL; const char *scheme = NULL; const char *plaintext = NULL; const char *test_hash = NULL; bool list_schemes = FALSE, reverse_verify = FALSE; - unsigned int rounds = 0; int c; struct module_dir_load_settings mod_set; + struct password_generate_params gen_params; + i_zero(&gen_params); password_schemes_init(); @@ -49,7 +49,7 @@ static void cmd_pw(int argc, char *argv[]) plaintext = optarg; break; case 'r': - if (str_to_uint(optarg, &rounds) < 0) + if (str_to_uint(optarg, &gen_params.rounds) < 0) i_fatal("Invalid number of rounds: %s", optarg); break; case 's': @@ -60,7 +60,7 @@ static void cmd_pw(int argc, char *argv[]) reverse_verify = TRUE; break; case 'u': - user = optarg; + gen_params.user = optarg; break; case 'V': reverse_verify = TRUE; @@ -88,8 +88,6 @@ static void cmd_pw(int argc, char *argv[]) help(&doveadm_cmd_pw); scheme = scheme == NULL ? DEFAULT_SCHEME : t_str_ucase(scheme); - if (rounds > 0) - password_set_encryption_rounds(rounds); if (test_hash != NULL && plaintext == NULL) plaintext = t_askpass("Enter password to verify: "); @@ -107,7 +105,7 @@ static void cmd_pw(int argc, char *argv[]) } } - if (!password_generate_encoded(plaintext, user, scheme, &hash)) + if (!password_generate_encoded(plaintext, &gen_params, scheme, &hash)) i_fatal("Unknown scheme: %s", scheme); if (reverse_verify) { const unsigned char *raw_password; @@ -125,7 +123,7 @@ static void cmd_pw(int argc, char *argv[]) &error) <= 0) i_fatal("reverse decode check failed: %s", error); - if (password_verify(plaintext, user, scheme, + if (password_verify(plaintext, &gen_params, scheme, raw_password, size, &error) <= 0) { i_fatal("reverse password verification check failed: %s", error);