Hello!

On 31.07.2025 18:36, Cy Schubert wrote:
In message <20250731152803.19f9...@slippy.cwsent.com>, Cy Schubert writes:
In message <CAM5tNy4XupPGXHMS0p0TK0Wf_zAg5bsOzx4C1K1e-_2b=3eyUw@mail.gmail.c
om>
, Rick Macklem writes:
On Thu, Jul 31, 2025 at 6:51=E2=80=AFAM Rick Macklem <rick.mack...@gmail.co
=
m> wrote:

On Thu, Jul 31, 2025 at 6:07=E2=80=AFAM Rick Macklem <rick.macklem@gmail.
=
com> wrote:

On Wed, Jul 30, 2025 at 9:24=E2=80=AFPM Benjamin Kaduk <bjkfbsd@gmail.c
=
om> wrote:

On Wed, Jul 30, 2025 at 10:36=E2=80=AFAM Rick Macklem <rick.macklem@g
=
mail.com> wrote:

On Mon, Jul 28, 2025 at 3:32=E2=80=AFPM Benjamin Kaduk <bjkfbsd@gmai
=
l.com> wrote:

On Mon, Jul 28, 2025 at 3:04=E2=80=AFPM Benjamin Kaduk <bjkfbsd@gm
=
ail.com> wrote:


Note that MIT krb5 provides the gss_krb5_export_lucid_sec_context
=
() API that does a lot of the work of getting useful bits out of an establi
=
shed GSS security context.





And a bit more context on what is going on here and why kgssapi ha
=
s to care:
The GSS-API (RFC 2743) is all about a way to "establish a security
=
  context" (i.e., do crypto negotiation, authentication, sometimes authoriza
=
tion, etc.) between two entities, the initiator and the acceprot, and then
=
exchanging protected messages between the two (which can be either encrypte
=
d or just integrity protection tags for otherweise cleartext data); later e
=
xtensions included the ability to produce identical PRF output on both part
=
ies, etc..  The details are "mechanism-specific", and for this purpose we'r
=
e exclusively talking about the krb5 mechanism.  The steps to establish the
=
  security context are complicated and sometimes fiddly, and in the general
=
case can require a large number of round-trips between the initiator and ac
=
ceptor before the security context is established.  The individual message-
=
protection parts are comparatively simple and amendable to implementation i
=
n the kernel for processing efficiency.
RFC 2743 also defines functions for GSS_Export_sec_context() and G
=
SS_Import_sec_context(), that are designed essentially to pass information
=
about an established security context from one process to another on the sa
=
me machine (which are presumably using the same implementation and version
=
of the implementation), so the contents of the exported blob are opaque and
=
  implementation-specific.  We are abusing that mechanism to export informat
=
ion about the security context that gssd has established and feed that info
=
rmation into the kernel implementation of the per-message processing routin
=
es.  At present, this necessarily entails knowing the details of the implem
=
entation-specific opaque blob that is the "export sec context token", which
=
  is what the sys/kgssapi/krb5/krb5_mech.c code is doing.  But if we can get
=
  the information we want without breaking the abstraction barrier, such as
=
via the gss_krb5_export_lucid_sec_context() API, we are in a more robust po
=
sture overall and somewhat future-proofed against future evolution by MIT k
=
rb5.
(I note that recent Heimdal versions seem to also expose a gss_krb
=
5_export_lucid_sec_context() API, so part of the problem is just that the H
=
eimdal in base is so old.)

Well, here's some "not so good" news...
I've been trying to use gss_inquire_sec_context_by_oid(..) with the
=
oid
for the GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID with version 1.
It kept failing.
The problem seems to be that "gctx->proto =3D=3D 4" in make_external
=
_lucid_ctx_v1()
function. This function only knows about the 0 and 1 setting for gct
=
x->proto.

Any ideas, rick



I'm not seeing anything to suggest that a "gctx->proto" value of 4 is
=
  ever expected; it looks like it's supposed to just be 0 (for the legacy RF
=
C 1964 format) or 1 (for the "CFX" format of RFC 4121, with wider sequence
=
numbers for message-protection formats, etc.).  So maybe it's worth posting
=
  your current WIP somewhere to take a closer look at what's going on.

Yea, the debugging I did was flawed (I probably got the wrong offset
in the structure).
It is weird, though. If I do gss_inquire_sec_context_by_oid(&minor, ctx
=
,
OID_FOR_GSS_INQUIRE_SSPI_SESSION_KEY, &key), it
works and gives me the key and encryption type.

If I do the same, but with the 12 byte OID for LUCID v1 (the 11 bytes f
=
rom the
string + a 1 byte), it returns major =3D=3D GSS_S_COMPLETE, but no data
=
  and
a weird 39756046(decimal) or 0x25ea10e(hex) minor.
(Oh, and I tried gss_krb5_export_lucid_sec_context() and got the same
weird error.)
--> Now (after doing a "make buildworld"), gss_krb5_export_lucid_sec_cont
=
ext()
      returns GSS_S_BAD_MECH. Looking at the src, that error has to be fro
=
m
      gss_inquire_sec_context_by_oid(). So, same function fails, but a dif
=
ferent
      error return?

It looks like "gssint_get_mechanism (ctx->mech_type)" is failing.
I'm currently just passing GSS_C_NULL_OID into gss_init_sec_context(),
but I've also tried the Kerberos 9 byte OID (both work, in the sense that
gss_init_sec_context() seems to work, except that the actual_mech_type
returned by it has a bogus pointer in the reply).
--> It looks like the "mech_type" field of "ctx" is busted, for some reas
=
on?

I'm going to try building krb5 from ports and linking to that, to see if
=
it
does the same thing.
Finally some good news...
All I did was "pkg install krb5" and then linked the gssd to the libraries
=
in
/usr/local/lib and it worked!!

gssapi/gssapi.h from krb5/lib/gssapi/generic is overwritten by our
lib/libgssapi. As we have two the MIT gssapi.h is put in
/usr/include/gssapi_krb5/gssapi.h.

This patch should fix the problem. I haven't tested this yet.

diff --git a/usr.sbin/gssd/Makefile b/usr.sbin/gssd/Makefile
index 569e2c7e18f5..4c9d342c48c3 100644
--- a/usr.sbin/gssd/Makefile
+++ b/usr.sbin/gssd/Makefile
@@ -14,7 +14,7 @@ LIBADD=       gssapi
  .if ${MK_MITKRB5} != "no"
  # MIT KRB5
  LIBADD+=      krb5 k5crypto krb5profile krb5support
-CFLAGS+= -DMK_MITKRB5=yes
+CFLAGS+= -DMK_MITKRB5=yes -Iinclude/gssapi_krb5
  .else
  # Heimdal
  LIBADD+=      krb5 roken



Now I can test/debug the changes.

Btw, the stuff in /usr/local/include/gssapi are correct and not messed up
like the stuff in /usr/include/gssapi. (The ones in /usr/local/include defi
=
ne
GSS_DLLIMP for example.)

I'm going to leave figuring out why the libraries in /usr/lib are messed up
to someone else.

rick


I had explained this to Lexi private moments ago.

It's not that. gssapi.h is installed by lib/libgssapi, the gssapi
forwarder. Heimdal had no gssapi.h whereas MIT KRB5 does. I put the MIT
gssapi.h in /usr/include/gssapi_krb5 for apps that might need it.

And this leads to the mess due to rest of includes in /usr/include/gssapi comes 
from MIT and relying on gsspai.h from MIT too but it hidded by separated prefix 
and not hooked up by default.
Great example of messing comes from evolution-data-server (or from any other consumer of #include <gssapi/gssapi_ext.h> or #include <gssapi/gssapi_generic.h> due to both want #include <gssapi/gssapi.h>):

In file included from 
/wrkdirs/usr/ports/databases/evolution-data-server/work/evolution-data-server-3.56.2/src/camel/camel-sasl-gssapi.c:59:
/usr/include/gssapi/gssapi_generic.h:50:1: error: unknown type name 'GSS_DLLIMP'
   50 | GSS_DLLIMP extern gss_OID gss_nt_user_name;
      | ^
/usr/include/gssapi/gssapi_generic.h:50:26: error: expected ';' after top level 
declarator
   50 | GSS_DLLIMP extern gss_OID gss_nt_user_name;
      |                          ^
/usr/include/gssapi/gssapi_generic.h:51:1: error: unknown type name 'GSS_DLLIMP'
   51 | GSS_DLLIMP extern gss_OID gss_nt_machine_uid_name;
      | ^
/usr/include/gssapi/gssapi_generic.h:51:26: error: expected ';' after top level 
declarator
   51 | GSS_DLLIMP extern gss_OID gss_nt_machine_uid_name;
      |                          ^
/usr/include/gssapi/gssapi_generic.h:52:1: error: unknown type name 'GSS_DLLIMP'
   52 | GSS_DLLIMP extern gss_OID gss_nt_string_uid_name;
      | ^
/usr/include/gssapi/gssapi_generic.h:52:26: error: expected ';' after top level 
declarator
   52 | GSS_DLLIMP extern gss_OID gss_nt_string_uid_name;
      |                          ^
/usr/include/gssapi/gssapi_generic.h:54:1: error: unknown type name 'GSS_DLLIMP'
   54 | GSS_DLLIMP extern gss_OID gss_nt_service_name;
      | ^
/usr/include/gssapi/gssapi_generic.h:54:26: error: expected ';' after top level 
declarator
   54 | GSS_DLLIMP extern gss_OID gss_nt_service_name;
      |                          ^
8 errors generated.

Best way is install MIT's one gssapi.h alongside with other mit header under 
/include/gssapi/ and move libgssapi's one under own prefix as you previously 
did for mit one.



This was not a problem because Heimdal never had a gssapi.h while with MIT
there is a conflict. Removing lib/libgssapi or its gssapi.h is not an
option because it's a gssapi forwarder. This was the compromise I settled
on.



--
Sincerely,
Dima (flu...@freebsd.org, https://t.me/FluffyBSD, 
@fluffy:matrix-dev.freebsd.org)
(desktop, kde, x11, office, ports-secteam)@FreeBSD team

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to