From 94fd60db10830bd76bf8122522f6a314f5f878b7 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Fri, 21 Dec 2018 11:32:17 +0000 Subject: [PATCH] Transports: Improve banning of routers from wrong network --- .../KademliaNetworkDatabaseFacade.java | 2 +- .../transport/ntcp/InboundEstablishState.java | 35 +++++++++++++++++++ .../router/transport/ntcp/NTCPTransport.java | 7 ++++ .../transport/udp/EstablishmentManager.java | 2 +- .../router/transport/udp/UDPTransport.java | 15 +++++--- 5 files changed, 55 insertions(+), 6 deletions(-) diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java index 8962b3635c..d6f0bb7903 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java @@ -920,7 +920,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad return "Invalid routerInfo signature"; } if (routerInfo.getNetworkId() != _networkID){ - _context.banlist().banlistRouter(key, "Not in our network"); + _context.banlist().banlistRouterForever(key, "Not in our network: " + routerInfo.getNetworkId()); if (_log.shouldLog(Log.WARN)) _log.warn("Bad network: " + routerInfo); return "Not in our network"; diff --git a/router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java b/router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java index 38066761e0..c718de552c 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java @@ -572,6 +572,38 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa return true; } + /** + * Validate network ID, NTCP 2 only. + * Call after receiving Alice's RouterInfo, + * but before storing it in the netdb. + * + * Side effects: When returning false, sets _msg3p2FailReason, + * banlists permanently and blocklists + * + * @return success + * @since 0.9.38 + */ + private boolean verifyInboundNetworkID(RouterInfo alice) { + int aliceID = alice.getNetworkId(); + boolean rv = aliceID == _context.router().getNetworkID(); + if (!rv) { + Hash aliceHash = alice.getHash(); + if (_log.shouldLog(Log.WARN)) + _log.warn("Dropping inbound connection from wrong network: " + aliceID + ' ' + aliceHash); + // So next time we will not accept the con from this IP, + // rather than doing the whole handshake + InetAddress addr = _con.getChannel().socket().getInetAddress(); + if (addr != null) { + byte[] ip = addr.getAddress(); + _context.blocklist().add(ip); + } + _context.banlist().banlistRouterForever(aliceHash, "Not in our network: " + aliceID); + _transport.markUnreachable(aliceHash); + _msg3p2FailReason = NTCPConnection.REASON_BANNED; + } + return rv; + } + /** * We are Bob. Send message #4 to Alice. * @@ -988,6 +1020,9 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa boolean ok = verifyInbound(h); if (!ok) throw new DataFormatException("NTCP2 verifyInbound() fail"); + ok = verifyInboundNetworkID(ri); + if (!ok) + throw new DataFormatException("NTCP2 network ID mismatch"); try { RouterInfo old = _context.netDb().store(h, ri); if (flood && !ri.equals(old)) { diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java index e05a935a69..321b250cb4 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -81,6 +81,7 @@ public class NTCPTransport extends TransportImpl { private int _ssuPort; /** synch on this */ private final Set<InetSocketAddress> _endpoints; + private final int _networkID; /** * list of NTCPConnection of connections not yet established that we @@ -229,6 +230,7 @@ public class NTCPTransport extends TransportImpl { _reader = new Reader(ctx); _writer = new net.i2p.router.transport.ntcp.Writer(ctx); + _networkID = ctx.router().getNetworkID(); _fastBid = new SharedBid(25); // best _slowBid = new SharedBid(70); // better than ssu unestablished, but not better than ssu established _slowCostBid = new SharedBid(85); @@ -504,6 +506,11 @@ public class NTCPTransport extends TransportImpl { } return _fastBid; } + if (toAddress.getNetworkId() != _networkID) { + _context.banlist().banlistRouterForever(peer, "Not in our network: " + toAddress.getNetworkId()); + markUnreachable(peer); + return null; + } if (dataSize > NTCPConnection.NTCP1_MAX_MSG_SIZE) { // Not established, too big for NTCP 1, let SSU deal with it // TODO look at his addresses to see if NTCP2 supported? diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java index 9d5c912079..645d2f8096 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -252,7 +252,7 @@ class EstablishmentManager { RouterIdentity toIdentity = toRouterInfo.getIdentity(); Hash toHash = toIdentity.calculateHash(); if (toRouterInfo.getNetworkId() != _networkID) { - _context.banlist().banlistRouter(toHash); + _context.banlist().banlistRouterForever(toHash, "Not in our network: " + toRouterInfo.getNetworkId()); _transport.markUnreachable(toHash); _transport.failed(msg, "Remote peer is on the wrong network, cannot establish"); return; diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index 4071879422..5b0a680661 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -1416,7 +1416,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority _context.simpleTimer2().addEvent(new RemoveDropList(remote), DROPLIST_PERIOD); } markUnreachable(peerHash); - _context.banlist().banlistRouter(peerHash, "Part of the wrong network, version = " + ((RouterInfo) entry).getVersion()); + _context.banlist().banlistRouterForever(peerHash, "Not in our network: " + ((RouterInfo) entry).getNetworkId()); //_context.banlist().banlistRouter(peerHash, "Part of the wrong network", STYLE); if (peer != null) sendDestroy(peer); @@ -1754,6 +1754,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority else return _cachedBid[FAST_BID]; } else { + if (toAddress.getNetworkId() != _networkID) { + _context.banlist().banlistRouterForever(to, "Not in our network: " + toAddress.getNetworkId()); + markUnreachable(to); + return null; + } + // If we don't have a port, all is lost if ( _reachabilityStatus == Status.HOSED) { markUnreachable(to); @@ -1880,15 +1886,16 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority @Override public void send(OutNetMessage msg) { if (msg == null) return; - if (msg.getTarget() == null) return; - if (msg.getTarget().getIdentity() == null) return; + RouterInfo tori = msg.getTarget(); + if (tori == null) return; + if (tori.getIdentity() == null) return; if (_establisher == null) { failed(msg, "UDP not up yet"); return; } msg.timestamp("sending on UDP transport"); - Hash to = msg.getTarget().getIdentity().calculateHash(); + Hash to = tori.getIdentity().calculateHash(); PeerState peer = getPeerState(to); if (_log.shouldLog(Log.DEBUG)) _log.debug("Sending to " + (to != null ? to.toString() : "")); -- GitLab