]> granicus.if.org Git - curl/commitdiff
Added --pubkey option to curl and made --key also work for SCP/SFTP,
authorDan Fandrich <dan@coneharvesters.com>
Fri, 23 Mar 2007 17:59:40 +0000 (17:59 +0000)
committerDan Fandrich <dan@coneharvesters.com>
Fri, 23 Mar 2007 17:59:40 +0000 (17:59 +0000)
plus made --pass work on an SSH private key as well.

CHANGES
RELEASE-NOTES
docs/MANUAL
docs/curl.1
docs/libcurl/curl_easy_setopt.3
lib/ssh.c
src/main.c

diff --git a/CHANGES b/CHANGES
index 8e1a6c999397e5b49d544df4808f217080609164..dec9678a92925f6fea2545c9c8f82c15326ebe70 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,10 @@
 
                                   Changelog
 
+Dan F (23 March 2007)
+- Added --pubkey option to curl and made --key also work for SCP/SFTP,
+  plus made --pass work on an SSH private key as well.
+
 Yang Tse (20 March 2007)
 - Fixed: When a signal was caught awaiting for an event using Curl_select()
   or Curl_poll() with a non-zero timeout both functions would restart the
index 20ad3d43a0e4c51fba2dd3683c4b70beb00504ce..f3a8cfaa2aa1173648a46066ccc35c415985c7cb 100644 (file)
@@ -2,7 +2,7 @@ Curl and libcurl 7.16.2
 
  Public curl release number:               98
  Releases counted from the very beginning: 125
- Available command line options:           117
+ Available command line options:           118
  Available curl_easy_setopt() options:     141
  Number of public functions in libcurl:    54
  Amount of public web site mirrors:        38
@@ -22,6 +22,8 @@ This release includes the following changes:
  o includes VC8 Makefiles in the release archive
  o --ftp-ssl-control is now honoured on ftps:// URLs
  o added experimental CURL_ACKNOWLEDGE_EINTR symbol definition check
+ o --key and new --pubkey options for SSH public key file logins
+ o --pass now works for a SSH public key file, too
 
 This release includes the following bugfixes:
 
index dd063911dc79b37bb89010f98e549849aead31f8..d087c3b228d9e8fc786c1eaf9e9a01d56f984b50 100644 (file)
@@ -7,7 +7,7 @@ LATEST VERSION
 
 SIMPLE USAGE
 
-  Get the main page from netscape's web-server:
+  Get the main page from Netscape's web-server:
 
         curl http://www.netscape.com/
 
@@ -39,6 +39,15 @@ SIMPLE USAGE
 
         curl --ftp-ssl ftp://files.are.secure.com/secrets.txt
 
+  Get a file from an SSH server using SFTP:
+
+        curl -u username sftp://shell.example.com/~/personal.txt
+
+  Get a file from an SSH server using SCP using a private key to authenticate:
+
+        curl -u username: --key ~/.ssh/id_dsa --pubkey ~/.ssh/id_dsa.pub \
+               scp://shell.example.com/~/personal.txt
+
 
 DOWNLOAD TO A FILE
 
index a08432c0b4ef02b100bf627f2fa7aca41a1276e3..3014613395764c6af2e2f28271e705c277d65fa7 100644 (file)
@@ -582,7 +582,7 @@ See this online resource for further details:
 
 If this option is used twice, the second time will again disable it.
 .IP "--key <key>"
-(SSL) 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.
 
 If this option is used several times, the last one will be used.
@@ -825,7 +825,7 @@ nothing else.
 
 You may use this option as many times as you have number of URLs.
 .IP "--pass <phrase>"
-(SSL) Pass phrase for the private key
+(SSL/SSH) Pass phrase for the private key
 
 If this option is used several times, the last one will be used.
 .IP "--proxy-anyauth"
@@ -860,6 +860,11 @@ CONNECT request and requires that the proxy allows direct connect to the
 remote port number curl wants to tunnel through to.
 
 If this option is used twice, the second will again disable proxy tunnel.
+.IP "--pubkey <key>"
+(SSH) Public key file name. Allows you to provide your public key in this
+separate file.
+
+If this option is used several times, the last one will be used.
 .IP "-P/--ftp-port <address>"
 (FTP) Reverses the initiator/listener roles when connecting with ftp. This
 switch makes Curl use the PORT command instead of PASV. In practice, PORT
index ac26b7237761dd1770242986a83b05f147e45dad..9706008593117b6bcdc2afe6aafa0df2ef6d031b 100644 (file)
@@ -1217,7 +1217,8 @@ engine. You have to set the crypto engine with \fICURLOPT_SSLENGINE\fP.
 \&"DER" format key file currently does not work because of a bug in OpenSSL.
 .IP CURLOPT_SSLKEYPASSWD
 Pass a pointer to a zero terminated string as parameter. It will be used as
-the password required to use the \fICURLOPT_SSLKEY\fP private key.
+the password required to use the \fICURLOPT_SSLKEY\fP or
+\fICURLOPT_SSH_PRIVATE_KEYFILE\fP private key.
 .IP CURLOPT_SSLENGINE
 Pass a pointer to a zero terminated string as parameter. It will be used as
 the identifier for the crypto engine you want to use for your private
@@ -1372,6 +1373,7 @@ libcurl defaults to using \fB~/.ssh/id_dsa.pub\fP.
 .IP CURLOPT_SSH_PRIVATE_KEYFILE
 Pass a char * pointing to a file name for your private key. If not used,
 libcurl defaults to using \fB~/.ssh/id_dsa\fP.
+If the file is password-protected, set the password with \fICURLOPT_SSLKEYPASSWD\fP.
 .SH OTHER OPTIONS
 .IP CURLOPT_PRIVATE
 Pass a char * as parameter, pointing to data that should be associated with
index 0a3ed420da56ddd451b6aa59d84cfccbf80b78b5..30cd2250893240339af5dee4d4dd58d006289734 100644 (file)
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -268,9 +268,6 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
   struct SSHPROTO *ssh;
   const char *fingerprint;
   const char *authlist;
-  char *home;
-  char rsa_pub[PATH_MAX];
-  char rsa[PATH_MAX];
   char tempHome[PATH_MAX];
   curl_socket_t sock;
   char *real_path;
@@ -280,8 +277,6 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
   CURLcode result;
   struct SessionHandle *data = conn->data;
 
-  rsa_pub[0] = rsa[0] = '\0';
-
   result = ssh_init(conn);
   if (result)
     return result;
@@ -369,6 +364,13 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
    */
   if ((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
       (strstr(authlist, "publickey") != NULL)) {
+    const char *home;
+    const char *passphrase;
+    char rsa_pub[PATH_MAX];
+    char rsa[PATH_MAX];
+
+    rsa_pub[0] = rsa[0] = '\0';
+
     /* To ponder about: should really the lib be messing about with the HOME
        environment variable etc? */
     home = curl_getenv("HOME");
@@ -383,6 +385,10 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
     else if (home)
       snprintf(rsa, sizeof(rsa), "%s/.ssh/id_dsa", home);
 
+    passphrase = data->set.key_passwd;
+    if (!passphrase)
+      passphrase = "";
+
     curl_free(home);
 
     infof(conn->data, "Using ssh public key file %s\n", rsa_pub);
@@ -392,7 +398,7 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
       /* The function below checks if the files exists, no need to stat() here.
       */
       if (libssh2_userauth_publickey_fromfile(ssh->ssh_session, ssh->user,
-                                              rsa_pub, rsa, "") == 0) {
+                                              rsa_pub, rsa, passphrase) == 0) {
         authed = TRUE;
         infof(conn->data, "Initialized SSH public key authentication\n");
       }
index 32bc8a03ce4cef0ab66354665e7629b8211fb85f..56bc1c7bf00309c6a199a4c901c9968f7e30c10e 100644 (file)
@@ -389,6 +389,7 @@ struct Configurable {
   char *key;
   char *key_type;
   char *key_passwd;
+  char *pubkey;
   char *engine;
   bool list_engines;
   bool crlf;
@@ -607,9 +608,10 @@ static void help(void)
     " -e/--referer       Referer URL (H)",
     " -E/--cert <cert[:passwd]> Client certificate file and password (SSL)",
     "    --cert-type <type> Certificate file type (DER/PEM/ENG) (SSL)",
-    "    --key <key>     Private key file name (SSL)",
+    "    --key <key>     Private key file name (SSL/SSH)",
     "    --key-type <type> Private key file type (DER/PEM/ENG) (SSL)",
-    "    --pass  <pass>  Pass phrase for the private key (SSL)",
+    "    --pass  <pass>  Pass phrase for the private key (SSL/SSH)",
+    "    --pubkey <key>  Public key file name (SSH)",
     "    --engine <eng>  Crypto engine to use (SSL). \"--engine list\" for list",
     "    --cacert <file> CA certificate to verify peer against (SSL)",
     "    --capath <directory> CA directory (made using c_rehash) to verify",
@@ -1505,6 +1507,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
     {"Ee","pass",        TRUE},
     {"Ef","engine",      TRUE},
     {"Eg","capath ",     TRUE},
+    {"Eh","pubkey",      TRUE},
     {"f", "fail",        FALSE},
     {"F", "form",        TRUE},
     {"Fs","form-string", TRUE},
@@ -2111,6 +2114,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
         /* CA cert directory */
         GetStr(&config->capath, nextarg);
         break;
+      case 'h': /* --pubkey public key file */
+        GetStr(&config->pubkey, nextarg);
+        break;
       default: /* certificate file */
         {
           char *ptr = strchr(nextarg, ':');
@@ -3255,6 +3261,8 @@ static void free_config_fields(struct Configurable *config)
     free(config->key);
   if (config->key_type)
     free(config->key_type);
+  if (config->pubkey)
+    free(config->pubkey);
   if (config->referer)
     free(config->referer);
 
@@ -4112,6 +4120,10 @@ operate(struct Configurable *config, int argc, char *argv[])
         my_setopt(curl, CURLOPT_SSLKEYTYPE, config->key_type);
         my_setopt(curl, CURLOPT_SSLKEYPASSWD, config->key_passwd);
 
+       /* SSH private key uses the same command-line option as SSL private key */
+        my_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, config->key);
+        my_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, config->pubkey);
+
         /* default to strict verifyhost */
         my_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
         if(config->cacert || config->capath) {