[tor-commits] [vidalia/alpha] Implement panic button

chiiph at torproject.org chiiph at torproject.org
Tue Mar 20 18:00:00 UTC 2012


commit 14c94f93f207e8088fc56e5d192d29276fc7ca38
Author: Tomás Touceda <chiiph at torproject.org>
Date:   Sat Mar 17 17:33:30 2012 -0300

    Implement panic button
---
 src/common/file.cpp                    |   27 +++++++
 src/common/file.h                      |    3 +
 src/vidalia/MainWindow.cpp             |   80 +++++++++++++++++++
 src/vidalia/MainWindow.h               |    4 +
 src/vidalia/config/AdvancedPage.cpp    |   30 +++++++
 src/vidalia/config/AdvancedPage.h      |    3 +
 src/vidalia/config/AdvancedPage.ui     |  133 +++++++++++++++++++++++++++++++-
 src/vidalia/config/VidaliaSettings.cpp |   28 +++++++
 src/vidalia/config/VidaliaSettings.h   |   10 +++
 9 files changed, 314 insertions(+), 4 deletions(-)

diff --git a/src/common/file.cpp b/src/common/file.cpp
index f133565..7434bef 100644
--- a/src/common/file.cpp
+++ b/src/common/file.cpp
@@ -123,3 +123,30 @@ expand_filename(const QString &filename)
   return fname;
 }
 
+/** Recursively remove the directory with all its contents. */
+bool
+remove_dir(const QString &path)
+{
+  bool res = true;
+  QDir dir(path);
+
+  if(not dir.exists(path))
+    return false;
+
+  foreach(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot |
+                                            QDir::System |
+                                            QDir::Hidden |
+                                            QDir::AllDirs |
+                                            QDir::Files)) {
+    if(info.isDir())
+      res = remove_dir(info.absoluteFilePath());
+    else
+      res = QFile::remove(info.absoluteFilePath());
+
+    if(!res)
+      return res;
+  }
+  res = dir.rmdir(path);
+
+  return res;
+}
diff --git a/src/common/file.h b/src/common/file.h
index 30d4477..c4f0873 100644
--- a/src/common/file.h
+++ b/src/common/file.h
@@ -38,5 +38,8 @@ QString expand_filename(const QString &filename);
  * otherwise. */
 bool copy_dir(const QString &source, const QString &dest);
 
+/** Recursively remove the directory with all its contents. */
+bool remove_dir(const QString &dir);
+
 #endif
 
diff --git a/src/vidalia/MainWindow.cpp b/src/vidalia/MainWindow.cpp
index 3b505ad..c568c80 100644
--- a/src/vidalia/MainWindow.cpp
+++ b/src/vidalia/MainWindow.cpp
@@ -180,6 +180,7 @@ MainWindow::createActions()
   _actionStartStopTor = new QAction(QIcon(IMG_START_TOR_16), tr("Start Tor"), this);
   _actionExit = new QAction(QIcon(IMG_EXIT), tr("Exit"), this);
   _actionDebugDialog = new QAction(tr("Debug output"), this);
+  _actionPanic = new QAction(QIcon(IMG_EXIT), tr("Panic!"), this);
 }
 
 /** Creates the menu bar */
@@ -238,6 +239,10 @@ MainWindow::createToolBar()
   tool->addAction(_actionNewIdentity);
   tool->addAction(_actionConfigure);
 
+  VidaliaSettings settings;
+  if(settings.allowPanic())
+    tool->addAction(_actionPanic);
+
   tool->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
 }
 
@@ -256,6 +261,12 @@ MainWindow::createTrayMenu()
   menu->addSeparator();
   menu->addAction(_actionShowControlPanel);
 
+  VidaliaSettings settings;
+  if(settings.allowPanic()) {
+    menu->addSeparator();
+    menu->addAction(_actionPanic);
+  }
+
   menu->addMenu(&_reattachMenu);
 
 #if !defined(Q_WS_MAC)
@@ -365,6 +376,7 @@ MainWindow::retranslateUi()
   _actionStatus->setText(tr("Status"));
   _actionVidaliaHelp->setText(tr("Help"));
   _actionNewIdentity->setText(tr("New Circuit"));
+  _actionPanic->setText(tr("Panic!"));
 
 #if !defined(Q_WS_MAC)
   _actionAbout->setText(tr("About"));
@@ -396,6 +408,8 @@ MainWindow::createConnections()
 
   connect(_actionDebugDialog, SIGNAL(triggered()), this, SLOT(showDebugDialog()));
 
+  connect(_actionPanic, SIGNAL(triggered()), this, SLOT(panic()));
+
   /* Catch signals when the application is running or shutting down */
   connect(vApp, SIGNAL(running()), this, SLOT(running()));
   connect(vApp, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit()));
@@ -2138,3 +2152,69 @@ MainWindow::installUpdatesFailed(const QString &errmsg)
 
 #endif
 
+/** Called when the panic button is pressed */
+void
+MainWindow::panic()
+{
+  VidaliaSettings settings;
+  QString binaryPath;
+  QFileInfo starter, vidalia;
+
+  // First some sanity checks so we don't remove any directory
+
+#if defined(Q_WS_WIN)
+  starter.setFile(QString("%1/%2")
+                  .arg(settings.panicPath())
+                  .arg("Start Tor Browser.exe"));
+  vidalia.setFile(QString("%1/%2")
+                  .arg(settings.panicPath())
+                  .arg("App/vidalia.exe"));
+
+  binaryPath = vidalia.absoluteFilePath();
+#elif defined(Q_WS_MAC)
+  starter.setFile(QString("%1/%2")
+                  .arg(settings.panicPath())
+                  .arg("Contents/MacOS/TorBrowserBundle"));
+  vidalia.setFile(QString("%1/%2")
+                  .arg(settings.panicPath())
+                  .arg("Contents/MacOS/Vidalia.app"));
+
+  binaryPath = QFileInfo(QString("%1/%2")
+                         .arg(settings.panicPath())
+                         .arg("Contents/MacOS/Vidalia.app/Contents/MacOS/Vidalia")).absolutePath();
+#else
+  starter.setFile(QString("%1/%2")
+                  .arg(settings.panicPath())
+                  .arg("start-tor-browser"));
+  vidalia.setFile(QString("%1/%2")
+                  .arg(settings.panicPath())
+                  .arg("App/vidalia"));
+
+  binaryPath = vidalia.absoluteFilePath();
+#endif
+
+  if(not (starter.exists() and vidalia.exists())) {
+    vWarn("Trying to panic but the directory is not what was expected.");
+    return;
+  }
+
+  if(binaryPath != QApplication::applicationFilePath()) {
+    vWarn("Trying to panic but the Panic Path does not contain Vidalia's binary");
+    return;
+  }
+
+  hide();
+  _trayIcon.setVisible(false);
+
+#if !defined(Q_WS_WIN)
+  bool res = remove_dir(settings.panicPath());
+#else
+  QProcess::startDetached(QString("cmd /C ping -n 1 127.0.0.1 >NUL && rmdir /Q /S \"%1\"")
+                          .arg(settings.panicPath()));
+#endif
+  if(_torControl->isRunning()) {
+    // We have taken tor's ownership, so just quit
+    vApp->disconnect();
+  }
+  vApp->quit();
+}
diff --git a/src/vidalia/MainWindow.h b/src/vidalia/MainWindow.h
index 6e60bb7..db9b7e1 100644
--- a/src/vidalia/MainWindow.h
+++ b/src/vidalia/MainWindow.h
@@ -162,6 +162,9 @@ private slots:
   /** Called when tor detects a problem with the system clock */
   void clockSkewed(int skew, const QString &source);
 
+  /** Called when the Panic! button is pressed */
+  void panic();
+
 #if defined(USE_AUTOUPDATE)
   /** Called when the user clicks the 'Check Now' button in the General
    * settings page. */
@@ -291,6 +294,7 @@ private:
   QAction *_actionAbout;
   QAction *_actionExit;
   QAction *_actionDebugDialog;
+  QAction *_actionPanic;
 
   QMenu _reattachMenu; /**< Menu used to handle tab re-attaching */
   QAction *_dummy; /**< Dummy action to display when there are no more tabs */
diff --git a/src/vidalia/config/AdvancedPage.cpp b/src/vidalia/config/AdvancedPage.cpp
index 7f9d884..084d17c 100644
--- a/src/vidalia/config/AdvancedPage.cpp
+++ b/src/vidalia/config/AdvancedPage.cpp
@@ -19,6 +19,7 @@
 #include "VMessageBox.h"
 #include "IpValidator.h"
 #include "Local8BitStringValidator.h"
+#include "VidaliaSettings.h"
 
 #include "file.h"
 
@@ -68,6 +69,8 @@ AdvancedPage::AdvancedPage(QWidget *parent)
   connect(ui.btnBrowseSocketPath, SIGNAL(clicked()), this, SLOT(browseSocketPath()));
   connect(ui.chkAuto, SIGNAL(toggled(bool)), this, SLOT(toggleAuto(bool)));
 
+  connect(ui.btnBrowsePanicPath, SIGNAL(clicked()), this, SLOT(browsePanicPath()));
+
   /* Hide platform specific features */
 #if defined(Q_WS_WIN)
 #if 0
@@ -76,6 +79,11 @@ AdvancedPage::AdvancedPage(QWidget *parent)
   /* Disable ControlSocket */
   ui.rdoControlSocket->setEnabled(false);
 #endif
+
+  ui.lblPanicWarn->setVisible(false);
+  ui.lblPanicPath->setVisible(false);
+  ui.linePanicPath->setVisible(false);
+  ui.btnBrowsePanicPath->setVisible(false);
 }
 
 /** Destructor */
@@ -209,6 +217,10 @@ AdvancedPage::save(QString &errmsg)
         && !ui.chkRandomPassword->isChecked())
     _settings->setControlPassword(ui.linePassword->text());
 
+  VidaliaSettings vsettings;
+  vsettings.setAllowPanic(ui.chkEnablePanic->isChecked());
+  vsettings.setPanicPath(ui.linePanicPath->text());
+
 #if 0
 #if defined(Q_WS_WIN)
   /* Install or uninstall the Tor service as necessary */
@@ -252,6 +264,11 @@ AdvancedPage::load()
     ui.chkAuto->setChecked(false);
     ui.chkAuto->setVisible(false);
   }
+
+  VidaliaSettings settings;
+
+  ui.chkEnablePanic->setChecked(settings.allowPanic());
+  ui.linePanicPath->setText(settings.panicPath());
 }
 
 /** Called when the user selects a different authentication method from the
@@ -448,3 +465,16 @@ AdvancedPage::displayWarning(bool checked)
                          indexToAuthMethod(ui.cmbAuthMethod->currentIndex()) ==
                          TorSettings::PasswordAuth);
 }
+
+/** Opens a QFileDialog for the user to browse to or create a directory for
+ * Tor's DataDirectory. */
+void
+AdvancedPage::browsePanicPath()
+{
+  QString panicPath = QFileDialog::getExistingDirectory(this,
+                      tr("Select a Directory to Use for Panic"),
+                      ui.linePanicPath->text());
+
+  if (!panicPath.isEmpty())
+    ui.linePanicPath->setText(panicPath);
+}
diff --git a/src/vidalia/config/AdvancedPage.h b/src/vidalia/config/AdvancedPage.h
index 0650376..ab91d0e 100644
--- a/src/vidalia/config/AdvancedPage.h
+++ b/src/vidalia/config/AdvancedPage.h
@@ -67,6 +67,9 @@ private slots:
   /** Called when the user clicks "Browse" to choose the location of Tor's
    * socket path. */
   void browseSocketPath();
+  /** Called when the user clicks "Browse" to choose location of Tor config
+   * file */
+  void browsePanicPath();
   /** Called when the user changes from ControlPort to ControlSocket or
    * the other way aroud */
   void toggleControl(bool);
diff --git a/src/vidalia/config/AdvancedPage.ui b/src/vidalia/config/AdvancedPage.ui
index 1799e24..a9c97fa 100644
--- a/src/vidalia/config/AdvancedPage.ui
+++ b/src/vidalia/config/AdvancedPage.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>586</width>
-    <height>522</height>
+    <width>619</width>
+    <height>608</height>
    </rect>
   </property>
   <property name="contextMenuPolicy">
@@ -252,7 +252,7 @@
       <item>
        <widget class="QLabel" name="lblWarn">
         <property name="text">
-         <string>WARNING: If you hand pick the password it will be saved as plain text in Vidalia's configuration file. Using a random password is safer.</string>
+         <string><b>WARNING</b>: If you hand pick the password it will be saved as plain text in Vidalia's configuration file. Using a random password is safer.</string>
         </property>
         <property name="wordWrap">
          <bool>true</bool>
@@ -415,6 +415,66 @@
     </widget>
    </item>
    <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Panic</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="3" column="1" colspan="2">
+       <widget class="QLabel" name="lblPanicWarn">
+        <property name="text">
+         <string><b>WARNING</b>: The panic button will erease the application if pressed</string>
+        </property>
+       </widget>
+      </item>
+      <item row="6" column="0" colspan="2">
+       <widget class="QLineEdit" name="linePanicPath">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+       </widget>
+      </item>
+      <item row="6" column="2">
+       <widget class="QPushButton" name="btnBrowsePanicPath">
+        <property name="text">
+         <string>Browse</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0">
+       <widget class="QCheckBox" name="chkEnablePanic">
+        <property name="text">
+         <string>Enable panic button</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0" colspan="2">
+       <widget class="QLabel" name="lblPanicPath">
+        <property name="text">
+         <string>Panic path:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1">
+       <spacer name="horizontalSpacer_2">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>1</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
@@ -439,5 +499,70 @@
   <tabstop>btnBrowseTorDataDirectory</tabstop>
  </tabstops>
  <resources/>
- <connections/>
+ <connections>
+  <connection>
+   <sender>chkEnablePanic</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>lblPanicWarn</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>319</x>
+     <y>448</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>316</x>
+     <y>472</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>chkEnablePanic</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>lblPanicPath</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>319</x>
+     <y>448</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>274</x>
+     <y>496</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>chkEnablePanic</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>linePanicPath</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>319</x>
+     <y>448</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>274</x>
+     <y>529</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>chkEnablePanic</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>btnBrowsePanicPath</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>319</x>
+     <y>448</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>568</x>
+     <y>531</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
 </ui>
diff --git a/src/vidalia/config/VidaliaSettings.cpp b/src/vidalia/config/VidaliaSettings.cpp
index c848358..913b0b1 100644
--- a/src/vidalia/config/VidaliaSettings.cpp
+++ b/src/vidalia/config/VidaliaSettings.cpp
@@ -38,6 +38,8 @@
 #define SETTING_LOCAL_GEOIP_DATABASE "LocalGeoIpDatabase"
 #define SETTING_PLUGIN_PATH         "PluginPath"
 #define SETTING_SKIP_VERSION_CHECK  "SkipVersionCheck"
+#define SETTING_ALLOW_PANIC         "AllowPanic"
+#define SETTING_PANIC_PATH          "PanicPath"
 
 #if defined(Q_OS_WIN32)
 #define STARTUP_REG_KEY        "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
@@ -84,6 +86,8 @@ VidaliaSettings::VidaliaSettings()
   setDefault(SETTING_ICON_PREF, Both);
   setDefault(SETTING_SKIP_VERSION_CHECK, false);
   setDefault(SETTING_REMEMBER_SHUTDOWN, false);
+  setDefault(SETTING_ALLOW_PANIC, false);
+  setDefault(SETTING_PANIC_PATH, "");
 }
 
 /** Gets the currently preferred language code for Vidalia. */
@@ -338,3 +342,27 @@ VidaliaSettings::setRememberShutdown(bool val)
 {
   setValue(SETTING_REMEMBER_SHUTDOWN, val);
 }
+
+bool
+VidaliaSettings::allowPanic() const
+{
+  return value(SETTING_ALLOW_PANIC).toBool();
+}
+
+void
+VidaliaSettings::setAllowPanic(bool val)
+{
+  setValue(SETTING_ALLOW_PANIC, val);
+}
+
+QString
+VidaliaSettings::panicPath() const
+{
+  return value(SETTING_PANIC_PATH).toString();
+}
+
+void
+VidaliaSettings::setPanicPath(const QString &path)
+{
+  setValue(SETTING_PANIC_PATH, path);
+}
diff --git a/src/vidalia/config/VidaliaSettings.h b/src/vidalia/config/VidaliaSettings.h
index d1c83a2..6f5efb1 100644
--- a/src/vidalia/config/VidaliaSettings.h
+++ b/src/vidalia/config/VidaliaSettings.h
@@ -136,6 +136,16 @@ public:
   bool rememberShutdown();
   /** Sets RememberShutdown to val */
   void setRememberShutdown(bool val);
+
+  /** Returns true if AllowPanic is enabled */
+  bool allowPanic() const;
+  /** Sets AllowPanic to val */
+  void setAllowPanic(bool val);
+
+  /** Returns the path that should be eliminated for panic */
+  QString panicPath() const;
+  /** Sets the path for panic */
+  void setPanicPath(const QString &path);
 };
 
 #endif





More information about the tor-commits mailing list