]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-oauth2: Add iss validation support
authorAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 2 Jun 2020 12:59:37 +0000 (15:59 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 5 Jun 2020 06:12:08 +0000 (09:12 +0300)
src/auth/db-oauth2.c
src/lib-oauth2/oauth2-jwt.c
src/lib-oauth2/oauth2.h
src/lib-oauth2/test-oauth2-jwt.c

index 5115183ab431e0991a2bbc05a75b750f96711d3f..6e7eefdbbcd1fe5943ad2379ebeb9c17ffa02362 100644 (file)
@@ -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;
index 93fe81f5de960b751584733591d269da14fb86c3..aaac16ead346ae9ca4a35d788bfc1987051e03e7 100644 (file)
@@ -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;
index 7896fdf0e4989c9a50e0a35d6d7dfef26b5b59f0..b549f4cde432f2fd565b60466ef90297f882c3c0 100644 (file)
@@ -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,
index 1dc62cde88ca16498d1c4d25cc6b7e8701aa9f18..84790e82f4d37c30fdd09eb82c03b66c390b0f20 100644 (file)
@@ -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;