Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 22 additions & 20 deletions native/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ BIN_DIR="$HOME/.local/bin"
TARGET_HOST_PATH="$BIN_DIR/webauthnlinux_host.py"
MANIFEST_PATH="$SCRIPT_DIR/webauthnlinux_host.json"

# Default values
FIREFOX_ID="webauthnlinux@samveen.github.io"
CHROME_ID=""
DO_FIREFOX=false
DO_CHROME=false
DO_FLATPAK=false

usage() {
echo "Usage: $0 [options]"
echo ""
echo "Options:"
echo " --firefox Install for Firefox"
echo " --firefox Install for Firefox (XDG + legacy + Flatpak)"
echo " --chrome <ID> Install for Chrome/Chromium with the specified Extension ID"
echo " --help Show this help message"
echo ""
Expand All @@ -28,21 +28,19 @@ usage() {
exit 1
}

# Parse arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--firefox) DO_FIREFOX=true ;;
--firefox) DO_FIREFOX=true;;
--chrome) CHROME_ID="$2"; DO_CHROME=true; shift ;;
--help) usage ;;
*) echo "Unknown parameter: $1"; usage ;;
esac
shift
done

# Interactively ask if no flags provided
if [ "$DO_FIREFOX" = false ] && [ "$DO_CHROME" = false ]; then
echo "No browser targets specified."
read -p "Install for Firefox? (y/n): " resp
read -p "Install for Firefox (native + Flatpak)? (y/n): " resp
if [[ "$resp" =~ ^[Yy]$ ]]; then DO_FIREFOX=true; fi

read -p "Install for Chrome/Chromium? (y/n): " resp
Expand All @@ -52,15 +50,15 @@ if [ "$DO_FIREFOX" = false ] && [ "$DO_CHROME" = false ]; then
fi
fi

[[ "$DO_FIREFOX" == true ]] && [[ "$DO_CHROME" == true ]] && { echo "Only one browser install can be done at a time"; exit 2; }
[[ "$DO_FIREFOX" = false ]] && [[ "$DO_CHROME" = false ]] && { echo "No browsers selected. Exiting."; exit 0; }
[ "$DO_FIREFOX" = false ] && [ "$DO_CHROME" = false ] && {
echo "No browsers selected. Exiting."
exit 0
}

echo "Installing Native Messaging Host for WebAuthnLinux..."

# Install host script to ~/.local/bin
install -v -D -m 755 "$SOURCE_HOST_PATH" "$TARGET_HOST_PATH"

# Create Manifest
(
cat <<EOF
{
Expand All @@ -85,25 +83,29 @@ cat <<EOF
}
EOF
) > "$MANIFEST_PATH"

# Directories to install to
DIRS=()

if [ "$DO_FIREFOX" = true ]; then

DIRS+=("$HOME/.mozilla/native-messaging-hosts")
XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
DIRS+=("$XDG_CONFIG_HOME/mozilla/native-messaging-hosts")

DIRS+=("$HOME/.var/app/org.mozilla.firefox/.mozilla/native-messaging-hosts")
fi

if [ "$DO_CHROME" = true ]; then
DIRS+=("$HOME/.config/google-chrome/NativeMessagingHosts")
DIRS+=("$HOME/.config/chromium/NativeMessagingHosts")
fi

# Following open bug https://bugzilla.mozilla.org/show_bug.cgi?id=2005167 firefox does not check the new XDG paths it uses for new installations thus i opted for creation in the previous ~/.mozilla folder instead since that still works.
# I did it using the below
for HOST_DIR in "${DIRS[@]}"; do
if [ -d "$(dirname "$HOST_DIR")" ]; then
mkdir -p "$HOST_DIR"
mv -f "$MANIFEST_PATH" "$HOST_DIR/$HOST_NAME.json"
echo "Registered manifest at: $HOST_DIR/$HOST_NAME.json"
else
echo "Skipping non-existent browser config directory: $(dirname "$HOST_DIR")"
fi
mkdir -p "$HOST_DIR"
cp "$MANIFEST_PATH" "$HOST_DIR/$HOST_NAME.json"
echo "Registered manifest at: $HOST_DIR/$HOST_NAME.json"
done

rm -f "$MANIFEST_PATH"

echo "Done."
7 changes: 2 additions & 5 deletions native/webauthnlinux_host.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,9 @@ def verify_fingerprint():
# NOTE: fprintd-verify usually writes to stdout/stderr.
# Since we are communicating over stdin/stdout with the browser,
# we MUST capture or redirect subprocess IO to avoid corrupting the stream.
result = subprocess.run(
['fprintd-verify'],
capture_output=True,
text=True
)

# Small fix here since this only asked for one finger, the initially enrolled one instead on any since the user might have multiple enrolled ones
result = subprocess.run(['fprintd-verify', '-f', 'any'], capture_output=True, text=True)
# Check for success string usually present in fprintd output
if result.returncode == 0 and ("verify-match" in result.stdout or "verify-match" in result.stderr):
return True, "Verified"
Expand Down