login_no_tls_networks setting to list networks for which we don't want to advertise STARTTLS capability. Proper way to do this will be once master/config rewrite is finished. Then you can change any settings based on IP and whatever. Index: src/imap-login/client.c =================================================================== RCS file: /var/lib/cvs/dovecot/src/imap-login/client.c,v retrieving revision 1.38 diff -u -r1.38 client.c --- src/imap-login/client.c 28 Oct 2004 15:22:35 -0000 1.38 +++ src/imap-login/client.c 5 Nov 2004 15:22:56 -0000 @@ -93,11 +93,26 @@ static const char *get_capability(struct imap_client *client) { const char *auths; + int starttls; + + starttls = ssl_initialized && !client->common.tls; + if (starttls && no_tls_networks != NULL && + client->common.ip.family == AF_INET) { + const uint32_t *data = no_tls_networks->data; + unsigned int i, count = no_tls_networks->used / sizeof(*data); + uint32_t client_ip; + + memcpy(&client_ip, &client->common.ip.ip, 4); + for (i = 0; i < count; i += 2) { + if (data[i] == (client_ip & data[i+1])) { + starttls = FALSE; + break; + } + } + } auths = client_authenticate_get_capabilities(client->common.secured); - return t_strconcat(CAPABILITY_STRING, - (ssl_initialized && !client->common.tls) ? - " STARTTLS" : "", + return t_strconcat(CAPABILITY_STRING, starttls ? " STARTTLS" : "", disable_plaintext_auth && !client->common.secured ? " LOGINDISABLED" : "", auths, NULL); } Index: src/login-common/common.h =================================================================== RCS file: /var/lib/cvs/dovecot/src/login-common/common.h,v retrieving revision 1.6 diff -u -r1.6 common.h --- src/login-common/common.h 18 Oct 2004 23:07:01 -0000 1.6 +++ src/login-common/common.h 5 Nov 2004 15:22:56 -0000 @@ -11,6 +11,7 @@ extern unsigned int max_logging_users; extern unsigned int login_process_uid; extern struct auth_client *auth_client; +extern buffer_t *no_tls_networks; void main_ref(void); void main_unref(void); Index: src/login-common/main.c =================================================================== RCS file: /var/lib/cvs/dovecot/src/login-common/main.c,v retrieving revision 1.23 diff -u -r1.23 main.c --- src/login-common/main.c 18 Oct 2004 19:21:47 -0000 1.23 +++ src/login-common/main.c 5 Nov 2004 15:22:56 -0000 @@ -1,6 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "common.h" +#include "buffer.h" #include "ioloop.h" #include "lib-signals.h" #include "randgen.h" @@ -24,6 +25,7 @@ unsigned int max_logging_users; unsigned int login_process_uid; struct auth_client *auth_client; +buffer_t *no_tls_networks; static struct ioloop *ioloop; static struct io *io_listen, *io_ssl_listen; @@ -150,6 +152,46 @@ restrict_process_size((unsigned int)-1, 1); } +static void parse_no_tls_networks(const char *value) +{ + const char *const *tmp, *addr, *prefix; + struct ip_addr ip; + uint32_t ipnum, mask; + + no_tls_networks = buffer_create_dynamic(default_pool, 256); + + t_push(); + for (tmp = t_strsplit_spaces(value, " "); *tmp != NULL; tmp++) { + addr = *tmp; + prefix = strchr(addr, '/'); + if (prefix != NULL) { + addr = t_strdup_until(addr, prefix); + prefix++; + if (!is_numeric(prefix, '\0')) { + i_error("no_tls_networks: Invalid prefix: %s", + prefix); + continue; + } + mask = atoi(prefix); + } else { + mask = 32; + } + + if (net_addr2ip(addr, &ip) < 0 || ip.family != AF_INET) { + i_error("no_tls_networks: Invalid IPv4 address: %s", + addr); + continue; + } + mask = htonl(~((1U << (32 - mask))-1)); + memcpy(&ipnum, &ip.ip, 4); + ipnum &= mask; + + buffer_append(no_tls_networks, &ipnum, 4); + buffer_append(no_tls_networks, &mask, 4); + } + t_pop(); +} + static void main_init(void) { const char *value; @@ -177,7 +219,11 @@ if (login_process_uid == 0) i_fatal("BUG: PROCESS_UID environment is 0"); - closing_down = FALSE; + value = getenv("NO_TLS_NETWORKS"); + if (value != NULL && *value != '\0') + parse_no_tls_networks(value); + + closing_down = FALSE; main_refcount = 0; auth_client = auth_client_new((unsigned int)getpid()); Index: src/master/login-process.c =================================================================== RCS file: /var/lib/cvs/dovecot/src/master/login-process.c,v retrieving revision 1.61 diff -u -r1.61 login-process.c --- src/master/login-process.c 19 Oct 2004 01:17:39 -0000 1.61 +++ src/master/login-process.c 5 Nov 2004 15:22:56 -0000 @@ -441,6 +441,8 @@ env_put(t_strconcat("GREETING=", set->login_greeting, NULL)); if (set->login_greeting_capability) env_put("GREETING_CAPABILITY=1"); + env_put(t_strconcat("NO_TLS_NETWORKS=", + set->login_no_tls_networks, NULL)); } static pid_t create_login_process(struct login_group *group) Index: src/master/master-settings.c =================================================================== RCS file: /var/lib/cvs/dovecot/src/master/master-settings.c,v retrieving revision 1.75 diff -u -r1.75 master-settings.c --- src/master/master-settings.c 21 Oct 2004 20:47:36 -0000 1.75 +++ src/master/master-settings.c 5 Nov 2004 15:22:57 -0000 @@ -65,6 +65,7 @@ DEF(SET_STR, login_executable), DEF(SET_STR, login_user), DEF(SET_STR, login_greeting), + DEF(SET_STR, login_no_tls_networks), DEF(SET_BOOL, login_process_per_connection), DEF(SET_BOOL, login_chroot), @@ -231,6 +232,7 @@ MEMBER(login_executable) NULL, MEMBER(login_user) "dovecot", MEMBER(login_greeting) "Dovecot ready.", + MEMBER(login_no_tls_networks) NULL, MEMBER(login_process_per_connection) TRUE, MEMBER(login_chroot) TRUE, Index: src/master/master-settings.h =================================================================== RCS file: /var/lib/cvs/dovecot/src/master/master-settings.h,v retrieving revision 1.49 diff -u -r1.49 master-settings.h --- src/master/master-settings.h 21 Oct 2004 02:23:13 -0000 1.49 +++ src/master/master-settings.h 5 Nov 2004 15:22:57 -0000 @@ -38,6 +38,7 @@ const char *login_executable; const char *login_user; const char *login_greeting; + const char *login_no_tls_networks; int login_process_per_connection; int login_chroot; Index: src/pop3-login/client-authenticate.c =================================================================== RCS file: /var/lib/cvs/dovecot/src/pop3-login/client-authenticate.c,v retrieving revision 1.39 diff -u -r1.39 client-authenticate.c --- src/pop3-login/client-authenticate.c 29 Oct 2004 17:56:46 -0000 1.39 +++ src/pop3-login/client-authenticate.c 5 Nov 2004 15:22:57 -0000 @@ -24,6 +24,7 @@ const struct auth_mech_desc *mech; unsigned int i, count; string_t *str; + int stls; str = t_str_new(128); str_append(str, "SASL"); @@ -42,10 +43,25 @@ } } + stls = ssl_initialized && !client->common.tls; + if (stls && no_tls_networks != NULL && + client->common.ip.family == AF_INET) { + const uint32_t *data = no_tls_networks->data; + unsigned int i, count = no_tls_networks->used / sizeof(*data); + uint32_t client_ip; + + memcpy(&client_ip, &client->common.ip.ip, 4); + for (i = 0; i < count; i += 2) { + if (data[i] == (client_ip & data[i+1])) { + stls = FALSE; + break; + } + } + } + client_send_line(client, t_strconcat("+OK\r\n" POP3_CAPABILITY_REPLY, - (ssl_initialized && !client->common.tls) ? - "STLS\r\n" : "", + stls ? "STLS\r\n" : "", str_c(str), "\r\n.", NULL)); return TRUE; }