X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=edward;h=d7443927cabc24fa373c66b8019015be5d981dd2;hb=cbe017bc9637a97c6275a1e3992760ee70f3860e;hp=3cbede14511bbf992edf8092d2e9737b681b1432;hpb=494c6e507d9b18a7f58e84655863ea1f435d31cb;p=edward.git diff --git a/edward b/edward index 3cbede1..d744392 100755 --- a/edward +++ b/edward @@ -51,7 +51,7 @@ from email.mime.nonmultipart import MIMENonMultipart import edward_config -langs = ["de", "el", "en", "es", "fr", "it", "ja", "pt-br", "ro", "ru", "tr"] +langs = ["de", "el", "en", "es", "fr", "it", "ja", "pt-br", "ro", "ru", "tr", "zh"] """This list contains the abbreviated names of reply languages available to edward.""" @@ -267,13 +267,18 @@ def main (): print_reply_only = handle_args() + email_bytes = sys.stdin.buffer.read() + + test_auto_reply(email_bytes) + gpgme_ctx = get_gpg_context(edward_config.gnupghome, edward_config.sign_with_key) - email_bytes = sys.stdin.buffer.read() + # do this twice so sigs can be verified with newly imported keys + parse_pgp_mime(email_bytes, gpgme_ctx) email_struct = parse_pgp_mime(email_bytes, gpgme_ctx) - email_to, email_from, email_subject = email_to_from_subject(email_bytes) + email_to, email_reply_to, email_subject = email_to_reply_to_subject(email_bytes) lang, reply_from = import_lang_pick_address(email_to, edward_config.hostname) replyinfo_obj = ReplyInfo() @@ -283,14 +288,14 @@ def main (): get_key_from_fp(replyinfo_obj, gpgme_ctx) reply_plaintext = write_reply(replyinfo_obj) - reply_mime = generate_encrypted_mime(reply_plaintext, email_from, \ + reply_mime = generate_encrypted_mime(reply_plaintext, email_reply_to, reply_from, \ email_subject, replyinfo_obj.encrypt_to_key, gpgme_ctx) if print_reply_only == True: print(reply_mime) else: - send_reply(reply_mime, email_from, reply_from) + send_reply(reply_mime, email_reply_to, reply_from) def get_gpg_context (gnupghome, sign_with_key_fp): @@ -406,8 +411,7 @@ def scan_and_split (payload_piece, match_name, pattern): return [payload_piece] flags = re.DOTALL | re.MULTILINE - matches = re.search("(?P.*?)(?P" + pattern + - ")(?P.*)", payload_piece.string, flags=flags) + matches = re.search(pattern, payload_piece.string, flags=flags) if matches == None: pieces = [payload_piece] @@ -415,15 +419,15 @@ def scan_and_split (payload_piece, match_name, pattern): else: beginning = PayloadPiece() - beginning.string = matches.group('beginning') + beginning.string = payload_piece.string[:matches.start()] beginning.piece_type = payload_piece.piece_type match = PayloadPiece() - match.string = matches.group('match') + match.string = payload_piece.string[matches.start():matches.end()] match.piece_type = match_name rest = PayloadPiece() - rest.string = matches.group('rest') + rest.string = payload_piece.string[matches.end():] rest.piece_type = payload_piece.piece_type more_pieces = scan_and_split(rest, match_name, pattern) @@ -971,15 +975,6 @@ def write_reply (replyinfo_obj): if replyinfo_obj.decrypt_success == True: debug('decrypt success') reply_plain += replyinfo_obj.replies['success_decrypt'] - - if (replyinfo_obj.sig_success == True) and (replyinfo_obj.have_reply_key == True): - debug('message quoted') - reply_plain += replyinfo_obj.replies['space'] - reply_plain += replyinfo_obj.replies['quote_follows'] - reply_plain += "\n\n" - quoted_text = email_quote_text(replyinfo_obj.msg_to_quote) - reply_plain += quoted_text - reply_plain += "\n\n" elif replyinfo_obj.decrypt_failure == True: @@ -1016,6 +1011,17 @@ def write_reply (replyinfo_obj): reply_plain += "\n\n" + if (replyinfo_obj.decrypt_success == True) \ + and (replyinfo_obj.sig_success == True) \ + and (replyinfo_obj.have_reply_key == True): + debug('message quoted') + reply_plain += replyinfo_obj.replies['quote_follows'] + reply_plain += "\n\n" + quoted_text = email_quote_text(replyinfo_obj.msg_to_quote) + reply_plain += quoted_text + reply_plain += "\n\n" + + if (reply_plain == ""): debug('plaintext message') reply_plain += replyinfo_obj.replies['failed_decrypt'] @@ -1239,8 +1245,34 @@ def is_key_usable (key_obj): return False -def email_to_from_subject (email_bytes): - """Returns the values of the email's To:, From: and Subject: fields +def test_auto_reply (email_bytes): + """Test whether email is auto-generated + + If the email is autogenerated, edward quits without sending a response. + This is not a perfect test. Some auto-responses will go undetected. + + Args: + email_bytes: the byte string from of the email + + Returns: + Nothing, or exits the program + """ + + email_struct = email.parser.BytesHeaderParser().parsebytes(email_bytes) + + auto_submitted = email_struct['Auto-Submitted'] + + if auto_submitted == None or auto_submitted == "no" \ + or auto_submitted == "No": + + return + + debug("autoreply") + exit(0) + + +def email_to_reply_to_subject (email_bytes): + """Returns the email's To:, Reply-To: (or From:), and Subject: fields Returns this information from an email. @@ -1248,16 +1280,21 @@ def email_to_from_subject (email_bytes): email_bytes: the byte string form of the email Returns: - the email To:, From:, and Subject: fields as strings + the email To:, Reply-To: (or From:), and Subject: fields as strings """ - email_struct = email.parser.BytesParser().parsebytes(email_bytes) + email_struct = email.parser.BytesHeaderParser().parsebytes(email_bytes) email_to = email_struct['To'] email_from = email_struct['From'] + email_reply_to = email_struct['Reply-To'] + email_subject = email_struct['Subject'] - return email_to, email_from, email_subject + if email_reply_to == None: + email_reply_to = email_from + + return email_to, email_reply_to, email_subject def import_lang_pick_address(email_to, hostname): @@ -1297,8 +1334,8 @@ def import_lang_pick_address(email_to, hostname): return lang_module, reply_from -def generate_encrypted_mime (plaintext, email_to, email_subject, encrypt_to_key, - gpgme_ctx): +def generate_encrypted_mime (plaintext, email_to, email_from, email_subject, + encrypt_to_key, gpgme_ctx): """This function creates the mime email reply. It can encrypt the email. If the encrypt_key is included, then the email is encrypted and signed. @@ -1346,7 +1383,10 @@ def generate_encrypted_mime (plaintext, email_to, email_subject, encrypt_to_key, else: message_mime = plaintext_mime + message_mime['Auto-Submitted'] = 'auto-replied' + message_mime['To'] = email_to + message_mime['From'] = email_from message_mime['Subject'] = email_subject reply = message_mime.as_string()