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.
--Max
> 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