Fix stale gss api authentication security context

Inside __authn_gssapi function, the else clause is never executed
because the return statement in the try section, which means if there is
an error and a reconnect is tried, the authentication will now fail with
due the stale self.gss_vc value. For example, offlineimap will be
stuck after any socket error and unable to reconnect, even if I have a
valid kerberos ticket:

========================================================================
abort: command: FETCH => socket error: <type 'exceptions.IOError'> - Too many read 0

  command: FETCH => socket error: <type 'exceptions.IOError'> - Too many read 0
 GSSAPI authentication failed: AUTHENTICATE command error: BAD ['AUTHENTICATE aborted']. Data: BLMC2 AUTHENTICATE GSSAPI

Enter password for user 'XXX':
========================================================================

You can verify this try..finally behaviour with this slightly modified
example that I copied from python documentation:

>>> def divide(x, y):
...     try:
...         result = x / y
...         return 1
...     except ZeroDivisionError:
...         print("division by zero!")
...     else:
...         print("result is", result)
...     finally:
...         print("executing finally clause")
...
>>> divide(2, 1)
executing finally clause
1
>>>

The else section is never executed with a return inside try.

To fix the issue here, instead of relying on else clause, just clear
gss_vc always inside finally, and we don't need to handle any exception
to set self.gssapi, it can be left False by default and just set to True
after authentication is done.

I'm running with this fix and now offlineimap doesn't stop requiring manual
intervention, and succesfully re-authenticate after errors while fetching
data.

Signed-off-by: Herton R. Krzesinski <herton@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Herton R. Krzesinski 2020-04-09 18:07:34 -03:00 committed by Nicolas Sebrecht
parent da69fd81ed
commit 6a25f1930c
1 changed files with 3 additions and 6 deletions

View File

@ -356,16 +356,13 @@ class IMAPServer(object):
return False
self.connectionlock.acquire()
self.gssapi = False
try:
imapobj.authenticate('GSSAPI', self.__gsshandler)
return True
except imapobj.error as e:
self.gssapi = False
raise
else:
self.gssapi = True
self.gss_vc = None
return True
finally:
self.gss_vc = None
self.connectionlock.release()
def __authn_cram_md5(self, imapobj):