10

I have made a bash script that uses kdialog exclusively for interacting with the user. It is launched from a ".desktop" file so the user never sees the terminal. It looks 100% like a GUI app (even though it is just a bash script). It runs in KDE only (Kubuntu 12.04).

My only problem is handling password input securely and conveniently. I can't find a satisfactory solution.

The script was designed to be run as a normal user and to prompt for the password when a sudo command is first needed. In this way, most commands, those not requiring sudo rights, are run as the normal user. What happens (when the script is run from the terminal) is that the user is prompted for their password once and the default sudo timeout allows the script to finish, including any additional sudo commands, without prompting the user again. This is how I want it to work when run behind the GUI too.

The main problem is that using kdesudo to launch my script, which is the standard GUI way, means that the entire script is executed by the root user. So file ownerships get assigned to the root user, I can't rely upon ~/ in paths, and many other things are less than ideal. Running the entire script as the root user is just a very unsatisfactory solution and I think it is a bad practice.

I appreciate any ideas for letting a user enter the sudo password just once via GUI while not running the whole script as root. Thanks.

3 Answers 3

19

The -A sudo option allows you to specify a helper program (in the SUDO_ASKPASS variable) that will ask for the password.

Create a script to ask the password (myaskpass.sh):

#!/bin/bash
zenity --password --title=Authentication

Then insert this line at the beginning of your script:

export SUDO_ASKPASS="/path/to/myaskpass.sh"

and replace all occurences of sudo <command> with:

sudo -A <command>

You can use whatever password asking program you want instead of zenity. I had to encapsulate it within a script because SUDO_ASKPASS must point to a file, so it won't work with the --password option required by zenity.

The above works like a charm if it runs from command line or if you choose Run in terminal after double click the script file in the file manager, but if you choose Run or try to launch it from a .desktop file every sudo will ask for the for password again.


If you don't want a terminal window at all, you can store the password in a variable and pipe it to sudo -S. Maybe there's some security concerns, but I think it's pretty safe (read the comments on this answer).

Insert this line at the beginning of your script:

PASSWD="$(zenity --password --title=Authentication)\n"

and replace all occurences of sudo <command> with:

echo -e $PASSWD | sudo -S <command>
3
  • Thank you. That's very interesting. However, when using this the usual sudo timeout (e.g., 15 minutes) is lost. My script, which has over 50 sudo commands now prompts for the user's password 50+ times! I googled around a bit and I didn't see a solution. Do you know one?
    – MountainX
    Jun 29, 2013 at 23:03
  • Thanks for the update. The alternative you suggest is something I had ruled out due to security concerns, but from reading the comments at the link you provided, I think it is probably secure enough. And it is an easy way to solve the issue. Thank you.
    – MountainX
    Jun 30, 2013 at 2:24
  • Testing on my system it has to be sudo -s (lower-case s) and not sudo -S (upper-case s). Jan 5, 2017 at 1:00
1

This is based on Eric Carvalho's excellent answer. I am posting it to elaborate on the problem I encountered. Specifically, when using this the usual sudo timeout (e.g., 15 minutes) is lost. My script, which has over 50 sudo commands now prompts for the user's password 50+ times!

Here are full working example of all parts of the solution. It consists of a bash script, a "myaskpass" script as Eric suggested, and a ".desktop" file. The whole things should be 100% GUI (no terminal interaction at all), so the .desktop file is essential (afaik).

$ cat myaskpass.sh 
#!/bin/bash
kdialog --password "Please enter your password: "
exit 0


$ cat askpasstest1.desktop 
#!/usr/bin/env xdg-open
[Desktop Entry]
Comment=SUDO_ASKPASS tester1
Exec=bash /home/user/test/askpasstest1.sh
GenericName=SUDO_ASKPASS tester1
Name=SUDO_ASKPASS tester1
NoDisplay=false
Path[$e]=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
Categories=Application;Utility;
X-KDE-SubstituteUID=false
X-KDE-Username=

And a test script itself. This one will ask for your password twice when using this solution. (Normally, it would ask only once due to the default sudo timeout.)

#!/bin/bash

sudo -k
SUDO_ASKPASS="/home/user/test/myaskpass.sh" sudo -A touch filemadeas_askpass1
touch filemadeas_regularuser1
SUDO_ASKPASS="/home/user/test/myaskpass.sh" sudo -A touch filemadeas_askpass2
touch filemadeas_regularuser2
ls -la filemadeas* > /home/user/test/fma.log
kdialog --title "Files Created" --textbox /home/user/test/fma.log 640 480
sudo rm filemadeas_*
rm fma.log

exit 0
3
  • Running this script from command line, the password is asked only once. Running from GUI (clicking .desktop or .sh in file manager) every sudo -A reasks the password. I'll try to figure this out. Jun 29, 2013 at 23:52
  • I just updated my answer. Jun 30, 2013 at 2:19
  • Eric... did you figure out a solution to the problem?
    – anthony
    May 17, 2017 at 2:04
0

The following script works via command line, desktop file or double-click, asks for the password only once, and the command pattern sudo -Sp '' <your command here> <<<${sudo_password} can be used multiple times anywhere in the file:

    # get sudo password
    sudo_password=$( gksudo --print-pass --message="Provide permission to make system changes: Type your password or press Cancel." -- : 2>/dev/null )
    # check for null entry or cancellation
    if [[ ${?} != 0 || -z ${sudo_password} ]]
    then
        exit 4
    fi
    if ! sudo -kSp '' [ 1 ] <<<${sudo_password} 2>/dev/null
    then
        exit 4
    fi
    # command
    sudo -Sp '' gedit "/etc/hosts" <<<${sudo_password}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .