00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00041 #define DEFAULT_POLICY Policy(AcceptAll)
00042
00043 #define COL_ACTION 0
00044 #define COL_ADDRESS 1
00045 #define COL_PORT 2
00046
00047
00048 #define AUTO_UPDATE_ADDR_INTERVAL 1000*60*60
00049
00050
00051 #define EXIT_POLICY_HELP "server.exitpolicy"
00052 #define BANDWIDTH_HELP "server.bandwidth"
00053
00054 #define MIN_RATE 20
00055
00056
00057 #define MAX_RATE 2097151
00058
00059
00060
00061 ServerPage::ServerPage(QWidget *parent)
00062 : ConfigPage(parent)
00063 {
00064
00065 ui.setupUi(this);
00066
00067
00068 _torControl = Vidalia::torControl();
00069
00070
00071 _settings = new ServerSettings(_torControl);
00072
00073
00074
00075 _autoUpdateTimer = new QTimer(this);
00076 connect(_autoUpdateTimer, SIGNAL(timeout()),
00077 this, SLOT(updateServerIP()));
00078
00079
00080 connect(ui.btnAddPolicy, SIGNAL(clicked()), this, SLOT(addPolicy()));
00081 connect(ui.btnRemovePolicy, SIGNAL(clicked()), this, SLOT(removePolicy()));
00082 connect(ui.btnRaisePriority, SIGNAL(clicked()), this, SLOT(raisePriority()));
00083 connect(ui.btnLowerPriority, SIGNAL(clicked()), this, SLOT(lowerPriority()));
00084 connect(ui.btnGetAddress, SIGNAL(clicked()), this, SLOT(getServerAddress()));
00085 connect(ui.btnRateHelp, SIGNAL(clicked()), this, SLOT(bandwidthHelp()));
00086 connect(ui.btnExitHelp, SIGNAL(clicked()), this, SLOT(exitPolicyHelp()));
00087
00088 connect(ui.lineAvgRateLimit, SIGNAL(editingFinished()),
00089 this, SLOT(rateChanged()));
00090 connect(ui.lineMaxRateLimit, SIGNAL(editingFinished()),
00091 this, SLOT(rateChanged()));
00092
00093
00094 ui.lineServerNickname->setValidator(new NicknameValidator(this));
00095 ui.lineServerAddress->setValidator(new DomainValidator(this));
00096 ui.lineServerPort->setValidator(new QIntValidator(1, 65535, this));
00097 ui.lineDirPort->setValidator(new QIntValidator(1, 65535, this));
00098 ui.lineExitAddress->setValidator(new IPValidator(this));
00099 ui.lineExitMask->setValidator(new QIntValidator(0, 32, this));
00100 ui.lineExitFromPort->setValidator(new PortValidator(this));
00101 ui.lineExitToPort->setValidator(new PortValidator(this));
00102 ui.lineAvgRateLimit->setValidator(new QIntValidator(MIN_RATE, MAX_RATE, this));
00103 ui.lineMaxRateLimit->setValidator(new QIntValidator(MIN_RATE, MAX_RATE, this));
00104 }
00105
00106
00107 ServerPage::~ServerPage()
00108 {
00109 delete _settings;
00110 }
00111
00112
00113 void
00114 ServerPage::setAutoUpdateTimer(bool enabled)
00115 {
00116 if (enabled && _settings->isServerEnabled()) {
00117 _autoUpdateTimer->start(AUTO_UPDATE_ADDR_INTERVAL);
00118 } else {
00119 _autoUpdateTimer->stop();
00120 }
00121 }
00122
00123
00124 bool
00125 ServerPage::save(QString &errmsg)
00126 {
00127
00128 rateChanged();
00129
00130 if (ui.chkEnableServer->isChecked()) {
00131
00132 if (ui.lineServerPort->text().isEmpty() ||
00133 ui.lineServerNickname->text().isEmpty()) {
00134 errmsg = tr("You must specify at least a server nickname and port.");
00135 return false;
00136 }
00137
00138 if (ui.lineAvgRateLimit->text().isEmpty()) {
00139 ui.lineAvgRateLimit->setText(QString::number(2097152/1024) );
00140 }
00141 if (ui.lineMaxRateLimit->text().isEmpty()) {
00142 ui.lineMaxRateLimit->setText(QString::number(5242880/1024) );
00143 }
00144 }
00145 _settings->setServerEnabled(ui.chkEnableServer->isChecked());
00146 _settings->setDirectoryMirror(ui.chkMirrorDirectory->isChecked());
00147 _settings->setMiddleman(ui.chkMiddleMan->isChecked());
00148 _settings->setAutoUpdateAddress(ui.chkAutoUpdate->isChecked());
00149 _settings->setNickname(ui.lineServerNickname->text());
00150 _settings->setORPort(ui.lineServerPort->text().toUInt());
00151 _settings->setDirPort(ui.lineDirPort->text().toUInt());
00152 _settings->setAddress(ui.lineServerAddress->text());
00153 _settings->setContactInfo(ui.lineServerContact->text());
00154 _settings->setBandwidthAvgRate(ui.lineAvgRateLimit->text().toUInt()*1024);
00155 _settings->setBandwidthBurstRate(ui.lineMaxRateLimit->text().toUInt()*1024);
00156 setAutoUpdateTimer(ui.chkAutoUpdate->isChecked());
00157
00158
00159 ExitPolicy exitPolicy;
00160 for (int i = 0; i < ui.lstExitPolicies->topLevelItemCount(); ++i) {
00161 savePolicy(ui.lstExitPolicies->topLevelItem(i), exitPolicy);
00162 }
00163 _settings->setExitPolicy(exitPolicy);
00164
00165
00166
00167 if (_torControl->isConnected() && _settings->changedSinceLastApply()) {
00168 if (!_settings->apply(&errmsg)) {
00169 _settings->revert();
00170 return false;
00171 }
00172 }
00173 return true;
00174 }
00175
00176
00177 void
00178 ServerPage::load()
00179 {
00180 ui.chkEnableServer->setChecked(_settings->isServerEnabled());
00181 ui.chkMirrorDirectory->setChecked(_settings->isDirectoryMirror());
00182 ui.chkMiddleMan->setChecked(_settings->isMiddleman());
00183 ui.chkAutoUpdate->setChecked(_settings->getAutoUpdateAddress());
00184 setAutoUpdateTimer(_settings->getAutoUpdateAddress());
00185
00186 ui.lineServerNickname->setText(_settings->getNickname());
00187 ui.lineServerPort->setText(QString::number(_settings->getORPort()));
00188 ui.lineDirPort->setText(QString::number(_settings->getDirPort()));
00189 ui.lineServerAddress->setText(_settings->getAddress());
00190 ui.lineServerContact->setText(_settings->getContactInfo());
00191 ui.lineAvgRateLimit->setText(
00192 QString::number((uint)(_settings->getBandwidthAvgRate()/1024)));
00193 ui.lineMaxRateLimit->setText(
00194 QString::number((uint)(_settings->getBandwidthBurstRate()/1024)));
00195
00196
00197 ui.lstExitPolicies->clear();
00198
00199 foreach (Policy policy, _settings->getExitPolicy().policyList()) {
00200 addPolicyItem(policy);
00201 }
00202
00203 ui.frmExitPolicy->setHidden(ui.chkMiddleMan->isChecked());
00204 ui.frmServer->setVisible(ui.chkEnableServer->isChecked());
00205 }
00206
00207
00208 void
00209 ServerPage::savePolicy(QTreeWidgetItem *item, ExitPolicy &exitPolicy)
00210 {
00211
00212 exitPolicy.addPolicy(Policy(item->text(COL_ACTION),
00213 item->text(COL_ADDRESS),
00214 item->text(COL_PORT)));
00215 }
00216
00217
00218 void
00219 ServerPage::addPolicy()
00220 {
00221
00222 QString address = ui.lineExitAddress->text();
00223 if (!address.isEmpty()) {
00224 if (((IPValidator *)ui.lineExitAddress->validator())->
00225 validate(address) != QValidator::Acceptable) {
00226 return;
00227 }
00228 }
00229
00230
00231 QString fromPort = ui.lineExitFromPort->text();
00232 QString toPort = ui.lineExitToPort->text();
00233
00234 if (!fromPort.isEmpty() && !toPort.isEmpty() && toPort != fromPort) {
00235 if (toPort == "*") toPort = "65535";
00236 if (fromPort == "*") fromPort = "1";
00237 if (fromPort.toUShort() > toPort.toUShort()) {
00238 return;
00239 }
00240 }
00241
00242
00243 addPolicyItem(Policy(Policy::toAction(ui.cmboExitAction->currentText()),
00244 QHostAddress(ui.lineExitAddress->text()),
00245 ui.lineExitMask->text().toUShort(),
00246 fromPort.toUShort(),
00247 toPort.toUShort()), false);
00248
00249
00250 ui.lineExitAddress->clear();
00251 ui.lineExitMask->clear();
00252 ui.lineExitFromPort->clear();
00253 ui.lineExitToPort->clear();
00254 }
00255
00256
00257 void
00258 ServerPage::addPolicyItem(Policy policy, bool append)
00259 {
00260 QTreeWidgetItem *newPolicy = new QTreeWidgetItem();
00261
00262 newPolicy->setText(COL_ACTION, policy.action());
00263 newPolicy->setText(COL_ADDRESS, policy.address());
00264 newPolicy->setText(COL_PORT, policy.ports());
00265
00266 for (int i = 0; i < newPolicy->columnCount(); i++) {
00267 newPolicy->setTextAlignment(i, Qt::AlignHCenter);
00268 }
00269
00270 if (append) {
00271 ui.lstExitPolicies->addTopLevelItem(newPolicy);
00272 } else {
00273 ui.lstExitPolicies->insertTopLevelItem(0, newPolicy);
00274 }
00275 }
00276
00277
00278 void
00279 ServerPage::removePolicy()
00280 {
00281 int index = selectedIndex();
00282
00283 if (index > -1) {
00284 delete ui.lstExitPolicies->takeTopLevelItem(index);
00285 }
00286 }
00287
00288
00289 void
00290 ServerPage::raisePriority()
00291 {
00292 int index = selectedIndex();
00293
00294 if (index > 0) {
00295 ui.lstExitPolicies->insertTopLevelItem(index - 1,
00296 ui.lstExitPolicies->takeTopLevelItem(index));
00297 }
00298 }
00299
00300
00301 void
00302 ServerPage::lowerPriority()
00303 {
00304 int index = selectedIndex();
00305 int lastItem = ui.lstExitPolicies->topLevelItemCount() - 1;
00306
00307 if (index > -1 && index < lastItem) {
00308 ui.lstExitPolicies->insertTopLevelItem(index + 1,
00309 ui.lstExitPolicies->takeTopLevelItem(index));
00310 }
00311 }
00312
00313
00314 int
00315 ServerPage::selectedIndex()
00316 {
00317 if (ui.lstExitPolicies->selectedItems().isEmpty()) return -1;
00318
00319
00320 QTreeWidgetItem *selectedItem = ui.lstExitPolicies->selectedItems()[0];
00321 return ui.lstExitPolicies->indexOfTopLevelItem(selectedItem);
00322 }
00323
00324
00325 void
00326 ServerPage::exitPolicyHelp()
00327 {
00328 Vidalia::help(EXIT_POLICY_HELP);
00329 }
00330
00331
00332 void
00333 ServerPage::bandwidthHelp()
00334 {
00335 Vidalia::help(BANDWIDTH_HELP);
00336 }
00337
00338
00339 void
00340 ServerPage::getServerPublicIP()
00341 {
00342 QString ip;
00343 bool success;
00344
00345
00346 QApplication::setOverrideCursor(Qt::WaitCursor);
00347 success = net_get_public_ip(ip);
00348 QApplication::restoreOverrideCursor();
00349
00350
00351 if (success) {
00352 ui.lineServerAddress->setText(ip);
00353 } else {
00354 VMessageBox::warning(this, tr("Error"),
00355 p(tr("Vidalia was unable to determine your public IP address.")),
00356 VMessageBox::Ok);
00357 }
00358 }
00359
00360
00361
00362
00363 void
00364 ServerPage::getServerAddress()
00365 {
00366 QHostAddress addr = net_local_address();
00367 if (net_is_private_address(addr)) {
00368 int button = VMessageBox::information(this, tr("Get Address"),
00369 tr("Vidalia was only able to find a private IP "
00370 "address for your server.\n\nWould you like to "
00371 "access an external service to determine your public "
00372 "IP address?"),
00373 VMessageBox::Yes, VMessageBox::No);
00374 if (button == VMessageBox::Yes) {
00375 getServerPublicIP();
00376 return;
00377 }
00378 } else {
00379 ui.lineServerAddress->setText(addr.toString());
00380 }
00381 }
00382
00383
00384
00385 void
00386 ServerPage::updateServerIP()
00387 {
00388 bool changed = false;
00389 QString ip;
00390 QHostAddress addr = net_local_address();
00391
00392 if (net_is_private_address(addr)) {
00393
00394 if (net_get_public_ip(ip) && ip != _settings->getAddress()) {
00395 changed = true;
00396 }
00397 } else if (addr.toString() != _settings->getAddress()) {
00398 ip = addr.toString();
00399 changed = true;
00400 }
00401
00402 if (changed) {
00403
00404 _settings->setAddress(ip);
00405 ui.lineServerAddress->setText(ip);
00406
00407
00408 if (_torControl->isConnected()) {
00409 _settings->apply();
00410 }
00411 }
00412 }
00413
00414
00415
00416
00417 void
00418 ServerPage::rateChanged()
00419 {
00420
00421 quint32 avgRate = (quint32)ui.lineAvgRateLimit->text().toUInt();
00422 if (avgRate < MIN_RATE) {
00423 ui.lineAvgRateLimit->setText(QString::number(MIN_RATE));
00424 }
00425 if (avgRate > MAX_RATE) {
00426 ui.lineAvgRateLimit->setText(QString::number(MAX_RATE));
00427 }
00428
00429
00430 quint32 burstRate = (quint32)ui.lineMaxRateLimit->text().toUInt();
00431 if (avgRate > burstRate) {
00432 ui.lineMaxRateLimit->setText(QString::number(avgRate));
00433 }
00434 if (burstRate > MAX_RATE) {
00435 ui.lineMaxRateLimit->setText(QString::number(MAX_RATE));
00436 }
00437 }
00438