Re: Sitecopy and certificate management

Joe Orton <[email protected]> Wed, 12 Apr 2006 21:33:09 +0100
Newsgroups gmane.comp.web.sitecopy
Message-ID <[email protected]>
On Wed, Apr 12, 2006 at 04:22:42PM +0200, Jesus Climent wrote:
> Hi.
> 
> While trying to sync some data over a https tunnel, I get the following:
> 
> $ sitecopy -u sitecopy
> sitecopy: Updating site `sitecopy' (on sitecopy.service.org in /repository/)
> sitecopy: Error: Server certificate verification failed: certificate issued for a different hostname, issuer is not trusted
> 
> The certificate is accepted in the first attempt, but the following ones it
> refuses to update the site.

Yeah, the SSL cert verification is a bit simplistic in sitecopy at the 
moment.  Try this patch:

Index: src/davdriver.c
===================================================================
--- src/davdriver.c	(revision 1019)
+++ src/davdriver.c	(working copy)
@@ -180,30 +180,34 @@
     }
 }
 
-/* Verify callback for when a trusted cert is not known. */
-static int verify_untrusted(void *userdata, int failures,
-                            const ne_ssl_certificate *cert)
+/* Callback invoked when SSL server cert verification fails. */
+static int verify_certificate(void *userdata, int failures,
+                              const ne_ssl_certificate *cert)
 {
     struct site *site = userdata;
 
-    if (fe_accept_cert(cert, failures))
+    /* If the server cert has not changed since the user accepted it,
+     * trust the cert, unless it has expired, in which case the user
+     * should get a warning. */
+    if (site->server_cert 
+        && ne_ssl_cert_cmp(cert, site->server_cert) == 0
+        && (failures & NE_SSL_EXPIRED) == 0) {
+        return 0;
+    }
+
+    if (fe_accept_cert(cert, failures)) {
+        /* Not accepted by user => fail verification. */
         return -1;
-    
-    /* TODO: how to handle a write error here? */
-    ne_ssl_cert_write(cert, site->certfile);
+    }
 
+    if (ne_ssl_cert_write(cert, site->certfile)) {
+        fe_warning(_("Could not write SSL certificate"),
+                   NULL, site->certfile);
+    }
+
     return 0;
 }
 
-/* Verify callback for when a trusted cert is known. */
-static int verify_trusted(void *userdata, int failures,
-                          const ne_ssl_certificate *cert)
-{
-    ne_ssl_certificate *expected = userdata;
-
-    return failures != NE_SSL_UNTRUSTED || ne_ssl_cert_cmp(expected, cert);
-}
-
 static int init(void **session, struct site *site)
 {
     ne_session *sess;
@@ -223,16 +227,14 @@
 
     if (site->http_secure) {
         if (access(site->certfile, R_OK) == 0) {
-            ne_ssl_certificate *cert = ne_ssl_cert_read(site->certfile);
-            if (cert == NULL) {
+            site->server_cert = ne_ssl_cert_read(site->certfile);
+            if (site->server_cert == NULL) {
                 ne_set_error(sess, _("Could not load certificate `%s'."),
                              site->certfile);
                 return SITE_FAILED;
             }
-            ne_ssl_set_verify(sess, verify_trusted, cert);
-        } else {
-            ne_ssl_set_verify(sess, verify_untrusted, site);
         }
+        ne_ssl_set_verify(sess, verify_certificate, site);
     }
 
     ne_set_status(sess, notify_cb, NULL);
_______________________________________________
sitecopy maillist  -  [email protected]
http://dav.lyra.org/mailman/listinfo/sitecopy