blob: a421e517f3a13b0d7b40c0ac8763ec1c50339242 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.security.jgss;
27
28import java.util.HashMap;
29import javax.security.auth.login.AppConfigurationEntry;
30import javax.security.auth.login.Configuration;
31import org.ietf.jgss.Oid;
32
33/**
34 * A Configuration implementation especially designed for JGSS.
35 *
36 * @author weijun.wang
37 * @since 1.6
38 */
39public class LoginConfigImpl extends Configuration {
40
41 private final Configuration config;
42 private final int caller;
43 private final String mechName;
44 private static final sun.security.util.Debug debug =
45 sun.security.util.Debug.getInstance("gssloginconfig", "\t[GSS LoginConfigImpl]");
46
47 /**
48 * A new instance of LoginConfigImpl must be created for each login request
49 * since it's only used by a single (caller, mech) pair
50 * @param caller defined in GSSUtil as CALLER_XXX final fields
51 * @param oid defined in GSSUtil as XXX_MECH_OID final fields
52 */
53 public LoginConfigImpl(int caller, Oid mech) {
54
55 this.caller = caller;
56
57 if (mech.equals(GSSUtil.GSS_KRB5_MECH_OID)) {
58 mechName = "krb5";
59 } else {
60 throw new IllegalArgumentException(mech.toString() + " not supported");
61 }
62 config = java.security.AccessController.doPrivileged
63 (new java.security.PrivilegedAction <Configuration> () {
64 public Configuration run() {
65 return Configuration.getConfiguration();
66 }
67 });
68 }
69
70 /**
71 * @param name Almost useless, since the (caller, mech) is already passed
72 * into constructor. The only use will be detecting OTHER which
73 * is called in LoginContext
74 */
75 public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
76
77 AppConfigurationEntry[] entries = null;
78
79 // This is the second call from LoginContext, which we will just ignore
80 if ("OTHER".equalsIgnoreCase(name)) {
81 return null;
82 }
83
84 String[] alts = null;
85
86 // Compatibility:
87 // For the 4 old callers, old entry names will be used if the new
88 // entry name is not provided.
89
90 if ("krb5".equals(mechName)) {
91 switch (caller) {
92 case GSSUtil.CALLER_INITIATE:
93 alts = new String[] {
94 "com.sun.security.jgss.krb5.initiate",
95 "com.sun.security.jgss.initiate",
96 };
97 break;
98 case GSSUtil.CALLER_ACCEPT:
99 alts = new String[] {
100 "com.sun.security.jgss.krb5.accept",
101 "com.sun.security.jgss.accept",
102 };
103 break;
104 case GSSUtil.CALLER_SSL_CLIENT:
105 alts = new String[] {
106 "com.sun.security.jgss.krb5.initiate",
107 "com.sun.net.ssl.client",
108 };
109 break;
110 case GSSUtil.CALLER_SSL_SERVER:
111 alts = new String[] {
112 "com.sun.security.jgss.krb5.accept",
113 "com.sun.net.ssl.server",
114 };
115 break;
116 case GSSUtil.CALLER_HTTP_NEGOTIATE:
117 alts = new String[] {
118 "com.sun.security.jgss.krb5.initiate",
119 };
120 break;
121 case GSSUtil.CALLER_UNKNOWN:
122 // should never use
123 throw new AssertionError("caller cannot be unknown");
124 default:
125 throw new AssertionError("caller not defined");
126 }
127 } else {
128 throw new IllegalArgumentException(mechName + " not supported");
129 // No other mech at the moment, maybe --
130 /*
131 switch (caller) {
132 case GSSUtil.CALLER_INITIATE:
133 case GSSUtil.CALLER_SSL_CLIENT:
134 case GSSUtil.CALLER_HTTP_NEGOTIATE:
135 alts = new String[] {
136 "com.sun.security.jgss." + mechName + ".initiate",
137 };
138 break;
139 case GSSUtil.CALLER_ACCEPT:
140 case GSSUtil.CALLER_SSL_SERVER:
141 alts = new String[] {
142 "com.sun.security.jgss." + mechName + ".accept",
143 };
144 break;
145 case GSSUtil.CALLER_UNKNOWN:
146 // should never use
147 throw new AssertionError("caller cannot be unknown");
148 default:
149 throw new AssertionError("caller not defined");
150 }
151 */
152 }
153 for (String alt: alts) {
154 entries = config.getAppConfigurationEntry(alt);
155 if (debug != null) {
156 debug.println("Trying " + alt +
157 ((entries == null)?": does not exist.":": Found!"));
158 }
159 if (entries != null) {
160 break;
161 }
162 }
163
164 if (entries == null) {
165 if (debug != null) {
166 debug.println("Cannot read JGSS entry, use default values instead.");
167 }
168 entries = getDefaultConfigurationEntry();
169 }
170 return entries;
171 }
172
173 /**
174 * Default value for a caller-mech pair when no entry is defined in
175 * the system-wide Configuration object.
176 */
177 private AppConfigurationEntry[] getDefaultConfigurationEntry() {
178 HashMap <String, String> options = new HashMap <String, String> (2);
179
180 if (mechName == null || mechName.equals("krb5")) {
181 if (isServerSide(caller)) {
182 // Assuming the keytab file can be found through
183 // krb5 config file or under user home directory
184 options.put("useKeyTab", "true");
185 options.put("storeKey", "true");
186 options.put("doNotPrompt", "true");
187 options.put("isInitiator", "false");
188 } else {
189 options.put("useTicketCache", "true");
190 options.put("doNotPrompt", "false");
191 }
192 return new AppConfigurationEntry[] {
193 new AppConfigurationEntry(
194 "com.sun.security.auth.module.Krb5LoginModule",
195 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
196 options)
197 };
198 }
199 return null;
200 }
201
202 private static boolean isServerSide (int caller) {
203 return GSSUtil.CALLER_ACCEPT == caller ||
204 GSSUtil.CALLER_SSL_SERVER == caller;
205 }
206}