Skip to content

Commit c1cfdf5

Browse files
committed
setopt: clear proxy auth properties when switching
Verify with test 1588 Closes #21453
1 parent 7586ca7 commit c1cfdf5

6 files changed

Lines changed: 275 additions & 2 deletions

File tree

lib/setopt.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "curlx/strdup.h"
5050
#include "escape.h"
5151
#include "bufref.h"
52+
#include "vauth/vauth.h"
5253

5354
static CURLcode setopt_set_timeout_sec(timediff_t *ptimeout_ms, long secs)
5455
{
@@ -1622,6 +1623,20 @@ static CURLcode cookiefile(struct Curl_easy *data, const char *ptr)
16221623
#endif
16231624

16241625
#ifndef CURL_DISABLE_PROXY
1626+
1627+
static CURLcode setproxy(struct Curl_easy *data, const char *proxy)
1628+
{
1629+
if((data->set.str[STRING_PROXY] && proxy) &&
1630+
/* there was one set, is this a new one? */
1631+
!strcmp(data->set.str[STRING_PROXY], proxy))
1632+
return CURLE_OK; /* same one as before */
1633+
1634+
Curl_auth_digest_cleanup(&data->state.proxydigest);
1635+
memset(&data->state.authproxy, 0, sizeof(data->state.authproxy));
1636+
return Curl_setstropt(&data->set.str[STRING_PROXY], proxy);
1637+
}
1638+
1639+
16251640
static CURLcode setopt_cptr_proxy(struct Curl_easy *data, CURLoption option,
16261641
const char *ptr)
16271642
{
@@ -1717,7 +1732,7 @@ static CURLcode setopt_cptr_proxy(struct Curl_easy *data, CURLoption option,
17171732
* Setting it to NULL, means no proxy but allows the environment variables
17181733
* to decide for us (if CURLOPT_PRE_PROXY setting it to NULL).
17191734
*/
1720-
return Curl_setstropt(&s->str[STRING_PROXY], ptr);
1735+
return setproxy(data, ptr);
17211736
case CURLOPT_PRE_PROXY:
17221737
/*
17231738
* Set proxy server:port to use as SOCKS proxy.

lib/vauth/vauth.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
117117
/* This is used to clean up the digest specific data */
118118
void Curl_auth_digest_cleanup(struct digestdata *digest);
119119
#else
120+
#define Curl_auth_digest_cleanup(x)
120121
#define Curl_auth_is_digest_supported() FALSE
121122
#endif /* !CURL_DISABLE_DIGEST_AUTH */
122123

tests/data/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ test1556 test1557 test1558 test1559 test1560 test1561 test1562 test1563 \
209209
test1564 test1565 test1566 test1567 test1568 test1569 test1570 test1571 \
210210
test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 \
211211
test1580 test1581 test1582 test1583 test1584 test1585 test1586 test1587 \
212+
test1588 \
212213
\
213214
test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 \
214215
test1598 test1599 test1600 test1601 test1602 test1603 test1604 test1605 \

tests/data/test1588

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?xml version="1.0" encoding="US-ASCII"?>
2+
<testcase>
3+
<info>
4+
<keywords>
5+
HTTP
6+
HTTP GET
7+
HTTP proxy
8+
HTTP proxy Digest auth
9+
multi
10+
</keywords>
11+
</info>
12+
13+
# Server-side
14+
<reply>
15+
16+
# this is returned first since we get no proxy-auth
17+
<data crlf="headers">
18+
HTTP/1.1 407 Authorization Required to proxy me my dear
19+
Proxy-Authenticate: Digest realm="weirdorealm", nonce="12345"
20+
Content-Length: 33
21+
22+
And you should ignore this data.
23+
</data>
24+
25+
# then this is returned when we get proxy-auth
26+
<data1000 crlf="headers">
27+
HTTP/1.1 200 OK
28+
Content-Length: 21
29+
Server: no
30+
31+
Nice proxy auth sir!
32+
</data1000>
33+
34+
<datacheck crlf="headers">
35+
HTTP/1.1 407 Authorization Required to proxy me my dear
36+
Proxy-Authenticate: Digest realm="weirdorealm", nonce="12345"
37+
Content-Length: 33
38+
39+
HTTP/1.1 200 OK
40+
Content-Length: 21
41+
Server: no
42+
43+
Nice proxy auth sir!
44+
HTTP/1.1 407 Authorization Required to proxy me my dear
45+
Proxy-Authenticate: Digest realm="weirdorealm", nonce="12345"
46+
Content-Length: 33
47+
48+
HTTP/1.1 200 OK
49+
Content-Length: 21
50+
Server: no
51+
52+
Nice proxy auth sir!
53+
</datacheck>
54+
</reply>
55+
56+
# Client-side
57+
<client>
58+
<server>
59+
http
60+
</server>
61+
# tool is what to use instead of 'curl'
62+
<tool>
63+
lib%TESTNUMBER
64+
</tool>
65+
<features>
66+
!SSPI
67+
crypto
68+
proxy
69+
digest
70+
</features>
71+
<name>
72+
HTTP proxy auth Digest, then change proxy and do it again
73+
</name>
74+
<command>
75+
http://test.remote.example.com/path/%TESTNUMBER %HOSTIP %HTTPPORT silly:person custom.set.host.name
76+
</command>
77+
</client>
78+
79+
# Verify data after the test has been "shot"
80+
<verify>
81+
<protocol crlf="headers">
82+
GET http://test.remote.example.com/path/1588 HTTP/1.1
83+
Host: test.remote.example.com
84+
Accept: */*
85+
Proxy-Connection: Keep-Alive
86+
87+
GET http://test.remote.example.com/path/1588 HTTP/1.1
88+
Host: test.remote.example.com
89+
Proxy-Authorization: Digest username="silly", realm="weirdorealm", nonce="12345", uri="/path/1588", response="d0b2f000c7e3fca24452b5810713404a"
90+
Accept: */*
91+
Proxy-Connection: Keep-Alive
92+
93+
GET http://test.remote.example.com/path/1588 HTTP/1.1
94+
Host: test.remote.example.com
95+
Accept: */*
96+
Proxy-Connection: Keep-Alive
97+
98+
GET http://test.remote.example.com/path/1588 HTTP/1.1
99+
Host: test.remote.example.com
100+
Proxy-Authorization: Digest username="silly", realm="weirdorealm", nonce="12345", uri="/path/1588", response="d0b2f000c7e3fca24452b5810713404a"
101+
Accept: */*
102+
Proxy-Connection: Keep-Alive
103+
104+
</protocol>
105+
</verify>
106+
</testcase>

tests/libtest/Makefile.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ TESTS_C = \
9696
lib1552.c lib1553.c lib1554.c lib1555.c lib1556.c lib1557.c lib1558.c \
9797
lib1559.c lib1560.c lib1564.c lib1565.c \
9898
lib1567.c lib1568.c lib1569.c lib1571.c \
99-
lib1576.c lib1582.c lib1587.c \
99+
lib1576.c lib1582.c lib1587.c lib1588.c \
100100
lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c \
101101
lib1598.c lib1599.c \
102102
lib1662.c \

tests/libtest/lib1588.c

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/***************************************************************************
2+
* _ _ ____ _
3+
* Project ___| | | | _ \| |
4+
* / __| | | | |_) | |
5+
* | (__| |_| | _ <| |___
6+
* \___|\___/|_| \_\_____|
7+
*
8+
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9+
*
10+
* This software is licensed as described in the file COPYING, which
11+
* you should have received as part of this distribution. The terms
12+
* are also available at https://curl.se/docs/copyright.html.
13+
*
14+
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
15+
* copies of the Software, and permit persons to whom the Software is
16+
* furnished to do so, under the terms of the COPYING file.
17+
*
18+
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19+
* KIND, either express or implied.
20+
*
21+
* SPDX-License-Identifier: curl
22+
*
23+
***************************************************************************/
24+
/*
25+
* argv1 = URL
26+
* argv2 = proxy host
27+
* argv3 = proxy port
28+
* argv4 = proxyuser:password
29+
*/
30+
31+
#include "first.h"
32+
33+
static CURLcode init1588(CURL *curl, const char *url,
34+
const char *userpwd, const char *proxy)
35+
{
36+
CURLcode result = CURLE_OK;
37+
38+
res_easy_setopt(curl, CURLOPT_URL, url);
39+
if(result)
40+
goto init_failed;
41+
42+
res_easy_setopt(curl, CURLOPT_PROXY, proxy);
43+
if(result)
44+
goto init_failed;
45+
46+
res_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userpwd);
47+
if(result)
48+
goto init_failed;
49+
50+
res_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
51+
if(result)
52+
goto init_failed;
53+
54+
res_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
55+
if(result)
56+
goto init_failed;
57+
#if 0
58+
res_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L);
59+
if(result)
60+
goto init_failed;
61+
#endif
62+
63+
res_easy_setopt(curl, CURLOPT_HEADER, 1L);
64+
if(result)
65+
goto init_failed;
66+
67+
return CURLE_OK; /* success */
68+
69+
init_failed:
70+
return result; /* failure */
71+
}
72+
73+
static CURLcode run1588(CURL *curl, const char *url, const char *userpwd,
74+
const char *proxy)
75+
{
76+
CURLcode result = CURLE_OK;
77+
78+
result = init1588(curl, url, userpwd, proxy);
79+
if(result)
80+
return result;
81+
82+
return curl_easy_perform(curl);
83+
}
84+
85+
static CURLcode test_lib1588(const char *URL)
86+
{
87+
CURLcode result = CURLE_OK;
88+
CURL *curl = NULL;
89+
const char *proxyuserpws = libtest_arg4;
90+
struct curl_slist *host = NULL;
91+
struct curl_slist *host2 = NULL;
92+
char proxy1_resolve[128];
93+
char proxy2_resolve[128];
94+
char proxy1_connect[128];
95+
char proxy2_connect[128];
96+
97+
if(test_argc < 3)
98+
return TEST_ERR_MAJOR_BAD;
99+
100+
curl_msnprintf(proxy1_resolve, sizeof(proxy1_resolve),
101+
"firstproxy:%s:%s", libtest_arg3, libtest_arg2);
102+
curl_msnprintf(proxy2_resolve, sizeof(proxy2_resolve),
103+
"secondproxy:%s:%s", libtest_arg3, libtest_arg2);
104+
105+
/* we connect to the fake host name but the right port number */
106+
curl_msnprintf(proxy1_connect, sizeof(proxy1_connect),
107+
"firstproxy:%s", libtest_arg3);
108+
curl_msnprintf(proxy2_connect, sizeof(proxy2_connect),
109+
"secondproxy:%s", libtest_arg3);
110+
111+
res_global_init(CURL_GLOBAL_ALL);
112+
if(result)
113+
return result;
114+
115+
curl = curl_easy_init();
116+
if(!curl) {
117+
curl_mfprintf(stderr, "curl_easy_init() failed\n");
118+
curl_global_cleanup();
119+
return TEST_ERR_MAJOR_BAD;
120+
}
121+
122+
host = curl_slist_append(NULL, proxy1_resolve);
123+
if(!host)
124+
goto test_cleanup;
125+
host2 = curl_slist_append(host, proxy2_resolve);
126+
if(!host2)
127+
goto test_cleanup;
128+
host = host2;
129+
130+
start_test_timing();
131+
132+
easy_setopt(curl, CURLOPT_RESOLVE, host);
133+
134+
result = run1588(curl, URL, proxyuserpws, proxy1_connect);
135+
if(result)
136+
goto test_cleanup;
137+
138+
curl_mfprintf(stderr, "lib1588: now we do the request again\n");
139+
140+
result = run1588(curl, URL, proxyuserpws, proxy2_connect);
141+
142+
test_cleanup:
143+
144+
/* proper cleanup sequence - type PB */
145+
146+
curl_easy_cleanup(curl);
147+
curl_global_cleanup();
148+
curl_slist_free_all(host);
149+
return result;
150+
}

0 commit comments

Comments
 (0)