Password management using GNU recutils
GNU recutils is a an under-appreciated piece of software. When MySQL or even SQlite is an overkill, recutils fits the bill. It is a database which is
- Key-value store
- Text-based, flat-file
- Human-readable
- Git-friendly
- Supporting encryption
Recutils also comes with many command-line programs to manipulate the text
files, such as recins
, recdel
, etc. Since there aren’t that many online
resources available, I thought of writing a small tutorial using a password
manager as an example.
Installation
Recutils is available for both DEB and RPM-based systems. Choose your poison:
sudo apt-get install recutils
sudo yum install recutils
But of course, you can always build it from upstream sources. It takes just a couple of minutes:
# dependencies
sudo apt-get install libgcrypt-dev libreadline-dev
# Download the package and verify its authenticity
wget https://ftp.gnu.org/gnu/recutils/recutils-1.7.tar.gz
wget https://ftp.gnu.org/gnu/recutils/recutils-1.7.tar.gz.sig
# The tarball is signed by recutils' developer Jose E. Marchesi
gpg --keyserver keys.gnupg.net --recv-keys B304AF08
gpg --verify recutils-1.7.tar.gz.sig recutils-1.7.tar.gz
# Unpack and install
tar xf recutils-1.7.tar.gz
cd recutils-1.7/
./configure --prefix=/usr/local --enable-static --disable-shared \
--enable-encryption --with-pic --disable-dependency-tracking
make -j4
sudo make install
A Music Database
In the simplest case, a recfile is a collection of records. A record is a
collection of fields. Create a text file music.rec
to hold music records:
# Comments begin with a #. Fields starting with a percentage are special.
%rec: MusicDB
# Multiline fields are separated by a + sign in column 1 followed by a space
Title: Siva Sankari
Movie: Jagadeka Veeruni Katha
Singer: Ghantasala
Actor: NTR
Year: 1961
Comment: This song is renowned for being very
+ hard to sing.
Yes. That’s all it takes to create a database ! The above file contains one
record with six fields. New entries can be inserted into the database by the
recins
program as well:
recins -t MusicDB -r "Title: Suprabhatam" -r "Album: Venkatesha Suprabhatam" \
-f "Artist" -v "M.S. Subbulakshmi" music.rec
tail -4 music.rec
Title: Suprabhatam
Album: Venkatesha Suprabhatam
Artist: M.S. Subbulakshmi
Fields and values can be specified separately (with -f
and -v
) or together
(with -r
). The type/title of the record is given with -t
(must match the %rec
line in the file).
The PasswordDB
Here’s a more detailed database. Create a file called mysecrects.rec
with
these contents:
%rec: PasswordDB
%key: Title
%sort: Title
%confidential: Password
%typedef: Date_t date
%type: Date Date_t
%auto: Date
The title of the record is given by %rec
. In our example, the PasswordDB
record consists of six fields: Title, Username, Password, URL, Date and
Comment. The records are sorted by the field indicated by %sort
. The records
themselves are indexed by %key
. In the above example, both are Title
. The
Password field is marked as %confidential
and it will be encrypted
automatically during entry insertion. The last three lines enable us to insert
the Date
field automatically. Note that %key
is a synonym for %unique
and
%mandatory
(meaning Title
must be unique for the given record and every
entry compulsorily contains a title).
A record can be empty. Let’s insert our first entry using recins
as before:
# Bash doesn't store in history any command that begins with a leading space
# whenever HISTCONTROL=ignoreboth (which is the default)
recins -t PasswordDB -r "Title: Gmail" -r "Username: myuser" \
-r "URL: http://gmail.com" \
-f Comment -v 'This is
an example of multiline comment.
It holds my Gmail secrets' \
-r "Password: gmailpasswd" -s mysecrets.rec
Password:
Password again:
As you can see, since Password
field was marked as %confidential
, the
program prompts for an encryption password. This has nothing to do with the -r
"Password: gmailpasswd"
option given above. gmailpasswd
is the value of the
Password
field as stored in the text file. The Password prompt asked by
recins
will encrypt the word gmailpasswd
as shown below:
cat mysecrets.rec
%rec: PasswordDB
%key: Title
%sort: Title
%confidential: Password
%typedef: Date_t date
%type: Date Date_t
%auto: Date
Date: Sun, 05 Apr 2015 01:51:59 +0530
Title: Gmail
Username: myuser
URL: http://gmail.com
Comment: This is
+ an example of multiline comment.
+ It holds my Gmail secrets
Password: encrypted-CycHu08aE78gMvE4JIZ9kzVkiAQ=
All confidential fields will start with the word encrypted-
. Also note how the
Date field was populated automatically :) It is recommended that a single
password be used for all confidential fields (i.e. the password you enter at the
recins
prompt acts as a file-password, which remains the same for all
entries).
Reading the database
Selecting values in the database is performed by the recsel
program.
In the simplest case, we specify an expression (-e
) to match a certain
criteria:
recsel -p Title,Artist -e "Title = 'Suprabhatam'" music.rec
Album: Venkatesha Suprabhatam
Artist: M.S. Subbulakshmi
Note that the string to match must be enclosed in single quotes. Recutils has
the usual operators (<
, >
, =
, !=
, &&
, ||
, etc.) and operands
(strings, numbers) for filtering data. Currently, there is no option to list
all the fields and values matching the predicate; you must select the fields
using a comma-separated list for -p
.
recsel -t PasswordDB -p Username,Password mysecrets.rec
Password:
Username: myuser
Password: secret
In the first password prompt, you enter the file-level password that you gave
during the recins
invocation. The -p
options prints those fields (Username
and Password) from the PasswordDB.
Anyways, that’s all folks ! Hope this gave you a taste of Recutils and how easy it is to maintain records with it. Please read the entire GNU Recutils Manual for more detailed documentation.