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"); }
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; } } }
public void AddError(ClientData client, string message, Exception ex) { this.AddError("[" + client.Ip + "] " + message, ex); }
public void AddWarning(ClientData client, string message) { this.AddWarning("[" + client.Ip + "] " + message); }
public void AddInformation(ClientData client, string message) { this.AddInformation("[" + client.Ip + "] " + message); }