improve support for SSL connections. make passing in the SSL context into the http_connection mandatory (simplifying it, so it doesn't have to create its own). Sepaate the SSL context used for trackers and SSL torrents, so normal trackers can be validated, without interfering with the special SNI callback used for SSL torrents

This commit is contained in:
arvidn 2020-03-13 12:15:39 +01:00 committed by Arvid Norberg
parent b1a3782264
commit 4fd6136b2a
21 changed files with 277 additions and 95 deletions

View File

@ -320,6 +320,7 @@ set(sources
instantiate_connection instantiate_connection
merkle merkle
natpmp natpmp
openssl
part_file part_file
packet_buffer packet_buffer
piece_picker piece_picker

View File

@ -1,3 +1,4 @@
* support validation of HTTPS trackers
* deprecate strict super seeding mode * deprecate strict super seeding mode
* make UPnP port-mapping lease duration configurable * make UPnP port-mapping lease duration configurable
* deprecate the bittyrant choking algorithm * deprecate the bittyrant choking algorithm

View File

@ -663,6 +663,7 @@ SOURCES =
instantiate_connection instantiate_connection
lazy_bdecode lazy_bdecode
natpmp natpmp
openssl
packet_buffer packet_buffer
piece_picker piece_picker
peer_list peer_list

View File

@ -559,3 +559,6 @@ leecher
6881l 6881l
NOTSENT NOTSENT
LOWAT LOWAT
tls11
tls12
tls13

View File

@ -51,7 +51,6 @@ POSSIBILITY OF SUCH DAMAGE.
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
// all of OpenSSL causes warnings, so we just have to disable them
#include "libtorrent/aux_/disable_warnings_push.hpp" #include "libtorrent/aux_/disable_warnings_push.hpp"
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
@ -63,43 +62,50 @@ POSSIBILITY OF SUCH DAMAGE.
#include <openssl/safestack.h> // for sk_GENERAL_NAME_value #include <openssl/safestack.h> // for sk_GENERAL_NAME_value
#include <openssl/x509v3.h> // for GENERAL_NAME #include <openssl/x509v3.h> // for GENERAL_NAME
namespace libtorrent { namespace aux { #include <boost/asio/ssl.hpp>
inline void openssl_set_tlsext_hostname(SSL* s, char const* name) #if defined TORRENT_BUILD_SIMULATOR
{ #include "simulator/simulator.hpp"
#if OPENSSL_VERSION_NUMBER >= 0x90812f
SSL_set_tlsext_host_name(s, name);
#endif #endif
}
#include "libtorrent/aux_/disable_warnings_pop.hpp"
namespace libtorrent {
namespace ssl {
#if defined TORRENT_BUILD_SIMULATOR
using sim::asio::ssl::context;
using sim::asio::ssl::stream_base;
using sim::asio::ssl::stream;
#else
using boost::asio::ssl::context;
using boost::asio::ssl::stream_base;
using boost::asio::ssl::stream;
#endif
} // ssl
namespace aux {
TORRENT_EXTRA_EXPORT void openssl_set_tlsext_hostname(SSL* s, char const* name);
#if OPENSSL_VERSION_NUMBER >= 0x90812f #if OPENSSL_VERSION_NUMBER >= 0x90812f
inline void openssl_set_tlsext_servername_callback(SSL_CTX* ctx TORRENT_EXTRA_EXPORT void openssl_set_tlsext_servername_callback(SSL_CTX* ctx
, int (*servername_callback)(SSL*, int*, void*)) , int (*servername_callback)(SSL*, int*, void*));
{
SSL_CTX_set_tlsext_servername_callback(ctx, servername_callback);
}
inline void openssl_set_tlsext_servername_arg(SSL_CTX* ctx, void* userdata) TORRENT_EXTRA_EXPORT void openssl_set_tlsext_servername_arg(SSL_CTX* ctx, void* userdata);
{
SSL_CTX_set_tlsext_servername_arg(ctx, userdata);
}
inline int openssl_num_general_names(GENERAL_NAMES* gens) TORRENT_EXTRA_EXPORT int openssl_num_general_names(GENERAL_NAMES* gens);
{
return sk_GENERAL_NAME_num(gens);
}
inline GENERAL_NAME* openssl_general_name_value(GENERAL_NAMES* gens, int i) TORRENT_EXTRA_EXPORT GENERAL_NAME* openssl_general_name_value(GENERAL_NAMES* gens, int i);
{
return sk_GENERAL_NAME_value(gens, i);
}
#endif // OPENSSL_VERSION_NUMBER #endif // OPENSSL_VERSION_NUMBER
} // converts setting_pack::ssl_version_t enum into asio version
} ssl::context::method ssl_version(int const v);
#include "libtorrent/aux_/disable_warnings_pop.hpp" } // aux
} // libtorrent
#endif // TORRENT_USE_OPENSSL #endif // TORRENT_USE_OPENSSL

View File

@ -876,9 +876,14 @@ namespace aux {
io_service& m_io_service; io_service& m_io_service;
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
// this is a generic SSL context used when talking to // this is a generic SSL context used when talking to HTTPS servers
// unauthenticated HTTPS servers
ssl::context m_ssl_ctx; ssl::context m_ssl_ctx;
// this is the SSL context used for SSL listen sockets. It doesn't
// verify peers, but it has the servername callback set on it. Once it
// knows which torrent a peer is connecting to, it will switch the
// socket over to the torrent specific context, which does verify peers
ssl::context m_peer_ssl_ctx;
#endif #endif
// handles delayed alerts // handles delayed alerts

View File

@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/version.hpp>
#include "libtorrent/aux_/disable_warnings_pop.hpp" #include "libtorrent/aux_/disable_warnings_pop.hpp"
@ -567,6 +568,14 @@ constexpr std::size_t TORRENT_WRITE_HANDLER_MAX_SIZE = 342;
#endif #endif
#endif // TORRENT_HAS_ARM_CRC32 #endif // TORRENT_HAS_ARM_CRC32
#ifndef TORRENT_USE_TLS13
#if BOOST_VERSION >= 106900
#define TORRENT_USE_TLS13 1
#else
#define TORRENT_USE_TLS13 0
#endif
#endif
namespace libtorrent {} namespace libtorrent {}
// create alias // create alias

View File

@ -82,12 +82,12 @@ struct TORRENT_EXTRA_EXPORT http_connection
http_connection(io_service& ios http_connection(io_service& ios
, resolver_interface& resolver , resolver_interface& resolver
, http_handler const& handler , http_handler const& handler
, bool bottled = true , bool bottled
, int max_bottled_buffer_size = default_max_bottled_buffer_size , int max_bottled_buffer_size
, http_connect_handler const& ch = http_connect_handler() , http_connect_handler const& ch
, http_filter_handler const& fh = http_filter_handler() , http_filter_handler const& fh
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
, ssl::context* ssl_ctx = nullptr , ssl::context* ssl_ctx
#endif #endif
); );
@ -165,7 +165,6 @@ private:
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
ssl::context* m_ssl_ctx; ssl::context* m_ssl_ctx;
bool m_own_ssl_context;
#endif #endif
#if TORRENT_USE_I2P #if TORRENT_USE_I2P

View File

@ -1746,6 +1746,12 @@ namespace aux {
// lower than 5 minutes. // lower than 5 minutes.
upnp_lease_duration, upnp_lease_duration,
// the SSL/TLS version to use for HTTPS trackers and SSL torrents. Set
// it to one of the ssl_version_t values. This setting only takes
// effect when passed in to the session constructor. It cannot be
// changed once the session has been constructed.
ssl_version,
max_int_setting_internal max_int_setting_internal
}; };
@ -1759,6 +1765,18 @@ namespace aux {
enum suggest_mode_t : std::uint8_t { no_piece_suggestions = 0, suggest_read_cache = 1 }; enum suggest_mode_t : std::uint8_t { no_piece_suggestions = 0, suggest_read_cache = 1 };
enum ssl_version_t : std::uint8_t
{
// TLS version 1.1
tls11,
// TLS version 1.2
tls12,
#if TORRENT_USE_TLS13
// TLS version 1.3
tls13,
#endif
};
enum choking_algorithm_t : std::uint8_t enum choking_algorithm_t : std::uint8_t
{ {
fixed_slots_choker = 0, fixed_slots_choker = 0,

View File

@ -42,28 +42,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include <functional> #include <functional>
#include "libtorrent/aux_/disable_warnings_push.hpp"
#include <boost/asio/ssl.hpp>
#if defined TORRENT_BUILD_SIMULATOR
#include "simulator/simulator.hpp"
#endif
#include "libtorrent/aux_/disable_warnings_pop.hpp"
namespace libtorrent { namespace libtorrent {
namespace ssl {
#if defined TORRENT_BUILD_SIMULATOR
using sim::asio::ssl::context;
using sim::asio::ssl::stream_base;
using sim::asio::ssl::stream;
#else
using boost::asio::ssl::context;
using boost::asio::ssl::stream_base;
using boost::asio::ssl::stream;
#endif
}
template <class Stream> template <class Stream>
class ssl_stream class ssl_stream
{ {

View File

@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/portmap.hpp" #include "libtorrent/aux_/portmap.hpp"
#include "libtorrent/aux_/vector.hpp" #include "libtorrent/aux_/vector.hpp"
#include "libtorrent/aux_/session_settings.hpp" #include "libtorrent/aux_/session_settings.hpp"
#include "libtorrent/aux_/openssl.hpp" // for ssl::context
#include <memory> #include <memory>
#include <functional> #include <functional>
@ -357,6 +358,10 @@ private:
address_v4 m_listen_address; address_v4 m_listen_address;
address_v4 m_netmask; address_v4 m_netmask;
std::string m_device; std::string m_device;
#ifdef TORRENT_USE_OPENSSL
ssl::context m_ssl_ctx;
#endif
}; };
} }

View File

@ -131,6 +131,11 @@ std::shared_ptr<http_connection> test_request(io_service& ios
{ {
std::printf(" ===== TESTING: %s =====\n", url.c_str()); std::printf(" ===== TESTING: %s =====\n", url.c_str());
#ifdef TORRENT_USE_OPENSSL
ssl::context ssl_ctx(ssl::context::sslv23_client);
ssl_ctx.set_verify_mode(ssl::context::verify_none);
#endif
auto h = std::make_shared<http_connection>(ios auto h = std::make_shared<http_connection>(ios
, res , res
, [=](error_code const& ec, http_parser const& parser , [=](error_code const& ec, http_parser const& parser
@ -177,7 +182,12 @@ std::shared_ptr<http_connection> test_request(io_service& ios
++*connect_handler_called; ++*connect_handler_called;
TEST_CHECK(c.socket().is_open()); TEST_CHECK(c.socket().is_open());
std::printf("CONNECTED: %s\n", url.c_str()); std::printf("CONNECTED: %s\n", url.c_str());
}); }
, lt::http_filter_handler()
#ifdef TORRENT_USE_OPENSSL
, &ssl_ctx
#endif
);
h->get(url, seconds(1), 0, &ps, 5, "test/user-agent", boost::none h->get(url, seconds(1), 0, &ps, 5, "test/user-agent", boost::none
, resolver_flags{}, auth); , resolver_flags{}, auth);
@ -630,14 +640,25 @@ TORRENT_TEST(http_connection_ssl_proxy)
return sim::send_response(403, "Not supported", 1337); return sim::send_response(403, "Not supported", 1337);
}); });
#ifdef TORRENT_USE_OPENSSL
lt::ssl::context ssl_ctx(ssl::context::sslv23_client);
ssl_ctx.set_verify_mode(ssl::context::verify_none);
#endif
auto h = std::make_shared<http_connection>(client_ios auto h = std::make_shared<http_connection>(client_ios
, res , res
, [&client_counter](error_code const& ec, http_parser const& , [&client_counter](error_code const& ec, http_parser const&
, span<char const>, http_connection&) , span<char const>, http_connection&)
{ {
client_counter++; client_counter++;
TEST_EQUAL(ec, boost::asio::error::operation_not_supported); TEST_EQUAL(ec, boost::asio::error::operation_not_supported);
}); }
, true, 1024*1024, lt::http_connect_handler()
, http_filter_handler()
#ifdef TORRENT_USE_OPENSSL
, &ssl_ctx
#endif
);
h->start("10.0.0.2", 8080, seconds(1), 0, &ps, true /*ssl*/); h->start("10.0.0.2", 8080, seconds(1), 0, &ps, true /*ssl*/);

View File

@ -94,6 +94,7 @@ libtorrent_rasterbar_la_SOURCES = \
magnet_uri.cpp \ magnet_uri.cpp \
merkle.cpp \ merkle.cpp \
natpmp.cpp \ natpmp.cpp \
openssl.cpp \
parse_url.cpp \ parse_url.cpp \
part_file.cpp \ part_file.cpp \
pe_crypto.cpp \ pe_crypto.cpp \

View File

@ -74,7 +74,6 @@ http_connection::http_connection(io_service& ios
, m_sock(ios) , m_sock(ios)
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
, m_ssl_ctx(ssl_ctx) , m_ssl_ctx(ssl_ctx)
, m_own_ssl_context(false)
#endif #endif
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
, m_i2p_conn(nullptr) , m_i2p_conn(nullptr)
@ -107,12 +106,7 @@ http_connection::http_connection(io_service& ios
TORRENT_ASSERT(m_handler); TORRENT_ASSERT(m_handler);
} }
http_connection::~http_connection() http_connection::~http_connection() = default;
{
#ifdef TORRENT_USE_OPENSSL
if (m_own_ssl_context) delete m_ssl_ctx;
#endif
}
void http_connection::get(std::string const& url, time_duration timeout, int prio void http_connection::get(std::string const& url, time_duration timeout, int prio
, aux::proxy_settings const* ps, int handle_redirects, std::string const& user_agent , aux::proxy_settings const* ps, int handle_redirects, std::string const& user_agent
@ -256,6 +250,10 @@ void http_connection::start(std::string const& hostname, int port
m_read_pos = 0; m_read_pos = 0;
m_priority = prio; m_priority = prio;
#ifdef TORRENT_USE_OPENSSL
TORRENT_ASSERT(!ssl || m_ssl_ctx != nullptr);
#endif
if (ec) if (ec)
{ {
lt::get_io_service(m_timer).post(std::bind(&http_connection::callback lt::get_io_service(m_timer).post(std::bind(&http_connection::callback
@ -323,21 +321,7 @@ void http_connection::start(std::string const& hostname, int port
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
if (m_ssl) if (m_ssl)
{ {
if (m_ssl_ctx == nullptr) TORRENT_ASSERT(m_ssl_ctx != nullptr);
{
m_ssl_ctx = new (std::nothrow) ssl::context(ssl::context::sslv23_client);
if (m_ssl_ctx)
{
m_own_ssl_context = true;
m_ssl_ctx->set_verify_mode(ssl::context::verify_none, ec);
if (ec)
{
lt::get_io_service(m_timer).post(std::bind(&http_connection::callback
, me, ec, span<char>{}));
return;
}
}
}
userdata = m_ssl_ctx; userdata = m_ssl_ctx;
} }
#endif #endif

97
src/openssl.cpp Normal file
View File

@ -0,0 +1,97 @@
/*
Copyright (c) 2020, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "libtorrent/config.hpp"
#include "libtorrent/aux_/openssl.hpp"
#include "libtorrent/settings_pack.hpp"
namespace libtorrent {
namespace aux {
#ifdef TORRENT_USE_OPENSSL
// all of OpenSSL causes warnings, so we just have to disable them
#include "libtorrent/aux_/disable_warnings_push.hpp"
void openssl_set_tlsext_hostname(SSL* s, char const* name)
{
#if OPENSSL_VERSION_NUMBER >= 0x90812f
SSL_set_tlsext_host_name(s, name);
#endif
}
#if OPENSSL_VERSION_NUMBER >= 0x90812f
void openssl_set_tlsext_servername_callback(SSL_CTX* ctx
, int (*servername_callback)(SSL*, int*, void*))
{
SSL_CTX_set_tlsext_servername_callback(ctx, servername_callback);
}
void openssl_set_tlsext_servername_arg(SSL_CTX* ctx, void* userdata)
{
SSL_CTX_set_tlsext_servername_arg(ctx, userdata);
}
int openssl_num_general_names(GENERAL_NAMES* gens)
{
return sk_GENERAL_NAME_num(gens);
}
GENERAL_NAME* openssl_general_name_value(GENERAL_NAMES* gens, int i)
{
return sk_GENERAL_NAME_value(gens, i);
}
#include "libtorrent/aux_/disable_warnings_pop.hpp"
#endif // OPENSSL_VERSION_NUMBER
ssl::context::method ssl_version(int const v)
{
switch (v)
{
case settings_pack::tls11: return ssl::context::tlsv11;
case settings_pack::tls12: return ssl::context::tlsv12;
#if TORRENT_USE_TLS13
case settings_pack::tls13: return ssl::context::tlsv13;
default: return ssl::context::tlsv13;
#else
default: return ssl::context::tlsv12;
#endif
};
}
#endif // TORRENT_USE_OPENSSL
}
}

View File

@ -454,7 +454,8 @@ namespace aux {
: m_settings(pack) : m_settings(pack)
, m_io_service(ios) , m_io_service(ios)
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
, m_ssl_ctx(boost::asio::ssl::context::sslv23) , m_ssl_ctx(ssl_version(pack.get_int(settings_pack::ssl_version)))
, m_peer_ssl_ctx(ssl_version(pack.get_int(settings_pack::ssl_version)))
#endif #endif
, m_alerts(m_settings.get_int(settings_pack::alert_queue_size) , m_alerts(m_settings.get_int(settings_pack::alert_queue_size)
, alert_category_t{static_cast<unsigned int>(m_settings.get_int(settings_pack::alert_mask))}) , alert_category_t{static_cast<unsigned int>(m_settings.get_int(settings_pack::alert_mask))})
@ -495,7 +496,7 @@ namespace aux {
, std::bind(&session_impl::on_incoming_utp_ssl, this, _1) , std::bind(&session_impl::on_incoming_utp_ssl, this, _1)
, m_io_service , m_io_service
, m_settings, m_stats_counters , m_settings, m_stats_counters
, &m_ssl_ctx) , &m_peer_ssl_ctx)
#endif #endif
, m_timer(m_io_service) , m_timer(m_io_service)
, m_lsd_announce_timer(m_io_service) , m_lsd_announce_timer(m_io_service)
@ -537,10 +538,11 @@ namespace aux {
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
error_code ec; error_code ec;
m_ssl_ctx.set_verify_mode(boost::asio::ssl::context::verify_none, ec); m_ssl_ctx.set_verify_mode(boost::asio::ssl::context::verify_none, ec);
m_peer_ssl_ctx.set_verify_mode(boost::asio::ssl::context::verify_none, ec);
#if OPENSSL_VERSION_NUMBER >= 0x90812f #if OPENSSL_VERSION_NUMBER >= 0x90812f
aux::openssl_set_tlsext_servername_callback(m_ssl_ctx.native_handle() aux::openssl_set_tlsext_servername_callback(m_peer_ssl_ctx.native_handle()
, servername_callback); , servername_callback);
aux::openssl_set_tlsext_servername_arg(m_ssl_ctx.native_handle(), this); aux::openssl_set_tlsext_servername_arg(m_peer_ssl_ctx.native_handle(), this);
#endif // OPENSSL_VERSION_NUMBER #endif // OPENSSL_VERSION_NUMBER
#endif #endif
@ -2461,11 +2463,11 @@ namespace {
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
if (ssl == transport::ssl) if (ssl == transport::ssl)
{ {
// accept connections initializing the SSL connection to // accept connections initializing the SSL connection to use the peer
// use the generic m_ssl_ctx context. However, since it has // ssl context. Since it has the servername callback set on it, we will
// the servername callback set on it, we will switch away from // switch away from this context into a specific torrent once we start
// this context into a specific torrent once we start handshaking // handshaking
c->instantiate<ssl_stream<tcp::socket>>(m_io_service, &m_ssl_ctx); c->instantiate<ssl_stream<tcp::socket>>(m_io_service, &m_peer_ssl_ctx);
str = &c->get<ssl_stream<tcp::socket>>()->next_layer(); str = &c->get<ssl_stream<tcp::socket>>()->next_layer();
} }
else else

View File

@ -350,6 +350,11 @@ constexpr int CLOSE_FILE_INTERVAL = 0;
SET(resolver_cache_timeout, 1200, &session_impl::update_resolver_cache_timeout), SET(resolver_cache_timeout, 1200, &session_impl::update_resolver_cache_timeout),
SET(send_not_sent_low_watermark, 16384, nullptr), SET(send_not_sent_low_watermark, 16384, nullptr),
SET(upnp_lease_duration, 3600, nullptr), SET(upnp_lease_duration, 3600, nullptr),
#if TORRENT_USE_TLS13
SET(ssl_version, settings_pack::tls13, nullptr),
#else
SET(ssl_version, settings_pack::tls12, nullptr),
#endif
}}); }});
#undef SET #undef SET

View File

@ -1625,7 +1625,8 @@ bool is_downloading_state(int const st)
// create the SSL context for this torrent. We need to // create the SSL context for this torrent. We need to
// inject the root certificate, and no other, to // inject the root certificate, and no other, to
// verify other peers against // verify other peers against
std::shared_ptr<context> ctx = std::make_shared<context>(context::sslv23); std::shared_ptr<context> ctx = std::make_shared<context>(
aux::ssl_version(settings().get_int(settings_pack::ssl_version)));
if (!ctx) if (!ctx)
{ {

View File

@ -50,6 +50,9 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/disable_warnings_push.hpp" #include "libtorrent/aux_/disable_warnings_push.hpp"
#include <boost/asio/ip/host_name.hpp> #include <boost/asio/ip/host_name.hpp>
#include <boost/asio/ip/multicast.hpp> #include <boost/asio/ip/multicast.hpp>
#ifdef TORRENT_USE_OPENSSL
#include <boost/asio/ssl/context.hpp>
#endif
#include "libtorrent/aux_/disable_warnings_pop.hpp" #include "libtorrent/aux_/disable_warnings_pop.hpp"
#include <cstdlib> #include <cstdlib>
@ -114,7 +117,13 @@ upnp::upnp(io_service& ios
, m_listen_address(listen_address) , m_listen_address(listen_address)
, m_netmask(netmask) , m_netmask(netmask)
, m_device(std::move(listen_device)) , m_device(std::move(listen_device))
#ifdef TORRENT_USE_OPENSSL
, m_ssl_ctx(ssl::context::sslv23_client)
#endif
{ {
#ifdef TORRENT_USE_OPENSSL
m_ssl_ctx.set_verify_mode(ssl::context::verify_none);
#endif
} }
void upnp::start() void upnp::start()
@ -420,7 +429,13 @@ void upnp::connect(rootdevice& d)
d.upnp_connection = std::make_shared<http_connection>(m_io_service d.upnp_connection = std::make_shared<http_connection>(m_io_service
, m_resolver , m_resolver
, std::bind(&upnp::on_upnp_xml, self(), _1, _2 , std::bind(&upnp::on_upnp_xml, self(), _1, _2
, std::ref(d), _4)); , std::ref(d), _4), true, default_max_bottled_buffer_size
, http_connect_handler()
, http_filter_handler()
#ifdef TORRENT_USE_OPENSSL
, &m_ssl_ctx
#endif
);
d.upnp_connection->get(d.url, seconds(30), 1); d.upnp_connection->get(d.url, seconds(30), 1);
} }
TORRENT_CATCH (std::exception const& exc) TORRENT_CATCH (std::exception const& exc)
@ -819,7 +834,12 @@ void upnp::update_map(rootdevice& d, port_mapping_t const i)
, m_resolver , m_resolver
, std::bind(&upnp::on_upnp_map_response, self(), _1, _2 , std::bind(&upnp::on_upnp_map_response, self(), _1, _2
, std::ref(d), i, _4), true, default_max_bottled_buffer_size , std::ref(d), i, _4), true, default_max_bottled_buffer_size
, std::bind(&upnp::create_port_mapping, self(), _1, std::ref(d), i)); , std::bind(&upnp::create_port_mapping, self(), _1, std::ref(d), i)
, http_filter_handler()
#ifdef TORRENT_USE_OPENSSL
, &m_ssl_ctx
#endif
);
d.upnp_connection->start(d.hostname, d.port d.upnp_connection->start(d.hostname, d.port
, seconds(10), 1, nullptr, false, 5, m.local_ep.address()); , seconds(10), 1, nullptr, false, 5, m.local_ep.address());
@ -831,7 +851,12 @@ void upnp::update_map(rootdevice& d, port_mapping_t const i)
, m_resolver , m_resolver
, std::bind(&upnp::on_upnp_unmap_response, self(), _1, _2 , std::bind(&upnp::on_upnp_unmap_response, self(), _1, _2
, std::ref(d), i, _4), true, default_max_bottled_buffer_size , std::ref(d), i, _4), true, default_max_bottled_buffer_size
, std::bind(&upnp::delete_port_mapping, self(), std::ref(d), i)); , std::bind(&upnp::delete_port_mapping, self(), std::ref(d), i)
, http_filter_handler()
#ifdef TORRENT_USE_OPENSSL
, &m_ssl_ctx
#endif
);
d.upnp_connection->start(d.hostname, d.port d.upnp_connection->start(d.hostname, d.port
, seconds(10), 1, nullptr, false, 5, m.local_ep.address()); , seconds(10), 1, nullptr, false, 5, m.local_ep.address());
} }
@ -1044,7 +1069,12 @@ void upnp::on_upnp_xml(error_code const& e
, m_resolver , m_resolver
, std::bind(&upnp::on_upnp_get_ip_address_response, self(), _1, _2 , std::bind(&upnp::on_upnp_get_ip_address_response, self(), _1, _2
, std::ref(d), _4), true, default_max_bottled_buffer_size , std::ref(d), _4), true, default_max_bottled_buffer_size
, std::bind(&upnp::get_ip_address, self(), std::ref(d))); , std::bind(&upnp::get_ip_address, self(), std::ref(d))
, http_filter_handler()
#ifdef TORRENT_USE_OPENSSL
, &m_ssl_ctx
#endif
);
d.upnp_connection->start(d.hostname, d.port d.upnp_connection->start(d.hostname, d.port
, seconds(10), 1); , seconds(10), 1);
} }

View File

@ -87,6 +87,9 @@ lt::settings_pack settings()
pack.set_int(settings_pack::half_open_limit, 1); pack.set_int(settings_pack::half_open_limit, 1);
#endif #endif
// to be compatible with python
pack.set_int(settings_pack::ssl_version, settings_pack::tls12);
return pack; return pack;
} }

View File

@ -121,8 +121,18 @@ void run_test(std::string const& url, int size, int status, int connected
<< " connected: " << connected << " connected: " << connected
<< " error: " << (ec?ec->message():"no error") << std::endl; << " error: " << (ec?ec->message():"no error") << std::endl;
#ifdef TORRENT_USE_OPENSSL
ssl::context ssl_ctx(ssl::context::sslv23_client);
ssl_ctx.set_verify_mode(ssl::context::verify_none);
#endif
std::shared_ptr<http_connection> h = std::make_shared<http_connection>(ios std::shared_ptr<http_connection> h = std::make_shared<http_connection>(ios
, res, &::http_handler_test, true, 1024*1024, &::http_connect_handler_test); , res, &::http_handler_test, true, 1024*1024, &::http_connect_handler_test
, http_filter_handler()
#ifdef TORRENT_USE_OPENSSL
, &ssl_ctx
#endif
);
h->get(url, seconds(5), 0, &ps, 5, "test/user-agent", boost::none, resolver_flags{}, auth); h->get(url, seconds(5), 0, &ps, 5, "test/user-agent", boost::none, resolver_flags{}, auth);
ios.reset(); ios.reset();
error_code e; error_code e;