diff options
1 files changed, 130 insertions, 78 deletions
| -rw-r--r-- | badwolf.c | 208 |
@@ -1,16 +1,18 @@ // BadWolf: Minimalist and privacy-oriented WebKitGTK+ browser -// Copyright © 2019 Haelwenn (lanodan) Monnier <contact@hacktivis.me> +// Copyright © 2019-2020 Badwolf Authors <https://hacktivis.me/projects/badwolf> // SPDX-License-Identifier: BSD-3-Clause #include "badwolf.h" #include "config.h" #include "keybindings.h" +#include "uri.h" #include <glib/gi18n.h> /* _() and other internationalization/localization helpers */ -#include <glib/gprintf.h> /* g_fprintf() */ +#include <libsoup/soup.h> /* soup* */ #include <locale.h> /* LC_* */ -#include <stdlib.h> /* realpath(), malloc() */ +#include <stdio.h> /* perror(), fprintf() */ +#include <stdlib.h> /* malloc() */ const gchar *homepage = "https://hacktivis.me/projects/badwolf"; const gchar *version = VERSION; @@ -61,32 +63,6 @@ static void closeCb_clicked(GtkButton *close, gpointer user_data); static void notebookCb_switch__page(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data); -gchar * -badwolf_ensure_uri_scheme(gchar *text, gboolean try_file) -{ - if(text == NULL) return "about:blank"; - - char *scheme = g_uri_parse_scheme(text); - - if(scheme != NULL) return text; - - if(try_file) - { - gchar *f; - char *path; - path = realpath(text, NULL); - - if(path != NULL) - { - f = g_strdup_printf("file://%s", path); - free(path); - return f; - } - } - - return g_strdup_printf("http://%s", text); -} - static gboolean WebViewCb_close(WebKitWebView *webView, gpointer user_data) { @@ -115,16 +91,16 @@ WebViewCb_web_process_terminated(WebKitWebView *webView, switch(reason) { case WEBKIT_WEB_PROCESS_CRASHED: - g_fprintf(stderr, _("the web process crashed.\n")); - webView_tab_label_change(browser, _("title|Crashed")); + fprintf(stderr, "%s", _("the web process crashed.\n")); + webView_tab_label_change(browser, _("Crashed")); break; case WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT: - g_fprintf(stderr, _("the web process exceeded the memory limit.\n")); - webView_tab_label_change(browser, _("title|Out of Memory")); + fprintf(stderr, "%s", _("the web process exceeded the memory limit.\n")); + webView_tab_label_change(browser, _("Out of Memory")); break; default: - g_fprintf(stderr, _("the web process terminated for an unknown reason.\n")); - webView_tab_label_change(browser, _("title|Unknown Crash")); + fprintf(stderr, "%s", _("the web process terminated for an unknown reason.\n")); + webView_tab_label_change(browser, _("Unknown Crash")); } return FALSE; @@ -244,10 +220,9 @@ WebViewCb_notify__estimated_load_progress(WebKitWebView *webView, gdouble progress; progress = webkit_web_view_get_estimated_load_progress(browser->webView); - if(progress == 1) - { - progress = 0; - } + + if(progress >= 1) progress = 0; + gtk_entry_set_progress_fraction(GTK_ENTRY(browser->location), progress); return TRUE; @@ -305,13 +280,9 @@ WebViewCb_create(WebKitWebView *related_web_view, struct Client *browser = new_browser(window, NULL, related_web_view); if(badwolf_new_tab(GTK_NOTEBOOK(window->notebook), browser) < 0) - { return NULL; - } else - { return browser->webView; - } } static gboolean @@ -354,6 +325,82 @@ WebViewCb_decide_policy(WebKitWebView *web_view, return TRUE; } +static char * +detail_tls_certificate_flags(GTlsCertificateFlags tls_errors) +{ + GString *errors = g_string_new(NULL); + + g_string_append_printf(errors, + _("Couldn't verify the TLS certificate to ensure a better security of the " + "connection. You might want to verify your machine and network.\n\n")); + + if(tls_errors & G_TLS_CERTIFICATE_UNKNOWN_CA) + g_string_append_printf(errors, _("Error: The X509 Certificate Authority is unknown.\n")); + + if(tls_errors & G_TLS_CERTIFICATE_BAD_IDENTITY) + g_string_append(errors, _("Error: The given identity doesn't match the expected one.\n")); + + if(tls_errors & G_TLS_CERTIFICATE_NOT_ACTIVATED) + g_string_append(errors, + _("Error: The certificate isn't valid yet. Check your system's clock.\n")); + + if(tls_errors & G_TLS_CERTIFICATE_EXPIRED) + g_string_append(errors, _("Error: The certificate has expired. Check your system's clock.\n")); + + if(tls_errors & G_TLS_CERTIFICATE_REVOKED) + g_string_append(errors, _("Error: The certificate has been revoked.\n")); + + if(tls_errors & G_TLS_CERTIFICATE_INSECURE) + g_string_append(errors, _("Error: The certificate is considered to be insecure.\n")); + + if(tls_errors & G_TLS_CERTIFICATE_GENERIC_ERROR) + g_string_append(errors, _("Error: Some unknown error occurred validating the certificate.\n")); + + return g_string_free(errors, FALSE); +} + +static gboolean +WebViewCb_load_failed_with_tls_errors(WebKitWebView *web_view, + gchar *failing_text, + GTlsCertificate *certificate, + GTlsCertificateFlags errors, + gpointer user_data) +{ + (void)web_view; + (void)certificate; + (void)errors; + struct Client *browser = (struct Client *)user_data; + gchar *error_details = detail_tls_certificate_flags(errors); + gint dialog_response; + SoupURI *failing_uri = soup_uri_new(failing_text); + + GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(browser->window->main_window), + GTK_DIALOG_MODAL & GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_NONE, + _("TLS Error for %s."), + failing_text); + gtk_dialog_add_buttons( + GTK_DIALOG(dialog), _("Temporarly Add Exception"), 1, _("Continue"), 0, NULL); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), 0); + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s\n", error_details); + + dialog_response = gtk_dialog_run(GTK_DIALOG(dialog)); + + if(dialog_response == 1) + { + webkit_web_context_allow_tls_certificate_for_host( + webkit_web_view_get_context(browser->webView), certificate, failing_uri->host); + webkit_web_view_reload(browser->webView); + } + + soup_uri_free(failing_uri); + g_free(error_details); + gtk_widget_destroy(dialog); + + return FALSE; /* propagate the event further */ +} + static void web_contextCb_download_started(WebKitWebContext *web_context, WebKitDownload *download, @@ -376,28 +423,22 @@ downloadCb_decide_destination(WebKitDownload *download, gint chooser_response; GtkWindow *parent_window = GTK_WINDOW(browser->window->main_window); - GtkWidget *file_dialog = gtk_file_chooser_dialog_new(NULL, - parent_window, - GTK_FILE_CHOOSER_ACTION_SAVE, - _("_Cancel"), - GTK_RESPONSE_CANCEL, - _("_Save"), - GTK_RESPONSE_ACCEPT, - NULL); + GtkFileChooserNative *file_dialog = + gtk_file_chooser_native_new(NULL, parent_window, GTK_FILE_CHOOSER_ACTION_SAVE, NULL, NULL); GtkFileChooser *file_chooser = GTK_FILE_CHOOSER(file_dialog); gtk_file_chooser_set_current_name(file_chooser, suggested_filename); gtk_file_chooser_set_do_overwrite_confirmation(file_chooser, TRUE); webkit_download_set_allow_overwrite(download, TRUE); - chooser_response = gtk_dialog_run(GTK_DIALOG(file_dialog)); + chooser_response = gtk_native_dialog_run(GTK_NATIVE_DIALOG(file_dialog)); if(chooser_response == GTK_RESPONSE_ACCEPT) webkit_download_set_destination(download, gtk_file_chooser_get_uri(file_chooser)); else webkit_download_cancel(download); - gtk_widget_destroy(file_dialog); + g_object_unref(file_dialog); return FALSE; /* Let it propagate */ } @@ -405,12 +446,10 @@ downloadCb_decide_destination(WebKitDownload *download, static gboolean locationCb_activate(GtkEntry *location, gpointer user_data) { - char *target_url; struct Client *browser = (struct Client *)user_data; - target_url = badwolf_ensure_uri_scheme((char *)gtk_entry_get_text(location), TRUE); - - if(target_url != NULL) webkit_web_view_load_uri(browser->webView, target_url); + webkit_web_view_load_uri(browser->webView, + badwolf_ensure_uri_scheme(gtk_entry_get_text(location), TRUE)); return TRUE; } @@ -479,7 +518,7 @@ SearchEntryCb_stop__search(GtkSearchEntry *search, gpointer user_data) } struct Client * -new_browser(struct Window *window, gchar *target_url, WebKitWebView *related_web_view) +new_browser(struct Window *window, const gchar *target_url, WebKitWebView *related_web_view) { struct Client *browser = malloc(sizeof(struct Client)); target_url = badwolf_ensure_uri_scheme(target_url, (related_web_view == NULL)); @@ -606,6 +645,10 @@ new_browser(struct Window *window, gchar *target_url, WebKitWebView *related_web g_signal_connect( browser->webView, "permission-request", G_CALLBACK(WebViewCb_permission_request), NULL); g_signal_connect(browser->webView, "decide-policy", G_CALLBACK(WebViewCb_decide_policy), NULL); + g_signal_connect(browser->webView, + "load-failed-with-tls-errors", + G_CALLBACK(WebViewCb_load_failed_with_tls_errors), + browser); /* signals for WebView's WebContext */ g_signal_connect(G_OBJECT(web_context), @@ -646,10 +689,7 @@ badwolf_new_tab(GtkNotebook *notebook, struct Client *browser) gtk_widget_show_all(browser->box); - if(gtk_notebook_insert_page(notebook, browser->box, NULL, (current_page + 1)) == -1) - { - return -1; - } + if(gtk_notebook_insert_page(notebook, browser->box, NULL, (current_page + 1)) == -1) return -1; gtk_notebook_set_tab_reorderable(notebook, browser->box, TRUE); gtk_notebook_set_tab_label(notebook, browser->box, badwolf_new_tab_box(title, browser)); @@ -704,9 +744,7 @@ badwolf_get_tab_position(GtkContainer *notebook, GtkWidget *child) int main(int argc, char *argv[]) { - // getting an abort if this one fails to alloc - struct Window *window = g_malloc(sizeof(struct Window)); - + struct Window *window = &(struct Window){NULL}; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, DATADIR "/locale"); bind_textdomain_codeset(PACKAGE, "UTF-8"); @@ -714,20 +752,28 @@ main(int argc, char *argv[]) gtk_init(&argc, &argv); - g_fprintf(stderr, _("Running Badwolf version: %s\n"), version); - g_fprintf(stderr, - _("Buildtime WebKit version: %d.%d.%d\n"), - WEBKIT_MAJOR_VERSION, - WEBKIT_MINOR_VERSION, - WEBKIT_MICRO_VERSION); - g_fprintf(stderr, - _("Runtime WebKit version: %d.%d.%d\n"), - webkit_get_major_version(), - webkit_get_minor_version(), - webkit_get_micro_version()); +#ifdef BADWOLF_PREFER_DARK_THEME + g_object_set(gtk_settings_get_default(), + "gtk-application-prefer-dark-theme", + BADWOLF_PREFER_DARK_THEME, + NULL); +#endif + + fprintf(stderr, _("Running Badwolf version: %s\n"), version); + fprintf(stderr, + _("Buildtime WebKit version: %d.%d.%d\n"), + WEBKIT_MAJOR_VERSION, + WEBKIT_MINOR_VERSION, + WEBKIT_MICRO_VERSION); + fprintf(stderr, + _("Runtime WebKit version: %d.%d.%d\n"), + webkit_get_major_version(), + webkit_get_minor_version(), + webkit_get_micro_version()); - web_extensions_directory = g_build_filename(g_get_user_data_dir(), "badwolf", "webkit-web-extension", NULL); - g_fprintf(stderr, _("webkit-web-extension directory set to: %s\n"), web_extensions_directory); + web_extensions_directory = + g_build_filename(g_get_user_data_dir(), "badwolf", "webkit-web-extension", NULL); + fprintf(stderr, _("webkit-web-extension directory set to: %s\n"), web_extensions_directory); window->main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); window->notebook = gtk_notebook_new(); @@ -763,5 +809,11 @@ main(int argc, char *argv[]) gtk_widget_show_all(window->main_window); gtk_main(); + +#if 0 + /* TRANSLATOR Ignore this entry. Done for forcing Unicode in xgettext. */ + _("ø"); +#endif + return 0; } |