aboutsummaryrefslogtreecommitdiff
path: root/parcimini.bash
blob: 954463fdc35e3ba635115a3a28d9420d79aaadb5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!bash
#
# Copyright (C) 2019--2021 Tom Ryder <tom@sanctum.geek.nz>
#
# This file is part of doomsh.
#
# doomsh is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# doomsh is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# doomsh.  If not, see <https://www.gnu.org/licenses/>.

# parcimini: Refresh GnuPG keyring via Tor avoiding correlation attacks
self=parcimini

# If systemd made us a logs directory, write to files in there
if [ -n "$LOGS_DIRECTORY" ] ; then
    dir=${LOGS_DIRECTORY%%:%}
    exec >>"$dir"/"$self".log
fi

# Base interval between key retrievals from first arg; default 20 mins
interval=${1:-120}

# Check we have gpg and shuf, neither of which are POSIX
hash gpg || exit
hash shuf || exit

# Define logging function
logf() {
    format=$1
    shift
    printf "%s: %s: $format" \
        "$(date +'%FT%T')" "$self" "$@"
}

# Make a temporary file for the key listings, delete on exit
cleanup() {
    logf 'Stopped\n'
    rm -f -- "$list"
}
trap cleanup EXIT
list=$(mktemp) || exit

# Define a function to retrieve all keychain fingerprints
key_ids() {
    gpg --batch --no-tty --list-keys --with-colons |
    awk 'BEGIN { FS = ":" }
$1 == "pub" { pub = 1 ; next }
$1 == "fpr" && pub { pub = 0 ; key_ids[$(NF-1)]++ }
END { for (key_id in key_ids) print key_id }'
}

# Log process start
logf 'Started; base interval %u seconds.\n' \
    "$interval"

# While we're able to write a shuffled key list to the file, refresh all of them
while key_ids | shuf > "$list" ; do
    logf 'Beginning new round; %u key IDs found.\n' \
        "$(sed '$=;d' "$list")"

    # Shuffle list and read each ID
    while read -r key_id ; do

        # Sleep for a random interval
        spell=$((RANDOM % interval + 1))
        logf 'Sleeping for %u seconds...\n' \
            "$spell"
        sleep "$spell"

        # Retrieve key
        logf 'Retrieving key %s...\n' \
            "$key_id"
        gpg --batch --no-tty --recv-key "$key_id" 2>&1

    done < $list
done