mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 12:20:42 +09:00
Fixed and added support for several identity files.
This commit is contained in:
@@ -252,6 +252,7 @@ enum ssh_options_e {
|
||||
SSH_OPTIONS_USER,
|
||||
SSH_OPTIONS_SSH_DIR,
|
||||
SSH_OPTIONS_IDENTITY,
|
||||
SSH_OPTIONS_ADD_IDENTITY,
|
||||
SSH_OPTIONS_KNOWNHOSTS,
|
||||
SSH_OPTIONS_TIMEOUT,
|
||||
SSH_OPTIONS_TIMEOUT_USEC,
|
||||
@@ -335,10 +336,14 @@ LIBSSH_API void privatekey_free(ssh_private_key prv);
|
||||
LIBSSH_API ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
|
||||
int type, const char *passphrase);
|
||||
LIBSSH_API void publickey_free(ssh_public_key key);
|
||||
LIBSSH_API int ssh_publickey_to_file(ssh_session session, const char *file,
|
||||
ssh_string pubkey, int type);
|
||||
LIBSSH_API ssh_string publickey_from_file(ssh_session session, const char *filename,
|
||||
int *type);
|
||||
LIBSSH_API ssh_public_key publickey_from_privatekey(ssh_private_key prv);
|
||||
LIBSSH_API ssh_string publickey_to_string(ssh_public_key key);
|
||||
LIBSSH_API int ssh_try_publickey_from_file(ssh_session session, const char *keyfile,
|
||||
ssh_string *publickey, int *type);
|
||||
|
||||
LIBSSH_API int ssh_auth_list(ssh_session session);
|
||||
LIBSSH_API char *ssh_basename (const char *path);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
/* in misc.c */
|
||||
/* gets the user home dir. */
|
||||
char *ssh_get_user_home_dir(void);
|
||||
char *ssh_get_local_username(ssh_session session);
|
||||
int ssh_file_readaccess_ok(const char *file);
|
||||
|
||||
/* macro for byte ordering */
|
||||
|
||||
@@ -104,7 +104,7 @@ struct ssh_session_struct {
|
||||
char *host;
|
||||
char *bindaddr; /* TODO: check if needed */
|
||||
char *xbanner; /* TODO: looks like it is not needed */
|
||||
char *identity;
|
||||
struct ssh_list *identity;
|
||||
char *sshdir;
|
||||
char *knownhosts;
|
||||
char *wanted_methods[10];
|
||||
|
||||
269
libssh/auth.c
269
libssh/auth.c
@@ -35,6 +35,7 @@
|
||||
#include "libssh/buffer.h"
|
||||
#include "libssh/agent.h"
|
||||
#include "libssh/keyfiles.h"
|
||||
#include "libssh/misc.h"
|
||||
#include "libssh/packet.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/keys.h"
|
||||
@@ -756,42 +757,6 @@ error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
#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 = "SSH_DIR/identity",
|
||||
.publickey = "SSH_DIR/identity.pub"
|
||||
},
|
||||
{
|
||||
.privatekey = "SSH_DIR/id_dsa",
|
||||
.publickey = "SSH_DIR/id_dsa.pub",
|
||||
},
|
||||
{
|
||||
.privatekey = "SSH_DIR/id_rsa",
|
||||
.publickey = "SSH_DIR/id_rsa.pub",
|
||||
},
|
||||
{
|
||||
.privatekey = NULL,
|
||||
.publickey = NULL
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Tries to automaticaly authenticate with public key and "none"
|
||||
*
|
||||
@@ -815,13 +780,10 @@ static struct ssh_keys_struct keytab[] = {
|
||||
* @see ssh_options_set()
|
||||
*/
|
||||
int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
|
||||
struct ssh_public_key_struct *publickey;
|
||||
ssh_string pubkey;
|
||||
struct ssh_iterator *it;
|
||||
ssh_private_key privkey;
|
||||
char *privkeyfile = NULL;
|
||||
char *id = NULL;
|
||||
size_t size;
|
||||
unsigned int i = 0;
|
||||
ssh_public_key pubkey;
|
||||
ssh_string pubkey_string;
|
||||
int type = 0;
|
||||
int rc;
|
||||
|
||||
@@ -837,142 +799,170 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
|
||||
/* Try authentication with ssh-agent first */
|
||||
#ifndef _WIN32
|
||||
if (agent_is_running(session)) {
|
||||
char *privkey_file = NULL;
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE,
|
||||
"Trying to authenticate with SSH agent keys as user: %s",
|
||||
session->username);
|
||||
|
||||
for (publickey = agent_get_first_ident(session, &privkeyfile);
|
||||
publickey != NULL;
|
||||
publickey = agent_get_next_ident(session, &privkeyfile)) {
|
||||
for (pubkey = agent_get_first_ident(session, &privkey_file);
|
||||
pubkey != NULL;
|
||||
pubkey = agent_get_next_ident(session, &privkey_file)) {
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE, "Trying identity %s", privkeyfile);
|
||||
ssh_log(session, SSH_LOG_RARE, "Trying identity %s", privkey_file);
|
||||
|
||||
pubkey = publickey_to_string(publickey);
|
||||
if (pubkey) {
|
||||
rc = ssh_userauth_offer_pubkey(session, NULL, publickey->type, pubkey);
|
||||
string_free(pubkey);
|
||||
pubkey_string = publickey_to_string(pubkey);
|
||||
if (pubkey_string) {
|
||||
rc = ssh_userauth_offer_pubkey(session, NULL, pubkey->type, pubkey_string);
|
||||
string_free(pubkey_string);
|
||||
if (rc == SSH_AUTH_ERROR) {
|
||||
SAFE_FREE(id);
|
||||
SAFE_FREE(privkeyfile);
|
||||
publickey_free(publickey);
|
||||
SAFE_FREE(privkey_file);
|
||||
publickey_free(pubkey);
|
||||
leave_function();
|
||||
|
||||
return rc;
|
||||
} else if (rc != SSH_AUTH_SUCCESS) {
|
||||
ssh_log(session, SSH_LOG_PACKET, "Public key refused by server\n");
|
||||
SAFE_FREE(id);
|
||||
SAFE_FREE(privkeyfile);
|
||||
publickey_free(publickey);
|
||||
ssh_log(session, SSH_LOG_PROTOCOL, "Public key refused by server");
|
||||
SAFE_FREE(privkey_file);
|
||||
publickey_free(pubkey);
|
||||
continue;
|
||||
}
|
||||
ssh_log(session, SSH_LOG_RARE, "Public key accepted");
|
||||
/* pubkey accepted by server ! */
|
||||
rc = ssh_userauth_agent_pubkey(session, NULL, publickey);
|
||||
rc = ssh_userauth_agent_pubkey(session, NULL, pubkey);
|
||||
if (rc == SSH_AUTH_ERROR) {
|
||||
SAFE_FREE(id);
|
||||
SAFE_FREE(privkeyfile);
|
||||
publickey_free(publickey);
|
||||
SAFE_FREE(privkey_file);
|
||||
publickey_free(pubkey);
|
||||
leave_function();
|
||||
|
||||
return rc;
|
||||
} else if (rc != SSH_AUTH_SUCCESS) {
|
||||
ssh_log(session, SSH_LOG_RARE,
|
||||
"Server accepted public key but refused the signature\n"
|
||||
"It might be a bug of libssh\n");
|
||||
SAFE_FREE(id);
|
||||
SAFE_FREE(privkeyfile);
|
||||
publickey_free(publickey);
|
||||
"Server accepted public key but refused the signature ;"
|
||||
" It might be a bug of libssh");
|
||||
SAFE_FREE(privkey_file);
|
||||
publickey_free(pubkey);
|
||||
continue;
|
||||
}
|
||||
/* auth success */
|
||||
ssh_log(session, SSH_LOG_RARE, "Authentication using %s success\n",
|
||||
privkeyfile);
|
||||
SAFE_FREE(id);
|
||||
SAFE_FREE(privkeyfile);
|
||||
publickey_free(publickey);
|
||||
ssh_log(session, SSH_LOG_PROTOCOL, "Authentication using %s success",
|
||||
privkey_file);
|
||||
SAFE_FREE(privkey_file);
|
||||
publickey_free(pubkey);
|
||||
|
||||
leave_function();
|
||||
|
||||
return SSH_AUTH_SUCCESS;
|
||||
} /* if pubkey */
|
||||
SAFE_FREE(id);
|
||||
SAFE_FREE(privkeyfile);
|
||||
publickey_free(publickey);
|
||||
SAFE_FREE(privkey_file);
|
||||
publickey_free(pubkey);
|
||||
} /* for each privkey */
|
||||
} /* if agent is running */
|
||||
#endif
|
||||
|
||||
size = ARRAY_SIZE(keytab);
|
||||
if (session->identity) {
|
||||
ssh_log(session, SSH_LOG_RARE,
|
||||
"Trying identity file %s\n", session->identity);
|
||||
for (it = ssh_list_get_iterator(session->identity);
|
||||
it != NULL;
|
||||
it = it->next) {
|
||||
char *privkey_file = NULL;
|
||||
int privkey_open = 0;
|
||||
|
||||
id = malloc(strlen(session->identity) + 1 + 4);
|
||||
if (id == NULL) {
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
sprintf(id, "%s.pub", session->identity);
|
||||
|
||||
keytab[size - 1].privatekey = session->identity;
|
||||
keytab[size - 1].publickey = id;
|
||||
}
|
||||
|
||||
for (i = 0, pubkey = try_publickey_from_file(session, keytab[i],
|
||||
&privkeyfile, &type);
|
||||
i < size;
|
||||
pubkey = try_publickey_from_file(session, keytab[i++],
|
||||
&privkeyfile, &type)) {
|
||||
if (pubkey == NULL) {
|
||||
privkey_file = dir_expand_dup(session, it->data, 1);
|
||||
if (privkey_file == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = ssh_userauth_offer_pubkey(session, NULL, type, pubkey);
|
||||
if (rc == SSH_AUTH_ERROR){
|
||||
if (id != NULL) {
|
||||
keytab[size - 1].privatekey = NULL;
|
||||
keytab[size - 1].publickey = NULL;
|
||||
SAFE_FREE(id);
|
||||
ssh_log(session, SSH_LOG_PROTOCOL, "Trying to read privatekey %s", privkey_file);
|
||||
|
||||
rc = ssh_try_publickey_from_file(session, privkey_file, &pubkey_string, &type);
|
||||
if (rc == 1) {
|
||||
char *publickey_file;
|
||||
size_t len;
|
||||
|
||||
privkey = privatekey_from_file(session, privkey_file, type, passphrase);
|
||||
if (privkey == NULL) {
|
||||
ssh_log(session, SSH_LOG_RARE,
|
||||
"Reading private key %s failed (bad passphrase ?)",
|
||||
privkey_file);
|
||||
SAFE_FREE(privkey_file);
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
string_free(pubkey);
|
||||
SAFE_FREE(privkeyfile);
|
||||
privkey_open = 1;
|
||||
|
||||
pubkey = publickey_from_privatekey(privkey);
|
||||
if (pubkey == NULL) {
|
||||
SAFE_FREE(privkey_file);
|
||||
privatekey_free(privkey);
|
||||
ssh_set_error_oom(session);
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
pubkey_string = publickey_to_string(pubkey);
|
||||
type = pubkey->type;
|
||||
publickey_free(pubkey);
|
||||
if (pubkey_string == NULL) {
|
||||
SAFE_FREE(privkey_file);
|
||||
ssh_set_error_oom(session);
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
len = strlen(privkey_file) + 5;
|
||||
publickey_file = malloc(len);
|
||||
if (publickey_file == NULL) {
|
||||
SAFE_FREE(privkey_file);
|
||||
ssh_set_error_oom(session);
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
snprintf(publickey_file, len, "%s.pub", privkey_file);
|
||||
rc = ssh_publickey_to_file(session, publickey_file, pubkey_string, type);
|
||||
if (rc < 0) {
|
||||
ssh_log(session, SSH_LOG_PACKET,
|
||||
"Could not write public key to file: %s", publickey_file);
|
||||
}
|
||||
SAFE_FREE(publickey_file);
|
||||
} else if (rc < 0) {
|
||||
SAFE_FREE(privkey_file);
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = ssh_userauth_offer_pubkey(session, NULL, type, pubkey_string);
|
||||
if (rc == SSH_AUTH_ERROR){
|
||||
SAFE_FREE(privkey_file);
|
||||
string_free(pubkey_string);
|
||||
ssh_log(session, SSH_LOG_RARE, "Publickey authentication error");
|
||||
leave_function();
|
||||
return rc;
|
||||
} else {
|
||||
if (rc != SSH_AUTH_SUCCESS){
|
||||
ssh_log(session, SSH_LOG_RARE, "Publickey refused by server");
|
||||
string_free(pubkey);
|
||||
pubkey = NULL;
|
||||
SAFE_FREE(privkeyfile);
|
||||
privkeyfile = NULL;
|
||||
ssh_log(session, SSH_LOG_PROTOCOL, "Publickey refused by server");
|
||||
SAFE_FREE(privkey_file);
|
||||
string_free(pubkey_string);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Public key accepted by server! */
|
||||
ssh_log(session, SSH_LOG_RARE, "Trying to read privatekey %s", privkeyfile);
|
||||
privkey = privatekey_from_file(session, privkeyfile, type, passphrase);
|
||||
if (privkey == NULL) {
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS,
|
||||
"Reading private key %s failed (bad passphrase ?)",
|
||||
privkeyfile);
|
||||
string_free(pubkey);
|
||||
pubkey = NULL;
|
||||
SAFE_FREE(privkeyfile);
|
||||
privkeyfile = NULL;
|
||||
continue; /* continue the loop with other pubkey */
|
||||
if (!privkey_open) {
|
||||
ssh_log(session, SSH_LOG_PROTOCOL, "Trying to read privatekey %s",
|
||||
privkey_file);
|
||||
privkey = privatekey_from_file(session, privkey_file, type, passphrase);
|
||||
if (privkey == NULL) {
|
||||
ssh_log(session, SSH_LOG_RARE,
|
||||
"Reading private key %s failed (bad passphrase ?)",
|
||||
privkey_file);
|
||||
SAFE_FREE(privkey_file);
|
||||
string_free(pubkey_string);
|
||||
continue; /* continue the loop with other pubkey */
|
||||
}
|
||||
}
|
||||
|
||||
rc = ssh_userauth_pubkey(session, NULL, pubkey, privkey);
|
||||
rc = ssh_userauth_pubkey(session, NULL, pubkey_string, privkey);
|
||||
if (rc == SSH_AUTH_ERROR) {
|
||||
if (id != NULL) {
|
||||
keytab[size - 1].privatekey = NULL;
|
||||
keytab[size - 1].publickey = NULL;
|
||||
SAFE_FREE(id);
|
||||
}
|
||||
string_free(pubkey);
|
||||
SAFE_FREE(privkeyfile);
|
||||
SAFE_FREE(privkey_file);
|
||||
string_free(pubkey_string);
|
||||
privatekey_free(privkey);
|
||||
leave_function();
|
||||
return rc;
|
||||
@@ -980,39 +970,28 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
|
||||
if (rc != SSH_AUTH_SUCCESS){
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS,
|
||||
"The server accepted the public key but refused the signature");
|
||||
string_free(pubkey);
|
||||
pubkey = NULL;
|
||||
SAFE_FREE(privkeyfile);
|
||||
privkeyfile = NULL;
|
||||
SAFE_FREE(privkey_file);
|
||||
string_free(pubkey_string);
|
||||
privatekey_free(privkey);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* auth success */
|
||||
ssh_log(session, SSH_LOG_RARE,
|
||||
"Successfully authenticated using %s", privkeyfile);
|
||||
string_free(pubkey);
|
||||
ssh_log(session, SSH_LOG_PROTOCOL,
|
||||
"Successfully authenticated using %s", privkey_file);
|
||||
SAFE_FREE(privkey_file);
|
||||
string_free(pubkey_string);
|
||||
privatekey_free(privkey);
|
||||
SAFE_FREE(privkeyfile);
|
||||
if (id != NULL) {
|
||||
keytab[size - 1].privatekey = NULL;
|
||||
keytab[size - 1].publickey = NULL;
|
||||
SAFE_FREE(id);
|
||||
}
|
||||
|
||||
leave_function();
|
||||
return SSH_AUTH_SUCCESS;
|
||||
}
|
||||
|
||||
/* at this point, pubkey is NULL and so is privkeyfile */
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS,
|
||||
"Tried every public key, none matched");
|
||||
ssh_set_error(session,SSH_NO_ERROR,"No public key matched");
|
||||
if (id) {
|
||||
keytab[size - 1].privatekey = NULL;
|
||||
keytab[size - 1].publickey = NULL;
|
||||
SAFE_FREE(id);
|
||||
}
|
||||
|
||||
leave_function();
|
||||
return SSH_AUTH_DENIED;
|
||||
|
||||
@@ -887,6 +887,79 @@ void privatekey_free(ssh_private_key prv) {
|
||||
SAFE_FREE(prv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a public key to a file.
|
||||
*
|
||||
* @param[in] session The ssh session to use.
|
||||
*
|
||||
* @param[in] file The filename to write the key into.
|
||||
*
|
||||
* @param[in] pubkey The public key to write.
|
||||
*
|
||||
* @param[in] type The type of the public key.
|
||||
*
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int ssh_publickey_to_file(ssh_session session, const char *file,
|
||||
ssh_string pubkey, int type) {
|
||||
FILE *fp;
|
||||
char *user;
|
||||
char buffer[1024];
|
||||
char host[256];
|
||||
unsigned char *pubkey_64;
|
||||
size_t len;
|
||||
int rc;
|
||||
|
||||
pubkey_64 = bin_to_base64(pubkey->string, string_len(pubkey));
|
||||
if (pubkey_64 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
user = ssh_get_local_username(session);
|
||||
if (user == NULL) {
|
||||
SAFE_FREE(pubkey_64);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = gethostname(host, sizeof(host));
|
||||
if (rc < 0) {
|
||||
SAFE_FREE(user);
|
||||
SAFE_FREE(pubkey_64);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%s %s %s@%s\n",
|
||||
ssh_type_to_char(type),
|
||||
pubkey_64,
|
||||
user,
|
||||
host);
|
||||
|
||||
SAFE_FREE(pubkey_64);
|
||||
SAFE_FREE(user);
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE, "Trying to write public key file: %s", file);
|
||||
ssh_log(session, SSH_LOG_PACKET, "public key file content: %s", buffer);
|
||||
|
||||
fp = fopen(file, "w+");
|
||||
if (fp == NULL) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"Error opening %s: %s", file, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strlen(buffer);
|
||||
if (fwrite(buffer, len, 1, fp) != 1 || ferror(fp)) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"Unable to write to %s", file);
|
||||
fclose(fp);
|
||||
unlink(file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Retrieve a public key from a file
|
||||
* \param session the SSH session
|
||||
* \param filename Filename of the key
|
||||
@@ -964,6 +1037,79 @@ ssh_string publickey_from_file(ssh_session session, const char *filename,
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Try to read the public key from a given file.
|
||||
*
|
||||
* @param[in] session The ssh session to use.
|
||||
*
|
||||
* @param[in] keyfile The name of the private keyfile.
|
||||
*
|
||||
* @param[out] publickey A ssh_string to store the public key.
|
||||
*
|
||||
* @param[out] type A pointer to an integer to store the type.
|
||||
*
|
||||
* @return 0 on success, -1 on error or the private key doesn't
|
||||
* exist, 1 if the public key doesn't exist.
|
||||
*/
|
||||
int ssh_try_publickey_from_file(ssh_session session, const char *keyfile,
|
||||
ssh_string *publickey, int *type) {
|
||||
char *pubkey_file;
|
||||
size_t len;
|
||||
ssh_string pubkey_string;
|
||||
int pubkey_type;
|
||||
|
||||
if (session == NULL || keyfile == NULL || publickey == NULL || type == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (session->sshdir == NULL) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_SSH_DIR, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_PACKET, "Trying to open privatekey %s", keyfile);
|
||||
if (!ssh_file_readaccess_ok(keyfile)) {
|
||||
ssh_log(session, SSH_LOG_PACKET, "Failed to open privatekey %s", keyfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strlen(keyfile) + 5;
|
||||
pubkey_file = malloc(len);
|
||||
if (pubkey_file == NULL) {
|
||||
return -1;
|
||||
}
|
||||
snprintf(pubkey_file, len, "%s.pub", keyfile);
|
||||
|
||||
ssh_log(session, SSH_LOG_PACKET, "Trying to open publickey %s",
|
||||
pubkey_file);
|
||||
if (!ssh_file_readaccess_ok(pubkey_file)) {
|
||||
ssh_log(session, SSH_LOG_PACKET, "Failed to open publickey %s",
|
||||
pubkey_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_PACKET, "Success opening public and private key");
|
||||
|
||||
/*
|
||||
* We are sure both the private and public key file is readable. We return
|
||||
* the public as a string, and the private filename as an argument
|
||||
*/
|
||||
pubkey_string = publickey_from_file(session, pubkey_file, &pubkey_type);
|
||||
if (pubkey_string == NULL) {
|
||||
ssh_log(session, SSH_LOG_PACKET,
|
||||
"Wasn't able to open public key file %s: %s",
|
||||
pubkey_file,
|
||||
ssh_get_error(session));
|
||||
return -1;
|
||||
}
|
||||
|
||||
*publickey = pubkey_string;
|
||||
*type = pubkey_type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssh_string try_publickey_from_file(ssh_session session, struct ssh_keys_struct keytab,
|
||||
char **privkeyfile, int *type) {
|
||||
char *public;
|
||||
|
||||
@@ -158,6 +158,52 @@ uint64_t ntohll(uint64_t a) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
char *ssh_get_local_username(ssh_session session) {
|
||||
DWORD size = 0;
|
||||
char *user;
|
||||
|
||||
/* get the size */
|
||||
GetUserName(NULL, &size);
|
||||
|
||||
user = malloc(size);
|
||||
if (user == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (GetUserName(user, &size)) {
|
||||
return user;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
char *ssh_get_local_username(ssh_session session) {
|
||||
struct passwd pwd;
|
||||
struct passwd *pwdbuf;
|
||||
char buf[NSS_BUFLEN_PASSWD];
|
||||
char *name;
|
||||
int rc;
|
||||
|
||||
rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Couldn't retrieve information for current user!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
name = strdup(pwd.pw_name);
|
||||
|
||||
if (name == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Check if libssh is the required version or get the version
|
||||
* string.
|
||||
|
||||
@@ -83,10 +83,29 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) {
|
||||
}
|
||||
|
||||
if (src->identity) {
|
||||
new->identity = strdup(src->identity);
|
||||
struct ssh_iterator *it;
|
||||
|
||||
new->identity = ssh_list_new();
|
||||
if (new->identity == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
it = ssh_list_get_iterator(src->identity);
|
||||
while (it) {
|
||||
char *id;
|
||||
int rc;
|
||||
|
||||
id = strdup((char *) it->data);
|
||||
if (id == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ssh_list_append(new->identity, id);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
it = it->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (src->sshdir) {
|
||||
@@ -124,29 +143,6 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
static char *get_username_from_uid(ssh_session session, uid_t uid){
|
||||
struct passwd *pwd = NULL;
|
||||
char *name;
|
||||
|
||||
pwd = getpwuid(uid);
|
||||
|
||||
if (pwd == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "uid %d doesn't exist !", uid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
name = strdup(pwd->pw_name);
|
||||
|
||||
if (name == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ssh_options_set_algo(ssh_session session, int algo,
|
||||
const char *list) {
|
||||
if (!verify_existing_algo(algo, list)) {
|
||||
@@ -376,6 +372,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
const void *value) {
|
||||
char *p, *q;
|
||||
long int i;
|
||||
int rc;
|
||||
|
||||
if (session == NULL) {
|
||||
return -1;
|
||||
@@ -442,27 +439,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
case SSH_OPTIONS_USER:
|
||||
SAFE_FREE(session->username);
|
||||
if (value == NULL) { /* set default username */
|
||||
#ifdef _WIN32
|
||||
DWORD size = 0;
|
||||
GetUserName(NULL, &size); //Get Size
|
||||
q = malloc(size);
|
||||
if (q == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return -1;
|
||||
}
|
||||
if (GetUserName(q, &size)) {
|
||||
session->username = q;
|
||||
} else {
|
||||
SAFE_FREE(q);
|
||||
return -1;
|
||||
}
|
||||
#else /* _WIN32 */
|
||||
q = get_username_from_uid(session, getuid());
|
||||
q = ssh_get_local_username(session);
|
||||
if (q == NULL) {
|
||||
return -1;
|
||||
}
|
||||
session->username = q;
|
||||
#endif /* _WIN32 */
|
||||
} else { /* username provided */
|
||||
session->username = strdup(value);
|
||||
if (session->username == NULL) {
|
||||
@@ -489,14 +470,18 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_IDENTITY:
|
||||
|
||||
case SSH_OPTIONS_ADD_IDENTITY:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(session, __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
SAFE_FREE(session->identity);
|
||||
session->identity = dir_expand_dup(session, value, 1);
|
||||
if (session->identity == NULL) {
|
||||
q = dir_expand_dup(session, value, 1);
|
||||
if (q == NULL) {
|
||||
return -1;
|
||||
}
|
||||
rc = ssh_list_prepend(session->identity, q);
|
||||
if (rc < 0) {
|
||||
SAFE_FREE(q);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
*/
|
||||
ssh_session ssh_new(void) {
|
||||
ssh_session session;
|
||||
char *id;
|
||||
int rc;
|
||||
|
||||
session = malloc(sizeof (struct ssh_session_struct));
|
||||
if (session == NULL) {
|
||||
@@ -95,6 +97,39 @@ ssh_session ssh_new(void) {
|
||||
goto err;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
session->identity = ssh_list_new();
|
||||
if (session->identity == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
id = strdup("SSH_DIR/id_rsa");
|
||||
if (id == NULL) {
|
||||
goto err;
|
||||
}
|
||||
rc = ssh_list_append(session->identity, id);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
id = strdup("SSH_DIR/id_dsa");
|
||||
if (id == NULL) {
|
||||
goto err;
|
||||
}
|
||||
rc = ssh_list_append(session->identity, id);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
id = strdup("SSH_DIR/identity");
|
||||
if (id == NULL) {
|
||||
goto err;
|
||||
}
|
||||
rc = ssh_list_append(session->identity, id);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
return session;
|
||||
|
||||
err:
|
||||
@@ -162,10 +197,20 @@ void ssh_free(ssh_session session) {
|
||||
ssh_list_free(session->ssh_message_list);
|
||||
}
|
||||
|
||||
if (session->identity) {
|
||||
char *id;
|
||||
|
||||
for (id = ssh_list_pop_head(char *, session->identity);
|
||||
id != NULL;
|
||||
id = ssh_list_pop_head(char *, session->identity)) {
|
||||
SAFE_FREE(id);
|
||||
}
|
||||
ssh_list_free(session->identity);
|
||||
}
|
||||
|
||||
/* options */
|
||||
SAFE_FREE(session->username);
|
||||
SAFE_FREE(session->host);
|
||||
SAFE_FREE(session->identity);
|
||||
SAFE_FREE(session->sshdir);
|
||||
SAFE_FREE(session->knownhosts);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user