001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.javamail.authentication; 019 020 import java.lang.reflect.Constructor; 021 import java.util.List; 022 import java.util.Properties; 023 024 import org.apache.geronimo.javamail.util.ProtocolProperties; 025 026 public class AuthenticatorFactory { 027 // the list of authentication mechanisms we have direct support for. Others come from 028 // SASL, if it's available. 029 030 public static final String AUTHENTICATION_PLAIN = "PLAIN"; 031 public static final String AUTHENTICATION_LOGIN = "LOGIN"; 032 public static final String AUTHENTICATION_CRAMMD5 = "CRAM-MD5"; 033 public static final String AUTHENTICATION_DIGESTMD5 = "DIGEST-MD5"; 034 035 static public ClientAuthenticator getAuthenticator(ProtocolProperties props, List mechanisms, String host, String username, String password, String authId, String realm) 036 { 037 // if the authorization id isn't given, then this is the same as the logged in user name. 038 if (authId == null) { 039 authId = username; 040 } 041 042 // if SASL is enabled, try getting a SASL authenticator first 043 if (props.getBooleanProperty("sasl.enable", false)) { 044 // we need to convert the mechanisms map into an array of strings for SASL. 045 String [] mechs = (String [])mechanisms.toArray(new String[mechanisms.size()]); 046 047 try { 048 // need to try to load this using reflection since it has references to 049 // the SASL API. That's only available with 1.5 or later. 050 Class authenticatorClass = Class.forName("org.apache.geronimo.javamal.authentication.SASLAuthenticator"); 051 Constructor c = authenticatorClass.getConstructor(new Class[] { 052 (new String[0]).getClass(), 053 Properties.class, 054 String.class, 055 String.class, 056 String.class, 057 String.class, 058 String.class, 059 String.class 060 }); 061 062 Object[] args = { mechs, props.getProperties(), props.getProtocol(), host, realm, authId, username, password }; 063 064 return (ClientAuthenticator)c.newInstance(args); 065 } catch (Throwable e) { 066 // Any exception is likely because we're running on 1.4 and can't use the Sasl API. 067 // just ignore and use our fallback implementations. 068 } 069 } 070 071 // now go through the progression of mechanisms we support, from the 072 // most secure to the least secure. 073 074 if (mechanisms.contains(AUTHENTICATION_DIGESTMD5)) { 075 return new DigestMD5Authenticator(host, username, password, realm); 076 } else if (mechanisms.contains(AUTHENTICATION_CRAMMD5)) { 077 return new CramMD5Authenticator(username, password); 078 } else if (mechanisms.contains(AUTHENTICATION_LOGIN)) { 079 return new LoginAuthenticator(username, password); 080 } else if (mechanisms.contains(AUTHENTICATION_PLAIN)) { 081 return new PlainAuthenticator(username, password); 082 } else { 083 // can't find a mechanism we support in common 084 return null; 085 } 086 } 087 } 088