1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.geronimo.javamail.authentication;
19
20 import java.lang.reflect.Constructor;
21 import java.util.List;
22 import java.util.Properties;
23
24 import org.apache.geronimo.javamail.util.ProtocolProperties;
25
26 public class AuthenticatorFactory {
27 // the list of authentication mechanisms we have direct support for. Others come from
28 // SASL, if it's available.
29
30 public static final String AUTHENTICATION_PLAIN = "PLAIN";
31 public static final String AUTHENTICATION_LOGIN = "LOGIN";
32 public static final String AUTHENTICATION_CRAMMD5 = "CRAM-MD5";
33 public static final String AUTHENTICATION_DIGESTMD5 = "DIGEST-MD5";
34
35 static public ClientAuthenticator getAuthenticator(ProtocolProperties props, List mechanisms, String host, String username, String password, String authId, String realm)
36 {
37 // if the authorization id isn't given, then this is the same as the logged in user name.
38 if (authId == null) {
39 authId = username;
40 }
41
42 // if SASL is enabled, try getting a SASL authenticator first
43 if (props.getBooleanProperty("sasl.enable", false)) {
44 // we need to convert the mechanisms map into an array of strings for SASL.
45 String [] mechs = (String [])mechanisms.toArray(new String[mechanisms.size()]);
46
47 try {
48 // need to try to load this using reflection since it has references to
49 // the SASL API. That's only available with 1.5 or later.
50 Class authenticatorClass = Class.forName("org.apache.geronimo.javamal.authentication.SASLAuthenticator");
51 Constructor c = authenticatorClass.getConstructor(new Class[] {
52 (new String[0]).getClass(),
53 Properties.class,
54 String.class,
55 String.class,
56 String.class,
57 String.class,
58 String.class,
59 String.class
60 });
61
62 Object[] args = { mechs, props.getProperties(), props.getProtocol(), host, realm, authId, username, password };
63
64 return (ClientAuthenticator)c.newInstance(args);
65 } catch (Throwable e) {
66 // Any exception is likely because we're running on 1.4 and can't use the Sasl API.
67 // just ignore and use our fallback implementations.
68 }
69 }
70
71 // now go through the progression of mechanisms we support, from the
72 // most secure to the least secure.
73
74 if (mechanisms.contains(AUTHENTICATION_DIGESTMD5)) {
75 return new DigestMD5Authenticator(host, username, password, realm);
76 } else if (mechanisms.contains(AUTHENTICATION_CRAMMD5)) {
77 return new CramMD5Authenticator(username, password);
78 } else if (mechanisms.contains(AUTHENTICATION_LOGIN)) {
79 return new LoginAuthenticator(username, password);
80 } else if (mechanisms.contains(AUTHENTICATION_PLAIN)) {
81 return new PlainAuthenticator(username, password);
82 } else {
83 // can't find a mechanism we support in common
84 return null;
85 }
86 }
87 }
88