2 * Dumbster: a dummy SMTP server.
\r
3 * Copyright (C) 2003, Jason Paul Kitchen
\r
4 * lilnottsman@yahoo.com
\r
6 * This library is free software; you can redistribute it and/or
\r
7 * modify it under the terms of the GNU Lesser General Public
\r
8 * License as published by the Free Software Foundation; either
\r
9 * version 2.1 of the License, or (at your option) any later version.
\r
11 * This library is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
14 * Lesser General Public License for more details.
\r
16 * You should have received a copy of the GNU Lesser General Public
\r
17 * License along with this library; if not, write to the Free Software
\r
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
20 package com.dumbster.smtp;
\r
23 * Contains an SMTP client request.
\r
25 public class SmtpRequest {
\r
27 /** SMTP action received from client. */
\r
28 private SmtpActionType action;
\r
30 /** Current state of the SMTP state table. */
\r
31 private SmtpState state;
\r
33 /** Additional information passed from the client with the SMTP action. */
\r
34 private String params;
\r
37 * Create a new SMTP client request.
\r
38 * @param actionType type of action/command
\r
39 * @param params remainder of command line once command is removed
\r
40 * @param state current SMTP server state
\r
42 public SmtpRequest(SmtpActionType actionType, String params, SmtpState state) {
\r
43 this.action = actionType;
\r
45 this.params = params;
\r
49 * Execute the SMTP request returning a response. This method models the state transition table for the SMTP server.
\r
50 * @return reponse to the request
\r
52 public SmtpResponse execute() {
\r
53 SmtpResponse response = null;
\r
54 if (action.isStateless()) {
\r
55 if (SmtpActionType.EXPN == action || SmtpActionType.VRFY == action) {
\r
56 response = new SmtpResponse(252, "Not supported", this.state);
\r
57 } else if (SmtpActionType.HELP == action) {
\r
58 response = new SmtpResponse(211, "No help available", this.state);
\r
59 } else if (SmtpActionType.NOOP == action) {
\r
60 response = new SmtpResponse(250, "OK", this.state);
\r
61 } else if (SmtpActionType.VRFY == action) {
\r
62 response = new SmtpResponse(252, "Not supported", this.state);
\r
63 } else if (SmtpActionType.RSET == action) {
\r
64 response = new SmtpResponse(250, "OK", SmtpState.GREET);
\r
66 response = new SmtpResponse(500, "Command not recognized", this.state);
\r
68 } else { // Stateful commands
\r
69 if (SmtpActionType.CONNECT == action) {
\r
70 if (SmtpState.CONNECT == state) {
\r
71 response = new SmtpResponse(220, "localhost Dumbster SMTP service ready",
\r
74 response = new SmtpResponse(503, "Bad sequence of commands: " + action,
\r
77 } else if (SmtpActionType.EHLO == action) {
\r
78 if (SmtpState.GREET == state) {
\r
79 response = new SmtpResponse(250, "OK", SmtpState.MAIL);
\r
81 response = new SmtpResponse(503, "Bad sequence of commands: " + action,
\r
84 } else if (SmtpActionType.MAIL == action) {
\r
85 if (SmtpState.MAIL == state) {
\r
86 response = new SmtpResponse(250, "OK", SmtpState.RCPT);
\r
88 response = new SmtpResponse(503, "Bad sequence of commands: " + action,
\r
91 } else if (SmtpActionType.RCPT == action) {
\r
92 if (SmtpState.RCPT == state) {
\r
93 response = new SmtpResponse(250, "OK", this.state);
\r
95 response = new SmtpResponse(503, "Bad sequence of commands: " + action,
\r
98 } else if (SmtpActionType.DATA == action) {
\r
99 if (SmtpState.RCPT == state) {
\r
100 response = new SmtpResponse(354, "Start mail input; end with <CRLF>.<CRLF>",
\r
101 SmtpState.DATA_HDR);
\r
103 response = new SmtpResponse(503, "Bad sequence of commands: " + action,
\r
106 } else if (SmtpActionType.UNRECOG == action) {
\r
107 if (SmtpState.DATA_HDR == state || SmtpState.DATA_BODY == state) {
\r
108 response = new SmtpResponse(-1, "", this.state);
\r
110 response = new SmtpResponse(503, "Bad sequence of commands: " + action,
\r
113 } else if (SmtpActionType.DATA_END == action) {
\r
114 if (SmtpState.DATA_HDR == state || SmtpState.DATA_BODY == state) {
\r
115 response = new SmtpResponse(250, "OK", SmtpState.QUIT);
\r
117 response = new SmtpResponse(503, "Bad sequence of commands: " + action,
\r
120 } else if (SmtpActionType.BLANK_LINE == action) {
\r
121 if (SmtpState.DATA_HDR == state) {
\r
122 response = new SmtpResponse(-1, "", SmtpState.DATA_BODY);
\r
123 } else if (SmtpState.DATA_BODY == state) {
\r
124 response = new SmtpResponse(-1, "", this.state);
\r
126 response = new SmtpResponse(503, "Bad sequence of commands: " + action,
\r
129 } else if (SmtpActionType.QUIT == action) {
\r
130 if (SmtpState.QUIT == state) {
\r
131 response = new SmtpResponse(250, "OK", SmtpState.CONNECT);
\r
133 response = new SmtpResponse(503, "Bad sequence of commands: " + action,
\r
137 response = new SmtpResponse(500, "Command not recognized", this.state);
\r
144 * Create an SMTP request object given a line of the input stream from the client and the current internal state.
\r
145 * @param s line of input
\r
146 * @param state current state
\r
147 * @return a populated SmtpRequest object
\r
149 public static SmtpRequest createRequest(String s, SmtpState state) {
\r
150 SmtpActionType action = null;
\r
151 String params = null;
\r
153 if (state == SmtpState.DATA_HDR) {
\r
154 if (s.equals(".")) {
\r
155 action = SmtpActionType.DATA_END;
\r
156 } else if (s.length() < 1) {
\r
157 action = SmtpActionType.BLANK_LINE;
\r
159 action = SmtpActionType.UNRECOG;
\r
162 } else if (state == SmtpState.DATA_BODY) {
\r
163 if (s.equals(".")) {
\r
164 action = SmtpActionType.DATA_END;
\r
166 action = SmtpActionType.UNRECOG;
\r
167 if (s.length() < 1) {
\r
174 String su = s.toUpperCase();
\r
175 if (su.startsWith("EHLO ") || su.startsWith("HELO")) {
\r
176 action = SmtpActionType.EHLO;
\r
177 params = s.substring(5);
\r
178 } else if (su.startsWith("MAIL FROM:")) {
\r
179 action = SmtpActionType.MAIL;
\r
180 params = s.substring(10);
\r
181 } else if (su.startsWith("RCPT TO:")) {
\r
182 action = SmtpActionType.RCPT;
\r
183 params = s.substring(8);
\r
184 } else if (su.startsWith("DATA")) {
\r
185 action = SmtpActionType.DATA;
\r
186 } else if (su.startsWith("QUIT")) {
\r
187 action = SmtpActionType.QUIT;
\r
188 } else if (su.startsWith("RSET")) {
\r
189 action = SmtpActionType.RSET;
\r
190 } else if (su.startsWith("NOOP")) {
\r
191 action = SmtpActionType.NOOP;
\r
192 } else if (su.startsWith("EXPN")) {
\r
193 action = SmtpActionType.EXPN;
\r
194 } else if (su.startsWith("VRFY")) {
\r
195 action = SmtpActionType.VRFY;
\r
196 } else if (su.startsWith("HELP")) {
\r
197 action = SmtpActionType.HELP;
\r
201 SmtpRequest req = new SmtpRequest(action, params, state);
\r
206 * Get the parameters of this request (remainder of command line once the command is removed.
\r
207 * @return parameters
\r
209 public String getParams() {
\r