Adds a hidden pref "use_tls_sni".
Patch by Alex Smith.
Closes bug #4103: TLS SNI (Server Name Indication) support for IMAP, POP & SMTP
Michael Schwendt
Eric S. Raymond
Avinash Sonawane
+ Alex Smith
session->port = 0;
#ifdef USE_GNUTLS
session->ssl_type = SSL_NONE;
+ session->use_tls_sni = TRUE;
#endif
session->nonblocking = TRUE;
session->state = SESSION_READY;
#ifdef USE_GNUTLS
sock->gnutls_priority = session->gnutls_priority;
+ sock->use_tls_sni = session->use_tls_sni;
if (session->ssl_type == SSL_TUNNEL) {
sock_set_nonblocking_mode(sock, FALSE);
session->sock->ssl_cert_auto_accept = session->ssl_cert_auto_accept;
session->sock->gnutls_priority = session->gnutls_priority;
+ session->sock->use_tls_sni = session->use_tls_sni;
if (nb_mode)
sock_set_nonblocking_mode(session->sock, FALSE);
#ifdef USE_GNUTLS
SSLType ssl_type;
gchar *gnutls_priority;
+ gboolean use_tls_sni;
#endif
};
const void *account;
gboolean is_smtp;
gboolean ssl_cert_auto_accept;
+ gboolean use_tls_sni;
};
void refresh_resolvers (void);
gnutls_record_disable_padding(session);
+ /* If we have a host name, rather than a numerical IP address, tell
+ * gnutls to send it in the server name identification extension field,
+ * to give the server a chance to select the correct certificate in the
+ * virtual hosting case where multiple domain names are hosted on the
+ * same IP address. */
+ if (sockinfo->use_tls_sni &&
+ sockinfo->hostname != NULL &&
+ !is_numeric_host_address(sockinfo->hostname)) {
+ r = gnutls_server_name_set(session, GNUTLS_NAME_DNS,
+ sockinfo->hostname, strlen(sockinfo->hostname));
+ debug_print("Set GnuTLS session server name indication to %s, status = %d\n",
+ sockinfo->hostname, r);
+ }
+
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
if (claws_ssl_get_cert_file()) {
#endif
}
+/* Tells whether the given host address string is a valid representation of a
+ * numerical IP (v4 or, if supported, v6) address.
+ */
+gboolean is_numeric_host_address(const gchar *hostaddress)
+{
+ struct addrinfo hints, *res;
+ int err;
+
+ /* See what getaddrinfo makes of the string when told that it is a
+ * numeric IP address representation. */
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = 0;
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_protocol = 0;
+
+ err = getaddrinfo(hostaddress, NULL, &hints, &res);
+ if (err == 0)
+ freeaddrinfo(res);
+
+ return (err == 0);
+}
+
off_t get_file_size(const gchar *file)
{
#ifdef G_OS_WIN32
const gchar *get_locale_dir (void);
gchar *get_tmp_file (void);
const gchar *get_domain_name (void);
+gboolean is_numeric_host_address (const gchar *hostaddress);
const gchar *get_desktop_file(void);
#ifdef G_OS_WIN32
const gchar *w32_get_themes_dir (void);
gnutls_x509_crt_deinit(x509);
gnutls_x509_privkey_deinit(pkey);
}
+
+#if (defined LIBETPAN_API_CURRENT && LIBETPAN_API_CURRENT >= 23)
+ /* If we have a host name, rather than a numerical IP address, tell
+ * gnutls to send it in the Server Name Identification extension field,
+ * to give the server a chance to select the correct certificate in the
+ * virtual hosting case where multiple domain names are hosted on the
+ * same IP address. */
+ if (session->use_tls_sni &&
+ !is_numeric_host_address(account->recv_server)) {
+ int r;
+
+ r = mailstream_ssl_set_server_name(ssl_context, account->recv_server);
+ debug_print("Set libetpan SSL mail stream server name indication to %s, status = %d\n",
+ account->recv_server, r);
+ }
+#endif /* LIBETPAN_API_CURRENT >= 23 */
+
}
#endif /* USE_GNUTLS */
"shigeri",
"Jesse Skinner",
"Ville Skyttä",
+"Alex Smith",
"Dale P. Smith",
"Avinash Sonawane",
"Andrea Spadaccini",
session->uidplus = FALSE;
session->cmd_count = 1;
}
+ SESSION(session)->use_tls_sni = account->use_tls_sni;
#endif
+
log_message(LOG_PROTOCOL, "IMAP connection is %s-authenticated\n",
(session->authenticated) ? "pre" : "un");
nntp_init(folder);
#ifdef USE_GNUTLS
+ SESSION(session)->use_tls_sni = account->use_tls_sni;
if (ssl_type != SSL_NONE)
r = nntp_threaded_connect_ssl(folder, server, port, proxy_info);
else
session->state = SIEVE_CAPABILITIES;
#ifdef USE_GNUTLS
session->tls_init_done = FALSE;
+ SESSION(session)->use_tls_sni = account->use_tls_sni;
#endif
session->avail_auth_type = 0;
session->auth_type = 0;
if (account->set_gnutls_priority && account->gnutls_priority &&
strlen(account->gnutls_priority) != 0)
SESSION(session)->gnutls_priority = g_strdup(account->gnutls_priority);
+ SESSION(session)->use_tls_sni = account->use_tls_sni;
#endif
session->state = POP3_READY;
&ssl_page.use_nonblocking_ssl_checkbtn,
prefs_set_data_from_toggle, prefs_set_toggle},
+ {"use_tls_sni", "1", &tmp_ac_prefs.use_tls_sni, P_BOOL,
+ NULL, NULL, NULL},
+
{"in_ssl_client_cert_file", "", &tmp_ac_prefs.in_ssl_client_cert_file, P_STRING,
&ssl_page.entry_in_cert_file, prefs_set_data_from_entry, prefs_set_entry},
gboolean ssl_certs_auto_accept;
gboolean use_nonblocking_ssl;
+ gboolean use_tls_sni;
/* Receive */
gboolean use_apop_auth;
if (ac_prefs->set_gnutls_priority && ac_prefs->gnutls_priority &&
strlen(ac_prefs->gnutls_priority))
session->gnutls_priority = g_strdup(ac_prefs->gnutls_priority);
+ session->use_tls_sni = ac_prefs->use_tls_sni;
#else
if (ac_prefs->ssl_smtp != SSL_NONE) {
if (alertpanel_full(_("Insecure connection"),