Scanner serverdata now tries to get a non-localhost IPV4 address if possible

android-scanner
Tal Moran 2017-06-25 18:54:34 +03:00
parent 6b47387920
commit 291f7d93c0
3 changed files with 78 additions and 10 deletions

View File

@ -13,8 +13,8 @@ apply plugin: 'maven-publish'
// Uncomment the lines below to define an application
// (this will also allow you to build a "fatCapsule" which includes
// the entire application, including all dependencies in a single jar)
//apply plugin: 'application'
//mainClassName='your.main.ApplicationClass'
apply plugin: 'application'
mainClassName='meerkat.pollingstation.PollingStationToyRun'
// Is this a snapshot version?
@ -32,7 +32,7 @@ ext {
description = "Meerkat polling-station application"
// Your project version
version = "0.0"
version = "0.1"
version += "${isSnapshot ? '-SNAPSHOT' : ''}"

View File

@ -29,6 +29,7 @@ public class PollingStationToyRun {
scanner = new PollingStationWebScanner(0, CONTEXT_PATH);
PollingStation.ConnectionServerData serverData = scanner.start(true);
logger.info("Started polling station web scanner on {}", serverData.getServerUrl());
PollingStationMainController controller = new PollingStationMainController();
controller.init(scanner);

View File

@ -1,9 +1,13 @@
package meerkat.pollingstation;
import java.io.IOException;
import java.net.*;
import java.nio.channels.ServerSocketChannel;
import java.security.InvalidKeyException;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.util.Enumeration;
import java.util.List;
import java.util.LinkedList;
@ -13,6 +17,7 @@ import meerkat.crypto.DigitalSignature;
import meerkat.crypto.concrete.ECDSASignature;
import meerkat.protobuf.Crypto;
import meerkat.protobuf.PollingStation;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.*;
@ -38,6 +43,12 @@ public class PollingStationWebScanner implements PollingStationScanner.PollingSt
*/
long expectedSerial;
/**
* Context path for servlet
*/
String contextPath;
/**
* Should a newly-connected scanner be verified using the nonce?
@ -108,6 +119,7 @@ public class PollingStationWebScanner implements PollingStationScanner.PollingSt
return false;
}
expectedSerial = 0;
return true;
}
@ -116,7 +128,7 @@ public class PollingStationWebScanner implements PollingStationScanner.PollingSt
if (verifySignatures) {
ByteString scannerID = scannedData.getScannerId();
if (!scannerID.equals(connectedScannerID)) {
logger.warn("Scanner ID doesn't match connection public key");
logger.error("Scanner ID doesn't match connection public key");
return false;
}
@ -124,22 +136,28 @@ public class PollingStationWebScanner implements PollingStationScanner.PollingSt
verifier.initVerify(data.getScannerSig());
verifier.updateContent(scannedData);
if (!verifier.verify()) {
logger.warn("Bad Signature");
logger.error("Bad Signature");
return false;
}
} catch (CertificateException e) {
logger.warn("Certificate Exception: {}", e);
logger.error("Certificate Exception: {}", e);
return false;
} catch (InvalidKeyException e) {
logger.warn("InvalidKey Exception: {}", e);
logger.error("InvalidKey Exception: {}", e);
return false;
} catch (SignatureException e) {
logger.warn("Signature Exception: {}", e);
logger.error("Signature Exception: {}", e);
return false;
}
}
if (scannedData.getSerial() != expectedSerial) {
logger.warn("Got scan with serial {}, expecting {}", scannedData.getSerial(), expectedSerial);
}
expectedSerial = scannedData.getSerial() + 1;
for (FutureCallback<ScannedData> callback : callbacks) {
callback.onSuccess(scannedData);
}
@ -153,7 +171,7 @@ public class PollingStationWebScanner implements PollingStationScanner.PollingSt
public PollingStationWebScanner(int port, String contextPath) {
this.contextPath = contextPath;
scanRequestHandler = new ScanRequestHandler();
callbacks = new LinkedList<>();
verifier = new ECDSASignature();
@ -173,15 +191,64 @@ public class PollingStationWebScanner implements PollingStationScanner.PollingSt
}
String getServerURL(Server server) {
String serverURL = server.getURI().toASCIIString();
try {
Connector connector = server.getConnectors()[0];
Object transport = connector.getTransport();
if (transport instanceof ServerSocketChannel) {
// We can get better info about the local endpoint
ServerSocketChannel sock = (ServerSocketChannel) transport;
SocketAddress localAddr = null;
localAddr = sock.getLocalAddress();
if (localAddr instanceof InetSocketAddress) {
InetSocketAddress localInet = (InetSocketAddress) localAddr;
InetAddress hostAddr = localInet.getAddress();
if (hostAddr.isAnyLocalAddress()) {
Enumeration<NetworkInterface> n = null;
n = NetworkInterface.getNetworkInterfaces();
while (n.hasMoreElements()) {
NetworkInterface e = n.nextElement();
if (e.isLoopback() || e.isPointToPoint() || !e.isUp())
continue;
Enumeration<InetAddress> aList = e.getInetAddresses();
while (aList.hasMoreElements()) {
InetAddress a = aList.nextElement();
if (a instanceof Inet4Address) {
serverURL = "http://" + a.getHostAddress() + ":" + localInet.getPort()
+ contextPath;
}
}
}
}
}
}
} catch (SocketException e) {
// Ignore
} catch (IOException e) {
// Ignore
}
return serverURL;
}
@Override
public PollingStation.ConnectionServerData start(boolean verifyScanner) throws Exception {
this.verifyNonce = this.verifySignatures = verifyScanner;
nonce = new SecureRandom().nextLong();
server.start();
return PollingStation.ConnectionServerData.newBuilder()
.setNonce(nonce)
.setServerUrl(server.getURI().toString())
.setServerUrl(getServerURL(server))
.build();
}