Commit 8eeeb3d7 authored by charlie ablett's avatar charlie ablett

Handle received header fallback for missing Delivered-To

Changelog: fixed
parent fac71f1e
......@@ -8,6 +8,8 @@ module Gitlab
class Receiver
include Gitlab::Utils::StrongMemoize
RECEIVER_HEADER_REGEX = /for \<(.*)\>/.freeze
def initialize(raw)
@raw = raw
end
......@@ -37,6 +39,8 @@ module Gitlab
delivered_to: delivered_to.map(&:value),
envelope_to: envelope_to.map(&:value),
x_envelope_to: x_envelope_to.map(&:value),
# reduced down to what looks like an email in the received headers
received_recipients: received_headers_containing_possible_recipients.map(&:value).map { |v| RECEIVER_HEADER_REGEX.match(v)[1] },
meta: {
client_id: "email/#{mail.from.first}",
project: handler&.project&.full_path
......@@ -82,7 +86,8 @@ module Gitlab
find_key_from_references ||
find_key_from_delivered_to_header ||
find_key_from_envelope_to_header ||
find_key_from_x_envelope_to_header
find_key_from_x_envelope_to_header ||
find_first_key_from_received_headers
end
def ensure_references_array(references)
......@@ -117,6 +122,10 @@ module Gitlab
Array(mail[:x_envelope_to])
end
def received
Array(mail[:received])
end
def find_key_from_delivered_to_header
delivered_to.find do |header|
key = email_class.key_from_address(header.value)
......@@ -138,6 +147,29 @@ module Gitlab
end
end
def find_first_key_from_received_headers
# there are often multiple Received headers
# and we just want ones that has something that looks like an email
# and return the first one that matches
filtered = received_headers_containing_possible_recipients
matching = filtered.map(&:value).grep(RECEIVER_HEADER_REGEX)
matching.find do |value|
looks_like_email = RECEIVER_HEADER_REGEX.match(value)
key = email_class.key_from_address(looks_like_email[1])
break key if key
end
end
def received_headers_containing_possible_recipients
strong_memoize :matching_received_headers do
# there are often multiple Received headers so we filter them out
# and also have some extra stuff so we have to strip that out
received.select { |header| RECEIVER_HEADER_REGEX =~ header.value }
end
end
def ignore_auto_reply!
if auto_submitted? || auto_replied?
raise AutoGeneratedEmailError
......
Return-Path: <jake@example.com>
Received: from myserver.example.com ([unix socket]) by myserver (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Received: from blabla.google.com (blabla.google.com. [1.1.1.1])
by bla.google.com with SMTPS id something.1.1.1.1.1.1.1
for <incoming+gitlabhq/gitlabhq+auth_token@appmail.example.com>
(Google Transport Security);
Mon, 21 Feb 2022 14:41:58 -0800 (PST)
Received: from mail.example.com (mail.example.com [IPv6:2607:f8b0:4001:c03::234]) by myserver.example.com (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@example.com>; Thu, 13 Jun 2013 17:03:50 -0400
From: "jake@example.com" <jake@example.com>
To: "support@example.com" <support@example.com>
Subject: Insert hilarious subject line here
Date: Tue, 26 Nov 2019 14:22:41 +0000
Message-ID: <7e2296f83dbf4de388cbf5f56f52c11f@EXDAG29-1.EXCHANGE.INT>
Accept-Language: de-DE, en-US
Content-Language: de-DE
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
x-ms-exchange-transport-fromentityheader: Hosted
x-originating-ip: [62.96.54.178]
Content-Type: multipart/alternative;
boundary="_000_7e2296f83dbf4de388cbf5f56f52c11fEXDAG291EXCHANGEINT_"
MIME-Version: 1.0
--_000_7e2296f83dbf4de388cbf5f56f52c11fEXDAG291EXCHANGEINT_
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
--_000_7e2296f83dbf4de388cbf5f56f52c11fEXDAG291EXCHANGEINT_
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Look, a message with no Delivered-To header! Let's fallback to Received: in case it's there.
Return-Path: <jake@adventuretime.ooo>
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq-gitlabhq-project_id-auth_token-issue-issue_iid@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq-gitlabhq-project_id-auth_token-issue-issue_iid@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Date: Thu, 13 Jun 2013 17:03:48 -0400
......
......@@ -32,7 +32,7 @@ RSpec.describe Gitlab::Email::Receiver do
metadata = receiver.mail_metadata
expect(metadata.keys).to match_array(%i(mail_uid from_address to_address mail_key references delivered_to envelope_to x_envelope_to meta))
expect(metadata.keys).to match_array(%i(mail_uid from_address to_address mail_key references delivered_to envelope_to x_envelope_to meta received_recipients))
expect(metadata[:meta]).to include(client_id: 'email/jake@example.com', project: project.full_path)
expect(metadata[meta_key]).to eq(meta_value)
end
......@@ -74,6 +74,14 @@ RSpec.describe Gitlab::Email::Receiver do
it_behaves_like 'successful receive'
end
context 'when all other headers are missing, fall back to checking Received headers' do
let(:email_raw) { fixture_file('emails/missing_delivered_to_header.eml') }
let(:meta_key) { :received_recipients }
let(:meta_value) { ['incoming+gitlabhq/gitlabhq+auth_token@appmail.example.com', 'incoming+gitlabhq/gitlabhq@example.com'] }
it_behaves_like 'successful receive'
end
end
shared_examples 'failed receive' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment