1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2018, 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 https://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 */
25 #include "curl_setup.h"
32 #include <libssh2_sftp.h>
38 #ifdef HAVE_NETINET_IN_H
39 #include <netinet/in.h>
41 #ifdef HAVE_ARPA_INET_H
42 #include <arpa/inet.h>
45 #include <sys/utsname.h>
55 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
57 #define in_addr_t unsigned long
60 #include <curl/curl.h>
67 #include "http.h" /* for HTTP proxy tunnel stuff */
70 #include "speedcheck.h"
74 #include "vtls/vtls.h"
77 #include "inet_ntop.h"
78 #include "parsedate.h" /* for the week day and month names */
79 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
80 #include "strtoofft.h"
85 /* The last 3 #include files should be in this order */
86 #include "curl_printf.h"
87 #include "curl_memory.h"
88 #include "curl_path.h"
91 #if LIBSSH2_VERSION_NUM >= 0x010206
92 /* libssh2_sftp_statvfs and friends were added in 1.2.6 */
93 #define HAS_STATVFS_SUPPORT 1
96 #define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
98 #define sftp_libssh2_realpath(s,p,t,m) \
99 libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
100 (t), (m), LIBSSH2_SFTP_REALPATH)
103 /* Local functions: */
104 static const char *sftp_libssh2_strerror(int err);
105 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
106 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
107 static LIBSSH2_FREE_FUNC(my_libssh2_free);
109 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
110 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
111 static CURLcode ssh_do(struct connectdata *conn, bool *done);
113 static CURLcode scp_done(struct connectdata *conn,
114 CURLcode, bool premature);
115 static CURLcode scp_doing(struct connectdata *conn,
117 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
119 static CURLcode sftp_done(struct connectdata *conn,
120 CURLcode, bool premature);
121 static CURLcode sftp_doing(struct connectdata *conn,
123 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
125 CURLcode sftp_perform(struct connectdata *conn,
129 static int ssh_getsock(struct connectdata *conn,
130 curl_socket_t *sock, /* points to numsocks number
134 static int ssh_perform_getsock(const struct connectdata *conn,
135 curl_socket_t *sock, /* points to numsocks
139 static CURLcode ssh_setup_connection(struct connectdata *conn);
142 * SCP protocol handler.
145 const struct Curl_handler Curl_handler_scp = {
147 ssh_setup_connection, /* setup_connection */
150 ZERO_NULL, /* do_more */
151 ssh_connect, /* connect_it */
152 ssh_multi_statemach, /* connecting */
153 scp_doing, /* doing */
154 ssh_getsock, /* proto_getsock */
155 ssh_getsock, /* doing_getsock */
156 ZERO_NULL, /* domore_getsock */
157 ssh_perform_getsock, /* perform_getsock */
158 scp_disconnect, /* disconnect */
159 ZERO_NULL, /* readwrite */
160 ZERO_NULL, /* connection_check */
161 PORT_SSH, /* defport */
162 CURLPROTO_SCP, /* protocol */
163 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
164 | PROTOPT_NOURLQUERY /* flags */
169 * SFTP protocol handler.
172 const struct Curl_handler Curl_handler_sftp = {
174 ssh_setup_connection, /* setup_connection */
176 sftp_done, /* done */
177 ZERO_NULL, /* do_more */
178 ssh_connect, /* connect_it */
179 ssh_multi_statemach, /* connecting */
180 sftp_doing, /* doing */
181 ssh_getsock, /* proto_getsock */
182 ssh_getsock, /* doing_getsock */
183 ZERO_NULL, /* domore_getsock */
184 ssh_perform_getsock, /* perform_getsock */
185 sftp_disconnect, /* disconnect */
186 ZERO_NULL, /* readwrite */
187 ZERO_NULL, /* connection_check */
188 PORT_SSH, /* defport */
189 CURLPROTO_SFTP, /* protocol */
190 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
191 | PROTOPT_NOURLQUERY /* flags */
195 kbd_callback(const char *name, int name_len, const char *instruction,
196 int instruction_len, int num_prompts,
197 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
198 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
201 struct connectdata *conn = (struct connectdata *)*abstract;
203 #ifdef CURL_LIBSSH2_DEBUG
204 fprintf(stderr, "name=%s\n", name);
205 fprintf(stderr, "name_len=%d\n", name_len);
206 fprintf(stderr, "instruction=%s\n", instruction);
207 fprintf(stderr, "instruction_len=%d\n", instruction_len);
208 fprintf(stderr, "num_prompts=%d\n", num_prompts);
213 (void)instruction_len;
214 #endif /* CURL_LIBSSH2_DEBUG */
215 if(num_prompts == 1) {
216 responses[0].text = strdup(conn->passwd);
217 responses[0].length = curlx_uztoui(strlen(conn->passwd));
223 static CURLcode sftp_libssh2_error_to_CURLE(int err)
229 case LIBSSH2_FX_NO_SUCH_FILE:
230 case LIBSSH2_FX_NO_SUCH_PATH:
231 return CURLE_REMOTE_FILE_NOT_FOUND;
233 case LIBSSH2_FX_PERMISSION_DENIED:
234 case LIBSSH2_FX_WRITE_PROTECT:
235 case LIBSSH2_FX_LOCK_CONFlICT:
236 return CURLE_REMOTE_ACCESS_DENIED;
238 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
239 case LIBSSH2_FX_QUOTA_EXCEEDED:
240 return CURLE_REMOTE_DISK_FULL;
242 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
243 return CURLE_REMOTE_FILE_EXISTS;
245 case LIBSSH2_FX_DIR_NOT_EMPTY:
246 return CURLE_QUOTE_ERROR;
255 static CURLcode libssh2_session_error_to_CURLE(int err)
258 /* Ordered by order of appearance in libssh2.h */
259 case LIBSSH2_ERROR_NONE:
262 /* This is the error returned by libssh2_scp_recv2
264 case LIBSSH2_ERROR_SCP_PROTOCOL:
265 return CURLE_REMOTE_FILE_NOT_FOUND;
267 case LIBSSH2_ERROR_SOCKET_NONE:
268 return CURLE_COULDNT_CONNECT;
270 case LIBSSH2_ERROR_ALLOC:
271 return CURLE_OUT_OF_MEMORY;
273 case LIBSSH2_ERROR_SOCKET_SEND:
274 return CURLE_SEND_ERROR;
276 case LIBSSH2_ERROR_HOSTKEY_INIT:
277 case LIBSSH2_ERROR_HOSTKEY_SIGN:
278 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
279 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
280 return CURLE_PEER_FAILED_VERIFICATION;
282 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
283 return CURLE_LOGIN_DENIED;
285 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
286 case LIBSSH2_ERROR_TIMEOUT:
287 return CURLE_OPERATION_TIMEDOUT;
289 case LIBSSH2_ERROR_EAGAIN:
293 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
294 error code, and possibly add a few new SSH-related one. We must however
295 not return or even depend on libssh2 errors in the public libcurl API */
300 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
302 (void)abstract; /* arg not used */
303 return malloc(count);
306 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
308 (void)abstract; /* arg not used */
309 return realloc(ptr, count);
312 static LIBSSH2_FREE_FUNC(my_libssh2_free)
314 (void)abstract; /* arg not used */
315 if(ptr) /* ssh2 agent sometimes call free with null ptr */
320 * SSH State machine related code
322 /* This is the ONLY way to change SSH state! */
323 static void state(struct connectdata *conn, sshstate nowstate)
325 struct ssh_conn *sshc = &conn->proto.sshc;
326 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
327 /* for debug purposes */
328 static const char * const names[] = {
334 "SSH_AUTH_PKEY_INIT",
336 "SSH_AUTH_PASS_INIT",
338 "SSH_AUTH_AGENT_INIT",
339 "SSH_AUTH_AGENT_LIST",
341 "SSH_AUTH_HOST_INIT",
349 "SSH_SFTP_QUOTE_INIT",
350 "SSH_SFTP_POSTQUOTE_INIT",
352 "SSH_SFTP_NEXT_QUOTE",
353 "SSH_SFTP_QUOTE_STAT",
354 "SSH_SFTP_QUOTE_SETSTAT",
355 "SSH_SFTP_QUOTE_SYMLINK",
356 "SSH_SFTP_QUOTE_MKDIR",
357 "SSH_SFTP_QUOTE_RENAME",
358 "SSH_SFTP_QUOTE_RMDIR",
359 "SSH_SFTP_QUOTE_UNLINK",
360 "SSH_SFTP_QUOTE_STATVFS",
363 "SSH_SFTP_TRANS_INIT",
364 "SSH_SFTP_UPLOAD_INIT",
365 "SSH_SFTP_CREATE_DIRS_INIT",
366 "SSH_SFTP_CREATE_DIRS",
367 "SSH_SFTP_CREATE_DIRS_MKDIR",
368 "SSH_SFTP_READDIR_INIT",
370 "SSH_SFTP_READDIR_LINK",
371 "SSH_SFTP_READDIR_BOTTOM",
372 "SSH_SFTP_READDIR_DONE",
373 "SSH_SFTP_DOWNLOAD_INIT",
374 "SSH_SFTP_DOWNLOAD_STAT",
377 "SSH_SCP_TRANS_INIT",
378 "SSH_SCP_UPLOAD_INIT",
379 "SSH_SCP_DOWNLOAD_INIT",
384 "SSH_SCP_WAIT_CLOSE",
385 "SSH_SCP_CHANNEL_FREE",
386 "SSH_SESSION_DISCONNECT",
391 /* a precaution to make sure the lists are in sync */
392 DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST);
394 if(sshc->state != nowstate) {
395 infof(conn->data, "SFTP %p state change from %s to %s\n",
396 (void *)sshc, names[sshc->state], names[nowstate]);
400 sshc->state = nowstate;
404 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
405 static int sshkeycallback(struct Curl_easy *easy,
406 const struct curl_khkey *knownkey, /* known */
407 const struct curl_khkey *foundkey, /* found */
408 enum curl_khmatch match,
416 /* we only allow perfect matches, and we reject everything else */
417 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
422 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
425 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
426 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
428 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
432 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
433 * architectures so we check of the necessary function is present.
435 #ifndef HAVE_LIBSSH2_SCP_SEND64
436 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
438 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
439 (libssh2_uint64_t)d, 0, 0)
443 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
445 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
446 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
449 static CURLcode ssh_knownhost(struct connectdata *conn)
451 CURLcode result = CURLE_OK;
453 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
454 struct Curl_easy *data = conn->data;
456 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
457 /* we're asked to verify the host against a file */
458 struct ssh_conn *sshc = &conn->proto.sshc;
462 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
464 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
469 * A subject to figure out is what host name we need to pass in here.
470 * What host name does OpenSSH store in its file if an IDN name is
473 struct libssh2_knownhost *host;
474 enum curl_khmatch keymatch;
475 curl_sshkeycallback func =
476 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
477 struct curl_khkey knownkey;
478 struct curl_khkey *knownkeyp = NULL;
479 struct curl_khkey foundkey;
481 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
482 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
484 #ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
485 keycheck = libssh2_knownhost_checkp(sshc->kh,
487 (conn->remote_port != PORT_SSH)?
488 conn->remote_port:-1,
490 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
491 LIBSSH2_KNOWNHOST_KEYENC_RAW|
495 keycheck = libssh2_knownhost_check(sshc->kh,
498 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
499 LIBSSH2_KNOWNHOST_KEYENC_RAW|
504 infof(data, "SSH host check: %d, key: %s\n", keycheck,
505 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
508 /* setup 'knownkey' */
509 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
510 knownkey.key = host->key;
512 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
513 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
514 knownkeyp = &knownkey;
517 /* setup 'foundkey' */
518 foundkey.key = remotekey;
519 foundkey.len = keylen;
520 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
521 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
524 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
525 * curl_khmatch enum are ever modified, we need to introduce a
526 * translation table here!
528 keymatch = (enum curl_khmatch)keycheck;
530 /* Ask the callback how to behave */
531 Curl_set_in_callback(data, true);
532 rc = func(data, knownkeyp, /* from the knownhosts file */
533 &foundkey, /* from the remote host */
534 keymatch, data->set.ssh_keyfunc_userp);
535 Curl_set_in_callback(data, false);
538 /* no remotekey means failure! */
539 rc = CURLKHSTAT_REJECT;
542 default: /* unknown return codes will equal reject */
544 case CURLKHSTAT_REJECT:
545 state(conn, SSH_SESSION_FREE);
547 case CURLKHSTAT_DEFER:
548 /* DEFER means bail out but keep the SSH_HOSTKEY state */
549 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
551 case CURLKHSTAT_FINE:
552 case CURLKHSTAT_FINE_ADD_TO_FILE:
554 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
555 /* the found host+key didn't match but has been told to be fine
556 anyway so we add it in memory */
557 int addrc = libssh2_knownhost_add(sshc->kh,
558 conn->host.name, NULL,
560 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
561 LIBSSH2_KNOWNHOST_KEYENC_RAW|
564 infof(data, "Warning adding the known host %s failed!\n",
566 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
567 /* now we write the entire in-memory list of known hosts to the
570 libssh2_knownhost_writefile(sshc->kh,
571 data->set.str[STRING_SSH_KNOWNHOSTS],
572 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
574 infof(data, "Warning, writing %s failed!\n",
575 data->set.str[STRING_SSH_KNOWNHOSTS]);
582 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
588 static CURLcode ssh_check_fingerprint(struct connectdata *conn)
590 struct ssh_conn *sshc = &conn->proto.sshc;
591 struct Curl_easy *data = conn->data;
592 const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
596 const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
597 LIBSSH2_HOSTKEY_HASH_MD5);
600 /* The fingerprint points to static storage (!), don't free() it. */
601 for(i = 0; i < 16; i++)
602 snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
603 infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
606 /* Before we authenticate we check the hostkey's MD5 fingerprint
607 * against a known fingerprint, if available.
609 if(pubkey_md5 && strlen(pubkey_md5) == 32) {
610 if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) {
613 "Denied establishing ssh session: mismatch md5 fingerprint. "
614 "Remote %s is not equal to %s", md5buffer, pubkey_md5);
617 "Denied establishing ssh session: md5 fingerprint not available");
618 state(conn, SSH_SESSION_FREE);
619 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
620 return sshc->actualcode;
622 infof(data, "MD5 checksum match!\n");
623 /* as we already matched, we skip the check for known hosts */
626 return ssh_knownhost(conn);
630 * ssh_statemach_act() runs the SSH state machine as far as it can without
631 * blocking and without reaching the end. The data the pointer 'block' points
632 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
633 * meaning it wants to be called again when the socket is ready
636 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
638 CURLcode result = CURLE_OK;
639 struct Curl_easy *data = conn->data;
640 struct SSHPROTO *sftp_scp = data->req.protop;
641 struct ssh_conn *sshc = &conn->proto.sshc;
642 curl_socket_t sock = conn->sock[FIRSTSOCKET];
643 char *new_readdir_line;
644 int rc = LIBSSH2_ERROR_NONE;
646 int seekerr = CURL_SEEKFUNC_OK;
647 *block = 0; /* we're not blocking by default */
651 switch(sshc->state) {
653 sshc->secondCreateDirs = 0;
654 sshc->nextstate = SSH_NO_STATE;
655 sshc->actualcode = CURLE_OK;
657 /* Set libssh2 to non-blocking, since everything internally is
659 libssh2_session_set_blocking(sshc->ssh_session, 0);
661 state(conn, SSH_S_STARTUP);
665 rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
666 if(rc == LIBSSH2_ERROR_EAGAIN) {
670 failf(data, "Failure establishing ssh session");
671 state(conn, SSH_SESSION_FREE);
672 sshc->actualcode = CURLE_FAILED_INIT;
676 state(conn, SSH_HOSTKEY);
681 * Before we authenticate we should check the hostkey's fingerprint
682 * against our known hosts. How that is handled (reading from file,
683 * whatever) is up to us.
685 result = ssh_check_fingerprint(conn);
687 state(conn, SSH_AUTHLIST);
688 /* ssh_check_fingerprint sets state appropriately on error */
693 * Figure out authentication methods
694 * NB: As soon as we have provided a username to an openssh server we
695 * must never change it later. Thus, always specify the correct username
696 * here, even though the libssh2 docs kind of indicate that it should be
697 * possible to get a 'generic' list (not user-specific) of authentication
698 * methods, presumably with a blank username. That won't work in my
700 * So always specify it here.
702 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
704 curlx_uztoui(strlen(conn->user)));
706 if(!sshc->authlist) {
707 if(libssh2_userauth_authenticated(sshc->ssh_session)) {
709 infof(data, "SSH user accepted with no authentication\n");
710 state(conn, SSH_AUTH_DONE);
713 err = libssh2_session_last_errno(sshc->ssh_session);
714 if(err == LIBSSH2_ERROR_EAGAIN)
715 rc = LIBSSH2_ERROR_EAGAIN;
717 state(conn, SSH_SESSION_FREE);
718 sshc->actualcode = libssh2_session_error_to_CURLE(err);
722 infof(data, "SSH authentication methods available: %s\n",
725 state(conn, SSH_AUTH_PKEY_INIT);
728 case SSH_AUTH_PKEY_INIT:
730 * Check the supported auth types in the order I feel is most secure
731 * with the requested type of authentication
733 sshc->authed = FALSE;
735 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
736 (strstr(sshc->authlist, "publickey") != NULL)) {
738 bool out_of_memory = FALSE;
740 sshc->rsa_pub = sshc->rsa = NULL;
742 /* To ponder about: should really the lib be messing about with the
743 HOME environment variable etc? */
744 home = curl_getenv("HOME");
746 if(data->set.str[STRING_SSH_PRIVATE_KEY])
747 sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
749 /* If no private key file is specified, try some common paths. */
751 /* Try ~/.ssh first. */
752 sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
754 out_of_memory = TRUE;
755 else if(access(sshc->rsa, R_OK) != 0) {
756 Curl_safefree(sshc->rsa);
757 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
759 out_of_memory = TRUE;
760 else if(access(sshc->rsa, R_OK) != 0) {
761 Curl_safefree(sshc->rsa);
765 if(!out_of_memory && !sshc->rsa) {
766 /* Nothing found; try the current dir. */
767 sshc->rsa = strdup("id_rsa");
768 if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
769 Curl_safefree(sshc->rsa);
770 sshc->rsa = strdup("id_dsa");
771 if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
772 Curl_safefree(sshc->rsa);
773 /* Out of guesses. Set to the empty string to avoid
774 * surprising info messages. */
775 sshc->rsa = strdup("");
782 * Unless the user explicitly specifies a public key file, let
783 * libssh2 extract the public key from the private key file.
784 * This is done by simply passing sshc->rsa_pub = NULL.
786 if(data->set.str[STRING_SSH_PUBLIC_KEY]
787 /* treat empty string the same way as NULL */
788 && data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
789 sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
791 out_of_memory = TRUE;
794 if(out_of_memory || sshc->rsa == NULL) {
796 Curl_safefree(sshc->rsa);
797 Curl_safefree(sshc->rsa_pub);
798 state(conn, SSH_SESSION_FREE);
799 sshc->actualcode = CURLE_OUT_OF_MEMORY;
803 sshc->passphrase = data->set.ssl.key_passwd;
804 if(!sshc->passphrase)
805 sshc->passphrase = "";
810 infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
811 infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
813 state(conn, SSH_AUTH_PKEY);
816 state(conn, SSH_AUTH_PASS_INIT);
821 /* The function below checks if the files exists, no need to stat() here.
823 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
828 sshc->rsa, sshc->passphrase);
829 if(rc == LIBSSH2_ERROR_EAGAIN) {
833 Curl_safefree(sshc->rsa_pub);
834 Curl_safefree(sshc->rsa);
838 infof(data, "Initialized SSH public key authentication\n");
839 state(conn, SSH_AUTH_DONE);
843 (void)libssh2_session_last_error(sshc->ssh_session,
845 infof(data, "SSH public key authentication failed: %s\n", err_msg);
846 state(conn, SSH_AUTH_PASS_INIT);
847 rc = 0; /* clear rc and continue */
851 case SSH_AUTH_PASS_INIT:
852 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
853 (strstr(sshc->authlist, "password") != NULL)) {
854 state(conn, SSH_AUTH_PASS);
857 state(conn, SSH_AUTH_HOST_INIT);
858 rc = 0; /* clear rc and continue */
863 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
864 curlx_uztoui(strlen(conn->user)),
866 curlx_uztoui(strlen(conn->passwd)),
868 if(rc == LIBSSH2_ERROR_EAGAIN) {
873 infof(data, "Initialized password authentication\n");
874 state(conn, SSH_AUTH_DONE);
877 state(conn, SSH_AUTH_HOST_INIT);
878 rc = 0; /* clear rc and continue */
882 case SSH_AUTH_HOST_INIT:
883 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
884 (strstr(sshc->authlist, "hostbased") != NULL)) {
885 state(conn, SSH_AUTH_HOST);
888 state(conn, SSH_AUTH_AGENT_INIT);
893 state(conn, SSH_AUTH_AGENT_INIT);
896 case SSH_AUTH_AGENT_INIT:
897 #ifdef HAVE_LIBSSH2_AGENT_API
898 if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
899 && (strstr(sshc->authlist, "publickey") != NULL)) {
901 /* Connect to the ssh-agent */
902 /* The agent could be shared by a curl thread i believe
903 but nothing obvious as keys can be added/removed at any time */
904 if(!sshc->ssh_agent) {
905 sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
906 if(!sshc->ssh_agent) {
907 infof(data, "Could not create agent object\n");
909 state(conn, SSH_AUTH_KEY_INIT);
914 rc = libssh2_agent_connect(sshc->ssh_agent);
915 if(rc == LIBSSH2_ERROR_EAGAIN)
918 infof(data, "Failure connecting to agent\n");
919 state(conn, SSH_AUTH_KEY_INIT);
920 rc = 0; /* clear rc and continue */
923 state(conn, SSH_AUTH_AGENT_LIST);
927 #endif /* HAVE_LIBSSH2_AGENT_API */
928 state(conn, SSH_AUTH_KEY_INIT);
931 case SSH_AUTH_AGENT_LIST:
932 #ifdef HAVE_LIBSSH2_AGENT_API
933 rc = libssh2_agent_list_identities(sshc->ssh_agent);
935 if(rc == LIBSSH2_ERROR_EAGAIN)
938 infof(data, "Failure requesting identities to agent\n");
939 state(conn, SSH_AUTH_KEY_INIT);
940 rc = 0; /* clear rc and continue */
943 state(conn, SSH_AUTH_AGENT);
944 sshc->sshagent_prev_identity = NULL;
950 #ifdef HAVE_LIBSSH2_AGENT_API
951 /* as prev_identity evolves only after an identity user auth finished we
952 can safely request it again as long as EAGAIN is returned here or by
953 libssh2_agent_userauth */
954 rc = libssh2_agent_get_identity(sshc->ssh_agent,
955 &sshc->sshagent_identity,
956 sshc->sshagent_prev_identity);
957 if(rc == LIBSSH2_ERROR_EAGAIN)
961 rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
962 sshc->sshagent_identity);
965 if(rc != LIBSSH2_ERROR_EAGAIN) {
966 /* tried and failed? go to next identity */
967 sshc->sshagent_prev_identity = sshc->sshagent_identity;
974 infof(data, "Failure requesting identities to agent\n");
976 infof(data, "No identity would match\n");
978 if(rc == LIBSSH2_ERROR_NONE) {
980 infof(data, "Agent based authentication successful\n");
981 state(conn, SSH_AUTH_DONE);
984 state(conn, SSH_AUTH_KEY_INIT);
985 rc = 0; /* clear rc and continue */
990 case SSH_AUTH_KEY_INIT:
991 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
992 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
993 state(conn, SSH_AUTH_KEY);
996 state(conn, SSH_AUTH_DONE);
1001 /* Authentication failed. Continue with keyboard-interactive now. */
1002 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
1005 strlen(conn->user)),
1007 if(rc == LIBSSH2_ERROR_EAGAIN) {
1011 sshc->authed = TRUE;
1012 infof(data, "Initialized keyboard interactive authentication\n");
1014 state(conn, SSH_AUTH_DONE);
1019 failf(data, "Authentication failure");
1020 state(conn, SSH_SESSION_FREE);
1021 sshc->actualcode = CURLE_LOGIN_DENIED;
1026 * At this point we have an authenticated ssh session.
1028 infof(data, "Authentication complete\n");
1030 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
1032 conn->sockfd = sock;
1033 conn->writesockfd = CURL_SOCKET_BAD;
1035 if(conn->handler->protocol == CURLPROTO_SFTP) {
1036 state(conn, SSH_SFTP_INIT);
1039 infof(data, "SSH CONNECT phase done\n");
1040 state(conn, SSH_STOP);
1045 * Start the libssh2 sftp session
1047 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
1048 if(!sshc->sftp_session) {
1050 if(libssh2_session_last_errno(sshc->ssh_session) ==
1051 LIBSSH2_ERROR_EAGAIN) {
1052 rc = LIBSSH2_ERROR_EAGAIN;
1056 (void)libssh2_session_last_error(sshc->ssh_session,
1058 failf(data, "Failure initializing sftp session: %s", err_msg);
1059 state(conn, SSH_SESSION_FREE);
1060 sshc->actualcode = CURLE_FAILED_INIT;
1063 state(conn, SSH_SFTP_REALPATH);
1066 case SSH_SFTP_REALPATH:
1068 char tempHome[PATH_MAX];
1071 * Get the "home" directory
1073 rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
1074 tempHome, PATH_MAX-1);
1075 if(rc == LIBSSH2_ERROR_EAGAIN) {
1079 /* It seems that this string is not always NULL terminated */
1080 tempHome[rc] = '\0';
1081 sshc->homedir = strdup(tempHome);
1082 if(!sshc->homedir) {
1083 state(conn, SSH_SFTP_CLOSE);
1084 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1087 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1090 /* Return the error type */
1091 err = sftp_libssh2_last_error(sshc->sftp_session);
1093 result = sftp_libssh2_error_to_CURLE(err);
1095 /* in this case, the error wasn't in the SFTP level but for example
1096 a time-out or similar */
1098 sshc->actualcode = result;
1099 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1101 state(conn, SSH_STOP);
1105 /* This is the last step in the SFTP connect phase. Do note that while
1106 we get the homedir here, we get the "workingpath" in the DO action
1107 since the homedir will remain the same between request but the
1108 working path will not. */
1109 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1110 state(conn, SSH_STOP);
1113 case SSH_SFTP_QUOTE_INIT:
1115 result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1117 sshc->actualcode = result;
1118 state(conn, SSH_STOP);
1122 if(data->set.quote) {
1123 infof(data, "Sending quote commands\n");
1124 sshc->quote_item = data->set.quote;
1125 state(conn, SSH_SFTP_QUOTE);
1128 state(conn, SSH_SFTP_GETINFO);
1132 case SSH_SFTP_POSTQUOTE_INIT:
1133 if(data->set.postquote) {
1134 infof(data, "Sending quote commands\n");
1135 sshc->quote_item = data->set.postquote;
1136 state(conn, SSH_SFTP_QUOTE);
1139 state(conn, SSH_STOP);
1143 case SSH_SFTP_QUOTE:
1144 /* Send any quote commands */
1149 * Support some of the "FTP" commands
1151 * 'sshc->quote_item' is already verified to be non-NULL before it
1152 * switched to this state.
1154 char *cmd = sshc->quote_item->data;
1155 sshc->acceptfail = FALSE;
1157 /* if a command starts with an asterisk, which a legal SFTP command never
1158 can, the command will be allowed to fail without it causing any
1159 aborts or cancels etc. It will cause libcurl to act as if the command
1160 is successful, whatever the server reponds. */
1164 sshc->acceptfail = TRUE;
1167 if(strcasecompare("pwd", cmd)) {
1168 /* output debug output if that is requested */
1169 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1172 result = CURLE_OUT_OF_MEMORY;
1173 state(conn, SSH_SFTP_CLOSE);
1174 sshc->nextstate = SSH_NO_STATE;
1177 if(data->set.verbose) {
1178 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1179 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1181 /* this sends an FTP-like "header" to the header callback so that the
1182 current directory can be read very similar to how it is read when
1183 using ordinary FTP. */
1184 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1187 state(conn, SSH_SFTP_CLOSE);
1188 sshc->nextstate = SSH_NO_STATE;
1189 sshc->actualcode = result;
1192 state(conn, SSH_SFTP_NEXT_QUOTE);
1197 * the arguments following the command must be separated from the
1198 * command with a space so we can check for it unconditionally
1200 cp = strchr(cmd, ' ');
1202 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1203 state(conn, SSH_SFTP_CLOSE);
1204 sshc->nextstate = SSH_NO_STATE;
1205 sshc->actualcode = CURLE_QUOTE_ERROR;
1210 * also, every command takes at least one argument so we get that
1211 * first argument right now
1213 result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
1215 if(result == CURLE_OUT_OF_MEMORY)
1216 failf(data, "Out of memory");
1218 failf(data, "Syntax error: Bad first parameter");
1219 state(conn, SSH_SFTP_CLOSE);
1220 sshc->nextstate = SSH_NO_STATE;
1221 sshc->actualcode = result;
1226 * SFTP is a binary protocol, so we don't send text commands
1227 * to the server. Instead, we scan for commands used by
1228 * OpenSSH's sftp program and call the appropriate libssh2
1231 if(strncasecompare(cmd, "chgrp ", 6) ||
1232 strncasecompare(cmd, "chmod ", 6) ||
1233 strncasecompare(cmd, "chown ", 6) ) {
1234 /* attribute change */
1236 /* sshc->quote_path1 contains the mode to set */
1237 /* get the destination */
1238 result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
1240 if(result == CURLE_OUT_OF_MEMORY)
1241 failf(data, "Out of memory");
1243 failf(data, "Syntax error in chgrp/chmod/chown: "
1244 "Bad second parameter");
1245 Curl_safefree(sshc->quote_path1);
1246 state(conn, SSH_SFTP_CLOSE);
1247 sshc->nextstate = SSH_NO_STATE;
1248 sshc->actualcode = result;
1251 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1252 state(conn, SSH_SFTP_QUOTE_STAT);
1255 if(strncasecompare(cmd, "ln ", 3) ||
1256 strncasecompare(cmd, "symlink ", 8)) {
1257 /* symbolic linking */
1258 /* sshc->quote_path1 is the source */
1259 /* get the destination */
1260 result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
1262 if(result == CURLE_OUT_OF_MEMORY)
1263 failf(data, "Out of memory");
1266 "Syntax error in ln/symlink: Bad second parameter");
1267 Curl_safefree(sshc->quote_path1);
1268 state(conn, SSH_SFTP_CLOSE);
1269 sshc->nextstate = SSH_NO_STATE;
1270 sshc->actualcode = result;
1273 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1276 else if(strncasecompare(cmd, "mkdir ", 6)) {
1278 state(conn, SSH_SFTP_QUOTE_MKDIR);
1281 else if(strncasecompare(cmd, "rename ", 7)) {
1283 /* first param is the source path */
1284 /* second param is the dest. path */
1285 result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
1287 if(result == CURLE_OUT_OF_MEMORY)
1288 failf(data, "Out of memory");
1290 failf(data, "Syntax error in rename: Bad second parameter");
1291 Curl_safefree(sshc->quote_path1);
1292 state(conn, SSH_SFTP_CLOSE);
1293 sshc->nextstate = SSH_NO_STATE;
1294 sshc->actualcode = result;
1297 state(conn, SSH_SFTP_QUOTE_RENAME);
1300 else if(strncasecompare(cmd, "rmdir ", 6)) {
1302 state(conn, SSH_SFTP_QUOTE_RMDIR);
1305 else if(strncasecompare(cmd, "rm ", 3)) {
1306 state(conn, SSH_SFTP_QUOTE_UNLINK);
1309 #ifdef HAS_STATVFS_SUPPORT
1310 else if(strncasecompare(cmd, "statvfs ", 8)) {
1311 state(conn, SSH_SFTP_QUOTE_STATVFS);
1316 failf(data, "Unknown SFTP command");
1317 Curl_safefree(sshc->quote_path1);
1318 Curl_safefree(sshc->quote_path2);
1319 state(conn, SSH_SFTP_CLOSE);
1320 sshc->nextstate = SSH_NO_STATE;
1321 sshc->actualcode = CURLE_QUOTE_ERROR;
1327 case SSH_SFTP_NEXT_QUOTE:
1328 Curl_safefree(sshc->quote_path1);
1329 Curl_safefree(sshc->quote_path2);
1331 sshc->quote_item = sshc->quote_item->next;
1333 if(sshc->quote_item) {
1334 state(conn, SSH_SFTP_QUOTE);
1337 if(sshc->nextstate != SSH_NO_STATE) {
1338 state(conn, sshc->nextstate);
1339 sshc->nextstate = SSH_NO_STATE;
1342 state(conn, SSH_SFTP_GETINFO);
1347 case SSH_SFTP_QUOTE_STAT:
1349 char *cmd = sshc->quote_item->data;
1350 sshc->acceptfail = FALSE;
1352 /* if a command starts with an asterisk, which a legal SFTP command never
1353 can, the command will be allowed to fail without it causing any
1354 aborts or cancels etc. It will cause libcurl to act as if the command
1355 is successful, whatever the server reponds. */
1359 sshc->acceptfail = TRUE;
1362 if(!strncasecompare(cmd, "chmod", 5)) {
1363 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1364 * set them both at once, we need to obtain the current ownership
1365 * first. This takes an extra protocol round trip.
1367 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1368 curlx_uztoui(strlen(sshc->quote_path2)),
1370 &sshc->quote_attrs);
1371 if(rc == LIBSSH2_ERROR_EAGAIN) {
1374 if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1375 err = sftp_libssh2_last_error(sshc->sftp_session);
1376 Curl_safefree(sshc->quote_path1);
1377 Curl_safefree(sshc->quote_path2);
1378 failf(data, "Attempt to get SFTP stats failed: %s",
1379 sftp_libssh2_strerror(err));
1380 state(conn, SSH_SFTP_CLOSE);
1381 sshc->nextstate = SSH_NO_STATE;
1382 sshc->actualcode = CURLE_QUOTE_ERROR;
1387 /* Now set the new attributes... */
1388 if(strncasecompare(cmd, "chgrp", 5)) {
1389 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1390 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1391 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1392 !sshc->acceptfail) {
1393 Curl_safefree(sshc->quote_path1);
1394 Curl_safefree(sshc->quote_path2);
1395 failf(data, "Syntax error: chgrp gid not a number");
1396 state(conn, SSH_SFTP_CLOSE);
1397 sshc->nextstate = SSH_NO_STATE;
1398 sshc->actualcode = CURLE_QUOTE_ERROR;
1402 else if(strncasecompare(cmd, "chmod", 5)) {
1403 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1404 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1405 /* permissions are octal */
1406 if(sshc->quote_attrs.permissions == 0 &&
1407 !ISDIGIT(sshc->quote_path1[0])) {
1408 Curl_safefree(sshc->quote_path1);
1409 Curl_safefree(sshc->quote_path2);
1410 failf(data, "Syntax error: chmod permissions not a number");
1411 state(conn, SSH_SFTP_CLOSE);
1412 sshc->nextstate = SSH_NO_STATE;
1413 sshc->actualcode = CURLE_QUOTE_ERROR;
1417 else if(strncasecompare(cmd, "chown", 5)) {
1418 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1419 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1420 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1421 !sshc->acceptfail) {
1422 Curl_safefree(sshc->quote_path1);
1423 Curl_safefree(sshc->quote_path2);
1424 failf(data, "Syntax error: chown uid not a number");
1425 state(conn, SSH_SFTP_CLOSE);
1426 sshc->nextstate = SSH_NO_STATE;
1427 sshc->actualcode = CURLE_QUOTE_ERROR;
1432 /* Now send the completed structure... */
1433 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1437 case SSH_SFTP_QUOTE_SETSTAT:
1438 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1439 curlx_uztoui(strlen(sshc->quote_path2)),
1440 LIBSSH2_SFTP_SETSTAT,
1441 &sshc->quote_attrs);
1442 if(rc == LIBSSH2_ERROR_EAGAIN) {
1445 if(rc != 0 && !sshc->acceptfail) {
1446 err = sftp_libssh2_last_error(sshc->sftp_session);
1447 Curl_safefree(sshc->quote_path1);
1448 Curl_safefree(sshc->quote_path2);
1449 failf(data, "Attempt to set SFTP stats failed: %s",
1450 sftp_libssh2_strerror(err));
1451 state(conn, SSH_SFTP_CLOSE);
1452 sshc->nextstate = SSH_NO_STATE;
1453 sshc->actualcode = CURLE_QUOTE_ERROR;
1456 state(conn, SSH_SFTP_NEXT_QUOTE);
1459 case SSH_SFTP_QUOTE_SYMLINK:
1460 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1461 curlx_uztoui(strlen(sshc->quote_path1)),
1463 curlx_uztoui(strlen(sshc->quote_path2)),
1464 LIBSSH2_SFTP_SYMLINK);
1465 if(rc == LIBSSH2_ERROR_EAGAIN) {
1468 if(rc != 0 && !sshc->acceptfail) {
1469 err = sftp_libssh2_last_error(sshc->sftp_session);
1470 Curl_safefree(sshc->quote_path1);
1471 Curl_safefree(sshc->quote_path2);
1472 failf(data, "symlink command failed: %s",
1473 sftp_libssh2_strerror(err));
1474 state(conn, SSH_SFTP_CLOSE);
1475 sshc->nextstate = SSH_NO_STATE;
1476 sshc->actualcode = CURLE_QUOTE_ERROR;
1479 state(conn, SSH_SFTP_NEXT_QUOTE);
1482 case SSH_SFTP_QUOTE_MKDIR:
1483 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1484 curlx_uztoui(strlen(sshc->quote_path1)),
1485 data->set.new_directory_perms);
1486 if(rc == LIBSSH2_ERROR_EAGAIN) {
1489 if(rc != 0 && !sshc->acceptfail) {
1490 err = sftp_libssh2_last_error(sshc->sftp_session);
1491 Curl_safefree(sshc->quote_path1);
1492 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1493 state(conn, SSH_SFTP_CLOSE);
1494 sshc->nextstate = SSH_NO_STATE;
1495 sshc->actualcode = CURLE_QUOTE_ERROR;
1498 state(conn, SSH_SFTP_NEXT_QUOTE);
1501 case SSH_SFTP_QUOTE_RENAME:
1502 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1503 curlx_uztoui(strlen(sshc->quote_path1)),
1505 curlx_uztoui(strlen(sshc->quote_path2)),
1506 LIBSSH2_SFTP_RENAME_OVERWRITE |
1507 LIBSSH2_SFTP_RENAME_ATOMIC |
1508 LIBSSH2_SFTP_RENAME_NATIVE);
1510 if(rc == LIBSSH2_ERROR_EAGAIN) {
1513 if(rc != 0 && !sshc->acceptfail) {
1514 err = sftp_libssh2_last_error(sshc->sftp_session);
1515 Curl_safefree(sshc->quote_path1);
1516 Curl_safefree(sshc->quote_path2);
1517 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1518 state(conn, SSH_SFTP_CLOSE);
1519 sshc->nextstate = SSH_NO_STATE;
1520 sshc->actualcode = CURLE_QUOTE_ERROR;
1523 state(conn, SSH_SFTP_NEXT_QUOTE);
1526 case SSH_SFTP_QUOTE_RMDIR:
1527 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1528 curlx_uztoui(strlen(sshc->quote_path1)));
1529 if(rc == LIBSSH2_ERROR_EAGAIN) {
1532 if(rc != 0 && !sshc->acceptfail) {
1533 err = sftp_libssh2_last_error(sshc->sftp_session);
1534 Curl_safefree(sshc->quote_path1);
1535 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1536 state(conn, SSH_SFTP_CLOSE);
1537 sshc->nextstate = SSH_NO_STATE;
1538 sshc->actualcode = CURLE_QUOTE_ERROR;
1541 state(conn, SSH_SFTP_NEXT_QUOTE);
1544 case SSH_SFTP_QUOTE_UNLINK:
1545 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1546 curlx_uztoui(strlen(sshc->quote_path1)));
1547 if(rc == LIBSSH2_ERROR_EAGAIN) {
1550 if(rc != 0 && !sshc->acceptfail) {
1551 err = sftp_libssh2_last_error(sshc->sftp_session);
1552 Curl_safefree(sshc->quote_path1);
1553 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1554 state(conn, SSH_SFTP_CLOSE);
1555 sshc->nextstate = SSH_NO_STATE;
1556 sshc->actualcode = CURLE_QUOTE_ERROR;
1559 state(conn, SSH_SFTP_NEXT_QUOTE);
1562 #ifdef HAS_STATVFS_SUPPORT
1563 case SSH_SFTP_QUOTE_STATVFS:
1565 LIBSSH2_SFTP_STATVFS statvfs;
1566 rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1,
1567 curlx_uztoui(strlen(sshc->quote_path1)),
1570 if(rc == LIBSSH2_ERROR_EAGAIN) {
1573 if(rc != 0 && !sshc->acceptfail) {
1574 err = sftp_libssh2_last_error(sshc->sftp_session);
1575 Curl_safefree(sshc->quote_path1);
1576 failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(err));
1577 state(conn, SSH_SFTP_CLOSE);
1578 sshc->nextstate = SSH_NO_STATE;
1579 sshc->actualcode = CURLE_QUOTE_ERROR;
1583 char *tmp = aprintf("statvfs:\n"
1584 "f_bsize: %llu\n" "f_frsize: %llu\n"
1585 "f_blocks: %llu\n" "f_bfree: %llu\n"
1586 "f_bavail: %llu\n" "f_files: %llu\n"
1587 "f_ffree: %llu\n" "f_favail: %llu\n"
1588 "f_fsid: %llu\n" "f_flag: %llu\n"
1589 "f_namemax: %llu\n",
1590 statvfs.f_bsize, statvfs.f_frsize,
1591 statvfs.f_blocks, statvfs.f_bfree,
1592 statvfs.f_bavail, statvfs.f_files,
1593 statvfs.f_ffree, statvfs.f_favail,
1594 statvfs.f_fsid, statvfs.f_flag,
1597 result = CURLE_OUT_OF_MEMORY;
1598 state(conn, SSH_SFTP_CLOSE);
1599 sshc->nextstate = SSH_NO_STATE;
1603 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1606 state(conn, SSH_SFTP_CLOSE);
1607 sshc->nextstate = SSH_NO_STATE;
1608 sshc->actualcode = result;
1611 state(conn, SSH_SFTP_NEXT_QUOTE);
1615 case SSH_SFTP_GETINFO:
1617 if(data->set.get_filetime) {
1618 state(conn, SSH_SFTP_FILETIME);
1621 state(conn, SSH_SFTP_TRANS_INIT);
1626 case SSH_SFTP_FILETIME:
1628 LIBSSH2_SFTP_ATTRIBUTES attrs;
1630 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1631 curlx_uztoui(strlen(sftp_scp->path)),
1632 LIBSSH2_SFTP_STAT, &attrs);
1633 if(rc == LIBSSH2_ERROR_EAGAIN) {
1637 data->info.filetime = attrs.mtime;
1640 state(conn, SSH_SFTP_TRANS_INIT);
1644 case SSH_SFTP_TRANS_INIT:
1645 if(data->set.upload)
1646 state(conn, SSH_SFTP_UPLOAD_INIT);
1648 if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1649 state(conn, SSH_SFTP_READDIR_INIT);
1651 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1655 case SSH_SFTP_UPLOAD_INIT:
1657 unsigned long flags;
1659 * NOTE!!! libssh2 requires that the destination path is a full path
1660 * that includes the destination file and name OR ends in a "/"
1661 * If this is not done the destination file will be named the
1662 * same name as the last directory in the path.
1665 if(data->state.resume_from != 0) {
1666 LIBSSH2_SFTP_ATTRIBUTES attrs;
1667 if(data->state.resume_from < 0) {
1668 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1669 curlx_uztoui(strlen(sftp_scp->path)),
1670 LIBSSH2_SFTP_STAT, &attrs);
1671 if(rc == LIBSSH2_ERROR_EAGAIN) {
1675 data->state.resume_from = 0;
1678 curl_off_t size = attrs.filesize;
1680 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
1681 return CURLE_BAD_DOWNLOAD_RESUME;
1683 data->state.resume_from = attrs.filesize;
1688 if(data->set.ftp_append)
1689 /* Try to open for append, but create if nonexisting */
1690 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1691 else if(data->state.resume_from > 0)
1692 /* If we have restart position then open for append */
1693 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1695 /* Clear file before writing (normal behaviour) */
1696 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1699 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1700 curlx_uztoui(strlen(sftp_scp->path)),
1701 flags, data->set.new_file_perms,
1702 LIBSSH2_SFTP_OPENFILE);
1704 if(!sshc->sftp_handle) {
1705 rc = libssh2_session_last_errno(sshc->ssh_session);
1707 if(LIBSSH2_ERROR_EAGAIN == rc)
1710 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1711 /* only when there was an SFTP protocol error can we extract
1713 err = sftp_libssh2_last_error(sshc->sftp_session);
1715 err = -1; /* not an sftp error at all */
1717 if(sshc->secondCreateDirs) {
1718 state(conn, SSH_SFTP_CLOSE);
1719 sshc->actualcode = err>= LIBSSH2_FX_OK?
1720 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1721 failf(data, "Creating the dir/file failed: %s",
1722 sftp_libssh2_strerror(err));
1725 if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1726 (err == LIBSSH2_FX_FAILURE) ||
1727 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1728 (data->set.ftp_create_missing_dirs &&
1729 (strlen(sftp_scp->path) > 1))) {
1730 /* try to create the path remotely */
1731 rc = 0; /* clear rc and continue */
1732 sshc->secondCreateDirs = 1;
1733 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1736 state(conn, SSH_SFTP_CLOSE);
1737 sshc->actualcode = err>= LIBSSH2_FX_OK?
1738 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1739 if(!sshc->actualcode) {
1740 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1741 zero even though libssh2_sftp_open() failed previously! We need
1742 to work around that! */
1743 sshc->actualcode = CURLE_SSH;
1746 failf(data, "Upload failed: %s (%d/%d)",
1747 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1752 /* If we have a restart point then we need to seek to the correct
1754 if(data->state.resume_from > 0) {
1755 /* Let's read off the proper amount of bytes from the input. */
1756 if(conn->seek_func) {
1757 Curl_set_in_callback(data, true);
1758 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1760 Curl_set_in_callback(data, false);
1763 if(seekerr != CURL_SEEKFUNC_OK) {
1764 curl_off_t passed = 0;
1766 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1767 failf(data, "Could not seek stream");
1768 return CURLE_FTP_COULDNT_USE_REST;
1770 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1772 size_t readthisamountnow =
1773 (data->state.resume_from - passed > data->set.buffer_size) ?
1774 (size_t)data->set.buffer_size :
1775 curlx_sotouz(data->state.resume_from - passed);
1777 size_t actuallyread;
1778 Curl_set_in_callback(data, true);
1779 actuallyread = data->state.fread_func(data->state.buffer, 1,
1782 Curl_set_in_callback(data, false);
1784 passed += actuallyread;
1785 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1786 /* this checks for greater-than only to make sure that the
1787 CURL_READFUNC_ABORT return code still aborts */
1788 failf(data, "Failed to read data");
1789 return CURLE_FTP_COULDNT_USE_REST;
1791 } while(passed < data->state.resume_from);
1794 /* now, decrease the size of the read */
1795 if(data->state.infilesize > 0) {
1796 data->state.infilesize -= data->state.resume_from;
1797 data->req.size = data->state.infilesize;
1798 Curl_pgrsSetUploadSize(data, data->state.infilesize);
1801 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1803 if(data->state.infilesize > 0) {
1804 data->req.size = data->state.infilesize;
1805 Curl_pgrsSetUploadSize(data, data->state.infilesize);
1808 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1810 /* not set by Curl_setup_transfer to preserve keepon bits */
1811 conn->sockfd = conn->writesockfd;
1814 state(conn, SSH_SFTP_CLOSE);
1815 sshc->actualcode = result;
1818 /* store this original bitmask setup to use later on if we can't
1819 figure out a "real" bitmask */
1820 sshc->orig_waitfor = data->req.keepon;
1822 /* we want to use the _sending_ function even when the socket turns
1823 out readable as the underlying libssh2 sftp send function will deal
1824 with both accordingly */
1825 conn->cselect_bits = CURL_CSELECT_OUT;
1827 /* since we don't really wait for anything at this point, we want the
1828 state machine to move on as soon as possible so we set a very short
1830 Curl_expire(data, 0, EXPIRE_RUN_NOW);
1832 state(conn, SSH_STOP);
1837 case SSH_SFTP_CREATE_DIRS_INIT:
1838 if(strlen(sftp_scp->path) > 1) {
1839 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1840 state(conn, SSH_SFTP_CREATE_DIRS);
1843 state(conn, SSH_SFTP_UPLOAD_INIT);
1847 case SSH_SFTP_CREATE_DIRS:
1848 sshc->slash_pos = strchr(sshc->slash_pos, '/');
1849 if(sshc->slash_pos) {
1850 *sshc->slash_pos = 0;
1852 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1853 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1856 state(conn, SSH_SFTP_UPLOAD_INIT);
1859 case SSH_SFTP_CREATE_DIRS_MKDIR:
1860 /* 'mode' - parameter is preliminary - default to 0644 */
1861 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1862 curlx_uztoui(strlen(sftp_scp->path)),
1863 data->set.new_directory_perms);
1864 if(rc == LIBSSH2_ERROR_EAGAIN) {
1867 *sshc->slash_pos = '/';
1871 * Abort if failure wasn't that the dir already exists or the
1872 * permission was denied (creation might succeed further down the
1873 * path) - retry on unspecific FAILURE also
1875 err = sftp_libssh2_last_error(sshc->sftp_session);
1876 if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1877 (err != LIBSSH2_FX_FAILURE) &&
1878 (err != LIBSSH2_FX_PERMISSION_DENIED)) {
1879 result = sftp_libssh2_error_to_CURLE(err);
1880 state(conn, SSH_SFTP_CLOSE);
1881 sshc->actualcode = result?result:CURLE_SSH;
1884 rc = 0; /* clear rc and continue */
1886 state(conn, SSH_SFTP_CREATE_DIRS);
1889 case SSH_SFTP_READDIR_INIT:
1890 Curl_pgrsSetDownloadSize(data, -1);
1891 if(data->set.opt_no_body) {
1892 state(conn, SSH_STOP);
1897 * This is a directory that we are trying to get, so produce a directory
1900 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1903 strlen(sftp_scp->path)),
1904 0, 0, LIBSSH2_SFTP_OPENDIR);
1905 if(!sshc->sftp_handle) {
1906 if(libssh2_session_last_errno(sshc->ssh_session) ==
1907 LIBSSH2_ERROR_EAGAIN) {
1908 rc = LIBSSH2_ERROR_EAGAIN;
1911 err = sftp_libssh2_last_error(sshc->sftp_session);
1912 failf(data, "Could not open directory for reading: %s",
1913 sftp_libssh2_strerror(err));
1914 state(conn, SSH_SFTP_CLOSE);
1915 result = sftp_libssh2_error_to_CURLE(err);
1916 sshc->actualcode = result?result:CURLE_SSH;
1919 sshc->readdir_filename = malloc(PATH_MAX + 1);
1920 if(!sshc->readdir_filename) {
1921 state(conn, SSH_SFTP_CLOSE);
1922 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1925 sshc->readdir_longentry = malloc(PATH_MAX + 1);
1926 if(!sshc->readdir_longentry) {
1927 Curl_safefree(sshc->readdir_filename);
1928 state(conn, SSH_SFTP_CLOSE);
1929 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1932 state(conn, SSH_SFTP_READDIR);
1935 case SSH_SFTP_READDIR:
1936 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1937 sshc->readdir_filename,
1939 sshc->readdir_longentry,
1941 &sshc->readdir_attrs);
1942 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1943 rc = LIBSSH2_ERROR_EAGAIN;
1946 if(sshc->readdir_len > 0) {
1947 sshc->readdir_filename[sshc->readdir_len] = '\0';
1949 if(data->set.ftp_list_only) {
1952 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1953 if(tmpLine == NULL) {
1954 state(conn, SSH_SFTP_CLOSE);
1955 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1958 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1959 tmpLine, sshc->readdir_len + 1);
1963 state(conn, SSH_STOP);
1966 /* since this counts what we send to the client, we include the
1967 newline in this counter */
1968 data->req.bytecount += sshc->readdir_len + 1;
1970 /* output debug output if that is requested */
1971 if(data->set.verbose) {
1972 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1973 sshc->readdir_len, conn);
1977 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1978 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1979 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1980 if(!sshc->readdir_line) {
1981 Curl_safefree(sshc->readdir_filename);
1982 Curl_safefree(sshc->readdir_longentry);
1983 state(conn, SSH_SFTP_CLOSE);
1984 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1988 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1989 sshc->readdir_currLen);
1990 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1991 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1992 LIBSSH2_SFTP_S_IFLNK)) {
1993 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1994 if(sshc->readdir_linkPath == NULL) {
1995 Curl_safefree(sshc->readdir_filename);
1996 Curl_safefree(sshc->readdir_longentry);
1997 state(conn, SSH_SFTP_CLOSE);
1998 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2002 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
2003 sshc->readdir_filename);
2004 state(conn, SSH_SFTP_READDIR_LINK);
2007 state(conn, SSH_SFTP_READDIR_BOTTOM);
2011 else if(sshc->readdir_len == 0) {
2012 Curl_safefree(sshc->readdir_filename);
2013 Curl_safefree(sshc->readdir_longentry);
2014 state(conn, SSH_SFTP_READDIR_DONE);
2017 else if(sshc->readdir_len <= 0) {
2018 err = sftp_libssh2_last_error(sshc->sftp_session);
2019 result = sftp_libssh2_error_to_CURLE(err);
2020 sshc->actualcode = result?result:CURLE_SSH;
2021 failf(data, "Could not open remote file for reading: %s :: %d",
2022 sftp_libssh2_strerror(err),
2023 libssh2_session_last_errno(sshc->ssh_session));
2024 Curl_safefree(sshc->readdir_filename);
2025 Curl_safefree(sshc->readdir_longentry);
2026 state(conn, SSH_SFTP_CLOSE);
2031 case SSH_SFTP_READDIR_LINK:
2033 libssh2_sftp_symlink_ex(sshc->sftp_session,
2034 sshc->readdir_linkPath,
2035 curlx_uztoui(strlen(sshc->readdir_linkPath)),
2036 sshc->readdir_filename,
2037 PATH_MAX, LIBSSH2_SFTP_READLINK);
2038 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
2039 rc = LIBSSH2_ERROR_EAGAIN;
2042 Curl_safefree(sshc->readdir_linkPath);
2044 /* get room for the filename and extra output */
2045 sshc->readdir_totalLen += 4 + sshc->readdir_len;
2046 new_readdir_line = Curl_saferealloc(sshc->readdir_line,
2047 sshc->readdir_totalLen);
2048 if(!new_readdir_line) {
2049 sshc->readdir_line = NULL;
2050 Curl_safefree(sshc->readdir_filename);
2051 Curl_safefree(sshc->readdir_longentry);
2052 state(conn, SSH_SFTP_CLOSE);
2053 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2056 sshc->readdir_line = new_readdir_line;
2058 sshc->readdir_currLen += snprintf(sshc->readdir_line +
2059 sshc->readdir_currLen,
2060 sshc->readdir_totalLen -
2061 sshc->readdir_currLen,
2063 sshc->readdir_filename);
2065 state(conn, SSH_SFTP_READDIR_BOTTOM);
2068 case SSH_SFTP_READDIR_BOTTOM:
2069 sshc->readdir_currLen += snprintf(sshc->readdir_line +
2070 sshc->readdir_currLen,
2071 sshc->readdir_totalLen -
2072 sshc->readdir_currLen, "\n");
2073 result = Curl_client_write(conn, CLIENTWRITE_BODY,
2075 sshc->readdir_currLen);
2079 /* output debug output if that is requested */
2080 if(data->set.verbose) {
2081 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
2082 sshc->readdir_currLen, conn);
2084 data->req.bytecount += sshc->readdir_currLen;
2086 Curl_safefree(sshc->readdir_line);
2088 state(conn, SSH_STOP);
2091 state(conn, SSH_SFTP_READDIR);
2094 case SSH_SFTP_READDIR_DONE:
2095 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
2096 LIBSSH2_ERROR_EAGAIN) {
2097 rc = LIBSSH2_ERROR_EAGAIN;
2100 sshc->sftp_handle = NULL;
2101 Curl_safefree(sshc->readdir_filename);
2102 Curl_safefree(sshc->readdir_longentry);
2104 /* no data to transfer */
2105 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2106 state(conn, SSH_STOP);
2109 case SSH_SFTP_DOWNLOAD_INIT:
2111 * Work on getting the specified file
2114 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
2115 curlx_uztoui(strlen(sftp_scp->path)),
2116 LIBSSH2_FXF_READ, data->set.new_file_perms,
2117 LIBSSH2_SFTP_OPENFILE);
2118 if(!sshc->sftp_handle) {
2119 if(libssh2_session_last_errno(sshc->ssh_session) ==
2120 LIBSSH2_ERROR_EAGAIN) {
2121 rc = LIBSSH2_ERROR_EAGAIN;
2124 err = sftp_libssh2_last_error(sshc->sftp_session);
2125 failf(data, "Could not open remote file for reading: %s",
2126 sftp_libssh2_strerror(err));
2127 state(conn, SSH_SFTP_CLOSE);
2128 result = sftp_libssh2_error_to_CURLE(err);
2129 sshc->actualcode = result?result:CURLE_SSH;
2132 state(conn, SSH_SFTP_DOWNLOAD_STAT);
2135 case SSH_SFTP_DOWNLOAD_STAT:
2137 LIBSSH2_SFTP_ATTRIBUTES attrs;
2139 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
2140 curlx_uztoui(strlen(sftp_scp->path)),
2141 LIBSSH2_SFTP_STAT, &attrs);
2142 if(rc == LIBSSH2_ERROR_EAGAIN) {
2146 !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
2147 (attrs.filesize == 0)) {
2149 * libssh2_sftp_open() didn't return an error, so maybe the server
2150 * just doesn't support stat()
2151 * OR the server doesn't return a file size with a stat()
2154 data->req.size = -1;
2155 data->req.maxdownload = -1;
2156 Curl_pgrsSetDownloadSize(data, -1);
2159 curl_off_t size = attrs.filesize;
2162 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
2163 return CURLE_BAD_DOWNLOAD_RESUME;
2165 if(conn->data->state.use_range) {
2166 curl_off_t from, to;
2172 from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
2173 if(from_t == CURL_OFFT_FLOW)
2174 return CURLE_RANGE_ERROR;
2175 while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
2177 to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
2178 if(to_t == CURL_OFFT_FLOW)
2179 return CURLE_RANGE_ERROR;
2180 if((to_t == CURL_OFFT_INVAL) /* no "to" value given */
2185 /* from is relative to end of file */
2190 failf(data, "Offset (%"
2191 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2192 CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
2193 return CURLE_BAD_DOWNLOAD_RESUME;
2200 size = to - from + 1;
2203 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2205 data->req.size = size;
2206 data->req.maxdownload = size;
2207 Curl_pgrsSetDownloadSize(data, size);
2210 /* We can resume if we can seek to the resume position */
2211 if(data->state.resume_from) {
2212 if(data->state.resume_from < 0) {
2213 /* We're supposed to download the last abs(from) bytes */
2214 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2215 failf(data, "Offset (%"
2216 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2217 CURL_FORMAT_CURL_OFF_T ")",
2218 data->state.resume_from, attrs.filesize);
2219 return CURLE_BAD_DOWNLOAD_RESUME;
2221 /* download from where? */
2222 data->state.resume_from += attrs.filesize;
2225 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2226 failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
2227 ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
2228 data->state.resume_from, attrs.filesize);
2229 return CURLE_BAD_DOWNLOAD_RESUME;
2232 /* Does a completed file need to be seeked and started or closed ? */
2233 /* Now store the number of bytes we are expected to download */
2234 data->req.size = attrs.filesize - data->state.resume_from;
2235 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2236 Curl_pgrsSetDownloadSize(data,
2237 attrs.filesize - data->state.resume_from);
2238 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2242 /* Setup the actual download */
2243 if(data->req.size == 0) {
2244 /* no data to transfer */
2245 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2246 infof(data, "File already completely downloaded\n");
2247 state(conn, SSH_STOP);
2250 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2251 FALSE, NULL, -1, NULL);
2253 /* not set by Curl_setup_transfer to preserve keepon bits */
2254 conn->writesockfd = conn->sockfd;
2256 /* we want to use the _receiving_ function even when the socket turns
2257 out writableable as the underlying libssh2 recv function will deal
2258 with both accordingly */
2259 conn->cselect_bits = CURL_CSELECT_IN;
2262 /* this should never occur; the close state should be entered
2263 at the time the error occurs */
2264 state(conn, SSH_SFTP_CLOSE);
2265 sshc->actualcode = result;
2268 state(conn, SSH_STOP);
2272 case SSH_SFTP_CLOSE:
2273 if(sshc->sftp_handle) {
2274 rc = libssh2_sftp_close(sshc->sftp_handle);
2275 if(rc == LIBSSH2_ERROR_EAGAIN) {
2279 infof(data, "Failed to close libssh2 file\n");
2281 sshc->sftp_handle = NULL;
2284 Curl_safefree(sftp_scp->path);
2286 DEBUGF(infof(data, "SFTP DONE done\n"));
2288 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2289 After nextstate is executed, the control should come back to
2290 SSH_SFTP_CLOSE to pass the correct result back */
2291 if(sshc->nextstate != SSH_NO_STATE &&
2292 sshc->nextstate != SSH_SFTP_CLOSE) {
2293 state(conn, sshc->nextstate);
2294 sshc->nextstate = SSH_SFTP_CLOSE;
2297 state(conn, SSH_STOP);
2298 result = sshc->actualcode;
2302 case SSH_SFTP_SHUTDOWN:
2303 /* during times we get here due to a broken transfer and then the
2304 sftp_handle might not have been taken down so make sure that is done
2305 before we proceed */
2307 if(sshc->sftp_handle) {
2308 rc = libssh2_sftp_close(sshc->sftp_handle);
2309 if(rc == LIBSSH2_ERROR_EAGAIN) {
2313 infof(data, "Failed to close libssh2 file\n");
2315 sshc->sftp_handle = NULL;
2317 if(sshc->sftp_session) {
2318 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2319 if(rc == LIBSSH2_ERROR_EAGAIN) {
2323 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2325 sshc->sftp_session = NULL;
2328 Curl_safefree(sshc->homedir);
2329 conn->data->state.most_recent_ftp_entrypath = NULL;
2331 state(conn, SSH_SESSION_DISCONNECT);
2334 case SSH_SCP_TRANS_INIT:
2335 result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2337 sshc->actualcode = result;
2338 state(conn, SSH_STOP);
2342 if(data->set.upload) {
2343 if(data->state.infilesize < 0) {
2344 failf(data, "SCP requires a known file size for upload");
2345 sshc->actualcode = CURLE_UPLOAD_FAILED;
2346 state(conn, SSH_SCP_CHANNEL_FREE);
2349 state(conn, SSH_SCP_UPLOAD_INIT);
2352 state(conn, SSH_SCP_DOWNLOAD_INIT);
2356 case SSH_SCP_UPLOAD_INIT:
2358 * libssh2 requires that the destination path is a full path that
2359 * includes the destination file and name OR ends in a "/" . If this is
2360 * not done the destination file will be named the same name as the last
2361 * directory in the path.
2364 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2365 data->state.infilesize);
2366 if(!sshc->ssh_channel) {
2370 if(libssh2_session_last_errno(sshc->ssh_session) ==
2371 LIBSSH2_ERROR_EAGAIN) {
2372 rc = LIBSSH2_ERROR_EAGAIN;
2376 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2377 &err_msg, NULL, 0));
2378 failf(conn->data, "%s", err_msg);
2379 state(conn, SSH_SCP_CHANNEL_FREE);
2380 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2381 /* Map generic errors to upload failed */
2382 if(sshc->actualcode == CURLE_SSH ||
2383 sshc->actualcode == CURLE_REMOTE_FILE_NOT_FOUND)
2384 sshc->actualcode = CURLE_UPLOAD_FAILED;
2389 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2392 /* not set by Curl_setup_transfer to preserve keepon bits */
2393 conn->sockfd = conn->writesockfd;
2396 state(conn, SSH_SCP_CHANNEL_FREE);
2397 sshc->actualcode = result;
2400 /* store this original bitmask setup to use later on if we can't
2401 figure out a "real" bitmask */
2402 sshc->orig_waitfor = data->req.keepon;
2404 /* we want to use the _sending_ function even when the socket turns
2405 out readable as the underlying libssh2 scp send function will deal
2406 with both accordingly */
2407 conn->cselect_bits = CURL_CSELECT_OUT;
2409 state(conn, SSH_STOP);
2413 case SSH_SCP_DOWNLOAD_INIT:
2415 curl_off_t bytecount;
2418 * We must check the remote file; if it is a directory no values will
2423 * If support for >2GB files exists, use it.
2426 /* get a fresh new channel from the ssh layer */
2427 #if LIBSSH2_VERSION_NUM < 0x010700
2429 memset(&sb, 0, sizeof(struct stat));
2430 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2431 sftp_scp->path, &sb);
2433 libssh2_struct_stat sb;
2434 memset(&sb, 0, sizeof(libssh2_struct_stat));
2435 sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session,
2436 sftp_scp->path, &sb);
2439 if(!sshc->ssh_channel) {
2443 if(libssh2_session_last_errno(sshc->ssh_session) ==
2444 LIBSSH2_ERROR_EAGAIN) {
2445 rc = LIBSSH2_ERROR_EAGAIN;
2450 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2451 &err_msg, NULL, 0));
2452 failf(conn->data, "%s", err_msg);
2453 state(conn, SSH_SCP_CHANNEL_FREE);
2454 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2459 bytecount = (curl_off_t)sb.st_size;
2460 data->req.maxdownload = (curl_off_t)sb.st_size;
2461 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2463 /* not set by Curl_setup_transfer to preserve keepon bits */
2464 conn->writesockfd = conn->sockfd;
2466 /* we want to use the _receiving_ function even when the socket turns
2467 out writableable as the underlying libssh2 recv function will deal
2468 with both accordingly */
2469 conn->cselect_bits = CURL_CSELECT_IN;
2472 state(conn, SSH_SCP_CHANNEL_FREE);
2473 sshc->actualcode = result;
2476 state(conn, SSH_STOP);
2481 if(data->set.upload)
2482 state(conn, SSH_SCP_SEND_EOF);
2484 state(conn, SSH_SCP_CHANNEL_FREE);
2487 case SSH_SCP_SEND_EOF:
2488 if(sshc->ssh_channel) {
2489 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2490 if(rc == LIBSSH2_ERROR_EAGAIN) {
2494 infof(data, "Failed to send libssh2 channel EOF\n");
2497 state(conn, SSH_SCP_WAIT_EOF);
2500 case SSH_SCP_WAIT_EOF:
2501 if(sshc->ssh_channel) {
2502 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2503 if(rc == LIBSSH2_ERROR_EAGAIN) {
2507 infof(data, "Failed to get channel EOF: %d\n", rc);
2510 state(conn, SSH_SCP_WAIT_CLOSE);
2513 case SSH_SCP_WAIT_CLOSE:
2514 if(sshc->ssh_channel) {
2515 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2516 if(rc == LIBSSH2_ERROR_EAGAIN) {
2520 infof(data, "Channel failed to close: %d\n", rc);
2523 state(conn, SSH_SCP_CHANNEL_FREE);
2526 case SSH_SCP_CHANNEL_FREE:
2527 if(sshc->ssh_channel) {
2528 rc = libssh2_channel_free(sshc->ssh_channel);
2529 if(rc == LIBSSH2_ERROR_EAGAIN) {
2533 infof(data, "Failed to free libssh2 scp subsystem\n");
2535 sshc->ssh_channel = NULL;
2537 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2539 state(conn, SSH_SESSION_DISCONNECT);
2541 state(conn, SSH_STOP);
2542 result = sshc->actualcode;
2545 case SSH_SESSION_DISCONNECT:
2546 /* during weird times when we've been prematurely aborted, the channel
2547 is still alive when we reach this state and we MUST kill the channel
2549 if(sshc->ssh_channel) {
2550 rc = libssh2_channel_free(sshc->ssh_channel);
2551 if(rc == LIBSSH2_ERROR_EAGAIN) {
2555 infof(data, "Failed to free libssh2 scp subsystem\n");
2557 sshc->ssh_channel = NULL;
2560 if(sshc->ssh_session) {
2561 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2562 if(rc == LIBSSH2_ERROR_EAGAIN) {
2566 infof(data, "Failed to disconnect libssh2 session\n");
2570 Curl_safefree(sshc->homedir);
2571 conn->data->state.most_recent_ftp_entrypath = NULL;
2573 state(conn, SSH_SESSION_FREE);
2576 case SSH_SESSION_FREE:
2577 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2579 libssh2_knownhost_free(sshc->kh);
2584 #ifdef HAVE_LIBSSH2_AGENT_API
2585 if(sshc->ssh_agent) {
2586 rc = libssh2_agent_disconnect(sshc->ssh_agent);
2587 if(rc == LIBSSH2_ERROR_EAGAIN) {
2591 infof(data, "Failed to disconnect from libssh2 agent\n");
2593 libssh2_agent_free(sshc->ssh_agent);
2594 sshc->ssh_agent = NULL;
2596 /* NB: there is no need to free identities, they are part of internal
2598 sshc->sshagent_identity = NULL;
2599 sshc->sshagent_prev_identity = NULL;
2603 if(sshc->ssh_session) {
2604 rc = libssh2_session_free(sshc->ssh_session);
2605 if(rc == LIBSSH2_ERROR_EAGAIN) {
2609 infof(data, "Failed to free libssh2 session\n");
2611 sshc->ssh_session = NULL;
2614 /* worst-case scenario cleanup */
2616 DEBUGASSERT(sshc->ssh_session == NULL);
2617 DEBUGASSERT(sshc->ssh_channel == NULL);
2618 DEBUGASSERT(sshc->sftp_session == NULL);
2619 DEBUGASSERT(sshc->sftp_handle == NULL);
2620 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2621 DEBUGASSERT(sshc->kh == NULL);
2623 #ifdef HAVE_LIBSSH2_AGENT_API
2624 DEBUGASSERT(sshc->ssh_agent == NULL);
2627 Curl_safefree(sshc->rsa_pub);
2628 Curl_safefree(sshc->rsa);
2630 Curl_safefree(sshc->quote_path1);
2631 Curl_safefree(sshc->quote_path2);
2633 Curl_safefree(sshc->homedir);
2635 Curl_safefree(sshc->readdir_filename);
2636 Curl_safefree(sshc->readdir_longentry);
2637 Curl_safefree(sshc->readdir_line);
2638 Curl_safefree(sshc->readdir_linkPath);
2640 /* the code we are about to return */
2641 result = sshc->actualcode;
2643 memset(sshc, 0, sizeof(struct ssh_conn));
2645 connclose(conn, "SSH session free");
2646 sshc->state = SSH_SESSION_FREE; /* current */
2647 sshc->nextstate = SSH_NO_STATE;
2648 state(conn, SSH_STOP);
2652 /* fallthrough, just stop! */
2654 /* internal error */
2655 sshc->nextstate = SSH_NO_STATE;
2656 state(conn, SSH_STOP);
2660 } while(!rc && (sshc->state != SSH_STOP));
2662 if(rc == LIBSSH2_ERROR_EAGAIN) {
2663 /* we would block, we need to wait for the socket to be ready (in the
2664 right direction too)! */
2671 /* called by the multi interface to figure out what socket(s) to wait for and
2672 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2673 static int ssh_perform_getsock(const struct connectdata *conn,
2674 curl_socket_t *sock, /* points to numsocks
2675 number of sockets */
2678 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2679 int bitmap = GETSOCK_BLANK;
2682 sock[0] = conn->sock[FIRSTSOCKET];
2684 if(conn->waitfor & KEEP_RECV)
2685 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2687 if(conn->waitfor & KEEP_SEND)
2688 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2692 /* if we don't know the direction we can use the generic *_getsock()
2693 function even for the protocol_connect and doing states */
2694 return Curl_single_getsock(conn, sock, numsocks);
2698 /* Generic function called by the multi interface to figure out what socket(s)
2699 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2700 static int ssh_getsock(struct connectdata *conn,
2701 curl_socket_t *sock, /* points to numsocks number
2705 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2709 /* if we don't know any direction we can just play along as we used to and
2710 not provide any sensible info */
2711 return GETSOCK_BLANK;
2713 /* if we know the direction we can use the generic *_getsock() function even
2714 for the protocol_connect and doing states */
2715 return ssh_perform_getsock(conn, sock, numsocks);
2719 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2721 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2722 * function is used to figure out in what direction and stores this info so
2723 * that the multi interface can take advantage of it. Make sure to call this
2724 * function in all cases so that when it _doesn't_ return EAGAIN we can
2725 * restore the default wait bits.
2727 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2729 struct ssh_conn *sshc = &conn->proto.sshc;
2732 dir = libssh2_session_block_directions(sshc->ssh_session);
2734 /* translate the libssh2 define bits into our own bit defines */
2735 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2736 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2740 /* It didn't block or libssh2 didn't reveal in which direction, put back
2742 conn->waitfor = sshc->orig_waitfor;
2745 /* no libssh2 directional support so we simply don't know */
2746 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2749 /* called repeatedly until done from multi.c */
2750 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2752 struct ssh_conn *sshc = &conn->proto.sshc;
2753 CURLcode result = CURLE_OK;
2754 bool block; /* we store the status and use that to provide a ssh_getsock()
2757 result = ssh_statemach_act(conn, &block);
2758 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2759 ssh_block2waitfor(conn, block);
2764 static CURLcode ssh_block_statemach(struct connectdata *conn,
2767 struct ssh_conn *sshc = &conn->proto.sshc;
2768 CURLcode result = CURLE_OK;
2769 struct Curl_easy *data = conn->data;
2771 while((sshc->state != SSH_STOP) && !result) {
2773 timediff_t left = 1000;
2774 struct curltime now = Curl_now();
2776 result = ssh_statemach_act(conn, &block);
2781 if(Curl_pgrsUpdate(conn))
2782 return CURLE_ABORTED_BY_CALLBACK;
2784 result = Curl_speedcheck(data, now);
2788 left = Curl_timeleft(data, NULL, FALSE);
2790 failf(data, "Operation timed out");
2791 return CURLE_OPERATION_TIMEDOUT;
2795 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2796 if(!result && block) {
2797 int dir = libssh2_session_block_directions(sshc->ssh_session);
2798 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2799 curl_socket_t fd_read = CURL_SOCKET_BAD;
2800 curl_socket_t fd_write = CURL_SOCKET_BAD;
2801 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2803 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2805 /* wait for the socket to become ready */
2806 (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
2807 left>1000?1000:left); /* ignore result */
2817 * SSH setup and connection
2819 static CURLcode ssh_setup_connection(struct connectdata *conn)
2821 struct SSHPROTO *ssh;
2823 conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
2825 return CURLE_OUT_OF_MEMORY;
2830 static Curl_recv scp_recv, sftp_recv;
2831 static Curl_send scp_send, sftp_send;
2834 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2835 * do protocol-specific actions at connect-time.
2837 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2839 #ifdef CURL_LIBSSH2_DEBUG
2842 struct ssh_conn *ssh;
2844 struct Curl_easy *data = conn->data;
2846 /* initialize per-handle data if not already */
2847 if(!data->req.protop)
2848 ssh_setup_connection(conn);
2850 /* We default to persistent connections. We set this already in this connect
2851 function to make the re-use checks properly be able to check this bit. */
2852 connkeep(conn, "SSH default");
2854 if(conn->handler->protocol & CURLPROTO_SCP) {
2855 conn->recv[FIRSTSOCKET] = scp_recv;
2856 conn->send[FIRSTSOCKET] = scp_send;
2859 conn->recv[FIRSTSOCKET] = sftp_recv;
2860 conn->send[FIRSTSOCKET] = sftp_send;
2862 ssh = &conn->proto.sshc;
2864 #ifdef CURL_LIBSSH2_DEBUG
2866 infof(data, "User: %s\n", conn->user);
2869 infof(data, "Password: %s\n", conn->passwd);
2871 sock = conn->sock[FIRSTSOCKET];
2872 #endif /* CURL_LIBSSH2_DEBUG */
2874 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2876 my_libssh2_realloc, conn);
2877 if(ssh->ssh_session == NULL) {
2878 failf(data, "Failure initialising ssh session");
2879 return CURLE_FAILED_INIT;
2882 if(data->set.ssh_compression) {
2883 #if LIBSSH2_VERSION_NUM >= 0x010208
2884 if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0)
2886 infof(data, "Failed to enable compression for ssh session\n");
2889 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2890 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2892 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2894 /* eeek. TODO: free the ssh_session! */
2895 return CURLE_FAILED_INIT;
2898 /* read all known hosts from there */
2899 rc = libssh2_knownhost_readfile(ssh->kh,
2900 data->set.str[STRING_SSH_KNOWNHOSTS],
2901 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2903 infof(data, "Failed to read known hosts from %s\n",
2904 data->set.str[STRING_SSH_KNOWNHOSTS]);
2906 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2908 #ifdef CURL_LIBSSH2_DEBUG
2909 libssh2_trace(ssh->ssh_session, ~0);
2910 infof(data, "SSH socket: %d\n", (int)sock);
2911 #endif /* CURL_LIBSSH2_DEBUG */
2913 state(conn, SSH_INIT);
2915 result = ssh_multi_statemach(conn, done);
2921 ***********************************************************************
2925 * This is the actual DO function for SCP. Get a file according to
2926 * the options previously setup.
2930 CURLcode scp_perform(struct connectdata *conn,
2934 CURLcode result = CURLE_OK;
2936 DEBUGF(infof(conn->data, "DO phase starts\n"));
2938 *dophase_done = FALSE; /* not done yet */
2940 /* start the first command in the DO phase */
2941 state(conn, SSH_SCP_TRANS_INIT);
2943 /* run the state-machine */
2944 result = ssh_multi_statemach(conn, dophase_done);
2946 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2949 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2955 /* called from multi.c while DOing */
2956 static CURLcode scp_doing(struct connectdata *conn,
2960 result = ssh_multi_statemach(conn, dophase_done);
2963 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2969 * The DO function is generic for both protocols. There was previously two
2970 * separate ones but this way means less duplicated code.
2973 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2977 struct Curl_easy *data = conn->data;
2978 struct ssh_conn *sshc = &conn->proto.sshc;
2980 *done = FALSE; /* default to false */
2982 data->req.size = -1; /* make sure this is unknown at this point */
2984 sshc->actualcode = CURLE_OK; /* reset error code */
2985 sshc->secondCreateDirs = 0; /* reset the create dir attempt state
2988 Curl_pgrsSetUploadCounter(data, 0);
2989 Curl_pgrsSetDownloadCounter(data, 0);
2990 Curl_pgrsSetUploadSize(data, -1);
2991 Curl_pgrsSetDownloadSize(data, -1);
2993 if(conn->handler->protocol & CURLPROTO_SCP)
2994 result = scp_perform(conn, &connected, done);
2996 result = sftp_perform(conn, &connected, done);
3001 /* BLOCKING, but the function is using the state machine so the only reason
3002 this is still blocking is that the multi interface code has no support for
3003 disconnecting operations that takes a while */
3004 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
3006 CURLcode result = CURLE_OK;
3007 struct ssh_conn *ssh = &conn->proto.sshc;
3008 (void) dead_connection;
3010 if(ssh->ssh_session) {
3011 /* only if there's a session still around to use! */
3013 state(conn, SSH_SESSION_DISCONNECT);
3015 result = ssh_block_statemach(conn, TRUE);
3021 /* generic done function for both SCP and SFTP called from their specific
3023 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
3025 CURLcode result = CURLE_OK;
3026 struct SSHPROTO *sftp_scp = conn->data->req.protop;
3029 /* run the state-machine
3031 TODO: when the multi interface is used, this _really_ should be using
3032 the ssh_multi_statemach function but we have no general support for
3033 non-blocking DONE operations!
3035 result = ssh_block_statemach(conn, FALSE);
3041 Curl_safefree(sftp_scp->path);
3042 if(Curl_pgrsDone(conn))
3043 return CURLE_ABORTED_BY_CALLBACK;
3045 conn->data->req.keepon = 0; /* clear all bits */
3050 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
3053 (void)premature; /* not used */
3056 state(conn, SSH_SCP_DONE);
3058 return ssh_done(conn, status);
3062 static ssize_t scp_send(struct connectdata *conn, int sockindex,
3063 const void *mem, size_t len, CURLcode *err)
3066 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3068 /* libssh2_channel_write() returns int! */
3070 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
3072 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3074 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3078 else if(nwrite < LIBSSH2_ERROR_NONE) {
3079 *err = libssh2_session_error_to_CURLE((int)nwrite);
3086 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
3087 char *mem, size_t len, CURLcode *err)
3090 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3092 /* libssh2_channel_read() returns int */
3094 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
3096 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3097 if(nread == LIBSSH2_ERROR_EAGAIN) {
3106 * =============== SFTP ===============
3110 ***********************************************************************
3114 * This is the actual DO function for SFTP. Get a file/directory according to
3115 * the options previously setup.
3119 CURLcode sftp_perform(struct connectdata *conn,
3123 CURLcode result = CURLE_OK;
3125 DEBUGF(infof(conn->data, "DO phase starts\n"));
3127 *dophase_done = FALSE; /* not done yet */
3129 /* start the first command in the DO phase */
3130 state(conn, SSH_SFTP_QUOTE_INIT);
3132 /* run the state-machine */
3133 result = ssh_multi_statemach(conn, dophase_done);
3135 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3138 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3144 /* called from multi.c while DOing */
3145 static CURLcode sftp_doing(struct connectdata *conn,
3148 CURLcode result = ssh_multi_statemach(conn, dophase_done);
3151 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3156 /* BLOCKING, but the function is using the state machine so the only reason
3157 this is still blocking is that the multi interface code has no support for
3158 disconnecting operations that takes a while */
3159 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
3161 CURLcode result = CURLE_OK;
3162 (void) dead_connection;
3164 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3166 if(conn->proto.sshc.ssh_session) {
3167 /* only if there's a session still around to use! */
3168 state(conn, SSH_SFTP_SHUTDOWN);
3169 result = ssh_block_statemach(conn, TRUE);
3172 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3178 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3181 struct ssh_conn *sshc = &conn->proto.sshc;
3184 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3185 errors that could happen due to open file handles during POSTQUOTE
3187 if(!status && !premature && conn->data->set.postquote) {
3188 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3189 state(conn, SSH_SFTP_CLOSE);
3192 state(conn, SSH_SFTP_CLOSE);
3194 return ssh_done(conn, status);
3197 /* return number of sent bytes */
3198 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3199 const void *mem, size_t len, CURLcode *err)
3201 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3202 but is changed to ssize_t in 0.15. These days we don't
3203 support libssh2 0.15*/
3206 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3208 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3210 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3214 else if(nwrite < LIBSSH2_ERROR_NONE) {
3215 *err = libssh2_session_error_to_CURLE((int)nwrite);
3223 * Return number of received (decrypted) bytes
3226 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3227 char *mem, size_t len, CURLcode *err)
3232 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3234 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3236 if(nread == LIBSSH2_ERROR_EAGAIN) {
3241 else if(nread < 0) {
3242 *err = libssh2_session_error_to_CURLE((int)nread);
3247 static const char *sftp_libssh2_strerror(int err)
3250 case LIBSSH2_FX_NO_SUCH_FILE:
3251 return "No such file or directory";
3253 case LIBSSH2_FX_PERMISSION_DENIED:
3254 return "Permission denied";
3256 case LIBSSH2_FX_FAILURE:
3257 return "Operation failed";
3259 case LIBSSH2_FX_BAD_MESSAGE:
3260 return "Bad message from SFTP server";
3262 case LIBSSH2_FX_NO_CONNECTION:
3263 return "Not connected to SFTP server";
3265 case LIBSSH2_FX_CONNECTION_LOST:
3266 return "Connection to SFTP server lost";
3268 case LIBSSH2_FX_OP_UNSUPPORTED:
3269 return "Operation not supported by SFTP server";
3271 case LIBSSH2_FX_INVALID_HANDLE:
3272 return "Invalid handle";
3274 case LIBSSH2_FX_NO_SUCH_PATH:
3275 return "No such file or directory";
3277 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3278 return "File already exists";
3280 case LIBSSH2_FX_WRITE_PROTECT:
3281 return "File is write protected";
3283 case LIBSSH2_FX_NO_MEDIA:
3286 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3289 case LIBSSH2_FX_QUOTA_EXCEEDED:
3290 return "User quota exceeded";
3292 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3293 return "Unknown principle";
3295 case LIBSSH2_FX_LOCK_CONFlICT:
3296 return "File lock conflict";
3298 case LIBSSH2_FX_DIR_NOT_EMPTY:
3299 return "Directory not empty";
3301 case LIBSSH2_FX_NOT_A_DIRECTORY:
3302 return "Not a directory";
3304 case LIBSSH2_FX_INVALID_FILENAME:
3305 return "Invalid filename";
3307 case LIBSSH2_FX_LINK_LOOP:
3308 return "Link points to itself";
3310 return "Unknown error in libssh2";
3313 #endif /* USE_LIBSSH2 */