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);
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);
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;
990 /* Return the error type */
991 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
992 result = sftp_libssh2_error_to_CURLE(err);
993 sshc->actualcode = result?result:CURLE_SSH;
994 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
996 state(conn, SSH_STOP);
1000 /* This is the last step in the SFTP connect phase. Do note that while
1001 we get the homedir here, we get the "workingpath" in the DO action
1002 since the homedir will remain the same between request but the
1003 working path will not. */
1004 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1005 state(conn, SSH_STOP);
1008 case SSH_SFTP_QUOTE_INIT:
1010 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1012 sshc->actualcode = result;
1013 state(conn, SSH_STOP);
1017 if(data->set.quote) {
1018 infof(data, "Sending quote commands\n");
1019 sshc->quote_item = data->set.quote;
1020 state(conn, SSH_SFTP_QUOTE);
1023 state(conn, SSH_SFTP_TRANS_INIT);
1027 case SSH_SFTP_POSTQUOTE_INIT:
1028 if(data->set.postquote) {
1029 infof(data, "Sending quote commands\n");
1030 sshc->quote_item = data->set.postquote;
1031 state(conn, SSH_SFTP_QUOTE);
1034 state(conn, SSH_STOP);
1038 case SSH_SFTP_QUOTE:
1039 /* Send any quote commands */
1044 * Support some of the "FTP" commands
1046 if(curl_strequal("pwd", sshc->quote_item->data)) {
1047 /* output debug output if that is requested */
1048 if(data->set.verbose) {
1049 char tmp[PATH_MAX+1];
1051 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1052 snprintf(tmp, PATH_MAX, "257 \"%s\" is current directory.\n",
1054 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1056 state(conn, SSH_SFTP_NEXT_QUOTE);
1059 else if(sshc->quote_item->data) {
1061 * the arguments following the command must be separated from the
1062 * command with a space so we can check for it unconditionally
1064 cp = strchr(sshc->quote_item->data, ' ');
1066 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1067 state(conn, SSH_SFTP_CLOSE);
1068 sshc->actualcode = CURLE_QUOTE_ERROR;
1073 * also, every command takes at least one argument so we get that
1074 * first argument right now
1076 result = get_pathname(&cp, &sshc->quote_path1);
1078 if(result == CURLE_OUT_OF_MEMORY)
1079 failf(data, "Out of memory");
1081 failf(data, "Syntax error: Bad first parameter");
1082 state(conn, SSH_SFTP_CLOSE);
1083 sshc->actualcode = result;
1088 * SFTP is a binary protocol, so we don't send text commands to
1089 * the server. Instead, we scan for commands for commands used by
1090 * OpenSSH's sftp program and call the appropriate libssh2
1093 if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
1094 curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
1095 curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
1096 /* attribute change */
1098 /* sshc->quote_path1 contains the mode to set */
1099 /* get the destination */
1100 result = get_pathname(&cp, &sshc->quote_path2);
1102 if(result == CURLE_OUT_OF_MEMORY)
1103 failf(data, "Out of memory");
1105 failf(data, "Syntax error in chgrp/chmod/chown: "
1106 "Bad second parameter");
1107 Curl_safefree(sshc->quote_path1);
1108 sshc->quote_path1 = NULL;
1109 state(conn, SSH_SFTP_CLOSE);
1110 sshc->actualcode = result;
1113 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1114 state(conn, SSH_SFTP_QUOTE_STAT);
1117 else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
1118 curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
1119 /* symbolic linking */
1120 /* sshc->quote_path1 is the source */
1121 /* get the destination */
1122 result = get_pathname(&cp, &sshc->quote_path2);
1124 if(result == CURLE_OUT_OF_MEMORY)
1125 failf(data, "Out of memory");
1128 "Syntax error in ln/symlink: Bad second parameter");
1129 Curl_safefree(sshc->quote_path1);
1130 sshc->quote_path1 = NULL;
1131 state(conn, SSH_SFTP_CLOSE);
1132 sshc->actualcode = result;
1135 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1138 else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
1140 state(conn, SSH_SFTP_QUOTE_MKDIR);
1143 else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
1145 /* first param is the source path */
1146 /* second param is the dest. path */
1147 result = get_pathname(&cp, &sshc->quote_path2);
1149 if(result == CURLE_OUT_OF_MEMORY)
1150 failf(data, "Out of memory");
1152 failf(data, "Syntax error in rename: Bad second parameter");
1153 Curl_safefree(sshc->quote_path1);
1154 sshc->quote_path1 = NULL;
1155 state(conn, SSH_SFTP_CLOSE);
1156 sshc->actualcode = result;
1159 state(conn, SSH_SFTP_QUOTE_RENAME);
1162 else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
1164 state(conn, SSH_SFTP_QUOTE_RMDIR);
1167 else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
1168 state(conn, SSH_SFTP_QUOTE_UNLINK);
1172 failf(data, "Unknown SFTP command");
1173 Curl_safefree(sshc->quote_path1);
1174 sshc->quote_path1 = NULL;
1175 Curl_safefree(sshc->quote_path2);
1176 sshc->quote_path2 = NULL;
1177 state(conn, SSH_SFTP_CLOSE);
1178 sshc->actualcode = CURLE_QUOTE_ERROR;
1182 if(!sshc->quote_item) {
1183 state(conn, SSH_SFTP_TRANS_INIT);
1187 case SSH_SFTP_NEXT_QUOTE:
1188 if(sshc->quote_path1) {
1189 Curl_safefree(sshc->quote_path1);
1190 sshc->quote_path1 = NULL;
1192 if(sshc->quote_path2) {
1193 Curl_safefree(sshc->quote_path2);
1194 sshc->quote_path2 = NULL;
1197 sshc->quote_item = sshc->quote_item->next;
1199 if(sshc->quote_item) {
1200 state(conn, SSH_SFTP_QUOTE);
1203 if(sshc->nextstate != SSH_NO_STATE) {
1204 state(conn, sshc->nextstate);
1205 sshc->nextstate = SSH_NO_STATE;
1208 state(conn, SSH_SFTP_TRANS_INIT);
1213 case SSH_SFTP_QUOTE_STAT:
1214 if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1215 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1216 * set them both at once, we need to obtain the current ownership
1217 * first. This takes an extra protocol round trip.
1219 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1220 (unsigned int)strlen(sshc->quote_path2),
1222 &sshc->quote_attrs);
1223 if(rc == LIBSSH2_ERROR_EAGAIN) {
1226 else if(rc != 0) { /* get those attributes */
1227 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1228 Curl_safefree(sshc->quote_path1);
1229 sshc->quote_path1 = NULL;
1230 Curl_safefree(sshc->quote_path2);
1231 sshc->quote_path2 = NULL;
1232 failf(data, "Attempt to get SFTP stats failed: %s",
1233 sftp_libssh2_strerror(err));
1234 state(conn, SSH_SFTP_CLOSE);
1235 sshc->actualcode = CURLE_QUOTE_ERROR;
1240 /* Now set the new attributes... */
1241 if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
1242 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1243 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1244 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1245 Curl_safefree(sshc->quote_path1);
1246 sshc->quote_path1 = NULL;
1247 Curl_safefree(sshc->quote_path2);
1248 sshc->quote_path2 = NULL;
1249 failf(data, "Syntax error: chgrp gid not a number");
1250 state(conn, SSH_SFTP_CLOSE);
1251 sshc->actualcode = CURLE_QUOTE_ERROR;
1255 else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1256 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1257 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1258 /* permissions are octal */
1259 if(sshc->quote_attrs.permissions == 0 &&
1260 !ISDIGIT(sshc->quote_path1[0])) {
1261 Curl_safefree(sshc->quote_path1);
1262 sshc->quote_path1 = NULL;
1263 Curl_safefree(sshc->quote_path2);
1264 sshc->quote_path2 = NULL;
1265 failf(data, "Syntax error: chmod permissions not a number");
1266 state(conn, SSH_SFTP_CLOSE);
1267 sshc->actualcode = CURLE_QUOTE_ERROR;
1271 else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
1272 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1273 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1274 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1275 Curl_safefree(sshc->quote_path1);
1276 sshc->quote_path1 = NULL;
1277 Curl_safefree(sshc->quote_path2);
1278 sshc->quote_path2 = NULL;
1279 failf(data, "Syntax error: chown uid not a number");
1280 state(conn, SSH_SFTP_CLOSE);
1281 sshc->actualcode = CURLE_QUOTE_ERROR;
1286 /* Now send the completed structure... */
1287 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1290 case SSH_SFTP_QUOTE_SETSTAT:
1291 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1292 (unsigned int)strlen(sshc->quote_path2),
1293 LIBSSH2_SFTP_SETSTAT,
1294 &sshc->quote_attrs);
1295 if(rc == LIBSSH2_ERROR_EAGAIN) {
1299 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
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, "Attempt to set SFTP stats failed: %s",
1305 sftp_libssh2_strerror(err));
1306 state(conn, SSH_SFTP_CLOSE);
1307 sshc->actualcode = CURLE_QUOTE_ERROR;
1310 state(conn, SSH_SFTP_NEXT_QUOTE);
1313 case SSH_SFTP_QUOTE_SYMLINK:
1314 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1315 (unsigned int)strlen(sshc->quote_path1),
1317 (unsigned int)strlen(sshc->quote_path2),
1318 LIBSSH2_SFTP_SYMLINK);
1319 if(rc == LIBSSH2_ERROR_EAGAIN) {
1323 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1324 Curl_safefree(sshc->quote_path1);
1325 sshc->quote_path1 = NULL;
1326 Curl_safefree(sshc->quote_path2);
1327 sshc->quote_path2 = NULL;
1328 failf(data, "symlink command failed: %s",
1329 sftp_libssh2_strerror(err));
1330 state(conn, SSH_SFTP_CLOSE);
1331 sshc->actualcode = CURLE_QUOTE_ERROR;
1334 state(conn, SSH_SFTP_NEXT_QUOTE);
1337 case SSH_SFTP_QUOTE_MKDIR:
1338 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1339 (unsigned int)strlen(sshc->quote_path1),
1341 if(rc == LIBSSH2_ERROR_EAGAIN) {
1345 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1346 Curl_safefree(sshc->quote_path1);
1347 sshc->quote_path1 = NULL;
1348 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1349 state(conn, SSH_SFTP_CLOSE);
1350 sshc->actualcode = CURLE_QUOTE_ERROR;
1353 state(conn, SSH_SFTP_NEXT_QUOTE);
1356 case SSH_SFTP_QUOTE_RENAME:
1357 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1358 (unsigned int)strlen(sshc->quote_path1),
1360 (unsigned int)strlen(sshc->quote_path2),
1361 LIBSSH2_SFTP_RENAME_OVERWRITE |
1362 LIBSSH2_SFTP_RENAME_ATOMIC |
1363 LIBSSH2_SFTP_RENAME_NATIVE);
1364 if(rc == LIBSSH2_ERROR_EAGAIN) {
1368 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1369 Curl_safefree(sshc->quote_path1);
1370 sshc->quote_path1 = NULL;
1371 Curl_safefree(sshc->quote_path2);
1372 sshc->quote_path2 = NULL;
1373 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1374 state(conn, SSH_SFTP_CLOSE);
1375 sshc->actualcode = CURLE_QUOTE_ERROR;
1378 state(conn, SSH_SFTP_NEXT_QUOTE);
1381 case SSH_SFTP_QUOTE_RMDIR:
1382 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1383 (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, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1392 state(conn, SSH_SFTP_CLOSE);
1393 sshc->actualcode = CURLE_QUOTE_ERROR;
1396 state(conn, SSH_SFTP_NEXT_QUOTE);
1399 case SSH_SFTP_QUOTE_UNLINK:
1400 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1401 (unsigned int)strlen(sshc->quote_path1));
1402 if(rc == LIBSSH2_ERROR_EAGAIN) {
1406 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1407 Curl_safefree(sshc->quote_path1);
1408 sshc->quote_path1 = NULL;
1409 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1410 state(conn, SSH_SFTP_CLOSE);
1411 sshc->actualcode = CURLE_QUOTE_ERROR;
1414 state(conn, SSH_SFTP_NEXT_QUOTE);
1417 case SSH_SFTP_TRANS_INIT:
1418 if(data->set.upload)
1419 state(conn, SSH_SFTP_UPLOAD_INIT);
1421 if(data->set.opt_no_body)
1422 state(conn, SSH_STOP);
1423 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1424 state(conn, SSH_SFTP_READDIR_INIT);
1426 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1430 case SSH_SFTP_UPLOAD_INIT:
1432 unsigned long flags;
1434 * NOTE!!! libssh2 requires that the destination path is a full path
1435 * that includes the destination file and name OR ends in a "/"
1436 * If this is not done the destination file will be named the
1437 * same name as the last directory in the path.
1440 if(data->state.resume_from != 0) {
1441 LIBSSH2_SFTP_ATTRIBUTES attrs;
1442 if(data->state.resume_from < 0) {
1443 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1444 (unsigned int)strlen(sftp_scp->path),
1445 LIBSSH2_SFTP_STAT, &attrs);
1446 if(rc == LIBSSH2_ERROR_EAGAIN) {
1450 data->state.resume_from = 0;
1453 curl_off_t size = attrs.filesize;
1455 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1456 return CURLE_BAD_DOWNLOAD_RESUME;
1458 data->state.resume_from = attrs.filesize;
1463 if(data->set.ftp_append)
1464 /* Try to open for append, but create if nonexisting */
1465 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1466 else if (data->state.resume_from > 0)
1467 /* If we have restart position then open for append */
1468 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1470 /* Clear file before writing (normal behaviour) */
1471 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1474 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1475 (unsigned int)strlen(sftp_scp->path),
1476 flags, data->set.new_file_perms,
1477 LIBSSH2_SFTP_OPENFILE);
1479 if(!sshc->sftp_handle) {
1480 rc = libssh2_session_last_errno(sshc->ssh_session);
1482 if(LIBSSH2_ERROR_EAGAIN == rc)
1485 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1486 /* only when there was an SFTP protocol error can we extract
1488 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1490 err = -1; /* not an sftp error at all */
1492 if(sshc->secondCreateDirs) {
1493 state(conn, SSH_SFTP_CLOSE);
1494 sshc->actualcode = err>= LIBSSH2_FX_OK?
1495 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1496 failf(data, "Creating the dir/file failed: %s",
1497 sftp_libssh2_strerror(err));
1500 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1501 (err == LIBSSH2_FX_FAILURE) ||
1502 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1503 (data->set.ftp_create_missing_dirs &&
1504 (strlen(sftp_scp->path) > 1))) {
1505 /* try to create the path remotely */
1506 sshc->secondCreateDirs = 1;
1507 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1510 state(conn, SSH_SFTP_CLOSE);
1511 sshc->actualcode = err>= LIBSSH2_FX_OK?
1512 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1513 if(!sshc->actualcode) {
1514 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1515 zero even though libssh2_sftp_open() failed previously! We need
1516 to work around that! */
1517 sshc->actualcode = CURLE_SSH;
1520 failf(data, "Upload failed: %s (%d/%d)",
1521 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1527 /* If we have restart point then we need to seek to the correct
1529 if(data->state.resume_from > 0) {
1530 /* Let's read off the proper amount of bytes from the input. */
1531 if(conn->seek_func) {
1532 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1536 if(seekerr != CURL_SEEKFUNC_OK){
1538 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1539 failf(data, "Could not seek stream");
1540 return CURLE_FTP_COULDNT_USE_REST;
1542 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1544 curl_off_t passed=0;
1546 size_t readthisamountnow =
1547 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1548 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1550 size_t actuallyread =
1551 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1554 passed += actuallyread;
1555 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1556 /* this checks for greater-than only to make sure that the
1557 CURL_READFUNC_ABORT return code still aborts */
1558 failf(data, "Failed to read data");
1559 return CURLE_FTP_COULDNT_USE_REST;
1561 } while(passed < data->state.resume_from);
1565 /* now, decrease the size of the read */
1566 if(data->set.infilesize > 0) {
1567 data->set.infilesize -= data->state.resume_from;
1568 data->req.size = data->set.infilesize;
1569 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1572 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1574 if(data->set.infilesize > 0) {
1575 data->req.size = data->set.infilesize;
1576 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1579 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1581 /* not set by Curl_setup_transfer to preserve keepon bits */
1582 conn->sockfd = conn->writesockfd;
1585 state(conn, SSH_SFTP_CLOSE);
1586 sshc->actualcode = result;
1589 /* store this original bitmask setup to use later on if we can't
1590 figure out a "real" bitmask */
1591 sshc->orig_waitfor = data->req.keepon;
1593 state(conn, SSH_STOP);
1598 case SSH_SFTP_CREATE_DIRS_INIT:
1599 if(strlen(sftp_scp->path) > 1) {
1600 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1601 state(conn, SSH_SFTP_CREATE_DIRS);
1604 state(conn, SSH_SFTP_UPLOAD_INIT);
1608 case SSH_SFTP_CREATE_DIRS:
1609 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1610 *sshc->slash_pos = 0;
1612 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1613 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1617 state(conn, SSH_SFTP_UPLOAD_INIT);
1621 case SSH_SFTP_CREATE_DIRS_MKDIR:
1622 /* 'mode' - parameter is preliminary - default to 0644 */
1623 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1624 (unsigned int)strlen(sftp_scp->path),
1625 data->set.new_directory_perms);
1626 if(rc == LIBSSH2_ERROR_EAGAIN) {
1629 *sshc->slash_pos = '/';
1632 unsigned int sftp_err = 0;
1634 * Abort if failure wasn't that the dir already exists or the
1635 * permission was denied (creation might succeed further down the
1636 * path) - retry on unspecific FAILURE also
1638 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1639 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1640 (sftp_err != LIBSSH2_FX_FAILURE) &&
1641 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1642 result = sftp_libssh2_error_to_CURLE(sftp_err);
1643 state(conn, SSH_SFTP_CLOSE);
1644 sshc->actualcode = result?result:CURLE_SSH;
1648 state(conn, SSH_SFTP_CREATE_DIRS);
1651 case SSH_SFTP_READDIR_INIT:
1653 * This is a directory that we are trying to get, so produce a directory
1656 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1659 strlen(sftp_scp->path),
1660 0, 0, LIBSSH2_SFTP_OPENDIR);
1661 if(!sshc->sftp_handle) {
1662 if(libssh2_session_last_errno(sshc->ssh_session) ==
1663 LIBSSH2_ERROR_EAGAIN) {
1664 rc = LIBSSH2_ERROR_EAGAIN;
1668 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1669 failf(data, "Could not open directory for reading: %s",
1670 sftp_libssh2_strerror(err));
1671 state(conn, SSH_SFTP_CLOSE);
1672 result = sftp_libssh2_error_to_CURLE(err);
1673 sshc->actualcode = result?result:CURLE_SSH;
1677 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1678 state(conn, SSH_SFTP_CLOSE);
1679 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1682 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1683 Curl_safefree(sshc->readdir_filename);
1684 sshc->readdir_filename = NULL;
1685 state(conn, SSH_SFTP_CLOSE);
1686 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1689 state(conn, SSH_SFTP_READDIR);
1692 case SSH_SFTP_READDIR:
1693 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1694 sshc->readdir_filename,
1696 sshc->readdir_longentry,
1698 &sshc->readdir_attrs);
1699 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1700 rc = LIBSSH2_ERROR_EAGAIN;
1703 if(sshc->readdir_len > 0) {
1704 sshc->readdir_filename[sshc->readdir_len] = '\0';
1706 if(data->set.ftp_list_only) {
1709 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1710 if(tmpLine == NULL) {
1711 state(conn, SSH_SFTP_CLOSE);
1712 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1715 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1716 tmpLine, sshc->readdir_len+1);
1717 Curl_safefree(tmpLine);
1720 state(conn, SSH_STOP);
1723 /* since this counts what we send to the client, we include the
1724 newline in this counter */
1725 data->req.bytecount += sshc->readdir_len+1;
1727 /* output debug output if that is requested */
1728 if(data->set.verbose) {
1729 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1730 sshc->readdir_len, conn);
1734 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1735 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1736 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1737 if(!sshc->readdir_line) {
1738 Curl_safefree(sshc->readdir_filename);
1739 sshc->readdir_filename = NULL;
1740 Curl_safefree(sshc->readdir_longentry);
1741 sshc->readdir_longentry = NULL;
1742 state(conn, SSH_SFTP_CLOSE);
1743 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1747 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1748 sshc->readdir_currLen);
1749 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1750 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1751 LIBSSH2_SFTP_S_IFLNK)) {
1752 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1753 if(sshc->readdir_linkPath == NULL) {
1754 Curl_safefree(sshc->readdir_filename);
1755 sshc->readdir_filename = NULL;
1756 Curl_safefree(sshc->readdir_longentry);
1757 sshc->readdir_longentry = NULL;
1758 state(conn, SSH_SFTP_CLOSE);
1759 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1763 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1764 sshc->readdir_filename);
1765 state(conn, SSH_SFTP_READDIR_LINK);
1768 state(conn, SSH_SFTP_READDIR_BOTTOM);
1772 else if(sshc->readdir_len == 0) {
1773 Curl_safefree(sshc->readdir_filename);
1774 sshc->readdir_filename = NULL;
1775 Curl_safefree(sshc->readdir_longentry);
1776 sshc->readdir_longentry = NULL;
1777 state(conn, SSH_SFTP_READDIR_DONE);
1780 else if(sshc->readdir_len <= 0) {
1781 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1782 result = sftp_libssh2_error_to_CURLE(err);
1783 sshc->actualcode = result?result:CURLE_SSH;
1784 failf(data, "Could not open remote file for reading: %s :: %d",
1785 sftp_libssh2_strerror(err),
1786 libssh2_session_last_errno(sshc->ssh_session));
1787 Curl_safefree(sshc->readdir_filename);
1788 sshc->readdir_filename = NULL;
1789 Curl_safefree(sshc->readdir_longentry);
1790 sshc->readdir_longentry = NULL;
1791 state(conn, SSH_SFTP_CLOSE);
1796 case SSH_SFTP_READDIR_LINK:
1798 libssh2_sftp_symlink_ex(sshc->sftp_session,
1799 sshc->readdir_linkPath,
1800 (unsigned int) strlen(sshc->readdir_linkPath),
1801 sshc->readdir_filename,
1802 PATH_MAX, LIBSSH2_SFTP_READLINK);
1803 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1804 rc = LIBSSH2_ERROR_EAGAIN;
1807 Curl_safefree(sshc->readdir_linkPath);
1808 sshc->readdir_linkPath = NULL;
1809 sshc->readdir_line = realloc(sshc->readdir_line,
1810 sshc->readdir_totalLen + 4 +
1812 if(!sshc->readdir_line) {
1813 Curl_safefree(sshc->readdir_filename);
1814 sshc->readdir_filename = NULL;
1815 Curl_safefree(sshc->readdir_longentry);
1816 sshc->readdir_longentry = NULL;
1817 state(conn, SSH_SFTP_CLOSE);
1818 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1822 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1823 sshc->readdir_currLen,
1824 sshc->readdir_totalLen -
1825 sshc->readdir_currLen,
1827 sshc->readdir_filename);
1829 state(conn, SSH_SFTP_READDIR_BOTTOM);
1832 case SSH_SFTP_READDIR_BOTTOM:
1833 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1834 sshc->readdir_currLen,
1835 sshc->readdir_totalLen -
1836 sshc->readdir_currLen, "\n");
1837 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1839 sshc->readdir_currLen);
1841 if(result == CURLE_OK) {
1843 /* output debug output if that is requested */
1844 if(data->set.verbose) {
1845 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1846 sshc->readdir_currLen, conn);
1848 data->req.bytecount += sshc->readdir_currLen;
1850 Curl_safefree(sshc->readdir_line);
1851 sshc->readdir_line = NULL;
1853 state(conn, SSH_STOP);
1856 state(conn, SSH_SFTP_READDIR);
1859 case SSH_SFTP_READDIR_DONE:
1860 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1861 LIBSSH2_ERROR_EAGAIN) {
1862 rc = LIBSSH2_ERROR_EAGAIN;
1865 sshc->sftp_handle = NULL;
1866 Curl_safefree(sshc->readdir_filename);
1867 sshc->readdir_filename = NULL;
1868 Curl_safefree(sshc->readdir_longentry);
1869 sshc->readdir_longentry = NULL;
1871 /* no data to transfer */
1872 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1873 state(conn, SSH_STOP);
1876 case SSH_SFTP_DOWNLOAD_INIT:
1878 * Work on getting the specified file
1881 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1882 (unsigned int)strlen(sftp_scp->path),
1883 LIBSSH2_FXF_READ, data->set.new_file_perms,
1884 LIBSSH2_SFTP_OPENFILE);
1885 if(!sshc->sftp_handle) {
1886 if(libssh2_session_last_errno(sshc->ssh_session) ==
1887 LIBSSH2_ERROR_EAGAIN) {
1888 rc = LIBSSH2_ERROR_EAGAIN;
1892 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1893 failf(data, "Could not open remote file for reading: %s",
1894 sftp_libssh2_strerror(err));
1895 state(conn, SSH_SFTP_CLOSE);
1896 result = sftp_libssh2_error_to_CURLE(err);
1897 sshc->actualcode = result?result:CURLE_SSH;
1901 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1904 case SSH_SFTP_DOWNLOAD_STAT:
1906 LIBSSH2_SFTP_ATTRIBUTES attrs;
1908 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1909 (unsigned int)strlen(sftp_scp->path),
1910 LIBSSH2_SFTP_STAT, &attrs);
1911 if(rc == LIBSSH2_ERROR_EAGAIN) {
1916 * libssh2_sftp_open() didn't return an error, so maybe the server
1917 * just doesn't support stat()
1919 data->req.size = -1;
1920 data->req.maxdownload = -1;
1923 curl_off_t size = attrs.filesize;
1926 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1927 return CURLE_BAD_DOWNLOAD_RESUME;
1929 if(conn->data->state.use_range) {
1930 curl_off_t from, to;
1934 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1935 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
1937 to=curlx_strtoofft(ptr, &ptr2, 0);
1938 if((ptr == ptr2) /* no "to" value given */
1943 /* from is relative to end of file */
1947 failf(data, "Offset (%"
1948 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1949 from, attrs.filesize);
1950 return CURLE_BAD_DOWNLOAD_RESUME;
1957 size = to - from + 1;
1960 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
1962 data->req.size = size;
1963 data->req.maxdownload = size;
1964 Curl_pgrsSetDownloadSize(data, size);
1967 /* We can resume if we can seek to the resume position */
1968 if(data->state.resume_from) {
1969 if(data->state.resume_from < 0) {
1970 /* We're supposed to download the last abs(from) bytes */
1971 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
1972 failf(data, "Offset (%"
1973 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1974 data->state.resume_from, attrs.filesize);
1975 return CURLE_BAD_DOWNLOAD_RESUME;
1977 /* download from where? */
1978 data->state.resume_from += attrs.filesize;
1981 if((curl_off_t)attrs.filesize < data->state.resume_from) {
1982 failf(data, "Offset (%" FORMAT_OFF_T
1983 ") was beyond file size (%" FORMAT_OFF_T ")",
1984 data->state.resume_from, attrs.filesize);
1985 return CURLE_BAD_DOWNLOAD_RESUME;
1988 /* Does a completed file need to be seeked and started or closed ? */
1989 /* Now store the number of bytes we are expected to download */
1990 data->req.size = attrs.filesize - data->state.resume_from;
1991 data->req.maxdownload = attrs.filesize - data->state.resume_from;
1992 Curl_pgrsSetDownloadSize(data,
1993 attrs.filesize - data->state.resume_from);
1994 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1997 /* Setup the actual download */
1998 if(data->req.size == 0) {
1999 /* no data to transfer */
2000 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2001 infof(data, "File already completely downloaded\n");
2002 state(conn, SSH_STOP);
2006 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2007 FALSE, NULL, -1, NULL);
2009 /* not set by Curl_setup_transfer to preserve keepon bits */
2010 conn->writesockfd = conn->sockfd;
2012 /* FIXME: here should be explained why we need it to start the
2014 conn->cselect_bits = CURL_CSELECT_IN;
2017 state(conn, SSH_SFTP_CLOSE);
2018 sshc->actualcode = result;
2021 state(conn, SSH_STOP);
2025 case SSH_SFTP_CLOSE:
2026 if(sshc->sftp_handle) {
2027 rc = libssh2_sftp_close(sshc->sftp_handle);
2028 if(rc == LIBSSH2_ERROR_EAGAIN) {
2032 infof(data, "Failed to close libssh2 file\n");
2034 sshc->sftp_handle = NULL;
2036 Curl_safefree(sftp_scp->path);
2037 sftp_scp->path = NULL;
2039 DEBUGF(infof(data, "SFTP DONE done\n"));
2041 state(conn, SSH_SFTP_SHUTDOWN);
2043 state(conn, SSH_STOP);
2044 result = sshc->actualcode;
2047 case SSH_SFTP_SHUTDOWN:
2048 /* during times we get here due to a broken transfer and then the
2049 sftp_handle might not have been taken down so make sure that is done
2050 before we proceed */
2052 if(sshc->sftp_handle) {
2053 rc = libssh2_sftp_close(sshc->sftp_handle);
2054 if(rc == LIBSSH2_ERROR_EAGAIN) {
2058 infof(data, "Failed to close libssh2 file\n");
2060 sshc->sftp_handle = NULL;
2062 if(sshc->sftp_session) {
2063 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2064 if(rc == LIBSSH2_ERROR_EAGAIN) {
2068 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2070 sshc->sftp_session = NULL;
2073 Curl_safefree(sshc->homedir);
2074 sshc->homedir = NULL;
2076 state(conn, SSH_SESSION_DISCONNECT);
2079 case SSH_SCP_TRANS_INIT:
2080 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2082 sshc->actualcode = result;
2083 state(conn, SSH_STOP);
2087 if(data->set.upload) {
2088 if(data->set.infilesize < 0) {
2089 failf(data, "SCP requires a known file size for upload");
2090 sshc->actualcode = CURLE_UPLOAD_FAILED;
2091 state(conn, SSH_SCP_CHANNEL_FREE);
2094 state(conn, SSH_SCP_UPLOAD_INIT);
2097 state(conn, SSH_SCP_DOWNLOAD_INIT);
2101 case SSH_SCP_UPLOAD_INIT:
2103 * libssh2 requires that the destination path is a full path that
2104 * includes the destination file and name OR ends in a "/" . If this is
2105 * not done the destination file will be named the same name as the last
2106 * directory in the path.
2109 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2110 data->set.infilesize);
2111 if(!sshc->ssh_channel) {
2112 if(libssh2_session_last_errno(sshc->ssh_session) ==
2113 LIBSSH2_ERROR_EAGAIN) {
2114 rc = LIBSSH2_ERROR_EAGAIN;
2121 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2122 &err_msg, NULL, 0));
2123 failf(conn->data, "%s", err_msg);
2124 state(conn, SSH_SCP_CHANNEL_FREE);
2125 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2131 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2134 /* not set by Curl_setup_transfer to preserve keepon bits */
2135 conn->sockfd = conn->writesockfd;
2138 state(conn, SSH_SCP_CHANNEL_FREE);
2139 sshc->actualcode = result;
2142 state(conn, SSH_STOP);
2146 case SSH_SCP_DOWNLOAD_INIT:
2149 * We must check the remote file; if it is a directory no values will
2153 curl_off_t bytecount;
2155 /* clear the struct scp recv will fill in */
2156 memset(&sb, 0, sizeof(struct stat));
2158 /* get a fresh new channel from the ssh layer */
2159 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2160 sftp_scp->path, &sb);
2161 if(!sshc->ssh_channel) {
2162 if(libssh2_session_last_errno(sshc->ssh_session) ==
2163 LIBSSH2_ERROR_EAGAIN) {
2164 rc = LIBSSH2_ERROR_EAGAIN;
2171 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2172 &err_msg, NULL, 0));
2173 failf(conn->data, "%s", err_msg);
2174 state(conn, SSH_SCP_CHANNEL_FREE);
2175 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2181 bytecount = (curl_off_t)sb.st_size;
2182 data->req.maxdownload = (curl_off_t)sb.st_size;
2183 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2185 /* not set by Curl_setup_transfer to preserve keepon bits */
2186 conn->writesockfd = conn->sockfd;
2188 /* FIXME: here should be explained why we need it to start the
2190 conn->cselect_bits = CURL_CSELECT_IN;
2193 state(conn, SSH_SCP_CHANNEL_FREE);
2194 sshc->actualcode = result;
2197 state(conn, SSH_STOP);
2202 if(data->set.upload)
2203 state(conn, SSH_SCP_SEND_EOF);
2205 state(conn, SSH_SCP_CHANNEL_FREE);
2208 case SSH_SCP_SEND_EOF:
2209 if(sshc->ssh_channel) {
2210 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2211 if(rc == LIBSSH2_ERROR_EAGAIN) {
2215 infof(data, "Failed to send libssh2 channel EOF\n");
2218 state(conn, SSH_SCP_WAIT_EOF);
2221 case SSH_SCP_WAIT_EOF:
2222 if(sshc->ssh_channel) {
2223 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2224 if(rc == LIBSSH2_ERROR_EAGAIN) {
2228 infof(data, "Failed to get channel EOF: %d\n", rc);
2231 state(conn, SSH_SCP_WAIT_CLOSE);
2234 case SSH_SCP_WAIT_CLOSE:
2235 if(sshc->ssh_channel) {
2236 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2237 if(rc == LIBSSH2_ERROR_EAGAIN) {
2241 infof(data, "Channel failed to close: %d\n", rc);
2244 state(conn, SSH_SCP_CHANNEL_FREE);
2247 case SSH_SCP_CHANNEL_FREE:
2248 if(sshc->ssh_channel) {
2249 rc = libssh2_channel_free(sshc->ssh_channel);
2250 if(rc == LIBSSH2_ERROR_EAGAIN) {
2254 infof(data, "Failed to free libssh2 scp subsystem\n");
2256 sshc->ssh_channel = NULL;
2258 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2260 state(conn, SSH_SESSION_DISCONNECT);
2262 state(conn, SSH_STOP);
2263 result = sshc->actualcode;
2266 case SSH_SESSION_DISCONNECT:
2267 /* during weird times when we've been prematurely aborted, the channel
2268 is still alive when we reach this state and we MUST kill the channel
2270 if(sshc->ssh_channel) {
2271 rc = libssh2_channel_free(sshc->ssh_channel);
2272 if(rc == LIBSSH2_ERROR_EAGAIN) {
2276 infof(data, "Failed to free libssh2 scp subsystem\n");
2278 sshc->ssh_channel = NULL;
2281 if(sshc->ssh_session) {
2282 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2283 if(rc == LIBSSH2_ERROR_EAGAIN) {
2287 infof(data, "Failed to disconnect libssh2 session\n");
2291 Curl_safefree(sshc->homedir);
2292 sshc->homedir = NULL;
2294 state(conn, SSH_SESSION_FREE);
2297 case SSH_SESSION_FREE:
2298 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2300 libssh2_knownhost_free(sshc->kh);
2305 if(sshc->ssh_session) {
2306 rc = libssh2_session_free(sshc->ssh_session);
2307 if(rc == LIBSSH2_ERROR_EAGAIN) {
2311 infof(data, "Failed to free libssh2 session\n");
2313 sshc->ssh_session = NULL;
2315 conn->bits.close = TRUE;
2316 sshc->nextstate = SSH_NO_STATE;
2317 state(conn, SSH_STOP);
2318 result = sshc->actualcode;
2322 /* fallthrough, just stop! */
2324 /* internal error */
2325 sshc->nextstate = SSH_NO_STATE;
2326 state(conn, SSH_STOP);
2330 } while(!rc && (sshc->state != SSH_STOP));
2332 if(rc == LIBSSH2_ERROR_EAGAIN) {
2333 /* we would block, we need to wait for the socket to be ready (in the
2334 right direction too)! */
2341 /* called by the multi interface to figure out what socket(s) to wait for and
2342 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2343 static int ssh_perform_getsock(const struct connectdata *conn,
2344 curl_socket_t *sock, /* points to numsocks
2345 number of sockets */
2348 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2349 int bitmap = GETSOCK_BLANK;
2352 sock[0] = conn->sock[FIRSTSOCKET];
2354 if(conn->waitfor & KEEP_RECV)
2355 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2357 if(conn->waitfor & KEEP_SEND)
2358 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2362 /* if we don't know the direction we can use the generic *_getsock()
2363 function even for the protocol_connect and doing states */
2364 return Curl_single_getsock(conn, sock, numsocks);
2368 /* Generic function called by the multi interface to figure out what socket(s)
2369 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2370 static int ssh_getsock(struct connectdata *conn,
2371 curl_socket_t *sock, /* points to numsocks number
2375 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2379 /* if we don't know any direction we can just play along as we used to and
2380 not provide any sensible info */
2381 return GETSOCK_BLANK;
2383 /* if we know the direction we can use the generic *_getsock() function even
2384 for the protocol_connect and doing states */
2385 return ssh_perform_getsock(conn, sock, numsocks);
2389 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2391 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2392 * function is used to figure out in what direction and stores this info so
2393 * that the multi interface can take advantage of it. Make sure to call this
2394 * function in all cases so that when it _doesn't_ return EAGAIN we can
2395 * restore the default wait bits.
2397 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2399 struct ssh_conn *sshc = &conn->proto.sshc;
2403 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2404 /* translate the libssh2 define bits into our own bit defines */
2405 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2406 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2409 /* It didn't block or libssh2 didn't reveal in which direction, put back
2411 conn->waitfor = sshc->orig_waitfor;
2414 /* no libssh2 directional support so we simply don't know */
2415 #define ssh_block2waitfor(x,y)
2418 /* called repeatedly until done from multi.c */
2419 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2421 struct ssh_conn *sshc = &conn->proto.sshc;
2422 CURLcode result = CURLE_OK;
2423 bool block; /* we store the status and use that to provide a ssh_getsock()
2426 result = ssh_statemach_act(conn, &block);
2427 *done = (bool)(sshc->state == SSH_STOP);
2428 ssh_block2waitfor(conn, block);
2433 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2436 struct ssh_conn *sshc = &conn->proto.sshc;
2437 CURLcode result = CURLE_OK;
2438 struct SessionHandle *data = conn->data;
2440 while((sshc->state != SSH_STOP) && !result) {
2444 result = ssh_statemach_act(conn, &block);
2446 if(Curl_pgrsUpdate(conn))
2447 return CURLE_ABORTED_BY_CALLBACK;
2449 left = Curl_timeleft(conn, NULL, duringconnect);
2451 failf(data, "Operation timed out\n");
2452 return CURLE_OPERATION_TIMEDOUT;
2455 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2456 if((CURLE_OK == result) && block) {
2457 int dir = libssh2_session_block_directions(sshc->ssh_session);
2458 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2459 curl_socket_t fd_read = CURL_SOCKET_BAD;
2460 curl_socket_t fd_write = CURL_SOCKET_BAD;
2461 if (LIBSSH2_SESSION_BLOCK_INBOUND & dir) {
2464 if (LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) {
2467 /* wait for the socket to become ready */
2468 Curl_socket_ready(fd_read, fd_write,
2469 (int)(left>1000?1000:left)); /* ignore result */
2479 * SSH setup and connection
2481 static CURLcode ssh_init(struct connectdata *conn)
2483 struct SessionHandle *data = conn->data;
2484 struct SSHPROTO *ssh;
2485 struct ssh_conn *sshc = &conn->proto.sshc;
2487 sshc->actualcode = CURLE_OK; /* reset error code */
2488 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2491 if(data->state.proto.ssh)
2494 ssh = calloc(1, sizeof(struct SSHPROTO));
2496 return CURLE_OUT_OF_MEMORY;
2498 data->state.proto.ssh = ssh;
2503 static Curl_recv scp_recv, sftp_recv;
2504 static Curl_send scp_send, sftp_send;
2507 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2508 * do protocol-specific actions at connect-time.
2510 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2512 #ifdef CURL_LIBSSH2_DEBUG
2515 struct ssh_conn *ssh;
2517 struct SessionHandle *data = conn->data;
2519 /* We default to persistent connections. We set this already in this connect
2520 function to make the re-use checks properly be able to check this bit. */
2521 conn->bits.close = FALSE;
2523 /* If there already is a protocol-specific struct allocated for this
2524 sessionhandle, deal with it */
2525 Curl_reset_reqproto(conn);
2527 result = ssh_init(conn);
2531 if(conn->protocol & PROT_SCP) {
2532 conn->recv[FIRSTSOCKET] = scp_recv;
2533 conn->send[FIRSTSOCKET] = scp_send;
2535 conn->recv[FIRSTSOCKET] = sftp_recv;
2536 conn->send[FIRSTSOCKET] = sftp_send;
2538 ssh = &conn->proto.sshc;
2540 #ifdef CURL_LIBSSH2_DEBUG
2542 infof(data, "User: %s\n", conn->user);
2545 infof(data, "Password: %s\n", conn->passwd);
2547 sock = conn->sock[FIRSTSOCKET];
2548 #endif /* CURL_LIBSSH2_DEBUG */
2550 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2552 my_libssh2_realloc, conn);
2553 if(ssh->ssh_session == NULL) {
2554 failf(data, "Failure initialising ssh session");
2555 return CURLE_FAILED_INIT;
2558 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2559 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2561 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2563 /* eeek. TODO: free the ssh_session! */
2564 return CURLE_FAILED_INIT;
2567 /* read all known hosts from there */
2568 rc = libssh2_knownhost_readfile(ssh->kh,
2569 data->set.str[STRING_SSH_KNOWNHOSTS],
2570 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2572 infof(data, "Failed to read known hosts from %s\n",
2573 data->set.str[STRING_SSH_KNOWNHOSTS]);
2576 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2578 #ifdef CURL_LIBSSH2_DEBUG
2579 libssh2_trace(ssh->ssh_session, ~0);
2580 infof(data, "SSH socket: %d\n", (int)sock);
2581 #endif /* CURL_LIBSSH2_DEBUG */
2583 state(conn, SSH_S_STARTUP);
2585 if(data->state.used_interface == Curl_if_multi)
2586 result = ssh_multi_statemach(conn, done);
2588 result = ssh_easy_statemach(conn, TRUE);
2597 ***********************************************************************
2601 * This is the actual DO function for SCP. Get a file according to
2602 * the options previously setup.
2606 CURLcode scp_perform(struct connectdata *conn,
2610 CURLcode result = CURLE_OK;
2612 DEBUGF(infof(conn->data, "DO phase starts\n"));
2614 *dophase_done = FALSE; /* not done yet */
2616 /* start the first command in the DO phase */
2617 state(conn, SSH_SCP_TRANS_INIT);
2619 /* run the state-machine */
2620 if(conn->data->state.used_interface == Curl_if_multi) {
2621 result = ssh_multi_statemach(conn, dophase_done);
2624 result = ssh_easy_statemach(conn, FALSE);
2625 *dophase_done = TRUE; /* with the easy interface we are done here */
2627 *connected = conn->bits.tcpconnect;
2630 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2636 /* called from multi.c while DOing */
2637 static CURLcode scp_doing(struct connectdata *conn,
2641 result = ssh_multi_statemach(conn, dophase_done);
2644 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2650 * The DO function is generic for both protocols. There was previously two
2651 * separate ones but this way means less duplicated code.
2654 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2658 struct SessionHandle *data = conn->data;
2660 *done = FALSE; /* default to false */
2663 Since connections can be re-used between SessionHandles, this might be a
2664 connection already existing but on a fresh SessionHandle struct so we must
2665 make sure we have a good 'struct SSHPROTO' to play with. For new
2666 connections, the struct SSHPROTO is allocated and setup in the
2667 ssh_connect() function.
2669 Curl_reset_reqproto(conn);
2670 res = ssh_init(conn);
2674 data->req.size = -1; /* make sure this is unknown at this point */
2676 Curl_pgrsSetUploadCounter(data, 0);
2677 Curl_pgrsSetDownloadCounter(data, 0);
2678 Curl_pgrsSetUploadSize(data, 0);
2679 Curl_pgrsSetDownloadSize(data, 0);
2681 if(conn->protocol & PROT_SCP)
2682 res = scp_perform(conn, &connected, done);
2684 res = sftp_perform(conn, &connected, done);
2689 /* BLOCKING, but the function is using the state machine so the only reason
2690 this is still blocking is that the multi interface code has no support for
2691 disconnecting operations that takes a while */
2692 static CURLcode scp_disconnect(struct connectdata *conn)
2694 CURLcode result = CURLE_OK;
2695 struct ssh_conn *ssh = &conn->proto.sshc;
2697 Curl_safefree(conn->data->state.proto.ssh);
2698 conn->data->state.proto.ssh = NULL;
2700 if(ssh->ssh_session) {
2701 /* only if there's a session still around to use! */
2703 state(conn, SSH_SESSION_DISCONNECT);
2705 result = ssh_easy_statemach(conn, FALSE);
2711 /* generic done function for both SCP and SFTP called from their specific
2713 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2715 CURLcode result = CURLE_OK;
2716 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2718 if(status == CURLE_OK) {
2719 /* run the state-machine
2721 TODO: when the multi interface is used, this _really_ should be using
2722 the ssh_multi_statemach function but we have no general support for
2723 non-blocking DONE operations, not in the multi state machine and with
2724 Curl_done() invokes on several places in the code!
2726 result = ssh_easy_statemach(conn, FALSE);
2731 Curl_safefree(sftp_scp->path);
2732 sftp_scp->path = NULL;
2733 Curl_pgrsDone(conn);
2735 conn->data->req.keepon = 0; /* clear all bits */
2740 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2743 (void)premature; /* not used */
2745 if(status == CURLE_OK)
2746 state(conn, SSH_SCP_DONE);
2748 return ssh_done(conn, status);
2752 /* return number of received (decrypted) bytes */
2753 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2754 const void *mem, size_t len, CURLcode *err)
2757 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2759 /* libssh2_channel_write() returns int! */
2761 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2763 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2765 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2774 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2775 * a regular CURLcode value.
2777 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2778 char *mem, size_t len, CURLcode *err)
2781 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2783 /* libssh2_channel_read() returns int */
2785 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2787 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2788 if (nread == LIBSSH2_ERROR_EAGAIN) {
2797 * =============== SFTP ===============
2801 ***********************************************************************
2805 * This is the actual DO function for SFTP. Get a file/directory according to
2806 * the options previously setup.
2810 CURLcode sftp_perform(struct connectdata *conn,
2814 CURLcode result = CURLE_OK;
2816 DEBUGF(infof(conn->data, "DO phase starts\n"));
2818 *dophase_done = FALSE; /* not done yet */
2820 /* start the first command in the DO phase */
2821 state(conn, SSH_SFTP_QUOTE_INIT);
2823 /* run the state-machine */
2824 if(conn->data->state.used_interface == Curl_if_multi) {
2825 result = ssh_multi_statemach(conn, dophase_done);
2828 result = ssh_easy_statemach(conn, FALSE);
2829 *dophase_done = TRUE; /* with the easy interface we are done here */
2831 *connected = conn->bits.tcpconnect;
2834 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2840 /* called from multi.c while DOing */
2841 static CURLcode sftp_doing(struct connectdata *conn,
2845 result = ssh_multi_statemach(conn, dophase_done);
2848 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2853 /* BLOCKING, but the function is using the state machine so the only reason
2854 this is still blocking is that the multi interface code has no support for
2855 disconnecting operations that takes a while */
2856 static CURLcode sftp_disconnect(struct connectdata *conn)
2858 CURLcode result = CURLE_OK;
2860 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2862 Curl_safefree(conn->data->state.proto.ssh);
2863 conn->data->state.proto.ssh = NULL;
2865 if(conn->proto.sshc.ssh_session) {
2866 /* only if there's a session still around to use! */
2867 state(conn, SSH_SFTP_SHUTDOWN);
2868 result = ssh_easy_statemach(conn, FALSE);
2871 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2877 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2880 struct ssh_conn *sshc = &conn->proto.sshc;
2882 if(status == CURLE_OK) {
2883 /* Before we shut down, see if there are any post-quote commands to
2885 if(!status && !premature && conn->data->set.postquote) {
2886 sshc->nextstate = SSH_SFTP_CLOSE;
2887 state(conn, SSH_SFTP_POSTQUOTE_INIT);
2890 state(conn, SSH_SFTP_CLOSE);
2892 return ssh_done(conn, status);
2895 /* return number of sent bytes */
2896 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
2897 const void *mem, size_t len, CURLcode *err)
2899 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2900 but is changed to ssize_t in 0.15. These days we don't
2901 support libssh2 0.15*/
2904 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2906 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2908 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2917 * Return number of received (decrypted) bytes
2919 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
2920 char *mem, size_t len, CURLcode *err)
2925 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
2927 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2929 if(nread == LIBSSH2_ERROR_EAGAIN) {
2936 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
2939 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
2941 * Permission to use, copy, modify, and distribute this software for any
2942 * purpose with or without fee is hereby granted, provided that the above
2943 * copyright notice and this permission notice appear in all copies.
2945 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2946 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2947 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2948 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2949 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2950 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2951 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2954 get_pathname(const char **cpp, char **path)
2956 const char *cp = *cpp, *end;
2959 static const char WHITESPACE[] = " \t\r\n";
2961 cp += strspn(cp, WHITESPACE);
2965 return CURLE_QUOTE_ERROR;
2968 *path = malloc(strlen(cp) + 1);
2970 return CURLE_OUT_OF_MEMORY;
2972 /* Check for quoted filenames */
2973 if(*cp == '\"' || *cp == '\'') {
2976 /* Search for terminating quote, unescape some chars */
2977 for (i = j = 0; i <= strlen(cp); i++) {
2978 if(cp[i] == quot) { /* Found quote */
2983 if(cp[i] == '\0') { /* End of string */
2984 /*error("Unterminated quote");*/
2987 if(cp[i] == '\\') { /* Escaped characters */
2989 if(cp[i] != '\'' && cp[i] != '\"' &&
2991 /*error("Bad escaped character '\\%c'",
2996 (*path)[j++] = cp[i];
3000 /*error("Empty quotes");*/
3003 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3006 /* Read to end of filename */
3007 end = strpbrk(cp, WHITESPACE);
3009 end = strchr(cp, '\0');
3010 *cpp = end + strspn(end, WHITESPACE);
3012 memcpy(*path, cp, end - cp);
3013 (*path)[end - cp] = '\0';
3018 Curl_safefree(*path);
3020 return CURLE_QUOTE_ERROR;
3024 static const char *sftp_libssh2_strerror(unsigned long err)
3027 case LIBSSH2_FX_NO_SUCH_FILE:
3028 return "No such file or directory";
3030 case LIBSSH2_FX_PERMISSION_DENIED:
3031 return "Permission denied";
3033 case LIBSSH2_FX_FAILURE:
3034 return "Operation failed";
3036 case LIBSSH2_FX_BAD_MESSAGE:
3037 return "Bad message from SFTP server";
3039 case LIBSSH2_FX_NO_CONNECTION:
3040 return "Not connected to SFTP server";
3042 case LIBSSH2_FX_CONNECTION_LOST:
3043 return "Connection to SFTP server lost";
3045 case LIBSSH2_FX_OP_UNSUPPORTED:
3046 return "Operation not supported by SFTP server";
3048 case LIBSSH2_FX_INVALID_HANDLE:
3049 return "Invalid handle";
3051 case LIBSSH2_FX_NO_SUCH_PATH:
3052 return "No such file or directory";
3054 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3055 return "File already exists";
3057 case LIBSSH2_FX_WRITE_PROTECT:
3058 return "File is write protected";
3060 case LIBSSH2_FX_NO_MEDIA:
3063 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3066 case LIBSSH2_FX_QUOTA_EXCEEDED:
3067 return "User quota exceeded";
3069 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3070 return "Unknown principle";
3072 case LIBSSH2_FX_LOCK_CONFlICT:
3073 return "File lock conflict";
3075 case LIBSSH2_FX_DIR_NOT_EMPTY:
3076 return "Directory not empty";
3078 case LIBSSH2_FX_NOT_A_DIRECTORY:
3079 return "Not a directory";
3081 case LIBSSH2_FX_INVALID_FILENAME:
3082 return "Invalid filename";
3084 case LIBSSH2_FX_LINK_LOOP:
3085 return "Link points to itself";
3087 return "Unknown error in libssh2";
3090 #endif /* USE_LIBSSH2 */