Added support for ssl validation.
authorDaniel Carl <danielcarl@gmx.de>
Sat, 5 Jan 2013 12:17:19 +0000 (13:17 +0100)
committerDaniel Carl <danielcarl@gmx.de>
Sat, 5 Jan 2013 14:05:20 +0000 (15:05 +0100)
SSL certificates are checked against a CA bundle (by default:
/etc/ssl/certs/ca-certificates.crt)
If verified, green background colour in the status bar.
If unverified, vimp will refuse to connect.

src/main.c
src/main.h
src/setting.c

index b696f75..27165a0 100644 (file)
@@ -58,6 +58,7 @@ static void vp_read_config(void);
 static void vp_init_gui(void);
 static void vp_init_files(void);
 static void vp_setup_signals(void);
+static void vp_setup_settings(void);
 static void vp_set_cookie(SoupCookie* cookie);
 static const gchar* vp_get_cookies(SoupURI *uri);
 static gboolean vp_hide_message(void);
@@ -80,6 +81,19 @@ static void vp_webview_load_status_cb(WebKitWebView* view, GParamSpec* pspec, gp
             break;
 
         case WEBKIT_LOAD_COMMITTED:
+            /* set the status */
+            if (g_str_has_prefix(uri, "https://")) {
+                WebKitWebFrame* frame         = webkit_web_view_get_main_frame(vp.gui.webview);
+                WebKitWebDataSource* src      = webkit_web_frame_get_data_source(frame);
+                WebKitNetworkRequest* request = webkit_web_data_source_get_request(src);
+                SoupMessage* msg              = webkit_network_request_get_message(request);
+                vp.state.status = (soup_message_get_flags(msg) ^ SOUP_MESSAGE_CERTIFICATE_TRUSTED)
+                    ? VP_STATUS_SSL_VALID
+                    : VP_STATUS_SSL_INVALID;
+            } else {
+                vp.state.status = VP_STATUS_NORMAL;
+            }
+
             /* status bar is updated by vp_set_mode */
             vp_set_mode(VP_MODE_NORMAL , FALSE);
             vp_update_urlbar(uri);
@@ -411,6 +425,8 @@ void vp_update_statusbar(void)
 {
     GString* status = g_string_new("");
 
+    vp_update_status_style();
+
     /* show current count */
     g_string_append_printf(status, "%.0d", vp.state.count);
     /* show current modkey */
@@ -440,6 +456,14 @@ void vp_update_statusbar(void)
     g_string_free(status, TRUE);
 }
 
+void vp_update_status_style(void)
+{
+    StatusType type = vp.state.status;
+    vp_set_widget_font(vp.gui.eventbox, &vp.style.status_fg[type], &vp.style.status_bg[type], vp.style.status_font[type]);
+    vp_set_widget_font(vp.gui.statusbar.left, &vp.style.status_fg[type], &vp.style.status_bg[type], vp.style.status_font[type]);
+    vp_set_widget_font(vp.gui.statusbar.right, &vp.style.status_fg[type], &vp.style.status_bg[type], vp.style.status_font[type]);
+}
+
 void vp_echo(const MessageType type, gboolean hide, const char *error, ...)
 {
     va_list arg_list;
@@ -492,7 +516,11 @@ static void vp_init(void)
     /* initialize settings */
     setting_init();
 
+    /* read additional configuration from config files */
     vp_read_config();
+
+    /* set the configuration to the required objects */
+    vp_setup_settings();
 }
 
 static void vp_read_config(void)
@@ -617,13 +645,16 @@ static void vp_init_files(void)
 void vp_set_widget_font(GtkWidget* widget, const VpColor* fg, const VpColor* bg, PangoFontDescription* font)
 {
     VP_WIDGET_OVERRIDE_FONT(widget, font);
+    /* TODO are they all required? */
     VP_WIDGET_OVERRIDE_TEXT(widget, GTK_STATE_NORMAL, fg);
+    VP_WIDGET_OVERRIDE_COLOR(widget, GTK_STATE_NORMAL, fg);
     VP_WIDGET_OVERRIDE_BASE(widget, GTK_STATE_NORMAL, bg);
+    VP_WIDGET_OVERRIDE_BACKGROUND(widget, GTK_STATE_NORMAL, bg);
 }
 
 static void vp_setup_signals(void)
 {
-    Gui* gui              = &vp.gui;
+    Gui* gui = &vp.gui;
 
     /* Set up callbacks so that if either the main window or the browser
      * instance is closed, the program will exit */
@@ -652,8 +683,6 @@ static void vp_setup_signals(void)
         NULL
     );
 
-    g_object_set(vp.net.soup_session, "max-conns", SETTING_MAX_CONNS , NULL);
-    g_object_set(vp.net.soup_session, "max-conns-per-host", SETTING_MAX_CONNS_PER_HOST, NULL);
     g_signal_connect_after(G_OBJECT(vp.net.soup_session), "request-started", G_CALLBACK(vp_new_request_cb), NULL);
 
     /* inspector */
@@ -665,6 +694,12 @@ static void vp_setup_signals(void)
     );
 }
 
+static void vp_setup_settings(void)
+{
+    g_object_set(vp.net.soup_session, "max-conns", SETTING_MAX_CONNS , NULL);
+    g_object_set(vp.net.soup_session, "max-conns-per-host", SETTING_MAX_CONNS_PER_HOST, NULL);
+}
+
 static gboolean vp_button_relase_cb(WebKitWebView* webview, GdkEventButton* event, gpointer data)
 {
     gboolean propagate = FALSE;
index b8ead11..2ce3bee 100644 (file)
@@ -134,6 +134,13 @@ typedef enum {
     VP_MSG_LAST
 } MessageType;
 
+typedef enum {
+    VP_STATUS_NORMAL,
+    VP_STATUS_SSL_VALID,
+    VP_STATUS_SSL_INVALID,
+    VP_STATUS_LAST
+} StatusType;
+
 typedef enum {
     VP_COMP_NORMAL,
     VP_COMP_ACTIVE,
@@ -198,6 +205,7 @@ typedef struct {
     guint           count;
     GdkNativeWindow embed;
     guint           progress;
+    StatusType      status;
 } State;
 
 /* behaviour */
@@ -239,9 +247,9 @@ typedef struct {
     gchar                 hint_fg[HEX_COLOR_LEN];
     gchar*                hint_style;
     /* status bar */
-    VpColor               status_bg;
-    VpColor               status_fg;
-    PangoFontDescription* status_font;
+    VpColor               status_bg[VP_STATUS_LAST];
+    VpColor               status_fg[VP_STATUS_LAST];
+    PangoFontDescription* status_font[VP_STATUS_LAST];
 } Style;
 
 typedef struct {
@@ -272,6 +280,7 @@ extern VpCore vp;
 /* functions */
 void vp_update_statusbar(void);
 void vp_update_urlbar(const gchar* uri);
+void vp_update_status_style(void);
 void vp_echo(const MessageType type, gboolean hide, const char *error, ...);
 gboolean vp_set_mode(Mode mode, gboolean clean);
 void vp_set_widget_font(GtkWidget* widget, const VpColor* fg, const VpColor* bg, PangoFontDescription* font);
index e78e969..65f2329 100644 (file)
@@ -20,6 +20,8 @@
 #include "setting.h"
 #include "util.h"
 
+#define OVERWRITE_STRING(t, s) {if(t){g_free(t);t=NULL;}t=g_strdup(s);}
+
 static Arg* setting_char_to_arg(const gchar* str, const Type type);
 static void setting_print_value(const Setting* s, void* value);
 static gboolean setting_webkit(const Setting* s, const gboolean get);
@@ -31,6 +33,8 @@ static gboolean setting_status_font(const Setting* s, const gboolean get);
 static gboolean setting_input_style(const Setting* s, const gboolean get);
 static gboolean setting_completion_style(const Setting* s, const gboolean get);
 static gboolean setting_hint_style(const Setting* s, const gboolean get);
+static gboolean setting_strict_ssl(const Setting* s, const gboolean get);
+static gboolean setting_ca_bundle(const Setting* s, const gboolean get);
 
 static Setting default_settings[] = {
     /* webkit settings */
@@ -80,9 +84,18 @@ static Setting default_settings[] = {
     /* internal variables */
     {NULL, "cookie-timeout", TYPE_INTEGER, setting_cookie_timeout, {.i = 4800}},
     {NULL, "scrollstep", TYPE_INTEGER, setting_scrollstep, {.i = 40}},
+
+    /* TODO set type to color */
     {NULL, "status-color-bg", TYPE_CHAR, setting_status_color_bg, {.s = "#000"}},
     {NULL, "status-color-fg", TYPE_CHAR, setting_status_color_fg, {.s = "#fff"}},
     {NULL, "status-font", TYPE_FONT, setting_status_font, {.s = "monospace bold 8"}},
+    {NULL, "status-ssl-color-bg", TYPE_CHAR, setting_status_color_bg, {.s = "#95e454"}},
+    {NULL, "status-ssl-color-fg", TYPE_CHAR, setting_status_color_fg, {.s = "#000"}},
+    {NULL, "status-ssl-font", TYPE_FONT, setting_status_font, {.s = "monospace bold 8"}},
+    {NULL, "status-sslinvalid-color-bg", TYPE_CHAR, setting_status_color_bg, {.s = "#f08080"}},
+    {NULL, "status-sslinvalid-color-fg", TYPE_CHAR, setting_status_color_fg, {.s = "#000"}},
+    {NULL, "status-sslinvalid-font", TYPE_FONT, setting_status_font, {.s = "monospace bold 8"}},
+
     {NULL, "input-bg-normal", TYPE_COLOR, setting_input_style, {.s = "#fff"}},
     {NULL, "input-bg-error", TYPE_COLOR, setting_input_style, {.s = "#f00"}},
     {NULL, "input-fg-normal", TYPE_COLOR, setting_input_style, {.s = "#000"}},
@@ -100,6 +113,8 @@ static Setting default_settings[] = {
     {NULL, "hint-bg-focus", TYPE_CHAR, setting_hint_style, {.s = "#8f0"}},
     {NULL, "hint-fg", TYPE_CHAR, setting_hint_style, {.s = "#000"}},
     {NULL, "hint-style", TYPE_CHAR, setting_hint_style, {.s = "font-family:monospace;font-weight:bold;color:#000;background-color:#fff;margin:0;padding:0px 1px;border:1px solid #444;opacity:0.7;"}},
+    {NULL, "strict-ssl", TYPE_BOOLEAN, setting_strict_ssl, {.i = 1}},
+    {NULL, "ca-bundle", TYPE_CHAR, setting_ca_bundle, {.s = "/etc/ssl/certs/ca-certificates.crt"}},
 };
 
 
@@ -323,13 +338,20 @@ static gboolean setting_scrollstep(const Setting* s, const gboolean get)
 
 static gboolean setting_status_color_bg(const Setting* s, const gboolean get)
 {
+    StatusType type;
+    if (g_str_has_prefix(s->name, "status-sslinvalid")) {
+        type = VP_STATUS_SSL_INVALID;
+    } else if (g_str_has_prefix(s->name, "status-ssl")) {
+        type = VP_STATUS_SSL_VALID;
+    } else {
+        type = VP_STATUS_NORMAL;
+    }
+
     if (get) {
-        setting_print_value(s, &vp.style.status_bg);
+        setting_print_value(s, &vp.style.status_bg[type]);
     } else {
-        VP_COLOR_PARSE(&vp.style.status_bg, s->arg.s);
-        VP_WIDGET_OVERRIDE_BACKGROUND(vp.gui.eventbox, GTK_STATE_NORMAL, &vp.style.status_bg);
-        VP_WIDGET_OVERRIDE_BACKGROUND(GTK_WIDGET(vp.gui.statusbar.left), GTK_STATE_NORMAL, &vp.style.status_bg);
-        VP_WIDGET_OVERRIDE_BACKGROUND(GTK_WIDGET(vp.gui.statusbar.right), GTK_STATE_NORMAL, &vp.style.status_bg);
+        VP_COLOR_PARSE(&vp.style.status_bg[type], s->arg.s);
+        vp_update_status_style();
     }
 
     return TRUE;
@@ -337,13 +359,20 @@ static gboolean setting_status_color_bg(const Setting* s, const gboolean get)
 
 static gboolean setting_status_color_fg(const Setting* s, const gboolean get)
 {
+    StatusType type;
+    if (g_str_has_prefix(s->name, "status-sslinvalid")) {
+        type = VP_STATUS_SSL_INVALID;
+    } else if (g_str_has_prefix(s->name, "status-ssl")) {
+        type = VP_STATUS_SSL_VALID;
+    } else {
+        type = VP_STATUS_NORMAL;
+    }
+
     if (get) {
-        setting_print_value(s, &vp.style.status_fg);
+        setting_print_value(s, &vp.style.status_fg[type]);
     } else {
-        VP_COLOR_PARSE(&vp.style.status_fg, s->arg.s);
-        VP_WIDGET_OVERRIDE_COLOR(vp.gui.eventbox, GTK_STATE_NORMAL, &vp.style.status_fg);
-        VP_WIDGET_OVERRIDE_COLOR(GTK_WIDGET(vp.gui.statusbar.left), GTK_STATE_NORMAL, &vp.style.status_fg);
-        VP_WIDGET_OVERRIDE_COLOR(GTK_WIDGET(vp.gui.statusbar.right), GTK_STATE_NORMAL, &vp.style.status_fg);
+        VP_COLOR_PARSE(&vp.style.status_fg[type], s->arg.s);
+        vp_update_status_style();
     }
 
     return TRUE;
@@ -351,18 +380,25 @@ static gboolean setting_status_color_fg(const Setting* s, const gboolean get)
 
 static gboolean setting_status_font(const Setting* s, const gboolean get)
 {
+    StatusType type;
+    if (g_str_has_prefix(s->name, "status-sslinvalid")) {
+        type = VP_STATUS_SSL_INVALID;
+    } else if (g_str_has_prefix(s->name, "status-ssl")) {
+        type = VP_STATUS_SSL_VALID;
+    } else {
+        type = VP_STATUS_NORMAL;
+    }
+
     if (get) {
-        setting_print_value(s, vp.style.status_font);
+        setting_print_value(s, vp.style.status_font[type]);
     } else {
-        if (vp.style.status_font) {
+        if (vp.style.status_font[type]) {
             /* free previous font description */
-            pango_font_description_free(vp.style.status_font);
+            pango_font_description_free(vp.style.status_font[type]);
         }
-        vp.style.status_font = pango_font_description_from_string(s->arg.s);
+        vp.style.status_font[type] = pango_font_description_from_string(s->arg.s);
 
-        VP_WIDGET_OVERRIDE_FONT(vp.gui.eventbox, vp.style.status_font);
-        VP_WIDGET_OVERRIDE_FONT(GTK_WIDGET(vp.gui.statusbar.left), vp.style.status_font);
-        VP_WIDGET_OVERRIDE_FONT(GTK_WIDGET(vp.gui.statusbar.right), vp.style.status_font);
+        vp_update_status_style();
     }
 
     return TRUE;
@@ -476,13 +512,37 @@ static gboolean setting_hint_style(const Setting* s, const gboolean get)
         if (get) {
             setting_print_value(s, style->hint_style);
         } else {
-            if (style->hint_style) {
-                g_free(style->hint_style);
-                style->hint_style = NULL;
-            }
-            style->hint_style = g_strdup(s->arg.s);
+            OVERWRITE_STRING(style->hint_style, s->arg.s);
         }
     }
 
     return TRUE;
 }
+
+static gboolean setting_strict_ssl(const Setting* s, const gboolean get)
+{
+    if (get) {
+        gboolean value;
+        g_object_get(vp.net.soup_session, "ssl-strict", &value, NULL);
+        setting_print_value(s, &value);
+    } else {
+        g_object_set(vp.net.soup_session, "ssl-strict", s->arg.i ? TRUE : FALSE, NULL);
+
+    }
+
+    return TRUE;
+}
+
+static gboolean setting_ca_bundle(const Setting* s, const gboolean get)
+{
+    if (get) {
+        gchar* value = NULL;
+        g_object_get(vp.net.soup_session, "ssl-ca-file", &value, NULL);
+        setting_print_value(s, value);
+        g_free(value);
+    } else {
+        g_object_set(vp.net.soup_session, "ssl-ca-file", s->arg.s, NULL);
+    }
+
+    return TRUE;
+}