Browse Source

ignore extended options for SessionCreated and SessionConfirmed

pull/308/head
orignal 9 years ago
parent
commit
c36a810bcb
  1. 84
      SSUSession.cpp
  2. 12
      SSUSession.h

84
SSUSession.cpp

@ -131,10 +131,10 @@ namespace transport
} }
} }
size_t SSUSession::GetSSUHeaderSize (uint8_t * buf) const size_t SSUSession::GetSSUHeaderSize (const uint8_t * buf) const
{ {
size_t s = sizeof (SSUHeader); size_t s = sizeof (SSUHeader);
if (((SSUHeader *)buf)->IsExtendedOptions ()) if (((const SSUHeader *)buf)->IsExtendedOptions ())
s += buf[s] + 1; // byte right after header is extended options length s += buf[s] + 1; // byte right after header is extended options length
return s; return s;
} }
@ -145,6 +145,11 @@ namespace transport
if (len <= sizeof (SSUHeader)) return; // drop empty message if (len <= sizeof (SSUHeader)) return; // drop empty message
//TODO: since we are accessing a uint8_t this is unlikely to crash due to alignment but should be improved //TODO: since we are accessing a uint8_t this is unlikely to crash due to alignment but should be improved
auto headerSize = GetSSUHeaderSize (buf); auto headerSize = GetSSUHeaderSize (buf);
if (headerSize >= len)
{
LogPrint (eLogError, "SSU header size ", headerSize, " exceeds packet length ", len);
return;
}
SSUHeader * header = (SSUHeader *)buf; SSUHeader * header = (SSUHeader *)buf;
switch (header->GetPayloadType ()) switch (header->GetPayloadType ())
{ {
@ -152,13 +157,13 @@ namespace transport
ProcessData (buf + headerSize, len - headerSize); ProcessData (buf + headerSize, len - headerSize);
break; break;
case PAYLOAD_TYPE_SESSION_REQUEST: case PAYLOAD_TYPE_SESSION_REQUEST:
ProcessSessionRequest (buf, len, senderEndpoint); ProcessSessionRequest (buf + headerSize, len - headerSize, senderEndpoint);
break; break;
case PAYLOAD_TYPE_SESSION_CREATED: case PAYLOAD_TYPE_SESSION_CREATED:
ProcessSessionCreated (buf, len); ProcessSessionCreated (buf, len); // buf with header
break; break;
case PAYLOAD_TYPE_SESSION_CONFIRMED: case PAYLOAD_TYPE_SESSION_CONFIRMED:
ProcessSessionConfirmed (buf, len); ProcessSessionConfirmed (buf, len); // buf with header
break; break;
case PAYLOAD_TYPE_PEER_TEST: case PAYLOAD_TYPE_PEER_TEST:
LogPrint (eLogDebug, "SSU peer test received"); LogPrint (eLogDebug, "SSU peer test received");
@ -171,7 +176,7 @@ namespace transport
break; break;
} }
case PAYLOAD_TYPE_RELAY_RESPONSE: case PAYLOAD_TYPE_RELAY_RESPONSE:
ProcessRelayResponse (buf, len); ProcessRelayResponse (buf + headerSize, len - headerSize);
if (m_State != eSessionStateEstablished) if (m_State != eSessionStateEstablished)
m_Server.DeleteSession (shared_from_this ()); m_Server.DeleteSession (shared_from_this ());
break; break;
@ -188,14 +193,14 @@ namespace transport
} }
} }
void SSUSession::ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint) void SSUSession::ProcessSessionRequest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint)
{ {
LogPrint (eLogDebug, "Session request received"); LogPrint (eLogDebug, "Session request received");
m_RemoteEndpoint = senderEndpoint; m_RemoteEndpoint = senderEndpoint;
if (!m_DHKeysPair) if (!m_DHKeysPair)
m_DHKeysPair = transports.GetNextDHKeysPair (); m_DHKeysPair = transports.GetNextDHKeysPair ();
CreateAESandMacKey (buf + sizeof (SSUHeader)); CreateAESandMacKey (buf);
SendSessionCreated (buf + sizeof (SSUHeader)); SendSessionCreated (buf);
} }
void SSUSession::ProcessSessionCreated (uint8_t * buf, size_t len) void SSUSession::ProcessSessionCreated (uint8_t * buf, size_t len)
@ -209,7 +214,13 @@ namespace transport
LogPrint (eLogDebug, "Session created received"); LogPrint (eLogDebug, "Session created received");
m_Timer.cancel (); // connect timer m_Timer.cancel (); // connect timer
SignedData s; // x,y, our IP, our port, remote IP, remote port, relayTag, signed on time SignedData s; // x,y, our IP, our port, remote IP, remote port, relayTag, signed on time
uint8_t * payload = buf + sizeof (SSUHeader); auto headerSize = GetSSUHeaderSize (buf);
if (headerSize >= len)
{
LogPrint (eLogError, "Session created header size ", headerSize, " exceeds packet length ", len);
return;
}
uint8_t * payload = buf + headerSize;
uint8_t * y = payload; uint8_t * y = payload;
CreateAESandMacKey (y); CreateAESandMacKey (y);
s.Insert (m_DHKeysPair->GetPublicKey (), 256); // x s.Insert (m_DHKeysPair->GetPublicKey (), 256); // x
@ -253,7 +264,7 @@ namespace transport
if (paddingSize > 0) signatureLen += (16 - paddingSize); if (paddingSize > 0) signatureLen += (16 - paddingSize);
//TODO: since we are accessing a uint8_t this is unlikely to crash due to alignment but should be improved //TODO: since we are accessing a uint8_t this is unlikely to crash due to alignment but should be improved
m_SessionKeyDecryption.SetIV (((SSUHeader *)buf)->iv); m_SessionKeyDecryption.SetIV (((SSUHeader *)buf)->iv);
m_SessionKeyDecryption.Decrypt (payload, signatureLen, payload); m_SessionKeyDecryption.Decrypt (payload, signatureLen, payload); // TODO: non-const payload
// verify // verify
if (!s.Verify (m_RemoteIdentity, payload)) if (!s.Verify (m_RemoteIdentity, payload))
LogPrint (eLogError, "Session created SSU signature verification failed"); LogPrint (eLogError, "Session created SSU signature verification failed");
@ -261,10 +272,16 @@ namespace transport
SendSessionConfirmed (y, ourAddress, addressSize + 2); SendSessionConfirmed (y, ourAddress, addressSize + 2);
} }
void SSUSession::ProcessSessionConfirmed (uint8_t * buf, size_t len) void SSUSession::ProcessSessionConfirmed (const uint8_t * buf, size_t len)
{ {
LogPrint (eLogDebug, "Session confirmed received"); LogPrint (eLogDebug, "Session confirmed received");
uint8_t * payload = buf + sizeof (SSUHeader); auto headerSize = GetSSUHeaderSize (buf);
if (headerSize >= len)
{
LogPrint (eLogError, "Session confirmed header size ", len, " exceeds packet length ", len);
return;
}
const uint8_t * payload = buf + headerSize;
payload++; // identity fragment info payload++; // identity fragment info
uint16_t identitySize = bufbe16toh (payload); uint16_t identitySize = bufbe16toh (payload);
payload += 2; // size of identity fragment payload += 2; // size of identity fragment
@ -461,7 +478,7 @@ namespace transport
Send (buf, msgLen); Send (buf, msgLen);
} }
void SSUSession::ProcessRelayRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& from) void SSUSession::ProcessRelayRequest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& from)
{ {
uint32_t relayTag = bufbe32toh (buf); uint32_t relayTag = bufbe32toh (buf);
auto session = m_Server.FindRelaySession (relayTag); auto session = m_Server.FindRelaySession (relayTag);
@ -475,7 +492,7 @@ namespace transport
uint8_t challengeSize = *buf; uint8_t challengeSize = *buf;
buf++; // challenge size buf++; // challenge size
buf += challengeSize; buf += challengeSize;
uint8_t * introKey = buf; const uint8_t * introKey = buf;
buf += 32; // introkey buf += 32; // introkey
uint32_t nonce = bufbe32toh (buf); uint32_t nonce = bufbe32toh (buf);
SendRelayResponse (nonce, from, introKey, session->m_RemoteEndpoint); SendRelayResponse (nonce, from, introKey, session->m_RemoteEndpoint);
@ -562,38 +579,37 @@ namespace transport
LogPrint (eLogDebug, "SSU relay intro sent"); LogPrint (eLogDebug, "SSU relay intro sent");
} }
void SSUSession::ProcessRelayResponse (uint8_t * buf, size_t len) void SSUSession::ProcessRelayResponse (const uint8_t * buf, size_t len)
{ {
LogPrint (eLogDebug, "Relay response received"); LogPrint (eLogDebug, "Relay response received");
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t remoteSize = *buf;
uint8_t remoteSize = *payload; buf++; // remote size
payload++; // remote size boost::asio::ip::address_v4 remoteIP (bufbe32toh (buf));
boost::asio::ip::address_v4 remoteIP (bufbe32toh (payload)); buf += remoteSize; // remote address
payload += remoteSize; // remote address uint16_t remotePort = bufbe16toh (buf);
uint16_t remotePort = bufbe16toh (payload); buf += 2; // remote port
payload += 2; // remote port uint8_t ourSize = *buf;
uint8_t ourSize = *payload; buf++; // our size
payload++; // our size
boost::asio::ip::address ourIP; boost::asio::ip::address ourIP;
if (ourSize == 4) if (ourSize == 4)
{ {
boost::asio::ip::address_v4::bytes_type bytes; boost::asio::ip::address_v4::bytes_type bytes;
memcpy (bytes.data (), payload, 4); memcpy (bytes.data (), buf, 4);
ourIP = boost::asio::ip::address_v4 (bytes); ourIP = boost::asio::ip::address_v4 (bytes);
} }
else else
{ {
boost::asio::ip::address_v6::bytes_type bytes; boost::asio::ip::address_v6::bytes_type bytes;
memcpy (bytes.data (), payload, 16); memcpy (bytes.data (), buf, 16);
ourIP = boost::asio::ip::address_v6 (bytes); ourIP = boost::asio::ip::address_v6 (bytes);
} }
payload += ourSize; // our address buf += ourSize; // our address
uint16_t ourPort = bufbe16toh (payload); uint16_t ourPort = bufbe16toh (buf);
payload += 2; // our port buf += 2; // our port
LogPrint ("Our external address is ", ourIP.to_string (), ":", ourPort); LogPrint ("Our external address is ", ourIP.to_string (), ":", ourPort);
i2p::context.UpdateAddress (ourIP); i2p::context.UpdateAddress (ourIP);
uint32_t nonce = bufbe32toh (payload); uint32_t nonce = bufbe32toh (buf);
payload += 4; // nonce buf += 4; // nonce
auto it = m_RelayRequests.find (nonce); auto it = m_RelayRequests.find (nonce);
if (it != m_RelayRequests.end ()) if (it != m_RelayRequests.end ())
{ {
@ -615,7 +631,7 @@ namespace transport
LogPrint (eLogError, "Unsolicited RelayResponse, nonce=", nonce); LogPrint (eLogError, "Unsolicited RelayResponse, nonce=", nonce);
} }
void SSUSession::ProcessRelayIntro (uint8_t * buf, size_t len) void SSUSession::ProcessRelayIntro (const uint8_t * buf, size_t len)
{ {
uint8_t size = *buf; uint8_t size = *buf;
if (size == 4) if (size == 4)
@ -624,7 +640,7 @@ namespace transport
boost::asio::ip::address_v4 address (bufbe32toh (buf)); boost::asio::ip::address_v4 address (bufbe32toh (buf));
buf += 4; // address buf += 4; // address
uint16_t port = bufbe16toh (buf); uint16_t port = bufbe16toh (buf);
// send hole punch of 1 byte // send hole punch of 0 bytes
m_Server.Send (buf, 0, boost::asio::ip::udp::endpoint (address, port)); m_Server.Send (buf, 0, boost::asio::ip::udp::endpoint (address, port));
} }
else else

12
SSUSession.h

@ -96,22 +96,22 @@ namespace transport
boost::asio::io_service& GetService (); boost::asio::io_service& GetService ();
void CreateAESandMacKey (const uint8_t * pubKey); void CreateAESandMacKey (const uint8_t * pubKey);
size_t GetSSUHeaderSize (uint8_t * buf) const; size_t GetSSUHeaderSize (const uint8_t * buf) const;
void PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs); void PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs);
void ProcessMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); // call for established session void ProcessMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); // call for established session
void ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); void ProcessSessionRequest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
void SendSessionRequest (); void SendSessionRequest ();
void SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer, uint32_t nonce); void SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer, uint32_t nonce);
void ProcessSessionCreated (uint8_t * buf, size_t len); void ProcessSessionCreated (uint8_t * buf, size_t len);
void SendSessionCreated (const uint8_t * x); void SendSessionCreated (const uint8_t * x);
void ProcessSessionConfirmed (uint8_t * buf, size_t len); void ProcessSessionConfirmed (const uint8_t * buf, size_t len);
void SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, size_t ourAddressLen); void SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, size_t ourAddressLen);
void ProcessRelayRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& from); void ProcessRelayRequest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& from);
void SendRelayResponse (uint32_t nonce, const boost::asio::ip::udp::endpoint& from, void SendRelayResponse (uint32_t nonce, const boost::asio::ip::udp::endpoint& from,
const uint8_t * introKey, const boost::asio::ip::udp::endpoint& to); const uint8_t * introKey, const boost::asio::ip::udp::endpoint& to);
void SendRelayIntro (std::shared_ptr<SSUSession> session, const boost::asio::ip::udp::endpoint& from); void SendRelayIntro (std::shared_ptr<SSUSession> session, const boost::asio::ip::udp::endpoint& from);
void ProcessRelayResponse (uint8_t * buf, size_t len); void ProcessRelayResponse (const uint8_t * buf, size_t len);
void ProcessRelayIntro (uint8_t * buf, size_t len); void ProcessRelayIntro (const uint8_t * buf, size_t len);
void Established (); void Established ();
void Failed (); void Failed ();
void ScheduleConnectTimer (); void ScheduleConnectTimer ();

Loading…
Cancel
Save