diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 2e9a02ca..2e469f98 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -180,6 +180,7 @@ namespace http { case eRouterStatusOK: s << "OK"; break; case eRouterStatusTesting: s << "Testing"; break; case eRouterStatusFirewalled: s << "Firewalled"; break; + case eRouterStatusError: s << "Error"; break; default: s << "Unknown"; } s << "
\r\n"; diff --git a/RouterContext.h b/RouterContext.h index 27e0947d..23c03593 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -20,7 +20,8 @@ namespace i2p { eRouterStatusOK = 0, eRouterStatusTesting = 1, - eRouterStatusFirewalled = 2 + eRouterStatusFirewalled = 2, + eRouterStatusError = 3 }; class RouterContext: public i2p::garlic::GarlicDestination diff --git a/SSUSession.cpp b/SSUSession.cpp index 26c14570..ca714aed 100644 --- a/SSUSession.cpp +++ b/SSUSession.cpp @@ -272,6 +272,16 @@ namespace transport s.Insert (payload, 8); // relayTag and signed on time m_RelayTag = bufbe32toh (payload); payload += 4; // relayTag + if (i2p::context.GetStatus () == eRouterStatusTesting) + { + auto ts = i2p::util::GetSecondsSinceEpoch (); + uint32_t signedOnTime = bufbe32toh(payload); + if (signedOnTime < ts - SSU_CLOCK_SKEW || signedOnTime > ts + SSU_CLOCK_SKEW) + { + LogPrint (eLogError, "SSU: clock skew detected ", (int)ts - signedOnTime, ". Check your clock"); + i2p::context.SetStatus (eRouterStatusError); + } + } payload += 4; // signed on time // decrypt signature size_t signatureLen = m_RemoteIdentity->GetSignatureLen (); @@ -310,6 +320,14 @@ namespace transport SetRemoteIdentity (std::make_shared (payload, identitySize)); m_Data.UpdatePacketSize (m_RemoteIdentity->GetIdentHash ()); payload += identitySize; // identity + auto ts = i2p::util::GetSecondsSinceEpoch (); + uint32_t signedOnTime = bufbe32toh(payload); + if (signedOnTime < ts - SSU_CLOCK_SKEW || signedOnTime > ts + SSU_CLOCK_SKEW) + { + LogPrint (eLogError, "SSU message 'confirmed' time difference ", (int)ts - signedOnTime, " exceeds clock skew"); + Failed (); + return; + } if (m_SignedData) m_SignedData->Insert (payload, 4); // insert Alice's signed on time payload += 4; // signed-on time diff --git a/SSUSession.h b/SSUSession.h index 69669187..4838be2a 100644 --- a/SSUSession.h +++ b/SSUSession.h @@ -27,6 +27,7 @@ namespace transport const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes + const int SSU_CLOCK_SKEW = 60; // in seconds // payload types (4 bits) const uint8_t PAYLOAD_TYPE_SESSION_REQUEST = 0;