The example program uses internal APIs not present in the public header
file (krb5_gen_portaddr, krb5_gen_replay_name; the THIS IS UGLY part).
Are there alternatives part of the public API?
The issue here is that the example code has leaked outside of krb5 to
other projects, and it only builds there because current compilers still support implicit function declarations. I would like to give guidance
to the external users, but unfortunately I don't know anything about Kerberos.
"Simo" == Simo Sorce <simo@redhat.com> writes:
"Simo" == Simo Sorce <simo@redhat.com> writes:
Simo> Wherever possible you should recommend people use GSSAPI and
Simo> not krb5 APIs directly, unless they are building tools
Simo> specifically to manage aspects of krb5 (acquiring tickets,
Simo> managing ccaches, etc.)
I agree with the above.
I also think that the simple client referred to in the subject has a
bunch of anti-patterns.
As an example, I don't think it integrity protects or encrypts its
exchanges; I think it's too simple to actually be useful in today's
world.
That said, it looks like krb5_auth_con_genaddrs is probably the API you
want to use instead of krb5_gen_portaddr. It takes an auth context and
a socet FD and extracts addresses from the socket FD.
I suspect that the auth context machinery will generate the replay cache
name for you, and again, you don't need that API either.
But please use GSS-API instead:-)
"Florian" == Florian Weimer <fweimer@redhat.com> writes:
"Florian" == Florian Weimer <fweimer@redhat.com> writes:
Florian> * Sam Hartman:
>>>>>>> "Simo" == Simo Sorce <simo@redhat.com> writes:
>>
Simo> Wherever possible you should recommend people use GSSAPI and
Simo> not krb5 APIs directly, unless they are building tools
Simo> specifically to manage aspects of krb5 (acquiring tickets,
Simo> managing ccaches, etc.)
>>
>> I agree with the above. I also think that the simple client
>> referred to in the subject has a bunch of anti-patterns. As an
>> example, I don't think it integrity protects or encrypts its
>> exchanges; I think it's too simple to actually be useful in
>> today's world.
>>
>> That said, it looks like krb5_auth_con_genaddrs is probably the
>> API you want to use instead of krb5_gen_portaddr. It takes an
>> auth context and a socet FD and extracts addresses from the
>> socket FD.
>>
>> I suspect that the auth context machinery will generate the
>> replay cache name for you, and again, you don't need that API
>> either. But please use GSS-API instead:-)
Florian> I need to fix Authen::Krb5 (a Perl wrapper) not rely on
Florian> this krb5 internals. Obviously, this is going to stay a
Florian> krb5 wrapper, and won't switch to GSSAPI. So I'd really
Florian> appreciate if someone would fix the
Florian> appl/simple/client/sim_client.c example not to rely on
Florian> <k5-int.h>, so that I can apply the parallel changes to the
Florian> Perl port of this example code.
That code is not maintained, and I'd probably fix it with git rm.
If you'll point me at upstreams sources for authen::krb5 I'll take a
look and figure out a recommendation for whether delete or some sort of repair is best in that case.
If the code actually provides integrity and confidentiality protection
it is salvagable. Otherwise it is probably worth deleting. ________________________________________________
Kerberos mailing list Kerberos@mit.edu https://mailman.mit.edu/mailman/listinfo/kerberos
I also think that the simple client referred to in the subject has a
bunch of anti-patterns.
As an example, I don't think it integrity protects or encrypts its
exchanges
Yeah, by portable I meant I just compile the parts of krb5 client code I
need when necessary. The krb5 client is very portable and fairly small. I strip out some stuff I don’t use, but not too much.
Chris
On Fri, Feb 24, 2023 at 11:51 Ken Hornstein <kenh@cmf.nrl.navy.mil> wrote:
I have said this before on the list and it’s not a very popular thing to >> >say, but I program to the krb5 public API, and it is a nice and clean and >> >performant and simple and portable and flexible API, and GSSAPI lookslike
none of those things, it looks like a mess to use (just from looking atit
for my needs, I have never programmed with it). So, I hope there isn’t >> >some movement to deprecate the lowlevel public krb5 API, because it isvery
useful for me at least.
Dude, you are NOT the only one who feels that way, and I can't even
BELIEVE people argue otherwise! Yes, the GSSAPI is a mess; there is
no getting around it. The krb5 API is about 100x simpler (there are
more functions, true, but most of the time you only need a handful
of them). I've used both; there's just no comparison. I understand
why the GSSAPI was created and the point of it and I use it when I
feel it is appropriate; I understand why it is specified in protocol
standards. But in the service of making it "generic" it ended up being
very complicated. And if you want to have your protocol only require a
single round trip, you're stuck either calling the krb5 API directly OR
assuming that your GSSAPI mechanism will complete in a single round trip
(the latter is what Microsoft chose for their GSSAPI HTTP protocol),
which in my mind kind of negates the "g" in GSSAPI.
However, one thing is worth mentioning: in my experience the GSSAPI
is portable. The details of the krb5 API are basically tied to the
particular Kerberos implementation you're using, and that means you're
stuck either with a lot of compatibility code OR you have to compile
your preferred Kerberos implementation for your target platform, which
presents it's own issues. If I want a truly portable application then I
do use the GSSAPI.
--Ken
I have said this before on the list and it’s not a very popular thing to >say, but I program to the krb5 public API, and it is a nice and clean and >performant and simple and portable and flexible API, and GSSAPI looks like >none of those things, it looks like a mess to use (just from looking at it >for my needs, I have never programmed with it). So, I hope there isn’t >some movement to deprecate the lowlevel public krb5 API, because it is very >useful for me at least.
I have said this before on the list and it’s not a very popular thing to >say, but I program to the krb5 public API, and it is a nice and clean and >performant and simple and portable and flexible API, and GSSAPI looks like >none of those things, it looks like a mess to use (just from looking at it >for my needs, I have never programmed with it). So, I hope there isn’t >some movement to deprecate the lowlevel public krb5 API, because it isvery
useful for me at least.
Dude, you are NOT the only one who feels that way, and I can't even
BELIEVE people argue otherwise! Yes, the GSSAPI is a mess; there is
no getting around it. The krb5 API is about 100x simpler (there are
more functions, true, but most of the time you only need a handful
of them). I've used both; there's just no comparison. I understand
why the GSSAPI was created and the point of it and I use it when I
feel it is appropriate; I understand why it is specified in protocol standards. But in the service of making it "generic" it ended up being
very complicated. And if you want to have your protocol only require a single round trip, you're stuck either calling the krb5 API directly OR assuming that your GSSAPI mechanism will complete in a single round trip
(the latter is what Microsoft chose for their GSSAPI HTTP protocol),
which in my mind kind of negates the "g" in GSSAPI.
However, one thing is worth mentioning: in my experience the GSSAPI
is portable. The details of the krb5 API are basically tied to the particular Kerberos implementation you're using, and that means you're
stuck either with a lot of compatibility code OR you have to compile
your preferred Kerberos implementation for your target platform, which presents it's own issues. If I want a truly portable application then I
do use the GSSAPI.
--Ken
"Florian" == Florian Weimer <fweimer@redhat.com> writes:
Florian> * Sam Hartman:
>>>>>>> "Simo" == Simo Sorce <simo@redhat.com> writes:
>>
Simo> Wherever possible you should recommend people use GSSAPI and
Simo> not krb5 APIs directly, unless they are building tools
Simo> specifically to manage aspects of krb5 (acquiring tickets,
Simo> managing ccaches, etc.)
>>
>> I agree with the above. I also think that the simple client
>> referred to in the subject has a bunch of anti-patterns. As an
>> example, I don't think it integrity protects or encrypts its
>> exchanges; I think it's too simple to actually be useful in
>> today's world.
>>
>> That said, it looks like krb5_auth_con_genaddrs is probably the
>> API you want to use instead of krb5_gen_portaddr. It takes an
>> auth context and a socet FD and extracts addresses from the
>> socket FD.
>>
>> I suspect that the auth context machinery will generate the
>> replay cache name for you, and again, you don't need that API
>> either. But please use GSS-API instead:-)
Florian> I need to fix Authen::Krb5 (a Perl wrapper) not rely on
Florian> this krb5 internals. Obviously, this is going to stay a
Florian> krb5 wrapper, and won't switch to GSSAPI. So I'd really
Florian> appreciate if someone would fix the
Florian> appl/simple/client/sim_client.c example not to rely on
Florian> <k5-int.h>, so that I can apply the parallel changes to the
Florian> Perl port of this example code.
That code is not maintained, and I'd probably fix it with git rm.
If you'll point me at upstreams sources for authen::krb5 I'll take a
look and figure out a recommendation for whether delete or some sort of repair is best in that case.
I guess if I’m on a tear saying forbidden things, sometimes identity is all
you need, you don’t want all the samples to encrypt everything, because >that makes it look like you have to, which you don’t? It is use-case >dependent, and krb5 is great because it is granular enough to let >developers choose what they do for their own use-cases.
I'd like to push back on THIS a bit.
While I agree that you don't ALWAYS need to encrypt everything, I would
argue that in 2023 you should to encrypt everything 99% of the time, and
the 1% you don't you should think about very carefully. And having the samples encrypt stuff would be helpful as examples (and to take later
further point, the breakdown between sample/simple always confuses me as well).
--Ken
I guess if I’m on a tear saying forbidden things, sometimes identity is all >you need, you don’t want all the samples to encrypt everything, because >that makes it look like you have to, which you don’t? It is use-case >dependent, and krb5 is great because it is granular enough to let
developers choose what they do for their own use-cases.
"Chris" == Chris Hecker <checker@d6.com> writes:
I have said this before on the list and it’s not a very popular thing to >say, but I program to the krb5 public API, and it is a nice and clean and >performant and simple and portable and flexible API, and GSSAPI looks like >none of those things, it looks like a mess to use (just from looking at it >for my needs, I have never programmed with it). So, I hope there isn’t >some movement to deprecate the lowlevel public krb5 API, because it is very >useful for me at least.
Dude, you are NOT the only one who feels that way, and I can't even
BELIEVE people argue otherwise! Yes, the GSSAPI is a mess; there is
no getting around it. The krb5 API is about 100x simpler (there are
more functions, true, but most of the time you only need a handful
of them). I've used both; there's just no comparison. I understand
why the GSSAPI was created and the point of it and I use it when I
feel it is appropriate; I understand why it is specified in protocol standards. But in the service of making it "generic" it ended up being
very complicated. And if you want to have your protocol only require a single round trip, you're stuck either calling the krb5 API directly OR assuming that your GSSAPI mechanism will complete in a single round trip
(the latter is what Microsoft chose for their GSSAPI HTTP protocol),
which in my mind kind of negates the "g" in GSSAPI.
However, one thing is worth mentioning: in my experience the GSSAPI
is portable. The details of the krb5 API are basically tied to the particular Kerberos implementation you're using, and that means you're
stuck either with a lot of compatibility code OR you have to compile
your preferred Kerberos implementation for your target platform, which presents it's own issues. If I want a truly portable application then I
do use the GSSAPI.
"Florian" == Florian Weimer <fweimer@redhat.com> writes:
It has been a long time since I made this evaluation so I don’t remember the details, but I definitely do all sorts of stuff with ccaches and
keytabs and profiles and threads and static linking and controlling memory allocations and controlling sockets and file usage and whatnot, it seemed like GSSAPI would have been a nightmare. Also, the design of krb5 is
pretty clear, it is lowlevel, but everything is right there, it doesn’t try to hide much, which I value.
Anyway, if others prefer GSSAPI that’s fine with me, I just wanted speak up and say there are some of us who like calling krb5 and kadm.
If you're just trying to set up a GSS context between a client and a
server, then GSS is really simple, and much simpler than the krb5 API.
Nico Williams <nico@cryptonector.com> writes:
If you're just trying to set up a GSS context between a client and a server, then GSS is really simple, and much simpler than the krb5 API.
I'm very dubious about this statement. The requirement to handle
negotiation and potential multiple round trips and all the complexity with major and minor status codes makes the equivalent GSS code complicated and annoying.
GSS pays a significant price for being a generic mechanism with a
negotiation method, and the API does not hide that price from the
programmer.
On Fri, Feb 24, 2023 at 01:50:58PM -0500, Ken Hornstein via Kerberos wrote:
andI have said this before on the list and it’s not a very popular thing to >say, but I program to the krb5 public API, and it is a nice and clean
likeperformant and simple and portable and flexible API, and GSSAPI looks
itnone of those things, it looks like a mess to use (just from looking at
veryfor my needs, I have never programmed with it). So, I hope there isn’t >some movement to deprecate the lowlevel public krb5 API, because it is
useful for me at least.
If you're just trying to set up a GSS context between a client and a
server, then GSS is really simple, and much simpler than the krb5 API.
If you have to deal with where credentials are (what ccaches, etc.) or acquiring them, then historically you couldn't really do that with GSS,
bit now with the new gss_acquire_cred_from() and gss_store_cred_into() functions you can.
Dude, you are NOT the only one who feels that way, and I can't even
BELIEVE people argue otherwise! Yes, the GSSAPI is a mess; there is
no getting around it. The krb5 API is about 100x simpler (there are
more functions, true, but most of the time you only need a handful
of them). I've used both; there's just no comparison. I understand
why the GSSAPI was created and the point of it and I use it when I
feel it is appropriate; I understand why it is specified in protocol standards. But in the service of making it "generic" it ended up being very complicated. And if you want to have your protocol only require a single round trip, you're stuck either calling the krb5 API directly OR assuming that your GSSAPI mechanism will complete in a single round trip (the latter is what Microsoft chose for their GSSAPI HTTP protocol),
which in my mind kind of negates the "g" in GSSAPI.
The krb5 API is a mess too. And API compatibility between Heimdal and
MIT isn't complete.
With GSS though, with the new gss_acquire_cred_from() and gss_store_cred_into(), I find there's very little need for krb5 APIs.
For example, in a PR to Heimdal I've a GSS-based equivalent of kinit
that has practically the same functionality as the Heimdal kinit
command. The only thing it doesn't have is the ability to let the KDC
drive prompting, though I think I could do something about that too by encoding the necessary information into minor status codes.
However, one thing is worth mentioning: in my experience the GSSAPI
is portable. The details of the krb5 API are basically tied to the particular Kerberos implementation you're using, and that means you're stuck either with a lot of compatibility code OR you have to compile
your preferred Kerberos implementation for your target platform, which presents it's own issues. If I want a truly portable application then I
do use the GSSAPI.
Basically.
Nico
--
On Fri, Feb 24, 2023 at 12:19:53PM -0800, Russ Allbery wrote:
Nico Williams <nico@cryptonector.com> writes:
If you're just trying to set up a GSS context between a client and a server, then GSS is really simple, and much simpler than the krb5 API.
I'm very dubious about this statement. The requirement to handle negotiation and potential multiple round trips and all the complexity with major and minor status codes makes the equivalent GSS code complicated and annoying.
RFC 7546 exists.
If you're using SPNEGO then you don't have to concern yourself with >negotiation. If you're implementing SSHv2 or SASL it's another story,
though not much more complicated because you're doing negotiation at a
layer that already does it and all you have to do is maybe pick a GSS >mechanism.
RFC 7546 exists.
I've written a fair amount of app code using krb5 and GSS APIs, and I >strongly prefer GSS code.
GSS does have some ugly things, mainly OIDs, but also not having
something like a krb5_context. Regarding not having a krb5_context,
I've played with a couple of ways to fix that in Heimdal: either a)
enhancing the `OM_uint32 *minor_status` to be a more complex, opaque
object, or b) adding configuration key/value parameters to the
`cred_store` used in `gss_acquire_cred_from()`.
RFC 7546 exists.
And https://github.com/kaduk/gssdoc/blob/master/gss-sample.c has the un-processed version of the sample code from the RFC; I did compile and run it during development of the RFC.
I can't argue your preference, and I'll be the first to admit that
"simpler" can be subjective (although I would argue one metric, "lines
of code", the krb5 API would win). But let me point out a few things:
- I alluded to this on the kitten list (and I know you replied there
but I didn't get to reply to it yet), but the issue of multiple round
trips is a concern. You point out that even with SPNEGO you should
have a single round trip most of the time and that's a fair point,
but this puts you in a tough spot with the usage of GSS; you have to
assume your GSS mechanism is a single-trip and violate the API OR
complicate your protocol and implementation design and presume an
unspecified number of round trips. At least with the krb5 API you can
definitively design the protocol (and implementation) for a single
round trip.
- I don't want to crap over the work Ben did on RFC 7546, but I couldn't
help noticing that he skipped over the vital work of extracting out
a useful error message out of the GSSAPI; that code alone is always
a mess but you'd need it anything you'd use in production.
GSS does have some ugly things, mainly OIDs, but also not having
something like a krb5_context. Regarding not having a krb5_context,
I've played with a couple of ways to fix that in Heimdal: either a) >enhancing the `OM_uint32 *minor_status` to be a more complex, opaque >object, or b) adding configuration key/value parameters to the
`cred_store` used in `gss_acquire_cred_from()`.
I was under the impression the "context_handle" served that purpose,
although I realize not everything takes that as an argument. If it
doesn't serve that purpose then I understand the GSSAPI even less than I thought :-/
I recognize that the issue of krb5 API vs GSS is something that we're
just never going to agree on.
RFC 7546 exists.
I've written a fair amount of app code using krb5 and GSS APIs, and I strongly prefer GSS code.
It does pay a price, but if all you need is encrypted sessions, then
it's simple.
As an alternative to the krb5 api, stick in the krb5 mechanism oid.
You can definitively design your protocol and implementation for a
single round trip by doing that.
You can have more code in common with applications that do support >multi-round-trip negotiations, while still getting your half or one
round trip.
I use GSSAPI for new code because it is a *better* API (or, more
precisely, a better *protocol*) that fixes various underlying issues and
has better defaults. But it is not *simpler*; quite the opposite, it's
more tedious and annoying and weird, harder to debug because of the imposition of the generic layer that has a tendency to get in the way of understanding what's going on, and requires you think about both Kerberos
and GSS concepts at the same time when implementing a non-trivial
application instead of focusing only on Kerberos.
Just to take another example, GSSAPI introduces yet another identity
format and now you have to be aware of both the Kerberos identity and the
GSS identity, which are sort of the same but not always.
Which is why, for a new mechanism, I would much prefer that it support Kerberos naming. Certainly I don't ever want to see a mechanism use
x.500 style naming again.
"Ken" == Ken Hornstein via Kerberos <kerberos@mit.edu> writes:
(There is the other problem that all of the effort, hardware support, and optimization work is going into TLS now, and it feels like a huge waste of energy to try to compete with TLS in the secure transport business. But that's a whole different can of worms since TLS is very wedded to X.509 certificates and there are a bunch of very good reasons to not want to use X.509 certificates for client authentication in a lot of situations.)
Primarily what I'd want in a new mechanism is for it to be a protocol for Kerberos authentication. (Or some other underlying authentication system that we all use instead, although that would be off-topic for this group.)
In other words, not generic. I understand why GSSAPI was made generic,
but that's not what I want, and I think the security world is starting to realize that being able to negotiate every security property and mechanism
is more of a bug than a feature.
Right now, it is possible to get into the truly absurd situation where to authenticate a client to a server you use:
* HTTP authentication, to negotiate
* SPNEGO, to negotiate
* GSASPI, to negotiate
* Kerberos, to do the actual authentication
Something similar happens with SASL. This is three layers of negotiation
too many. [...]
I understand the need for *a* negotiation layer. I think the error was in accepting additional negotiation layers below that, as opposed to getting
out of the generic mode as quickly as possible and start working directly with the true protocol.
Essentially everything that I don't like about GSSAPI is a direct
consequence of the fact that it's a generic authentication protocol that
in theory (although essentially never in practice outside of toys and
science experiments) could negotiate a mechanism other than Kerberos. Supporting that generality forces the addition of irreducible complexity
to the API.
(There is the other problem that all of the effort, hardware support, and optimization work is going into TLS now, and it feels like a huge waste of energy to try to compete with TLS in the secure transport business. But that's a whole different can of worms since TLS is very wedded to X.509 certificates and there are a bunch of very good reasons to not want to use X.509 certificates for client authentication in a lot of situations.)
On Fri, 2023-02-24 at 16:27 -0800, Russ Allbery wrote:
Essentially everything that I don't like about GSSAPI is a direct
consequence of the fact that it's a generic authentication protocol
that in theory (although essentially never in practice outside of toys
and science experiments) could negotiate a mechanism other than
Kerberos. Supporting that generality forces the addition of
irreducible complexity to the API.
Sorry Russ,
I do not know about toys or science experiments, but I have been using
GSSAPI in real HTTP applications to do either NTLM or Krb5 just fine.
And before that in SMB applications (although Samba is more complicated because of its history).
Essentially everything that I don't like about GSSAPI is a direct
consequence of the fact that it's a generic authentication protocol that
in theory (although essentially never in practice outside of toys and
science experiments) could negotiate a mechanism other than Kerberos. Supporting that generality forces the addition of irreducible complexity
to the API.
I need to fix Authen::Krb5 (a Perl wrapper) not rely on this krb5
internals. Obviously, this is going to stay a krb5 wrapper, and won't
switch to GSSAPI. So I'd really appreciate if someone would fix the appl/simple/client/sim_client.c example not to rely on <k5-int.h>, so
that I can apply the parallel changes to the Perl port of this example
code.
My basic point is that I understand the need to first negotiate a security mechanism and then use that security mechanism, but I don't like the
layering of multiple negotiation mechanisms, so I'm not a big fan of SASL
and GSSAPI/SPNEGO being separate and HTTP using yet another negotiation protocol via WWW-Authenticate headers, although I understand why this happened.
Ideally, I'd like to have three concepts: a negotiation protocol, a
security protocol for Kerberos, and an encoding layer for both of those protocols into the application protocol (HTTP, IMAP, whatever) that deals with problems like how to put this into valid HTTP requests. I feel like
we've collectively taken multiple shots at this over the years and we keep getting closer, but we keep ending up with the divisions between the
layers being murky and having multiple negotiation layers, and that in
turn makes the code more complicated. And this is probably a pipe dream
at this point, since all this stuff is very baked into long-standing protocols that are unlikely to change significantly.
More actionably, for a lot of applications I think there's some merit in dispensing with the negitiation layer and having one single supported security mechanism and that's it. This was the idea behind Wireguard, and
I think it's an interesting model. This isn't suitable for IMAP or HTTP
or whatnot for obvious reasons, but it adds a lot of simplicity when one knows what security mechanism is in play because the (often private)
protocol only supports a single one and can just use it directly. And
this is what becomes impossible when GSSAPI is the only recommended way of using Kerberos, because then you can't get rid of the generic layer of the API even if you don't need it, so you're stuck with having multiple
identity concepts, etc. (I do understand all of the other problems with
the raw Kerberos API, though, and I'm not saying it should be used
instead. The API that I actually want doesn't exist, I think.)
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 300 |
Nodes: | 16 (2 / 14) |
Uptime: | 08:55:36 |
Calls: | 6,706 |
Files: | 12,236 |
Messages: | 5,350,772 |