1 /*
2  * Copyright (c) 2009, 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 6853328 7172701 8194486
27  * @summary Support OK-AS-DELEGATE flag
28  * @library /test/lib
29  * @run main jdk.test.lib.FileInstaller TestHosts TestHosts
30  * @run main/othervm -Djdk.net.hosts.file=TestHosts OkAsDelegateXRealm false
31  *      KDC no OK-AS-DELEGATE, fail
32  * @run main/othervm -Djdk.net.hosts.file=TestHosts
33  *      -Dtest.kdc.policy.ok-as-delegate OkAsDelegateXRealm true
34  *      KDC set OK-AS-DELEGATE for all, succeed
35  * @run main/othervm -Djdk.net.hosts.file=TestHosts
36  *      -Dtest.kdc.policy.ok-as-delegate=host/host.r3.local
37  *      OkAsDelegateXRealm false
38  *      KDC set OK-AS-DELEGATE for host/host.r3.local only, fail
39  * @run main/othervm -Djdk.net.hosts.file=TestHosts
40  *      -Dtest.kdc.policy.ok-as-delegate=host/host.r3.local,krbtgt/R2,krbtgt/R3
41  *      OkAsDelegateXRealm true
42  *      KDC set OK-AS-DELEGATE for all three, succeed
43  */
44 import java.io.FileOutputStream;
45 import java.io.IOException;
46 import java.security.Security;
47 import javax.security.auth.callback.Callback;
48 import javax.security.auth.callback.CallbackHandler;
49 import javax.security.auth.callback.NameCallback;
50 import javax.security.auth.callback.PasswordCallback;
51 import javax.security.auth.callback.UnsupportedCallbackException;
52 
53 import com.sun.security.jgss.ExtendedGSSContext;
54 import org.ietf.jgss.GSSException;
55 import sun.security.jgss.GSSUtil;
56 import sun.security.krb5.Config;
57 
58 public class OkAsDelegateXRealm implements CallbackHandler {
59 
60     /**
61      * @param args boolean if the program should succeed
62      */
main(String[] args)63     public static void main(String[] args)
64             throws Exception {
65 
66         // Create and start the KDCs. Here we have 3 realms: R1, R2 and R3.
67         // R1 is trusted by R2, and R2 trusted by R3.
68         KDC kdc1 = KDC.create("R1");
69         kdc1.setOption(KDC.Option.OK_AS_DELEGATE,
70                 System.getProperty("test.kdc.policy.ok-as-delegate"));
71         kdc1.addPrincipal("dummy", "bogus".toCharArray());
72         kdc1.addPrincipalRandKey("krbtgt/R1");
73         kdc1.addPrincipal("krbtgt/R2@R1", "r1->r2".toCharArray());
74 
75         KDC kdc2 = KDC.create("R2");
76         kdc2.setOption(KDC.Option.OK_AS_DELEGATE,
77                 System.getProperty("test.kdc.policy.ok-as-delegate"));
78         kdc2.addPrincipalRandKey("krbtgt/R2");
79         kdc2.addPrincipal("krbtgt/R2@R1", "r1->r2".toCharArray());
80         kdc2.addPrincipal("krbtgt/R3@R2", "r2->r3".toCharArray());
81 
82         KDC kdc3 = KDC.create("R3");
83         kdc3.setOption(KDC.Option.OK_AS_DELEGATE,
84                 System.getProperty("test.kdc.policy.ok-as-delegate"));
85         kdc3.addPrincipalRandKey("krbtgt/R3");
86         kdc3.addPrincipal("krbtgt/R3@R2", "r2->r3".toCharArray());
87         kdc3.addPrincipalRandKey("host/host.r3.local");
88 
89         KDC.saveConfig("krb5-localkdc.conf", kdc1, kdc2, kdc3,
90                 "forwardable=true",
91                 "[capaths]",
92                 "R1 = {",
93                 "    R2 = .",
94                 "    R3 = R2",
95                 "}",
96                 "[domain_realm]",
97                 ".r3.local=R3"
98                 );
99 
100         System.setProperty("java.security.krb5.conf", "krb5-localkdc.conf");
101         kdc3.writeKtab("localkdc.ktab");
102 
103         FileOutputStream fos = new FileOutputStream("jaas-localkdc.conf");
104 
105         // Defines the client and server on R1 and R3 respectively.
106         fos.write(("com.sun.security.jgss.krb5.initiate {\n" +
107                 "    com.sun.security.auth.module.Krb5LoginModule\n" +
108                 "    required\n" +
109                 "    principal=dummy\n" +
110                 "    doNotPrompt=false\n" +
111                 "    useTicketCache=false\n" +
112                 "    ;\n};\n" +
113                 "com.sun.security.jgss.krb5.accept {\n" +
114                 "    com.sun.security.auth.module.Krb5LoginModule required\n" +
115                 "    principal=\"host/host.r3.local@R3\"\n" +
116                 "    useKeyTab=true\n" +
117                 "    keyTab=localkdc.ktab\n" +
118                 "    isInitiator=false\n" +
119                 "    storeKey=true;\n};\n" +
120                 "\n").getBytes());
121         fos.close();
122 
123         Security.setProperty("auth.login.defaultCallbackHandler",
124                 "OkAsDelegateXRealm");
125 
126         System.setProperty("java.security.auth.login.config", "jaas-localkdc.conf");
127 
128         Config.refresh();
129 
130         Context c = Context.fromJAAS("com.sun.security.jgss.krb5.initiate");
131         Context s = Context.fromJAAS("com.sun.security.jgss.krb5.accept");
132 
133         // Test twice. The frist time the whole cross realm process is tried,
134         // the second time the cached service ticket is used. This is to make sure
135         // the behaviors are the same, especailly for the case when one of the
136         // cross-realm TGTs does not have OK-AS-DELEGATE on.
137 
138         for (int i=0; i<2; i++) {
139             c.startAsClient("host@host.r3.local", GSSUtil.GSS_KRB5_MECH_OID);
140             s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
141             ((ExtendedGSSContext)c.x()).requestDelegPolicy(true);
142 
143             Context.handshake(c, s);
144             boolean succeed = true;
145             try {
146                 s.x().getDelegCred();
147             } catch (GSSException gsse) {
148                 succeed = false;
149             }
150             if (succeed != Boolean.parseBoolean(args[0])) {
151                 throw new Exception("Test fail at round #" + i);
152             }
153         }
154     }
155 
156     @Override
handle(Callback[] callbacks)157     public void handle(Callback[] callbacks)
158             throws IOException, UnsupportedCallbackException {
159         for (Callback callback : callbacks) {
160             if (callback instanceof NameCallback) {
161                 ((NameCallback) callback).setName("dummy");
162             }
163             if (callback instanceof PasswordCallback) {
164                 ((PasswordCallback) callback).setPassword("bogus".toCharArray());
165             }
166         }
167     }
168 }
169 
170