Skip to content

auth: support qop=auth in digest client (#1074) - #1155

Merged
aler9 merged 4 commits into
bluenviron:mainfrom
winklemad:fix/digest-qop-auth
Sep 5, 2026
Merged

aler9 merged 4 commits into
bluenviron:mainfrom
winklemad:fix/digest-qop-auth

Conversation

@winklemad

Copy link
Copy Markdown
Contributor

Fixes #1074.

The client never looked at the qop directive of a digest challenge. It always computed the legacy RFC 2069 response, so a server that requires qop="auth", which most RFC 7616 implementations do, rejects every request with a 401 and the stream never starts.

This parses qop in WWW-Authenticate and, when the server offers auth, sends qop, cnonce and nc and computes the response as H(HA1:nonce:nc:cnonce:qop:HA2) (RFC 7616, section 3.4.1). The nonce count increases on every request that reuses the nonce, and the client nonce stays constant for the session. Challenges without qop keep the exact previous behavior, and auth-int is not implemented, it falls back to the legacy computation.

The response formula is pinned by the test vectors in RFC 7616 section 3.9.1, which I used as the expected values in the header round-trip test.

While in there, the opaque value of the challenge is now copied into the Authorization header. It was already parsed and marshalable but never set; RFC 7616 section 3.3 says the client should return it unchanged.

The server side of this package does not advertise or verify qop, which is why the existing round-trip tests never caught this. I left that out to keep the change focused, happy to follow up if you want it.

winklemad and others added 3 commits September 4, 2026 23:19
The client never looked at the qop directive of a digest challenge and
always computed the legacy RFC 2069 response, so servers that require
qop="auth" - as most RFC 7616 implementations do - rejected every request
with a 401.

Parse qop in WWW-Authenticate, and when the server offers "auth", send
qop, cnonce and nc and compute the response as
H(HA1:nonce:nc:cnonce:qop:HA2) (RFC 7616, section 3.4.1). The nonce count
increases at every request, as required. Challenges without qop keep the
previous behavior. auth-int is not implemented.

Also copy the opaque value of the challenge into the Authorization
header, which RFC 7616 section 3.3 says the client should return
unchanged.
@codecov

codecov Bot commented Sep 5, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.22222% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 87.17%. Comparing base (3e20947) to head (7c0ecbb).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
pkg/auth/sender.go 95.83% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1155   +/-   ##
=======================================
  Coverage   87.17%   87.17%           
=======================================
  Files         133      133           
  Lines       10587    10621   +34     
=======================================
+ Hits         9229     9259   +30     
- Misses       1358     1362    +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@aler9

aler9 commented Sep 5, 2026

Copy link
Copy Markdown
Member

i moved the "auth in QOP" check in a dedicated function, added mentioned specifications in the README and merged, thanks!

@aler9
aler9 merged commit 2960e60 into bluenviron:main Sep 5, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Digest authentication: qop is not honored in pkg/auth/sender

2 participants