Правильный способ разрешить пользователю вводить пароль для скрипта bash, используя только графический интерфейс (со скрытым терминалом)

Я создал bash-скрипт, который использует kdialog исключительно для взаимодействия с пользователем. Он запускается из файла ".desktop", поэтому пользователь никогда не видит терминал. Это выглядит на 100% как приложение с графическим интерфейсом (хотя это всего лишь скрипт bash). Он работает только в KDE (Kubuntu 12.04).

Моей единственной проблемой является безопасная и удобная обработка ввода пароля . Я не могу найти удовлетворительное решение.

Сценарий был разработан для запуска в качестве обычного пользователя и для запроса пароля, когда команда sudo требуется в первый раз. Таким образом, большинство команд, не требующих прав sudo, запускаются как обычный пользователь. Что происходит (когда скрипт запускается из терминала), так это то, что у пользователя запрашивается пароль один раз, а тайм-аут sudo по умолчанию позволяет скрипту завершиться, включая любые дополнительные команды sudo, без повторного запроса пользователя. Вот как я хочу, чтобы это работало и при запуске за графическим интерфейсом.

Основная проблема заключается в том, что использование kdesudo для запуска моего сценария, который является стандартным способом графического интерфейса пользователя, означает, что весь сценарий выполняется пользователем root. Таким образом, владение файлами назначается пользователю root, я не могу полагаться на ~/ в путях, а многие другие вещи не идеальны. Выполнение всего сценария от имени пользователя root - это просто очень неудовлетворительное решение, и я считаю, что это плохая практика.

Я ценю любые идеи, позволяющие пользователю вводить пароль sudo только один раз через графический интерфейс, при этом не запуская весь сценарий от имени пользователя root. Благодаря.

8
задан 13 April 2017 в 15:37

3 ответа

Следующий скрипт работает через командную строку, файл рабочего стола или двойной щелчок, запрашивает пароль только один раз, а шаблон команды sudo -Sp '' <your command here> <<<${sudo_password} может использоваться несколько раз в любом месте файла:

    # 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
ответ дан 13 April 2017 в 15:37

Это основано на превосходном ответе Эрика Карвалью. Я публикую это, чтобы уточнить проблему, с которой я столкнулся. В частности, при использовании этого обычного тайм-аута sudo (например, 15 минут) теряется. Мой сценарий, содержащий более 50 команд sudo, теперь запрашивает пароль пользователя более 50 раз!

Вот полный рабочий пример всех частей решения. Он состоит из сценария bash, сценария "myaskpass", как предложил Эрик, и файла ".desktop". Все это должно быть на 100% графическим интерфейсом пользователя (вообще никакого взаимодействия с терминалом), поэтому файл .desktop необходим (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=

И сам тестовый скрипт. Этот пользователь дважды запросит ваш пароль при использовании этого решения. (Обычно он запрашивает только один раз из-за тайм-аута 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
0
ответ дан 13 April 2017 в 15:37

Параметр sudo -A позволяет указать вспомогательную программу (в переменной SUDO_ASKPASS), которая будет запрашивать пароль.

Создайте сценарий для запроса пароля (myaskpass.sh):

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

Затем вставьте эту строку в начало вашего сценария:

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

и замените все вхождения sudo <command> с:

sudo -A <command>

Вы можете использовать любую программу запроса пароля вместо zenity. Мне пришлось заключить его в сценарий, поскольку SUDO_ASKPASS должен указывать на файл, поэтому он не будет работать с опцией --password, требуемой для zenity.

Вышеописанное работает как талисман, если он запускается из командной строки или если вы выбираете Запускать в терминале после двойного щелчка по файлу скрипта в файловом менеджере, но если вы выбираете Выполнить или попробуйте запустить его из файла .desktop, каждый sudo снова запросит пароль.


Если вам вообще не нужно окно терминала, вы можете сохранить пароль в переменной и направить его в sudo -S. Может быть, есть некоторые проблемы с безопасностью, но я думаю, что это довольно безопасно (прочитайте комментарии к этому ответу ).

Вставьте эту строку в начале вашего сценария:

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

и замените все вхождения sudo <command> на:

echo -e $PASSWD | sudo -S <command>
0
ответ дан 13 April 2017 в 15:37

Другие вопросы по тегам:

Похожие вопросы: