AdvancedPage.cpp

Go to the documentation of this file.
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.vidalia-project.net/. No part of Vidalia, including this file,
00007 **  may be copied, modified, propagated, or distributed except according to the
00008 **  terms described in the LICENSE file.
00009 */
00010 
00011 /*
00012 ** \file AdvancedPage.cpp
00013 ** \version $Id: AdvancedPage.cpp 4023 2009-08-10 15:20:25Z edmanm $
00014 ** \brief Advanced Tor and Vidalia configuration options
00015 */
00016 
00017 #include "AdvancedPage.h"
00018 #include "Vidalia.h"
00019 #include "VMessageBox.h"
00020 #include "IpValidator.h"
00021 
00022 #include "file.h"
00023 
00024 #if defined(Q_WS_WIN)
00025 #include "TorService.h"
00026 #endif
00027 
00028 #include <QFile>
00029 #include <QFileInfo>
00030 #include <QHostAddress>
00031 
00032 
00033 /** Constructor */
00034 AdvancedPage::AdvancedPage(QWidget *parent)
00035   : ConfigPage(parent, "Advanced")
00036 {
00037   /* Invoke the Qt Designer generated object setup routine */
00038   ui.setupUi(this);
00039 
00040   /* Create TorSettings object */
00041   _settings = new TorSettings(Vidalia::torControl());
00042   
00043   /* Set validators for the control port and IP address fields */
00044   ui.lineControlAddress->setValidator(new IpValidator(this));
00045   ui.lineControlPort->setValidator(new QIntValidator(1, 65535, this));
00046   
00047   /* Bind event to actions */
00048   connect(ui.btnBrowseTorConfig, SIGNAL(clicked()), this, SLOT(browseTorConfig()));
00049   connect(ui.btnBrowseTorDataDirectory, SIGNAL(clicked()),
00050           this, SLOT(browseTorDataDirectory()));
00051   connect(ui.cmbAuthMethod, SIGNAL(currentIndexChanged(int)),
00052           this, SLOT(authMethodChanged(int)));
00053   connect(ui.chkRandomPassword, SIGNAL(toggled(bool)),
00054           ui.linePassword, SLOT(setDisabled(bool)));
00055 
00056   /* Hide platform specific features */
00057 #if defined(Q_WS_WIN)
00058 #if 0
00059   ui.grpService->setVisible(TorService::isSupported());
00060 #endif
00061 #endif
00062 }
00063 
00064 /** Destructor */
00065 AdvancedPage::~AdvancedPage()
00066 {
00067   delete _settings;
00068 }
00069 
00070 /** Called when the user changes the UI translation. */
00071 void
00072 AdvancedPage::retranslateUi()
00073 {
00074   ui.retranslateUi(this);
00075 }
00076 
00077 /** Applies the network configuration settings to Tor. Returns true if the
00078  * settings were applied successfully. Otherwise, <b>errmsg</b> is set
00079  * and false is returned. */
00080 bool
00081 AdvancedPage::apply(QString &errmsg)
00082 {
00083   return _settings->apply(&errmsg);
00084 }
00085 
00086 /** Reverts the Tor configuration settings to their values at the last
00087  * time they were successfully applied to Tor. */
00088 bool
00089 AdvancedPage::changedSinceLastApply()
00090 {
00091   return _settings->changedSinceLastApply();
00092 }
00093 
00094 /** Returns true if the user has changed their advanced Tor settings since
00095  * the last time they were applied to Tor. */
00096 void
00097 AdvancedPage::revert()
00098 {
00099   return _settings->revert();
00100 }
00101 
00102 /** Saves all settings for this page. */
00103 bool
00104 AdvancedPage::save(QString &errmsg)
00105 {
00106   /* Validate the control listener address */
00107   QHostAddress controlAddress(ui.lineControlAddress->text());
00108   if (controlAddress.isNull()) {
00109     errmsg = tr("'%1' is not a valid IP address.")
00110                .arg(ui.lineControlAddress->text());
00111     return false; 
00112   }
00113   
00114   /* Validate the selected authentication options */
00115   TorSettings::AuthenticationMethod authMethod = 
00116     indexToAuthMethod(ui.cmbAuthMethod->currentIndex());
00117   if (authMethod == TorSettings::PasswordAuth
00118         && ui.linePassword->text().isEmpty()
00119         && !ui.chkRandomPassword->isChecked()) {
00120     errmsg = tr("You selected 'Password' authentication, but did not "
00121                 "specify a password.");
00122     return false;
00123   }
00124  
00125   /* Only remember the torrc and datadir values if Vidalia started Tor, or
00126    * if the user changed the displayed values. */
00127   if (!Vidalia::torControl()->isVidaliaRunningTor()) {
00128     QString torrc = ui.lineTorConfig->text();
00129     if (torrc != _settings->getTorrc())
00130       _settings->setTorrc(torrc);
00131 
00132     QString dataDir = ui.lineTorDataDirectory->text();
00133     if (dataDir != _settings->getDataDirectory())
00134       _settings->setDataDirectory(dataDir);
00135   } else {
00136     _settings->setTorrc(ui.lineTorConfig->text());
00137     _settings->setDataDirectory(ui.lineTorDataDirectory->text());
00138   }
00139 
00140   _settings->setControlAddress(controlAddress);
00141   _settings->setControlPort(ui.lineControlPort->text().toUShort());
00142 
00143   _settings->setAuthenticationMethod(authMethod);
00144   _settings->setUseRandomPassword(ui.chkRandomPassword->isChecked());
00145   if (authMethod == TorSettings::PasswordAuth
00146         && !ui.chkRandomPassword->isChecked())
00147     _settings->setControlPassword(ui.linePassword->text());
00148 
00149 #if 0
00150 #if defined(Q_WS_WIN)
00151   /* Install or uninstall the Tor service as necessary */
00152   setupService(ui.chkUseService->isChecked());
00153 #endif
00154 #endif
00155 
00156   return true;
00157 }
00158 
00159 /** Loads previously saved settings. */
00160 void
00161 AdvancedPage::load()
00162 {
00163   ui.lineControlAddress->setText(_settings->getControlAddress().toString());
00164   ui.lineControlPort->setText(QString::number(_settings->getControlPort()));
00165   ui.lineTorConfig->setText(_settings->getTorrc());
00166   ui.lineTorDataDirectory->setText(_settings->getDataDirectory());
00167 
00168   ui.cmbAuthMethod->setCurrentIndex(
00169     authMethodToIndex(_settings->getAuthenticationMethod()));
00170   ui.chkRandomPassword->setChecked(_settings->useRandomPassword());
00171   if (!ui.chkRandomPassword->isChecked())
00172     ui.linePassword->setText(_settings->getControlPassword());
00173 
00174 #if 0
00175 #if defined(Q_WS_WIN)
00176   TorService s;
00177   ui.chkUseService->setChecked(s.isInstalled());
00178 #endif
00179 #endif
00180 }
00181 
00182 /** Called when the user selects a different authentication method from the
00183  * combo box. */
00184 void
00185 AdvancedPage::authMethodChanged(int index)
00186 {
00187   bool usePassword = (indexToAuthMethod(index) == TorSettings::PasswordAuth);
00188   ui.linePassword->setEnabled(usePassword && !ui.chkRandomPassword->isChecked());
00189   ui.chkRandomPassword->setEnabled(usePassword);
00190 }
00191 
00192 /** Returns the authentication method for the given <b>index</b>. */
00193 TorSettings::AuthenticationMethod
00194 AdvancedPage::indexToAuthMethod(int index)
00195 {
00196   switch (index) {
00197     case 0: return TorSettings::NullAuth;
00198     case 1: return TorSettings::CookieAuth;
00199     case 2: return TorSettings::PasswordAuth;
00200     default: break;
00201   }
00202   return TorSettings::UnknownAuth;
00203 }
00204 
00205 /** Returns the index in the authentication methods combo box for the given
00206  * authentication <b>method</b>. */
00207 int
00208 AdvancedPage::authMethodToIndex(TorSettings::AuthenticationMethod method)
00209 {
00210   switch (method) {
00211     case TorSettings::NullAuth: return 0;
00212     case TorSettings::CookieAuth: return 1;
00213     default: break;
00214   }
00215   return 2;
00216 }
00217 
00218 /** Open a QFileDialog to browse for Tor config file. */
00219 void
00220 AdvancedPage::browseTorConfig()
00221 {
00222   /* Prompt the user to select a file or create a new one */
00223   QString filename = QFileDialog::getOpenFileName(this, 
00224                        tr("Select Tor Configuration File"),
00225                        QFileInfo(ui.lineTorConfig->text()).filePath(),
00226                        tr("Tor Configuration File (torrc);;All Files (*)"));
00227  
00228   /* Make sure a filename was selected */
00229   if (filename.isEmpty()) {
00230     return;
00231   }
00232 
00233   /* Check if the file exists */
00234   QFile torrcFile(filename);
00235   if (!QFileInfo(filename).exists()) {
00236     /* The given file does not exist. Should we create it? */
00237     int response = VMessageBox::question(this,
00238                      tr("File Not Found"),
00239                      tr("%1 does not exist. Would you like to create it?")
00240                                                             .arg(filename),
00241                      VMessageBox::Yes, VMessageBox::No);
00242     
00243     if (response == VMessageBox::No) {
00244       /* Don't create it. Just bail. */
00245       return;
00246     }
00247     /* Attempt to create the specified file */
00248     QString errmsg;
00249     if (!touch_file(filename, false, &errmsg)) {
00250       VMessageBox::warning(this,
00251         tr("Failed to Create File"),
00252         tr("Unable to create %1 [%2]").arg(filename)
00253                                       .arg(errmsg),
00254         VMessageBox::Ok);
00255       return;
00256     }
00257   }
00258   ui.lineTorConfig->setText(filename);
00259 }
00260 
00261 /** Opens a QFileDialog for the user to browse to or create a directory for
00262  * Tor's DataDirectory. */
00263 void
00264 AdvancedPage::browseTorDataDirectory()
00265 {
00266   QString dataDir = QFileDialog::getExistingDirectory(this,
00267                       tr("Select a Directory to Use for Tor Data"),
00268                       ui.lineTorDataDirectory->text());
00269   
00270   if (!dataDir.isEmpty()) 
00271     ui.lineTorDataDirectory->setText(dataDir);
00272 }
00273 
00274 #if 0
00275 #if defined(Q_WS_WIN)
00276 /** Installs or removes the Tor service as necessary. */
00277 void
00278 AdvancedPage::setupService(bool useService)
00279 {
00280   TorService service;
00281   bool isInstalled = service.isInstalled();
00282 
00283   if (!useService && isInstalled) {
00284     /* Uninstall if we don't want to use it anymore */
00285     Vidalia::torControl()->stop();
00286     
00287     if (!service.remove()) {
00288       VMessageBox::critical(this,
00289                             tr("Unable to remove Tor Service"),
00290                             tr("Vidalia was unable to remove the Tor service.\n\n"
00291                                "You may need to remove it manually."), 
00292                             VMessageBox::Ok, VMessageBox::Cancel);
00293     }
00294   } else if (useService && !isInstalled) {
00295     /* Install if we want to start using a service */
00296     if (!service.install(_settings->getExecutable(),
00297                          _settings->getTorrc(),
00298                          _settings->getControlPort())) {
00299       VMessageBox::critical(this,
00300                             tr("Unable to install Tor Service"),
00301                             tr("Vidalia was unable to install the Tor service."),
00302                             VMessageBox::Ok, VMessageBox::Cancel);
00303     }
00304   }
00305 }
00306 #endif
00307 #endif
00308 

Generated on Mon Aug 30 19:09:59 2010 for Vidalia by  doxygen 1.5.9