From 3fb9be207507aac66239eb1d0d00aa9995a303c9 Mon Sep 17 00:00:00 2001 From: weijun Date: Tue, 30 Jun 2015 22:32:03 +0800 Subject: [PATCH] 8075301: Tests for sun.security.krb5.principal system property Reviewed-by: weijun Contributed-by: Sibabrata Sahoo --- test/sun/security/krb5/auto/KDC.java | 65 ++++++++ test/sun/security/krb5/auto/UnboundSSL.java | 6 +- .../krb5/auto/UnboundSSLMultipleKeys.java | 6 +- .../auto/UnboundSSLPrincipalProperty.java | 5 +- .../security/krb5/auto/UnboundSSLUtils.java | 61 ------- .../PrincipalSystemPropTest.java | 155 ++++++++++++++++++ .../krb5/auto/principalProperty/jaas.conf | 34 ++++ .../principalSystemPropTest.policy | 21 +++ 8 files changed, 286 insertions(+), 67 deletions(-) create mode 100644 test/sun/security/krb5/auto/principalProperty/PrincipalSystemPropTest.java create mode 100644 test/sun/security/krb5/auto/principalProperty/jaas.conf create mode 100644 test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy diff --git a/test/sun/security/krb5/auto/KDC.java b/test/sun/security/krb5/auto/KDC.java index 15b161200..76bb9085b 100644 --- a/test/sun/security/krb5/auto/KDC.java +++ b/test/sun/security/krb5/auto/KDC.java @@ -30,6 +30,7 @@ import java.lang.reflect.Method; import java.security.SecureRandom; import java.util.*; import java.util.concurrent.*; + import sun.net.spi.nameservice.NameService; import sun.net.spi.nameservice.NameServiceDescriptor; import sun.security.krb5.*; @@ -151,6 +152,8 @@ public class KDC { DatagramSocket u1 = null; ServerSocket t1 = null; + public static enum KtabMode { APPEND, EXISTING }; + /** * Option names, to be expanded forever. */ @@ -1294,6 +1297,68 @@ public class KDC { // OK } } + + public static void startKDC(final String host, final String krbConfFileName, + final String realm, final Map principals, + final String ktab, final KtabMode mode) { + + try { + KDC kdc = KDC.create(realm, host, 0, true); + kdc.setOption(KDC.Option.PREAUTH_REQUIRED, Boolean.FALSE); + KDC.saveConfig(krbConfFileName, kdc); + + // Add principals + if (principals != null) { + principals.forEach((name, password) -> { + if (password == null || password.isEmpty()) { + System.out.println(String.format( + "KDC:add a principal '%s' with a random " + + "password", name)); + kdc.addPrincipalRandKey(name); + } else { + System.out.println(String.format( + "KDC:add a principal '%s' with '%s' password", + name, password)); + kdc.addPrincipal(name, password.toCharArray()); + } + }); + } + + // Create or append keys to existing keytab file + if (ktab != null) { + File ktabFile = new File(ktab); + switch(mode) { + case APPEND: + if (ktabFile.exists()) { + System.out.println(String.format( + "KDC:append keys to an exising keytab " + + "file %s", ktab)); + kdc.appendKtab(ktab); + } else { + System.out.println(String.format( + "KDC:create a new keytab file %s", ktab)); + kdc.writeKtab(ktab); + } + break; + case EXISTING: + System.out.println(String.format( + "KDC:use an existing keytab file %s", ktab)); + break; + default: + throw new RuntimeException(String.format( + "KDC:unsupported keytab mode: %s", mode)); + } + } + + System.out.println(String.format( + "KDC: started on %s:%s with '%s' realm", + host, kdc.getPort(), realm)); + } catch (Exception e) { + throw new RuntimeException("KDC: unexpected exception", e); + } + + } + /** * Helper class to encapsulate a job in a KDC. */ diff --git a/test/sun/security/krb5/auto/UnboundSSL.java b/test/sun/security/krb5/auto/UnboundSSL.java index 0862f072f..5df24f852 100644 --- a/test/sun/security/krb5/auto/UnboundSSL.java +++ b/test/sun/security/krb5/auto/UnboundSSL.java @@ -26,6 +26,7 @@ import java.security.NoSuchAlgorithmException; import java.security.PrivilegedActionException; import java.util.HashMap; import java.util.Map; + import javax.security.auth.login.LoginException; /* @@ -74,8 +75,9 @@ public class UnboundSSL { UnboundSSLUtils.KRB5_CONF_FILENAME); // start a local KDC instance - UnboundSSLUtils.startKDC(UnboundSSLUtils.REALM, principals, - UnboundSSLUtils.KTAB_FILENAME, UnboundSSLUtils.KtabMode.APPEND); + KDC.startKDC(UnboundSSLUtils.HOST, UnboundSSLUtils.KRB5_CONF_FILENAME, + UnboundSSLUtils.REALM, principals, + UnboundSSLUtils.KTAB_FILENAME, KDC.KtabMode.APPEND); System.setProperty("java.security.auth.login.config", UnboundSSLUtils.TEST_SRC + UnboundSSLUtils.FS + jaacConfigFile); diff --git a/test/sun/security/krb5/auto/UnboundSSLMultipleKeys.java b/test/sun/security/krb5/auto/UnboundSSLMultipleKeys.java index 255a40ca1..aa1ea2b38 100644 --- a/test/sun/security/krb5/auto/UnboundSSLMultipleKeys.java +++ b/test/sun/security/krb5/auto/UnboundSSLMultipleKeys.java @@ -26,6 +26,7 @@ import java.security.NoSuchAlgorithmException; import java.security.PrivilegedActionException; import java.util.HashMap; import java.util.Map; + import javax.security.auth.login.LoginException; /* @@ -81,8 +82,9 @@ public class UnboundSSLMultipleKeys { * principal, but password for only one key is the same with the record * for service1 principal in KDC. */ - UnboundSSLUtils.startKDC(UnboundSSLUtils.REALM, principals, - UnboundSSLUtils.KTAB_FILENAME, UnboundSSLUtils.KtabMode.APPEND); + KDC.startKDC(UnboundSSLUtils.HOST, UnboundSSLUtils.KRB5_CONF_FILENAME, + UnboundSSLUtils.REALM, principals, + UnboundSSLUtils.KTAB_FILENAME, KDC.KtabMode.APPEND); System.setProperty("java.security.auth.login.config", UnboundSSLUtils.TEST_SRC + UnboundSSLUtils.FS + jaacConfigFile); diff --git a/test/sun/security/krb5/auto/UnboundSSLPrincipalProperty.java b/test/sun/security/krb5/auto/UnboundSSLPrincipalProperty.java index 3ccb4bf60..ab8549eb8 100644 --- a/test/sun/security/krb5/auto/UnboundSSLPrincipalProperty.java +++ b/test/sun/security/krb5/auto/UnboundSSLPrincipalProperty.java @@ -70,8 +70,9 @@ public class UnboundSSLPrincipalProperty { UnboundSSLUtils.KRB5_CONF_FILENAME); // start a local KDC instance - UnboundSSLUtils.startKDC(UnboundSSLUtils.REALM, principals, - UnboundSSLUtils.KTAB_FILENAME, UnboundSSLUtils.KtabMode.APPEND); + KDC.startKDC(UnboundSSLUtils.HOST, UnboundSSLUtils.KRB5_CONF_FILENAME, + UnboundSSLUtils.REALM, principals, + UnboundSSLUtils.KTAB_FILENAME, KDC.KtabMode.APPEND); System.setProperty("java.security.auth.login.config", UnboundSSLUtils.TEST_SRC + UnboundSSLUtils.FS + jaacConfigFile); diff --git a/test/sun/security/krb5/auto/UnboundSSLUtils.java b/test/sun/security/krb5/auto/UnboundSSLUtils.java index ab55e1fa1..1aefac2c3 100644 --- a/test/sun/security/krb5/auto/UnboundSSLUtils.java +++ b/test/sun/security/krb5/auto/UnboundSSLUtils.java @@ -50,8 +50,6 @@ import javax.security.auth.login.LoginException; */ class UnboundSSLUtils { - static enum KtabMode { APPEND, EXISTING }; - static final String KTAB_FILENAME = "krb5.keytab.data"; static final String HOST = "localhost"; static final String REALM = "TEST.REALM"; @@ -87,65 +85,6 @@ class UnboundSSLUtils { }); } - /* - * Start a KDC server: - * - create a KDC instance - * - create Kerberos principals - * - save Kerberos configuration - * - save keys to keytab file - * - no pre-auth required - */ - static void startKDC(String realm, Map principals, - String ktab, KtabMode mode) { - try { - KDC kdc = KDC.create(realm, HOST, 0, true); - kdc.setOption(KDC.Option.PREAUTH_REQUIRED, Boolean.FALSE); - if (principals != null) { - for (Map.Entry entry : principals.entrySet()) { - String name = entry.getKey(); - String password = entry.getValue(); - if (password == null || password.isEmpty()) { - System.out.println("KDC: add a principal '" + name + - "' with a random password"); - kdc.addPrincipalRandKey(name); - } else { - System.out.println("KDC: add a principal '" + name + - "' with '" + password + "' password"); - kdc.addPrincipal(name, password.toCharArray()); - } - } - } - - KDC.saveConfig(KRB5_CONF_FILENAME, kdc); - - if (ktab != null) { - File ktabFile = new File(ktab); - if (mode == KtabMode.APPEND) { - if (ktabFile.exists()) { - System.out.println("KDC: append keys to an exising " + - "keytab file " + ktab); - kdc.appendKtab(ktab); - } else { - System.out.println("KDC: create a new keytab file " + - ktab); - kdc.writeKtab(ktab); - } - } else if (mode == KtabMode.EXISTING) { - System.out.println("KDC: use an existing keytab file " - + ktab); - } else { - throw new RuntimeException("KDC: unsupported keytab mode: " - + mode); - } - } - - System.out.println("KDC: started on " + HOST + ":" + kdc.getPort() - + " with '" + realm + "' realm"); - } catch (Exception e) { - throw new RuntimeException("KDC: unexpected exception", e); - } - } - } class SSLClient { diff --git a/test/sun/security/krb5/auto/principalProperty/PrincipalSystemPropTest.java b/test/sun/security/krb5/auto/principalProperty/PrincipalSystemPropTest.java new file mode 100644 index 000000000..262e1da18 --- /dev/null +++ b/test/sun/security/krb5/auto/principalProperty/PrincipalSystemPropTest.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2015, 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 8075301 + * @library /sun/security/krb5/auto + * @summary New test for sun.security.krb5.principal system property. + * The principal can set using the system property sun.security.krb5.principal. + * This property is checked during login. If this property is not set, + * then the principal name from the configuration is used. + * @run main/othervm/java.security.policy=principalSystemPropTest.policy + * PrincipalSystemPropTest + */ + +import java.io.File; +import java.util.HashMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.security.auth.login.LoginException; +import javax.security.auth.login.LoginContext; +import com.sun.security.auth.callback.TextCallbackHandler; + +public class PrincipalSystemPropTest { + + private static final boolean PASS = Boolean.TRUE; + private static final boolean FAIL = Boolean.FALSE; + private static final String VALID_PRINCIPAL_JAAS_ENTRY = + "ValidPrincipalSystemPropTest"; + private static final String INVALID_PRINCIPAL_JAAS_ENTRY = + "InvalidPrincipalSystemPropTest"; + private static final String NO_PRINCIPAL_JAAS_ENTRY = + "NoPrincipalSystemPropTest"; + private static final String SAME_PRINCIPAL_JAAS_ENTRY = + "SelfPrincipalSystemPropTest"; + private static final String HOST = "localhost"; + private static final String KTAB_FILENAME = "krb5.keytab.data"; + private static final String REALM = "TEST.REALM"; + private static final String TEST_SRC = System.getProperty("test.src", "."); + private static final String USER = "USER"; + private static final String AVAILABLE_USER = "AVAILABLE"; + private static final String USER_PASSWORD = "password"; + private static final String FS = System.getProperty("file.separator"); + private static final String KRB5_CONF_FILENAME = "krb5.conf"; + private static final String JAAS_CONF_FILENAME = "jaas.conf"; + private static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM; + private static final String USER_PRINCIPAL = USER + "@" + REALM; + private static final String AVAILABLE_USER_PRINCIPAL = + AVAILABLE_USER + "@" + REALM; + + public static void main(String[] args) throws Exception { + + setupTest(); + + // Expected result, Jaas Config Entry, Login Principal Expected, + // Principal passed through System property + runTest(PASS, VALID_PRINCIPAL_JAAS_ENTRY, + USER_PRINCIPAL, "USER@TEST.REALM"); + runTest(PASS, VALID_PRINCIPAL_JAAS_ENTRY, + AVAILABLE_USER_PRINCIPAL, null); + runTest(PASS, INVALID_PRINCIPAL_JAAS_ENTRY, + USER_PRINCIPAL, "USER@TEST.REALM"); + runTest(FAIL, INVALID_PRINCIPAL_JAAS_ENTRY, null, null); + runTest(PASS, NO_PRINCIPAL_JAAS_ENTRY, + USER_PRINCIPAL, "USER@TEST.REALM"); + runTest(FAIL, NO_PRINCIPAL_JAAS_ENTRY, null, null); + runTest(PASS, SAME_PRINCIPAL_JAAS_ENTRY, + USER_PRINCIPAL, "USER@TEST.REALM"); + + } + + private static void setupTest() { + + System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME); + System.setProperty("java.security.auth.login.config", + TEST_SRC + FS + JAAS_CONF_FILENAME); + + Map principals = new HashMap<>(); + principals.put(USER_PRINCIPAL, USER_PASSWORD); + principals.put(AVAILABLE_USER_PRINCIPAL, USER_PASSWORD); + principals.put(KRBTGT_PRINCIPAL, null); + KDC.startKDC(HOST, KRB5_CONF_FILENAME, REALM, principals, + KTAB_FILENAME, KDC.KtabMode.APPEND); + + } + + private static void runTest(boolean expected, String jaasConfigEntry, + String expectedLoginUser, String loginUserBySysProp) { + + if(loginUserBySysProp != null) { + System.setProperty("sun.security.krb5.principal", + loginUserBySysProp); + } else { + System.clearProperty("sun.security.krb5.principal"); + } + + try { + LoginContext lc = new LoginContext(jaasConfigEntry, + new TextCallbackHandler()); + lc.login(); + System.out.println(String.format( + "Authentication completed with Subject '%s' ", + lc.getSubject())); + + if (!expected) { + throw new RuntimeException( + "TEST FAILED - JAAS login success isn't expected"); + } + if(expectedLoginUser != null && !lc.getSubject().getPrincipals() + .stream().map(p -> p.getName()).filter( + expectedLoginUser :: equals).findFirst() + .isPresent()) { + throw new RuntimeException(String.format( + "TEST FAILED - Login principal is not matched " + + "to expected principal '%s'.", expectedLoginUser)); + } + System.out.println( + "TEST PASSED - JAAS login success is expected."); + } catch (LoginException ie) { + System.out.println(String.format( + "Authentication failed with exception: %s", + ie.getMessage())); + if (expected) { + System.out.println( + "TEST FAILED - JAAS login failure isn't expected"); + throw new RuntimeException(ie); + } + System.out.println( + "TEST PASSED - JAAS login failure is expected."); + } + + } + +} diff --git a/test/sun/security/krb5/auto/principalProperty/jaas.conf b/test/sun/security/krb5/auto/principalProperty/jaas.conf new file mode 100644 index 000000000..0a5b794e9 --- /dev/null +++ b/test/sun/security/krb5/auto/principalProperty/jaas.conf @@ -0,0 +1,34 @@ +NoPrincipalSystemPropTest { + com.sun.security.auth.module.Krb5LoginModule required + useKeyTab = true + keyTab = krb5.keytab.data + doNotPrompt =true + debug=true; +}; + +InvalidPrincipalSystemPropTest { + com.sun.security.auth.module.Krb5LoginModule required + principal="UNAVAILABLE@TEST.REALM" + useKeyTab = true + keyTab = krb5.keytab.data + doNotPrompt =true + debug=true; +}; + +ValidPrincipalSystemPropTest { + com.sun.security.auth.module.Krb5LoginModule required + principal="AVAILABLE@TEST.REALM" + useKeyTab = true + keyTab = krb5.keytab.data + doNotPrompt =true + debug=true; +}; + +SelfPrincipalSystemPropTest { + com.sun.security.auth.module.Krb5LoginModule required + principal="USER@TEST.REALM" + useKeyTab = true + keyTab = krb5.keytab.data + doNotPrompt =true + debug=true; +}; diff --git a/test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy b/test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy new file mode 100644 index 000000000..ac9ef4861 --- /dev/null +++ b/test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy @@ -0,0 +1,21 @@ +grant { + permission javax.security.auth.AuthPermission + "createLoginContext.ValidPrincipalSystemPropTest"; + permission javax.security.auth.AuthPermission + "createLoginContext.InvalidPrincipalSystemPropTest"; + permission javax.security.auth.AuthPermission + "createLoginContext.NoPrincipalSystemPropTest"; + permission javax.security.auth.AuthPermission + "createLoginContext.SelfPrincipalSystemPropTest"; + permission javax.security.auth.AuthPermission "doAs"; + permission javax.security.auth.AuthPermission "modifyPrincipals"; + permission javax.security.auth.AuthPermission "getSubject"; + permission java.util.PropertyPermission "*", "read,write"; + permission java.io.FilePermission "*", "read,write,delete"; + permission java.lang.RuntimePermission "accessDeclaredMembers"; + permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; + permission java.lang.RuntimePermission "accessClassInPackage.*"; + permission java.net.SocketPermission "*:*", + "listen,resolve,accept,connect"; +}; + -- GitLab