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>  | 
