commit 63bb27bcfc0036ab693225018da1e70d88dadbcf Author: Feroze Naina ferozenaina@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@start"); + }, + + buildGUI: function() { + vdebug("HiddenService@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@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>
tor-commits@lists.torproject.org