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

Generated on Tue Jul 7 16:58:26 2009 for Vidalia by  doxygen 1.4.7