From dbb155a849256d0b723cb1ca27413c78a64f4b5b Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Mon, 17 Oct 2022 10:41:07 +0200 Subject: [PATCH] Messaging: Add MailSender class --- Messaging/Email2.vb | 15 ++- Messaging/Limilab.vb | 2 +- Messaging/MailSender.vb | 244 +++++++++++++++++++++++++++++++++++++ Messaging/Messaging.vbproj | 6 +- Messaging/SMS.vb | 3 - 5 files changed, 257 insertions(+), 13 deletions(-) create mode 100644 Messaging/MailSender.vb delete mode 100644 Messaging/SMS.vb diff --git a/Messaging/Email2.vb b/Messaging/Email2.vb index c97aec66..6575d591 100644 --- a/Messaging/Email2.vb +++ b/Messaging/Email2.vb @@ -5,7 +5,6 @@ Imports Limilabs.Mail Imports Limilabs.Mail.MIME Imports Limilabs.Mail.MSG Imports Limilabs.Client.IMAP -Imports Limilabs.Client.SMTP Imports Limilabs.Client Public Class Email2 @@ -41,17 +40,17 @@ Public Class Email2 End If End Sub - Public Function New_SMTPConnection(pSMTP As Smtp, pServer As String, pUsername As String, pPassword As String, pSecurity As EmailSecurity, Optional pPort As Integer = 0) As Smtp + Public Function New_SMTPConnection(pSMTP As Limilabs.Client.SMTP.Smtp, pServer As String, pUsername As String, pPassword As String, pSecurity As EmailSecurity, Optional pPort As Integer = 0) As Limilabs.Client.SMTP.Smtp Try Logger.Info("Connecting to SMTP server [{0}:{1}] with user [{2}]", pServer, pPort, pUsername) Dim oPort As Integer If pPort = 0 Then If pSecurity = EmailSecurity.SSL Then - oPort = Smtp.DefaultSSLPort + oPort = Limilabs.Client.SMTP.Smtp.DefaultSSLPort Else - oPort = Smtp.DefaultPort + oPort = Limilabs.Client.SMTP.Smtp.DefaultPort End If @@ -146,7 +145,7 @@ Public Class Email2 End Try End Function - Public Function Test_SMTPLogin(pClient As Smtp) As Boolean + Public Function Test_SMTPLogin(pClient As Limilabs.Client.SMTP.Smtp) As Boolean Logger.Info("Testing Login to IMAP Server") Try @@ -241,7 +240,7 @@ Public Class Email2 End Try End Function - Public Function Send_SMTPMessage(pClient As Smtp, pSender As String, pReceiver As String, pSubject As String, pBody As String) As Boolean + Public Function Send_SMTPMessage(pClient As Limilabs.Client.SMTP.Smtp, pSender As String, pReceiver As String, pSubject As String, pBody As String) As Boolean Logger.Info("Sending Message with Subject [{0}]", pSubject) Try @@ -252,9 +251,9 @@ Public Class Email2 oBuilder.Text = pBody Dim oMail As IMail = oBuilder.Create() - Dim oResult As ISendMessageResult = pClient.SendMessage(oMail) + Dim oResult As Limilabs.Client.SMTP.ISendMessageResult = pClient.SendMessage(oMail) - If oResult.Status = SendMessageStatus.Success Then + If oResult.Status = Limilabs.Client.SMTP.SendMessageStatus.Success Then Logger.Debug("Message sent successful!") Return True diff --git a/Messaging/Limilab.vb b/Messaging/Limilab.vb index c48632f9..fc583368 100644 --- a/Messaging/Limilab.vb +++ b/Messaging/Limilab.vb @@ -283,7 +283,7 @@ Public Class Limilab Dim email As IMail = oMailBuilder.Create() ' Send the message - Using oSmtp As New Smtp() + Using oSmtp As New Limilabs.Client.SMTP.Smtp() AddHandler oSmtp.ServerCertificateValidate, AddressOf Validate Logger.Debug($"AUTH_TYPE [{AUTH_TYPE}]") If AUTH_TYPE = "SSL" Then diff --git a/Messaging/MailSender.vb b/Messaging/MailSender.vb new file mode 100644 index 00000000..3181d127 --- /dev/null +++ b/Messaging/MailSender.vb @@ -0,0 +1,244 @@ +Imports DigitalData.Modules.Logging +Imports DigitalData.Modules.Base +Imports System.Net.Security +Imports Limilabs.Client.SMTP +Imports Limilabs.Client + +Public Class MailSender + Inherits BaseClass + + Private Server As String + Private Port As Integer + Private User As String + Private Password As String + Private AuthType As String + + Private Session As Smtp = Nothing + + Const SMTP_IGNORED_ERRORS As SslPolicyErrors = + SslPolicyErrors.RemoteCertificateChainErrors Or ' self-signed + SslPolicyErrors.RemoteCertificateNameMismatch ' name mismatch + + Public Sub New(pLogConfig As LogConfig) + MyBase.New(pLogConfig) + End Sub + + ''' + ''' Start a connection with the specified server and return the SMTP client. Throws if there was an error. + ''' + ''' + ''' + ''' + ''' + ''' + ''' + Public Function ConnectToServer(pServer As String, pPort As Integer, pUser As String, pPassword As String, pAuthType As String) As Boolean + Server = pServer + Port = pPort + User = pUser + Password = pPassword + AuthType = pAuthType + + Logger.Info("Connecting to Server..") + Logger.Debug("SMTP Server: [{0}]", Server) + Logger.Debug("SMTP Port: [{0}]", Port) + Logger.Debug("SMTP User: [{0}]", User) + Logger.Debug("SMTP AuthType: [{0}]", AuthType) + + Dim oSession As New Smtp() + AddHandler oSession.ServerCertificateValidate, AddressOf Session_ServerCertificateValidate + + Logger.Debug("Initializing Connection with Auth type [{0}].", pAuthType) + + If pAuthType = "SSL" Then + Try + If pPort = 465 Then + Logger.Debug("Connecting with [ConnectSSL] on [{0}/{1}]", pServer, pPort) + oSession.ConnectSSL(pServer) + Else + Logger.Debug("Connecting with [Connect] on [{0}/{1}]", pServer, pPort) + oSession.Connect(pServer, pPort) + End If + Logger.Info("Connection Successful!") + + Catch ex As Exception + Logger.Warn("Error while connecting with Auth type SSL!") + Logger.Error(ex) + + Return False + End Try + + ElseIf AuthType = "SSL/TLS" Or AuthType = "STARTTLS" Then + + Try + Logger.Debug("Connecting with [Connect] on [{0}/{1}]", pServer, pPort) + oSession.Connect(pServer, pPort) + Logger.Info("Connection Successful!") + + Dim oSupportsSTARTTLS As Boolean = oSession.SupportedExtensions.Contains(Limilabs.Client.SMTP.SmtpExtension.StartTLS) + Logger.Debug("Server supports STARTTLS: [{0}]", oSupportsSTARTTLS) + + If oSupportsSTARTTLS Then + oSession.StartTLS() + Logger.Info("STARTTLS Successful!") + Else + Logger.Debug("Server does not support STARTTLS. Enabling TLS1.2 instead.") + oSession.SSLConfiguration.EnabledSslProtocols = Security.Authentication.SslProtocols.Tls12 + End If + + Catch ex As Exception + Logger.Warn("Error while connecting with Auth type STARTTLS!") + Logger.Error(ex) + + Return False + End Try + + Else + Try + Logger.Debug("Unknown Auth type. Using PLAINTEXT connection.") + oSession.Connect(pServer) + Logger.Info("Connection Successful!") + Catch ex As Exception + Logger.Warn("Error while connecting with Auth type PLAINTEXT!") + Logger.Error(ex) + + Return False + End Try + + End If + + Try + Logger.Info("Logging in with user [{0}]", pUser) + oSession.UseBestLogin(pUser, pPassword) + + Catch ex As Exception + Logger.Warn("Error while connecting with Auth type PLAINTEXT!") + Logger.Error(ex) + + Return False + End Try + + Session = oSession + + Return True + End Function + + Public Function DisconnectFromServer() As Boolean + Try + If Session IsNot Nothing Then + Logger.Debug("Closing connection to Server [{0}].", Server) + Session.Close() + Session = Nothing + Logger.Info("Connection to Server [{0}] closed.", Server) + Else + Logger.Debug("No connection currently open. Exiting.") + End If + + Return True + + Catch ex As Exception + Logger.Error(ex) + Return False + + End Try + End Function + + Private Sub Session_ServerCertificateValidate(sender As Object, e As ServerCertificateValidateEventArgs) + ' i dont know why it works but it does + If (e.SslPolicyErrors And Not SMTP_IGNORED_ERRORS) = SslPolicyErrors.None Then + e.IsValid = True + Return + End If + e.IsValid = False + End Sub + + Public Function SendMail(pSendTo As List(Of String), pSendFrom As String, pSubject As String, pBody As String, pCreationTime As Date, pAttachments As List(Of String), pTest As Boolean) As Boolean + Dim oSuccessfulSends As New List(Of String) + Dim oFailedSends As New List(Of String) + + For Each oSendToAddress In pSendTo + Dim oResult = SendMailTo(Session, oSendToAddress, pSendFrom, pSubject, pBody, pCreationTime, pAttachments, pTest) + + If oResult = True Then + oSuccessfulSends.Add(oSendToAddress) + Else + oFailedSends.Add(oSendToAddress) + End If + Next + + Logger.Debug("Sent [{0}] mails.", pSendTo.Count) + Logger.Debug("Successful [{0}]", oSuccessfulSends.Count) + Logger.Debug("Failed [{0}]", oFailedSends.Count) + + Return True + End Function + + Private Function SendMailTo(pSession As Smtp, pSendTo As String, pSendFrom As String, pSubject As String, pBody As String, pCreationTime As Date, pAttachments As List(Of String), pTest As Boolean) + Try + Logger.Debug("Preparing to send mail to [{0}]", pSendTo) + + Dim oMailBuilder As New Limilabs.Mail.MailBuilder() + oMailBuilder.From.Add(New Limilabs.Mail.Headers.MailBox(pSendFrom)) + oMailBuilder.To.Add(New Limilabs.Mail.Headers.MailBox(pSendTo)) + oMailBuilder.Subject = pSubject + + Logger.Debug("Setting body for mail") + SetBody(oMailBuilder, pBody, pCreationTime, pTest) + + Logger.Debug("Adding [{0}] attachments to mail", pAttachments.Count) + oMailBuilder = AddAttachments(oMailBuilder, pAttachments) + + Logger.Debug("Now sending mail..") + Dim oMail = oMailBuilder.Create() + pSession.SendMessage(oMail) + Logger.Info("Mail to [{0}] has been sent.", pSendTo) + + Return True + + Catch ex As Exception + Logger.Warn("Error while sending mail to [{0}]", pSendTo) + Logger.Error(ex) + + Return False + End Try + End Function + + Private Function SetBody(pMailBuilder As Limilabs.Mail.MailBuilder, pBody As String, pCreationTime As Date, pTest As Boolean) As Limilabs.Mail.MailBuilder + If pCreationTime <> Date.MinValue Then + pBody &= $"

Creation-time: {pCreationTime}

" + End If + + If pTest Then + pBody = $"

This Is a Testmail!
+ The body-text will be replaced within profile!
+ Server/Port: {Server}/{Port}
+ User: {User}
+ Password: XXXX
+ Auth Type: {AuthType}

" + End If + + Logger.Debug("Final Mailbody is: [{0}]", pBody) + pMailBuilder.Html = pBody + + Return pMailBuilder + End Function + + Private Function AddAttachments(pMailBuilder As Limilabs.Mail.MailBuilder, pAttachments As List(Of String)) As Limilabs.Mail.MailBuilder + For Each oAttachment In pAttachments + Try + ' Read attachment from disk, add it to Attachments collection + If IO.File.Exists(oAttachment) Then + Logger.Debug("Adding attachment [{0}] to mail.", oAttachment) + pMailBuilder.AddAttachment(oAttachment) + Else + Logger.Warn("Attachment [{0}] does not exist. Skipping.", oAttachment) + End If + Catch ex As Exception + Logger.Warn("Could not read or add attachment [{0}]!", oAttachment) + Logger.Error(ex) + End Try + Next + + Return pMailBuilder + End Function +End Class diff --git a/Messaging/Messaging.vbproj b/Messaging/Messaging.vbproj index bb077481..c19ef3b3 100644 --- a/Messaging/Messaging.vbproj +++ b/Messaging/Messaging.vbproj @@ -95,7 +95,7 @@ Settings.settings True - + @@ -118,6 +118,10 @@ + + {6ea0c51f-c2b1-4462-8198-3de0b32b74f8} + Base + {991d0231-4623-496d-8bd0-9ca906029cbc} Filesystem diff --git a/Messaging/SMS.vb b/Messaging/SMS.vb deleted file mode 100644 index eeab6d15..00000000 --- a/Messaging/SMS.vb +++ /dev/null @@ -1,3 +0,0 @@ -Public Class SMS - -End Class