aboutsummaryrefslogtreecommitdiffstats
path: root/pullimap
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2016-06-25 18:34:58 +0200
committerGuilhem Moulin <guilhem@fripost.org>2016-06-25 18:34:58 +0200
commit7e720edd5557a88b5e595240b123a7dad377c9a7 (patch)
tree4863a310df5258c092adb941eb1effd1bd10a9bb /pullimap
parent6ca6518df24a29590ed9e2a5eb3df3063d210787 (diff)
pullimap: quote the local part if need be (cf. RFC 5321).
Diffstat (limited to 'pullimap')
-rwxr-xr-xpullimap14
1 files changed, 13 insertions, 1 deletions
diff --git a/pullimap b/pullimap
index e971f64..18572e6 100755
--- a/pullimap
+++ b/pullimap
@@ -269,13 +269,25 @@ sub purge() {
my $ATTRS = "ENVELOPE INTERNALDATE";
$ATTRS .= " BODY.PEEK[]" unless $CONFIG{'no-delivery'};
+my $RE_ATOM = qr/[A-Za-z0-9\x21\x23-\x27\x2A\x2B\x2D\x2F\x3D\x3F\x5E-\x60\x7B-\x7E]+/;
sub pull_callback($$) {
my ($uids, $mail) = @_;
return unless exists $mail->{RFC822} or $CONFIG{'no-delivery'}; # not for us
my $uid = $mail->{UID};
my $from = first { defined $_ and @$_ } @{$mail->{ENVELOPE}}[2,3,4];
- $from = (defined $from and @$from) ? $from->[0]->[2].'@'.$from->[0]->[3] : '';
+ if (defined $from and @$from) {
+ my ($l, $d) = ($from->[0]->[2], $from->[0]->[3]);
+ if ($l !~ qr/\A$RE_ATOM(?:\.$RE_ATOM)*\z/o) { # Dot-string, RFC 5321
+ # quote the local part
+ $IMAP->panic("Invalid MAIL FROM: <$l\@$d>") unless $l =~ qr/\A[\x20-\x7E]*\z/;
+ $l =~ s/([\x22\x5C])/\\$1/g; # escape double-quote and backslash
+ $l = '"' .$l. '"';
+ }
+ $from = $l .'@'. $d;
+ } else {
+ $from = '';
+ }
$IMAP->log("UID $uid from <$from> ($mail->{INTERNALDATE})") unless $CONFIG{quiet};
sendmail($from, $mail->{RFC822}) unless $CONFIG{'no-delivery'};