Yedaya Katsman [Mon, 8 Jun 2026 19:48:45 +0000 (22:48 +0300)]
cf-socket: store errno from do_connect in ctx->error
This fixes a misleading log in verbose mode when ipv6 connectivity isn't
available, presumably also in other cases:
```
* Immediate connect fail for 2a00:1450:4028:806::200e: Network is unreachable
* connect to 2a00:1450:4028:806::200e port 443 from :: port 0 failed: Success
```
Daniel Stenberg [Mon, 8 Jun 2026 14:37:44 +0000 (16:37 +0200)]
cookie: tailmatch the domains for secure override
If a SECURE cookie is set for a sub-domain (`example.com`) and is then
attempted to get set again for more specific part of that domain
(`www.example.com`) without the SECURE property, the second occurance
should not be allowed.
Reported-by: Trail of Bits
Verified by test 3305
Closes #21910
Stefan Eissing [Mon, 8 Jun 2026 14:57:01 +0000 (16:57 +0200)]
ws: make pong sending lazy
Do not send PONG frames unless there is sufficient space left in the
websocket send buffer. A server might be lazy in reading our data and
intermediary PONG frames can be skipped by a client (RFC 6455, ch.
5.5.3).
Add test case measuring no real RSS increase on a server blasting with
PING frames.
Viktor Szakats [Tue, 9 Jun 2026 00:08:30 +0000 (02:08 +0200)]
pytest: close file handles after use (cont.), and tidy-ups
- dante.py, dnsd.py, sshd.py: drop redundant conditions.
Spotted in sshd by GitHub Code Quality.
- curl.py: comment out `if` to silence CodeQL warning.
Daniel Stenberg [Mon, 8 Jun 2026 21:21:55 +0000 (23:21 +0200)]
digest: escape control codes too
Since the username is decoded when used and control codes are accepted
in HTTP usernames in general, the username encoding for the Digest auth
needs to percent encode such bytes.
Viktor Szakats [Mon, 8 Jun 2026 11:56:49 +0000 (13:56 +0200)]
checksrc-all.pl: do not check files multiple times
Restrict `git ls-files` to return `*.[ch]` files within `$dir` only.
Before this patch it returned files in subdirectories too, which did
double work and may have made `checksrc.pl` pick `.checksrc` from the
first such subdirectory, masking the one in `$dir`. (current curl tree
is not affected)
alhudz [Mon, 8 Jun 2026 05:07:34 +0000 (10:37 +0530)]
chunked: reject invalid bytes in trailer
Trailers are delivered to the application as headers via
CLIENTWRITE_TRAILER, but unlike regular response headers they skipped
the verify_header() checks, so a server could smuggle a nul byte (or
stray CR) into a header reaching CURLOPT_HEADERFUNCTION and
curl_easy_header().
Run each assembled trailer line through Curl_verify_header(), the same
validation used for normal headers.
Stefan Eissing [Mon, 8 Jun 2026 08:11:30 +0000 (10:11 +0200)]
ssl native_ca_store: always reinit
Add bit `native_ca_store_opt` to keep the setting of
CURLOPT_(PROXY_)SSL_OPTIONS and use that to calculate every easy
transfer if a native CA store shall be used or not.
This avoids `native_ca_store` getting stuck on TRUE after being set
once.
Stefan Eissing [Tue, 2 Jun 2026 09:10:10 +0000 (11:10 +0200)]
progress: fx CURLINFO time reporting
Whack the times reported for a transfer (see
https://curl.se/libcurl/c/curl_easy_getinfo.html#TIMES) into order for
all variations of up-/download, http/ftp etc. Make sure they are
reported in the documented order.
There is still the *possibility* of PRETRANSFER being longer then
POSTTRANSFER, if a server sends a response before an upload is done.
POST is the time the first response byte is received, and PRE is the
time the last byte was sent by curl.
This may happen with more likelihood on HTTP/2 and 3 for a server
rejected upload. But for successful uploads, the answer will almost over
come afterwards.
Undo the previous twists in lib500.c tests, adjust pytest timeline
checks.
Fixes #21828 Reported-by: BazaarAcc32 on github
Closes #21843
Stefan Eissing [Fri, 5 Jun 2026 06:34:46 +0000 (08:34 +0200)]
quic: count zero length packets against max
With a flood of zero lenght UDP packets to curl, the receive loop might
run longer than intended to. Count such packets against the max to
terminate the loop as intended.
URL: https://hackerone.com/reports/3783438 Reported-by: vectorqueue on hackerone
Closes #21869
Viktor Szakats [Tue, 2 Jun 2026 13:33:14 +0000 (15:33 +0200)]
gtls: minor fixes and improvements
- fix GnuTLS function name reference in `Curl_gtls_shared_creds_create()`
error message.
Spotted by GitHub Code Quality.
- unfold a line.
- in `Curl_gtls_verifyserver()`:
- report the failure of `gnutls_x509_crt_import()`.
Spotted by GitHub Code Quality.
- fix a minor inconsistency in error strings.
- drop redundant NULL checks for `config->issuercert`.
Joshua Rogers [Tue, 19 May 2026 13:54:30 +0000 (15:54 +0200)]
gtls: verify OCSP response signature in gtls_verify_ocsp_status
Since aeb1a281ca ("gtls: fix OCSP stapling management"), the function
parses the stapled OCSP response and reads the certificate status via
gnutls_ocsp_resp_get_single(), but never calls gnutls_ocsp_resp_verify()
or gnutls_ocsp_resp_verify_direct(). A response with a forged or
corrupted signature is accepted without question.
Fix by calling gnutls_ocsp_resp_verify() against the trust list obtained
from the session credentials immediately after gnutls_ocsp_resp_import().
This handles both directly-signed responses and delegated OCSP responders
without requiring the issuer certificate to be present in the peer chain.
The missing check only affects the CURLOPT_SSL_VERIFYSTATUS code path
when CURLOPT_SSL_VERIFYPEER is disabled. With peer verification enabled,
gnutls_certificate_verify_peers2() independently catches the invalid
response via GNUTLS_CERT_INVALID_OCSP_STATUS before
gtls_verify_ocsp_status() is reached. As a result, no attack is possible
that is not already trivially achievable without OCSP stapling when peer
verification is off. This is a correctness and consistency fix, not a
security vulnerability.
Joshua Rogers [Tue, 19 May 2026 22:37:27 +0000 (00:37 +0200)]
telnet: honor CURLOPT_TIMEOUT in send_telnet_data()
The poll-before-write loop used -1 (infinite) as the Curl_poll timeout,
so a peer that stops reading could stall the transfer indefinitely,
bypassing CURLOPT_TIMEOUT. Use Curl_timeleft_ms() instead and return
CURLE_OPERATION_TIMEDOUT when the deadline is reached or exceeded.
Viktor Szakats [Sun, 31 May 2026 23:29:14 +0000 (01:29 +0200)]
units: drop redundant pointer check and workaround
All users of the `verify_memory()` macro used a fixed-length buffer for
the test output, which then needed a workaround to silence GCC
`-Waddress` warnings.
```
tests/unit/unit1615.c: In function 'test_unit1615':
tests/libtest/unitcheck.h:51:8: error: the address of 'output_buf' will always evaluate as 'true' [-Werror=address]
51 | if((dynamic) && memcmp(dynamic, check, len)) { \
| ^
tests/unit/unit1615.c:114:3: note: in expansion of macro 'verify_memory'
114 | verify_memory(output_buf, precomp_hash1, CURL_SHA512_256_DIGEST_LENGTH);
| ^~~~~~~~~~~~~
```
Drop redundant address check and the workarounds with it.
Viktor Szakats [Thu, 28 May 2026 21:50:52 +0000 (23:50 +0200)]
tidy-up: miscellaneous
- drop more uses of the word "just". (not enforced here)
- drop some uses of the "will" word.
- "then" -> "than".
- tests/http/testenv/curl.py: fix copy-paste typo in error message.
- pytest: replace `shutdownh` with `shutdown` in test names.
Spotted by GitHub Code Quality.
- comment typos.
- whitespace and newlines fixes.
Stefan Eissing [Tue, 26 May 2026 13:01:09 +0000 (15:01 +0200)]
data creds: detect change
Reshuffle code a little to detect when the transfer's credentials
actually change. Otherwise, leave the existing creds in place.
This gives the precise location where we may want to reset other
states that become invalid with change credentials. Also, by
keeping a creds instance as long as it is valid, we can associate
meta data with it.
Viktor Szakats [Sun, 31 May 2026 18:44:57 +0000 (20:44 +0200)]
cmake: add basic way to select pytests to run
Not documented and experimental, example:
`-D_CURL_PYTEST=/test_60_h3_proxy.py`
Ideally, this should be an env like `TFLAGS` and it should allow
selecting any test ID or a group of them, but so far could not figure
out how even a basic env could work.
Viktor Szakats [Sat, 30 May 2026 08:53:21 +0000 (10:53 +0200)]
pytest: fixes and tidy-ups to h3-proxy tests
- merge tests into a single class.
For shorter names, to fix sort order by test number, and to align with
other tests.
- fix preconditions to make `test_60_04_guard_proxy_http3_unsupported`
actually run.
- replace local precondition with constant of the same effect.
- drop redundant non-`ngtcp2` requirement for
`test_60_04_guard_proxy_http3_unsupported`.
(seemed relevant for no longer supported openssl-quic builds.)
- drop unused `NGTCP2_ONLY_MSG` constant.
Follow-up to e4139a73c82d2035142f5ae36196adb4e9831dae #21798
- avoid creating unnecessary test data blobs, and minimize their scopes.
Stefan Eissing [Wed, 20 May 2026 11:25:49 +0000 (13:25 +0200)]
vtls_config: adjust to origin
When a transfer goes against another origin than the initial one, do not
add the following to the ssl configuration: client cert, client key, srp
user/pass, pinned key.
Stefan Eissing [Tue, 19 May 2026 08:57:53 +0000 (10:57 +0200)]
url: connection reuse fixes for starttls
Add test_31_13 to check connection reuse on mixed --ssl-reqd setting.
For that add debug env var CURL_DBG_NO_USE_SSL_ON_FIRST to disable
--ssl-reqd for the first url. Check that the connection without SSL
from the first url is not reused on the second URL that requires it.
Tweak special ftp: protocol check to fail a DEBUGASSERT on mismatched
`use_ssl` settings as that should have been caught before in the
connection reuse matching (imap/smtp etc. do not have this extra check
and rely on the general part doing its job).