私は、最初の本格的なプロジェクトの後期段階で、Android 開発にかなり慣れていません。簡単に言うと、プログラムは Linux ホストに ssh 接続し、コマンドを実行します。しかし、私はこれを終わらせようとして、本当に結び目に縛られていることに気づきました。
私は ganymed-ssh2 を使用して ssh grunt-work を実行しています。
アクティビティ ボタンが押されると、プログラムで SSH セッションを開始し、ホスト フィンガープリントを確認し、必要に応じて承認を求め、プログラムどおりにリモート コマンドを発行します。しかし、この一見単純ないくつかの手順は、次のように非常に複雑になっています。
- ssh は UI スレッドでは実行できないため、AsyncTask を開始する必要があります。そのため、次の面倒なことで説明することはすべて、フォアグラウンド UI スレッドにはありません。
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 接続コードを再開できるようにする必要があります。モーダル ダイアログを使用する機能はありません。
率直に言って、私はどこから始めればよいのかよくわからず、アイデアやガイダンスなどを探しています.