From 8005b3d41dcf9fde22dadb9f3e4b24a0ab34babf Mon Sep 17 00:00:00 2001 From: Tero Tervala Date: Wed, 25 Sep 2024 10:40:45 +0300 Subject: [PATCH] Open trusted browser link in normal browser Add chromium extension to trusted browser that allows opening links in normal browser. Signed-off-by: Tero Tervala --- modules/givc/flake-module.nix | 4 + .../microvm/virtualization/microvm/appvm.nix | 1 + modules/reference/appvms/business.nix | 24 ++++- overlays/custom-packages/default.nix | 1 + .../open-normal-extension/default.nix | 3 + packages/open-normal-extension/default.nix | 31 +++++++ .../fi.ssrc.open_normal.json | 11 +++ packages/open-normal-extension/manifest.json | 12 +++ packages/open-normal-extension/open_normal.js | 25 ++++++ packages/open-normal-extension/open_normal.sh | 87 +++++++++++++++++++ 10 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 overlays/custom-packages/open-normal-extension/default.nix create mode 100644 packages/open-normal-extension/default.nix create mode 100644 packages/open-normal-extension/fi.ssrc.open_normal.json create mode 100644 packages/open-normal-extension/manifest.json create mode 100644 packages/open-normal-extension/open_normal.js create mode 100755 packages/open-normal-extension/open_normal.sh diff --git a/modules/givc/flake-module.nix b/modules/givc/flake-module.nix index 33bce39b2d..45969f8b5a 100644 --- a/modules/givc/flake-module.nix +++ b/modules/givc/flake-module.nix @@ -36,6 +36,10 @@ inputs.givc.nixosModules.appvm ./common.nix ./appvm.nix + { + # Include givc overlay to import app + nixpkgs.overlays = [ inputs.givc.overlays.default ]; + } ]; }; } diff --git a/modules/microvm/virtualization/microvm/appvm.nix b/modules/microvm/virtualization/microvm/appvm.nix index a4f9237ff8..c1a15b8a46 100644 --- a/modules/microvm/virtualization/microvm/appvm.nix +++ b/modules/microvm/virtualization/microvm/appvm.nix @@ -115,6 +115,7 @@ let runWaypipe pkgs.tpm2-tools pkgs.opensc + pkgs.givc-cli ]; security.tpm2 = { diff --git a/modules/reference/appvms/business.nix b/modules/reference/appvms/business.nix index 9b55d52df6..efbdef6d45 100644 --- a/modules/reference/appvms/business.nix +++ b/modules/reference/appvms/business.nix @@ -38,6 +38,7 @@ in pkgs.globalprotect-openconnect pkgs.openconnect pkgs.nftables + pkgs.open-normal-extension ]; # TODO create a repository of mac addresses to avoid conflicts macAddress = "02:00:00:03:10:01"; @@ -62,7 +63,7 @@ in applications = [ { name = "chromium"; - command = "${config.ghaf.givc.appPrefix}/run-waypipe ${config.ghaf.givc.appPrefix}/chromium --enable-features=UseOzonePlatform --ozone-platform=wayland ${config.ghaf.givc.idsExtraArgs}"; + command = "${config.ghaf.givc.appPrefix}/run-waypipe ${config.ghaf.givc.appPrefix}/chromium --enable-features=UseOzonePlatform --ozone-platform=wayland ${config.ghaf.givc.idsExtraArgs} --load-extension=${pkgs.open-normal-extension}"; args = [ "url" ]; } { @@ -86,6 +87,27 @@ in ghaf.reference.programs.chromium.enable = true; + environment.etc."chromium/native-messaging-hosts/fi.ssrc.open_normal.json" = { + source = "${pkgs.open-normal-extension}/fi.ssrc.open_normal.json"; + }; + environment.etc."open-normal-extension.cfg" = { + text = let + cliArgs = builtins.replaceStrings [ "\n" ] [ " " ] '' + --name ${config.ghaf.givc.adminConfig.name} + --addr ${config.ghaf.givc.adminConfig.addr} + --port ${config.ghaf.givc.adminConfig.port} + ${lib.optionalString config.ghaf.givc.enableTls "--cacert /run/givc/ca-cert.pem"} + ${lib.optionalString config.ghaf.givc.enableTls "--cert /run/givc/gui-vm-cert.pem"} + ${lib.optionalString config.ghaf.givc.enableTls "--key /run/givc/gui-vm-key.pem"} + ${lib.optionalString (!config.ghaf.givc.enableTls) "--notls"} + ''; + in + '' + GIVC_PATH="/run/current-system/sw" + GIVC_OPTS="${cliArgs}" + ''; + }; + # Set default PDF XDG handler xdg.mime.defaultApplications."application/pdf" = "ghaf-pdf.desktop"; diff --git a/overlays/custom-packages/default.nix b/overlays/custom-packages/default.nix index c2d90be845..2e5e635dc8 100644 --- a/overlays/custom-packages/default.nix +++ b/overlays/custom-packages/default.nix @@ -18,6 +18,7 @@ tpm2-pkcs11 = import ./tpm2-pkcs11 { inherit prev; }; waybar = import ./waybar { inherit prev; }; mitmweb-ui = final.callPackage ../../packages/mitmweb-ui { }; + open-normal-extension = final.callPackage ../../packages/open-normal-extension { }; gtklock = import ./gtklock { inherit prev; }; hardware-scan = final.callPackage ../../packages/hardware-scan { }; pulseaudio-ghaf = import ./pulseaudio { inherit prev; }; diff --git a/overlays/custom-packages/open-normal-extension/default.nix b/overlays/custom-packages/open-normal-extension/default.nix new file mode 100644 index 0000000000..6c711ba5ec --- /dev/null +++ b/overlays/custom-packages/open-normal-extension/default.nix @@ -0,0 +1,3 @@ +# Copyright 2022-2023 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +(final: _prev: { open-normal-extension = final.callPackage ../../../packages/open-normal-extension { }; }) diff --git a/packages/open-normal-extension/default.nix b/packages/open-normal-extension/default.nix new file mode 100644 index 0000000000..c0e131bd84 --- /dev/null +++ b/packages/open-normal-extension/default.nix @@ -0,0 +1,31 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ + stdenvNoCC, + pkgs, + lib, + config, + ... +}: +stdenvNoCC.mkDerivation { + name = "open-normal-extension"; + + src = ./.; + + buildInputs = [pkgs.gettext]; + + postInstall = '' + mkdir -p "$out" + cp -v ./manifest.json ./open_normal.js ./open_normal.sh "$out" + chmod a+x "$out/open_normal.sh" + ${pkgs.gettext}/bin/envsubst < "./fi.ssrc.open_normal.json" > "$out/fi.ssrc.open_normal.json" + ''; + + meta = with lib; { + description = "Browser extension for Chromium to launch trusted browser"; + platforms = [ + "x86_64-linux" + "aarch64-linux" + ]; + }; +} diff --git a/packages/open-normal-extension/fi.ssrc.open_normal.json b/packages/open-normal-extension/fi.ssrc.open_normal.json new file mode 100644 index 0000000000..e8b66cd467 --- /dev/null +++ b/packages/open-normal-extension/fi.ssrc.open_normal.json @@ -0,0 +1,11 @@ +{ + "__comment1__": "SPDX-FileCopyrightText: 2022-2024 TII (SSRC) and the Ghaf contributors", + "__comment2__": "SPDX-License-Identifier: Apache-2.0", + "name": "fi.ssrc.open_normal", + "description": "Open link in normal browser", + "path": "${out}/open_normal.sh", + "type": "stdio", + "allowed_origins": [ + "chrome-extension://ehlgfonodkljjbpedhnphehcflbohngk/" + ] +} diff --git a/packages/open-normal-extension/manifest.json b/packages/open-normal-extension/manifest.json new file mode 100644 index 0000000000..e1ea2f94b5 --- /dev/null +++ b/packages/open-normal-extension/manifest.json @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2022-2024 TII (SSRC) and the Ghaf contributors +// SPDX-License-Identifier: Apache-2.0 +{ + "manifest_version": 3, + "name": "Open in normal browser", + "version": "1.0", + "permissions": ["nativeMessaging", "contextMenus"], + "background": { + "service_worker": "open_normal.js" + }, + "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwDuuaHrpJGYZyXylG9Ag+mA4MbZPUZWhteMR9VpsHmblziD+Q02QA1z67H7FbnmsAIjY/yI+m0Q7lC4iFyksLyvJKlM8pMtBhMQxOwr9x+f+bUak2BmmQO4MFX/O2+k5viGF7kTzfp2KNBzpzUYMr9BrTuxyZ76z7abPohobYAA6spDHZW5DXOsBoXZ4+zg7G5R8Rg/MV+U9mobmyPsa9RGgpLX4KB8ysgJu4wpPGOyXdxf+Pp7h7NhP2Hk9PBl05DHEHTzoJMz0bGxGmAYBxjS95PfI4hC0Dr0YfUmIwY6IOTIvpY4qnqGHr6Qc4aeAwZDncFKj0xVx5nHsNze9WwIDAQAB" +} diff --git a/packages/open-normal-extension/open_normal.js b/packages/open-normal-extension/open_normal.js new file mode 100644 index 0000000000..3bb2c1ee2a --- /dev/null +++ b/packages/open-normal-extension/open_normal.js @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2022-2024 TII (SSRC) and the Ghaf contributors +// SPDX-License-Identifier: Apache-2.0 + +chrome.contextMenus.create({ + id: "openNormal", + title: "Open in normal browser", + contexts: ["link"] +}); + +chrome.contextMenus.onClicked.addListener((info, tab) => { + if (info.menuItemId === "openNormal") { + sendNativeMessage(info.linkUrl); + } +}); + +function sendNativeMessage(linkUrl) { + chrome.runtime.sendNativeMessage('fi.ssrc.open_normal', { "URL": linkUrl }, + (response) => { + if (chrome.runtime.lastError) { + console.error(chrome.runtime.lastError); + } else { + console.log("open_normal:", response); + } + }); +} diff --git a/packages/open-normal-extension/open_normal.sh b/packages/open-normal-extension/open_normal.sh new file mode 100755 index 0000000000..7663edf054 --- /dev/null +++ b/packages/open-normal-extension/open_normal.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 + +CFGF="/etc/open-normal-extension.cfg" + +function Ord { + printf "%d" "\"$1" +} + +function Chr { + printf "%b" "$(printf "\\\\x%02x" "$1")" +} + +function Msg { + local len b1 b2 b3 b4 + + len="${#1}" + b1="$(( len & 255 ))" + b2="$(( (len >> 8) & 255 ))" + b3="$(( (len >> 16) & 255 ))" + b4="$(( (len >> 24) & 255 ))" + Chr "$b1" + Chr "$b2" + Chr "$b3" + Chr "$b4" + printf "%s" "$1" +} + +LANG=C IFS= read -r -d '' -n 1 B1 +LANG=C IFS= read -r -d '' -n 1 B2 +LANG=C IFS= read -r -d '' -n 1 B3 +LANG=C IFS= read -r -d '' -n 1 B4 + +if [ -z "$B1" ]; then + B1=0 +else + B1="$(Ord "$B1")" +fi +if [ -z "$B2" ]; then + B2=0 +else + B2="$(Ord "$B2")" +fi +if [ -z "$B3" ]; then + B3=0 +else + B3="$(Ord "$B3")" +fi +if [ -z "$B4" ]; then + B4=0 +else + B4="$(Ord "$B4")" +fi + +LEN="$((B1+(B2*256)+(B3*65536)+(B4*16777216)))" + +if [ "$LEN" -lt 0 ] || [ "$LEN" -gt 4096 ]; then + Msg "{\"status\":\"Failed to read parameters from API\"}" + exit 1 +fi + +LANG=C IFS= read -r -d '' -n "$LEN" JSON +PFX="{\"URL\":\"" +URL="${JSON##"$PFX"}" +SFX="\"}" +URL="${URL%%"$SFX"}" + +if [ -r "$CFGF" ]; then + # Do not complain about not being able to follow non-constant source + # shellcheck disable=SC1090 + . "$CFGF" + if [ -z "$GIVC_PATH" ] || [ -z "$GIVC_OPTS" ] || [ ! -x "${GIVC_PATH}/bin/givc-cli" ]; then + Msg "{\"status\":\"Invalid config in ${CFGF}\"}" + exit 1 + else + # Do not complain about double quotes, $GIVC_OPTS is purposefully unquoted here + # shellcheck disable=SC2086 + "${GIVC_PATH}/bin/givc-cli" $GIVC_OPTS start chromium -- "${URL}" > /dev/null 2>&1 + RES=$? + Msg "{\"status\":\"${RES}\"}" + exit "$RES" + fi +else + Msg "{\"status\":\"Failed to read ${CFGF}\"}" + exit 1 +fi