]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Use auth-stream API to build all TAB-delimited strings to make sure strings
authorTimo Sirainen <tss@iki.fi>
Sun, 9 Mar 2008 10:37:26 +0000 (12:37 +0200)
committerTimo Sirainen <tss@iki.fi>
Sun, 9 Mar 2008 10:37:26 +0000 (12:37 +0200)
are escaped properly where necessary.

--HG--
branch : HEAD

14 files changed:
src/auth/auth-client-connection.c
src/auth/auth-master-connection.c
src/auth/auth-master-connection.h
src/auth/auth-request-handler.c
src/auth/auth-request-handler.h
src/auth/auth-request.c
src/auth/auth-request.h
src/auth/auth-stream.c
src/auth/auth-stream.h
src/auth/auth-worker-client.c
src/auth/auth-worker-server.c
src/auth/auth-worker-server.h
src/auth/passdb-blocking.c
src/auth/userdb-blocking.c

index 9ad7dbe972d60bd7035b6e4516c6d249ba10867a..ed8fabbfe5d3e1e31a7329ac652579e6861a5f82 100644 (file)
@@ -9,6 +9,7 @@
 #include "str.h"
 #include "str-sanitize.h"
 #include "safe-memset.h"
+#include "auth-stream.h"
 #include "auth-request-handler.h"
 #include "auth-client-interface.h"
 #include "auth-client-connection.h"
@@ -63,7 +64,7 @@ static void auth_client_send(struct auth_client_connection *conn,
        }
 }
 
-static void auth_callback(const char *reply,
+static void auth_callback(struct auth_stream_reply *reply,
                          struct auth_client_connection *conn)
 {
        if (reply == NULL) {
@@ -72,7 +73,7 @@ static void auth_callback(const char *reply,
                return;
        }
 
-       auth_client_send(conn, reply);
+       auth_client_send(conn, auth_stream_reply_export(reply));
 }
 
 static bool
index de0016d8ebfb692fea3f3f89431d660e0bd6dd1e..2601dc5a55088142aa704d02299311c0591b7d00 100644 (file)
@@ -29,16 +29,20 @@ struct master_userdb_request {
        struct auth_request *auth_request;
 };
 
-void auth_master_request_callback(const char *reply, void *context)
+void auth_master_request_callback(struct auth_stream_reply *reply,
+                                 void *context)
 {
        struct auth_master_connection *conn = context;
        struct const_iovec iov[2];
+       const char *reply_str;
+
+       reply_str = auth_stream_reply_export(reply);
 
        if (conn->listener->auth->verbose_debug)
-               i_info("master out: %s", reply);
+               i_info("master out: %s", reply_str);
 
-       iov[0].iov_base = reply;
-       iov[0].iov_len = strlen(reply);
+       iov[0].iov_base = reply_str;
+       iov[0].iov_len = strlen(reply_str);
        iov[1].iov_base = "\n";
        iov[1].iov_len = 1;
 
index 4ddc8ece3740f86073bc4b0bedc30100c821ea04..637c3bef009b2cae1b8ca83222d31562fa3a8a88 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef AUTH_MASTER_CONNECTION_H
 #define AUTH_MASTER_CONNECTION_H
 
+struct auth_stream_reply;
+
 struct auth_master_connection {
        struct auth_master_listener *listener;
        int refcount;
@@ -24,6 +26,7 @@ void auth_master_connection_unref(struct auth_master_connection **conn);
 void auth_master_connection_send_handshake(struct auth_master_connection *conn);
 void auth_master_connections_send_handshake(void);
 
-void auth_master_request_callback(const char *reply, void *context);
+void auth_master_request_callback(struct auth_stream_reply *reply,
+                                 void *context);
 
 #endif
index 22895d8431f1e47f5b403ccb6788527c7547448c..6568b46393b94a8b386aca64377fccd5dd9cee83 100644 (file)
@@ -116,53 +116,51 @@ void auth_request_handler_check_timeouts(struct auth_request_handler *handler)
        hash_iterate_deinit(&iter);
 }
 
-static const char *get_client_extra_fields(struct auth_request *request)
+static void get_client_extra_fields(struct auth_request *request,
+                                   struct auth_stream_reply *reply)
 {
-       string_t *str;
        const char **fields, *extra_fields;
        unsigned int src, dest;
        bool seen_pass = FALSE;
 
        if (auth_stream_is_empty(request->extra_fields))
-               return NULL;
+               return;
 
        extra_fields = auth_stream_reply_export(request->extra_fields);
 
        if (!request->proxy) {
                /* we only wish to remove all fields prefixed with "userdb_" */
-               if (strstr(extra_fields, "userdb_") == NULL)
-                       return extra_fields;
+               if (strstr(extra_fields, "userdb_") == NULL) {
+                       auth_stream_reply_import(reply, extra_fields);
+                       return;
+               }
        }
 
-       str = t_str_new(128);
        fields = t_strsplit(extra_fields, "\t");
        for (src = dest = 0; fields[src] != NULL; src++) {
                if (strncmp(fields[src], "userdb_", 7) != 0) {
-                       if (str_len(str) > 0)
-                               str_append_c(str, '\t');
                        if (!seen_pass && strncmp(fields[src], "pass=", 5) == 0)
                                seen_pass = TRUE;
-                       str_append(str, fields[src]);
+                       auth_stream_reply_import(reply, fields[src]);
                }
        }
 
        if (request->proxy && !seen_pass && request->mech_password != NULL) {
                /* we're proxying - send back the password that was
                   sent by user (not the password in passdb). */
-               str_printfa(str, "\tpass=%s", request->mech_password);
+               auth_stream_reply_add(reply, "pass", request->mech_password);
        }
-
-       return str_len(str) == 0 ? NULL : str_c(str);
 }
 
 static void
-auth_request_handle_failure(struct auth_request *request, const char *str)
+auth_request_handle_failure(struct auth_request *request,
+                           struct auth_stream_reply *reply)
 {
         struct auth_request_handler *handler = request->context;
 
        if (request->delayed_failure) {
                /* we came here from flush_failures() */
-               handler->callback(str, handler->context);
+               handler->callback(reply, handler->context);
                return;
        }
 
@@ -173,7 +171,7 @@ auth_request_handle_failure(struct auth_request *request, const char *str)
        if (request->no_failure_delay) {
                /* passdb specifically requested not to delay the
                   reply. */
-               handler->callback(str, handler->context);
+               handler->callback(reply, handler->context);
                auth_request_unref(&request);
                return;
        }
@@ -194,56 +192,56 @@ auth_request_handle_failure(struct auth_request *request, const char *str)
 
 static void auth_callback(struct auth_request *request,
                          enum auth_client_result result,
-                         const void *reply, size_t reply_size)
+                         const void *auth_reply, size_t reply_size)
 {
         struct auth_request_handler *handler = request->context;
+       struct auth_stream_reply *reply;
        string_t *str;
-       const char *fields;
 
-       str = t_str_new(128 + MAX_BASE64_ENCODED_SIZE(reply_size));
+       reply = auth_stream_reply_init(pool_datastack_create());
        switch (result) {
        case AUTH_CLIENT_RESULT_CONTINUE:
-               str_printfa(str, "CONT\t%u\t", request->id);
-               base64_encode(reply, reply_size, str);
-                request->accept_input = TRUE;
-               handler->callback(str_c(str), handler->context);
+               auth_stream_reply_add(reply, "CONT", NULL);
+               auth_stream_reply_add(reply, NULL, dec2str(request->id));
+
+               str = t_str_new(MAX_BASE64_ENCODED_SIZE(reply_size));
+               base64_encode(auth_reply, reply_size, str);
+               auth_stream_reply_add(reply, NULL, str_c(str));
+
+               request->accept_input = TRUE;
+               handler->callback(reply, handler->context);
                break;
        case AUTH_CLIENT_RESULT_SUCCESS:
                auth_request_proxy_finish(request, TRUE);
 
-               str_printfa(str, "OK\t%u\tuser=%s", request->id, request->user);
+               auth_stream_reply_add(reply, "OK", NULL);
+               auth_stream_reply_add(reply, NULL, dec2str(request->id));
+               auth_stream_reply_add(reply, "user", request->user);
                if (reply_size > 0) {
-                       str_append(str, "\tresp=");
-                       base64_encode(reply, reply_size, str);
-               }
-               fields = get_client_extra_fields(request);
-               if (fields != NULL) {
-                       str_append_c(str, '\t');
-                       str_append(str, fields);
+                       str = t_str_new(MAX_BASE64_ENCODED_SIZE(reply_size));
+                       base64_encode(auth_reply, reply_size, str);
+                       auth_stream_reply_add(reply, "resp", str_c(str));
                }
-
+               get_client_extra_fields(request, reply);
                if (request->no_login || handler->master_callback == NULL) {
                        /* this request doesn't have to wait for master
                           process to pick it up. delete it */
                        auth_request_handler_remove(handler, request);
                }
-               handler->callback(str_c(str), handler->context);
+               handler->callback(reply, handler->context);
                break;
        case AUTH_CLIENT_RESULT_FAILURE:
                auth_request_proxy_finish(request, FALSE);
 
-               str_printfa(str, "FAIL\t%u", request->id);
+               auth_stream_reply_add(reply, "FAIL", NULL);
+               auth_stream_reply_add(reply, NULL, dec2str(request->id));
                if (request->user != NULL)
-                       str_printfa(str, "\tuser=%s", request->user);
+                       auth_stream_reply_add(reply, "user", request->user);
                if (request->internal_failure)
-                       str_append(str, "\ttemp");
-               fields = get_client_extra_fields(request);
-               if (fields != NULL) {
-                       str_append_c(str, '\t');
-                       str_append(str, fields);
-               }
+                       auth_stream_reply_add(reply, "temp", NULL);
+               get_client_extra_fields(request, reply);
 
-               auth_request_handle_failure(request, str_c(str));
+               auth_request_handle_failure(request, reply);
                break;
        }
        /* NOTE: request may be destroyed now */
@@ -255,13 +253,16 @@ static void auth_request_handler_auth_fail(struct auth_request_handler *handler,
                                           struct auth_request *request,
                                           const char *reason)
 {
-       string_t *reply = t_str_new(64);
+       struct auth_stream_reply *reply;
 
        auth_request_log_info(request, request->mech->mech_name, "%s", reason);
 
-       str_printfa(reply, "FAIL\t%u\treason=%s", request->id, reason);
-       handler->callback(str_c(reply), handler->context);
+       reply = auth_stream_reply_init(pool_datastack_create());
+       auth_stream_reply_add(reply, "FAIL", NULL);
+       auth_stream_reply_add(reply, NULL, dec2str(request->id));
+       auth_stream_reply_add(reply, "reason", reason);
 
+       handler->callback(reply, handler->context);
        auth_request_handler_remove(handler, request);
 }
 
@@ -391,10 +392,13 @@ bool auth_request_handler_auth_continue(struct auth_request_handler *handler,
 
        request = hash_lookup(handler->requests, POINTER_CAST(id));
        if (request == NULL) {
-               string_t *reply = t_str_new(64);
+               struct auth_stream_reply *reply;
 
-               str_printfa(reply, "FAIL\t%u\treason=Timeouted", id);
-               handler->callback(str_c(reply), handler->context);
+               reply = auth_stream_reply_init(pool_datastack_create());
+               auth_stream_reply_add(reply, "FAIL", NULL);
+               auth_stream_reply_add(reply, NULL, dec2str(id));
+               auth_stream_reply_add(reply, "reason", "Timeouted");
+               handler->callback(reply, handler->context);
                return TRUE;
        }
 
@@ -425,8 +429,7 @@ static void userdb_callback(enum userdb_result result,
                            struct auth_request *request)
 {
         struct auth_request_handler *handler = request->context;
-       struct auth_stream_reply *reply = request->userdb_reply;
-       string_t *str;
+       struct auth_stream_reply *reply;
 
        i_assert(request->state == AUTH_REQUEST_STATE_USERDB);
 
@@ -435,24 +438,29 @@ static void userdb_callback(enum userdb_result result,
        if (request->userdb_lookup_failed)
                result = USERDB_RESULT_INTERNAL_FAILURE;
 
-       str = t_str_new(256);
+       reply = auth_stream_reply_init(pool_datastack_create());
        switch (result) {
        case USERDB_RESULT_INTERNAL_FAILURE:
-               str_printfa(str, "FAIL\t%u", request->id);
+               auth_stream_reply_add(reply, "FAIL", NULL);
+               auth_stream_reply_add(reply, NULL, dec2str(request->id));
                break;
        case USERDB_RESULT_USER_UNKNOWN:
-               str_printfa(str, "NOTFOUND\t%u", request->id);
+               auth_stream_reply_add(reply, "NOTFOUND", NULL);
+               auth_stream_reply_add(reply, NULL, dec2str(request->id));
                break;
        case USERDB_RESULT_OK:
+               auth_stream_reply_add(reply, "USER", NULL);
+               auth_stream_reply_add(reply, NULL, dec2str(request->id));
                if (request->master_user != NULL) {
-                       auth_stream_reply_add(reply, "master_user",
+                       auth_stream_reply_add(request->userdb_reply,
+                                             "master_user",
                                              request->master_user);
                }
-               str_printfa(str, "USER\t%u\t", request->id);
-               str_append(str, auth_stream_reply_export(reply));
+               auth_stream_reply_import(reply,
+                       auth_stream_reply_export(request->userdb_reply));
                break;
        }
-       handler->master_callback(str_c(str), request->master);
+       handler->master_callback(reply, request->master);
 
        auth_master_connection_unref(&request->master);
        auth_request_unref(&request);
@@ -465,16 +473,17 @@ void auth_request_handler_master_request(struct auth_request_handler *handler,
                                         unsigned int client_id)
 {
        struct auth_request *request;
-       string_t *reply;
+       struct auth_stream_reply *reply;
 
-       reply = t_str_new(64);
+       reply = auth_stream_reply_init(pool_datastack_create());
 
        request = hash_lookup(handler->requests, POINTER_CAST(client_id));
        if (request == NULL) {
                i_error("Master request %u.%u not found",
                        handler->client_pid, client_id);
-               str_printfa(reply, "NOTFOUND\t%u", id);
-               handler->master_callback(str_c(reply), master);
+               auth_stream_reply_add(reply, "NOTFOUND", NULL);
+               auth_stream_reply_add(reply, NULL, dec2str(id));
+               handler->master_callback(reply, master);
                return;
        }
 
@@ -485,8 +494,9 @@ void auth_request_handler_master_request(struct auth_request_handler *handler,
            !request->successful) {
                i_error("Master requested unfinished authentication request "
                        "%u.%u", handler->client_pid, client_id);
-               str_printfa(reply, "NOTFOUND\t%u", id);
-               handler->master_callback(str_c(reply), master);
+               auth_stream_reply_add(reply, "NOTFOUND", NULL);
+               auth_stream_reply_add(reply, NULL, dec2str(id));
+               handler->master_callback(reply, master);
                auth_request_unref(&request);
        } else {
                /* the request isn't being referenced anywhere anymore,
index 40612c605a15506d553b69d54a4efbb359496cc5..d81abfb8f3c75dc72197fa1c750072cb8202b807 100644 (file)
@@ -3,8 +3,10 @@
 
 struct auth_request;
 struct auth_master_connection;
+struct auth_stream_reply;
 
-typedef void auth_request_callback_t(const char *reply, void *context);
+typedef void
+auth_request_callback_t(struct auth_stream_reply *reply, void *context);
 
 struct auth_request_handler *
 auth_request_handler_create(struct auth *auth,
@@ -12,7 +14,7 @@ auth_request_handler_create(struct auth *auth,
                            auth_request_callback_t *master_callback);
 #ifdef CONTEXT_TYPE_SAFETY
 #  define auth_request_handler_create(auth, callback, context, master_callback)\
-       ({(void)(1 ? 0 : callback((const char *)NULL, context)); \
+       ({(void)(1 ? 0 : callback((struct auth_stream_reply *)NULL, context)); \
          auth_request_handler_create(auth, \
                (auth_request_callback_t *)callback, context, \
                master_callback); })
index a18aef2fa140e42bcea6a4a6315c27dc1dd6053f..e4b6da7f9f62e6349653e9b1717dd11f491bd034 100644 (file)
@@ -115,38 +115,37 @@ void auth_request_unref(struct auth_request **_request)
                pool_unref(&request->pool);
 }
 
-void auth_request_export(struct auth_request *request, string_t *str)
+void auth_request_export(struct auth_request *request,
+                        struct auth_stream_reply *reply)
 {
-       str_append(str, "user=");
-       str_append(str, request->user);
-       str_append(str, "\tservice=");
-       str_append(str, request->service);
+       auth_stream_reply_add(reply, "user", request->user);
+       auth_stream_reply_add(reply, "service", request->service);
 
         if (request->master_user != NULL) {
-                str_append(str, "\tmaster_user=");
-                str_append(str, request->master_user);
+               auth_stream_reply_add(reply, "master_user",
+                                     request->master_user);
         }
 
        if (request->local_ip.family != 0) {
-               str_append(str, "\tlip=");
-               str_append(str, net_ip2addr(&request->local_ip));
+               auth_stream_reply_add(reply, "lip",
+                                     net_ip2addr(&request->local_ip));
        }
        if (request->remote_ip.family != 0) {
-               str_append(str, "\trip=");
-               str_append(str, net_ip2addr(&request->remote_ip));
+               auth_stream_reply_add(reply, "rip",
+                                     net_ip2addr(&request->remote_ip));
        }
        if (request->local_port != 0) {
-               str_append(str, "\tlport=");
-               str_printfa(str, "%u", request->local_port);
+               auth_stream_reply_add(reply, "lport",
+                                     dec2str(request->local_port));
        }
        if (request->remote_port != 0) {
-               str_append(str, "\trport=");
-               str_printfa(str, "%u", request->remote_port);
+               auth_stream_reply_add(reply, "rport",
+                                     dec2str(request->remote_port));
        }
        if (request->secured)
-               str_append(str, "\tsecured=1");
+               auth_stream_reply_add(reply, "secured", "1");
        if (request->skip_password_check)
-               str_append(str, "\tskip_password_check=1");
+               auth_stream_reply_add(reply, "skip_password_check", "1");
 }
 
 bool auth_request_import(struct auth_request *request,
@@ -352,8 +351,10 @@ auth_request_handle_passdb_callback(enum passdb_result *result,
                        }
                }
        } else if (*result == PASSDB_RESULT_PASS_EXPIRED) {
-               if (request->extra_fields == NULL)
-                       request->extra_fields = auth_stream_reply_init(request);
+               if (request->extra_fields == NULL) {
+                       request->extra_fields =
+                               auth_stream_reply_init(request->pool);
+               }
                auth_stream_reply_add(request->extra_fields, "reason",
                                      "Password expired");
        } else if (request->passdb->next != NULL &&
@@ -632,12 +633,12 @@ static bool auth_request_lookup_user_cache(struct auth_request *request,
        if (*value == '\0') {
                /* negative cache entry */
                *result_r = USERDB_RESULT_USER_UNKNOWN;
-               *reply_r = auth_stream_reply_init(request);
+               *reply_r = auth_stream_reply_init(request->pool);
                return TRUE;
        }
 
        *result_r = USERDB_RESULT_OK;
-       *reply_r = auth_stream_reply_init(request);
+       *reply_r = auth_stream_reply_init(request->pool);
        auth_stream_reply_import(*reply_r, value);
        return TRUE;
 }
@@ -994,7 +995,7 @@ static void auth_request_set_reply_field(struct auth_request *request,
        }
 
        if (request->extra_fields == NULL)
-               request->extra_fields = auth_stream_reply_init(request);
+               request->extra_fields = auth_stream_reply_init(request->pool);
        auth_stream_reply_add(request->extra_fields, name, value);
 }
 
@@ -1087,7 +1088,7 @@ void auth_request_set_field(struct auth_request *request,
                /* we'll need to get this field stored into cache */
                if (request->extra_cache_fields == NULL) {
                        request->extra_cache_fields =
-                               auth_stream_reply_init(request);
+                               auth_stream_reply_init(request->pool);
                }
                auth_stream_reply_add(request->extra_cache_fields, name, value);
        }
@@ -1117,7 +1118,7 @@ void auth_request_set_fields(struct auth_request *request,
 
 void auth_request_init_userdb_reply(struct auth_request *request)
 {
-       request->userdb_reply = auth_stream_reply_init(request);
+       request->userdb_reply = auth_stream_reply_init(request->pool);
        auth_stream_reply_add(request->userdb_reply, NULL, request->user);
 }
 
index 69b9d112a549336183b32fcf058b57c7ff59ab04..050a6db7c881ab2a76c20a8c6a479e340e728a4e 100644 (file)
@@ -111,7 +111,8 @@ void auth_request_success(struct auth_request *request,
 void auth_request_fail(struct auth_request *request);
 void auth_request_internal_failure(struct auth_request *request);
 
-void auth_request_export(struct auth_request *request, string_t *str);
+void auth_request_export(struct auth_request *request,
+                        struct auth_stream_reply *reply);
 bool auth_request_import(struct auth_request *request,
                         const char *key, const char *value);
 
index 6210d33d5fce83fc4ddb0bf29e6c371e63ef0c7c..0611888b78d42865105a7c2a5334d485f1a74bce 100644 (file)
@@ -10,12 +10,12 @@ struct auth_stream_reply {
        string_t *str;
 };
 
-struct auth_stream_reply *auth_stream_reply_init(struct auth_request *request)
+struct auth_stream_reply *auth_stream_reply_init(pool_t pool)
 {
        struct auth_stream_reply *reply;
 
-       reply = p_new(request->pool, struct auth_stream_reply, 1);
-       reply->str = str_new(request->pool, 256);
+       reply = p_new(pool, struct auth_stream_reply, 1);
+       reply->str = str_new(pool, 256);
        return reply;
 }
 
@@ -110,3 +110,8 @@ const char *const *auth_stream_split(struct auth_stream_reply *reply)
 {
        return t_strsplit(str_c(reply->str), "\t");
 }
+
+string_t *auth_stream_reply_get_str(struct auth_stream_reply *reply)
+{
+       return reply->str;
+}
index c5733a118130906d074e821b7611938cf7fbc1b7..51cb329fd602b046e72e06aabc225e41bbc1adca 100644 (file)
@@ -3,7 +3,7 @@
 
 struct auth_request;
 
-struct auth_stream_reply *auth_stream_reply_init(struct auth_request *request);
+struct auth_stream_reply *auth_stream_reply_init(pool_t pool);
 void auth_stream_reply_add(struct auth_stream_reply *reply,
                           const char *key, const char *value);
 void auth_stream_reply_reset(struct auth_stream_reply *reply);
@@ -14,5 +14,6 @@ const char *auth_stream_reply_export(struct auth_stream_reply *reply);
 bool auth_stream_is_empty(struct auth_stream_reply *reply);
 
 const char *const *auth_stream_split(struct auth_stream_reply *reply);
+string_t *auth_stream_reply_get_str(struct auth_stream_reply *reply);
 
 #endif
index 2a4f77c8441259bfff11baba3b4998198d2aeee1..89cf0b28da304d6a3d0f9f7460e1c9cb56179f14 100644 (file)
@@ -71,56 +71,58 @@ worker_auth_request_new(struct auth_worker_client *client, unsigned int id,
        return auth_request;
 }
 
-static void add_userdb_replies(string_t *str, const char *data)
+static void
+add_userdb_replies(struct auth_stream_reply *reply,
+                  struct auth_stream_reply *userdb_reply)
 {
        const char *const *tmp;
 
-       tmp = t_strsplit(data, "\t");
+       tmp = auth_stream_split(userdb_reply);
        i_assert(*tmp != NULL);
        /* first field is the user name */
        tmp++;
-       for (; *tmp != NULL; tmp++)
-               str_printfa(str, "\tuserdb_%s", *tmp);
+       for (; *tmp != NULL; tmp++) {
+               auth_stream_reply_import(reply,
+                                        t_strconcat("userdb_", *tmp, NULL));
+       }
 }
 
 static void verify_plain_callback(enum passdb_result result,
                                  struct auth_request *request)
 {
        struct auth_worker_client *client = request->context;
+       struct auth_stream_reply *reply;
        string_t *str;
 
        if (request->passdb_failure && result == PASSDB_RESULT_OK)
                result = PASSDB_RESULT_PASSWORD_MISMATCH;
 
-       str = t_str_new(64);
-       str_printfa(str, "%u\t", request->id);
+       reply = auth_stream_reply_init(pool_datastack_create());
+       auth_stream_reply_add(reply, NULL, dec2str(request->id));
 
-       if (result == PASSDB_RESULT_INTERNAL_FAILURE)
-               str_printfa(str, "FAIL\t%d", result);
+       if (result == PASSDB_RESULT_OK)
+               auth_stream_reply_add(reply, "OK", NULL);
        else {
-               if (result != PASSDB_RESULT_OK)
-                       str_printfa(str, "FAIL\t%d\t", result);
-               else
-                       str_append(str, "OK\t");
-               str_append(str, request->user);
-               str_append_c(str, '\t');
-               if (request->passdb_password != NULL)
-                       str_append(str, request->passdb_password);
+               auth_stream_reply_add(reply, "FAIL", NULL);
+               auth_stream_reply_add(reply, NULL,
+                                     t_strdup_printf("%d", result));
+       }
+       if (result != PASSDB_RESULT_INTERNAL_FAILURE) {
+               auth_stream_reply_add(reply, NULL, request->user);
+               auth_stream_reply_add(reply, NULL,
+                                     request->passdb_password == NULL ? "" :
+                                     request->passdb_password);
                if (request->no_password)
-                       str_append(str, "\tnopassword");
-               if (request->userdb_reply != NULL) {
-                       const char *data =
-                               auth_stream_reply_export(request->userdb_reply);
-                       add_userdb_replies(str, data);
-               }
+                       auth_stream_reply_add(reply, "nopassword", NULL);
+               if (request->userdb_reply != NULL)
+                       add_userdb_replies(reply, request->userdb_reply);
                if (request->extra_fields != NULL) {
-                       const char *field =
+                       const char *fields =
                                auth_stream_reply_export(request->extra_fields);
-
-                       str_append_c(str, '\t');
-                       str_append(str, field);
+                       auth_stream_reply_import(reply, fields);
                }
        }
+       str = auth_stream_reply_get_str(reply);
        str_append_c(str, '\n');
        o_stream_send(client->output, str_data(str), str_len(str));
 
@@ -189,32 +191,37 @@ lookup_credentials_callback(enum passdb_result result,
                            struct auth_request *request)
 {
        struct auth_worker_client *client = request->context;
+       struct auth_stream_reply *reply;
        string_t *str;
 
        if (request->passdb_failure && result == PASSDB_RESULT_OK)
                result = PASSDB_RESULT_PASSWORD_MISMATCH;
 
-       str = t_str_new(64);
-       str_printfa(str, "%u\t", request->id);
+       reply = auth_stream_reply_init(pool_datastack_create());
+       auth_stream_reply_add(reply, NULL, dec2str(request->id));
 
-       if (result != PASSDB_RESULT_OK)
-               str_printfa(str, "FAIL\t%d", result);
-       else {
-               str_printfa(str, "OK\t%s\t{%s.b64}", request->user,
-                           request->credentials_scheme);
+       if (result != PASSDB_RESULT_OK) {
+               auth_stream_reply_add(reply, "FAIL", NULL);
+               auth_stream_reply_add(reply, NULL,
+                                     t_strdup_printf("%d", result));
+       } else {
+               auth_stream_reply_add(reply, "OK", NULL);
+               auth_stream_reply_add(reply, NULL, request->user);
+
+               str = t_str_new(64);
+               str_printfa(str, "{%s.b64}", request->credentials_scheme);
                base64_encode(credentials, size, str);
-               str_append_c(str, '\t');
+               auth_stream_reply_add(reply, NULL, str_c(str));
+
                if (request->extra_fields != NULL) {
-                       const char *field =
+                       const char *fields =
                                auth_stream_reply_export(request->extra_fields);
-                       str_append(str, field);
-               }
-               if (request->userdb_reply != NULL) {
-                       const char *data =
-                               auth_stream_reply_export(request->userdb_reply);
-                       add_userdb_replies(str, data);
+                       auth_stream_reply_import(reply, fields);
                }
+               if (request->userdb_reply != NULL)
+                       add_userdb_replies(reply, request->userdb_reply);
        }
+       str = auth_stream_reply_get_str(reply);
        str_append_c(str, '\n');
        o_stream_send(client->output, str_data(str), str_len(str));
 
index a46b9d829374dd11cc98f2eff29b120a25d09f35..123911336a959ef77e222efbbf1dc4d5b8aa246b 100644 (file)
@@ -251,12 +251,13 @@ auth_worker_request_get(struct auth_worker_connection *conn)
        return request != NULL ? request : array_append_space(&conn->requests);
 }
 
-void auth_worker_call(struct auth_request *auth_request, const char *data,
+void auth_worker_call(struct auth_request *auth_request,
+                     struct auth_stream_reply *data,
                      auth_worker_callback_t *callback)
 {
        struct auth_worker_connection *conn;
        struct auth_worker_request *request;
-       const char *reply;
+       const char *reply, *data_str;
        struct const_iovec iov[3];
 
        conn = auth_worker_find_free();
@@ -276,10 +277,11 @@ void auth_worker_call(struct auth_request *auth_request, const char *data,
 
        i_assert(conn->requests_left > 0);
 
+       data_str = auth_stream_reply_export(data);
        iov[0].iov_base = t_strdup_printf("%d\t", ++conn->id_counter);
        iov[0].iov_len = strlen(iov[0].iov_base);
-       iov[1].iov_base = data;
-       iov[1].iov_len = strlen(data);
+       iov[1].iov_base = data_str;
+       iov[1].iov_len = strlen(data_str);
        iov[2].iov_base = "\n";
        iov[2].iov_len = 1;
 
index 3182e0c835429df89c0850ec3ec1c7e7f6fe3c92..f50ab4a3d6c837ae3f3994b6bdbbbe70092c0f8e 100644 (file)
@@ -2,11 +2,13 @@
 #define AUTH_WORKER_SERVER_H
 
 struct auth_request;
+struct auth_stream_reply;
 
 typedef void auth_worker_callback_t(struct auth_request *request,
                                    const char *reply);
 
-void auth_worker_call(struct auth_request *auth_request, const char *data,
+void auth_worker_call(struct auth_request *auth_request,
+                     struct auth_stream_reply *data,
                      auth_worker_callback_t *callback);
 
 void auth_worker_server_init(void);
index 4bba90600606516e838c4d4039916e24968c3e6c..b23209ea5a8b4e2999a0ec75bf400599f6bc1cf8 100644 (file)
@@ -70,18 +70,18 @@ verify_plain_callback(struct auth_request *request, const char *reply)
 
 void passdb_blocking_verify_plain(struct auth_request *request)
 {
-       string_t *str;
+       struct auth_stream_reply *reply;
 
        i_assert(auth_stream_is_empty(request->extra_fields) ||
                 request->master_user != NULL);
 
-       str = t_str_new(64);
-       str_printfa(str, "PASSV\t%u\t", request->passdb->id);
-       str_append(str, request->mech_password);
-       str_append_c(str, '\t');
-       auth_request_export(request, str);
+       reply = auth_stream_reply_init(pool_datastack_create());
+       auth_stream_reply_add(reply, "PASSV", NULL);
+       auth_stream_reply_add(reply, NULL, dec2str(request->passdb->id));
+       auth_stream_reply_add(reply, NULL, request->mech_password);
+       auth_request_export(request, reply);
 
-       auth_worker_call(request, str_c(str), verify_plain_callback);
+       auth_worker_call(request, reply, verify_plain_callback);
 }
 
 static void
@@ -109,17 +109,18 @@ lookup_credentials_callback(struct auth_request *request, const char *reply)
 
 void passdb_blocking_lookup_credentials(struct auth_request *request)
 {
-       string_t *str;
+       struct auth_stream_reply *reply;
 
        i_assert(auth_stream_is_empty(request->extra_fields) ||
                 request->master_user != NULL);
 
-       str = t_str_new(64);
-       str_printfa(str, "PASSL\t%u\t%s\t",
-                   request->passdb->id, request->credentials_scheme);
-       auth_request_export(request, str);
+       reply = auth_stream_reply_init(pool_datastack_create());
+       auth_stream_reply_add(reply, "PASSL", NULL);
+       auth_stream_reply_add(reply, NULL, dec2str(request->passdb->id));
+       auth_stream_reply_add(reply, NULL, request->credentials_scheme);
+       auth_request_export(request, reply);
 
-       auth_worker_call(request, str_c(str), lookup_credentials_callback);
+       auth_worker_call(request, reply, lookup_credentials_callback);
 }
 
 static void
@@ -134,12 +135,13 @@ set_credentials_callback(struct auth_request *request, const char *reply)
 void passdb_blocking_set_credentials(struct auth_request *request,
                                     const char *new_credentials)
 {
-       string_t *str;
+       struct auth_stream_reply *reply;
 
-       str = t_str_new(64);
-       str_printfa(str, "SETCRED\t%u\t%s\t",
-                   request->passdb->id, new_credentials);
-       auth_request_export(request, str);
+       reply = auth_stream_reply_init(pool_datastack_create());
+       auth_stream_reply_add(reply, "SETCRED", NULL);
+       auth_stream_reply_add(reply, NULL, dec2str(request->passdb->id));
+       auth_stream_reply_add(reply, NULL, new_credentials);
+       auth_request_export(request, reply);
 
-       auth_worker_call(request, str_c(str), set_credentials_callback);
+       auth_worker_call(request, reply, set_credentials_callback);
 }
index c7531ef02d0d64de59f69c914c0d13863194a7f7..c746fb4fdc33cf07e66564e9bc7db35557dbb9e6 100644 (file)
@@ -18,7 +18,7 @@ static void user_callback(struct auth_request *request, const char *reply)
                result = USERDB_RESULT_USER_UNKNOWN;
        else if (strncmp(reply, "OK\t", 3) == 0) {
                result = USERDB_RESULT_OK;
-               request->userdb_reply = auth_stream_reply_init(request);
+               request->userdb_reply = auth_stream_reply_init(request->pool);
                auth_stream_reply_import(request->userdb_reply, reply + 3);
        } else {
                result = USERDB_RESULT_INTERNAL_FAILURE;
@@ -30,11 +30,12 @@ static void user_callback(struct auth_request *request, const char *reply)
 
 void userdb_blocking_lookup(struct auth_request *request)
 {
-       string_t *str;
+       struct auth_stream_reply *reply;
 
-       str = t_str_new(64);
-       str_printfa(str, "USER\t%u\t", request->userdb->num);
-       auth_request_export(request, str);
+       reply = auth_stream_reply_init(pool_datastack_create());
+       auth_stream_reply_add(reply, "USER", NULL);
+       auth_stream_reply_add(reply, NULL, dec2str(request->userdb->num));
+       auth_request_export(request, reply);
 
-       auth_worker_call(request, str_c(str), user_callback);
+       auth_worker_call(request, reply, user_callback);
 }