Właściwy sposób, aby pozwolić użytkownikowi na wprowadzenie hasła do skryptu bash przy użyciu tylko GUI (z ukrytym terminalem)

8

Stworzyłem skrypt bash, który używa kdialog wyłącznie do interakcji z użytkownikiem. Jest uruchamiany z pliku „.desktop”, więc użytkownik nigdy nie widzi terminala. Wygląda w 100% jak aplikacja GUI (mimo że jest to tylko skrypt bash). Działa tylko w KDE (Kubuntu 12.04).

Moim jedynym problemem jest bezpieczne i wygodne wprowadzanie hasła . Nie mogę znaleźć zadowalającego rozwiązania.

Skrypt został zaprojektowany do działania jako zwykły użytkownik i monitowania o hasło, gdy polecenie sudo jest po raz pierwszy potrzebne. W ten sposób większość poleceń, które nie wymagają uprawnień sudo, są uruchamiane jako zwykły użytkownik. To, co się dzieje (gdy skrypt jest uruchamiany z terminala), polega na tym, że użytkownik jest proszony o podanie hasła raz, a domyślny limit czasu sudo pozwala na zakończenie skryptu, łącznie z wszelkimi dodatkowymi poleceniami sudo, bez ponownego monitowania użytkownika. Tak właśnie chcę, żeby działało, gdy działa za GUI.

Główny problem polega na tym, że użycie kdesudodo uruchomienia mojego skryptu, który jest standardowym sposobem GUI, oznacza, że ​​cały skrypt jest wykonywany przez użytkownika root. Własności plików są przypisywane do użytkownika root, więc nie mogę polegać na ~/ścieżkach, a wiele innych rzeczy jest mniej niż idealnych. Uruchamianie całego skryptu jako użytkownik root jest po prostu bardzo niezadowalającym rozwiązaniem i myślę, że to zła praktyka.

Doceniam wszelkie pomysły na to, aby użytkownik mógł wprowadzić hasło sudo tylko raz za pośrednictwem GUI, nie uruchamiając całego skryptu jako root. Dzięki.

MountainX
źródło

Odpowiedzi:

14

Opcja -Asudo pozwala określić program pomocniczy (w zmiennej SUDO_ASKPASS), który będzie pytał o hasło.

Utwórz skrypt, aby zapytać o hasło (myaskpass.sh):

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

Następnie wstaw ten wiersz na początku skryptu:

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

i zamień wszystkie wystąpienia na sudo <command>:

sudo -A <command>

Zamiast tego możesz użyć dowolnego programu pytającego o hasło zenity. Musiałem umieścić go w skrypcie, ponieważ SUDO_ASKPASS musi wskazywać na plik, więc nie będzie działać z --passwordopcją wymaganą przez zenity.

Powyższe działa jak urok, jeśli działa z wiersza polecenia lub jeśli wybierzesz Uruchom w terminalu po dwukrotnym kliknięciu pliku skryptu w menedżerze plików, ale jeśli wybierzesz Uruchom lub spróbuj uruchomić go z pliku .desktop, każdy sudopoprosi o po hasło ponownie.


Jeśli nie chcesz w ogóle okna terminala, możesz przechowywać hasło w zmiennej i przesyłać je do potoku sudo -S. Być może istnieją pewne obawy dotyczące bezpieczeństwa, ale myślę, że jest to dość bezpieczne (przeczytaj komentarze do tej odpowiedzi ).

Wstaw ten wiersz na początku skryptu:

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

i zamień wszystkie wystąpienia na sudo <command>:

echo -e $PASSWD | sudo -S <command>
Eric Carvalho
źródło
Dziękuję Ci. To bardzo interesujące. Jednak podczas korzystania z tego traci się zwykły limit czasu sudo (np. 15 minut). Mój skrypt, który ma ponad 50 poleceń sudo, teraz prosi o hasło użytkownika ponad 50 razy! Trochę googlowałem i nie widziałem rozwiązania. Czy znasz jeden
MountainX
Dziękuję za aktualizację. Sugerowana przez ciebie alternatywa jest czymś, co wykluczyłem ze względów bezpieczeństwa, ale po przeczytaniu komentarzy pod podanym linkiem myślę, że jest to prawdopodobnie wystarczająco bezpieczne. Jest to łatwy sposób na rozwiązanie problemu. Dziękuję Ci.
MountainX
Testowanie w moim systemie musi być sudo -s(małe litery s), a nie sudo -S(wielkie litery s).
WinEunuuchs2Unix
0

Jest to oparte na doskonałej odpowiedzi Erica Carvalho. Zamieszczam go w celu wyjaśnienia napotkanego problemu. W szczególności podczas korzystania z tego traci się zwykły limit czasu sudo (np. 15 minut). Mój skrypt, który ma ponad 50 poleceń sudo, teraz prosi o hasło użytkownika ponad 50 razy!

Oto pełny przykładowy przykład wszystkich części rozwiązania. Składa się ze skryptu bash, skryptu „myaskpass”, jak sugerował Eric, i pliku „.desktop”. Wszystko powinno być w 100% GUI (bez interakcji terminalu), więc plik .desktop jest niezbędny (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=

I sam skrypt testowy. Podczas korzystania z tego rozwiązania ten poprosi o podanie hasła dwukrotnie. (Zwykle pytałby tylko raz ze względu na domyślny limit czasu sudo).

#!/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
MountainX
źródło
Po uruchomieniu tego skryptu z wiersza polecenia hasło jest zadawane tylko raz. Uruchamianie z GUI (kliknięcie .desktop lub .sh w menedżerze plików) sudo -Apowoduje ponowne podanie hasła. Spróbuję to rozgryźć.
Eric Carvalho
Właśnie zaktualizowałem swoją odpowiedź.
Eric Carvalho,
Eric ... wymyśliłeś rozwiązanie problemu?
Anthony
0

Poniższy skrypt działa za pośrednictwem wiersza polecenia, pliku na pulpicie lub dwukrotnego kliknięcia, pyta o hasło tylko raz, a wzorca polecenia sudo -Sp '' <your command here> <<<${sudo_password}można użyć wiele razy w dowolnym miejscu pliku:

    # 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}
Sadi
źródło