Skip to content

Commit

Permalink
[WIP] Fix handling of emails with missing headers
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-lerch committed Jan 1, 2025
1 parent 0955a9b commit 3e97d8b
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Korga.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_", "_", "{28945597-DB66-4C
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{2ED6D7FB-8B8A-4139-98C3-854E00A38490}"
ProjectSection(SolutionItems) = preProject
docs\docker-compose.yml = docs\docker-compose.yml
docs\compose.yaml = docs\compose.yaml
docs\email-processing-pipeline.md = docs\email-processing-pipeline.md
docs\frontend.md = docs\frontend.md
EndProjectSection
Expand Down
22 changes: 16 additions & 6 deletions server/Korga/EmailRelay/EmailRelayJobController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,22 @@ public EmailRelayJobController(DatabaseContext database, ILogger<EmailRelayJobCo

protected override async ValueTask ExecuteJob(InboxEmail email, CancellationToken cancellationToken)
{
if (email.From == null)
{
await RejectEmail(email, errorMessage: null, cancellationToken);

logger.LogWarning("Email #{Id} has no From header and will be rejected. " +
"According to RFC 5311 section 3.6, emails must include a From header. " +
"Please contact your email service provider.", email.Id);
return;
}

if (email.Receiver == null)
{
using MimeMessage? errorMessage = emailRelay.InvalidServerConfiguration(email);
await SendErrorMessage(email, errorMessage, cancellationToken);
await RejectEmail(email, errorMessage, cancellationToken);

logger.LogWarning("Could not determine receiver for message #{Id} from {From} to {To}. This message will not be forwarded." +
logger.LogWarning("Could not determine receiver for message #{Id} from {From} to {To}. This message will not be forwarded. " +
"Please make sure your email provider specifies the receiver in the Received, Envelope-To, or X-Envelope-To header", email.Id, email.From, email.To);
return;
}
Expand All @@ -56,7 +66,7 @@ protected override async ValueTask ExecuteJob(InboxEmail email, CancellationToke
if (distributionList == null)
{
using MimeMessage? errorMessage = emailRelay.InvalidAlias(email);
await SendErrorMessage(email, errorMessage, cancellationToken);
await RejectEmail(email, errorMessage, cancellationToken);

logger.LogInformation("No group found with alias {Receiver} for email #{Id} from {From}", email.Receiver, email.Id, email.From);
return;
Expand All @@ -65,7 +75,7 @@ protected override async ValueTask ExecuteJob(InboxEmail email, CancellationToke
if (email.Header == null)
{
using MimeMessage? errorMessage = emailRelay.TooManyHeaders(email);
await SendErrorMessage(email, errorMessage, cancellationToken);
await RejectEmail(email, errorMessage, cancellationToken);

logger.LogInformation("Email #{Id} from {From} to {Receiver} exceeded the header size limit", email.Id, email.From, email.Receiver);
return;
Expand All @@ -74,7 +84,7 @@ protected override async ValueTask ExecuteJob(InboxEmail email, CancellationToke
if (email.Body == null)
{
using MimeMessage? errorMessage = emailRelay.TooBigMessage(email);
await SendErrorMessage(email, errorMessage, cancellationToken);
await RejectEmail(email, errorMessage, cancellationToken);

logger.LogInformation("Email #{Id} from {From} to {Receiver} exceeded the body size limit", email.Id, email.From, email.Receiver);
return;
Expand All @@ -96,7 +106,7 @@ protected override async ValueTask ExecuteJob(InboxEmail email, CancellationToke
return;
}

private async ValueTask SendErrorMessage(InboxEmail email, MimeMessage? errorMessage, CancellationToken cancellationToken)
private async ValueTask RejectEmail(InboxEmail email, MimeMessage? errorMessage, CancellationToken cancellationToken)
{
if (errorMessage != null)
await emailDelivery.Enqueue(((MailboxAddress)errorMessage.To[0]).Address, errorMessage, email.Id, cancellationToken);
Expand Down
8 changes: 4 additions & 4 deletions server/Korga/EmailRelay/Entities/InboxEmail.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Korga.EmailRelay.Entities;

public class InboxEmail
{
public InboxEmail(uint? uniqueId, string subject, string from, string? sender, string? replyTo, string to, string? receiver, byte[]? header, byte[]? body)
public InboxEmail(uint? uniqueId, string? subject, string? from, string? sender, string? replyTo, string? to, string? receiver, byte[]? header, byte[]? body)
{
UniqueId = uniqueId;
Subject = subject;
Expand All @@ -23,11 +23,11 @@ public InboxEmail(uint? uniqueId, string subject, string from, string? sender, s
public DistributionList? DistributionList { get; set; }

public uint? UniqueId { get; set; }
public string Subject { get; set; }
public string From { get; set; }
public string? Subject { get; set; }
public string? From { get; set; }
public string? Sender { get; set; }
public string? ReplyTo { get; set; }
public string To { get; set; }
public string? To { get; set; }
/// <summary>
/// The mailbox this email was delivered to via SMTP.
/// Determined by <c>Received</c>, <c>Envelope-To</c> or <c>X-Envelope-To</c> headers.
Expand Down
6 changes: 4 additions & 2 deletions server/Korga/EmailRelay/ImapReceiverService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,10 @@ private async Task QueueEmailForProcessing(ImapClient imap, IMessageSummary mess
bodyContent = memoryStream.ToArray();
}

string from = message.Headers[HeaderId.From];
string to = message.Headers[HeaderId.To];
// According to RFC 5322 section 3.6, the Orig-Date and From headers are required
// In case of missing headers, the message will be rejected in the next pipeline step
string? from = message.Headers[HeaderId.From];
string? to = message.Headers[HeaderId.To];
string? receiver = message.Headers.GetReceiver();

InboxEmail emailEntity = new(
Expand Down

0 comments on commit 3e97d8b

Please sign in to comment.