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

Generated on Wed Nov 26 21:02:42 2008 for Vidalia by  doxygen 1.5.7.1