]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
login processes: Added initial support for per-connection configuration.
authorTimo Sirainen <tss@iki.fi>
Thu, 14 May 2009 23:01:28 +0000 (19:01 -0400)
committerTimo Sirainen <tss@iki.fi>
Thu, 14 May 2009 23:01:28 +0000 (19:01 -0400)
--HG--
branch : HEAD

17 files changed:
src/imap-login/client-authenticate.c
src/imap-login/client-authenticate.h
src/imap-login/client.c
src/imap-login/imap-proxy.c
src/login-common/client-common.c
src/login-common/client-common.h
src/login-common/common.h
src/login-common/login-proxy.c
src/login-common/login-settings.c
src/login-common/login-settings.h
src/login-common/main.c
src/login-common/sasl-server.c
src/login-common/ssl-proxy-openssl.c
src/login-common/ssl-proxy.h
src/pop3-login/client-authenticate.c
src/pop3-login/client.c
src/pop3-login/pop3-proxy.c

index 9df8b001b1bf34b59857c3d908ef07ec8b42d1bc..5d7d44797dad8091ccfaa9d4bcc76ce7f3c2cbfa 100644 (file)
@@ -22,7 +22,7 @@
 
 #define IMAP_SERVICE_NAME "imap"
 
-const char *client_authenticate_get_capabilities(bool secured)
+const char *client_authenticate_get_capabilities(struct imap_client *client)
 {
        const struct auth_mech_desc *mech;
        unsigned int i, count;
@@ -36,7 +36,8 @@ const char *client_authenticate_get_capabilities(bool secured)
                   c) we allow insecure authentication
                */
                if ((mech[i].flags & MECH_SEC_PRIVATE) == 0 &&
-                   (secured || !login_settings->disable_plaintext_auth ||
+                   (client->common.secured ||
+                    !client->common.set->disable_plaintext_auth ||
                     (mech[i].flags & MECH_SEC_PLAINTEXT) == 0)) {
                        str_append_c(str, ' ');
                        str_append(str, "AUTH=");
@@ -165,7 +166,7 @@ static bool client_handle_args(struct imap_client *client,
                        master_user = value;
                else if (strcmp(key, "user") == 0) {
                        /* already handled in login-common */
-               } else if (login_settings->auth_debug)
+               } else if (client->common.set->auth_debug)
                        i_info("Ignoring unknown passdb extra field: %s", key);
        }
 
@@ -353,8 +354,8 @@ int cmd_authenticate(struct imap_client *client, const struct imap_arg *args)
        }
 
        if (!client->common.secured &&
-           strcmp(login_settings->ssl, "required") == 0) {
-               if (login_settings->verbose_auth) {
+           strcmp(client->common.set->ssl, "required") == 0) {
+               if (client->common.set->verbose_auth) {
                        client_syslog(&client->common, "Login failed: "
                                      "SSL required for authentication");
                }
@@ -387,8 +388,9 @@ int cmd_login(struct imap_client *client, const struct imap_arg *args)
        user = IMAP_ARG_STR(&args[0]);
        pass = IMAP_ARG_STR(&args[1]);
 
-       if (!client->common.secured && login_settings->disable_plaintext_auth) {
-               if (login_settings->verbose_auth) {
+       if (!client->common.secured &&
+           client->common.set->disable_plaintext_auth) {
+               if (client->common.set->verbose_auth) {
                        client_syslog(&client->common, "Login failed: "
                                      "Plaintext authentication disabled");
                }
index 9932aefa92fd783e22c9f761a2d5d70173bf8c70..b5e2d393d2f98e9ffaa23ea56836d965a5edb431 100644 (file)
@@ -8,7 +8,7 @@ struct imap_arg;
 #define IMAP_AUTHZ_FAILED_MSG \
        "["IMAP_RESP_CODE_AUTHZFAILED"] Authorization failed"
 
-const char *client_authenticate_get_capabilities(bool secured);
+const char *client_authenticate_get_capabilities(struct imap_client *client);
 
 int cmd_login(struct imap_client *client, const struct imap_arg *args);
 int cmd_authenticate(struct imap_client *client, const struct imap_arg *args);
index c38a8ce562afb1dcd99cfa835a5a6fc07a4fad63..79c7e780ee89890ea97023467040a7c339609c9c 100644 (file)
@@ -56,8 +56,8 @@ static void client_set_title(struct imap_client *client)
 {
        const char *addr;
 
-       if (!login_settings->verbose_proctitle ||
-           !login_settings->login_process_per_connection)
+       if (!client->common.set->verbose_proctitle ||
+           !client->common.set->login_process_per_connection)
                return;
 
        addr = net_ip2addr(&client->common.ip);
@@ -100,12 +100,12 @@ static const char *get_capability(struct imap_client *client, bool full)
 {
        const char *auths;
 
-       auths = client_authenticate_get_capabilities(client->common.secured);
-       return t_strconcat(full ? login_settings->capability_string :
+       auths = client_authenticate_get_capabilities(client);
+       return t_strconcat(full ? client->common.set->capability_string :
                           CAPABILITY_BANNER_STRING,
                           (ssl_initialized && !client->common.tls) ?
                           " STARTTLS" : "",
-                          login_settings->disable_plaintext_auth &&
+                          client->common.set->disable_plaintext_auth &&
                           !client->common.secured ?
                           " LOGINDISABLED" : "", auths, NULL);
 }
@@ -128,7 +128,7 @@ static void client_start_tls(struct imap_client *client)
                return;
 
        fd_ssl = ssl_proxy_new(client->common.fd, &client->common.ip,
-                              &client->common.proxy);
+                              client->common.set, &client->common.proxy);
        if (fd_ssl == -1) {
                client_send_line(client, "* BYE TLS initialization failed.");
                client_destroy(client,
@@ -431,7 +431,8 @@ void client_input(struct imap_client *client)
 
 void client_destroy_oldest(void)
 {
-       unsigned int max_connections = login_settings->login_max_connections;
+       unsigned int max_connections =
+               global_login_settings->login_max_connections;
        struct client *client;
        struct imap_client *destroy_buf[CLIENT_DESTROY_OLDEST_COUNT];
        unsigned int i, destroy_count;
@@ -474,7 +475,7 @@ static void client_send_greeting(struct imap_client *client)
        greet = t_str_new(128);
        str_append(greet, "* OK ");
        str_printfa(greet, "[CAPABILITY %s] ", get_capability(client, FALSE));
-       str_append(greet, login_settings->login_greeting);
+       str_append(greet, client->common.set->login_greeting);
 
        client_send_line(client, str_c(greet));
        client->greeting_sent = TRUE;
@@ -501,14 +502,16 @@ void client_set_auth_waiting(struct imap_client *client)
                            client_auth_waiting_timeout, client);
 }
 
-struct client *client_create(int fd, bool ssl, const struct ip_addr *local_ip,
-                            const struct ip_addr *ip)
+struct client *client_create(int fd, bool ssl, pool_t pool,
+                            const struct login_settings *set,
+                            const struct ip_addr *local_ip,
+                            const struct ip_addr *remote_ip)
 {
        struct imap_client *client;
 
        i_assert(fd != -1);
 
-       if (clients_get_count() >= login_settings->login_max_connections) {
+       if (clients_get_count() >= set->login_max_connections) {
                /* reached max. users count, kill few of the
                   oldest connections */
                client_destroy_oldest();
@@ -517,17 +520,19 @@ struct client *client_create(int fd, bool ssl, const struct ip_addr *local_ip,
        /* always use nonblocking I/O */
        net_set_nonblock(fd, TRUE);
 
-       client = i_new(struct imap_client, 1);
+       client = p_new(pool, struct imap_client, 1);
        client->created = ioloop_time;
        client->refcount = 1;
 
+       client->common.pool = pool;
+       client->common.set = set;
        client->common.local_ip = *local_ip;
-       client->common.ip = *ip;
+       client->common.ip = *remote_ip;
        client->common.fd = fd;
        client->common.tls = ssl;
        client->common.trusted = client_is_trusted(&client->common);
        client->common.secured = ssl || client->common.trusted ||
-               net_ip_compare(ip, local_ip);
+               net_ip_compare(remote_ip, local_ip);
 
        client_open_streams(client, fd);
        client->io = io_add(fd, IO_READ, client_input, client);
index fcd7737bcca962461d3bb22d391a3c3b88588ffe..a0c5d9dbde8a25e398c6e57461e07061d1e77d66 100644 (file)
@@ -128,7 +128,7 @@ client_send_capability_if_needed(struct imap_client *client, string_t *str,
        backend_capabilities =
                capabilities_strip_prelogin(t_strsplit(capability, " "));
        proxy_capabilities =
-               capabilities_strip_prelogin(t_strsplit(login_settings->capability_string, " "));
+               capabilities_strip_prelogin(t_strsplit(client->common.set->capability_string, " "));
 
        if (str_array_icmp(backend_capabilities, proxy_capabilities))
                return;
@@ -290,7 +290,7 @@ static int proxy_input_line(struct imap_client *client, const char *line)
                return 1;
        } else if (strncmp(line, "L ", 2) == 0) {
                line += 2;
-               if (login_settings->verbose_auth) {
+               if (client->common.set->verbose_auth) {
                        str = t_str_new(128);
                        str_printfa(str, "proxy(%s): Login failed to %s:%u",
                                    client->common.virtual_user,
index 32adfbe73894041af2c0b446e9f1d4c8defab63c..80836475d6136a68694d4c7e422fa5ff6c73bd0f 100644 (file)
@@ -90,7 +90,6 @@ get_var_expand_table(struct client *client)
                tab[12].value = ssl_proxy_get_security_string(client->proxy);
        }
        tab[13].value = dec2str(client->mail_pid);
-
        return tab;
 }
 
@@ -119,7 +118,8 @@ client_get_log_str(struct client *client, const char *msg)
        };
        const struct var_expand_table *var_expand_table;
        struct var_expand_table *tab;
-       const char *p, *const *e;
+       const char *p;
+       char *const *e;
        string_t *str;
 
        var_expand_table = get_var_expand_table(client);
@@ -128,7 +128,7 @@ client_get_log_str(struct client *client, const char *msg)
        memcpy(tab, static_tab, sizeof(static_tab));
 
        str = t_str_new(256);
-       for (e = login_settings->log_format_elements_split; *e != NULL; e++) {
+       for (e = client->set->log_format_elements_split; *e != NULL; e++) {
                for (p = *e; *p != '\0'; p++) {
                        if (*p != '%' || p[1] == '\0')
                                continue;
@@ -147,7 +147,7 @@ client_get_log_str(struct client *client, const char *msg)
        tab[1].value = msg;
        str_truncate(str, 0);
 
-       var_expand(str, login_settings->login_log_format, tab);
+       var_expand(str, client->set->login_log_format, tab);
        return str_c(str);
 }
 
@@ -171,10 +171,10 @@ bool client_is_trusted(struct client *client)
        struct ip_addr net_ip;
        unsigned int bits;
 
-       if (login_settings->login_trusted_networks == NULL)
+       if (client->set->login_trusted_networks == NULL)
                return FALSE;
 
-       net = t_strsplit_spaces(login_settings->login_trusted_networks, ", ");
+       net = t_strsplit_spaces(client->set->login_trusted_networks, ", ");
        for (; *net != NULL; net++) {
                if (net_parse_range(*net, &net_ip, &bits) < 0) {
                        i_error("login_trusted_networks: "
@@ -190,7 +190,7 @@ bool client_is_trusted(struct client *client)
 
 const char *client_get_extra_disconnect_reason(struct client *client)
 {
-       if (login_settings->ssl_require_client_cert && client->proxy != NULL) {
+       if (client->set->ssl_require_client_cert && client->proxy != NULL) {
                if (ssl_proxy_has_broken_client_cert(client->proxy))
                        return "(client sent an invalid cert)";
                if (!ssl_proxy_has_valid_client_cert(client->proxy))
@@ -203,7 +203,7 @@ const char *client_get_extra_disconnect_reason(struct client *client)
        /* some auth attempts without SSL/TLS */
        if (client->auth_tried_disabled_plaintext)
                return "(tried to use disabled plaintext auth)";
-       if (login_settings->ssl_require_client_cert)
+       if (client->set->ssl_require_client_cert)
                return "(cert required, client didn't start TLS)";
 
        return t_strdup_printf("(auth failed, %u attempts)",
index 02337c292607109934c48bc5e17cd76413baed74..4216ad89e24e23ee26b579dd8960dc97d61cc456 100644 (file)
 
 struct client {
        struct client *prev, *next;
+       pool_t pool;
 
        struct ip_addr local_ip;
        struct ip_addr ip;
        unsigned int local_port, remote_port;
        struct ssl_proxy *proxy;
+       const struct login_settings *set;
 
        int fd;
        struct istream *input;
@@ -45,8 +47,10 @@ struct client {
 
 extern struct client *clients;
 
-struct client *client_create(int fd, bool ssl, const struct ip_addr *local_ip,
-                            const struct ip_addr *ip);
+struct client *client_create(int fd, bool ssl, pool_t pool,
+                            const struct login_settings *set,
+                            const struct ip_addr *local_ip,
+                            const struct ip_addr *remote_ip);
 
 void client_link(struct client *client);
 void client_unlink(struct client *client);
index 0ae8a36acf7af3c1038e1678f4ee257f524dc2d4..899c1be0c3d7b0c2d7c78b382124c5522b6ec3ce 100644 (file)
@@ -19,6 +19,6 @@ extern bool closing_down;
 extern int anvil_fd;
 
 extern struct master_service *service;
-extern struct login_settings *login_settings;
+extern const struct login_settings *global_login_settings;
 
 #endif
index c8017fa421f46b232ff03fef3c6efe239370d33a..e9fe56d4e445351de96fe1645d0ba7d38f849069 100644 (file)
@@ -358,6 +358,7 @@ int login_proxy_starttls(struct login_proxy *proxy)
        io_remove(&proxy->server_io);
 
        fd = ssl_proxy_client_new(proxy->server_fd, &proxy->ip,
+                                 proxy->prelogin_client->set,
                                  login_proxy_ssl_handshaked, proxy,
                                  &proxy->ssl_proxy);
        if (fd < 0) {
index d5ce7c35a9b0c631b2bc9d6d450d54b14f3eece7..4547e56ed637b2d10b813c3510d389538b5efd52 100644 (file)
@@ -51,7 +51,7 @@ static struct setting_define login_setting_defines[] = {
 static struct login_settings login_default_settings = {
        MEMBER(login_chroot) TRUE,
        MEMBER(login_trusted_networks) "",
-       MEMBER(login_greeting) PACKAGE" ready.",
+       MEMBER(login_greeting) PACKAGE_NAME" ready.",
        MEMBER(login_log_format_elements) "user=<%u> method=%m rip=%r lip=%l %c",
        MEMBER(login_log_format) "%$: %s",
 
@@ -127,13 +127,12 @@ static int ssl_settings_check(void *_set ATTR_UNUSED, const char **error_r)
 #endif
 }
 
-static bool login_settings_check(void *_set, pool_t pool ATTR_UNUSED,
-                                const char **error_r)
+static bool login_settings_check(void *_set, pool_t pool, const char **error_r)
 {
        struct login_settings *set = _set;
 
        set->log_format_elements_split =
-               t_strsplit(set->login_log_format_elements, " ");
+               p_strsplit(pool, set->login_log_format_elements, " ");
 
        if (set->ssl_require_client_cert || set->ssl_username_from_cert) {
                /* if we require valid cert, make sure we also ask for it */
@@ -162,7 +161,10 @@ static bool login_settings_check(void *_set, pool_t pool ATTR_UNUSED,
 }
 /* </settings checks> */
 
-struct login_settings *login_settings_read(struct master_service *service)
+struct login_settings *
+login_settings_read(struct master_service *service, pool_t pool,
+                   const struct ip_addr *local_ip,
+                   const struct ip_addr *remote_ip)
 {
        static const struct setting_parser_info *set_roots[] = {
                &login_setting_parser_info,
@@ -171,15 +173,27 @@ struct login_settings *login_settings_read(struct master_service *service)
        struct master_service_settings_input input;
        const char *error;
        void **sets;
+       struct login_settings *set;
 
        memset(&input, 0, sizeof(input));
        input.roots = set_roots;
        input.module = "login";
        input.service = login_protocol;
 
+       if (local_ip != NULL)
+               input.local_ip = *local_ip;
+       if (remote_ip != NULL)
+               input.remote_ip = *remote_ip;
+
+       /* this function always clears the previous settings pool. since we're
+          doing per-connection lookups, we always need to duplicate the
+          settings using another pool. */
        if (master_service_settings_read(service, &input, &error) < 0)
                i_fatal("Error reading configuration: %s", error);
 
        sets = master_service_settings_get_others(service);
-       return sets[0];
+       set = settings_dup(&login_setting_parser_info, sets[0], pool);
+       if (!login_settings_check(set, pool, &error))
+               i_fatal("login_settings_check() failed: %s", error);
+       return set;
 }
index aa721b2f6dea419659c6730101d1a21c302d62d9..bb8ca59300f53cc6a3bff6bfdd8a74a587cb095b 100644 (file)
@@ -34,9 +34,12 @@ struct login_settings {
        unsigned int mail_max_userip_connections;
 
        /* generated: */
-       const char *const *log_format_elements_split;
+       char *const *log_format_elements_split;
 };
 
-struct login_settings *login_settings_read(struct master_service *service);
+struct login_settings *
+login_settings_read(struct master_service *service, pool_t pool,
+                   const struct ip_addr *local_ip,
+                   const struct ip_addr *remote_ip);
 
 #endif
index 886fde7064e0085b588db9dfbafa5683a8c0a4a0..921a8049d54b2b9007ccad7beca0e4100f28064b 100644 (file)
@@ -23,7 +23,7 @@ bool closing_down;
 int anvil_fd = -1;
 
 struct master_service *service;
-struct login_settings *login_settings;
+const struct login_settings *global_login_settings;
 
 static bool ssl_connections = FALSE;
 
@@ -32,7 +32,9 @@ static void client_connected(const struct master_service_connection *conn)
        struct client *client;
        struct ssl_proxy *proxy;
        struct ip_addr local_ip;
+       const struct login_settings *set;
        unsigned int local_port;
+       pool_t pool;
        int fd_ssl;
 
        if (net_getsockname(conn->fd, &local_ip, &local_port) < 0) {
@@ -40,21 +42,26 @@ static void client_connected(const struct master_service_connection *conn)
                local_port = 0;
        }
 
+       pool = pool_alloconly_create("login client", 1024);
+       set = login_settings_read(service, pool, &local_ip, &conn->remote_ip);
+
        if (!ssl_connections && !conn->ssl) {
-               client = client_create(conn->fd, FALSE, &local_ip,
+               client = client_create(conn->fd, FALSE, pool, set, &local_ip,
                                       &conn->remote_ip);
        } else {
-               fd_ssl = ssl_proxy_new(conn->fd, &conn->remote_ip, &proxy);
+               fd_ssl = ssl_proxy_new(conn->fd, &conn->remote_ip, set, &proxy);
                if (fd_ssl == -1) {
                        net_disconnect(conn->fd);
+                       pool_unref(&pool);
                        return;
                }
 
-               client = client_create(fd_ssl, TRUE,
+               client = client_create(fd_ssl, TRUE, pool, set,
                                       &local_ip, &conn->remote_ip);
                client->proxying = TRUE;
                client->proxy = proxy;
        }
+
        client->remote_port = conn->remote_port;
        client->local_port = local_port;
 }
@@ -95,13 +102,14 @@ static void main_preinit(void)
           normal connections each use one fd, but SSL connections use two */
        max_fds = MASTER_LISTEN_FD_FIRST + 16 +
                master_service_get_socket_count(service) +
-               login_settings->login_max_connections*2;
+               global_login_settings->login_max_connections*2;
        restrict_fd_limit(max_fds);
        io_loop_set_max_fd_count(current_ioloop, max_fds);
 
-       i_assert(strcmp(login_settings->ssl, "no") == 0 || ssl_initialized);
+       i_assert(strcmp(global_login_settings->ssl, "no") == 0 ||
+                ssl_initialized);
 
-       if (login_settings->mail_max_userip_connections > 0)
+       if (global_login_settings->mail_max_userip_connections > 0)
                anvil_fd = anvil_connect();
 
        restrict_access_by_env(NULL, TRUE);
@@ -143,11 +151,14 @@ static void main_deinit(void)
 int main(int argc, char *argv[], char *envp[])
 {
        const char *getopt_str;
+       pool_t set_pool;
        int c;
 
        //FIXME:is_inetd = getenv("DOVECOT_MASTER") == NULL;
 
-       service = master_service_init(login_process_name, 0, argc, argv);
+       service = master_service_init(login_process_name,
+                                     MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN,
+                                     argc, argv);
        master_service_init_log(service, t_strconcat(login_process_name, ": ",
                                                     NULL), 0);
 
@@ -176,7 +187,9 @@ int main(int argc, char *argv[], char *envp[])
 #endif
 
        process_title_init(argv, envp);
-        login_settings = login_settings_read(service);
+       set_pool = pool_alloconly_create("global login settings", 1024);
+       global_login_settings =
+               login_settings_read(service, set_pool, NULL, NULL);
 
        main_preinit();
        master_service_init_finish(service);
@@ -184,6 +197,7 @@ int main(int argc, char *argv[], char *envp[])
 
        master_service_run(service, client_connected);
        main_deinit();
+       pool_unref(&set_pool);
        master_service_deinit(&service);
         return 0;
 }
index 70808fe16290e968bd633206ed85fb4d74537a99..95b722bed61f59d76e4bad1164d638d0780d6707 100644 (file)
@@ -105,7 +105,7 @@ static bool anvil_has_too_many_connections(struct client *client)
 
        if (client->virtual_user == NULL)
                return FALSE;
-       if (login_settings->mail_max_userip_connections == 0)
+       if (client->set->mail_max_userip_connections == 0)
                return FALSE;
 
        ident = t_strconcat("LOOKUP\t", net_ip2addr(&client->ip), "/",
@@ -123,7 +123,7 @@ static bool anvil_has_too_many_connections(struct client *client)
        buf[ret-1] = '\0';
 
        return strtoul(buf, NULL, 10) >=
-               login_settings->mail_max_userip_connections;
+               client->set->mail_max_userip_connections;
 }
 
 static void authenticate_callback(struct auth_request *request, int status,
@@ -219,7 +219,7 @@ void sasl_server_auth_begin(struct client *client,
                return;
        }
 
-       if (!client->secured && login_settings->disable_plaintext_auth &&
+       if (!client->secured && client->set->disable_plaintext_auth &&
            (mech->flags & MECH_SEC_PLAINTEXT) != 0) {
                sasl_server_auth_failed(client,
                        "Plaintext authentication disabled.");
@@ -252,7 +252,7 @@ static void sasl_server_auth_cancel(struct client *client, const char *reason,
 {
        i_assert(client->authenticating);
 
-       if (login_settings->verbose_auth && reason != NULL) {
+       if (client->set->verbose_auth && reason != NULL) {
                const char *auth_name =
                        str_sanitize(client->auth_mech_name, MAX_MECH_NAME);
                client_syslog(client,
index d4f7ea3117a3e00214bd239fd864626d224dd6e9..ddc69870227c27f1fad985424ee6f06724580d54 100644 (file)
@@ -42,6 +42,7 @@ struct ssl_proxy {
 
        SSL *ssl;
        struct ip_addr ip;
+       const struct login_settings *set;
 
        int fd_ssl, fd_plain;
        struct io *io_ssl_read, *io_ssl_write, *io_plain_read, *io_plain_write;
@@ -496,6 +497,7 @@ static void ssl_step(struct ssl_proxy *proxy)
 
 static int
 ssl_proxy_new_common(SSL_CTX *ssl_ctx, int fd, const struct ip_addr *ip,
+                    const struct login_settings *set,
                     struct ssl_proxy **proxy_r)
 {
        struct ssl_proxy *proxy;
@@ -538,6 +540,7 @@ ssl_proxy_new_common(SSL_CTX *ssl_ctx, int fd, const struct ip_addr *ip,
        proxy = i_new(struct ssl_proxy, 1);
        proxy->refcount = 2;
        proxy->ssl = ssl;
+       proxy->set = set;
        proxy->fd_ssl = fd;
        proxy->fd_plain = sfd[0];
        proxy->ip = *ip;
@@ -550,11 +553,13 @@ ssl_proxy_new_common(SSL_CTX *ssl_ctx, int fd, const struct ip_addr *ip,
        return sfd[1];
 }
 
-int ssl_proxy_new(int fd, const struct ip_addr *ip, struct ssl_proxy **proxy_r)
+int ssl_proxy_new(int fd, const struct ip_addr *ip,
+                 const struct login_settings *set, struct ssl_proxy **proxy_r)
 {
        int ret;
 
-       if ((ret = ssl_proxy_new_common(ssl_server_ctx, fd, ip, proxy_r)) < 0)
+       ret = ssl_proxy_new_common(ssl_server_ctx, fd, ip, set, proxy_r);
+       if (ret < 0)
                return -1;
 
        ssl_step(*proxy_r);
@@ -562,12 +567,14 @@ int ssl_proxy_new(int fd, const struct ip_addr *ip, struct ssl_proxy **proxy_r)
 }
 
 int ssl_proxy_client_new(int fd, struct ip_addr *ip,
+                        const struct login_settings *set,
                         ssl_handshake_callback_t *callback, void *context,
                         struct ssl_proxy **proxy_r)
 {
        int ret;
 
-       if ((ret = ssl_proxy_new_common(ssl_client_ctx, fd, ip, proxy_r)) < 0)
+       ret = ssl_proxy_new_common(ssl_client_ctx, fd, ip, set, proxy_r);
+       if (ret < 0)
                return -1;
 
        (*proxy_r)->handshake_callback = callback;
@@ -724,8 +731,8 @@ static int ssl_verify_client_cert(int preverify_ok, X509_STORE_CTX *ctx)
        proxy = SSL_get_ex_data(ssl, extdata_index);
        proxy->cert_received = TRUE;
 
-       if (login_settings->verbose_ssl ||
-           (login_settings->verbose_auth && !preverify_ok)) {
+       if (proxy->set->verbose_ssl ||
+           (proxy->set->verbose_auth && !preverify_ok)) {
                char buf[1024];
                X509_NAME *subject;
 
@@ -927,7 +934,7 @@ static void ssl_proxy_init_client(const struct login_settings *set)
 
 void ssl_proxy_init(void)
 {
-       const struct login_settings *set = login_settings;
+       const struct login_settings *set = global_login_settings;
        static char dovecot[] = "dovecot";
        unsigned char buf;
 
index e1b66ccd75ecb7d0bbb1502cd27ff7f1c6cbde43..a2ee5324738d6cef6b1fcbcab5de003185a6fa6e 100644 (file)
@@ -5,6 +5,7 @@
 
 struct ip_addr;
 struct ssl_proxy;
+struct login_settings;
 
 extern bool ssl_initialized;
 
@@ -13,8 +14,10 @@ typedef int ssl_handshake_callback_t(void *context);
 /* establish SSL connection with the given fd, returns a new fd which you
    must use from now on, or -1 if error occurred. Unless -1 is returned,
    the given fd must be simply forgotten. */
-int ssl_proxy_new(int fd, const struct ip_addr *ip, struct ssl_proxy **proxy_r);
+int ssl_proxy_new(int fd, const struct ip_addr *ip,
+                 const struct login_settings *set, struct ssl_proxy **proxy_r);
 int ssl_proxy_client_new(int fd, struct ip_addr *ip,
+                        const struct login_settings *set,
                         ssl_handshake_callback_t *callback, void *context,
                         struct ssl_proxy **proxy_r);
 bool ssl_proxy_has_valid_client_cert(const struct ssl_proxy *proxy) ATTR_PURE;
index 13d2e327620ac6d8b79d0128ecd3281c227ed82b..b6a4fe7e5d7d1e39cd2fa4f3bc92c4634f20f9e9 100644 (file)
@@ -36,7 +36,8 @@ bool cmd_capa(struct pop3_client *client, const char *args ATTR_UNUSED)
 
        if (ssl_initialized && !client->common.tls)
                str_append(str, "STLS\r\n");
-       if (!login_settings->disable_plaintext_auth || client->common.secured)
+       if (!client->common.set->disable_plaintext_auth ||
+           client->common.secured)
                str_append(str, "USER\r\n");
 
        str_append(str, "SASL");
@@ -48,7 +49,7 @@ bool cmd_capa(struct pop3_client *client, const char *args ATTR_UNUSED)
                */
                if ((mech[i].flags & MECH_SEC_PRIVATE) == 0 &&
                    (client->common.secured ||
-                    !login_settings->disable_plaintext_auth ||
+                    !client->common.set->disable_plaintext_auth ||
                     (mech[i].flags & MECH_SEC_PLAINTEXT) == 0)) {
                        str_append_c(str, ' ');
                        str_append(str, mech[i].name);
@@ -166,7 +167,7 @@ static bool client_handle_args(struct pop3_client *client,
                        master_user = value;
                else if (strcmp(key, "user") == 0) {
                        /* already handled in login-common */
-               } else if (login_settings->auth_debug)
+               } else if (client->common.set->auth_debug)
                        i_info("Ignoring unknown passdb extra field: %s", key);
        }
 
@@ -280,8 +281,8 @@ bool cmd_auth(struct pop3_client *client, const char *args)
        const char *mech_name, *p;
 
        if (!client->common.secured &&
-           strcmp(login_settings->ssl, "required") == 0) {
-               if (login_settings->verbose_auth) {
+           strcmp(client->common.set->ssl, "required") == 0) {
+               if (client->common.set->verbose_auth) {
                        client_syslog(&client->common, "Login failed: "
                                      "SSL required for authentication");
                }
@@ -300,7 +301,7 @@ bool cmd_auth(struct pop3_client *client, const char *args)
                for (i = 0; i < count; i++) {
                        if ((mech[i].flags & MECH_SEC_PRIVATE) == 0 &&
                            (client->common.secured ||
-                            login_settings->disable_plaintext_auth ||
+                            client->common.set->disable_plaintext_auth ||
                             (mech[i].flags & MECH_SEC_PLAINTEXT) == 0))
                                client_send_line(client, mech[i].name);
                }
@@ -333,10 +334,10 @@ bool cmd_auth(struct pop3_client *client, const char *args)
 static bool check_plaintext_auth(struct pop3_client *client)
 {
        if (client->common.secured ||
-           !login_settings->disable_plaintext_auth)
+           !client->common.set->disable_plaintext_auth)
                return TRUE;
 
-       if (login_settings->verbose_auth) {
+       if (client->common.set->verbose_auth) {
                client_syslog(&client->common, "Login failed: "
                              "Plaintext authentication disabled");
        }
@@ -406,7 +407,7 @@ bool cmd_apop(struct pop3_client *client, const char *args)
        const char *p;
 
        if (client->apop_challenge == NULL) {
-               if (login_settings->verbose_auth) {
+               if (client->common.set->verbose_auth) {
                        client_syslog(&client->common,
                                      "APOP failed: APOP not enabled");
                }
@@ -417,7 +418,7 @@ bool cmd_apop(struct pop3_client *client, const char *args)
        /* <username> <md5 sum in hex> */
        p = strchr(args, ' ');
        if (p == NULL || strlen(p+1) != 32) {
-               if (login_settings->verbose_auth) {
+               if (client->common.set->verbose_auth) {
                        client_syslog(&client->common,
                                      "APOP failed: Invalid parameters");
                }
@@ -433,7 +434,7 @@ bool cmd_apop(struct pop3_client *client, const char *args)
        buffer_append_c(apop_data, '\0');
 
        if (hex_to_binary(p+1, apop_data) < 0) {
-               if (login_settings->verbose_auth) {
+               if (client->common.set->verbose_auth) {
                        client_syslog(&client->common, "APOP failed: "
                                      "Invalid characters in MD5 response");
                }
index 082af0a3c914d6505fb99ccbdf70d5e04bf4a742..176a07249caaf91ea3a0cc227b6618033821e1a7 100644 (file)
@@ -42,8 +42,8 @@ static void client_set_title(struct pop3_client *client)
 {
        const char *addr;
 
-       if (!login_settings->verbose_proctitle ||
-           !login_settings->login_process_per_connection)
+       if (!client->common.set->verbose_proctitle ||
+           !client->common.set->login_process_per_connection)
                return;
 
        addr = net_ip2addr(&client->common.ip);
@@ -70,7 +70,7 @@ static void client_start_tls(struct pop3_client *client)
                return;
 
        fd_ssl = ssl_proxy_new(client->common.fd, &client->common.ip,
-                              &client->common.proxy);
+                              client->common.set, &client->common.proxy);
        if (fd_ssl == -1) {
                client_send_line(client, "-ERR TLS initialization failed.");
                client_destroy(client,
@@ -229,7 +229,8 @@ void client_input(struct pop3_client *client)
 
 void client_destroy_oldest(void)
 {
-       unsigned int max_connections = login_settings->login_max_connections;
+       unsigned int max_connections =
+               global_login_settings->login_max_connections;
        struct client *client;
        struct pop3_client *destroy_buf[CLIENT_DESTROY_OLDEST_COUNT];
        unsigned int i, destroy_count;
@@ -292,7 +293,7 @@ static void client_auth_ready(struct pop3_client *client)
 
        client->apop_challenge = get_apop_challenge(client);
        client_send_line(client, t_strconcat("+OK ",
-                                            login_settings->login_greeting,
+                                            client->common.set->login_greeting,
                                             client->apop_challenge != NULL ?
                                             " " : NULL,
                                             client->apop_challenge, NULL));
@@ -303,14 +304,16 @@ static void client_idle_disconnect_timeout(struct pop3_client *client)
        client_destroy(client, "Disconnected: Inactivity");
 }
 
-struct client *client_create(int fd, bool ssl, const struct ip_addr *local_ip,
-                            const struct ip_addr *ip)
+struct client *client_create(int fd, bool ssl, pool_t pool,
+                            const struct login_settings *set,
+                            const struct ip_addr *local_ip,
+                            const struct ip_addr *remote_ip)
 {
        struct pop3_client *client;
 
        i_assert(fd != -1);
 
-       if (clients_get_count() >= login_settings->login_max_connections) {
+       if (clients_get_count() >= set->login_max_connections) {
                /* reached max. users count, kill few of the
                   oldest connections */
                client_destroy_oldest();
@@ -319,17 +322,19 @@ struct client *client_create(int fd, bool ssl, const struct ip_addr *local_ip,
        /* always use nonblocking I/O */
        net_set_nonblock(fd, TRUE);
 
-       client = i_new(struct pop3_client, 1);
+       client = p_new(pool, struct pop3_client, 1);
        client->created = ioloop_time;
        client->refcount = 1;
 
+       client->common.pool = pool;
+       client->common.set = set;
        client->common.local_ip = *local_ip;
-       client->common.ip = *ip;
+       client->common.ip = *remote_ip;
        client->common.fd = fd;
        client->common.tls = ssl;
        client->common.trusted = client_is_trusted(&client->common);
        client->common.secured = ssl || client->common.trusted ||
-               net_ip_compare(ip, local_ip);
+               net_ip_compare(remote_ip, local_ip);
 
        client_open_streams(client, fd);
        client_link(&client->common);
index 1cd1a5d145780e8c5308c67f9680543034b6a396..7081ac7d943b1026eecf48bebf17c33bdd7e9c29 100644 (file)
@@ -188,7 +188,7 @@ static int proxy_input_line(struct pop3_client *client, const char *line)
        else
                client_send_line(client, line);
 
-       if (login_settings->verbose_auth) {
+       if (client->common.set->verbose_auth) {
                str = t_str_new(128);
                str_printfa(str, "proxy(%s): Login failed to %s:%u",
                            client->common.virtual_user,