/* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test * @bug 8005447 * @compile -XDignore.symbol.file ServiceCredsCombination.java * @run main ServiceCredsCombination * @summary default principal can act as anyone */ import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.Objects; import javax.security.auth.Subject; import javax.security.auth.kerberos.KerberosKey; import javax.security.auth.kerberos.KerberosPrincipal; import javax.security.auth.kerberos.KeyTab; import org.ietf.jgss.GSSCredential; import org.ietf.jgss.GSSException; import org.ietf.jgss.GSSManager; import org.ietf.jgss.GSSName; import sun.security.jgss.GSSUtil; public class ServiceCredsCombination { public static void main(String[] args) throws Exception { // pass check("a", "a", princ("a"), key("a")); check(null, "a", princ("a"), key("a")); check("x", "NOCRED", princ("a"), key("a")); // two pass check("a", "a", princ("a"), key("a"), princ("b"), key("b")); check("b", "b", princ("a"), key("a"), princ("b"), key("b")); check(null, null, princ("a"), key("a"), princ("b"), key("b")); check("x", "NOCRED", princ("a"), key("a"), princ("b"), key("b")); // old ktab check("b", "b", princ("b"), oldktab()); check("x", "NOCRED", princ("b"), oldktab()); check(null, "b", princ("b"), oldktab()); // Two old ktab check("a", "a", princ("a"), princ("b"), oldktab(), oldktab()); check("b", "b", princ("a"), princ("b"), oldktab(), oldktab()); check(null, null, princ("a"), princ("b"), oldktab(), oldktab()); check("x", "NOCRED", princ("a"), princ("b"), oldktab(), oldktab()); // bound ktab check("c", "c", princ("c"), ktab("c")); check(null, "c", princ("c"), ktab("c")); // unbound ktab check("x", "x", ktab()); check(null, null, ktab()); // Two bound ktab check("c1", "c1", princ("c1"), princ("c2"), ktab("c1"), ktab("c2")); check("c2", "c2", princ("c1"), princ("c2"), ktab("c1"), ktab("c2")); check("x", "NOCRED", princ("c1"), princ("c2"), ktab("c1"), ktab("c2")); check(null, null, princ("c1"), princ("c2"), ktab("c1"), ktab("c2")); // One bound, one unbound check("c1", "c1", princ("c1"), ktab("c1"), ktab()); check("x", "x", princ("c1"), ktab("c1"), ktab()); check(null, null, princ("c1"), ktab("c1"), ktab()); // Two unbound ktab check("x", "x", ktab(), ktab()); check(null, null, ktab(), ktab()); // pass + old ktab check("a", "a", princ("a"), princ("b"), key("a"), oldktab()); check("b", "b", princ("a"), princ("b"), key("a"), oldktab()); check(null, null, princ("a"), princ("b"), key("a"), oldktab()); check("x", "NOCRED", princ("a"), princ("b"), key("a"), oldktab()); // pass + bound ktab check("a", "a", princ("a"), princ("c"), key("a"), ktab("c")); check("c", "c", princ("a"), princ("c"), key("a"), ktab("c")); check("x", "NOCRED", princ("a"), princ("c"), key("a"), ktab("c")); check(null, null, princ("a"), princ("c"), key("a"), ktab("c")); // pass + unbound ktab check("a", "a", princ("a"), key("a"), ktab()); check("x", "x", princ("a"), key("a"), ktab()); check(null, null, princ("a"), key("a"), ktab()); // Compatibility, automatically add princ for keys check(null, "a", key("a")); check("x", "NOCRED", key("a")); check(null, "a", key("a"), oldktab()); check("x", "NOCRED", key("a"), oldktab()); // Limitation, "a" has no key, but we don't know oldktab() is for "b" check("a", "a", princ("a"), princ("b"), oldktab()); } /** * Checks the correct bound * @param a get a creds for this principal, null for default one * @param b expected name, null for still unbound, "NOCRED" for no creds * @param objs princs, keys and keytabs in the subject */ private static void check(final String a, String b, Object... objs) throws Exception { Subject subj = new Subject(); for (Object obj: objs) { if (obj instanceof KerberosPrincipal) { subj.getPrincipals().add((KerberosPrincipal)obj); } else if (obj instanceof KerberosKey || obj instanceof KeyTab) { subj.getPrivateCredentials().add(obj); } } final GSSManager man = GSSManager.getInstance(); try { String result = Subject.doAs( subj, new PrivilegedExceptionAction<String>() { @Override public String run() throws GSSException { GSSCredential cred = man.createCredential( a == null ? null : man.createName(r(a), null), GSSCredential.INDEFINITE_LIFETIME, GSSUtil.GSS_KRB5_MECH_OID, GSSCredential.ACCEPT_ONLY); GSSName name = cred.getName(); return name == null ? null : name.toString(); } }); if (!Objects.equals(result, r(b))) { throw new Exception("Check failed: getInstance(" + a + ") has name " + result + ", not " + b); } } catch (PrivilegedActionException e) { if (!"NOCRED".equals(b)) { throw new Exception("Check failed: getInstance(" + a + ") is null " + ", but not one with name " + b); } } } private static String r(String s) { return s == null ? null : (s+"@REALM"); } private static KerberosPrincipal princ(String s) { return new KerberosPrincipal(r(s)); } private static KerberosKey key(String s) { return new KerberosKey(princ(s), new byte[0], 0, 0); } private static KeyTab oldktab() { return KeyTab.getInstance(); } static KeyTab ktab(String s) { return KeyTab.getInstance(princ(s)); } static KeyTab ktab() { return KeyTab.getUnboundInstance(); } }