wolf2600 wolf2600 - 2 months ago 22
Python Question

Py3.4 IMAPLib Login... 'str' does not support the buffer interface

Using imaplib, I'm trying to connect to a mailserver.
When I include the password as just a normal string: 'password'
It connects fine. But I'm trying to slightly obfuscate my password, so I previously had run it through b64encode, and then used b64decode in the login:

#Works:
mail.login('myloginname', 'myPassword')

#Doesn't Work:
mail.login('myloginname', base64.b64decode('Ja3rHsnakhdgkhervc'))
# or
mail.login('myloginname', bytes(base64.b64decode('Ja3rHsnakhdgkhervc')))


...

Traceback (most recent call last):
File "./testing.py", line 15, in <module>
mail.login('myloginname', bytes(base64.b64decode('Ja3rHsnakhdgkhervc')))
File "/usr/local/lib/python3.4/imaplib.py", line 536, in login
typ, dat = self._simple_command('LOGIN', user, self._quote(password))
File "/usr/local/lib/python3.4/imaplib.py", line 1125, in _quote
arg = arg.replace('\\', '\\\\')
TypeError: 'str' does not support the buffer interface


Suggestions?

Answer

You are passing in a bytes object for the password, not a str value, because that's what base64.b64decode() returns.

You'd have to decode that value to a string:

 base64.b64decode('Ja3rHsnakhdgkhervc').decode('ascii')

The exception is caused by the bytes.replace() method, which expects bytes arguments. Since '\\' and '\\\\' are str objects, you get a traceback at args.replace('\\', '\\\\') only because args is a bytes object:

>>> b'foo'.replace('\\', '\\\\')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: a bytes-like object is required, not 'str'
>>> 'foo'.replace('\\', '\\\\')
'foo'
Comments