8

I need a bash script to source a file that is encrypted, as the file being sourced contains sensitive information.

I would like the script to prompt for the GPG passphrase and then run, sourcing the encrypted file. I cannot figure out how to do this though. There must be user input for the passphrase, as I don't want to store a key on the server with the encrypted file.

Looking into some different methods, I do not want to decrypt the file, source the non-encrypted file, then delete it after. I would like to reduce the chance of leaving an non-encrypted file behind, if something went wrong in the script.

Is there a way to get the GPG output of a file to source it this way? Possibly collecting STDOUT and parsing it (if GPG can even output the contents this way).

Also, if there is another way to encrypt a file that shell scripts can use, I am not aware of it, but open to other possibilities.

16

You can do this using process substitution.

. <(gpg -qd "$encrypted_filename")

Here's an example:

% cat > to-source <<< 'echo "Hello"'
% . ./to-source                     
Hello
% gpg -e -r chris@chrisdown.name to-source
% . <(gpg -qd to-source.gpg)
Hello

gpg -d does not persist the file to disk, it just outputs it to stdout. <() uses a FIFO, which also does not result in the actual file data being written to disk.

In bash, . and source are synonyms, but . is more portable (it's part of POSIX), so I've used it here. Note, however, that <() is not as portable -- as far as I know it's only supported in bash, zsh, ksh88, and ksh93. pdksh and mksh have coprocesses which can have the same effect.

  • this is a very nice solution. Thought of a named pipe, but did not want to manage it. I was not aware I could do it this way. – BriGuy Oct 22 '15 at 15:33
  • Of course, if you have a worry about someone being able to read a temporary FILE, with this you have the exact same worry with someone being able to read the temporary pipe created by <(command). – Zan Lynx Oct 22 '15 at 20:17
  • @ZanLynx The question explicitly states that this is about not persisting on disk. The solution to doing this securely otherwise is the same as everywhere else: use a user that only you control, and do it on a system where only you have root. – Chris Down Oct 23 '15 at 8:32
  • 1
    You can also do this with an aescrypt encrypted file (which I did): . <(aescrypt -d -o - file.aes) – Freedom_Ben Feb 20 '16 at 1:02
3

If you've got gpg-agent set up properly, using pinentry-tty or some other version that doesn't pollute stdin/stdout, then you should be able to do something like:

source <( gpg --decrypt file.gpg )

This uses process substitution to feed the result to source as if it's a file. The specific file data will vanish as soon as the shell is done with it, though you still need to be careful about the sensitive data in the shell's memory after that.

0

Since the most sane answer has already been given, here's an insane one - use this filesystem:

https://github.com/jseppanen/gpgfs

This way your program will not notice it's talking to a pipe.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.