summaryrefslogtreecommitdiffhomepage
path: root/https.cpp
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-04-05 12:03:52 +0200
committerRoland Reichwein <mail@reichwein.it>2020-04-05 12:03:52 +0200
commit918685c1c09de1e3cd14c41bb8cc8b89a177ccd2 (patch)
treef803517e6a34be0216f00249dd62525eadce0d05 /https.cpp
parentcbfc28a946ded64e9402e1e6d32511150339ec72 (diff)
Different certificates for different hosts
Diffstat (limited to 'https.cpp')
-rw-r--r--https.cpp66
1 files changed, 49 insertions, 17 deletions
diff --git a/https.cpp b/https.cpp
index b4e77f9..9d0784e 100644
--- a/https.cpp
+++ b/https.cpp
@@ -8,6 +8,7 @@
#include "server_certificate.h"
+#include <openssl/ssl.h>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
@@ -104,7 +105,8 @@ template<
class Send>
void
handle_request(
- beast::string_view doc_root,
+ const Config& config,
+ const Socket& socket,
http::request<Body, http::basic_fields<Allocator>>&& req,
Send&& send)
{
@@ -159,7 +161,9 @@ handle_request(
return send(bad_request("Illegal request-target"));
// Build the path to the requested file
- std::string path = path_cat(doc_root, req.target());
+ std::string host{req["host"]}; // TODO: just use string_view
+ std::string target{req.target()};
+ std::string path = path_cat(config.DocRoot(socket, host, target), req.target());
if(req.target().back() == '/')
path.append("index.html");
@@ -273,7 +277,8 @@ class session : public std::enable_shared_from_this<session>
beast::ssl_stream<beast::tcp_stream> stream_;
beast::flat_buffer buffer_;
- std::shared_ptr<std::string const> doc_root_;
+ const Config& m_config;
+ const Socket& m_socket;
http::request<http::string_body> req_;
std::shared_ptr<void> res_;
send_lambda lambda_;
@@ -284,9 +289,11 @@ public:
session(
tcp::socket&& socket,
ssl::context& ctx,
- std::shared_ptr<std::string const> const& doc_root)
+ const Config& config,
+ const Socket& config_socket)
: stream_(std::move(socket), ctx)
- , doc_root_(doc_root)
+ , m_config(config)
+ , m_socket(config_socket)
, lambda_(*this)
{
}
@@ -296,9 +303,7 @@ public:
run()
{
// We need to be executing within a strand to perform async operations
- // on the I/O objects in this session. Although not strictly necessary
- // for single-threaded contexts, this example code is written to be
- // thread-safe by default.
+ // on the I/O objects in this session.
net::dispatch(
stream_.get_executor(),
beast::bind_front_handler(
@@ -362,7 +367,7 @@ public:
return fail(ec, "read");
// Send the response
- handle_request(*doc_root_, std::move(req_), lambda_);
+ handle_request(m_config, m_socket, std::move(req_), lambda_);
}
void
@@ -421,18 +426,21 @@ class listener : public std::enable_shared_from_this<listener>
net::io_context& ioc_;
ssl::context& ctx_;
tcp::acceptor acceptor_;
- std::shared_ptr<std::string const> doc_root_;
+ const Config& m_config;
+ const Socket& m_socket;
public:
listener(
net::io_context& ioc,
ssl::context& ctx,
tcp::endpoint endpoint,
- std::shared_ptr<std::string const> const& doc_root)
+ const Config& config,
+ const Socket& socket)
: ioc_(ioc)
, ctx_(ctx)
, acceptor_(ioc)
- , doc_root_(doc_root)
+ , m_config(config)
+ , m_socket(socket)
{
beast::error_code ec;
@@ -502,7 +510,8 @@ private:
std::make_shared<session>(
std::move(socket),
ctx_,
- doc_root_)->run();
+ m_config,
+ m_socket)->run();
}
// Accept another connection
@@ -515,10 +524,34 @@ private:
namespace HTTPS {
+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)};
+
+ Server* server = (Server*)arg;
+ if (server_name == "lists.antcom.de"s) {
+ SSL_set_SSL_CTX(s, server->m_ctx.native_handle());
+ } else {
+ SSL_set_SSL_CTX(s, server->m_ctx2.native_handle());
+ }
+ return SSL_TLSEXT_ERR_OK;
+}
+
Server::Server(Config& config, boost::asio::io_context& ioc, const Socket& socket): ::Server(config, ioc), m_socket(socket)
{
- // This holds the self-signed certificate used by the server
+ for (const auto& site: socket.serve_sites) {
+ std::cout << "Creating SSL context/cert for site " << site << std::endl;
+ }
+
load_server_certificate(m_ctx, m_socket.cert_path, m_socket.key_path);
+ load_server_certificate(m_ctx2, "/home/ernie/code/webserver/cert.pem", "/home/ernie/code/webserver/key.pem");
+
+ SSL_CTX_set_tlsext_servername_callback(m_ctx.native_handle(), servername_callback);
+ SSL_CTX_set_tlsext_servername_arg(m_ctx.native_handle(), this);
+
+ SSL_CTX_set_tlsext_servername_callback(m_ctx2.native_handle(), servername_callback);
+ SSL_CTX_set_tlsext_servername_arg(m_ctx2.native_handle(), this);
}
Server::~Server()
@@ -527,17 +560,16 @@ Server::~Server()
int Server::start()
{
- // TODO: Config
auto const address = net::ip::make_address(m_socket.address);
auto const port = static_cast<unsigned short>(std::atoi(m_socket.port.data()));
- auto const doc_root = std::make_shared<std::string>(m_config.Sites()[0].paths[0].params.at("target"));
// Create and launch a listening port
std::make_shared<listener>(
m_ioc,
m_ctx,
tcp::endpoint{address, port},
- doc_root)->run();
+ m_config,
+ m_socket)->run();
return EXIT_SUCCESS;
}