You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@serf.apache.org by Branko Čibej <br...@apache.org> on 2025/06/14 19:23:19 UTC
Thinking about MFA infrastructure
Hi all,
I've been digging into Serf's support for various authentication schemes
and I notices something that looks like a bit of a limitation.
Unless I'm much mistaken, there's space for only one authentication
baton in Serf's context. It would seem that this is rather a blocker for
implementing multi-factor authentication flows, for example, Basic +
OTP, where the server would first require basic credentials and then, if
those were correct, go on to issue an OTP challenge.
It seems to me that a simple solution for that would be to store an
authn baton per scheme, but I know on the close order of nothing about
the possible side effects.
Yeah, I'm starting small, I have no wish to implement OAuth2 flow any
time soon. Still, a bit of insight from the knowledgeable would be welcome.
-- Brane
Re: Thinking about MFA infrastructure
Posted by Branko Čibej <br...@apache.org>.
On 8. 7. 25 22:22, Dirk-Willem van Gulik wrote:
> On 8 Jul 2025, at 17:26, Branko Čibej<br...@apache.org> wrote:
>> On 26. 6. 25 08:16, Branko Čibej wrote:
>>> On 24. 6. 25 07:52, Branko Čibej wrote:
>>>> On 14. 6. 25 21:23, Branko Čibej wrote:
>>>>> Hi all,
>>>>>
>>>>> I've been digging into Serf's support for various authentication schemes and I notices something that looks like a bit of a limitation.
>>>>>
>>>>> Unless I'm much mistaken, there's space for only one authentication baton in Serf's context. It would seem that this is rather a blocker for implementing multi-factor authentication flows, for example, Basic + OTP, where the server would first require basic credentials and then, if those were correct, go on to issue an OTP challenge.
>>>>>
>>>>> It seems to me that a simple solution for that would be to store an authn baton per scheme, but I know on the close order of nothing about the possible side effects.
>>>>>
>>>>> Yeah, I'm starting small, I have no wish to implement OAuth2 flow any time soon. Still, a bit of insight from the knowledgeable would be welcome.
>>>>
>>>> With r1926674, I think the user-defined-authn branch is ready for review. Here's a short summary of the changes on the branch:
>>>>
>>>> * The (private) struct serf__authn_scheme_t, defined in auth/auth.h,
>>>> grew a number of new members to support user-defined schemes, among
>>>> them five new user-visible callback functions. These, along with
>>>> their interactions, are described in serf.h. The built-in
>>>> authentication schemes don't need or use these new members.
>>>>
>>>> * The (private) table serf_authn_schemes, defined in auth/auth.c, has
>>>> been extended to have room for as many schemes as there are bits in
>>>> serf__authn_scheme_t::type. Locking was added to serialize access,
>>>> because new schemes can be registered at runtime.
>>>>
>>>> * Private callbacks were added to implement the user-visible
>>>> authentication flow.
>>>>
>>>> * Two new public APIs take care of registering and unregistering
>>>> authentication schemes. The latter is tricky because we don't track
>>>> references to the schemes in contexts and connections, only in the
>>>> serf_authn_schemes table; this issue is documented.
>>>>
>>>> * A number of tests were added for all this new stuff.
>>>>
>>>>
>>>> Please take a look if you have time.
>>>>
>>>> svn diff --internal-diff \
>>>> https://svn.apache.org/repos/asf/serf/trunk \
>>>> https://svn.apache.org/repos/asf/serf/branches/user-defined-authn \
>>>> | colordiff --color=always \
>>>> | less -R
>>>>
>>> There are a couple more changes on that branch now:
>>>
>>> * The parameters in the authentication challenge (headers
>>> WWW-Authenticate and Proxy-Authenticate) are now parsed into a
>>> dictionary, using the rules described in RFC 9110.
>>>
>>> * The Authentication-Info and Proxy-Authentication-Info response
>>> headers are now handled and their values parsed as above.
>>>
>>> These two changes should make life much easier for authn scheme implementers. I decided to add this once I saw how many times we have copy-pasted not-quite-compliant parsers throughout the auth code...
>>>
>>> (Note that these changes do not stop implementers from doing whatever wrong-headed, non-compliant horror they can think of, as all the raw information and headers are still available in the callbacks.)
>> Any takers? It's been a couple of weeks now. I'd sure like to get another pair of eyes on these changes before merging them to trunk, but I'd rather not have the branch fall victim to bitrot, either.
> I'll bite - so I've tried it against some auth testing code we privately maintain for legacy hardware keys - and it certainly gets rid of a lot of the boilerplate/header parse code - without loss of functionality. And oddly it passes now an EAGAIN/EINTR edge case that always broke our tests.
>
> Improvement overall.
Thanks for testing! This is encouraging.
-- Brane
Re: Thinking about MFA infrastructure
Posted by Daniel Sahlberg <da...@gmail.com>.
Den tis 8 juli 2025 kl 22:23 skrev Dirk-Willem van Gulik <
dirkx@webweaving.org>:
> On 8 Jul 2025, at 17:26, Branko Čibej <br...@apache.org> wrote:
> > On 26. 6. 25 08:16, Branko Čibej wrote:
> >> On 24. 6. 25 07:52, Branko Čibej wrote:
> >>> On 14. 6. 25 21:23, Branko Čibej wrote:
> >>>> Hi all,
> >>>>
> >>>> I've been digging into Serf's support for various authentication
> schemes and I notices something that looks like a bit of a limitation.
> >>>>
> >>>> Unless I'm much mistaken, there's space for only one authentication
> baton in Serf's context. It would seem that this is rather a blocker for
> implementing multi-factor authentication flows, for example, Basic + OTP,
> where the server would first require basic credentials and then, if those
> were correct, go on to issue an OTP challenge.
> >>>>
> >>>> It seems to me that a simple solution for that would be to store an
> authn baton per scheme, but I know on the close order of nothing about the
> possible side effects.
> >>>>
> >>>> Yeah, I'm starting small, I have no wish to implement OAuth2 flow any
> time soon. Still, a bit of insight from the knowledgeable would be welcome.
> >>>
> >>>
> >>> With r1926674, I think the user-defined-authn branch is ready for
> review. Here's a short summary of the changes on the branch:
> >>>
> >>> * The (private) struct serf__authn_scheme_t, defined in auth/auth.h,
> >>> grew a number of new members to support user-defined schemes, among
> >>> them five new user-visible callback functions. These, along with
> >>> their interactions, are described in serf.h. The built-in
> >>> authentication schemes don't need or use these new members.
> >>>
> >>> * The (private) table serf_authn_schemes, defined in auth/auth.c, has
> >>> been extended to have room for as many schemes as there are bits in
> >>> serf__authn_scheme_t::type. Locking was added to serialize access,
> >>> because new schemes can be registered at runtime.
> >>>
> >>> * Private callbacks were added to implement the user-visible
> >>> authentication flow.
> >>>
> >>> * Two new public APIs take care of registering and unregistering
> >>> authentication schemes. The latter is tricky because we don't track
> >>> references to the schemes in contexts and connections, only in the
> >>> serf_authn_schemes table; this issue is documented.
> >>>
> >>> * A number of tests were added for all this new stuff.
> >>>
> >>>
> >>> Please take a look if you have time.
> >>>
> >>> svn diff --internal-diff \
> >>> https://svn.apache.org/repos/asf/serf/trunk \
> >>> https://svn.apache.org/repos/asf/serf/branches/user-defined-authn \
> >>> | colordiff --color=always \
> >>> | less -R
> >>>
> >>
> >> There are a couple more changes on that branch now:
> >>
> >> * The parameters in the authentication challenge (headers
> >> WWW-Authenticate and Proxy-Authenticate) are now parsed into a
> >> dictionary, using the rules described in RFC 9110.
> >>
> >> * The Authentication-Info and Proxy-Authentication-Info response
> >> headers are now handled and their values parsed as above.
> >>
> >> These two changes should make life much easier for authn scheme
> implementers. I decided to add this once I saw how many times we have
> copy-pasted not-quite-compliant parsers throughout the auth code...
> >>
> >> (Note that these changes do not stop implementers from doing whatever
> wrong-headed, non-compliant horror they can think of, as all the raw
> information and headers are still available in the callbacks.)
> >
> > Any takers? It's been a couple of weeks now. I'd sure like to get
> another pair of eyes on these changes before merging them to trunk, but I'd
> rather not have the branch fall victim to bitrot, either.
>
> I'll bite - so I've tried it against some auth testing code we privately
> maintain for legacy hardware keys - and it certainly gets rid of a lot of
> the boilerplate/header parse code - without loss of functionality. And
> oddly it passes now an EAGAIN/EINTR edge case that always broke our tests.
>
> Improvement overall.
>
> Dw
Thanks for testing! It is on my todo list to review it but it seems there
are always new issues / pr popping up and I've not been able to prioritise
this. My goal is to do it before the end of summer vacations...
/Daniel
Re: Thinking about MFA infrastructure
Posted by Dirk-Willem van Gulik <di...@webweaving.org>.
On 8 Jul 2025, at 17:26, Branko Čibej <br...@apache.org> wrote:
> On 26. 6. 25 08:16, Branko Čibej wrote:
>> On 24. 6. 25 07:52, Branko Čibej wrote:
>>> On 14. 6. 25 21:23, Branko Čibej wrote:
>>>> Hi all,
>>>>
>>>> I've been digging into Serf's support for various authentication schemes and I notices something that looks like a bit of a limitation.
>>>>
>>>> Unless I'm much mistaken, there's space for only one authentication baton in Serf's context. It would seem that this is rather a blocker for implementing multi-factor authentication flows, for example, Basic + OTP, where the server would first require basic credentials and then, if those were correct, go on to issue an OTP challenge.
>>>>
>>>> It seems to me that a simple solution for that would be to store an authn baton per scheme, but I know on the close order of nothing about the possible side effects.
>>>>
>>>> Yeah, I'm starting small, I have no wish to implement OAuth2 flow any time soon. Still, a bit of insight from the knowledgeable would be welcome.
>>>
>>>
>>> With r1926674, I think the user-defined-authn branch is ready for review. Here's a short summary of the changes on the branch:
>>>
>>> * The (private) struct serf__authn_scheme_t, defined in auth/auth.h,
>>> grew a number of new members to support user-defined schemes, among
>>> them five new user-visible callback functions. These, along with
>>> their interactions, are described in serf.h. The built-in
>>> authentication schemes don't need or use these new members.
>>>
>>> * The (private) table serf_authn_schemes, defined in auth/auth.c, has
>>> been extended to have room for as many schemes as there are bits in
>>> serf__authn_scheme_t::type. Locking was added to serialize access,
>>> because new schemes can be registered at runtime.
>>>
>>> * Private callbacks were added to implement the user-visible
>>> authentication flow.
>>>
>>> * Two new public APIs take care of registering and unregistering
>>> authentication schemes. The latter is tricky because we don't track
>>> references to the schemes in contexts and connections, only in the
>>> serf_authn_schemes table; this issue is documented.
>>>
>>> * A number of tests were added for all this new stuff.
>>>
>>>
>>> Please take a look if you have time.
>>>
>>> svn diff --internal-diff \
>>> https://svn.apache.org/repos/asf/serf/trunk \
>>> https://svn.apache.org/repos/asf/serf/branches/user-defined-authn \
>>> | colordiff --color=always \
>>> | less -R
>>>
>>
>> There are a couple more changes on that branch now:
>>
>> * The parameters in the authentication challenge (headers
>> WWW-Authenticate and Proxy-Authenticate) are now parsed into a
>> dictionary, using the rules described in RFC 9110.
>>
>> * The Authentication-Info and Proxy-Authentication-Info response
>> headers are now handled and their values parsed as above.
>>
>> These two changes should make life much easier for authn scheme implementers. I decided to add this once I saw how many times we have copy-pasted not-quite-compliant parsers throughout the auth code...
>>
>> (Note that these changes do not stop implementers from doing whatever wrong-headed, non-compliant horror they can think of, as all the raw information and headers are still available in the callbacks.)
>
> Any takers? It's been a couple of weeks now. I'd sure like to get another pair of eyes on these changes before merging them to trunk, but I'd rather not have the branch fall victim to bitrot, either.
I'll bite - so I've tried it against some auth testing code we privately maintain for legacy hardware keys - and it certainly gets rid of a lot of the boilerplate/header parse code - without loss of functionality. And oddly it passes now an EAGAIN/EINTR edge case that always broke our tests.
Improvement overall.
Dw
Re: Thinking about MFA infrastructure
Posted by Branko Čibej <br...@apache.org>.
On 8. 7. 25 17:26, Branko Čibej wrote:
> On 26. 6. 25 08:16, Branko Čibej wrote:
>> On 24. 6. 25 07:52, Branko Čibej wrote:
>>> On 14. 6. 25 21:23, Branko Čibej wrote:
>>>> Hi all,
>>>>
>>>> I've been digging into Serf's support for various authentication
>>>> schemes and I notices something that looks like a bit of a limitation.
>>>>
>>>> Unless I'm much mistaken, there's space for only one authentication
>>>> baton in Serf's context. It would seem that this is rather a
>>>> blocker for implementing multi-factor authentication flows, for
>>>> example, Basic + OTP, where the server would first require basic
>>>> credentials and then, if those were correct, go on to issue an OTP
>>>> challenge.
>>>>
>>>> It seems to me that a simple solution for that would be to store an
>>>> authn baton per scheme, but I know on the close order of nothing
>>>> about the possible side effects.
>>>>
>>>> Yeah, I'm starting small, I have no wish to implement OAuth2 flow
>>>> any time soon. Still, a bit of insight from the knowledgeable would
>>>> be welcome.
>>>
>>>
>>> With r1926674, I think the user-defined-authn branch is ready for
>>> review. Here's a short summary of the changes on the branch:
>>>
>>> * The (private) struct serf__authn_scheme_t, defined in auth/auth.h,
>>> grew a number of new members to support user-defined schemes, among
>>> them five new user-visible callback functions. These, along with
>>> their interactions, are described in serf.h. The built-in
>>> authentication schemes don't need or use these new members.
>>>
>>> * The (private) table serf_authn_schemes, defined in auth/auth.c, has
>>> been extended to have room for as many schemes as there are bits in
>>> serf__authn_scheme_t::type. Locking was added to serialize access,
>>> because new schemes can be registered at runtime.
>>>
>>> * Private callbacks were added to implement the user-visible
>>> authentication flow.
>>>
>>> * Two new public APIs take care of registering and unregistering
>>> authentication schemes. The latter is tricky because we don't track
>>> references to the schemes in contexts and connections, only in the
>>> serf_authn_schemes table; this issue is documented.
>>>
>>> * A number of tests were added for all this new stuff.
>>>
>>>
>>> Please take a look if you have time.
>>>
>>> svn diff --internal-diff \
>>> https://svn.apache.org/repos/asf/serf/trunk \
>>> https://svn.apache.org/repos/asf/serf/branches/user-defined-authn \
>>> | colordiff --color=always \
>>> | less -R
>>>
>>
>> There are a couple more changes on that branch now:
>>
>> * The parameters in the authentication challenge (headers
>> WWW-Authenticate and Proxy-Authenticate) are now parsed into a
>> dictionary, using the rules described in RFC 9110.
>>
>> * The Authentication-Info and Proxy-Authentication-Info response
>> headers are now handled and their values parsed as above.
>>
>> These two changes should make life much easier for authn scheme
>> implementers. I decided to add this once I saw how many times we have
>> copy-pasted not-quite-compliant parsers throughout the auth code...
>>
>> (Note that these changes do not stop implementers from doing whatever
>> wrong-headed, non-compliant horror they can think of, as all the raw
>> information and headers are still available in the callbacks.)
>
>
> Any takers? It's been a couple of weeks now. I'd sure like to get
> another pair of eyes on these changes before merging them to trunk,
> but I'd rather not have the branch fall victim to bitrot, either.
After a month of waiting for feedback, I decided to merge this branch to
trunk in r1927627. All my testing on several platforms has not shown any
problems.
-- Brane
Re: Thinking about MFA infrastructure
Posted by Branko Čibej <br...@apache.org>.
On 26. 6. 25 08:16, Branko Čibej wrote:
> On 24. 6. 25 07:52, Branko Čibej wrote:
>> On 14. 6. 25 21:23, Branko Čibej wrote:
>>> Hi all,
>>>
>>> I've been digging into Serf's support for various authentication
>>> schemes and I notices something that looks like a bit of a limitation.
>>>
>>> Unless I'm much mistaken, there's space for only one authentication
>>> baton in Serf's context. It would seem that this is rather a blocker
>>> for implementing multi-factor authentication flows, for example,
>>> Basic + OTP, where the server would first require basic credentials
>>> and then, if those were correct, go on to issue an OTP challenge.
>>>
>>> It seems to me that a simple solution for that would be to store an
>>> authn baton per scheme, but I know on the close order of nothing
>>> about the possible side effects.
>>>
>>> Yeah, I'm starting small, I have no wish to implement OAuth2 flow
>>> any time soon. Still, a bit of insight from the knowledgeable would
>>> be welcome.
>>
>>
>> With r1926674, I think the user-defined-authn branch is ready for
>> review. Here's a short summary of the changes on the branch:
>>
>> * The (private) struct serf__authn_scheme_t, defined in auth/auth.h,
>> grew a number of new members to support user-defined schemes, among
>> them five new user-visible callback functions. These, along with
>> their interactions, are described in serf.h. The built-in
>> authentication schemes don't need or use these new members.
>>
>> * The (private) table serf_authn_schemes, defined in auth/auth.c, has
>> been extended to have room for as many schemes as there are bits in
>> serf__authn_scheme_t::type. Locking was added to serialize access,
>> because new schemes can be registered at runtime.
>>
>> * Private callbacks were added to implement the user-visible
>> authentication flow.
>>
>> * Two new public APIs take care of registering and unregistering
>> authentication schemes. The latter is tricky because we don't track
>> references to the schemes in contexts and connections, only in the
>> serf_authn_schemes table; this issue is documented.
>>
>> * A number of tests were added for all this new stuff.
>>
>>
>> Please take a look if you have time.
>>
>> svn diff --internal-diff \
>> https://svn.apache.org/repos/asf/serf/trunk \
>> https://svn.apache.org/repos/asf/serf/branches/user-defined-authn \
>> | colordiff --color=always \
>> | less -R
>>
>
> There are a couple more changes on that branch now:
>
> * The parameters in the authentication challenge (headers
> WWW-Authenticate and Proxy-Authenticate) are now parsed into a
> dictionary, using the rules described in RFC 9110.
>
> * The Authentication-Info and Proxy-Authentication-Info response
> headers are now handled and their values parsed as above.
>
> These two changes should make life much easier for authn scheme
> implementers. I decided to add this once I saw how many times we have
> copy-pasted not-quite-compliant parsers throughout the auth code...
>
> (Note that these changes do not stop implementers from doing whatever
> wrong-headed, non-compliant horror they can think of, as all the raw
> information and headers are still available in the callbacks.)
Any takers? It's been a couple of weeks now. I'd sure like to get
another pair of eyes on these changes before merging them to trunk, but
I'd rather not have the branch fall victim to bitrot, either.
-- Brane
Re: Thinking about MFA infrastructure
Posted by Branko Čibej <br...@apache.org>.
On 24. 6. 25 07:52, Branko Čibej wrote:
> On 14. 6. 25 21:23, Branko Čibej wrote:
>> Hi all,
>>
>> I've been digging into Serf's support for various authentication
>> schemes and I notices something that looks like a bit of a limitation.
>>
>> Unless I'm much mistaken, there's space for only one authentication
>> baton in Serf's context. It would seem that this is rather a blocker
>> for implementing multi-factor authentication flows, for example,
>> Basic + OTP, where the server would first require basic credentials
>> and then, if those were correct, go on to issue an OTP challenge.
>>
>> It seems to me that a simple solution for that would be to store an
>> authn baton per scheme, but I know on the close order of nothing
>> about the possible side effects.
>>
>> Yeah, I'm starting small, I have no wish to implement OAuth2 flow any
>> time soon. Still, a bit of insight from the knowledgeable would be
>> welcome.
>
>
> With r1926674, I think the user-defined-authn branch is ready for
> review. Here's a short summary of the changes on the branch:
>
> * The (private) struct serf__authn_scheme_t, defined in auth/auth.h,
> grew a number of new members to support user-defined schemes, among
> them five new user-visible callback functions. These, along with
> their interactions, are described in serf.h. The built-in
> authentication schemes don't need or use these new members.
>
> * The (private) table serf_authn_schemes, defined in auth/auth.c, has
> been extended to have room for as many schemes as there are bits in
> serf__authn_scheme_t::type. Locking was added to serialize access,
> because new schemes can be registered at runtime.
>
> * Private callbacks were added to implement the user-visible
> authentication flow.
>
> * Two new public APIs take care of registering and unregistering
> authentication schemes. The latter is tricky because we don't track
> references to the schemes in contexts and connections, only in the
> serf_authn_schemes table; this issue is documented.
>
> * A number of tests were added for all this new stuff.
>
>
> Please take a look if you have time.
>
> svn diff --internal-diff \
> https://svn.apache.org/repos/asf/serf/trunk \
> https://svn.apache.org/repos/asf/serf/branches/user-defined-authn \
> | colordiff --color=always \
> | less -R
>
There are a couple more changes on that branch now:
* The parameters in the authentication challenge (headers
WWW-Authenticate and Proxy-Authenticate) are now parsed into a
dictionary, using the rules described in RFC 9110.
* The Authentication-Info and Proxy-Authentication-Info response
headers are now handled and their values parsed as above.
These two changes should make life much easier for authn scheme
implementers. I decided to add this once I saw how many times we have
copy-pasted not-quite-compliant parsers throughout the auth code...
(Note that these changes do not stop implementers from doing whatever
wrong-headed, non-compliant horror they can think of, as all the raw
information and headers are still available in the callbacks.)
-- Brane
Re: Thinking about MFA infrastructure
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
This seems to be exactly what I need, I'll continue working on the
integration, and let you know if I get stuck :)
Thanks
Best regards,
Peter
On 2025. 06. 24. 14:58, Peter Balogh wrote:
>
> Hi,
>
> Awesome, thank you! :)
> I'll see if I can fire up my svn 2FA PoC using this in a few days
>
> Best regards,
> Peter
> On 2025. 06. 24. 7:52, Branko Čibej wrote:
>> On 14. 6. 25 21:23, Branko Čibej wrote:
>>> Hi all,
>>>
>>> I've been digging into Serf's support for various authentication
>>> schemes and I notices something that looks like a bit of a limitation.
>>>
>>> Unless I'm much mistaken, there's space for only one authentication
>>> baton in Serf's context. It would seem that this is rather a blocker
>>> for implementing multi-factor authentication flows, for example,
>>> Basic + OTP, where the server would first require basic credentials
>>> and then, if those were correct, go on to issue an OTP challenge.
>>>
>>> It seems to me that a simple solution for that would be to store an
>>> authn baton per scheme, but I know on the close order of nothing
>>> about the possible side effects.
>>>
>>> Yeah, I'm starting small, I have no wish to implement OAuth2 flow
>>> any time soon. Still, a bit of insight from the knowledgeable would
>>> be welcome.
>>
>>
>> With r1926674, I think the user-defined-authn branch is ready for
>> review. Here's a short summary of the changes on the branch:
>>
>> * The (private) struct serf__authn_scheme_t, defined in
>> auth/auth.h, grew a number of new members to support user-defined
>> schemes, among them five new user-visible callback functions.
>> These, along with their interactions, are described in serf.h.
>> The built-in authentication schemes don't need or use these new
>> members.
>>
>> * The (private) table serf_authn_schemes, defined in auth/auth.c,
>> has been extended to have room for as many schemes as there are
>> bits in serf__authn_scheme_t::type. Locking was added to
>> serialize access, because new schemes can be registered at runtime.
>>
>> * Private callbacks were added to implement the user-visible
>> authentication flow.
>>
>> * Two new public APIs take care of registering and unregistering
>> authentication schemes. The latter is tricky because we don't
>> track references to the schemes in contexts and connections, only
>> in the serf_authn_schemes table; this issue is documented.
>>
>> * A number of tests were added for all this new stuff.
>>
>>
>> Please take a look if you have time.
>>
>> svn diff --internal-diff \
>> https://svn.apache.org/repos/asf/serf/trunk \
>> https://svn.apache.org/repos/asf/serf/branches/user-defined-authn \
>> | colordiff --color=always \
>> | less -R
>>
>>
>> -- Brane
>>
Re: Thinking about MFA infrastructure
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
Awesome, thank you! :)
I'll see if I can fire up my svn 2FA PoC using this in a few days
Best regards,
Peter
On 2025. 06. 24. 7:52, Branko Čibej wrote:
> On 14. 6. 25 21:23, Branko Čibej wrote:
>> Hi all,
>>
>> I've been digging into Serf's support for various authentication
>> schemes and I notices something that looks like a bit of a limitation.
>>
>> Unless I'm much mistaken, there's space for only one authentication
>> baton in Serf's context. It would seem that this is rather a blocker
>> for implementing multi-factor authentication flows, for example,
>> Basic + OTP, where the server would first require basic credentials
>> and then, if those were correct, go on to issue an OTP challenge.
>>
>> It seems to me that a simple solution for that would be to store an
>> authn baton per scheme, but I know on the close order of nothing
>> about the possible side effects.
>>
>> Yeah, I'm starting small, I have no wish to implement OAuth2 flow any
>> time soon. Still, a bit of insight from the knowledgeable would be
>> welcome.
>
>
> With r1926674, I think the user-defined-authn branch is ready for
> review. Here's a short summary of the changes on the branch:
>
> * The (private) struct serf__authn_scheme_t, defined in auth/auth.h,
> grew a number of new members to support user-defined schemes,
> among them five new user-visible callback functions. These, along
> with their interactions, are described in serf.h. The built-in
> authentication schemes don't need or use these new members.
>
> * The (private) table serf_authn_schemes, defined in auth/auth.c,
> has been extended to have room for as many schemes as there are
> bits in serf__authn_scheme_t::type. Locking was added to serialize
> access, because new schemes can be registered at runtime.
>
> * Private callbacks were added to implement the user-visible
> authentication flow.
>
> * Two new public APIs take care of registering and unregistering
> authentication schemes. The latter is tricky because we don't
> track references to the schemes in contexts and connections, only
> in the serf_authn_schemes table; this issue is documented.
>
> * A number of tests were added for all this new stuff.
>
>
> Please take a look if you have time.
>
> svn diff --internal-diff \
> https://svn.apache.org/repos/asf/serf/trunk \
> https://svn.apache.org/repos/asf/serf/branches/user-defined-authn \
> | colordiff --color=always \
> | less -R
>
>
> -- Brane
>
Re: Thinking about MFA infrastructure
Posted by Daniel Sahlberg <da...@gmail.com>.
Den tis 24 juni 2025 kl 07:52 skrev Branko Čibej <br...@apache.org>:
> With r1926674, I think the user-defined-authn branch is ready for
> review. Here's a short summary of the changes on the branch:
>
[...]
Thanks for the hard work so far!
I will try to take a look but I won't be able to allocate any meaningful
time until earliest during the weekend.
Cheers,
Daniel
Re: Thinking about MFA infrastructure
Posted by Branko Čibej <br...@apache.org>.
On 14. 6. 25 21:23, Branko Čibej wrote:
> Hi all,
>
> I've been digging into Serf's support for various authentication
> schemes and I notices something that looks like a bit of a limitation.
>
> Unless I'm much mistaken, there's space for only one authentication
> baton in Serf's context. It would seem that this is rather a blocker
> for implementing multi-factor authentication flows, for example, Basic
> + OTP, where the server would first require basic credentials and
> then, if those were correct, go on to issue an OTP challenge.
>
> It seems to me that a simple solution for that would be to store an
> authn baton per scheme, but I know on the close order of nothing about
> the possible side effects.
>
> Yeah, I'm starting small, I have no wish to implement OAuth2 flow any
> time soon. Still, a bit of insight from the knowledgeable would be
> welcome.
With r1926674, I think the user-defined-authn branch is ready for
review. Here's a short summary of the changes on the branch:
* The (private) struct serf__authn_scheme_t, defined in auth/auth.h,
grew a number of new members to support user-defined schemes, among
them five new user-visible callback functions. These, along with
their interactions, are described in serf.h. The built-in
authentication schemes don't need or use these new members.
* The (private) table serf_authn_schemes, defined in auth/auth.c, has
been extended to have room for as many schemes as there are bits in
serf__authn_scheme_t::type. Locking was added to serialize access,
because new schemes can be registered at runtime.
* Private callbacks were added to implement the user-visible
authentication flow.
* Two new public APIs take care of registering and unregistering
authentication schemes. The latter is tricky because we don't track
references to the schemes in contexts and connections, only in the
serf_authn_schemes table; this issue is documented.
* A number of tests were added for all this new stuff.
Please take a look if you have time.
svn diff --internal-diff \
https://svn.apache.org/repos/asf/serf/trunk \
https://svn.apache.org/repos/asf/serf/branches/user-defined-authn \
| colordiff --color=always \
| less -R
-- Brane
Re: Thinking about MFA infrastructure
Posted by Branko Čibej <br...@apache.org>.
On 23. 9. 25 09:14, Peter Balogh wrote:
> On 7/20/2025 2:55 AM, Branko Čibej wrote:
>> [please do not top-post]
>> On 19. 7. 25 23:50, Peter Balogh wrote:
>>> Hi,
>>>
>>> So you’re generally you have no objection to the idea, that I
>>> recreate the whole Basic auth implementation in svn to support a
>>> custom Basic+OTP auth scheme?
>>
>>
>> Why are you asking about Subversion here? That's another mailing
>> list, you should discuss that there.
>>
>>
>> The point of multi-factor authorisation is that each identifying
>> factor comes from a different place. Some Basic+OTP authentication
>> scheme isn't MFA, and the client will have to keep sending the same
>> info (possibly with an updated OTP token) on every request. That
>> would probably involve using some kind of bearer token. I think the
>> place to start is here: https://www.rfc-editor.org/rfc/rfc9110,
>> section 11, and design a scheme that at the very least does not
>> require sending the username+password on every request. the
>> Authentication-Info response header (11.6.3) may turn out to be
>> useful here. And at that point it might make sense to look closely at
>> OAuth2 again. Who knows, maybe it can be made to work without
>> requiring a browser. -- Brane
>>> On Thu, Jul 17, 2025, at 15:05, Branko Čibej wrote:
>>>> On 14. 7. 25 01:01, Peter Balogh wrote:
>>>>> Hi,
>>>>>
>>>>> I think I've just run into this,
>>>>>
>>>>> Here's the current flow:
>>>>> 1st request without auth gets a 401 response with WWW-Authenticate:
>>>>> Digest header
>>>>> 2nd request sent with Authorization header gets a WWW-Authenticate:
>>>>> MFA headaer
>>>>> 3rd request is sent with OTP, but this goes without Authorization:
>>>>> Digest
>>>>> In my current implementation the user's password is rerequested, and
>>>>> everything works fine after that, but I'm having trouble fixing this
>>>> As I already wrote elsewhere, Serf handles only one authentication
>>>> method per realm. And that's correct, because it turns out that the
>>>> RFC
>>>> requires it to be so.
>>>>
>>>>
>>>>> I can probably add an auth method that does both Basic+OTP, but it'd
>>>>> probably mean code duplication, or calling the Basic auth method
>>>>> functions from the new method,
>>>> Not without hacking Serf's internals directly. The user-defined-authn
>>>> code doesn't give you access to those, on purpose.
>>>>
>>>>> but these feel wrong
>>>>>
>>>>> Any pointers, how to move this forward?
>>>>>
>>>>> Best regards,
>>>>> Peter
>>>>>
>>>>> On 2025. 06. 14. 21:23, Branko Čibej wrote:
>>>>>> Hi all,
>>>>>>
>>>>>> I've been digging into Serf's support for various authentication
>>>>>> schemes and I notices something that looks like a bit of a
>>>>>> limitation.
>>>>>>
>>>>>> Unless I'm much mistaken, there's space for only one authentication
>>>>>> baton in Serf's context. It would seem that this is rather a blocker
>>>>>> for implementing multi-factor authentication flows, for example,
>>>>>> Basic + OTP, where the server would first require basic credentials
>>>>>> and then, if those were correct, go on to issue an OTP challenge.
>>>>>>
>>>>>> It seems to me that a simple solution for that would be to store an
>>>>>> authn baton per scheme, but I know on the close order of nothing
>>>>>> about the possible side effects.
>>>>>>
>>>>>> Yeah, I'm starting small, I have no wish to implement OAuth2 flow
>>>>>> any
>>>>>> time soon. Still, a bit of insight from the knowledgeable would be
>>>>>> welcome.
>>>>>>
>>>>>> -- Brane
>>>>>>
>>
> Hi,
>
> I wanted to give a quick update of my progress in the last couple
> months, partially to share the current plan for feedback, and
> partially to have a written log of how I got to the server side of MFA.
> The initial idea was that after a successful Basic / Digest auth
> request, the server would still return a 401, but with a different
> Auth method
Keep in mind that once an authorisation method succeeds, you must from
then on always send the Authorization header for that method with
requests. Serf does that automagically, as long as the authn scheme
code is written correctly.
> The current svn/serf implementation poses a problem, because after the
> auth response, in the subsequent requests, the Authorization header
> will not be presented, as that auth method did not succeed
> That makes properly setting the user on the server side a difficult task.
Invalid Authorization headers (those that did not produce a successful
response) must not be repeated in requests. In other words, whatever you
send to the server must contain all the information required for
authenticating a request. In your case, you'll have to somehow send the
username along with whichever second factor you choose.
> Initially I tried using mod rewrite, but I have not found a way to set
> a username that way
> I've tried implementing an AuthBasicProvider script, but that doesn't
> trigger in case there's no Authorization header
> I've finally found mod_lua, and LuaHookAccessChecker seems to be on
> the correct path, so I'll be implementing the MFA server side using
> this route
The server must not cache raw credentials. What it can do is return an
Authentication-Info response that contains, e.g., an access token to
present for subsequent requests, and the client then takes care of
constructing the correct Authorization header. The cache is then on the
client side, the server only validates the token. A JWT for example
contains all relevant info, without exposing passwords, even encrypted,
on the 'net. Something like a TOTP code can't be part of the JWT, but
can be safely sent in a separate authn parameter, since it's a one-time
code that can't be spoofed in a repeat attack, especially when paired
with a token with a unique nonce.
-- Brane
Re: Thinking about MFA infrastructure
Posted by Peter Balogh <pe...@svnplus.com>.
On 7/20/2025 2:55 AM, Branko Čibej wrote:
> [please do not top-post]
> On 19. 7. 25 23:50, Peter Balogh wrote:
>> Hi,
>>
>> So you’re generally you have no objection to the idea, that I
>> recreate the whole Basic auth implementation in svn to support a
>> custom Basic+OTP auth scheme?
>
>
> Why are you asking about Subversion here? That's another mailing list,
> you should discuss that there.
>
>
> The point of multi-factor authorisation is that each identifying
> factor comes from a different place. Some Basic+OTP authentication
> scheme isn't MFA, and the client will have to keep sending the same
> info (possibly with an updated OTP token) on every request. That would
> probably involve using some kind of bearer token. I think the place to
> start is here: https://www.rfc-editor.org/rfc/rfc9110, section 11, and
> design a scheme that at the very least does not require sending the
> username+password on every request. the Authentication-Info response
> header (11.6.3) may turn out to be useful here. And at that point it
> might make sense to look closely at OAuth2 again. Who knows, maybe it
> can be made to work without requiring a browser. -- Brane
>> On Thu, Jul 17, 2025, at 15:05, Branko Čibej wrote:
>>> On 14. 7. 25 01:01, Peter Balogh wrote:
>>>> Hi,
>>>>
>>>> I think I've just run into this,
>>>>
>>>> Here's the current flow:
>>>> 1st request without auth gets a 401 response with WWW-Authenticate:
>>>> Digest header
>>>> 2nd request sent with Authorization header gets a WWW-Authenticate:
>>>> MFA headaer
>>>> 3rd request is sent with OTP, but this goes without Authorization:
>>>> Digest
>>>> In my current implementation the user's password is rerequested, and
>>>> everything works fine after that, but I'm having trouble fixing this
>>> As I already wrote elsewhere, Serf handles only one authentication
>>> method per realm. And that's correct, because it turns out that the RFC
>>> requires it to be so.
>>>
>>>
>>>> I can probably add an auth method that does both Basic+OTP, but it'd
>>>> probably mean code duplication, or calling the Basic auth method
>>>> functions from the new method,
>>> Not without hacking Serf's internals directly. The user-defined-authn
>>> code doesn't give you access to those, on purpose.
>>>
>>>> but these feel wrong
>>>>
>>>> Any pointers, how to move this forward?
>>>>
>>>> Best regards,
>>>> Peter
>>>>
>>>> On 2025. 06. 14. 21:23, Branko Čibej wrote:
>>>>> Hi all,
>>>>>
>>>>> I've been digging into Serf's support for various authentication
>>>>> schemes and I notices something that looks like a bit of a
>>>>> limitation.
>>>>>
>>>>> Unless I'm much mistaken, there's space for only one authentication
>>>>> baton in Serf's context. It would seem that this is rather a blocker
>>>>> for implementing multi-factor authentication flows, for example,
>>>>> Basic + OTP, where the server would first require basic credentials
>>>>> and then, if those were correct, go on to issue an OTP challenge.
>>>>>
>>>>> It seems to me that a simple solution for that would be to store an
>>>>> authn baton per scheme, but I know on the close order of nothing
>>>>> about the possible side effects.
>>>>>
>>>>> Yeah, I'm starting small, I have no wish to implement OAuth2 flow any
>>>>> time soon. Still, a bit of insight from the knowledgeable would be
>>>>> welcome.
>>>>>
>>>>> -- Brane
>>>>>
>
Hi,
I wanted to give a quick update of my progress in the last couple
months, partially to share the current plan for feedback, and partially
to have a written log of how I got to the server side of MFA.
The initial idea was that after a successful Basic / Digest auth
request, the server would still return a 401, but with a different Auth
method
The current svn/serf implementation poses a problem, because after the
auth response, in the subsequent requests, the Authorization header will
not be presented, as that auth method did not succeed
That makes properly setting the user on the server side a difficult task.
Initially I tried using mod rewrite, but I have not found a way to set a
username that way
I've tried implementing an AuthBasicProvider script, but that doesn't
trigger in case there's no Authorization header
I've finally found mod_lua, and LuaHookAccessChecker seems to be on the
correct path, so I'll be implementing the MFA server side using this route
Let me know if you have any insight or comments to this approach
Best regards,
Peter
Re: Thinking about MFA infrastructure
Posted by Branko Čibej <br...@apache.org>.
[please do not top-post]
On 19. 7. 25 23:50, Peter Balogh wrote:
> Hi,
>
> So you’re generally you have no objection to the idea, that I recreate the whole Basic auth implementation in svn to support a custom Basic+OTP auth scheme?
Why are you asking about Subversion here? That's another mailing list,
you should discuss that there.
The point of multi-factor authorisation is that each identifying factor
comes from a different place. Some Basic+OTP authentication scheme isn't
MFA, and the client will have to keep sending the same info (possibly
with an updated OTP token) on every request. That would probably involve
using some kind of bearer token. I think the place to start is here:
https://www.rfc-editor.org/rfc/rfc9110, section 11, and design a scheme
that at the very least does not require sending the username+password on
every request. the Authentication-Info response header (11.6.3) may turn
out to be useful here. And at that point it might make sense to look
closely at OAuth2 again. Who knows, maybe it can be made to work without
requiring a browser. -- Brane
> On Thu, Jul 17, 2025, at 15:05, Branko Čibej wrote:
>> On 14. 7. 25 01:01, Peter Balogh wrote:
>>> Hi,
>>>
>>> I think I've just run into this,
>>>
>>> Here's the current flow:
>>> 1st request without auth gets a 401 response with WWW-Authenticate:
>>> Digest header
>>> 2nd request sent with Authorization header gets a WWW-Authenticate:
>>> MFA headaer
>>> 3rd request is sent with OTP, but this goes without Authorization: Digest
>>> In my current implementation the user's password is rerequested, and
>>> everything works fine after that, but I'm having trouble fixing this
>> As I already wrote elsewhere, Serf handles only one authentication
>> method per realm. And that's correct, because it turns out that the RFC
>> requires it to be so.
>>
>>
>>> I can probably add an auth method that does both Basic+OTP, but it'd
>>> probably mean code duplication, or calling the Basic auth method
>>> functions from the new method,
>> Not without hacking Serf's internals directly. The user-defined-authn
>> code doesn't give you access to those, on purpose.
>>
>>> but these feel wrong
>>>
>>> Any pointers, how to move this forward?
>>>
>>> Best regards,
>>> Peter
>>>
>>> On 2025. 06. 14. 21:23, Branko Čibej wrote:
>>>> Hi all,
>>>>
>>>> I've been digging into Serf's support for various authentication
>>>> schemes and I notices something that looks like a bit of a limitation.
>>>>
>>>> Unless I'm much mistaken, there's space for only one authentication
>>>> baton in Serf's context. It would seem that this is rather a blocker
>>>> for implementing multi-factor authentication flows, for example,
>>>> Basic + OTP, where the server would first require basic credentials
>>>> and then, if those were correct, go on to issue an OTP challenge.
>>>>
>>>> It seems to me that a simple solution for that would be to store an
>>>> authn baton per scheme, but I know on the close order of nothing
>>>> about the possible side effects.
>>>>
>>>> Yeah, I'm starting small, I have no wish to implement OAuth2 flow any
>>>> time soon. Still, a bit of insight from the knowledgeable would be
>>>> welcome.
>>>>
>>>> -- Brane
>>>>
Re: Thinking about MFA infrastructure
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
So you’re generally you have no objection to the idea, that I recreate the whole Basic auth implementation in svn to support a custom Basic+OTP auth scheme?
Best regards,
Peter
On Thu, Jul 17, 2025, at 15:05, Branko Čibej wrote:
> On 14. 7. 25 01:01, Peter Balogh wrote:
> > Hi,
> >
> > I think I've just run into this,
> >
> > Here's the current flow:
> > 1st request without auth gets a 401 response with WWW-Authenticate:
> > Digest header
> > 2nd request sent with Authorization header gets a WWW-Authenticate:
> > MFA headaer
> > 3rd request is sent with OTP, but this goes without Authorization: Digest
> > In my current implementation the user's password is rerequested, and
> > everything works fine after that, but I'm having trouble fixing this
>
> As I already wrote elsewhere, Serf handles only one authentication
> method per realm. And that's correct, because it turns out that the RFC
> requires it to be so.
>
>
> > I can probably add an auth method that does both Basic+OTP, but it'd
> > probably mean code duplication, or calling the Basic auth method
> > functions from the new method,
>
> Not without hacking Serf's internals directly. The user-defined-authn
> code doesn't give you access to those, on purpose.
>
> > but these feel wrong
> >
> > Any pointers, how to move this forward?
> >
> > Best regards,
> > Peter
> >
> > On 2025. 06. 14. 21:23, Branko Čibej wrote:
> >> Hi all,
> >>
> >> I've been digging into Serf's support for various authentication
> >> schemes and I notices something that looks like a bit of a limitation.
> >>
> >> Unless I'm much mistaken, there's space for only one authentication
> >> baton in Serf's context. It would seem that this is rather a blocker
> >> for implementing multi-factor authentication flows, for example,
> >> Basic + OTP, where the server would first require basic credentials
> >> and then, if those were correct, go on to issue an OTP challenge.
> >>
> >> It seems to me that a simple solution for that would be to store an
> >> authn baton per scheme, but I know on the close order of nothing
> >> about the possible side effects.
> >>
> >> Yeah, I'm starting small, I have no wish to implement OAuth2 flow any
> >> time soon. Still, a bit of insight from the knowledgeable would be
> >> welcome.
> >>
> >> -- Brane
> >>
>
Re: Thinking about MFA infrastructure
Posted by Branko Čibej <br...@apache.org>.
On 14. 7. 25 01:01, Peter Balogh wrote:
> Hi,
>
> I think I've just run into this,
>
> Here's the current flow:
> 1st request without auth gets a 401 response with WWW-Authenticate:
> Digest header
> 2nd request sent with Authorization header gets a WWW-Authenticate:
> MFA headaer
> 3rd request is sent with OTP, but this goes without Authorization: Digest
> In my current implementation the user's password is rerequested, and
> everything works fine after that, but I'm having trouble fixing this
As I already wrote elsewhere, Serf handles only one authentication
method per realm. And that's correct, because it turns out that the RFC
requires it to be so.
> I can probably add an auth method that does both Basic+OTP, but it'd
> probably mean code duplication, or calling the Basic auth method
> functions from the new method,
Not without hacking Serf's internals directly. The user-defined-authn
code doesn't give you access to those, on purpose.
> but these feel wrong
>
> Any pointers, how to move this forward?
>
> Best regards,
> Peter
>
> On 2025. 06. 14. 21:23, Branko Čibej wrote:
>> Hi all,
>>
>> I've been digging into Serf's support for various authentication
>> schemes and I notices something that looks like a bit of a limitation.
>>
>> Unless I'm much mistaken, there's space for only one authentication
>> baton in Serf's context. It would seem that this is rather a blocker
>> for implementing multi-factor authentication flows, for example,
>> Basic + OTP, where the server would first require basic credentials
>> and then, if those were correct, go on to issue an OTP challenge.
>>
>> It seems to me that a simple solution for that would be to store an
>> authn baton per scheme, but I know on the close order of nothing
>> about the possible side effects.
>>
>> Yeah, I'm starting small, I have no wish to implement OAuth2 flow any
>> time soon. Still, a bit of insight from the knowledgeable would be
>> welcome.
>>
>> -- Brane
>>
Re: Thinking about MFA infrastructure
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
I think I've just run into this,
Here's the current flow:
1st request without auth gets a 401 response with WWW-Authenticate:
Digest header
2nd request sent with Authorization header gets a WWW-Authenticate: MFA
headaer
3rd request is sent with OTP, but this goes without Authorization: Digest
In my current implementation the user's password is rerequested, and
everything works fine after that, but I'm having trouble fixing this
I can probably add an auth method that does both Basic+OTP, but it'd
probably mean code duplication, or calling the Basic auth method
functions from the new method, but these feel wrong
Any pointers, how to move this forward?
Best regards,
Peter
On 2025. 06. 14. 21:23, Branko Čibej wrote:
> Hi all,
>
> I've been digging into Serf's support for various authentication
> schemes and I notices something that looks like a bit of a limitation.
>
> Unless I'm much mistaken, there's space for only one authentication
> baton in Serf's context. It would seem that this is rather a blocker
> for implementing multi-factor authentication flows, for example, Basic
> + OTP, where the server would first require basic credentials and
> then, if those were correct, go on to issue an OTP challenge.
>
> It seems to me that a simple solution for that would be to store an
> authn baton per scheme, but I know on the close order of nothing about
> the possible side effects.
>
> Yeah, I'm starting small, I have no wish to implement OAuth2 flow any
> time soon. Still, a bit of insight from the knowledgeable would be
> welcome.
>
> -- Brane
>