Andrew Gallagher [2018-11-10 01:18:30Z] wrote:

> I’ve found parcimonie to be useful. 
>
> https://gaffer.ptitcanardnoir.org/intrigeri/code/parcimonie/

I found Parcimonie too bloated and complicated. I don't think it is a
good idea to use a daemon for this purpose.

So, like probably many others, I wrote a Bash script that refreshes just
one random key and remembers it. Next time it refreshes again a random
key from what is left. After all keys have been refreshed it starts the
round again. I run the script through systemd's user timer.

The script gpg-refresh, as I call it, is small so I will attach it to
this message. Hopefully it will come through. It is written completely
by me and I place it in the public domain so anybody is free to do
anything they wish with it.

#!/bin/bash

# Author: Teemu Likonen <tliko...@iki.fi>
# PGP: 4E1055DC84E9DFF613D78557719D69D324539450

# This program is placed in the public domain.

[ "$FLOCKER" != "$0" ] && exec env FLOCKER="$0" flock "$0" "$0" "$@"

program=$(basename -- "$0")
gpg_dir=${GNUPGHOME:-$HOME/.gnupg}

if [[ ! -d $gpg_dir ]]; then
	echo "The gpg directory $gpg_dir does not exist."
	exit 1
fi

umask 077

reset_jobfile() {
	date +start=%s >"$jobfile"
	printf '\n' >>"$jobfile"
}

jobfile=$gpg_dir/gpg-refresh-job
[[ -e $jobfile ]] || reset_jobfile

all_keys=( $(gpg --batch --list-keys --with-colons | awk -F: '
$1 == "pub" {pub = 1}
pub == 1 && $1 == "fpr" {print $10; pub = 0}
') )

if (( ${#all_keys[@]} == 0 )); then
	echo "No keys found in the keyring."
	exit 0
fi

refreshed_keys=( $(sed -e '0,/^$/d' "$jobfile") )

keys=(); i=0
for key in "${all_keys[@]}"; do
	for refreshed in "${refreshed_keys[@]}"; do
		[[ "$key" == "$refreshed" ]] && continue 2
	done
	keys[i++]=$key
done

if (( ${#keys[@]} == 0 )); then
	echo "All keys refreshed. Starting the round again."
	reset_jobfile
	keys=( "${all_keys[@]}" )
fi

keys_left=${#keys[@]}

status_file=$(mktemp /tmp/"$program".XXXXXX) || exit 1
n=$(shuf --head-count=1 --input-range=0-$(( ${#keys[@]} - 1 )))
key=${keys[n]}
echo "Refreshing key $key"
gpg --batch --status-file "$status_file" --refresh-keys -- "$key"

import_ok=
next_key=
print_status_file=
reset_dirmngr=
while read -r line; do
	line=${line#'[GNUPG:] '}
	case "$line" in
	IMPORT_OK*)
		next_key=1
		import_ok=1
		;;
	WARNING*)
		next_key=1
		print_status_file=1
		;;
	FAILURE*)
		line=${line#*' '*' '}
		line=${line%_*}
		case "$line" in
		# No data
		167772218) next_key=1 ;;
		# Server indicated a failure
		219) reset_dirmngr=1 ;;
		# No keyserver available
		167772346) reset_dirmngr=1 ;;
		# Connection closed in DNS
		167772876) reset_dirmngr=1 ;;
		# No dirmngr
		# 33554524
		esac
		;;
	KEYEXPIRED*)
		next_key=1
		;;
	esac
done <"$status_file"

if (( next_key )); then
	printf '%s\n' "$key" >>"$jobfile"
	keys_left=$(( keys_left - 1 ))
fi

if (( ! import_ok || print_status_file )); then
	cat -- "$status_file"
fi

if (( reset_dirmngr )); then
	echo "Killing dirmngr; it will be restarted next time."
	gpgconf --kill dirmngr
fi

rm -f -- "$status_file"
start=$(sed -En -e '0,/$^/s/^start=(.+)$/\1/p' "$jobfile")
days=$(( ( $(date +%s) - start ) / 3600 / 24 ))
printf "Keys total: %d, left: %d (started %d days ago)\n" \
	"${#all_keys[@]}" "$keys_left" "$days"

exit 0
-- 
/// Teemu Likonen   - .-..   <https://keybase.io/tlikonen> //
// PGP: 4E10 55DC 84E9 DFF6 13D7 8557 719D 69D3 2453 9450 ///

Attachment: signature.asc
Description: PGP signature

_______________________________________________
Gnupg-users mailing list
Gnupg-users@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-users

Reply via email to