1 /*
2  * Copyright (c) 2011, 2018, 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 6894072 8194486
27  * @summary always refresh keytab
28  * @library /test/lib
29  * @compile -XDignore.symbol.file TwoPrinces.java
30  * @run main jdk.test.lib.FileInstaller TestHosts TestHosts
31  * @run main/othervm -Djdk.net.hosts.file=TestHosts TwoPrinces
32  */
33 
34 import java.io.File;
35 import java.io.FileOutputStream;
36 import sun.security.jgss.GSSUtil;
37 import sun.security.krb5.Config;
38 
39 public class TwoPrinces {
40 
main(String[] args)41     public static void main(String[] args)
42             throws Exception {
43 
44         KDC k1 = KDC.create("R1");
45         k1.addPrincipal("u1", "hello".toCharArray());
46         k1.addPrincipalRandKey("krbtgt/R1");
47         k1.addPrincipalRandKey("host/same.host");
48 
49         KDC k2 = KDC.create("R2");
50         k2.addPrincipal("u2", "hello".toCharArray());
51         k2.addPrincipalRandKey("krbtgt/R2");
52         k2.addPrincipalRandKey("host/same.host");
53 
54         System.setProperty("java.security.krb5.conf", "krb5.conf");
55 
56         // R1 is the default realm now
57         KDC.saveConfig("krb5.conf", k1, k2);
58         Config.refresh();
59 
60         k1.writeKtab("ktab1");
61         k2.writeKtab("ktab2");
62 
63         // A JAAS config file with 2 Krb5LoginModules, after commit, the
64         // subject with have principals and keytabs from both sides
65         System.setProperty("java.security.auth.login.config", "jaas.conf");
66         File f = new File("jaas.conf");
67         FileOutputStream fos = new FileOutputStream(f);
68         fos.write((
69                 "me {\n"
70                 + "  com.sun.security.auth.module.Krb5LoginModule required"
71                 + "    isInitiator=true principal=\"host/same.host@R1\""
72                 + "    useKeyTab=true keyTab=ktab1 storeKey=true;\n"
73                 + "  com.sun.security.auth.module.Krb5LoginModule required"
74                 + "    isInitiator=true principal=\"host/same.host@R2\""
75                 + "    useKeyTab=true keyTab=ktab2 storeKey=true;\n"
76                 + "};\n"
77                 ).getBytes());
78         fos.close();
79 
80         /*
81          * This server side context will be able to act as services in both
82          * realms. Please note that we still don't support a single instance
83          * of server to accept connections from two realms at the same time.
84          * Therefore, we must call startAsServer in a given realm to start
85          * working there. The same Subject never changes anyway.
86          */
87         Context s = Context.fromJAAS("me");
88 
89         // Default realm still R1
90         s.startAsServer("host@same.host", GSSUtil.GSS_KRB5_MECH_OID);
91         Context c1 = Context.fromUserPass("u1", "hello".toCharArray(), false);
92         c1.startAsClient("host@same.host", GSSUtil.GSS_KRB5_MECH_OID);
93         Context.handshake(c1, s);
94 
95         KDC.saveConfig("krb5.conf", k2, k1);
96         Config.refresh();
97 
98         // Default realm now R2
99         s.startAsServer("host@same.host", GSSUtil.GSS_KRB5_MECH_OID);
100         Context c2 = Context.fromUserPass("u2", "hello".toCharArray(), false);
101         c2.startAsClient("host@same.host", GSSUtil.GSS_KRB5_MECH_OID);
102         Context.handshake(c2, s);
103     }
104 }
105