Send and check target destination in first streaming SYN packet
This commit is contained in:
@ -2,6 +2,7 @@ package net.i2p.client.streaming.impl;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -205,6 +206,14 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
||||
packet.setFlag(Packet.FLAG_SYNCHRONIZE);
|
||||
packet.setOptionalFrom();
|
||||
packet.setOptionalMaxSize(_connection.getOptions().getMaxMessageSize());
|
||||
if (!_connection.isInbound()) {
|
||||
byte[] h = _connection.getRemotePeer().calculateHash().getData();
|
||||
long[] fakeNacks = new long[8];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
fakeNacks[i] = DataHelper.fromLong(h, i << 2, 4);
|
||||
}
|
||||
packet.setNacks(fakeNacks);
|
||||
}
|
||||
}
|
||||
packet.setLocalPort(_connection.getLocalPort());
|
||||
packet.setRemotePort(_connection.getPort());
|
||||
|
@ -250,6 +250,31 @@ class ConnectionManager {
|
||||
ByteArray ba = _cache.acquire();
|
||||
boolean sigOk = synPacket.verifySignature(_context, ba.getData());
|
||||
_cache.release(ba);
|
||||
if (sigOk) {
|
||||
long[] nacks = synPacket.getNacks();
|
||||
if (nacks != null && nacks.length == 8) {
|
||||
// we use the packet's session because it may be a subsession
|
||||
Hash hash = synPacket.getSession().getMyDestination().calculateHash();
|
||||
byte[] h = hash.getData();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (nacks[i] != DataHelper.fromLong(h, i << 2, 4)) {
|
||||
if (_log.shouldWarn()) {
|
||||
// glue it back together for logging only
|
||||
byte[] g = new byte[32];
|
||||
for (int j = 0; j < 8; j++) {
|
||||
DataHelper.toLong(g, j << 2, 4, nacks[j]);
|
||||
}
|
||||
Hash ghash = new Hash(g);
|
||||
_log.warn("Sig passed but hash failed, expected: " + hash.toBase32() + " got: " + ghash.toBase32());
|
||||
}
|
||||
sigOk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sigOk && _log.shouldWarn())
|
||||
_log.warn("Validated SYN NACKS from: " + from.toBase32());
|
||||
}
|
||||
}
|
||||
if (!sigOk) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Received unsigned / forged SYN apparently from " + from.toBase32() + ": " + synPacket);
|
||||
|
Reference in New Issue
Block a user