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 2728 2008-06-14 23:47:49Z edmanm $
00014 ** \brief Settings for running a Tor server
00015 */
00016 
00017 #include <QHostInfo>
00018 #include <net.h>
00019 #include <stringutil.h>
00020 #include <config.h>
00021 
00022 #include "serversettings.h"
00023 #include "torsettings.h"
00024 
00025 #ifdef USE_MINIUPNPC
00026 #include "upnpcontrol.h"
00027 #endif
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_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,       "<your@email.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_PUBLISH_DESCRIPTOR,    "1");
00074   setDefault(SETTING_EXITPOLICY,
00075     ExitPolicy(ExitPolicy::Default).toString());
00076   setDefault(SETTING_ENABLE_UPNP, false); 
00077 }
00078 
00079 /** Returns a QHash of Tor-recognizable configuratin keys to their current
00080  * values. */
00081 QHash<QString, QString>
00082 ServerSettings::confValues()
00083 {
00084   QHash<QString, QString> conf;
00085   quint32 torVersion = torControl()->getTorVersion();
00086 
00087   /* Server Nickname */
00088   conf.insert(SETTING_NICKNAME,
00089     (isServerEnabled() ? localValue(SETTING_NICKNAME).toString()
00090                        : ""));
00091   /* Server ORPort */
00092   conf.insert(SETTING_ORPORT,
00093     (isServerEnabled() ? localValue(SETTING_ORPORT).toString()
00094                        : "0"));
00095   /* Server DirPort */
00096   conf.insert(SETTING_DIRPORT, 
00097     (isDirectoryMirror() ? localValue(SETTING_DIRPORT).toString() 
00098                          : "0"));
00099   /* Server Exit Policy */
00100   conf.insert(SETTING_EXITPOLICY, 
00101     (isBridgeEnabled() ? "reject *:*"
00102                        : localValue(SETTING_EXITPOLICY).toString()));
00103   
00104   /* Server bandwidth settings */
00105   conf.insert((torVersion >= 0x020001 ? SETTING_RELAY_BANDWIDTH_RATE 
00106                                       : SETTING_BANDWIDTH_RATE),
00107     QString::number(localValue(SETTING_BANDWIDTH_RATE).toUInt()) + " bytes");
00108   conf.insert((torVersion >= 0x020001 ? SETTING_RELAY_BANDWIDTH_BURST
00109                                       : SETTING_BANDWIDTH_BURST),
00110     QString::number(localValue(SETTING_BANDWIDTH_BURST).toUInt()) + " bytes");
00111     
00112   /* Server Contact Information */
00113   QString contact = 
00114     localValue(SETTING_CONTACT).toString().trimmed();
00115   QString defaultContact = defaultValue(SETTING_CONTACT).toString();
00116   if ((contact == defaultContact) ||
00117       (contact == scrub_email_addr(defaultContact))) {
00118     /* Only set the contact info if they put something non-default there */
00119     contact = "";
00120   }
00121   conf.insert(SETTING_CONTACT, scrub_email_addr(contact));
00122   
00123   /* If we're a bridge, don't publish our server descriptor */
00124   conf.insert(SETTING_PUBLISH_DESCRIPTOR,
00125               (torVersion >= 0x020008 && isBridgeEnabled() ? "bridge" : "1"));
00126   if (torVersion >= 0x020013)
00127     conf.insert(SETTING_BRIDGE_RELAY, isBridgeEnabled() ? "1" : "0");
00128   return conf;
00129 }
00130 
00131 /** Applies the current server configuration settings to Tor. If <b>errmsg</b>
00132  * is specified and an error occurs while applying the settings, it will be 
00133  * set to a string describing the error. */
00134 bool
00135 ServerSettings::apply(QString *errmsg)
00136 {
00137   bool rc;
00138 
00139   configurePortForwarding();
00140 
00141   if (isServerEnabled()) {
00142     rc = torControl()->setConf(confValues(), errmsg);
00143   } else { 
00144     QStringList resetKeys;
00145     quint32 torVersion = torControl()->getTorVersion();
00146     resetKeys << SETTING_ORPORT 
00147               << SETTING_NICKNAME 
00148               << SETTING_DIRPORT
00149               << SETTING_CONTACT
00150               << SETTING_EXITPOLICY
00151               << SETTING_PUBLISH_DESCRIPTOR;
00152     if (torVersion >= 0x020001) {
00153       resetKeys << SETTING_RELAY_BANDWIDTH_RATE
00154                 << SETTING_RELAY_BANDWIDTH_BURST;
00155     } else {
00156       resetKeys << SETTING_BANDWIDTH_RATE
00157                 << SETTING_BANDWIDTH_BURST;
00158     }
00159     rc = torControl()->resetConf(resetKeys, errmsg);
00160   }
00161   return rc;
00162 }
00163 
00164 /* TODO: We should call this periodically, in case the router gets rebooted or forgets its UPnP settings */
00165 /* TODO: Remove port forwarding when Tor is shutdown or the ORPort changes */
00166 /* TODO: init_upnp() will block for up to 2 seconds. We should fire off a thread */
00167 
00168 /** Configure UPnP device to forward DirPort and ORPort. If enable is
00169 true, will forward ORPort and DirPort; otherwise will remove exising
00170 port mappings */
00171 void
00172 ServerSettings::configurePortForwarding()
00173 {
00174 #ifdef USE_MINIUPNPC
00175   quint16 ORPort, DirPort;
00176 
00177   // This is how the tickbox should control UPNP
00178   if (!isUpnpEnabled())
00179     return;
00180 
00181   ORPort = getORPort();
00182   if (!isServerEnabled())
00183     ORPort = 0;
00184 
00185   DirPort = getDirPort();
00186   if (!isServerEnabled() || !isDirectoryMirror())
00187     DirPort = 0;
00188 
00189   UPNPControl *control = UPNPControl::instance();
00190   control->setDesiredState(DirPort, ORPort);
00191 #endif
00192 }
00193 
00194 void
00195 ServerSettings::cleanupPortForwarding()
00196 {
00197 #ifdef USE_MINIUPNPC
00198   UPNPControl::cleanup();
00199 #endif
00200 }
00201 
00202 /** Virtual method called when we retrieve a server-related setting from Tor.
00203  * Currently this just translates BandwidthFoo to RelayBandwidthFoo when
00204  * appropriate. */
00205 QVariant
00206 ServerSettings::torValue(const QString &key) const
00207 {
00208   if (torControl()->getTorVersion() >= 0x020001) {
00209     if (key == SETTING_BANDWIDTH_RATE)
00210       return AbstractTorSettings::torValue(SETTING_RELAY_BANDWIDTH_RATE);
00211     else if (key == SETTING_BANDWIDTH_BURST)
00212       return AbstractTorSettings::torValue(SETTING_RELAY_BANDWIDTH_BURST);
00213   }
00214   return AbstractTorSettings::torValue(key);
00215 }
00216 
00217 /** Enables or disables running Tor as a server. 
00218  * \param enable Whether to enable or disable the Tor server. 
00219  */
00220 void
00221 ServerSettings::setServerEnabled(bool enable)
00222 {
00223   setValue(SETTING_ENABLED, enable);
00224 }
00225 
00226 /** Returns true if Tor is currently configured to run as a Tor server. If Tor
00227  * is running, we will check whether it has an ORPort defined. Otherwise, we
00228  * will use our saved settings. */
00229 bool
00230 ServerSettings::isServerEnabled()
00231 {
00232   QString orPort;
00233   if (torControl()->isConnected() && !changedSinceLastApply()) {
00234     if (torControl()->getConf(SETTING_ORPORT, orPort))
00235       return (orPort.toUInt() > 0);
00236   }
00237   return localValue(SETTING_ENABLED).toBool();
00238 }
00239 
00240 /** Sets to <b>enabled</b> whether Tor should be a bridge node when acting as
00241  * a server. */
00242 void
00243 ServerSettings::setBridgeEnabled(bool enabled)
00244 {
00245   setValue(SETTING_PUBLISH_DESCRIPTOR, enabled ? "bridge" : "1");
00246 }
00247 
00248 /** Returns true if Tor is configured to act as a bridge node. */
00249 bool
00250 ServerSettings::isBridgeEnabled()
00251 {
00252   return (isServerEnabled() && 
00253           value(SETTING_PUBLISH_DESCRIPTOR).toString().toLower() == "bridge");
00254 }
00255 
00256 /** Sets the server's ORPort. */
00257 void
00258 ServerSettings::setORPort(quint16 orPort)
00259 {
00260   setValue(SETTING_ORPORT, orPort);
00261 }
00262 
00263 /** Gets the server's current ORPort setting. */
00264 quint16
00265 ServerSettings::getORPort()
00266 {
00267   return (quint16)value(SETTING_ORPORT).toUInt();
00268 }
00269 
00270 /** Sets the server's current DirPort. */
00271 void
00272 ServerSettings::setDirPort(quint16 dirPort)
00273 {
00274   setValue(SETTING_DIRPORT, dirPort);
00275 }
00276 
00277 /** Gets the server's current DirPort. */
00278 quint16
00279 ServerSettings::getDirPort()
00280 {
00281   return (quint16)value(SETTING_DIRPORT).toUInt();
00282 }
00283 
00284 /** Sets the server's nickname. */
00285 void
00286 ServerSettings::setNickname(QString nickname)
00287 {
00288   setValue(SETTING_NICKNAME, nickname);
00289 }
00290 
00291 /** Gets the server's nickname. */
00292 QString
00293 ServerSettings::getNickname()
00294 {
00295   QString nickname = value(SETTING_NICKNAME).toString();
00296   /* Ensure the nickname contains only valid characters and is not too long. */
00297   return ensure_valid_chars(nickname, 
00298                             VALID_NICKNAME_CHARS).left(MAX_NICKNAME_LEN);
00299 }
00300 
00301 /** Sets the server's contact information. */
00302 void
00303 ServerSettings::setContactInfo(QString contact)
00304 {
00305   setValue(SETTING_CONTACT, contact);
00306 }
00307 
00308 /** Gets the server's contact information. */
00309 QString
00310 ServerSettings::getContactInfo()
00311 {
00312   return value(SETTING_CONTACT).toString();
00313 }
00314 
00315 /** Returns whether this server will act as a directory mirror or not. */
00316 bool
00317 ServerSettings::isDirectoryMirror()
00318 {
00319   return localValue(SETTING_DIRMIRROR).toBool();
00320 }
00321 
00322 /** Sets whether this server will act as a directory mirror. */
00323 void
00324 ServerSettings::setDirectoryMirror(bool mirror)
00325 {
00326   setValue(SETTING_DIRMIRROR, mirror);
00327 }
00328 
00329 /** Returns the exit policy for this server. */
00330 ExitPolicy
00331 ServerSettings::getExitPolicy()
00332 {
00333   return ExitPolicy(value(SETTING_EXITPOLICY).toString());
00334 }
00335 
00336 /** Sets the exit policy for this server. */
00337 void
00338 ServerSettings::setExitPolicy(ExitPolicy &exitPolicy)
00339 {
00340   setValue(SETTING_EXITPOLICY, exitPolicy.toString());
00341 }
00342 
00343 /** Returns the long-term average bandwidth rate (in KB/s) for this server. */
00344 quint32
00345 ServerSettings::getBandwidthAvgRate()
00346 {
00347   return value(SETTING_BANDWIDTH_RATE).toUInt();
00348 }
00349 
00350 /** Sets the long-term average bandwidth rate (in KB/s) for this server. */
00351 void
00352 ServerSettings::setBandwidthAvgRate(quint32 rate)
00353 {
00354   setValue(SETTING_BANDWIDTH_RATE, rate);
00355 }
00356 
00357 /** Returns the maximum bandwidth burst rate (in KB/s) for this server. */
00358 quint32
00359 ServerSettings::getBandwidthBurstRate()
00360 {
00361   return value(SETTING_BANDWIDTH_BURST).toUInt();
00362 }
00363 
00364 /** Sets the maximum bandwidth burst rate (in KB/s) for this server. */
00365 void
00366 ServerSettings::setBandwidthBurstRate(quint32 rate)
00367 {
00368   setValue(SETTING_BANDWIDTH_BURST, rate);
00369 }
00370 
00371 /** Returns true if UPnP support is available and enabled. */
00372 bool
00373 ServerSettings::isUpnpEnabled()
00374 {
00375 #if defined(USE_MINIUPNPC)
00376   return localValue(SETTING_ENABLE_UPNP).toBool();
00377 #else
00378   return false;
00379 #endif
00380 }
00381 
00382 /** Sets whether Vidalia should try to configure port forwarding using UPnP.
00383  * If Vidalia was compiled without UPnP support, this method has no effect. */
00384 void
00385 ServerSettings::setUpnpEnabled(bool enabled)
00386 {
00387 #if defined(USE_MINIUPNPC)
00388   setValue(SETTING_ENABLE_UPNP, enabled);
00389 #endif
00390 }
00391 

Generated on Sat Aug 16 17:31:48 2008 for Vidalia by  doxygen 1.5.6