aboutsummaryrefslogtreecommitdiff
path: root/libssh/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'libssh/auth.c')
-rw-r--r--libssh/auth.c251
1 files changed, 115 insertions, 136 deletions
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;