]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix SNI on resumed sessions by acknowledging the name sent by the client
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 7 Jan 2021 15:41:32 +0000 (16:41 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 7 Jan 2021 15:41:32 +0000 (16:41 +0100)
Otherwise `SSL_get_servername()` only returns true when the session
has been freshly established, and will return `nullptr` when it is
resumed.

pdns/dnsdistdist/libssl.cc

index 26647cddc56d67496aa823d04cdf7b481347e426..deffcdbf49e5af3bf0b0673cf9c6cc929bd5a937 100644 (file)
@@ -161,6 +161,18 @@ int libssl_ticket_key_callback(SSL *s, OpenSSLTLSTicketKeysRing& keyring, unsign
   return 1;
 }
 
+static long libssl_server_name_callback(SSL* ssl, int* al, void* arg)
+{
+  (void) al;
+  (void) arg;
+
+  if (SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name)) {
+    return SSL_TLSEXT_ERR_OK;
+  }
+
+  return SSL_TLSEXT_ERR_NOACK;
+}
+
 static void libssl_info_callback(const SSL *ssl, int where, int ret)
 {
   SSL_CTX* sslCtx = SSL_get_SSL_CTX(ssl);
@@ -685,6 +697,11 @@ std::unique_ptr<SSL_CTX, void(*)(SSL_CTX*)> libssl_init_server_context(const TLS
     SSL_CTX_sess_set_cache_size(ctx.get(), config.d_maxStoredSessions);
   }
 
+  /* we need to set this callback to acknowledge the server name sent by the client,
+     otherwise it will not stored in the session and will not be accessible when the
+     session is resumed, causing SSL_get_servername to return nullptr */
+  SSL_CTX_set_tlsext_servername_callback(ctx.get(), &libssl_server_name_callback);
+
   std::vector<int> keyTypes;
   /* load certificate and private key */
   for (const auto& pair : config.d_certKeyPairs) {