[or-cvs] r15705: Support the v3 directory protocol (finally!). (in puppetor/trunk/src/de/uniba/wiai/lspi/puppetor: examples impl)

kloesing at seul.org kloesing at seul.org
Sun Jul 6 22:30:03 UTC 2008


Author: kloesing
Date: 2008-07-06 18:30:03 -0400 (Sun, 06 Jul 2008)
New Revision: 15705

Modified:
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/examples/AdvertisingAndAccessingHiddenServiceOverPrivateTorNetwork.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/DirectoryNodeImpl.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/NetworkImpl.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/ProxyNodeImpl.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/RouterNodeImpl.java
Log:
Support the v3 directory protocol (finally!).

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/examples/AdvertisingAndAccessingHiddenServiceOverPrivateTorNetwork.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/examples/AdvertisingAndAccessingHiddenServiceOverPrivateTorNetwork.java	2008-07-06 20:31:45 UTC (rev 15704)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/examples/AdvertisingAndAccessingHiddenServiceOverPrivateTorNetwork.java	2008-07-06 22:30:03 UTC (rev 15705)
@@ -70,15 +70,16 @@
 
 		// create a network to initialize the test case
 		Network network = NetworkFactory.createNetwork("example4");
+		network.addTemplateConfiguration(RouterNode.class,
+				"TestingTorNetwork 1");
 
 		// create three router nodes
 		RouterNode router1 = network.createRouter("router1");
 		network.createRouter("router2");
 		RouterNode router3 = network.createRouter("router3");
 
-		// create two directory nodes
+		// create only one directory node
 		network.createDirectory("dir1");
-		network.createDirectory("dir2");
 
 		// add hidden service
 		HiddenService hidServ1 = router1.addHiddenService("hidServ");
@@ -99,9 +100,9 @@
 		}
 		System.out.println("Successfully started nodes!");
 
-		// hup until nodes have built circuits (10 retries, 10 seconds timeout
+		// hup until nodes have built circuits (6 retries, 12 minutes timeout
 		// each)
-		if (!network.hupUntilUp(10, 10000)) {
+		if (!network.hupUntilUp(6, 12L * 60L * 1000L)) {
 
 			// failed to build circuits
 			System.out.println("Failed to build circuits!");
@@ -112,10 +113,10 @@
 		// obtain reference to event manager to be able to respond to events
 		EventManager manager = network.getEventManager();
 
-		// wait for 3 minutes that the proxy has published its first RSD
+		// wait for 1 hour that the proxy has published its first RSD
 		if (!manager.waitForAnyOccurence(router1.getNodeName(),
 				HiddenServiceEventType.BOB_DESC_PUBLISHED_RECEIVED,
-				3L * 60L * 1000L)) {
+				1L * 60L * 60L * 1000L)) {
 			// failed to publish an RSD
 			System.out.println("Failed to publish an RSD!");
 			System.exit(0);

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/DirectoryNodeImpl.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/DirectoryNodeImpl.java	2008-07-06 20:31:45 UTC (rev 15704)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/DirectoryNodeImpl.java	2008-07-06 22:30:03 UTC (rev 15705)
@@ -31,16 +31,22 @@
  */
 package de.uniba.wiai.lspi.puppetor.impl;
 
+import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
+import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
 import java.rmi.RemoteException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
+import java.util.logging.Level;
 
 import de.uniba.wiai.lspi.puppetor.DirectoryNode;
 import de.uniba.wiai.lspi.puppetor.PuppeTorException;
@@ -54,6 +60,137 @@
 public class DirectoryNodeImpl extends RouterNodeImpl implements DirectoryNode {
 
 	/**
+	 * Executable file for generating v3 directory authority certificates.
+	 * 
+	 * TODO make this configurable!
+	 */
+	protected static final File torGencertExecutable = new File(
+			"tor-gencert");
+
+	/**
+	 * Internal thread class that is used to generate v3 directory authority
+	 * certificates in parallel, which can take a few seconds.
+	 */
+	public class GenerateCertificateThread extends Thread {
+
+		@Override
+		public void run() {
+
+			// log entering
+			logger.entering(this.getClass().getName(), "run");
+
+			// run tor-gencert
+			ProcessBuilder processBuilder = new ProcessBuilder(
+					torGencertExecutable.getPath(), "--create-identity-key"// );
+					, "--passphrase-fd", "0");
+			File workingDirectory = new File(DirectoryNodeImpl.this.workingDir
+					.getAbsolutePath()
+					+ File.separator + "keys" + File.separator);
+
+			// create working directory
+			workingDirectory.mkdirs();
+
+			processBuilder.directory(workingDirectory);
+			processBuilder.redirectErrorStream(true);
+			Process tmpProcess = null;
+			try {
+				tmpProcess = processBuilder.start();
+			} catch (IOException e) {
+				PuppeTorException ex = new PuppeTorException(
+						"Could not start tor-gencert process for generating a "
+								+ "v3 directory authority certificate!", e);
+				logger.log(Level.WARNING, "Could not start tor-gencert "
+						+ "process for generating a v3 directory authority "
+						+ "certificate!", ex);
+				DirectoryNodeImpl.this.setCaughtException(ex);
+				return;
+			}
+
+			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
+					tmpProcess.getOutputStream()));
+			try {
+				writer.write("somepassword\n");
+				writer.close();
+			} catch (IOException e1) {
+				System.out.println("Exception at write! " + e1.getMessage());
+				e1.printStackTrace();
+			}
+
+			InputStream stderr = tmpProcess.getInputStream();
+			InputStreamReader isr = new InputStreamReader(stderr);
+			BufferedReader br = new BufferedReader(isr);
+			String line = null;
+			try {
+				while ((line = br.readLine()) != null)
+					;
+			} catch (IOException e1) {
+				e1.printStackTrace();
+			}
+
+			// wait for process to terminate
+			int exitValue = 0;
+			try {
+				exitValue = tmpProcess.waitFor();
+			} catch (InterruptedException e) {
+				PuppeTorException ex = new PuppeTorException(
+						"Interrupted while waiting for tor-gencert process to exit!",
+						e);
+				logger.log(Level.WARNING,
+						"tor-gencert process was interrupted!", ex);
+				DirectoryNodeImpl.this.setCaughtException(ex);
+				return;
+			}
+
+			if (exitValue != 0) {
+				PuppeTorException ex = new PuppeTorException(
+						"Could not start tor-gencert process! tor-gencert exited with "
+								+ "exit value " + exitValue + "!");
+				logger.log(Level.WARNING,
+						"Could not start tor-gencert process!", ex);
+				DirectoryNodeImpl.this.setCaughtException(ex);
+				return;
+			}
+
+			// read fingerprint from file
+			File authorityCertificateFile = new File(workingDirectory
+					.getAbsolutePath()
+					+ File.separator + "authority_certificate");
+			String identity;
+			try {
+				BufferedReader br2 = new BufferedReader(new FileReader(
+						authorityCertificateFile));
+				while ((line = br2.readLine()) != null
+						&& !line.startsWith("fingerprint "))
+					;
+				if (line == null) {
+					PuppeTorException ex = new PuppeTorException(
+							"Could not find fingerprint line in file "
+									+ "authority_certificate!");
+					logger.log(Level.WARNING,
+							"Could not find fingerprint line in file "
+									+ "authority_certificate!", ex);
+					DirectoryNodeImpl.this.setCaughtException(ex);
+					return;
+				}
+				identity = line.substring(line.indexOf(" ") + 1);
+				br2.close();
+			} catch (IOException e) {
+				PuppeTorException ex = new PuppeTorException(
+						"Could not read fingerprint from file!", e);
+				logger.log(Level.WARNING, "Could not read fingerprint file!",
+						ex);
+				DirectoryNodeImpl.this.setCaughtException(ex);
+				return;
+			}
+
+			DirectoryNodeImpl.this.setV3Identity(identity);
+
+			// log exiting
+			logger.exiting(this.getClass().getName(), "run");
+		}
+	}
+
+	/**
 	 * Set of routers that are approved by this directory node.
 	 */
 	private SortedSet<String> approvedRouters;
@@ -120,6 +257,59 @@
 		this.logger.exiting(this.getClass().getName(), "DirectoryNodeImpl");
 	}
 
+	/**
+	 * Invoked by the certificate generating thread: sets the generated v3
+	 * identity string.
+	 * 
+	 * @param v3Identity
+	 *            The generated v3 identity string.
+	 */
+	private synchronized void setV3Identity(String v3Identity) {
+		// log entering
+		this.logger.entering(this.getClass().getName(), "setV3Identity",
+				v3Identity);
+
+		// remember fingerprint and notify all waiting threads
+		this.v3Identity = v3Identity;
+		this.notifyAll();
+
+		// log exiting
+		this.logger.exiting(this.getClass().getName(), "setV3Identity");
+	}
+
+	/**
+	 * The generated v3 identity string.
+	 */
+	private String v3Identity;
+
+	public synchronized String getV3Identity() throws PuppeTorException {
+
+		// log entering
+		this.logger.entering(this.getClass().getName(), "getV3Identity");
+
+		// wait until either the v3 identity has been determined or an exception
+		// was caught
+		while (this.v3Identity == null && this.caughtException == null) {
+
+			try {
+				wait(500);
+			} catch (InterruptedException e) {
+				// do nothing
+			}
+		}
+
+		if (this.caughtException != null) {
+			this.logger.throwing(this.getClass().getName(), "getV3Identity",
+					this.caughtException);
+			throw this.caughtException;
+		}
+
+		// log exiting
+		this.logger.exiting(this.getClass().getName(), "getV3Identity",
+				this.v3Identity);
+		return this.v3Identity;
+	}
+
 	public synchronized String getDirServerString() throws PuppeTorException,
 			RemoteException {
 
@@ -132,10 +322,13 @@
 		// cut off router nickname
 		fingerprint = fingerprint.substring(fingerprint.indexOf(" ") + 1);
 
+		// determine v3 identity
+		String determinedV3Identity = this.getV3Identity();
+
 		// put everything together
-		String dirServerString = "DirServer " + this.nodeName + " hs orport="
-				+ this.orPort + " " + this.serverIpAddress + ":" + this.dirPort
-				+ " " + fingerprint;
+		String dirServerString = "DirServer " + this.nodeName + " v3ident="
+				+ determinedV3Identity + " orport=" + this.orPort + " "
+				+ this.serverIpAddress + ":" + this.dirPort + " " + fingerprint;
 
 		// log exiting and return dir server string
 		this.logger.exiting(this.getClass().getName(), "getDirServerString",
@@ -166,11 +359,26 @@
 	}
 
 	@Override
-	protected void determineFingerprint() {
+	protected synchronized void determineFingerprint() {
 
 		// log entering
 		this.logger.entering(this.getClass().getName(), "determineFingerprint");
 
+		// start a thread to generate the directory's certificate
+		GenerateCertificateThread certificateThread = new GenerateCertificateThread();
+		certificateThread.setName(nodeName + " Certificate Generator");
+		certificateThread.start();
+
+		// wait (non-blocking) for the v3 identity string
+		try {
+			this.getV3Identity();
+		} catch (PuppeTorException e1) {
+			PuppeTorException ex = new PuppeTorException(
+					"Could not read v3 identity string!", e1);
+			this.caughtException = ex;
+			return;
+		}
+
 		// create an empty approved-routers file to make Tor happy
 		try {
 			new File(this.workingDir.getAbsolutePath() + File.separator
@@ -227,25 +435,9 @@
 
 		// configure this node as an authoritative directory
 		templateConfiguration.add("AuthoritativeDirectory 1");
-
-		// TODO make this a little bit more configurable
-		templateConfiguration
-				.add("RecommendedVersions 0.2.0.7-alpha,0.2.0.7-alpha-dev");
-
-		templateConfiguration.add("VersioningAuthoritativeDirectory 1");
-
-		templateConfiguration.add("NamingAuthoritativeDirectory 1");
-
-		// TODO this requires version 0.2.x, but when using version 0.2.x this
-		// is vital for running a private network!!
 		templateConfiguration.add("V2AuthoritativeDirectory 1");
-
-		templateConfiguration.add("V1AuthoritativeDirectory 1");
-
-		// TODO this only works since Tor 0.1.2.x!!!
-		templateConfiguration.add("HSAuthoritativeDir 1");
-
-		// TODO only in v0.2.x
-		// templateConfiguration.add("HSAuthorityRecordStats 1");
+		templateConfiguration.add("V3AuthoritativeDirectory 1");
+		templateConfiguration.add("DirAllowPrivateAddresses 1");
+		templateConfiguration.add("MinUptimeHidServDirectoryV2 0 minutes");
 	}
 }

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/NetworkImpl.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/NetworkImpl.java	2008-07-06 20:31:45 UTC (rev 15704)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/NetworkImpl.java	2008-07-06 22:30:03 UTC (rev 15705)
@@ -307,6 +307,13 @@
 		this.logger.entering(this.getClass().getName(),
 				"configureAsPrivateNetwork");
 
+		for (ProxyNode node : this.nodes.values()) {
+			if (node.getNodeState() == NodeState.CONFIGURING) {
+				// add to configuration
+				node.addConfiguration("TestingTorNetwork 1");
+			}
+		}
+
 		// read DirServer strings for all directories
 		List<String> authorizedDirectoriesFingerprints = new ArrayList<String>();
 		for (ProxyNode node : this.nodes.values()) {

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/ProxyNodeImpl.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/ProxyNodeImpl.java	2008-07-06 20:31:45 UTC (rev 15704)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/ProxyNodeImpl.java	2008-07-06 22:30:03 UTC (rev 15705)
@@ -764,22 +764,5 @@
 		templateConfiguration.add("Log info stdout");
 		templateConfiguration.add("Log info file log");
 
-		// TODO do we need this in all nodes or only in directory nodes?!
-		templateConfiguration.add("DirAllowPrivateAddresses 1");
-
-		// allow two nodes on the same circuit to be in the same /16 net
-		// TODO this depends in private or public network setting!!!
-		templateConfiguration.add("EnforceDistinctSubnets 0");
-
-		templateConfiguration.add("ClientDNSRejectInternalAddresses 0");
-
-		// don't rely on node verification, yet... TODO change?
-		templateConfiguration
-				.add("AllowInvalidNodes middle,rendezvous,exit,entry,introduction");
-
-		// tunnel dir connections
-		// templateConfiguration.add("TunnelDirConns 1");
-		// templateConfiguration.add("PreferTunneledDirConns 1");
-
 	}
 }

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/RouterNodeImpl.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/RouterNodeImpl.java	2008-07-06 20:31:45 UTC (rev 15704)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/RouterNodeImpl.java	2008-07-06 22:30:03 UTC (rev 15705)
@@ -195,7 +195,7 @@
 	 *            The exception that occurred when trying to determine the
 	 *            fingerprint.
 	 */
-	private synchronized void setCaughtException(
+	protected synchronized void setCaughtException(
 			PuppeTorException caughtException) {
 
 		// log entering
@@ -389,7 +389,7 @@
 	 * Determines the fingerprint of this node by starting a background thread
 	 * that performs this operation.
 	 */
-	protected void determineFingerprint() {
+	protected synchronized void determineFingerprint() {
 
 		// log entering
 		this.logger.entering(this.getClass().getName(), "determineFingerprint");
@@ -412,13 +412,6 @@
 		templateConfiguration = new ArrayList<String>();
 
 		templateConfiguration.add("ContactInfo wont at reply.org");
-
-		// allow exit to private network and everything else (node will only
-		// be used by other nodes in the private network, so no worry)
-		templateConfiguration.add("ExitPolicyRejectPrivate 0");
-		templateConfiguration.add("ExitPolicy accept *:*");
-
-		// bypass testing if we are reachable
-		templateConfiguration.add("AssumeReachable 1");
+		templateConfiguration.add("HidServDirectoryV2 1");
 	}
 }



More information about the tor-commits mailing list