Exemple #1
0
std::shared_ptr<ssl_context> WSService::on_tls_init(websocketpp::connection_hdl hdl) {
	log_->trace() << log_tag() << BOOST_CURRENT_FUNCTION;

	auto ssl_ctx_ptr = make_ssl_ctx();
	ssl_ctx_ptr->set_verify_callback(std::bind(&WSService::on_tls_verify, this, hdl, std::placeholders::_1, std::placeholders::_2));
	return ssl_ctx_ptr;
}
    void TcpServer::AsyncSecureAccept() {
        auto errorHandler = std::bind(&TcpServer::ErrorHandler, this, std::placeholders::_1, std::placeholders::_2);
        
        auto context = boost::asio::ssl::context(boost::asio::ssl::context::sslv23);

		auto optionsMask = 
			boost::asio::ssl::context::default_workarounds
			| boost::asio::ssl::context::no_sslv2
			| boost::asio::ssl::context::single_dh_use;

		if (_securityOptions.VerifyClient)
		{
			auto verifyCallback = [](bool preverified,
				boost::asio::ssl::verify_context& ctx) {

				std::cout << "Verifying certificate, pre-verified: " << std::string(preverified ? "true" : "false");
				char subject_name[256];
				X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
				X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
				LOG() << "Verifying, subject: " << subject_name << "\n";

				char issuer_name[256];
				X509_NAME_oneline(X509_get_issuer_name(cert), issuer_name, 256);
				LOG() << "Verifying, issuer: " << issuer_name << "\n";

				return preverified;
			};

			context.set_verify_mode(boost::asio::ssl::context::verify_fail_if_no_peer_cert | boost::asio::ssl::verify_peer);
			context.set_verify_callback(verifyCallback);
			context.load_verify_file(_securityOptions.ClientVerifyFile);
		}

		context.set_options(optionsMask);
        
        context.set_password_callback(std::bind(&TcpServer::GetPassword, this));
        context.use_certificate_chain_file(_securityOptions.CertificateFilename);
        context.use_rsa_private_key_file(_securityOptions.PrivKeyFilename, boost::asio::ssl::context::pem);
        context.use_tmp_dh_file(_securityOptions.DHExchangeFilename);
        
        auto conn = std::make_shared<TcpSslConnection>(_ioService, std::move(context), std::move(errorHandler));
        
        auto acceptor = std::bind(&TcpServer::SecureAcceptHandler, this, conn, std::placeholders::_1);
        
        // Async accept does not block and takes references to the socket and end point of the connection.
        // The connection smart pointer is kept alive by being bound to the acceptor callback.
        _acceptor->async_accept(conn->PeerSocket, conn->PeerEndPoint, std::move(acceptor));
        
    }
Exemple #3
0
client
connect(const uri& uri)
{
	static asio::io_service service;

	if (uri.scheme() == "http")
    {
		auto socket = std::make_unique<http_socket_t>(service);
		connect(uri, socket);
		return std::make_shared<client_impl<http_socket_t>>(std::move(socket), uri.host());
    }
    else
    {
		ssl::context context(ssl::context::sslv23_client);
		context.set_default_verify_paths();

		auto socket = std::make_unique<https_socket_t>(service, context);
		connect(uri, socket);
		socket->set_verify_mode(ssl::verify_peer);
		socket->set_verify_callback(ssl::rfc2818_verification(uri.host()));
		socket->handshake(ssl::stream_base::client);
		return std::make_shared<client_impl<https_socket_t>>(std::move(socket), uri.host());
    }
}
Exemple #4
0
bool TLSClient::BeginConnect(const IPEndpoint& remote, const connect_callback_t& callback)
{
    if (canceled)
        return false;

    auto stream = std::make_shared<asio::ssl::stream<asio::ip::tcp::socket>>(this->executor->strand.get_io_service(),
                                                                             this->ctx.value);

    auto verify = [self = shared_from_this()](bool preverified, asio::ssl::verify_context& ctx) -> bool {
        self->LogVerifyCallback(preverified, ctx);
        return preverified;
    };

    std::error_code ec;
    stream->set_verify_callback(verify, ec);

    if (ec)
    {
        auto cb = [self = shared_from_this(), callback, stream, ec] {
            if (!self->canceled)
            {
                callback(self->executor, stream, ec);
            }
        };

        this->executor->strand.post(cb);
        return true;
    }

    SocketHelpers::BindToLocalAddress(this->adapter, this->localEndpoint, stream->lowest_layer(), ec);

    if (ec)
    {
        auto cb = [self = shared_from_this(), callback, stream, ec] {
            if (!self->canceled)
            {
                callback(self->executor, stream, ec);
            }
        };

        this->executor->strand.post(cb);
        return true;
    }

    const auto address = asio::ip::address::from_string(remote.address, ec);
    auto self = this->shared_from_this();
    if (ec)
    {
        // Try DNS resolution instead
        auto cb = [self, callback, stream](const std::error_code& ec, asio::ip::tcp::resolver::iterator endpoints) {
            self->HandleResolveResult(callback, stream, endpoints, ec);
        };

        std::stringstream portstr;
        portstr << remote.port;

        resolver.async_resolve(asio::ip::tcp::resolver::query(remote.address, portstr.str()),
                               executor->strand.wrap(cb));

        return true;
    }

    asio::ip::tcp::endpoint remoteEndpoint(address, remote.port);
    auto cb = [self, stream, callback](const std::error_code& ec) { self->HandleConnectResult(callback, stream, ec); };

    stream->lowest_layer().async_connect(remoteEndpoint, executor->strand.wrap(cb));
    return true;
}