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 */
34 #include <libssh2_sftp.h>
44 #ifdef HAVE_SYS_SOCKET_H
45 #include <sys/socket.h>
47 #ifdef HAVE_NETINET_IN_H
48 #include <netinet/in.h>
50 #ifdef HAVE_ARPA_INET_H
51 #include <arpa/inet.h>
54 #include <sys/utsname.h>
64 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
66 #define in_addr_t unsigned long
69 #include <curl/curl.h>
76 #include "http.h" /* for HTTP proxy tunnel stuff */
79 #include "speedcheck.h"
86 #include "inet_ntop.h"
87 #include "parsedate.h" /* for the week day and month names */
88 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
89 #include "strtoofft.h"
94 #define _MPRINTF_REPLACE /* use our functions only */
95 #include <curl/mprintf.h>
97 #include "curl_memory.h"
98 /* The last #include file should be: */
102 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
103 have their definition hidden well */
106 /* Local functions: */
107 static const char *sftp_libssh2_strerror(unsigned long err);
108 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
109 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
110 static LIBSSH2_FREE_FUNC(my_libssh2_free);
112 static CURLcode get_pathname(const char **cpp, char **path);
114 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
115 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
116 static CURLcode ssh_do(struct connectdata *conn, bool *done);
118 static CURLcode ssh_getworkingpath(struct connectdata *conn,
119 char *homedir, /* when SFTP is used */
122 static CURLcode scp_done(struct connectdata *conn,
123 CURLcode, bool premature);
124 static CURLcode scp_doing(struct connectdata *conn,
126 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
128 static CURLcode sftp_done(struct connectdata *conn,
129 CURLcode, bool premature);
130 static CURLcode sftp_doing(struct connectdata *conn,
132 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
134 CURLcode sftp_perform(struct connectdata *conn,
138 static int ssh_getsock(struct connectdata *conn,
139 curl_socket_t *sock, /* points to numsocks number
143 static int ssh_perform_getsock(const struct connectdata *conn,
144 curl_socket_t *sock, /* points to numsocks
149 * SCP protocol handler.
152 const struct Curl_handler Curl_handler_scp = {
154 ZERO_NULL, /* setup_connection */
157 ZERO_NULL, /* do_more */
158 ssh_connect, /* connect_it */
159 ssh_multi_statemach, /* connecting */
160 scp_doing, /* doing */
161 ssh_getsock, /* proto_getsock */
162 ssh_getsock, /* doing_getsock */
163 ssh_perform_getsock, /* perform_getsock */
164 scp_disconnect, /* disconnect */
165 ZERO_NULL, /* readwrite */
166 PORT_SSH, /* defport */
167 CURLPROTO_SCP, /* protocol */
168 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
173 * SFTP protocol handler.
176 const struct Curl_handler Curl_handler_sftp = {
178 ZERO_NULL, /* setup_connection */
180 sftp_done, /* done */
181 ZERO_NULL, /* do_more */
182 ssh_connect, /* connect_it */
183 ssh_multi_statemach, /* connecting */
184 sftp_doing, /* doing */
185 ssh_getsock, /* proto_getsock */
186 ssh_getsock, /* doing_getsock */
187 ssh_perform_getsock, /* perform_getsock */
188 sftp_disconnect, /* disconnect */
189 ZERO_NULL, /* readwrite */
190 PORT_SSH, /* defport */
191 CURLPROTO_SFTP, /* protocol */
192 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
197 kbd_callback(const char *name, int name_len, const char *instruction,
198 int instruction_len, int num_prompts,
199 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
200 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
203 struct connectdata *conn = (struct connectdata *)*abstract;
205 #ifdef CURL_LIBSSH2_DEBUG
206 fprintf(stderr, "name=%s\n", name);
207 fprintf(stderr, "name_len=%d\n", name_len);
208 fprintf(stderr, "instruction=%s\n", instruction);
209 fprintf(stderr, "instruction_len=%d\n", instruction_len);
210 fprintf(stderr, "num_prompts=%d\n", num_prompts);
215 (void)instruction_len;
216 #endif /* CURL_LIBSSH2_DEBUG */
217 if(num_prompts == 1) {
218 responses[0].text = strdup(conn->passwd);
219 responses[0].length = (unsigned int)strlen(conn->passwd);
225 static CURLcode sftp_libssh2_error_to_CURLE(int err)
231 case LIBSSH2_FX_NO_SUCH_FILE:
232 case LIBSSH2_FX_NO_SUCH_PATH:
233 return CURLE_REMOTE_FILE_NOT_FOUND;
235 case LIBSSH2_FX_PERMISSION_DENIED:
236 case LIBSSH2_FX_WRITE_PROTECT:
237 case LIBSSH2_FX_LOCK_CONFlICT:
238 return CURLE_REMOTE_ACCESS_DENIED;
240 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
241 case LIBSSH2_FX_QUOTA_EXCEEDED:
242 return CURLE_REMOTE_DISK_FULL;
244 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
245 return CURLE_REMOTE_FILE_EXISTS;
247 case LIBSSH2_FX_DIR_NOT_EMPTY:
248 return CURLE_QUOTE_ERROR;
257 static CURLcode libssh2_session_error_to_CURLE(int err)
260 /* Ordered by order of appearance in libssh2.h */
261 case LIBSSH2_ERROR_NONE:
264 case LIBSSH2_ERROR_SOCKET_NONE:
265 return CURLE_COULDNT_CONNECT;
267 case LIBSSH2_ERROR_ALLOC:
268 return CURLE_OUT_OF_MEMORY;
270 case LIBSSH2_ERROR_SOCKET_SEND:
271 return CURLE_SEND_ERROR;
273 case LIBSSH2_ERROR_HOSTKEY_INIT:
274 case LIBSSH2_ERROR_HOSTKEY_SIGN:
275 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
276 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
277 return CURLE_PEER_FAILED_VERIFICATION;
279 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
280 return CURLE_LOGIN_DENIED;
282 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
283 case LIBSSH2_ERROR_TIMEOUT:
284 return CURLE_OPERATION_TIMEDOUT;
286 case LIBSSH2_ERROR_EAGAIN:
290 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
291 error code, and possibly add a few new SSH-related one. We must however
292 not return or even depend on libssh2 errors in the public libcurl API */
297 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
299 (void)abstract; /* arg not used */
300 return malloc(count);
303 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
305 (void)abstract; /* arg not used */
306 return realloc(ptr, count);
309 static LIBSSH2_FREE_FUNC(my_libssh2_free)
311 (void)abstract; /* arg not used */
316 * SSH State machine related code
318 /* This is the ONLY way to change SSH state! */
319 static void state(struct connectdata *conn, sshstate nowstate)
321 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
322 /* for debug purposes */
323 static const char * const names[] = {
329 "SSH_AUTH_PKEY_INIT",
331 "SSH_AUTH_PASS_INIT",
333 "SSH_AUTH_HOST_INIT",
340 "SSH_SFTP_QUOTE_INIT",
341 "SSH_SFTP_POSTQUOTE_INIT",
343 "SSH_SFTP_NEXT_QUOTE",
344 "SSH_SFTP_QUOTE_STAT",
345 "SSH_SFTP_QUOTE_SETSTAT",
346 "SSH_SFTP_QUOTE_SYMLINK",
347 "SSH_SFTP_QUOTE_MKDIR",
348 "SSH_SFTP_QUOTE_RENAME",
349 "SSH_SFTP_QUOTE_RMDIR",
350 "SSH_SFTP_QUOTE_UNLINK",
351 "SSH_SFTP_TRANS_INIT",
352 "SSH_SFTP_UPLOAD_INIT",
353 "SSH_SFTP_CREATE_DIRS_INIT",
354 "SSH_SFTP_CREATE_DIRS",
355 "SSH_SFTP_CREATE_DIRS_MKDIR",
356 "SSH_SFTP_READDIR_INIT",
358 "SSH_SFTP_READDIR_LINK",
359 "SSH_SFTP_READDIR_BOTTOM",
360 "SSH_SFTP_READDIR_DONE",
361 "SSH_SFTP_DOWNLOAD_INIT",
362 "SSH_SFTP_DOWNLOAD_STAT",
365 "SSH_SCP_TRANS_INIT",
366 "SSH_SCP_UPLOAD_INIT",
367 "SSH_SCP_DOWNLOAD_INIT",
371 "SSH_SCP_WAIT_CLOSE",
372 "SSH_SCP_CHANNEL_FREE",
373 "SSH_SESSION_DISCONNECT",
378 struct ssh_conn *sshc = &conn->proto.sshc;
380 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
381 if(sshc->state != nowstate) {
382 infof(conn->data, "SFTP %p state change from %s to %s\n",
383 sshc, names[sshc->state], names[nowstate]);
387 sshc->state = nowstate;
390 /* figure out the path to work with in this particular request */
391 static CURLcode ssh_getworkingpath(struct connectdata *conn,
392 char *homedir, /* when SFTP is used */
393 char **path) /* returns the allocated
394 real path to work with */
396 struct SessionHandle *data = conn->data;
397 char *real_path = NULL;
399 int working_path_len;
401 working_path = curl_easy_unescape(data, data->state.path, 0,
404 return CURLE_OUT_OF_MEMORY;
406 /* Check for /~/ , indicating relative to the user's home directory */
407 if(conn->handler->protocol & CURLPROTO_SCP) {
408 real_path = malloc(working_path_len+1);
409 if(real_path == NULL) {
411 return CURLE_OUT_OF_MEMORY;
413 if((working_path_len > 1) && (working_path[1] == '~'))
414 /* It is referenced to the home directory, so strip the leading '/' */
415 memcpy(real_path, working_path+1, 1 + working_path_len-1);
417 memcpy(real_path, working_path, 1 + working_path_len);
419 else if(conn->handler->protocol & CURLPROTO_SFTP) {
420 if((working_path_len > 1) && (working_path[1] == '~')) {
421 size_t homelen = strlen(homedir);
422 real_path = malloc(homelen + working_path_len + 1);
423 if(real_path == NULL) {
425 return CURLE_OUT_OF_MEMORY;
427 /* It is referenced to the home directory, so strip the
429 memcpy(real_path, homedir, homelen);
430 real_path[homelen] = '/';
431 real_path[homelen+1] = '\0';
432 if(working_path_len > 3) {
433 memcpy(real_path+homelen+1, working_path + 3,
434 1 + working_path_len -3);
438 real_path = malloc(working_path_len+1);
439 if(real_path == NULL) {
441 return CURLE_OUT_OF_MEMORY;
443 memcpy(real_path, working_path, 1+working_path_len);
449 /* store the pointer for the caller to receive */
455 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
456 static int sshkeycallback(CURL *easy,
457 const struct curl_khkey *knownkey, /* known */
458 const struct curl_khkey *foundkey, /* found */
459 enum curl_khmatch match,
467 /* we only allow perfect matches, and we reject everything else */
468 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
473 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
476 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
477 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
479 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
483 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
484 * architectures so we check of the necessary function is present.
486 #ifndef HAVE_LIBSSH2_SCP_SEND64
487 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
489 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
490 (libssh2_uint64_t)d, 0, 0)
494 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
496 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
497 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
500 static CURLcode ssh_knownhost(struct connectdata *conn)
502 CURLcode result = CURLE_OK;
504 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
505 struct SessionHandle *data = conn->data;
507 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
508 /* we're asked to verify the host against a file */
509 struct ssh_conn *sshc = &conn->proto.sshc;
513 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
515 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
520 * A subject to figure out is what host name we need to pass in here.
521 * What host name does OpenSSH store in its file if an IDN name is
524 struct libssh2_knownhost *host;
525 enum curl_khmatch keymatch;
526 curl_sshkeycallback func =
527 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
528 struct curl_khkey knownkey;
529 struct curl_khkey *knownkeyp = NULL;
530 struct curl_khkey foundkey;
532 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
533 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
535 keycheck = libssh2_knownhost_check(sshc->kh,
538 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
539 LIBSSH2_KNOWNHOST_KEYENC_RAW|
543 infof(data, "SSH host check: %d, key: %s\n", keycheck,
544 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
547 /* setup 'knownkey' */
548 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
549 knownkey.key = host->key;
551 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
552 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
553 knownkeyp = &knownkey;
556 /* setup 'foundkey' */
557 foundkey.key = remotekey;
558 foundkey.len = keylen;
559 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
560 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
563 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
564 * curl_khmatch enum are ever modified, we need to introduce a
565 * translation table here!
567 keymatch = (enum curl_khmatch)keycheck;
569 /* Ask the callback how to behave */
570 rc = func(data, knownkeyp, /* from the knownhosts file */
571 &foundkey, /* from the remote host */
572 keymatch, data->set.ssh_keyfunc_userp);
575 /* no remotekey means failure! */
576 rc = CURLKHSTAT_REJECT;
579 default: /* unknown return codes will equal reject */
580 case CURLKHSTAT_REJECT:
581 state(conn, SSH_SESSION_FREE);
582 case CURLKHSTAT_DEFER:
583 /* DEFER means bail out but keep the SSH_HOSTKEY state */
584 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
586 case CURLKHSTAT_FINE:
587 case CURLKHSTAT_FINE_ADD_TO_FILE:
589 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
590 /* the found host+key didn't match but has been told to be fine
591 anyway so we add it in memory */
592 int addrc = libssh2_knownhost_add(sshc->kh,
593 conn->host.name, NULL,
595 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
596 LIBSSH2_KNOWNHOST_KEYENC_RAW|
599 infof(data, "Warning adding the known host %s failed!\n",
601 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
602 /* now we write the entire in-memory list of known hosts to the
605 libssh2_knownhost_writefile(sshc->kh,
606 data->set.str[STRING_SSH_KNOWNHOSTS],
607 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
609 infof(data, "Warning, writing %s failed!\n",
610 data->set.str[STRING_SSH_KNOWNHOSTS]);
617 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
625 * ssh_statemach_act() runs the SSH state machine as far as it can without
626 * blocking and without reaching the end. The data the pointer 'block' points
627 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
628 * meaning it wants to be called again when the socket is ready
631 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
633 CURLcode result = CURLE_OK;
634 struct SessionHandle *data = conn->data;
635 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
636 struct ssh_conn *sshc = &conn->proto.sshc;
637 curl_socket_t sock = conn->sock[FIRSTSOCKET];
638 #ifdef CURL_LIBSSH2_DEBUG
639 const char *fingerprint;
640 #endif /* CURL_LIBSSH2_DEBUG */
641 const char *host_public_key_md5;
642 int rc = LIBSSH2_ERROR_NONE, i;
644 int seekerr = CURL_SEEKFUNC_OK;
645 *block = 0; /* we're not blocking by default */
649 switch(sshc->state) {
651 sshc->secondCreateDirs = 0;
652 sshc->nextstate = SSH_NO_STATE;
653 sshc->actualcode = CURLE_OK;
655 /* Set libssh2 to non-blocking, since everything internally is
657 libssh2_session_set_blocking(sshc->ssh_session, 0);
659 state(conn, SSH_S_STARTUP);
663 rc = libssh2_session_startup(sshc->ssh_session, sock);
664 if(rc == LIBSSH2_ERROR_EAGAIN) {
668 failf(data, "Failure establishing ssh session");
669 state(conn, SSH_SESSION_FREE);
670 sshc->actualcode = CURLE_FAILED_INIT;
674 state(conn, SSH_HOSTKEY);
679 #ifdef CURL_LIBSSH2_DEBUG
681 * Before we authenticate we should check the hostkey's fingerprint
682 * against our known hosts. How that is handled (reading from file,
683 * whatever) is up to us. As for know not much is implemented, besides
684 * showing how to get the fingerprint.
686 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
687 LIBSSH2_HOSTKEY_HASH_MD5);
689 /* The fingerprint points to static storage (!), don't free() it. */
690 infof(data, "Fingerprint: ");
691 for(rc = 0; rc < 16; rc++)
692 infof(data, "%02X ", (unsigned char) fingerprint[rc]);
694 #endif /* CURL_LIBSSH2_DEBUG */
696 /* Before we authenticate we check the hostkey's MD5 fingerprint
697 * against a known fingerprint, if available. This implementation pulls
698 * it from the curl option.
700 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
701 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
703 host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
704 LIBSSH2_HOSTKEY_HASH_MD5);
705 for(i = 0; i < 16; i++)
706 snprintf(&buf[i*2], 3, "%02x",
707 (unsigned char) host_public_key_md5[i]);
708 if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
710 "Denied establishing ssh session: mismatch md5 fingerprint. "
711 "Remote %s is not equal to %s",
712 buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
713 state(conn, SSH_SESSION_FREE);
714 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
719 result = ssh_knownhost(conn);
721 state(conn, SSH_AUTHLIST);
726 * Figure out authentication methods
727 * NB: As soon as we have provided a username to an openssh server we
728 * must never change it later. Thus, always specify the correct username
729 * here, even though the libssh2 docs kind of indicate that it should be
730 * possible to get a 'generic' list (not user-specific) of authentication
731 * methods, presumably with a blank username. That won't work in my
733 * So always specify it here.
735 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
737 (unsigned int)strlen(conn->user));
739 if(!sshc->authlist) {
740 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
741 LIBSSH2_ERROR_EAGAIN) {
742 rc = LIBSSH2_ERROR_EAGAIN;
746 state(conn, SSH_SESSION_FREE);
747 sshc->actualcode = libssh2_session_error_to_CURLE(err);
751 infof(data, "SSH authentication methods available: %s\n",
754 state(conn, SSH_AUTH_PKEY_INIT);
757 case SSH_AUTH_PKEY_INIT:
759 * Check the supported auth types in the order I feel is most secure
760 * with the requested type of authentication
762 sshc->authed = FALSE;
764 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
765 (strstr(sshc->authlist, "publickey") != NULL)) {
768 sshc->rsa_pub = sshc->rsa = NULL;
770 /* To ponder about: should really the lib be messing about with the
771 HOME environment variable etc? */
772 home = curl_getenv("HOME");
774 if(data->set.str[STRING_SSH_PUBLIC_KEY])
775 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
777 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
779 /* as a final resort, try current dir! */
780 sshc->rsa_pub = strdup("id_dsa.pub");
782 if(sshc->rsa_pub == NULL) {
785 state(conn, SSH_SESSION_FREE);
786 sshc->actualcode = CURLE_OUT_OF_MEMORY;
790 if(data->set.str[STRING_SSH_PRIVATE_KEY])
791 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
793 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
795 /* as a final resort, try current dir! */
796 sshc->rsa = strdup("id_dsa");
798 if(sshc->rsa == NULL) {
801 Curl_safefree(sshc->rsa_pub);
802 sshc->rsa_pub = NULL;
803 state(conn, SSH_SESSION_FREE);
804 sshc->actualcode = CURLE_OUT_OF_MEMORY;
808 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
809 if(!sshc->passphrase)
810 sshc->passphrase = "";
815 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
816 infof(data, "Using ssh private key file %s\n", sshc->rsa);
818 state(conn, SSH_AUTH_PKEY);
821 state(conn, SSH_AUTH_PASS_INIT);
826 /* The function below checks if the files exists, no need to stat() here.
828 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
833 sshc->rsa, sshc->passphrase);
834 if(rc == LIBSSH2_ERROR_EAGAIN) {
838 Curl_safefree(sshc->rsa_pub);
839 sshc->rsa_pub = NULL;
840 Curl_safefree(sshc->rsa);
845 infof(data, "Initialized SSH public key authentication\n");
846 state(conn, SSH_AUTH_DONE);
850 (void)libssh2_session_last_error(sshc->ssh_session,
852 infof(data, "SSH public key authentication failed: %s\n", err_msg);
853 state(conn, SSH_AUTH_PASS_INIT);
857 case SSH_AUTH_PASS_INIT:
858 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
859 (strstr(sshc->authlist, "password") != NULL)) {
860 state(conn, SSH_AUTH_PASS);
863 state(conn, SSH_AUTH_HOST_INIT);
868 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
869 (unsigned int)strlen(conn->user),
871 (unsigned int)strlen(conn->passwd),
873 if(rc == LIBSSH2_ERROR_EAGAIN) {
878 infof(data, "Initialized password authentication\n");
879 state(conn, SSH_AUTH_DONE);
882 state(conn, SSH_AUTH_HOST_INIT);
886 case SSH_AUTH_HOST_INIT:
887 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
888 (strstr(sshc->authlist, "hostbased") != NULL)) {
889 state(conn, SSH_AUTH_HOST);
892 state(conn, SSH_AUTH_KEY_INIT);
897 state(conn, SSH_AUTH_KEY_INIT);
900 case SSH_AUTH_KEY_INIT:
901 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
902 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
903 state(conn, SSH_AUTH_KEY);
906 state(conn, SSH_AUTH_DONE);
911 /* Authentication failed. Continue with keyboard-interactive now. */
912 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
917 if(rc == LIBSSH2_ERROR_EAGAIN) {
922 infof(data, "Initialized keyboard interactive authentication\n");
924 state(conn, SSH_AUTH_DONE);
929 failf(data, "Authentication failure");
930 state(conn, SSH_SESSION_FREE);
931 sshc->actualcode = CURLE_LOGIN_DENIED;
936 * At this point we have an authenticated ssh session.
938 infof(data, "Authentication complete\n");
940 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
943 conn->writesockfd = CURL_SOCKET_BAD;
945 if(conn->handler->protocol == CURLPROTO_SFTP) {
946 state(conn, SSH_SFTP_INIT);
949 infof(data, "SSH CONNECT phase done\n");
950 state(conn, SSH_STOP);
955 * Start the libssh2 sftp session
957 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
958 if(!sshc->sftp_session) {
959 if(libssh2_session_last_errno(sshc->ssh_session) ==
960 LIBSSH2_ERROR_EAGAIN) {
961 rc = LIBSSH2_ERROR_EAGAIN;
967 (void)libssh2_session_last_error(sshc->ssh_session,
969 failf(data, "Failure initializing sftp session: %s", err_msg);
970 state(conn, SSH_SESSION_FREE);
971 sshc->actualcode = CURLE_FAILED_INIT;
975 state(conn, SSH_SFTP_REALPATH);
978 case SSH_SFTP_REALPATH:
980 char tempHome[PATH_MAX];
983 * Get the "home" directory
985 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
986 tempHome, PATH_MAX-1);
987 if(rc == LIBSSH2_ERROR_EAGAIN) {
991 /* It seems that this string is not always NULL terminated */
993 sshc->homedir = strdup(tempHome);
995 state(conn, SSH_SFTP_CLOSE);
996 sshc->actualcode = CURLE_OUT_OF_MEMORY;
999 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1002 /* Return the error type */
1003 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1004 result = sftp_libssh2_error_to_CURLE(err);
1005 sshc->actualcode = result?result:CURLE_SSH;
1006 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1008 state(conn, SSH_STOP);
1012 /* This is the last step in the SFTP connect phase. Do note that while
1013 we get the homedir here, we get the "workingpath" in the DO action
1014 since the homedir will remain the same between request but the
1015 working path will not. */
1016 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1017 state(conn, SSH_STOP);
1020 case SSH_SFTP_QUOTE_INIT:
1022 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1024 sshc->actualcode = result;
1025 state(conn, SSH_STOP);
1029 if(data->set.quote) {
1030 infof(data, "Sending quote commands\n");
1031 sshc->quote_item = data->set.quote;
1032 state(conn, SSH_SFTP_QUOTE);
1035 state(conn, SSH_SFTP_TRANS_INIT);
1039 case SSH_SFTP_POSTQUOTE_INIT:
1040 if(data->set.postquote) {
1041 infof(data, "Sending quote commands\n");
1042 sshc->quote_item = data->set.postquote;
1043 state(conn, SSH_SFTP_QUOTE);
1046 state(conn, SSH_STOP);
1050 case SSH_SFTP_QUOTE:
1051 /* Send any quote commands */
1056 * Support some of the "FTP" commands
1058 if(curl_strequal("pwd", sshc->quote_item->data)) {
1059 /* output debug output if that is requested */
1060 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1063 result = CURLE_OUT_OF_MEMORY;
1064 state(conn, SSH_SFTP_CLOSE);
1065 sshc->nextstate = SSH_NO_STATE;
1068 if(data->set.verbose) {
1069 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1070 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1072 /* this sends an FTP-like "header" to the header callback so that the
1073 current directory can be read very similar to how it is read when
1074 using ordinary FTP. */
1075 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1077 state(conn, SSH_SFTP_NEXT_QUOTE);
1080 else if(sshc->quote_item->data) {
1082 * the arguments following the command must be separated from the
1083 * command with a space so we can check for it unconditionally
1085 cp = strchr(sshc->quote_item->data, ' ');
1087 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1088 state(conn, SSH_SFTP_CLOSE);
1089 sshc->nextstate = SSH_NO_STATE;
1090 sshc->actualcode = CURLE_QUOTE_ERROR;
1095 * also, every command takes at least one argument so we get that
1096 * first argument right now
1098 result = get_pathname(&cp, &sshc->quote_path1);
1100 if(result == CURLE_OUT_OF_MEMORY)
1101 failf(data, "Out of memory");
1103 failf(data, "Syntax error: Bad first parameter");
1104 state(conn, SSH_SFTP_CLOSE);
1105 sshc->nextstate = SSH_NO_STATE;
1106 sshc->actualcode = result;
1111 * SFTP is a binary protocol, so we don't send text commands to
1112 * the server. Instead, we scan for commands for commands used by
1113 * OpenSSH's sftp program and call the appropriate libssh2
1116 if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
1117 curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
1118 curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
1119 /* attribute change */
1121 /* sshc->quote_path1 contains the mode to set */
1122 /* get the destination */
1123 result = get_pathname(&cp, &sshc->quote_path2);
1125 if(result == CURLE_OUT_OF_MEMORY)
1126 failf(data, "Out of memory");
1128 failf(data, "Syntax error in chgrp/chmod/chown: "
1129 "Bad second parameter");
1130 Curl_safefree(sshc->quote_path1);
1131 sshc->quote_path1 = NULL;
1132 state(conn, SSH_SFTP_CLOSE);
1133 sshc->nextstate = SSH_NO_STATE;
1134 sshc->actualcode = result;
1137 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1138 state(conn, SSH_SFTP_QUOTE_STAT);
1141 else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
1142 curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
1143 /* symbolic linking */
1144 /* sshc->quote_path1 is the source */
1145 /* get the destination */
1146 result = get_pathname(&cp, &sshc->quote_path2);
1148 if(result == CURLE_OUT_OF_MEMORY)
1149 failf(data, "Out of memory");
1152 "Syntax error in ln/symlink: Bad second parameter");
1153 Curl_safefree(sshc->quote_path1);
1154 sshc->quote_path1 = NULL;
1155 state(conn, SSH_SFTP_CLOSE);
1156 sshc->nextstate = SSH_NO_STATE;
1157 sshc->actualcode = result;
1160 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1163 else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
1165 state(conn, SSH_SFTP_QUOTE_MKDIR);
1168 else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
1170 /* first param is the source path */
1171 /* second param is the dest. path */
1172 result = get_pathname(&cp, &sshc->quote_path2);
1174 if(result == CURLE_OUT_OF_MEMORY)
1175 failf(data, "Out of memory");
1177 failf(data, "Syntax error in rename: Bad second parameter");
1178 Curl_safefree(sshc->quote_path1);
1179 sshc->quote_path1 = NULL;
1180 state(conn, SSH_SFTP_CLOSE);
1181 sshc->nextstate = SSH_NO_STATE;
1182 sshc->actualcode = result;
1185 state(conn, SSH_SFTP_QUOTE_RENAME);
1188 else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
1190 state(conn, SSH_SFTP_QUOTE_RMDIR);
1193 else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
1194 state(conn, SSH_SFTP_QUOTE_UNLINK);
1198 failf(data, "Unknown SFTP command");
1199 Curl_safefree(sshc->quote_path1);
1200 sshc->quote_path1 = NULL;
1201 Curl_safefree(sshc->quote_path2);
1202 sshc->quote_path2 = NULL;
1203 state(conn, SSH_SFTP_CLOSE);
1204 sshc->nextstate = SSH_NO_STATE;
1205 sshc->actualcode = CURLE_QUOTE_ERROR;
1209 if(!sshc->quote_item) {
1210 state(conn, SSH_SFTP_TRANS_INIT);
1214 case SSH_SFTP_NEXT_QUOTE:
1215 if(sshc->quote_path1) {
1216 Curl_safefree(sshc->quote_path1);
1217 sshc->quote_path1 = NULL;
1219 if(sshc->quote_path2) {
1220 Curl_safefree(sshc->quote_path2);
1221 sshc->quote_path2 = NULL;
1224 sshc->quote_item = sshc->quote_item->next;
1226 if(sshc->quote_item) {
1227 state(conn, SSH_SFTP_QUOTE);
1230 if(sshc->nextstate != SSH_NO_STATE) {
1231 state(conn, sshc->nextstate);
1232 sshc->nextstate = SSH_NO_STATE;
1235 state(conn, SSH_SFTP_TRANS_INIT);
1240 case SSH_SFTP_QUOTE_STAT:
1241 if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1242 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1243 * set them both at once, we need to obtain the current ownership
1244 * first. This takes an extra protocol round trip.
1246 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1247 (unsigned int)strlen(sshc->quote_path2),
1249 &sshc->quote_attrs);
1250 if(rc == LIBSSH2_ERROR_EAGAIN) {
1253 else if(rc != 0) { /* get those attributes */
1254 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1255 Curl_safefree(sshc->quote_path1);
1256 sshc->quote_path1 = NULL;
1257 Curl_safefree(sshc->quote_path2);
1258 sshc->quote_path2 = NULL;
1259 failf(data, "Attempt to get SFTP stats failed: %s",
1260 sftp_libssh2_strerror(err));
1261 state(conn, SSH_SFTP_CLOSE);
1262 sshc->nextstate = SSH_NO_STATE;
1263 sshc->actualcode = CURLE_QUOTE_ERROR;
1268 /* Now set the new attributes... */
1269 if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
1270 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1271 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1272 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1273 Curl_safefree(sshc->quote_path1);
1274 sshc->quote_path1 = NULL;
1275 Curl_safefree(sshc->quote_path2);
1276 sshc->quote_path2 = NULL;
1277 failf(data, "Syntax error: chgrp gid not a number");
1278 state(conn, SSH_SFTP_CLOSE);
1279 sshc->nextstate = SSH_NO_STATE;
1280 sshc->actualcode = CURLE_QUOTE_ERROR;
1284 else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1285 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1286 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1287 /* permissions are octal */
1288 if(sshc->quote_attrs.permissions == 0 &&
1289 !ISDIGIT(sshc->quote_path1[0])) {
1290 Curl_safefree(sshc->quote_path1);
1291 sshc->quote_path1 = NULL;
1292 Curl_safefree(sshc->quote_path2);
1293 sshc->quote_path2 = NULL;
1294 failf(data, "Syntax error: chmod permissions not a number");
1295 state(conn, SSH_SFTP_CLOSE);
1296 sshc->nextstate = SSH_NO_STATE;
1297 sshc->actualcode = CURLE_QUOTE_ERROR;
1301 else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
1302 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1303 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1304 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1305 Curl_safefree(sshc->quote_path1);
1306 sshc->quote_path1 = NULL;
1307 Curl_safefree(sshc->quote_path2);
1308 sshc->quote_path2 = NULL;
1309 failf(data, "Syntax error: chown uid not a number");
1310 state(conn, SSH_SFTP_CLOSE);
1311 sshc->nextstate = SSH_NO_STATE;
1312 sshc->actualcode = CURLE_QUOTE_ERROR;
1317 /* Now send the completed structure... */
1318 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1321 case SSH_SFTP_QUOTE_SETSTAT:
1322 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1323 (unsigned int)strlen(sshc->quote_path2),
1324 LIBSSH2_SFTP_SETSTAT,
1325 &sshc->quote_attrs);
1326 if(rc == LIBSSH2_ERROR_EAGAIN) {
1330 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1331 Curl_safefree(sshc->quote_path1);
1332 sshc->quote_path1 = NULL;
1333 Curl_safefree(sshc->quote_path2);
1334 sshc->quote_path2 = NULL;
1335 failf(data, "Attempt to set SFTP stats failed: %s",
1336 sftp_libssh2_strerror(err));
1337 state(conn, SSH_SFTP_CLOSE);
1338 sshc->nextstate = SSH_NO_STATE;
1339 sshc->actualcode = CURLE_QUOTE_ERROR;
1342 state(conn, SSH_SFTP_NEXT_QUOTE);
1345 case SSH_SFTP_QUOTE_SYMLINK:
1346 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1347 (unsigned int)strlen(sshc->quote_path1),
1349 (unsigned int)strlen(sshc->quote_path2),
1350 LIBSSH2_SFTP_SYMLINK);
1351 if(rc == LIBSSH2_ERROR_EAGAIN) {
1355 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1356 Curl_safefree(sshc->quote_path1);
1357 sshc->quote_path1 = NULL;
1358 Curl_safefree(sshc->quote_path2);
1359 sshc->quote_path2 = NULL;
1360 failf(data, "symlink command failed: %s",
1361 sftp_libssh2_strerror(err));
1362 state(conn, SSH_SFTP_CLOSE);
1363 sshc->nextstate = SSH_NO_STATE;
1364 sshc->actualcode = CURLE_QUOTE_ERROR;
1367 state(conn, SSH_SFTP_NEXT_QUOTE);
1370 case SSH_SFTP_QUOTE_MKDIR:
1371 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1372 (unsigned int)strlen(sshc->quote_path1),
1374 if(rc == LIBSSH2_ERROR_EAGAIN) {
1378 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1379 Curl_safefree(sshc->quote_path1);
1380 sshc->quote_path1 = NULL;
1381 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1382 state(conn, SSH_SFTP_CLOSE);
1383 sshc->nextstate = SSH_NO_STATE;
1384 sshc->actualcode = CURLE_QUOTE_ERROR;
1387 state(conn, SSH_SFTP_NEXT_QUOTE);
1390 case SSH_SFTP_QUOTE_RENAME:
1391 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1392 (unsigned int)strlen(sshc->quote_path1),
1394 (unsigned int)strlen(sshc->quote_path2),
1395 LIBSSH2_SFTP_RENAME_OVERWRITE |
1396 LIBSSH2_SFTP_RENAME_ATOMIC |
1397 LIBSSH2_SFTP_RENAME_NATIVE);
1399 if(rc == LIBSSH2_ERROR_EAGAIN) {
1403 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1404 Curl_safefree(sshc->quote_path1);
1405 sshc->quote_path1 = NULL;
1406 Curl_safefree(sshc->quote_path2);
1407 sshc->quote_path2 = NULL;
1408 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1409 state(conn, SSH_SFTP_CLOSE);
1410 sshc->nextstate = SSH_NO_STATE;
1411 sshc->actualcode = CURLE_QUOTE_ERROR;
1414 state(conn, SSH_SFTP_NEXT_QUOTE);
1417 case SSH_SFTP_QUOTE_RMDIR:
1418 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1419 (unsigned int)strlen(sshc->quote_path1));
1420 if(rc == LIBSSH2_ERROR_EAGAIN) {
1424 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1425 Curl_safefree(sshc->quote_path1);
1426 sshc->quote_path1 = NULL;
1427 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1428 state(conn, SSH_SFTP_CLOSE);
1429 sshc->nextstate = SSH_NO_STATE;
1430 sshc->actualcode = CURLE_QUOTE_ERROR;
1433 state(conn, SSH_SFTP_NEXT_QUOTE);
1436 case SSH_SFTP_QUOTE_UNLINK:
1437 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1438 (unsigned int)strlen(sshc->quote_path1));
1439 if(rc == LIBSSH2_ERROR_EAGAIN) {
1443 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1444 Curl_safefree(sshc->quote_path1);
1445 sshc->quote_path1 = NULL;
1446 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1447 state(conn, SSH_SFTP_CLOSE);
1448 sshc->nextstate = SSH_NO_STATE;
1449 sshc->actualcode = CURLE_QUOTE_ERROR;
1452 state(conn, SSH_SFTP_NEXT_QUOTE);
1455 case SSH_SFTP_TRANS_INIT:
1456 if(data->set.upload)
1457 state(conn, SSH_SFTP_UPLOAD_INIT);
1459 if(data->set.opt_no_body)
1460 state(conn, SSH_STOP);
1461 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1462 state(conn, SSH_SFTP_READDIR_INIT);
1464 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1468 case SSH_SFTP_UPLOAD_INIT:
1470 unsigned long flags;
1472 * NOTE!!! libssh2 requires that the destination path is a full path
1473 * that includes the destination file and name OR ends in a "/"
1474 * If this is not done the destination file will be named the
1475 * same name as the last directory in the path.
1478 if(data->state.resume_from != 0) {
1479 LIBSSH2_SFTP_ATTRIBUTES attrs;
1480 if(data->state.resume_from < 0) {
1481 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1482 (unsigned int)strlen(sftp_scp->path),
1483 LIBSSH2_SFTP_STAT, &attrs);
1484 if(rc == LIBSSH2_ERROR_EAGAIN) {
1488 data->state.resume_from = 0;
1491 curl_off_t size = attrs.filesize;
1493 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1494 return CURLE_BAD_DOWNLOAD_RESUME;
1496 data->state.resume_from = attrs.filesize;
1501 if(data->set.ftp_append)
1502 /* Try to open for append, but create if nonexisting */
1503 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1504 else if(data->state.resume_from > 0)
1505 /* If we have restart position then open for append */
1506 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1508 /* Clear file before writing (normal behaviour) */
1509 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1512 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1513 (unsigned int)strlen(sftp_scp->path),
1514 flags, data->set.new_file_perms,
1515 LIBSSH2_SFTP_OPENFILE);
1517 if(!sshc->sftp_handle) {
1518 rc = libssh2_session_last_errno(sshc->ssh_session);
1520 if(LIBSSH2_ERROR_EAGAIN == rc)
1523 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1524 /* only when there was an SFTP protocol error can we extract
1526 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1528 err = -1; /* not an sftp error at all */
1530 if(sshc->secondCreateDirs) {
1531 state(conn, SSH_SFTP_CLOSE);
1532 sshc->actualcode = err>= LIBSSH2_FX_OK?
1533 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1534 failf(data, "Creating the dir/file failed: %s",
1535 sftp_libssh2_strerror(err));
1538 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1539 (err == LIBSSH2_FX_FAILURE) ||
1540 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1541 (data->set.ftp_create_missing_dirs &&
1542 (strlen(sftp_scp->path) > 1))) {
1543 /* try to create the path remotely */
1544 sshc->secondCreateDirs = 1;
1545 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1548 state(conn, SSH_SFTP_CLOSE);
1549 sshc->actualcode = err>= LIBSSH2_FX_OK?
1550 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1551 if(!sshc->actualcode) {
1552 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1553 zero even though libssh2_sftp_open() failed previously! We need
1554 to work around that! */
1555 sshc->actualcode = CURLE_SSH;
1558 failf(data, "Upload failed: %s (%d/%d)",
1559 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1565 /* If we have restart point then we need to seek to the correct
1567 if(data->state.resume_from > 0) {
1568 /* Let's read off the proper amount of bytes from the input. */
1569 if(conn->seek_func) {
1570 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1574 if(seekerr != CURL_SEEKFUNC_OK) {
1576 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1577 failf(data, "Could not seek stream");
1578 return CURLE_FTP_COULDNT_USE_REST;
1580 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1582 curl_off_t passed=0;
1584 size_t readthisamountnow =
1585 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1586 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1588 size_t actuallyread =
1589 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1592 passed += actuallyread;
1593 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1594 /* this checks for greater-than only to make sure that the
1595 CURL_READFUNC_ABORT return code still aborts */
1596 failf(data, "Failed to read data");
1597 return CURLE_FTP_COULDNT_USE_REST;
1599 } while(passed < data->state.resume_from);
1603 /* now, decrease the size of the read */
1604 if(data->set.infilesize > 0) {
1605 data->set.infilesize -= data->state.resume_from;
1606 data->req.size = data->set.infilesize;
1607 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1610 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1612 if(data->set.infilesize > 0) {
1613 data->req.size = data->set.infilesize;
1614 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1617 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1619 /* not set by Curl_setup_transfer to preserve keepon bits */
1620 conn->sockfd = conn->writesockfd;
1623 state(conn, SSH_SFTP_CLOSE);
1624 sshc->actualcode = result;
1627 /* store this original bitmask setup to use later on if we can't
1628 figure out a "real" bitmask */
1629 sshc->orig_waitfor = data->req.keepon;
1631 /* we want to use the _sending_ function even when the socket turns
1632 out readable as the underlying libssh2 sftp send function will deal
1633 with both accordingly */
1634 conn->cselect_bits = CURL_CSELECT_OUT;
1636 /* since we don't really wait for anything at this point, we want the
1637 state machine to move on as soon as possible so we set a very short
1639 Curl_expire(data, 1);
1641 state(conn, SSH_STOP);
1646 case SSH_SFTP_CREATE_DIRS_INIT:
1647 if(strlen(sftp_scp->path) > 1) {
1648 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1649 state(conn, SSH_SFTP_CREATE_DIRS);
1652 state(conn, SSH_SFTP_UPLOAD_INIT);
1656 case SSH_SFTP_CREATE_DIRS:
1657 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1658 *sshc->slash_pos = 0;
1660 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1661 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1665 state(conn, SSH_SFTP_UPLOAD_INIT);
1669 case SSH_SFTP_CREATE_DIRS_MKDIR:
1670 /* 'mode' - parameter is preliminary - default to 0644 */
1671 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1672 (unsigned int)strlen(sftp_scp->path),
1673 data->set.new_directory_perms);
1674 if(rc == LIBSSH2_ERROR_EAGAIN) {
1677 *sshc->slash_pos = '/';
1680 unsigned int sftp_err = 0;
1682 * Abort if failure wasn't that the dir already exists or the
1683 * permission was denied (creation might succeed further down the
1684 * path) - retry on unspecific FAILURE also
1686 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1687 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1688 (sftp_err != LIBSSH2_FX_FAILURE) &&
1689 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1690 result = sftp_libssh2_error_to_CURLE(sftp_err);
1691 state(conn, SSH_SFTP_CLOSE);
1692 sshc->actualcode = result?result:CURLE_SSH;
1696 state(conn, SSH_SFTP_CREATE_DIRS);
1699 case SSH_SFTP_READDIR_INIT:
1701 * This is a directory that we are trying to get, so produce a directory
1704 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1707 strlen(sftp_scp->path),
1708 0, 0, LIBSSH2_SFTP_OPENDIR);
1709 if(!sshc->sftp_handle) {
1710 if(libssh2_session_last_errno(sshc->ssh_session) ==
1711 LIBSSH2_ERROR_EAGAIN) {
1712 rc = LIBSSH2_ERROR_EAGAIN;
1716 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1717 failf(data, "Could not open directory for reading: %s",
1718 sftp_libssh2_strerror(err));
1719 state(conn, SSH_SFTP_CLOSE);
1720 result = sftp_libssh2_error_to_CURLE(err);
1721 sshc->actualcode = result?result:CURLE_SSH;
1725 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1726 state(conn, SSH_SFTP_CLOSE);
1727 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1730 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1731 Curl_safefree(sshc->readdir_filename);
1732 sshc->readdir_filename = NULL;
1733 state(conn, SSH_SFTP_CLOSE);
1734 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1737 state(conn, SSH_SFTP_READDIR);
1740 case SSH_SFTP_READDIR:
1741 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1742 sshc->readdir_filename,
1744 sshc->readdir_longentry,
1746 &sshc->readdir_attrs);
1747 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1748 rc = LIBSSH2_ERROR_EAGAIN;
1751 if(sshc->readdir_len > 0) {
1752 sshc->readdir_filename[sshc->readdir_len] = '\0';
1754 if(data->set.ftp_list_only) {
1757 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1758 if(tmpLine == NULL) {
1759 state(conn, SSH_SFTP_CLOSE);
1760 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1763 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1764 tmpLine, sshc->readdir_len+1);
1765 Curl_safefree(tmpLine);
1768 state(conn, SSH_STOP);
1771 /* since this counts what we send to the client, we include the
1772 newline in this counter */
1773 data->req.bytecount += sshc->readdir_len+1;
1775 /* output debug output if that is requested */
1776 if(data->set.verbose) {
1777 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1778 sshc->readdir_len, conn);
1782 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1783 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1784 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1785 if(!sshc->readdir_line) {
1786 Curl_safefree(sshc->readdir_filename);
1787 sshc->readdir_filename = NULL;
1788 Curl_safefree(sshc->readdir_longentry);
1789 sshc->readdir_longentry = NULL;
1790 state(conn, SSH_SFTP_CLOSE);
1791 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1795 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1796 sshc->readdir_currLen);
1797 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1798 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1799 LIBSSH2_SFTP_S_IFLNK)) {
1800 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1801 if(sshc->readdir_linkPath == NULL) {
1802 Curl_safefree(sshc->readdir_filename);
1803 sshc->readdir_filename = NULL;
1804 Curl_safefree(sshc->readdir_longentry);
1805 sshc->readdir_longentry = NULL;
1806 state(conn, SSH_SFTP_CLOSE);
1807 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1811 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1812 sshc->readdir_filename);
1813 state(conn, SSH_SFTP_READDIR_LINK);
1816 state(conn, SSH_SFTP_READDIR_BOTTOM);
1820 else if(sshc->readdir_len == 0) {
1821 Curl_safefree(sshc->readdir_filename);
1822 sshc->readdir_filename = NULL;
1823 Curl_safefree(sshc->readdir_longentry);
1824 sshc->readdir_longentry = NULL;
1825 state(conn, SSH_SFTP_READDIR_DONE);
1828 else if(sshc->readdir_len <= 0) {
1829 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1830 result = sftp_libssh2_error_to_CURLE(err);
1831 sshc->actualcode = result?result:CURLE_SSH;
1832 failf(data, "Could not open remote file for reading: %s :: %d",
1833 sftp_libssh2_strerror(err),
1834 libssh2_session_last_errno(sshc->ssh_session));
1835 Curl_safefree(sshc->readdir_filename);
1836 sshc->readdir_filename = NULL;
1837 Curl_safefree(sshc->readdir_longentry);
1838 sshc->readdir_longentry = NULL;
1839 state(conn, SSH_SFTP_CLOSE);
1844 case SSH_SFTP_READDIR_LINK:
1846 libssh2_sftp_symlink_ex(sshc->sftp_session,
1847 sshc->readdir_linkPath,
1848 (unsigned int) strlen(sshc->readdir_linkPath),
1849 sshc->readdir_filename,
1850 PATH_MAX, LIBSSH2_SFTP_READLINK);
1851 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1852 rc = LIBSSH2_ERROR_EAGAIN;
1855 Curl_safefree(sshc->readdir_linkPath);
1856 sshc->readdir_linkPath = NULL;
1857 sshc->readdir_line = realloc(sshc->readdir_line,
1858 sshc->readdir_totalLen + 4 +
1860 if(!sshc->readdir_line) {
1861 Curl_safefree(sshc->readdir_filename);
1862 sshc->readdir_filename = NULL;
1863 Curl_safefree(sshc->readdir_longentry);
1864 sshc->readdir_longentry = NULL;
1865 state(conn, SSH_SFTP_CLOSE);
1866 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1870 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1871 sshc->readdir_currLen,
1872 sshc->readdir_totalLen -
1873 sshc->readdir_currLen,
1875 sshc->readdir_filename);
1877 state(conn, SSH_SFTP_READDIR_BOTTOM);
1880 case SSH_SFTP_READDIR_BOTTOM:
1881 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1882 sshc->readdir_currLen,
1883 sshc->readdir_totalLen -
1884 sshc->readdir_currLen, "\n");
1885 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1887 sshc->readdir_currLen);
1889 if(result == CURLE_OK) {
1891 /* output debug output if that is requested */
1892 if(data->set.verbose) {
1893 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1894 sshc->readdir_currLen, conn);
1896 data->req.bytecount += sshc->readdir_currLen;
1898 Curl_safefree(sshc->readdir_line);
1899 sshc->readdir_line = NULL;
1901 state(conn, SSH_STOP);
1904 state(conn, SSH_SFTP_READDIR);
1907 case SSH_SFTP_READDIR_DONE:
1908 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1909 LIBSSH2_ERROR_EAGAIN) {
1910 rc = LIBSSH2_ERROR_EAGAIN;
1913 sshc->sftp_handle = NULL;
1914 Curl_safefree(sshc->readdir_filename);
1915 sshc->readdir_filename = NULL;
1916 Curl_safefree(sshc->readdir_longentry);
1917 sshc->readdir_longentry = NULL;
1919 /* no data to transfer */
1920 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1921 state(conn, SSH_STOP);
1924 case SSH_SFTP_DOWNLOAD_INIT:
1926 * Work on getting the specified file
1929 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1930 (unsigned int)strlen(sftp_scp->path),
1931 LIBSSH2_FXF_READ, data->set.new_file_perms,
1932 LIBSSH2_SFTP_OPENFILE);
1933 if(!sshc->sftp_handle) {
1934 if(libssh2_session_last_errno(sshc->ssh_session) ==
1935 LIBSSH2_ERROR_EAGAIN) {
1936 rc = LIBSSH2_ERROR_EAGAIN;
1940 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1941 failf(data, "Could not open remote file for reading: %s",
1942 sftp_libssh2_strerror(err));
1943 state(conn, SSH_SFTP_CLOSE);
1944 result = sftp_libssh2_error_to_CURLE(err);
1945 sshc->actualcode = result?result:CURLE_SSH;
1949 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1952 case SSH_SFTP_DOWNLOAD_STAT:
1954 LIBSSH2_SFTP_ATTRIBUTES attrs;
1956 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1957 (unsigned int)strlen(sftp_scp->path),
1958 LIBSSH2_SFTP_STAT, &attrs);
1959 if(rc == LIBSSH2_ERROR_EAGAIN) {
1964 * libssh2_sftp_open() didn't return an error, so maybe the server
1965 * just doesn't support stat()
1967 data->req.size = -1;
1968 data->req.maxdownload = -1;
1971 curl_off_t size = attrs.filesize;
1974 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1975 return CURLE_BAD_DOWNLOAD_RESUME;
1977 if(conn->data->state.use_range) {
1978 curl_off_t from, to;
1982 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1983 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
1985 to=curlx_strtoofft(ptr, &ptr2, 0);
1986 if((ptr == ptr2) /* no "to" value given */
1991 /* from is relative to end of file */
1995 failf(data, "Offset (%"
1996 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1997 from, attrs.filesize);
1998 return CURLE_BAD_DOWNLOAD_RESUME;
2005 size = to - from + 1;
2008 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2010 data->req.size = size;
2011 data->req.maxdownload = size;
2012 Curl_pgrsSetDownloadSize(data, size);
2015 /* We can resume if we can seek to the resume position */
2016 if(data->state.resume_from) {
2017 if(data->state.resume_from < 0) {
2018 /* We're supposed to download the last abs(from) bytes */
2019 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2020 failf(data, "Offset (%"
2021 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2022 data->state.resume_from, attrs.filesize);
2023 return CURLE_BAD_DOWNLOAD_RESUME;
2025 /* download from where? */
2026 data->state.resume_from += attrs.filesize;
2029 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2030 failf(data, "Offset (%" FORMAT_OFF_T
2031 ") was beyond file size (%" FORMAT_OFF_T ")",
2032 data->state.resume_from, attrs.filesize);
2033 return CURLE_BAD_DOWNLOAD_RESUME;
2036 /* Does a completed file need to be seeked and started or closed ? */
2037 /* Now store the number of bytes we are expected to download */
2038 data->req.size = attrs.filesize - data->state.resume_from;
2039 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2040 Curl_pgrsSetDownloadSize(data,
2041 attrs.filesize - data->state.resume_from);
2042 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2045 /* Setup the actual download */
2046 if(data->req.size == 0) {
2047 /* no data to transfer */
2048 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2049 infof(data, "File already completely downloaded\n");
2050 state(conn, SSH_STOP);
2054 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2055 FALSE, NULL, -1, NULL);
2057 /* not set by Curl_setup_transfer to preserve keepon bits */
2058 conn->writesockfd = conn->sockfd;
2060 /* we want to use the _receiving_ function even when the socket turns
2061 out writableable as the underlying libssh2 recv function will deal
2062 with both accordingly */
2063 conn->cselect_bits = CURL_CSELECT_IN;
2066 state(conn, SSH_SFTP_CLOSE);
2067 sshc->actualcode = result;
2070 state(conn, SSH_STOP);
2074 case SSH_SFTP_CLOSE:
2075 if(sshc->sftp_handle) {
2076 rc = libssh2_sftp_close(sshc->sftp_handle);
2077 if(rc == LIBSSH2_ERROR_EAGAIN) {
2081 infof(data, "Failed to close libssh2 file\n");
2083 sshc->sftp_handle = NULL;
2086 Curl_safefree(sftp_scp->path);
2087 sftp_scp->path = NULL;
2090 DEBUGF(infof(data, "SFTP DONE done\n"));
2092 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2093 After nextstate is executed,the control should come back to
2094 SSH_SFTP_CLOSE to pass the correct result back */
2095 if(sshc->nextstate != SSH_NO_STATE) {
2096 state(conn, sshc->nextstate);
2097 sshc->nextstate = SSH_SFTP_CLOSE;
2100 state(conn, SSH_STOP);
2101 result = sshc->actualcode;
2105 case SSH_SFTP_SHUTDOWN:
2106 /* during times we get here due to a broken transfer and then the
2107 sftp_handle might not have been taken down so make sure that is done
2108 before we proceed */
2110 if(sshc->sftp_handle) {
2111 rc = libssh2_sftp_close(sshc->sftp_handle);
2112 if(rc == LIBSSH2_ERROR_EAGAIN) {
2116 infof(data, "Failed to close libssh2 file\n");
2118 sshc->sftp_handle = NULL;
2120 if(sshc->sftp_session) {
2121 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2122 if(rc == LIBSSH2_ERROR_EAGAIN) {
2126 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2128 sshc->sftp_session = NULL;
2131 Curl_safefree(sshc->homedir);
2132 sshc->homedir = NULL;
2133 conn->data->state.most_recent_ftp_entrypath = NULL;
2135 state(conn, SSH_SESSION_DISCONNECT);
2138 case SSH_SCP_TRANS_INIT:
2139 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2141 sshc->actualcode = result;
2142 state(conn, SSH_STOP);
2146 if(data->set.upload) {
2147 if(data->set.infilesize < 0) {
2148 failf(data, "SCP requires a known file size for upload");
2149 sshc->actualcode = CURLE_UPLOAD_FAILED;
2150 state(conn, SSH_SCP_CHANNEL_FREE);
2153 state(conn, SSH_SCP_UPLOAD_INIT);
2156 state(conn, SSH_SCP_DOWNLOAD_INIT);
2160 case SSH_SCP_UPLOAD_INIT:
2162 * libssh2 requires that the destination path is a full path that
2163 * includes the destination file and name OR ends in a "/" . If this is
2164 * not done the destination file will be named the same name as the last
2165 * directory in the path.
2168 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2169 data->set.infilesize);
2170 if(!sshc->ssh_channel) {
2171 if(libssh2_session_last_errno(sshc->ssh_session) ==
2172 LIBSSH2_ERROR_EAGAIN) {
2173 rc = LIBSSH2_ERROR_EAGAIN;
2180 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2181 &err_msg, NULL, 0));
2182 failf(conn->data, "%s", err_msg);
2183 state(conn, SSH_SCP_CHANNEL_FREE);
2184 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2190 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2193 /* not set by Curl_setup_transfer to preserve keepon bits */
2194 conn->sockfd = conn->writesockfd;
2197 state(conn, SSH_SCP_CHANNEL_FREE);
2198 sshc->actualcode = result;
2201 /* we want to use the _sending_ function even when the socket turns
2202 out readable as the underlying libssh2 scp send function will deal
2203 with both accordingly */
2204 conn->cselect_bits = CURL_CSELECT_OUT;
2206 state(conn, SSH_STOP);
2210 case SSH_SCP_DOWNLOAD_INIT:
2213 * We must check the remote file; if it is a directory no values will
2217 curl_off_t bytecount;
2219 /* clear the struct scp recv will fill in */
2220 memset(&sb, 0, sizeof(struct stat));
2222 /* get a fresh new channel from the ssh layer */
2223 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2224 sftp_scp->path, &sb);
2225 if(!sshc->ssh_channel) {
2226 if(libssh2_session_last_errno(sshc->ssh_session) ==
2227 LIBSSH2_ERROR_EAGAIN) {
2228 rc = LIBSSH2_ERROR_EAGAIN;
2235 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2236 &err_msg, NULL, 0));
2237 failf(conn->data, "%s", err_msg);
2238 state(conn, SSH_SCP_CHANNEL_FREE);
2239 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2245 bytecount = (curl_off_t)sb.st_size;
2246 data->req.maxdownload = (curl_off_t)sb.st_size;
2247 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2249 /* not set by Curl_setup_transfer to preserve keepon bits */
2250 conn->writesockfd = conn->sockfd;
2252 /* we want to use the _receiving_ function even when the socket turns
2253 out writableable as the underlying libssh2 recv function will deal
2254 with both accordingly */
2255 conn->cselect_bits = CURL_CSELECT_IN;
2258 state(conn, SSH_SCP_CHANNEL_FREE);
2259 sshc->actualcode = result;
2262 state(conn, SSH_STOP);
2267 if(data->set.upload)
2268 state(conn, SSH_SCP_SEND_EOF);
2270 state(conn, SSH_SCP_CHANNEL_FREE);
2273 case SSH_SCP_SEND_EOF:
2274 if(sshc->ssh_channel) {
2275 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2276 if(rc == LIBSSH2_ERROR_EAGAIN) {
2280 infof(data, "Failed to send libssh2 channel EOF\n");
2283 state(conn, SSH_SCP_WAIT_EOF);
2286 case SSH_SCP_WAIT_EOF:
2287 if(sshc->ssh_channel) {
2288 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2289 if(rc == LIBSSH2_ERROR_EAGAIN) {
2293 infof(data, "Failed to get channel EOF: %d\n", rc);
2296 state(conn, SSH_SCP_WAIT_CLOSE);
2299 case SSH_SCP_WAIT_CLOSE:
2300 if(sshc->ssh_channel) {
2301 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2302 if(rc == LIBSSH2_ERROR_EAGAIN) {
2306 infof(data, "Channel failed to close: %d\n", rc);
2309 state(conn, SSH_SCP_CHANNEL_FREE);
2312 case SSH_SCP_CHANNEL_FREE:
2313 if(sshc->ssh_channel) {
2314 rc = libssh2_channel_free(sshc->ssh_channel);
2315 if(rc == LIBSSH2_ERROR_EAGAIN) {
2319 infof(data, "Failed to free libssh2 scp subsystem\n");
2321 sshc->ssh_channel = NULL;
2323 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2325 state(conn, SSH_SESSION_DISCONNECT);
2327 state(conn, SSH_STOP);
2328 result = sshc->actualcode;
2331 case SSH_SESSION_DISCONNECT:
2332 /* during weird times when we've been prematurely aborted, the channel
2333 is still alive when we reach this state and we MUST kill the channel
2335 if(sshc->ssh_channel) {
2336 rc = libssh2_channel_free(sshc->ssh_channel);
2337 if(rc == LIBSSH2_ERROR_EAGAIN) {
2341 infof(data, "Failed to free libssh2 scp subsystem\n");
2343 sshc->ssh_channel = NULL;
2346 if(sshc->ssh_session) {
2347 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2348 if(rc == LIBSSH2_ERROR_EAGAIN) {
2352 infof(data, "Failed to disconnect libssh2 session\n");
2356 Curl_safefree(sshc->homedir);
2357 sshc->homedir = NULL;
2358 conn->data->state.most_recent_ftp_entrypath = NULL;
2360 state(conn, SSH_SESSION_FREE);
2363 case SSH_SESSION_FREE:
2364 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2366 libssh2_knownhost_free(sshc->kh);
2371 if(sshc->ssh_session) {
2372 rc = libssh2_session_free(sshc->ssh_session);
2373 if(rc == LIBSSH2_ERROR_EAGAIN) {
2377 infof(data, "Failed to free libssh2 session\n");
2379 sshc->ssh_session = NULL;
2381 conn->bits.close = TRUE;
2382 sshc->nextstate = SSH_NO_STATE;
2383 state(conn, SSH_STOP);
2384 result = sshc->actualcode;
2388 /* fallthrough, just stop! */
2390 /* internal error */
2391 sshc->nextstate = SSH_NO_STATE;
2392 state(conn, SSH_STOP);
2396 } while(!rc && (sshc->state != SSH_STOP));
2398 if(rc == LIBSSH2_ERROR_EAGAIN) {
2399 /* we would block, we need to wait for the socket to be ready (in the
2400 right direction too)! */
2407 /* called by the multi interface to figure out what socket(s) to wait for and
2408 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2409 static int ssh_perform_getsock(const struct connectdata *conn,
2410 curl_socket_t *sock, /* points to numsocks
2411 number of sockets */
2414 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2415 int bitmap = GETSOCK_BLANK;
2418 sock[0] = conn->sock[FIRSTSOCKET];
2420 if(conn->waitfor & KEEP_RECV)
2421 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2423 if(conn->waitfor & KEEP_SEND)
2424 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2428 /* if we don't know the direction we can use the generic *_getsock()
2429 function even for the protocol_connect and doing states */
2430 return Curl_single_getsock(conn, sock, numsocks);
2434 /* Generic function called by the multi interface to figure out what socket(s)
2435 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2436 static int ssh_getsock(struct connectdata *conn,
2437 curl_socket_t *sock, /* points to numsocks number
2441 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2445 /* if we don't know any direction we can just play along as we used to and
2446 not provide any sensible info */
2447 return GETSOCK_BLANK;
2449 /* if we know the direction we can use the generic *_getsock() function even
2450 for the protocol_connect and doing states */
2451 return ssh_perform_getsock(conn, sock, numsocks);
2455 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2457 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2458 * function is used to figure out in what direction and stores this info so
2459 * that the multi interface can take advantage of it. Make sure to call this
2460 * function in all cases so that when it _doesn't_ return EAGAIN we can
2461 * restore the default wait bits.
2463 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2465 struct ssh_conn *sshc = &conn->proto.sshc;
2469 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2470 /* translate the libssh2 define bits into our own bit defines */
2471 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2472 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2475 /* It didn't block or libssh2 didn't reveal in which direction, put back
2477 conn->waitfor = sshc->orig_waitfor;
2480 /* no libssh2 directional support so we simply don't know */
2481 #define ssh_block2waitfor(x,y)
2484 /* called repeatedly until done from multi.c */
2485 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2487 struct ssh_conn *sshc = &conn->proto.sshc;
2488 CURLcode result = CURLE_OK;
2489 bool block; /* we store the status and use that to provide a ssh_getsock()
2492 result = ssh_statemach_act(conn, &block);
2493 *done = (bool)(sshc->state == SSH_STOP);
2494 ssh_block2waitfor(conn, block);
2499 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2502 struct ssh_conn *sshc = &conn->proto.sshc;
2503 CURLcode result = CURLE_OK;
2504 struct SessionHandle *data = conn->data;
2506 while((sshc->state != SSH_STOP) && !result) {
2510 result = ssh_statemach_act(conn, &block);
2514 if(Curl_pgrsUpdate(conn))
2515 return CURLE_ABORTED_BY_CALLBACK;
2517 struct timeval now = Curl_tvnow();
2518 result = Curl_speedcheck(data, now);
2523 left = Curl_timeleft(data, NULL, duringconnect);
2525 failf(data, "Operation timed out\n");
2526 return CURLE_OPERATION_TIMEDOUT;
2529 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2530 if((CURLE_OK == result) && block) {
2531 int dir = libssh2_session_block_directions(sshc->ssh_session);
2532 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2533 curl_socket_t fd_read = CURL_SOCKET_BAD;
2534 curl_socket_t fd_write = CURL_SOCKET_BAD;
2535 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2537 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2539 /* wait for the socket to become ready */
2540 Curl_socket_ready(fd_read, fd_write,
2541 left>1000?1000:left); /* ignore result */
2551 * SSH setup and connection
2553 static CURLcode ssh_init(struct connectdata *conn)
2555 struct SessionHandle *data = conn->data;
2556 struct SSHPROTO *ssh;
2557 struct ssh_conn *sshc = &conn->proto.sshc;
2559 sshc->actualcode = CURLE_OK; /* reset error code */
2560 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2563 if(data->state.proto.ssh)
2566 ssh = calloc(1, sizeof(struct SSHPROTO));
2568 return CURLE_OUT_OF_MEMORY;
2570 data->state.proto.ssh = ssh;
2575 static Curl_recv scp_recv, sftp_recv;
2576 static Curl_send scp_send, sftp_send;
2579 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2580 * do protocol-specific actions at connect-time.
2582 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2584 #ifdef CURL_LIBSSH2_DEBUG
2587 struct ssh_conn *ssh;
2589 struct SessionHandle *data = conn->data;
2591 /* We default to persistent connections. We set this already in this connect
2592 function to make the re-use checks properly be able to check this bit. */
2593 conn->bits.close = FALSE;
2595 /* If there already is a protocol-specific struct allocated for this
2596 sessionhandle, deal with it */
2597 Curl_reset_reqproto(conn);
2599 result = ssh_init(conn);
2603 if(conn->handler->protocol & CURLPROTO_SCP) {
2604 conn->recv[FIRSTSOCKET] = scp_recv;
2605 conn->send[FIRSTSOCKET] = scp_send;
2608 conn->recv[FIRSTSOCKET] = sftp_recv;
2609 conn->send[FIRSTSOCKET] = sftp_send;
2611 ssh = &conn->proto.sshc;
2613 #ifdef CURL_LIBSSH2_DEBUG
2615 infof(data, "User: %s\n", conn->user);
2618 infof(data, "Password: %s\n", conn->passwd);
2620 sock = conn->sock[FIRSTSOCKET];
2621 #endif /* CURL_LIBSSH2_DEBUG */
2623 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2625 my_libssh2_realloc, conn);
2626 if(ssh->ssh_session == NULL) {
2627 failf(data, "Failure initialising ssh session");
2628 return CURLE_FAILED_INIT;
2631 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2632 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2634 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2636 /* eeek. TODO: free the ssh_session! */
2637 return CURLE_FAILED_INIT;
2640 /* read all known hosts from there */
2641 rc = libssh2_knownhost_readfile(ssh->kh,
2642 data->set.str[STRING_SSH_KNOWNHOSTS],
2643 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2645 infof(data, "Failed to read known hosts from %s\n",
2646 data->set.str[STRING_SSH_KNOWNHOSTS]);
2648 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2650 #ifdef CURL_LIBSSH2_DEBUG
2651 libssh2_trace(ssh->ssh_session, ~0);
2652 infof(data, "SSH socket: %d\n", (int)sock);
2653 #endif /* CURL_LIBSSH2_DEBUG */
2655 state(conn, SSH_INIT);
2657 if(data->state.used_interface == Curl_if_multi)
2658 result = ssh_multi_statemach(conn, done);
2660 result = ssh_easy_statemach(conn, TRUE);
2669 ***********************************************************************
2673 * This is the actual DO function for SCP. Get a file according to
2674 * the options previously setup.
2678 CURLcode scp_perform(struct connectdata *conn,
2682 CURLcode result = CURLE_OK;
2684 DEBUGF(infof(conn->data, "DO phase starts\n"));
2686 *dophase_done = FALSE; /* not done yet */
2688 /* start the first command in the DO phase */
2689 state(conn, SSH_SCP_TRANS_INIT);
2691 /* run the state-machine */
2692 if(conn->data->state.used_interface == Curl_if_multi) {
2693 result = ssh_multi_statemach(conn, dophase_done);
2696 result = ssh_easy_statemach(conn, FALSE);
2697 *dophase_done = TRUE; /* with the easy interface we are done here */
2699 *connected = conn->bits.tcpconnect;
2702 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2708 /* called from multi.c while DOing */
2709 static CURLcode scp_doing(struct connectdata *conn,
2713 result = ssh_multi_statemach(conn, dophase_done);
2716 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2722 * The DO function is generic for both protocols. There was previously two
2723 * separate ones but this way means less duplicated code.
2726 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2730 struct SessionHandle *data = conn->data;
2732 *done = FALSE; /* default to false */
2735 Since connections can be re-used between SessionHandles, this might be a
2736 connection already existing but on a fresh SessionHandle struct so we must
2737 make sure we have a good 'struct SSHPROTO' to play with. For new
2738 connections, the struct SSHPROTO is allocated and setup in the
2739 ssh_connect() function.
2741 Curl_reset_reqproto(conn);
2742 res = ssh_init(conn);
2746 data->req.size = -1; /* make sure this is unknown at this point */
2748 Curl_pgrsSetUploadCounter(data, 0);
2749 Curl_pgrsSetDownloadCounter(data, 0);
2750 Curl_pgrsSetUploadSize(data, 0);
2751 Curl_pgrsSetDownloadSize(data, 0);
2753 if(conn->handler->protocol & CURLPROTO_SCP)
2754 res = scp_perform(conn, &connected, done);
2756 res = sftp_perform(conn, &connected, done);
2761 /* BLOCKING, but the function is using the state machine so the only reason
2762 this is still blocking is that the multi interface code has no support for
2763 disconnecting operations that takes a while */
2764 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2766 CURLcode result = CURLE_OK;
2767 struct ssh_conn *ssh = &conn->proto.sshc;
2768 (void) dead_connection;
2770 Curl_safefree(conn->data->state.proto.ssh);
2771 conn->data->state.proto.ssh = NULL;
2773 if(ssh->ssh_session) {
2774 /* only if there's a session still around to use! */
2776 state(conn, SSH_SESSION_DISCONNECT);
2778 result = ssh_easy_statemach(conn, FALSE);
2784 /* generic done function for both SCP and SFTP called from their specific
2786 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2788 CURLcode result = CURLE_OK;
2789 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2791 if(status == CURLE_OK) {
2792 /* run the state-machine
2794 TODO: when the multi interface is used, this _really_ should be using
2795 the ssh_multi_statemach function but we have no general support for
2796 non-blocking DONE operations, not in the multi state machine and with
2797 Curl_done() invokes on several places in the code!
2799 result = ssh_easy_statemach(conn, FALSE);
2805 Curl_safefree(sftp_scp->path);
2806 sftp_scp->path = NULL;
2808 Curl_pgrsDone(conn);
2810 conn->data->req.keepon = 0; /* clear all bits */
2815 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2818 (void)premature; /* not used */
2820 if(status == CURLE_OK)
2821 state(conn, SSH_SCP_DONE);
2823 return ssh_done(conn, status);
2827 /* return number of received (decrypted) bytes */
2828 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2829 const void *mem, size_t len, CURLcode *err)
2832 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2834 /* libssh2_channel_write() returns int! */
2836 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2838 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2840 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2849 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2850 * a regular CURLcode value.
2852 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2853 char *mem, size_t len, CURLcode *err)
2856 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2858 /* libssh2_channel_read() returns int */
2860 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2862 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2863 if(nread == LIBSSH2_ERROR_EAGAIN) {
2872 * =============== SFTP ===============
2876 ***********************************************************************
2880 * This is the actual DO function for SFTP. Get a file/directory according to
2881 * the options previously setup.
2885 CURLcode sftp_perform(struct connectdata *conn,
2889 CURLcode result = CURLE_OK;
2891 DEBUGF(infof(conn->data, "DO phase starts\n"));
2893 *dophase_done = FALSE; /* not done yet */
2895 /* start the first command in the DO phase */
2896 state(conn, SSH_SFTP_QUOTE_INIT);
2898 /* run the state-machine */
2899 if(conn->data->state.used_interface == Curl_if_multi) {
2900 result = ssh_multi_statemach(conn, dophase_done);
2903 result = ssh_easy_statemach(conn, FALSE);
2904 *dophase_done = TRUE; /* with the easy interface we are done here */
2906 *connected = conn->bits.tcpconnect;
2909 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2915 /* called from multi.c while DOing */
2916 static CURLcode sftp_doing(struct connectdata *conn,
2920 result = ssh_multi_statemach(conn, dophase_done);
2923 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2928 /* BLOCKING, but the function is using the state machine so the only reason
2929 this is still blocking is that the multi interface code has no support for
2930 disconnecting operations that takes a while */
2931 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
2933 CURLcode result = CURLE_OK;
2934 (void) dead_connection;
2936 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2938 Curl_safefree(conn->data->state.proto.ssh);
2939 conn->data->state.proto.ssh = NULL;
2941 if(conn->proto.sshc.ssh_session) {
2942 /* only if there's a session still around to use! */
2943 state(conn, SSH_SFTP_SHUTDOWN);
2944 result = ssh_easy_statemach(conn, FALSE);
2947 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2953 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2956 struct ssh_conn *sshc = &conn->proto.sshc;
2958 if(status == CURLE_OK) {
2959 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
2960 errors that could happen due to open file handles during POSTQUOTE
2962 if(!status && !premature && conn->data->set.postquote) {
2963 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
2964 state(conn, SSH_SFTP_CLOSE);
2967 state(conn, SSH_SFTP_CLOSE);
2969 return ssh_done(conn, status);
2972 /* return number of sent bytes */
2973 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
2974 const void *mem, size_t len, CURLcode *err)
2976 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2977 but is changed to ssize_t in 0.15. These days we don't
2978 support libssh2 0.15*/
2981 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2983 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2985 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2994 * Return number of received (decrypted) bytes
2996 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
2997 char *mem, size_t len, CURLcode *err)
3002 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3004 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3006 if(nread == LIBSSH2_ERROR_EAGAIN) {
3013 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3016 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3018 * Permission to use, copy, modify, and distribute this software for any
3019 * purpose with or without fee is hereby granted, provided that the above
3020 * copyright notice and this permission notice appear in all copies.
3022 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3023 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3024 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3025 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3026 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3027 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3028 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3031 get_pathname(const char **cpp, char **path)
3033 const char *cp = *cpp, *end;
3036 static const char WHITESPACE[] = " \t\r\n";
3038 cp += strspn(cp, WHITESPACE);
3042 return CURLE_QUOTE_ERROR;
3045 *path = malloc(strlen(cp) + 1);
3047 return CURLE_OUT_OF_MEMORY;
3049 /* Check for quoted filenames */
3050 if(*cp == '\"' || *cp == '\'') {
3053 /* Search for terminating quote, unescape some chars */
3054 for(i = j = 0; i <= strlen(cp); i++) {
3055 if(cp[i] == quot) { /* Found quote */
3060 if(cp[i] == '\0') { /* End of string */
3061 /*error("Unterminated quote");*/
3064 if(cp[i] == '\\') { /* Escaped characters */
3066 if(cp[i] != '\'' && cp[i] != '\"' &&
3068 /*error("Bad escaped character '\\%c'",
3073 (*path)[j++] = cp[i];
3077 /*error("Empty quotes");*/
3080 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3083 /* Read to end of filename */
3084 end = strpbrk(cp, WHITESPACE);
3086 end = strchr(cp, '\0');
3087 *cpp = end + strspn(end, WHITESPACE);
3089 memcpy(*path, cp, end - cp);
3090 (*path)[end - cp] = '\0';
3095 Curl_safefree(*path);
3097 return CURLE_QUOTE_ERROR;
3101 static const char *sftp_libssh2_strerror(unsigned long err)
3104 case LIBSSH2_FX_NO_SUCH_FILE:
3105 return "No such file or directory";
3107 case LIBSSH2_FX_PERMISSION_DENIED:
3108 return "Permission denied";
3110 case LIBSSH2_FX_FAILURE:
3111 return "Operation failed";
3113 case LIBSSH2_FX_BAD_MESSAGE:
3114 return "Bad message from SFTP server";
3116 case LIBSSH2_FX_NO_CONNECTION:
3117 return "Not connected to SFTP server";
3119 case LIBSSH2_FX_CONNECTION_LOST:
3120 return "Connection to SFTP server lost";
3122 case LIBSSH2_FX_OP_UNSUPPORTED:
3123 return "Operation not supported by SFTP server";
3125 case LIBSSH2_FX_INVALID_HANDLE:
3126 return "Invalid handle";
3128 case LIBSSH2_FX_NO_SUCH_PATH:
3129 return "No such file or directory";
3131 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3132 return "File already exists";
3134 case LIBSSH2_FX_WRITE_PROTECT:
3135 return "File is write protected";
3137 case LIBSSH2_FX_NO_MEDIA:
3140 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3143 case LIBSSH2_FX_QUOTA_EXCEEDED:
3144 return "User quota exceeded";
3146 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3147 return "Unknown principle";
3149 case LIBSSH2_FX_LOCK_CONFlICT:
3150 return "File lock conflict";
3152 case LIBSSH2_FX_DIR_NOT_EMPTY:
3153 return "Directory not empty";
3155 case LIBSSH2_FX_NOT_A_DIRECTORY:
3156 return "Not a directory";
3158 case LIBSSH2_FX_INVALID_FILENAME:
3159 return "Invalid filename";
3161 case LIBSSH2_FX_LINK_LOOP:
3162 return "Link points to itself";
3164 return "Unknown error in libssh2";
3167 #endif /* USE_LIBSSH2 */