From: Stephan Bosch Date: Thu, 16 Mar 2023 19:55:01 +0000 (+0100) Subject: auth: sasl-server - Use struct sasl_server_req_ctx in public API X-Git-Tag: 2.4.2~244 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1971e3be2473ba51eb12fbca0a9224563acb7d19;p=thirdparty%2Fdovecot%2Fcore.git auth: sasl-server - Use struct sasl_server_req_ctx in public API --- diff --git a/src/auth/auth-request-handler.c b/src/auth/auth-request-handler.c index 07abdf7584..1d9e338800 100644 --- a/src/auth/auth-request-handler.c +++ b/src/auth/auth-request-handler.c @@ -10,7 +10,7 @@ #include "str.h" #include "strescape.h" #include "str-sanitize.h" -#include "sasl-server-protected.h" // FIXME: remove +#include "sasl-server.h" #include "master-interface.h" #include "auth-sasl.h" #include "auth-penalty.h" diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c index b0b41106b5..ed3a483ff8 100644 --- a/src/auth/auth-request.c +++ b/src/auth/auth-request.c @@ -15,7 +15,6 @@ #include "hostpid.h" #include "settings.h" #include "master-service.h" -#include "sasl-server-private.h" // FIXME: remove #include "auth-cache.h" #include "auth-request.h" #include "auth-request-handler.h" diff --git a/src/auth/auth-request.h b/src/auth/auth-request.h index d829448e8f..cbef305000 100644 --- a/src/auth/auth-request.h +++ b/src/auth/auth-request.h @@ -17,9 +17,6 @@ #define AUTH_REQUEST_USER_KEY_IGNORE " " -struct sasl_server_mech_def; -struct sasl_server_mech_request; - struct auth_client_connection; enum auth_request_state { @@ -139,7 +136,11 @@ struct auth_request { enum passdb_result passdb_result; const struct sasl_server_mech_def *mech; - struct sasl_server_mech_request *sasl; + struct { + struct sasl_server_req_ctx req; + sasl_server_passdb_callback_t *passdb_callback; + } sasl; + /* Protocol-specific settings */ const struct auth_settings *protocol_set; /* Currently active settings. May be the same as protocol_set, but diff --git a/src/auth/auth-sasl-mech-oauth2.c b/src/auth/auth-sasl-mech-oauth2.c index 187e9c0a4f..8c2d5a30ed 100644 --- a/src/auth/auth-sasl-mech-oauth2.c +++ b/src/auth/auth-sasl-mech-oauth2.c @@ -5,19 +5,24 @@ #include "auth-sasl-oauth2.h" #include "auth-request.h" +#include "auth-sasl-oauth2.h" + static void -oauth2_verify_finish(enum passdb_result result, struct auth_request *request) +oauth2_verify_finish(enum passdb_result result, + struct auth_request *auth_request) { + struct sasl_server_req_ctx *srctx = &auth_request->sasl.req; + struct sasl_server_mech_request *request = + sasl_server_request_get_mech_request(srctx); struct oauth2_auth_request *oauth2_req = - container_of(request->sasl, - struct oauth2_auth_request, request); + container_of(request, struct oauth2_auth_request, request); struct sasl_server_oauth2_failure failure; i_zero(&failure); switch (result) { case PASSDB_RESULT_INTERNAL_FAILURE: - sasl_server_oauth2_request_fail(request, NULL); + sasl_server_oauth2_request_fail(srctx, NULL); return; case PASSDB_RESULT_USER_DISABLED: case PASSDB_RESULT_PASS_EXPIRED: @@ -32,7 +37,7 @@ oauth2_verify_finish(enum passdb_result result, struct auth_request *request) case PASSDB_RESULT_SCHEME_NOT_AVAILABLE: case PASSDB_RESULT_OK: /* sending success */ - sasl_server_oauth2_request_succeed(request); + sasl_server_oauth2_request_succeed(srctx); return; default: i_unreached(); @@ -42,17 +47,18 @@ oauth2_verify_finish(enum passdb_result result, struct auth_request *request) failure.openid_configuration = db_oauth2_get_openid_configuration_url(oauth2_req->db); } - sasl_server_oauth2_request_fail(request, &failure); + sasl_server_oauth2_request_fail(srctx, &failure); } static void oauth2_verify_callback(enum passdb_result result, const unsigned char *credentials ATTR_UNUSED, - size_t size ATTR_UNUSED, struct auth_request *request) + size_t size ATTR_UNUSED, + struct auth_request *auth_request) { if (result == PASSDB_RESULT_USER_UNKNOWN) result = PASSDB_RESULT_OK; - oauth2_verify_finish(result, request); + oauth2_verify_finish(result, auth_request); } static void diff --git a/src/auth/auth-sasl.c b/src/auth/auth-sasl.c index cea96ca52d..8ddf5588bd 100644 --- a/src/auth/auth-sasl.c +++ b/src/auth/auth-sasl.c @@ -1,22 +1,24 @@ /* Copyright (c) 2023 Dovecot authors, see the included COPYING file */ #include "lib.h" -#include "sasl-server-protected.h" // FIXME: Use public API only -#include "sasl-server.h" +#include "sasl-server-private.h" // FIXME: remove #include "auth.h" #include "auth-common.h" #include "auth-sasl.h" #include "auth-request.h" +#include "auth-request-handler.h" /* * Request */ bool -auth_sasl_request_set_authid(struct auth_request *request, +auth_sasl_request_set_authid(struct sasl_server_req_ctx *rctx, enum sasl_server_authid_type authid_type, const char *authid) { + struct auth_request *request = + container_of(rctx, struct auth_request, sasl.req); const char *error; switch (authid_type) { @@ -61,9 +63,11 @@ auth_sasl_request_set_authid(struct auth_request *request, } bool -auth_sasl_request_set_authzid(struct auth_request *request, +auth_sasl_request_set_authzid(struct sasl_server_req_ctx *rctx, const char *authzid) { + struct auth_request *request = + container_of(rctx, struct auth_request, sasl.req); const char *error; if (!auth_request_set_login_username(request, authzid, &error)) { @@ -74,16 +78,21 @@ auth_sasl_request_set_authzid(struct auth_request *request, } void -auth_sasl_request_set_realm(struct auth_request *request, +auth_sasl_request_set_realm(struct sasl_server_req_ctx *rctx, const char *realm) { + struct auth_request *request = + container_of(rctx, struct auth_request, sasl.req); + auth_request_set_realm(request, realm); } bool -auth_sasl_request_get_extra_field(struct auth_request *request, +auth_sasl_request_get_extra_field(struct sasl_server_req_ctx *rctx, const char *name, const char **field_r) { + struct auth_request *request = + container_of(rctx, struct auth_request, sasl.req); const char *value; value = auth_fields_find(request->fields.extra_fields, name); @@ -95,23 +104,32 @@ auth_sasl_request_get_extra_field(struct auth_request *request, } void -auth_sasl_request_start_channel_binding(struct auth_request *request, +auth_sasl_request_start_channel_binding(struct sasl_server_req_ctx *rctx, const char *type) { + struct auth_request *request = + container_of(rctx, struct auth_request, sasl.req); + auth_request_start_channel_binding(request, type); } int -auth_sasl_request_accept_channel_binding(struct auth_request *request, +auth_sasl_request_accept_channel_binding(struct sasl_server_req_ctx *rctx, buffer_t **data_r) { + struct auth_request *request = + container_of(rctx, struct auth_request, sasl.req); + return auth_request_accept_channel_binding(request, data_r); } void -auth_sasl_request_output(struct auth_request *request, +auth_sasl_request_output(struct sasl_server_req_ctx *rctx, const struct sasl_server_output *output) { + struct auth_request *request = + container_of(rctx, struct auth_request, sasl.req); + switch (output->status) { case SASL_SERVER_OUTPUT_INTERNAL_FAILURE: auth_request_internal_failure(request); @@ -129,28 +147,98 @@ auth_sasl_request_output(struct auth_request *request, } } +static enum sasl_passdb_result_status +translate_result_status(enum passdb_result result) +{ + switch (result) { + case PASSDB_RESULT_INTERNAL_FAILURE:; + return SASL_PASSDB_RESULT_INTERNAL_FAILURE; + case PASSDB_RESULT_SCHEME_NOT_AVAILABLE: + return SASL_PASSDB_RESULT_SCHEME_NOT_AVAILABLE; + case PASSDB_RESULT_USER_UNKNOWN: + return SASL_PASSDB_RESULT_USER_UNKNOWN; + case PASSDB_RESULT_USER_DISABLED: + return SASL_PASSDB_RESULT_USER_DISABLED; + case PASSDB_RESULT_PASS_EXPIRED: + return SASL_PASSDB_RESULT_PASS_EXPIRED; + case PASSDB_RESULT_PASSWORD_MISMATCH: + return SASL_PASSDB_RESULT_PASSWORD_MISMATCH; + case PASSDB_RESULT_NEXT: + case PASSDB_RESULT_OK: + return SASL_PASSDB_RESULT_OK; + } + i_unreached(); +} + +static void +verify_plain_callback(enum passdb_result status, struct auth_request *request) +{ + const struct sasl_passdb_result result = { + .status = translate_result_status(status), + }; + request->sasl.passdb_callback(&request->sasl.req, &result); +} + void -auth_sasl_request_verify_plain(struct auth_request *request, +auth_sasl_request_verify_plain(struct sasl_server_req_ctx *rctx, const char *password, - verify_plain_callback_t *verify_plain_callback) + sasl_server_passdb_callback_t *callback) { + struct auth_request *request = + container_of(rctx, struct auth_request, sasl.req); + + request->sasl.passdb_callback = callback; auth_request_verify_plain(request, password, verify_plain_callback); } +static void +lookup_credentials_callback(enum passdb_result status, + const unsigned char *credentials, size_t size, + struct auth_request *request) +{ + const struct sasl_passdb_result result = { + .status = translate_result_status(status), + .credentials = { + .data = credentials, + .size = size, + }, + }; + request->sasl.passdb_callback(&request->sasl.req, &result); +} + void -auth_sasl_request_lookup_credentials(struct auth_request *request, +auth_sasl_request_lookup_credentials(struct sasl_server_req_ctx *rctx, const char *scheme, - lookup_credentials_callback_t *lookup_credentials_callback) + sasl_server_passdb_callback_t *callback) { + struct auth_request *request = + container_of(rctx, struct auth_request, sasl.req); + + request->sasl.passdb_callback = callback; auth_request_lookup_credentials(request, scheme, lookup_credentials_callback); } +static void +set_credentials_callback(bool success, struct auth_request *request) +{ + const struct sasl_passdb_result result = { + .status = (success ? + SASL_PASSDB_RESULT_OK : + SASL_PASSDB_RESULT_INTERNAL_FAILURE), + }; + request->sasl.passdb_callback(&request->sasl.req, &result); +} + void -auth_sasl_request_set_credentials(struct auth_request *request, +auth_sasl_request_set_credentials(struct sasl_server_req_ctx *rctx, const char *scheme, const char *data, - set_credentials_callback_t *set_credentials_callback) + sasl_server_passdb_callback_t *callback) { + struct auth_request *request = + container_of(rctx, struct auth_request, sasl.req); + + request->sasl.passdb_callback = callback; auth_request_set_credentials(request, scheme, data, set_credentials_callback); } @@ -158,17 +246,18 @@ auth_sasl_request_set_credentials(struct auth_request *request, void auth_sasl_request_init(struct auth_request *request, const struct sasl_server_mech_def *mech) { - sasl_server_request_create(request, mech, request->mech_event); + sasl_server_request_create(&request->sasl.req, mech, + request->mech_event); } void auth_sasl_request_deinit(struct auth_request *request) { - sasl_server_request_destroy(request); + sasl_server_request_destroy(&request->sasl.req); } void auth_sasl_request_initial(struct auth_request *request) { - sasl_server_request_initial(request->sasl, + sasl_server_request_initial(&request->sasl.req, request->initial_response, request->initial_response_len); } @@ -176,7 +265,7 @@ void auth_sasl_request_initial(struct auth_request *request) void auth_sasl_request_continue(struct auth_request *request, const unsigned char *data, size_t data_size) { - sasl_server_request_input(request->sasl, data, data_size); + sasl_server_request_input(&request->sasl.req, data, data_size); } /* diff --git a/src/auth/auth-sasl.h b/src/auth/auth-sasl.h index 3fdded49bf..75f1dbff7c 100644 --- a/src/auth/auth-sasl.h +++ b/src/auth/auth-sasl.h @@ -17,47 +17,47 @@ struct auth_sasl_mech_module { */ bool -auth_sasl_request_set_authid(struct auth_request *request, +auth_sasl_request_set_authid(struct sasl_server_req_ctx *rctx, enum sasl_server_authid_type authid_type, const char *authid); bool -auth_sasl_request_set_authzid(struct auth_request *request, +auth_sasl_request_set_authzid(struct sasl_server_req_ctx *rctx, const char *authzid); void -auth_sasl_request_set_realm(struct auth_request *request, +auth_sasl_request_set_realm(struct sasl_server_req_ctx *rctx, const char *realm); bool -auth_sasl_request_get_extra_field(struct auth_request *request, +auth_sasl_request_get_extra_field(struct sasl_server_req_ctx *rctx, const char *name, const char **field_r); void -auth_sasl_request_start_channel_binding(struct auth_request *request, +auth_sasl_request_start_channel_binding(struct sasl_server_req_ctx *rctx, const char *type); int -auth_sasl_request_accept_channel_binding(struct auth_request *request, +auth_sasl_request_accept_channel_binding(struct sasl_server_req_ctx *rctx, buffer_t **data_r); void -auth_sasl_request_output(struct auth_request *request, +auth_sasl_request_output(struct sasl_server_req_ctx *rctx, const struct sasl_server_output *output); void -auth_sasl_request_verify_plain(struct auth_request *request, +auth_sasl_request_verify_plain(struct sasl_server_req_ctx *rctx, const char *password, - verify_plain_callback_t *verify_plain_callback); + sasl_server_passdb_callback_t *callback); void -auth_sasl_request_lookup_credentials(struct auth_request *request, +auth_sasl_request_lookup_credentials(struct sasl_server_req_ctx *rctx, const char *scheme, - lookup_credentials_callback_t *lookup_credentials_callback); + sasl_server_passdb_callback_t *callback); void -auth_sasl_request_set_credentials(struct auth_request *request, +auth_sasl_request_set_credentials(struct sasl_server_req_ctx *rctx, const char *scheme, const char *data, - set_credentials_callback_t *set_credentials_callback); + sasl_server_passdb_callback_t *callback); void auth_sasl_request_init(struct auth_request *request, const struct sasl_server_mech_def *mech); diff --git a/src/auth/sasl-server-mech-digest-md5.c b/src/auth/sasl-server-mech-digest-md5.c index 678ebe47f4..5cba9a58b4 100644 --- a/src/auth/sasl-server-mech-digest-md5.c +++ b/src/auth/sasl-server-mech-digest-md5.c @@ -13,7 +13,7 @@ #include "str-sanitize.h" #include "settings-parser.h" -#include "sasl-server-protected.h" +#include "sasl-server-private.h" // FIXME: Use protected API only /* Linear whitespace */ #define IS_LWS(c) ((c) == ' ' || (c) == '\t') @@ -620,8 +620,8 @@ void mech_digest_test_set_nonce(struct auth_request *auth_request, const char *nonce) { struct digest_auth_request *request = - container_of(auth_request->sasl, struct digest_auth_request, - auth_request); + container_of(auth_request->sasl.req.request->mech, + struct digest_auth_request, auth_request); i_assert(auth_request->mech == &mech_digest_md5); request->nonce = p_strdup(auth_request->pool, nonce); diff --git a/src/auth/sasl-server-mech-oauth2.c b/src/auth/sasl-server-mech-oauth2.c index 69a0f1406d..0e2fb0bcbc 100644 --- a/src/auth/sasl-server-mech-oauth2.c +++ b/src/auth/sasl-server-mech-oauth2.c @@ -95,9 +95,10 @@ static void oauth2_fail_invalid_token(struct oauth2_auth_request *oauth2_req) oauth2_fail_status(oauth2_req, "invalid_token"); } -void sasl_server_oauth2_request_succeed(struct auth_request *auth_request) +void sasl_server_oauth2_request_succeed(struct sasl_server_req_ctx *rctx) { - struct sasl_server_mech_request *request = auth_request->sasl; + struct sasl_server_mech_request *request = + sasl_server_request_get_mech_request(rctx); i_assert(request->mech == &mech_oauthbearer || request->mech == &mech_xoauth2); @@ -110,10 +111,11 @@ void sasl_server_oauth2_request_succeed(struct auth_request *auth_request) } void sasl_server_oauth2_request_fail( - struct auth_request *auth_request, + struct sasl_server_req_ctx *rctx, const struct sasl_server_oauth2_failure *failure) { - struct sasl_server_mech_request *request = auth_request->sasl; + struct sasl_server_mech_request *request = + sasl_server_request_get_mech_request(rctx); i_assert(request->mech == &mech_oauthbearer || request->mech == &mech_xoauth2); diff --git a/src/auth/sasl-server-oauth2.h b/src/auth/sasl-server-oauth2.h index 15a644465a..cbe2580566 100644 --- a/src/auth/sasl-server-oauth2.h +++ b/src/auth/sasl-server-oauth2.h @@ -9,9 +9,9 @@ struct sasl_server_oauth2_failure { const char *openid_configuration; }; -void sasl_server_oauth2_request_succeed(struct auth_request *request); +void sasl_server_oauth2_request_succeed(struct sasl_server_req_ctx *rctx); void sasl_server_oauth2_request_fail( - struct auth_request *request, + struct sasl_server_req_ctx *rctx, const struct sasl_server_oauth2_failure *failure); #endif diff --git a/src/auth/sasl-server-private.h b/src/auth/sasl-server-private.h index 88432be6bc..93e512de3f 100644 --- a/src/auth/sasl-server-private.h +++ b/src/auth/sasl-server-private.h @@ -10,6 +10,8 @@ enum sasl_server_passdb_type { }; struct sasl_server_request { + pool_t pool; + struct sasl_server_req_ctx *rctx; struct sasl_server_mech_request *mech; enum sasl_server_passdb_type passdb_type; diff --git a/src/auth/sasl-server-protected.h b/src/auth/sasl-server-protected.h index 24a541a85c..8e6df4065a 100644 --- a/src/auth/sasl-server-protected.h +++ b/src/auth/sasl-server-protected.h @@ -1,8 +1,7 @@ #ifndef SASL_SERVER_PROTECTED_H #define SASL_SERVER_PROTECTED_H -#include "passdb.h" // FIXME: remove -#include "auth-request-handler.h" +#include "auth-request.h" // FIXME: remove #include "sasl-server.h" @@ -118,4 +117,13 @@ void sasl_server_request_set_credentials( const char *scheme, const char *data, sasl_server_mech_passdb_callback_t *callback); +/* Obtains the mechanism request struct (protected) from the request context + struct (public). This function meant for providing the means to have + mechanisms that add their own backend API. If you use this function for + something else, you are subverting the design of the SASL server API, which + is to be avoided. +*/ +struct sasl_server_mech_request * +sasl_server_request_get_mech_request(struct sasl_server_req_ctx *rctx); + #endif diff --git a/src/auth/sasl-server-request.c b/src/auth/sasl-server-request.c index 0559398d4b..cd36244524 100644 --- a/src/auth/sasl-server-request.c +++ b/src/auth/sasl-server-request.c @@ -9,15 +9,21 @@ * Public API */ -void sasl_server_request_create(struct auth_request *request, +void sasl_server_request_create(struct sasl_server_req_ctx *rctx, const struct sasl_server_mech_def *mech, struct event *event_parent) { + struct auth_request *request = + container_of(rctx, struct auth_request, sasl.req); struct sasl_server_request *req; pool_t pool; + i_zero(rctx); + pool = request->pool; req = p_new(pool, struct sasl_server_request, 1); + req->pool = pool; + req->rctx = rctx; struct sasl_server_mech_request *mreq; @@ -32,55 +38,63 @@ void sasl_server_request_create(struct auth_request *request, mreq->mech_event = event_parent; req->mech = mreq; - request->sasl = mreq; + rctx->mech = mech; + rctx->mech_name = mech->mech_name; + rctx->request = req; } -void sasl_server_request_destroy(struct auth_request *request) +void sasl_server_request_destroy(struct sasl_server_req_ctx *rctx) { - struct sasl_server_mech_request *mreq = request->sasl; + struct sasl_server_request *req = rctx->request; - if (mreq == NULL) + i_zero(rctx); + if (req == NULL) return; - request->sasl = NULL; + + struct sasl_server_mech_request *mreq = req->mech; if (mreq->mech->auth_free != NULL) mreq->mech->auth_free(mreq); } static bool -sasl_server_request_fail_on_nuls(struct sasl_server_mech_request *mreq, +sasl_server_request_fail_on_nuls(struct sasl_server_request *req, const unsigned char *data, size_t data_size) { - const struct sasl_server_mech_def *mech = mreq->mech; + const struct sasl_server_mech_def *mech = req->mech->mech; if ((mech->flags & SASL_MECH_SEC_ALLOW_NULS) != 0) return FALSE; if (memchr(data, '\0', data_size) != NULL) { - e_debug(mreq->mech_event, "Unexpected NUL in auth data"); - sasl_server_request_failure(mreq); + e_debug(req->mech->mech_event, "Unexpected NUL in auth data"); + sasl_server_request_failure(req->mech); return TRUE; } return FALSE; } -void sasl_server_request_initial(struct sasl_server_mech_request *mreq, +void sasl_server_request_initial(struct sasl_server_req_ctx *rctx, const unsigned char *data, size_t data_size) { + struct sasl_server_request *req = rctx->request; + struct sasl_server_mech_request *mreq = req->mech; const struct sasl_server_mech_def *mech = mreq->mech; - if (sasl_server_request_fail_on_nuls(mreq, data, data_size)) + if (sasl_server_request_fail_on_nuls(req, data, data_size)) return; i_assert(mech->auth_initial != NULL); mech->auth_initial(mreq, data, data_size); } -void sasl_server_request_input(struct sasl_server_mech_request *mreq, +void sasl_server_request_input(struct sasl_server_req_ctx *rctx, const unsigned char *data, size_t data_size) { + struct sasl_server_request *req = rctx->request; + struct sasl_server_mech_request *mreq = req->mech; const struct sasl_server_mech_def *mech = mreq->mech; - if (sasl_server_request_fail_on_nuls(mreq, data, data_size)) + if (sasl_server_request_fail_on_nuls(req, data, data_size)) return; i_assert(mech->auth_continue != NULL); @@ -95,76 +109,76 @@ bool sasl_server_request_set_authid(struct sasl_server_mech_request *mreq, enum sasl_server_authid_type authid_type, const char *authid) { - struct auth_request *request = mreq->request; + struct sasl_server_request *req = mreq->req; - return auth_sasl_request_set_authid(request, authid_type, authid); + return auth_sasl_request_set_authid(req->rctx, authid_type, authid); } bool sasl_server_request_set_authzid(struct sasl_server_mech_request *mreq, const char *authzid) { - struct auth_request *request = mreq->request; + struct sasl_server_request *req = mreq->req; - return auth_sasl_request_set_authzid(request, authzid); + return auth_sasl_request_set_authzid(req->rctx, authzid); } void sasl_server_request_set_realm(struct sasl_server_mech_request *mreq, const char *realm) { - struct auth_request *request = mreq->request; + struct sasl_server_request *req = mreq->req; - auth_sasl_request_set_realm(request, realm); + auth_sasl_request_set_realm(req->rctx, realm); } bool sasl_server_request_get_extra_field(struct sasl_server_mech_request *mreq, const char *name, const char **field_r) { - struct auth_request *request = mreq->request; + struct sasl_server_request *req = mreq->req; - return auth_sasl_request_get_extra_field(request, name, field_r); + return auth_sasl_request_get_extra_field(req->rctx, name, field_r); } void sasl_server_request_start_channel_binding( struct sasl_server_mech_request *mreq, const char *type) { - struct auth_request *request = mreq->request; + struct sasl_server_request *req = mreq->req; - auth_sasl_request_start_channel_binding(request, type); + auth_sasl_request_start_channel_binding(req->rctx, type); } int sasl_server_request_accept_channel_binding( struct sasl_server_mech_request *mreq, buffer_t **data_r) { - struct auth_request *request = mreq->request; + struct sasl_server_request *req = mreq->req; - return auth_sasl_request_accept_channel_binding(request, data_r); + return auth_sasl_request_accept_channel_binding(req->rctx, data_r); } void sasl_server_request_output(struct sasl_server_mech_request *mreq, const void *data, size_t data_size) { - struct auth_request *request = mreq->request; + struct sasl_server_request *req = mreq->req; const struct sasl_server_output output = { .status = SASL_SERVER_OUTPUT_CONTINUE, .data = data, .data_size = data_size, }; - auth_sasl_request_output(request, &output); + auth_sasl_request_output(req->rctx, &output); } void sasl_server_request_success(struct sasl_server_mech_request *mreq, const void *data, size_t data_size) { - struct auth_request *request = mreq->request; + struct sasl_server_request *req = mreq->req; const struct sasl_server_output output = { .status = SASL_SERVER_OUTPUT_SUCCESS, .data = data, .data_size = data_size, }; - auth_sasl_request_output(request, &output); + auth_sasl_request_output(req->rctx, &output); } static void @@ -172,14 +186,14 @@ sasl_server_request_failure_common(struct sasl_server_mech_request *mreq, enum sasl_server_output_status status, const void *data, size_t data_size) { - struct auth_request *request = mreq->request; + struct sasl_server_request *req = mreq->req; const struct sasl_server_output output = { .status = status, .data = data, .data_size = data_size, }; - auth_sasl_request_output(request, &output); + auth_sasl_request_output(req->rctx, &output); } void sasl_server_request_failure_with_reply( @@ -203,103 +217,61 @@ void sasl_server_request_internal_failure( mreq, SASL_SERVER_OUTPUT_INTERNAL_FAILURE, "", 0); } -static enum sasl_passdb_result_status -translate_result_status(enum passdb_result result) -{ - switch (result) { - case PASSDB_RESULT_INTERNAL_FAILURE:; - return SASL_PASSDB_RESULT_INTERNAL_FAILURE; - case PASSDB_RESULT_SCHEME_NOT_AVAILABLE: - return SASL_PASSDB_RESULT_SCHEME_NOT_AVAILABLE; - case PASSDB_RESULT_USER_UNKNOWN: - return SASL_PASSDB_RESULT_USER_UNKNOWN; - case PASSDB_RESULT_USER_DISABLED: - return SASL_PASSDB_RESULT_USER_DISABLED; - case PASSDB_RESULT_PASS_EXPIRED: - return SASL_PASSDB_RESULT_PASS_EXPIRED; - case PASSDB_RESULT_PASSWORD_MISMATCH: - return SASL_PASSDB_RESULT_PASSWORD_MISMATCH; - case PASSDB_RESULT_NEXT: - case PASSDB_RESULT_OK: - return SASL_PASSDB_RESULT_OK; - } - i_unreached(); -} - static void -verify_plain_callback(enum passdb_result status, struct auth_request *request) +verify_plain_callback(struct sasl_server_req_ctx *rctx, + const struct sasl_passdb_result *result) { - struct sasl_server_mech_request *mreq = request->sasl; - struct sasl_server_request *req = mreq->req; + struct sasl_server_request *req = rctx->request; i_assert(req->passdb_type == SASL_SERVER_PASSDB_TYPE_VERIFY_PLAIN); - - const struct sasl_passdb_result result = { - .status = translate_result_status(status), - }; - req->passdb_callback(mreq, &result); + req->passdb_callback(req->mech, result); } void sasl_server_request_verify_plain( struct sasl_server_mech_request *mreq, const char *password, sasl_server_mech_passdb_callback_t *callback) { - struct auth_request *request = mreq->request; struct sasl_server_request *req = mreq->req; req->passdb_type = SASL_SERVER_PASSDB_TYPE_VERIFY_PLAIN; req->passdb_callback = callback; - auth_sasl_request_verify_plain(request, password, verify_plain_callback); + + auth_sasl_request_verify_plain(req->rctx, password, + verify_plain_callback); } static void -lookup_credentials_callback(enum passdb_result status, - const unsigned char *credentials, - size_t size, struct auth_request *request) +lookup_credentials_callback(struct sasl_server_req_ctx *rctx, + const struct sasl_passdb_result *result) { - struct sasl_server_mech_request *mreq = request->sasl; - struct sasl_server_request *req = mreq->req; + struct sasl_server_request *req = rctx->request; i_assert(req->passdb_type == SASL_SERVER_PASSDB_TYPE_LOOKUP_CREDENTIALS); - - const struct sasl_passdb_result result = { - .status = translate_result_status(status), - .credentials = { - .data = credentials, - .size = size, - }, - }; - req->passdb_callback(mreq, &result); + req->passdb_callback(req->mech, result); } void sasl_server_request_lookup_credentials( struct sasl_server_mech_request *mreq, const char *scheme, sasl_server_mech_passdb_callback_t *callback) { - struct auth_request *request = mreq->request; struct sasl_server_request *req = mreq->req; req->passdb_type = SASL_SERVER_PASSDB_TYPE_LOOKUP_CREDENTIALS; req->passdb_callback = callback; - auth_sasl_request_lookup_credentials(request, scheme, + + auth_sasl_request_lookup_credentials(req->rctx, scheme, lookup_credentials_callback); } static void -set_credentials_callback(bool success, struct auth_request *request) +set_credentials_callback(struct sasl_server_req_ctx *rctx, + const struct sasl_passdb_result *result) { - struct sasl_server_mech_request *mreq = request->sasl; - struct sasl_server_request *req = mreq->req; + struct sasl_server_request *req = rctx->request; i_assert(req->passdb_type == SASL_SERVER_PASSDB_TYPE_SET_CREDENTIALS); - - const struct sasl_passdb_result result = { - .status = (success ? - SASL_PASSDB_RESULT_OK : - SASL_PASSDB_RESULT_INTERNAL_FAILURE), - }; - req->passdb_callback(mreq, &result); + req->passdb_callback(req->mech, result); } void sasl_server_request_set_credentials( @@ -307,11 +279,17 @@ void sasl_server_request_set_credentials( const char *scheme, const char *data, sasl_server_mech_passdb_callback_t *callback) { - struct auth_request *request = mreq->request; struct sasl_server_request *req = mreq->req; req->passdb_type = SASL_SERVER_PASSDB_TYPE_SET_CREDENTIALS; req->passdb_callback = callback; - auth_sasl_request_set_credentials(request, scheme, data, + + auth_sasl_request_set_credentials(req->rctx, scheme, data, set_credentials_callback); } + +struct sasl_server_mech_request * +sasl_server_request_get_mech_request(struct sasl_server_req_ctx *rctx) +{ + return rctx->request->mech; +} diff --git a/src/auth/sasl-server.h b/src/auth/sasl-server.h index 882e1fda17..d6aa1f7ed3 100644 --- a/src/auth/sasl-server.h +++ b/src/auth/sasl-server.h @@ -3,8 +3,8 @@ #include "sasl-common.h" +struct sasl_passdb_result; struct sasl_server_mech_def; -struct sasl_server_mech_request; struct sasl_server_request; struct sasl_server_req_ctx; @@ -46,6 +46,10 @@ enum sasl_server_output_status { SASL_SERVER_OUTPUT_SUCCESS = 1, }; +typedef void +sasl_server_passdb_callback_t(struct sasl_server_req_ctx *rctx, + const struct sasl_passdb_result *result); + struct sasl_server_output { enum sasl_server_output_status status; @@ -75,14 +79,21 @@ enum sasl_server_authid_type { SASL_SERVER_AUTHID_TYPE_EXTERNAL, }; -void sasl_server_request_create(struct auth_request *request, +struct sasl_server_req_ctx { + const struct sasl_server_mech_def *mech; + const char *mech_name; + + struct sasl_server_request *request; +}; + +void sasl_server_request_create(struct sasl_server_req_ctx *rctx, const struct sasl_server_mech_def *mech, struct event *event_parent); -void sasl_server_request_destroy(struct auth_request *request); +void sasl_server_request_destroy(struct sasl_server_req_ctx *rctx); -void sasl_server_request_initial(struct sasl_server_mech_request *mreq, +void sasl_server_request_initial(struct sasl_server_req_ctx *rctx, const unsigned char *data, size_t data_size); -void sasl_server_request_input(struct sasl_server_mech_request *mreq, +void sasl_server_request_input(struct sasl_server_req_ctx *rctx, const unsigned char *data, size_t data_size); #endif diff --git a/src/auth/test-auth.c b/src/auth/test-auth.c index 7d6c8a20e9..1806e2bbd2 100644 --- a/src/auth/test-auth.c +++ b/src/auth/test-auth.c @@ -7,6 +7,7 @@ #include "auth-token.h" #include "auth-penalty.h" #include "sasl-server-protected.h" // FIXME: remove +#include "auth-sasl-oauth2.h" #include "otp.h" #include "mech-otp.h" #include "db-oauth2.h" @@ -62,6 +63,7 @@ void test_auth_init(void) password_schemes_register_all(); password_schemes_allow_weak(TRUE); + auth_sasl_oauth2_initialize(); auths_preinit(simple_set.event, global_auth_settings, mech_reg, protocols); auths_init(); auth_token_init(); diff --git a/src/auth/test-mech.c b/src/auth/test-mech.c index 1ba82e24bc..358bb8ccca 100644 --- a/src/auth/test-mech.c +++ b/src/auth/test-mech.c @@ -5,7 +5,7 @@ #include "str.h" #include "ioloop.h" #include "master-service.h" -#include "sasl-server-protected.h" // FIXME: remove +#include "sasl-server-private.h" // FIXME: remove #include "auth-common.h" #include "auth-request.h" #include "auth-request-handler-private.h"