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