2016-04-15 3 views
2

suの下にあるサーバーでリモートでコマンドを実行しようとしています。具体的には、リモートで実行しています。"su"コマンドに提供されたパスワードがJSchライブラリで補完されているかどうかをテストします

su -c '[command]' 

これはリモートサーバーにログインしているときに機能します。

私の質問はうまくいけばかなり簡単です:out.writesuコマンドで提供されたパスワードプロンプトに返信しているかどうかを確認するにはどうすればよいですか?チャンネルが接続されているように見え、プログラムはsuが関与していない限り動作するように見えます。

理想的動作のシーケンスである:初期化

リモートコマンド - パスワードの>プロンプト - リモート>入力されたパスワード[不良点] - >コマンドを

を実行これはsuなければなりません。 sudoにはできません。

ホープスこれは、同様の問題を誰にも役立ちます

/** 
* Method to connect to session. 
*/ 
protected void connectSession(Session session){ 
    try { 

     //connect to session and open exec channel 
     session.connect(); 
     channel=session.openChannel("exec"); 

     ((ChannelExec)channel).setCommand(command); //set the command 
     ((ChannelExec)channel).setPty(true); //set PTY tru for Password input 
     ((ChannelExec)channel).setErrStream(System.err); 

     in = channel.getInputStream(); //set input stream 
     out=channel.getOutputStream(); //set output stream and connect 
     channel.connect(); 

     System.out.println("Channel was connected"); 
     out.write((sudo_pass+"\n").getBytes()); //write password upon prompt 
     out.flush(); 

     //I believe the out.write and the out.flush section is not working. It probably breaks right before here. 

     System.out.println("Wrote sudo Pass"); 

    } catch (JSchException | IOException e) { 
     System.out.println("Could not connect to session"); 
     e.printStackTrace(); 
    } 
} 
@Override 
protected Integer RunCommand() throws Exception { 
    int j = 0; 
    System.out.println("Running command: " + command); 
    connectSession(session); 

    byte[] tmp=new byte[1024]; 
    while(in.available()>0){ 
     int i=in.read(tmp, 0, 1024); 
     if(i<0)break; 
     System.out.print(new String(tmp, 0, i)); 
    } 

    if(channel.isClosed()){ 
     if(in.available()>0) continue; 
     System.out.println("exit-status: "+channel.getExitStatus()); 
     break; 
    } 

    try{Thread.sleep(1000);} 
    catch(Exception ee){} 
    channel.disconnect(); 
} 

私はから重く借りてきました!

+0

*パスワードを出力ストリームに書き込むにはどうすればよいですか?* - それはどういう意味ですか? –

+0

この行には:out.write((sudo_pass + "\ n")。getBytes()); //プロンプトでパスワードを書いてください私は、プロンプトにsuのパスワードを書いていると思います。問題は、このソリューションはhttp://www.jcraft.com/jsch/examples/Sudo.java.htmlで動作しますが、 "su"には-pオプションがなく、私はout.write関数を信じていません実際にパスワードの入力を求められたら入力します。私はスクリプトを期待していると考えましたが、より洗練されたソリューションを探していました。 – and0rsk

+0

質問をより明確に編集しました。 "out.writeがsuコマンドで提供されたパスワードプロンプトに返信しているかどうかを確認するにはどうすればいいですか" – and0rsk

答えて

1

間違ったパスワードを入力した場合、コマンドは打ち切り、ゼロ以外の終了コードを返します。

パスワードを入力した後に「exec」チャネルが閉じるかどうかを確認するだけです。終了した場合は、間違ったパスワードを入力したことになります。 suコマンドを自動化することがないを特別に設計されていることを

正しいパスワードを入力すると、suはシェルを起動し、コマンドを待って続ける(または-cで指定したコマンドを実行)


注意。自動化しようとすると間違っています。

正しい方法は次のとおりです。あなたの特定のタスク のための単一のスクリプトに制限root、ユーザの秘密鍵を使用して、特定のタスク

  • のための単一のスクリプトに制限パスワードレスsudoコマンドを使用して

  • +0

    閉じるが、パスワードが正しいことが分かっている。元のリクエストをきれいにして明快さを加えていただきありがとうございます。私は、(out.writeの)パスワード書き込みの入力タイミングが、正しいスロット(プロンプトの後)で行われていることを確認することに、さらに関心があります。 suコマンドは、パスワードプロンプトの直後にコマンドを実行するsu -cです。プロンプトが表示されたら、パスワードを出力ストリームで正確に計時してコマンドを実行することを確認したい。したがって、イベントシーケンスは元のプロンプトに従うべきです。 – and0rsk

    +0

    なぜあなたはそれをタイムアウトしなければならないと思いますか?入力は必要になるまで待ちます。私はあなたがそれを計る必要はないと思う。 –

    +0

    私はsuを使わずにコマンドを実行するので、 "time"する必要があると信じています。私のローカルマシンに正しいパスワードが入力されています。この問題は、suパスワードを遠隔から受け取っているところで発生しています。 – and0rsk

    関連する問題