Vidalia  0.2.21
ServerSettings.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 ServerSettings.cpp
13 ** \brief Settings for running a Tor server
14 */
15 
16 #include "config.h"
17 #include "ServerSettings.h"
18 #include "TorSettings.h"
19 #include "TorControl.h"
20 #ifdef USE_MINIUPNPC
21 #include "UPNPControl.h"
22 #endif
23 
24 #include "net.h"
25 #include "stringutil.h"
26 
27 #include <QHostInfo>
28 
29 /** Define the set of characters that are valid in a nickname. */
30 #define VALID_NICKNAME_CHARS \
31  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
32 /** Define the maximum length of a server's nickname. */
33 #define MAX_NICKNAME_LEN 19
34 
35 /* Server configuration settings */
36 #define SETTING_ENABLED "Enabled"
37 #define SETTING_DIRMIRROR "DirectoryMirror"
38 #define SETTING_NICKNAME "Nickname"
39 #define SETTING_ORPORT "ORPort"
40 #define SETTING_DIRPORT "DirPort"
41 #define SETTING_CONTACT "ContactInfo"
42 #define SETTING_EXITPOLICY "ExitPolicy"
43 #define SETTING_BANDWIDTH_RATE "BandwidthRate"
44 #define SETTING_BANDWIDTH_BURST "BandwidthBurst"
45 #define SETTING_BRIDGE_RELAY "BridgeRelay"
46 #define SETTING_NONEXIT_RELAY "NonExitRelay"
47 #define SETTING_ENABLE_UPNP "EnableUPnP"
48 #define SETTING_RELAY_BANDWIDTH_RATE "RelayBandwidthRate"
49 #define SETTING_RELAY_BANDWIDTH_BURST "RelayBandwidthBurst"
50 #define SETTING_PUBLISH_SERVER_DESCRIPTOR "PublishServerDescriptor"
51 
52 
53 /** Constructor.
54  * \param torControl a TorControl object used to read and apply the server
55  * configuration settings.
56  */
58 : AbstractTorSettings("Server", torControl)
59 {
62 #if defined(Q_OS_WIN32)
64 #else
66 #endif
68  setDefault(SETTING_NICKNAME, "Unnamed");
69  setDefault(SETTING_CONTACT, "<you@example.com>");
75  ExitPolicy(ExitPolicy::Middleman).toString());
79 }
80 
81 /** Returns a QHash of Tor-recognizable configuratin keys to their current
82  * values. */
83 QHash<QString, QString>
85 {
86  QHash<QString, QString> conf;
87  quint32 torVersion = torControl()->getTorVersion();
88 
89  /* Server Nickname */
90  conf.insert(SETTING_NICKNAME,
92  : ""));
93  /* Server ORPort */
94  conf.insert(SETTING_ORPORT,
96  : "0"));
97  /* Server DirPort */
98  conf.insert(SETTING_DIRPORT,
100  : "0"));
101  /* Server Exit Policy */
102  conf.insert(SETTING_EXITPOLICY,
103  ((isBridgeEnabled() || isNonExitEnabled()) ? "reject *:*"
104  : localValue(SETTING_EXITPOLICY).toString()));
105 
106  /* Server bandwidth settings */
107  conf.insert((torVersion >= 0x020001 ? SETTING_RELAY_BANDWIDTH_RATE
109  QString::number(localValue(SETTING_BANDWIDTH_RATE).toUInt()) + " bytes");
110  conf.insert((torVersion >= 0x020001 ? SETTING_RELAY_BANDWIDTH_BURST
112  QString::number(localValue(SETTING_BANDWIDTH_BURST).toUInt()) + " bytes");
113 
114  /* Server Contact Information */
115  QString contact =
116  localValue(SETTING_CONTACT).toString().trimmed();
117  QString defaultContact = defaultValue(SETTING_CONTACT).toString();
118  if ((contact == defaultContact) ||
119  (contact == scrub_email_addr(defaultContact))) {
120  /* Only set the contact info if they put something non-default there */
121  contact = "";
122  }
123  conf.insert(SETTING_CONTACT, scrub_email_addr(contact));
124 
125  /* Set if we're a bridge relay */
126  if (isBridgeEnabled()) {
127  conf.insert(SETTING_BRIDGE_RELAY, "1");
129  publishServerDescriptor() ? "1" : "0");
130  } else {
131  conf.insert(SETTING_BRIDGE_RELAY, "0");
132  conf.insert(SETTING_PUBLISH_SERVER_DESCRIPTOR, "1");
133  }
134  return conf;
135 }
136 
137 /** Applies the current server configuration settings to Tor. If <b>errmsg</b>
138  * is specified and an error occurs while applying the settings, it will be
139  * set to a string describing the error. */
140 bool
141 ServerSettings::apply(QString *errmsg)
142 {
143  bool rc;
144 
146 
147  if (isServerEnabled()) {
148  rc = torControl()->setConf(confValues(), errmsg);
149  } else {
150  QStringList resetKeys;
151  quint32 torVersion = torControl()->getTorVersion();
152  resetKeys << SETTING_ORPORT
154  << SETTING_DIRPORT
155  << SETTING_CONTACT
159  if (torVersion >= 0x020001) {
160  resetKeys << SETTING_RELAY_BANDWIDTH_RATE
162  } else {
163  resetKeys << SETTING_BANDWIDTH_RATE
165  }
166  rc = torControl()->resetConf(resetKeys, errmsg);
167  }
168  return rc;
169 }
170 
171 /* TODO: We should call this periodically, in case the router gets rebooted or forgets its UPnP settings */
172 /* TODO: Remove port forwarding when Tor is shutdown or the ORPort changes */
173 /* TODO: init_upnp() will block for up to 2 seconds. We should fire off a thread */
174 
175 /** Configure UPnP device to forward DirPort and ORPort. If enable is
176  * true, will forward ORPort and DirPort; otherwise will remove exising
177  * port mappings */
178 void
180 {
181 #ifdef USE_MINIUPNPC
182  quint16 ORPort, DirPort;
183 
184  // This is how the tickbox should control UPNP
185  if (!isUpnpEnabled())
186  return;
187 
188  ORPort = getORPort();
189  if (!isServerEnabled())
190  ORPort = 0;
191 
192  DirPort = getDirPort();
193  if (!isServerEnabled() || !isDirectoryMirror())
194  DirPort = 0;
195 
196  UPNPControl *control = UPNPControl::instance();
197  control->setDesiredState(DirPort, ORPort);
198 #endif
199 }
200 
201 void
203 {
204 #ifdef USE_MINIUPNPC
206 #endif
207 }
208 
209 /** Virtual method called when we retrieve a server-related setting from Tor.
210  * Currently this just translates BandwidthFoo to RelayBandwidthFoo when
211  * appropriate. */
212 QVariant
213 ServerSettings::torValue(const QString &key) const
214 {
215  if (torControl()->getTorVersion() >= 0x020001) {
216  if (key == SETTING_BANDWIDTH_RATE)
218  else if (key == SETTING_BANDWIDTH_BURST)
220  }
221  return AbstractTorSettings::torValue(key);
222 }
223 
224 /** Enables or disables running Tor as a server.
225  * \param enable Whether to enable or disable the Tor server.
226  */
227 void
229 {
230  setValue(SETTING_ENABLED, enable);
231 }
232 
233 /** Returns true if Tor is currently configured to run as a Tor server. If Tor
234  * is running, we will check whether it has an ORPort defined. Otherwise, we
235  * will use our saved settings. */
236 bool
238 {
239  QString orPort;
240  if (torControl()->isConnected() && !changedSinceLastApply()) {
241  if (torControl()->getConf(SETTING_ORPORT, orPort))
242  return (orPort.toUInt() > 0);
243  }
244  return localValue(SETTING_ENABLED).toBool();
245 }
246 
247 /** Sets to <b>enabled</b> whether Tor should be a bridge node when acting as
248  * a server. */
249 void
251 {
252  setValue(SETTING_BRIDGE_RELAY, enabled);
253 }
254 
255 /** Returns true if Tor is configured to act as a bridge node. */
256 bool
258 {
259  return value(SETTING_BRIDGE_RELAY).toBool() && isServerEnabled();
260 }
261 
262 /** Sets to <b>enabled</b> whether Tor should be a non-exit node when acting as
263  * a server. */
264 void
266 {
268 }
269 
270 /** Returns true if Tor is configured to act as a non-exit node. */
271 bool
273 {
274  return value(SETTING_NONEXIT_RELAY).toBool() && isServerEnabled();
275 }
276 
277 /** Sets the server's ORPort. */
278 void
280 {
281  setValue(SETTING_ORPORT, orPort);
282 }
283 
284 /** Gets the server's current ORPort setting. */
285 quint16
287 {
288  return (quint16)value(SETTING_ORPORT).toUInt();
289 }
290 
291 /** Sets the server's current DirPort. */
292 void
294 {
295  setValue(SETTING_DIRPORT, dirPort);
296 }
297 
298 /** Gets the server's current DirPort. */
299 quint16
301 {
302  return (quint16)value(SETTING_DIRPORT).toUInt();
303 }
304 
305 /** Sets the server's nickname. */
306 void
308 {
309  setValue(SETTING_NICKNAME, nickname);
310 }
311 
312 /** Gets the server's nickname. */
313 QString
315 {
316  QString nickname = value(SETTING_NICKNAME).toString();
317  /* Ensure the nickname contains only valid characters and is not too long. */
318  return ensure_valid_chars(nickname,
320 }
321 
322 /** Sets the server's contact information. */
323 void
325 {
326  setValue(SETTING_CONTACT, contact);
327 }
328 
329 /** Gets the server's contact information. */
330 QString
332 {
333  return value(SETTING_CONTACT).toString();
334 }
335 
336 /** Returns whether this server will act as a directory mirror or not. */
337 bool
339 {
340  return localValue(SETTING_DIRMIRROR).toBool();
341 }
342 
343 /** Sets whether this server will act as a directory mirror. */
344 void
346 {
347  setValue(SETTING_DIRMIRROR, mirror);
348 }
349 
350 /** Returns the exit policy for this server. */
353 {
354  return ExitPolicy(value(SETTING_EXITPOLICY).toString());
355 }
356 
357 /** Sets the exit policy for this server. */
358 void
360 {
361  setValue(SETTING_EXITPOLICY, exitPolicy.toString());
362 }
363 
364 /** Returns the long-term average bandwidth rate (in KB/s) for this server. */
365 quint32
367 {
368  return value(SETTING_BANDWIDTH_RATE).toUInt();
369 }
370 
371 /** Sets the long-term average bandwidth rate (in KB/s) for this server. */
372 void
374 {
376 }
377 
378 /** Returns the maximum bandwidth burst rate (in KB/s) for this server. */
379 quint32
381 {
382  return value(SETTING_BANDWIDTH_BURST).toUInt();
383 }
384 
385 /** Sets the maximum bandwidth burst rate (in KB/s) for this server. */
386 void
388 {
390 }
391 
392 /** Sets whether the user's server descriptor will be published or not.
393  * Currently this only affects publishing of bridge descriptors. If the
394  * user is running a normal relay, its descriptor will always be
395  * published regardless of this setting. */
396 void
398 {
399  if (publish)
401  else
403 }
404 
405 /** Returns true if the user's server descriptor will be published to the
406  * appropriate authorities. */
407 bool
409 {
410  return (value(SETTING_PUBLISH_SERVER_DESCRIPTOR).toString() != "0");
411 }
412 
413 /** Returns true if UPnP support is available and enabled. */
414 bool
416 {
417 #if defined(USE_MINIUPNPC)
418  return localValue(SETTING_ENABLE_UPNP).toBool();
419 #else
420  return false;
421 #endif
422 }
423 
424 /** Sets whether Vidalia should try to configure port forwarding using UPnP.
425  * If Vidalia was compiled without UPnP support, this method has no effect. */
426 void
428 {
429 #if defined(USE_MINIUPNPC)
430  setValue(SETTING_ENABLE_UPNP, enabled);
431 #endif
432 }
433