Add verify arg to diff against a specified parent branch on failure

This commit is contained in:
Lance Vick 2020-11-24 18:16:50 -08:00
parent e9da8fee86
commit 685c93d4b4
Signed by: lrvick
GPG Key ID: 8E47A1EC35A1551D
5 changed files with 158 additions and 53 deletions

View File

@ -1,16 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEZ1U/vaRrtxq9LgsLjkeh7DWhVR0FAl+4nEwACgkQjkeh7DWh
VR0HOg/+M33tcLn9pmiE+31ovH+4/XuDfYIuefWrxc/YLS+E8QIvmw5X+cXCuohV
/qtfPg/EHddvMHq6BCMdo4XwqiPhYXbrh25FgT+bG2c8N8SMK797ffGo3DRH2ZbF
yDFlQz0jShSbjvSFDFHYiS75ACKQ1AXN86gHr+/oH4aMiVtNA2AwrFmcajtY/nUN
UmmRW6h/4mFbIp+MhbX9YH9Pc39da7ZvZyO/S6t9jA3M6Kwu5TZGkhPIHmuhnWc4
CLG+PqQJabtYjt6VniJCcz4uubKKAgmjgB7RgVCQt05wLiB3Ca9MiTWZpGjuhedJ
XrdphEep6cvWa4hvgWvKHQMtJEAKCD21rmnFXkGUl4hbe/joQ1rvEv+JL+QLIZv9
S8rPeByVM4MtItJGIALL157K7dQdepxneRsGOJam6bI0ZLo3DJyDMODJWLFiHmUt
WlZ2Queqp6UQbs19HJYgNve82wZsX/iXbqSRzg6V+043EDgOHpXX0zbJ6qMQXEd9
UlJZQE4VPr/4V8LvYzMxbtlEClhAFIjKY2qAGwvkwoQgEcxYZ6fQZz6nriSPmWOO
lFa5QQZEgJtMge9kQqmYAenD4J0F30S2Lj2IcS+t28XtTYyMiQ48cI37PUkuB5BC
LSCx7lUGGLo5+Uz3aJ89yTpmhCXK0XvmCEqA0rPpz30NcWEaJ+Q=
=7Skg
iQIzBAABCgAdFiEEZ1U/vaRrtxq9LgsLjkeh7DWhVR0FAl+9voEACgkQjkeh7DWh
VR1oSg//X/RqCuceOFQdn8HfC24P8mFuHgFFJpdcVDZALLrXek9QuBd++3VSQBPq
ID26OWh0644BOZDNOXkNvYVnyrwc27CAxjWpbQkn8Z+vl/tpO+A7BTSVxS7M70ID
krxi78nZGgatMsZMWzsPvWe8UCzMd4EN92AUhXGCdU2iSSUeHBz4LEJ46QjnAwq9
dda+mo7qvYLcLcGZJcdrjKTdgquDi83eUkCvB5tI+SJsdRrQED9sEjAQW/rwVs1p
eh1riIJ7ooG0s1SGWT25tn7Z8Xm91mV7GjcbG+PZJUFdcmwouV9lqc0Kzx/6sxvO
veD68TasBcDvn3HfOVrM641HuXVqLPwDWq+eZz8WdhfNj6fKF0u5325XKKfDBIsH
uro3AuE/t1KkAnPcYUQXh3lhG/aY6Xddgy7JJ2ZwaiV6jV17XoNKfstjrEGkBgRc
BZmAX4dtVK6VLcnoZC16DBFicn7EwCKO1eoSJD7n+3kPH9TbcwD9134g3GJDzif/
n7PGPEtinO0lGRUbtr3QO73eaV2IaGvc/d0e7zzHq1gyaMOycTAxouSe8ePaJVn5
iQkqSr/dcgHNL7XA/o39V2CWuC2Tx5UtRKJusJNQhM92Sn9lcAfTz1U6L0nZj4uk
SKShEww86RLSj07jGfcgHjEXPQ5WZ5qmizsxJyXOITpR2wV1FmM=
=jgfL
-----END PGP SIGNATURE-----

View File

@ -1,8 +1,8 @@
64263feac7b00952e9ec3b6c1fd11316faa58ff673c6bd085fac9f6f8d8389f6 .gitignore
67377eee89dfc4411665474ac0bee0f9a19ea7e594bcc8606b0bc3ace69f0aa1 .gitlab-ci.yml
ad3d473c630217dff7c4499efc1de46fc3a55068677c2bb3a21714aa56dd408a Makefile
464ed12795e3e41eee83713709069fefb07f0676ba237894a9325aafe5c91e31 README.md
3dfa934d88199ed8992d63d68bce81c5b82970b4a78d4ccde056d6039ee3cf5f sig
7d6ada59fb41657c84b9fed7984a0e763d58c1fa851bf306db50f686eebdfbdd README.md
e6517003db9161086c31e8fc21184273a1e66d536bf628739eae7118052c9be8 sig
646a6c11ef22d51bd7fadff5ecc806d8d3e7c62151a0dd56bbeb59eca74c671c test/Dockerfile
dd79ef0e6d0738321f916a5c85a60d44152fb1ffcd71572de98cf48e0d0d911c test/keys/user1.pub.asc
c98a656738f188f650fa0107e3478d640c175a3db481a6c3cbc267f75a05b440 test/keys/user1.sec.asc
@ -14,5 +14,5 @@ c0e3df63b1f01a83e17c463af9e37365a5e38ee0289d59cdfee725df202a311b test/keys/user3
d4cbeffdbf7064aaffe94556b5879c88cddf479e3e76518f25c3491482abd789 test/keys/user4.sec.asc
c608e63175a1e9cc3fe2500372769a9e30b808d2e4d4a950796d98dac14775ea test/keys/user5.pub.asc
873f3a1e2da41587f4b5a0dad5d8b704a37144e54931fe3a167ea9648772a5dc test/keys/user5.sec.asc
ab7f531be1e3f9075ee43e20dd230b6400cf856f7dfc857b848c5e9b766fc3f4 test/test.bats
8a517fceb28c7afe5c6baba7792f5f914310800b7ddfde8d3265e26ab46cbee7 test/test.bats
418903b58dad935ee3aa1dfcc4c4ac22fd77a838b87a5c2c3fe4e510a164f0a0 test/test_helper.bash

View File

@ -52,7 +52,7 @@ The simple GPG signature toolchain for directories or git repos.
## Usage
* sig verify [-g,--group=<group>] [-t,--threshold=<N>] [-m,--method=<git|detached> ]
* sig verify [-g,--group=<group>] [-t,--threshold=<N>] [-m,--method=<git|detached> ] [-d,--diff=<branch>]
* Verify m-of-n signatures by given group are present for directory
* sig add
* Add signature to manifest for this directory
@ -119,7 +119,13 @@ sig verify --threshold 2
#### Verify 3 unique signatures from specified signing group via Git method
```
sig verify --threshold 2 --group myteam --method git
sig verify --threshold 3 --group myteam --method git
```
#### Verify 2 unique signatures via detached method and diff on failure
```
sig verify --threshold 2 --diff master --method detached
```
#### Add Detached Signature

143
sig
View File

@ -8,7 +8,7 @@ readonly MIN_GETOPT_VERSION=2.33
## Private Functions
### Bail with error message
### Exit with error message
die() {
echo "$@" >&2
exit 1
@ -117,7 +117,11 @@ check_tools(){
### Use git if available, else fall back to find
get_files(){
if [ -d '.git' ] && command -v git >/dev/null; then
git ls-files | grep -v ".${PROGRAM}"
git ls-files \
--cached \
--others \
--exclude-standard \
| grep -v ".${PROGRAM}"
else
find . \
-type f \
@ -233,27 +237,33 @@ verify_detached() {
for sig_filename in "${filename%.*}".*.asc; do
gpg --verify "${sig_filename}" "${filename}" >/dev/null 2>&1 || {
echo "Invalid detached signature: ${sig_filename}";
exit 1;
return 1;
}
file_fp=$( get_file_fp "${sig_filename}" )
fp=$( get_primary_fp "${file_fp}" )
uid=$( get_uid "${fp}" )
[[ "${seen_fps}" == *"${fp}"* ]] \
&& die "Duplicate signature: ${sig_filename}";
[[ "${seen_fps}" == *"${fp}"* ]] && {
echo "Duplicate signature: ${sig_filename}";
return 1;
}
echo "Verified detached signature by \"${uid}\""
if [ ! -z "${group}" ]; then
group_check_fp "${fp}" "${group}" \
|| die "Detached signing key not in group \"${group}\": ${fp}";
group_check_fp "${fp}" "${group}" || {
echo "Detached signing key not in group \"${group}\": ${fp}";
return 1;
}
fi
seen_fps="${seen_fps} ${fp}"
((sig_count=sig_count+1))
done
[[ "${sig_count}" -ge "${threshold}" ]] || \
die "Minimum detached signatures not found: ${sig_count}/${threshold}";
[[ "${sig_count}" -ge "${threshold}" ]] || {
echo "Minimum detached signatures not found: ${sig_count}/${threshold}";
return 1;
}
}
### Verify all commits in git repo have valid signatures
@ -263,7 +273,7 @@ verify_git(){
[ $# -eq 2 ] || die "Usage: verify_git <threshold> <group>"
local -r threshold="${1}"
local -r group="${2}"
local seen_fps="" sig_count=0 depth=0
local seen_fps="" sig_count=0 depth=0 ref commit fp uid
while [[ $depth != "$(git rev-list --count HEAD)" ]]; do
ref=HEAD~${depth}
@ -271,8 +281,10 @@ verify_git(){
fp=$(git log --format="%GP" "$ref" -n1 )
uid=$( get_uid "${fp}" )
git verify-commit HEAD~${depth} >/dev/null 2>&1\
|| die "Unsigned commit: ${commit}"
git verify-commit HEAD~${depth} >/dev/null 2>&1 || {
echo "Unsigned commit: ${commit}";
return 1;
}
if [[ "${seen_fps}" != *"${fp}"* ]]; then
seen_fps="${seen_fps} ${fp}"
@ -281,8 +293,10 @@ verify_git(){
fi
if [ ! -z "$group" ]; then
group_check_fp "${fp}" "${group}" \
|| die "Git signing key not in group \"${group}\": ${fp}"
group_check_fp "${fp}" "${group}" || {
echo "Git signing key not in group \"${group}\": ${fp}";
return 1;
}
fi
[[ "${sig_count}" -ge "${threshold}" ]] && break;
@ -290,10 +304,75 @@ verify_git(){
((depth=depth+1))
done
[[ "${sig_count}" -ge "${threshold}" ]] \
|| die "Minimum git signatures not found: ${sig_count}/${threshold}";
[[ "${sig_count}" -ge "${threshold}" ]] || {
echo "Minimum git signatures not found: ${sig_count}/${threshold}";
return 1;
}
}
get_temp(){
echo "$(
mktemp \
--quiet \
--directory \
-t "$(basename "$0").XXXXXX" 2>/dev/null \
|| mktemp \
--quiet \
--directory
)"
}
verify_git_diff(){
[ $# -eq 4 ] \
|| die "Usage: verify_git_diff <ref> <threshold> <group> <method>"
command -v git >/dev/null 2>&1 \
|| die "Error: verify diff requires 'git' which is not installed"
local -r diff_ref=${1}
local -r threshold=${2}
local -r group=${3}
local -r method=${4}
local -r temp_repo=$(get_temp)
local -r git_root=$(git rev-parse --show-toplevel)
local -r curr_ref=$(git rev-parse HEAD)
set -x
cp -a "${git_root}/." "${temp_repo}/"
cd "${temp_repo}"
git reset --hard "${diff_ref}" >/dev/null 2>&1
if verify "${threshold}" "${group}" "${method}"; then
git --no-pager diff "${diff_ref}" "${curr_ref}"
else
echo "Verification of specifed diff ref failed: ${ref}"
fi
set +x
}
verify(){
[ $# -eq 3 ] || die "Usage: verify <threshold> <group> <method>"
local -r threshold=${1}
local -r group=${2}
local -r method=${3}
if [ -z "$method" ] || [ "$method" == "git" ]; then
if [ "$method" == "git" ]; then
command -v git >/dev/null 2>&1 \
|| die "Error: method 'git' specified and git is not installed"
fi
if command -v git >/dev/null 2>&1 \
&& ( [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1 );
then
verify_git "${threshold}" "${group}" || return 1
fi
fi
if [ -z "$method" ] || [ "$method" == "detached" ]; then
( [ -d ".${PROGRAM}" ] && ls ."${PROGRAM}"/*.asc >/dev/null 2>&1 ) || {
echo "Error: No signatures";
return 1;
}
cmd_manifest || return 1
verify_detached "${threshold}" "${group}" ."${PROGRAM}"/manifest.txt \
|| return 1
fi
}
## Public Commands
@ -306,32 +385,26 @@ cmd_manifest() {
}
cmd_verify() {
local opts threshold=1 group="" method=""
opts="$(getopt -o t:g:m: -l threshold:,group:,method: -n "$PROGRAM" -- "$@")"
local opts threshold=1 group="" method="" diff=""
local -r args="$@"
opts="$(getopt -o t:g:m:d: -l threshold:,group:,method:,diff: -n "$PROGRAM" -- "$@")"
eval set -- "$opts"
while true; do case $1 in
-t|--threshold) threshold="$2"; shift 2 ;;
-g|--group) group="$2"; shift 2 ;;
-m|--method) method="$2"; shift 2 ;;
-d|--diff) diff="$2"; shift 2 ;;
--) shift; break ;;
esac done
if [ -z "$method" ] || [ "$method" == "git" ]; then
if [ "$method" == "git" ]; then
command -v git >/dev/null 2>&1 \
|| die "Error: method 'git' specified and git is not installed"
fi
command -v git >/dev/null 2>&1 \
&& ( [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1 ) \
&& verify_git "${threshold}" "${group}"
fi
if [ -z "$method" ] || [ "$method" == "detached" ]; then
( [ -d ".${PROGRAM}" ] && ls ."${PROGRAM}"/*.asc >/dev/null 2>&1 ) \
|| die "Error: No signatures"
cmd_manifest
verify_detached "${threshold}" "${group}" ."${PROGRAM}"/manifest.txt
if verify "$threshold" "$group" "$method"; then
return 0
elif [ ! -z "$diff" ]; then
echo "Verification failed."
echo "Attempting verified diff against git ref ${diff} ..."
verify_git_diff "$diff" "$threshold" "$group" "$method"
fi
return 1
}
cmd_fetch() {
@ -405,8 +478,8 @@ cmd_usage() {
Usage:
$PROGRAM add
Add signature to manifest for this directory
$PROGRAM verify [-g,--group=<group>] [-t,--threshold=<N>] [-m,--method=<git|detached> ]
Verify m-of-n signatures by given group are present for directory
$PROGRAM verify [-g,--group=<group>] [-t,--threshold=<N>] [-m,--method=<git|detached> ] [d,--diff=<branch>]
Verify m-of-n signatures by given group are present for directory.
$PROGRAM fetch [-g,--group=<group>]
Fetch key by fingerprint. Optionally add to group.
$PROGRAM manifest

View File

@ -197,3 +197,29 @@ load test_helper
run sig verify --method detached --threshold 2 --group maintainers
[ "$status" -eq 1 ]
}
@test "Verify diff shows changes between feature branch and verified master" {
git init
set_identity "user1"
echo "test string" > testfile
sig add
git add .
git commit -m "User 1 Commit"
set_identity "user2"
sig add
git add .
git commit -m "User 2 Commit"
set_identity "user1"
git checkout -b feature_branch
echo "updated test string" > somefile1
sig add
git add .
git commit -m "User 1 Update Commit"
run sig verify --diff master --method detached --threshold 2
[ "$status" -eq 1 ]
echo "${output}" | grep "updated test string"
}