serversettings.cpp

Go to the documentation of this file.
00001 /****************************************************************
00002  *  Vidalia is distributed under the following license:
00003  *
00004  *  Copyright (C) 2006,  Matt Edman, Justin Hipple
00005  *
00006  *  This program is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU General Public License
00008  *  as published by the Free Software Foundation; either version 2
00009  *  of the License, or (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
00019  *  Boston, MA  02110-1301, USA.
00020  ****************************************************************/
00021 
00022 /** 
00023  * \file serversettings.cpp
00024  * \version $Id: serversettings.cpp 1790 2007-06-17 18:58:00Z edmanm $
00025  * \brief Settings for running a Tor server
00026  */
00027 
00028 #include <QHostInfo>
00029 #include <util/net.h>
00030 #include <util/string.h>
00031 
00032 #include "serversettings.h"
00033 #include "torsettings.h"
00034 
00035 /** Define the set of characters that are valid in a nickname. */
00036 #define VALID_NICKNAME_CHARS \
00037   "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
00038 /** Define the maximum length of a server's nickname. */
00039 #define MAX_NICKNAME_LEN   19
00040 
00041 /* Server-related torrc configuration parameters */
00042 #define SERVER_NICKNAME         "Nickname"
00043 #define SERVER_ORPORT           "ORPort"
00044 #define SERVER_DIRPORT          "DirPort"
00045 #define SERVER_CONTACTINFO      "ContactInfo"
00046 #define SERVER_EXITPOLICY       "ExitPolicy"
00047 #define SERVER_BANDWIDTH_RATE   "BandwidthRate"
00048 #define SERVER_BANDWIDTH_BURST  "BandwidthBurst"
00049 #define SERVER_RELAY_BANDWIDTH_RATE   "RelayBandwidthRate"
00050 #define SERVER_RELAY_BANDWIDTH_BURST  "RelayBandwidthBurst"
00051 
00052 /* Server configuration settings */
00053 #define SETTING_SERVER_ENABLED    "Server/Enabled"
00054 #define SETTING_SERVER_CHANGED    "Server/Changed"
00055 #define SETTING_SERVER_DIRMIRROR  "Server/DirectoryMirror"
00056 #define SETTING_SERVER_AUTOUPDATE_ADDRESS "Server/AutoUpdateAddress"
00057 #define SETTING_SERVER_NICKNAME   "Server/"SERVER_NICKNAME
00058 #define SETTING_SERVER_ORPORT     "Server/"SERVER_ORPORT
00059 #define SETTING_SERVER_DIRPORT    "Server/"SERVER_DIRPORT
00060 #define SETTING_SERVER_ADDRESS    "Server/"SERVER_ADDRESS
00061 #define SETTING_SERVER_CONTACT    "Server/"SERVER_CONTACTINFO
00062 #define SETTING_SERVER_EXITPOLICY "Server/"SERVER_EXITPOLICY
00063 #define SETTING_SERVER_BWRATE     "Server/"SERVER_BANDWIDTH_RATE
00064 #define SETTING_SERVER_BWBURST    "Server/"SERVER_BANDWIDTH_BURST
00065 
00066 
00067 /** Constructor.
00068  * \param torControl a TorControl object used to read and apply the server
00069  * configuration settings.
00070  */
00071 ServerSettings::ServerSettings(TorControl *torControl)
00072 {
00073   _torControl = torControl;
00074   _backupSettings = allSettings();
00075 
00076   setDefault(SETTING_SERVER_ENABLED,    false);
00077   setDefault(SETTING_SERVER_CHANGED,    false);
00078   setDefault(SETTING_SERVER_DIRMIRROR,  true);
00079   setDefault(SETTING_SERVER_ORPORT,     9001);
00080   setDefault(SETTING_SERVER_DIRPORT,    9030);
00081   setDefault(SETTING_SERVER_CONTACT,    "<your@email.com>");
00082   setDefault(SETTING_SERVER_BWRATE,     3145728);
00083   setDefault(SETTING_SERVER_BWBURST,    6291456);
00084   setDefault(SETTING_SERVER_NICKNAME,   "Unnamed");
00085   setDefault(SETTING_SERVER_EXITPOLICY,
00086     ExitPolicy(ExitPolicy::Default).toString());
00087 }
00088 
00089 /** Stores a boolean value indicating if the server's configuration has
00090  * changed since it was last applied.
00091  * \param changed Boolean value indicating whether settings have been changed.
00092  */
00093 void
00094 ServerSettings::setChanged(bool changed)
00095 {
00096   VidaliaSettings::setValue(SETTING_SERVER_CHANGED, changed);
00097 }
00098 
00099 /** Returns a boolean value indicating if the server's configuration has
00100  * changed since it was last applied.
00101  */
00102 bool
00103 ServerSettings::changedSinceLastApply()
00104 {
00105   return VidaliaSettings::value(SETTING_SERVER_CHANGED).toBool();
00106 }
00107 
00108 /** Restores the server configuration back to its state after the last call to
00109  * apply().
00110  * \sa apply()
00111  */
00112 void
00113 ServerSettings::revert()
00114 {
00115   beginGroup("Server");
00116   remove(""); /* Removes all settings in the Server group */
00117   foreach(QString key, _backupSettings.keys()) {
00118     setValue(key, _backupSettings.value(key));
00119   }
00120   endGroup();
00121 }
00122 
00123 /** Returns a map of all server configuration settings currently stored in
00124  * Vidalia's settings file. */
00125 QMap<QString, QVariant>
00126 ServerSettings::allSettings()
00127 {
00128   QMap<QString, QVariant> settings;
00129   beginGroup("Server");
00130   foreach(QString key, allKeys()) {
00131     settings.insert(key, QSettings::value(key));
00132   }
00133   endGroup();
00134   return settings;
00135 }
00136 
00137 /** Returns true if the given QVariant contains an empty value, depending on
00138  * the data type. For example, 0 is considered an empty integer and "" is an
00139  * empty string. */
00140 bool
00141 ServerSettings::isEmptyValue(QVariant value)
00142 {
00143   switch (value.type()) {
00144     case QVariant::String: 
00145       return (value.toString().isEmpty());
00146     case QVariant::UInt:
00147     case QVariant::Int:
00148       return (value.toUInt() == 0);
00149     case QVariant::Invalid:
00150       return true;
00151     default:  break;
00152   }
00153   return false;
00154 }
00155 
00156 /** Returns the stored value for the given key. If no stored value exists for
00157  * the given key, the specified default value is used. If Vidalia is currently
00158  * connected to Tor, we will ask Tor what its value is. Otherwise, we will
00159  * retrieve it from Vidalia's stored settings, allowing the configuration
00160  * information to be edited even if Tor isn't running.
00161  * \param key Configuration key
00162  * \param defaultValue Value to use if no configuration value exists for the
00163  * specified key.
00164  */
00165 QVariant
00166 ServerSettings::value(QString key)
00167 {
00168   QVariant value;
00169   QString confKey, confValue;
00170   confKey = key.mid(key.indexOf("/")+1);
00171   if (_torControl->isConnected()) {
00172     quint32 torVersion = _torControl->getTorVersion();
00173     if (torVersion >= 0x020001) {
00174       if (confKey == SERVER_BANDWIDTH_RATE)
00175         confKey = SERVER_RELAY_BANDWIDTH_RATE;
00176       else if (confKey == SERVER_BANDWIDTH_BURST)
00177         confKey = SERVER_RELAY_BANDWIDTH_BURST;
00178     }
00179     if (_torControl->getConf(confKey, confValue)) {
00180       /* Get the value from Tor */
00181       value.setValue(confValue);
00182       value.convert(defaultValue(key).type());
00183     }
00184   } else {
00185     /* Read our saved value from vidalia.conf */
00186     value = VidaliaSettings::value(key);
00187   }
00188   return (isEmptyValue(value) ? defaultValue(key) : value);
00189 }
00190 
00191 /** Saves the given configuration key-value to the application settings file.
00192  * \param key Configuration key
00193  * \param value Value to assign to <b>key</b>
00194  */
00195 void
00196 ServerSettings::setValue(QString key, QVariant value)
00197 {
00198   if (value != VidaliaSettings::value(key)) {
00199     setChanged(true);
00200     VidaliaSettings::setValue(key, value);
00201   }
00202 }
00203 
00204 /** Returns a QHash of Tor-recognizable configuratin keys to their current
00205  * values. */
00206 QHash<QString, QString>
00207 ServerSettings::confValues()
00208 {
00209   QHash<QString, QString> conf;
00210   quint32 torVersion = _torControl->getTorVersion();
00211 
00212   /* Server Nickname */
00213   conf.insert(SERVER_NICKNAME,
00214     (isServerEnabled() ? VidaliaSettings::value(SETTING_SERVER_NICKNAME).toString()
00215                        : ""));
00216   /* Server ORPort */
00217   conf.insert(SERVER_ORPORT,
00218     (isServerEnabled() ? VidaliaSettings::value(SETTING_SERVER_ORPORT).toString()
00219                        : "0"));
00220   /* Server DirPort */
00221   conf.insert(SERVER_DIRPORT, 
00222     (isDirectoryMirror() ? VidaliaSettings::value(SETTING_SERVER_DIRPORT).toString() 
00223                          : "0"));
00224   /* Server Exit Policy */
00225   conf.insert(SERVER_EXITPOLICY, 
00226     VidaliaSettings::value(SETTING_SERVER_EXITPOLICY).toString());
00227   
00228   /* Server bandwidth settings */
00229   conf.insert((torVersion >= 0x020001 ? SERVER_RELAY_BANDWIDTH_RATE 
00230                                       : SERVER_BANDWIDTH_RATE),
00231     QString::number(VidaliaSettings::value(SETTING_SERVER_BWRATE).toUInt()) + " bytes");
00232   conf.insert((torVersion >= 0x020001 ? SERVER_RELAY_BANDWIDTH_BURST
00233                                       : SERVER_BANDWIDTH_BURST),
00234     QString::number(VidaliaSettings::value(SETTING_SERVER_BWBURST).toUInt()) + " bytes");
00235     
00236   /* Server Contact Information */
00237   QString contact = 
00238     VidaliaSettings::value(SETTING_SERVER_CONTACT).toString().trimmed();
00239   QString defaultContact =
00240     VidaliaSettings::defaultValue(SETTING_SERVER_CONTACT).toString();
00241   if ((contact == defaultContact) ||
00242       (contact == scrub_email_addr(defaultContact))) {
00243     /* Only set the contact info if they put something non-default there */
00244     contact = "";
00245   }
00246   conf.insert(SERVER_CONTACTINFO, scrub_email_addr(contact));
00247   return conf;
00248 }
00249 
00250 /** Applies the current server configuration settings to Tor and tells Tor to
00251  * write the new configuration to disk. 
00252  * \param errmsg If specified, will store an error message should something go
00253  * wrong. 
00254  */
00255 bool
00256 ServerSettings::apply(QString *errmsg)
00257 {
00258   bool rc;
00259 
00260   if (isServerEnabled()) {
00261     rc = _torControl->setConf(confValues(), errmsg);
00262   } else { 
00263     QStringList resetKeys;
00264     quint32 torVersion = _torControl->getTorVersion();
00265     resetKeys << SERVER_ORPORT 
00266               << SERVER_NICKNAME 
00267               << SERVER_DIRPORT
00268               << SERVER_CONTACTINFO
00269               << SERVER_EXITPOLICY;
00270     if (torVersion >= 0x020001) {
00271       resetKeys << SERVER_RELAY_BANDWIDTH_RATE
00272                 << SERVER_RELAY_BANDWIDTH_BURST;
00273     } else {
00274       resetKeys << SERVER_BANDWIDTH_RATE
00275                 << SERVER_BANDWIDTH_BURST;
00276     }
00277     rc = _torControl->resetConf(resetKeys, errmsg);
00278   }
00279   if (rc) {
00280     if (_torControl->saveConf(errmsg))
00281       setChanged(false);
00282     _backupSettings = allSettings();
00283   }
00284   return rc;
00285 }
00286 
00287 /** Enables or disables running Tor as a server. 
00288  * \param enable Whether to enable or disable the Tor server. 
00289  */
00290 void
00291 ServerSettings::setServerEnabled(bool enable)
00292 {
00293   setValue(SETTING_SERVER_ENABLED, enable);
00294 }
00295 
00296 /** Returns true if Tor is currently configured to run as a Tor server. If Tor
00297  * was started with a specific torrc, we will ask Tor whether that torrc told
00298  * it to be a server. Otherwise, we use our local settings. */
00299 bool
00300 ServerSettings::isServerEnabled()
00301 {
00302   TorSettings settings;
00303   QHash<QString,QString> confValues;
00304   if (_torControl->isConnected() && !changedSinceLastApply()) {
00305     confValues.insert(SERVER_ORPORT, "");
00306     confValues.insert(SERVER_NICKNAME, "");
00307     if (_torControl->getConf(confValues)) {
00308       return (confValues.value(SERVER_ORPORT).toUInt() != 0 &&
00309               !confValues.value(SERVER_NICKNAME).isEmpty());
00310     }
00311   }
00312   return VidaliaSettings::value(SETTING_SERVER_ENABLED).toBool();
00313 }
00314 
00315 /** Sets the server's ORPort. */
00316 void
00317 ServerSettings::setORPort(quint16 orPort)
00318 {
00319   setValue(SETTING_SERVER_ORPORT, orPort);
00320 }
00321 
00322 /** Gets the server's current ORPort setting. */
00323 quint16
00324 ServerSettings::getORPort()
00325 {
00326   return (quint16)value(SETTING_SERVER_ORPORT).toUInt();
00327 }
00328 
00329 /** Sets the server's current DirPort. */
00330 void
00331 ServerSettings::setDirPort(quint16 dirPort)
00332 {
00333   setValue(SETTING_SERVER_DIRPORT, dirPort);
00334 }
00335 
00336 /** Gets the server's current DirPort. */
00337 quint16
00338 ServerSettings::getDirPort()
00339 {
00340   return (quint16)value(SETTING_SERVER_DIRPORT).toUInt();
00341 }
00342 
00343 /** Sets the server's nickname. */
00344 void
00345 ServerSettings::setNickname(QString nickname)
00346 {
00347   setValue(SETTING_SERVER_NICKNAME, nickname);
00348 }
00349 
00350 /** Gets the server's nickname. */
00351 QString
00352 ServerSettings::getNickname()
00353 {
00354   QString nickname = value(SETTING_SERVER_NICKNAME).toString();
00355   /* Ensure the nickname contains only valid characters and is not too long. */
00356   return ensure_valid_chars(nickname, 
00357                             VALID_NICKNAME_CHARS).left(MAX_NICKNAME_LEN);
00358 }
00359 
00360 /** Sets the server's contact information. */
00361 void
00362 ServerSettings::setContactInfo(QString contact)
00363 {
00364   setValue(SETTING_SERVER_CONTACT, contact);
00365 }
00366 
00367 /** Gets the server's contact information. */
00368 QString
00369 ServerSettings::getContactInfo()
00370 {
00371   return value(SETTING_SERVER_CONTACT).toString();
00372 }
00373 
00374 /** Returns whether this server will act as a directory mirror or not. */
00375 bool
00376 ServerSettings::isDirectoryMirror()
00377 {
00378   return VidaliaSettings::value(SETTING_SERVER_DIRMIRROR).toBool();
00379 }
00380 
00381 /** Sets whether this server will act as a directory mirror. */
00382 void
00383 ServerSettings::setDirectoryMirror(bool mirror)
00384 {
00385   setValue(SETTING_SERVER_DIRMIRROR, mirror);
00386 }
00387 
00388 /** Returns the exit policy for this server. */
00389 ExitPolicy
00390 ServerSettings::getExitPolicy()
00391 {
00392   return ExitPolicy(value(SETTING_SERVER_EXITPOLICY).toString());
00393 }
00394 
00395 /** Sets the exit policy for this server. */
00396 void
00397 ServerSettings::setExitPolicy(ExitPolicy &exitPolicy)
00398 {
00399   setValue(SETTING_SERVER_EXITPOLICY, exitPolicy.toString());
00400 }
00401 
00402 /** Returns the long-term average bandwidth rate (in KB/s) for this server. */
00403 quint32
00404 ServerSettings::getBandwidthAvgRate()
00405 {
00406   return value(SETTING_SERVER_BWRATE).toUInt();
00407 }
00408 
00409 /** Sets the long-term average bandwidth rate (in KB/s) for this server. */
00410 void
00411 ServerSettings::setBandwidthAvgRate(quint32 rate)
00412 {
00413   setValue(SETTING_SERVER_BWRATE, rate);
00414 }
00415 
00416 /** Returns the maximum bandwidth burst rate (in KB/s) for this server. */
00417 quint32
00418 ServerSettings::getBandwidthBurstRate()
00419 {
00420   return value(SETTING_SERVER_BWBURST).toUInt();
00421 }
00422 
00423 /** Sets the maximum bandwidth burst rate (in KB/s) for this server. */
00424 void
00425 ServerSettings::setBandwidthBurstRate(quint32 rate)
00426 {
00427   setValue(SETTING_SERVER_BWBURST, rate);
00428 }
00429 

Generated on Wed Sep 5 15:49:28 2007 for Vidalia by  doxygen 1.5.3