mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 12:49:55 +01:00
Compare commits
2 Commits
2165-windo
...
bluecove-f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3e1c62aff | ||
|
|
1020c70c22 |
@@ -105,46 +105,43 @@ import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
|||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||||
|
|
||||||
static final Logger LOG = getLogger(TorPlugin.class.getName());
|
private static final Logger LOG = getLogger(TorPlugin.class.getName());
|
||||||
|
|
||||||
static final String[] EVENTS = {
|
private static final String[] EVENTS = {
|
||||||
"CIRC", "ORCONN", "HS_DESC", "NOTICE", "WARN", "ERR"
|
"CIRC", "ORCONN", "HS_DESC", "NOTICE", "WARN", "ERR"
|
||||||
};
|
};
|
||||||
static final String OWNER = "__OwningControllerProcess";
|
private static final String OWNER = "__OwningControllerProcess";
|
||||||
static final int COOKIE_TIMEOUT_MS = 3000;
|
private static final int COOKIE_TIMEOUT_MS = 3000;
|
||||||
static final int COOKIE_POLLING_INTERVAL_MS = 200;
|
private static final int COOKIE_POLLING_INTERVAL_MS = 200;
|
||||||
private static final Pattern ONION_V3 = Pattern.compile("[a-z2-7]{56}");
|
private static final Pattern ONION_V3 = Pattern.compile("[a-z2-7]{56}");
|
||||||
|
|
||||||
private final Executor ioExecutor, wakefulIoExecutor;
|
private final Executor ioExecutor, wakefulIoExecutor;
|
||||||
private final Executor connectionStatusExecutor;
|
private final Executor connectionStatusExecutor;
|
||||||
final NetworkManager networkManager;
|
private final NetworkManager networkManager;
|
||||||
private final LocationUtils locationUtils;
|
private final LocationUtils locationUtils;
|
||||||
private final SocketFactory torSocketFactory;
|
private final SocketFactory torSocketFactory;
|
||||||
final Clock clock;
|
private final Clock clock;
|
||||||
final BatteryManager batteryManager;
|
private final BatteryManager batteryManager;
|
||||||
private final Backoff backoff;
|
private final Backoff backoff;
|
||||||
private final TorRendezvousCrypto torRendezvousCrypto;
|
private final TorRendezvousCrypto torRendezvousCrypto;
|
||||||
final PluginCallback callback;
|
private final PluginCallback callback;
|
||||||
private final String architecture;
|
private final String architecture;
|
||||||
private final CircumventionProvider circumventionProvider;
|
private final CircumventionProvider circumventionProvider;
|
||||||
private final ResourceProvider resourceProvider;
|
private final ResourceProvider resourceProvider;
|
||||||
private final long maxLatency;
|
private final long maxLatency;
|
||||||
private final int maxIdleTime;
|
private final int maxIdleTime;
|
||||||
private final int socketTimeout;
|
private final int socketTimeout;
|
||||||
final File torDirectory;
|
private final File torDirectory, geoIpFile, configFile;
|
||||||
final File geoIpFile;
|
private final int torSocksPort;
|
||||||
final File configFile;
|
private final int torControlPort;
|
||||||
final int torSocksPort;
|
private final File doneFile, cookieFile;
|
||||||
final int torControlPort;
|
private final AtomicBoolean used = new AtomicBoolean(false);
|
||||||
private final File doneFile;
|
|
||||||
final File cookieFile;
|
|
||||||
final AtomicBoolean used = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
protected final PluginState state = new PluginState();
|
protected final PluginState state = new PluginState();
|
||||||
|
|
||||||
volatile Socket controlSocket = null;
|
private volatile Socket controlSocket = null;
|
||||||
volatile TorControlConnection controlConnection = null;
|
private volatile TorControlConnection controlConnection = null;
|
||||||
volatile Settings settings = null;
|
private volatile Settings settings = null;
|
||||||
|
|
||||||
protected abstract int getProcessId();
|
protected abstract int getProcessId();
|
||||||
|
|
||||||
@@ -245,7 +242,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
Process torProcess;
|
Process torProcess;
|
||||||
ProcessBuilder pb =
|
ProcessBuilder pb =
|
||||||
new ProcessBuilder(torPath, "-f", configPath, OWNER, pid);
|
new ProcessBuilder(torPath, "-f", configPath, OWNER, pid);
|
||||||
// TODO: pb.redirectErrorStream on Linux, too?
|
|
||||||
Map<String, String> env = pb.environment();
|
Map<String, String> env = pb.environment();
|
||||||
env.put("HOME", torDirectory.getAbsolutePath());
|
env.put("HOME", torDirectory.getAbsolutePath());
|
||||||
pb.directory(torDirectory);
|
pb.directory(torDirectory);
|
||||||
@@ -322,9 +318,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
bind();
|
bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: Remove after a reasonable migration period (added 2020-06-25)
|
// TODO: Remove after a reasonable migration period (added 2020-06-25)
|
||||||
Settings migrateSettings(Settings settings) {
|
private Settings migrateSettings(Settings settings) {
|
||||||
int network = settings.getInt(PREF_TOR_NETWORK,
|
int network = settings.getInt(PREF_TOR_NETWORK,
|
||||||
DEFAULT_PREF_TOR_NETWORK);
|
DEFAULT_PREF_TOR_NETWORK);
|
||||||
if (network == PREF_TOR_NETWORK_NEVER) {
|
if (network == PREF_TOR_NETWORK_NEVER) {
|
||||||
@@ -335,11 +330,11 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean assetsAreUpToDate() {
|
private boolean assetsAreUpToDate() {
|
||||||
return doneFile.lastModified() > getLastUpdateTime();
|
return doneFile.lastModified() > getLastUpdateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void installAssets() throws PluginException {
|
private void installAssets() throws PluginException {
|
||||||
try {
|
try {
|
||||||
// The done file may already exist from a previous installation
|
// The done file may already exist from a previous installation
|
||||||
//noinspection ResultOfMethodCallIgnored
|
//noinspection ResultOfMethodCallIgnored
|
||||||
@@ -394,20 +389,20 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
|
|
||||||
private InputStream getObfs4InputStream() throws IOException {
|
private InputStream getObfs4InputStream() throws IOException {
|
||||||
InputStream in = resourceProvider
|
InputStream in = resourceProvider
|
||||||
.getResourceInputStream("obfs4proxy_" + "linux-x86_64", ".zip");
|
.getResourceInputStream("obfs4proxy_" + architecture, ".zip");
|
||||||
ZipInputStream zin = new ZipInputStream(in);
|
ZipInputStream zin = new ZipInputStream(in);
|
||||||
if (zin.getNextEntry() == null) throw new IOException();
|
if (zin.getNextEntry() == null) throw new IOException();
|
||||||
return zin;
|
return zin;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void append(StringBuilder strb, String name, int value) {
|
private static void append(StringBuilder strb, String name, int value) {
|
||||||
strb.append(name);
|
strb.append(name);
|
||||||
strb.append(" ");
|
strb.append(" ");
|
||||||
strb.append(value);
|
strb.append(value);
|
||||||
strb.append("\n");
|
strb.append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InputStream getConfigInputStream() {
|
private InputStream getConfigInputStream() {
|
||||||
StringBuilder strb = new StringBuilder();
|
StringBuilder strb = new StringBuilder();
|
||||||
append(strb, "ControlPort", torControlPort);
|
append(strb, "ControlPort", torControlPort);
|
||||||
append(strb, "CookieAuthentication", 1);
|
append(strb, "CookieAuthentication", 1);
|
||||||
@@ -420,7 +415,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
strb.toString().getBytes(Charset.forName("UTF-8")));
|
strb.toString().getBytes(Charset.forName("UTF-8")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void listFiles(File f) {
|
private void listFiles(File f) {
|
||||||
if (f.isDirectory()) {
|
if (f.isDirectory()) {
|
||||||
File[] children = f.listFiles();
|
File[] children = f.listFiles();
|
||||||
if (children != null) for (File child : children) listFiles(child);
|
if (children != null) for (File child : children) listFiles(child);
|
||||||
@@ -429,7 +424,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] read(File f) throws IOException {
|
private byte[] read(File f) throws IOException {
|
||||||
byte[] b = new byte[(int) f.length()];
|
byte[] b = new byte[(int) f.length()];
|
||||||
FileInputStream in = new FileInputStream(f);
|
FileInputStream in = new FileInputStream(f);
|
||||||
try {
|
try {
|
||||||
@@ -445,7 +440,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind() {
|
private void bind() {
|
||||||
ioExecutor.execute(() -> {
|
ioExecutor.execute(() -> {
|
||||||
// If there's already a port number stored in config, reuse it
|
// If there's already a port number stored in config, reuse it
|
||||||
String portString = settings.get(PREF_TOR_PORT);
|
String portString = settings.get(PREF_TOR_PORT);
|
||||||
@@ -819,8 +814,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateConnectionStatus(NetworkStatus status,
|
private void updateConnectionStatus(NetworkStatus status,
|
||||||
boolean charging) {
|
boolean charging) {
|
||||||
connectionStatusExecutor.execute(() -> {
|
connectionStatusExecutor.execute(() -> {
|
||||||
if (!state.isTorRunning()) return;
|
if (!state.isTorRunning()) return;
|
||||||
boolean online = status.isConnected();
|
boolean online = status.isConnected();
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
package org.briarproject.bramble.system;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.security.Provider;
|
|
||||||
|
|
||||||
public class WindowsSecureRandomProvider extends AbstractSecureRandomProvider {
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Provider getProvider() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,7 +17,10 @@ dependencies {
|
|||||||
def jna_version = '4.5.2'
|
def jna_version = '4.5.2'
|
||||||
implementation "net.java.dev.jna:jna:$jna_version"
|
implementation "net.java.dev.jna:jna:$jna_version"
|
||||||
implementation "net.java.dev.jna:jna-platform:$jna_version"
|
implementation "net.java.dev.jna:jna-platform:$jna_version"
|
||||||
tor fileTree(dir: 'libs', include: '*.zip')
|
def bluecove_version = '2.1.0'
|
||||||
|
implementation "net.sf.bluecove:bluecove:$bluecove_version"
|
||||||
|
implementation "net.sf.bluecove:bluecove-gpl:$bluecove_version"
|
||||||
|
tor "org.briarproject:tor:$tor_version"
|
||||||
tor "org.briarproject:obfs4proxy:$obfs4proxy_version@zip"
|
tor "org.briarproject:obfs4proxy:$obfs4proxy_version@zip"
|
||||||
|
|
||||||
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -21,7 +21,9 @@ import javax.microedition.io.StreamConnectionNotifier;
|
|||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
||||||
import static org.briarproject.bramble.util.StringUtils.isValidMac;
|
import static org.briarproject.bramble.util.StringUtils.isValidMac;
|
||||||
|
import static org.briarproject.bramble.util.StringUtils.macToString;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -65,12 +67,13 @@ class JavaBluetoothPlugin extends
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
String getBluetoothAddress() {
|
String getBluetoothAddress() {
|
||||||
return localDevice.getBluetoothAddress();
|
if (localDevice == null) return null;
|
||||||
|
return macToString(fromHexString(localDevice.getBluetoothAddress()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
StreamConnectionNotifier openServerSocket(String uuid) throws IOException {
|
StreamConnectionNotifier openServerSocket(String uuid) throws IOException {
|
||||||
String url = makeUrl("localhost", uuid);
|
String url = makeServerSocketUrl(uuid);
|
||||||
return (StreamConnectionNotifier) Connector.open(url);
|
return (StreamConnectionNotifier) Connector.open(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,9 +100,7 @@ class JavaBluetoothPlugin extends
|
|||||||
@Override
|
@Override
|
||||||
DuplexTransportConnection connectTo(String address, String uuid)
|
DuplexTransportConnection connectTo(String address, String uuid)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
String url = makeUrl(address, uuid);
|
throw new IOException("Not implemented"); // TODO
|
||||||
StreamConnection s = (StreamConnection) Connector.open(url);
|
|
||||||
return connectionFactory.wrapSocket(this, s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -113,7 +114,9 @@ class JavaBluetoothPlugin extends
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
private String makeUrl(String address, String uuid) {
|
private String makeServerSocketUrl(String uuid) {
|
||||||
return "btspp://" + address + ":" + uuid + ";name=RFCOMM";
|
uuid = uuid.replaceAll("-", "");
|
||||||
|
return "btspp://" + "localhost" + ":" + uuid
|
||||||
|
+ ";encrypt=false;authenticate=false";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,14 +32,13 @@ import javax.net.SocketFactory;
|
|||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.util.OsUtils.isLinux;
|
import static org.briarproject.bramble.util.OsUtils.isLinux;
|
||||||
import static org.briarproject.bramble.util.OsUtils.isWindows;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class DesktopTorPluginFactory implements DuplexPluginFactory {
|
public class UnixTorPluginFactory implements DuplexPluginFactory {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(DesktopTorPluginFactory.class.getName());
|
getLogger(UnixTorPluginFactory.class.getName());
|
||||||
|
|
||||||
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds
|
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds
|
||||||
private static final int MAX_IDLE_TIME = 30 * 1000; // 30 seconds
|
private static final int MAX_IDLE_TIME = 30 * 1000; // 30 seconds
|
||||||
@@ -63,7 +62,7 @@ public class DesktopTorPluginFactory implements DuplexPluginFactory {
|
|||||||
private final CryptoComponent crypto;
|
private final CryptoComponent crypto;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DesktopTorPluginFactory(@IoExecutor Executor ioExecutor,
|
UnixTorPluginFactory(@IoExecutor Executor ioExecutor,
|
||||||
@WakefulIoExecutor Executor wakefulIoExecutor,
|
@WakefulIoExecutor Executor wakefulIoExecutor,
|
||||||
NetworkManager networkManager,
|
NetworkManager networkManager,
|
||||||
LocationUtils locationUtils,
|
LocationUtils locationUtils,
|
||||||
@@ -108,33 +107,25 @@ public class DesktopTorPluginFactory implements DuplexPluginFactory {
|
|||||||
@Override
|
@Override
|
||||||
public DuplexPlugin createPlugin(PluginCallback callback) {
|
public DuplexPlugin createPlugin(PluginCallback callback) {
|
||||||
// Check that we have a Tor binary for this architecture
|
// Check that we have a Tor binary for this architecture
|
||||||
|
String architecture = null;
|
||||||
if (isLinux()) {
|
if (isLinux()) {
|
||||||
String arch = System.getProperty("os.arch");
|
String arch = System.getProperty("os.arch");
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("System's os.arch is " + arch);
|
LOG.info("System's os.arch is " + arch);
|
||||||
}
|
}
|
||||||
if (arch.equals("amd64")) {
|
if (arch.equals("amd64")) {
|
||||||
return createUnixPlugin(callback, "linux-x86_64");
|
architecture = "linux-x86_64";
|
||||||
} else if (arch.equals("aarch64")) {
|
} else if (arch.equals("aarch64")) {
|
||||||
return createUnixPlugin(callback, "linux-aarch64");
|
architecture = "linux-aarch64";
|
||||||
} else if (arch.equals("arm")) {
|
} else if (arch.equals("arm")) {
|
||||||
return createUnixPlugin(callback, "linux-armhf");
|
architecture = "linux-armhf";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isWindows()) {
|
if (architecture == null) {
|
||||||
String arch = System.getProperty("os.arch");
|
LOG.info("Tor is not supported on this architecture");
|
||||||
if (LOG.isLoggable(INFO)) {
|
return null;
|
||||||
LOG.info("System's os.arch is " + arch);
|
|
||||||
}
|
|
||||||
if (arch.equals("amd64")) {
|
|
||||||
return createWindowsPlugin(callback, "windows-x86_64");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
LOG.info("Tor is not supported on this architecture");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DuplexPlugin createUnixPlugin(PluginCallback callback, String architecture) {
|
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("The selected architecture for Tor is " + architecture);
|
LOG.info("The selected architecture for Tor is " + architecture);
|
||||||
}
|
}
|
||||||
@@ -152,21 +143,4 @@ public class DesktopTorPluginFactory implements DuplexPluginFactory {
|
|||||||
eventBus.addListener(plugin);
|
eventBus.addListener(plugin);
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DuplexPlugin createWindowsPlugin(PluginCallback callback, String architecture) {
|
|
||||||
if (LOG.isLoggable(INFO)) {
|
|
||||||
LOG.info("The selected architecture for Tor is " + architecture);
|
|
||||||
}
|
|
||||||
|
|
||||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
|
||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
|
||||||
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
|
|
||||||
WindowsTorPlugin plugin = new WindowsTorPlugin(ioExecutor, wakefulIoExecutor,
|
|
||||||
networkManager, locationUtils, torSocketFactory, clock,
|
|
||||||
resourceProvider, circumventionProvider, batteryManager,
|
|
||||||
backoff, torRendezvousCrypto, callback, architecture,
|
|
||||||
MAX_LATENCY, MAX_IDLE_TIME, torDirectory, torSocksPort, torControlPort);
|
|
||||||
eventBus.addListener(plugin);
|
|
||||||
return plugin;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,217 +0,0 @@
|
|||||||
package org.briarproject.bramble.plugin.tor;
|
|
||||||
|
|
||||||
import com.sun.jna.Library;
|
|
||||||
import com.sun.jna.Native;
|
|
||||||
|
|
||||||
import net.freehaven.tor.control.TorControlConnection;
|
|
||||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
|
||||||
import org.briarproject.bramble.api.plugin.PluginException;
|
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
|
||||||
import org.briarproject.bramble.api.system.LocationUtils;
|
|
||||||
import org.briarproject.bramble.api.system.ResourceProvider;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.net.SocketFactory;
|
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static java.util.Collections.singletonList;
|
|
||||||
import static java.util.logging.Level.INFO;
|
|
||||||
import static java.util.logging.Level.WARNING;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
|
||||||
class WindowsTorPlugin extends JavaTorPlugin {
|
|
||||||
|
|
||||||
WindowsTorPlugin(Executor ioExecutor,
|
|
||||||
Executor wakefulIoExecutor,
|
|
||||||
NetworkManager networkManager,
|
|
||||||
LocationUtils locationUtils,
|
|
||||||
SocketFactory torSocketFactory,
|
|
||||||
Clock clock,
|
|
||||||
ResourceProvider resourceProvider,
|
|
||||||
CircumventionProvider circumventionProvider,
|
|
||||||
BatteryManager batteryManager,
|
|
||||||
Backoff backoff,
|
|
||||||
TorRendezvousCrypto torRendezvousCrypto,
|
|
||||||
PluginCallback callback,
|
|
||||||
String architecture,
|
|
||||||
long maxLatency,
|
|
||||||
int maxIdleTime,
|
|
||||||
File torDirectory,
|
|
||||||
int torSocksPort,
|
|
||||||
int torControlPort) {
|
|
||||||
super(ioExecutor, wakefulIoExecutor, networkManager, locationUtils,
|
|
||||||
torSocketFactory, clock, resourceProvider,
|
|
||||||
circumventionProvider, batteryManager, backoff,
|
|
||||||
torRendezvousCrypto, callback, architecture,
|
|
||||||
maxLatency, maxIdleTime, torDirectory, torSocksPort, torControlPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected File getTorExecutableFile() {
|
|
||||||
return new File(torDirectory, "tor.exe");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected InputStream getConfigInputStream() {
|
|
||||||
StringBuilder strb = new StringBuilder();
|
|
||||||
append(strb, "ControlPort", torControlPort);
|
|
||||||
append(strb, "CookieAuthentication", 1);
|
|
||||||
append(strb, "DisableNetwork", 1);
|
|
||||||
append(strb, "RunAsDaemon", 1);
|
|
||||||
append(strb, "SafeSocks", 1);
|
|
||||||
append(strb, "SocksPort", torSocksPort);
|
|
||||||
InputStream inputStream = new ByteArrayInputStream(
|
|
||||||
strb.toString().getBytes(Charset.forName("UTF-8")));
|
|
||||||
InputStream windowsPaths = new ByteArrayInputStream(getTorrcPaths());
|
|
||||||
inputStream = new SequenceInputStream(inputStream, windowsPaths);
|
|
||||||
return inputStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] getTorrcPaths() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("\n");
|
|
||||||
sb.append("GeoIPFile ");
|
|
||||||
sb.append(geoIpFile.getAbsolutePath());
|
|
||||||
sb.append("\n");
|
|
||||||
sb.append("GeoIPv6File ");
|
|
||||||
sb.append(geoIpFile.getAbsolutePath());
|
|
||||||
sb.append("6");
|
|
||||||
sb.append("\n");
|
|
||||||
sb.append("DataDirectory ");
|
|
||||||
sb.append(torDirectory);
|
|
||||||
sb.append("\\.tor");
|
|
||||||
return sb.toString().getBytes(StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start() throws PluginException {
|
|
||||||
/*
|
|
||||||
TODO:
|
|
||||||
- properly handle and throw PluginExceptions etc.
|
|
||||||
- absolute paths in Windows torrc (Linux too?)
|
|
||||||
- don't do 10 seconds sleep in main thread
|
|
||||||
*/
|
|
||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
|
||||||
if (!torDirectory.exists()) {
|
|
||||||
if (!torDirectory.mkdirs()) {
|
|
||||||
LOG.warning("Could not create Tor directory.");
|
|
||||||
throw new PluginException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Load the settings
|
|
||||||
settings = migrateSettings(callback.getSettings());
|
|
||||||
// Install or update the assets if necessary
|
|
||||||
if (!assetsAreUpToDate()) installAssets();
|
|
||||||
if (cookieFile.exists() && !cookieFile.delete())
|
|
||||||
LOG.warning("Old auth cookie not deleted");
|
|
||||||
// Start a new Tor process
|
|
||||||
LOG.info("Starting Tor");
|
|
||||||
File torFile = getTorExecutableFile();
|
|
||||||
String torPath = torFile.getAbsolutePath();
|
|
||||||
String configPath = configFile.getAbsolutePath();
|
|
||||||
String pid = String.valueOf(getProcessId());
|
|
||||||
Executors.newSingleThreadExecutor().execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Process torProcess;
|
|
||||||
ProcessBuilder pb =
|
|
||||||
new ProcessBuilder(torPath, "-f", configPath, OWNER, pid);
|
|
||||||
pb.redirectErrorStream(true); // logged only first line on Windows otherwise
|
|
||||||
Map<String, String> env = pb.environment();
|
|
||||||
env.put("HOME", torDirectory.getAbsolutePath());
|
|
||||||
pb.directory(torDirectory);
|
|
||||||
try {
|
|
||||||
torProcess = pb.start();
|
|
||||||
// Log the process's standard output until it detaches
|
|
||||||
if (LOG.isLoggable(INFO)) {
|
|
||||||
Scanner stdout = new Scanner(torProcess.getInputStream());
|
|
||||||
while (stdout.hasNextLine()) {
|
|
||||||
if (stdout.hasNextLine()) {
|
|
||||||
LOG.info(stdout.nextLine());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stdout.close();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// Wait for the process to detach or exit
|
|
||||||
int exit = torProcess.waitFor();
|
|
||||||
if (exit != 0) {
|
|
||||||
if (LOG.isLoggable(WARNING))
|
|
||||||
LOG.warning("Tor exited with value " + exit);
|
|
||||||
}
|
|
||||||
// Wait for the auth cookie file to be created/updated
|
|
||||||
long start = clock.currentTimeMillis();
|
|
||||||
while (cookieFile.length() < 32) {
|
|
||||||
if (clock.currentTimeMillis() - start > COOKIE_TIMEOUT_MS) {
|
|
||||||
LOG.warning("Auth cookie not created");
|
|
||||||
if (LOG.isLoggable(INFO)) listFiles(torDirectory);
|
|
||||||
}
|
|
||||||
Thread.sleep(COOKIE_POLLING_INTERVAL_MS);
|
|
||||||
}
|
|
||||||
LOG.info("Auth cookie created");
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
LOG.warning("Interrupted while starting Tor");
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} catch (SecurityException | IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
try {
|
|
||||||
TimeUnit.SECONDS.sleep(10);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// Open a control connection and authenticate using the cookie file
|
|
||||||
controlSocket = new Socket("127.0.0.1", torControlPort);
|
|
||||||
controlConnection = new TorControlConnection(controlSocket);
|
|
||||||
controlConnection.authenticate(read(cookieFile));
|
|
||||||
// Tell Tor to exit when the control connection is closed
|
|
||||||
controlConnection.takeOwnership();
|
|
||||||
controlConnection.resetConf(singletonList(OWNER));
|
|
||||||
// Register to receive events from the Tor process
|
|
||||||
controlConnection.setEventHandler(this);
|
|
||||||
controlConnection.setEvents(asList(EVENTS));
|
|
||||||
// Check whether Tor has already bootstrapped
|
|
||||||
String phase = controlConnection.getInfo("status/bootstrap-phase");
|
|
||||||
if (phase != null && phase.contains("PROGRESS=100")) {
|
|
||||||
LOG.info("Tor has already bootstrapped");
|
|
||||||
state.setBootstrapped();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new PluginException(e);
|
|
||||||
}
|
|
||||||
state.setStarted();
|
|
||||||
// Check whether we're online
|
|
||||||
updateConnectionStatus(networkManager.getNetworkStatus(),
|
|
||||||
batteryManager.isCharging());
|
|
||||||
// Bind a server socket to receive incoming hidden service connections
|
|
||||||
bind();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getProcessId() {
|
|
||||||
return CLibrary.INSTANCE._getpid();
|
|
||||||
}
|
|
||||||
|
|
||||||
private interface CLibrary extends Library {
|
|
||||||
|
|
||||||
CLibrary INSTANCE = Native.loadLibrary("msvcrt", CLibrary.class);
|
|
||||||
|
|
||||||
int _getpid();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,6 @@ import dagger.Provides;
|
|||||||
|
|
||||||
import static org.briarproject.bramble.util.OsUtils.isLinux;
|
import static org.briarproject.bramble.util.OsUtils.isLinux;
|
||||||
import static org.briarproject.bramble.util.OsUtils.isMac;
|
import static org.briarproject.bramble.util.OsUtils.isMac;
|
||||||
import static org.briarproject.bramble.util.OsUtils.isWindows;
|
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
public class DesktopSecureRandomModule {
|
public class DesktopSecureRandomModule {
|
||||||
@@ -19,8 +18,7 @@ public class DesktopSecureRandomModule {
|
|||||||
SecureRandomProvider provideSecureRandomProvider() {
|
SecureRandomProvider provideSecureRandomProvider() {
|
||||||
if (isLinux() || isMac())
|
if (isLinux() || isMac())
|
||||||
return new UnixSecureRandomProvider();
|
return new UnixSecureRandomProvider();
|
||||||
if (isWindows())
|
// TODO: Create a secure random provider for Windows
|
||||||
return new WindowsSecureRandomProvider();
|
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ public class BridgeTest extends BrambleTestCase {
|
|||||||
private final File torDir = getTestDirectory();
|
private final File torDir = getTestDirectory();
|
||||||
private final Params params;
|
private final Params params;
|
||||||
|
|
||||||
private DesktopTorPluginFactory factory;
|
private UnixTorPluginFactory factory;
|
||||||
|
|
||||||
public BridgeTest(Params params) {
|
public BridgeTest(Params params) {
|
||||||
this.params = params;
|
this.params = params;
|
||||||
@@ -152,7 +152,7 @@ public class BridgeTest extends BrambleTestCase {
|
|||||||
return singletonList(params.bridge);
|
return singletonList(params.bridge);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
factory = new DesktopTorPluginFactory(ioExecutor, wakefulIoExecutor,
|
factory = new UnixTorPluginFactory(ioExecutor, wakefulIoExecutor,
|
||||||
networkManager, locationUtils, eventBus, torSocketFactory,
|
networkManager, locationUtils, eventBus, torSocketFactory,
|
||||||
backoffFactory, resourceProvider, bridgeProvider,
|
backoffFactory, resourceProvider, bridgeProvider,
|
||||||
batteryManager, clock, torDir, DEFAULT_SOCKS_PORT,
|
batteryManager, clock, torDir, DEFAULT_SOCKS_PORT,
|
||||||
|
|||||||
@@ -23,8 +23,11 @@ dependencyVerification {
|
|||||||
'net.java.dev.jna:jna:4.5.2:jna-4.5.2.jar:0c8eb7acf67261656d79005191debaba3b6bf5dd60a43735a245429381dbecff',
|
'net.java.dev.jna:jna:4.5.2:jna-4.5.2.jar:0c8eb7acf67261656d79005191debaba3b6bf5dd60a43735a245429381dbecff',
|
||||||
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
||||||
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
||||||
|
'net.sf.bluecove:bluecove-gpl:2.1.0:bluecove-gpl-2.1.0.jar:6b697a3d4d50be16b86cdfad6aac173251f1fd0dce83f4947d1ed7b2aea894d0',
|
||||||
|
'net.sf.bluecove:bluecove:2.1.0:bluecove-2.1.0.jar:add9a58dbee3eaa35a062010a11066ba772a72119f24165f4adf0e19e60a4b8a',
|
||||||
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
|
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
|
||||||
'org.briarproject:obfs4proxy:0.0.12-dev-40245c4a:obfs4proxy-0.0.12-dev-40245c4a.zip:172029e7058b3a83ac93ac4991a44bf76e16ce8d46f558f5836d57da3cb3a766',
|
'org.briarproject:obfs4proxy:0.0.12-dev-40245c4a:obfs4proxy-0.0.12-dev-40245c4a.zip:172029e7058b3a83ac93ac4991a44bf76e16ce8d46f558f5836d57da3cb3a766',
|
||||||
|
'org.briarproject:tor:0.3.5.17:tor-0.3.5.17.jar:ce0e1f4d8f14878e61b23a35a452bc0f2a8e3117ced5a74773cd78475fa7af39',
|
||||||
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
||||||
'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a',
|
'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a',
|
||||||
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
|
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
diff -Bbur bluecove-2.1.1-SNAPSHOT/bluecove/pom.xml bluecove-2.1.1-SNAPSHOT-briar/bluecove/pom.xml
|
|
||||||
--- bluecove-2.1.1-SNAPSHOT/bluecove/pom.xml 2013-01-04 00:43:17.961294408 +0000
|
|
||||||
+++ bluecove-2.1.1-SNAPSHOT-briar/bluecove/pom.xml 2013-01-03 23:17:37.549293571 +0000
|
|
||||||
@@ -126,8 +126,8 @@
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
- <source>1.3</source>
|
|
||||||
- <target>1.1</target>
|
|
||||||
+ <source>1.5</source>
|
|
||||||
+ <target>1.5</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
@@ -355,7 +355,7 @@
|
|
||||||
<configuration>
|
|
||||||
<linkXref>true</linkXref>
|
|
||||||
<minimumTokens>100</minimumTokens>
|
|
||||||
- <targetJdk>1.4</targetJdk>
|
|
||||||
+ <targetJdk>1.5</targetJdk>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
diff -Bbur bluecove-2.1.1-SNAPSHOT/bluecove/src/main/c/intelbth/OSXStackRFCOMMServer.mm bluecove-2.1.1-SNAPSHOT-briar/bluecove/src/main/c/intelbth/OSXStackRFCOMMServer.mm
|
|
||||||
--- bluecove-2.1.1-SNAPSHOT/bluecove/src/main/c/intelbth/OSXStackRFCOMMServer.mm 2013-01-04 00:43:17.549293781 +0000
|
|
||||||
+++ bluecove-2.1.1-SNAPSHOT-briar/bluecove/src/main/c/intelbth/OSXStackRFCOMMServer.mm 2013-01-03 23:19:02.269295705 +0000
|
|
||||||
@@ -280,6 +280,10 @@
|
|
||||||
ndebug(("fail to get IOBluetoothRFCOMMChannel"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
+ if(![rfcommChannel isIncoming]) {
|
|
||||||
+ ndebug(("ignoring outgoing connection"));
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
if (comm->authenticate) {
|
|
||||||
IOBluetoothDevice* device = [rfcommChannel getDevice];
|
|
||||||
if (device == NULL) {
|
|
||||||
diff -Bbur bluecove-2.1.1-SNAPSHOT/bluecove-gpl/pom.xml bluecove-2.1.1-SNAPSHOT-briar/bluecove-gpl/pom.xml
|
|
||||||
--- bluecove-2.1.1-SNAPSHOT/bluecove-gpl/pom.xml 2013-01-04 00:43:14.509294005 +0000
|
|
||||||
+++ bluecove-2.1.1-SNAPSHOT-briar/bluecove-gpl/pom.xml 2013-01-03 23:17:52.181293751 +0000
|
|
||||||
@@ -81,8 +81,8 @@
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
- <source>1.3</source>
|
|
||||||
- <target>1.1</target>
|
|
||||||
+ <source>1.5</source>
|
|
||||||
+ <target>1.5</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
diff -Bbur bluecove-2.1.1-SNAPSHOT/pom.xml bluecove-2.1.1-SNAPSHOT-briar/pom.xml
|
|
||||||
--- bluecove-2.1.1-SNAPSHOT/pom.xml 2013-01-04 00:43:19.721293788 +0000
|
|
||||||
+++ bluecove-2.1.1-SNAPSHOT-briar/pom.xml 2013-01-03 23:17:18.713293930 +0000
|
|
||||||
@@ -436,7 +436,7 @@
|
|
||||||
<configuration>
|
|
||||||
<linkXref>true</linkXref>
|
|
||||||
<minimumTokens>100</minimumTokens>
|
|
||||||
- <targetJdk>1.4</targetJdk>
|
|
||||||
+ <targetJdk>1.5</targetJdk>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
Reference in New Issue
Block a user