--- a/src/common/ssl.c +++ a/src/common/ssl.c @@ -410,6 +410,17 @@ gboolean ssl_init_socket(SockInfo *sockinfo) 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 (NULL != sockinfo->canonical_name && !is_numeric_host_address(sockinfo->canonical_name)) { + r = gnutls_server_name_set(session, GNUTLS_NAME_DNS, sockinfo->canonical_name, strlen(sockinfo->canonical_name)); + debug_print("Set GnuTLS session server name indication to %s, status = %d\n", + sockinfo->canonical_name, r); + } + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); if (claws_ssl_get_cert_file()) { --- a/src/common/utils.c +++ a/src/common/utils.c @@ -1924,6 +1924,29 @@ const gchar *get_domain_name(void) #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 (0 == err) { + freeaddrinfo(res); + } + return (0 == err); +} + off_t get_file_size(const gchar *file) { #ifdef G_OS_WIN32 --- a/src/common/utils.h +++ a/src/common/utils.h @@ -396,6 +396,7 @@ const gchar *get_tmp_dir (void); 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); --- a/src/etpan/etpan-ssl.c +++ a/src/etpan/etpan-ssl.c @@ -171,6 +171,19 @@ void etpan_connect_ssl_context_cb(struct mailstream_ssl_context * ssl_context, v gnutls_x509_crt_deinit(x509); gnutls_x509_privkey_deinit(pkey); } + + /* 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 (!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 /* USE_GNUTLS */