From ed0d1c29119b68ffa72c3c4f1fd2d4cf23f4398a Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Sat, 13 Jun 2015 17:37:55 +0200 Subject: [PATCH] issue #4: prevent connections to self, select random nodes to connect to --- .../java/ch/dissem/bitmessage/InternalContext.java | 10 ++++++++++ .../main/java/ch/dissem/bitmessage/utils/Security.java | 4 ++++ .../ch/dissem/bitmessage/networking/Connection.java | 9 ++++++--- .../dissem/bitmessage/repository/JdbcNodeRegistry.java | 2 +- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/domain/src/main/java/ch/dissem/bitmessage/InternalContext.java b/domain/src/main/java/ch/dissem/bitmessage/InternalContext.java index a66efd8..600ee4f 100644 --- a/domain/src/main/java/ch/dissem/bitmessage/InternalContext.java +++ b/domain/src/main/java/ch/dissem/bitmessage/InternalContext.java @@ -52,6 +52,7 @@ public class InternalContext { private final int port; private long networkNonceTrialsPerByte = 1000; private long networkExtraBytes = 1000; + private long clientNonce; public InternalContext(BitmessageContext.Builder builder) { this.inventory = builder.inventory; @@ -60,6 +61,7 @@ public class InternalContext { this.addressRepository = builder.addressRepo; this.messageRepository = builder.messageRepo; this.proofOfWorkEngine = builder.proofOfWorkEngine; + this.clientNonce = Security.randomNonce(); port = builder.port; streams = builder.streams; @@ -212,6 +214,14 @@ public class InternalContext { } } + public long getClientNonce() { + return clientNonce; + } + + public void setClientNonce(long clientNonce) { + this.clientNonce = clientNonce; + } + public interface ContextHolder { void setContext(InternalContext context); } diff --git a/domain/src/main/java/ch/dissem/bitmessage/utils/Security.java b/domain/src/main/java/ch/dissem/bitmessage/utils/Security.java index db4faed..d3e5878 100644 --- a/domain/src/main/java/ch/dissem/bitmessage/utils/Security.java +++ b/domain/src/main/java/ch/dissem/bitmessage/utils/Security.java @@ -230,4 +230,8 @@ public class Security { throw new RuntimeException(e); } } + + public static long randomNonce() { + return RANDOM.nextLong(); + } } diff --git a/networking/src/main/java/ch/dissem/bitmessage/networking/Connection.java b/networking/src/main/java/ch/dissem/bitmessage/networking/Connection.java index 9b191dc..fcf7eee 100644 --- a/networking/src/main/java/ch/dissem/bitmessage/networking/Connection.java +++ b/networking/src/main/java/ch/dissem/bitmessage/networking/Connection.java @@ -102,7 +102,10 @@ public class Connection implements Runnable { switch (msg.getPayload().getCommand()) { case VERSION: Version payload = (Version) msg.getPayload(); - if (payload.getVersion() >= BitmessageContext.CURRENT_VERSION) { + if (payload.getNonce() == ctx.getClientNonce()) { + LOG.info("Tried to connect to self, disconnecting."); + disconnect(); + } else if (payload.getVersion() >= BitmessageContext.CURRENT_VERSION) { this.version = payload.getVersion(); this.streams = payload.getStreams(); send(new VerAck()); @@ -120,8 +123,8 @@ public class Connection implements Runnable { } break; default: - throw new RuntimeException("Command 'version' or 'verack' expected, but was " - + msg.getPayload().getCommand()); + throw new RuntimeException("Command 'version' or 'verack' expected, but was '" + + msg.getPayload().getCommand() + "'"); } } if (socket.isClosed()) state = DISCONNECTED; diff --git a/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcNodeRegistry.java b/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcNodeRegistry.java index 3cd81e4..43b29a9 100644 --- a/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcNodeRegistry.java +++ b/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcNodeRegistry.java @@ -37,7 +37,7 @@ public class JdbcNodeRegistry extends JdbcHelper implements NodeRegistry { List result = new LinkedList<>(); try (Connection connection = config.getConnection()) { Statement stmt = connection.createStatement(); - ResultSet rs = stmt.executeQuery("SELECT * FROM Node WHERE stream IN (" + join(streams) + ") LIMIT " + limit); + ResultSet rs = stmt.executeQuery("SELECT * FROM Node WHERE stream IN (" + join(streams) + ") ORDER BY RANDOM() LIMIT " + limit); while (rs.next()) { result.add(new NetworkAddress.Builder() .ipv6(rs.getBytes("ip"))