Skip to content

Commit

Permalink
merged RC_1_2 into RC_2_0
Browse files Browse the repository at this point in the history
  • Loading branch information
arvidn committed Apr 11, 2022
2 parents 41e17c4 + 175c20a commit 93b7fcf
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 80 deletions.
3 changes: 1 addition & 2 deletions Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,7 @@ rule linking ( properties * )
result += <framework>CoreFoundation <framework>SystemConfiguration ;
}

if ( <toolset>gcc in $(properties)
|| <toolset>clang in $(properties) )
if <toolset>gcc in $(properties)
&& <target-os>linux in $(properties)
&& ( <asserts>on in $(properties)
|| <asserts>production in $(properties)
Expand Down
5 changes: 4 additions & 1 deletion include/libtorrent/bt_peer_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,10 @@ namespace libtorrent {

private:

#if !defined TORRENT_DISABLE_ENCRYPTION
void init_bt_handshake();
#endif

enum class state_t : std::uint8_t
{
#if !defined TORRENT_DISABLE_ENCRYPTION
Expand All @@ -374,7 +378,6 @@ namespace libtorrent {
read_pe_cryptofield,
read_pe_pad,
read_pe_ia,
init_bt_handshake,
#endif
read_protocol_identifier,
read_info_hash,
Expand Down
1 change: 0 additions & 1 deletion include/libtorrent/pe_crypto.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ namespace libtorrent {
{
public:
dh_key_exchange();
bool good() const { return true; }

// Get local public key
key_t const& get_local_key() const { return m_dh_local_key; }
Expand Down
155 changes: 79 additions & 76 deletions src/bt_peer_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ namespace {
#endif

m_dh_key_exchange.reset(new (std::nothrow) dh_key_exchange);
if (!m_dh_key_exchange || !m_dh_key_exchange->good())
if (!m_dh_key_exchange)
{
disconnect(errors::no_memory, operation_t::encryption);
return;
Expand Down Expand Up @@ -2729,6 +2729,44 @@ namespace {
on_receive_impl(bytes_transferred);
}

#if !defined TORRENT_DISABLE_ENCRYPTION
void bt_peer_connection::init_bt_handshake()
{
m_encrypted = true;
if (m_rc4_encrypted)
{
switch_send_crypto(m_rc4);
switch_recv_crypto(m_rc4);
}

// decrypt remaining received bytes
if (m_rc4_encrypted)
{
span<char> const remaining = m_recv_buffer.mutable_buffer()
.subspan(m_recv_buffer.packet_size());
rc4_decrypt(remaining);

#ifndef TORRENT_DISABLE_LOGGING
peer_log(peer_log_alert::info, "ENCRYPTION"
, "decrypted remaining %d bytes", int(remaining.size()));
#endif
}
m_rc4.reset();

// encrypted portion of handshake completed, toggle
// peer_info pe_support flag back to true
if (is_outgoing() &&
m_settings.get_int(settings_pack::out_enc_policy)
== settings_pack::pe_enabled)
{
torrent_peer* pi = peer_info_struct();
TORRENT_ASSERT(pi);

pi->pe_support = true;
}
}
#endif

void bt_peer_connection::on_receive_impl(std::size_t bytes_transferred)
{
std::shared_ptr<torrent> t = associated_torrent().lock();
Expand Down Expand Up @@ -3119,30 +3157,28 @@ namespace {
m_rc4_encrypted = true;
}

int const len_pad = aux::read_int16(recv_buffer);
int len_pad = aux::read_int16(recv_buffer);
if (len_pad < 0 || len_pad > 512)
{
disconnect(errors::invalid_pad_size, operation_t::encryption, peer_error);
return;
}

m_state = state_t::read_pe_pad;
// len(IA) at the end of pad
if (!is_outgoing())
m_recv_buffer.reset(len_pad + 2); // len(IA) at the end of pad
len_pad += 2;

if (len_pad > 0)
{
m_state = state_t::read_pe_pad;
m_recv_buffer.reset(len_pad);
}
else
{
if (len_pad == 0)
{
m_encrypted = true;
if (m_rc4_encrypted)
{
switch_send_crypto(m_rc4);
switch_recv_crypto(m_rc4);
}
m_state = state_t::init_bt_handshake;
}
else
m_recv_buffer.reset(len_pad);
TORRENT_ASSERT(len_pad == 0);
init_bt_handshake();
m_state = state_t::read_protocol_identifier;
m_recv_buffer.reset(20);
}
}

Expand All @@ -3164,55 +3200,51 @@ namespace {
recv_buffer = recv_buffer.subspan(pad_size);
int const len_ia = aux::read_int16(recv_buffer);

if (len_ia < 0)
#ifndef TORRENT_DISABLE_LOGGING
peer_log(peer_log_alert::info, "ENCRYPTION", "len(IA) : %d", len_ia);
#endif
if (len_ia < 0 || len_ia > 68)
{
disconnect(errors::invalid_encrypt_handshake, operation_t::encryption, peer_error);
return;
}

#ifndef TORRENT_DISABLE_LOGGING
peer_log(peer_log_alert::info, "ENCRYPTION", "len(IA) : %d", len_ia);
#endif
if (len_ia == 0)
{
// everything after this is Encrypt2
m_encrypted = true;
if (m_rc4_encrypted)
{
switch_send_crypto(m_rc4);
switch_recv_crypto(m_rc4);
}
m_state = state_t::init_bt_handshake;
// everything after this is encrypted
init_bt_handshake();
m_state = state_t::read_protocol_identifier;
m_recv_buffer.reset(20);
}
else
{
// The other peer indicated that a non-zero bytes will be
// encrypted at the start of the underlying bittorrent
// protocol. This number of bytes, len_ia, is not
// necessarily aligned to message boundaries. We first read
// that many bytes, decrypt it, and then pass it back into
// the regular protocol parser
m_state = state_t::read_pe_ia;
m_recv_buffer.reset(len_ia);
}
}
else // is_outgoing()
{
// everything that arrives after this is Encrypt2
m_encrypted = true;
if (m_rc4_encrypted)
{
switch_send_crypto(m_rc4);
switch_recv_crypto(m_rc4);
}
m_state = state_t::init_bt_handshake;
// everything that arrives after this is encrypted
init_bt_handshake();
m_state = state_t::read_protocol_identifier;
m_recv_buffer.reset(20);
}
}

if (m_state == state_t::read_pe_ia)
{
received_bytes(0, int(bytes_transferred));
bytes_transferred = 0;
TORRENT_ASSERT(!is_outgoing());
TORRENT_ASSERT(!m_encrypted);

if (!m_recv_buffer.packet_finished()) return;

// ia is always rc4, so decrypt it
// the IA bytes are always rc4, so decrypt it
rc4_decrypt(m_recv_buffer.mutable_buffer().first(m_recv_buffer.packet_size()));

#ifndef TORRENT_DISABLE_LOGGING
Expand All @@ -3229,47 +3261,14 @@ namespace {
}
m_rc4.reset();

// now that we have decrypted IA length of bytes, we
// reinterpret the receive buffer as the very start of a normal
// connection. First we expect to find the protocol identifier
// (i.e. "BitTorrent Protocol")
m_state = state_t::read_protocol_identifier;
m_recv_buffer.cut(0, 20);
}

if (m_state == state_t::init_bt_handshake)
{
received_bytes(0, int(bytes_transferred));
bytes_transferred = 0;
TORRENT_ASSERT(m_encrypted);

// decrypt remaining received bytes
if (m_rc4_encrypted)
{
span<char> const remaining = m_recv_buffer.mutable_buffer()
.subspan(m_recv_buffer.packet_size());
rc4_decrypt(remaining);

#ifndef TORRENT_DISABLE_LOGGING
peer_log(peer_log_alert::info, "ENCRYPTION"
, "decrypted remaining %d bytes", int(remaining.size()));
#endif
}
m_rc4.reset();

// payload stream, start with 20 handshake bytes
m_state = state_t::read_protocol_identifier;
m_recv_buffer.reset(20);

// encrypted portion of handshake completed, toggle
// peer_info pe_support flag back to true
if (is_outgoing() &&
m_settings.get_int(settings_pack::out_enc_policy)
== settings_pack::pe_enabled)
{
torrent_peer* pi = peer_info_struct();
TORRENT_ASSERT(pi);

pi->pe_support = true;
}
}

#endif // #if !defined TORRENT_DISABLE_ENCRYPTION

if (m_state == state_t::read_protocol_identifier)
Expand Down Expand Up @@ -3327,6 +3326,10 @@ namespace {
peer_log(peer_log_alert::info, "ENCRYPTION", "attempting encrypted connection");
#endif
m_state = state_t::read_pe_dhkey;
// we're "cutting" off 0 bytes from the receive buffer here
// because we want to interpret it as something else. It didn't
// contain the expected bittorrent handshake string, so let's
// try again to interpret it as an encrypted handshake
m_recv_buffer.cut(0, dh_key_len);
TORRENT_ASSERT(!m_recv_buffer.packet_finished());
return;
Expand Down

0 comments on commit 93b7fcf

Please sign in to comment.