Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to avoid tls certificate validation #112

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/Seq.App.EmailPlus/DirectMailGateway.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ public async Task SendAsync(SmtpOptions options, MimeMessage message)
if (message == null) throw new ArgumentNullException(nameof(message));

var client = new SmtpClient();


if (options.SkipCertificateValidation == true)
{
// WARNING: this bypasses certificate validation.
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
}

await client.ConnectAsync(options.Host, options.Port, options.SocketOptions);
if (options.RequiresAuthentication)
await client.AuthenticateAsync(options.Username, options.Password);
Expand Down
44 changes: 27 additions & 17 deletions src/Seq.App.EmailPlus/EmailApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ public EmailApp()
"implicit SSL will be enabled; otherwise, the STARTTLS extension will be used.")]
public bool? EnableSsl { get; set; }

[SeqAppSetting(
IsOptional = true,
DisplayName = "Skip CertificateValidation",
HelpText = "This option allows you to have TLS enabled, but with an invalid certificate " +
"(expired, for another hostname, ...). Never use this in production.")]
public bool? SkipCertificateValidation { get; set; }

[SeqAppSetting(
IsOptional = true,
InputType = SettingInputType.LongText,
Expand All @@ -104,22 +111,22 @@ public EmailApp()
InputType = SettingInputType.Password,
HelpText = "The password to use when authenticating to the SMTP server, if required.")]
public string? Password { get; set; }

[SeqAppSetting(
DisplayName = "Time zone name",
IsOptional = true,
HelpText = "The IANA name of the time zone to use when formatting dates and times. The default is `Etc/UTC`. " +
"On Windows versions before Server 2019, and Seq versions before 2023.1, only Windows time zone " +
"names are accepted.")]
public string? TimeZoneName { get; set; }

[SeqAppSetting(
DisplayName = "Date/time format",
IsOptional = true,
HelpText = "A format string controlling how dates and times are formatted. Supports .NET date/time formatting " +
"syntax. The default is `o`, producing ISO-8601.")]
public string? DateTimeFormat { get; set; }

protected override void OnAttached()
{
var port = Port ?? DefaultPort;
Expand All @@ -130,13 +137,16 @@ protected override void OnAttached()
? RequireSslForPort(port)
: SecureSocketOptions.StartTlsWhenAvailable,
Username,
Password);
Password)
{
SkipCertificateValidation = SkipCertificateValidation ?? false,
};

_subjectTemplate = Handlebars.Compile(string.IsNullOrEmpty(SubjectTemplate)
? DefaultSubjectTemplate
_subjectTemplate = Handlebars.Compile(string.IsNullOrEmpty(SubjectTemplate)
? DefaultSubjectTemplate
: SubjectTemplate);
_bodyTemplate = Handlebars.Compile(string.IsNullOrEmpty(BodyTemplate)
? Resources.DefaultBodyTemplate
_bodyTemplate = Handlebars.Compile(string.IsNullOrEmpty(BodyTemplate)
? Resources.DefaultBodyTemplate
: BodyTemplate);
_toAddressesTemplate = string.IsNullOrEmpty(To) ? (_, _) => To : Handlebars.Compile(To);
}
Expand All @@ -146,7 +156,7 @@ public async Task OnAsync(Event<LogEventData> evt)
if (ShouldSuppress(evt)) return;

var to = FormatTemplate(_toAddressesTemplate!, evt, base.Host)
.Split(new[]{','}, StringSplitOptions.RemoveEmptyEntries);
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

if (to.Length == 0)
{
Expand All @@ -163,10 +173,10 @@ public async Task OnAsync(Event<LogEventData> evt)
await _mailGateway.SendAsync(
_options,
new MimeMessage(
new[] {MailboxAddress.Parse(From)},
new[] { MailboxAddress.Parse(From) },
to.Select(MailboxAddress.Parse),
subject,
new BodyBuilder {HtmlBody = body}.ToMessageBody()));
new BodyBuilder { HtmlBody = body }.ToMessageBody()));
}

bool ShouldSuppress(Event<LogEventData> evt)
Expand Down Expand Up @@ -207,10 +217,10 @@ internal static string FormatTemplate(Template template, Event<LogEventData> evt
{
if (template == null) throw new ArgumentNullException(nameof(template));
if (evt == null) throw new ArgumentNullException(nameof(evt));

var properties = (IDictionary<string,object?>) ToDynamic(evt.Data.Properties ?? new Dictionary<string, object?>());

var payload = (IDictionary<string,object?>) ToDynamic(new Dictionary<string, object?>
var properties = (IDictionary<string, object?>)ToDynamic(evt.Data.Properties ?? new Dictionary<string, object?>());

var payload = (IDictionary<string, object?>)ToDynamic(new Dictionary<string, object?>
{
{ "$Id", evt.Id },
{ "$UtcTimestamp", evt.TimestampUtc },
Expand All @@ -236,7 +246,7 @@ internal static string FormatTemplate(Template template, Event<LogEventData> evt

return template(payload);
}

string FormatTemplate(Template template, Event<LogEventData> evt, Host host)
{
return FormatTemplate(
Expand All @@ -246,7 +256,7 @@ string FormatTemplate(Template template, Event<LogEventData> evt, Host host)
string.IsNullOrEmpty(DateTimeFormat) ? "o" : DateTimeFormat!.Trim(),
string.IsNullOrEmpty(TimeZoneName) ? PortableTimeZoneInfo.UtcTimeZoneName : TimeZoneName!.Trim());
}

internal static string TestFormatTemplate(Template template, Event<LogEventData> evt, Host host)
{
return FormatTemplate(
Expand All @@ -262,7 +272,7 @@ static object ToDynamic(object o)
if (o is IEnumerable<KeyValuePair<string, object>> dictionary)
{
var result = new ExpandoObject();
var asDict = (IDictionary<string, object?>) result;
var asDict = (IDictionary<string, object?>)result;
foreach (var kvp in dictionary)
asDict.Add(kvp.Key, ToDynamic(kvp.Value));
return result;
Expand Down
1 change: 1 addition & 0 deletions src/Seq.App.EmailPlus/SmtpOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class SmtpOptions
public string Username { get; }
public string Password { get; }
public SecureSocketOptions SocketOptions { get; }
public bool? SkipCertificateValidation { get; set; }

public bool RequiresAuthentication => !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password);

Expand Down