Hi,
Sounds like a plan! But I still don't see how I can do this without
modifying serf
The TOTP scheme have to be in the serf_authn_schemes array, and that's
internal to serf
Am I missing something?
JWT is easy to detect and handle, this can be added easily in my
opinion, but I'll take a look once we get there :)
I'll keep sending the same token with a set cookie, that serf and svn
can ignore to make browsers work
Best regards,
Peter
On 2025. 05. 24. 14:01, Branko Čibej wrote:
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.