Transports: Check RI in handshake for matching IP

This commit is contained in:
zzz
2023-02-08 08:25:09 -05:00
parent 10e0596011
commit 9e2bb1ad0a
2 changed files with 50 additions and 3 deletions

View File

@@ -629,15 +629,32 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
throw new DataFormatException("no NTCP in RI: " + ri);
}
String s = null;
String mismatchMessage = null;
byte[] realIP = _con.getRemoteIP();
for (RouterAddress addr : addrs) {
String v = addr.getOption("v");
if (v == null ||
(!v.equals(NTCPTransport.NTCP2_VERSION) && !v.startsWith(NTCPTransport.NTCP2_VERSION_ALT))) {
continue;
}
s = addr.getOption("s");
if (s != null)
break;
if (s == null)
s = addr.getOption("s");
if (realIP != null) {
byte[] infoIP = addr.getIP();
if (infoIP != null && infoIP.length == realIP.length) {
if (infoIP.length == 16) {
if ((((int) infoIP[0]) & 0xfe) == 0x02)
continue; // ygg
if (DataHelper.eq(realIP, 0, infoIP, 0, 8))
continue;
} else {
if (DataHelper.eq(realIP, infoIP))
continue;
}
// We will ban and throw below after checking s
mismatchMessage = "IP mismatch actual IP " + Addresses.toString(realIP) + " in RI: ";
}
}
}
if (s == null) {
_msg3p2FailReason = NTCPConnection.REASON_S_MISMATCH;
@@ -661,6 +678,14 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
boolean ok = verifyInbound(h);
if (!ok)
throw new DataFormatException("NTCP2 verifyInbound() fail");
// s is verified, we may now ban the hash
if (mismatchMessage != null) {
_context.banlist().banlistRouter(h, "IP mismatch", null, null, _context.clock().now() + 2*60*60*1000);
_msg3p2FailReason = NTCPConnection.REASON_BANNED;
throw new DataFormatException(mismatchMessage + ri);
}
try {
RouterInfo old = _context.netDb().store(h, ri);
if (flood && !ri.equals(old)) {

View File

@@ -248,6 +248,7 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
boolean isIPv6 = _aliceIP.length == 16;
List<RouterAddress> addrs = _transport.getTargetAddresses(ri);
RouterAddress ra = null;
String mismatchMessage = null;
for (RouterAddress addr : addrs) {
// skip SSU 1 address w/o "s"
if (addrs.size() > 1 && addr.getTransportStyle().equals("SSU") && addr.getOption("s") == null)
@@ -266,6 +267,20 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
continue;
}
ra = addr;
byte[] infoIP = ra.getIP();
if (infoIP != null && infoIP.length == _aliceIP.length) {
if (isIPv6) {
if ((((int) infoIP[0]) & 0xfe) == 0x02)
continue; // ygg
if (DataHelper.eq(_aliceIP, 0, infoIP, 0, 8))
continue;
} else {
if (DataHelper.eq(_aliceIP, infoIP))
continue;
}
// We will ban and throw below after checking signature
mismatchMessage = "IP mismatch actual IP " + Addresses.toString(_aliceIP) + " in RI: ";
}
break;
}
@@ -312,6 +327,13 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
throw new RIException("SSU2 network ID mismatch", REASON_NETID);
}
if (mismatchMessage != null) {
_context.banlist().banlistRouter(h, "IP mismatch", null, null, _context.clock().now() + 2*60*60*1000);
if (ri.verifySignature())
_context.blocklist().add(_aliceIP);
throw new RIException(mismatchMessage + ri, REASON_BANNED);
}
if (!"2".equals(ra.getOption("v")))
throw new RIException("bad SSU2 v", REASON_VERSION);