tAdd support for using custom certificates per url - surf - customized build of surf, the suckless webkit browser
 (HTM) git clone git://src.adamsgaard.dk/surf
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 3c2c0a65250e1415124603cb8d91bff4a657d46a
 (DIR) parent eb32dd6eca5b6224bb5fb28cadef5bd035581ef3
 (HTM) Author: Quentin Rameau <quinq@fifth.space>
       Date:   Fri, 28 Apr 2017 12:58:36 +0200
       
       Add support for using custom certificates per url
       
       Diffstat:
         M config.def.h                        |      11 +++++++++++
         M surf.c                              |      55 +++++++++++++++++++++++++++++++
       
       2 files changed, 66 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/config.def.h b/config.def.h
       t@@ -3,12 +3,14 @@ static int surfuseragent    = 1;  /* Append Surf version to default WebKit user 
        static char *fulluseragent  = ""; /* Or override the whole user agent string */
        static char *scriptfile     = "~/.surf/script.js";
        static char *styledir       = "~/.surf/styles/";
       +static char *certdir        = "~/.surf/certificates/";
        static char *cachedir       = "~/.surf/cache/";
        static char *cookiefile     = "~/.surf/cookies.txt";
        
        /* Webkit default features */
        static Parameter defconfig[ParameterLast] = {
                SETB(AcceleratedCanvas,  1),
       +        SETB(Certificate,        0),
                SETB(CaretBrowsing,      0),
                SETV(CookiePolicies,     "@Aa"),
                SETB(DiskCache,          1),
       t@@ -95,6 +97,15 @@ static SiteSpecific styles[] = {
                { ".*",                 "default.css" },
        };
        
       +/* certificates */
       +/*
       + * Provide custom certificate for urls
       + */
       +static SiteSpecific certs[] = {
       +        /* regexp               file in $certdir */
       +        { "://suckless\\.org/", "suckless.org.crt" },
       +};
       +
        #define MODKEY GDK_CONTROL_MASK
        
        /* hotkeys */
 (DIR) diff --git a/surf.c b/surf.c
       t@@ -60,6 +60,7 @@ enum {
        typedef enum {
                AcceleratedCanvas,
                CaretBrowsing,
       +        Certificate,
                CookiePolicies,
                DiskCache,
                DNSPrefetch,
       t@@ -162,6 +163,8 @@ static WebKitCookieAcceptPolicy cookiepolicy_get(void);
        static char cookiepolicy_set(const WebKitCookieAcceptPolicy p);
        static void seturiparameters(Client *c, const char *uri);
        static void setparameter(Client *c, int refresh, ParamName p, const Arg *a);
       +static const char *getcert(const char *uri);
       +static void setcert(Client *c, const char *file);
        static const char *getstyle(const char *uri);
        static void setstyle(Client *c, const char *file);
        static void runscript(Client *c);
       t@@ -291,9 +294,19 @@ setup(void)
                cookiefile = buildfile(cookiefile);
                scriptfile = buildfile(scriptfile);
                cachedir   = buildpath(cachedir);
       +        certdir    = buildpath(certdir);
        
                gdkkb = gdk_seat_get_keyboard(gdk_display_get_default_seat(gdpy));
        
       +        for (i = 0; i < LENGTH(certs); ++i) {
       +                if (regcomp(&(certs[i].re), certs[i].regex, REG_EXTENDED)) {
       +                        fprintf(stderr, "Could not compile regex: %s\n",
       +                                certs[i].regex);
       +                        certs[i].regex = NULL;
       +                }
       +                certs[i].file = g_strconcat(certdir, "/", certs[i].file, NULL);
       +        }
       +
                if (!stylefile) {
                        styledir = buildpath(styledir);
                        for (i = 0; i < LENGTH(styles); ++i) {
       t@@ -642,6 +655,10 @@ setparameter(Client *c, int refresh, ParamName p, const Arg *a)
                        webkit_settings_set_enable_caret_browsing(s, a->b);
                        refresh = 0;
                        break;
       +        case Certificate:
       +                if (a->b)
       +                        setcert(c, geturi(c));
       +                return; /* do not update */
                case CookiePolicies:
                        webkit_cookie_manager_set_accept_policy(
                            webkit_web_context_get_cookie_manager(
       t@@ -738,6 +755,44 @@ setparameter(Client *c, int refresh, ParamName p, const Arg *a)
        }
        
        const char *
       +getcert(const char *uri)
       +{
       +        int i;
       +
       +        for (i = 0; i < LENGTH(certs); ++i) {
       +                if (certs[i].regex &&
       +                    !regexec(&(certs[i].re), uri, 0, NULL, 0))
       +                        return certs[i].file;
       +        }
       +
       +        return NULL;
       +}
       +
       +void
       +setcert(Client *c, const char *uri)
       +{
       +        const char *file = getcert(uri);
       +        char *host;
       +        GTlsCertificate *cert;
       +
       +        if (!file)
       +                return;
       +
       +        if (!(cert = g_tls_certificate_new_from_file(file, NULL))) {
       +                fprintf(stderr, "Could not read certificate file: %s\n", file);
       +                return;
       +        }
       +
       +        uri = strstr(uri, "://") + sizeof("://") - 1;
       +        host = strndup(uri, strstr(uri, "/") - uri);
       +
       +        webkit_web_context_allow_tls_certificate_for_host(
       +            webkit_web_view_get_context(c->view), cert, host);
       +
       +        free(host);
       +}
       +
       +const char *
        getstyle(const char *uri)
        {
                int i;