Maneira correta de permitir que o usuário digite a senha para um script bash usando apenas a GUI (com o terminal oculto)

6

Eu fiz um script bash que usa o kdialog exclusivamente para interagir com o usuário. É lançado a partir de um arquivo ".desktop" para que o usuário nunca veja o terminal. Parece 100% como um aplicativo GUI (mesmo que seja apenas um script bash). Ele é executado apenas no KDE (Kubuntu 12.04).

Meu único problema é processar a entrada de senha com segurança e de maneira conveniente. Não consigo encontrar uma solução satisfatória.

O script foi projetado para ser executado como um usuário normal e para solicitar a senha quando um comando sudo for necessário primeiro. Dessa forma, a maioria dos comandos, aqueles que não exigem direitos de sudo, são executados como o usuário normal. O que acontece (quando o script é executado a partir do terminal) é que o usuário é solicitado a fornecer sua senha uma vez e o tempo limite padrão sudo permite que o script seja concluído, incluindo comandos adicionais do sudo, sem avisar o usuário novamente. É assim que eu quero que ele funcione quando executado atrás da GUI também.

O principal problema é que usar kdesudo para iniciar meu script, que é a maneira padrão de GUI, significa que o script inteiro é executado pelo usuário root. Portanto, as propriedades de arquivos são atribuídas ao usuário root, não posso confiar em ~/ em caminhos e muitas outras coisas são menos que ideais. Executar o script inteiro como o usuário root é apenas uma solução muito insatisfatória e acho que é uma prática ruim.

Agradeço todas as ideias para permitir que um usuário insira a senha sudo apenas uma vez por meio da GUI, sem executar o script inteiro como raiz. Obrigado.

    
por MountainX 29.06.2013 / 20:05

3 respostas

9

A opção -A sudo permite que você especifique um programa auxiliar (na variável SUDO_ASKPASS) que solicitará a senha.

Crie um script para perguntar a senha (myaskpass.sh):

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

Em seguida, insira esta linha no início do seu script:

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

e substitua todas as ocorrências de sudo <command> por:

sudo -A <command>

Você pode usar qualquer programa de solicitação de senha que desejar, em vez de zenity . Eu tive que encapsulá-lo dentro de um script porque SUDO_ASKPASS deve apontar para um arquivo, então não funcionará com a opção --password requerida por zenity .

O acima funciona como um encanto se for executado a partir da linha de comando ou se você escolher Executar no terminal após clicar duas vezes no arquivo de script no gerenciador de arquivos, mas se escolher Executar ou tente iniciá-lo a partir de um arquivo .desktop, cada sudo solicitará a senha novamente.

Se você não quiser uma janela de terminal, você pode armazenar a senha em uma variável e enviá-la para sudo -S . Talvez haja algumas preocupações de segurança, mas acho que é bastante seguro (leia os comentários em esta resposta ).

Insira esta linha no início do seu script:

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

e substitua todas as ocorrências de sudo <command> por:

echo -e $PASSWD | sudo -S <command>
    
por Eric Carvalho 29.06.2013 / 20:28
0

Isto é baseado na excelente resposta de Eric Carvalho. Estou postando para elaborar o problema que encontrei. Especificamente, ao usar isso, o tempo limite usual de sudo (por exemplo, 15 minutos) é perdido. Meu script, que tem mais de 50 comandos sudo, agora pede a senha do usuário mais de 50 vezes!

Aqui está um exemplo de trabalho completo de todas as partes da solução. Ele consiste em um script bash, um script "myaskpass", como sugerido por Eric, e um arquivo ".desktop". As coisas inteiras devem ser 100% GUI (nenhuma interação terminal), então o arquivo .desktop é essencial (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=

E um script de teste em si. Este pedirá sua senha duas vezes ao usar esta solução. (Normalmente, isso seria solicitado apenas uma vez devido ao tempo limite padrão do 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
    
por MountainX 30.06.2013 / 01:10
0

O script a seguir funciona via linha de comando, arquivo da área de trabalho ou clique duplo, solicita a senha apenas uma vez e o padrão de comando sudo -Sp '' <your command here> <<<${sudo_password} pode ser usado várias vezes em qualquer parte do arquivo:

    # 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}
    
por Sadi 31.05.2017 / 17:58