Compare commits
No commits in common. "c8" and "c8-beta" have entirely different histories.
@ -41,7 +41,7 @@ index e827dc58f378c..d061c6356f97f 100644
|
|||||||
/*
|
/*
|
||||||
* Match a hostname against a wildcard pattern.
|
* Match a hostname against a wildcard pattern.
|
||||||
* E.g.
|
* E.g.
|
||||||
@@ -65,26 +76,31 @@
|
@@ -65,26 +76,27 @@
|
||||||
|
|
||||||
static int hostmatch(char *hostname, char *pattern)
|
static int hostmatch(char *hostname, char *pattern)
|
||||||
{
|
{
|
||||||
@ -73,14 +73,10 @@ index e827dc58f378c..d061c6356f97f 100644
|
|||||||
- if(pattern_wildcard == NULL)
|
- if(pattern_wildcard == NULL)
|
||||||
- return strcasecompare(pattern, hostname) ?
|
- return strcasecompare(pattern, hostname) ?
|
||||||
- CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
- CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||||
+ if(hostname[hostlen-1]=='.') {
|
+ if(hostname[hostlen-1]=='.')
|
||||||
+ hostname[hostlen-1] = 0;
|
+ hostname[hostlen-1] = 0;
|
||||||
+ hostlen--;
|
+ if(pattern[patternlen-1]=='.')
|
||||||
+ }
|
|
||||||
+ if(pattern[patternlen-1]=='.') {
|
|
||||||
+ pattern[patternlen-1] = 0;
|
+ pattern[patternlen-1] = 0;
|
||||||
+ patternlen--;
|
|
||||||
+ }
|
|
||||||
+
|
+
|
||||||
+ if(strncmp(pattern, "*.", 2))
|
+ if(strncmp(pattern, "*.", 2))
|
||||||
+ return pmatch(hostname, hostlen, pattern, patternlen);
|
+ return pmatch(hostname, hostlen, pattern, patternlen);
|
||||||
@ -174,7 +170,7 @@ index 2f3d3aa4d09e1..3ae75618d5d10 100644
|
|||||||
static CURLcode unit_setup(void)
|
static CURLcode unit_setup(void)
|
||||||
{
|
{
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@@ -30,50 +28,91 @@ static CURLcode unit_setup(void)
|
@@ -30,50 +28,93 @@ static CURLcode unit_setup(void)
|
||||||
|
|
||||||
static void unit_stop(void)
|
static void unit_stop(void)
|
||||||
{
|
{
|
||||||
@ -285,7 +281,9 @@ index 2f3d3aa4d09e1..3ae75618d5d10 100644
|
|||||||
+ int i;
|
+ int i;
|
||||||
+ for(i = 0; tests[i].host; i++) {
|
+ for(i = 0; tests[i].host; i++) {
|
||||||
+ if(tests[i].match != Curl_cert_hostcheck(tests[i].pattern,
|
+ if(tests[i].match != Curl_cert_hostcheck(tests[i].pattern,
|
||||||
+ tests[i].host)) {
|
+ strlen(tests[i].pattern),
|
||||||
|
+ tests[i].host,
|
||||||
|
+ strlen(tests[i].host))) {
|
||||||
+ fprintf(stderr,
|
+ fprintf(stderr,
|
||||||
+ "HOST: %s\n"
|
+ "HOST: %s\n"
|
||||||
+ "PTRN: %s\n"
|
+ "PTRN: %s\n"
|
||||||
|
|||||||
@ -153,7 +153,7 @@ index 7ebe61321419f..1cecb649cb623 100644
|
|||||||
if(rc == SSH_OK) {
|
if(rc == SSH_OK) {
|
||||||
sshc->authed = TRUE;
|
sshc->authed = TRUE;
|
||||||
infof(data, "completed keyboard interactive authentication\n");
|
infof(data, "completed keyboard interactive authentication\n");
|
||||||
+ state(conn, SSH_AUTH_DONE);
|
+ state(data, SSH_AUTH_DONE);
|
||||||
+ }
|
+ }
|
||||||
+ else {
|
+ else {
|
||||||
+ MOVE_TO_PASSWD_AUTH;
|
+ MOVE_TO_PASSWD_AUTH;
|
||||||
|
|||||||
@ -1,80 +0,0 @@
|
|||||||
From deca8039991886a559b67bcd6701db800a5cf764 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stefan Eissing <stefan@eissing.org>
|
|
||||||
Date: Wed, 6 Mar 2024 09:36:08 +0100
|
|
||||||
Subject: [PATCH] http2: push headers better cleanup
|
|
||||||
|
|
||||||
- provide common cleanup method for push headers
|
|
||||||
|
|
||||||
Closes #13054
|
|
||||||
---
|
|
||||||
lib/http2.c | 34 +++++++++++++++-------------------
|
|
||||||
1 file changed, 15 insertions(+), 19 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/http2.c b/lib/http2.c
|
|
||||||
index c63ecd38371ab4..96868728a53a1f 100644
|
|
||||||
--- a/lib/http2.c
|
|
||||||
+++ b/lib/http2.c
|
|
||||||
@@ -271,6 +271,15 @@ static CURLcode http2_data_setup(struct Curl_cfilter *cf,
|
|
||||||
return http2_perform_getsock(conn, sock, numsocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void free_push_headers(struct HTTP *http)
|
|
||||||
+{
|
|
||||||
+ size_t i;
|
|
||||||
+ for(i = 0; i<http->push_headers_used; i++)
|
|
||||||
+ free(http->push_headers[i]);
|
|
||||||
+ Curl_safefree(http->push_headers);
|
|
||||||
+ http->push_headers_used = 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* http2_stream_free() free HTTP2 stream related data
|
|
||||||
*/
|
|
||||||
@@ -306,11 +315,7 @@ static void http2_data_done(struct Curl_cfilter *cf,
|
|
||||||
http->header_recvbuf = NULL; /* clear the pointer */
|
|
||||||
Curl_add_buffer_free(http->trailer_recvbuf);
|
|
||||||
http->trailer_recvbuf = NULL; /* clear the pointer */
|
|
||||||
- for(; http->push_headers_used > 0; --http->push_headers_used) {
|
|
||||||
- free(http->push_headers[http->push_headers_used - 1]);
|
|
||||||
- }
|
|
||||||
- free(http->push_headers);
|
|
||||||
- http->push_headers = NULL;
|
|
||||||
+ free_push_headers(http);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -860,7 +861,6 @@ static int push_promise(struct Curl_cfilter *cf,
|
|
||||||
struct curl_pushheaders heads;
|
|
||||||
CURLMcode rc;
|
|
||||||
struct http_conn *httpc;
|
|
||||||
- size_t i;
|
|
||||||
/* clone the parent */
|
|
||||||
struct Curl_easy *newhandle = duphandle(data);
|
|
||||||
if(!newhandle) {
|
|
||||||
@@ -904,11 +904,7 @@ static int push_promise(struct Curl_cfilter *cf,
|
|
||||||
Curl_set_in_callback(data, false);
|
|
||||||
|
|
||||||
/* free the headers again */
|
|
||||||
- for(i = 0; i<stream->push_headers_used; i++)
|
|
||||||
- free(stream->push_headers[i]);
|
|
||||||
- free(stream->push_headers);
|
|
||||||
- stream->push_headers = NULL;
|
|
||||||
- stream->push_headers_used = 0;
|
|
||||||
+ free_push_headers(stream);
|
|
||||||
|
|
||||||
if(rv) {
|
|
||||||
/* denied, kill off the new handle again */
|
|
||||||
@@ -1426,10 +1422,10 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
|
||||||
stream->push_headers_alloc) {
|
|
||||||
char **headp;
|
|
||||||
stream->push_headers_alloc *= 2;
|
|
||||||
- headp = Curl_saferealloc(stream->push_headers,
|
|
||||||
- stream->push_headers_alloc * sizeof(char *));
|
|
||||||
+ headp = realloc(stream->push_headers,
|
|
||||||
+ stream->push_headers_alloc * sizeof(char *));
|
|
||||||
if(!headp) {
|
|
||||||
- stream->push_headers = NULL;
|
|
||||||
+ free_push_headers(stream);
|
|
||||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
|
||||||
}
|
|
||||||
stream->push_headers = headp;
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
From eb9a604f8d7db859555adc0ddacdabd1ed986106 Mon Sep 17 00:00:00 2001
|
|
||||||
From: amkatyal <amkatyal@cisco.com>
|
|
||||||
Date: Fri, 26 Jul 2019 21:28:41 +0530
|
|
||||||
Subject: [PATCH] asyn-thread: create a socketpair to wait on
|
|
||||||
|
|
||||||
Closes #4157
|
|
||||||
---
|
|
||||||
lib/asyn-thread.c | 76 ++++++++++++++++++++++++++++++++++++++++-------
|
|
||||||
lib/multi.c | 0
|
|
||||||
2 files changed, 65 insertions(+), 11 deletions(-)
|
|
||||||
mode change 100644 => 100755 lib/asyn-thread.c
|
|
||||||
mode change 100644 => 100755 lib/multi.c
|
|
||||||
|
|
||||||
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
|
|
||||||
old mode 100644
|
|
||||||
new mode 100755
|
|
||||||
index 5f33c9affd0f27..f17638e44e6b18
|
|
||||||
--- a/lib/asyn-thread.c
|
|
||||||
+++ b/lib/asyn-thread.c
|
|
||||||
@@ -163,6 +163,9 @@ struct thread_sync_data {
|
|
||||||
char *hostname; /* hostname to resolve, Curl_async.hostname
|
|
||||||
duplicate */
|
|
||||||
int port;
|
|
||||||
+#ifdef HAVE_SOCKETPAIR
|
|
||||||
+ curl_socket_t sock_pair[2]; /* socket pair */
|
|
||||||
+#endif
|
|
||||||
int sock_error;
|
|
||||||
Curl_addrinfo *res;
|
|
||||||
#ifdef HAVE_GETADDRINFO
|
|
||||||
@@ -197,6 +200,16 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
|
||||||
if(tsd->res)
|
|
||||||
Curl_freeaddrinfo(tsd->res);
|
|
||||||
|
|
||||||
+#ifdef HAVE_SOCKETPAIR
|
|
||||||
+ /* close socket pair */
|
|
||||||
+ if(tsd->sock_pair[0] != CURL_SOCKET_BAD) {
|
|
||||||
+ sclose(tsd->sock_pair[0]);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
|
|
||||||
+ sclose(tsd->sock_pair[1]);
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
memset(tsd, 0, sizeof(*tsd));
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -230,6 +243,14 @@ int init_thread_sync_data(struct thread_data * td,
|
|
||||||
|
|
||||||
Curl_mutex_init(tsd->mtx);
|
|
||||||
|
|
||||||
+#ifdef HAVE_SOCKETPAIR
|
|
||||||
+ /* create socket pair */
|
|
||||||
+ if(socketpair(AF_LOCAL, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) {
|
|
||||||
+ tsd->sock_pair[0] = CURL_SOCKET_BAD;
|
|
||||||
+ tsd->sock_pair[1] = CURL_SOCKET_BAD;
|
|
||||||
+ goto err_exit;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
tsd->sock_error = CURL_ASYNC_SUCCESS;
|
|
||||||
|
|
||||||
/* Copying hostname string because original can be destroyed by parent
|
|
||||||
@@ -297,6 +318,9 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
|
|
||||||
struct thread_data *td = tsd->td;
|
|
||||||
char service[12];
|
|
||||||
int rc;
|
|
||||||
+#ifdef HAVE_SOCKETPAIR
|
|
||||||
+ char buf[1];
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
snprintf(service, sizeof(service), "%d", tsd->port);
|
|
||||||
|
|
||||||
@@ -298,6 +322,16 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
|
|
||||||
free(td);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
+#ifdef HAVE_SOCKETPAIR
|
|
||||||
+ if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
|
|
||||||
+ /* DNS has been resolved, signal client task */
|
|
||||||
+ buf[0] = 1;
|
|
||||||
+ if(write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) {
|
|
||||||
+ /* update sock_erro to errno */
|
|
||||||
+ tsd->sock_error = SOCKERRNO;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
tsd->done = 1;
|
|
||||||
Curl_mutex_release(tsd->mtx);
|
|
||||||
}
|
|
||||||
@@ -595,23 +629,43 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
|
||||||
curl_socket_t *socks,
|
|
||||||
int numsocks)
|
|
||||||
{
|
|
||||||
+ int ret_val = 0;
|
|
||||||
time_t milli;
|
|
||||||
timediff_t ms;
|
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
struct resdata *reslv = (struct resdata *)data->state.resolver;
|
|
||||||
+#ifdef HAVE_SOCKETPAIR
|
|
||||||
+ struct thread_data *td = (struct thread_data*)conn->async.os_specific;
|
|
||||||
+ int loop_idx;
|
|
||||||
+#else
|
|
||||||
(void)socks;
|
|
||||||
(void)numsocks;
|
|
||||||
- ms = Curl_timediff(Curl_now(), reslv->start);
|
|
||||||
- if(ms < 3)
|
|
||||||
- milli = 0;
|
|
||||||
- else if(ms <= 50)
|
|
||||||
- milli = ms/3;
|
|
||||||
- else if(ms <= 250)
|
|
||||||
- milli = 50;
|
|
||||||
- else
|
|
||||||
- milli = 200;
|
|
||||||
- Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
|
|
||||||
- return 0;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#ifdef HAVE_SOCKETPAIR
|
|
||||||
+ if(td) {
|
|
||||||
+ /* return read fd to client for polling the DNS resolution status */
|
|
||||||
+ socks[0] = td->tsd.sock_pair[0];
|
|
||||||
+ ret_val = GETSOCK_READSOCK(0);
|
|
||||||
+ }
|
|
||||||
+ else {
|
|
||||||
+#endif
|
|
||||||
+ ms = Curl_timediff(Curl_now(), reslv->start);
|
|
||||||
+ if(ms < 3)
|
|
||||||
+ milli = 0;
|
|
||||||
+ else if(ms <= 50)
|
|
||||||
+ milli = ms/3;
|
|
||||||
+ else if(ms <= 250)
|
|
||||||
+ milli = 50;
|
|
||||||
+ else
|
|
||||||
+ milli = 200;
|
|
||||||
+ Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
|
|
||||||
+#ifdef HAVE_SOCKETPAIR
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ return ret_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef HAVE_GETADDRINFO
|
|
||||||
diff --git a/lib/multi.c b/lib/multi.c
|
|
||||||
old mode 100644
|
|
||||||
new mode 100755
|
|
||||||
@ -1,279 +0,0 @@
|
|||||||
diff -up curl-7.61.1/lib/curl_md5.h.RHEL-32335 curl-7.61.1/lib/curl_md5.h
|
|
||||||
--- curl-7.61.1/lib/curl_md5.h.RHEL-32335 2024-04-10 10:09:36.758098940 +0200
|
|
||||||
+++ curl-7.61.1/lib/curl_md5.h 2024-04-10 10:10:22.426370509 +0200
|
|
||||||
@@ -49,8 +49,8 @@ typedef struct {
|
|
||||||
extern const MD5_params Curl_DIGEST_MD5[1];
|
|
||||||
extern const HMAC_params Curl_HMAC_MD5[1];
|
|
||||||
|
|
||||||
-void Curl_md5it(unsigned char *output,
|
|
||||||
- const unsigned char *input);
|
|
||||||
+void Curl_md5it(unsigned char *output, const unsigned char *input,
|
|
||||||
+ const size_t len);
|
|
||||||
|
|
||||||
MD5_context * Curl_MD5_init(const MD5_params *md5params);
|
|
||||||
int Curl_MD5_update(MD5_context *context,
|
|
||||||
diff -up curl-7.61.1/lib/curl_ntlm_core.h.RHEL-32335 curl-7.61.1/lib/curl_ntlm_core.h
|
|
||||||
--- curl-7.61.1/lib/curl_ntlm_core.h.RHEL-32335 2024-04-10 09:52:39.872042425 +0200
|
|
||||||
+++ curl-7.61.1/lib/curl_ntlm_core.h 2024-04-10 09:54:46.230795176 +0200
|
|
||||||
@@ -48,9 +48,9 @@
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define USE_NTLM2SESSION in order to make the type-3 message include the
|
|
||||||
- NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
|
|
||||||
- Crypto engine that we have curl_ssl_md5sum() for. */
|
|
||||||
-#if defined(USE_NTRESPONSES) && !defined(USE_WIN32_CRYPTO)
|
|
||||||
+ NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and
|
|
||||||
+ MD5 support */
|
|
||||||
+#if defined(USE_NTRESPONSES) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
|
||||||
#define USE_NTLM2SESSION
|
|
||||||
#endif
|
|
||||||
|
|
||||||
diff -up curl-7.61.1/lib/curl_sha256.h.RHEL-32335 curl-7.61.1/lib/curl_sha256.h
|
|
||||||
--- curl-7.61.1/lib/curl_sha256.h.RHEL-32335 2024-04-10 10:13:40.975551190 +0200
|
|
||||||
+++ curl-7.61.1/lib/curl_sha256.h 2024-04-10 10:14:00.251665815 +0200
|
|
||||||
@@ -24,8 +24,8 @@
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
|
||||||
|
|
||||||
-void Curl_sha256it(unsigned char *outbuffer,
|
|
||||||
- const unsigned char *input);
|
|
||||||
+void Curl_sha256it(unsigned char *outbuffer, const unsigned char *input,
|
|
||||||
+ const size_t len);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
diff -up curl-7.61.1/lib/md5.c.RHEL-32335 curl-7.61.1/lib/md5.c
|
|
||||||
--- curl-7.61.1/lib/md5.c.RHEL-32335 2024-04-10 10:10:39.831474009 +0200
|
|
||||||
+++ curl-7.61.1/lib/md5.c 2024-04-10 10:13:29.963485706 +0200
|
|
||||||
@@ -519,12 +519,13 @@ const MD5_params Curl_DIGEST_MD5[] = {
|
|
||||||
/*
|
|
||||||
* @unittest: 1601
|
|
||||||
*/
|
|
||||||
-void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
|
|
||||||
- const unsigned char *input)
|
|
||||||
+void Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
|
|
||||||
+ const size_t len)
|
|
||||||
{
|
|
||||||
MD5_CTX ctx;
|
|
||||||
+
|
|
||||||
MD5_Init(&ctx);
|
|
||||||
- MD5_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
|
|
||||||
+ MD5_Update(&ctx, input, curlx_uztoui(len));
|
|
||||||
MD5_Final(outbuffer, &ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff -up curl-7.61.1/lib/sha256.c.RHEL-32335 curl-7.61.1/lib/sha256.c
|
|
||||||
--- curl-7.61.1/lib/sha256.c.RHEL-32335 2024-04-10 10:14:32.047854892 +0200
|
|
||||||
+++ curl-7.61.1/lib/sha256.c 2024-04-10 10:15:23.010157942 +0200
|
|
||||||
@@ -255,12 +255,13 @@ static int SHA256_Final(unsigned char *o
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-void Curl_sha256it(unsigned char *outbuffer, /* 32 unsigned chars */
|
|
||||||
- const unsigned char *input)
|
|
||||||
+void Curl_sha256it(unsigned char *outbuffer, const unsigned char *input,
|
|
||||||
+ const size_t len)
|
|
||||||
{
|
|
||||||
SHA256_CTX ctx;
|
|
||||||
+
|
|
||||||
SHA256_Init(&ctx);
|
|
||||||
- SHA256_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
|
|
||||||
+ SHA256_Update(&ctx, input, curlx_uztoui(len));
|
|
||||||
SHA256_Final(outbuffer, &ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff -up curl-7.61.1/lib/vauth/digest.c.RHEL-32335 curl-7.61.1/lib/vauth/digest.c
|
|
||||||
--- curl-7.61.1/lib/vauth/digest.c.RHEL-32335 2024-04-10 10:15:31.737209838 +0200
|
|
||||||
+++ curl-7.61.1/lib/vauth/digest.c 2024-04-10 10:20:11.293872233 +0200
|
|
||||||
@@ -62,7 +62,7 @@
|
|
||||||
what ultimately goes over the network.
|
|
||||||
*/
|
|
||||||
#define CURL_OUTPUT_DIGEST_CONV(a, b) \
|
|
||||||
- result = Curl_convert_to_network(a, (char *)b, strlen((const char *)b)); \
|
|
||||||
+ result = Curl_convert_to_network(a, b, strlen(b)); \
|
|
||||||
if(result) { \
|
|
||||||
free(b); \
|
|
||||||
return result; \
|
|
||||||
@@ -687,12 +687,12 @@ static CURLcode _Curl_auth_create_digest
|
|
||||||
struct digestdata *digest,
|
|
||||||
char **outptr, size_t *outlen,
|
|
||||||
void (*convert_to_ascii)(unsigned char *, unsigned char *),
|
|
||||||
- void (*hash)(unsigned char *, const unsigned char *))
|
|
||||||
+ void (*hash)(unsigned char *, const unsigned char *,
|
|
||||||
+ const size_t))
|
|
||||||
{
|
|
||||||
CURLcode result;
|
|
||||||
unsigned char hashbuf[32]; /* 32 bytes/256 bits */
|
|
||||||
unsigned char request_digest[65];
|
|
||||||
- unsigned char *hashthis;
|
|
||||||
unsigned char ha1[65]; /* 64 digits and 1 zero byte */
|
|
||||||
unsigned char ha2[65]; /* 64 digits and 1 zero byte */
|
|
||||||
char userh[65];
|
|
||||||
@@ -700,6 +700,7 @@ static CURLcode _Curl_auth_create_digest
|
|
||||||
size_t cnonce_sz = 0;
|
|
||||||
char *userp_quoted;
|
|
||||||
char *response = NULL;
|
|
||||||
+ char *hashthis = NULL;
|
|
||||||
char *tmp = NULL;
|
|
||||||
|
|
||||||
if(!digest->nc)
|
|
||||||
@@ -721,12 +722,12 @@ static CURLcode _Curl_auth_create_digest
|
|
||||||
}
|
|
||||||
|
|
||||||
if(digest->userhash) {
|
|
||||||
- hashthis = (unsigned char *) aprintf("%s:%s", userp, digest->realm);
|
|
||||||
+ hashthis = aprintf("%s:%s", userp, digest->realm);
|
|
||||||
if(!hashthis)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
CURL_OUTPUT_DIGEST_CONV(data, hashthis);
|
|
||||||
- hash(hashbuf, hashthis);
|
|
||||||
+ hash(hashbuf, (unsigned char *) hashthis, strlen(hashthis));
|
|
||||||
free(hashthis);
|
|
||||||
convert_to_ascii(hashbuf, (unsigned char *)userh);
|
|
||||||
}
|
|
||||||
@@ -742,14 +743,13 @@ static CURLcode _Curl_auth_create_digest
|
|
||||||
unq(nonce-value) ":" unq(cnonce-value)
|
|
||||||
*/
|
|
||||||
|
|
||||||
- hashthis = (unsigned char *)
|
|
||||||
- aprintf("%s:%s:%s", digest->userhash ? userh : userp,
|
|
||||||
- digest->realm, passwdp);
|
|
||||||
+ hashthis = aprintf("%s:%s:%s", digest->userhash ? userh : userp,
|
|
||||||
+ digest->realm, passwdp);
|
|
||||||
if(!hashthis)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
|
|
||||||
- hash(hashbuf, hashthis);
|
|
||||||
+ hash(hashbuf, (unsigned char *) hashthis, strlen(hashthis));
|
|
||||||
free(hashthis);
|
|
||||||
convert_to_ascii(hashbuf, ha1);
|
|
||||||
|
|
||||||
@@ -762,7 +762,7 @@ static CURLcode _Curl_auth_create_digest
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
CURL_OUTPUT_DIGEST_CONV(data, tmp); /* Convert on non-ASCII machines */
|
|
||||||
- hash(hashbuf, (unsigned char *) tmp);
|
|
||||||
+ hash(hashbuf, (unsigned char *) tmp, strlen(tmp));
|
|
||||||
free(tmp);
|
|
||||||
convert_to_ascii(hashbuf, ha1);
|
|
||||||
}
|
|
||||||
@@ -780,18 +780,18 @@ static CURLcode _Curl_auth_create_digest
|
|
||||||
5.1.1 of RFC 2616)
|
|
||||||
*/
|
|
||||||
|
|
||||||
- hashthis = (unsigned char *) aprintf("%s:%s", request, uripath);
|
|
||||||
+ hashthis = aprintf("%s:%s", request, uripath);
|
|
||||||
|
|
||||||
if(digest->qop && strcasecompare(digest->qop, "auth-int")) {
|
|
||||||
/* We don't support auth-int for PUT or POST at the moment.
|
|
||||||
TODO: replace hash of empty string with entity-body for PUT/POST */
|
|
||||||
char hashed[65];
|
|
||||||
- unsigned char *hashthis2;
|
|
||||||
+ char *hashthis2;
|
|
||||||
|
|
||||||
- hash(hashbuf, (const unsigned char *)"");
|
|
||||||
+ hash(hashbuf, (const unsigned char *)"", 0);
|
|
||||||
convert_to_ascii(hashbuf, (unsigned char *)hashed);
|
|
||||||
|
|
||||||
- hashthis2 = (unsigned char *)aprintf("%s:%s", hashthis, hashed);
|
|
||||||
+ hashthis2 = aprintf("%s:%s", hashthis, hashed);
|
|
||||||
free(hashthis);
|
|
||||||
hashthis = hashthis2;
|
|
||||||
}
|
|
||||||
@@ -800,31 +800,23 @@ static CURLcode _Curl_auth_create_digest
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
|
|
||||||
- hash(hashbuf, hashthis);
|
|
||||||
+ hash(hashbuf, (unsigned char *) hashthis, strlen(hashthis));
|
|
||||||
free(hashthis);
|
|
||||||
convert_to_ascii(hashbuf, ha2);
|
|
||||||
|
|
||||||
if(digest->qop) {
|
|
||||||
- hashthis = (unsigned char *) aprintf("%s:%s:%08x:%s:%s:%s",
|
|
||||||
- ha1,
|
|
||||||
- digest->nonce,
|
|
||||||
- digest->nc,
|
|
||||||
- digest->cnonce,
|
|
||||||
- digest->qop,
|
|
||||||
- ha2);
|
|
||||||
+ hashthis = aprintf("%s:%s:%08x:%s:%s:%s", ha1, digest->nonce, digest->nc,
|
|
||||||
+ digest->cnonce, digest->qop, ha2);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
- hashthis = (unsigned char *) aprintf("%s:%s:%s",
|
|
||||||
- ha1,
|
|
||||||
- digest->nonce,
|
|
||||||
- ha2);
|
|
||||||
+ hashthis = aprintf("%s:%s:%s", ha1, digest->nonce, ha2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!hashthis)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
|
|
||||||
- hash(hashbuf, hashthis);
|
|
||||||
+ hash(hashbuf, (unsigned char *) hashthis, strlen(hashthis));
|
|
||||||
free(hashthis);
|
|
||||||
convert_to_ascii(hashbuf, request_digest);
|
|
||||||
|
|
||||||
diff -up curl-7.61.1/lib/vauth/ntlm.c.RHEL-32335 curl-7.61.1/lib/vauth/ntlm.c
|
|
||||||
--- curl-7.61.1/lib/vauth/ntlm.c.RHEL-32335 2024-04-10 09:51:15.114537483 +0200
|
|
||||||
+++ curl-7.61.1/lib/vauth/ntlm.c 2024-04-10 09:52:26.411962237 +0200
|
|
||||||
@@ -40,6 +40,7 @@
|
|
||||||
#include "curl_ntlm_core.h"
|
|
||||||
#include "curl_gethostname.h"
|
|
||||||
#include "curl_multibyte.h"
|
|
||||||
+#include "curl_md5.h"
|
|
||||||
#include "warnless.h"
|
|
||||||
#include "rand.h"
|
|
||||||
#include "vtls/vtls.h"
|
|
||||||
@@ -621,11 +622,10 @@ CURLcode Curl_auth_create_ntlm_type3_mes
|
|
||||||
memcpy(tmp, &ntlm->nonce[0], 8);
|
|
||||||
memcpy(tmp + 8, entropy, 8);
|
|
||||||
|
|
||||||
- result = Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH);
|
|
||||||
- if(!result)
|
|
||||||
- /* We shall only use the first 8 bytes of md5sum, but the des code in
|
|
||||||
- Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
|
|
||||||
- result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
|
|
||||||
+ Curl_md5it(md5sum, tmp, 16);
|
|
||||||
+ /* We shall only use the first 8 bytes of md5sum, but the des code in
|
|
||||||
+ Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
|
|
||||||
+ result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
|
|
||||||
if(result)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
diff -up curl-7.61.1/tests/unit/unit1601.c.RHEL-32335 curl-7.61.1/tests/unit/unit1601.c
|
|
||||||
--- curl-7.61.1/tests/unit/unit1601.c.RHEL-32335 2024-04-10 10:20:19.347920127 +0200
|
|
||||||
+++ curl-7.61.1/tests/unit/unit1601.c 2024-04-10 10:21:53.606480641 +0200
|
|
||||||
@@ -36,18 +36,19 @@ static void unit_stop(void)
|
|
||||||
UNITTEST_START
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
|
||||||
- unsigned char output[16];
|
|
||||||
+ const char string1[] = "1";
|
|
||||||
+ const char string2[] = "hello-you-fool";
|
|
||||||
+ unsigned char output[MD5_DIGEST_LEN];
|
|
||||||
unsigned char *testp = output;
|
|
||||||
- Curl_md5it(output, (const unsigned char *)"1");
|
|
||||||
|
|
||||||
-/* !checksrc! disable LONGLINE 2 */
|
|
||||||
- verify_memory(testp,
|
|
||||||
- "\xc4\xca\x42\x38\xa0\xb9\x23\x82\x0d\xcc\x50\x9a\x6f\x75\x84\x9b", 16);
|
|
||||||
+ Curl_md5it(output, (const unsigned char *) string1, strlen(string1));
|
|
||||||
+ verify_memory(testp, "\xc4\xca\x42\x38\xa0\xb9\x23\x82\x0d\xcc\x50\x9a\x6f"
|
|
||||||
+ "\x75\x84\x9b", MD5_DIGEST_LEN);
|
|
||||||
|
|
||||||
- Curl_md5it(output, (const unsigned char *)"hello-you-fool");
|
|
||||||
+ Curl_md5it(output, (const unsigned char *) string2, strlen(string2));
|
|
||||||
|
|
||||||
- verify_memory(testp,
|
|
||||||
- "\x88\x67\x0b\x6d\x5d\x74\x2f\xad\xa5\xcd\xf9\xb6\x82\x87\x5f\x22", 16);
|
|
||||||
+ verify_memory(testp, "\x88\x67\x0b\x6d\x5d\x74\x2f\xad\xa5\xcd\xf9\xb6\x82"
|
|
||||||
+ "\x87\x5f\x22", MD5_DIGEST_LEN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,283 +0,0 @@
|
|||||||
From 17d1e27d309f16da960fd3b9933e6e2b1db22b17 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Eric Wong <e@80x24.org>
|
|
||||||
Date: Sat, 10 Aug 2019 21:20:23 +0000
|
|
||||||
Subject: [PATCH] asyn-thread: issue CURL_POLL_REMOVE before closing socket
|
|
||||||
|
|
||||||
This avoids EBADF errors from EPOLL_CTL_DEL operations in the
|
|
||||||
ephiperfifo.c example. EBADF is dangerous in multi-threaded
|
|
||||||
applications where I rely on epoll_ctl to operate on the same
|
|
||||||
epoll description from different threads.
|
|
||||||
|
|
||||||
Follow-up to eb9a604f8d7db8
|
|
||||||
|
|
||||||
Bug: https://curl.haxx.se/mail/lib-2019-08/0026.html
|
|
||||||
Closes #4211
|
|
||||||
---
|
|
||||||
lib/asyn-thread.c | 25 ++++++++++++++++++++-----
|
|
||||||
1 file changed, 20 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
|
|
||||||
index 222e78d98..24da74885 100755
|
|
||||||
--- a/lib/asyn-thread.c
|
|
||||||
+++ b/lib/asyn-thread.c
|
|
||||||
@@ -164,6 +164,7 @@ struct thread_sync_data {
|
|
||||||
duplicate */
|
|
||||||
int port;
|
|
||||||
#ifdef HAVE_SOCKETPAIR
|
|
||||||
+ struct connectdata *conn;
|
|
||||||
curl_socket_t sock_pair[2]; /* socket pair */
|
|
||||||
#endif
|
|
||||||
int sock_error;
|
|
||||||
@@ -201,11 +202,10 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
|
||||||
Curl_freeaddrinfo(tsd->res);
|
|
||||||
|
|
||||||
#ifdef HAVE_SOCKETPAIR
|
|
||||||
- /* close socket pair */
|
|
||||||
- if(tsd->sock_pair[0] != CURL_SOCKET_BAD) {
|
|
||||||
- sclose(tsd->sock_pair[0]);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
+ /*
|
|
||||||
+ * close one end of the socket pair (may be done in resolver thread);
|
|
||||||
+ * the other end (for reading) is always closed in the parent thread.
|
|
||||||
+ */
|
|
||||||
if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
|
|
||||||
sclose(tsd->sock_pair[1]);
|
|
||||||
}
|
|
||||||
@@ -382,6 +382,10 @@ static void destroy_async_data(struct Curl_async *async)
|
|
||||||
if(async->os_specific) {
|
|
||||||
struct thread_data *td = (struct thread_data*) async->os_specific;
|
|
||||||
int done;
|
|
||||||
+#ifdef HAVE_SOCKETPAIR
|
|
||||||
+ curl_socket_t sock_rd = td->tsd.sock_pair[0];
|
|
||||||
+ struct connectdata *conn = td->tsd.conn;
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if the thread is still blocking in the resolve syscall, detach it and
|
|
||||||
@@ -403,6 +407,15 @@ static void destroy_async_data(struct Curl_async *async)
|
|
||||||
|
|
||||||
free(async->os_specific);
|
|
||||||
}
|
|
||||||
+#ifdef HAVE_SOCKETPAIR
|
|
||||||
+ /*
|
|
||||||
+ * ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE
|
|
||||||
+ * before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL
|
|
||||||
+ */
|
|
||||||
+ if(conn)
|
|
||||||
+ Curl_multi_closed(conn->data, sock_rd);
|
|
||||||
+ sclose(sock_rd);
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
async->os_specific = NULL;
|
|
||||||
|
|
||||||
@@ -644,6 +657,8 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
|
||||||
if(td) {
|
|
||||||
/* return read fd to client for polling the DNS resolution status */
|
|
||||||
socks[0] = td->tsd.sock_pair[0];
|
|
||||||
+ DEBUGASSERT(td->tsd.conn == conn || !td->tsd.conn);
|
|
||||||
+ td->tsd.conn = conn;
|
|
||||||
ret_val = GETSOCK_READSOCK(0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
--
|
|
||||||
2.49.0
|
|
||||||
|
|
||||||
From 041690aadb1357775ff06c5bf827a98585627c76 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Stenberg <daniel@haxx.se>
|
|
||||||
Date: Tue, 30 Jul 2019 10:29:54 +0200
|
|
||||||
Subject: [PATCH] asyn-thread: removed unused variable
|
|
||||||
|
|
||||||
Follow-up to eb9a604f. Mistake caused by me when I edited the commit
|
|
||||||
before push...
|
|
||||||
---
|
|
||||||
lib/asyn-thread.c | 3 +--
|
|
||||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
|
|
||||||
index f17638e44..e323cbe20 100755
|
|
||||||
--- a/lib/asyn-thread.c
|
|
||||||
+++ b/lib/asyn-thread.c
|
|
||||||
@@ -636,11 +636,10 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
|
||||||
struct resdata *reslv = (struct resdata *)data->state.resolver;
|
|
||||||
#ifdef HAVE_SOCKETPAIR
|
|
||||||
struct thread_data *td = (struct thread_data*)conn->async.os_specific;
|
|
||||||
- int loop_idx;
|
|
||||||
#else
|
|
||||||
(void)socks;
|
|
||||||
- (void)numsocks;
|
|
||||||
#endif
|
|
||||||
+ (void)numsocks;
|
|
||||||
|
|
||||||
#ifdef HAVE_SOCKETPAIR
|
|
||||||
if(td) {
|
|
||||||
--
|
|
||||||
2.49.0
|
|
||||||
|
|
||||||
From 060fb84a5a07388f099c7a3422e281ac64d623a5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Xiang Xiao <xiaoxiang@xiaomi.com>
|
|
||||||
Date: Tue, 24 Dec 2019 21:47:37 +0800
|
|
||||||
Subject: [PATCH] lib: remove erroneous +x file permission on some c files
|
|
||||||
|
|
||||||
Modified by commit eb9a604 accidentally.
|
|
||||||
|
|
||||||
Closes https://github.com/curl/curl/pull/4756
|
|
||||||
---
|
|
||||||
lib/asyn-thread.c | 0
|
|
||||||
lib/multi.c | 0
|
|
||||||
2 files changed, 0 insertions(+), 0 deletions(-)
|
|
||||||
mode change 100755 => 100644 lib/asyn-thread.c
|
|
||||||
mode change 100755 => 100644 lib/multi.c
|
|
||||||
|
|
||||||
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
|
|
||||||
old mode 100755
|
|
||||||
new mode 100644
|
|
||||||
diff --git a/lib/multi.c b/lib/multi.c
|
|
||||||
old mode 100755
|
|
||||||
new mode 100644
|
|
||||||
--
|
|
||||||
2.49.0
|
|
||||||
|
|
||||||
From e34ec7de5964baa214555115f5061ed199d0f7b4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Stenberg <daniel@haxx.se>
|
|
||||||
Date: Wed, 11 Sep 2019 23:11:58 +0200
|
|
||||||
Subject: [PATCH] asyn-thread: s/AF_LOCAL/AF_UNIX for Solaris
|
|
||||||
|
|
||||||
Reported-by: Dagobert Michelsen
|
|
||||||
Fixes #4328
|
|
||||||
Closes #4333
|
|
||||||
---
|
|
||||||
lib/asyn-thread.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
|
|
||||||
index 24da74885..fcbf1305e 100755
|
|
||||||
--- a/lib/asyn-thread.c
|
|
||||||
+++ b/lib/asyn-thread.c
|
|
||||||
@@ -244,8 +244,8 @@ int init_thread_sync_data(struct thread_data * td,
|
|
||||||
Curl_mutex_init(tsd->mtx);
|
|
||||||
|
|
||||||
#ifdef HAVE_SOCKETPAIR
|
|
||||||
- /* create socket pair */
|
|
||||||
- if(socketpair(AF_LOCAL, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) {
|
|
||||||
+ /* create socket pair, avoid AF_LOCAL since it doesn't build on Solaris */
|
|
||||||
+ if(socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) {
|
|
||||||
tsd->sock_pair[0] = CURL_SOCKET_BAD;
|
|
||||||
tsd->sock_pair[1] = CURL_SOCKET_BAD;
|
|
||||||
goto err_exit;
|
|
||||||
--
|
|
||||||
2.49.0
|
|
||||||
|
|
||||||
From 9c76f694de1765152e0b349cd55baad5a501f55b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Stenberg <daniel@haxx.se>
|
|
||||||
Date: Sat, 5 Oct 2019 15:41:09 +0200
|
|
||||||
Subject: [PATCH] asyn-thread: make use of Curl_socketpair() where available
|
|
||||||
|
|
||||||
---
|
|
||||||
lib/asyn-thread.c | 26 ++++++++++++++------------
|
|
||||||
1 file changed, 14 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
|
|
||||||
index fcbf1305e..8c552baa9 100755
|
|
||||||
--- a/lib/asyn-thread.c
|
|
||||||
+++ b/lib/asyn-thread.c
|
|
||||||
@@ -163,7 +165,7 @@ struct thread_sync_data {
|
|
||||||
char *hostname; /* hostname to resolve, Curl_async.hostname
|
|
||||||
duplicate */
|
|
||||||
int port;
|
|
||||||
-#ifdef HAVE_SOCKETPAIR
|
|
||||||
+#ifdef USE_SOCKETPAIR
|
|
||||||
struct connectdata *conn;
|
|
||||||
curl_socket_t sock_pair[2]; /* socket pair */
|
|
||||||
#endif
|
|
||||||
@@ -201,7 +203,7 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
|
||||||
if(tsd->res)
|
|
||||||
Curl_freeaddrinfo(tsd->res);
|
|
||||||
|
|
||||||
-#ifdef HAVE_SOCKETPAIR
|
|
||||||
+#ifdef USE_SOCKETPAIR
|
|
||||||
/*
|
|
||||||
* close one end of the socket pair (may be done in resolver thread);
|
|
||||||
* the other end (for reading) is always closed in the parent thread.
|
|
||||||
@@ -243,9 +245,9 @@ int init_thread_sync_data(struct thread_data * td,
|
|
||||||
|
|
||||||
Curl_mutex_init(tsd->mtx);
|
|
||||||
|
|
||||||
-#ifdef HAVE_SOCKETPAIR
|
|
||||||
+#ifdef USE_SOCKETPAIR
|
|
||||||
/* create socket pair, avoid AF_LOCAL since it doesn't build on Solaris */
|
|
||||||
- if(socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) {
|
|
||||||
+ if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) {
|
|
||||||
tsd->sock_pair[0] = CURL_SOCKET_BAD;
|
|
||||||
tsd->sock_pair[1] = CURL_SOCKET_BAD;
|
|
||||||
goto err_exit;
|
|
||||||
@@ -297,7 +299,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
|
|
||||||
struct thread_data *td = tsd->td;
|
|
||||||
char service[12];
|
|
||||||
int rc;
|
|
||||||
-#ifdef HAVE_SOCKETPAIR
|
|
||||||
+#ifdef USE_SOCKETPAIR
|
|
||||||
char buf[1];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -322,11 +324,11 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
|
|
||||||
free(td);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
-#ifdef HAVE_SOCKETPAIR
|
|
||||||
+#ifdef USE_SOCKETPAIR
|
|
||||||
if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
|
|
||||||
/* DNS has been resolved, signal client task */
|
|
||||||
buf[0] = 1;
|
|
||||||
- if(write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) {
|
|
||||||
+ if(swrite(tsd->sock_pair[1], buf, sizeof(buf)) < 0) {
|
|
||||||
/* update sock_erro to errno */
|
|
||||||
tsd->sock_error = SOCKERRNO;
|
|
||||||
}
|
|
||||||
@@ -382,7 +384,7 @@ static void destroy_async_data(struct Curl_async *async)
|
|
||||||
if(async->os_specific) {
|
|
||||||
struct thread_data *td = (struct thread_data*) async->os_specific;
|
|
||||||
int done;
|
|
||||||
-#ifdef HAVE_SOCKETPAIR
|
|
||||||
+#ifdef USE_SOCKETPAIR
|
|
||||||
curl_socket_t sock_rd = td->tsd.sock_pair[0];
|
|
||||||
struct connectdata *conn = td->tsd.conn;
|
|
||||||
#endif
|
|
||||||
@@ -407,7 +409,7 @@ static void destroy_async_data(struct Curl_async *async)
|
|
||||||
|
|
||||||
free(async->os_specific);
|
|
||||||
}
|
|
||||||
-#ifdef HAVE_SOCKETPAIR
|
|
||||||
+#ifdef USE_SOCKETPAIR
|
|
||||||
/*
|
|
||||||
* ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE
|
|
||||||
* before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL
|
|
||||||
@@ -649,14 +651,14 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
|
||||||
timediff_t ms;
|
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
struct resdata *reslv = (struct resdata *)data->state.resolver;
|
|
||||||
-#ifdef HAVE_SOCKETPAIR
|
|
||||||
+#ifdef USE_SOCKETPAIR
|
|
||||||
struct thread_data *td = (struct thread_data*)conn->async.os_specific;
|
|
||||||
#else
|
|
||||||
(void)socks;
|
|
||||||
#endif
|
|
||||||
(void)numsocks;
|
|
||||||
|
|
||||||
-#ifdef HAVE_SOCKETPAIR
|
|
||||||
+#ifdef USE_SOCKETPAIR
|
|
||||||
if(td) {
|
|
||||||
/* return read fd to client for polling the DNS resolution status */
|
|
||||||
socks[0] = td->tsd.sock_pair[0];
|
|
||||||
@@ -673,7 +675,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
|
||||||
else
|
|
||||||
milli = 200;
|
|
||||||
Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
|
|
||||||
-#ifdef HAVE_SOCKETPAIR
|
|
||||||
+#ifdef USE_SOCKETPAIR
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
--
|
|
||||||
2.49.0
|
|
||||||
|
|
||||||
@ -1,338 +0,0 @@
|
|||||||
From b1a049b4c024ea69ef571da8def3cc13889430f4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jay Satiro <raysatiro@yahoo.com>
|
|
||||||
Date: Sun, 23 Feb 2020 18:37:09 -0500
|
|
||||||
Subject: [PATCH] libssh: Fix matching user-specified MD5 hex key
|
|
||||||
|
|
||||||
Prior to this change a match would never be successful because it
|
|
||||||
was mistakenly coded to compare binary data from libssh to a
|
|
||||||
user-specified hex string (ie CURLOPT_SSH_HOST_PUBLIC_KEY_MD5).
|
|
||||||
|
|
||||||
Reported-by: fds242@users.noreply.github.com
|
|
||||||
|
|
||||||
Fixes https://github.com/curl/curl/issues/4971
|
|
||||||
Closes https://github.com/curl/curl/pull/4974
|
|
||||||
(cherry picked from commit 09aa807240b9dcde78a919ff712316a1daf0655e)
|
|
||||||
---
|
|
||||||
lib/ssh-libssh.c | 20 ++++++++++++++++---
|
|
||||||
tests/FILEFORMAT | 1 +
|
|
||||||
tests/data/Makefile.inc | 1 +
|
|
||||||
tests/data/test664 | 44 +++++++++++++++++++++++++++++++++++++++++
|
|
||||||
tests/data/test665 | 44 +++++++++++++++++++++++++++++++++++++++++
|
|
||||||
tests/runtests.pl | 24 ++++++++++++++++++++++
|
|
||||||
tests/sshhelp.pm | 3 +++
|
|
||||||
tests/sshserver.pl | 31 +++++++++++++++++++++++++----
|
|
||||||
8 files changed, 161 insertions(+), 7 deletions(-)
|
|
||||||
create mode 100644 tests/data/test664
|
|
||||||
create mode 100644 tests/data/test665
|
|
||||||
|
|
||||||
diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
|
|
||||||
index 7d590891c..c203d6336 100644
|
|
||||||
--- a/lib/ssh-libssh.c
|
|
||||||
+++ b/lib/ssh-libssh.c
|
|
||||||
@@ -327,13 +327,27 @@ static int myssh_is_known(struct connectdata *conn)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) {
|
|
||||||
+ int i;
|
|
||||||
+ char md5buffer[33];
|
|
||||||
+ const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
|
|
||||||
+
|
|
||||||
rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5,
|
|
||||||
&hash, &hlen);
|
|
||||||
- if(rc != SSH_OK)
|
|
||||||
+ if(rc != SSH_OK || hlen != 16) {
|
|
||||||
+ failf(data,
|
|
||||||
+ "Denied establishing ssh session: md5 fingerprint not available");
|
|
||||||
goto cleanup;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for(i = 0; i < 16; i++)
|
|
||||||
+ snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char)hash[i]);
|
|
||||||
+
|
|
||||||
+ infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
|
|
||||||
|
|
||||||
- if(hlen != strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) ||
|
|
||||||
- memcmp(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], hash, hlen)) {
|
|
||||||
+ if(!strcasecompare(md5buffer, pubkey_md5)) {
|
|
||||||
+ failf(data,
|
|
||||||
+ "Denied establishing ssh session: mismatch md5 fingerprint. "
|
|
||||||
+ "Remote %s is not equal to %s", md5buffer, pubkey_md5);
|
|
||||||
rc = SSH_ERROR;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
diff --git a/tests/FILEFORMAT b/tests/FILEFORMAT
|
|
||||||
index 135ded6c1..6b79093ab 100644
|
|
||||||
--- a/tests/FILEFORMAT
|
|
||||||
+++ b/tests/FILEFORMAT
|
|
||||||
@@ -368,6 +368,7 @@ Available substitute variables include:
|
|
||||||
%PWD - Current directory
|
|
||||||
%RTSP6PORT - IPv6 port number of the RTSP server
|
|
||||||
%RTSPPORT - Port number of the RTSP server
|
|
||||||
+%SSHSRVMD5 - MD5 of SSH server's public key
|
|
||||||
%SMTP6PORT - IPv6 port number of the SMTP server
|
|
||||||
%SMTPPORT - Port number of the SMTP server
|
|
||||||
%SOCKSPORT - Port number of the SOCKS4/5 server
|
|
||||||
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
|
|
||||||
index e0457486b..923b58a63 100644
|
|
||||||
--- a/tests/data/Makefile.inc
|
|
||||||
+++ b/tests/data/Makefile.inc
|
|
||||||
@@ -84,6 +84,7 @@ test626 test627 test628 test629 test630 test631 test632 test633 test634 \
|
|
||||||
test635 test636 test637 test638 test639 test640 test641 test642 \
|
|
||||||
test643 test644 test645 test646 test647 test648 test649 test650 test651 \
|
|
||||||
test652 test653 test654 test655 test656 \
|
|
||||||
+test664 test665 \
|
|
||||||
\
|
|
||||||
test700 test701 test702 test703 test704 test705 test706 test707 test708 \
|
|
||||||
test709 test710 test711 test712 test713 test714 test715 \
|
|
||||||
diff --git a/tests/data/test664 b/tests/data/test664
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..cb73b248b
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/data/test664
|
|
||||||
@@ -0,0 +1,44 @@
|
|
||||||
+<testcase>
|
|
||||||
+<info>
|
|
||||||
+<keywords>
|
|
||||||
+SFTP
|
|
||||||
+server key check
|
|
||||||
+</keywords>
|
|
||||||
+</info>
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Server-side
|
|
||||||
+<reply>
|
|
||||||
+<data>
|
|
||||||
+test
|
|
||||||
+</data>
|
|
||||||
+</reply>
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Client-side
|
|
||||||
+<client>
|
|
||||||
+<server>
|
|
||||||
+sftp
|
|
||||||
+</server>
|
|
||||||
+ <name>
|
|
||||||
+SFTP correct host key
|
|
||||||
+ </name>
|
|
||||||
+ <command>
|
|
||||||
+--hostpubmd5 %SSHSRVMD5 --key curl_client_key --pubkey curl_client_key.pub -u %USER: sftp://%HOSTIP:%SSHPORT%POSIX_PWD/log/file664.txt
|
|
||||||
+</command>
|
|
||||||
+<file name="log/file664.txt">
|
|
||||||
+test
|
|
||||||
+</file>
|
|
||||||
+</client>
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Verify data after the test has been "shot"
|
|
||||||
+<verify>
|
|
||||||
+<errorcode>
|
|
||||||
+0
|
|
||||||
+</errorcode>
|
|
||||||
+<valgrind>
|
|
||||||
+disable
|
|
||||||
+</valgrind>
|
|
||||||
+</verify>
|
|
||||||
+</testcase>
|
|
||||||
diff --git a/tests/data/test665 b/tests/data/test665
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..830adb8f6
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/data/test665
|
|
||||||
@@ -0,0 +1,44 @@
|
|
||||||
+<testcase>
|
|
||||||
+<info>
|
|
||||||
+<keywords>
|
|
||||||
+SCP
|
|
||||||
+server key check
|
|
||||||
+</keywords>
|
|
||||||
+</info>
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Server-side
|
|
||||||
+<reply>
|
|
||||||
+<data>
|
|
||||||
+test
|
|
||||||
+</data>
|
|
||||||
+</reply>
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Client-side
|
|
||||||
+<client>
|
|
||||||
+<server>
|
|
||||||
+scp
|
|
||||||
+</server>
|
|
||||||
+ <name>
|
|
||||||
+SCP correct host key
|
|
||||||
+ </name>
|
|
||||||
+ <command>
|
|
||||||
+--hostpubmd5 %SSHSRVMD5 --key curl_client_key --pubkey curl_client_key.pub -u %USER: scp://%HOSTIP:%SSHPORT%POSIX_PWD/log/file665.txt
|
|
||||||
+</command>
|
|
||||||
+<file name="log/file665.txt">
|
|
||||||
+test
|
|
||||||
+</file>
|
|
||||||
+</client>
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Verify data after the test has been "shot"
|
|
||||||
+<verify>
|
|
||||||
+<errorcode>
|
|
||||||
+0
|
|
||||||
+</errorcode>
|
|
||||||
+<valgrind>
|
|
||||||
+disable
|
|
||||||
+</valgrind>
|
|
||||||
+</verify>
|
|
||||||
+</testcase>
|
|
||||||
diff --git a/tests/runtests.pl b/tests/runtests.pl
|
|
||||||
index e12c1429a..4e2a19cf2 100755
|
|
||||||
--- a/tests/runtests.pl
|
|
||||||
+++ b/tests/runtests.pl
|
|
||||||
@@ -150,6 +150,8 @@ my $SMBPORT; # SMB server port
|
|
||||||
my $SMBSPORT; # SMBS server port
|
|
||||||
my $NEGTELNETPORT; # TELNET server port with negotiation
|
|
||||||
|
|
||||||
+my $SSHSRVMD5; # MD5 of ssh server public key
|
|
||||||
+
|
|
||||||
my $srcdir = $ENV{'srcdir'} || '.';
|
|
||||||
my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
|
|
||||||
my $VCURL=$CURL; # what curl binary to use to verify the servers with
|
|
||||||
@@ -2181,6 +2183,18 @@ sub runsshserver {
|
|
||||||
return (0,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ my $hstpubmd5f = "curl_host_rsa_key.pub_md5";
|
|
||||||
+ if(!open(PUBMD5FILE, "<", $hstpubmd5f) ||
|
|
||||||
+ (read(PUBMD5FILE, $SSHSRVMD5, 32) != 32) ||
|
|
||||||
+ !close(PUBMD5FILE) ||
|
|
||||||
+ ($SSHSRVMD5 !~ /^[a-f0-9]{32}$/i))
|
|
||||||
+ {
|
|
||||||
+ my $msg = "Fatal: $srvrname pubkey md5 missing : \"$hstpubmd5f\" : $!";
|
|
||||||
+ logmsg "$msg\n";
|
|
||||||
+ stopservers($verbose);
|
|
||||||
+ die $msg;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if($verbose) {
|
|
||||||
logmsg "RUN: $srvrname server is now running PID $pid2\n";
|
|
||||||
}
|
|
||||||
@@ -3205,6 +3219,16 @@ sub subVariables {
|
|
||||||
$$thing =~ s/%SRCDIR/$srcdir/g;
|
|
||||||
$$thing =~ s/%USER/$USER/g;
|
|
||||||
|
|
||||||
+ if($$thing =~ /%SSHSRVMD5/) {
|
|
||||||
+ if(!$SSHSRVMD5) {
|
|
||||||
+ my $msg = "Fatal: Missing SSH server pubkey MD5. Is server running?";
|
|
||||||
+ logmsg "$msg\n";
|
|
||||||
+ stopservers($verbose);
|
|
||||||
+ die $msg;
|
|
||||||
+ }
|
|
||||||
+ $$thing =~ s/%SSHSRVMD5/$SSHSRVMD5/g;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
# The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be
|
|
||||||
# used for time-out tests and that whould work on most hosts as these
|
|
||||||
# adjust for the startup/check time for this particular host. We needed
|
|
||||||
diff --git a/tests/sshhelp.pm b/tests/sshhelp.pm
|
|
||||||
index c5618a109..abdf9c458 100644
|
|
||||||
--- a/tests/sshhelp.pm
|
|
||||||
+++ b/tests/sshhelp.pm
|
|
||||||
@@ -50,6 +50,7 @@ use vars qw(
|
|
||||||
$sftpcmds
|
|
||||||
$hstprvkeyf
|
|
||||||
$hstpubkeyf
|
|
||||||
+ $hstpubmd5f
|
|
||||||
$cliprvkeyf
|
|
||||||
$clipubkeyf
|
|
||||||
@sftppath
|
|
||||||
@@ -82,6 +83,7 @@ use vars qw(
|
|
||||||
$sftpcmds
|
|
||||||
$hstprvkeyf
|
|
||||||
$hstpubkeyf
|
|
||||||
+ $hstpubmd5f
|
|
||||||
$cliprvkeyf
|
|
||||||
$clipubkeyf
|
|
||||||
display_sshdconfig
|
|
||||||
@@ -122,6 +124,7 @@ $sftpcmds = 'curl_sftp_cmds'; # sftp client commands batch file
|
|
||||||
$knownhosts = 'curl_client_knownhosts'; # ssh knownhosts file
|
|
||||||
$hstprvkeyf = 'curl_host_rsa_key'; # host private key file
|
|
||||||
$hstpubkeyf = 'curl_host_rsa_key.pub'; # host public key file
|
|
||||||
+$hstpubmd5f = 'curl_host_rsa_key.pub_md5'; # md5 hash of host public key
|
|
||||||
$cliprvkeyf = 'curl_client_key'; # client private key file
|
|
||||||
$clipubkeyf = 'curl_client_key.pub'; # client public key file
|
|
||||||
|
|
||||||
diff --git a/tests/sshserver.pl b/tests/sshserver.pl
|
|
||||||
index 9b3d122fd..cd92a62c5 100755
|
|
||||||
--- a/tests/sshserver.pl
|
|
||||||
+++ b/tests/sshserver.pl
|
|
||||||
@@ -28,6 +28,9 @@ use strict;
|
|
||||||
use warnings;
|
|
||||||
use Cwd;
|
|
||||||
use Cwd 'abs_path';
|
|
||||||
+use Digest::MD5;
|
|
||||||
+use Digest::MD5 'md5_hex';
|
|
||||||
+use MIME::Base64;
|
|
||||||
|
|
||||||
#***************************************************************************
|
|
||||||
# Variables and subs imported from sshhelp module
|
|
||||||
@@ -48,6 +51,7 @@ use sshhelp qw(
|
|
||||||
$sftpcmds
|
|
||||||
$hstprvkeyf
|
|
||||||
$hstpubkeyf
|
|
||||||
+ $hstpubmd5f
|
|
||||||
$cliprvkeyf
|
|
||||||
$clipubkeyf
|
|
||||||
display_sshdconfig
|
|
||||||
@@ -367,10 +371,11 @@ if((($sshid =~ /OpenSSH/) && ($sshvernum < 299)) ||
|
|
||||||
#
|
|
||||||
if((! -e $hstprvkeyf) || (! -s $hstprvkeyf) ||
|
|
||||||
(! -e $hstpubkeyf) || (! -s $hstpubkeyf) ||
|
|
||||||
+ (! -e $hstpubmd5f) || (! -s $hstpubmd5f) ||
|
|
||||||
(! -e $cliprvkeyf) || (! -s $cliprvkeyf) ||
|
|
||||||
(! -e $clipubkeyf) || (! -s $clipubkeyf)) {
|
|
||||||
# Make sure all files are gone so ssh-keygen doesn't complain
|
|
||||||
- unlink($hstprvkeyf, $hstpubkeyf, $cliprvkeyf, $clipubkeyf);
|
|
||||||
+ unlink($hstprvkeyf, $hstpubkeyf, $hstpubmd5f, $cliprvkeyf, $clipubkeyf);
|
|
||||||
logmsg 'generating host keys...' if($verbose);
|
|
||||||
if(system "\"$sshkeygen\" -q -t rsa -f $hstprvkeyf -C 'curl test server' -N ''") {
|
|
||||||
logmsg 'Could not generate host key';
|
|
||||||
@@ -381,6 +386,24 @@ if((! -e $hstprvkeyf) || (! -s $hstprvkeyf) ||
|
|
||||||
logmsg 'Could not generate client key';
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
+ # Make sure that permissions are restricted so openssh doesn't complain
|
|
||||||
+ system "chmod 600 $hstprvkeyf";
|
|
||||||
+ system "chmod 600 $cliprvkeyf";
|
|
||||||
+ # Save md5 hash of public host key
|
|
||||||
+ open(RSAKEYFILE, "<$hstpubkeyf");
|
|
||||||
+ my @rsahostkey = do { local $/ = ' '; <RSAKEYFILE> };
|
|
||||||
+ close(RSAKEYFILE);
|
|
||||||
+ if(!$rsahostkey[1]) {
|
|
||||||
+ logmsg 'Failed parsing base64 encoded RSA host key';
|
|
||||||
+ exit 1;
|
|
||||||
+ }
|
|
||||||
+ open(PUBMD5FILE, ">$hstpubmd5f");
|
|
||||||
+ print PUBMD5FILE md5_hex(decode_base64($rsahostkey[1]));
|
|
||||||
+ close(PUBMD5FILE);
|
|
||||||
+ if((! -e $hstpubmd5f) || (! -s $hstpubmd5f)) {
|
|
||||||
+ logmsg 'Failed writing md5 hash of RSA host key';
|
|
||||||
+ exit 1;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1073,8 +1096,8 @@ elsif($verbose && ($rc >> 8)) {
|
|
||||||
#***************************************************************************
|
|
||||||
# Clean up once the server has stopped
|
|
||||||
#
|
|
||||||
-unlink($hstprvkeyf, $hstpubkeyf, $cliprvkeyf, $clipubkeyf, $knownhosts);
|
|
||||||
-unlink($sshdconfig, $sshconfig, $sftpconfig);
|
|
||||||
-
|
|
||||||
+unlink($hstprvkeyf, $hstpubkeyf, $hstpubmd5f,
|
|
||||||
+ $cliprvkeyf, $clipubkeyf, $knownhosts,
|
|
||||||
+ $sshdconfig, $sshconfig, $sftpconfig);
|
|
||||||
|
|
||||||
exit 0;
|
|
||||||
--
|
|
||||||
2.47.1
|
|
||||||
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
From a1c1af1b82bf9427b2bd5ad949d24923f995909a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jacek Migacz <jmigacz@redhat.com>
|
|
||||||
Date: Wed, 9 Jul 2025 14:33:09 +0200
|
|
||||||
Subject: [PATCH] crypto: ensure crypto initialization works
|
|
||||||
|
|
||||||
---
|
|
||||||
lib/vtls/openssl.c | 14 ++++++++++++--
|
|
||||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
|
|
||||||
index 161e79e..7c41f54 100644
|
|
||||||
--- a/lib/vtls/openssl.c
|
|
||||||
+++ b/lib/vtls/openssl.c
|
|
||||||
@@ -3802,7 +3802,12 @@ static CURLcode Curl_ossl_md5sum(unsigned char *tmp, /* input */
|
|
||||||
(void) unused;
|
|
||||||
|
|
||||||
mdctx = EVP_MD_CTX_create();
|
|
||||||
- EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
|
|
||||||
+ if(!mdctx)
|
|
||||||
+ return CURLE_OUT_OF_MEMORY;
|
|
||||||
+ if(!EVP_DigestInit_ex(mdctx, EVP_md5(), NULL)) {
|
|
||||||
+ EVP_MD_CTX_destroy(mdctx);
|
|
||||||
+ return CURLE_FAILED_INIT;
|
|
||||||
+ }
|
|
||||||
EVP_DigestUpdate(mdctx, tmp, tmplen);
|
|
||||||
EVP_DigestFinal_ex(mdctx, md5sum, &len);
|
|
||||||
EVP_MD_CTX_destroy(mdctx);
|
|
||||||
@@ -3820,7 +3825,12 @@ static CURLcode Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
|
|
||||||
(void) unused;
|
|
||||||
|
|
||||||
mdctx = EVP_MD_CTX_create();
|
|
||||||
- EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
|
|
||||||
+ if(!mdctx)
|
|
||||||
+ return CURLE_OUT_OF_MEMORY;
|
|
||||||
+ if(!EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL)) {
|
|
||||||
+ EVP_MD_CTX_destroy(mdctx);
|
|
||||||
+ return CURLE_FAILED_INIT;
|
|
||||||
+ }
|
|
||||||
EVP_DigestUpdate(mdctx, tmp, tmplen);
|
|
||||||
EVP_DigestFinal_ex(mdctx, sha256sum, &len);
|
|
||||||
EVP_MD_CTX_destroy(mdctx);
|
|
||||||
--
|
|
||||||
2.50.0
|
|
||||||
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
From cbea2fd2c74feabeb6f13b3e3df243b225b3b3ab Mon Sep 17 00:00:00 2001
|
|
||||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
|
||||||
Date: Thu, 6 Dec 2018 17:26:13 +0100
|
|
||||||
Subject: [PATCH] NTLM: force the connection to HTTP/1.1
|
|
||||||
|
|
||||||
Since v7.62.0, cURL tries to use HTTP/2 whenever the server announces
|
|
||||||
the capability. However, NTLM authentication only works with HTTP/1.1,
|
|
||||||
and will likely remain in that boat (for details, see
|
|
||||||
https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10/http2-on-iis#when-is-http2-not-supported).
|
|
||||||
|
|
||||||
When we just found out that we want to use NTLM, and when the current
|
|
||||||
connection runs in HTTP/2 mode, let's force the connection to be closed
|
|
||||||
and to be re-opened using HTTP/1.1.
|
|
||||||
|
|
||||||
Fixes https://github.com/curl/curl/issues/3341.
|
|
||||||
Closes #3345
|
|
||||||
|
|
||||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
|
||||||
---
|
|
||||||
lib/http.c | 6 ++++++
|
|
||||||
1 file changed, 6 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/lib/http.c b/lib/http.c
|
|
||||||
index aed7aa80f..7be6f8b92 100644
|
|
||||||
--- a/lib/http.c
|
|
||||||
+++ b/lib/http.c
|
|
||||||
@@ -526,6 +526,12 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
|
||||||
pickhost = pickoneauth(&data->state.authhost, authmask);
|
|
||||||
if(!pickhost)
|
|
||||||
data->state.authproblem = TRUE;
|
|
||||||
+ if(data->state.authhost.picked == CURLAUTH_NTLM &&
|
|
||||||
+ conn->httpversion > 11) {
|
|
||||||
+ infof(data, "Forcing HTTP/1.1 for NTLM");
|
|
||||||
+ connclose(conn, "Force HTTP/1.1 connection");
|
|
||||||
+ conn->data->set.httpversion = CURL_HTTP_VERSION_1_1;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
if(conn->bits.proxy_user_passwd &&
|
|
||||||
((data->req.httpcode == 407) ||
|
|
||||||
--
|
|
||||||
2.50.0
|
|
||||||
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
From c6ae07c6a541e0e96d0040afb62b45dd37711300 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Stenberg <daniel@haxx.se>
|
|
||||||
Date: Mon, 11 Aug 2025 20:23:05 +0200
|
|
||||||
Subject: [PATCH] cookie: don't treat the leading slash as trailing
|
|
||||||
|
|
||||||
If there is only a leading slash in the path, keep that. Also add an
|
|
||||||
assert to make sure the path is never blank.
|
|
||||||
|
|
||||||
Reported-by: Google Big Sleep
|
|
||||||
Closes #18266
|
|
||||||
---
|
|
||||||
lib/cookie.c | 11 ++++++-----
|
|
||||||
1 file changed, 6 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/cookie.c b/lib/cookie.c
|
|
||||||
index 914a4aca12ac..b72dd99bce9b 100644
|
|
||||||
--- a/lib/cookie.c
|
|
||||||
+++ b/lib/cookie.c
|
|
||||||
@@ -420,8 +420,9 @@ static char *sanitize_cookie_path(const char *cookie_path)
|
|
||||||
return new_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* remove trailing slash when path is non-empty (len > 1) */
|
|
||||||
/* convert /hoge/ to /hoge */
|
|
||||||
- if(len && new_path[len - 1] == '/') {
|
|
||||||
+ if(len > 1 && new_path[len - 1] == '/') {
|
|
||||||
new_path[len - 1] = 0x0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,988 +0,0 @@
|
|||||||
diff -Naur curl-7.61.1.orig/lib/http_aws_sigv4.c curl-7.61.1/lib/http_aws_sigv4.c
|
|
||||||
--- curl-7.61.1.orig/lib/http_aws_sigv4.c 1970-01-01 01:00:00.000000000 +0100
|
|
||||||
+++ curl-7.61.1/lib/http_aws_sigv4.c 2025-12-02 13:31:38.991776478 +0100
|
|
||||||
@@ -0,0 +1,511 @@
|
|
||||||
+/***************************************************************************
|
|
||||||
+ * _ _ ____ _
|
|
||||||
+ * Project ___| | | | _ \| |
|
|
||||||
+ * / __| | | | |_) | |
|
|
||||||
+ * | (__| |_| | _ <| |___
|
|
||||||
+ * \___|\___/|_| \_\_____|
|
|
||||||
+ *
|
|
||||||
+ * Copyright (C) 1998 - 2021, 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.haxx.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.
|
|
||||||
+ *
|
|
||||||
+ ***************************************************************************/
|
|
||||||
+
|
|
||||||
+#include "curl_setup.h"
|
|
||||||
+
|
|
||||||
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
|
||||||
+
|
|
||||||
+#define USE_AWS_SIGV4
|
|
||||||
+
|
|
||||||
+#include "urldata.h"
|
|
||||||
+#include "strcase.h"
|
|
||||||
+#include "strdup.h"
|
|
||||||
+#include "vauth/vauth.h"
|
|
||||||
+#include "vauth/digest.h"
|
|
||||||
+#include "http_aws_sigv4.h"
|
|
||||||
+#include "curl_sha256.h"
|
|
||||||
+#include "curl_hmac.h"
|
|
||||||
+#include "warnless.h"
|
|
||||||
+#include "transfer.h"
|
|
||||||
+
|
|
||||||
+#include "strcase.h"
|
|
||||||
+#include "parsedate.h"
|
|
||||||
+#include "sendf.h"
|
|
||||||
+
|
|
||||||
+#include <time.h>
|
|
||||||
+
|
|
||||||
+/* The last 3 #include files should be in this order */
|
|
||||||
+#include "curl_printf.h"
|
|
||||||
+#include "curl_memory.h"
|
|
||||||
+#include "memdebug.h"
|
|
||||||
+
|
|
||||||
+/* SHA256 Init/Update/Final function pointers for HMAC */
|
|
||||||
+#if defined(USE_OPENSSL)
|
|
||||||
+#include <openssl/sha.h>
|
|
||||||
+#include <openssl/opensslv.h>
|
|
||||||
+#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
|
|
||||||
+#define USE_OPENSSL_SHA256
|
|
||||||
+#endif
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#ifdef USE_OPENSSL_SHA256
|
|
||||||
+static void SHA256_Init_Wrapper(void *context)
|
|
||||||
+{
|
|
||||||
+ SHA256_Init((SHA256_CTX *)context);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void SHA256_Update_Wrapper(void *context,
|
|
||||||
+ const unsigned char *data,
|
|
||||||
+ unsigned int len)
|
|
||||||
+{
|
|
||||||
+ SHA256_Update((SHA256_CTX *)context, data, len);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void SHA256_Final_Wrapper(unsigned char *result, void *context)
|
|
||||||
+{
|
|
||||||
+ SHA256_Final(result, (SHA256_CTX *)context);
|
|
||||||
+}
|
|
||||||
+#else
|
|
||||||
+/* Use internal SHA256 implementation */
|
|
||||||
+typedef struct sha256_state SHA256_CTX;
|
|
||||||
+
|
|
||||||
+static void SHA256_Init_Wrapper(void *context);
|
|
||||||
+static int SHA256_Update_Wrapper_Internal(void *context,
|
|
||||||
+ const unsigned char *data,
|
|
||||||
+ unsigned int len);
|
|
||||||
+static int SHA256_Final_Wrapper_Internal(unsigned char *result,
|
|
||||||
+ void *context);
|
|
||||||
+
|
|
||||||
+static void SHA256_Update_Wrapper(void *context,
|
|
||||||
+ const unsigned char *data,
|
|
||||||
+ unsigned int len)
|
|
||||||
+{
|
|
||||||
+ SHA256_Update_Wrapper_Internal(context, data, len);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void SHA256_Final_Wrapper(unsigned char *result, void *context)
|
|
||||||
+{
|
|
||||||
+ SHA256_Final_Wrapper_Internal(result, context);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/* Forward declarations for internal SHA256 functions */
|
|
||||||
+extern void SHA256_Init(SHA256_CTX *ctx);
|
|
||||||
+extern int SHA256_Update(SHA256_CTX *ctx, const unsigned char *data,
|
|
||||||
+ unsigned int len);
|
|
||||||
+extern int SHA256_Final(unsigned char *out, SHA256_CTX *ctx);
|
|
||||||
+
|
|
||||||
+static void SHA256_Init_Wrapper(void *context)
|
|
||||||
+{
|
|
||||||
+ SHA256_Init((SHA256_CTX *)context);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int SHA256_Update_Wrapper_Internal(void *context,
|
|
||||||
+ const unsigned char *data,
|
|
||||||
+ unsigned int len)
|
|
||||||
+{
|
|
||||||
+ return SHA256_Update((SHA256_CTX *)context, data, len);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int SHA256_Final_Wrapper_Internal(unsigned char *result,
|
|
||||||
+ void *context)
|
|
||||||
+{
|
|
||||||
+ return SHA256_Final(result, (SHA256_CTX *)context);
|
|
||||||
+}
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+/* HMAC-SHA256 parameters for curl 7.61.1 */
|
|
||||||
+static const HMAC_params Curl_HMAC_SHA256[] = {
|
|
||||||
+ {
|
|
||||||
+ CURLX_FUNCTION_CAST(HMAC_hinit_func, SHA256_Init_Wrapper),
|
|
||||||
+ CURLX_FUNCTION_CAST(HMAC_hupdate_func, SHA256_Update_Wrapper),
|
|
||||||
+ CURLX_FUNCTION_CAST(HMAC_hfinal_func, SHA256_Final_Wrapper),
|
|
||||||
+ sizeof(SHA256_CTX),
|
|
||||||
+ 64, /* Maximum key length (block size) */
|
|
||||||
+ 32 /* Result length (SHA256 produces 32 bytes) */
|
|
||||||
+ }
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+#define HMAC_SHA256(k, kl, d, dl, o) \
|
|
||||||
+ do { \
|
|
||||||
+ HMAC_context *hctx = Curl_HMAC_init(Curl_HMAC_SHA256, \
|
|
||||||
+ (unsigned char *)k, \
|
|
||||||
+ (unsigned int)kl); \
|
|
||||||
+ if(!hctx) { \
|
|
||||||
+ ret = CURLE_OUT_OF_MEMORY; \
|
|
||||||
+ goto fail; \
|
|
||||||
+ } \
|
|
||||||
+ Curl_HMAC_update(hctx, \
|
|
||||||
+ (unsigned char *)d, \
|
|
||||||
+ (unsigned int)dl); \
|
|
||||||
+ Curl_HMAC_final(hctx, o); \
|
|
||||||
+ } while(0)
|
|
||||||
+
|
|
||||||
+static void sha256_to_hex(char *dst, unsigned char *sha, size_t dst_l)
|
|
||||||
+{
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ DEBUGASSERT(dst_l >= 65);
|
|
||||||
+ for(i = 0; i < 32; ++i) {
|
|
||||||
+ curl_msnprintf(dst + (i * 2), dst_l - (i * 2), "%02x", sha[i]);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+CURLcode Curl_output_aws_sigv4(struct connectdata *conn, bool proxy)
|
|
||||||
+{
|
|
||||||
+ CURLcode ret = CURLE_OUT_OF_MEMORY;
|
|
||||||
+ struct Curl_easy *data = conn->data;
|
|
||||||
+ size_t len;
|
|
||||||
+ const char *tmp0;
|
|
||||||
+ const char *tmp1;
|
|
||||||
+ char *provider0_low = NULL;
|
|
||||||
+ char *provider0_up = NULL;
|
|
||||||
+ char *provider1_low = NULL;
|
|
||||||
+ char *provider1_mid = NULL;
|
|
||||||
+ char *region = NULL;
|
|
||||||
+ char *service = NULL;
|
|
||||||
+ const char *hostname = conn->host.name;
|
|
||||||
+#ifdef DEBUGBUILD
|
|
||||||
+ char *force_timestamp;
|
|
||||||
+#endif
|
|
||||||
+ time_t clock;
|
|
||||||
+ struct tm tm;
|
|
||||||
+ char timestamp[17];
|
|
||||||
+ char date[9];
|
|
||||||
+ const char *content_type = Curl_checkheaders(conn, "Content-Type");
|
|
||||||
+ char *canonical_headers = NULL;
|
|
||||||
+ char *signed_headers = NULL;
|
|
||||||
+ Curl_HttpReq httpreq;
|
|
||||||
+ const char *method = NULL;
|
|
||||||
+ const char *post_data = data->set.postfields ? data->set.postfields : "";
|
|
||||||
+ unsigned char sha_hash[32];
|
|
||||||
+ char sha_hex[65];
|
|
||||||
+ char *canonical_request = NULL;
|
|
||||||
+ char *request_type = NULL;
|
|
||||||
+ char *credential_scope = NULL;
|
|
||||||
+ char *str_to_sign = NULL;
|
|
||||||
+ const char *user = data->state.aptr.user ? data->state.aptr.user : "";
|
|
||||||
+ const char *passwd = data->state.aptr.passwd ? data->state.aptr.passwd : "";
|
|
||||||
+ char *secret = NULL;
|
|
||||||
+ unsigned char tmp_sign0[32] = {0};
|
|
||||||
+ unsigned char tmp_sign1[32] = {0};
|
|
||||||
+ char *auth_headers = NULL;
|
|
||||||
+
|
|
||||||
+ DEBUGASSERT(!proxy);
|
|
||||||
+ (void)proxy;
|
|
||||||
+
|
|
||||||
+ if(Curl_checkheaders(conn, "Authorization")) {
|
|
||||||
+ /* Authorization already present, Bailing out */
|
|
||||||
+ return CURLE_OK;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Parameters parsing
|
|
||||||
+ * Google and Outscale use the same OSC or GOOG,
|
|
||||||
+ * but Amazon uses AWS and AMZ for header arguments.
|
|
||||||
+ * AWS is the default because most of non-amazon providers
|
|
||||||
+ * are still using aws:amz as a prefix.
|
|
||||||
+ */
|
|
||||||
+ tmp0 = data->set.str[STRING_AWS_SIGV4] ?
|
|
||||||
+ data->set.str[STRING_AWS_SIGV4] : "aws:amz";
|
|
||||||
+ tmp1 = strchr(tmp0, ':');
|
|
||||||
+ len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0);
|
|
||||||
+ if(len < 1) {
|
|
||||||
+ infof(data, "first provider can't be empty\n");
|
|
||||||
+ ret = CURLE_BAD_FUNCTION_ARGUMENT;
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ provider0_low = malloc(len + 1);
|
|
||||||
+ provider0_up = malloc(len + 1);
|
|
||||||
+ if(!provider0_low || !provider0_up) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ Curl_strntolower(provider0_low, tmp0, len);
|
|
||||||
+ provider0_low[len] = '\0';
|
|
||||||
+ Curl_strntoupper(provider0_up, tmp0, len);
|
|
||||||
+ provider0_up[len] = '\0';
|
|
||||||
+
|
|
||||||
+ if(tmp1) {
|
|
||||||
+ tmp0 = tmp1 + 1;
|
|
||||||
+ tmp1 = strchr(tmp0, ':');
|
|
||||||
+ len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0);
|
|
||||||
+ if(len < 1) {
|
|
||||||
+ infof(data, "second provider can't be empty\n");
|
|
||||||
+ ret = CURLE_BAD_FUNCTION_ARGUMENT;
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ provider1_low = malloc(len + 1);
|
|
||||||
+ provider1_mid = malloc(len + 1);
|
|
||||||
+ if(!provider1_low || !provider1_mid) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ Curl_strntolower(provider1_low, tmp0, len);
|
|
||||||
+ provider1_low[len] = '\0';
|
|
||||||
+ Curl_strntolower(provider1_mid, tmp0, len);
|
|
||||||
+ provider1_mid[0] = Curl_raw_toupper(provider1_mid[0]);
|
|
||||||
+ provider1_mid[len] = '\0';
|
|
||||||
+
|
|
||||||
+ if(tmp1) {
|
|
||||||
+ tmp0 = tmp1 + 1;
|
|
||||||
+ tmp1 = strchr(tmp0, ':');
|
|
||||||
+ len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0);
|
|
||||||
+ if(len < 1) {
|
|
||||||
+ infof(data, "region can't be empty\n");
|
|
||||||
+ ret = CURLE_BAD_FUNCTION_ARGUMENT;
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ region = Curl_memdup(tmp0, len + 1);
|
|
||||||
+ if(!region) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ region[len] = '\0';
|
|
||||||
+
|
|
||||||
+ if(tmp1) {
|
|
||||||
+ tmp0 = tmp1 + 1;
|
|
||||||
+ service = strdup(tmp0);
|
|
||||||
+ if(!service) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ if(strlen(service) < 1) {
|
|
||||||
+ infof(data, "service can't be empty\n");
|
|
||||||
+ ret = CURLE_BAD_FUNCTION_ARGUMENT;
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ else {
|
|
||||||
+ provider1_low = Curl_memdup(provider0_low, len + 1);
|
|
||||||
+ provider1_mid = Curl_memdup(provider0_low, len + 1);
|
|
||||||
+ if(!provider1_low || !provider1_mid) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ provider1_mid[0] = Curl_raw_toupper(provider1_mid[0]);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if(!service) {
|
|
||||||
+ tmp0 = hostname;
|
|
||||||
+ tmp1 = strchr(tmp0, '.');
|
|
||||||
+ len = tmp1 - tmp0;
|
|
||||||
+ if(!tmp1 || len < 1) {
|
|
||||||
+ infof(data, "service missing in parameters or hostname\n");
|
|
||||||
+ ret = CURLE_URL_MALFORMAT;
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ service = Curl_memdup(tmp0, len + 1);
|
|
||||||
+ if(!service) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ service[len] = '\0';
|
|
||||||
+
|
|
||||||
+ if(!region) {
|
|
||||||
+ tmp0 = tmp1 + 1;
|
|
||||||
+ tmp1 = strchr(tmp0, '.');
|
|
||||||
+ len = tmp1 - tmp0;
|
|
||||||
+ if(!tmp1 || len < 1) {
|
|
||||||
+ infof(data, "region missing in parameters or hostname\n");
|
|
||||||
+ ret = CURLE_URL_MALFORMAT;
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ region = Curl_memdup(tmp0, len + 1);
|
|
||||||
+ if(!region) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ region[len] = '\0';
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+#ifdef DEBUGBUILD
|
|
||||||
+ force_timestamp = getenv("CURL_FORCETIME");
|
|
||||||
+ if(force_timestamp)
|
|
||||||
+ clock = 0;
|
|
||||||
+ else
|
|
||||||
+ time(&clock);
|
|
||||||
+#else
|
|
||||||
+ time(&clock);
|
|
||||||
+#endif
|
|
||||||
+ ret = Curl_gmtime(clock, &tm);
|
|
||||||
+ if(ret != CURLE_OK) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ if(!strftime(timestamp, sizeof(timestamp), "%Y%m%dT%H%M%SZ", &tm)) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ memcpy(date, timestamp, sizeof(date));
|
|
||||||
+ date[sizeof(date) - 1] = 0;
|
|
||||||
+
|
|
||||||
+ if(content_type) {
|
|
||||||
+ content_type = strchr(content_type, ':');
|
|
||||||
+ if(!content_type) {
|
|
||||||
+ ret = CURLE_FAILED_INIT;
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ content_type++;
|
|
||||||
+ /* Skip whitespace now */
|
|
||||||
+ while(*content_type == ' ' || *content_type == '\t')
|
|
||||||
+ ++content_type;
|
|
||||||
+
|
|
||||||
+ canonical_headers = curl_maprintf("content-type:%s\n"
|
|
||||||
+ "host:%s\n"
|
|
||||||
+ "x-%s-date:%s\n",
|
|
||||||
+ content_type,
|
|
||||||
+ hostname,
|
|
||||||
+ provider1_low, timestamp);
|
|
||||||
+ signed_headers = curl_maprintf("content-type;host;x-%s-date",
|
|
||||||
+ provider1_low);
|
|
||||||
+ }
|
|
||||||
+ else {
|
|
||||||
+ canonical_headers = curl_maprintf("host:%s\n"
|
|
||||||
+ "x-%s-date:%s\n",
|
|
||||||
+ hostname,
|
|
||||||
+ provider1_low, timestamp);
|
|
||||||
+ signed_headers = curl_maprintf("host;x-%s-date", provider1_low);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if(!canonical_headers || !signed_headers) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ Curl_sha256it(sha_hash,
|
|
||||||
+ (const unsigned char *) post_data, strlen(post_data));
|
|
||||||
+ sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex));
|
|
||||||
+
|
|
||||||
+ /* Determine HTTP method - curl 7.61.1 style */
|
|
||||||
+ httpreq = data->set.httpreq;
|
|
||||||
+ switch(httpreq) {
|
|
||||||
+ case HTTPREQ_GET:
|
|
||||||
+ method = "GET";
|
|
||||||
+ break;
|
|
||||||
+ case HTTPREQ_POST:
|
|
||||||
+ case HTTPREQ_POST_FORM:
|
|
||||||
+ case HTTPREQ_POST_MIME:
|
|
||||||
+ method = "POST";
|
|
||||||
+ break;
|
|
||||||
+ case HTTPREQ_PUT:
|
|
||||||
+ method = "PUT";
|
|
||||||
+ break;
|
|
||||||
+ case HTTPREQ_HEAD:
|
|
||||||
+ method = "HEAD";
|
|
||||||
+ break;
|
|
||||||
+ case HTTPREQ_OPTIONS:
|
|
||||||
+ method = "OPTIONS";
|
|
||||||
+ break;
|
|
||||||
+ case HTTPREQ_CUSTOM:
|
|
||||||
+ method = data->set.customrequest;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ method = "GET";
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ canonical_request =
|
|
||||||
+ curl_maprintf("%s\n" /* HTTPRequestMethod */
|
|
||||||
+ "%s\n" /* CanonicalURI */
|
|
||||||
+ "%s\n" /* CanonicalQueryString */
|
|
||||||
+ "%s\n" /* CanonicalHeaders */
|
|
||||||
+ "%s\n" /* SignedHeaders */
|
|
||||||
+ "%s", /* HashedRequestPayload in hex */
|
|
||||||
+ method,
|
|
||||||
+ data->state.up.path,
|
|
||||||
+ data->state.up.query ? data->state.up.query : "",
|
|
||||||
+ canonical_headers,
|
|
||||||
+ signed_headers,
|
|
||||||
+ sha_hex);
|
|
||||||
+ if(!canonical_request) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ request_type = curl_maprintf("%s4_request", provider0_low);
|
|
||||||
+ if(!request_type) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ credential_scope = curl_maprintf("%s/%s/%s/%s",
|
|
||||||
+ date, region, service, request_type);
|
|
||||||
+ if(!credential_scope) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ Curl_sha256it(sha_hash, (unsigned char *) canonical_request,
|
|
||||||
+ strlen(canonical_request));
|
|
||||||
+ sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex));
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Google allow to use rsa key instead of HMAC, so this code might change
|
|
||||||
+ * In the furure, but for now we support only HMAC version
|
|
||||||
+ */
|
|
||||||
+ str_to_sign = curl_maprintf("%s4-HMAC-SHA256\n" /* Algorithm */
|
|
||||||
+ "%s\n" /* RequestDateTime */
|
|
||||||
+ "%s\n" /* CredentialScope */
|
|
||||||
+ "%s", /* HashedCanonicalRequest in hex */
|
|
||||||
+ provider0_up,
|
|
||||||
+ timestamp,
|
|
||||||
+ credential_scope,
|
|
||||||
+ sha_hex);
|
|
||||||
+ if(!str_to_sign) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ secret = curl_maprintf("%s4%s", provider0_up, passwd);
|
|
||||||
+ if(!secret) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ HMAC_SHA256(secret, strlen(secret),
|
|
||||||
+ date, strlen(date), tmp_sign0);
|
|
||||||
+ HMAC_SHA256(tmp_sign0, sizeof(tmp_sign0),
|
|
||||||
+ region, strlen(region), tmp_sign1);
|
|
||||||
+ HMAC_SHA256(tmp_sign1, sizeof(tmp_sign1),
|
|
||||||
+ service, strlen(service), tmp_sign0);
|
|
||||||
+ HMAC_SHA256(tmp_sign0, sizeof(tmp_sign0),
|
|
||||||
+ request_type, strlen(request_type), tmp_sign1);
|
|
||||||
+ HMAC_SHA256(tmp_sign1, sizeof(tmp_sign1),
|
|
||||||
+ str_to_sign, strlen(str_to_sign), tmp_sign0);
|
|
||||||
+
|
|
||||||
+ sha256_to_hex(sha_hex, tmp_sign0, sizeof(sha_hex));
|
|
||||||
+
|
|
||||||
+ auth_headers = curl_maprintf("Authorization: %s4-HMAC-SHA256 "
|
|
||||||
+ "Credential=%s/%s, "
|
|
||||||
+ "SignedHeaders=%s, "
|
|
||||||
+ "Signature=%s\r\n"
|
|
||||||
+ "X-%s-Date: %s\r\n",
|
|
||||||
+ provider0_up,
|
|
||||||
+ user,
|
|
||||||
+ credential_scope,
|
|
||||||
+ signed_headers,
|
|
||||||
+ sha_hex,
|
|
||||||
+ provider1_mid,
|
|
||||||
+ timestamp);
|
|
||||||
+ if(!auth_headers) {
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ Curl_safefree(data->state.aptr.userpwd);
|
|
||||||
+ data->state.aptr.userpwd = auth_headers;
|
|
||||||
+ data->state.authhost.done = TRUE;
|
|
||||||
+ ret = CURLE_OK;
|
|
||||||
+
|
|
||||||
+fail:
|
|
||||||
+ free(provider0_low);
|
|
||||||
+ free(provider0_up);
|
|
||||||
+ free(provider1_low);
|
|
||||||
+ free(provider1_mid);
|
|
||||||
+ free(region);
|
|
||||||
+ free(service);
|
|
||||||
+ free(canonical_headers);
|
|
||||||
+ free(signed_headers);
|
|
||||||
+ free(canonical_request);
|
|
||||||
+ free(request_type);
|
|
||||||
+ free(credential_scope);
|
|
||||||
+ free(str_to_sign);
|
|
||||||
+ free(secret);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#endif /* !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) */
|
|
||||||
diff -Naur curl-7.61.1.orig/lib/http_aws_sigv4.h curl-7.61.1/lib/http_aws_sigv4.h
|
|
||||||
--- curl-7.61.1.orig/lib/http_aws_sigv4.h 1970-01-01 01:00:00.000000000 +0100
|
|
||||||
+++ curl-7.61.1/lib/http_aws_sigv4.h 2025-12-02 13:31:38.992776500 +0100
|
|
||||||
@@ -0,0 +1,29 @@
|
|
||||||
+#ifndef HEADER_CURL_HTTP_AWS_SIGV4_H
|
|
||||||
+#define HEADER_CURL_HTTP_AWS_SIGV4_H
|
|
||||||
+/***************************************************************************
|
|
||||||
+ * _ _ ____ _
|
|
||||||
+ * Project ___| | | | _ \| |
|
|
||||||
+ * / __| | | | |_) | |
|
|
||||||
+ * | (__| |_| | _ <| |___
|
|
||||||
+ * \___|\___/|_| \_\_____|
|
|
||||||
+ *
|
|
||||||
+ * Copyright (C) 1998 - 2024, Daniel Stenberg, <daniel@haxx.se>, et al.
|
|
||||||
+ *
|
|
||||||
+ * AWS SigV4 Support - Backport to RHEL 8
|
|
||||||
+ *
|
|
||||||
+ ***************************************************************************/
|
|
||||||
+
|
|
||||||
+#include "curl_setup.h"
|
|
||||||
+
|
|
||||||
+#ifdef USE_AWS_SIGV4
|
|
||||||
+
|
|
||||||
+/* AWS SigV4 authentication function */
|
|
||||||
+CURLcode Curl_output_aws_sigv4(struct connectdata *conn, bool proxy);
|
|
||||||
+
|
|
||||||
+#else
|
|
||||||
+
|
|
||||||
+#define Curl_output_aws_sigv4(x,y) CURLE_NOT_BUILT_IN
|
|
||||||
+
|
|
||||||
+#endif /* USE_AWS_SIGV4 */
|
|
||||||
+
|
|
||||||
+#endif /* HEADER_CURL_HTTP_AWS_SIGV4_H */
|
|
||||||
diff -Naur curl-7.61.1.orig/lib/Makefile.inc curl-7.61.1/lib/Makefile.inc
|
|
||||||
--- curl-7.61.1.orig/lib/Makefile.inc 2025-12-02 13:31:37.675747831 +0100
|
|
||||||
+++ curl-7.61.1/lib/Makefile.inc 2025-12-02 13:31:40.198802751 +0100
|
|
||||||
@@ -54,7 +54,7 @@
|
|
||||||
curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \
|
|
||||||
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \
|
|
||||||
mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \
|
|
||||||
- urlapi.c
|
|
||||||
+ urlapi.c http_aws_sigv4.c
|
|
||||||
|
|
||||||
LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
|
|
||||||
formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
|
|
||||||
@@ -74,7 +74,8 @@
|
|
||||||
curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \
|
|
||||||
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
|
|
||||||
curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \
|
|
||||||
- curl_path.h curl_ctype.h curl_range.h psl.h urlapi-int.h
|
|
||||||
+ curl_path.h curl_ctype.h curl_range.h psl.h urlapi-int.h \
|
|
||||||
+ http_aws_sigv4.h
|
|
||||||
|
|
||||||
LIB_RCFILES = libcurl.rc
|
|
||||||
|
|
||||||
diff -Naur curl-7.61.1.orig/lib/openldap.c curl-7.61.1/lib/openldap.c
|
|
||||||
--- curl-7.61.1.orig/lib/openldap.c 2025-12-02 13:31:37.681747962 +0100
|
|
||||||
+++ curl-7.61.1/lib/openldap.c 2025-12-02 13:31:41.175824017 +0100
|
|
||||||
@@ -79,8 +79,8 @@
|
|
||||||
static CURLcode ldap_setup_connection(struct connectdata *conn);
|
|
||||||
static CURLcode ldap_do(struct connectdata *conn, bool *done);
|
|
||||||
static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool);
|
|
||||||
-static CURLcode ldap_connect(struct connectdata *conn, bool *done);
|
|
||||||
-static CURLcode ldap_connecting(struct connectdata *conn, bool *done);
|
|
||||||
+static CURLcode oldap_connect(struct connectdata *conn, bool *done);
|
|
||||||
+static CURLcode ooldap_connecting(struct connectdata *conn, bool *done);
|
|
||||||
static CURLcode ldap_disconnect(struct connectdata *conn, bool dead);
|
|
||||||
|
|
||||||
static Curl_recv ldap_recv;
|
|
||||||
@@ -95,8 +95,8 @@
|
|
||||||
ldap_do, /* do_it */
|
|
||||||
ldap_done, /* done */
|
|
||||||
ZERO_NULL, /* do_more */
|
|
||||||
- ldap_connect, /* connect_it */
|
|
||||||
- ldap_connecting, /* connecting */
|
|
||||||
+ oldap_connect, /* connect_it */
|
|
||||||
+ ooldap_connecting, /* connecting */
|
|
||||||
ZERO_NULL, /* doing */
|
|
||||||
ZERO_NULL, /* proto_getsock */
|
|
||||||
ZERO_NULL, /* doing_getsock */
|
|
||||||
@@ -121,8 +121,8 @@
|
|
||||||
ldap_do, /* do_it */
|
|
||||||
ldap_done, /* done */
|
|
||||||
ZERO_NULL, /* do_more */
|
|
||||||
- ldap_connect, /* connect_it */
|
|
||||||
- ldap_connecting, /* connecting */
|
|
||||||
+ oldap_connect, /* connect_it */
|
|
||||||
+ ooldap_connecting, /* connecting */
|
|
||||||
ZERO_NULL, /* doing */
|
|
||||||
ZERO_NULL, /* proto_getsock */
|
|
||||||
ZERO_NULL, /* doing_getsock */
|
|
||||||
@@ -206,7 +206,7 @@
|
|
||||||
static Sockbuf_IO ldapsb_tls;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-static CURLcode ldap_connect(struct connectdata *conn, bool *done)
|
|
||||||
+static CURLcode oldap_connect(struct connectdata *conn, bool *done)
|
|
||||||
{
|
|
||||||
ldapconninfo *li = conn->proto.generic;
|
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
@@ -253,7 +253,7 @@
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
|
|
||||||
+static CURLcode ooldap_connecting(struct connectdata *conn, bool *done)
|
|
||||||
{
|
|
||||||
ldapconninfo *li = conn->proto.generic;
|
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
diff -Naur curl-7.61.1.orig/lib/http.c curl-7.61.1/lib/http.c
|
|
||||||
--- curl-7.61.1.orig/lib/http.c 2025-12-05 12:00:00.000000000 +0100
|
|
||||||
+++ curl-7.61.1/lib/http.c 2025-12-05 12:30:00.000000000 +0100
|
|
||||||
@@ -60,6 +60,7 @@
|
|
||||||
#include "http_ntlm.h"
|
|
||||||
#include "curl_ntlm_wb.h"
|
|
||||||
#include "http_negotiate.h"
|
|
||||||
+#include "http_aws_sigv4.h"
|
|
||||||
#include "url.h"
|
|
||||||
#include "share.h"
|
|
||||||
#include "hostip.h"
|
|
||||||
@@ -362,6 +363,8 @@
|
|
||||||
pick->picked = CURLAUTH_NTLM_WB;
|
|
||||||
else if(avail & CURLAUTH_BASIC)
|
|
||||||
pick->picked = CURLAUTH_BASIC;
|
|
||||||
+ else if(avail & CURLAUTH_AWS_SIGV4)
|
|
||||||
+ pick->picked = CURLAUTH_AWS_SIGV4;
|
|
||||||
else {
|
|
||||||
pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
|
|
||||||
picked = FALSE;
|
|
||||||
@@ -682,6 +685,21 @@
|
|
||||||
functions work that way */
|
|
||||||
authstatus->done = TRUE;
|
|
||||||
}
|
|
||||||
+ if(authstatus->picked == CURLAUTH_AWS_SIGV4) {
|
|
||||||
+ /* AWS SigV4 */
|
|
||||||
+ if((!proxy && data->set.str[STRING_AWS_SIGV4] &&
|
|
||||||
+ !Curl_checkheaders(conn, "Authorization:"))) {
|
|
||||||
+ auth = "AWS_SIGV4";
|
|
||||||
+ result = Curl_output_aws_sigv4(conn, FALSE);
|
|
||||||
+ if(result)
|
|
||||||
+ return result;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* NOTE: this function should set 'done' TRUE, as the other auth
|
|
||||||
+ functions work that way */
|
|
||||||
+ authstatus->done = TRUE;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
|
|
||||||
if(auth) {
|
|
||||||
infof(data, "%s auth using %s with user '%s'\n",
|
|
||||||
diff -Naur curl-7.61.1.orig/include/curl/curl.h curl-7.61.1/include/curl/curl.h
|
|
||||||
--- curl-7.61.1.orig/include/curl/curl.h 2018-07-11 07:17:00.000000000 +0200
|
|
||||||
+++ curl-7.61.1/include/curl/curl.h 2025-12-10 14:00:00.000000000 +0100
|
|
||||||
@@ -710,6 +710,7 @@
|
|
||||||
#define CURLAUTH_NTLM (((unsigned long)1)<<3)
|
|
||||||
#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4)
|
|
||||||
#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
|
|
||||||
+#define CURLAUTH_AWS_SIGV4 (((unsigned long)1)<<7)
|
|
||||||
#define CURLAUTH_BEARER (((unsigned long)1)<<6)
|
|
||||||
#define CURLAUTH_ONLY (((unsigned long)1)<<31)
|
|
||||||
#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
|
|
||||||
@@ -1856,6 +1857,9 @@
|
|
||||||
/* Disallow specifying username/login in URL. */
|
|
||||||
CINIT(DISALLOW_USERNAME_IN_URL, LONG, 278),
|
|
||||||
|
|
||||||
+ /* AWS HTTP V4 Signature */
|
|
||||||
+ CINIT(AWS_SIGV4, STRINGPOINT, 279),
|
|
||||||
+
|
|
||||||
CURLOPT_LASTENTRY /* the last unused */
|
|
||||||
} CURLoption;
|
|
||||||
|
|
||||||
--- curl-7.61.1.orig/lib/urldata.h 2018-07-11 07:17:00.000000000 +0200
|
|
||||||
+++ curl-7.61.1/lib/urldata.h 2025-12-09 00:00:00.000000000 +0100
|
|
||||||
@@ -1414,6 +1414,7 @@
|
|
||||||
STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth <password> */
|
|
||||||
#endif
|
|
||||||
STRING_BEARER, /* <bearer>, if used */
|
|
||||||
+ STRING_AWS_SIGV4, /* <aws-sigv4>, if used */
|
|
||||||
#ifdef USE_UNIX_SOCKETS
|
|
||||||
STRING_UNIX_SOCKET_PATH, /* path to Unix socket, if used */
|
|
||||||
#endif
|
|
||||||
diff -Naur curl-7.61.1.orig/lib/http_aws_sigv4.c curl-7.61.1/lib/http_aws_sigv4.c
|
|
||||||
--- curl-7.61.1.orig/lib/http_aws_sigv4.c 2025-12-09 07:00:00.000000000 +0100
|
|
||||||
+++ curl-7.61.1/lib/http_aws_sigv4.c 2025-12-09 14:30:00.000000000 +0100
|
|
||||||
@@ -192,8 +192,8 @@
|
|
||||||
char *request_type = NULL;
|
|
||||||
char *credential_scope = NULL;
|
|
||||||
char *str_to_sign = NULL;
|
|
||||||
- const char *user = data->state.aptr.user ? data->state.aptr.user : "";
|
|
||||||
- const char *passwd = data->state.aptr.passwd ? data->state.aptr.passwd : "";
|
|
||||||
+ const char *user = conn->user ? conn->user : "";
|
|
||||||
+ const char *passwd = conn->passwd ? conn->passwd : "";
|
|
||||||
char *secret = NULL;
|
|
||||||
unsigned char tmp_sign0[32] = {0};
|
|
||||||
unsigned char tmp_sign1[32] = {0};
|
|
||||||
@@ -399,7 +399,7 @@
|
|
||||||
method = "OPTIONS";
|
|
||||||
break;
|
|
||||||
case HTTPREQ_CUSTOM:
|
|
||||||
- method = data->set.customrequest;
|
|
||||||
+ method = data->set.str[STRING_CUSTOMREQUEST];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
method = "GET";
|
|
||||||
@@ -406,6 +406,16 @@
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* Extract query string from path if present */
|
|
||||||
+ const char *query_str = NULL;
|
|
||||||
+ char *question_mark = strchr(data->state.path, '?');
|
|
||||||
+ if(question_mark) {
|
|
||||||
+ query_str = question_mark + 1;
|
|
||||||
+ }
|
|
||||||
+ else {
|
|
||||||
+ query_str = "";
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
canonical_request =
|
|
||||||
curl_maprintf("%s\n" /* HTTPRequestMethod */
|
|
||||||
"%s\n" /* CanonicalURI */
|
|
||||||
@@ -414,8 +424,8 @@
|
|
||||||
"%s\n" /* SignedHeaders */
|
|
||||||
"%s", /* HashedRequestPayload in hex */
|
|
||||||
method,
|
|
||||||
- data->state.up.path,
|
|
||||||
- data->state.up.query ? data->state.up.query : "",
|
|
||||||
+ data->state.path,
|
|
||||||
+ query_str,
|
|
||||||
canonical_headers,
|
|
||||||
signed_headers,
|
|
||||||
sha_hex);
|
|
||||||
@@ -488,8 +498,8 @@
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
- Curl_safefree(data->state.aptr.userpwd);
|
|
||||||
- data->state.aptr.userpwd = auth_headers;
|
|
||||||
+ Curl_safefree(conn->allocptr.userpwd);
|
|
||||||
+ conn->allocptr.userpwd = auth_headers;
|
|
||||||
data->state.authhost.done = TRUE;
|
|
||||||
ret = CURLE_OK;
|
|
||||||
|
|
||||||
@@ -509,3 +519,5 @@
|
|
||||||
free(secret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+#endif /* !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) */
|
|
||||||
diff -Naur a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
|
|
||||||
--- a/docs/libcurl/symbols-in-versions 2018-09-04 22:48:37.000000000 +0200
|
|
||||||
+++ b/docs/libcurl/symbols-in-versions 2025-12-10 14:23:34.178991689 +0100
|
|
||||||
@@ -15,6 +15,7 @@
|
|
||||||
CURLAUTH_ANY 7.10.6
|
|
||||||
CURLAUTH_ANYSAFE 7.10.6
|
|
||||||
CURLAUTH_BASIC 7.10.6
|
|
||||||
+CURLAUTH_AWS_SIGV4 7.61.1
|
|
||||||
CURLAUTH_BEARER 7.61.0
|
|
||||||
CURLAUTH_DIGEST 7.10.6
|
|
||||||
CURLAUTH_DIGEST_IE 7.19.3
|
|
||||||
@@ -344,6 +345,7 @@
|
|
||||||
CURLOPT_ACCEPT_ENCODING 7.21.6
|
|
||||||
CURLOPT_ADDRESS_SCOPE 7.19.0
|
|
||||||
CURLOPT_APPEND 7.17.0
|
|
||||||
+CURLOPT_AWS_SIGV4 7.61.1
|
|
||||||
CURLOPT_AUTOREFERER 7.1
|
|
||||||
CURLOPT_BUFFERSIZE 7.10
|
|
||||||
CURLOPT_CAINFO 7.4.2
|
|
||||||
diff -Naur a/lib/setopt.c b/lib/setopt.c
|
|
||||||
--- a/lib/setopt.c 2025-12-02 13:31:37.682747984 +0100
|
|
||||||
+++ b/lib/setopt.c 2025-12-10 12:46:02.532544111 +0100
|
|
||||||
@@ -618,6 +618,20 @@
|
|
||||||
data->set.httpreq = HTTPREQ_POST_FORM;
|
|
||||||
data->set.opt_no_body = FALSE; /* this is implied */
|
|
||||||
break;
|
|
||||||
+
|
|
||||||
+ case CURLOPT_AWS_SIGV4:
|
|
||||||
+ /*
|
|
||||||
+ * String that is merged to some authentication
|
|
||||||
+ * parameters are used by the algorithm.
|
|
||||||
+ */
|
|
||||||
+ result = Curl_setstropt(&data->set.str[STRING_AWS_SIGV4],
|
|
||||||
+ va_arg(param, char *));
|
|
||||||
+ /*
|
|
||||||
+ * Basic been set by default it need to be unset here
|
|
||||||
+ */
|
|
||||||
+ if(data->set.str[STRING_AWS_SIGV4])
|
|
||||||
+ data->set.httpauth = CURLAUTH_AWS_SIGV4;
|
|
||||||
+ break;
|
|
||||||
#endif /* CURL_DISABLE_HTTP */
|
|
||||||
|
|
||||||
case CURLOPT_MIMEPOST:
|
|
||||||
diff -Naur a/src/tool_cfgable.c b/src/tool_cfgable.c
|
|
||||||
--- a/src/tool_cfgable.c 2025-12-02 13:31:37.707011250 +0100
|
|
||||||
+++ b/src/tool_cfgable.c 2025-12-10 12:33:54.247212425 +0100
|
|
||||||
@@ -130,6 +130,7 @@
|
|
||||||
Curl_safefree(config->krblevel);
|
|
||||||
|
|
||||||
Curl_safefree(config->oauth_bearer);
|
|
||||||
+ Curl_safefree(config->aws_sigv4);
|
|
||||||
|
|
||||||
Curl_safefree(config->unix_socket_path);
|
|
||||||
Curl_safefree(config->writeout);
|
|
||||||
diff -Naur a/src/tool_cfgable.h b/src/tool_cfgable.h
|
|
||||||
--- a/src/tool_cfgable.h 2025-12-02 13:31:37.707011250 +0100
|
|
||||||
+++ b/src/tool_cfgable.h 2025-12-10 12:33:38.542315604 +0100
|
|
||||||
@@ -240,6 +240,7 @@
|
|
||||||
bool test_event_based;
|
|
||||||
#endif
|
|
||||||
char *oauth_bearer; /* OAuth 2.0 bearer token */
|
|
||||||
+ char *aws_sigv4; /* AWS Signature Version 4 */
|
|
||||||
bool nonpn; /* enable/disable TLS NPN extension */
|
|
||||||
bool noalpn; /* enable/disable TLS ALPN extension */
|
|
||||||
char *unix_socket_path; /* path to Unix domain socket */
|
|
||||||
diff -Naur a/src/tool_getparam.c b/src/tool_getparam.c
|
|
||||||
--- a/src/tool_getparam.c 2025-12-02 13:31:37.711748615 +0100
|
|
||||||
+++ b/src/tool_getparam.c 2025-12-10 12:36:24.374195746 +0100
|
|
||||||
@@ -79,6 +79,7 @@
|
|
||||||
{"*a", "random-file", ARG_FILENAME},
|
|
||||||
{"*b", "egd-file", ARG_STRING},
|
|
||||||
{"*B", "oauth2-bearer", ARG_STRING},
|
|
||||||
+ {"*V", "aws-sigv4", ARG_STRING},
|
|
||||||
{"*c", "connect-timeout", ARG_STRING},
|
|
||||||
{"*d", "ciphers", ARG_STRING},
|
|
||||||
{"*D", "dns-interface", ARG_STRING},
|
|
||||||
@@ -813,6 +814,10 @@
|
|
||||||
config->disable_eprt = toggle;
|
|
||||||
break;
|
|
||||||
case 'Z': /* --eprt */
|
|
||||||
+ case 'V': /* --aws-sigv4 */
|
|
||||||
+ GetStr(&config->aws_sigv4, nextarg);
|
|
||||||
+ config->authtype |= CURLAUTH_AWS_SIGV4;
|
|
||||||
+ break;
|
|
||||||
config->disable_eprt = (!toggle)?TRUE:FALSE;
|
|
||||||
break;
|
|
||||||
case '~': /* --xattr */
|
|
||||||
diff -Naur a/src/tool_help.c b/src/tool_help.c
|
|
||||||
--- a/src/tool_help.c 2025-12-02 13:31:37.709748572 +0100
|
|
||||||
+++ b/src/tool_help.c 2025-12-10 12:39:33.200888878 +0100
|
|
||||||
@@ -52,6 +52,8 @@
|
|
||||||
"Pick any authentication method"},
|
|
||||||
{"-a, --append",
|
|
||||||
"Append to target file when uploading"},
|
|
||||||
+ {" --aws-sigv4 <provider1[:provider2[:region[:service]]]>",
|
|
||||||
+ "Use AWS V4 signature authentication"},
|
|
||||||
{" --basic",
|
|
||||||
"Use HTTP Basic Authentication"},
|
|
||||||
{" --cacert <file>",
|
|
||||||
diff -Naur a/src/tool_operate.c b/src/tool_operate.c
|
|
||||||
--- a/src/tool_operate.c 2025-12-02 13:31:37.711748615 +0100
|
|
||||||
+++ b/src/tool_operate.c 2025-12-10 12:40:10.466140413 +0100
|
|
||||||
@@ -1136,6 +1136,8 @@
|
|
||||||
my_setopt_str(curl, CURLOPT_SSLKEYTYPE, config->key_type);
|
|
||||||
my_setopt_str(curl, CURLOPT_PROXY_SSLKEYTYPE,
|
|
||||||
config->proxy_key_type);
|
|
||||||
+ my_setopt_str(curl, CURLOPT_AWS_SIGV4,
|
|
||||||
+ config->aws_sigv4);
|
|
||||||
|
|
||||||
if(config->insecure_ok) {
|
|
||||||
my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
|
||||||
diff -Naur a/docs/curl.1 b/docs/curl.1
|
|
||||||
--- a/docs/curl.1 2018-09-05 08:15:48.000000000 +0200
|
|
||||||
+++ b/docs/curl.1 2025-12-10 12:00:00.000000000 +0100
|
|
||||||
@@ -163,6 +163,12 @@
|
|
||||||
See also \fI--proxy-anyauth\fP and \fI--basic\fP and \fI--digest\fP.
|
|
||||||
.IP "-a, --append"
|
|
||||||
(FTP SFTP) When used in an upload, this makes curl append to the target file instead of
|
|
||||||
+.IP "--aws-sigv4 <service:region>"
|
|
||||||
+(HTTP) Use AWS Signature Version 4 authentication for the specified service and region.
|
|
||||||
+The service is the AWS service name (such as s3) and the region is the geographical
|
|
||||||
+AWS region (such as us-east-1). The credentials must be provided via \fI-u, --user\fP.
|
|
||||||
+
|
|
||||||
+If this option is used several times, the last one will be used.
|
|
||||||
overwriting it. If the remote file doesn't exist, it will be created. Note
|
|
||||||
that this flag is ignored by some SFTP servers (including OpenSSH).
|
|
||||||
.IP "--basic"
|
|
||||||
diff -Naur a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
|
|
||||||
--- a/docs/libcurl/curl_easy_setopt.3 2018-09-05 08:15:48.000000000 +0200
|
|
||||||
+++ b/docs/libcurl/curl_easy_setopt.3 2025-12-10 12:00:00.000000000 +0100
|
|
||||||
@@ -262,6 +262,8 @@
|
|
||||||
.IP CURLOPT_DISALLOW_USERNAME_IN_URL
|
|
||||||
Don't allow username in URL. See \fICURLOPT_DISALLOW_USERNAME_IN_URL(3)\fP
|
|
||||||
.SH HTTP OPTIONS
|
|
||||||
+.IP CURLOPT_AWS_SIGV4
|
|
||||||
+Set AWS Signature Version 4 authentication. See \fICURLOPT_AWS_SIGV4(3)\fP
|
|
||||||
.IP CURLOPT_AUTOREFERER
|
|
||||||
Automatically set Referer: header. See \fICURLOPT_AUTOREFERER(3)\fP
|
|
||||||
.IP CURLOPT_ACCEPT_ENCODING
|
|
||||||
diff -Naur a/docs/libcurl/opts/CURLOPT_AWS_SIGV4.3 b/docs/libcurl/opts/CURLOPT_AWS_SIGV4.3
|
|
||||||
--- a/docs/libcurl/opts/CURLOPT_AWS_SIGV4.3 1970-01-01 00:00:00.000000000 +0000
|
|
||||||
+++ b/docs/libcurl/opts/CURLOPT_AWS_SIGV4.3 2025-12-10 12:00:00.000000000 +0100
|
|
||||||
@@ -0,0 +1,78 @@
|
|
||||||
+.\" **************************************************************************
|
|
||||||
+.\" * _ _ ____ _
|
|
||||||
+.\" * Project ___| | | | _ \| |
|
|
||||||
+.\" * / __| | | | |_) | |
|
|
||||||
+.\" * | (__| |_| | _ <| |___
|
|
||||||
+.\" * \___\|\___/|_| \_\_____|
|
|
||||||
+.\" *
|
|
||||||
+.\" * Copyright (C) 1998 - 2018, 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.haxx.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.
|
|
||||||
+.\" *
|
|
||||||
+.\" **************************************************************************
|
|
||||||
+.\"
|
|
||||||
+.TH CURLOPT_AWS_SIGV4 3 "December 10, 2025" "libcurl 7.61.1" "curl_easy_setopt options"
|
|
||||||
+
|
|
||||||
+.SH NAME
|
|
||||||
+CURLOPT_AWS_SIGV4 \- set AWS Signature Version 4 authentication
|
|
||||||
+.SH SYNOPSIS
|
|
||||||
+.nf
|
|
||||||
+#include <curl/curl.h>
|
|
||||||
+
|
|
||||||
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_AWS_SIGV4, char *param);
|
|
||||||
+.SH DESCRIPTION
|
|
||||||
+Pass a char * that is the collection of service and region parameters that
|
|
||||||
+are used to authorize and sign requests.
|
|
||||||
+
|
|
||||||
+The format is:
|
|
||||||
+.B service:region
|
|
||||||
+where the
|
|
||||||
+.B service
|
|
||||||
+is the AWS service (for example,
|
|
||||||
+.B s3
|
|
||||||
+) and the
|
|
||||||
+.B region
|
|
||||||
+is the geographical AWS region (for example,
|
|
||||||
+.B us-east-1
|
|
||||||
+).
|
|
||||||
+
|
|
||||||
+When this option is set, the HTTP request will be signed using AWS Signature
|
|
||||||
+Version 4. The request is signed using the credentials provided in the
|
|
||||||
+\fICURLOPT_USERNAME(3)\fP and \fICURLOPT_PASSWORD(3)\fP options, which
|
|
||||||
+correspond to the AWS Access Key ID and Secret Access Key, respectively.
|
|
||||||
+
|
|
||||||
+The application does not have to keep the string around after setting this
|
|
||||||
+option.
|
|
||||||
+.SH DEFAULT
|
|
||||||
+NULL
|
|
||||||
+.SH PROTOCOLS
|
|
||||||
+HTTP
|
|
||||||
+.SH EXAMPLE
|
|
||||||
+.nf
|
|
||||||
+CURL *curl = curl_easy_init();
|
|
||||||
+if(curl) {
|
|
||||||
+ curl_easy_setopt(curl, CURLOPT_URL,
|
|
||||||
+ "https://s3.us-east-1.amazonaws.com/bucket/file");
|
|
||||||
+ curl_easy_setopt(curl, CURLOPT_AWS_SIGV4, "s3:us-east-1");
|
|
||||||
+ curl_easy_setopt(curl, CURLOPT_USERNAME, "AKIAIOSFODNN7EXAMPLE");
|
|
||||||
+ curl_easy_setopt(curl, CURLOPT_PASSWORD,
|
|
||||||
+ "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY");
|
|
||||||
+ curl_easy_perform(curl);
|
|
||||||
+}
|
|
||||||
+.SH AVAILABILITY
|
|
||||||
+Added in 7.61.1
|
|
||||||
+.SH RETURN VALUE
|
|
||||||
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
|
|
||||||
+.SH "SEE ALSO"
|
|
||||||
+.BR CURLOPT_HTTPAUTH "(3), "
|
|
||||||
+.BR CURLOPT_USERNAME "(3), "
|
|
||||||
+.BR CURLOPT_PASSWORD "(3), "
|
|
||||||
@ -1,268 +0,0 @@
|
|||||||
From 1e9a538e05c0107c54ef81d9de7cd0b27cd13309 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Stenberg <daniel@haxx.se>
|
|
||||||
Date: Thu, 20 Oct 2022 15:21:12 +0200
|
|
||||||
Subject: [PATCH] noproxy: support proxies specified using cidr notation
|
|
||||||
|
|
||||||
For both IPv4 and IPv6 addresses. Now also checks IPv6 addresses "correctly"
|
|
||||||
and not with string comparisons.
|
|
||||||
|
|
||||||
Backported to curl 7.61.1 for RHEL 8.
|
|
||||||
|
|
||||||
Reported-by: Mathieu Carbonneaux
|
|
||||||
Fixes #9773
|
|
||||||
Fixes #5745
|
|
||||||
Closes #9775
|
|
||||||
---
|
|
||||||
index f159008..d151f5c 100644
|
|
||||||
--- a/lib/url.c
|
|
||||||
+++ b/lib/url.c
|
|
||||||
@@ -2509,6 +2509,75 @@ void Curl_free_request_state(struct Curl_easy *data)
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_PROXY
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Curl_cidr4_match() returns TRUE if the given IPv4 address is within the
|
|
||||||
+ * specified CIDR address range.
|
|
||||||
+ */
|
|
||||||
+static bool Curl_cidr4_match(const char *ipv4, /* 1.2.3.4 address */
|
|
||||||
+ const char *network, /* 1.2.3.4 address */
|
|
||||||
+ unsigned int bits)
|
|
||||||
+{
|
|
||||||
+ unsigned int address = 0;
|
|
||||||
+ unsigned int check = 0;
|
|
||||||
+
|
|
||||||
+ if(bits > 32)
|
|
||||||
+ /* strange input */
|
|
||||||
+ return FALSE;
|
|
||||||
+
|
|
||||||
+ if(1 != Curl_inet_pton(AF_INET, ipv4, &address))
|
|
||||||
+ return FALSE;
|
|
||||||
+ if(1 != Curl_inet_pton(AF_INET, network, &check))
|
|
||||||
+ return FALSE;
|
|
||||||
+
|
|
||||||
+ if(!bits)
|
|
||||||
+ return TRUE; /* /0 means all addresses match */
|
|
||||||
+
|
|
||||||
+ if(bits && (bits != 32)) {
|
|
||||||
+ unsigned int mask = 0xffffffff << (32 - bits);
|
|
||||||
+ unsigned int haddr = htonl(address);
|
|
||||||
+ unsigned int hcheck = htonl(check);
|
|
||||||
+ if((haddr ^ hcheck) & mask)
|
|
||||||
+ return FALSE;
|
|
||||||
+ return TRUE;
|
|
||||||
+ }
|
|
||||||
+ return (address == check);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static bool Curl_cidr6_match(const char *ipv6,
|
|
||||||
+ const char *network,
|
|
||||||
+ unsigned int bits)
|
|
||||||
+{
|
|
||||||
+ int bytes;
|
|
||||||
+ int rest;
|
|
||||||
+ unsigned char address[16];
|
|
||||||
+ unsigned char check[16];
|
|
||||||
+
|
|
||||||
+ if(!bits)
|
|
||||||
+ bits = 128;
|
|
||||||
+
|
|
||||||
+ bytes = bits/8;
|
|
||||||
+ rest = bits & 0x07;
|
|
||||||
+ if((bytes > 16) || ((bytes == 16) && rest))
|
|
||||||
+ return FALSE;
|
|
||||||
+ if(1 != Curl_inet_pton(AF_INET6, ipv6, address))
|
|
||||||
+ return FALSE;
|
|
||||||
+ if(1 != Curl_inet_pton(AF_INET6, network, check))
|
|
||||||
+ return FALSE;
|
|
||||||
+ if(bytes && memcmp(address, check, bytes))
|
|
||||||
+ return FALSE;
|
|
||||||
+ if(rest && !((address[bytes] ^ check[bytes]) & (0xff << (8 - rest))))
|
|
||||||
+ return FALSE;
|
|
||||||
+
|
|
||||||
+ return TRUE;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+enum nametype {
|
|
||||||
+ TYPE_HOST,
|
|
||||||
+ TYPE_IPV4,
|
|
||||||
+ TYPE_IPV6
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
/****************************************************************
|
|
||||||
* Checks if the host is in the noproxy list. returns true if it matches
|
|
||||||
* and therefore the proxy should NOT be used.
|
|
||||||
@@ -2521,70 +2590,127 @@ static bool check_noproxy(const char *name, const char *no_proxy)
|
|
||||||
* all proxy variables)
|
|
||||||
*/
|
|
||||||
if(no_proxy && no_proxy[0]) {
|
|
||||||
- size_t tok_start;
|
|
||||||
- size_t tok_end;
|
|
||||||
- const char *separator = ", ";
|
|
||||||
- size_t no_proxy_len;
|
|
||||||
+ const char *p = no_proxy;
|
|
||||||
size_t namelen;
|
|
||||||
- char *endptr;
|
|
||||||
- if(strcasecompare("*", no_proxy)) {
|
|
||||||
+ enum nametype type = TYPE_HOST;
|
|
||||||
+ char hostip[128];
|
|
||||||
+ if(strcasecompare("*", no_proxy))
|
|
||||||
return TRUE;
|
|
||||||
- }
|
|
||||||
|
|
||||||
/* NO_PROXY was specified and it wasn't just an asterisk */
|
|
||||||
|
|
||||||
- no_proxy_len = strlen(no_proxy);
|
|
||||||
if(name[0] == '[') {
|
|
||||||
+ char *endptr;
|
|
||||||
/* IPv6 numerical address */
|
|
||||||
endptr = strchr(name, ']');
|
|
||||||
if(!endptr)
|
|
||||||
return FALSE;
|
|
||||||
name++;
|
|
||||||
- }
|
|
||||||
- else
|
|
||||||
- endptr = strchr(name, ':');
|
|
||||||
- if(endptr)
|
|
||||||
namelen = endptr - name;
|
|
||||||
- else
|
|
||||||
- namelen = strlen(name);
|
|
||||||
-
|
|
||||||
- for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
|
|
||||||
- while(tok_start < no_proxy_len &&
|
|
||||||
- strchr(separator, no_proxy[tok_start]) != NULL) {
|
|
||||||
- /* Look for the beginning of the token. */
|
|
||||||
- ++tok_start;
|
|
||||||
+ if(namelen >= sizeof(hostip))
|
|
||||||
+ return FALSE;
|
|
||||||
+ memcpy(hostip, name, namelen);
|
|
||||||
+ hostip[namelen] = 0;
|
|
||||||
+ name = hostip;
|
|
||||||
+ type = TYPE_IPV6;
|
|
||||||
+ }
|
|
||||||
+ else {
|
|
||||||
+ char *portptr;
|
|
||||||
+ unsigned int address;
|
|
||||||
+ /* First, strip off any port number */
|
|
||||||
+ portptr = strchr(name, ':');
|
|
||||||
+ if(portptr)
|
|
||||||
+ namelen = portptr - name;
|
|
||||||
+ else
|
|
||||||
+ namelen = strlen(name);
|
|
||||||
+
|
|
||||||
+ /* Copy name without port to buffer for type detection */
|
|
||||||
+ if(namelen >= sizeof(hostip))
|
|
||||||
+ namelen = sizeof(hostip) - 1;
|
|
||||||
+ memcpy(hostip, name, namelen);
|
|
||||||
+ hostip[namelen] = 0;
|
|
||||||
+
|
|
||||||
+ /* Now check if it's an IPv4 address */
|
|
||||||
+ if(1 == Curl_inet_pton(AF_INET, hostip, &address)) {
|
|
||||||
+ type = TYPE_IPV4;
|
|
||||||
+ name = hostip;
|
|
||||||
}
|
|
||||||
+ else {
|
|
||||||
+ /* It's a hostname - namelen already excludes port */
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- if(tok_start == no_proxy_len)
|
|
||||||
- break; /* It was all trailing separator chars, no more tokens. */
|
|
||||||
+ while(*p) {
|
|
||||||
+ const char *token;
|
|
||||||
+ size_t tokenlen = 0;
|
|
||||||
+ bool match = FALSE;
|
|
||||||
|
|
||||||
- for(tok_end = tok_start; tok_end < no_proxy_len &&
|
|
||||||
- strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
|
|
||||||
- /* Look for the end of the token. */
|
|
||||||
- ;
|
|
||||||
+ /* pass blanks */
|
|
||||||
+ while(*p && ISBLANK(*p))
|
|
||||||
+ p++;
|
|
||||||
|
|
||||||
- /* To match previous behaviour, where it was necessary to specify
|
|
||||||
- * ".local.com" to prevent matching "notlocal.com", we will leave
|
|
||||||
- * the '.' off.
|
|
||||||
- */
|
|
||||||
- if(no_proxy[tok_start] == '.')
|
|
||||||
- ++tok_start;
|
|
||||||
-
|
|
||||||
- if((tok_end - tok_start) <= namelen) {
|
|
||||||
- /* Match the last part of the name to the domain we are checking. */
|
|
||||||
- const char *checkn = name + namelen - (tok_end - tok_start);
|
|
||||||
- if(strncasecompare(no_proxy + tok_start, checkn,
|
|
||||||
- tok_end - tok_start)) {
|
|
||||||
- if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
|
|
||||||
- /* We either have an exact match, or the previous character is a .
|
|
||||||
- * so it is within the same domain, so no proxy for this host.
|
|
||||||
- */
|
|
||||||
- return TRUE;
|
|
||||||
+ token = p;
|
|
||||||
+ /* pass over the pattern */
|
|
||||||
+ while(*p && !ISBLANK(*p) && (*p != ',')) {
|
|
||||||
+ p++;
|
|
||||||
+ tokenlen++;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if(tokenlen) {
|
|
||||||
+ switch(type) {
|
|
||||||
+ case TYPE_HOST:
|
|
||||||
+ /* Skip leading dot in token */
|
|
||||||
+ if(tokenlen && (*token == '.')) {
|
|
||||||
+ token++;
|
|
||||||
+ tokenlen--;
|
|
||||||
+ }
|
|
||||||
+ /* A: example.com matches 'example.com'
|
|
||||||
+ B: www.example.com matches 'example.com'
|
|
||||||
+ C: nonexample.com DOES NOT match 'example.com' */
|
|
||||||
+ if(tokenlen == namelen)
|
|
||||||
+ /* case A, exact match */
|
|
||||||
+ match = strncasecompare(token, name, namelen);
|
|
||||||
+ else if(tokenlen < namelen) {
|
|
||||||
+ /* case B, tailmatch domain */
|
|
||||||
+ match = (name[namelen - tokenlen - 1] == '.') &&
|
|
||||||
+ strncasecompare(token, name + (namelen - tokenlen), tokenlen);
|
|
||||||
}
|
|
||||||
+ /* case C passes through, not a match */
|
|
||||||
+ break;
|
|
||||||
+ case TYPE_IPV4:
|
|
||||||
+ /* FALLTHROUGH */
|
|
||||||
+ case TYPE_IPV6: {
|
|
||||||
+ const char *check = token;
|
|
||||||
+ char *slash;
|
|
||||||
+ unsigned int bits = 0;
|
|
||||||
+ char checkip[128];
|
|
||||||
+ if(tokenlen >= sizeof(checkip))
|
|
||||||
+ /* this cannot match */
|
|
||||||
+ break;
|
|
||||||
+ /* copy the check name to a temp buffer */
|
|
||||||
+ memcpy(checkip, check, tokenlen);
|
|
||||||
+ checkip[tokenlen] = 0;
|
|
||||||
+ check = checkip;
|
|
||||||
+
|
|
||||||
+ slash = strchr(check, '/');
|
|
||||||
+ /* if the slash is part of this token, use it */
|
|
||||||
+ if(slash) {
|
|
||||||
+ bits = atoi(slash + 1);
|
|
||||||
+ *slash = 0;
|
|
||||||
+ }
|
|
||||||
+ if(type == TYPE_IPV6)
|
|
||||||
+ match = Curl_cidr6_match(name, check, bits);
|
|
||||||
+ else
|
|
||||||
+ match = Curl_cidr4_match(name, check, bits);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
- } /* if((tok_end - tok_start) <= namelen) */
|
|
||||||
- } /* for(tok_start = 0; tok_start < no_proxy_len;
|
|
||||||
- tok_start = tok_end + 1) */
|
|
||||||
+ if(match)
|
|
||||||
+ return TRUE;
|
|
||||||
+ } /* if(tokenlen) */
|
|
||||||
+ while(*p == ',')
|
|
||||||
+ p++;
|
|
||||||
+ } /* while(*p) */
|
|
||||||
} /* NO_PROXY was specified and it wasn't just an asterisk */
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
202
SPECS/curl.spec
202
SPECS/curl.spec
@ -1,7 +1,7 @@
|
|||||||
Summary: A utility for getting files from remote servers (FTP, HTTP, and others)
|
Summary: A utility for getting files from remote servers (FTP, HTTP, and others)
|
||||||
Name: curl
|
Name: curl
|
||||||
Version: 7.61.1
|
Version: 7.61.1
|
||||||
Release: 34%{?dist}.11
|
Release: 34%{?dist}
|
||||||
License: MIT
|
License: MIT
|
||||||
Source: https://curl.haxx.se/download/%{name}-%{version}.tar.xz
|
Source: https://curl.haxx.se/download/%{name}-%{version}.tar.xz
|
||||||
|
|
||||||
@ -175,36 +175,6 @@ Patch59: 0059-curl-7.61.1-CVE-2023-46218.patch
|
|||||||
# lowercase headernames
|
# lowercase headernames
|
||||||
Patch60: 0060-curl-7.61.1-lowercase-headernames.patch
|
Patch60: 0060-curl-7.61.1-lowercase-headernames.patch
|
||||||
|
|
||||||
# provide common cleanup method for push headers (CVE-2024-2398)
|
|
||||||
Patch61: 0061-curl-7.61.1-CVE-2024-2398.patch
|
|
||||||
|
|
||||||
# asyn-thread: create a socketpair to wait on
|
|
||||||
Patch62: 0062-curl-7.61.1-socketpair-to-wait-on.patch
|
|
||||||
|
|
||||||
# fix crash, when talking to a NTLM proxy in FIPS mode
|
|
||||||
Patch63: 0063-curl-7.61.1-native-md5.patch
|
|
||||||
|
|
||||||
# asyn-thread: issue CURL_POLL_REMOVE before closing socket
|
|
||||||
Patch64: 0064-curl-7.61.1-EBADF.patch
|
|
||||||
|
|
||||||
# libssh: Fix matching user-specified MD5 hex key
|
|
||||||
Patch65: 0065-md5-hex-key.patch
|
|
||||||
|
|
||||||
# crypto: ensure crypto initialization works
|
|
||||||
Patch66: 0066-crypto-initialization.patch
|
|
||||||
|
|
||||||
# NTLM: force the connection to HTTP/1.1
|
|
||||||
Patch67: 0067-curl-7.61.1-ntlm-force-http-1-1.patch
|
|
||||||
|
|
||||||
# cookie: don't treat the leading slash as trailing (CVE-2025-9086)
|
|
||||||
Patch68: 0068-curl-7.61.1-CVE-2025-9086.patch
|
|
||||||
|
|
||||||
# AWS Signature Version 4 authentication support
|
|
||||||
Patch69: 0069-curl-7.61.1-aws-sigv4.patch
|
|
||||||
|
|
||||||
# noproxy: support proxies specified using cidr notation
|
|
||||||
Patch70: 0070-curl-7.61.1-noproxy-support-using-cidr.patch
|
|
||||||
|
|
||||||
# patch making libcurl multilib ready
|
# patch making libcurl multilib ready
|
||||||
Patch101: 0101-curl-7.32.0-multilib.patch
|
Patch101: 0101-curl-7.32.0-multilib.patch
|
||||||
|
|
||||||
@ -365,88 +335,79 @@ be installed.
|
|||||||
%setup -q
|
%setup -q
|
||||||
|
|
||||||
# upstream patches
|
# upstream patches
|
||||||
%patch -P 1 -p1
|
%patch1 -p1
|
||||||
%patch -P 2 -p1
|
%patch2 -p1
|
||||||
%patch -P 3 -p1
|
%patch3 -p1
|
||||||
git init
|
git init
|
||||||
git apply %{PATCH4}
|
git apply %{PATCH4}
|
||||||
%patch -P 5 -p1
|
%patch5 -p1
|
||||||
%patch -P 6 -p1
|
%patch6 -p1
|
||||||
%patch -P 7 -p1
|
%patch7 -p1
|
||||||
%patch -P 8 -p1
|
%patch8 -p1
|
||||||
%patch -P 9 -p1
|
%patch9 -p1
|
||||||
%patch -P 10 -p1
|
%patch10 -p1
|
||||||
%patch -P 11 -p1
|
%patch11 -p1
|
||||||
%patch -P 14 -p1
|
%patch14 -p1
|
||||||
|
|
||||||
# Fedora patches
|
# Fedora patches
|
||||||
%patch -P 101 -p1
|
%patch101 -p1
|
||||||
%patch -P 102 -p1
|
%patch102 -p1
|
||||||
%patch -P 103 -p1
|
%patch103 -p1
|
||||||
%patch -P 104 -p1
|
%patch104 -p1
|
||||||
|
|
||||||
# use different port range for 32bit and 64bit builds, thus make it possible
|
# use different port range for 32bit and 64bit builds, thus make it possible
|
||||||
# to run both the builds in parallel on the same machine
|
# to run both the builds in parallel on the same machine
|
||||||
%patch -P 105 -p1
|
%patch105 -p1
|
||||||
sed -e 's|%%HTTPPORT|%{?__isa_bits}90|g' -i tests/data/test1448
|
sed -e 's|%%HTTPPORT|%{?__isa_bits}90|g' -i tests/data/test1448
|
||||||
|
|
||||||
# upstream patches
|
# upstream patches
|
||||||
%patch -P 17 -p1
|
%patch17 -p1
|
||||||
%patch -P 18 -p1
|
%patch18 -p1
|
||||||
%patch -P 19 -p1
|
%patch19 -p1
|
||||||
%patch -P 20 -p1
|
%patch20 -p1
|
||||||
%patch -P 21 -p1
|
%patch21 -p1
|
||||||
%patch -P 22 -p1
|
%patch22 -p1
|
||||||
%patch -P 23 -p1
|
%patch23 -p1
|
||||||
%patch -P 24 -p1
|
%patch24 -p1
|
||||||
%patch -P 25 -p1
|
%patch25 -p1
|
||||||
%patch -P 26 -p1
|
%patch26 -p1
|
||||||
%patch -P 27 -p1
|
%patch27 -p1
|
||||||
%patch -P 28 -p1
|
%patch28 -p1
|
||||||
%patch -P 29 -p1
|
%patch29 -p1
|
||||||
%patch -P 30 -p1
|
%patch30 -p1
|
||||||
%patch -P 31 -p1
|
%patch31 -p1
|
||||||
%patch -P 32 -p1
|
%patch32 -p1
|
||||||
%patch -P 33 -p1
|
%patch33 -p1
|
||||||
%patch -P 34 -p1
|
%patch34 -p1
|
||||||
%patch -P 35 -p1
|
%patch35 -p1
|
||||||
%patch -P 36 -p1
|
%patch36 -p1
|
||||||
%patch -P 37 -p1
|
%patch37 -p1
|
||||||
%patch -P 38 -p1
|
|
||||||
|
%patch38 -p1
|
||||||
sed -e 's|:8992/|:%{?__isa_bits}92/|g' -i tests/data/test97{3..6}
|
sed -e 's|:8992/|:%{?__isa_bits}92/|g' -i tests/data/test97{3..6}
|
||||||
|
|
||||||
%patch -P 39 -p1
|
%patch39 -p1
|
||||||
%patch -P 40 -p1
|
%patch40 -p1
|
||||||
%patch -P 41 -p1
|
%patch41 -p1
|
||||||
%patch -P 42 -p1
|
%patch42 -p1
|
||||||
%patch -P 43 -p1
|
%patch43 -p1
|
||||||
%patch -P 44 -p1
|
%patch44 -p1
|
||||||
%patch -P 45 -p1
|
%patch45 -p1
|
||||||
%patch -P 46 -p1
|
%patch46 -p1
|
||||||
%patch -P 47 -p1
|
%patch47 -p1
|
||||||
%patch -P 48 -p1
|
%patch48 -p1
|
||||||
%patch -P 49 -p1
|
%patch49 -p1
|
||||||
%patch -P 50 -p1
|
%patch50 -p1
|
||||||
%patch -P 51 -p1
|
%patch51 -p1
|
||||||
git apply %{PATCH52}
|
git apply %{PATCH52}
|
||||||
%patch -P 53 -p1
|
%patch53 -p1
|
||||||
%patch -P 54 -p1
|
%patch54 -p1
|
||||||
%patch -P 55 -p1
|
%patch55 -p1
|
||||||
%patch -P 56 -p1
|
%patch56 -p1
|
||||||
%patch -P 57 -p1
|
%patch57 -p1
|
||||||
%patch -P 58 -p1
|
%patch58 -p1
|
||||||
%patch -P 59 -p1
|
%patch59 -p1
|
||||||
%patch -P 60 -p1
|
%patch60 -p1
|
||||||
%patch -P 61 -p1
|
|
||||||
%patch -P 62 -p1
|
|
||||||
%patch -P 63 -p1
|
|
||||||
%patch -P 64 -p1
|
|
||||||
%patch -P 65 -p1
|
|
||||||
%patch -P 66 -p1
|
|
||||||
%patch -P 67 -p1
|
|
||||||
%patch -P 68 -p1
|
|
||||||
%patch -P 69 -p1
|
|
||||||
%patch -P 70 -p1
|
|
||||||
|
|
||||||
# make tests/*.py use Python 3
|
# make tests/*.py use Python 3
|
||||||
sed -e '1 s|^#!/.*python|#!%{__python3}|' -i tests/*.py
|
sed -e '1 s|^#!/.*python|#!%{__python3}|' -i tests/*.py
|
||||||
@ -460,9 +421,7 @@ automake
|
|||||||
# <https://github.com/bagder/curl/commit/21e82bd6#commitcomment-12226582>
|
# <https://github.com/bagder/curl/commit/21e82bd6#commitcomment-12226582>
|
||||||
# and test 1900, which is flaky and covers a deprecated feature of libcurl
|
# and test 1900, which is flaky and covers a deprecated feature of libcurl
|
||||||
# <https://github.com/curl/curl/pull/2705>
|
# <https://github.com/curl/curl/pull/2705>
|
||||||
# disable test 1456 - requires test framework features not available in 7.61.1
|
printf "1112\n1455\n1801\n1900\n" >> tests/data/DISABLED
|
||||||
# (crlf attribute support for <protocol> tag)
|
|
||||||
printf "1112\n1455\n1456\n1801\n1900\n" >> tests/data/DISABLED
|
|
||||||
|
|
||||||
# disable test 1319 on ppc64 (server times out)
|
# disable test 1319 on ppc64 (server times out)
|
||||||
%ifarch ppc64
|
%ifarch ppc64
|
||||||
@ -611,43 +570,6 @@ rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la
|
|||||||
%{_libdir}/libcurl.so.4.[0-9].[0-9].minimal
|
%{_libdir}/libcurl.so.4.[0-9].[0-9].minimal
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Tue Jan 13 2026 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34.el8_10.11
|
|
||||||
- noproxy: support proxies specified using cidr notation (RHEL-86910)
|
|
||||||
- disable test1456 (requires test framework features not in 7.61.1)
|
|
||||||
|
|
||||||
* Wed Dec 03 2025 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34.el8_10.10
|
|
||||||
- AWS Signature Version 4 authentication support (RHEL-116183)
|
|
||||||
|
|
||||||
* Fri Oct 24 2025 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34.el8_10.9
|
|
||||||
- cookie: don't treat the leading slash as trailing (CVE-2025-9086)
|
|
||||||
Resolves: RHEL-121655
|
|
||||||
|
|
||||||
* Mon Jul 21 2025 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34.el8_10.8
|
|
||||||
- NTLM: force the connection to HTTP/1.1 (RHEL-73788)
|
|
||||||
|
|
||||||
* Wed Jul 09 2025 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34.el8_10.7
|
|
||||||
* crypto: ensure crypto initialization works (RHEL-102601)
|
|
||||||
|
|
||||||
* Thu May 29 2025 Carlos Santos <casantos@redhat.com> - 7.61.1-34.el8_10.6
|
|
||||||
- libssh: Fix matching user-specified MD5 hex key (RHEL-94574)
|
|
||||||
|
|
||||||
* Wed Jan 08 2025 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34.el8_10.5
|
|
||||||
- asyn-thread: fix EBADF regression (RHEL-85602)
|
|
||||||
|
|
||||||
* Wed Jan 08 2025 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34.el8_10.4
|
|
||||||
- make up incomplete patch for host name wildcard checking (RHEL-5680)
|
|
||||||
- asyn-thread: issue CURL_POLL_REMOVE before closing socket (RHEL-85602)
|
|
||||||
|
|
||||||
* Wed Oct 30 2024 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34.el8_10.3
|
|
||||||
- asyn-thread: create a socketpair to wait on (RHEL-34906)
|
|
||||||
- fix crash, when talking to a NTLM proxy in FIPS mode (RHEL-32641)
|
|
||||||
|
|
||||||
* Wed Aug 14 2024 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34.el8_10.2
|
|
||||||
- provide common cleanup method for push headers (CVE-2024-2398)
|
|
||||||
|
|
||||||
* Tue Jun 25 2024 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34.el8_10.1
|
|
||||||
- fix incorrect backport of bz2229800 (RHEL-44684)
|
|
||||||
|
|
||||||
* Tue Sep 19 2023 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34
|
* Tue Sep 19 2023 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34
|
||||||
- when keyboard-interactive auth fails, try password (#2229800)
|
- when keyboard-interactive auth fails, try password (#2229800)
|
||||||
- cap SFTP packet size sent (RHEL-5311)
|
- cap SFTP packet size sent (RHEL-5311)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user