about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJosh Rickmar <jrick@devio.us>2012-08-15 15:55:28 -0400
committerJosh Rickmar <jrick@devio.us>2012-08-15 15:55:28 -0400
commitbdcc74ccbecc617774bc6e5af9d0e4a11ad00137 (patch)
treeacc64c32bad11e0d70f30102567dbde98348040d
parent88275e2ea86b2feebf85395c9f2b3f1debcd826a (diff)
downloadxombrero-bdcc74ccbecc617774bc6e5af9d0e4a11ad00137.tar.gz
Add more info and features to about:secviolation
This adds the full url to the about:secviolation warning page, as well
as implementing a new link to show the local cached cert instead of
only the new remote one.
-rw-r--r--about.c48
-rw-r--r--xombrero.c62
-rw-r--r--xombrero.h3
3 files changed, 98 insertions, 15 deletions
diff --git a/about.c b/about.c
index cab3efa..fdd6032 100644
--- a/about.c
+++ b/about.c
@@ -858,9 +858,19 @@ xtp_handle_sv(struct tab *t, uint8_t cmd, int id, const char *query)
 	args.s = sv->uri;
 
 	switch (cmd) {
-	case XT_XTP_SV_SHOW_CERT:
+	case XT_XTP_SV_SHOW_NEW_CERT:
 		args.i = XT_SHOW;
-		cert_cmd(t, &args);
+		if (cert_cmd(t, &args)) {
+			xtp_page_sv(t, &args);
+			return;
+		}
+		break;
+	case XT_XTP_SV_SHOW_CACHED_CERT:
+		args.i = XT_CACHE | XT_SHOW;
+		if (cert_cmd(t, &args)) {
+			xtp_page_sv(t, &args);
+			return;
+		}
 		break;
 	case XT_XTP_SV_ALLOW_SESSION:
 		soupuri = soup_uri_new(sv->uri);
@@ -872,7 +882,10 @@ xtp_handle_sv(struct tab *t, uint8_t cmd, int id, const char *query)
 		break;
 	case XT_XTP_SV_CACHE:
 		args.i = XT_CACHE;
-		cert_cmd(t, &args);
+		if (cert_cmd(t, &args)) {
+			xtp_page_sv(t, &args);
+			return;
+		}
 		load_uri(t, sv->uri);
 		focus_webview(t);
 		break;
@@ -1894,22 +1907,29 @@ xtp_page_sv(struct tab *t, struct karg *args)
 		return (-1);
 
 	body = g_strdup_printf(
-	    "The domain of the page you have tried to access, %s, has a "
-	    "different remote certificate then the local cached version from a "
-	    "previous visit.  As a security precaution to help prevent against "
-	    "man-in-the-middle attacks, please choose one of the following "
-	    "actions to continue, or disable the <tt>warn_cert_changes</tt> "
-	    "setting in your xombrero configuration."
+	    "<p><b>You tried to access %s</b>."
+	    "<p><b>The site's security certificate has been modified.</b>"
+	    "<p>The domain of the page you have tried to access, <b>%s</b>, "
+	    "has a different remote certificate then the local cached version "
+	    "from a previous visit.  As a security precaution to help prevent "
+	    "against man-in-the-middle attacks, please choose one of the "
+	    "following actions to continue, or disable the "
+	    "<tt>warn_cert_changes</tt> setting in your xombrero "
+	    "configuration."
 	    "<p><b>Choose an action:"
-	    "<br><a href='%s%d/%s/%d/%d'>Show Certificate</a>"
-	    "<br><a href='%s%d/%s/%d/%d'>Allow for this Session</a>"
-	    "<br><a href='%s%d/%s/%d/%d'>Cache new certificate</a>",
+	    "<br><a href='%s%d/%s/%d/%d'>Allow for this session</a>"
+	    "<br><a href='%s%d/%s/%d/%d'>Cache new certificate</a>"
+	    "<br><a href='%s%d/%s/%d/%d'>Show cached certificate</a>"
+	    "<br><a href='%s%d/%s/%d/%d'>Show new certificate</a>",
+	    sv->uri,
 	    soupuri->host,
-	    XT_XTP_STR, XT_XTP_SV, sv_session_key, XT_XTP_SV_SHOW_CERT,
-		sv->xtp_arg,
 	    XT_XTP_STR, XT_XTP_SV, sv_session_key, XT_XTP_SV_ALLOW_SESSION,
 		sv->xtp_arg,
 	    XT_XTP_STR, XT_XTP_SV, sv_session_key, XT_XTP_SV_CACHE,
+		sv->xtp_arg,
+	    XT_XTP_STR, XT_XTP_SV, sv_session_key, XT_XTP_SV_SHOW_CACHED_CERT,
+		sv->xtp_arg,
+	    XT_XTP_STR, XT_XTP_SV, sv_session_key, XT_XTP_SV_SHOW_NEW_CERT,
 		sv->xtp_arg);
 
 	page = get_html_page("Security Violation", body, "", 0);
diff --git a/xombrero.c b/xombrero.c
index 53b68f3..cd24a6d 100644
--- a/xombrero.c
+++ b/xombrero.c
@@ -2000,6 +2000,51 @@ done:
 	return (rv);
 }
 
+gnutls_x509_crt_t *
+get_local_cert_chain(const char *uri, size_t *ncerts, const char **error_str,
+    const char *dir)
+{
+	SoupURI			*su;
+	unsigned char		cert_buf[64 * 1024] = {0};
+	gnutls_datum_t		data;
+	unsigned int		len = UINT_MAX;
+	int			bytes_read;
+	char			file[PATH_MAX];
+	FILE			*f;
+	gnutls_x509_crt_t	*certs;
+
+	if ((su = soup_uri_new(uri)) == NULL) {
+		*error_str = "Invalid URI";
+		return (NULL);
+	}
+
+	snprintf(file, sizeof file, "%s" PS "%s", dir, su->host);
+	if ((f = fopen(file, "r")) == NULL) {
+		*error_str = "Could not read local cert";
+		return (NULL);
+	}
+
+	bytes_read = fread(cert_buf, sizeof *cert_buf, sizeof cert_buf, f);
+	if (bytes_read == 0) {
+		*error_str = "Could not read local cert";
+		return (NULL);
+	}
+
+	data.data = cert_buf;
+	data.size = bytes_read;
+	certs = g_malloc(sizeof *certs);
+	*ncerts = INT_MAX;
+	if (gnutls_x509_crt_list_import(certs, &len, &data,
+	    GNUTLS_X509_FMT_PEM, 0) < 0) {
+		*error_str = "Error reading local cert chain";
+		return (NULL);
+	}
+
+	*ncerts = len;
+	return (certs);
+}
+
+
 int
 cert_cmd(struct tab *t, struct karg *args)
 {
@@ -2024,6 +2069,23 @@ cert_cmd(struct tab *t, struct karg *args)
 		return (1);
 	}
 
+	/* 
+	 * if we're only showing the local certs, don't open a socket and get
+	 * the remote certs
+	 */
+	if (args->i & XT_SHOW && args->i & XT_CACHE) {
+		certs = get_local_cert_chain(uri, &cert_count, &error_str,
+		    certs_cache_dir);
+		if (error_str == NULL) {
+			show_certs(t, certs, cert_count, "Certificate Chain");
+			free_connection_certs(certs, cert_count);
+		} else {
+			show_oops(t, "%s", error_str);
+			return (1);
+		}
+		return (0);
+	}
+
 	if ((s = connect_socket_from_uri(uri, &error_str, domain,
 	    sizeof domain)) == -1) {
 		show_oops(t, "%s", error_str);
diff --git a/xombrero.h b/xombrero.h
index e78c68f..1b47f3e 100644
--- a/xombrero.h
+++ b/xombrero.h
@@ -726,9 +726,10 @@ int		command_mode(struct tab *, struct karg *);
 #define XT_XTP_AB_EDIT_CONF	(1)
 
 /* XTP security violation actions */
-#define XT_XTP_SV_SHOW_CERT	(1)
+#define XT_XTP_SV_SHOW_NEW_CERT	(1)
 #define XT_XTP_SV_ALLOW_SESSION	(2)
 #define XT_XTP_SV_CACHE		(3)
+#define XT_XTP_SV_SHOW_CACHED_CERT	(4)
 
 /* XTP set actions */
 #define XT_XTP_RT_SAVE		(1)