Vidalia
0.2.17
|
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.torproject.org/projects/vidalia.html. No part of Vidalia, 00007 ** including this file, may be copied, modified, propagated, or distributed 00008 ** except according to the terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file ServerPage.cpp 00013 ** \brief Tor server configuration options 00014 */ 00015 00016 #include "config.h" 00017 #include "ServerPage.h" 00018 #include "Vidalia.h" 00019 #include "VMessageBox.h" 00020 #include "ConfigDialog.h" 00021 #include "IpValidator.h" 00022 #include "PortValidator.h" 00023 #include "DomainValidator.h" 00024 #include "NicknameValidator.h" 00025 #include "BridgeUsageDialog.h" 00026 00027 #include "html.h" 00028 #include "stringutil.h" 00029 00030 #if defined(USE_MINIUPNPC) 00031 #include "UPNPTestDialog.h" 00032 #endif 00033 00034 00035 #include <QClipboard> 00036 #include <QMessageBox> 00037 00038 /* These are completely made up values (in bytes/sec). */ 00039 #define CABLE256_AVG_RATE (32*1024) 00040 #define CABLE256_MAX_RATE (64*1024) 00041 #define CABLE512_AVG_RATE (64*1024) 00042 #define CABLE512_MAX_RATE (128*1024) 00043 #define CABLE768_AVG_RATE (96*1024) 00044 #define CABLE768_MAX_RATE (192*1024) 00045 #define T1_AVG_RATE (192*1024) 00046 #define T1_MAX_RATE (384*1024) 00047 #define HIGHBW_AVG_RATE (5120*1024) 00048 #define HIGHBW_MAX_RATE (10240*1024) 00049 /** Minimum allowed bandwidth rate (20KB) */ 00050 #define MIN_BANDWIDTH_RATE 20 00051 /** Maximum bandwidth rate. This is limited to 2147483646 bytes, 00052 * or 2097151 kilobytes. (2147483646/1024) */ 00053 #define MAX_BANDWIDTH_RATE 2097151 00054 00055 /** Ports represented by the "Websites" checkbox. (80) */ 00056 #define PORTS_HTTP (QStringList() << "80") 00057 /** Ports represented by the "Secure Websites" checkbox. (443) */ 00058 #define PORTS_HTTPS (QStringList() << "443") 00059 /** Ports represented by the "Retrieve Mail" checkbox. (110,143,993,995) */ 00060 #define PORTS_MAIL (QStringList() << "110" << "143" << "993" << "995") 00061 /** Ports represented by the "Instant Messaging" checkbox. 00062 * (703,1863,5050,5190,5222,8300,8888) */ 00063 #define PORTS_IM (QStringList() << "706" << "1863" << "5050" << "5190" \ 00064 << "5222" << "5223" << "8300" << "8888") 00065 /** Ports represented by the "Internet Relay Chat" checkbox. 00066 * (6660-6669,6697,7000-7001) */ 00067 #define PORTS_IRC (QStringList() << "6660-6669" << "6697" << "7000-7001") 00068 00069 00070 /** Constructor */ 00071 ServerPage::ServerPage(QWidget *parent) 00072 : ConfigPage(parent, "Server") 00073 { 00074 /* Invoke the Qt Designer generated object setup routine */ 00075 ui.setupUi(this); 00076 00077 /* Create ServerSettings object */ 00078 _settings = new ServerSettings(Vidalia::torControl()); 00079 00080 /* Bind events to actions */ 00081 connect(ui.btnRateHelp, SIGNAL(clicked()), this, SLOT(bandwidthHelp())); 00082 connect(ui.btnExitHelp, SIGNAL(clicked()), this, SLOT(exitPolicyHelp())); 00083 connect(ui.btnUpnpHelp, SIGNAL(clicked()), this, SLOT(upnpHelp())); 00084 connect(ui.cmboRate, SIGNAL(currentIndexChanged(int)), 00085 this, SLOT(rateChanged(int))); 00086 connect(ui.lineAvgRateLimit, SIGNAL(editingFinished()), 00087 this, SLOT(customRateChanged())); 00088 connect(ui.lineMaxRateLimit, SIGNAL(editingFinished()), 00089 this, SLOT(customRateChanged())); 00090 connect(ui.rdoClientMode, SIGNAL(toggled(bool)), 00091 this, SLOT(serverModeChanged(bool))); 00092 connect(ui.rdoNonExitMode, SIGNAL(toggled(bool)), 00093 this, SLOT(serverModeChanged(bool))); 00094 connect(ui.rdoServerMode, SIGNAL(toggled(bool)), 00095 this, SLOT(serverModeChanged(bool))); 00096 connect(ui.rdoBridgeMode, SIGNAL(toggled(bool)), 00097 this, SLOT(serverModeChanged(bool))); 00098 connect(Vidalia::torControl(), SIGNAL(authenticated()), 00099 this, SLOT(onAuthenticated())); 00100 connect(Vidalia::torControl(), SIGNAL(disconnected()), 00101 this, SLOT(onDisconnected())); 00102 connect(ui.btnCopyBridgeIdentity, SIGNAL(clicked()), 00103 this, SLOT(copyBridgeIdentity())); 00104 connect(ui.lblBridgeUsage, SIGNAL(linkActivated(QString)), 00105 this, SLOT(linkActivated(QString))); 00106 connect(ui.lblWhatsThis, SIGNAL(linkActivated(QString)), 00107 this, SLOT(linkActivated(QString))); 00108 00109 /* Set validators for address, mask and various port number fields */ 00110 ui.lineServerNickname->setValidator(new NicknameValidator(this)); 00111 ui.lineServerPort->setValidator(new QIntValidator(1, 65535, this)); 00112 ui.lineDirPort->setValidator(new QIntValidator(1, 65535, this)); 00113 ui.lineAvgRateLimit->setValidator( 00114 new QIntValidator(MIN_BANDWIDTH_RATE, MAX_BANDWIDTH_RATE, this)); 00115 ui.lineMaxRateLimit->setValidator( 00116 new QIntValidator(MIN_BANDWIDTH_RATE, MAX_BANDWIDTH_RATE, this)); 00117 00118 #if defined(USE_MINIUPNPC) 00119 connect(ui.btnTestUpnp, SIGNAL(clicked()), this, SLOT(testUpnp())); 00120 #else 00121 ui.chkEnableUpnp->setVisible(false); 00122 ui.btnTestUpnp->setVisible(false); 00123 #endif 00124 00125 _tmpDirPort = "9030"; 00126 _tmpMirror = true; 00127 } 00128 00129 /** Destructor */ 00130 ServerPage::~ServerPage() 00131 { 00132 delete _settings; 00133 } 00134 00135 /** Called when the user changes the UI translation. */ 00136 void 00137 ServerPage::retranslateUi() 00138 { 00139 ui.retranslateUi(this); 00140 } 00141 00142 /** Called when Vidalia has authenticated to Tor. If the user's Tor is not 00143 * recent enough, this disables the bridge server option and displays a 00144 * warning if the user had previously configured Tor as a bridge. */ 00145 void 00146 ServerPage::onAuthenticated() 00147 { 00148 quint32 torVersion = Vidalia::torControl()->getTorVersion(); 00149 if (torVersion < 0x020008) { 00150 ui.rdoBridgeMode->setEnabled(false); 00151 if (ui.rdoBridgeMode->isChecked()) { 00152 int ret = VMessageBox::warning(this, 00153 tr("Bridge Support Unavailable"), 00154 p(tr("You have configured Tor to act as a bridge relay " 00155 "for censored users, but your version of Tor does not " 00156 "support bridges.")) + 00157 p(tr("Please upgrade your Tor software or configure Tor to " 00158 "act as a normal Tor relay.")), 00159 VMessageBox::ShowSettings|VMessageBox::Default, 00160 VMessageBox::Cancel); 00161 if (ret == VMessageBox::ShowSettings) { 00162 ConfigDialog *dialog = dynamic_cast<ConfigDialog *>(window()); 00163 if (dialog) 00164 dialog->showWindow(ConfigDialog::Server); 00165 } 00166 } 00167 } 00168 } 00169 00170 /** Called when Vidalia disconnects from Tor. This method reenables the bridge 00171 * server option. */ 00172 void 00173 ServerPage::onDisconnected() 00174 { 00175 ui.rdoBridgeMode->setEnabled(true); 00176 } 00177 00178 /** Copies the user's bridge relay identity to the clipboard. */ 00179 void 00180 ServerPage::copyBridgeIdentity() 00181 { 00182 QString bridge = ui.lblBridgeIdentity->text(); 00183 if (!bridge.isEmpty()) 00184 vApp->clipboard()->setText(bridge); 00185 } 00186 00187 /** Loads the user's bridge relay identity into the appropriate widgets. If 00188 * the user's bridge is not running, then "Not Running" will be displayed. 00189 * Otherwise, either the bridge's "address:port", "fingerprint", or 00190 * "address:port fingerprint" will be displayed, depending on whether our 00191 * GETCONF and GETINFO commands are successful. */ 00192 void 00193 ServerPage::loadBridgeIdentity() 00194 { 00195 TorControl *tc = Vidalia::torControl(); 00196 QString bridge, address, orPort, fingerprint; 00197 00198 if (tc->isConnected()) { 00199 tc->getInfo("address", address); 00200 tc->getInfo("fingerprint", fingerprint); 00201 tc->getConf("ORPort", orPort); 00202 00203 if (!address.isEmpty() && !orPort.isEmpty() && orPort != "0") 00204 bridge = address + ":" + orPort + " "; 00205 if (!fingerprint.isEmpty()) 00206 bridge += fingerprint; 00207 bridge = bridge.trimmed(); 00208 } 00209 00210 ui.lblBridgeIdentity->setText(bridge.isEmpty() 00211 ? tr("Your bridge relay is not running.") 00212 : bridge); 00213 ui.lblYourBridgeRelayIs->setEnabled(!bridge.isEmpty()); 00214 ui.lblBridgeIdentity->setEnabled(!bridge.isEmpty()); 00215 ui.btnCopyBridgeIdentity->setEnabled(!bridge.isEmpty()); 00216 } 00217 00218 /** Called when the user toggles any one of the server mode radio buttons 00219 * and hides or displays the server configuration tabs appropriately. */ 00220 void 00221 ServerPage::serverModeChanged(bool enabled) 00222 { 00223 Q_UNUSED(enabled); 00224 bool bridgeEnabled = ui.rdoBridgeMode->isChecked(); 00225 bool relayEnabled = ui.rdoServerMode->isChecked() || 00226 ui.rdoNonExitMode->isChecked(); 00227 00228 /* Show the tab menu only if the user is running a normal relay or a bridge 00229 * relay. */ 00230 ui.tabsMenu->setVisible(relayEnabled || bridgeEnabled); 00231 00232 /* Disable the Exit Policies tab when bridge relay mode is selected */ 00233 ui.tabsMenu->setTabEnabled(2, !bridgeEnabled); 00234 00235 /* Display the widgets that show the user their bridge identity if bridge 00236 * relay mode is selected. */ 00237 ui.lblYourBridgeRelayIs->setVisible(bridgeEnabled); 00238 ui.lblBridgeIdentity->setVisible(bridgeEnabled); 00239 ui.btnCopyBridgeIdentity->setVisible(bridgeEnabled); 00240 ui.chkPublishBridgeAddress->setVisible(bridgeEnabled); 00241 ui.lblBridgeUsage->setVisible(bridgeEnabled 00242 && Vidalia::torControl()->isConnected()); 00243 00244 if(bridgeEnabled) { 00245 if(ui.lineDirPort->text().length() != 0) { 00246 _tmpDirPort = ui.lineDirPort->text(); 00247 _tmpMirror = ui.chkMirrorDirectory->isChecked(); 00248 } 00249 ui.lineDirPort->clear(); 00250 ui.chkMirrorDirectory->setChecked(false); 00251 } else { 00252 ui.lineDirPort->setText(_tmpDirPort); 00253 ui.chkMirrorDirectory->setChecked(_tmpMirror); 00254 } 00255 00256 ui.chkMirrorDirectory->setEnabled(!bridgeEnabled); 00257 if(ui.chkMirrorDirectory->isChecked()) { 00258 ui.lblDirPort->setEnabled(!bridgeEnabled); 00259 ui.lineDirPort->setEnabled(!bridgeEnabled); 00260 } 00261 00262 /* Disable the Exit Policies tab when bridge or non-exit relay mode is 00263 * selected */ 00264 ui.tabsMenu->setTabEnabled(2, !bridgeEnabled and !ui.rdoNonExitMode->isChecked()); 00265 } 00266 00267 /** Returns true if the user has changed their server settings since the 00268 * last time they were applied to Tor. */ 00269 bool 00270 ServerPage::changedSinceLastApply() 00271 { 00272 return _settings->changedSinceLastApply(); 00273 } 00274 00275 /** Applies the server configuration settings to Tor. Returns true if the 00276 * settings were applied successfully. Otherwise, <b>errmsg</b> is 00277 * set and false is returned. */ 00278 bool 00279 ServerPage::apply(QString &errmsg) 00280 { 00281 return _settings->apply(&errmsg); 00282 } 00283 00284 /** Returns true if the user has changed their server settings since the 00285 * last time they were applied to Tor. */ 00286 void 00287 ServerPage::revert() 00288 { 00289 _settings->revert(); 00290 } 00291 00292 /** Saves changes made to settings on the Server settings page. */ 00293 bool 00294 ServerPage::save(QString &errmsg) 00295 { 00296 /* Force the bandwidth rate limits to validate */ 00297 customRateChanged(); 00298 00299 if (ui.rdoServerMode->isChecked() || 00300 ui.rdoNonExitMode->isChecked() || 00301 ui.rdoBridgeMode->isChecked()) { 00302 /* A server must have an ORPort and a nickname */ 00303 if (ui.lineServerPort->text().isEmpty() || 00304 ui.lineServerNickname->text().isEmpty()) { 00305 errmsg = tr("You must specify at least a relay nickname and port."); 00306 return false; 00307 } 00308 /* If the bandwidth rates aren't set, use some defaults before saving */ 00309 if (ui.lineAvgRateLimit->text().isEmpty()) { 00310 ui.lineAvgRateLimit->setText(QString::number(2097152/1024) /* 2MB */); 00311 } 00312 if (ui.lineMaxRateLimit->text().isEmpty()) { 00313 ui.lineMaxRateLimit->setText(QString::number(5242880/1024) /* 5MB */); 00314 } 00315 } 00316 00317 /* "Server" is enabled whether we're a bridge or normal relay. "Bridge" is 00318 * only enabled if we're a bridge (obviously). */ 00319 _settings->setServerEnabled(ui.rdoServerMode->isChecked() 00320 || ui.rdoNonExitMode->isChecked() 00321 || ui.rdoBridgeMode->isChecked()); 00322 _settings->setNonExitEnabled(ui.rdoNonExitMode->isChecked()); 00323 _settings->setBridgeEnabled(ui.rdoBridgeMode->isChecked()); 00324 if (ui.rdoBridgeMode->isChecked()) 00325 _settings->setPublishServerDescriptor(ui.chkPublishBridgeAddress->isChecked()); 00326 00327 /* Save the rest of the server settings. */ 00328 _settings->setNickname(ui.lineServerNickname->text()); 00329 _settings->setORPort(ui.lineServerPort->text().toUInt()); 00330 if (!ui.rdoBridgeMode->isChecked()) { 00331 _settings->setDirPort(ui.lineDirPort->text().toUInt()); 00332 _settings->setDirectoryMirror(ui.chkMirrorDirectory->isChecked()); 00333 } else { 00334 _settings->setDirectoryMirror(false); 00335 } 00336 _settings->setContactInfo(ui.lineServerContact->text()); 00337 saveBandwidthLimits(); 00338 saveExitPolicies(); 00339 00340 #if defined(USE_MINIUPNPC) 00341 _settings->setUpnpEnabled(ui.chkEnableUpnp->isChecked()); 00342 #endif 00343 00344 return true; 00345 } 00346 00347 /** Loads previously saved settings */ 00348 void 00349 ServerPage::load() 00350 { 00351 if (_settings->isBridgeEnabled()) 00352 ui.rdoBridgeMode->setChecked(true); 00353 else if (_settings->isNonExitEnabled()) { 00354 if(_settings->getExitPolicy().toString() != "reject *:*") 00355 ui.rdoServerMode->setChecked(true); 00356 else 00357 ui.rdoNonExitMode->setChecked(true); 00358 } else if (_settings->isServerEnabled()) { 00359 if(_settings->getExitPolicy().toString() == "reject *:*") 00360 ui.rdoNonExitMode->setChecked(true); 00361 else 00362 ui.rdoServerMode->setChecked(true); 00363 } else 00364 ui.rdoClientMode->setChecked(true); 00365 00366 ui.lineServerNickname->setText(_settings->getNickname()); 00367 ui.lineServerPort->setText(QString::number(_settings->getORPort())); 00368 ui.lineDirPort->setText(QString::number(_settings->getDirPort())); 00369 ui.lineServerContact->setText(_settings->getContactInfo()); 00370 ui.chkMirrorDirectory->setChecked(_settings->isDirectoryMirror()); 00371 ui.lblBridgeUsage->setVisible(_settings->isBridgeEnabled() 00372 && Vidalia::torControl()->isConnected()); 00373 ui.chkPublishBridgeAddress->setChecked(_settings->publishServerDescriptor()); 00374 00375 loadBandwidthLimits(); 00376 loadExitPolicies(); 00377 loadBridgeIdentity(); 00378 00379 #if defined(USE_MINIUPNPC) 00380 ui.chkEnableUpnp->setChecked(_settings->isUpnpEnabled()); 00381 #endif 00382 } 00383 00384 /** Shows exit policy related help information */ 00385 void 00386 ServerPage::exitPolicyHelp() 00387 { 00388 emit helpRequested("server.exitpolicy"); 00389 } 00390 00391 /** Shows the bandwidth rate limiting help information */ 00392 void 00393 ServerPage::bandwidthHelp() 00394 { 00395 emit helpRequested("server.bandwidth"); 00396 } 00397 00398 /** Loads the server's bandwidth average and burst limits. */ 00399 void 00400 ServerPage::loadBandwidthLimits() 00401 { 00402 quint32 avgRate = _settings->getBandwidthAvgRate(); 00403 quint32 maxRate = _settings->getBandwidthBurstRate(); 00404 00405 if (avgRate == CABLE256_AVG_RATE && 00406 maxRate == CABLE256_MAX_RATE) { 00407 /* Cable/DSL 256 Kbps */ 00408 ui.cmboRate->setCurrentIndex(CableDsl256); 00409 } else if (avgRate == CABLE512_AVG_RATE && 00410 maxRate == CABLE512_MAX_RATE) { 00411 /* Cable/DSL 512 Kbps */ 00412 ui.cmboRate->setCurrentIndex(CableDsl512); 00413 } else if (avgRate == CABLE768_AVG_RATE && 00414 maxRate == CABLE768_MAX_RATE) { 00415 /* Cable/DSL 768 Kbps */ 00416 ui.cmboRate->setCurrentIndex(CableDsl768); 00417 } else if (avgRate == T1_AVG_RATE && 00418 maxRate == T1_MAX_RATE) { 00419 /* T1/Cable/DSL 1.5 Mbps */ 00420 ui.cmboRate->setCurrentIndex(T1CableDsl1500); 00421 } else if (avgRate == HIGHBW_AVG_RATE && 00422 maxRate == HIGHBW_MAX_RATE) { 00423 /* > 1.5 Mbps */ 00424 ui.cmboRate->setCurrentIndex(GreaterThan1500); 00425 } else { 00426 /* Custom bandwidth limits */ 00427 ui.cmboRate->setCurrentIndex(CustomBwLimits); 00428 } 00429 /* Fill in the custom bandwidth limit boxes */ 00430 ui.lineAvgRateLimit->setText(QString::number(avgRate/1024)); 00431 ui.lineMaxRateLimit->setText(QString::number(maxRate/1024)); 00432 } 00433 00434 /** Saves the server's bandwidth average and burst limits. */ 00435 void 00436 ServerPage::saveBandwidthLimits() 00437 { 00438 quint32 avgRate, maxRate; 00439 00440 switch (ui.cmboRate->currentIndex()) { 00441 case CableDsl256: /* Cable/DSL 256 Kbps */ 00442 avgRate = CABLE256_AVG_RATE; 00443 maxRate = CABLE256_MAX_RATE; 00444 break; 00445 case CableDsl512: /* Cable/DSL 512 Kbps */ 00446 avgRate = CABLE512_AVG_RATE; 00447 maxRate = CABLE512_MAX_RATE; 00448 break; 00449 case CableDsl768: /* Cable/DSL 768 Kbps */ 00450 avgRate = CABLE768_AVG_RATE; 00451 maxRate = CABLE768_MAX_RATE; 00452 break; 00453 case T1CableDsl1500: /* T1/Cable/DSL 1.5 Mbps */ 00454 avgRate = T1_AVG_RATE; 00455 maxRate = T1_MAX_RATE; 00456 break; 00457 case GreaterThan1500: /* > 1.5 Mbps */ 00458 avgRate = HIGHBW_AVG_RATE; 00459 maxRate = HIGHBW_MAX_RATE; 00460 break; 00461 default: /* Custom bandwidth limits */ 00462 avgRate = (quint32)(ui.lineAvgRateLimit->text().toUInt()*1024); 00463 maxRate = (quint32)(ui.lineMaxRateLimit->text().toUInt()*1024); 00464 break; 00465 } 00466 _settings->setBandwidthAvgRate(avgRate); 00467 _settings->setBandwidthBurstRate(maxRate); 00468 } 00469 00470 /** */ 00471 void 00472 ServerPage::loadExitPolicies() 00473 { 00474 ExitPolicy exitPolicy = _settings->getExitPolicy(); 00475 00476 if (exitPolicy.contains(Policy(Policy::RejectAll))) { 00477 /* If the policy ends with reject *:*, check if the policy explicitly 00478 * accepts these ports */ 00479 ui.chkWebsites->setChecked(exitPolicy.acceptsPorts(PORTS_HTTP)); 00480 ui.chkSecWebsites->setChecked(exitPolicy.acceptsPorts(PORTS_HTTPS)); 00481 ui.chkMail->setChecked(exitPolicy.acceptsPorts(PORTS_MAIL)); 00482 ui.chkIRC->setChecked(exitPolicy.acceptsPorts(PORTS_IRC)); 00483 ui.chkIM->setChecked(exitPolicy.acceptsPorts(PORTS_IM)); 00484 ui.chkMisc->setChecked(false); 00485 } else { 00486 /* If the exit policy ends with accept *:*, check if the policy explicitly 00487 * rejects these ports */ 00488 ui.chkWebsites->setChecked(!exitPolicy.rejectsPorts(PORTS_HTTP)); 00489 ui.chkSecWebsites->setChecked(!exitPolicy.rejectsPorts(PORTS_HTTPS)); 00490 ui.chkMail->setChecked(!exitPolicy.rejectsPorts(PORTS_MAIL)); 00491 ui.chkIRC->setChecked(!exitPolicy.rejectsPorts(PORTS_IRC)); 00492 ui.chkIM->setChecked(!exitPolicy.rejectsPorts(PORTS_IM)); 00493 ui.chkMisc->setChecked(true); 00494 } 00495 } 00496 00497 /** */ 00498 void 00499 ServerPage::saveExitPolicies() 00500 { 00501 ExitPolicy *exitPolicy; 00502 if(ui.rdoNonExitMode->isChecked()) { 00503 exitPolicy = new ExitPolicy(ExitPolicy::Middleman); 00504 } else { 00505 exitPolicy = new ExitPolicy(); 00506 bool rejectUnchecked = ui.chkMisc->isChecked(); 00507 00508 /* If misc is checked, then reject unchecked items and leave the default exit 00509 * policy alone. Else, accept only checked items and end with reject *:*, 00510 * replacing the default exit policy. */ 00511 if (ui.chkWebsites->isChecked() && !rejectUnchecked) { 00512 exitPolicy->addAcceptedPorts(PORTS_HTTP); 00513 } else if (!ui.chkWebsites->isChecked() && rejectUnchecked) { 00514 exitPolicy->addRejectedPorts(PORTS_HTTP); 00515 } 00516 if (ui.chkSecWebsites->isChecked() && !rejectUnchecked) { 00517 exitPolicy->addAcceptedPorts(PORTS_HTTPS); 00518 } else if (!ui.chkSecWebsites->isChecked() && rejectUnchecked) { 00519 exitPolicy->addRejectedPorts(PORTS_HTTPS); 00520 } 00521 if (ui.chkMail->isChecked() && !rejectUnchecked) { 00522 exitPolicy->addAcceptedPorts(PORTS_MAIL); 00523 } else if (!ui.chkMail->isChecked() && rejectUnchecked) { 00524 exitPolicy->addRejectedPorts(PORTS_MAIL); 00525 } 00526 if (ui.chkIRC->isChecked() && !rejectUnchecked) { 00527 exitPolicy->addAcceptedPorts(PORTS_IRC); 00528 } else if (!ui.chkIRC->isChecked() && rejectUnchecked) { 00529 exitPolicy->addRejectedPorts(PORTS_IRC); 00530 } 00531 if (ui.chkIM->isChecked() && !rejectUnchecked) { 00532 exitPolicy->addAcceptedPorts(PORTS_IM); 00533 } else if (!ui.chkIM->isChecked() && rejectUnchecked) { 00534 exitPolicy->addRejectedPorts(PORTS_IM); 00535 } 00536 if (!ui.chkMisc->isChecked()) { 00537 exitPolicy->addPolicy(Policy(Policy::RejectAll)); 00538 } 00539 } 00540 00541 _settings->setExitPolicy(*exitPolicy); 00542 } 00543 00544 /** Called when the user selects a new value from the rate combo box. */ 00545 void 00546 ServerPage::rateChanged(int index) 00547 { 00548 /* If the "Custom" option is selected, show the custom bandwidth 00549 * limits form. */ 00550 ui.frmCustomRate->setVisible(index == CustomBwLimits); 00551 } 00552 00553 /** Called when the user edits the long-term average or maximum bandwidth limit. 00554 * This ensures that the average bandwidth rate is greater than MIN_RATE 00555 * (20KB/s) and that the max rate is greater than the average rate. */ 00556 void 00557 ServerPage::customRateChanged() 00558 { 00559 /* Make sure the average rate isn't too low or too high */ 00560 quint32 avgRate = (quint32)ui.lineAvgRateLimit->text().toUInt(); 00561 if (avgRate < MIN_BANDWIDTH_RATE) { 00562 ui.lineAvgRateLimit->setText(QString::number(MIN_BANDWIDTH_RATE)); 00563 } 00564 if (avgRate > MAX_BANDWIDTH_RATE) { 00565 ui.lineAvgRateLimit->setText(QString::number(MAX_BANDWIDTH_RATE)); 00566 } 00567 /* Ensure the max burst rate is greater than the average rate but less than 00568 * the maximum allowed rate. */ 00569 quint32 burstRate = (quint32)ui.lineMaxRateLimit->text().toUInt(); 00570 if (avgRate > burstRate) { 00571 ui.lineMaxRateLimit->setText(QString::number(avgRate)); 00572 } 00573 if (burstRate > MAX_BANDWIDTH_RATE) { 00574 ui.lineMaxRateLimit->setText(QString::number(MAX_BANDWIDTH_RATE)); 00575 } 00576 } 00577 00578 /** Tests automatic port forwarding using UPnP. */ 00579 void 00580 ServerPage::testUpnp() 00581 { 00582 #if defined(USE_MINIUPNPC) 00583 UPNPTestDialog dlg(ui.lineServerPort->text().toUInt(), 00584 ui.lineDirPort->text().toUInt(), this); 00585 00586 connect(&dlg, SIGNAL(help()), this, SLOT(upnpHelp())); 00587 00588 dlg.exec(); 00589 #endif 00590 } 00591 00592 /** Called when the user clicks the UPnP test dialog's help button. */ 00593 void 00594 ServerPage::upnpHelp() 00595 { 00596 emit helpRequested("server.upnp"); 00597 } 00598 00599 /** Called when the user clicks on a QLabel containing a hyperlink. */ 00600 void 00601 ServerPage::linkActivated(const QString &url) 00602 { 00603 if (!url.compare("#bridgeUsage")) 00604 displayBridgeUsage(); 00605 else if(!url.compare("#bridgeHelp")) 00606 emit helpRequested("bridges.about"); 00607 } 00608 00609 /** Retrieves bridge usage history from Tor, parses and validates it, and 00610 * then displays it in a new dialog. */ 00611 void 00612 ServerPage::displayBridgeUsage() 00613 { 00614 QString info; 00615 QMessageBox dlg(this); 00616 00617 info = Vidalia::torControl()->getInfo("status/clients-seen").toString(); 00618 if (info.isEmpty()) { 00619 goto none; 00620 } else { 00621 QDateTime timeStarted; 00622 QHash<QString,int> countrySummary; 00623 QHash<QString,QString> keyvals; 00624 BridgeUsageDialog dlg(this); 00625 bool ok; 00626 00627 keyvals = string_parse_keyvals(info, &ok); 00628 if (!ok || !keyvals.contains("TimeStarted") 00629 || !keyvals.contains("CountrySummary")) 00630 goto err; 00631 00632 timeStarted = QDateTime::fromString(keyvals.value("TimeStarted"), 00633 "yyyy-MM-dd HH:mm:ss"); 00634 if (!timeStarted.isValid()) 00635 goto err; 00636 00637 // Default is LocalTime, force UTC 00638 timeStarted.setTimeSpec(Qt::UTC); 00639 00640 QStringList summary = keyvals.value("CountrySummary") 00641 .split(",", QString::SkipEmptyParts); 00642 if (summary.isEmpty()) { 00643 goto none; 00644 } else { 00645 foreach (QString pair, summary) { 00646 QStringList parts = pair.split("="); 00647 if (parts.size() != 2) 00648 goto err; 00649 00650 countrySummary.insert(parts.at(0).toUpper(), parts.at(1).toInt(&ok)); 00651 if (!ok) 00652 goto err; 00653 } 00654 00655 dlg.update(timeStarted, countrySummary); 00656 dlg.exec(); 00657 } 00658 } 00659 return; 00660 00661 none: 00662 dlg.setIcon(QMessageBox::Information); 00663 dlg.setWindowTitle(tr("No Recent Usage")); 00664 dlg.setText(tr("No clients have used your relay recently.")); 00665 dlg.setInformativeText(tr("Leave your relay running so clients have " 00666 "a better chance of finding and using it.")); 00667 dlg.setStandardButtons(QMessageBox::Ok); 00668 dlg.exec(); 00669 return; 00670 00671 err: 00672 dlg.setIcon(QMessageBox::Warning); 00673 dlg.setWindowTitle(tr("Bridge History")); 00674 dlg.setText(tr("Vidalia was unable to retrieve your bridge's usage " 00675 "history.")); 00676 dlg.setInformativeText(tr("Tor returned an improperly formatted " 00677 "response when Vidalia requested your " 00678 "bridge's usage history.")); 00679 dlg.setDetailedText(tr("The returned response was: %1").arg(info)); 00680 dlg.setStandardButtons(QMessageBox::Ok); 00681 dlg.exec(); 00682 } 00683