Bug#603450: Fwd: Due offlineimap absence of certificate validation issue -- Debian BTS#603450

2010-12-08 Thread Alexander Reichle-Schmehl
Hi!

Am 08.12.2010 09:33, schrieb dave b:

>> I verified it, and your patch works:  I accepts valid ssl connections,
>> and rejects invalid ones.

At this point I should have also said "many thanks for your work!"
Sorry, didn't had a coffee when I wrote my first mail ;)

>>> +self.sslobj = ssl_wrap(self.sock, self.keyfile, self.certfile, 
>>> cert_reqs=ssl.CERT_REQUIRED, ca_certs="/etc/ssl/certs/ca-certificates.crt")
>>
>> But that looks kind of ugly, having a hardcoded path... Also, I wonder
>> if not self.certfile should be used for verification?
> Sorry?
> Um. Well sure a hard coded path path not be the best thing ... if you
> know how to determine the path to the ca store on a system modify the
> patch to use that I guess.

Sorry, that was complete nonsense.  For a moment I thought one could use
the certfile parameter to specify a file holding certs for verification.


I take my question back.  Sorry for the noise.


Best regards,
  Alexander



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Bug#603450: Fwd: Due offlineimap absence of certificate validation issue -- Debian BTS#603450

2010-12-08 Thread dave b
On 8 December 2010 18:39, Alexander Reichle-Schmehl  wrote:
> Hi dave!
>
> * dave b  [101202 05:58]:
>
>> Here have a patch!
>> This obviously will break connecting to hosts which use a self-signed
>> certificate.
>> Perhaps some one else can fix this when they want it fixed ;) ?
>> I tested using the following config:
>
> I verified it, and your patch works:  I accepts valid ssl connections,
> and rejects invalid ones.
>
>> +        self.sslobj = ssl_wrap(self.sock, self.keyfile, self.certfile, 
>> cert_reqs=ssl.CERT_REQUIRED, ca_certs="/etc/ssl/certs/ca-certificates.crt")
>
> But that looks kind of ugly, having a hardcoded path... Also, I wonder
> if not self.certfile should be used for verification?

Sorry?
Um. Well sure a hard coded path path not be the best thing ... if you
know how to determine the path to the ca store on a system modify the
patch to use that I guess.



--
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Bug#603450: Fwd: Due offlineimap absence of certificate validation issue -- Debian BTS#603450

2010-12-07 Thread Alexander Reichle-Schmehl
Hi dave!

* dave b  [101202 05:58]:

> Here have a patch!
> This obviously will break connecting to hosts which use a self-signed
> certificate.
> Perhaps some one else can fix this when they want it fixed ;) ?
> I tested using the following config:

I verified it, and your patch works:  I accepts valid ssl connections,
and rejects invalid ones.

> +self.sslobj = ssl_wrap(self.sock, self.keyfile, self.certfile, 
> cert_reqs=ssl.CERT_REQUIRED, ca_certs="/etc/ssl/certs/ca-certificates.crt")

But that looks kind of ugly, having a hardcoded path... Also, I wonder
if not self.certfile should be used for verification?

Best Regards,
  Alexander



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Bug#603450: Fwd: Due offlineimap absence of certificate validation issue -- Debian BTS#603450

2010-12-01 Thread dave b
-- Forwarded message --
From: dave b 
Date: 1 December 2010 13:59
Subject: Re: Due offlineimap absence of certificate validation issue
-- Debian BTS#603450
To: John Goerzen 
Cc: Jan Lieskovsky , Christoph Höger



Here have a patch!
This obviously will break connecting to hosts which use a self-signed
certificate.
Perhaps some one else can fix this when they want it fixed ;) ?
I tested using the following config:

# Sample minimal config file.  Copy this to ~/.offlineimaprc and edit to
# suit to get started fast.

[general]
accounts = Test

[Account Test]
localrepository = Local
remoterepository = Remote

[Repository Local]
type = Maildir
localfolders = ~/Test

[Repository Remote]
type = IMAP
ssl = yes
remotehost = imap.gmail.com # this should work
#remotehost = 74.125.39.109 # this should fail
#remotehost = $putselfsignedserveraddresshere #this should fail
remoteuser = jgoerzen

For these hosts (listed here) the expected outcome matched the actual
outcome when I tried offlineimap.
diff --git a/offlineimap/imaplibutil.py b/offlineimap/imaplibutil.py
index a60242b..3df92c2 100644
--- a/offlineimap/imaplibutil.py
+++ b/offlineimap/imaplibutil.py
@@ -27,6 +27,7 @@ try:
 import ssl
 ssl_wrap = ssl.wrap_socket
 except ImportError:
+print e
 ssl_wrap = socket.ssl
 
 class IMAP4_Tunnel(IMAP4):
@@ -62,7 +63,7 @@ class IMAP4_Tunnel(IMAP4):
 self.infd.close()
 self.outfd.close()
 self.process.wait()
-
+
 class sslwrapper:
 def __init__(self, sslsock):
 self.sslsock = sslsock
@@ -144,6 +145,27 @@ def new_open(self, host = '', port = IMAP4_PORT):
 raise socket.error(last_error)
 self.file = self.sock.makefile('rb')
 
+
+def _verifycert(cert, hostname):
+'''Verify that cert (in socket.getpeercert() format) matches hostname.
+CRLs and subjectAltName are not handled.
+
+Returns error message if any problems are found and None on success.
+'''
+if not cert:
+return ('no certificate received')
+dnsname = hostname.lower()
+for s in cert.get('subject', []):
+key, value = s[0]
+if key == 'commonName':
+certname = value.lower()
+if (certname == dnsname or
+'.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]):
+return None
+return ('certificate is for %s') % certname
+return ('no commonName found in certificate')
+
+
 def new_open_ssl(self, host = '', port = IMAP4_SSL_PORT):
 """Setup connection to remote server on "host:port".
 (default: localhost:standard IMAP4 SSL port).
@@ -171,7 +193,10 @@ def new_open_ssl(self, host = '', port = IMAP4_SSL_PORT):
 if last_error != 0:
 # FIXME
 raise socket.error(last_error)
-self.sslobj = ssl_wrap(self.sock, self.keyfile, self.certfile)
+self.sslobj = ssl_wrap(self.sock, self.keyfile, self.certfile, cert_reqs=ssl.CERT_REQUIRED, ca_certs="/etc/ssl/certs/ca-certificates.crt")
+msg = _verifycert(self.sslobj.getpeercert(), host)
+if msg:
+raise socket.error(('%s certificate error: %s') % (host, msg) )
 self.sslobj = sslwrapper(self.sslobj)
 
 mustquote = re.compile(r"[^\w!#$%&'+,.:;<=>?^`|~-]")
diff --git a/offlineimap/imapserver.py b/offlineimap/imapserver.py
index 74f1a27..a4925b1 100644
--- a/offlineimap/imapserver.py
+++ b/offlineimap/imapserver.py
@@ -85,7 +85,7 @@ class UsefulIMAP4_SSL(UsefulIMAPMixIn, imaplibutil.WrappedIMAP4_SSL):
 imaplibutil.new_open_ssl(self, host, port)
 
 # This is the same hack as above, to be used in the case of an SSL
-# connexion.
+# connection.
 
 def read(self, size):
 if (system() == 'Darwin') and (size>0) :
@@ -191,7 +191,7 @@ class IMAPServer:
 try:
 if self.gss_step == self.GSS_STATE_STEP:
 if not self.gss_vc:
-rc, self.gss_vc = kerberos.authGSSClientInit('imap@' + 
+rc, self.gss_vc = kerberos.authGSSClientInit('imap@' +
  self.hostname)
 response = kerberos.authGSSClientResponse(self.gss_vc)
 rc = kerberos.authGSSClientStep(self.gss_vc, data)
@@ -243,7 +243,7 @@ class IMAPServer:
 self.lastowner[imapobj] = thread.get_ident()
 self.connectionlock.release()
 return imapobj
-
+
 self.connectionlock.release()   # Release until need to modify data
 
 """ Must be careful here that if we fail we should bail out gracefully
@@ -328,7 +328,7 @@ class IMAPServer:
 if(self.connectionlock.locked()):
 self.connectionlock.release()
 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
@@ -378,7 +378