#!/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' mkdir "${tmp_dir}/gnupg" while read -r s _; do printf '%s\n' "${s}" \ | base64 -w0 -d done \ <"${tmp_dir}/packager-keys" \ | ${GPG} --import while read -r _ fp; do printf '"%s"[label="packager key %s\\n%s",color="#0000ff",fontcolor="%s"];\n' \ "${fp}" \ "${fp: -8}" \ "$(get_user_info "${fp}")" \ "$(expiration_color "${fp}")" done \ <"${tmp_dir}/packager-keys" rm -rf --one-file-system "${tmp_dir}/gnupg" find "${tmp_dir}" -type f -name 'archlinux32-*.pkg.tar*' \ | while read -r keyring_package; do mkdir "${tmp_dir}/gnupg" kpf="${keyring_package##*/}" kpf="${kpf%.pkg.tar*}" { 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 ) printf 'subgraph "cluster %s" {\n' \ "${kpf}" printf 'label="%s";\n' \ "${kpf}" 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' \ "${kpf}" \ "${fp}" \ "${fp: -8}" \ "$(get_user_info "${fp}")" \ "$(expiration_color "${fp}")" done printf '}\n' 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}" \ | while read -r sig; do if cut -f2 \ < "${tmp_dir}/packager-keys" \ | grep -qxF "${sig}"; then print_sig="${sig}" else print_sig="${kpf}-${sig}" fi if cut -f2 \ < "${tmp_dir}/packager-keys" \ | grep -qxF "${key_id}"; then print_key="${key_id}" else print_key="${kpf}-${key_id}" fi printf '"%s" -> "%s";\n' \ "${print_sig}" \ "${print_key}" done done \ | sort -u rm -rf --one-file-system "${tmp_dir}/gnupg" done printf '}\n' } \ | dot -Tpng \ >"${webserver_directory}/key-graph.png"