1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.james.transport.matchers;
23
24 import org.apache.avalon.cornerstone.services.datasources.DataSourceSelector;
25 import org.apache.avalon.excalibur.datasource.DataSourceComponent;
26 import org.apache.avalon.framework.service.ServiceManager;
27 import org.apache.james.Constants;
28 import org.apache.james.api.user.JamesUser;
29 import org.apache.james.api.user.UsersRepository;
30 import org.apache.james.transport.mailets.WhiteListManager;
31 import org.apache.james.util.sql.JDBCUtil;
32 import org.apache.james.util.sql.SqlResources;
33 import org.apache.mailet.base.GenericMatcher;
34 import org.apache.mailet.Mail;
35 import org.apache.mailet.MailAddress;
36
37 import javax.mail.MessagingException;
38
39 import java.io.File;
40 import java.sql.Connection;
41 import java.sql.PreparedStatement;
42 import java.sql.ResultSet;
43 import java.sql.SQLException;
44 import java.util.Collection;
45 import java.util.HashMap;
46 import java.util.Iterator;
47 import java.util.Locale;
48 import java.util.Map;
49 import java.util.StringTokenizer;
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public class IsInWhiteList extends GenericMatcher {
66
67 private String selectByPK;
68
69 private DataSourceComponent datasource;
70
71
72
73
74 private UsersRepository localusers;
75
76
77
78
79 private final JDBCUtil theJDBCUtil = new JDBCUtil() {
80 protected void delegatedLog(String logString) {
81 log("IsInWhiteList: " + logString);
82 }
83 };
84
85
86
87
88 private SqlResources sqlQueries = new SqlResources();
89
90
91
92
93 private File sqlFile;
94
95
96
97
98 private Map sqlParameters = new HashMap();
99
100
101
102
103
104 private Map getSqlParameters() {
105
106 return this.sqlParameters;
107 }
108
109
110
111
112 public void init() throws javax.mail.MessagingException {
113 String repositoryPath = null;
114 StringTokenizer st = new StringTokenizer(getCondition(), ", \t", false);
115 if (st.hasMoreTokens()) {
116 repositoryPath = st.nextToken().trim();
117 }
118 if (repositoryPath != null) {
119 log("repositoryPath: " + repositoryPath);
120 }
121 else {
122 throw new MessagingException("repositoryPath is null");
123 }
124
125 ServiceManager serviceManager = (ServiceManager) getMailetContext().getAttribute(Constants.AVALON_COMPONENT_MANAGER);
126
127 try {
128
129 DataSourceSelector datasources = (DataSourceSelector) serviceManager.lookup(DataSourceSelector.ROLE);
130
131 int stindex = repositoryPath.indexOf("://") + 3;
132 String datasourceName = repositoryPath.substring(stindex);
133 datasource = (DataSourceComponent) datasources.select(datasourceName);
134 } catch (Exception e) {
135 throw new MessagingException("Can't get datasource", e);
136 }
137
138 try {
139
140 localusers = (UsersRepository)serviceManager.lookup(UsersRepository.ROLE);
141 } catch (Exception e) {
142 throw new MessagingException("Can't get the local users repository", e);
143 }
144
145 try {
146 initSqlQueries(datasource.getConnection(), getMailetContext());
147 } catch (Exception e) {
148 throw new MessagingException("Exception initializing queries", e);
149 }
150
151 selectByPK = sqlQueries.getSqlString("selectByPK", true);
152 }
153
154
155
156
157 public Collection match(Mail mail) throws MessagingException {
158
159 MailAddress senderMailAddress = mail.getSender();
160 if (senderMailAddress == null) {
161 return null;
162 }
163 if (getMailetContext().isLocalEmail(senderMailAddress)) {
164
165 return null;
166 }
167
168 String senderUser = senderMailAddress.getUser();
169 String senderHost = senderMailAddress.getHost();
170
171 senderUser = senderUser.toLowerCase(Locale.US);
172 senderHost = senderHost.toLowerCase(Locale.US);
173
174 Collection recipients = mail.getRecipients();
175
176 Collection inWhiteList = new java.util.HashSet();
177
178 Connection conn = null;
179 PreparedStatement selectStmt = null;
180 ResultSet selectRS = null;
181 try {
182
183 for (Iterator i = recipients.iterator(); i.hasNext(); ) {
184 try {
185 MailAddress recipientMailAddress = (MailAddress)i.next();
186 String recipientUser = recipientMailAddress.getUser().toLowerCase(Locale.US);
187 String recipientHost = recipientMailAddress.getHost().toLowerCase(Locale.US);
188
189 if (!getMailetContext().isLocalServer(recipientHost)) {
190
191 continue;
192 }
193
194 recipientUser = getPrimaryName(recipientUser);
195
196 if (conn == null) {
197 conn = datasource.getConnection();
198 }
199
200 if (selectStmt == null) {
201 selectStmt = conn.prepareStatement(selectByPK);
202 }
203 selectStmt.setString(1, recipientUser);
204 selectStmt.setString(2, recipientHost);
205 selectStmt.setString(3, senderUser);
206 selectStmt.setString(4, senderHost);
207 selectRS = selectStmt.executeQuery();
208 if (selectRS.next()) {
209
210 inWhiteList.add(recipientMailAddress);
211 }
212
213 } finally {
214 theJDBCUtil.closeJDBCResultSet(selectRS);
215 }
216
217 }
218
219 return inWhiteList;
220
221 } catch (SQLException sqle) {
222 log("Error accessing database", sqle);
223 throw new MessagingException("Exception thrown", sqle);
224 } finally {
225 theJDBCUtil.closeJDBCStatement(selectStmt);
226 theJDBCUtil.closeJDBCConnection(conn);
227 }
228 }
229
230
231 private String getPrimaryName(String originalUsername) {
232 String username;
233 try {
234 username = localusers.getRealName(originalUsername);
235 JamesUser user = (JamesUser) localusers.getUserByName(username);
236 if (user.getAliasing()) {
237 username = user.getAlias();
238 }
239 }
240 catch (Exception e) {
241 username = originalUsername;
242 }
243 return username;
244 }
245
246
247
248
249
250
251
252
253
254
255
256
257 private void initSqlQueries(Connection conn, org.apache.mailet.MailetContext mailetContext) throws Exception {
258 try {
259 if (conn.getAutoCommit()) {
260 conn.setAutoCommit(false);
261 }
262
263 this.sqlFile = new File((String) mailetContext.getAttribute("confDir"), "sqlResources.xml").getCanonicalFile();
264 sqlQueries.init(this.sqlFile, "WhiteList" , conn, getSqlParameters());
265
266 } finally {
267 theJDBCUtil.closeJDBCConnection(conn);
268 }
269 }
270
271 }