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:
		| @@ -590,9 +590,16 @@ type = IMAP | ||||
| # "getcredentials" that parses a file "filename" and returns the account | ||||
| # details for "hostname". | ||||
| # | ||||
| # | ||||
| #remotehosteval = getcredentials("filename", "hostname", "hostname") | ||||
| # | ||||
| # The returned value must be int type. | ||||
| #remoteporteval = getcredentials("filename", "hostname", "port") | ||||
| # | ||||
| # The returned value must be unicode type. | ||||
| #remoteusereval = getcredentials("filename", "hostname", "user") | ||||
| # | ||||
| # The returned value must be unicode type. | ||||
| #remotepasseval = getcredentials("filename", "hostname", "passwd") | ||||
|  | ||||
|  | ||||
| @@ -742,9 +749,9 @@ remotehost = examplehost | ||||
|  | ||||
| # This option stands in the [Repository RemoteExample] section. | ||||
| # | ||||
| # Specify the remote user name. | ||||
| # Specify the remote user name. Must be unicode. | ||||
| # | ||||
| remoteuser = username | ||||
| remoteuser = u"username" | ||||
|  | ||||
|  | ||||
| # This option stands in the [Repository RemoteExample] section. | ||||
| @@ -760,7 +767,9 @@ remoteuser = username | ||||
| # mechanism, so consider using auth_mechanisms to prioritize PLAIN | ||||
| # or even make it the only mechanism to be tried. | ||||
| # | ||||
| #remote_identity = authzuser | ||||
| # Must be unicode type. | ||||
| # | ||||
| #remote_identity = u"authzuser" | ||||
|  | ||||
|  | ||||
| # This option stands in the [Repository RemoteExample] section. | ||||
| @@ -842,11 +851,11 @@ remoteuser = username | ||||
| # | ||||
| # 2. The remote password stored in this file with the remotepass | ||||
| #    option. Any '%' needs to be encoded as '%%'. Example: | ||||
| #    remotepass = mypassword | ||||
| #remotepass = u"mypassword" | ||||
| # | ||||
| # 3. The remote password stored as a single line in an external | ||||
| #    file, which is referenced by the remotefile option.  Example: | ||||
| #    remotepassfile = ~/Password.IMAP.Account1 | ||||
| #remotepassfile = ~/Password.IMAP.Account1 | ||||
| # | ||||
| # 4. With a preauth tunnel.  With this method, you invoke an external | ||||
| #    program that is guaranteed *NOT* to ask for a password, but rather | ||||
| @@ -855,7 +864,7 @@ remoteuser = username | ||||
| #    NOT specify a user or password (if you do, they'll be ignored.) | ||||
| #    Instead, you specify a preauthtunnel, as this example illustrates | ||||
| #    for Courier IMAP on Debian: | ||||
| #    preauthtunnel = ssh -q imaphost '/usr/bin/imapd ./Maildir' | ||||
| #preauthtunnel = ssh -q imaphost '/usr/bin/imapd ./Maildir' | ||||
| # | ||||
| # 5. If you are using Kerberos and have the Python Kerberos package | ||||
| #    installed, you should not specify a remotepass.  If the user has a | ||||
| @@ -865,9 +874,9 @@ remoteuser = username | ||||
| # 6. Using arbitrary python code.  With this method, you invoke a | ||||
| #    function from your pythonfile.  To use this method assign the name | ||||
| #    of the function to the variable 'remotepasseval'.  Example: | ||||
| #    remotepasseval = get_password("imap.example.net") | ||||
| #remotepasseval = get_password("imap.example.net") | ||||
| #    You can also query for the username: | ||||
| #    remoteusereval = get_username("imap.example.net") | ||||
| #remoteusereval = get_username("imap.example.net") | ||||
| #    This method can be used to design more elaborate setups, e.g. by | ||||
| #    querying the gnome-keyring via its python bindings. | ||||
|  | ||||
| @@ -1186,7 +1195,9 @@ type = Gmail | ||||
| # | ||||
| # Specify the Gmail user name. This is the only mandatory parameter. | ||||
| # | ||||
| remoteuser = username@gmail.com | ||||
| # Must be unicode type. | ||||
| # | ||||
| remoteuser = u"username@gmail.com" | ||||
|  | ||||
|  | ||||
| # This option stands in the [Repository GmailExample] section. | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -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()) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Nicolas Sebrecht
					Nicolas Sebrecht