This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

superconfig / tools / pinentry-rofi / pinentry-rofi.sh
3.5 kB 151 lines
1#!/usr/bin/env bash 2# pinentry-rofi: A rofi-based pinentry for SSH TPM authentication 3# Reads SSH_CLIENT_PID to extract SSH command context 4# Caches PIN in kernel keyring for 5 minutes (sliding window) 5set -efu 6 7CACHE_KEY="pinentry-rofi-pin" 8CACHE_TIMEOUT=300 # 5 minutes 9 10# Get cached PIN from kernel keyring 11get_cached_pin() { 12 local key_id 13 key_id=$(keyctl search @s user "$CACHE_KEY" 2>/dev/null) || return 1 14 keyctl pipe "$key_id" 2>/dev/null 15} 16 17# Store PIN in kernel keyring with timeout 18cache_pin() { 19 local pin="$1" 20 # Remove old key if exists 21 keyctl purge user "$CACHE_KEY" >/dev/null 2>&1 || true 22 # Add new key with timeout (using padd to avoid PIN in /proc/*/cmdline) 23 local key_id 24 key_id=$(printf '%s' "$pin" | keyctl padd user "$CACHE_KEY" @s) || return 0 25 keyctl timeout "$key_id" "$CACHE_TIMEOUT" || true 26} 27 28# Extend cache timeout (sliding window) 29extend_cache() { 30 local key_id 31 key_id=$(keyctl search @s user "$CACHE_KEY" 2>/dev/null) || return 0 32 keyctl timeout "$key_id" "$CACHE_TIMEOUT" || true 33} 34 35# Clear cached PIN 36clear_cache() { 37 keyctl purge user "$CACHE_KEY" >/dev/null 2>&1 || true 38} 39 40# Extract SSH args from client PID 41# Groups flags with their arguments on the same line 42get_ssh_args() { 43 local pid="${SSH_CLIENT_PID:-}" 44 [[ -z "$pid" ]] && return 1 45 [[ ! -r "/proc/$pid/cmdline" ]] && return 1 46 47 # Read command line (null-separated) into array 48 local -a args=() 49 while IFS= read -r -d '' arg; do 50 args+=("$arg") 51 done < "/proc/$pid/cmdline" 52 53 # Check first arg is ssh 54 [[ "${args[0]}" == "ssh" || "${args[0]}" == */ssh ]] || return 1 55 56 # Output args, keeping flags and their values on the same line 57 local i=1 58 local line="" 59 while [[ $i -lt ${#args[@]} ]]; do 60 local arg="${args[$i]}" 61 if [[ "$arg" == -* ]]; then 62 # Print previous line if exists 63 [[ -n "$line" ]] && echo "$line" 64 line="$arg" 65 else 66 # Append to current line 67 if [[ -n "$line" ]]; then 68 line="$line $arg" 69 else 70 line="$arg" 71 fi 72 fi 73 ((i++)) 74 done 75 # Print last line 76 [[ -n "$line" ]] && echo "$line" 77} 78 79# Escape string for pango markup 80escape_pango() { 81 sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g' 82} 83 84# Get SSH args 85ssh_args="" 86if ssh_args=$(get_ssh_args 2>/dev/null | escape_pango); then 87 : # got args 88fi 89 90# Build the rofi message 91mesg_args=() 92if [[ -n "$ssh_args" ]]; then 93 mesg="<b>SSH:</b> 94$ssh_args" 95 mesg_args=(-mesg "$mesg") 96fi 97 98# Determine theme 99theme_file="/var/theme/config/rofi-theme" 100theme_args=() 101if [[ -r "$theme_file" ]]; then 102 theme=$(cat "$theme_file") 103 theme_args=(-theme "$theme") 104fi 105 106# Check for cached PIN 107cached_pin="" 108if cached_pin=$(get_cached_pin 2>/dev/null) && [[ -n "$cached_pin" ]]; then 109 # Show menu with cache options 110 choice=$(printf "OK\nCancel\nClear cache" | rofi -dmenu \ 111 -i \ 112 -no-custom \ 113 -no-fixed-num-lines \ 114 "${mesg_args[@]}" \ 115 "${theme_args[@]}" \ 116 2>/dev/null) || exit 1 117 118 case "$choice" in 119 "OK") 120 extend_cache 121 echo "$cached_pin" 122 exit 0 123 ;; 124 "Cancel") 125 exit 1 126 ;; 127 "Clear cache") 128 clear_cache 129 # Fall through to password prompt below 130 ;; 131 esac 132fi 133 134# Use rofi in password mode 135result=$(rofi -dmenu \ 136 -password \ 137 -p "PIN" \ 138 -lines 0 \ 139 -no-fixed-num-lines \ 140 "${mesg_args[@]}" \ 141 "${theme_args[@]}" \ 142 < /dev/null 2>/dev/null) || exit 1 143 144if [[ -z "$result" ]]; then 145 exit 1 146fi 147 148# Cache the PIN 149cache_pin "$result" 150 151echo "$result"