[evolution-data-server] Bug #440316 - Improve SSL Certificate check bad signature dialog



commit 287ea88b08c4fd81b49587a432e6e0d329ccdbe9
Author: Milan Crha <mcrha redhat com>
Date:   Tue Nov 15 12:55:17 2011 +0100

    Bug #440316 - Improve SSL Certificate check bad signature dialog

 camel/camel-certdb.c         |    4 ++++
 camel/camel-certdb.h         |    3 ++-
 camel/camel-disco-diary.c    |    4 ++--
 camel/camel-session.c        |   17 ++++++++---------
 camel/camel-session.h        |    8 ++++----
 camel/camel-tcp-stream-ssl.c |   41 ++++++++++++++++++++++++++++++++---------
 6 files changed, 52 insertions(+), 25 deletions(-)
---
diff --git a/camel/camel-certdb.c b/camel/camel-certdb.c
index 9241a1c..4e1c6a4 100644
--- a/camel/camel-certdb.c
+++ b/camel/camel-certdb.c
@@ -219,6 +219,10 @@ certdb_cert_load (CamelCertDB *certdb,
 	if (camel_file_util_decode_uint32 (istream, &cert->trust) == -1)
 		goto error;
 
+	/* unset temporary trusts on load */
+	if (cert->trust == CAMEL_CERT_TRUST_TEMPORARY)
+		cert->trust = CAMEL_CERT_TRUST_UNKNOWN;
+
 	return cert;
 
  error:
diff --git a/camel/camel-certdb.h b/camel/camel-certdb.h
index c289e72..6d5bf5f 100644
--- a/camel/camel-certdb.h
+++ b/camel/camel-certdb.h
@@ -72,7 +72,8 @@ typedef enum {
 	CAMEL_CERT_TRUST_NEVER,
 	CAMEL_CERT_TRUST_MARGINAL,
 	CAMEL_CERT_TRUST_FULLY,
-	CAMEL_CERT_TRUST_ULTIMATE
+	CAMEL_CERT_TRUST_ULTIMATE,
+	CAMEL_CERT_TRUST_TEMPORARY
 } CamelCertTrust;
 
 typedef struct {
diff --git a/camel/camel-disco-diary.c b/camel/camel-disco-diary.c
index 5410c67..1bc2312 100644
--- a/camel/camel-disco-diary.c
+++ b/camel/camel-disco-diary.c
@@ -205,7 +205,7 @@ camel_disco_diary_log (CamelDiscoDiary *diary,
 				       g_strerror (errno));
 		camel_session_alert_user (camel_service_get_session (CAMEL_SERVICE (diary->store)),
 					  CAMEL_SESSION_ALERT_ERROR,
-					  msg, FALSE);
+					  msg, NULL);
 		g_free (msg);
 
 		fclose (diary->file);
@@ -271,7 +271,7 @@ diary_decode_folder (CamelDiscoDiary *diary,
 			camel_session_alert_user (
 				camel_service_get_session (CAMEL_SERVICE (diary->store)),
 				CAMEL_SESSION_ALERT_WARNING,
-				msg, FALSE);
+				msg, NULL);
 			g_free (msg);
 			g_free (name);
 		}
diff --git a/camel/camel-session.c b/camel/camel-session.c
index b59aa8c..a661988 100644
--- a/camel/camel-session.c
+++ b/camel/camel-session.c
@@ -1091,30 +1091,29 @@ camel_session_forget_password (CamelSession *session,
  * @session: a #CamelSession
  * @type: the type of alert (info, warning, or error)
  * @prompt: the message for the user
- * @cancel: whether or not to provide a "Cancel" option in addition to
- * an "OK" option.
+ * @button_captions: List of button captions to use. If NULL, only "Dismiss" button is shown.
  *
  * Presents the given @prompt to the user, in the style indicated by
  * @type. If @cancel is %TRUE, the user will be able to accept or
  * cancel. Otherwise, the message is purely informational.
  *
- * Returns: %TRUE if the user accepts, %FALSE if they cancel.
+ * Returns: Index of pressed button from @button_captions, -1 if NULL.
  */
-gboolean
+gint
 camel_session_alert_user (CamelSession *session,
                           CamelSessionAlertType type,
                           const gchar *prompt,
-                          gboolean cancel)
+                          GSList *button_captions)
 {
 	CamelSessionClass *class;
 
-	g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE);
-	g_return_val_if_fail (prompt != NULL, FALSE);
+	g_return_val_if_fail (CAMEL_IS_SESSION (session), -1);
+	g_return_val_if_fail (prompt != NULL, -1);
 
 	class = CAMEL_SESSION_GET_CLASS (session);
-	g_return_val_if_fail (class->alert_user != NULL, FALSE);
+	g_return_val_if_fail (class->alert_user != NULL, -1);
 
-	return class->alert_user (session, type, prompt, cancel);
+	return class->alert_user (session, type, prompt, button_captions);
 }
 
 /**
diff --git a/camel/camel-session.h b/camel/camel-session.h
index 005233e..6216fee 100644
--- a/camel/camel-session.h
+++ b/camel/camel-session.h
@@ -120,10 +120,10 @@ struct _CamelSessionClass {
 						 CamelService *service,
 						 const gchar *item,
 						 GError **error);
-	gboolean	(*alert_user)		(CamelSession *session,
+	gint		(*alert_user)		(CamelSession *session,
 						 CamelSessionAlertType type,
 						 const gchar *prompt,
-						 gboolean cancel);
+						 GSList *button_captions);
 	CamelFilterDriver *
 			(*get_filter_driver)	(CamelSession *session,
 						 const gchar *type,
@@ -200,10 +200,10 @@ gboolean	camel_session_forget_password	(CamelSession *session,
 						 CamelService *service,
 						 const gchar *item,
 						 GError **error);
-gboolean	camel_session_alert_user	(CamelSession *session,
+gint		camel_session_alert_user	(CamelSession *session,
 						 CamelSessionAlertType type,
 						 const gchar *prompt,
-						 gboolean cancel);
+						 GSList *button_captions);
 gchar *		camel_session_build_password_prompt
 						(const gchar *type,
 						 const gchar *user,
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index ff6b57f..842b3ca 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -455,35 +455,58 @@ ssl_bad_cert (gpointer data,
 	}
 
 	if (ccert->trust == CAMEL_CERT_TRUST_UNKNOWN) {
+		GSList *button_captions = NULL;
+		gint button_id;
+
 		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_str = g_strdup_printf (_("   Issuer:       %s\n"
+					      "   Subject:      %s\n"
+					      "   Fingerprint:  %s\n"
+					      "   Signature:    %s"),
 					    CERT_NameToAscii (&cert->issuer),
 					    CERT_NameToAscii (&cert->subject),
 					    fingerprint, status == SECSuccess?_("GOOD"):_("BAD"));
 		g_free (fingerprint);
 
 		/* construct our user prompt */
-		prompt = g_strdup_printf (_("SSL Certificate check for %s:\n\n%s\n\nDo you wish to accept?"),
+		prompt = g_strdup_printf (_("SSL Certificate for '%s' is not trusted. Do you wish to accept it?\n\nDetailed information about the certificate:\n%s"),
 					  ssl->priv->expected_host, cert_str);
 		g_free (cert_str);
 
+		button_captions = g_slist_append (button_captions, _("_Reject"));
+		button_captions = g_slist_append (button_captions, _("Accept _temporarily"));
+		button_captions = g_slist_append (button_captions, _("_Accept permanently"));
+
 		/* query the user to find out if we want to accept this certificate */
-		accept = camel_session_alert_user (ssl->priv->session, CAMEL_SESSION_ALERT_WARNING, prompt, TRUE);
+		button_id = camel_session_alert_user (ssl->priv->session, CAMEL_SESSION_ALERT_WARNING, prompt, button_captions);
+		g_slist_free (button_captions);
 		g_free (prompt);
-		if (accept) {
-			camel_certdb_nss_cert_set (certdb, ccert, cert);
+
+		accept = button_id != 0;
+		camel_certdb_nss_cert_set (certdb, ccert, cert);
+
+		switch (button_id) {
+		case 0: /* Reject */
+			camel_cert_set_trust (certdb, ccert, CAMEL_CERT_TRUST_NEVER);
+			break;
+		case 1: /* Accept temporarily */
+			camel_cert_set_trust (certdb, ccert, CAMEL_CERT_TRUST_TEMPORARY);
+			break;
+		case 2: /* Accept permanently */
 			camel_cert_set_trust (certdb, ccert, CAMEL_CERT_TRUST_FULLY);
-			camel_certdb_touch (certdb);
+			break;
+		default: /* anything else means failure and will ask again */
+			accept = FALSE;
+			break;
 		}
+		camel_certdb_touch (certdb);
 	} else {
 		accept = ccert->trust != CAMEL_CERT_TRUST_NEVER;
 	}
 
 	camel_certdb_cert_unref (certdb, ccert);
+	camel_certdb_save (certdb);
 	g_object_unref (certdb);
 
 	return accept ? SECSuccess : SECFailure;



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