#!/bin/bash # Wrapper for yubisigner-cli that uses pinentry/zenity for PIN prompt # This allows PIN entry to work from non-interactive contexts like NeoMutt set -euo pipefail # Release YubiKey from gpg-agent first gpgconf --kill gpg-agent 2>/dev/null || true sleep 0.5 # Try different PIN entry methods in order of preference get_pin() { local pin="" # Method 1: Try zenity (GUI, works best from NeoMutt) if command -v zenity >/dev/null 2>&1; then pin=$(zenity --password --title="YubiKey PIN" --text="Enter YubiKey PIN:" 2>/dev/null || true) if [ -n "$pin" ]; then echo "$pin" return 0 fi fi # Method 2: Try pinentry-qt (GUI) if command -v pinentry-qt >/dev/null 2>&1; then pin=$(echo -e "SETDESC Enter YubiKey PIN\nSETPROMPT PIN:\nGETPIN\n" | pinentry-qt 2>/dev/null | grep "^D " | cut -d' ' -f2- || true) if [ -n "$pin" ]; then echo "$pin" return 0 fi fi # Method 3: Try pinentry-curses (TUI, works in terminal) if command -v pinentry-curses >/dev/null 2>&1 && [ -t 0 ]; then pin=$(echo -e "SETDESC Enter YubiKey PIN\nSETPROMPT PIN:\nGETPIN\n" | pinentry-curses 2>/dev/null | grep "^D " | cut -d' ' -f2- || true) if [ -n "$pin" ]; then echo "$pin" return 0 fi fi # Method 4: Fallback to /dev/tty direct read if [ -e /dev/tty ]; then echo "Enter YubiKey PIN: " >/dev/tty read -s pin /dev/tty if [ -n "$pin" ]; then echo "$pin" return 0 fi fi return 1 } # Get PIN PIN=$(get_pin) if [ -z "$PIN" ]; then echo "ERROR: Failed to get PIN" >&2 exit 1 fi # Call yubisigner-cli with PIN exec "$HOME/bin/yubisigner-cli/yubisigner-cli" --pin "$PIN" "$@"