GPG-Based Password Wallet

Keep your passwords safe in an encrypted file.
How It Works

Let's dig in to the script to see how it works. The first thing it does is use the dot operator to source a file called functions, which appears as shown in Listing 2. Having wallet source an external file (with the dot operator) is essentially equivalent to inserting the contents of the sourced file (~/bin/functions) at line 3 of wallet. Doing it this way allows other scripts to use the same code (a code library for shell scripts).

The functions file includes a function called is_installed, which uses the bash built-in type to see whether a program is installed. If is_installed doesn't find the program in your $PATH, is_installed prints an error message and calls exit, which terminates wallet. So, if you run wallet and it quits with an error like “cannot locate dialog in path”, you probably haven't installed the dialog package. Use your distribution's package management system (yum, apt-get, whatever) to install dialog and try again.

Input Validation

Lines 18 through 28 of the wallet script parse the command-line arguments using the getopts bash built-in. The while loop loops through the options specified by the string ec:. This means that wallet can accept the -e and -c options, and that the -c option requires an argument. As the while loop moves through the command-line arguments, the current option is assigned to the variable $OPTION, and any argument to the current option is assigned to the variable $OPTARG. Any unrecognized option results in an error message, and wallet exits. After the while loop completes, it's important to reset the $OPTIND variable (this is necessary after any getopts call).

Running wallet the First Time

Lines 37 through 45 of the wallet script verify that the encrypted file exists, and create the file if it doesn't exist already. The -f test checks to see whether $WALLET_FILENAME exists as a normal file. If not, the test fails, and wallet assumes you are running wallet for the first time and that wallet needs to set up the working environment. wallet uses the command substitution syntax for creating the directory in which the encrypted file should exist (line 40):

mkdir -p $( dirname $WALLET_FILENAME )

The command inside the $(...) runs first, and the result becomes the argument to mkdir. The dirname command returns the encrypted file's directory, and mkdir -p creates that directory (and any necessary parent directories).

Next, wallet needs to create the encrypted file (even though the unencrypted version will be empty). Line 41 uses mktemp to create an empty file in /tmp whose name ends in six randomly chosen characters. mktemp prints the name of the file it creates, so running this in a command substitution shell and assigning the result to $TEMPFILE puts the name of the temporary file in $TEMPFILE.

Now we see the first use of gpg. Line 42 uses gpg to encrypt the (empty) temporary file ($TEMPFILE) via symmetric encryption (gpg's -c option) and to write the encrypted file to $WALLET_FILENAME. wallet then deletes the temporary file. Because this is the first time wallet has run, it assumes that edit mode is appropriate and sets the $EDIT_PWFILE flag.

Prompting the User for the Master Password

Line 52 uses the command substitution trick again, this time to prompt the user for the master password (used to encrypt the wallet file). The dialog man page describes the many ways that scripts using dialog can retrieve input from the user. This example uses dialog to create a simple password box. The --stdout option tells dialog to print the user's input (the master password) to standard output, so that it may be assigned to $PASSWORD.

Line 55 inspects the bash variable $?, which contains the exit code of the previous process (dialog, in this case). The convention is that an exit code of 0 indicates success (and wallet follows this convention in its own exit calls). If $? differs from 0 on line 55, this indicates that dialog encountered an error, and wallet terminates with an error message.

Read-Only Mode

If $EDIT_PWFILE is 0 (line 65), then wallet is running in read-only mode:

echo $PASSWORD | gpg --decrypt --passphrase-fd 0 
 ↪$WALLET_FILENAME | less

This tells gpg to decrypt $WALLET_FILENAME and to read the password from standard input (fd 0). Piping $PASSWORD into gpg enables gpg to decrypt the wallet file without interactively asking the user for the master password. The output (the decrypted wallet file) is printed to standard output, which is piped into less, allowing the user to page through the passwords, run searches and so on. When the user closes less, wallet clears the screen and exits.

The rest of the script assumes that $EDIT_PWFILE is nonzero (that wallet is running in edit mode).

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Just use vi directly

Anonymous's picture

Besides the issue with echo $PASSWORD already mentioned, this also puts a cleartext version of your secrets on disk, in tmp files, etc. Although there is an attempt to clean it all up, it's still rather messy and overly complex.
If you use vi, you can edit the gpg files directly with no cleartext ever touching the disk. And it's much simpler.

http://www.antagonism.org/privacy/gpg-vi.shtml

... and even worse: echo

Anonymous's picture

... and even worse:

echo $PASSWORD | gpg --decrypt --passphrase-fd 0

$PASSWORD will be visible to every local user, in cleartext on process list (ps command)

well...

Milo's picture

well, it's nice idea to use shred instead of rm. with rm -f you are deleting link to the inode, but inode itself is left untouched. on BSD rm -P should be sufficient.

Webcast
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers

Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.

Learn More

Sponsored by AMD

White Paper
Red Hat White Paper: Using an Open Source Framework to Catch the Bad Guy

Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6

Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.

Learn more about catching the bad guy in this free white paper.

Learn More

Sponsored by DLT Solutions