1 /* 2 * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8044500 27 * @summary Add kinit options and krb5.conf flags that allow users to 28 * obtain renewable tickets and specify ticket lifetimes 29 * @library ../../../../java/security/testlibrary/ 30 * @compile -XDignore.symbol.file Renewal.java 31 * @run main/othervm Renewal 32 */ 33 34 import sun.security.krb5.Config; 35 import sun.security.krb5.internal.ccache.Credentials; 36 import sun.security.krb5.internal.ccache.FileCredentialsCache; 37 38 import javax.security.auth.kerberos.KerberosTicket; 39 import java.util.Date; 40 import java.util.Random; 41 import java.util.Set; 42 43 // The basic krb5 test skeleton you can copy from 44 public class Renewal { 45 46 static OneKDC kdc; 47 static String clazz = "sun.security.krb5.internal.tools.Kinit"; 48 static String hostsFileName = null; 49 50 public static void main(String[] args) throws Exception { 51 hostsFileName = System.getProperty("test.src", ".") + "/TestHosts"; 52 System.setProperty("jdk.net.hosts.file", hostsFileName); 53 54 kdc = new OneKDC(null); 55 kdc.writeJAASConf(); 56 kdc.setOption(KDC.Option.PREAUTH_REQUIRED, false); 57 58 checkLogin(null, null, KDC.DEFAULT_LIFETIME, -1); 59 checkLogin("1h", null, 3600, -1); 60 checkLogin(null, "2d", KDC.DEFAULT_LIFETIME, 86400*2); 61 checkLogin("1h", "10h", 3600, 36000); 62 // When rtime is before till, use till as rtime 63 checkLogin("10h", "1h", 36000, 36000); 64 65 try { 66 Class.forName(clazz); 67 } catch (ClassNotFoundException cnfe) { 68 return; 69 } 70 71 checkKinit(null, null, null, null, KDC.DEFAULT_LIFETIME, -1); 72 checkKinit("1h", "10h", null, null, 3600, 36000); 73 checkKinit(null, null, "30m", "5h", 1800, 18000); 74 checkKinit("1h", "10h", "30m", "5h", 1800, 18000); 75 76 checkKinitRenew(); 77 } 78 79 static int count = 0; 80 81 static void checkKinit( 82 String s1, // ticket_lifetime in krb5.conf, null if none 83 String s2, // renew_lifetime in krb5.conf, null if none 84 String c1, // -l on kinit, null if none 85 String c2, // -r on kinit, null if none 86 int t1, int t2 // expected lifetimes, -1 of unexpected 87 ) throws Exception { 88 KDC.saveConfig(OneKDC.KRB5_CONF, kdc, 89 s1 != null ? ("ticket_lifetime = " + s1) : "", 90 s2 != null ? ("renew_lifetime = " + s2) : ""); 91 Proc p = Proc.create(clazz); 92 if (c1 != null) { 93 p.args("-l", c1); 94 } 95 if (c2 != null) { 96 p.args("-r", c2); 97 } 98 count++; 99 p.args(OneKDC.USER, new String(OneKDC.PASS)) 100 .inheritIO() 101 .prop("jdk.net.hosts.file", hostsFileName) 102 .prop("java.security.krb5.conf", OneKDC.KRB5_CONF) 103 .env("KRB5CCNAME", "ccache" + count) 104 .start(); 105 if (p.waitFor() != 0) { 106 throw new Exception(); 107 } 108 FileCredentialsCache fcc = 109 FileCredentialsCache.acquireInstance(null, "ccache" + count); 110 Credentials cred = fcc.getDefaultCreds(); 111 checkRough(cred.getEndTime().toDate(), t1); 112 if (cred.getRenewTill() == null) { 113 checkRough(null, t2); 114 } else { 115 checkRough(cred.getRenewTill().toDate(), t2); 116 } 117 } 118 119 static void checkKinitRenew() throws Exception { 120 121 Proc p = Proc.create(clazz) 122 .args("-R") 123 .inheritIO() 124 .prop("jdk.net.hosts.file", hostsFileName) 125 .prop("java.security.krb5.conf", OneKDC.KRB5_CONF) 126 .env("KRB5CCNAME", "ccache" + count) 127 .start(); 128 if (p.waitFor() != 0) { 129 throw new Exception(); 130 } 131 } 132 133 static void checkLogin( 134 String s1, // ticket_lifetime in krb5.conf, null if none 135 String s2, // renew_lifetime in krb5.conf, null if none 136 int t1, int t2 // expected lifetimes, -1 of unexpected 137 ) throws Exception { 138 KDC.saveConfig(OneKDC.KRB5_CONF, kdc, 139 s1 != null ? ("ticket_lifetime = " + s1) : "", 140 s2 != null ? ("renew_lifetime = " + s2) : ""); 141 Config.refresh(); 142 143 Context c; 144 c = Context.fromJAAS("client"); 145 146 Set<KerberosTicket> tickets = 147 c.s().getPrivateCredentials(KerberosTicket.class); 148 if (tickets.size() != 1) { 149 throw new Exception(); 150 } 151 KerberosTicket ticket = tickets.iterator().next(); 152 153 checkRough(ticket.getEndTime(), t1); 154 checkRough(ticket.getRenewTill(), t2); 155 } 156 157 static void checkRough(Date t, int duration) throws Exception { 158 Date now = new Date(); 159 if (t == null && duration == -1) { 160 return; 161 } 162 long change = (t.getTime() - System.currentTimeMillis()) / 1000; 163 if (change > duration + 20 || change < duration - 20) { 164 throw new Exception(t + " is not " + duration); 165 } 166 } 167 }