Renewal.java revision 17113:d17577d4839b
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
34import sun.security.krb5.Config;
35import sun.security.krb5.internal.ccache.Credentials;
36import sun.security.krb5.internal.ccache.FileCredentialsCache;
37
38import javax.security.auth.kerberos.KerberosTicket;
39import java.util.Date;
40import java.util.Random;
41import java.util.Set;
42
43// The basic krb5 test skeleton you can copy from
44public 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}
168