真夜中の司令官でSFTPサポートの開発を監視し続け、今週著者と話しました-sftpサポートにssh-agentによる承認が登場しました。 祝うために、私はすぐにバッグを投げてテストしました。
そして最初の失望は、真夜中はエージェントを介してログインできないことです。 以前のバージョンで機能していた以前の承認スキームを試しました。
- パスワードで-問題なく動作します。
- キーによる-これは機能しますが、パスワードで保護されていないキーに対してのみです(明らかにこれはライブラリの制限です)。
エージェントでさまざまなオプションを試した後、著者にどのように機能するかを尋ねました。 問題ないことが判明しました。 後で、libssh2開発者サイトでssh-agentを介した承認の例を見つけ、コンパイルしようとしました
$ gcc -o agent_auth -Wall -I/usr/include -I. -lssh2 ssh2_agent.c ssh2_agent.c: In function 'main': ssh2_agent.c:99: warning: implicit declaration of function 'libssh2_session_handshake' /home/andrey/tmp/ccmczn2V.o: In function `main': ssh2_agent.c:(.text+0x1a8): undefined reference to `libssh2_session_handshake' collect2: ld returned 1 exit status
このエラーメッセージは、この例がdebian squeezeリポジトリにあるバージョンよりも新しいバージョン用に設計されていることを示唆しています。 libssh2の現在のバージョン(1.3.0)をビルドし、既に新しいライブラリを使用して例を再構築しようとしました。
$ gcc -o agent_auth -Wall -I$PWD/libssh2/include -I. -L$PWD/libssh2/lib -lssh2 ssh2_agent.c
その後、サンプルはエラーなしで組み立てられましたが、接続できないことを理由に動作を拒否しました。
$ LD_LIBRARY_PATH=$PWD/libssh2/lib ./agent-auth localhost andrey failed to connect! zsh: segmentation fault ./agent_auth localhost andrey
straceで実行すると、まず、接続が127.0.0.1ではなく255.255.255.255になり、次にサンプルコードが使用を確認せずにリソースを解放しようとすることが示されました。 したがって、終了時のセグメンテーション違反。
munmap(0xb7813000, 4096) = 0 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 connect(3, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("255.255.255.255")}, 16) = -1 ENETUNREACH (Network is unreachable) write(2, "failed to connect!\n", 19failed to connect! ) = 19 --- SIGSEGV (Segmentation fault) @ 0 (0) --- +++ killed by SIGSEGV +++ zsh: segmentation fault strace -f ./agent_auth localhost username
リソースをリリースする前にチェックを追加
--- ssh2_agent.c.orig 2011-12-08 23:53:41.000000000 +0300 +++ ssh2_agent.c 2011-12-09 00:02:10.000000000 +0300 @@ -231,10 +231,12 @@ int main(int argc, char *argv[]) */ shutdown: - - libssh2_agent_disconnect(agent); - libssh2_agent_free(agent); + if (agent) { + libssh2_agent_disconnect(agent); + + libssh2_agent_free(agent); + } if(session) {
その後、再構築して起動しました。
$ gcc -o agent_auth -Wall -I$PWD/libssh2/include -I. -L$PWD/libssh2/lib -lssh2 ssh2_agent.c $ LD_LIBRARY_PATH=$PWD/libssh2/lib ./agent_auth localhost andrey failed to connect!
すでにより良い-出口でのセグメンテーション違反は消えましたが、接続できないことを誓います。 コードをもう一度見てください。 Inet_addr()は、ホストをconnect()関数が理解できる形式に変換するために使用されます。
if (argc > 1) { hostaddr = inet_addr(argv[1]); } else { hostaddr = htonl(0x7F000001); }
man 3 inet_addrを見ると、関数がIPアドレスのシンボリックレコードをバイナリ表現に変換していることがわかります。 ビンゴ! ホスト名をlocalhostとして渡します。 localhostを127.0.0.1に置き換えると、実用的な例が得られます。
$ LD_LIBRARY_PATH=$PWD/libssh2/lib ./agent_auth 127.0.0.1 andrey Fingerprint: FA F3 92 9E C4 AE 14 B4 FC BE ED 2A E8 33 0C 1E 34 09 9F B3 Authentication methods: publickey,password Authentication with username andrey and public key /home/andrey/.ssh/id_rsa failed! Authentication with username andrey and public key /home/andrey/.ssh/id_dsa succeeded! all done!
squeeze用のlibssh2(1.3.0)のバージョンをビルドし、ライブラリの新しいバージョンで深夜に再構築するのはあなた次第です。 完成したアセンブリをここで拾うことができます