diff options
-rw-r--r-- | https.cpp | 62 | ||||
-rw-r--r-- | webserver.conf | 3 |
2 files changed, 51 insertions, 14 deletions
@@ -6,6 +6,7 @@ #include "response.h" #include <openssl/ssl.h> +#include <openssl/crypto.h> #include <boost/asio/buffer.hpp> #include <boost/beast/core.hpp> @@ -566,25 +567,62 @@ void load_server_certificate(boost::asio::ssl::context& ctx, fs::path cert_path, boost::asio::buffer(dh.data(), dh.size())); } +int ServerNameError(SSL *s, HTTPS::Server::ctx_type& ctx_map) +{ + std::shared_ptr<ssl::context> ctx{ctx_map.at("")}; + SSL_set_SSL_CTX(s, ctx->native_handle()); + return SSL_CLIENT_HELLO_SUCCESS; // OK for now +} + int servername_callback(SSL *s, int *al, void *arg) { - int type {SSL_get_servername_type(s)}; - std::string server_name {SSL_get_servername(s, type)}; + HTTPS::Server::ctx_type& ctx_map = *(HTTPS::Server::ctx_type*)arg; + + if (0) { // not really necessary + int* numbers; + size_t numbers_size; + if (SSL_client_hello_get1_extensions_present(s, &numbers, &numbers_size) != 1) { + std::cout << "Error on SSL_client_hello_get1_extensions_present" << std::endl; + return ServerNameError(s, ctx_map); + } + bool server_name_available {false}; + for (size_t i = 0; i < numbers_size; i++) + if (numbers[i] == 0) + server_name_available = true; + + OPENSSL_free(numbers); + + if (!server_name_available) { + std::cout << "Error: No server_name available at SSL_client_hello_get1_extensions_present" << std::endl; + return ServerNameError(s, ctx_map); + } + } + + const unsigned char* data; + size_t data_size; + // 0 is server_name + if (SSL_client_hello_get0_ext(s, 0, &data, &data_size) != 1) { + std::cout << "Warning: Error on SSL_client_hello_get0_ext: servername not available. Using dummy ctx." << std::endl; + return ServerNameError(s, ctx_map); + } - HTTPS::Server::ctx_type* ctx_map = (HTTPS::Server::ctx_type*)arg; + // SNI Server Name, See https://tools.ietf.org/html/rfc6066 (TODO: why are there 5 bytes header?) + std::string server_name {std::string((const char*)data, (size_t)data_size)}; + if (server_name.size() >= 5 && server_name[0] == '\0') + server_name = server_name.substr(5); - auto it {ctx_map->find(server_name)}; + auto it {ctx_map.find(server_name)}; std::shared_ptr<ssl::context> ctx{}; - if (it != ctx_map->end()) { + if (it != ctx_map.end()) { ctx = it->second; } else { - std::cout << "Warning: server_name " << server_name << " not found in list of prepared contexts. Using dummy ctx." << std::endl; - ctx = ctx_map->at(""); + std::cout << "Warning: server_name " << server_name << " (" << server_name.size() << ") not found in list of prepared contexts. Using dummy ctx." << std::endl; + return ServerNameError(s, ctx_map); } SSL_set_SSL_CTX(s, ctx->native_handle()); - return SSL_TLSEXT_ERR_OK; + return SSL_CLIENT_HELLO_SUCCESS; } } // anonymous namespace @@ -598,9 +636,7 @@ Server::Server(Config& config, boost::asio::io_context& ioc, const Socket& socke // initial dummy, before we can add specific ctx w/ certificate std::shared_ptr<ssl::context> ctx_dummy{std::make_shared<ssl::context>(tls_method)}; load_server_certificate(*ctx_dummy, "", ""); - //SSL_CTX_set_client_hello_cb(ctx_dummy->native_handle(), servername_callback, &m_ctx); - SSL_CTX_set_tlsext_servername_callback(ctx_dummy->native_handle(), servername_callback); - SSL_CTX_set_tlsext_servername_arg(ctx_dummy->native_handle(), &m_ctx); + SSL_CTX_set_client_hello_cb(ctx_dummy->native_handle(), servername_callback, &m_ctx); m_ctx.emplace("", ctx_dummy); // import the real certificates @@ -612,9 +648,7 @@ Server::Server(Config& config, boost::asio::io_context& ioc, const Socket& socke std::cout << "Creating SSL context/cert for site " << serve_site << " on port " << socket.port << std::endl; load_server_certificate(*ctx, site.cert_path, site.key_path); - //SSL_CTX_set_client_hello_cb(ctx->native_handle(), servername_callback, &m_ctx); - SSL_CTX_set_tlsext_servername_callback(ctx->native_handle(), servername_callback); - SSL_CTX_set_tlsext_servername_arg(ctx->native_handle(), &m_ctx); + SSL_CTX_set_client_hello_cb(ctx->native_handle(), servername_callback, &m_ctx); for (const auto& host: site.hosts) { std::cout << " Adding Host " << host << std::endl; diff --git a/webserver.conf b/webserver.conf index 44dba49..e3731bc 100644 --- a/webserver.conf +++ b/webserver.conf @@ -13,6 +13,7 @@ <host>lists.antcom.de</host> <host>antcom.de</host> <host>www.antcom.de</host> + <host>localhost</host> <host>ip6-localhost</host> <host>127.0.0.1</host> <host>[::1]</host> @@ -32,6 +33,8 @@ <site> <name>marx</name> <host>marx.antcom.de</host> + <host>marx1.antcom.de</host> + <host>localhost</host> <path requested="/"> <plugin>static-files</plugin> <target>/home/ernie/homepage/test1</target> |