require usernames and passwords to be UTF-8 encoded

- Learn to support UTF-8 characters where it was not supported for usernames and
  passwords (but for netrc).
- Fix the types in the code for both py2 and py3: we now expect unicode for
  usernames and passwords.

Unicode (UTF-8) is required only for variables with non-ASCII characters.

Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Nicolas Sebrecht
2016-06-16 19:51:41 +02:00
parent 092264c8e7
commit 08e17de7e2
3 changed files with 40 additions and 22 deletions

View File

@ -154,6 +154,7 @@ class IMAPServer(object):
def __getpassword(self):
"""Returns the server password or None"""
if self.goodpassword != None: # use cached good one first
return self.goodpassword
@ -216,13 +217,15 @@ class IMAPServer(object):
authc = self.username
passwd = self.__getpassword()
authz = ''
authz = b''
if self.user_identity != None:
authz = self.user_identity
NULL = u'\x00'
retval = NULL.join((authz, authc, passwd)).encode('utf-8')
logsafe_retval = NULL.join((authz, authc, "(passwd hidden for log)")).encode('utf-8')
self.ui.debug('imap', '__plainhandler: returning %s' % logsafe_retval)
# At this point all authz, authc and passwd are expected bytes encoded
# in UTF-8.
NULL = b'\x00'
retval = NULL.join((authz, authc, passwd))
logsafe_retval = NULL.join((authz, authc, "(passwd hidden for log)"))
self.ui.debug('imap', '__plainhandler: returning %s'% logsafe_retval)
return retval

View File

@ -1,5 +1,5 @@
# IMAP repository support
# Copyright (C) 2002-2015 John Goerzen & contributors
# Copyright (C) 2002-2016 John Goerzen & contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -21,6 +21,7 @@ from sys import exc_info
import netrc
import errno
import six
import codecs
from offlineimap.repository.Base import BaseRepository
from offlineimap import folder, imaputil, imapserver, OfflineImapError
@ -129,7 +130,10 @@ class IMAPRepository(BaseRepository):
(currently -- PLAIN) to inform server about the ID
we want to authorize as instead of our login name."""
return self.getconf('remote_identity', default=None)
identity = self.getconf('remote_identity', default=None)
if identity != None:
identity = identity.encode('UTF-8')
return identity
def get_auth_mechanisms(self):
supported = ["GSSAPI", "XOAUTH2", "CRAM-MD5", "PLAIN", "LOGIN"]
@ -159,12 +163,12 @@ class IMAPRepository(BaseRepository):
if self.config.has_option(self.getsection(), 'remoteusereval'):
user = self.getconf('remoteusereval')
if user != None:
return localeval.eval(user)
return localeval.eval(user).encode('UTF-8')
if self.config.has_option(self.getsection(), 'remoteuser'):
user = self.getconf('remoteuser')
if user != None:
return user
return user.encode('UTF-8')
try:
netrcentry = netrc.netrc().authenticators(self.gethost())
@ -326,18 +330,18 @@ class IMAPRepository(BaseRepository):
# 1. evaluate Repository 'remotepasseval'
passwd = self.getconf('remotepasseval', None)
if passwd != None:
return self.localeval.eval(passwd)
return self.localeval.eval(passwd).encode('UTF-8')
# 2. read password from Repository 'remotepass'
password = self.getconf('remotepass', None)
if password != None:
return password
return password.encode('UTF-8')
# 3. read password from file specified in Repository 'remotepassfile'
passfile = self.getconf('remotepassfile', None)
if passfile != None:
fd = open(os.path.expanduser(passfile))
fd = codecs.open(os.path.expanduser(passfile), 'r', 'UTF-8')
password = fd.readline().strip()
fd.close()
return password
return password.encode('UTF-8')
# 4. read password from ~/.netrc
try:
netrcentry = netrc.netrc().authenticators(self.gethost())