00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "SmtpdSocket.h"
00034 #include "Parse.h"
00035 #include "Utility.h"
00036
00037 #ifdef SOCKETS_NAMESPACE
00038 namespace SOCKETS_NAMESPACE {
00039 #endif
00040
00041 SmtpdSocket::SmtpdSocket(ISocketHandler& h)
00042 :TcpSocket(h)
00043 ,m_hello(false)
00044 ,m_data(false)
00045 ,m_header(false)
00046 {
00047 SetLineProtocol();
00048 }
00049
00050
00051 void SmtpdSocket::OnAccept()
00052 {
00053 Send("220 ESMTP; \r\n");
00054 }
00055
00056
00057 void SmtpdSocket::OnLine(const std::string& line)
00058 {
00059 if (m_data)
00060 {
00061 if (m_header)
00062 {
00063 if (!line.size())
00064 {
00065 if (m_header_line.size())
00066 {
00067 Parse pa(m_header_line, ":");
00068 std::string key = pa.getword();
00069 OnHeader(key, pa.getrest());
00070 }
00071 m_header = false;
00072 OnHeaderComplete();
00073 }
00074 else
00075 if (line[0] == ' ' || line[0] == '\t')
00076 {
00077 m_header_line += line;
00078 }
00079 else
00080 {
00081 if (m_header_line.size())
00082 {
00083 Parse pa(m_header_line, ":");
00084 std::string key = pa.getword();
00085 OnHeader(key, pa.getrest());
00086 }
00087 m_header_line = line;
00088 }
00089 }
00090 else
00091 if (line == ".")
00092 {
00093 m_data = false;
00094 if (OnDataComplete())
00095 Send("250 OK\r\n");
00096 else
00097 Send("550 Failed\r\n");
00098 }
00099 else
00100 if (line.size() && line[0] == '.')
00101 {
00102 OnData(line.substr(1));
00103 }
00104 else
00105 {
00106 OnData(line);
00107 }
00108 return;
00109 }
00110 Parse pa(line);
00111 std::string cmd = Utility::ToUpper(pa.getword());
00112
00113 if (cmd == "EHLO")
00114 {
00115 if (!OnHello(pa.getrest()))
00116 {
00117 Send("550 Failed\r\n");
00118 }
00119 else
00120 {
00121 m_hello = true;
00122 Send("250 mail.alhem.net\r\n");
00123 }
00124 }
00125 else
00126 if (cmd == "HELO")
00127 {
00128 if (!OnHello(pa.getrest()))
00129 {
00130 Send("550 Failed\r\n");
00131 }
00132 else
00133 {
00134 m_hello = true;
00135 Send("250 mail.alhem.net\r\n");
00136 }
00137 }
00138 else
00139 if (!m_hello)
00140 {
00141 OnAbort(SMTP_NO_HELLO);
00142 SetCloseAndDelete();
00143 }
00144 else
00145 if (cmd == "MAIL")
00146 {
00147 Parse pa(line, ":");
00148 pa.getword();
00149 pa.getword();
00150 std::string email = Utility::ToLower(pa.getrest());
00151
00152 EmailAddress addr( email );
00153 if (addr.GetName().size() > 64)
00154 {
00155 OnAbort(SMTP_NAME_TOO_LONG);
00156 Send("500 Name too long.\r\n");
00157 return;
00158 }
00159 if (addr.GetDomain().size() > 64)
00160 {
00161 OnAbort(SMTP_DOMAIN_TOO_LONG);
00162 Send("500 Domain too long.\r\n");
00163 return;
00164 }
00165
00166 if (!OnMailFrom( addr ))
00167 {
00168 Send("550 Failed\r\n");
00169 }
00170 else
00171 {
00172 Send("250 OK\r\n");
00173 }
00174 }
00175 else
00176 if (cmd == "RCPT")
00177 {
00178 Parse pa(line, ":");
00179 pa.getword();
00180 pa.getword();
00181 std::string email = Utility::ToLower(pa.getrest());
00182
00183 EmailAddress addr( email );
00184
00185 if (addr.GetName().size() > 64)
00186 {
00187 OnAbort(SMTP_NAME_TOO_LONG);
00188 Send("500 Name too long.\r\n");
00189 return;
00190 }
00191 if (addr.GetDomain().size() > 64)
00192 {
00193 OnAbort(SMTP_DOMAIN_TOO_LONG);
00194 Send("500 Domain too long.\r\n");
00195 return;
00196 }
00197
00198 if (!OnRcptTo( addr ))
00199 {
00200 Send("553 Failed\r\n");
00201 }
00202 else
00203 {
00204 Send("250 OK\r\n");
00205 }
00206 }
00207 else
00208 if (cmd == "DATA")
00209 {
00210 Send("354 Enter mail, end with \".\" on a line by itself\r\n");
00211 m_data = true;
00212 m_header = false;
00213 }
00214 else
00215 if (cmd == "RSET")
00216 {
00217 m_data = false;
00218 m_header = false;
00219 OnRset();
00220 Send("250 OK\r\n");
00221 }
00222 else
00223 if (cmd == "QUIT")
00224 {
00225 OnAbort(SMTP_QUIT);
00226 Send("221 Bye Bye\r\n");
00227 SetCloseAndDelete();
00228 }
00229 else
00230 if (cmd == "NOOP")
00231 {
00232 Send("250 OK\r\n");
00233 }
00234 else
00235 {
00236 OnNotSupported(cmd, pa.getrest());
00237 }
00238 }
00239
00240
00241 #ifdef SOCKETS_NAMESPACE
00242 }
00243 #endif
00244