1 /* 2 * Copyright (c) 2012, 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.jgss.GSSUtil; 35 import sun.security.krb5.Config; 36 import sun.security.krb5.internal.ccache.Credentials; 37 import sun.security.krb5.internal.ccache.FileCredentialsCache; 38 39 import javax.security.auth.kerberos.KerberosTicket; 40 import java.util.Date; 41 import java.util.Random; 42 import java.util.Set; 43 44 // The basic krb5 test skeleton you can copy from 45 public class Renewal { 46 47 static OneKDC kdc; 48 static String clazz = "sun.security.krb5.internal.tools.Kinit"; 49 50 public static void main(String[] args) throws Exception { 51 52 kdc = new OneKDC(null); 53 kdc.writeJAASConf(); 54 kdc.setOption(KDC.Option.PREAUTH_REQUIRED, false); 55 56 checkLogin(null, null, KDC.DEFAULT_LIFETIME, -1); 57 checkLogin("1h", null, 3600, -1); 58 checkLogin(null, "2d", KDC.DEFAULT_LIFETIME, 86400*2); 59 checkLogin("1h", "10h", 3600, 36000); 60 // When rtime is before till, use till as rtime 61 checkLogin("10h", "1h", 36000, 36000); 62 63 try { 64 Class.forName(clazz); 65 } catch (ClassNotFoundException cnfe) { 66 return; 67 } 68 69 checkKinit(null, null, null, null, KDC.DEFAULT_LIFETIME, -1); 70 checkKinit("1h", "10h", null, null, 3600, 36000); 71 checkKinit(null, null, "30m", "5h", 1800, 18000); 72 checkKinit("1h", "10h", "30m", "5h", 1800, 18000); 73 74 checkKinitRenew(); 75 } 76 77 static int count = 0; 78 79 static void checkKinit( 80 String s1, // ticket_lifetime in krb5.conf, null if none 81 String s2, // renew_lifetime in krb5.conf, null if none 82 String c1, // -l on kinit, null if none 83 String c2, // -r on kinit, null if none 84 int t1, int t2 // expected lifetimes, -1 of unexpected 85 ) throws Exception { 86 KDC.saveConfig(OneKDC.KRB5_CONF, kdc, 87 s1 != null ? ("ticket_lifetime = " + s1) : "", 88 s2 != null ? ("renew_lifetime = " + s2) : ""); 89 Proc p = Proc.create(clazz); 90 if (c1 != null) { 91 p.args("-l", c1); 92 } 93 if (c2 != null) { 94 p.args("-r", c2); 95 } 96 count++; 97 p.args(OneKDC.USER, new String(OneKDC.PASS)) 98 .inheritIO() 99 .prop("sun.net.spi.nameservice.provider.1", "ns,mock") 100 .prop("java.security.krb5.conf", OneKDC.KRB5_CONF) 101 .env("KRB5CCNAME", "ccache" + count) 102 .start(); 103 if (p.waitFor() != 0) { 104 throw new Exception(); 105 } 106 FileCredentialsCache fcc = 107 FileCredentialsCache.acquireInstance(null, "ccache" + count); 108 Credentials cred = fcc.getDefaultCreds(); 109 checkRough(cred.getEndTime().toDate(), t1); 110 if (cred.getRenewTill() == null) { 111 checkRough(null, t2); 112 } else { 113 checkRough(cred.getRenewTill().toDate(), t2); 114 } 115 } 116 117 static void checkKinitRenew() throws Exception { 118 Proc p = Proc.create(clazz) 119 .args("-R") 120 .inheritIO() 121 .prop("sun.net.spi.nameservice.provider.1", "ns,mock") 122 .prop("java.security.krb5.conf", OneKDC.KRB5_CONF) 123 .env("KRB5CCNAME", "ccache" + count) 124 .start(); 125 if (p.waitFor() != 0) { 126 throw new Exception(); 127 } 128 } 129 130 static void checkLogin( 131 String s1, // ticket_lifetime in krb5.conf, null if none 132 String s2, // renew_lifetime in krb5.conf, null if none 133 int t1, int t2 // expected lifetimes, -1 of unexpected 134 ) throws Exception { 135 KDC.saveConfig(OneKDC.KRB5_CONF, kdc, 136 s1 != null ? ("ticket_lifetime = " + s1) : "", 137 s2 != null ? ("renew_lifetime = " + s2) : ""); 138 Config.refresh(); 139 140 Context c; 141 c = Context.fromJAAS("client"); 142 143 Set<KerberosTicket> tickets = 144 c.s().getPrivateCredentials(KerberosTicket.class); 145 if (tickets.size() != 1) { 146 throw new Exception(); 147 } 148 KerberosTicket ticket = tickets.iterator().next(); 149 150 checkRough(ticket.getEndTime(), t1); 151 checkRough(ticket.getRenewTill(), t2); 152 } 153 154 static void checkRough(Date t, int duration) throws Exception { 155 Date now = new Date(); 156 if (t == null && duration == -1) { 157 return; 158 } 159 long change = (t.getTime() - System.currentTimeMillis()) / 1000; 160 if (change > duration + 20 || change < duration - 20) { 161 throw new Exception(t + " is not " + duration); 162 } 163 } 164 }