N52ZICTOT7TZ2TMETMBDELF777QNZHKFD6YWU7DRSOPOFSSW7IYQC
# pijul-encrypt
Pijul hook to encrypt files using GnuPG in Pijul repositry before recording.
Add globs matching paths you want to encrypt to `.encrypt`.
Register your and collaborators GnuPG public key using `.pijul/encrypt/add-recipients.sh`.
Files will be encrypted both asymmetricaly and symmetricaly.
Symmetric key can be retrieved by decrypting `.encrypt.d/master_key.gpg`.
GnuPGでrecord前にファイルを暗号化するPijulフック。
`.encrypt`に記入したグロブパターンにマッチするファイルを暗号化します。
`.pijul/encrypt/add-recipients.sh`で自分や共同編集者のGnuPG公開鍵を登録できます。
ファイルは公開鍵暗号と共通鍵暗号の両方で暗号化されます。
共通鍵は `.encrypt.d/master_key.gpg`を復号することで確認できます。
``` toml
[hooks]
record = [".pijul/encrypt/hook-record.sh"]
```
#!/bin/sh
[ -d .pijul ] || {
echo 'this directory does not seem to be Pijul repositry.' >&2
false
}
. .pijul/encrypt/scripts.sh
[ "$*" ] || {
echo 'Please supply the recipients fingerprints as arguments.' >&2
false
}
mkdir -p .encrypt.d/recipient/
for recipient in "$@"; do
gpg --armor --export "$recipient" >".encrypt.d/recipient/$recipient.asc"
done
if [ -f .encrypt.d/master_key.gpg ]; then
echo 're-encrypting master key...'
$gpg --decrypt .encrypt.d/master_key.gpg |
$gpg --batch --sign --encrypt \
$(printf -- "--recipient-file$IFS%s$IFS" .encrypt.d/recipient/*.asc) \
--output .encrypt.d/master_key.gpg.tmp
mv .encrypt.d/master_key.gpg.tmp .encrypt.d/master_key.gpg
echo 'done'
fi
#!/bin/sh
. .pijul/encrypt/scripts.sh
if ! sha256sum=$(command -v sha256sum) >/dev/null; then
echo "$0 requires sha256sum" >&2
false
fi
if [ ! -f .encrypt.d/master_key.gpg ]; then
echo "No master key in repositry. Repositry not initialized for pijul-encrypt" >&2
false
fi
encrypt() {
path=$1
$gpg --decrypt .encrypt.d/master_key.gpg |
$gpg --batch --passphrase-fd 0 \
--sign --encrypt --symmetric \
$(printf -- "--recipient-file$IFS%s$IFS" .encrypt.d/recipient/*.asc) "$path"
}
decrypt() {
path=$1
$gpg --decrypt .encrypt.d/master_key.gpg |
$gpg --batch --output - --passphrase-fd 0 \
--decrypt "$path"
}
# globを展開、マッチするディレクトリの中身も全部マッチしたいのでfindを噛ませる
# shellcheck disable=SC2046
worktree_glob=$(find $(cat .encrypt) -type f -not -name '*.gpg')
: "↓debug worktree_glob↓
$worktree_glob"
# pijulが記録しているパスのうち`.encrypt`にマッチするもの
# shellcheck disable=SC2086
# shellcheck disable=SC2046
tracked_glob=$(printf '%s\n' $worktree_glob $(pijul list) | sort | uniq -d)
: "↓debug tracked_glob↓
$tracked_glob"
# shellcheck disable=SC2086
pijul remove $tracked_glob # 秘密のファイルはさっさと記録から除外
# pijulが記録しているパスのうち`*.gpg`にマッチするもの (pijul listが変わってるのでtracked_globとは重複しない)
gpg_tracked=$(pijul list | grep '\.gpg$' | sed 's/\.gpg$//')
: "↓debug gpg_tracked↓
$gpg_tracked"
# 秘密にしなければいけないファイルたち
will_be_encrypted="$tracked_glob
$gpg_tracked"
# 秘密のファイルに変更があれば暗号化し直す
for path in $will_be_encrypted; do
if [ ! -f "$path" ]; then
[ "$path" = ".encrypt.d/master_key" ] || pijul remove "$path.gpg"
else
if [ -f "$path.gpg" ] &&
[ "$($sha256sum <"$path")" != "$(decrypt "$path.gpg" | $sha256sum)" ]; then
rm "$path.gpg"
fi
if [ ! -e "$path.gpg" ]; then
encrypt "$path"
fi
pijul add "$path.gpg"
fi
done
#!/bin/sh
[ -d .pijul ] || {
echo 'this directory does not seem to be Pijul repositry.' >&2
false
}
. .pijul/encrypt/scripts.sh
if [ -f .encrypt.d/master_key.gpg ]; then
echo 'pijul-encrypt already configured!'
false
fi
recipients="$*"
[ "$recipients" ] || {
echo 'Specify recipients fingerprints.'
read -r recipients
}
(
IFS=' '
.pijul/encrypt/add-recipients.sh $recipients
)
echo 'generating master key...'
master_key=$($gpg --armor --gen-random 16 512)
echo "master key generated: $master_key"
printf %s "$master_key" | $gpg --batch --sign --encrypt \
$(printf -- '--recipient-file\n%s\n' .encrypt.d/recipient/*.asc) \
--output .encrypt.d/master_key.gpg
echo "Now add .pijul/encrypt/hook-record.sh to record hook.
edit .pijul/config as below:
\`\`\`
[hooks]
record = ['.pijul/encrypt/hook-record.sh']
\`\`\`
"
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZ9AE3BYJKwYBBAHaRw8BAQdAGN94pisGcqoak2YpkdGbI7LN7LiYx9usauKW
Ma7Bs8+0GzFpbmd1aW5pIDx0aGVAMWluZ3VpbmkuY29tPoiZBBMWCgBBAhsDBQsJ
CAcCAiICBhUKCQgLAgQWAgMBAh4HAheAFiEEcJ1Q2LkR14A7vrhLSTM8CHdnucEF
AmfQKIEFCQHhflcACgkQSTM8CHdnucH/cgD/Wx+M5frnmtpCK3eEu/mXeMc7kcHG
/ABPBib4MML88AoBAOD0UxwiLVQAoj5kWgMF6KvGwyUpzP/JrJM6sSGlBy0DuDgE
Z9AE3BIKKwYBBAGXVQEFAQEHQOBUFAO7TrDwCRF/wf5a4mbMg3oFtdAzHfaTRyZA
polXAwEIB4h+BBgWCgAmAhsMFiEEcJ1Q2LkR14A7vrhLSTM8CHdnucEFAmfQKIcF
CQHhfl0ACgkQSTM8CHdnucH63wD/aWCRxBYfY+/3ojTwXPMG/2MvkJJlUOzZOLo2
vXl8+GABAJu/053eNjD8vPd7sQiMyIO1nTwnJnUXUwSp5/G+0oEKuDMEZ9AoLRYJ
KwYBBAHaRw8BAQdAzACcPo9xNqMc7jPtHwHvY4i7GoBq2OLrQ+quaGgIxUmI9QQY
FgoAJgIbAhYhBHCdUNi5EdeAO764S0kzPAh3Z7nBBQJn0CiHBQkB4VsMAIF2IAQZ
FgoAHRYhBIqd6IQKm47IZWFsLax5ACEx1Ms7BQJn0CgtAAoJEKx5ACEx1Ms75tQA
/iZRhOvFzUBNAB88jj+jAqklXMTVTkeeGYPe4+lzo0a/AQDr2XxM0jax5u/afXHg
b9k4+zs4FxZkfXCDU/L2FdQaAAkQSTM8CHdnucGKzAD9HXR5jPl+qhJ70ji6hCl9
YvR2IE6NLUa/p08us3c5e0QA/1wuoWlU2t0KHCKnvc+clv7b2Pb3Dh69BAycDGM0
MicEuDMEZ9AoVxYJKwYBBAHaRw8BAQdA+lFud6c0oerH3nFcm5k0S1fCm+1ul+tr
0iILkZKAUQ+IfgQYFgoAJgIbIBYhBHCdUNi5EdeAO764S0kzPAh3Z7nBBQJn0CiI
BQkB4VriAAoJEEkzPAh3Z7nBGzMA/13T8AyUrEnojAkq7DpRzjDNPUHZUTdwWxlv
qsF+0byqAQD5DWWlSzFBPveW0EC2jfnNsC2TuoKohYydQfI0qKghCg==
=PKBP
-----END PGP PUBLIC KEY BLOCK-----
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Hello World!
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZ9AE3BYJKwYBBAHaRw8BAQdAGN94pisGcqoak2YpkdGbI7LN7LiYx9usauKW
Ma7Bs8+0GzFpbmd1aW5pIDx0aGVAMWluZ3VpbmkuY29tPoiZBBMWCgBBAhsDBQsJ
CAcCAiICBhUKCQgLAgQWAgMBAh4HAheAFiEEcJ1Q2LkR14A7vrhLSTM8CHdnucEF
AmfQKIEFCQHhflcACgkQSTM8CHdnucH/cgD/Wx+M5frnmtpCK3eEu/mXeMc7kcHG
/ABPBib4MML88AoBAOD0UxwiLVQAoj5kWgMF6KvGwyUpzP/JrJM6sSGlBy0DuDgE
Z9AE3BIKKwYBBAGXVQEFAQEHQOBUFAO7TrDwCRF/wf5a4mbMg3oFtdAzHfaTRyZA
polXAwEIB4h+BBgWCgAmAhsMFiEEcJ1Q2LkR14A7vrhLSTM8CHdnucEFAmfQKIcF
CQHhfl0ACgkQSTM8CHdnucH63wD/aWCRxBYfY+/3ojTwXPMG/2MvkJJlUOzZOLo2
vXl8+GABAJu/053eNjD8vPd7sQiMyIO1nTwnJnUXUwSp5/G+0oEKuDMEZ9AoLRYJ
KwYBBAHaRw8BAQdAzACcPo9xNqMc7jPtHwHvY4i7GoBq2OLrQ+quaGgIxUmI9QQY
FgoAJgIbAhYhBHCdUNi5EdeAO764S0kzPAh3Z7nBBQJn0CiHBQkB4VsMAIF2IAQZ
FgoAHRYhBIqd6IQKm47IZWFsLax5ACEx1Ms7BQJn0CgtAAoJEKx5ACEx1Ms75tQA
/iZRhOvFzUBNAB88jj+jAqklXMTVTkeeGYPe4+lzo0a/AQDr2XxM0jax5u/afXHg
b9k4+zs4FxZkfXCDU/L2FdQaAAkQSTM8CHdnucGKzAD9HXR5jPl+qhJ70ji6hCl9
YvR2IE6NLUa/p08us3c5e0QA/1wuoWlU2t0KHCKnvc+clv7b2Pb3Dh69BAycDGM0
MicEuDMEZ9AoVxYJKwYBBAHaRw8BAQdA+lFud6c0oerH3nFcm5k0S1fCm+1ul+tr
0iILkZKAUQ+IfgQYFgoAJgIbIBYhBHCdUNi5EdeAO764S0kzPAh3Z7nBBQJn0CiI
BQkB4VriAAoJEEkzPAh3Z7nBGzMA/13T8AyUrEnojAkq7DpRzjDNPUHZUTdwWxlv
qsF+0byqAQD5DWWlSzFBPveW0EC2jfnNsC2TuoKohYydQfI0qKghCg==
=PKBP
-----END PGP PUBLIC KEY BLOCK-----
**/secret/*
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Hello World!
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZ9AE3BYJKwYBBAHaRw8BAQdAGN94pisGcqoak2YpkdGbI7LN7LiYx9usauKW
Ma7Bs8+0GzFpbmd1aW5pIDx0aGVAMWluZ3VpbmkuY29tPoiZBBMWCgBBAhsDBQsJ
CAcCAiICBhUKCQgLAgQWAgMBAh4HAheAFiEEcJ1Q2LkR14A7vrhLSTM8CHdnucEF
AmfQKIEFCQHhflcACgkQSTM8CHdnucH/cgD/Wx+M5frnmtpCK3eEu/mXeMc7kcHG
/ABPBib4MML88AoBAOD0UxwiLVQAoj5kWgMF6KvGwyUpzP/JrJM6sSGlBy0DuDgE
Z9AE3BIKKwYBBAGXVQEFAQEHQOBUFAO7TrDwCRF/wf5a4mbMg3oFtdAzHfaTRyZA
polXAwEIB4h+BBgWCgAmAhsMFiEEcJ1Q2LkR14A7vrhLSTM8CHdnucEFAmfQKIcF
CQHhfl0ACgkQSTM8CHdnucH63wD/aWCRxBYfY+/3ojTwXPMG/2MvkJJlUOzZOLo2
vXl8+GABAJu/053eNjD8vPd7sQiMyIO1nTwnJnUXUwSp5/G+0oEKuDMEZ9AoLRYJ
KwYBBAHaRw8BAQdAzACcPo9xNqMc7jPtHwHvY4i7GoBq2OLrQ+quaGgIxUmI9QQY
FgoAJgIbAhYhBHCdUNi5EdeAO764S0kzPAh3Z7nBBQJn0CiHBQkB4VsMAIF2IAQZ
FgoAHRYhBIqd6IQKm47IZWFsLax5ACEx1Ms7BQJn0CgtAAoJEKx5ACEx1Ms75tQA
/iZRhOvFzUBNAB88jj+jAqklXMTVTkeeGYPe4+lzo0a/AQDr2XxM0jax5u/afXHg
b9k4+zs4FxZkfXCDU/L2FdQaAAkQSTM8CHdnucGKzAD9HXR5jPl+qhJ70ji6hCl9
YvR2IE6NLUa/p08us3c5e0QA/1wuoWlU2t0KHCKnvc+clv7b2Pb3Dh69BAycDGM0
MicEuDMEZ9AoVxYJKwYBBAHaRw8BAQdA+lFud6c0oerH3nFcm5k0S1fCm+1ul+tr
0iILkZKAUQ+IfgQYFgoAJgIbIBYhBHCdUNi5EdeAO764S0kzPAh3Z7nBBQJn0CiI
BQkB4VriAAoJEEkzPAh3Z7nBGzMA/13T8AyUrEnojAkq7DpRzjDNPUHZUTdwWxlv
qsF+0byqAQD5DWWlSzFBPveW0EC2jfnNsC2TuoKohYydQfI0qKghCg==
=PKBP
-----END PGP PUBLIC KEY BLOCK-----
**/secret/*