aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libssh/libssh.h5
-rw-r--r--include/libssh/misc.h1
-rw-r--r--include/libssh/session.h2
-rw-r--r--libssh/auth.c251
-rw-r--r--libssh/keyfiles.c146
-rw-r--r--libssh/misc.c46
-rw-r--r--libssh/options.c75
-rw-r--r--libssh/session.c47
8 files changed, 390 insertions, 183 deletions
diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h
index 46b6eb8e..c9047a68 100644
--- a/include/libssh/libssh.h
+++ b/include/libssh/libssh.h
@@ -259,6 +259,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,
@@ -342,10 +343,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);
diff --git a/include/libssh/misc.h b/include/libssh/misc.h
index 647faedc..ddd72fe7 100644
--- a/include/libssh/misc.h
+++ b/include/libssh/misc.h
@@ -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 */
diff --git a/include/libssh/session.h b/include/libssh/session.h
index 582049aa..56352c10 100644
--- a/include/libssh/session.h
+++ b/include/libssh/session.h
@@ -131,7 +131,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];
diff --git a/libssh/auth.c b/libssh/auth.c
index b89f57d0..c73afb05 100644
--- a/libssh/auth.c
+++ b/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"
@@ -902,42 +903,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 automatically authenticate with public key and "none"
*
@@ -961,13 +926,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;
@@ -983,41 +945,40 @@ 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_PROTOCOL, "Public key refused by server");
- SAFE_FREE(id);
- SAFE_FREE(privkeyfile);
- publickey_free(publickey);
+ SAFE_FREE(privkey_file);
+ publickey_free(pubkey);
continue;
}
ssh_log(session, SSH_LOG_PROTOCOL, "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;
@@ -1025,100 +986,129 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
ssh_log(session, SSH_LOG_RARE,
"Server accepted public key but refused the signature ;"
" It might be a bug of libssh");
- SAFE_FREE(id);
- SAFE_FREE(privkeyfile);
- publickey_free(publickey);
+ SAFE_FREE(privkey_file);
+ publickey_free(pubkey);
continue;
}
/* auth success */
ssh_log(session, SSH_LOG_PROTOCOL, "Authentication using %s success",
- privkeyfile);
- SAFE_FREE(id);
- SAFE_FREE(privkeyfile);
- publickey_free(publickey);
+ 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_PROTOCOL,
- "Trying identity file %s", 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;
+ privkey_file = dir_expand_dup(session, it->data, 1);
+ if (privkey_file == NULL) {
+ continue;
}
- sprintf(id, "%s.pub", session->identity);
- keytab[size - 1].privatekey = session->identity;
- keytab[size - 1].publickey = 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;
- 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 = 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;
+ }
+ 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);
+ rc = ssh_userauth_offer_pubkey(session, NULL, type, pubkey_string);
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);
ssh_log(session, SSH_LOG_RARE, "Publickey authentication error");
leave_function();
return rc;
} else {
if (rc != SSH_AUTH_SUCCESS){
ssh_log(session, SSH_LOG_PROTOCOL, "Publickey refused by server");
- string_free(pubkey);
- pubkey = NULL;
- SAFE_FREE(privkeyfile);
- privkeyfile = NULL;
+ SAFE_FREE(privkey_file);
+ string_free(pubkey_string);
continue;
}
}
/* Public key accepted by server! */
- ssh_log(session, SSH_LOG_PROTOCOL, "Trying to read privatekey %s", privkeyfile);
- privkey = privatekey_from_file(session, privkeyfile, type, passphrase);
- if (privkey == NULL) {
- ssh_log(session, SSH_LOG_RARE,
- "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;
@@ -1126,10 +1116,8 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
if (rc != SSH_AUTH_SUCCESS){
ssh_log(session, SSH_LOG_RARE,
"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;
}
@@ -1137,28 +1125,19 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
/* auth success */
ssh_log(session, SSH_LOG_PROTOCOL,
- "Successfully authenticated using %s", privkeyfile);
- string_free(pubkey);
+ "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_PROTOCOL,
"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;
diff --git a/libssh/keyfiles.c b/libssh/keyfiles.c
index ab2050ed..40c60304 100644
--- a/libssh/keyfiles.c
+++ b/libssh/keyfiles.c
@@ -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;
diff --git a/libssh/misc.c b/libssh/misc.c
index 95b20306..22fb1a65 100644
--- a/libssh/misc.c
+++ b/libssh/misc.c
@@ -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.
diff --git a/libssh/options.c b/libssh/options.c
index 7a06fad9..a7d62415 100644
--- a/libssh/options.c
+++ b/libssh/options.c
@@ -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;
diff --git a/libssh/session.c b/libssh/session.c
index a39a68c5..e6d9fc7d 100644
--- a/libssh/session.c
+++ b/libssh/session.c
@@ -54,6 +54,8 @@
*/
ssh_session ssh_new(void) {
ssh_session session;
+ char *id;
+ int rc;
session = malloc(sizeof (struct ssh_session_struct));
if (session == NULL) {
@@ -103,6 +105,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:
@@ -173,10 +208,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);