Vidalia  0.3.1
ServerPage.cpp
Go to the documentation of this file.
1 /*
2 ** This file is part of Vidalia, and is subject to the license terms in the
3 ** LICENSE file, found in the top level directory of this distribution. If you
4 ** did not receive the LICENSE file with this file, you may obtain it from the
5 ** Vidalia source package distributed by the Vidalia Project at
6 ** http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
7 ** including this file, may be copied, modified, propagated, or distributed
8 ** except according to the terms described in the LICENSE file.
9 */
10 
11 /*
12 ** \file ServerPage.cpp
13 ** \brief Tor server configuration options
14 */
15 
16 #include "config.h"
17 #include "ServerPage.h"
18 #include "Vidalia.h"
19 #include "VMessageBox.h"
20 #include "ConfigDialog.h"
21 #include "IpValidator.h"
22 #include "PortValidator.h"
23 #include "DomainValidator.h"
24 #include "NicknameValidator.h"
25 #include "BridgeUsageDialog.h"
26 
27 #include "html.h"
28 #include "stringutil.h"
29 
30 #if defined(USE_MINIUPNPC)
31 #include "UPNPTestDialog.h"
32 #endif
33 
34 
35 #include <QClipboard>
36 #include <QMessageBox>
37 
38 /* These are completely made up values (in bytes/sec). */
39 #define CABLE256_AVG_RATE (32*1024)
40 #define CABLE256_MAX_RATE (64*1024)
41 #define CABLE512_AVG_RATE (64*1024)
42 #define CABLE512_MAX_RATE (128*1024)
43 #define CABLE768_AVG_RATE (96*1024)
44 #define CABLE768_MAX_RATE (192*1024)
45 #define T1_AVG_RATE (192*1024)
46 #define T1_MAX_RATE (384*1024)
47 #define HIGHBW_AVG_RATE (5120*1024)
48 #define HIGHBW_MAX_RATE (10240*1024)
49 /** Minimum allowed bandwidth rate (20KB) */
50 #define MIN_BANDWIDTH_RATE 20
51 /** Maximum bandwidth rate. This is limited to 2147483646 bytes,
52  * or 2097151 kilobytes. (2147483646/1024) */
53 #define MAX_BANDWIDTH_RATE 2097151
54 
55 /** Ports represented by the "Websites" checkbox. (80) */
56 #define PORTS_HTTP (QStringList() << "80")
57 /** Ports represented by the "Secure Websites" checkbox. (443) */
58 #define PORTS_HTTPS (QStringList() << "443")
59 /** Ports represented by the "Retrieve Mail" checkbox. (110,143,993,995) */
60 #define PORTS_MAIL (QStringList() << "110" << "143" << "993" << "995")
61 /** Ports represented by the "Instant Messaging" checkbox.
62  * (703,1863,5050,5190,5222,8300,8888) */
63 #define PORTS_IM (QStringList() << "706" << "1863" << "5050" << "5190" \
64  << "5222" << "5223" << "8300" << "8888")
65 /** Ports represented by the "Internet Relay Chat" checkbox.
66  * (6660-6669,6697,7000-7001) */
67 #define PORTS_IRC (QStringList() << "6660-6669" << "6697" << "7000-7001")
68 
69 
70 /** Constructor */
71 ServerPage::ServerPage(QWidget *parent)
72 : ConfigPage(parent, "Server")
73 {
74  /* Invoke the Qt Designer generated object setup routine */
75  ui.setupUi(this);
76 
77  /* Create ServerSettings object */
79 
80  /* Bind events to actions */
81  connect(ui.btnRateHelp, SIGNAL(clicked()), this, SLOT(bandwidthHelp()));
82  connect(ui.btnExitHelp, SIGNAL(clicked()), this, SLOT(exitPolicyHelp()));
83  connect(ui.btnUpnpHelp, SIGNAL(clicked()), this, SLOT(upnpHelp()));
84  connect(ui.cmboRate, SIGNAL(currentIndexChanged(int)),
85  this, SLOT(rateChanged(int)));
86  connect(ui.lineAvgRateLimit, SIGNAL(editingFinished()),
87  this, SLOT(customRateChanged()));
88  connect(ui.lineMaxRateLimit, SIGNAL(editingFinished()),
89  this, SLOT(customRateChanged()));
90  connect(ui.rdoClientMode, SIGNAL(toggled(bool)),
91  this, SLOT(serverModeChanged(bool)));
92  connect(ui.rdoNonExitMode, SIGNAL(toggled(bool)),
93  this, SLOT(serverModeChanged(bool)));
94  connect(ui.rdoServerMode, SIGNAL(toggled(bool)),
95  this, SLOT(serverModeChanged(bool)));
96  connect(ui.rdoBridgeMode, SIGNAL(toggled(bool)),
97  this, SLOT(serverModeChanged(bool)));
98  connect(Vidalia::torControl(), SIGNAL(authenticated()),
99  this, SLOT(onAuthenticated()));
100  connect(Vidalia::torControl(), SIGNAL(disconnected()),
101  this, SLOT(onDisconnected()));
102  connect(ui.btnCopyBridgeIdentity, SIGNAL(clicked()),
103  this, SLOT(copyBridgeIdentity()));
104  connect(ui.lblBridgeUsage, SIGNAL(linkActivated(QString)),
105  this, SLOT(linkActivated(QString)));
106  connect(ui.lblWhatsThis, SIGNAL(linkActivated(QString)),
107  this, SLOT(linkActivated(QString)));
108 
109  /* Set validators for address, mask and various port number fields */
110  ui.lineServerNickname->setValidator(new NicknameValidator(this));
111  ui.lineServerPort->setValidator(new QIntValidator(1, 65535, this));
112  ui.lineDirPort->setValidator(new QIntValidator(1, 65535, this));
113  ui.lineAvgRateLimit->setValidator(
114  new QIntValidator(MIN_BANDWIDTH_RATE, MAX_BANDWIDTH_RATE, this));
115  ui.lineMaxRateLimit->setValidator(
116  new QIntValidator(MIN_BANDWIDTH_RATE, MAX_BANDWIDTH_RATE, this));
117 
118 #if defined(USE_MINIUPNPC)
119  connect(ui.btnTestUpnp, SIGNAL(clicked()), this, SLOT(testUpnp()));
120 #else
121  ui.chkEnableUpnp->setVisible(false);
122  ui.btnTestUpnp->setVisible(false);
123 #endif
124 
125  _tmpDirPort = "9030";
126  _tmpMirror = true;
127 }
128 
129 /** Destructor */
131 {
132  delete _settings;
133 }
134 
135 /** Called when the user changes the UI translation. */
136 void
138 {
139  ui.retranslateUi(this);
140 }
141 
142 /** Called when Vidalia has authenticated to Tor. If the user's Tor is not
143  * recent enough, this disables the bridge server option and displays a
144  * warning if the user had previously configured Tor as a bridge. */
145 void
147 {
148  quint32 torVersion = Vidalia::torControl()->getTorVersion();
149  if (torVersion < 0x020008) {
150  ui.rdoBridgeMode->setEnabled(false);
151  if (ui.rdoBridgeMode->isChecked()) {
152  int ret = VMessageBox::warning(this,
153  tr("Bridge Support Unavailable"),
154  p(tr("You have configured Tor to act as a bridge relay "
155  "for censored users, but your version of Tor does not "
156  "support bridges.")) +
157  p(tr("Please upgrade your Tor software or configure Tor to "
158  "act as a normal Tor relay.")),
159  VMessageBox::ShowSettings|VMessageBox::Default,
161  if (ret == VMessageBox::ShowSettings) {
162  ConfigDialog *dialog = dynamic_cast<ConfigDialog *>(window());
163  if (dialog)
165  }
166  }
167  }
168 }
169 
170 /** Called when Vidalia disconnects from Tor. This method reenables the bridge
171  * server option. */
172 void
174 {
175  ui.rdoBridgeMode->setEnabled(true);
176 }
177 
178 /** Copies the user's bridge relay identity to the clipboard. */
179 void
181 {
182  QString bridge = ui.lblBridgeIdentity->text();
183  if (!bridge.isEmpty())
184  vApp->clipboard()->setText(bridge);
185 }
186 
187 /** Loads the user's bridge relay identity into the appropriate widgets. If
188  * the user's bridge is not running, then "Not Running" will be displayed.
189  * Otherwise, either the bridge's "address:port", "fingerprint", or
190  * "address:port fingerprint" will be displayed, depending on whether our
191  * GETCONF and GETINFO commands are successful. */
192 void
194 {
196  QString bridge, address, orPort, fingerprint;
197 
198  if (tc->isConnected()) {
199  tc->getInfo("address", address);
200  tc->getInfo("fingerprint", fingerprint);
201  tc->getConf("ORPort", orPort);
202 
203  if (!address.isEmpty() && !orPort.isEmpty() && orPort != "0")
204  bridge = address + ":" + orPort + " ";
205  if (!fingerprint.isEmpty())
206  bridge += fingerprint;
207  bridge = bridge.trimmed();
208  }
209 
210  ui.lblBridgeIdentity->setText(bridge.isEmpty()
211  ? tr("Your bridge relay is not running.")
212  : bridge);
213  ui.lblYourBridgeRelayIs->setEnabled(!bridge.isEmpty());
214  ui.lblBridgeIdentity->setEnabled(!bridge.isEmpty());
215  ui.btnCopyBridgeIdentity->setEnabled(!bridge.isEmpty());
216 }
217 
218 /** Called when the user toggles any one of the server mode radio buttons
219  * and hides or displays the server configuration tabs appropriately. */
220 void
222 {
223  Q_UNUSED(enabled);
224  bool bridgeEnabled = ui.rdoBridgeMode->isChecked();
225  bool relayEnabled = ui.rdoServerMode->isChecked() ||
226  ui.rdoNonExitMode->isChecked();
227 
228  /* Show the tab menu only if the user is running a normal relay or a bridge
229  * relay. */
230  ui.tabsMenu->setVisible(relayEnabled || bridgeEnabled);
231 
232  /* Display the widgets that show the user their bridge identity if bridge
233  * relay mode is selected. */
234  ui.lblYourBridgeRelayIs->setVisible(bridgeEnabled);
235  ui.lblBridgeIdentity->setVisible(bridgeEnabled);
236  ui.btnCopyBridgeIdentity->setVisible(bridgeEnabled);
237  ui.chkPublishBridgeAddress->setVisible(bridgeEnabled);
238  ui.lblBridgeUsage->setVisible(bridgeEnabled
240 
241  if(bridgeEnabled) {
242  if(ui.lineDirPort->text().length() != 0) {
243  _tmpDirPort = ui.lineDirPort->text();
244  _tmpMirror = ui.chkMirrorDirectory->isChecked();
245  }
246  ui.lineDirPort->clear();
247  ui.chkMirrorDirectory->setChecked(false);
248  } else {
249  ui.lineDirPort->setText(_tmpDirPort);
250  ui.chkMirrorDirectory->setChecked(_tmpMirror);
251  }
252 
253  ui.lineDirPort->setEnabled(!bridgeEnabled);
254  ui.lblDirPort->setEnabled(!bridgeEnabled);
255 
256  ui.chkMirrorDirectory->setEnabled(!bridgeEnabled);
257 
258  /* Disable the Exit Policies tab when bridge or non-exit relay mode is
259  * selected */
260  ui.tabsMenu->setTabEnabled(2, !bridgeEnabled and !ui.rdoNonExitMode->isChecked());
261 
262  if(ui.chkMirrorDirectory->isChecked()) {
263  ui.lblDirPort->setEnabled(!bridgeEnabled);
264  ui.lineDirPort->setEnabled(!bridgeEnabled);
265  }
266 }
267 
268 /** Returns true if the user has changed their server settings since the
269  * last time they were applied to Tor. */
270 bool
272 {
274 }
275 
276 /** Applies the server configuration settings to Tor. Returns true if the
277  * settings were applied successfully. Otherwise, <b>errmsg</b> is
278  * set and false is returned. */
279 bool
280 ServerPage::apply(QString &errmsg)
281 {
282  return _settings->apply(&errmsg);
283 }
284 
285 /** Returns true if the user has changed their server settings since the
286  * last time they were applied to Tor. */
287 void
289 {
290  _settings->revert();
291 }
292 
293 /** Saves changes made to settings on the Server settings page. */
294 bool
295 ServerPage::save(QString &errmsg)
296 {
297  /* Force the bandwidth rate limits to validate */
299 
300  if (ui.rdoServerMode->isChecked() ||
301  ui.rdoNonExitMode->isChecked() ||
302  ui.rdoBridgeMode->isChecked()) {
303  /* A server must have an ORPort and a nickname */
304  if (ui.lineServerPort->text().isEmpty() ||
305  ui.lineServerNickname->text().isEmpty()) {
306  errmsg = tr("You must specify at least a relay nickname and port.");
307  return false;
308  }
309  /* If the bandwidth rates aren't set, use some defaults before saving */
310  if (ui.lineAvgRateLimit->text().isEmpty()) {
311  ui.lineAvgRateLimit->setText(QString::number(2097152/1024) /* 2MB */);
312  }
313  if (ui.lineMaxRateLimit->text().isEmpty()) {
314  ui.lineMaxRateLimit->setText(QString::number(5242880/1024) /* 5MB */);
315  }
316  }
317 
318  /* "Server" is enabled whether we're a bridge or normal relay. "Bridge" is
319  * only enabled if we're a bridge (obviously). */
320  _settings->setServerEnabled(ui.rdoServerMode->isChecked()
321  || ui.rdoNonExitMode->isChecked()
322  || ui.rdoBridgeMode->isChecked());
323  _settings->setNonExitEnabled(ui.rdoNonExitMode->isChecked());
324  _settings->setBridgeEnabled(ui.rdoBridgeMode->isChecked());
325  if (ui.rdoBridgeMode->isChecked())
326  _settings->setPublishServerDescriptor(ui.chkPublishBridgeAddress->isChecked());
327 
328  /* Save the rest of the server settings. */
329  _settings->setNickname(ui.lineServerNickname->text());
330  _settings->setORPort(ui.lineServerPort->text().toUInt());
331  if (!ui.rdoBridgeMode->isChecked()) {
332  _settings->setDirPort(ui.lineDirPort->text().toUInt());
333  _settings->setDirectoryMirror(ui.chkMirrorDirectory->isChecked());
334  } else {
336  }
337  _settings->setContactInfo(ui.lineServerContact->text());
340 
341 #if defined(USE_MINIUPNPC)
342  _settings->setUpnpEnabled(ui.chkEnableUpnp->isChecked());
343 #endif
344 
345  return true;
346 }
347 
348 /** Loads previously saved settings */
349 void
351 {
352  if (_settings->isBridgeEnabled())
353  ui.rdoBridgeMode->setChecked(true);
354  else if (_settings->isNonExitEnabled()) {
355  if(_settings->getExitPolicy().toString() != "reject *:*")
356  ui.rdoServerMode->setChecked(true);
357  else
358  ui.rdoNonExitMode->setChecked(true);
359  } else if (_settings->isServerEnabled()) {
360  if(_settings->getExitPolicy().toString() == "reject *:*")
361  ui.rdoNonExitMode->setChecked(true);
362  else
363  ui.rdoServerMode->setChecked(true);
364  } else
365  ui.rdoClientMode->setChecked(true);
366 
367  ui.lineServerNickname->setText(_settings->getNickname());
368  ui.lineServerPort->setText(QString::number(_settings->getORPort()));
369  ui.lineDirPort->setText(QString::number(_settings->getDirPort()));
370  ui.lineServerContact->setText(_settings->getContactInfo());
371  ui.chkMirrorDirectory->setChecked(_settings->isDirectoryMirror());
372  ui.lblBridgeUsage->setVisible(_settings->isBridgeEnabled()
374  ui.chkPublishBridgeAddress->setChecked(_settings->publishServerDescriptor());
375 
379 
380 #if defined(USE_MINIUPNPC)
381  ui.chkEnableUpnp->setChecked(_settings->isUpnpEnabled());
382 #endif
383 }
384 
385 /** Shows exit policy related help information */
386 void
388 {
389  emit helpRequested("server.exitpolicy");
390 }
391 
392 /** Shows the bandwidth rate limiting help information */
393 void
395 {
396  emit helpRequested("server.bandwidth");
397 }
398 
399 /** Loads the server's bandwidth average and burst limits. */
400 void
402 {
405 
406  if (avgRate == CABLE256_AVG_RATE &&
407  maxRate == CABLE256_MAX_RATE) {
408  /* Cable/DSL 256 Kbps */
409  ui.cmboRate->setCurrentIndex(CableDsl256);
410  } else if (avgRate == CABLE512_AVG_RATE &&
411  maxRate == CABLE512_MAX_RATE) {
412  /* Cable/DSL 512 Kbps */
413  ui.cmboRate->setCurrentIndex(CableDsl512);
414  } else if (avgRate == CABLE768_AVG_RATE &&
415  maxRate == CABLE768_MAX_RATE) {
416  /* Cable/DSL 768 Kbps */
417  ui.cmboRate->setCurrentIndex(CableDsl768);
418  } else if (avgRate == T1_AVG_RATE &&
419  maxRate == T1_MAX_RATE) {
420  /* T1/Cable/DSL 1.5 Mbps */
421  ui.cmboRate->setCurrentIndex(T1CableDsl1500);
422  } else if (avgRate == HIGHBW_AVG_RATE &&
423  maxRate == HIGHBW_MAX_RATE) {
424  /* > 1.5 Mbps */
425  ui.cmboRate->setCurrentIndex(GreaterThan1500);
426  } else {
427  /* Custom bandwidth limits */
428  ui.cmboRate->setCurrentIndex(CustomBwLimits);
429  }
430  /* Fill in the custom bandwidth limit boxes */
431  ui.lineAvgRateLimit->setText(QString::number(avgRate/1024));
432  ui.lineMaxRateLimit->setText(QString::number(maxRate/1024));
433 }
434 
435 /** Saves the server's bandwidth average and burst limits. */
436 void
438 {
439  quint32 avgRate, maxRate;
440 
441  switch (ui.cmboRate->currentIndex()) {
442  case CableDsl256: /* Cable/DSL 256 Kbps */
443  avgRate = CABLE256_AVG_RATE;
444  maxRate = CABLE256_MAX_RATE;
445  break;
446  case CableDsl512: /* Cable/DSL 512 Kbps */
447  avgRate = CABLE512_AVG_RATE;
448  maxRate = CABLE512_MAX_RATE;
449  break;
450  case CableDsl768: /* Cable/DSL 768 Kbps */
451  avgRate = CABLE768_AVG_RATE;
452  maxRate = CABLE768_MAX_RATE;
453  break;
454  case T1CableDsl1500: /* T1/Cable/DSL 1.5 Mbps */
455  avgRate = T1_AVG_RATE;
456  maxRate = T1_MAX_RATE;
457  break;
458  case GreaterThan1500: /* > 1.5 Mbps */
459  avgRate = HIGHBW_AVG_RATE;
460  maxRate = HIGHBW_MAX_RATE;
461  break;
462  default: /* Custom bandwidth limits */
463  avgRate = (quint32)(ui.lineAvgRateLimit->text().toUInt()*1024);
464  maxRate = (quint32)(ui.lineMaxRateLimit->text().toUInt()*1024);
465  break;
466  }
467  _settings->setBandwidthAvgRate(avgRate);
469 }
470 
471 /** */
472 void
474 {
475  ExitPolicy exitPolicy = _settings->getExitPolicy();
476 
477  if (exitPolicy.contains(Policy(Policy::RejectAll))) {
478  /* If the policy ends with reject *:*, check if the policy explicitly
479  * accepts these ports */
480  ui.chkWebsites->setChecked(exitPolicy.acceptsPorts(PORTS_HTTP));
481  ui.chkSecWebsites->setChecked(exitPolicy.acceptsPorts(PORTS_HTTPS));
482  ui.chkMail->setChecked(exitPolicy.acceptsPorts(PORTS_MAIL));
483  ui.chkIRC->setChecked(exitPolicy.acceptsPorts(PORTS_IRC));
484  ui.chkIM->setChecked(exitPolicy.acceptsPorts(PORTS_IM));
485  ui.chkMisc->setChecked(false);
486  } else {
487  /* If the exit policy ends with accept *:*, check if the policy explicitly
488  * rejects these ports */
489  ui.chkWebsites->setChecked(!exitPolicy.rejectsPorts(PORTS_HTTP));
490  ui.chkSecWebsites->setChecked(!exitPolicy.rejectsPorts(PORTS_HTTPS));
491  ui.chkMail->setChecked(!exitPolicy.rejectsPorts(PORTS_MAIL));
492  ui.chkIRC->setChecked(!exitPolicy.rejectsPorts(PORTS_IRC));
493  ui.chkIM->setChecked(!exitPolicy.rejectsPorts(PORTS_IM));
494  ui.chkMisc->setChecked(true);
495  }
496 }
497 
498 /** */
499 void
501 {
502  ExitPolicy *exitPolicy;
503  if(ui.rdoNonExitMode->isChecked()) {
504  exitPolicy = new ExitPolicy(ExitPolicy::Middleman);
505  } else {
506  exitPolicy = new ExitPolicy();
507  bool rejectUnchecked = ui.chkMisc->isChecked();
508 
509  /* If misc is checked, then reject unchecked items and leave the default exit
510  * policy alone. Else, accept only checked items and end with reject *:*,
511  * replacing the default exit policy. */
512  if (ui.chkWebsites->isChecked() && !rejectUnchecked) {
513  exitPolicy->addAcceptedPorts(PORTS_HTTP);
514  } else if (!ui.chkWebsites->isChecked() && rejectUnchecked) {
515  exitPolicy->addRejectedPorts(PORTS_HTTP);
516  }
517  if (ui.chkSecWebsites->isChecked() && !rejectUnchecked) {
518  exitPolicy->addAcceptedPorts(PORTS_HTTPS);
519  } else if (!ui.chkSecWebsites->isChecked() && rejectUnchecked) {
520  exitPolicy->addRejectedPorts(PORTS_HTTPS);
521  }
522  if (ui.chkMail->isChecked() && !rejectUnchecked) {
523  exitPolicy->addAcceptedPorts(PORTS_MAIL);
524  } else if (!ui.chkMail->isChecked() && rejectUnchecked) {
525  exitPolicy->addRejectedPorts(PORTS_MAIL);
526  }
527  if (ui.chkIRC->isChecked() && !rejectUnchecked) {
528  exitPolicy->addAcceptedPorts(PORTS_IRC);
529  } else if (!ui.chkIRC->isChecked() && rejectUnchecked) {
530  exitPolicy->addRejectedPorts(PORTS_IRC);
531  }
532  if (ui.chkIM->isChecked() && !rejectUnchecked) {
533  exitPolicy->addAcceptedPorts(PORTS_IM);
534  } else if (!ui.chkIM->isChecked() && rejectUnchecked) {
535  exitPolicy->addRejectedPorts(PORTS_IM);
536  }
537  if (!ui.chkMisc->isChecked()) {
538  exitPolicy->addPolicy(Policy(Policy::RejectAll));
539  }
540  }
541  _settings->setExitPolicy(*exitPolicy);
542 }
543 
544 /** Called when the user selects a new value from the rate combo box. */
545 void
547 {
548  /* If the "Custom" option is selected, show the custom bandwidth
549  * limits form. */
550  ui.frmCustomRate->setVisible(index == CustomBwLimits);
551 }
552 
553 /** Called when the user edits the long-term average or maximum bandwidth limit.
554  * This ensures that the average bandwidth rate is greater than MIN_RATE
555  * (20KB/s) and that the max rate is greater than the average rate. */
556 void
558 {
559  /* Make sure the average rate isn't too low or too high */
560  quint32 avgRate = (quint32)ui.lineAvgRateLimit->text().toUInt();
561  if (avgRate < MIN_BANDWIDTH_RATE) {
562  ui.lineAvgRateLimit->setText(QString::number(MIN_BANDWIDTH_RATE));
563  }
564  if (avgRate > MAX_BANDWIDTH_RATE) {
565  ui.lineAvgRateLimit->setText(QString::number(MAX_BANDWIDTH_RATE));
566  }
567  /* Ensure the max burst rate is greater than the average rate but less than
568  * the maximum allowed rate. */
569  quint32 burstRate = (quint32)ui.lineMaxRateLimit->text().toUInt();
570  if (avgRate > burstRate) {
571  ui.lineMaxRateLimit->setText(QString::number(avgRate));
572  }
573  if (burstRate > MAX_BANDWIDTH_RATE) {
574  ui.lineMaxRateLimit->setText(QString::number(MAX_BANDWIDTH_RATE));
575  }
576 }
577 
578 /** Tests automatic port forwarding using UPnP. */
579 void
581 {
582 #if defined(USE_MINIUPNPC)
583  UPNPTestDialog dlg(ui.lineServerPort->text().toUInt(),
584  ui.lineDirPort->text().toUInt(), this);
585 
586  connect(&dlg, SIGNAL(help()), this, SLOT(upnpHelp()));
587 
588  dlg.exec();
589 #endif
590 }
591 
592 /** Called when the user clicks the UPnP test dialog's help button. */
593 void
595 {
596  emit helpRequested("server.upnp");
597 }
598 
599 /** Called when the user clicks on a QLabel containing a hyperlink. */
600 void
601 ServerPage::linkActivated(const QString &url)
602 {
603  if (!url.compare("#bridgeUsage"))
605  else if(!url.compare("#bridgeHelp"))
606  emit helpRequested("bridges.about");
607 }
608 
609 /** Retrieves bridge usage history from Tor, parses and validates it, and
610  * then displays it in a new dialog. */
611 void
613 {
614  QString info;
615  QMessageBox dlg(this);
616 
617  info = Vidalia::torControl()->getInfo("status/clients-seen").toString();
618  if (info.isEmpty()) {
619  goto none;
620  } else {
621  QDateTime timeStarted;
622  QHash<QString,int> countrySummary;
623  QHash<QString,QString> keyvals;
624  BridgeUsageDialog dlg(this);
625  bool ok;
626 
627  keyvals = string_parse_keyvals(info, &ok);
628  if (!ok || !keyvals.contains("TimeStarted")
629  || !keyvals.contains("CountrySummary"))
630  goto err;
631 
632  timeStarted = QDateTime::fromString(keyvals.value("TimeStarted"),
633  "yyyy-MM-dd HH:mm:ss");
634  if (!timeStarted.isValid())
635  goto err;
636 
637  // Default is LocalTime, force UTC
638  timeStarted.setTimeSpec(Qt::UTC);
639 
640  QStringList summary = keyvals.value("CountrySummary")
641  .split(",", QString::SkipEmptyParts);
642  if (summary.isEmpty()) {
643  goto none;
644  } else {
645  foreach (QString pair, summary) {
646  QStringList parts = pair.split("=");
647  if (parts.size() != 2)
648  goto err;
649 
650  countrySummary.insert(parts.at(0).toUpper(), parts.at(1).toInt(&ok));
651  if (!ok)
652  goto err;
653  }
654 
655  dlg.update(timeStarted, countrySummary);
656  dlg.exec();
657  }
658  }
659  return;
660 
661 none:
662  dlg.setIcon(QMessageBox::Information);
663  dlg.setWindowTitle(tr("No Recent Usage"));
664  dlg.setText(tr("No clients have used your relay recently."));
665  dlg.setInformativeText(tr("Leave your relay running so clients have "
666  "a better chance of finding and using it."));
667  dlg.setStandardButtons(QMessageBox::Ok);
668  dlg.exec();
669  return;
670 
671 err:
672  dlg.setIcon(QMessageBox::Warning);
673  dlg.setWindowTitle(tr("Bridge History"));
674  dlg.setText(tr("Vidalia was unable to retrieve your bridge's usage "
675  "history."));
676  dlg.setInformativeText(tr("Tor returned an improperly formatted "
677  "response when Vidalia requested your "
678  "bridge's usage history."));
679  dlg.setDetailedText(tr("The returned response was: %1").arg(info));
680  dlg.setStandardButtons(QMessageBox::Ok);
681  dlg.exec();
682 }
683 
QString p(QString str)
Definition: html.cpp:22
bool rejectsPorts(QStringList portList)
Definition: ExitPolicy.cpp:118
void setDirectoryMirror(bool mirror)
void rateChanged(int rate)
Definition: ServerPage.cpp:546
bool getConf(QHash< QString, QString > &map, QString *errmsg=0)
Definition: TorControl.cpp:766
void bandwidthHelp()
Definition: ServerPage.cpp:394
Definition: tcglobal.cpp:19
bool err(QString *str, const QString &errmsg)
Definition: stringutil.cpp:37
void upnpHelp()
Definition: ServerPage.cpp:594
QHash< QString, QString > string_parse_keyvals(const QString &str, bool *ok)
Definition: stringutil.cpp:244
#define PORTS_IRC
Definition: ServerPage.cpp:67
QString toString()
Definition: ExitPolicy.cpp:156
quint32 getTorVersion()
Definition: TorControl.cpp:667
#define HIGHBW_AVG_RATE
Definition: ServerPage.cpp:47
void serverModeChanged(bool enabled)
Definition: ServerPage.cpp:221
void loadBandwidthLimits()
Definition: ServerPage.cpp:401
bool save(QString &errmsg)
Definition: ServerPage.cpp:295
#define PORTS_IM
Definition: ServerPage.cpp:63
bool publishServerDescriptor() const
bool _tmpMirror
Definition: ServerPage.h:128
#define CABLE512_MAX_RATE
Definition: ServerPage.cpp:42
bool apply(QString &errmsg)
Definition: ServerPage.cpp:280
bool contains(Policy policy)
Definition: ExitPolicy.cpp:130
#define CABLE256_MAX_RATE
Definition: ServerPage.cpp:40
#define CABLE768_MAX_RATE
Definition: ServerPage.cpp:44
void helpRequested(const QString &topic)
void load()
Definition: ServerPage.cpp:350
QString _tmpDirPort
Definition: ServerPage.h:127
#define MIN_BANDWIDTH_RATE
Definition: ServerPage.cpp:50
void setBridgeEnabled(bool enable)
void onDisconnected()
Definition: ServerPage.cpp:173
void exitPolicyHelp()
Definition: ServerPage.cpp:387
void saveExitPolicies()
Definition: ServerPage.cpp:500
void update(const QDateTime &timeStarted, const QHash< QString, int > &countrySummary)
void addRejectedPorts(QStringList portList)
Definition: ExitPolicy.cpp:107
void displayBridgeUsage()
Definition: ServerPage.cpp:612
void setContactInfo(QString info)
bool getInfo(QHash< QString, QString > &map, QString *errmsg=0)
Definition: TorControl.cpp:450
void setUpnpEnabled(bool enabled)
#define MAX_BANDWIDTH_RATE
Definition: ServerPage.cpp:53
void customRateChanged()
Definition: ServerPage.cpp:557
QString getContactInfo()
void setPublishServerDescriptor(bool publish)
quint16 getDirPort()
void revert()
Definition: ServerPage.cpp:288
#define T1_AVG_RATE
Definition: ServerPage.cpp:45
void showWindow(Page page=General)
void setServerEnabled(bool enable)
#define PORTS_MAIL
Definition: ServerPage.cpp:60
void loadBridgeIdentity()
Definition: ServerPage.cpp:193
bool acceptsPorts(QStringList portList)
Definition: ExitPolicy.cpp:94
static TorControl * torControl()
Definition: Vidalia.h:76
void onAuthenticated()
Definition: ServerPage.cpp:146
#define CABLE256_AVG_RATE
Definition: ServerPage.cpp:39
stop errmsg connect(const QHostAddress &address, quint16 port)
Ui::ServerPage ui
Definition: ServerPage.h:122
quint32 getBandwidthBurstRate()
bool apply(QString *errmsg=0)
void setNonExitEnabled(bool enable)
void testUpnp()
Definition: ServerPage.cpp:580
void linkActivated(const QString &url)
Definition: ServerPage.cpp:601
#define PORTS_HTTP
Definition: ServerPage.cpp:56
void setNickname(QString nickname)
#define PORTS_HTTPS
Definition: ServerPage.cpp:58
void addPolicy(Policy policy)
Definition: ExitPolicy.cpp:61
ServerSettings * _settings
Definition: ServerPage.h:119
static int warning(QWidget *parent, QString caption, QString text, int button0, int button1=NoButton, int button2=NoButton)
quint32 getBandwidthAvgRate()
virtual bool changedSinceLastApply() const
Definition: Policy.h:24
bool isConnected()
Definition: TorControl.cpp:262
void copyBridgeIdentity()
Definition: ServerPage.cpp:180
virtual void retranslateUi()
Definition: ServerPage.cpp:137
bool changedSinceLastApply()
Definition: ServerPage.cpp:271
#define CABLE512_AVG_RATE
Definition: ServerPage.cpp:41
#define HIGHBW_MAX_RATE
Definition: ServerPage.cpp:48
ServerPage(QWidget *parent=0)
Definition: ServerPage.cpp:71
#define CABLE768_AVG_RATE
Definition: ServerPage.cpp:43
void setBandwidthAvgRate(quint32 rate)
#define vApp
Definition: Vidalia.h:37
void setExitPolicy(ExitPolicy &policy)
void loadExitPolicies()
Definition: ServerPage.cpp:473
void addAcceptedPorts(QStringList portList)
Definition: ExitPolicy.cpp:83
void saveBandwidthLimits()
Definition: ServerPage.cpp:437
ExitPolicy getExitPolicy()
void setBandwidthBurstRate(quint32 rate)
#define T1_MAX_RATE
Definition: ServerPage.cpp:46
QString getNickname()
void setORPort(quint16 orPort)
stop errmsg isConnected()
void setDirPort(quint16 dirPort)