Mi Max,

looking at the commit, I see only this being relevant:
+        ReferralsState() throws KrbException {
+            if (Config.DISABLE_REFERRALS) {
+                if (cname.getNameType() == PrincipalName.KRB_NT_ENTERPRISE) {
+                    throw new KrbException("NT-ENTERPRISE principals only 
allowed" +
+                            " when referrals are enabled.");
+                }
+                enabled = false;
+            } else {
+                enabled = true;
+            }
+            refreshComm = true;
+        }

but I see no way to set cname with that name type.

Anyway, the change provided by Martin Balao is merely limited to the Kerberos mechanism and does no export any of those changes upto the JGSS interface.
I am excited to see these next steps.

My use case is the following: one upcoming application will require a change in authentication layers with two phases where phase two might or might not happen.

All changes happen on already existing code which works with Java for the last 8+ years and are freely available under ALv2.

Phase 1: A webapp (REST API) hosted on Tomcat shall support either optional certificate-based and/or mandatory SPNEGO-based authentication. With SPNEGO I get the GSS name from the context, with the OID KRB5_NT_PRINCIPAL: 1.2.840.113554.1.2.2.1. Windows always canonicalizes and all Unix servers have "canonicalize = true" set. With certificates we don't have a GSS name, but we use then SAN which contains SSL_CLIENT_SAN_Email_0 and SSL_CLIENT_SAN_OTHER_msUPN_0. We care for the UPN only which maps to AD's userPrincipalName attribute with the OID 1.3.6.1.4.1.311.20.2.3. Though, this OID does not exist in Kerberos space we can map it to KRB5_NT_ENTERPRISE_PRINCIPAL: 1.2.840.113554.1.2.2.6 because in AD it is the same value. Similar to he MS-PAC data .

With this GSS name which can be distinguished by OID I can feed Tomcat's Realm#authenticate(GSSName, GSSCredential) (in development by me [1]).
My realm impl ActiveDirectoryRealm will happily pass this GSS name to a
UsernameSearchMapper [2] which will tell the realm how to search for this principal. The OID-based support is not there yet, but is trivial to implement.

After all that I can easily locate the user in the tree and read out all AD attributes including security groups.

Without the KRB5_NT_ENTERPRISE_PRINCIPAL OID I cannot construct the GSS name from the cert and reuse it properly. As I have mentioned one can write a WrappedGSSName, but that's ugly.

Phase 2: reuse the supplied principal to use S4U2 which may or may not be used. So this is optional. The GSS name will be crucial here because when S4U2proxy will have the enterprise principal from the cert, it will fail with unsupported OID.

I would have to perform another AD search to construct the Kerberos principal or normalize in phase one to regular principals and throw away the enterprise principals which I don't want to do.

Side note: I still run on Java 8 and Java 11 won't happen that fast here. Cross-realm referrals were solved with krb5.conf in previous years. In AD terms, you can use enterprise principals w/o following referrals in my opinions if and only if the principal is in the same realm and the machine you are logged in.

Michael

[1] https://github.com/apache/tomcat/commit/6be96ebba4e7056d5c9621bada2c496f8c0a82d0 [2] http://tomcatspnegoad.sourceforge.net/xref/net/sf/michaelo/tomcat/realm/mapper/UsernameSearchMapper.html#UsernameSearchMapper

Am 2019-10-10 um 04:47 schrieb Weijun Wang:
Hi Michael,

Thanks for trying this new feature, you are always the first one.

If I remember correctly, when Martin developed this new feature, he was 
thinking of adding as little as possible spec change at the beginning. 
Therefore although there is a new KerberosPrincipal::KRB_NT_ENTERPRISE 
constant, it was just an integer and anyone can hardcode it. His next steps 
will be `kinit -e` and a new Krb5LoginModule option.

And welcome to provide more detail on your usecase.

--Max

On Sep 26, 2019, at 5:27 AM, Osipov, Michael <michael.osi...@siemens.com> wrote:

Hi folks,

apologies upfront that I wasn't able when Martin Balao asked for a review of 
the code. I finally made to test it and cannot see that it is working anyhow 
here.

I won't dive into my usecase now, but will depict two simple cases which are 
not possible.

All tests were performed with Oracle JDK 13 on Windows 7:
java version "13" 2019-09-17
Java(TM) SE Runtime Environment (build 13+33)
Java HotSpot(TM) 64-Bit Server VM (build 13+33, mixed mode, sharing)

1. kinit (JDK bundled) does not work. It does neither provide an '-E' option, 
nor does it send NT-ENTERPRISE, but only NT-UNKNOWN:

0000   30 25 a0 03 02 01 00 a1 1e 30 1c 1b 1a 6d 69 63   0%.......0...mic
0010   68 61 65 6c 2e 6f 73 69 70 6f 76 40 73 69 65 6d   hael.osipov@siem
0020   65 6e 73 2e 63 6f 6d                              ens.com

In byte 0x06 is the name type NT-UNKNOWN (0). In contrast to this with MIT 
Kerberos 1.17 and 'kinit -E' I see in Wireshark:

0000   30 25 a0 03 02 01 0a a1 1e 30 1c 1b 1a 6d 69 63   0%.......0...mic
0010   68 61 65 6c 2e 6f 73 69 70 6f 76 40 73 69 65 6d   hael.osipov@siem
0020   65 6e 73 2e 63 6f 6d                              ens.com

byte 0x06 is now name type NT-ENTERPRISE-PRINCIPAL (10).

Trying the very same with LSA on Windows with "run as user" I get for my 
implicit UPN osipo...@ad001.siemens.net always type 10. It only uses NT-PRINCIPAL when I 
provide the local part (samAccountName).

2. Using the appropriate OID for the enterprise principal:

        public static void main(String[] args) throws GSSException {
                GSSManager m = GSSManager.getInstance();
                Oid msUpnOid = new Oid("1.3.6.1.4.1.311.20.2.3");
                Oid krb5PrincipalOid = new Oid("1.2.840.113554.1.2.2.1");
                Oid krb5EnterprisePrincialOid = new 
Oid("1.2.840.113554.1.2.2.6");
                Oid krb5MechOid = new Oid("1.2.840.113554.1.2.2");
                GSSName upn = m.createName("michael.osi...@siemens.com", 
krb5EnterprisePrincialOid);
        }

gives me:
Exception in thread "main" GSSException: Name of unsupported type provided 
(Mechanism level: 1.2.840.113554.1.2.2.6 is an unsupported nametype)
        at 
java.security.jgss/sun.security.jgss.krb5.Krb5NameElement.getInstance(Krb5NameElement.java:87)
        at 
java.security.jgss/sun.security.jgss.krb5.Krb5MechFactory.getNameElement(Krb5MechFactory.java:99)
        at 
java.security.jgss/sun.security.jgss.GSSManagerImpl.getNameElement(GSSManagerImpl.java:184)
        at 
java.security.jgss/sun.security.jgss.GSSNameImpl.getElement(GSSNameImpl.java:478)
        at 
java.security.jgss/sun.security.jgss.GSSNameImpl.init(GSSNameImpl.java:201)
        at 
java.security.jgss/sun.security.jgss.GSSNameImpl.<init>(GSSNameImpl.java:170)
        at 
java.security.jgss/sun.security.jgss.GSSNameImpl.<init>(GSSNameImpl.java:151)
        at 
java.security.jgss/sun.security.jgss.GSSManagerImpl.createName(GSSManagerImpl.java:109)
        at com.siemens.dynamowerk.Main.main(Main.java:20)

and yes, the OID has never been defined in that class [1], but is present in 
MIT Kerberos [2].

I haven't tried a programmatical kinit, but as mentioned in the notes [3], 
Krb5LoginModule does not support it, so I don't even have to try.


Any insights?

Beside that, it'd be very cool if this gets into 11u or better yet to 8u. I 
have talked with Weijun about this several times many years ago for Java 7+. I 
have no option to use anything else, but Java 8 for now.

If someone  wants to know better about my usecase, I'd be happy to lay it out 
in detail. I do need at least krb5EnterprisePrincialOid and better msUpnOid for 
my usecase.

The only option I see now is to write a delegating wrapper for this:

GSSName upn = m.createName("michael.osi...@siemens.com", krb5PrincipalOid);
GSSName wrappedUpn = new WrappedGSSName(upn, krb5EnterprisePrincialOid);
System.out.println(wrappedUpn);
System.out.println(wrappedUpn.getStringNameType());

michael.osi...@siemens.com
1.2.840.113554.1.2.2.6

Michael

[1] 
https://github.com/AdoptOpenJDK/openjdk-jdk13u/blob/bb0786d980437800b9d6efe17e42d18241714ea1/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java#L51-L61
[2] https://web.mit.edu/kerberos/krb5-devel/doc/appdev/gssapi.html
[3] 
http://mail.openjdk.java.net/pipermail/security-dev/2018-December/018952.html

Reply via email to