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 CURLcode result = CURLE_OK;
514 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
515 struct SessionHandle *data = conn->data;
517 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
518 /* we're asked to verify the host against a file */
519 struct ssh_conn *sshc = &conn->proto.sshc;
523 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
525 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
530 * A subject to figure out is what host name we need to pass in here.
531 * What host name does OpenSSH store in its file if an IDN name is
534 struct libssh2_knownhost *host;
535 enum curl_khmatch keymatch;
536 curl_sshkeycallback func =
537 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
538 struct curl_khkey knownkey;
539 struct curl_khkey *knownkeyp = NULL;
540 struct curl_khkey foundkey;
542 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
543 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
545 keycheck = libssh2_knownhost_check(sshc->kh,
548 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
549 LIBSSH2_KNOWNHOST_KEYENC_RAW|
553 infof(data, "SSH host check: %d, key: %s\n", keycheck,
554 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
557 /* setup 'knownkey' */
558 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
559 knownkey.key = host->key;
561 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
562 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
563 knownkeyp = &knownkey;
566 /* setup 'foundkey' */
567 foundkey.key = remotekey;
568 foundkey.len = keylen;
569 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
570 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
573 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
574 * curl_khmatch enum are ever modified, we need to introduce a
575 * translation table here!
577 keymatch = (enum curl_khmatch)keycheck;
579 /* Ask the callback how to behave */
580 rc = func(data, knownkeyp, /* from the knownhosts file */
581 &foundkey, /* from the remote host */
582 keymatch, data->set.ssh_keyfunc_userp);
585 /* no remotekey means failure! */
586 rc = CURLKHSTAT_REJECT;
589 default: /* unknown return codes will equal reject */
590 case CURLKHSTAT_REJECT:
591 state(conn, SSH_SESSION_FREE);
592 case CURLKHSTAT_DEFER:
593 /* DEFER means bail out but keep the SSH_HOSTKEY state */
594 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
596 case CURLKHSTAT_FINE:
597 case CURLKHSTAT_FINE_ADD_TO_FILE:
599 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
600 /* the found host+key didn't match but has been told to be fine
601 anyway so we add it in memory */
602 int addrc = libssh2_knownhost_add(sshc->kh,
603 conn->host.name, NULL,
605 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
606 LIBSSH2_KNOWNHOST_KEYENC_RAW|
609 infof(data, "Warning adding the known host %s failed!\n",
611 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
612 /* now we write the entire in-memory list of known hosts to the
615 libssh2_knownhost_writefile(sshc->kh,
616 data->set.str[STRING_SSH_KNOWNHOSTS],
617 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
619 infof(data, "Warning, writing %s failed!\n",
620 data->set.str[STRING_SSH_KNOWNHOSTS]);
627 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
635 * ssh_statemach_act() runs the SSH state machine as far as it can without
636 * blocking and without reaching the end. The data the pointer 'block' points
637 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
638 * meaning it wants to be called again when the socket is ready
641 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
643 CURLcode result = CURLE_OK;
644 struct SessionHandle *data = conn->data;
645 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
646 struct ssh_conn *sshc = &conn->proto.sshc;
647 curl_socket_t sock = conn->sock[FIRSTSOCKET];
648 #ifdef CURL_LIBSSH2_DEBUG
649 const char *fingerprint;
650 #endif /* CURL_LIBSSH2_DEBUG */
651 const char *host_public_key_md5;
652 int rc = LIBSSH2_ERROR_NONE, i;
654 int seekerr = CURL_SEEKFUNC_OK;
655 *block = 0; /* we're not blocking by default */
659 switch(sshc->state) {
661 sshc->secondCreateDirs = 0;
662 sshc->nextstate = SSH_NO_STATE;
663 sshc->actualcode = CURLE_OK;
665 /* Set libssh2 to non-blocking, since everything internally is
667 libssh2_session_set_blocking(sshc->ssh_session, 0);
669 state(conn, SSH_S_STARTUP);
673 rc = libssh2_session_startup(sshc->ssh_session, sock);
674 if(rc == LIBSSH2_ERROR_EAGAIN) {
678 failf(data, "Failure establishing ssh session");
679 state(conn, SSH_SESSION_FREE);
680 sshc->actualcode = CURLE_FAILED_INIT;
684 state(conn, SSH_HOSTKEY);
689 #ifdef CURL_LIBSSH2_DEBUG
691 * Before we authenticate we should check the hostkey's fingerprint
692 * against our known hosts. How that is handled (reading from file,
693 * whatever) is up to us. As for know not much is implemented, besides
694 * showing how to get the fingerprint.
696 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
697 LIBSSH2_HOSTKEY_HASH_MD5);
699 /* The fingerprint points to static storage (!), don't free() it. */
700 infof(data, "Fingerprint: ");
701 for(rc = 0; rc < 16; rc++)
702 infof(data, "%02X ", (unsigned char) fingerprint[rc]);
704 #endif /* CURL_LIBSSH2_DEBUG */
706 /* Before we authenticate we check the hostkey's MD5 fingerprint
707 * against a known fingerprint, if available. This implementation pulls
708 * it from the curl option.
710 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
711 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
713 host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
714 LIBSSH2_HOSTKEY_HASH_MD5);
715 for(i = 0; i < 16; i++)
716 snprintf(&buf[i*2], 3, "%02x",
717 (unsigned char) host_public_key_md5[i]);
718 if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
720 "Denied establishing ssh session: mismatch md5 fingerprint. "
721 "Remote %s is not equal to %s",
722 buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
723 state(conn, SSH_SESSION_FREE);
724 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
729 result = ssh_knownhost(conn);
731 state(conn, SSH_AUTHLIST);
736 * Figure out authentication methods
737 * NB: As soon as we have provided a username to an openssh server we
738 * must never change it later. Thus, always specify the correct username
739 * here, even though the libssh2 docs kind of indicate that it should be
740 * possible to get a 'generic' list (not user-specific) of authentication
741 * methods, presumably with a blank username. That won't work in my
743 * So always specify it here.
745 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
747 (unsigned int)strlen(conn->user));
749 if(!sshc->authlist) {
750 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
751 LIBSSH2_ERROR_EAGAIN) {
752 rc = LIBSSH2_ERROR_EAGAIN;
756 state(conn, SSH_SESSION_FREE);
757 sshc->actualcode = libssh2_session_error_to_CURLE(err);
761 infof(data, "SSH authentication methods available: %s\n",
764 state(conn, SSH_AUTH_PKEY_INIT);
767 case SSH_AUTH_PKEY_INIT:
769 * Check the supported auth types in the order I feel is most secure
770 * with the requested type of authentication
772 sshc->authed = FALSE;
774 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
775 (strstr(sshc->authlist, "publickey") != NULL)) {
778 sshc->rsa_pub = sshc->rsa = NULL;
780 /* To ponder about: should really the lib be messing about with the
781 HOME environment variable etc? */
782 home = curl_getenv("HOME");
784 if(data->set.str[STRING_SSH_PUBLIC_KEY])
785 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
787 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
789 /* as a final resort, try current dir! */
790 sshc->rsa_pub = strdup("id_dsa.pub");
792 if(sshc->rsa_pub == NULL) {
795 state(conn, SSH_SESSION_FREE);
796 sshc->actualcode = CURLE_OUT_OF_MEMORY;
800 if(data->set.str[STRING_SSH_PRIVATE_KEY])
801 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
803 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
805 /* as a final resort, try current dir! */
806 sshc->rsa = strdup("id_dsa");
808 if(sshc->rsa == NULL) {
811 Curl_safefree(sshc->rsa_pub);
812 sshc->rsa_pub = NULL;
813 state(conn, SSH_SESSION_FREE);
814 sshc->actualcode = CURLE_OUT_OF_MEMORY;
818 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
819 if(!sshc->passphrase)
820 sshc->passphrase = "";
825 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
826 infof(data, "Using ssh private key file %s\n", sshc->rsa);
828 state(conn, SSH_AUTH_PKEY);
831 state(conn, SSH_AUTH_PASS_INIT);
836 /* The function below checks if the files exists, no need to stat() here.
838 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
843 sshc->rsa, sshc->passphrase);
844 if(rc == LIBSSH2_ERROR_EAGAIN) {
848 Curl_safefree(sshc->rsa_pub);
849 sshc->rsa_pub = NULL;
850 Curl_safefree(sshc->rsa);
855 infof(data, "Initialized SSH public key authentication\n");
856 state(conn, SSH_AUTH_DONE);
860 (void)libssh2_session_last_error(sshc->ssh_session,
862 infof(data, "SSH public key authentication failed: %s\n", err_msg);
863 state(conn, SSH_AUTH_PASS_INIT);
867 case SSH_AUTH_PASS_INIT:
868 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
869 (strstr(sshc->authlist, "password") != NULL)) {
870 state(conn, SSH_AUTH_PASS);
873 state(conn, SSH_AUTH_HOST_INIT);
878 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
879 (unsigned int)strlen(conn->user),
881 (unsigned int)strlen(conn->passwd),
883 if(rc == LIBSSH2_ERROR_EAGAIN) {
888 infof(data, "Initialized password authentication\n");
889 state(conn, SSH_AUTH_DONE);
892 state(conn, SSH_AUTH_HOST_INIT);
896 case SSH_AUTH_HOST_INIT:
897 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
898 (strstr(sshc->authlist, "hostbased") != NULL)) {
899 state(conn, SSH_AUTH_HOST);
902 state(conn, SSH_AUTH_KEY_INIT);
907 state(conn, SSH_AUTH_KEY_INIT);
910 case SSH_AUTH_KEY_INIT:
911 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
912 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
913 state(conn, SSH_AUTH_KEY);
916 state(conn, SSH_AUTH_DONE);
921 /* Authentication failed. Continue with keyboard-interactive now. */
922 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
927 if(rc == LIBSSH2_ERROR_EAGAIN) {
932 infof(data, "Initialized keyboard interactive authentication\n");
934 state(conn, SSH_AUTH_DONE);
939 failf(data, "Authentication failure");
940 state(conn, SSH_SESSION_FREE);
941 sshc->actualcode = CURLE_LOGIN_DENIED;
946 * At this point we have an authenticated ssh session.
948 infof(data, "Authentication complete\n");
950 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
953 conn->writesockfd = CURL_SOCKET_BAD;
955 if(conn->handler->protocol == CURLPROTO_SFTP) {
956 state(conn, SSH_SFTP_INIT);
959 infof(data, "SSH CONNECT phase done\n");
960 state(conn, SSH_STOP);
965 * Start the libssh2 sftp session
967 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
968 if(!sshc->sftp_session) {
969 if(libssh2_session_last_errno(sshc->ssh_session) ==
970 LIBSSH2_ERROR_EAGAIN) {
971 rc = LIBSSH2_ERROR_EAGAIN;
977 (void)libssh2_session_last_error(sshc->ssh_session,
979 failf(data, "Failure initializing sftp session: %s", err_msg);
980 state(conn, SSH_SESSION_FREE);
981 sshc->actualcode = CURLE_FAILED_INIT;
985 state(conn, SSH_SFTP_REALPATH);
988 case SSH_SFTP_REALPATH:
990 char tempHome[PATH_MAX];
993 * Get the "home" directory
995 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
996 tempHome, PATH_MAX-1);
997 if(rc == LIBSSH2_ERROR_EAGAIN) {
1001 /* It seems that this string is not always NULL terminated */
1002 tempHome[rc] = '\0';
1003 sshc->homedir = strdup(tempHome);
1004 if(!sshc->homedir) {
1005 state(conn, SSH_SFTP_CLOSE);
1006 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1009 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1012 /* Return the error type */
1013 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1014 result = sftp_libssh2_error_to_CURLE(err);
1015 sshc->actualcode = result?result:CURLE_SSH;
1016 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1018 state(conn, SSH_STOP);
1022 /* This is the last step in the SFTP connect phase. Do note that while
1023 we get the homedir here, we get the "workingpath" in the DO action
1024 since the homedir will remain the same between request but the
1025 working path will not. */
1026 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1027 state(conn, SSH_STOP);
1030 case SSH_SFTP_QUOTE_INIT:
1032 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1034 sshc->actualcode = result;
1035 state(conn, SSH_STOP);
1039 if(data->set.quote) {
1040 infof(data, "Sending quote commands\n");
1041 sshc->quote_item = data->set.quote;
1042 state(conn, SSH_SFTP_QUOTE);
1045 state(conn, SSH_SFTP_TRANS_INIT);
1049 case SSH_SFTP_POSTQUOTE_INIT:
1050 if(data->set.postquote) {
1051 infof(data, "Sending quote commands\n");
1052 sshc->quote_item = data->set.postquote;
1053 state(conn, SSH_SFTP_QUOTE);
1056 state(conn, SSH_STOP);
1060 case SSH_SFTP_QUOTE:
1061 /* Send any quote commands */
1066 * Support some of the "FTP" commands
1068 if(curl_strequal("pwd", sshc->quote_item->data)) {
1069 /* output debug output if that is requested */
1070 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1073 result = CURLE_OUT_OF_MEMORY;
1074 state(conn, SSH_SFTP_CLOSE);
1075 sshc->nextstate = SSH_NO_STATE;
1078 if(data->set.verbose) {
1079 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1080 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1082 /* this sends an FTP-like "header" to the header callback so that the
1083 current directory can be read very similar to how it is read when
1084 using ordinary FTP. */
1085 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1087 state(conn, SSH_SFTP_NEXT_QUOTE);
1090 else if(sshc->quote_item->data) {
1092 * the arguments following the command must be separated from the
1093 * command with a space so we can check for it unconditionally
1095 cp = strchr(sshc->quote_item->data, ' ');
1097 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1098 state(conn, SSH_SFTP_CLOSE);
1099 sshc->nextstate = SSH_NO_STATE;
1100 sshc->actualcode = CURLE_QUOTE_ERROR;
1105 * also, every command takes at least one argument so we get that
1106 * first argument right now
1108 result = get_pathname(&cp, &sshc->quote_path1);
1110 if(result == CURLE_OUT_OF_MEMORY)
1111 failf(data, "Out of memory");
1113 failf(data, "Syntax error: Bad first parameter");
1114 state(conn, SSH_SFTP_CLOSE);
1115 sshc->nextstate = SSH_NO_STATE;
1116 sshc->actualcode = result;
1121 * SFTP is a binary protocol, so we don't send text commands to
1122 * the server. Instead, we scan for commands for commands used by
1123 * OpenSSH's sftp program and call the appropriate libssh2
1126 if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
1127 curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
1128 curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
1129 /* attribute change */
1131 /* sshc->quote_path1 contains the mode to set */
1132 /* get the destination */
1133 result = get_pathname(&cp, &sshc->quote_path2);
1135 if(result == CURLE_OUT_OF_MEMORY)
1136 failf(data, "Out of memory");
1138 failf(data, "Syntax error in chgrp/chmod/chown: "
1139 "Bad second parameter");
1140 Curl_safefree(sshc->quote_path1);
1141 sshc->quote_path1 = NULL;
1142 state(conn, SSH_SFTP_CLOSE);
1143 sshc->nextstate = SSH_NO_STATE;
1144 sshc->actualcode = result;
1147 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1148 state(conn, SSH_SFTP_QUOTE_STAT);
1151 else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
1152 curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
1153 /* symbolic linking */
1154 /* sshc->quote_path1 is the source */
1155 /* get the destination */
1156 result = get_pathname(&cp, &sshc->quote_path2);
1158 if(result == CURLE_OUT_OF_MEMORY)
1159 failf(data, "Out of memory");
1162 "Syntax error in ln/symlink: Bad second parameter");
1163 Curl_safefree(sshc->quote_path1);
1164 sshc->quote_path1 = NULL;
1165 state(conn, SSH_SFTP_CLOSE);
1166 sshc->nextstate = SSH_NO_STATE;
1167 sshc->actualcode = result;
1170 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1173 else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
1175 state(conn, SSH_SFTP_QUOTE_MKDIR);
1178 else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
1180 /* first param is the source path */
1181 /* second param is the dest. path */
1182 result = get_pathname(&cp, &sshc->quote_path2);
1184 if(result == CURLE_OUT_OF_MEMORY)
1185 failf(data, "Out of memory");
1187 failf(data, "Syntax error in rename: Bad second parameter");
1188 Curl_safefree(sshc->quote_path1);
1189 sshc->quote_path1 = NULL;
1190 state(conn, SSH_SFTP_CLOSE);
1191 sshc->nextstate = SSH_NO_STATE;
1192 sshc->actualcode = result;
1195 state(conn, SSH_SFTP_QUOTE_RENAME);
1198 else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
1200 state(conn, SSH_SFTP_QUOTE_RMDIR);
1203 else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
1204 state(conn, SSH_SFTP_QUOTE_UNLINK);
1208 failf(data, "Unknown SFTP command");
1209 Curl_safefree(sshc->quote_path1);
1210 sshc->quote_path1 = NULL;
1211 Curl_safefree(sshc->quote_path2);
1212 sshc->quote_path2 = NULL;
1213 state(conn, SSH_SFTP_CLOSE);
1214 sshc->nextstate = SSH_NO_STATE;
1215 sshc->actualcode = CURLE_QUOTE_ERROR;
1219 if(!sshc->quote_item) {
1220 state(conn, SSH_SFTP_TRANS_INIT);
1224 case SSH_SFTP_NEXT_QUOTE:
1225 if(sshc->quote_path1) {
1226 Curl_safefree(sshc->quote_path1);
1227 sshc->quote_path1 = NULL;
1229 if(sshc->quote_path2) {
1230 Curl_safefree(sshc->quote_path2);
1231 sshc->quote_path2 = NULL;
1234 sshc->quote_item = sshc->quote_item->next;
1236 if(sshc->quote_item) {
1237 state(conn, SSH_SFTP_QUOTE);
1240 if(sshc->nextstate != SSH_NO_STATE) {
1241 state(conn, sshc->nextstate);
1242 sshc->nextstate = SSH_NO_STATE;
1245 state(conn, SSH_SFTP_TRANS_INIT);
1250 case SSH_SFTP_QUOTE_STAT:
1251 if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1252 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1253 * set them both at once, we need to obtain the current ownership
1254 * first. This takes an extra protocol round trip.
1256 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1257 (unsigned int)strlen(sshc->quote_path2),
1259 &sshc->quote_attrs);
1260 if(rc == LIBSSH2_ERROR_EAGAIN) {
1263 else if(rc != 0) { /* get those attributes */
1264 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1265 Curl_safefree(sshc->quote_path1);
1266 sshc->quote_path1 = NULL;
1267 Curl_safefree(sshc->quote_path2);
1268 sshc->quote_path2 = NULL;
1269 failf(data, "Attempt to get SFTP stats failed: %s",
1270 sftp_libssh2_strerror(err));
1271 state(conn, SSH_SFTP_CLOSE);
1272 sshc->nextstate = SSH_NO_STATE;
1273 sshc->actualcode = CURLE_QUOTE_ERROR;
1278 /* Now set the new attributes... */
1279 if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
1280 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1281 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1282 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1283 Curl_safefree(sshc->quote_path1);
1284 sshc->quote_path1 = NULL;
1285 Curl_safefree(sshc->quote_path2);
1286 sshc->quote_path2 = NULL;
1287 failf(data, "Syntax error: chgrp gid not a number");
1288 state(conn, SSH_SFTP_CLOSE);
1289 sshc->nextstate = SSH_NO_STATE;
1290 sshc->actualcode = CURLE_QUOTE_ERROR;
1294 else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1295 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1296 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1297 /* permissions are octal */
1298 if(sshc->quote_attrs.permissions == 0 &&
1299 !ISDIGIT(sshc->quote_path1[0])) {
1300 Curl_safefree(sshc->quote_path1);
1301 sshc->quote_path1 = NULL;
1302 Curl_safefree(sshc->quote_path2);
1303 sshc->quote_path2 = NULL;
1304 failf(data, "Syntax error: chmod permissions not a number");
1305 state(conn, SSH_SFTP_CLOSE);
1306 sshc->nextstate = SSH_NO_STATE;
1307 sshc->actualcode = CURLE_QUOTE_ERROR;
1311 else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
1312 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1313 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1314 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1315 Curl_safefree(sshc->quote_path1);
1316 sshc->quote_path1 = NULL;
1317 Curl_safefree(sshc->quote_path2);
1318 sshc->quote_path2 = NULL;
1319 failf(data, "Syntax error: chown uid not a number");
1320 state(conn, SSH_SFTP_CLOSE);
1321 sshc->nextstate = SSH_NO_STATE;
1322 sshc->actualcode = CURLE_QUOTE_ERROR;
1327 /* Now send the completed structure... */
1328 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1331 case SSH_SFTP_QUOTE_SETSTAT:
1332 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1333 (unsigned int)strlen(sshc->quote_path2),
1334 LIBSSH2_SFTP_SETSTAT,
1335 &sshc->quote_attrs);
1336 if(rc == LIBSSH2_ERROR_EAGAIN) {
1340 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1341 Curl_safefree(sshc->quote_path1);
1342 sshc->quote_path1 = NULL;
1343 Curl_safefree(sshc->quote_path2);
1344 sshc->quote_path2 = NULL;
1345 failf(data, "Attempt to set SFTP stats failed: %s",
1346 sftp_libssh2_strerror(err));
1347 state(conn, SSH_SFTP_CLOSE);
1348 sshc->nextstate = SSH_NO_STATE;
1349 sshc->actualcode = CURLE_QUOTE_ERROR;
1352 state(conn, SSH_SFTP_NEXT_QUOTE);
1355 case SSH_SFTP_QUOTE_SYMLINK:
1356 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1357 (unsigned int)strlen(sshc->quote_path1),
1359 (unsigned int)strlen(sshc->quote_path2),
1360 LIBSSH2_SFTP_SYMLINK);
1361 if(rc == LIBSSH2_ERROR_EAGAIN) {
1365 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1366 Curl_safefree(sshc->quote_path1);
1367 sshc->quote_path1 = NULL;
1368 Curl_safefree(sshc->quote_path2);
1369 sshc->quote_path2 = NULL;
1370 failf(data, "symlink command failed: %s",
1371 sftp_libssh2_strerror(err));
1372 state(conn, SSH_SFTP_CLOSE);
1373 sshc->nextstate = SSH_NO_STATE;
1374 sshc->actualcode = CURLE_QUOTE_ERROR;
1377 state(conn, SSH_SFTP_NEXT_QUOTE);
1380 case SSH_SFTP_QUOTE_MKDIR:
1381 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1382 (unsigned int)strlen(sshc->quote_path1),
1384 if(rc == LIBSSH2_ERROR_EAGAIN) {
1388 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1389 Curl_safefree(sshc->quote_path1);
1390 sshc->quote_path1 = NULL;
1391 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1392 state(conn, SSH_SFTP_CLOSE);
1393 sshc->nextstate = SSH_NO_STATE;
1394 sshc->actualcode = CURLE_QUOTE_ERROR;
1397 state(conn, SSH_SFTP_NEXT_QUOTE);
1400 case SSH_SFTP_QUOTE_RENAME:
1401 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1402 (unsigned int)strlen(sshc->quote_path1),
1404 (unsigned int)strlen(sshc->quote_path2),
1405 LIBSSH2_SFTP_RENAME_OVERWRITE |
1406 LIBSSH2_SFTP_RENAME_ATOMIC |
1407 LIBSSH2_SFTP_RENAME_NATIVE);
1409 if(rc == LIBSSH2_ERROR_EAGAIN) {
1413 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1414 Curl_safefree(sshc->quote_path1);
1415 sshc->quote_path1 = NULL;
1416 Curl_safefree(sshc->quote_path2);
1417 sshc->quote_path2 = NULL;
1418 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1419 state(conn, SSH_SFTP_CLOSE);
1420 sshc->nextstate = SSH_NO_STATE;
1421 sshc->actualcode = CURLE_QUOTE_ERROR;
1424 state(conn, SSH_SFTP_NEXT_QUOTE);
1427 case SSH_SFTP_QUOTE_RMDIR:
1428 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1429 (unsigned int)strlen(sshc->quote_path1));
1430 if(rc == LIBSSH2_ERROR_EAGAIN) {
1434 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1435 Curl_safefree(sshc->quote_path1);
1436 sshc->quote_path1 = NULL;
1437 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1438 state(conn, SSH_SFTP_CLOSE);
1439 sshc->nextstate = SSH_NO_STATE;
1440 sshc->actualcode = CURLE_QUOTE_ERROR;
1443 state(conn, SSH_SFTP_NEXT_QUOTE);
1446 case SSH_SFTP_QUOTE_UNLINK:
1447 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1448 (unsigned int)strlen(sshc->quote_path1));
1449 if(rc == LIBSSH2_ERROR_EAGAIN) {
1453 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1454 Curl_safefree(sshc->quote_path1);
1455 sshc->quote_path1 = NULL;
1456 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1457 state(conn, SSH_SFTP_CLOSE);
1458 sshc->nextstate = SSH_NO_STATE;
1459 sshc->actualcode = CURLE_QUOTE_ERROR;
1462 state(conn, SSH_SFTP_NEXT_QUOTE);
1465 case SSH_SFTP_TRANS_INIT:
1466 if(data->set.upload)
1467 state(conn, SSH_SFTP_UPLOAD_INIT);
1469 if(data->set.opt_no_body)
1470 state(conn, SSH_STOP);
1471 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1472 state(conn, SSH_SFTP_READDIR_INIT);
1474 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1478 case SSH_SFTP_UPLOAD_INIT:
1480 unsigned long flags;
1482 * NOTE!!! libssh2 requires that the destination path is a full path
1483 * that includes the destination file and name OR ends in a "/"
1484 * If this is not done the destination file will be named the
1485 * same name as the last directory in the path.
1488 if(data->state.resume_from != 0) {
1489 LIBSSH2_SFTP_ATTRIBUTES attrs;
1490 if(data->state.resume_from < 0) {
1491 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1492 (unsigned int)strlen(sftp_scp->path),
1493 LIBSSH2_SFTP_STAT, &attrs);
1494 if(rc == LIBSSH2_ERROR_EAGAIN) {
1498 data->state.resume_from = 0;
1501 curl_off_t size = attrs.filesize;
1503 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1504 return CURLE_BAD_DOWNLOAD_RESUME;
1506 data->state.resume_from = attrs.filesize;
1511 if(data->set.ftp_append)
1512 /* Try to open for append, but create if nonexisting */
1513 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1514 else if(data->state.resume_from > 0)
1515 /* If we have restart position then open for append */
1516 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1518 /* Clear file before writing (normal behaviour) */
1519 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1522 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1523 (unsigned int)strlen(sftp_scp->path),
1524 flags, data->set.new_file_perms,
1525 LIBSSH2_SFTP_OPENFILE);
1527 if(!sshc->sftp_handle) {
1528 rc = libssh2_session_last_errno(sshc->ssh_session);
1530 if(LIBSSH2_ERROR_EAGAIN == rc)
1533 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1534 /* only when there was an SFTP protocol error can we extract
1536 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1538 err = -1; /* not an sftp error at all */
1540 if(sshc->secondCreateDirs) {
1541 state(conn, SSH_SFTP_CLOSE);
1542 sshc->actualcode = err>= LIBSSH2_FX_OK?
1543 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1544 failf(data, "Creating the dir/file failed: %s",
1545 sftp_libssh2_strerror(err));
1548 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1549 (err == LIBSSH2_FX_FAILURE) ||
1550 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1551 (data->set.ftp_create_missing_dirs &&
1552 (strlen(sftp_scp->path) > 1))) {
1553 /* try to create the path remotely */
1554 sshc->secondCreateDirs = 1;
1555 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1558 state(conn, SSH_SFTP_CLOSE);
1559 sshc->actualcode = err>= LIBSSH2_FX_OK?
1560 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1561 if(!sshc->actualcode) {
1562 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1563 zero even though libssh2_sftp_open() failed previously! We need
1564 to work around that! */
1565 sshc->actualcode = CURLE_SSH;
1568 failf(data, "Upload failed: %s (%d/%d)",
1569 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1575 /* If we have restart point then we need to seek to the correct
1577 if(data->state.resume_from > 0) {
1578 /* Let's read off the proper amount of bytes from the input. */
1579 if(conn->seek_func) {
1580 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1584 if(seekerr != CURL_SEEKFUNC_OK){
1586 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1587 failf(data, "Could not seek stream");
1588 return CURLE_FTP_COULDNT_USE_REST;
1590 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1592 curl_off_t passed=0;
1594 size_t readthisamountnow =
1595 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1596 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1598 size_t actuallyread =
1599 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1602 passed += actuallyread;
1603 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1604 /* this checks for greater-than only to make sure that the
1605 CURL_READFUNC_ABORT return code still aborts */
1606 failf(data, "Failed to read data");
1607 return CURLE_FTP_COULDNT_USE_REST;
1609 } while(passed < data->state.resume_from);
1613 /* now, decrease the size of the read */
1614 if(data->set.infilesize > 0) {
1615 data->set.infilesize -= data->state.resume_from;
1616 data->req.size = data->set.infilesize;
1617 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1620 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1622 if(data->set.infilesize > 0) {
1623 data->req.size = data->set.infilesize;
1624 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1627 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1629 /* not set by Curl_setup_transfer to preserve keepon bits */
1630 conn->sockfd = conn->writesockfd;
1633 state(conn, SSH_SFTP_CLOSE);
1634 sshc->actualcode = result;
1637 /* store this original bitmask setup to use later on if we can't
1638 figure out a "real" bitmask */
1639 sshc->orig_waitfor = data->req.keepon;
1641 /* we want to use the _sending_ function even when the socket turns
1642 out readable as the underlying libssh2 sftp send function will deal
1643 with both accordingly */
1644 conn->cselect_bits = CURL_CSELECT_OUT;
1646 /* since we don't really wait for anything at this point, we want the
1647 state machine to move on as soon as possible so we set a very short
1649 Curl_expire(data, 1);
1651 state(conn, SSH_STOP);
1656 case SSH_SFTP_CREATE_DIRS_INIT:
1657 if(strlen(sftp_scp->path) > 1) {
1658 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1659 state(conn, SSH_SFTP_CREATE_DIRS);
1662 state(conn, SSH_SFTP_UPLOAD_INIT);
1666 case SSH_SFTP_CREATE_DIRS:
1667 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1668 *sshc->slash_pos = 0;
1670 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1671 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1675 state(conn, SSH_SFTP_UPLOAD_INIT);
1679 case SSH_SFTP_CREATE_DIRS_MKDIR:
1680 /* 'mode' - parameter is preliminary - default to 0644 */
1681 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1682 (unsigned int)strlen(sftp_scp->path),
1683 data->set.new_directory_perms);
1684 if(rc == LIBSSH2_ERROR_EAGAIN) {
1687 *sshc->slash_pos = '/';
1690 unsigned int sftp_err = 0;
1692 * Abort if failure wasn't that the dir already exists or the
1693 * permission was denied (creation might succeed further down the
1694 * path) - retry on unspecific FAILURE also
1696 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1697 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1698 (sftp_err != LIBSSH2_FX_FAILURE) &&
1699 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1700 result = sftp_libssh2_error_to_CURLE(sftp_err);
1701 state(conn, SSH_SFTP_CLOSE);
1702 sshc->actualcode = result?result:CURLE_SSH;
1706 state(conn, SSH_SFTP_CREATE_DIRS);
1709 case SSH_SFTP_READDIR_INIT:
1711 * This is a directory that we are trying to get, so produce a directory
1714 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1717 strlen(sftp_scp->path),
1718 0, 0, LIBSSH2_SFTP_OPENDIR);
1719 if(!sshc->sftp_handle) {
1720 if(libssh2_session_last_errno(sshc->ssh_session) ==
1721 LIBSSH2_ERROR_EAGAIN) {
1722 rc = LIBSSH2_ERROR_EAGAIN;
1726 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1727 failf(data, "Could not open directory for reading: %s",
1728 sftp_libssh2_strerror(err));
1729 state(conn, SSH_SFTP_CLOSE);
1730 result = sftp_libssh2_error_to_CURLE(err);
1731 sshc->actualcode = result?result:CURLE_SSH;
1735 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1736 state(conn, SSH_SFTP_CLOSE);
1737 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1740 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1741 Curl_safefree(sshc->readdir_filename);
1742 sshc->readdir_filename = NULL;
1743 state(conn, SSH_SFTP_CLOSE);
1744 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1747 state(conn, SSH_SFTP_READDIR);
1750 case SSH_SFTP_READDIR:
1751 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1752 sshc->readdir_filename,
1754 sshc->readdir_longentry,
1756 &sshc->readdir_attrs);
1757 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1758 rc = LIBSSH2_ERROR_EAGAIN;
1761 if(sshc->readdir_len > 0) {
1762 sshc->readdir_filename[sshc->readdir_len] = '\0';
1764 if(data->set.ftp_list_only) {
1767 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1768 if(tmpLine == NULL) {
1769 state(conn, SSH_SFTP_CLOSE);
1770 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1773 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1774 tmpLine, sshc->readdir_len+1);
1775 Curl_safefree(tmpLine);
1778 state(conn, SSH_STOP);
1781 /* since this counts what we send to the client, we include the
1782 newline in this counter */
1783 data->req.bytecount += sshc->readdir_len+1;
1785 /* output debug output if that is requested */
1786 if(data->set.verbose) {
1787 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1788 sshc->readdir_len, conn);
1792 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1793 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1794 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1795 if(!sshc->readdir_line) {
1796 Curl_safefree(sshc->readdir_filename);
1797 sshc->readdir_filename = NULL;
1798 Curl_safefree(sshc->readdir_longentry);
1799 sshc->readdir_longentry = NULL;
1800 state(conn, SSH_SFTP_CLOSE);
1801 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1805 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1806 sshc->readdir_currLen);
1807 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1808 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1809 LIBSSH2_SFTP_S_IFLNK)) {
1810 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1811 if(sshc->readdir_linkPath == NULL) {
1812 Curl_safefree(sshc->readdir_filename);
1813 sshc->readdir_filename = NULL;
1814 Curl_safefree(sshc->readdir_longentry);
1815 sshc->readdir_longentry = NULL;
1816 state(conn, SSH_SFTP_CLOSE);
1817 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1821 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1822 sshc->readdir_filename);
1823 state(conn, SSH_SFTP_READDIR_LINK);
1826 state(conn, SSH_SFTP_READDIR_BOTTOM);
1830 else if(sshc->readdir_len == 0) {
1831 Curl_safefree(sshc->readdir_filename);
1832 sshc->readdir_filename = NULL;
1833 Curl_safefree(sshc->readdir_longentry);
1834 sshc->readdir_longentry = NULL;
1835 state(conn, SSH_SFTP_READDIR_DONE);
1838 else if(sshc->readdir_len <= 0) {
1839 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1840 result = sftp_libssh2_error_to_CURLE(err);
1841 sshc->actualcode = result?result:CURLE_SSH;
1842 failf(data, "Could not open remote file for reading: %s :: %d",
1843 sftp_libssh2_strerror(err),
1844 libssh2_session_last_errno(sshc->ssh_session));
1845 Curl_safefree(sshc->readdir_filename);
1846 sshc->readdir_filename = NULL;
1847 Curl_safefree(sshc->readdir_longentry);
1848 sshc->readdir_longentry = NULL;
1849 state(conn, SSH_SFTP_CLOSE);
1854 case SSH_SFTP_READDIR_LINK:
1856 libssh2_sftp_symlink_ex(sshc->sftp_session,
1857 sshc->readdir_linkPath,
1858 (unsigned int) strlen(sshc->readdir_linkPath),
1859 sshc->readdir_filename,
1860 PATH_MAX, LIBSSH2_SFTP_READLINK);
1861 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1862 rc = LIBSSH2_ERROR_EAGAIN;
1865 Curl_safefree(sshc->readdir_linkPath);
1866 sshc->readdir_linkPath = NULL;
1867 sshc->readdir_line = realloc(sshc->readdir_line,
1868 sshc->readdir_totalLen + 4 +
1870 if(!sshc->readdir_line) {
1871 Curl_safefree(sshc->readdir_filename);
1872 sshc->readdir_filename = NULL;
1873 Curl_safefree(sshc->readdir_longentry);
1874 sshc->readdir_longentry = NULL;
1875 state(conn, SSH_SFTP_CLOSE);
1876 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1880 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1881 sshc->readdir_currLen,
1882 sshc->readdir_totalLen -
1883 sshc->readdir_currLen,
1885 sshc->readdir_filename);
1887 state(conn, SSH_SFTP_READDIR_BOTTOM);
1890 case SSH_SFTP_READDIR_BOTTOM:
1891 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1892 sshc->readdir_currLen,
1893 sshc->readdir_totalLen -
1894 sshc->readdir_currLen, "\n");
1895 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1897 sshc->readdir_currLen);
1899 if(result == CURLE_OK) {
1901 /* output debug output if that is requested */
1902 if(data->set.verbose) {
1903 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1904 sshc->readdir_currLen, conn);
1906 data->req.bytecount += sshc->readdir_currLen;
1908 Curl_safefree(sshc->readdir_line);
1909 sshc->readdir_line = NULL;
1911 state(conn, SSH_STOP);
1914 state(conn, SSH_SFTP_READDIR);
1917 case SSH_SFTP_READDIR_DONE:
1918 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1919 LIBSSH2_ERROR_EAGAIN) {
1920 rc = LIBSSH2_ERROR_EAGAIN;
1923 sshc->sftp_handle = NULL;
1924 Curl_safefree(sshc->readdir_filename);
1925 sshc->readdir_filename = NULL;
1926 Curl_safefree(sshc->readdir_longentry);
1927 sshc->readdir_longentry = NULL;
1929 /* no data to transfer */
1930 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1931 state(conn, SSH_STOP);
1934 case SSH_SFTP_DOWNLOAD_INIT:
1936 * Work on getting the specified file
1939 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1940 (unsigned int)strlen(sftp_scp->path),
1941 LIBSSH2_FXF_READ, data->set.new_file_perms,
1942 LIBSSH2_SFTP_OPENFILE);
1943 if(!sshc->sftp_handle) {
1944 if(libssh2_session_last_errno(sshc->ssh_session) ==
1945 LIBSSH2_ERROR_EAGAIN) {
1946 rc = LIBSSH2_ERROR_EAGAIN;
1950 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1951 failf(data, "Could not open remote file for reading: %s",
1952 sftp_libssh2_strerror(err));
1953 state(conn, SSH_SFTP_CLOSE);
1954 result = sftp_libssh2_error_to_CURLE(err);
1955 sshc->actualcode = result?result:CURLE_SSH;
1959 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1962 case SSH_SFTP_DOWNLOAD_STAT:
1964 LIBSSH2_SFTP_ATTRIBUTES attrs;
1966 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1967 (unsigned int)strlen(sftp_scp->path),
1968 LIBSSH2_SFTP_STAT, &attrs);
1969 if(rc == LIBSSH2_ERROR_EAGAIN) {
1974 * libssh2_sftp_open() didn't return an error, so maybe the server
1975 * just doesn't support stat()
1977 data->req.size = -1;
1978 data->req.maxdownload = -1;
1981 curl_off_t size = attrs.filesize;
1984 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1985 return CURLE_BAD_DOWNLOAD_RESUME;
1987 if(conn->data->state.use_range) {
1988 curl_off_t from, to;
1992 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1993 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
1995 to=curlx_strtoofft(ptr, &ptr2, 0);
1996 if((ptr == ptr2) /* no "to" value given */
2001 /* from is relative to end of file */
2005 failf(data, "Offset (%"
2006 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2007 from, attrs.filesize);
2008 return CURLE_BAD_DOWNLOAD_RESUME;
2015 size = to - from + 1;
2018 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2020 data->req.size = size;
2021 data->req.maxdownload = size;
2022 Curl_pgrsSetDownloadSize(data, size);
2025 /* We can resume if we can seek to the resume position */
2026 if(data->state.resume_from) {
2027 if(data->state.resume_from < 0) {
2028 /* We're supposed to download the last abs(from) bytes */
2029 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2030 failf(data, "Offset (%"
2031 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2032 data->state.resume_from, attrs.filesize);
2033 return CURLE_BAD_DOWNLOAD_RESUME;
2035 /* download from where? */
2036 data->state.resume_from += attrs.filesize;
2039 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2040 failf(data, "Offset (%" FORMAT_OFF_T
2041 ") was beyond file size (%" FORMAT_OFF_T ")",
2042 data->state.resume_from, attrs.filesize);
2043 return CURLE_BAD_DOWNLOAD_RESUME;
2046 /* Does a completed file need to be seeked and started or closed ? */
2047 /* Now store the number of bytes we are expected to download */
2048 data->req.size = attrs.filesize - data->state.resume_from;
2049 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2050 Curl_pgrsSetDownloadSize(data,
2051 attrs.filesize - data->state.resume_from);
2052 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2055 /* Setup the actual download */
2056 if(data->req.size == 0) {
2057 /* no data to transfer */
2058 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2059 infof(data, "File already completely downloaded\n");
2060 state(conn, SSH_STOP);
2064 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2065 FALSE, NULL, -1, NULL);
2067 /* not set by Curl_setup_transfer to preserve keepon bits */
2068 conn->writesockfd = conn->sockfd;
2070 /* we want to use the _receiving_ function even when the socket turns
2071 out writableable as the underlying libssh2 recv function will deal
2072 with both accordingly */
2073 conn->cselect_bits = CURL_CSELECT_IN;
2076 state(conn, SSH_SFTP_CLOSE);
2077 sshc->actualcode = result;
2080 state(conn, SSH_STOP);
2084 case SSH_SFTP_CLOSE:
2085 if(sshc->sftp_handle) {
2086 rc = libssh2_sftp_close(sshc->sftp_handle);
2087 if(rc == LIBSSH2_ERROR_EAGAIN) {
2091 infof(data, "Failed to close libssh2 file\n");
2093 sshc->sftp_handle = NULL;
2096 Curl_safefree(sftp_scp->path);
2097 sftp_scp->path = NULL;
2100 DEBUGF(infof(data, "SFTP DONE done\n"));
2102 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2103 After nextstate is executed,the control should come back to
2104 SSH_SFTP_CLOSE to pass the correct result back */
2105 if(sshc->nextstate != SSH_NO_STATE) {
2106 state(conn, sshc->nextstate);
2107 sshc->nextstate = SSH_SFTP_CLOSE;
2110 state(conn, SSH_STOP);
2111 result = sshc->actualcode;
2115 case SSH_SFTP_SHUTDOWN:
2116 /* during times we get here due to a broken transfer and then the
2117 sftp_handle might not have been taken down so make sure that is done
2118 before we proceed */
2120 if(sshc->sftp_handle) {
2121 rc = libssh2_sftp_close(sshc->sftp_handle);
2122 if(rc == LIBSSH2_ERROR_EAGAIN) {
2126 infof(data, "Failed to close libssh2 file\n");
2128 sshc->sftp_handle = NULL;
2130 if(sshc->sftp_session) {
2131 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2132 if(rc == LIBSSH2_ERROR_EAGAIN) {
2136 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2138 sshc->sftp_session = NULL;
2141 Curl_safefree(sshc->homedir);
2142 sshc->homedir = NULL;
2143 conn->data->state.most_recent_ftp_entrypath = NULL;
2145 state(conn, SSH_SESSION_DISCONNECT);
2148 case SSH_SCP_TRANS_INIT:
2149 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2151 sshc->actualcode = result;
2152 state(conn, SSH_STOP);
2156 if(data->set.upload) {
2157 if(data->set.infilesize < 0) {
2158 failf(data, "SCP requires a known file size for upload");
2159 sshc->actualcode = CURLE_UPLOAD_FAILED;
2160 state(conn, SSH_SCP_CHANNEL_FREE);
2163 state(conn, SSH_SCP_UPLOAD_INIT);
2166 state(conn, SSH_SCP_DOWNLOAD_INIT);
2170 case SSH_SCP_UPLOAD_INIT:
2172 * libssh2 requires that the destination path is a full path that
2173 * includes the destination file and name OR ends in a "/" . If this is
2174 * not done the destination file will be named the same name as the last
2175 * directory in the path.
2178 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2179 data->set.infilesize);
2180 if(!sshc->ssh_channel) {
2181 if(libssh2_session_last_errno(sshc->ssh_session) ==
2182 LIBSSH2_ERROR_EAGAIN) {
2183 rc = LIBSSH2_ERROR_EAGAIN;
2190 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2191 &err_msg, NULL, 0));
2192 failf(conn->data, "%s", err_msg);
2193 state(conn, SSH_SCP_CHANNEL_FREE);
2194 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2200 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2203 /* not set by Curl_setup_transfer to preserve keepon bits */
2204 conn->sockfd = conn->writesockfd;
2207 state(conn, SSH_SCP_CHANNEL_FREE);
2208 sshc->actualcode = result;
2211 /* we want to use the _sending_ function even when the socket turns
2212 out readable as the underlying libssh2 scp send function will deal
2213 with both accordingly */
2214 conn->cselect_bits = CURL_CSELECT_OUT;
2216 state(conn, SSH_STOP);
2220 case SSH_SCP_DOWNLOAD_INIT:
2223 * We must check the remote file; if it is a directory no values will
2227 curl_off_t bytecount;
2229 /* clear the struct scp recv will fill in */
2230 memset(&sb, 0, sizeof(struct stat));
2232 /* get a fresh new channel from the ssh layer */
2233 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2234 sftp_scp->path, &sb);
2235 if(!sshc->ssh_channel) {
2236 if(libssh2_session_last_errno(sshc->ssh_session) ==
2237 LIBSSH2_ERROR_EAGAIN) {
2238 rc = LIBSSH2_ERROR_EAGAIN;
2245 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2246 &err_msg, NULL, 0));
2247 failf(conn->data, "%s", err_msg);
2248 state(conn, SSH_SCP_CHANNEL_FREE);
2249 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2255 bytecount = (curl_off_t)sb.st_size;
2256 data->req.maxdownload = (curl_off_t)sb.st_size;
2257 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2259 /* not set by Curl_setup_transfer to preserve keepon bits */
2260 conn->writesockfd = conn->sockfd;
2262 /* we want to use the _receiving_ function even when the socket turns
2263 out writableable as the underlying libssh2 recv function will deal
2264 with both accordingly */
2265 conn->cselect_bits = CURL_CSELECT_IN;
2268 state(conn, SSH_SCP_CHANNEL_FREE);
2269 sshc->actualcode = result;
2272 state(conn, SSH_STOP);
2277 if(data->set.upload)
2278 state(conn, SSH_SCP_SEND_EOF);
2280 state(conn, SSH_SCP_CHANNEL_FREE);
2283 case SSH_SCP_SEND_EOF:
2284 if(sshc->ssh_channel) {
2285 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2286 if(rc == LIBSSH2_ERROR_EAGAIN) {
2290 infof(data, "Failed to send libssh2 channel EOF\n");
2293 state(conn, SSH_SCP_WAIT_EOF);
2296 case SSH_SCP_WAIT_EOF:
2297 if(sshc->ssh_channel) {
2298 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2299 if(rc == LIBSSH2_ERROR_EAGAIN) {
2303 infof(data, "Failed to get channel EOF: %d\n", rc);
2306 state(conn, SSH_SCP_WAIT_CLOSE);
2309 case SSH_SCP_WAIT_CLOSE:
2310 if(sshc->ssh_channel) {
2311 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2312 if(rc == LIBSSH2_ERROR_EAGAIN) {
2316 infof(data, "Channel failed to close: %d\n", rc);
2319 state(conn, SSH_SCP_CHANNEL_FREE);
2322 case SSH_SCP_CHANNEL_FREE:
2323 if(sshc->ssh_channel) {
2324 rc = libssh2_channel_free(sshc->ssh_channel);
2325 if(rc == LIBSSH2_ERROR_EAGAIN) {
2329 infof(data, "Failed to free libssh2 scp subsystem\n");
2331 sshc->ssh_channel = NULL;
2333 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2335 state(conn, SSH_SESSION_DISCONNECT);
2337 state(conn, SSH_STOP);
2338 result = sshc->actualcode;
2341 case SSH_SESSION_DISCONNECT:
2342 /* during weird times when we've been prematurely aborted, the channel
2343 is still alive when we reach this state and we MUST kill the channel
2345 if(sshc->ssh_channel) {
2346 rc = libssh2_channel_free(sshc->ssh_channel);
2347 if(rc == LIBSSH2_ERROR_EAGAIN) {
2351 infof(data, "Failed to free libssh2 scp subsystem\n");
2353 sshc->ssh_channel = NULL;
2356 if(sshc->ssh_session) {
2357 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2358 if(rc == LIBSSH2_ERROR_EAGAIN) {
2362 infof(data, "Failed to disconnect libssh2 session\n");
2366 Curl_safefree(sshc->homedir);
2367 sshc->homedir = NULL;
2368 conn->data->state.most_recent_ftp_entrypath = NULL;
2370 state(conn, SSH_SESSION_FREE);
2373 case SSH_SESSION_FREE:
2374 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2376 libssh2_knownhost_free(sshc->kh);
2381 if(sshc->ssh_session) {
2382 rc = libssh2_session_free(sshc->ssh_session);
2383 if(rc == LIBSSH2_ERROR_EAGAIN) {
2387 infof(data, "Failed to free libssh2 session\n");
2389 sshc->ssh_session = NULL;
2391 conn->bits.close = TRUE;
2392 sshc->nextstate = SSH_NO_STATE;
2393 state(conn, SSH_STOP);
2394 result = sshc->actualcode;
2398 /* fallthrough, just stop! */
2400 /* internal error */
2401 sshc->nextstate = SSH_NO_STATE;
2402 state(conn, SSH_STOP);
2406 } while(!rc && (sshc->state != SSH_STOP));
2408 if(rc == LIBSSH2_ERROR_EAGAIN) {
2409 /* we would block, we need to wait for the socket to be ready (in the
2410 right direction too)! */
2417 /* called by the multi interface to figure out what socket(s) to wait for and
2418 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2419 static int ssh_perform_getsock(const struct connectdata *conn,
2420 curl_socket_t *sock, /* points to numsocks
2421 number of sockets */
2424 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2425 int bitmap = GETSOCK_BLANK;
2428 sock[0] = conn->sock[FIRSTSOCKET];
2430 if(conn->waitfor & KEEP_RECV)
2431 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2433 if(conn->waitfor & KEEP_SEND)
2434 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2438 /* if we don't know the direction we can use the generic *_getsock()
2439 function even for the protocol_connect and doing states */
2440 return Curl_single_getsock(conn, sock, numsocks);
2444 /* Generic function called by the multi interface to figure out what socket(s)
2445 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2446 static int ssh_getsock(struct connectdata *conn,
2447 curl_socket_t *sock, /* points to numsocks number
2451 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2455 /* if we don't know any direction we can just play along as we used to and
2456 not provide any sensible info */
2457 return GETSOCK_BLANK;
2459 /* if we know the direction we can use the generic *_getsock() function even
2460 for the protocol_connect and doing states */
2461 return ssh_perform_getsock(conn, sock, numsocks);
2465 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2467 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2468 * function is used to figure out in what direction and stores this info so
2469 * that the multi interface can take advantage of it. Make sure to call this
2470 * function in all cases so that when it _doesn't_ return EAGAIN we can
2471 * restore the default wait bits.
2473 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2475 struct ssh_conn *sshc = &conn->proto.sshc;
2479 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2480 /* translate the libssh2 define bits into our own bit defines */
2481 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2482 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2485 /* It didn't block or libssh2 didn't reveal in which direction, put back
2487 conn->waitfor = sshc->orig_waitfor;
2490 /* no libssh2 directional support so we simply don't know */
2491 #define ssh_block2waitfor(x,y)
2494 /* called repeatedly until done from multi.c */
2495 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2497 struct ssh_conn *sshc = &conn->proto.sshc;
2498 CURLcode result = CURLE_OK;
2499 bool block; /* we store the status and use that to provide a ssh_getsock()
2502 result = ssh_statemach_act(conn, &block);
2503 *done = (bool)(sshc->state == SSH_STOP);
2504 ssh_block2waitfor(conn, block);
2509 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2512 struct ssh_conn *sshc = &conn->proto.sshc;
2513 CURLcode result = CURLE_OK;
2514 struct SessionHandle *data = conn->data;
2516 while((sshc->state != SSH_STOP) && !result) {
2520 result = ssh_statemach_act(conn, &block);
2524 if(Curl_pgrsUpdate(conn))
2525 return CURLE_ABORTED_BY_CALLBACK;
2527 struct timeval now = Curl_tvnow();
2528 result = Curl_speedcheck(data, now);
2533 left = Curl_timeleft(data, NULL, duringconnect);
2535 failf(data, "Operation timed out\n");
2536 return CURLE_OPERATION_TIMEDOUT;
2539 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2540 if((CURLE_OK == result) && block) {
2541 int dir = libssh2_session_block_directions(sshc->ssh_session);
2542 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2543 curl_socket_t fd_read = CURL_SOCKET_BAD;
2544 curl_socket_t fd_write = CURL_SOCKET_BAD;
2545 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2547 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2549 /* wait for the socket to become ready */
2550 Curl_socket_ready(fd_read, fd_write,
2551 (int)(left>1000?1000:left)); /* ignore result */
2561 * SSH setup and connection
2563 static CURLcode ssh_init(struct connectdata *conn)
2565 struct SessionHandle *data = conn->data;
2566 struct SSHPROTO *ssh;
2567 struct ssh_conn *sshc = &conn->proto.sshc;
2569 sshc->actualcode = CURLE_OK; /* reset error code */
2570 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2573 if(data->state.proto.ssh)
2576 ssh = calloc(1, sizeof(struct SSHPROTO));
2578 return CURLE_OUT_OF_MEMORY;
2580 data->state.proto.ssh = ssh;
2585 static Curl_recv scp_recv, sftp_recv;
2586 static Curl_send scp_send, sftp_send;
2589 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2590 * do protocol-specific actions at connect-time.
2592 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2594 #ifdef CURL_LIBSSH2_DEBUG
2597 struct ssh_conn *ssh;
2599 struct SessionHandle *data = conn->data;
2601 /* We default to persistent connections. We set this already in this connect
2602 function to make the re-use checks properly be able to check this bit. */
2603 conn->bits.close = FALSE;
2605 /* If there already is a protocol-specific struct allocated for this
2606 sessionhandle, deal with it */
2607 Curl_reset_reqproto(conn);
2609 result = ssh_init(conn);
2613 if(conn->handler->protocol & CURLPROTO_SCP) {
2614 conn->recv[FIRSTSOCKET] = scp_recv;
2615 conn->send[FIRSTSOCKET] = scp_send;
2618 conn->recv[FIRSTSOCKET] = sftp_recv;
2619 conn->send[FIRSTSOCKET] = sftp_send;
2621 ssh = &conn->proto.sshc;
2623 #ifdef CURL_LIBSSH2_DEBUG
2625 infof(data, "User: %s\n", conn->user);
2628 infof(data, "Password: %s\n", conn->passwd);
2630 sock = conn->sock[FIRSTSOCKET];
2631 #endif /* CURL_LIBSSH2_DEBUG */
2633 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2635 my_libssh2_realloc, conn);
2636 if(ssh->ssh_session == NULL) {
2637 failf(data, "Failure initialising ssh session");
2638 return CURLE_FAILED_INIT;
2641 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2642 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2644 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2646 /* eeek. TODO: free the ssh_session! */
2647 return CURLE_FAILED_INIT;
2650 /* read all known hosts from there */
2651 rc = libssh2_knownhost_readfile(ssh->kh,
2652 data->set.str[STRING_SSH_KNOWNHOSTS],
2653 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2655 infof(data, "Failed to read known hosts from %s\n",
2656 data->set.str[STRING_SSH_KNOWNHOSTS]);
2658 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2660 #ifdef CURL_LIBSSH2_DEBUG
2661 libssh2_trace(ssh->ssh_session, ~0);
2662 infof(data, "SSH socket: %d\n", (int)sock);
2663 #endif /* CURL_LIBSSH2_DEBUG */
2665 state(conn, SSH_INIT);
2667 if(data->state.used_interface == Curl_if_multi)
2668 result = ssh_multi_statemach(conn, done);
2670 result = ssh_easy_statemach(conn, TRUE);
2679 ***********************************************************************
2683 * This is the actual DO function for SCP. Get a file according to
2684 * the options previously setup.
2688 CURLcode scp_perform(struct connectdata *conn,
2692 CURLcode result = CURLE_OK;
2694 DEBUGF(infof(conn->data, "DO phase starts\n"));
2696 *dophase_done = FALSE; /* not done yet */
2698 /* start the first command in the DO phase */
2699 state(conn, SSH_SCP_TRANS_INIT);
2701 /* run the state-machine */
2702 if(conn->data->state.used_interface == Curl_if_multi) {
2703 result = ssh_multi_statemach(conn, dophase_done);
2706 result = ssh_easy_statemach(conn, FALSE);
2707 *dophase_done = TRUE; /* with the easy interface we are done here */
2709 *connected = conn->bits.tcpconnect;
2712 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2718 /* called from multi.c while DOing */
2719 static CURLcode scp_doing(struct connectdata *conn,
2723 result = ssh_multi_statemach(conn, dophase_done);
2726 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2732 * The DO function is generic for both protocols. There was previously two
2733 * separate ones but this way means less duplicated code.
2736 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2740 struct SessionHandle *data = conn->data;
2742 *done = FALSE; /* default to false */
2745 Since connections can be re-used between SessionHandles, this might be a
2746 connection already existing but on a fresh SessionHandle struct so we must
2747 make sure we have a good 'struct SSHPROTO' to play with. For new
2748 connections, the struct SSHPROTO is allocated and setup in the
2749 ssh_connect() function.
2751 Curl_reset_reqproto(conn);
2752 res = ssh_init(conn);
2756 data->req.size = -1; /* make sure this is unknown at this point */
2758 Curl_pgrsSetUploadCounter(data, 0);
2759 Curl_pgrsSetDownloadCounter(data, 0);
2760 Curl_pgrsSetUploadSize(data, 0);
2761 Curl_pgrsSetDownloadSize(data, 0);
2763 if(conn->handler->protocol & CURLPROTO_SCP)
2764 res = scp_perform(conn, &connected, done);
2766 res = sftp_perform(conn, &connected, done);
2771 /* BLOCKING, but the function is using the state machine so the only reason
2772 this is still blocking is that the multi interface code has no support for
2773 disconnecting operations that takes a while */
2774 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2776 CURLcode result = CURLE_OK;
2777 struct ssh_conn *ssh = &conn->proto.sshc;
2778 (void) dead_connection;
2780 Curl_safefree(conn->data->state.proto.ssh);
2781 conn->data->state.proto.ssh = NULL;
2783 if(ssh->ssh_session) {
2784 /* only if there's a session still around to use! */
2786 state(conn, SSH_SESSION_DISCONNECT);
2788 result = ssh_easy_statemach(conn, FALSE);
2794 /* generic done function for both SCP and SFTP called from their specific
2796 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2798 CURLcode result = CURLE_OK;
2799 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2801 if(status == CURLE_OK) {
2802 /* run the state-machine
2804 TODO: when the multi interface is used, this _really_ should be using
2805 the ssh_multi_statemach function but we have no general support for
2806 non-blocking DONE operations, not in the multi state machine and with
2807 Curl_done() invokes on several places in the code!
2809 result = ssh_easy_statemach(conn, FALSE);
2815 Curl_safefree(sftp_scp->path);
2816 sftp_scp->path = NULL;
2818 Curl_pgrsDone(conn);
2820 conn->data->req.keepon = 0; /* clear all bits */
2825 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2828 (void)premature; /* not used */
2830 if(status == CURLE_OK)
2831 state(conn, SSH_SCP_DONE);
2833 return ssh_done(conn, status);
2837 /* return number of received (decrypted) bytes */
2838 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2839 const void *mem, size_t len, CURLcode *err)
2842 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2844 /* libssh2_channel_write() returns int! */
2846 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2848 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2850 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2859 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2860 * a regular CURLcode value.
2862 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2863 char *mem, size_t len, CURLcode *err)
2866 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2868 /* libssh2_channel_read() returns int */
2870 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2872 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2873 if(nread == LIBSSH2_ERROR_EAGAIN) {
2882 * =============== SFTP ===============
2886 ***********************************************************************
2890 * This is the actual DO function for SFTP. Get a file/directory according to
2891 * the options previously setup.
2895 CURLcode sftp_perform(struct connectdata *conn,
2899 CURLcode result = CURLE_OK;
2901 DEBUGF(infof(conn->data, "DO phase starts\n"));
2903 *dophase_done = FALSE; /* not done yet */
2905 /* start the first command in the DO phase */
2906 state(conn, SSH_SFTP_QUOTE_INIT);
2908 /* run the state-machine */
2909 if(conn->data->state.used_interface == Curl_if_multi) {
2910 result = ssh_multi_statemach(conn, dophase_done);
2913 result = ssh_easy_statemach(conn, FALSE);
2914 *dophase_done = TRUE; /* with the easy interface we are done here */
2916 *connected = conn->bits.tcpconnect;
2919 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2925 /* called from multi.c while DOing */
2926 static CURLcode sftp_doing(struct connectdata *conn,
2930 result = ssh_multi_statemach(conn, dophase_done);
2933 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2938 /* BLOCKING, but the function is using the state machine so the only reason
2939 this is still blocking is that the multi interface code has no support for
2940 disconnecting operations that takes a while */
2941 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
2943 CURLcode result = CURLE_OK;
2944 (void) dead_connection;
2946 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2948 Curl_safefree(conn->data->state.proto.ssh);
2949 conn->data->state.proto.ssh = NULL;
2951 if(conn->proto.sshc.ssh_session) {
2952 /* only if there's a session still around to use! */
2953 state(conn, SSH_SFTP_SHUTDOWN);
2954 result = ssh_easy_statemach(conn, FALSE);
2957 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2963 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2966 struct ssh_conn *sshc = &conn->proto.sshc;
2968 if(status == CURLE_OK) {
2969 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
2970 errors that could happen due to open file handles during POSTQUOTE
2972 if(!status && !premature && conn->data->set.postquote) {
2973 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
2974 state(conn, SSH_SFTP_CLOSE);
2977 state(conn, SSH_SFTP_CLOSE);
2979 return ssh_done(conn, status);
2982 /* return number of sent bytes */
2983 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
2984 const void *mem, size_t len, CURLcode *err)
2986 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2987 but is changed to ssize_t in 0.15. These days we don't
2988 support libssh2 0.15*/
2991 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2993 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2995 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3004 * Return number of received (decrypted) bytes
3006 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3007 char *mem, size_t len, CURLcode *err)
3012 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3014 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3016 if(nread == LIBSSH2_ERROR_EAGAIN) {
3023 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3026 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3028 * Permission to use, copy, modify, and distribute this software for any
3029 * purpose with or without fee is hereby granted, provided that the above
3030 * copyright notice and this permission notice appear in all copies.
3032 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3033 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3034 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3035 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3036 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3037 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3038 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3041 get_pathname(const char **cpp, char **path)
3043 const char *cp = *cpp, *end;
3046 static const char WHITESPACE[] = " \t\r\n";
3048 cp += strspn(cp, WHITESPACE);
3052 return CURLE_QUOTE_ERROR;
3055 *path = malloc(strlen(cp) + 1);
3057 return CURLE_OUT_OF_MEMORY;
3059 /* Check for quoted filenames */
3060 if(*cp == '\"' || *cp == '\'') {
3063 /* Search for terminating quote, unescape some chars */
3064 for(i = j = 0; i <= strlen(cp); i++) {
3065 if(cp[i] == quot) { /* Found quote */
3070 if(cp[i] == '\0') { /* End of string */
3071 /*error("Unterminated quote");*/
3074 if(cp[i] == '\\') { /* Escaped characters */
3076 if(cp[i] != '\'' && cp[i] != '\"' &&
3078 /*error("Bad escaped character '\\%c'",
3083 (*path)[j++] = cp[i];
3087 /*error("Empty quotes");*/
3090 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3093 /* Read to end of filename */
3094 end = strpbrk(cp, WHITESPACE);
3096 end = strchr(cp, '\0');
3097 *cpp = end + strspn(end, WHITESPACE);
3099 memcpy(*path, cp, end - cp);
3100 (*path)[end - cp] = '\0';
3105 Curl_safefree(*path);
3107 return CURLE_QUOTE_ERROR;
3111 static const char *sftp_libssh2_strerror(unsigned long err)
3114 case LIBSSH2_FX_NO_SUCH_FILE:
3115 return "No such file or directory";
3117 case LIBSSH2_FX_PERMISSION_DENIED:
3118 return "Permission denied";
3120 case LIBSSH2_FX_FAILURE:
3121 return "Operation failed";
3123 case LIBSSH2_FX_BAD_MESSAGE:
3124 return "Bad message from SFTP server";
3126 case LIBSSH2_FX_NO_CONNECTION:
3127 return "Not connected to SFTP server";
3129 case LIBSSH2_FX_CONNECTION_LOST:
3130 return "Connection to SFTP server lost";
3132 case LIBSSH2_FX_OP_UNSUPPORTED:
3133 return "Operation not supported by SFTP server";
3135 case LIBSSH2_FX_INVALID_HANDLE:
3136 return "Invalid handle";
3138 case LIBSSH2_FX_NO_SUCH_PATH:
3139 return "No such file or directory";
3141 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3142 return "File already exists";
3144 case LIBSSH2_FX_WRITE_PROTECT:
3145 return "File is write protected";
3147 case LIBSSH2_FX_NO_MEDIA:
3150 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3153 case LIBSSH2_FX_QUOTA_EXCEEDED:
3154 return "User quota exceeded";
3156 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3157 return "Unknown principle";
3159 case LIBSSH2_FX_LOCK_CONFlICT:
3160 return "File lock conflict";
3162 case LIBSSH2_FX_DIR_NOT_EMPTY:
3163 return "Directory not empty";
3165 case LIBSSH2_FX_NOT_A_DIRECTORY:
3166 return "Not a directory";
3168 case LIBSSH2_FX_INVALID_FILENAME:
3169 return "Invalid filename";
3171 case LIBSSH2_FX_LINK_LOOP:
3172 return "Link points to itself";
3174 return "Unknown error in libssh2";
3177 #endif /* USE_LIBSSH2 */