serverpage.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 serverpage.cpp
00024  * \version $Id: serverpage.cpp 1789 2007-06-17 13:04:42Z edmanm $
00025  * \brief Tor server configuration options
00026  */
00027 
00028 #include <vidalia.h>
00029 #include <util/net.h>
00030 #include <util/http.h>
00031 #include <util/html.h>
00032 #include <gui/common/vmessagebox.h>
00033 
00034 #include "serverpage.h"
00035 #include "ipvalidator.h"
00036 #include "portvalidator.h"
00037 #include "domainvalidator.h"
00038 #include "nicknamevalidator.h"
00039 
00040 /** Delay between updating our server IP address (in ms). */
00041 #define AUTO_UPDATE_ADDR_INTERVAL  1000*60*60
00042 
00043 /** Help topics */
00044 #define EXIT_POLICY_HELP      "server.exitpolicy"
00045 #define BANDWIDTH_HELP        "server.bandwidth"
00046 
00047 /* These are completely made up values (in bytes/sec). */
00048 #define CABLE256_AVG_RATE       (32*1024)
00049 #define CABLE256_MAX_RATE       (64*1024)
00050 #define CABLE512_AVG_RATE       (64*1024)
00051 #define CABLE512_MAX_RATE       (128*1024)
00052 #define CABLE768_AVG_RATE       (96*1024)
00053 #define CABLE768_MAX_RATE       (192*1024)
00054 #define T1_AVG_RATE             (192*1024)
00055 #define T1_MAX_RATE             (384*1024)
00056 #define HIGHBW_AVG_RATE         (3072*1024)
00057 #define HIGHBW_MAX_RATE         (6144*1024)
00058 /** Minimum allowed bandwidth rate (20KB) */
00059 #define MIN_BANDWIDTH_RATE      20
00060 /** Maximum bandwidth rate. This is limited to 2147483646 bytes, 
00061  * or 2097151 kilobytes. (2147483646/1024) */ 
00062 #define MAX_BANDWIDTH_RATE      2097151
00063 
00064 /** Ports represented by the "Websites" checkbox. (80) */
00065 #define PORTS_HTTP   (QStringList() << "80")
00066 /** Ports represented by the "Secure Websites" checkbox. (443) */
00067 #define PORTS_HTTPS  (QStringList() << "443")
00068 /** Ports represented by the "Retrieve Mail" checkbox. (110,143,993,995) */
00069 #define PORTS_MAIL   (QStringList() << "110" << "143" << "993" << "995")
00070 /** Ports represented by the "Instant Messaging" checkbox.
00071  * (703,1863,5050,5190,5222,8300,8888) */
00072 #define PORTS_IM     (QStringList() << "706" << "1863" << "5050" << "5190" \
00073                                     << "5222" << "8300" << "8888")
00074 /** Ports represented by the "Internet Relay Chat" checkbox. 
00075  * (6660-6669,6697) */
00076 #define PORTS_IRC    (QStringList() << "6660-6669" << "6697")
00077 
00078 
00079 /** Constructor */
00080 ServerPage::ServerPage(QWidget *parent)
00081 : ConfigPage(parent)
00082 {
00083   /* Invoke the Qt Designer generated object setup routine */
00084   ui.setupUi(this);
00085   
00086   /* Keep a pointer to the TorControl object used to talk to Tor */
00087   _torControl = Vidalia::torControl();
00088 
00089   /* Create ServerSettings object */
00090   _settings = new ServerSettings(_torControl);
00091 
00092   /* Bind events to actions */
00093   connect(ui.btnRateHelp, SIGNAL(clicked()), this, SLOT(bandwidthHelp()));
00094   connect(ui.btnExitHelp, SIGNAL(clicked()), this, SLOT(exitPolicyHelp()));
00095   connect(ui.cmboRate, SIGNAL(currentIndexChanged(int)),
00096           this, SLOT(rateChanged(int)));
00097   connect(ui.lineAvgRateLimit, SIGNAL(editingFinished()), 
00098                          this, SLOT(customRateChanged()));
00099   connect(ui.lineMaxRateLimit, SIGNAL(editingFinished()), 
00100                          this, SLOT(customRateChanged()));
00101 
00102   /* Set validators for address, mask and various port number fields */
00103   ui.lineServerNickname->setValidator(new NicknameValidator(this));
00104   ui.lineServerPort->setValidator(new QIntValidator(1, 65535, this));
00105   ui.lineDirPort->setValidator(new QIntValidator(1, 65535, this));
00106   ui.lineAvgRateLimit->setValidator(
00107     new QIntValidator(MIN_BANDWIDTH_RATE, MAX_BANDWIDTH_RATE, this));
00108   ui.lineMaxRateLimit->setValidator(
00109     new QIntValidator(MIN_BANDWIDTH_RATE, MAX_BANDWIDTH_RATE, this));
00110 }
00111 
00112 /** Destructor */
00113 ServerPage::~ServerPage()
00114 {
00115   delete _settings;
00116 }
00117 
00118 /** Saves changes made to settings on the Server settings page. */
00119 bool
00120 ServerPage::save(QString &errmsg)
00121 {
00122   /* Force the bandwidth rate limits to validate */
00123   customRateChanged();
00124   
00125   if (ui.chkEnableServer->isChecked()) {
00126     /* A server must have an ORPort and a nickname */
00127     if (ui.lineServerPort->text().isEmpty() ||
00128         ui.lineServerNickname->text().isEmpty()) {
00129       errmsg = tr("You must specify at least a server nickname and port.");
00130       return false;
00131     }
00132     /* If the bandwidth rates aren't set, use some defaults before saving */
00133     if (ui.lineAvgRateLimit->text().isEmpty()) {
00134       ui.lineAvgRateLimit->setText(QString::number(2097152/1024) /* 2MB */);
00135     }
00136     if (ui.lineMaxRateLimit->text().isEmpty()) {
00137       ui.lineMaxRateLimit->setText(QString::number(5242880/1024) /* 5MB */);
00138     }
00139   }
00140   _settings->setServerEnabled(ui.chkEnableServer->isChecked());
00141   _settings->setDirectoryMirror(ui.chkMirrorDirectory->isChecked());
00142   _settings->setNickname(ui.lineServerNickname->text());
00143   _settings->setORPort(ui.lineServerPort->text().toUInt());
00144   _settings->setDirPort(ui.lineDirPort->text().toUInt());
00145   _settings->setContactInfo(ui.lineServerContact->text());
00146   saveBandwidthLimits();
00147   saveExitPolicies();
00148 
00149   /* If we're connected to Tor and we've changed the server settings, attempt
00150    * to apply the new settings now. */
00151   if (_torControl->isConnected() && _settings->changedSinceLastApply()) {
00152     if (!_settings->apply(&errmsg)) {
00153       _settings->revert();
00154       return false;
00155     }
00156   }
00157   return true;
00158 }
00159 
00160 /** Loads previously saved settings */
00161 void
00162 ServerPage::load()
00163 {
00164   ui.chkEnableServer->setChecked(_settings->isServerEnabled());
00165   ui.chkMirrorDirectory->setChecked(_settings->isDirectoryMirror());
00166 
00167   ui.lineServerNickname->setText(_settings->getNickname());
00168   ui.lineServerPort->setText(QString::number(_settings->getORPort()));
00169   ui.lineDirPort->setText(QString::number(_settings->getDirPort()));
00170   ui.lineServerContact->setText(_settings->getContactInfo());
00171   loadBandwidthLimits();
00172   loadExitPolicies();
00173 
00174   ui.frmServer->setVisible(ui.chkEnableServer->isChecked());
00175 }
00176 
00177 /** Shows exit policy related help information */
00178 void
00179 ServerPage::exitPolicyHelp()
00180 {
00181   Vidalia::help(EXIT_POLICY_HELP);
00182 }
00183 
00184 /** Shows the bandwidth rate limiting help information */
00185 void
00186 ServerPage::bandwidthHelp()
00187 {
00188   Vidalia::help(BANDWIDTH_HELP);
00189 }
00190 
00191 /** Loads the server's bandwidth average and burst limits. */
00192 void
00193 ServerPage::loadBandwidthLimits()
00194 {
00195   quint32 avgRate = _settings->getBandwidthAvgRate();
00196   quint32 maxRate = _settings->getBandwidthBurstRate();
00197 
00198   if (avgRate == CABLE256_AVG_RATE && 
00199       maxRate == CABLE256_MAX_RATE) {
00200     /* Cable/DSL 256 Kbps */
00201     ui.cmboRate->setCurrentIndex(CableDsl256); 
00202   } else if (avgRate == CABLE512_AVG_RATE && 
00203              maxRate == CABLE512_MAX_RATE) {
00204     /* Cable/DSL 512 Kbps */
00205     ui.cmboRate->setCurrentIndex(CableDsl512);
00206   } else if (avgRate == CABLE768_AVG_RATE && 
00207              maxRate == CABLE768_MAX_RATE) {
00208     /* Cable/DSL 768 Kbps */
00209     ui.cmboRate->setCurrentIndex(CableDsl768);
00210   } else if (avgRate == T1_AVG_RATE && 
00211              maxRate == T1_MAX_RATE) {
00212     /* T1/Cable/DSL 1.5 Mbps */
00213     ui.cmboRate->setCurrentIndex(T1CableDsl1500);
00214   } else if (avgRate == HIGHBW_AVG_RATE && 
00215              maxRate == HIGHBW_MAX_RATE) {
00216     /* > 1.5 Mbps */
00217     ui.cmboRate->setCurrentIndex(GreaterThan1500);
00218   } else {
00219     /* Custom bandwidth limits */
00220     ui.cmboRate->setCurrentIndex(CustomBwLimits);
00221   }
00222   /* Fill in the custom bandwidth limit boxes */
00223   ui.lineAvgRateLimit->setText(QString::number(avgRate/1024));
00224   ui.lineMaxRateLimit->setText(QString::number(maxRate/1024));
00225 }
00226 
00227 /** Saves the server's bandwidth average and burst limits. */
00228 void
00229 ServerPage::saveBandwidthLimits()
00230 {
00231   quint32 avgRate, maxRate;
00232 
00233   switch (ui.cmboRate->currentIndex()) {
00234     case CableDsl256: /* Cable/DSL 256 Kbps */
00235       avgRate = CABLE256_AVG_RATE;
00236       maxRate = CABLE256_MAX_RATE;
00237       break;
00238     case CableDsl512: /* Cable/DSL 512 Kbps */
00239       avgRate = CABLE512_AVG_RATE;
00240       maxRate = CABLE512_MAX_RATE;
00241       break;
00242     case CableDsl768: /* Cable/DSL 768 Kbps */
00243       avgRate = CABLE768_AVG_RATE;
00244       maxRate = CABLE768_MAX_RATE;
00245       break;
00246     case T1CableDsl1500: /* T1/Cable/DSL 1.5 Mbps */
00247       avgRate = T1_AVG_RATE;
00248       maxRate = T1_MAX_RATE;
00249       break;
00250     case GreaterThan1500: /* > 1.5 Mbps */
00251       avgRate = HIGHBW_AVG_RATE;
00252       maxRate = HIGHBW_MAX_RATE;
00253       break;
00254     default: /* Custom bandwidth limits */
00255       avgRate = (quint32)(ui.lineAvgRateLimit->text().toUInt()*1024);
00256       maxRate = (quint32)(ui.lineMaxRateLimit->text().toUInt()*1024);
00257       break;
00258   }
00259   _settings->setBandwidthAvgRate(avgRate);
00260   _settings->setBandwidthBurstRate(maxRate);
00261 }
00262 
00263 /** */
00264 void
00265 ServerPage::loadExitPolicies()
00266 {
00267   ExitPolicy exitPolicy = _settings->getExitPolicy();
00268   
00269   if (exitPolicy.contains(Policy(Policy::RejectAll))) {
00270     /* If the policy ends with reject *:*, check if the policy explicitly
00271      * accepts these ports */
00272     ui.chkWebsites->setChecked(exitPolicy.acceptsPorts(PORTS_HTTP));
00273     ui.chkSecWebsites->setChecked(exitPolicy.acceptsPorts(PORTS_HTTPS));
00274     ui.chkMail->setChecked(exitPolicy.acceptsPorts(PORTS_MAIL));
00275     ui.chkIRC->setChecked(exitPolicy.acceptsPorts(PORTS_IRC));
00276     ui.chkIM->setChecked(exitPolicy.acceptsPorts(PORTS_IM));
00277     ui.chkMisc->setChecked(false);
00278   } else {
00279     /* If the exit policy ends with accept *:*, check if the policy explicitly
00280      * rejects these ports */
00281     ui.chkWebsites->setChecked(!exitPolicy.rejectsPorts(PORTS_HTTP));
00282     ui.chkSecWebsites->setChecked(!exitPolicy.rejectsPorts(PORTS_HTTPS));
00283     ui.chkMail->setChecked(!exitPolicy.rejectsPorts(PORTS_MAIL));
00284     ui.chkIRC->setChecked(!exitPolicy.rejectsPorts(PORTS_IRC));
00285     ui.chkIM->setChecked(!exitPolicy.rejectsPorts(PORTS_IM));
00286     ui.chkMisc->setChecked(true);
00287   }
00288 }
00289 
00290 /** */
00291 void
00292 ServerPage::saveExitPolicies()
00293 {
00294   ExitPolicy exitPolicy;
00295   bool rejectUnchecked = ui.chkMisc->isChecked();
00296   
00297   /* If misc is checked, then reject unchecked items and leave the default exit
00298    * policy alone. Else, accept only checked items and end with reject *:*,
00299    * replacing the default exit policy. */
00300   if (ui.chkWebsites->isChecked() && !rejectUnchecked) {
00301     exitPolicy.addAcceptedPorts(PORTS_HTTP);
00302   } else if (!ui.chkWebsites->isChecked() && rejectUnchecked) {
00303     exitPolicy.addRejectedPorts(PORTS_HTTP);
00304   }
00305   if (ui.chkSecWebsites->isChecked() && !rejectUnchecked) {
00306     exitPolicy.addAcceptedPorts(PORTS_HTTPS);
00307   } else if (!ui.chkSecWebsites->isChecked() && rejectUnchecked) {
00308     exitPolicy.addRejectedPorts(PORTS_HTTPS);
00309   }
00310   if (ui.chkMail->isChecked() && !rejectUnchecked) {
00311     exitPolicy.addAcceptedPorts(PORTS_MAIL);
00312   } else if (!ui.chkMail->isChecked() && rejectUnchecked) {
00313     exitPolicy.addRejectedPorts(PORTS_MAIL);
00314   }
00315   if (ui.chkIRC->isChecked() && !rejectUnchecked) {
00316     exitPolicy.addAcceptedPorts(PORTS_IRC);
00317   } else if (!ui.chkIRC->isChecked() && rejectUnchecked) {
00318     exitPolicy.addRejectedPorts(PORTS_IRC);
00319   }
00320   if (ui.chkIM->isChecked() && !rejectUnchecked) {
00321     exitPolicy.addAcceptedPorts(PORTS_IM);
00322   } else if (!ui.chkIM->isChecked() && rejectUnchecked) {
00323     exitPolicy.addRejectedPorts(PORTS_IM);
00324   }
00325   if (!ui.chkMisc->isChecked()) {
00326     exitPolicy.addPolicy(Policy(Policy::RejectAll));
00327   }
00328   _settings->setExitPolicy(exitPolicy);
00329 }
00330 
00331 /** Called when the user selects a new value from the rate combo box. */
00332 void
00333 ServerPage::rateChanged(int index)
00334 {
00335   /* If the "Custom" option is selected, show the custom bandwidth 
00336    * limits form. */
00337   ui.frmCustomRate->setVisible(index == CustomBwLimits);
00338 }
00339 
00340 /** Called when the user edits the long-term average or maximum bandwidth limit. 
00341  * This ensures that the average bandwidth rate is greater than MIN_RATE
00342  * (20KB/s) and that the max rate is greater than the average rate. */
00343 void
00344 ServerPage::customRateChanged()
00345 {
00346   /* Make sure the average rate isn't too low or too high */
00347   quint32 avgRate = (quint32)ui.lineAvgRateLimit->text().toUInt();
00348   if (avgRate < MIN_BANDWIDTH_RATE) {
00349     ui.lineAvgRateLimit->setText(QString::number(MIN_BANDWIDTH_RATE));    
00350   }
00351   if (avgRate > MAX_BANDWIDTH_RATE) {
00352     ui.lineAvgRateLimit->setText(QString::number(MAX_BANDWIDTH_RATE));
00353   }
00354   /* Ensure the max burst rate is greater than the average rate but less than
00355    * the maximum allowed rate. */
00356   quint32 burstRate = (quint32)ui.lineMaxRateLimit->text().toUInt();
00357   if (avgRate > burstRate) {
00358     ui.lineMaxRateLimit->setText(QString::number(avgRate));
00359   }
00360   if (burstRate > MAX_BANDWIDTH_RATE) {
00361     ui.lineMaxRateLimit->setText(QString::number(MAX_BANDWIDTH_RATE));
00362   }
00363 }
00364 

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