forked from premiere/premiere-libtorrent
merged SSL fix from RC_0_16
This commit is contained in:
parent
05aeda31c6
commit
6acde24799
|
@ -422,11 +422,11 @@ inline int snprintf(char* buf, int len, char const* fmt, ...)
|
|||
#endif
|
||||
|
||||
#if !defined(TORRENT_READ_HANDLER_MAX_SIZE)
|
||||
# define TORRENT_READ_HANDLER_MAX_SIZE 256
|
||||
# define TORRENT_READ_HANDLER_MAX_SIZE 300
|
||||
#endif
|
||||
|
||||
#if !defined(TORRENT_WRITE_HANDLER_MAX_SIZE)
|
||||
# define TORRENT_WRITE_HANDLER_MAX_SIZE 256
|
||||
# define TORRENT_WRITE_HANDLER_MAX_SIZE 300
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER <= 1200
|
||||
|
|
|
@ -42,9 +42,7 @@ namespace libtorrent
|
|||
struct utp_socket_manager;
|
||||
struct socket_type;
|
||||
|
||||
// if from is specified, a new socket will be created
|
||||
// using the same underlying socket object as 'from'.
|
||||
// this can be used to "upgrade" a socket into an SSL socket
|
||||
// instantiate a socket_type (s) according to the specified criteria
|
||||
TORRENT_EXTRA_EXPORT bool instantiate_connection(io_service& ios
|
||||
, proxy_settings const& ps, socket_type& s
|
||||
, void* ssl_context = 0
|
||||
|
|
|
@ -295,8 +295,15 @@ namespace libtorrent
|
|||
size_type m_data[(storage_size + sizeof(size_type) - 1) / sizeof(size_type)];
|
||||
};
|
||||
|
||||
// returns true if this socket is an SSL socket
|
||||
bool is_ssl(socket_type const& s);
|
||||
|
||||
// assuming the socket_type s is an ssl socket, make sure it
|
||||
// verifies the hostname in its SSL handshake
|
||||
void setup_ssl_hostname(socket_type& s, std::string const& hostname, error_code& ec);
|
||||
|
||||
// properly shuts down SSL sockets. holder keeps s alive
|
||||
void async_shutdown(socket_type& s, boost::shared_ptr<void> holder);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,15 +37,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/parse_url.hpp"
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/connection_queue.hpp"
|
||||
#include "libtorrent/socket_type.hpp" // for async_shutdown
|
||||
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
#include "libtorrent/debug.hpp"
|
||||
#endif
|
||||
|
||||
#if defined TORRENT_USE_OPENSSL && BOOST_VERSION >= 104700
|
||||
#include <boost/asio/ssl/rfc2818_verification.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
@ -92,10 +89,6 @@ http_connection::http_connection(io_service& ios, connection_queue& cc
|
|||
, m_abort(false)
|
||||
{
|
||||
TORRENT_ASSERT(!m_handler.empty());
|
||||
// TODO: if we were handed an SSL context, we should really
|
||||
// verify the hostname of the web server as well. This is supported
|
||||
// in boost starting with version 1.47.0. See ssl::rfc2818_verification
|
||||
// and ssl::context::set_verify_callback
|
||||
}
|
||||
|
||||
http_connection::~http_connection()
|
||||
|
@ -262,7 +255,7 @@ void http_connection::start(std::string const& hostname, std::string const& port
|
|||
m_ssl = ssl;
|
||||
m_bind_addr = bind_addr;
|
||||
error_code ec;
|
||||
m_sock.close(ec);
|
||||
if (m_sock.is_open()) m_sock.close(ec);
|
||||
|
||||
#if TORRENT_USE_I2P
|
||||
bool is_i2p = false;
|
||||
|
@ -340,30 +333,13 @@ void http_connection::start(std::string const& hostname, std::string const& port
|
|||
}
|
||||
}
|
||||
|
||||
#if defined TORRENT_USE_OPENSSL && BOOST_VERSION >= 104700
|
||||
// for SSL connections, make sure to authenticate the hostname
|
||||
// of the certificate
|
||||
#define CASE(t) case socket_type_int_impl<ssl_stream<t> >::value: \
|
||||
m_sock.get<ssl_stream<t> >()->set_verify_callback(asio::ssl::rfc2818_verification(hostname), ec); \
|
||||
break;
|
||||
|
||||
switch(m_sock.type())
|
||||
{
|
||||
CASE(stream_socket)
|
||||
CASE(socks5_stream)
|
||||
CASE(http_stream)
|
||||
CASE(utp_stream)
|
||||
}
|
||||
|
||||
setup_ssl_hostname(m_sock, hostname, ec);
|
||||
if (ec)
|
||||
{
|
||||
m_resolver.get_io_service().post(boost::bind(&http_connection::callback
|
||||
, me, ec, (char*)0, 0));
|
||||
return;
|
||||
}
|
||||
#undef CASE
|
||||
|
||||
#endif
|
||||
|
||||
#if TORRENT_USE_I2P
|
||||
if (is_i2p)
|
||||
|
@ -443,7 +419,7 @@ void http_connection::on_timeout(boost::weak_ptr<http_connection> p
|
|||
add_outstanding_async("http_connection::on_timeout");
|
||||
#endif
|
||||
error_code ec;
|
||||
c->m_sock.close(ec);
|
||||
async_shutdown(c->m_sock, c);
|
||||
c->m_timer.expires_at((std::min)(
|
||||
c->m_last_receive + c->m_read_timeout
|
||||
, c->m_start_time + c->m_completion_timeout), ec);
|
||||
|
@ -470,11 +446,15 @@ void http_connection::on_timeout(boost::weak_ptr<http_connection> p
|
|||
|
||||
void http_connection::close()
|
||||
{
|
||||
if (m_abort) return;
|
||||
|
||||
error_code ec;
|
||||
m_timer.cancel(ec);
|
||||
m_resolver.cancel();
|
||||
m_limiter_timer.cancel(ec);
|
||||
m_sock.close(ec);
|
||||
|
||||
async_shutdown(m_sock, shared_from_this());
|
||||
|
||||
m_hostname.clear();
|
||||
m_port.clear();
|
||||
m_handler.clear();
|
||||
|
@ -812,6 +792,10 @@ void http_connection::on_read(error_code const& e
|
|||
}
|
||||
|
||||
error_code ec;
|
||||
// it would be nice to gracefully shut down SSL here
|
||||
// but then we'd have to do all the reconnect logic
|
||||
// in its handler. For now, just kill the connection.
|
||||
// async_shutdown(m_sock, shared_from_this());
|
||||
m_sock.close(ec);
|
||||
using boost::tuples::ignore;
|
||||
boost::tie(ignore, ignore, ignore, ignore, ignore)
|
||||
|
|
|
@ -3489,15 +3489,6 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
|
||||
void on_close_socket(boost::shared_ptr<socket_type> const& s)
|
||||
{
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("on_close_socket");
|
||||
#endif
|
||||
error_code ec;
|
||||
s->close(ec);
|
||||
}
|
||||
|
||||
// the error argument defaults to 0, which means deliberate disconnect
|
||||
// 1 means unexpected disconnect/error
|
||||
// 2 protocol error (client sent something invalid)
|
||||
|
@ -3711,29 +3702,7 @@ namespace libtorrent
|
|||
m_disconnecting = true;
|
||||
error_code e;
|
||||
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
// for SSL connections, first do an async_shutdown, before closing the socket
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
#define MAYBE_ASIO_DEBUGGING add_outstanding_async("on_close_socket");
|
||||
#else
|
||||
#define MAYBE_ASIO_DEBUGGING
|
||||
#endif
|
||||
#define CASE(t) case socket_type_int_impl<ssl_stream<t> >::value: \
|
||||
MAYBE_ASIO_DEBUGGING \
|
||||
m_socket->get<ssl_stream<t> >()->async_shutdown(boost::bind(&on_close_socket, m_socket)); \
|
||||
break;
|
||||
switch(m_socket->type())
|
||||
{
|
||||
CASE(stream_socket)
|
||||
CASE(socks5_stream)
|
||||
CASE(http_stream)
|
||||
CASE(utp_stream)
|
||||
default: m_socket->close(e); break;
|
||||
}
|
||||
#undef CASE
|
||||
#else
|
||||
m_socket->close(e);
|
||||
#endif // TORRENT_USE_OPENSSL
|
||||
async_shutdown(*m_socket, m_socket);
|
||||
|
||||
m_ses.close_connection(this, ec);
|
||||
|
||||
|
|
|
@ -34,6 +34,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 104700
|
||||
#include <boost/asio/ssl/rfc2818_verification.hpp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace libtorrent
|
||||
|
@ -58,6 +63,76 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
|
||||
void setup_ssl_hostname(socket_type& s, std::string const& hostname, error_code& ec)
|
||||
{
|
||||
#if defined TORRENT_USE_OPENSSL && BOOST_VERSION >= 104700
|
||||
// for SSL connections, make sure to authenticate the hostname
|
||||
// of the certificate
|
||||
#define CASE(t) case socket_type_int_impl<ssl_stream<t> >::value: \
|
||||
s.get<ssl_stream<t> >()->set_verify_callback(asio::ssl::rfc2818_verification(hostname), ec); \
|
||||
ctx = SSL_get_SSL_CTX(s.get<ssl_stream<t> >()->native_handle()); \
|
||||
break;
|
||||
|
||||
SSL_CTX* ctx = 0;
|
||||
|
||||
switch(s.type())
|
||||
{
|
||||
CASE(stream_socket)
|
||||
CASE(socks5_stream)
|
||||
CASE(http_stream)
|
||||
CASE(utp_stream)
|
||||
}
|
||||
#undef CASE
|
||||
|
||||
if (ctx)
|
||||
{
|
||||
SSL_CTX_set_tlsext_servername_callback(ctx, 0);
|
||||
SSL_CTX_set_tlsext_servername_arg(ctx, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void on_close_socket(socket_type* s, boost::shared_ptr<void> holder)
|
||||
{
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("on_close_socket");
|
||||
#endif
|
||||
error_code ec;
|
||||
s->close(ec);
|
||||
}
|
||||
|
||||
// the second argument is a shared pointer to an object that
|
||||
// will keep the socket (s) alive for the duration of the async operation
|
||||
void async_shutdown(socket_type& s, boost::shared_ptr<void> holder)
|
||||
{
|
||||
error_code e;
|
||||
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
// for SSL connections, first do an async_shutdown, before closing the socket
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
#define MAYBE_ASIO_DEBUGGING add_outstanding_async("on_close_socket");
|
||||
#else
|
||||
#define MAYBE_ASIO_DEBUGGING
|
||||
#endif
|
||||
#define CASE(t) case socket_type_int_impl<ssl_stream<t> >::value: \
|
||||
MAYBE_ASIO_DEBUGGING \
|
||||
s.get<ssl_stream<t> >()->async_shutdown(boost::bind(&on_close_socket, &s, holder)); \
|
||||
break;
|
||||
|
||||
switch(s.type())
|
||||
{
|
||||
CASE(stream_socket)
|
||||
CASE(socks5_stream)
|
||||
CASE(http_stream)
|
||||
CASE(utp_stream)
|
||||
default: s.close(e); break;
|
||||
}
|
||||
#undef CASE
|
||||
#else
|
||||
s.close(e);
|
||||
#endif // TORRENT_USE_OPENSSL
|
||||
}
|
||||
|
||||
void socket_type::destruct()
|
||||
{
|
||||
switch (m_type)
|
||||
|
|
|
@ -86,7 +86,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/ssl_stream.hpp"
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#if BOOST_VERSION >= 104700
|
||||
#include <boost/asio/ssl/rfc2818_verification.hpp>
|
||||
#include <boost/asio/ssl/verify_context.hpp>
|
||||
#endif // BOOST_VERSION
|
||||
#endif // TORRENT_USE_OPENSSL
|
||||
|
@ -4655,28 +4654,13 @@ namespace libtorrent
|
|||
str->set_dst_name(hostname);
|
||||
}
|
||||
|
||||
#if defined TORRENT_USE_OPENSSL && BOOST_VERSION >= 104700
|
||||
// for SSL connections, make sure to authenticate the hostname
|
||||
// of the certificate
|
||||
#define CASE(t) case socket_type_int_impl<ssl_stream<t> >::value: \
|
||||
s->get<ssl_stream<t> >()->set_verify_callback(asio::ssl::rfc2818_verification(hostname), ec); \
|
||||
break;
|
||||
|
||||
switch(s->type())
|
||||
{
|
||||
CASE(stream_socket)
|
||||
CASE(socks5_stream)
|
||||
CASE(http_stream)
|
||||
CASE(utp_stream)
|
||||
}
|
||||
setup_ssl_hostname(*s, hostname, ec);
|
||||
if (ec)
|
||||
{
|
||||
if (m_ses.m_alerts.should_post<url_seed_alert>())
|
||||
m_ses.m_alerts.post_alert(url_seed_alert(get_handle(), web->url, ec));
|
||||
return;
|
||||
}
|
||||
#undef CASE
|
||||
#endif
|
||||
|
||||
boost::intrusive_ptr<peer_connection> c;
|
||||
if (web->type == web_seed_entry::url_seed)
|
||||
|
|
|
@ -600,7 +600,7 @@ int start_web_server(bool ssl, bool chunked_encoding)
|
|||
system("echo test city >> tmp");
|
||||
system("echo test company >> tmp");
|
||||
system("echo test department >> tmp");
|
||||
system("echo tester >> tmp");
|
||||
system("echo 127.0.0.1 >> tmp");
|
||||
system("echo test@test.com >> tmp");
|
||||
system("openssl req -new -x509 -keyout server.pem -out server.pem "
|
||||
"-days 365 -nodes <tmp");
|
||||
|
@ -876,7 +876,7 @@ void web_server_thread(int* port, bool ssl, bool chunked)
|
|||
s.async_read_some(boost::asio::buffer(&buf[len]
|
||||
, sizeof(buf) - len), boost::bind(&on_read, _1, _2, &received, &ec, &done));
|
||||
deadline_timer timer(ios);
|
||||
timer.expires_at(time_now_hires() + seconds(100));
|
||||
timer.expires_at(time_now_hires() + seconds(2));
|
||||
timer.async_wait(boost::bind(&on_read_timeout, _1, &timed_out));
|
||||
|
||||
while (!done && !timed_out)
|
||||
|
|
Loading…
Reference in New Issue