[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[vidalia-svn] r1370: Start NT service fixes: - Always use the Tor service if it's (in trunk/src: config control gui/config)



Author: edmanm
Date: 2006-10-22 00:56:44 -0400 (Sun, 22 Oct 2006)
New Revision: 1370

Modified:
   trunk/src/config/torsettings.cpp
   trunk/src/config/torsettings.h
   trunk/src/control/torcontrol.cpp
   trunk/src/control/torservice.cpp
   trunk/src/control/torservice.h
   trunk/src/gui/config/advancedpage.cpp
   trunk/src/gui/config/advancedpage.h
Log:
Start NT service fixes:
  - Always use the Tor service if it's installed, not just if we have some
    setting in our vidalia.conf.
  - Make sure the service has a ControlPort.
  - Stop leaking memory every time the service is started with Vidalia.
To do:
  - Make the Tor service look at the same DataDirectory as normal Tor
    processes.
  - Give the Tor service an absolute path to a torrc, since Vidalia's idea of
    "./torrc" can be different than the service's idea of "./torrc", and make
    sure that torrc exists.
  - Load NT service functions on demand so Vidalia can work on old Windowses
    again.
  - And, of course, making a special Tor user.


Modified: trunk/src/config/torsettings.cpp
===================================================================
--- trunk/src/config/torsettings.cpp	2006-10-21 19:32:24 UTC (rev 1369)
+++ trunk/src/config/torsettings.cpp	2006-10-22 04:56:44 UTC (rev 1370)
@@ -36,7 +36,6 @@
 #define SETTING_CONTROL_ADDR    "Tor/ControlAddr"
 #define SETTING_CONTROL_PORT    "Tor/ControlPort"
 #define SETTING_AUTH_TOKEN      "Tor/AuthToken"
-#define SETTING_USE_SERVICE     "Tor/UseService"
 #define SETTING_TOR_USER        "Tor/User"
 #define SETTING_TOR_GROUP       "Tor/Group"
 
@@ -65,7 +64,6 @@
   setDefault(SETTING_AUTH_TOKEN,    QByteArray(""));
   setDefault(SETTING_TOR_USER,      "");
   setDefault(SETTING_TOR_GROUP,     "");
-  setDefault(SETTING_USE_SERVICE,   false);
 }
 
 /** Returns a fully-qualified path to Tor's executable, including the
@@ -220,17 +218,3 @@
   setValue(SETTING_AUTH_TOKEN, token.toBase64());
 }
 
-/** Get whether Tor will run as an NT service */
-bool
-TorSettings::getUseService()
-{
-  return value(SETTING_USE_SERVICE).toBool();
-}
-
-/** Set whether Tor will run as an NT service */
-void
-TorSettings::setUseService(bool useService)
-{
-  setValue(SETTING_USE_SERVICE, useService);
-}
-

Modified: trunk/src/config/torsettings.h
===================================================================
--- trunk/src/config/torsettings.h	2006-10-21 19:32:24 UTC (rev 1369)
+++ trunk/src/config/torsettings.h	2006-10-22 04:56:44 UTC (rev 1370)
@@ -78,11 +78,6 @@
   /** Set which group will be used to run Tor. */
   void setGroup(QString group);
 
-  /** Get whether Tor is used as an NT service or not */
-  bool getUseService();
-  /** Set whether Tor is used as an NT service */
-  void setUseService(bool useService);
-
 private:
   /** Formats the argument name <b>name</b> with the given value <b>value</b>.
    * If <b>value</b> contains a space, <b>value</b> will be wrapped in quotes. */

Modified: trunk/src/control/torcontrol.cpp
===================================================================
--- trunk/src/control/torcontrol.cpp	2006-10-21 19:32:24 UTC (rev 1369)
+++ trunk/src/control/torcontrol.cpp	2006-10-22 04:56:44 UTC (rev 1370)
@@ -41,7 +41,6 @@
    * the QProcess code. So, we create a new TorProcess object each time we
    * start Tor and then destroy it when it stops. */
   _torProcess = 0;
-  _torService = 0;
 
   /** Create an instance of a connection to Tor's control interface and give
    * it an object to use to handle asynchronous events. */
@@ -54,6 +53,15 @@
                    this, SLOT(onConnectFailed(QString)));
   QObject::connect(_controlConn, SIGNAL(disconnected()),
                    this, SLOT(onDisconnected()));
+
+  _torService = new TorService(this);
+  QObject::connect(_torService, SIGNAL(started()),
+                   this, SLOT(onStarted()), Qt::QueuedConnection);
+  QObject::connect(_torService, SIGNAL(finished()),
+                   this, SLOT(onStopped()));
+  QObject::connect(_torService, SIGNAL(startFailed(QString)),
+                   this, SLOT(onStartFailed(QString)), 
+                   Qt::QueuedConnection);
 }
 
 /** Default destructor */
@@ -84,18 +92,7 @@
      * then touch it. */
     touch_file(settings.getTorrc(), true);
     
-    if (TorService::isSupported() && settings.getUseService()) {
-      _torService = new TorService(settings.getExecutable(),
-                                   settings.getTorrc(), this);
-
-      QObject::connect(_torService, SIGNAL(started()),
-                       this, SLOT(onStarted()), Qt::QueuedConnection);
-      QObject::connect(_torService, SIGNAL(finished()),
-                       this, SLOT(onStopped()));
-      QObject::connect(_torService, SIGNAL(startFailed(QString)),
-                       this, SLOT(onStartFailed(QString)), 
-                       Qt::QueuedConnection);
-
+    if (TorService::isSupported() && _torService->isInstalled()) {
       _torService->start();
       
     } else {

Modified: trunk/src/control/torservice.cpp
===================================================================
--- trunk/src/control/torservice.cpp	2006-10-21 19:32:24 UTC (rev 1369)
+++ trunk/src/control/torservice.cpp	2006-10-22 04:56:44 UTC (rev 1370)
@@ -39,14 +39,9 @@
 }
 
 /** Default ctor. */
-TorService::TorService(const QString &torPath, const QString &torrc,
-                       QObject* parent)
+TorService::TorService(QObject* parent)
   : QObject(parent)
 {
-  Q_UNUSED(torrc);
-
-  _torrc = "\"" + torrc + "\"";
-  _torPath = "\"" + torPath + "\"";
   _manager = NULL;
   _service = NULL;
 
@@ -59,7 +54,6 @@
   close();
 }
 
-/** Closes the service and the service manager. */
 void
 TorService::close()
 {
@@ -68,7 +62,6 @@
     CloseServiceHandle(_service);
     _service = NULL;
   }
-
   if (_manager) {
     CloseServiceHandle(_manager);
     _manager = NULL;
@@ -99,7 +92,8 @@
 bool
 TorService::isInstalled()
 {
-  return _service != NULL;
+  initialize();
+  return (_service != NULL);
 }
 
 /** Returns true if the Tor service is running. */
@@ -107,6 +101,7 @@
 TorService::isRunning()
 {
 #if defined(Q_OS_WIN32)
+  initialize();
   return (status() == SERVICE_RUNNING);
 #else
   return false;
@@ -121,13 +116,11 @@
     emit startFailed(tr("Services not supported on this platform."));
     return;
   }
-
   if (!isInstalled()) {
-    if (!install()) {
-      emit startFailed(tr("Unable to install the Tor service."));
-      return;
-    }
+    emit startFailed(tr("The Tor service is not installed."));
+    return;
   }
+
 #if defined(Q_OS_WIN32)
   /* Make sure we're initialized */
   initialize();
@@ -145,7 +138,6 @@
 
   if (isRunning()) {
     emit started();
-
   } else {
     emit startFailed(tr("Unable to start Tor service."));
   }
@@ -177,25 +169,28 @@
 
 /** Installs the Tor service. */
 bool
-TorService::install()
+TorService::install(const QString &torPath, const QString &torrc,
+                    quint16 controlPort)
 {
 #if defined(Q_OS_WIN32)
   if (!isSupported()) return false;
 
-  /* Make sure we're initialized */
-  initialize();
-
   if (!isInstalled()) {
-    QString command = _torPath + " --nt-service -f " + _torrc;
+    QString command = QString("\"%1\" --nt-service -f \"%2\" ControlPort %3")
+                                                 .arg(torPath)
+                                                 .arg(torrc)
+                                                 .arg(controlPort);
 
     _service = CreateServiceA(_manager, TOR_SERVICE_NAME, TOR_SERVICE_DISP,
                               TOR_SERVICE_ACCESS, SERVICE_WIN32_OWN_PROCESS,
                               SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
                               command.toAscii().data(), NULL, NULL, NULL, NULL, "");
 
-    SERVICE_DESCRIPTION desc;
-    desc.lpDescription = TOR_SERVICE_DESC;
-    ChangeServiceConfig2(_service, SERVICE_CONFIG_DESCRIPTION, &desc);
+    if (_service != NULL) {
+      SERVICE_DESCRIPTION desc;
+      desc.lpDescription = TOR_SERVICE_DESC;
+      ChangeServiceConfig2(_service, SERVICE_CONFIG_DESCRIPTION, &desc);
+    }
   }
   return isInstalled();
 #else
@@ -219,7 +214,6 @@
     /* Release references to manager and service */
     close();
   }
-
   return !isInstalled();
 #else
   return false;

Modified: trunk/src/control/torservice.h
===================================================================
--- trunk/src/control/torservice.h	2006-10-21 19:32:24 UTC (rev 1369)
+++ trunk/src/control/torservice.h	2006-10-22 04:56:44 UTC (rev 1370)
@@ -53,7 +53,7 @@
   static bool isSupported();
 
   /** Default ctor. */
-  TorService(const QString &torPath,  const QString &torrc, QObject* parent = 0);
+  TorService(QObject* parent = 0);
   /** Default dtor. */
   ~TorService();
 
@@ -66,7 +66,8 @@
   /** Stops the Tor service. Emits finished on success. */
   void stop();
   /** Installs the Tor service. */
-  bool install();
+  bool install(const QString &torPath, const QString &torrc,
+               quint16 controlPort);
   /** Removes the Tor service. */
   bool remove();
 
@@ -79,17 +80,13 @@
   void startFailed(QString error);
 
 private:
-  /** Closes the service and the service manager. */
-  void close();
   /** Initializes the service and the service manager. */
   void initialize();
+  /** Closes the service and the service manager. */
+  void close();
+  /** Gets the status of the Tor service. */
+  DWORD status(); 
   
-  /** Path to the tor executable. */
-  QString _torPath;
-  /** Path to the torrc. */
-  QString _torrc;
-
-  DWORD status(); /** Gets the status of the Tor service. */
   SC_HANDLE _manager; /** Handle to a service manager object. */
   SC_HANDLE _service; /** Handle to the Tor service object. */
 };

Modified: trunk/src/gui/config/advancedpage.cpp
===================================================================
--- trunk/src/gui/config/advancedpage.cpp	2006-10-21 19:32:24 UTC (rev 1369)
+++ trunk/src/gui/config/advancedpage.cpp	2006-10-22 04:56:44 UTC (rev 1370)
@@ -75,7 +75,7 @@
   
 #if defined(Q_WS_WIN)
   /* Install or uninstall the Tor service as necessary */
-  setupService();
+  setupService(ui.chkUseService->isChecked());
 #endif
 
   return true;
@@ -91,7 +91,8 @@
   ui.lineGroup->setText(_settings->getGroup());
 
 #if defined(Q_WS_WIN)
-  ui.chkUseService->setChecked(useService());
+  TorService s;
+  ui.chkUseService->setChecked(s.isInstalled());
 #endif
 }
 
@@ -140,55 +141,35 @@
 }
 
 #if defined(Q_WS_WIN)
-/** Returns true if service support is enabled and functional */
-bool
-AdvancedPage::useService()
-{
-  TorService s(_settings->getExecutable(), _settings->getTorrc());
-
-  /* If the Tor service was previously installed, or we plan on running
-   * Tor as a service, return true. */
-  if (s.isInstalled() || _settings->getUseService()) {
-    return true;
-  }
-  return false;
-}
-
 /** Installs or removes the Tor service as necessary. */
 void
-AdvancedPage::setupService()
+AdvancedPage::setupService(bool useService)
 {
-  bool checked = ui.chkUseService->isChecked();
-  TorService* s = new TorService(_settings->getExecutable(),
-                                 _settings->getTorrc());
+  TorService service;
+  bool isInstalled = service.isInstalled();
 
-  if (!checked && s->isInstalled()) {
+  if (!useService && isInstalled) {
     /* Uninstall if we don't want to use it anymore */
     Vidalia::torControl()->stop();
     
-    if (!s->remove()) {
+    if (!service.remove()) {
       VMessageBox::critical(this,
                             tr("Unable to remove Tor Service"),
                             tr("Vidalia was unable to remove the Tor service.\n\n"
                                "You may need to remove it manually."), 
                             VMessageBox::Ok, VMessageBox::Cancel);
     }
-    _settings->setUseService(false);
-
-  } else if (checked && !s->isInstalled()) {
+  } else if (useService && !isInstalled) {
     /* Install if we want to start using a service */
-    if (!s->install()) {
+    if (!service.install(_settings->getExecutable(),
+                         _settings->getTorrc(),
+                         _settings->getControlPort())) {
       VMessageBox::critical(this,
                             tr("Unable to install Tor Service"),
                             tr("Vidalia was unable to install the Tor service."),
                             VMessageBox::Ok, VMessageBox::Cancel);
     }
-    _settings->setUseService(s->isInstalled());
-  } else {
-    _settings->setUseService(checked);
   }
-
-  delete s;
 }
 #endif
 

Modified: trunk/src/gui/config/advancedpage.h
===================================================================
--- trunk/src/gui/config/advancedpage.h	2006-10-21 19:32:24 UTC (rev 1369)
+++ trunk/src/gui/config/advancedpage.h	2006-10-22 04:56:44 UTC (rev 1370)
@@ -55,10 +55,8 @@
   
 private:
 #if defined(Q_WS_WIN)
-  /** Returns if service support is enabled and functional */
-  bool useService();
   /** Installs or removes the Tor service as necessary */
-  void setupService();
+  void setupService(bool useService);
 #endif
 
   /** A TorSettings object used to save/load settings */