sshc1 = Curl_conn_meta_get(one, CURL_META_SSH_CONN);
sshc2 = Curl_conn_meta_get(two, CURL_META_SSH_CONN);
- return sshc1 && sshc2 && Curl_safecmp(sshc1->rsa, sshc2->rsa) &&
- Curl_safecmp(sshc1->rsa_pub, sshc2->rsa_pub);
+ return sshc1 && sshc2 && Curl_safecmp(sshc1->priv_key, sshc2->priv_key) &&
+ Curl_safecmp(sshc1->pub_key, sshc2->pub_key);
}
#endif
/* For public key auth we need either the private key or
CURLSSH_AUTH_AGENT. */
if((sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) &&
- (data->set.str[STRING_SSH_PRIVATE_KEY] ||
- (data->set.ssh_auth_types & CURLSSH_AUTH_AGENT))) {
+ (sshc->priv_key || (data->set.ssh_auth_types & CURLSSH_AUTH_AGENT))) {
myssh_to(data, sshc, SSH_AUTH_PKEY_INIT);
infof(data, "Authentication using SSH public key file");
}
/* Two choices, (1) private key was given on CMD,
* (2) use the "default" keys. */
- if(data->set.str[STRING_SSH_PRIVATE_KEY]) {
+ if(sshc->priv_key) {
if(sshc->pubkey && !data->set.ssl.primary.key_passwd) {
rc = ssh_userauth_try_publickey(sshc->ssh_session, NULL, sshc->pubkey);
if(rc == SSH_AUTH_AGAIN)
}
}
- rc = ssh_pki_import_privkey_file(data->
- set.str[STRING_SSH_PRIVATE_KEY],
+ rc = ssh_pki_import_privkey_file(sshc->priv_key,
data->set.ssl.primary.key_passwd, NULL,
NULL, &sshc->privkey);
if(rc != SSH_OK) {
- failf(data, "Could not load private key file %s",
- data->set.str[STRING_SSH_PRIVATE_KEY]);
+ failf(data, "Could not load private key file %s", sshc->priv_key);
rc = myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED);
return rc;
}
sshc->pubkey = NULL;
}
- curlx_safefree(sshc->rsa_pub);
- curlx_safefree(sshc->rsa);
+ curlx_safefree(sshc->pub_key);
+ curlx_safefree(sshc->priv_key);
curlx_safefree(sshc->quote_path1);
curlx_safefree(sshc->quote_path2);
curlx_dyn_free(&sshc->readdir_buf);
Curl_meta_set(data, CURL_META_SSH_EASY, sshp, myssh_easy_dtor))
return CURLE_OUT_OF_MEMORY;
- return CURLE_OK;
+ return Curl_ssh_setup_pkey(data, sshc);
}
static Curl_recv scp_recv, sftp_recv;
sshc->privkey = NULL;
sshc->pubkey = NULL;
- if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
- rc = ssh_pki_import_pubkey_file(data->set.str[STRING_SSH_PUBLIC_KEY],
- &sshc->pubkey);
+ if(sshc->pub_key) {
+ rc = ssh_pki_import_pubkey_file(sshc->pub_key, &sshc->pubkey);
if(rc != SSH_OK) {
failf(data, "Could not load public key file");
return CURLE_FAILED_INIT;
return CURLE_OK;
}
-static CURLcode ssh_state_pkey_init(struct Curl_easy *data,
- struct ssh_conn *sshc)
+static void ssh_state_pkey_init(struct Curl_easy *data, struct ssh_conn *sshc)
{
/*
* Check the supported auth types in the order I feel is most secure
if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
strstr(sshc->authlist, "publickey")) {
- bool out_of_memory = FALSE;
-
- sshc->rsa_pub = sshc->rsa = NULL;
-
- if(data->set.str[STRING_SSH_PRIVATE_KEY]) {
- sshc->rsa = curlx_strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
- if(!sshc->rsa)
- out_of_memory = TRUE;
- }
- else {
- /* To ponder about: should really the lib be messing about with the
- HOME environment variable etc? */
- char *home = curl_getenv("HOME");
- curlx_struct_stat sbuf;
-
- /* If no private key file is specified, try some common paths. */
- if(home) {
- /* Try ~/.ssh first. */
- sshc->rsa = curl_maprintf("%s/.ssh/id_rsa", home);
- if(!sshc->rsa)
- out_of_memory = TRUE;
- else if(curlx_stat(sshc->rsa, &sbuf)) {
- curlx_free(sshc->rsa);
- sshc->rsa = curl_maprintf("%s/.ssh/id_dsa", home);
- if(!sshc->rsa)
- out_of_memory = TRUE;
- else if(curlx_stat(sshc->rsa, &sbuf)) {
- curlx_safefree(sshc->rsa);
- }
- }
- curlx_free(home);
- }
- if(!out_of_memory && !sshc->rsa) {
- /* Nothing found; try the current dir. */
- sshc->rsa = curlx_strdup("id_rsa");
- if(sshc->rsa && curlx_stat(sshc->rsa, &sbuf)) {
- curlx_free(sshc->rsa);
- sshc->rsa = curlx_strdup("id_dsa");
- if(sshc->rsa && curlx_stat(sshc->rsa, &sbuf)) {
- curlx_free(sshc->rsa);
- /* Out of guesses. Set to the empty string to avoid
- * surprising info messages. */
- sshc->rsa = curlx_strdup("");
- }
- }
- }
- }
-
- /*
- * Unless the user explicitly specifies a public key file, let
- * libssh2 extract the public key from the private key file.
- * This is done by passing sshc->rsa_pub = NULL.
- */
- if(!out_of_memory && data->set.str[STRING_SSH_PUBLIC_KEY] &&
- /* treat empty string the same way as NULL */
- data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
- sshc->rsa_pub = curlx_strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
- if(!sshc->rsa_pub)
- out_of_memory = TRUE;
- }
-
- if(out_of_memory || !sshc->rsa) {
- curlx_safefree(sshc->rsa);
- curlx_safefree(sshc->rsa_pub);
- myssh_to(data, sshc, SSH_SESSION_FREE);
- return CURLE_OUT_OF_MEMORY;
- }
-
- sshc->passphrase = data->set.ssl.primary.key_passwd;
- if(!sshc->passphrase)
- sshc->passphrase = "";
-
- if(sshc->rsa_pub)
- infof(data, "SSH: trying public key file '%s'", sshc->rsa_pub);
- infof(data, "SSH: trying private key file '%s'", sshc->rsa);
-
+ if(sshc->pub_key)
+ infof(data, "SSH: trying public key file '%s'", sshc->pub_key);
+ infof(data, "SSH: trying private key file '%s'", sshc->priv_key);
myssh_to(data, sshc, SSH_AUTH_PKEY);
}
- else {
+ else
myssh_to(data, sshc, SSH_AUTH_PASS_INIT);
- }
- return CURLE_OK;
}
static CURLcode sftp_quote_stat(struct Curl_easy *data,
libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
user,
curlx_uztoui(strlen(user)),
- sshc->rsa_pub,
- sshc->rsa, sshc->passphrase);
+ sshc->pub_key,
+ sshc->priv_key, sshc->passphrase);
if(rc == LIBSSH2_ERROR_EAGAIN)
return CURLE_AGAIN;
- curlx_safefree(sshc->rsa_pub);
- curlx_safefree(sshc->rsa);
-
if(rc == 0) {
sshc->authed = TRUE;
infof(data, "SSH: authenticated via publickey");
DEBUGASSERT(!sshc->kh);
DEBUGASSERT(!sshc->ssh_agent);
- curlx_safefree(sshc->rsa_pub);
- curlx_safefree(sshc->rsa);
+ curlx_safefree(sshc->pub_key);
+ curlx_safefree(sshc->priv_key);
curlx_safefree(sshc->quote_path1);
curlx_safefree(sshc->quote_path2);
curlx_safefree(sshc->homedir);
break;
case SSH_AUTH_PKEY_INIT:
- result = ssh_state_pkey_init(data, sshc);
+ ssh_state_pkey_init(data, sshc);
break;
case SSH_AUTH_PKEY:
if(Curl_meta_set(data, CURL_META_SSH_EASY, sshp, myssh_easy_dtor))
return CURLE_OUT_OF_MEMORY;
- return CURLE_OK;
+ return Curl_ssh_setup_pkey(data, sshc);
}
static Curl_recv scp_recv, sftp_recv;
/* common */
const char *passphrase; /* pass-phrase to use */
- char *rsa_pub; /* strdup'ed public key file */
- char *rsa; /* strdup'ed private key file */
+ char *pub_key; /* strdup'ed public key file */
+ char *priv_key; /* strdup'ed private key file */
sshstate state; /* always use ssh.c:state() to change state! */
sshstate nextstate; /* the state to goto after stopping */
struct curl_slist *quote_item; /* for the quote option */
#include "escape.h"
#include "select.h" /* for Curl_pollset_change() */
#include "url.h" /* for Curl_conn_meta_get() */
+#include "curlx/fopen.h"
#ifdef CURLVERBOSE
const char *Curl_ssh_statename(sshstate state)
return CURLE_OK;
}
+CURLcode Curl_ssh_setup_pkey(struct Curl_easy *data, struct ssh_conn *sshc)
+{
+ char *home = NULL;
+ if(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) {
+ sshc->pub_key = sshc->priv_key = NULL;
+
+ if(data->set.str[STRING_SSH_PRIVATE_KEY]) {
+ sshc->priv_key = curlx_strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
+ if(!sshc->priv_key)
+ goto fail;
+ }
+ else {
+ /* To ponder about: should really the lib be messing about with the HOME
+ environment variable etc? */
+ curlx_struct_stat sbuf;
+ home = curl_getenv("HOME");
+
+ /* If no private key file is specified, try some common paths. */
+ if(home) {
+ /* Try ~/.ssh first. */
+ sshc->priv_key = curl_maprintf("%s/.ssh/id_rsa", home);
+ if(!sshc->priv_key)
+ goto fail;
+ else if(curlx_stat(sshc->priv_key, &sbuf)) {
+ curlx_free(sshc->priv_key);
+ sshc->priv_key = curl_maprintf("%s/.ssh/id_dsa", home);
+ if(!sshc->priv_key)
+ goto fail;
+ else if(curlx_stat(sshc->priv_key, &sbuf)) {
+ curlx_safefree(sshc->priv_key);
+ }
+ }
+ curlx_safefree(home);
+ }
+ if(!sshc->priv_key) {
+ /* Nothing found; try the current dir. */
+ sshc->priv_key = curlx_strdup("id_rsa");
+ if(sshc->priv_key && curlx_stat(sshc->priv_key, &sbuf)) {
+ curlx_free(sshc->priv_key);
+ sshc->priv_key = curlx_strdup("id_dsa");
+ if(sshc->priv_key && curlx_stat(sshc->priv_key, &sbuf)) {
+ curlx_free(sshc->priv_key);
+ /* Out of guesses. Set to the empty string to avoid
+ * surprising info messages. */
+ sshc->priv_key = curlx_strdup("");
+ }
+ }
+ }
+ }
+
+ /*
+ * Unless the user explicitly specifies a public key file, let the SSH
+ * library extract the public key from the private key file. This is done
+ * by passing sshc->pub_key = NULL.
+ */
+ if(data->set.str[STRING_SSH_PUBLIC_KEY] &&
+ /* treat empty string the same way as NULL */
+ data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
+ sshc->pub_key = curlx_strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
+ if(!sshc->pub_key)
+ goto fail;
+ }
+
+ sshc->passphrase = data->set.ssl.primary.key_passwd;
+ if(!sshc->passphrase)
+ sshc->passphrase = "";
+
+ if(sshc->pub_key)
+ infof(data, "SSH: public key file '%s'", sshc->pub_key);
+ if(sshc->priv_key)
+ infof(data, "SSH: private key file '%s'", sshc->priv_key);
+ else
+ infof(data, "SSH: public key auth without private key set!");
+ }
+ return CURLE_OK;
+
+fail:
+ curlx_safefree(home);
+ curlx_safefree(sshc->priv_key);
+ curlx_safefree(sshc->pub_key);
+ return CURLE_OUT_OF_MEMORY;
+}
+
#endif /* USE_SSH */
#include "urldata.h"
+struct ssh_conn;
+
CURLcode Curl_getworkingpath(struct Curl_easy *data,
const char *homedir,
char **path);
curl_off_t *startp, curl_off_t *sizep);
CURLcode Curl_ssh_pollset(struct Curl_easy *data, struct easy_pollset *ps);
+CURLcode Curl_ssh_setup_pkey(struct Curl_easy *data, struct ssh_conn *sshc);
+
#endif /* USE_SSH */
#endif /* HEADER_CURL_VSSH_VSSH_H */