示例#1
0
        private void HandleClient(object rawClient)
        {
            ClientData client = new ClientData();

            try
            {
                // Prepare the connection.
                using (TcpClient tcpClient = (TcpClient)rawClient)
                {
                    NetworkStream clientStream = tcpClient.GetStream();

                    // Prepare the state variables.
                    byte[] buffer       = new byte[4096];
                    string message      = "";
                    bool   isNewMessage = true;
                    bool   running      = true;

                    // Make sure we don't have rawClient hanging too long. Miliseconds.
                    clientStream.ReadTimeout  = this.ClientTimeout;
                    clientStream.WriteTimeout = this.ClientTimeout;

                    var endPoint = tcpClient.Client.RemoteEndPoint as IPEndPoint;
                    if (endPoint != null)
                    {
                        client.Ip = endPoint.Address.ToString();
                    }

                    Logger.Instance.AddInformation(client, "### Client connected");

                    // Greet the rawClient.
                    this.SendClientData("220 buckthurn.oexenhave.dk SMTP Server", client, ref clientStream);

                    while (running)
                    {
                        // Reset the string is the message has been processed.
                        if (isNewMessage)
                        {
                            message = "";
                        }

                        // Do a read from the socket. Break if anything unexpected goes on.
                        int bytesRead;
                        try
                        {
                            bytesRead = clientStream.Read(buffer, 0, 4096);
                        }
                        catch (Exception)
                        {
                            Logger.Instance.AddInformation(client, "### Client inactive");
                            this.SendClientData("500 Inactive", client, ref clientStream);
                            break;
                        }

                        if (bytesRead == 0)
                        {
                            break;
                        }

                        message += this.encoder.GetString(buffer, 0, bytesRead);

                        // Allow telnet-like connections to work as well.
                        isNewMessage = message.EndsWith("\r\n");

                        // Process the message
                        if (isNewMessage)
                        {
                            // Process one line at a time.
                            foreach (string messageLine in message.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
                            {
                                Logger.Instance.AddInformation(client, messageLine.Substring(0, Math.Min(255, messageLine.Length)));

                                // Intepretate the message.
                                this.ProcessMessage(this.GetMessageType(client, messageLine), messageLine, ref client, ref clientStream, ref running);
                            }
                        }
                    }

                    clientStream.Close();
                    tcpClient.Close();
                }
            }
            catch (Exception ex)
            {
                Logger.Instance.AddError(client, "### Ending client thread due to an error", ex);
            }

            Logger.Instance.AddInformation(client, "### Client disconnected");
        }
示例#2
0
        private void ProcessMessage(MessageType type, string message, ref ClientData client, ref NetworkStream clientStream, ref bool running)
        {
            switch (type)
            {
            case MessageType.EHLO:
            {
                if (client.State == ClientState.EHLO)
                {
                    this.SendClientData("250 buckthurn.oexenhave.dk", client, ref clientStream);
                    client.State = ClientState.FROM;
                }
                else
                {
                    this.SendClientData("503 Bad sequence of commands", client, ref clientStream);
                }
                break;
            }

            case MessageType.FROM:
            {
                this.SendClientData("250 OK", client, ref clientStream);
                client.State = ClientState.TO;
                break;
            }

            case MessageType.TO:
            {
                if (client.State == ClientState.TO || client.State == ClientState.DATA)
                {
                    if (!message.Contains("@buckthurn.oexenhave.dk"))
                    {
                        this.SendClientData("550 No such user here", client, ref clientStream);
                        Logger.Instance.AddInformation("### Email disallowed: " + message);
                    }
                    else
                    {
                        this.SendClientData("250 OK", client, ref clientStream);
                        client.State = ClientState.DATA;
                    }
                }
                else
                {
                    this.SendClientData("503 Bad sequence of commands", client, ref clientStream);
                }
                break;
            }

            case MessageType.DATA:
            {
                if (client.State == ClientState.DATA)
                {
                    this.SendClientData("354 Start mail input; end with <CRLF>.<CRLF>", client, ref clientStream);
                    client.State = ClientState.DATA;
                }
                else
                {
                    this.SendClientData("503 Bad sequence of commands", client, ref clientStream);
                }
                break;
            }

            case MessageType.CONTENT:
            {
                Logger.Instance.AddInformation(message);
                //if (Message.IndexOf("Mindtrio-Quasar-Ident") > -1)
                //{
                //    client.Ident = Message.Replace("Mindtrio-Quasar-Ident: ", "");
                //}

                //if (Message.IndexOf("Mindtrio-Quasar-Type") > -1)
                //{
                //    client.Type = Message.Replace("Mindtrio-Quasar-Type: ", "");
                //}

                //if (!String.IsNullOrEmpty(client.Ident) && !String.IsNullOrEmpty(client.Type))
                //{
                //    this.PushClient.ReportBounce(client.Type, client.Ident, this.AppSettings["PushKey"]);
                //    if (logger.IsInfoEnabled) logger.Info("Bounce reported. Type: {" + client.Type + "}. Ident: {" + client.Ident + "}.");
                //    client.Type = "";
                //    client.Ident = "";
                //}

                break;
            }

            case MessageType.CONTENTEND:
            {
                this.SendClientData("250 OK", client, ref clientStream);
                client.State = ClientState.QUIT;
                break;
            }

            case MessageType.QUIT:
            {
                running = false;
                break;
            }

            case MessageType.UNKNOWN:
            {
                this.SendClientData("500 Syntax error, command unrecognized", client, ref clientStream);
                break;
            }
            }
        }
示例#3
0
 public void AddError(ClientData client, string message, Exception ex)
 {
     this.AddError("[" + client.Ip + "] " + message, ex);
 }
示例#4
0
 public void AddWarning(ClientData client, string message)
 {
     this.AddWarning("[" + client.Ip + "] " + message);
 }
示例#5
0
 public void AddInformation(ClientData client, string message)
 {
     this.AddInformation("[" + client.Ip + "] " + message);
 }