1 #!/usr/bin/env python 2 3 from MoinMessage import * 4 from email.mime.application import MIMEApplication 5 from email.mime.text import MIMEText 6 from email.parser import Parser 7 from os.path import join, exists 8 from os import makedirs 9 import sys 10 11 def writefile(filename, s): 12 f = open(filename, "wb") 13 try: 14 f.write(s) 15 finally: 16 f.close() 17 18 if __name__ == "__main__": 19 try: 20 service = sys.argv[1] 21 signer = sys.argv[2] 22 url = sys.argv[3] 23 sender = sys.argv[4] 24 datetime = sys.argv[5] 25 target_dir = sys.argv[6] 26 except IndexError: 27 print >>sys.stderr, """\ 28 Need a service key identifier, signing key identifier, the repository URL, 29 sender identifier, the datetime of the last resources retrieved, and the target 30 directory as arguments to this program. 31 """ 32 sys.exit(1) 33 34 # Bundle files into a message. 35 36 message = Message() 37 38 part = MIMEText("\n".join([sender, datetime]), "moinmessage-request") 39 message.add_update(part) 40 41 # Get the e-mail message itself. 42 43 message = message.get_payload() 44 45 # Encrypt, sign and send the message. 46 47 gpg = GPG() 48 message = gpg.encryptMessage(message, service) 49 message = gpg.signMessage(message, signer) 50 resp = sendMessageForReading(message, url) 51 52 # Verify, decrypt and unpack the message. 53 54 try: 55 if not is_signed(message): 56 print >>sys.stderr, "Incoming message was not signed." 57 sys.exit(1) 58 59 message = Parser().parse(resp) 60 fingerprint, identity, content = gpg.verifyMessage(message) 61 62 if is_encrypted(content): 63 text = gpg.decryptMessage(content) 64 content = Parser().parsestr(text) 65 66 except MoinMessageDecodingError: 67 print >>sys.stderr, "Incoming message was improperly encoded." 68 sys.exit(1) 69 70 except MoinMessageError, exc: 71 print >>sys.stderr, "Incoming message was not verifiable: %s" % exc 72 sys.exit(1) 73 74 message = Message() 75 message.handle_message(content) 76 77 for part in message.updates: 78 79 # Use the "outer" filename to determine a directory for the retrieved 80 # file, even though the eventual filename in the directory may be 81 # different. 82 83 filename = part["Content-Disposition"] 84 directory, leafname = filename.split("/") 85 86 # The signed data will have been wrapped in a representation-insensitive 87 # part. 88 89 data = part.get_payload(decode=True) 90 91 # The data may be encrypted. 92 93 try: 94 data = gpg.decryptMessageText(data) 95 except MoinMessageError: 96 print >>sys.stderr, "Message part was not decrypted." 97 98 # Parse the decoded data. 99 100 content = Parser().parsestr(data) 101 102 if content.is_multipart(): 103 files = content.get_payload() 104 else: 105 files = [content] 106 107 # Treat each part of the verified, possibly encrypted message as a file. 108 109 for file in files: 110 data = file.get_payload(decode=True) 111 112 realname = file.get("Content-Disposition") 113 filename = join(directory, realname or leafname) 114 115 dirpath = join(target_dir, directory) 116 if not exists(dirpath): 117 makedirs(dirpath) 118 writefile(join(target_dir, filename), data) 119 120 # vim: tabstop=4 expandtab shiftwidth=4