more style consistency

Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Nicolas Sebrecht
2015-01-08 17:13:33 +01:00
parent 594a286888
commit 0f40ca4799
14 changed files with 261 additions and 237 deletions

View File

@ -56,7 +56,7 @@ class IMAPServer:
self.preauth_tunnel = repos.getpreauthtunnel()
self.transport_tunnel = repos.gettransporttunnel()
if self.preauth_tunnel and self.transport_tunnel:
raise OfflineImapError('%s: ' % repos + \
raise OfflineImapError('%s: '% repos + \
'you must enable precisely one '
'type of tunnel (preauth or transport), '
'not both', OfflineImapError.ERROR.REPO)
@ -116,8 +116,9 @@ class IMAPServer:
# XXX: is this function used anywhere?
def getroot(self):
"""Returns this server's folder root. Can only be called after one
"""Returns this server's folder root. Can only be called after one
or more calls to acquireconnection."""
return self.root
@ -126,6 +127,7 @@ class IMAPServer:
:param drop_conn: If True, the connection will be released and
not be reused. This can be used to indicate broken connections."""
if connection is None: return #noop on bad connection
self.connectionlock.acquire()
self.assignedconnections.remove(connection)
@ -139,25 +141,24 @@ class IMAPServer:
def __md5handler(self, response):
challenge = response.strip()
self.ui.debug('imap', '__md5handler: got challenge %s' % challenge)
self.ui.debug('imap', '__md5handler: got challenge %s'% challenge)
passwd = self.__getpassword()
retval = self.username + ' ' + hmac.new(passwd, challenge).hexdigest()
self.ui.debug('imap', '__md5handler: returning %s' % retval)
self.ui.debug('imap', '__md5handler: returning %s'% retval)
return retval
def __loginauth(self, imapobj):
""" Basic authentication via LOGIN command """
""" Basic authentication via LOGIN command."""
self.ui.debug('imap', 'Attempting IMAP LOGIN authentication')
imapobj.login(self.username, self.__getpassword())
def __plainhandler(self, response):
"""
Implements SASL PLAIN authentication, RFC 4616,
http://tools.ietf.org/html/rfc4616
"""Implements SASL PLAIN authentication, RFC 4616,
http://tools.ietf.org/html/rfc4616"""
"""
authc = self.username
passwd = self.__getpassword()
authz = ''
@ -175,8 +176,8 @@ class IMAPServer:
try:
if self.gss_step == self.GSS_STATE_STEP:
if not self.gss_vc:
rc, self.gss_vc = kerberos.authGSSClientInit('imap@' +
self.hostname)
rc, self.gss_vc = kerberos.authGSSClientInit(
'imap@' + self.hostname)
response = kerberos.authGSSClientResponse(self.gss_vc)
rc = kerberos.authGSSClientStep(self.gss_vc, data)
if rc != kerberos.AUTH_GSS_CONTINUE:
@ -184,13 +185,13 @@ class IMAPServer:
elif self.gss_step == self.GSS_STATE_WRAP:
rc = kerberos.authGSSClientUnwrap(self.gss_vc, data)
response = kerberos.authGSSClientResponse(self.gss_vc)
rc = kerberos.authGSSClientWrap(self.gss_vc, response,
self.username)
rc = kerberos.authGSSClientWrap(
self.gss_vc, response, self.username)
response = kerberos.authGSSClientResponse(self.gss_vc)
except kerberos.GSSError as err:
# Kerberos errored out on us, respond with None to cancel the
# authentication
self.ui.debug('imap', '%s: %s' % (err[0][0], err[1][0]))
self.ui.debug('imap', '%s: %s'% (err[0][0], err[1][0]))
return None
if not response:
@ -205,7 +206,7 @@ class IMAPServer:
imapobj.starttls()
except imapobj.error as e:
raise OfflineImapError("Failed to start "
"TLS connection: %s" % str(e),
"TLS connection: %s"% str(e),
OfflineImapError.ERROR.REPO)
@ -266,8 +267,7 @@ class IMAPServer:
def __authn_helper(self, imapobj):
"""
Authentication machinery for self.acquireconnection().
"""Authentication machinery for self.acquireconnection().
Raises OfflineImapError() of type ERROR.REPO when
there are either fatal problems or no authentications
@ -275,9 +275,7 @@ class IMAPServer:
If any authentication method succeeds, routine should exit:
warnings for failed methods are to be produced in the
respective except blocks.
"""
respective except blocks."""
# Authentication routines, hash keyed by method name
# with value that is a tuple with
@ -321,13 +319,13 @@ class IMAPServer:
continue
tried_to_authn = True
self.ui.debug('imap', 'Attempting '
'%s authentication' % m)
self.ui.debug('imap', u'Attempting '
'%s authentication'% m)
try:
if func(imapobj):
return
except (imapobj.error, OfflineImapError) as e:
self.ui.warn('%s authentication failed: %s' % (m, e))
self.ui.warn('%s authentication failed: %s'% (m, e))
exc_stack.append((m, e))
if len(exc_stack):
@ -343,9 +341,9 @@ class IMAPServer:
lambda x: x[5:], filter(lambda x: x[0:5] == "AUTH=",
imapobj.capabilities)
))
raise OfflineImapError("Repository %s: no supported "
raise OfflineImapError(u"Repository %s: no supported "
"authentication mechanisms found; configured %s, "
"server advertises %s" % (self.repos,
"server advertises %s"% (self.repos,
", ".join(self.authmechs), methods),
OfflineImapError.ERROR.REPO)
@ -383,9 +381,8 @@ class IMAPServer:
self.connectionlock.release() # Release until need to modify data
""" Must be careful here that if we fail we should bail out gracefully
and release locks / threads so that the next attempt can try...
"""
# Must be careful here that if we fail we should bail out gracefully
# and release locks / threads so that the next attempt can try...
success = 0
try:
while not success:
@ -441,7 +438,7 @@ class IMAPServer:
# No Folders were returned. This occurs, e.g. if the
# 'reference' prefix does not exist on the mail
# server. Raise exception.
err = "Server '%s' returned no folders in '%s'" % \
err = "Server '%s' returned no folders in '%s'"% \
(self.repos.getname(), self.reference)
self.ui.warn(err)
raise Exception(err)
@ -458,6 +455,7 @@ class IMAPServer:
"""If we are here then we did not succeed in getting a
connection - we should clean up and then re-raise the
error..."""
self.semaphore.release()
severity = OfflineImapError.ERROR.REPO
@ -489,7 +487,7 @@ class IMAPServer:
reason = "Connection to host '%s:%d' for repository '%s' was "\
"refused. Make sure you have the right host and port "\
"configured and that you are actually able to access the "\
"network." % (self.hostname, self.port, self.repos)
"network."% (self.hostname, self.port, self.repos)
raise OfflineImapError(reason, severity)
# Could not acquire connection to the remote;
# socket.error(last_error) raised
@ -503,13 +501,15 @@ class IMAPServer:
raise
def connectionwait(self):
"""Waits until there is a connection available. Note that between
the time that a connection becomes available and the time it is
requested, another thread may have grabbed it. This function is
mainly present as a way to avoid spawning thousands of threads
to copy messages, then have them all wait for 3 available connections.
It's OK if we have maxconnections + 1 or 2 threads, which is what
this will help us do."""
"""Waits until there is a connection available.
Note that between the time that a connection becomes available and the
time it is requested, another thread may have grabbed it. This function
is mainly present as a way to avoid spawning thousands of threads to
copy messages, then have them all wait for 3 available connections.
It's OK if we have maxconnections + 1 or 2 threads, which is what this
will help us do."""
self.semaphore.acquire()
self.semaphore.release()
@ -533,11 +533,13 @@ class IMAPServer:
self.gssapi = False
def keepalive(self, timeout, event):
"""Sends a NOOP to each connection recorded. It will wait a maximum
of timeout seconds between doing this, and will continue to do so
until the Event object as passed is true. This method is expected
to be invoked in a separate thread, which should be join()'d after
the event is set."""
"""Sends a NOOP to each connection recorded.
It will wait a maximum of timeout seconds between doing this, and will
continue to do so until the Event object as passed is true. This method
is expected to be invoked in a separate thread, which should be join()'d
after the event is set."""
self.ui.debug('imap', 'keepalive thread started')
while not event.isSet():
self.connectionlock.acquire()
@ -547,7 +549,7 @@ class IMAPServer:
threads = []
for i in range(numconnections):
self.ui.debug('imap', 'keepalive: processing connection %d of %d' % (i, numconnections))
self.ui.debug('imap', 'keepalive: processing connection %d of %d'% (i, numconnections))
if len(self.idlefolders) > i:
# IDLE thread
idler = IdleThread(self, self.idlefolders[i])
@ -570,14 +572,14 @@ class IMAPServer:
return
def __verifycert(self, cert, hostname):
'''Verify that cert (in socket.getpeercert() format) matches hostname.
CRLs are not handled.
"""Verify that cert (in socket.getpeercert() format) matches hostname.
CRLs are not handled.
Returns error message if any problems are found and None on success."""
Returns error message if any problems are found and None on success.
'''
errstr = "CA Cert verifying failed: "
if not cert:
return ('%s no certificate received' % errstr)
return ('%s no certificate received'% errstr)
dnsname = hostname.lower()
certnames = []
@ -585,7 +587,7 @@ class IMAPServer:
notafter = cert.get('notAfter')
if notafter:
if time.time() >= cert_time_to_seconds(notafter):
return '%s certificate expired %s' % (errstr, notafter)
return '%s certificate expired %s'% (errstr, notafter)
# First read commonName
for s in cert.get('subject', []):
@ -593,7 +595,7 @@ class IMAPServer:
if key == 'commonName':
certnames.append(value.lower())
if len(certnames) == 0:
return ('%s no commonName found in certificate' % errstr)
return ('%s no commonName found in certificate'% errstr)
# Then read subjectAltName
for key, value in cert.get('subjectAltName', []):
@ -606,7 +608,7 @@ class IMAPServer:
'.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]):
return None
return ('%s no matching domain name found in certificate' % errstr)
return ('%s no matching domain name found in certificate'% errstr)
class IdleThread(object):
@ -614,6 +616,7 @@ class IdleThread(object):
"""If invoked without 'folder', perform a NOOP and wait for
self.stop() to be called. If invoked with folder, switch to IDLE
mode and synchronize once we have a new message"""
self.parent = parent
self.folder = folder
self.stop_sig = Event()
@ -634,18 +637,18 @@ class IdleThread(object):
self.thread.join()
def noop(self):
#TODO: AFAIK this is not optimal, we will send a NOOP on one
#random connection (ie not enough to keep all connections
#open). In case we do the noop multiple times, we can well use
#the same connection every time, as we get a random one. This
#function should IMHO send a noop on ALL available connections
#to the server.
# TODO: AFAIK this is not optimal, we will send a NOOP on one
# random connection (ie not enough to keep all connections
# open). In case we do the noop multiple times, we can well use
# the same connection every time, as we get a random one. This
# function should IMHO send a noop on ALL available connections
# to the server.
imapobj = self.parent.acquireconnection()
try:
imapobj.noop()
except imapobj.abort:
self.ui.warn('Attempting NOOP on dropped connection %s' % \
imapobj.identifier)
self.ui.warn('Attempting NOOP on dropped connection %s'%
imapobj.identifier)
self.parent.releaseconnection(imapobj, True)
imapobj = None
finally: