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.axis2.transport.mail.server;
021:
022: import org.apache.axis2.context.ConfigurationContext;
023: import org.apache.axis2.transport.mail.Constants;
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026:
027: import javax.mail.Authenticator;
028: import javax.mail.Message;
029: import javax.mail.MessagingException;
030: import javax.mail.PasswordAuthentication;
031: import javax.mail.Session;
032: import javax.mail.internet.MimeMessage;
033: import java.io.BufferedReader;
034: import java.io.BufferedWriter;
035: import java.io.IOException;
036: import java.io.InputStreamReader;
037: import java.io.OutputStreamWriter;
038: import java.net.Socket;
039: import java.util.ArrayList;
040: import java.util.Properties;
041:
042: public class SMTPWorker extends Thread {
043: private BufferedReader reader = null;
044: private BufferedWriter writer = null;
045: private boolean transmitionEnd = false;
046: private String temp = "";
047: private Storage st = null;
048: boolean runThread = true;
049: private ArrayList receivers = new ArrayList();
050: private MimeMessage mail = null;
051: private static final Log log = LogFactory.getLog(SMTPWorker.class);
052: private boolean dataWriting = false;
053: private ConfigurationContext configurationContext = null;
054: private boolean bodyData = false;
055: private boolean actAsMailet = false;
056:
057: public SMTPWorker(Socket socket, Storage st) {
058: doWork(socket, st, null);
059: }
060:
061: public SMTPWorker(Socket socket, Storage st,
062: ConfigurationContext configurationContext) {
063: doWork(socket, st, configurationContext);
064: }
065:
066: private void doWork(Socket socket, Storage st,
067: ConfigurationContext configurationContext) {
068: try {
069: this .st = st;
070:
071: if (configurationContext == null) {
072: actAsMailet = false;
073: } else {
074: this .configurationContext = configurationContext;
075: actAsMailet = true;
076: }
077:
078: // get the streams from the socket and save in instance variables.
079: reader = new BufferedReader(new InputStreamReader(socket
080: .getInputStream()));
081: writer = new BufferedWriter(new OutputStreamWriter(socket
082: .getOutputStream()));
083: } catch (IOException ex) {
084: log.info(ex.getMessage());
085: }
086: }
087:
088: // transmission is over. setting to exit
089: private void exitWorker() throws IOException {
090: reader.close();
091: writer.close();
092: runThread = false;
093: }
094:
095: // initializing the client by sending the initial message.
096: private void initializeClient() throws IOException {
097: if (writer != null) {
098: send("220 SMTP Server IS UP");
099: }
100: }
101:
102: private String processInput(String input) {
103: if (input == null) {
104: return Constants.COMMAND_UNKNOWN;
105: }
106:
107: if ((mail != null) && transmitionEnd) {
108: return Constants.COMMAND_TRANSMISSION_END;
109: }
110:
111: if (input.startsWith("MAIL")) {
112: mail = new MimeMessage(Session.getInstance(
113: new Properties(), new Authenticator() {
114: protected PasswordAuthentication getPasswordAuthentication() {
115: return null;
116: }
117: }));
118:
119: int start = input.indexOf("<") + 1;
120: int end;
121:
122: if (start <= 0) {
123: start = input.indexOf("FROM:") + 5;
124: end = input.length();
125: } else {
126: end = input.indexOf(">");
127: }
128:
129: String from = input.substring(start, end);
130:
131: if ((from != null) && from.trim().length() != 0) {
132:
133: // TODO this is an ugly hack to get the from address in. There
134: // should be a better way to do this.
135: MailAddress mailFrom[] = new MailAddress[1];
136:
137: mailFrom[0] = new MailAddress(from);
138:
139: try {
140: mail.addFrom(mailFrom);
141: } catch (MessagingException e) {
142: log.info(e.getMessage());
143: }
144: }
145:
146: return Constants.MAIL_OK;
147: }
148:
149: if (input.startsWith("HELO")) {
150: return Constants.HELO_REPLY;
151: } else if (input.startsWith("RCPT")) {
152:
153: int start = input.indexOf("<") + 1;
154: int end;
155:
156: if (start <= 0) {
157: start = input.indexOf("TO:") + 3;
158: /*
159: * if(!input.endsWith(domain)){ System.out.println("ERROR: wrong
160: * donmain name"); return Constants.RCPT_ERROR; }
161: */
162: } else {
163:
164: /*
165: * if(!input.endsWith(domain + ">")){ System.out.println("ERROR:
166: * wrong donmain name"); return Constants.RCPT_ERROR; }
167: */
168: }
169:
170: end = input.indexOf(">");
171:
172: String toStr = input.substring(start, end);
173:
174: try {
175: mail.addRecipient(Message.RecipientType.TO,
176: new MailAddress(toStr));
177: receivers.add(toStr);
178: } catch (MessagingException e) {
179: log.info(e.getMessage());
180: }
181:
182: return Constants.RCPT_OK;
183: } else if (input.equalsIgnoreCase("DATA")) {
184: dataWriting = true;
185:
186: return Constants.DATA_START_SUCCESS;
187: } else if (input.equalsIgnoreCase("QUIT")) {
188: dataWriting = true;
189: transmitionEnd = true;
190:
191: return Constants.COMMAND_TRANSMISSION_END;
192: } else if (input.equals(".")) {
193: dataWriting = false;
194:
195: return Constants.DATA_END_SUCCESS;
196: } else if (input.length() == 0 && !bodyData) {
197: bodyData = true;
198:
199: return null;
200: } else if ((mail != null) && dataWriting) {
201: try {
202: if (bodyData) {
203: temp += input;
204: mail.setContent(temp, "text/xml"); //Since this is for axis2 :-)
205: } else {
206: mail.addHeaderLine(input);
207: }
208: } catch (MessagingException e) {
209: log.info(e.getMessage());
210: }
211:
212: return null;
213: } else {
214: return Constants.COMMAND_UNKNOWN;
215: }
216: }
217:
218: // running the thread
219: public void run() {
220: try {
221:
222: // do initial transmission.
223: initializeClient();
224:
225: // analyze all the inputs from client and work accordingly.
226: while (runThread) {
227: String input = null;
228:
229: // get client input
230: input = reader.readLine();
231:
232: String retString = processInput(input);
233:
234: if (Constants.COMMAND_EXIT.equals(retString)) {
235: exitWorker();
236: } else {
237: if (retString != null) {
238: send(retString); // Send the reply
239: }
240:
241: if ((mail != null) && transmitionEnd) {
242: exitWorker();
243: }
244: }
245: }
246:
247: for (int idx = 0; idx < receivers.size(); idx++) {
248: try {
249: MailSorter mSort = null;
250:
251: if (actAsMailet) {
252: mSort = new MailSorter(this .st,
253: this .configurationContext);
254: } else {
255: mSort = new MailSorter(this .st, null);
256: }
257:
258: mSort.sort((String) receivers.get(idx),
259: new MimeMessage(mail));
260: } catch (MessagingException e1) {
261: log.info(e1.getMessage());
262:
263: // e1.printStackTrace();
264: }
265: }
266:
267: //
268: } catch (IOException e) {
269: log.info("ERROR: CLIENT CLOSED THE SOCKET");
270: }
271: }
272:
273: private void send(String s) throws IOException {
274: writer.write(s);
275: writer.newLine();
276: writer.flush();
277: }
278: }
|