Vidalia
0.2.17
|
00001 /* 00002 ** This file is part of Vidalia, and is subject to the license terms in the 00003 ** LICENSE file, found in the top level directory of this distribution. If you 00004 ** did not receive the LICENSE file with this file, you may obtain it from the 00005 ** Vidalia source package distributed by the Vidalia Project at 00006 ** http://www.torproject.org/projects/vidalia.html. No part of Vidalia, 00007 ** including this file, may be copied, modified, propagated, or distributed 00008 ** except according to the terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file NetworkSettings.cpp 00013 ** \brief Settings for configuring an HTTP/HTTPS proxy or bridges 00014 */ 00015 00016 #include "NetworkSettings.h" 00017 #include "TorControl.h" 00018 00019 #define SETTING_FASCIST_FIREWALL "FascistFirewall" 00020 #define SETTING_REACHABLE_ADDRESSES "ReachableAddresses" 00021 00022 /* Vidalia-specific proxy options */ 00023 #define SETTING_PROXY_TYPE "ProxyType" 00024 #define SETTING_PROXY_ADDRESS "ProxyAddress" 00025 #define SETTING_PROXY_USERNAME "ProxyUsername" 00026 #define SETTING_PROXY_PASSWORD "ProxyPassword" 00027 00028 /* Tor's proxy options */ 00029 #define SETTING_HTTPS_PROXY "HttpsProxy" 00030 #define SETTING_HTTPS_PROXY_AUTH "HttpsProxyAuthenticator" 00031 #define SETTING_SOCKS4_PROXY "Socks4Proxy" 00032 #define SETTING_SOCKS5_PROXY "Socks5Proxy" 00033 #define SETTING_SOCKS5_USERNAME "Socks5ProxyUsername" 00034 #define SETTING_SOCKS5_PASSWORD "Socks5ProxyPassword" 00035 00036 #define SETTING_USE_BRIDGES "UseBridges" 00037 #define SETTING_BRIDGE_LIST "Bridge" 00038 #define SETTING_UPDATE_BRIDGES "UpdateBridgesFromAuthority" 00039 #define SETTING_TUNNEL_DIR_CONNS "TunnelDirConns" 00040 #define SETTING_PREFER_TUNNELED_DIR_CONNS "PreferTunneledDirConns" 00041 00042 00043 /** Default constructor */ 00044 NetworkSettings::NetworkSettings(TorControl *torControl) 00045 : AbstractTorSettings("Network", torControl) 00046 { 00047 setDefault(SETTING_PROXY_TYPE, NoProxy); 00048 setDefault(SETTING_PROXY_ADDRESS, ""); 00049 setDefault(SETTING_PROXY_USERNAME, ""); 00050 setDefault(SETTING_PROXY_PASSWORD, ""); 00051 setDefault(SETTING_USE_BRIDGES, false); 00052 setDefault(SETTING_BRIDGE_LIST, QStringList()); 00053 setDefault(SETTING_FASCIST_FIREWALL, false); 00054 setDefault(SETTING_TUNNEL_DIR_CONNS, true); 00055 setDefault(SETTING_REACHABLE_ADDRESSES, 00056 QStringList() << "*:80" << "*:443"); 00057 } 00058 00059 /** Applies the current network configuration settings to Tor. If 00060 * <b>errmsg</b> is specified and an error occurs while applying the settings, 00061 * it will be set to a string describing the error. */ 00062 bool 00063 NetworkSettings::apply(QString *errmsg) 00064 { 00065 QMultiHash<QString, QString> conf; 00066 quint32 torVersion = torControl()->getTorVersion(); 00067 00068 conf.insert(SETTING_REACHABLE_ADDRESSES, 00069 (getFascistFirewall() ? 00070 localValue(SETTING_REACHABLE_ADDRESSES).toStringList().join(",") : "")); 00071 00072 QString socks4, socks5, http, https; 00073 QString addr, user, pass, auth; 00074 00075 addr = localValue(SETTING_PROXY_ADDRESS).toString(); 00076 user = localValue(SETTING_PROXY_USERNAME).toString(); 00077 pass = localValue(SETTING_PROXY_PASSWORD).toString(); 00078 00079 if (!user.isEmpty() || !pass.isEmpty()) 00080 auth = QString("%1:%2").arg(user).arg(pass); 00081 00082 switch (getProxyType()) { 00083 case NoProxy: 00084 break; 00085 case Socks4Proxy: 00086 socks4 = addr; 00087 break; 00088 case Socks5Proxy: 00089 socks5 = addr; 00090 break; 00091 case HttpHttpsProxy: 00092 http = addr; 00093 https = http; 00094 break; 00095 } 00096 00097 if (torVersion >= 0x020201) { 00098 /* SOCKS support was implemented in 0.2.2.1 */ 00099 conf.insert(SETTING_SOCKS4_PROXY, socks4); 00100 conf.insert(SETTING_SOCKS5_PROXY, socks5); 00101 conf.insert(SETTING_SOCKS5_USERNAME, user); 00102 conf.insert(SETTING_SOCKS5_PASSWORD, pass); 00103 } 00104 00105 conf.insert(SETTING_HTTPS_PROXY, https); 00106 conf.insert(SETTING_HTTPS_PROXY_AUTH, auth); 00107 00108 if (getUseBridges()) { 00109 /* We want to always enable TunnelDirConns and friends when using 00110 * bridge relays. */ 00111 conf.insert(SETTING_TUNNEL_DIR_CONNS, "1"); 00112 conf.insert(SETTING_PREFER_TUNNELED_DIR_CONNS, "1"); 00113 } else if (torVersion <= 0x020021) { 00114 /* TunnelDirConns is enabled by default on Tor >= 0.2.0.22-rc, so don't 00115 * disable it if our Tor is recent enough. */ 00116 conf.insert(SETTING_TUNNEL_DIR_CONNS, "0"); 00117 conf.insert(SETTING_PREFER_TUNNELED_DIR_CONNS, "0"); 00118 } 00119 00120 if (torVersion >= 0x020003) { 00121 /* Do the bridge stuff only on Tor >= 0.2.0.3-alpha */ 00122 QStringList bridges = localValue(SETTING_BRIDGE_LIST).toStringList(); 00123 if (getUseBridges() && !bridges.isEmpty()) { 00124 conf.insert(SETTING_USE_BRIDGES, "1"); 00125 conf.insert(SETTING_UPDATE_BRIDGES, "1"); 00126 foreach (QString bridge, bridges) { 00127 conf.insert(SETTING_BRIDGE_LIST, bridge); 00128 } 00129 } else { 00130 conf.insert(SETTING_USE_BRIDGES, "0"); 00131 conf.insert(SETTING_BRIDGE_LIST, ""); 00132 conf.insert(SETTING_UPDATE_BRIDGES, "0"); 00133 } 00134 } 00135 return torControl()->setConf(conf, errmsg); 00136 } 00137 00138 /** Returns true if we need to set ReachableAddresses because we're behind a 00139 * restrictive firewall that limits the ports Tor can connect to. */ 00140 bool 00141 NetworkSettings::getFascistFirewall() 00142 { 00143 return localValue(SETTING_FASCIST_FIREWALL).toBool(); 00144 } 00145 00146 /** Sets to <b>fascistFirewall</b> whether Tor should only create outgoing 00147 * connections to the list of ports specified in setReachablePorts(). 00148 * \sa setReachablePorts() */ 00149 void 00150 NetworkSettings::setFascistFirewall(bool fascistFirewall) 00151 { 00152 setValue(SETTING_FASCIST_FIREWALL, fascistFirewall); 00153 } 00154 00155 /** Returns a list of ports to be specified in ReachableAddresses. */ 00156 QList<quint16> 00157 NetworkSettings::getReachablePorts() 00158 { 00159 QList<quint16> reachablePorts; 00160 QStringList lineList; 00161 bool ok; 00162 00163 lineList = value(SETTING_REACHABLE_ADDRESSES).toStringList(); 00164 foreach (QString line, lineList) { 00165 foreach (QString address, line.split(",", QString::SkipEmptyParts)) { 00166 QStringList parts = address.split(":"); 00167 if (parts.size() >= 2) { 00168 quint16 port = parts.at(1).toUInt(&ok); 00169 if (ok) 00170 reachablePorts << port; 00171 } 00172 } 00173 } 00174 return reachablePorts; 00175 } 00176 00177 /** Sets the list of ports that will be specified in ReachableAddresses to 00178 * <b>reachablePorts</b>. */ 00179 void 00180 NetworkSettings::setReachablePorts(const QList<quint16> &reachablePorts) 00181 { 00182 if (!reachablePorts.isEmpty()) { 00183 QStringList portList; 00184 foreach (quint16 port, reachablePorts) { 00185 portList << "*:" + QString::number(port); 00186 } 00187 setValue(SETTING_REACHABLE_ADDRESSES, portList); 00188 } 00189 } 00190 00191 /** Returns the proxy type Tor is using, or NoProxy if it makes direct 00192 * connections. */ 00193 NetworkSettings::ProxyType 00194 NetworkSettings::getProxyType() 00195 { 00196 QString type = value(SETTING_PROXY_TYPE).toString(); 00197 return proxyTypeFromString(type); 00198 } 00199 00200 /** Set the type of proxy Tor should use to <b>type</b>. */ 00201 void 00202 NetworkSettings::setProxyType(ProxyType type) 00203 { 00204 setValue(SETTING_PROXY_TYPE, proxyTypeToString(type)); 00205 } 00206 00207 /** Returns the address of the proxy server Tor makes connections through. */ 00208 QString 00209 NetworkSettings::getProxyAddress() 00210 { 00211 return value(SETTING_PROXY_ADDRESS).toString(); 00212 } 00213 00214 /** Sets the proxy address and port to <b>addr</b>. */ 00215 void 00216 NetworkSettings::setProxyAddress(const QString &addr) 00217 { 00218 setValue(SETTING_PROXY_ADDRESS, addr); 00219 } 00220 00221 /** Returns the username used to login to the proxy server. */ 00222 QString 00223 NetworkSettings::getProxyUsername() 00224 { 00225 return value(SETTING_PROXY_USERNAME).toString(); 00226 } 00227 00228 /** Sets the proxy server username to <b>user</b>. */ 00229 void 00230 NetworkSettings::setProxyUsername(const QString &user) 00231 { 00232 setValue(SETTING_PROXY_USERNAME, user); 00233 } 00234 00235 /** Returns the password used to login to the proxy server. */ 00236 QString 00237 NetworkSettings::getProxyPassword() 00238 { 00239 return value(SETTING_PROXY_PASSWORD).toString(); 00240 } 00241 00242 /** Sets the proxy server password to <b>pass</b>. */ 00243 void 00244 NetworkSettings::setProxyPassword(const QString &pass) 00245 { 00246 setValue(SETTING_PROXY_PASSWORD, pass); 00247 } 00248 00249 /** Returns true if Tor should try to use bridge nodes to access the Tor 00250 * network. */ 00251 bool 00252 NetworkSettings::getUseBridges() 00253 { 00254 return value(SETTING_USE_BRIDGES).toBool(); 00255 } 00256 00257 /** Sets to <b>useBridges</b> whether Tor should try to use bridge nodes 00258 * to access the Tor network. */ 00259 void 00260 NetworkSettings::setUseBridges(bool useBridges) 00261 { 00262 setValue(SETTING_USE_BRIDGES, useBridges); 00263 } 00264 00265 /** Returns a list of bridge nodes Tor should use. */ 00266 QStringList 00267 NetworkSettings::getBridgeList() 00268 { 00269 return value(SETTING_BRIDGE_LIST).toStringList(); 00270 } 00271 00272 /** Sets to <b>bridgeList</b> the list of bridge nodes Tor should use. */ 00273 void 00274 NetworkSettings::setBridgeList(const QStringList &bridgeList) 00275 { 00276 setValue(SETTING_BRIDGE_LIST, bridgeList); 00277 } 00278 00279 /** Returns true if Tor is configured to try to tunnel its directory 00280 * connections through a one-hop circuit. */ 00281 bool 00282 NetworkSettings::getTunnelDirConns() 00283 { 00284 return value(SETTING_TUNNEL_DIR_CONNS).toBool(); 00285 } 00286 00287 /** Converts the ProxyType <b>type</b> to a string to store in the 00288 * configuration file. */ 00289 QString 00290 NetworkSettings::proxyTypeToString(ProxyType type) 00291 { 00292 QString ret; 00293 00294 switch (type) { 00295 case Socks4Proxy: 00296 ret = "socks4"; 00297 break; 00298 case Socks5Proxy: 00299 ret = "socks5"; 00300 break; 00301 case HttpHttpsProxy: 00302 ret = "httphttps"; 00303 break; 00304 case NoProxy: 00305 default: 00306 ret = "none"; 00307 break; 00308 } 00309 00310 return ret; 00311 } 00312 00313 /** Converts the proxy type string <b>type</b> to its ProxyType counterpart. */ 00314 NetworkSettings::ProxyType 00315 NetworkSettings::proxyTypeFromString(const QString &type) 00316 { 00317 QString str = type.toLower(); 00318 00319 if (str == "socks4") 00320 return Socks4Proxy; 00321 if (str == "socks5") 00322 return Socks5Proxy; 00323 if (str == "httphttps") 00324 return HttpHttpsProxy; 00325 00326 return NoProxy; 00327 } 00328