From 03bbbcc350177fe359892d70789e0c8a60bd30dd Mon Sep 17 00:00:00 2001 From: "Lance R. Vick" Date: Fri, 5 May 2023 18:17:42 -0700 Subject: [PATCH] Drop 'fetch', add 'pull', support custom gpg binaries via env. --- git-sig | 97 +++++++++++++++++++++------------------------------------ 1 file changed, 36 insertions(+), 61 deletions(-) diff --git a/git-sig b/git-sig index 11ff5b8..f13e5d6 100755 --- a/git-sig +++ b/git-sig @@ -6,6 +6,9 @@ readonly MIN_GPG_VERSION=2.2 readonly MIN_OPENSSL_VERSION=1.1 readonly MIN_GETOPT_VERSION=2.33 +GIT_SIG_GPG_VERIFY_COMMAND=${GIT_SIG_GPG_VERIFY_COMMAND:-gpg} +GIT_SIG_SIGN_COMMAND=${GIT_SIG_SIGN_COMMAND:-gpg} + ## Private Functions ### Exit with error message @@ -97,7 +100,7 @@ check_tools(){ for cmd in "$@"; do command -v "$1" >/dev/null || die "Error: $cmd not found" case $cmd in - gpg) + ${GIT_SIG_VERIFY_COMMAND}) version=$(gpg --version | head -n1 | cut -d" " -f3) check_version "gnupg" "${version}" "${MIN_GPG_VERSION}" ;; @@ -116,7 +119,7 @@ check_tools(){ ### Get primary UID for a given fingerprint get_uid(){ local -r fp="${1?}" - gpg --list-keys --with-colons "${fp}" 2>&1 \ + ${GIT_SIG_VERIFY_COMMAND} --list-keys --with-colons "${fp}" 2>&1 \ | awk -F: '$1 == "uid" {print $10}' \ | head -n1 } @@ -124,7 +127,7 @@ get_uid(){ ### Get primary fingerprint for given search get_primary_fp(){ local -r search="${1?}" - gpg --list-keys --with-colons "${search}" 2>&1 \ + ${GIT_SIG_VERIFY_COMMAND} --list-keys --with-colons "${search}" 2>&1 \ | awk -F: '$1 == "fpr" {print $10}' \ | head -n1 } @@ -132,7 +135,7 @@ get_primary_fp(){ ### Get fingerprint for a given pgp file get_file_fp(){ local -r filename="${1?}" - gpg --list-packets "${filename}" \ + ${GIT_SIG_VERIFY_COMMAND} --list-packets "${filename}" \ | grep keyid \ | sed 's/.*keyid //g' } @@ -168,7 +171,7 @@ group_add_fp(){ done echo "Adding key \"${fp}\" to group \"${group_name}\"" - gpg --list-keys >/dev/null 2>&1 + ${GIT_SIG_VERIFY_COMMAND} --list-keys >/dev/null 2>&1 printf 'group:0:%s' "${data%?}" \ | gpgconf --change-options gpg >/dev/null 2>&1 } @@ -176,7 +179,7 @@ group_add_fp(){ ### Get fingerprints for a given group group_get_fps(){ local -r group_name=${1?} - gpg --with-colons --list-config group \ + ${GIT_SIG_VERIFY_COMMAND} --with-colons --list-config group \ | grep -i "^cfg:group:${group_name}:" \ | cut -d ':' -f4 } @@ -221,7 +224,7 @@ sig_generate(){ local -r body="sig:$version:$vcs_ref:$tree_hash:$review_hash:$sig_type" local -r signature=$(\ printf "%s" "$body" \ - | gpg \ + | ${GIT_SIG_SIGN_COMMAND} \ --detach-sign \ --local-user "$key" \ | openssl base64 -A \ @@ -286,7 +289,7 @@ verify_git_note(){ return 1; } gpg_sig_raw="$( - gpg --verify --status-fd=1 \ + ${GIT_SIG_VERIFY_COMMAND} --verify --status-fd=1 \ <(printf '%s' "$sig" | openssl base64 -d -A) \ <(printf '%s' "$body") 2>/dev/null \ )" @@ -314,7 +317,13 @@ verify_git_notes(){ verify_git_commit(){ local -r ref="${1:-HEAD}" local gpg_sig_raw - gpg_sig_raw=$(git verify-commit "$ref" --raw 2>&1) + gpg_sig_raw=$( \ + git \ + -c "gpg.program=$GIT_SIG_VERIFY_COMMAND" \ + verify-commit "$ref" \ + --raw \ + 2>&1 \ + ) parse_gpg_status "$gpg_sig_raw" } @@ -340,7 +349,7 @@ verify(){ local -r ref=${3:-HEAD} local sig_count=0 seen_fps fp commit_sig tag_sigs note_sigs git rev-parse --git-dir >/dev/null 2>&1 \ - || die "Error: This folder is not a git repository" + || die "Error: This folder is not a git repository" if [[ $(git diff --stat) != '' ]]; then die "Error: git tree is dirty" fi @@ -468,7 +477,6 @@ cmd_verify() { --) shift; break ;; esac done - git fetch "$remote" refs/notes/signatures:refs/notes/signatures local -r head=$(git rev-parse --short HEAD) if [ -n "$diff" ] && [ -z "$ref" ]; then while read -r commit; do @@ -491,49 +499,6 @@ cmd_verify() { return 1 } -cmd_fetch() { - local opts group="" group_fps="" - opts="$(getopt -o g: -l group: -n "$PROGRAM" -- "$@")" - eval set -- "$opts" - while true; do case $1 in - -g|--group) group="${2:-1}"; shift 2 ;; - --) shift; break ;; - esac done - [ $# -eq 1 ] || \ - die "Usage: $PROGRAM fetch [-g,--group=]" - local -r fingerprint=${1} - - if [ -n "$group" ]; then - group_fps=$(group_get_fps "${group_name}") - if [[ "${group_fps}" == *"${fingerprint}"* ]]; then - echo "Key \"${fingerprint}\" is already in group \"${group}\"" - else - group_add_fp "${fingerprint}" "${group}" - fi - fi - - gpg --list-keys "${fingerprint}" > /dev/null 2>&1 \ - && echo "Key \"${fingerprint}\" is already in local keychain" \ - && return 0 - - echo "Requested key is not in keyring. Trying keyservers..." - for server in \ - keys.openpgp.org \ - ha.pool.sks-keyservers.net \ - hkp://keyserver.ubuntu.com:80 \ - hkp://p80.pool.sks-keyservers.net:80 \ - pgp.mit.edu \ - ; do - echo "Fetching key \"${fingerprint}\" from \"${server}\""; - gpg \ - --recv-key \ - --keyserver "$server" \ - --keyserver-options timeout=10 \ - --recv-keys "${fingerprint}" \ - && break - done -} - cmd_add(){ local opts method="" push="0" opts="$(getopt -o m:p:: -l method:,push:: -n "$PROGRAM" -- "$@")" @@ -558,17 +523,27 @@ cmd_push() { -r|--remote) remote="$2"; shift 2 ;; --) shift; break ;; esac done - git fetch "$remote" refs/notes/signatures:refs/notes/signatures - git notes --ref signatures merge -s cat_sort_uniq "${remote}"/signatures git push --tags "$remote" refs/notes/signatures } +cmd_pull() { + local opts remote="origin" + opts="$(getopt -o r: -l remote: -n "$PROGRAM" -- "$@")" + eval set -- "$opts" + while true; do case $1 in + -r|--remote) remote="$2"; shift 2 ;; + --) shift; break ;; + esac done + git fetch "$remote" refs/notes/signatures:refs/notes/${remote}/signatures + git notes --ref signatures merge -s cat_sort_uniq "${remote}"/signatures +} + cmd_version() { cat <<-_EOF ========================================== = git-sig: multisig trust for git = = = - = v0.3 = + = v0.4 = = = = https://codeberg.org/distrust/git-sig = ========================================== @@ -587,8 +562,8 @@ cmd_usage() { Verify m-of-n signatures by given group are present for directory. git sig push [-r,--remote=] Push all signatures on current ref - git sig fetch [-g,--group=] - Fetch key by fingerprint. Optionally add to group. + git sig pull [-r,--remote=] + Pull all signatures for current ref git sig help Show this text. git sig version @@ -597,7 +572,7 @@ cmd_usage() { } # Verify all tools in this list are installed at needed versions -check_tools git head cut find sort sed getopt gpg openssl +check_tools git head cut find sort sed getopt openssl ${GIT_SIG_VERIFY_COMMAND} # Allow entire script to be namespaced based on filename readonly PROGRAM="${0##*/}" @@ -607,8 +582,8 @@ case "$1" in verify) shift; cmd_verify "$@" ;; add) shift; cmd_add "$@" ;; remove) shift; cmd_remove "$@" ;; - fetch) shift; cmd_fetch "$@" ;; push) shift; cmd_push "$@" ;; + pull) shift; cmd_pull "$@" ;; version|--version) shift; cmd_version "$@" ;; help|--help) shift; cmd_usage "$@" ;; *) cmd_usage "$@" ;;