mirror of
https://github.com/transmission/transmission.git
synced 2025-12-24 12:28:52 +00:00
fix: limit pad search during encrypted handshake (#3471)
This commit is contained in:
@@ -146,7 +146,6 @@ struct tr_handshake
|
|||||||
uint16_t ia_len = {};
|
uint16_t ia_len = {};
|
||||||
uint32_t crypto_select = {};
|
uint32_t crypto_select = {};
|
||||||
uint32_t crypto_provide = {};
|
uint32_t crypto_provide = {};
|
||||||
tr_sha1_digest_t myReq1 = {};
|
|
||||||
struct event* timeout_timer = nullptr;
|
struct event* timeout_timer = nullptr;
|
||||||
|
|
||||||
std::optional<tr_peer_id_t> peer_id;
|
std::optional<tr_peer_id_t> peer_id;
|
||||||
@@ -481,34 +480,36 @@ static ReadState readYb(tr_handshake* handshake, struct evbuffer* inbuf)
|
|||||||
// A will be able to resynchronize on ENCRYPT(VC)"
|
// A will be able to resynchronize on ENCRYPT(VC)"
|
||||||
static ReadState readVC(tr_handshake* handshake, struct evbuffer* inbuf)
|
static ReadState readVC(tr_handshake* handshake, struct evbuffer* inbuf)
|
||||||
{
|
{
|
||||||
auto tmp = vc_t{};
|
// find the end of PadB by looking for `ENCRYPT(VC)`
|
||||||
|
auto needle = VC;
|
||||||
|
auto filter = tr_message_stream_encryption::Filter{};
|
||||||
|
filter.encryptInit(true, handshake->dh, *handshake->io->torrentHash());
|
||||||
|
filter.encrypt(std::size(needle), std::data(needle));
|
||||||
|
|
||||||
/* note: this works w/o having to `unwind' the buffer if
|
for (size_t i = 0; i < PadB_MAXLEN; ++i)
|
||||||
* we read too much, but it is pretty brute-force.
|
|
||||||
* it would be nice to make this cleaner. */
|
|
||||||
for (;;)
|
|
||||||
{
|
{
|
||||||
if (evbuffer_get_length(inbuf) < std::size(tmp))
|
if (evbuffer_get_length(inbuf) < std::size(needle))
|
||||||
{
|
{
|
||||||
tr_logAddTraceHand(handshake, "not enough bytes... returning read_more");
|
tr_logAddTraceHand(handshake, "not enough bytes... returning read_more");
|
||||||
return READ_LATER;
|
return READ_LATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::copy_n(reinterpret_cast<std::byte const*>(evbuffer_pullup(inbuf, std::size(tmp))), std::size(tmp), std::data(tmp));
|
auto const* peek = reinterpret_cast<std::byte const*>(evbuffer_pullup(inbuf, std::size(needle)));
|
||||||
handshake->io->decryptInit(handshake->io->isIncoming(), handshake->dh, *handshake->io->torrentHash());
|
if (std::equal(std::begin(needle), std::end(needle), peek))
|
||||||
handshake->io->decrypt(std::size(tmp), std::data(tmp));
|
|
||||||
if (tmp == VC)
|
|
||||||
{
|
{
|
||||||
break;
|
tr_logAddTraceHand(handshake, "got it!");
|
||||||
|
// We already know it's a match; now we just need to
|
||||||
|
// consume it from the read buffer.
|
||||||
|
tr_peerIoReadBytes(handshake->io, inbuf, std::data(needle), std::size(needle));
|
||||||
|
setState(handshake, AWAITING_CRYPTO_SELECT);
|
||||||
|
return READ_NOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
evbuffer_drain(inbuf, 1);
|
evbuffer_drain(inbuf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_logAddTraceHand(handshake, "got it!");
|
tr_logAddTraceHand(handshake, "couldn't find ENCRYPT(VC)");
|
||||||
evbuffer_drain(inbuf, std::size(VC));
|
return tr_handshakeDone(handshake, false);
|
||||||
setState(handshake, AWAITING_CRYPTO_SELECT);
|
|
||||||
return READ_NOW;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ReadState readCryptoSelect(tr_handshake* handshake, struct evbuffer* inbuf)
|
static ReadState readCryptoSelect(tr_handshake* handshake, struct evbuffer* inbuf)
|
||||||
@@ -719,16 +720,6 @@ static ReadState readYa(tr_handshake* handshake, struct evbuffer* inbuf)
|
|||||||
evbuffer_remove(inbuf, std::data(peer_public_key), std::size(peer_public_key));
|
evbuffer_remove(inbuf, std::data(peer_public_key), std::size(peer_public_key));
|
||||||
handshake->dh.setPeerPublicKey(peer_public_key);
|
handshake->dh.setPeerPublicKey(peer_public_key);
|
||||||
|
|
||||||
if (auto const req1 = tr_sha1("req1"sv, handshake->dh.secret()); req1)
|
|
||||||
{
|
|
||||||
handshake->myReq1 = *req1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tr_logAddTraceHand(handshake, "error while computing req1 hash after Ya");
|
|
||||||
return tr_handshakeDone(handshake, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// send our public key to the peer
|
// send our public key to the peer
|
||||||
tr_logAddTraceHand(handshake, "sending B->A: Diffie Hellman Yb, PadB");
|
tr_logAddTraceHand(handshake, "sending B->A: Diffie Hellman Yb, PadB");
|
||||||
sendPublicKeyAndPad<PadB_MAXLEN>(handshake);
|
sendPublicKeyAndPad<PadB_MAXLEN>(handshake);
|
||||||
@@ -739,27 +730,31 @@ static ReadState readYa(tr_handshake* handshake, struct evbuffer* inbuf)
|
|||||||
|
|
||||||
static ReadState readPadA(tr_handshake* handshake, struct evbuffer* inbuf)
|
static ReadState readPadA(tr_handshake* handshake, struct evbuffer* inbuf)
|
||||||
{
|
{
|
||||||
/* resynchronizing on HASH('req1', S) */
|
// find the end of PadA by looking for HASH('req1', S)
|
||||||
struct evbuffer_ptr ptr = evbuffer_search(
|
auto const needle = *tr_sha1("req1"sv, handshake->dh.secret());
|
||||||
inbuf,
|
|
||||||
reinterpret_cast<char const*>(std::data(handshake->myReq1)),
|
|
||||||
std::size(handshake->myReq1),
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
if (ptr.pos != -1) /* match */
|
for (size_t i = 0; i < PadA_MAXLEN; ++i)
|
||||||
{
|
{
|
||||||
evbuffer_drain(inbuf, ptr.pos);
|
if (evbuffer_get_length(inbuf) < std::size(needle))
|
||||||
tr_logAddTraceHand(handshake, "found it... looking setting to awaiting_crypto_provide");
|
{
|
||||||
setState(handshake, AWAITING_CRYPTO_PROVIDE);
|
tr_logAddTraceHand(handshake, "not enough bytes... returning read_more");
|
||||||
return READ_NOW;
|
return READ_LATER;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const* peek = reinterpret_cast<std::byte const*>(evbuffer_pullup(inbuf, std::size(needle)));
|
||||||
|
if (std::equal(std::begin(needle), std::end(needle), peek))
|
||||||
|
{
|
||||||
|
tr_logAddTraceHand(handshake, "found it... looking setting to awaiting_crypto_provide");
|
||||||
|
evbuffer_drain(inbuf, std::size(needle));
|
||||||
|
setState(handshake, AWAITING_CRYPTO_PROVIDE);
|
||||||
|
return READ_NOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
evbuffer_drain(inbuf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size_t const len = evbuffer_get_length(inbuf); len > SHA_DIGEST_LENGTH)
|
tr_logAddTraceHand(handshake, "couldn't find HASH('req', S)");
|
||||||
{
|
return tr_handshakeDone(handshake, false);
|
||||||
evbuffer_drain(inbuf, len - SHA_DIGEST_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
return READ_LATER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ReadState readCryptoProvide(tr_handshake* handshake, struct evbuffer* inbuf)
|
static ReadState readCryptoProvide(tr_handshake* handshake, struct evbuffer* inbuf)
|
||||||
@@ -768,8 +763,7 @@ static ReadState readCryptoProvide(tr_handshake* handshake, struct evbuffer* inb
|
|||||||
|
|
||||||
uint16_t padc_len = 0;
|
uint16_t padc_len = 0;
|
||||||
uint32_t crypto_provide = 0;
|
uint32_t crypto_provide = 0;
|
||||||
size_t const needlen = SHA_DIGEST_LENGTH + /* HASH('req1', s) */
|
size_t const needlen = SHA_DIGEST_LENGTH + /* HASH('req2', SKEY) xor HASH('req3', S) */
|
||||||
SHA_DIGEST_LENGTH + /* HASH('req2', SKEY) xor HASH('req3', S) */
|
|
||||||
std::size(VC) + sizeof(crypto_provide) + sizeof(padc_len);
|
std::size(VC) + sizeof(crypto_provide) + sizeof(padc_len);
|
||||||
|
|
||||||
if (evbuffer_get_length(inbuf) < needlen)
|
if (evbuffer_get_length(inbuf) < needlen)
|
||||||
@@ -777,9 +771,6 @@ static ReadState readCryptoProvide(tr_handshake* handshake, struct evbuffer* inb
|
|||||||
return READ_LATER;
|
return READ_LATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: confirm they sent HASH('req1',S) here? */
|
|
||||||
evbuffer_drain(inbuf, SHA_DIGEST_LENGTH);
|
|
||||||
|
|
||||||
/* This next piece is HASH('req2', SKEY) xor HASH('req3', S) ...
|
/* This next piece is HASH('req2', SKEY) xor HASH('req3', S) ...
|
||||||
* we can get the first half of that (the obfuscatedTorrentHash)
|
* we can get the first half of that (the obfuscatedTorrentHash)
|
||||||
* by building the latter and xor'ing it with what the peer sent us */
|
* by building the latter and xor'ing it with what the peer sent us */
|
||||||
|
|||||||
@@ -38,11 +38,13 @@ using HandshakeTest = SessionTest;
|
|||||||
class MediatorMock final : public tr_handshake_mediator
|
class MediatorMock final : public tr_handshake_mediator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MediatorMock(tr_session* session)
|
explicit MediatorMock(tr_session* session)
|
||||||
: session_{ session }
|
: session_{ session }
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual ~MediatorMock() = default;
|
||||||
|
|
||||||
[[nodiscard]] std::optional<torrent_info> torrentInfo(tr_sha1_digest_t const& info_hash) const override
|
[[nodiscard]] std::optional<torrent_info> torrentInfo(tr_sha1_digest_t const& info_hash) const override
|
||||||
{
|
{
|
||||||
if (auto const iter = torrents.find(info_hash); iter != std::end(torrents))
|
if (auto const iter = torrents.find(info_hash); iter != std::end(torrents))
|
||||||
@@ -137,17 +139,17 @@ void sendB64ToClient(evutil_socket_t sock, std::string_view b64)
|
|||||||
|
|
||||||
auto constexpr ReservedBytesNoExtensions = std::array<uint8_t, 8>{ 0, 0, 0, 0, 0, 0, 0, 0 };
|
auto constexpr ReservedBytesNoExtensions = std::array<uint8_t, 8>{ 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
auto constexpr PlaintextProtocolName = "\023BitTorrent protocol"sv;
|
auto constexpr PlaintextProtocolName = "\023BitTorrent protocol"sv;
|
||||||
auto const default_peer_addr = *tr_address::fromString("127.0.0.1"sv);
|
auto const DefaultPeerAddr = *tr_address::fromString("127.0.0.1"sv);
|
||||||
auto const default_peer_port = tr_port::fromHost(8080);
|
auto const DefaultPeerPort = tr_port::fromHost(8080);
|
||||||
auto const torrent_we_are_seeding = tr_handshake_mediator::torrent_info{ *tr_sha1("abcde"sv),
|
auto const TorrentWeAreSeeding = tr_handshake_mediator::torrent_info{ *tr_sha1("abcde"sv),
|
||||||
tr_peerIdInit(),
|
tr_peerIdInit(),
|
||||||
tr_torrent_id_t{ 100 },
|
tr_torrent_id_t{ 100 },
|
||||||
true /*is_done*/ };
|
true /*is_done*/ };
|
||||||
auto const ubuntu_torrent = tr_handshake_mediator::torrent_info{ *tr_sha1_from_string(
|
auto const UbuntuTorrent = tr_handshake_mediator::torrent_info{ *tr_sha1_from_string(
|
||||||
"2c6b6858d61da9543d4231a71db4b1c9264b0685"sv),
|
"2c6b6858d61da9543d4231a71db4b1c9264b0685"sv),
|
||||||
tr_peerIdInit(),
|
tr_peerIdInit(),
|
||||||
tr_torrent_id_t{ 101 },
|
tr_torrent_id_t{ 101 },
|
||||||
false /*is_done*/ };
|
false /*is_done*/ };
|
||||||
|
|
||||||
auto createIncomingIo(tr_session* session)
|
auto createIncomingIo(tr_session* session)
|
||||||
{
|
{
|
||||||
@@ -156,7 +158,7 @@ auto createIncomingIo(tr_session* session)
|
|||||||
auto const now = tr_time();
|
auto const now = tr_time();
|
||||||
auto const peer_socket = tr_peer_socket_tcp_create(sockpair[0]);
|
auto const peer_socket = tr_peer_socket_tcp_create(sockpair[0]);
|
||||||
auto* const
|
auto* const
|
||||||
io = tr_peerIoNewIncoming(session, &session->top_bandwidth_, &default_peer_addr, default_peer_port, now, peer_socket);
|
io = tr_peerIoNewIncoming(session, &session->top_bandwidth_, &DefaultPeerAddr, DefaultPeerPort, now, peer_socket);
|
||||||
return std::make_pair(io, sockpair[1]);
|
return std::make_pair(io, sockpair[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,8 +171,8 @@ auto createOutgoingIo(tr_session* session, tr_sha1_digest_t const& info_hash)
|
|||||||
auto* const io = tr_peerIoNew(
|
auto* const io = tr_peerIoNew(
|
||||||
session,
|
session,
|
||||||
&session->top_bandwidth_,
|
&session->top_bandwidth_,
|
||||||
&default_peer_addr,
|
&DefaultPeerAddr,
|
||||||
default_peer_port,
|
DefaultPeerPort,
|
||||||
now,
|
now,
|
||||||
&info_hash,
|
&info_hash,
|
||||||
false /*is_incoming*/,
|
false /*is_incoming*/,
|
||||||
@@ -205,13 +207,13 @@ auto runHandshake(
|
|||||||
{
|
{
|
||||||
auto result = std::optional<tr_handshake_result>{};
|
auto result = std::optional<tr_handshake_result>{};
|
||||||
|
|
||||||
static auto const done_callback = [](auto const& resin)
|
static auto const DoneCallback = [](auto const& resin)
|
||||||
{
|
{
|
||||||
*static_cast<std::optional<tr_handshake_result>*>(resin.userData) = resin;
|
*static_cast<std::optional<tr_handshake_result>*>(resin.userData) = resin;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
tr_handshakeNew(mediator, io, encryption_mode, done_callback, &result);
|
tr_handshakeNew(std::move(mediator), io, encryption_mode, DoneCallback, &result);
|
||||||
|
|
||||||
waitFor([&result]() { return result.has_value(); }, MaxWaitMsec);
|
waitFor([&result]() { return result.has_value(); }, MaxWaitMsec);
|
||||||
|
|
||||||
@@ -222,7 +224,7 @@ TEST_F(HandshakeTest, incomingPlaintext)
|
|||||||
{
|
{
|
||||||
auto const peer_id = makeRandomPeerId();
|
auto const peer_id = makeRandomPeerId();
|
||||||
auto mediator = std::make_shared<MediatorMock>(session_);
|
auto mediator = std::make_shared<MediatorMock>(session_);
|
||||||
mediator->torrents.emplace(torrent_we_are_seeding.info_hash, torrent_we_are_seeding);
|
mediator->torrents.emplace(TorrentWeAreSeeding.info_hash, TorrentWeAreSeeding);
|
||||||
|
|
||||||
// The simplest handshake there is. "The handshake starts with character
|
// The simplest handshake there is. "The handshake starts with character
|
||||||
// nineteen (decimal) followed by the string 'BitTorrent protocol'.
|
// nineteen (decimal) followed by the string 'BitTorrent protocol'.
|
||||||
@@ -235,7 +237,7 @@ TEST_F(HandshakeTest, incomingPlaintext)
|
|||||||
auto [io, sock] = createIncomingIo(session_);
|
auto [io, sock] = createIncomingIo(session_);
|
||||||
sendToClient(sock, PlaintextProtocolName);
|
sendToClient(sock, PlaintextProtocolName);
|
||||||
sendToClient(sock, ReservedBytesNoExtensions);
|
sendToClient(sock, ReservedBytesNoExtensions);
|
||||||
sendToClient(sock, torrent_we_are_seeding.info_hash);
|
sendToClient(sock, TorrentWeAreSeeding.info_hash);
|
||||||
sendToClient(sock, peer_id);
|
sendToClient(sock, peer_id);
|
||||||
|
|
||||||
auto const res = runHandshake(mediator, io);
|
auto const res = runHandshake(mediator, io);
|
||||||
@@ -248,7 +250,7 @@ TEST_F(HandshakeTest, incomingPlaintext)
|
|||||||
EXPECT_TRUE(res->peer_id);
|
EXPECT_TRUE(res->peer_id);
|
||||||
EXPECT_EQ(peer_id, res->peer_id);
|
EXPECT_EQ(peer_id, res->peer_id);
|
||||||
EXPECT_TRUE(io->torrentHash());
|
EXPECT_TRUE(io->torrentHash());
|
||||||
EXPECT_EQ(torrent_we_are_seeding.info_hash, *io->torrentHash());
|
EXPECT_EQ(TorrentWeAreSeeding.info_hash, *io->torrentHash());
|
||||||
|
|
||||||
tr_peerIoUnref(io);
|
tr_peerIoUnref(io);
|
||||||
evutil_closesocket(sock);
|
evutil_closesocket(sock);
|
||||||
@@ -259,7 +261,7 @@ TEST_F(HandshakeTest, incomingPlaintext)
|
|||||||
TEST_F(HandshakeTest, incomingPlaintextUnknownInfoHash)
|
TEST_F(HandshakeTest, incomingPlaintextUnknownInfoHash)
|
||||||
{
|
{
|
||||||
auto mediator = std::make_shared<MediatorMock>(session_);
|
auto mediator = std::make_shared<MediatorMock>(session_);
|
||||||
mediator->torrents.emplace(torrent_we_are_seeding.info_hash, torrent_we_are_seeding);
|
mediator->torrents.emplace(TorrentWeAreSeeding.info_hash, TorrentWeAreSeeding);
|
||||||
|
|
||||||
auto [io, sock] = createIncomingIo(session_);
|
auto [io, sock] = createIncomingIo(session_);
|
||||||
sendToClient(sock, PlaintextProtocolName);
|
sendToClient(sock, PlaintextProtocolName);
|
||||||
@@ -285,12 +287,12 @@ TEST_F(HandshakeTest, outgoingPlaintext)
|
|||||||
{
|
{
|
||||||
auto const peer_id = makeRandomPeerId();
|
auto const peer_id = makeRandomPeerId();
|
||||||
auto mediator = std::make_shared<MediatorMock>(session_);
|
auto mediator = std::make_shared<MediatorMock>(session_);
|
||||||
mediator->torrents.emplace(ubuntu_torrent.info_hash, torrent_we_are_seeding);
|
mediator->torrents.emplace(UbuntuTorrent.info_hash, TorrentWeAreSeeding);
|
||||||
|
|
||||||
auto [io, sock] = createOutgoingIo(session_, ubuntu_torrent.info_hash);
|
auto [io, sock] = createOutgoingIo(session_, UbuntuTorrent.info_hash);
|
||||||
sendToClient(sock, PlaintextProtocolName);
|
sendToClient(sock, PlaintextProtocolName);
|
||||||
sendToClient(sock, ReservedBytesNoExtensions);
|
sendToClient(sock, ReservedBytesNoExtensions);
|
||||||
sendToClient(sock, ubuntu_torrent.info_hash);
|
sendToClient(sock, UbuntuTorrent.info_hash);
|
||||||
sendToClient(sock, peer_id);
|
sendToClient(sock, peer_id);
|
||||||
|
|
||||||
auto const res = runHandshake(mediator, io);
|
auto const res = runHandshake(mediator, io);
|
||||||
@@ -303,8 +305,8 @@ TEST_F(HandshakeTest, outgoingPlaintext)
|
|||||||
EXPECT_TRUE(res->peer_id);
|
EXPECT_TRUE(res->peer_id);
|
||||||
EXPECT_EQ(peer_id, res->peer_id);
|
EXPECT_EQ(peer_id, res->peer_id);
|
||||||
EXPECT_TRUE(io->torrentHash());
|
EXPECT_TRUE(io->torrentHash());
|
||||||
EXPECT_EQ(ubuntu_torrent.info_hash, *io->torrentHash());
|
EXPECT_EQ(UbuntuTorrent.info_hash, *io->torrentHash());
|
||||||
EXPECT_EQ(tr_sha1_to_string(ubuntu_torrent.info_hash), tr_sha1_to_string(*io->torrentHash()));
|
EXPECT_EQ(tr_sha1_to_string(UbuntuTorrent.info_hash), tr_sha1_to_string(*io->torrentHash()));
|
||||||
|
|
||||||
tr_peerIoUnref(io);
|
tr_peerIoUnref(io);
|
||||||
evutil_closesocket(sock);
|
evutil_closesocket(sock);
|
||||||
@@ -315,7 +317,7 @@ TEST_F(HandshakeTest, incomingEncrypted)
|
|||||||
static auto constexpr ExpectedPeerId = makePeerId("-TR300Z-w4bd4mkebkbi"sv);
|
static auto constexpr ExpectedPeerId = makePeerId("-TR300Z-w4bd4mkebkbi"sv);
|
||||||
|
|
||||||
auto mediator = std::make_shared<MediatorMock>(session_);
|
auto mediator = std::make_shared<MediatorMock>(session_);
|
||||||
mediator->torrents.emplace(ubuntu_torrent.info_hash, ubuntu_torrent);
|
mediator->torrents.emplace(UbuntuTorrent.info_hash, UbuntuTorrent);
|
||||||
mediator->setPrivateKeyFromBase64("0EYKCwBWQ4Dg9kX3c5xxjVtBDKw="sv);
|
mediator->setPrivateKeyFromBase64("0EYKCwBWQ4Dg9kX3c5xxjVtBDKw="sv);
|
||||||
|
|
||||||
auto [io, sock] = createIncomingIo(session_);
|
auto [io, sock] = createIncomingIo(session_);
|
||||||
@@ -343,8 +345,8 @@ TEST_F(HandshakeTest, incomingEncrypted)
|
|||||||
EXPECT_TRUE(res->peer_id);
|
EXPECT_TRUE(res->peer_id);
|
||||||
EXPECT_EQ(ExpectedPeerId, res->peer_id);
|
EXPECT_EQ(ExpectedPeerId, res->peer_id);
|
||||||
EXPECT_TRUE(io->torrentHash());
|
EXPECT_TRUE(io->torrentHash());
|
||||||
EXPECT_EQ(ubuntu_torrent.info_hash, *io->torrentHash());
|
EXPECT_EQ(UbuntuTorrent.info_hash, *io->torrentHash());
|
||||||
EXPECT_EQ(tr_sha1_to_string(ubuntu_torrent.info_hash), tr_sha1_to_string(*io->torrentHash()));
|
EXPECT_EQ(tr_sha1_to_string(UbuntuTorrent.info_hash), tr_sha1_to_string(*io->torrentHash()));
|
||||||
|
|
||||||
tr_peerIoUnref(io);
|
tr_peerIoUnref(io);
|
||||||
evutil_closesocket(sock);
|
evutil_closesocket(sock);
|
||||||
@@ -389,10 +391,10 @@ TEST_F(HandshakeTest, outgoingEncrypted)
|
|||||||
static auto constexpr ExpectedPeerId = makePeerId("-qB4250-scysDI_JuVN3"sv);
|
static auto constexpr ExpectedPeerId = makePeerId("-qB4250-scysDI_JuVN3"sv);
|
||||||
|
|
||||||
auto mediator = std::make_shared<MediatorMock>(session_);
|
auto mediator = std::make_shared<MediatorMock>(session_);
|
||||||
mediator->torrents.emplace(ubuntu_torrent.info_hash, ubuntu_torrent);
|
mediator->torrents.emplace(UbuntuTorrent.info_hash, UbuntuTorrent);
|
||||||
mediator->setPrivateKeyFromBase64("0EYKCwBWQ4Dg9kX3c5xxjVtBDKw="sv);
|
mediator->setPrivateKeyFromBase64("0EYKCwBWQ4Dg9kX3c5xxjVtBDKw="sv);
|
||||||
|
|
||||||
auto [io, sock] = createOutgoingIo(session_, ubuntu_torrent.info_hash);
|
auto [io, sock] = createOutgoingIo(session_, UbuntuTorrent.info_hash);
|
||||||
|
|
||||||
// Peer->Client data from a successful encrypted handshake recorded
|
// Peer->Client data from a successful encrypted handshake recorded
|
||||||
// in the wild for replay here
|
// in the wild for replay here
|
||||||
@@ -422,8 +424,8 @@ TEST_F(HandshakeTest, outgoingEncrypted)
|
|||||||
EXPECT_TRUE(res->peer_id);
|
EXPECT_TRUE(res->peer_id);
|
||||||
EXPECT_EQ(ExpectedPeerId, res->peer_id);
|
EXPECT_EQ(ExpectedPeerId, res->peer_id);
|
||||||
EXPECT_TRUE(io->torrentHash());
|
EXPECT_TRUE(io->torrentHash());
|
||||||
EXPECT_EQ(ubuntu_torrent.info_hash, *io->torrentHash());
|
EXPECT_EQ(UbuntuTorrent.info_hash, *io->torrentHash());
|
||||||
EXPECT_EQ(tr_sha1_to_string(ubuntu_torrent.info_hash), tr_sha1_to_string(*io->torrentHash()));
|
EXPECT_EQ(tr_sha1_to_string(UbuntuTorrent.info_hash), tr_sha1_to_string(*io->torrentHash()));
|
||||||
|
|
||||||
tr_peerIoUnref(io);
|
tr_peerIoUnref(io);
|
||||||
evutil_closesocket(sock);
|
evutil_closesocket(sock);
|
||||||
|
|||||||
Reference in New Issue
Block a user