Skip to content
Permalink
Browse files

http: implement secure connection

cmake: use provided findopenssl module
  • Loading branch information...
binarytrails committed Aug 5, 2019
1 parent 4054ec6 commit 49f6dd3c9c8e0fa156d29a07ae6f7aa53427d572
Showing with 76 additions and 89 deletions.
  1. +11 −15 CMakeLists.txt
  2. +0 −21 cmake/FindCrypto.cmake
  3. +0 −22 cmake/FindOpenSSL.cmake
  4. +10 −7 include/opendht/http.h
  5. +55 −24 src/http.cpp
@@ -70,19 +70,14 @@ if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT)
message(SEND_ERROR "Jsoncpp is required for DHT proxy support")
endif()
if (OPENDHT_PROXY_OPENSSL)
find_package(OpenSSL REQUIRED)
if (NOT OpenSSL_FOUND)
message(SEND_ERROR "OpenSSL is required for DHT proxy as specified")
else ()
message("OpenSSL found")
add_library(ssl SHARED IMPORTED)
# https://cmake.org/cmake/help/latest/module/FindOpenSSL.html
pkg_search_module(OPENSSL REQUIRED openssl)
if (OPENSSL_FOUND)
message(STATUS "Found OpenSSL ${OPENSSL_VERSION}")
include_directories(${OPENSSL_INCLUDE_DIRS})
add_definitions(-DOPENDHT_PROXY_OPENSSL)
find_package(Crypto REQUIRED)
if (NOT Crypto_FOUND)
message(SEND_ERROR "libcrypto is required for openssl")
else ()
add_library(crypto SHARED IMPORTED)
endif()
else ()
message(SEND_ERROR "OpenSSL is required for DHT proxy as specified")
endif()
endif()
endif()
@@ -288,7 +283,7 @@ if (OPENDHT_STATIC)
PRIVATE ${argon2_LIBRARIES}
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES} ${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY}
${Crypto_LIBRARIES} ${OpenSSL_LIBRARY})
${OPENSSL_LIBRARIES})
install (TARGETS opendht-static DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
endif ()

@@ -307,9 +302,9 @@ if (OPENDHT_SHARED)
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
endif ()
target_link_libraries(opendht
PUBLIC ${CMAKE_THREAD_LIBS_INIT}
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES} ${Crypto_LIBRARIES} ${OpenSSL_LIBRARY}
${Jsoncpp_LIBRARIES}
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY})

install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
@@ -381,6 +376,7 @@ if (OPENDHT_TESTS)
${CMAKE_THREAD_LIBS_INIT}
${CPPUNIT_LIBRARIES}
${GNUTLS_LIBRARIES}
ssl crypto
)
enable_testing()
add_test(TEST opendht_unit_tests)

This file was deleted.

This file was deleted.

@@ -33,10 +33,11 @@
namespace http {

using HandlerCb = std::function<void(const asio::error_code& ec)>;
using ConnectHandlerCb = std::function<void(const asio::error_code& ec,
const asio::ip::tcp::endpoint& endpoint)>;

#ifdef OPENDHT_PROXY_OPENSSL
using socket_t = restinio::impl::tls_socket_t;
//using socket_t = asio::ssl::stream<asio::ip::tcp::socket>;
#else
using socket_t = asio::ip::tcp::socket;
#endif
@@ -57,31 +58,33 @@ class OPENDHT_PUBLIC Connection
bool is_v6();

void set_endpoint(const asio::ip::tcp::endpoint& endpoint);
#ifdef OPENDHT_PROXY_OPENSSL
void set_verify_certificate(const std::string hostname, const asio::ssl::verify_mode verify_mode);
#endif

asio::streambuf& input();
asio::streambuf& data();

std::string read_bytes(const size_t bytes);
std::string read_until(const char delim);

#ifdef OPENDHT_PROXY_OPENSSL
socket_t& get_socket();
#else
socket_t& get_socket();

void async_connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, ConnectHandlerCb);
#ifdef OPENDHT_PROXY_OPENSSL
void async_handshake(HandlerCb cb);
#endif

void timeout(const std::chrono::seconds timeout, HandlerCb cb = {});

void close();

private:
unsigned int id_;
static unsigned int ids_;

asio::io_context& ctx_;
std::unique_ptr<socket_t> socket_;
#ifdef OPENDHT_PROXY_OPENSSL
std::unique_ptr<asio::ssl::context> ssl_ctx_;
std::shared_ptr<asio::ssl::context> ssl_ctx_;
asio::ssl::context::options ssl_options_;
#endif

@@ -37,15 +37,10 @@ Connection::Connection(asio::io_context& ctx, asio::ssl::context_base::method&&
std::shared_ptr<dht::Logger> l)
: id_(Connection::ids_++), ctx_(ctx), logger_(l)
{
ssl_ctx_ = std::make_unique<asio::ssl::context>(std::move(ssl_method));
ssl_ctx_ = std::make_shared<asio::ssl::context>(std::move(ssl_method));
ssl_ctx_->set_default_verify_paths();
ssl_ctx_->set_verify_mode(asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert);
/*
ssl_ctx_->use_certificate_chain_file(chain_file);
ssl_ctx_->use_private_key_file(key_file, asio::ssl::context::pem);
get_socket().set_verify_callback(asio::ssl::rfc2818_verification(host_name));
socket_ = std::make_unique<ssl_socket_t>(ctx_, ssl_ctx_.get());
*/
socket_ = std::make_unique<socket_t>(ctx_, ssl_ctx_);
}
#else
Connection::Connection(asio::io_context& ctx, std::shared_ptr<dht::Logger> l)
@@ -55,7 +50,13 @@ Connection::Connection(asio::io_context& ctx, std::shared_ptr<dht::Logger> l)

Connection::~Connection()
{
close();
if (is_open()){
#ifdef OPENDHT_PROXY_OPENSSL
get_socket().cancel();
get_socket().shutdown(asio::ip::tcp::socket::shutdown_both);
#endif
get_socket().close();
}
socket_.reset();
}

@@ -112,17 +113,35 @@ Connection::read_until(const char delim)
return content;
}

#ifdef OPENDHT_PROXY_OPENSSL
socket_t&
Connection::get_socket()
{
return *socket_;
}

void
Connection::async_connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, ConnectHandlerCb cb)
{
#ifdef OPENDHT_PROXY_OPENSSL
asio::async_connect(get_socket().lowest_layer(),
#else
socket_t&
Connection::get_socket()
asio::async_connect(get_socket(),
#endif
std::move(endpoints), cb);
}

#ifdef OPENDHT_PROXY_OPENSSL
void
Connection::set_verify_certificate(const std::string hostname, const asio::ssl::verify_mode verify_mode)
{
return *socket_;
socket_->asio_ssl_stream().set_verify_mode(verify_mode);
socket_->asio_ssl_stream().set_verify_callback(asio::ssl::rfc2818_verification(hostname));
}

void
Connection::async_handshake(HandlerCb cb)
{
socket_->async_handshake(asio::ssl::stream<asio::ip::tcp::socket>::client, cb);
}
#endif

@@ -149,12 +168,6 @@ Connection::timeout(const std::chrono::seconds timeout, HandlerCb cb)
});
}

void
Connection::close()
{
get_socket().close();
}

// connection listener

ConnectionListener::ConnectionListener()
@@ -571,12 +584,10 @@ Request::connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, HandlerCb cb)
}
}
conn_ = std::make_shared<Connection>(ctx_, asio::ssl::context::sslv23);
asio::async_connect(conn_->get_socket().lowest_layer(),
#else
conn_ = std::make_shared<Connection>(ctx_);
asio::async_connect(conn_->get_socket(),
#endif
std::move(endpoints), [this, cb]
conn_->async_connect(std::move(endpoints), [this, cb]
(const asio::error_code& ec, const asio::ip::tcp::endpoint& endpoint){
// try to connect to any until one works
if (ec == asio::error::operation_aborted)
@@ -591,8 +602,24 @@ Request::connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, HandlerCb cb)
// save the associated endpoint
conn_->set_endpoint(endpoint);
}
#ifdef OPENDHT_PROXY_OPENSSL
conn_->set_verify_certificate(endpoint.address().to_string(), asio::ssl::stream_base::client);
conn_->async_handshake([this, cb](const asio::error_code& ec){
if (ec){
if (logger_)
logger_->e("[http:request:%i] [connect:ssl] error: %s", id_, ec.message().c_str());
}
else {
if (logger_)
logger_->d("[http:request:%i] [connect:ssl] secure channel established", id_);
}
if (cb)
cb(ec);
});
#else
if (cb)
cb(ec);
#endif
});
}

@@ -644,8 +671,12 @@ Request::post()

// send the request
notify_state_change(State::SENDING);
asio::async_write(conn_->get_socket(), conn_->input(),
std::bind(&Request::handle_request, this, std::placeholders::_1));
#ifdef OPENDHT_PROXY_OPENSSL
asio::async_write(conn_->get_socket(),
#else
asio::async_write(conn_->get_socket(),
#endif
conn_->input(), std::bind(&Request::handle_request, this, std::placeholders::_1));
}

void
@@ -656,7 +687,7 @@ Request::terminate(const asio::error_code& ec)
logger_->e("[http:request:%i] end with error: %s", id_, ec.message().c_str());

// close the connection cancelling the scheduled socket operations on the io_context
conn_->close();
conn_.reset();
// reset the http_parser holding the data pointer to the user callbacks
parser_.reset();
parser_s_.reset();

0 comments on commit 49f6dd3

Please sign in to comment.
You can’t perform that action at this time.