From c1c7daea00058fc20b85fd1628bb35ddd7bcef23 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 21 May 2018 10:09:54 +0200 Subject: Prevent malicious peer from replaying user ping --- src/Channel.cpp | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) (limited to 'src/Channel.cpp') diff --git a/src/Channel.cpp b/src/Channel.cpp index 5043665..1ac34c0 100644 --- a/src/Channel.cpp +++ b/src/Channel.cpp @@ -48,14 +48,10 @@ namespace dchat string unsignedData = userPublicKey.unsign(odhtdb::DataView((void*)deserializer.getBuffer(), deserializer.getSize())); sibs::SafeDeserializer unsignedDeserializer((const u8*)unsignedData.data(), unsignedData.size()); - u32 pingCounter = unsignedDeserializer.extract(); - u64 pingTimestamp = unsignedDeserializer.extract(); - // TODO: A malicious peer can capture the packets and reply them after the user has reconnect and counter has reset, need to fix this somehow. - // One solution is for the user to store the counter locally in file and continue using it when reconnecting - if(pingTimestamp > user->pingTimestamp) + u32 pingTimestampSec = unsignedDeserializer.extract(); + if(pingTimestampSec > user->pingTimestampSec) { - user->pingCounter = pingCounter; - user->pingTimestamp = pingTimestamp; + user->pingTimestampSec = pingTimestampSec; } } catch(std::exception &e) @@ -65,11 +61,7 @@ namespace dchat return result; }); - if(localUser->type == User::Type::ONLINE_LOCAL_USER) - { - auto onlineLocalUser = static_cast(localUser); - sendPing(onlineLocalUser->pingCounter + 1, database->getSyncedTimestampUtc().getCombined()); - } + sendPing(database->getSyncedTimestampUtc().seconds); } } @@ -79,11 +71,7 @@ namespace dchat { database->cancelNodeListener(pingKey, pingListener); database->stopSeeding(*databaseNodeInfo.getRequestHash()); - if(database && localUser->type == User::Type::ONLINE_LOCAL_USER) - { - auto onlineLocalUser = static_cast(localUser); - sendPing(onlineLocalUser->pingCounter + 1, 0); - } + sendPing(0); } for(User *user : users) @@ -266,12 +254,11 @@ namespace dchat if(database && localUser->type == User::Type::ONLINE_LOCAL_USER && pingTimer.getElapsedTime().asMilliseconds() > 5000) { pingTimer.restart(); - auto onlineLocalUser = static_cast(localUser); - sendPing(onlineLocalUser->pingCounter + 1, database->getSyncedTimestampUtc().getCombined()); + sendPing(database->getSyncedTimestampUtc().seconds); } } - void Channel::sendPing(u32 pingCounter, u64 pingTimestamp) + void Channel::sendPing(u32 pingTimestampSec) { if(database && localUser->type == User::Type::ONLINE_LOCAL_USER) { @@ -281,19 +268,18 @@ namespace dchat serializer.add((const u8*)onlineLocalUser->getPublicKey().getData(), onlineLocalUser->getPublicKey().getSize()); sibs::SafeSerializer signedSerializer; - signedSerializer.add(pingCounter); - signedSerializer.add(pingTimestamp); + signedSerializer.add(pingTimestampSec); string signedData = onlineLocalUser->keyPair.getPrivateKey().sign(odhtdb::DataView(signedSerializer.getBuffer().data(), signedSerializer.getBuffer().size())); serializer.add((const u8*)signedData.data(), signedData.size()); database->sendCustomMessage(pingKey, move(serializer.getBuffer())); } } - u64 Channel::getSyncedTimestampUtcCombined() + u32 Channel::getSyncedTimestampUtcInSec() { if(!database) return 0; - return database->getSyncedTimestampUtc().getCombined(); + return database->getSyncedTimestampUtc().seconds; } void Channel::setCurrent(Channel *channel) -- cgit v1.2.3