web-dev-qa-db-ja.com

期待スクリプトにパスワードの入力を求めるにはどうすればよいですか?

Sshを介していくつかのルーターに接続するexpectスクリプトがあります。これらのルーターはすべて同じパスワードを持っており(私は知っています、それは間違っています)、ルーターに接続できるようにするには、スクリプトがそのパスワードを知っている必要があります。現在、パスワードはコマンドラインの引数としてスクリプトに渡されていますが、これは、.bash_historyファイルと実行中のプロセスにそのパスワードの痕跡があることを意味します。その代わりに、可能であればサイレントに、ユーザーにパスワードの入力を求めてもらいたいと思います。

期待値を使用してユーザーにパスワードの入力を求めることができるかどうかを知っていますか?

ありがとうございました。

編集:ルーターではなくサーバーに接続している場合、パスワードではなくsshキーを使用することになります。しかし、私が使用しているルーターはパスワードのみをサポートしています。

22
MiniQuark

次のようにexpectのsttyコマンドを使用します。

# grab the password
stty -echo
send_user -- "Password for $user@$Host: "
expect_user -re "(.*)\n"
send_user "\n"
stty echo
set pass $expect_out(1,string)

#... later
send -- "$pass\r"

stty -echoを呼び出すことが重要であることに注意してください send_userに電話する-正確な理由はわかりません:タイミングの問題だと思います。

プログラマーはすべて読むべきだと期待する インクルード 本:ドン・リベスによる期待の探求

40
glenn jackman

OK、上(または下または現在の場所)の2つの回答をマージします。

#!/usr/bin/expect
log_user 0
set timeout 10
set userid  "XXXXX"
set pass    "XXXXXX"

### Get two arguments - (1) Host (2) Command to be executed
set Host    [lindex $argv 0] 
set command [lindex $argv 1]

# grab the password
stty -echo
send_user -- "Password for $userid@$Host: "
expect_user -re "(.*)\n"
send_user "\n"
stty echo
set pass $expect_out(1,string)

spawn /usr/bin/ssh -l $userid $Host
match_max [expr 32 * 1024]

expect {
    -re "RSA key fingerprint" {send "yes\r"}
    timeout {puts "Host is known"}
}

expect {
     -re "username: " {send "$userid\r"} 
     -re "(P|p)assword: " {send "$pass\r"}
     -re "Warning:" {send "$pass\r"}
     -re "Connection refused" {puts "Host error -> $expect_out(buffer)";exit}
     -re "Connection closed"  {puts "Host error -> $expect_out(buffer)";exit}
     -re "no address.*" {puts "Host error -> $expect_out(buffer)";exit}

     timeout {puts "Timeout error. Is Host down or unreachable?? ssh_expect";exit}
}

expect {
   -re "\[#>]$" {send "term len 0\r"}
   timeout {puts "Error reading Prompt -> $expect_out(buffer)";exit}
}


expect {
   -re "\[#>]$" {send "$command\r"}

   timeout {puts "Error reading Prompt -> $expect_out(buffer)";exit}
}

expect -re "\[#>]$"
set output $expect_out(buffer)
send "exit\r"
puts "$output\r\n"

$ password変数を$ passに変更して、他の回答と一貫性があることに注意してください。

8
dr-jan

あるいは、SSHに、SSH_ASKPASS環境変数を使用してX11経由でパスワードを収集させることもできます。

マニュアルページから:

> SSH_ASKPASS
>     If ssh needs a passphrase, it will read the passphrase from the
>     current terminal if it was run from a terminal.  If ssh does not
>     have a terminal associated with it but DISPLAY and SSH_ASKPASS
>     are set, it will execute the program specified by SSH_ASKPASS
>     and open an X11 window to read the passphrase.  This is particularly
>     useful when calling ssh from a .xsession or related script.
>     (Note that on some machines it may be necessary to redirect the
>     input from /dev/null to make this work.)
0
qneill