8 Week Progress Update for PGP Clean Room


During the last few weeks, I learned about internationalization in bash and did a lot of refactoring/decomposing of the UI code, making the code a lot more DRY.

…Internationalization…

This intro to Internationalization in Bash from the Linux Journal and this Slackware doc put me on the road to internationalizing the UI code I had written thus far.

Instead of hardcoding strings into the whiptail commands, like this:

PRIMARY_UID=$(whiptail --inputbox "$PRIMARY_UID_TEXT_EN" 8 78 --title "$PRIMARY_UID_TITLE_EN" 3>&1 1>&2 2>&3)

I set up a Message Catalog in a Portable Object file for English: en.po. The .po file contains msgid-msgstr key-value pairs:

msgid "EXPIRY_TEXT"
msgstr ""
"Please specify how long the key should be valid.\n"
"\t   0 = key does not expire\n"
"\t <n> = key expires in n days\n"
"\t<n>w = key expires in n weeks\n"
"\t<n>m = key expires in n months\n"
"\t<n>y = key expires in n years"

msgid "PRIMARY_UID_TITLE"
msgstr "Primary UID"

To make these .po files usable in a script, use the Linux utility msgfmt to turn .po files into Message Object files:

mkdir -p $HOME/project/locale/en_US/LC_MESSAGES/
msgfmt -o $HOME/project/locale/en_US/LC_MESSAGES/ui-strings.mo po/en.po

Now that we have a Message Object file, we can access the key value pairs in a script using the gettext command. Pass the name of the msgid as a string to get back the localized natural language string:

whiptail_yesno() {	
	whiptail --yesno "$(gettext $1)" $DIMENS --title "$(gettext $2)"
	return $?

if whiptail_yesno "ENCR_SUBKEY_YESNO_TEXT" "ENCR_SUBKEY_YESNO_TITLE"; then
...

In order for this to work, though, it’s important to export some environmental variables before running gettext. Mine look like:

export TEXTDOMAINDIR=$HOME/gpg-helper-scripts/locale
export TEXTDOMAIN=ui-strings
export LANG=en_US.UTF-8

…Refactoring/Reorganizing…

gpg-helper-scripts/
├─ gpg/
│    ├─ create_keys.sh
│    ├─ add_uids.py
├─ whiptail/
│    ├─ main_menu.sh
│    ├─ gen_keys.sh
│    ├─ smartcard_init.sh
│    ├─ whiptail_helper.sh
├─ po/
│    ├─ en.po
├─ locale/
│    ├─ en_US/LC_MESSAGES/ui-strings.mo
├─ details/
│    ├─ gpg-algos
│    ├─ smartcard-workflow
├─ init.sh
├─ README.md

While setting up whiptail functions I learned that one does not simply return values in bash. With the help of another Linux Journal article, I came up with:

whiptail_password() {
	__resultvar=$1	
	result=$(whiptail --passwordbox "$(gettext $2)" $DIMENS --title "$(gettext $3)" 3>&1 1>&2 2>&3)
	eval $__resultvar="'$result'"
}

to store user input as variables while keeping the code DRY.

I also looked a little bit at Google’s Shell Style Guide, gave my files better names and organized the directory structure.

…GPG…

I was curious about the correct abbreviations, key lengths and usages for all of the gpg2.1.16 supported algorithms so I created a reference in details/gpg-algos that will come in handy for validating the user’s input for different types of keys.

…Moving Forward…

Now that the code is much more readable, I can think more about the UI and the options that I want to include:

Lots more options could be added here.. Let me know your ideas.

Thanks for reading!

Related Posts

12 Week Progress Update for PGP Clean Room

Default and Custom Key Generation

10 Week Progress Update for PGP Clean Room

Developing Whiptail TUI... GIFs!

6 Week Progress Update for PGP Clean Room

Implementing smartcard functionality

4 Week Progress Update for PGP Clean Room

Using GPG 2.1.16 on Sid and more feature ideas

2 Week Progress Update for PGP Clean Room

Building a Whiptail TUI and using GPG 2.1.16

Applying to Debian for Outreachy 2016

Applying to the PKI Clean Room Project for Round 13 of Outreachy

Free and Awesome Programming Resources

Free video courses, interactive tutorials, project ideas, drills, and e-books for learning to code online