Move Tor wrapper to library.

This commit is contained in:
akwizgran
2023-03-28 15:39:47 +01:00
parent 06dd8c65aa
commit 61e7d2ebf9
37 changed files with 39 additions and 2225 deletions

View File

@@ -3,9 +3,9 @@ package org.briarproject.bramble;
import org.briarproject.bramble.io.DnsModule;
import org.briarproject.bramble.mailbox.ModularMailboxModule;
import org.briarproject.bramble.network.JavaNetworkModule;
import org.briarproject.bramble.plugin.tor.wrapper.CircumventionModule;
import org.briarproject.bramble.socks.SocksModule;
import org.briarproject.bramble.system.JavaSystemModule;
import org.briarproject.onionwrapper.CircumventionModule;
import dagger.Module;

View File

@@ -15,10 +15,10 @@ import org.briarproject.bramble.api.plugin.TorSocksPort;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.WakefulIoExecutor;
import org.briarproject.bramble.plugin.tor.wrapper.CircumventionProvider;
import org.briarproject.bramble.plugin.tor.wrapper.TorWrapper;
import org.briarproject.bramble.plugin.tor.wrapper.UnixTorWrapper;
import org.briarproject.nullsafety.NotNullByDefault;
import org.briarproject.onionwrapper.CircumventionProvider;
import org.briarproject.onionwrapper.TorWrapper;
import org.briarproject.onionwrapper.UnixTorWrapper;
import java.io.File;
import java.util.concurrent.Executor;

View File

@@ -15,10 +15,10 @@ import org.briarproject.bramble.api.plugin.TorSocksPort;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.WakefulIoExecutor;
import org.briarproject.bramble.plugin.tor.wrapper.CircumventionProvider;
import org.briarproject.bramble.plugin.tor.wrapper.TorWrapper;
import org.briarproject.bramble.plugin.tor.wrapper.WindowsTorWrapper;
import org.briarproject.nullsafety.NotNullByDefault;
import org.briarproject.onionwrapper.CircumventionProvider;
import org.briarproject.onionwrapper.TorWrapper;
import org.briarproject.onionwrapper.WindowsTorWrapper;
import java.io.File;
import java.util.concurrent.Executor;

View File

@@ -1,47 +0,0 @@
package org.briarproject.bramble.plugin.tor.wrapper;
import org.briarproject.nullsafety.NotNullByDefault;
import java.io.File;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.CodeSource;
import java.util.concurrent.Executor;
import static org.briarproject.nullsafety.NullSafety.requireNonNull;
@NotNullByDefault
abstract class JavaTorWrapper extends AbstractTorWrapper {
JavaTorWrapper(Executor ioExecutor,
Executor eventExecutor,
String architecture,
File torDirectory,
int torSocksPort,
int torControlPort) {
super(ioExecutor, eventExecutor, architecture, torDirectory,
torSocksPort, torControlPort);
}
@Override
protected long getLastUpdateTime() {
CodeSource codeSource =
getClass().getProtectionDomain().getCodeSource();
if (codeSource == null) throw new AssertionError("CodeSource null");
try {
URI path = codeSource.getLocation().toURI();
File file = new File(path);
return file.lastModified();
} catch (URISyntaxException e) {
throw new AssertionError(e);
}
}
@Override
protected InputStream getResourceInputStream(String name,
String extension) {
ClassLoader cl = getClass().getClassLoader();
return requireNonNull(cl.getResourceAsStream(name + extension));
}
}

View File

@@ -1,53 +0,0 @@
package org.briarproject.bramble.plugin.tor.wrapper;
import com.sun.jna.Library;
import com.sun.jna.Native;
import org.briarproject.nullsafety.NotNullByDefault;
import java.io.File;
import java.util.concurrent.Executor;
/**
* A Tor wrapper for Unix-like operating systems.
*/
@NotNullByDefault
public class UnixTorWrapper extends JavaTorWrapper {
/**
* @param ioExecutor The wrapper will use this executor to run IO tasks,
* some of which may run for the lifetime of the wrapper, so the executor
* should have an unlimited thread pool.
* @param eventExecutor The wrapper will use this executor to call the
* {@link Observer observer} (if any). To ensure that events are observed
* in the order they occur, this executor should have a single thread (eg
* the app's main thread).
* @param architecture The processor architecture of the Tor and pluggable
* transport binaries.
* @param torDirectory The directory where the Tor process should keep its
* state.
* @param torSocksPort The port number to use for Tor's SOCKS port.
* @param torControlPort The port number to use for Tor's control port.
*/
public UnixTorWrapper(Executor ioExecutor,
Executor eventExecutor,
String architecture,
File torDirectory,
int torSocksPort,
int torControlPort) {
super(ioExecutor, eventExecutor, architecture, torDirectory,
torSocksPort, torControlPort);
}
@Override
protected int getProcessId() {
return CLibrary.INSTANCE.getpid();
}
private interface CLibrary extends Library {
CLibrary INSTANCE = Native.loadLibrary("c", CLibrary.class);
int getpid();
}
}

View File

@@ -1,95 +0,0 @@
package org.briarproject.bramble.plugin.tor.wrapper;
import com.sun.jna.platform.win32.Kernel32;
import org.briarproject.nullsafety.NotNullByDefault;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import static java.util.logging.Level.INFO;
/**
* A Tor wrapper for the Windows operating system.
*/
@NotNullByDefault
public class WindowsTorWrapper extends JavaTorWrapper {
/**
* @param ioExecutor The wrapper will use this executor to run IO tasks,
* some of which may run for the lifetime of the wrapper, so the executor
* should have an unlimited thread pool.
* @param eventExecutor The wrapper will use this executor to call
* @param eventExecutor The wrapper will use this executor to call the
* {@link Observer observer} (if any). To ensure that events are observed
* in the order they occur, this executor should have a single thread (eg
* the app's main thread).
* @param architecture The processor architecture of the Tor and pluggable
* transport binaries.
* @param torDirectory The directory where the Tor process should keep its
* state.
* @param torSocksPort The port number to use for Tor's SOCKS port.
* @param torControlPort The port number to use for Tor's control port.
*/
public WindowsTorWrapper(Executor ioExecutor,
Executor eventExecutor,
String architecture,
File torDirectory,
int torSocksPort,
int torControlPort) {
super(ioExecutor, eventExecutor, architecture, torDirectory,
torSocksPort, torControlPort);
}
@Override
protected int getProcessId() {
return Kernel32.INSTANCE.GetCurrentProcessId();
}
@Override
protected void waitForTorToStart(Process torProcess)
throws InterruptedException, IOException {
// On Windows the RunAsDaemon option has no effect, so Tor won't detach.
// Wait for the control port to be opened, then continue to read its
// stdout and stderr in a background thread until it exits.
BlockingQueue<Boolean> success = new ArrayBlockingQueue<>(1);
ioExecutor.execute(() -> {
boolean started = false;
// Read the process's stdout (and redirected stderr)
Scanner stdout = new Scanner(torProcess.getInputStream());
// Log the first line of stdout (contains Tor and library versions)
if (stdout.hasNextLine()) LOG.info(stdout.nextLine());
// Startup has succeeded when the control port is open
while (stdout.hasNextLine()) {
String line = stdout.nextLine();
if (!started && line.contains("Opened Control listener")) {
success.add(true);
started = true;
}
}
stdout.close();
// If the control port wasn't opened, startup has failed
if (!started) success.add(false);
// Wait for the process to exit
try {
int exit = torProcess.waitFor();
if (LOG.isLoggable(INFO))
LOG.info("Tor exited with value " + exit);
} catch (InterruptedException e1) {
LOG.warning("Interrupted while waiting for Tor to exit");
Thread.currentThread().interrupt();
}
});
// Wait for the startup result
if (!success.take()) throw new IOException();
}
@Override
protected String getExecutableExtension() {
return ".exe";
}
}