Аутентификация открытого ключа libssh2 требует парольной фразы только в том случае, если запрос ключа принят

Я использую libssh2, чтобы сделать сетевую программу более безопасной.

Я бы хотел, чтобы моя программа аутентифицировалась максимально похоже на ssh(1) клиента OpenSSH. Клиент OpenSSH будет запрашивать парольные фразы только для ключей, которые фактически приняты сервером.

Насколько я понял из этой ссылки, клиент ssh отправляет запрос использовать открытый ключ, и если это будет принято, он может разблокировать закрытый ключ с помощью парольной фразы.

libssh2 предоставляет функцию libssh2_userauth_publickey_fromfile, которая принимает имена файлов закрытого и открытого ключей и парольную фразу. Использование этой функции очень прямолинейно, но это означает, что я должен получить парольную фразу для закрытых ключей, даже если открытый ключ не был бы принят сервером в первую очередь. Это явно проблема для пользователей, у которых много разных ключей (в настоящее время моя программа перебирает файлы ключей в каталоге ~/.ssh).

Я пробовал читать справочные страницы для libssh2 функций, и большинство из них кажутся мне слишком краткими, чтобы их можно было понять без более подробного знания протокола ssh. Фактически, некоторые из них еще даже не написаны.

Может ли кто-нибудь сказать мне, как запрашивать парольные фразы только для ключей, которые фактически принимаются ssh-сервером с использованием libssh2?


person szmoore    schedule 19.02.2013    source источник


Ответы (1)


После RTFM и проведения некоторого тестирования я обнаружил, что libssh2_userauth_publickey_fromfile будет возвращать другой код ошибки в зависимости от того, был ли ключ не принят сервером или парольная фраза была неверной.

Итак, вот довольно неэффективное решение (потому что оно вызывает libssh2_userauth_publickey_fromfile и, следовательно, все части обмена ключами протокола как минимум дважды).

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 использует решение этого вопроса, чтобы запросить у пользователя парольную фразу.

person szmoore    schedule 19.02.2013