Transports: Implement cross-network detection (proposal 147)

Reseed: Send network ID in query string (proposal 147)
This commit is contained in:
zzz
2019-08-05 14:27:17 +00:00
parent fb7b3c2793
commit a4bcff093f
6 changed files with 55 additions and 12 deletions

View File

@ -385,7 +385,11 @@ public class Router implements RouterClock.ClockShiftListener {
if (sid != null) {
try {
id = Integer.parseInt(sid);
} catch (NumberFormatException nfe) {}
if (id < 2 || id > 254)
throw new IllegalArgumentException("Invalid " + PROP_NETWORK_ID);
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException("Invalid " + PROP_NETWORK_ID);
}
}
_networkID = id;
// for testing
@ -600,6 +604,8 @@ public class Router implements RouterClock.ClockShiftListener {
* The network ID. Default 2.
* May be changed with the config property router.networkID (restart required).
* Change only if running a test network to prevent cross-network contamination.
*
* @return 2 - 254
* @since 0.9.25
*/
public int getNetworkID() { return _networkID; }

View File

@ -66,6 +66,8 @@ public class Reseeder {
private static final boolean ENABLE_NON_SU3 = false;
private static final int MIN_RI_WANTED = 100;
private static final int MIN_RESEED_SERVERS = 2;
// network ID cross-check, proposal 147, as of 0.9.42
private static final String NETID_PARAM = "?netid=";
/**
* NOTE - URLs that are in both the standard and SSL groups must use the same hostname,
@ -112,10 +114,8 @@ public class Reseeder {
"https://reseed.i2p.net.in/" + ',' + // reseedi2pnetin_at_mail.i2p.crt // CA // Java 8+ only, TLS 1.2 only
"https://i2p.novg.net/" + ',' + // igor_at_novg.net.crt // CA // Java 8+ only
"https://i2pseed.creativecowpat.net:8443/" + ',' + // creativecowpat_at_mail.i2p.crt // i2pseed.creativecowpat.net.crt // Java 7+
//"https://itoopie.atomike.ninja/" + ',' + // atomike_at_mail.i2p.crt // CA // Java 8+ only
"https://reseed.onion.im/" + ',' + // lazygravy_at_mail.i2p // reseed.onion.im.crt // Java 8+ only
"https://reseed.memcpy.io/" + ',' + // hottuna_at_mail.i2p.crt // CA // SNI required
//"https://reseed.atomike.ninja/" + ',' + // atomike_at_mail.i2p.crt // CA // SNI required, Java 8+ only
"https://i2p.mooo.com/netDb/" + ',' + // bugme_at_mail.i2p.crt // i2p.mooo.com.crt
"https://download.xxlspeed.com/" + ',' + // backup_at_mail.i2p.crt // CA // Java 8+
"https://netdb.i2p2.no/" + ',' + // meeh_at_mail.i2p.crt // CA // SNI required
@ -338,12 +338,19 @@ public class Reseeder {
int total;
if (_url != null) {
String lc = _url.getPath().toLowerCase(Locale.US);
if (lc.endsWith(".su3"))
total = reseedSU3(_url, false);
else if (lc.endsWith(".zip"))
if (lc.endsWith(".su3")) {
URI uri;
try {
uri = new URI(_url.toString() + SU3_FILENAME + NETID_PARAM + _context.router().getNetworkID());
} catch (URISyntaxException use) {
throw new IllegalArgumentException("Bad URL " + _url, use);
}
total = reseedSU3(uri, false);
} else if (lc.endsWith(".zip")) {
total = reseedZip(_url, false);
else
} else {
throw new IllegalArgumentException("Must end with .zip or .su3");
}
} else {
total = reseed(false);
}
@ -550,8 +557,6 @@ public class Reseeder {
}
if (!isSNISupported()) {
try {
URLList.remove(new URI("https://i2p.manas.ca:8443/"));
URLList.remove(new URI("https://i2p-0.manas.ca:8443/"));
URLList.remove(new URI("https://download.xxlspeed.com/"));
URLList.remove(new URI("https://netdb.i2p2.no/"));
} catch (URISyntaxException mue) {}
@ -573,6 +578,8 @@ public class Reseeder {
* @return count of routerinfos successfully fetched
*/
private int reseed(List<URI> URLList, boolean echoStatus) {
// network ID cross-check, proposal 147, as of 0.9.42
String query = NETID_PARAM + _context.router().getNetworkID();
int total = 0;
int fetched_reseed_servers = 0;
for (int i = 0; i < URLList.size() && _isRunning; i++) {
@ -584,7 +591,7 @@ public class Reseeder {
int dl = 0;
if (ENABLE_SU3) {
try {
dl = reseedSU3(new URI(url.toString() + SU3_FILENAME), echoStatus);
dl = reseedSU3(new URI(url.toString() + SU3_FILENAME + query), echoStatus);
} catch (URISyntaxException mue) {}
}
if (ENABLE_NON_SU3) {

View File

@ -729,6 +729,20 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
fail("Bad version: " + v);
return;
}
// network ID cross-check, proposal 147, as of 0.9.42
v = options[0] & 0xff;
if (v != 0 && v != _context.router().getNetworkID()) {
InetAddress addr = _con.getChannel().socket().getInetAddress();
if (addr != null) {
if (_log.shouldLog(Log.WARN))
_log.warn("Dropping inbound connection from wrong network: " + addr);
byte[] ip = addr.getAddress();
// So next time we will not accept the con from this IP
_context.blocklist().add(ip);
}
fail("Bad network id: " + v);
return;
}
_padlen1 = (int) DataHelper.fromLong(options, 2, 2);
_msg3p2len = (int) DataHelper.fromLong(options, 4, 2);
long tsA = DataHelper.fromLong(options, 8, 4);

View File

@ -191,6 +191,8 @@ class OutboundNTCP2State implements EstablishState {
if (_log.shouldLog(Log.DEBUG))
_log.debug(this + "send X");
byte options[] = new byte[OPTIONS1_SIZE];
// network ID cross-check, proposal 147
options[0] = (byte) (_context.router().getNetworkID());
options[1] = NTCPTransport.NTCP2_INT_VERSION;
int padlen1 = _context.random().nextInt(PADDING1_MAX);
DataHelper.toLong(options, 2, 2, padlen1);

View File

@ -1614,7 +1614,14 @@ class PacketBuilder {
off += totalSize;
System.arraycopy(iv, 0, data, off, UDPPacket.IV_SIZE);
off += UDPPacket.IV_SIZE;
DataHelper.toLong(data, off, 2, totalSize /* ^ PROTOCOL_VERSION */ );
// version is zero, unlikely to ever change
int plval = totalSize /* ^ PacketBuilder.PROTOCOL_VERSION */ ;
// network ID cross-check, proposal 147
int netid = _context.router().getNetworkID();
if (netid != 2) {
plval ^= (netid - 2) << 8;
}
DataHelper.toLong(data, off, 2, plval);
int hmacLen = totalSize + UDPPacket.IV_SIZE + 2;
//Hash hmac = _context.hmac().calculate(macKey, data, hmacOff, hmacLen);

View File

@ -242,7 +242,14 @@ class UDPPacket implements CDQEntry {
off += payloadLength;
System.arraycopy(_data, _packet.getOffset() + MAC_SIZE, _validateBuf, off, IV_SIZE);
off += IV_SIZE;
DataHelper.toLong(_validateBuf, off, 2, payloadLength /* ^ PacketBuilder.PROTOCOL_VERSION */ );
// version is zero, unlikely to ever change
int plval = payloadLength /* ^ PacketBuilder.PROTOCOL_VERSION */ ;
// network ID cross-check, proposal 147
int netid = _context.router().getNetworkID();
if (netid != 2) {
plval ^= (netid - 2) << 8;
}
DataHelper.toLong(_validateBuf, off, 2, plval);
off += 2;
eq = hmac.verify(macKey, _validateBuf, 0, off, _data, _packet.getOffset(), MAC_SIZE);