Skip to content

socks: track SOCKS5 authentication per socket, not per connection - #23014

Closed
MegaManSec wants to merge 2 commits into
curl:masterfrom
MegaManSec:socks5-auth-per-socket
Closed

MegaManSec wants to merge 2 commits into
curl:masterfrom
MegaManSec:socks5-auth-per-socket

Conversation

@MegaManSec

Copy link
Copy Markdown
Contributor

Follow-up to #23003.

conn->bits.socks5_authenticated is written by any SOCKS5 filter on the connection, but only the primary socket's tunnel is what gets reused. FTP negotiates a separate tunnel for the data connection, so a proxy that answers method 0 for the control connection and method 2 for the data connection leaves the bit set on a control connection that never authenticated. A later CURLAUTH_ONLY transfer then passes the reuse check in url_match_proxy_use() and keeps using that tunnel. The bit was also never cleared, so it survived a re-negotiation that selected no authentication.

Gate both writes on cf->sockindex == FIRSTSOCKET and clear the bit when the primary socket starts a negotiation, so it always reflects the tunnel that reuse is deciding about.

Test 1745 does two FTP transfers over one handle: the proxy leaves the control connection unauthenticated and authenticates the data connection, then the second transfer sets CURLAUTH_ONLY. Without the fix the reused control connection carries the second transfer's commands. It needs a new socksd method2 keyword, since the contamination requires the proxy to answer the two tunnels differently.

Note this is an incomplete guarantee in the new option rather than a regression: before #23003 CURLAUTH_ONLY was rejected by setopt for this option, and the guard only ever refuses reuse, so no configuration reuses a connection it would not have reused before.

The bit that CURLAUTH_ONLY uses to refuse reuse of an unauthenticated
connection was set by any SOCKS5 filter on the connection. The FTP data
connection negotiates its own tunnel, so a proxy answering "no auth" for
the control connection and an authenticated method for the data one left
the bit set on a control connection that never authenticated.

Only the primary socket decides, and the bit is cleared when it starts a
new negotiation.

Add test 1745, and a socksd "method2" keyword to answer the second
connection differently.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The process-global connection counter prevents the regression test from reliably exercising its intended authentication sequence.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Tracks SOCKS5 authentication only for the primary reusable socket and adds an FTP regression test.

Changes:

  • Gates authentication state updates by socket index.
  • Clears stale authentication state when renegotiating.
  • Adds method2 support and test 1745.
File Description
lib/​socks.c Scopes authentication tracking to FIRSTSOCKET.
lib/​urldata.h Clarifies authentication flag semantics.
tests/​server/​socksd.c Adds second-connection method configuration.
tests/​libtest/​lib1745.c Implements the FTP regression scenario.
tests/​libtest/​Makefile.inc Registers the libtest source.
tests/​data/​test1745 Defines expected regression behavior.
tests/​data/​Makefile.am Registers test 1745.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/server/socksd.c Outdated
@testclutch

Copy link
Copy Markdown

Analysis of PR #23014 at 30ef17c0:

Test ../../tests/http/test_07_upload.py::TestUpload::test_07_13_upload_seq_large[http/1.1] failed, which has NOT been flaky recently, so there could be a real issue in this PR. Note that this test has failed in 2 different CI jobs (the link just goes to one of them).

Generated by Testclutch

@MegaManSec
MegaManSec force-pushed the socks5-auth-per-socket branch from 30ef17c to a1925f5 Compare September 21, 2026 16:56
@bagder bagder closed this in 47d2019 Sep 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

4 participants