mirror of
https://github.com/curl/curl.git
synced 2026-07-26 14:37:16 +03:00
digest: flush state on origin or credential change
Verified by test 1686 Closes #21944
This commit is contained in:
parent
3f1055303e
commit
5c6b488035
8 changed files with 203 additions and 4 deletions
|
|
@ -94,6 +94,22 @@ CURLcode Curl_output_digest(struct Curl_easy *data,
|
|||
#endif
|
||||
}
|
||||
else {
|
||||
bool flush = FALSE;
|
||||
DEBUGASSERT(data->conn->origin);
|
||||
if(data->state.digest.origin &&
|
||||
!Curl_peer_same_destination(data->conn->origin,
|
||||
data->state.digest.origin))
|
||||
flush = TRUE;
|
||||
else if(data->state.digest.creds &&
|
||||
!Curl_creds_same(data->state.creds, data->state.digest.creds))
|
||||
flush = TRUE;
|
||||
|
||||
if(flush)
|
||||
/* flush host Digest state */
|
||||
Curl_auth_digest_cleanup(&data->state.digest);
|
||||
|
||||
Curl_peer_link(&data->state.digest.origin, data->conn->origin);
|
||||
Curl_creds_link(&data->state.digest.creds, data->state.creds);
|
||||
digest = &data->state.digest;
|
||||
allocuserpwd = &data->req.hd_auth;
|
||||
creds = data->state.creds;
|
||||
|
|
|
|||
|
|
@ -148,13 +148,12 @@ typedef CURLcode (Curl_recv)(struct Curl_easy *data, /* transfer */
|
|||
#ifndef CURL_DISABLE_DIGEST_AUTH
|
||||
/* Struct used for Digest challenge-response authentication */
|
||||
struct digestdata {
|
||||
struct Curl_creds *creds;
|
||||
struct Curl_peer *origin;
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
BYTE *input_token;
|
||||
size_t input_token_len;
|
||||
CtxtHandle *http_context;
|
||||
/* linked credentials used to make the identity for http_context.
|
||||
may be NULL. */
|
||||
struct Curl_creds *creds;
|
||||
#else
|
||||
char *nonce;
|
||||
char *cnonce;
|
||||
|
|
|
|||
|
|
@ -1039,6 +1039,8 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
|||
*/
|
||||
void Curl_auth_digest_cleanup(struct digestdata *digest)
|
||||
{
|
||||
Curl_peer_unlink(&digest->origin);
|
||||
Curl_creds_unlink(&digest->creds);
|
||||
curlx_safefree(digest->nonce);
|
||||
curlx_safefree(digest->cnonce);
|
||||
curlx_safefree(digest->realm);
|
||||
|
|
|
|||
|
|
@ -630,6 +630,7 @@ void Curl_auth_digest_cleanup(struct digestdata *digest)
|
|||
|
||||
/* Free the copy of user/passwd used to make the identity for http_context */
|
||||
Curl_creds_unlink(&digest->creds);
|
||||
Curl_peer_unlink(&digest->origin);
|
||||
}
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI && !CURL_DISABLE_DIGEST_AUTH */
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ test1653 test1654 test1655 test1656 test1657 test1658 test1659 test1660 \
|
|||
test1661 test1662 test1663 test1664 test1665 test1666 test1667 test1668 \
|
||||
test1669 test1670 test1671 test1672 test1673 test1674 test1675 test1676 \
|
||||
test1677 test1680 test1681 test1682 test1683 test1684 \
|
||||
test1685 \
|
||||
test1685 test1686 \
|
||||
\
|
||||
test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 \
|
||||
test1708 test1709 test1710 test1711 test1712 test1713 test1714 test1715 \
|
||||
|
|
|
|||
84
tests/data/test1686
Normal file
84
tests/data/test1686
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
Digest
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
<reply>
|
||||
<data crlf="headers" nocheck="yes">
|
||||
HTTP/1.1 401 Authorization Required
|
||||
Server: Apache/1.3.27 (Darwin) PHP/4.1.2
|
||||
WWW-Authenticate: Digest realm="my-backyard", nonce="314156295"
|
||||
Content-Length: 26
|
||||
|
||||
This is not the real page
|
||||
</data>
|
||||
|
||||
# This is supposed to be returned when the server gets a
|
||||
# Authorization: Digest line passed-in from the client
|
||||
<data1000 crlf="headers">
|
||||
HTTP/1.1 200 OK
|
||||
Server: Apache/1.3.27 (Darwin) PHP/4.1.2
|
||||
Content-Type: text/html; charset=iso-8859-1
|
||||
Content-Length: 23
|
||||
|
||||
This IS the real page!
|
||||
</data1000>
|
||||
|
||||
</reply>
|
||||
|
||||
<client>
|
||||
<features>
|
||||
!SSPI
|
||||
crypto
|
||||
digest
|
||||
</features>
|
||||
<server>
|
||||
http
|
||||
</server>
|
||||
<name>
|
||||
HTTP Digest to different origins and switching credentials
|
||||
</name>
|
||||
<tool>
|
||||
lib%TESTNUMBER
|
||||
</tool>
|
||||
<command>
|
||||
%HOSTIP %HTTPPORT
|
||||
</command>
|
||||
</client>
|
||||
|
||||
<verify>
|
||||
<protocol crlf="headers">
|
||||
GET /api HTTP/1.1
|
||||
Host: first.test:%HTTPPORT
|
||||
Accept: */*
|
||||
|
||||
GET /api HTTP/1.1
|
||||
Host: first.test:%HTTPPORT
|
||||
Authorization: Digest username="alice", realm="my-backyard", nonce="314156295", uri="/api", response="4ecc00e567c37a9d537727890c2e5b32"
|
||||
Accept: */*
|
||||
|
||||
GET /hook HTTP/1.1
|
||||
Host: second.test:%HTTPPORT
|
||||
Accept: */*
|
||||
|
||||
GET /hook HTTP/1.1
|
||||
Host: second.test:%HTTPPORT
|
||||
Authorization: Digest username="alice", realm="my-backyard", nonce="314156295", uri="/hook", response="d3a7738fb6a23f5543fb8dacc0f0f253"
|
||||
Accept: */*
|
||||
|
||||
GET /hook HTTP/1.1
|
||||
Host: second.test:%HTTPPORT
|
||||
Accept: */*
|
||||
|
||||
GET /hook HTTP/1.1
|
||||
Host: second.test:%HTTPPORT
|
||||
Authorization: Digest username="bob", realm="my-backyard", nonce="314156295", uri="/hook", response="777e68eddb77294d9cbd6134973cbbab"
|
||||
Accept: */*
|
||||
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
||||
|
|
@ -101,6 +101,7 @@ TESTS_C = \
|
|||
lib1598.c lib1599.c \
|
||||
lib1647.c lib1648.c lib1649.c \
|
||||
lib1662.c \
|
||||
lib1686.c \
|
||||
lib1900.c lib1901.c lib1902.c lib1903.c lib1905.c lib1906.c lib1907.c \
|
||||
lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c \
|
||||
lib1915.c lib1916.c lib1918.c lib1919.c lib1920.c lib1921.c \
|
||||
|
|
|
|||
96
tests/libtest/lib1686.c
Normal file
96
tests/libtest/lib1686.c
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "first.h"
|
||||
|
||||
static size_t devnull_1686(char *p, size_t s, size_t n, void *u)
|
||||
{
|
||||
(void)p;
|
||||
(void)u;
|
||||
return s * n;
|
||||
}
|
||||
|
||||
#define FIRSTHOST "first.test"
|
||||
#define SECONDHOST "second.test"
|
||||
|
||||
static CURLcode test_lib1686(const char *hostip)
|
||||
{
|
||||
CURL *curl = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
const char *httpport = libtest_arg2;
|
||||
char firsturl[100];
|
||||
char secondurl[100];
|
||||
char firstres[100];
|
||||
char secondres[100];
|
||||
struct curl_slist *host = NULL;
|
||||
struct curl_slist *host2 = NULL;
|
||||
|
||||
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
curl_mfprintf(stderr, "curl_global_init() failed\n");
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
/* create strings for CURLOPT_RESOLVE */
|
||||
curl_msnprintf(firstres, sizeof(firstres), "%s:%s:%s",
|
||||
FIRSTHOST, httpport, hostip);
|
||||
curl_msnprintf(secondres, sizeof(secondres), "%s:%s:%s",
|
||||
SECONDHOST, httpport, hostip);
|
||||
|
||||
/* create URLs */
|
||||
curl_msnprintf(firsturl, sizeof(firsturl), "http://%s:%s/api",
|
||||
FIRSTHOST, httpport);
|
||||
curl_msnprintf(secondurl, sizeof(secondurl), "http://%s:%s/hook",
|
||||
SECONDHOST, httpport);
|
||||
|
||||
host = curl_slist_append(NULL, firstres);
|
||||
if(!host)
|
||||
goto test_cleanup;
|
||||
host2 = curl_slist_append(host, secondres);
|
||||
if(!host2)
|
||||
goto test_cleanup;
|
||||
host = host2;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
easy_setopt(curl, CURLOPT_RESOLVE, host);
|
||||
easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
|
||||
easy_setopt(curl, CURLOPT_USERPWD, "alice:bond");
|
||||
easy_setopt(curl, CURLOPT_WRITEFUNCTION, devnull_1686);
|
||||
|
||||
easy_setopt(curl, CURLOPT_URL, firsturl);
|
||||
result = curl_easy_perform(curl);
|
||||
|
||||
easy_setopt(curl, CURLOPT_URL, secondurl);
|
||||
result = curl_easy_perform(curl);
|
||||
|
||||
easy_setopt(curl, CURLOPT_USERPWD, "bob:secret");
|
||||
easy_setopt(curl, CURLOPT_URL, secondurl);
|
||||
result = curl_easy_perform(curl);
|
||||
}
|
||||
|
||||
test_cleanup:
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
curl_slist_free_all(host);
|
||||
return result;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue