diff --git a/openpgp/gitprotect.sh b/openpgp/gitprotect.sh index 3fde2c84f33929cc5c0c90e2ffb82c1d689bca4c..04ac4bf0a73bd954a4ff40994193da6ded183890 100755 --- a/openpgp/gitprotect.sh +++ b/openpgp/gitprotect.sh @@ -276,9 +276,20 @@ elif [[ $command = "encrypt" ]]; then # Encrypt every file from the decrypted sub-directory. while read filePath; do filename=$(basename "$filePath") - cat "$filePath" | gpg2 --trust-model always --batch --homedir "$gnupgHome" \ - --armor "${recipients[@]}" --encrypt > "${filename}.gpg" - done < <(find "decrypted/" -maxdepth 1 -type f) + checksumFile="decrypted/.${filename}.sha256" + + # If the checksum file exists, then verify it. This way we detect if + # decrypted file has been changed in any way since it has been + # decrypted. We should skip unchanged files. + if [[ -f $checksumFile ]] && sha256sum --quiet -c "$checksumFile" > /dev/null 2>&1; then + echo "INFO: File decrypted/$filename doesn't seem to have been changed. Skipping." + # The file was changed, so we need to encrypt new version of it. + else + cat "$filePath" | gpg2 --trust-model always --batch --homedir "$gnupgHome" \ + --armor "${recipients[@]}" --encrypt > "${filename}.gpg" + sha256sum "decrypted/$filename" > "decrypted/.${filename}.sha256" + fi + done < <(find "decrypted/" -maxdepth 1 -type f ! -name '.*.sha256') elif [[ $command = "decrypt" ]]; then gitprotectConfigured || exit "$ERR_NOCONFIG" @@ -288,11 +299,21 @@ elif [[ $command = "decrypt" ]]; then # Process each GnuPG-encrypted file. while read filePath; do filename=$(basename "$filePath" ".gpg") - - # Remove the "decrypted" file if decryption had failed. - if ! gpg2 --quiet --decrypt "$filePath" > "decrypted/$filename"; then + checksumFile="decrypted/.${filename}.sha256" + + # If the checksum file exists, and it does not match, the destination + # file has been modified, so refuse to overwrite it. + if [[ -f $checksumFile ]] && ! sha256sum --quiet -c "$checksumFile" > /dev/null 2>&1; then + echo "ERROR: Current decrypted file 'decrypted/$filename' seems to have been modified since it was last decrypted." + # Decrypt the file. If decryption has failed, we've ended-up with empty + # file we need to remove. + elif ! gpg2 --quiet --decrypt "$filePath" > "decrypted/$filename"; then echo "ERROR: Failed to decrypt file '$filePath'. No private key available." >&2 rm "decrypted/$filename" + # Create a new checksum file for checking if file had been changed by + # user or not. + else + sha256sum "decrypted/$filename" > "decrypted/.${filename}.sha256" fi done < <(find . -maxdepth 1 -name '*.gpg') else