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);
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 ZERO_NULL, /* readwrite */
176 PORT_SSH, /* defport */
177 CURLPROTO_SCP, /* protocol */
178 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
183 * SFTP protocol handler.
186 const struct Curl_handler Curl_handler_sftp = {
188 ZERO_NULL, /* setup_connection */
190 sftp_done, /* done */
191 ZERO_NULL, /* do_more */
192 ssh_connect, /* connect_it */
193 ssh_multi_statemach, /* connecting */
194 sftp_doing, /* doing */
195 ssh_getsock, /* proto_getsock */
196 ssh_getsock, /* doing_getsock */
197 ssh_perform_getsock, /* perform_getsock */
198 sftp_disconnect, /* disconnect */
199 ZERO_NULL, /* readwrite */
200 PORT_SSH, /* defport */
201 CURLPROTO_SFTP, /* protocol */
202 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
207 kbd_callback(const char *name, int name_len, const char *instruction,
208 int instruction_len, int num_prompts,
209 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
210 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
213 struct connectdata *conn = (struct connectdata *)*abstract;
215 #ifdef CURL_LIBSSH2_DEBUG
216 fprintf(stderr, "name=%s\n", name);
217 fprintf(stderr, "name_len=%d\n", name_len);
218 fprintf(stderr, "instruction=%s\n", instruction);
219 fprintf(stderr, "instruction_len=%d\n", instruction_len);
220 fprintf(stderr, "num_prompts=%d\n", num_prompts);
225 (void)instruction_len;
226 #endif /* CURL_LIBSSH2_DEBUG */
227 if(num_prompts == 1) {
228 responses[0].text = strdup(conn->passwd);
229 responses[0].length = (unsigned int)strlen(conn->passwd);
235 static CURLcode sftp_libssh2_error_to_CURLE(int err)
241 case LIBSSH2_FX_NO_SUCH_FILE:
242 case LIBSSH2_FX_NO_SUCH_PATH:
243 return CURLE_REMOTE_FILE_NOT_FOUND;
245 case LIBSSH2_FX_PERMISSION_DENIED:
246 case LIBSSH2_FX_WRITE_PROTECT:
247 case LIBSSH2_FX_LOCK_CONFlICT:
248 return CURLE_REMOTE_ACCESS_DENIED;
250 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
251 case LIBSSH2_FX_QUOTA_EXCEEDED:
252 return CURLE_REMOTE_DISK_FULL;
254 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
255 return CURLE_REMOTE_FILE_EXISTS;
257 case LIBSSH2_FX_DIR_NOT_EMPTY:
258 return CURLE_QUOTE_ERROR;
267 static CURLcode libssh2_session_error_to_CURLE(int err)
270 /* Ordered by order of appearance in libssh2.h */
271 case LIBSSH2_ERROR_NONE:
274 case LIBSSH2_ERROR_SOCKET_NONE:
275 return CURLE_COULDNT_CONNECT;
277 case LIBSSH2_ERROR_ALLOC:
278 return CURLE_OUT_OF_MEMORY;
280 case LIBSSH2_ERROR_SOCKET_SEND:
281 return CURLE_SEND_ERROR;
283 case LIBSSH2_ERROR_HOSTKEY_INIT:
284 case LIBSSH2_ERROR_HOSTKEY_SIGN:
285 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
286 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
287 return CURLE_PEER_FAILED_VERIFICATION;
289 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
290 return CURLE_LOGIN_DENIED;
292 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
293 case LIBSSH2_ERROR_TIMEOUT:
294 return CURLE_OPERATION_TIMEDOUT;
296 case LIBSSH2_ERROR_EAGAIN:
300 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
301 error code, and possibly add a few new SSH-related one. We must however
302 not return or even depend on libssh2 errors in the public libcurl API */
307 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
309 (void)abstract; /* arg not used */
310 return malloc(count);
313 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
315 (void)abstract; /* arg not used */
316 return realloc(ptr, count);
319 static LIBSSH2_FREE_FUNC(my_libssh2_free)
321 (void)abstract; /* arg not used */
326 * SSH State machine related code
328 /* This is the ONLY way to change SSH state! */
329 static void state(struct connectdata *conn, sshstate nowstate)
331 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
332 /* for debug purposes */
333 static const char * const names[] = {
339 "SSH_AUTH_PKEY_INIT",
341 "SSH_AUTH_PASS_INIT",
343 "SSH_AUTH_HOST_INIT",
350 "SSH_SFTP_QUOTE_INIT",
351 "SSH_SFTP_POSTQUOTE_INIT",
353 "SSH_SFTP_NEXT_QUOTE",
354 "SSH_SFTP_QUOTE_STAT",
355 "SSH_SFTP_QUOTE_SETSTAT",
356 "SSH_SFTP_QUOTE_SYMLINK",
357 "SSH_SFTP_QUOTE_MKDIR",
358 "SSH_SFTP_QUOTE_RENAME",
359 "SSH_SFTP_QUOTE_RMDIR",
360 "SSH_SFTP_QUOTE_UNLINK",
361 "SSH_SFTP_TRANS_INIT",
362 "SSH_SFTP_UPLOAD_INIT",
363 "SSH_SFTP_CREATE_DIRS_INIT",
364 "SSH_SFTP_CREATE_DIRS",
365 "SSH_SFTP_CREATE_DIRS_MKDIR",
366 "SSH_SFTP_READDIR_INIT",
368 "SSH_SFTP_READDIR_LINK",
369 "SSH_SFTP_READDIR_BOTTOM",
370 "SSH_SFTP_READDIR_DONE",
371 "SSH_SFTP_DOWNLOAD_INIT",
372 "SSH_SFTP_DOWNLOAD_STAT",
375 "SSH_SCP_TRANS_INIT",
376 "SSH_SCP_UPLOAD_INIT",
377 "SSH_SCP_DOWNLOAD_INIT",
381 "SSH_SCP_WAIT_CLOSE",
382 "SSH_SCP_CHANNEL_FREE",
383 "SSH_SESSION_DISCONNECT",
388 struct ssh_conn *sshc = &conn->proto.sshc;
390 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
391 if(sshc->state != nowstate) {
392 infof(conn->data, "SFTP %p state change from %s to %s\n",
393 sshc, names[sshc->state], names[nowstate]);
397 sshc->state = nowstate;
400 /* figure out the path to work with in this particular request */
401 static CURLcode ssh_getworkingpath(struct connectdata *conn,
402 char *homedir, /* when SFTP is used */
403 char **path) /* returns the allocated
404 real path to work with */
406 struct SessionHandle *data = conn->data;
407 char *real_path = NULL;
409 int working_path_len;
411 working_path = curl_easy_unescape(data, data->state.path, 0,
414 return CURLE_OUT_OF_MEMORY;
416 /* Check for /~/ , indicating relative to the user's home directory */
417 if(conn->handler->protocol & CURLPROTO_SCP) {
418 real_path = malloc(working_path_len+1);
419 if(real_path == NULL) {
421 return CURLE_OUT_OF_MEMORY;
423 if((working_path_len > 1) && (working_path[1] == '~'))
424 /* It is referenced to the home directory, so strip the leading '/' */
425 memcpy(real_path, working_path+1, 1 + working_path_len-1);
427 memcpy(real_path, working_path, 1 + working_path_len);
429 else if(conn->handler->protocol & CURLPROTO_SFTP) {
430 if((working_path_len > 1) && (working_path[1] == '~')) {
431 size_t homelen = strlen(homedir);
432 real_path = malloc(homelen + working_path_len + 1);
433 if(real_path == NULL) {
435 return CURLE_OUT_OF_MEMORY;
437 /* It is referenced to the home directory, so strip the
439 memcpy(real_path, homedir, homelen);
440 real_path[homelen] = '/';
441 real_path[homelen+1] = '\0';
442 if(working_path_len > 3) {
443 memcpy(real_path+homelen+1, working_path + 3,
444 1 + working_path_len -3);
448 real_path = malloc(working_path_len+1);
449 if(real_path == NULL) {
451 return CURLE_OUT_OF_MEMORY;
453 memcpy(real_path, working_path, 1+working_path_len);
459 /* store the pointer for the caller to receive */
465 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
466 static int sshkeycallback(CURL *easy,
467 const struct curl_khkey *knownkey, /* known */
468 const struct curl_khkey *foundkey, /* found */
469 enum curl_khmatch match,
477 /* we only allow perfect matches, and we reject everything else */
478 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
483 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
486 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
487 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
489 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
493 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
494 * architectures so we check of the necessary function is present.
496 #ifndef HAVE_LIBSSH2_SCP_SEND64
497 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
499 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
500 (libssh2_uint64_t)d, 0, 0)
504 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
506 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
507 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
510 static CURLcode ssh_knownhost(struct connectdata *conn)
512 struct SessionHandle *data = conn->data;
513 CURLcode result = CURLE_OK;
515 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
516 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
517 /* we're asked to verify the host against a file */
518 struct ssh_conn *sshc = &conn->proto.sshc;
522 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
529 * A subject to figure out is what host name we need to pass in here.
530 * What host name does OpenSSH store in its file if an IDN name is
533 struct libssh2_knownhost *host;
534 enum curl_khmatch keymatch;
535 curl_sshkeycallback func =
536 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
537 struct curl_khkey knownkey;
538 struct curl_khkey *knownkeyp = NULL;
539 struct curl_khkey foundkey;
541 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
542 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
544 keycheck = libssh2_knownhost_check(sshc->kh,
547 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
548 LIBSSH2_KNOWNHOST_KEYENC_RAW|
552 infof(data, "SSH host check: %d, key: %s\n", keycheck,
553 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
556 /* setup 'knownkey' */
557 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
558 knownkey.key = host->key;
560 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
561 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
562 knownkeyp = &knownkey;
565 /* setup 'foundkey' */
566 foundkey.key = remotekey;
567 foundkey.len = keylen;
568 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
569 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
572 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
573 * curl_khmatch enum are ever modified, we need to introduce a
574 * translation table here!
576 keymatch = (enum curl_khmatch)keycheck;
578 /* Ask the callback how to behave */
579 rc = func(data, knownkeyp, /* from the knownhosts file */
580 &foundkey, /* from the remote host */
581 keymatch, data->set.ssh_keyfunc_userp);
584 /* no remotekey means failure! */
585 rc = CURLKHSTAT_REJECT;
588 default: /* unknown return codes will equal reject */
589 case CURLKHSTAT_REJECT:
590 state(conn, SSH_SESSION_FREE);
591 case CURLKHSTAT_DEFER:
592 /* DEFER means bail out but keep the SSH_HOSTKEY state */
593 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
595 case CURLKHSTAT_FINE:
596 case CURLKHSTAT_FINE_ADD_TO_FILE:
598 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
599 /* the found host+key didn't match but has been told to be fine
600 anyway so we add it in memory */
601 int addrc = libssh2_knownhost_add(sshc->kh,
602 conn->host.name, NULL,
604 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
605 LIBSSH2_KNOWNHOST_KEYENC_RAW|
608 infof(data, "Warning adding the known host %s failed!\n",
610 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
611 /* now we write the entire in-memory list of known hosts to the
614 libssh2_knownhost_writefile(sshc->kh,
615 data->set.str[STRING_SSH_KNOWNHOSTS],
616 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
618 infof(data, "Warning, writing %s failed!\n",
619 data->set.str[STRING_SSH_KNOWNHOSTS]);
626 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
634 * ssh_statemach_act() runs the SSH state machine as far as it can without
635 * blocking and without reaching the end. The data the pointer 'block' points
636 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
637 * meaning it wants to be called again when the socket is ready
640 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
642 CURLcode result = CURLE_OK;
643 struct SessionHandle *data = conn->data;
644 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
645 struct ssh_conn *sshc = &conn->proto.sshc;
646 curl_socket_t sock = conn->sock[FIRSTSOCKET];
647 #ifdef CURL_LIBSSH2_DEBUG
648 const char *fingerprint;
649 #endif /* CURL_LIBSSH2_DEBUG */
650 const char *host_public_key_md5;
651 int rc = LIBSSH2_ERROR_NONE, i;
653 int seekerr = CURL_SEEKFUNC_OK;
654 *block = 0; /* we're not blocking by default */
658 switch(sshc->state) {
660 sshc->secondCreateDirs = 0;
661 sshc->nextstate = SSH_NO_STATE;
662 sshc->actualcode = CURLE_OK;
664 /* Set libssh2 to non-blocking, since everything internally is
666 libssh2_session_set_blocking(sshc->ssh_session, 0);
668 state(conn, SSH_S_STARTUP);
672 rc = libssh2_session_startup(sshc->ssh_session, sock);
673 if(rc == LIBSSH2_ERROR_EAGAIN) {
677 failf(data, "Failure establishing ssh session");
678 state(conn, SSH_SESSION_FREE);
679 sshc->actualcode = CURLE_FAILED_INIT;
683 state(conn, SSH_HOSTKEY);
688 #ifdef CURL_LIBSSH2_DEBUG
690 * Before we authenticate we should check the hostkey's fingerprint
691 * against our known hosts. How that is handled (reading from file,
692 * whatever) is up to us. As for know not much is implemented, besides
693 * showing how to get the fingerprint.
695 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
696 LIBSSH2_HOSTKEY_HASH_MD5);
698 /* The fingerprint points to static storage (!), don't free() it. */
699 infof(data, "Fingerprint: ");
700 for(rc = 0; rc < 16; rc++)
701 infof(data, "%02X ", (unsigned char) fingerprint[rc]);
703 #endif /* CURL_LIBSSH2_DEBUG */
705 /* Before we authenticate we check the hostkey's MD5 fingerprint
706 * against a known fingerprint, if available. This implementation pulls
707 * it from the curl option.
709 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
710 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
712 host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
713 LIBSSH2_HOSTKEY_HASH_MD5);
714 for(i = 0; i < 16; i++)
715 snprintf(&buf[i*2], 3, "%02x",
716 (unsigned char) host_public_key_md5[i]);
717 if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
719 "Denied establishing ssh session: mismatch md5 fingerprint. "
720 "Remote %s is not equal to %s",
721 buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
722 state(conn, SSH_SESSION_FREE);
723 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
728 result = ssh_knownhost(conn);
730 state(conn, SSH_AUTHLIST);
735 * Figure out authentication methods
736 * NB: As soon as we have provided a username to an openssh server we
737 * must never change it later. Thus, always specify the correct username
738 * here, even though the libssh2 docs kind of indicate that it should be
739 * possible to get a 'generic' list (not user-specific) of authentication
740 * methods, presumably with a blank username. That won't work in my
742 * So always specify it here.
744 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
746 (unsigned int)strlen(conn->user));
748 if(!sshc->authlist) {
749 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
750 LIBSSH2_ERROR_EAGAIN) {
751 rc = LIBSSH2_ERROR_EAGAIN;
755 state(conn, SSH_SESSION_FREE);
756 sshc->actualcode = libssh2_session_error_to_CURLE(err);
760 infof(data, "SSH authentication methods available: %s\n",
763 state(conn, SSH_AUTH_PKEY_INIT);
766 case SSH_AUTH_PKEY_INIT:
768 * Check the supported auth types in the order I feel is most secure
769 * with the requested type of authentication
771 sshc->authed = FALSE;
773 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
774 (strstr(sshc->authlist, "publickey") != NULL)) {
777 sshc->rsa_pub = sshc->rsa = NULL;
779 /* To ponder about: should really the lib be messing about with the
780 HOME environment variable etc? */
781 home = curl_getenv("HOME");
783 if(data->set.str[STRING_SSH_PUBLIC_KEY])
784 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
786 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
788 /* as a final resort, try current dir! */
789 sshc->rsa_pub = strdup("id_dsa.pub");
791 if(sshc->rsa_pub == NULL) {
794 state(conn, SSH_SESSION_FREE);
795 sshc->actualcode = CURLE_OUT_OF_MEMORY;
799 if(data->set.str[STRING_SSH_PRIVATE_KEY])
800 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
802 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
804 /* as a final resort, try current dir! */
805 sshc->rsa = strdup("id_dsa");
807 if(sshc->rsa == NULL) {
810 Curl_safefree(sshc->rsa_pub);
811 sshc->rsa_pub = NULL;
812 state(conn, SSH_SESSION_FREE);
813 sshc->actualcode = CURLE_OUT_OF_MEMORY;
817 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
818 if(!sshc->passphrase)
819 sshc->passphrase = "";
824 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
825 infof(data, "Using ssh private key file %s\n", sshc->rsa);
827 state(conn, SSH_AUTH_PKEY);
830 state(conn, SSH_AUTH_PASS_INIT);
835 /* The function below checks if the files exists, no need to stat() here.
837 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
842 sshc->rsa, sshc->passphrase);
843 if(rc == LIBSSH2_ERROR_EAGAIN) {
847 Curl_safefree(sshc->rsa_pub);
848 sshc->rsa_pub = NULL;
849 Curl_safefree(sshc->rsa);
854 infof(data, "Initialized SSH public key authentication\n");
855 state(conn, SSH_AUTH_DONE);
859 (void)libssh2_session_last_error(sshc->ssh_session,
861 infof(data, "SSH public key authentication failed: %s\n", err_msg);
862 state(conn, SSH_AUTH_PASS_INIT);
866 case SSH_AUTH_PASS_INIT:
867 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
868 (strstr(sshc->authlist, "password") != NULL)) {
869 state(conn, SSH_AUTH_PASS);
872 state(conn, SSH_AUTH_HOST_INIT);
877 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
878 (unsigned int)strlen(conn->user),
880 (unsigned int)strlen(conn->passwd),
882 if(rc == LIBSSH2_ERROR_EAGAIN) {
887 infof(data, "Initialized password authentication\n");
888 state(conn, SSH_AUTH_DONE);
891 state(conn, SSH_AUTH_HOST_INIT);
895 case SSH_AUTH_HOST_INIT:
896 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
897 (strstr(sshc->authlist, "hostbased") != NULL)) {
898 state(conn, SSH_AUTH_HOST);
901 state(conn, SSH_AUTH_KEY_INIT);
906 state(conn, SSH_AUTH_KEY_INIT);
909 case SSH_AUTH_KEY_INIT:
910 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
911 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
912 state(conn, SSH_AUTH_KEY);
915 state(conn, SSH_AUTH_DONE);
920 /* Authentication failed. Continue with keyboard-interactive now. */
921 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
926 if(rc == LIBSSH2_ERROR_EAGAIN) {
931 infof(data, "Initialized keyboard interactive authentication\n");
933 state(conn, SSH_AUTH_DONE);
938 failf(data, "Authentication failure");
939 state(conn, SSH_SESSION_FREE);
940 sshc->actualcode = CURLE_LOGIN_DENIED;
945 * At this point we have an authenticated ssh session.
947 infof(data, "Authentication complete\n");
949 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
952 conn->writesockfd = CURL_SOCKET_BAD;
954 if(conn->handler->protocol == CURLPROTO_SFTP) {
955 state(conn, SSH_SFTP_INIT);
958 infof(data, "SSH CONNECT phase done\n");
959 state(conn, SSH_STOP);
964 * Start the libssh2 sftp session
966 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
967 if(!sshc->sftp_session) {
968 if(libssh2_session_last_errno(sshc->ssh_session) ==
969 LIBSSH2_ERROR_EAGAIN) {
970 rc = LIBSSH2_ERROR_EAGAIN;
976 (void)libssh2_session_last_error(sshc->ssh_session,
978 failf(data, "Failure initializing sftp session: %s", err_msg);
979 state(conn, SSH_SESSION_FREE);
980 sshc->actualcode = CURLE_FAILED_INIT;
984 state(conn, SSH_SFTP_REALPATH);
987 case SSH_SFTP_REALPATH:
989 char tempHome[PATH_MAX];
992 * Get the "home" directory
994 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
995 tempHome, PATH_MAX-1);
996 if(rc == LIBSSH2_ERROR_EAGAIN) {
1000 /* It seems that this string is not always NULL terminated */
1001 tempHome[rc] = '\0';
1002 sshc->homedir = strdup(tempHome);
1003 if(!sshc->homedir) {
1004 state(conn, SSH_SFTP_CLOSE);
1005 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1008 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1011 /* Return the error type */
1012 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1013 result = sftp_libssh2_error_to_CURLE(err);
1014 sshc->actualcode = result?result:CURLE_SSH;
1015 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1017 state(conn, SSH_STOP);
1021 /* This is the last step in the SFTP connect phase. Do note that while
1022 we get the homedir here, we get the "workingpath" in the DO action
1023 since the homedir will remain the same between request but the
1024 working path will not. */
1025 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1026 state(conn, SSH_STOP);
1029 case SSH_SFTP_QUOTE_INIT:
1031 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1033 sshc->actualcode = result;
1034 state(conn, SSH_STOP);
1038 if(data->set.quote) {
1039 infof(data, "Sending quote commands\n");
1040 sshc->quote_item = data->set.quote;
1041 state(conn, SSH_SFTP_QUOTE);
1044 state(conn, SSH_SFTP_TRANS_INIT);
1048 case SSH_SFTP_POSTQUOTE_INIT:
1049 if(data->set.postquote) {
1050 infof(data, "Sending quote commands\n");
1051 sshc->quote_item = data->set.postquote;
1052 state(conn, SSH_SFTP_QUOTE);
1055 state(conn, SSH_STOP);
1059 case SSH_SFTP_QUOTE:
1060 /* Send any quote commands */
1065 * Support some of the "FTP" commands
1067 if(curl_strequal("pwd", sshc->quote_item->data)) {
1068 /* output debug output if that is requested */
1069 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1072 result = CURLE_OUT_OF_MEMORY;
1073 state(conn, SSH_SFTP_CLOSE);
1074 sshc->nextstate = SSH_NO_STATE;
1077 if(data->set.verbose) {
1078 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1079 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1081 /* this sends an FTP-like "header" to the header callback so that the
1082 current directory can be read very similar to how it is read when
1083 using ordinary FTP. */
1084 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1086 state(conn, SSH_SFTP_NEXT_QUOTE);
1089 else if(sshc->quote_item->data) {
1091 * the arguments following the command must be separated from the
1092 * command with a space so we can check for it unconditionally
1094 cp = strchr(sshc->quote_item->data, ' ');
1096 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1097 state(conn, SSH_SFTP_CLOSE);
1098 sshc->nextstate = SSH_NO_STATE;
1099 sshc->actualcode = CURLE_QUOTE_ERROR;
1104 * also, every command takes at least one argument so we get that
1105 * first argument right now
1107 result = get_pathname(&cp, &sshc->quote_path1);
1109 if(result == CURLE_OUT_OF_MEMORY)
1110 failf(data, "Out of memory");
1112 failf(data, "Syntax error: Bad first parameter");
1113 state(conn, SSH_SFTP_CLOSE);
1114 sshc->nextstate = SSH_NO_STATE;
1115 sshc->actualcode = result;
1120 * SFTP is a binary protocol, so we don't send text commands to
1121 * the server. Instead, we scan for commands for commands used by
1122 * OpenSSH's sftp program and call the appropriate libssh2
1125 if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
1126 curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
1127 curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
1128 /* attribute change */
1130 /* sshc->quote_path1 contains the mode to set */
1131 /* get the destination */
1132 result = get_pathname(&cp, &sshc->quote_path2);
1134 if(result == CURLE_OUT_OF_MEMORY)
1135 failf(data, "Out of memory");
1137 failf(data, "Syntax error in chgrp/chmod/chown: "
1138 "Bad second parameter");
1139 Curl_safefree(sshc->quote_path1);
1140 sshc->quote_path1 = NULL;
1141 state(conn, SSH_SFTP_CLOSE);
1142 sshc->nextstate = SSH_NO_STATE;
1143 sshc->actualcode = result;
1146 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1147 state(conn, SSH_SFTP_QUOTE_STAT);
1150 else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
1151 curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
1152 /* symbolic linking */
1153 /* sshc->quote_path1 is the source */
1154 /* get the destination */
1155 result = get_pathname(&cp, &sshc->quote_path2);
1157 if(result == CURLE_OUT_OF_MEMORY)
1158 failf(data, "Out of memory");
1161 "Syntax error in ln/symlink: Bad second parameter");
1162 Curl_safefree(sshc->quote_path1);
1163 sshc->quote_path1 = NULL;
1164 state(conn, SSH_SFTP_CLOSE);
1165 sshc->nextstate = SSH_NO_STATE;
1166 sshc->actualcode = result;
1169 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1172 else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
1174 state(conn, SSH_SFTP_QUOTE_MKDIR);
1177 else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
1179 /* first param is the source path */
1180 /* second param is the dest. path */
1181 result = get_pathname(&cp, &sshc->quote_path2);
1183 if(result == CURLE_OUT_OF_MEMORY)
1184 failf(data, "Out of memory");
1186 failf(data, "Syntax error in rename: Bad second parameter");
1187 Curl_safefree(sshc->quote_path1);
1188 sshc->quote_path1 = NULL;
1189 state(conn, SSH_SFTP_CLOSE);
1190 sshc->nextstate = SSH_NO_STATE;
1191 sshc->actualcode = result;
1194 state(conn, SSH_SFTP_QUOTE_RENAME);
1197 else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
1199 state(conn, SSH_SFTP_QUOTE_RMDIR);
1202 else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
1203 state(conn, SSH_SFTP_QUOTE_UNLINK);
1207 failf(data, "Unknown SFTP command");
1208 Curl_safefree(sshc->quote_path1);
1209 sshc->quote_path1 = NULL;
1210 Curl_safefree(sshc->quote_path2);
1211 sshc->quote_path2 = NULL;
1212 state(conn, SSH_SFTP_CLOSE);
1213 sshc->nextstate = SSH_NO_STATE;
1214 sshc->actualcode = CURLE_QUOTE_ERROR;
1218 if(!sshc->quote_item) {
1219 state(conn, SSH_SFTP_TRANS_INIT);
1223 case SSH_SFTP_NEXT_QUOTE:
1224 if(sshc->quote_path1) {
1225 Curl_safefree(sshc->quote_path1);
1226 sshc->quote_path1 = NULL;
1228 if(sshc->quote_path2) {
1229 Curl_safefree(sshc->quote_path2);
1230 sshc->quote_path2 = NULL;
1233 sshc->quote_item = sshc->quote_item->next;
1235 if(sshc->quote_item) {
1236 state(conn, SSH_SFTP_QUOTE);
1239 if(sshc->nextstate != SSH_NO_STATE) {
1240 state(conn, sshc->nextstate);
1241 sshc->nextstate = SSH_NO_STATE;
1244 state(conn, SSH_SFTP_TRANS_INIT);
1249 case SSH_SFTP_QUOTE_STAT:
1250 if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1251 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1252 * set them both at once, we need to obtain the current ownership
1253 * first. This takes an extra protocol round trip.
1255 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1256 (unsigned int)strlen(sshc->quote_path2),
1258 &sshc->quote_attrs);
1259 if(rc == LIBSSH2_ERROR_EAGAIN) {
1262 else if(rc != 0) { /* get those attributes */
1263 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1264 Curl_safefree(sshc->quote_path1);
1265 sshc->quote_path1 = NULL;
1266 Curl_safefree(sshc->quote_path2);
1267 sshc->quote_path2 = NULL;
1268 failf(data, "Attempt to get SFTP stats failed: %s",
1269 sftp_libssh2_strerror(err));
1270 state(conn, SSH_SFTP_CLOSE);
1271 sshc->nextstate = SSH_NO_STATE;
1272 sshc->actualcode = CURLE_QUOTE_ERROR;
1277 /* Now set the new attributes... */
1278 if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
1279 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1280 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1281 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1282 Curl_safefree(sshc->quote_path1);
1283 sshc->quote_path1 = NULL;
1284 Curl_safefree(sshc->quote_path2);
1285 sshc->quote_path2 = NULL;
1286 failf(data, "Syntax error: chgrp gid not a number");
1287 state(conn, SSH_SFTP_CLOSE);
1288 sshc->nextstate = SSH_NO_STATE;
1289 sshc->actualcode = CURLE_QUOTE_ERROR;
1293 else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1294 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1295 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1296 /* permissions are octal */
1297 if(sshc->quote_attrs.permissions == 0 &&
1298 !ISDIGIT(sshc->quote_path1[0])) {
1299 Curl_safefree(sshc->quote_path1);
1300 sshc->quote_path1 = NULL;
1301 Curl_safefree(sshc->quote_path2);
1302 sshc->quote_path2 = NULL;
1303 failf(data, "Syntax error: chmod permissions not a number");
1304 state(conn, SSH_SFTP_CLOSE);
1305 sshc->nextstate = SSH_NO_STATE;
1306 sshc->actualcode = CURLE_QUOTE_ERROR;
1310 else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
1311 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1312 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1313 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1314 Curl_safefree(sshc->quote_path1);
1315 sshc->quote_path1 = NULL;
1316 Curl_safefree(sshc->quote_path2);
1317 sshc->quote_path2 = NULL;
1318 failf(data, "Syntax error: chown uid not a number");
1319 state(conn, SSH_SFTP_CLOSE);
1320 sshc->nextstate = SSH_NO_STATE;
1321 sshc->actualcode = CURLE_QUOTE_ERROR;
1326 /* Now send the completed structure... */
1327 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1330 case SSH_SFTP_QUOTE_SETSTAT:
1331 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1332 (unsigned int)strlen(sshc->quote_path2),
1333 LIBSSH2_SFTP_SETSTAT,
1334 &sshc->quote_attrs);
1335 if(rc == LIBSSH2_ERROR_EAGAIN) {
1339 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1340 Curl_safefree(sshc->quote_path1);
1341 sshc->quote_path1 = NULL;
1342 Curl_safefree(sshc->quote_path2);
1343 sshc->quote_path2 = NULL;
1344 failf(data, "Attempt to set SFTP stats failed: %s",
1345 sftp_libssh2_strerror(err));
1346 state(conn, SSH_SFTP_CLOSE);
1347 sshc->nextstate = SSH_NO_STATE;
1348 sshc->actualcode = CURLE_QUOTE_ERROR;
1351 state(conn, SSH_SFTP_NEXT_QUOTE);
1354 case SSH_SFTP_QUOTE_SYMLINK:
1355 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1356 (unsigned int)strlen(sshc->quote_path1),
1358 (unsigned int)strlen(sshc->quote_path2),
1359 LIBSSH2_SFTP_SYMLINK);
1360 if(rc == LIBSSH2_ERROR_EAGAIN) {
1364 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1365 Curl_safefree(sshc->quote_path1);
1366 sshc->quote_path1 = NULL;
1367 Curl_safefree(sshc->quote_path2);
1368 sshc->quote_path2 = NULL;
1369 failf(data, "symlink command failed: %s",
1370 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_MKDIR:
1380 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1381 (unsigned int)strlen(sshc->quote_path1),
1383 if(rc == LIBSSH2_ERROR_EAGAIN) {
1387 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1388 Curl_safefree(sshc->quote_path1);
1389 sshc->quote_path1 = NULL;
1390 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1391 state(conn, SSH_SFTP_CLOSE);
1392 sshc->nextstate = SSH_NO_STATE;
1393 sshc->actualcode = CURLE_QUOTE_ERROR;
1396 state(conn, SSH_SFTP_NEXT_QUOTE);
1399 case SSH_SFTP_QUOTE_RENAME:
1400 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1401 (unsigned int)strlen(sshc->quote_path1),
1403 (unsigned int)strlen(sshc->quote_path2),
1404 LIBSSH2_SFTP_RENAME_OVERWRITE |
1405 LIBSSH2_SFTP_RENAME_ATOMIC |
1406 LIBSSH2_SFTP_RENAME_NATIVE);
1408 if(rc == LIBSSH2_ERROR_EAGAIN) {
1412 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1413 Curl_safefree(sshc->quote_path1);
1414 sshc->quote_path1 = NULL;
1415 Curl_safefree(sshc->quote_path2);
1416 sshc->quote_path2 = NULL;
1417 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1418 state(conn, SSH_SFTP_CLOSE);
1419 sshc->nextstate = SSH_NO_STATE;
1420 sshc->actualcode = CURLE_QUOTE_ERROR;
1423 state(conn, SSH_SFTP_NEXT_QUOTE);
1426 case SSH_SFTP_QUOTE_RMDIR:
1427 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1428 (unsigned int)strlen(sshc->quote_path1));
1429 if(rc == LIBSSH2_ERROR_EAGAIN) {
1433 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1434 Curl_safefree(sshc->quote_path1);
1435 sshc->quote_path1 = NULL;
1436 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1437 state(conn, SSH_SFTP_CLOSE);
1438 sshc->nextstate = SSH_NO_STATE;
1439 sshc->actualcode = CURLE_QUOTE_ERROR;
1442 state(conn, SSH_SFTP_NEXT_QUOTE);
1445 case SSH_SFTP_QUOTE_UNLINK:
1446 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1447 (unsigned int)strlen(sshc->quote_path1));
1448 if(rc == LIBSSH2_ERROR_EAGAIN) {
1452 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1453 Curl_safefree(sshc->quote_path1);
1454 sshc->quote_path1 = NULL;
1455 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1456 state(conn, SSH_SFTP_CLOSE);
1457 sshc->nextstate = SSH_NO_STATE;
1458 sshc->actualcode = CURLE_QUOTE_ERROR;
1461 state(conn, SSH_SFTP_NEXT_QUOTE);
1464 case SSH_SFTP_TRANS_INIT:
1465 if(data->set.upload)
1466 state(conn, SSH_SFTP_UPLOAD_INIT);
1468 if(data->set.opt_no_body)
1469 state(conn, SSH_STOP);
1470 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1471 state(conn, SSH_SFTP_READDIR_INIT);
1473 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1477 case SSH_SFTP_UPLOAD_INIT:
1479 unsigned long flags;
1481 * NOTE!!! libssh2 requires that the destination path is a full path
1482 * that includes the destination file and name OR ends in a "/"
1483 * If this is not done the destination file will be named the
1484 * same name as the last directory in the path.
1487 if(data->state.resume_from != 0) {
1488 LIBSSH2_SFTP_ATTRIBUTES attrs;
1489 if(data->state.resume_from < 0) {
1490 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1491 (unsigned int)strlen(sftp_scp->path),
1492 LIBSSH2_SFTP_STAT, &attrs);
1493 if(rc == LIBSSH2_ERROR_EAGAIN) {
1497 data->state.resume_from = 0;
1500 curl_off_t size = attrs.filesize;
1502 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1503 return CURLE_BAD_DOWNLOAD_RESUME;
1505 data->state.resume_from = attrs.filesize;
1510 if(data->set.ftp_append)
1511 /* Try to open for append, but create if nonexisting */
1512 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1513 else if(data->state.resume_from > 0)
1514 /* If we have restart position then open for append */
1515 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1517 /* Clear file before writing (normal behaviour) */
1518 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1521 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1522 (unsigned int)strlen(sftp_scp->path),
1523 flags, data->set.new_file_perms,
1524 LIBSSH2_SFTP_OPENFILE);
1526 if(!sshc->sftp_handle) {
1527 rc = libssh2_session_last_errno(sshc->ssh_session);
1529 if(LIBSSH2_ERROR_EAGAIN == rc)
1532 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1533 /* only when there was an SFTP protocol error can we extract
1535 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1537 err = -1; /* not an sftp error at all */
1539 if(sshc->secondCreateDirs) {
1540 state(conn, SSH_SFTP_CLOSE);
1541 sshc->actualcode = err>= LIBSSH2_FX_OK?
1542 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1543 failf(data, "Creating the dir/file failed: %s",
1544 sftp_libssh2_strerror(err));
1547 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1548 (err == LIBSSH2_FX_FAILURE) ||
1549 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1550 (data->set.ftp_create_missing_dirs &&
1551 (strlen(sftp_scp->path) > 1))) {
1552 /* try to create the path remotely */
1553 sshc->secondCreateDirs = 1;
1554 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1557 state(conn, SSH_SFTP_CLOSE);
1558 sshc->actualcode = err>= LIBSSH2_FX_OK?
1559 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1560 if(!sshc->actualcode) {
1561 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1562 zero even though libssh2_sftp_open() failed previously! We need
1563 to work around that! */
1564 sshc->actualcode = CURLE_SSH;
1567 failf(data, "Upload failed: %s (%d/%d)",
1568 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1574 /* If we have restart point then we need to seek to the correct
1576 if(data->state.resume_from > 0) {
1577 /* Let's read off the proper amount of bytes from the input. */
1578 if(conn->seek_func) {
1579 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1583 if(seekerr != CURL_SEEKFUNC_OK){
1585 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1586 failf(data, "Could not seek stream");
1587 return CURLE_FTP_COULDNT_USE_REST;
1589 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1591 curl_off_t passed=0;
1593 size_t readthisamountnow =
1594 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1595 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1597 size_t actuallyread =
1598 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1601 passed += actuallyread;
1602 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1603 /* this checks for greater-than only to make sure that the
1604 CURL_READFUNC_ABORT return code still aborts */
1605 failf(data, "Failed to read data");
1606 return CURLE_FTP_COULDNT_USE_REST;
1608 } while(passed < data->state.resume_from);
1612 /* now, decrease the size of the read */
1613 if(data->set.infilesize > 0) {
1614 data->set.infilesize -= data->state.resume_from;
1615 data->req.size = data->set.infilesize;
1616 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1619 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1621 if(data->set.infilesize > 0) {
1622 data->req.size = data->set.infilesize;
1623 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1626 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1628 /* not set by Curl_setup_transfer to preserve keepon bits */
1629 conn->sockfd = conn->writesockfd;
1632 state(conn, SSH_SFTP_CLOSE);
1633 sshc->actualcode = result;
1636 /* store this original bitmask setup to use later on if we can't
1637 figure out a "real" bitmask */
1638 sshc->orig_waitfor = data->req.keepon;
1640 /* we want to use the _sending_ function even when the socket turns
1641 out readable as the underlying libssh2 sftp send function will deal
1642 with both accordingly */
1643 conn->cselect_bits = CURL_CSELECT_OUT;
1645 /* since we don't really wait for anything at this point, we want the
1646 state machine to move on as soon as possible so we set a very short
1648 Curl_expire(data, 1);
1650 state(conn, SSH_STOP);
1655 case SSH_SFTP_CREATE_DIRS_INIT:
1656 if(strlen(sftp_scp->path) > 1) {
1657 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1658 state(conn, SSH_SFTP_CREATE_DIRS);
1661 state(conn, SSH_SFTP_UPLOAD_INIT);
1665 case SSH_SFTP_CREATE_DIRS:
1666 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1667 *sshc->slash_pos = 0;
1669 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1670 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1674 state(conn, SSH_SFTP_UPLOAD_INIT);
1678 case SSH_SFTP_CREATE_DIRS_MKDIR:
1679 /* 'mode' - parameter is preliminary - default to 0644 */
1680 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1681 (unsigned int)strlen(sftp_scp->path),
1682 data->set.new_directory_perms);
1683 if(rc == LIBSSH2_ERROR_EAGAIN) {
1686 *sshc->slash_pos = '/';
1689 unsigned int sftp_err = 0;
1691 * Abort if failure wasn't that the dir already exists or the
1692 * permission was denied (creation might succeed further down the
1693 * path) - retry on unspecific FAILURE also
1695 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1696 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1697 (sftp_err != LIBSSH2_FX_FAILURE) &&
1698 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1699 result = sftp_libssh2_error_to_CURLE(sftp_err);
1700 state(conn, SSH_SFTP_CLOSE);
1701 sshc->actualcode = result?result:CURLE_SSH;
1705 state(conn, SSH_SFTP_CREATE_DIRS);
1708 case SSH_SFTP_READDIR_INIT:
1710 * This is a directory that we are trying to get, so produce a directory
1713 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1716 strlen(sftp_scp->path),
1717 0, 0, LIBSSH2_SFTP_OPENDIR);
1718 if(!sshc->sftp_handle) {
1719 if(libssh2_session_last_errno(sshc->ssh_session) ==
1720 LIBSSH2_ERROR_EAGAIN) {
1721 rc = LIBSSH2_ERROR_EAGAIN;
1725 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1726 failf(data, "Could not open directory for reading: %s",
1727 sftp_libssh2_strerror(err));
1728 state(conn, SSH_SFTP_CLOSE);
1729 result = sftp_libssh2_error_to_CURLE(err);
1730 sshc->actualcode = result?result:CURLE_SSH;
1734 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1735 state(conn, SSH_SFTP_CLOSE);
1736 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1739 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1740 Curl_safefree(sshc->readdir_filename);
1741 sshc->readdir_filename = NULL;
1742 state(conn, SSH_SFTP_CLOSE);
1743 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1746 state(conn, SSH_SFTP_READDIR);
1749 case SSH_SFTP_READDIR:
1750 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1751 sshc->readdir_filename,
1753 sshc->readdir_longentry,
1755 &sshc->readdir_attrs);
1756 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1757 rc = LIBSSH2_ERROR_EAGAIN;
1760 if(sshc->readdir_len > 0) {
1761 sshc->readdir_filename[sshc->readdir_len] = '\0';
1763 if(data->set.ftp_list_only) {
1766 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1767 if(tmpLine == NULL) {
1768 state(conn, SSH_SFTP_CLOSE);
1769 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1772 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1773 tmpLine, sshc->readdir_len+1);
1774 Curl_safefree(tmpLine);
1777 state(conn, SSH_STOP);
1780 /* since this counts what we send to the client, we include the
1781 newline in this counter */
1782 data->req.bytecount += sshc->readdir_len+1;
1784 /* output debug output if that is requested */
1785 if(data->set.verbose) {
1786 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1787 sshc->readdir_len, conn);
1791 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1792 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1793 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1794 if(!sshc->readdir_line) {
1795 Curl_safefree(sshc->readdir_filename);
1796 sshc->readdir_filename = NULL;
1797 Curl_safefree(sshc->readdir_longentry);
1798 sshc->readdir_longentry = NULL;
1799 state(conn, SSH_SFTP_CLOSE);
1800 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1804 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1805 sshc->readdir_currLen);
1806 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1807 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1808 LIBSSH2_SFTP_S_IFLNK)) {
1809 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1810 if(sshc->readdir_linkPath == NULL) {
1811 Curl_safefree(sshc->readdir_filename);
1812 sshc->readdir_filename = NULL;
1813 Curl_safefree(sshc->readdir_longentry);
1814 sshc->readdir_longentry = NULL;
1815 state(conn, SSH_SFTP_CLOSE);
1816 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1820 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1821 sshc->readdir_filename);
1822 state(conn, SSH_SFTP_READDIR_LINK);
1825 state(conn, SSH_SFTP_READDIR_BOTTOM);
1829 else if(sshc->readdir_len == 0) {
1830 Curl_safefree(sshc->readdir_filename);
1831 sshc->readdir_filename = NULL;
1832 Curl_safefree(sshc->readdir_longentry);
1833 sshc->readdir_longentry = NULL;
1834 state(conn, SSH_SFTP_READDIR_DONE);
1837 else if(sshc->readdir_len <= 0) {
1838 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1839 result = sftp_libssh2_error_to_CURLE(err);
1840 sshc->actualcode = result?result:CURLE_SSH;
1841 failf(data, "Could not open remote file for reading: %s :: %d",
1842 sftp_libssh2_strerror(err),
1843 libssh2_session_last_errno(sshc->ssh_session));
1844 Curl_safefree(sshc->readdir_filename);
1845 sshc->readdir_filename = NULL;
1846 Curl_safefree(sshc->readdir_longentry);
1847 sshc->readdir_longentry = NULL;
1848 state(conn, SSH_SFTP_CLOSE);
1853 case SSH_SFTP_READDIR_LINK:
1855 libssh2_sftp_symlink_ex(sshc->sftp_session,
1856 sshc->readdir_linkPath,
1857 (unsigned int) strlen(sshc->readdir_linkPath),
1858 sshc->readdir_filename,
1859 PATH_MAX, LIBSSH2_SFTP_READLINK);
1860 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1861 rc = LIBSSH2_ERROR_EAGAIN;
1864 Curl_safefree(sshc->readdir_linkPath);
1865 sshc->readdir_linkPath = NULL;
1866 sshc->readdir_line = realloc(sshc->readdir_line,
1867 sshc->readdir_totalLen + 4 +
1869 if(!sshc->readdir_line) {
1870 Curl_safefree(sshc->readdir_filename);
1871 sshc->readdir_filename = NULL;
1872 Curl_safefree(sshc->readdir_longentry);
1873 sshc->readdir_longentry = NULL;
1874 state(conn, SSH_SFTP_CLOSE);
1875 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1879 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1880 sshc->readdir_currLen,
1881 sshc->readdir_totalLen -
1882 sshc->readdir_currLen,
1884 sshc->readdir_filename);
1886 state(conn, SSH_SFTP_READDIR_BOTTOM);
1889 case SSH_SFTP_READDIR_BOTTOM:
1890 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1891 sshc->readdir_currLen,
1892 sshc->readdir_totalLen -
1893 sshc->readdir_currLen, "\n");
1894 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1896 sshc->readdir_currLen);
1898 if(result == CURLE_OK) {
1900 /* output debug output if that is requested */
1901 if(data->set.verbose) {
1902 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1903 sshc->readdir_currLen, conn);
1905 data->req.bytecount += sshc->readdir_currLen;
1907 Curl_safefree(sshc->readdir_line);
1908 sshc->readdir_line = NULL;
1910 state(conn, SSH_STOP);
1913 state(conn, SSH_SFTP_READDIR);
1916 case SSH_SFTP_READDIR_DONE:
1917 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1918 LIBSSH2_ERROR_EAGAIN) {
1919 rc = LIBSSH2_ERROR_EAGAIN;
1922 sshc->sftp_handle = NULL;
1923 Curl_safefree(sshc->readdir_filename);
1924 sshc->readdir_filename = NULL;
1925 Curl_safefree(sshc->readdir_longentry);
1926 sshc->readdir_longentry = NULL;
1928 /* no data to transfer */
1929 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1930 state(conn, SSH_STOP);
1933 case SSH_SFTP_DOWNLOAD_INIT:
1935 * Work on getting the specified file
1938 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1939 (unsigned int)strlen(sftp_scp->path),
1940 LIBSSH2_FXF_READ, data->set.new_file_perms,
1941 LIBSSH2_SFTP_OPENFILE);
1942 if(!sshc->sftp_handle) {
1943 if(libssh2_session_last_errno(sshc->ssh_session) ==
1944 LIBSSH2_ERROR_EAGAIN) {
1945 rc = LIBSSH2_ERROR_EAGAIN;
1949 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1950 failf(data, "Could not open remote file for reading: %s",
1951 sftp_libssh2_strerror(err));
1952 state(conn, SSH_SFTP_CLOSE);
1953 result = sftp_libssh2_error_to_CURLE(err);
1954 sshc->actualcode = result?result:CURLE_SSH;
1958 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1961 case SSH_SFTP_DOWNLOAD_STAT:
1963 LIBSSH2_SFTP_ATTRIBUTES attrs;
1965 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1966 (unsigned int)strlen(sftp_scp->path),
1967 LIBSSH2_SFTP_STAT, &attrs);
1968 if(rc == LIBSSH2_ERROR_EAGAIN) {
1973 * libssh2_sftp_open() didn't return an error, so maybe the server
1974 * just doesn't support stat()
1976 data->req.size = -1;
1977 data->req.maxdownload = -1;
1980 curl_off_t size = attrs.filesize;
1983 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1984 return CURLE_BAD_DOWNLOAD_RESUME;
1986 if(conn->data->state.use_range) {
1987 curl_off_t from, to;
1991 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1992 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
1994 to=curlx_strtoofft(ptr, &ptr2, 0);
1995 if((ptr == ptr2) /* no "to" value given */
2000 /* from is relative to end of file */
2004 failf(data, "Offset (%"
2005 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2006 from, attrs.filesize);
2007 return CURLE_BAD_DOWNLOAD_RESUME;
2014 size = to - from + 1;
2017 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2019 data->req.size = size;
2020 data->req.maxdownload = size;
2021 Curl_pgrsSetDownloadSize(data, size);
2024 /* We can resume if we can seek to the resume position */
2025 if(data->state.resume_from) {
2026 if(data->state.resume_from < 0) {
2027 /* We're supposed to download the last abs(from) bytes */
2028 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2029 failf(data, "Offset (%"
2030 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2031 data->state.resume_from, attrs.filesize);
2032 return CURLE_BAD_DOWNLOAD_RESUME;
2034 /* download from where? */
2035 data->state.resume_from += attrs.filesize;
2038 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2039 failf(data, "Offset (%" FORMAT_OFF_T
2040 ") was beyond file size (%" FORMAT_OFF_T ")",
2041 data->state.resume_from, attrs.filesize);
2042 return CURLE_BAD_DOWNLOAD_RESUME;
2045 /* Does a completed file need to be seeked and started or closed ? */
2046 /* Now store the number of bytes we are expected to download */
2047 data->req.size = attrs.filesize - data->state.resume_from;
2048 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2049 Curl_pgrsSetDownloadSize(data,
2050 attrs.filesize - data->state.resume_from);
2051 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2054 /* Setup the actual download */
2055 if(data->req.size == 0) {
2056 /* no data to transfer */
2057 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2058 infof(data, "File already completely downloaded\n");
2059 state(conn, SSH_STOP);
2063 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2064 FALSE, NULL, -1, NULL);
2066 /* not set by Curl_setup_transfer to preserve keepon bits */
2067 conn->writesockfd = conn->sockfd;
2069 /* we want to use the _receiving_ function even when the socket turns
2070 out writableable as the underlying libssh2 recv function will deal
2071 with both accordingly */
2072 conn->cselect_bits = CURL_CSELECT_IN;
2075 state(conn, SSH_SFTP_CLOSE);
2076 sshc->actualcode = result;
2079 state(conn, SSH_STOP);
2083 case SSH_SFTP_CLOSE:
2084 if(sshc->sftp_handle) {
2085 rc = libssh2_sftp_close(sshc->sftp_handle);
2086 if(rc == LIBSSH2_ERROR_EAGAIN) {
2090 infof(data, "Failed to close libssh2 file\n");
2092 sshc->sftp_handle = NULL;
2095 Curl_safefree(sftp_scp->path);
2096 sftp_scp->path = NULL;
2099 DEBUGF(infof(data, "SFTP DONE done\n"));
2101 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2102 After nextstate is executed,the control should come back to
2103 SSH_SFTP_CLOSE to pass the correct result back */
2104 if(sshc->nextstate != SSH_NO_STATE) {
2105 state(conn, sshc->nextstate);
2106 sshc->nextstate = SSH_SFTP_CLOSE;
2109 state(conn, SSH_STOP);
2110 result = sshc->actualcode;
2114 case SSH_SFTP_SHUTDOWN:
2115 /* during times we get here due to a broken transfer and then the
2116 sftp_handle might not have been taken down so make sure that is done
2117 before we proceed */
2119 if(sshc->sftp_handle) {
2120 rc = libssh2_sftp_close(sshc->sftp_handle);
2121 if(rc == LIBSSH2_ERROR_EAGAIN) {
2125 infof(data, "Failed to close libssh2 file\n");
2127 sshc->sftp_handle = NULL;
2129 if(sshc->sftp_session) {
2130 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2131 if(rc == LIBSSH2_ERROR_EAGAIN) {
2135 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2137 sshc->sftp_session = NULL;
2140 Curl_safefree(sshc->homedir);
2141 sshc->homedir = NULL;
2142 conn->data->state.most_recent_ftp_entrypath = NULL;
2144 state(conn, SSH_SESSION_DISCONNECT);
2147 case SSH_SCP_TRANS_INIT:
2148 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2150 sshc->actualcode = result;
2151 state(conn, SSH_STOP);
2155 if(data->set.upload) {
2156 if(data->set.infilesize < 0) {
2157 failf(data, "SCP requires a known file size for upload");
2158 sshc->actualcode = CURLE_UPLOAD_FAILED;
2159 state(conn, SSH_SCP_CHANNEL_FREE);
2162 state(conn, SSH_SCP_UPLOAD_INIT);
2165 state(conn, SSH_SCP_DOWNLOAD_INIT);
2169 case SSH_SCP_UPLOAD_INIT:
2171 * libssh2 requires that the destination path is a full path that
2172 * includes the destination file and name OR ends in a "/" . If this is
2173 * not done the destination file will be named the same name as the last
2174 * directory in the path.
2177 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2178 data->set.infilesize);
2179 if(!sshc->ssh_channel) {
2180 if(libssh2_session_last_errno(sshc->ssh_session) ==
2181 LIBSSH2_ERROR_EAGAIN) {
2182 rc = LIBSSH2_ERROR_EAGAIN;
2189 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2190 &err_msg, NULL, 0));
2191 failf(conn->data, "%s", err_msg);
2192 state(conn, SSH_SCP_CHANNEL_FREE);
2193 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2199 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2202 /* not set by Curl_setup_transfer to preserve keepon bits */
2203 conn->sockfd = conn->writesockfd;
2206 state(conn, SSH_SCP_CHANNEL_FREE);
2207 sshc->actualcode = result;
2210 /* we want to use the _sending_ function even when the socket turns
2211 out readable as the underlying libssh2 scp send function will deal
2212 with both accordingly */
2213 conn->cselect_bits = CURL_CSELECT_OUT;
2215 state(conn, SSH_STOP);
2219 case SSH_SCP_DOWNLOAD_INIT:
2222 * We must check the remote file; if it is a directory no values will
2226 curl_off_t bytecount;
2228 /* clear the struct scp recv will fill in */
2229 memset(&sb, 0, sizeof(struct stat));
2231 /* get a fresh new channel from the ssh layer */
2232 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2233 sftp_scp->path, &sb);
2234 if(!sshc->ssh_channel) {
2235 if(libssh2_session_last_errno(sshc->ssh_session) ==
2236 LIBSSH2_ERROR_EAGAIN) {
2237 rc = LIBSSH2_ERROR_EAGAIN;
2244 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2245 &err_msg, NULL, 0));
2246 failf(conn->data, "%s", err_msg);
2247 state(conn, SSH_SCP_CHANNEL_FREE);
2248 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2254 bytecount = (curl_off_t)sb.st_size;
2255 data->req.maxdownload = (curl_off_t)sb.st_size;
2256 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2258 /* not set by Curl_setup_transfer to preserve keepon bits */
2259 conn->writesockfd = conn->sockfd;
2261 /* we want to use the _receiving_ function even when the socket turns
2262 out writableable as the underlying libssh2 recv function will deal
2263 with both accordingly */
2264 conn->cselect_bits = CURL_CSELECT_IN;
2267 state(conn, SSH_SCP_CHANNEL_FREE);
2268 sshc->actualcode = result;
2271 state(conn, SSH_STOP);
2276 if(data->set.upload)
2277 state(conn, SSH_SCP_SEND_EOF);
2279 state(conn, SSH_SCP_CHANNEL_FREE);
2282 case SSH_SCP_SEND_EOF:
2283 if(sshc->ssh_channel) {
2284 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2285 if(rc == LIBSSH2_ERROR_EAGAIN) {
2289 infof(data, "Failed to send libssh2 channel EOF\n");
2292 state(conn, SSH_SCP_WAIT_EOF);
2295 case SSH_SCP_WAIT_EOF:
2296 if(sshc->ssh_channel) {
2297 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2298 if(rc == LIBSSH2_ERROR_EAGAIN) {
2302 infof(data, "Failed to get channel EOF: %d\n", rc);
2305 state(conn, SSH_SCP_WAIT_CLOSE);
2308 case SSH_SCP_WAIT_CLOSE:
2309 if(sshc->ssh_channel) {
2310 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2311 if(rc == LIBSSH2_ERROR_EAGAIN) {
2315 infof(data, "Channel failed to close: %d\n", rc);
2318 state(conn, SSH_SCP_CHANNEL_FREE);
2321 case SSH_SCP_CHANNEL_FREE:
2322 if(sshc->ssh_channel) {
2323 rc = libssh2_channel_free(sshc->ssh_channel);
2324 if(rc == LIBSSH2_ERROR_EAGAIN) {
2328 infof(data, "Failed to free libssh2 scp subsystem\n");
2330 sshc->ssh_channel = NULL;
2332 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2334 state(conn, SSH_SESSION_DISCONNECT);
2336 state(conn, SSH_STOP);
2337 result = sshc->actualcode;
2340 case SSH_SESSION_DISCONNECT:
2341 /* during weird times when we've been prematurely aborted, the channel
2342 is still alive when we reach this state and we MUST kill the channel
2344 if(sshc->ssh_channel) {
2345 rc = libssh2_channel_free(sshc->ssh_channel);
2346 if(rc == LIBSSH2_ERROR_EAGAIN) {
2350 infof(data, "Failed to free libssh2 scp subsystem\n");
2352 sshc->ssh_channel = NULL;
2355 if(sshc->ssh_session) {
2356 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2357 if(rc == LIBSSH2_ERROR_EAGAIN) {
2361 infof(data, "Failed to disconnect libssh2 session\n");
2365 Curl_safefree(sshc->homedir);
2366 sshc->homedir = NULL;
2367 conn->data->state.most_recent_ftp_entrypath = NULL;
2369 state(conn, SSH_SESSION_FREE);
2372 case SSH_SESSION_FREE:
2373 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2375 libssh2_knownhost_free(sshc->kh);
2380 if(sshc->ssh_session) {
2381 rc = libssh2_session_free(sshc->ssh_session);
2382 if(rc == LIBSSH2_ERROR_EAGAIN) {
2386 infof(data, "Failed to free libssh2 session\n");
2388 sshc->ssh_session = NULL;
2390 conn->bits.close = TRUE;
2391 sshc->nextstate = SSH_NO_STATE;
2392 state(conn, SSH_STOP);
2393 result = sshc->actualcode;
2397 /* fallthrough, just stop! */
2399 /* internal error */
2400 sshc->nextstate = SSH_NO_STATE;
2401 state(conn, SSH_STOP);
2405 } while(!rc && (sshc->state != SSH_STOP));
2407 if(rc == LIBSSH2_ERROR_EAGAIN) {
2408 /* we would block, we need to wait for the socket to be ready (in the
2409 right direction too)! */
2416 /* called by the multi interface to figure out what socket(s) to wait for and
2417 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2418 static int ssh_perform_getsock(const struct connectdata *conn,
2419 curl_socket_t *sock, /* points to numsocks
2420 number of sockets */
2423 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2424 int bitmap = GETSOCK_BLANK;
2427 sock[0] = conn->sock[FIRSTSOCKET];
2429 if(conn->waitfor & KEEP_RECV)
2430 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2432 if(conn->waitfor & KEEP_SEND)
2433 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2437 /* if we don't know the direction we can use the generic *_getsock()
2438 function even for the protocol_connect and doing states */
2439 return Curl_single_getsock(conn, sock, numsocks);
2443 /* Generic function called by the multi interface to figure out what socket(s)
2444 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2445 static int ssh_getsock(struct connectdata *conn,
2446 curl_socket_t *sock, /* points to numsocks number
2450 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2454 /* if we don't know any direction we can just play along as we used to and
2455 not provide any sensible info */
2456 return GETSOCK_BLANK;
2458 /* if we know the direction we can use the generic *_getsock() function even
2459 for the protocol_connect and doing states */
2460 return ssh_perform_getsock(conn, sock, numsocks);
2464 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2466 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2467 * function is used to figure out in what direction and stores this info so
2468 * that the multi interface can take advantage of it. Make sure to call this
2469 * function in all cases so that when it _doesn't_ return EAGAIN we can
2470 * restore the default wait bits.
2472 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2474 struct ssh_conn *sshc = &conn->proto.sshc;
2478 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2479 /* translate the libssh2 define bits into our own bit defines */
2480 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2481 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2484 /* It didn't block or libssh2 didn't reveal in which direction, put back
2486 conn->waitfor = sshc->orig_waitfor;
2489 /* no libssh2 directional support so we simply don't know */
2490 #define ssh_block2waitfor(x,y)
2493 /* called repeatedly until done from multi.c */
2494 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2496 struct ssh_conn *sshc = &conn->proto.sshc;
2497 CURLcode result = CURLE_OK;
2498 bool block; /* we store the status and use that to provide a ssh_getsock()
2501 result = ssh_statemach_act(conn, &block);
2502 *done = (bool)(sshc->state == SSH_STOP);
2503 ssh_block2waitfor(conn, block);
2508 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2511 struct ssh_conn *sshc = &conn->proto.sshc;
2512 CURLcode result = CURLE_OK;
2513 struct SessionHandle *data = conn->data;
2515 while((sshc->state != SSH_STOP) && !result) {
2519 result = ssh_statemach_act(conn, &block);
2523 if(Curl_pgrsUpdate(conn))
2524 return CURLE_ABORTED_BY_CALLBACK;
2526 struct timeval now = Curl_tvnow();
2527 result = Curl_speedcheck(data, now);
2532 left = Curl_timeleft(data, NULL, duringconnect);
2534 failf(data, "Operation timed out\n");
2535 return CURLE_OPERATION_TIMEDOUT;
2538 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2539 if((CURLE_OK == result) && block) {
2540 int dir = libssh2_session_block_directions(sshc->ssh_session);
2541 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2542 curl_socket_t fd_read = CURL_SOCKET_BAD;
2543 curl_socket_t fd_write = CURL_SOCKET_BAD;
2544 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2546 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2548 /* wait for the socket to become ready */
2549 Curl_socket_ready(fd_read, fd_write,
2550 (int)(left>1000?1000:left)); /* ignore result */
2560 * SSH setup and connection
2562 static CURLcode ssh_init(struct connectdata *conn)
2564 struct SessionHandle *data = conn->data;
2565 struct SSHPROTO *ssh;
2566 struct ssh_conn *sshc = &conn->proto.sshc;
2568 sshc->actualcode = CURLE_OK; /* reset error code */
2569 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2572 if(data->state.proto.ssh)
2575 ssh = calloc(1, sizeof(struct SSHPROTO));
2577 return CURLE_OUT_OF_MEMORY;
2579 data->state.proto.ssh = ssh;
2584 static Curl_recv scp_recv, sftp_recv;
2585 static Curl_send scp_send, sftp_send;
2588 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2589 * do protocol-specific actions at connect-time.
2591 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2593 #ifdef CURL_LIBSSH2_DEBUG
2596 struct ssh_conn *ssh;
2598 struct SessionHandle *data = conn->data;
2600 /* We default to persistent connections. We set this already in this connect
2601 function to make the re-use checks properly be able to check this bit. */
2602 conn->bits.close = FALSE;
2604 /* If there already is a protocol-specific struct allocated for this
2605 sessionhandle, deal with it */
2606 Curl_reset_reqproto(conn);
2608 result = ssh_init(conn);
2612 if(conn->handler->protocol & CURLPROTO_SCP) {
2613 conn->recv[FIRSTSOCKET] = scp_recv;
2614 conn->send[FIRSTSOCKET] = scp_send;
2617 conn->recv[FIRSTSOCKET] = sftp_recv;
2618 conn->send[FIRSTSOCKET] = sftp_send;
2620 ssh = &conn->proto.sshc;
2622 #ifdef CURL_LIBSSH2_DEBUG
2624 infof(data, "User: %s\n", conn->user);
2627 infof(data, "Password: %s\n", conn->passwd);
2629 sock = conn->sock[FIRSTSOCKET];
2630 #endif /* CURL_LIBSSH2_DEBUG */
2632 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2634 my_libssh2_realloc, conn);
2635 if(ssh->ssh_session == NULL) {
2636 failf(data, "Failure initialising ssh session");
2637 return CURLE_FAILED_INIT;
2640 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2641 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2643 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2645 /* eeek. TODO: free the ssh_session! */
2646 return CURLE_FAILED_INIT;
2649 /* read all known hosts from there */
2650 rc = libssh2_knownhost_readfile(ssh->kh,
2651 data->set.str[STRING_SSH_KNOWNHOSTS],
2652 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2654 infof(data, "Failed to read known hosts from %s\n",
2655 data->set.str[STRING_SSH_KNOWNHOSTS]);
2657 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2659 #ifdef CURL_LIBSSH2_DEBUG
2660 libssh2_trace(ssh->ssh_session, ~0);
2661 infof(data, "SSH socket: %d\n", (int)sock);
2662 #endif /* CURL_LIBSSH2_DEBUG */
2664 state(conn, SSH_INIT);
2666 if(data->state.used_interface == Curl_if_multi)
2667 result = ssh_multi_statemach(conn, done);
2669 result = ssh_easy_statemach(conn, TRUE);
2678 ***********************************************************************
2682 * This is the actual DO function for SCP. Get a file according to
2683 * the options previously setup.
2687 CURLcode scp_perform(struct connectdata *conn,
2691 CURLcode result = CURLE_OK;
2693 DEBUGF(infof(conn->data, "DO phase starts\n"));
2695 *dophase_done = FALSE; /* not done yet */
2697 /* start the first command in the DO phase */
2698 state(conn, SSH_SCP_TRANS_INIT);
2700 /* run the state-machine */
2701 if(conn->data->state.used_interface == Curl_if_multi) {
2702 result = ssh_multi_statemach(conn, dophase_done);
2705 result = ssh_easy_statemach(conn, FALSE);
2706 *dophase_done = TRUE; /* with the easy interface we are done here */
2708 *connected = conn->bits.tcpconnect;
2711 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2717 /* called from multi.c while DOing */
2718 static CURLcode scp_doing(struct connectdata *conn,
2722 result = ssh_multi_statemach(conn, dophase_done);
2725 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2731 * The DO function is generic for both protocols. There was previously two
2732 * separate ones but this way means less duplicated code.
2735 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2739 struct SessionHandle *data = conn->data;
2741 *done = FALSE; /* default to false */
2744 Since connections can be re-used between SessionHandles, this might be a
2745 connection already existing but on a fresh SessionHandle struct so we must
2746 make sure we have a good 'struct SSHPROTO' to play with. For new
2747 connections, the struct SSHPROTO is allocated and setup in the
2748 ssh_connect() function.
2750 Curl_reset_reqproto(conn);
2751 res = ssh_init(conn);
2755 data->req.size = -1; /* make sure this is unknown at this point */
2757 Curl_pgrsSetUploadCounter(data, 0);
2758 Curl_pgrsSetDownloadCounter(data, 0);
2759 Curl_pgrsSetUploadSize(data, 0);
2760 Curl_pgrsSetDownloadSize(data, 0);
2762 if(conn->handler->protocol & CURLPROTO_SCP)
2763 res = scp_perform(conn, &connected, done);
2765 res = sftp_perform(conn, &connected, done);
2770 /* BLOCKING, but the function is using the state machine so the only reason
2771 this is still blocking is that the multi interface code has no support for
2772 disconnecting operations that takes a while */
2773 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2775 CURLcode result = CURLE_OK;
2776 struct ssh_conn *ssh = &conn->proto.sshc;
2777 (void) dead_connection;
2779 Curl_safefree(conn->data->state.proto.ssh);
2780 conn->data->state.proto.ssh = NULL;
2782 if(ssh->ssh_session) {
2783 /* only if there's a session still around to use! */
2785 state(conn, SSH_SESSION_DISCONNECT);
2787 result = ssh_easy_statemach(conn, FALSE);
2793 /* generic done function for both SCP and SFTP called from their specific
2795 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2797 CURLcode result = CURLE_OK;
2798 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2800 if(status == CURLE_OK) {
2801 /* run the state-machine
2803 TODO: when the multi interface is used, this _really_ should be using
2804 the ssh_multi_statemach function but we have no general support for
2805 non-blocking DONE operations, not in the multi state machine and with
2806 Curl_done() invokes on several places in the code!
2808 result = ssh_easy_statemach(conn, FALSE);
2814 Curl_safefree(sftp_scp->path);
2815 sftp_scp->path = NULL;
2817 Curl_pgrsDone(conn);
2819 conn->data->req.keepon = 0; /* clear all bits */
2824 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2827 (void)premature; /* not used */
2829 if(status == CURLE_OK)
2830 state(conn, SSH_SCP_DONE);
2832 return ssh_done(conn, status);
2836 /* return number of received (decrypted) bytes */
2837 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2838 const void *mem, size_t len, CURLcode *err)
2841 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2843 /* libssh2_channel_write() returns int! */
2845 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2847 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2849 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2858 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2859 * a regular CURLcode value.
2861 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2862 char *mem, size_t len, CURLcode *err)
2865 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2867 /* libssh2_channel_read() returns int */
2869 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2871 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2872 if(nread == LIBSSH2_ERROR_EAGAIN) {
2881 * =============== SFTP ===============
2885 ***********************************************************************
2889 * This is the actual DO function for SFTP. Get a file/directory according to
2890 * the options previously setup.
2894 CURLcode sftp_perform(struct connectdata *conn,
2898 CURLcode result = CURLE_OK;
2900 DEBUGF(infof(conn->data, "DO phase starts\n"));
2902 *dophase_done = FALSE; /* not done yet */
2904 /* start the first command in the DO phase */
2905 state(conn, SSH_SFTP_QUOTE_INIT);
2907 /* run the state-machine */
2908 if(conn->data->state.used_interface == Curl_if_multi) {
2909 result = ssh_multi_statemach(conn, dophase_done);
2912 result = ssh_easy_statemach(conn, FALSE);
2913 *dophase_done = TRUE; /* with the easy interface we are done here */
2915 *connected = conn->bits.tcpconnect;
2918 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2924 /* called from multi.c while DOing */
2925 static CURLcode sftp_doing(struct connectdata *conn,
2929 result = ssh_multi_statemach(conn, dophase_done);
2932 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2937 /* BLOCKING, but the function is using the state machine so the only reason
2938 this is still blocking is that the multi interface code has no support for
2939 disconnecting operations that takes a while */
2940 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
2942 CURLcode result = CURLE_OK;
2943 (void) dead_connection;
2945 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2947 Curl_safefree(conn->data->state.proto.ssh);
2948 conn->data->state.proto.ssh = NULL;
2950 if(conn->proto.sshc.ssh_session) {
2951 /* only if there's a session still around to use! */
2952 state(conn, SSH_SFTP_SHUTDOWN);
2953 result = ssh_easy_statemach(conn, FALSE);
2956 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2962 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2965 struct ssh_conn *sshc = &conn->proto.sshc;
2967 if(status == CURLE_OK) {
2968 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
2969 errors that could happen due to open file handles during POSTQUOTE
2971 if(!status && !premature && conn->data->set.postquote) {
2972 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
2973 state(conn, SSH_SFTP_CLOSE);
2976 state(conn, SSH_SFTP_CLOSE);
2978 return ssh_done(conn, status);
2981 /* return number of sent bytes */
2982 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
2983 const void *mem, size_t len, CURLcode *err)
2985 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2986 but is changed to ssize_t in 0.15. These days we don't
2987 support libssh2 0.15*/
2990 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2992 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2994 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3003 * Return number of received (decrypted) bytes
3005 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3006 char *mem, size_t len, CURLcode *err)
3011 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3013 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3015 if(nread == LIBSSH2_ERROR_EAGAIN) {
3022 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3025 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3027 * Permission to use, copy, modify, and distribute this software for any
3028 * purpose with or without fee is hereby granted, provided that the above
3029 * copyright notice and this permission notice appear in all copies.
3031 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3032 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3033 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3034 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3035 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3036 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3037 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3040 get_pathname(const char **cpp, char **path)
3042 const char *cp = *cpp, *end;
3045 static const char WHITESPACE[] = " \t\r\n";
3047 cp += strspn(cp, WHITESPACE);
3051 return CURLE_QUOTE_ERROR;
3054 *path = malloc(strlen(cp) + 1);
3056 return CURLE_OUT_OF_MEMORY;
3058 /* Check for quoted filenames */
3059 if(*cp == '\"' || *cp == '\'') {
3062 /* Search for terminating quote, unescape some chars */
3063 for(i = j = 0; i <= strlen(cp); i++) {
3064 if(cp[i] == quot) { /* Found quote */
3069 if(cp[i] == '\0') { /* End of string */
3070 /*error("Unterminated quote");*/
3073 if(cp[i] == '\\') { /* Escaped characters */
3075 if(cp[i] != '\'' && cp[i] != '\"' &&
3077 /*error("Bad escaped character '\\%c'",
3082 (*path)[j++] = cp[i];
3086 /*error("Empty quotes");*/
3089 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3092 /* Read to end of filename */
3093 end = strpbrk(cp, WHITESPACE);
3095 end = strchr(cp, '\0');
3096 *cpp = end + strspn(end, WHITESPACE);
3098 memcpy(*path, cp, end - cp);
3099 (*path)[end - cp] = '\0';
3104 Curl_safefree(*path);
3106 return CURLE_QUOTE_ERROR;
3110 static const char *sftp_libssh2_strerror(unsigned long err)
3113 case LIBSSH2_FX_NO_SUCH_FILE:
3114 return "No such file or directory";
3116 case LIBSSH2_FX_PERMISSION_DENIED:
3117 return "Permission denied";
3119 case LIBSSH2_FX_FAILURE:
3120 return "Operation failed";
3122 case LIBSSH2_FX_BAD_MESSAGE:
3123 return "Bad message from SFTP server";
3125 case LIBSSH2_FX_NO_CONNECTION:
3126 return "Not connected to SFTP server";
3128 case LIBSSH2_FX_CONNECTION_LOST:
3129 return "Connection to SFTP server lost";
3131 case LIBSSH2_FX_OP_UNSUPPORTED:
3132 return "Operation not supported by SFTP server";
3134 case LIBSSH2_FX_INVALID_HANDLE:
3135 return "Invalid handle";
3137 case LIBSSH2_FX_NO_SUCH_PATH:
3138 return "No such file or directory";
3140 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3141 return "File already exists";
3143 case LIBSSH2_FX_WRITE_PROTECT:
3144 return "File is write protected";
3146 case LIBSSH2_FX_NO_MEDIA:
3149 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3152 case LIBSSH2_FX_QUOTA_EXCEEDED:
3153 return "User quota exceeded";
3155 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3156 return "Unknown principle";
3158 case LIBSSH2_FX_LOCK_CONFlICT:
3159 return "File lock conflict";
3161 case LIBSSH2_FX_DIR_NOT_EMPTY:
3162 return "Directory not empty";
3164 case LIBSSH2_FX_NOT_A_DIRECTORY:
3165 return "Not a directory";
3167 case LIBSSH2_FX_INVALID_FILENAME:
3168 return "Invalid filename";
3170 case LIBSSH2_FX_LINK_LOOP:
3171 return "Link points to itself";
3173 return "Unknown error in libssh2";
3176 #endif /* USE_LIBSSH2 */