On 23. 5. 25 23:48, Peter Balogh wrote:
Hi,
The reason I choose the 499 status code, that it was the cleanest way
to reroute the 2FA case in auth.c dispatch_auth function
Hard-coding the 401 can also accomplish this
But without that, I have two directions I can take, and I'd appreciate
some insight, what should I try next:
1.
I can provide a response with 401 status and valid WWW-Authenticate
header where I control the realm string
I can use that to intercept the 2FA request in
svn_ra_serf__credentials_callback in libsvn_ra_serf util.c, and do the
2FA input
That combined with bearer token, that we return could work without
modifying serf
2.
I can introduce a new serf__authn_scheme_t, and have a cleaner
implementation, but it means serf would have an unofficial auth scheme
implementation
I'm all for doing the right thing, working out how to extend the RFC,
but I have 0 knowledge or experience doing that
I'm happy to help any way I can, but I'd rather not wait for months,
before implementing this :)
What do you think, what route should I explore next?
Do I have a change to get the 1. version approved by the svn community?
Do I have a change to get the 2. version approved by the serf
community? :)
I guess that you realise by now that there's a large overlap between the
two. :)
I just read through RFC 7235 and the way I read this, It's perfectly OK
and blessed from on high to use status 401 to require a multi-factor
token. The interaction would look like this:
1. Client: sends request to URL
2. Server: responds with 401 + WWW-Authenticate for initial
username+password authentication, with Subversion's realm=... parameter
3. Client: sends to URL + Authorization with username and password
(This is how it works now, regardless of authentication type, and
the client continues to send further requests with the same
Authorization header. In the multi-factor scenario, what happens
next is; I'll illustrate with TOTP):
4. Server responds with 401 + "WWW-Authenticate: TOTP realm=..."
5. Client: sends to URL + "Authorization: TOTP 123456" (the time-based PIN)
6. Server: processes the request and responds with a generated token in
a header (or cookies). The token could be a JWT if we want more
control or a random token as suggested by Greg.
7. Client sends "Authorization: Bearer <token>" with further requests.
This works for other 2FA schemes, too; for example, in step 4 the server
could respond with "WWW-Authenticate: SCRAM challenge=Y2hhbGxlbmdlPw==,
realm=..." and in step 5 the client would respond with "Authenticate:
SCRAM cmVzcG9uc2Uh", using the shared secret and the challenge to
generate the token.
This does not require any changes in Serf and is, as far as I can see,
compliant with RFC 7235. But you do need an authentication handler on
the server side to handle the second (and third and fourth... there's no
reason this would be limited to two factors). Also if you use some
random token, the authn handler has to store it and eventually
invalidate it; a JWT contains its expiration time, removing the need for
a token database on the server, but it's a bit of a pain to implement.
On the Subversion client side, libsvn_ra_serf might have to grow another
hook for multi-factor callbacks, and we'd need another authentication
provider that would store the shared-secret per realm, similar to what
the username provider does now.
Best regards,
Peter
On 2025. 05. 23. 17:28, Branko Čibej wrote:
On 23. 5. 25 17:05, Daniel Sahlberg wrote:
Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh<pe...@svnplus.com>:
Hi,
So basically the patch becomes this
I can't say I like the actual branch condition, but I'm open to
suggestions :)
Hi,
I have not studied the patches in detail but I'm not so sure if I
like the
idea of Serf special-casing / hardcoding a custom response reason. I
feel
it would be better to offloading this to Subversion since we control
both
ends there.
I agree. Serf is a general-purpose HTTP client, what we're talking
about here is application-level behaviour. Serf already offloads
authentication to the application, I also can't see a reason why this
would be special-cased in Serf.
Also, RFC7235 [1] require a 401 response to send a WWW-Authenticate
header
- I don't know if it would be possible to use this to send the
challenge.
I have to read up on WWW-Authenticate. ISTR that aside from telling
the client /how/ to authenticate, it's there also support complex
authentication processes.
The response could then be added as a header field. Would it be
possible
for the server to return a bearer token (= more or less the same as a
Set-Cookie) that we could store client-side to include on future
requests?
I'm surprised that multi-step challenge/response mechanism isn't
already standardised in HTTP. True, all the multi-factor schemes I've
used to date are for authentication flow in browsers, where the
server presents a user interface. For headless cases, things like API
tokens tend to be generated in advance through an out of band channel
(again, usually through a UI in a browser). App tokens are, again,
not multi-factor authentication.
Maybe we will have to invent an HTTP workflow for this, but let's not
go it alone. This is, after all, the ASF and there are a few people
around that are ... quite knowledgeable about HTTP. I suggest we
consult. Worst case, there may be an IETF RFC waiting to be written.
-- Brane
P.S.: I say "worst case" because it should've been written long ago
instead of people using status 499 and stuff like that.