X-Git-Url: https://projects.mako.cc/source/attachcheck/blobdiff_plain/023d680cdab18123a86099680f3ac33f95196b67..HEAD:/attachcheck diff --git a/attachcheck b/attachcheck old mode 100644 new mode 100755 index 60da156..19159e4 --- a/attachcheck +++ b/attachcheck @@ -1,16 +1,26 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # AttachCheck -- A MTA wrapper to help check outgoing email for # forgotten attachments. -# (c) 2005 -- Benjamin Mako Hill -# Author/Software Homepage at: http://mako.cc +# (c) 2004-2009 -- Benjamin Mako Hill +# Software Homepage at: http://mako.cc/projects/attachcheck -# This software comes with ABSOLUTELY NO WARRANTY. -# This is free software and is licensed under the GNU GPL. +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or (at +# your option) any later version. -__copyright__ = "Copyright (c) 2004 Benjamin Mako Hill" -__author__ = "Benjamin Mako Hill " +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +__copyright__ = "Copyright (c) 2004-2009 Benjamin Mako Hill" +__author__ = "Benjamin Mako Hill " ### Configuration Options ########################################### @@ -24,9 +34,11 @@ ignored_types = ( "applica/pgp-signat", "application/pgp-signature" ) # list of regular expressions which we will view as being indicative # of an attachment -attachment_regexes = [ r'\battach(ed|ment|ing)?\b(?im)', +attachment_regexes = [ r'\battach(ed|ment|ing)?\b', r'\balleg(o|at[oaie]|ando)' ] +# ignore quoted text (which might refer to attachments in previous emails) +attachment_regexes = [ r'(?im)(^|^[^\n>].*)' + x for x in attachment_regexes ] ### No Edit Below This Line ########################################### @@ -37,14 +49,24 @@ import email import re ## SUB: send message -def send_message(): - mailpipe = os.popen("%s -t" % sendmail, 'w') - mailpipe.write( message_string ) - sys.exit( mailpipe.close() ) +def send_message(message): + + global sendmail + + # construct the sendmail pipe more safely (thanks iain murray!) + cmd = sys.argv[:] + cmd[0] = sendmail + + from subprocess import Popen, PIPE + process = Popen(cmd, stdin=PIPE) + mailpipe = process.stdin + mailpipe.write( message.as_string().encode() ) + mailpipe.close() + sys.exit( process.wait() ) ## SUB: print error message def print_error(): - print >>sys.stderr, \ + print(\ """(Your message mentions attachments but does not include any. Either: @@ -56,11 +78,11 @@ Either: (2) Add a \"X-AttachCheck-Override: Yes\" header the message. -Read the documentation for AttachCheck for more details.""" +Read the documentation for AttachCheck for more details.""", file=sys.stderr) # get the mail from stdin -message_string = sys.stdin.read() -message = email.message_from_string( message_string ) +message_bytes = sys.stdin.buffer.read() +message = email.message_from_bytes( message_bytes ) attachment_expected = False attachment_seen = False @@ -87,8 +109,8 @@ for part in message.walk(): attachment_expected = True # check to see if this mime-type is something we can ignore - elif ( re.match( r'message/(?m)', part.get_content_type() ) or - re.match( r'multipart/(?m)', part.get_content_type() ) or + elif ( re.match( r'(?m)message/', part.get_content_type() ) or + re.match( r'(?m)multipart/', part.get_content_type() ) or part.get_content_type() in ignored_types ): continue @@ -102,21 +124,22 @@ if attachment_expected: # if we are expecting an attachment and we've seen one, we should # send the file and be done with things if attachment_seen: - send_message() + send_message(message) # if we are expected have not seen it, we need to check to see if # the mail has been confirmed else: # check for the confirmation - - if re.search( r'Subject: CONFIRM', message_string ): - message_string = re.sub( r'(Subject: )(CONFIRM )(.*?)\n', - r'\1\3\n', message_string ) - send_message() - - elif message.get( 'X-AttachCheck-Override' ) == "Yes": - send_message() + subject_string = message['Subject'] + print(subject_string) + if re.search( r'^\s*CONFIRM', subject_string ): + subject_string = re.sub( r'(CONFIRM )(.*?)', r'\2', subject_string ) + message['Subject'] = subject_string + send_message(message) + + elif message['X-AttachCheck-Override'] == "Yes": + send_message(message) else: print_error() @@ -125,4 +148,4 @@ if attachment_expected: # if we are not expecting anything more, we should send the message else: - send_message() + send_message(message)