Vidalia  0.2.21
NetworkSettings.cpp
Go to the documentation of this file.
1 /*
2 ** This file is part of Vidalia, and is subject to the license terms in the
3 ** LICENSE file, found in the top level directory of this distribution. If you
4 ** did not receive the LICENSE file with this file, you may obtain it from the
5 ** Vidalia source package distributed by the Vidalia Project at
6 ** http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
7 ** including this file, may be copied, modified, propagated, or distributed
8 ** except according to the terms described in the LICENSE file.
9 */
10 
11 /*
12 ** \file NetworkSettings.cpp
13 ** \brief Settings for configuring an HTTP/HTTPS proxy or bridges
14 */
15 
16 #include "NetworkSettings.h"
17 #include "TorControl.h"
18 
19 #define SETTING_FASCIST_FIREWALL "FascistFirewall"
20 #define SETTING_REACHABLE_ADDRESSES "ReachableAddresses"
21 
22 /* Vidalia-specific proxy options */
23 #define SETTING_PROXY_TYPE "ProxyType"
24 #define SETTING_PROXY_ADDRESS "ProxyAddress"
25 #define SETTING_PROXY_USERNAME "ProxyUsername"
26 #define SETTING_PROXY_PASSWORD "ProxyPassword"
27 
28 /* Tor's proxy options */
29 #define SETTING_HTTPS_PROXY "HttpsProxy"
30 #define SETTING_HTTPS_PROXY_AUTH "HttpsProxyAuthenticator"
31 #define SETTING_SOCKS4_PROXY "Socks4Proxy"
32 #define SETTING_SOCKS5_PROXY "Socks5Proxy"
33 #define SETTING_SOCKS5_USERNAME "Socks5ProxyUsername"
34 #define SETTING_SOCKS5_PASSWORD "Socks5ProxyPassword"
35 
36 #define SETTING_USE_BRIDGES "UseBridges"
37 #define SETTING_BRIDGE_LIST "Bridge"
38 #define SETTING_UPDATE_BRIDGES "UpdateBridgesFromAuthority"
39 #define SETTING_TUNNEL_DIR_CONNS "TunnelDirConns"
40 #define SETTING_PREFER_TUNNELED_DIR_CONNS "PreferTunneledDirConns"
41 
42 
43 /** Default constructor */
45 : AbstractTorSettings("Network", torControl)
46 {
52  setDefault(SETTING_BRIDGE_LIST, QStringList());
56  QStringList() << "*:80" << "*:443");
57 }
58 
59 /** Applies the current network configuration settings to Tor. If
60  * <b>errmsg</b> is specified and an error occurs while applying the settings,
61  * it will be set to a string describing the error. */
62 bool
63 NetworkSettings::apply(QString *errmsg)
64 {
65  QMultiHash<QString, QString> conf;
66  quint32 torVersion = torControl()->getTorVersion();
67 
68  conf.insert(SETTING_REACHABLE_ADDRESSES,
70  localValue(SETTING_REACHABLE_ADDRESSES).toStringList().join(",") : ""));
71 
72  QString socks4, socks5, http, https;
73  QString addr, user, pass, auth;
74 
75  addr = localValue(SETTING_PROXY_ADDRESS).toString();
76  user = localValue(SETTING_PROXY_USERNAME).toString();
77  pass = localValue(SETTING_PROXY_PASSWORD).toString();
78 
79  if (!user.isEmpty() || !pass.isEmpty())
80  auth = QString("%1:%2").arg(user).arg(pass);
81 
82  switch (getProxyType()) {
83  case NoProxy:
84  break;
85  case Socks4Proxy:
86  socks4 = addr;
87  break;
88  case Socks5Proxy:
89  socks5 = addr;
90  break;
91  case HttpHttpsProxy:
92  http = addr;
93  https = http;
94  break;
95  }
96 
97  if (torVersion >= 0x020201) {
98  /* SOCKS support was implemented in 0.2.2.1 */
99  conf.insert(SETTING_SOCKS4_PROXY, socks4);
100  conf.insert(SETTING_SOCKS5_PROXY, socks5);
101  conf.insert(SETTING_SOCKS5_USERNAME, user);
102  conf.insert(SETTING_SOCKS5_PASSWORD, pass);
103  }
104 
105  conf.insert(SETTING_HTTPS_PROXY, https);
106  conf.insert(SETTING_HTTPS_PROXY_AUTH, auth);
107 
108  if (getUseBridges()) {
109  /* We want to always enable TunnelDirConns and friends when using
110  * bridge relays. */
111  conf.insert(SETTING_TUNNEL_DIR_CONNS, "1");
112  conf.insert(SETTING_PREFER_TUNNELED_DIR_CONNS, "1");
113  } else if (torVersion <= 0x020021) {
114  /* TunnelDirConns is enabled by default on Tor >= 0.2.0.22-rc, so don't
115  * disable it if our Tor is recent enough. */
116  conf.insert(SETTING_TUNNEL_DIR_CONNS, "0");
117  conf.insert(SETTING_PREFER_TUNNELED_DIR_CONNS, "0");
118  }
119 
120  if (torVersion >= 0x020003) {
121  /* Do the bridge stuff only on Tor >= 0.2.0.3-alpha */
122  QStringList bridges = localValue(SETTING_BRIDGE_LIST).toStringList();
123  if (getUseBridges() && !bridges.isEmpty()) {
124  conf.insert(SETTING_USE_BRIDGES, "1");
125  conf.insert(SETTING_UPDATE_BRIDGES, "1");
126  foreach (QString bridge, bridges) {
127  conf.insert(SETTING_BRIDGE_LIST, bridge);
128  }
129  } else {
130  conf.insert(SETTING_USE_BRIDGES, "0");
131  conf.insert(SETTING_BRIDGE_LIST, "");
132  conf.insert(SETTING_UPDATE_BRIDGES, "0");
133  }
134  }
135  return torControl()->setConf(conf, errmsg);
136 }
137 
138 /** Returns true if we need to set ReachableAddresses because we're behind a
139  * restrictive firewall that limits the ports Tor can connect to. */
140 bool
142 {
143  return localValue(SETTING_FASCIST_FIREWALL).toBool();
144 }
145 
146 /** Sets to <b>fascistFirewall</b> whether Tor should only create outgoing
147  * connections to the list of ports specified in setReachablePorts().
148  * \sa setReachablePorts() */
149 void
151 {
152  setValue(SETTING_FASCIST_FIREWALL, fascistFirewall);
153 }
154 
155 /** Returns a list of ports to be specified in ReachableAddresses. */
156 QList<quint16>
158 {
159  QList<quint16> reachablePorts;
160  QStringList lineList;
161  bool ok;
162 
163  lineList = value(SETTING_REACHABLE_ADDRESSES).toStringList();
164  foreach (QString line, lineList) {
165  foreach (QString address, line.split(",", QString::SkipEmptyParts)) {
166  QStringList parts = address.split(":");
167  if (parts.size() >= 2) {
168  quint16 port = parts.at(1).toUInt(&ok);
169  if (ok)
170  reachablePorts << port;
171  }
172  }
173  }
174  return reachablePorts;
175 }
176 
177 /** Sets the list of ports that will be specified in ReachableAddresses to
178  * <b>reachablePorts</b>. */
179 void
180 NetworkSettings::setReachablePorts(const QList<quint16> &reachablePorts)
181 {
182  if (!reachablePorts.isEmpty()) {
183  QStringList portList;
184  foreach (quint16 port, reachablePorts) {
185  portList << "*:" + QString::number(port);
186  }
188  }
189 }
190 
191 /** Returns the proxy type Tor is using, or NoProxy if it makes direct
192  * connections. */
195 {
196  QString type = value(SETTING_PROXY_TYPE).toString();
197  return proxyTypeFromString(type);
198 }
199 
200 /** Set the type of proxy Tor should use to <b>type</b>. */
201 void
203 {
205 }
206 
207 /** Returns the address of the proxy server Tor makes connections through. */
208 QString
210 {
211  return value(SETTING_PROXY_ADDRESS).toString();
212 }
213 
214 /** Sets the proxy address and port to <b>addr</b>. */
215 void
217 {
219 }
220 
221 /** Returns the username used to login to the proxy server. */
222 QString
224 {
225  return value(SETTING_PROXY_USERNAME).toString();
226 }
227 
228 /** Sets the proxy server username to <b>user</b>. */
229 void
231 {
233 }
234 
235 /** Returns the password used to login to the proxy server. */
236 QString
238 {
239  return value(SETTING_PROXY_PASSWORD).toString();
240 }
241 
242 /** Sets the proxy server password to <b>pass</b>. */
243 void
245 {
247 }
248 
249 /** Returns true if Tor should try to use bridge nodes to access the Tor
250  * network. */
251 bool
253 {
254  return value(SETTING_USE_BRIDGES).toBool();
255 }
256 
257 /** Sets to <b>useBridges</b> whether Tor should try to use bridge nodes
258  * to access the Tor network. */
259 void
261 {
262  setValue(SETTING_USE_BRIDGES, useBridges);
263 }
264 
265 /** Returns a list of bridge nodes Tor should use. */
266 QStringList
268 {
269  return value(SETTING_BRIDGE_LIST).toStringList();
270 }
271 
272 /** Sets to <b>bridgeList</b> the list of bridge nodes Tor should use. */
273 void
274 NetworkSettings::setBridgeList(const QStringList &bridgeList)
275 {
276  setValue(SETTING_BRIDGE_LIST, bridgeList);
277 }
278 
279 /** Returns true if Tor is configured to try to tunnel its directory
280  * connections through a one-hop circuit. */
281 bool
283 {
284  return value(SETTING_TUNNEL_DIR_CONNS).toBool();
285 }
286 
287 /** Converts the ProxyType <b>type</b> to a string to store in the
288  * configuration file. */
289 QString
291 {
292  QString ret;
293 
294  switch (type) {
295  case Socks4Proxy:
296  ret = "socks4";
297  break;
298  case Socks5Proxy:
299  ret = "socks5";
300  break;
301  case HttpHttpsProxy:
302  ret = "httphttps";
303  break;
304  case NoProxy:
305  default:
306  ret = "none";
307  break;
308  }
309 
310  return ret;
311 }
312 
313 /** Converts the proxy type string <b>type</b> to its ProxyType counterpart. */
316 {
317  QString str = type.toLower();
318 
319  if (str == "socks4")
320  return Socks4Proxy;
321  if (str == "socks5")
322  return Socks5Proxy;
323  if (str == "httphttps")
324  return HttpHttpsProxy;
325 
326  return NoProxy;
327 }
328