forked from I2P_Developers/i2p.i2p
* SSU:
- Don't relay or introduce to/from privileged ports - Various spoof detections
This commit is contained in:
@@ -3,6 +3,7 @@ package net.i2p.router.transport.udp;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -241,7 +242,8 @@ class EstablishmentManager {
|
||||
if (remAddr != null && port > 0 && port <= 65535) {
|
||||
maybeTo = new RemoteHostId(remAddr.getAddress(), port);
|
||||
|
||||
if (!_transport.isValid(maybeTo.getIP())) {
|
||||
if ((!_transport.isValid(maybeTo.getIP())) ||
|
||||
Arrays.equals(maybeTo.getIP(), _transport.getExternalIP())) {
|
||||
_transport.failed(msg, "Remote peer's IP isn't valid");
|
||||
_transport.markUnreachable(toHash);
|
||||
//_context.shitlist().shitlistRouter(msg.getTarget().getIdentity().calculateHash(), "Invalid SSU address", UDPTransport.STYLE);
|
||||
@@ -449,18 +451,18 @@ class EstablishmentManager {
|
||||
// Don't offer if we are approaching max connections. While Relay Intros do not
|
||||
// count as connections, we have to keep the connection to this peer up longer if
|
||||
// we are offering introductions.
|
||||
// Don't offer to relay to privileged ports.
|
||||
if ((!_context.router().isHidden()) && (!_transport.introducersRequired()) && _transport.haveCapacity() &&
|
||||
state.getSentPort() >= 1024 &&
|
||||
!((FloodfillNetworkDatabaseFacade)_context.netDb()).floodfillEnabled()) {
|
||||
// ensure > 0
|
||||
long tag = 1 + _context.random().nextLong(MAX_TAG_VALUE);
|
||||
state.setSentRelayTag(tag);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Received NEW session request from " + from + ", sending relay tag " + tag);
|
||||
} else {
|
||||
// we got an IB even though we were firewalled, hidden, not high cap, etc.
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Received session request, but our status is " + _transport.getReachabilityStatus());
|
||||
}
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Received NEW session request " + state);
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Receive DUP session request from: " + state);
|
||||
@@ -900,16 +902,16 @@ class EstablishmentManager {
|
||||
try {
|
||||
if (!_transport.isValid(ip))
|
||||
throw new UnknownHostException("non-public IP");
|
||||
if (port <= 0 || port > 65535)
|
||||
// let's not relay to a privileged port, sounds like trouble
|
||||
if (port < 1024 || port > 65535)
|
||||
throw new UnknownHostException("bad port " + port);
|
||||
if (Arrays.equals(ip, _transport.getExternalIP()))
|
||||
throw new UnknownHostException("relay myself");
|
||||
addr = InetAddress.getByAddress(ip);
|
||||
} catch (UnknownHostException uhe) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Introducer for " + state + " (" + bob + ") sent us an invalid address for our target: " + Addresses.toString(ip, port), uhe);
|
||||
// these two cause this peer to requeue for a new intro peer
|
||||
// FIXME no it doesn't, we send to all at once
|
||||
//state.introductionFailed();
|
||||
//notifyActivity();
|
||||
// TODO either put the nonce back in liveintroductions, or fail
|
||||
return;
|
||||
}
|
||||
_context.statManager().addRateData("udp.receiveIntroRelayResponse", state.getLifetime(), 0);
|
||||
|
@@ -3,6 +3,7 @@ package net.i2p.router.transport.udp;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -72,6 +73,9 @@ class IntroductionManager {
|
||||
|
||||
public void add(PeerState peer) {
|
||||
if (peer == null) return;
|
||||
// let's not use an introducer on a privileged port, sounds like trouble
|
||||
if (peer.getRemotePort() < 1024)
|
||||
return;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Adding peer " + peer.getRemoteHostId() + ", weRelayToThemAs "
|
||||
+ peer.getWeRelayToThemAs() + ", theyRelayToUsAs " + peer.getTheyRelayToUsAs());
|
||||
@@ -156,7 +160,7 @@ class IntroductionManager {
|
||||
}
|
||||
byte[] ip = cur.getRemoteIP();
|
||||
int port = cur.getRemotePort();
|
||||
if (ip == null || !TransportImpl.isPubliclyRoutable(ip) || port <= 0 || port > 65535)
|
||||
if (ip == null || !TransportImpl.isPubliclyRoutable(ip) || port < 1024 || port > 65535)
|
||||
continue;
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Picking introducer: " + cur);
|
||||
@@ -233,8 +237,11 @@ class IntroductionManager {
|
||||
try {
|
||||
if (!_transport.isValid(ip))
|
||||
throw new UnknownHostException("non-public IP");
|
||||
if (port <= 0 || port > 65535)
|
||||
// let's not punch to a privileged port, sounds like trouble
|
||||
if (port < 1024 || port > 65535)
|
||||
throw new UnknownHostException("bad port " + port);
|
||||
if (Arrays.equals(ip, _transport.getExternalIP()))
|
||||
throw new UnknownHostException("punch myself");
|
||||
to = InetAddress.getByAddress(ip);
|
||||
} catch (UnknownHostException uhe) {
|
||||
// shitlist Bob?
|
||||
|
@@ -1066,15 +1066,18 @@ class PacketBuilder {
|
||||
int iport = addr.getIntroducerPort(i);
|
||||
byte ikey[] = addr.getIntroducerKey(i);
|
||||
long tag = addr.getIntroducerTag(i);
|
||||
if ( (ikey == null) || (iport <= 0) || (iaddr == null) || (tag <= 0) ) {
|
||||
// let's not use an introducer on a privileged port, sounds like trouble
|
||||
if (ikey == null || iport < 1024 || iport > 65535 ||
|
||||
iaddr == null || tag <= 0 ||
|
||||
(!_transport.isValid(iaddr.getAddress())) ||
|
||||
Arrays.equals(iaddr.getAddress(), _transport.getExternalIP())) {
|
||||
if (_log.shouldLog(_log.WARN))
|
||||
_log.warn("Cannot build a relay request to " + state.getRemoteIdentity().calculateHash()
|
||||
+ ", as their UDP address is invalid: addr=" + addr + " index=" + i);
|
||||
// TODO implement some sort of introducer shitlist
|
||||
continue;
|
||||
}
|
||||
// TODO implement some sort of introducer shitlist
|
||||
if (transport.isValid(iaddr.getAddress()))
|
||||
rv.add(buildRelayRequest(iaddr, iport, ikey, tag, ourIntroKey, state.getIntroNonce(), true));
|
||||
rv.add(buildRelayRequest(iaddr, iport, ikey, tag, ourIntroKey, state.getIntroNonce(), true));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package net.i2p.router.transport.udp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramSocket;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
@@ -168,6 +169,14 @@ class UDPReceiver {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// drop anything apparently from our IP (any port)
|
||||
if (Arrays.equals(from.getIP(), _transport.getExternalIP())) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Dropping (spoofed?) packet from ourselves");
|
||||
packet.release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
packet.enqueue();
|
||||
boolean rejected = false;
|
||||
int queueSize = 0;
|
||||
|
@@ -6,6 +6,7 @@ import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
@@ -406,6 +407,17 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
public InetAddress getLocalAddress() { return _externalListenHost; }
|
||||
public int getExternalPort() { return _externalListenPort; }
|
||||
|
||||
/**
|
||||
* @return IP or null
|
||||
* @since 0.9.2
|
||||
*/
|
||||
byte[] getExternalIP() {
|
||||
InetAddress ia = _externalListenHost;
|
||||
if (ia == null)
|
||||
return null;
|
||||
return ia.getAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* _externalListenPort should always be set (by startup()) before this is called,
|
||||
* so the returned value should be > 0
|
||||
@@ -1183,14 +1195,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
markUnreachable(to);
|
||||
return null;
|
||||
}
|
||||
|
||||
UDPAddress ua = new UDPAddress(addr);
|
||||
if (ua == null) {
|
||||
markUnreachable(to);
|
||||
return null;
|
||||
}
|
||||
if (ua.getIntroducerCount() <= 0) {
|
||||
InetAddress ia = ua.getHostAddress();
|
||||
if (ua.getPort() <= 0 || ia == null || !isValid(ia.getAddress())) {
|
||||
if (ua.getPort() <= 0 || ia == null || !isValid(ia.getAddress()) ||
|
||||
Arrays.equals(ia.getAddress(), getExternalIP())) {
|
||||
markUnreachable(to);
|
||||
return null;
|
||||
}
|
||||
|
Reference in New Issue
Block a user