diff options
-rwxr-xr-x | bin/generate-key-graph | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/bin/generate-key-graph b/bin/generate-key-graph new file mode 100755 index 0000000..17e6bd1 --- /dev/null +++ b/bin/generate-key-graph @@ -0,0 +1,125 @@ +#!/bin/bash + +# shellcheck source=../lib/load-configuration +. "${0%/*}/../lib/load-configuration" + +tmp_dir=$(mktemp -d 'tmp.generate-key-graph.XXXXXXXXXX') +trap 'rm -rf --one-file-system "${tmp_dir}"' EXIT + +# shellcheck disable=SC2016 +{ + printf 'SELECT DISTINCT ' + printf 'REPLACE(TO_BASE64(`gpg_keys`.`public_key`),"\\n",""),' + printf '`gpg_keys`.`fingerprint`' + printf ' FROM `gpg_keys`' + mysql_join_gpg_keys_binary_packages + mysql_join_binary_packages_binary_packages_in_repositories + mysql_join_binary_packages_in_repositories_repositories + printf ' AND `repositories`.`is_on_master_mirror`;\n' +} \ +| mysql_run_query \ +> "${tmp_dir}/packager-keys" + +# shellcheck disable=SC2046 +${master_mirror_rsync_command} $( + ls_master_mirror pool \ + | grep '^archlinux32-keyring\(-transition\)\?\(-[^-]\+\)\{3\}\.pkg\.tar\.zst$' \ + | sed 's#^#'"${master_mirror_rsync_directory}"'/pool/#' +) "${tmp_dir}/" + +GPG='gpg --quiet --batch --no-tty --no-permission-warning --homedir='"${tmp_dir}"'/gnupg' + +get_user_info() { + ${GPG} --with-colons --list-keys "0x${fp}" \ + | grep -m1 '^uid:' \ + | cut -d: -f 10 \ + | sed 's/^.*<\(\S\+\)>$/\1/' +} + +expiration_color() { + local expiration + expiration=$( + ${GPG} --with-colons --list-keys "0x${fp}" \ + | grep -m1 '^pub:' \ + | cut -d: -f 7 + ) + if [ -z "${expiration}" ]; then + printf '#000000' + return + fi + expiration=$(( + (expiration - $(date +%s))/60/60/24 + )) + if [ ${expiration} -gt 100 ]; then + printf '#000000' + elif [ ${expiration} -gt 50 ]; then + printf '#808000' + elif [ ${expiration} -gt 25 ]; then + printf '#ffff00' + elif [ ${expiration} -gt 0 ]; then + printf '#ff8000' + else + printf '#ff0000' + fi +} + +{ + printf 'digraph "key-graph" {\n' + printf 'rankdir=LR;\n' + + find "${tmp_dir}" -type f -name 'archlinux32-*.pkg.tar*' \ + | while read -r keyring_package; do + mkdir "${tmp_dir}/gnupg" + + { + while read -r s _; do + printf '%s\n' "${s}" \ + | base64 -w0 -d + done \ + <"${tmp_dir}/packager-keys" + bsdtar -Oxf "${keyring_package}" usr/share/pacman/keyrings/archlinux32.gpg + } \ + | ${GPG} --import + + all_keys=$( + cut -f2 \ + < "${tmp_dir}/packager-keys" + bsdtar -Oxf "${keyring_package}" usr/share/pacman/keyrings/archlinux32-trusted \ + | cut -d: -f1 + ) + + while read -r _ fp; do + printf '"%s-%s"[label="packager key %s\\n%s",color="#0000ff",fontcolor="%s"];\n' \ + "${keyring_package##*/}" \ + "${fp}" \ + "${fp:0:8}" \ + "$(get_user_info "${fp}")" \ + "$(expiration_color "${fp}")" + done \ + <"${tmp_dir}/packager-keys" + + bsdtar -Oxf "${keyring_package}" usr/share/pacman/keyrings/archlinux32-trusted \ + | while IFS=: read -r fp _; do + printf '"%s-%s"[label="master key %s\\n%s",color="#00ff00",fontcolor="%s"];\n' \ + "${keyring_package##*/}" \ + "${fp}" \ + "${fp:0:8}" \ + "$(get_user_info "${fp}")" \ + "$(expiration_color "${fp}")" + done + for key_id in ${all_keys}; do + ${GPG} --list-sigs --with-colons "0x${key_id}" \ + | grep -wF "${all_keys}" \ + | grep '^sig:' \ + | cut -d : -f 13 \ + | grep -vxF "${key_id}" \ + | sed 's/^\S\+$/"'"${keyring_package##*/}"'-\0" -> "'"${keyring_package##*/}"'-'"${key_id}"'";/' + done \ + | sort -u + + rm -rf --one-file-system "${tmp_dir}/gnupg" + done + printf '}\n' +} \ +| dot -Tpng \ +>"${webserver_directory}/key-graph.png" |