JGSS fails with KrbException: Message stream modified (41) on cross-realm intermediate/unexpected TGT

Osipov, Michael michael.osipov at siemens.com
Tue Apr 19 11:06:53 UTC 2016


Hi Max,

> If you are sure the exception is thrown from the code snippet you quoted,
> that is because Java's Kerberos 5 implementation requires that the service
> name in TGS_REP must match the one in the TGS_REQ. Otherwise it fails.

I am quite certain, I have attached the OpenJDK code in Eclipse an stepped
to this spot. It exactly happens and you say. It does not match.
 
> MIT and SSPI support referral so the names can be different.
> 
> The workaround you described is the only solution by now.

Are there any  plans to add referral support?
Can we log this issue in bugs.openjdk.java.net/browse/JDK?

As I have written, the workaround is feasible in few cases only.
Not having referral support makes JGSS hardly usable in a big enterprise
environment. Disappointing :-(

Anyway thanks for the quick response and confirmation of the issue.

Michael

> > On Apr 19, 2016, at 5:05 PM, Osipov, Michael
> <michael.osipov at siemens.com> wrote:
> >
> > Hi,
> >
> > I am trying to obtain a service ticket for a cross-realm service within
> one hierarchy (forest).
> >
> > The root realm is COMPANY.NET, my realm is R004.COMPANY.NET, target
> realm is R002.COMPANY.NET and
> > SPN ldap/server.r002.company.net.
> >
> > Host to realm mapping in my krb5.conf:
> > [domain_realm]
> >    .r004.company.net = R004.COMPANY.NET
> >    r004.company.net = R004.COMPANY.NET
> >    .company.net = COMPANY.NET
> >    company.net = COMPANY.NET
> >
> > I have tested the same case with MIT Kerberos and SSPI and both have a
> completely different approach
> > of requesting service tickets. They do:
> >
> > TGS-REQ for ldap/server.r002.company.net to a KDC in my home realm
> > TGS-REP is krbtgt/r002.company.net at R004.COMPANY.NET
> > TGS-REQ for ldap/server.r002.company.net to a KDC in R002.COMPANY.NET
> with
> > 	  krbtgt/r002.company.net at R004.COMPANY.NET
> > TGS-REP is ldap/server.r002.company.net at WW002.SIEMENS.NET
> >
> > This works as desired.
> >
> > JGSS in turn does this:
> > Match hostname to domain realm => COMPANY.NET
> > TGS-REQ for krbtgt/COMPANY.NET
> > TGS-REP is krbtgt/company.net at R004.COMPANY.NET
> > TGS-REQ for ldap/server.r002.company.net to a KDC in COMPANY.NET with
> > 	  krbtgt/company.net at R004.COMPANY.NET
> > TGS-REP is krbtgt/r002.company.net at COMPANY.NET
> > and here happens the crash
> > KrbException: Message stream modified (41)
> > KrbException: Fail to create credential. (63) - No service creds
> > 	at
> sun.security.krb5.internal.CredentialsUtil.acquireServiceCreds(Credentials
> Util.java:299)
> > 	at
> sun.security.krb5.Credentials.acquireServiceCreds(Credentials.java:454)
> > 	at
> sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:641)
> > 	at
> sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:248)
> > 	at
> sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
> > in KrbKdcRep.java#check(), lines 54 to 56:
> > 	if (!req.reqBody.sname.equalsWithoutRealm(rep.encKDCRepPart.sname))
> {
> > 		rep.encKDCRepPart.key.destroy();
> > 		throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
> > 	}
> >
> > This code assumes that the ticket is already the final service ticket
> but it is an intermediate TGT
> > for the target realm. I would expect another TGS-REQ/TGS-REP from JGSS.
> Due to the logic implemented,
> > the only known workaround is to add another [domain_realm] mapping but
> this is daunting because we have
> > tens of those and I do not know all realms/hostnames upfront due to
> dynamic TGT referrals.
> >
> > Another case is HTTP proxy (HTTP/proxyfarm.company.net). JGSS requests
> at COMPANY.NET but
> > receives a TGT for R002.COMPANY.NET. Especially in this case, I am not
> able to know the realm upfront.
> > Adding the domain realm mapping does not help because this file is used
> initially only or even worse,
> > direct hostname to realm mapping is hell. Removing [domain_realm] makes
> it immediately fail due to
> > the TGT referral. MIT Kerberos follows all TGT referrals as necessary.
> >
> > The manpage for krb5.conf for [domain_realm] says:
> > "If no translation entry applies to a hostname used for a service
> principal for a service ticket request,
> > the library will try to get a referral to the appropriate realm from the
> client realm's KDC..."
> >
> > I would expect that the TGS logic would resemble the one described
> above, follow all referrals until
> > it gets the desired service ticket. Ultimately, not [domain_realm] is
> necessary, at least with MIT Kerberos
> > and Active Directory.
> >
> > Setup:
> > * KDCs are Windows Server 2008/2012
> > * Clients are Windows 7 Enterprise
> > * MIT Kerberos 1.14.1 on FreeBSD
> > * Oracle JDKs 1.7.0_72 and 1.80_72
> >
> > All tests happen on Windows, deployment happens on HP-UX with HP JVM
> which is merely a repackaged Oracle
> > JVM with native patches for that OS.
> >
> > I have already created a bundle with log files, krb5.conf and Wireshark
> pcap files, debug screenshots for
> > JGSS, MIT Kerberos and SSPI and will happily share in private. Also
> willing to assist as necessary.
> >
> > This is actually an annoying blocker disabling us to use cross-domain
> and cross-forest services. I would
> > prefer a solution for Java 7 because we haven't migrated to Java 8 yet
> but willing to do so.
> >
> > How can we resolve this issue?
> >
> > Thanks and regards,
> >
> > Michael Osipov
> >



More information about the security-dev mailing list