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 blackList = new Dictionary(); 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 /// /// Set the time of the last email as written in the DataBase. /// Only newer emails will be handled /// /// Unix TimeStap for the last email time public void setLastEmailTime(Int64 time) { lastEmailTime = time; } /// /// Get the latest email time as received from the server /// /// Unix timestamp of the latest email public Int64 getLastEmailTime() { return lastEmailTime; } /// /// Get the emails from the server and check which ones were not /// parsed /// /// A list of emails 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 messageList = new List(); 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 messageList = new List(); 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; } /// /// Connect to the Pop Server in order to be used to get the emails /// 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; } /// /// 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 /// /// POP Server name or IP /// POP Server Port /// Email address from which the emails will be read /// Email Account password used to read the email /// Flag if the POP connection is SSL encrypted or not 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); } /// /// 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 /// /// SMTP Server name or IP /// SMTP Server Port /// Email address from which and to which the email will be send /// Email Account password used to send the email /// Flag if the SMTP connection is SSL encrypted or not 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 = "      "; message.Subject = "Email test from Dispatch System"; message.Body = "Hi.
You have tested your email server settings from the Dispatch System.
" + "Your valid configuration is:

" + tab + _serverIP + ":" + _port + "
" + tab + "This server " + (_isSSL ? "requires" : "do not requires") + " SSL encryption.


" + "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); } /// /// Get the unix timestamp of a specific Date /// /// Date which needs to be converted /// An int representing the number of seconds since 1 Jan 1970 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; } } }