修复: 升级框架并完善报告导出
- 升级 Drogon 和 Trantor,修复畸形请求导致的连接计数泄漏\n- 增加第三方框架版本校验与自动重建\n- 完善完整报告导出和接口文档
This commit is contained in:
+12
-7
@@ -5,8 +5,17 @@ option(BUILD_DOC "Build Doxygen documentation" OFF)
|
||||
option(BUILD_C-ARES "Build C-ARES" ON)
|
||||
option(BUILD_TESTING "Build tests" OFF)
|
||||
option(BUILD_SHARED_LIBS "Build trantor as a shared lib" OFF)
|
||||
option(TRANTOR_USE_TLS
|
||||
"TLS provider for trantor. Valid options are 'openssl', 'botan' or '' (let the build scripr decide)" ""
|
||||
set(TRANTOR_USE_TLS
|
||||
""
|
||||
CACHE STRING "TLS provider for trantor. Valid options are 'openssl', 'botan', 'none' or '' (auto-detect)"
|
||||
)
|
||||
set_property(
|
||||
CACHE TRANTOR_USE_TLS
|
||||
PROPERTY STRINGS
|
||||
""
|
||||
openssl
|
||||
botan
|
||||
none
|
||||
)
|
||||
option(USE_SPDLOG "Allow using the spdlog logging library" OFF)
|
||||
|
||||
@@ -14,7 +23,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules/)
|
||||
|
||||
set(TRANTOR_MAJOR_VERSION 1)
|
||||
set(TRANTOR_MINOR_VERSION 5)
|
||||
set(TRANTOR_PATCH_VERSION 26)
|
||||
set(TRANTOR_PATCH_VERSION 28)
|
||||
set(TRANTOR_VERSION ${TRANTOR_MAJOR_VERSION}.${TRANTOR_MINOR_VERSION}.${TRANTOR_PATCH_VERSION})
|
||||
|
||||
include(GNUInstallDirs)
|
||||
@@ -158,10 +167,6 @@ else(WIN32)
|
||||
set(TRANTOR_SOURCES ${TRANTOR_SOURCES} trantor/net/inner/FileBufferNodeUnix.cc)
|
||||
endif(WIN32)
|
||||
|
||||
# Somehow the default value of TRANTOR_USE_TLS is OFF
|
||||
if(TRANTOR_USE_TLS STREQUAL OFF)
|
||||
set(TRANTOR_USE_TLS "")
|
||||
endif()
|
||||
set(VALID_TLS_PROVIDERS "openssl" "botan" "none")
|
||||
list(
|
||||
FIND
|
||||
|
||||
+29
-1
@@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.5.28] - 2026-05-06
|
||||
|
||||
### Fixed
|
||||
|
||||
- Avoid abort on closeWrite shutdown failure.
|
||||
|
||||
## [1.5.27] - 2026-05-06
|
||||
|
||||
### Changed
|
||||
|
||||
- Add automatic SSL.
|
||||
|
||||
- Add getter for `TcpConnection::closeCallback_`.
|
||||
|
||||
- Remove spurious executable permissions from non-script sources.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix `TRANTOR_USE_TLS` cache setting in CMake.
|
||||
|
||||
- Fix TLS implementation quirks.
|
||||
|
||||
- Fix server-side mTLS client certificate hostname validation.
|
||||
|
||||
## [1.5.26] - 2026-01-26
|
||||
|
||||
### Changed
|
||||
@@ -742,7 +766,11 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
## [1.0.0-rc1] - 2019-06-11
|
||||
|
||||
[Unreleased]: https://github.com/an-tao/trantor/compare/v1.5.26...HEAD
|
||||
[Unreleased]: https://github.com/an-tao/trantor/compare/v1.5.28...HEAD
|
||||
|
||||
[1.5.28]: https://github.com/an-tao/trantor/compare/v1.5.27...v1.5.28
|
||||
|
||||
[1.5.27]: https://github.com/an-tao/trantor/compare/v1.5.26...v1.5.27
|
||||
|
||||
[1.5.26]: https://github.com/an-tao/trantor/compare/v1.5.25...v1.5.26
|
||||
|
||||
|
||||
@@ -351,6 +351,10 @@ class TRANTOR_EXPORT TcpConnection
|
||||
{
|
||||
closeCallback_ = std::move(cb);
|
||||
}
|
||||
CloseCallback getCloseCallback() const
|
||||
{
|
||||
return closeCallback_;
|
||||
}
|
||||
void setSSLErrorCallback(const SSLErrorCallback &cb)
|
||||
{
|
||||
sslErrorCallback_ = cb;
|
||||
@@ -367,6 +371,8 @@ class TRANTOR_EXPORT TcpConnection
|
||||
size_t timeout,
|
||||
const std::shared_ptr<TimingWheel> &timingWheel) = 0;
|
||||
|
||||
virtual void forwardToTLSBuffer(MsgBuffer *buffer) = 0;
|
||||
|
||||
protected:
|
||||
// callbacks
|
||||
RecvMessageCallback recvMsgCallback_;
|
||||
|
||||
@@ -203,6 +203,12 @@ class TcpConnectionImpl : public TcpConnection,
|
||||
timingWheel->insertEntry(timeout, entry);
|
||||
}
|
||||
|
||||
void forwardToTLSBuffer(MsgBuffer *buffer) override
|
||||
{
|
||||
if (tlsProviderPtr_)
|
||||
tlsProviderPtr_->recvData(buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
/// Internal use only.
|
||||
|
||||
|
||||
+2
-2
@@ -474,8 +474,6 @@ SSLContextPtr trantor::newSSLContext(const TLSPolicy &policy, bool server)
|
||||
ctx->certStore =
|
||||
std::make_shared<Botan::Flatfile_Certificate_Store>(
|
||||
policy.getCaPath());
|
||||
if (server)
|
||||
ctx->requireClientCert = true;
|
||||
}
|
||||
else if (policy.getUseSystemCertStore())
|
||||
{
|
||||
@@ -484,6 +482,8 @@ SSLContextPtr trantor::newSSLContext(const TLSPolicy &policy, bool server)
|
||||
ctx->certStore = systemCertStore;
|
||||
}
|
||||
}
|
||||
if (server && policy.getValidate() && !policy.getCaPath().empty())
|
||||
ctx->requireClientCert = true;
|
||||
|
||||
if (policy.getUseOldTLS())
|
||||
LOG_WARN << "SSLPloicy have set useOldTLS to true. BUt Botan does not "
|
||||
|
||||
+25
-70
@@ -8,12 +8,10 @@
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include "callbacks.h"
|
||||
|
||||
@@ -70,62 +68,6 @@ inline bool loadWindowsSystemCert(X509_STORE *store)
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool verifyCommonName(X509 *cert, const std::string &hostname)
|
||||
{
|
||||
X509_NAME *subjectName = X509_get_subject_name(cert);
|
||||
|
||||
if (subjectName != nullptr)
|
||||
{
|
||||
std::array<char, BUFSIZ> name;
|
||||
auto length = X509_NAME_get_text_by_NID(subjectName,
|
||||
NID_commonName,
|
||||
name.data(),
|
||||
(int)name.size());
|
||||
if (length == -1)
|
||||
return false;
|
||||
|
||||
return utils::verifySslName(std::string(name.begin(),
|
||||
name.begin() + length),
|
||||
hostname);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool verifyAltName(X509 *cert, const std::string &hostname)
|
||||
{
|
||||
bool good = false;
|
||||
auto altNames = static_cast<const struct stack_st_GENERAL_NAME *>(
|
||||
X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr));
|
||||
|
||||
if (altNames)
|
||||
{
|
||||
int numNames = sk_GENERAL_NAME_num(altNames);
|
||||
|
||||
for (int i = 0; i < numNames && !good; i++)
|
||||
{
|
||||
auto val = sk_GENERAL_NAME_value(altNames, i);
|
||||
if (val->type != GEN_DNS)
|
||||
{
|
||||
LOG_WARN << "Name using IP addresses are not supported. Open "
|
||||
"an issue if you need that feature";
|
||||
continue;
|
||||
}
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
||||
auto name = (const char *)ASN1_STRING_get0_data(val->d.ia5);
|
||||
#else
|
||||
auto name = (const char *)ASN1_STRING_data(val->d.ia5);
|
||||
#endif
|
||||
auto name_len = (size_t)ASN1_STRING_length(val->d.ia5);
|
||||
good = utils::verifySslName(std::string(name, name + name_len),
|
||||
hostname);
|
||||
}
|
||||
}
|
||||
|
||||
GENERAL_NAMES_free((STACK_OF(GENERAL_NAME) *)altNames);
|
||||
return good;
|
||||
}
|
||||
|
||||
static bool validatePeerCertificate(SSL *ssl,
|
||||
X509 *cert,
|
||||
const std::string &hostname,
|
||||
@@ -136,12 +78,16 @@ static bool validatePeerCertificate(SSL *ssl,
|
||||
assert(cert != nullptr);
|
||||
LOG_TRACE << "Validating peer certificate";
|
||||
|
||||
if (isServer)
|
||||
if (!isServer)
|
||||
{
|
||||
bool domainIsValid =
|
||||
verifyCommonName(cert, hostname) || verifyAltName(cert, hostname);
|
||||
if (!domainIsValid)
|
||||
const int rc =
|
||||
X509_check_host(cert, hostname.data(), hostname.size(), 0, nullptr);
|
||||
if (rc != 1)
|
||||
{
|
||||
LOG_TRACE << "Peer certificate does not match hostname: "
|
||||
<< hostname;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto result = SSL_get_verify_result(ssl);
|
||||
@@ -423,16 +369,20 @@ class SessionManager
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns a session with an additional reference held by the caller.
|
||||
// Caller must SSL_SESSION_free() when done. Required because the entry
|
||||
// in sessionMap_ may be evicted/replaced/expired by another thread the
|
||||
// moment we release the mutex, so the SessionManager's reference is not
|
||||
// a stable ownership root for the returned pointer.
|
||||
SSL_SESSION *get(const std::string &hostname, InetAddress peerAddr)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto key = toKey(hostname, peerAddr);
|
||||
auto it = sessionMap_.find(key);
|
||||
if (it != sessionMap_.end())
|
||||
{
|
||||
return it->second->session;
|
||||
}
|
||||
return nullptr;
|
||||
auto it = sessionMap_.find(toKey(hostname, peerAddr));
|
||||
if (it == sessionMap_.end())
|
||||
return nullptr;
|
||||
SSL_SESSION *s = it->second->session;
|
||||
SSL_SESSION_up_ref(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
void removeExcessSession()
|
||||
@@ -529,7 +479,9 @@ struct OpenSSLProvider : public TLSProvider, public NonCopyable
|
||||
conn_->peerAddr());
|
||||
if (cachedSession)
|
||||
{
|
||||
// SSL_set_session takes its own reference; release ours.
|
||||
SSL_set_session(ssl_, cachedSession);
|
||||
SSL_SESSION_free(cachedSession);
|
||||
}
|
||||
SSL_set_connect_state(ssl_);
|
||||
}
|
||||
@@ -671,7 +623,10 @@ struct OpenSSLProvider : public TLSProvider, public NonCopyable
|
||||
cert,
|
||||
policyPtr_->getHostname(),
|
||||
policyPtr_->getAllowBrokenChain(),
|
||||
contextPtr_->isServer);
|
||||
!contextPtr_
|
||||
->isServer); // From the server's point of view,
|
||||
// the client certificate is verified
|
||||
// and vice versa
|
||||
if (!valid)
|
||||
{
|
||||
LOG_TRACE
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#include <trantor/net/TcpClient.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <trantor/net/EventLoopThread.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <atomic>
|
||||
using namespace trantor;
|
||||
#define USE_IPV6 0
|
||||
int main()
|
||||
{
|
||||
trantor::Logger::setLogLevel(trantor::Logger::kDebug);
|
||||
LOG_DEBUG << "TcpClient class test!";
|
||||
EventLoop loop;
|
||||
#if USE_IPV6
|
||||
InetAddress serverAddr("::1", 8888, true);
|
||||
#else
|
||||
InetAddress serverAddr("127.0.0.1", 8888);
|
||||
#endif
|
||||
std::shared_ptr<trantor::TcpClient> client[10];
|
||||
std::atomic_int connCount;
|
||||
connCount = 1;
|
||||
for (int i = 0; i < 1; ++i)
|
||||
{
|
||||
client[i] = std::make_shared<trantor::TcpClient>(&loop,
|
||||
serverAddr,
|
||||
"tcpclienttest");
|
||||
auto policy = TLSPolicy::defaultClientPolicy();
|
||||
policy->setValidate(false);
|
||||
client[i]->enableSSL(std::move(policy));
|
||||
client[i]->setConnectionCallback(
|
||||
[i, &loop, &connCount](const TcpConnectionPtr &conn) {
|
||||
if (conn->connected())
|
||||
{
|
||||
LOG_DEBUG << i << " connected";
|
||||
conn->send("Hello");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG << i << " disconnected";
|
||||
--connCount;
|
||||
if (connCount == 0)
|
||||
loop.quit();
|
||||
}
|
||||
});
|
||||
client[i]->setMessageCallback(
|
||||
[](const TcpConnectionPtr &conn, MsgBuffer *buf) {
|
||||
auto msg = std::string(buf->peek(), buf->readableBytes());
|
||||
LOG_INFO << msg;
|
||||
buf->retrieveAll();
|
||||
});
|
||||
client[i]->connect();
|
||||
}
|
||||
loop.loop();
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
#include <trantor/net/TcpServer.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <trantor/net/EventLoopThread.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
using namespace trantor;
|
||||
#define USE_IPV6 0
|
||||
|
||||
bool has_ssl(MsgBuffer *buffer)
|
||||
{
|
||||
if (buffer->readableBytes() < 3)
|
||||
return false;
|
||||
const char *data = buffer->peek();
|
||||
unsigned char byte1 = static_cast<unsigned char>(data[0]);
|
||||
unsigned char byte2 = static_cast<unsigned char>(data[1]);
|
||||
unsigned char byte3 = static_cast<unsigned char>(data[2]);
|
||||
return (byte1 == 0x16) && (byte2 == 0x03) && (byte3 == 0x01);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
LOG_DEBUG << "test start";
|
||||
Logger::setLogLevel(Logger::kDebug);
|
||||
EventLoopThread loopThread;
|
||||
loopThread.run();
|
||||
#if USE_IPV6
|
||||
InetAddress addr(8888, true, true);
|
||||
#else
|
||||
InetAddress addr(8888);
|
||||
#endif
|
||||
TcpServer server(loopThread.getLoop(), addr, "test");
|
||||
// auto ctx = newSSLServerContext("server.pem", "server.pem", {});
|
||||
LOG_INFO << "start";
|
||||
server.setRecvMessageCallback(
|
||||
[](const TcpConnectionPtr &connectionPtr, MsgBuffer *buffer) {
|
||||
if (has_ssl(buffer))
|
||||
{
|
||||
LOG_DEBUG << "SSL data received";
|
||||
auto policy =
|
||||
TLSPolicy::defaultServerPolicy("server.crt", "server.key");
|
||||
connectionPtr->startEncryption(policy, true);
|
||||
connectionPtr->forwardToTLSBuffer(buffer);
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG << std::string{buffer->peek(), buffer->readableBytes()};
|
||||
connectionPtr->send(*buffer);
|
||||
buffer->retrieveAll();
|
||||
connectionPtr->shutdown();
|
||||
});
|
||||
server.setConnectionCallback([](const TcpConnectionPtr &connPtr) {
|
||||
if (connPtr->connected())
|
||||
{
|
||||
LOG_DEBUG << "New connection";
|
||||
}
|
||||
else if (connPtr->disconnected())
|
||||
{
|
||||
LOG_DEBUG << "connection disconnected";
|
||||
}
|
||||
});
|
||||
server.setIoLoopNum(3);
|
||||
server.start();
|
||||
loopThread.wait();
|
||||
}
|
||||
@@ -23,6 +23,8 @@ add_executable(logger_macro_test LoggerMacroTest.cc)
|
||||
add_executable(delayed_ssl_server_test DelayedSSLServerTest.cc)
|
||||
add_executable(delayed_ssl_client_test DelayedSSLClientTest.cc)
|
||||
add_executable(tcp_asyncstream_server_test TcpAsyncStreamServerTest.cc)
|
||||
add_executable(automatic_ssl_server_test AutomaticSSLServerTest.cc)
|
||||
add_executable(automatic_ssl_client_test AutomaticSSLClientTest.cc)
|
||||
set(targets_list
|
||||
ssl_server_test
|
||||
ssl_client_test
|
||||
@@ -49,6 +51,8 @@ set(targets_list
|
||||
delayed_ssl_server_test
|
||||
delayed_ssl_client_test
|
||||
tcp_asyncstream_server_test
|
||||
automatic_ssl_server_test
|
||||
automatic_ssl_client_test
|
||||
)
|
||||
|
||||
if(HAVE_SPDLOG)
|
||||
|
||||
@@ -4,7 +4,6 @@ add_executable(inetaddress_unittest InetAddressUnittest.cc)
|
||||
add_executable(date_unittest DateUnittest.cc)
|
||||
add_executable(split_string_unittest splitStringUnittest.cc)
|
||||
add_executable(string_encoding_unittest stringEncodingUnittest.cc)
|
||||
add_executable(ssl_name_verify_unittest sslNameVerifyUnittest.cc)
|
||||
add_executable(hash_unittest HashUnittest.cc)
|
||||
set(UNITTEST_TARGETS
|
||||
msgbuffer_unittest
|
||||
@@ -12,7 +11,6 @@ set(UNITTEST_TARGETS
|
||||
date_unittest
|
||||
split_string_unittest
|
||||
string_encoding_unittest
|
||||
ssl_name_verify_unittest
|
||||
hash_unittest
|
||||
)
|
||||
set_property(TARGET ${UNITTEST_TARGETS} PROPERTY CXX_STANDARD 14)
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#include <trantor/utils/Utilities.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
using namespace trantor;
|
||||
using namespace trantor::utils;
|
||||
|
||||
TEST(sslNameCheck, baseCases)
|
||||
{
|
||||
EXPECT_EQ(verifySslName("example.com", "example.com"), true);
|
||||
EXPECT_EQ(verifySslName("example.com", "example.org"), false);
|
||||
EXPECT_EQ(verifySslName("example.com", "www.example.com"), false);
|
||||
}
|
||||
|
||||
TEST(sslNameCheck, rfc6125Examples)
|
||||
{
|
||||
EXPECT_EQ(verifySslName("*.example.com", "foo.example.com"), true);
|
||||
EXPECT_EQ(verifySslName("*.example.com", "foo.bar.example.com"), false);
|
||||
EXPECT_EQ(verifySslName("*.example.com", "example.com"), false);
|
||||
EXPECT_EQ(verifySslName("*bar.example.com", "foobar.example.com"), true);
|
||||
EXPECT_EQ(verifySslName("baz*.example.com", "baz1.example.com"), true);
|
||||
EXPECT_EQ(verifySslName("b*z.example.com", "buzz.example.com"), true);
|
||||
}
|
||||
|
||||
TEST(sslNameCheck, rfcCounterExamples)
|
||||
{
|
||||
EXPECT_EQ(verifySslName("buz*.example.com", "buaz.example.com"), false);
|
||||
EXPECT_EQ(verifySslName("*bar.example.com", "aaasdasbaz.example.com"),
|
||||
false);
|
||||
EXPECT_EQ(verifySslName("b*z.example.com", "baaaaaa.example.com"), false);
|
||||
}
|
||||
|
||||
TEST(sslNameCheck, wildExamples)
|
||||
{
|
||||
EXPECT_EQ(verifySslName("datatracker.ietf.org", "datatracker.ietf.org"),
|
||||
true);
|
||||
EXPECT_EQ(verifySslName("*.nsysu.edu.tw", "nsysu.edu.tw"), false);
|
||||
EXPECT_EQ(verifySslName("nsysu.edu.tw", "nsysu.edu.tw"), true);
|
||||
}
|
||||
|
||||
TEST(sslNameCheck, edgeCase)
|
||||
{
|
||||
EXPECT_EQ(verifySslName(".example.com", "example.com"), false);
|
||||
EXPECT_EQ(verifySslName("example.com.", "example.com."), true);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -228,120 +228,6 @@ std::string fromWidePath(const std::wstring &wstrPath)
|
||||
return toUtf8(srcPath);
|
||||
}
|
||||
|
||||
bool verifySslName(const std::string &certName, const std::string &hostname)
|
||||
{
|
||||
if (certName.find('*') == std::string::npos)
|
||||
{
|
||||
return certName == hostname;
|
||||
}
|
||||
|
||||
size_t firstDot = certName.find('.');
|
||||
size_t hostFirstDot = hostname.find('.');
|
||||
size_t pos, len, hostPos, hostLen;
|
||||
|
||||
if (firstDot != std::string::npos)
|
||||
{
|
||||
pos = firstDot + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
firstDot = pos = certName.size();
|
||||
}
|
||||
|
||||
len = certName.size() - pos;
|
||||
|
||||
if (hostFirstDot != std::string::npos)
|
||||
{
|
||||
hostPos = hostFirstDot + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
hostFirstDot = hostPos = hostname.size();
|
||||
}
|
||||
|
||||
hostLen = hostname.size() - hostPos;
|
||||
|
||||
// *. in the beginning of the cert name
|
||||
if (certName.compare(0, firstDot, "*") == 0)
|
||||
{
|
||||
return certName.compare(pos, len, hostname, hostPos, hostLen) == 0;
|
||||
}
|
||||
// * in the left most. but other chars in the right
|
||||
else if (certName[0] == '*')
|
||||
{
|
||||
// compare if `hostname` ends with `certName` but without the leftmost
|
||||
// should be fine as domain names can't be that long
|
||||
intmax_t hostnameIdx = hostname.size() - 1;
|
||||
intmax_t certNameIdx = certName.size() - 1;
|
||||
while (hostnameIdx >= 0 && certNameIdx != 0)
|
||||
{
|
||||
if (hostname[hostnameIdx] != certName[certNameIdx])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
hostnameIdx--;
|
||||
certNameIdx--;
|
||||
}
|
||||
if (certNameIdx != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// * in the right of the first dot
|
||||
else if (firstDot != 0 && certName[firstDot - 1] == '*')
|
||||
{
|
||||
if (certName.compare(pos, len, hostname, hostPos, hostLen) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0;
|
||||
i < hostFirstDot && i < firstDot && certName[i] != '*';
|
||||
i++)
|
||||
{
|
||||
if (hostname[i] != certName[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// else there's a * in the middle
|
||||
else
|
||||
{
|
||||
if (certName.compare(pos, len, hostname, hostPos, hostLen) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0;
|
||||
i < hostFirstDot && i < firstDot && certName[i] != '*';
|
||||
i++)
|
||||
{
|
||||
if (hostname[i] != certName[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
intmax_t hostnameIdx = hostFirstDot - 1;
|
||||
intmax_t certNameIdx = firstDot - 1;
|
||||
while (hostnameIdx >= 0 && certNameIdx >= 0 &&
|
||||
certName[certNameIdx] != '*')
|
||||
{
|
||||
if (hostname[hostnameIdx] != certName[certNameIdx])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
hostnameIdx--;
|
||||
certNameIdx--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
assert(false && "This line should not be reached in verifySslName");
|
||||
// should not reach
|
||||
return certName == hostname;
|
||||
}
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
|
||||
|
||||
@@ -171,15 +171,6 @@ inline std::string fromNativePath(const std::wstring &strPath)
|
||||
return fromWidePath(strPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the name supplied by the SSL Cert matches a FQDN
|
||||
* @param certName The name supplied by the SSL Cert
|
||||
* @param hostName The FQDN to match
|
||||
*
|
||||
* @return true if matches. false otherwise
|
||||
*/
|
||||
bool verifySslName(const std::string &certName, const std::string &hostName);
|
||||
|
||||
/**
|
||||
* @brief Returns the TLS backend used by trantor. Could be "None", "OpenSSL" or
|
||||
* "Botan"
|
||||
|
||||
Reference in New Issue
Block a user