Skip to content

Commit

Permalink
Attribute Parser Should return an error if Email is longer than 80 ch…
Browse files Browse the repository at this point in the history
…aracters (#1492)

* feat: Attribute Parser Should return an error if Email is bigger than 80 characters

* feat: check if an email is valid when we process a new message

* feat: add test

* feat: fix tests

* feat: rename, put variable as constant and order tests

* feat: put same name as the P

* feat: add test for too large email is not added in database and the message is deleted
  • Loading branch information
MiguelAHM authored Jul 9, 2024
1 parent 05546e7 commit f6e821a
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import jakarta.mail.internet.MimeMultipart;
import net.ripe.db.whois.api.mail.EmailMessageInfo;
import net.ripe.db.whois.api.mail.exception.MailParsingException;
import net.ripe.db.whois.common.rpsl.AttributeParser;
import net.ripe.db.whois.common.rpsl.attrs.AttributeParseException;
import org.apache.commons.compress.utils.Lists;
import org.eclipse.angus.mail.dsn.DeliveryStatus;
import org.eclipse.angus.mail.dsn.MultipartReport;
Expand Down Expand Up @@ -40,6 +42,7 @@ public class BouncedMessageParser {

private static final Pattern FINAL_RECIPIENT_MATCHER = Pattern.compile("(?i)^(rfc822;)\s?(.+@.+$)");

private static final AttributeParser.EmailParser EMAIL_PARSER = new AttributeParser.EmailParser();

@Autowired
public BouncedMessageParser(@Value("${mail.smtp.from:}") final String smtpFrom) {
Expand Down Expand Up @@ -183,11 +186,23 @@ private List<String> extractRecipients(final DeliveryStatus deliveryStatus) {
LOGGER.error("Wrong formatted recipient {}", recipient);
continue;
}
recipients.add(finalRecipientMatcher.group(2));
final String email = finalRecipientMatcher.group(2);
if (isValidEmail(email)) {
recipients.add(email);
}
}
return recipients;
}

private boolean isValidEmail(final String email){
try {
EMAIL_PARSER.parse(email);
return true;
} catch (AttributeParseException ex){
return false;
}
}

private boolean isFailed(final DeliveryStatus deliveryStatus) {
for (int dsn = 0; dsn < deliveryStatus.getRecipientDSNCount(); dsn++) {
if ("failed".equals(getHeaderValue(deliveryStatus.getRecipientDSN(dsn), "Action"))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ public void parse_permanent_delivery_failure_message_rfc822_headers_real() throw
assertThat(bouncedMessage.emailAddresses(), containsInAnyOrder("[email protected]"));
}

@Test
public void parse_permanent_delivery_failure_to_a_too_long_recipient_then_recipient_ignored() throws Exception {
final EmailMessageInfo bouncedMessage = subject.parse(MimeMessageProvider.getUpdateMessage("permanentFailureMessageRfc822TooLongAddress.mail"));

assertThat(bouncedMessage.messageId(), is("[email protected]"));
assertThat(bouncedMessage.emailAddresses(), containsInAnyOrder("[email protected]"));
}

@Test
public void parse_permanent_delivery_failure_without_message_id() {
final MailParsingException e = assertThrows(MailParsingException.class, () -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,21 @@ public void permanent_delivery_failure_to_one_recipient_multiple_final_recipient

}

@Test
public void permanent_delivery_failure_to_one_recipient_too_long_address_then_delete_message_without_marking_undeliverable_address() {
insertOutgoingMessageId("[email protected]", "[email protected]");
final MimeMessage message = MimeMessageProvider.getUpdateMessage("permanentFailureMessageRfc822JustOneTooLongAddress.mail");
insertIncomingMessage(message);

// wait for incoming message to be processed
Awaitility.waitAtMost(10L, TimeUnit.SECONDS).until(() -> (! anyIncomingMessages()));

// delayed message has been processed but address is not set to undeliverable
assertThat(isUndeliverableAddress("[email protected]"), is(false));
assertThat(isUndeliverableAddress("G=noreply/S=noreply/O=noreplynoreplynorepl/P=AA/A=ripe.net/C=SP/@noreply.ripe.net"), is(false));
}


@Test
public void delayed_delivery_is_not_permanently_undeliverable() {
// insert delayed response
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5823,6 +5823,31 @@ public void undeliverable_notify_user_gets_warn_when_updating() {
undeliverableEmail, EmailStatus.UNDELIVERABLE.getValue());
}


@Test
public void create_too_big_address_then_error() {
final RpslObject PAULETH_PALTHEN_LONG_EMAIL = RpslObject.parse("" +
"person: Pauleth Palthen\n" +
"address: Singel 258\n" +
"phone: +31-1234567890\n" +
"e-mail: G=noreply/S=noreply/O=noreplynoreplynorepl/P=AA/A=ripe.net/C=SP/@noreply.ripe.net\n" +
"mnt-by: OWNER-MNT\n" +
"nic-hdl: PP1-TEST\n" +
"remarks: remark\n" +
"source: TEST\n");

final BadRequestException badRequestException = assertThrows(BadRequestException.class, () -> {
RestTest.target(getPort(), "whois/test/person?password=test")
.request()
.post(Entity.entity(map(PAULETH_PALTHEN_LONG_EMAIL), MediaType.APPLICATION_JSON_TYPE), WhoisResources.class);
});

assertThat(badRequestException.getMessage(), is("HTTP 400 Bad Request"));
final WhoisResources whoisResources = RestTest.mapClientException(badRequestException);
RestTest.assertErrorCount(whoisResources, 1);
RestTest.assertErrorMessage(whoisResources, 0, "Error", "Syntax error in %s", "G=noreply/S=noreply/O=noreplynoreplynorepl/P=AA/A=ripe.net/C=SP/@noreply.ripe.net");
}

// helper methods

private String encode(final String input) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
Return-path: <>
Envelope-to: [email protected]
Delivery-date: Fri, 23 Feb 2024 17:29:29 +0200
Received: from mahimahi.ripe.net ([193.0.19.1])
by allealle.ripe.net with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
(Exim 4.94)
id xxxxxx-0004d4-OF
for [email protected]; Fri, 23 Feb 2024 17:29:29 +0200
Received: from abc1.host.org ([68.232.147.154]:21686)
by mahimahi.ripe.net with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
(Exim 4.94.2)
id xxxxxx-0009P6-50
for [email protected]; Fri, 23 Feb 2024 17:29:29 +0200
Received: from localhost by abc1.host.org;
23 Feb 2024 11:29:19 -0400
Message-Id: <[email protected]>
Date: 23 Feb 2024 11:29:19 -0400
To: [email protected]
From: "Mail Delivery System" <[email protected]>
Subject: Delivery Status Notification (Failure)
MIME-Version: 1.0
Content-Type: multipart/report; report-type=delivery-status; boundary="6KTYe.5maleLdVv.5/WobWlHy4k.7vnm51B"
Delivered-To: [email protected]

--6KTYe.5maleLdVv.5/WobWlHy4k.7vnm51B
content-type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: quoted-printable

The following message to <[email protected]> was undeliverable.
The reason for the problem:
5.1.0 - Unknown address error 550-'5.4.1 Recipient address rejected: Access=
denied. AS(3333) [xxx.protection.outlook.com=
]'

--6KTYe.5maleLdVv.5/WobWlHy4k.7vnm51B
Content-Type: message/delivery-status

Reporting-MTA: dns; mx0.host.org
Received-From-MTA: DNS; mx0.host.org
Arrival-Date: Thu, 4 Apr 2024 09:26:37 +0300

Original-Recipient: rfc822;G=noreply/S=noreply/O=noreplynoreplynorepl/P=AA/A=ripe.net/C=SP/@noreply.ripe.net
Final-Recipient: RFC822; G=noreply/S=noreply/O=noreplynoreplynorepl/P=AA/A=ripe.net/C=SP/@noreply.ripe.net
Action: failed
Status: 5.7.1
Remote-MTA: DNS; mx0.host.org
Diagnostic-Code: SMTP; 550 5.7.1 This message is blocked due to security reason
Last-Attempt-Date: Thu, 4 Apr 2024 09:26:40 +0300

--6KTYe.5maleLdVv.5/WobWlHy4k.7vnm51B
content-type: message/rfc822

Received: from mahimahi.ripe.net ([193.0.19.1])
by abc1.host.org with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 23 Feb 2024 11:29:15 -0400
Received: from allealle.ripe.net ([193.0.23.2]:38580)
by mahimahi.ripe.net with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
(Exim 4.94.2)
(envelope-from <[email protected]>)
id xxxxxx-0009Oo-Ib
for [email protected]; Fri, 23 Feb 2024 17:29:13 +0200
Received: from whois.ipv6.ripe.net ([2001:67c:2e8:9::1234] helo=smtpclient.apple)
by allealle.ripe.net with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
(Exim 4.94)
(envelope-from <[email protected]>)
id xxxxxx-0004cV-FW
for [email protected]; Fri, 23 Feb 2024 17:29:13 +0200
From: Test DBM <[email protected]>
Reply-To: [email protected]
Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.80.0.2.43\))
Subject: Test Message
Message-Id: <[email protected]>
Date: Fri, 23 Feb 2024 17:29:10 +0200
To: [email protected]
X-Mailer: Apple Mail (2.3654.80.0.2.43)
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64

--6KTYe.5maleLdVv.5/WobWlHy4k.7vnm51B--


Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
Return-path: <>
Envelope-to: [email protected]
Delivery-date: Fri, 23 Feb 2024 17:29:29 +0200
Received: from mahimahi.ripe.net ([193.0.19.1])
by allealle.ripe.net with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
(Exim 4.94)
id xxxxxx-0004d4-OF
for [email protected]; Fri, 23 Feb 2024 17:29:29 +0200
Received: from abc1.host.org ([68.232.147.154]:21686)
by mahimahi.ripe.net with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
(Exim 4.94.2)
id xxxxxx-0009P6-50
for [email protected]; Fri, 23 Feb 2024 17:29:29 +0200
Received: from localhost by abc1.host.org;
23 Feb 2024 11:29:19 -0400
Message-Id: <[email protected]>
Date: 23 Feb 2024 11:29:19 -0400
To: [email protected]
From: "Mail Delivery System" <[email protected]>
Subject: Delivery Status Notification (Failure)
MIME-Version: 1.0
Content-Type: multipart/report; report-type=delivery-status; boundary="6KTYe.5maleLdVv.5/WobWlHy4k.7vnm51B"
Delivered-To: [email protected]

--6KTYe.5maleLdVv.5/WobWlHy4k.7vnm51B
content-type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: quoted-printable

The following message to <[email protected]> was undeliverable.
The reason for the problem:
5.1.0 - Unknown address error 550-'5.4.1 Recipient address rejected: Access=
denied. AS(3333) [xxx.protection.outlook.com=
]'

--6KTYe.5maleLdVv.5/WobWlHy4k.7vnm51B
Content-Type: message/delivery-status

Reporting-MTA: dns; mx0.host.org
Received-From-MTA: DNS; mx0.host.org
Arrival-Date: Thu, 4 Apr 2024 09:26:37 +0300

Original-Recipient: rfc822;[email protected]
Final-Recipient: RFC822; [email protected]
Action: failed
Status: 5.7.1
Remote-MTA: DNS; mx0.host.org
Diagnostic-Code: SMTP; 550 5.7.1 This message is blocked due to security reason
Last-Attempt-Date: Thu, 4 Apr 2024 09:26:40 +0300

Original-Recipient: rfc822;G=noreply/S=noreply/O=noreplynoreplynorepl/P=AA/A=ripe.net/C=SP/@noreply.ripe.net
Final-Recipient: RFC822; G=noreply/S=noreply/O=noreplynoreplynorepl/P=AA/A=ripe.net/C=SP/@noreply.ripe.net
Action: failed
Status: 5.7.1
Remote-MTA: DNS; mx0.host.org
Diagnostic-Code: SMTP; 550 5.7.1 This message is blocked due to security reason
Last-Attempt-Date: Thu, 4 Apr 2024 09:26:40 +0300

--6KTYe.5maleLdVv.5/WobWlHy4k.7vnm51B
content-type: message/rfc822

Received: from mahimahi.ripe.net ([193.0.19.1])
by abc1.host.org with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 23 Feb 2024 11:29:15 -0400
Received: from allealle.ripe.net ([193.0.23.2]:38580)
by mahimahi.ripe.net with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
(Exim 4.94.2)
(envelope-from <[email protected]>)
id xxxxxx-0009Oo-Ib
for [email protected]; Fri, 23 Feb 2024 17:29:13 +0200
Received: from whois.ipv6.ripe.net ([2001:67c:2e8:9::1234] helo=smtpclient.apple)
by allealle.ripe.net with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
(Exim 4.94)
(envelope-from <[email protected]>)
id xxxxxx-0004cV-FW
for [email protected]; Fri, 23 Feb 2024 17:29:13 +0200
From: Test DBM <[email protected]>
Reply-To: [email protected]
Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.80.0.2.43\))
Subject: Test Message
Message-Id: <[email protected]>
Date: Fri, 23 Feb 2024 17:29:10 +0200
To: [email protected]
X-Mailer: Apple Mail (2.3654.80.0.2.43)
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64

--6KTYe.5maleLdVv.5/WobWlHy4k.7vnm51B--


Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ public String parse(final String s) {

final class EmailParser implements AttributeParser<InternetAddress> {

private static final int MAXIMUM_LENGTH = 80;

@Override
public InternetAddress parse(final String s) {
final InternetAddress[] parsed;
Expand All @@ -199,6 +201,11 @@ public InternetAddress parse(final String s) {
final String address = parsed[0].getAddress();
final String localPart = address.substring(0, address.indexOf('@'));

if (address.length() > MAXIMUM_LENGTH){
throw new AttributeParseException(String.format("Illegal address length, maximum supported length is %d",
MAXIMUM_LENGTH), s);
}

if (!StandardCharsets.US_ASCII.newEncoder().canEncode(localPart)) {
throw new AttributeParseException("Address contains non ASCII characters (%s)", s);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,12 +239,13 @@ public void email() {
verifyFailure(ObjectType.PERSON, AttributeType.E_MAIL, "[email protected] 20180529");
verifyFailure(ObjectType.PERSON, AttributeType.E_MAIL, "a.a.a");
verifyFailure(ObjectType.PERSON, AttributeType.E_MAIL, "user");
verifyFailure(ObjectType.PERSON, AttributeType.E_MAIL, "0@2.45678901234567890123456789012345678901234567890123456789012345678901234567890"); //To large email

verifySuccess(ObjectType.PERSON, AttributeType.E_MAIL, "a@a");
verifySuccess(ObjectType.PERSON, AttributeType.E_MAIL, "[email protected]");
verifySuccess(ObjectType.PERSON, AttributeType.E_MAIL, "Any User <[email protected]>");
verifySuccess(ObjectType.PERSON, AttributeType.E_MAIL, "[email protected]");
verifySuccess(ObjectType.PERSON, AttributeType.E_MAIL, "0@2.45678901234567890123456789012345678901234567890123456789012345678901234567890");
verifySuccess(ObjectType.PERSON, AttributeType.E_MAIL, "0@2.4567890123456789012345678901234567890123456789012345678901234567890123456789");
verifySuccess(ObjectType.PERSON, AttributeType.E_MAIL, "test@ümlaut.email");
}

Expand Down

0 comments on commit f6e821a

Please sign in to comment.