/** * OnionCoffee - Anonymous Communication through TOR Network * Copyright (C) 2005-2007 RWTH Aachen University, Informatik IV * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package TorJava; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; import TorJava.Common.Parsing; import TorJava.Common.StreamsAndHTTP; /** * used for global configuration - stuff * * @author Lexi * @author Michael Koellejan * @author Andriy Panchenko */ public class TorConfig { HashMap<String, HashMap<String, Object>> trustedServers; // functionality static String logFileName = null; static int cacheMaxAgeSeconds = 24 * 3600; static int startupDelaySeconds = 15; static int dirserver_port = 0; // for running an own directory server static int or_port = 0; // for running an own onion router String nickname = "TorJava"; // myself // Static final/utility variables public static final String TORJAVA_VERSION_STRING = "TorJava 0.1a"; // QoS-parameters static int retriesConnect = 5; static int reconnectCircuit = 3; static int retriesStreamBuildup = 5; static int defaultIdleCircuits = 5; static int queueTimeoutCircuit = 40; static int queueTimeoutResolve = 20; static int queueTimeoutStreamBuildup = 10; static int circuitClosesOnFailures = 3; static int circuitsMaximumNumber = 15; static float rankingTransferPerServerUpdate = 0.95f; // 0..1 static boolean veryAggressiveStreamBuilding = false; // this is a truely asocial way of building streams!! // directory parameters static int intervalDirectoryV1Refresh = 30; // in minutes longer, since it updates the complete directory at once static int intervalDirectoryRefresh = 2; // in minutes static int dirV2ReadMaxNumberOfDescriptorsFirstTime = 180; // set to <=0 to read all static int dirV2ReadMaxNumberOfDescriptorsPerUpdate = 80; // set to <=0 to read all static int dirV2ReadMaxNumberOfThreads = 3; static int dirV2ReloadRetries = 3; // per descriptor static int dirV2ReloadTimeout = 10; // in seconds static int dirV2DescriptorsPerBatch = 1; static int dirV2NetworkStatusRequestTimeOut = 60000; // millisecond // QoS-parameter, see updateRanking in Circuit.java static final int CIRCUIT_ESTABLISHMENT_TIME_IMPACT = 5; // Security parameters static int streamsPerCircuit = 50; static float rankingIndexEffect = 0.9f; // see Server.getRefinedRankingIndex // Path length static int route_min_length = 3; static int route_max_length = 3; // Don't establish any circuits until a certain part of // the descriptors of running routers is present static float min_percentage = 1; // Wait at most until this number of descriptors is known static int min_descriptors = route_min_length; // True if there shouldn't be two class C addresses on the route static boolean route_uniq_class_c = true; // True if there should be at most one router from one country // (or block of countries) on the path static boolean route_uniq_country = false; // Allow a single node to be present in multiple circuits static int allow_node_multiple_circs = 3; static HashSet<String> avoidedCountries; static HashSet<String> avoidedNodes; // Time intervals of gui updates in ms public static int guiUpdateIntervalMilliSeconds = 3000; public static boolean guiDisplayNodeNames = false; public static String guiCountryOfUser = "EU"; // Filenames private static final String TOR_CONFIG_FILENAME = "torrc"; private static final String TOR_CACHE_FILENAME = "cached-directory"; static final String TOR_STABLE_DIR_FILENAME = "data/directory-stable"; static final String TOR_GEOIPCITY_FILENAME = "data/GeoLiteCity.dat"; // PROXY-Stuff // FIXME: is public (and in fact: complete class is public) only to be accessed from HTTPConnection public static Vector<String> setFilteredHeaders; public static Vector<String[]> setReplaceHeaders; public static int portWWWProxy = 8080; public static int portSocksProxy = 1080; private static String filename; /** * @param readFileName set to false to avoid any access to the lcoal file system */ TorConfig(boolean readFileName) { if (readFileName) init(getConfigDir() + TOR_CONFIG_FILENAME); else init(null); } TorConfig(String filename) { init(filename); } void reload() { if (filename == null) return; Logger.logGeneral(Logger.INFO,"TorConfig.reload: reloading config-file "+filename); init(filename); } private void init(String filename) { // init trusted dirctory servers trustedServers = new HashMap<String, HashMap<String, Object>>(); // init set of avoided nodes, countries avoidedCountries = new HashSet<String>(); avoidedNodes = new HashSet<String>(); // init set of filtered HTTP-headers setFilteredHeaders = new Vector<String>(); setReplaceHeaders = new Vector<String[]>(); // read everything else from config readFromConfig(filename); // set filename, such that file can be reloaded TorConfig.filename = filename; } public void close() { writeToFile("/tmp/torrc.test"); } /** should be called in case there are no trusted servers in the config-file given */ private void addDefaultTrustedServers() { // Deprecated: V2-servers, only for fallback HashMap<String,Object> dirServer = new HashMap<String,Object>(); dirServer = new HashMap<String,Object>(); dirServer.put("version", new Integer(2)); dirServer.put("ip", "194.109.206.212"); dirServer.put("port", new Integer(80)); dirServer.put("fingerprint", "7E:A6:EA:D6:FD:83:08:3C:53:8F:44:03:8B:BF:A0:77:58:7D:D7:55"); trustedServers.put("dizum", dirServer); // V3-servers dirServer.put("version", new Integer(3)); dirServer.put("ip", "128.31.0.34"); dirServer.put("port", new Integer(9031)); dirServer.put("fingerprint", "FF:CB:46:DB:13:39:DA:84:67:4C:70:D7:CB:58:64:34:C4:37:04:41"); trustedServers.put("moria1", dirServer); dirServer = new HashMap<String,Object>(); dirServer.put("version", new Integer(3)); dirServer.put("ip", "128.31.0.34"); dirServer.put("port", new Integer(9032)); dirServer.put("fingerprint", "71:9B:E4:5D:E2:24:B6:07:C5:37:07:D0:E2:14:3E:2D:42:3E:74:CF"); trustedServers.put("moria2", dirServer); dirServer = new HashMap<String,Object>(); dirServer.put("version", new Integer(3)); dirServer.put("ip", "86.59.21.38"); dirServer.put("port", new Integer(80)); dirServer.put("fingerprint", "84:7B:1F:85:03:44:D7:87:64:91:A5:48:92:F9:04:93:4E:4E:B8:5D"); trustedServers.put("tor26", dirServer); dirServer = new HashMap<String,Object>(); dirServer.put("version", new Integer(3)); dirServer.put("ip", "82.94.251.206"); dirServer.put("port", new Integer(80)); dirServer.put("fingerprint", "4A:0C:CD:2D:DC:79:95:08:3D:73:F5:D6:67:10:0C:8A:58:31:F1:6D"); trustedServers.put("Tonga", dirServer); dirServer = new HashMap<String,Object>(); dirServer.put("version", new Integer(3)); dirServer.put("ip", "216.224.124.114"); dirServer.put("port", new Integer(9030)); dirServer.put("fingerprint", "F3:97:03:8A:DC:51:33:61:35:E7:B8:0B:D9:9C:A3:84:43:60:29:2B"); trustedServers.put("ides", dirServer); dirServer = new HashMap<String,Object>(); dirServer.put("version", new Integer(3)); dirServer.put("ip", "80.190.246.100"); dirServer.put("port", new Integer(80)); dirServer.put("fingerprint", "68:33:3D:07:61:BC:F3:97:A5:87:A0:C0:B9:63:E4:A9:E9:9E:C4:D3"); trustedServers.put("gabelmoo", dirServer); dirServer = new HashMap<String,Object>(); dirServer.put("version", new Integer(3)); dirServer.put("ip", "213.73.91.31"); dirServer.put("port", new Integer(80)); dirServer.put("fingerprint", "7B:E6:83:E6:5D:48:14:13:21:C5:ED:92:F0:75:C5:53:64:AC:71:23"); trustedServers.put("dannenberg", dirServer); } private String replaceSpaceWithSpaceRegExp(String regexp) { return regexp.replaceAll(" ","\\\\s+"); } private int parseInt(String config,String name,int myDefault) { int x = Integer.parseInt(Parsing.parseStringByRE(config,"^\\s*"+replaceSpaceWithSpaceRegExp(name)+"\\s+(\\d+)",Integer.toString(myDefault))); Logger.logGeneral(Logger.RAW_DATA,"TorConfig.parseInt: Parsed '"+name+"' as '"+x+"'"); return x; } private String writeInt(String name,int value) { return name + " " + value + "\n"; } /*private float parseFloat(String config,String name,float myDefault) { float x = Float.parseFloat(Parsing.parseStringByRE(config,"^\\s*"+replaceSpaceWithSpaceRegExp(name)+"\\s+([0-9.]+)",Float.toString(myDefault))); Logger.logGeneral(Logger.RAW_DATA,"TorConfig.parseFloat: Parsed '"+name+"' as '"+x+"'"); return x; }*/ private String writeFloat(String name,float value) { return name + " " + value + "\n"; } private float parseFloat(String config,String name,float myDefault,float lower,float upper) { float x = Float.parseFloat(Parsing.parseStringByRE(config,"^\\s*"+replaceSpaceWithSpaceRegExp(name)+"\\s+([0-9.]+)",Float.toString(myDefault))); if (x<lower) x = lower; if (x>upper) x = upper; Logger.logGeneral(Logger.RAW_DATA,"TorConfig.parseFloat: Parsed '"+name+"' as '"+x+"'"); return x; } private String parseString(String config,String name,String myDefault) { String x = Parsing.parseStringByRE(config,"^\\s*"+replaceSpaceWithSpaceRegExp(name)+"\\s+(\\S.*?)$",myDefault); Logger.logGeneral(Logger.RAW_DATA,"TorConfig.parseString: Parsed '"+name+"' as '"+x+"'"); return x; } private String writeString(String name, String value) { return name + " " + value + "\n"; } private boolean parseBoolean(String config,String name,boolean myDefault) { String mydef = "false"; if (myDefault) mydef="true"; String x = Parsing.parseStringByRE(config,"^\\s*"+replaceSpaceWithSpaceRegExp(name)+"\\s+(\\S.*?)$",mydef).trim(); boolean ret = false; if (x.equals("1") || x.equalsIgnoreCase("true") || x.equalsIgnoreCase("yes")) ret = true; Logger.logGeneral(Logger.RAW_DATA,"TorConfig.parseBoolean: Parsed '"+name+"' as '"+ret+"'"); return ret; } private String writeBoolean(String name, boolean value) { if (value == true) { return name + " " + "true" + "\n"; } else { return name + " " + "false" + "\n"; } } void readFromConfig(String filename) { try { String config=""; if (filename != null) { DataInputStream sin = new DataInputStream(new FileInputStream(new File(filename))); //DataInputStream sin = new DataInputStream(ClassLoader.getSystemResourceAsStream(filename)); config = StreamsAndHTTP.readAllFromStream(sin); Logger.logGeneral(Logger.RAW_DATA, "TorConfig.readFromConfig(): " + config); } // Read variable config information here // logging-verbosity Logger.LOG_GENERAL = parseInt(config,"Log General",Logger.LOG_GENERAL); Logger.LOG_DIRECTORY = parseInt(config,"Log Directory",Logger.LOG_DIRECTORY); Logger.LOG_TLS = parseInt(config,"Log TLS",Logger.LOG_TLS); Logger.LOG_CIRCUIT = parseInt(config,"Log Circuit",Logger.LOG_CIRCUIT); Logger.LOG_STREAM = parseInt(config,"Log Stream",Logger.LOG_STREAM); Logger.LOG_CELL = parseInt(config,"Log Cell",Logger.LOG_CELL); Logger.LOG_CRYPTO = parseInt(config,"Log Crypto",Logger.LOG_CRYPTO); Logger.LOG_HIDDENSERVICE = parseInt(config,"Log HiddenService",Logger.LOG_HIDDENSERVICE); Logger.LOG_FILE_GENERAL = parseInt(config,"LogFile General",Logger.LOG_FILE_GENERAL); Logger.LOG_FILE_DIRECTORY = parseInt(config,"LogFile Directory",Logger.LOG_FILE_DIRECTORY); Logger.LOG_FILE_TLS = parseInt(config,"LogFile TLS",Logger.LOG_FILE_TLS); Logger.LOG_FILE_CIRCUIT = parseInt(config,"LogFile Circuit",Logger.LOG_FILE_CIRCUIT); Logger.LOG_FILE_STREAM = parseInt(config,"LogFile Stream",Logger.LOG_FILE_STREAM); Logger.LOG_FILE_CELL = parseInt(config,"LogFile Cell",Logger.LOG_FILE_CELL); Logger.LOG_FILE_CRYPTO = parseInt(config,"LogFile Crypto",Logger.LOG_FILE_CRYPTO); Logger.LOG_FILE_HIDDENSERVICE = parseInt(config,"LogFile HiddenService",Logger.LOG_FILE_HIDDENSERVICE); // You can still manually define V1 authorities Pattern p_trusted = Pattern.compile("^\\s*trusted\\s+(\\S+)\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s+(\\d+)\\s+([0-9a-f:]+)\\s*$", Pattern.UNIX_LINES + Pattern.MULTILINE+Pattern.CASE_INSENSITIVE + Pattern.DOTALL); Matcher m = p_trusted.matcher(config); while (m.find()) { HashMap<String,Object> dirServer = new HashMap<String,Object>(); dirServer.put("version", new Integer(1)); dirServer.put("ip", m.group(2)); dirServer.put("port", new Integer(m.group(3))); dirServer.put("fingerprint", m.group(4)); trustedServers.put(m.group(1), dirServer); Logger.logGeneral(Logger.VERBOSE,"TorConfig.readFromConfig(): Parsed v1Dir '"+m.group(1)+"' with fingerprint '"+m.group(4)+"'"); } // Parse trusted servers V2 p_trusted = Pattern.compile("^\\s*trustedv2\\s+(\\S+)\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s+(\\d+)\\s+([0-9a-f:]+)\\s*$", Pattern.UNIX_LINES + Pattern.MULTILINE+Pattern.CASE_INSENSITIVE + Pattern.DOTALL); m = p_trusted.matcher(config); while (m.find()) { HashMap<String,Object> dirServer = new HashMap<String,Object>(); dirServer.put("version", new Integer(2)); dirServer.put("ip", m.group(2)); dirServer.put("port", new Integer(m.group(3))); dirServer.put("fingerprint", m.group(4)); trustedServers.put(m.group(1), dirServer); Logger.logGeneral(Logger.VERBOSE,"TorConfig.readFromConfig: Parsed v2Dir '"+m.group(1)+"' with fingerprint '"+m.group(4)+"'"); } // NEW: Parse trusted servers V3 p_trusted = Pattern.compile("^\\s*trustedv3\\s+(\\S+)\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s+(\\d+)\\s+([0-9a-f:]+)\\s*$", Pattern.UNIX_LINES + Pattern.MULTILINE+Pattern.CASE_INSENSITIVE + Pattern.DOTALL); m = p_trusted.matcher(config); while (m.find()) { HashMap<String,Object> dirServer = new HashMap<String,Object>(); dirServer.put("version", new Integer(3)); dirServer.put("ip", m.group(2)); dirServer.put("port", new Integer(m.group(3))); dirServer.put("fingerprint", m.group(4)); trustedServers.put(m.group(1), dirServer); Logger.logGeneral(Logger.VERBOSE,"TorConfig.readFromConfig: Parsed v3Dir '"+m.group(1)+"' with fingerprint '"+m.group(4)+"'"); } // security parameters streamsPerCircuit= parseInt(config,"StreamsPerCircuit",streamsPerCircuit); rankingIndexEffect = parseFloat(config,"RankingIndexEffect",rankingIndexEffect,0,1); route_min_length = parseInt(config,"RouteMinLength",route_min_length); route_max_length = parseInt(config,"RouteMaxLength",route_max_length); min_percentage = parseFloat(config,"MinPercentage",min_percentage,0,1); min_descriptors = parseInt(config,"MinDescriptors",min_descriptors); route_uniq_class_c = parseBoolean(config,"RouteUniqClassC",route_uniq_class_c); route_uniq_country = parseBoolean(config,"RouteUniqCountry",route_uniq_country); allow_node_multiple_circs = parseInt(config,"AllowNodeMultipleCircuits", allow_node_multiple_circs); // Avoid Countries Pattern p = Pattern.compile("^\\s*AvoidCountry\\s+(.*?)$", Pattern.MULTILINE + Pattern.CASE_INSENSITIVE + Pattern.UNIX_LINES); m = p.matcher(config); while(m.find()) { Logger.logGeneral(Logger.VERBOSE,"TorConfig.readConfig: will avoid country: "+m.group(1)); avoidedCountries.add(m.group(1)); } // Avoid Nodes p = Pattern.compile("^\\s*AvoidNode\\s+(.*?)$", Pattern.MULTILINE + Pattern.CASE_INSENSITIVE + Pattern.UNIX_LINES); m = p.matcher(config); while(m.find()) { Logger.logGeneral(Logger.VERBOSE,"TorConfig.readConfig: will avoid node: "+m.group(1)); avoidedNodes.add(m.group(1)); } // functionality cacheMaxAgeSeconds = parseInt(config,"cacheMaxAgeSeconds",cacheMaxAgeSeconds); startupDelaySeconds = parseInt(config,"startupDelaySeconds",startupDelaySeconds); guiUpdateIntervalMilliSeconds = parseInt(config,"guiUpdateIntervalMilliSeconds",guiUpdateIntervalMilliSeconds); guiDisplayNodeNames = parseBoolean(config,"guiDisplayNodeNames",guiDisplayNodeNames); guiCountryOfUser = parseString(config,"guiCountryOfUser",guiCountryOfUser); dirserver_port = parseInt(config,"dirserverport",0); or_port = parseInt(config,"orport",0); logFileName = parseString(config,"Log filename",null); nickname = parseString(config,"nickname",nickname); portWWWProxy = parseInt(config,"portwwwproxy",portWWWProxy); portSocksProxy = parseInt(config,"portsocksproxy",portSocksProxy); // QoS parameters retriesConnect = parseInt(config,"RetriesConnect",retriesConnect); retriesStreamBuildup = parseInt(config,"RetriesStreamBuildup",retriesStreamBuildup); reconnectCircuit = parseInt(config,"ReconnectCircuit",reconnectCircuit); defaultIdleCircuits = parseInt(config,"DefaultIdleCircuits",defaultIdleCircuits); queueTimeoutCircuit = parseInt(config,"QueueTimeoutCircuit",queueTimeoutCircuit); queueTimeoutResolve = parseInt(config,"QueueTimeoutResolve",queueTimeoutResolve); queueTimeoutStreamBuildup = parseInt(config,"QueueTimeoutStreamBuildup",queueTimeoutStreamBuildup); rankingTransferPerServerUpdate = parseFloat(config,"RankingTransferPerServerUpdate",rankingTransferPerServerUpdate,0,1); circuitClosesOnFailures = parseInt(config,"CircuitClosesOnFailures",circuitClosesOnFailures); circuitsMaximumNumber = parseInt(config,"circuitsMaximumNumber",circuitsMaximumNumber); veryAggressiveStreamBuilding = parseBoolean(config,"veryAggressiveStreamBuilding",veryAggressiveStreamBuilding); // directory parameters intervalDirectoryV1Refresh = parseInt(config,"DirectoryV1Refresh",intervalDirectoryV1Refresh); intervalDirectoryRefresh = parseInt(config,"DirectoryRefresh",intervalDirectoryRefresh); dirV2ReadMaxNumberOfDescriptorsFirstTime = parseInt(config,"MaxNumberOfDescriptorsFirstTime",dirV2ReadMaxNumberOfDescriptorsFirstTime); dirV2ReadMaxNumberOfDescriptorsPerUpdate = parseInt(config,"MaxNumberOfDescriptorsPerUpdate",dirV2ReadMaxNumberOfDescriptorsPerUpdate); dirV2ReloadRetries = parseInt(config,"dirV2ReloadRetries",dirV2ReloadRetries); dirV2ReloadTimeout = parseInt(config,"dirV2ReloadTimeout",dirV2ReloadTimeout); dirV2DescriptorsPerBatch = parseInt(config,"dirV2DescriptorsPerBatch",dirV2DescriptorsPerBatch); // Filtering HTTP-headers p = Pattern.compile("^\\s*FilterHeader\\s+(.*?)$", Pattern.MULTILINE + Pattern.CASE_INSENSITIVE + Pattern.UNIX_LINES); m = p.matcher(config); while(m.find()) { Logger.logGeneral(Logger.RAW_DATA,"TorConfig.readConfig: will filter '"+m.group(1)+"' HTTP-headers"); setFilteredHeaders.add(m.group(1)); } // Filtering HTTP-headers p = Pattern.compile("^\\s*ReplaceHeader\\s+(\\S+)\\s+(.*?)$", Pattern.MULTILINE + Pattern.CASE_INSENSITIVE + Pattern.UNIX_LINES); m = p.matcher(config); while(m.find()) { Logger.logGeneral(Logger.RAW_DATA,"TorConfig.readConfig: will replace '"+m.group(1)+"' HTTP-headers with "+m.group(2)); String[] set = new String[2]; set[0] = m.group(1); set[1] = m.group(2); setReplaceHeaders.add(set); } } catch (IOException e) { Logger.logGeneral(Logger.WARNING, "TorConfig.readFromConfig(): Warning: " + e.getMessage()); } if (trustedServers.size()<1) addDefaultTrustedServers(); } /** used to store some new values to a file */ void writeToFile(String filename) { if (filename==null) return; try { StringBuffer config = new StringBuffer(); Logger.logGeneral(Logger.VERBOSE, "TorConfig.writeToFile(): " + config); // Write variable config information here // logging-verbosity config.append(writeInt("Log General", Logger.LOG_GENERAL)); config.append(writeInt("Log Directory", Logger.LOG_DIRECTORY)); config.append(writeInt("Log TLS", Logger.LOG_TLS)); config.append(writeInt("Log Circuit",Logger.LOG_CIRCUIT)); config.append(writeInt("Log Stream",Logger.LOG_STREAM)); config.append(writeInt("Log Cell",Logger.LOG_CELL)); config.append(writeInt("Log Crypto",Logger.LOG_CRYPTO)); config.append(writeInt("Log HiddenService",Logger.LOG_HIDDENSERVICE)); config.append(writeInt("LogFile General",Logger.LOG_FILE_GENERAL)); config.append(writeInt("LogFile Directory",Logger.LOG_FILE_DIRECTORY)); config.append(writeInt("LogFile TLS",Logger.LOG_FILE_TLS)); config.append(writeInt("LogFile Circuit",Logger.LOG_FILE_CIRCUIT)); config.append(writeInt("LogFile Stream",Logger.LOG_FILE_STREAM)); config.append(writeInt("LogFile Cell",Logger.LOG_FILE_CELL)); config.append(writeInt("LogFile Crypto",Logger.LOG_FILE_CRYPTO)); config.append(writeInt("LogFile HiddenService",Logger.LOG_FILE_HIDDENSERVICE)); // trusted servers Iterator<String> trustedIterate = trustedServers.keySet().iterator(); while (trustedIterate.hasNext()) { String dirServerName = (String)trustedIterate.next(); HashMap<String, Object> dirServer = trustedServers.get(dirServerName); StringBuffer dirServerString = new StringBuffer(); dirServerString.append(dirServerName + " "); dirServerString.append(dirServer.get("ip") + " "); dirServerString.append(dirServer.get("port") + " "); dirServerString.append(dirServer.get("fingerprint") + " "); config.append(writeString("trusted",dirServerString.toString())); Logger.logGeneral(Logger.VERBOSE,"TorConfig.writeToFile: Wrote Dir '"+dirServerName+"' with fingerprint '"+dirServer.get("fingerprint")+"'"); } // security parameters config.append(writeInt("StreamsPerCircuit",streamsPerCircuit)); config.append(writeFloat("RankingIndexEffect",rankingIndexEffect)); config.append(writeInt("RouteMinLength",route_min_length)); config.append(writeInt("RouteMaxLength",route_max_length)); config.append(writeFloat("MinPercentage",min_percentage)); config.append(writeInt("MinDescriptors",min_descriptors)); config.append(writeBoolean("RouteUniqClassC",route_uniq_class_c)); config.append(writeBoolean("RouteUniqCountry",route_uniq_country)); config.append(writeInt("AllowNodeMultipleCircuits", allow_node_multiple_circs)); // Avoided countries Iterator<String> it = avoidedCountries.iterator(); while (it.hasNext()) { String countryName = (String)it.next(); config.append(writeString("AvoidCountry",countryName)); Logger.logGeneral(Logger.VERBOSE,"TorConfig.writeToFile: will avoid country "+countryName); } // Avoided nodes it = avoidedNodes.iterator(); while (it.hasNext()) { String nodeName = (String)it.next(); config.append(writeString("AvoidNode",nodeName)); Logger.logGeneral(Logger.VERBOSE,"TorConfig.writeToFile: will avoid node "+nodeName); } // Functionality config.append(writeInt("cacheMaxAgeSeconds",cacheMaxAgeSeconds)); config.append(writeInt("startupDelaySeconds",startupDelaySeconds)); config.append(writeInt("guiUpdateIntervalMilliSeconds",guiUpdateIntervalMilliSeconds)); config.append(writeBoolean("guiDisplayNodeNames",guiDisplayNodeNames)); config.append(writeString("guiCountryOfUser",guiCountryOfUser)); config.append(writeInt("dirserverport",dirserver_port)); config.append(writeInt("orport",or_port)); config.append(writeString("Log filename",logFileName)); config.append(writeString("nickname",nickname)); config.append(writeInt("portwwwproxy",portWWWProxy)); config.append(writeInt("portsocksproxy",portSocksProxy)); // QoS parameters config.append(writeInt("RetriesConnect",retriesConnect)); config.append(writeInt("RetriesStreamBuildup",retriesStreamBuildup)); config.append(writeInt("ReconnectCircuit",reconnectCircuit)); config.append(writeInt("DefaultIdleCircuits",defaultIdleCircuits)); config.append(writeInt("QueueTimeoutCircuit",queueTimeoutCircuit)); config.append(writeInt("QueueTimeoutResolve",queueTimeoutResolve)); config.append(writeInt("QueueTimeoutStreamBuildup",queueTimeoutStreamBuildup)); config.append(writeInt("CircuitClosesOnFailures",circuitClosesOnFailures)); config.append(writeInt("circuitsMaximumNumber",circuitsMaximumNumber)); config.append(writeBoolean("veryAggressiveStreamBuilding",veryAggressiveStreamBuilding)); // FIXME: Check if this really works config.append(writeFloat("RankingTransferPerServerUpdate",rankingTransferPerServerUpdate)); // directory parameters config.append(writeInt("DirectoryV1Refresh",intervalDirectoryV1Refresh)); config.append(writeInt("DirectoryRefresh",intervalDirectoryRefresh)); config.append(writeInt("MaxNumberOfDescriptorsFirstTime",dirV2ReadMaxNumberOfDescriptorsFirstTime)); config.append(writeInt("MaxNumberOfDescriptorsPerUpdate",dirV2ReadMaxNumberOfDescriptorsPerUpdate)); config.append(writeInt("dirV2ReloadRetries",dirV2ReloadRetries)); config.append(writeInt("dirV2ReloadTimeout",dirV2ReloadTimeout)); config.append(writeInt("dirV2DescriptorsPerBatch",dirV2DescriptorsPerBatch)); // Filtering HTTP-headers Iterator<String> iterateHeaders = setFilteredHeaders.iterator(); while (iterateHeaders.hasNext()) { String headerName = (String)iterateHeaders.next(); config.append(writeString("FilterHeader",headerName)); Logger.logGeneral(Logger.RAW_DATA,"TorConfig.writeToFile: will filter '"+headerName+"' HTTP-headers"); } // Replace HTTP-headers Iterator<String[]> iterateReplace = setReplaceHeaders.iterator(); while(iterateReplace.hasNext()) { String[] set = iterateReplace.next(); config.append(writeString("ReplaceHeader",set[0] + " " + set[1])); Logger.logGeneral(Logger.RAW_DATA,"TorConfig.writeToFile: will filter '"+set[0]+"' HTTP-headers"); } FileWriter writer = new FileWriter(new File(filename)); writer.write(config.toString()); writer.close(); } catch (IOException e) { Logger.logGeneral(Logger.WARNING, "TorConfig.writeToFile(): Warning: " + e.getMessage()); } } static String getConfigDir() { //String os = operatingSystem(); /*if (os.equals("Linux")) return System.getProperty("user.home") + System.getProperty("file.separator") + ".TorJava" + System.getProperty("file.separator"); return System.getProperty("user.home") + System.getProperty("file.separator") + "TorJava" + System.getProperty("file.separator");*/ return TorKeeper.getConfigPath() + System.getProperty("file.separator"); } /** removed, since it is no more used */ /*static String getTempDir() { String os = operatingSystem(); if (os.equals("Linux")) return "/tmp/"; return getConfigDir(); }*/ static String getCacheFilename() { return getConfigDir() + TOR_CACHE_FILENAME; } static String getLogFilename() { return logFileName; } static void setLogFilename(String name) { logFileName = name; } static String operatingSystem() { return System.getProperty("os.name"); } } // vim: et