Mercurial > dovecot > core-2.2
changeset 9773:8e099a00f8a9 HEAD
login proxy: Added client_proxy passdb extra field to specify proxy's connect timeout.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 12 Aug 2009 18:02:20 -0400 |
parents | 1bcd692d6312 |
children | da0a48b243a2 |
files | src/login-common/client-common-auth.c src/login-common/client-common.h src/login-common/login-proxy.c src/login-common/login-proxy.h |
diffstat | 4 files changed, 51 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/src/login-common/client-common-auth.c Wed Aug 12 17:27:50 2009 -0400 +++ b/src/login-common/client-common-auth.c Wed Aug 12 18:02:20 2009 -0400 @@ -112,6 +112,8 @@ reply_r->destuser = value; else if (strcmp(key, "pass") == 0) reply_r->password = value; + else if (strcmp(key, "proxy_timeout") == 0) + reply_r->proxy_timeout_msecs = 1000*atoi(value); else if (strcmp(key, "master") == 0) reply_r->master_user = value; else if (strcmp(key, "ssl") == 0) { @@ -248,6 +250,8 @@ static int proxy_start(struct client *client, const struct client_auth_reply *reply) { + struct login_proxy_settings proxy_set; + i_assert(reply->destuser != NULL); i_assert(!client->destroyed); @@ -275,9 +279,14 @@ return -1; } + memset(&proxy_set, 0, sizeof(proxy_set)); + proxy_set.host = reply->host; + proxy_set.port = reply->port; + proxy_set.connect_timeout_msecs = reply->proxy_timeout_msecs; + proxy_set.ssl_flags = reply->ssl_flags; + client->login_proxy = - login_proxy_new(client, reply->host, reply->port, - reply->ssl_flags, proxy_input, client); + login_proxy_new(client, &proxy_set, proxy_input, client); if (client->login_proxy == NULL) { client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP, AUTH_TEMP_FAILED_MSG);
--- a/src/login-common/client-common.h Wed Aug 12 17:27:50 2009 -0400 +++ b/src/login-common/client-common.h Wed Aug 12 18:02:20 2009 -0400 @@ -42,6 +42,7 @@ /* for proxying */ const char *host, *destuser, *password; unsigned int port; + unsigned int proxy_timeout_msecs; enum login_proxy_ssl_flags ssl_flags; unsigned int proxy:1;
--- a/src/login-common/login-proxy.c Wed Aug 12 17:27:50 2009 -0400 +++ b/src/login-common/login-proxy.c Wed Aug 12 18:02:20 2009 -0400 @@ -25,6 +25,8 @@ struct ip_addr ip; struct ssl_proxy *ssl_proxy; + struct timeout *to; + char *host, *user; unsigned int port; enum login_proxy_ssl_flags ssl_flags; @@ -139,6 +141,9 @@ return; } + if (proxy->to != NULL) + timeout_remove(&proxy->to); + if ((proxy->ssl_flags & PROXY_SSL_FLAG_YES) != 0 && (proxy->ssl_flags & PROXY_SSL_FLAG_STARTTLS) == 0) { if (login_proxy_starttls(proxy) < 0) { @@ -151,43 +156,52 @@ } } +static void proxy_connect_timeout(struct login_proxy *proxy) +{ + i_error("proxy: connect(%s, %u) timed out", proxy->host, proxy->port); + login_proxy_free(&proxy); +} + #undef login_proxy_new struct login_proxy * -login_proxy_new(struct client *client, const char *host, unsigned int port, - enum login_proxy_ssl_flags ssl_flags, +login_proxy_new(struct client *client, const struct login_proxy_settings *set, proxy_callback_t *callback, void *context) { struct login_proxy *proxy; struct ip_addr ip; int fd; - if (host == NULL) { + if (set->host == NULL) { i_error("proxy(%s): host not given", client->virtual_user); return NULL; } - if (net_addr2ip(host, &ip) < 0) { + if (net_addr2ip(set->host, &ip) < 0) { i_error("proxy(%s): %s is not a valid IP", - client->virtual_user, host); + client->virtual_user, set->host); return NULL; } - fd = net_connect_ip(&ip, port, NULL); + fd = net_connect_ip(&ip, set->port, NULL); if (fd < 0) { i_error("proxy(%s): connect(%s, %u) failed: %m", - client->virtual_user, host, port); + client->virtual_user, set->host, set->port); return NULL; } proxy = i_new(struct login_proxy, 1); - proxy->host = i_strdup(host); + proxy->host = i_strdup(set->host); proxy->user = i_strdup(client->virtual_user); - proxy->port = port; - proxy->ssl_flags = ssl_flags; + proxy->port = set->port; + proxy->ssl_flags = set->ssl_flags; proxy->prelogin_client = client; proxy->server_fd = fd; proxy->server_io = io_add(fd, IO_WRITE, proxy_wait_connect, proxy); + if (set->connect_timeout_msecs != 0) { + proxy->to = timeout_add(set->connect_timeout_msecs, + proxy_connect_timeout, proxy); + } proxy->callback = callback; proxy->context = context; @@ -208,6 +222,9 @@ return; proxy->destroying = TRUE; + if (proxy->to != NULL) + timeout_remove(&proxy->to); + if (proxy->server_io != NULL) io_remove(&proxy->server_io); if (proxy->server_input != NULL)
--- a/src/login-common/login-proxy.h Wed Aug 12 17:27:50 2009 -0400 +++ b/src/login-common/login-proxy.h Wed Aug 12 18:02:20 2009 -0400 @@ -13,24 +13,29 @@ PROXY_SSL_FLAG_ANY_CERT = 0x04 }; +struct login_proxy_settings { + const char *host; + unsigned int port; + unsigned int connect_timeout_msecs; + enum login_proxy_ssl_flags ssl_flags; +}; + /* Called when new input comes from proxy. */ typedef void proxy_callback_t(void *context); /* Create a proxy to given host. Returns NULL if failed. Given callback is called when new input is available from proxy. */ struct login_proxy * -login_proxy_new(struct client *client, const char *host, unsigned int port, - enum login_proxy_ssl_flags ssl_flags, +login_proxy_new(struct client *client, const struct login_proxy_settings *set, proxy_callback_t *callback, void *context); #ifdef CONTEXT_TYPE_SAFETY -# define login_proxy_new(client, host, port, ssl_flags, callback, context) \ +# define login_proxy_new(client, set, callback, context) \ ({(void)(1 ? 0 : callback(context)); \ - login_proxy_new(client, host, port, ssl_flags, \ + login_proxy_new(client, set, \ (proxy_callback_t *)callback, context); }) #else -# define login_proxy_new(client, host, port, ssl_flags, callback, context) \ - login_proxy_new(client, host, port, ssl_flags, \ - (proxy_callback_t *)callback, context) +# define login_proxy_new(client, set, callback, context) \ + login_proxy_new(client, set, (proxy_callback_t *)callback, context) #endif /* Free the proxy. This should be called if authentication fails. */ void login_proxy_free(struct login_proxy **proxy);