diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3f6bcae --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.eol": "\n", + "files.autoGuessEncoding": true, + "files.insertFinalNewline": true, + "files.trimTrailingWhitespace": true +} diff --git a/keychain.pod b/keychain.pod index 32a0d6c..6d776d4 100644 --- a/keychain.pod +++ b/keychain.pod @@ -28,11 +28,23 @@ Keychain also supports GnuPG 2.1 and later, and will automatically start gpg-agent if any GPG keys are referenced on the command-line, and will ensure these credentials are cached in memory and available for use. -Keychain supports most UNIX-like operating systems. It supports integration -with Bourne-compatible, csh-compatible and fish shells. - Official project home: L. +=head1 COMPATIBILITY + +Keychain supports most UNIX-like operating systems. + +Keychain itself requires a Bourne-compatible shell to function, but will +support integration with Bourne, csh/tcsh, and fish shells. Bash, ksh and +zsh should also work as they can consume the standard Bourne pidfiles +generated by Keychain. + +Keychain will work with a reasonably modern OpenSSH (7.3 and newer), and +should also be compatible with many legacy SSH implementations +such as SunSSH which can be found on older Oracle Solaris systems. + +GnuPG support requires GnuPG 2.1 or later. + =head1 LIFECYCLE Typically, you configure keychain to run when you first log in to a system. diff --git a/keychain.sh b/keychain.sh index 7840968..ead160d 100755 --- a/keychain.sh +++ b/keychain.sh @@ -2,7 +2,7 @@ versinfo() { qprint - qprint " Copyright ${CYANN}2009-##CUR_YEAR##${OFF} Daniel Robbins, BreezyOps;" + qprint " Copyright ${CYANN}2002-##CUR_YEAR##${OFF} Daniel Robbins, BreezyOps;" qprint " lockfile() Copyright ${CYANN}2009${OFF} Parallels, Inc." qprint " Copyright ${CYANN}2007${OFF} Aron Griffis;" qprint " Copyright ${CYANN}2002-2006${OFF} Gentoo Foundation;" @@ -124,8 +124,7 @@ me=$(id -un) || die "Who are you? id -un doesn't know..." # synopsis: testssh # Figure out which ssh is in use, set the global boolean $openssh and $sunssh testssh() { - # Query local host for SSH application, presently supporting - # OpenSSH, Sun SSH, and ssh.com + # Query local host for SSH application, presently supporting OpenSSH and Sun SSH: openssh=false sunssh=false @@ -429,7 +428,7 @@ SSH_AGENT_PID=$SSH_AGENT_PID; export SSH_AGENT_PID" else mesg "Starting ssh-agent..." # shellcheck disable=SC2086 # We purposely don't want to double-quote the args to ssh-agent so they disappear if not used: - pidfile_out="$(ssh-agent ${ssh_timeout} ${ssh_agent_socket})" + pidfile_out="$(ssh-agent -s ${ssh_timeout} ${ssh_agent_socket})" return $? fi fi @@ -438,18 +437,11 @@ SSH_AGENT_PID=$SSH_AGENT_PID; export SSH_AGENT_PID" write_pidfile() { if [ -n "$pidfile_out" ]; then pidfile_out=$(echo "$pidfile_out" | grep -v 'Agent pid') + case $pidfile_out in setenv\ *) error "unexpected csh-style ssh-agent output (expected -s)"; exit 1;; esac rm -f "$pidf" "$cshpidf" "$fishpidf" # Remove first, so we can recreate with our umask - case "$pidfile_out" in - setenv*) - echo "$pidfile_out" >"$cshpidf" - echo "$pidfile_out" | awk '{print $2"="$3" export "$2";"}' >"$pidf" - ;; - *) - echo "$pidfile_out" >"$pidf" - echo "$pidfile_out" | sed 's/;.*/;/' | sed 's/=/ /' | sed 's/^/setenv /' >"$cshpidf" - echo "$pidfile_out" | sed 's/;.*/;/' | sed 's/^\(.*\)=\(.*\);/set -e \1; set -x -U \1 \2;/' >"$fishpidf" - ;; - esac + echo "$pidfile_out" >"$pidf" + echo "$pidfile_out" | sed 's/;.*/;/' | sed 's/=/ /' | sed 's/^/setenv /' >"$cshpidf" + echo "$pidfile_out" | sed 's/;.*/;/' | sed 's/^\(.*\)=\(.*\);/set -e \1; set -x -U \1 \2;/' >"$fishpidf" else debug skipping creation of pidfiles! fi diff --git a/scripts/release-create.sh b/scripts/release-create.sh index f1c1077..f8c35d0 100755 --- a/scripts/release-create.sh +++ b/scripts/release-create.sh @@ -37,7 +37,7 @@ for f in "$ASSET_TARBALL" "$ASSET_KEYCHAIN" "$ASSET_MAN"; do [ -f "$f" ] || fail "Missing asset file $f" # Determine publish name (basename should remain canonical filenames) case $(basename "$f") in - keychain-$VER.tar.gz) pname="keychain-$VER.tar.gz";; + "keychain-$VER.tar.gz") pname="keychain-$VER.tar.gz";; keychain) pname="keychain";; keychain.1) pname="keychain.1";; *) # If path is different (e.g., CI dir), map by type heuristics diff --git a/scripts/release-orchestrate.sh b/scripts/release-orchestrate.sh index 65616ae..e614dce 100755 --- a/scripts/release-orchestrate.sh +++ b/scripts/release-orchestrate.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Orchestrated release creation/refresh with: # 1. Local build presence check (already performed via Makefile prereqs) # 2. CI artifact fetch (mandatory) @@ -142,7 +142,7 @@ for artifact in keychain keychain.1 keychain-$VER.tar.gz; do fi fi ;; - keychain-$VER.tar.gz) + "keychain-$VER.tar.gz") if compare_tar_content "$artifact" "$CI_DIR/$artifact"; then # If tar blob hash matches display it; else note normalized match. L=$(calc_sha256 "$artifact"); R=$(calc_sha256 "$CI_DIR/$artifact") @@ -203,7 +203,7 @@ sed 's/^/| /' "$NOTES_FILE" echo "=========================================================================" printf 'Continue with %s of %s? (Y/N): ' "$MODE" "$VER" -read ans < /dev/tty || ans=N +read -r ans < /dev/tty || ans=N case "$ans" in Y|y) echo "Continuing...";; *) echo "Aborted by user."; exit 1;; diff --git a/scripts/release-refresh.sh b/scripts/release-refresh.sh index fa0c33d..28234b0 100755 --- a/scripts/release-refresh.sh +++ b/scripts/release-refresh.sh @@ -29,7 +29,7 @@ ASSET_TARBALL=${KEYCHAIN_ASSET_TARBALL:-keychain-$VER.tar.gz} for f in "$ASSET_TARBALL" "$ASSET_KEYCHAIN" "$ASSET_MAN"; do [ -f "$f" ] || fail "Missing asset file $f" case $(basename "$f") in - keychain-$VER.tar.gz) pname="keychain-$VER.tar.gz";; + "keychain-$VER.tar.gz") pname="keychain-$VER.tar.gz";; keychain) pname="keychain";; keychain.1) pname="keychain.1";; *) if echo "$f" | grep -q "keychain-$VER.tar.gz"; then pname="keychain-$VER.tar.gz"; fi