Commit | Line | Data |
---|---|---|
67e2ec02 PD |
1 | ''' |
2 | restore-mail-inject.py - Tool to inject mails via IMAP | |
3 | ||
4 | Copyright (c) 2012 Intra2net AG | |
5 | ''' | |
6 | ||
4a1a0b03 | 7 | import socket, imaplib |
67e2ec02 PD |
8 | import re |
9 | ||
10 | MAILBOX_RESP = re.compile(r'\((?P<flags>.*?)\) "(?P<delimiter>.*)" (?P<name>.*)') | |
11 | UIDVAL_RESP = re.compile(r'(?P<name>.*) \(UIDVALIDITY (?P<uidval>.*)\)') | |
4a1a0b03 | 12 | ACLS_RESP = re.compile(b'(?P<user>.*) (?P<acls>.*)') |
67e2ec02 PD |
13 | |
14 | class MailIterator: | |
15 | """This class communicates with the e-mail server.""" | |
16 | ||
17 | # class attributes | |
18 | # IMAP4_SSL for connection with an IMAP server | |
19 | mail_con = None | |
20 | # list of tuples (uidvalidity, mailboxname) for the retrieved mailboxes | |
21 | mailboxes = None | |
22 | # logged in status | |
23 | logged_in = None | |
24 | ||
7aad8dab | 25 | def __init__(self, username): |
67e2ec02 | 26 | """Creates a connection and a user session.""" |
9ce1038d | 27 | |
b2bbd1f5 | 28 | # connect to server |
67e2ec02 | 29 | try: |
7aad8dab | 30 | self.mail_con = imaplib.IMAP4("intranator.m.i2n") |
4a1a0b03 PD |
31 | # MODIFIED |
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') | |
7aad8dab | 36 | print("Connected to mail server.") |
b2bbd1f5 | 37 | except Exception as ex: |
7aad8dab PD |
38 | #raise UserWarning("Could not connect to host: %s" % (ex)) |
39 | raise | |
b2bbd1f5 PD |
40 | |
41 | # log in | |
42 | try: | |
7aad8dab | 43 | self.mail_con.login("cyrus", "geheim") |
b2bbd1f5 | 44 | self.logged_in = True |
7aad8dab | 45 | #self.mail_con.proxyauth(username) |
67e2ec02 PD |
46 | print("Logged in as %s." % username) |
47 | except: | |
48 | self.logged_in = False | |
b2bbd1f5 | 49 | raise UserWarning("Could not log in as user " + username) |
9ce1038d | 50 | |
b2bbd1f5 PD |
51 | # list mailboxes |
52 | try: | |
53 | _result, mailboxes = self.mail_con.list() | |
54 | except (self.mail_con.error): | |
55 | raise UserWarning("Could not retrieve mailboxes for user " + username) | |
67e2ec02 PD |
56 | self.mailboxes = [] |
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) | |
9ce1038d | 61 | |
67e2ec02 PD |
62 | return |
63 | ||
64 | def __del__(self): | |
65 | """Closes the connection and the user session.""" | |
b2bbd1f5 PD |
66 | #if self.logged_in: |
67 | # self.mail_con.close() | |
68 | # self.mail_con.logout() | |
67e2ec02 PD |
69 | |
70 | def clear_inbox_acls(self, user): | |
b2bbd1f5 | 71 | """Resets the inbox acls for a given user.""" |
67e2ec02 | 72 | try: |
b2bbd1f5 | 73 | _result, inbox_acls = self.mail_con.getacl("INBOX") |
67e2ec02 PD |
74 | except: |
75 | print("Could not get the acls of INBOX.") | |
9ce1038d PD |
76 | inbox_acls = ACLS_RESP.findall(inbox_acls[0][6:]) |
77 | #print(inbox_acls) | |
78 | for acl_ref in inbox_acls: | |
79 | if acl_ref[0] != user: | |
67e2ec02 | 80 | try: |
9ce1038d PD |
81 | self.mail_con.setacl("INBOX", acl_ref[0], "") |
82 | print("Reset acls on INBOX for user %s" % acl_ref[0]) | |
67e2ec02 | 83 | except: |
9ce1038d | 84 | print("Could not reset acls on INBOX for user %s" % acl_ref[0]) |
67e2ec02 PD |
85 | return |
86 | ||
e42bd6a5 | 87 | def add_acls(self, mailbox, mailbox_list, original_user, target_user): |
67e2ec02 | 88 | """Add acls to mailbox.""" |
b2bbd1f5 | 89 | |
e42bd6a5 PD |
90 | # change encoding to internal cyrus format and make folder absolute |
91 | mailbox = mailbox.replace("INBOX/", "user/" + original_user + "/") | |
67e2ec02 PD |
92 | mailbox = mailbox.replace(".", "^") |
93 | mailbox = mailbox.replace("/", ".") | |
b2bbd1f5 | 94 | |
b0169e56 PD |
95 | # find folder to set all acls |
96 | try: | |
97 | mbox_acls = mailbox_list[mailbox] | |
98 | except KeyError: | |
99 | # no rights for the mailbox were found | |
100 | return | |
101 | for acl_user in mbox_acls: | |
b0169e56 PD |
102 | if acl_user != target_user and acl_user != original_user: |
103 | try: | |
b2bbd1f5 | 104 | self.mail_con.setacl(mailbox, acl_user, mbox_acls[acl_user]) |
b0169e56 PD |
105 | print("Set acls %s for user %s on mailbox %s." % (mbox_acls[acl_user], acl_user, mailbox)) |
106 | except: | |
107 | print("Could not set acls %s for user %s on mailbox %s." % (mbox_acls[acl_user], acl_user, mailbox)) | |
b2bbd1f5 | 108 | |
67e2ec02 PD |
109 | return |
110 | ||
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] | |
e42bd6a5 | 118 | if re.compile(pattern).match(mailbox[2]): |
67e2ec02 | 119 | result, data = self.mail_con.delete(mailbox[2]) |
e42bd6a5 | 120 | if result == "OK": |
67e2ec02 PD |
121 | print("Deleted mailbox %s" % mailbox[2]) |
122 | else: | |
123 | print("Could not delete folder %s: %s" % (mailbox[2], data[0])) | |
124 | return | |
125 | ||
126 | def create_mailbox(self, mailbox): | |
127 | """Create new mailbox to inject messages.""" | |
e42bd6a5 | 128 | if mailbox != "INBOX": |
67e2ec02 | 129 | result, data = self.mail_con.create(mailbox) |
e42bd6a5 | 130 | if result == "OK": |
67e2ec02 PD |
131 | print("Creating mailbox %s" % mailbox) |
132 | else: | |
133 | print("Could not create mailbox %s: %s" % (mailbox, data[0])) | |
134 | return | |
135 | ||
136 | def inject_message(self, message, mailbox, internal_date): | |
137 | """Inject a message into a mailbox.""" | |
7aad8dab | 138 | result, data = self.mail_con.append(mailbox, "\\Seen", internal_date, message.encode()) |
b2bbd1f5 | 139 | if result == "OK": |
67e2ec02 | 140 | print("Appending message to mailbox %s" % mailbox) |
b2bbd1f5 PD |
141 | else: |
142 | print("Could not append the e-mail %s: %s" % (message, data[0])) | |
67e2ec02 | 143 | return |