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 Public Connected2Server As Boolean = False Const SMTP_IGNORED_ERRORS As SslPolicyErrors = SslPolicyErrors.RemoteCertificateChainErrors Or ' self-signed SslPolicyErrors.RemoteCertificateNameMismatch ' name mismatch Public Class MailSenderOptions Public Property EnableDefault As Boolean = True Public Property EnableTls1_1 As Boolean = False Public Property EnableTls1_2 As Boolean = False Public Property EnableTls1_3 As Boolean = False End Class Public Sub New(pLogConfig As LogConfig) MyBase.New(pLogConfig) End Sub Public Function ConnectToServer(pServer As String, pPort As Integer, pUser As String, pPassword As String, pAuthType As String) As Boolean Return ConnectToServer(pServer, pPort, pUser, pPassword, pAuthType) End Function ''' ''' 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, pOptions As MailSenderOptions) As Boolean Server = pServer Port = pPort User = pUser Password = pPassword AuthType = pAuthType Logger.Debug("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 pOptions.EnableDefault Then Logger.Debug("Enabling Default TLS Version") oSession.SSLConfiguration.EnabledSslProtocols = Security.Authentication.SslProtocols.Default Else Logger.Debug("Disabling Default TLS Version") oSession.SSLConfiguration.EnabledSslProtocols = Security.Authentication.SslProtocols.None End If ' Set TLS Version manually if requested If pOptions.EnableTls1_1 Then Logger.Debug("Enabling TLS Version 1.1") oSession.SSLConfiguration.EnabledSslProtocols = oSession.SSLConfiguration.EnabledSslProtocols Or Security.Authentication.SslProtocols.Tls11 End If If pOptions.EnableTls1_2 Then Logger.Debug("Enabling TLS Version 1.2") oSession.SSLConfiguration.EnabledSslProtocols = oSession.SSLConfiguration.EnabledSslProtocols Or Security.Authentication.SslProtocols.Tls12 End If If pOptions.EnableTls1_3 Then Logger.Debug("Enabling TLS Version 1.3") oSession.SSLConfiguration.EnabledSslProtocols = oSession.SSLConfiguration.EnabledSslProtocols Or Security.Authentication.SslProtocols.Tls13 End If Logger.Debug("Enabled Encryption Protocols: [{0}]", oSession.SSLConfiguration.EnabledSslProtocols) 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 If pUser <> String.Empty Then Logger.Info("Logging in with user [{0}]", pUser) oSession.UseBestLogin(pUser, pPassword) End If Catch ex As Exception Logger.Warn("Error while connecting with Auth type PLAINTEXT!") Logger.Error(ex) Return False End Try Session = oSession Connected2Server = True 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 If IsNothing(pSession) Then Logger.Info("ATTENTION-ERROR: pSession is nothing!") Return False End If 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..") If IsNothing(oMailBuilder) Then Logger.Info("ATTENTION-ERROR: oMailBuilder is nothing!") Return False End If 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