Bug#1009617: mailscripts: new script to reinject a message via sendmail: sendmail-reinject
Package: mailscripts Version: 0.24-1 Severity: wishlist Tags: patch Attached is a patch (via git format-patch) for a script to re-inject an existing message via sendmail. The script extracts the sender and all recipients from the message and constructs the appropriate sendmail command to re-send the message. This is very useful for messages that were fcc'd but for some reason failed to make it out on an initial pass (e.g. MTA misconfiguration). A man page is also included. Thanks for the useful package! jamie. -- System Information: Debian Release: bookworm/sid APT prefers testing APT policy: (600, 'testing'), (500, 'unstable-debug'), (200, 'unstable'), (101, 'experimental') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 5.16.0-5-amd64 (SMP w/8 CPU threads; PREEMPT) Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages mailscripts depends on: ii libconfig-tiny-perl2.28-1 ii libfile-which-perl 1.23-1 ii libipc-system-simple-perl 1.30-1 ii liblist-moreutils-perl 0.430-2 ii libmail-box-perl 3.009-1 ii perl 5.34.0-3 ii python33.9.8-1 Versions of packages mailscripts recommends: ii devscripts 2.22.1 ii git 1:2.35.1-1 ii libgit-wrapper-perl 0.048-1 ii notmuch 0.35-2 ii python3-argcomplete 1.12.3-0.1 ii python3-gssapi 1.6.12-2 ii python3-pgpy 0.5.4-4 Versions of packages mailscripts suggests: ii gnutls-bin 3.7.3-4+b1 ii gpg2.2.27-3+b1 ii gpg-agent 2.2.27-3+b1 ii gpgsm 2.2.27-3+b1 pn libdbd-sqlite3-perl ii libemail-date-format-perl 1.005-1.1 ii libio-socket-ssl-perl 2.074-2 ii libmailtools-perl 2.21-1 ii libmime-lite-perl 3.033-1 ii libtry-tiny-perl 0.31-1 pn libxml-feed-perl ii openssl1.1.1n-1 -- no debconf information >From 69693dcd497a2fae7f6eb7bdeb0545120b2cb0a6 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Tue, 12 Apr 2022 13:03:53 -0700 Subject: [PATCH] new script to reinject message via sendmail --- sendmail-reinject | 70 + sendmail-reinject.1.pod | 41 2 files changed, 111 insertions(+) create mode 100755 sendmail-reinject create mode 100644 sendmail-reinject.1.pod diff --git a/sendmail-reinject b/sendmail-reinject new file mode 100755 index 000..dfc18d5 --- /dev/null +++ b/sendmail-reinject @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 + +import sys +import argparse +import subprocess + +import email +from email.policy import default +from email.utils import parseaddr, getaddresses + + +def sendmail(recipients, message, sender): +"""send message via sendmail""" +cmd = [ +'sendmail', +'-f', sender, +] + recipients +print(' '.join(cmd), file=sys.stderr) +subprocess.run( +cmd, +input=message.as_bytes(), +check=True, +) + + +def main(): +parser = argparse.ArgumentParser( +description="Reinject an email message via sendmail.", +) +pgroup = parser.add_mutually_exclusive_group(required=True) +pgroup.add_argument( +'message', nargs='?', type=argparse.FileType('rb'), +help="email message path or '-' for stdin", +) +pgroup.add_argument( +'-i', '--id', +help="message ID for notmuch extraction", +) + +args = parser.parse_args() + +if args.id: +import notmuch2 as notmuch +db = notmuch.Database() +query = f'id:{args.id}' +assert db.count_messages(query) == 1, "Message ID does not match exactly one message??" +for msg in db.messages(query): +path = msg.path +break +f = open(path, 'rb') +else: +f = args.message + +# parse the email message +msg = email.message_from_binary_file(f, policy=default) + +sender = parseaddr(msg['from'])[1] + +# extract all recipients +tos = msg.get_all('to', []) +ccs = msg.get_all('cc', []) +resent_tos = msg.get_all('resent-to', []) +resent_ccs = msg.get_all('resent-cc', []) +recipients = [r[1] for r in getaddresses(tos + ccs + resent_tos + resent_ccs)] + +sendmail(recipients, msg, sender) + + +if __name__ == '__main__': +main() diff --git a/sendmail-reinject.1.pod b/sendmail-reinject.1.pod new file mode 100644 index 000..ed2ac22 --- /dev/null +++ b/sendmail-reinject.1.pod @@ -0,0 +1,41 @@ +=encoding utf8 + +=head1 NAME + +sendmail-reinject - reinject an e-mail via sendmail + +=head1 SYNOPSIS + +B B + +B B<-> + +B B<--id> B + +=head1 DESCRIPTION + +B reinjects a message to your MTA via sen
Bug#1009617: mailscripts: new script to reinject a message via sendmail: sendmail-reinject
Hello Jameson, On Tue 12 Apr 2022 at 03:17PM -07, Jameson Graef Rollins wrote: > Package: mailscripts > Version: 0.24-1 > Severity: wishlist > Tags: patch > > Attached is a patch (via git format-patch) for a script to re-inject > an existing message via sendmail. The script extracts the sender and > all recipients from the message and constructs the appropriate > sendmail command to re-send the message. This is very useful for > messages that were fcc'd but for some reason failed to make it out on > an initial pass (e.g. MTA misconfiguration). A man page is also > included. Cool, I'd like to add this. Just two questions - what license are you releasing it under? please add the usual copyright and license headers and update d/copyright - how about renaming --id to --notmuch-id or --notmuch-message-id ? -- Sean Whitton signature.asc Description: PGP signature
Bug#1009617: mailscripts: new script to reinject a message via sendmail: sendmail-reinject
On Wed, May 11 2022, Sean Whitton wrote: > Hello Jameson, > > On Tue 12 Apr 2022 at 03:17PM -07, Jameson Graef Rollins wrote: > >> Package: mailscripts >> Version: 0.24-1 >> Severity: wishlist >> Tags: patch >> >> Attached is a patch (via git format-patch) for a script to re-inject >> an existing message via sendmail. The script extracts the sender and >> all recipients from the message and constructs the appropriate >> sendmail command to re-send the message. This is very useful for >> messages that were fcc'd but for some reason failed to make it out on >> an initial pass (e.g. MTA misconfiguration). A man page is also >> included. > > Cool, I'd like to add this. Just two questions > > - what license are you releasing it under? please add the usual > copyright and license headers and update d/copyright > > - how about renaming --id to --notmuch-id or --notmuch-message-id ? Thanks Sean. --notmuch-id seems ok to me. Do you want to go ahead and make the change, or should I resend the patch? jamie.
Bug#1009617: mailscripts: new script to reinject a message via sendmail: sendmail-reinject
Hello, On Mon 16 May 2022 at 09:13am -07, Jameson Graef Rollins wrote: > On Wed, May 11 2022, Sean Whitton wrote: >> Hello Jameson, >> >> On Tue 12 Apr 2022 at 03:17PM -07, Jameson Graef Rollins wrote: >> >>> Package: mailscripts >>> Version: 0.24-1 >>> Severity: wishlist >>> Tags: patch >>> >>> Attached is a patch (via git format-patch) for a script to re-inject >>> an existing message via sendmail. The script extracts the sender and >>> all recipients from the message and constructs the appropriate >>> sendmail command to re-send the message. This is very useful for >>> messages that were fcc'd but for some reason failed to make it out on >>> an initial pass (e.g. MTA misconfiguration). A man page is also >>> included. >> >> Cool, I'd like to add this. Just two questions >> >> - what license are you releasing it under? please add the usual >> copyright and license headers and update d/copyright >> >> - how about renaming --id to --notmuch-id or --notmuch-message-id ? > > Thanks Sean. --notmuch-id seems ok to me. Do you want to go ahead and > make the change, or should I resend the patch? Well, you also need to add the license header, so please resend. -- Sean Whitton
Bug#1009617: mailscripts: new script to reinject a message via sendmail: sendmail-reinject
Here's a new version of the patch addressing Sean's comments. >From f4d9e714b556a144644cb597a783e4469506ddd1 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Tue, 12 Apr 2022 13:03:53 -0700 Subject: [PATCH] new script to reinject message via sendmail --- sendmail-reinject | 73 + sendmail-reinject.1.pod | 45 + 2 files changed, 118 insertions(+) create mode 100755 sendmail-reinject create mode 100644 sendmail-reinject.1.pod diff --git a/sendmail-reinject b/sendmail-reinject new file mode 100755 index 000..e50c484 --- /dev/null +++ b/sendmail-reinject @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright 2022 Jameson Graef Rollins + +import sys +import argparse +import subprocess + +import email +from email.policy import default +from email.utils import parseaddr, getaddresses + + +def sendmail(recipients, message, sender): +"""send message via sendmail""" +cmd = [ +'sendmail', +'-f', sender, +] + recipients +print(' '.join(cmd), file=sys.stderr) +subprocess.run( +cmd, +input=message.as_bytes(), +check=True, +) + + +def main(): +parser = argparse.ArgumentParser( +description="Reinject an email message via sendmail.", +) +pgroup = parser.add_mutually_exclusive_group(required=True) +pgroup.add_argument( +'message', nargs='?', type=argparse.FileType('rb'), +help="email message path or '-' for stdin", +) +pgroup.add_argument( +'-i', '--notmuch-id', +help="message ID for notmuch extraction", +) + +args = parser.parse_args() + +if args.id: +import notmuch2 as notmuch +db = notmuch.Database() +query = f'id:{args.id}' +assert db.count_messages(query) == 1, "Message ID does not match exactly one message??" +for msg in db.messages(query): +path = msg.path +break +f = open(path, 'rb') +else: +f = args.message + +# parse the email message +msg = email.message_from_binary_file(f, policy=default) + +sender = parseaddr(msg['from'])[1] + +# extract all recipients +tos = msg.get_all('to', []) +ccs = msg.get_all('cc', []) +resent_tos = msg.get_all('resent-to', []) +resent_ccs = msg.get_all('resent-cc', []) +recipients = [r[1] for r in getaddresses(tos + ccs + resent_tos + resent_ccs)] + +sendmail(recipients, msg, sender) + + +if __name__ == '__main__': +main() diff --git a/sendmail-reinject.1.pod b/sendmail-reinject.1.pod new file mode 100644 index 000..f89d0f1 --- /dev/null +++ b/sendmail-reinject.1.pod @@ -0,0 +1,45 @@ +=encoding utf8 + +=head1 NAME + +sendmail-reinject - reinject an e-mail via sendmail + +=head1 SYNOPSIS + +B B + +B B<-> + +B B<-i> B + + +=head1 DESCRIPTION + +B reinjects a message to your MTA via sendmail. +The message is read in (via path, stdin, or from notmuch via message +ID), the sender and recipients are extracted, and the appropriate +senmdail command is contructed to resent the message. + +=head1 OPTIONS + +=over 4 + +=item B<--notmuch-id>,B<-i> B + +Message ID of message to reinject as know to a local notmuch database. +Assumes the python3-notmuch package is available. + +=item B<--help>, B<-h> + +Show usage instructions. + +=back + +=head1 SEE ALSO + +sendmail(1), notmuch(1) + +=head1 AUTHOR + +B and this manpage were written by Jameson Graef +Rollins . -- 2.35.1
Bug#1009617: mailscripts: new script to reinject a message via sendmail: sendmail-reinject
Hello Jameson, On Mon 16 May 2022 at 12:33PM -07, Jameson Graef Rollins wrote: > Here's a new version of the patch addressing Sean's comments. I need it signed off; please see CONTRIBUTING.rst. -- Sean Whitton signature.asc Description: PGP signature
Bug#1009617: mailscripts: new script to reinject a message via sendmail: sendmail-reinject
One more time... >From 40e4e72fe8180c4ec387ce1c5b8662d5c6dd3ca2 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Tue, 12 Apr 2022 13:03:53 -0700 Subject: [PATCH] new script to reinject message via sendmail This script simply takes an existing mail file, parses it for sender and all recipients, and constructs an appropriate sendmail command to resend the message. It requires the sendmail binary at runtime, and the notmuch python library in order to extract the message from an existing notmuch store. Signed-off-by: Jameson Graef Rollins --- sendmail-reinject | 73 + sendmail-reinject.1.pod | 45 + 2 files changed, 118 insertions(+) create mode 100755 sendmail-reinject create mode 100644 sendmail-reinject.1.pod diff --git a/sendmail-reinject b/sendmail-reinject new file mode 100755 index 000..e50c484 --- /dev/null +++ b/sendmail-reinject @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright 2022 Jameson Graef Rollins + +import sys +import argparse +import subprocess + +import email +from email.policy import default +from email.utils import parseaddr, getaddresses + + +def sendmail(recipients, message, sender): +"""send message via sendmail""" +cmd = [ +'sendmail', +'-f', sender, +] + recipients +print(' '.join(cmd), file=sys.stderr) +subprocess.run( +cmd, +input=message.as_bytes(), +check=True, +) + + +def main(): +parser = argparse.ArgumentParser( +description="Reinject an email message via sendmail.", +) +pgroup = parser.add_mutually_exclusive_group(required=True) +pgroup.add_argument( +'message', nargs='?', type=argparse.FileType('rb'), +help="email message path or '-' for stdin", +) +pgroup.add_argument( +'-i', '--notmuch-id', +help="message ID for notmuch extraction", +) + +args = parser.parse_args() + +if args.id: +import notmuch2 as notmuch +db = notmuch.Database() +query = f'id:{args.id}' +assert db.count_messages(query) == 1, "Message ID does not match exactly one message??" +for msg in db.messages(query): +path = msg.path +break +f = open(path, 'rb') +else: +f = args.message + +# parse the email message +msg = email.message_from_binary_file(f, policy=default) + +sender = parseaddr(msg['from'])[1] + +# extract all recipients +tos = msg.get_all('to', []) +ccs = msg.get_all('cc', []) +resent_tos = msg.get_all('resent-to', []) +resent_ccs = msg.get_all('resent-cc', []) +recipients = [r[1] for r in getaddresses(tos + ccs + resent_tos + resent_ccs)] + +sendmail(recipients, msg, sender) + + +if __name__ == '__main__': +main() diff --git a/sendmail-reinject.1.pod b/sendmail-reinject.1.pod new file mode 100644 index 000..f89d0f1 --- /dev/null +++ b/sendmail-reinject.1.pod @@ -0,0 +1,45 @@ +=encoding utf8 + +=head1 NAME + +sendmail-reinject - reinject an e-mail via sendmail + +=head1 SYNOPSIS + +B B + +B B<-> + +B B<-i> B + + +=head1 DESCRIPTION + +B reinjects a message to your MTA via sendmail. +The message is read in (via path, stdin, or from notmuch via message +ID), the sender and recipients are extracted, and the appropriate +senmdail command is contructed to resent the message. + +=head1 OPTIONS + +=over 4 + +=item B<--notmuch-id>,B<-i> B + +Message ID of message to reinject as know to a local notmuch database. +Assumes the python3-notmuch package is available. + +=item B<--help>, B<-h> + +Show usage instructions. + +=back + +=head1 SEE ALSO + +sendmail(1), notmuch(1) + +=head1 AUTHOR + +B and this manpage were written by Jameson Graef +Rollins . -- 2.35.1