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 1254 2006-10-01 17:49:16Z 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_ADDRESS          "Address"
00044 #define SERVER_ORPORT           "ORPort"
00045 #define SERVER_DIRPORT          "DirPort"
00046 #define SERVER_CONTACTINFO      "ContactInfo"
00047 #define SERVER_EXITPOLICY       "ExitPolicy"
00048 #define SERVER_BANDWIDTH_RATE   "BandwidthRate"
00049 #define SERVER_BANDWIDTH_BURST  "BandwidthBurst"
00050 
00051 /* Server configuration settings */
00052 #define SETTING_SERVER_ENABLED    "Server/Enabled"
00053 #define SETTING_SERVER_CHANGED    "Server/Changed"
00054 #define SETTING_SERVER_DIRMIRROR  "Server/DirectoryMirror"
00055 #define SETTING_SERVER_AUTOUPDATE_ADDRESS "Server/AutoUpdateAddress"
00056 #define SETTING_SERVER_MIDDLEMAN  "Server/Middleman"
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,  false);
00079   setDefault(SETTING_SERVER_MIDDLEMAN,  true);
00080   setDefault(SETTING_SERVER_ORPORT,     9001);
00081   setDefault(SETTING_SERVER_DIRPORT,    9030);
00082   setDefault(SETTING_SERVER_CONTACT,    "<your@email.com>");
00083   setDefault(SETTING_SERVER_BWRATE,     2097152);
00084   setDefault(SETTING_SERVER_BWBURST,    5242880);
00085   setDefault(SETTING_SERVER_NICKNAME,   QHostInfo::localHostName());
00086   setDefault(SETTING_SERVER_ADDRESS,    net_local_address().toString());
00087   setDefault(SETTING_SERVER_AUTOUPDATE_ADDRESS, false);
00088   setDefault(SETTING_SERVER_EXITPOLICY,
00089     ExitPolicy(ExitPolicy::Default).toString());
00090 }
00091 
00092 /** Stores a boolean value indicating if the server's configuration has
00093  * changed since it was last applied.
00094  * \param changed Boolean value indicating whether settings have been changed.
00095  */
00096 void
00097 ServerSettings::setChanged(bool changed)
00098 {
00099   QSettings::setValue(SETTING_SERVER_CHANGED, changed);
00100 }
00101 
00102 /** Returns a boolean value indicating if the server's configuration has
00103  * changed since it was last applied.
00104  */
00105 bool
00106 ServerSettings::changedSinceLastApply()
00107 {
00108   return VidaliaSettings::value(SETTING_SERVER_CHANGED).toBool();
00109 }
00110 
00111 /** Restores the server configuration back to its state after the last call to
00112  * apply().
00113  * \sa apply()
00114  */
00115 void
00116 ServerSettings::revert()
00117 {
00118   beginGroup("Server");
00119   remove(""); /* Removes all settings in the Server group */
00120   foreach(QString key, _backupSettings.keys()) {
00121     setValue(key, _backupSettings.value(key));
00122   }
00123   endGroup();
00124 }
00125 
00126 /** Returns a map of all server configuration settings currently stored in
00127  * Vidalia's settings file. */
00128 QMap<QString, QVariant>
00129 ServerSettings::allSettings()
00130 {
00131   QMap<QString, QVariant> settings;
00132   beginGroup("Server");
00133   foreach(QString key, allKeys()) {
00134     settings.insert(key, QSettings::value(key));
00135   }
00136   endGroup();
00137   return settings;
00138 }
00139 
00140 /** Returns true if the given QVariant contains an empty value, depending on
00141  * the data type. For example, 0 is considered an empty integer and "" is an
00142  * empty string. */
00143 bool
00144 ServerSettings::isEmptyValue(QVariant value)
00145 {
00146   switch (value.type()) {
00147     case QVariant::String: 
00148       return (value.toString().isEmpty());
00149     case QVariant::UInt:
00150     case QVariant::Int:
00151       return (value.toUInt() == 0);
00152     case QVariant::Invalid:
00153       return true;
00154     default:  break;
00155   }
00156   return false;
00157 }
00158 
00159 /** Returns the stored value for the given key. If no stored value exists for
00160  * the given key, the specified default value is used. If Vidalia is currently
00161  * connected to Tor, we will ask Tor what its value is. Otherwise, we will
00162  * retrieve it from Vidalia's stored settings, allowing the configuration
00163  * information to be edited even if Tor isn't running.
00164  * \param key Configuration key
00165  * \param defaultValue Value to use if no configuration value exists for the
00166  * specified key.
00167  */
00168 QVariant
00169 ServerSettings::value(QString key)
00170 {
00171   QVariant value;
00172   QString confKey, confValue;
00173   confKey = key.mid(key.indexOf("/")+1);
00174   if (_torControl->isConnected()) {
00175     if (_torControl->getConf(confKey, confValue)) {
00176       value.setValue(confValue);
00177       value.convert(defaultValue(key).type());
00178     }
00179   } else {
00180     value = VidaliaSettings::value(key);
00181   }
00182   return (isEmptyValue(value) ? defaultValue(key) : value);
00183 }
00184 
00185 /** Saves the given configuration key-value to the application settings file.
00186  * \param key Configuration key
00187  * \param value Value to assign to <b>key</b>
00188  */
00189 void
00190 ServerSettings::setValue(QString key, QVariant value)
00191 {
00192   if (value != VidaliaSettings::value(key)) {
00193     setChanged(true);
00194     VidaliaSettings::setValue(key, value);
00195   }
00196 }
00197 
00198 /** Returns a QHash of Tor-recognizable configuratin keys to their current
00199  * values. */
00200 QHash<QString, QString>
00201 ServerSettings::confValues()
00202 {
00203   QHash<QString, QString> conf;
00204   /* Server Nickname */
00205   conf.insert(SERVER_NICKNAME,
00206     (isServerEnabled() ? VidaliaSettings::value(SETTING_SERVER_NICKNAME).toString()
00207                        : ""));
00208   /* Server ORPort */
00209   conf.insert(SERVER_ORPORT,
00210     (isServerEnabled() ? VidaliaSettings::value(SETTING_SERVER_ORPORT).toString()
00211                        : "0"));
00212   /* Server DirPort */
00213   conf.insert(SERVER_DIRPORT, 
00214     (isDirectoryMirror() ? VidaliaSettings::value(SETTING_SERVER_DIRPORT).toString() 
00215                          : "0"));
00216   /* Server Exit Policy */
00217   conf.insert(SERVER_EXITPOLICY, 
00218     (isMiddleman() ? ExitPolicy(ExitPolicy::Middleman).toString()
00219                    : VidaliaSettings::value(SETTING_SERVER_EXITPOLICY).toString()));
00220   /* Server Address */
00221   conf.insert(SERVER_ADDRESS,      
00222     VidaliaSettings::value(SETTING_SERVER_ADDRESS).toString());
00223   
00224   /* Server bandwidth settings */
00225   conf.insert(SERVER_BANDWIDTH_RATE,
00226     QString::number(VidaliaSettings::value(SETTING_SERVER_BWRATE).toUInt()) + " bytes");
00227   conf.insert(SERVER_BANDWIDTH_BURST,
00228     QString::number(VidaliaSettings::value(SETTING_SERVER_BWBURST).toUInt()) + " bytes");
00229     
00230   /* Server Contact Information */
00231   QString contact = 
00232     VidaliaSettings::value(SETTING_SERVER_CONTACT).toString().trimmed();
00233   QString defaultContact =
00234     VidaliaSettings::defaultValue(SETTING_SERVER_CONTACT).toString();
00235   if ((contact == defaultContact) ||
00236       (contact == scrub_email_addr(defaultContact))) {
00237     /* Only set the contact info if they put something non-default there */
00238     contact = "";
00239   }
00240   conf.insert(SERVER_CONTACTINFO, scrub_email_addr(contact));
00241   return conf;
00242 }
00243 
00244 /** Applies the current server configuration settings to Tor and tells Tor to
00245  * write the new configuration to disk. 
00246  * \param errmsg If specified, will store an error message should something go
00247  * wrong. 
00248  */
00249 bool
00250 ServerSettings::apply(QString *errmsg)
00251 {
00252   bool rc;
00253   if (isServerEnabled()) {
00254     rc = _torControl->setConf(confValues(), errmsg);
00255   } else { 
00256     QStringList resetKeys;
00257     resetKeys << SERVER_ORPORT << SERVER_NICKNAME;
00258     rc = _torControl->resetConf(resetKeys, errmsg);
00259   }
00260   if (rc) {
00261     if (!_torControl->saveConf(errmsg)) {
00262       return false;
00263     }
00264     setChanged(false);
00265     _backupSettings = allSettings();
00266   }
00267   return rc;
00268 }
00269 
00270 /** Enables or disables running Tor as a server. 
00271  * \param enable Whether to enable or disable the Tor server. 
00272  */
00273 void
00274 ServerSettings::setServerEnabled(bool enable)
00275 {
00276   setValue(SETTING_SERVER_ENABLED, enable);
00277 }
00278 
00279 /** Returns true if Tor is currently configured to run as a Tor server. If Tor
00280  * was started with a specific torrc, we will ask Tor whether that torrc told
00281  * it to be a server. Otherwise, we use our local settings. */
00282 bool
00283 ServerSettings::isServerEnabled()
00284 {
00285   TorSettings settings;
00286   QHash<QString,QString> confValues;
00287   if (_torControl->isConnected() && !changedSinceLastApply()) {
00288     confValues.insert(SERVER_ORPORT, "");
00289     confValues.insert(SERVER_NICKNAME, "");
00290     if (_torControl->getConf(confValues)) {
00291       return (confValues.value(SERVER_ORPORT).toUInt() != 0 &&
00292               !confValues.value(SERVER_NICKNAME).isEmpty());
00293     }
00294   }
00295   return VidaliaSettings::value(SETTING_SERVER_ENABLED).toBool();
00296 }
00297 
00298 /** Sets the server's ORPort. */
00299 void
00300 ServerSettings::setORPort(quint16 orPort)
00301 {
00302   setValue(SETTING_SERVER_ORPORT, orPort);
00303 }
00304 
00305 /** Gets the server's current ORPort setting. */
00306 quint16
00307 ServerSettings::getORPort()
00308 {
00309   return (quint16)value(SETTING_SERVER_ORPORT).toUInt();
00310 }
00311 
00312 /** Sets the server's current DirPort. */
00313 void
00314 ServerSettings::setDirPort(quint16 dirPort)
00315 {
00316   setValue(SETTING_SERVER_DIRPORT, dirPort);
00317 }
00318 
00319 /** Gets the server's current DirPort. */
00320 quint16
00321 ServerSettings::getDirPort()
00322 {
00323   return (quint16)value(SETTING_SERVER_DIRPORT).toUInt();
00324 }
00325 
00326 /** Sets the server's externally-reachable address. */
00327 void
00328 ServerSettings::setAddress(QString address)
00329 {
00330   setValue(SETTING_SERVER_ADDRESS, address);
00331 }
00332 
00333 /** Gets the server's externally-reachable IP address or hostname. */
00334 QString
00335 ServerSettings::getAddress()
00336 {
00337   return value(SETTING_SERVER_ADDRESS).toString();
00338 }
00339 
00340 /** Sets the server's nickname. */
00341 void
00342 ServerSettings::setNickname(QString nickname)
00343 {
00344   setValue(SETTING_SERVER_NICKNAME, nickname);
00345 }
00346 
00347 /** Gets the server's nickname. */
00348 QString
00349 ServerSettings::getNickname()
00350 {
00351   QString nickname = value(SETTING_SERVER_NICKNAME).toString();
00352   /* Ensure the nickname contains only valid characters and is not too long. */
00353   return ensure_valid_chars(nickname, 
00354                             VALID_NICKNAME_CHARS).left(MAX_NICKNAME_LEN);
00355 }
00356 
00357 /** Sets the server's contact information. */
00358 void
00359 ServerSettings::setContactInfo(QString contact)
00360 {
00361   setValue(SETTING_SERVER_CONTACT, contact);
00362 }
00363 
00364 /** Gets the server's contact information. */
00365 QString
00366 ServerSettings::getContactInfo()
00367 {
00368   return value(SETTING_SERVER_CONTACT).toString();
00369 }
00370 
00371 /** Returns whether this server will act as a directory mirror or not. */
00372 bool
00373 ServerSettings::isDirectoryMirror()
00374 {
00375   return VidaliaSettings::value(SETTING_SERVER_DIRMIRROR).toBool();
00376 }
00377 
00378 /** Sets whether this server will act as a directory mirror. */
00379 void
00380 ServerSettings::setDirectoryMirror(bool mirror)
00381 {
00382   setValue(SETTING_SERVER_DIRMIRROR, mirror);
00383 }
00384 
00385 /** Returns whether this server is a middle-man server. A middle-man server
00386  * simply relays traffic between other Tor servers. A middle-man server can
00387  * also act as an entry node for Tor clients. */
00388 bool
00389 ServerSettings::isMiddleman()
00390 {
00391   return QSettings::value(SETTING_SERVER_MIDDLEMAN).toBool();
00392 }
00393 
00394 /** Sets whether this server will act as a middle-man server. */
00395 void
00396 ServerSettings::setMiddleman(bool middleman)
00397 {
00398   setValue(SETTING_SERVER_MIDDLEMAN, middleman);
00399 }
00400 
00401 /** Returns the exit policy for this server. */
00402 ExitPolicy
00403 ServerSettings::getExitPolicy()
00404 {
00405   return ExitPolicy(value(SETTING_SERVER_EXITPOLICY).toString());
00406 }
00407 
00408 /** Sets the exit policy for this server. */
00409 void
00410 ServerSettings::setExitPolicy(ExitPolicy &exitPolicy)
00411 {
00412   setValue(SETTING_SERVER_EXITPOLICY, exitPolicy.toString());
00413 }
00414 
00415 /** Returns the long-term average bandwidth rate (in KB/s) for this server. */
00416 quint32
00417 ServerSettings::getBandwidthAvgRate()
00418 {
00419   return value(SETTING_SERVER_BWRATE).toUInt();
00420 }
00421 
00422 /** Sets the long-term average bandwidth rate (in KB/s) for this server. */
00423 void
00424 ServerSettings::setBandwidthAvgRate(quint32 rate)
00425 {
00426   setValue(SETTING_SERVER_BWRATE, rate);
00427 }
00428 
00429 /** Returns the maximum bandwidth burst rate (in KB/s) for this server. */
00430 quint32
00431 ServerSettings::getBandwidthBurstRate()
00432 {
00433   return value(SETTING_SERVER_BWBURST).toUInt();
00434 }
00435 
00436 /** Sets the maximum bandwidth burst rate (in KB/s) for this server. */
00437 void
00438 ServerSettings::setBandwidthBurstRate(quint32 rate)
00439 {
00440   setValue(SETTING_SERVER_BWBURST, rate);
00441 }
00442 
00443 /** Returns whether we should update the server's IP address automatically. */
00444 bool
00445 ServerSettings::getAutoUpdateAddress()
00446 {
00447   return VidaliaSettings::value(SETTING_SERVER_AUTOUPDATE_ADDRESS).toBool();
00448 }
00449 
00450 /** Sets whether we should update the server's IP address automatically. */
00451 void
00452 ServerSettings::setAutoUpdateAddress(bool enabled)
00453 {
00454   setValue(SETTING_SERVER_AUTOUPDATE_ADDRESS, enabled);
00455 }
00456 

Generated on Mon Oct 23 20:08:16 2006 for Vidalia by  doxygen 1.5.0