| /* |
| * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package sun.security.jgss; |
| |
| import java.util.HashMap; |
| import javax.security.auth.login.AppConfigurationEntry; |
| import javax.security.auth.login.Configuration; |
| import org.ietf.jgss.Oid; |
| |
| /** |
| * A Configuration implementation especially designed for JGSS. |
| * |
| * @author weijun.wang |
| * @since 1.6 |
| */ |
| public class LoginConfigImpl extends Configuration { |
| |
| private final Configuration config; |
| private final GSSCaller caller; |
| private final String mechName; |
| private static final sun.security.util.Debug debug = |
| sun.security.util.Debug.getInstance("gssloginconfig", "\t[GSS LoginConfigImpl]"); |
| |
| /** |
| * A new instance of LoginConfigImpl must be created for each login request |
| * since it's only used by a single (caller, mech) pair |
| * @param caller defined in GSSUtil as CALLER_XXX final fields |
| * @param mech defined in GSSUtil as XXX_MECH_OID final fields |
| */ |
| public LoginConfigImpl(GSSCaller caller, Oid mech) { |
| |
| this.caller = caller; |
| |
| if (mech.equals(GSSUtil.GSS_KRB5_MECH_OID)) { |
| mechName = "krb5"; |
| } else { |
| throw new IllegalArgumentException(mech.toString() + " not supported"); |
| } |
| config = java.security.AccessController.doPrivileged |
| (new java.security.PrivilegedAction <Configuration> () { |
| public Configuration run() { |
| return Configuration.getConfiguration(); |
| } |
| }); |
| } |
| |
| /** |
| * @param name Almost useless, since the (caller, mech) is already passed |
| * into constructor. The only use will be detecting OTHER which |
| * is called in LoginContext |
| */ |
| public AppConfigurationEntry[] getAppConfigurationEntry(String name) { |
| |
| AppConfigurationEntry[] entries = null; |
| |
| // This is the second call from LoginContext, which we will just ignore |
| if ("OTHER".equalsIgnoreCase(name)) { |
| return null; |
| } |
| |
| String[] alts = null; |
| |
| // Compatibility: |
| // For the 4 old callers, old entry names will be used if the new |
| // entry name is not provided. |
| |
| if ("krb5".equals(mechName)) { |
| if (caller == GSSCaller.CALLER_INITIATE) { |
| alts = new String[] { |
| "com.sun.security.jgss.krb5.initiate", |
| "com.sun.security.jgss.initiate", |
| }; |
| } else if (caller == GSSCaller.CALLER_ACCEPT) { |
| alts = new String[] { |
| "com.sun.security.jgss.krb5.accept", |
| "com.sun.security.jgss.accept", |
| }; |
| } else if (caller == GSSCaller.CALLER_SSL_CLIENT) { |
| alts = new String[] { |
| "com.sun.security.jgss.krb5.initiate", |
| "com.sun.net.ssl.client", |
| }; |
| } else if (caller == GSSCaller.CALLER_SSL_SERVER) { |
| alts = new String[] { |
| "com.sun.security.jgss.krb5.accept", |
| "com.sun.net.ssl.server", |
| }; |
| } else if (caller instanceof HttpCaller) { |
| alts = new String[] { |
| "com.sun.security.jgss.krb5.initiate", |
| }; |
| } else if (caller == GSSCaller.CALLER_UNKNOWN) { |
| throw new AssertionError("caller not defined"); |
| } |
| } else { |
| throw new IllegalArgumentException(mechName + " not supported"); |
| // No other mech at the moment, maybe -- |
| /* |
| switch (caller) { |
| case GSSUtil.CALLER_INITIATE: |
| case GSSUtil.CALLER_SSL_CLIENT: |
| case GSSUtil.CALLER_HTTP_NEGOTIATE: |
| alts = new String[] { |
| "com.sun.security.jgss." + mechName + ".initiate", |
| }; |
| break; |
| case GSSUtil.CALLER_ACCEPT: |
| case GSSUtil.CALLER_SSL_SERVER: |
| alts = new String[] { |
| "com.sun.security.jgss." + mechName + ".accept", |
| }; |
| break; |
| case GSSUtil.CALLER_UNKNOWN: |
| // should never use |
| throw new AssertionError("caller cannot be unknown"); |
| default: |
| throw new AssertionError("caller not defined"); |
| } |
| */ |
| } |
| for (String alt: alts) { |
| entries = config.getAppConfigurationEntry(alt); |
| if (debug != null) { |
| debug.println("Trying " + alt + |
| ((entries == null)?": does not exist.":": Found!")); |
| } |
| if (entries != null) { |
| break; |
| } |
| } |
| |
| if (entries == null) { |
| if (debug != null) { |
| debug.println("Cannot read JGSS entry, use default values instead."); |
| } |
| entries = getDefaultConfigurationEntry(); |
| } |
| return entries; |
| } |
| |
| /** |
| * Default value for a caller-mech pair when no entry is defined in |
| * the system-wide Configuration object. |
| */ |
| private AppConfigurationEntry[] getDefaultConfigurationEntry() { |
| HashMap <String, String> options = new HashMap <String, String> (2); |
| |
| if (mechName == null || mechName.equals("krb5")) { |
| if (isServerSide(caller)) { |
| // Assuming the keytab file can be found through |
| // krb5 config file or under user home directory |
| options.put("useKeyTab", "true"); |
| options.put("storeKey", "true"); |
| options.put("doNotPrompt", "true"); |
| options.put("principal", "*"); |
| options.put("isInitiator", "false"); |
| } else { |
| options.put("useTicketCache", "true"); |
| options.put("doNotPrompt", "false"); |
| } |
| return new AppConfigurationEntry[] { |
| new AppConfigurationEntry( |
| "com.sun.security.auth.module.Krb5LoginModule", |
| AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, |
| options) |
| }; |
| } |
| return null; |
| } |
| |
| private static boolean isServerSide (GSSCaller caller) { |
| return GSSCaller.CALLER_ACCEPT == caller || |
| GSSCaller.CALLER_SSL_SERVER == caller; |
| } |
| } |