diff -r 3ed5a6030c9b Lib/imaplib.py --- a/Lib/imaplib.py Mon Jan 02 19:18:02 2012 +0100 +++ b/Lib/imaplib.py Tue Jan 03 22:31:43 2012 +0200 @@ -1295,7 +1295,7 @@ # so when it gets to the end of the 8-bit input # there's no partial 6-bit output. # - oup = '' + oup = b'' while inp: if len(inp) > 48: t = inp[:48] @@ -1303,7 +1303,7 @@ else: t = inp inp = '' - e = binascii.b2a_base64(t) + e = binascii.b2a_base64(t.encode()) if e: oup = oup + e[:-1] return oup diff -r 3ed5a6030c9b Lib/test/test_imaplib.py --- a/Lib/test/test_imaplib.py Mon Jan 02 19:18:02 2012 +0100 +++ b/Lib/test/test_imaplib.py Tue Jan 03 22:31:43 2012 +0200 @@ -72,6 +72,9 @@ timeout = 1 + # Function to handle continuation input + _contcmd = None + def _send(self, message): if verbose: print("SENT: %r" % message.strip()) self.wfile.write(message) @@ -98,6 +101,10 @@ break if verbose: print('GOT: %r' % line.strip()) + if self._contcmd is not None: + self._contcmd(tag, line) + continue + splitline = line.split() tag = splitline[0].decode('ASCII') cmd = splitline[1].decode('ASCII') @@ -161,6 +168,50 @@ self.reap_server(server, thread) @reap_threads + def test_authenticate_plain(self): + """ Tests PLAIN authentication and logging out """ + + class AuthHandler(SimpleIMAPHandler): + + def cmd_CAPABILITY(self, tag, args): + self._send(b'* CAPABILITY IMAP4rev1 LOGINDISABLED AUTH=PLAIN\r\n') + self._send('{} OK Capability completed.\r\n'.format(tag).encode('ASCII')) + + def cmd_AUTHENTICATE(self, tag, args): + self._send(b'+ \r\n') + self._contcmd = self._cmd_AUTHENTICATE_CONT + + def _cmd_AUTHENTICATE_CONT(self, tag, args): + if args == b"dXNlcgB1c2VyAHBhc3M=\r\n": + self._send('{} OK PLAIN authentication successful\r\n' + .format(tag).encode('ASCII')) + else: + self._send('{} NO No access\r\n'.format(tag).encode('ASCII')) + self._contcmd = None + + def cmd_LOGOUT(self, tag, args): + self._send(b'* BYE Logging out\r\n') + self._send('{} OK Logout completed.\r\n'.format(tag).encode('ASCII')) + + with self.reaped_server(AuthHandler) as server: + try: + client = self.imap_class(*server.server_address) + except imaplib.IMAP4.abort: + self.fail("IMAP4 connection failed") + + self.assertTrue('AUTH=PLAIN' in client.capabilities) + + try: + authobj = lambda resp: "{0}\x00{0}\x00{1}".format("user", "pass") + ret, data = client.authenticate("PLAIN", authobj) + self.assertEqual(ret, "OK") + except imaplib.error: + self.fail("PLAIN authentication failed") + + ret, data = client.logout() + self.assertEqual(ret, "BYE") + + @reap_threads def test_connect(self): with self.reaped_server(SimpleIMAPHandler) as server: client = self.imap_class(*server.server_address)