Joshua Rogers [Tue, 19 May 2026 14:16:12 +0000 (16:16 +0200)]
gtls: fix ignored return and uninitialized status in OCSP check
gnutls_ocsp_resp_get_single() was called with (void) discarding its
return value, so a failure (e.g. an OCSP response with no
SingleResponse entries) went undetected. The following switch() then
read an uninitialized gnutls_ocsp_cert_status_t, which is undefined
behaviour and could yield GNUTLS_OCSP_CERT_GOOD (0) depending on
stack contents, causing gtls_verify_ocsp_status to return CURLE_OK for
a response that was never successfully parsed.
Fix by initializing status to GNUTLS_OCSP_CERT_UNKNOWN and treating a
negative return from gnutls_ocsp_resp_get_single as an error.
HTTP/3: add proxy CONNECT and MASQUE CONNECT-UDP support (ngtcp2 QUIC)
This patch adds two major proxy capabilities to curl (ngtcp2 QUIC):
- HTTP/3 Proxy CONNECT: Tunnel HTTP/1.1 or HTTP/2 traffic through an
HTTPS proxy that speaks HTTP/3 (QUIC) using the standard CONNECT
method over an HTTP/3 connection.
- MASQUE CONNECT-UDP: Tunnel HTTP/3 (QUIC) traffic through an HTTP
proxy (speaking HTTP/1.1, HTTP/2, or HTTP/3) using the extended
CONNECT method with the CONNECT-UDP protocol (RFC9297 & RFC9298).
Public API additions:
- `CURLPROXY_HTTPS3`: new proxy type constant for HTTP/3 proxy
- `--proxy-http3`: new CLI flag to negotiate HTTP/3 with HTTPS proxy
The implementation adds two new filters:
- `H3-PROXY` - enables negotiating HTTP/3 (QUIC) to the proxy and
running CONNECT/CONNECT-UDP through that proxy transport.
- `CAPSULE` - dedicated filter inserted between QUIC transport and
HTTP-PROXY to handle datagram capsule encapsulation/decapsulation.
Here is how the curl filter chaining looks in different scenarios:
- HTTP/3 Proxy CONNECT (tunneling TCP protocols over QUIC proxy):
conn -> HTTP/1.1 or HTTP/2 -> SSL -> HTTP-PROXY ->
H3-PROXY -> HAPPY-EYEBALLS -> UDP
- MASQUE CONNECT-UDP (tunneling QUIC over any proxy):
conn -> HTTP/3 -> CAPSULE -> HTTP-PROXY -> H3-PROXY ->
HAPPY-EYEBALLS -> UDP
conn -> HTTP/3 -> CAPSULE -> HTTP-PROXY -> H1-PROXY or H2-PROXY ->
SSL -> HAPPY-EYEBALLS -> TCP
- Both features currently require the ngtcp2 QUIC backend.
- Both features are experimental (disabled by default). Enable with
`--enable-proxy-http3`(autotools) or `-DUSE_PROXY_HTTP3=ON`(CMake).
Tests:
- tests/unit/unit3400.c: Unit tests for capsule protocol encode/decode
- tests/http/test_60_h3_proxy.py: Comprehensive pytest integration suite
- tests/http/testenv/h2o.py: Managing h2o instances with HTTP/1.1, HTTP/2,
and HTTP/3 (QUIC) listeners, proxy.connect and proxy.connect-udp enabled.
References:
RFC 9297 - HTTP Datagrams and the Capsule Protocol
RFC 9298 - Proxying UDP in HTTP
RFC 9000 §16 — Variable-Length Integer Encoding
Viktor Szakats [Tue, 26 May 2026 09:40:15 +0000 (11:40 +0200)]
GHA: fix locale tests on macOS, extend to verify test 1981
- fix macOS locale tests to clear existing variables.
(Without this, the system-defined `LC_ALL` takes precedence, and
the custom envs in CI are ignored.)
- trigger test 1981 issue by setting `LC_TIME` to non-English, on macOS.
(On Linux it'd require explicitly installing a non-English locale, I
skipped this for simplicity.)
```
[...]
-Time: 01/Aug/2025 08:31:43.037103 +0000 UTC[CR][LF]
+Time: 01/ao%c3%bb/2025 08:31:43.037103 +0000 UTC[CR][LF]
[...]
FAIL 1981: '%time output with --write-out' HTTP, HTTP GET
```
Follow-up to 90a7732d467eae7c5a59fc07c5a072970926f8c6 #21749
Viktor Szakats [Tue, 26 May 2026 13:56:27 +0000 (15:56 +0200)]
GHA: verify tarball downloads
Detect latest tarball version via the https://curl.se/downloads.html
page, download the signing key from a public keyserver then verify
source download signatures.
Viktor Szakats [Tue, 26 May 2026 11:22:20 +0000 (13:22 +0200)]
GHA: bump LibreSSL to 4.3.2
Also switch back to ftp.openbsd.org download server. More often than not
the GitHub release entry is missing the download artifacts at the time
of detecting a new version, breaking automatic bumps. We cache the
download so it does not bang the origin server with many requests.
Viktor Szakats [Sat, 23 May 2026 09:05:27 +0000 (11:05 +0200)]
quiche: bump cloudflare/quiche to v0.29.0, update pytest workaround
Also:
- drop no longer necessary quiche build workaround.
- update build for boringssl's new location (since v0.29.0, it's no
longer vendored) within the quiche tree.
- move boringssl install dir out of quiche tree, and shorten it.
Max Dymond [Sun, 24 May 2026 08:02:33 +0000 (09:02 +0100)]
KNOWN_BUGS: remove stale Threads::Threads entry
The old CMake bug about exporting -lpthread instead of Threads::Threads
no longer matches current master. As of 2d546d239ecd455b6459e68b85ef8d4b045c0a00
("cmake: use Threads::Threads imported target for POSIX Threads"),
the build now uses Threads::Threads and the generated CMake package
config resolves the dependency explicitly, so this KNOWN_BUGS entry is stale.
Joshua Rogers [Fri, 22 May 2026 07:59:17 +0000 (09:59 +0200)]
schannel: error on TLS 1.3-only with cipher list
The legacy SCHANNEL_CRED path cannot negotiate TLS 1.3. When TLS 1.3
is the only enabled protocol and a cipher list is set, fail instead of
silently downgrading to TLS 1.2.
Stefan Eissing [Fri, 22 May 2026 07:11:41 +0000 (09:11 +0200)]
http2: remove stream dependency tracking
The HTTP/2 feature is deprecated, few servers implement it and our
implementation is complicated by its state management. Make the two
CURLOPT_* involved a nop and deprecate them.
It may replace existing pedantic check, if this level isn't bringing
false-positives or annoyance. Officially it's not meant for CI, but curl
has been passing this in the last couple of months when checked locally.
Viktor Szakats [Thu, 21 May 2026 02:21:33 +0000 (04:21 +0200)]
units: tidy up begin/end blocks
- use `UNITTEST_BEGIN_SIMPLE`/`UNITTEST_END_SIMPLE` where missing.
- drop redundant `(void)arg;` where using `UNITTEST_BEGIN*`.
- unit1636: drop redundant block after `UNITTEST_BEGIN*`.
- unit1609: fix typo in comment.
- unit1627: merge to `if`s.
Viktor Szakats [Thu, 21 May 2026 09:16:49 +0000 (11:16 +0200)]
multi: silence gcc 16 `-Wnull-dereference`, bump CI job to test
- GHA/windows: bump dl-mingw job from gcc 15 to 16.
- multi: silence warning while building libcurlu:
```
In function 'multi_ischanged',
inlined from 'multi_socket.isra' at D:/a/curl/curl/lib/multi.c:3282:6:
D:/a/curl/curl/lib/multi.c:1710:17: error: null pointer dereference [-Werror=null-dereference]
1710 | bool retval = (bool)multi->recheckstate;
| ^~~~~~~~~~~~~~~~~~~~~~~~~
D:/a/curl/curl/lib/multi.c:1712:25: error: null pointer dereference [-Werror=null-dereference]
1712 | multi->recheckstate = FALSE;
| ^
```
Ref: https://github.com/curl/curl/actions/runs/26217071531/job/77142119137?pr=21707
- multi: silence another `-Wnull-dereference`, popping up in libcurl
with gcc 13 after the previous silencing:
```
In function 'Curl_multi_xfers_running',
inlined from 'multi_socket.isra' at ../../lib/multi.c:3292:28:
../../lib/multi.c:4132:15: error: null pointer dereference [-Werror=null-dereference]
4132 | return multi->xfers_alive;
| ~~~~~^~~~~~~~~~~~~
```
Ref: https://github.com/curl/curl/actions/runs/26218822231/job/77148186045
- multi: also add `DEBUGASSERT(multi)` to the two updated functions.
Dan Fandrich [Tue, 5 May 2026 03:48:52 +0000 (20:48 -0700)]
tests: add an assert to avoid IPC blocking
If so much data is being sent over the internal IPC pipe that the pipe
buffer fills and the syscall blocks, the program will hang. Add an
assert to ensure that this limit is never reached. The buffer size is
going to be different on different platforms, so choose 1KB which is
likely to be a reasonable lower bound on just about any system.
Currently, the maximum amount ever written is <100 bytes, so this should
provide plenty of headroom.
Prior to this change the revoke_best_effort setting for the proxy was
wrongly ignored in favor of the same setting for the destination host.
In other words, CURLSSLOPT_REVOKE_BEST_EFFORT set via
CURLOPT_PROXY_SSL_OPTIONS did not apply to the proxy and
CURLSSLOPT_REVOKE_BEST_EFFORT set via CURLOPT_SSL_OPTIONS wrongly
applied to the proxy.
Stefan Eissing [Tue, 19 May 2026 13:31:45 +0000 (15:31 +0200)]
cfilters: fix busy loop on blocked transfers
When a transfer gets paused after the connection has been established,
any data sitting in the kernel socket buffers will no longer get read.
Prevent the sockets form being added to the pollsets, because they
will trigger POLLIN endlessly and cause a busy poll loop. Same in event
based processing.
Reported-by: Harry Sintonen
Fixes https://github.com/curl/curl/issues/21671
Closes https://github.com/curl/curl/pull/21675
penpal [Fri, 15 May 2026 17:53:29 +0000 (23:38 +0545)]
sspi: clear SSPI credentials on AcquireCredentialsHandle failure
- Clear credentials on AcquireCredentialsHandle failure so it is not
used on a subsequent call.
SSPI initialization may evaluate the credentials pointer to determine
whether or not a prior call to AcquireCredentialsHandle was successful,
therefore we must clear it on a failed call.
Viktor Szakats [Wed, 20 May 2026 01:42:49 +0000 (03:42 +0200)]
GHA/non-native: drop DragonFlyBSD job, due to unreliable package repo updates
Example:
```
Wed, 20 May 2026 09:51:48 GMT Updating Avalon repository catalogue...
Wed, 20 May 2026 09:51:48 GMT pkg: An error occurred while fetching package: No error
Wed, 20 May 2026 09:51:48 GMT pkg: An error occurred while fetching package: No error
Wed, 20 May 2026 09:51:48 GMT repository Avalon has no meta file, using default settings
Wed, 20 May 2026 09:51:48 GMT pkg: An error occurred while fetching package: No error
Wed, 20 May 2026 09:51:48 GMT pkg: An error occurred while fetching package: No error
Wed, 20 May 2026 09:51:48 GMT pkg: An error occurred while fetching package: No error
Wed, 20 May 2026 09:51:48 GMT pkg: An error occurred while fetching package: No error
Wed, 20 May 2026 09:51:48 GMT Unable to update repository Avalon
Wed, 20 May 2026 09:51:48 GMT Error updating repositories!
Wed, 20 May 2026 09:51:48 GMT Error: Process completed with exit code 3.
```
As tested over at libssh2, retrying the install command also does not
help, only repeats the same failure.
Viktor Szakats [Tue, 19 May 2026 17:05:41 +0000 (19:05 +0200)]
GHA/non-native: move BSDs to a single matrix, add DragonFly and Midnight
- bump cross-platform-actions to v1.1.0.
Ref: https://github.com/cross-platform-actions/action/releases/tag/v1.1.0
- merge BSD jobs into a single matrix.
- split BSD jobs into build steps as used for other platforms.
A new feature of cross-platform-actions v1.1.0.
- sync BSD build steps with other platforms.
- add DragonFlyBSD and MidnightBSD to the BSD matrix.
New features of cross-platform-actions v1.1.0.
MidnightBSD uses GnuTLS to add variation, also the preinstalled
OpenSSL is too old (v1.1.1w) for curl.
Stick with autotools for DragonFlyBSD; I could not figure out how
to install cmake.
Refs:
https://en.wikipedia.org/wiki/DragonFly_BSD
https://en.wikipedia.org/wiki/MidnightBSD
- bump Intel FreeBSD jobs from v14.3 to v15.0.
- fix to show `gcc` in the NetBSD job name.
All these saved 50 lines of YAML. The two new jobs take 2m15s each. The
bump to FreeBSD 15 needs and extra minute in total.
Note, the DragonFlyBSD job seems to have reliability issues. If it
remains an issue, I'll comment it out or delete it in a future commit.
Viktor Szakats [Sat, 16 May 2026 16:58:47 +0000 (18:58 +0200)]
runner.pm: apply minor correctness fix
"Lines 244-245 overwrite global variables `$runnerr` and `$runnerw` that
were already assigned in the child process (lines 205-206). In the
parent process context, these assignments appear incorrect and could
cause issues if `runner_init` is called multiple times. The parent
should only store references in the controller hashes."
It could never cause an actual issue, but clarifies the intent of the
code.
Joshua Rogers [Tue, 19 May 2026 09:47:50 +0000 (11:47 +0200)]
tls: fix incomplete mTLS config in conn reuse and session cache
cert_type, key, key_type, key_passwd and key_blob lived in
ssl_config_data but not in ssl_primary_config, so they were invisible to
match_ssl_primary_config() and to the TLS session cache peer key.
Two easy handles sharing a connection pool could reuse each other's
authenticated connections when they differed only on SSLKEY, SSLKEYTYPE,
KEYPASSWD, SSLCERTTYPE or SSLKEYBLOB. The second handle would silently
inherit the first handle's authenticated identity.
Promote all five fields into ssl_primary_config so the conn-reuse
predicate and session cache key cover the complete client credential
set. Also replace the fixed ":CCERT" session cache marker with the
actual clientcert path so sessions are not shared across different
client certificates.
Viktor Szakats [Mon, 18 May 2026 16:38:25 +0000 (18:38 +0200)]
docs: tidy-up scheme references
After this patch `://` schemes are lowercase and enclosed in backticks.
Also:
- docs/libcurl/libcurl-multi.md: drop a stray C code fence.
- docs/libcurl/libcurl-tutorial.md: replace single/double quotes with
Markdown markup where applicable.
Joshua Rogers [Tue, 19 May 2026 10:29:34 +0000 (12:29 +0200)]
vtls: use Curl_safecmp for CRLfile and pinned_key comparison
Both are filesystem paths (or case-sensitive hash strings for
pinned_key). curl_strequal is case-insensitive and would treat
/etc/ssl/Crl.pem and /etc/ssl/crl.pem as the same file, unlike the other
path fields (CApath, CAfile, issuercert, clientcert) which already use
Curl_safecmp.
Shintomon Mathew [Mon, 18 May 2026 14:02:45 +0000 (19:32 +0530)]
creds: mask OAuth bearer token in trace logs
Masked OAuth bearer tokens in credential trace output by emitting ***
when a bearer token is present, matching the existing password redaction
behavior and preventing sensitive token disclosure in verbose/debug
logs.
Stefan Eissing [Fri, 15 May 2026 09:45:49 +0000 (11:45 +0200)]
netrc: scanner refactor
Refactor the netrc scanner. Add test case for checking that the last
matched machine with unmatched login does not return the password as
success (unit1304).
Mark Esler [Sat, 16 May 2026 22:07:15 +0000 (15:07 -0700)]
vtls_scache: include signature_algorithms in the SSL peer cache key
Curl_ssl_peer_key_make() omitted ssl->signature_algorithms, although
match_ssl_primary_config() compares the field. Two handles differing
only in CURLOPT_SSL_SIGNATURE_ALGORITHMS therefore shared a peer key and
could resume each other's sessions across a shared CURLSH SSL session
cache.
Add :SIGALGS-%s next to the other ssl_primary_config fields.
Viktor Szakats [Mon, 18 May 2026 09:50:37 +0000 (11:50 +0200)]
mk-unity.pl: `#include`, and not concatenate input headers
When using `-D_CURL_TESTS_CONCAT=ON` with CMake, do not concatenate
`first.h` (or any future header) into the output C file, but `#include`
it instead. This is to play nice with compilers and analyzers which may
apply different checker rules on logic found in headers, vs. the input
source file. As seen for example with `-Wunused-macro` enabled in CI.
After this patch concatenated sources behave closer to regular C
sources.
Also:
- first.h: drop some `-Wunused-macro` silencers that became redundant
with this patch.
Stefan Eissing [Fri, 15 May 2026 12:11:13 +0000 (14:11 +0200)]
unix-sockets: ignore proxy settings
Fix a recent regression: when a unix-socket is configured, all proxy
settings must be ignored. The `via_peer` had been checked correctly,
but the connections proxy bits were not cleared.
Viktor Szakats [Sat, 16 May 2026 01:56:33 +0000 (03:56 +0200)]
lib678: fix to not be perma-skipped
Prior to this patch the test was always skipped due to failing precheck
with `CURLE_BAD_FUNCTION_ARGUMENT`, because of the zero-length blob
passed to setopt. Fix by passing a non-zero long dummy blob as done in
`mk-lib1521.pl`.
Fixing:
```
test 0678 SKIPPED: CURLOPT_CAINFO_BLOB is not supported
```
Viktor Szakats [Tue, 12 May 2026 00:26:05 +0000 (02:26 +0200)]
GHA: enable `-Wunused-macros` in clang-tidy jobs
Also fix fallouts found.
Windows clang-tidy CI job is a little pickier than I'd prefer due to the
`_CURL_TESTS_CONCAT=ON` option used there, and all macros considered
local, thus checked by the compiler. Upside: it revealed macro usage
dynamics in tests. If too annoying, `first.h` may be opted-out from the
concat logic. Some macros may also be deleted instead of `#if 0`-ing.
Sergio Correia [Wed, 13 May 2026 18:44:05 +0000 (19:44 +0100)]
x509asn1: fix DH public key parameter extraction
The dh(g) parameter was read from param->beg instead of from the
cursor p returned by parsing dh(p). This caused dh(g) to always
report the same value as dh(p) when inspecting DH certificates
via CURLOPT_CERTINFO on non-OpenSSL backends.
The DSA branch correctly advances the cursor; the DH branch lost
this during what appears to be a copy-paste.
Add unit1676 to verify that dh(p) and dh(g) report distinct values
using a hand-crafted minimal DER certificate.
Assisted by: Claude Opus 4.6 Signed-off-by: Sergio Correia <scorreia@redhat.com>
Closes #21595
Stefan Eissing [Fri, 15 May 2026 11:03:02 +0000 (13:03 +0200)]
cf-h2-proxy: drop interim responses
Any 1xx response before the CONNECT final one can be dropped as no one
uses those in the HTTP/2 proxy filter. This eliminates a potential
memory exhaustion by the famous malicious server on the internet.