ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/src/utils/browser.c b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/src/utils/browser.c
new file mode 100644
index 0000000..b5d5ba7
--- /dev/null
+++ b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/src/utils/browser.c
@@ -0,0 +1,402 @@
+/*
+ * Hotspot 2.0 client - Web browser using WebKit
+ * Copyright (c) 2013, Qualcomm Atheros, Inc.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+#ifdef USE_WEBKIT2
+#include <webkit2/webkit2.h>
+#else /* USE_WEBKIT2 */
+#include <webkit/webkit.h>
+#endif /* USE_WEBKIT2 */
+
+#include "common.h"
+#include "browser.h"
+
+
+struct browser_context {
+ GtkWidget *win;
+ WebKitWebView *view;
+ int success;
+ int progress;
+ char *hover_link;
+ char *title;
+ int gtk_main_started;
+ int quit_gtk_main;
+};
+
+static void win_cb_destroy(GtkWidget *win, struct browser_context *ctx)
+{
+ wpa_printf(MSG_DEBUG, "BROWSER:%s", __func__);
+ if (ctx->gtk_main_started)
+ gtk_main_quit();
+}
+
+
+static void browser_update_title(struct browser_context *ctx)
+{
+ char buf[100];
+
+ if (ctx->hover_link) {
+ gtk_window_set_title(GTK_WINDOW(ctx->win), ctx->hover_link);
+ return;
+ }
+
+ if (ctx->progress == 100) {
+ gtk_window_set_title(GTK_WINDOW(ctx->win),
+ ctx->title ? ctx->title :
+ "Hotspot 2.0 client");
+ return;
+ }
+
+ snprintf(buf, sizeof(buf), "[%d%%] %s", ctx->progress,
+ ctx->title ? ctx->title : "Hotspot 2.0 client");
+ gtk_window_set_title(GTK_WINDOW(ctx->win), buf);
+}
+
+
+static void process_request_starting_uri(struct browser_context *ctx,
+ const char *uri)
+{
+ int quit = 0;
+
+ if (g_str_has_prefix(uri, "osu://")) {
+ ctx->success = atoi(uri + 6);
+ quit = 1;
+ } else if (g_str_has_prefix(uri, "http://localhost:12345")) {
+ /*
+ * This is used as a special trigger to indicate that the
+ * user exchange has been completed.
+ */
+ ctx->success = 1;
+ quit = 1;
+ }
+
+ if (quit) {
+ if (ctx->gtk_main_started) {
+ gtk_main_quit();
+ ctx->gtk_main_started = 0;
+ } else {
+ ctx->quit_gtk_main = 1;
+ }
+ }
+}
+
+
+#ifdef USE_WEBKIT2
+
+static void view_cb_notify_estimated_load_progress(WebKitWebView *view,
+ GParamSpec *pspec,
+ struct browser_context *ctx)
+{
+ ctx->progress = 100 * webkit_web_view_get_estimated_load_progress(view);
+ wpa_printf(MSG_DEBUG, "BROWSER:%s progress=%d", __func__,
+ ctx->progress);
+ browser_update_title(ctx);
+}
+
+
+static void view_cb_resource_load_starting(WebKitWebView *view,
+ WebKitWebResource *res,
+ WebKitURIRequest *req,
+ struct browser_context *ctx)
+{
+ const gchar *uri = webkit_uri_request_get_uri(req);
+
+ wpa_printf(MSG_DEBUG, "BROWSER:%s uri=%s", __func__, uri);
+ process_request_starting_uri(ctx, uri);
+}
+
+
+static gboolean view_cb_decide_policy(WebKitWebView *view,
+ WebKitPolicyDecision *policy,
+ WebKitPolicyDecisionType type,
+ struct browser_context *ctx)
+{
+ wpa_printf(MSG_DEBUG, "BROWSER:%s type=%d", __func__, type);
+ switch (type) {
+ case WEBKIT_POLICY_DECISION_TYPE_RESPONSE: {
+ /* This function makes webkit send a download signal for all
+ * unknown mime types. */
+ WebKitResponsePolicyDecision *response;
+
+ response = WEBKIT_RESPONSE_POLICY_DECISION(policy);
+ if (!webkit_response_policy_decision_is_mime_type_supported(
+ response)) {
+ webkit_policy_decision_download(policy);
+ return TRUE;
+ }
+ break;
+ }
+ case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION: {
+ WebKitNavigationPolicyDecision *d;
+ WebKitNavigationAction *a;
+ WebKitURIRequest *req;
+ const gchar *uri;
+
+ d = WEBKIT_NAVIGATION_POLICY_DECISION(policy);
+ a = webkit_navigation_policy_decision_get_navigation_action(d);
+ req = webkit_navigation_action_get_request(a);
+ uri = webkit_uri_request_get_uri(req);
+ wpa_printf(MSG_DEBUG, "BROWSER:%s navigation action: uri=%s",
+ __func__, uri);
+ process_request_starting_uri(ctx, uri);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+
+static void view_cb_mouse_target_changed(WebKitWebView *view,
+ WebKitHitTestResult *h,
+ guint modifiers,
+ struct browser_context *ctx)
+{
+ WebKitHitTestResultContext hc = webkit_hit_test_result_get_context(h);
+ const char *uri = NULL;
+
+ if (hc & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK)
+ uri = webkit_hit_test_result_get_link_uri(h);
+ else if (hc & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE)
+ uri = webkit_hit_test_result_get_image_uri(h);
+ else if (hc & WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA)
+ uri = webkit_hit_test_result_get_media_uri(h);
+
+ wpa_printf(MSG_DEBUG, "BROWSER:%s uri=%s", __func__, uri ? uri : "N/A");
+ os_free(ctx->hover_link);
+ if (uri)
+ ctx->hover_link = os_strdup(uri);
+ else
+ ctx->hover_link = NULL;
+
+ browser_update_title(ctx);
+}
+
+
+static void view_cb_notify_title(WebKitWebView *view, GParamSpec *ps,
+ struct browser_context *ctx)
+{
+ const char *title;
+
+ title = webkit_web_view_get_title(ctx->view);
+ wpa_printf(MSG_DEBUG, "BROWSER:%s title=%s", __func__, title);
+ os_free(ctx->title);
+ ctx->title = os_strdup(title);
+ browser_update_title(ctx);
+}
+
+#else /* USE_WEBKIT2 */
+
+static void view_cb_notify_progress(WebKitWebView *view, GParamSpec *pspec,
+ struct browser_context *ctx)
+{
+ ctx->progress = 100 * webkit_web_view_get_progress(view);
+ wpa_printf(MSG_DEBUG, "BROWSER:%s progress=%d", __func__,
+ ctx->progress);
+ browser_update_title(ctx);
+}
+
+
+static void view_cb_notify_load_status(WebKitWebView *view, GParamSpec *pspec,
+ struct browser_context *ctx)
+{
+ int status = webkit_web_view_get_load_status(view);
+ wpa_printf(MSG_DEBUG, "BROWSER:%s load-status=%d uri=%s",
+ __func__, status, webkit_web_view_get_uri(view));
+ if (ctx->quit_gtk_main) {
+ gtk_main_quit();
+ ctx->gtk_main_started = 0;
+ }
+}
+
+
+static void view_cb_resource_request_starting(WebKitWebView *view,
+ WebKitWebFrame *frame,
+ WebKitWebResource *res,
+ WebKitNetworkRequest *req,
+ WebKitNetworkResponse *resp,
+ struct browser_context *ctx)
+{
+ const gchar *uri = webkit_network_request_get_uri(req);
+
+ wpa_printf(MSG_DEBUG, "BROWSER:%s uri=%s", __func__, uri);
+ if (g_str_has_suffix(uri, "/favicon.ico"))
+ webkit_network_request_set_uri(req, "about:blank");
+
+ process_request_starting_uri(ctx, uri);
+}
+
+
+static gboolean view_cb_mime_type_policy_decision(
+ WebKitWebView *view, WebKitWebFrame *frame, WebKitNetworkRequest *req,
+ gchar *mime, WebKitWebPolicyDecision *policy,
+ struct browser_context *ctx)
+{
+ wpa_printf(MSG_DEBUG, "BROWSER:%s mime=%s", __func__, mime);
+
+ if (!webkit_web_view_can_show_mime_type(view, mime)) {
+ webkit_web_policy_decision_download(policy);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static gboolean view_cb_download_requested(WebKitWebView *view,
+ WebKitDownload *dl,
+ struct browser_context *ctx)
+{
+ const gchar *uri;
+ uri = webkit_download_get_uri(dl);
+ wpa_printf(MSG_DEBUG, "BROWSER:%s uri=%s", __func__, uri);
+ return FALSE;
+}
+
+
+static void view_cb_hovering_over_link(WebKitWebView *view, gchar *title,
+ gchar *uri, struct browser_context *ctx)
+{
+ wpa_printf(MSG_DEBUG, "BROWSER:%s title=%s uri=%s", __func__, title,
+ uri);
+ os_free(ctx->hover_link);
+ if (uri)
+ ctx->hover_link = os_strdup(uri);
+ else
+ ctx->hover_link = NULL;
+
+ browser_update_title(ctx);
+}
+
+
+static void view_cb_title_changed(WebKitWebView *view, WebKitWebFrame *frame,
+ const char *title,
+ struct browser_context *ctx)
+{
+ wpa_printf(MSG_DEBUG, "BROWSER:%s title=%s", __func__, title);
+ os_free(ctx->title);
+ ctx->title = os_strdup(title);
+ browser_update_title(ctx);
+}
+
+#endif /* USE_WEBKIT2 */
+
+
+int hs20_web_browser(const char *url, int ignore_tls)
+{
+ GtkWidget *scroll;
+ WebKitWebView *view;
+#ifdef USE_WEBKIT2
+ WebKitSettings *settings;
+#else /* USE_WEBKIT2 */
+ WebKitWebSettings *settings;
+ SoupSession *s;
+#endif /* USE_WEBKIT2 */
+ struct browser_context ctx;
+
+ memset(&ctx, 0, sizeof(ctx));
+ if (!gtk_init_check(NULL, NULL))
+ return -1;
+
+#ifndef USE_WEBKIT2
+ s = webkit_get_default_session();
+ g_object_set(G_OBJECT(s), "ssl-ca-file",
+ "/etc/ssl/certs/ca-certificates.crt", NULL);
+ if (ignore_tls)
+ g_object_set(G_OBJECT(s), "ssl-strict", FALSE, NULL);
+#endif /* USE_WEBKIT2 */
+
+ ctx.win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_role(GTK_WINDOW(ctx.win), "Hotspot 2.0 client");
+ gtk_window_set_default_size(GTK_WINDOW(ctx.win), 800, 600);
+
+ scroll = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
+ GTK_POLICY_NEVER, GTK_POLICY_NEVER);
+
+ g_signal_connect(G_OBJECT(ctx.win), "destroy",
+ G_CALLBACK(win_cb_destroy), &ctx);
+
+ view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ ctx.view = view;
+#ifdef USE_WEBKIT2
+ g_signal_connect(G_OBJECT(view), "notify::estimated-load-progress",
+ G_CALLBACK(view_cb_notify_estimated_load_progress),
+ &ctx);
+ g_signal_connect(G_OBJECT(view), "resource-load-started",
+ G_CALLBACK(view_cb_resource_load_starting), &ctx);
+ g_signal_connect(G_OBJECT(view), "decide-policy",
+ G_CALLBACK(view_cb_decide_policy), &ctx);
+ g_signal_connect(G_OBJECT(view), "mouse-target-changed",
+ G_CALLBACK(view_cb_mouse_target_changed), &ctx);
+ g_signal_connect(G_OBJECT(view), "notify::title",
+ G_CALLBACK(view_cb_notify_title), &ctx);
+#else /* USE_WEBKIT2 */
+ g_signal_connect(G_OBJECT(view), "notify::load-status",
+ G_CALLBACK(view_cb_notify_load_status), &ctx);
+ g_signal_connect(G_OBJECT(view), "notify::progress",
+ G_CALLBACK(view_cb_notify_progress), &ctx);
+ g_signal_connect(G_OBJECT(view), "resource-request-starting",
+ G_CALLBACK(view_cb_resource_request_starting), &ctx);
+ g_signal_connect(G_OBJECT(view), "mime-type-policy-decision-requested",
+ G_CALLBACK(view_cb_mime_type_policy_decision), &ctx);
+ g_signal_connect(G_OBJECT(view), "download-requested",
+ G_CALLBACK(view_cb_download_requested), &ctx);
+ g_signal_connect(G_OBJECT(view), "hovering-over-link",
+ G_CALLBACK(view_cb_hovering_over_link), &ctx);
+ g_signal_connect(G_OBJECT(view), "title-changed",
+ G_CALLBACK(view_cb_title_changed), &ctx);
+#endif /* USE_WEBKIT2 */
+
+ gtk_container_add(GTK_CONTAINER(scroll), GTK_WIDGET(view));
+ gtk_container_add(GTK_CONTAINER(ctx.win), GTK_WIDGET(scroll));
+
+ gtk_widget_grab_focus(GTK_WIDGET(view));
+ gtk_widget_show_all(ctx.win);
+
+ settings = webkit_web_view_get_settings(view);
+ g_object_set(G_OBJECT(settings), "user-agent",
+ "Mozilla/5.0 (X11; U; Unix; en-US) "
+ "AppleWebKit/537.15 (KHTML, like Gecko) "
+ "hs20-client/1.0", NULL);
+ g_object_set(G_OBJECT(settings), "auto-load-images", TRUE, NULL);
+
+#ifdef USE_WEBKIT2
+ if (ignore_tls) {
+#if WEBKIT_CHECK_VERSION(2, 32, 0)
+ WebKitWebContext *wkctx;
+ WebKitWebsiteDataManager *wkmgr;
+
+ wkctx = webkit_web_context_get_default();
+ wkmgr = webkit_web_context_get_website_data_manager(wkctx);
+ webkit_website_data_manager_set_tls_errors_policy(
+ wkmgr, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
+#else
+ WebKitWebContext *wkctx;
+
+ wkctx = webkit_web_context_get_default();
+ webkit_web_context_set_tls_errors_policy(
+ wkctx, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
+#endif
+ }
+#endif /* USE_WEBKIT2 */
+
+ webkit_web_view_load_uri(view, url);
+
+ ctx.gtk_main_started = 1;
+ gtk_main();
+ gtk_widget_destroy(ctx.win);
+ while (gtk_events_pending())
+ gtk_main_iteration();
+
+ free(ctx.hover_link);
+ free(ctx.title);
+ return ctx.success;
+}