De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.
Colaboração: Rodolfo Broco Manin
Data de Publicação: 26 de Novembro de 2001
O Expect (http://expect.nist.gov/) é uma ferramenta para automatizacao de aplicacoes interativas. Ele implementa uma linguagem de scripting similar ao tcl, porem com comandos adicionais para interagir com os aplicativos "no lugar do usuario", i.e.: "ler" prompts e mensagens de certos programas, tomar decisoes baseadas nelas e "digitar" os comandos necessarios.
Encontrei esse utilitario quando estava desenvolvendo uma pagina para troca de senha via web, e precisei de um metodo para fazer a troca nao-interativa da senha do usuario. Passwd, chpass & cia nao funcionam com pipes (eles utilizam a funcao getpass(), que só le a senha da entrada padrao se /dev/tty nao estiver disponivel).
Estou enviando em attach o script que fiz (estah sendo chamado via popen(), de uma pagina experimental com php). Ele le da entrada padrao o login, a senha atual e a nova senha do usuario (nessa ordem), efetua um telnet para a maquina local e executa o passwd. O script troca a senha de contas expiradas tambem (quando o proprio login chama o passwd), e tem a vantagem de ser "suid-free" :). Se alguem quiser usar, é só dar uma revisada, para compatibiliza-lo com as mensagens do passwd, o prompt do shell do sistema, etc.
#!/usr/local/bin/expect -f ############################################################################## # Script para troca nao-interativa de senhas # # Rodolfo Broco Manin - 14/09/2001 # #----------------------------------------------------------------------------# # Codigos de erro: # # - Referentes ao login inicial via telnet: # # 110 - Login ou Senha incorreta # # 198 - Timeout # # 199 - Finalizacao inesperada # # - Referentes aa troca de senha # # 210 - Senha nova invalida # # 220 - Impossivel trocar a senha (erro generico) # # 298 - Timeout # # 299 - Finalizacao inesperada # ############################################################################## # --- Variaveis configuraveis --- # Linha de comando para o 'telnet' set telnet_cmd "/usr/bin/telnet" # Linha de comando para o 'passwd' set passwd_cmd "/usr/bin/passwd" # Host a ser contactado pelo 'telnet' (em geral, o proprio 'localhost') set login_host "localhost" # ------------------------------- # --- Parametros da sessao --- set timeout 10 # Parece que funciona melhor assim... set stty_init -nottycopy # Soh para garantir set env(TERM) vt100 # Nao mostra ao usuario as respostas dos comandos log_user 0 # Exibe mensagem de ajuda, caso o usuario informe algum parametro na linha de comandos if [ expr $argc > 0 ] then { send_user "\n$argv0: Script para troca nao-interativa de senhas.\ \n Execute este script sem parametros, e infrome o login do usuario,\ \n sua senha atual e uma nova senha (nessa ordem, via entrada padrao).\n\n" exit } # Obtem os dados da conta do usuario da entrada padrao gets stdin login gets stdin old_password gets stdin new_password # Inicia a sessao com um cabecalho informativo, proprio para ser redirecionado # para um arquivo de log set timestr [clock format [clock seconds] -format "%d/%m/%Y - %T (%Z)"] send_user "\n----------= Iniciando sessao para troca de senha =----------\n" send_user " * Usuario: $login ----- $timestr\n\n" send_user "Iniciando sessao telnet (host: $login_host)...\n" spawn $telnet_cmd $login_host # Um breve delay para aguardar pela conexao sleep 2 # Efetua o login expect { "ogin:" { send_user " * Enviando login...\n" send "$login\r" # Sessao finalizada por timeout (ex.: servidor NIS ou NFS fora do ar) } timeout { send_user " - Timeout durante a conexao.\n" exit 198 # Sessao abortada inesperadamente (ex.: expect e telnet nao conseguiram se entender) } eof { send_user " - Finalizacao inesperada durante a conexao.\n" exit 199 } } # Finalizacao do login / interacao com o 'passwd' expect { # Espera prompt para senha de login "Password:" { send_user " * Enviando senha...\n" send "$old_password\r" exp_continue # Erros diversos que impedem a troca de senha (ex.: senha nova vazia) # (deve estar antes das linhas que testas os prompts do shell e do 'passwd) } "unchanged" { send_user " - Nao foi possivel efetuar a troca de senha.\n" exit 220 # Informa a senha antiga, solicitada apos a execucao do 'passwd' # ou logo apos o login, caso a senha esteja expirada } "Old" { send_user "\nEfetuando troca de senha:\n * Informando a senha antiga...\n" send "$old_password\r" exp_continue # Trata respostas do sistema a senhas novas invalidas # (deve estar antes da linha que testa o prompt 'New password') } "Please" { send_user " - Senha nova invalida.\n" exit 210 # Informa a senha nova } -r "New|Retype" { send_user " * Informando a senha nova / Confirmacao...\n" send "$new_password\r" exp_continue # Concluiu a troca de senha # (deve estar antes da linha que testa o prompt do shell) } "done" { send_user " + Troca de senha efetuada!\n" exit 0 # Executa 'passwd' caso obtenha-se o prompt do shell } "$login@" { send_user " + Login concluido.\n" send "$passwd_cmd\r" exp_continue # Testa login invalido } "ogin incorrect" { send_user " - Login ou Senha atual incorreta.\n" exit 110 # Timeout e eof em geral nao acontecem aqui, mas... } timeout { send_user " - Timeout durante a troca de senha.\n" exit 298 } eof { send_user " - Finalizacao inesperada durante a troca de senha.\n" exit 299 } }
This policy contains information about your privacy. By posting, you are declaring that you understand this policy:
This policy is subject to change at any time and without notice.
These terms and conditions contain rules about posting comments. By submitting a comment, you are declaring that you agree with these rules:
Failure to comply with these rules may result in being banned from submitting further comments.
These terms and conditions are subject to change at any time and without notice.
Comentários