3

libssh2ネットワークプログラムをより安全にするために使用しています。

私は自分のプログラムが OpenSSH クライアント ssh(1) とできるだけ同じ方法で認証することを望んでいます。OpenSSH クライアントは、サーバーによって実際に受け入れられるキーのパスフレーズのみを要求します。

このリンクからわかるように、ssh クライアントは公開鍵を使用する要求を送信し、それが受け入れられると、パスフレーズを使用して秘密鍵のロックを解除できます。

libssh2 はlibssh2_userauth_publickey_fromfile、秘密鍵と公開鍵のファイル名とパスフレーズを取る関数を提供します。この関数を使用するのは非常に簡単ですが、そもそも公開鍵がサーバーによって受け入れられなかったとしても、秘密鍵のパスフレーズを取得する必要があることを意味します。これは、多数の異なるキーを持っているユーザーにとって明らかに問題です (現在、私のプログラムは ~/.ssh ディレクトリ内のキー ファイルを反復処理しています)。

関数のマニュアル ページを読んでみlibssh2ましたが、ssh プロトコルの詳細な知識がなければ理解するには、ほとんどの関数が簡潔すぎてわかりません。実際、それらのいくつかはまだ書かれていません。

を使用してsshサーバーによって実際に受け入れられるキーのパスフレーズのみを要求する方法を誰か教えてもらえますlibssh2か?

4

1 に答える 1

4

RTFM といくつかのテストを行った後libssh2_userauth_publickey_fromfile、キーがサーバーによって受け入れられなかったか、パスフレーズが正しくなかったかによって、異なるエラー コードが返されることがわかりました。

したがって、これはかなり非効率的なソリューションです (libssh2_userauth_publickey_fromfileプロトコルのすべての鍵交換部分を少なくとも 2 回呼び出すため)。

int nAttempts = 3; // number of attempts the user gets at entering the passphrase

// Try authenticating with an empty passphrase
int err = libssh2_userauth_publickey_fromfile(session, user, pub, priv,"");
if (err == 0)
{
    fprintf(stderr, "You shouldn't use keys with an empty passphrase!\n");
}
else if (err == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED)
{
    // if we get here it means the public key was initially accepted
    // but the private key has a non-empty passphrase
    char p[BUFSIZ];

    for (int i = 0; i < nAttempts; ++i)
    {
         get_passphrase(p); // assume this gets the passphrase
         err = libssh2_userauth_publickey_fromfile(session, user, pub, priv,p);
         if (err != LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) break;
    }
}

if (err != 0)
{
    fprintf(stderr, "Authentication using key %s failed!\n", priv);
}

完全を期すために、get_passphrase関数はこの質問に対する解決策を使用して、ユーザーにパスフレーズを要求します。

于 2013-02-19T16:06:07.983 に答える