mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
ssh: improve key file search
For private keys, use the first match from: user-specified key file (if provided), ~/.ssh/id_rsa, ~/.ssh/id_dsa, ./id_rsa, ./id_dsa Note that the previous code only looked for id_dsa files. id_rsa is now generally preferred, as it supports larger key sizes. For public keys, use the user-specified key file, if provided. Otherwise, try to extract the public key from the private key file. This means that passing --pubkey is typically no longer required, and makes the key-handling behavior more like OpenSSH.
This commit is contained in:
parent
b1c4c39c58
commit
fa7d04fed4
26
docs/MANUAL
26
docs/MANUAL
@ -41,12 +41,19 @@ SIMPLE USAGE
|
|||||||
|
|
||||||
Get a file from an SSH server using SFTP:
|
Get a file from an SSH server using SFTP:
|
||||||
|
|
||||||
curl -u username sftp://shell.example.com/etc/issue
|
curl -u username sftp://example.com/etc/issue
|
||||||
|
|
||||||
Get a file from an SSH server using SCP using a private key to authenticate:
|
Get a file from an SSH server using SCP using a private key
|
||||||
|
(not password-protected) to authenticate:
|
||||||
|
|
||||||
curl -u username: --key ~/.ssh/id_dsa --pubkey ~/.ssh/id_dsa.pub \
|
curl -u username: --key ~/.ssh/id_rsa \
|
||||||
scp://shell.example.com/~/personal.txt
|
scp://example.com/~/file.txt
|
||||||
|
|
||||||
|
Get a file from an SSH server using SCP using a private key
|
||||||
|
(password-protected) to authenticate:
|
||||||
|
|
||||||
|
curl -u username: --key ~/.ssh/id_rsa --pass private_key_password \
|
||||||
|
scp://example.com/~/file.txt
|
||||||
|
|
||||||
Get the main page from an IPv6 web server:
|
Get the main page from an IPv6 web server:
|
||||||
|
|
||||||
@ -91,10 +98,13 @@ USING PASSWORDS
|
|||||||
|
|
||||||
SFTP / SCP
|
SFTP / SCP
|
||||||
|
|
||||||
This is similar to FTP, but you can specify a private key to use instead of
|
This is similar to FTP, but you can use the --key option to specify a
|
||||||
a password. Note that the private key may itself be protected by a password
|
private key to use instead of a password. Note that the private key may
|
||||||
that is unrelated to the login password of the remote system. If you
|
itself be protected by a password that is unrelated to the login password
|
||||||
provide a private key file you must also provide a public key file.
|
of the remote system; this password is specified using the --pass option.
|
||||||
|
Typically, curl will automatically extract the public key from the private
|
||||||
|
key file, but in cases where curl does not have the proper library support,
|
||||||
|
a matching public key file must be specified using the --pubkey option.
|
||||||
|
|
||||||
HTTP
|
HTTP
|
||||||
|
|
||||||
|
@ -825,7 +825,8 @@ If this option is used several times, the last one will be used. If
|
|||||||
unspecified, the option defaults to 60 seconds.
|
unspecified, the option defaults to 60 seconds.
|
||||||
.IP "--key <key>"
|
.IP "--key <key>"
|
||||||
(SSL/SSH) Private key file name. Allows you to provide your private key in this
|
(SSL/SSH) Private key file name. Allows you to provide your private key in this
|
||||||
separate file.
|
separate file. For SSH, if not specified, curl tries the following candidates
|
||||||
|
in order: '~/.ssh/id_rsa', '~/.ssh/id_dsa', './id_rsa', './id_dsa'.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "--key-type <type>"
|
.IP "--key-type <type>"
|
||||||
@ -1283,6 +1284,11 @@ protocol instead of the default HTTP 1.1.
|
|||||||
separate file.
|
separate file.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
|
|
||||||
|
(As of 7.39.0, curl attempts to automatically extract the public key from the
|
||||||
|
private key file, so passing this option is generally not required. Note that
|
||||||
|
this public key extraction requires libcurl to be linked against a copy of
|
||||||
|
libssh2 1.2.8 or higher that is itself linked against OpenSSL.)
|
||||||
.IP "-q"
|
.IP "-q"
|
||||||
If used as the first parameter on the command line, the \fIcurlrc\fP config
|
If used as the first parameter on the command line, the \fIcurlrc\fP config
|
||||||
file will not be read and used. See the \fI-K, --config\fP for details on the
|
file will not be read and used. See the \fI-K, --config\fP for details on the
|
||||||
|
75
lib/ssh.c
75
lib/ssh.c
@ -786,7 +786,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
|||||||
if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
|
if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
|
||||||
(strstr(sshc->authlist, "publickey") != NULL)) {
|
(strstr(sshc->authlist, "publickey") != NULL)) {
|
||||||
char *home = NULL;
|
char *home = NULL;
|
||||||
bool rsa_pub_empty_but_ok = FALSE;
|
bool out_of_memory = FALSE;
|
||||||
|
|
||||||
sshc->rsa_pub = sshc->rsa = NULL;
|
sshc->rsa_pub = sshc->rsa = NULL;
|
||||||
|
|
||||||
@ -794,34 +794,55 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
|||||||
HOME environment variable etc? */
|
HOME environment variable etc? */
|
||||||
home = curl_getenv("HOME");
|
home = curl_getenv("HOME");
|
||||||
|
|
||||||
if(data->set.str[STRING_SSH_PUBLIC_KEY] &&
|
if(data->set.str[STRING_SSH_PRIVATE_KEY])
|
||||||
!*data->set.str[STRING_SSH_PUBLIC_KEY])
|
sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
|
||||||
rsa_pub_empty_but_ok = true;
|
else {
|
||||||
else if(data->set.str[STRING_SSH_PUBLIC_KEY])
|
/* If no private key file is specified, try some common paths. */
|
||||||
sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
|
if(home) {
|
||||||
else if(home)
|
/* Try ~/.ssh first. */
|
||||||
sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
|
sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
|
||||||
else
|
if(!sshc->rsa)
|
||||||
/* as a final resort, try current dir! */
|
out_of_memory = TRUE;
|
||||||
sshc->rsa_pub = strdup("id_dsa.pub");
|
else if(access(sshc->rsa, R_OK) != 0) {
|
||||||
|
Curl_safefree(sshc->rsa);
|
||||||
if(!rsa_pub_empty_but_ok && (sshc->rsa_pub == NULL)) {
|
sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
|
||||||
Curl_safefree(home);
|
if(!sshc->rsa)
|
||||||
state(conn, SSH_SESSION_FREE);
|
out_of_memory = TRUE;
|
||||||
sshc->actualcode = CURLE_OUT_OF_MEMORY;
|
else if(access(sshc->rsa, R_OK) != 0) {
|
||||||
break;
|
Curl_safefree(sshc->rsa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!out_of_memory && !sshc->rsa) {
|
||||||
|
/* Nothing found; try the current dir. */
|
||||||
|
sshc->rsa = strdup("id_rsa");
|
||||||
|
if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
|
||||||
|
Curl_safefree(sshc->rsa);
|
||||||
|
sshc->rsa = strdup("id_dsa");
|
||||||
|
if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
|
||||||
|
Curl_safefree(sshc->rsa);
|
||||||
|
/* Out of guesses. Set to the empty string to avoid
|
||||||
|
* surprising info messages. */
|
||||||
|
sshc->rsa = strdup("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data->set.str[STRING_SSH_PRIVATE_KEY])
|
/*
|
||||||
sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
|
* Unless the user explicitly specifies a public key file, let
|
||||||
else if(home)
|
* libssh2 extract the public key from the private key file.
|
||||||
sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
|
* This is done by simply passing sshc->rsa_pub = NULL.
|
||||||
else
|
*/
|
||||||
/* as a final resort, try current dir! */
|
if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
|
||||||
sshc->rsa = strdup("id_dsa");
|
sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
|
||||||
|
if(!sshc->rsa_pub)
|
||||||
|
out_of_memory = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if(sshc->rsa == NULL) {
|
if(out_of_memory || sshc->rsa == NULL) {
|
||||||
Curl_safefree(home);
|
Curl_safefree(home);
|
||||||
|
Curl_safefree(sshc->rsa);
|
||||||
Curl_safefree(sshc->rsa_pub);
|
Curl_safefree(sshc->rsa_pub);
|
||||||
state(conn, SSH_SESSION_FREE);
|
state(conn, SSH_SESSION_FREE);
|
||||||
sshc->actualcode = CURLE_OUT_OF_MEMORY;
|
sshc->actualcode = CURLE_OUT_OF_MEMORY;
|
||||||
@ -834,8 +855,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
|||||||
|
|
||||||
Curl_safefree(home);
|
Curl_safefree(home);
|
||||||
|
|
||||||
infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
|
infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
|
||||||
infof(data, "Using ssh private key file %s\n", sshc->rsa);
|
infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
|
||||||
|
|
||||||
state(conn, SSH_AUTH_PKEY);
|
state(conn, SSH_AUTH_PKEY);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user