I have a shell script I wrote that needs sudo access only when needed. It uses Zenity for a GUI and runs without a termninal. The script was working fine but I had one issue with it. It uses Zenity to ask for user password and stores it in a variable. I didn't like how the password was stored as plain text in a variable so wanted to rewrite it to be more secure. Note that the password isn't stored inside the script, just inside a variable on demand.
I then considered to encrypt the password with a randomly generated key using OpenSSL which I tested as working. The only problem I had with that idea is there is a passcode with a passkey so anyone just needs to look at my script source and see how to decode it. Extract the variable contents and reveal it. So a bit like installing a keycode on your door and obfuscating the unlock code in the meter box. Just a deterrent but the info is still there. Perhaps I'm just being a bit over pedantic. :-)
I found I could could pipe the password directly from Zenity to sudo and verify it with "-vS" options. Great. There's still a pipe in between with plain text but at least it isn't stored in the process. I had that working fine. So changed my script to set a password flag. If the flag is set the credentials are confirmed.
I tested it as all working from a terminal. So then needed to test it running normally without the terminal. But it started failing.
My problems started when I wanted to validate the credentials. Whenever it needs another root operation it validates the credentials again just in case they timed out. But I found they failed. My script kept asking for a password again. This is seconds after logging in with "-vS" and already verifying it. It didn't make sense.
I then found that all other sudo operations kept failing. And all other file operations I needed to do returned fail from sudo as well. It seemed I was stuck with password plain text again. At this point using "-S" option works fine if I give it a password every time to run a command.
The following is my function that checks and verifies the password credentials:
get_password()
{
if [ $password -eq 1 ]; then
sudo -vn
if [ $? -ne 0 ]; then
password=0
fi
fi
if [ $password -eq 0 ]; then
zenity --title="$wt" --width=$ww --password | sudo -vS
if [ $? -ne 0 ]; then
zenity \
--title="$wt" \
--width=$qw \
--error \
--text="Error:\n\nThe password entered is incorrect."
return 1
else
password=1
fi
fi
return 0
}
The following are some file routines called once it has root access:
remove_file()
{
sudo rm "$1"
}
remove_folder()
{
sudo rm -R "$1"
}
When I found the problem I tested a few different versions of sudo I had on different Linux installs. All acted differently. I did a search for sudo bugs and didn't find anything specific to the behaviour I experienced. It would be good if there was some consistent behaviour I could rely on. But here are differences I found in return codes:
- 1.8.3p1-1: sudo -vS:0, sudo -vn:1, sudo cmd:1
- 1.8.9p5-1: sudo -vS:0, sudo -vn:0, sudo cmd:1
- 1.8.21p2-3: sudo -vS:0, sudo -vn:0, sudo cmd:0
- 1.9.13p3-3: sudo -vS:0, sudo -vn:0, sudo cmd:1
As you can see there is no consistency! The earliest only passes on verifying password through stdin and fails all else. The rest all pass on validation. But only one can run a command as root and it is not the newest one. On top of this I found on the newest it can work with sudo using rm for removing a file but not a folder. This is too confusing!
So is there any way around this? Are there any options I should be passing? I've read the manual and looked up guides. I've seen nothing to exactly describe this. I've tried using "-n" option to no avail. I've even tried sending a fake password with "-S" but it didn't like it. I'm somewhat stumped by this or I wouldn't be asking. I really don't want to go back to plain text passwords.
Pertaining to the sudoers config, this would be default. I have no need nor desire to modify this. This is also needs to work on other peoples systems so I consider it inappropriate to need any modification that way. The script is packaged as deb. So should be able to work as standard once installed.
I actually would have wrote a tutorial on using sudo in a background script without storing plain text passwords, with the research I've done, but since I cannot get it consistently work I won't be doing that yet. :-D