1
1

auth: Add ssh_userauth_publickey().

Этот коммит содержится в:
Andreas Schneider 2011-08-23 20:19:24 +02:00
родитель aa018c1484
Коммит 379d65eaaf
2 изменённых файлов: 177 добавлений и 0 удалений

Просмотреть файл

@ -497,6 +497,9 @@ LIBSSH_API int ssh_userauth_list(ssh_session session, const char *username);
LIBSSH_API int ssh_userauth_try_publickey(ssh_session session,
const char *username,
const ssh_key pubkey);
LIBSSH_API int ssh_userauth_publickey(ssh_session session,
const char *username,
const ssh_key privkey);
#ifndef _WIN32
LIBSSH_API int ssh_userauth_agent_pubkey(ssh_session session, const char *username,

Просмотреть файл

@ -629,6 +629,180 @@ fail:
return SSH_AUTH_ERROR;
}
/**
* @brief Authenticate with public/private key.
*
* @param[in] ssh_session The SSH session.
*
* @param[in] username The username, this SHOULD be NULL.
*
* @param[in] privkey The private key for authentication.
*
* @return SSH_AUTH_ERROR: A serious error happened.\n
* SSH_AUTH_DENIED: The server doesn't accept that public key as an
* authentication token. Try another key or another
* method.\n
* SSH_AUTH_PARTIAL: You've been partially authenticated, you still
* have to use another method.\n
* SSH_AUTH_SUCCESS: The public key is accepted, you want now to use
* ssh_userauth_pubkey().
* SSH_AUTH_AGAIN: In nonblocking mode, you've got to call this again
* later.
*
* @note Most server implementations do not permit changing the username during
* authentication. The username should only be set with ssh_optoins_set() only
* before you connect to the server.
*/
int ssh_userauth_publickey(ssh_session session,
const char *username,
const ssh_key privkey)
{
ssh_string str;
int rc;
if (session == NULL) {
return SSH_AUTH_ERROR;
}
if (privkey == NULL || !ssh_key_is_private(privkey)) {
ssh_set_error(session, SSH_FATAL, "Invalid private key");
return SSH_AUTH_ERROR;
}
#ifdef WITH_SSH1
if (session->version == 1) {
return SSH_AUTH_DENIED;
}
#endif
switch(session->pending_call_state) {
case SSH_PENDING_CALL_NONE:
break;
case SSH_PENDING_CALL_AUTH_OFFER_PUBKEY:
goto pending;
default:
ssh_set_error(session,
SSH_FATAL,
"Bad call during pending SSH call in ssh_userauth_try_pubkey");
return SSH_ERROR;
}
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* request */
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
if (rc < 0) {
goto fail;
}
/* username */
if (username) {
str = ssh_string_from_char(username);
} else {
str = ssh_string_from_char(session->username);
}
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* service */
str = ssh_string_from_char("ssh-connection");
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* method */
str = ssh_string_from_char("publickey");
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* private key? */
rc = buffer_add_u8(session->out_buffer, 1);
if (rc < 0) {
goto fail;
}
/* algo */
str = ssh_string_from_char(privkey->type_c);
if (rc < 0) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* public key */
str = ssh_pki_export_pubkey_blob(privkey);
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
/* sign the buffer with the private key */
str = ssh_pki_do_sign(session, session->out_buffer, privkey);
if (str == NULL) {
goto fail;
}
rc = buffer_add_ssh_string(session->out_buffer, str);
ssh_string_free(str);
if (rc < 0) {
goto fail;
}
session->auth_state = SSH_AUTH_STATE_NONE;
session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY;
rc = packet_send(session);
if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
pending:
rc = ssh_userauth_get_response(session);
if (rc != SSH_AUTH_AGAIN) {
session->pending_call_state = SSH_PENDING_CALL_NONE;
}
return rc;
fail:
ssh_set_error_oom(session);
buffer_reinit(session->out_buffer);
return SSH_AUTH_ERROR;
}
/**
* @brief Try to authenticate through public key (deprecated).
*