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