]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: sasl-server-mech-oauth2 - Move auth_sasl_oauth2_verify_token() to auth-sasl...
authorStephan Bosch <stephan.bosch@open-xchange.com>
Sat, 4 Nov 2023 13:56:49 +0000 (14:56 +0100)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Thu, 9 Oct 2025 08:41:22 +0000 (08:41 +0000)
src/auth/auth-sasl-mech-oauth2.c [new file with mode: 0644]
src/auth/sasl-server-mech-oauth2.c

diff --git a/src/auth/auth-sasl-mech-oauth2.c b/src/auth/auth-sasl-mech-oauth2.c
new file mode 100644 (file)
index 0000000..45cd9b8
--- /dev/null
@@ -0,0 +1,162 @@
+/* Copyright (c) 2023 Dovecot authors, see the included COPYING file */
+
+#include "auth-common.h"
+#include "auth-sasl.h"
+#include "auth-request.h"
+
+static void
+oauth2_verify_finish(enum passdb_result result, struct auth_request *request)
+{
+       struct oauth2_auth_request *oauth2_req =
+               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);
+               return;
+       case PASSDB_RESULT_USER_DISABLED:
+       case PASSDB_RESULT_PASS_EXPIRED:
+               /* user is explicitly disabled, don't allow it to log in */
+               failure.status = "insufficient_scope";
+               break;
+       case PASSDB_RESULT_USER_UNKNOWN:
+       case PASSDB_RESULT_PASSWORD_MISMATCH:
+               failure.status = "invalid_token";
+               break;
+       case PASSDB_RESULT_NEXT:
+       case PASSDB_RESULT_SCHEME_NOT_AVAILABLE:
+       case PASSDB_RESULT_OK:
+               /* sending success */
+               sasl_server_oauth2_request_succeed(request);
+               return;
+       default:
+               i_unreached();
+       }
+
+       if (oauth2_req->db != NULL) {
+               failure.openid_configuration =
+                       db_oauth2_get_openid_configuration_url(oauth2_req->db);
+       }
+       sasl_server_oauth2_request_fail(request, &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)
+{
+       if (result == PASSDB_RESULT_USER_UNKNOWN)
+               result = PASSDB_RESULT_OK;
+       oauth2_verify_finish(result, request);
+}
+
+static void
+mech_oauth2_verify_token_continue(struct oauth2_auth_request *oauth2_req,
+                                 const char *const *args)
+{
+       struct auth_request *request = &oauth2_req->request;
+       int parsed;
+       enum passdb_result result;
+
+       /* OK result user fields */
+       if (args[0] == NULL || args[1] == NULL) {
+               result = PASSDB_RESULT_INTERNAL_FAILURE;
+               e_error(request->mech_event,
+                       "BUG: Invalid auth worker response: empty");
+       } else if (str_to_int(args[1], &parsed) < 0) {
+               result = PASSDB_RESULT_INTERNAL_FAILURE;
+               e_error(request->mech_event,
+                       "BUG: Invalid auth worker response: cannot parse '%s'",
+                       args[1]);
+       } else if (args[2] == NULL) {
+               result = PASSDB_RESULT_INTERNAL_FAILURE;
+               e_error(request->mech_event,
+                       "BUG: Invalid auth worker response: cannot parse '%s'",
+                       args[1]);
+       } else {
+               result = parsed;
+       }
+
+       if (result == PASSDB_RESULT_OK) {
+               request->passdb_success = TRUE;
+               auth_request_set_password_verified(request);
+               auth_request_set_fields(request, args + 3, NULL);
+               auth_request_lookup_credentials(request, "",
+                                               oauth2_verify_callback);
+               auth_request_unref(&request);
+               return;
+       }
+
+       oauth2_verify_finish(result, request);
+       auth_request_unref(&request);
+}
+
+static bool
+mech_oauth2_verify_token_input_args(
+       struct auth_worker_connection *conn ATTR_UNUSED,
+       const char *const *args, void *context)
+{
+       struct oauth2_auth_request *oauth2_req = context;
+
+       mech_oauth2_verify_token_continue(oauth2_req, args);
+       return TRUE;
+}
+
+static void
+mech_oauth2_verify_token_local_continue(struct db_oauth2_request *db_req,
+                                       enum passdb_result result,
+                                       const char *error,
+                                       struct oauth2_auth_request *oauth2_req)
+{
+       struct auth_request *request = &oauth2_req->request;
+
+       if (result == PASSDB_RESULT_OK) {
+               auth_request_set_password_verified(request);
+               auth_request_set_field(request, "token", db_req->token, NULL);
+               auth_request_lookup_credentials(request, "",
+                                               oauth2_verify_callback);
+               auth_request_unref(&request);
+               pool_unref(&db_req->pool);
+               return;
+       } else if (result == PASSDB_RESULT_INTERNAL_FAILURE) {
+               e_error(request->mech_event, "oauth2 failed: %s", error);
+       } else {
+               e_info(request->mech_event, "oauth2 failed: %s", error);
+       }
+       oauth2_verify_finish(result, request);
+       auth_request_unref(&request);
+       pool_unref(&db_req->pool);
+}
+
+static void
+auth_sasl_oauth2_verify_token(struct oauth2_auth_request *oauth2_req,
+                            const char *token)
+{
+       struct auth_request *auth_request = &oauth2_req->request;
+
+       auth_request_ref(auth_request);
+       if (!db_oauth2_use_worker(oauth2_req->db)) {
+               pool_t pool = pool_alloconly_create(
+                       MEMPOOL_GROWING"oauth2 request", 256);
+               struct db_oauth2_request *db_req =
+                       p_new(pool, struct db_oauth2_request, 1);
+               db_req->pool = pool;
+               db_req->auth_request = auth_request;
+               db_oauth2_lookup(
+                       oauth2_req->db, db_req, token,  db_req->auth_request,
+                       mech_oauth2_verify_token_local_continue, oauth2_req);
+       } else {
+               string_t *str = t_str_new(128);
+               str_append(str, "TOKEN\tOAUTH2\t");
+               str_append_tabescaped(str, token);
+               str_append_c(str, '\t');
+               auth_request_export(auth_request, str);
+               auth_worker_call(
+                       oauth2_req->db_req.pool,
+                       auth_request->fields.user, str_c(str),
+                       mech_oauth2_verify_token_input_args, oauth2_req);
+       }
+}
index 849b5fa9af03f56aa20d19eafe803a4a6d09a2ff..bb5a6451ead89e8f69e413175126cacf587bd2ff 100644 (file)
@@ -117,162 +117,7 @@ void sasl_server_oauth2_request_fail(
        oauth2_fail(oauth2_req, failure);
 }
 
-static void
-oauth2_verify_finish(enum passdb_result result, struct auth_request *request)
-{
-       struct oauth2_auth_request *oauth2_req =
-               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);
-               return;
-       case PASSDB_RESULT_USER_DISABLED:
-       case PASSDB_RESULT_PASS_EXPIRED:
-               /* user is explicitly disabled, don't allow it to log in */
-               failure.status = "insufficient_scope";
-               break;
-       case PASSDB_RESULT_USER_UNKNOWN:
-       case PASSDB_RESULT_PASSWORD_MISMATCH:
-               failure.status = "invalid_token";
-               break;
-       case PASSDB_RESULT_NEXT:
-       case PASSDB_RESULT_SCHEME_NOT_AVAILABLE:
-       case PASSDB_RESULT_OK:
-               /* sending success */
-               sasl_server_oauth2_request_succeed(request);
-               return;
-       default:
-               i_unreached();
-       }
-
-       if (oauth2_req->db != NULL) {
-               failure.openid_configuration =
-                       db_oauth2_get_openid_configuration_url(oauth2_req->db);
-       }
-       sasl_server_oauth2_request_fail(request, &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)
-{
-       if (result == PASSDB_RESULT_USER_UNKNOWN)
-               result = PASSDB_RESULT_OK;
-       oauth2_verify_finish(result, request);
-}
-
-static void
-mech_oauth2_verify_token_continue(struct oauth2_auth_request *oauth2_req,
-                                 const char *const *args)
-{
-       struct auth_request *request = &oauth2_req->request;
-       int parsed;
-       enum passdb_result result;
-
-       /* OK result user fields */
-       if (args[0] == NULL || args[1] == NULL) {
-               result = PASSDB_RESULT_INTERNAL_FAILURE;
-               e_error(request->mech_event,
-                       "BUG: Invalid auth worker response: empty");
-       } else if (str_to_int(args[1], &parsed) < 0) {
-               result = PASSDB_RESULT_INTERNAL_FAILURE;
-               e_error(request->mech_event,
-                       "BUG: Invalid auth worker response: cannot parse '%s'",
-                       args[1]);
-       } else if (args[2] == NULL) {
-               result = PASSDB_RESULT_INTERNAL_FAILURE;
-               e_error(request->mech_event,
-                       "BUG: Invalid auth worker response: cannot parse '%s'",
-                       args[1]);
-       } else {
-               result = parsed;
-       }
-
-       if (result == PASSDB_RESULT_OK) {
-               request->passdb_success = TRUE;
-               auth_request_set_password_verified(request);
-               auth_request_set_fields(request, args + 3, NULL);
-               auth_request_lookup_credentials(request, "",
-                                               oauth2_verify_callback);
-               auth_request_unref(&request);
-               return;
-       }
-
-       oauth2_verify_finish(result, request);
-       auth_request_unref(&request);
-}
-
-static bool
-mech_oauth2_verify_token_input_args(
-       struct auth_worker_connection *conn ATTR_UNUSED,
-       const char *const *args, void *context)
-{
-       struct oauth2_auth_request *oauth2_req = context;
-
-       mech_oauth2_verify_token_continue(oauth2_req, args);
-       return TRUE;
-}
-
-static void
-mech_oauth2_verify_token_local_continue(struct db_oauth2_request *db_req,
-                                       enum passdb_result result,
-                                       const char *error,
-                                       struct oauth2_auth_request *oauth2_req)
-{
-       struct auth_request *request = &oauth2_req->request;
-
-       if (result == PASSDB_RESULT_OK) {
-               auth_request_set_password_verified(request);
-               auth_request_set_field(request, "token", db_req->token, NULL);
-               auth_request_lookup_credentials(request, "",
-                                               oauth2_verify_callback);
-               auth_request_unref(&request);
-               pool_unref(&db_req->pool);
-               return;
-       } else if (result == PASSDB_RESULT_INTERNAL_FAILURE) {
-               e_error(request->mech_event, "oauth2 failed: %s", error);
-       } else {
-               e_info(request->mech_event, "oauth2 failed: %s", error);
-       }
-       oauth2_verify_finish(result, request);
-       auth_request_unref(&request);
-       pool_unref(&db_req->pool);
-}
-
-static void
-auth_sasl_oauth2_verify_token(struct oauth2_auth_request *oauth2_req,
-                            const char *token)
-{
-       struct auth_request *auth_request = &oauth2_req->request;
-
-       auth_request_ref(auth_request);
-       if (!db_oauth2_use_worker(oauth2_req->db)) {
-               pool_t pool = pool_alloconly_create(
-                       MEMPOOL_GROWING"oauth2 request", 256);
-               struct db_oauth2_request *db_req =
-                       p_new(pool, struct db_oauth2_request, 1);
-               db_req->pool = pool;
-               db_req->auth_request = auth_request;
-               db_oauth2_lookup(
-                       oauth2_req->db, db_req, token,  db_req->auth_request,
-                       mech_oauth2_verify_token_local_continue, oauth2_req);
-       } else {
-               string_t *str = t_str_new(128);
-               str_append(str, "TOKEN\tOAUTH2\t");
-               str_append_tabescaped(str, token);
-               str_append_c(str, '\t');
-               auth_request_export(auth_request, str);
-               auth_worker_call(
-                       oauth2_req->db_req.pool,
-                       auth_request->fields.user, str_c(str),
-                       mech_oauth2_verify_token_input_args, oauth2_req);
-       }
-}
+#include "auth-sasl-mech-oauth2.c"
 
 static void
 mech_oauth2_verify_token(struct oauth2_auth_request *oauth2_req,