From: Aki Tuomi Date: Mon, 25 Mar 2024 08:29:32 +0000 (+0200) Subject: auth: Return error from db_oauth2_init X-Git-Tag: 2.4.1~883 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=877f40777f55a8fb95070709dcc74b7a48725c9e;p=thirdparty%2Fdovecot%2Fcore.git auth: Return error from db_oauth2_init --- diff --git a/src/auth/auth-worker-server.c b/src/auth/auth-worker-server.c index 999d1287e1..a43af1156d 100644 --- a/src/auth/auth-worker-server.c +++ b/src/auth/auth-worker-server.c @@ -1006,6 +1006,7 @@ auth_worker_server_create(struct auth *auth, const struct master_service_connection *master_conn) { struct auth_worker_server *server; + const char *error; if (clients == NULL) clients = connection_list_init(&auth_worker_server_set, @@ -1022,8 +1023,14 @@ auth_worker_server_create(struct auth *auth, auth_worker_refresh_proctitle(WORKER_STATE_HANDSHAKE); - if (*auth->protocol_set->oauth2_config_file != '\0') - server->oauth2 = db_oauth2_init(auth->protocol_set->oauth2_config_file); + if (*auth->protocol_set->oauth2_config_file != '\0') { + if (db_oauth2_init(auth->protocol_set->oauth2_config_file, + &server->oauth2, &error) < 0) { + e_error(auth_event, "Cannot initialize oauth2: %s", + error); + auth_worker_server_error = TRUE; + } + } if (auth_worker_server_error) auth_worker_server_send_error(); return server; diff --git a/src/auth/db-oauth2.c b/src/auth/db-oauth2.c index c02e348411..6cf7197a65 100644 --- a/src/auth/db-oauth2.c +++ b/src/auth/db-oauth2.c @@ -147,6 +147,7 @@ static struct passdb_oauth2_settings default_oauth2_settings = { static void db_oauth2_callback(struct db_oauth2_request *req, enum passdb_result result, const char *error_prefix, const char *error); +static void db_oauth2_free(struct db_oauth2 **_db); static const char *parse_setting(const char *key, const char *value, struct db_oauth2 *db) @@ -155,25 +156,30 @@ static const char *parse_setting(const char *key, const char *value, &db->set_store, key, value); } -static void db_oauth2_setup(struct db_oauth2 *db) +static int db_oauth2_setup(struct db_oauth2 *db, const char **error_r) { const char *error; - if (!settings_read_nosection(db->config_path, parse_setting, db, &error)) - i_fatal("oauth2 %s: %s", db->config_path, error); + if (!settings_read_nosection(db->config_path, parse_setting, db, &error)) { + *error_r = t_strdup_printf("oauth2 %s: %s", db->config_path, error); + return -1; + } db->tmpl = passdb_template_build(db->pool, db->set->pass_attrs); if (*db->set->local_validation_key_dict == '\0' && *db->set->tokeninfo_url == '\0' && (*db->set->grant_url == '\0' || *db->set->client_id == '\0') && - *db->set->introspection_url == '\0') - i_fatal("oauth2: Password grant, tokeninfo, introspection URL or " - "validation key dictionary must be given"); + *db->set->introspection_url == '\0') { + *error_r = "oauth2: Password grant, tokeninfo, introspection URL or validation key dictionary must be given"; + return -1; + } struct event *event = event_create(auth_event); event_set_ptr(event, SETTINGS_EVENT_FILTER_NAME, "oauth2"); - if (http_client_init_auto(event, &db->client, &error) < 0) - i_fatal("%s", error); + if (http_client_init_auto(event, &db->client, &error) < 0) { + *error_r = t_strdup_printf("%s", error); + return -1; + } event_unref(&event); i_zero(&db->oauth2_set); @@ -188,8 +194,10 @@ static void db_oauth2_setup(struct db_oauth2 *db) db->oauth2_set.scope = db->set->scope; if (*db->set->active_attribute == '\0' && - *db->set->active_value != '\0') - i_fatal("oauth2: Cannot have empty active_attribute is active_value is set"); + *db->set->active_value != '\0') { + *error_r = "oauth2: Cannot have empty active_attribute is active_value is set"; + return -1; + } if (*db->set->introspection_mode == '\0' || strcmp(db->set->introspection_mode, "auth") == 0) { @@ -199,13 +207,15 @@ static void db_oauth2_setup(struct db_oauth2 *db) } else if (strcmp(db->set->introspection_mode, "post") == 0) { db->oauth2_set.introspection_mode = INTROSPECTION_MODE_POST; } else if (strcmp(db->set->introspection_mode, "local") == 0) { - if (*db->set->local_validation_key_dict == '\0') - i_fatal("oauth2: local_validation_key_dict is required " - "for local introspection."); + if (*db->set->local_validation_key_dict == '\0') { + *error_r = "oauth2: local_validation_key_dict is required for local introspection."; + return -1; + } db->oauth2_set.introspection_mode = INTROSPECTION_MODE_LOCAL; } else { - i_fatal("oauth2: Invalid value '%s' for introspection mode, must be on auth, get, post or local", - db->set->introspection_mode); + *error_r = t_strdup_printf("oauth2: Invalid value '%s' for introspection mode, must be on auth, get, post or local", + db->set->introspection_mode); + return -1; } if (db->oauth2_set.introspection_mode == INTROSPECTION_MODE_LOCAL) { @@ -214,8 +224,11 @@ static void db_oauth2_setup(struct db_oauth2 *db) .event_parent = auth_event, }; if (dict_init_legacy(db->set->local_validation_key_dict, &dict_set, - &db->oauth2_set.key_dict, &error) < 0) - i_fatal("Cannot initialize key dict: %s", error); + &db->oauth2_set.key_dict, &error) < 0) { + *error_r = t_strdup_printf("Cannot initialize key dict: %s", + error); + return -1; + } /* failure to initialize dcrypt is not fatal - we can still validate HMAC based keys */ (void)dcrypt_initialize(NULL, NULL, &error); @@ -232,19 +245,24 @@ static void db_oauth2_setup(struct db_oauth2 *db) if (http_url_parse(db->set->openid_configuration_url, NULL, 0, pool_datastack_create(), &parsed_url, &error) < 0) { - i_fatal("Invalid openid_configuration_url: %s", - error); + *error_r = t_strdup_printf("Invalid openid_configuration_url: %s", + error); + return -1; } } + + return 0; } -struct db_oauth2 *db_oauth2_init(const char *config_path) +int db_oauth2_init(const char *config_path, struct db_oauth2 **db_r, + const char **error_r) { struct db_oauth2 *db; for(db = db_oauth2_head; db != NULL; db = db->next) { if (strcmp(db->config_path, config_path) == 0) { - return db; + *db_r = db; + return 0; } } @@ -254,9 +272,14 @@ struct db_oauth2 *db_oauth2_init(const char *config_path) db->config_path = p_strdup(pool, config_path); db->set = &default_oauth2_settings; DLLIST_PREPEND(&db_oauth2_head, db); - db_oauth2_setup(db); - return db; + if (db_oauth2_setup(db, error_r) < 0) { + db_oauth2_free(&db); + return -1; + } + + *db_r = db; + return 0; } static void db_oauth2_free(struct db_oauth2 **_db) @@ -283,7 +306,8 @@ static void db_oauth2_free(struct db_oauth2 **_db) "", "aborted"); } } - http_client_deinit(&db->client); + if (db->client != NULL) + http_client_deinit(&db->client); if (db->oauth2_set.key_dict != NULL) dict_deinit(&db->oauth2_set.key_dict); oauth2_validation_key_cache_deinit(&db->oauth2_set.key_cache); diff --git a/src/auth/db-oauth2.h b/src/auth/db-oauth2.h index 1b83d6cf7e..a23f56a362 100644 --- a/src/auth/db-oauth2.h +++ b/src/auth/db-oauth2.h @@ -30,7 +30,8 @@ struct db_oauth2_request { }; -struct db_oauth2 *db_oauth2_init(const char *config_path); +int db_oauth2_init(const char *config_path, struct db_oauth2 **db_r, + const char **error_r); bool db_oauth2_uses_password_grant(const struct db_oauth2 *db); bool db_oauth2_use_worker(const struct db_oauth2 *db); diff --git a/src/auth/mech-oauth2.c b/src/auth/mech-oauth2.c index 3a44849ec6..3abc90e05c 100644 --- a/src/auth/mech-oauth2.c +++ b/src/auth/mech-oauth2.c @@ -200,15 +200,18 @@ mech_oauth2_verify_token(struct oauth2_auth_request *oauth2_req, const char *tok static void oauth2_init_db(struct oauth2_auth_request *oauth2_req) { + const char *error; if (oauth2_req->db != NULL) return; - if (*oauth2_req->auth.set->oauth2_config_file != '\0') - oauth2_req->db = db_oauth2_init(oauth2_req->auth.set->oauth2_config_file); - else { - e_error(oauth2_req->auth.mech_event, "Cannot initialize oauth2"); - oauth2_req->failed = TRUE; - auth_request_internal_failure(&oauth2_req->auth); - } + if (*oauth2_req->auth.set->oauth2_config_file != '\0') { + if (db_oauth2_init(oauth2_req->auth.set->oauth2_config_file, + &oauth2_req->db, &error) >= 0) + return; + } else + error = "No config file specified"; + e_error(oauth2_req->auth.mech_event, "Cannot initialize oauth2: %s", error); + oauth2_req->failed = TRUE; + auth_request_internal_failure(&oauth2_req->auth); } /* Input syntax: @@ -421,5 +424,3 @@ const struct mech_module mech_xoauth2 = { mech_xoauth2_auth_continue, mech_generic_auth_free }; - - diff --git a/src/auth/passdb-oauth2.c b/src/auth/passdb-oauth2.c index f75b894190..dd59b1b4a5 100644 --- a/src/auth/passdb-oauth2.c +++ b/src/auth/passdb-oauth2.c @@ -47,9 +47,11 @@ static struct passdb_module * oauth2_preinit(pool_t pool, const char *args) { struct oauth2_passdb_module *module; + const char *error; module = p_new(pool, struct oauth2_passdb_module, 1); - module->db = db_oauth2_init(args); + if (db_oauth2_init(args, &module->db, &error) < 0) + i_fatal("%s", error); module->module.default_pass_scheme = "PLAIN"; if (db_oauth2_uses_password_grant(module->db)) {