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.naming.factory;
19
20 import java.security.AccessController;
21 import java.security.PrivilegedAction;
22 import java.util.Enumeration;
23 import java.util.Hashtable;
24 import java.util.Properties;
25 import javax.mail.Authenticator;
26 import javax.mail.PasswordAuthentication;
27 import javax.mail.Session;
28 import javax.naming.Name;
29 import javax.naming.Context;
30 import javax.naming.RefAddr;
31 import javax.naming.Reference;
32 import javax.naming.spi.ObjectFactory;
33
34 /**
35 * <p>Factory class that creates a JNDI named JavaMail Session factory,
36 * which can be used for managing inbound and outbound electronic mail
37 * messages via JavaMail APIs. All messaging environment properties
38 * described in the JavaMail Specification may be passed to the Session
39 * factory; however the following properties are the most commonly used:</p>
40 * <ul>
41 * <li>
42 * <li><strong>mail.smtp.host</strong> - Hostname for outbound transport
43 * connections. Defaults to <code>localhost</code> if not specified.</li>
44 * </ul>
45 *
46 * <p>This factory can be configured in a <code><DefaultContext></code>
47 * or <code><Context></code> element in your <code>conf/server.xml</code>
48 * configuration file. An example of factory configuration is:</p>
49 * <pre>
50 * <Resource name="mail/smtp" auth="CONTAINER"
51 * type="javax.mail.Session"/>
52 * <ResourceParams name="mail/smtp">
53 * <parameter>
54 * <name>factory</name>
55 * <value>org.apache.naming.factory.MailSessionFactory</value>
56 * </parameter>
57 * <parameter>
58 * <name>mail.smtp.host</name>
59 * <value>mail.mycompany.com</value>
60 * </parameter>
61 * </ResourceParams>
62 * </pre>
63 *
64 * @author Craig R. McClanahan
65 * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
66 */
67
68 public class MailSessionFactory implements ObjectFactory {
69
70
71 /**
72 * The Java type for which this factory knows how to create objects.
73 */
74 protected static final String factoryType = "javax.mail.Session";
75
76
77 /**
78 * Create and return an object instance based on the specified
79 * characteristics.
80 *
81 * @param refObj Reference information containing our parameters, or null
82 * if there are no parameters
83 * @param name The name of this object, relative to context, or null
84 * if there is no name
85 * @param context The context to which name is relative, or null if name
86 * is relative to the default initial context
87 * @param env Environment variables, or null if there are none
88 *
89 * @exception Exception if an error occurs during object creation
90 */
91 public Object getObjectInstance(Object refObj, Name name, Context context,
92 Hashtable env) throws Exception
93 {
94
95 // Return null if we cannot create an object of the requested type
96 final Reference ref = (Reference) refObj;
97 if (!ref.getClassName().equals(factoryType))
98 return (null);
99
100 // Create a new Session inside a doPrivileged block, so that JavaMail
101 // can read its default properties without throwing Security
102 // exceptions.
103 //
104 // Bugzilla 31288, 33077: add support for authentication.
105 return AccessController.doPrivileged( new PrivilegedAction() {
106 public Object run() {
107
108 // Create the JavaMail properties we will use
109 Properties props = new Properties();
110 props.put("mail.transport.protocol", "smtp");
111 props.put("mail.smtp.host", "localhost");
112
113 String password = null;
114
115 Enumeration attrs = ref.getAll();
116 while (attrs.hasMoreElements()) {
117 RefAddr attr = (RefAddr) attrs.nextElement();
118 if ("factory".equals(attr.getType())) {
119 continue;
120 }
121
122 if ("password".equals(attr.getType())) {
123 password = (String) attr.getContent();
124 continue;
125 }
126
127 props.put(attr.getType(), (String) attr.getContent());
128 }
129
130 Authenticator auth = null;
131 if (password != null) {
132 String user = props.getProperty("mail.smtp.user");
133 if(user == null) {
134 user = props.getProperty("mail.user");
135 }
136
137 if(user != null) {
138 final PasswordAuthentication pa = new PasswordAuthentication(user, password);
139 auth = new Authenticator() {
140 protected PasswordAuthentication getPasswordAuthentication() {
141 return pa;
142 }
143 };
144 }
145 }
146
147 // Create and return the new Session object
148 Session session = Session.getInstance(props, auth);
149 return (session);
150
151 }
152 } );
153
154 }
155
156
157 }