GnuPG Shell Script - Refuses to read password - shell

The script below used to work on Mac OS X, but, since moving it to Ubuntu, it doesn't seem to read from the password file at all. Even when I run it from the command line, no matter what I do, I get a popup prompt asking me for the password. As this will run via cron, I don't want this to happen... I want it to read the password from the file with no prompt. To note, I did try using passphrase-fd and passphrase-file, neither of which worked...
#!/bin/sh
p=$(<pass.txt)
set -- $p
pass_phrase=$1
destination="/var/www/decrypted"
cd /var/sl_bin/
for FILE in *.pgp;
do
FILENAME=${FILE%.pgp}
gpg --passphrase "$pass_phrase" --output "$destination/$FILENAME" --decrypt "$FILE"
rm -f $FILE
done

This works:
gpg --no-use-agent --batch --passphrase-file pass.txt --output kkkk.tar.bz2 --decrypt kkk-data.tar.bz2.gpg

The --passphrase-file option seems to be broken / not honored. I had to use --passphrase-fd 0 instead, like so:
cat .password | gpg --passphrase-fd 0 --output foo --decrypt foo.gpg

Use option --no-use-agent. It won't prompt you using option --passphrase.

If you don't want to supply the file via standard input (eg, because you're plugging this into another command like git, which wants to supply the content to sign via standard input), then you can use another file descriptor:
gpg --passphrase-fd 3 <your command here> 3< pass.txt

Your problem is probably that $passphrase is null. On Ubuntu sh is symlinked to dash which doesn't understand $(<file_name) in the same way that Bash does (but doesn't issue an error either).
You can change your shebang to:
#!/bin/bash
or use $(cat pass.txt)
Also, why not combine the second, third and fourth lines?: pass_phrase=$(<pass.txt) (or pass_phrase=($(<pass.txt)) if you're trying to strip off all but the first "word" in the file).
Your previous question

use
#!/bin/bash
or
#!/usr/bin/env bash
as your first line instead of #!/bin/sh
As for your pass phrase problem, you should probably try to use some automatic mechanism. check the gpg documentation for information. I don't use gpg, but you can check out gpg-agent.

Two solutions (the first one solved my problem ;-))
http://www.roguedaemon.net/rephrase/
gpg uses --passphrase-fd not --passphrase
echo yourpw|gpg --passphrase-fd 0 --output out.txt -d file.txt

You're getting password prompt because you have DISPLAY variable set (if you click cancel the script will continue decrypting files). DISPLAY shouldn't be set in the cron environment, so you can probably ignore it, but to be sure or be able to test the script from command prompt add
unset DISPLAY
to the beginning of the script or run it before executing.
Also to be able to use $(<file) syntax you need to change
#!/bin/sh
to
#!/bin/bash
You should avoid using --passphrase option which could lead to revealing your password on multi-user system. You can use --passphrase-file instead. Here's how I would change your script:
#!/bin/sh
PASSFILE=$(pwd)/pass.txt
destination="/var/www/decrypted"
cd /var/sl_bin/
for FILE in *.pgp;
do
FILENAME=${FILE%.pgp}
gpg --passphrase-file $PASSFILE --output "$destination/$FILENAME" --decrypt "$FILE"
rm -f $FILE
done
To save location of the password file before changing current directory, I saved it in PASSFILE variable.

add --archive to read password from --passphrase-file

You must to use:
gpg --batch --passphrase-fd 1 --passphrase-file your_password_file -c your_file_to_encript.txt

Use below script
#! /bin/sh
gpg --pinentry-mode loopback --passphrase='PASSWORD' --output /output/outputFileName /input/inputFileName

Related

Syntax error when calling variable in bash

Here is my code:
#!bin/bash
id=$(sshpass -p password ssh -tt username#ipaddress -p PORT "grep --include=\*.cr -rlw '/usr/local/bin/' -e '$1' | cut -c16-")
echo $id
sshpass -p password rsync -avHPe 'ssh -p PORT' username#ipaddress:/usr/local/bin/"$id" /usr/local/bin/
id echos correctly, but I get an rsync error when trying to call the variable.
If I manually populate and run rsync, the command works, so I'm not sure what is going on.
Rsync gives me the following output on error.
rsync: link_stat "/usr/local/bin/match.cr\#015" failed: No such file or directory (2)
It seems to be grabbing extra characters? Any help is appreciated :)
Looks like your file contains Windows specific "CR LF" characters. You need to convert these to Linux specific "LF" characters in your script. You can use a tool like dos2unix or Notepad++.

Unattended GPG command script hangs at GPG command

I want to create an auto GnuPG key generation script for one person atm who, although they run ubuntu, does not feel comfortable using the CLI. In addition, someone else manages their computer, keeping it up to date and in good running order, so they do not have root/sudo access either. And I would really like to try and avoid doing as much as possible with instructions over the phone... been there too many times to know what a PITA that can be!
So I whipped up this script borrowing heavily from an example I found on the gnupg.org forums (I think?). But it does not seem to do anything once the gpg --gen-key --batch command is run no matter how much mouse activity is generated in 3 or 4 minutes. All the echo statements btw are just a temporary means to indicate script progress, which isn't very far atm.
#!/bin/bash
# First run give your server some work, otherwise gpg won't be able to generator random bytes.
#sudo rngd -r /dev/urandom
#no sudo so:
echo -e "\nYou need to begin moving your mouse continuously and in random patterns for as long as it takes to generate a new key. This could take a minute or two, so be patient and just keep moving the mouse.\n"
echo -e "\ngpg --gen-key --batch\n"
gpg --batch --gen-key
%echo Generating a default key
Key-Type: default
Key-Length: 2048
Subkey-Type: default
Name-Real: Firstname Lastname
Name-Comment: No comment
Name-Email: user#domain.com
Expire-Date: 0
Passphrase: abcde
%pubring foo.pub
%secring foo.sec
# Do a commit here, so that we can later print "done" :-)
%commit
%echo done
# kill the rngd task.
#sudo service rng-tools stop
echo -e "\ngpg -k\n"
gpg -k
# get key id for newly created passkey
echo -e "\nkId=$(gpg -k Firstname|grep pub|sed -r 's/^pub[ ]*2048R\/([A-Z0-9]{8,})[ ]*.*$/\1/')\n" #; echo "\$kId: ${kId}"
kId=$(gpg -k Firstname|grep pub|sed -r 's/^pub[ ]*2048R\/([A-Z0-9]{8,})[ ]*.*$/\1/') ; echo -e "\n\$kId: ${kId}\n"
# set key as the default key (if desired) by entering this line in your ~/.bashrc
echo -e "\nexport GPGKEY=$kId\n"
export GPGKEY="$kId"
# restart the gpg-agent and source your .bashrc again
echo -e "\nkillall -q gpg-agent\n"
killall -q gpg-agent
eval $(gpg-agent --daemon)
source ~/.bashrc
#create revocation cert
echo -e "\ngpg --output revoke.asc --gen-revoke $GPGKEY\n"
gpg --output revoke.asc --gen-revoke $GPGKEY
# send public key to keyserver
echo -e "\ngpg --send-keys --keyserver keyserver.ubuntu.com $GPGKEY\n"
#gpg --send-keys --keyserver keyserver.ubuntu.com $GPGKEY
I wonder if anyone can see any obvious problems or omissions feeding 'gpg' required key details?
I get the same thing even if I run the script with the sudo rngd -r /dev/random command that I need to bypass for the intended user (no sudo access).
So I guess the prob is in the key params I want to pass to gpg, but I have cross referenced them with the man page and can't seem to find what the problem might be. It is funny though that gpg does not return the error.
With batch key generation, GnuPG expects the creation commands in a file, compare with the GnuPG manual page on batch key generation.
cat <<EOT >batch-cmds
%echo Generating a default key
Key-Type: default
Key-Length: 2048
Subkey-Type: default
Name-Real: Firstname Lastname
Name-Comment: No comment
Name-Email: user#domain.com
Expire-Date: 0
Passphrase: abcde
%pubring foo.pub
%secring foo.sec
# Do a commit here, so that we can later print "done" :-)
%commit
%echo done
EOT
gpg --batch --gen-key batch-cmds
Consider the security implications of storing the passwords in a file on the hard disk. I'm not sure if you can also pipe the contents directly into GnuPG instead of storing them to a file. Try something like this:
gpg --batch --gen-key <<EOT
%echo Generating a default key
Key-Type: default
Key-Length: 2048
Subkey-Type: default
Name-Real: Firstname Lastname
Name-Comment: No comment
Name-Email: user#domain.com
Expire-Date: 0
Passphrase: abcde
%pubring foo.pub
%secring foo.sec
# Do a commit here, so that we can later print "done" :-)
%commit
%echo done
EOT

decrypt multiple OpenPGP files in a directory

I have several hundred gpg encrypted files in a directory, of the format filename.xyz.gpg where "xyz" is some arbitrary extension. I need to decrypt all of the files to generate filename.xyz decrypted in such a way that I don't have to manually enter the password for each file.
I have tried the following for directory "Testing":
for file in 'ls Testing'; do (echo <password>|gpg --passphrase-fd 0 -d $file
--output $file.decrypted);
I just wind up with a command prompt >, and nothing happens.
What is the matter with my syntax? Is there some more efficient way to do this without a bash shell loop?
gpg can decrypt multiple files so you shouldn't need to write a loop.
Try the following. You will need to enter your password once.
gpg --passphrase-fd 0 --decrypt-files *.gpg
As it is said in the manual you need to add --batch option:
--passphrase-fd n
Read the passphrase from file descriptor n. Only the first line will be read from file descriptor n. If you use 0 for n, the passphrase will be read from
STDIN. This can only be used if only one passphrase is supplied. Note that this passphrase is only used if the option --batch has also been given. This is
different from gpg.
--passphrase string
Use string as the passphrase. This can only be used if only one passphrase is supplied. Obviously, this is of very questionable security on a multi-user sys‐
tem. Don't use this option if you can avoid it. Note that this passphrase is only used if the option --batch has also been given. This is different from
gpg.
You can have either of these two forms:
echo "passphrase" | gpg --passphrase-fd 0 --batch -d --output "decrypted.file" "file.gpg"
Or simpler:
gpg --passphrase "passphrase" --batch -d --output "decrypted.file" "file.gpg"
You can try a script like this to extract your files:
#!/bin/bash
read -rsp "Enter passphrase: " PASSPHRASE
for FILE in *.*.gpg; do
echo "Extracting $FILE to ${FILE%.gpg}."
echo "$PASSPHRASE" | gpg --passphrase-fd 0 --batch -d --output "${FILE%.gpg}" "$FILE"
done
I had success with
gpg --decrypt-files *.gpg
cf. https://serverfault.com/a/388068/103585
I had success with gpg --decrypt-files *
but not *.gpg
It worked with below commands for me:
For single file:
gpg --decrypt --input C:\PGPFiles\[encryptedfilename.pgp] --passphrase [yourpassphrase]
For multiple files:
gpg --decrypt --input C:\PGPFiles\* --passphrase [yourpassphrase]

Writing gpg decrypted file to a specified outfile

I attempted to decrypt an encrypted gpg file using:
gpg -d <encrypted file> --output <outfile>
and just get a message:
usage: gpg [options] --decrypt [filename]
In contrast, if I use
gpg -d <encrypted file>
the file is decrypted, but it's written to a default file and displayed to the terminal screen. The former isn't a big issue, but the latter (display in terminal screen while decrypting) is a real nuisance. What, if anything, can be done about it?
Try gpg --output <outfile> -d <encrypted file>
The "-d" is unnecessary, this is fine:
gpg -o plaintext.txt ciphertext.asc
As for printing the decypted data to stdout, that usually only happens when the sender uses the old "for-your-eyes-only" flag. To determine exactly what is happening there, though, I'd need more detail on the version of GPG in use and possibly some information on the ciphertext.

Write to stdout instead of file

How can I write data to stdout instead of writing file?
I'm using GPG and want to print encrypted text to stdout, without saving files.
However, with gpg command, encrypted text is written to file in ordinary way:
$> gpg --recipient someone#example.com --armor --output encrypted.txt --encrypt example.pdf
(With above command, encrypted file is saved in encrypted.txt)
What I want to do is like following:
$> gpg --recipient someone#example.com --armor --output <STDOUT> --encrypt example.pdf
and encrypted messages are shown in console.
I don't want to save hard disk to avoid loss of performance.
Usually you use "-" to specify stdout, but not all commands accept this and I don't about gpg.
For example:
tar -cvzf - foo/ ¦ split -b 50k foobar_
will pipe the "tar-file" to stdout, split it and save to "foobar_<123...>".
If your application does not support '-' as a filename (and it should) then an alternative is to use a named pipe, although I'll admit this looks like using a sledgehammer to crack a nut:
pipe='/tmp/pipe'
mkfifo "$pipe"
gpg --recipient someone#example.com --armor --output "$pipe" --encrypt example.pdf &
while read
do
echo "$REPLY"
done < $pipe
rm "$pipe"
Based on the gnupg manual
Simply omit the --output.

Resources