]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: Refactor auth client input handling functions
authorAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 26 Jan 2024 09:51:16 +0000 (11:51 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 12 Feb 2024 11:27:27 +0000 (13:27 +0200)
Simplifies next change

src/auth/auth-client-connection.c
src/auth/auth-request-handler.c
src/auth/auth-request-handler.h

index e3ec7680d8d30487c62cf906a55cfad4911eed10..fc699431f459eedb3a359473c917bd218f0aab7c 100644 (file)
@@ -9,6 +9,7 @@
 #include "hostpid.h"
 #include "llist.h"
 #include "str.h"
+#include "strescape.h"
 #include "str-sanitize.h"
 #include "randgen.h"
 #include "safe-memset.h"
@@ -42,13 +43,13 @@ static const char *reply_line_hide_pass(const char *line)
 
        newline = t_str_new(strlen(line));
 
-       const char *const *fields = t_strsplit(line, "\t");
+       const char *const *fields = t_strsplit_tabescaped(line);
 
        while(*fields != NULL) {
                p = strstr(*fields, "pass");
                p2 = strchr(*fields, '=');
                if (p == NULL || p2 == NULL || p2 < p) {
-                       str_append(newline, *fields);
+                       str_append_tabescaped(newline, *fields);
                } else {
                        /* include = */
                        str_append_data(newline, *fields, (p2 - *fields)+1);
@@ -163,44 +164,48 @@ static int auth_client_output(struct auth_client_connection *conn)
 }
 
 static const char *
-auth_line_hide_pass(struct auth_client_connection *conn, const char *line)
+auth_line_hide_pass(struct auth_client_connection *conn, const char *const *args)
 {
-       const char *p, *p2;
-
-       p = strstr(line, "\tresp=");
-       if (p == NULL)
-               return line;
-       p += 6;
-
-       if (conn->auth->set->debug_passwords)
-               return t_strconcat(line, AUTH_DEBUG_SENSITIVE_SUFFIX, NULL);
+       string_t *newline = t_str_new(128);
+       for (const char *const *arg = args; *arg != NULL; arg++) {
+               if (arg != args)
+                       str_append_c(newline, '\t');
+               if (str_begins_with(*arg, "resp=")) {
+                       if (conn->auth->set->debug_passwords) {
+                               str_append_tabescaped(newline, *arg);
+                               str_append(newline, AUTH_DEBUG_SENSITIVE_SUFFIX);
+                               break;
+                       } else {
+                               str_append_tabescaped(newline, "resp="PASSWORD_HIDDEN_STR);
+                       }
+               } else {
+                       str_append_tabescaped(newline, *arg);
+               }
+       }
 
-       p2 = strchr(p, '\t');
-       return t_strconcat(t_strdup_until(line, p), PASSWORD_HIDDEN_STR,
-                          p2, NULL);
+       return str_c(newline);
 }
 
 static const char *
-cont_line_hide_pass(struct auth_client_connection *conn, const char *line)
+cont_line_hide_pass(struct auth_client_connection *conn, const char *const *args)
 {
-       const char *p;
-
-       if (conn->auth->set->debug_passwords)
-               return t_strconcat(line, AUTH_DEBUG_SENSITIVE_SUFFIX, NULL);
+       if (args[1] == NULL)
+               return args[0];
 
-       p = strchr(line, '\t');
-       if (p == NULL)
-               return line;
+       if (conn->auth->set->debug_passwords) {
+               return t_strconcat(t_strarray_join(args, "\t"),
+                                  AUTH_DEBUG_SENSITIVE_SUFFIX, NULL);
+       }
 
-       return t_strconcat(t_strdup_until(line, p), PASSWORD_HIDDEN_STR, NULL);
+       return t_strconcat(args[0], PASSWORD_HIDDEN_STR, NULL);
 }
 
 static int
-auth_client_cancel(struct auth_client_connection *conn, const char *line)
+auth_client_cancel(struct auth_client_connection *conn, const char *const *args)
 {
        unsigned int client_id;
 
-       if (str_to_uint(line, &client_id) < 0) {
+       if (args[0] == NULL || str_to_uint(args[0], &client_id) < 0) {
                e_error(conn->conn.event, "BUG: Authentication client sent broken CANCEL");
                return -1;
        }
@@ -210,29 +215,30 @@ auth_client_cancel(struct auth_client_connection *conn, const char *line)
 }
 
 static int
-auth_client_handle_line(struct auth_client_connection *conn, const char *line)
+auth_client_input_args(struct connection *conn, const char *const *args)
 {
-       const char *args;
-
-       if (str_begins(line, "AUTH\t", &args)) {
-               e_debug(conn->conn.event, "client in: %s",
-                       auth_line_hide_pass(conn, line));
-               return auth_request_handler_auth_begin(conn->request_handler,
-                                                      args);
+       struct auth_client_connection *aconn =
+               container_of(conn, struct auth_client_connection, conn);
+
+       if (strcmp(args[0], "AUTH") == 0) {
+               e_debug(conn->event, "client in: %s",
+                       auth_line_hide_pass(aconn, args));
+               return auth_request_handler_auth_begin(aconn->request_handler,
+                                                      args + 1);
        }
-       if (str_begins(line, "CONT\t", &args)) {
-               e_debug(conn->conn.event, "client in: %s",
-                       cont_line_hide_pass(conn, line));
-               return auth_request_handler_auth_continue(conn->request_handler,
-                                                         args);
+       if (strcmp(args[0], "CONT") == 0) {
+               e_debug(conn->event, "client in: %s",
+                       cont_line_hide_pass(aconn, args));
+               return auth_request_handler_auth_continue(aconn->request_handler,
+                                                         args + 1);
        }
-       if (str_begins(line, "CANCEL\t", &args)) {
-               e_debug(conn->conn.event, "client in: %s", line);
-               return auth_client_cancel(conn, args);
+       if (strcmp(args[0], "CANCEL") == 0) {
+               e_debug(conn->event, "client in: %s", args[1]);
+               return auth_client_cancel(aconn, args + 1);
        }
 
-       e_error(conn->conn.event, "BUG: Authentication client sent unknown command: %s",
-               str_sanitize(line, 80));
+       e_error(conn->event, "BUG: Authentication client sent unknown command: %s",
+               str_sanitize(args[0], 80));
        return -1;
 }
 
@@ -287,7 +293,6 @@ static void auth_client_input(struct auth_client_connection *conn)
 {
        const char *args;
        char *line;
-       int ret;
 
        switch (i_stream_read(conn->conn.input)) {
        case 0:
@@ -352,9 +357,16 @@ static void auth_client_input(struct auth_client_connection *conn)
 
        conn->refcount++;
        while ((line = i_stream_next_line(conn->conn.input)) != NULL) {
+               int ret;
                T_BEGIN {
-                       ret = auth_client_handle_line(conn, line);
+                       const char *const *args = t_strsplit_tabescaped(line);
                        safe_memset(line, 0, strlen(line));
+                       if (args[0] == NULL) {
+                               e_error(conn->conn.event, "BUG: Authentication client sent empty line");
+                               ret = -1;
+                       } else {
+                               ret = auth_client_input_args(&conn->conn, args);
+                       }
                } T_END;
 
                if (ret < 1) {
index a62ed84817c5b68741b0262a00546ef14740288f..00311f970ab6da155fbc62de0167b4eea9205bda 100644 (file)
@@ -518,11 +518,11 @@ auth_penalty_callback(unsigned int penalty, struct auth_request *request)
 }
 
 int auth_request_handler_auth_begin(struct auth_request_handler *handler,
-                                   const char *args_str)
+                                   const char *const *args)
 {
        const struct mech_module *mech;
        struct auth_request *request;
-       const char *const *args, *name, *arg, *initial_resp;
+       const char *name, *arg, *initial_resp;
        void *initial_resp_data;
        unsigned int id;
        buffer_t *buf;
@@ -530,7 +530,6 @@ int auth_request_handler_auth_begin(struct auth_request_handler *handler,
        i_assert(!handler->destroyed);
 
        /* <id> <mechanism> [...] */
-       args = t_strsplit_tabescaped(args_str);
        if (args[0] == NULL || args[1] == NULL ||
            str_to_uint(args[0], &id) < 0 || id == 0) {
                e_error(handler->conn->conn.event,
@@ -688,15 +687,13 @@ int auth_request_handler_auth_begin(struct auth_request_handler *handler,
 }
 
 int auth_request_handler_auth_continue(struct auth_request_handler *handler,
-                                      const char *args_str)
+                                      const char *const *args)
 {
        struct auth_request *request;
-       const char *const *args;
        size_t data_len;
        buffer_t *buf;
        unsigned int id;
 
-       args = t_strsplit_tabescaped(args_str);
        if (args[0] == NULL || str_to_uint(args[0], &id) < 0) {
                e_error(handler->conn->conn.event,
                        "BUG: Authentication client sent broken CONT request");
@@ -717,6 +714,12 @@ int auth_request_handler_auth_continue(struct auth_request_handler *handler,
                                               "Unexpected continuation");
                return 1;
        }
+       if (args[1] == NULL) {
+               e_error(handler->conn->conn.event,
+                       "BUG: Authentication client sent broken CONT request");
+               return -1;
+       }
+
        request->accept_cont_input = FALSE;
 
        data_len = strlen(args[1]);
index 6a62466c139258643f66355479df7b11886b67e3..0f040ba45cc0e10689b25c1a4c2d7ddf46066fa3 100644 (file)
@@ -42,9 +42,9 @@ void auth_request_handler_set(struct auth_request_handler *handler,
                              unsigned int client_pid);
 
 int auth_request_handler_auth_begin(struct auth_request_handler *handler,
-                                   const char *args_str);
+                                   const char *const *args);
 int auth_request_handler_auth_continue(struct auth_request_handler *handler,
-                                      const char *args_str);
+                                      const char *const *args);
 void auth_request_handler_reply(struct auth_request *request,
                                enum auth_client_result result,
                                const void *reply, size_t reply_size);