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