0

最初に、私は公開鍵と秘密鍵を使用することに慣れていると言う必要がありますが、これで問題は解決しませんでした。また、2 つのスクリプト (1 つは password1、もう 1 つは password2) を使用して 2 回実行できることも認識していますが、なぜ次のように動作しなかったのか疑問に思っています。ssh 経由で接続し、2 つのパスワードのいずれかが正しいかどうかを確認するスクリプトを期待しようとしています。このために、スクリプトの終了コードをチェックしています:

リモート マシンでより多くのログイン プロンプトが表示される可能性があります。このスクリプトをできるだけ一般的なものにしたいので、ログイン プロンプト文字列に頼ることはできません。これまでのところ、私はこのコードを持っています:

#!/usr/local/bin/expect
set username "username";
set remote_server "machine";
set password1 "badpassword";
set password2 "goodpassword";

set timeout 5;
set pretype 0;
set retcode 0;


if { $pretype == 0 } {
  spawn ssh -q ${username}@${remote_server}
  expect {
    "no)?"    { send "yes\r"; }
    "denied" {
                puts "Can't login to $remote_server. Check username and password\n";
                set retcode 2;
             }
    "telnet:" {
                puts "Can't connect to $remote_server via SSH or Telnet. Something went definitely wrong\n";
                set retcode 3;
              }
    "failed" {
                puts "Host $remote_server exists. Check ssh_hosts file\n";
                set retcode 4;
             }
    timeout {
                puts "Timeout problem. Host $remote_server doesn't respond\n";
                set retcode 5;
            }
    "refused" {
                puts "Host $remote_server refused to SSH. That is insecure.\n";
                set retcode 6;
                }
    "assword:" {    set pretype 1; send "${password1}\r";  }
  }
} else {
    expect{
        "assword:" {    send "${password2}\r"; exit 1; }
        timeout { exit 0; }
    }
}

この背後にある考え方は次のとおりです。間違ったパスワードを入力すると、正しいパスワードを入力する 2 番目の機会が得られます。したがって、最初に間違ったパスワードを入力した場合、スクリプトは else ブランチで続行する必要があります ( I のためset pretype to 1)。ここで、パスワードを再度入力するように求められます。したがって、2 番目のパスワードを送信し、コード 1 で終了します (password2 は OK でした)。else ブランチのタイムアウトが期限切れになった場合 (「password:」文字列が一致しなかった場合)、おそらく既にログイン プロンプトが表示されているため、スクリプトはコード 0 (password1 は OK) で終了します。しかし、これは機能しませんでした。これをデバッガー内で実行すると、最後の行は次のようになりました。

send: sending "badpassword\r\r" to { exp4 }

なぜこれが起こるのかわかりませんが、スクリプトが else ブランチに到達しないようです。どうもありがとうございました

4

1 に答える 1

2

set pretype 1ブロック内で再びブロックifに移動することはできませんelse。これを行うプログラミング言語はありません。ここでは、ループwhileまたはを使用)のようなものが必要ですexp_continue

次に例を示します。

#!/usr/bin/expect

set passwords { bad1 bad2 bad3 good }

spawn ssh -o PreferredAuthentications=keyboard-interactive \
          -o NumberOfPasswordPrompts=[llength $passwords] root@tree

set try 0
expect {
    "Password: " {
        if { $try >= [llength $passwords] } {
            send_error ">>> wrong passwords\n"
            exit 1
        }

        send [lindex $passwords $try]\r
        incr try
        exp_continue
    }

    "bash-4.2" {
        interact
    }

    timeout {
        send_error ">>> timed out\n"
        exit 1
    }
}
于 2013-03-21T01:58:42.897 に答える