1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 /* #define CURL_LIBSSH2_DEBUG */
38 #include <libssh2_sftp.h>
53 #ifdef HAVE_SYS_SOCKET_H
54 #include <sys/socket.h>
56 #ifdef HAVE_NETINET_IN_H
57 #include <netinet/in.h>
59 #ifdef HAVE_ARPA_INET_H
60 #include <arpa/inet.h>
63 #include <sys/utsname.h>
74 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
76 #define in_addr_t unsigned long
79 #include <curl/curl.h>
82 #include "easyif.h" /* for Curl_convert_... prototypes */
88 #include "http.h" /* for HTTP proxy tunnel stuff */
91 #include "speedcheck.h"
98 #include "inet_ntop.h"
99 #include "parsedate.h" /* for the week day and month names */
100 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
101 #include "strtoofft.h"
105 #define _MPRINTF_REPLACE /* use our functions only */
106 #include <curl/mprintf.h>
108 #include "curl_memory.h"
109 /* The last #include file should be: */
110 #include "memdebug.h"
113 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
114 have their definition hidden well */
117 /* Local functions: */
118 static const char *sftp_libssh2_strerror(unsigned long err);
119 static LIBSSH2_ALLOC_FUNC(libssh2_malloc);
120 static LIBSSH2_REALLOC_FUNC(libssh2_realloc);
121 static LIBSSH2_FREE_FUNC(libssh2_free);
123 static CURLcode get_pathname(const char **cpp, char **path);
125 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
126 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
127 static CURLcode ssh_do(struct connectdata *conn, bool *done);
129 static CURLcode ssh_getworkingpath(struct connectdata *conn,
130 char *homedir, /* when SFTP is used */
133 static CURLcode scp_done(struct connectdata *conn,
134 CURLcode, bool premature);
135 static CURLcode scp_doing(struct connectdata *conn,
137 static CURLcode scp_disconnect(struct connectdata *conn);
139 static CURLcode sftp_done(struct connectdata *conn,
140 CURLcode, bool premature);
141 static CURLcode sftp_doing(struct connectdata *conn,
143 static CURLcode sftp_disconnect(struct connectdata *conn);
145 CURLcode sftp_perform(struct connectdata *conn,
149 static int ssh_getsock(struct connectdata *conn,
150 curl_socket_t *sock, /* points to numsocks number
154 static int ssh_perform_getsock(const struct connectdata *conn,
155 curl_socket_t *sock, /* points to numsocks
160 * SCP protocol handler.
163 const struct Curl_handler Curl_handler_scp = {
165 ZERO_NULL, /* setup_connection */
168 ZERO_NULL, /* do_more */
169 ssh_connect, /* connect_it */
170 ssh_multi_statemach, /* connecting */
171 scp_doing, /* doing */
172 ssh_getsock, /* proto_getsock */
173 ssh_getsock, /* doing_getsock */
174 ssh_perform_getsock, /* perform_getsock */
175 scp_disconnect, /* disconnect */
176 PORT_SSH, /* defport */
177 PROT_SCP /* protocol */
182 * SFTP protocol handler.
185 const struct Curl_handler Curl_handler_sftp = {
187 ZERO_NULL, /* setup_connection */
189 sftp_done, /* done */
190 ZERO_NULL, /* do_more */
191 ssh_connect, /* connect_it */
192 ssh_multi_statemach, /* connecting */
193 sftp_doing, /* doing */
194 ssh_getsock, /* proto_getsock */
195 ssh_getsock, /* doing_getsock */
196 ssh_perform_getsock, /* perform_getsock */
197 sftp_disconnect, /* disconnect */
198 PORT_SSH, /* defport */
199 PROT_SFTP /* protocol */
204 kbd_callback(const char *name, int name_len, const char *instruction,
205 int instruction_len, int num_prompts,
206 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
207 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
210 struct connectdata *conn = (struct connectdata *)*abstract;
212 #ifdef CURL_LIBSSH2_DEBUG
213 fprintf(stderr, "name=%s\n", name);
214 fprintf(stderr, "name_len=%d\n", name_len);
215 fprintf(stderr, "instruction=%s\n", instruction);
216 fprintf(stderr, "instruction_len=%d\n", instruction_len);
217 fprintf(stderr, "num_prompts=%d\n", num_prompts);
222 (void)instruction_len;
223 #endif /* CURL_LIBSSH2_DEBUG */
224 if(num_prompts == 1) {
225 responses[0].text = strdup(conn->passwd);
226 responses[0].length = (unsigned int)strlen(conn->passwd);
232 static CURLcode sftp_libssh2_error_to_CURLE(int err)
238 case LIBSSH2_FX_NO_SUCH_FILE:
239 case LIBSSH2_FX_NO_SUCH_PATH:
240 return CURLE_REMOTE_FILE_NOT_FOUND;
242 case LIBSSH2_FX_PERMISSION_DENIED:
243 case LIBSSH2_FX_WRITE_PROTECT:
244 case LIBSSH2_FX_LOCK_CONFlICT:
245 return CURLE_REMOTE_ACCESS_DENIED;
247 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
248 case LIBSSH2_FX_QUOTA_EXCEEDED:
249 return CURLE_REMOTE_DISK_FULL;
251 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
252 return CURLE_REMOTE_FILE_EXISTS;
254 case LIBSSH2_FX_DIR_NOT_EMPTY:
255 return CURLE_QUOTE_ERROR;
264 static CURLcode libssh2_session_error_to_CURLE(int err)
267 /* Ordered by order of appearance in libssh2.h */
268 case LIBSSH2_ERROR_NONE:
271 case LIBSSH2_ERROR_SOCKET_NONE:
272 return CURLE_COULDNT_CONNECT;
274 case LIBSSH2_ERROR_ALLOC:
275 return CURLE_OUT_OF_MEMORY;
277 case LIBSSH2_ERROR_SOCKET_SEND:
278 return CURLE_SEND_ERROR;
280 case LIBSSH2_ERROR_HOSTKEY_INIT:
281 case LIBSSH2_ERROR_HOSTKEY_SIGN:
282 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
283 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
284 return CURLE_PEER_FAILED_VERIFICATION;
286 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
287 return CURLE_LOGIN_DENIED;
289 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
290 case LIBSSH2_ERROR_TIMEOUT:
291 return CURLE_OPERATION_TIMEDOUT;
293 case LIBSSH2_ERROR_EAGAIN:
297 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
298 error code, and possibly add a few new SSH-related one. We must however
299 not return or even depend on libssh2 errors in the public libcurl API */
304 static LIBSSH2_ALLOC_FUNC(libssh2_malloc)
306 (void)abstract; /* arg not used */
307 return malloc(count);
310 static LIBSSH2_REALLOC_FUNC(libssh2_realloc)
312 (void)abstract; /* arg not used */
313 return realloc(ptr, count);
316 static LIBSSH2_FREE_FUNC(libssh2_free)
318 (void)abstract; /* arg not used */
323 * SSH State machine related code
325 /* This is the ONLY way to change SSH state! */
326 static void state(struct connectdata *conn, sshstate nowstate)
328 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
329 /* for debug purposes */
330 static const char * const names[] = {
335 "SSH_AUTH_PKEY_INIT",
337 "SSH_AUTH_PASS_INIT",
339 "SSH_AUTH_HOST_INIT",
346 "SSH_SFTP_QUOTE_INIT",
347 "SSH_SFTP_POSTQUOTE_INIT",
349 "SSH_SFTP_NEXT_QUOTE",
350 "SSH_SFTP_QUOTE_STAT",
351 "SSH_SFTP_QUOTE_SETSTAT",
352 "SSH_SFTP_QUOTE_SYMLINK",
353 "SSH_SFTP_QUOTE_MKDIR",
354 "SSH_SFTP_QUOTE_RENAME",
355 "SSH_SFTP_QUOTE_RMDIR",
356 "SSH_SFTP_QUOTE_UNLINK",
357 "SSH_SFTP_TRANS_INIT",
358 "SSH_SFTP_UPLOAD_INIT",
359 "SSH_SFTP_CREATE_DIRS_INIT",
360 "SSH_SFTP_CREATE_DIRS",
361 "SSH_SFTP_CREATE_DIRS_MKDIR",
362 "SSH_SFTP_READDIR_INIT",
364 "SSH_SFTP_READDIR_LINK",
365 "SSH_SFTP_READDIR_BOTTOM",
366 "SSH_SFTP_READDIR_DONE",
367 "SSH_SFTP_DOWNLOAD_INIT",
368 "SSH_SFTP_DOWNLOAD_STAT",
371 "SSH_SCP_TRANS_INIT",
372 "SSH_SCP_UPLOAD_INIT",
373 "SSH_SCP_DOWNLOAD_INIT",
377 "SSH_SCP_WAIT_CLOSE",
378 "SSH_SCP_CHANNEL_FREE",
379 "SSH_SESSION_DISCONNECT",
384 struct ssh_conn *sshc = &conn->proto.sshc;
386 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
387 if(sshc->state != nowstate) {
388 infof(conn->data, "SFTP %p state change from %s to %s\n",
389 sshc, names[sshc->state], names[nowstate]);
393 sshc->state = nowstate;
396 /* figure out the path to work with in this particular request */
397 static CURLcode ssh_getworkingpath(struct connectdata *conn,
398 char *homedir, /* when SFTP is used */
399 char **path) /* returns the allocated
400 real path to work with */
402 struct SessionHandle *data = conn->data;
403 char *real_path = NULL;
405 int working_path_len;
407 working_path = curl_easy_unescape(data, data->state.path, 0,
410 return CURLE_OUT_OF_MEMORY;
412 /* Check for /~/ , indicating relative to the user's home directory */
413 if(conn->protocol & PROT_SCP) {
414 real_path = malloc(working_path_len+1);
415 if(real_path == NULL) {
417 return CURLE_OUT_OF_MEMORY;
419 if((working_path_len > 1) && (working_path[1] == '~'))
420 /* It is referenced to the home directory, so strip the leading '/' */
421 memcpy(real_path, working_path+1, 1 + working_path_len-1);
423 memcpy(real_path, working_path, 1 + working_path_len);
425 else if(conn->protocol & PROT_SFTP) {
426 if((working_path_len > 1) && (working_path[1] == '~')) {
427 size_t homelen = strlen(homedir);
428 real_path = malloc(homelen + working_path_len + 1);
429 if(real_path == NULL) {
431 return CURLE_OUT_OF_MEMORY;
433 /* It is referenced to the home directory, so strip the
435 memcpy(real_path, homedir, homelen);
436 real_path[homelen] = '/';
437 real_path[homelen+1] = '\0';
438 if(working_path_len > 3) {
439 memcpy(real_path+homelen+1, working_path + 3,
440 1 + working_path_len -3);
444 real_path = malloc(working_path_len+1);
445 if(real_path == NULL) {
447 return CURLE_OUT_OF_MEMORY;
449 memcpy(real_path, working_path, 1+working_path_len);
455 /* store the pointer for the caller to receive */
461 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
462 static int sshkeycallback(CURL *easy,
463 const struct curl_khkey *knownkey, /* known */
464 const struct curl_khkey *foundkey, /* found */
465 enum curl_khmatch match,
473 /* we only allow perfect matches, and we reject everything else */
474 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
479 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
482 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
483 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
485 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
489 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
490 * architectures so we check of the necessary function is present.
492 #ifdef HAVE_LIBSSH2_SCP_SEND64
493 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
495 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
496 (libssh2_uint64_t)d, 0, 0)
500 * ssh_statemach_act() runs the SSH state machine as far as it can without
501 * blocking and without reaching the end. The data the pointer 'block' points
502 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
503 * meaning it wants to be called again when the socket is ready
506 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
508 CURLcode result = CURLE_OK;
509 struct SessionHandle *data = conn->data;
510 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
511 struct ssh_conn *sshc = &conn->proto.sshc;
512 curl_socket_t sock = conn->sock[FIRSTSOCKET];
513 #ifdef CURL_LIBSSH2_DEBUG
514 const char *fingerprint;
515 #endif /* CURL_LIBSSH2_DEBUG */
516 const char *host_public_key_md5;
517 int rc = LIBSSH2_ERROR_NONE, i;
519 int seekerr = CURL_SEEKFUNC_OK;
520 *block = 0; /* we're not blocking by default */
524 switch(sshc->state) {
526 sshc->secondCreateDirs = 0;
527 sshc->nextstate = SSH_NO_STATE;
528 sshc->actualcode = CURLE_OK;
530 rc = libssh2_session_startup(sshc->ssh_session, sock);
531 if(rc == LIBSSH2_ERROR_EAGAIN) {
535 failf(data, "Failure establishing ssh session");
536 state(conn, SSH_SESSION_FREE);
537 sshc->actualcode = CURLE_FAILED_INIT;
541 /* Set libssh2 to non-blocking, since everything internally is
543 libssh2_session_set_blocking(sshc->ssh_session, 0);
545 state(conn, SSH_HOSTKEY);
550 #ifdef CURL_LIBSSH2_DEBUG
552 * Before we authenticate we should check the hostkey's fingerprint
553 * against our known hosts. How that is handled (reading from file,
554 * whatever) is up to us. As for know not much is implemented, besides
555 * showing how to get the fingerprint.
557 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
558 LIBSSH2_HOSTKEY_HASH_MD5);
560 /* The fingerprint points to static storage (!), don't free() it. */
561 infof(data, "Fingerprint: ");
562 for (rc = 0; rc < 16; rc++) {
563 infof(data, "%02X ", (unsigned char) fingerprint[rc]);
566 #endif /* CURL_LIBSSH2_DEBUG */
568 /* Before we authenticate we check the hostkey's MD5 fingerprint
569 * against a known fingerprint, if available. This implementation pulls
570 * it from the curl option.
572 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
573 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
575 host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
576 LIBSSH2_HOSTKEY_HASH_MD5);
577 for (i = 0; i < 16; i++)
578 snprintf(&buf[i*2], 3, "%02x",
579 (unsigned char) host_public_key_md5[i]);
580 if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
582 "Denied establishing ssh session: mismatch md5 fingerprint. "
583 "Remote %s is not equal to %s",
584 buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
585 state(conn, SSH_SESSION_FREE);
586 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
591 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
592 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
593 /* we're asked to verify the host against a file */
596 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
603 * A subject to figure out is what host name we need to pass in here.
604 * What host name does OpenSSH store in its file if an IDN name is
607 struct libssh2_knownhost *host;
608 enum curl_khmatch keymatch;
609 curl_sshkeycallback func =
610 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
611 struct curl_khkey knownkey;
612 struct curl_khkey *knownkeyp = NULL;
613 struct curl_khkey foundkey;
615 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
616 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
618 keycheck = libssh2_knownhost_check(sshc->kh,
621 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
622 LIBSSH2_KNOWNHOST_KEYENC_RAW|
626 infof(data, "SSH host check: %d, key: %s\n", keycheck,
627 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
630 /* setup 'knownkey' */
631 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
632 knownkey.key = host->key;
634 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
635 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
636 knownkeyp = &knownkey;
639 /* setup 'foundkey' */
640 foundkey.key = remotekey;
641 foundkey.len = keylen;
642 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
643 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
646 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
647 * curl_khmatch enum are ever modified, we need to introduce a
648 * translation table here!
650 keymatch = (enum curl_khmatch)keycheck;
652 /* Ask the callback how to behave */
653 rc = func(data, knownkeyp, /* from the knownhosts file */
654 &foundkey, /* from the remote host */
655 keymatch, data->set.ssh_keyfunc_userp);
658 /* no remotekey means failure! */
659 rc = CURLKHSTAT_REJECT;
662 default: /* unknown return codes will equal reject */
663 case CURLKHSTAT_REJECT:
664 state(conn, SSH_SESSION_FREE);
665 case CURLKHSTAT_DEFER:
666 /* DEFER means bail out but keep the SSH_HOSTKEY state */
667 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
669 case CURLKHSTAT_FINE:
670 case CURLKHSTAT_FINE_ADD_TO_FILE:
672 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
673 /* the found host+key didn't match but has been told to be fine
674 anyway so we add it in memory */
675 int addrc = libssh2_knownhost_add(sshc->kh,
676 conn->host.name, NULL,
678 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
679 LIBSSH2_KNOWNHOST_KEYENC_RAW|
682 infof(data, "Warning adding the known host %s failed!\n",
684 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
685 /* now we write the entire in-memory list of known hosts to the
688 libssh2_knownhost_writefile(sshc->kh,
689 data->set.str[STRING_SSH_KNOWNHOSTS],
690 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
692 infof(data, "Warning, writing %s failed!\n",
693 data->set.str[STRING_SSH_KNOWNHOSTS]);
700 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
702 state(conn, SSH_AUTHLIST);
707 * Figure out authentication methods
708 * NB: As soon as we have provided a username to an openssh server we
709 * must never change it later. Thus, always specify the correct username
710 * here, even though the libssh2 docs kind of indicate that it should be
711 * possible to get a 'generic' list (not user-specific) of authentication
712 * methods, presumably with a blank username. That won't work in my
714 * So always specify it here.
716 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
718 (unsigned int)strlen(conn->user));
720 if(!sshc->authlist) {
721 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
722 LIBSSH2_ERROR_EAGAIN) {
723 rc = LIBSSH2_ERROR_EAGAIN;
727 state(conn, SSH_SESSION_FREE);
728 sshc->actualcode = libssh2_session_error_to_CURLE(err);
732 infof(data, "SSH authentication methods available: %s\n",
735 state(conn, SSH_AUTH_PKEY_INIT);
738 case SSH_AUTH_PKEY_INIT:
740 * Check the supported auth types in the order I feel is most secure
741 * with the requested type of authentication
743 sshc->authed = FALSE;
745 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
746 (strstr(sshc->authlist, "publickey") != NULL)) {
749 sshc->rsa_pub = sshc->rsa = NULL;
751 /* To ponder about: should really the lib be messing about with the
752 HOME environment variable etc? */
753 home = curl_getenv("HOME");
755 if(data->set.str[STRING_SSH_PUBLIC_KEY])
756 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
758 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
760 /* as a final resort, try current dir! */
761 sshc->rsa_pub = strdup("id_dsa.pub");
763 if(sshc->rsa_pub == NULL) {
766 state(conn, SSH_SESSION_FREE);
767 sshc->actualcode = CURLE_OUT_OF_MEMORY;
771 if(data->set.str[STRING_SSH_PRIVATE_KEY])
772 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
774 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
776 /* as a final resort, try current dir! */
777 sshc->rsa = strdup("id_dsa");
779 if(sshc->rsa == NULL) {
782 Curl_safefree(sshc->rsa_pub);
783 sshc->rsa_pub = NULL;
784 state(conn, SSH_SESSION_FREE);
785 sshc->actualcode = CURLE_OUT_OF_MEMORY;
789 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
790 if(!sshc->passphrase)
791 sshc->passphrase = "";
796 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
797 infof(data, "Using ssh private key file %s\n", sshc->rsa);
799 state(conn, SSH_AUTH_PKEY);
802 state(conn, SSH_AUTH_PASS_INIT);
807 /* The function below checks if the files exists, no need to stat() here.
809 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
814 sshc->rsa, sshc->passphrase);
815 if(rc == LIBSSH2_ERROR_EAGAIN) {
819 Curl_safefree(sshc->rsa_pub);
820 sshc->rsa_pub = NULL;
821 Curl_safefree(sshc->rsa);
826 infof(data, "Initialized SSH public key authentication\n");
827 state(conn, SSH_AUTH_DONE);
831 (void)libssh2_session_last_error(sshc->ssh_session,
833 infof(data, "SSH public key authentication failed: %s\n", err_msg);
834 state(conn, SSH_AUTH_PASS_INIT);
838 case SSH_AUTH_PASS_INIT:
839 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
840 (strstr(sshc->authlist, "password") != NULL)) {
841 state(conn, SSH_AUTH_PASS);
844 state(conn, SSH_AUTH_HOST_INIT);
849 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
850 (unsigned int)strlen(conn->user),
852 (unsigned int)strlen(conn->passwd),
854 if(rc == LIBSSH2_ERROR_EAGAIN) {
859 infof(data, "Initialized password authentication\n");
860 state(conn, SSH_AUTH_DONE);
863 state(conn, SSH_AUTH_HOST_INIT);
867 case SSH_AUTH_HOST_INIT:
868 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
869 (strstr(sshc->authlist, "hostbased") != NULL)) {
870 state(conn, SSH_AUTH_HOST);
873 state(conn, SSH_AUTH_KEY_INIT);
878 state(conn, SSH_AUTH_KEY_INIT);
881 case SSH_AUTH_KEY_INIT:
882 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
883 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
884 state(conn, SSH_AUTH_KEY);
887 state(conn, SSH_AUTH_DONE);
892 /* Authentication failed. Continue with keyboard-interactive now. */
893 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
898 if(rc == LIBSSH2_ERROR_EAGAIN) {
903 infof(data, "Initialized keyboard interactive authentication\n");
905 state(conn, SSH_AUTH_DONE);
910 failf(data, "Authentication failure");
911 state(conn, SSH_SESSION_FREE);
912 sshc->actualcode = CURLE_LOGIN_DENIED;
917 * At this point we have an authenticated ssh session.
919 infof(data, "Authentication complete\n");
921 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
924 conn->writesockfd = CURL_SOCKET_BAD;
926 if(conn->protocol == PROT_SFTP) {
927 state(conn, SSH_SFTP_INIT);
930 infof(data, "SSH CONNECT phase done\n");
931 state(conn, SSH_STOP);
936 * Start the libssh2 sftp session
938 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
939 if(!sshc->sftp_session) {
940 if(libssh2_session_last_errno(sshc->ssh_session) ==
941 LIBSSH2_ERROR_EAGAIN) {
942 rc = LIBSSH2_ERROR_EAGAIN;
948 (void)libssh2_session_last_error(sshc->ssh_session,
950 failf(data, "Failure initializing sftp session: %s", err_msg);
951 state(conn, SSH_SESSION_FREE);
952 sshc->actualcode = CURLE_FAILED_INIT;
956 state(conn, SSH_SFTP_REALPATH);
959 case SSH_SFTP_REALPATH:
961 char tempHome[PATH_MAX];
964 * Get the "home" directory
966 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
967 tempHome, PATH_MAX-1);
968 if(rc == LIBSSH2_ERROR_EAGAIN) {
972 /* It seems that this string is not always NULL terminated */
974 sshc->homedir = strdup(tempHome);
976 state(conn, SSH_SFTP_CLOSE);
977 sshc->actualcode = CURLE_OUT_OF_MEMORY;
982 /* Return the error type */
983 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
984 result = sftp_libssh2_error_to_CURLE(err);
985 sshc->actualcode = result?result:CURLE_SSH;
986 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
988 state(conn, SSH_STOP);
992 /* This is the last step in the SFTP connect phase. Do note that while
993 we get the homedir here, we get the "workingpath" in the DO action
994 since the homedir will remain the same between request but the
995 working path will not. */
996 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
997 state(conn, SSH_STOP);
1000 case SSH_SFTP_QUOTE_INIT:
1002 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1004 sshc->actualcode = result;
1005 state(conn, SSH_STOP);
1009 if(data->set.quote) {
1010 infof(data, "Sending quote commands\n");
1011 sshc->quote_item = data->set.quote;
1012 state(conn, SSH_SFTP_QUOTE);
1015 state(conn, SSH_SFTP_TRANS_INIT);
1019 case SSH_SFTP_POSTQUOTE_INIT:
1020 if(data->set.postquote) {
1021 infof(data, "Sending quote commands\n");
1022 sshc->quote_item = data->set.postquote;
1023 state(conn, SSH_SFTP_QUOTE);
1026 state(conn, SSH_STOP);
1030 case SSH_SFTP_QUOTE:
1031 /* Send any quote commands */
1036 * Support some of the "FTP" commands
1038 if(curl_strequal("pwd", sshc->quote_item->data)) {
1039 /* output debug output if that is requested */
1040 if(data->set.verbose) {
1041 char tmp[PATH_MAX+1];
1043 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1044 snprintf(tmp, PATH_MAX, "257 \"%s\" is current directory.\n",
1046 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1048 state(conn, SSH_SFTP_NEXT_QUOTE);
1051 else if(sshc->quote_item->data) {
1053 * the arguments following the command must be separated from the
1054 * command with a space so we can check for it unconditionally
1056 cp = strchr(sshc->quote_item->data, ' ');
1058 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1059 state(conn, SSH_SFTP_CLOSE);
1060 sshc->actualcode = CURLE_QUOTE_ERROR;
1065 * also, every command takes at least one argument so we get that
1066 * first argument right now
1068 result = get_pathname(&cp, &sshc->quote_path1);
1070 if(result == CURLE_OUT_OF_MEMORY)
1071 failf(data, "Out of memory");
1073 failf(data, "Syntax error: Bad first parameter");
1074 state(conn, SSH_SFTP_CLOSE);
1075 sshc->actualcode = result;
1080 * SFTP is a binary protocol, so we don't send text commands to
1081 * the server. Instead, we scan for commands for commands used by
1082 * OpenSSH's sftp program and call the appropriate libssh2
1085 if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
1086 curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
1087 curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
1088 /* attribute change */
1090 /* sshc->quote_path1 contains the mode to set */
1091 /* get the destination */
1092 result = get_pathname(&cp, &sshc->quote_path2);
1094 if(result == CURLE_OUT_OF_MEMORY)
1095 failf(data, "Out of memory");
1097 failf(data, "Syntax error in chgrp/chmod/chown: "
1098 "Bad second parameter");
1099 Curl_safefree(sshc->quote_path1);
1100 sshc->quote_path1 = NULL;
1101 state(conn, SSH_SFTP_CLOSE);
1102 sshc->actualcode = result;
1105 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1106 state(conn, SSH_SFTP_QUOTE_STAT);
1109 else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
1110 curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
1111 /* symbolic linking */
1112 /* sshc->quote_path1 is the source */
1113 /* get the destination */
1114 result = get_pathname(&cp, &sshc->quote_path2);
1116 if(result == CURLE_OUT_OF_MEMORY)
1117 failf(data, "Out of memory");
1120 "Syntax error in ln/symlink: Bad second parameter");
1121 Curl_safefree(sshc->quote_path1);
1122 sshc->quote_path1 = NULL;
1123 state(conn, SSH_SFTP_CLOSE);
1124 sshc->actualcode = result;
1127 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1130 else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
1132 state(conn, SSH_SFTP_QUOTE_MKDIR);
1135 else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
1137 /* first param is the source path */
1138 /* second param is the dest. path */
1139 result = get_pathname(&cp, &sshc->quote_path2);
1141 if(result == CURLE_OUT_OF_MEMORY)
1142 failf(data, "Out of memory");
1144 failf(data, "Syntax error in rename: Bad second parameter");
1145 Curl_safefree(sshc->quote_path1);
1146 sshc->quote_path1 = NULL;
1147 state(conn, SSH_SFTP_CLOSE);
1148 sshc->actualcode = result;
1151 state(conn, SSH_SFTP_QUOTE_RENAME);
1154 else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
1156 state(conn, SSH_SFTP_QUOTE_RMDIR);
1159 else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
1160 state(conn, SSH_SFTP_QUOTE_UNLINK);
1164 failf(data, "Unknown SFTP command");
1165 Curl_safefree(sshc->quote_path1);
1166 sshc->quote_path1 = NULL;
1167 Curl_safefree(sshc->quote_path2);
1168 sshc->quote_path2 = NULL;
1169 state(conn, SSH_SFTP_CLOSE);
1170 sshc->actualcode = CURLE_QUOTE_ERROR;
1174 if(!sshc->quote_item) {
1175 state(conn, SSH_SFTP_TRANS_INIT);
1179 case SSH_SFTP_NEXT_QUOTE:
1180 if(sshc->quote_path1) {
1181 Curl_safefree(sshc->quote_path1);
1182 sshc->quote_path1 = NULL;
1184 if(sshc->quote_path2) {
1185 Curl_safefree(sshc->quote_path2);
1186 sshc->quote_path2 = NULL;
1189 sshc->quote_item = sshc->quote_item->next;
1191 if(sshc->quote_item) {
1192 state(conn, SSH_SFTP_QUOTE);
1195 if(sshc->nextstate != SSH_NO_STATE) {
1196 state(conn, sshc->nextstate);
1197 sshc->nextstate = SSH_NO_STATE;
1200 state(conn, SSH_SFTP_TRANS_INIT);
1205 case SSH_SFTP_QUOTE_STAT:
1206 if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1207 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1208 * set them both at once, we need to obtain the current ownership
1209 * first. This takes an extra protocol round trip.
1211 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1212 (unsigned int)strlen(sshc->quote_path2),
1214 &sshc->quote_attrs);
1215 if(rc == LIBSSH2_ERROR_EAGAIN) {
1218 else if(rc != 0) { /* get those attributes */
1219 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1220 Curl_safefree(sshc->quote_path1);
1221 sshc->quote_path1 = NULL;
1222 Curl_safefree(sshc->quote_path2);
1223 sshc->quote_path2 = NULL;
1224 failf(data, "Attempt to get SFTP stats failed: %s",
1225 sftp_libssh2_strerror(err));
1226 state(conn, SSH_SFTP_CLOSE);
1227 sshc->actualcode = CURLE_QUOTE_ERROR;
1232 /* Now set the new attributes... */
1233 if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
1234 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1235 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1236 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1237 Curl_safefree(sshc->quote_path1);
1238 sshc->quote_path1 = NULL;
1239 Curl_safefree(sshc->quote_path2);
1240 sshc->quote_path2 = NULL;
1241 failf(data, "Syntax error: chgrp gid not a number");
1242 state(conn, SSH_SFTP_CLOSE);
1243 sshc->actualcode = CURLE_QUOTE_ERROR;
1247 else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1248 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1249 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1250 /* permissions are octal */
1251 if(sshc->quote_attrs.permissions == 0 &&
1252 !ISDIGIT(sshc->quote_path1[0])) {
1253 Curl_safefree(sshc->quote_path1);
1254 sshc->quote_path1 = NULL;
1255 Curl_safefree(sshc->quote_path2);
1256 sshc->quote_path2 = NULL;
1257 failf(data, "Syntax error: chmod permissions not a number");
1258 state(conn, SSH_SFTP_CLOSE);
1259 sshc->actualcode = CURLE_QUOTE_ERROR;
1263 else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
1264 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1265 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1266 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1267 Curl_safefree(sshc->quote_path1);
1268 sshc->quote_path1 = NULL;
1269 Curl_safefree(sshc->quote_path2);
1270 sshc->quote_path2 = NULL;
1271 failf(data, "Syntax error: chown uid not a number");
1272 state(conn, SSH_SFTP_CLOSE);
1273 sshc->actualcode = CURLE_QUOTE_ERROR;
1278 /* Now send the completed structure... */
1279 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1282 case SSH_SFTP_QUOTE_SETSTAT:
1283 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1284 (unsigned int)strlen(sshc->quote_path2),
1285 LIBSSH2_SFTP_SETSTAT,
1286 &sshc->quote_attrs);
1287 if(rc == LIBSSH2_ERROR_EAGAIN) {
1291 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1292 Curl_safefree(sshc->quote_path1);
1293 sshc->quote_path1 = NULL;
1294 Curl_safefree(sshc->quote_path2);
1295 sshc->quote_path2 = NULL;
1296 failf(data, "Attempt to set SFTP stats failed: %s",
1297 sftp_libssh2_strerror(err));
1298 state(conn, SSH_SFTP_CLOSE);
1299 sshc->actualcode = CURLE_QUOTE_ERROR;
1302 state(conn, SSH_SFTP_NEXT_QUOTE);
1305 case SSH_SFTP_QUOTE_SYMLINK:
1306 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1307 (unsigned int)strlen(sshc->quote_path1),
1309 (unsigned int)strlen(sshc->quote_path2),
1310 LIBSSH2_SFTP_SYMLINK);
1311 if(rc == LIBSSH2_ERROR_EAGAIN) {
1315 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1316 Curl_safefree(sshc->quote_path1);
1317 sshc->quote_path1 = NULL;
1318 Curl_safefree(sshc->quote_path2);
1319 sshc->quote_path2 = NULL;
1320 failf(data, "symlink command failed: %s",
1321 sftp_libssh2_strerror(err));
1322 state(conn, SSH_SFTP_CLOSE);
1323 sshc->actualcode = CURLE_QUOTE_ERROR;
1326 state(conn, SSH_SFTP_NEXT_QUOTE);
1329 case SSH_SFTP_QUOTE_MKDIR:
1330 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1331 (unsigned int)strlen(sshc->quote_path1),
1333 if(rc == LIBSSH2_ERROR_EAGAIN) {
1337 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1338 Curl_safefree(sshc->quote_path1);
1339 sshc->quote_path1 = NULL;
1340 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1341 state(conn, SSH_SFTP_CLOSE);
1342 sshc->actualcode = CURLE_QUOTE_ERROR;
1345 state(conn, SSH_SFTP_NEXT_QUOTE);
1348 case SSH_SFTP_QUOTE_RENAME:
1349 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1350 (unsigned int)strlen(sshc->quote_path1),
1352 (unsigned int)strlen(sshc->quote_path2),
1353 LIBSSH2_SFTP_RENAME_OVERWRITE |
1354 LIBSSH2_SFTP_RENAME_ATOMIC |
1355 LIBSSH2_SFTP_RENAME_NATIVE);
1356 if(rc == LIBSSH2_ERROR_EAGAIN) {
1360 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1361 Curl_safefree(sshc->quote_path1);
1362 sshc->quote_path1 = NULL;
1363 Curl_safefree(sshc->quote_path2);
1364 sshc->quote_path2 = NULL;
1365 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1366 state(conn, SSH_SFTP_CLOSE);
1367 sshc->actualcode = CURLE_QUOTE_ERROR;
1370 state(conn, SSH_SFTP_NEXT_QUOTE);
1373 case SSH_SFTP_QUOTE_RMDIR:
1374 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1375 (unsigned int)strlen(sshc->quote_path1));
1376 if(rc == LIBSSH2_ERROR_EAGAIN) {
1380 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1381 Curl_safefree(sshc->quote_path1);
1382 sshc->quote_path1 = NULL;
1383 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1384 state(conn, SSH_SFTP_CLOSE);
1385 sshc->actualcode = CURLE_QUOTE_ERROR;
1388 state(conn, SSH_SFTP_NEXT_QUOTE);
1391 case SSH_SFTP_QUOTE_UNLINK:
1392 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1393 (unsigned int)strlen(sshc->quote_path1));
1394 if(rc == LIBSSH2_ERROR_EAGAIN) {
1398 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1399 Curl_safefree(sshc->quote_path1);
1400 sshc->quote_path1 = NULL;
1401 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1402 state(conn, SSH_SFTP_CLOSE);
1403 sshc->actualcode = CURLE_QUOTE_ERROR;
1406 state(conn, SSH_SFTP_NEXT_QUOTE);
1409 case SSH_SFTP_TRANS_INIT:
1410 if(data->set.upload)
1411 state(conn, SSH_SFTP_UPLOAD_INIT);
1413 if(data->set.opt_no_body)
1414 state(conn, SSH_STOP);
1415 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1416 state(conn, SSH_SFTP_READDIR_INIT);
1418 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1422 case SSH_SFTP_UPLOAD_INIT:
1424 unsigned long flags;
1426 * NOTE!!! libssh2 requires that the destination path is a full path
1427 * that includes the destination file and name OR ends in a "/"
1428 * If this is not done the destination file will be named the
1429 * same name as the last directory in the path.
1432 if(data->state.resume_from != 0) {
1433 LIBSSH2_SFTP_ATTRIBUTES attrs;
1434 if(data->state.resume_from< 0) {
1435 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1436 (unsigned int)strlen(sftp_scp->path),
1437 LIBSSH2_SFTP_STAT, &attrs);
1438 if(rc == LIBSSH2_ERROR_EAGAIN) {
1442 data->state.resume_from = 0;
1445 data->state.resume_from = attrs.filesize;
1450 if(data->set.ftp_append)
1451 /* Try to open for append, but create if nonexisting */
1452 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1453 else if (data->state.resume_from > 0)
1454 /* If we have restart position then open for append */
1455 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1457 /* Clear file before writing (normal behaviour) */
1458 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1461 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1462 (unsigned int)strlen(sftp_scp->path),
1463 flags, data->set.new_file_perms,
1464 LIBSSH2_SFTP_OPENFILE);
1466 if(!sshc->sftp_handle) {
1467 rc = libssh2_session_last_errno(sshc->ssh_session);
1469 if(LIBSSH2_ERROR_EAGAIN == rc)
1472 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1473 /* only when there was an SFTP protocol error can we extract
1475 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1477 err = -1; /* not an sftp error at all */
1479 if(sshc->secondCreateDirs) {
1480 state(conn, SSH_SFTP_CLOSE);
1481 sshc->actualcode = err>= LIBSSH2_FX_OK?
1482 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1483 failf(data, "Creating the dir/file failed: %s",
1484 sftp_libssh2_strerror(err));
1487 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1488 (err == LIBSSH2_FX_FAILURE) ||
1489 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1490 (data->set.ftp_create_missing_dirs &&
1491 (strlen(sftp_scp->path) > 1))) {
1492 /* try to create the path remotely */
1493 sshc->secondCreateDirs = 1;
1494 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1497 state(conn, SSH_SFTP_CLOSE);
1498 sshc->actualcode = err>= LIBSSH2_FX_OK?
1499 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1500 if(!sshc->actualcode) {
1501 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1502 zero even though libssh2_sftp_open() failed previously! We need
1503 to work around that! */
1504 sshc->actualcode = CURLE_SSH;
1507 failf(data, "Upload failed: %s (%d/%d)",
1508 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1514 /* If we have restart point then we need to seek to the correct
1516 if(data->state.resume_from > 0) {
1517 /* Let's read off the proper amount of bytes from the input. */
1518 if(conn->seek_func) {
1519 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1523 if(seekerr != CURL_SEEKFUNC_OK){
1525 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1526 failf(data, "Could not seek stream");
1527 return CURLE_FTP_COULDNT_USE_REST;
1529 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1531 curl_off_t passed=0;
1532 curl_off_t readthisamountnow;
1533 curl_off_t actuallyread;
1535 readthisamountnow = (data->state.resume_from - passed);
1537 if(readthisamountnow > BUFSIZE)
1538 readthisamountnow = BUFSIZE;
1541 (curl_off_t) conn->fread_func(data->state.buffer, 1,
1542 (size_t)readthisamountnow,
1545 passed += actuallyread;
1546 if((actuallyread <= 0) || (actuallyread > readthisamountnow)) {
1547 /* this checks for greater-than only to make sure that the
1548 CURL_READFUNC_ABORT return code still aborts */
1549 failf(data, "Failed to read data");
1550 return CURLE_FTP_COULDNT_USE_REST;
1552 } while(passed < data->state.resume_from);
1556 /* now, decrease the size of the read */
1557 if(data->set.infilesize>0) {
1558 data->set.infilesize -= data->state.resume_from;
1559 data->req.size = data->set.infilesize;
1560 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1563 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1565 if(data->set.infilesize>0) {
1566 data->req.size = data->set.infilesize;
1567 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1570 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1572 /* not set by Curl_setup_transfer to preserve keepon bits */
1573 conn->sockfd = conn->writesockfd;
1576 state(conn, SSH_SFTP_CLOSE);
1577 sshc->actualcode = result;
1580 /* store this original bitmask setup to use later on if we can't
1581 figure out a "real" bitmask */
1582 sshc->orig_waitfor = data->req.keepon;
1584 state(conn, SSH_STOP);
1589 case SSH_SFTP_CREATE_DIRS_INIT:
1590 if(strlen(sftp_scp->path) > 1) {
1591 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1592 state(conn, SSH_SFTP_CREATE_DIRS);
1595 state(conn, SSH_SFTP_UPLOAD_INIT);
1599 case SSH_SFTP_CREATE_DIRS:
1600 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1601 *sshc->slash_pos = 0;
1603 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1604 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1608 state(conn, SSH_SFTP_UPLOAD_INIT);
1612 case SSH_SFTP_CREATE_DIRS_MKDIR:
1613 /* 'mode' - parameter is preliminary - default to 0644 */
1614 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1615 (unsigned int)strlen(sftp_scp->path),
1616 data->set.new_directory_perms);
1617 if(rc == LIBSSH2_ERROR_EAGAIN) {
1620 *sshc->slash_pos = '/';
1623 unsigned int sftp_err = 0;
1625 * Abort if failure wasn't that the dir already exists or the
1626 * permission was denied (creation might succeed further down the
1627 * path) - retry on unspecific FAILURE also
1629 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1630 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1631 (sftp_err != LIBSSH2_FX_FAILURE) &&
1632 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1633 result = sftp_libssh2_error_to_CURLE(sftp_err);
1634 state(conn, SSH_SFTP_CLOSE);
1635 sshc->actualcode = result?result:CURLE_SSH;
1639 state(conn, SSH_SFTP_CREATE_DIRS);
1642 case SSH_SFTP_READDIR_INIT:
1644 * This is a directory that we are trying to get, so produce a directory
1647 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1650 strlen(sftp_scp->path),
1651 0, 0, LIBSSH2_SFTP_OPENDIR);
1652 if(!sshc->sftp_handle) {
1653 if(libssh2_session_last_errno(sshc->ssh_session) ==
1654 LIBSSH2_ERROR_EAGAIN) {
1655 rc = LIBSSH2_ERROR_EAGAIN;
1659 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1660 failf(data, "Could not open directory for reading: %s",
1661 sftp_libssh2_strerror(err));
1662 state(conn, SSH_SFTP_CLOSE);
1663 result = sftp_libssh2_error_to_CURLE(err);
1664 sshc->actualcode = result?result:CURLE_SSH;
1668 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1669 state(conn, SSH_SFTP_CLOSE);
1670 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1673 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1674 Curl_safefree(sshc->readdir_filename);
1675 sshc->readdir_filename = NULL;
1676 state(conn, SSH_SFTP_CLOSE);
1677 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1680 state(conn, SSH_SFTP_READDIR);
1683 case SSH_SFTP_READDIR:
1684 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1685 sshc->readdir_filename,
1687 sshc->readdir_longentry,
1689 &sshc->readdir_attrs);
1690 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1691 rc = LIBSSH2_ERROR_EAGAIN;
1694 if(sshc->readdir_len > 0) {
1695 sshc->readdir_filename[sshc->readdir_len] = '\0';
1697 if(data->set.ftp_list_only) {
1700 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1701 if(tmpLine == NULL) {
1702 state(conn, SSH_SFTP_CLOSE);
1703 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1706 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1707 tmpLine, sshc->readdir_len+1);
1708 Curl_safefree(tmpLine);
1711 state(conn, SSH_STOP);
1714 /* since this counts what we send to the client, we include the
1715 newline in this counter */
1716 data->req.bytecount += sshc->readdir_len+1;
1718 /* output debug output if that is requested */
1719 if(data->set.verbose) {
1720 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1721 sshc->readdir_len, conn);
1725 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1726 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1727 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1728 if(!sshc->readdir_line) {
1729 Curl_safefree(sshc->readdir_filename);
1730 sshc->readdir_filename = NULL;
1731 Curl_safefree(sshc->readdir_longentry);
1732 sshc->readdir_longentry = NULL;
1733 state(conn, SSH_SFTP_CLOSE);
1734 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1738 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1739 sshc->readdir_currLen);
1740 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1741 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1742 LIBSSH2_SFTP_S_IFLNK)) {
1743 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1744 if(sshc->readdir_linkPath == NULL) {
1745 Curl_safefree(sshc->readdir_filename);
1746 sshc->readdir_filename = NULL;
1747 Curl_safefree(sshc->readdir_longentry);
1748 sshc->readdir_longentry = NULL;
1749 state(conn, SSH_SFTP_CLOSE);
1750 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1754 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1755 sshc->readdir_filename);
1756 state(conn, SSH_SFTP_READDIR_LINK);
1759 state(conn, SSH_SFTP_READDIR_BOTTOM);
1763 else if(sshc->readdir_len == 0) {
1764 Curl_safefree(sshc->readdir_filename);
1765 sshc->readdir_filename = NULL;
1766 Curl_safefree(sshc->readdir_longentry);
1767 sshc->readdir_longentry = NULL;
1768 state(conn, SSH_SFTP_READDIR_DONE);
1771 else if(sshc->readdir_len <= 0) {
1772 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1773 result = sftp_libssh2_error_to_CURLE(err);
1774 sshc->actualcode = result?result:CURLE_SSH;
1775 failf(data, "Could not open remote file for reading: %s :: %d",
1776 sftp_libssh2_strerror(err),
1777 libssh2_session_last_errno(sshc->ssh_session));
1778 Curl_safefree(sshc->readdir_filename);
1779 sshc->readdir_filename = NULL;
1780 Curl_safefree(sshc->readdir_longentry);
1781 sshc->readdir_longentry = NULL;
1782 state(conn, SSH_SFTP_CLOSE);
1787 case SSH_SFTP_READDIR_LINK:
1789 libssh2_sftp_symlink_ex(sshc->sftp_session,
1790 sshc->readdir_linkPath,
1791 (unsigned int) strlen(sshc->readdir_linkPath),
1792 sshc->readdir_filename,
1793 PATH_MAX, LIBSSH2_SFTP_READLINK);
1794 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1795 rc = LIBSSH2_ERROR_EAGAIN;
1798 Curl_safefree(sshc->readdir_linkPath);
1799 sshc->readdir_linkPath = NULL;
1800 sshc->readdir_line = realloc(sshc->readdir_line,
1801 sshc->readdir_totalLen + 4 +
1803 if(!sshc->readdir_line) {
1804 Curl_safefree(sshc->readdir_filename);
1805 sshc->readdir_filename = NULL;
1806 Curl_safefree(sshc->readdir_longentry);
1807 sshc->readdir_longentry = NULL;
1808 state(conn, SSH_SFTP_CLOSE);
1809 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1813 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1814 sshc->readdir_currLen,
1815 sshc->readdir_totalLen -
1816 sshc->readdir_currLen,
1818 sshc->readdir_filename);
1820 state(conn, SSH_SFTP_READDIR_BOTTOM);
1823 case SSH_SFTP_READDIR_BOTTOM:
1824 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1825 sshc->readdir_currLen,
1826 sshc->readdir_totalLen -
1827 sshc->readdir_currLen, "\n");
1828 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1830 sshc->readdir_currLen);
1832 if(result == CURLE_OK) {
1834 /* output debug output if that is requested */
1835 if(data->set.verbose) {
1836 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1837 sshc->readdir_currLen, conn);
1839 data->req.bytecount += sshc->readdir_currLen;
1841 Curl_safefree(sshc->readdir_line);
1842 sshc->readdir_line = NULL;
1844 state(conn, SSH_STOP);
1847 state(conn, SSH_SFTP_READDIR);
1850 case SSH_SFTP_READDIR_DONE:
1851 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1852 LIBSSH2_ERROR_EAGAIN) {
1853 rc = LIBSSH2_ERROR_EAGAIN;
1856 sshc->sftp_handle = NULL;
1857 Curl_safefree(sshc->readdir_filename);
1858 sshc->readdir_filename = NULL;
1859 Curl_safefree(sshc->readdir_longentry);
1860 sshc->readdir_longentry = NULL;
1862 /* no data to transfer */
1863 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1864 state(conn, SSH_STOP);
1867 case SSH_SFTP_DOWNLOAD_INIT:
1869 * Work on getting the specified file
1872 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1873 (unsigned int)strlen(sftp_scp->path),
1874 LIBSSH2_FXF_READ, data->set.new_file_perms,
1875 LIBSSH2_SFTP_OPENFILE);
1876 if(!sshc->sftp_handle) {
1877 if(libssh2_session_last_errno(sshc->ssh_session) ==
1878 LIBSSH2_ERROR_EAGAIN) {
1879 rc = LIBSSH2_ERROR_EAGAIN;
1883 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1884 failf(data, "Could not open remote file for reading: %s",
1885 sftp_libssh2_strerror(err));
1886 state(conn, SSH_SFTP_CLOSE);
1887 result = sftp_libssh2_error_to_CURLE(err);
1888 sshc->actualcode = result?result:CURLE_SSH;
1892 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1895 case SSH_SFTP_DOWNLOAD_STAT:
1897 LIBSSH2_SFTP_ATTRIBUTES attrs;
1899 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1900 (unsigned int)strlen(sftp_scp->path),
1901 LIBSSH2_SFTP_STAT, &attrs);
1902 if(rc == LIBSSH2_ERROR_EAGAIN) {
1907 * libssh2_sftp_open() didn't return an error, so maybe the server
1908 * just doesn't support stat()
1910 data->req.size = -1;
1911 data->req.maxdownload = -1;
1916 size = attrs.filesize;
1917 if(conn->data->state.use_range) {
1918 curl_off_t from, to;
1922 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1923 while(*ptr && (isspace((int)*ptr) || (*ptr=='-')))
1925 to=curlx_strtoofft(ptr, &ptr2, 0);
1926 if((ptr == ptr2) /* no "to" value given */
1931 /* from is relative to end of file */
1935 failf(data, "Offset (%"
1936 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1937 from, attrs.filesize);
1938 return CURLE_BAD_DOWNLOAD_RESUME;
1945 size = to - from + 1;
1948 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
1950 data->req.size = size;
1951 data->req.maxdownload = size;
1952 Curl_pgrsSetDownloadSize(data, size);
1955 /* We can resume if we can seek to the resume position */
1956 if(data->state.resume_from) {
1957 if(data->state.resume_from< 0) {
1958 /* We're supposed to download the last abs(from) bytes */
1959 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
1960 failf(data, "Offset (%"
1961 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1962 data->state.resume_from, attrs.filesize);
1963 return CURLE_BAD_DOWNLOAD_RESUME;
1965 /* download from where? */
1966 data->state.resume_from = attrs.filesize - data->state.resume_from;
1969 if((curl_off_t)attrs.filesize < data->state.resume_from) {
1970 failf(data, "Offset (%" FORMAT_OFF_T
1971 ") was beyond file size (%" FORMAT_OFF_T ")",
1972 data->state.resume_from, attrs.filesize);
1973 return CURLE_BAD_DOWNLOAD_RESUME;
1976 /* Does a completed file need to be seeked and started or closed ? */
1977 /* Now store the number of bytes we are expected to download */
1978 data->req.size = attrs.filesize - data->state.resume_from;
1979 data->req.maxdownload = attrs.filesize - data->state.resume_from;
1980 Curl_pgrsSetDownloadSize(data,
1981 attrs.filesize - data->state.resume_from);
1982 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1985 /* Setup the actual download */
1986 if(data->req.size == 0) {
1987 /* no data to transfer */
1988 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1989 infof(data, "File already completely downloaded\n");
1990 state(conn, SSH_STOP);
1994 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
1995 FALSE, NULL, -1, NULL);
1997 /* not set by Curl_setup_transfer to preserve keepon bits */
1998 conn->writesockfd = conn->sockfd;
2000 /* FIXME: here should be explained why we need it to start the
2002 conn->cselect_bits = CURL_CSELECT_IN;
2005 state(conn, SSH_SFTP_CLOSE);
2006 sshc->actualcode = result;
2009 state(conn, SSH_STOP);
2013 case SSH_SFTP_CLOSE:
2014 if(sshc->sftp_handle) {
2015 rc = libssh2_sftp_close(sshc->sftp_handle);
2016 if(rc == LIBSSH2_ERROR_EAGAIN) {
2020 infof(data, "Failed to close libssh2 file\n");
2022 sshc->sftp_handle = NULL;
2024 Curl_safefree(sftp_scp->path);
2025 sftp_scp->path = NULL;
2027 DEBUGF(infof(data, "SFTP DONE done\n"));
2029 state(conn, SSH_SFTP_SHUTDOWN);
2031 state(conn, SSH_STOP);
2032 result = sshc->actualcode;
2035 case SSH_SFTP_SHUTDOWN:
2036 /* during times we get here due to a broken transfer and then the
2037 sftp_handle might not have been taken down so make sure that is done
2038 before we proceed */
2040 if(sshc->sftp_handle) {
2041 rc = libssh2_sftp_close(sshc->sftp_handle);
2042 if(rc == LIBSSH2_ERROR_EAGAIN) {
2046 infof(data, "Failed to close libssh2 file\n");
2048 sshc->sftp_handle = NULL;
2050 if(sshc->sftp_session) {
2051 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2052 if(rc == LIBSSH2_ERROR_EAGAIN) {
2056 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2058 sshc->sftp_session = NULL;
2061 Curl_safefree(sshc->homedir);
2062 sshc->homedir = NULL;
2064 state(conn, SSH_SESSION_DISCONNECT);
2067 case SSH_SCP_TRANS_INIT:
2068 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2070 sshc->actualcode = result;
2071 state(conn, SSH_STOP);
2075 if(data->set.upload) {
2076 if(data->set.infilesize < 0) {
2077 failf(data, "SCP requires a known file size for upload");
2078 sshc->actualcode = CURLE_UPLOAD_FAILED;
2079 state(conn, SSH_SCP_CHANNEL_FREE);
2082 state(conn, SSH_SCP_UPLOAD_INIT);
2085 state(conn, SSH_SCP_DOWNLOAD_INIT);
2089 case SSH_SCP_UPLOAD_INIT:
2091 * libssh2 requires that the destination path is a full path that
2092 * includes the destination file and name OR ends in a "/" . If this is
2093 * not done the destination file will be named the same name as the last
2094 * directory in the path.
2097 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2098 data->set.infilesize);
2099 if(!sshc->ssh_channel) {
2100 if(libssh2_session_last_errno(sshc->ssh_session) ==
2101 LIBSSH2_ERROR_EAGAIN) {
2102 rc = LIBSSH2_ERROR_EAGAIN;
2109 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2110 &err_msg, NULL, 0));
2111 failf(conn->data, "%s", err_msg);
2112 state(conn, SSH_SCP_CHANNEL_FREE);
2113 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2119 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2122 /* not set by Curl_setup_transfer to preserve keepon bits */
2123 conn->sockfd = conn->writesockfd;
2126 state(conn, SSH_SCP_CHANNEL_FREE);
2127 sshc->actualcode = result;
2130 state(conn, SSH_STOP);
2134 case SSH_SCP_DOWNLOAD_INIT:
2137 * We must check the remote file; if it is a directory no values will
2141 curl_off_t bytecount;
2143 /* clear the struct scp recv will fill in */
2144 memset(&sb, 0, sizeof(struct stat));
2146 /* get a fresh new channel from the ssh layer */
2147 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2148 sftp_scp->path, &sb);
2149 if(!sshc->ssh_channel) {
2150 if(libssh2_session_last_errno(sshc->ssh_session) ==
2151 LIBSSH2_ERROR_EAGAIN) {
2152 rc = LIBSSH2_ERROR_EAGAIN;
2159 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2160 &err_msg, NULL, 0));
2161 failf(conn->data, "%s", err_msg);
2162 state(conn, SSH_SCP_CHANNEL_FREE);
2163 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2169 bytecount = (curl_off_t)sb.st_size;
2170 data->req.maxdownload = (curl_off_t)sb.st_size;
2171 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2173 /* not set by Curl_setup_transfer to preserve keepon bits */
2174 conn->writesockfd = conn->sockfd;
2176 /* FIXME: here should be explained why we need it to start the
2178 conn->cselect_bits = CURL_CSELECT_IN;
2181 state(conn, SSH_SCP_CHANNEL_FREE);
2182 sshc->actualcode = result;
2185 state(conn, SSH_STOP);
2190 if(data->set.upload)
2191 state(conn, SSH_SCP_SEND_EOF);
2193 state(conn, SSH_SCP_CHANNEL_FREE);
2196 case SSH_SCP_SEND_EOF:
2197 if(sshc->ssh_channel) {
2198 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2199 if(rc == LIBSSH2_ERROR_EAGAIN) {
2203 infof(data, "Failed to send libssh2 channel EOF\n");
2206 state(conn, SSH_SCP_WAIT_EOF);
2209 case SSH_SCP_WAIT_EOF:
2210 if(sshc->ssh_channel) {
2211 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2212 if(rc == LIBSSH2_ERROR_EAGAIN) {
2216 infof(data, "Failed to get channel EOF: %d\n", rc);
2219 state(conn, SSH_SCP_WAIT_CLOSE);
2222 case SSH_SCP_WAIT_CLOSE:
2223 if(sshc->ssh_channel) {
2224 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2225 if(rc == LIBSSH2_ERROR_EAGAIN) {
2229 infof(data, "Channel failed to close: %d\n", rc);
2232 state(conn, SSH_SCP_CHANNEL_FREE);
2235 case SSH_SCP_CHANNEL_FREE:
2236 if(sshc->ssh_channel) {
2237 rc = libssh2_channel_free(sshc->ssh_channel);
2238 if(rc == LIBSSH2_ERROR_EAGAIN) {
2242 infof(data, "Failed to free libssh2 scp subsystem\n");
2244 sshc->ssh_channel = NULL;
2246 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2248 state(conn, SSH_SESSION_DISCONNECT);
2250 state(conn, SSH_STOP);
2251 result = sshc->actualcode;
2254 case SSH_SESSION_DISCONNECT:
2255 /* during weird times when we've been prematurely aborted, the channel
2256 is still alive when we reach this state and we MUST kill the channel
2258 if(sshc->ssh_channel) {
2259 rc = libssh2_channel_free(sshc->ssh_channel);
2260 if(rc == LIBSSH2_ERROR_EAGAIN) {
2264 infof(data, "Failed to free libssh2 scp subsystem\n");
2266 sshc->ssh_channel = NULL;
2269 if(sshc->ssh_session) {
2270 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2271 if(rc == LIBSSH2_ERROR_EAGAIN) {
2275 infof(data, "Failed to disconnect libssh2 session\n");
2279 Curl_safefree(sshc->homedir);
2280 sshc->homedir = NULL;
2282 state(conn, SSH_SESSION_FREE);
2285 case SSH_SESSION_FREE:
2286 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2288 libssh2_knownhost_free(sshc->kh);
2293 if(sshc->ssh_session) {
2294 rc = libssh2_session_free(sshc->ssh_session);
2295 if(rc == LIBSSH2_ERROR_EAGAIN) {
2299 infof(data, "Failed to free libssh2 session\n");
2301 sshc->ssh_session = NULL;
2303 conn->bits.close = TRUE;
2304 sshc->nextstate = SSH_NO_STATE;
2305 state(conn, SSH_STOP);
2306 result = sshc->actualcode;
2310 /* fallthrough, just stop! */
2312 /* internal error */
2313 sshc->nextstate = SSH_NO_STATE;
2314 state(conn, SSH_STOP);
2318 } while(!rc && (sshc->state != SSH_STOP));
2320 if(rc == LIBSSH2_ERROR_EAGAIN) {
2321 /* we would block, we need to wait for the socket to be ready (in the
2322 right direction too)! */
2329 /* called by the multi interface to figure out what socket(s) to wait for and
2330 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2331 static int ssh_perform_getsock(const struct connectdata *conn,
2332 curl_socket_t *sock, /* points to numsocks
2333 number of sockets */
2336 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2337 int bitmap = GETSOCK_BLANK;
2340 sock[0] = conn->sock[FIRSTSOCKET];
2342 if(conn->waitfor & KEEP_RECV)
2343 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2345 if(conn->waitfor & KEEP_SEND)
2346 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2350 /* if we don't know the direction we can use the generic *_getsock()
2351 function even for the protocol_connect and doing states */
2352 return Curl_single_getsock(conn, sock, numsocks);
2356 /* Generic function called by the multi interface to figure out what socket(s)
2357 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2358 static int ssh_getsock(struct connectdata *conn,
2359 curl_socket_t *sock, /* points to numsocks number
2363 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2367 /* if we don't know any direction we can just play along as we used to and
2368 not provide any sensible info */
2369 return GETSOCK_BLANK;
2371 /* if we know the direction we can use the generic *_getsock() function even
2372 for the protocol_connect and doing states */
2373 return ssh_perform_getsock(conn, sock, numsocks);
2377 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2379 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2380 * function is used to figure out in what direction and stores this info so
2381 * that the multi interface can take advantage of it. Make sure to call this
2382 * function in all cases so that when it _doesn't_ return EAGAIN we can
2383 * restore the default wait bits.
2385 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2387 struct ssh_conn *sshc = &conn->proto.sshc;
2391 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2392 /* translate the libssh2 define bits into our own bit defines */
2393 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2394 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2397 /* It didn't block or libssh2 didn't reveal in which direction, put back
2399 conn->waitfor = sshc->orig_waitfor;
2402 /* no libssh2 directional support so we simply don't know */
2403 #define ssh_block2waitfor(x,y)
2406 /* called repeatedly until done from multi.c */
2407 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2409 struct ssh_conn *sshc = &conn->proto.sshc;
2410 CURLcode result = CURLE_OK;
2411 bool block; /* we store the status and use that to provide a ssh_getsock()
2414 result = ssh_statemach_act(conn, &block);
2415 *done = (bool)(sshc->state == SSH_STOP);
2416 ssh_block2waitfor(conn, block);
2421 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2424 struct ssh_conn *sshc = &conn->proto.sshc;
2425 CURLcode result = CURLE_OK;
2426 struct SessionHandle *data = conn->data;
2428 while((sshc->state != SSH_STOP) && !result) {
2432 result = ssh_statemach_act(conn, &block);
2434 if(Curl_pgrsUpdate(conn))
2435 return CURLE_ABORTED_BY_CALLBACK;
2437 left = Curl_timeleft(conn, NULL, duringconnect);
2439 failf(data, "Operation timed out\n");
2440 return CURLE_OPERATION_TIMEDOUT;
2443 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2444 if((CURLE_OK == result) && block) {
2445 int dir = libssh2_session_block_directions(sshc->ssh_session);
2446 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2447 curl_socket_t fd_read = CURL_SOCKET_BAD;
2448 curl_socket_t fd_write = CURL_SOCKET_BAD;
2449 if (LIBSSH2_SESSION_BLOCK_INBOUND & dir) {
2452 if (LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) {
2455 /* wait for the socket to become ready */
2456 Curl_socket_ready(fd_read, fd_write,
2457 (int)(left>1000?1000:left)); /* ignore result */
2467 * SSH setup and connection
2469 static CURLcode ssh_init(struct connectdata *conn)
2471 struct SessionHandle *data = conn->data;
2472 struct SSHPROTO *ssh;
2473 struct ssh_conn *sshc = &conn->proto.sshc;
2475 sshc->actualcode = CURLE_OK; /* reset error code */
2476 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2479 if(data->state.proto.ssh)
2482 ssh = calloc(1, sizeof(struct SSHPROTO));
2484 return CURLE_OUT_OF_MEMORY;
2486 data->state.proto.ssh = ssh;
2491 static Curl_recv scp_recv, sftp_recv;
2492 static Curl_send scp_send, sftp_send;
2495 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2496 * do protocol-specific actions at connect-time.
2498 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2500 #ifdef CURL_LIBSSH2_DEBUG
2503 struct ssh_conn *ssh;
2505 struct SessionHandle *data = conn->data;
2507 /* We default to persistent connections. We set this already in this connect
2508 function to make the re-use checks properly be able to check this bit. */
2509 conn->bits.close = FALSE;
2511 /* If there already is a protocol-specific struct allocated for this
2512 sessionhandle, deal with it */
2513 Curl_reset_reqproto(conn);
2515 result = ssh_init(conn);
2519 if(conn->protocol & PROT_SCP) {
2520 conn->recv[FIRSTSOCKET] = scp_recv;
2521 conn->send[FIRSTSOCKET] = scp_send;
2523 conn->recv[FIRSTSOCKET] = sftp_recv;
2524 conn->send[FIRSTSOCKET] = sftp_send;
2526 ssh = &conn->proto.sshc;
2528 #ifdef CURL_LIBSSH2_DEBUG
2530 infof(data, "User: %s\n", conn->user);
2533 infof(data, "Password: %s\n", conn->passwd);
2535 sock = conn->sock[FIRSTSOCKET];
2536 #endif /* CURL_LIBSSH2_DEBUG */
2538 ssh->ssh_session = libssh2_session_init_ex(libssh2_malloc, libssh2_free,
2539 libssh2_realloc, conn);
2540 if(ssh->ssh_session == NULL) {
2541 failf(data, "Failure initialising ssh session");
2542 return CURLE_FAILED_INIT;
2545 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2546 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2548 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2550 /* eeek. TODO: free the ssh_session! */
2551 return CURLE_FAILED_INIT;
2554 /* read all known hosts from there */
2555 rc = libssh2_knownhost_readfile(ssh->kh,
2556 data->set.str[STRING_SSH_KNOWNHOSTS],
2557 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2559 infof(data, "Failed to read known hosts from %s\n",
2560 data->set.str[STRING_SSH_KNOWNHOSTS]);
2563 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2565 #ifdef CURL_LIBSSH2_DEBUG
2566 libssh2_trace(ssh->ssh_session, ~0);
2567 infof(data, "SSH socket: %d\n", (int)sock);
2568 #endif /* CURL_LIBSSH2_DEBUG */
2570 state(conn, SSH_S_STARTUP);
2572 if(data->state.used_interface == Curl_if_multi)
2573 result = ssh_multi_statemach(conn, done);
2575 result = ssh_easy_statemach(conn, TRUE);
2584 ***********************************************************************
2588 * This is the actual DO function for SCP. Get a file according to
2589 * the options previously setup.
2593 CURLcode scp_perform(struct connectdata *conn,
2597 CURLcode result = CURLE_OK;
2599 DEBUGF(infof(conn->data, "DO phase starts\n"));
2601 *dophase_done = FALSE; /* not done yet */
2603 /* start the first command in the DO phase */
2604 state(conn, SSH_SCP_TRANS_INIT);
2606 /* run the state-machine */
2607 if(conn->data->state.used_interface == Curl_if_multi) {
2608 result = ssh_multi_statemach(conn, dophase_done);
2611 result = ssh_easy_statemach(conn, FALSE);
2612 *dophase_done = TRUE; /* with the easy interface we are done here */
2614 *connected = conn->bits.tcpconnect;
2617 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2623 /* called from multi.c while DOing */
2624 static CURLcode scp_doing(struct connectdata *conn,
2628 result = ssh_multi_statemach(conn, dophase_done);
2631 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2637 * The DO function is generic for both protocols. There was previously two
2638 * separate ones but this way means less duplicated code.
2641 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2645 struct SessionHandle *data = conn->data;
2647 *done = FALSE; /* default to false */
2650 Since connections can be re-used between SessionHandles, this might be a
2651 connection already existing but on a fresh SessionHandle struct so we must
2652 make sure we have a good 'struct SSHPROTO' to play with. For new
2653 connections, the struct SSHPROTO is allocated and setup in the
2654 ssh_connect() function.
2656 Curl_reset_reqproto(conn);
2657 res = ssh_init(conn);
2661 data->req.size = -1; /* make sure this is unknown at this point */
2663 Curl_pgrsSetUploadCounter(data, 0);
2664 Curl_pgrsSetDownloadCounter(data, 0);
2665 Curl_pgrsSetUploadSize(data, 0);
2666 Curl_pgrsSetDownloadSize(data, 0);
2668 if(conn->protocol & PROT_SCP)
2669 res = scp_perform(conn, &connected, done);
2671 res = sftp_perform(conn, &connected, done);
2676 /* BLOCKING, but the function is using the state machine so the only reason
2677 this is still blocking is that the multi interface code has no support for
2678 disconnecting operations that takes a while */
2679 static CURLcode scp_disconnect(struct connectdata *conn)
2681 CURLcode result = CURLE_OK;
2682 struct ssh_conn *ssh = &conn->proto.sshc;
2684 Curl_safefree(conn->data->state.proto.ssh);
2685 conn->data->state.proto.ssh = NULL;
2687 if(ssh->ssh_session) {
2688 /* only if there's a session still around to use! */
2690 state(conn, SSH_SESSION_DISCONNECT);
2692 result = ssh_easy_statemach(conn, FALSE);
2698 /* generic done function for both SCP and SFTP called from their specific
2700 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2702 CURLcode result = CURLE_OK;
2703 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2705 if(status == CURLE_OK) {
2706 /* run the state-machine
2708 TODO: when the multi interface is used, this _really_ should be using
2709 the ssh_multi_statemach function but we have no general support for
2710 non-blocking DONE operations, not in the multi state machine and with
2711 Curl_done() invokes on several places in the code!
2713 result = ssh_easy_statemach(conn, FALSE);
2718 Curl_safefree(sftp_scp->path);
2719 sftp_scp->path = NULL;
2720 Curl_pgrsDone(conn);
2722 conn->data->req.keepon = 0; /* clear all bits */
2727 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2730 (void)premature; /* not used */
2732 if(status == CURLE_OK)
2733 state(conn, SSH_SCP_DONE);
2735 return ssh_done(conn, status);
2739 /* return number of received (decrypted) bytes */
2740 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2741 const void *mem, size_t len, CURLcode *err)
2744 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2746 /* libssh2_channel_write() returns int! */
2748 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2750 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2752 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2761 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2762 * a regular CURLcode value.
2764 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2765 char *mem, size_t len, CURLcode *err)
2768 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2770 /* libssh2_channel_read() returns int */
2772 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2774 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2775 if (nread == LIBSSH2_ERROR_EAGAIN) {
2784 * =============== SFTP ===============
2788 ***********************************************************************
2792 * This is the actual DO function for SFTP. Get a file/directory according to
2793 * the options previously setup.
2797 CURLcode sftp_perform(struct connectdata *conn,
2801 CURLcode result = CURLE_OK;
2803 DEBUGF(infof(conn->data, "DO phase starts\n"));
2805 *dophase_done = FALSE; /* not done yet */
2807 /* start the first command in the DO phase */
2808 state(conn, SSH_SFTP_QUOTE_INIT);
2810 /* run the state-machine */
2811 if(conn->data->state.used_interface == Curl_if_multi) {
2812 result = ssh_multi_statemach(conn, dophase_done);
2815 result = ssh_easy_statemach(conn, FALSE);
2816 *dophase_done = TRUE; /* with the easy interface we are done here */
2818 *connected = conn->bits.tcpconnect;
2821 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2827 /* called from multi.c while DOing */
2828 static CURLcode sftp_doing(struct connectdata *conn,
2832 result = ssh_multi_statemach(conn, dophase_done);
2835 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2840 /* BLOCKING, but the function is using the state machine so the only reason
2841 this is still blocking is that the multi interface code has no support for
2842 disconnecting operations that takes a while */
2843 static CURLcode sftp_disconnect(struct connectdata *conn)
2845 CURLcode result = CURLE_OK;
2847 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2849 Curl_safefree(conn->data->state.proto.ssh);
2850 conn->data->state.proto.ssh = NULL;
2852 if(conn->proto.sshc.ssh_session) {
2853 /* only if there's a session still around to use! */
2854 state(conn, SSH_SFTP_SHUTDOWN);
2855 result = ssh_easy_statemach(conn, FALSE);
2858 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2864 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2867 struct ssh_conn *sshc = &conn->proto.sshc;
2869 if(status == CURLE_OK) {
2870 /* Before we shut down, see if there are any post-quote commands to
2872 if(!status && !premature && conn->data->set.postquote) {
2873 sshc->nextstate = SSH_SFTP_CLOSE;
2874 state(conn, SSH_SFTP_POSTQUOTE_INIT);
2877 state(conn, SSH_SFTP_CLOSE);
2879 return ssh_done(conn, status);
2882 /* return number of sent bytes */
2883 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
2884 const void *mem, size_t len, CURLcode *err)
2886 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2887 but is changed to ssize_t in 0.15. These days we don't
2888 support libssh2 0.15*/
2891 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2893 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2895 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2904 * Return number of received (decrypted) bytes
2906 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
2907 char *mem, size_t len, CURLcode *err)
2912 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
2914 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2916 if(nread == LIBSSH2_ERROR_EAGAIN) {
2923 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
2926 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
2928 * Permission to use, copy, modify, and distribute this software for any
2929 * purpose with or without fee is hereby granted, provided that the above
2930 * copyright notice and this permission notice appear in all copies.
2932 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2933 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2934 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2935 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2936 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2937 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2938 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2941 get_pathname(const char **cpp, char **path)
2943 const char *cp = *cpp, *end;
2946 static const char WHITESPACE[] = " \t\r\n";
2948 cp += strspn(cp, WHITESPACE);
2952 return CURLE_QUOTE_ERROR;
2955 *path = malloc(strlen(cp) + 1);
2957 return CURLE_OUT_OF_MEMORY;
2959 /* Check for quoted filenames */
2960 if(*cp == '\"' || *cp == '\'') {
2963 /* Search for terminating quote, unescape some chars */
2964 for (i = j = 0; i <= strlen(cp); i++) {
2965 if(cp[i] == quot) { /* Found quote */
2970 if(cp[i] == '\0') { /* End of string */
2971 /*error("Unterminated quote");*/
2974 if(cp[i] == '\\') { /* Escaped characters */
2976 if(cp[i] != '\'' && cp[i] != '\"' &&
2978 /*error("Bad escaped character '\\%c'",
2983 (*path)[j++] = cp[i];
2987 /*error("Empty quotes");*/
2990 *cpp = cp + i + strspn(cp + i, WHITESPACE);
2993 /* Read to end of filename */
2994 end = strpbrk(cp, WHITESPACE);
2996 end = strchr(cp, '\0');
2997 *cpp = end + strspn(end, WHITESPACE);
2999 memcpy(*path, cp, end - cp);
3000 (*path)[end - cp] = '\0';
3005 Curl_safefree(*path);
3007 return CURLE_QUOTE_ERROR;
3011 static const char *sftp_libssh2_strerror(unsigned long err)
3014 case LIBSSH2_FX_NO_SUCH_FILE:
3015 return "No such file or directory";
3017 case LIBSSH2_FX_PERMISSION_DENIED:
3018 return "Permission denied";
3020 case LIBSSH2_FX_FAILURE:
3021 return "Operation failed";
3023 case LIBSSH2_FX_BAD_MESSAGE:
3024 return "Bad message from SFTP server";
3026 case LIBSSH2_FX_NO_CONNECTION:
3027 return "Not connected to SFTP server";
3029 case LIBSSH2_FX_CONNECTION_LOST:
3030 return "Connection to SFTP server lost";
3032 case LIBSSH2_FX_OP_UNSUPPORTED:
3033 return "Operation not supported by SFTP server";
3035 case LIBSSH2_FX_INVALID_HANDLE:
3036 return "Invalid handle";
3038 case LIBSSH2_FX_NO_SUCH_PATH:
3039 return "No such file or directory";
3041 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3042 return "File already exists";
3044 case LIBSSH2_FX_WRITE_PROTECT:
3045 return "File is write protected";
3047 case LIBSSH2_FX_NO_MEDIA:
3050 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3053 case LIBSSH2_FX_QUOTA_EXCEEDED:
3054 return "User quota exceeded";
3056 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3057 return "Unknown principle";
3059 case LIBSSH2_FX_LOCK_CONFlICT:
3060 return "File lock conflict";
3062 case LIBSSH2_FX_DIR_NOT_EMPTY:
3063 return "Directory not empty";
3065 case LIBSSH2_FX_NOT_A_DIRECTORY:
3066 return "Not a directory";
3068 case LIBSSH2_FX_INVALID_FILENAME:
3069 return "Invalid filename";
3071 case LIBSSH2_FX_LINK_LOOP:
3072 return "Link points to itself";
3074 return "Unknown error in libssh2";
3077 #endif /* USE_LIBSSH2 */