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 
  33 import java.nio.file.Files;
  34 import java.nio.file.Paths;
  35 import java.nio.file.StandardOpenOption;
  36 import java.security.Permission;
  37 import javax.security.auth.kerberos.ServicePermission;
  38 import sun.security.jgss.GSSUtil;
  39 import java.util.*;
  40 
  41 public 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 }