Complete Yocto mirror with license table for TQMa6UL (2038-compliance)

- 264 license table entries with exact download URLs (224/264 resolved)
- Complete sources/ directory with all BitBake recipes
- Build configuration: tqma6ul-multi-mba6ulx, spaetzle (musl)
- Full traceability for Softwarefreigabeantrag
- GCC 13.4.0, Linux 6.6.102, U-Boot 2023.04, musl 1.2.4
- License distribution: GPL-2.0 (24), MIT (23), GPL-2.0+ (18), BSD-3 (16)
This commit is contained in:
Siggi (OpenClaw Agent)
2026-03-01 20:58:18 +00:00
commit 16accb6b24
15086 changed files with 1292356 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
From 721941aadf4adf4f6aeb3f4c0ab489bb89610c36 Mon Sep 17 00:00:00 2001
From: Stefan Eissing <stefan@eissing.org>
Date: Mon, 1 Apr 2024 15:41:18 +0200
Subject: [PATCH] http: with chunked POST forced, disable length check on read
callback
- when an application forces HTTP/1.1 chunked transfer encoding
by setting the corresponding header and instructs curl to use
the CURLOPT_READFUNCTION, disregard any POST length information.
- this establishes backward compatibility with previous curl versions
Applications are encouraged to not force "chunked", but rather
set length information for a POST. By setting -1, curl will
auto-select chunked on HTTP/1.1 and work properly on other HTTP
versions.
Reported-by: Jeff King
Fixes #13229
Closes #13257
Upstream-Status: Backport
---
lib/http.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/lib/http.c b/lib/http.c
index 92c04e69cd8373..a764d3c4403c39 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -2046,8 +2046,19 @@ static CURLcode set_reader(struct Curl_easy *data, Curl_HttpReq httpreq)
else
result = Curl_creader_set_null(data);
}
- else { /* we read the bytes from the callback */
- result = Curl_creader_set_fread(data, postsize);
+ else {
+ /* we read the bytes from the callback. In case "chunked" encoding
+ * is forced by the application, we disregard `postsize`. This is
+ * a backward compatibility decision to earlier versions where
+ * chunking disregarded this. See issue #13229. */
+ bool chunked = FALSE;
+ char *ptr = Curl_checkheaders(data, STRCONST("Transfer-Encoding"));
+ if(ptr) {
+ /* Some kind of TE is requested, check if 'chunked' is chosen */
+ chunked = Curl_compareheader(ptr, STRCONST("Transfer-Encoding:"),
+ STRCONST("chunked"));
+ }
+ result = Curl_creader_set_fread(data, chunked? -1 : postsize);
}
return result;
@@ -2115,6 +2126,13 @@ CURLcode Curl_http_req_set_reader(struct Curl_easy *data,
data->req.upload_chunky =
Curl_compareheader(ptr,
STRCONST("Transfer-Encoding:"), STRCONST("chunked"));
+ if(data->req.upload_chunky &&
+ Curl_use_http_1_1plus(data, data->conn) &&
+ (data->conn->httpversion >= 20)) {
+ infof(data, "suppressing chunked transfer encoding on connection "
+ "using HTTP version 2 or higher");
+ data->req.upload_chunky = FALSE;
+ }
}
else {
curl_off_t req_clen = Curl_creader_total_length(data);

View File

@@ -0,0 +1,353 @@
From 9bee39bfed2c413b4cc4eb306a57ac92a1854907 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 12 Oct 2024 23:54:39 +0200
Subject: [PATCH] url: use same credentials on redirect
Previously it could lose the username and only use the password.
Added test 998 and 999 to verify.
Reported-by: Tobias Bora
Fixes #15262
Closes #15282
Changes:
- Test files are added in Makefile.inc.
CVE: CVE-2024-11053
Upstream-Status: Backport [https://github.com/curl/curl/commit/9bee39bfed2c413b4cc4eb306a57ac92a1854907]
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
---
lib/transfer.c | 3 ++
lib/url.c | 19 +++++----
lib/urldata.h | 9 +++-
tests/data/Makefile.inc | 2 +-
tests/data/test998 | 92 +++++++++++++++++++++++++++++++++++++++++
tests/data/test999 | 81 ++++++++++++++++++++++++++++++++++++
6 files changed, 195 insertions(+), 11 deletions(-)
create mode 100644 tests/data/test998
create mode 100644 tests/data/test999
diff --git a/lib/transfer.c b/lib/transfer.c
index e31d1d6..ccd042b 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -700,6 +700,9 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
return CURLE_OUT_OF_MEMORY;
}
+ if(data->set.str[STRING_USERNAME] ||
+ data->set.str[STRING_PASSWORD])
+ data->state.creds_from = CREDS_OPTION;
if(!result)
result = Curl_setstropt(&data->state.aptr.user,
data->set.str[STRING_USERNAME]);
diff --git a/lib/url.c b/lib/url.c
index 224b9f3..05431b9 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1899,10 +1899,10 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
return result;
/*
- * User name and password set with their own options override the
- * credentials possibly set in the URL.
+ * username and password set with their own options override the credentials
+ * possibly set in the URL, but netrc does not.
*/
- if(!data->set.str[STRING_PASSWORD]) {
+ if(!data->state.aptr.passwd || (data->state.creds_from != CREDS_OPTION)) {
uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0);
if(!uc) {
char *decoded;
@@ -1915,12 +1915,13 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
result = Curl_setstropt(&data->state.aptr.passwd, decoded);
if(result)
return result;
+ data->state.creds_from = CREDS_URL;
}
else if(uc != CURLUE_NO_PASSWORD)
return Curl_uc_to_curlcode(uc);
}
- if(!data->set.str[STRING_USERNAME]) {
+ if(!data->state.aptr.user || (data->state.creds_from != CREDS_OPTION)) {
/* we don't use the URL API's URL decoder option here since it rejects
control codes and we want to allow them for some schemes in the user
and password fields */
@@ -1934,13 +1935,10 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
return result;
conn->user = decoded;
result = Curl_setstropt(&data->state.aptr.user, decoded);
+ data->state.creds_from = CREDS_URL;
}
else if(uc != CURLUE_NO_USER)
return Curl_uc_to_curlcode(uc);
- else if(data->state.aptr.passwd) {
- /* no user was set but a password, set a blank user */
- result = Curl_setstropt(&data->state.aptr.user, "");
- }
if(result)
return result;
}
@@ -2730,7 +2728,8 @@ static CURLcode override_login(struct Curl_easy *data,
int ret;
bool url_provided = FALSE;
- if(data->state.aptr.user) {
+ if(data->state.aptr.user &&
+ (data->state.creds_from != CREDS_NETRC)) {
/* there was a user name in the URL. Use the URL decoded version */
userp = &data->state.aptr.user;
url_provided = TRUE;
@@ -2778,6 +2777,7 @@ static CURLcode override_login(struct Curl_easy *data,
result = Curl_setstropt(&data->state.aptr.user, *userp);
if(result)
return result;
+ data->state.creds_from = CREDS_NETRC;
}
}
if(data->state.aptr.user) {
@@ -2795,6 +2795,7 @@ static CURLcode override_login(struct Curl_easy *data,
CURLcode result = Curl_setstropt(&data->state.aptr.passwd, *passwdp);
if(result)
return result;
+ data->state.creds_from = CREDS_NETRC;
}
if(data->state.aptr.passwd) {
uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD,
diff --git a/lib/urldata.h b/lib/urldata.h
index ce28f25..b68d023 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1207,6 +1207,11 @@ struct urlpieces {
char *query;
};
+#define CREDS_NONE 0
+#define CREDS_URL 1 /* from URL */
+#define CREDS_OPTION 2 /* set with a CURLOPT_ */
+#define CREDS_NETRC 3 /* found in netrc */
+
struct UrlState {
/* Points to the connection cache */
struct conncache *conn_cache;
@@ -1344,7 +1349,6 @@ struct UrlState {
char *proxyuser;
char *proxypasswd;
} aptr;
-
unsigned char httpwant; /* when non-zero, a specific HTTP version requested
to be used in the library's request(s) */
unsigned char httpversion; /* the lowest HTTP version*10 reported by any
@@ -1354,6 +1358,9 @@ struct UrlState {
unsigned char select_bits; /* != 0 -> bitmask of socket events for this
transfer overriding anything the socket may
report */
+ unsigned int creds_from:2; /* where is the server credentials originating
+ from, see the CREDS_* defines above */
+
#ifdef CURLDEBUG
BIT(conncache_lock);
#endif
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index d89e565..03cb6a0 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -126,7 +126,7 @@ test952 test953 test954 test955 test956 test957 test958 test959 test960 \
test961 test962 test963 test964 test965 test966 test967 test968 test969 \
test970 test971 test972 test973 test974 test975 test976 test977 test978 \
test979 test980 test981 test982 test983 test984 test985 test986 test987 \
-test988 test989 test990 test991 test992 \
+test988 test989 test990 test991 test992 test998 test999 \
\
test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \
test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \
diff --git a/tests/data/test998 b/tests/data/test998
new file mode 100644
index 0000000..596b18e
--- /dev/null
+++ b/tests/data/test998
@@ -0,0 +1,92 @@
+<testcase>
+ <info>
+ <keywords>
+ HTTP
+ --location-trusted
+ </keywords>
+ </info>
+
+ #
+ # Server-side
+ <reply>
+ <data>
+ HTTP/1.1 301 redirect
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Server: test-server/fake
+ Content-Length: 0
+ Connection: close
+ Content-Type: text/html
+ Location: http://somewhere.else.example/a/path/%TESTNUMBER0002
+
+ </data>
+ <data2>
+ HTTP/1.1 200 OK
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Content-Length: 6
+ Content-Type: text/html
+ Funny-head: yesyes
+
+ -foo-
+ </data2>
+
+ <datacheck>
+ HTTP/1.1 301 redirect
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Server: test-server/fake
+ Content-Length: 0
+ Connection: close
+ Content-Type: text/html
+ Location: http://somewhere.else.example/a/path/%TESTNUMBER0002
+
+ HTTP/1.1 200 OK
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Content-Length: 6
+ Content-Type: text/html
+ Funny-head: yesyes
+
+ -foo-
+ </datacheck>
+
+ </reply>
+
+ #
+ # Client-side
+ <client>
+ <features>
+ proxy
+ </features>
+ <server>
+ http
+ </server>
+ <name>
+ HTTP with auth in URL redirected to another host
+ </name>
+ <command>
+ -x %HOSTIP:%HTTPPORT http://alberto:einstein@somwhere.example/%TESTNUMBER --location-trusted
+ </command>
+ </client>
+
+ #
+ # Verify data after the test has been "shot"
+ <verify>
+ <strip>
+ QUIT
+ </strip>
+ <protocol>
+ GET http://somwhere.example/998 HTTP/1.1
+ Host: somwhere.example
+ Authorization: Basic YWxiZXJ0bzplaW5zdGVpbg==
+ User-Agent: curl/%VERSION
+ Accept: */*
+ Proxy-Connection: Keep-Alive
+
+ GET http://somewhere.else.example/a/path/9980002 HTTP/1.1
+ Host: somewhere.else.example
+ Authorization: Basic YWxiZXJ0bzplaW5zdGVpbg==
+ User-Agent: curl/%VERSION
+ Accept: */*
+ Proxy-Connection: Keep-Alive
+
+ </protocol>
+ </verify>
+ </testcase>
diff --git a/tests/data/test999 b/tests/data/test999
new file mode 100644
index 0000000..184821d
--- /dev/null
+++ b/tests/data/test999
@@ -0,0 +1,81 @@
+<testcase>
+ <info>
+ <keywords>
+ HTTP
+ --location-trusted
+ </keywords>
+ </info>
+
+ #
+ # Server-side
+ <reply>
+ <data nocheck="yes">
+ HTTP/1.1 200 OK
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Content-Length: 6
+ Content-Type: text/html
+ Funny-head: yesyes
+
+ -foo-
+ </data>
+
+ <datacheck>
+ HTTP/1.1 301 redirect
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Server: test-server/fake
+ Content-Length: 0
+ Connection: close
+ Content-Type: text/html
+ Location: http://somewhere.else.example/a/path/%TESTNUMBER0002
+
+ HTTP/1.1 200 OK
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Content-Length: 6
+ Content-Type: text/html
+ Funny-head: yesyes
+
+ -foo-
+ </datacheck>
+
+ </reply>
+
+ #
+ # Client-side
+ <client>
+ <features>
+ proxy
+ </features>
+ <server>
+ http
+ </server>
+ <name>
+ HTTP with auth in first URL but not second
+ </name>
+ <command>
+ -x %HOSTIP:%HTTPPORT http://alberto:einstein@somwhere.example/%TESTNUMBER http://somewhere.else.example/%TESTNUMBER
+ </command>
+ </client>
+
+ #
+ # Verify data after the test has been "shot"
+ <verify>
+ <strip>
+ QUIT
+ </strip>
+ <protocol>
+ GET http://somwhere.example/%TESTNUMBER HTTP/1.1
+ Host: somwhere.example
+ Authorization: Basic YWxiZXJ0bzplaW5zdGVpbg==
+ User-Agent: curl/%VERSION
+ Accept: */*
+ Proxy-Connection: Keep-Alive
+
+ GET http://somewhere.else.example/%TESTNUMBER HTTP/1.1
+ Host: somewhere.else.example
+ User-Agent: curl/%VERSION
+ Accept: */*
+ Proxy-Connection: Keep-Alive
+
+ </protocol>
+ </verify>
+ </testcase>
--
2.40.0

View File

@@ -0,0 +1,728 @@
From e9b9bbac22c26cf67316fa8e6c6b9e831af31949 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 15 Nov 2024 11:06:36 +0100
Subject: [PATCH] netrc: address several netrc parser flaws
- make sure that a match that returns a username also returns a
password, that should be blank if no password is found
- fix handling of multiple logins for same host where the password/login
order might be reversed.
- reject credentials provided in the .netrc if they contain ASCII control
codes - if the used protocol does not support such (like HTTP and WS do)
Reported-by: Harry Sintonen
Add test 478, 479 and 480 to verify. Updated unit 1304.
Closes #15586
Changes:
- Refresh patch context.
- Adjust `%LOGDIR/` to 'log/' due to its absence in code.
- Backported only required enum found_state defination from:
https://github.com/curl/curl/commit/3b43a05e000aa8f65bda513f733a73fefe35d5ca
- Replaces the previous usage of the state_login, state_password, and
state_our_login variables with the found_state enum, which includes the
values NONE, LOGIN, and PASSWORD. As a result, all conditionals and memory
management logic associated with these variables were updated.
CVE: CVE-2024-11053
Upstream-Status: Backport [https://github.com/curl/curl/commit/e9b9bbac22c26cf67316fa8e6c6b9e831af3194]
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
---
lib/netrc.c | 122 ++++++++++++++++++++++------------------
lib/url.c | 59 ++++++++++++-------
tests/data/Makefile.inc | 2 +-
tests/data/test478 | 73 ++++++++++++++++++++++++
tests/data/test479 | 107 +++++++++++++++++++++++++++++++++++
tests/data/test480 | 38 +++++++++++++
tests/unit/unit1304.c | 75 +++++++-----------------
7 files changed, 347 insertions(+), 129 deletions(-)
create mode 100644 tests/data/test478
create mode 100644 tests/data/test479
create mode 100644 tests/data/test480
diff --git a/lib/netrc.c b/lib/netrc.c
index cd2a284..64efdc0 100644
--- a/lib/netrc.c
+++ b/lib/netrc.c
@@ -49,6 +49,15 @@ enum host_lookup_state {
MACDEF
};
+enum found_state {
+ NONE,
+ LOGIN,
+ PASSWORD
+};
+
+#define FOUND_LOGIN 1
+#define FOUND_PASSWORD 2
+
#define NETRC_FILE_MISSING 1
#define NETRC_FAILED -1
#define NETRC_SUCCESS 0
@@ -59,23 +68,20 @@ enum host_lookup_state {
* Returns zero on success.
*/
static int parsenetrc(const char *host,
- char **loginp,
+ char **loginp, /* might point to a username */
char **passwordp,
char *netrcfile)
{
FILE *file;
int retcode = NETRC_FILE_MISSING;
char *login = *loginp;
- char *password = *passwordp;
- bool specific_login = (login && *login != 0);
- bool login_alloc = FALSE;
- bool password_alloc = FALSE;
+ char *password = NULL;
+ bool specific_login = login; /* points to something */
enum host_lookup_state state = NOTHING;
-
- char state_login = 0; /* Found a login keyword */
- char state_password = 0; /* Found a password keyword */
- int state_our_login = TRUE; /* With specific_login, found *our* login
- name (or login-less line) */
+ enum found_state keyword = NONE;
+ unsigned char found = 0; /* login + password found bits, as they can come in
+ any order */
+ bool our_login = FALSE; /* found our login name */
DEBUGASSERT(netrcfile);
@@ -97,7 +103,7 @@ static int parsenetrc(const char *host,
continue;
}
tok = netrcbuffer;
- while(tok) {
+ while(tok && !done) {
while(ISBLANK(*tok))
tok++;
/* tok is first non-space letter */
@@ -156,11 +162,6 @@ static int parsenetrc(const char *host,
}
}
- if((login && *login) && (password && *password)) {
- done = TRUE;
- break;
- }
-
switch(state) {
case NOTHING:
if(strcasecompare("macdef", tok)) {
@@ -175,6 +176,12 @@ static int parsenetrc(const char *host,
after this we need to search for 'login' and
'password'. */
state = HOSTFOUND;
+ keyword = NONE;
+ found = 0;
+ our_login = FALSE;
+ Curl_safefree(password);
+ if(!specific_login)
+ Curl_safefree(login);
}
else if(strcasecompare("default", tok)) {
state = HOSTVALID;
@@ -198,48 +205,55 @@ static int parsenetrc(const char *host,
break;
case HOSTVALID:
/* we are now parsing sub-keywords concerning "our" host */
- if(state_login) {
+ if(keyword == LOGIN) {
if(specific_login) {
- state_our_login = !Curl_timestrcmp(login, tok);
+ our_login = !Curl_timestrcmp(login, tok);
}
- else if(!login || Curl_timestrcmp(login, tok)) {
- if(login_alloc) {
- free(login);
- login_alloc = FALSE;
- }
+ else {
+ our_login = TRUE;
+ free(login);
login = strdup(tok);
if(!login) {
retcode = NETRC_FAILED; /* allocation failed */
goto out;
}
- login_alloc = TRUE;
}
- state_login = 0;
+ found |= FOUND_LOGIN;
+ keyword = NONE;
}
- else if(state_password) {
- if((state_our_login || !specific_login)
- && (!password || Curl_timestrcmp(password, tok))) {
- if(password_alloc) {
- free(password);
- password_alloc = FALSE;
- }
- password = strdup(tok);
- if(!password) {
- retcode = NETRC_FAILED; /* allocation failed */
- goto out;
- }
- password_alloc = TRUE;
+ else if(keyword == PASSWORD) {
+ free(password);
+ password = strdup(tok);
+ if(!password) {
+ retcode = NETRC_FAILED; /* allocation failed */
+ goto out;
}
- state_password = 0;
+ found |= FOUND_PASSWORD;
+ keyword = NONE;
}
else if(strcasecompare("login", tok))
- state_login = 1;
+ keyword = LOGIN;
else if(strcasecompare("password", tok))
- state_password = 1;
+ keyword = PASSWORD;
else if(strcasecompare("machine", tok)) {
- /* ok, there's machine here go => */
+ /* a new machine here */
state = HOSTFOUND;
- state_our_login = FALSE;
+ keyword = NONE;
+ found = 0;
+ Curl_safefree(password);
+ if(!specific_login)
+ Curl_safefree(login);
+ }
+ else if(strcasecompare("default", tok)) {
+ state = HOSTVALID;
+ retcode = NETRC_SUCCESS; /* we did find our host */
+ Curl_safefree(password);
+ if(!specific_login)
+ Curl_safefree(login);
+ }
+ if((found == (FOUND_PASSWORD|FOUND_LOGIN)) && our_login) {
+ done = TRUE;
+ break;
}
break;
} /* switch (state) */
@@ -249,24 +263,22 @@ static int parsenetrc(const char *host,
out:
Curl_dyn_free(&buf);
+ if(!retcode && !password && our_login) {
+ /* success without a password, set a blank one */
+ password = strdup("");
+ if(!password)
+ retcode = 1; /* out of memory */
+ }
if(!retcode) {
/* success */
- if(login_alloc) {
- if(*loginp)
- free(*loginp);
+ if(!specific_login)
*loginp = login;
- }
- if(password_alloc) {
- if(*passwordp)
- free(*passwordp);
- *passwordp = password;
- }
+ *passwordp = password;
}
else {
- if(login_alloc)
+ if(!specific_login)
free(login);
- if(password_alloc)
- free(password);
+ free(password);
}
fclose(file);
}
diff --git a/lib/url.c b/lib/url.c
index 05431b9..1439c9e 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -2699,6 +2699,17 @@ static CURLcode parse_remote_port(struct Curl_easy *data,
return CURLE_OK;
}
+static bool str_has_ctrl(const char *input)
+{
+ const unsigned char *str = (const unsigned char *)input;
+ while(*str) {
+ if(*str < 0x20)
+ return TRUE;
+ str++;
+ }
+ return FALSE;
+}
+
/*
* Override the login details from the URL with that in the CURLOPT_USERPWD
* option or a .netrc file, if applicable.
@@ -2730,29 +2741,39 @@ static CURLcode override_login(struct Curl_easy *data,
if(data->state.aptr.user &&
(data->state.creds_from != CREDS_NETRC)) {
- /* there was a user name in the URL. Use the URL decoded version */
+ /* there was a username with a length in the URL. Use the URL decoded
+ version */
userp = &data->state.aptr.user;
url_provided = TRUE;
}
- ret = Curl_parsenetrc(conn->host.name,
- userp, passwdp,
- data->set.str[STRING_NETRC_FILE]);
- if(ret > 0) {
- infof(data, "Couldn't find host %s in the %s file; using defaults",
- conn->host.name,
- (data->set.str[STRING_NETRC_FILE] ?
- data->set.str[STRING_NETRC_FILE] : ".netrc"));
- }
- else if(ret < 0) {
- failf(data, ".netrc parser error");
- return CURLE_READ_ERROR;
- }
- else {
- /* set bits.netrc TRUE to remember that we got the name from a .netrc
- file, so that it is safe to use even if we followed a Location: to a
- different host or similar. */
- conn->bits.netrc = TRUE;
+ if(!*passwdp) {
+ ret = Curl_parsenetrc(conn->host.name, userp, passwdp,
+ data->set.str[STRING_NETRC_FILE]);
+ if(ret > 0) {
+ infof(data, "Couldn't find host %s in the %s file; using defaults",
+ conn->host.name,
+ (data->set.str[STRING_NETRC_FILE] ?
+ data->set.str[STRING_NETRC_FILE] : ".netrc"));
+ }
+ else if(ret < 0) {
+ failf(data, ".netrc parser error");
+ return CURLE_READ_ERROR;
+ }
+ else {
+ if(!(conn->handler->flags&PROTOPT_USERPWDCTRL)) {
+ /* if the protocol can't handle control codes in credentials, make
+ sure there are none */
+ if(str_has_ctrl(*userp) || str_has_ctrl(*passwdp)) {
+ failf(data, "control code detected in .netrc credentials");
+ return CURLE_READ_ERROR;
+ }
+ }
+ /* set bits.netrc TRUE to remember that we got the name from a .netrc
+ file, so that it is safe to use even if we followed a Location: to a
+ different host or similar. */
+ conn->bits.netrc = TRUE;
+ }
}
if(url_provided) {
Curl_safefree(conn->user);
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 03cb6a0..e3508cb 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -73,7 +73,7 @@ test426 test427 test428 test429 test430 test431 test432 test433 test434 \
test435 test436 test437 test438 test439 test440 test441 test442 test443 \
test444 test445 test446 test447 test448 test449 test450 test451 test452 \
test453 test454 test455 test456 test457 test458 test459 test460 test461 \
-test462 test463 test467 test468 \
+test462 test463 test467 test468 test478 test479 test480 \
\
test490 test491 test492 test493 test494 test495 test496 test497 test498 \
test499 test500 test501 test502 test503 test504 test505 test506 test507 \
diff --git a/tests/data/test478 b/tests/data/test478
new file mode 100644
index 0000000..4acc72e
--- /dev/null
+++ b/tests/data/test478
@@ -0,0 +1,73 @@
+<testcase>
+ <info>
+ <keywords>
+ netrc
+ HTTP
+ </keywords>
+ </info>
+ #
+ # Server-side
+ <reply>
+ <data crlf="yes">
+ HTTP/1.1 200 OK
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Server: test-server/fake
+ Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ ETag: "21025-dc7-39462498"
+ Accept-Ranges: bytes
+ Content-Length: 6
+ Connection: close
+ Content-Type: text/html
+ Funny-head: yesyes
+
+ -foo-
+ </data>
+ </reply>
+
+ #
+ # Client-side
+ <client>
+ <server>
+ http
+ </server>
+ <features>
+ proxy
+ </features>
+ <name>
+ .netrc with multiple accounts for same host
+ </name>
+ <command>
+ --netrc --netrc-file log/netrc%TESTNUMBER -x http://%HOSTIP:%HTTPPORT/ http://debbie@github.com/
+ </command>
+ <file name="log/netrc%TESTNUMBER" >
+
+ machine github.com
+ password weird
+ password firstone
+ login daniel
+
+ machine github.com
+
+ machine github.com
+ login debbie
+
+ machine github.com
+ password weird
+ password "second\r"
+ login debbie
+
+ </file>
+ </client>
+
+ <verify>
+ <protocol>
+ GET http://github.com/ HTTP/1.1
+ Host: github.com
+ Authorization: Basic %b64[debbie:second%0D]b64%
+ User-Agent: curl/%VERSION
+ Accept: */*
+ Proxy-Connection: Keep-Alive
+
+ </protocol>
+ </verify>
+ </testcase>
diff --git a/tests/data/test479 b/tests/data/test479
new file mode 100644
index 0000000..62a2057
--- /dev/null
+++ b/tests/data/test479
@@ -0,0 +1,107 @@
+<testcase>
+ <info>
+ <keywords>
+ netrc
+ HTTP
+ </keywords>
+ </info>
+ #
+ # Server-side
+ <reply>
+ <data crlf="yes">
+ HTTP/1.1 301 Follow this you fool
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Server: test-server/fake
+ Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ ETag: "21025-dc7-39462498"
+ Accept-Ranges: bytes
+ Content-Length: 6
+ Connection: close
+ Location: http://b.com/%TESTNUMBER0002
+
+ -foo-
+ </data>
+
+ <data2 crlf="yes">
+ HTTP/1.1 200 OK
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Server: test-server/fake
+ Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ ETag: "21025-dc7-39462498"
+ Accept-Ranges: bytes
+ Content-Length: 7
+ Connection: close
+
+ target
+ </data2>
+
+ <datacheck crlf="yes">
+ HTTP/1.1 301 Follow this you fool
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Server: test-server/fake
+ Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ ETag: "21025-dc7-39462498"
+ Accept-Ranges: bytes
+ Content-Length: 6
+ Connection: close
+ Location: http://b.com/%TESTNUMBER0002
+
+ HTTP/1.1 200 OK
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Server: test-server/fake
+ Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ ETag: "21025-dc7-39462498"
+ Accept-Ranges: bytes
+ Content-Length: 7
+ Connection: close
+
+ target
+ </datacheck>
+ </reply>
+
+ #
+ # Client-side
+ <client>
+ <server>
+ http
+ </server>
+ <features>
+ proxy
+ </features>
+ <name>
+ .netrc with redirect and default without password
+ </name>
+ <command>
+ --netrc --netrc-file log/netrc%TESTNUMBER -L -x http://%HOSTIP:%HTTPPORT/ http://a.com/
+ </command>
+ <file name="log/netrc%TESTNUMBER" >
+
+ machine a.com
+ login alice
+ password alicespassword
+
+ default
+ login bob
+
+ </file>
+ </client>
+
+ <verify>
+ <protocol>
+ GET http://a.com/ HTTP/1.1
+ Host: a.com
+ Authorization: Basic %b64[alice:alicespassword]b64%
+ User-Agent: curl/%VERSION
+ Accept: */*
+ Proxy-Connection: Keep-Alive
+
+ GET http://b.com/%TESTNUMBER0002 HTTP/1.1
+ Host: b.com
+ Authorization: Basic %b64[bob:]b64%
+ User-Agent: curl/%VERSION
+ Accept: */*
+ Proxy-Connection: Keep-Alive
+
+ </protocol>
+ </verify>
+ </testcase>
diff --git a/tests/data/test480 b/tests/data/test480
new file mode 100644
index 0000000..47db7ab
--- /dev/null
+++ b/tests/data/test480
@@ -0,0 +1,38 @@
+<testcase>
+ <info>
+ <keywords>
+ netrc
+ pop3
+ </keywords>
+ </info>
+ #
+ # Server-side
+ <reply>
+
+ </reply>
+
+ #
+ # Client-side
+ <client>
+ <server>
+ pop3
+ </server>
+ <name>
+ Reject .netrc with credentials using CRLF for POP3
+ </name>
+ <command>
+ --netrc --netrc-file log/netrc%TESTNUMBER pop3://%HOSTIP:%POP3PORT/%TESTNUMBER
+ </command>
+ <file name="log/netrc%TESTNUMBER" >
+ machine %HOSTIP
+ login alice
+ password "password\r\ncommand"
+ </file>
+ </client>
+
+ <verify>
+ <errorcode>
+ 26
+ </errorcode>
+ </verify>
+ </testcase>
diff --git a/tests/unit/unit1304.c b/tests/unit/unit1304.c
index 0288562..b2b4366 100644
--- a/tests/unit/unit1304.c
+++ b/tests/unit/unit1304.c
@@ -32,13 +32,8 @@ static char *password;
static CURLcode unit_setup(void)
{
- password = strdup("");
- login = strdup("");
- if(!password || !login) {
- Curl_safefree(password);
- Curl_safefree(login);
- return CURLE_OUT_OF_MEMORY;
- }
+ password = NULL;
+ login = NULL;
return CURLE_OK;
}
@@ -56,76 +51,48 @@ UNITTEST_START
*/
result = Curl_parsenetrc("test.example.com", &login, &password, arg);
fail_unless(result == 1, "Host not found should return 1");
- abort_unless(password != NULL, "returned NULL!");
- fail_unless(password[0] == 0, "password should not have been changed");
- abort_unless(login != NULL, "returned NULL!");
- fail_unless(login[0] == 0, "login should not have been changed");
+ abort_unless(password == NULL, "password did not return NULL!");
+ abort_unless(login == NULL, "user did not return NULL!");
/*
* Test a non existent login in our netrc file.
*/
- free(login);
- login = strdup("me");
- abort_unless(login != NULL, "returned NULL!");
+ login = (char *)"me";
result = Curl_parsenetrc("example.com", &login, &password, arg);
fail_unless(result == 0, "Host should have been found");
- abort_unless(password != NULL, "returned NULL!");
- fail_unless(password[0] == 0, "password should not have been changed");
- abort_unless(login != NULL, "returned NULL!");
- fail_unless(strncmp(login, "me", 2) == 0,
- "login should not have been changed");
+ abort_unless(password == NULL, "password is not NULL!");
/*
* Test a non existent login and host in our netrc file.
*/
- free(login);
- login = strdup("me");
- abort_unless(login != NULL, "returned NULL!");
+ login = (char *)"me";
result = Curl_parsenetrc("test.example.com", &login, &password, arg);
fail_unless(result == 1, "Host not found should return 1");
- abort_unless(password != NULL, "returned NULL!");
- fail_unless(password[0] == 0, "password should not have been changed");
- abort_unless(login != NULL, "returned NULL!");
- fail_unless(strncmp(login, "me", 2) == 0,
- "login should not have been changed");
+ abort_unless(password == NULL, "password is not NULL!");
/*
* Test a non existent login (substring of an existing one) in our
* netrc file.
*/
- free(login);
- login = strdup("admi");
- abort_unless(login != NULL, "returned NULL!");
+ login = (char *)"admi";
result = Curl_parsenetrc("example.com", &login, &password, arg);
fail_unless(result == 0, "Host should have been found");
- abort_unless(password != NULL, "returned NULL!");
- fail_unless(password[0] == 0, "password should not have been changed");
- abort_unless(login != NULL, "returned NULL!");
- fail_unless(strncmp(login, "admi", 4) == 0,
- "login should not have been changed");
+ abort_unless(password == NULL, "password is not NULL!");
/*
* Test a non existent login (superstring of an existing one)
* in our netrc file.
*/
- free(login);
- login = strdup("adminn");
- abort_unless(login != NULL, "returned NULL!");
+ login = (char *)"adminn";
result = Curl_parsenetrc("example.com", &login, &password, arg);
fail_unless(result == 0, "Host should have been found");
- abort_unless(password != NULL, "returned NULL!");
- fail_unless(password[0] == 0, "password should not have been changed");
- abort_unless(login != NULL, "returned NULL!");
- fail_unless(strncmp(login, "adminn", 6) == 0,
- "login should not have been changed");
+ abort_unless(password == NULL, "password is not NULL!");
/*
* Test for the first existing host in our netrc file
* with login[0] = 0.
*/
- free(login);
- login = strdup("");
- abort_unless(login != NULL, "returned NULL!");
+ login = NULL;
result = Curl_parsenetrc("example.com", &login, &password, arg);
fail_unless(result == 0, "Host should have been found");
abort_unless(password != NULL, "returned NULL!");
@@ -139,8 +106,9 @@ UNITTEST_START
* with login[0] != 0.
*/
free(password);
- password = strdup("");
- abort_unless(password != NULL, "returned NULL!");
+ free(login);
+ password = NULL;
+ login = NULL;
result = Curl_parsenetrc("example.com", &login, &password, arg);
fail_unless(result == 0, "Host should have been found");
abort_unless(password != NULL, "returned NULL!");
@@ -154,11 +122,9 @@ UNITTEST_START
* with login[0] = 0.
*/
free(password);
- password = strdup("");
- abort_unless(password != NULL, "returned NULL!");
+ password = NULL;
free(login);
- login = strdup("");
- abort_unless(login != NULL, "returned NULL!");
+ login = NULL;
result = Curl_parsenetrc("curl.example.com", &login, &password, arg);
fail_unless(result == 0, "Host should have been found");
abort_unless(password != NULL, "returned NULL!");
@@ -172,8 +138,9 @@ UNITTEST_START
* with login[0] != 0.
*/
free(password);
- password = strdup("");
- abort_unless(password != NULL, "returned NULL!");
+ free(login);
+ password = NULL;
+ login = NULL;
result = Curl_parsenetrc("curl.example.com", &login, &password, arg);
fail_unless(result == 0, "Host should have been found");
abort_unless(password != NULL, "returned NULL!");
--
2.40.0

View File

@@ -0,0 +1,130 @@
From 9fce2c55d4b0273ac99b59bd8cb982a6d96b88cf Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 17 Dec 2024 23:56:42 +0100
Subject: [PATCH] netrc: fix password-only entries
When a specific hostname matched, and only a password is set before
another machine is specified in the netrc file, the parser would not be
happy and stop there and return the password-only state. It instead
continued and did not return a match.
Add test 2005 to verify this case
Regression from e9b9bba, shipped in 8.11.1.
Reported-by: Ben Zanin
Fixes #15767
Closes #15768
CVE: CVE-2024-11053
Upstream-Status: Backport [https://github.com/curl/curl/commit/9fce2c55d4b0273ac99b59bd8cb982a6d96b88cf]
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
---
lib/netrc.c | 7 +++++-
tests/data/Makefile.inc | 2 +-
tests/data/test2005 | 55 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 62 insertions(+), 2 deletions(-)
create mode 100644 tests/data/test2005
diff --git a/lib/netrc.c b/lib/netrc.c
index 64efdc0..695e89a 100644
--- a/lib/netrc.c
+++ b/lib/netrc.c
@@ -228,7 +228,8 @@ static int parsenetrc(const char *host,
retcode = NETRC_FAILED; /* allocation failed */
goto out;
}
- found |= FOUND_PASSWORD;
+ if(!specific_login || our_login)
+ found |= FOUND_PASSWORD;
keyword = NONE;
}
else if(strcasecompare("login", tok))
@@ -237,6 +238,10 @@ static int parsenetrc(const char *host,
keyword = PASSWORD;
else if(strcasecompare("machine", tok)) {
/* a new machine here */
+ if(found & FOUND_PASSWORD) {
+ done = TRUE;
+ break;
+ }
state = HOSTFOUND;
keyword = NONE;
found = 0;
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index e3508cb..dc2af79 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -230,7 +230,7 @@ test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 \
test1955 test1956 test1957 test1958 test1959 test1960 test1964 \
test1970 test1971 test1972 test1973 test1974 test1975 \
\
-test2000 test2001 test2002 test2003 test2004 \
+test2000 test2001 test2002 test2003 test2004 test2005 \
\
test2023 \
test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
diff --git a/tests/data/test2005 b/tests/data/test2005
new file mode 100644
index 0000000..66afe84
--- /dev/null
+++ b/tests/data/test2005
@@ -0,0 +1,55 @@
+<testcase>
+ <info>
+ <keywords>
+ HTTP
+ netrc
+ </keywords>
+ </info>
+ #
+ # Server-side
+ <reply>
+ <data>
+ HTTP/1.1 200 OK
+ Date: Fri, 05 Aug 2022 10:09:00 GMT
+ Server: test-server/fake
+ Content-Type: text/plain
+ Content-Length: 6
+ Connection: close
+
+ -foo-
+ </data>
+ </reply>
+
+ #
+ # Client-side
+ <client>
+ <server>
+ http
+ </server>
+ <name>
+ netrc match with password only in file, no username. machine follows
+ </name>
+ <command>
+ --netrc-optional --netrc-file log/netrc%TESTNUMBER http://%HOSTIP:%HTTPPORT/
+ </command>
+ <file name="log/netrc%TESTNUMBER" >
+ machine %HOSTIP
+ password 5up3r53cr37
+
+ machine example.com
+ </file>
+ </client>
+
+ #
+ # Verify data after the test has been "shot"
+ <verify>
+ <protocol>
+ GET / HTTP/1.1
+ Host: %HOSTIP:%HTTPPORT
+ Authorization: Basic %b64[:5up3r53cr37]b64%
+ User-Agent: curl/%VERSION
+ Accept: */*
+
+ </protocol>
+ </verify>
+ </testcase>
--
2.40.0

View File

@@ -0,0 +1,24 @@
From 3a537a4db9e65e545ec45b1b5d5575ee09a2569d Mon Sep 17 00:00:00 2001
From: z2_ <88509734+z2-2z@users.noreply.github.com>
Date: Fri, 28 Jun 2024 14:45:47 +0200
Subject: [PATCH] x509asn1: remove superfluous free()
CVE: CVE-2024-6197
Upstream-Status: Backport [https://github.com/curl/curl/commit/3a537a4db9e65e545ec45b1b5d5575ee09a2569d.patch]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
lib/vtls/x509asn1.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c
index f71ab0b90a5931..1bc4243ddae343 100644
--- a/lib/vtls/x509asn1.c
+++ b/lib/vtls/x509asn1.c
@@ -393,7 +393,6 @@ utf8asn1str(struct dynbuf *to, int type, const char *from, const char *end)
if(wc >= 0x00000800) {
if(wc >= 0x00010000) {
if(wc >= 0x00200000) {
- free(buf);
/* Invalid char. size for target encoding. */
return CURLE_WEIRD_SERVER_REPLY;
}

View File

@@ -0,0 +1,61 @@
From 3c914bc680155b32178f1f15ca8d47c7f4640afe Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 30 Jul 2024 10:05:17 +0200
Subject: [PATCH] x509asn1: clean up GTime2str
Co-authored-by: Stefan Eissing
Reported-by: Dov Murik
Closes #14307
CVE: CVE-2024-7264
Upstream-Status: Backport [https://github.com/curl/curl/commit/3c914bc680155b32178f1f15ca8d47c7f4640afe.patch]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
lib/vtls/x509asn1.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c
index 1bc4243ddae343..e3a9fe4232a4ea 100644
--- a/lib/vtls/x509asn1.c
+++ b/lib/vtls/x509asn1.c
@@ -488,7 +488,7 @@ static CURLcode GTime2str(struct dynbuf *store,
/* Convert an ASN.1 Generalized time to a printable string.
Return the dynamically allocated string, or NULL if an error occurs. */
- for(fracp = beg; fracp < end && *fracp >= '0' && *fracp <= '9'; fracp++)
+ for(fracp = beg; fracp < end && ISDIGIT(*fracp); fracp++)
;
/* Get seconds digits. */
@@ -507,17 +507,22 @@ static CURLcode GTime2str(struct dynbuf *store,
return CURLE_BAD_FUNCTION_ARGUMENT;
}
- /* Scan for timezone, measure fractional seconds. */
+ /* timezone follows optional fractional seconds. */
tzp = fracp;
- fracl = 0;
+ fracl = 0; /* no fractional seconds detected so far */
if(fracp < end && (*fracp == '.' || *fracp == ',')) {
- fracp++;
- do
+ /* Have fractional seconds, e.g. "[.,]\d+". How many? */
+ tzp = fracp++; /* should be a digit char or BAD ARGUMENT */
+ while(tzp < end && ISDIGIT(*tzp))
tzp++;
- while(tzp < end && *tzp >= '0' && *tzp <= '9');
- /* Strip leading zeroes in fractional seconds. */
- for(fracl = tzp - fracp - 1; fracl && fracp[fracl - 1] == '0'; fracl--)
- ;
+ if(tzp == fracp) /* never looped, no digit after [.,] */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ fracl = tzp - fracp - 1; /* number of fractional sec digits */
+ DEBUGASSERT(fracl > 0);
+ /* Strip trailing zeroes in fractional seconds.
+ * May reduce fracl to 0 if only '0's are present. */
+ while(fracl && fracp[fracl - 1] == '0')
+ fracl--;
}
/* Process timezone. */

View File

@@ -0,0 +1,316 @@
From 27959ecce75cdb2809c0bdb3286e60e08fadb519 Mon Sep 17 00:00:00 2001
From: Stefan Eissing <stefan@eissing.org>
Date: Tue, 30 Jul 2024 16:40:48 +0200
Subject: [PATCH] x509asn1: unittests and fixes for gtime2str
Fix issues in GTime2str() and add unit test cases to verify correct
behaviour.
Follow-up to 3c914bc6801
Closes #14316
CVE: CVE-2024-7264
Upstream-Status: Backport [https://github.com/curl/curl/commit/27959ecce75cdb2809c0bdb3286e60e08fadb519.patch]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
lib/vtls/x509asn1.c | 32 +++++++---
lib/vtls/x509asn1.h | 11 ++++
tests/data/Makefile.inc | 2 +-
tests/data/test1656 | 22 +++++++
tests/unit/Makefile.inc | 4 +-
tests/unit/unit1656.c | 133 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 194 insertions(+), 10 deletions(-)
create mode 100644 tests/data/test1656
create mode 100644 tests/unit/unit1656.c
diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c
index e3a9fe4232a4ea..7f04af3b9778c5 100644
--- a/lib/vtls/x509asn1.c
+++ b/lib/vtls/x509asn1.c
@@ -512,12 +512,13 @@ static CURLcode GTime2str(struct dynbuf *store,
fracl = 0; /* no fractional seconds detected so far */
if(fracp < end && (*fracp == '.' || *fracp == ',')) {
/* Have fractional seconds, e.g. "[.,]\d+". How many? */
- tzp = fracp++; /* should be a digit char or BAD ARGUMENT */
+ fracp++; /* should be a digit char or BAD ARGUMENT */
+ tzp = fracp;
while(tzp < end && ISDIGIT(*tzp))
tzp++;
if(tzp == fracp) /* never looped, no digit after [.,] */
return CURLE_BAD_FUNCTION_ARGUMENT;
- fracl = tzp - fracp - 1; /* number of fractional sec digits */
+ fracl = tzp - fracp; /* number of fractional sec digits */
DEBUGASSERT(fracl > 0);
/* Strip trailing zeroes in fractional seconds.
* May reduce fracl to 0 if only '0's are present. */
@@ -526,18 +527,24 @@ static CURLcode GTime2str(struct dynbuf *store,
}
/* Process timezone. */
- if(tzp >= end)
- ; /* Nothing to do. */
+ if(tzp >= end) {
+ tzp = "";
+ tzl = 0;
+ }
else if(*tzp == 'Z') {
- tzp = " GMT";
- end = tzp + 4;
+ sep = " ";
+ tzp = "GMT";
+ tzl = 3;
+ }
+ else if((*tzp == '+') || (*tzp == '-')) {
+ sep = " UTC";
+ tzl = end - tzp;
}
else {
sep = " ";
- tzp++;
+ tzl = end - tzp;
}
- tzl = end - tzp;
return Curl_dyn_addf(store,
"%.4s-%.2s-%.2s %.2s:%.2s:%c%c%s%.*s%s%.*s",
beg, beg + 4, beg + 6,
@@ -546,6 +553,15 @@ static CURLcode GTime2str(struct dynbuf *store,
sep, (int)tzl, tzp);
}
+#ifdef UNITTESTS
+/* used by unit1656.c */
+CURLcode Curl_x509_GTime2str(struct dynbuf *store,
+ const char *beg, const char *end)
+{
+ return GTime2str(store, beg, end);
+}
+#endif
+
/*
* Convert an ASN.1 UTC time to a printable string.
*
diff --git a/lib/vtls/x509asn1.h b/lib/vtls/x509asn1.h
index 5844460467ccef..5b48596c75910a 100644
--- a/lib/vtls/x509asn1.h
+++ b/lib/vtls/x509asn1.h
@@ -76,5 +76,16 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, int certnum,
const char *beg, const char *end);
CURLcode Curl_verifyhost(struct Curl_cfilter *cf, struct Curl_easy *data,
const char *beg, const char *end);
+
+#ifdef UNITTESTS
+#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \
+ defined(USE_MBEDTLS)
+
+/* used by unit1656.c */
+CURLcode Curl_x509_GTime2str(struct dynbuf *store,
+ const char *beg, const char *end);
+#endif
+#endif
+
#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP */
#endif /* HEADER_CURL_X509ASN1_H */
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index d0e20df4b900c8..792cb16eef20ad 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -210,7 +210,7 @@ test1620 test1621 \
\
test1630 test1631 test1632 test1633 test1634 test1635 \
\
-test1650 test1651 test1652 test1653 test1654 test1655 \
+test1650 test1651 test1652 test1653 test1654 test1655 test1656 \
test1660 test1661 test1662 \
\
test1670 test1671 \
diff --git a/tests/data/test1656 b/tests/data/test1656
new file mode 100644
index 00000000000000..2fab21be63d7e3
--- /dev/null
+++ b/tests/data/test1656
@@ -0,0 +1,22 @@
+<testcase>
+<info>
+<keywords>
+unittest
+Curl_x509_GTime2str
+</keywords>
+</info>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+<features>
+unittest
+</features>
+<name>
+Curl_x509_GTime2str unit tests
+</name>
+</client>
+</testcase>
diff --git a/tests/unit/Makefile.inc b/tests/unit/Makefile.inc
index c402f803509c8a..5b23c2559280f0 100644
--- a/tests/unit/Makefile.inc
+++ b/tests/unit/Makefile.inc
@@ -36,7 +36,7 @@ UNITPROGS = unit1300 unit1302 unit1303 unit1304 unit1305 unit1307 \
unit1600 unit1601 unit1602 unit1603 unit1604 unit1605 unit1606 unit1607 \
unit1608 unit1609 unit1610 unit1611 unit1612 unit1614 unit1615 \
unit1620 unit1621 \
- unit1650 unit1651 unit1652 unit1653 unit1654 unit1655 \
+ unit1650 unit1651 unit1652 unit1653 unit1654 unit1655 unit1656 \
unit1660 unit1661 \
unit2600 unit2601 unit2602 unit2603 \
unit3200
@@ -119,6 +119,8 @@ unit1654_SOURCES = unit1654.c $(UNITFILES)
unit1655_SOURCES = unit1655.c $(UNITFILES)
+unit1656_SOURCES = unit1656.c $(UNITFILES)
+
unit1660_SOURCES = unit1660.c $(UNITFILES)
unit1661_SOURCES = unit1661.c $(UNITFILES)
diff --git a/tests/unit/unit1656.c b/tests/unit/unit1656.c
new file mode 100644
index 00000000000000..644e72fc7d6577
--- /dev/null
+++ b/tests/unit/unit1656.c
@@ -0,0 +1,133 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curlcheck.h"
+
+#include "vtls/x509asn1.h"
+
+static CURLcode unit_setup(void)
+{
+ return CURLE_OK;
+}
+
+static void unit_stop(void)
+{
+
+}
+
+#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \
+ defined(USE_MBEDTLS)
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
+#endif
+
+struct test_spec {
+ const char *input;
+ const char *exp_output;
+ CURLcode exp_result;
+};
+
+static struct test_spec test_specs[] = {
+ { "190321134340", "1903-21-13 43:40:00", CURLE_OK },
+ { "", NULL, CURLE_BAD_FUNCTION_ARGUMENT },
+ { "WTF", NULL, CURLE_BAD_FUNCTION_ARGUMENT },
+ { "0WTF", NULL, CURLE_BAD_FUNCTION_ARGUMENT },
+ { "19032113434", NULL, CURLE_BAD_FUNCTION_ARGUMENT },
+ { "19032113434WTF", NULL, CURLE_BAD_FUNCTION_ARGUMENT },
+ { "190321134340.", NULL, CURLE_BAD_FUNCTION_ARGUMENT },
+ { "190321134340.1", "1903-21-13 43:40:00.1", CURLE_OK },
+ { "19032113434017.0", "1903-21-13 43:40:17", CURLE_OK },
+ { "19032113434017.01", "1903-21-13 43:40:17.01", CURLE_OK },
+ { "19032113434003.001", "1903-21-13 43:40:03.001", CURLE_OK },
+ { "19032113434003.090", "1903-21-13 43:40:03.09", CURLE_OK },
+ { "190321134340Z", "1903-21-13 43:40:00 GMT", CURLE_OK },
+ { "19032113434017.0Z", "1903-21-13 43:40:17 GMT", CURLE_OK },
+ { "19032113434017.01Z", "1903-21-13 43:40:17.01 GMT", CURLE_OK },
+ { "19032113434003.001Z", "1903-21-13 43:40:03.001 GMT", CURLE_OK },
+ { "19032113434003.090Z", "1903-21-13 43:40:03.09 GMT", CURLE_OK },
+ { "190321134340CET", "1903-21-13 43:40:00 CET", CURLE_OK },
+ { "19032113434017.0CET", "1903-21-13 43:40:17 CET", CURLE_OK },
+ { "19032113434017.01CET", "1903-21-13 43:40:17.01 CET", CURLE_OK },
+ { "190321134340+02:30", "1903-21-13 43:40:00 UTC+02:30", CURLE_OK },
+ { "19032113434017.0+02:30", "1903-21-13 43:40:17 UTC+02:30", CURLE_OK },
+ { "19032113434017.01+02:30", "1903-21-13 43:40:17.01 UTC+02:30", CURLE_OK },
+ { "190321134340-3", "1903-21-13 43:40:00 UTC-3", CURLE_OK },
+ { "19032113434017.0-04", "1903-21-13 43:40:17 UTC-04", CURLE_OK },
+ { "19032113434017.01-01:10", "1903-21-13 43:40:17.01 UTC-01:10", CURLE_OK },
+};
+
+static bool do_test(struct test_spec *spec, size_t i, struct dynbuf *dbuf)
+{
+ CURLcode result;
+ const char *in = spec->input;
+
+ Curl_dyn_reset(dbuf);
+ result = Curl_x509_GTime2str(dbuf, in, in + strlen(in));
+ if(result != spec->exp_result) {
+ fprintf(stderr, "test %zu: expect result %d, got %d\n",
+ i, spec->exp_result, result);
+ return FALSE;
+ }
+ else if(!result && strcmp(spec->exp_output, Curl_dyn_ptr(dbuf))) {
+ fprintf(stderr, "test %zu: input '%s', expected output '%s', got '%s'\n",
+ i, in, spec->exp_output, Curl_dyn_ptr(dbuf));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+UNITTEST_START
+{
+ size_t i;
+ struct dynbuf dbuf;
+ bool all_ok = TRUE;
+
+ Curl_dyn_init(&dbuf, 32*1024);
+
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ for(i = 0; i < ARRAYSIZE(test_specs); ++i) {
+ if(!do_test(&test_specs[i], i, &dbuf))
+ all_ok = FALSE;
+ }
+ fail_unless(all_ok, "some tests of Curl_x509_GTime2str() fails");
+
+ Curl_dyn_free(&dbuf);
+ curl_global_cleanup();
+}
+UNITTEST_STOP
+
+#else
+
+UNITTEST_START
+{
+ puts("not tested since Curl_x509_GTime2str() is not built-in");
+}
+UNITTEST_STOP
+
+#endif

View File

@@ -0,0 +1,207 @@
From aeb1a281cab13c7ba791cb104e556b20e713941f Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 20 Aug 2024 16:14:39 +0200
Subject: [PATCH] gtls: fix OCSP stapling management
Reported-by: Hiroki Kurosawa
Closes #14642
Upstream-Status: Backport [https://github.com/curl/curl/commit/aeb1a281cab13c7ba791cb104e556b20e713941f]
CVE: CVE-2024-8096
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
---
lib/vtls/gtls.c | 146 ++++++++++++++++++++++++------------------------
1 file changed, 73 insertions(+), 73 deletions(-)
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 6eaa6a8..7dd7df8 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -538,6 +538,13 @@ CURLcode gtls_client_init(struct Curl_easy *data,
init_flags |= GNUTLS_NO_TICKETS;
#endif
+#if defined(GNUTLS_NO_STATUS_REQUEST)
+ if(!config->verifystatus)
+ /* Disable the "status_request" TLS extension, enabled by default since
+ GnuTLS 3.8.0. */
+ init_flags |= GNUTLS_NO_STATUS_REQUEST;
+#endif
+
rc = gnutls_init(&gtls->session, init_flags);
if(rc != GNUTLS_E_SUCCESS) {
failf(data, "gnutls_init() failed: %d", rc);
@@ -923,104 +930,97 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
infof(data, " server certificate verification SKIPPED");
if(config->verifystatus) {
- if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
- gnutls_datum_t status_request;
- gnutls_ocsp_resp_t ocsp_resp;
+ gnutls_datum_t status_request;
+ gnutls_ocsp_resp_t ocsp_resp;
+ gnutls_ocsp_cert_status_t status;
+ gnutls_x509_crl_reason_t reason;
- gnutls_ocsp_cert_status_t status;
- gnutls_x509_crl_reason_t reason;
+ rc = gnutls_ocsp_status_request_get(session, &status_request);
- rc = gnutls_ocsp_status_request_get(session, &status_request);
+ if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ failf(data, "No OCSP response received");
+ return CURLE_SSL_INVALIDCERTSTATUS;
+ }
- infof(data, " server certificate status verification FAILED");
+ if(rc < 0) {
+ failf(data, "Invalid OCSP response received");
+ return CURLE_SSL_INVALIDCERTSTATUS;
+ }
- if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
- failf(data, "No OCSP response received");
- return CURLE_SSL_INVALIDCERTSTATUS;
- }
+ gnutls_ocsp_resp_init(&ocsp_resp);
- if(rc < 0) {
- failf(data, "Invalid OCSP response received");
- return CURLE_SSL_INVALIDCERTSTATUS;
- }
+ rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
+ if(rc < 0) {
+ failf(data, "Invalid OCSP response received");
+ return CURLE_SSL_INVALIDCERTSTATUS;
+ }
- gnutls_ocsp_resp_init(&ocsp_resp);
+ (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
+ &status, NULL, NULL, NULL, &reason);
- rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
- if(rc < 0) {
- failf(data, "Invalid OCSP response received");
- return CURLE_SSL_INVALIDCERTSTATUS;
- }
+ switch(status) {
+ case GNUTLS_OCSP_CERT_GOOD:
+ break;
- (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
- &status, NULL, NULL, NULL, &reason);
+ case GNUTLS_OCSP_CERT_REVOKED: {
+ const char *crl_reason;
- switch(status) {
- case GNUTLS_OCSP_CERT_GOOD:
+ switch(reason) {
+ default:
+ case GNUTLS_X509_CRLREASON_UNSPECIFIED:
+ crl_reason = "unspecified reason";
break;
- case GNUTLS_OCSP_CERT_REVOKED: {
- const char *crl_reason;
-
- switch(reason) {
- default:
- case GNUTLS_X509_CRLREASON_UNSPECIFIED:
- crl_reason = "unspecified reason";
- break;
-
- case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
- crl_reason = "private key compromised";
- break;
-
- case GNUTLS_X509_CRLREASON_CACOMPROMISE:
- crl_reason = "CA compromised";
- break;
-
- case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
- crl_reason = "affiliation has changed";
- break;
+ case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
+ crl_reason = "private key compromised";
+ break;
- case GNUTLS_X509_CRLREASON_SUPERSEDED:
- crl_reason = "certificate superseded";
- break;
+ case GNUTLS_X509_CRLREASON_CACOMPROMISE:
+ crl_reason = "CA compromised";
+ break;
- case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
- crl_reason = "operation has ceased";
- break;
+ case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
+ crl_reason = "affiliation has changed";
+ break;
- case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
- crl_reason = "certificate is on hold";
- break;
+ case GNUTLS_X509_CRLREASON_SUPERSEDED:
+ crl_reason = "certificate superseded";
+ break;
- case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
- crl_reason = "will be removed from delta CRL";
- break;
+ case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
+ crl_reason = "operation has ceased";
+ break;
- case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
- crl_reason = "privilege withdrawn";
- break;
+ case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
+ crl_reason = "certificate is on hold";
+ break;
- case GNUTLS_X509_CRLREASON_AACOMPROMISE:
- crl_reason = "AA compromised";
- break;
- }
+ case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
+ crl_reason = "will be removed from delta CRL";
+ break;
- failf(data, "Server certificate was revoked: %s", crl_reason);
+ case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
+ crl_reason = "privilege withdrawn";
break;
- }
- default:
- case GNUTLS_OCSP_CERT_UNKNOWN:
- failf(data, "Server certificate status is unknown");
+ case GNUTLS_X509_CRLREASON_AACOMPROMISE:
+ crl_reason = "AA compromised";
break;
}
- gnutls_ocsp_resp_deinit(ocsp_resp);
+ failf(data, "Server certificate was revoked: %s", crl_reason);
+ break;
+ }
+
+ default:
+ case GNUTLS_OCSP_CERT_UNKNOWN:
+ failf(data, "Server certificate status is unknown");
+ break;
+ }
+ gnutls_ocsp_resp_deinit(ocsp_resp);
+ if(status != GNUTLS_OCSP_CERT_GOOD)
return CURLE_SSL_INVALIDCERTSTATUS;
- }
- else
- infof(data, " server certificate status verification OK");
}
else
infof(data, " server certificate status verification SKIPPED");
--
2.25.1

View File

@@ -0,0 +1,85 @@
From a94973805df96269bf3f3bf0a20ccb9887313316 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Wed, 9 Oct 2024 10:04:35 +0200
Subject: [PATCH] hsts: improve subdomain handling
- on load, only replace existing HSTS entries if there is a full host
match
- on matching, prefer a full host match and secondary the longest tail
subdomain match
Closes #15210
CVE: CVE-2024-9681
Upstream-Status: Backport [https://github.com/curl/curl/commit/a94973805df96269bf3f3bf0a20ccb9887313316]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
lib/hsts.c | 14 ++++++++++----
tests/data/test1660 | 2 +-
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/lib/hsts.c b/lib/hsts.c
index d5e883f51ef0f7..12052ce53c1c5a 100644
--- a/lib/hsts.c
+++ b/lib/hsts.c
@@ -254,12 +254,14 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
struct stsentry *Curl_hsts(struct hsts *h, const char *hostname,
bool subdomain)
{
+ struct stsentry *bestsub = NULL;
if(h) {
char buffer[MAX_HSTS_HOSTLEN + 1];
time_t now = time(NULL);
size_t hlen = strlen(hostname);
struct Curl_llist_element *e;
struct Curl_llist_element *n;
+ size_t blen = 0;
if((hlen > MAX_HSTS_HOSTLEN) || !hlen)
return NULL;
@@ -284,15 +286,19 @@ struct stsentry *Curl_hsts(struct hsts *h, const char *hostname,
if(ntail < hlen) {
size_t offs = hlen - ntail;
if((hostname[offs-1] == '.') &&
- strncasecompare(&hostname[offs], sts->host, ntail))
- return sts;
+ strncasecompare(&hostname[offs], sts->host, ntail) &&
+ (ntail > blen)) {
+ /* save the tail match with the longest tail */
+ bestsub = sts;
+ blen = ntail;
+ }
}
}
if(strcasecompare(hostname, sts->host))
return sts;
}
}
- return NULL; /* no match */
+ return bestsub;
}
/*
@@ -444,7 +450,7 @@ static CURLcode hsts_add(struct hsts *h, char *line)
e = Curl_hsts(h, p, subdomain);
if(!e)
result = hsts_create(h, p, subdomain, expires);
- else {
+ else if(strcasecompare(p, e->host)) {
/* the same host name, use the largest expire time */
if(expires > e->expires)
e->expires = expires;
diff --git a/tests/data/test1660 b/tests/data/test1660
index f86126d19cf269..4b6f9615c9d517 100644
--- a/tests/data/test1660
+++ b/tests/data/test1660
@@ -52,7 +52,7 @@ this.example [this.example]: 1548400797
Input 12: error 43
Input 13: error 43
Input 14: error 43
-3.example.com [example.com]: 1569905261 includeSubDomains
+3.example.com [3.example.com]: 1569905261 includeSubDomains
3.example.com [example.com]: 1569905261 includeSubDomains
foo.example.com [example.com]: 1569905261 includeSubDomains
'foo.xample.com' is not HSTS

View File

@@ -0,0 +1,178 @@
From 0e120c5b925e8ca75d5319e319e5ce4b8080d8eb Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 3 Jan 2025 16:22:27 +0100
Subject: [PATCH] netrc: 'default' with no credentials is not a match
Test 486 verifies.
Reported-by: Yihang Zhou
Closes #15908
Changes:
- Test files are added in Makefile.inc.
- Adjust `%LOGDIR/` to 'log/' due to its absence in code.
CVE: CVE-2025-0167
Upstream-Status: Backport [https://github.com/curl/curl/commit/0e120c5b925e8ca75d5319e]
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
---
lib/netrc.c | 15 ++++--
tests/data/Makefile.inc | 2 +-
tests/data/test486 | 105 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 116 insertions(+), 6 deletions(-)
create mode 100644 tests/data/test486
diff --git a/lib/netrc.c b/lib/netrc.c
index 64efdc0..5533ecc 100644
--- a/lib/netrc.c
+++ b/lib/netrc.c
@@ -263,11 +263,16 @@ static int parsenetrc(const char *host,
out:
Curl_dyn_free(&buf);
- if(!retcode && !password && our_login) {
- /* success without a password, set a blank one */
- password = strdup("");
- if(!password)
- retcode = 1; /* out of memory */
+ if(!retcode) {
+ if(!password && our_login) {
+ /* success without a password, set a blank one */
+ password = strdup("");
+ if(!password)
+ retcode = 1; /* out of memory */
+ }
+ else if(!login && !password)
+ /* a default with no credentials */
+ retcode = NETRC_FILE_MISSING;
}
if(!retcode) {
/* success */
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index e3508cb..7a8074f 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -73,7 +73,7 @@ test426 test427 test428 test429 test430 test431 test432 test433 test434 \
test435 test436 test437 test438 test439 test440 test441 test442 test443 \
test444 test445 test446 test447 test448 test449 test450 test451 test452 \
test453 test454 test455 test456 test457 test458 test459 test460 test461 \
-test462 test463 test467 test468 test478 test479 test480 \
+test462 test463 test467 test468 test478 test479 test480 test486 \
\
test490 test491 test492 test493 test494 test495 test496 test497 test498 \
test499 test500 test501 test502 test503 test504 test505 test506 test507 \
diff --git a/tests/data/test486 b/tests/data/test486
new file mode 100644
index 0000000..093899e
--- /dev/null
+++ b/tests/data/test486
@@ -0,0 +1,105 @@
+<testcase>
+ <info>
+ <keywords>
+ netrc
+ HTTP
+ </keywords>
+ </info>
+ #
+ # Server-side
+ <reply>
+ <data crlf="yes">
+ HTTP/1.1 301 Follow this you fool
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Server: test-server/fake
+ Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ ETag: "21025-dc7-39462498"
+ Accept-Ranges: bytes
+ Content-Length: 6
+ Connection: close
+ Location: http://b.com/%TESTNUMBER0002
+
+ -foo-
+ </data>
+
+ <data2 crlf="yes">
+ HTTP/1.1 200 OK
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Server: test-server/fake
+ Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ ETag: "21025-dc7-39462498"
+ Accept-Ranges: bytes
+ Content-Length: 7
+ Connection: close
+
+ target
+ </data2>
+
+ <datacheck crlf="yes">
+ HTTP/1.1 301 Follow this you fool
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Server: test-server/fake
+ Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ ETag: "21025-dc7-39462498"
+ Accept-Ranges: bytes
+ Content-Length: 6
+ Connection: close
+ Location: http://b.com/%TESTNUMBER0002
+
+ HTTP/1.1 200 OK
+ Date: Tue, 09 Nov 2010 14:49:00 GMT
+ Server: test-server/fake
+ Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ ETag: "21025-dc7-39462498"
+ Accept-Ranges: bytes
+ Content-Length: 7
+ Connection: close
+
+ target
+ </datacheck>
+ </reply>
+
+ #
+ # Client-side
+ <client>
+ <server>
+ http
+ </server>
+ <features>
+ proxy
+ </features>
+ <name>
+ .netrc with redirect and "default" with no password or login
+ </name>
+ <command>
+ --netrc --netrc-file log/netrc%TESTNUMBER -L -x http://%HOSTIP:%HTTPPORT/ http://a.com/
+ </command>
+ <file name="log/netrc%TESTNUMBER" >
+
+ machine a.com
+ login alice
+ password alicespassword
+
+ default
+
+ </file>
+ </client>
+
+ <verify>
+ <protocol>
+ GET http://a.com/ HTTP/1.1
+ Host: a.com
+ Authorization: Basic %b64[alice:alicespassword]b64%
+ User-Agent: curl/%VERSION
+ Accept: */*
+ Proxy-Connection: Keep-Alive
+
+ GET http://b.com/%TESTNUMBER0002 HTTP/1.1
+ Host: b.com
+ User-Agent: curl/%VERSION
+ Accept: */*
+ Proxy-Connection: Keep-Alive
+
+ </protocol>
+ </verify>
+ </testcase>
--
2.40.0

View File

@@ -0,0 +1,41 @@
# Intermittently fails e.g. https://autobuilder.yocto.io/pub/non-release/20231220-28/testresults/qemux86-64-ptest/curl.log
# https://autobuilder.yocto.io/pub/non-release/20231220-27/testresults/qemux86-64-ptest/curl.log
337
# These CRL test (alt-avc) are failing
356
412
413
# These CRL tests are scanning docs
971
# Intermittently hangs e.g http://autobuilder.yocto.io/pub/non-release/20231228-18/testresults/qemux86-64-ptest/curl.log
1091
# Intermittently hangs e.g https://autobuilder.yocto.io/pub/non-release/20231220-27/testresults/qemux86-64-ptest/curl.log
1096
# These CRL tests are scanning docs
1119
1132
1135
1478
# These CRL tests are scanning headers
1167
1477
# These CRL tests are scanning man pages
1139
1140
1173
1177
# This CRL test is looking for m4 files
1165
# This CRL test is looking for src files
1185
# This test is scanning the source tree
1222
# These CRL tests need --libcurl option to be enabled
1279
1400
1401
1402
1403
1404
1405
1465

View File

@@ -0,0 +1,19 @@
# Respect host env CURL_CA_BUNDLE/CURL_CA_PATH first, then auto-detected host cert, then cert in buildtools
# CAFILE/CAPATH is auto-deteced when source buildtools
if [ -z "$CURL_CA_PATH" ]; then
if [ -n "$CAFILE" ];then
export CURL_CA_BUNDLE="$CAFILE"
elif [ -e "${OECORE_NATIVE_SYSROOT}/etc/ssl/certs/ca-certificates.crt" ];then
export CURL_CA_BUNDLE="${OECORE_NATIVE_SYSROOT}/etc/ssl/certs/ca-certificates.crt"
fi
fi
if [ -z "$CURL_CA_PATH" ]; then
if [ -n "$CAPATH" ];then
export CURL_CA_PATH="$CAPATH"
elif [ -e "${OECORE_NATIVE_SYSROOT}/etc/ssl/certs/ca-certificates.crt" ];then
export CURL_CA_PATH="${OECORE_NATIVE_SYSROOT}/etc/ssl/certs"
fi
fi
export BB_ENV_PASSTHROUGH_ADDITIONS="${BB_ENV_PASSTHROUGH_ADDITIONS:-} CURL_CA_BUNDLE CURL_CA_PATH"

View File

@@ -0,0 +1,25 @@
From 42cddb52e821cfc2f09f1974742714e5f2f1856e Mon Sep 17 00:00:00 2001
From: Ross Burton <ross.burton@arm.com>
Date: Fri, 15 Mar 2024 14:37:37 +0000
Subject: [PATCH] Set the max-time timeout to 600 so the timeout is 10 minutes
instead of 13 seconds.
Upstream-Status: Inappropriate
Signed-off-by: Ross Burton <ross.burton@arm.com>
---
tests/servers.pm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/servers.pm b/tests/servers.pm
index d4472d5..9999938 100644
--- a/tests/servers.pm
+++ b/tests/servers.pm
@@ -120,7 +120,7 @@ my $sshdverstr; # for socks server, ssh daemon version string
my $sshderror; # for socks server, ssh daemon version error
my %doesntrun; # servers that don't work, identified by pidfile
my %PORT = (nolisten => 47); # port we use for a local non-listening service
-my $server_response_maxtime=13;
+my $server_response_maxtime=600;
my $httptlssrv = find_httptlssrv();
my %run; # running server
my %runcert; # cert file currently in use by an ssl running server

View File

@@ -0,0 +1,13 @@
#!/bin/sh
cd tests
# Run all tests, don't stop on first failure
# Don't use valgrind if it is found
# Use automake-style output
# Run four tests in parallel
# Print log output on failure
# Don't run the flaky or timing dependent tests
# Until https://github.com/curl/curl/issues/13350 is resolved, don't run FTP tests
./runtests.pl -a -n -am -j4 -p !flaky !timing-dependent !FTP

View File

@@ -0,0 +1,173 @@
SUMMARY = "Command line tool and library for client-side URL transfers"
DESCRIPTION = "It uses URL syntax to transfer data to and from servers. \
curl is a widely used because of its ability to be flexible and complete \
complex tasks. For example, you can use curl for things like user authentication, \
HTTP post, SSL connections, proxy support, FTP uploads, and more!"
HOMEPAGE = "https://curl.se/"
BUGTRACKER = "https://github.com/curl/curl/issues"
SECTION = "console/network"
LICENSE = "curl"
LIC_FILES_CHKSUM = "file://COPYING;md5=eed2e5088e1ac619c9a1c747da291d75"
SRC_URI = " \
https://curl.se/download/${BP}.tar.xz \
file://721941aadf4adf4f6aeb3f4c0ab489bb89610c36.patch \
file://run-ptest \
file://disable-tests \
file://no-test-timeout.patch \
file://CVE-2024-6197.patch \
file://CVE-2024-7264-1.patch \
file://CVE-2024-7264-2.patch \
file://CVE-2024-8096.patch \
file://CVE-2024-9681.patch \
file://CVE-2024-11053-0001.patch \
file://CVE-2024-11053-0002.patch \
file://CVE-2024-11053-0003.patch \
file://CVE-2025-0167.patch \
"
SRC_URI:append:class-nativesdk = " \
file://environment.d-curl.sh \
"
SRC_URI[sha256sum] = "6fea2aac6a4610fbd0400afb0bcddbe7258a64c63f1f68e5855ebc0c659710cd"
# Curl has used many names over the years...
CVE_PRODUCT = "haxx:curl haxx:libcurl curl:curl curl:libcurl libcurl:libcurl daniel_stenberg:curl"
CVE_STATUS[CVE-2024-32928] = "ignored: CURLOPT_SSL_VERIFYPEER was disabled on google cloud services causing a potential man in the middle attack"
CVE_STATUS[CVE-2025-0725] = "not-applicable-config: gzip decompression of content-encoded HTTP responses with the `CURLOPT_ACCEPT_ENCODING` option, using zlib 1.2.0.3 or older"
CVE_STATUS[CVE-2025-5025] = "${@bb.utils.contains('PACKAGECONFIG', 'openssl', 'not-applicable-config: build with openssl','unpatched',d)}"
inherit autotools pkgconfig binconfig multilib_header ptest
# Entropy source for random PACKAGECONFIG option
RANDOM ?= "/dev/urandom"
PACKAGECONFIG ??= "${@bb.utils.filter('DISTRO_FEATURES', 'ipv6', d)} aws basic-auth bearer-auth digest-auth negotiate-auth libidn openssl proxy random threaded-resolver verbose zlib"
PACKAGECONFIG:class-native = "ipv6 openssl proxy random threaded-resolver verbose zlib aws basic-auth bearer-auth digest-auth negotiate-auth"
PACKAGECONFIG:class-nativesdk = "ipv6 openssl proxy random threaded-resolver verbose zlib aws basic-auth bearer-auth digest-auth negotiate-auth"
# 'ares' and 'threaded-resolver' are mutually exclusive
PACKAGECONFIG[ares] = "--enable-ares,--disable-ares,c-ares,,,threaded-resolver"
PACKAGECONFIG[aws] = "--enable-aws,--disable-aws"
PACKAGECONFIG[basic-auth] = "--enable-basic-auth,--disable-basic-auth"
PACKAGECONFIG[bearer-auth] = "--enable-bearer-auth,--disable-bearer-auth"
PACKAGECONFIG[brotli] = "--with-brotli,--without-brotli,brotli"
PACKAGECONFIG[builtinmanual] = "--enable-manual,--disable-manual"
# Don't use this in production
PACKAGECONFIG[debug] = "--enable-debug,--disable-debug"
PACKAGECONFIG[dict] = "--enable-dict,--disable-dict,"
PACKAGECONFIG[digest-auth] = "--enable-digest-auth,--disable-digest-auth"
PACKAGECONFIG[gnutls] = "--with-gnutls,--without-gnutls,gnutls"
PACKAGECONFIG[gopher] = "--enable-gopher,--disable-gopher,"
PACKAGECONFIG[imap] = "--enable-imap,--disable-imap,"
PACKAGECONFIG[ipv6] = "--enable-ipv6,--disable-ipv6,"
PACKAGECONFIG[kerberos-auth] = "--enable-kerberos-auth,--disable-kerberos-auth"
PACKAGECONFIG[krb5] = "--with-gssapi,--without-gssapi,krb5"
PACKAGECONFIG[ldap] = "--enable-ldap,--disable-ldap,openldap"
PACKAGECONFIG[ldaps] = "--enable-ldaps,--disable-ldaps,openldap"
PACKAGECONFIG[libgsasl] = "--with-libgsasl,--without-libgsasl,libgsasl"
PACKAGECONFIG[libidn] = "--with-libidn2,--without-libidn2,libidn2"
PACKAGECONFIG[libssh2] = "--with-libssh2,--without-libssh2,libssh2"
PACKAGECONFIG[mbedtls] = "--with-mbedtls=${STAGING_DIR_TARGET},--without-mbedtls,mbedtls"
PACKAGECONFIG[mqtt] = "--enable-mqtt,--disable-mqtt,"
PACKAGECONFIG[negotiate-auth] = "--enable-negotiate-auth,--disable-negotiate-auth"
PACKAGECONFIG[nghttp2] = "--with-nghttp2,--without-nghttp2,nghttp2"
PACKAGECONFIG[openssl] = "--with-openssl,--without-openssl,openssl"
PACKAGECONFIG[pop3] = "--enable-pop3,--disable-pop3,"
PACKAGECONFIG[proxy] = "--enable-proxy,--disable-proxy,"
PACKAGECONFIG[random] = "--with-random=${RANDOM},--without-random"
PACKAGECONFIG[rtmpdump] = "--with-librtmp,--without-librtmp,rtmpdump"
PACKAGECONFIG[rtsp] = "--enable-rtsp,--disable-rtsp,"
PACKAGECONFIG[smb] = "--enable-smb,--disable-smb,"
PACKAGECONFIG[smtp] = "--enable-smtp,--disable-smtp,"
PACKAGECONFIG[telnet] = "--enable-telnet,--disable-telnet,"
PACKAGECONFIG[tftp] = "--enable-tftp,--disable-tftp,"
PACKAGECONFIG[threaded-resolver] = "--enable-threaded-resolver,--disable-threaded-resolver,,,,ares"
PACKAGECONFIG[verbose] = "--enable-verbose,--disable-verbose"
PACKAGECONFIG[zlib] = "--with-zlib=${STAGING_LIBDIR}/../,--without-zlib,zlib"
PACKAGECONFIG[zstd] = "--with-zstd,--without-zstd,zstd"
EXTRA_OECONF = " \
--disable-libcurl-option \
--disable-ntlm-wb \
--with-ca-bundle=${sysconfdir}/ssl/certs/ca-certificates.crt \
--without-libpsl \
--enable-optimize \
${@'--without-ssl' if (bb.utils.filter('PACKAGECONFIG', 'gnutls mbedtls openssl', d) == '') else ''} \
"
fix_absolute_paths () {
# cleanup buildpaths from curl-config
sed -i \
-e 's,--sysroot=${STAGING_DIR_TARGET},,g' \
-e 's,--with-libtool-sysroot=${STAGING_DIR_TARGET},,g' \
-e 's|${DEBUG_PREFIX_MAP}||g' \
-e 's|${@" ".join(d.getVar("DEBUG_PREFIX_MAP").split())}||g' \
${D}${bindir}/curl-config
}
do_install:append:class-target() {
fix_absolute_paths
}
do_install:append:class-nativesdk() {
fix_absolute_paths
mkdir -p ${D}${SDKPATHNATIVE}/environment-setup.d
install -m 644 ${WORKDIR}/environment.d-curl.sh ${D}${SDKPATHNATIVE}/environment-setup.d/curl.sh
}
do_compile_ptest() {
oe_runmake -C ${B}/tests
}
do_install_ptest() {
cat ${WORKDIR}/disable-tests >> ${S}/tests/data/DISABLED
rm -f ${B}/tests/configurehelp.pm
cp -rf ${B}/tests ${D}${PTEST_PATH}
rm -f ${D}${PTEST_PATH}/tests/libtest/.libs/libhostname.la
rm -f ${D}${PTEST_PATH}/tests/libtest/libhostname.la
mv ${D}${PTEST_PATH}/tests/libtest/.libs/* ${D}${PTEST_PATH}/tests/libtest/
mv ${D}${PTEST_PATH}/tests/libtest/libhostname.so ${D}${PTEST_PATH}/tests/libtest/.libs/
mv ${D}${PTEST_PATH}/tests/http/clients/.libs/* ${D}${PTEST_PATH}/tests/http/clients/
cp -rf ${S}/tests ${D}${PTEST_PATH}
find ${D}${PTEST_PATH}/ -type f -name Makefile.am -o -name Makefile.in -o -name Makefile -delete
install -d ${D}${PTEST_PATH}/src
ln -sf ${bindir}/curl ${D}${PTEST_PATH}/src/curl
cp -rf ${D}${bindir}/curl-config ${D}${PTEST_PATH}
}
RDEPENDS:${PN}-ptest += " \
bash \
locale-base-en-us \
perl-module-b \
perl-module-base \
perl-module-cwd \
perl-module-digest \
perl-module-digest-md5 \
perl-module-file-basename \
perl-module-file-spec \
perl-module-file-temp \
perl-module-io-socket \
perl-module-ipc-open2 \
perl-module-list-util \
perl-module-memoize \
perl-module-storable \
perl-module-time-hires \
"
PACKAGES =+ "lib${BPN}"
FILES:lib${BPN} = "${libdir}/lib*.so.*"
RRECOMMENDS:lib${BPN} += "ca-certificates"
FILES:${PN} += "${datadir}/zsh"
FILES:${PN}:append:class-nativesdk = " ${SDKPATHNATIVE}/environment-setup.d/curl.sh"
inherit multilib_script
MULTILIB_SCRIPTS = "${PN}-dev:${bindir}/curl-config"
BBCLASSEXTEND = "native nativesdk"