reload HTTP proxy credentials when moving to the next connection profile
PATCH v2 1/1 reload HTTP proxy credentials when moving to the next connection profile
The HTTP proxy credentials are stored in a static variable that is possibly initialized before each connection attempt.
However, the variable is never "released" therefore get_user_pass() refuses to overwrite its content and leaves it as it is. Consequently, if the user config contains multiple connection profiles with different http-proxy, each having its own credentials, only the first user/pass couple is loaded and the others are all ignored. This leads to connection failures because the proper credentials are not associated with the right proxy server.
The root of the misbehaviour seems to be located in the fact that, despite the argument force passed to get_user_pass_http() being true, no action is taken to release the static object containing the credentials.
Fix the misbehaviour by releasing the http-proxy credential object when the reload is "forced".
Trac: #836
---
v2:
- rebased on current master
src/openvpn/proxy.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
src/openvpn/proxy.c +10 -1
@@ -255,7 +255,16 @@ username_password_as_base64(const struct http_proxy_info *p,static void get_user_pass_http (struct http_proxy_info *p,const bool force) { -if (!static_proxy_user_pass.defined || force) +/* +* in case of forced (re)load, make sure the static storage is set as +* undefined, otherwise get_user_pass() won't try to load any credential +*/ +if (force) + { + static_proxy_user_pass.defined = false; + } + +if (!static_proxy_user_pass.defined) {unsigned int flags =GET_USER_PASS_MANAGEMENT ;if (p->queried_creds)
Signature · 1 line
2.15.1
Hi,
Feature-ACK, but one implementation concern:
Quoted 36 lines · Antonio Quartulli
The HTTP proxy credentials are stored in a static variable that is possibly initialized before each connection attempt.
However, the variable is never "released" therefore
get_user_pass()refuses to overwrite its content and leaves it as it is. Consequently, if the user config contains multiple connection profiles with different http-proxy, each having its own credentials, only the first user/pass couple is loaded and the others are all ignored. This leads to connection failures because the proper credentials are not associated with the right proxy server.The root of the misbehaviour seems to be located in the fact that, despite the argument force passed to
get_user_pass_http()being true, no action is taken to release the static object containing the credentials.Fix the misbehaviour by releasing the http-proxy credential object when the reload is "forced".
Trac: #836
Signed-off-by Antonio Quartulli <[email protected]...>---
v2:
- rebased on current mastersrc/openvpn/proxy.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)src/openvpn/proxy.c +0
-0@@ -255,7 +255,16 @@ username_password_as_base64(const struct http_proxy_info *p,static void get_user_pass_http (struct http_proxy_info *p,const bool force)
src/openvpn/proxy.c username_password_as_base64(const struct http_proxy_info *p, · line 265
Quoted 10 lines
src/openvpn/proxy.c +8
-1{ -if (!static_proxy_user_pass.defined || force) +/* +* in case of forced (re)load, make sure the static storage is set as +* undefined, otherwise get_user_pass() won't try to load any credential +*/ +if (force) + { + static_proxy_user_pass.defined = false; + }
I'm wondering, shouldn't we clear the username/password in the struct if we set defined=false as a hardening measure? And shouldn't we then just replace this if(force) block with a call to purge_user_pass(up, force)? Or should we be careful to not clear the other members of static_proxy_user_pass?
-Steffan
Hi,
Quoted 49 lines · Steffan Karger
Hi,
Feature-ACK, but one implementation concern:
Quoted 44 lines · Antonio Quartulli
The HTTP proxy credentials are stored in a static variable that is possibly initialized before each connection attempt.
However, the variable is never "released" therefore
get_user_pass()refuses to overwrite its content and leaves it as it is. Consequently, if the user config contains multiple connection profiles with different http-proxy, each having its own credentials, only the first user/pass couple is loaded and the others are all ignored. This leads to connection failures because the proper credentials are not associated with the right proxy server.The root of the misbehaviour seems to be located in the fact that, despite the argument force passed to
get_user_pass_http()being true, no action is taken to release the static object containing the credentials.Fix the misbehaviour by releasing the http-proxy credential object when the reload is "forced".
Trac: #836
Signed-off-by Antonio Quartulli <[email protected]...>---
v2:
- rebased on current mastersrc/openvpn/proxy.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)src/openvpn/proxy.c +6
-1@@ -255,7 +255,16 @@ username_password_as_base64(const struct http_proxy_info *p,static void get_user_pass_http (struct http_proxy_info *p,const bool force) { -if (!static_proxy_user_pass.defined || force) +/* +* in case of forced (re)load, make sure the static storage is set as +* undefined, otherwise get_user_pass() won't try to load any credential +*/ +if (force) + {
Quoted 8 lines
src/openvpn/proxy.c username_password_as_base64(const struct http_proxy_info *p, · line 265
Quoted 2 lines
src/openvpn/proxy.c +2
-0+ static_proxy_user_pass.defined = false; + }I'm wondering, shouldn't we clear the username/password in the struct if we set defined=false as a hardening measure? And shouldn't we then just replace this if(force) block with a call to
purge_user_pass(up, force)? Or should we be careful to not clear the other members ofstatic_proxy_user_pass?
There should be no problem in clearing up the struct, because the idea is that it has to be fully reinitialized with the "next proxy" information (so nothing to save).
Actually we could just re-use clear_user_pass_http() that is there for this purpose.
I'll send v3 with this change.
Thanks a lot for your review!
Cheers,
Quoted 11 lines
-Steffan
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Openvpn-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel
Signature · 1 line
Antonio Quartulli
PATCH v3 1/1 reload HTTP proxy credentials when moving to the next connection profile
The HTTP proxy credentials are stored in a static variable that is possibly initialized before each connection attempt.
However, the variable is never "released" therefore get_user_pass() refuses to overwrite its content and leaves it as it is. Consequently, if the user config contains multiple connection profiles with different http-proxy, each having its own credentials, only the first user/pass couple is loaded and the others are all ignored. This leads to connection failures because the proper credentials are not associated with the right proxy server.
The root of the misbehaviour seems to be located in the fact that, despite the argument force passed to get_user_pass_http() being true, no action is taken to release the static object containing the credentials.
Fix the misbehaviour by releasing the http-proxy credential object when the reload is "forced".
Trac: #836
---
v3:
- call clear_user_pass_http() directly to clear user/pass object
v2:
- rebased on current master
src/openvpn/proxy.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
src/openvpn/proxy.c +10 -1
@@ -255,7 +255,16 @@ username_password_as_base64(const struct http_proxy_info *p,static void get_user_pass_http (struct http_proxy_info *p,const bool force) { -if (!static_proxy_user_pass.defined || force) +/* +* in case of forced (re)load, make sure the static storage is set as +* undefined, otherwise get_user_pass() won't try to load any credential +*/ +if (force) + { +clear_user_pass_http (); + } + +if (!static_proxy_user_pass.defined) {unsigned int flags =GET_USER_PASS_MANAGEMENT ;if (p->queried_creds)
Signature · 1 line
2.15.1
PATCH v4 1/1 reload HTTP proxy credentials when moving to the next connection profile
The HTTP proxy credentials are stored in a static variable that is possibly initialized before each connection attempt.
However, the variable is never "released" therefore get_user_pass() refuses to overwrite its content and leaves it as it is. Consequently, if the user config contains multiple connection profiles with different http-proxy, each having its own credentials, only the first user/pass couple is loaded and the others are all ignored. This leads to connection failures because the proper credentials are not associated with the right proxy server.
The root of the misbehaviour seems to be located in the fact that, despite the argument force passed to get_user_pass_http() being true, no action is taken to release the static object containing the credentials.
Fix the misbehaviour by releasing the http-proxy credential object when the reload is "forced".
Trac: #836
---
v4:
- move clear_user_pass_http() above its invocation to prevent compile error
v3:
- call clear_user_pass_http() directly to clear user/pass object
v2:
- rebased on current master
src/openvpn/proxy.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
src/openvpn/proxy.c +16 -6
@@ -252,10 +252,25 @@ username_password_as_base64(const struct http_proxy_info *p,return (const char *)make_base64_string ((const uint8_t *)BSTR (&out), gc); } +static void +clear_user_pass_http (void ) +{ +purge_user_pass (&static_proxy_user_pass, true); +} +static void get_user_pass_http (struct http_proxy_info *p,const bool force) { -if (!static_proxy_user_pass.defined || force) +/* +* in case of forced (re)load, make sure the static storage is set as +* undefined, otherwise get_user_pass() won't try to load any credential +*/ +if (force) + { +clear_user_pass_http (); + } + +if (!static_proxy_user_pass.defined) {unsigned int flags =GET_USER_PASS_MANAGEMENT ;if (p->queried_creds)
@@ -274,11 +289,6 @@ get_user_pass_http(struct http_proxy_info *p, const bool force) p->up = static_proxy_user_pass; } } -static void -clear_user_pass_http (void ) -{ -purge_user_pass (&static_proxy_user_pass, true); -}#if 0 /* function only used in #if 0 debug statement */
Signature · 1 line
2.15.1
Hi,
Quoted 70 lines · Antonio Quartulli
The HTTP proxy credentials are stored in a static variable that is possibly initialized before each connection attempt.
However, the variable is never "released" therefore
get_user_pass()refuses to overwrite its content and leaves it as it is. Consequently, if the user config contains multiple connection profiles with different http-proxy, each having its own credentials, only the first user/pass couple is loaded and the others are all ignored. This leads to connection failures because the proper credentials are not associated with the right proxy server.The root of the misbehaviour seems to be located in the fact that, despite the argument force passed to
get_user_pass_http()being true, no action is taken to release the static object containing the credentials.Fix the misbehaviour by releasing the http-proxy credential object when the reload is "forced".
Trac: #836
Signed-off-by Antonio Quartulli <[email protected]...>---
v4:
- moveclear_user_pass_http()above its invocation to prevent compile errorv3:
- callclear_user_pass_http()directly to clear user/pass objectv2:
- rebased on current mastersrc/openvpn/proxy.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)src/openvpn/proxy.c +16
-1@@ -252,10 +252,25 @@ username_password_as_base64(const struct http_proxy_info *p,return (const char *)make_base64_string ((const uint8_t *)BSTR (&out), gc); } +static void +clear_user_pass_http (void ) +{ +purge_user_pass (&static_proxy_user_pass, true); +} +static void get_user_pass_http (struct http_proxy_info *p,const bool force) { -if (!static_proxy_user_pass.defined || force) +/* +* in case of forced (re)load, make sure the static storage is set as +* undefined, otherwise get_user_pass() won't try to load any credential +*/ +if (force) + { +clear_user_pass_http (); + } + +if (!static_proxy_user_pass.defined) {unsigned int flags =GET_USER_PASS_MANAGEMENT ;if (p->queried_creds)@@ -274,11 +289,6 @@ get_user_pass_http(struct http_proxy_info *p, const bool force) p->up = static_proxy_user_pass;
src/openvpn/proxy.c get_user_pass_http(struct http_proxy_info *p, const bool force) · line 294
Quoted 10 lines
src/openvpn/proxy.c +0
-5} } -static void -clear_user_pass_http (void ) -{ -purge_user_pass (&static_proxy_user_pass, true); -}#if 0 /* function only used in #if 0 debug statement */
Only "compile-tested" (no test proxies around), but change makes total sense, code is clear and I trust Antonio to have properly tested the behaviour.
-Steffan
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
ACK from me as well. Code looks sane and have tested this against a quickly patched tinyproxy [1] with basic auth support. The client switched between three different connection blocks, all depending on which tinyproxy instance I brought up or took down.
[1] <https://github.com/dsommers/tinyproxy
Your patch has been applied to the following branches
commit 86b58ceb29cf1cc3acf32e2ff370d9a4af68c051 (master) commit fbc50963b9f8a4bac4362d472366730fed23aae9 (release/2.4)
Author: Antonio Quartulli Date: Mon Dec 4 12:49:07 2017 +0800
reload HTTP proxy credentials when moving to the next connection profile
Trac: #836
Signed-off-by: Antonio Quartulli <[email protected]...>
Acked-by: Steffan Karger <[email protected]...>
Acked-by: David Sommerseth <[email protected]...>
Tested-by: David Sommerseth <[email protected]...>
Message-Id: <[email protected]...>
URL: https://www.mail-archive.com/[email protected]/msg16007.html
Signed-off-by: David Sommerseth <[email protected]...>- --
kind regards,
David Sommerseth
OpenVPN Inc.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
iQIcBAEBCgAGBQJaKFx8AAoJEIbPlEyWcf3yxJIQAL6ABxeacMYBJuFamF8gEoL+ W0a+grWzL7wNQ7n05pc/2UuOgbpliyGerhBx85VCFPTdYN6JBuVUEEDj67CptVL9 N3zSCbzVxeX21oaLfyoeYVypTopOBHB1rxBhwdC8MBdLBNPhZQ2Qy1r7XWLDX1mH 4vY1SP/X25NJcU71dmDN8zCimEPns/ANTjMf0r8lyQAdvMuSZE5sCRCutwTRNh/S REAcXHtgFRfmNsmDRRCJvTvm+XiPNNY15EH/NmmHFquZAJuj2GkpGeBYa59q9l3D tHcPzwes2xc1Te4kbca1tXAx6XCt/6e7FwENCQHCrwC0/NRSdmOFg89BiIZVnodh L9NbVte8f+jFuV8DuBDqHIQdodry0JKD4YnC+QQhTJChGWwexyimLuxKMNANVEmb 6KRJvaUKzOyrsh8ct6ZMG35AgXM6MKQqMwmP+VB/SJrh6uCOZkxxxQMY5/vXL+hp Zlzxs9WS/p2MbO9igHcMGXPGBEuzsp4KFKyMBAjrlpCFCFJFJfPPThi2eaiPSkXt StFkSCLu1CnKifbB7KiLL2YORy3QyITDVshUbaBVZRl7g1Jlr+4UzG48NR9RIWE0 59XGJARegLPtxevO/DyArPOU+Ls5HQfN8YNCIf/dj41GuuYx4AdiKD1KSkClQHRK 83xeFyq2p7wWcIilIXXY
=NQs1
-----END PGP SIGNATURE-----