2016-11-27 17:38:47 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2016-11-28 16:26:04 +00:00
|
|
|
|
using System.Net;
|
2016-11-27 17:38:47 +00:00
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
|
|
|
|
namespace MailServer.SMTPServer
|
|
|
|
|
{
|
|
|
|
|
public delegate void ReceivedLineEventHandler(string line);
|
|
|
|
|
|
|
|
|
|
class SmtpSession
|
|
|
|
|
{
|
|
|
|
|
public event ReceivedLineEventHandler NewLine;
|
|
|
|
|
|
|
|
|
|
private TcpClient Client { get; set; }
|
2016-11-28 16:26:04 +00:00
|
|
|
|
public IPEndPoint IPEndPoint { get; private set; }
|
2016-11-27 17:38:47 +00:00
|
|
|
|
private NetworkStream Stream { get; set; }
|
|
|
|
|
private Encoding Encoding = Encoding.ASCII;
|
|
|
|
|
private string Others;
|
|
|
|
|
private Thread Worker;
|
|
|
|
|
private bool Active = true;
|
2016-11-28 16:26:04 +00:00
|
|
|
|
private int SessionID { get; set; }
|
2016-11-27 17:38:47 +00:00
|
|
|
|
|
|
|
|
|
public SmtpSession(TcpClient client)
|
|
|
|
|
{
|
|
|
|
|
Client = client;
|
2016-11-28 16:26:04 +00:00
|
|
|
|
IPEndPoint = (IPEndPoint)client.Client.RemoteEndPoint;
|
2016-11-27 17:38:47 +00:00
|
|
|
|
Stream = client.GetStream();
|
|
|
|
|
Others = "";
|
2016-11-28 16:26:04 +00:00
|
|
|
|
SessionID = new Random(123).Next(10000, 99999);
|
|
|
|
|
Logging.AddLogMessage(Logging.LoggingType.INFO, "New SMTPSession with id '" + SessionID + "' started");
|
2016-11-27 17:38:47 +00:00
|
|
|
|
Worker = new Thread(ReadClientInput);
|
|
|
|
|
Worker.Start();
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-30 20:09:45 +00:00
|
|
|
|
public void SendExtensionResponse(Extensions extension) => SendResponse("250-" + extension.ToString());
|
|
|
|
|
|
2016-11-27 17:38:47 +00:00
|
|
|
|
public void SendResponse(ResponseCodes responseCode) => SendResponse(responseCode, "");
|
|
|
|
|
|
2016-11-30 20:09:45 +00:00
|
|
|
|
public void SendResponse(ResponseCodes responseCode, string args) => SendResponse(((int)responseCode).ToString() + " " + args);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void SendResponse(string response)
|
2016-11-27 17:38:47 +00:00
|
|
|
|
{
|
2016-11-30 20:09:45 +00:00
|
|
|
|
Logging.AddLogMessage(Logging.LoggingType.INFO, response);
|
|
|
|
|
response += '\r' + '\n';
|
|
|
|
|
var bytes = Encoding.UTF8.GetBytes(response);
|
2016-11-27 17:38:47 +00:00
|
|
|
|
Stream.Write(bytes, 0, bytes.Length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ReadClientInput()
|
|
|
|
|
{
|
|
|
|
|
while (Active)
|
|
|
|
|
{
|
|
|
|
|
if (Stream.DataAvailable)
|
|
|
|
|
{
|
|
|
|
|
byte[] buffer = new byte[Client.ReceiveBufferSize];
|
|
|
|
|
var readed = Stream.Read(buffer, 0, buffer.Length);
|
|
|
|
|
|
|
|
|
|
var str = Encoding.GetString(buffer, 0, readed);
|
|
|
|
|
lock (Others)
|
|
|
|
|
{
|
|
|
|
|
Others += str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CheckLines();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(10);
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-28 16:26:04 +00:00
|
|
|
|
|
2016-11-27 17:38:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool r = false;
|
|
|
|
|
|
|
|
|
|
private void CheckLines()
|
|
|
|
|
{
|
|
|
|
|
lock (Others)
|
|
|
|
|
{
|
|
|
|
|
var line = "";
|
|
|
|
|
foreach (char c in Others)
|
|
|
|
|
{
|
|
|
|
|
if (c.Equals('\r'))
|
|
|
|
|
{
|
|
|
|
|
r = true;
|
|
|
|
|
}
|
|
|
|
|
else if (r && c.Equals('\n'))
|
|
|
|
|
{
|
|
|
|
|
//Console.WriteLine(line);
|
2016-11-28 16:26:04 +00:00
|
|
|
|
Logging.AddLogMessage(Logging.LoggingType.DEBUG, "Seession " + SessionID + ": received line: " + line);
|
2016-11-27 17:38:47 +00:00
|
|
|
|
NewLine(line);
|
|
|
|
|
line = "";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
line += c;
|
|
|
|
|
r = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Others = line;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void CloseAll()
|
|
|
|
|
{
|
|
|
|
|
Stream.Dispose();
|
|
|
|
|
Client.Dispose();
|
|
|
|
|
Active = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|