1

私は、最初の本格的なプロジェクトの後期段階で、Android 開発にかなり慣れていません。簡単に言うと、プログラムは Linux ホストに ssh 接続し、コマンドを実行します。しかし、私はこれを終わらせようとして、本当に結び目に縛られていることに気づきました。

私は ganymed-ssh2 を使用して ssh grunt-work を実行しています。

アクティビティ ボタンが押されると、プログラムで SSH セッションを開始し、ホスト フィンガープリントを確認し、必要に応じて承認を求め、プログラムどおりにリモート コマンドを発行します。しかし、この一見単純ないくつかの手順は、次のように非常に複雑になっています。

  1. ssh は UI スレッドでは実行できないため、AsyncTask を開始する必要があります。そのため、次の面倒なことで説明することはすべて、フォアグラウンド UI スレッドにはありません。
  2. ssh フィンガープリンティング コードを有効にするには、AsyncTask クラス内で次のような呼び出しを行う必要があります。

    @Override
    protected String doInBackground(String... command) {
        String result;
    result = "";
    try {
      /* Create a connection instance */            
          Connection conn = new Connection(connect.getHost(), connect.getPort());
    
      /* Now connect */
      ConnectionInfo info = conn.connect(new AdvancedVerifier());
    
          boolean isAuthenticated = false;
      // first try public key if defined
      if (connect.getPrivateKey() != null)
      isAuthenticated = conn.authenticateWithPublicKey
             (connect.getUserid(), connect.getPrivateKey(), null);  
      // if failed, or not defined, try password if provide
          if (!isAuthenticated && connect.getPassword() != null)
      isAuthenticated = conn.authenticateWithPassword(connect.getUserid(), 
                 new String (connect.getPassword()));
    
          // all else, get out
          if (!isAuthenticated)
            throw new IOException("Authentication failed.");
    
      /* Create a session */
          Session sess = conn.openSession();
          sess.execCommand(command[0]);
    }
    

ただし、conn.connect(new AdvancedVerifier()) 行により、AdvancedVerifier のコールバック インターフェイス クラスが呼び出され、接続呼び出しで実行パスが中断され、このクラスが呼び出されます。

    class AdvancedVerifier implements ServerHostKeyVerifier
    {
        public boolean verifyServerHostKey(String hostname, int port, 
          String serverHostKeyAlgorithm,
          byte[] serverHostKey) throws Exception
        {
            final String host = hostname;
            final String algo = serverHostKeyAlgorithm;

            /* Check database   - code removed*/
            /* assuming fingerprint needs verification */

            String hexFingerprint =
                KnownHosts.createHexFingerprint(serverHostKeyAlgorithm,
                    serverHostKey);

            String msg = "Hex Fingerprint: " + hexFingerprint;

            /* right here, I need to display dialog of fingerprint, 
               and ask user for to continue;
               If user accepts, return true, else return false.

               If return true, the above class continues after connect(), if false
               it is aborted.
            */
            return UserAccepts? true : false;
       }
     }

私の限られた経験では、これは本当に厄介なコードをたくさん発生させるようです。まず、UI スレッドに再アタッチしてダイアログを表示し、ユーザーが [OK] を選択した場合は、verifyServerHostKey() から「true」を返し、UI スレッドをデタッチして、ssh 接続コードを再開できるようにする必要があります。モーダル ダイアログを使用する機能はありません。
率直に言って、私はどこから始めればよいのかよくわからず、アイデアやガイダンスなどを探しています.

4

1 に答える 1

0

私は最終的に、問題を解決するための少なくとも 1 つの方法を考え出しました。AdvancedVerifier クラスと onProgressUpdate の AlertDialog との間で待機/通知の組み合わせを使用して、ユーザーがホスト フィンガープリントを受け入れ/拒否している間、ベリファイア クラスを一時停止することができました。

もっと良い方法があるかどうかはわかりませんが、これで作業できると思います。

于 2013-04-13T05:36:24.200 に答える