SafeDispatch/SafeMobileLIB_DLL/EmailServerSSL.cs

803 lines
29 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;
using System.Collections;
using OpenPop.Pop3;
using OpenPop.Mime;
using System.Net.Sockets;
using OpenPop.Pop3.Exceptions;
using System.ComponentModel;
using System.Threading;
namespace SafeMobileLib
{
public class EmailServerSSL
{
private Pop3Client popClient;
private string serverIP;
private int port;
private string loginName;
private string password;
private bool isSSL = true;
private Int64 lastEmailTime = 0;
private Int64 startEmailServiceTime = 0;
public static Dictionary<string, int> blackList = new Dictionary<string, int>();
public const int MAX_ATTEMPTS = 100;
// blank constructor in order to be used in Email Checking
public EmailServerSSL()
{
}
//constructor
public EmailServerSSL(string _serverIP, string _port, string _logName, string _pass)
{
bool result = Int32.TryParse(_port, out port);
if (!result)
{
Console.WriteLine("Email port not numeric, error in EmailServerSSL constructor.");
return;
}
serverIP = _serverIP;
loginName = _logName;
password = _pass;
popClient = new Pop3Client();
// create the pop connection
ConnectEmailPopServer();
}
public EmailServerSSL(string _serverIP, Int32 _port, string _logName, string _pass, bool _isSSL)
{
serverIP = _serverIP;
loginName = _logName;
port = _port;
password = _pass;
isSSL = _isSSL;
startEmailServiceTime = DateTo70Format(DateTime.UtcNow);
// create the pop connection
ConnectEmailPopServer();
}
#region popCLient events
private void AddEvent(string strEvent)
{
}
private void popClient_CommunicationBegan(object sender, EventArgs e)
{
AddEvent("CommunicationBegan");
}
private void popClient_CommunicationOccured(object sender, EventArgs e)
{
AddEvent("CommunicationOccured");
}
private void popClient_AuthenticationBegan(object sender, EventArgs e)
{
AddEvent("AuthenticationBegan");
}
private void popClient_AuthenticationFinished(object sender, EventArgs e)
{
AddEvent("AuthenticationFinished");
}
private void popClient_MessageTransferBegan(object sender, EventArgs e)
{
AddEvent("MessageTransferBegan");
}
private void popClient_MessageTransferFinished(object sender, EventArgs e)
{
AddEvent("MessageTransferFinished");
}
private void popClient_CommunicationLost(object sender, EventArgs e)
{
AddEvent("CommunicationLost");
}
#endregion
/// <summary>
/// Set the time of the last email as written in the DataBase.
/// Only newer emails will be handled
/// </summary>
/// <param name="time">Unix TimeStap for the last email time</param>
public void setLastEmailTime(Int64 time)
{
lastEmailTime = time;
}
/// <summary>
/// Get the latest email time as received from the server
/// </summary>
/// <returns>Unix timestamp of the latest email</returns>
public Int64 getLastEmailTime()
{
return lastEmailTime;
}
/// <summary>
/// Get the emails from the server and check which ones were not
/// parsed
/// </summary>
/// <returns>A list of emails</returns>
public ArrayList getEmails()
{
ArrayList ret = new ArrayList();
try
{
if (popClient != null && !popClient.Connected)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("PopServer is not authenticated/connected. Check the email address, password and settings");
Console.ForegroundColor = ConsoleColor.Gray;
// reconnect if the email server is outlook one
if (serverIP.Contains("outlook"))
ConnectEmailPopServer();
}
else
{
// reconnect if the email server is not the outlook one
if (!serverIP.Contains("outlook"))
ConnectEmailPopServer();
else
{
// reconnect every 10 minutes
if (((DateTo70Format(DateTime.UtcNow) - startEmailServiceTime) / 60) % 10 == 0)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("RECONNECTING");
Console.ForegroundColor = ConsoleColor.Gray;
ConnectEmailPopServer();
}
}
int messageCount = 0;
try
{
messageCount = popClient.GetMessageCount();
}
catch (InvalidUseException iue) {}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Socket Exception -> " + ex.ToString());
Console.ForegroundColor = ConsoleColor.Gray;
popClient = null;
}
// save the latest time before this search
Int64 initialLatestTime = lastEmailTime;
int newEmails = 0;
// Messages are numbered in the interval: [1, messageCount]
// Ergo: message numbers are 1-based.
// Most servers give the latest message the highest number
List<OpenPop.Mime.Message> messageList = new List<OpenPop.Mime.Message>();
for (int i = messageCount; i > 0; i--)
{
//try
//{
OpenPop.Mime.Message email = popClient.GetMessage(i);
messageList.Add(email);
//}
//catch (Exception ex)
//{
// Console.ForegroundColor = ConsoleColor.Cyan;
// Console.WriteLine("Exception [Marked deletion?]-> " + ex.ToString());
// Console.ForegroundColor = ConsoleColor.Gray;
//}
}
for (int i=0; i < messageCount; i++)
{
OpenPop.Mime.Message email = messageList[i];
if (email != null)
{
// check if the message was already parsed by verifying email time with initialLatestTime
// and close the parsing
if (initialLatestTime >= DateTo70Format(email.Headers.DateSent.ToUniversalTime()))
{
break;
}
// save the latest time to the first one (assuming it's the newest)
if (i == messageCount)
{
this.lastEmailTime = DateTo70Format(email.Headers.DateSent.ToUniversalTime());
}
// this email is new
newEmails++;
Console.WriteLine("-----------------------------------------------------------------");
Console.WriteLine("From: " + email.Headers.From);
if (email.Headers.To.Count() >= 0)
Console.WriteLine("To: " + email.Headers.To[0]);
Console.WriteLine("Subject: " + email.Headers.Subject);
Console.WriteLine("Date: " + email.Headers.DateSent.ToUniversalTime().ToShortTimeString()
+ "[" + DateTo70Format(email.Headers.DateSent.ToUniversalTime()) + "]");
MessagePart html = email.FindFirstHtmlVersion();
if (html != null)
{
string text = RemoveHTMLtags(html.GetBodyAsText());
Console.WriteLine("Text: " + text.Substring(0, (text.Length > 30 ? 30 : text.Length)) + (text.Length > 30 ? "..." : ""));
}
else
html = email.FindFirstPlainTextVersion();
EmailtoSMS ets = processMessage(email.Headers.Subject, RemoveHTMLtags(html.GetBodyAsText()), email.Headers.From.ToString());
if ((ets.id != "") && (ets.text == ""))
{
Console.WriteLine("Incorrect email body " + RemoveHTMLtags(html.GetBodyAsText()));
}
else if ((ets.id != "") && (ets.text != ""))
{
ret.Add(ets);
}
}
else
{
Console.WriteLine("-----------------------------------------------------------------");
Console.WriteLine("BAD email");
}
}
Console.WriteLine("Got " + newEmails + " new emails [total " + messageCount +"] " );
}
}
catch (Exception ex)
{
Console.WriteLine("getEmails() from EmailServerSSL Exception: " + ex.Message + ex.ToString());
}
return ret;
}
public ArrayList getEmailsRaw()
{
ArrayList ret = new ArrayList();
try
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(String.Format("Ser = {0} Psw = {1} SSL = {2}", serverIP, password, isSSL));
Console.ForegroundColor = ConsoleColor.Gray;
int messageCount = popClient.GetMessageCount();
Console.WriteLine("Got " + messageCount + " emails");
// Messages are numbered in the interval: [1, messageCount]
// Ergo: message numbers are 1-based.
// Most servers give the latest message the highest number
List<OpenPop.Mime.Message> messageList = new List<OpenPop.Mime.Message>();
for (int i = messageCount; i > 0; i--)
{
OpenPop.Mime.Message email = popClient.GetMessage(i);
messageList.Add(email);
}
for (int i = 0; i< messageCount; i++)
{
OpenPop.Mime.Message email = messageList[i];
if (email != null)
{
Console.WriteLine("-----------------------------------------------------------------");
Console.WriteLine("From: " + email.Headers.From);
if (email.Headers.To.Count >= 0)
Console.WriteLine("To: " + email.Headers.To[0]);
Console.WriteLine("Subject: " + email.Headers.Subject);
string body = RemoveHTMLtags(email.MessagePart.Body.ToString());
EmailtoSMS ets = new EmailtoSMS();
ets.from = email.Headers.From.ToString();
ets.text = body;
ets.id = "";
if (ets.from.Contains("@"))
{
string temp = (ets.from.Split("@".ToCharArray()))[0];
int i_id = 0;
bool valid = Int32.TryParse(temp, out i_id);
if (valid)
ets.id = i_id.ToString();
}
if ((ets.id != "") && (ets.text == ""))
{
Console.WriteLine("Incorrect email body " + email.MessagePart.Body.ToString());
}
else if (ets.text != "")
{
try
{
popClient.DeleteMessage(i);
}
catch (Exception e)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Exception [Marked deletion?]-> " + e.ToString());
Console.ForegroundColor = ConsoleColor.Gray;
}
ret.Add(ets);
}
}
else
{
Console.WriteLine("-----------------------------------------------------------------");
Console.WriteLine("BAD email");
}
}
}
catch (Exception ex)
{
Console.WriteLine("getEmails() from EmailServerSSL Exception: " + ex.Message + ex.ToString());
}
return ret;
}
public static void HandleBlacklist(string key)
{
// add key to backlist
if (!blackList.ContainsKey(key))
blackList.Add(key, MAX_ATTEMPTS);
}
public static bool IsBlacklisted(string key)
{
if (!blackList.ContainsKey(key))
return false;
// avoid to connect to pop3 MAX_ATTEMPTS times => give another chance to try to connect to pop 3 when count = 0
int count = blackList[key];
if (count == 0)
{
blackList.Remove(key);
return false;
}
blackList[key] = count - 1;
return true;
}
/// <summary>
/// Connect to the Pop Server in order to be used to get the emails
/// </summary>
private void ConnectEmailPopServer()
{
if (IsBlacklisted(serverIP))
{
Utils.WriteLine($"ConnectEmailPopServer : Could not conenct to the pop server '{serverIP}'. The pop server '{serverIP}' is in blacklist count = {blackList[serverIP]}");
return;
}
Thread t = new Thread(() =>
{
ConnectAsync();
});
t.Start();
}
private void ConnectAsync()
{
try
{
if (popClient != null && popClient.Connected)
popClient.Disconnect();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
popClient = null;
popClient = new Pop3Client();
try
{
// Connect to the server
popClient.Connect(serverIP, port, isSSL);
// Authenticate ourselves towards the server
popClient.Authenticate(loginName, password);
}
catch (PopServerNotFoundException ee)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("PopServerNotFoundException -> " + ee.ToString());
Console.ForegroundColor = ConsoleColor.Gray;
HandleBlacklist(serverIP);
}
catch (InvalidLoginException e)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("InvalidLoginException -> " + e.ToString());
Console.ForegroundColor = ConsoleColor.Gray;
HandleBlacklist(serverIP);
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("ConnectEmailPopServer -> " + ex.ToString());
Console.ForegroundColor = ConsoleColor.Gray;
HandleBlacklist(serverIP);
}
}
private EmailtoSMS processMessage(string subj, string body, string from)
{
EmailtoSMS obj = new EmailtoSMS();
obj.from = from;
String s = subj.ToUpper();
if (s.Contains("GROUPID[") && subj.Contains("]"))
{
obj.id = s;
obj.id = obj.id.Remove(0, s.IndexOf("GROUPID[") + 8);
obj.id = obj.id.Remove(obj.id.IndexOf("]"));
obj.is_group = true;
}
else if (s.Contains("GRPID[") && subj.Contains("]"))
{
obj.id = s;
obj.id = obj.id.Remove(0, s.IndexOf("GRPID[") + 6);
obj.id = obj.id.Remove(obj.id.IndexOf("]"));
obj.is_group = true;
}
else if (s.Contains("ID[") && subj.Contains("]"))
{
obj.id = s;
obj.id = obj.id.Remove(0, s.IndexOf("ID[") + 3);
obj.id = obj.id.Remove(obj.id.IndexOf("]"));
obj.is_group = false;
}
if (obj.id.Length > 0)
{ // ID prezent in subject
s = body.ToUpper();
if (s.Contains("BODY[") && body.Contains("]"))
{
obj.text = body;
obj.text = obj.text.Remove(0, s.IndexOf("BODY[") + 5);
obj.text = obj.text.Remove(obj.text.IndexOf("]"));
if (obj.text.Length > 139)
obj.text = obj.text.Remove(140);
}
}
else
{ //check for id in email body
s = body.ToUpper();
if (s.Contains("GROUPID[") && s.Contains("]"))
{
obj.id = s;
obj.id = obj.id.Remove(0, s.IndexOf("GROUPID[") + 8);
obj.id = obj.id.Remove(obj.id.IndexOf("]"));
obj.is_group = true;
}
else if (s.Contains("GRPID[") && s.Contains("]"))
{
obj.id = s;
obj.id = obj.id.Remove(0, s.IndexOf("GRPID[") + 6);
obj.id = obj.id.Remove(obj.id.IndexOf("]"));
obj.is_group = true;
}
else if (s.Contains("ID[") && s.Contains("]"))
{
obj.id = s;
obj.id = obj.id.Remove(0, s.IndexOf("ID[") + 3);
obj.id = obj.id.Remove(obj.id.IndexOf("]"));
obj.is_group = false;
}
else if (s.Contains("RPL[") && s.Contains("]"))
{
obj.id = s;
obj.id = obj.id.Remove(0, obj.id.IndexOf("RPL[") + 4);
obj.id = obj.id.Remove(obj.id.IndexOf("]"));
obj.text = obj.id;
obj.is_group = true;
obj.is_sierra = true;
if (obj.from.Contains("<") && obj.from.Contains(">"))
{
obj.from = obj.from.Remove(0, obj.from.IndexOf("<") + 1);
obj.from = obj.from.Remove(obj.from.IndexOf(">"));
}
}
if (obj.id.Length > 0)
{
s = body.ToUpper();
if (s.Contains("BODY[") && s.Contains("]"))
{
obj.text = body;
obj.text = obj.text.Remove(0, s.IndexOf("BODY[") + 5);
obj.text = obj.text.Remove(obj.text.IndexOf("]"));
if (obj.text.Length > 139)
obj.text = obj.text.Remove(140);
}
}
}
Console.WriteLine("ID: " + obj.id);
Console.WriteLine("Text: " + obj.text);
Console.WriteLine("-----------------------------------------------------------------");
return obj;
}
public static void sendEmail(string server, Int32 _port, string user, string pass, MailMessage mailMessage, Boolean enableSSL)
{
SmtpClient mailClient = new SmtpClient();
mailClient.Host = server;
mailClient.Port = _port;
NetworkCredential cred = new NetworkCredential(user, pass);
mailClient.Credentials = cred;
mailClient.EnableSsl = enableSSL;
mailClient.Send(mailMessage);
Console.WriteLine("------Sending email on " + server + " TO: " + mailMessage.To[0].ToString() + "--------------");
}
public void sendEmailWithFeedback(string server, Int32 _port, string user, string pass, MailMessage mailMessage, Boolean enableSSL)
{
Console.WriteLine("------Sending email on " + server + " TO: " + mailMessage.To[0].ToString() + "--------------");
try
{
SmtpClient mailClient = new SmtpClient();
mailClient.Host = server;
mailClient.Port = _port;
NetworkCredential cred = new NetworkCredential(user, pass);
mailClient.Credentials = cred;
mailClient.EnableSsl = enableSSL;
mailClient.Send(mailMessage);
if (OnMailSendComplete != null)
OnMailSendComplete(true);
}
catch
{
if (OnMailSendComplete != null)
OnMailSendComplete(false);
}
}
public static void sendListofEmail(string server, Int32 _port, string user, string pass, ArrayList ListofmailMessage, Boolean enableSSL)
{
SmtpClient mailClient = new SmtpClient();
mailClient.Host = server;
mailClient.Port = _port;
mailClient.UseDefaultCredentials = false;
NetworkCredential cred = new NetworkCredential(user, pass);
mailClient.Credentials = cred;
mailClient.EnableSsl = enableSSL;
foreach (MailMessage obj in ListofmailMessage)
{
obj.IsBodyHtml = true;
mailClient.Send(obj);
Console.WriteLine("------Sending email on " + server + " TO: " + obj.To[0].ToString() + "--------------");
}
}
public string RemoveHTMLtags(string _data)
{
string data = _data;
while(data.Contains('<'))
{
int firstindex = data.IndexOf('<');
int secondindex = data.IndexOf('>');
data = data.Remove(firstindex, secondindex - firstindex+1);
}
data = data.Replace("\n","");
data = data.Replace("\r", "");
return data;
}
/// <summary>
/// Check the configuration of the POP Server to see if it's valid. The check consists in reading the email
/// list from the account provided
/// </summary>
/// <param name="_serverIP">POP Server name or IP</param>
/// <param name="_port">POP Server Port</param>
/// <param name="_logName">Email address from which the emails will be read</param>
/// <param name="_pass">Email Account password used to read the email</param>
/// <param name="_isSSL">Flag if the POP connection is SSL encrypted or not</param>
public void CheckPopServerSettings(string _serverIP, Int32 _port, string _logName, string _pass, bool _isSSL)
{
bool result = false;
string message = "";
Pop3Client tmpClient = new Pop3Client();
try
{
// Connect to the server
tmpClient.Connect(_serverIP, _port, _isSSL);
// Authenticate ourselves towards the server
tmpClient.Authenticate(_logName, _pass);
// Get the message count to check if the email settings are correct
int messageCount = tmpClient.GetMessageCount();
message = "Success";
result = true;
}
catch (PopServerNotFoundException ee)
{
message = "PopServerNotFoundException";
}
catch (InvalidLoginException e)
{
message = "InvalidLoginException";
}
catch (Exception ex)
{
message = "InvalidLoginException";
}
// trigger response
if(OnPopServerCheckResponseReceived != null)
OnPopServerCheckResponseReceived(result, message);
}
/// <summary>
/// Check the configuration of the SMTP Server to see if it's valid. The check consists in sending a simple
/// text mail message to the emailAddress provided by the user
/// </summary>
/// <param name="_serverIP">SMTP Server name or IP</param>
/// <param name="_port">SMTP Server Port</param>
/// <param name="_logName">Email address from which and to which the email will be send</param>
/// <param name="_pass">Email Account password used to send the email</param>
/// <param name="_isSSL">Flag if the SMTP connection is SSL encrypted or not</param>
public void CheckSmtpServerSettings(string _serverIP, Int32 _port, string _logName, string _pass, bool _isSSL)
{
bool result = false;
string responseMessage = "";
try
{
MailAddress from = new MailAddress(_logName);
MailAddress to = new MailAddress(_logName);
MailMessage message = new MailMessage(from, to);
message.IsBodyHtml = true; // This line
string tab = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
message.Subject = "Email test from Dispatch System";
message.Body = "Hi.<br/>You have tested your email server settings from the Dispatch System. <br/>" +
"Your valid configuration is: <b><br/><br/>" +
tab + _serverIP + ":" + _port + " <br/>" +
tab + "This server " + (_isSSL ? "requires" : "do not requires") + " SSL encryption. </b><br/><br/>" +
"Thank you!";
SmtpClient mailClient = new SmtpClient();
mailClient.Host = _serverIP;
mailClient.Port = _port;
NetworkCredential cred = new NetworkCredential(_logName, _pass);
mailClient.Credentials = cred;
mailClient.EnableSsl = _isSSL;
mailClient.Send(message);
result = true;
responseMessage = "Success";
}
catch (Exception ex)
{
result = false;
responseMessage = "Exception " + ex.ToString();
}
// trigger event
if(OnSmtpServerCheckResponseReceived != null)
OnSmtpServerCheckResponseReceived(result, responseMessage);
}
/// <summary>
/// Get the unix timestamp of a specific Date
/// </summary>
/// <param name="param">Date which needs to be converted</param>
/// <returns>An int representing the number of seconds since 1 Jan 1970</returns>
private uint DateTo70Format(DateTime param)
{
long nOfSeconds;
//Console.WriteLine("DateTo70Format param=" + param);
System.DateTime dt70 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
TimeSpan span = param - dt70;
nOfSeconds = (long)span.TotalSeconds;
return ((uint)nOfSeconds);
}
#region EVENTS
public delegate void PopServerCheckDEl(bool isValid, string responseMessage);
public event PopServerCheckDEl OnPopServerCheckResponseReceived;
public delegate void SmtpServerCheckDEl(bool isValid, string responseMessage);
public event SmtpServerCheckDEl OnSmtpServerCheckResponseReceived;
public delegate void MailSendComplete(bool result);
public event MailSendComplete OnMailSendComplete;
#endregion
}
public class EmailtoSMS
{
public String from;
public String id;
public String text;
public Boolean is_group;
public Boolean is_sierra;
public EmailtoSMS()
{
from = "";
id = "";
text = "";
is_group = false;
is_sierra = false;
}
}
}