Add patch for clickhouse-cpp to set the server CN to use for TLS cert verification
Some checks are pending
Build / build (push) Waiting to run
CIFuzz / Fuzzing (address) (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
CodeQL / Analyze-1 (push) Waiting to run

This commit is contained in:
Alfredo Cardigliano 2026-07-08 18:36:39 +02:00
parent c03b56e56f
commit 30961dd5e9

View file

@ -5,7 +5,7 @@ index f6d896b..2bd15e4 100644
@@ -24,6 +24,10 @@
# define _unix_
#endif
+#ifdef __FreeBSD__
+#define _unix_
+#endif
@ -20,16 +20,16 @@ index 3bb1aa5..dad6e4d 100644
@@ -18,6 +18,10 @@
# include <unistd.h>
#endif
+#if defined(__FreeBSD__)
+#include <netinet/in.h>
+#endif
+
namespace clickhouse {
#if defined(_win_)
@@ -355,7 +359,7 @@ void Socket::SetTcpKeepAlive(int idle, int intvl, int cnt) noexcept {
#if defined(_unix_)
setsockopt(handle_, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
-# if defined(_linux_)
@ -37,14 +37,77 @@ index 3bb1aa5..dad6e4d 100644
setsockopt(handle_, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle));
# elif defined(_darwin_)
setsockopt(handle_, IPPROTO_TCP, TCP_KEEPALIVE, &idle, sizeof(idle));
diff --git a/clickhouse/base/sslsocket.cpp b/clickhouse/base/sslsocket.cpp
index c93957d..a9e3e6d 100644
--- a/clickhouse/base/sslsocket.cpp
+++ b/clickhouse/base/sslsocket.cpp
@@ -174,6 +174,7 @@ clickhouse::SSLParams GetSSLParams(const clickhouse::ClientOptions& opts) {
ssl_options.use_sni,
ssl_options.skip_verification,
ssl_options.host_flags,
+ ssl_options.server_host_name,
convertConfiguration(ssl_options.configuration)
};
}
@@ -222,15 +223,19 @@ SSLSocket::SSLSocket(const NetworkAddress& addr, const SocketTimeoutParams& time
if (!ssl)
throw clickhouse::OpenSSLError("Failed to create SSL instance");
- std::unique_ptr<ASN1_OCTET_STRING, decltype(&ASN1_OCTET_STRING_free)> ip_addr(a2i_IPADDRESS(addr.Host().c_str()), &ASN1_OCTET_STRING_free);
+ const std::string & tls_host_name = !ssl_params.server_host_name.empty()
+ ? ssl_params.server_host_name
+ : addr.Host();
+
+ std::unique_ptr<ASN1_OCTET_STRING, decltype(&ASN1_OCTET_STRING_free)> ip_addr(a2i_IPADDRESS(tls_host_name.c_str()), &ASN1_OCTET_STRING_free);
HANDLE_SSL_ERROR(ssl, SSL_set_fd(ssl, static_cast<int>(handle_)));
if (ssl_params.use_SNI)
- HANDLE_SSL_ERROR(ssl, SSL_set_tlsext_host_name(ssl, addr.Host().c_str()));
+ HANDLE_SSL_ERROR(ssl, SSL_set_tlsext_host_name(ssl, tls_host_name.c_str()));
if (ssl_params.host_flags != -1)
SSL_set_hostflags(ssl, ssl_params.host_flags);
- HANDLE_SSL_ERROR(ssl, SSL_set1_host(ssl, addr.Host().c_str()));
+ HANDLE_SSL_ERROR(ssl, SSL_set1_host(ssl, tls_host_name.c_str()));
// DO NOT use SSL_set_verify(ssl, SSL_VERIFY_PEER, nullptr), since
// we check verification result later, and that provides better error message.
diff --git a/clickhouse/base/sslsocket.h b/clickhouse/base/sslsocket.h
index 945de86..32ae3bb 100644
--- a/clickhouse/base/sslsocket.h
+++ b/clickhouse/base/sslsocket.h
@@ -22,6 +22,7 @@ struct SSLParams
bool use_SNI;
bool skip_verification;
int host_flags;
+ std::string server_host_name;
using ConfigurationType = std::vector<std::pair<std::string, std::optional<std::string>>>;
ConfigurationType configuration;
};
diff --git a/clickhouse/client.h b/clickhouse/client.h
index f1d5005..18811d1 100644
--- a/clickhouse/client.h
+++ b/clickhouse/client.h
@@ -197,6 +197,11 @@ struct ClientOptions {
*/
DECLARE_FIELD(host_flags, int, SetHostVerifyFlags, DEFAULT_VALUE);
+ /** Server hostname to use for TLS SNI (via SSL_set_tlsext_host_name) and for
+ * certificate hostname verification (via SSL_set1_host), instead of ClientOptions::host.
+ */
+ DECLARE_FIELD(server_host_name, std::string, SetServerHostName, "");
+
struct CommandAndValue {
std::string command;
std::optional<std::string> value = std::nullopt;
diff --git a/clickhouse/columns/ip6.cpp b/clickhouse/columns/ip6.cpp
index 55ba2d4..96fd2a2 100644
--- a/clickhouse/columns/ip6.cpp
+++ b/clickhouse/columns/ip6.cpp
@@ -4,6 +4,12 @@
#include <stdexcept>
+#if defined(__FreeBSD__)
+ #include <sys/types.h>
+ #include <sys/socket.h>
@ -52,7 +115,7 @@ index 55ba2d4..96fd2a2 100644
+#endif
+
namespace clickhouse {
static_assert(sizeof(struct in6_addr) == 16, "sizeof in6_addr should be 16 bytes");
diff --git a/clickhouse/columns/lowcardinality.cpp b/clickhouse/columns/lowcardinality.cpp
index e286c86..14c869e 100644
@ -60,12 +123,12 @@ index e286c86..14c869e 100644
+++ b/clickhouse/columns/lowcardinality.cpp
@@ -396,8 +396,9 @@ void ColumnLowCardinality::SavePrefix(OutputStream* output) {
}
void ColumnLowCardinality::SaveBody(OutputStream* output) {
+ uint64_t iflag = static_cast<uint64_t>(IndexFlag::HasAdditionalKeysBit);
const uint64_t index_serialization_type =
- static_cast<uint64_t>(indexTypeFromIndexColumn(*index_column_)) | IndexFlag::HasAdditionalKeysBit;
+ static_cast<uint64_t>(indexTypeFromIndexColumn(*index_column_)) | iflag;
WireFormat::WriteFixed(*output, index_serialization_type);
const uint64_t number_of_keys = dictionary_column_->Size();