I have been writing an IMAP archival utility and one of the obstacles was getting PLAIN authentication to work. I know it does not sound complicated. PLAIN authentication allows for multiple identities, which allows a master user to access the mailbox of a regular user using the master user's password. This is vital to my utility as I do not want to keep track of the passwords of each user in the system. This was only a challenge because imaplib has close to no documentation. After sifting through the IMAP specifications and reading the code of imapsync, I have a working example!
1 2 3 4 5 6 7 | def login_plain(imap, user, password, authuser=None): def plain_callback(response): if authuser is None: return "%s\x00%s\x00%s" % (user, user, password) else: return "%s\x00%s\x00%s" % (user, authuser, password) return imap.authenticate('PLAIN', plain_callback) |
The imaplib.IMAP4 authenticate method has a weird way of working. It take two arguments. The first is a string declaring the method to use, PLAIN in this case. The second is a callable that returns a string or None. What should that string contain though? It is different for everything and you have to read specifications to know what is needed. PLAIN takes a null, \x00, delimited string of three fields. The first field is the authorization identity whose mailbox will be accessed. The second is the authentication identity whose credentials will be used. The third is the password. Pretty easy after that!!! Here is an example of how to use this:
import imaplib imapconn = imaplib.IMAP4_SSL(host1, 993) # Non-SSL works too # Login as tlesmann using adminuser's credentials login_plain(imapconn, 'tlesmann', 'adminuser', 'adminuserspassword')
This is how imaplib should work and now it will for you.
