1/*
2 * Copyright (c) 2012, 2013, 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 9999999
27 * @summary default principal can act as anyone
28 * @compile -XDignore.symbol.file AcceptPermissions.java
29 * @run main/othervm AcceptPermissions two
30 * @run main/othervm AcceptPermissions unbound
31 */
32
33import java.nio.file.Files;
34import java.nio.file.Paths;
35import java.nio.file.StandardOpenOption;
36import java.security.Permission;
37import javax.security.auth.kerberos.ServicePermission;
38import sun.security.jgss.GSSUtil;
39import java.util.*;
40
41public class AcceptPermissions extends SecurityManager {
42
43    private static Map<Permission,String> perms = new HashMap<>();
44    @Override
45    public void checkPermission(Permission perm) {
46        if (!(perm instanceof ServicePermission)) {
47            return;
48        }
49        ServicePermission sp = (ServicePermission)perm;
50        if (!sp.getActions().equals("accept")) {
51            return;
52        }
53        // We only care about accept ServicePermission in this test
54        try {
55            super.checkPermission(sp);
56        } catch (SecurityException se) {
57            if (perms.containsKey(sp)) {
58                perms.put(sp, "checked");
59            } else {
60                throw se;   // We didn't expect this is needed
61            }
62        }
63    }
64
65    // Fills in permissions we are expecting
66    private static void initPerms(String... names) {
67        perms.clear();
68        for (String name: names) {
69            perms.put(new ServicePermission(
70                    name + "@" + OneKDC.REALM, "accept"), "expected");
71        }
72    }
73
74    // Checks if they are all checked
75    private static void checkPerms() {
76        for (Map.Entry<Permission,String> entry: perms.entrySet()) {
77            if (entry.getValue().equals("expected")) {
78                throw new RuntimeException(
79                        "Expected but not used: " + entry.getKey());
80            }
81        }
82    }
83
84    public static void main(String[] args) throws Exception {
85        System.setSecurityManager(new AcceptPermissions());
86        new OneKDC(null).writeJAASConf();
87        String moreEntries = "two {\n"
88                + " com.sun.security.auth.module.Krb5LoginModule required"
89                + "     principal=\"" + OneKDC.SERVER + "\" useKeyTab=true"
90                + "     isInitiator=false storeKey=true;\n"
91                + " com.sun.security.auth.module.Krb5LoginModule required"
92                + "     principal=\"" + OneKDC.BACKEND + "\" useKeyTab=true"
93                + "     isInitiator=false storeKey=true;\n"
94                + "};\n"
95                + "unbound {"
96                + " com.sun.security.auth.module.Krb5LoginModule required"
97                + "     principal=* useKeyTab=true"
98                + "     isInitiator=false storeKey=true;\n"
99                + "};\n";
100        Files.write(Paths.get(OneKDC.JAAS_CONF), moreEntries.getBytes(),
101                StandardOpenOption.APPEND);
102
103        Context c, s;
104
105        // In all cases, a ServicePermission on the acceptor name is needed
106        // for a handshake. For default principal with no predictable name,
107        // permission not needed (yet) for credentials creation.
108
109        // Named principal
110        initPerms(OneKDC.SERVER);
111        c = Context.fromJAAS("client");
112        s = Context.fromJAAS("server");
113        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
114        s.startAsServer(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
115        checkPerms();
116        initPerms(OneKDC.SERVER);
117        Context.handshake(c, s);
118        checkPerms();
119
120        // Named principal (even if there are 2 JAAS modules)
121        initPerms(OneKDC.SERVER);
122        c = Context.fromJAAS("client");
123        s = Context.fromJAAS(args[0]);
124        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
125        s.startAsServer(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
126        checkPerms();
127        initPerms(OneKDC.SERVER);
128        Context.handshake(c, s);
129        checkPerms();
130
131        // Default principal with a predictable name
132        initPerms(OneKDC.SERVER);
133        c = Context.fromJAAS("client");
134        s = Context.fromJAAS("server");
135        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
136        s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
137        checkPerms();
138        initPerms(OneKDC.SERVER);
139        Context.handshake(c, s);
140        checkPerms();
141
142        // Default principal with no predictable name
143        initPerms();    // permission not needed for cred !!!
144        c = Context.fromJAAS("client");
145        s = Context.fromJAAS(args[0]);
146        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
147        s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
148        checkPerms();
149        initPerms(OneKDC.SERVER);   // still needed for handshake !!!
150        Context.handshake(c, s);
151        checkPerms();
152    }
153}
154