fireinfo: support upstream proxy with authentication

Message ID 20181027142016.5402-1-peter.mueller@link38.eu
State Superseded
Headers
Series fireinfo: support upstream proxy with authentication |

Commit Message

Peter Müller Oct. 28, 2018, 1:20 a.m. UTC
  Fireinfo could not send its profile to https://fireinfo.ipfire.org/
if the machine is behind an upstream proxy which requires username
and password. This is fixed by tweaking urllib2's opening handler.

To apply this on existing installations, the fireinfo package
needs to be shipped during an update.

Fixes #11905

Signed-off-by: Peter Müller <peter.mueller@link38.eu>
---
 src/sendprofile | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
 mode change 100644 => 100755 src/sendprofile
  

Comments

Michael Tremer Oct. 30, 2018, 12:32 a.m. UTC | #1
Hi,

On Sat, 2018-10-27 at 16:20 +0200, Peter Müller wrote:
> Fireinfo could not send its profile to https://fireinfo.ipfire.org/
> if the machine is behind an upstream proxy which requires username
> and password. This is fixed by tweaking urllib2's opening handler.
> 
> To apply this on existing installations, the fireinfo package
> needs to be shipped during an update.
> 
> Fixes #11905
> 
> Signed-off-by: Peter Müller <peter.mueller@link38.eu>
> ---
>  src/sendprofile | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
>  mode change 100644 => 100755 src/sendprofile
> 
> diff --git a/src/sendprofile b/src/sendprofile
> old mode 100644
> new mode 100755
> index b836567..8c0603f
> --- a/src/sendprofile
> +++ b/src/sendprofile
> @@ -73,10 +73,17 @@ def send_profile(profile):
>  	request.add_header("User-Agent", "fireinfo/%s" % fireinfo.__version__)
>  
>  	# Set upstream proxy if we have one.
> -	# XXX this cannot handle authentication
>  	proxy = get_upstream_proxy()
> +
>  	if proxy["host"]:
> -		request.set_proxy(proxy["host"], "http")
> +                # handling upstream proxies with authentication is more
> tricky...

The commented line is indented with spaces whereas everything else is using
tabs. Python doesn't like this to be mixed.

> +		if proxy["user"] and proxy["pass"]:
> +			proxy_handler = urllib2.ProxyHandler({'https': '
> http://' + proxy["user"] + ':' + proxy["pass"] + '@' + proxy["host"] + '/'})

I am not a fan of formatting strings like this, because I find it hard to read,
and this doesn't work when one of the variables isn't a string.

> +			auth = urllib2.HTTPBasicAuthHandler()
> +			opener = urllib2.build_opener(proxy_handler, auth,
> urllib2.HTTPHandler)
> +			urllib2.install_opener(opener)
> +		else:
> +			request.set_proxy(proxy["host"], "https")

Why does this patch remove the proxy for HTTP without mentioning it? I know that
we only send requests via HTTPS now, but I think generally this should be
configured just in case.

>  	try:
>  		urllib2.urlopen(request, timeout=60)

-Michael
  

Patch

diff --git a/src/sendprofile b/src/sendprofile
old mode 100644
new mode 100755
index b836567..8c0603f
--- a/src/sendprofile
+++ b/src/sendprofile
@@ -73,10 +73,17 @@  def send_profile(profile):
 	request.add_header("User-Agent", "fireinfo/%s" % fireinfo.__version__)
 
 	# Set upstream proxy if we have one.
-	# XXX this cannot handle authentication
 	proxy = get_upstream_proxy()
+
 	if proxy["host"]:
-		request.set_proxy(proxy["host"], "http")
+                # handling upstream proxies with authentication is more tricky...
+		if proxy["user"] and proxy["pass"]:
+			proxy_handler = urllib2.ProxyHandler({'https': 'http://' + proxy["user"] + ':' + proxy["pass"] + '@' + proxy["host"] + '/'})
+			auth = urllib2.HTTPBasicAuthHandler()
+			opener = urllib2.build_opener(proxy_handler, auth, urllib2.HTTPHandler)
+			urllib2.install_opener(opener)
+		else:
+			request.set_proxy(proxy["host"], "https")
 
 	try:
 		urllib2.urlopen(request, timeout=60)