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