Create hidden service via conf file so we can use Tor 0.2.6.

This commit is contained in:
akwizgran
2016-08-26 23:32:06 +01:00
parent 749695187e
commit 84b3670624
2 changed files with 44 additions and 39 deletions

View File

@@ -51,7 +51,6 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Scanner; import java.util.Scanner;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -69,8 +68,6 @@ import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS;
import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY;
import static org.briarproject.util.PrivacyUtils.scrubOnion; import static org.briarproject.util.PrivacyUtils.scrubOnion;
class TorPlugin implements DuplexPlugin, EventHandler, EventListener { class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
@@ -84,6 +81,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private static final String OWNER = "__OwningControllerProcess"; private static final String OWNER = "__OwningControllerProcess";
private static final int SOCKS_PORT = 59050, CONTROL_PORT = 59051; private static final int SOCKS_PORT = 59050, CONTROL_PORT = 59051;
private static final int COOKIE_TIMEOUT = 3000; // Milliseconds private static final int COOKIE_TIMEOUT = 3000; // Milliseconds
private static final int HOSTNAME_TIMEOUT = 30 * 1000; // Milliseconds
private static final Pattern ONION = Pattern.compile("[a-z2-7]{16}"); private static final Pattern ONION = Pattern.compile("[a-z2-7]{16}");
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(TorPlugin.class.getName()); Logger.getLogger(TorPlugin.class.getName());
@@ -98,7 +96,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private final int pollingInterval; private final int pollingInterval;
private final ConnectionStatus connectionStatus; private final ConnectionStatus connectionStatus;
private final File torDirectory, torFile, geoIpFile, configFile; private final File torDirectory, torFile, geoIpFile, configFile;
private final File doneFile, cookieFile; private final File doneFile, cookieFile, hostnameFile;
private final PowerManager.WakeLock wakeLock; private final PowerManager.WakeLock wakeLock;
private final AtomicBoolean used = new AtomicBoolean(false); private final AtomicBoolean used = new AtomicBoolean(false);
@@ -131,6 +129,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
configFile = new File(torDirectory, "torrc"); configFile = new File(torDirectory, "torrc");
doneFile = new File(torDirectory, "done"); doneFile = new File(torDirectory, "done");
cookieFile = new File(torDirectory, ".tor/control_auth_cookie"); cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
hostnameFile = new File(torDirectory, "hs/hostname");
Object o = appContext.getSystemService(POWER_SERVICE); Object o = appContext.getSystemService(POWER_SERVICE);
PowerManager pm = (PowerManager) o; PowerManager pm = (PowerManager) o;
wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "TorPlugin"); wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "TorPlugin");
@@ -380,40 +379,48 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private void publishHiddenService(String port) { private void publishHiddenService(String port) {
if (!running) return; if (!running) return;
LOG.info("Creating hidden service"); if (!hostnameFile.exists()) {
String privKey = callback.getSettings().get(HS_PRIVKEY); LOG.info("Creating hidden service");
Map<Integer, String> portLines = try {
Collections.singletonMap(80, "127.0.0.1:" + port); // Watch for the hostname file being created/updated
Map<String, String> response; File serviceDirectory = hostnameFile.getParentFile();
try { serviceDirectory.mkdirs();
// Use the control connection to set up the hidden service hostnameFile.createNewFile();
if (privKey == null) CountDownLatch latch = new CountDownLatch(1);
response = controlConnection.addOnion(portLines); FileObserver obs = new WriteObserver(hostnameFile, latch);
else response = controlConnection.addOnion(privKey, portLines); obs.startWatching();
} catch (IOException e) { // Use the control connection to update the Tor config
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); List<String> config = Arrays.asList(
return; "HiddenServiceDir " +
} serviceDirectory.getAbsolutePath(),
if (!response.containsKey(HS_ADDRESS)) { "HiddenServicePort 80 127.0.0.1:" + port);
LOG.warning("Tor did not return a hidden service address"); controlConnection.setConf(config);
return; controlConnection.saveConf();
} // Wait for the hostname file to be created/updated
if (privKey == null && !response.containsKey(HS_PRIVKEY)) { if (!latch.await(HOSTNAME_TIMEOUT, MILLISECONDS)) {
LOG.warning("Tor did not return a private key"); LOG.warning("Hidden service not created");
return; if (LOG.isLoggable(INFO)) listFiles(torDirectory);
return;
}
if (!running) return;
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (InterruptedException e) {
LOG.warning("Interrupted while creating hidden service");
Thread.currentThread().interrupt();
return;
}
} }
// Publish the hidden service's onion hostname in transport properties // Publish the hidden service's onion hostname in transport properties
String hostname = response.get(HS_ADDRESS); try {
if (LOG.isLoggable(INFO)) String hostname = new String(read(hostnameFile), "UTF-8").trim();
LOG.info("Hidden service " + scrubOnion(hostname)); if (LOG.isLoggable(INFO))
TransportProperties p = new TransportProperties(); LOG.info("Hidden service " + scrubOnion(hostname));
p.put(PROP_ONION, hostname); TransportProperties p = new TransportProperties();
callback.mergeLocalProperties(p); p.put(PROP_ONION, hostname.substring(0, 16));
if (privKey == null) { callback.mergeLocalProperties(p);
// Save the hidden service's private key for next time } catch (IOException e) {
Settings s = new Settings(); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
s.put(HS_PRIVKEY, response.get(HS_PRIVKEY));
callback.mergeSettings(s);
} }
} }

View File

@@ -1,6 +1,5 @@
package org.briarproject.util; package org.briarproject.util;
import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@@ -9,8 +8,7 @@ import java.net.SocketAddress;
public class PrivacyUtils { public class PrivacyUtils {
public static String scrubOnion(String onion) { public static String scrubOnion(String onion) {
// keep first three characters of onion address return onion;
return onion.substring(0, 3) + "[_scrubbed_]";
} }
public static String scrubMacAddress(String address) { public static String scrubMacAddress(String address) {