[tor-commits] [vidalia-plugins/master] Add hidden service configuration plugin

chiiph at torproject.org chiiph at torproject.org
Sat Aug 4 00:36:26 UTC 2012


commit 63bb27bcfc0036ab693225018da1e70d88dadbcf
Author: Feroze Naina <ferozenaina at gmail.com>
Date:   Sat Jun 30 16:19:49 2012 +0530

    Add hidden service configuration plugin
---
 hiddenservice/containerWidget.ui |  171 +++++++++++++++++++++++++++++
 hiddenservice/customWidget.ui    |  162 ++++++++++++++++++++++++++++
 hiddenservice/hiddenservice.js   |  219 ++++++++++++++++++++++++++++++++++++++
 hiddenservice/info.xml           |   10 ++
 4 files changed, 562 insertions(+), 0 deletions(-)

diff --git a/hiddenservice/containerWidget.ui b/hiddenservice/containerWidget.ui
new file mode 100644
index 0000000..426dd89
--- /dev/null
+++ b/hiddenservice/containerWidget.ui
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>668</width>
+    <height>628</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="2" column="0">
+    <spacer name="horizontalSpacer_2">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>40</width>
+       <height>20</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="1" column="0" colspan="5">
+    <widget class="QScrollArea" name="scrollArea">
+     <property name="minimumSize">
+      <size>
+       <width>600</width>
+       <height>400</height>
+      </size>
+     </property>
+     <property name="widgetResizable">
+      <bool>true</bool>
+     </property>
+     <widget class="QWidget" name="scrollAreaWidgetContents">
+      <property name="geometry">
+       <rect>
+        <x>0</x>
+        <y>0</y>
+        <width>642</width>
+        <height>522</height>
+       </rect>
+      </property>
+      <layout class="QVBoxLayout" name="verticalLayout_2">
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>495</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+   <item row="2" column="1">
+    <widget class="QPushButton" name="btnApply">
+     <property name="enabled">
+      <bool>false</bool>
+     </property>
+     <property name="text">
+      <string>Apply</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="4">
+    <widget class="QPushButton" name="btnRemove">
+     <property name="enabled">
+      <bool>false</bool>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>32</width>
+       <height>32</height>
+      </size>
+     </property>
+     <property name="text">
+      <string/>
+     </property>
+     <property name="icon">
+      <iconset resource="../../vidalia/src/vidalia/res/vidalia.qrc">
+       <normaloff>:/images/22x22/list-remove.png</normaloff>:/images/22x22/list-remove.png</iconset>
+     </property>
+     <property name="iconSize">
+      <size>
+       <width>22</width>
+       <height>22</height>
+      </size>
+     </property>
+     <property name="flat">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="2" colspan="3">
+    <widget class="QPushButton" name="btnDiscard">
+     <property name="enabled">
+      <bool>false</bool>
+     </property>
+     <property name="text">
+      <string>Discard Changes</string>
+     </property>
+     <property name="default">
+      <bool>false</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="3">
+    <widget class="QPushButton" name="btnAdd">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>32</width>
+       <height>32</height>
+      </size>
+     </property>
+     <property name="text">
+      <string/>
+     </property>
+     <property name="icon">
+      <iconset resource="../../vidalia/src/vidalia/res/vidalia.qrc">
+       <normaloff>:/images/22x22/list-add.png</normaloff>:/images/22x22/list-add.png</iconset>
+     </property>
+     <property name="iconSize">
+      <size>
+       <width>22</width>
+       <height>22</height>
+      </size>
+     </property>
+     <property name="flat">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="0" colspan="3">
+    <spacer name="horizontalSpacer">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>40</width>
+       <height>0</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../../vidalia/src/vidalia/res/vidalia.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/hiddenservice/customWidget.ui b/hiddenservice/customWidget.ui
new file mode 100644
index 0000000..2345872
--- /dev/null
+++ b/hiddenservice/customWidget.ui
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>488</width>
+    <height>173</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>400</width>
+    <height>0</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="minimumSize">
+      <size>
+       <width>410</width>
+       <height>150</height>
+      </size>
+     </property>
+     <property name="title">
+      <string/>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="4" column="1">
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>Port</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="2">
+       <widget class="QLineEdit" name="lineDir">
+        <property name="minimumSize">
+         <size>
+          <width>100</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="placeholderText">
+         <string/>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QLabel" name="label_3">
+        <property name="text">
+         <string>Name</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="2" colspan="2">
+       <widget class="QLineEdit" name="lineName">
+        <property name="inputMask">
+         <string/>
+        </property>
+        <property name="readOnly">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>Directory</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="3" alignment="Qt::AlignRight">
+       <widget class="QPushButton" name="btnBrowse">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>25</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>Browse</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="3">
+       <widget class="QSpinBox" name="spinPort">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Ignored" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>50</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="maximum">
+         <number>65535</number>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="2">
+       <widget class="QLineEdit" name="lineAddress">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>127.0.0.1</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="1" colspan="2">
+       <widget class="QCheckBox" name="checkBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>25</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>Mark for removal</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/hiddenservice/hiddenservice.js b/hiddenservice/hiddenservice.js
new file mode 100644
index 0000000..606a759
--- /dev/null
+++ b/hiddenservice/hiddenservice.js
@@ -0,0 +1,219 @@
+importExtension("qt");
+importExtension("qt.core");
+importExtension("qt.gui");
+importExtension("qt.uitools");
+importExtension("qt.network");
+
+var hiddenservice = {
+    removeServices: function() {
+        torrc.clear(["HiddenServiceDir", "HiddenServicePort"]);
+
+        for(i = 0; i < this.customwidget.length; i++) {
+            if (this.chkBox[i].checkState() == Qt.Unchecked) {
+            torrc.setValue("HiddenServiceDir", this.hidservdir[i]);
+            torrc.setValue("HiddenServicePort", this.hidservport[i]);
+            }
+        }
+
+        torrc.apply(torControl);
+
+        this.updateList();
+        this.btnRemove.enabled = false;
+    },
+
+    updateList: function() {
+
+        try{
+            for(i = 0; i < this.customwidget.length; i++) {
+                this.customwidget[i].hide();
+                this.listLayout.removeWidget(this.customwidget[i]);
+            }
+        }
+        catch(err){}
+
+        this.hidservdir = torrc.value("HiddenServiceDir");
+        this.hidservport = torrc.value("HiddenServicePort");
+
+        this.customwidget = new Array();
+        this.grpBox = new Array();
+        this.lineDir = new Array();
+        this.spinPort = new Array();
+        this.lineAddress = new Array();
+        this.lineName = new Array();
+        this.chkBox = new Array();
+        this.btnBrowse = new Array();
+
+        this.address = new QHostAddress();
+
+        this.listLayout = this.scrollArea.widget().layout();
+        while(this.listLayout.count() > 1) this.listLayout.takeAt(0);
+
+        var loader = new QUiLoader(this.containerWidget);
+
+        for(i = 0; i< this.hidservdir.length; i++) {
+            this.customwidget[i] = loader.load(new QFile(pluginPath + "/hiddenservice/customWidget.ui"));
+            this.grpBox[i] = this.customwidget[i].children()[findWidget(this.customwidget[i], "groupBox")];
+            this.lineDir[i] = this.grpBox[i].children()[findWidget(this.grpBox[i], "lineDir")];
+            this.spinPort[i] = this.grpBox[i].children()[findWidget(this.grpBox[i], "spinPort")];
+            this.lineAddress[i] = this.grpBox[i].children()[findWidget(this.grpBox[i], "lineAddress")];
+            this.lineName[i] = this.grpBox[i].children()[findWidget(this.grpBox[i], "lineName")];
+            this.chkBox[i] = this.grpBox[i].children()[findWidget(this.grpBox[i], "checkBox")];
+            this.btnBrowse[i] = this.grpBox[i].children()[findWidget(this.grpBox[i], "btnBrowse")];
+
+            var file = new QFile(this.hidservdir[i] + "/hostname");
+            if(file.open(QIODevice.ReadOnly))
+            {
+                var textStream = new QTextStream(file);
+                this.lineName[i].setText(textStream.readLine());
+            }
+
+            this.lineDir[i].setText(this.hidservdir[i]);
+            this.spinPort[i].value = this.hidservport[i].split(" ")[0];
+            if (this.hidservport[i].split(" ")[1])
+                this.lineAddress[i].setText(this.hidservport[i].split(" ")[1]);
+            else
+                this.lineAddress[i].setText("127.0.0.1");
+
+            this.chkBox[i]['stateChanged(int)'].connect(this, this.enableRemove);
+            this.lineDir[i]['textEdited(QString)'].connect(this, this.enableApply);
+            this.spinPort[i]['valueChanged(int)'].connect(this, this.enableApply);
+            this.lineAddress[i]['textEdited(QString)'].connect(this, this.enableApply);
+            this.btnBrowse[i]['clicked()'].connect(this, this.browseDir);
+
+            this.listLayout.insertWidget(0, this.customwidget[i], 0, 0);
+        }
+
+        this.btnApply.enabled = false;
+        this.btnDiscard.enabled = false;
+    },
+
+    browseDir: function() {
+        QFileDialog.getExistingDirectory(this, "Browse Directory", "/home");
+    },
+
+    applyServices: function() {
+        torrc.clear(["HiddenServiceDir", "HiddenServicePort"]);
+
+        for(i = this.customwidget.length-1; i >= 0; i--) {
+            torrc.setValue("HiddenServiceDir", this.lineDir[i].text);
+            torrc.setValue("HiddenServicePort", this.spinPort[i].value + " " + this.lineAddress[i].text);
+        }
+
+        torrc.apply(torControl);
+
+        this.updateList();
+        this.btnApply.enabled = false;
+        this.btnDiscard.enabled = false;
+    },
+
+    enableApply: function() {
+        this.btnDiscard.enabled = true;
+        if(this.sanityCheck()) 
+            this.btnApply.enabled = true;
+        else
+            this.btnApply.enabled = false;
+    },
+
+    sanityCheck: function() {
+        for(i = 0; i < this.customwidget.length; i++) {
+            var ip = this.lineAddress[i].text.split(":");
+            var port = this.spinPort[i].value;
+
+            if(! this.address.setAddress(ip[0]))
+                return false;
+            if(port < 1 || port >65535)
+                return false;
+            if(ip[1] < 1 || ip[1] > 65535)
+                return false;
+        }
+
+            return true;
+    },
+
+    enableRemove: function() {
+        this.btnRemove.enabled = false;
+        for (i = 0; i < this.hidservdir.length; i++) {
+            if(this.chkBox[i].checkState() == Qt.Checked) {
+                this.btnRemove.enabled = true;
+                break;
+            }
+        }
+    },
+
+    addService: function() {
+
+        var loader = new QUiLoader(this.containerWidget);
+        this.customwidget.push(loader.load(new QFile(pluginPath + "/hiddenservice/customWidget.ui")));
+        var pos = this.customwidget.length-1;
+
+        this.grpBox[pos] = this.customwidget[pos].children()[findWidget(this.customwidget[pos], "groupBox")];
+        this.lineDir[pos] = this.grpBox[pos].children()[findWidget(this.grpBox[pos], "lineDir")];
+        this.spinPort[pos] = this.grpBox[pos].children()[findWidget(this.grpBox[pos], "spinPort")];
+        this.lineAddress[pos] = this.grpBox[i].children()[findWidget(this.grpBox[pos], "lineAddress")];
+        this.lineName[pos] = this.grpBox[pos].children()[findWidget(this.grpBox[pos], "lineName")];
+        this.chkBox[pos] = this.grpBox[pos].children()[findWidget(this.grpBox[pos], "checkBox")];
+
+        this.chkBox[pos]['stateChanged(int)'].connect(this, this.enableRemove);
+        this.lineDir[pos]['textEdited(QString)'].connect(this, this.enableApply);
+        this.spinPort[pos]['valueChanged(int)'].connect(this, this.enableApply);
+        this.lineAddress[pos]['textEdited(QString)'].connect(this, this.enableApply);
+
+        this.listLayout.insertWidget(0, this.customwidget[this.customwidget.length-1], 0, 0);
+    },
+
+
+    start: function() {
+        vdebug("HiddenService at start");
+    },
+
+    buildGUI: function() {
+        vdebug("HiddenService at buildGUI");
+
+        this.tab = new VidaliaTab("Configure hidden services", "HiddenService");
+
+        var containerui = new QFile(pluginPath + "/hiddenservice/containerWidget.ui");
+        var loader = new QUiLoader(this.tab);
+        containerui.open(QIODevice.ReadOnly);
+
+        this.containerwidget = loader.load(containerui);
+
+        var layout = new QVBoxLayout();
+        layout.addWidget(this.containerwidget, 0, Qt.AlignCenter);
+        this.tab.setLayout(layout);
+
+        this.scrollArea = this.containerwidget.children()[findWidget(this.containerwidget, "scrollArea")];
+        if(this.scrollArea == null)
+            return this.tab;
+
+        this.btnAdd = this.containerwidget.children()[findWidget(this.containerwidget, "btnAdd")];
+        if(this.btnAdd == null)
+            return this.tab;
+
+        this.btnRemove = this.containerwidget.children()[findWidget(this.containerwidget, "btnRemove")];
+        if(this.btnRemove == null)
+            return this.tab;
+
+        this.btnApply = this.containerwidget.children()[findWidget(this.containerwidget, "btnApply")];
+        if(this.btnApply == null)
+            return this.tab;
+
+        this.btnDiscard = this.containerwidget.children()[findWidget(this.containerwidget, "btnDiscard")];
+        if(this.btnDiscard == null)
+            return this.tab;
+
+        this.updateList();
+
+        this.btnRemove['clicked()'].connect(this, this.removeServices);
+        this.btnAdd['clicked()'].connect(this, this.addService);
+        this.btnApply['clicked()'].connect(this, this.applyServices);
+        this.btnDiscard['clicked()'].connect(this, this.updateList);
+
+        containerui.close();
+
+        return this.tab;
+    },
+
+    stop: function() {
+        vdebug("Tutorial at stop");
+    },
+};
diff --git a/hiddenservice/info.xml b/hiddenservice/info.xml
new file mode 100644
index 0000000..0460e12
--- /dev/null
+++ b/hiddenservice/info.xml
@@ -0,0 +1,10 @@
+<VidaliaPlugin>
+  <name>Hidden Service</name>
+  <date>7/05/2012</date>
+  <author>feroze</author>
+  <type persistent="false" gui="true" />
+  <files>
+    <file>hiddenservice.js</file>
+  </files>
+  <namespace>hiddenservice</namespace>
+</VidaliaPlugin>





More information about the tor-commits mailing list