Code cleanup

This commit is contained in:
Christian Basler 2016-02-28 23:03:00 +01:00
parent 57057298a1
commit 3e5e431d6f
6 changed files with 313 additions and 261 deletions

View File

@ -51,19 +51,23 @@ import java.util.Arrays;
*/ */
public class BouncyCryptography extends AbstractCryptography { public class BouncyCryptography extends AbstractCryptography {
private static final X9ECParameters EC_CURVE_PARAMETERS = CustomNamedCurves.getByName("secp256k1"); private static final X9ECParameters EC_CURVE_PARAMETERS = CustomNamedCurves.getByName("secp256k1");
private static final String ALGORITHM_ECDSA = "ECDSA";
private static final String PROVIDER = "BC";
static { static {
java.security.Security.addProvider(new BouncyCastleProvider()); java.security.Security.addProvider(new BouncyCastleProvider());
} }
public BouncyCryptography() { public BouncyCryptography() {
super("BC"); super(PROVIDER);
} }
@Override @Override
public byte[] crypt(boolean encrypt, byte[] data, byte[] key_e, byte[] initializationVector) { public byte[] crypt(boolean encrypt, byte[] data, byte[] key_e, byte[] initializationVector) {
BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()), new PKCS7Padding()); BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()),
new PKCS7Padding()
);
CipherParameters params = new ParametersWithIV(new KeyParameter(key_e), initializationVector); CipherParameters params = new ParametersWithIV(new KeyParameter(key_e), initializationVector);
cipher.init(encrypt, params); cipher.init(encrypt, params);
@ -105,9 +109,9 @@ public class BouncyCryptography extends AbstractCryptography {
ECPoint Q = keyToPoint(pubkey.getSigningKey()); ECPoint Q = keyToPoint(pubkey.getSigningKey());
KeySpec keySpec = new ECPublicKeySpec(Q, spec); KeySpec keySpec = new ECPublicKeySpec(Q, spec);
PublicKey publicKey = KeyFactory.getInstance("ECDSA", "BC").generatePublic(keySpec); PublicKey publicKey = KeyFactory.getInstance(ALGORITHM_ECDSA, PROVIDER).generatePublic(keySpec);
Signature sig = Signature.getInstance("ECDSA", "BC"); Signature sig = Signature.getInstance(ALGORITHM_ECDSA, PROVIDER);
sig.initVerify(publicKey); sig.initVerify(publicKey);
sig.update(data); sig.update(data);
return sig.verify(signature); return sig.verify(signature);
@ -129,9 +133,10 @@ public class BouncyCryptography extends AbstractCryptography {
BigInteger d = keyToBigInt(privateKey.getPrivateSigningKey()); BigInteger d = keyToBigInt(privateKey.getPrivateSigningKey());
KeySpec keySpec = new ECPrivateKeySpec(d, spec); KeySpec keySpec = new ECPrivateKeySpec(d, spec);
java.security.PrivateKey privKey = KeyFactory.getInstance("ECDSA", "BC").generatePrivate(keySpec); java.security.PrivateKey privKey = KeyFactory.getInstance(ALGORITHM_ECDSA, PROVIDER)
.generatePrivate(keySpec);
Signature sig = Signature.getInstance("ECDSA", "BC"); Signature sig = Signature.getInstance(ALGORITHM_ECDSA, PROVIDER);
sig.initSign(privKey); sig.initSign(privKey);
sig.update(data); sig.update(data);
return sig.sign(); return sig.sign();

View File

@ -51,19 +51,23 @@ import java.util.Arrays;
*/ */
public class SpongyCryptography extends AbstractCryptography { public class SpongyCryptography extends AbstractCryptography {
private static final X9ECParameters EC_CURVE_PARAMETERS = CustomNamedCurves.getByName("secp256k1"); private static final X9ECParameters EC_CURVE_PARAMETERS = CustomNamedCurves.getByName("secp256k1");
private static final String ALGORITHM_ECDSA = "ECDSA";
private static final String PROVIDER = "SC";
static { static {
java.security.Security.addProvider(new BouncyCastleProvider()); java.security.Security.addProvider(new BouncyCastleProvider());
} }
public SpongyCryptography() { public SpongyCryptography() {
super("SC"); super(PROVIDER);
} }
@Override @Override
public byte[] crypt(boolean encrypt, byte[] data, byte[] key_e, byte[] initializationVector) { public byte[] crypt(boolean encrypt, byte[] data, byte[] key_e, byte[] initializationVector) {
BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()), new PKCS7Padding()); BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()),
new PKCS7Padding()
);
CipherParameters params = new ParametersWithIV(new KeyParameter(key_e), initializationVector); CipherParameters params = new ParametersWithIV(new KeyParameter(key_e), initializationVector);
cipher.init(encrypt, params); cipher.init(encrypt, params);
@ -105,9 +109,9 @@ public class SpongyCryptography extends AbstractCryptography {
ECPoint Q = keyToPoint(pubkey.getSigningKey()); ECPoint Q = keyToPoint(pubkey.getSigningKey());
KeySpec keySpec = new ECPublicKeySpec(Q, spec); KeySpec keySpec = new ECPublicKeySpec(Q, spec);
PublicKey publicKey = KeyFactory.getInstance("ECDSA", "SC").generatePublic(keySpec); PublicKey publicKey = KeyFactory.getInstance(ALGORITHM_ECDSA, PROVIDER).generatePublic(keySpec);
Signature sig = Signature.getInstance("ECDSA", "SC"); Signature sig = Signature.getInstance(ALGORITHM_ECDSA, PROVIDER);
sig.initVerify(publicKey); sig.initVerify(publicKey);
sig.update(data); sig.update(data);
return sig.verify(signature); return sig.verify(signature);
@ -129,9 +133,10 @@ public class SpongyCryptography extends AbstractCryptography {
BigInteger d = keyToBigInt(privateKey.getPrivateSigningKey()); BigInteger d = keyToBigInt(privateKey.getPrivateSigningKey());
KeySpec keySpec = new ECPrivateKeySpec(d, spec); KeySpec keySpec = new ECPrivateKeySpec(d, spec);
java.security.PrivateKey privKey = KeyFactory.getInstance("ECDSA", "SC").generatePrivate(keySpec); java.security.PrivateKey privKey = KeyFactory.getInstance(ALGORITHM_ECDSA, PROVIDER)
.generatePrivate(keySpec);
Signature sig = Signature.getInstance("ECDSA", "SC"); Signature sig = Signature.getInstance(ALGORITHM_ECDSA, PROVIDER);
sig.initSign(privKey); sig.initSign(privKey);
sig.update(data); sig.update(data);
return sig.sign(); return sig.sign();

View File

@ -17,31 +17,33 @@
package ch.dissem.bitmessage.demo; package ch.dissem.bitmessage.demo;
import ch.dissem.bitmessage.BitmessageContext; import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography;
import ch.dissem.bitmessage.entity.BitmessageAddress; import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.entity.Plaintext; import ch.dissem.bitmessage.entity.Plaintext;
import ch.dissem.bitmessage.entity.payload.Pubkey; import ch.dissem.bitmessage.entity.payload.Pubkey;
import ch.dissem.bitmessage.networking.DefaultNetworkHandler; import ch.dissem.bitmessage.networking.DefaultNetworkHandler;
import ch.dissem.bitmessage.ports.MemoryNodeRegistry; import ch.dissem.bitmessage.ports.MemoryNodeRegistry;
import ch.dissem.bitmessage.repository.*; import ch.dissem.bitmessage.repository.*;
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.List; import java.util.List;
import java.util.Scanner;
import static ch.dissem.bitmessage.demo.CommandLine.COMMAND_BACK;
import static ch.dissem.bitmessage.demo.CommandLine.ERROR_UNKNOWN_COMMAND;
/** /**
* A simple command line Bitmessage application * A simple command line Bitmessage application
*/ */
public class Application { public class Application {
private final static Logger LOG = LoggerFactory.getLogger(Application.class); private final static Logger LOG = LoggerFactory.getLogger(Application.class);
private final Scanner scanner; private final CommandLine commandLine;
private BitmessageContext ctx; private BitmessageContext ctx;
public Application(String syncServer, int syncPort) { public Application(InetAddress syncServer, int syncPort) {
JdbcConfig jdbcConfig = new JdbcConfig(); JdbcConfig jdbcConfig = new JdbcConfig();
ctx = new BitmessageContext.Builder() ctx = new BitmessageContext.Builder()
.addressRepo(new JdbcAddressRepository(jdbcConfig)) .addressRepo(new JdbcAddressRepository(jdbcConfig))
@ -68,7 +70,7 @@ public class Application {
ctx.startup(); ctx.startup();
} }
scanner = new Scanner(System.in); commandLine = new CommandLine();
String command; String command;
do { do {
@ -84,7 +86,7 @@ public class Application {
System.out.println("?) info"); System.out.println("?) info");
System.out.println("e) exit"); System.out.println("e) exit");
command = nextCommand(); command = commandLine.nextCommand();
try { try {
switch (command) { switch (command) {
case "i": { case "i": {
@ -106,10 +108,12 @@ public class Application {
case "e": case "e":
break; break;
case "y": case "y":
ctx.synchronize(InetAddress.getByName(syncServer), syncPort, 120, true); if (syncServer != null) {
ctx.synchronize(syncServer, syncPort, 120, true);
}
break; break;
default: default:
System.out.println("Unknown command. Please try again."); System.out.println(ERROR_UNKNOWN_COMMAND);
} }
} catch (Exception e) { } catch (Exception e) {
LOG.debug(e.getMessage()); LOG.debug(e.getMessage());
@ -125,32 +129,16 @@ public class Application {
System.out.println(ctx.status()); System.out.println(ctx.status());
} }
private String nextCommand() {
return scanner.nextLine().trim().toLowerCase();
}
private void identities() { private void identities() {
String command; String command;
List<BitmessageAddress> identities = ctx.addresses().getIdentities(); List<BitmessageAddress> identities = ctx.addresses().getIdentities();
do { do {
System.out.println(); System.out.println();
int i = 0; commandLine.listAddresses(identities, "identities");
for (BitmessageAddress identity : identities) {
i++;
System.out.print(i + ") ");
if (identity.getAlias() != null) {
System.out.println(identity.getAlias() + " (" + identity.getAddress() + ")");
} else {
System.out.println(identity.getAddress());
}
}
if (i == 0) {
System.out.println("You have no identities yet.");
}
System.out.println("a) create identity"); System.out.println("a) create identity");
System.out.println("b) back"); System.out.println(COMMAND_BACK);
command = nextCommand(); command = commandLine.nextCommand();
switch (command) { switch (command) {
case "a": case "a":
addIdentity(); addIdentity();
@ -163,7 +151,7 @@ public class Application {
int index = Integer.parseInt(command) - 1; int index = Integer.parseInt(command) - 1;
address(identities.get(index)); address(identities.get(index));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
System.out.println("Unknown command. Please try again."); System.out.println(ERROR_UNKNOWN_COMMAND);
} }
} }
} while (!"b".equals(command)); } while (!"b".equals(command));
@ -171,9 +159,9 @@ public class Application {
private void addIdentity() { private void addIdentity() {
System.out.println(); System.out.println();
BitmessageAddress identity = ctx.createIdentity(yesNo("would you like a shorter address? This will take some time to calculate."), Pubkey.Feature.DOES_ACK); BitmessageAddress identity = ctx.createIdentity(commandLine.yesNo("would you like a shorter address? This will take some time to calculate."), Pubkey.Feature.DOES_ACK);
System.out.println("Please enter an alias for this identity, or an empty string for none"); System.out.println("Please enter an alias for this identity, or an empty string for none");
String alias = scanner.nextLine().trim(); String alias = commandLine.nextLineTrimmed();
if (alias.length() > 0) { if (alias.length() > 0) {
identity.setAlias(alias); identity.setAlias(alias);
} }
@ -185,24 +173,12 @@ public class Application {
List<BitmessageAddress> contacts = ctx.addresses().getContacts(); List<BitmessageAddress> contacts = ctx.addresses().getContacts();
do { do {
System.out.println(); System.out.println();
int i = 0; commandLine.listAddresses(contacts, "contacts");
for (BitmessageAddress contact : contacts) {
i++;
System.out.print(i + ") ");
if (contact.getAlias() != null) {
System.out.println(contact.getAlias() + " (" + contact.getAddress() + ")");
} else {
System.out.println(contact.getAddress());
}
}
if (i == 0) {
System.out.println("You have no contacts yet.");
}
System.out.println(); System.out.println();
System.out.println("a) add contact"); System.out.println("a) add contact");
System.out.println("b) back"); System.out.println(COMMAND_BACK);
command = nextCommand(); command = commandLine.nextCommand();
switch (command) { switch (command) {
case "a": case "a":
addContact(false); addContact(false);
@ -215,7 +191,7 @@ public class Application {
int index = Integer.parseInt(command) - 1; int index = Integer.parseInt(command) - 1;
address(contacts.get(index)); address(contacts.get(index));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
System.out.println("Unknown command. Please try again."); System.out.println(ERROR_UNKNOWN_COMMAND);
} }
} }
} while (!"b".equals(command)); } while (!"b".equals(command));
@ -225,9 +201,9 @@ public class Application {
System.out.println(); System.out.println();
System.out.println("Please enter the Bitmessage address you want to add"); System.out.println("Please enter the Bitmessage address you want to add");
try { try {
BitmessageAddress address = new BitmessageAddress(scanner.nextLine().trim()); BitmessageAddress address = new BitmessageAddress(commandLine.nextLineTrimmed());
System.out.println("Please enter an alias for this address, or an empty string for none"); System.out.println("Please enter an alias for this address, or an empty string for none");
String alias = scanner.nextLine().trim(); String alias = commandLine.nextLineTrimmed();
if (alias.length() > 0) { if (alias.length() > 0) {
address.setAlias(alias); address.setAlias(alias);
} }
@ -245,24 +221,12 @@ public class Application {
List<BitmessageAddress> subscriptions = ctx.addresses().getSubscriptions(); List<BitmessageAddress> subscriptions = ctx.addresses().getSubscriptions();
do { do {
System.out.println(); System.out.println();
int i = 0; commandLine.listAddresses(subscriptions, "subscriptions");
for (BitmessageAddress contact : subscriptions) {
i++;
System.out.print(i + ") ");
if (contact.getAlias() != null) {
System.out.println(contact.getAlias() + " (" + contact.getAddress() + ")");
} else {
System.out.println(contact.getAddress());
}
}
if (i == 0) {
System.out.println("You have no subscriptions yet.");
}
System.out.println(); System.out.println();
System.out.println("a) add subscription"); System.out.println("a) add subscription");
System.out.println("b) back"); System.out.println(COMMAND_BACK);
command = nextCommand(); command = commandLine.nextCommand();
switch (command) { switch (command) {
case "a": case "a":
addContact(true); addContact(true);
@ -275,7 +239,7 @@ public class Application {
int index = Integer.parseInt(command) - 1; int index = Integer.parseInt(command) - 1;
address(subscriptions.get(index)); address(subscriptions.get(index));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
System.out.println("Unknown command. Please try again."); System.out.println(ERROR_UNKNOWN_COMMAND);
} }
} }
} while (!"b".equals(command)); } while (!"b".equals(command));
@ -313,9 +277,9 @@ public class Application {
System.out.println(); System.out.println();
System.out.println("c) compose message"); System.out.println("c) compose message");
System.out.println("s) compose broadcast"); System.out.println("s) compose broadcast");
System.out.println("b) back"); System.out.println(COMMAND_BACK);
command = scanner.nextLine().trim(); command = commandLine.nextCommand();
switch (command) { switch (command) {
case "c": case "c":
compose(false); compose(false);
@ -330,7 +294,7 @@ public class Application {
int index = Integer.parseInt(command) - 1; int index = Integer.parseInt(command) - 1;
show(messages.get(index)); show(messages.get(index));
} catch (NumberFormatException | IndexOutOfBoundsException e) { } catch (NumberFormatException | IndexOutOfBoundsException e) {
System.out.println("Unknown command. Please try again."); System.out.println(ERROR_UNKNOWN_COMMAND);
} }
} }
} while (!"b".equalsIgnoreCase(command)); } while (!"b".equalsIgnoreCase(command));
@ -350,8 +314,8 @@ public class Application {
do { do {
System.out.println("r) reply"); System.out.println("r) reply");
System.out.println("d) delete"); System.out.println("d) delete");
System.out.println("b) back"); System.out.println(COMMAND_BACK);
command = nextCommand(); command = commandLine.nextCommand();
switch (command) { switch (command) {
case "r": case "r":
compose(message.getTo(), message.getFrom(), "RE: " + message.getSubject()); compose(message.getTo(), message.getFrom(), "RE: " + message.getSubject());
@ -361,18 +325,18 @@ public class Application {
case "b": case "b":
return; return;
default: default:
System.out.println("Unknown command. Please try again."); System.out.println(ERROR_UNKNOWN_COMMAND);
} }
} while (!"b".equalsIgnoreCase(command)); } while (!"b".equalsIgnoreCase(command));
} }
private void compose(boolean broadcast) { private void compose(boolean broadcast) {
System.out.println(); System.out.println();
BitmessageAddress from = selectAddress(true); BitmessageAddress from = selectIdentity();
if (from == null) { if (from == null) {
return; return;
} }
BitmessageAddress to = (broadcast ? null : selectAddress(false)); BitmessageAddress to = (broadcast ? null : selectContact());
if (!broadcast && to == null) { if (!broadcast && to == null) {
return; return;
} }
@ -380,58 +344,22 @@ public class Application {
compose(from, to, null); compose(from, to, null);
} }
private BitmessageAddress selectAddress(boolean id) { private BitmessageAddress selectIdentity() {
List<BitmessageAddress> addresses = (id ? ctx.addresses().getIdentities() : ctx.addresses().getContacts()); List<BitmessageAddress> addresses = ctx.addresses().getIdentities();
while (addresses.size() == 0) { while (addresses.size() == 0) {
if (id) {
addIdentity(); addIdentity();
addresses = ctx.addresses().getIdentities(); addresses = ctx.addresses().getIdentities();
} else { }
return commandLine.selectAddress(addresses, "From:");
}
private BitmessageAddress selectContact() {
List<BitmessageAddress> addresses = ctx.addresses().getContacts();
while (addresses.size() == 0) {
addContact(false); addContact(false);
addresses = ctx.addresses().getContacts(); addresses = ctx.addresses().getContacts();
} }
} return commandLine.selectAddress(addresses, "To:");
if (addresses.size() == 1) {
return addresses.get(0);
}
String command;
do {
System.out.println();
if (id) {
System.out.println("From:");
} else {
System.out.println("To:");
}
int i = 0;
for (BitmessageAddress identity : addresses) {
i++;
System.out.print(i + ") ");
if (identity.getAlias() != null) {
System.out.println(identity.getAlias() + " (" + identity.getAddress() + ")");
} else {
System.out.println(identity.getAddress());
}
}
System.out.println("b) back");
command = nextCommand();
switch (command) {
case "b":
return null;
default:
try {
int index = Integer.parseInt(command) - 1;
if (addresses.get(index) != null) {
return addresses.get(index);
}
} catch (NumberFormatException e) {
System.out.println("Unknown command. Please try again.");
}
}
} while (!"b".equals(command));
return null;
} }
private void compose(BitmessageAddress from, BitmessageAddress to, String subject) { private void compose(BitmessageAddress from, BitmessageAddress to, String subject) {
@ -445,29 +373,19 @@ public class Application {
System.out.println("Subject: " + subject); System.out.println("Subject: " + subject);
} else { } else {
System.out.print("Subject: "); System.out.print("Subject: ");
subject = scanner.nextLine().trim(); subject = commandLine.nextLineTrimmed();
} }
System.out.println("Message:"); System.out.println("Message:");
StringBuilder message = new StringBuilder(); StringBuilder message = new StringBuilder();
String line; String line;
do { do {
line = scanner.nextLine(); line = commandLine.nextLine();
message.append(line).append('\n'); message.append(line).append('\n');
} while (line.length() > 0 || !yesNo("Send message?")); } while (line.length() > 0 || !commandLine.yesNo("Send message?"));
if (broadcast) { if (broadcast) {
ctx.broadcast(from, subject, message.toString()); ctx.broadcast(from, subject, message.toString());
} else { } else {
ctx.send(from, to, subject, message.toString()); ctx.send(from, to, subject, message.toString());
} }
} }
private boolean yesNo(String question) {
String answer;
do {
System.out.println(question + " (y/n)");
answer = scanner.nextLine();
if ("y".equalsIgnoreCase(answer)) return true;
if ("n".equalsIgnoreCase(answer)) return false;
} while (true);
}
} }

View File

@ -0,0 +1,102 @@
/*
* Copyright 2016 Christian Basler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.dissem.bitmessage.demo;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import java.util.List;
import java.util.Scanner;
/**
* @author Christian Basler
*/
public class CommandLine {
public static final String COMMAND_BACK = "b) back";
public static final String ERROR_UNKNOWN_COMMAND = "Unknown command. Please try again.";
private Scanner scanner = new Scanner(System.in);
public String nextCommand() {
return scanner.nextLine().trim().toLowerCase();
}
public String nextLine() {
return scanner.nextLine();
}
public String nextLineTrimmed() {
return scanner.nextLine();
}
public boolean yesNo(String question) {
String answer;
do {
System.out.println(question + " (y/n)");
answer = scanner.nextLine();
if ("y".equalsIgnoreCase(answer)) return true;
if ("n".equalsIgnoreCase(answer)) return false;
} while (true);
}
public BitmessageAddress selectAddress(List<BitmessageAddress> addresses, String label) {
if (addresses.size() == 1) {
return addresses.get(0);
}
String command;
do {
System.out.println();
System.out.println(label);
listAddresses(addresses, "contacts");
System.out.println(COMMAND_BACK);
command = nextCommand();
switch (command) {
case "b":
return null;
default:
try {
int index = Integer.parseInt(command) - 1;
if (addresses.get(index) != null) {
return addresses.get(index);
}
} catch (NumberFormatException e) {
System.out.println(ERROR_UNKNOWN_COMMAND);
}
}
} while (!"b".equals(command));
return null;
}
public void listAddresses(List<BitmessageAddress> addresses, String kind) {
int i = 0;
for (BitmessageAddress address : addresses) {
i++;
System.out.print(i + ") ");
if (address.getAlias() == null) {
System.out.println(address.getAddress());
} else {
System.out.println(address.getAlias() + " (" + address.getAddress() + ")");
}
}
if (i == 0) {
System.out.println("You have no " + kind + " yet.");
}
}
}

View File

@ -17,10 +17,10 @@
package ch.dissem.bitmessage.demo; package ch.dissem.bitmessage.demo;
import ch.dissem.bitmessage.BitmessageContext; import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography;
import ch.dissem.bitmessage.networking.DefaultNetworkHandler; import ch.dissem.bitmessage.networking.DefaultNetworkHandler;
import ch.dissem.bitmessage.ports.MemoryNodeRegistry; import ch.dissem.bitmessage.ports.MemoryNodeRegistry;
import ch.dissem.bitmessage.repository.*; import ch.dissem.bitmessage.repository.*;
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography;
import ch.dissem.bitmessage.wif.WifExporter; import ch.dissem.bitmessage.wif.WifExporter;
import ch.dissem.bitmessage.wif.WifImporter; import ch.dissem.bitmessage.wif.WifImporter;
import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineException;
@ -29,6 +29,7 @@ import org.kohsuke.args4j.Option;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress;
public class Main { public class Main {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
@ -64,7 +65,8 @@ public class Main {
new WifImporter(ctx, options.importWIF).importAll(); new WifImporter(ctx, options.importWIF).importAll();
} }
} else { } else {
new Application(options.syncServer, options.syncPort); InetAddress syncServer = options.syncServer == null ? null : InetAddress.getByName(options.syncServer);
new Application(syncServer, options.syncPort);
} }
} }

View File

@ -203,7 +203,26 @@ class Connection {
private void receiveMessage(MessagePayload messagePayload) { private void receiveMessage(MessagePayload messagePayload) {
switch (messagePayload.getCommand()) { switch (messagePayload.getCommand()) {
case INV: case INV:
Inv inv = (Inv) messagePayload; receiveMessage((Inv) messagePayload);
break;
case GETDATA:
receiveMessage((GetData) messagePayload);
break;
case OBJECT:
receiveMessage((ObjectMessage) messagePayload);
break;
case ADDR:
receiveMessage((Addr) messagePayload);
break;
case CUSTOM:
case VERACK:
case VERSION:
default:
throw new IllegalStateException("Unexpectedly received '" + messagePayload.getCommand() + "' command");
}
}
private void receiveMessage(Inv inv) {
int originalSize = inv.getInventory().size(); int originalSize = inv.getInventory().size();
updateIvCache(inv.getInventory()); updateIvCache(inv.getInventory());
List<InventoryVector> missing = ctx.getInventory().getMissing(inv.getInventory(), streams); List<InventoryVector> missing = ctx.getInventory().getMissing(inv.getInventory(), streams);
@ -211,22 +230,22 @@ class Connection {
LOG.debug("Received inventory with " + originalSize + " elements, of which are " LOG.debug("Received inventory with " + originalSize + " elements, of which are "
+ missing.size() + " missing."); + missing.size() + " missing.");
send(new GetData.Builder().inventory(missing).build()); send(new GetData.Builder().inventory(missing).build());
break; }
case GETDATA:
GetData getData = (GetData) messagePayload; private void receiveMessage(GetData getData) {
for (InventoryVector iv : getData.getInventory()) { for (InventoryVector iv : getData.getInventory()) {
ObjectMessage om = ctx.getInventory().getObject(iv); ObjectMessage om = ctx.getInventory().getObject(iv);
if (om != null) sendingQueue.offer(om); if (om != null) sendingQueue.offer(om);
} }
break; }
case OBJECT:
ObjectMessage objectMessage = (ObjectMessage) messagePayload; private void receiveMessage(ObjectMessage objectMessage) {
try {
requestedObjects.remove(objectMessage.getInventoryVector()); requestedObjects.remove(objectMessage.getInventoryVector());
if (ctx.getInventory().contains(objectMessage)) { if (ctx.getInventory().contains(objectMessage)) {
LOG.trace("Received object " + objectMessage.getInventoryVector() + " - already in inventory"); LOG.trace("Received object " + objectMessage.getInventoryVector() + " - already in inventory");
break; return;
} }
try {
listener.receive(objectMessage); listener.receive(objectMessage);
security().checkProofOfWork(objectMessage, ctx.getNetworkNonceTrialsPerByte(), ctx.getNetworkExtraBytes()); security().checkProofOfWork(objectMessage, ctx.getNetworkNonceTrialsPerByte(), ctx.getNetworkExtraBytes());
ctx.getInventory().storeObject(objectMessage); ctx.getInventory().storeObject(objectMessage);
@ -243,18 +262,11 @@ class Connection {
LOG.debug("Received object that wasn't requested."); LOG.debug("Received object that wasn't requested.");
} }
} }
break; }
case ADDR:
Addr addr = (Addr) messagePayload; private void receiveMessage(Addr addr) {
LOG.debug("Received " + addr.getAddresses().size() + " addresses."); LOG.debug("Received " + addr.getAddresses().size() + " addresses.");
ctx.getNodeRegistry().offerAddresses(addr.getAddresses()); ctx.getNodeRegistry().offerAddresses(addr.getAddresses());
break;
case CUSTOM:
case VERACK:
case VERSION:
default:
throw new IllegalStateException("Unexpectedly received '" + messagePayload.getCommand() + "' command");
}
} }
private void sendAddresses() { private void sendAddresses() {
@ -358,41 +370,44 @@ class Connection {
Thread.sleep(100); Thread.sleep(100);
} }
} }
receive();
}
} catch (Exception e) {
LOG.trace("Reader disconnected from node " + node + ": " + e.getMessage());
} finally {
disconnect();
try {
socket.close();
} catch (Exception e) {
LOG.debug(e.getMessage(), e);
}
}
}
private void receive() throws InterruptedException {
try { try {
NetworkMessage msg = Factory.getNetworkMessage(version, in); NetworkMessage msg = Factory.getNetworkMessage(version, in);
if (msg == null) if (msg == null)
continue; return;
switch (state) { switch (state) {
case ACTIVE: case ACTIVE:
receiveMessage(msg.getPayload()); receiveMessage(msg.getPayload());
break; break;
default: default:
switch (msg.getPayload().getCommand()) { handleCommand(msg.getPayload());
break;
}
if (socket.isClosed() || syncFinished(msg) || checkOpenRequests()) disconnect();
} catch (SocketTimeoutException ignore) {
if (state == ACTIVE && syncFinished(null)) disconnect();
}
}
private void handleCommand(MessagePayload payload) {
switch (payload.getCommand()) {
case VERSION: case VERSION:
Version payload = (Version) msg.getPayload(); handleVersion((Version) payload);
if (payload.getNonce() == ctx.getClientNonce()) {
LOG.info("Tried to connect to self, disconnecting.");
disconnect();
} else if (payload.getVersion() >= BitmessageContext.CURRENT_VERSION) {
version = payload.getVersion();
streams = payload.getStreams();
send(new VerAck());
switch (mode) {
case SERVER:
send(new Version.Builder().defaults().addrFrom(host).addrRecv(node).build());
break;
case CLIENT:
case SYNC:
activateConnection();
break;
default:
// NO OP
}
} else {
LOG.info("Received unsupported version " + payload.getVersion() + ", disconnecting.");
disconnect();
}
break; break;
case VERACK: case VERACK:
switch (mode) { switch (mode) {
@ -407,7 +422,7 @@ class Connection {
} }
break; break;
case CUSTOM: case CUSTOM:
MessagePayload response = ctx.getCustomCommandHandler().handle((CustomMessage) msg.getPayload()); MessagePayload response = ctx.getCustomCommandHandler().handle((CustomMessage) payload);
if (response != null) { if (response != null) {
send(response); send(response);
} }
@ -415,27 +430,32 @@ class Connection {
break; break;
default: default:
throw new NodeException("Command 'version' or 'verack' expected, but was '" throw new NodeException("Command 'version' or 'verack' expected, but was '"
+ msg.getPayload().getCommand() + "'"); + payload.getCommand() + "'");
} }
} }
if (socket.isClosed() || syncFinished(msg) || checkOpenRequests()) disconnect();
} catch (SocketTimeoutException ignore) { private void handleVersion(Version version) {
if (state == ACTIVE) { if (version.getNonce() == ctx.getClientNonce()) {
if (syncFinished(null)) disconnect(); LOG.info("Tried to connect to self, disconnecting.");
}
}
}
} catch (InterruptedException | IOException | NodeException e) {
LOG.trace("Reader disconnected from node " + node + ": " + e.getMessage());
} catch (RuntimeException e) {
LOG.trace("Reader disconnecting from node " + node + " due to error: " + e.getMessage(), e);
} finally {
disconnect(); disconnect();
try { } else if (version.getVersion() >= BitmessageContext.CURRENT_VERSION) {
socket.close(); Connection.this.version = version.getVersion();
} catch (Exception e) { streams = version.getStreams();
LOG.debug(e.getMessage(), e); send(new VerAck());
switch (mode) {
case SERVER:
send(new Version.Builder().defaults().addrFrom(host).addrRecv(node).build());
break;
case CLIENT:
case SYNC:
activateConnection();
break;
default:
// NO OP
} }
} else {
LOG.info("Received unsupported version " + version.getVersion() + ", disconnecting.");
disconnect();
} }
} }
} }
@ -450,10 +470,10 @@ class Connection {
try (Socket socket = Connection.this.socket) { try (Socket socket = Connection.this.socket) {
initSocket(socket); initSocket(socket);
while (state != DISCONNECTED) { while (state != DISCONNECTED) {
if (!sendingQueue.isEmpty()) { if (sendingQueue.isEmpty()) {
send(sendingQueue.poll());
} else {
Thread.sleep(1000); Thread.sleep(1000);
} else {
send(sendingQueue.poll());
} }
} }
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {