web-dev-qa-db-fra.com

Manière correcte de laisser l'utilisateur entrer le mot de passe pour un script bash en utilisant uniquement l'interface graphique (avec le terminal masqué)

J'ai créé un script bash qui utilise kdialog exclusivement pour interagir avec l'utilisateur. Il est lancé à partir d'un fichier ".desktop" afin que l'utilisateur ne voie jamais le terminal. Cela ressemble à 100% à une application graphique (même s'il ne s'agit que d'un script bash). Il fonctionne uniquement dans KDE (Kubuntu 12.04).

Mon seul problème est gérer le mot de passe en toute sécurité et facilement. Je ne trouve pas de solution satisfaisante.

Le script était conçu pour être exécuté en tant qu'utilisateur normal et pour demander le mot de passe lorsqu'une commande Sudo est requise pour la première fois. De cette manière, la plupart des commandes, celles ne nécessitant pas de droits Sudo, sont exécutées en tant qu'utilisateur normal. Ce qui se produit (lorsque le script est exécuté à partir du terminal) est que l'utilisateur est invité à entrer son mot de passe une fois et que le délai d'expiration Sudo par défaut permet au script de se terminer, y compris les commandes Sudo supplémentaires, sans que l'utilisateur ne soit invité à nouveau. C’est ainsi que je veux que cela fonctionne lorsque j’exécute aussi derrière l’interface graphique.

Le principal problème est que le fait d'utiliser kdesudo pour lancer mon script, qui est la méthode standard de l'interface graphique, signifie que l'intégralité du script est exécutée par l'utilisateur root. Ainsi, les droits de propriété des fichiers sont attribués à l'utilisateur root. Je ne peux pas compter sur ~/ dans les chemins d'accès, et bien d'autres choses sont loin d'être idéales. Exécuter le script en tant qu'utilisateur root n'est qu'une solution très peu satisfaisante et je pense que c'est une mauvaise pratique.

J'apprécie toutes les idées permettant à un utilisateur de saisir le mot de passe Sudo une seule fois via l'interface graphique sans exécuter le script en tant que root. Merci.

7
MountainX

L'option -A Sudo vous permet de spécifier un programme d'assistance (dans la variable Sudo_ASKPASS) qui demandera le mot de passe.

Créez un script pour demander le mot de passe (myaskpass.sh):

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

Puis insérez cette ligne au début de votre script:

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

et remplacez toutes les occurrences de Sudo <command> par:

Sudo -A <command>

Vous pouvez utiliser le programme demandant le mot de passe de votre choix au lieu de zenity. J'ai dû l'encapsuler dans un script car Sudo_ASKPASS doit pointer sur un fichier, de sorte qu'il ne fonctionnera pas avec l'option --password requise par zenity.

Ce qui précède fonctionne comme un charme s’il s’exécute en ligne de commande ou si vous choisissez Exécuter en mode terminal après avoir double-cliqué sur le fichier script dans le gestionnaire de fichiers, mais si vous choisissez Exécuter ou essayez de le lancer à partir d'un fichier .desktop chaque Sudo vous demandera à nouveau le mot de passe for.


Si vous ne voulez pas du tout une fenêtre de terminal, vous pouvez stocker le mot de passe dans une variable et le rediriger vers Sudo -S. Il y a peut-être des problèmes de sécurité, mais je pense que c'est assez sûr (lisez les commentaires sur cette réponse ).

Insérez cette ligne au début de votre script:

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

et remplacez toutes les occurrences de Sudo <command> par:

echo -e $PASSWD | Sudo -S <command>
12
Eric Carvalho

Ceci est basé sur l'excellente réponse d'Eric Carvalho. Je le poste pour élaborer sur le problème que j'ai rencontré. En particulier, lors de l’utilisation de cette option, le délai d’expiration Sudo habituel (par exemple 15 minutes) est perdu. Mon script, qui compte plus de 50 commandes Sudo, demande maintenant le mot de passe de l'utilisateur plus de 50 fois!

Voici un exemple complet de toutes les parties de la solution. Il se compose d'un script bash, d'un script "myaskpass" comme suggéré par Eric et d'un fichier ".desktop". Le tout doit être à 100% graphique (aucune interaction de terminal), le fichier .desktop est donc essentiel (autant que je sache).

$ 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=

Et un script de test lui-même. Celui-ci vous demandera votre mot de passe deux fois lorsque vous utiliserez cette solution. (Normalement, il ne demanderait qu'une fois en raison du délai d'expiration Sudo par défaut.)

#!/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
0
MountainX

Le script suivant fonctionne via une ligne de commande, un fichier du bureau ou un double-clic, demande le mot de passe une seule fois, et le modèle de commande Sudo -Sp '' <your command here> <<<${Sudo_password} peut être utilisé plusieurs fois dans le fichier:

    # 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}
0
Sadi