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

Wang Weijun weijun.wang at oracle.com
Tue Apr 19 10:50:03 UTC 2016

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.

MIT and SSPI support referral so the names can be different.

The workaround you described is the only solution by now.


> 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(CredentialsUtil.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