2 restore-mail-inject.py - Tool to inject mails via IMAP
4 Copyright (c) 2012 Intra2net AG
10 MAILBOX_RESP = re.compile(r'\((?P<flags>.*?)\) "(?P<delimiter>.*)" (?P<name>.*)')
11 UIDVAL_RESP = re.compile(r'(?P<name>.*) \(UIDVALIDITY (?P<uidval>.*)\)')
12 ACLS_RESP = re.compile(b'(?P<user>.*) (?P<acls>.*)')
15 """This class communicates with the e-mail server."""
18 # IMAP4_SSL for connection with an IMAP server
20 # list of tuples (uidvalidity, mailboxname) for the retrieved mailboxes
25 def __init__(self, username):
26 """Creates a connection and a user session."""
30 self.mail_con = imaplib.IMAP4("intranator.m.i2n")
32 imap_socket = socket.socket(socket.AF_UNIX)
33 imap_socket.connect("/var/imap/socket/imap")
34 self.mail_con.sock = imap_socket
35 self.mail_con.file = self.mail_con.sock.makefile('rb')
36 print("Connected to mail server.")
37 except Exception as ex:
38 #raise UserWarning("Could not connect to host: %s" % (ex))
43 self.mail_con.login("cyrus", "geheim")
45 #self.mail_con.proxyauth(username)
46 print("Logged in as %s." % username)
48 self.logged_in = False
49 raise UserWarning("Could not log in as user " + username)
53 _result, mailboxes = self.mail_con.list()
54 except (self.mail_con.error):
55 raise UserWarning("Could not retrieve mailboxes for user " + username)
57 for mailbox in mailboxes:
58 mailbox = MAILBOX_RESP.match(mailbox.decode('iso-8859-1')).groups()
59 self.mailboxes.append(mailbox)
60 self.mailboxes = sorted(self.mailboxes, key=lambda box: box[2], reverse=True)
65 """Closes the connection and the user session."""
67 # self.mail_con.close()
68 # self.mail_con.logout()
70 def clear_inbox_acls(self, user):
71 """Resets the inbox acls for a given user."""
73 _result, inbox_acls = self.mail_con.getacl("INBOX")
75 print("Could not get the acls of INBOX.")
76 inbox_acls = ACLS_RESP.findall(inbox_acls[0][6:])
78 for acl_ref in inbox_acls:
79 if acl_ref[0] != user:
81 self.mail_con.setacl("INBOX", acl_ref[0], "")
82 print("Reset acls on INBOX for user %s" % acl_ref[0])
84 print("Could not reset acls on INBOX for user %s" % acl_ref[0])
87 def add_acls(self, mailbox, mailbox_list, original_user, target_user):
88 """Add acls to mailbox."""
90 # change encoding to internal cyrus format and make folder absolute
91 mailbox = mailbox.replace("INBOX/", "user/" + original_user + "/")
92 mailbox = mailbox.replace(".", "^")
93 mailbox = mailbox.replace("/", ".")
95 # find folder to set all acls
97 mbox_acls = mailbox_list[mailbox]
99 # no rights for the mailbox were found
101 for acl_user in mbox_acls:
102 if acl_user != target_user and acl_user != original_user:
104 self.mail_con.setacl(mailbox, acl_user, mbox_acls[acl_user])
105 print("Set acls %s for user %s on mailbox %s." % (mbox_acls[acl_user], acl_user, mailbox))
107 print("Could not set acls %s for user %s on mailbox %s." % (mbox_acls[acl_user], acl_user, mailbox))
111 def delete_mailboxes(self, deleted_mailbox):
112 """Delete specified mailbox or empty inbox."""
113 for mailbox in self.mailboxes:
114 pattern = '^\"?' + deleted_mailbox
115 # if INBOX it cannot be deleted so add delimiter
116 if (deleted_mailbox == "INBOX"):
117 pattern += mailbox[1]
118 if re.compile(pattern).match(mailbox[2]):
119 result, data = self.mail_con.delete(mailbox[2])
121 print("Deleted mailbox %s" % mailbox[2])
123 print("Could not delete folder %s: %s" % (mailbox[2], data[0]))
126 def create_mailbox(self, mailbox):
127 """Create new mailbox to inject messages."""
128 if mailbox != "INBOX":
129 result, data = self.mail_con.create(mailbox)
131 print("Creating mailbox %s" % mailbox)
133 print("Could not create mailbox %s: %s" % (mailbox, data[0]))
136 def inject_message(self, message, mailbox, internal_date):
137 """Inject a message into a mailbox."""
138 result, data = self.mail_con.append(mailbox, "\\Seen", internal_date, message.encode())
140 print("Appending message to mailbox %s" % mailbox)
142 print("Could not append the e-mail %s: %s" % (message, data[0]))