NixOS + home-manager configs, mirrored from GitLab SaaS. gitlab.com/andreijiroh-dev/nixops-config
nix-flake nixos home-manager nixpkgs nix-flakes
at main 138 lines 4.5 kB view raw
1#!/usr/bin/env bash 2# shellcheck disable=SC2034 3# SPDX-License-Identifier: MPL-2.0 4# Reliably detect and switch between SSH agents like keychain, yubikey-agent, 1Password, etc. 5 6if [[ $DEBUG != "" ]]; then 7 set -x 8fi 9 10logOps() { 11 PREFIX=$3 12 13 if [[ $PREFIX != "" ]]; then 14 LOGOPS_PREFIX="[ssh-agent-loader::$PREFIX]" 15 else 16 LOGOPS_PREFIX="[ssh-agent-loader]" 17 fi 18 19 if [[ $1 == "debug" ]]; then 20 [[ $DEBUG != "" ]] && echo "[ssh-agent-loader] debug: $2" 21 elif [[ $1 == "warn" ]]; then 22 echo "$LOGOPS_PREFIX warning: $2" 23 elif [[ $1 == "error" ]]; then 24 echo "$LOGOPS_PREFIX error: $2" 25 else 26 [[ $SSH_AGENT_LOADER_SLIENT != "1" ]] && echo "$LOGOPS_PREFIX $2" 27 fi 28} 29 30# Workaround in cases where XDG_RUNTIME_DIR is undefined on login 31if [[ -z "${XDG_RUNTIME_DIR}" ]]; then 32 logOps warn "XDG_RUNTIME_DIR is possibly undefined, see https://github.com/swaywm/sway/issues/7202" 33 logOps warn "for context and https://wiki.archlinux.org/title/XDG_Base_Directory for docs" 34 logOps warn "Temporarily using '/run/user/$(id -u)' for XDG_RUNTIME_DIR in 3s..." 35 sleep 3 36 XDG_RUNTIME_DIR="/run/user/$(id -u)" 37 export XDG_RUNTIME_DIR 38fi 39 40# do feature detection if keychain is installed 41if command -v keychain >> /dev/null; then 42 FF_KEYCHAIN=1 43else 44 FF_KEYCHAIN=0 45fi 46 47try_keychain_ssh_agent() { 48 if [[ $FF_KEYCHAIN == "1" ]]; then 49 logOps info "attempting to use keychain for SSH agents" keychain 50 if [[ "$SSH_AGENT_LOADER_SLIENT" == "" ]]; then 51 eval "$(keychain --eval --ssh-spawn-gpg --ssh-allow-gpg)" 52 else 53 eval "$(keychain --eval --ssh-spawn-gpg --ssh-allow-gpg --quiet)" 54 fi 55 else 56 logOps warn "keychain is not in PATH yet" keychain 57 return 1 58 fi 59} 60 61# Ripped off NixOS-generated set-environment on my laptop for yubikey-agent setup 62try_yubikey_agent() { 63 YUBIKEY_AGENT_AUTH_SOCK="${XDG_RUNTIME_DIR}/yubikey-agent/yubikey-agent.sock" 64 if [[ -f "${YUBIKEY_AGENT_AUTH_SOCK}" ]]; then 65 logOps info "attempting to use Yubikey SSH agent" yubikey-agent 66 if ! SSH_AUTH_SOCK=${YUBIKEY_AGENT_AUTH_SOCK} ssh-add -l >> /dev/null 2>&1; then 67 logOps warn "something went wrong while checking for Yubikey SSH agent availability" yubikey-agent 68 logOps warn "is your Yubikey plugged in properly?" yubikey-agent 69 return 1 70 fi 71 else 72 logOps error "Yubikey SSH agent seems to be not available on this host" yubikey-agent 73 return 1 74 fi 75} 76 77try_1password_ssh_agent() { 78 OP_SSH_AUTH_SOCK="$HOME/.1password/agent.sock" 79 if [[ ! -S "$OP_SSH_AUTH_SOCK" ]]; then 80 logOps warn "1Password SSH agent isn't enabled or desktop app isn't installed yet" 1password 81 return 1 82 fi 83 84 logOps info "attempting to use 1Password SSH agent" 1password 85 if ! SSH_AUTH_SOCK=$OP_SSH_AUTH_SOCK ssh-add -l >> /dev/null 2>&1; then 86 logOps warn "something went wrong while checking for 1Password SSH agent availability" 1password 87 logOps warn "unlock the desktop app first or enable SSH agent from settings" 1password 88 return 1 89 fi 90 export SSH_AUTH_SOCK=$OP_SSH_AUTH_SOCK FF_USE_OP_CLI_PLUGINS=true 91 unset OP_SSH_AUTH_SOCK 92} 93 94ssh-agent-loader() { 95 if [[ $1 == "" || $1 == "auto" ]]; then 96 if [[ $SSH_CONNECTION != "" ]] && [[ $VSCODE_IPC_HOOK_CLI != "" ]]; then 97 logOps info "automatic detection is disabled while you're in a VS Code Remote SSH/Tunnels session" 98 logOps info "to enable SSH agent, please manually invoke the shell function with desired agent" 99 return 100 fi 101 102 export OLD_SSH_AUTH_SOCK="$SSH_AUTH_SOCK" 103 104 unset SSH_AGENT_PID SSH_AUTH_SOCK 105 if try_1password_ssh_agent; then 106 return 107 elif try_keychain_ssh_agent; then 108 return 109 elif try_yubikey_agent; then 110 return 111 else 112 logOps error "SSH agent seems to be failed to load at the moment" 113 logOps error "try again later by manually invoking the shell function" 114 return 1 115 fi 116 elif [[ $1 == "1passowrd" || $1 == "op" ]]; then 117 unset SSH_AGENT_PID SSH_AUTH_SOCK 118 try_1password_ssh_agent 119 elif [[ $1 == "keychain" ]]; then 120 try_keychain_ssh_agent 121 elif [[ $1 == "yubikey" ]]; then 122 try_yubikey_agent 123 else 124 echo "Usage: ssh-agent-loader [auto|[1password|op|1p]|keychain|yubikey]" 125 return 1 126 fi 127} 128 129# Avoid source loops on subsequent file resourcing. 130if [[ -z "$SSH_AGENT_LOADED" ]]; then 131 # automatically detect things as we source this 132 [[ "$FF_SKIP_AUTO_SSH_AGENT_LOADER" == "" ]] && ssh-agent-loader auto 133 export SSH_AGENT_LOADED=1 134fi 135 136if [[ $DEBUG == "1" ]]; then 137 set +x 138fi