Target realm gets overwritten

Alibek Jorajev <[email protected]> Fri, 10 Aug 2018 20:01:48 +0000 (UTC)
Newsgroups gmane.comp.encryption.kerberos.heimdal.general
Message-ID <[email protected]>
------=_Part_5833980_1333071435.1533931308182
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable


hi !

I am using KRB5 API to fetch TGT and then GSS API to generate negotiate tok=
ens.
(then I add these tokens into HTTP headers when needed). I am using Heimdal=
 v. 1.4.

This works in all cases, but in one specific scenario,

Scenario (I just made up names):

- Client ([email protected]) obtains TGT from KDC1:=C2=A0=C2=A0 krbtgt/KDC1=
[email protected]

- Client obtains a cross-realm ticket-granting ticket: krbtgt/EAST.TESTNET.=
[email protected]

- Client obtains service ticket:=C2=A0 HTTP/[email protected]=
STNET.NET

This works, but next time I call GSS API,=C2=A0 cached service tickets are =
ignored
and for each and every resource a new service ticket is obtained (thus floo=
ding KDC server and also filling up local client's cache).


After debugging and code reading, I have established the root cause:=20

1. new requests are done because "check_cc" function (in check_cc.c file) i=
s given a wrong server name:=20

check_cc(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5=
_creds *in_creds, krb5_creds *out_creds)=20
gets this "HTTP/[email protected]" instead of "HTTP/proxy=
[email protected]"


2.=C2=A0 "in_creds->server->realm" gets overridden in import_name.c file, i=
n function _gsskrb5_canon_name:

When gsskrb5_get_creds calls _gsskrb5_canon_name function, it passes correc=
t creds with "EAST.TESTNET.NET" as a realm.=20
but here, in this place:


=C2=A0=C2=A0=C2=A0 /* If its not a hostname */
=C2=A0=C2=A0=C2=A0 if (krb5_principal_get_type(context, p) !=3D MAGIC_HOSTB=
ASED_NAME_TYPE) {
=C2=A0=C2=A0 =C2=A0ret =3D krb5_copy_principal(context, p, out);
=C2=A0=C2=A0=C2=A0 } else if (!use_dns) {
=C2=A0=C2=A0 =C2=A0ret =3D krb5_copy_principal(context, p, out);
=C2=A0=C2=A0 =C2=A0if (ret)
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 goto out;
=C2=A0=C2=A0 =C2=A0krb5_principal_set_type(context, *out, KRB5_NT_SRV_HST);
=C2=A0=C2=A0 =C2=A0if (sourcename)
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 ret =3D krb5_principal_set_realm(cont=
ext, *out, sourcename->realm);
=C2=A0=C2=A0=C2=A0 } else {
=C2=A0=C2=A0=C2=A0=C2=A0 .......

"sourcename" is client principal ("[email protected]") - in_creds cred's re=
alm is overwritten by one from "sourcename->realm"


this issue is present in Heimdal versions in 1.4.x and 1.5.x. From v.7.0 an=
d up, _gsskrb5_canon_name() has been reworked.=20
so it is not possible to simply backport changes.=20


is this normal?=C2=A0 if so, why we need to overwrite it?

regards,
Alibek
------=_Part_5833980_1333071435.1533931308182
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html><head></head><body><div style=3D"font-family:courier new, courier, mo=
naco, monospace, sans-serif;font-size:16px;"><div style=3D"font-family:cour=
ier new, courier, monaco, monospace, sans-serif;font-size:16px;"><span><br>=
hi !<br><br>I am using KRB5 API to fetch TGT and then GSS API to generate n=
egotiate tokens.<br>(then I add these tokens into HTTP headers when needed)=
. I am using Heimdal v. 1.4.<br><br>This works in all cases, but in one spe=
cific scenario,<br><br>Scenario (I just made up names):<br><br>- Client (us=
[email protected]) obtains TGT from KDC1:&nbsp;&nbsp; krbtgt/KDC1.SW.NET@KDC1=
.SW.NET<br><br>- Client obtains a cross-realm ticket-granting ticket: krbtg=
t/[email protected]<br><br>- Client obtains service ticket:&nbsp=
; HTTP/[email protected]<br><br>This works, but next=
 time I call GSS API,&nbsp; cached service tickets are ignored<br>and for e=
ach and every resource a new service ticket is obtained (thus flooding KDC =
server and also filling up local client's cache).<br><br><br>After debuggin=
g and code reading, I have established the root cause: <br><br>1. new reque=
sts are done because "check_cc" function (in check_cc.c file) is given a wr=
ong server name: <br><br>check_cc(krb5_context context, krb5_flags options,=
 krb5_ccache ccache, krb5_creds *in_creds, krb5_creds *out_creds) <br>gets =
this "HTTP/[email protected]" instead of "HTTP/proxy4.eas=
[email protected]"<br><br><br>2.&nbsp; "in_creds-&gt;server-&g=
t;realm" gets overridden in import_name.c file, in function _gsskrb5_canon_=
name:<br><br>When gsskrb5_get_creds calls _gsskrb5_canon_name function, it =
passes correct creds with "EAST.TESTNET.NET" as a realm. <br>but here, in t=
his place:<br><br><br>&nbsp;&nbsp;&nbsp; /* If its not a hostname */<br>&nb=
sp;&nbsp;&nbsp; if (krb5_principal_get_type(context, p) !=3D MAGIC_HOSTBASE=
D_NAME_TYPE) {<br>&nbsp;&nbsp; &nbsp;ret =3D krb5_copy_principal(context, p=
, out);<br>&nbsp;&nbsp;&nbsp; } else if (!use_dns) {<br>&nbsp;&nbsp; &nbsp;=
ret =3D krb5_copy_principal(context, p, out);<br>&nbsp;&nbsp; &nbsp;if (ret=
)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; goto out;<br>&nbsp;&nbsp; &nbsp;=
krb5_principal_set_type(context, *out, KRB5_NT_SRV_HST);<br>&nbsp;&nbsp; &n=
bsp;if (sourcename)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; ret =3D krb5_p=
rincipal_set_realm(context, *out, sourcename-&gt;realm);<br>&nbsp;&nbsp;&nb=
sp; } else {<br>&nbsp;&nbsp;&nbsp;&nbsp; .......<br><br>"sourcename" is cli=
ent principal ("[email protected]") - in_creds cred's realm is overwritten =
by one from "sourcename-&gt;realm"<br><br><br>this issue is present in Heim=
dal versions in 1.4.x and 1.5.x. From v.7.0 and up, _gsskrb5_canon_name() h=
as been reworked. <br>so it is not possible to simply backport changes. <br=
><br><br>is this normal?&nbsp; if so, why we need to overwrite it?<br><br>r=
egards,<br>Alibek</span></div></div></body></html>
------=_Part_5833980_1333071435.1533931308182--