-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Redirect mail (Resend/redirect/bounce) rfc5322 #1739
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found a few errors.
Some level of automated testing would be nice to see.
DateTimeField field = (DateTimeField)DefaultFieldParser.parse("Resent-Date: " | ||
+ MimeUtility.unfoldAndDecode(getFirstHeader("Resent-Date"))); | ||
mResentDate = field.getDate(); | ||
} catch (Exception e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Empty catch block
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the function tries to get the Resent-Date header from the headers list.
if there aint one or an error happens, then the internal one will be returned.
it's a perfect clone of the existing function getSentDate()
`
@Override
public Date getSentDate() {
if (mSentDate == null) {
try {
DateTimeField field = (DateTimeField)DefaultFieldParser.parse("Date: "
+ MimeUtility.unfoldAndDecode(getFirstHeader("Date")));
mSentDate = field.getDate();
} catch (Exception e) {
}
}
return mSentDate;
}
`
if (mResentTo == null) { | ||
mResentTo = Address.parse(MimeUtility.unfold(getFirstHeader("Resent-To"))); | ||
} | ||
return mTo; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is an error.
if (mResentCc == null) { | ||
mResentCc = Address.parse(MimeUtility.unfold(getFirstHeader("Resent-CC"))); | ||
} | ||
return mCc; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto
if (mResentBcc == null) { | ||
mResentBcc = Address.parse(MimeUtility.unfold(getFirstHeader("Resent-BCC"))); | ||
} | ||
return mBcc; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto
thanks for the review, i have fixed the errors! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remailing is a nice advanced feature. I wonder though if it is problematic with modern anti-spam techniques, since it essentially spoofs the sender address, doesn't it?
Possibly relevant: https://wiki.list.org/DEV/DMARC
I like the feature idea, but we should have a clear picture of these considerations before we merge this
@@ -509,6 +488,17 @@ public LocalMessage clone() { | |||
return message; | |||
} | |||
|
|||
public MimeMessage cloneAsSuper( boolean clearUid) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code style issues
@@ -142,7 +144,10 @@ public static void findViewablesAndAttachments(Part part, | |||
} | |||
|
|||
Body body = part.getBody(); | |||
if (body instanceof Multipart) { | |||
if (body instanceof BinaryMemoryBody) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of this? Seems like a hotfix to fix a very specific problem, which will have deep implications on content extraction behavior
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the diff here is shown misleading - please check the diff in MessageExtractor.java manually.
i had just added handling of BinaryMemoryBody for the specific case of redirecting.
i have reverted the change with a later commit.
@@ -159,6 +160,7 @@ | |||
*/ | |||
private Account mAccount; | |||
|
|||
private com.fsck.k9.mail.Body mRedirectBody = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no point fully qualifying this type
@@ -1489,12 +1533,28 @@ public void onMessageBuildSuccess(MimeMessage message, boolean isDraft) { | |||
} | |||
} else { | |||
currentMessageBuilder = null; | |||
|
|||
if (mAction == Action.REDIRECT) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This piece of logic is misplaced here, redirected messages should also be built by a MessageBuilder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the whole point of redirecting a message is to not modify the headers at all - except for adding resent-xxx headers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't matter what should or shouldn't be done to the message, there should be no logic that changes (or creates) the message here. that's the MessageBuilder's job
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i have added a new builder for resending messages - please review
setRecipients(type, addresses, true); | ||
} | ||
|
||
public void setRecipients(RecipientType type, Address[] addresses, boolean setHeader) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the setHeader
paramter allows desync of fields from the rfc2045 headers, which seems contrary to the purpose of MimeMessage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the whole code had been nearly duplicated for localmessage vs. mimemessage - with the exception of calling setHeader().
by adding the parameter now localmessage can use the same functionality without duplicating it, just by giving the setHeader parameter.
LocalMessage referenceMessage = mMessageReference.restoreToLocalMessage(getApplicationContext()); | ||
message = referenceMessage.cloneAsSuper(true); | ||
message.setResentDate(new Date(), K9.hideTimeZone()); | ||
message.setRecipients(RecipientType.RESENT_TO, toArray(recipientPresenter.getToAddresses())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this sets the resent-to header, but does it influence who the mail is actually sent to by way of the smtp-transport?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thats what the whole thing is about.
of cause k-9 only has to support the client part of adding the headers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The question was whether the RCPT in the smtp transport end up with the correct values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i haven't found any hint about the RCPT being wrong - nor about it would matter at all when using resent-headers.
do you have a server where you could test the behaviour?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'm just missing something here. Just to help me understand, at the end of this block of code the message that is queued for sending will be the originally referenced one, except with added Resent-
headers, right? But the addresses where the message will be actually delivered are the addresses in To
, Cc
and Bcc
(see SmtpTransport
), so doesn't that mean it will be sent to the same recipients as original one, rather than the ones they should be redirected to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
K-9 opens the connection to the mail server of the identity.
All headers (and later the body) are sent to the server.
If the server finds Resent-xxx headers then those will be used instead of the adresses in To, Cc, Bcc.
Not to the ones in To, Cc, Bcc.
Only to those in Resent-To, Resent-Cc, Resent-Bcc.
Example: Let's assume you send a message to my email1 and my email2. And i redirect from email2 to email3. Then you, email1 and email2 will not get the message again. It will only be sent to email3 and email3 will only see you as the sender and email2 and email3 as recipients.
That is by design and exactly what many people other than me seem to require as well =)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Valodim & @philipwhiuk - any idea why the SmtpTransportTest unit tests fail? |
Run them locally, and check out the html report file mentioned in the output, that should point you to the failing assertion. I'm also not really convinced yet that remailing is a use case that is still fine with how current mail transport networks work. Check out the DMARC FAQ, and maybe here and the wiki link above. |
I'd like to reassert that the DMARC problem mentioned above is a showstopper here. Without a good answer that clears up this problem, we won't be able to merge this PR, I suggest you look into this before investing more work |
Travis did test against latest whereas my source was on the branched version. |
In some cases bouncing a message can interfer with antispam-techniques when used "publically" - as your server will send with a "forged" sender (the original one). One possible way would imho be to at least set the smtp-envelope correctly to the re-sender but keep the mail itself as is. We use bouncing internally, locally on the same mailserver and with smtp-auth. In that scenario you can relax antispam-measurements for authenticated users and bouncing will work fine. Having bounce-functionality would be totally awesome. |
@neufeind absolutely, i agree about the smtp-envelope. |
Um, I think I'd like to see more of a rationale here than "might work in a special scenario or two, let's roll!" |
imho it's more a "might fail for certain people in certain scenarios" ... as will SPF when using normal email-forwarding :-) |
How about "might fail in the gmail case, as pointed out in a link above, and which is half of the email user base"? Ignoring this does not fill me with confidence that this has been thought through as much as it needs to be. And just to be clear, spf in some cases breaks "forwarding" as in the thing recipients set up ("forward incoming mail to other address" on a mail server), not as in the thing that happens when you click "forward" in an email client. Not sure how this is relevant in a discussion about clients though. |
With the latest commit 7e4f5d7 resending to Gmail addresses definitely works as expected. |
@philipwhiuk |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please clean up this branch so it only contains relevant commits.
sure. please let me know the details. |
One way is:
|
3b992a9
to
c51c1e8
Compare
please let me know if this is what you requested. |
Looking good! Thanks so far 👍 |
@philipwhiuk Thanks! 😃 |
@cketti The branch has been cleaned up as requested - please review. |
Thanks for cleaning up the branch which made it easier to see the changes. |
@cketti Do you mind sharing your reasons? |
It's functionality that is not commonly used/supported and has the potential to confuse non-expert users. Also, I believe clients should simply not be able to "resend" a message. |
There's also the DKIM/SPF/DMARC troubles. SMTP servers can't be assumed to deliver messages if they have From addresses your sending server isn't authorized for, and these policies are getting more and more strict these days. |
OK, make sense. Did K-9 gain support for attached email recently (both opening and forwarding as such)? Last time I checked that wasn’t working. |
Support for displaying |
I think having the forwarding functionality off by default and having to enable it in settings would be a better option. |
I agree with @the0ne. I am watching this issue for quite some time and can't wait to see this implemented. |
We've done that in the past. But adding all kinds of functionality with a setting to turn it on/off doesn't scale. The maintenance cost is real and part of what slows down development of the app. |
@neufeind and @darkdragon-001 feel free to build
I've been using these since a year now and the additions work pretty well. |
@the0ne please enable issues on your fork. While I can build the original |
I'd like to re-open that discussion since I also requested that feature in 2017 and I miss it every day (yes, every day!). Not every use case could be handled by forwarding a mail as an attachment. I often redirect mails from customers to employes or into ticket systems and there it's very important to keep the original from/sender address to send ticket notifications to the right people. I also prefer having mails from customers redirected to me, because then I'm able to search directly for a customer's mail instead of having thousands of mails that "seem" to come from my team and where the original sender isn't directly visible. Also DKIM/DMARC isn't really a problem here, since also redirected mails could get a new DKIM signature and/or the original DKIM signatur could/should stay in that mail. At the end, redirecting a mail is nothing else then redirecting mails with a virtual table on Postfix SMTP servers (which is a standard feature there for >15 years and working). SPF /could/ be a problem, but SPF is broken in general (so don't blame redirecting mails for problems if all kinds of forwardings do have problems with SPF) and also redirecting mails SHOULD change the SMTP envelope sender address (which is mostly matched against SPF) -- while the header sender/from isn't changed. Last but not least: The Redirect Plugin in Thunderbird is working perfectly for years now, but since K9 doesn't have this feature, I have to mark mails in K9 during the day to redirect them in thunderbird later when I'm back in the my office or back at home. I'm really missing that feature and there's no way to substitute it in a good way. |
@heinlein-support feel free to use k9mail-debug-5.600.apk.zip which includes the above implementation based on k9mail 5.600. It intentionally is the debug version so you can install and use it parallel to your regular k9mail if you want. Personally I did uninstall the regular k9mail on all of my devices quite a while ago as I feel same as you: I heavily use the redirect functionality and it works as well as the Thunderbird Redirect plugin. |
Hi the0ne, |
No chance to get this great and unproblematic feature into K9? |
Any News? It would be great to Add this. |
I'd like to see this in K9. Yes, the use cases are limited (spoofed sender). But bouncing a message from e.g. my personal company account to my company's ticket system is expected to work (depending on the setup of my company's mail system). |
this is a working proposal for the implementation of rfc5322