Add support for .otp{login,pass} files to automatically login.
[easyotp.git] / SecureInbox.py
blobcb4ab87f616dcd56347e31f81addfd350f947f34
1 #!/bin/env python
2 # Created:20080603
3 # By Jeff Connelly
5 # Communicate with mail servers
7 import imaplib
8 import smtplib
9 import getpass
10 import email
12 class SecureInbox(object):
13 def __init__(self, username, password):
14 # IMAP SSL for incoming messages
15 self.mail_in = imaplib.IMAP4_SSL("imap.gmail.com", 993)
17 self.username = username
19 try:
20 typ, data = self.mail_in.login(username, password)
21 except imaplib.error, e:
22 raise "Login failure: %s" % (e,)
23 else:
24 assert typ == "OK", "imap login returned: %s %s" % (status, message)
25 print "Logged in:", typ, data
27 # Always have "Secure" mailbox selected
28 typ, num_msgs = self.mail_in.select(mailbox="Secure")
29 if typ != "OK":
30 raise ("imap select failure: %s %s" % (typ, num_msgs) +
31 "The 'Secure' tag doesn't exist. Tag some of your EMOTP messages" +
32 "using a new label, named 'Secure'")
34 # Outgoing mail, SMTP server
35 self.mail_out = smtplib.SMTP("smtp.gmail.com", 25)
36 ret = self.mail_out.ehlo()
37 assert ret[0] == 250, "SMTP server EHLO failed: %s" % (ret,)
39 ret = self.mail_out.starttls()
40 assert ret[0] == 220, "SMTP server STARTTLS failed: %s" % (ret,)
42 ret = self.mail_out.ehlo()
43 assert ret[0] == 250, "SMTP server EHLO over TLS failed: %s" % (ret,)
45 ret = self.mail_out.noop()
46 assert ret[0] == 250, "SMTP server NOOP failed: %s" % (ret,)
48 ret = self.mail_out.login(username, password)
49 assert ret[0] == 235, "SMTP server login failed: %s" % (ret,)
50 print "Logged in to SMTP server: %s" % (ret,)
52 def get_messages(self):
53 msgs = []
55 try:
56 typ, all_msgs_string = self.mail_in.search(None, 'ALL')
57 except imaplib.error, e:
58 raise "imap search failed: %s" % (e,)
60 all_msgs = all_msgs_string[0].split()
61 for num in all_msgs:
62 typ, body = self.mail_in.fetch(num, "(BODY[])")
63 msg = email.message_from_string(body[0][1])
65 body = str(msg.get_payload())
66 subject = msg.get("Subject")
67 sender = msg.get("From")
68 id = msg.get("Message-ID")
70 #print 'Message %s\n%s\n' % (num, data[0][1])
71 if "--EMOTP_BEGIN--" not in body:
72 continue
74 msgs.append({"body": body,
75 "subject": subject,
76 "sender": sender,
77 "id": id,
78 "num": num})
80 return msgs
82 def __iter__(self):
83 """Fetch messages from server."""
84 self.msgs = self.get_messages()
85 return iter(self.msgs)
87 def __getitem__(self, k):
88 """Lookup a message of a given number. Messages
89 must have been previous fetched from server up by __iter__"""
90 return self.msgs[k]
92 def send(self, to, subject, body):
93 from_address = "%s@gmail.com" % (self.username,)
94 return self.mail_out.sendmail(from_address,
95 [to],
96 "\r\n".join([
97 "From: %s" % (from_address,),
98 "To: %s" % (to,),
99 "Subject: %s" % (subject,),
101 body]))
103 def __del__(self):
104 self.mail_in.close()
105 self.mail_in.logout()
106 self.mail_out.quit()
108 def main():
109 ms = SecureInbox("shellreef", getpass.getpass())
111 for m in ms.get_messages():
112 print m["sender"], m["subject"]
114 if __name__ == "__main__":
115 main()