Repository: spesmilo/electrum

Issue:
FEATURE REQUEST SOCKS5 Proxy With Authentication
I have a paid vpn/proxy combo and would like to be able to route electrum through the proxy rather than connecting my entire machine to the vpn. It would be nice if it was possible to login to my proxy to connect. 


Discussion:
how would that differ from wht we currently have?
There is no field to fill in your username and password

On Dec 11, 2016 1:15 AM, "ThomasV" <notifications@github.com> wrote:

> how would that differ from wht we currently have?
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/spesmilo/electrum/issues/2073#issuecomment-266267456>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AXWCx4R4D2mrGFtP8Bqm5WDTiTq1BpFeks5rG6MdgaJpZM4LJAlL>
> .
>

@mamamia88 I implemented this last night. I'll submit a PR later tonight.
thanks! looking forward to it
Any update on said pull request @desantis 
@mamamia88 cleaning as we speak. Sorry, a few other things popped up.

Resolving patch:
diff --git a/gui/qt/network_dialog.py b/gui/qt/network_dialog.py
--- a/gui/qt/network_dialog.py
+++ b/gui/qt/network_dialog.py
@@ -155,15 +155,17 @@ def enable_set_server():
         self.proxy_port = QLineEdit()
         self.proxy_port.setFixedWidth(60)
         self.proxy_mode.addItems(['NONE', 'SOCKS4', 'SOCKS5', 'HTTP'])
+        self.proxy_user = QLineEdit()
+        self.proxy_user.setPlaceholderText(_("Proxy user"))
+        self.proxy_password = QLineEdit()
+        self.proxy_password.setPlaceholderText(_("Password"))
+        self.proxy_password.setEchoMode(QLineEdit.Password)
+        self.proxy_password.setFixedWidth(60)
 
         def check_for_disable(index = False):
             if self.config.is_modifiable('proxy'):
-                if self.proxy_mode.currentText() != 'NONE':
-                    self.proxy_host.setEnabled(True)
-                    self.proxy_port.setEnabled(True)
-                else:
-                    self.proxy_host.setEnabled(False)
-                    self.proxy_port.setEnabled(False)
+                for w in [self.proxy_host, self.proxy_port, self.proxy_user, self.proxy_password]:
+                    w.setEnabled(self.proxy_mode.currentText() != 'NONE')
             else:
                 for w in [self.proxy_host, self.proxy_port, self.proxy_mode]: w.setEnabled(False)
 
@@ -173,20 +175,26 @@ def check_for_disable(index = False):
         self.proxy_mode.setCurrentIndex(self.proxy_mode.findText(str(proxy_config.get("mode").upper())))
         self.proxy_host.setText(proxy_config.get("host"))
         self.proxy_port.setText(proxy_config.get("port"))
+        self.proxy_user.setText(proxy_config.get("user", ""))
+        self.proxy_password.setText(proxy_config.get("password", ""))
 
         self.proxy_mode.connect(self.proxy_mode, SIGNAL('currentIndexChanged(int)'), self.proxy_settings_changed)
         self.proxy_host.connect(self.proxy_host, SIGNAL('textEdited(QString)'), self.proxy_settings_changed)
         self.proxy_port.connect(self.proxy_port, SIGNAL('textEdited(QString)'), self.proxy_settings_changed)
+        self.proxy_user.connect(self.proxy_user, SIGNAL('textEdited(QString)'), self.proxy_settings_changed)
+        self.proxy_password.connect(self.proxy_password, SIGNAL('textEdited(QString)'), self.proxy_settings_changed)
 
         grid.addWidget(QLabel(_('Proxy') + ':'), 4, 0)
         grid.addWidget(self.proxy_mode, 4, 1)
         grid.addWidget(self.proxy_host, 4, 2)
         grid.addWidget(self.proxy_port, 4, 3)
-        self.tor_button = QCheckBox("Use Tor Proxy")
+        grid.addWidget(self.proxy_user, 5, 2)
+        grid.addWidget(self.proxy_password, 5, 3)
+        self.tor_button = QCheckBox(_("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)
+        grid.addWidget(self.tor_button, 6, 2, 1, 2)
         self.layout_ = vbox
         self.td = td = TorDetector()
         td.found_proxy.connect(self.suggest_proxy)
@@ -258,7 +266,9 @@ def accept(self):
         if self.proxy_mode.currentText() != 'NONE':
             proxy = { 'mode':str(self.proxy_mode.currentText()).lower(),
                       'host':str(self.proxy_host.text()),
-                      'port':str(self.proxy_port.text()) }
+                      'port':str(self.proxy_port.text()),
+                      'user':str(self.proxy_user.text()),
+                      'password':str(self.proxy_password.text())}
         else:
             proxy = None
 
@@ -284,6 +294,8 @@ def use_tor_proxy(self, use_it):
             self.proxy_mode.setCurrentIndex(2)
             self.proxy_host.setText("127.0.0.1")
             self.proxy_port.setText(str(self.tor_proxy[1]))
+            self.proxy_user.setText("")
+            self.proxy_password.setText("")
             self.tor_button.setChecked(True)
 
     def proxy_settings_changed(self):
diff --git a/lib/network.py b/lib/network.py
--- a/lib/network.py
+++ b/lib/network.py
@@ -129,7 +129,7 @@ def pick_random_server(hostmap = None, protocol = 's', exclude_set = set()):
 def serialize_proxy(p):
     if type(p) != dict:
         return None
-    return ':'.join([p.get('mode'),p.get('host'), p.get('port')])
+    return ':'.join([p.get('mode'),p.get('host'), p.get('port'), p.get('user'), p.get('password')])
 
 def deserialize_proxy(s):
     if type(s) not in [str, unicode]:
@@ -147,8 +147,14 @@ def deserialize_proxy(s):
         n += 1
     if len(args) > n:
         proxy["port"] = args[n]
+        n += 1
     else:
         proxy["port"] = "8080" if proxy["mode"] == "http" else "1080"
+    if len(args) > n:
+        proxy["user"] = args[n]
+        n += 1
+    if len(args) > n:
+        proxy["password"] = args[n]
     return proxy
 
 def deserialize_server(server_str):
@@ -400,7 +406,12 @@ def set_proxy(self, proxy):
         if proxy:
             self.print_error('setting proxy', proxy)
             proxy_mode = proxy_modes.index(proxy["mode"]) + 1
-            socks.setdefaultproxy(proxy_mode, proxy["host"], int(proxy["port"]))
+            socks.setdefaultproxy(proxy_mode,
+                                  proxy["host"],
+                                  int(proxy["port"]),
+                                  # socks.py seems to want either None or a non-empty string
+                                  username=(proxy.get("user", "") or None),
+                                  password=(proxy.get("password", "") or None))
             socket.socket = socks.socksocket
             # prevent dns leaks, see http://stackoverflow.com/questions/13184205/dns-over-proxy
             socket.getaddrinfo = lambda *args: [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (args[0], args[1]))]


Test patch: