Automation secure input and saving of encrypted passwords in Linux configs. We are writing a script in Python

Ivan Piskunov
4 min readJun 21, 2022

How to bring your system to a new level of security with python modules-gnupg and getpass4.

With increasing security requirements, creating and storing passwords can raise questions not only for users, but also for developers and system administrators. Experts and other knowledgeable people know that passwords need to be stored in encrypted form. Even at the stage of entering the password characters should be hidden from any eyes (even from the person who enters it). Can we always meet at least these requirements?

I am the only user of my laptop, and on board it runs the Linux OS family. So I don’t worry about users who might accidentally or accidentally view my configuration files while working on the same computer. I decided to mess around and increase the security of my personal laptop, and for good reason. Yes, I encrypt my home directory, but as soon as I log in, any password stored in plain text in the configuration file can potentially be vulnerable to prying eyes.

Well, if an attacker suddenly gets hold of my laptop or otherwise gains access to the system, they will not be able to get my password without a fight, just by running cat to view logs and configs.

Finding a solution to the problem

I decided that the best way to protect my Mutt password was to enter the password from the keyboard, save it in an encrypted GPG file, write a Python decryption script for my GPG password, and at the same time ensure that the Mutt password is passed to the offlineimap script that I use to sync my laptop locally with the mail server.

From the subtitle of the article, it is clear that I will use the python modules-gnupg and getpass. The Python module python-gnupg is a wrapper for the gpg encryption tool. Note that python-gnupg should not be confused with a module calledgnupg. GnuPG (GPG) is an encryption utility for Linux, and I’ve been using it since 2009 or so. I feel comfortable with her and believe in her safety.

Getting user input using Python is quite simple. You call input, and everything that the user enters is stored in a variable:

print("Enter password: ")myinput = input()

print("You entered: ", myinput)

And in this case, there is one huge problem: when I enter the password in the terminal, everything I type is visible to everyone who looks over my shoulder or looks at the history of my terminal:

$ ./test.py
Enter password: my-Complex-Passphrase

Writing a script with python-gnupg and getpass

As is often the case, you don’t need to write anything yourself, because there is already a Python module that allows you to solve the problem. This is a modulegetpass4. From the user’s point of view, it behaves exactly like any standard input prompt, except that it doesn’t display the characters you entered.

Install both modules using pip:

$ python -m pip install --user \
python-gnupg getpass4

I got this script to create a password with invisible input and decryption:

#!/usr/bin/env python
# by Seth Kenlon
# GPLv3

# install deps:
# python3 -m pip install --user python-gnupg getpass4

import gnupg
import getpass
from pathlib import Path

def get_api_pass():
homedir = str(Path.home())
gpg = gnupg.GPG(gnupghome=os.path.join(homedir,".gnupg"), use_agent=True)
passwd = getpass.getpass(prompt="Enter your GnuPG password: ", stream=None)

with open(os.path.join(homedir,'.mutt','pass.gpg'), 'rb') as f:
apipass = (gpg.decrypt_file(f, passphrase=passwd))

f.close()

return str(apipass)

if __name__ == "__main__":
apipass = get_api_pass()
print(apipass)

Save the file as password_prompt.py, if you want to try the script yourself. If you want to use offlineimap with it, specify the name and path to the script with the password in the .offlineimaprc configuration file (I have it ~/.mutt/password_prompt.py). However, there is something else to be done there, but more on that later.

Testing a script with gpg

I hope you already have gpg installed, as we will now be creating an encrypted password file and testing the script.

Encrypt it:

$ echo "hello world" > pass
$ gpg --encrypt pass
$ mv pass.gpg ~/.mutt/pass.gpg
$ rm pass

Running the previously created script:

$ python ~/.mutt/password_prompt.py
Enter your GPG password:
hello world

Hurray! Nothing is displayed when you enter it, but if you enter the password correctly (you need to enter hello world), you will see the test message “hello world”on the next line. It is also the password obtained as a result of decrypting the ~/.mutt/pass.gpg file. This means that the script is working correctly.

Integration with offlineimap

I chose Python because I knew that offlineimap can call scripts written in Python. If you’re already using offlineimap, you’ll realize that the only “integration” you need is to change two lines in your file .offlineimaprc (more precisely, to add one line and change another).

First, add a line that links to our script file:

pythonfile = ~/.mutt/password_prompt.py

Now, instead of the password in the line with remotepasseval after the “ = “ sign, call the get_api_pass () function that lives in the script password_prompt.py:

remotepasseval = get_api_pass()

Everything! Now no one can read the password from your configuration file!

Security gives you freedom

Sometimes I feel paranoid: I think a lot about the intricacies of security on my personal computer. Does the SSH config really need to have chmod 600 permissions? Does it really matter that the email password is in a configuration file hidden in a hidden folder called, oddly enough,. mutt? Although you can write a similar script in Python for other configuration files.

Knowing that my configuration files are missing unencrypted sensitive data makes it much easier for me to post files to public Git repositories, copy and paste snippets on forums, and share my knowledge in the form of up-to-date, working configuration files. From this point of view, the increased security level has made my life easier. And with so many Python modules for all occasions, it was easy enough to do this.

--

--

Ivan Piskunov

DevSecOps expert, Security Evangelist, Researcher, Speaker, Book’s author