# HG changeset patch # User asmotrak # Date 1441968270 -10800 # Node ID 5c9c62dad68f7cdfc1bd1be9b7d671858821d835 # Parent b6277cad14882bef9b5828ee8f7c0e041c958f2c 8075299: Additional tests for 6857795 Reviewed-by: weijun diff -r b6277cad1488 -r 5c9c62dad68f jdk/test/sun/security/krb5/auto/KrbTicket.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/krb5/auto/KrbTicket.java Fri Sep 11 13:44:30 2015 +0300 @@ -0,0 +1,146 @@ +/* + * 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. + */ + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Instant; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import javax.security.auth.RefreshFailedException; +import javax.security.auth.Subject; +import javax.security.auth.kerberos.KerberosTicket; +import javax.security.auth.login.LoginContext; + +/* + * @test + * @bug 6857795 8075299 + * @summary Checks Kerberos ticket properties + * @run main/othervm KrbTicket + */ +public class KrbTicket { + + private static final String REALM = "TEST.REALM"; + private static final String HOST = "localhost"; + private static final String USER = "TESTER"; + private static final String USER_PRINCIPAL = USER + "@" + REALM; + private static final String PASSWORD = "password"; + private static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM; + private static final String KRB5_CONF_FILENAME = "krb5.conf"; + private static final String JAAS_CONF = "jaas.conf"; + private static final long TICKET_LIFTETIME = 5 * 60 * 1000; // 5 mins + + public static void main(String[] args) throws Exception { + // define principals + Map principals = new HashMap<>(); + principals.put(USER_PRINCIPAL, PASSWORD); + principals.put(KRBTGT_PRINCIPAL, null); + + System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME); + + // start a local KDC instance + KDC kdc = KDC.startKDC(HOST, null, REALM, principals, null, null); + KDC.saveConfig(KRB5_CONF_FILENAME, kdc, + "forwardable = true", "proxiable = true"); + + // create JAAS config + Files.write(Paths.get(JAAS_CONF), Arrays.asList( + "Client {", + " com.sun.security.auth.module.Krb5LoginModule required;", + "};" + )); + System.setProperty("java.security.auth.login.config", JAAS_CONF); + System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); + + long startTime = Instant.now().getEpochSecond() * 1000; + + LoginContext lc = new LoginContext("Client", + new Helper.UserPasswordHandler(USER, PASSWORD)); + lc.login(); + + Subject subject = lc.getSubject(); + System.out.println("subject: " + subject); + + Set creds = subject.getPrivateCredentials( + KerberosTicket.class); + + if (creds.size() > 1) { + throw new RuntimeException("Multiple credintials found"); + } + + Object o = creds.iterator().next(); + if (!(o instanceof KerberosTicket)) { + throw new RuntimeException("Instance of KerberosTicket expected"); + } + KerberosTicket krbTkt = (KerberosTicket) o; + + System.out.println("forwardable = " + krbTkt.isForwardable()); + System.out.println("proxiable = " + krbTkt.isProxiable()); + System.out.println("renewable = " + krbTkt.isRenewable()); + System.out.println("current = " + krbTkt.isCurrent()); + + if (!krbTkt.isForwardable()) { + throw new RuntimeException("Forwardable ticket expected"); + } + + if (!krbTkt.isProxiable()) { + throw new RuntimeException("Proxiable ticket expected"); + } + + if (!krbTkt.isCurrent()) { + throw new RuntimeException("Ticket is not current"); + } + + if (krbTkt.isRenewable()) { + throw new RuntimeException("Not renewable ticket expected"); + } + try { + krbTkt.refresh(); + throw new RuntimeException( + "Expected RefreshFailedException not thrown"); + } catch(RefreshFailedException e) { + System.out.println("Expected exception: " + e); + } + + if (!checkTime(krbTkt, startTime)) { + throw new RuntimeException("Wrong ticket life time"); + } + + krbTkt.destroy(); + if (!krbTkt.isDestroyed()) { + throw new RuntimeException("Ticket not destroyed"); + } + + System.out.println("Test passed"); + } + + private static boolean checkTime(KerberosTicket krbTkt, long startTime) { + long ticketEndTime = krbTkt.getEndTime().getTime(); + long roughLifeTime = ticketEndTime - startTime; + System.out.println("start time = " + startTime); + System.out.println("end time = " + ticketEndTime); + System.out.println("rough life time = " + roughLifeTime); + return roughLifeTime >= TICKET_LIFTETIME; + } +} diff -r b6277cad1488 -r 5c9c62dad68f jdk/test/sun/security/krb5/auto/tools/KinitConfPlusProps.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/krb5/auto/tools/KinitConfPlusProps.java Fri Sep 11 13:44:30 2015 +0300 @@ -0,0 +1,188 @@ +/* + * 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. + */ + +import java.io.File; +import java.net.PortUnreachableException; +import java.util.HashMap; +import java.util.Map; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.OutputAnalyzer; + +/* + * @test + * @bug 6857795 8075299 + * @summary Checks if kinit uses both krb5 conf file and system properties + * @requires os.family == "windows" + * @library /lib/testlibrary + * @library /sun/security/krb5/auto + * @run main/othervm KinitConfPlusProps + */ +public class KinitConfPlusProps { + + private static final String KINIT = System.getProperty("java.home") + + File.separator + "bin" + File.separator + "kinit"; + private static final String KLIST = System.getProperty("java.home") + + File.separator + "bin" + File.separator + "klist"; + private static final String REALM = "REALM"; + private static final String ANOTHER_REALM = "ANOTHER.REALM"; + private static final String HOST = "localhost"; + private static final String CC_FILENAME = "krb5cc_test"; + private static final String USER = "TESTER"; + private static final String USER_PRINCIPAL = USER + "@" + REALM; + private static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM; + private static final String KEYTAB_FILE = "test.keytab"; + private static final String KRB5_CONF_FILENAME = "krb5.conf"; + + public static void main(String[] args) throws Exception { + // define principals + Map principals = new HashMap<>(); + principals.put(USER_PRINCIPAL, null); + principals.put(KRBTGT_PRINCIPAL, null); + + System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME); + + // start a local KDC instance + KDC kdc = KDC.startKDC(HOST, null, REALM, principals, KEYTAB_FILE, + KDC.KtabMode.APPEND); + KDC.saveConfig(KRB5_CONF_FILENAME, kdc, + "forwardable = true", "proxiable = true"); + + boolean success = true; + + /* + * kinit should fail since java.security.krb5.kdc + * and java.security.krb5.realm properties override correct values + * in krb5 conf file + */ + String[] command = {KINIT, "-k", + "-J-Djava.security.krb5.realm=" + REALM, + "-J-Djava.security.krb5.kdc=" + HOST, // without port + "-J-Djava.security.krb5.conf=" + KRB5_CONF_FILENAME, + "-t", KEYTAB_FILE, + "-c", CC_FILENAME, + USER + }; + + try { + OutputAnalyzer out = ProcessTools.executeCommand(command); + out.shouldHaveExitValue(-1); + out.shouldContain(PortUnreachableException.class.getName()); + } catch(Throwable e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + success = false; + } + + /* + * kinit should succeed + * since realm should be picked up from principal name + */ + command = new String[] {KINIT, "-k", + "-J-Djava.security.krb5.realm=" + ANOTHER_REALM, + "-J-Djava.security.krb5.kdc=" + HOST, + "-J-Djava.security.krb5.conf=" + KRB5_CONF_FILENAME, + "-t", KEYTAB_FILE, + "-c", CC_FILENAME, + USER_PRINCIPAL + }; + + try { + OutputAnalyzer out = ProcessTools.executeCommand(command); + out.shouldHaveExitValue(0); + out.shouldContain(CC_FILENAME); + } catch(Throwable e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + success = false; + } + + success &= checkTicketFlags(); + + /* + * kinit should succeed + * since realm should be picked up from principal name, + * and other data should come from krb5 conf file + */ + command = new String[] {KINIT, "-k", + "-J-Djava.security.krb5.conf=" + KRB5_CONF_FILENAME, + "-t", KEYTAB_FILE, + "-c", CC_FILENAME, + USER_PRINCIPAL + }; + + try { + OutputAnalyzer out = ProcessTools.executeCommand(command); + out.shouldHaveExitValue(0); + out.shouldContain(CC_FILENAME); + } catch(Throwable e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + success = false; + } + + success &= checkTicketFlags(); + + // kinit should succeed even if a principal name doesn't have realm + command = new String[] {KINIT, "-k", + "-J-Djava.security.krb5.conf=" + KRB5_CONF_FILENAME, + "-t", KEYTAB_FILE, + "-c", CC_FILENAME, + USER + }; + + try { + OutputAnalyzer out = ProcessTools.executeCommand(command); + out.shouldHaveExitValue(0); + out.shouldContain(CC_FILENAME); + } catch(Throwable e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + success = false; + } + + success &= checkTicketFlags(); + + if (!success) { + throw new RuntimeException("At least one test case failed"); + } + System.out.println("Test passed"); + } + + // check if a ticket has forwardable and proxiable flags + private static boolean checkTicketFlags() { + String[] command = new String[] {KLIST, "-f", "-c", CC_FILENAME}; + + try { + OutputAnalyzer out = ProcessTools.executeCommand(command); + out.shouldHaveExitValue(0); + out.shouldContain("FORWARDABLE"); + out.shouldContain("PROXIABLE"); + } catch(Throwable e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + return false; + } + + return true; + } +}