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