From 30fbf1172c681f1be851eabb6ff4286a0e741dc0 Mon Sep 17 00:00:00 2001 From: Giovanni Date: Sun, 16 Mar 2025 15:43:39 +0000 Subject: [PATCH] Fix host name retrieval during TLS certificate generation (#1935) Use HOSTNAME if defined, otherwise invoke gethostname(3) if possible, fallback to uname(2) --- CMakeLists.txt | 2 ++ include/znc/Utils.h | 3 ++- include/znc/zncconfig.h.cmake.in | 2 ++ src/Utils.cpp | 46 +++++++++++++++++++++++++------- src/znc.cpp | 2 +- 5 files changed, 43 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3aacbe5..348024b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,6 +318,8 @@ check_cxx_symbol_exists(lstat "sys/types.h;sys/stat.h;unistd.h" HAVE_LSTAT) check_cxx_symbol_exists(getpassphrase "stdlib.h" HAVE_GETPASSPHRASE) check_cxx_symbol_exists(tcsetattr "termios.h;unistd.h" HAVE_TCSETATTR) check_cxx_symbol_exists(clock_gettime "time.h" HAVE_CLOCK_GETTIME) +check_cxx_symbol_exists(gethostname "unistd.h" ZNC_HAVE_GETHOSTNAME) +check_cxx_symbol_exists(uname "sys/utsname.h" ZNC_HAVE_UNAME) # Note that old broken systems, such as OpenBSD, NetBSD, which don't support # AI_ADDRCONFIG, also have thread-unsafe getaddrinfo(). Gladly, they fixed diff --git a/include/znc/Utils.h b/include/znc/Utils.h index 4da6ab7c..52fe6471 100644 --- a/include/znc/Utils.h +++ b/include/znc/Utils.h @@ -44,6 +44,7 @@ class CUtils { static CString GetIP(unsigned long addr); static unsigned long GetLongIP(const CString& sIP); + static CString GetHostName(); static void PrintError(const CString& sMessage); static void PrintMessage(const CString& sMessage, bool bStrong = false); @@ -74,7 +75,7 @@ class CUtils { static timeval GetTime(); static unsigned long long GetMillTime(); #ifdef HAVE_LIBSSL - static void GenerateCert(FILE* pOut, const CString& sHost = ""); + static void GenerateCert(FILE* pOut); #endif /* HAVE_LIBSSL */ static CString CTime(time_t t, const CString& sTZ); diff --git a/include/znc/zncconfig.h.cmake.in b/include/znc/zncconfig.h.cmake.in index 57faf808..230ecef1 100644 --- a/include/znc/zncconfig.h.cmake.in +++ b/include/znc/zncconfig.h.cmake.in @@ -43,6 +43,8 @@ #cmakedefine HAVE_TCSETATTR 1 #cmakedefine HAVE_GETPASSPHRASE 1 #cmakedefine HAVE_CLOCK_GETTIME 1 +#cmakedefine ZNC_HAVE_GETHOSTNAME 1 +#cmakedefine ZNC_HAVE_UNAME 1 #cmakedefine HAVE_ICU 1 #define U_USING_ICU_NAMESPACE 1 diff --git a/src/Utils.cpp b/src/Utils.cpp index ddf6e861..6bf383cb 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -38,6 +38,10 @@ #include #include +#ifdef ZNC_HAVE_GETHOSTNAME +#include +#endif + #include #include #include @@ -56,6 +60,10 @@ #include #endif +#ifdef ZNC_HAVE_UNAME +#include +#endif + // Required with GCC 4.3+ if openssl is disabled #include #include @@ -82,7 +90,7 @@ constexpr const char* szDefaultDH2048 = "cvUyzAEcCQYHmiYjp2hoZbSa8b690TQaAwIBAg==\n" "-----END DH PARAMETERS-----\n"; -void CUtils::GenerateCert(FILE* pOut, const CString& sHost) { +void CUtils::GenerateCert(FILE* pOut) { const int days = 365; const int years = 10; @@ -112,25 +120,19 @@ void CUtils::GenerateCert(FILE* pOut, const CString& sHost) { X509_set_pubkey(pCert.get(), pKey.get()); const char* pLogName = getenv("LOGNAME"); - const char* pHostName = nullptr; + const CString sHostName = GetHostName(); if (!pLogName) pLogName = "Unknown"; - if (!sHost.empty()) pHostName = sHost.c_str(); - - if (!pHostName) pHostName = getenv("HOSTNAME"); - - if (!pHostName) pHostName = "host.unknown"; - CString sEmailAddr = pLogName; sEmailAddr += "@"; - sEmailAddr += pHostName; + sEmailAddr += sHostName; X509_NAME* pName = X509_get_subject_name(pCert.get()); X509_NAME_add_entry_by_txt(pName, "OU", MBSTRING_ASC, (unsigned char*)pLogName, -1, -1, 0); X509_NAME_add_entry_by_txt(pName, "CN", MBSTRING_ASC, - (unsigned char*)pHostName, -1, -1, 0); + (unsigned char*)sHostName.c_str(), -1, -1, 0); X509_NAME_add_entry_by_txt(pName, "emailAddress", MBSTRING_ASC, (unsigned char*)sEmailAddr.c_str(), -1, -1, 0); @@ -180,6 +182,30 @@ unsigned long CUtils::GetLongIP(const CString& sIP) { return ret; } +CString CUtils::GetHostName() { + const char *pEnv; + + pEnv = getenv("HOSTNAME"); + if (pEnv && pEnv[0]) + return pEnv; + +#if defined(ZNC_HAVE_GETHOSTNAME) && defined(_POSIX_HOST_NAME_MAX) + char szBuffer[_POSIX_HOST_NAME_MAX + 1]; + szBuffer[_POSIX_HOST_NAME_MAX] = 0; + if (gethostname(szBuffer, _POSIX_HOST_NAME_MAX) == 0) + return std::string(szBuffer); +#endif + +#if defined(ZNC_HAVE_UNAME) + struct utsname UnameBuffer; + + if (uname(&UnameBuffer) == 0 && UnameBuffer.nodename[0] != '\0') + return UnameBuffer.nodename; +#endif + + return "host.unknown"; +} + #ifdef ZNC_HAVE_ARGON static CString SaltedArgonHash(const CString& sPass, const CString& sSalt) { #define ZNC_ARGON_PARAMS /* iterations */ 6, /* memory */ 6144, /* parallelism */ 1 diff --git a/src/znc.cpp b/src/znc.cpp index 40d3720a..f4a67d8d 100644 --- a/src/znc.cpp +++ b/src/znc.cpp @@ -316,7 +316,7 @@ bool CZNC::WritePemFile() { return false; } - CUtils::GenerateCert(f, ""); + CUtils::GenerateCert(f); fclose(f); CUtils::PrintStatus(true);