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/