From bdcc74ccbecc617774bc6e5af9d0e4a11ad00137 Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Wed, 15 Aug 2012 15:55:28 -0400 Subject: 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. --- about.c | 48 ++++++++++++++++++++++++++++++++++-------------- xombrero.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ xombrero.h | 3 ++- 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 warn_cert_changes " - "setting in your xombrero configuration." + "

You tried to access %s." + "

The site's security certificate has been modified." + "

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 " + "warn_cert_changes setting in your xombrero " + "configuration." "

Choose an action:" - "
Show Certificate" - "
Allow for this Session" - "
Cache new certificate", + "
Allow for this session" + "
Cache new certificate" + "
Show cached certificate" + "
Show new certificate", + 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) -- cgit 1.4.1-2-gfad0