From: Markus Valentin Date: Thu, 26 Mar 2020 14:26:54 +0000 (+0100) Subject: auth: Add checks for NULs for different auth-mechanisms X-Git-Tag: 2.3.11.2~178 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ce7a61301cb233647c447dd917d5df1184d02317;p=thirdparty%2Fdovecot%2Fcore.git auth: Add checks for NULs for different auth-mechanisms This change adds a check to for NULs in the authentication input in different auth mechanisms. For this purpose the different mechanisms use the newly introduced auth_request_fail_on_nuls function. --- diff --git a/src/auth/mech-external.c b/src/auth/mech-external.c index b9a287b2fc..512288b743 100644 --- a/src/auth/mech-external.c +++ b/src/auth/mech-external.c @@ -11,6 +11,9 @@ mech_external_auth_continue(struct auth_request *request, { const char *authzid, *error; + if (auth_request_fail_on_nuls(request, data, data_size)) + return; + authzid = t_strndup(data, data_size); if (request->user == NULL) { e_info(request->mech_event, diff --git a/src/auth/mech-login.c b/src/auth/mech-login.c index e4da330b93..4a8a41a166 100644 --- a/src/auth/mech-login.c +++ b/src/auth/mech-login.c @@ -20,6 +20,9 @@ mech_login_auth_continue(struct auth_request *request, static const char prompt2[] = "Password:"; const char *username, *error; + if (auth_request_fail_on_nuls(request, data, data_size)) + return; + if (request->user == NULL) { username = t_strndup(data, data_size); diff --git a/src/auth/mech-otp.c b/src/auth/mech-otp.c index 706fde4dde..0d4a51bdef 100644 --- a/src/auth/mech-otp.c +++ b/src/auth/mech-otp.c @@ -23,6 +23,9 @@ otp_send_challenge(struct auth_request *auth_request, (struct otp_auth_request *)auth_request; const char *answer; + if (auth_request_fail_on_nuls(auth_request, credentials, size)) + return; + if (otp_parse_dbentry(t_strndup(credentials, size), &request->state) != 0) { e_error(request->auth_request.mech_event, @@ -113,7 +116,7 @@ mech_otp_auth_phase1(struct auth_request *auth_request, } } - if ((count < 1) || (count > 2)) { + if (count != 1) { e_error(request->auth_request.mech_event, "invalid input"); auth_request_fail(auth_request); @@ -201,6 +204,9 @@ static void mech_otp_auth_phase2(struct auth_request *auth_request, const unsigned char *data, size_t data_size) { + if (auth_request_fail_on_nuls(auth_request, data, data_size)) + return; + const char *str = t_strndup(data, data_size); if (str_begins(str, "hex:")) { diff --git a/src/auth/mech-rpa.c b/src/auth/mech-rpa.c index 94fca52ec0..e7c741d691 100644 --- a/src/auth/mech-rpa.c +++ b/src/auth/mech-rpa.c @@ -535,6 +535,9 @@ mech_rpa_auth_continue(struct auth_request *auth_request, struct rpa_auth_request *request = (struct rpa_auth_request *)auth_request; + if (auth_request_fail_on_nuls(auth_request, data, data_size)) + return; + switch (request->phase) { case 0: mech_rpa_auth_phase1(auth_request, data, data_size); diff --git a/src/auth/mech-scram.c b/src/auth/mech-scram.c index 35fedc91ab..14f556bb12 100644 --- a/src/auth/mech-scram.c +++ b/src/auth/mech-scram.c @@ -361,6 +361,9 @@ void mech_scram_auth_continue(struct auth_request *auth_request, const char *server_final_message; size_t len; + if (auth_request_fail_on_nuls(auth_request, data, data_size)) + return; + if (request->client_first_message_bare == NULL) { /* Received client-first-message */ if (parse_scram_client_first(request, data, diff --git a/src/auth/mech-skey.c b/src/auth/mech-skey.c index d6819a8590..7ba2db8661 100644 --- a/src/auth/mech-skey.c +++ b/src/auth/mech-skey.c @@ -162,6 +162,9 @@ static void mech_skey_auth_continue(struct auth_request *auth_request, const unsigned char *data, size_t data_size) { + if (auth_request_fail_on_nuls(auth_request, data, data_size)) + return; + if (auth_request->user == NULL) { mech_skey_auth_phase1(auth_request, data, data_size); } else { diff --git a/src/auth/mech.c b/src/auth/mech.c index d12c0db2d7..77c9f437c2 100644 --- a/src/auth/mech.c +++ b/src/auth/mech.c @@ -65,6 +65,17 @@ void mech_generic_auth_free(struct auth_request *request) pool_unref(&request->pool); } +bool auth_request_fail_on_nuls(struct auth_request *request, + const unsigned char *data, size_t data_size) +{ + if (memchr(data, '\0', data_size) != NULL) { + e_debug(request->mech_event, "Unexpected NUL in auth data"); + auth_request_fail(request); + return TRUE; + } + return FALSE; +} + extern const struct mech_module mech_plain; extern const struct mech_module mech_login; extern const struct mech_module mech_apop; diff --git a/src/auth/mech.h b/src/auth/mech.h index 4a9f593586..55d9e9ed70 100644 --- a/src/auth/mech.h +++ b/src/auth/mech.h @@ -64,6 +64,8 @@ const struct mech_module *mech_module_find(const char *name); void mech_generic_auth_initial(struct auth_request *request, const unsigned char *data, size_t data_size); void mech_generic_auth_free(struct auth_request *request); +bool auth_request_fail_on_nuls(struct auth_request *request, + const unsigned char *data, size_t data_size); struct mechanisms_register * mech_register_init(const struct auth_settings *set);