1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 /* #define CURL_LIBSSH2_DEBUG */
38 #include <libssh2_sftp.h>
53 #ifdef HAVE_SYS_SOCKET_H
54 #include <sys/socket.h>
56 #ifdef HAVE_NETINET_IN_H
57 #include <netinet/in.h>
59 #ifdef HAVE_ARPA_INET_H
60 #include <arpa/inet.h>
63 #include <sys/utsname.h>
74 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
76 #define in_addr_t unsigned long
79 #include <curl/curl.h>
82 #include "easyif.h" /* for Curl_convert_... prototypes */
88 #include "http.h" /* for HTTP proxy tunnel stuff */
91 #include "speedcheck.h"
98 #include "inet_ntop.h"
99 #include "parsedate.h" /* for the week day and month names */
100 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
101 #include "strtoofft.h"
104 #include "warnless.h"
106 #define _MPRINTF_REPLACE /* use our functions only */
107 #include <curl/mprintf.h>
109 #include "curl_memory.h"
110 /* The last #include file should be: */
111 #include "memdebug.h"
114 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
115 have their definition hidden well */
118 /* Local functions: */
119 static const char *sftp_libssh2_strerror(unsigned long err);
120 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
121 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
122 static LIBSSH2_FREE_FUNC(my_libssh2_free);
124 static CURLcode get_pathname(const char **cpp, char **path);
126 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
127 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
128 static CURLcode ssh_do(struct connectdata *conn, bool *done);
130 static CURLcode ssh_getworkingpath(struct connectdata *conn,
131 char *homedir, /* when SFTP is used */
134 static CURLcode scp_done(struct connectdata *conn,
135 CURLcode, bool premature);
136 static CURLcode scp_doing(struct connectdata *conn,
138 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
140 static CURLcode sftp_done(struct connectdata *conn,
141 CURLcode, bool premature);
142 static CURLcode sftp_doing(struct connectdata *conn,
144 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection);
146 CURLcode sftp_perform(struct connectdata *conn,
150 static int ssh_getsock(struct connectdata *conn,
151 curl_socket_t *sock, /* points to numsocks number
155 static int ssh_perform_getsock(const struct connectdata *conn,
156 curl_socket_t *sock, /* points to numsocks
161 * SCP protocol handler.
164 const struct Curl_handler Curl_handler_scp = {
166 ZERO_NULL, /* setup_connection */
169 ZERO_NULL, /* do_more */
170 ssh_connect, /* connect_it */
171 ssh_multi_statemach, /* connecting */
172 scp_doing, /* doing */
173 ssh_getsock, /* proto_getsock */
174 ssh_getsock, /* doing_getsock */
175 ssh_perform_getsock, /* perform_getsock */
176 scp_disconnect, /* disconnect */
177 PORT_SSH, /* defport */
178 PROT_SCP /* protocol */
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 PORT_SSH, /* defport */
200 PROT_SFTP /* protocol */
205 kbd_callback(const char *name, int name_len, const char *instruction,
206 int instruction_len, int num_prompts,
207 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
208 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
211 struct connectdata *conn = (struct connectdata *)*abstract;
213 #ifdef CURL_LIBSSH2_DEBUG
214 fprintf(stderr, "name=%s\n", name);
215 fprintf(stderr, "name_len=%d\n", name_len);
216 fprintf(stderr, "instruction=%s\n", instruction);
217 fprintf(stderr, "instruction_len=%d\n", instruction_len);
218 fprintf(stderr, "num_prompts=%d\n", num_prompts);
223 (void)instruction_len;
224 #endif /* CURL_LIBSSH2_DEBUG */
225 if(num_prompts == 1) {
226 responses[0].text = strdup(conn->passwd);
227 responses[0].length = (unsigned int)strlen(conn->passwd);
233 static CURLcode sftp_libssh2_error_to_CURLE(int err)
239 case LIBSSH2_FX_NO_SUCH_FILE:
240 case LIBSSH2_FX_NO_SUCH_PATH:
241 return CURLE_REMOTE_FILE_NOT_FOUND;
243 case LIBSSH2_FX_PERMISSION_DENIED:
244 case LIBSSH2_FX_WRITE_PROTECT:
245 case LIBSSH2_FX_LOCK_CONFlICT:
246 return CURLE_REMOTE_ACCESS_DENIED;
248 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
249 case LIBSSH2_FX_QUOTA_EXCEEDED:
250 return CURLE_REMOTE_DISK_FULL;
252 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
253 return CURLE_REMOTE_FILE_EXISTS;
255 case LIBSSH2_FX_DIR_NOT_EMPTY:
256 return CURLE_QUOTE_ERROR;
265 static CURLcode libssh2_session_error_to_CURLE(int err)
268 /* Ordered by order of appearance in libssh2.h */
269 case LIBSSH2_ERROR_NONE:
272 case LIBSSH2_ERROR_SOCKET_NONE:
273 return CURLE_COULDNT_CONNECT;
275 case LIBSSH2_ERROR_ALLOC:
276 return CURLE_OUT_OF_MEMORY;
278 case LIBSSH2_ERROR_SOCKET_SEND:
279 return CURLE_SEND_ERROR;
281 case LIBSSH2_ERROR_HOSTKEY_INIT:
282 case LIBSSH2_ERROR_HOSTKEY_SIGN:
283 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
284 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
285 return CURLE_PEER_FAILED_VERIFICATION;
287 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
288 return CURLE_LOGIN_DENIED;
290 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
291 case LIBSSH2_ERROR_TIMEOUT:
292 return CURLE_OPERATION_TIMEDOUT;
294 case LIBSSH2_ERROR_EAGAIN:
298 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
299 error code, and possibly add a few new SSH-related one. We must however
300 not return or even depend on libssh2 errors in the public libcurl API */
305 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
307 (void)abstract; /* arg not used */
308 return malloc(count);
311 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
313 (void)abstract; /* arg not used */
314 return realloc(ptr, count);
317 static LIBSSH2_FREE_FUNC(my_libssh2_free)
319 (void)abstract; /* arg not used */
324 * SSH State machine related code
326 /* This is the ONLY way to change SSH state! */
327 static void state(struct connectdata *conn, sshstate nowstate)
329 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
330 /* for debug purposes */
331 static const char * const names[] = {
336 "SSH_AUTH_PKEY_INIT",
338 "SSH_AUTH_PASS_INIT",
340 "SSH_AUTH_HOST_INIT",
347 "SSH_SFTP_QUOTE_INIT",
348 "SSH_SFTP_POSTQUOTE_INIT",
350 "SSH_SFTP_NEXT_QUOTE",
351 "SSH_SFTP_QUOTE_STAT",
352 "SSH_SFTP_QUOTE_SETSTAT",
353 "SSH_SFTP_QUOTE_SYMLINK",
354 "SSH_SFTP_QUOTE_MKDIR",
355 "SSH_SFTP_QUOTE_RENAME",
356 "SSH_SFTP_QUOTE_RMDIR",
357 "SSH_SFTP_QUOTE_UNLINK",
358 "SSH_SFTP_TRANS_INIT",
359 "SSH_SFTP_UPLOAD_INIT",
360 "SSH_SFTP_CREATE_DIRS_INIT",
361 "SSH_SFTP_CREATE_DIRS",
362 "SSH_SFTP_CREATE_DIRS_MKDIR",
363 "SSH_SFTP_READDIR_INIT",
365 "SSH_SFTP_READDIR_LINK",
366 "SSH_SFTP_READDIR_BOTTOM",
367 "SSH_SFTP_READDIR_DONE",
368 "SSH_SFTP_DOWNLOAD_INIT",
369 "SSH_SFTP_DOWNLOAD_STAT",
372 "SSH_SCP_TRANS_INIT",
373 "SSH_SCP_UPLOAD_INIT",
374 "SSH_SCP_DOWNLOAD_INIT",
378 "SSH_SCP_WAIT_CLOSE",
379 "SSH_SCP_CHANNEL_FREE",
380 "SSH_SESSION_DISCONNECT",
385 struct ssh_conn *sshc = &conn->proto.sshc;
387 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
388 if(sshc->state != nowstate) {
389 infof(conn->data, "SFTP %p state change from %s to %s\n",
390 sshc, names[sshc->state], names[nowstate]);
394 sshc->state = nowstate;
397 /* figure out the path to work with in this particular request */
398 static CURLcode ssh_getworkingpath(struct connectdata *conn,
399 char *homedir, /* when SFTP is used */
400 char **path) /* returns the allocated
401 real path to work with */
403 struct SessionHandle *data = conn->data;
404 char *real_path = NULL;
406 int working_path_len;
408 working_path = curl_easy_unescape(data, data->state.path, 0,
411 return CURLE_OUT_OF_MEMORY;
413 /* Check for /~/ , indicating relative to the user's home directory */
414 if(conn->protocol & PROT_SCP) {
415 real_path = malloc(working_path_len+1);
416 if(real_path == NULL) {
418 return CURLE_OUT_OF_MEMORY;
420 if((working_path_len > 1) && (working_path[1] == '~'))
421 /* It is referenced to the home directory, so strip the leading '/' */
422 memcpy(real_path, working_path+1, 1 + working_path_len-1);
424 memcpy(real_path, working_path, 1 + working_path_len);
426 else if(conn->protocol & PROT_SFTP) {
427 if((working_path_len > 1) && (working_path[1] == '~')) {
428 size_t homelen = strlen(homedir);
429 real_path = malloc(homelen + working_path_len + 1);
430 if(real_path == NULL) {
432 return CURLE_OUT_OF_MEMORY;
434 /* It is referenced to the home directory, so strip the
436 memcpy(real_path, homedir, homelen);
437 real_path[homelen] = '/';
438 real_path[homelen+1] = '\0';
439 if(working_path_len > 3) {
440 memcpy(real_path+homelen+1, working_path + 3,
441 1 + working_path_len -3);
445 real_path = malloc(working_path_len+1);
446 if(real_path == NULL) {
448 return CURLE_OUT_OF_MEMORY;
450 memcpy(real_path, working_path, 1+working_path_len);
456 /* store the pointer for the caller to receive */
462 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
463 static int sshkeycallback(CURL *easy,
464 const struct curl_khkey *knownkey, /* known */
465 const struct curl_khkey *foundkey, /* found */
466 enum curl_khmatch match,
474 /* we only allow perfect matches, and we reject everything else */
475 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
480 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
483 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
484 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
486 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
490 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
491 * architectures so we check of the necessary function is present.
493 #ifndef HAVE_LIBSSH2_SCP_SEND64
494 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
496 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
497 (libssh2_uint64_t)d, 0, 0)
501 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
503 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
504 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
508 * ssh_statemach_act() runs the SSH state machine as far as it can without
509 * blocking and without reaching the end. The data the pointer 'block' points
510 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
511 * meaning it wants to be called again when the socket is ready
514 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
516 CURLcode result = CURLE_OK;
517 struct SessionHandle *data = conn->data;
518 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
519 struct ssh_conn *sshc = &conn->proto.sshc;
520 curl_socket_t sock = conn->sock[FIRSTSOCKET];
521 #ifdef CURL_LIBSSH2_DEBUG
522 const char *fingerprint;
523 #endif /* CURL_LIBSSH2_DEBUG */
524 const char *host_public_key_md5;
525 int rc = LIBSSH2_ERROR_NONE, i;
527 int seekerr = CURL_SEEKFUNC_OK;
528 *block = 0; /* we're not blocking by default */
532 switch(sshc->state) {
534 sshc->secondCreateDirs = 0;
535 sshc->nextstate = SSH_NO_STATE;
536 sshc->actualcode = CURLE_OK;
538 rc = libssh2_session_startup(sshc->ssh_session, sock);
539 if(rc == LIBSSH2_ERROR_EAGAIN) {
543 failf(data, "Failure establishing ssh session");
544 state(conn, SSH_SESSION_FREE);
545 sshc->actualcode = CURLE_FAILED_INIT;
549 /* Set libssh2 to non-blocking, since everything internally is
551 libssh2_session_set_blocking(sshc->ssh_session, 0);
553 state(conn, SSH_HOSTKEY);
558 #ifdef CURL_LIBSSH2_DEBUG
560 * Before we authenticate we should check the hostkey's fingerprint
561 * against our known hosts. How that is handled (reading from file,
562 * whatever) is up to us. As for know not much is implemented, besides
563 * showing how to get the fingerprint.
565 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
566 LIBSSH2_HOSTKEY_HASH_MD5);
568 /* The fingerprint points to static storage (!), don't free() it. */
569 infof(data, "Fingerprint: ");
570 for (rc = 0; rc < 16; rc++) {
571 infof(data, "%02X ", (unsigned char) fingerprint[rc]);
574 #endif /* CURL_LIBSSH2_DEBUG */
576 /* Before we authenticate we check the hostkey's MD5 fingerprint
577 * against a known fingerprint, if available. This implementation pulls
578 * it from the curl option.
580 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
581 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
583 host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
584 LIBSSH2_HOSTKEY_HASH_MD5);
585 for (i = 0; i < 16; i++)
586 snprintf(&buf[i*2], 3, "%02x",
587 (unsigned char) host_public_key_md5[i]);
588 if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
590 "Denied establishing ssh session: mismatch md5 fingerprint. "
591 "Remote %s is not equal to %s",
592 buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
593 state(conn, SSH_SESSION_FREE);
594 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
599 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
600 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
601 /* we're asked to verify the host against a file */
604 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
611 * A subject to figure out is what host name we need to pass in here.
612 * What host name does OpenSSH store in its file if an IDN name is
615 struct libssh2_knownhost *host;
616 enum curl_khmatch keymatch;
617 curl_sshkeycallback func =
618 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
619 struct curl_khkey knownkey;
620 struct curl_khkey *knownkeyp = NULL;
621 struct curl_khkey foundkey;
623 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
624 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
626 keycheck = libssh2_knownhost_check(sshc->kh,
629 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
630 LIBSSH2_KNOWNHOST_KEYENC_RAW|
634 infof(data, "SSH host check: %d, key: %s\n", keycheck,
635 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
638 /* setup 'knownkey' */
639 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
640 knownkey.key = host->key;
642 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
643 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
644 knownkeyp = &knownkey;
647 /* setup 'foundkey' */
648 foundkey.key = remotekey;
649 foundkey.len = keylen;
650 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
651 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
654 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
655 * curl_khmatch enum are ever modified, we need to introduce a
656 * translation table here!
658 keymatch = (enum curl_khmatch)keycheck;
660 /* Ask the callback how to behave */
661 rc = func(data, knownkeyp, /* from the knownhosts file */
662 &foundkey, /* from the remote host */
663 keymatch, data->set.ssh_keyfunc_userp);
666 /* no remotekey means failure! */
667 rc = CURLKHSTAT_REJECT;
670 default: /* unknown return codes will equal reject */
671 case CURLKHSTAT_REJECT:
672 state(conn, SSH_SESSION_FREE);
673 case CURLKHSTAT_DEFER:
674 /* DEFER means bail out but keep the SSH_HOSTKEY state */
675 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
677 case CURLKHSTAT_FINE:
678 case CURLKHSTAT_FINE_ADD_TO_FILE:
680 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
681 /* the found host+key didn't match but has been told to be fine
682 anyway so we add it in memory */
683 int addrc = libssh2_knownhost_add(sshc->kh,
684 conn->host.name, NULL,
686 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
687 LIBSSH2_KNOWNHOST_KEYENC_RAW|
690 infof(data, "Warning adding the known host %s failed!\n",
692 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
693 /* now we write the entire in-memory list of known hosts to the
696 libssh2_knownhost_writefile(sshc->kh,
697 data->set.str[STRING_SSH_KNOWNHOSTS],
698 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
700 infof(data, "Warning, writing %s failed!\n",
701 data->set.str[STRING_SSH_KNOWNHOSTS]);
708 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
710 state(conn, SSH_AUTHLIST);
715 * Figure out authentication methods
716 * NB: As soon as we have provided a username to an openssh server we
717 * must never change it later. Thus, always specify the correct username
718 * here, even though the libssh2 docs kind of indicate that it should be
719 * possible to get a 'generic' list (not user-specific) of authentication
720 * methods, presumably with a blank username. That won't work in my
722 * So always specify it here.
724 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
726 (unsigned int)strlen(conn->user));
728 if(!sshc->authlist) {
729 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
730 LIBSSH2_ERROR_EAGAIN) {
731 rc = LIBSSH2_ERROR_EAGAIN;
735 state(conn, SSH_SESSION_FREE);
736 sshc->actualcode = libssh2_session_error_to_CURLE(err);
740 infof(data, "SSH authentication methods available: %s\n",
743 state(conn, SSH_AUTH_PKEY_INIT);
746 case SSH_AUTH_PKEY_INIT:
748 * Check the supported auth types in the order I feel is most secure
749 * with the requested type of authentication
751 sshc->authed = FALSE;
753 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
754 (strstr(sshc->authlist, "publickey") != NULL)) {
757 sshc->rsa_pub = sshc->rsa = NULL;
759 /* To ponder about: should really the lib be messing about with the
760 HOME environment variable etc? */
761 home = curl_getenv("HOME");
763 if(data->set.str[STRING_SSH_PUBLIC_KEY])
764 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
766 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
768 /* as a final resort, try current dir! */
769 sshc->rsa_pub = strdup("id_dsa.pub");
771 if(sshc->rsa_pub == NULL) {
774 state(conn, SSH_SESSION_FREE);
775 sshc->actualcode = CURLE_OUT_OF_MEMORY;
779 if(data->set.str[STRING_SSH_PRIVATE_KEY])
780 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
782 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
784 /* as a final resort, try current dir! */
785 sshc->rsa = strdup("id_dsa");
787 if(sshc->rsa == NULL) {
790 Curl_safefree(sshc->rsa_pub);
791 sshc->rsa_pub = NULL;
792 state(conn, SSH_SESSION_FREE);
793 sshc->actualcode = CURLE_OUT_OF_MEMORY;
797 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
798 if(!sshc->passphrase)
799 sshc->passphrase = "";
804 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
805 infof(data, "Using ssh private key file %s\n", sshc->rsa);
807 state(conn, SSH_AUTH_PKEY);
810 state(conn, SSH_AUTH_PASS_INIT);
815 /* The function below checks if the files exists, no need to stat() here.
817 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
822 sshc->rsa, sshc->passphrase);
823 if(rc == LIBSSH2_ERROR_EAGAIN) {
827 Curl_safefree(sshc->rsa_pub);
828 sshc->rsa_pub = NULL;
829 Curl_safefree(sshc->rsa);
834 infof(data, "Initialized SSH public key authentication\n");
835 state(conn, SSH_AUTH_DONE);
839 (void)libssh2_session_last_error(sshc->ssh_session,
841 infof(data, "SSH public key authentication failed: %s\n", err_msg);
842 state(conn, SSH_AUTH_PASS_INIT);
846 case SSH_AUTH_PASS_INIT:
847 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
848 (strstr(sshc->authlist, "password") != NULL)) {
849 state(conn, SSH_AUTH_PASS);
852 state(conn, SSH_AUTH_HOST_INIT);
857 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
858 (unsigned int)strlen(conn->user),
860 (unsigned int)strlen(conn->passwd),
862 if(rc == LIBSSH2_ERROR_EAGAIN) {
867 infof(data, "Initialized password authentication\n");
868 state(conn, SSH_AUTH_DONE);
871 state(conn, SSH_AUTH_HOST_INIT);
875 case SSH_AUTH_HOST_INIT:
876 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
877 (strstr(sshc->authlist, "hostbased") != NULL)) {
878 state(conn, SSH_AUTH_HOST);
881 state(conn, SSH_AUTH_KEY_INIT);
886 state(conn, SSH_AUTH_KEY_INIT);
889 case SSH_AUTH_KEY_INIT:
890 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
891 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
892 state(conn, SSH_AUTH_KEY);
895 state(conn, SSH_AUTH_DONE);
900 /* Authentication failed. Continue with keyboard-interactive now. */
901 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
906 if(rc == LIBSSH2_ERROR_EAGAIN) {
911 infof(data, "Initialized keyboard interactive authentication\n");
913 state(conn, SSH_AUTH_DONE);
918 failf(data, "Authentication failure");
919 state(conn, SSH_SESSION_FREE);
920 sshc->actualcode = CURLE_LOGIN_DENIED;
925 * At this point we have an authenticated ssh session.
927 infof(data, "Authentication complete\n");
929 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
932 conn->writesockfd = CURL_SOCKET_BAD;
934 if(conn->protocol == PROT_SFTP) {
935 state(conn, SSH_SFTP_INIT);
938 infof(data, "SSH CONNECT phase done\n");
939 state(conn, SSH_STOP);
944 * Start the libssh2 sftp session
946 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
947 if(!sshc->sftp_session) {
948 if(libssh2_session_last_errno(sshc->ssh_session) ==
949 LIBSSH2_ERROR_EAGAIN) {
950 rc = LIBSSH2_ERROR_EAGAIN;
956 (void)libssh2_session_last_error(sshc->ssh_session,
958 failf(data, "Failure initializing sftp session: %s", err_msg);
959 state(conn, SSH_SESSION_FREE);
960 sshc->actualcode = CURLE_FAILED_INIT;
964 state(conn, SSH_SFTP_REALPATH);
967 case SSH_SFTP_REALPATH:
969 char tempHome[PATH_MAX];
972 * Get the "home" directory
974 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
975 tempHome, PATH_MAX-1);
976 if(rc == LIBSSH2_ERROR_EAGAIN) {
980 /* It seems that this string is not always NULL terminated */
982 sshc->homedir = strdup(tempHome);
984 state(conn, SSH_SFTP_CLOSE);
985 sshc->actualcode = CURLE_OUT_OF_MEMORY;
988 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
991 /* Return the error type */
992 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
993 result = sftp_libssh2_error_to_CURLE(err);
994 sshc->actualcode = result?result:CURLE_SSH;
995 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
997 state(conn, SSH_STOP);
1001 /* This is the last step in the SFTP connect phase. Do note that while
1002 we get the homedir here, we get the "workingpath" in the DO action
1003 since the homedir will remain the same between request but the
1004 working path will not. */
1005 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1006 state(conn, SSH_STOP);
1009 case SSH_SFTP_QUOTE_INIT:
1011 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1013 sshc->actualcode = result;
1014 state(conn, SSH_STOP);
1018 if(data->set.quote) {
1019 infof(data, "Sending quote commands\n");
1020 sshc->quote_item = data->set.quote;
1021 state(conn, SSH_SFTP_QUOTE);
1024 state(conn, SSH_SFTP_TRANS_INIT);
1028 case SSH_SFTP_POSTQUOTE_INIT:
1029 if(data->set.postquote) {
1030 infof(data, "Sending quote commands\n");
1031 sshc->quote_item = data->set.postquote;
1032 state(conn, SSH_SFTP_QUOTE);
1035 state(conn, SSH_STOP);
1039 case SSH_SFTP_QUOTE:
1040 /* Send any quote commands */
1045 * Support some of the "FTP" commands
1047 if(curl_strequal("pwd", sshc->quote_item->data)) {
1048 /* output debug output if that is requested */
1049 if(data->set.verbose) {
1050 char tmp[PATH_MAX+1];
1052 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1053 snprintf(tmp, PATH_MAX, "257 \"%s\" is current directory.\n",
1055 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1057 state(conn, SSH_SFTP_NEXT_QUOTE);
1060 else if(sshc->quote_item->data) {
1062 * the arguments following the command must be separated from the
1063 * command with a space so we can check for it unconditionally
1065 cp = strchr(sshc->quote_item->data, ' ');
1067 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1068 state(conn, SSH_SFTP_CLOSE);
1069 sshc->actualcode = CURLE_QUOTE_ERROR;
1074 * also, every command takes at least one argument so we get that
1075 * first argument right now
1077 result = get_pathname(&cp, &sshc->quote_path1);
1079 if(result == CURLE_OUT_OF_MEMORY)
1080 failf(data, "Out of memory");
1082 failf(data, "Syntax error: Bad first parameter");
1083 state(conn, SSH_SFTP_CLOSE);
1084 sshc->actualcode = result;
1089 * SFTP is a binary protocol, so we don't send text commands to
1090 * the server. Instead, we scan for commands for commands used by
1091 * OpenSSH's sftp program and call the appropriate libssh2
1094 if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
1095 curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
1096 curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
1097 /* attribute change */
1099 /* sshc->quote_path1 contains the mode to set */
1100 /* get the destination */
1101 result = get_pathname(&cp, &sshc->quote_path2);
1103 if(result == CURLE_OUT_OF_MEMORY)
1104 failf(data, "Out of memory");
1106 failf(data, "Syntax error in chgrp/chmod/chown: "
1107 "Bad second parameter");
1108 Curl_safefree(sshc->quote_path1);
1109 sshc->quote_path1 = NULL;
1110 state(conn, SSH_SFTP_CLOSE);
1111 sshc->actualcode = result;
1114 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1115 state(conn, SSH_SFTP_QUOTE_STAT);
1118 else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
1119 curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
1120 /* symbolic linking */
1121 /* sshc->quote_path1 is the source */
1122 /* get the destination */
1123 result = get_pathname(&cp, &sshc->quote_path2);
1125 if(result == CURLE_OUT_OF_MEMORY)
1126 failf(data, "Out of memory");
1129 "Syntax error in ln/symlink: Bad second parameter");
1130 Curl_safefree(sshc->quote_path1);
1131 sshc->quote_path1 = NULL;
1132 state(conn, SSH_SFTP_CLOSE);
1133 sshc->actualcode = result;
1136 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1139 else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
1141 state(conn, SSH_SFTP_QUOTE_MKDIR);
1144 else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
1146 /* first param is the source path */
1147 /* second param is the dest. path */
1148 result = get_pathname(&cp, &sshc->quote_path2);
1150 if(result == CURLE_OUT_OF_MEMORY)
1151 failf(data, "Out of memory");
1153 failf(data, "Syntax error in rename: Bad second parameter");
1154 Curl_safefree(sshc->quote_path1);
1155 sshc->quote_path1 = NULL;
1156 state(conn, SSH_SFTP_CLOSE);
1157 sshc->actualcode = result;
1160 state(conn, SSH_SFTP_QUOTE_RENAME);
1163 else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
1165 state(conn, SSH_SFTP_QUOTE_RMDIR);
1168 else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
1169 state(conn, SSH_SFTP_QUOTE_UNLINK);
1173 failf(data, "Unknown SFTP command");
1174 Curl_safefree(sshc->quote_path1);
1175 sshc->quote_path1 = NULL;
1176 Curl_safefree(sshc->quote_path2);
1177 sshc->quote_path2 = NULL;
1178 state(conn, SSH_SFTP_CLOSE);
1179 sshc->actualcode = CURLE_QUOTE_ERROR;
1183 if(!sshc->quote_item) {
1184 state(conn, SSH_SFTP_TRANS_INIT);
1188 case SSH_SFTP_NEXT_QUOTE:
1189 if(sshc->quote_path1) {
1190 Curl_safefree(sshc->quote_path1);
1191 sshc->quote_path1 = NULL;
1193 if(sshc->quote_path2) {
1194 Curl_safefree(sshc->quote_path2);
1195 sshc->quote_path2 = NULL;
1198 sshc->quote_item = sshc->quote_item->next;
1200 if(sshc->quote_item) {
1201 state(conn, SSH_SFTP_QUOTE);
1204 if(sshc->nextstate != SSH_NO_STATE) {
1205 state(conn, sshc->nextstate);
1206 sshc->nextstate = SSH_NO_STATE;
1209 state(conn, SSH_SFTP_TRANS_INIT);
1214 case SSH_SFTP_QUOTE_STAT:
1215 if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1216 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1217 * set them both at once, we need to obtain the current ownership
1218 * first. This takes an extra protocol round trip.
1220 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1221 (unsigned int)strlen(sshc->quote_path2),
1223 &sshc->quote_attrs);
1224 if(rc == LIBSSH2_ERROR_EAGAIN) {
1227 else if(rc != 0) { /* get those attributes */
1228 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1229 Curl_safefree(sshc->quote_path1);
1230 sshc->quote_path1 = NULL;
1231 Curl_safefree(sshc->quote_path2);
1232 sshc->quote_path2 = NULL;
1233 failf(data, "Attempt to get SFTP stats failed: %s",
1234 sftp_libssh2_strerror(err));
1235 state(conn, SSH_SFTP_CLOSE);
1236 sshc->actualcode = CURLE_QUOTE_ERROR;
1241 /* Now set the new attributes... */
1242 if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
1243 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1244 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1245 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1246 Curl_safefree(sshc->quote_path1);
1247 sshc->quote_path1 = NULL;
1248 Curl_safefree(sshc->quote_path2);
1249 sshc->quote_path2 = NULL;
1250 failf(data, "Syntax error: chgrp gid not a number");
1251 state(conn, SSH_SFTP_CLOSE);
1252 sshc->actualcode = CURLE_QUOTE_ERROR;
1256 else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1257 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1258 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1259 /* permissions are octal */
1260 if(sshc->quote_attrs.permissions == 0 &&
1261 !ISDIGIT(sshc->quote_path1[0])) {
1262 Curl_safefree(sshc->quote_path1);
1263 sshc->quote_path1 = NULL;
1264 Curl_safefree(sshc->quote_path2);
1265 sshc->quote_path2 = NULL;
1266 failf(data, "Syntax error: chmod permissions not a number");
1267 state(conn, SSH_SFTP_CLOSE);
1268 sshc->actualcode = CURLE_QUOTE_ERROR;
1272 else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
1273 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1274 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1275 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1276 Curl_safefree(sshc->quote_path1);
1277 sshc->quote_path1 = NULL;
1278 Curl_safefree(sshc->quote_path2);
1279 sshc->quote_path2 = NULL;
1280 failf(data, "Syntax error: chown uid not a number");
1281 state(conn, SSH_SFTP_CLOSE);
1282 sshc->actualcode = CURLE_QUOTE_ERROR;
1287 /* Now send the completed structure... */
1288 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1291 case SSH_SFTP_QUOTE_SETSTAT:
1292 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1293 (unsigned int)strlen(sshc->quote_path2),
1294 LIBSSH2_SFTP_SETSTAT,
1295 &sshc->quote_attrs);
1296 if(rc == LIBSSH2_ERROR_EAGAIN) {
1300 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1301 Curl_safefree(sshc->quote_path1);
1302 sshc->quote_path1 = NULL;
1303 Curl_safefree(sshc->quote_path2);
1304 sshc->quote_path2 = NULL;
1305 failf(data, "Attempt to set SFTP stats failed: %s",
1306 sftp_libssh2_strerror(err));
1307 state(conn, SSH_SFTP_CLOSE);
1308 sshc->actualcode = CURLE_QUOTE_ERROR;
1311 state(conn, SSH_SFTP_NEXT_QUOTE);
1314 case SSH_SFTP_QUOTE_SYMLINK:
1315 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1316 (unsigned int)strlen(sshc->quote_path1),
1318 (unsigned int)strlen(sshc->quote_path2),
1319 LIBSSH2_SFTP_SYMLINK);
1320 if(rc == LIBSSH2_ERROR_EAGAIN) {
1324 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1325 Curl_safefree(sshc->quote_path1);
1326 sshc->quote_path1 = NULL;
1327 Curl_safefree(sshc->quote_path2);
1328 sshc->quote_path2 = NULL;
1329 failf(data, "symlink command failed: %s",
1330 sftp_libssh2_strerror(err));
1331 state(conn, SSH_SFTP_CLOSE);
1332 sshc->actualcode = CURLE_QUOTE_ERROR;
1335 state(conn, SSH_SFTP_NEXT_QUOTE);
1338 case SSH_SFTP_QUOTE_MKDIR:
1339 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1340 (unsigned int)strlen(sshc->quote_path1),
1342 if(rc == LIBSSH2_ERROR_EAGAIN) {
1346 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1347 Curl_safefree(sshc->quote_path1);
1348 sshc->quote_path1 = NULL;
1349 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1350 state(conn, SSH_SFTP_CLOSE);
1351 sshc->actualcode = CURLE_QUOTE_ERROR;
1354 state(conn, SSH_SFTP_NEXT_QUOTE);
1357 case SSH_SFTP_QUOTE_RENAME:
1358 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1359 (unsigned int)strlen(sshc->quote_path1),
1361 (unsigned int)strlen(sshc->quote_path2),
1362 LIBSSH2_SFTP_RENAME_OVERWRITE |
1363 LIBSSH2_SFTP_RENAME_ATOMIC |
1364 LIBSSH2_SFTP_RENAME_NATIVE);
1365 if(rc == LIBSSH2_ERROR_EAGAIN) {
1369 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1370 Curl_safefree(sshc->quote_path1);
1371 sshc->quote_path1 = NULL;
1372 Curl_safefree(sshc->quote_path2);
1373 sshc->quote_path2 = NULL;
1374 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1375 state(conn, SSH_SFTP_CLOSE);
1376 sshc->actualcode = CURLE_QUOTE_ERROR;
1379 state(conn, SSH_SFTP_NEXT_QUOTE);
1382 case SSH_SFTP_QUOTE_RMDIR:
1383 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1384 (unsigned int)strlen(sshc->quote_path1));
1385 if(rc == LIBSSH2_ERROR_EAGAIN) {
1389 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1390 Curl_safefree(sshc->quote_path1);
1391 sshc->quote_path1 = NULL;
1392 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1393 state(conn, SSH_SFTP_CLOSE);
1394 sshc->actualcode = CURLE_QUOTE_ERROR;
1397 state(conn, SSH_SFTP_NEXT_QUOTE);
1400 case SSH_SFTP_QUOTE_UNLINK:
1401 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1402 (unsigned int)strlen(sshc->quote_path1));
1403 if(rc == LIBSSH2_ERROR_EAGAIN) {
1407 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1408 Curl_safefree(sshc->quote_path1);
1409 sshc->quote_path1 = NULL;
1410 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1411 state(conn, SSH_SFTP_CLOSE);
1412 sshc->actualcode = CURLE_QUOTE_ERROR;
1415 state(conn, SSH_SFTP_NEXT_QUOTE);
1418 case SSH_SFTP_TRANS_INIT:
1419 if(data->set.upload)
1420 state(conn, SSH_SFTP_UPLOAD_INIT);
1422 if(data->set.opt_no_body)
1423 state(conn, SSH_STOP);
1424 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1425 state(conn, SSH_SFTP_READDIR_INIT);
1427 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1431 case SSH_SFTP_UPLOAD_INIT:
1433 unsigned long flags;
1435 * NOTE!!! libssh2 requires that the destination path is a full path
1436 * that includes the destination file and name OR ends in a "/"
1437 * If this is not done the destination file will be named the
1438 * same name as the last directory in the path.
1441 if(data->state.resume_from != 0) {
1442 LIBSSH2_SFTP_ATTRIBUTES attrs;
1443 if(data->state.resume_from < 0) {
1444 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1445 (unsigned int)strlen(sftp_scp->path),
1446 LIBSSH2_SFTP_STAT, &attrs);
1447 if(rc == LIBSSH2_ERROR_EAGAIN) {
1451 data->state.resume_from = 0;
1454 curl_off_t size = attrs.filesize;
1456 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1457 return CURLE_BAD_DOWNLOAD_RESUME;
1459 data->state.resume_from = attrs.filesize;
1464 if(data->set.ftp_append)
1465 /* Try to open for append, but create if nonexisting */
1466 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1467 else if (data->state.resume_from > 0)
1468 /* If we have restart position then open for append */
1469 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1471 /* Clear file before writing (normal behaviour) */
1472 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1475 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1476 (unsigned int)strlen(sftp_scp->path),
1477 flags, data->set.new_file_perms,
1478 LIBSSH2_SFTP_OPENFILE);
1480 if(!sshc->sftp_handle) {
1481 rc = libssh2_session_last_errno(sshc->ssh_session);
1483 if(LIBSSH2_ERROR_EAGAIN == rc)
1486 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1487 /* only when there was an SFTP protocol error can we extract
1489 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1491 err = -1; /* not an sftp error at all */
1493 if(sshc->secondCreateDirs) {
1494 state(conn, SSH_SFTP_CLOSE);
1495 sshc->actualcode = err>= LIBSSH2_FX_OK?
1496 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1497 failf(data, "Creating the dir/file failed: %s",
1498 sftp_libssh2_strerror(err));
1501 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1502 (err == LIBSSH2_FX_FAILURE) ||
1503 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1504 (data->set.ftp_create_missing_dirs &&
1505 (strlen(sftp_scp->path) > 1))) {
1506 /* try to create the path remotely */
1507 sshc->secondCreateDirs = 1;
1508 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1511 state(conn, SSH_SFTP_CLOSE);
1512 sshc->actualcode = err>= LIBSSH2_FX_OK?
1513 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1514 if(!sshc->actualcode) {
1515 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1516 zero even though libssh2_sftp_open() failed previously! We need
1517 to work around that! */
1518 sshc->actualcode = CURLE_SSH;
1521 failf(data, "Upload failed: %s (%d/%d)",
1522 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1528 /* If we have restart point then we need to seek to the correct
1530 if(data->state.resume_from > 0) {
1531 /* Let's read off the proper amount of bytes from the input. */
1532 if(conn->seek_func) {
1533 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1537 if(seekerr != CURL_SEEKFUNC_OK){
1539 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1540 failf(data, "Could not seek stream");
1541 return CURLE_FTP_COULDNT_USE_REST;
1543 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1545 curl_off_t passed=0;
1547 size_t readthisamountnow =
1548 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1549 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1551 size_t actuallyread =
1552 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1555 passed += actuallyread;
1556 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1557 /* this checks for greater-than only to make sure that the
1558 CURL_READFUNC_ABORT return code still aborts */
1559 failf(data, "Failed to read data");
1560 return CURLE_FTP_COULDNT_USE_REST;
1562 } while(passed < data->state.resume_from);
1566 /* now, decrease the size of the read */
1567 if(data->set.infilesize > 0) {
1568 data->set.infilesize -= data->state.resume_from;
1569 data->req.size = data->set.infilesize;
1570 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1573 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1575 if(data->set.infilesize > 0) {
1576 data->req.size = data->set.infilesize;
1577 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1580 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1582 /* not set by Curl_setup_transfer to preserve keepon bits */
1583 conn->sockfd = conn->writesockfd;
1586 state(conn, SSH_SFTP_CLOSE);
1587 sshc->actualcode = result;
1590 /* store this original bitmask setup to use later on if we can't
1591 figure out a "real" bitmask */
1592 sshc->orig_waitfor = data->req.keepon;
1594 state(conn, SSH_STOP);
1599 case SSH_SFTP_CREATE_DIRS_INIT:
1600 if(strlen(sftp_scp->path) > 1) {
1601 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1602 state(conn, SSH_SFTP_CREATE_DIRS);
1605 state(conn, SSH_SFTP_UPLOAD_INIT);
1609 case SSH_SFTP_CREATE_DIRS:
1610 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1611 *sshc->slash_pos = 0;
1613 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1614 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1618 state(conn, SSH_SFTP_UPLOAD_INIT);
1622 case SSH_SFTP_CREATE_DIRS_MKDIR:
1623 /* 'mode' - parameter is preliminary - default to 0644 */
1624 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1625 (unsigned int)strlen(sftp_scp->path),
1626 data->set.new_directory_perms);
1627 if(rc == LIBSSH2_ERROR_EAGAIN) {
1630 *sshc->slash_pos = '/';
1633 unsigned int sftp_err = 0;
1635 * Abort if failure wasn't that the dir already exists or the
1636 * permission was denied (creation might succeed further down the
1637 * path) - retry on unspecific FAILURE also
1639 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1640 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1641 (sftp_err != LIBSSH2_FX_FAILURE) &&
1642 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1643 result = sftp_libssh2_error_to_CURLE(sftp_err);
1644 state(conn, SSH_SFTP_CLOSE);
1645 sshc->actualcode = result?result:CURLE_SSH;
1649 state(conn, SSH_SFTP_CREATE_DIRS);
1652 case SSH_SFTP_READDIR_INIT:
1654 * This is a directory that we are trying to get, so produce a directory
1657 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1660 strlen(sftp_scp->path),
1661 0, 0, LIBSSH2_SFTP_OPENDIR);
1662 if(!sshc->sftp_handle) {
1663 if(libssh2_session_last_errno(sshc->ssh_session) ==
1664 LIBSSH2_ERROR_EAGAIN) {
1665 rc = LIBSSH2_ERROR_EAGAIN;
1669 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1670 failf(data, "Could not open directory for reading: %s",
1671 sftp_libssh2_strerror(err));
1672 state(conn, SSH_SFTP_CLOSE);
1673 result = sftp_libssh2_error_to_CURLE(err);
1674 sshc->actualcode = result?result:CURLE_SSH;
1678 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1679 state(conn, SSH_SFTP_CLOSE);
1680 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1683 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1684 Curl_safefree(sshc->readdir_filename);
1685 sshc->readdir_filename = NULL;
1686 state(conn, SSH_SFTP_CLOSE);
1687 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1690 state(conn, SSH_SFTP_READDIR);
1693 case SSH_SFTP_READDIR:
1694 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1695 sshc->readdir_filename,
1697 sshc->readdir_longentry,
1699 &sshc->readdir_attrs);
1700 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1701 rc = LIBSSH2_ERROR_EAGAIN;
1704 if(sshc->readdir_len > 0) {
1705 sshc->readdir_filename[sshc->readdir_len] = '\0';
1707 if(data->set.ftp_list_only) {
1710 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1711 if(tmpLine == NULL) {
1712 state(conn, SSH_SFTP_CLOSE);
1713 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1716 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1717 tmpLine, sshc->readdir_len+1);
1718 Curl_safefree(tmpLine);
1721 state(conn, SSH_STOP);
1724 /* since this counts what we send to the client, we include the
1725 newline in this counter */
1726 data->req.bytecount += sshc->readdir_len+1;
1728 /* output debug output if that is requested */
1729 if(data->set.verbose) {
1730 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1731 sshc->readdir_len, conn);
1735 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1736 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1737 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1738 if(!sshc->readdir_line) {
1739 Curl_safefree(sshc->readdir_filename);
1740 sshc->readdir_filename = NULL;
1741 Curl_safefree(sshc->readdir_longentry);
1742 sshc->readdir_longentry = NULL;
1743 state(conn, SSH_SFTP_CLOSE);
1744 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1748 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1749 sshc->readdir_currLen);
1750 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1751 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1752 LIBSSH2_SFTP_S_IFLNK)) {
1753 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1754 if(sshc->readdir_linkPath == NULL) {
1755 Curl_safefree(sshc->readdir_filename);
1756 sshc->readdir_filename = NULL;
1757 Curl_safefree(sshc->readdir_longentry);
1758 sshc->readdir_longentry = NULL;
1759 state(conn, SSH_SFTP_CLOSE);
1760 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1764 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1765 sshc->readdir_filename);
1766 state(conn, SSH_SFTP_READDIR_LINK);
1769 state(conn, SSH_SFTP_READDIR_BOTTOM);
1773 else if(sshc->readdir_len == 0) {
1774 Curl_safefree(sshc->readdir_filename);
1775 sshc->readdir_filename = NULL;
1776 Curl_safefree(sshc->readdir_longentry);
1777 sshc->readdir_longentry = NULL;
1778 state(conn, SSH_SFTP_READDIR_DONE);
1781 else if(sshc->readdir_len <= 0) {
1782 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1783 result = sftp_libssh2_error_to_CURLE(err);
1784 sshc->actualcode = result?result:CURLE_SSH;
1785 failf(data, "Could not open remote file for reading: %s :: %d",
1786 sftp_libssh2_strerror(err),
1787 libssh2_session_last_errno(sshc->ssh_session));
1788 Curl_safefree(sshc->readdir_filename);
1789 sshc->readdir_filename = NULL;
1790 Curl_safefree(sshc->readdir_longentry);
1791 sshc->readdir_longentry = NULL;
1792 state(conn, SSH_SFTP_CLOSE);
1797 case SSH_SFTP_READDIR_LINK:
1799 libssh2_sftp_symlink_ex(sshc->sftp_session,
1800 sshc->readdir_linkPath,
1801 (unsigned int) strlen(sshc->readdir_linkPath),
1802 sshc->readdir_filename,
1803 PATH_MAX, LIBSSH2_SFTP_READLINK);
1804 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1805 rc = LIBSSH2_ERROR_EAGAIN;
1808 Curl_safefree(sshc->readdir_linkPath);
1809 sshc->readdir_linkPath = NULL;
1810 sshc->readdir_line = realloc(sshc->readdir_line,
1811 sshc->readdir_totalLen + 4 +
1813 if(!sshc->readdir_line) {
1814 Curl_safefree(sshc->readdir_filename);
1815 sshc->readdir_filename = NULL;
1816 Curl_safefree(sshc->readdir_longentry);
1817 sshc->readdir_longentry = NULL;
1818 state(conn, SSH_SFTP_CLOSE);
1819 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1823 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1824 sshc->readdir_currLen,
1825 sshc->readdir_totalLen -
1826 sshc->readdir_currLen,
1828 sshc->readdir_filename);
1830 state(conn, SSH_SFTP_READDIR_BOTTOM);
1833 case SSH_SFTP_READDIR_BOTTOM:
1834 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1835 sshc->readdir_currLen,
1836 sshc->readdir_totalLen -
1837 sshc->readdir_currLen, "\n");
1838 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1840 sshc->readdir_currLen);
1842 if(result == CURLE_OK) {
1844 /* output debug output if that is requested */
1845 if(data->set.verbose) {
1846 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1847 sshc->readdir_currLen, conn);
1849 data->req.bytecount += sshc->readdir_currLen;
1851 Curl_safefree(sshc->readdir_line);
1852 sshc->readdir_line = NULL;
1854 state(conn, SSH_STOP);
1857 state(conn, SSH_SFTP_READDIR);
1860 case SSH_SFTP_READDIR_DONE:
1861 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1862 LIBSSH2_ERROR_EAGAIN) {
1863 rc = LIBSSH2_ERROR_EAGAIN;
1866 sshc->sftp_handle = NULL;
1867 Curl_safefree(sshc->readdir_filename);
1868 sshc->readdir_filename = NULL;
1869 Curl_safefree(sshc->readdir_longentry);
1870 sshc->readdir_longentry = NULL;
1872 /* no data to transfer */
1873 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1874 state(conn, SSH_STOP);
1877 case SSH_SFTP_DOWNLOAD_INIT:
1879 * Work on getting the specified file
1882 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1883 (unsigned int)strlen(sftp_scp->path),
1884 LIBSSH2_FXF_READ, data->set.new_file_perms,
1885 LIBSSH2_SFTP_OPENFILE);
1886 if(!sshc->sftp_handle) {
1887 if(libssh2_session_last_errno(sshc->ssh_session) ==
1888 LIBSSH2_ERROR_EAGAIN) {
1889 rc = LIBSSH2_ERROR_EAGAIN;
1893 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1894 failf(data, "Could not open remote file for reading: %s",
1895 sftp_libssh2_strerror(err));
1896 state(conn, SSH_SFTP_CLOSE);
1897 result = sftp_libssh2_error_to_CURLE(err);
1898 sshc->actualcode = result?result:CURLE_SSH;
1902 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1905 case SSH_SFTP_DOWNLOAD_STAT:
1907 LIBSSH2_SFTP_ATTRIBUTES attrs;
1909 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1910 (unsigned int)strlen(sftp_scp->path),
1911 LIBSSH2_SFTP_STAT, &attrs);
1912 if(rc == LIBSSH2_ERROR_EAGAIN) {
1917 * libssh2_sftp_open() didn't return an error, so maybe the server
1918 * just doesn't support stat()
1920 data->req.size = -1;
1921 data->req.maxdownload = -1;
1924 curl_off_t size = attrs.filesize;
1927 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1928 return CURLE_BAD_DOWNLOAD_RESUME;
1930 if(conn->data->state.use_range) {
1931 curl_off_t from, to;
1935 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1936 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
1938 to=curlx_strtoofft(ptr, &ptr2, 0);
1939 if((ptr == ptr2) /* no "to" value given */
1944 /* from is relative to end of file */
1948 failf(data, "Offset (%"
1949 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1950 from, attrs.filesize);
1951 return CURLE_BAD_DOWNLOAD_RESUME;
1958 size = to - from + 1;
1961 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
1963 data->req.size = size;
1964 data->req.maxdownload = size;
1965 Curl_pgrsSetDownloadSize(data, size);
1968 /* We can resume if we can seek to the resume position */
1969 if(data->state.resume_from) {
1970 if(data->state.resume_from < 0) {
1971 /* We're supposed to download the last abs(from) bytes */
1972 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
1973 failf(data, "Offset (%"
1974 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1975 data->state.resume_from, attrs.filesize);
1976 return CURLE_BAD_DOWNLOAD_RESUME;
1978 /* download from where? */
1979 data->state.resume_from += attrs.filesize;
1982 if((curl_off_t)attrs.filesize < data->state.resume_from) {
1983 failf(data, "Offset (%" FORMAT_OFF_T
1984 ") was beyond file size (%" FORMAT_OFF_T ")",
1985 data->state.resume_from, attrs.filesize);
1986 return CURLE_BAD_DOWNLOAD_RESUME;
1989 /* Does a completed file need to be seeked and started or closed ? */
1990 /* Now store the number of bytes we are expected to download */
1991 data->req.size = attrs.filesize - data->state.resume_from;
1992 data->req.maxdownload = attrs.filesize - data->state.resume_from;
1993 Curl_pgrsSetDownloadSize(data,
1994 attrs.filesize - data->state.resume_from);
1995 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1998 /* Setup the actual download */
1999 if(data->req.size == 0) {
2000 /* no data to transfer */
2001 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2002 infof(data, "File already completely downloaded\n");
2003 state(conn, SSH_STOP);
2007 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2008 FALSE, NULL, -1, NULL);
2010 /* not set by Curl_setup_transfer to preserve keepon bits */
2011 conn->writesockfd = conn->sockfd;
2013 /* FIXME: here should be explained why we need it to start the
2015 conn->cselect_bits = CURL_CSELECT_IN;
2018 state(conn, SSH_SFTP_CLOSE);
2019 sshc->actualcode = result;
2022 state(conn, SSH_STOP);
2026 case SSH_SFTP_CLOSE:
2027 if(sshc->sftp_handle) {
2028 rc = libssh2_sftp_close(sshc->sftp_handle);
2029 if(rc == LIBSSH2_ERROR_EAGAIN) {
2033 infof(data, "Failed to close libssh2 file\n");
2035 sshc->sftp_handle = NULL;
2037 Curl_safefree(sftp_scp->path);
2038 sftp_scp->path = NULL;
2040 DEBUGF(infof(data, "SFTP DONE done\n"));
2042 state(conn, SSH_SFTP_SHUTDOWN);
2044 state(conn, SSH_STOP);
2045 result = sshc->actualcode;
2048 case SSH_SFTP_SHUTDOWN:
2049 /* during times we get here due to a broken transfer and then the
2050 sftp_handle might not have been taken down so make sure that is done
2051 before we proceed */
2053 if(sshc->sftp_handle) {
2054 rc = libssh2_sftp_close(sshc->sftp_handle);
2055 if(rc == LIBSSH2_ERROR_EAGAIN) {
2059 infof(data, "Failed to close libssh2 file\n");
2061 sshc->sftp_handle = NULL;
2063 if(sshc->sftp_session) {
2064 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2065 if(rc == LIBSSH2_ERROR_EAGAIN) {
2069 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2071 sshc->sftp_session = NULL;
2074 Curl_safefree(sshc->homedir);
2075 sshc->homedir = NULL;
2076 conn->data->state.most_recent_ftp_entrypath = NULL;
2078 state(conn, SSH_SESSION_DISCONNECT);
2081 case SSH_SCP_TRANS_INIT:
2082 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2084 sshc->actualcode = result;
2085 state(conn, SSH_STOP);
2089 if(data->set.upload) {
2090 if(data->set.infilesize < 0) {
2091 failf(data, "SCP requires a known file size for upload");
2092 sshc->actualcode = CURLE_UPLOAD_FAILED;
2093 state(conn, SSH_SCP_CHANNEL_FREE);
2096 state(conn, SSH_SCP_UPLOAD_INIT);
2099 state(conn, SSH_SCP_DOWNLOAD_INIT);
2103 case SSH_SCP_UPLOAD_INIT:
2105 * libssh2 requires that the destination path is a full path that
2106 * includes the destination file and name OR ends in a "/" . If this is
2107 * not done the destination file will be named the same name as the last
2108 * directory in the path.
2111 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2112 data->set.infilesize);
2113 if(!sshc->ssh_channel) {
2114 if(libssh2_session_last_errno(sshc->ssh_session) ==
2115 LIBSSH2_ERROR_EAGAIN) {
2116 rc = LIBSSH2_ERROR_EAGAIN;
2123 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2124 &err_msg, NULL, 0));
2125 failf(conn->data, "%s", err_msg);
2126 state(conn, SSH_SCP_CHANNEL_FREE);
2127 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2133 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2136 /* not set by Curl_setup_transfer to preserve keepon bits */
2137 conn->sockfd = conn->writesockfd;
2140 state(conn, SSH_SCP_CHANNEL_FREE);
2141 sshc->actualcode = result;
2144 state(conn, SSH_STOP);
2148 case SSH_SCP_DOWNLOAD_INIT:
2151 * We must check the remote file; if it is a directory no values will
2155 curl_off_t bytecount;
2157 /* clear the struct scp recv will fill in */
2158 memset(&sb, 0, sizeof(struct stat));
2160 /* get a fresh new channel from the ssh layer */
2161 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2162 sftp_scp->path, &sb);
2163 if(!sshc->ssh_channel) {
2164 if(libssh2_session_last_errno(sshc->ssh_session) ==
2165 LIBSSH2_ERROR_EAGAIN) {
2166 rc = LIBSSH2_ERROR_EAGAIN;
2173 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2174 &err_msg, NULL, 0));
2175 failf(conn->data, "%s", err_msg);
2176 state(conn, SSH_SCP_CHANNEL_FREE);
2177 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2183 bytecount = (curl_off_t)sb.st_size;
2184 data->req.maxdownload = (curl_off_t)sb.st_size;
2185 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2187 /* not set by Curl_setup_transfer to preserve keepon bits */
2188 conn->writesockfd = conn->sockfd;
2190 /* FIXME: here should be explained why we need it to start the
2192 conn->cselect_bits = CURL_CSELECT_IN;
2195 state(conn, SSH_SCP_CHANNEL_FREE);
2196 sshc->actualcode = result;
2199 state(conn, SSH_STOP);
2204 if(data->set.upload)
2205 state(conn, SSH_SCP_SEND_EOF);
2207 state(conn, SSH_SCP_CHANNEL_FREE);
2210 case SSH_SCP_SEND_EOF:
2211 if(sshc->ssh_channel) {
2212 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2213 if(rc == LIBSSH2_ERROR_EAGAIN) {
2217 infof(data, "Failed to send libssh2 channel EOF\n");
2220 state(conn, SSH_SCP_WAIT_EOF);
2223 case SSH_SCP_WAIT_EOF:
2224 if(sshc->ssh_channel) {
2225 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2226 if(rc == LIBSSH2_ERROR_EAGAIN) {
2230 infof(data, "Failed to get channel EOF: %d\n", rc);
2233 state(conn, SSH_SCP_WAIT_CLOSE);
2236 case SSH_SCP_WAIT_CLOSE:
2237 if(sshc->ssh_channel) {
2238 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2239 if(rc == LIBSSH2_ERROR_EAGAIN) {
2243 infof(data, "Channel failed to close: %d\n", rc);
2246 state(conn, SSH_SCP_CHANNEL_FREE);
2249 case SSH_SCP_CHANNEL_FREE:
2250 if(sshc->ssh_channel) {
2251 rc = libssh2_channel_free(sshc->ssh_channel);
2252 if(rc == LIBSSH2_ERROR_EAGAIN) {
2256 infof(data, "Failed to free libssh2 scp subsystem\n");
2258 sshc->ssh_channel = NULL;
2260 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2262 state(conn, SSH_SESSION_DISCONNECT);
2264 state(conn, SSH_STOP);
2265 result = sshc->actualcode;
2268 case SSH_SESSION_DISCONNECT:
2269 /* during weird times when we've been prematurely aborted, the channel
2270 is still alive when we reach this state and we MUST kill the channel
2272 if(sshc->ssh_channel) {
2273 rc = libssh2_channel_free(sshc->ssh_channel);
2274 if(rc == LIBSSH2_ERROR_EAGAIN) {
2278 infof(data, "Failed to free libssh2 scp subsystem\n");
2280 sshc->ssh_channel = NULL;
2283 if(sshc->ssh_session) {
2284 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2285 if(rc == LIBSSH2_ERROR_EAGAIN) {
2289 infof(data, "Failed to disconnect libssh2 session\n");
2293 Curl_safefree(sshc->homedir);
2294 sshc->homedir = NULL;
2295 conn->data->state.most_recent_ftp_entrypath = NULL;
2297 state(conn, SSH_SESSION_FREE);
2300 case SSH_SESSION_FREE:
2301 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2303 libssh2_knownhost_free(sshc->kh);
2308 if(sshc->ssh_session) {
2309 rc = libssh2_session_free(sshc->ssh_session);
2310 if(rc == LIBSSH2_ERROR_EAGAIN) {
2314 infof(data, "Failed to free libssh2 session\n");
2316 sshc->ssh_session = NULL;
2318 conn->bits.close = TRUE;
2319 sshc->nextstate = SSH_NO_STATE;
2320 state(conn, SSH_STOP);
2321 result = sshc->actualcode;
2325 /* fallthrough, just stop! */
2327 /* internal error */
2328 sshc->nextstate = SSH_NO_STATE;
2329 state(conn, SSH_STOP);
2333 } while(!rc && (sshc->state != SSH_STOP));
2335 if(rc == LIBSSH2_ERROR_EAGAIN) {
2336 /* we would block, we need to wait for the socket to be ready (in the
2337 right direction too)! */
2344 /* called by the multi interface to figure out what socket(s) to wait for and
2345 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2346 static int ssh_perform_getsock(const struct connectdata *conn,
2347 curl_socket_t *sock, /* points to numsocks
2348 number of sockets */
2351 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2352 int bitmap = GETSOCK_BLANK;
2355 sock[0] = conn->sock[FIRSTSOCKET];
2357 if(conn->waitfor & KEEP_RECV)
2358 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2360 if(conn->waitfor & KEEP_SEND)
2361 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2365 /* if we don't know the direction we can use the generic *_getsock()
2366 function even for the protocol_connect and doing states */
2367 return Curl_single_getsock(conn, sock, numsocks);
2371 /* Generic function called by the multi interface to figure out what socket(s)
2372 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2373 static int ssh_getsock(struct connectdata *conn,
2374 curl_socket_t *sock, /* points to numsocks number
2378 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2382 /* if we don't know any direction we can just play along as we used to and
2383 not provide any sensible info */
2384 return GETSOCK_BLANK;
2386 /* if we know the direction we can use the generic *_getsock() function even
2387 for the protocol_connect and doing states */
2388 return ssh_perform_getsock(conn, sock, numsocks);
2392 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2394 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2395 * function is used to figure out in what direction and stores this info so
2396 * that the multi interface can take advantage of it. Make sure to call this
2397 * function in all cases so that when it _doesn't_ return EAGAIN we can
2398 * restore the default wait bits.
2400 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2402 struct ssh_conn *sshc = &conn->proto.sshc;
2406 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2407 /* translate the libssh2 define bits into our own bit defines */
2408 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2409 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2412 /* It didn't block or libssh2 didn't reveal in which direction, put back
2414 conn->waitfor = sshc->orig_waitfor;
2417 /* no libssh2 directional support so we simply don't know */
2418 #define ssh_block2waitfor(x,y)
2421 /* called repeatedly until done from multi.c */
2422 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2424 struct ssh_conn *sshc = &conn->proto.sshc;
2425 CURLcode result = CURLE_OK;
2426 bool block; /* we store the status and use that to provide a ssh_getsock()
2429 result = ssh_statemach_act(conn, &block);
2430 *done = (bool)(sshc->state == SSH_STOP);
2431 ssh_block2waitfor(conn, block);
2436 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2439 struct ssh_conn *sshc = &conn->proto.sshc;
2440 CURLcode result = CURLE_OK;
2441 struct SessionHandle *data = conn->data;
2443 while((sshc->state != SSH_STOP) && !result) {
2447 result = ssh_statemach_act(conn, &block);
2449 if(Curl_pgrsUpdate(conn))
2450 return CURLE_ABORTED_BY_CALLBACK;
2452 left = Curl_timeleft(conn, NULL, duringconnect);
2454 failf(data, "Operation timed out\n");
2455 return CURLE_OPERATION_TIMEDOUT;
2458 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2459 if((CURLE_OK == result) && block) {
2460 int dir = libssh2_session_block_directions(sshc->ssh_session);
2461 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2462 curl_socket_t fd_read = CURL_SOCKET_BAD;
2463 curl_socket_t fd_write = CURL_SOCKET_BAD;
2464 if (LIBSSH2_SESSION_BLOCK_INBOUND & dir) {
2467 if (LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) {
2470 /* wait for the socket to become ready */
2471 Curl_socket_ready(fd_read, fd_write,
2472 (int)(left>1000?1000:left)); /* ignore result */
2482 * SSH setup and connection
2484 static CURLcode ssh_init(struct connectdata *conn)
2486 struct SessionHandle *data = conn->data;
2487 struct SSHPROTO *ssh;
2488 struct ssh_conn *sshc = &conn->proto.sshc;
2490 sshc->actualcode = CURLE_OK; /* reset error code */
2491 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2494 if(data->state.proto.ssh)
2497 ssh = calloc(1, sizeof(struct SSHPROTO));
2499 return CURLE_OUT_OF_MEMORY;
2501 data->state.proto.ssh = ssh;
2506 static Curl_recv scp_recv, sftp_recv;
2507 static Curl_send scp_send, sftp_send;
2510 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2511 * do protocol-specific actions at connect-time.
2513 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2515 #ifdef CURL_LIBSSH2_DEBUG
2518 struct ssh_conn *ssh;
2520 struct SessionHandle *data = conn->data;
2522 /* We default to persistent connections. We set this already in this connect
2523 function to make the re-use checks properly be able to check this bit. */
2524 conn->bits.close = FALSE;
2526 /* If there already is a protocol-specific struct allocated for this
2527 sessionhandle, deal with it */
2528 Curl_reset_reqproto(conn);
2530 result = ssh_init(conn);
2534 if(conn->protocol & PROT_SCP) {
2535 conn->recv[FIRSTSOCKET] = scp_recv;
2536 conn->send[FIRSTSOCKET] = scp_send;
2538 conn->recv[FIRSTSOCKET] = sftp_recv;
2539 conn->send[FIRSTSOCKET] = sftp_send;
2541 ssh = &conn->proto.sshc;
2543 #ifdef CURL_LIBSSH2_DEBUG
2545 infof(data, "User: %s\n", conn->user);
2548 infof(data, "Password: %s\n", conn->passwd);
2550 sock = conn->sock[FIRSTSOCKET];
2551 #endif /* CURL_LIBSSH2_DEBUG */
2553 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2555 my_libssh2_realloc, conn);
2556 if(ssh->ssh_session == NULL) {
2557 failf(data, "Failure initialising ssh session");
2558 return CURLE_FAILED_INIT;
2561 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2562 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2564 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2566 /* eeek. TODO: free the ssh_session! */
2567 return CURLE_FAILED_INIT;
2570 /* read all known hosts from there */
2571 rc = libssh2_knownhost_readfile(ssh->kh,
2572 data->set.str[STRING_SSH_KNOWNHOSTS],
2573 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2575 infof(data, "Failed to read known hosts from %s\n",
2576 data->set.str[STRING_SSH_KNOWNHOSTS]);
2579 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2581 #ifdef CURL_LIBSSH2_DEBUG
2582 libssh2_trace(ssh->ssh_session, ~0);
2583 infof(data, "SSH socket: %d\n", (int)sock);
2584 #endif /* CURL_LIBSSH2_DEBUG */
2586 state(conn, SSH_S_STARTUP);
2588 if(data->state.used_interface == Curl_if_multi)
2589 result = ssh_multi_statemach(conn, done);
2591 result = ssh_easy_statemach(conn, TRUE);
2600 ***********************************************************************
2604 * This is the actual DO function for SCP. Get a file according to
2605 * the options previously setup.
2609 CURLcode scp_perform(struct connectdata *conn,
2613 CURLcode result = CURLE_OK;
2615 DEBUGF(infof(conn->data, "DO phase starts\n"));
2617 *dophase_done = FALSE; /* not done yet */
2619 /* start the first command in the DO phase */
2620 state(conn, SSH_SCP_TRANS_INIT);
2622 /* run the state-machine */
2623 if(conn->data->state.used_interface == Curl_if_multi) {
2624 result = ssh_multi_statemach(conn, dophase_done);
2627 result = ssh_easy_statemach(conn, FALSE);
2628 *dophase_done = TRUE; /* with the easy interface we are done here */
2630 *connected = conn->bits.tcpconnect;
2633 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2639 /* called from multi.c while DOing */
2640 static CURLcode scp_doing(struct connectdata *conn,
2644 result = ssh_multi_statemach(conn, dophase_done);
2647 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2653 * The DO function is generic for both protocols. There was previously two
2654 * separate ones but this way means less duplicated code.
2657 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2661 struct SessionHandle *data = conn->data;
2663 *done = FALSE; /* default to false */
2666 Since connections can be re-used between SessionHandles, this might be a
2667 connection already existing but on a fresh SessionHandle struct so we must
2668 make sure we have a good 'struct SSHPROTO' to play with. For new
2669 connections, the struct SSHPROTO is allocated and setup in the
2670 ssh_connect() function.
2672 Curl_reset_reqproto(conn);
2673 res = ssh_init(conn);
2677 data->req.size = -1; /* make sure this is unknown at this point */
2679 Curl_pgrsSetUploadCounter(data, 0);
2680 Curl_pgrsSetDownloadCounter(data, 0);
2681 Curl_pgrsSetUploadSize(data, 0);
2682 Curl_pgrsSetDownloadSize(data, 0);
2684 if(conn->protocol & PROT_SCP)
2685 res = scp_perform(conn, &connected, done);
2687 res = sftp_perform(conn, &connected, done);
2692 /* BLOCKING, but the function is using the state machine so the only reason
2693 this is still blocking is that the multi interface code has no support for
2694 disconnecting operations that takes a while */
2695 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2697 CURLcode result = CURLE_OK;
2698 struct ssh_conn *ssh = &conn->proto.sshc;
2699 (void) dead_connection;
2701 Curl_safefree(conn->data->state.proto.ssh);
2702 conn->data->state.proto.ssh = NULL;
2704 if(ssh->ssh_session) {
2705 /* only if there's a session still around to use! */
2707 state(conn, SSH_SESSION_DISCONNECT);
2709 result = ssh_easy_statemach(conn, FALSE);
2715 /* generic done function for both SCP and SFTP called from their specific
2717 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2719 CURLcode result = CURLE_OK;
2720 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2722 if(status == CURLE_OK) {
2723 /* run the state-machine
2725 TODO: when the multi interface is used, this _really_ should be using
2726 the ssh_multi_statemach function but we have no general support for
2727 non-blocking DONE operations, not in the multi state machine and with
2728 Curl_done() invokes on several places in the code!
2730 result = ssh_easy_statemach(conn, FALSE);
2735 Curl_safefree(sftp_scp->path);
2736 sftp_scp->path = NULL;
2737 Curl_pgrsDone(conn);
2739 conn->data->req.keepon = 0; /* clear all bits */
2744 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2747 (void)premature; /* not used */
2749 if(status == CURLE_OK)
2750 state(conn, SSH_SCP_DONE);
2752 return ssh_done(conn, status);
2756 /* return number of received (decrypted) bytes */
2757 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2758 const void *mem, size_t len, CURLcode *err)
2761 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2763 /* libssh2_channel_write() returns int! */
2765 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2767 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2769 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2778 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2779 * a regular CURLcode value.
2781 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2782 char *mem, size_t len, CURLcode *err)
2785 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2787 /* libssh2_channel_read() returns int */
2789 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2791 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2792 if (nread == LIBSSH2_ERROR_EAGAIN) {
2801 * =============== SFTP ===============
2805 ***********************************************************************
2809 * This is the actual DO function for SFTP. Get a file/directory according to
2810 * the options previously setup.
2814 CURLcode sftp_perform(struct connectdata *conn,
2818 CURLcode result = CURLE_OK;
2820 DEBUGF(infof(conn->data, "DO phase starts\n"));
2822 *dophase_done = FALSE; /* not done yet */
2824 /* start the first command in the DO phase */
2825 state(conn, SSH_SFTP_QUOTE_INIT);
2827 /* run the state-machine */
2828 if(conn->data->state.used_interface == Curl_if_multi) {
2829 result = ssh_multi_statemach(conn, dophase_done);
2832 result = ssh_easy_statemach(conn, FALSE);
2833 *dophase_done = TRUE; /* with the easy interface we are done here */
2835 *connected = conn->bits.tcpconnect;
2838 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2844 /* called from multi.c while DOing */
2845 static CURLcode sftp_doing(struct connectdata *conn,
2849 result = ssh_multi_statemach(conn, dophase_done);
2852 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2857 /* BLOCKING, but the function is using the state machine so the only reason
2858 this is still blocking is that the multi interface code has no support for
2859 disconnecting operations that takes a while */
2860 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
2862 CURLcode result = CURLE_OK;
2863 (void) dead_connection;
2865 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2867 Curl_safefree(conn->data->state.proto.ssh);
2868 conn->data->state.proto.ssh = NULL;
2870 if(conn->proto.sshc.ssh_session) {
2871 /* only if there's a session still around to use! */
2872 state(conn, SSH_SFTP_SHUTDOWN);
2873 result = ssh_easy_statemach(conn, FALSE);
2876 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2882 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2885 struct ssh_conn *sshc = &conn->proto.sshc;
2887 if(status == CURLE_OK) {
2888 /* Before we shut down, see if there are any post-quote commands to
2890 if(!status && !premature && conn->data->set.postquote) {
2891 sshc->nextstate = SSH_SFTP_CLOSE;
2892 state(conn, SSH_SFTP_POSTQUOTE_INIT);
2895 state(conn, SSH_SFTP_CLOSE);
2897 return ssh_done(conn, status);
2900 /* return number of sent bytes */
2901 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
2902 const void *mem, size_t len, CURLcode *err)
2904 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2905 but is changed to ssize_t in 0.15. These days we don't
2906 support libssh2 0.15*/
2909 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2911 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2913 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2922 * Return number of received (decrypted) bytes
2924 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
2925 char *mem, size_t len, CURLcode *err)
2930 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
2932 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2934 if(nread == LIBSSH2_ERROR_EAGAIN) {
2941 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
2944 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
2946 * Permission to use, copy, modify, and distribute this software for any
2947 * purpose with or without fee is hereby granted, provided that the above
2948 * copyright notice and this permission notice appear in all copies.
2950 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2951 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2952 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2953 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2954 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2955 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2956 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2959 get_pathname(const char **cpp, char **path)
2961 const char *cp = *cpp, *end;
2964 static const char WHITESPACE[] = " \t\r\n";
2966 cp += strspn(cp, WHITESPACE);
2970 return CURLE_QUOTE_ERROR;
2973 *path = malloc(strlen(cp) + 1);
2975 return CURLE_OUT_OF_MEMORY;
2977 /* Check for quoted filenames */
2978 if(*cp == '\"' || *cp == '\'') {
2981 /* Search for terminating quote, unescape some chars */
2982 for (i = j = 0; i <= strlen(cp); i++) {
2983 if(cp[i] == quot) { /* Found quote */
2988 if(cp[i] == '\0') { /* End of string */
2989 /*error("Unterminated quote");*/
2992 if(cp[i] == '\\') { /* Escaped characters */
2994 if(cp[i] != '\'' && cp[i] != '\"' &&
2996 /*error("Bad escaped character '\\%c'",
3001 (*path)[j++] = cp[i];
3005 /*error("Empty quotes");*/
3008 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3011 /* Read to end of filename */
3012 end = strpbrk(cp, WHITESPACE);
3014 end = strchr(cp, '\0');
3015 *cpp = end + strspn(end, WHITESPACE);
3017 memcpy(*path, cp, end - cp);
3018 (*path)[end - cp] = '\0';
3023 Curl_safefree(*path);
3025 return CURLE_QUOTE_ERROR;
3029 static const char *sftp_libssh2_strerror(unsigned long err)
3032 case LIBSSH2_FX_NO_SUCH_FILE:
3033 return "No such file or directory";
3035 case LIBSSH2_FX_PERMISSION_DENIED:
3036 return "Permission denied";
3038 case LIBSSH2_FX_FAILURE:
3039 return "Operation failed";
3041 case LIBSSH2_FX_BAD_MESSAGE:
3042 return "Bad message from SFTP server";
3044 case LIBSSH2_FX_NO_CONNECTION:
3045 return "Not connected to SFTP server";
3047 case LIBSSH2_FX_CONNECTION_LOST:
3048 return "Connection to SFTP server lost";
3050 case LIBSSH2_FX_OP_UNSUPPORTED:
3051 return "Operation not supported by SFTP server";
3053 case LIBSSH2_FX_INVALID_HANDLE:
3054 return "Invalid handle";
3056 case LIBSSH2_FX_NO_SUCH_PATH:
3057 return "No such file or directory";
3059 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3060 return "File already exists";
3062 case LIBSSH2_FX_WRITE_PROTECT:
3063 return "File is write protected";
3065 case LIBSSH2_FX_NO_MEDIA:
3068 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3071 case LIBSSH2_FX_QUOTA_EXCEEDED:
3072 return "User quota exceeded";
3074 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3075 return "Unknown principle";
3077 case LIBSSH2_FX_LOCK_CONFlICT:
3078 return "File lock conflict";
3080 case LIBSSH2_FX_DIR_NOT_EMPTY:
3081 return "Directory not empty";
3083 case LIBSSH2_FX_NOT_A_DIRECTORY:
3084 return "Not a directory";
3086 case LIBSSH2_FX_INVALID_FILENAME:
3087 return "Invalid filename";
3089 case LIBSSH2_FX_LINK_LOOP:
3090 return "Link points to itself";
3092 return "Unknown error in libssh2";
3095 #endif /* USE_LIBSSH2 */