1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 /* #define CURL_LIBSSH2_DEBUG */
34 #include <libssh2_sftp.h>
44 #ifdef HAVE_SYS_SOCKET_H
45 #include <sys/socket.h>
47 #ifdef HAVE_NETINET_IN_H
48 #include <netinet/in.h>
50 #ifdef HAVE_ARPA_INET_H
51 #include <arpa/inet.h>
54 #include <sys/utsname.h>
64 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
66 #define in_addr_t unsigned long
69 #include <curl/curl.h>
76 #include "http.h" /* for HTTP proxy tunnel stuff */
79 #include "speedcheck.h"
86 #include "inet_ntop.h"
87 #include "parsedate.h" /* for the week day and month names */
88 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
89 #include "strtoofft.h"
94 #define _MPRINTF_REPLACE /* use our functions only */
95 #include <curl/mprintf.h>
97 #include "curl_memory.h"
98 /* The last #include file should be: */
103 # define PATH_MAX MAX_PATH
107 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
108 have their definition hidden well */
111 /* Local functions: */
112 static const char *sftp_libssh2_strerror(unsigned long err);
113 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
114 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
115 static LIBSSH2_FREE_FUNC(my_libssh2_free);
117 static CURLcode get_pathname(const char **cpp, char **path);
119 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
120 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
121 static CURLcode ssh_do(struct connectdata *conn, bool *done);
123 static CURLcode ssh_getworkingpath(struct connectdata *conn,
124 char *homedir, /* when SFTP is used */
127 static CURLcode scp_done(struct connectdata *conn,
128 CURLcode, bool premature);
129 static CURLcode scp_doing(struct connectdata *conn,
131 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
133 static CURLcode sftp_done(struct connectdata *conn,
134 CURLcode, bool premature);
135 static CURLcode sftp_doing(struct connectdata *conn,
137 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
139 CURLcode sftp_perform(struct connectdata *conn,
143 static int ssh_getsock(struct connectdata *conn,
144 curl_socket_t *sock, /* points to numsocks number
148 static int ssh_perform_getsock(const struct connectdata *conn,
149 curl_socket_t *sock, /* points to numsocks
154 * SCP protocol handler.
157 const struct Curl_handler Curl_handler_scp = {
159 ZERO_NULL, /* setup_connection */
162 ZERO_NULL, /* do_more */
163 ssh_connect, /* connect_it */
164 ssh_multi_statemach, /* connecting */
165 scp_doing, /* doing */
166 ssh_getsock, /* proto_getsock */
167 ssh_getsock, /* doing_getsock */
168 ZERO_NULL, /* domore_getsock */
169 ssh_perform_getsock, /* perform_getsock */
170 scp_disconnect, /* disconnect */
171 ZERO_NULL, /* readwrite */
172 PORT_SSH, /* defport */
173 CURLPROTO_SCP, /* protocol */
174 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
175 | PROTOPT_NOURLQUERY /* flags */
180 * SFTP protocol handler.
183 const struct Curl_handler Curl_handler_sftp = {
185 ZERO_NULL, /* setup_connection */
187 sftp_done, /* done */
188 ZERO_NULL, /* do_more */
189 ssh_connect, /* connect_it */
190 ssh_multi_statemach, /* connecting */
191 sftp_doing, /* doing */
192 ssh_getsock, /* proto_getsock */
193 ssh_getsock, /* doing_getsock */
194 ZERO_NULL, /* domore_getsock */
195 ssh_perform_getsock, /* perform_getsock */
196 sftp_disconnect, /* disconnect */
197 ZERO_NULL, /* readwrite */
198 PORT_SSH, /* defport */
199 CURLPROTO_SFTP, /* protocol */
200 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
201 | PROTOPT_NOURLQUERY /* flags */
206 kbd_callback(const char *name, int name_len, const char *instruction,
207 int instruction_len, int num_prompts,
208 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
209 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
212 struct connectdata *conn = (struct connectdata *)*abstract;
214 #ifdef CURL_LIBSSH2_DEBUG
215 fprintf(stderr, "name=%s\n", name);
216 fprintf(stderr, "name_len=%d\n", name_len);
217 fprintf(stderr, "instruction=%s\n", instruction);
218 fprintf(stderr, "instruction_len=%d\n", instruction_len);
219 fprintf(stderr, "num_prompts=%d\n", num_prompts);
224 (void)instruction_len;
225 #endif /* CURL_LIBSSH2_DEBUG */
226 if(num_prompts == 1) {
227 responses[0].text = strdup(conn->passwd);
228 responses[0].length = (unsigned int)strlen(conn->passwd);
234 static CURLcode sftp_libssh2_error_to_CURLE(int err)
240 case LIBSSH2_FX_NO_SUCH_FILE:
241 case LIBSSH2_FX_NO_SUCH_PATH:
242 return CURLE_REMOTE_FILE_NOT_FOUND;
244 case LIBSSH2_FX_PERMISSION_DENIED:
245 case LIBSSH2_FX_WRITE_PROTECT:
246 case LIBSSH2_FX_LOCK_CONFlICT:
247 return CURLE_REMOTE_ACCESS_DENIED;
249 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
250 case LIBSSH2_FX_QUOTA_EXCEEDED:
251 return CURLE_REMOTE_DISK_FULL;
253 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
254 return CURLE_REMOTE_FILE_EXISTS;
256 case LIBSSH2_FX_DIR_NOT_EMPTY:
257 return CURLE_QUOTE_ERROR;
266 static CURLcode libssh2_session_error_to_CURLE(int err)
269 /* Ordered by order of appearance in libssh2.h */
270 case LIBSSH2_ERROR_NONE:
273 case LIBSSH2_ERROR_SOCKET_NONE:
274 return CURLE_COULDNT_CONNECT;
276 case LIBSSH2_ERROR_ALLOC:
277 return CURLE_OUT_OF_MEMORY;
279 case LIBSSH2_ERROR_SOCKET_SEND:
280 return CURLE_SEND_ERROR;
282 case LIBSSH2_ERROR_HOSTKEY_INIT:
283 case LIBSSH2_ERROR_HOSTKEY_SIGN:
284 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
285 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
286 return CURLE_PEER_FAILED_VERIFICATION;
288 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
289 return CURLE_LOGIN_DENIED;
291 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
292 case LIBSSH2_ERROR_TIMEOUT:
293 return CURLE_OPERATION_TIMEDOUT;
295 case LIBSSH2_ERROR_EAGAIN:
299 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
300 error code, and possibly add a few new SSH-related one. We must however
301 not return or even depend on libssh2 errors in the public libcurl API */
306 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
308 (void)abstract; /* arg not used */
309 return malloc(count);
312 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
314 (void)abstract; /* arg not used */
315 return realloc(ptr, count);
318 static LIBSSH2_FREE_FUNC(my_libssh2_free)
320 (void)abstract; /* arg not used */
325 * SSH State machine related code
327 /* This is the ONLY way to change SSH state! */
328 static void state(struct connectdata *conn, sshstate nowstate)
330 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
331 /* for debug purposes */
332 static const char * const names[] = {
338 "SSH_AUTH_PKEY_INIT",
340 "SSH_AUTH_PASS_INIT",
342 "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_TRANS_INIT",
361 "SSH_SFTP_UPLOAD_INIT",
362 "SSH_SFTP_CREATE_DIRS_INIT",
363 "SSH_SFTP_CREATE_DIRS",
364 "SSH_SFTP_CREATE_DIRS_MKDIR",
365 "SSH_SFTP_READDIR_INIT",
367 "SSH_SFTP_READDIR_LINK",
368 "SSH_SFTP_READDIR_BOTTOM",
369 "SSH_SFTP_READDIR_DONE",
370 "SSH_SFTP_DOWNLOAD_INIT",
371 "SSH_SFTP_DOWNLOAD_STAT",
374 "SSH_SCP_TRANS_INIT",
375 "SSH_SCP_UPLOAD_INIT",
376 "SSH_SCP_DOWNLOAD_INIT",
380 "SSH_SCP_WAIT_CLOSE",
381 "SSH_SCP_CHANNEL_FREE",
382 "SSH_SESSION_DISCONNECT",
387 struct ssh_conn *sshc = &conn->proto.sshc;
389 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
390 if(sshc->state != nowstate) {
391 infof(conn->data, "SFTP %p state change from %s to %s\n",
392 sshc, names[sshc->state], names[nowstate]);
396 sshc->state = nowstate;
399 /* figure out the path to work with in this particular request */
400 static CURLcode ssh_getworkingpath(struct connectdata *conn,
401 char *homedir, /* when SFTP is used */
402 char **path) /* returns the allocated
403 real path to work with */
405 struct SessionHandle *data = conn->data;
406 char *real_path = NULL;
408 int working_path_len;
410 working_path = curl_easy_unescape(data, data->state.path, 0,
413 return CURLE_OUT_OF_MEMORY;
415 /* Check for /~/ , indicating relative to the user's home directory */
416 if(conn->handler->protocol & CURLPROTO_SCP) {
417 real_path = malloc(working_path_len+1);
418 if(real_path == NULL) {
420 return CURLE_OUT_OF_MEMORY;
422 if((working_path_len > 1) && (working_path[1] == '~'))
423 /* It is referenced to the home directory, so strip the leading '/' */
424 memcpy(real_path, working_path+1, 1 + working_path_len-1);
426 memcpy(real_path, working_path, 1 + working_path_len);
428 else if(conn->handler->protocol & CURLPROTO_SFTP) {
429 if((working_path_len > 1) && (working_path[1] == '~')) {
430 size_t homelen = strlen(homedir);
431 real_path = malloc(homelen + working_path_len + 1);
432 if(real_path == NULL) {
434 return CURLE_OUT_OF_MEMORY;
436 /* It is referenced to the home directory, so strip the
438 memcpy(real_path, homedir, homelen);
439 real_path[homelen] = '/';
440 real_path[homelen+1] = '\0';
441 if(working_path_len > 3) {
442 memcpy(real_path+homelen+1, working_path + 3,
443 1 + working_path_len -3);
447 real_path = malloc(working_path_len+1);
448 if(real_path == NULL) {
450 return CURLE_OUT_OF_MEMORY;
452 memcpy(real_path, working_path, 1+working_path_len);
458 /* store the pointer for the caller to receive */
464 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
465 static int sshkeycallback(CURL *easy,
466 const struct curl_khkey *knownkey, /* known */
467 const struct curl_khkey *foundkey, /* found */
468 enum curl_khmatch match,
476 /* we only allow perfect matches, and we reject everything else */
477 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
482 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
485 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
486 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
488 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
492 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
493 * architectures so we check of the necessary function is present.
495 #ifndef HAVE_LIBSSH2_SCP_SEND64
496 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
498 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
499 (libssh2_uint64_t)d, 0, 0)
503 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
505 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
506 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
509 static CURLcode ssh_knownhost(struct connectdata *conn)
511 CURLcode result = CURLE_OK;
513 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
514 struct SessionHandle *data = conn->data;
516 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
517 /* we're asked to verify the host against a file */
518 struct ssh_conn *sshc = &conn->proto.sshc;
522 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
524 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
529 * A subject to figure out is what host name we need to pass in here.
530 * What host name does OpenSSH store in its file if an IDN name is
533 struct libssh2_knownhost *host;
534 enum curl_khmatch keymatch;
535 curl_sshkeycallback func =
536 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
537 struct curl_khkey knownkey;
538 struct curl_khkey *knownkeyp = NULL;
539 struct curl_khkey foundkey;
541 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
542 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
544 keycheck = libssh2_knownhost_check(sshc->kh,
547 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
548 LIBSSH2_KNOWNHOST_KEYENC_RAW|
552 infof(data, "SSH host check: %d, key: %s\n", keycheck,
553 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
556 /* setup 'knownkey' */
557 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
558 knownkey.key = host->key;
560 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
561 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
562 knownkeyp = &knownkey;
565 /* setup 'foundkey' */
566 foundkey.key = remotekey;
567 foundkey.len = keylen;
568 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
569 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
572 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
573 * curl_khmatch enum are ever modified, we need to introduce a
574 * translation table here!
576 keymatch = (enum curl_khmatch)keycheck;
578 /* Ask the callback how to behave */
579 rc = func(data, knownkeyp, /* from the knownhosts file */
580 &foundkey, /* from the remote host */
581 keymatch, data->set.ssh_keyfunc_userp);
584 /* no remotekey means failure! */
585 rc = CURLKHSTAT_REJECT;
588 default: /* unknown return codes will equal reject */
589 case CURLKHSTAT_REJECT:
590 state(conn, SSH_SESSION_FREE);
591 case CURLKHSTAT_DEFER:
592 /* DEFER means bail out but keep the SSH_HOSTKEY state */
593 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
595 case CURLKHSTAT_FINE:
596 case CURLKHSTAT_FINE_ADD_TO_FILE:
598 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
599 /* the found host+key didn't match but has been told to be fine
600 anyway so we add it in memory */
601 int addrc = libssh2_knownhost_add(sshc->kh,
602 conn->host.name, NULL,
604 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
605 LIBSSH2_KNOWNHOST_KEYENC_RAW|
608 infof(data, "Warning adding the known host %s failed!\n",
610 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
611 /* now we write the entire in-memory list of known hosts to the
614 libssh2_knownhost_writefile(sshc->kh,
615 data->set.str[STRING_SSH_KNOWNHOSTS],
616 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
618 infof(data, "Warning, writing %s failed!\n",
619 data->set.str[STRING_SSH_KNOWNHOSTS]);
626 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
634 * ssh_statemach_act() runs the SSH state machine as far as it can without
635 * blocking and without reaching the end. The data the pointer 'block' points
636 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
637 * meaning it wants to be called again when the socket is ready
640 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
642 CURLcode result = CURLE_OK;
643 struct SessionHandle *data = conn->data;
644 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
645 struct ssh_conn *sshc = &conn->proto.sshc;
646 curl_socket_t sock = conn->sock[FIRSTSOCKET];
647 #ifdef CURL_LIBSSH2_DEBUG
648 const char *fingerprint;
649 #endif /* CURL_LIBSSH2_DEBUG */
650 const char *host_public_key_md5;
651 char *new_readdir_line;
652 int rc = LIBSSH2_ERROR_NONE, i;
654 int seekerr = CURL_SEEKFUNC_OK;
655 *block = 0; /* we're not blocking by default */
659 switch(sshc->state) {
661 sshc->secondCreateDirs = 0;
662 sshc->nextstate = SSH_NO_STATE;
663 sshc->actualcode = CURLE_OK;
665 /* Set libssh2 to non-blocking, since everything internally is
667 libssh2_session_set_blocking(sshc->ssh_session, 0);
669 state(conn, SSH_S_STARTUP);
673 rc = libssh2_session_startup(sshc->ssh_session, sock);
674 if(rc == LIBSSH2_ERROR_EAGAIN) {
678 failf(data, "Failure establishing ssh session");
679 state(conn, SSH_SESSION_FREE);
680 sshc->actualcode = CURLE_FAILED_INIT;
684 state(conn, SSH_HOSTKEY);
689 #ifdef CURL_LIBSSH2_DEBUG
691 * Before we authenticate we should check the hostkey's fingerprint
692 * against our known hosts. How that is handled (reading from file,
693 * whatever) is up to us. As for know not much is implemented, besides
694 * showing how to get the fingerprint.
696 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
697 LIBSSH2_HOSTKEY_HASH_MD5);
699 /* The fingerprint points to static storage (!), don't free() it. */
700 infof(data, "Fingerprint: ");
701 for(rc = 0; rc < 16; rc++)
702 infof(data, "%02X ", (unsigned char) fingerprint[rc]);
704 #endif /* CURL_LIBSSH2_DEBUG */
706 /* Before we authenticate we check the hostkey's MD5 fingerprint
707 * against a known fingerprint, if available. This implementation pulls
708 * it from the curl option.
710 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
711 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
713 host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
714 LIBSSH2_HOSTKEY_HASH_MD5);
715 for(i = 0; i < 16; i++)
716 snprintf(&buf[i*2], 3, "%02x",
717 (unsigned char) host_public_key_md5[i]);
718 if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
720 "Denied establishing ssh session: mismatch md5 fingerprint. "
721 "Remote %s is not equal to %s",
722 buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
723 state(conn, SSH_SESSION_FREE);
724 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
729 result = ssh_knownhost(conn);
731 state(conn, SSH_AUTHLIST);
736 * Figure out authentication methods
737 * NB: As soon as we have provided a username to an openssh server we
738 * must never change it later. Thus, always specify the correct username
739 * here, even though the libssh2 docs kind of indicate that it should be
740 * possible to get a 'generic' list (not user-specific) of authentication
741 * methods, presumably with a blank username. That won't work in my
743 * So always specify it here.
745 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
747 (unsigned int)strlen(conn->user));
749 if(!sshc->authlist) {
750 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
751 LIBSSH2_ERROR_EAGAIN) {
752 rc = LIBSSH2_ERROR_EAGAIN;
756 state(conn, SSH_SESSION_FREE);
757 sshc->actualcode = libssh2_session_error_to_CURLE(err);
761 infof(data, "SSH authentication methods available: %s\n",
764 state(conn, SSH_AUTH_PKEY_INIT);
767 case SSH_AUTH_PKEY_INIT:
769 * Check the supported auth types in the order I feel is most secure
770 * with the requested type of authentication
772 sshc->authed = FALSE;
774 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
775 (strstr(sshc->authlist, "publickey") != NULL)) {
778 sshc->rsa_pub = sshc->rsa = NULL;
780 /* To ponder about: should really the lib be messing about with the
781 HOME environment variable etc? */
782 home = curl_getenv("HOME");
784 if(data->set.str[STRING_SSH_PUBLIC_KEY])
785 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
787 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
789 /* as a final resort, try current dir! */
790 sshc->rsa_pub = strdup("id_dsa.pub");
792 if(sshc->rsa_pub == NULL) {
795 state(conn, SSH_SESSION_FREE);
796 sshc->actualcode = CURLE_OUT_OF_MEMORY;
800 if(data->set.str[STRING_SSH_PRIVATE_KEY])
801 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
803 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
805 /* as a final resort, try current dir! */
806 sshc->rsa = strdup("id_dsa");
808 if(sshc->rsa == NULL) {
811 Curl_safefree(sshc->rsa_pub);
812 sshc->rsa_pub = NULL;
813 state(conn, SSH_SESSION_FREE);
814 sshc->actualcode = CURLE_OUT_OF_MEMORY;
818 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
819 if(!sshc->passphrase)
820 sshc->passphrase = "";
825 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
826 infof(data, "Using ssh private key file %s\n", sshc->rsa);
828 state(conn, SSH_AUTH_PKEY);
831 state(conn, SSH_AUTH_PASS_INIT);
836 /* The function below checks if the files exists, no need to stat() here.
838 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
843 sshc->rsa, sshc->passphrase);
844 if(rc == LIBSSH2_ERROR_EAGAIN) {
848 Curl_safefree(sshc->rsa_pub);
849 sshc->rsa_pub = NULL;
850 Curl_safefree(sshc->rsa);
855 infof(data, "Initialized SSH public key authentication\n");
856 state(conn, SSH_AUTH_DONE);
860 (void)libssh2_session_last_error(sshc->ssh_session,
862 infof(data, "SSH public key authentication failed: %s\n", err_msg);
863 state(conn, SSH_AUTH_PASS_INIT);
867 case SSH_AUTH_PASS_INIT:
868 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
869 (strstr(sshc->authlist, "password") != NULL)) {
870 state(conn, SSH_AUTH_PASS);
873 state(conn, SSH_AUTH_HOST_INIT);
878 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
879 (unsigned int)strlen(conn->user),
881 (unsigned int)strlen(conn->passwd),
883 if(rc == LIBSSH2_ERROR_EAGAIN) {
888 infof(data, "Initialized password authentication\n");
889 state(conn, SSH_AUTH_DONE);
892 state(conn, SSH_AUTH_HOST_INIT);
896 case SSH_AUTH_HOST_INIT:
897 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
898 (strstr(sshc->authlist, "hostbased") != NULL)) {
899 state(conn, SSH_AUTH_HOST);
902 state(conn, SSH_AUTH_KEY_INIT);
907 state(conn, SSH_AUTH_KEY_INIT);
910 case SSH_AUTH_KEY_INIT:
911 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
912 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
913 state(conn, SSH_AUTH_KEY);
916 state(conn, SSH_AUTH_DONE);
921 /* Authentication failed. Continue with keyboard-interactive now. */
922 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
927 if(rc == LIBSSH2_ERROR_EAGAIN) {
932 infof(data, "Initialized keyboard interactive authentication\n");
934 state(conn, SSH_AUTH_DONE);
939 failf(data, "Authentication failure");
940 state(conn, SSH_SESSION_FREE);
941 sshc->actualcode = CURLE_LOGIN_DENIED;
946 * At this point we have an authenticated ssh session.
948 infof(data, "Authentication complete\n");
950 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
953 conn->writesockfd = CURL_SOCKET_BAD;
955 if(conn->handler->protocol == CURLPROTO_SFTP) {
956 state(conn, SSH_SFTP_INIT);
959 infof(data, "SSH CONNECT phase done\n");
960 state(conn, SSH_STOP);
965 * Start the libssh2 sftp session
967 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
968 if(!sshc->sftp_session) {
969 if(libssh2_session_last_errno(sshc->ssh_session) ==
970 LIBSSH2_ERROR_EAGAIN) {
971 rc = LIBSSH2_ERROR_EAGAIN;
977 (void)libssh2_session_last_error(sshc->ssh_session,
979 failf(data, "Failure initializing sftp session: %s", err_msg);
980 state(conn, SSH_SESSION_FREE);
981 sshc->actualcode = CURLE_FAILED_INIT;
985 state(conn, SSH_SFTP_REALPATH);
988 case SSH_SFTP_REALPATH:
990 char tempHome[PATH_MAX];
993 * Get the "home" directory
995 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
996 tempHome, PATH_MAX-1);
997 if(rc == LIBSSH2_ERROR_EAGAIN) {
1001 /* It seems that this string is not always NULL terminated */
1002 tempHome[rc] = '\0';
1003 sshc->homedir = strdup(tempHome);
1004 if(!sshc->homedir) {
1005 state(conn, SSH_SFTP_CLOSE);
1006 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1009 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1012 /* Return the error type */
1013 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1014 result = sftp_libssh2_error_to_CURLE(err);
1015 sshc->actualcode = result?result:CURLE_SSH;
1016 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1018 state(conn, SSH_STOP);
1022 /* This is the last step in the SFTP connect phase. Do note that while
1023 we get the homedir here, we get the "workingpath" in the DO action
1024 since the homedir will remain the same between request but the
1025 working path will not. */
1026 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1027 state(conn, SSH_STOP);
1030 case SSH_SFTP_QUOTE_INIT:
1032 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1034 sshc->actualcode = result;
1035 state(conn, SSH_STOP);
1039 if(data->set.quote) {
1040 infof(data, "Sending quote commands\n");
1041 sshc->quote_item = data->set.quote;
1042 state(conn, SSH_SFTP_QUOTE);
1045 state(conn, SSH_SFTP_TRANS_INIT);
1049 case SSH_SFTP_POSTQUOTE_INIT:
1050 if(data->set.postquote) {
1051 infof(data, "Sending quote commands\n");
1052 sshc->quote_item = data->set.postquote;
1053 state(conn, SSH_SFTP_QUOTE);
1056 state(conn, SSH_STOP);
1060 case SSH_SFTP_QUOTE:
1061 /* Send any quote commands */
1066 * Support some of the "FTP" commands
1068 char *cmd = sshc->quote_item->data;
1069 sshc->acceptfail = FALSE;
1071 /* if a command starts with an asterisk, which a legal SFTP command never
1072 can, the command will be allowed to fail without it causing any
1073 aborts or cancels etc. It will cause libcurl to act as if the command
1074 is successful, whatever the server reponds. */
1078 sshc->acceptfail = TRUE;
1081 if(curl_strequal("pwd", cmd)) {
1082 /* output debug output if that is requested */
1083 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1086 result = CURLE_OUT_OF_MEMORY;
1087 state(conn, SSH_SFTP_CLOSE);
1088 sshc->nextstate = SSH_NO_STATE;
1091 if(data->set.verbose) {
1092 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1093 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1095 /* this sends an FTP-like "header" to the header callback so that the
1096 current directory can be read very similar to how it is read when
1097 using ordinary FTP. */
1098 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1100 state(conn, SSH_SFTP_NEXT_QUOTE);
1105 * the arguments following the command must be separated from the
1106 * command with a space so we can check for it unconditionally
1108 cp = strchr(cmd, ' ');
1110 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1111 state(conn, SSH_SFTP_CLOSE);
1112 sshc->nextstate = SSH_NO_STATE;
1113 sshc->actualcode = CURLE_QUOTE_ERROR;
1118 * also, every command takes at least one argument so we get that
1119 * first argument right now
1121 result = get_pathname(&cp, &sshc->quote_path1);
1123 if(result == CURLE_OUT_OF_MEMORY)
1124 failf(data, "Out of memory");
1126 failf(data, "Syntax error: Bad first parameter");
1127 state(conn, SSH_SFTP_CLOSE);
1128 sshc->nextstate = SSH_NO_STATE;
1129 sshc->actualcode = result;
1134 * SFTP is a binary protocol, so we don't send text commands to
1135 * the server. Instead, we scan for commands for commands used by
1136 * OpenSSH's sftp program and call the appropriate libssh2
1139 if(curl_strnequal(cmd, "chgrp ", 6) ||
1140 curl_strnequal(cmd, "chmod ", 6) ||
1141 curl_strnequal(cmd, "chown ", 6) ) {
1142 /* attribute change */
1144 /* sshc->quote_path1 contains the mode to set */
1145 /* get the destination */
1146 result = get_pathname(&cp, &sshc->quote_path2);
1148 if(result == CURLE_OUT_OF_MEMORY)
1149 failf(data, "Out of memory");
1151 failf(data, "Syntax error in chgrp/chmod/chown: "
1152 "Bad second parameter");
1153 Curl_safefree(sshc->quote_path1);
1154 sshc->quote_path1 = NULL;
1155 state(conn, SSH_SFTP_CLOSE);
1156 sshc->nextstate = SSH_NO_STATE;
1157 sshc->actualcode = result;
1160 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1161 state(conn, SSH_SFTP_QUOTE_STAT);
1164 else if(curl_strnequal(cmd, "ln ", 3) ||
1165 curl_strnequal(cmd, "symlink ", 8)) {
1166 /* symbolic linking */
1167 /* sshc->quote_path1 is the source */
1168 /* get the destination */
1169 result = get_pathname(&cp, &sshc->quote_path2);
1171 if(result == CURLE_OUT_OF_MEMORY)
1172 failf(data, "Out of memory");
1175 "Syntax error in ln/symlink: Bad second parameter");
1176 Curl_safefree(sshc->quote_path1);
1177 sshc->quote_path1 = NULL;
1178 state(conn, SSH_SFTP_CLOSE);
1179 sshc->nextstate = SSH_NO_STATE;
1180 sshc->actualcode = result;
1183 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1186 else if(curl_strnequal(cmd, "mkdir ", 6)) {
1188 state(conn, SSH_SFTP_QUOTE_MKDIR);
1191 else if(curl_strnequal(cmd, "rename ", 7)) {
1193 /* first param is the source path */
1194 /* second param is the dest. path */
1195 result = get_pathname(&cp, &sshc->quote_path2);
1197 if(result == CURLE_OUT_OF_MEMORY)
1198 failf(data, "Out of memory");
1200 failf(data, "Syntax error in rename: Bad second parameter");
1201 Curl_safefree(sshc->quote_path1);
1202 sshc->quote_path1 = NULL;
1203 state(conn, SSH_SFTP_CLOSE);
1204 sshc->nextstate = SSH_NO_STATE;
1205 sshc->actualcode = result;
1208 state(conn, SSH_SFTP_QUOTE_RENAME);
1211 else if(curl_strnequal(cmd, "rmdir ", 6)) {
1213 state(conn, SSH_SFTP_QUOTE_RMDIR);
1216 else if(curl_strnequal(cmd, "rm ", 3)) {
1217 state(conn, SSH_SFTP_QUOTE_UNLINK);
1221 failf(data, "Unknown SFTP command");
1222 Curl_safefree(sshc->quote_path1);
1223 sshc->quote_path1 = NULL;
1224 Curl_safefree(sshc->quote_path2);
1225 sshc->quote_path2 = NULL;
1226 state(conn, SSH_SFTP_CLOSE);
1227 sshc->nextstate = SSH_NO_STATE;
1228 sshc->actualcode = CURLE_QUOTE_ERROR;
1232 if(!sshc->quote_item) {
1233 state(conn, SSH_SFTP_TRANS_INIT);
1237 case SSH_SFTP_NEXT_QUOTE:
1238 if(sshc->quote_path1) {
1239 Curl_safefree(sshc->quote_path1);
1240 sshc->quote_path1 = NULL;
1242 if(sshc->quote_path2) {
1243 Curl_safefree(sshc->quote_path2);
1244 sshc->quote_path2 = NULL;
1247 sshc->quote_item = sshc->quote_item->next;
1249 if(sshc->quote_item) {
1250 state(conn, SSH_SFTP_QUOTE);
1253 if(sshc->nextstate != SSH_NO_STATE) {
1254 state(conn, sshc->nextstate);
1255 sshc->nextstate = SSH_NO_STATE;
1258 state(conn, SSH_SFTP_TRANS_INIT);
1263 case SSH_SFTP_QUOTE_STAT:
1265 char *cmd = sshc->quote_item->data;
1266 sshc->acceptfail = FALSE;
1268 /* if a command starts with an asterisk, which a legal SFTP command never
1269 can, the command will be allowed to fail without it causing any
1270 aborts or cancels etc. It will cause libcurl to act as if the command
1271 is successful, whatever the server reponds. */
1275 sshc->acceptfail = TRUE;
1278 if(!curl_strnequal(cmd, "chmod", 5)) {
1279 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1280 * set them both at once, we need to obtain the current ownership
1281 * first. This takes an extra protocol round trip.
1283 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1284 (unsigned int)strlen(sshc->quote_path2),
1286 &sshc->quote_attrs);
1287 if(rc == LIBSSH2_ERROR_EAGAIN) {
1290 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1291 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1292 Curl_safefree(sshc->quote_path1);
1293 sshc->quote_path1 = NULL;
1294 Curl_safefree(sshc->quote_path2);
1295 sshc->quote_path2 = NULL;
1296 failf(data, "Attempt to get SFTP stats failed: %s",
1297 sftp_libssh2_strerror(err));
1298 state(conn, SSH_SFTP_CLOSE);
1299 sshc->nextstate = SSH_NO_STATE;
1300 sshc->actualcode = CURLE_QUOTE_ERROR;
1305 /* Now set the new attributes... */
1306 if(curl_strnequal(cmd, "chgrp", 5)) {
1307 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1308 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1309 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1310 !sshc->acceptfail) {
1311 Curl_safefree(sshc->quote_path1);
1312 sshc->quote_path1 = NULL;
1313 Curl_safefree(sshc->quote_path2);
1314 sshc->quote_path2 = NULL;
1315 failf(data, "Syntax error: chgrp gid not a number");
1316 state(conn, SSH_SFTP_CLOSE);
1317 sshc->nextstate = SSH_NO_STATE;
1318 sshc->actualcode = CURLE_QUOTE_ERROR;
1322 else if(curl_strnequal(cmd, "chmod", 5)) {
1323 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1324 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1325 /* permissions are octal */
1326 if(sshc->quote_attrs.permissions == 0 &&
1327 !ISDIGIT(sshc->quote_path1[0])) {
1328 Curl_safefree(sshc->quote_path1);
1329 sshc->quote_path1 = NULL;
1330 Curl_safefree(sshc->quote_path2);
1331 sshc->quote_path2 = NULL;
1332 failf(data, "Syntax error: chmod permissions not a number");
1333 state(conn, SSH_SFTP_CLOSE);
1334 sshc->nextstate = SSH_NO_STATE;
1335 sshc->actualcode = CURLE_QUOTE_ERROR;
1339 else if(curl_strnequal(cmd, "chown", 5)) {
1340 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1341 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1342 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1343 !sshc->acceptfail) {
1344 Curl_safefree(sshc->quote_path1);
1345 sshc->quote_path1 = NULL;
1346 Curl_safefree(sshc->quote_path2);
1347 sshc->quote_path2 = NULL;
1348 failf(data, "Syntax error: chown uid not a number");
1349 state(conn, SSH_SFTP_CLOSE);
1350 sshc->nextstate = SSH_NO_STATE;
1351 sshc->actualcode = CURLE_QUOTE_ERROR;
1356 /* Now send the completed structure... */
1357 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1361 case SSH_SFTP_QUOTE_SETSTAT:
1362 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1363 (unsigned int)strlen(sshc->quote_path2),
1364 LIBSSH2_SFTP_SETSTAT,
1365 &sshc->quote_attrs);
1366 if(rc == LIBSSH2_ERROR_EAGAIN) {
1369 else if(rc != 0 && !sshc->acceptfail) {
1370 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1371 Curl_safefree(sshc->quote_path1);
1372 sshc->quote_path1 = NULL;
1373 Curl_safefree(sshc->quote_path2);
1374 sshc->quote_path2 = NULL;
1375 failf(data, "Attempt to set SFTP stats failed: %s",
1376 sftp_libssh2_strerror(err));
1377 state(conn, SSH_SFTP_CLOSE);
1378 sshc->nextstate = SSH_NO_STATE;
1379 sshc->actualcode = CURLE_QUOTE_ERROR;
1382 state(conn, SSH_SFTP_NEXT_QUOTE);
1385 case SSH_SFTP_QUOTE_SYMLINK:
1386 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1387 (unsigned int)strlen(sshc->quote_path1),
1389 (unsigned int)strlen(sshc->quote_path2),
1390 LIBSSH2_SFTP_SYMLINK);
1391 if(rc == LIBSSH2_ERROR_EAGAIN) {
1394 else if(rc != 0 && !sshc->acceptfail) {
1395 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1396 Curl_safefree(sshc->quote_path1);
1397 sshc->quote_path1 = NULL;
1398 Curl_safefree(sshc->quote_path2);
1399 sshc->quote_path2 = NULL;
1400 failf(data, "symlink command failed: %s",
1401 sftp_libssh2_strerror(err));
1402 state(conn, SSH_SFTP_CLOSE);
1403 sshc->nextstate = SSH_NO_STATE;
1404 sshc->actualcode = CURLE_QUOTE_ERROR;
1407 state(conn, SSH_SFTP_NEXT_QUOTE);
1410 case SSH_SFTP_QUOTE_MKDIR:
1411 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1412 (unsigned int)strlen(sshc->quote_path1),
1414 if(rc == LIBSSH2_ERROR_EAGAIN) {
1417 else if(rc != 0 && !sshc->acceptfail) {
1418 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1419 Curl_safefree(sshc->quote_path1);
1420 sshc->quote_path1 = NULL;
1421 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1422 state(conn, SSH_SFTP_CLOSE);
1423 sshc->nextstate = SSH_NO_STATE;
1424 sshc->actualcode = CURLE_QUOTE_ERROR;
1427 state(conn, SSH_SFTP_NEXT_QUOTE);
1430 case SSH_SFTP_QUOTE_RENAME:
1431 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1432 (unsigned int)strlen(sshc->quote_path1),
1434 (unsigned int)strlen(sshc->quote_path2),
1435 LIBSSH2_SFTP_RENAME_OVERWRITE |
1436 LIBSSH2_SFTP_RENAME_ATOMIC |
1437 LIBSSH2_SFTP_RENAME_NATIVE);
1439 if(rc == LIBSSH2_ERROR_EAGAIN) {
1442 else if(rc != 0 && !sshc->acceptfail) {
1443 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1444 Curl_safefree(sshc->quote_path1);
1445 sshc->quote_path1 = NULL;
1446 Curl_safefree(sshc->quote_path2);
1447 sshc->quote_path2 = NULL;
1448 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1449 state(conn, SSH_SFTP_CLOSE);
1450 sshc->nextstate = SSH_NO_STATE;
1451 sshc->actualcode = CURLE_QUOTE_ERROR;
1454 state(conn, SSH_SFTP_NEXT_QUOTE);
1457 case SSH_SFTP_QUOTE_RMDIR:
1458 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1459 (unsigned int)strlen(sshc->quote_path1));
1460 if(rc == LIBSSH2_ERROR_EAGAIN) {
1463 else if(rc != 0 && !sshc->acceptfail) {
1464 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1465 Curl_safefree(sshc->quote_path1);
1466 sshc->quote_path1 = NULL;
1467 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1468 state(conn, SSH_SFTP_CLOSE);
1469 sshc->nextstate = SSH_NO_STATE;
1470 sshc->actualcode = CURLE_QUOTE_ERROR;
1473 state(conn, SSH_SFTP_NEXT_QUOTE);
1476 case SSH_SFTP_QUOTE_UNLINK:
1477 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1478 (unsigned int)strlen(sshc->quote_path1));
1479 if(rc == LIBSSH2_ERROR_EAGAIN) {
1482 else if(rc != 0 && !sshc->acceptfail) {
1483 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1484 Curl_safefree(sshc->quote_path1);
1485 sshc->quote_path1 = NULL;
1486 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1487 state(conn, SSH_SFTP_CLOSE);
1488 sshc->nextstate = SSH_NO_STATE;
1489 sshc->actualcode = CURLE_QUOTE_ERROR;
1492 state(conn, SSH_SFTP_NEXT_QUOTE);
1495 case SSH_SFTP_TRANS_INIT:
1496 if(data->set.upload)
1497 state(conn, SSH_SFTP_UPLOAD_INIT);
1499 if(data->set.opt_no_body)
1500 state(conn, SSH_STOP);
1501 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1502 state(conn, SSH_SFTP_READDIR_INIT);
1504 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1508 case SSH_SFTP_UPLOAD_INIT:
1510 unsigned long flags;
1512 * NOTE!!! libssh2 requires that the destination path is a full path
1513 * that includes the destination file and name OR ends in a "/"
1514 * If this is not done the destination file will be named the
1515 * same name as the last directory in the path.
1518 if(data->state.resume_from != 0) {
1519 LIBSSH2_SFTP_ATTRIBUTES attrs;
1520 if(data->state.resume_from < 0) {
1521 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1522 (unsigned int)strlen(sftp_scp->path),
1523 LIBSSH2_SFTP_STAT, &attrs);
1524 if(rc == LIBSSH2_ERROR_EAGAIN) {
1528 data->state.resume_from = 0;
1531 curl_off_t size = attrs.filesize;
1533 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1534 return CURLE_BAD_DOWNLOAD_RESUME;
1536 data->state.resume_from = attrs.filesize;
1541 if(data->set.ftp_append)
1542 /* Try to open for append, but create if nonexisting */
1543 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1544 else if(data->state.resume_from > 0)
1545 /* If we have restart position then open for append */
1546 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1548 /* Clear file before writing (normal behaviour) */
1549 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1552 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1553 (unsigned int)strlen(sftp_scp->path),
1554 flags, data->set.new_file_perms,
1555 LIBSSH2_SFTP_OPENFILE);
1557 if(!sshc->sftp_handle) {
1558 rc = libssh2_session_last_errno(sshc->ssh_session);
1560 if(LIBSSH2_ERROR_EAGAIN == rc)
1563 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1564 /* only when there was an SFTP protocol error can we extract
1566 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1568 err = -1; /* not an sftp error at all */
1570 if(sshc->secondCreateDirs) {
1571 state(conn, SSH_SFTP_CLOSE);
1572 sshc->actualcode = err>= LIBSSH2_FX_OK?
1573 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1574 failf(data, "Creating the dir/file failed: %s",
1575 sftp_libssh2_strerror(err));
1578 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1579 (err == LIBSSH2_FX_FAILURE) ||
1580 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1581 (data->set.ftp_create_missing_dirs &&
1582 (strlen(sftp_scp->path) > 1))) {
1583 /* try to create the path remotely */
1584 sshc->secondCreateDirs = 1;
1585 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1588 state(conn, SSH_SFTP_CLOSE);
1589 sshc->actualcode = err>= LIBSSH2_FX_OK?
1590 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1591 if(!sshc->actualcode) {
1592 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1593 zero even though libssh2_sftp_open() failed previously! We need
1594 to work around that! */
1595 sshc->actualcode = CURLE_SSH;
1598 failf(data, "Upload failed: %s (%d/%d)",
1599 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1605 /* If we have restart point then we need to seek to the correct
1607 if(data->state.resume_from > 0) {
1608 /* Let's read off the proper amount of bytes from the input. */
1609 if(conn->seek_func) {
1610 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1614 if(seekerr != CURL_SEEKFUNC_OK) {
1616 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1617 failf(data, "Could not seek stream");
1618 return CURLE_FTP_COULDNT_USE_REST;
1620 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1622 curl_off_t passed=0;
1624 size_t readthisamountnow =
1625 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1626 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1628 size_t actuallyread =
1629 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1632 passed += actuallyread;
1633 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1634 /* this checks for greater-than only to make sure that the
1635 CURL_READFUNC_ABORT return code still aborts */
1636 failf(data, "Failed to read data");
1637 return CURLE_FTP_COULDNT_USE_REST;
1639 } while(passed < data->state.resume_from);
1643 /* now, decrease the size of the read */
1644 if(data->set.infilesize > 0) {
1645 data->set.infilesize -= data->state.resume_from;
1646 data->req.size = data->set.infilesize;
1647 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1650 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1652 if(data->set.infilesize > 0) {
1653 data->req.size = data->set.infilesize;
1654 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1657 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1659 /* not set by Curl_setup_transfer to preserve keepon bits */
1660 conn->sockfd = conn->writesockfd;
1663 state(conn, SSH_SFTP_CLOSE);
1664 sshc->actualcode = result;
1667 /* store this original bitmask setup to use later on if we can't
1668 figure out a "real" bitmask */
1669 sshc->orig_waitfor = data->req.keepon;
1671 /* we want to use the _sending_ function even when the socket turns
1672 out readable as the underlying libssh2 sftp send function will deal
1673 with both accordingly */
1674 conn->cselect_bits = CURL_CSELECT_OUT;
1676 /* since we don't really wait for anything at this point, we want the
1677 state machine to move on as soon as possible so we set a very short
1679 Curl_expire(data, 1);
1681 state(conn, SSH_STOP);
1686 case SSH_SFTP_CREATE_DIRS_INIT:
1687 if(strlen(sftp_scp->path) > 1) {
1688 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1689 state(conn, SSH_SFTP_CREATE_DIRS);
1692 state(conn, SSH_SFTP_UPLOAD_INIT);
1696 case SSH_SFTP_CREATE_DIRS:
1697 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1698 *sshc->slash_pos = 0;
1700 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1701 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1705 state(conn, SSH_SFTP_UPLOAD_INIT);
1709 case SSH_SFTP_CREATE_DIRS_MKDIR:
1710 /* 'mode' - parameter is preliminary - default to 0644 */
1711 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1712 (unsigned int)strlen(sftp_scp->path),
1713 data->set.new_directory_perms);
1714 if(rc == LIBSSH2_ERROR_EAGAIN) {
1717 *sshc->slash_pos = '/';
1720 unsigned int sftp_err = 0;
1722 * Abort if failure wasn't that the dir already exists or the
1723 * permission was denied (creation might succeed further down the
1724 * path) - retry on unspecific FAILURE also
1726 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1727 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1728 (sftp_err != LIBSSH2_FX_FAILURE) &&
1729 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1730 result = sftp_libssh2_error_to_CURLE(sftp_err);
1731 state(conn, SSH_SFTP_CLOSE);
1732 sshc->actualcode = result?result:CURLE_SSH;
1736 state(conn, SSH_SFTP_CREATE_DIRS);
1739 case SSH_SFTP_READDIR_INIT:
1741 * This is a directory that we are trying to get, so produce a directory
1744 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1747 strlen(sftp_scp->path),
1748 0, 0, LIBSSH2_SFTP_OPENDIR);
1749 if(!sshc->sftp_handle) {
1750 if(libssh2_session_last_errno(sshc->ssh_session) ==
1751 LIBSSH2_ERROR_EAGAIN) {
1752 rc = LIBSSH2_ERROR_EAGAIN;
1756 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1757 failf(data, "Could not open directory for reading: %s",
1758 sftp_libssh2_strerror(err));
1759 state(conn, SSH_SFTP_CLOSE);
1760 result = sftp_libssh2_error_to_CURLE(err);
1761 sshc->actualcode = result?result:CURLE_SSH;
1765 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1766 state(conn, SSH_SFTP_CLOSE);
1767 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1770 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1771 Curl_safefree(sshc->readdir_filename);
1772 sshc->readdir_filename = NULL;
1773 state(conn, SSH_SFTP_CLOSE);
1774 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1777 state(conn, SSH_SFTP_READDIR);
1780 case SSH_SFTP_READDIR:
1781 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1782 sshc->readdir_filename,
1784 sshc->readdir_longentry,
1786 &sshc->readdir_attrs);
1787 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1788 rc = LIBSSH2_ERROR_EAGAIN;
1791 if(sshc->readdir_len > 0) {
1792 sshc->readdir_filename[sshc->readdir_len] = '\0';
1794 if(data->set.ftp_list_only) {
1797 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1798 if(tmpLine == NULL) {
1799 state(conn, SSH_SFTP_CLOSE);
1800 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1803 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1804 tmpLine, sshc->readdir_len+1);
1805 Curl_safefree(tmpLine);
1808 state(conn, SSH_STOP);
1811 /* since this counts what we send to the client, we include the
1812 newline in this counter */
1813 data->req.bytecount += sshc->readdir_len+1;
1815 /* output debug output if that is requested */
1816 if(data->set.verbose) {
1817 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1818 sshc->readdir_len, conn);
1822 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1823 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1824 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1825 if(!sshc->readdir_line) {
1826 Curl_safefree(sshc->readdir_filename);
1827 sshc->readdir_filename = NULL;
1828 Curl_safefree(sshc->readdir_longentry);
1829 sshc->readdir_longentry = NULL;
1830 state(conn, SSH_SFTP_CLOSE);
1831 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1835 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1836 sshc->readdir_currLen);
1837 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1838 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1839 LIBSSH2_SFTP_S_IFLNK)) {
1840 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1841 if(sshc->readdir_linkPath == NULL) {
1842 Curl_safefree(sshc->readdir_filename);
1843 sshc->readdir_filename = NULL;
1844 Curl_safefree(sshc->readdir_longentry);
1845 sshc->readdir_longentry = NULL;
1846 state(conn, SSH_SFTP_CLOSE);
1847 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1851 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1852 sshc->readdir_filename);
1853 state(conn, SSH_SFTP_READDIR_LINK);
1856 state(conn, SSH_SFTP_READDIR_BOTTOM);
1860 else if(sshc->readdir_len == 0) {
1861 Curl_safefree(sshc->readdir_filename);
1862 sshc->readdir_filename = NULL;
1863 Curl_safefree(sshc->readdir_longentry);
1864 sshc->readdir_longentry = NULL;
1865 state(conn, SSH_SFTP_READDIR_DONE);
1868 else if(sshc->readdir_len <= 0) {
1869 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1870 result = sftp_libssh2_error_to_CURLE(err);
1871 sshc->actualcode = result?result:CURLE_SSH;
1872 failf(data, "Could not open remote file for reading: %s :: %d",
1873 sftp_libssh2_strerror(err),
1874 libssh2_session_last_errno(sshc->ssh_session));
1875 Curl_safefree(sshc->readdir_filename);
1876 sshc->readdir_filename = NULL;
1877 Curl_safefree(sshc->readdir_longentry);
1878 sshc->readdir_longentry = NULL;
1879 state(conn, SSH_SFTP_CLOSE);
1884 case SSH_SFTP_READDIR_LINK:
1886 libssh2_sftp_symlink_ex(sshc->sftp_session,
1887 sshc->readdir_linkPath,
1888 (unsigned int) strlen(sshc->readdir_linkPath),
1889 sshc->readdir_filename,
1890 PATH_MAX, LIBSSH2_SFTP_READLINK);
1891 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1892 rc = LIBSSH2_ERROR_EAGAIN;
1895 Curl_safefree(sshc->readdir_linkPath);
1896 sshc->readdir_linkPath = NULL;
1898 new_readdir_line = realloc(sshc->readdir_line,
1899 sshc->readdir_totalLen + 4 +
1901 if(!new_readdir_line) {
1902 Curl_safefree(sshc->readdir_line);
1903 sshc->readdir_line = NULL;
1904 Curl_safefree(sshc->readdir_filename);
1905 sshc->readdir_filename = NULL;
1906 Curl_safefree(sshc->readdir_longentry);
1907 sshc->readdir_longentry = NULL;
1908 state(conn, SSH_SFTP_CLOSE);
1909 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1912 sshc->readdir_line = new_readdir_line;
1914 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1915 sshc->readdir_currLen,
1916 sshc->readdir_totalLen -
1917 sshc->readdir_currLen,
1919 sshc->readdir_filename);
1921 state(conn, SSH_SFTP_READDIR_BOTTOM);
1924 case SSH_SFTP_READDIR_BOTTOM:
1925 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1926 sshc->readdir_currLen,
1927 sshc->readdir_totalLen -
1928 sshc->readdir_currLen, "\n");
1929 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1931 sshc->readdir_currLen);
1933 if(result == CURLE_OK) {
1935 /* output debug output if that is requested */
1936 if(data->set.verbose) {
1937 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1938 sshc->readdir_currLen, conn);
1940 data->req.bytecount += sshc->readdir_currLen;
1942 Curl_safefree(sshc->readdir_line);
1943 sshc->readdir_line = NULL;
1945 state(conn, SSH_STOP);
1948 state(conn, SSH_SFTP_READDIR);
1951 case SSH_SFTP_READDIR_DONE:
1952 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1953 LIBSSH2_ERROR_EAGAIN) {
1954 rc = LIBSSH2_ERROR_EAGAIN;
1957 sshc->sftp_handle = NULL;
1958 Curl_safefree(sshc->readdir_filename);
1959 sshc->readdir_filename = NULL;
1960 Curl_safefree(sshc->readdir_longentry);
1961 sshc->readdir_longentry = NULL;
1963 /* no data to transfer */
1964 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1965 state(conn, SSH_STOP);
1968 case SSH_SFTP_DOWNLOAD_INIT:
1970 * Work on getting the specified file
1973 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1974 (unsigned int)strlen(sftp_scp->path),
1975 LIBSSH2_FXF_READ, data->set.new_file_perms,
1976 LIBSSH2_SFTP_OPENFILE);
1977 if(!sshc->sftp_handle) {
1978 if(libssh2_session_last_errno(sshc->ssh_session) ==
1979 LIBSSH2_ERROR_EAGAIN) {
1980 rc = LIBSSH2_ERROR_EAGAIN;
1984 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1985 failf(data, "Could not open remote file for reading: %s",
1986 sftp_libssh2_strerror(err));
1987 state(conn, SSH_SFTP_CLOSE);
1988 result = sftp_libssh2_error_to_CURLE(err);
1989 sshc->actualcode = result?result:CURLE_SSH;
1993 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1996 case SSH_SFTP_DOWNLOAD_STAT:
1998 LIBSSH2_SFTP_ATTRIBUTES attrs;
2000 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
2001 (unsigned int)strlen(sftp_scp->path),
2002 LIBSSH2_SFTP_STAT, &attrs);
2003 if(rc == LIBSSH2_ERROR_EAGAIN) {
2008 * libssh2_sftp_open() didn't return an error, so maybe the server
2009 * just doesn't support stat()
2011 data->req.size = -1;
2012 data->req.maxdownload = -1;
2015 curl_off_t size = attrs.filesize;
2018 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
2019 return CURLE_BAD_DOWNLOAD_RESUME;
2021 if(conn->data->state.use_range) {
2022 curl_off_t from, to;
2026 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2027 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2029 to=curlx_strtoofft(ptr, &ptr2, 0);
2030 if((ptr == ptr2) /* no "to" value given */
2035 /* from is relative to end of file */
2039 failf(data, "Offset (%"
2040 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2041 from, attrs.filesize);
2042 return CURLE_BAD_DOWNLOAD_RESUME;
2049 size = to - from + 1;
2052 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2054 data->req.size = size;
2055 data->req.maxdownload = size;
2056 Curl_pgrsSetDownloadSize(data, size);
2059 /* We can resume if we can seek to the resume position */
2060 if(data->state.resume_from) {
2061 if(data->state.resume_from < 0) {
2062 /* We're supposed to download the last abs(from) bytes */
2063 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2064 failf(data, "Offset (%"
2065 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2066 data->state.resume_from, attrs.filesize);
2067 return CURLE_BAD_DOWNLOAD_RESUME;
2069 /* download from where? */
2070 data->state.resume_from += attrs.filesize;
2073 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2074 failf(data, "Offset (%" FORMAT_OFF_T
2075 ") was beyond file size (%" FORMAT_OFF_T ")",
2076 data->state.resume_from, attrs.filesize);
2077 return CURLE_BAD_DOWNLOAD_RESUME;
2080 /* Does a completed file need to be seeked and started or closed ? */
2081 /* Now store the number of bytes we are expected to download */
2082 data->req.size = attrs.filesize - data->state.resume_from;
2083 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2084 Curl_pgrsSetDownloadSize(data,
2085 attrs.filesize - data->state.resume_from);
2086 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2089 /* Setup the actual download */
2090 if(data->req.size == 0) {
2091 /* no data to transfer */
2092 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2093 infof(data, "File already completely downloaded\n");
2094 state(conn, SSH_STOP);
2098 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2099 FALSE, NULL, -1, NULL);
2101 /* not set by Curl_setup_transfer to preserve keepon bits */
2102 conn->writesockfd = conn->sockfd;
2104 /* we want to use the _receiving_ function even when the socket turns
2105 out writableable as the underlying libssh2 recv function will deal
2106 with both accordingly */
2107 conn->cselect_bits = CURL_CSELECT_IN;
2110 state(conn, SSH_SFTP_CLOSE);
2111 sshc->actualcode = result;
2114 state(conn, SSH_STOP);
2118 case SSH_SFTP_CLOSE:
2119 if(sshc->sftp_handle) {
2120 rc = libssh2_sftp_close(sshc->sftp_handle);
2121 if(rc == LIBSSH2_ERROR_EAGAIN) {
2125 infof(data, "Failed to close libssh2 file\n");
2127 sshc->sftp_handle = NULL;
2130 Curl_safefree(sftp_scp->path);
2131 sftp_scp->path = NULL;
2134 DEBUGF(infof(data, "SFTP DONE done\n"));
2136 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2137 After nextstate is executed,the control should come back to
2138 SSH_SFTP_CLOSE to pass the correct result back */
2139 if(sshc->nextstate != SSH_NO_STATE) {
2140 state(conn, sshc->nextstate);
2141 sshc->nextstate = SSH_SFTP_CLOSE;
2144 state(conn, SSH_STOP);
2145 result = sshc->actualcode;
2149 case SSH_SFTP_SHUTDOWN:
2150 /* during times we get here due to a broken transfer and then the
2151 sftp_handle might not have been taken down so make sure that is done
2152 before we proceed */
2154 if(sshc->sftp_handle) {
2155 rc = libssh2_sftp_close(sshc->sftp_handle);
2156 if(rc == LIBSSH2_ERROR_EAGAIN) {
2160 infof(data, "Failed to close libssh2 file\n");
2162 sshc->sftp_handle = NULL;
2164 if(sshc->sftp_session) {
2165 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2166 if(rc == LIBSSH2_ERROR_EAGAIN) {
2170 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2172 sshc->sftp_session = NULL;
2175 Curl_safefree(sshc->homedir);
2176 sshc->homedir = NULL;
2177 conn->data->state.most_recent_ftp_entrypath = NULL;
2179 state(conn, SSH_SESSION_DISCONNECT);
2182 case SSH_SCP_TRANS_INIT:
2183 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2185 sshc->actualcode = result;
2186 state(conn, SSH_STOP);
2190 if(data->set.upload) {
2191 if(data->set.infilesize < 0) {
2192 failf(data, "SCP requires a known file size for upload");
2193 sshc->actualcode = CURLE_UPLOAD_FAILED;
2194 state(conn, SSH_SCP_CHANNEL_FREE);
2197 state(conn, SSH_SCP_UPLOAD_INIT);
2200 state(conn, SSH_SCP_DOWNLOAD_INIT);
2204 case SSH_SCP_UPLOAD_INIT:
2206 * libssh2 requires that the destination path is a full path that
2207 * includes the destination file and name OR ends in a "/" . If this is
2208 * not done the destination file will be named the same name as the last
2209 * directory in the path.
2212 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2213 data->set.infilesize);
2214 if(!sshc->ssh_channel) {
2215 if(libssh2_session_last_errno(sshc->ssh_session) ==
2216 LIBSSH2_ERROR_EAGAIN) {
2217 rc = LIBSSH2_ERROR_EAGAIN;
2224 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2225 &err_msg, NULL, 0));
2226 failf(conn->data, "%s", err_msg);
2227 state(conn, SSH_SCP_CHANNEL_FREE);
2228 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2234 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2237 /* not set by Curl_setup_transfer to preserve keepon bits */
2238 conn->sockfd = conn->writesockfd;
2241 state(conn, SSH_SCP_CHANNEL_FREE);
2242 sshc->actualcode = result;
2245 /* we want to use the _sending_ function even when the socket turns
2246 out readable as the underlying libssh2 scp send function will deal
2247 with both accordingly */
2248 conn->cselect_bits = CURL_CSELECT_OUT;
2250 state(conn, SSH_STOP);
2254 case SSH_SCP_DOWNLOAD_INIT:
2257 * We must check the remote file; if it is a directory no values will
2261 curl_off_t bytecount;
2263 /* clear the struct scp recv will fill in */
2264 memset(&sb, 0, sizeof(struct stat));
2266 /* get a fresh new channel from the ssh layer */
2267 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2268 sftp_scp->path, &sb);
2269 if(!sshc->ssh_channel) {
2270 if(libssh2_session_last_errno(sshc->ssh_session) ==
2271 LIBSSH2_ERROR_EAGAIN) {
2272 rc = LIBSSH2_ERROR_EAGAIN;
2279 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2280 &err_msg, NULL, 0));
2281 failf(conn->data, "%s", err_msg);
2282 state(conn, SSH_SCP_CHANNEL_FREE);
2283 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2289 bytecount = (curl_off_t)sb.st_size;
2290 data->req.maxdownload = (curl_off_t)sb.st_size;
2291 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2293 /* not set by Curl_setup_transfer to preserve keepon bits */
2294 conn->writesockfd = conn->sockfd;
2296 /* we want to use the _receiving_ function even when the socket turns
2297 out writableable as the underlying libssh2 recv function will deal
2298 with both accordingly */
2299 conn->cselect_bits = CURL_CSELECT_IN;
2302 state(conn, SSH_SCP_CHANNEL_FREE);
2303 sshc->actualcode = result;
2306 state(conn, SSH_STOP);
2311 if(data->set.upload)
2312 state(conn, SSH_SCP_SEND_EOF);
2314 state(conn, SSH_SCP_CHANNEL_FREE);
2317 case SSH_SCP_SEND_EOF:
2318 if(sshc->ssh_channel) {
2319 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2320 if(rc == LIBSSH2_ERROR_EAGAIN) {
2324 infof(data, "Failed to send libssh2 channel EOF\n");
2327 state(conn, SSH_SCP_WAIT_EOF);
2330 case SSH_SCP_WAIT_EOF:
2331 if(sshc->ssh_channel) {
2332 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2333 if(rc == LIBSSH2_ERROR_EAGAIN) {
2337 infof(data, "Failed to get channel EOF: %d\n", rc);
2340 state(conn, SSH_SCP_WAIT_CLOSE);
2343 case SSH_SCP_WAIT_CLOSE:
2344 if(sshc->ssh_channel) {
2345 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2346 if(rc == LIBSSH2_ERROR_EAGAIN) {
2350 infof(data, "Channel failed to close: %d\n", rc);
2353 state(conn, SSH_SCP_CHANNEL_FREE);
2356 case SSH_SCP_CHANNEL_FREE:
2357 if(sshc->ssh_channel) {
2358 rc = libssh2_channel_free(sshc->ssh_channel);
2359 if(rc == LIBSSH2_ERROR_EAGAIN) {
2363 infof(data, "Failed to free libssh2 scp subsystem\n");
2365 sshc->ssh_channel = NULL;
2367 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2369 state(conn, SSH_SESSION_DISCONNECT);
2371 state(conn, SSH_STOP);
2372 result = sshc->actualcode;
2375 case SSH_SESSION_DISCONNECT:
2376 /* during weird times when we've been prematurely aborted, the channel
2377 is still alive when we reach this state and we MUST kill the channel
2379 if(sshc->ssh_channel) {
2380 rc = libssh2_channel_free(sshc->ssh_channel);
2381 if(rc == LIBSSH2_ERROR_EAGAIN) {
2385 infof(data, "Failed to free libssh2 scp subsystem\n");
2387 sshc->ssh_channel = NULL;
2390 if(sshc->ssh_session) {
2391 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2392 if(rc == LIBSSH2_ERROR_EAGAIN) {
2396 infof(data, "Failed to disconnect libssh2 session\n");
2400 Curl_safefree(sshc->homedir);
2401 sshc->homedir = NULL;
2402 conn->data->state.most_recent_ftp_entrypath = NULL;
2404 state(conn, SSH_SESSION_FREE);
2407 case SSH_SESSION_FREE:
2408 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2410 libssh2_knownhost_free(sshc->kh);
2415 if(sshc->ssh_session) {
2416 rc = libssh2_session_free(sshc->ssh_session);
2417 if(rc == LIBSSH2_ERROR_EAGAIN) {
2421 infof(data, "Failed to free libssh2 session\n");
2423 sshc->ssh_session = NULL;
2426 /* worst-case scenario cleanup */
2428 DEBUGASSERT(sshc->ssh_session == NULL);
2429 DEBUGASSERT(sshc->ssh_channel == NULL);
2430 DEBUGASSERT(sshc->sftp_session == NULL);
2431 DEBUGASSERT(sshc->sftp_handle == NULL);
2432 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2433 DEBUGASSERT(sshc->kh == NULL);
2436 Curl_safefree(sshc->rsa_pub);
2437 Curl_safefree(sshc->rsa);
2439 Curl_safefree(sshc->quote_path1);
2440 Curl_safefree(sshc->quote_path2);
2442 Curl_safefree(sshc->homedir);
2444 Curl_safefree(sshc->readdir_filename);
2445 Curl_safefree(sshc->readdir_longentry);
2446 Curl_safefree(sshc->readdir_line);
2447 Curl_safefree(sshc->readdir_linkPath);
2449 /* the code we are about to return */
2450 result = sshc->actualcode;
2452 memset(sshc, 0, sizeof(struct ssh_conn));
2454 conn->bits.close = TRUE;
2455 sshc->state = SSH_SESSION_FREE; /* current */
2456 sshc->nextstate = SSH_NO_STATE;
2457 state(conn, SSH_STOP);
2461 /* fallthrough, just stop! */
2463 /* internal error */
2464 sshc->nextstate = SSH_NO_STATE;
2465 state(conn, SSH_STOP);
2469 } while(!rc && (sshc->state != SSH_STOP));
2471 if(rc == LIBSSH2_ERROR_EAGAIN) {
2472 /* we would block, we need to wait for the socket to be ready (in the
2473 right direction too)! */
2480 /* called by the multi interface to figure out what socket(s) to wait for and
2481 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2482 static int ssh_perform_getsock(const struct connectdata *conn,
2483 curl_socket_t *sock, /* points to numsocks
2484 number of sockets */
2487 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2488 int bitmap = GETSOCK_BLANK;
2491 sock[0] = conn->sock[FIRSTSOCKET];
2493 if(conn->waitfor & KEEP_RECV)
2494 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2496 if(conn->waitfor & KEEP_SEND)
2497 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2501 /* if we don't know the direction we can use the generic *_getsock()
2502 function even for the protocol_connect and doing states */
2503 return Curl_single_getsock(conn, sock, numsocks);
2507 /* Generic function called by the multi interface to figure out what socket(s)
2508 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2509 static int ssh_getsock(struct connectdata *conn,
2510 curl_socket_t *sock, /* points to numsocks number
2514 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2518 /* if we don't know any direction we can just play along as we used to and
2519 not provide any sensible info */
2520 return GETSOCK_BLANK;
2522 /* if we know the direction we can use the generic *_getsock() function even
2523 for the protocol_connect and doing states */
2524 return ssh_perform_getsock(conn, sock, numsocks);
2528 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2530 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2531 * function is used to figure out in what direction and stores this info so
2532 * that the multi interface can take advantage of it. Make sure to call this
2533 * function in all cases so that when it _doesn't_ return EAGAIN we can
2534 * restore the default wait bits.
2536 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2538 struct ssh_conn *sshc = &conn->proto.sshc;
2542 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2543 /* translate the libssh2 define bits into our own bit defines */
2544 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2545 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2548 /* It didn't block or libssh2 didn't reveal in which direction, put back
2550 conn->waitfor = sshc->orig_waitfor;
2553 /* no libssh2 directional support so we simply don't know */
2554 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2557 /* called repeatedly until done from multi.c */
2558 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2560 struct ssh_conn *sshc = &conn->proto.sshc;
2561 CURLcode result = CURLE_OK;
2562 bool block; /* we store the status and use that to provide a ssh_getsock()
2565 result = ssh_statemach_act(conn, &block);
2566 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2567 ssh_block2waitfor(conn, block);
2572 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2575 struct ssh_conn *sshc = &conn->proto.sshc;
2576 CURLcode result = CURLE_OK;
2577 struct SessionHandle *data = conn->data;
2579 while((sshc->state != SSH_STOP) && !result) {
2583 result = ssh_statemach_act(conn, &block);
2587 if(Curl_pgrsUpdate(conn))
2588 return CURLE_ABORTED_BY_CALLBACK;
2590 struct timeval now = Curl_tvnow();
2591 result = Curl_speedcheck(data, now);
2596 left = Curl_timeleft(data, NULL, duringconnect);
2598 failf(data, "Operation timed out\n");
2599 return CURLE_OPERATION_TIMEDOUT;
2602 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2603 if((CURLE_OK == result) && block) {
2604 int dir = libssh2_session_block_directions(sshc->ssh_session);
2605 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2606 curl_socket_t fd_read = CURL_SOCKET_BAD;
2607 curl_socket_t fd_write = CURL_SOCKET_BAD;
2608 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2610 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2612 /* wait for the socket to become ready */
2613 Curl_socket_ready(fd_read, fd_write,
2614 left>1000?1000:left); /* ignore result */
2624 * SSH setup and connection
2626 static CURLcode ssh_init(struct connectdata *conn)
2628 struct SessionHandle *data = conn->data;
2629 struct SSHPROTO *ssh;
2630 struct ssh_conn *sshc = &conn->proto.sshc;
2632 sshc->actualcode = CURLE_OK; /* reset error code */
2633 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2636 if(data->state.proto.ssh)
2639 ssh = calloc(1, sizeof(struct SSHPROTO));
2641 return CURLE_OUT_OF_MEMORY;
2643 data->state.proto.ssh = ssh;
2648 static Curl_recv scp_recv, sftp_recv;
2649 static Curl_send scp_send, sftp_send;
2652 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2653 * do protocol-specific actions at connect-time.
2655 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2657 #ifdef CURL_LIBSSH2_DEBUG
2660 struct ssh_conn *ssh;
2662 struct SessionHandle *data = conn->data;
2664 /* We default to persistent connections. We set this already in this connect
2665 function to make the re-use checks properly be able to check this bit. */
2666 conn->bits.close = FALSE;
2668 /* If there already is a protocol-specific struct allocated for this
2669 sessionhandle, deal with it */
2670 Curl_reset_reqproto(conn);
2672 result = ssh_init(conn);
2676 if(conn->handler->protocol & CURLPROTO_SCP) {
2677 conn->recv[FIRSTSOCKET] = scp_recv;
2678 conn->send[FIRSTSOCKET] = scp_send;
2681 conn->recv[FIRSTSOCKET] = sftp_recv;
2682 conn->send[FIRSTSOCKET] = sftp_send;
2684 ssh = &conn->proto.sshc;
2686 #ifdef CURL_LIBSSH2_DEBUG
2688 infof(data, "User: %s\n", conn->user);
2691 infof(data, "Password: %s\n", conn->passwd);
2693 sock = conn->sock[FIRSTSOCKET];
2694 #endif /* CURL_LIBSSH2_DEBUG */
2696 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2698 my_libssh2_realloc, conn);
2699 if(ssh->ssh_session == NULL) {
2700 failf(data, "Failure initialising ssh session");
2701 return CURLE_FAILED_INIT;
2704 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2705 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2707 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2709 /* eeek. TODO: free the ssh_session! */
2710 return CURLE_FAILED_INIT;
2713 /* read all known hosts from there */
2714 rc = libssh2_knownhost_readfile(ssh->kh,
2715 data->set.str[STRING_SSH_KNOWNHOSTS],
2716 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2718 infof(data, "Failed to read known hosts from %s\n",
2719 data->set.str[STRING_SSH_KNOWNHOSTS]);
2721 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2723 #ifdef CURL_LIBSSH2_DEBUG
2724 libssh2_trace(ssh->ssh_session, ~0);
2725 infof(data, "SSH socket: %d\n", (int)sock);
2726 #endif /* CURL_LIBSSH2_DEBUG */
2728 state(conn, SSH_INIT);
2730 if(data->state.used_interface == Curl_if_multi)
2731 result = ssh_multi_statemach(conn, done);
2733 result = ssh_easy_statemach(conn, TRUE);
2742 ***********************************************************************
2746 * This is the actual DO function for SCP. Get a file according to
2747 * the options previously setup.
2751 CURLcode scp_perform(struct connectdata *conn,
2755 CURLcode result = CURLE_OK;
2757 DEBUGF(infof(conn->data, "DO phase starts\n"));
2759 *dophase_done = FALSE; /* not done yet */
2761 /* start the first command in the DO phase */
2762 state(conn, SSH_SCP_TRANS_INIT);
2764 /* run the state-machine */
2765 if(conn->data->state.used_interface == Curl_if_multi) {
2766 result = ssh_multi_statemach(conn, dophase_done);
2769 result = ssh_easy_statemach(conn, FALSE);
2770 *dophase_done = TRUE; /* with the easy interface we are done here */
2772 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2775 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2781 /* called from multi.c while DOing */
2782 static CURLcode scp_doing(struct connectdata *conn,
2786 result = ssh_multi_statemach(conn, dophase_done);
2789 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2795 * The DO function is generic for both protocols. There was previously two
2796 * separate ones but this way means less duplicated code.
2799 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2803 struct SessionHandle *data = conn->data;
2805 *done = FALSE; /* default to false */
2808 Since connections can be re-used between SessionHandles, this might be a
2809 connection already existing but on a fresh SessionHandle struct so we must
2810 make sure we have a good 'struct SSHPROTO' to play with. For new
2811 connections, the struct SSHPROTO is allocated and setup in the
2812 ssh_connect() function.
2814 Curl_reset_reqproto(conn);
2815 res = ssh_init(conn);
2819 data->req.size = -1; /* make sure this is unknown at this point */
2821 Curl_pgrsSetUploadCounter(data, 0);
2822 Curl_pgrsSetDownloadCounter(data, 0);
2823 Curl_pgrsSetUploadSize(data, 0);
2824 Curl_pgrsSetDownloadSize(data, 0);
2826 if(conn->handler->protocol & CURLPROTO_SCP)
2827 res = scp_perform(conn, &connected, done);
2829 res = sftp_perform(conn, &connected, done);
2834 /* BLOCKING, but the function is using the state machine so the only reason
2835 this is still blocking is that the multi interface code has no support for
2836 disconnecting operations that takes a while */
2837 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2839 CURLcode result = CURLE_OK;
2840 struct ssh_conn *ssh = &conn->proto.sshc;
2841 (void) dead_connection;
2843 Curl_safefree(conn->data->state.proto.ssh);
2844 conn->data->state.proto.ssh = NULL;
2846 if(ssh->ssh_session) {
2847 /* only if there's a session still around to use! */
2849 state(conn, SSH_SESSION_DISCONNECT);
2851 result = ssh_easy_statemach(conn, FALSE);
2857 /* generic done function for both SCP and SFTP called from their specific
2859 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2861 CURLcode result = CURLE_OK;
2862 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2864 if(status == CURLE_OK) {
2865 /* run the state-machine
2867 TODO: when the multi interface is used, this _really_ should be using
2868 the ssh_multi_statemach function but we have no general support for
2869 non-blocking DONE operations, not in the multi state machine and with
2870 Curl_done() invokes on several places in the code!
2872 result = ssh_easy_statemach(conn, FALSE);
2878 Curl_safefree(sftp_scp->path);
2879 sftp_scp->path = NULL;
2881 Curl_pgrsDone(conn);
2883 conn->data->req.keepon = 0; /* clear all bits */
2888 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2891 (void)premature; /* not used */
2893 if(status == CURLE_OK)
2894 state(conn, SSH_SCP_DONE);
2896 return ssh_done(conn, status);
2900 /* return number of received (decrypted) bytes */
2901 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2902 const void *mem, size_t len, CURLcode *err)
2905 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2907 /* libssh2_channel_write() returns int! */
2909 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2911 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2913 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2922 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2923 * a regular CURLcode value.
2925 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2926 char *mem, size_t len, CURLcode *err)
2929 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2931 /* libssh2_channel_read() returns int */
2933 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2935 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2936 if(nread == LIBSSH2_ERROR_EAGAIN) {
2945 * =============== SFTP ===============
2949 ***********************************************************************
2953 * This is the actual DO function for SFTP. Get a file/directory according to
2954 * the options previously setup.
2958 CURLcode sftp_perform(struct connectdata *conn,
2962 CURLcode result = CURLE_OK;
2964 DEBUGF(infof(conn->data, "DO phase starts\n"));
2966 *dophase_done = FALSE; /* not done yet */
2968 /* start the first command in the DO phase */
2969 state(conn, SSH_SFTP_QUOTE_INIT);
2971 /* run the state-machine */
2972 if(conn->data->state.used_interface == Curl_if_multi) {
2973 result = ssh_multi_statemach(conn, dophase_done);
2976 result = ssh_easy_statemach(conn, FALSE);
2977 *dophase_done = TRUE; /* with the easy interface we are done here */
2979 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2982 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2988 /* called from multi.c while DOing */
2989 static CURLcode sftp_doing(struct connectdata *conn,
2993 result = ssh_multi_statemach(conn, dophase_done);
2996 DEBUGF(infof(conn->data, "DO phase is complete\n"));
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 sftp_disconnect(struct connectdata *conn, bool dead_connection)
3006 CURLcode result = CURLE_OK;
3007 (void) dead_connection;
3009 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3011 Curl_safefree(conn->data->state.proto.ssh);
3012 conn->data->state.proto.ssh = NULL;
3014 if(conn->proto.sshc.ssh_session) {
3015 /* only if there's a session still around to use! */
3016 state(conn, SSH_SFTP_SHUTDOWN);
3017 result = ssh_easy_statemach(conn, FALSE);
3020 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3026 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3029 struct ssh_conn *sshc = &conn->proto.sshc;
3031 if(status == CURLE_OK) {
3032 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3033 errors that could happen due to open file handles during POSTQUOTE
3035 if(!status && !premature && conn->data->set.postquote) {
3036 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3037 state(conn, SSH_SFTP_CLOSE);
3040 state(conn, SSH_SFTP_CLOSE);
3042 return ssh_done(conn, status);
3045 /* return number of sent bytes */
3046 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3047 const void *mem, size_t len, CURLcode *err)
3049 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3050 but is changed to ssize_t in 0.15. These days we don't
3051 support libssh2 0.15*/
3054 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3056 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3058 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3067 * Return number of received (decrypted) bytes
3069 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3070 char *mem, size_t len, CURLcode *err)
3075 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3077 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3079 if(nread == LIBSSH2_ERROR_EAGAIN) {
3086 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3089 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3091 * Permission to use, copy, modify, and distribute this software for any
3092 * purpose with or without fee is hereby granted, provided that the above
3093 * copyright notice and this permission notice appear in all copies.
3095 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3096 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3097 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3098 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3099 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3100 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3101 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3104 get_pathname(const char **cpp, char **path)
3106 const char *cp = *cpp, *end;
3109 static const char WHITESPACE[] = " \t\r\n";
3111 cp += strspn(cp, WHITESPACE);
3115 return CURLE_QUOTE_ERROR;
3118 *path = malloc(strlen(cp) + 1);
3120 return CURLE_OUT_OF_MEMORY;
3122 /* Check for quoted filenames */
3123 if(*cp == '\"' || *cp == '\'') {
3126 /* Search for terminating quote, unescape some chars */
3127 for(i = j = 0; i <= strlen(cp); i++) {
3128 if(cp[i] == quot) { /* Found quote */
3133 if(cp[i] == '\0') { /* End of string */
3134 /*error("Unterminated quote");*/
3137 if(cp[i] == '\\') { /* Escaped characters */
3139 if(cp[i] != '\'' && cp[i] != '\"' &&
3141 /*error("Bad escaped character '\\%c'",
3146 (*path)[j++] = cp[i];
3150 /*error("Empty quotes");*/
3153 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3156 /* Read to end of filename */
3157 end = strpbrk(cp, WHITESPACE);
3159 end = strchr(cp, '\0');
3160 *cpp = end + strspn(end, WHITESPACE);
3162 memcpy(*path, cp, end - cp);
3163 (*path)[end - cp] = '\0';
3168 Curl_safefree(*path);
3170 return CURLE_QUOTE_ERROR;
3174 static const char *sftp_libssh2_strerror(unsigned long err)
3177 case LIBSSH2_FX_NO_SUCH_FILE:
3178 return "No such file or directory";
3180 case LIBSSH2_FX_PERMISSION_DENIED:
3181 return "Permission denied";
3183 case LIBSSH2_FX_FAILURE:
3184 return "Operation failed";
3186 case LIBSSH2_FX_BAD_MESSAGE:
3187 return "Bad message from SFTP server";
3189 case LIBSSH2_FX_NO_CONNECTION:
3190 return "Not connected to SFTP server";
3192 case LIBSSH2_FX_CONNECTION_LOST:
3193 return "Connection to SFTP server lost";
3195 case LIBSSH2_FX_OP_UNSUPPORTED:
3196 return "Operation not supported by SFTP server";
3198 case LIBSSH2_FX_INVALID_HANDLE:
3199 return "Invalid handle";
3201 case LIBSSH2_FX_NO_SUCH_PATH:
3202 return "No such file or directory";
3204 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3205 return "File already exists";
3207 case LIBSSH2_FX_WRITE_PROTECT:
3208 return "File is write protected";
3210 case LIBSSH2_FX_NO_MEDIA:
3213 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3216 case LIBSSH2_FX_QUOTA_EXCEEDED:
3217 return "User quota exceeded";
3219 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3220 return "Unknown principle";
3222 case LIBSSH2_FX_LOCK_CONFlICT:
3223 return "File lock conflict";
3225 case LIBSSH2_FX_DIR_NOT_EMPTY:
3226 return "Directory not empty";
3228 case LIBSSH2_FX_NOT_A_DIRECTORY:
3229 return "Not a directory";
3231 case LIBSSH2_FX_INVALID_FILENAME:
3232 return "Invalid filename";
3234 case LIBSSH2_FX_LINK_LOOP:
3235 return "Link points to itself";
3237 return "Unknown error in libssh2";
3240 #endif /* USE_LIBSSH2 */