Browse Source

[transports] validate IP when trying connect to remote peer for being in reserved IP range

Signed-off-by: R4SAS <r4sas@i2pmail.org>
pull/1559/head
R4SAS 4 years ago committed by R4SAS
parent
commit
85e9da82b0
  1. 2
      daemon/Daemon.cpp
  2. 1
      libi2pd/Config.cpp
  3. 1
      libi2pd/SSU.cpp
  4. 9
      libi2pd/Transports.cpp
  5. 5
      libi2pd/Transports.h
  6. 49
      libi2pd/util.cpp
  7. 1
      libi2pd/util.h

2
daemon/Daemon.cpp

@ -299,10 +299,12 @@ namespace i2p @@ -299,10 +299,12 @@ namespace i2p
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
bool ssu; i2p::config::GetOption("ssu", ssu);
bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved);
LogPrint(eLogInfo, "Daemon: starting Transports");
if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled");
if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled");
i2p::transport::transports.SetCheckReserved(checkInReserved);
i2p::transport::transports.Start(ntcp2, ssu);
if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
LogPrint(eLogInfo, "Daemon: Transports started");

1
libi2pd/Config.cpp

@ -51,6 +51,7 @@ namespace config { @@ -51,6 +51,7 @@ namespace config {
("port", value<uint16_t>()->default_value(0), "Port to listen for incoming connections (default: auto)")
("ipv4", value<bool>()->default_value(true), "Enable communication through ipv4 (default: enabled)")
("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)")
("reservedrange", value<bool>()->default_value(true), "Check remote RI for being in blacklist of reserved IP ranges (default: enabled)")
("netid", value<int>()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2")
("daemon", bool_switch()->default_value(false), "Router will go to background after start (default: disabled)")
("service", bool_switch()->default_value(false), "Router will use system folders like '/var/lib/i2pd' (default: disabled)")

1
libi2pd/SSU.cpp

@ -459,6 +459,7 @@ namespace transport @@ -459,6 +459,7 @@ namespace transport
// otherwise create new session
auto session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest);
sessions[remoteEndpoint] = session;
// connect
LogPrint (eLogDebug, "SSU: Creating new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ",
remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ());

9
libi2pd/Transports.cpp

@ -131,8 +131,8 @@ namespace transport @@ -131,8 +131,8 @@ namespace transport
Transports transports;
Transports::Transports ():
m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_Thread (nullptr), m_Service (nullptr),
m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr),
m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_СheckReserved(true), m_Thread (nullptr),
m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr),
m_SSUServer (nullptr), m_NTCP2Server (nullptr),
m_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 pre-generated keys
m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0),
@ -393,7 +393,7 @@ namespace transport @@ -393,7 +393,7 @@ namespace transport
{
// NTCP2 have priority over NTCP
auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only
if (address && !peer.router->IsUnreachable ())
if (address && !peer.router->IsUnreachable () && (!m_СheckReserved || !i2p::util::net::IsInReservedRange(address->host)))
{
auto s = std::make_shared<NTCP2Session> (*m_NTCP2Server, peer.router);
@ -419,10 +419,13 @@ namespace transport @@ -419,10 +419,13 @@ namespace transport
if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ()))
{
auto address = peer.router->GetSSUAddress (!context.SupportsV6 ());
if (!m_СheckReserved || !i2p::util::net::IsInReservedRange(address->host))
{
m_SSUServer->CreateSession (peer.router, address->host, address->port);
return true;
}
}
}
LogPrint (eLogInfo, "Transports: No NTCP or SSU addresses available");
i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed
peer.Done ();

5
libi2pd/Transports.h

@ -136,6 +136,9 @@ namespace transport @@ -136,6 +136,9 @@ namespace transport
void PeerTest ();
void SetCheckReserved (bool check) { m_СheckReserved = check; };
bool IsCheckReserved () { return m_СheckReserved; };
private:
void Run ();
@ -152,7 +155,7 @@ namespace transport @@ -152,7 +155,7 @@ namespace transport
private:
volatile bool m_IsOnline;
bool m_IsRunning, m_IsNAT;
bool m_IsRunning, m_IsNAT, m_СheckReserved;
std::thread * m_Thread;
boost::asio::io_service * m_Service;
boost::asio::io_service::work * m_Work;

49
libi2pd/util.cpp

@ -61,6 +61,9 @@ int inet_pton_xp(int af, const char *src, void *dst) @@ -61,6 +61,9 @@ int inet_pton_xp(int af, const char *src, void *dst)
#include <ifaddrs.h>
#endif
#define address_pair_v4(a,b) { boost::asio::ip::address_v4::from_string (a).to_ulong (), boost::asio::ip::address_v4::from_string (b).to_ulong () }
#define address_pair_v6(a,b) { boost::asio::ip::address_v6::from_string (a).to_bytes (), boost::asio::ip::address_v6::from_string (b).to_bytes () }
namespace i2p
{
namespace util
@ -391,6 +394,50 @@ namespace net @@ -391,6 +394,50 @@ namespace net
return boost::asio::ip::address::from_string(fallback);
#endif
}
}
bool IsInReservedRange(const boost::asio::ip::address& host) {
// https://en.wikipedia.org/wiki/Reserved_IP_addresses
if(host.is_v4())
{
static const std::vector< std::pair<uint32_t, uint32_t> > reservedIPv4Ranges {
address_pair_v4("0.0.0.0", "0.255.255.255"),
address_pair_v4("10.0.0.0", "10.255.255.255"),
address_pair_v4("100.64.0.0", "100.127.255.255"),
address_pair_v4("127.0.0.0", "127.255.255.255"),
address_pair_v4("169.254.0.0", "169.254.255.255"),
address_pair_v4("172.16.0.0", "172.31.255.255"),
address_pair_v4("192.0.0.0", "192.0.0.255"),
address_pair_v4("192.0.2.0", "192.0.2.255"),
address_pair_v4("192.88.99.0", "192.88.99.255"),
address_pair_v4("192.168.0.0", "192.168.255.255"),
address_pair_v4("198.18.0.0", "192.19.255.255"),
address_pair_v4("198.51.100.0", "198.51.100.255"),
address_pair_v4("203.0.113.0", "203.0.113.255"),
address_pair_v4("224.0.0.0", "255.255.255.255")
};
uint32_t ipv4_address = host.to_v4 ().to_ulong ();
for(const auto& it : reservedIPv4Ranges) {
if (ipv4_address >= it.first && ipv4_address <= it.second)
return true;
}
}
if(host.is_v6())
{
static const std::vector< std::pair<boost::asio::ip::address_v6::bytes_type, boost::asio::ip::address_v6::bytes_type> > reservedIPv6Ranges {
address_pair_v6("2001:db8::", "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff"),
address_pair_v6("fc00::", "fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"),
address_pair_v6("fe80::", "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
};
boost::asio::ip::address_v6::bytes_type ipv6_address = host.to_v6 ().to_bytes ();
for(const auto& it : reservedIPv6Ranges) {
if (ipv6_address >= it.first && ipv6_address <= it.second)
return true;
}
}
return false;
}
} // net
} // util
} // i2p

1
libi2pd/util.h

@ -172,6 +172,7 @@ namespace util @@ -172,6 +172,7 @@ namespace util
{
int GetMTU (const boost::asio::ip::address& localAddress);
const boost::asio::ip::address GetInterfaceAddress(const std::string & ifname, bool ipv6=false);
bool IsInReservedRange(const boost::asio::ip::address& host);
}
}
}

Loading…
Cancel
Save