SSL fixes (especially over uTP)

This commit is contained in:
Arvid Norberg 2015-01-04 01:04:56 +00:00
parent 80b5a61655
commit 1218e328cd
4 changed files with 43 additions and 18 deletions

View File

@ -404,7 +404,7 @@ feature.compose <dht>logging : <define>TORRENT_DHT_VERBOSE_LOGGING ;
feature encryption : on off : composite propagated link-incompatible ;
feature.compose <encryption>off : <define>TORRENT_DISABLE_ENCRYPTION ;
feature crypto : built-in openssl gcrypt : composite ;
feature crypto : built-in openssl gcrypt : composite propagated ;
feature.compose <crypto>openssl : <define>TORRENT_USE_OPENSSL ;
feature.compose <crypto>gcrypt : <define>TORRENT_USE_GCRYPT ;

View File

@ -847,6 +847,7 @@ namespace libtorrent
#ifdef TORRENT_USE_OPENSSL
boost::asio::ssl::context* ssl_ctx() { return &m_ssl_ctx; }
void on_incoming_utp_ssl(boost::shared_ptr<socket_type> const& s);
void ssl_handshake(error_code const& ec, boost::shared_ptr<socket_type> s);
#endif

View File

@ -396,7 +396,7 @@ namespace aux {
, m_ssl_udp_socket(m_io_service)
, m_ssl_utp_socket_manager(m_settings, m_ssl_udp_socket, m_stats_counters
, &m_ssl_ctx
, boost::bind(&session_impl::incoming_connection, this, _1))
, boost::bind(&session_impl::on_incoming_utp_ssl, this, _1))
#endif
, m_boost_connections(0)
, m_timer(m_io_service)
@ -1552,6 +1552,7 @@ namespace aux {
, bool ipv4, int port, int& retries, int flags, error_code& ec)
{
listen_socket_t ret;
ret.ssl = flags & open_ssl_socket;
int last_op = 0;
listen_failed_alert::socket_type_t sock_type = (flags & open_ssl_socket)
? listen_failed_alert::tcp_ssl : listen_failed_alert::tcp;
@ -2177,6 +2178,11 @@ retry:
#if defined TORRENT_ASIO_DEBUGGING
add_outstanding_async("session_impl::on_accept_connection");
#endif
#ifdef TORRENT_USE_OPENSSL
TORRENT_ASSERT(ssl == is_ssl(*c));
#endif
listener->async_accept(*str
, boost::bind(&session_impl::on_accept_connection, this, c
, boost::weak_ptr<socket_acceptor>(listener), _1, ssl));
@ -2263,6 +2269,8 @@ retry:
#ifdef TORRENT_USE_OPENSSL
if (ssl)
{
TORRENT_ASSERT(is_ssl(*s));
// for SSL connections, incoming_connection() is called
// after the handshake is done
#if defined TORRENT_ASIO_DEBUGGING
@ -2281,6 +2289,20 @@ retry:
#ifdef TORRENT_USE_OPENSSL
void session_impl::on_incoming_utp_ssl(boost::shared_ptr<socket_type> const& s)
{
TORRENT_ASSERT(is_ssl(*s));
// for SSL connections, incoming_connection() is called
// after the handshake is done
#if defined TORRENT_ASIO_DEBUGGING
add_outstanding_async("session_impl::ssl_handshake");
#endif
s->get<ssl_stream<utp_stream> >()->async_accept_handshake(
boost::bind(&session_impl::ssl_handshake, this, _1, s));
m_incoming_sockets.insert(s);
}
// to test SSL connections, one can use this openssl command template:
//
// openssl s_client -cert <client-cert>.pem -key <client-private-key>.pem
@ -2292,6 +2314,8 @@ retry:
#if defined TORRENT_ASIO_DEBUGGING
complete_async("session_impl::ssl_handshake");
#endif
TORRENT_ASSERT(is_ssl(*s));
m_incoming_sockets.erase(s);
error_code e;
@ -3518,7 +3542,7 @@ retry:
torrent* t = i->second.get();
TORRENT_ASSERT(t);
if (t->is_auto_managed() && !t->has_error())
if (!t->has_error())
{
if (t->state() == torrent_status::checking_files)
{

View File

@ -255,20 +255,12 @@ void test_ssl(int test_idx, bool use_utp)
test_sleep(100);
}
fprintf(stderr, "peer_errors: %d peer_disconnects: %d expected: %d\n"
, peer_errors, peer_disconnects, test.peer_errors);
if (test.peer_errors > 0) {
TEST_CHECK(peer_errors + peer_disconnects >= test.peer_errors);
} else {
TEST_EQUAL(peer_errors + peer_disconnects, test.peer_errors);
}
fprintf(stderr, "peer_errors: %d expected_errors: %d\n"
, peer_errors, test.peer_errors);
TEST_EQUAL(peer_errors, test.peer_errors);
fprintf(stderr, "ssl_disconnects: %d expected: %d\n", ssl_peer_disconnects, test.ssl_disconnects);
if (test.ssl_disconnects > 0) {
TEST_CHECK(ssl_peer_disconnects >= test.ssl_disconnects);
} else {
TEST_EQUAL(ssl_peer_disconnects, test.ssl_disconnects);
}
TEST_EQUAL(ssl_peer_disconnects, test.ssl_disconnects);
fprintf(stderr, "%s: EXPECT: %s\n", time_now_string(), test.expected_to_complete ? "SUCCEESS" : "FAILURE");
fprintf(stderr, "%s: RESULT: %s\n", time_now_string(), tor2.status().is_seeding ? "SUCCEESS" : "FAILURE");
@ -339,7 +331,7 @@ bool try_connect(libtorrent::session& ses1, int port
if (flags & valid_bittorrent_hash) fprintf(stderr, "valid-bittorrent-hash ");
else fprintf(stderr, "invalid-bittorrent-hash ");
fprintf(stderr, "\n");
fprintf(stderr, " port: %d\n", port);
error_code ec;
boost::asio::io_service ios;
@ -482,6 +474,7 @@ bool try_connect(libtorrent::session& ses1, int port
fprintf(stderr, "bittorrent handshake\n");
boost::asio::write(ssl_sock, libtorrent::asio::buffer(handshake, (sizeof(handshake) - 1)), ec);
print_alerts(ses1, "ses1", true, true, true, &on_alert);
if (ec)
{
fprintf(stderr, "failed to write bittorrent handshake: %s\n"
@ -492,6 +485,7 @@ bool try_connect(libtorrent::session& ses1, int port
char buf[68];
fprintf(stderr, "read bittorrent handshake\n");
boost::asio::read(ssl_sock, libtorrent::asio::buffer(buf, sizeof(buf)), ec);
print_alerts(ses1, "ses1", true, true, true, &on_alert);
if (ec)
{
fprintf(stderr, "failed to read bittorrent handshake: %s\n"
@ -559,12 +553,18 @@ void test_malicious_peer()
, combine_path("..", combine_path("ssl", "dhparams.pem"))
, "test");
wait_for_alert(ses1, torrent_finished_alert::alert_type);
std::auto_ptr<alert> a = wait_for_alert(ses1
, torrent_finished_alert::alert_type, "ses1");
TEST_CHECK(a.get());
if (a.get())
{
TEST_EQUAL(a->type(), torrent_finished_alert::alert_type);
}
for (int i = 0; i < num_attacks; ++i)
{
bool success = try_connect(ses1, ssl_port, t, attacks[i].flags);
TEST_EQUAL(attacks[i].expect, success);
TEST_EQUAL(success, attacks[i].expect);
}
}
#endif // TORRENT_USE_OPENSSL