#!/bin/bash
set -e

# license: MIT
# latest ver: https://ocv.me/dev/?rpmchk.sh

[ -z "$2" ] && { cat <<'EOF'

 needs arg 1: list of accepted signatures
 needs arg 2: list of accepted header digest algs
 needs arg 3: list of accepted body digest algs

 * returns 0 if all-OK, 1 otherwise
 * not thread-safe, run one copy at a time
 * `rpm --import` all relevant gpg keys first
 * lists are `|` pipe-separated
 * example:
   rpmchk.sh 'V4 DSA/SHA1|V3 RSA/SHA256' 'SHA1' 'SHA1|MD5'

EOF
exit 1
}

rm -f /dev/shm/bad-rpms;
for f in *.rpm; do
	set +e;
	rpm -Kv -- "$f" |
	awk -v sigs="$1" -v hds="$2" -v bds="$3" '
		BEGIN {
			sigs = "^\\s+(Header )?(" sigs ") Signature, key ID [0-9a-f]+: OK$"
			hds = "^\\s+Header (" hds ") digest: OK \\("
			bds = "^\\s+(" bds ") digest: OK \\("
		}

		# line 1: filename
		NR==1 {
			sub(/.$/, "");
			n = $1;
			next;
		}

		# line n: header signature
		$1=="Header" && $0~sigs {
			hs = $(NF-1);
			next;
		}
		
		# line n: header digest
		$1=="Header" && $0~hds {
			hd = 1;
			next;
		}
		
		# line n: body signature
		$0~sigs {
			bs = $(NF-1);
		}
		
		# line n: body digest
		$0~bds {
			bd = 1;
			next;
		}
		
		# ensure we got the 5 expected lines,
		# and that the same signature is used for header and body
		END {
			e=0; m="ok  \033[32m";
			
			if (!hd || !bd || !hs || !bs || hs!=bs || NR!=5) {
				e=1; m=sprintf("bad [%s] [%s] [%s] [%s] [%d] \033[1;37;41m", hd,bd,hs,bs,NR)
			}
			
			printf "%s%s\033[0m\n", m, n;
			exit e;
		}
	';
	
	echo ${PIPESTATUS[*]} |
	grep -qE '^0 0$' && ok=1 || ok=
	set -e

	[ $ok ] ||
		printf '%s\n' "$f" >> /dev/shm/bad-rpms;
done;

printf '\nlist of bad RPMs:\n';
cat /dev/shm/bad-rpms 2>/dev/null || true;
echo
[ ! -e /dev/shm/bad-rpms ]

