From: Aki Tuomi Date: Tue, 2 Jun 2020 12:59:37 +0000 (+0300) Subject: lib-oauth2: Add iss validation support X-Git-Tag: 2.3.11.2~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e3d591f32acea9742654c5f3b434bcab02b54355;p=thirdparty%2Fdovecot%2Fcore.git lib-oauth2: Add iss validation support --- diff --git a/src/auth/db-oauth2.c b/src/auth/db-oauth2.c index 5115183ab4..6e7eefdbbc 100644 --- a/src/auth/db-oauth2.c +++ b/src/auth/db-oauth2.c @@ -52,6 +52,8 @@ struct passdb_oauth2_settings { const char *pass_attrs; /* template to expand into key path, turns on local validation support */ const char *local_validation_key_dict; + /* valid token issuers */ + const char *issuers; /* TLS options */ const char *tls_ca_cert_file; @@ -119,6 +121,7 @@ static struct setting_def setting_defs[] = { DEF_STR(active_value), DEF_STR(client_id), DEF_STR(client_secret), + DEF_STR(issuers), DEF_INT(timeout_msecs), DEF_INT(max_idle_time_msecs), DEF_INT(max_parallel_connections), @@ -153,6 +156,7 @@ static struct passdb_oauth2_settings default_oauth2_settings = { .active_value = "", .client_id = "", .client_secret = "", + .issuers = "", .pass_attrs = "", .local_validation_key_dict = "", .rawlog_dir = "", @@ -287,6 +291,10 @@ struct db_oauth2 *db_oauth2_init(const char *config_path) db->oauth2_set.key_cache = oauth2_validation_key_cache_init(); } + if (*db->set.issuers != '\0') + db->oauth2_set.issuers = (const char *const *) + p_strsplit_spaces(pool, db->set.issuers, " "); + DLLIST_PREPEND(&db_oauth2_head, db); return db; diff --git a/src/lib-oauth2/oauth2-jwt.c b/src/lib-oauth2/oauth2-jwt.c index 93fe81f5de..aaac16ead3 100644 --- a/src/lib-oauth2/oauth2-jwt.c +++ b/src/lib-oauth2/oauth2-jwt.c @@ -11,6 +11,7 @@ #include "json-tree.h" #include "array.h" #include "base64.h" +#include "str-sanitize.h" #include "dcrypt.h" #include "var-expand.h" #include "oauth2.h" @@ -275,7 +276,8 @@ oauth2_jwt_header_process(struct json_tree *tree, const char **alg_r, } static int -oauth2_jwt_body_process(ARRAY_TYPE(oauth2_field) *fields, struct json_tree *tree, +oauth2_jwt_body_process(const struct oauth2_settings *set, + ARRAY_TYPE(oauth2_field) *fields, struct json_tree *tree, const char **error_r) { const char *sub = get_field(tree, "sub"); @@ -330,6 +332,19 @@ oauth2_jwt_body_process(ARRAY_TYPE(oauth2_field) *fields, struct json_tree *tree return -1; } + const char *iss = get_field(tree, "iss"); + if (set->issuers != NULL && *set->issuers != NULL) { + if (iss == NULL) { + *error_r = "Token is missing 'iss' field"; + return -1; + } + if (!str_array_find(set->issuers, iss)) { + *error_r = t_strdup_printf("Issuer '%s' is not allowed", + str_sanitize_utf8(iss, 128)); + return -1; + } + } + oauth2_jwt_copy_fields(fields, tree); return 0; } @@ -390,7 +405,7 @@ int oauth2_try_parse_jwt(const struct oauth2_settings *set, t_base64url_decode_str(BASE64_DECODE_FLAG_NO_PADDING, blobs[1]); if (oauth2_json_tree_build(body, &body_tree, error_r) == -1) return -1; - ret = oauth2_jwt_body_process(fields, body_tree, error_r); + ret = oauth2_jwt_body_process(set, fields, body_tree, error_r); json_tree_deinit(&body_tree); return ret; diff --git a/src/lib-oauth2/oauth2.h b/src/lib-oauth2/oauth2.h index 7896fdf0e4..b549f4cde4 100644 --- a/src/lib-oauth2/oauth2.h +++ b/src/lib-oauth2/oauth2.h @@ -36,6 +36,8 @@ struct oauth2_settings { struct dict *key_dict; /* cache for validation keys */ struct oauth2_validation_key_cache *key_cache; + /* valid issuer names */ + const char *const *issuers; enum { INTROSPECTION_MODE_GET_AUTH, diff --git a/src/lib-oauth2/test-oauth2-jwt.c b/src/lib-oauth2/test-oauth2-jwt.c index 1dc62cde88..84790e82f4 100644 --- a/src/lib-oauth2/test-oauth2-jwt.c +++ b/src/lib-oauth2/test-oauth2-jwt.c @@ -81,6 +81,7 @@ static int parse_jwt_token(struct oauth2_request *req, const char *token, bool *is_jwt_r, const char **error_r) { struct oauth2_settings set; + i_zero(&set); set.scope = "mail"; set.key_dict = keys_dict; set.key_cache = key_cache;