@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Don't bounce mail messages if any recipient was reserved

Summary:
Ref T13222. If we receive a message and nothing processes it, we normally try to send the user an error message like "hey, nothing handled this, maybe you got the address wrong".

Just skip the "send them an error message" part if any recipient was reserved, so if you "Reply All" to a message that is "From: noreply@phabricator" you don't get a relatively unhelpful error.

This also makes sure that the "void" address doesn't generate bounces if the "From" is a valid user email address (e.g., with `metamta.can-send-as-user`). That is:

- Phabricator needs to send a mail with only "CC" users.
- Phabricator puts the "void" address in "To" as a placeholder.
- The "void" address happens to route back to Phabricator.

We don't want that mail to bounce to anywhere. Normally, it won't:

- From is usually "noreply@phabricator", which isn't a user, so we won't send anything back: we only send mail to verified user email addresses.
- The message will have "X-Phabricator-Sent-This-Message: true" so we won't process it at all.

...but this is another layer of certainty.

Test Plan: Used `bin/mail receive-test` to receive mail to an invalid, unreserved address (bounce/error email) and an invalid, reserved address (no bounce/error email).

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13222

Differential Revision: https://secure.phabricator.com/D19987

+29 -1
+2
src/applications/metamta/constants/MetaMTAReceivedMailStatus.php
··· 16 16 const STATUS_UNHANDLED_EXCEPTION = 'err:exception'; 17 17 const STATUS_EMPTY = 'err:empty'; 18 18 const STATUS_EMPTY_IGNORED = 'err:empty-ignored'; 19 + const STATUS_RESERVED = 'err:reserved-recipient'; 19 20 20 21 public static function getHumanReadableName($status) { 21 22 $map = array( ··· 32 33 self::STATUS_UNHANDLED_EXCEPTION => pht('Unhandled Exception'), 33 34 self::STATUS_EMPTY => pht('Empty Mail'), 34 35 self::STATUS_EMPTY_IGNORED => pht('Ignored Empty Mail'), 36 + self::STATUS_RESERVED => pht('Reserved Recipient'), 35 37 ); 36 38 37 39 return idx($map, $status, pht('Processing Exception'));
+27 -1
src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php
··· 161 161 ->setFilterMethod('isEnabled') 162 162 ->execute(); 163 163 164 + $reserved_recipient = null; 164 165 $targets = $this->newTargetAddresses(); 165 166 foreach ($targets as $key => $target) { 166 167 // Never accept any reserved address as a mail target. This prevents 167 168 // security issues around "hostmaster@" and bad behavior with 168 169 // "noreply@". 169 170 if (PhabricatorMailUtil::isReservedAddress($target)) { 171 + if (!$reserved_recipient) { 172 + $reserved_recipient = $target; 173 + } 170 174 unset($targets[$key]); 171 175 continue; 172 176 } ··· 212 216 throw $receiver_exception; 213 217 } 214 218 219 + 215 220 if (!$any_accepted) { 216 - if (!$sender) { 221 + if ($reserved_recipient) { 222 + // If nothing accepted the mail, we normally raise an error to help 223 + // users who mistakenly send mail to "barges@" instead of "bugs@". 224 + 225 + // However, if the recipient list included a reserved recipient, we 226 + // don't bounce the mail with an error. 227 + 228 + // The intent here is that if a user does a "Reply All" and includes 229 + // "From: noreply@phabricator" in the receipient list, we just want 230 + // to drop the mail rather than send them an unhelpful bounce message. 231 + 232 + throw new PhabricatorMetaMTAReceivedMailProcessingException( 233 + MetaMTAReceivedMailStatus::STATUS_RESERVED, 234 + pht( 235 + 'No application handled this mail. This mail was sent to a '. 236 + 'reserved recipient ("%s") so bounces are suppressed.', 237 + (string)$reserved_recipient)); 238 + } else if (!$sender) { 217 239 // NOTE: Currently, we'll always drop this mail (since it's headed to 218 240 // an unverified recipient). See T12237. These details are still 219 241 // useful because they'll appear in the mail logs and Mail web UI. ··· 243 265 case MetaMTAReceivedMailStatus::STATUS_FROM_PHABRICATOR: 244 266 // Don't send an error email back in these cases, since they're 245 267 // very unlikely to be the sender's fault. 268 + break; 269 + case MetaMTAReceivedMailStatus::STATUS_RESERVED: 270 + // This probably is the sender's fault, but it's likely an accident 271 + // that we received the mail at all. 246 272 break; 247 273 case MetaMTAReceivedMailStatus::STATUS_EMPTY_IGNORED: 248 274 // This error is explicitly ignored.