|
@@ -0,0 +1,220 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.IO;
|
|
|
+using System.Net.Mail;
|
|
|
+using System.Net.Sockets;
|
|
|
+using System.Text;
|
|
|
+
|
|
|
+namespace BanTur.Core.Utility
|
|
|
+{
|
|
|
+ public class MailSender
|
|
|
+ {
|
|
|
+ private readonly string _host;
|
|
|
+ private readonly int _smtpPort;
|
|
|
+ private readonly string _user;
|
|
|
+ private readonly string _pass;
|
|
|
+ private readonly string _senderName;
|
|
|
+
|
|
|
+ public MailSender(string host, int smtpPort, string user, string pass, string senderName)
|
|
|
+ {
|
|
|
+ _host = host;
|
|
|
+ _smtpPort = smtpPort;
|
|
|
+ _user = user;
|
|
|
+ _pass = pass;
|
|
|
+ _senderName = senderName;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public MailSender() : this(
|
|
|
+ DbAccess.Config.SendMailHost,
|
|
|
+ DbAccess.Config.SendMailPort,
|
|
|
+ DbAccess.Config.SendMailUser,
|
|
|
+ DbAccess.Config.SendMailPass,
|
|
|
+ "BanTur")
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void SendMail(string subject, string body = "")
|
|
|
+ {
|
|
|
+ SendMail(DbAccess.Config.SendMailTarget, subject, DbAccess.Config.SendMailTargetName, body);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void SendMail(string to, string subject, string toName, string body)
|
|
|
+ {
|
|
|
+ var cl = new TcpClient();
|
|
|
+ cl.SmtpConnect(_host, _smtpPort);
|
|
|
+ cl.SmtpLogin(_user, _pass);
|
|
|
+ cl.SmtpSendMail(_user, to, subject, body, _senderName, toName);
|
|
|
+ cl.SmtpQuit();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ internal static class MailExtensions
|
|
|
+ {
|
|
|
+ //-- internal func --
|
|
|
+
|
|
|
+ private static void SmtpCheckStatus(this TcpClient client, int status)
|
|
|
+ {
|
|
|
+ var line = client.ReadAsciiLine();
|
|
|
+ if (line.StartsWith(status + " ") == false)
|
|
|
+ throw new SmtpException(line);
|
|
|
+ }
|
|
|
+
|
|
|
+ //-- public func --
|
|
|
+
|
|
|
+ public static void SmtpConnect(this TcpClient client, string host, int port)
|
|
|
+ {
|
|
|
+ client.Connect(host, port);
|
|
|
+ client.SmtpCheckStatus(220);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void SmtpLogin(this TcpClient client, string user, string pass)
|
|
|
+ {
|
|
|
+ client.WriteLine("AUTH LOGIN");
|
|
|
+ client.SmtpCheckStatus(334);
|
|
|
+
|
|
|
+ client.WriteLine(Convert.ToBase64String(Encoding.ASCII.GetBytes(user)));
|
|
|
+ client.SmtpCheckStatus(334);
|
|
|
+
|
|
|
+ client.WriteLine(Convert.ToBase64String(Encoding.ASCII.GetBytes(pass)));
|
|
|
+ client.SmtpCheckStatus(235);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void SmtpSendMail(this TcpClient client, string from, string to, string subject, string body = "", string senderName = "", string toName = "")
|
|
|
+ {
|
|
|
+ var bodyB64 = Convert.ToBase64String(
|
|
|
+ Encoding.UTF8.GetBytes(body + Environment.NewLine + "Mail generate by LibSharpMail")
|
|
|
+ , Base64FormattingOptions.InsertLineBreaks);
|
|
|
+
|
|
|
+ client.WriteLine("MAIL FROM: <{0}>", from);
|
|
|
+ client.SmtpCheckStatus(250);
|
|
|
+
|
|
|
+ client.WriteLine("RCPT TO: <{0}>", to);
|
|
|
+ client.SmtpCheckStatus(250);
|
|
|
+
|
|
|
+ client.WriteLine("DATA");
|
|
|
+ client.SmtpCheckStatus(354);
|
|
|
+
|
|
|
+ client.WriteLine("Subject: {0}", subject.SubjectEncoding());
|
|
|
+ client.WriteLine("From: \"{1}\" <{0}>", from, senderName.SubjectEncoding());
|
|
|
+ client.WriteLine("TO: \"{1}\" <{0}>", to, toName);
|
|
|
+ client.WriteLine("MIME-Version: 1.0");
|
|
|
+ client.WriteLine("Content-Type: multipart/mixed; boundary=frontier");
|
|
|
+ client.WriteLine("");
|
|
|
+ client.WriteLine("This is a message with multiple parts in MIME format.");
|
|
|
+ client.WriteLine("--frontier");
|
|
|
+ client.WriteLine("Content-Type: text/plain; charset=utf-8");
|
|
|
+ client.WriteLine("Content-Transfer-Encoding: base64");
|
|
|
+ client.WriteLine("");
|
|
|
+ client.WriteLine(bodyB64);
|
|
|
+ client.WriteLine("--frontier--");
|
|
|
+ client.WriteLine(".");
|
|
|
+
|
|
|
+ client.SmtpCheckStatus(250);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void SmtpQuit(this TcpClient client)
|
|
|
+ {
|
|
|
+ client.WriteLine("QUIT");
|
|
|
+ client.SmtpCheckStatus(221);
|
|
|
+ client.Close();
|
|
|
+ }
|
|
|
+
|
|
|
+ ////////////////////////
|
|
|
+
|
|
|
+ private const byte Cr = (byte)'\r';
|
|
|
+ private const byte Lf = (byte)'\n';
|
|
|
+ private static readonly byte[] CrLf = { Cr, Lf };
|
|
|
+
|
|
|
+ public static string SubjectEncoding(this string subject, Encoding encoding = null)
|
|
|
+ {
|
|
|
+ var enc = encoding ?? Encoding.UTF8;
|
|
|
+ return $"=?{enc.BodyName}?B?{Convert.ToBase64String(enc.GetBytes(subject))}?=";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static void WriteBytes(this Stream s, byte[] bytes)
|
|
|
+ {
|
|
|
+ s.Write(bytes, 0, bytes.Length);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void WriteCrlf(this Stream s)
|
|
|
+ {
|
|
|
+ s.WriteBytes(CrLf);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void WriteLine(this TcpClient client, string s)
|
|
|
+ {
|
|
|
+ client.WriteLine("{0}", s);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void WriteLine(this TcpClient client, string fmt, params object[] args)
|
|
|
+ {
|
|
|
+ var s = client.GetStream();
|
|
|
+ s.WriteBytes(Encoding.ASCII.GetBytes(String.Format(fmt, args)));
|
|
|
+ s.WriteCrlf();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static byte[] ReadBinLine(this TcpClient client)
|
|
|
+ {
|
|
|
+ var s = client.GetStream();
|
|
|
+ var ms = new MemoryStream();
|
|
|
+ var len = 0;
|
|
|
+
|
|
|
+ do
|
|
|
+ {
|
|
|
+ var b = s.ReadByte();
|
|
|
+ if (b < 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ ms.WriteByte((byte)b);
|
|
|
+
|
|
|
+ len++;
|
|
|
+ if (len < 2)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ var msbuf = ms.GetBuffer();
|
|
|
+ if (msbuf[len - 2] == Cr
|
|
|
+ && msbuf[len - 1] == Lf)
|
|
|
+ break;
|
|
|
+ } while (true);
|
|
|
+
|
|
|
+ var buf = new byte[len - 2];
|
|
|
+ Array.Copy(ms.GetBuffer(), 0, buf, 0, len - 2);
|
|
|
+
|
|
|
+ return buf;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static string ReadAsciiLine(this TcpClient client)
|
|
|
+ {
|
|
|
+ return Encoding.ASCII.GetString(client.ReadBinLine());
|
|
|
+ }
|
|
|
+
|
|
|
+ public static string[] ReadAsciiLinesUntilDot(this TcpClient client)
|
|
|
+ {
|
|
|
+ var ret = new List<string>();
|
|
|
+ do
|
|
|
+ {
|
|
|
+ var line = client.ReadAsciiLine();
|
|
|
+ if (line.Trim() == ".")
|
|
|
+ break;
|
|
|
+ ret.Add(line);
|
|
|
+ } while (true);
|
|
|
+ return ret.ToArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static byte[][] ReadBinLineUntilDot(this TcpClient client)
|
|
|
+ {
|
|
|
+ var ret = new List<byte[]>();
|
|
|
+ do
|
|
|
+ {
|
|
|
+ var line = client.ReadBinLine();
|
|
|
+ if (line.Length > 0 && line[0] == (byte)'.')
|
|
|
+ break;
|
|
|
+ ret.Add(line);
|
|
|
+ } while (true);
|
|
|
+ return ret.ToArray();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|