ServerSettings.cpp

Go to the documentation of this file.
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 ServerSettings.cpp
00013 ** \version $Id: ServerSettings.cpp 4143 2009-10-12 00:59:22Z edmanm $
00014 ** \brief Settings for running a Tor server
00015 */
00016 
00017 #include "config.h"
00018 #include "ServerSettings.h"
00019 #include "TorSettings.h"
00020 #ifdef USE_MINIUPNPC
00021 #include "UPNPControl.h"
00022 #endif
00023 
00024 #include "net.h"
00025 #include "stringutil.h"
00026 
00027 #include <QHostInfo>
00028 
00029 /** Define the set of characters that are valid in a nickname. */
00030 #define VALID_NICKNAME_CHARS \
00031   "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
00032 /** Define the maximum length of a server's nickname. */
00033 #define MAX_NICKNAME_LEN   19
00034 
00035 /* Server configuration settings */
00036 #define SETTING_ENABLED         "Enabled"
00037 #define SETTING_DIRMIRROR       "DirectoryMirror"
00038 #define SETTING_NICKNAME        "Nickname"
00039 #define SETTING_ORPORT          "ORPort"
00040 #define SETTING_DIRPORT         "DirPort"
00041 #define SETTING_CONTACT         "ContactInfo"
00042 #define SETTING_EXITPOLICY      "ExitPolicy"
00043 #define SETTING_BANDWIDTH_RATE  "BandwidthRate"
00044 #define SETTING_BANDWIDTH_BURST "BandwidthBurst"
00045 #define SETTING_BRIDGE_RELAY    "BridgeRelay"
00046 #define SETTING_ENABLE_UPNP     "EnableUPnP"
00047 #define SETTING_RELAY_BANDWIDTH_RATE   "RelayBandwidthRate"
00048 #define SETTING_RELAY_BANDWIDTH_BURST  "RelayBandwidthBurst"
00049 #define SETTING_PUBLISH_SERVER_DESCRIPTOR "PublishServerDescriptor"
00050 
00051 
00052 /** Constructor.
00053  * \param torControl a TorControl object used to read and apply the server
00054  * configuration settings.
00055  */
00056 ServerSettings::ServerSettings(TorControl *torControl)
00057 : AbstractTorSettings("Server", torControl)
00058 {
00059   setDefault(SETTING_ENABLED,       false);
00060   setDefault(SETTING_DIRMIRROR,     true);
00061 #if defined(Q_OS_WIN32)
00062   setDefault(SETTING_ORPORT,        443);
00063 #else
00064   setDefault(SETTING_ORPORT,        9001);
00065 #endif
00066   setDefault(SETTING_DIRPORT,       9030);
00067   setDefault(SETTING_NICKNAME,      "Unnamed");
00068   setDefault(SETTING_CONTACT,       "<you@example.com>");
00069   setDefault(SETTING_BANDWIDTH_RATE,        5242880);
00070   setDefault(SETTING_RELAY_BANDWIDTH_RATE,  5242880);
00071   setDefault(SETTING_BANDWIDTH_BURST,       10485760);
00072   setDefault(SETTING_RELAY_BANDWIDTH_BURST, 10485760);
00073   setDefault(SETTING_EXITPOLICY,
00074     ExitPolicy(ExitPolicy::Default).toString());
00075   setDefault(SETTING_ENABLE_UPNP, false); 
00076   setDefault(SETTING_BRIDGE_RELAY, false);
00077   setDefault(SETTING_PUBLISH_SERVER_DESCRIPTOR, "1");
00078 }
00079 
00080 /** Returns a QHash of Tor-recognizable configuratin keys to their current
00081  * values. */
00082 QHash<QString, QString>
00083 ServerSettings::confValues()
00084 {
00085   QHash<QString, QString> conf;
00086   quint32 torVersion = torControl()->getTorVersion();
00087 
00088   /* Server Nickname */
00089   conf.insert(SETTING_NICKNAME,
00090     (isServerEnabled() ? localValue(SETTING_NICKNAME).toString()
00091                        : ""));
00092   /* Server ORPort */
00093   conf.insert(SETTING_ORPORT,
00094     (isServerEnabled() ? localValue(SETTING_ORPORT).toString()
00095                        : "0"));
00096   /* Server DirPort */
00097   conf.insert(SETTING_DIRPORT, 
00098     (isDirectoryMirror() ? localValue(SETTING_DIRPORT).toString() 
00099                          : "0"));
00100   /* Server Exit Policy */
00101   conf.insert(SETTING_EXITPOLICY, 
00102     (isBridgeEnabled() ? "reject *:*"
00103                        : localValue(SETTING_EXITPOLICY).toString()));
00104   
00105   /* Server bandwidth settings */
00106   conf.insert((torVersion >= 0x020001 ? SETTING_RELAY_BANDWIDTH_RATE 
00107                                       : SETTING_BANDWIDTH_RATE),
00108     QString::number(localValue(SETTING_BANDWIDTH_RATE).toUInt()) + " bytes");
00109   conf.insert((torVersion >= 0x020001 ? SETTING_RELAY_BANDWIDTH_BURST
00110                                       : SETTING_BANDWIDTH_BURST),
00111     QString::number(localValue(SETTING_BANDWIDTH_BURST).toUInt()) + " bytes");
00112     
00113   /* Server Contact Information */
00114   QString contact = 
00115     localValue(SETTING_CONTACT).toString().trimmed();
00116   QString defaultContact = defaultValue(SETTING_CONTACT).toString();
00117   if ((contact == defaultContact) ||
00118       (contact == scrub_email_addr(defaultContact))) {
00119     /* Only set the contact info if they put something non-default there */
00120     contact = "";
00121   }
00122   conf.insert(SETTING_CONTACT, scrub_email_addr(contact));
00123   
00124   /* Set if we're a bridge relay */
00125   if (isBridgeEnabled()) {
00126     conf.insert(SETTING_BRIDGE_RELAY, "1");
00127     conf.insert(SETTING_PUBLISH_SERVER_DESCRIPTOR,
00128                 publishServerDescriptor() ? "1" : "0");
00129   } else {
00130     conf.insert(SETTING_BRIDGE_RELAY, "0");
00131     conf.insert(SETTING_PUBLISH_SERVER_DESCRIPTOR, "1");
00132   }
00133   return conf;
00134 }
00135 
00136 /** Applies the current server configuration settings to Tor. If <b>errmsg</b>
00137  * is specified and an error occurs while applying the settings, it will be 
00138  * set to a string describing the error. */
00139 bool
00140 ServerSettings::apply(QString *errmsg)
00141 {
00142   bool rc;
00143 
00144   configurePortForwarding();
00145 
00146   if (isServerEnabled()) {
00147     rc = torControl()->setConf(confValues(), errmsg);
00148   } else { 
00149     QStringList resetKeys;
00150     quint32 torVersion = torControl()->getTorVersion();
00151     resetKeys << SETTING_ORPORT 
00152               << SETTING_NICKNAME 
00153               << SETTING_DIRPORT
00154               << SETTING_CONTACT
00155               << SETTING_EXITPOLICY
00156               << SETTING_BRIDGE_RELAY
00157               << SETTING_PUBLISH_SERVER_DESCRIPTOR;
00158     if (torVersion >= 0x020001) {
00159       resetKeys << SETTING_RELAY_BANDWIDTH_RATE
00160                 << SETTING_RELAY_BANDWIDTH_BURST;
00161     } else {
00162       resetKeys << SETTING_BANDWIDTH_RATE
00163                 << SETTING_BANDWIDTH_BURST;
00164     }
00165     rc = torControl()->resetConf(resetKeys, errmsg);
00166   }
00167   return rc;
00168 }
00169 
00170 /* TODO: We should call this periodically, in case the router gets rebooted or forgets its UPnP settings */
00171 /* TODO: Remove port forwarding when Tor is shutdown or the ORPort changes */
00172 /* TODO: init_upnp() will block for up to 2 seconds. We should fire off a thread */
00173 
00174 /** Configure UPnP device to forward DirPort and ORPort. If enable is
00175  * true, will forward ORPort and DirPort; otherwise will remove exising
00176  * port mappings */
00177 void
00178 ServerSettings::configurePortForwarding()
00179 {
00180 #ifdef USE_MINIUPNPC
00181   quint16 ORPort, DirPort;
00182 
00183   // This is how the tickbox should control UPNP
00184   if (!isUpnpEnabled())
00185     return;
00186 
00187   ORPort = getORPort();
00188   if (!isServerEnabled())
00189     ORPort = 0;
00190 
00191   DirPort = getDirPort();
00192   if (!isServerEnabled() || !isDirectoryMirror())
00193     DirPort = 0;
00194 
00195   UPNPControl *control = UPNPControl::instance();
00196   control->setDesiredState(DirPort, ORPort);
00197 #endif
00198 }
00199 
00200 void
00201 ServerSettings::cleanupPortForwarding()
00202 {
00203 #ifdef USE_MINIUPNPC
00204   UPNPControl::cleanup();
00205 #endif
00206 }
00207 
00208 /** Virtual method called when we retrieve a server-related setting from Tor.
00209  * Currently this just translates BandwidthFoo to RelayBandwidthFoo when
00210  * appropriate. */
00211 QVariant
00212 ServerSettings::torValue(const QString &key) const
00213 {
00214   if (torControl()->getTorVersion() >= 0x020001) {
00215     if (key == SETTING_BANDWIDTH_RATE)
00216       return AbstractTorSettings::torValue(SETTING_RELAY_BANDWIDTH_RATE);
00217     else if (key == SETTING_BANDWIDTH_BURST)
00218       return AbstractTorSettings::torValue(SETTING_RELAY_BANDWIDTH_BURST);
00219   }
00220   return AbstractTorSettings::torValue(key);
00221 }
00222 
00223 /** Enables or disables running Tor as a server. 
00224  * \param enable Whether to enable or disable the Tor server. 
00225  */
00226 void
00227 ServerSettings::setServerEnabled(bool enable)
00228 {
00229   setValue(SETTING_ENABLED, enable);
00230 }
00231 
00232 /** Returns true if Tor is currently configured to run as a Tor server. If Tor
00233  * is running, we will check whether it has an ORPort defined. Otherwise, we
00234  * will use our saved settings. */
00235 bool
00236 ServerSettings::isServerEnabled()
00237 {
00238   QString orPort;
00239   if (torControl()->isConnected() && !changedSinceLastApply()) {
00240     if (torControl()->getConf(SETTING_ORPORT, orPort))
00241       return (orPort.toUInt() > 0);
00242   }
00243   return localValue(SETTING_ENABLED).toBool();
00244 }
00245 
00246 /** Sets to <b>enabled</b> whether Tor should be a bridge node when acting as
00247  * a server. */
00248 void
00249 ServerSettings::setBridgeEnabled(bool enabled)
00250 {
00251   setValue(SETTING_BRIDGE_RELAY, enabled);
00252 }
00253 
00254 /** Returns true if Tor is configured to act as a bridge node. */
00255 bool
00256 ServerSettings::isBridgeEnabled()
00257 {
00258   return value(SETTING_BRIDGE_RELAY).toBool() && isServerEnabled();
00259 }
00260 
00261 /** Sets the server's ORPort. */
00262 void
00263 ServerSettings::setORPort(quint16 orPort)
00264 {
00265   setValue(SETTING_ORPORT, orPort);
00266 }
00267 
00268 /** Gets the server's current ORPort setting. */
00269 quint16
00270 ServerSettings::getORPort()
00271 {
00272   return (quint16)value(SETTING_ORPORT).toUInt();
00273 }
00274 
00275 /** Sets the server's current DirPort. */
00276 void
00277 ServerSettings::setDirPort(quint16 dirPort)
00278 {
00279   setValue(SETTING_DIRPORT, dirPort);
00280 }
00281 
00282 /** Gets the server's current DirPort. */
00283 quint16
00284 ServerSettings::getDirPort()
00285 {
00286   return (quint16)value(SETTING_DIRPORT).toUInt();
00287 }
00288 
00289 /** Sets the server's nickname. */
00290 void
00291 ServerSettings::setNickname(QString nickname)
00292 {
00293   setValue(SETTING_NICKNAME, nickname);
00294 }
00295 
00296 /** Gets the server's nickname. */
00297 QString
00298 ServerSettings::getNickname()
00299 {
00300   QString nickname = value(SETTING_NICKNAME).toString();
00301   /* Ensure the nickname contains only valid characters and is not too long. */
00302   return ensure_valid_chars(nickname, 
00303                             VALID_NICKNAME_CHARS).left(MAX_NICKNAME_LEN);
00304 }
00305 
00306 /** Sets the server's contact information. */
00307 void
00308 ServerSettings::setContactInfo(QString contact)
00309 {
00310   setValue(SETTING_CONTACT, contact);
00311 }
00312 
00313 /** Gets the server's contact information. */
00314 QString
00315 ServerSettings::getContactInfo()
00316 {
00317   return value(SETTING_CONTACT).toString();
00318 }
00319 
00320 /** Returns whether this server will act as a directory mirror or not. */
00321 bool
00322 ServerSettings::isDirectoryMirror()
00323 {
00324   return localValue(SETTING_DIRMIRROR).toBool();
00325 }
00326 
00327 /** Sets whether this server will act as a directory mirror. */
00328 void
00329 ServerSettings::setDirectoryMirror(bool mirror)
00330 {
00331   setValue(SETTING_DIRMIRROR, mirror);
00332 }
00333 
00334 /** Returns the exit policy for this server. */
00335 ExitPolicy
00336 ServerSettings::getExitPolicy()
00337 {
00338   return ExitPolicy(value(SETTING_EXITPOLICY).toString());
00339 }
00340 
00341 /** Sets the exit policy for this server. */
00342 void
00343 ServerSettings::setExitPolicy(ExitPolicy &exitPolicy)
00344 {
00345   setValue(SETTING_EXITPOLICY, exitPolicy.toString());
00346 }
00347 
00348 /** Returns the long-term average bandwidth rate (in KB/s) for this server. */
00349 quint32
00350 ServerSettings::getBandwidthAvgRate()
00351 {
00352   return value(SETTING_BANDWIDTH_RATE).toUInt();
00353 }
00354 
00355 /** Sets the long-term average bandwidth rate (in KB/s) for this server. */
00356 void
00357 ServerSettings::setBandwidthAvgRate(quint32 rate)
00358 {
00359   setValue(SETTING_BANDWIDTH_RATE, rate);
00360 }
00361 
00362 /** Returns the maximum bandwidth burst rate (in KB/s) for this server. */
00363 quint32
00364 ServerSettings::getBandwidthBurstRate()
00365 {
00366   return value(SETTING_BANDWIDTH_BURST).toUInt();
00367 }
00368 
00369 /** Sets the maximum bandwidth burst rate (in KB/s) for this server. */
00370 void
00371 ServerSettings::setBandwidthBurstRate(quint32 rate)
00372 {
00373   setValue(SETTING_BANDWIDTH_BURST, rate);
00374 }
00375 
00376 /** Sets whether the user's server descriptor will be published or not.
00377  * Currently this only affects publishing of bridge descriptors. If the
00378  * user is running a normal relay, its descriptor will always be
00379  * published regardless of this setting. */
00380 void
00381 ServerSettings::setPublishServerDescriptor(bool publish)
00382 {
00383   if (publish)
00384     setValue(SETTING_PUBLISH_SERVER_DESCRIPTOR, "1");
00385   else
00386     setValue(SETTING_PUBLISH_SERVER_DESCRIPTOR, "0");
00387 }
00388 
00389 /** Returns true if the user's server descriptor will be published to the
00390  * appropriate authorities. */
00391 bool
00392 ServerSettings::publishServerDescriptor() const
00393 {
00394   return (value(SETTING_PUBLISH_SERVER_DESCRIPTOR).toString() != "0"); 
00395 }
00396 
00397 /** Returns true if UPnP support is available and enabled. */
00398 bool
00399 ServerSettings::isUpnpEnabled()
00400 {
00401 #if defined(USE_MINIUPNPC)
00402   return localValue(SETTING_ENABLE_UPNP).toBool();
00403 #else
00404   return false;
00405 #endif
00406 }
00407 
00408 /** Sets whether Vidalia should try to configure port forwarding using UPnP.
00409  * If Vidalia was compiled without UPnP support, this method has no effect. */
00410 void
00411 ServerSettings::setUpnpEnabled(bool enabled)
00412 {
00413 #if defined(USE_MINIUPNPC)
00414   setValue(SETTING_ENABLE_UPNP, enabled);
00415 #endif
00416 }
00417 
Generated on Mon Aug 30 22:58:54 2010 for Vidalia by  doxygen 1.6.3