]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: auth_fields_import_*() - Handle empty key without crashing
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 11 Sep 2025 12:20:26 +0000 (15:20 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Sat, 20 Sep 2025 07:03:34 +0000 (07:03 +0000)
src/auth/auth-fields.c
src/auth/auth-fields.h
src/auth/auth-request-fields.c
src/auth/userdb-blocking.c

index 8b92836588302717d5d25a9b1bc50b113d4526ce..36d9cba3ef1036c956fb690e8f502bd6ca5a89dc 100644 (file)
@@ -115,12 +115,13 @@ void auth_fields_reset(struct auth_fields *fields)
        }
 }
 
-static void auth_fields_import_prefixed_args(struct auth_fields *fields,
-                                            const char *prefix,
-                                            const char *const *args,
-                                            enum auth_field_flags flags)
+static int auth_fields_import_prefixed_args(struct auth_fields *fields,
+                                           const char *prefix,
+                                           const char *const *args,
+                                           enum auth_field_flags flags)
 {
        const char *key, *value;
+       int ret = 0;
 
        for (; *args != NULL; args++) {
                value = strchr(*args, '=');
@@ -131,26 +132,33 @@ static void auth_fields_import_prefixed_args(struct auth_fields *fields,
                        if (*prefix != '\0')
                                key = t_strconcat(prefix, key, NULL);
                }
+               if (key[0] == '\0')
+                       ret = -1;
                auth_fields_add(fields, key, value, flags);
        }
+       return ret;
 }
 
-void auth_fields_import_prefixed(struct auth_fields *fields, const char *prefix,
-                                const char *str, enum auth_field_flags flags)
+int auth_fields_import_prefixed(struct auth_fields *fields, const char *prefix,
+                               const char *str, enum auth_field_flags flags)
 {
+       int ret;
        T_BEGIN {
                const char *const *arg = t_strsplit_tabescaped(str);
-               auth_fields_import_prefixed_args(fields, prefix, arg, flags);
+               ret = auth_fields_import_prefixed_args(fields, prefix, arg, flags);
        } T_END;
+       return ret;
 }
 
-void auth_fields_import_args(struct auth_fields *fields,
-                            const char *const *args,
-                            enum auth_field_flags flags)
+int auth_fields_import_args(struct auth_fields *fields,
+                           const char *const *args,
+                           enum auth_field_flags flags)
 {
+       int ret;
        T_BEGIN {
-               auth_fields_import_prefixed_args(fields, "", args, flags);
+               ret = auth_fields_import_prefixed_args(fields, "", args, flags);
        } T_END;
+       return ret;
 }
 
 const ARRAY_TYPE(auth_field) *auth_fields_export(struct auth_fields *fields)
index 855f0ac47589240ba0f9ceadf6bb606dedb25e69..e7f0e6e63c5cc8e3f66350420f1596f47e9b0de0 100644 (file)
@@ -26,11 +26,11 @@ void auth_fields_remove(struct auth_fields *fields, const char *key);
 const char *auth_fields_find(struct auth_fields *fields, const char *key);
 bool auth_fields_exists(struct auth_fields *fields, const char *key);
 
-void auth_fields_import_args(struct auth_fields *fields,
-                            const char *const *args,
-                            enum auth_field_flags flags);
-void auth_fields_import_prefixed(struct auth_fields *fields, const char *prefix,
-                                const char *str, enum auth_field_flags flags);
+int auth_fields_import_args(struct auth_fields *fields,
+                           const char *const *args,
+                           enum auth_field_flags flags);
+int auth_fields_import_prefixed(struct auth_fields *fields, const char *prefix,
+                               const char *str, enum auth_field_flags flags);
 const ARRAY_TYPE(auth_field) *auth_fields_export(struct auth_fields *fields);
 /* Append fields where (flag & flags_mask) == flags_result. */
 void auth_fields_append(struct auth_fields *fields, string_t *dest,
index 51e82aabcb53d40076460c18336dfc2f84f2fbf2..8a5fe8a1a6a2e144d556a5e1ef0be6a8cf3a176d 100644 (file)
@@ -208,8 +208,11 @@ bool auth_request_import_info(struct auth_request *request,
                fields->client_id = p_strdup(request->pool, value);
                event_add_str(event, "client_id", value);
        } else if (strcmp(key, "forward_fields") == 0) {
-               auth_fields_import_prefixed(fields->extra_fields,
-                                           "forward_", value, 0);
+               if (auth_fields_import_prefixed(fields->extra_fields,
+                                               "forward_", value, 0) < 0) {
+                       e_error(request->event,
+                               "Invalid forward_fields: %s", value);
+               }
                /* make sure the forward_ fields aren't deleted by
                   auth_fields_rollback() if the first passdb lookup fails. */
                auth_fields_snapshot(fields->extra_fields);
index 5ce9523e1b1f3dae635744e909414cb8a9308899..771efd8b2bed06f713b64627d6efa3509b5c4121 100644 (file)
@@ -50,7 +50,11 @@ static bool user_callback(struct auth_worker_connection *conn ATTR_UNUSED,
        }
 
        if (args != NULL && args[0] != NULL && *args[0] != '\0') {
-               auth_fields_import_args(request->fields.userdb_reply, args, 0);
+               if (auth_fields_import_args(request->fields.userdb_reply,
+                                           args, 0) < 0) {
+                       e_error(authdb_event(request),
+                               "BUG: auth-worker sent invalid args");
+               }
                if (auth_fields_exists(request->fields.userdb_reply, "tempfail"))
                        request->userdb_lookup_tempfailed = TRUE;
        }