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 <gianmarco@mandelbit.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Change-Id: Ia3e06c0832c4ca0ab868c845279fb71c01a1a78a
Acked-by: Frank Lichtenheld <frank@lichtenheld.com>
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 <gert@greenie.muc.de>
(cherry picked from commit 3cfd6f961d5c92bec283ac3616e1633b4e16760c)
| ... | ... |
@@ -19,9 +19,6 @@ which mode OpenVPN is configured as. |
| 19 | 19 |
When using ``--auth-nocache`` in combination with a user/password file |
| 20 | 20 |
and ``--chroot`` or ``--daemon``, make sure to use an absolute path. |
| 21 | 21 |
|
| 22 |
- This directive does not affect the ``--http-proxy`` username/password. |
|
| 23 |
- It is always cached. |
|
| 24 |
- |
|
| 25 | 22 |
--cd dir |
| 26 | 23 |
Change directory to ``dir`` prior to reading any files such as |
| 27 | 24 |
configuration files, key files, scripts, etc. ``dir`` should be an |
| ... | ... |
@@ -691,6 +691,8 @@ init_proxy_dowork(struct context *c) |
| 691 | 691 |
|
| 692 | 692 |
if (c->options.ce.http_proxy_options) |
| 693 | 693 |
{
|
| 694 |
+ c->options.ce.http_proxy_options->first_time = c->first_time; |
|
| 695 |
+ |
|
| 694 | 696 |
/* Possible HTTP proxy user/pass input */ |
| 695 | 697 |
c->c1.http_proxy = http_proxy_new(c->options.ce.http_proxy_options); |
| 696 | 698 |
if (c->c1.http_proxy) |
| ... | ... |
@@ -1653,6 +1653,7 @@ show_http_proxy_options(const struct http_proxy_options *o) |
| 1653 | 1653 |
SHOW_STR(auth_file); |
| 1654 | 1654 |
SHOW_STR(auth_file_up); |
| 1655 | 1655 |
SHOW_BOOL(inline_creds); |
| 1656 |
+ SHOW_BOOL(nocache); |
|
| 1656 | 1657 |
SHOW_STR(http_version); |
| 1657 | 1658 |
SHOW_STR(user_agent); |
| 1658 | 1659 |
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) |
| 3156 | 3156 |
ce->flags |= CE_DISABLED; |
| 3157 | 3157 |
} |
| 3158 | 3158 |
|
| 3159 |
+ if (ce->http_proxy_options) |
|
| 3160 |
+ {
|
|
| 3161 |
+ ce->http_proxy_options->nocache = ssl_get_auth_nocache(); |
|
| 3162 |
+ } |
|
| 3163 |
+ |
|
| 3159 | 3164 |
/* our socks code is not fully IPv6 enabled yet (TCP works, UDP not) |
| 3160 | 3165 |
* so fall back to IPv4-only (trac #1221) |
| 3161 | 3166 |
*/ |
| ... | ... |
@@ -276,7 +276,7 @@ get_user_pass_http(struct http_proxy_info *p, const bool force) |
| 276 | 276 |
{
|
| 277 | 277 |
auth_file = p->options.auth_file_up; |
| 278 | 278 |
} |
| 279 |
- if (p->queried_creds) |
|
| 279 |
+ if (p->queried_creds && !static_proxy_user_pass.nocache) |
|
| 280 | 280 |
{
|
| 281 | 281 |
flags |= GET_USER_PASS_PREVIOUS_CREDS_FAILED; |
| 282 | 282 |
} |
| ... | ... |
@@ -288,9 +288,14 @@ get_user_pass_http(struct http_proxy_info *p, const bool force) |
| 288 | 288 |
auth_file, |
| 289 | 289 |
UP_TYPE_PROXY, |
| 290 | 290 |
flags); |
| 291 |
- p->queried_creds = true; |
|
| 292 |
- p->up = static_proxy_user_pass; |
|
| 291 |
+ static_proxy_user_pass.nocache = p->options.nocache; |
|
| 293 | 292 |
} |
| 293 |
+ |
|
| 294 |
+ /* |
|
| 295 |
+ * Using cached credentials |
|
| 296 |
+ */ |
|
| 297 |
+ p->queried_creds = true; |
|
| 298 |
+ p->up = static_proxy_user_pass; |
|
| 294 | 299 |
} |
| 295 | 300 |
|
| 296 | 301 |
#if 0 |
| ... | ... |
@@ -541,7 +546,7 @@ http_proxy_new(const struct http_proxy_options *o) |
| 541 | 541 |
/* only basic and NTLM/NTLMv2 authentication supported so far */ |
| 542 | 542 |
if (p->auth_method == HTTP_AUTH_BASIC || p->auth_method == HTTP_AUTH_NTLM || p->auth_method == HTTP_AUTH_NTLM2) |
| 543 | 543 |
{
|
| 544 |
- get_user_pass_http(p, true); |
|
| 544 |
+ get_user_pass_http(p, p->options.first_time); |
|
| 545 | 545 |
} |
| 546 | 546 |
|
| 547 | 547 |
#if !NTLM |
| ... | ... |
@@ -656,6 +661,11 @@ establish_http_proxy_passthru(struct http_proxy_info *p, |
| 656 | 656 |
|| p->auth_method == HTTP_AUTH_NTLM) |
| 657 | 657 |
{
|
| 658 | 658 |
get_user_pass_http(p, false); |
| 659 |
+ |
|
| 660 |
+ if (p->up.nocache) |
|
| 661 |
+ {
|
|
| 662 |
+ clear_user_pass_http(); |
|
| 663 |
+ } |
|
| 659 | 664 |
} |
| 660 | 665 |
|
| 661 | 666 |
/* 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, |
| 1031 | 1031 |
} |
| 1032 | 1032 |
goto error; |
| 1033 | 1033 |
} |
| 1034 |
- |
|
| 1035 |
- /* clear state */ |
|
| 1036 |
- if (p->options.auth_retry) |
|
| 1037 |
- {
|
|
| 1038 |
- clear_user_pass_http(); |
|
| 1039 |
- } |
|
| 1040 |
- store_proxy_authenticate(p, NULL); |
|
| 1041 | 1034 |
} |
| 1042 | 1035 |
|
| 1043 | 1036 |
/* check return code, success = 200 */ |
| ... | ... |
@@ -57,6 +57,8 @@ struct http_proxy_options {
|
| 57 | 57 |
const char *user_agent; |
| 58 | 58 |
struct http_custom_header custom_headers[MAX_CUSTOM_HTTP_HEADER]; |
| 59 | 59 |
bool inline_creds; /* auth_file_up is inline credentials */ |
| 60 |
+ bool first_time; /* indicates if we need to wipe user creds at the first iteration of the main loop */ |
|
| 61 |
+ bool nocache; |
|
| 60 | 62 |
}; |
| 61 | 63 |
|
| 62 | 64 |
struct http_proxy_options_simple {
|
| ... | ... |
@@ -397,6 +397,11 @@ void auth_user_pass_setup(const char *auth_file, bool is_inline, |
| 397 | 397 |
void ssl_set_auth_nocache(void); |
| 398 | 398 |
|
| 399 | 399 |
/* |
| 400 |
+ * Getter method for retrieving the auth-nocache option. |
|
| 401 |
+ */ |
|
| 402 |
+bool ssl_get_auth_nocache(void); |
|
| 403 |
+ |
|
| 404 |
+/* |
|
| 400 | 405 |
* Purge any stored authentication information, both for key files and tunnel |
| 401 | 406 |
* authentication. If PCKS #11 is enabled, purge authentication for that too. |
| 402 | 407 |
* Note that auth_token is not cleared. |