131 lines
3.3 KiB
Bash
Executable File
131 lines
3.3 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# Sign an entire [Website]/[Gemini capsule]/[Gopher hole]
|
|
# Verify any file on a signed [Website]/[Gemini capsule]/[Gopher hole]
|
|
|
|
helptext='Usage:
|
|
netsigil --sign <dir> Sign a local copy of your site
|
|
netsigil --verify <URL> Verify remote signature'
|
|
|
|
set -o errexit # -e
|
|
set -o nounset # -u
|
|
#set -o xtrace # for debugging
|
|
|
|
finish() {
|
|
# Clean up on exit
|
|
rm -rf "${tempdir:-netsigil_tempdir_not_set}"
|
|
}
|
|
trap finish EXIT
|
|
|
|
# Process input
|
|
if [ "$#" -lt 2 ] || [ "$#" -gt 2 ]; then
|
|
>&2 echo "$helptext"
|
|
exit 1
|
|
fi
|
|
|
|
action="${1:-}"
|
|
target="${2:-}"
|
|
|
|
if [ "$action" = '--sign' ]; then
|
|
action='sign'
|
|
[ -z "$target" ] && >&2 echo 'Directory not provided' && exit 1
|
|
[ ! -d "$target" ] && >&2 echo 'Directory does not exist' && exit 1
|
|
elif [ "$action" = '--verify' ]; then
|
|
action='verify'
|
|
[ -z "$target" ] && >&2 echo 'URL not provided' && exit 1
|
|
else
|
|
>&2 echo "$helptext"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if signify is installed
|
|
if ! command -v signify >/dev/null; then
|
|
if command -v signify-openbsd >/dev/null; then
|
|
alias signify='signify-openbsd'
|
|
else
|
|
>&2 echo 'signify could not be found.'
|
|
# Offer to install it
|
|
if command -v apt >/dev/null; then
|
|
printf 'Do you want to install it? [Y/n] '
|
|
read -r reply
|
|
reply="$(echo "$reply" | cut -c1)" # get first character of $reply
|
|
case $reply in
|
|
''|[Yy]) echo "Running \`sudo apt install -y signify-openbsd\`"
|
|
sudo apt install -y signify-openbsd || exit 1
|
|
alias signify='signify-openbsd';;
|
|
*) exit 1;;
|
|
esac
|
|
else
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Create temporary directory with a random suffix
|
|
tempdir=$(mktemp -d -t netsigil-XXXXXXX)
|
|
|
|
|
|
# Sign
|
|
if [ "$action" = 'sign' ]; then
|
|
|
|
# Go to specified directory
|
|
cd "$target" || exit 1
|
|
|
|
dir=$(pwd)
|
|
|
|
# Generate keypair
|
|
datadir=${XDG_DATA_HOME:-~/.local/share}
|
|
public_key=$datadir/signify/key.pub
|
|
secret_key=$datadir/signify/key.sec
|
|
if [ ! -f "$public_key" ] && [ ! -f "$secret_key" ]; then
|
|
if [ ! -d "$datadir/signify" ]; then
|
|
mkdir "$datadir/signify" || exit 1
|
|
fi
|
|
echo 'Generating keypair...'
|
|
signify -G -p "$public_key" -s "$secret_key" || exit 1
|
|
echo "Keypair saved in $datadir/signify/"
|
|
fi
|
|
|
|
# Copy public key to temporary directory
|
|
cp "$public_key" "$tempdir/key.pub"
|
|
|
|
# Remove the old signature-bundle, if it exists
|
|
rm -f .well-known/signature-bundle
|
|
|
|
# Generate SHA256SUMS file
|
|
find -- . -type f -print | cut -d '/' -f 2- | sort | xargs sha256sum > "$tempdir/SHA256SUMS"
|
|
|
|
# Go to temporary directory
|
|
cd "$tempdir" || exit 1
|
|
|
|
# Compress
|
|
tar -czf signature-bundle-unsigned --remove-files key.pub SHA256SUMS
|
|
|
|
# Sign the archive
|
|
echo "Signing \`$target\` with \`$datadir/signify/key.sec\`"
|
|
signify -Sz -s "$secret_key" -m signature-bundle-unsigned -x signature-bundle || exit 1
|
|
rm signature-bundle-unsigned
|
|
|
|
# Go back to user-specified directory
|
|
cd "$dir" || exit 1
|
|
|
|
# Create .well-known directory, if it does not exist
|
|
if [ ! -d .well-known ]; then
|
|
mkdir .well-known || exit 1
|
|
fi
|
|
|
|
mv -f "$tempdir/signature-bundle" .well-known/ || exit 1
|
|
|
|
printf "Done. Signature saved in:\\n%s/.well-known/signature-bundle\\n" "$dir"
|
|
|
|
|
|
# Verify
|
|
elif [ "$action" = 'verify' ]; then
|
|
|
|
#cd "$tempdir" || exit 1
|
|
#dir=$(pwd)
|
|
|
|
echo 'TODO'
|
|
|
|
fi
|