advancedpage.cpp

Go to the documentation of this file.
00001 /****************************************************************
00002  *  Vidalia is distributed under the following license:
00003  *
00004  *  Copyright (C) 2006,  Matt Edman, Justin Hipple
00005  *
00006  *  This program is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU General Public License
00008  *  as published by the Free Software Foundation; either version 2
00009  *  of the License, or (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
00019  *  Boston, MA  02110-1301, USA.
00020  ****************************************************************/
00021 
00022 /** 
00023  * \file advancedpage.cpp
00024  * \version $Id: advancedpage.cpp 1843 2007-08-21 04:33:48Z edmanm $
00025  * \brief Advanced Tor and Vidalia configuration options
00026  */
00027 
00028 #include <QFile>
00029 #include <QFileInfo>
00030 #include <QHostAddress>
00031 #include <gui/common/vmessagebox.h>
00032 #include <util/file.h>
00033 #include <vidalia.h>
00034 
00035 #include "ipvalidator.h"
00036 #include "advancedpage.h"
00037 
00038 #if defined(Q_WS_WIN)
00039 #include <control/torservice.h>
00040 #endif
00041 
00042 
00043 /** Constructor */
00044 AdvancedPage::AdvancedPage(QWidget *parent)
00045 : ConfigPage(parent)
00046 {
00047   /* Invoke the Qt Designer generated object setup routine */
00048   ui.setupUi(this);
00049 
00050   /* Create TorSettings object */
00051   _settings = new TorSettings();
00052   
00053   /* Set validators for the control port and IP address fields */
00054   ui.lineControlAddress->setValidator(new IPValidator(this));
00055   ui.lineControlPort->setValidator(new QIntValidator(1, 65535, this));
00056   
00057   /* Bind event to actions */
00058   connect(ui.btnBrowseTorConfig, SIGNAL(clicked()), this, SLOT(browseTorConfig()));
00059   connect(ui.btnBrowseTorDataDirectory, SIGNAL(clicked()),
00060           this, SLOT(browseTorDataDirectory()));
00061   connect(ui.cmbAuthMethod, SIGNAL(currentIndexChanged(int)),
00062           this, SLOT(authMethodChanged(int)));
00063   connect(ui.chkRandomPassword, SIGNAL(toggled(bool)),
00064           ui.linePassword, SLOT(setDisabled(bool)));
00065 
00066   /* Hide platform specific features */
00067 #if defined(Q_WS_WIN)
00068   ui.grpPermissions->setVisible(false);
00069   ui.grpService->setVisible(TorService::isSupported());
00070 #endif
00071 }
00072 
00073 /** Destructor */
00074 AdvancedPage::~AdvancedPage()
00075 {
00076   delete _settings;
00077 }
00078 
00079 /** Saves all settings for this page. */
00080 bool
00081 AdvancedPage::save(QString &errmsg)
00082 {
00083   /* Validate the control listener address */
00084   QHostAddress controlAddress(ui.lineControlAddress->text());
00085   if (controlAddress.isNull()) {
00086     errmsg = tr("'%1' is not a valid IP address.")
00087                .arg(ui.lineControlAddress->text());
00088     return false; 
00089   }
00090   
00091   /* Validate the selected authentication options */
00092   TorSettings::AuthenticationMethod authMethod = 
00093     indexToAuthMethod(ui.cmbAuthMethod->currentIndex());
00094   if (authMethod == TorSettings::PasswordAuth &&
00095       ui.linePassword->text().isEmpty() &&
00096       !ui.chkRandomPassword->isChecked()) {
00097     errmsg = tr("You selected 'Password' authentication, but did not "
00098                 "specify a password.");
00099     return false;
00100   }
00101 
00102   _settings->setControlAddress(controlAddress);
00103   _settings->setControlPort(ui.lineControlPort->text().toUShort());
00104   _settings->setTorrc(ui.lineTorConfig->text());
00105   _settings->setDataDirectory(ui.lineTorDataDirectory->text());
00106   _settings->setUser(ui.lineUser->text());
00107   _settings->setGroup(ui.lineGroup->text());
00108   
00109   _settings->setAuthenticationMethod(authMethod);
00110   _settings->setUseRandomPassword(ui.chkRandomPassword->isChecked());
00111   if (authMethod == TorSettings::PasswordAuth && 
00112       !ui.chkRandomPassword->isChecked())
00113     _settings->setControlPassword(ui.linePassword->text());
00114 
00115 #if defined(Q_WS_WIN)
00116   /* Install or uninstall the Tor service as necessary */
00117   setupService(ui.chkUseService->isChecked());
00118 #endif
00119 
00120   return true;
00121 }
00122 
00123 /** Loads previously saved settings. */
00124 void
00125 AdvancedPage::load()
00126 {
00127   ui.lineControlAddress->setText(_settings->getControlAddress().toString());
00128   ui.lineControlPort->setText(QString::number(_settings->getControlPort()));
00129   ui.lineTorConfig->setText(_settings->getTorrc());
00130   ui.lineTorDataDirectory->setText(_settings->getDataDirectory());
00131   ui.lineUser->setText(_settings->getUser());
00132   ui.lineGroup->setText(_settings->getGroup());
00133   
00134   ui.cmbAuthMethod->setCurrentIndex(
00135     authMethodToIndex(_settings->getAuthenticationMethod()));
00136   ui.chkRandomPassword->setChecked(_settings->useRandomPassword());
00137   if (!ui.chkRandomPassword->isChecked())
00138     ui.linePassword->setText(_settings->getControlPassword());
00139 
00140 #if defined(Q_WS_WIN)
00141   TorService s;
00142   ui.chkUseService->setChecked(s.isInstalled());
00143 #endif
00144 }
00145 
00146 /** Called when the user selects a different authentication method from the
00147  * combo box. */
00148 void
00149 AdvancedPage::authMethodChanged(int index)
00150 {
00151   bool usePassword = (indexToAuthMethod(index) == TorSettings::PasswordAuth);
00152   ui.linePassword->setEnabled(usePassword && !ui.chkRandomPassword->isChecked());
00153   ui.chkRandomPassword->setEnabled(usePassword);
00154 }
00155 
00156 /** Returns the authentication method for the given <b>index</b>. */
00157 TorSettings::AuthenticationMethod
00158 AdvancedPage::indexToAuthMethod(int index)
00159 {
00160   switch (index) {
00161     case 0: return TorSettings::NullAuth;
00162     case 1: return TorSettings::CookieAuth;
00163     case 2: return TorSettings::PasswordAuth;
00164     default: break;
00165   }
00166   return TorSettings::UnknownAuth;
00167 }
00168 
00169 /** Returns the index in the authentication methods combo box for the given
00170  * authentication <b>method</b>. */
00171 int
00172 AdvancedPage::authMethodToIndex(TorSettings::AuthenticationMethod method)
00173 {
00174   switch (method) {
00175     case TorSettings::NullAuth: return 0;
00176     case TorSettings::CookieAuth: return 1;
00177     default: break;
00178   }
00179   return 2;
00180 }
00181 
00182 /** Open a QFileDialog to browse for Tor config file. */
00183 void
00184 AdvancedPage::browseTorConfig()
00185 {
00186   /* Prompt the user to select a file or create a new one */
00187   QString filename = QFileDialog::getOpenFileName(this, 
00188                        tr("Select Tor Configuration File"),
00189                        QFileInfo(ui.lineTorConfig->text()).fileName());
00190  
00191   /* Make sure a filename was selected */
00192   if (filename.isEmpty()) {
00193     return;
00194   }
00195 
00196   /* Check if the file exists */
00197   QFile torrcFile(filename);
00198   if (!QFileInfo(filename).exists()) {
00199     /* The given file does not exist. Should we create it? */
00200     int response = VMessageBox::question(this,
00201                      tr("File Not Found"),
00202                      tr("%1 does not exist. Would you like to create it?")
00203                                                             .arg(filename),
00204                      VMessageBox::Yes, VMessageBox::No);
00205     
00206     if (response == VMessageBox::No) {
00207       /* Don't create it. Just bail. */
00208       return;
00209     }
00210     /* Attempt to create the specified file */
00211     QString errmsg;
00212     if (!touch_file(filename, false, &errmsg)) {
00213       VMessageBox::warning(this,
00214         tr("Failed to Create File"),
00215         tr("Unable to create %1 [%2]").arg(filename)
00216                                       .arg(errmsg),
00217         VMessageBox::Ok);
00218       return;
00219     }
00220   }
00221   ui.lineTorConfig->setText(filename);
00222 }
00223 
00224 /** Opens a QFileDialog for the user to browse to or create a directory for
00225  * Tor's DataDirectory. */
00226 void
00227 AdvancedPage::browseTorDataDirectory()
00228 {
00229   QString dataDir = QFileDialog::getExistingDirectory(this,
00230                       tr("Select a Directory to Use for Tor Data"),
00231                       ui.lineTorDataDirectory->text());
00232   
00233   if (!dataDir.isEmpty()) 
00234     ui.lineTorDataDirectory->setText(dataDir);
00235 }
00236 
00237 #if defined(Q_WS_WIN)
00238 /** Installs or removes the Tor service as necessary. */
00239 void
00240 AdvancedPage::setupService(bool useService)
00241 {
00242   TorService service;
00243   bool isInstalled = service.isInstalled();
00244 
00245   if (!useService && isInstalled) {
00246     /* Uninstall if we don't want to use it anymore */
00247     Vidalia::torControl()->stop();
00248     
00249     if (!service.remove()) {
00250       VMessageBox::critical(this,
00251                             tr("Unable to remove Tor Service"),
00252                             tr("Vidalia was unable to remove the Tor service.\n\n"
00253                                "You may need to remove it manually."), 
00254                             VMessageBox::Ok, VMessageBox::Cancel);
00255     }
00256   } else if (useService && !isInstalled) {
00257     /* Install if we want to start using a service */
00258     if (!service.install(_settings->getExecutable(),
00259                          _settings->getTorrc(),
00260                          _settings->getControlPort())) {
00261       VMessageBox::critical(this,
00262                             tr("Unable to install Tor Service"),
00263                             tr("Vidalia was unable to install the Tor service."),
00264                             VMessageBox::Ok, VMessageBox::Cancel);
00265     }
00266   }
00267 }
00268 #endif
00269 

Generated on Wed Sep 5 15:49:27 2007 for Vidalia by  doxygen 1.5.3