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