dotbot icon indicating copy to clipboard operation
dotbot copied to clipboard

Feature Request: GPG encrypted files

Open Anachron opened this issue 8 years ago • 11 comments

@I've made this quick and dirty hack to allow gpg encrypted files to be automatically decrypted and added to my .gitignore (if not blacklisted yet).

The script also checks if the file has been decrypted already.

#!/usr/bin/env bash

# =======================================
# Encrypt and decrypt files based on gpg
# =======================================
# 
# Howto:
# Create a file, for example test, inside the main directory.
# Now encrypt it using gpg (like 'gpg -o test.enc.gpg -r <IDENTITY> -e test')
# And run this script. 
# The script will find all files ending with .enc.gpg and tries to find it's decrypted file counterpart.
# If the decrypted file is not in the .gitignore file it will be added.
# Further changes to the decrypted file will automatically be transfered to the encrypted file.
# In case there is no decrypted version, the script will also decrypt it itself.
# If the encrypted file is newer than the decrypted one, it will decrypt again.

set -e
shopt -s globstar

# If no GPG ID available in ENV, take the first private identity that we have
[[ "${GPG_ID}" == '' ]] && GPG_ID=$(gpg -K 2>/dev/null | grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" | head -n 1)

# If at this point we don't have a GPG identity, exit
[[ "${GPG_ID}" == '' ]] && exit 1

function decFile(){
  gpg -q -d "${1}" 2>/dev/null > "${2}"
}

function encFile(){
  #echo "[INFO] Encrypting \"${1}\" to \"${2}\""
  gpg -q -o "${2}" -r "${GPG_ID}" -e "${1}" 2>/dev/null
}

function ts2Str(){
  date -d @"${1}" +%Y%m%d%H%M.%S
}

for encName in **/*.enc.gpg; do
  [[ ! -f "${encName}" ]] && continue
  encModified=$(stat -c %Y "${encName}")
  decName="${encName%.enc.gpg}"
  if [[ ! -f "${decName}" ]]; then
    echo "[INFO] Decrypting \"${1}\" to \"${2}\""
    decFile "${encName}" "${decName}"
    touch -mt $(ts2Str ${encModified}) "${decName}"
  else
    decModified=$(stat -c %Y "${decName}")
    if [[ "${decModified}" -gt "${encModified}" ]]; then
      echo "[INFO] Decrypted file \"${decName}\" has changed."
      encFile "${decName}" "${encName}"
      touch -mt $(ts2Str ${decModified}) "${encName}"
    elif [[ "${encModified}" -gt "${decModified}" ]]; then
      echo "[INFO] Encrypted file \"${encName}\" has changed."
      decFile "${encName}" "${decName}"
      touch -mt $(ts2Str ${encModified}) "${decName}"
    fi
  fi
  if [[ ! $(git check-ignore "${decName}") ]]; then
    echo "[INFO] Ignoring \"${decName}\""
    echo -en "\n${decName}" >> '.gitignore'
  fi
done

Maybe it would be helpful for someone?

Anachron avatar Jul 29 '16 20:07 Anachron

Pinging @bbenne10 and @dwhoban talked about it here: https://github.com/anishathalye/dotbot/issues/35#issuecomment-216308469

anishathalye avatar Jul 29 '16 20:07 anishathalye

Wow that's a quick reply! Basically files having the extension *.enc.gpg will be looked for and one would only have to add that script to the dotbot shell section.

Anachron avatar Jul 29 '16 20:07 Anachron

Email notifications are great 😄

In any case, we can add this to the wiki, and keep the issue open while we're thinking about the feature request.

anishathalye avatar Jul 29 '16 20:07 anishathalye

I will try to mess more with my script to make it more solid. For now it's a very simple way how to do it. (All that I need for now)

Anachron avatar Jul 29 '16 21:07 Anachron

Ill clone and test this out this evening! This looks pretty cool.

bbenne10 avatar Jul 30 '16 14:07 bbenne10

@bbenne10 I updated it slighty to use git check-ignore now instead

Anachron avatar Jul 30 '16 15:07 Anachron

I've updated my code. The new version can encrypt and decrypt files depending on which counterpart has been changed. So if the decrypted file has been changed, it will update the encrypted file. If the encrypted file is newer than the decrypted one, it will update the decrypted file.

Also the GPG identify is now either based on the env you set (GPG_ID) or it takes the first private ID that can be found within GPG (the first one with an email).

Last but not least I've added a check whether the found node is a valid file and skips if its isn't.

In the future I plan to allow encrypting/decrypting of tar.gz archives to not have the need to encrypt single files all over the place. Also I plan to find a solution on where to store the encrypted files rather than next to the decrypted ones.

Anachron avatar Jul 31 '16 07:07 Anachron

Having this feature ootb would be nice.

xen0l avatar Nov 15 '16 15:11 xen0l

+1 to this feature. really would be great.

ashkitten avatar Apr 03 '17 17:04 ashkitten

I wonder if it could first be done as a plugin (and then maybe incorporated into the core distribution at some point)?

anishathalye avatar Apr 03 '17 18:04 anishathalye

You can use something like git-secret or blackbox to handle that.

sobolevn avatar Jun 21 '17 06:06 sobolevn