From: Gianmarco De Gregori Date: Sun, 23 Jun 2024 20:05:51 +0000 (+0200) Subject: Http-proxy: fix bug preventing proxy credentials caching X-Git-Tag: v2.6.12~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ad0c2c078ea505436b19255ebfbc8365044c5953;p=thirdparty%2Fopenvpn.git Http-proxy: fix bug preventing proxy credentials caching Caching proxy credentials was not working due to the lack of handling already defined creds in get_user_pass(), which prevented the caching from working properly. Fix this issue by getting the value of c->first_time, that indicates if we're at the first iteration of the main loop and use it as second argument of the get_user_pass_http(). Otherwise, on SIGUSR1 or SIGHUP upon instance context restart credentials would be erased every time. The nocache member has been added to the struct http_proxy_options and also a getter method to retrieve that option from ssl has been added, by doing this we're able to erase previous queried user credentials to ensure correct operation. Fixes: Trac #1187 Signed-off-by: Gianmarco De Gregori Acked-by: Gert Doering Change-Id: Ia3e06c0832c4ca0ab868c845279fb71c01a1a78a Acked-by: Frank Lichtenheld Message-Id: <20240623200551.20092-1-gert@greenie.muc.de> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28835.html Signed-off-by: Gert Doering (cherry picked from commit 3cfd6f961d5c92bec283ac3616e1633b4e16760c) --- diff --git a/doc/man-sections/generic-options.rst b/doc/man-sections/generic-options.rst index 45794860e..f805d13ed 100644 --- a/doc/man-sections/generic-options.rst +++ b/doc/man-sections/generic-options.rst @@ -19,9 +19,6 @@ which mode OpenVPN is configured as. When using ``--auth-nocache`` in combination with a user/password file and ``--chroot`` or ``--daemon``, make sure to use an absolute path. - This directive does not affect the ``--http-proxy`` username/password. - It is always cached. - --cd dir Change directory to ``dir`` prior to reading any files such as configuration files, key files, scripts, etc. ``dir`` should be an diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 7e231ec56..103aa3c18 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -691,6 +691,8 @@ init_proxy_dowork(struct context *c) if (c->options.ce.http_proxy_options) { + c->options.ce.http_proxy_options->first_time = c->first_time; + /* Possible HTTP proxy user/pass input */ c->c1.http_proxy = http_proxy_new(c->options.ce.http_proxy_options); if (c->c1.http_proxy) diff --git a/src/openvpn/options.c b/src/openvpn/options.c index c0a2606e6..9d33dadcd 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -1653,6 +1653,7 @@ show_http_proxy_options(const struct http_proxy_options *o) SHOW_STR(auth_file); SHOW_STR(auth_file_up); SHOW_BOOL(inline_creds); + SHOW_BOOL(nocache); SHOW_STR(http_version); SHOW_STR(user_agent); for (i = 0; i < MAX_CUSTOM_HTTP_HEADER && o->custom_headers[i].name; i++) @@ -3156,6 +3157,11 @@ options_postprocess_mutate_ce(struct options *o, struct connection_entry *ce) ce->flags |= CE_DISABLED; } + if (ce->http_proxy_options) + { + ce->http_proxy_options->nocache = ssl_get_auth_nocache(); + } + /* our socks code is not fully IPv6 enabled yet (TCP works, UDP not) * so fall back to IPv4-only (trac #1221) */ diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c index f88a1f734..f6475fbe6 100644 --- a/src/openvpn/proxy.c +++ b/src/openvpn/proxy.c @@ -276,7 +276,7 @@ get_user_pass_http(struct http_proxy_info *p, const bool force) { auth_file = p->options.auth_file_up; } - if (p->queried_creds) + if (p->queried_creds && !static_proxy_user_pass.nocache) { flags |= GET_USER_PASS_PREVIOUS_CREDS_FAILED; } @@ -288,9 +288,14 @@ get_user_pass_http(struct http_proxy_info *p, const bool force) auth_file, UP_TYPE_PROXY, flags); - p->queried_creds = true; - p->up = static_proxy_user_pass; + static_proxy_user_pass.nocache = p->options.nocache; } + + /* + * Using cached credentials + */ + p->queried_creds = true; + p->up = static_proxy_user_pass; } #if 0 @@ -541,7 +546,7 @@ http_proxy_new(const struct http_proxy_options *o) /* only basic and NTLM/NTLMv2 authentication supported so far */ if (p->auth_method == HTTP_AUTH_BASIC || p->auth_method == HTTP_AUTH_NTLM || p->auth_method == HTTP_AUTH_NTLM2) { - get_user_pass_http(p, true); + get_user_pass_http(p, p->options.first_time); } #if !NTLM @@ -656,6 +661,11 @@ establish_http_proxy_passthru(struct http_proxy_info *p, || p->auth_method == HTTP_AUTH_NTLM) { get_user_pass_http(p, false); + + if (p->up.nocache) + { + clear_user_pass_http(); + } } /* are we being called again after getting the digest server nonce in the previous transaction? */ @@ -1031,13 +1041,6 @@ establish_http_proxy_passthru(struct http_proxy_info *p, } goto error; } - - /* clear state */ - if (p->options.auth_retry) - { - clear_user_pass_http(); - } - store_proxy_authenticate(p, NULL); } /* check return code, success = 200 */ diff --git a/src/openvpn/proxy.h b/src/openvpn/proxy.h index 04ab13ac7..3448e7d8d 100644 --- a/src/openvpn/proxy.h +++ b/src/openvpn/proxy.h @@ -57,6 +57,8 @@ struct http_proxy_options { const char *user_agent; struct http_custom_header custom_headers[MAX_CUSTOM_HTTP_HEADER]; bool inline_creds; /* auth_file_up is inline credentials */ + bool first_time; /* indicates if we need to wipe user creds at the first iteration of the main loop */ + bool nocache; }; struct http_proxy_options_simple { diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 162a8622d..e37ebc189 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -498,6 +498,15 @@ ssl_set_auth_nocache(void) auth_user_pass.nocache = true; } +/* + * Get the password caching + */ +bool +ssl_get_auth_nocache(void) +{ + return passbuf.nocache; +} + /* * Set an authentication token */ diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index 47a170f4e..1e15e2632 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -396,6 +396,11 @@ void auth_user_pass_setup(const char *auth_file, bool is_inline, */ void ssl_set_auth_nocache(void); +/* + * Getter method for retrieving the auth-nocache option. + */ +bool ssl_get_auth_nocache(void); + /* * Purge any stored authentication information, both for key files and tunnel * authentication. If PCKS #11 is enabled, purge authentication for that too.