From 9183263304e4bb3d717ee5f5ed9635327e442fb6 Mon Sep 17 00:00:00 2001 From: Johann Bauer Date: Fri, 17 Feb 2017 13:56:23 +0100 Subject: [PATCH] Detect Tor and suggest using it --- gui/qt/network_dialog.py | 55 +++++++++++++++++++++++++++++++++++++-- icons.qrc | 1 + icons/tor_logo.png | Bin 0 -> 2712 bytes 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 icons/tor_logo.png diff --git a/gui/qt/network_dialog.py b/gui/qt/network_dialog.py index 1c9b1a3c..83d7ef9f 100644 --- a/gui/qt/network_dialog.py +++ b/gui/qt/network_dialog.py @@ -22,6 +22,7 @@ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import socket from PyQt4.QtGui import * from PyQt4.QtCore import * @@ -38,7 +39,7 @@ protocol_letters = 'ts' class NetworkDialog(WindowModalDialog): def __init__(self, network, config, parent): WindowModalDialog.__init__(self, parent, _('Network')) - self.setMinimumSize(375, 20) + self.setMinimumSize(400, 20) self.nlayout = NetworkChoiceLayout(network, config) vbox = QVBoxLayout(self) vbox.addLayout(self.nlayout.layout()) @@ -56,6 +57,7 @@ class NetworkChoiceLayout(object): self.network = network self.config = config self.protocol = None + self.tor_proxy = None self.servers = network.get_servers() host, port, protocol, proxy_config, auto_connect = network.get_parameters() @@ -108,7 +110,7 @@ class NetworkChoiceLayout(object): # use SSL self.ssl_cb = QCheckBox(_('Use SSL')) self.ssl_cb.setChecked(auto_connect) - grid.addWidget(self.ssl_cb, 3, 1, 1, 3) + grid.addWidget(self.ssl_cb, 0, 2, 1, 1, Qt.AlignRight) self.ssl_cb.stateChanged.connect(self.change_protocol) # auto connect @@ -175,7 +177,15 @@ class NetworkChoiceLayout(object): grid.addWidget(self.proxy_mode, 4, 1) grid.addWidget(self.proxy_host, 4, 2) grid.addWidget(self.proxy_port, 4, 3) + self.tor_button = QPushButton("Use Tor Proxy") + self.tor_button.setIcon(QIcon(":icons/tor_logo.png")) + self.tor_button.hide() + self.tor_button.clicked.connect(self.use_tor_proxy) + grid.addWidget(self.tor_button, 5, 1, 1, 2) self.layout_ = vbox + td = TorDetector() + td.found_proxy.connect(self.suggest_proxy) + td.start() def layout(self): return self.layout_ @@ -250,3 +260,44 @@ class NetworkChoiceLayout(object): auto_connect = self.autoconnect_cb.isChecked() self.network.set_parameters(host, port, protocol, proxy, auto_connect) + + def suggest_proxy(self, found_proxy): + self.tor_proxy = found_proxy + self.tor_button.setText("Use Tor proxy at port " + str(found_proxy[1])) + self.tor_button.show() + + def use_tor_proxy(self): + # 2 = SOCKS5 + self.proxy_mode.setCurrentIndex(2) + self.proxy_host.setText("127.0.0.1") + self.proxy_port.setText(str(self.tor_proxy[1])) + self.tor_button.hide() + + +class TorDetector(QThread): + found_proxy = pyqtSignal(object) + + def __init__(self): + QThread.__init__(self) + + def run(self): + # Probable ports for Tor to listen at + ports = [9050, 9150] + for p in ports: + if TorDetector.is_tor_port(p): + self.found_proxy.emit(("127.0.0.1", p)) + return + + @staticmethod + def is_tor_port(port): + try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.settimeout(0.1) + s.connect(("127.0.0.1", port)) + # Tor responds uniquely to HTTP-like requests + s.send("GET\n") + if "Tor is not an HTTP Proxy" in s.recv(1024): + return True + except socket.error: + pass + return False diff --git a/icons.qrc b/icons.qrc index 2a05c23d..b75d167c 100644 --- a/icons.qrc +++ b/icons.qrc @@ -30,6 +30,7 @@ icons/status_waiting.png icons/status_lagging.png icons/seal.png + icons/tor_logo.png icons/speaker.png icons/trezor_unpaired.png icons/trezor.png diff --git a/icons/tor_logo.png b/icons/tor_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a4afd849207b3a046691c05a5afa307ff459c886 GIT binary patch literal 2712 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