001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.server.core.jndi;
021
022
023 import java.util.Hashtable;
024
025 import javax.naming.ConfigurationException;
026 import javax.naming.Context;
027 import javax.naming.NamingException;
028
029 import org.apache.directory.server.i18n.I18n;
030 import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
031 import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
032 import org.apache.directory.shared.ldap.name.DN;
033 import org.apache.directory.shared.ldap.util.StringTools;
034
035
036 /**
037 * A wrapper around a JNDI environment which checks for correct LDAP specific
038 * environment settings.
039 *
040 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
041 * @version $Rev: 924262 $
042 */
043 public class LdapJndiProperties
044 {
045 private static final String SASL_AUTHID = "java.naming.security.sasl.authorizationId";
046
047 private DN providerDn;
048 private DN bindDn;
049 private String saslAuthId;
050 private AuthenticationLevel level;
051 private String saslMechanism;
052 private byte[] credentials;
053
054
055 public static AuthenticationLevel getAuthenticationLevel( Hashtable env ) throws NamingException
056 {
057 AuthenticationLevel level;
058 Object credobj = env.get( Context.SECURITY_CREDENTIALS );
059 Object authentication = env.get( Context.SECURITY_AUTHENTICATION );
060
061 // -------------------------------------------------------------------
062 // Figure out and set the authentication level and mechanisms
063 // -------------------------------------------------------------------
064
065 if ( authentication == null )
066 {
067 // if the property is not set but Context.SECURITY_CREDENTIALS is then SIMPLE
068 if ( credobj == null )
069 {
070 level = AuthenticationLevel.NONE;
071 }
072 else
073 {
074 level = AuthenticationLevel.SIMPLE;
075 }
076 }
077 else if ( !( authentication instanceof String ) )
078 {
079 throw new ConfigurationException( I18n.err( I18n.ERR_483, authentication.getClass(),
080 Context.SECURITY_AUTHENTICATION ) );
081 }
082 else
083 {
084 if ( AuthenticationLevel.NONE.toString().equals( authentication ) )
085 {
086 level = AuthenticationLevel.NONE;
087 }
088 else if ( AuthenticationLevel.SIMPLE.toString().equals( authentication ) )
089 {
090 level = AuthenticationLevel.SIMPLE;
091 }
092 else
093 {
094 level = AuthenticationLevel.STRONG;
095 }
096 }
097
098 return level;
099 }
100
101
102 public static LdapJndiProperties getLdapJndiProperties( Hashtable env ) throws NamingException
103 {
104 if ( env == null )
105 {
106 throw new ConfigurationException( "environment cannot be null" );
107 }
108
109 LdapJndiProperties props = new LdapJndiProperties();
110 Object principal = env.get( Context.SECURITY_PRINCIPAL );
111 Object credobj = env.get( Context.SECURITY_CREDENTIALS );
112 Object authentication = env.get( Context.SECURITY_AUTHENTICATION );
113
114 // -------------------------------------------------------------------
115 // check for the provider URL property
116 // -------------------------------------------------------------------
117
118 if ( !env.containsKey( Context.PROVIDER_URL ) )
119 {
120 String msg = I18n.err( I18n.ERR_484, Context.PROVIDER_URL );
121 throw new ConfigurationException( msg );
122 }
123
124 String url = ( String ) env.get( Context.PROVIDER_URL );
125
126 if ( url == null )
127 {
128 String msg = I18n.err( I18n.ERR_485, Context.PROVIDER_URL );
129 throw new ConfigurationException( msg );
130 }
131
132 if ( url.trim().equals( "" ) )
133 {
134 props.providerDn = DN.EMPTY_DN;
135 }
136 else
137 {
138 try
139 {
140 props.providerDn = new DN( url );
141 }
142 catch ( LdapInvalidDnException lide )
143 {
144 String msg = I18n.err( I18n.ERR_733, url );
145 throw new ConfigurationException( msg );
146 }
147 }
148
149 // -------------------------------------------------------------------
150 // Figure out and set the authentication level and mechanisms
151 // -------------------------------------------------------------------
152
153 if ( authentication == null )
154 {
155 // if the property is not set but Context.SECURITY_CREDENTIALS is then SIMPLE
156 if ( credobj == null )
157 {
158 props.level = AuthenticationLevel.NONE;
159 }
160 else
161 {
162 props.level = AuthenticationLevel.SIMPLE;
163 }
164 }
165 else if ( !( authentication instanceof String ) )
166 {
167 throw new ConfigurationException( I18n.err( I18n.ERR_483, authentication.getClass(),
168 Context.SECURITY_AUTHENTICATION ) );
169 }
170 else
171 {
172 if ( AuthenticationLevel.NONE.toString().equals( authentication ) )
173 {
174 props.level = AuthenticationLevel.NONE;
175 }
176 else if ( AuthenticationLevel.SIMPLE.toString().equals( authentication ) )
177 {
178 props.level = AuthenticationLevel.SIMPLE;
179 }
180 else
181 {
182 props.level = AuthenticationLevel.STRONG;
183 props.saslMechanism = ( String ) authentication;
184 // String[] mechList = ( ( String ) authentication ).trim().split( " " );
185 // for ( String mech : mechList )
186 // {
187 // if ( !mech.trim().equals( "" ) )
188 // {
189 // props.mechanisms.add( mech );
190 // }
191 // }
192 }
193 }
194
195 // -------------------------------------------------------------------
196 // Figure out and set the security principal bindDn and saslAuthId
197 // -------------------------------------------------------------------
198
199 if ( principal == null && props.level == AuthenticationLevel.SIMPLE )
200 {
201 throw new ConfigurationException( I18n.err( I18n.ERR_487, Context.SECURITY_PRINCIPAL ) );
202 }
203 else if ( principal == null && props.level == AuthenticationLevel.NONE )
204 {
205 props.bindDn = DN.EMPTY_DN;
206 }
207 else if ( !( principal instanceof String ) )
208 {
209 throw new ConfigurationException( I18n.err( I18n.ERR_483, principal.getClass(), Context.SECURITY_PRINCIPAL ) );
210 }
211 else if ( ( ( String ) principal ).trim().equals( "" ) )
212 {
213 props.bindDn = DN.EMPTY_DN;
214 }
215 else
216 {
217 try
218 {
219 props.providerDn = new DN( ( String ) principal );
220 }
221 catch ( LdapInvalidDnException lide )
222 {
223 String msg = I18n.err( I18n.ERR_733, principal );
224 throw new ConfigurationException( msg );
225 }
226
227 }
228
229
230 if ( env.get( SASL_AUTHID ) != null && props.level == AuthenticationLevel.STRONG )
231 {
232 Object obj = env.get( SASL_AUTHID );
233 if ( obj instanceof String )
234 {
235 props.saslAuthId = ( String ) obj;
236 }
237 else
238 {
239 throw new ConfigurationException( I18n.err( I18n.ERR_483, obj.getClass(), SASL_AUTHID ) );
240 }
241 props.saslAuthId = ( String ) principal;
242 }
243
244 // -------------------------------------------------------------------
245 // Figure out the credentials
246 // -------------------------------------------------------------------
247
248 if ( props.level == AuthenticationLevel.SIMPLE && credobj == null )
249 {
250 throw new ConfigurationException( I18n.err( I18n.ERR_489 ) );
251 }
252 else if ( credobj != null )
253 {
254 if ( credobj instanceof String )
255 {
256 props.credentials = StringTools.getBytesUtf8( ( String ) credobj );
257 }
258 else if ( credobj instanceof byte[] )
259 {
260 props.credentials = ( byte[] ) credobj;
261 }
262 else
263 {
264 throw new ConfigurationException( I18n.err( I18n.ERR_483, credobj.getClass(), Context.SECURITY_CREDENTIALS ) );
265 }
266 }
267
268 return props;
269 }
270
271
272 public DN getBindDn()
273 {
274 return bindDn;
275 }
276
277
278 public DN getProviderDn()
279 {
280 return providerDn;
281 }
282
283
284 public String getSaslAuthId()
285 {
286 return saslAuthId;
287 }
288
289
290 public AuthenticationLevel getAuthenticationLevel()
291 {
292 return level;
293 }
294
295
296 public String getSaslMechanism()
297 {
298 return saslMechanism;
299 }
300
301
302 public byte[] getCredentials()
303 {
304 return credentials;
305 }
306 }