[Fwd: Re: (Patch) Add support for LibCST to tinymail camel]



-- 
Philip Van Hoof, freelance software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
http://pvanhoof.be/blog
http://codeminded.be



--- Begin Message ---
El mié, 09-04-2008 a las 16:20 +0200, Philip Van Hoof escribió:
> o. gtk-doc.m4 diff is included in the patch (I don't see why these
>    changes are necessary)
> o. Same for camel-mime-part-utils.c

	Bad patch review from my side, sorry.

> o. The changes in camel-tcp-stream-ssl.c are not ifdeffed under HAVE_CST

	It's intended this way. The code should work with and without cst.

> o. This lock:

	Oops!!!!, fixed now.

	Attached a new review of the patch.
Index: libtinymail-camel/camel-lite/camel/camel-certdb-cst.c
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-certdb-cst.c	(revision 0)
+++ libtinymail-camel/camel-lite/camel/camel-certdb-cst.c	(revision 0)
@@ -0,0 +1,724 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  Authors: Jose Dapena Paz <jdapena igalia com>
+ *
+ *  Copyright 2008 Jose Dapena Paz
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include <libedataserver/e-memory.h>
+
+#include "camel-certdb.h"
+#include "camel-file-utils.h"
+#include "camel-private.h"
+
+#define CAMEL_CERTDB_GET_CLASS(db)  ((CamelCertDBClass *) CAMEL_OBJECT_GET_CLASS (db))
+
+#define CAMEL_CERTDB_VERSION  0x100
+
+static void camel_certdb_class_init (CamelCertDBClass *klass);
+static void camel_certdb_init       (CamelCertDB *certdb);
+static void camel_certdb_finalize   (CamelObject *obj);
+
+static int certdb_header_load (CamelCertDB *certdb, FILE *istream);
+static int certdb_header_save (CamelCertDB *certdb, FILE *ostream);
+static CamelCert *certdb_cert_load (CamelCertDB *certdb, FILE *istream);
+static int certdb_cert_save (CamelCertDB *certdb, CamelCert *cert, FILE *ostream);
+static CamelCert *certdb_cert_new (CamelCertDB *certdb);
+static void certdb_cert_free (CamelCertDB *certdb, CamelCert *cert);
+
+static const char *cert_get_string (CamelCertDB *certdb, CamelCert *cert, int string);
+static void cert_set_string (CamelCertDB *certdb, CamelCert *cert, int string, const char *value);
+
+static char *cert_dehexify (const char *hex_fingerprint);
+static char *cert_hexify (gchar * finger);
+static char *x509_dn_to_str (X509_NAME *xname);
+
+static CamelCertTrust cert_eval_one_trust (CamelCertDB *certdb, cst_t_seqnum certID);
+static CamelCertTrust cert_eval_trust (CamelCertDB *certdb, cst_t_seqnum certID);
+
+
+static CamelObjectClass *parent_class = NULL;
+
+
+CamelType
+camel_certdb_get_type (void)
+{
+	static CamelType type = CAMEL_INVALID_TYPE;
+
+	if (type == CAMEL_INVALID_TYPE) {
+		type = camel_type_register (camel_object_get_type (),
+					    "CamelCertDB",
+					    sizeof (CamelCertDB),
+					    sizeof (CamelCertDBClass),
+					    (CamelObjectClassInitFunc) camel_certdb_class_init,
+					    NULL,
+					    (CamelObjectInitFunc) camel_certdb_init,
+					    (CamelObjectFinalizeFunc) camel_certdb_finalize);
+	}
+
+	return type;
+}
+
+
+static void
+camel_certdb_class_init (CamelCertDBClass *klass)
+{
+	parent_class = camel_type_get_global_classfuncs (camel_object_get_type ());
+
+	klass->header_load = certdb_header_load;
+	klass->header_save = certdb_header_save;
+
+	klass->cert_new  = certdb_cert_new;
+	klass->cert_load = certdb_cert_load;
+	klass->cert_save = certdb_cert_save;
+	klass->cert_free = certdb_cert_free;
+	klass->cert_get_string = cert_get_string;
+	klass->cert_set_string = cert_set_string;
+}
+
+static void
+camel_certdb_init (CamelCertDB *certdb)
+{
+	certdb->priv = g_malloc0 (sizeof (struct _CamelCertDBPrivate));
+
+	certdb->filename = NULL;
+	certdb->version = CAMEL_CERTDB_VERSION;
+	certdb->saved_certs = 0;
+
+	certdb->cert_size = sizeof (CamelCert);
+
+	certdb->cert_chunks = NULL;
+
+	certdb->certs = NULL;
+	certdb->cert_hash = NULL;
+
+	certdb->priv->db_lock = g_mutex_new ();
+	certdb->priv->io_lock = g_mutex_new ();
+	certdb->priv->alloc_lock = g_mutex_new ();
+	certdb->priv->ref_lock = g_mutex_new ();
+
+	certdb->priv->cst = CST_open (FALSE, NULL);
+}
+
+static void
+camel_certdb_finalize (CamelObject *obj)
+{
+	CamelCertDB *certdb = (CamelCertDB *) obj;
+	struct _CamelCertDBPrivate *p;
+
+	p = certdb->priv;
+
+	g_free (certdb->filename);
+
+	g_mutex_lock (certdb->priv->db_lock);
+	CST_save (p->cst);
+	CST_free (p->cst);
+	g_mutex_unlock (certdb->priv->db_lock);
+
+	g_mutex_free (p->db_lock);
+	g_mutex_free (p->io_lock);
+	g_mutex_free (p->alloc_lock);
+	g_mutex_free (p->ref_lock);
+
+	g_free (p);
+}
+
+/* We want to keep compatibility with the certificate format of camel, so we need
+ * to convert the CST format (all the fingerprint uppercase without quotes) to the
+ * one here */
+
+static char *
+cert_dehexify (const char *hex_fingerprint)
+{
+	GString *result = g_string_new ("");
+
+	while (*hex_fingerprint) {
+		if (*hex_fingerprint != ':') {
+			result = g_string_append_c (result, g_ascii_toupper (*hex_fingerprint));
+		}
+			
+		hex_fingerprint ++;
+	}
+
+	return g_string_free (result, FALSE);
+}
+
+static char *
+cert_hexify (gchar * finger)
+{
+	GString *result = g_string_new ("");
+	gboolean add_colon = FALSE;
+
+	while (*finger) {
+		result = g_string_append_c (result, g_ascii_tolower (*finger));
+		if (add_colon && (*(finger +1)))
+			result = g_string_append_c (result, ':');
+		add_colon = !add_colon;
+			
+		finger ++;
+	}
+
+	return g_string_free (result, FALSE);
+}
+
+/* This provides a readable string for the issuer and subject fields */
+static char *
+x509_dn_to_str (X509_NAME *xname)
+{
+	gchar *result = NULL;
+	int ou_idx;
+	BIO *bio;
+	char buffer[128];
+
+	/* FLAGS WE USE:
+	 * XN_FLAG_FN_NONE (no field names)
+	 * XN_FLAG_DN_REV (reverse order)
+	 * XN_FLAG_SEP_CPLUS_SPC (comma and space sparated fields)
+	 * ASN1_STRFLGS_RFC2253 (should help with utf8)
+	 */
+
+	bio = BIO_new (BIO_s_mem ());
+	if (bio == NULL)
+		return NULL;
+
+	X509_NAME_print_ex (bio, xname, 0, 
+			    ASN1_STRFLGS_RFC2253 | XN_FLAG_DN_REV | 
+			    XN_FLAG_FN_NONE | XN_FLAG_SEP_CPLUS_SPC);
+	BIO_gets (bio, buffer, 128);
+	result = g_strdup (buffer);
+	BIO_free_all (bio);
+
+	return result;
+}
+
+/* very basic trust model implementation to fit with expected CST behavior.
+ * This will add anyway certificates to manager, even valid ones. This checks if we
+ * have any of the trust purposes we allow (ssl client, server and wlan), in the chain.
+ *
+ * NOTE: the certificate manager "email trust" is intended for SMIME, so we're using the
+ * WLAN, but mainly we set the SSL CLIENT purpose.
+ */
+static CamelCertTrust
+cert_eval_one_trust (CamelCertDB *certdb, cst_t_seqnum certID)
+{
+	int state;
+	int purpose_valid;
+	CamelCertTrust result;
+	X509 *x509_cert;
+
+	purpose_valid = (CST_is_purpose (certdb->priv->cst, certID, CST_PURPOSE_SSL_CLIENT)||
+			 CST_is_purpose (certdb->priv->cst, certID, CST_PURPOSE_SSL_SERVER)||
+			 CST_is_purpose (certdb->priv->cst, certID, CST_PURPOSE_SSL_WLAN));
+	x509_cert = CST_get_cert (certdb->priv->cst, certID);
+	state = CST_get_state (certdb->priv->cst, x509_cert);
+	X509_free (x509_cert);
+
+	if (state == CST_STATE_VALID && purpose_valid) {
+		result = CAMEL_CERT_TRUST_FULLY;
+	} else if (state == CST_STATE_VALID) {
+		result = CAMEL_CERT_TRUST_UNKNOWN;
+	} else {
+		result = CAMEL_CERT_TRUST_NEVER;
+	}
+
+	return result;
+}
+
+static CamelCertTrust
+cert_eval_trust (CamelCertDB *certdb, cst_t_seqnum certID)
+{
+	GSList *chain, *node;
+	CamelCertTrust result;
+
+	g_mutex_lock (certdb->priv->db_lock);
+	result = cert_eval_one_trust (certdb, certID);
+	if (result != CAMEL_CERT_TRUST_UNKNOWN) {
+		g_mutex_unlock (certdb->priv->db_lock);
+		return result;
+	}
+
+	chain = CST_get_chain_id_by_id (certdb->priv->cst, certID);
+	node = chain;
+	while (node) {
+		result = cert_eval_one_trust (certdb, GPOINTER_TO_UINT (node->data));
+		if (result != CAMEL_CERT_TRUST_UNKNOWN)
+			break;
+		node = g_slist_next (node);
+	}
+
+	g_slist_free (chain);
+
+	g_mutex_unlock (certdb->priv->db_lock);
+	return result;
+}
+
+static int 
+certdb_header_load (CamelCertDB *certdb, FILE *istream)
+{
+	return 0;
+}
+
+static int
+certdb_header_save (CamelCertDB *certdb, FILE *ostream)
+{
+	return 0;
+}
+
+static CamelCert *
+certdb_cert_load (CamelCertDB *certdb, FILE *istream)
+{
+	return NULL;
+}
+static int
+certdb_cert_save (CamelCertDB *certdb, CamelCert *cert, FILE *ostream)
+{
+	return 0;
+}
+
+static CamelCert *
+certdb_cert_new (CamelCertDB *certdb)
+{
+	/* this way we set a 0 to trust level (unknown) */
+	
+	return g_malloc0 (certdb->cert_size);
+}
+
+CamelCertDB *
+camel_certdb_new (void)
+{
+	return (CamelCertDB *) camel_object_new (camel_certdb_get_type ());
+}
+
+
+static CamelCertDB *default_certdb = NULL;
+static pthread_mutex_t default_certdb_lock = PTHREAD_MUTEX_INITIALIZER;
+
+void
+camel_certdb_set_default (CamelCertDB *certdb)
+{
+	pthread_mutex_lock (&default_certdb_lock);
+
+	if (default_certdb)
+		camel_object_unref (default_certdb);
+
+	if (certdb)
+		camel_object_ref (certdb);
+
+	default_certdb = certdb;
+
+	pthread_mutex_unlock (&default_certdb_lock);
+}
+
+
+CamelCertDB *
+camel_certdb_get_default (void)
+{
+	CamelCertDB *certdb;
+
+	pthread_mutex_lock (&default_certdb_lock);
+
+	if (default_certdb)
+		camel_object_ref (default_certdb);
+
+	certdb = default_certdb;
+
+	pthread_mutex_unlock (&default_certdb_lock);
+
+	return certdb;
+}
+
+
+void
+camel_certdb_set_filename (CamelCertDB *certdb, const char *filename)
+{
+	g_return_if_fail (CAMEL_IS_CERTDB (certdb));
+	g_return_if_fail (filename != NULL);
+
+	CAMEL_CERTDB_LOCK (certdb, db_lock);
+
+	g_free (certdb->filename);
+	certdb->filename = g_strdup (filename);
+
+	CAMEL_CERTDB_UNLOCK (certdb, db_lock);
+}
+
+
+int
+camel_certdb_load (CamelCertDB *certdb)
+{
+	return 0;
+}
+
+int
+camel_certdb_save (CamelCertDB *certdb)
+{
+	int result;
+	g_mutex_lock (certdb->priv->db_lock);
+	result = (CST_save (certdb->priv->cst) == CST_ERROR_OK);
+	g_mutex_unlock (certdb->priv->db_lock);
+
+	return result;
+	
+}
+
+void
+camel_certdb_touch (CamelCertDB *certdb)
+{
+}
+
+CamelCert *
+camel_certdb_get_cert (CamelCertDB *certdb, const char *fingerprint)
+{
+	CamelCert *cert = NULL;
+	GSList *cst_id_list;
+	X509 *x509_cert;
+	gchar *dehexify;
+	
+	g_return_val_if_fail (CAMEL_IS_CERTDB (certdb), NULL);
+	dehexify = cert_dehexify (fingerprint);
+
+	g_mutex_lock (certdb->priv->db_lock);
+	cst_id_list = CST_search_by_fingerprint (certdb->priv->cst, dehexify);
+	g_free (dehexify);
+
+	if (cst_id_list == NULL) {
+		g_mutex_unlock (certdb->priv->db_lock);
+		return NULL;
+	}
+
+	x509_cert = CST_get_cert (certdb->priv->cst, GPOINTER_TO_UINT (cst_id_list->data));
+	if (x509_cert) {
+		X509_NAME *x509_issuer;
+		X509_NAME *x509_subject;
+		gchar *issuer;
+		gchar *subject;
+		gchar *finger;
+		gchar *hex_finger;
+		unsigned char *der_data = NULL;
+		int der_len;
+			
+		cert = g_malloc0 (certdb->cert_size);
+
+		cert->certID = GPOINTER_TO_UINT (cst_id_list->data);
+
+		x509_issuer = CST_get_issued_by_dn (x509_cert);
+		issuer = x509_dn_to_str (x509_issuer);
+		camel_cert_set_issuer (certdb, cert, issuer);
+		g_free (issuer);
+
+		x509_subject = CST_get_subject_dn (x509_cert);
+		subject = x509_dn_to_str (x509_subject);
+		camel_cert_set_subject (certdb, cert, subject);
+		g_free (subject);
+
+		finger = CST_get_fingerprint (x509_cert);
+		hex_finger = cert_hexify (finger);
+		camel_cert_set_fingerprint (certdb, cert, hex_finger);
+		g_free (finger);
+		g_free (hex_finger);
+
+		der_len = i2d_X509 (x509_cert, &der_data);
+		cert->rawcert = g_byte_array_new ();
+		cert->rawcert = g_byte_array_append (cert->rawcert, der_data, der_len);
+		OPENSSL_free (der_data);
+		
+	}
+	g_mutex_unlock (certdb->priv->db_lock);
+
+	return cert;
+}
+
+void
+camel_certdb_add (CamelCertDB *certdb, CamelCert *cert)
+{
+	X509 *x509_cert;
+	const unsigned char *buffer_p;
+	GSList *old_list, *new_list, *p;
+        cst_t_seqnum certID = 0;
+
+	g_return_if_fail (CAMEL_IS_CERTDB (certdb));
+
+	buffer_p = (const unsigned char *) cert->rawcert->data;
+	x509_cert = d2i_X509 (NULL, &buffer_p, cert->rawcert->len);
+
+	if (x509_cert == NULL) {
+		return;
+	}
+
+	g_mutex_lock (certdb->priv->db_lock);
+
+	old_list = CST_search_by_purpose (certdb->priv->cst, CST_PURPOSE_NONE);
+
+	CST_append_X509 (certdb->priv->cst, x509_cert);
+
+	new_list = CST_search_by_purpose (certdb->priv->cst, CST_PURPOSE_NONE);
+
+	for (p = new_list; p != NULL; p = g_slist_next (p)) {
+		if (!g_slist_find (old_list, p->data)) {
+			certID = GPOINTER_TO_UINT (p->data);
+			break;
+		}
+	}
+	g_slist_free (old_list);
+	g_slist_free (new_list);
+
+	if (certID) {
+		X509_NAME *x509_issuer;
+		X509_NAME *x509_subject;
+		gchar *issuer;
+		gchar *subject;
+
+		CST_set_folder (certdb->priv->cst, certID, CST_FOLDER_PERSONAL);
+		cert->certID = certID;
+
+		x509_issuer = CST_get_issued_by_dn (x509_cert);
+		issuer = x509_dn_to_str (x509_issuer);
+		camel_cert_set_issuer (certdb, cert, issuer);
+		g_free (issuer);
+
+		x509_subject = CST_get_subject_dn (x509_cert);
+		subject = x509_dn_to_str (x509_subject);
+		camel_cert_set_subject (certdb, cert, subject);
+		g_free (subject);
+
+		/* we don't set any trust. This way it's "unknown" (not allowed if not set
+		   as trust explicitely, or no chain member is trusting */
+	}
+	X509_free (x509_cert);
+	g_mutex_unlock (certdb->priv->db_lock);
+}
+
+void
+camel_certdb_remove (CamelCertDB *certdb, CamelCert *cert)
+{
+	const gchar *fingerprint;
+	gchar *dehex_finger;
+	GSList *cst_id_list;
+
+	g_return_if_fail (CAMEL_IS_CERTDB (certdb));
+
+	fingerprint = camel_cert_get_fingerprint (certdb, cert);
+	if (fingerprint == NULL)
+		return;
+	
+	dehex_finger = cert_dehexify (fingerprint);
+	g_mutex_lock (certdb->priv->db_lock);
+	cst_id_list = CST_search_by_fingerprint (certdb->priv->cst, dehex_finger);
+	g_free (dehex_finger);
+
+	if (cst_id_list == NULL) {
+		g_mutex_unlock (certdb->priv->db_lock);
+		return;
+	}
+	
+	CST_delete_cert (certdb->priv->cst, GPOINTER_TO_UINT (cst_id_list->data));
+	g_slist_free (cst_id_list);
+	g_mutex_unlock (certdb->priv->db_lock);
+
+}
+
+
+CamelCert *
+camel_certdb_cert_new (CamelCertDB *certdb)
+{
+	CamelCert *cert;
+
+	g_return_val_if_fail (CAMEL_IS_CERTDB (certdb), NULL);
+
+	CAMEL_CERTDB_LOCK (certdb, alloc_lock);
+
+	cert = CAMEL_CERTDB_GET_CLASS (certdb)->cert_new (certdb);
+
+	CAMEL_CERTDB_UNLOCK (certdb, alloc_lock);
+
+	return cert;
+}
+
+void
+camel_certdb_cert_ref (CamelCertDB *certdb, CamelCert *cert)
+{
+	g_return_if_fail (CAMEL_IS_CERTDB (certdb));
+	g_return_if_fail (cert != NULL);
+
+	CAMEL_CERTDB_LOCK (certdb, ref_lock);
+	cert->refcount++;
+	CAMEL_CERTDB_UNLOCK (certdb, ref_lock);
+}
+
+static void
+certdb_cert_free (CamelCertDB *certdb, CamelCert *cert)
+{
+	g_free (cert->issuer);
+	g_free (cert->subject);
+	g_free (cert->hostname);
+	g_free (cert->fingerprint);
+	if (cert->rawcert)
+		g_byte_array_free(cert->rawcert, TRUE);
+}
+
+void
+camel_certdb_cert_unref (CamelCertDB *certdb, CamelCert *cert)
+{
+	g_return_if_fail (CAMEL_IS_CERTDB (certdb));
+	g_return_if_fail (cert != NULL);
+
+	CAMEL_CERTDB_LOCK (certdb, ref_lock);
+
+	if (cert->refcount <= 1) {
+		CAMEL_CERTDB_GET_CLASS (certdb)->cert_free (certdb, cert);
+		if (certdb->cert_chunks)
+			e_memchunk_free (certdb->cert_chunks, cert);
+		else
+			g_free (cert);
+	} else {
+		cert->refcount--;
+	}
+
+	CAMEL_CERTDB_UNLOCK (certdb, ref_lock);
+}
+
+
+void
+camel_certdb_clear (CamelCertDB *certdb)
+{
+}
+
+
+static const char *
+cert_get_string (CamelCertDB *certdb, CamelCert *cert, int string)
+{
+	switch (string) {
+	case CAMEL_CERT_STRING_ISSUER:
+		return cert->issuer;
+	case CAMEL_CERT_STRING_SUBJECT:
+		return cert->subject;
+	case CAMEL_CERT_STRING_HOSTNAME:
+		return cert->hostname;
+	case CAMEL_CERT_STRING_FINGERPRINT:
+		return cert->fingerprint;
+	default:
+		return NULL;
+	}
+}
+
+
+const char *
+camel_cert_get_string (CamelCertDB *certdb, CamelCert *cert, int string)
+{
+	g_return_val_if_fail (CAMEL_IS_CERTDB (certdb), NULL);
+	g_return_val_if_fail (cert != NULL, NULL);
+
+	/* FIXME: do locking? */
+
+	return CAMEL_CERTDB_GET_CLASS (certdb)->cert_get_string (certdb, cert, string);
+}
+
+static void
+cert_set_string (CamelCertDB *certdb, CamelCert *cert, int string, const char *value)
+{
+	switch (string) {
+	case CAMEL_CERT_STRING_ISSUER:
+		g_free (cert->issuer);
+		cert->issuer = g_strdup (value);
+		break;
+	case CAMEL_CERT_STRING_SUBJECT:
+		g_free (cert->subject);
+		cert->subject = g_strdup (value);
+		break;
+	case CAMEL_CERT_STRING_HOSTNAME:
+		g_free (cert->hostname);
+		cert->hostname = g_strdup (value);
+		break;
+	case CAMEL_CERT_STRING_FINGERPRINT:
+		g_free (cert->fingerprint);
+		cert->fingerprint = g_strdup (value);
+		break;
+	default:
+		break;
+	}
+}
+
+
+void
+camel_cert_set_string (CamelCertDB *certdb, CamelCert *cert, int string, const char *value)
+{
+	g_return_if_fail (CAMEL_IS_CERTDB (certdb));
+	g_return_if_fail (cert != NULL);
+
+	/* FIXME: do locking? */
+
+	CAMEL_CERTDB_GET_CLASS (certdb)->cert_set_string (certdb, cert, string, value);
+}
+
+
+CamelCertTrust
+camel_cert_get_trust (CamelCertDB *certdb, CamelCert *cert)
+{
+	g_return_val_if_fail (CAMEL_IS_CERTDB (certdb), CAMEL_CERT_TRUST_UNKNOWN);
+	g_return_val_if_fail (cert != NULL, CAMEL_CERT_TRUST_UNKNOWN);
+
+	if (cert->certID) {
+		return cert_eval_trust (certdb, cert->certID);
+	} else {
+		return cert->trust;
+	}
+}
+
+
+void
+camel_cert_set_trust (CamelCertDB *certdb, CamelCert *cert, CamelCertTrust trust)
+{
+
+	g_return_if_fail (CAMEL_IS_CERTDB (certdb));
+	g_return_if_fail (cert != NULL);
+
+	cert->trust = trust;
+	g_mutex_lock (certdb->priv->db_lock);
+	/* we only set the ssl client purpose. In UI this will set Browser trust, not Email trust */
+	if (cert->certID) {
+		switch (trust) {
+		case CAMEL_CERT_TRUST_FULLY:
+		case CAMEL_CERT_TRUST_ULTIMATE:
+			CST_set_purpose (certdb->priv->cst, cert->certID, CST_PURPOSE_SSL_CLIENT, TRUE);
+			break;
+		case CAMEL_CERT_TRUST_NEVER:
+			CST_set_purpose (certdb->priv->cst, cert->certID, CST_PURPOSE_SSL_CLIENT, FALSE);
+			break;
+		default:
+			break;
+		}
+	}
+	g_mutex_unlock (certdb->priv->db_lock);
+}
Index: libtinymail-camel/camel-lite/camel/Makefile.am
===================================================================
--- libtinymail-camel/camel-lite/camel/Makefile.am	(revision 3558)
+++ libtinymail-camel/camel-lite/camel/Makefile.am	(working copy)
@@ -146,7 +146,6 @@
 	camel-address.c				\
 	camel-arg.c				\
 	camel-block-file.c			\
-	camel-certdb.c				\
 	camel-charset-map.c			\
 	camel-data-cache.c			\
 	camel-data-wrapper.c			\
@@ -208,6 +207,13 @@
 	camel.c					\
 	$(LIBCAMEL_PLATFORM_DEP_SOURCES)
 
+if HAVE_CST
+libcamel_lite_1_2_la_SOURCES +=	camel-certdb-cst.c
+else
+libcamel_lite_1_2_la_SOURCES +=	camel-certdb.c
+endif
+
+
 libcamel_liteinclude_HEADERS =			\
 	$(providerinclude_headers)		\
 	broken-date-parser.h			\
Index: libtinymail-camel/camel-lite/camel/camel-certdb.c
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-certdb.c	(revision 3558)
+++ libtinymail-camel/camel-lite/camel/camel-certdb.c	(working copy)
@@ -478,6 +478,8 @@
 {
 	CamelCert *cert;
 
+	/* we set 0 to trust level this way (unknown) */
+
 	if (certdb->cert_chunks)
 		cert = e_memchunk_alloc0 (certdb->cert_chunks);
 	else
Index: libtinymail-camel/camel-lite/camel/camel-certdb.h
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-certdb.h	(revision 3558)
+++ libtinymail-camel/camel-lite/camel/camel-certdb.h	(working copy)
@@ -26,6 +26,9 @@
 
 #include <stdio.h>
 #include <camel/camel-object.h>
+#ifdef ENABLE_CST
+#include <cst.h>
+#endif
 
 #define CAMEL_CERTDB_TYPE         (camel_certdb_get_type ())
 #define CAMEL_CERTDB(obj)         (CAMEL_CHECK_CAST (obj, camel_certdb_get_type (), CamelCertDB))
@@ -65,6 +68,9 @@
 	char *fingerprint;
 
 	CamelCertTrust trust;
+#ifdef ENABLE_CST
+	cst_t_seqnum certID;
+#endif
 	GByteArray *rawcert;
 } CamelCert;
 
Index: libtinymail-camel/camel-lite/camel/camel-private.h
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-private.h	(revision 3558)
+++ libtinymail-camel/camel-lite/camel/camel-private.h	(working copy)
@@ -32,6 +32,9 @@
 
 #include <pthread.h>
 #include <libedataserver/e-msgport.h>
+#ifdef ENABLE_CST
+#include <cst.h>
+#endif
 
 G_BEGIN_DECLS
 
@@ -182,6 +185,9 @@
 	GMutex *io_lock;	/* load/save lock, for access to saved_count, etc */
 	GMutex *alloc_lock;	/* for setting up and using allocators */
 	GMutex *ref_lock;	/* for reffing/unreffing certs */
+#ifdef ENABLE_CST
+	CST    *cst;            /* Certificate storage */
+#endif
 };
 
 #define CAMEL_CERTDB_LOCK(db, l) \
Index: libtinymail-camel/camel-lite/camel/camel-tcp-stream-ssl.c
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-tcp-stream-ssl.c	(revision 3558)
+++ libtinymail-camel/camel-lite/camel/camel-tcp-stream-ssl.c	(working copy)
@@ -902,8 +902,6 @@
 				filename, error->message);
 			g_error_free (error);
 
-			camel_cert_set_trust (
-				certdb, ccert, CAMEL_CERT_TRUST_UNKNOWN);
 			camel_certdb_touch (certdb);
 			g_free (fingerprint);
 			g_free (filename);
@@ -923,7 +921,6 @@
 	if (ccert->rawcert->len != cert->derCert.len
 	    || memcmp(ccert->rawcert->data, cert->derCert.data, cert->derCert.len) != 0) {
 		g_warning("rawcert != derCer");
-		camel_cert_set_trust(certdb, ccert, CAMEL_CERT_TRUST_UNKNOWN);
 		camel_certdb_touch(certdb);
 	}
 
@@ -945,7 +942,6 @@
 	/* hostname is set in caller */
 	/*camel_cert_set_hostname(certdb, ccert, ssl->priv->expected_host);*/
 	camel_cert_set_fingerprint(certdb, ccert, fingerprint);
-	camel_cert_set_trust(certdb, ccert, CAMEL_CERT_TRUST_UNKNOWN);
 	g_free(fingerprint);
 
 	camel_certdb_nss_cert_set(certdb, ccert, cert, session);
@@ -1036,6 +1032,7 @@
 	CERTCertificate *cert;
 	SECStatus status = SECFailure;
 	struct _CamelTcpStreamSSLPrivate *priv;
+	CamelCertTrust trust;
 
 	g_return_val_if_fail (data != NULL, SECFailure);
 	g_return_val_if_fail (CAMEL_IS_TCP_STREAM_SSL (data), SECFailure);
@@ -1054,15 +1051,16 @@
 		camel_cert_set_hostname(certdb, ccert, ssl->priv->expected_host);
 	}
 
-	if (ccert->trust == CAMEL_CERT_TRUST_UNKNOWN) {
+	trust = camel_cert_get_trust (certdb, ccert);
+	if (trust == CAMEL_CERT_TRUST_UNKNOWN) {
 		status = CERT_VerifyCertNow(cert->dbhandle, cert, TRUE, certUsageSSLClient, NULL);
 		fingerprint = cert_fingerprint(cert);
 		cert_str = g_strdup_printf (_("Issuer:            %s\n"
 					      "Subject:           %s\n"
 					      "Fingerprint:       %s\n"
 					      "Signature:         %s"),
-					    CERT_NameToAscii (&cert->issuer),
-					    CERT_NameToAscii (&cert->subject),
+					    ccert?camel_cert_get_issuer (certdb, ccert):CERT_NameToAscii (&cert->issuer),
+					    ccert?camel_cert_get_subject (certdb, ccert):CERT_NameToAscii (&cert->subject),
 					    fingerprint, status == SECSuccess?_("GOOD"):_("BAD"));
 		g_free(fingerprint);
 
@@ -1080,7 +1078,7 @@
 			camel_certdb_touch(certdb);
 		}
 	} else {
-		accept = ccert->trust != CAMEL_CERT_TRUST_NEVER;
+		accept = trust != CAMEL_CERT_TRUST_NEVER;
 	}
 
 	camel_certdb_cert_unref(certdb, ccert);
Index: libtinymail-camel/camel-lite/config.h.in
===================================================================
--- libtinymail-camel/camel-lite/config.h.in	(revision 3558)
+++ libtinymail-camel/camel-lite/config.h.in	(working copy)
@@ -6,6 +6,9 @@
 /* Base version (Major.Minor) */
 #undef BASE_VERSION
 
+/* Is libcst enabled */
+#undef ENABLE_CST
+
 /* Really don't try this at home */
 #undef ENABLE_IMAPP
 
Index: libtinymail-camel/camel-lite/configure.ac
===================================================================
--- libtinymail-camel/camel-lite/configure.ac	(revision 3558)
+++ libtinymail-camel/camel-lite/configure.ac	(working copy)
@@ -83,6 +83,7 @@
 		mozilla_nspr_eds=$mozilla_nspr
 		msg_ssl="yes (Mozilla NSS)"
 		msg_smime="yes (Mozilla NSS)"
+		has_nss=yes
 		AC_DEFINE(ENABLE_SMIME,1,[Define if SMIME should be enabled])
 	        AC_DEFINE(HAVE_NSS,1,[Define if you have NSS])
         	AC_DEFINE(HAVE_SSL,1,[Define if you have a supported SSL library])
@@ -96,6 +97,7 @@
 	    AC_CHECK_LIB(crypto, EVP_md5, [
                 SSL_LIBS="-lcrypto -lssl"
                 msg_ssl="yes (OpenSSL)"
+		has_nss=no
                 AC_DEFINE(HAVE_SSL,1,[Define if you have a supported SSL library])
                 AC_DEFINE(HAVE_OPENSSL,1,[Define if you want to use OpenSSL as SSL library])
         	],,)
@@ -111,6 +113,7 @@
 		mozilla_nss_eds=$mozilla_nss
                 msg_ssl="yes (Mozilla NSS)"
                 msg_smime="yes (Mozilla NSS)"
+		has_nss=yes
                 AC_DEFINE(ENABLE_SMIME,1,[Define if SMIME should be enabled])
                 AC_DEFINE(HAVE_NSS,1,[Define if you have NSS])
                 AC_DEFINE(HAVE_SSL,1,[Define if you have a supported SSL library])
@@ -118,6 +121,19 @@
         fi
    ])
 
+if test x$has_nss = xyes; then
+     AC_MSG_CHECKING(Support for libCST)
+     PKG_CHECK_MODULES(LIBCST, cst, have_cst=yes, have_cst=no)
+     AC_MSG_RESULT($have_cst)
+else
+     LIBCST_CFLAGS=
+     LIBCST_LIBS=
+     have_cst=no
+fi
+AM_CONDITIONAL([HAVE_CST],[test x"$have_cst" == "xyes"])
+AC_DEFINE_UNQUOTED(ENABLE_CST, "$have_cst", [Is libcst enabled])
+AC_SUBST(LIBCST_CFLAGS)
+AC_SUBST(LIBCST_LIBS)
 
 AC_SUBST(msg_smime)
 AC_SUBST(msg_ssl)
@@ -208,8 +224,8 @@
 fi
 
 PKG_CHECK_MODULES(CAMEL, gthread-2.0 gmodule-2.0 gobject-2.0 $mozilla_nss_eds $mozilla_nspr_eds)
-CAMEL_CFLAGS="$CAMEL_CFLAGS $THREADS_CFLAGS $KRB4_CFLAGS $KRB5_CFLAGS"
-CAMEL_LIBS="$CAMEL_LIBS -lz $THREADS_LIBS $KRB4_LDFLAGS $KRB5_LDFLAGS"
+CAMEL_CFLAGS="$CAMEL_CFLAGS $LIBCST_CFLAGS $THREADS_CFLAGS $KRB4_CFLAGS $KRB5_CFLAGS"
+CAMEL_LIBS="$CAMEL_LIBS -lz $LIBCST_LIBS $THREADS_LIBS $KRB4_LDFLAGS $KRB5_LDFLAGS"
 
 AC_SUBST(CAMEL_CFLAGS)
 AC_SUBST(CAMEL_LIBS)

--- End Message ---


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]