From 512e20fa063e4a4525e47e048f26cc68668e7fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Sat, 16 Sep 2023 11:33:40 +0200 Subject: Protocol: use cookies during whole plaintext phase --- src/network.cpp | 3 +-- src/network/protocol.cpp | 58 +++++++++++++++++++++++++++++++++++------------- src/network/protocol.h | 7 +++--- 3 files changed, 46 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/network.cpp b/src/network.cpp index da480c3..6840f43 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -698,8 +698,7 @@ void Server::Peer::updateChannel(ReplyBuilder & reply) if (!holds_alternative(identity)) return; - if (holds_alternative(connection.channel()) || - holds_alternative(connection.channel())) { + if (holds_alternative(connection.channel())) { auto req = Channel::generateRequest(tempStorage, server.self, std::get(identity)); connection.channel().emplace>(req); diff --git a/src/network/protocol.cpp b/src/network/protocol.cpp index 79c023d..93d171a 100644 --- a/src/network/protocol.cpp +++ b/src/network/protocol.cpp @@ -32,6 +32,8 @@ struct NetworkProtocol::ConnectionPriv mutex cmutex {}; vector buffer {}; + optional receivedCookie = nullopt; + bool confirmedCookie = false; ChannelState channel = monostate(); vector> secureOutQueue {}; }; @@ -88,7 +90,8 @@ NetworkProtocol::PollResult NetworkProtocol::poll() } auto pst = self->ref()->storage().deriveEphemeralStorage(); - if (auto header = Connection::receive(buffer, nullptr, pst)) { + bool secure = false; + if (auto header = Connection::parsePacket(buffer, nullptr, pst, secure)) { if (auto conn = verifyNewConnection(*header, addr)) return NewConnection { move(*conn) }; @@ -113,6 +116,7 @@ NetworkProtocol::Connection NetworkProtocol::connect(sockaddr_in6 addr) vector header { Header::Initiation { Digest(array {}) }, + Header::AnnounceSelf { self->ref()->digest() }, Header::Version { defaultVersion }, }; conn->send(self->ref()->storage(), move(header), {}, false); @@ -311,32 +315,50 @@ optional NetworkProtocol::Connection::receive(const Par } } - if (auto header = receive(buf, channel, partStorage)) { + bool secure = false; + if (auto header = parsePacket(buf, channel, partStorage, secure)) { scoped_lock lock(p->cmutex); + if (secure) + return header; + + if (const auto * cookieEcho = header->lookupFirst()) { + if (!p->protocol->verifyCookie(p->peerAddress, cookieEcho->value)) + return nullopt; + + p->confirmedCookie = true; + + if (const auto * cookieSet = header->lookupFirst()) + p->receivedCookie = cookieSet->value; + + return header; + } + + if (holds_alternative(p->channel)) { + if (const auto * cookieSet = header->lookupFirst()) { + p->receivedCookie = cookieSet->value; + return header; + } + } + if (header->lookupFirst()) { p->protocol->sendCookie(p->peerAddress); return nullopt; } - - if (holds_alternative(p->channel) || - holds_alternative(p->channel)) - if (const auto * cookie = header->lookupFirst()) - p->channel = cookie->value; - - return header; } return nullopt; } -optional NetworkProtocol::Connection::receive(vector & buf, - Channel * channel, - const PartialStorage & partStorage) +optional NetworkProtocol::Connection::parsePacket(vector & buf, + Channel * channel, const PartialStorage & partStorage, + bool & secure) { vector decrypted; auto plainBegin = buf.cbegin(); auto plainEnd = buf.cbegin(); + secure = false; + if ((buf[0] & 0xE0) == 0x80) { if (not channel) { std::cerr << "unexpected encrypted packet\n"; @@ -356,6 +378,8 @@ optional NetworkProtocol::Connection::receive(vector>(&this->channel)) channel = uptr->get(); - if (channel || secure) + if (channel || secure) { data.push_back(0x00); - else if (const auto * ptr = get_if(&this->channel)) { - header.items.push_back(Header::CookieEcho { ptr->value }); - header.items.push_back(Header::Version { defaultVersion }); + } else { + if (receivedCookie) + header.items.push_back(Header::CookieEcho { receivedCookie->value }); + if (!confirmedCookie) + header.items.push_back(Header::CookieSet { protocol->generateCookie(peerAddress) }); } part = header.toObject(partStorage).encode(); diff --git a/src/network/protocol.h b/src/network/protocol.h index dda2ffb..3d7c073 100644 --- a/src/network/protocol.h +++ b/src/network/protocol.h @@ -54,7 +54,6 @@ public: struct Cookie { vector value; }; using ChannelState = variant, shared_ptr, Stored, @@ -115,9 +114,9 @@ public: void trySendOutQueue(); private: - static optional
receive(vector & buf, - Channel * channel, - const PartialStorage & st); + static optional
parsePacket(vector & buf, + Channel * channel, const PartialStorage & st, + bool & secure); unique_ptr p; }; -- cgit v1.2.3