[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r15705: Support the v3 directory protocol (finally!). (in puppetor/trunk/src/de/uniba/wiai/lspi/puppetor: examples impl)
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@xxxxxxxxx");
-
- // 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");
}
}