about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorMarco Peereboom <marco@conformal.com>2010-12-26 19:49:10 +0000
committerMarco Peereboom <marco@conformal.com>2010-12-26 19:49:10 +0000
commit486b84d4ff885638037f56561f8984d0c9e92591 (patch)
treeeb5210fa6a93cc2e63b69e44fd9c617b1735a859
parentb7a81e74d0154eb460e90873fc3822897558ef38 (diff)
downloadxombrero-486b84d4ff885638037f56561f8984d0c9e92591.tar.gz
handle certificates more gracefully. Trusted is green, untrusted yellow.
When there is no CA file color all secure connections red.
-rw-r--r--xxxterm.19
-rw-r--r--xxxterm.c80
-rw-r--r--xxxterm.conf2
3 files changed, 82 insertions, 9 deletions
diff --git a/xxxterm.1 b/xxxterm.1
index 9aa97af..7094302 100644
--- a/xxxterm.1
+++ b/xxxterm.1
@@ -161,6 +161,15 @@ the alias on the address bar is substituted.
 For example, if g,http://www.google.com/search?q=%s is defined as an alias,
 then the URL http://www.google.com/search?q=foo is loaded when navigating to
 "g foo".
+.It Cm ssl_ca_file
+If set to a valid PEM file all server certificates will be validated against it.
+The URL bar will be colored green when the certificate is trusted and yellow when
+untrusted.
+.Pp
+If ssl_ca_file is not set then the URL bar will color all https connections red.
+.It Cm ssl_strict_certs
+If this value is set connections to untrusted sites will be aborted.
+This value is only used if ssl_ca_file is set.
 .El
 .Pp
 .Nm
diff --git a/xxxterm.c b/xxxterm.c
index c2eaab2..a49ea35 100644
--- a/xxxterm.c
+++ b/xxxterm.c
@@ -362,6 +362,9 @@ int			enable_cookie_whitelist = 1;
 int			enable_js_whitelist = 1;
 time_t			session_timeout = 3600; /* cookie session timeout */
 int			cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
+char			*ssl_ca_file = NULL;
+gboolean		ssl_strict_certs = FALSE;
+
 /*
  * Session IDs.
  * We use these to prevent people putting xxxt:// URLs on
@@ -811,10 +814,16 @@ config_parse(char *filename)
 			if (http_proxy)
 				g_free(http_proxy);
 			http_proxy = g_strdup(val);
-		} else if (!strcmp(var, "search_string")) {
+		} else if (!strcmp(var, "ssl_strict_certs"))
+			ssl_strict_certs = atoi(val);
+		else if (!strcmp(var, "search_string")) {
 			if (search_string)
 				g_free(search_string);
 			search_string = g_strdup(val);
+		} else if (!strcmp(var, "ssl_ca_file")) {
+			if (ssl_ca_file)
+				g_free(ssl_ca_file);
+			ssl_ca_file = g_strdup(val);
 		} else if (!strcmp(var, "download_dir")) {
 			if (val[0] == '~')
 				snprintf(download_dir, sizeof download_dir,
@@ -2732,9 +2741,56 @@ check_and_set_js(gchar *uri, struct tab *t)
 }
 
 void
-notify_load_status_cb(WebKitWebView* wview, GParamSpec* pspec, struct tab *t)
+show_ca_status(struct tab *t, const char *uri)
 {
+	WebKitWebFrame		*frame;
+	WebKitWebDataSource	*source;
+	WebKitNetworkRequest	*request;
+	SoupMessage		*message;
 	GdkColor		color;
+	gchar			*col_str = "white";
+
+	DNPRINTF(XT_D_URL, "show_ca_status: %d %s %s\n",
+	    ssl_strict_certs, ssl_ca_file, uri);
+
+	if (uri == NULL)
+		goto done;
+	if (ssl_ca_file == NULL) {
+		if (g_str_has_prefix(uri, "http://"))
+			goto done;
+		if (g_str_has_prefix(uri, "https://")) {
+			col_str = "red";
+			goto done;
+		}
+		return;
+	}
+	if (g_str_has_prefix(uri, "http://") ||
+	    !g_str_has_prefix(uri, "https://"))
+		goto done;
+
+	frame = webkit_web_view_get_main_frame(t->wv);
+	source = webkit_web_frame_get_data_source(frame);
+	request = webkit_web_data_source_get_request(source);
+	message = webkit_network_request_get_message(request);
+
+	if (message && (soup_message_get_flags(message) &
+	    SOUP_MESSAGE_CERTIFICATE_TRUSTED)) {
+		col_str = "green";
+		goto done;
+	} else {
+		col_str = "yellow";
+		goto done;
+	}
+done:
+	if (col_str) {
+		gdk_color_parse(col_str, &color);
+		gtk_widget_modify_base(t->uri_entry, GTK_STATE_NORMAL, &color);
+	}
+}
+
+void
+notify_load_status_cb(WebKitWebView* wview, GParamSpec* pspec, struct tab *t)
+{
 	WebKitWebFrame		*frame;
 	const gchar		*set = NULL, *uri = NULL, *title = NULL;
 	struct history		*h, find;
@@ -2775,13 +2831,7 @@ notify_load_status_cb(WebKitWebView* wview, GParamSpec* pspec, struct tab *t)
 		if (uri)
 			gtk_entry_set_text(GTK_ENTRY(t->uri_entry), uri);
 
-		/* color uri_entry */
-		if (uri && !strncmp(uri, "https://", strlen("https://")))
-			gdk_color_parse("green", &color);
-		else
-			gdk_color_parse("white", &color);
-		gtk_widget_modify_base(t->uri_entry, GTK_STATE_NORMAL, &color);
-
+		show_ca_status(t, uri);
 		break;
 
 	case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT:
@@ -3994,6 +4044,18 @@ main(int argc, char *argv[])
 	snprintf(file, sizeof file, "%s/cookies.txt", work_dir);
 	setup_cookies(file);
 
+	if (ssl_ca_file) {
+		if (stat(ssl_ca_file, &sb)) {
+			warn("no CA file: %s", ssl_ca_file);
+			g_free(ssl_ca_file);
+			ssl_ca_file = NULL;
+		} else
+			g_object_set(session,
+			    SOUP_SESSION_SSL_CA_FILE, ssl_ca_file,
+			    SOUP_SESSION_SSL_STRICT, ssl_strict_certs,
+			    (void *)NULL);
+	}
+
 	/* proxy */
 	env_proxy = getenv("http_proxy");
 	if (env_proxy)
diff --git a/xxxterm.conf b/xxxterm.conf
index 746176d..bd8231d 100644
--- a/xxxterm.conf
+++ b/xxxterm.conf
@@ -12,6 +12,8 @@ fancy_bar		= 1
 refresh_interval	= 1
 session_timeout		= 3600
 enable_cookie_whitelist = 1
+# ssl_ca_file		= /etc/ssl/cert.pem
+ssl_strict_certs	= 0
 
 # only useful if enable_scripts = 0
 enable_js_whitelist	= 1