Passar Senha Para O Sudo Pela Entrada Padrão

Introdução

Quem nunca precisou usar o sudo dentro de um shell script e percebeu que não é possível passar a senha pela entrada padrão? Se você alguma vez já fez:

$ echo 'minhasenha' | sudo su

percebeu que o sudo se recusa a ler a senha enviada pelo echo e continua a mostrar o prompt de leitura da senha.

Nesse post iremos aprender como passar a senha de um usuário para o sudo usando a entrada padrão.

A Manpage

Lendo a manpage do sudo vemos a seguinte opção:

-S          The -S (stdin) option causes sudo to read the password from
the standard input instead of the terminal device.  The
password must be followed by a newline character.

Essa opção permite a passagem da senha pela entrada padrão e a única exigência é que deve haver um ‘\n’ no fim da senha.

Usando a opção -S do sudo

Para testar essa opção, suponha que o usuário atual tem senha “minhasenha” e que ele deseja executar um comando qualquer como root. Assim, o seguinte comando deve ser digitado:

$ echo 'minhasenha' | sudo -S id
uid=0(root) gid=0(root) groups=0(root),3(sys),7(lp)

Veja que o comando id foi executado como root (uid=0).

Nota sobre segurança

Usar a dupla de comandos echo + sudo -S não é muito seguro, pois a senha fica disponível em clean text para qualquer usuário com permissão de leitura em seu script. Por causa disso, aconselho a não usar esse tipo de sintaxe para não expor sua senha para pessoas indesejáveis, mesmo que só você use o seu sistema.

Qual o objetivo da opção -S ?

Se usar a sintaxe echo+sudo pode expor a senha para outros usuários então por que criaram essa opção? O objetivo dessa opção é para que um programa gráfico de autenticação passe a senha para o sudo sem que a senha em si seja mostrada. Usando um programa gráfico ao invés de um simples echo faz com que a senha seja lida dinamicamente não precisando armazená-la no código fonte do script.

zenity + sudo

Para exemplificar um uso ideal da opção -S, vou montar um simples programinha gráfico de autenticação em shell script:

#!/bin/bash
# Autor: Marcos Paulo Ferreira (daemonio)
# undefinido gmail com
# daemoniolabs.wordpress.com
#
# [zensudo.sh]
# Script que simula uma autenticação usando
# o zenity e o sudo.
#
# OBS: Executar o sudo em seu próprio usuário, a senha
# não é verificada. Executar o script mais de uma
# vez em um curto intervalo de tempo, implica no sudo nem
# considerar a senha de entrada.
# Isso porque o sudo tem um tempo que ele fica sem pedir a senha.
#
# Qui Out 20 18:36:37 BRST 2011
#

while true
do
    resp=$(zenity --password)

    # Pega a senha do login gráfico
    senha=$(echo "$resp" | cut -f1 -d'|')

    # Passa a senha
    echo $senha | sudo -S -u root zenity --info --text "Bem vindo: r00t" 1 2>/dev/null && exit

    # Perguntar se quer tentar novamente.
    zenity --question --text 'Erro. Tentar novamente?'

    # Sair se pressionou cancelar.
    (( $? )) && exit
done

#EOF

Para usar:

$ ./zensudo.sh

Digite sua senha e se tudo ocorrer corretamente, a mensagem “Bem vindo: r00t” aparecerá na sua tela.

Opção -A do sudo

O sudo pode invocar um login gráfico através da opção -A e desse modo, dispensando o uso da opção -S:

Primeiro, deve-se criar o script gráfico que passará a senha para o sudo:

$ chmod +x /tmp/logingrafico
$ cat /tmp/logingrafico
#!/bin/bash
zenity --password

Depois devemos setar a variável SUDO_ASKPASS com o nome do script:

$ export SUDO_ASKPASS='/tmp/logingrafico'

Em seguida, basta chamar o sudo com a opção -A e também passar o comando que se deseja executar como root:

$ sudo -A id
# digite a senha no login gráfico
uid=0(root) gid=0(root) groups=0(root),3(sys),7(lp)

Conclusão

O utilitário sudo é indispensável na utilização de sistemas *nix, pois facilita bastante a troca de usuários para a execução de comandos. Uma de suas opções permite que o usuário passe a sua própria senha pela entrada padrão. Porém, não é aconselhável passar a senha em texto limpo, via echo por exemplo, e sempre que possível, utilizar-se de uma aplicação gráfica para isso.

Referências

[1] sudo: lendo a senha automaticamente através de shell script by Valter Ferraz Sanches (Acessado em: Outubro/2011)
http://www.vivaolinux.com.br/dica/sudo-lendo-a-senha-automaticamente-atraves-de-shell-script

5 pensamentos sobre “Passar Senha Para O Sudo Pela Entrada Padrão

  1. Olá amigo! Não estou conseguindo obter exito com este script:

    sudo -k | \
    zenity –entry \
    –width=200 \
    –height=80 \
    –title=”SENHA DE USUÁRIO” \
    –text=”Entre com a senha aqui abaixo:” \
    –entry-text “” \
    –hide-text | sudo -S aptitude purge linux-image-$ESC | zenity –list –title “KernelClean” –text ” Iniciando processo de remoção…\n” –column “Status” –width=700 –height=400
    fi

    Recebe a senha do zenity ( entrada padrão ) inicia o processo e de repente dá a informação:

    Gostaria de remover? [Y/N].Abortar

    E não consigo resolver isto. Ja tentei de várias formas, li o man do sudo e coisa e tal, mas nada. Pode me ajudar se puder? Agradeço a atenção!
    Wilson

    • Olá Wilson,

      Acredito que o único problema esteja no segundo zenity. Ele só vai ser executado se o sudo retornar sucesso, ou seja,
      se a senha foi verificada. Para isso, troque o | por && (AND). Fica assim:

      #!/bin/bash
      zenity –entry \
      –width=200 \
      –height=80 \
      –title=”SENHA DE USUÁRIO” \
      –text=”Entre com a senha aqui abaixo:” \
      –entry-text “” \
      –hide-text | sudo -S aptitude purge linux-image-$ESC && zenity –list –title “KernelClean” –text ” Iniciando processo de remoção…\n” –column “Status” –width=700 –height=400

      Quando digito a senha correta, o aptitude é executado como root e no mesmo instante a tela do zenity aparece.

      Penso que seja isso.
      Abraços.

  2. Tudo bem, Daemonio ?

    Obrigado pela prontidão do seu tempo! O problema está na realidade com o aptitude em relação a senha vinda do zenity. Mesmo trocando o pipe por && (AND), nada se alterou. Consultei hoje o livro (Linux, Prática e Certificação LPI) do Bonan e encontrei a solução, ao menos eficiente para esta situação e que resolveu o impasse. Ao invés de utilizar o aptitude eu utilizo o “dpkg –purge” que além de remover o kernel, também remove arquivos de configuração por completo, tendo praticamente o mesmo efeito. O mais curioso é que o comando (sudo aptitude purge linux-image…) executado diretamente no terminal funciona perfeitamente, mas vindo do zenity esbarra na questão que você me alertou apropriadamente a despeito do retorno da verificação da senha, que não sei por que cargas d’agua não funciona nem com reza brava. Mas o mais importante é que houve como resolver! Deixo aqui no teu site a “Dica/solução” caso alguém mais passe pelo mesmo problema. E mais uma vez obrigado pela ajuda e um grande abraço amigo.

    sudo -k | \
    zenity –entry \
    –width=200 \
    –height=80 \
    –title=”SENHA DE USUÁRIO” \
    –text=”Entre com a senha aqui abaixo:” \
    –entry-text “” \
    –hide-text | sudo -S dpkg –purge linux-image-$ESC | zenity –list \
    –title “KernelClean” \
    –text “Iniciando processo de remoção…\n” \
    –column “Status” –width=700 –height=400

    • Olá Wilson,

      Pela resposta que te dei, nem pensei que a saída do aptitude era para ser a entrada do zenity. Aí nesse caso nem faria sentido usar o ‘&&’, tinha que ser o pipe mesmo. ;)

      Como estou usando Fedora, aí não tem como eu executar os comandos que você me passou (aptitude, dpkg, etc). Mas o mais importante é que você já resolveu o problema. Fica aqui a solução para que está passando por isso.

      Abraços.

Deixe um comentário