auth.c | auth.c | |||
---|---|---|---|---|
skipping to change at line 35 | skipping to change at line 35 | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <stdio.h> | #include <stdio.h> | |||
#include <string.h> | #include <string.h> | |||
#ifndef _WIN32 | #ifndef _WIN32 | |||
#include <arpa/inet.h> | #include <arpa/inet.h> | |||
#endif | #endif | |||
#include "libssh/priv.h" | #include "libssh/priv.h" | |||
#include "libssh/ssh2.h" | #include "libssh/ssh2.h" | |||
#include "libssh/buffer.h" | ||||
#include "libssh/agent.h" | ||||
#include "libssh/keyfiles.h" | ||||
#include "libssh/packet.h" | ||||
#include "libssh/session.h" | ||||
#include "libssh/keys.h" | ||||
/** \defgroup ssh_auth SSH Authentication functions | /** \defgroup ssh_auth SSH Authentication functions | |||
* \brief functions to authenticate to servers | * \brief functions to authenticate to servers | |||
*/ | */ | |||
/** \addtogroup ssh_auth | /** \addtogroup ssh_auth | |||
* @{ */ | * @{ */ | |||
static int ask_userauth(SSH_SESSION *session) { | static int ask_userauth(ssh_session session) { | |||
int rc = 0; | int rc = 0; | |||
enter_function(); | enter_function(); | |||
if (session->auth_service_asked) { | if (session->auth_service_asked) { | |||
rc = 0; | rc = 0; | |||
} else if (ssh_service_request(session,"ssh-userauth")) { | } else if (ssh_service_request(session,"ssh-userauth")) { | |||
rc = -1; | rc = -1; | |||
} else { | } else { | |||
session->auth_service_asked++; | session->auth_service_asked++; | |||
} | } | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
static int wait_auth_status(SSH_SESSION *session, int kbdint) { | static int wait_auth_status(ssh_session session, int kbdint) { | |||
char *auth_methods = NULL; | char *auth_methods = NULL; | |||
STRING *auth; | ssh_string auth; | |||
int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
int cont = 1; | int cont = 1; | |||
u8 partial = 0; | uint8_t partial = 0; | |||
enter_function(); | enter_function(); | |||
while (cont) { | while (cont) { | |||
if (packet_read(session) != SSH_OK) { | if (packet_read(session) != SSH_OK) { | |||
break; | break; | |||
} | } | |||
if (packet_translate(session) != SSH_OK) { | if (packet_translate(session) != SSH_OK) { | |||
break; | break; | |||
} | } | |||
skipping to change at line 142 | skipping to change at line 148 | |||
cont = 0; | cont = 0; | |||
break; | break; | |||
} | } | |||
/* continue through success */ | /* continue through success */ | |||
case SSH2_MSG_USERAUTH_SUCCESS: | case SSH2_MSG_USERAUTH_SUCCESS: | |||
rc = SSH_AUTH_SUCCESS; | rc = SSH_AUTH_SUCCESS; | |||
cont = 0; | cont = 0; | |||
break; | break; | |||
case SSH2_MSG_USERAUTH_BANNER: | case SSH2_MSG_USERAUTH_BANNER: | |||
{ | { | |||
STRING *banner; | ssh_string banner; | |||
banner = buffer_get_ssh_string(session->in_buffer); | banner = buffer_get_ssh_string(session->in_buffer); | |||
if (banner == NULL) { | if (banner == NULL) { | |||
ssh_log(session, SSH_LOG_PACKET, | ssh_log(session, SSH_LOG_PACKET, | |||
"The banner message was invalid. Continuing though\n"); | "The banner message was invalid. Continuing though\n"); | |||
break; | break; | |||
} | } | |||
ssh_log(session, SSH_LOG_PACKET, | ssh_log(session, SSH_LOG_PACKET, | |||
"Received a message banner\n"); | "Received a message banner\n"); | |||
string_free(session->banner); /* erase the older one */ | string_free(session->banner); /* erase the older one */ | |||
skipping to change at line 166 | skipping to change at line 172 | |||
default: | default: | |||
packet_parse(session); | packet_parse(session); | |||
break; | break; | |||
} | } | |||
} | } | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
int ssh_auth_list(SSH_SESSION *session) { | int ssh_auth_list(ssh_session session) { | |||
if (session == NULL) { | if (session == NULL) { | |||
return -1; | return -1; | |||
} | } | |||
return session->auth_methods; | return session->auth_methods; | |||
} | } | |||
int ssh_userauth_list(SSH_SESSION *session, const char *username) { | int ssh_userauth_list(ssh_session session, const char *username) { | |||
if (session == NULL || username == NULL) { | if (session == NULL || username == NULL) { | |||
return SSH_AUTH_ERROR; | return SSH_AUTH_ERROR; | |||
} | } | |||
if (session->auth_methods == 0) { | if (session->auth_methods == 0) { | |||
ssh_userauth_none(session, username); | ssh_userauth_none(session, username); | |||
} | } | |||
return ssh_auth_list(session); | return ssh_auth_list(session); | |||
} | } | |||
skipping to change at line 203 | skipping to change at line 209 | |||
* @param username The username to authenticate. You can specify NULL if | * @param username The username to authenticate. You can specify NULL if | |||
* ssh_option_set_username() has been used. You cannot try | * ssh_option_set_username() has been used. You cannot try | |||
* two different logins in a row. | * two different logins in a row. | |||
* | * | |||
* @returns SSH_AUTH_ERROR: A serious error happened.\n | * @returns SSH_AUTH_ERROR: A serious error happened.\n | |||
* SSH_AUTH_DENIED: Authentication failed: use another method\n | * SSH_AUTH_DENIED: Authentication failed: use another method\n | |||
* SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | |||
* have to use another method\n | * have to use another method\n | |||
* SSH_AUTH_SUCCESS: Authentication success | * SSH_AUTH_SUCCESS: Authentication success | |||
*/ | */ | |||
int ssh_userauth_none(SSH_SESSION *session, const char *username) { | int ssh_userauth_none(ssh_session session, const char *username) { | |||
STRING *user = NULL; | ssh_string user = NULL; | |||
STRING *service = NULL; | ssh_string service = NULL; | |||
STRING *method = NULL; | ssh_string method = NULL; | |||
int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
enter_function(); | enter_function(); | |||
#ifdef WITH_SSH1 | #ifdef WITH_SSH1 | |||
if (session->version == 1) { | if (session->version == 1) { | |||
ssh_userauth1_none(session, username); | ssh_userauth1_none(session, username); | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
#endif | #endif | |||
if (username == NULL) { | if (username == NULL) { | |||
if (session->options->username == NULL) { | if (session->username == NULL) { | |||
if (ssh_options_default_username(session->options) < 0) { | if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
} | } | |||
user = string_from_char(session->options->username); | user = string_from_char(session->username); | |||
} else { | } else { | |||
user = string_from_char(username); | user = string_from_char(username); | |||
} | } | |||
if (user == NULL) { | if (user == NULL) { | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
if (ask_userauth(session) < 0) { | if (ask_userauth(session) < 0) { | |||
skipping to change at line 307 | skipping to change at line 313 | |||
* method.\n | * method.\n | |||
* SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | |||
* have to use another method.\n | * have to use another method.\n | |||
* SSH_AUTH_SUCCESS: The public key is accepted, you want now to u se | * SSH_AUTH_SUCCESS: The public key is accepted, you want now to u se | |||
* ssh_userauth_pubkey(). | * ssh_userauth_pubkey(). | |||
* | * | |||
* @see publickey_from_file() | * @see publickey_from_file() | |||
* @see privatekey_from_file() | * @see privatekey_from_file() | |||
* @see ssh_userauth_pubkey() | * @see ssh_userauth_pubkey() | |||
*/ | */ | |||
int ssh_userauth_offer_pubkey(SSH_SESSION *session, const char *username, | int ssh_userauth_offer_pubkey(ssh_session session, const char *username, | |||
int type, STRING *publickey) { | int type, ssh_string publickey) { | |||
STRING *user = NULL; | ssh_string user = NULL; | |||
STRING *service = NULL; | ssh_string service = NULL; | |||
STRING *method = NULL; | ssh_string method = NULL; | |||
STRING *algo = NULL; | ssh_string algo = NULL; | |||
int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
enter_function(); | enter_function(); | |||
#ifdef WITH_SSH1 | #ifdef WITH_SSH1 | |||
if (session->version == 1) { | if (session->version == 1) { | |||
ssh_userauth1_offer_pubkey(session, username, type, publickey); | ssh_userauth1_offer_pubkey(session, username, type, publickey); | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
#endif | #endif | |||
if (username == NULL) { | if (username == NULL) { | |||
if (session->options->username == NULL) { | if (session->username == NULL) { | |||
if (ssh_options_default_username(session->options) < 0) { | if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
} | } | |||
user = string_from_char(session->options->username); | user = string_from_char(session->username); | |||
} else { | } else { | |||
user = string_from_char(username); | user = string_from_char(username); | |||
} | } | |||
if (user == NULL) { | if (user == NULL) { | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
if (ask_userauth(session) < 0) { | if (ask_userauth(session) < 0) { | |||
skipping to change at line 419 | skipping to change at line 425 | |||
* SSH_AUTH_DENIED: Authentication failed: use another method.\n | * SSH_AUTH_DENIED: Authentication failed: use another method.\n | |||
* SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | |||
* have to use another method.\n | * have to use another method.\n | |||
* SSH_AUTH_SUCCESS: Authentication successful. | * SSH_AUTH_SUCCESS: Authentication successful. | |||
* | * | |||
* @see publickey_from_file() | * @see publickey_from_file() | |||
* @see privatekey_from_file() | * @see privatekey_from_file() | |||
* @see privatekey_free() | * @see privatekey_free() | |||
* @see ssh_userauth_offer_pubkey() | * @see ssh_userauth_offer_pubkey() | |||
*/ | */ | |||
int ssh_userauth_pubkey(SSH_SESSION *session, const char *username, | int ssh_userauth_pubkey(ssh_session session, const char *username, | |||
STRING *publickey, PRIVATE_KEY *privatekey) { | ssh_string publickey, ssh_private_key privatekey) { | |||
STRING *user = NULL; | ssh_string user = NULL; | |||
STRING *service = NULL; | ssh_string service = NULL; | |||
STRING *method = NULL; | ssh_string method = NULL; | |||
STRING *algo = NULL; | ssh_string algo = NULL; | |||
STRING *sign = NULL; | ssh_string sign = NULL; | |||
int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
enter_function(); | enter_function(); | |||
#if 0 | #if 0 | |||
if (session->version == 1) { | if (session->version == 1) { | |||
return ssh_userauth1_pubkey(session, username, publickey, privatekey); | return ssh_userauth1_pubkey(session, username, publickey, privatekey); | |||
} | } | |||
#endif | #endif | |||
if (username == NULL) { | if (username == NULL) { | |||
if (session->options->username == NULL) { | if (session->username == NULL) { | |||
if (ssh_options_default_username(session->options) < 0) { | if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
} | } | |||
user = string_from_char(session->options->username); | user = string_from_char(session->username); | |||
} else { | } else { | |||
user = string_from_char(username); | user = string_from_char(username); | |||
} | } | |||
if (user == NULL) { | if (user == NULL) { | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
if (ask_userauth(session) < 0) { | if (ask_userauth(session) < 0) { | |||
skipping to change at line 538 | skipping to change at line 544 | |||
* SSH_AUTH_DENIED: Authentication failed: use another method.\n | * SSH_AUTH_DENIED: Authentication failed: use another method.\n | |||
* SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | |||
* have to use another method.\n | * have to use another method.\n | |||
* SSH_AUTH_SUCCESS: Authentication successful. | * SSH_AUTH_SUCCESS: Authentication successful. | |||
* | * | |||
* @see publickey_from_file() | * @see publickey_from_file() | |||
* @see privatekey_from_file() | * @see privatekey_from_file() | |||
* @see privatekey_free() | * @see privatekey_free() | |||
* @see ssh_userauth_offer_pubkey() | * @see ssh_userauth_offer_pubkey() | |||
*/ | */ | |||
int ssh_userauth_agent_pubkey(SSH_SESSION *session, const char *username, | int ssh_userauth_agent_pubkey(ssh_session session, const char *username, | |||
PUBLIC_KEY *publickey) { | ssh_public_key publickey) { | |||
STRING *user = NULL; | ssh_string user = NULL; | |||
STRING *service = NULL; | ssh_string service = NULL; | |||
STRING *method = NULL; | ssh_string method = NULL; | |||
STRING *algo = NULL; | ssh_string algo = NULL; | |||
STRING *key = NULL; | ssh_string key = NULL; | |||
STRING *sign = NULL; | ssh_string sign = NULL; | |||
int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
enter_function(); | enter_function(); | |||
if (! agent_is_running(session)) { | if (! agent_is_running(session)) { | |||
return rc; | return rc; | |||
} | } | |||
if (username == NULL) { | if (username == NULL) { | |||
if (session->options->username == NULL) { | if (session->username == NULL) { | |||
if (ssh_options_default_username(session->options) < 0) { | if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
} | } | |||
user = string_from_char(session->options->username); | user = string_from_char(session->username); | |||
} else { | } else { | |||
user = string_from_char(username); | user = string_from_char(username); | |||
} | } | |||
if (user == NULL) { | if (user == NULL) { | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
if (ask_userauth(session) < 0) { | if (ask_userauth(session) < 0) { | |||
skipping to change at line 663 | skipping to change at line 669 | |||
* | * | |||
* @returns SSH_AUTH_ERROR: A serious error happened.\n | * @returns SSH_AUTH_ERROR: A serious error happened.\n | |||
* SSH_AUTH_DENIED: Authentication failed: use another method.\n | * SSH_AUTH_DENIED: Authentication failed: use another method.\n | |||
* SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | |||
* have to use another method.\n | * have to use another method.\n | |||
* SSH_AUTH_SUCCESS: Authentication successful. | * SSH_AUTH_SUCCESS: Authentication successful. | |||
* | * | |||
* @see ssh_userauth_kbdint() | * @see ssh_userauth_kbdint() | |||
* @see BURN_STRING | * @see BURN_STRING | |||
*/ | */ | |||
int ssh_userauth_password(SSH_SESSION *session, const char *username, | int ssh_userauth_password(ssh_session session, const char *username, | |||
const char *password) { | const char *password) { | |||
STRING *user = NULL; | ssh_string user = NULL; | |||
STRING *service = NULL; | ssh_string service = NULL; | |||
STRING *method = NULL; | ssh_string method = NULL; | |||
STRING *pwd = NULL; | ssh_string pwd = NULL; | |||
int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
enter_function(); | enter_function(); | |||
#ifdef WITH_SSH1 | #ifdef WITH_SSH1 | |||
if (session->version == 1) { | if (session->version == 1) { | |||
rc = ssh_userauth1_password(session, username, password); | rc = ssh_userauth1_password(session, username, password); | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
#endif | #endif | |||
if (username == NULL) { | if (username == NULL) { | |||
if (session->options->username == NULL) { | if (session->username == NULL) { | |||
if (ssh_options_default_username(session->options) < 0) { | if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
} | } | |||
user = string_from_char(session->options->username); | user = string_from_char(session->username); | |||
} else { | } else { | |||
user = string_from_char(username); | user = string_from_char(username); | |||
} | } | |||
if (user == NULL) { | if (user == NULL) { | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
if (ask_userauth(session) < 0) { | if (ask_userauth(session) < 0) { | |||
skipping to change at line 752 | skipping to change at line 758 | |||
string_free(user); | string_free(user); | |||
string_free(service); | string_free(service); | |||
string_free(method); | string_free(method); | |||
string_burn(pwd); | string_burn(pwd); | |||
string_free(pwd); | string_free(pwd); | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
static struct keys_struct keytab[] = { | #ifdef _MSC_VER | |||
static const char privKey_1[] = "SSH_DIR/identity"; | ||||
static const char pubKey_1[] = "SSH_DIR/identity.pub"; | ||||
static const char privKey_2[] = "SSH_DIR/id_dsa"; | ||||
static const char pubKey_2[] = "SSH_DIR/id_dsa.pub"; | ||||
static const char privKey_3[] = "SSH_DIR/id_rsa"; | ||||
static const char pubKey_3[] = "SSH_DIR/id_rsa.pub"; | ||||
/** Used different var to allow const char[] declaration */ | ||||
static struct ssh_keys_struct keytab[] = { | ||||
{ privKey_1, pubKey_1}, | ||||
{ privKey_2, pubKey_2}, | ||||
{ privKey_3, pubKey_3}, | ||||
{0} | ||||
}; | ||||
#else | ||||
/* This requires GCC extensions */ | ||||
static struct ssh_keys_struct keytab[] = { | ||||
{ | { | |||
.privatekey = "%s/.ssh/identity", | .privatekey = "SSH_DIR/identity", | |||
.publickey = "%s/.ssh/identity.pub" | .publickey = "SSH_DIR/identity.pub" | |||
}, | }, | |||
{ | { | |||
.privatekey = "%s/.ssh/id_dsa", | .privatekey = "SSH_DIR/id_dsa", | |||
.publickey = "%s/.ssh/id_dsa.pub", | .publickey = "SSH_DIR/id_dsa.pub", | |||
}, | }, | |||
{ | { | |||
.privatekey = "%s/.ssh/id_rsa", | .privatekey = "SSH_DIR/id_rsa", | |||
.publickey = "%s/.ssh/id_rsa.pub", | .publickey = "SSH_DIR/id_rsa.pub", | |||
}, | }, | |||
{ | { | |||
.privatekey = NULL, | .privatekey = NULL, | |||
.publickey = NULL | .publickey = NULL | |||
} | } | |||
}; | }; | |||
#endif | ||||
/* this function initialy was in the client */ | ||||
/* but the fools are the ones who never change mind */ | ||||
/** | /** | |||
* @brief Tries to automaticaly authenticate with public key and "none" | * @brief Tries to automaticaly authenticate with public key and "none" | |||
* | * | |||
* It may fail, for instance it doesn't ask for a password and uses a defau lt | * It may fail, for instance it doesn't ask for a password and uses a defau lt | |||
* asker for passphrases (in case the private key is encrypted). | * asker for passphrases (in case the private key is encrypted). | |||
* | * | |||
* @param session The ssh session to authenticate with. | * @param session The ssh session to authenticate with. | |||
* | * | |||
* @param passphrase Use this passphrase to unlock the privatekey. Use N ULL | * @param passphrase Use this passphrase to unlock the privatekey. Use N ULL | |||
skipping to change at line 794 | skipping to change at line 814 | |||
* should be asked. | * should be asked. | |||
* | * | |||
* @returns SSH_AUTH_ERROR: A serious error happened\n | * @returns SSH_AUTH_ERROR: A serious error happened\n | |||
* SSH_AUTH_DENIED: Authentication failed: use another method\n | * SSH_AUTH_DENIED: Authentication failed: use another method\n | |||
* SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | * SSH_AUTH_PARTIAL: You've been partially authenticated, you stil l | |||
* have to use another method\n | * have to use another method\n | |||
* SSH_AUTH_SUCCESS: Authentication success | * SSH_AUTH_SUCCESS: Authentication success | |||
* | * | |||
* @see ssh_userauth_kbdint() | * @see ssh_userauth_kbdint() | |||
* @see ssh_userauth_password() | * @see ssh_userauth_password() | |||
* @see ssh_options_set_identity() | * @see ssh_options_set() | |||
*/ | */ | |||
int ssh_userauth_autopubkey(SSH_SESSION *session, const char *passphrase) { | int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) { | |||
struct public_key_struct *publickey; | struct ssh_public_key_struct *publickey; | |||
STRING *pubkey; | ssh_string pubkey; | |||
PRIVATE_KEY *privkey; | ssh_private_key privkey; | |||
char *privkeyfile = NULL; | char *privkeyfile = NULL; | |||
char *id = NULL; | char *id = NULL; | |||
size_t size; | size_t size; | |||
unsigned int i = 0; | unsigned int i = 0; | |||
int type = 0; | int type = 0; | |||
int rc; | int rc; | |||
enter_function(); | enter_function(); | |||
/* Always test none authentication */ | /* Always test none authentication */ | |||
rc = ssh_userauth_none(session, NULL); | rc = ssh_userauth_none(session, NULL); | |||
if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_SUCCESS) { | if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_SUCCESS) { | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
/* Try authentication with ssh-agent first */ | /* Try authentication with ssh-agent first */ | |||
#ifndef _WIN32 | #ifndef _WIN32 | |||
if (agent_is_running(session)) { | if (agent_is_running(session)) { | |||
ssh_log(session, SSH_LOG_RARE, | ssh_log(session, SSH_LOG_RARE, | |||
"Trying to authenticate with SSH agent keys"); | "Trying to authenticate with SSH agent keys as user: %s", | |||
session->username); | ||||
for (publickey = agent_get_first_ident(session, &privkeyfile); | for (publickey = agent_get_first_ident(session, &privkeyfile); | |||
publickey != NULL; | publickey != NULL; | |||
publickey = agent_get_next_ident(session, &privkeyfile)) { | publickey = agent_get_next_ident(session, &privkeyfile)) { | |||
ssh_log(session, SSH_LOG_RARE, "Trying identity %s", privkeyfile); | ssh_log(session, SSH_LOG_RARE, "Trying identity %s", privkeyfile); | |||
pubkey = publickey_to_string(publickey); | pubkey = publickey_to_string(publickey); | |||
if (pubkey) { | if (pubkey) { | |||
rc = ssh_userauth_offer_pubkey(session, NULL, publickey->type, pubk ey); | rc = ssh_userauth_offer_pubkey(session, NULL, publickey->type, pubk ey); | |||
skipping to change at line 884 | skipping to change at line 905 | |||
return SSH_AUTH_SUCCESS; | return SSH_AUTH_SUCCESS; | |||
} /* if pubkey */ | } /* if pubkey */ | |||
SAFE_FREE(id); | SAFE_FREE(id); | |||
SAFE_FREE(privkeyfile); | SAFE_FREE(privkeyfile); | |||
publickey_free(publickey); | publickey_free(publickey); | |||
} /* for each privkey */ | } /* for each privkey */ | |||
} /* if agent is running */ | } /* if agent is running */ | |||
#endif | #endif | |||
size = ARRAY_SIZE(keytab); | size = ARRAY_SIZE(keytab); | |||
if (session->options->identity) { | if (session->identity) { | |||
ssh_log(session, SSH_LOG_RARE, | ssh_log(session, SSH_LOG_RARE, | |||
"Trying identity file %s\n", session->options->identity); | "Trying identity file %s\n", session->identity); | |||
id = malloc(strlen(session->options->identity) + 1 + 4); | id = malloc(strlen(session->identity) + 1 + 4); | |||
if (id == NULL) { | if (id == NULL) { | |||
leave_function(); | leave_function(); | |||
return SSH_AUTH_ERROR; | return SSH_AUTH_ERROR; | |||
} | } | |||
sprintf(id, "%s.pub", session->options->identity); | sprintf(id, "%s.pub", session->identity); | |||
keytab[size - 1].privatekey = session->options->identity; | keytab[size - 1].privatekey = session->identity; | |||
keytab[size - 1].publickey = id; | keytab[size - 1].publickey = id; | |||
} | } | |||
for (i = 0, pubkey = try_publickey_from_file(session, keytab[i], | for (i = 0, pubkey = try_publickey_from_file(session, keytab[i], | |||
&privkeyfile, &type); | &privkeyfile, &type); | |||
i < size; | i < size; | |||
pubkey = try_publickey_from_file(session, keytab[i++], | pubkey = try_publickey_from_file(session, keytab[i++], | |||
&privkeyfile, &type)) { | &privkeyfile, &type)) { | |||
if (pubkey == NULL) { | if (pubkey == NULL) { | |||
continue; | continue; | |||
skipping to change at line 917 | skipping to change at line 938 | |||
rc = ssh_userauth_offer_pubkey(session, NULL, type, pubkey); | rc = ssh_userauth_offer_pubkey(session, NULL, type, pubkey); | |||
if (rc == SSH_AUTH_ERROR){ | if (rc == SSH_AUTH_ERROR){ | |||
if (id != NULL) { | if (id != NULL) { | |||
keytab[size - 1].privatekey = NULL; | keytab[size - 1].privatekey = NULL; | |||
keytab[size - 1].publickey = NULL; | keytab[size - 1].publickey = NULL; | |||
SAFE_FREE(id); | SAFE_FREE(id); | |||
} | } | |||
string_free(pubkey); | string_free(pubkey); | |||
SAFE_FREE(privkeyfile); | SAFE_FREE(privkeyfile); | |||
ssh_log(session, SSH_LOG_RARE, "Publickey authentication error"); | ||||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} else { | } else { | |||
if (rc != SSH_AUTH_SUCCESS){ | if (rc != SSH_AUTH_SUCCESS){ | |||
ssh_log(session, SSH_LOG_RARE, "Public key refused by server"); | ssh_log(session, SSH_LOG_RARE, "Publickey refused by server"); | |||
string_free(pubkey); | string_free(pubkey); | |||
pubkey = NULL; | pubkey = NULL; | |||
SAFE_FREE(privkeyfile); | SAFE_FREE(privkeyfile); | |||
privkeyfile = NULL; | privkeyfile = NULL; | |||
continue; | continue; | |||
} | } | |||
} | } | |||
/* Public key accepted by server! */ | /* Public key accepted by server! */ | |||
ssh_log(session, SSH_LOG_RARE, "Trying to read privatekey %s", privkeyf ile); | ||||
privkey = privatekey_from_file(session, privkeyfile, type, passphrase); | privkey = privatekey_from_file(session, privkeyfile, type, passphrase); | |||
if (privkey == NULL) { | if (privkey == NULL) { | |||
ssh_log(session, SSH_LOG_FUNCTIONS, | ssh_log(session, SSH_LOG_FUNCTIONS, | |||
"Reading private key %s failed (bad passphrase ?)", | "Reading private key %s failed (bad passphrase ?)", | |||
privkeyfile); | privkeyfile); | |||
string_free(pubkey); | string_free(pubkey); | |||
pubkey = NULL; | pubkey = NULL; | |||
SAFE_FREE(privkeyfile); | SAFE_FREE(privkeyfile); | |||
privkeyfile = NULL; | privkeyfile = NULL; | |||
continue; /* continue the loop with other pubkey */ | continue; /* continue the loop with other pubkey */ | |||
skipping to change at line 997 | skipping to change at line 1020 | |||
if (id) { | if (id) { | |||
keytab[size - 1].privatekey = NULL; | keytab[size - 1].privatekey = NULL; | |||
keytab[size - 1].publickey = NULL; | keytab[size - 1].publickey = NULL; | |||
SAFE_FREE(id); | SAFE_FREE(id); | |||
} | } | |||
leave_function(); | leave_function(); | |||
return SSH_AUTH_DENIED; | return SSH_AUTH_DENIED; | |||
} | } | |||
static struct ssh_kbdint *kbdint_new(void) { | struct ssh_kbdint_struct { | |||
struct ssh_kbdint *kbd; | uint32_t nprompts; | |||
char *name; | ||||
char *instruction; | ||||
char **prompts; | ||||
unsigned char *echo; /* bool array */ | ||||
char **answers; | ||||
}; | ||||
static ssh_kbdint kbdint_new(void) { | ||||
ssh_kbdint kbd; | ||||
kbd = malloc(sizeof (struct ssh_kbdint)); | kbd = malloc(sizeof (struct ssh_kbdint_struct)); | |||
if (kbd == NULL) { | if (kbd == NULL) { | |||
return NULL; | return NULL; | |||
} | } | |||
ZERO_STRUCTP(kbd); | ZERO_STRUCTP(kbd); | |||
return kbd; | return kbd; | |||
} | } | |||
static void kbdint_free(struct ssh_kbdint *kbd) { | static void kbdint_free(ssh_kbdint kbd) { | |||
int i, n; | int i, n; | |||
if (kbd == NULL) { | if (kbd == NULL) { | |||
return; | return; | |||
} | } | |||
n = kbd->nprompts; | n = kbd->nprompts; | |||
SAFE_FREE(kbd->name); | SAFE_FREE(kbd->name); | |||
SAFE_FREE(kbd->instruction); | SAFE_FREE(kbd->instruction); | |||
skipping to change at line 1040 | skipping to change at line 1072 | |||
for (i = 0; i < n; i++) { | for (i = 0; i < n; i++) { | |||
BURN_STRING(kbd->answers[i]); | BURN_STRING(kbd->answers[i]); | |||
SAFE_FREE(kbd->answers[i]); | SAFE_FREE(kbd->answers[i]); | |||
} | } | |||
SAFE_FREE(kbd->answers); | SAFE_FREE(kbd->answers); | |||
} | } | |||
SAFE_FREE(kbd); | SAFE_FREE(kbd); | |||
} | } | |||
static void kbdint_clean(struct ssh_kbdint *kbd) { | static void kbdint_clean(ssh_kbdint kbd) { | |||
int i, n; | int i, n; | |||
if (kbd == NULL) { | if (kbd == NULL) { | |||
return; | return; | |||
} | } | |||
n = kbd->nprompts; | n = kbd->nprompts; | |||
SAFE_FREE(kbd->name); | SAFE_FREE(kbd->name); | |||
SAFE_FREE(kbd->instruction); | SAFE_FREE(kbd->instruction); | |||
skipping to change at line 1074 | skipping to change at line 1106 | |||
SAFE_FREE(kbd->answers[i]); | SAFE_FREE(kbd->answers[i]); | |||
} | } | |||
SAFE_FREE(kbd->answers); | SAFE_FREE(kbd->answers); | |||
} | } | |||
kbd->nprompts = 0; | kbd->nprompts = 0; | |||
} | } | |||
/* this function sends the first packet as explained in section 3.1 | /* this function sends the first packet as explained in section 3.1 | |||
* of the draft */ | * of the draft */ | |||
static int kbdauth_init(SSH_SESSION *session, const char *user, | static int kbdauth_init(ssh_session session, const char *user, | |||
const char *submethods) { | const char *submethods) { | |||
STRING *usr = NULL; | ssh_string usr = NULL; | |||
STRING *sub = NULL; | ssh_string sub = NULL; | |||
STRING *service = NULL; | ssh_string service = NULL; | |||
STRING *method = NULL; | ssh_string method = NULL; | |||
int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
enter_function(); | enter_function(); | |||
usr = string_from_char(user); | usr = string_from_char(user); | |||
if (usr == NULL) { | if (usr == NULL) { | |||
goto error; | goto error; | |||
} | } | |||
sub = (submethods ? string_from_char(submethods) : string_from_char("")); | sub = (submethods ? string_from_char(submethods) : string_from_char("")); | |||
if (sub == NULL) { | if (sub == NULL) { | |||
skipping to change at line 1134 | skipping to change at line 1166 | |||
buffer_reinit(session->out_buffer); | buffer_reinit(session->out_buffer); | |||
string_free(usr); | string_free(usr); | |||
string_free(service); | string_free(service); | |||
string_free(method); | string_free(method); | |||
string_free(sub); | string_free(sub); | |||
leave_function(); | leave_function(); | |||
return rc; | return rc; | |||
} | } | |||
static int kbdauth_info_get(SSH_SESSION *session) { | static int kbdauth_info_get(ssh_session session) { | |||
STRING *name; /* name of the "asking" window showed to client */ | ssh_string name; /* name of the "asking" window showed to client */ | |||
STRING *instruction; | ssh_string instruction; | |||
STRING *tmp; | ssh_string tmp; | |||
u32 nprompts; | uint32_t nprompts; | |||
u32 i; | uint32_t i; | |||
enter_function(); | enter_function(); | |||
name = buffer_get_ssh_string(session->in_buffer); | name = buffer_get_ssh_string(session->in_buffer); | |||
instruction = buffer_get_ssh_string(session->in_buffer); | instruction = buffer_get_ssh_string(session->in_buffer); | |||
tmp = buffer_get_ssh_string(session->in_buffer); | tmp = buffer_get_ssh_string(session->in_buffer); | |||
buffer_get_u32(session->in_buffer, &nprompts); | buffer_get_u32(session->in_buffer, &nprompts); | |||
if (name == NULL || instruction == NULL || tmp == NULL) { | if (name == NULL || instruction == NULL || tmp == NULL) { | |||
string_free(name); | string_free(name); | |||
skipping to change at line 1251 | skipping to change at line 1283 | |||
leave_function(); | leave_function(); | |||
return SSH_AUTH_ERROR; | return SSH_AUTH_ERROR; | |||
} | } | |||
} | } | |||
leave_function(); | leave_function(); | |||
return SSH_AUTH_INFO; /* we are not auth. but we parsed the packet */ | return SSH_AUTH_INFO; /* we are not auth. but we parsed the packet */ | |||
} | } | |||
/* sends challenge back to the server */ | /* sends challenge back to the server */ | |||
static int kbdauth_send(SSH_SESSION *session) { | static int kbdauth_send(ssh_session session) { | |||
STRING *answer = NULL; | ssh_string answer = NULL; | |||
int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
u32 i; | uint32_t i; | |||
enter_function(); | enter_function(); | |||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_INFO_RESPONSE) < 0 || | if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_INFO_RESPONSE) < 0 || | |||
buffer_add_u32(session->out_buffer, | buffer_add_u32(session->out_buffer, | |||
htonl(session->kbdint->nprompts)) < 0) { | htonl(session->kbdint->nprompts)) < 0) { | |||
goto error; | goto error; | |||
} | } | |||
for (i = 0; i < session->kbdint->nprompts; i++) { | for (i = 0; i < session->kbdint->nprompts; i++) { | |||
skipping to change at line 1324 | skipping to change at line 1356 | |||
* SSH_AUTH_SUCCESS: Authentication success\n | * SSH_AUTH_SUCCESS: Authentication success\n | |||
* SSH_AUTH_INFO: The server asked some questions. Use | * SSH_AUTH_INFO: The server asked some questions. Use | |||
* ssh_userauth_kbdint_getnprompts() and such. | * ssh_userauth_kbdint_getnprompts() and such. | |||
* | * | |||
* @see ssh_userauth_kbdint_getnprompts() | * @see ssh_userauth_kbdint_getnprompts() | |||
* @see ssh_userauth_kbdint_getname() | * @see ssh_userauth_kbdint_getname() | |||
* @see ssh_userauth_kbdint_getinstruction() | * @see ssh_userauth_kbdint_getinstruction() | |||
* @see ssh_userauth_kbdint_getprompt() | * @see ssh_userauth_kbdint_getprompt() | |||
* @see ssh_userauth_kbdint_setanswer() | * @see ssh_userauth_kbdint_setanswer() | |||
*/ | */ | |||
int ssh_userauth_kbdint(SSH_SESSION *session, const char *user, | int ssh_userauth_kbdint(ssh_session session, const char *user, | |||
const char *submethods) { | const char *submethods) { | |||
int rc = SSH_AUTH_ERROR; | int rc = SSH_AUTH_ERROR; | |||
if (session->version == 1) { | if (session->version == 1) { | |||
/* No keyb-interactive for ssh1 */ | /* No keyb-interactive for ssh1 */ | |||
return SSH_AUTH_DENIED; | return SSH_AUTH_DENIED; | |||
} | } | |||
enter_function(); | enter_function(); | |||
if (session->kbdint == NULL) { | if (session->kbdint == NULL) { | |||
/* first time we call. we must ask for a challenge */ | /* first time we call. we must ask for a challenge */ | |||
if (user == NULL) { | if (user == NULL) { | |||
if ((user = session->options->username) == NULL) { | if ((user = session->username) == NULL) { | |||
if (ssh_options_default_username(session->options) < 0) { | if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { | |||
leave_function(); | leave_function(); | |||
return SSH_AUTH_ERROR; | return SSH_AUTH_ERROR; | |||
} else { | } else { | |||
user = session->options->username; | user = session->username; | |||
} | } | |||
} | } | |||
} | } | |||
if (ask_userauth(session)) { | if (ask_userauth(session)) { | |||
leave_function(); | leave_function(); | |||
return SSH_AUTH_ERROR; | return SSH_AUTH_ERROR; | |||
} | } | |||
rc = kbdauth_init(session, user, submethods); | rc = kbdauth_init(session, user, submethods); | |||
skipping to change at line 1404 | skipping to change at line 1436 | |||
/** | /** | |||
* @brief Get the number of prompts (questions) the server has given. | * @brief Get the number of prompts (questions) the server has given. | |||
* | * | |||
* You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | * You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | |||
* function returns the questions from the server. | * function returns the questions from the server. | |||
* | * | |||
* @param session The ssh session to use. | * @param session The ssh session to use. | |||
* | * | |||
* @returns The number of prompts. | * @returns The number of prompts. | |||
*/ | */ | |||
int ssh_userauth_kbdint_getnprompts(SSH_SESSION *session) { | int ssh_userauth_kbdint_getnprompts(ssh_session session) { | |||
return session->kbdint->nprompts; | return session->kbdint->nprompts; | |||
} | } | |||
/** | /** | |||
* @brief Get the "name" of the message block. | * @brief Get the "name" of the message block. | |||
* | * | |||
* You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | * You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | |||
* function returns the questions from the server. | * function returns the questions from the server. | |||
* | * | |||
* @param session The ssh session to use. | * @param session The ssh session to use. | |||
* | * | |||
* @returns The name of the message block. Do not free it. | * @returns The name of the message block. Do not free it. | |||
*/ | */ | |||
const char *ssh_userauth_kbdint_getname(SSH_SESSION *session) { | const char *ssh_userauth_kbdint_getname(ssh_session session) { | |||
return session->kbdint->name; | return session->kbdint->name; | |||
} | } | |||
/** | /** | |||
* @brief Get the "instruction" of the message block. | * @brief Get the "instruction" of the message block. | |||
* | * | |||
* You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | * You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | |||
* function returns the questions from the server. | * function returns the questions from the server. | |||
* | * | |||
* @param session The ssh session to use. | * @param session The ssh session to use. | |||
* | * | |||
* @returns The instruction of the message block. | * @returns The instruction of the message block. | |||
*/ | */ | |||
const char *ssh_userauth_kbdint_getinstruction(SSH_SESSION *session) { | const char *ssh_userauth_kbdint_getinstruction(ssh_session session) { | |||
return session->kbdint->instruction; | return session->kbdint->instruction; | |||
} | } | |||
/** | /** | |||
* @brief Get a prompt from a message block. | * @brief Get a prompt from a message block. | |||
* | * | |||
* You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | * You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. This | |||
* function returns the questions from the server. | * function returns the questions from the server. | |||
* | * | |||
* @param session The ssh session to use. | * @param session The ssh session to use. | |||
* | * | |||
* @param i The inndex number of the i'th prompt. | * @param i The inndex number of the i'th prompt. | |||
* | * | |||
* @param echo When different of NULL, it will obtain a boolean me aning | * @param echo When different of NULL, it will obtain a boolean me aning | |||
* that the resulting user input should be echoed or n ot | * that the resulting user input should be echoed or n ot | |||
* (like passwords). | * (like passwords). | |||
* | * | |||
* @returns A pointer to the prompt. Do not free it. | * @returns A pointer to the prompt. Do not free it. | |||
*/ | */ | |||
const char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session, unsigned in t i, | const char *ssh_userauth_kbdint_getprompt(ssh_session session, unsigned int i, | |||
char *echo) { | char *echo) { | |||
if (i > session->kbdint->nprompts) { | if (i > session->kbdint->nprompts) { | |||
return NULL; | return NULL; | |||
} | } | |||
if (echo) { | if (echo) { | |||
*echo = session->kbdint->echo[i]; | *echo = session->kbdint->echo[i]; | |||
} | } | |||
return session->kbdint->prompts[i]; | return session->kbdint->prompts[i]; | |||
} | } | |||
/** You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. this | /** You have called ssh_userauth_kbdint() and got SSH_AUTH_INFO. this | |||
* function returns the questions from the server | * function returns the questions from the server | |||
* \brief set the answer for a question from a message block. | * \brief set the answer for a question from a message block. | |||
* \param session ssh session | * \param session ssh session | |||
* \param i index number of the ith prompt | * \param i index number of the ith prompt | |||
* \param answer answer to give to server | * \param answer answer to give to server | |||
* \return 0 on success, < 0 on error. | * \return 0 on success, < 0 on error. | |||
*/ | */ | |||
int ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i, | int ssh_userauth_kbdint_setanswer(ssh_session session, unsigned int i, | |||
const char *answer) { | const char *answer) { | |||
if (session == NULL || answer == NULL || i > session->kbdint->nprompts) { | if (session == NULL || answer == NULL || i > session->kbdint->nprompts) { | |||
return -1; | return -1; | |||
} | } | |||
if (session->kbdint->answers == NULL) { | if (session->kbdint->answers == NULL) { | |||
session->kbdint->answers = malloc(sizeof(char*) * session->kbdint->npro mpts); | session->kbdint->answers = malloc(sizeof(char*) * session->kbdint->npro mpts); | |||
if (session->kbdint->answers == NULL) { | if (session->kbdint->answers == NULL) { | |||
return -1; | return -1; | |||
} | } | |||
End of changes. 57 change blocks. | ||||
102 lines changed or deleted | 134 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |