package com.subgraph.orchid; import java.lang.reflect.Proxy; import java.nio.charset.Charset; import java.util.logging.Logger; import com.subgraph.orchid.circuits.CircuitManagerImpl; import com.subgraph.orchid.circuits.TorInitializationTracker; import com.subgraph.orchid.config.TorConfigProxy; import com.subgraph.orchid.connections.ConnectionCacheImpl; import com.subgraph.orchid.directory.DirectoryImpl; import com.subgraph.orchid.directory.downloader.DirectoryDownloaderImpl; import com.subgraph.orchid.socks.SocksPortListenerImpl; /** * The <code>Tor</code> class is a collection of static methods for instantiating * various subsystem modules. */ public class Tor { private final static Logger logger = Logger.getLogger(Tor.class.getName()); public final static int BOOTSTRAP_STATUS_STARTING = 0; public final static int BOOTSTRAP_STATUS_CONN_DIR = 5; public final static int BOOTSTRAP_STATUS_HANDSHAKE_DIR = 10; public final static int BOOTSTRAP_STATUS_ONEHOP_CREATE = 15; public final static int BOOTSTRAP_STATUS_REQUESTING_STATUS = 20; public final static int BOOTSTRAP_STATUS_LOADING_STATUS = 25; public final static int BOOTSTRAP_STATUS_REQUESTING_KEYS = 35; public final static int BOOTSTRAP_STATUS_LOADING_KEYS = 40; public final static int BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS = 45; public final static int BOOTSTRAP_STATUS_LOADING_DESCRIPTORS = 50; public final static int BOOTSTRAP_STATUS_CONN_OR = 80; public final static int BOOTSTRAP_STATUS_HANDSHAKE_OR = 85; public final static int BOOTSTRAP_STATUS_CIRCUIT_CREATE = 90; public final static int BOOTSTRAP_STATUS_DONE = 100; private final static String implementation = "Orchid"; private final static String version = "1.0.0"; private final static Charset defaultCharset = createDefaultCharset(); private static Charset createDefaultCharset() { return Charset.forName("ISO-8859-1"); } public static Charset getDefaultCharset() { return defaultCharset; } public static String getBuildRevision() { return Revision.getBuildRevision(); } public static String getImplementation() { return implementation; } public static String getFullVersion() { final String revision = getBuildRevision(); if(revision == null || revision.isEmpty()) { return getVersion(); } else { return getVersion() + "." + revision; } } /** * Return a string describing the version of this software. * * @return A string representation of the software version. */ public static String getVersion() { return version; } /** * Determine if running on Android by inspecting java.runtime.name property. * * @return True if running on Android. */ public static boolean isAndroidRuntime() { final String runtime = System.getProperty("java.runtime.name"); return runtime != null && runtime.equals("Android Runtime"); } /** * Create and return a new <code>TorConfig</code> instance. * * @param logManager This is a required dependency. You must create a <code>LogManager</code> * before calling this method to create a <code>TorConfig</code> * @return A new <code>TorConfig</code> instance. * @see TorConfig */ static public TorConfig createConfig() { final TorConfig config = (TorConfig) Proxy.newProxyInstance(TorConfigProxy.class.getClassLoader(), new Class[] { TorConfig.class }, new TorConfigProxy()); if(isAndroidRuntime()) { logger.warning("Android Runtime detected, disabling V2 Link protocol"); config.setHandshakeV2Enabled(false); } return config; } static public TorInitializationTracker createInitalizationTracker() { return new TorInitializationTracker(); } /** * Create and return a new <code>Directory</code> instance. * * @param logManager This is a required dependency. You must create a <code>LogManager</code> * before creating a <code>Directory</code>. * @param config This is a required dependency. You must create a <code>TorConfig</code> before * calling this method to create a <code>Directory</code> * @return A new <code>Directory</code> instance. * @see Directory */ static public Directory createDirectory(TorConfig config, DirectoryStore customDirectoryStore) { return new DirectoryImpl(config, customDirectoryStore); } static public ConnectionCache createConnectionCache(TorConfig config, TorInitializationTracker tracker) { return new ConnectionCacheImpl(config, tracker); } /** * Create and return a new <code>CircuitManager</code> instance. * * @return A new <code>CircuitManager</code> instance. * @see CircuitManager */ static public CircuitManager createCircuitManager(TorConfig config, DirectoryDownloaderImpl directoryDownloader, Directory directory, ConnectionCache connectionCache, TorInitializationTracker tracker) { return new CircuitManagerImpl(config, directoryDownloader, directory, connectionCache, tracker); } /** * Create and return a new <code>SocksPortListener</code> instance. * * @param logManager This is a required dependency. You must create a <code>LogManager</code> * before calling this method to create a <code>SocksPortListener</code>. * @param circuitManager This is a required dependency. You must create a <code>CircuitManager</code> * before calling this method to create a <code>SocksPortListener</code>. * @return A new <code>SocksPortListener</code> instance. * @see SocksPortListener */ static public SocksPortListener createSocksPortListener(TorConfig config, CircuitManager circuitManager) { return new SocksPortListenerImpl(config, circuitManager); } /** * Create and return a new <code>DirectoryDownloader</code> instance. * * @param logManager This is a required dependency. You must create a <code>LogManager</code> * before calling this method to create a <code>DirectoryDownloader</code>. * @param directory This is a required dependency. You must create a <code>Directory</code> * before calling this method to create a <code>DirectoryDownloader</code> * * @param circuitManager This is a required dependency. You must create a <code>CircuitManager</code> * before calling this method to create a <code>DirectoryDownloader</code>. * * @return A new <code>DirectoryDownloader</code> instance. * @see DirectoryDownloaderImpl */ static public DirectoryDownloaderImpl createDirectoryDownloader(TorConfig config, TorInitializationTracker initializationTracker) { return new DirectoryDownloaderImpl(config, initializationTracker); } }