1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2011, 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>
86 #include "http.h" /* for HTTP proxy tunnel stuff */
89 #include "speedcheck.h"
96 #include "inet_ntop.h"
97 #include "parsedate.h" /* for the week day and month names */
98 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
99 #include "strtoofft.h"
102 #include "warnless.h"
104 #define _MPRINTF_REPLACE /* use our functions only */
105 #include <curl/mprintf.h>
107 #include "curl_memory.h"
108 /* The last #include file should be: */
109 #include "memdebug.h"
112 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
113 have their definition hidden well */
116 /* Local functions: */
117 static const char *sftp_libssh2_strerror(unsigned long err);
118 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
119 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
120 static LIBSSH2_FREE_FUNC(my_libssh2_free);
122 static CURLcode get_pathname(const char **cpp, char **path);
124 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
125 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
126 static CURLcode ssh_do(struct connectdata *conn, bool *done);
128 static CURLcode ssh_getworkingpath(struct connectdata *conn,
129 char *homedir, /* when SFTP is used */
132 static CURLcode scp_done(struct connectdata *conn,
133 CURLcode, bool premature);
134 static CURLcode scp_doing(struct connectdata *conn,
136 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
138 static CURLcode sftp_done(struct connectdata *conn,
139 CURLcode, bool premature);
140 static CURLcode sftp_doing(struct connectdata *conn,
142 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection);
144 CURLcode sftp_perform(struct connectdata *conn,
148 static int ssh_getsock(struct connectdata *conn,
149 curl_socket_t *sock, /* points to numsocks number
153 static int ssh_perform_getsock(const struct connectdata *conn,
154 curl_socket_t *sock, /* points to numsocks
159 * SCP protocol handler.
162 const struct Curl_handler Curl_handler_scp = {
164 ZERO_NULL, /* setup_connection */
167 ZERO_NULL, /* do_more */
168 ssh_connect, /* connect_it */
169 ssh_multi_statemach, /* connecting */
170 scp_doing, /* doing */
171 ssh_getsock, /* proto_getsock */
172 ssh_getsock, /* doing_getsock */
173 ssh_perform_getsock, /* perform_getsock */
174 scp_disconnect, /* disconnect */
175 PORT_SSH, /* defport */
176 CURLPROTO_SCP, /* protocol */
177 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
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 CURLPROTO_SFTP, /* protocol */
200 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
205 kbd_callback(const char *name, int name_len, const char *instruction,
206 int instruction_len, int num_prompts,
207 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
208 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
211 struct connectdata *conn = (struct connectdata *)*abstract;
213 #ifdef CURL_LIBSSH2_DEBUG
214 fprintf(stderr, "name=%s\n", name);
215 fprintf(stderr, "name_len=%d\n", name_len);
216 fprintf(stderr, "instruction=%s\n", instruction);
217 fprintf(stderr, "instruction_len=%d\n", instruction_len);
218 fprintf(stderr, "num_prompts=%d\n", num_prompts);
223 (void)instruction_len;
224 #endif /* CURL_LIBSSH2_DEBUG */
225 if(num_prompts == 1) {
226 responses[0].text = strdup(conn->passwd);
227 responses[0].length = (unsigned int)strlen(conn->passwd);
233 static CURLcode sftp_libssh2_error_to_CURLE(int err)
239 case LIBSSH2_FX_NO_SUCH_FILE:
240 case LIBSSH2_FX_NO_SUCH_PATH:
241 return CURLE_REMOTE_FILE_NOT_FOUND;
243 case LIBSSH2_FX_PERMISSION_DENIED:
244 case LIBSSH2_FX_WRITE_PROTECT:
245 case LIBSSH2_FX_LOCK_CONFlICT:
246 return CURLE_REMOTE_ACCESS_DENIED;
248 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
249 case LIBSSH2_FX_QUOTA_EXCEEDED:
250 return CURLE_REMOTE_DISK_FULL;
252 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
253 return CURLE_REMOTE_FILE_EXISTS;
255 case LIBSSH2_FX_DIR_NOT_EMPTY:
256 return CURLE_QUOTE_ERROR;
265 static CURLcode libssh2_session_error_to_CURLE(int err)
268 /* Ordered by order of appearance in libssh2.h */
269 case LIBSSH2_ERROR_NONE:
272 case LIBSSH2_ERROR_SOCKET_NONE:
273 return CURLE_COULDNT_CONNECT;
275 case LIBSSH2_ERROR_ALLOC:
276 return CURLE_OUT_OF_MEMORY;
278 case LIBSSH2_ERROR_SOCKET_SEND:
279 return CURLE_SEND_ERROR;
281 case LIBSSH2_ERROR_HOSTKEY_INIT:
282 case LIBSSH2_ERROR_HOSTKEY_SIGN:
283 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
284 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
285 return CURLE_PEER_FAILED_VERIFICATION;
287 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
288 return CURLE_LOGIN_DENIED;
290 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
291 case LIBSSH2_ERROR_TIMEOUT:
292 return CURLE_OPERATION_TIMEDOUT;
294 case LIBSSH2_ERROR_EAGAIN:
298 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
299 error code, and possibly add a few new SSH-related one. We must however
300 not return or even depend on libssh2 errors in the public libcurl API */
305 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
307 (void)abstract; /* arg not used */
308 return malloc(count);
311 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
313 (void)abstract; /* arg not used */
314 return realloc(ptr, count);
317 static LIBSSH2_FREE_FUNC(my_libssh2_free)
319 (void)abstract; /* arg not used */
324 * SSH State machine related code
326 /* This is the ONLY way to change SSH state! */
327 static void state(struct connectdata *conn, sshstate nowstate)
329 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
330 /* for debug purposes */
331 static const char * const names[] = {
336 "SSH_AUTH_PKEY_INIT",
338 "SSH_AUTH_PASS_INIT",
340 "SSH_AUTH_HOST_INIT",
347 "SSH_SFTP_QUOTE_INIT",
348 "SSH_SFTP_POSTQUOTE_INIT",
350 "SSH_SFTP_NEXT_QUOTE",
351 "SSH_SFTP_QUOTE_STAT",
352 "SSH_SFTP_QUOTE_SETSTAT",
353 "SSH_SFTP_QUOTE_SYMLINK",
354 "SSH_SFTP_QUOTE_MKDIR",
355 "SSH_SFTP_QUOTE_RENAME",
356 "SSH_SFTP_QUOTE_RMDIR",
357 "SSH_SFTP_QUOTE_UNLINK",
358 "SSH_SFTP_TRANS_INIT",
359 "SSH_SFTP_UPLOAD_INIT",
360 "SSH_SFTP_CREATE_DIRS_INIT",
361 "SSH_SFTP_CREATE_DIRS",
362 "SSH_SFTP_CREATE_DIRS_MKDIR",
363 "SSH_SFTP_READDIR_INIT",
365 "SSH_SFTP_READDIR_LINK",
366 "SSH_SFTP_READDIR_BOTTOM",
367 "SSH_SFTP_READDIR_DONE",
368 "SSH_SFTP_DOWNLOAD_INIT",
369 "SSH_SFTP_DOWNLOAD_STAT",
372 "SSH_SCP_TRANS_INIT",
373 "SSH_SCP_UPLOAD_INIT",
374 "SSH_SCP_DOWNLOAD_INIT",
378 "SSH_SCP_WAIT_CLOSE",
379 "SSH_SCP_CHANNEL_FREE",
380 "SSH_SESSION_DISCONNECT",
385 struct ssh_conn *sshc = &conn->proto.sshc;
387 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
388 if(sshc->state != nowstate) {
389 infof(conn->data, "SFTP %p state change from %s to %s\n",
390 sshc, names[sshc->state], names[nowstate]);
394 sshc->state = nowstate;
397 /* figure out the path to work with in this particular request */
398 static CURLcode ssh_getworkingpath(struct connectdata *conn,
399 char *homedir, /* when SFTP is used */
400 char **path) /* returns the allocated
401 real path to work with */
403 struct SessionHandle *data = conn->data;
404 char *real_path = NULL;
406 int working_path_len;
408 working_path = curl_easy_unescape(data, data->state.path, 0,
411 return CURLE_OUT_OF_MEMORY;
413 /* Check for /~/ , indicating relative to the user's home directory */
414 if(conn->handler->protocol & CURLPROTO_SCP) {
415 real_path = malloc(working_path_len+1);
416 if(real_path == NULL) {
418 return CURLE_OUT_OF_MEMORY;
420 if((working_path_len > 1) && (working_path[1] == '~'))
421 /* It is referenced to the home directory, so strip the leading '/' */
422 memcpy(real_path, working_path+1, 1 + working_path_len-1);
424 memcpy(real_path, working_path, 1 + working_path_len);
426 else if(conn->handler->protocol & CURLPROTO_SFTP) {
427 if((working_path_len > 1) && (working_path[1] == '~')) {
428 size_t homelen = strlen(homedir);
429 real_path = malloc(homelen + working_path_len + 1);
430 if(real_path == NULL) {
432 return CURLE_OUT_OF_MEMORY;
434 /* It is referenced to the home directory, so strip the
436 memcpy(real_path, homedir, homelen);
437 real_path[homelen] = '/';
438 real_path[homelen+1] = '\0';
439 if(working_path_len > 3) {
440 memcpy(real_path+homelen+1, working_path + 3,
441 1 + working_path_len -3);
445 real_path = malloc(working_path_len+1);
446 if(real_path == NULL) {
448 return CURLE_OUT_OF_MEMORY;
450 memcpy(real_path, working_path, 1+working_path_len);
456 /* store the pointer for the caller to receive */
462 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
463 static int sshkeycallback(CURL *easy,
464 const struct curl_khkey *knownkey, /* known */
465 const struct curl_khkey *foundkey, /* found */
466 enum curl_khmatch match,
474 /* we only allow perfect matches, and we reject everything else */
475 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
480 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
483 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
484 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
486 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
490 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
491 * architectures so we check of the necessary function is present.
493 #ifndef HAVE_LIBSSH2_SCP_SEND64
494 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
496 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
497 (libssh2_uint64_t)d, 0, 0)
501 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
503 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
504 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
508 * ssh_statemach_act() runs the SSH state machine as far as it can without
509 * blocking and without reaching the end. The data the pointer 'block' points
510 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
511 * meaning it wants to be called again when the socket is ready
514 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
516 CURLcode result = CURLE_OK;
517 struct SessionHandle *data = conn->data;
518 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
519 struct ssh_conn *sshc = &conn->proto.sshc;
520 curl_socket_t sock = conn->sock[FIRSTSOCKET];
521 #ifdef CURL_LIBSSH2_DEBUG
522 const char *fingerprint;
523 #endif /* CURL_LIBSSH2_DEBUG */
524 const char *host_public_key_md5;
525 int rc = LIBSSH2_ERROR_NONE, i;
527 int seekerr = CURL_SEEKFUNC_OK;
528 *block = 0; /* we're not blocking by default */
532 switch(sshc->state) {
534 sshc->secondCreateDirs = 0;
535 sshc->nextstate = SSH_NO_STATE;
536 sshc->actualcode = CURLE_OK;
538 rc = libssh2_session_startup(sshc->ssh_session, sock);
539 if(rc == LIBSSH2_ERROR_EAGAIN) {
543 failf(data, "Failure establishing ssh session");
544 state(conn, SSH_SESSION_FREE);
545 sshc->actualcode = CURLE_FAILED_INIT;
549 /* Set libssh2 to non-blocking, since everything internally is
551 libssh2_session_set_blocking(sshc->ssh_session, 0);
553 state(conn, SSH_HOSTKEY);
558 #ifdef CURL_LIBSSH2_DEBUG
560 * Before we authenticate we should check the hostkey's fingerprint
561 * against our known hosts. How that is handled (reading from file,
562 * whatever) is up to us. As for know not much is implemented, besides
563 * showing how to get the fingerprint.
565 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
566 LIBSSH2_HOSTKEY_HASH_MD5);
568 /* The fingerprint points to static storage (!), don't free() it. */
569 infof(data, "Fingerprint: ");
570 for (rc = 0; rc < 16; rc++) {
571 infof(data, "%02X ", (unsigned char) fingerprint[rc]);
574 #endif /* CURL_LIBSSH2_DEBUG */
576 /* Before we authenticate we check the hostkey's MD5 fingerprint
577 * against a known fingerprint, if available. This implementation pulls
578 * it from the curl option.
580 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
581 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
583 host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
584 LIBSSH2_HOSTKEY_HASH_MD5);
585 for (i = 0; i < 16; i++)
586 snprintf(&buf[i*2], 3, "%02x",
587 (unsigned char) host_public_key_md5[i]);
588 if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
590 "Denied establishing ssh session: mismatch md5 fingerprint. "
591 "Remote %s is not equal to %s",
592 buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
593 state(conn, SSH_SESSION_FREE);
594 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
599 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
600 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
601 /* we're asked to verify the host against a file */
604 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
611 * A subject to figure out is what host name we need to pass in here.
612 * What host name does OpenSSH store in its file if an IDN name is
615 struct libssh2_knownhost *host;
616 enum curl_khmatch keymatch;
617 curl_sshkeycallback func =
618 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
619 struct curl_khkey knownkey;
620 struct curl_khkey *knownkeyp = NULL;
621 struct curl_khkey foundkey;
623 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
624 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
626 keycheck = libssh2_knownhost_check(sshc->kh,
629 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
630 LIBSSH2_KNOWNHOST_KEYENC_RAW|
634 infof(data, "SSH host check: %d, key: %s\n", keycheck,
635 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
638 /* setup 'knownkey' */
639 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
640 knownkey.key = host->key;
642 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
643 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
644 knownkeyp = &knownkey;
647 /* setup 'foundkey' */
648 foundkey.key = remotekey;
649 foundkey.len = keylen;
650 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
651 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
654 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
655 * curl_khmatch enum are ever modified, we need to introduce a
656 * translation table here!
658 keymatch = (enum curl_khmatch)keycheck;
660 /* Ask the callback how to behave */
661 rc = func(data, knownkeyp, /* from the knownhosts file */
662 &foundkey, /* from the remote host */
663 keymatch, data->set.ssh_keyfunc_userp);
666 /* no remotekey means failure! */
667 rc = CURLKHSTAT_REJECT;
670 default: /* unknown return codes will equal reject */
671 case CURLKHSTAT_REJECT:
672 state(conn, SSH_SESSION_FREE);
673 case CURLKHSTAT_DEFER:
674 /* DEFER means bail out but keep the SSH_HOSTKEY state */
675 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
677 case CURLKHSTAT_FINE:
678 case CURLKHSTAT_FINE_ADD_TO_FILE:
680 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
681 /* the found host+key didn't match but has been told to be fine
682 anyway so we add it in memory */
683 int addrc = libssh2_knownhost_add(sshc->kh,
684 conn->host.name, NULL,
686 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
687 LIBSSH2_KNOWNHOST_KEYENC_RAW|
690 infof(data, "Warning adding the known host %s failed!\n",
692 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
693 /* now we write the entire in-memory list of known hosts to the
696 libssh2_knownhost_writefile(sshc->kh,
697 data->set.str[STRING_SSH_KNOWNHOSTS],
698 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
700 infof(data, "Warning, writing %s failed!\n",
701 data->set.str[STRING_SSH_KNOWNHOSTS]);
708 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
710 state(conn, SSH_AUTHLIST);
715 * Figure out authentication methods
716 * NB: As soon as we have provided a username to an openssh server we
717 * must never change it later. Thus, always specify the correct username
718 * here, even though the libssh2 docs kind of indicate that it should be
719 * possible to get a 'generic' list (not user-specific) of authentication
720 * methods, presumably with a blank username. That won't work in my
722 * So always specify it here.
724 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
726 (unsigned int)strlen(conn->user));
728 if(!sshc->authlist) {
729 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
730 LIBSSH2_ERROR_EAGAIN) {
731 rc = LIBSSH2_ERROR_EAGAIN;
735 state(conn, SSH_SESSION_FREE);
736 sshc->actualcode = libssh2_session_error_to_CURLE(err);
740 infof(data, "SSH authentication methods available: %s\n",
743 state(conn, SSH_AUTH_PKEY_INIT);
746 case SSH_AUTH_PKEY_INIT:
748 * Check the supported auth types in the order I feel is most secure
749 * with the requested type of authentication
751 sshc->authed = FALSE;
753 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
754 (strstr(sshc->authlist, "publickey") != NULL)) {
757 sshc->rsa_pub = sshc->rsa = NULL;
759 /* To ponder about: should really the lib be messing about with the
760 HOME environment variable etc? */
761 home = curl_getenv("HOME");
763 if(data->set.str[STRING_SSH_PUBLIC_KEY])
764 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
766 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
768 /* as a final resort, try current dir! */
769 sshc->rsa_pub = strdup("id_dsa.pub");
771 if(sshc->rsa_pub == NULL) {
774 state(conn, SSH_SESSION_FREE);
775 sshc->actualcode = CURLE_OUT_OF_MEMORY;
779 if(data->set.str[STRING_SSH_PRIVATE_KEY])
780 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
782 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
784 /* as a final resort, try current dir! */
785 sshc->rsa = strdup("id_dsa");
787 if(sshc->rsa == NULL) {
790 Curl_safefree(sshc->rsa_pub);
791 sshc->rsa_pub = NULL;
792 state(conn, SSH_SESSION_FREE);
793 sshc->actualcode = CURLE_OUT_OF_MEMORY;
797 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
798 if(!sshc->passphrase)
799 sshc->passphrase = "";
804 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
805 infof(data, "Using ssh private key file %s\n", sshc->rsa);
807 state(conn, SSH_AUTH_PKEY);
810 state(conn, SSH_AUTH_PASS_INIT);
815 /* The function below checks if the files exists, no need to stat() here.
817 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
822 sshc->rsa, sshc->passphrase);
823 if(rc == LIBSSH2_ERROR_EAGAIN) {
827 Curl_safefree(sshc->rsa_pub);
828 sshc->rsa_pub = NULL;
829 Curl_safefree(sshc->rsa);
834 infof(data, "Initialized SSH public key authentication\n");
835 state(conn, SSH_AUTH_DONE);
839 (void)libssh2_session_last_error(sshc->ssh_session,
841 infof(data, "SSH public key authentication failed: %s\n", err_msg);
842 state(conn, SSH_AUTH_PASS_INIT);
846 case SSH_AUTH_PASS_INIT:
847 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
848 (strstr(sshc->authlist, "password") != NULL)) {
849 state(conn, SSH_AUTH_PASS);
852 state(conn, SSH_AUTH_HOST_INIT);
857 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
858 (unsigned int)strlen(conn->user),
860 (unsigned int)strlen(conn->passwd),
862 if(rc == LIBSSH2_ERROR_EAGAIN) {
867 infof(data, "Initialized password authentication\n");
868 state(conn, SSH_AUTH_DONE);
871 state(conn, SSH_AUTH_HOST_INIT);
875 case SSH_AUTH_HOST_INIT:
876 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
877 (strstr(sshc->authlist, "hostbased") != NULL)) {
878 state(conn, SSH_AUTH_HOST);
881 state(conn, SSH_AUTH_KEY_INIT);
886 state(conn, SSH_AUTH_KEY_INIT);
889 case SSH_AUTH_KEY_INIT:
890 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
891 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
892 state(conn, SSH_AUTH_KEY);
895 state(conn, SSH_AUTH_DONE);
900 /* Authentication failed. Continue with keyboard-interactive now. */
901 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
906 if(rc == LIBSSH2_ERROR_EAGAIN) {
911 infof(data, "Initialized keyboard interactive authentication\n");
913 state(conn, SSH_AUTH_DONE);
918 failf(data, "Authentication failure");
919 state(conn, SSH_SESSION_FREE);
920 sshc->actualcode = CURLE_LOGIN_DENIED;
925 * At this point we have an authenticated ssh session.
927 infof(data, "Authentication complete\n");
929 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
932 conn->writesockfd = CURL_SOCKET_BAD;
934 if(conn->handler->protocol == CURLPROTO_SFTP) {
935 state(conn, SSH_SFTP_INIT);
938 infof(data, "SSH CONNECT phase done\n");
939 state(conn, SSH_STOP);
944 * Start the libssh2 sftp session
946 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
947 if(!sshc->sftp_session) {
948 if(libssh2_session_last_errno(sshc->ssh_session) ==
949 LIBSSH2_ERROR_EAGAIN) {
950 rc = LIBSSH2_ERROR_EAGAIN;
956 (void)libssh2_session_last_error(sshc->ssh_session,
958 failf(data, "Failure initializing sftp session: %s", err_msg);
959 state(conn, SSH_SESSION_FREE);
960 sshc->actualcode = CURLE_FAILED_INIT;
964 state(conn, SSH_SFTP_REALPATH);
967 case SSH_SFTP_REALPATH:
969 char tempHome[PATH_MAX];
972 * Get the "home" directory
974 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
975 tempHome, PATH_MAX-1);
976 if(rc == LIBSSH2_ERROR_EAGAIN) {
980 /* It seems that this string is not always NULL terminated */
982 sshc->homedir = strdup(tempHome);
984 state(conn, SSH_SFTP_CLOSE);
985 sshc->actualcode = CURLE_OUT_OF_MEMORY;
988 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
991 /* Return the error type */
992 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
993 result = sftp_libssh2_error_to_CURLE(err);
994 sshc->actualcode = result?result:CURLE_SSH;
995 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
997 state(conn, SSH_STOP);
1001 /* This is the last step in the SFTP connect phase. Do note that while
1002 we get the homedir here, we get the "workingpath" in the DO action
1003 since the homedir will remain the same between request but the
1004 working path will not. */
1005 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1006 state(conn, SSH_STOP);
1009 case SSH_SFTP_QUOTE_INIT:
1011 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1013 sshc->actualcode = result;
1014 state(conn, SSH_STOP);
1018 if(data->set.quote) {
1019 infof(data, "Sending quote commands\n");
1020 sshc->quote_item = data->set.quote;
1021 state(conn, SSH_SFTP_QUOTE);
1024 state(conn, SSH_SFTP_TRANS_INIT);
1028 case SSH_SFTP_POSTQUOTE_INIT:
1029 if(data->set.postquote) {
1030 infof(data, "Sending quote commands\n");
1031 sshc->quote_item = data->set.postquote;
1032 state(conn, SSH_SFTP_QUOTE);
1035 state(conn, SSH_STOP);
1039 case SSH_SFTP_QUOTE:
1040 /* Send any quote commands */
1045 * Support some of the "FTP" commands
1047 if(curl_strequal("pwd", sshc->quote_item->data)) {
1048 /* output debug output if that is requested */
1049 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1052 result = CURLE_OUT_OF_MEMORY;
1053 state(conn, SSH_SFTP_CLOSE);
1054 sshc->nextstate = SSH_NO_STATE;
1057 if(data->set.verbose) {
1058 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1059 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1061 /* this sends an FTP-like "header" to the header callback so that the
1062 current directory can be read very similar to how it is read when
1063 using ordinary FTP. */
1064 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1066 state(conn, SSH_SFTP_NEXT_QUOTE);
1069 else if(sshc->quote_item->data) {
1071 * the arguments following the command must be separated from the
1072 * command with a space so we can check for it unconditionally
1074 cp = strchr(sshc->quote_item->data, ' ');
1076 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1077 state(conn, SSH_SFTP_CLOSE);
1078 sshc->nextstate = SSH_NO_STATE;
1079 sshc->actualcode = CURLE_QUOTE_ERROR;
1084 * also, every command takes at least one argument so we get that
1085 * first argument right now
1087 result = get_pathname(&cp, &sshc->quote_path1);
1089 if(result == CURLE_OUT_OF_MEMORY)
1090 failf(data, "Out of memory");
1092 failf(data, "Syntax error: Bad first parameter");
1093 state(conn, SSH_SFTP_CLOSE);
1094 sshc->nextstate = SSH_NO_STATE;
1095 sshc->actualcode = result;
1100 * SFTP is a binary protocol, so we don't send text commands to
1101 * the server. Instead, we scan for commands for commands used by
1102 * OpenSSH's sftp program and call the appropriate libssh2
1105 if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
1106 curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
1107 curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
1108 /* attribute change */
1110 /* sshc->quote_path1 contains the mode to set */
1111 /* get the destination */
1112 result = get_pathname(&cp, &sshc->quote_path2);
1114 if(result == CURLE_OUT_OF_MEMORY)
1115 failf(data, "Out of memory");
1117 failf(data, "Syntax error in chgrp/chmod/chown: "
1118 "Bad second parameter");
1119 Curl_safefree(sshc->quote_path1);
1120 sshc->quote_path1 = NULL;
1121 state(conn, SSH_SFTP_CLOSE);
1122 sshc->nextstate = SSH_NO_STATE;
1123 sshc->actualcode = result;
1126 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1127 state(conn, SSH_SFTP_QUOTE_STAT);
1130 else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
1131 curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
1132 /* symbolic linking */
1133 /* sshc->quote_path1 is the source */
1134 /* get the destination */
1135 result = get_pathname(&cp, &sshc->quote_path2);
1137 if(result == CURLE_OUT_OF_MEMORY)
1138 failf(data, "Out of memory");
1141 "Syntax error in ln/symlink: Bad second parameter");
1142 Curl_safefree(sshc->quote_path1);
1143 sshc->quote_path1 = NULL;
1144 state(conn, SSH_SFTP_CLOSE);
1145 sshc->nextstate = SSH_NO_STATE;
1146 sshc->actualcode = result;
1149 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1152 else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
1154 state(conn, SSH_SFTP_QUOTE_MKDIR);
1157 else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
1159 /* first param is the source path */
1160 /* second param is the dest. path */
1161 result = get_pathname(&cp, &sshc->quote_path2);
1163 if(result == CURLE_OUT_OF_MEMORY)
1164 failf(data, "Out of memory");
1166 failf(data, "Syntax error in rename: Bad second parameter");
1167 Curl_safefree(sshc->quote_path1);
1168 sshc->quote_path1 = NULL;
1169 state(conn, SSH_SFTP_CLOSE);
1170 sshc->nextstate = SSH_NO_STATE;
1171 sshc->actualcode = result;
1174 state(conn, SSH_SFTP_QUOTE_RENAME);
1177 else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
1179 state(conn, SSH_SFTP_QUOTE_RMDIR);
1182 else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
1183 state(conn, SSH_SFTP_QUOTE_UNLINK);
1187 failf(data, "Unknown SFTP command");
1188 Curl_safefree(sshc->quote_path1);
1189 sshc->quote_path1 = NULL;
1190 Curl_safefree(sshc->quote_path2);
1191 sshc->quote_path2 = NULL;
1192 state(conn, SSH_SFTP_CLOSE);
1193 sshc->nextstate = SSH_NO_STATE;
1194 sshc->actualcode = CURLE_QUOTE_ERROR;
1198 if(!sshc->quote_item) {
1199 state(conn, SSH_SFTP_TRANS_INIT);
1203 case SSH_SFTP_NEXT_QUOTE:
1204 if(sshc->quote_path1) {
1205 Curl_safefree(sshc->quote_path1);
1206 sshc->quote_path1 = NULL;
1208 if(sshc->quote_path2) {
1209 Curl_safefree(sshc->quote_path2);
1210 sshc->quote_path2 = NULL;
1213 sshc->quote_item = sshc->quote_item->next;
1215 if(sshc->quote_item) {
1216 state(conn, SSH_SFTP_QUOTE);
1219 if(sshc->nextstate != SSH_NO_STATE) {
1220 state(conn, sshc->nextstate);
1221 sshc->nextstate = SSH_NO_STATE;
1224 state(conn, SSH_SFTP_TRANS_INIT);
1229 case SSH_SFTP_QUOTE_STAT:
1230 if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1231 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1232 * set them both at once, we need to obtain the current ownership
1233 * first. This takes an extra protocol round trip.
1235 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1236 (unsigned int)strlen(sshc->quote_path2),
1238 &sshc->quote_attrs);
1239 if(rc == LIBSSH2_ERROR_EAGAIN) {
1242 else if(rc != 0) { /* get those attributes */
1243 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1244 Curl_safefree(sshc->quote_path1);
1245 sshc->quote_path1 = NULL;
1246 Curl_safefree(sshc->quote_path2);
1247 sshc->quote_path2 = NULL;
1248 failf(data, "Attempt to get SFTP stats failed: %s",
1249 sftp_libssh2_strerror(err));
1250 state(conn, SSH_SFTP_CLOSE);
1251 sshc->nextstate = SSH_NO_STATE;
1252 sshc->actualcode = CURLE_QUOTE_ERROR;
1257 /* Now set the new attributes... */
1258 if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
1259 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1260 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1261 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1262 Curl_safefree(sshc->quote_path1);
1263 sshc->quote_path1 = NULL;
1264 Curl_safefree(sshc->quote_path2);
1265 sshc->quote_path2 = NULL;
1266 failf(data, "Syntax error: chgrp gid not a number");
1267 state(conn, SSH_SFTP_CLOSE);
1268 sshc->nextstate = SSH_NO_STATE;
1269 sshc->actualcode = CURLE_QUOTE_ERROR;
1273 else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1274 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1275 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1276 /* permissions are octal */
1277 if(sshc->quote_attrs.permissions == 0 &&
1278 !ISDIGIT(sshc->quote_path1[0])) {
1279 Curl_safefree(sshc->quote_path1);
1280 sshc->quote_path1 = NULL;
1281 Curl_safefree(sshc->quote_path2);
1282 sshc->quote_path2 = NULL;
1283 failf(data, "Syntax error: chmod permissions not a number");
1284 state(conn, SSH_SFTP_CLOSE);
1285 sshc->nextstate = SSH_NO_STATE;
1286 sshc->actualcode = CURLE_QUOTE_ERROR;
1290 else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
1291 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1292 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1293 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1294 Curl_safefree(sshc->quote_path1);
1295 sshc->quote_path1 = NULL;
1296 Curl_safefree(sshc->quote_path2);
1297 sshc->quote_path2 = NULL;
1298 failf(data, "Syntax error: chown uid not a number");
1299 state(conn, SSH_SFTP_CLOSE);
1300 sshc->nextstate = SSH_NO_STATE;
1301 sshc->actualcode = CURLE_QUOTE_ERROR;
1306 /* Now send the completed structure... */
1307 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1310 case SSH_SFTP_QUOTE_SETSTAT:
1311 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1312 (unsigned int)strlen(sshc->quote_path2),
1313 LIBSSH2_SFTP_SETSTAT,
1314 &sshc->quote_attrs);
1315 if(rc == LIBSSH2_ERROR_EAGAIN) {
1319 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1320 Curl_safefree(sshc->quote_path1);
1321 sshc->quote_path1 = NULL;
1322 Curl_safefree(sshc->quote_path2);
1323 sshc->quote_path2 = NULL;
1324 failf(data, "Attempt to set SFTP stats failed: %s",
1325 sftp_libssh2_strerror(err));
1326 state(conn, SSH_SFTP_CLOSE);
1327 sshc->nextstate = SSH_NO_STATE;
1328 sshc->actualcode = CURLE_QUOTE_ERROR;
1331 state(conn, SSH_SFTP_NEXT_QUOTE);
1334 case SSH_SFTP_QUOTE_SYMLINK:
1335 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1336 (unsigned int)strlen(sshc->quote_path1),
1338 (unsigned int)strlen(sshc->quote_path2),
1339 LIBSSH2_SFTP_SYMLINK);
1340 if(rc == LIBSSH2_ERROR_EAGAIN) {
1344 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1345 Curl_safefree(sshc->quote_path1);
1346 sshc->quote_path1 = NULL;
1347 Curl_safefree(sshc->quote_path2);
1348 sshc->quote_path2 = NULL;
1349 failf(data, "symlink command failed: %s",
1350 sftp_libssh2_strerror(err));
1351 state(conn, SSH_SFTP_CLOSE);
1352 sshc->nextstate = SSH_NO_STATE;
1353 sshc->actualcode = CURLE_QUOTE_ERROR;
1356 state(conn, SSH_SFTP_NEXT_QUOTE);
1359 case SSH_SFTP_QUOTE_MKDIR:
1360 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1361 (unsigned int)strlen(sshc->quote_path1),
1363 if(rc == LIBSSH2_ERROR_EAGAIN) {
1367 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1368 Curl_safefree(sshc->quote_path1);
1369 sshc->quote_path1 = NULL;
1370 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1371 state(conn, SSH_SFTP_CLOSE);
1372 sshc->nextstate = SSH_NO_STATE;
1373 sshc->actualcode = CURLE_QUOTE_ERROR;
1376 state(conn, SSH_SFTP_NEXT_QUOTE);
1379 case SSH_SFTP_QUOTE_RENAME:
1380 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1381 (unsigned int)strlen(sshc->quote_path1),
1383 (unsigned int)strlen(sshc->quote_path2),
1384 LIBSSH2_SFTP_RENAME_OVERWRITE |
1385 LIBSSH2_SFTP_RENAME_ATOMIC |
1386 LIBSSH2_SFTP_RENAME_NATIVE);
1388 if(rc == LIBSSH2_ERROR_EAGAIN) {
1392 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1393 Curl_safefree(sshc->quote_path1);
1394 sshc->quote_path1 = NULL;
1395 Curl_safefree(sshc->quote_path2);
1396 sshc->quote_path2 = NULL;
1397 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1398 state(conn, SSH_SFTP_CLOSE);
1399 sshc->nextstate = SSH_NO_STATE;
1400 sshc->actualcode = CURLE_QUOTE_ERROR;
1403 state(conn, SSH_SFTP_NEXT_QUOTE);
1406 case SSH_SFTP_QUOTE_RMDIR:
1407 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1408 (unsigned int)strlen(sshc->quote_path1));
1409 if(rc == LIBSSH2_ERROR_EAGAIN) {
1413 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1414 Curl_safefree(sshc->quote_path1);
1415 sshc->quote_path1 = NULL;
1416 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1417 state(conn, SSH_SFTP_CLOSE);
1418 sshc->nextstate = SSH_NO_STATE;
1419 sshc->actualcode = CURLE_QUOTE_ERROR;
1422 state(conn, SSH_SFTP_NEXT_QUOTE);
1425 case SSH_SFTP_QUOTE_UNLINK:
1426 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1427 (unsigned int)strlen(sshc->quote_path1));
1428 if(rc == LIBSSH2_ERROR_EAGAIN) {
1432 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1433 Curl_safefree(sshc->quote_path1);
1434 sshc->quote_path1 = NULL;
1435 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1436 state(conn, SSH_SFTP_CLOSE);
1437 sshc->nextstate = SSH_NO_STATE;
1438 sshc->actualcode = CURLE_QUOTE_ERROR;
1441 state(conn, SSH_SFTP_NEXT_QUOTE);
1444 case SSH_SFTP_TRANS_INIT:
1445 if(data->set.upload)
1446 state(conn, SSH_SFTP_UPLOAD_INIT);
1448 if(data->set.opt_no_body)
1449 state(conn, SSH_STOP);
1450 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1451 state(conn, SSH_SFTP_READDIR_INIT);
1453 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1457 case SSH_SFTP_UPLOAD_INIT:
1459 unsigned long flags;
1461 * NOTE!!! libssh2 requires that the destination path is a full path
1462 * that includes the destination file and name OR ends in a "/"
1463 * If this is not done the destination file will be named the
1464 * same name as the last directory in the path.
1467 if(data->state.resume_from != 0) {
1468 LIBSSH2_SFTP_ATTRIBUTES attrs;
1469 if(data->state.resume_from < 0) {
1470 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1471 (unsigned int)strlen(sftp_scp->path),
1472 LIBSSH2_SFTP_STAT, &attrs);
1473 if(rc == LIBSSH2_ERROR_EAGAIN) {
1477 data->state.resume_from = 0;
1480 curl_off_t size = attrs.filesize;
1482 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1483 return CURLE_BAD_DOWNLOAD_RESUME;
1485 data->state.resume_from = attrs.filesize;
1490 if(data->set.ftp_append)
1491 /* Try to open for append, but create if nonexisting */
1492 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1493 else if (data->state.resume_from > 0)
1494 /* If we have restart position then open for append */
1495 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1497 /* Clear file before writing (normal behaviour) */
1498 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1501 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1502 (unsigned int)strlen(sftp_scp->path),
1503 flags, data->set.new_file_perms,
1504 LIBSSH2_SFTP_OPENFILE);
1506 if(!sshc->sftp_handle) {
1507 rc = libssh2_session_last_errno(sshc->ssh_session);
1509 if(LIBSSH2_ERROR_EAGAIN == rc)
1512 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1513 /* only when there was an SFTP protocol error can we extract
1515 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1517 err = -1; /* not an sftp error at all */
1519 if(sshc->secondCreateDirs) {
1520 state(conn, SSH_SFTP_CLOSE);
1521 sshc->actualcode = err>= LIBSSH2_FX_OK?
1522 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1523 failf(data, "Creating the dir/file failed: %s",
1524 sftp_libssh2_strerror(err));
1527 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1528 (err == LIBSSH2_FX_FAILURE) ||
1529 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1530 (data->set.ftp_create_missing_dirs &&
1531 (strlen(sftp_scp->path) > 1))) {
1532 /* try to create the path remotely */
1533 sshc->secondCreateDirs = 1;
1534 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1537 state(conn, SSH_SFTP_CLOSE);
1538 sshc->actualcode = err>= LIBSSH2_FX_OK?
1539 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1540 if(!sshc->actualcode) {
1541 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1542 zero even though libssh2_sftp_open() failed previously! We need
1543 to work around that! */
1544 sshc->actualcode = CURLE_SSH;
1547 failf(data, "Upload failed: %s (%d/%d)",
1548 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1554 /* If we have restart point then we need to seek to the correct
1556 if(data->state.resume_from > 0) {
1557 /* Let's read off the proper amount of bytes from the input. */
1558 if(conn->seek_func) {
1559 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1563 if(seekerr != CURL_SEEKFUNC_OK){
1565 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1566 failf(data, "Could not seek stream");
1567 return CURLE_FTP_COULDNT_USE_REST;
1569 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1571 curl_off_t passed=0;
1573 size_t readthisamountnow =
1574 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1575 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1577 size_t actuallyread =
1578 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1581 passed += actuallyread;
1582 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1583 /* this checks for greater-than only to make sure that the
1584 CURL_READFUNC_ABORT return code still aborts */
1585 failf(data, "Failed to read data");
1586 return CURLE_FTP_COULDNT_USE_REST;
1588 } while(passed < data->state.resume_from);
1592 /* now, decrease the size of the read */
1593 if(data->set.infilesize > 0) {
1594 data->set.infilesize -= data->state.resume_from;
1595 data->req.size = data->set.infilesize;
1596 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1599 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1601 if(data->set.infilesize > 0) {
1602 data->req.size = data->set.infilesize;
1603 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1606 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1608 /* not set by Curl_setup_transfer to preserve keepon bits */
1609 conn->sockfd = conn->writesockfd;
1612 state(conn, SSH_SFTP_CLOSE);
1613 sshc->actualcode = result;
1616 /* store this original bitmask setup to use later on if we can't
1617 figure out a "real" bitmask */
1618 sshc->orig_waitfor = data->req.keepon;
1620 /* we want to use the _sending_ function even when the socket turns
1621 out readable as the underlying libssh2 sftp send function will deal
1622 with both accordingly */
1623 conn->cselect_bits = CURL_CSELECT_OUT;
1625 /* since we don't really wait for anything at this point, we want the
1626 state machine to move on as soon as possible so we set a very short
1628 Curl_expire(data, 1);
1630 state(conn, SSH_STOP);
1635 case SSH_SFTP_CREATE_DIRS_INIT:
1636 if(strlen(sftp_scp->path) > 1) {
1637 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1638 state(conn, SSH_SFTP_CREATE_DIRS);
1641 state(conn, SSH_SFTP_UPLOAD_INIT);
1645 case SSH_SFTP_CREATE_DIRS:
1646 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1647 *sshc->slash_pos = 0;
1649 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1650 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1654 state(conn, SSH_SFTP_UPLOAD_INIT);
1658 case SSH_SFTP_CREATE_DIRS_MKDIR:
1659 /* 'mode' - parameter is preliminary - default to 0644 */
1660 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1661 (unsigned int)strlen(sftp_scp->path),
1662 data->set.new_directory_perms);
1663 if(rc == LIBSSH2_ERROR_EAGAIN) {
1666 *sshc->slash_pos = '/';
1669 unsigned int sftp_err = 0;
1671 * Abort if failure wasn't that the dir already exists or the
1672 * permission was denied (creation might succeed further down the
1673 * path) - retry on unspecific FAILURE also
1675 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1676 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1677 (sftp_err != LIBSSH2_FX_FAILURE) &&
1678 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1679 result = sftp_libssh2_error_to_CURLE(sftp_err);
1680 state(conn, SSH_SFTP_CLOSE);
1681 sshc->actualcode = result?result:CURLE_SSH;
1685 state(conn, SSH_SFTP_CREATE_DIRS);
1688 case SSH_SFTP_READDIR_INIT:
1690 * This is a directory that we are trying to get, so produce a directory
1693 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1696 strlen(sftp_scp->path),
1697 0, 0, LIBSSH2_SFTP_OPENDIR);
1698 if(!sshc->sftp_handle) {
1699 if(libssh2_session_last_errno(sshc->ssh_session) ==
1700 LIBSSH2_ERROR_EAGAIN) {
1701 rc = LIBSSH2_ERROR_EAGAIN;
1705 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1706 failf(data, "Could not open directory for reading: %s",
1707 sftp_libssh2_strerror(err));
1708 state(conn, SSH_SFTP_CLOSE);
1709 result = sftp_libssh2_error_to_CURLE(err);
1710 sshc->actualcode = result?result:CURLE_SSH;
1714 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1715 state(conn, SSH_SFTP_CLOSE);
1716 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1719 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1720 Curl_safefree(sshc->readdir_filename);
1721 sshc->readdir_filename = NULL;
1722 state(conn, SSH_SFTP_CLOSE);
1723 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1726 state(conn, SSH_SFTP_READDIR);
1729 case SSH_SFTP_READDIR:
1730 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1731 sshc->readdir_filename,
1733 sshc->readdir_longentry,
1735 &sshc->readdir_attrs);
1736 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1737 rc = LIBSSH2_ERROR_EAGAIN;
1740 if(sshc->readdir_len > 0) {
1741 sshc->readdir_filename[sshc->readdir_len] = '\0';
1743 if(data->set.ftp_list_only) {
1746 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1747 if(tmpLine == NULL) {
1748 state(conn, SSH_SFTP_CLOSE);
1749 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1752 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1753 tmpLine, sshc->readdir_len+1);
1754 Curl_safefree(tmpLine);
1757 state(conn, SSH_STOP);
1760 /* since this counts what we send to the client, we include the
1761 newline in this counter */
1762 data->req.bytecount += sshc->readdir_len+1;
1764 /* output debug output if that is requested */
1765 if(data->set.verbose) {
1766 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1767 sshc->readdir_len, conn);
1771 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1772 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1773 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1774 if(!sshc->readdir_line) {
1775 Curl_safefree(sshc->readdir_filename);
1776 sshc->readdir_filename = NULL;
1777 Curl_safefree(sshc->readdir_longentry);
1778 sshc->readdir_longentry = NULL;
1779 state(conn, SSH_SFTP_CLOSE);
1780 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1784 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1785 sshc->readdir_currLen);
1786 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1787 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1788 LIBSSH2_SFTP_S_IFLNK)) {
1789 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1790 if(sshc->readdir_linkPath == NULL) {
1791 Curl_safefree(sshc->readdir_filename);
1792 sshc->readdir_filename = NULL;
1793 Curl_safefree(sshc->readdir_longentry);
1794 sshc->readdir_longentry = NULL;
1795 state(conn, SSH_SFTP_CLOSE);
1796 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1800 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1801 sshc->readdir_filename);
1802 state(conn, SSH_SFTP_READDIR_LINK);
1805 state(conn, SSH_SFTP_READDIR_BOTTOM);
1809 else if(sshc->readdir_len == 0) {
1810 Curl_safefree(sshc->readdir_filename);
1811 sshc->readdir_filename = NULL;
1812 Curl_safefree(sshc->readdir_longentry);
1813 sshc->readdir_longentry = NULL;
1814 state(conn, SSH_SFTP_READDIR_DONE);
1817 else if(sshc->readdir_len <= 0) {
1818 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1819 result = sftp_libssh2_error_to_CURLE(err);
1820 sshc->actualcode = result?result:CURLE_SSH;
1821 failf(data, "Could not open remote file for reading: %s :: %d",
1822 sftp_libssh2_strerror(err),
1823 libssh2_session_last_errno(sshc->ssh_session));
1824 Curl_safefree(sshc->readdir_filename);
1825 sshc->readdir_filename = NULL;
1826 Curl_safefree(sshc->readdir_longentry);
1827 sshc->readdir_longentry = NULL;
1828 state(conn, SSH_SFTP_CLOSE);
1833 case SSH_SFTP_READDIR_LINK:
1835 libssh2_sftp_symlink_ex(sshc->sftp_session,
1836 sshc->readdir_linkPath,
1837 (unsigned int) strlen(sshc->readdir_linkPath),
1838 sshc->readdir_filename,
1839 PATH_MAX, LIBSSH2_SFTP_READLINK);
1840 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1841 rc = LIBSSH2_ERROR_EAGAIN;
1844 Curl_safefree(sshc->readdir_linkPath);
1845 sshc->readdir_linkPath = NULL;
1846 sshc->readdir_line = realloc(sshc->readdir_line,
1847 sshc->readdir_totalLen + 4 +
1849 if(!sshc->readdir_line) {
1850 Curl_safefree(sshc->readdir_filename);
1851 sshc->readdir_filename = NULL;
1852 Curl_safefree(sshc->readdir_longentry);
1853 sshc->readdir_longentry = NULL;
1854 state(conn, SSH_SFTP_CLOSE);
1855 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1859 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1860 sshc->readdir_currLen,
1861 sshc->readdir_totalLen -
1862 sshc->readdir_currLen,
1864 sshc->readdir_filename);
1866 state(conn, SSH_SFTP_READDIR_BOTTOM);
1869 case SSH_SFTP_READDIR_BOTTOM:
1870 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1871 sshc->readdir_currLen,
1872 sshc->readdir_totalLen -
1873 sshc->readdir_currLen, "\n");
1874 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1876 sshc->readdir_currLen);
1878 if(result == CURLE_OK) {
1880 /* output debug output if that is requested */
1881 if(data->set.verbose) {
1882 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1883 sshc->readdir_currLen, conn);
1885 data->req.bytecount += sshc->readdir_currLen;
1887 Curl_safefree(sshc->readdir_line);
1888 sshc->readdir_line = NULL;
1890 state(conn, SSH_STOP);
1893 state(conn, SSH_SFTP_READDIR);
1896 case SSH_SFTP_READDIR_DONE:
1897 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1898 LIBSSH2_ERROR_EAGAIN) {
1899 rc = LIBSSH2_ERROR_EAGAIN;
1902 sshc->sftp_handle = NULL;
1903 Curl_safefree(sshc->readdir_filename);
1904 sshc->readdir_filename = NULL;
1905 Curl_safefree(sshc->readdir_longentry);
1906 sshc->readdir_longentry = NULL;
1908 /* no data to transfer */
1909 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1910 state(conn, SSH_STOP);
1913 case SSH_SFTP_DOWNLOAD_INIT:
1915 * Work on getting the specified file
1918 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1919 (unsigned int)strlen(sftp_scp->path),
1920 LIBSSH2_FXF_READ, data->set.new_file_perms,
1921 LIBSSH2_SFTP_OPENFILE);
1922 if(!sshc->sftp_handle) {
1923 if(libssh2_session_last_errno(sshc->ssh_session) ==
1924 LIBSSH2_ERROR_EAGAIN) {
1925 rc = LIBSSH2_ERROR_EAGAIN;
1929 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1930 failf(data, "Could not open remote file for reading: %s",
1931 sftp_libssh2_strerror(err));
1932 state(conn, SSH_SFTP_CLOSE);
1933 result = sftp_libssh2_error_to_CURLE(err);
1934 sshc->actualcode = result?result:CURLE_SSH;
1938 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1941 case SSH_SFTP_DOWNLOAD_STAT:
1943 LIBSSH2_SFTP_ATTRIBUTES attrs;
1945 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1946 (unsigned int)strlen(sftp_scp->path),
1947 LIBSSH2_SFTP_STAT, &attrs);
1948 if(rc == LIBSSH2_ERROR_EAGAIN) {
1953 * libssh2_sftp_open() didn't return an error, so maybe the server
1954 * just doesn't support stat()
1956 data->req.size = -1;
1957 data->req.maxdownload = -1;
1960 curl_off_t size = attrs.filesize;
1963 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1964 return CURLE_BAD_DOWNLOAD_RESUME;
1966 if(conn->data->state.use_range) {
1967 curl_off_t from, to;
1971 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1972 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
1974 to=curlx_strtoofft(ptr, &ptr2, 0);
1975 if((ptr == ptr2) /* no "to" value given */
1980 /* from is relative to end of file */
1984 failf(data, "Offset (%"
1985 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1986 from, attrs.filesize);
1987 return CURLE_BAD_DOWNLOAD_RESUME;
1994 size = to - from + 1;
1997 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
1999 data->req.size = size;
2000 data->req.maxdownload = size;
2001 Curl_pgrsSetDownloadSize(data, size);
2004 /* We can resume if we can seek to the resume position */
2005 if(data->state.resume_from) {
2006 if(data->state.resume_from < 0) {
2007 /* We're supposed to download the last abs(from) bytes */
2008 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2009 failf(data, "Offset (%"
2010 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2011 data->state.resume_from, attrs.filesize);
2012 return CURLE_BAD_DOWNLOAD_RESUME;
2014 /* download from where? */
2015 data->state.resume_from += attrs.filesize;
2018 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2019 failf(data, "Offset (%" FORMAT_OFF_T
2020 ") was beyond file size (%" FORMAT_OFF_T ")",
2021 data->state.resume_from, attrs.filesize);
2022 return CURLE_BAD_DOWNLOAD_RESUME;
2025 /* Does a completed file need to be seeked and started or closed ? */
2026 /* Now store the number of bytes we are expected to download */
2027 data->req.size = attrs.filesize - data->state.resume_from;
2028 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2029 Curl_pgrsSetDownloadSize(data,
2030 attrs.filesize - data->state.resume_from);
2031 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2034 /* Setup the actual download */
2035 if(data->req.size == 0) {
2036 /* no data to transfer */
2037 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2038 infof(data, "File already completely downloaded\n");
2039 state(conn, SSH_STOP);
2043 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2044 FALSE, NULL, -1, NULL);
2046 /* not set by Curl_setup_transfer to preserve keepon bits */
2047 conn->writesockfd = conn->sockfd;
2049 /* we want to use the _receiving_ function even when the socket turns
2050 out writableable as the underlying libssh2 recv function will deal
2051 with both accordingly */
2052 conn->cselect_bits = CURL_CSELECT_IN;
2055 state(conn, SSH_SFTP_CLOSE);
2056 sshc->actualcode = result;
2059 state(conn, SSH_STOP);
2063 case SSH_SFTP_CLOSE:
2064 if(sshc->sftp_handle) {
2065 rc = libssh2_sftp_close(sshc->sftp_handle);
2066 if(rc == LIBSSH2_ERROR_EAGAIN) {
2070 infof(data, "Failed to close libssh2 file\n");
2072 sshc->sftp_handle = NULL;
2075 Curl_safefree(sftp_scp->path);
2076 sftp_scp->path = NULL;
2079 DEBUGF(infof(data, "SFTP DONE done\n"));
2081 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2082 After nextstate is executed,the control should come back to
2083 SSH_SFTP_CLOSE to pass the correct result back */
2084 if(sshc->nextstate != SSH_NO_STATE) {
2085 state(conn, sshc->nextstate);
2086 sshc->nextstate = SSH_SFTP_CLOSE;
2089 state(conn, SSH_STOP);
2090 result = sshc->actualcode;
2094 case SSH_SFTP_SHUTDOWN:
2095 /* during times we get here due to a broken transfer and then the
2096 sftp_handle might not have been taken down so make sure that is done
2097 before we proceed */
2099 if(sshc->sftp_handle) {
2100 rc = libssh2_sftp_close(sshc->sftp_handle);
2101 if(rc == LIBSSH2_ERROR_EAGAIN) {
2105 infof(data, "Failed to close libssh2 file\n");
2107 sshc->sftp_handle = NULL;
2109 if(sshc->sftp_session) {
2110 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2111 if(rc == LIBSSH2_ERROR_EAGAIN) {
2115 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2117 sshc->sftp_session = NULL;
2120 Curl_safefree(sshc->homedir);
2121 sshc->homedir = NULL;
2122 conn->data->state.most_recent_ftp_entrypath = NULL;
2124 state(conn, SSH_SESSION_DISCONNECT);
2127 case SSH_SCP_TRANS_INIT:
2128 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2130 sshc->actualcode = result;
2131 state(conn, SSH_STOP);
2135 if(data->set.upload) {
2136 if(data->set.infilesize < 0) {
2137 failf(data, "SCP requires a known file size for upload");
2138 sshc->actualcode = CURLE_UPLOAD_FAILED;
2139 state(conn, SSH_SCP_CHANNEL_FREE);
2142 state(conn, SSH_SCP_UPLOAD_INIT);
2145 state(conn, SSH_SCP_DOWNLOAD_INIT);
2149 case SSH_SCP_UPLOAD_INIT:
2151 * libssh2 requires that the destination path is a full path that
2152 * includes the destination file and name OR ends in a "/" . If this is
2153 * not done the destination file will be named the same name as the last
2154 * directory in the path.
2157 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2158 data->set.infilesize);
2159 if(!sshc->ssh_channel) {
2160 if(libssh2_session_last_errno(sshc->ssh_session) ==
2161 LIBSSH2_ERROR_EAGAIN) {
2162 rc = LIBSSH2_ERROR_EAGAIN;
2169 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2170 &err_msg, NULL, 0));
2171 failf(conn->data, "%s", err_msg);
2172 state(conn, SSH_SCP_CHANNEL_FREE);
2173 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2179 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2182 /* not set by Curl_setup_transfer to preserve keepon bits */
2183 conn->sockfd = conn->writesockfd;
2186 state(conn, SSH_SCP_CHANNEL_FREE);
2187 sshc->actualcode = result;
2190 /* we want to use the _sending_ function even when the socket turns
2191 out readable as the underlying libssh2 scp send function will deal
2192 with both accordingly */
2193 conn->cselect_bits = CURL_CSELECT_OUT;
2195 state(conn, SSH_STOP);
2199 case SSH_SCP_DOWNLOAD_INIT:
2202 * We must check the remote file; if it is a directory no values will
2206 curl_off_t bytecount;
2208 /* clear the struct scp recv will fill in */
2209 memset(&sb, 0, sizeof(struct stat));
2211 /* get a fresh new channel from the ssh layer */
2212 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2213 sftp_scp->path, &sb);
2214 if(!sshc->ssh_channel) {
2215 if(libssh2_session_last_errno(sshc->ssh_session) ==
2216 LIBSSH2_ERROR_EAGAIN) {
2217 rc = LIBSSH2_ERROR_EAGAIN;
2224 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2225 &err_msg, NULL, 0));
2226 failf(conn->data, "%s", err_msg);
2227 state(conn, SSH_SCP_CHANNEL_FREE);
2228 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2234 bytecount = (curl_off_t)sb.st_size;
2235 data->req.maxdownload = (curl_off_t)sb.st_size;
2236 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2238 /* not set by Curl_setup_transfer to preserve keepon bits */
2239 conn->writesockfd = conn->sockfd;
2241 /* we want to use the _receiving_ function even when the socket turns
2242 out writableable as the underlying libssh2 recv function will deal
2243 with both accordingly */
2244 conn->cselect_bits = CURL_CSELECT_IN;
2247 state(conn, SSH_SCP_CHANNEL_FREE);
2248 sshc->actualcode = result;
2251 state(conn, SSH_STOP);
2256 if(data->set.upload)
2257 state(conn, SSH_SCP_SEND_EOF);
2259 state(conn, SSH_SCP_CHANNEL_FREE);
2262 case SSH_SCP_SEND_EOF:
2263 if(sshc->ssh_channel) {
2264 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2265 if(rc == LIBSSH2_ERROR_EAGAIN) {
2269 infof(data, "Failed to send libssh2 channel EOF\n");
2272 state(conn, SSH_SCP_WAIT_EOF);
2275 case SSH_SCP_WAIT_EOF:
2276 if(sshc->ssh_channel) {
2277 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2278 if(rc == LIBSSH2_ERROR_EAGAIN) {
2282 infof(data, "Failed to get channel EOF: %d\n", rc);
2285 state(conn, SSH_SCP_WAIT_CLOSE);
2288 case SSH_SCP_WAIT_CLOSE:
2289 if(sshc->ssh_channel) {
2290 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2291 if(rc == LIBSSH2_ERROR_EAGAIN) {
2295 infof(data, "Channel failed to close: %d\n", rc);
2298 state(conn, SSH_SCP_CHANNEL_FREE);
2301 case SSH_SCP_CHANNEL_FREE:
2302 if(sshc->ssh_channel) {
2303 rc = libssh2_channel_free(sshc->ssh_channel);
2304 if(rc == LIBSSH2_ERROR_EAGAIN) {
2308 infof(data, "Failed to free libssh2 scp subsystem\n");
2310 sshc->ssh_channel = NULL;
2312 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2314 state(conn, SSH_SESSION_DISCONNECT);
2316 state(conn, SSH_STOP);
2317 result = sshc->actualcode;
2320 case SSH_SESSION_DISCONNECT:
2321 /* during weird times when we've been prematurely aborted, the channel
2322 is still alive when we reach this state and we MUST kill the channel
2324 if(sshc->ssh_channel) {
2325 rc = libssh2_channel_free(sshc->ssh_channel);
2326 if(rc == LIBSSH2_ERROR_EAGAIN) {
2330 infof(data, "Failed to free libssh2 scp subsystem\n");
2332 sshc->ssh_channel = NULL;
2335 if(sshc->ssh_session) {
2336 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2337 if(rc == LIBSSH2_ERROR_EAGAIN) {
2341 infof(data, "Failed to disconnect libssh2 session\n");
2345 Curl_safefree(sshc->homedir);
2346 sshc->homedir = NULL;
2347 conn->data->state.most_recent_ftp_entrypath = NULL;
2349 state(conn, SSH_SESSION_FREE);
2352 case SSH_SESSION_FREE:
2353 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2355 libssh2_knownhost_free(sshc->kh);
2360 if(sshc->ssh_session) {
2361 rc = libssh2_session_free(sshc->ssh_session);
2362 if(rc == LIBSSH2_ERROR_EAGAIN) {
2366 infof(data, "Failed to free libssh2 session\n");
2368 sshc->ssh_session = NULL;
2370 conn->bits.close = TRUE;
2371 sshc->nextstate = SSH_NO_STATE;
2372 state(conn, SSH_STOP);
2373 result = sshc->actualcode;
2377 /* fallthrough, just stop! */
2379 /* internal error */
2380 sshc->nextstate = SSH_NO_STATE;
2381 state(conn, SSH_STOP);
2385 } while(!rc && (sshc->state != SSH_STOP));
2387 if(rc == LIBSSH2_ERROR_EAGAIN) {
2388 /* we would block, we need to wait for the socket to be ready (in the
2389 right direction too)! */
2396 /* called by the multi interface to figure out what socket(s) to wait for and
2397 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2398 static int ssh_perform_getsock(const struct connectdata *conn,
2399 curl_socket_t *sock, /* points to numsocks
2400 number of sockets */
2403 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2404 int bitmap = GETSOCK_BLANK;
2407 sock[0] = conn->sock[FIRSTSOCKET];
2409 if(conn->waitfor & KEEP_RECV)
2410 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2412 if(conn->waitfor & KEEP_SEND)
2413 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2417 /* if we don't know the direction we can use the generic *_getsock()
2418 function even for the protocol_connect and doing states */
2419 return Curl_single_getsock(conn, sock, numsocks);
2423 /* Generic function called by the multi interface to figure out what socket(s)
2424 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2425 static int ssh_getsock(struct connectdata *conn,
2426 curl_socket_t *sock, /* points to numsocks number
2430 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2434 /* if we don't know any direction we can just play along as we used to and
2435 not provide any sensible info */
2436 return GETSOCK_BLANK;
2438 /* if we know the direction we can use the generic *_getsock() function even
2439 for the protocol_connect and doing states */
2440 return ssh_perform_getsock(conn, sock, numsocks);
2444 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2446 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2447 * function is used to figure out in what direction and stores this info so
2448 * that the multi interface can take advantage of it. Make sure to call this
2449 * function in all cases so that when it _doesn't_ return EAGAIN we can
2450 * restore the default wait bits.
2452 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2454 struct ssh_conn *sshc = &conn->proto.sshc;
2458 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2459 /* translate the libssh2 define bits into our own bit defines */
2460 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2461 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2464 /* It didn't block or libssh2 didn't reveal in which direction, put back
2466 conn->waitfor = sshc->orig_waitfor;
2469 /* no libssh2 directional support so we simply don't know */
2470 #define ssh_block2waitfor(x,y)
2473 /* called repeatedly until done from multi.c */
2474 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2476 struct ssh_conn *sshc = &conn->proto.sshc;
2477 CURLcode result = CURLE_OK;
2478 bool block; /* we store the status and use that to provide a ssh_getsock()
2481 result = ssh_statemach_act(conn, &block);
2482 *done = (bool)(sshc->state == SSH_STOP);
2483 ssh_block2waitfor(conn, block);
2488 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2491 struct ssh_conn *sshc = &conn->proto.sshc;
2492 CURLcode result = CURLE_OK;
2493 struct SessionHandle *data = conn->data;
2495 while((sshc->state != SSH_STOP) && !result) {
2499 result = ssh_statemach_act(conn, &block);
2503 if(Curl_pgrsUpdate(conn))
2504 return CURLE_ABORTED_BY_CALLBACK;
2506 struct timeval now = Curl_tvnow();
2507 result = Curl_speedcheck(data, now);
2512 left = Curl_timeleft(data, NULL, duringconnect);
2514 failf(data, "Operation timed out\n");
2515 return CURLE_OPERATION_TIMEDOUT;
2518 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2519 if((CURLE_OK == result) && block) {
2520 int dir = libssh2_session_block_directions(sshc->ssh_session);
2521 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2522 curl_socket_t fd_read = CURL_SOCKET_BAD;
2523 curl_socket_t fd_write = CURL_SOCKET_BAD;
2524 if (LIBSSH2_SESSION_BLOCK_INBOUND & dir) {
2527 if (LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) {
2530 /* wait for the socket to become ready */
2531 Curl_socket_ready(fd_read, fd_write,
2532 (int)(left>1000?1000:left)); /* ignore result */
2542 * SSH setup and connection
2544 static CURLcode ssh_init(struct connectdata *conn)
2546 struct SessionHandle *data = conn->data;
2547 struct SSHPROTO *ssh;
2548 struct ssh_conn *sshc = &conn->proto.sshc;
2550 sshc->actualcode = CURLE_OK; /* reset error code */
2551 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2554 if(data->state.proto.ssh)
2557 ssh = calloc(1, sizeof(struct SSHPROTO));
2559 return CURLE_OUT_OF_MEMORY;
2561 data->state.proto.ssh = ssh;
2566 static Curl_recv scp_recv, sftp_recv;
2567 static Curl_send scp_send, sftp_send;
2570 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2571 * do protocol-specific actions at connect-time.
2573 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2575 #ifdef CURL_LIBSSH2_DEBUG
2578 struct ssh_conn *ssh;
2580 struct SessionHandle *data = conn->data;
2582 /* We default to persistent connections. We set this already in this connect
2583 function to make the re-use checks properly be able to check this bit. */
2584 conn->bits.close = FALSE;
2586 /* If there already is a protocol-specific struct allocated for this
2587 sessionhandle, deal with it */
2588 Curl_reset_reqproto(conn);
2590 result = ssh_init(conn);
2594 if(conn->handler->protocol & CURLPROTO_SCP) {
2595 conn->recv[FIRSTSOCKET] = scp_recv;
2596 conn->send[FIRSTSOCKET] = scp_send;
2598 conn->recv[FIRSTSOCKET] = sftp_recv;
2599 conn->send[FIRSTSOCKET] = sftp_send;
2601 ssh = &conn->proto.sshc;
2603 #ifdef CURL_LIBSSH2_DEBUG
2605 infof(data, "User: %s\n", conn->user);
2608 infof(data, "Password: %s\n", conn->passwd);
2610 sock = conn->sock[FIRSTSOCKET];
2611 #endif /* CURL_LIBSSH2_DEBUG */
2613 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2615 my_libssh2_realloc, conn);
2616 if(ssh->ssh_session == NULL) {
2617 failf(data, "Failure initialising ssh session");
2618 return CURLE_FAILED_INIT;
2621 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2622 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2624 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2626 /* eeek. TODO: free the ssh_session! */
2627 return CURLE_FAILED_INIT;
2630 /* read all known hosts from there */
2631 rc = libssh2_knownhost_readfile(ssh->kh,
2632 data->set.str[STRING_SSH_KNOWNHOSTS],
2633 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2635 infof(data, "Failed to read known hosts from %s\n",
2636 data->set.str[STRING_SSH_KNOWNHOSTS]);
2638 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2640 #ifdef CURL_LIBSSH2_DEBUG
2641 libssh2_trace(ssh->ssh_session, ~0);
2642 infof(data, "SSH socket: %d\n", (int)sock);
2643 #endif /* CURL_LIBSSH2_DEBUG */
2645 state(conn, SSH_S_STARTUP);
2647 if(data->state.used_interface == Curl_if_multi)
2648 result = ssh_multi_statemach(conn, done);
2650 result = ssh_easy_statemach(conn, TRUE);
2659 ***********************************************************************
2663 * This is the actual DO function for SCP. Get a file according to
2664 * the options previously setup.
2668 CURLcode scp_perform(struct connectdata *conn,
2672 CURLcode result = CURLE_OK;
2674 DEBUGF(infof(conn->data, "DO phase starts\n"));
2676 *dophase_done = FALSE; /* not done yet */
2678 /* start the first command in the DO phase */
2679 state(conn, SSH_SCP_TRANS_INIT);
2681 /* run the state-machine */
2682 if(conn->data->state.used_interface == Curl_if_multi) {
2683 result = ssh_multi_statemach(conn, dophase_done);
2686 result = ssh_easy_statemach(conn, FALSE);
2687 *dophase_done = TRUE; /* with the easy interface we are done here */
2689 *connected = conn->bits.tcpconnect;
2692 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2698 /* called from multi.c while DOing */
2699 static CURLcode scp_doing(struct connectdata *conn,
2703 result = ssh_multi_statemach(conn, dophase_done);
2706 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2712 * The DO function is generic for both protocols. There was previously two
2713 * separate ones but this way means less duplicated code.
2716 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2720 struct SessionHandle *data = conn->data;
2722 *done = FALSE; /* default to false */
2725 Since connections can be re-used between SessionHandles, this might be a
2726 connection already existing but on a fresh SessionHandle struct so we must
2727 make sure we have a good 'struct SSHPROTO' to play with. For new
2728 connections, the struct SSHPROTO is allocated and setup in the
2729 ssh_connect() function.
2731 Curl_reset_reqproto(conn);
2732 res = ssh_init(conn);
2736 data->req.size = -1; /* make sure this is unknown at this point */
2738 Curl_pgrsSetUploadCounter(data, 0);
2739 Curl_pgrsSetDownloadCounter(data, 0);
2740 Curl_pgrsSetUploadSize(data, 0);
2741 Curl_pgrsSetDownloadSize(data, 0);
2743 if(conn->handler->protocol & CURLPROTO_SCP)
2744 res = scp_perform(conn, &connected, done);
2746 res = sftp_perform(conn, &connected, done);
2751 /* BLOCKING, but the function is using the state machine so the only reason
2752 this is still blocking is that the multi interface code has no support for
2753 disconnecting operations that takes a while */
2754 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2756 CURLcode result = CURLE_OK;
2757 struct ssh_conn *ssh = &conn->proto.sshc;
2758 (void) dead_connection;
2760 Curl_safefree(conn->data->state.proto.ssh);
2761 conn->data->state.proto.ssh = NULL;
2763 if(ssh->ssh_session) {
2764 /* only if there's a session still around to use! */
2766 state(conn, SSH_SESSION_DISCONNECT);
2768 result = ssh_easy_statemach(conn, FALSE);
2774 /* generic done function for both SCP and SFTP called from their specific
2776 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2778 CURLcode result = CURLE_OK;
2779 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2781 if(status == CURLE_OK) {
2782 /* run the state-machine
2784 TODO: when the multi interface is used, this _really_ should be using
2785 the ssh_multi_statemach function but we have no general support for
2786 non-blocking DONE operations, not in the multi state machine and with
2787 Curl_done() invokes on several places in the code!
2789 result = ssh_easy_statemach(conn, FALSE);
2795 Curl_safefree(sftp_scp->path);
2796 sftp_scp->path = NULL;
2798 Curl_pgrsDone(conn);
2800 conn->data->req.keepon = 0; /* clear all bits */
2805 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2808 (void)premature; /* not used */
2810 if(status == CURLE_OK)
2811 state(conn, SSH_SCP_DONE);
2813 return ssh_done(conn, status);
2817 /* return number of received (decrypted) bytes */
2818 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2819 const void *mem, size_t len, CURLcode *err)
2822 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2824 /* libssh2_channel_write() returns int! */
2826 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2828 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2830 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2839 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2840 * a regular CURLcode value.
2842 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2843 char *mem, size_t len, CURLcode *err)
2846 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2848 /* libssh2_channel_read() returns int */
2850 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2852 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2853 if (nread == LIBSSH2_ERROR_EAGAIN) {
2862 * =============== SFTP ===============
2866 ***********************************************************************
2870 * This is the actual DO function for SFTP. Get a file/directory according to
2871 * the options previously setup.
2875 CURLcode sftp_perform(struct connectdata *conn,
2879 CURLcode result = CURLE_OK;
2881 DEBUGF(infof(conn->data, "DO phase starts\n"));
2883 *dophase_done = FALSE; /* not done yet */
2885 /* start the first command in the DO phase */
2886 state(conn, SSH_SFTP_QUOTE_INIT);
2888 /* run the state-machine */
2889 if(conn->data->state.used_interface == Curl_if_multi) {
2890 result = ssh_multi_statemach(conn, dophase_done);
2893 result = ssh_easy_statemach(conn, FALSE);
2894 *dophase_done = TRUE; /* with the easy interface we are done here */
2896 *connected = conn->bits.tcpconnect;
2899 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2905 /* called from multi.c while DOing */
2906 static CURLcode sftp_doing(struct connectdata *conn,
2910 result = ssh_multi_statemach(conn, dophase_done);
2913 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2918 /* BLOCKING, but the function is using the state machine so the only reason
2919 this is still blocking is that the multi interface code has no support for
2920 disconnecting operations that takes a while */
2921 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
2923 CURLcode result = CURLE_OK;
2924 (void) dead_connection;
2926 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2928 Curl_safefree(conn->data->state.proto.ssh);
2929 conn->data->state.proto.ssh = NULL;
2931 if(conn->proto.sshc.ssh_session) {
2932 /* only if there's a session still around to use! */
2933 state(conn, SSH_SFTP_SHUTDOWN);
2934 result = ssh_easy_statemach(conn, FALSE);
2937 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2943 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2946 struct ssh_conn *sshc = &conn->proto.sshc;
2948 if(status == CURLE_OK) {
2949 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
2950 errors that could happen due to open file handles during POSTQUOTE
2952 if(!status && !premature && conn->data->set.postquote) {
2953 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
2954 state(conn, SSH_SFTP_CLOSE);
2957 state(conn, SSH_SFTP_CLOSE);
2959 return ssh_done(conn, status);
2962 /* return number of sent bytes */
2963 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
2964 const void *mem, size_t len, CURLcode *err)
2966 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2967 but is changed to ssize_t in 0.15. These days we don't
2968 support libssh2 0.15*/
2971 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2973 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2975 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2984 * Return number of received (decrypted) bytes
2986 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
2987 char *mem, size_t len, CURLcode *err)
2992 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
2994 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2996 if(nread == LIBSSH2_ERROR_EAGAIN) {
3003 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3006 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3008 * Permission to use, copy, modify, and distribute this software for any
3009 * purpose with or without fee is hereby granted, provided that the above
3010 * copyright notice and this permission notice appear in all copies.
3012 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3013 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3014 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3015 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3016 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3017 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3018 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3021 get_pathname(const char **cpp, char **path)
3023 const char *cp = *cpp, *end;
3026 static const char WHITESPACE[] = " \t\r\n";
3028 cp += strspn(cp, WHITESPACE);
3032 return CURLE_QUOTE_ERROR;
3035 *path = malloc(strlen(cp) + 1);
3037 return CURLE_OUT_OF_MEMORY;
3039 /* Check for quoted filenames */
3040 if(*cp == '\"' || *cp == '\'') {
3043 /* Search for terminating quote, unescape some chars */
3044 for (i = j = 0; i <= strlen(cp); i++) {
3045 if(cp[i] == quot) { /* Found quote */
3050 if(cp[i] == '\0') { /* End of string */
3051 /*error("Unterminated quote");*/
3054 if(cp[i] == '\\') { /* Escaped characters */
3056 if(cp[i] != '\'' && cp[i] != '\"' &&
3058 /*error("Bad escaped character '\\%c'",
3063 (*path)[j++] = cp[i];
3067 /*error("Empty quotes");*/
3070 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3073 /* Read to end of filename */
3074 end = strpbrk(cp, WHITESPACE);
3076 end = strchr(cp, '\0');
3077 *cpp = end + strspn(end, WHITESPACE);
3079 memcpy(*path, cp, end - cp);
3080 (*path)[end - cp] = '\0';
3085 Curl_safefree(*path);
3087 return CURLE_QUOTE_ERROR;
3091 static const char *sftp_libssh2_strerror(unsigned long err)
3094 case LIBSSH2_FX_NO_SUCH_FILE:
3095 return "No such file or directory";
3097 case LIBSSH2_FX_PERMISSION_DENIED:
3098 return "Permission denied";
3100 case LIBSSH2_FX_FAILURE:
3101 return "Operation failed";
3103 case LIBSSH2_FX_BAD_MESSAGE:
3104 return "Bad message from SFTP server";
3106 case LIBSSH2_FX_NO_CONNECTION:
3107 return "Not connected to SFTP server";
3109 case LIBSSH2_FX_CONNECTION_LOST:
3110 return "Connection to SFTP server lost";
3112 case LIBSSH2_FX_OP_UNSUPPORTED:
3113 return "Operation not supported by SFTP server";
3115 case LIBSSH2_FX_INVALID_HANDLE:
3116 return "Invalid handle";
3118 case LIBSSH2_FX_NO_SUCH_PATH:
3119 return "No such file or directory";
3121 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3122 return "File already exists";
3124 case LIBSSH2_FX_WRITE_PROTECT:
3125 return "File is write protected";
3127 case LIBSSH2_FX_NO_MEDIA:
3130 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3133 case LIBSSH2_FX_QUOTA_EXCEEDED:
3134 return "User quota exceeded";
3136 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3137 return "Unknown principle";
3139 case LIBSSH2_FX_LOCK_CONFlICT:
3140 return "File lock conflict";
3142 case LIBSSH2_FX_DIR_NOT_EMPTY:
3143 return "Directory not empty";
3145 case LIBSSH2_FX_NOT_A_DIRECTORY:
3146 return "Not a directory";
3148 case LIBSSH2_FX_INVALID_FILENAME:
3149 return "Invalid filename";
3151 case LIBSSH2_FX_LINK_LOOP:
3152 return "Link points to itself";
3154 return "Unknown error in libssh2";
3157 #endif /* USE_LIBSSH2 */