Exemplo n.º 1
0
 //-------------------------------------------------------------------------------------------
 public ArrayList CheckRCPT(SmtpClient smtpclient, Address address, bool AllowRelay)
 {
     if (AuthorizeRCPT != null)
         return AuthorizeRCPT(smtpclient, address, AllowRelay);
     else
         return null;
 }
Exemplo n.º 2
0
        //--------------------------------------------------------------------------------------------
        /// <summary>
        /// This is where 90% of the magic happens. Once the SmtpClient is issued a recipient's address this event is
        /// triggered and handles the address to return an address list which specifies how to route the incoming message.
        /// </summary>
        /// <param name="smtpclient">This is the client triggering the authorization event.</param>
        /// <param name="address">This is the address being verified.</param>
        /// <param name="AllowRelay">This states whether or not the client is allowed to relay. (i.e. if the address is not local, then
        /// an address should be added to the address list to route the message to the remote server.</param>
        /// <returns>This event should return an address list that contains routing instructions for the message.</returns>
        private ArrayList server_AuthorizeRCPT(SmtpClient smtpclient, Address mailaddress, bool AllowRelay)
        {
            string sql = "";
               ArrayList al = new ArrayList();

               ADODB.Recordset rs = null;
               if (!DBOpen())
               {
                    Address address = new Address();
                    address.SetAddress(mailaddress.address);
                    DebugOut("Database connection error, e-mail rejected.", true);
                    address.EndPoint = AddressEndPointStatus.Bad;
                    address.Error = "There is a problem on our side, we can not accept your mail due to a database connection error.";
                    al.Add(address);
                    return al;
               }

               try
               {
                    sql = String.Format(sqldomaincheck, mailaddress.domain);
                    rs = Query(sql);

                    if (rs.EOF && AllowRelay)
                    {
                         Address address = new Address();
                         address.SetAddress(mailaddress.address);
                         address.Path = address.address;
                         address.EndPoint = AddressEndPointStatus.Forward;
                         al.Add(address);
                         return al;
                    }
                    else if (rs.EOF && !AllowRelay)
                    {
                         Address address = new Address();
                         address.SetAddress(mailaddress.address);
                         address.Error = "This server is rejecting your mail because it is not an authority for the end address to which you are trying to send to and/or you are not authenticated for relay.";
                         address.EndPoint = AddressEndPointStatus.Bad;
                         al.Add(address);
                         return al;
                    }

                    while (!rs.EOF)
                    {
                         Address address = new Address();
                         address.SetAddress(mailaddress.address);
                         switch (Int32.Parse(rs.get_Collect("status").ToString()))
                         {
                              #region Case BLOCKED
                              case (int)Status.Blocked: //domain disabled
                                   address.EndPoint = AddressEndPointStatus.Bad;
                                   address.Error = "This server is not allowed to handle mail to this address and therefore can not accept your mail.";
                                   al.Add(address);
                                   return al;
                              #endregion

                              #region Case NORMAL
                              case (int)Status.Normal:	//normal operation
                                   address = null;
                                   // address.EndPoint	= AddressEndPoint.Local;
                                   break;
                              #endregion

                              #region Case REMOTE
                              case (int)AddressEndPointStatus.Remote: // forward mail to specified server
                                   address.EndPoint = AddressEndPointStatus.Remote;
                                   address.Server = rs.get_Collect("misc").ToString();
                                   al.Add(address);
                                   return al;
                              #endregion

                              #region Case FORWARD
                              case (int)AddressEndPointStatus.Forward:
                                   address.Path = rs.get_Collect("misc").ToString();
                                   address.EndPoint = AddressEndPointStatus.Forward;
                                   al.Add(address);
                                   return al;
                              #endregion

                              #region Case DEFAULT
                              default:
                                   address.Error = "Server is misconfigured for this domain and therefore can not accept any mail.";
                                   DebugOut("Domain status settings for " + address.domain + " are not set properly please check them again.", true);
                                   al.Add(address);
                                   return al;
                              #endregion
                         }
                         rs.MoveNext();
                    }

                    string disposableprefix = "<#IGNORE#>";
                    bool prefixfound = false;
                    bool disposablefound = false;

                    if (mailaddress.prefix.IndexOf("-") > 0 && mailaddress.prefix.Length > mailaddress.prefix.IndexOf("-"))
                         disposableprefix = mailaddress.prefix.Substring(0, mailaddress.prefix.IndexOf("-"));

                    sql = String.Format(sqladdressa, mailaddress.prefix, mailaddress.domain, disposableprefix);
                    rs = Query(sql);

                    if (rs.EOF)
                    {
                         Address address = new Address();
                         address.EndPoint = AddressEndPointStatus.Bad;
                         address.Error = "The address belongs to this server but no mail box for it exists. (" + mailaddress.address + ")";
                         al.Add(address);
                         return al;
                    }
                    while (!rs.EOF)
                    {
                         string prefix = rs.Fields["prefix"].Value.ToString().ToLower();
                         string astatus = rs.Fields["status"].Value.ToString();
                         int status = (int)rs.Fields["status"].Value;
                         if (prefix == mailaddress.prefix.ToLower())
                         {
                              prefixfound = true;
                         }

                         if (prefix == disposableprefix && status == 7)
                         {
                              disposablefound = true;
                         }
                         rs.MoveNext();
                    }
                    rs.MoveFirst();

                    int rowcount = 0;
                    while (!rs.EOF)
                    {
                         rowcount++;

                         string prefix = rs.Fields["prefix"].Value.ToString();
                         string misc = rs.Fields["misc"].Value.ToString();

                         if ((prefixfound || disposablefound) && prefix == "*")
                         {
                              rs.MoveNext();
                              continue;
                         }
                         else if (prefixfound && prefix == disposableprefix)
                         {
                              rs.MoveNext();
                              continue;
                         }

                         ADODB.Recordset rsb = null;

                         Address address = new Address();
                         address.SetAddress(mailaddress.address);

                         sql = "";
                         switch (Int32.Parse(rs.get_Collect("status").ToString()))
                         {
                              case (int)Status.Blocked:
                                   if (!(misc == "ignore" && prefix == disposableprefix))
                                   {
                                        address.EndPoint = AddressEndPointStatus.Blocked;
                                        address.Error = "This user's mail box has been disabled.";
                                        al.Add(address);
                                   }
                                   else
                                   {
                                        address = null;
                                   }
                                   break;

                              case (int)Status.Normal:
                                   sql = String.Format(sqladdressb, rs.get_Collect("mailboxid").ToString());
                                   rsb = Query(sql);
                                   address.EndPoint = AddressEndPointStatus.Local;
                                   address.quota = Decimal.Parse(rsb.Fields["quota"].Value.ToString());
                                   address.Path = server.MailPath + rsb.Fields["postoffice"].Value.ToString() + "\\" + rsb.Fields["mailbox"].Value.ToString() + "\\";
                                   al.Add(address);
                                   break;

                              case (int)Status.Forward:
                                   string fmisc = rs.Fields["misc"].Value.ToString().Replace(" ", "");
                                   address.EndPoint = AddressEndPointStatus.Forward;
                                   address.Path = fmisc;
                                   al.Add(address);
                                   break;

                              case (int)Status.Execute:
                                   sql = String.Format(sqladdressb, rs.get_Collect("mailboxid").ToString());
                                   rs = Query(sql);
                                   address.quota = Decimal.Parse(rs.get_Collect("quota").ToString());
                                   address.EndPoint = AddressEndPointStatus.Plugin;
                                   address.Path = server.MailPath + rs.Fields["postoffice"].Value.ToString() + "\\" + rs.Fields["mailbox"].Value + "\\";

                                   al.Add(address);
                                   break;

                              case (int)AddressEndPointStatus.AutoRespond:
                                   break;

                              case (int)AddressEndPointStatus.Disposable:
                                   //no action - just a pointer record
                                   break;

                              case (int)Status.Remote:
                                   string rmisc = rs.Fields["misc"].Value.ToString().Trim();

                                   address.EndPoint = AddressEndPointStatus.Remote;
                                   address.Path = rmisc;

                                   al.Add(address);
                                   break;

                              case (int)Status.SMS:
                                   sql = String.Format(sqlsms, rs.Fields["smsserviceid"].Value.ToString());
                                   rsb = Query(sql);
                                   if (!rsb.EOF)
                                   {
                                        switch (Int32.Parse(rsb.Fields["type"].Value.ToString()))
                                        {
                                             case 1:
                                                  address.EndPoint = AddressEndPointStatus.SMS;
                                                  address.Path = rs.Fields["misc"].Value.ToString() + "@" + rsb.Fields["misc"].Value.ToString();

                                                  al.Add(address);
                                                  break;

                                             case 2:
                                                  address.EndPoint = AddressEndPointStatus.Forward;
                                                  address.Path = rs.Fields["misc"].Value.ToString() + "@" + rsb.Fields["misc"].Value.ToString();

                                                  al.Add(address);
                                                  break;

                                             case 3:
                                                  address.EndPoint = AddressEndPointStatus.Plugin;
                                                  address.Path = rsb.Fields["misc"].Value.ToString();

                                                  al.Add(address);
                                                  break;
                                        }
                                   }
                                   break;

                              default:
                                   DebugOut("The status set for " + address.address + " is invalid. E-mail to this address was rejected, please fix it.", true);
                                   address.EndPoint = AddressEndPointStatus.Bad;
                                   address.Error = "The mailbox you are trying to reach does exist for this user however it is incorrectly configured and we are forced to reject your e-mail.";

                                   al.Add(address);
                                   break;
                         }
                         rs.MoveNext();
                    }

                    if (rowcount == 0)
                    {
                         Address address = new Address();
                         address.SetAddress(mailaddress.address);
                         address.Error = "This server is authoritive for the domain that you are trying to send an e-mail to, however the mailbox that you are trying to reach does not exist on this server!";
                         address.EndPoint = AddressEndPointStatus.Bad;
                         al.Add(address);
                    }
                    return al;
               }
               catch (Exception e)
               {
                    Address address = new Address();
                    address.SetAddress(mailaddress.address);
                    DebugOut("User check against database failed for " + mailaddress.address + ".\r\n\r\n" + e.Message, true);
                    address.Error = "This server can not accept your e-mail due to a local database error.";
                    address.EndPoint = AddressEndPointStatus.Bad;
                    al.Add(address);
                    return al;
               }
        }
Exemplo n.º 3
0
        //-------------------------------------------------------------------------------------------
        public void HandleData(string pData)
        {
            #region Parse Int
            int iSub	= (pData.Length > 4) ? 4 : pData.Length;
            #endregion

            switch (pData.Substring(0, iSub).ToUpper())
            {
                #region Case HELO
                case "HELO":
                    myData.iState = 1;
                         Send("250 Welcome to our server, spam is not welcome here." + newline);
                    break;
                #endregion

                #region Case EHLO
                case "EHLO":
                    myData.iState = 3;
                         Send("250-" + Parent.ServerName + " Weavver.Net.Mail - www.weavver.com" + newline);
                         Send("250-AUTH LOGIN" + newline);
                         Send("250 AUTH=LOGIN" + newline);
                    break;
                #endregion

                #region Case AUTH
                case "AUTH":
                    myData.iState = 10;
                    Send("334 VXNlcm5hbWU6" + newline);
                    break;
                    #endregion

                #region Case MAIL
                case "MAIL":
                    if (myData.iState == 1 || myData.iState == 3 || myData.iState > 9)
                    {
                        if (pData.IndexOf("<") > 0)
                        {
                            myData.MailFrom = pData.Substring(pData.IndexOf("<") + 1);
                            myData.MailFrom = myData.MailFrom.Trim().Replace(">", "");

                            myData.iState	= 2;
                            bool allow		= Parent.CheckMAIL(this, myData.MailFrom);

                            if (!allow)
                            {
                                Send("503 Permission denied.\r\n");
                            }
                            else
                            {
                                if (myData.MailFrom == "")
                                             Send("250 2.1.5 NULL SENDER OK:" + newline);
                                else
                                             Send("250 2.1.5 Continue:" + newline);
                            }
                        }
                        else
                        {
                            Send("503 Invalid MAIL command, please use this format -> MAIL FROM: <you@domain> <CRLF>" + newline);
                        }
                    }
                    else
                    {
                        Send("503 Out of sequence" + newline);
                    }
                    break;
                #endregion

                #region Case RCPT
                case "RCPT":
                    if (myData.iState > 1 && myData.iState < 10)
                    {
                        if (pData.IndexOf("<") > 0)
                        {
                            Address address		= new Address();

                            myData.Temp			= pData.Substring(pData.IndexOf("<") + 1);

                            address.SetAddress(myData.Temp.Replace(">", "").Trim());

                            ArrayList al		= Parent.CheckRCPT(this, address, myData.bForward);
                            if (al.Count == 0)
                            {
                                address			= new Address();
                                address.EndPoint	= AddressEndPointStatus.Bad;
                            }
                            for (int i = 0; i < al.Count; i++)
                            {
                                address						= (Address) al[i];
                                if (	address.EndPoint	== AddressEndPointStatus.Bad
                                    ||	address.EndPoint	== AddressEndPointStatus.Blocked)
                                {
                                    address = (Address) al[i];

                                    if (i == al.Count && al.Count > 0)
                                        address = (Address) al[0];
                                    break;
                                }
                            }

                            switch (address.EndPoint)
                            {
                                case AddressEndPointStatus.Bad:
                                case AddressEndPointStatus.Blocked:
                                    if (address.Path == "ignore" && al.Count > 1)
                                    {
                                        for (int i = 0; i < al.Count; i++)
                                        {
                                            myData.RCPT.Add(al[i]);
                                        }
                                        Send("250 2.1.5 Command good - Continue:" + newline);
                                    }
                                    else
                                    {
                                        Send("503 2.1.5 " + address.Error + newline);
                                    }
                                    break;

                                default:
                                    for (int i = 0; i < al.Count; i++)
                                    {
                                        myData.RCPT.Add(al[i]);
                                    }
                                    Send("250 2.1.5 Command good - Continue:" + newline);
                                    break;
                            }
                            myData.Temp = "";

                            myData.iState = (myData.iState == 2 ? 3 : myData.iState);
                        }
                        else
                        {
                            Send("501 5.5.4 Invalid Address, please use this syntax: \"MAIL TO: <you@domain> <CRLF>\"" + newline);
                        }
                    }
                    else
                    {
                        Send("503 Invalid state, please use the MAIL command first." + newline);
                    }
                    break;
                #endregion

                #region Case DATA
                case "DATA":
                    if (myData.iState == 3 && myData.RCPT.Count > 0)
                    {
                        myData.iState = 4;
                        try
                        {
                            if (!Directory.Exists(Parent.SmtpDirectory))
                                Directory.CreateDirectory(Parent.SmtpDirectory);

                            string filepath = Parent.SmtpDirectory + "in" + Path.DirectorySeparatorChar + FileName();

                            myData.IncomingFile = File.Open(filepath, FileMode.Append, FileAccess.Write, FileShare.Read);
                            string Received = "Received: from [{0}] by {1} via SMTP; {2}\r\n";
                            Received = String.Format(Received, myData.myEndPoint, Parent.ServerName, DateTime.Now.ToString("g"));

                            System.Byte[] lBytes = System.Text.Encoding.ASCII.GetBytes(Received);
                            myData.IncomingFile.Write(lBytes, 0, lBytes.Length);
                        }
                        catch(Exception e)
                        {
                            Send("500 Local error, unable to process." + newline);
                            Parent.DebugOut("Unable to access hard drive. \r\n\r\n A possible cause may be incorrectly set NTFS permissions. \r\n\r\n" + e.Message, true);
                            break;
                        }
                        Send("354 Start mail input; end with <CRLF> . <CRLF>" + newline);
                    }
                    else
                    {
                        Send("503 Command is out of sequence, please make sure you have specified recipients." + newline);
                    }
                    break;

                #endregion

                #region Case HELP
                case "HELP":
                    Send("214 Titanium Mail http://www.titaniumsoft.net" + newline);
                    break;
                #endregion

                #region Case QUIT
                case "QUIT":
                    Send("221 2.2.0 " + Parent.ServerName + " service closing transmission channel" + newline);
                    myData.bStayConnected = false;
                    break;
                #endregion

                #region Case NOOP
                case "NOOP":
                    Send("OK" + newline);
                    break;
                #endregion

                #region Case RSET
                case "RSET":
                    Reset();
                    Send("250 Command good - Continue:" + newline);
                    break;
                #endregion

                #region Default
                default:
                    if (myData.iState > 9)
                    {
                        HandleAuthorizationState(pData);
                    }
                    else
                    {
                        Send("503 Bad command or out of sequence." + newline);
                    }
                    break;
                #endregion
            }
        }