Summary Files Commits Branches @commit @diff @stats
path: root / badwolf.c
diff options
context:
space:
mode:
1 files changed, 130 insertions, 78 deletions
-rw-r--r--badwolf.c208
diff --git a/badwolf.c b/badwolf.c
index 6c6b0c9..cb26dcf 100644
--- a/badwolf.c
+++ b/badwolf.c
@@ -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;
}