diff options
| -rw-r--r-- | meta/recipes-support/curl/curl/CVE-2024-11053-0001.patch | 353 | ||||
| -rw-r--r-- | meta/recipes-support/curl/curl/CVE-2024-11053-0002.patch | 728 | ||||
| -rw-r--r-- | meta/recipes-support/curl/curl/CVE-2024-11053-0003.patch | 130 | ||||
| -rw-r--r-- | meta/recipes-support/curl/curl_8.7.1.bb | 3 |
4 files changed, 1214 insertions, 0 deletions
diff --git a/meta/recipes-support/curl/curl/CVE-2024-11053-0001.patch b/meta/recipes-support/curl/curl/CVE-2024-11053-0001.patch new file mode 100644 index 0000000000..52ba390cde --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2024-11053-0001.patch | |||
| @@ -0,0 +1,353 @@ | |||
| 1 | From 9bee39bfed2c413b4cc4eb306a57ac92a1854907 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Daniel Stenberg <daniel@haxx.se> | ||
| 3 | Date: Sat, 12 Oct 2024 23:54:39 +0200 | ||
| 4 | Subject: [PATCH] url: use same credentials on redirect | ||
| 5 | |||
| 6 | Previously it could lose the username and only use the password. | ||
| 7 | |||
| 8 | Added test 998 and 999 to verify. | ||
| 9 | |||
| 10 | Reported-by: Tobias Bora | ||
| 11 | Fixes #15262 | ||
| 12 | Closes #15282 | ||
| 13 | |||
| 14 | Changes: | ||
| 15 | - Test files are added in Makefile.inc. | ||
| 16 | |||
| 17 | CVE: CVE-2024-11053 | ||
| 18 | Upstream-Status: Backport [https://github.com/curl/curl/commit/9bee39bfed2c413b4cc4eb306a57ac92a1854907] | ||
| 19 | |||
| 20 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
| 21 | --- | ||
| 22 | lib/transfer.c | 3 ++ | ||
| 23 | lib/url.c | 19 +++++---- | ||
| 24 | lib/urldata.h | 9 +++- | ||
| 25 | tests/data/Makefile.inc | 2 +- | ||
| 26 | tests/data/test998 | 92 +++++++++++++++++++++++++++++++++++++++++ | ||
| 27 | tests/data/test999 | 81 ++++++++++++++++++++++++++++++++++++ | ||
| 28 | 6 files changed, 195 insertions(+), 11 deletions(-) | ||
| 29 | create mode 100644 tests/data/test998 | ||
| 30 | create mode 100644 tests/data/test999 | ||
| 31 | |||
| 32 | diff --git a/lib/transfer.c b/lib/transfer.c | ||
| 33 | index e31d1d6..ccd042b 100644 | ||
| 34 | --- a/lib/transfer.c | ||
| 35 | +++ b/lib/transfer.c | ||
| 36 | @@ -700,6 +700,9 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) | ||
| 37 | return CURLE_OUT_OF_MEMORY; | ||
| 38 | } | ||
| 39 | |||
| 40 | + if(data->set.str[STRING_USERNAME] || | ||
| 41 | + data->set.str[STRING_PASSWORD]) | ||
| 42 | + data->state.creds_from = CREDS_OPTION; | ||
| 43 | if(!result) | ||
| 44 | result = Curl_setstropt(&data->state.aptr.user, | ||
| 45 | data->set.str[STRING_USERNAME]); | ||
| 46 | diff --git a/lib/url.c b/lib/url.c | ||
| 47 | index 224b9f3..05431b9 100644 | ||
| 48 | --- a/lib/url.c | ||
| 49 | +++ b/lib/url.c | ||
| 50 | @@ -1899,10 +1899,10 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, | ||
| 51 | return result; | ||
| 52 | |||
| 53 | /* | ||
| 54 | - * User name and password set with their own options override the | ||
| 55 | - * credentials possibly set in the URL. | ||
| 56 | + * username and password set with their own options override the credentials | ||
| 57 | + * possibly set in the URL, but netrc does not. | ||
| 58 | */ | ||
| 59 | - if(!data->set.str[STRING_PASSWORD]) { | ||
| 60 | + if(!data->state.aptr.passwd || (data->state.creds_from != CREDS_OPTION)) { | ||
| 61 | uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0); | ||
| 62 | if(!uc) { | ||
| 63 | char *decoded; | ||
| 64 | @@ -1915,12 +1915,13 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, | ||
| 65 | result = Curl_setstropt(&data->state.aptr.passwd, decoded); | ||
| 66 | if(result) | ||
| 67 | return result; | ||
| 68 | + data->state.creds_from = CREDS_URL; | ||
| 69 | } | ||
| 70 | else if(uc != CURLUE_NO_PASSWORD) | ||
| 71 | return Curl_uc_to_curlcode(uc); | ||
| 72 | } | ||
| 73 | |||
| 74 | - if(!data->set.str[STRING_USERNAME]) { | ||
| 75 | + if(!data->state.aptr.user || (data->state.creds_from != CREDS_OPTION)) { | ||
| 76 | /* we don't use the URL API's URL decoder option here since it rejects | ||
| 77 | control codes and we want to allow them for some schemes in the user | ||
| 78 | and password fields */ | ||
| 79 | @@ -1934,13 +1935,10 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, | ||
| 80 | return result; | ||
| 81 | conn->user = decoded; | ||
| 82 | result = Curl_setstropt(&data->state.aptr.user, decoded); | ||
| 83 | + data->state.creds_from = CREDS_URL; | ||
| 84 | } | ||
| 85 | else if(uc != CURLUE_NO_USER) | ||
| 86 | return Curl_uc_to_curlcode(uc); | ||
| 87 | - else if(data->state.aptr.passwd) { | ||
| 88 | - /* no user was set but a password, set a blank user */ | ||
| 89 | - result = Curl_setstropt(&data->state.aptr.user, ""); | ||
| 90 | - } | ||
| 91 | if(result) | ||
| 92 | return result; | ||
| 93 | } | ||
| 94 | @@ -2730,7 +2728,8 @@ static CURLcode override_login(struct Curl_easy *data, | ||
| 95 | int ret; | ||
| 96 | bool url_provided = FALSE; | ||
| 97 | |||
| 98 | - if(data->state.aptr.user) { | ||
| 99 | + if(data->state.aptr.user && | ||
| 100 | + (data->state.creds_from != CREDS_NETRC)) { | ||
| 101 | /* there was a user name in the URL. Use the URL decoded version */ | ||
| 102 | userp = &data->state.aptr.user; | ||
| 103 | url_provided = TRUE; | ||
| 104 | @@ -2778,6 +2777,7 @@ static CURLcode override_login(struct Curl_easy *data, | ||
| 105 | result = Curl_setstropt(&data->state.aptr.user, *userp); | ||
| 106 | if(result) | ||
| 107 | return result; | ||
| 108 | + data->state.creds_from = CREDS_NETRC; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | if(data->state.aptr.user) { | ||
| 112 | @@ -2795,6 +2795,7 @@ static CURLcode override_login(struct Curl_easy *data, | ||
| 113 | CURLcode result = Curl_setstropt(&data->state.aptr.passwd, *passwdp); | ||
| 114 | if(result) | ||
| 115 | return result; | ||
| 116 | + data->state.creds_from = CREDS_NETRC; | ||
| 117 | } | ||
| 118 | if(data->state.aptr.passwd) { | ||
| 119 | uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, | ||
| 120 | diff --git a/lib/urldata.h b/lib/urldata.h | ||
| 121 | index ce28f25..b68d023 100644 | ||
| 122 | --- a/lib/urldata.h | ||
| 123 | +++ b/lib/urldata.h | ||
| 124 | @@ -1207,6 +1207,11 @@ struct urlpieces { | ||
| 125 | char *query; | ||
| 126 | }; | ||
| 127 | |||
| 128 | +#define CREDS_NONE 0 | ||
| 129 | +#define CREDS_URL 1 /* from URL */ | ||
| 130 | +#define CREDS_OPTION 2 /* set with a CURLOPT_ */ | ||
| 131 | +#define CREDS_NETRC 3 /* found in netrc */ | ||
| 132 | + | ||
| 133 | struct UrlState { | ||
| 134 | /* Points to the connection cache */ | ||
| 135 | struct conncache *conn_cache; | ||
| 136 | @@ -1344,7 +1349,6 @@ struct UrlState { | ||
| 137 | char *proxyuser; | ||
| 138 | char *proxypasswd; | ||
| 139 | } aptr; | ||
| 140 | - | ||
| 141 | unsigned char httpwant; /* when non-zero, a specific HTTP version requested | ||
| 142 | to be used in the library's request(s) */ | ||
| 143 | unsigned char httpversion; /* the lowest HTTP version*10 reported by any | ||
| 144 | @@ -1354,6 +1358,9 @@ struct UrlState { | ||
| 145 | unsigned char select_bits; /* != 0 -> bitmask of socket events for this | ||
| 146 | transfer overriding anything the socket may | ||
| 147 | report */ | ||
| 148 | + unsigned int creds_from:2; /* where is the server credentials originating | ||
| 149 | + from, see the CREDS_* defines above */ | ||
| 150 | + | ||
| 151 | #ifdef CURLDEBUG | ||
| 152 | BIT(conncache_lock); | ||
| 153 | #endif | ||
| 154 | diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc | ||
| 155 | index d89e565..03cb6a0 100644 | ||
| 156 | --- a/tests/data/Makefile.inc | ||
| 157 | +++ b/tests/data/Makefile.inc | ||
| 158 | @@ -126,7 +126,7 @@ test952 test953 test954 test955 test956 test957 test958 test959 test960 \ | ||
| 159 | test961 test962 test963 test964 test965 test966 test967 test968 test969 \ | ||
| 160 | test970 test971 test972 test973 test974 test975 test976 test977 test978 \ | ||
| 161 | test979 test980 test981 test982 test983 test984 test985 test986 test987 \ | ||
| 162 | -test988 test989 test990 test991 test992 \ | ||
| 163 | +test988 test989 test990 test991 test992 test998 test999 \ | ||
| 164 | \ | ||
| 165 | test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ | ||
| 166 | test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \ | ||
| 167 | diff --git a/tests/data/test998 b/tests/data/test998 | ||
| 168 | new file mode 100644 | ||
| 169 | index 0000000..596b18e | ||
| 170 | --- /dev/null | ||
| 171 | +++ b/tests/data/test998 | ||
| 172 | @@ -0,0 +1,92 @@ | ||
| 173 | +<testcase> | ||
| 174 | + <info> | ||
| 175 | + <keywords> | ||
| 176 | + HTTP | ||
| 177 | + --location-trusted | ||
| 178 | + </keywords> | ||
| 179 | + </info> | ||
| 180 | + | ||
| 181 | + # | ||
| 182 | + # Server-side | ||
| 183 | + <reply> | ||
| 184 | + <data> | ||
| 185 | + HTTP/1.1 301 redirect | ||
| 186 | + Date: Tue, 09 Nov 2010 14:49:00 GMT | ||
| 187 | + Server: test-server/fake | ||
| 188 | + Content-Length: 0 | ||
| 189 | + Connection: close | ||
| 190 | + Content-Type: text/html | ||
| 191 | + Location: http://somewhere.else.example/a/path/%TESTNUMBER0002 | ||
| 192 | + | ||
| 193 | + </data> | ||
| 194 | + <data2> | ||
| 195 | + HTTP/1.1 200 OK | ||
| 196 | + Date: Tue, 09 Nov 2010 14:49:00 GMT | ||
| 197 | + Content-Length: 6 | ||
| 198 | + Content-Type: text/html | ||
| 199 | + Funny-head: yesyes | ||
| 200 | + | ||
| 201 | + -foo- | ||
| 202 | + </data2> | ||
| 203 | + | ||
| 204 | + <datacheck> | ||
| 205 | + HTTP/1.1 301 redirect | ||
| 206 | + Date: Tue, 09 Nov 2010 14:49:00 GMT | ||
| 207 | + Server: test-server/fake | ||
| 208 | + Content-Length: 0 | ||
| 209 | + Connection: close | ||
| 210 | + Content-Type: text/html | ||
| 211 | + Location: http://somewhere.else.example/a/path/%TESTNUMBER0002 | ||
| 212 | + | ||
| 213 | + HTTP/1.1 200 OK | ||
| 214 | + Date: Tue, 09 Nov 2010 14:49:00 GMT | ||
| 215 | + Content-Length: 6 | ||
| 216 | + Content-Type: text/html | ||
| 217 | + Funny-head: yesyes | ||
| 218 | + | ||
| 219 | + -foo- | ||
| 220 | + </datacheck> | ||
| 221 | + | ||
| 222 | + </reply> | ||
| 223 | + | ||
| 224 | + # | ||
| 225 | + # Client-side | ||
| 226 | + <client> | ||
| 227 | + <features> | ||
| 228 | + proxy | ||
| 229 | + </features> | ||
| 230 | + <server> | ||
| 231 | + http | ||
| 232 | + </server> | ||
| 233 | + <name> | ||
| 234 | + HTTP with auth in URL redirected to another host | ||
| 235 | + </name> | ||
| 236 | + <command> | ||
| 237 | + -x %HOSTIP:%HTTPPORT http://alberto:einstein@somwhere.example/%TESTNUMBER --location-trusted | ||
| 238 | + </command> | ||
| 239 | + </client> | ||
| 240 | + | ||
| 241 | + # | ||
| 242 | + # Verify data after the test has been "shot" | ||
| 243 | + <verify> | ||
| 244 | + <strip> | ||
| 245 | + QUIT | ||
| 246 | + </strip> | ||
| 247 | + <protocol> | ||
| 248 | + GET http://somwhere.example/998 HTTP/1.1 | ||
| 249 | + Host: somwhere.example | ||
| 250 | + Authorization: Basic YWxiZXJ0bzplaW5zdGVpbg== | ||
| 251 | + User-Agent: curl/%VERSION | ||
| 252 | + Accept: */* | ||
| 253 | + Proxy-Connection: Keep-Alive | ||
| 254 | + | ||
| 255 | + GET http://somewhere.else.example/a/path/9980002 HTTP/1.1 | ||
| 256 | + Host: somewhere.else.example | ||
| 257 | + Authorization: Basic YWxiZXJ0bzplaW5zdGVpbg== | ||
| 258 | + User-Agent: curl/%VERSION | ||
| 259 | + Accept: */* | ||
| 260 | + Proxy-Connection: Keep-Alive | ||
| 261 | + | ||
| 262 | + </protocol> | ||
| 263 | + </verify> | ||
| 264 | + </testcase> | ||
| 265 | diff --git a/tests/data/test999 b/tests/data/test999 | ||
| 266 | new file mode 100644 | ||
| 267 | index 0000000..184821d | ||
| 268 | --- /dev/null | ||
| 269 | +++ b/tests/data/test999 | ||
| 270 | @@ -0,0 +1,81 @@ | ||
| 271 | +<testcase> | ||
| 272 | + <info> | ||
| 273 | + <keywords> | ||
| 274 | + HTTP | ||
| 275 | + --location-trusted | ||
| 276 | + </keywords> | ||
| 277 | + </info> | ||
| 278 | + | ||
| 279 | + # | ||
| 280 | + # Server-side | ||
| 281 | + <reply> | ||
| 282 | + <data nocheck="yes"> | ||
| 283 | + HTTP/1.1 200 OK | ||
| 284 | + Date: Tue, 09 Nov 2010 14:49:00 GMT | ||
| 285 | + Content-Length: 6 | ||
| 286 | + Content-Type: text/html | ||
| 287 | + Funny-head: yesyes | ||
| 288 | + | ||
| 289 | + -foo- | ||
| 290 | + </data> | ||
| 291 | + | ||
| 292 | + <datacheck> | ||
| 293 | + HTTP/1.1 301 redirect | ||
| 294 | + Date: Tue, 09 Nov 2010 14:49:00 GMT | ||
| 295 | + Server: test-server/fake | ||
| 296 | + Content-Length: 0 | ||
| 297 | + Connection: close | ||
| 298 | + Content-Type: text/html | ||
| 299 | + Location: http://somewhere.else.example/a/path/%TESTNUMBER0002 | ||
| 300 | + | ||
| 301 | + HTTP/1.1 200 OK | ||
| 302 | + Date: Tue, 09 Nov 2010 14:49:00 GMT | ||
| 303 | + Content-Length: 6 | ||
| 304 | + Content-Type: text/html | ||
| 305 | + Funny-head: yesyes | ||
| 306 | + | ||
| 307 | + -foo- | ||
| 308 | + </datacheck> | ||
| 309 | + | ||
| 310 | + </reply> | ||
| 311 | + | ||
| 312 | + # | ||
| 313 | + # Client-side | ||
| 314 | + <client> | ||
| 315 | + <features> | ||
| 316 | + proxy | ||
| 317 | + </features> | ||
| 318 | + <server> | ||
| 319 | + http | ||
| 320 | + </server> | ||
| 321 | + <name> | ||
| 322 | + HTTP with auth in first URL but not second | ||
| 323 | + </name> | ||
| 324 | + <command> | ||
| 325 | + -x %HOSTIP:%HTTPPORT http://alberto:einstein@somwhere.example/%TESTNUMBER http://somewhere.else.example/%TESTNUMBER | ||
| 326 | + </command> | ||
| 327 | + </client> | ||
| 328 | + | ||
| 329 | + # | ||
| 330 | + # Verify data after the test has been "shot" | ||
| 331 | + <verify> | ||
| 332 | + <strip> | ||
| 333 | + QUIT | ||
| 334 | + </strip> | ||
| 335 | + <protocol> | ||
| 336 | + GET http://somwhere.example/%TESTNUMBER HTTP/1.1 | ||
| 337 | + Host: somwhere.example | ||
| 338 | + Authorization: Basic YWxiZXJ0bzplaW5zdGVpbg== | ||
| 339 | + User-Agent: curl/%VERSION | ||
| 340 | + Accept: */* | ||
| 341 | + Proxy-Connection: Keep-Alive | ||
| 342 | + | ||
| 343 | + GET http://somewhere.else.example/%TESTNUMBER HTTP/1.1 | ||
| 344 | + Host: somewhere.else.example | ||
| 345 | + User-Agent: curl/%VERSION | ||
| 346 | + Accept: */* | ||
| 347 | + Proxy-Connection: Keep-Alive | ||
| 348 | + | ||
| 349 | + </protocol> | ||
| 350 | + </verify> | ||
| 351 | + </testcase> | ||
| 352 | -- | ||
| 353 | 2.40.0 | ||
diff --git a/meta/recipes-support/curl/curl/CVE-2024-11053-0002.patch b/meta/recipes-support/curl/curl/CVE-2024-11053-0002.patch new file mode 100644 index 0000000000..7f45f79cf2 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2024-11053-0002.patch | |||
| @@ -0,0 +1,728 @@ | |||
| 1 | From e9b9bbac22c26cf67316fa8e6c6b9e831af31949 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Daniel Stenberg <daniel@haxx.se> | ||
| 3 | Date: Fri, 15 Nov 2024 11:06:36 +0100 | ||
| 4 | Subject: [PATCH] netrc: address several netrc parser flaws | ||
| 5 | |||
| 6 | - make sure that a match that returns a username also returns a | ||
| 7 | password, that should be blank if no password is found | ||
| 8 | |||
| 9 | - fix handling of multiple logins for same host where the password/login | ||
| 10 | order might be reversed. | ||
| 11 | |||
| 12 | - reject credentials provided in the .netrc if they contain ASCII control | ||
| 13 | codes - if the used protocol does not support such (like HTTP and WS do) | ||
| 14 | |||
| 15 | Reported-by: Harry Sintonen | ||
| 16 | |||
| 17 | Add test 478, 479 and 480 to verify. Updated unit 1304. | ||
| 18 | |||
| 19 | Closes #15586 | ||
| 20 | |||
| 21 | Changes: | ||
| 22 | - Refresh patch context. | ||
| 23 | - Adjust `%LOGDIR/` to 'log/' due to its absence in code. | ||
| 24 | - Backported only required enum found_state defination from: | ||
| 25 | https://github.com/curl/curl/commit/3b43a05e000aa8f65bda513f733a73fefe35d5ca | ||
| 26 | - Replaces the previous usage of the state_login, state_password, and | ||
| 27 | state_our_login variables with the found_state enum, which includes the | ||
| 28 | values NONE, LOGIN, and PASSWORD. As a result, all conditionals and memory | ||
| 29 | management logic associated with these variables were updated. | ||
| 30 | |||
| 31 | CVE: CVE-2024-11053 | ||
| 32 | Upstream-Status: Backport [https://github.com/curl/curl/commit/e9b9bbac22c26cf67316fa8e6c6b9e831af3194] | ||
| 33 | |||
| 34 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
| 35 | --- | ||
| 36 | lib/netrc.c | 122 ++++++++++++++++++++++------------------ | ||
| 37 | lib/url.c | 59 ++++++++++++------- | ||
| 38 | tests/data/Makefile.inc | 2 +- | ||
| 39 | tests/data/test478 | 73 ++++++++++++++++++++++++ | ||
| 40 | tests/data/test479 | 107 +++++++++++++++++++++++++++++++++++ | ||
| 41 | tests/data/test480 | 38 +++++++++++++ | ||
| 42 | tests/unit/unit1304.c | 75 +++++++----------------- | ||
| 43 | 7 files changed, 347 insertions(+), 129 deletions(-) | ||
| 44 | create mode 100644 tests/data/test478 | ||
| 45 | create mode 100644 tests/data/test479 | ||
| 46 | create mode 100644 tests/data/test480 | ||
| 47 | |||
| 48 | diff --git a/lib/netrc.c b/lib/netrc.c | ||
| 49 | index cd2a284..64efdc0 100644 | ||
| 50 | --- a/lib/netrc.c | ||
| 51 | +++ b/lib/netrc.c | ||
| 52 | @@ -49,6 +49,15 @@ enum host_lookup_state { | ||
| 53 | MACDEF | ||
| 54 | }; | ||
| 55 | |||
| 56 | +enum found_state { | ||
| 57 | + NONE, | ||
| 58 | + LOGIN, | ||
| 59 | + PASSWORD | ||
| 60 | +}; | ||
| 61 | + | ||
| 62 | +#define FOUND_LOGIN 1 | ||
| 63 | +#define FOUND_PASSWORD 2 | ||
| 64 | + | ||
| 65 | #define NETRC_FILE_MISSING 1 | ||
| 66 | #define NETRC_FAILED -1 | ||
| 67 | #define NETRC_SUCCESS 0 | ||
| 68 | @@ -59,23 +68,20 @@ enum host_lookup_state { | ||
| 69 | * Returns zero on success. | ||
| 70 | */ | ||
| 71 | static int parsenetrc(const char *host, | ||
| 72 | - char **loginp, | ||
| 73 | + char **loginp, /* might point to a username */ | ||
| 74 | char **passwordp, | ||
| 75 | char *netrcfile) | ||
| 76 | { | ||
| 77 | FILE *file; | ||
| 78 | int retcode = NETRC_FILE_MISSING; | ||
| 79 | char *login = *loginp; | ||
| 80 | - char *password = *passwordp; | ||
| 81 | - bool specific_login = (login && *login != 0); | ||
| 82 | - bool login_alloc = FALSE; | ||
| 83 | - bool password_alloc = FALSE; | ||
| 84 | + char *password = NULL; | ||
| 85 | + bool specific_login = login; /* points to something */ | ||
| 86 | enum host_lookup_state state = NOTHING; | ||
| 87 | - | ||
| 88 | - char state_login = 0; /* Found a login keyword */ | ||
| 89 | - char state_password = 0; /* Found a password keyword */ | ||
| 90 | - int state_our_login = TRUE; /* With specific_login, found *our* login | ||
| 91 | - name (or login-less line) */ | ||
| 92 | + enum found_state keyword = NONE; | ||
| 93 | + unsigned char found = 0; /* login + password found bits, as they can come in | ||
| 94 | + any order */ | ||
| 95 | + bool our_login = FALSE; /* found our login name */ | ||
| 96 | |||
| 97 | DEBUGASSERT(netrcfile); | ||
| 98 | |||
| 99 | @@ -97,7 +103,7 @@ static int parsenetrc(const char *host, | ||
| 100 | continue; | ||
| 101 | } | ||
| 102 | tok = netrcbuffer; | ||
| 103 | - while(tok) { | ||
| 104 | + while(tok && !done) { | ||
| 105 | while(ISBLANK(*tok)) | ||
| 106 | tok++; | ||
| 107 | /* tok is first non-space letter */ | ||
| 108 | @@ -156,11 +162,6 @@ static int parsenetrc(const char *host, | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | - if((login && *login) && (password && *password)) { | ||
| 113 | - done = TRUE; | ||
| 114 | - break; | ||
| 115 | - } | ||
| 116 | - | ||
| 117 | switch(state) { | ||
| 118 | case NOTHING: | ||
| 119 | if(strcasecompare("macdef", tok)) { | ||
| 120 | @@ -175,6 +176,12 @@ static int parsenetrc(const char *host, | ||
| 121 | after this we need to search for 'login' and | ||
| 122 | 'password'. */ | ||
| 123 | state = HOSTFOUND; | ||
| 124 | + keyword = NONE; | ||
| 125 | + found = 0; | ||
| 126 | + our_login = FALSE; | ||
| 127 | + Curl_safefree(password); | ||
| 128 | + if(!specific_login) | ||
| 129 | + Curl_safefree(login); | ||
| 130 | } | ||
| 131 | else if(strcasecompare("default", tok)) { | ||
| 132 | state = HOSTVALID; | ||
| 133 | @@ -198,48 +205,55 @@ static int parsenetrc(const char *host, | ||
| 134 | break; | ||
| 135 | case HOSTVALID: | ||
| 136 | /* we are now parsing sub-keywords concerning "our" host */ | ||
| 137 | - if(state_login) { | ||
| 138 | + if(keyword == LOGIN) { | ||
| 139 | if(specific_login) { | ||
| 140 | - state_our_login = !Curl_timestrcmp(login, tok); | ||
| 141 | + our_login = !Curl_timestrcmp(login, tok); | ||
| 142 | } | ||
| 143 | - else if(!login || Curl_timestrcmp(login, tok)) { | ||
| 144 | - if(login_alloc) { | ||
| 145 | - free(login); | ||
| 146 | - login_alloc = FALSE; | ||
| 147 | - } | ||
| 148 | + else { | ||
| 149 | + our_login = TRUE; | ||
| 150 | + free(login); | ||
| 151 | login = strdup(tok); | ||
| 152 | if(!login) { | ||
| 153 | retcode = NETRC_FAILED; /* allocation failed */ | ||
| 154 | goto out; | ||
| 155 | } | ||
| 156 | - login_alloc = TRUE; | ||
| 157 | } | ||
| 158 | - state_login = 0; | ||
| 159 | + found |= FOUND_LOGIN; | ||
| 160 | + keyword = NONE; | ||
| 161 | } | ||
| 162 | - else if(state_password) { | ||
| 163 | - if((state_our_login || !specific_login) | ||
| 164 | - && (!password || Curl_timestrcmp(password, tok))) { | ||
| 165 | - if(password_alloc) { | ||
| 166 | - free(password); | ||
| 167 | - password_alloc = FALSE; | ||
| 168 | - } | ||
| 169 | - password = strdup(tok); | ||
| 170 | - if(!password) { | ||
| 171 | - retcode = NETRC_FAILED; /* allocation failed */ | ||
| 172 | - goto out; | ||
| 173 | - } | ||
| 174 | - password_alloc = TRUE; | ||
| 175 | + else if(keyword == PASSWORD) { | ||
| 176 | + free(password); | ||
| 177 | + password = strdup(tok); | ||
| 178 | + if(!password) { | ||
| 179 | + retcode = NETRC_FAILED; /* allocation failed */ | ||
| 180 | + goto out; | ||
| 181 | } | ||
| 182 | - state_password = 0; | ||
| 183 | + found |= FOUND_PASSWORD; | ||
| 184 | + keyword = NONE; | ||
| 185 | } | ||
| 186 | else if(strcasecompare("login", tok)) | ||
| 187 | - state_login = 1; | ||
| 188 | + keyword = LOGIN; | ||
| 189 | else if(strcasecompare("password", tok)) | ||
| 190 | - state_password = 1; | ||
| 191 | + keyword = PASSWORD; | ||
| 192 | else if(strcasecompare("machine", tok)) { | ||
| 193 | - /* ok, there's machine here go => */ | ||
| 194 | + /* a new machine here */ | ||
| 195 | state = HOSTFOUND; | ||
| 196 | - state_our_login = FALSE; | ||
| 197 | + keyword = NONE; | ||
| 198 | + found = 0; | ||
| 199 | + Curl_safefree(password); | ||
| 200 | + if(!specific_login) | ||
| 201 | + Curl_safefree(login); | ||
| 202 | + } | ||
| 203 | + else if(strcasecompare("default", tok)) { | ||
| 204 | + state = HOSTVALID; | ||
| 205 | + retcode = NETRC_SUCCESS; /* we did find our host */ | ||
| 206 | + Curl_safefree(password); | ||
| 207 | + if(!specific_login) | ||
| 208 | + Curl_safefree(login); | ||
| 209 | + } | ||
| 210 | + if((found == (FOUND_PASSWORD|FOUND_LOGIN)) && our_login) { | ||
| 211 | + done = TRUE; | ||
| 212 | + break; | ||
| 213 | } | ||
| 214 | break; | ||
| 215 | } /* switch (state) */ | ||
| 216 | @@ -249,24 +263,22 @@ static int parsenetrc(const char *host, | ||
| 217 | |||
| 218 | out: | ||
| 219 | Curl_dyn_free(&buf); | ||
| 220 | + if(!retcode && !password && our_login) { | ||
| 221 | + /* success without a password, set a blank one */ | ||
| 222 | + password = strdup(""); | ||
| 223 | + if(!password) | ||
| 224 | + retcode = 1; /* out of memory */ | ||
| 225 | + } | ||
| 226 | if(!retcode) { | ||
| 227 | /* success */ | ||
| 228 | - if(login_alloc) { | ||
| 229 | - if(*loginp) | ||
| 230 | - free(*loginp); | ||
| 231 | + if(!specific_login) | ||
| 232 | *loginp = login; | ||
| 233 | - } | ||
| 234 | - if(password_alloc) { | ||
| 235 | - if(*passwordp) | ||
| 236 | - free(*passwordp); | ||
| 237 | - *passwordp = password; | ||
| 238 | - } | ||
| 239 | + *passwordp = password; | ||
| 240 | } | ||
| 241 | else { | ||
| 242 | - if(login_alloc) | ||
| 243 | + if(!specific_login) | ||
| 244 | free(login); | ||
| 245 | - if(password_alloc) | ||
| 246 | - free(password); | ||
| 247 | + free(password); | ||
| 248 | } | ||
| 249 | fclose(file); | ||
| 250 | } | ||
| 251 | diff --git a/lib/url.c b/lib/url.c | ||
| 252 | index 05431b9..1439c9e 100644 | ||
| 253 | --- a/lib/url.c | ||
| 254 | +++ b/lib/url.c | ||
| 255 | @@ -2699,6 +2699,17 @@ static CURLcode parse_remote_port(struct Curl_easy *data, | ||
| 256 | return CURLE_OK; | ||
| 257 | } | ||
| 258 | |||
| 259 | +static bool str_has_ctrl(const char *input) | ||
| 260 | +{ | ||
| 261 | + const unsigned char *str = (const unsigned char *)input; | ||
| 262 | + while(*str) { | ||
| 263 | + if(*str < 0x20) | ||
| 264 | + return TRUE; | ||
| 265 | + str++; | ||
| 266 | + } | ||
| 267 | + return FALSE; | ||
| 268 | +} | ||
| 269 | + | ||
| 270 | /* | ||
| 271 | * Override the login details from the URL with that in the CURLOPT_USERPWD | ||
| 272 | * option or a .netrc file, if applicable. | ||
| 273 | @@ -2730,29 +2741,39 @@ static CURLcode override_login(struct Curl_easy *data, | ||
| 274 | |||
| 275 | if(data->state.aptr.user && | ||
| 276 | (data->state.creds_from != CREDS_NETRC)) { | ||
| 277 | - /* there was a user name in the URL. Use the URL decoded version */ | ||
| 278 | + /* there was a username with a length in the URL. Use the URL decoded | ||
| 279 | + version */ | ||
| 280 | userp = &data->state.aptr.user; | ||
| 281 | url_provided = TRUE; | ||
| 282 | } | ||
| 283 | |||
| 284 | - ret = Curl_parsenetrc(conn->host.name, | ||
| 285 | - userp, passwdp, | ||
| 286 | - data->set.str[STRING_NETRC_FILE]); | ||
| 287 | - if(ret > 0) { | ||
| 288 | - infof(data, "Couldn't find host %s in the %s file; using defaults", | ||
| 289 | - conn->host.name, | ||
| 290 | - (data->set.str[STRING_NETRC_FILE] ? | ||
| 291 | - data->set.str[STRING_NETRC_FILE] : ".netrc")); | ||
| 292 | - } | ||
| 293 | - else if(ret < 0) { | ||
| 294 | - failf(data, ".netrc parser error"); | ||
| 295 | - return CURLE_READ_ERROR; | ||
| 296 | - } | ||
| 297 | - else { | ||
| 298 | - /* set bits.netrc TRUE to remember that we got the name from a .netrc | ||
| 299 | - file, so that it is safe to use even if we followed a Location: to a | ||
| 300 | - different host or similar. */ | ||
| 301 | - conn->bits.netrc = TRUE; | ||
| 302 | + if(!*passwdp) { | ||
| 303 | + ret = Curl_parsenetrc(conn->host.name, userp, passwdp, | ||
| 304 | + data->set.str[STRING_NETRC_FILE]); | ||
| 305 | + if(ret > 0) { | ||
| 306 | + infof(data, "Couldn't find host %s in the %s file; using defaults", | ||
| 307 | + conn->host.name, | ||
| 308 | + (data->set.str[STRING_NETRC_FILE] ? | ||
| 309 | + data->set.str[STRING_NETRC_FILE] : ".netrc")); | ||
| 310 | + } | ||
| 311 | + else if(ret < 0) { | ||
| 312 | + failf(data, ".netrc parser error"); | ||
| 313 | + return CURLE_READ_ERROR; | ||
| 314 | + } | ||
| 315 | + else { | ||
| 316 | + if(!(conn->handler->flags&PROTOPT_USERPWDCTRL)) { | ||
| 317 | + /* if the protocol can't handle control codes in credentials, make | ||
| 318 | + sure there are none */ | ||
| 319 | + if(str_has_ctrl(*userp) || str_has_ctrl(*passwdp)) { | ||
| 320 | + failf(data, "control code detected in .netrc credentials"); | ||
| 321 | + return CURLE_READ_ERROR; | ||
| 322 | + } | ||
| 323 | + } | ||
| 324 | + /* set bits.netrc TRUE to remember that we got the name from a .netrc | ||
| 325 | + file, so that it is safe to use even if we followed a Location: to a | ||
| 326 | + different host or similar. */ | ||
| 327 | + conn->bits.netrc = TRUE; | ||
| 328 | + } | ||
| 329 | } | ||
| 330 | if(url_provided) { | ||
| 331 | Curl_safefree(conn->user); | ||
| 332 | diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc | ||
| 333 | index 03cb6a0..e3508cb 100644 | ||
| 334 | --- a/tests/data/Makefile.inc | ||
| 335 | +++ b/tests/data/Makefile.inc | ||
| 336 | @@ -73,7 +73,7 @@ test426 test427 test428 test429 test430 test431 test432 test433 test434 \ | ||
| 337 | test435 test436 test437 test438 test439 test440 test441 test442 test443 \ | ||
| 338 | test444 test445 test446 test447 test448 test449 test450 test451 test452 \ | ||
| 339 | test453 test454 test455 test456 test457 test458 test459 test460 test461 \ | ||
| 340 | -test462 test463 test467 test468 \ | ||
| 341 | +test462 test463 test467 test468 test478 test479 test480 \ | ||
| 342 | \ | ||
| 343 | test490 test491 test492 test493 test494 test495 test496 test497 test498 \ | ||
| 344 | test499 test500 test501 test502 test503 test504 test505 test506 test507 \ | ||
| 345 | diff --git a/tests/data/test478 b/tests/data/test478 | ||
| 346 | new file mode 100644 | ||
| 347 | index 0000000..4acc72e | ||
| 348 | --- /dev/null | ||
| 349 | +++ b/tests/data/test478 | ||
| 350 | @@ -0,0 +1,73 @@ | ||
| 351 | +<testcase> | ||
| 352 | + <info> | ||
| 353 | + <keywords> | ||
| 354 | + netrc | ||
| 355 | + HTTP | ||
| 356 | + </keywords> | ||
| 357 | + </info> | ||
| 358 | + # | ||
| 359 | + # Server-side | ||
| 360 | + <reply> | ||
| 361 | + <data crlf="yes"> | ||
| 362 | + HTTP/1.1 200 OK | ||
| 363 | + Date: Tue, 09 Nov 2010 14:49:00 GMT | ||
| 364 | + Server: test-server/fake | ||
| 365 | + Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT | ||
| 366 | + ETag: "21025-dc7-39462498" | ||
| 367 | + Accept-Ranges: bytes | ||
| 368 | + Content-Length: 6 | ||
| 369 | + Connection: close | ||
| 370 | + Content-Type: text/html | ||
| 371 | + Funny-head: yesyes | ||
| 372 | + | ||
| 373 | + -foo- | ||
| 374 | + </data> | ||
| 375 | + </reply> | ||
| 376 | + | ||
| 377 | + # | ||
| 378 | + # Client-side | ||
| 379 | + <client> | ||
| 380 | + <server> | ||
| 381 | + http | ||
| 382 | + </server> | ||
| 383 | + <features> | ||
| 384 | + proxy | ||
| 385 | + </features> | ||
| 386 | + <name> | ||
| 387 | + .netrc with multiple accounts for same host | ||
| 388 | + </name> | ||
| 389 | + <command> | ||
| 390 | + --netrc --netrc-file log/netrc%TESTNUMBER -x http://%HOSTIP:%HTTPPORT/ http://debbie@github.com/ | ||
| 391 | + </command> | ||
| 392 | + <file name="log/netrc%TESTNUMBER" > | ||
| 393 | + | ||
| 394 | + machine github.com | ||
| 395 | + password weird | ||
| 396 | + password firstone | ||
| 397 | + login daniel | ||
| 398 | + | ||
| 399 | + machine github.com | ||
| 400 | + | ||
| 401 | + machine github.com | ||
| 402 | + login debbie | ||
| 403 | + | ||
| 404 | + machine github.com | ||
| 405 | + password weird | ||
| 406 | + password "second\r" | ||
| 407 | + login debbie | ||
| 408 | + | ||
| 409 | + </file> | ||
| 410 | + </client> | ||
| 411 | + | ||
| 412 | + <verify> | ||
| 413 | + <protocol> | ||
| 414 | + GET http://github.com/ HTTP/1.1 | ||
| 415 | + Host: github.com | ||
| 416 | + Authorization: Basic %b64[debbie:second%0D]b64% | ||
| 417 | + User-Agent: curl/%VERSION | ||
| 418 | + Accept: */* | ||
| 419 | + Proxy-Connection: Keep-Alive | ||
| 420 | + | ||
| 421 | + </protocol> | ||
| 422 | + </verify> | ||
| 423 | + </testcase> | ||
| 424 | diff --git a/tests/data/test479 b/tests/data/test479 | ||
| 425 | new file mode 100644 | ||
| 426 | index 0000000..62a2057 | ||
| 427 | --- /dev/null | ||
| 428 | +++ b/tests/data/test479 | ||
| 429 | @@ -0,0 +1,107 @@ | ||
| 430 | +<testcase> | ||
| 431 | + <info> | ||
| 432 | + <keywords> | ||
| 433 | + netrc | ||
| 434 | + HTTP | ||
| 435 | + </keywords> | ||
| 436 | + </info> | ||
| 437 | + # | ||
| 438 | + # Server-side | ||
| 439 | + <reply> | ||
| 440 | + <data crlf="yes"> | ||
| 441 | + HTTP/1.1 301 Follow this you fool | ||
| 442 | + Date: Tue, 09 Nov 2010 14:49:00 GMT | ||
| 443 | + Server: test-server/fake | ||
| 444 | + Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT | ||
| 445 | + ETag: "21025-dc7-39462498" | ||
| 446 | + Accept-Ranges: bytes | ||
| 447 | + Content-Length: 6 | ||
| 448 | + Connection: close | ||
| 449 | + Location: http://b.com/%TESTNUMBER0002 | ||
| 450 | + | ||
| 451 | + -foo- | ||
| 452 | + </data> | ||
| 453 | + | ||
| 454 | + <data2 crlf="yes"> | ||
| 455 | + HTTP/1.1 200 OK | ||
| 456 | + Date: Tue, 09 Nov 2010 14:49:00 GMT | ||
| 457 | + Server: test-server/fake | ||
| 458 | + Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT | ||
| 459 | + ETag: "21025-dc7-39462498" | ||
| 460 | + Accept-Ranges: bytes | ||
| 461 | + Content-Length: 7 | ||
| 462 | + Connection: close | ||
| 463 | + | ||
| 464 | + target | ||
| 465 | + </data2> | ||
| 466 | + | ||
| 467 | + <datacheck crlf="yes"> | ||
| 468 | + HTTP/1.1 301 Follow this you fool | ||
| 469 | + Date: Tue, 09 Nov 2010 14:49:00 GMT | ||
| 470 | + Server: test-server/fake | ||
| 471 | + Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT | ||
| 472 | + ETag: "21025-dc7-39462498" | ||
| 473 | + Accept-Ranges: bytes | ||
| 474 | + Content-Length: 6 | ||
| 475 | + Connection: close | ||
| 476 | + Location: http://b.com/%TESTNUMBER0002 | ||
| 477 | + | ||
| 478 | + HTTP/1.1 200 OK | ||
| 479 | + Date: Tue, 09 Nov 2010 14:49:00 GMT | ||
| 480 | + Server: test-server/fake | ||
| 481 | + Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT | ||
| 482 | + ETag: "21025-dc7-39462498" | ||
| 483 | + Accept-Ranges: bytes | ||
| 484 | + Content-Length: 7 | ||
| 485 | + Connection: close | ||
| 486 | + | ||
| 487 | + target | ||
| 488 | + </datacheck> | ||
| 489 | + </reply> | ||
| 490 | + | ||
| 491 | + # | ||
| 492 | + # Client-side | ||
| 493 | + <client> | ||
| 494 | + <server> | ||
| 495 | + http | ||
| 496 | + </server> | ||
| 497 | + <features> | ||
| 498 | + proxy | ||
| 499 | + </features> | ||
| 500 | + <name> | ||
| 501 | + .netrc with redirect and default without password | ||
| 502 | + </name> | ||
| 503 | + <command> | ||
| 504 | + --netrc --netrc-file log/netrc%TESTNUMBER -L -x http://%HOSTIP:%HTTPPORT/ http://a.com/ | ||
| 505 | + </command> | ||
| 506 | + <file name="log/netrc%TESTNUMBER" > | ||
| 507 | + | ||
| 508 | + machine a.com | ||
| 509 | + login alice | ||
| 510 | + password alicespassword | ||
| 511 | + | ||
| 512 | + default | ||
| 513 | + login bob | ||
| 514 | + | ||
| 515 | + </file> | ||
| 516 | + </client> | ||
| 517 | + | ||
| 518 | + <verify> | ||
| 519 | + <protocol> | ||
| 520 | + GET http://a.com/ HTTP/1.1 | ||
| 521 | + Host: a.com | ||
| 522 | + Authorization: Basic %b64[alice:alicespassword]b64% | ||
| 523 | + User-Agent: curl/%VERSION | ||
| 524 | + Accept: */* | ||
| 525 | + Proxy-Connection: Keep-Alive | ||
| 526 | + | ||
| 527 | + GET http://b.com/%TESTNUMBER0002 HTTP/1.1 | ||
| 528 | + Host: b.com | ||
| 529 | + Authorization: Basic %b64[bob:]b64% | ||
| 530 | + User-Agent: curl/%VERSION | ||
| 531 | + Accept: */* | ||
| 532 | + Proxy-Connection: Keep-Alive | ||
| 533 | + | ||
| 534 | + </protocol> | ||
| 535 | + </verify> | ||
| 536 | + </testcase> | ||
| 537 | diff --git a/tests/data/test480 b/tests/data/test480 | ||
| 538 | new file mode 100644 | ||
| 539 | index 0000000..47db7ab | ||
| 540 | --- /dev/null | ||
| 541 | +++ b/tests/data/test480 | ||
| 542 | @@ -0,0 +1,38 @@ | ||
| 543 | +<testcase> | ||
| 544 | + <info> | ||
| 545 | + <keywords> | ||
| 546 | + netrc | ||
| 547 | + pop3 | ||
| 548 | + </keywords> | ||
| 549 | + </info> | ||
| 550 | + # | ||
| 551 | + # Server-side | ||
| 552 | + <reply> | ||
| 553 | + | ||
| 554 | + </reply> | ||
| 555 | + | ||
| 556 | + # | ||
| 557 | + # Client-side | ||
| 558 | + <client> | ||
| 559 | + <server> | ||
| 560 | + pop3 | ||
| 561 | + </server> | ||
| 562 | + <name> | ||
| 563 | + Reject .netrc with credentials using CRLF for POP3 | ||
| 564 | + </name> | ||
| 565 | + <command> | ||
| 566 | + --netrc --netrc-file log/netrc%TESTNUMBER pop3://%HOSTIP:%POP3PORT/%TESTNUMBER | ||
| 567 | + </command> | ||
| 568 | + <file name="log/netrc%TESTNUMBER" > | ||
| 569 | + machine %HOSTIP | ||
| 570 | + login alice | ||
| 571 | + password "password\r\ncommand" | ||
| 572 | + </file> | ||
| 573 | + </client> | ||
| 574 | + | ||
| 575 | + <verify> | ||
| 576 | + <errorcode> | ||
| 577 | + 26 | ||
| 578 | + </errorcode> | ||
| 579 | + </verify> | ||
| 580 | + </testcase> | ||
| 581 | diff --git a/tests/unit/unit1304.c b/tests/unit/unit1304.c | ||
| 582 | index 0288562..b2b4366 100644 | ||
| 583 | --- a/tests/unit/unit1304.c | ||
| 584 | +++ b/tests/unit/unit1304.c | ||
| 585 | @@ -32,13 +32,8 @@ static char *password; | ||
| 586 | |||
| 587 | static CURLcode unit_setup(void) | ||
| 588 | { | ||
| 589 | - password = strdup(""); | ||
| 590 | - login = strdup(""); | ||
| 591 | - if(!password || !login) { | ||
| 592 | - Curl_safefree(password); | ||
| 593 | - Curl_safefree(login); | ||
| 594 | - return CURLE_OUT_OF_MEMORY; | ||
| 595 | - } | ||
| 596 | + password = NULL; | ||
| 597 | + login = NULL; | ||
| 598 | return CURLE_OK; | ||
| 599 | } | ||
| 600 | |||
| 601 | @@ -56,76 +51,48 @@ UNITTEST_START | ||
| 602 | */ | ||
| 603 | result = Curl_parsenetrc("test.example.com", &login, &password, arg); | ||
| 604 | fail_unless(result == 1, "Host not found should return 1"); | ||
| 605 | - abort_unless(password != NULL, "returned NULL!"); | ||
| 606 | - fail_unless(password[0] == 0, "password should not have been changed"); | ||
| 607 | - abort_unless(login != NULL, "returned NULL!"); | ||
| 608 | - fail_unless(login[0] == 0, "login should not have been changed"); | ||
| 609 | + abort_unless(password == NULL, "password did not return NULL!"); | ||
| 610 | + abort_unless(login == NULL, "user did not return NULL!"); | ||
| 611 | |||
| 612 | /* | ||
| 613 | * Test a non existent login in our netrc file. | ||
| 614 | */ | ||
| 615 | - free(login); | ||
| 616 | - login = strdup("me"); | ||
| 617 | - abort_unless(login != NULL, "returned NULL!"); | ||
| 618 | + login = (char *)"me"; | ||
| 619 | result = Curl_parsenetrc("example.com", &login, &password, arg); | ||
| 620 | fail_unless(result == 0, "Host should have been found"); | ||
| 621 | - abort_unless(password != NULL, "returned NULL!"); | ||
| 622 | - fail_unless(password[0] == 0, "password should not have been changed"); | ||
| 623 | - abort_unless(login != NULL, "returned NULL!"); | ||
| 624 | - fail_unless(strncmp(login, "me", 2) == 0, | ||
| 625 | - "login should not have been changed"); | ||
| 626 | + abort_unless(password == NULL, "password is not NULL!"); | ||
| 627 | |||
| 628 | /* | ||
| 629 | * Test a non existent login and host in our netrc file. | ||
| 630 | */ | ||
| 631 | - free(login); | ||
| 632 | - login = strdup("me"); | ||
| 633 | - abort_unless(login != NULL, "returned NULL!"); | ||
| 634 | + login = (char *)"me"; | ||
| 635 | result = Curl_parsenetrc("test.example.com", &login, &password, arg); | ||
| 636 | fail_unless(result == 1, "Host not found should return 1"); | ||
| 637 | - abort_unless(password != NULL, "returned NULL!"); | ||
| 638 | - fail_unless(password[0] == 0, "password should not have been changed"); | ||
| 639 | - abort_unless(login != NULL, "returned NULL!"); | ||
| 640 | - fail_unless(strncmp(login, "me", 2) == 0, | ||
| 641 | - "login should not have been changed"); | ||
| 642 | + abort_unless(password == NULL, "password is not NULL!"); | ||
| 643 | |||
| 644 | /* | ||
| 645 | * Test a non existent login (substring of an existing one) in our | ||
| 646 | * netrc file. | ||
| 647 | */ | ||
| 648 | - free(login); | ||
| 649 | - login = strdup("admi"); | ||
| 650 | - abort_unless(login != NULL, "returned NULL!"); | ||
| 651 | + login = (char *)"admi"; | ||
| 652 | result = Curl_parsenetrc("example.com", &login, &password, arg); | ||
| 653 | fail_unless(result == 0, "Host should have been found"); | ||
| 654 | - abort_unless(password != NULL, "returned NULL!"); | ||
| 655 | - fail_unless(password[0] == 0, "password should not have been changed"); | ||
| 656 | - abort_unless(login != NULL, "returned NULL!"); | ||
| 657 | - fail_unless(strncmp(login, "admi", 4) == 0, | ||
| 658 | - "login should not have been changed"); | ||
| 659 | + abort_unless(password == NULL, "password is not NULL!"); | ||
| 660 | |||
| 661 | /* | ||
| 662 | * Test a non existent login (superstring of an existing one) | ||
| 663 | * in our netrc file. | ||
| 664 | */ | ||
| 665 | - free(login); | ||
| 666 | - login = strdup("adminn"); | ||
| 667 | - abort_unless(login != NULL, "returned NULL!"); | ||
| 668 | + login = (char *)"adminn"; | ||
| 669 | result = Curl_parsenetrc("example.com", &login, &password, arg); | ||
| 670 | fail_unless(result == 0, "Host should have been found"); | ||
| 671 | - abort_unless(password != NULL, "returned NULL!"); | ||
| 672 | - fail_unless(password[0] == 0, "password should not have been changed"); | ||
| 673 | - abort_unless(login != NULL, "returned NULL!"); | ||
| 674 | - fail_unless(strncmp(login, "adminn", 6) == 0, | ||
| 675 | - "login should not have been changed"); | ||
| 676 | + abort_unless(password == NULL, "password is not NULL!"); | ||
| 677 | |||
| 678 | /* | ||
| 679 | * Test for the first existing host in our netrc file | ||
| 680 | * with login[0] = 0. | ||
| 681 | */ | ||
| 682 | - free(login); | ||
| 683 | - login = strdup(""); | ||
| 684 | - abort_unless(login != NULL, "returned NULL!"); | ||
| 685 | + login = NULL; | ||
| 686 | result = Curl_parsenetrc("example.com", &login, &password, arg); | ||
| 687 | fail_unless(result == 0, "Host should have been found"); | ||
| 688 | abort_unless(password != NULL, "returned NULL!"); | ||
| 689 | @@ -139,8 +106,9 @@ UNITTEST_START | ||
| 690 | * with login[0] != 0. | ||
| 691 | */ | ||
| 692 | free(password); | ||
| 693 | - password = strdup(""); | ||
| 694 | - abort_unless(password != NULL, "returned NULL!"); | ||
| 695 | + free(login); | ||
| 696 | + password = NULL; | ||
| 697 | + login = NULL; | ||
| 698 | result = Curl_parsenetrc("example.com", &login, &password, arg); | ||
| 699 | fail_unless(result == 0, "Host should have been found"); | ||
| 700 | abort_unless(password != NULL, "returned NULL!"); | ||
| 701 | @@ -154,11 +122,9 @@ UNITTEST_START | ||
| 702 | * with login[0] = 0. | ||
| 703 | */ | ||
| 704 | free(password); | ||
| 705 | - password = strdup(""); | ||
| 706 | - abort_unless(password != NULL, "returned NULL!"); | ||
| 707 | + password = NULL; | ||
| 708 | free(login); | ||
| 709 | - login = strdup(""); | ||
| 710 | - abort_unless(login != NULL, "returned NULL!"); | ||
| 711 | + login = NULL; | ||
| 712 | result = Curl_parsenetrc("curl.example.com", &login, &password, arg); | ||
| 713 | fail_unless(result == 0, "Host should have been found"); | ||
| 714 | abort_unless(password != NULL, "returned NULL!"); | ||
| 715 | @@ -172,8 +138,9 @@ UNITTEST_START | ||
| 716 | * with login[0] != 0. | ||
| 717 | */ | ||
| 718 | free(password); | ||
| 719 | - password = strdup(""); | ||
| 720 | - abort_unless(password != NULL, "returned NULL!"); | ||
| 721 | + free(login); | ||
| 722 | + password = NULL; | ||
| 723 | + login = NULL; | ||
| 724 | result = Curl_parsenetrc("curl.example.com", &login, &password, arg); | ||
| 725 | fail_unless(result == 0, "Host should have been found"); | ||
| 726 | abort_unless(password != NULL, "returned NULL!"); | ||
| 727 | -- | ||
| 728 | 2.40.0 | ||
diff --git a/meta/recipes-support/curl/curl/CVE-2024-11053-0003.patch b/meta/recipes-support/curl/curl/CVE-2024-11053-0003.patch new file mode 100644 index 0000000000..32fb1812d6 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2024-11053-0003.patch | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | From 9fce2c55d4b0273ac99b59bd8cb982a6d96b88cf Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Daniel Stenberg <daniel@haxx.se> | ||
| 3 | Date: Tue, 17 Dec 2024 23:56:42 +0100 | ||
| 4 | Subject: [PATCH] netrc: fix password-only entries | ||
| 5 | |||
| 6 | When a specific hostname matched, and only a password is set before | ||
| 7 | another machine is specified in the netrc file, the parser would not be | ||
| 8 | happy and stop there and return the password-only state. It instead | ||
| 9 | continued and did not return a match. | ||
| 10 | |||
| 11 | Add test 2005 to verify this case | ||
| 12 | |||
| 13 | Regression from e9b9bba, shipped in 8.11.1. | ||
| 14 | |||
| 15 | Reported-by: Ben Zanin | ||
| 16 | Fixes #15767 | ||
| 17 | Closes #15768 | ||
| 18 | |||
| 19 | CVE: CVE-2024-11053 | ||
| 20 | Upstream-Status: Backport [https://github.com/curl/curl/commit/9fce2c55d4b0273ac99b59bd8cb982a6d96b88cf] | ||
| 21 | |||
| 22 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
| 23 | --- | ||
| 24 | lib/netrc.c | 7 +++++- | ||
| 25 | tests/data/Makefile.inc | 2 +- | ||
| 26 | tests/data/test2005 | 55 +++++++++++++++++++++++++++++++++++++++++ | ||
| 27 | 3 files changed, 62 insertions(+), 2 deletions(-) | ||
| 28 | create mode 100644 tests/data/test2005 | ||
| 29 | |||
| 30 | diff --git a/lib/netrc.c b/lib/netrc.c | ||
| 31 | index 64efdc0..695e89a 100644 | ||
| 32 | --- a/lib/netrc.c | ||
| 33 | +++ b/lib/netrc.c | ||
| 34 | @@ -228,7 +228,8 @@ static int parsenetrc(const char *host, | ||
| 35 | retcode = NETRC_FAILED; /* allocation failed */ | ||
| 36 | goto out; | ||
| 37 | } | ||
| 38 | - found |= FOUND_PASSWORD; | ||
| 39 | + if(!specific_login || our_login) | ||
| 40 | + found |= FOUND_PASSWORD; | ||
| 41 | keyword = NONE; | ||
| 42 | } | ||
| 43 | else if(strcasecompare("login", tok)) | ||
| 44 | @@ -237,6 +238,10 @@ static int parsenetrc(const char *host, | ||
| 45 | keyword = PASSWORD; | ||
| 46 | else if(strcasecompare("machine", tok)) { | ||
| 47 | /* a new machine here */ | ||
| 48 | + if(found & FOUND_PASSWORD) { | ||
| 49 | + done = TRUE; | ||
| 50 | + break; | ||
| 51 | + } | ||
| 52 | state = HOSTFOUND; | ||
| 53 | keyword = NONE; | ||
| 54 | found = 0; | ||
| 55 | diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc | ||
| 56 | index e3508cb..dc2af79 100644 | ||
| 57 | --- a/tests/data/Makefile.inc | ||
| 58 | +++ b/tests/data/Makefile.inc | ||
| 59 | @@ -230,7 +230,7 @@ test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 \ | ||
| 60 | test1955 test1956 test1957 test1958 test1959 test1960 test1964 \ | ||
| 61 | test1970 test1971 test1972 test1973 test1974 test1975 \ | ||
| 62 | \ | ||
| 63 | -test2000 test2001 test2002 test2003 test2004 \ | ||
| 64 | +test2000 test2001 test2002 test2003 test2004 test2005 \ | ||
| 65 | \ | ||
| 66 | test2023 \ | ||
| 67 | test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \ | ||
| 68 | diff --git a/tests/data/test2005 b/tests/data/test2005 | ||
| 69 | new file mode 100644 | ||
| 70 | index 0000000..66afe84 | ||
| 71 | --- /dev/null | ||
| 72 | +++ b/tests/data/test2005 | ||
| 73 | @@ -0,0 +1,55 @@ | ||
| 74 | +<testcase> | ||
| 75 | + <info> | ||
| 76 | + <keywords> | ||
| 77 | + HTTP | ||
| 78 | + netrc | ||
| 79 | + </keywords> | ||
| 80 | + </info> | ||
| 81 | + # | ||
| 82 | + # Server-side | ||
| 83 | + <reply> | ||
| 84 | + <data> | ||
| 85 | + HTTP/1.1 200 OK | ||
| 86 | + Date: Fri, 05 Aug 2022 10:09:00 GMT | ||
| 87 | + Server: test-server/fake | ||
| 88 | + Content-Type: text/plain | ||
| 89 | + Content-Length: 6 | ||
| 90 | + Connection: close | ||
| 91 | + | ||
| 92 | + -foo- | ||
| 93 | + </data> | ||
| 94 | + </reply> | ||
| 95 | + | ||
| 96 | + # | ||
| 97 | + # Client-side | ||
| 98 | + <client> | ||
| 99 | + <server> | ||
| 100 | + http | ||
| 101 | + </server> | ||
| 102 | + <name> | ||
| 103 | + netrc match with password only in file, no username. machine follows | ||
| 104 | + </name> | ||
| 105 | + <command> | ||
| 106 | + --netrc-optional --netrc-file log/netrc%TESTNUMBER http://%HOSTIP:%HTTPPORT/ | ||
| 107 | + </command> | ||
| 108 | + <file name="log/netrc%TESTNUMBER" > | ||
| 109 | + machine %HOSTIP | ||
| 110 | + password 5up3r53cr37 | ||
| 111 | + | ||
| 112 | + machine example.com | ||
| 113 | + </file> | ||
| 114 | + </client> | ||
| 115 | + | ||
| 116 | + # | ||
| 117 | + # Verify data after the test has been "shot" | ||
| 118 | + <verify> | ||
| 119 | + <protocol> | ||
| 120 | + GET / HTTP/1.1 | ||
| 121 | + Host: %HOSTIP:%HTTPPORT | ||
| 122 | + Authorization: Basic %b64[:5up3r53cr37]b64% | ||
| 123 | + User-Agent: curl/%VERSION | ||
| 124 | + Accept: */* | ||
| 125 | + | ||
| 126 | + </protocol> | ||
| 127 | + </verify> | ||
| 128 | + </testcase> | ||
| 129 | -- | ||
| 130 | 2.40.0 | ||
diff --git a/meta/recipes-support/curl/curl_8.7.1.bb b/meta/recipes-support/curl/curl_8.7.1.bb index ddd591dd96..6d6563591c 100644 --- a/meta/recipes-support/curl/curl_8.7.1.bb +++ b/meta/recipes-support/curl/curl_8.7.1.bb | |||
| @@ -20,6 +20,9 @@ SRC_URI = " \ | |||
| 20 | file://CVE-2024-7264-2.patch \ | 20 | file://CVE-2024-7264-2.patch \ |
| 21 | file://CVE-2024-8096.patch \ | 21 | file://CVE-2024-8096.patch \ |
| 22 | file://CVE-2024-9681.patch \ | 22 | file://CVE-2024-9681.patch \ |
| 23 | file://CVE-2024-11053-0001.patch \ | ||
| 24 | file://CVE-2024-11053-0002.patch \ | ||
| 25 | file://CVE-2024-11053-0003.patch \ | ||
| 23 | " | 26 | " |
| 24 | SRC_URI[sha256sum] = "6fea2aac6a4610fbd0400afb0bcddbe7258a64c63f1f68e5855ebc0c659710cd" | 27 | SRC_URI[sha256sum] = "6fea2aac6a4610fbd0400afb0bcddbe7258a64c63f1f68e5855ebc0c659710cd" |
| 25 | 28 | ||
