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 const char *fingerprint;
649 char *new_readdir_line;
650 int rc = LIBSSH2_ERROR_NONE, i;
652 int seekerr = CURL_SEEKFUNC_OK;
653 *block = 0; /* we're not blocking by default */
657 switch(sshc->state) {
659 sshc->secondCreateDirs = 0;
660 sshc->nextstate = SSH_NO_STATE;
661 sshc->actualcode = CURLE_OK;
663 /* Set libssh2 to non-blocking, since everything internally is
665 libssh2_session_set_blocking(sshc->ssh_session, 0);
667 state(conn, SSH_S_STARTUP);
671 rc = libssh2_session_startup(sshc->ssh_session, sock);
672 if(rc == LIBSSH2_ERROR_EAGAIN) {
676 failf(data, "Failure establishing ssh session");
677 state(conn, SSH_SESSION_FREE);
678 sshc->actualcode = CURLE_FAILED_INIT;
682 state(conn, SSH_HOSTKEY);
687 * Before we authenticate we should check the hostkey's fingerprint
688 * against our known hosts. How that is handled (reading from file,
689 * whatever) is up to us.
691 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
692 LIBSSH2_HOSTKEY_HASH_MD5);
694 /* The fingerprint points to static storage (!), don't free() it. */
695 for(i = 0; i < 16; i++)
696 snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
697 infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
699 /* Before we authenticate we check the hostkey's MD5 fingerprint
700 * against a known fingerprint, if available.
702 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
703 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
704 if(!strequal(md5buffer,
705 data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
707 "Denied establishing ssh session: mismatch md5 fingerprint. "
708 "Remote %s is not equal to %s",
709 md5buffer, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
710 state(conn, SSH_SESSION_FREE);
711 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
714 infof(data, "MD5 checksum match!\n");
715 /* as we already matched, we skip the check for known hosts */
718 result = ssh_knownhost(conn);
721 state(conn, SSH_AUTHLIST);
726 * Figure out authentication methods
727 * NB: As soon as we have provided a username to an openssh server we
728 * must never change it later. Thus, always specify the correct username
729 * here, even though the libssh2 docs kind of indicate that it should be
730 * possible to get a 'generic' list (not user-specific) of authentication
731 * methods, presumably with a blank username. That won't work in my
733 * So always specify it here.
735 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
737 (unsigned int)strlen(conn->user));
739 if(!sshc->authlist) {
740 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
741 LIBSSH2_ERROR_EAGAIN) {
742 rc = LIBSSH2_ERROR_EAGAIN;
746 state(conn, SSH_SESSION_FREE);
747 sshc->actualcode = libssh2_session_error_to_CURLE(err);
751 infof(data, "SSH authentication methods available: %s\n",
754 state(conn, SSH_AUTH_PKEY_INIT);
757 case SSH_AUTH_PKEY_INIT:
759 * Check the supported auth types in the order I feel is most secure
760 * with the requested type of authentication
762 sshc->authed = FALSE;
764 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
765 (strstr(sshc->authlist, "publickey") != NULL)) {
768 sshc->rsa_pub = sshc->rsa = NULL;
770 /* To ponder about: should really the lib be messing about with the
771 HOME environment variable etc? */
772 home = curl_getenv("HOME");
774 if(data->set.str[STRING_SSH_PUBLIC_KEY])
775 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
777 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
779 /* as a final resort, try current dir! */
780 sshc->rsa_pub = strdup("id_dsa.pub");
782 if(sshc->rsa_pub == NULL) {
785 state(conn, SSH_SESSION_FREE);
786 sshc->actualcode = CURLE_OUT_OF_MEMORY;
790 if(data->set.str[STRING_SSH_PRIVATE_KEY])
791 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
793 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
795 /* as a final resort, try current dir! */
796 sshc->rsa = strdup("id_dsa");
798 if(sshc->rsa == NULL) {
801 Curl_safefree(sshc->rsa_pub);
802 sshc->rsa_pub = NULL;
803 state(conn, SSH_SESSION_FREE);
804 sshc->actualcode = CURLE_OUT_OF_MEMORY;
808 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
809 if(!sshc->passphrase)
810 sshc->passphrase = "";
815 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
816 infof(data, "Using ssh private key file %s\n", sshc->rsa);
818 state(conn, SSH_AUTH_PKEY);
821 state(conn, SSH_AUTH_PASS_INIT);
826 /* The function below checks if the files exists, no need to stat() here.
828 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
833 sshc->rsa, sshc->passphrase);
834 if(rc == LIBSSH2_ERROR_EAGAIN) {
838 Curl_safefree(sshc->rsa_pub);
839 sshc->rsa_pub = NULL;
840 Curl_safefree(sshc->rsa);
845 infof(data, "Initialized SSH public key authentication\n");
846 state(conn, SSH_AUTH_DONE);
850 (void)libssh2_session_last_error(sshc->ssh_session,
852 infof(data, "SSH public key authentication failed: %s\n", err_msg);
853 state(conn, SSH_AUTH_PASS_INIT);
857 case SSH_AUTH_PASS_INIT:
858 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
859 (strstr(sshc->authlist, "password") != NULL)) {
860 state(conn, SSH_AUTH_PASS);
863 state(conn, SSH_AUTH_HOST_INIT);
868 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
869 (unsigned int)strlen(conn->user),
871 (unsigned int)strlen(conn->passwd),
873 if(rc == LIBSSH2_ERROR_EAGAIN) {
878 infof(data, "Initialized password authentication\n");
879 state(conn, SSH_AUTH_DONE);
882 state(conn, SSH_AUTH_HOST_INIT);
886 case SSH_AUTH_HOST_INIT:
887 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
888 (strstr(sshc->authlist, "hostbased") != NULL)) {
889 state(conn, SSH_AUTH_HOST);
892 state(conn, SSH_AUTH_KEY_INIT);
897 state(conn, SSH_AUTH_KEY_INIT);
900 case SSH_AUTH_KEY_INIT:
901 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
902 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
903 state(conn, SSH_AUTH_KEY);
906 state(conn, SSH_AUTH_DONE);
911 /* Authentication failed. Continue with keyboard-interactive now. */
912 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
917 if(rc == LIBSSH2_ERROR_EAGAIN) {
922 infof(data, "Initialized keyboard interactive authentication\n");
924 state(conn, SSH_AUTH_DONE);
929 failf(data, "Authentication failure");
930 state(conn, SSH_SESSION_FREE);
931 sshc->actualcode = CURLE_LOGIN_DENIED;
936 * At this point we have an authenticated ssh session.
938 infof(data, "Authentication complete\n");
940 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
943 conn->writesockfd = CURL_SOCKET_BAD;
945 if(conn->handler->protocol == CURLPROTO_SFTP) {
946 state(conn, SSH_SFTP_INIT);
949 infof(data, "SSH CONNECT phase done\n");
950 state(conn, SSH_STOP);
955 * Start the libssh2 sftp session
957 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
958 if(!sshc->sftp_session) {
959 if(libssh2_session_last_errno(sshc->ssh_session) ==
960 LIBSSH2_ERROR_EAGAIN) {
961 rc = LIBSSH2_ERROR_EAGAIN;
967 (void)libssh2_session_last_error(sshc->ssh_session,
969 failf(data, "Failure initializing sftp session: %s", err_msg);
970 state(conn, SSH_SESSION_FREE);
971 sshc->actualcode = CURLE_FAILED_INIT;
975 state(conn, SSH_SFTP_REALPATH);
978 case SSH_SFTP_REALPATH:
980 char tempHome[PATH_MAX];
983 * Get the "home" directory
985 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
986 tempHome, PATH_MAX-1);
987 if(rc == LIBSSH2_ERROR_EAGAIN) {
991 /* It seems that this string is not always NULL terminated */
993 sshc->homedir = strdup(tempHome);
995 state(conn, SSH_SFTP_CLOSE);
996 sshc->actualcode = CURLE_OUT_OF_MEMORY;
999 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1002 /* Return the error type */
1003 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1004 result = sftp_libssh2_error_to_CURLE(err);
1005 sshc->actualcode = result?result:CURLE_SSH;
1006 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1008 state(conn, SSH_STOP);
1012 /* This is the last step in the SFTP connect phase. Do note that while
1013 we get the homedir here, we get the "workingpath" in the DO action
1014 since the homedir will remain the same between request but the
1015 working path will not. */
1016 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1017 state(conn, SSH_STOP);
1020 case SSH_SFTP_QUOTE_INIT:
1022 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1024 sshc->actualcode = result;
1025 state(conn, SSH_STOP);
1029 if(data->set.quote) {
1030 infof(data, "Sending quote commands\n");
1031 sshc->quote_item = data->set.quote;
1032 state(conn, SSH_SFTP_QUOTE);
1035 state(conn, SSH_SFTP_TRANS_INIT);
1039 case SSH_SFTP_POSTQUOTE_INIT:
1040 if(data->set.postquote) {
1041 infof(data, "Sending quote commands\n");
1042 sshc->quote_item = data->set.postquote;
1043 state(conn, SSH_SFTP_QUOTE);
1046 state(conn, SSH_STOP);
1050 case SSH_SFTP_QUOTE:
1051 /* Send any quote commands */
1056 * Support some of the "FTP" commands
1058 char *cmd = sshc->quote_item->data;
1059 sshc->acceptfail = FALSE;
1061 /* if a command starts with an asterisk, which a legal SFTP command never
1062 can, the command will be allowed to fail without it causing any
1063 aborts or cancels etc. It will cause libcurl to act as if the command
1064 is successful, whatever the server reponds. */
1068 sshc->acceptfail = TRUE;
1071 if(curl_strequal("pwd", cmd)) {
1072 /* output debug output if that is requested */
1073 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1076 result = CURLE_OUT_OF_MEMORY;
1077 state(conn, SSH_SFTP_CLOSE);
1078 sshc->nextstate = SSH_NO_STATE;
1081 if(data->set.verbose) {
1082 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1083 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1085 /* this sends an FTP-like "header" to the header callback so that the
1086 current directory can be read very similar to how it is read when
1087 using ordinary FTP. */
1088 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1090 state(conn, SSH_SFTP_NEXT_QUOTE);
1095 * the arguments following the command must be separated from the
1096 * command with a space so we can check for it unconditionally
1098 cp = strchr(cmd, ' ');
1100 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1101 state(conn, SSH_SFTP_CLOSE);
1102 sshc->nextstate = SSH_NO_STATE;
1103 sshc->actualcode = CURLE_QUOTE_ERROR;
1108 * also, every command takes at least one argument so we get that
1109 * first argument right now
1111 result = get_pathname(&cp, &sshc->quote_path1);
1113 if(result == CURLE_OUT_OF_MEMORY)
1114 failf(data, "Out of memory");
1116 failf(data, "Syntax error: Bad first parameter");
1117 state(conn, SSH_SFTP_CLOSE);
1118 sshc->nextstate = SSH_NO_STATE;
1119 sshc->actualcode = result;
1124 * SFTP is a binary protocol, so we don't send text commands to
1125 * the server. Instead, we scan for commands for commands used by
1126 * OpenSSH's sftp program and call the appropriate libssh2
1129 if(curl_strnequal(cmd, "chgrp ", 6) ||
1130 curl_strnequal(cmd, "chmod ", 6) ||
1131 curl_strnequal(cmd, "chown ", 6) ) {
1132 /* attribute change */
1134 /* sshc->quote_path1 contains the mode to set */
1135 /* get the destination */
1136 result = get_pathname(&cp, &sshc->quote_path2);
1138 if(result == CURLE_OUT_OF_MEMORY)
1139 failf(data, "Out of memory");
1141 failf(data, "Syntax error in chgrp/chmod/chown: "
1142 "Bad second parameter");
1143 Curl_safefree(sshc->quote_path1);
1144 sshc->quote_path1 = NULL;
1145 state(conn, SSH_SFTP_CLOSE);
1146 sshc->nextstate = SSH_NO_STATE;
1147 sshc->actualcode = result;
1150 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1151 state(conn, SSH_SFTP_QUOTE_STAT);
1154 else if(curl_strnequal(cmd, "ln ", 3) ||
1155 curl_strnequal(cmd, "symlink ", 8)) {
1156 /* symbolic linking */
1157 /* sshc->quote_path1 is the source */
1158 /* get the destination */
1159 result = get_pathname(&cp, &sshc->quote_path2);
1161 if(result == CURLE_OUT_OF_MEMORY)
1162 failf(data, "Out of memory");
1165 "Syntax error in ln/symlink: Bad second parameter");
1166 Curl_safefree(sshc->quote_path1);
1167 sshc->quote_path1 = NULL;
1168 state(conn, SSH_SFTP_CLOSE);
1169 sshc->nextstate = SSH_NO_STATE;
1170 sshc->actualcode = result;
1173 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1176 else if(curl_strnequal(cmd, "mkdir ", 6)) {
1178 state(conn, SSH_SFTP_QUOTE_MKDIR);
1181 else if(curl_strnequal(cmd, "rename ", 7)) {
1183 /* first param is the source path */
1184 /* second param is the dest. path */
1185 result = get_pathname(&cp, &sshc->quote_path2);
1187 if(result == CURLE_OUT_OF_MEMORY)
1188 failf(data, "Out of memory");
1190 failf(data, "Syntax error in rename: Bad second parameter");
1191 Curl_safefree(sshc->quote_path1);
1192 sshc->quote_path1 = NULL;
1193 state(conn, SSH_SFTP_CLOSE);
1194 sshc->nextstate = SSH_NO_STATE;
1195 sshc->actualcode = result;
1198 state(conn, SSH_SFTP_QUOTE_RENAME);
1201 else if(curl_strnequal(cmd, "rmdir ", 6)) {
1203 state(conn, SSH_SFTP_QUOTE_RMDIR);
1206 else if(curl_strnequal(cmd, "rm ", 3)) {
1207 state(conn, SSH_SFTP_QUOTE_UNLINK);
1211 failf(data, "Unknown SFTP command");
1212 Curl_safefree(sshc->quote_path1);
1213 sshc->quote_path1 = NULL;
1214 Curl_safefree(sshc->quote_path2);
1215 sshc->quote_path2 = NULL;
1216 state(conn, SSH_SFTP_CLOSE);
1217 sshc->nextstate = SSH_NO_STATE;
1218 sshc->actualcode = CURLE_QUOTE_ERROR;
1222 if(!sshc->quote_item) {
1223 state(conn, SSH_SFTP_TRANS_INIT);
1227 case SSH_SFTP_NEXT_QUOTE:
1228 if(sshc->quote_path1) {
1229 Curl_safefree(sshc->quote_path1);
1230 sshc->quote_path1 = NULL;
1232 if(sshc->quote_path2) {
1233 Curl_safefree(sshc->quote_path2);
1234 sshc->quote_path2 = NULL;
1237 sshc->quote_item = sshc->quote_item->next;
1239 if(sshc->quote_item) {
1240 state(conn, SSH_SFTP_QUOTE);
1243 if(sshc->nextstate != SSH_NO_STATE) {
1244 state(conn, sshc->nextstate);
1245 sshc->nextstate = SSH_NO_STATE;
1248 state(conn, SSH_SFTP_TRANS_INIT);
1253 case SSH_SFTP_QUOTE_STAT:
1255 char *cmd = sshc->quote_item->data;
1256 sshc->acceptfail = FALSE;
1258 /* if a command starts with an asterisk, which a legal SFTP command never
1259 can, the command will be allowed to fail without it causing any
1260 aborts or cancels etc. It will cause libcurl to act as if the command
1261 is successful, whatever the server reponds. */
1265 sshc->acceptfail = TRUE;
1268 if(!curl_strnequal(cmd, "chmod", 5)) {
1269 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1270 * set them both at once, we need to obtain the current ownership
1271 * first. This takes an extra protocol round trip.
1273 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1274 (unsigned int)strlen(sshc->quote_path2),
1276 &sshc->quote_attrs);
1277 if(rc == LIBSSH2_ERROR_EAGAIN) {
1280 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1281 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1282 Curl_safefree(sshc->quote_path1);
1283 sshc->quote_path1 = NULL;
1284 Curl_safefree(sshc->quote_path2);
1285 sshc->quote_path2 = NULL;
1286 failf(data, "Attempt to get SFTP stats failed: %s",
1287 sftp_libssh2_strerror(err));
1288 state(conn, SSH_SFTP_CLOSE);
1289 sshc->nextstate = SSH_NO_STATE;
1290 sshc->actualcode = CURLE_QUOTE_ERROR;
1295 /* Now set the new attributes... */
1296 if(curl_strnequal(cmd, "chgrp", 5)) {
1297 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1298 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1299 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1300 !sshc->acceptfail) {
1301 Curl_safefree(sshc->quote_path1);
1302 sshc->quote_path1 = NULL;
1303 Curl_safefree(sshc->quote_path2);
1304 sshc->quote_path2 = NULL;
1305 failf(data, "Syntax error: chgrp gid not a number");
1306 state(conn, SSH_SFTP_CLOSE);
1307 sshc->nextstate = SSH_NO_STATE;
1308 sshc->actualcode = CURLE_QUOTE_ERROR;
1312 else if(curl_strnequal(cmd, "chmod", 5)) {
1313 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1314 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1315 /* permissions are octal */
1316 if(sshc->quote_attrs.permissions == 0 &&
1317 !ISDIGIT(sshc->quote_path1[0])) {
1318 Curl_safefree(sshc->quote_path1);
1319 sshc->quote_path1 = NULL;
1320 Curl_safefree(sshc->quote_path2);
1321 sshc->quote_path2 = NULL;
1322 failf(data, "Syntax error: chmod permissions not a number");
1323 state(conn, SSH_SFTP_CLOSE);
1324 sshc->nextstate = SSH_NO_STATE;
1325 sshc->actualcode = CURLE_QUOTE_ERROR;
1329 else if(curl_strnequal(cmd, "chown", 5)) {
1330 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1331 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1332 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1333 !sshc->acceptfail) {
1334 Curl_safefree(sshc->quote_path1);
1335 sshc->quote_path1 = NULL;
1336 Curl_safefree(sshc->quote_path2);
1337 sshc->quote_path2 = NULL;
1338 failf(data, "Syntax error: chown uid not a number");
1339 state(conn, SSH_SFTP_CLOSE);
1340 sshc->nextstate = SSH_NO_STATE;
1341 sshc->actualcode = CURLE_QUOTE_ERROR;
1346 /* Now send the completed structure... */
1347 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1351 case SSH_SFTP_QUOTE_SETSTAT:
1352 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1353 (unsigned int)strlen(sshc->quote_path2),
1354 LIBSSH2_SFTP_SETSTAT,
1355 &sshc->quote_attrs);
1356 if(rc == LIBSSH2_ERROR_EAGAIN) {
1359 else if(rc != 0 && !sshc->acceptfail) {
1360 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1361 Curl_safefree(sshc->quote_path1);
1362 sshc->quote_path1 = NULL;
1363 Curl_safefree(sshc->quote_path2);
1364 sshc->quote_path2 = NULL;
1365 failf(data, "Attempt to set SFTP stats failed: %s",
1366 sftp_libssh2_strerror(err));
1367 state(conn, SSH_SFTP_CLOSE);
1368 sshc->nextstate = SSH_NO_STATE;
1369 sshc->actualcode = CURLE_QUOTE_ERROR;
1372 state(conn, SSH_SFTP_NEXT_QUOTE);
1375 case SSH_SFTP_QUOTE_SYMLINK:
1376 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1377 (unsigned int)strlen(sshc->quote_path1),
1379 (unsigned int)strlen(sshc->quote_path2),
1380 LIBSSH2_SFTP_SYMLINK);
1381 if(rc == LIBSSH2_ERROR_EAGAIN) {
1384 else if(rc != 0 && !sshc->acceptfail) {
1385 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1386 Curl_safefree(sshc->quote_path1);
1387 sshc->quote_path1 = NULL;
1388 Curl_safefree(sshc->quote_path2);
1389 sshc->quote_path2 = NULL;
1390 failf(data, "symlink command failed: %s",
1391 sftp_libssh2_strerror(err));
1392 state(conn, SSH_SFTP_CLOSE);
1393 sshc->nextstate = SSH_NO_STATE;
1394 sshc->actualcode = CURLE_QUOTE_ERROR;
1397 state(conn, SSH_SFTP_NEXT_QUOTE);
1400 case SSH_SFTP_QUOTE_MKDIR:
1401 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1402 (unsigned int)strlen(sshc->quote_path1),
1403 data->set.new_directory_perms);
1404 if(rc == LIBSSH2_ERROR_EAGAIN) {
1407 else if(rc != 0 && !sshc->acceptfail) {
1408 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1409 Curl_safefree(sshc->quote_path1);
1410 sshc->quote_path1 = NULL;
1411 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1412 state(conn, SSH_SFTP_CLOSE);
1413 sshc->nextstate = SSH_NO_STATE;
1414 sshc->actualcode = CURLE_QUOTE_ERROR;
1417 state(conn, SSH_SFTP_NEXT_QUOTE);
1420 case SSH_SFTP_QUOTE_RENAME:
1421 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1422 (unsigned int)strlen(sshc->quote_path1),
1424 (unsigned int)strlen(sshc->quote_path2),
1425 LIBSSH2_SFTP_RENAME_OVERWRITE |
1426 LIBSSH2_SFTP_RENAME_ATOMIC |
1427 LIBSSH2_SFTP_RENAME_NATIVE);
1429 if(rc == LIBSSH2_ERROR_EAGAIN) {
1432 else if(rc != 0 && !sshc->acceptfail) {
1433 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1434 Curl_safefree(sshc->quote_path1);
1435 sshc->quote_path1 = NULL;
1436 Curl_safefree(sshc->quote_path2);
1437 sshc->quote_path2 = NULL;
1438 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1439 state(conn, SSH_SFTP_CLOSE);
1440 sshc->nextstate = SSH_NO_STATE;
1441 sshc->actualcode = CURLE_QUOTE_ERROR;
1444 state(conn, SSH_SFTP_NEXT_QUOTE);
1447 case SSH_SFTP_QUOTE_RMDIR:
1448 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1449 (unsigned int)strlen(sshc->quote_path1));
1450 if(rc == LIBSSH2_ERROR_EAGAIN) {
1453 else if(rc != 0 && !sshc->acceptfail) {
1454 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1455 Curl_safefree(sshc->quote_path1);
1456 sshc->quote_path1 = NULL;
1457 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1458 state(conn, SSH_SFTP_CLOSE);
1459 sshc->nextstate = SSH_NO_STATE;
1460 sshc->actualcode = CURLE_QUOTE_ERROR;
1463 state(conn, SSH_SFTP_NEXT_QUOTE);
1466 case SSH_SFTP_QUOTE_UNLINK:
1467 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1468 (unsigned int)strlen(sshc->quote_path1));
1469 if(rc == LIBSSH2_ERROR_EAGAIN) {
1472 else if(rc != 0 && !sshc->acceptfail) {
1473 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1474 Curl_safefree(sshc->quote_path1);
1475 sshc->quote_path1 = NULL;
1476 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1477 state(conn, SSH_SFTP_CLOSE);
1478 sshc->nextstate = SSH_NO_STATE;
1479 sshc->actualcode = CURLE_QUOTE_ERROR;
1482 state(conn, SSH_SFTP_NEXT_QUOTE);
1485 case SSH_SFTP_TRANS_INIT:
1486 if(data->set.upload)
1487 state(conn, SSH_SFTP_UPLOAD_INIT);
1489 if(data->set.opt_no_body)
1490 state(conn, SSH_STOP);
1491 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1492 state(conn, SSH_SFTP_READDIR_INIT);
1494 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1498 case SSH_SFTP_UPLOAD_INIT:
1500 unsigned long flags;
1502 * NOTE!!! libssh2 requires that the destination path is a full path
1503 * that includes the destination file and name OR ends in a "/"
1504 * If this is not done the destination file will be named the
1505 * same name as the last directory in the path.
1508 if(data->state.resume_from != 0) {
1509 LIBSSH2_SFTP_ATTRIBUTES attrs;
1510 if(data->state.resume_from < 0) {
1511 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1512 (unsigned int)strlen(sftp_scp->path),
1513 LIBSSH2_SFTP_STAT, &attrs);
1514 if(rc == LIBSSH2_ERROR_EAGAIN) {
1518 data->state.resume_from = 0;
1521 curl_off_t size = attrs.filesize;
1523 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1524 return CURLE_BAD_DOWNLOAD_RESUME;
1526 data->state.resume_from = attrs.filesize;
1531 if(data->set.ftp_append)
1532 /* Try to open for append, but create if nonexisting */
1533 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1534 else if(data->state.resume_from > 0)
1535 /* If we have restart position then open for append */
1536 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1538 /* Clear file before writing (normal behaviour) */
1539 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1542 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1543 (unsigned int)strlen(sftp_scp->path),
1544 flags, data->set.new_file_perms,
1545 LIBSSH2_SFTP_OPENFILE);
1547 if(!sshc->sftp_handle) {
1548 rc = libssh2_session_last_errno(sshc->ssh_session);
1550 if(LIBSSH2_ERROR_EAGAIN == rc)
1553 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1554 /* only when there was an SFTP protocol error can we extract
1556 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1558 err = -1; /* not an sftp error at all */
1560 if(sshc->secondCreateDirs) {
1561 state(conn, SSH_SFTP_CLOSE);
1562 sshc->actualcode = err>= LIBSSH2_FX_OK?
1563 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1564 failf(data, "Creating the dir/file failed: %s",
1565 sftp_libssh2_strerror(err));
1568 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1569 (err == LIBSSH2_FX_FAILURE) ||
1570 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1571 (data->set.ftp_create_missing_dirs &&
1572 (strlen(sftp_scp->path) > 1))) {
1573 /* try to create the path remotely */
1574 sshc->secondCreateDirs = 1;
1575 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1578 state(conn, SSH_SFTP_CLOSE);
1579 sshc->actualcode = err>= LIBSSH2_FX_OK?
1580 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1581 if(!sshc->actualcode) {
1582 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1583 zero even though libssh2_sftp_open() failed previously! We need
1584 to work around that! */
1585 sshc->actualcode = CURLE_SSH;
1588 failf(data, "Upload failed: %s (%d/%d)",
1589 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1595 /* If we have restart point then we need to seek to the correct
1597 if(data->state.resume_from > 0) {
1598 /* Let's read off the proper amount of bytes from the input. */
1599 if(conn->seek_func) {
1600 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1604 if(seekerr != CURL_SEEKFUNC_OK) {
1606 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1607 failf(data, "Could not seek stream");
1608 return CURLE_FTP_COULDNT_USE_REST;
1610 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1612 curl_off_t passed=0;
1614 size_t readthisamountnow =
1615 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1616 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1618 size_t actuallyread =
1619 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1622 passed += actuallyread;
1623 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1624 /* this checks for greater-than only to make sure that the
1625 CURL_READFUNC_ABORT return code still aborts */
1626 failf(data, "Failed to read data");
1627 return CURLE_FTP_COULDNT_USE_REST;
1629 } while(passed < data->state.resume_from);
1633 /* now, decrease the size of the read */
1634 if(data->set.infilesize > 0) {
1635 data->set.infilesize -= data->state.resume_from;
1636 data->req.size = data->set.infilesize;
1637 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1640 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1642 if(data->set.infilesize > 0) {
1643 data->req.size = data->set.infilesize;
1644 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1647 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1649 /* not set by Curl_setup_transfer to preserve keepon bits */
1650 conn->sockfd = conn->writesockfd;
1653 state(conn, SSH_SFTP_CLOSE);
1654 sshc->actualcode = result;
1657 /* store this original bitmask setup to use later on if we can't
1658 figure out a "real" bitmask */
1659 sshc->orig_waitfor = data->req.keepon;
1661 /* we want to use the _sending_ function even when the socket turns
1662 out readable as the underlying libssh2 sftp send function will deal
1663 with both accordingly */
1664 conn->cselect_bits = CURL_CSELECT_OUT;
1666 /* since we don't really wait for anything at this point, we want the
1667 state machine to move on as soon as possible so we set a very short
1669 Curl_expire(data, 1);
1671 state(conn, SSH_STOP);
1676 case SSH_SFTP_CREATE_DIRS_INIT:
1677 if(strlen(sftp_scp->path) > 1) {
1678 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1679 state(conn, SSH_SFTP_CREATE_DIRS);
1682 state(conn, SSH_SFTP_UPLOAD_INIT);
1686 case SSH_SFTP_CREATE_DIRS:
1687 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1688 *sshc->slash_pos = 0;
1690 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1691 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1695 state(conn, SSH_SFTP_UPLOAD_INIT);
1699 case SSH_SFTP_CREATE_DIRS_MKDIR:
1700 /* 'mode' - parameter is preliminary - default to 0644 */
1701 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1702 (unsigned int)strlen(sftp_scp->path),
1703 data->set.new_directory_perms);
1704 if(rc == LIBSSH2_ERROR_EAGAIN) {
1707 *sshc->slash_pos = '/';
1710 unsigned int sftp_err = 0;
1712 * Abort if failure wasn't that the dir already exists or the
1713 * permission was denied (creation might succeed further down the
1714 * path) - retry on unspecific FAILURE also
1716 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1717 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1718 (sftp_err != LIBSSH2_FX_FAILURE) &&
1719 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1720 result = sftp_libssh2_error_to_CURLE(sftp_err);
1721 state(conn, SSH_SFTP_CLOSE);
1722 sshc->actualcode = result?result:CURLE_SSH;
1726 state(conn, SSH_SFTP_CREATE_DIRS);
1729 case SSH_SFTP_READDIR_INIT:
1731 * This is a directory that we are trying to get, so produce a directory
1734 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1737 strlen(sftp_scp->path),
1738 0, 0, LIBSSH2_SFTP_OPENDIR);
1739 if(!sshc->sftp_handle) {
1740 if(libssh2_session_last_errno(sshc->ssh_session) ==
1741 LIBSSH2_ERROR_EAGAIN) {
1742 rc = LIBSSH2_ERROR_EAGAIN;
1746 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1747 failf(data, "Could not open directory for reading: %s",
1748 sftp_libssh2_strerror(err));
1749 state(conn, SSH_SFTP_CLOSE);
1750 result = sftp_libssh2_error_to_CURLE(err);
1751 sshc->actualcode = result?result:CURLE_SSH;
1755 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1756 state(conn, SSH_SFTP_CLOSE);
1757 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1760 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1761 Curl_safefree(sshc->readdir_filename);
1762 sshc->readdir_filename = NULL;
1763 state(conn, SSH_SFTP_CLOSE);
1764 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1767 state(conn, SSH_SFTP_READDIR);
1770 case SSH_SFTP_READDIR:
1771 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1772 sshc->readdir_filename,
1774 sshc->readdir_longentry,
1776 &sshc->readdir_attrs);
1777 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1778 rc = LIBSSH2_ERROR_EAGAIN;
1781 if(sshc->readdir_len > 0) {
1782 sshc->readdir_filename[sshc->readdir_len] = '\0';
1784 if(data->set.ftp_list_only) {
1787 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1788 if(tmpLine == NULL) {
1789 state(conn, SSH_SFTP_CLOSE);
1790 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1793 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1794 tmpLine, sshc->readdir_len+1);
1795 Curl_safefree(tmpLine);
1798 state(conn, SSH_STOP);
1801 /* since this counts what we send to the client, we include the
1802 newline in this counter */
1803 data->req.bytecount += sshc->readdir_len+1;
1805 /* output debug output if that is requested */
1806 if(data->set.verbose) {
1807 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1808 sshc->readdir_len, conn);
1812 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1813 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1814 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1815 if(!sshc->readdir_line) {
1816 Curl_safefree(sshc->readdir_filename);
1817 sshc->readdir_filename = NULL;
1818 Curl_safefree(sshc->readdir_longentry);
1819 sshc->readdir_longentry = NULL;
1820 state(conn, SSH_SFTP_CLOSE);
1821 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1825 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1826 sshc->readdir_currLen);
1827 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1828 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1829 LIBSSH2_SFTP_S_IFLNK)) {
1830 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1831 if(sshc->readdir_linkPath == NULL) {
1832 Curl_safefree(sshc->readdir_filename);
1833 sshc->readdir_filename = NULL;
1834 Curl_safefree(sshc->readdir_longentry);
1835 sshc->readdir_longentry = NULL;
1836 state(conn, SSH_SFTP_CLOSE);
1837 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1841 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1842 sshc->readdir_filename);
1843 state(conn, SSH_SFTP_READDIR_LINK);
1846 state(conn, SSH_SFTP_READDIR_BOTTOM);
1850 else if(sshc->readdir_len == 0) {
1851 Curl_safefree(sshc->readdir_filename);
1852 sshc->readdir_filename = NULL;
1853 Curl_safefree(sshc->readdir_longentry);
1854 sshc->readdir_longentry = NULL;
1855 state(conn, SSH_SFTP_READDIR_DONE);
1858 else if(sshc->readdir_len <= 0) {
1859 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1860 result = sftp_libssh2_error_to_CURLE(err);
1861 sshc->actualcode = result?result:CURLE_SSH;
1862 failf(data, "Could not open remote file for reading: %s :: %d",
1863 sftp_libssh2_strerror(err),
1864 libssh2_session_last_errno(sshc->ssh_session));
1865 Curl_safefree(sshc->readdir_filename);
1866 sshc->readdir_filename = NULL;
1867 Curl_safefree(sshc->readdir_longentry);
1868 sshc->readdir_longentry = NULL;
1869 state(conn, SSH_SFTP_CLOSE);
1874 case SSH_SFTP_READDIR_LINK:
1876 libssh2_sftp_symlink_ex(sshc->sftp_session,
1877 sshc->readdir_linkPath,
1878 (unsigned int) strlen(sshc->readdir_linkPath),
1879 sshc->readdir_filename,
1880 PATH_MAX, LIBSSH2_SFTP_READLINK);
1881 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1882 rc = LIBSSH2_ERROR_EAGAIN;
1885 Curl_safefree(sshc->readdir_linkPath);
1886 sshc->readdir_linkPath = NULL;
1888 new_readdir_line = realloc(sshc->readdir_line,
1889 sshc->readdir_totalLen + 4 +
1891 if(!new_readdir_line) {
1892 Curl_safefree(sshc->readdir_line);
1893 sshc->readdir_line = NULL;
1894 Curl_safefree(sshc->readdir_filename);
1895 sshc->readdir_filename = NULL;
1896 Curl_safefree(sshc->readdir_longentry);
1897 sshc->readdir_longentry = NULL;
1898 state(conn, SSH_SFTP_CLOSE);
1899 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1902 sshc->readdir_line = new_readdir_line;
1904 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1905 sshc->readdir_currLen,
1906 sshc->readdir_totalLen -
1907 sshc->readdir_currLen,
1909 sshc->readdir_filename);
1911 state(conn, SSH_SFTP_READDIR_BOTTOM);
1914 case SSH_SFTP_READDIR_BOTTOM:
1915 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1916 sshc->readdir_currLen,
1917 sshc->readdir_totalLen -
1918 sshc->readdir_currLen, "\n");
1919 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1921 sshc->readdir_currLen);
1923 if(result == CURLE_OK) {
1925 /* output debug output if that is requested */
1926 if(data->set.verbose) {
1927 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1928 sshc->readdir_currLen, conn);
1930 data->req.bytecount += sshc->readdir_currLen;
1932 Curl_safefree(sshc->readdir_line);
1933 sshc->readdir_line = NULL;
1935 state(conn, SSH_STOP);
1938 state(conn, SSH_SFTP_READDIR);
1941 case SSH_SFTP_READDIR_DONE:
1942 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1943 LIBSSH2_ERROR_EAGAIN) {
1944 rc = LIBSSH2_ERROR_EAGAIN;
1947 sshc->sftp_handle = NULL;
1948 Curl_safefree(sshc->readdir_filename);
1949 sshc->readdir_filename = NULL;
1950 Curl_safefree(sshc->readdir_longentry);
1951 sshc->readdir_longentry = NULL;
1953 /* no data to transfer */
1954 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1955 state(conn, SSH_STOP);
1958 case SSH_SFTP_DOWNLOAD_INIT:
1960 * Work on getting the specified file
1963 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1964 (unsigned int)strlen(sftp_scp->path),
1965 LIBSSH2_FXF_READ, data->set.new_file_perms,
1966 LIBSSH2_SFTP_OPENFILE);
1967 if(!sshc->sftp_handle) {
1968 if(libssh2_session_last_errno(sshc->ssh_session) ==
1969 LIBSSH2_ERROR_EAGAIN) {
1970 rc = LIBSSH2_ERROR_EAGAIN;
1974 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1975 failf(data, "Could not open remote file for reading: %s",
1976 sftp_libssh2_strerror(err));
1977 state(conn, SSH_SFTP_CLOSE);
1978 result = sftp_libssh2_error_to_CURLE(err);
1979 sshc->actualcode = result?result:CURLE_SSH;
1983 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1986 case SSH_SFTP_DOWNLOAD_STAT:
1988 LIBSSH2_SFTP_ATTRIBUTES attrs;
1990 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1991 (unsigned int)strlen(sftp_scp->path),
1992 LIBSSH2_SFTP_STAT, &attrs);
1993 if(rc == LIBSSH2_ERROR_EAGAIN) {
1998 * libssh2_sftp_open() didn't return an error, so maybe the server
1999 * just doesn't support stat()
2001 data->req.size = -1;
2002 data->req.maxdownload = -1;
2005 curl_off_t size = attrs.filesize;
2008 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
2009 return CURLE_BAD_DOWNLOAD_RESUME;
2011 if(conn->data->state.use_range) {
2012 curl_off_t from, to;
2016 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2017 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2019 to=curlx_strtoofft(ptr, &ptr2, 0);
2020 if((ptr == ptr2) /* no "to" value given */
2025 /* from is relative to end of file */
2029 failf(data, "Offset (%"
2030 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2031 from, attrs.filesize);
2032 return CURLE_BAD_DOWNLOAD_RESUME;
2039 size = to - from + 1;
2042 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2044 data->req.size = size;
2045 data->req.maxdownload = size;
2046 Curl_pgrsSetDownloadSize(data, size);
2049 /* We can resume if we can seek to the resume position */
2050 if(data->state.resume_from) {
2051 if(data->state.resume_from < 0) {
2052 /* We're supposed to download the last abs(from) bytes */
2053 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2054 failf(data, "Offset (%"
2055 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2056 data->state.resume_from, attrs.filesize);
2057 return CURLE_BAD_DOWNLOAD_RESUME;
2059 /* download from where? */
2060 data->state.resume_from += attrs.filesize;
2063 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2064 failf(data, "Offset (%" FORMAT_OFF_T
2065 ") was beyond file size (%" FORMAT_OFF_T ")",
2066 data->state.resume_from, attrs.filesize);
2067 return CURLE_BAD_DOWNLOAD_RESUME;
2070 /* Does a completed file need to be seeked and started or closed ? */
2071 /* Now store the number of bytes we are expected to download */
2072 data->req.size = attrs.filesize - data->state.resume_from;
2073 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2074 Curl_pgrsSetDownloadSize(data,
2075 attrs.filesize - data->state.resume_from);
2076 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2079 /* Setup the actual download */
2080 if(data->req.size == 0) {
2081 /* no data to transfer */
2082 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2083 infof(data, "File already completely downloaded\n");
2084 state(conn, SSH_STOP);
2088 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2089 FALSE, NULL, -1, NULL);
2091 /* not set by Curl_setup_transfer to preserve keepon bits */
2092 conn->writesockfd = conn->sockfd;
2094 /* we want to use the _receiving_ function even when the socket turns
2095 out writableable as the underlying libssh2 recv function will deal
2096 with both accordingly */
2097 conn->cselect_bits = CURL_CSELECT_IN;
2100 state(conn, SSH_SFTP_CLOSE);
2101 sshc->actualcode = result;
2104 state(conn, SSH_STOP);
2108 case SSH_SFTP_CLOSE:
2109 if(sshc->sftp_handle) {
2110 rc = libssh2_sftp_close(sshc->sftp_handle);
2111 if(rc == LIBSSH2_ERROR_EAGAIN) {
2115 infof(data, "Failed to close libssh2 file\n");
2117 sshc->sftp_handle = NULL;
2120 Curl_safefree(sftp_scp->path);
2121 sftp_scp->path = NULL;
2124 DEBUGF(infof(data, "SFTP DONE done\n"));
2126 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2127 After nextstate is executed,the control should come back to
2128 SSH_SFTP_CLOSE to pass the correct result back */
2129 if(sshc->nextstate != SSH_NO_STATE) {
2130 state(conn, sshc->nextstate);
2131 sshc->nextstate = SSH_SFTP_CLOSE;
2134 state(conn, SSH_STOP);
2135 result = sshc->actualcode;
2139 case SSH_SFTP_SHUTDOWN:
2140 /* during times we get here due to a broken transfer and then the
2141 sftp_handle might not have been taken down so make sure that is done
2142 before we proceed */
2144 if(sshc->sftp_handle) {
2145 rc = libssh2_sftp_close(sshc->sftp_handle);
2146 if(rc == LIBSSH2_ERROR_EAGAIN) {
2150 infof(data, "Failed to close libssh2 file\n");
2152 sshc->sftp_handle = NULL;
2154 if(sshc->sftp_session) {
2155 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2156 if(rc == LIBSSH2_ERROR_EAGAIN) {
2160 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2162 sshc->sftp_session = NULL;
2165 Curl_safefree(sshc->homedir);
2166 sshc->homedir = NULL;
2167 conn->data->state.most_recent_ftp_entrypath = NULL;
2169 state(conn, SSH_SESSION_DISCONNECT);
2172 case SSH_SCP_TRANS_INIT:
2173 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2175 sshc->actualcode = result;
2176 state(conn, SSH_STOP);
2180 if(data->set.upload) {
2181 if(data->set.infilesize < 0) {
2182 failf(data, "SCP requires a known file size for upload");
2183 sshc->actualcode = CURLE_UPLOAD_FAILED;
2184 state(conn, SSH_SCP_CHANNEL_FREE);
2187 state(conn, SSH_SCP_UPLOAD_INIT);
2190 state(conn, SSH_SCP_DOWNLOAD_INIT);
2194 case SSH_SCP_UPLOAD_INIT:
2196 * libssh2 requires that the destination path is a full path that
2197 * includes the destination file and name OR ends in a "/" . If this is
2198 * not done the destination file will be named the same name as the last
2199 * directory in the path.
2202 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2203 data->set.infilesize);
2204 if(!sshc->ssh_channel) {
2205 if(libssh2_session_last_errno(sshc->ssh_session) ==
2206 LIBSSH2_ERROR_EAGAIN) {
2207 rc = LIBSSH2_ERROR_EAGAIN;
2214 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2215 &err_msg, NULL, 0));
2216 failf(conn->data, "%s", err_msg);
2217 state(conn, SSH_SCP_CHANNEL_FREE);
2218 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2224 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2227 /* not set by Curl_setup_transfer to preserve keepon bits */
2228 conn->sockfd = conn->writesockfd;
2231 state(conn, SSH_SCP_CHANNEL_FREE);
2232 sshc->actualcode = result;
2235 /* we want to use the _sending_ function even when the socket turns
2236 out readable as the underlying libssh2 scp send function will deal
2237 with both accordingly */
2238 conn->cselect_bits = CURL_CSELECT_OUT;
2240 state(conn, SSH_STOP);
2244 case SSH_SCP_DOWNLOAD_INIT:
2247 * We must check the remote file; if it is a directory no values will
2251 curl_off_t bytecount;
2253 /* clear the struct scp recv will fill in */
2254 memset(&sb, 0, sizeof(struct stat));
2256 /* get a fresh new channel from the ssh layer */
2257 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2258 sftp_scp->path, &sb);
2259 if(!sshc->ssh_channel) {
2260 if(libssh2_session_last_errno(sshc->ssh_session) ==
2261 LIBSSH2_ERROR_EAGAIN) {
2262 rc = LIBSSH2_ERROR_EAGAIN;
2269 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2270 &err_msg, NULL, 0));
2271 failf(conn->data, "%s", err_msg);
2272 state(conn, SSH_SCP_CHANNEL_FREE);
2273 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2279 bytecount = (curl_off_t)sb.st_size;
2280 data->req.maxdownload = (curl_off_t)sb.st_size;
2281 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2283 /* not set by Curl_setup_transfer to preserve keepon bits */
2284 conn->writesockfd = conn->sockfd;
2286 /* we want to use the _receiving_ function even when the socket turns
2287 out writableable as the underlying libssh2 recv function will deal
2288 with both accordingly */
2289 conn->cselect_bits = CURL_CSELECT_IN;
2292 state(conn, SSH_SCP_CHANNEL_FREE);
2293 sshc->actualcode = result;
2296 state(conn, SSH_STOP);
2301 if(data->set.upload)
2302 state(conn, SSH_SCP_SEND_EOF);
2304 state(conn, SSH_SCP_CHANNEL_FREE);
2307 case SSH_SCP_SEND_EOF:
2308 if(sshc->ssh_channel) {
2309 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2310 if(rc == LIBSSH2_ERROR_EAGAIN) {
2314 infof(data, "Failed to send libssh2 channel EOF\n");
2317 state(conn, SSH_SCP_WAIT_EOF);
2320 case SSH_SCP_WAIT_EOF:
2321 if(sshc->ssh_channel) {
2322 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2323 if(rc == LIBSSH2_ERROR_EAGAIN) {
2327 infof(data, "Failed to get channel EOF: %d\n", rc);
2330 state(conn, SSH_SCP_WAIT_CLOSE);
2333 case SSH_SCP_WAIT_CLOSE:
2334 if(sshc->ssh_channel) {
2335 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2336 if(rc == LIBSSH2_ERROR_EAGAIN) {
2340 infof(data, "Channel failed to close: %d\n", rc);
2343 state(conn, SSH_SCP_CHANNEL_FREE);
2346 case SSH_SCP_CHANNEL_FREE:
2347 if(sshc->ssh_channel) {
2348 rc = libssh2_channel_free(sshc->ssh_channel);
2349 if(rc == LIBSSH2_ERROR_EAGAIN) {
2353 infof(data, "Failed to free libssh2 scp subsystem\n");
2355 sshc->ssh_channel = NULL;
2357 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2359 state(conn, SSH_SESSION_DISCONNECT);
2361 state(conn, SSH_STOP);
2362 result = sshc->actualcode;
2365 case SSH_SESSION_DISCONNECT:
2366 /* during weird times when we've been prematurely aborted, the channel
2367 is still alive when we reach this state and we MUST kill the channel
2369 if(sshc->ssh_channel) {
2370 rc = libssh2_channel_free(sshc->ssh_channel);
2371 if(rc == LIBSSH2_ERROR_EAGAIN) {
2375 infof(data, "Failed to free libssh2 scp subsystem\n");
2377 sshc->ssh_channel = NULL;
2380 if(sshc->ssh_session) {
2381 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2382 if(rc == LIBSSH2_ERROR_EAGAIN) {
2386 infof(data, "Failed to disconnect libssh2 session\n");
2390 Curl_safefree(sshc->homedir);
2391 sshc->homedir = NULL;
2392 conn->data->state.most_recent_ftp_entrypath = NULL;
2394 state(conn, SSH_SESSION_FREE);
2397 case SSH_SESSION_FREE:
2398 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2400 libssh2_knownhost_free(sshc->kh);
2405 if(sshc->ssh_session) {
2406 rc = libssh2_session_free(sshc->ssh_session);
2407 if(rc == LIBSSH2_ERROR_EAGAIN) {
2411 infof(data, "Failed to free libssh2 session\n");
2413 sshc->ssh_session = NULL;
2416 /* worst-case scenario cleanup */
2418 DEBUGASSERT(sshc->ssh_session == NULL);
2419 DEBUGASSERT(sshc->ssh_channel == NULL);
2420 DEBUGASSERT(sshc->sftp_session == NULL);
2421 DEBUGASSERT(sshc->sftp_handle == NULL);
2422 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2423 DEBUGASSERT(sshc->kh == NULL);
2426 Curl_safefree(sshc->rsa_pub);
2427 Curl_safefree(sshc->rsa);
2429 Curl_safefree(sshc->quote_path1);
2430 Curl_safefree(sshc->quote_path2);
2432 Curl_safefree(sshc->homedir);
2434 Curl_safefree(sshc->readdir_filename);
2435 Curl_safefree(sshc->readdir_longentry);
2436 Curl_safefree(sshc->readdir_line);
2437 Curl_safefree(sshc->readdir_linkPath);
2439 /* the code we are about to return */
2440 result = sshc->actualcode;
2442 memset(sshc, 0, sizeof(struct ssh_conn));
2444 conn->bits.close = TRUE;
2445 sshc->state = SSH_SESSION_FREE; /* current */
2446 sshc->nextstate = SSH_NO_STATE;
2447 state(conn, SSH_STOP);
2451 /* fallthrough, just stop! */
2453 /* internal error */
2454 sshc->nextstate = SSH_NO_STATE;
2455 state(conn, SSH_STOP);
2459 } while(!rc && (sshc->state != SSH_STOP));
2461 if(rc == LIBSSH2_ERROR_EAGAIN) {
2462 /* we would block, we need to wait for the socket to be ready (in the
2463 right direction too)! */
2470 /* called by the multi interface to figure out what socket(s) to wait for and
2471 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2472 static int ssh_perform_getsock(const struct connectdata *conn,
2473 curl_socket_t *sock, /* points to numsocks
2474 number of sockets */
2477 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2478 int bitmap = GETSOCK_BLANK;
2481 sock[0] = conn->sock[FIRSTSOCKET];
2483 if(conn->waitfor & KEEP_RECV)
2484 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2486 if(conn->waitfor & KEEP_SEND)
2487 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2491 /* if we don't know the direction we can use the generic *_getsock()
2492 function even for the protocol_connect and doing states */
2493 return Curl_single_getsock(conn, sock, numsocks);
2497 /* Generic function called by the multi interface to figure out what socket(s)
2498 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2499 static int ssh_getsock(struct connectdata *conn,
2500 curl_socket_t *sock, /* points to numsocks number
2504 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2508 /* if we don't know any direction we can just play along as we used to and
2509 not provide any sensible info */
2510 return GETSOCK_BLANK;
2512 /* if we know the direction we can use the generic *_getsock() function even
2513 for the protocol_connect and doing states */
2514 return ssh_perform_getsock(conn, sock, numsocks);
2518 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2520 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2521 * function is used to figure out in what direction and stores this info so
2522 * that the multi interface can take advantage of it. Make sure to call this
2523 * function in all cases so that when it _doesn't_ return EAGAIN we can
2524 * restore the default wait bits.
2526 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2528 struct ssh_conn *sshc = &conn->proto.sshc;
2532 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2533 /* translate the libssh2 define bits into our own bit defines */
2534 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2535 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2538 /* It didn't block or libssh2 didn't reveal in which direction, put back
2540 conn->waitfor = sshc->orig_waitfor;
2543 /* no libssh2 directional support so we simply don't know */
2544 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2547 /* called repeatedly until done from multi.c */
2548 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2550 struct ssh_conn *sshc = &conn->proto.sshc;
2551 CURLcode result = CURLE_OK;
2552 bool block; /* we store the status and use that to provide a ssh_getsock()
2555 result = ssh_statemach_act(conn, &block);
2556 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2557 ssh_block2waitfor(conn, block);
2562 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2565 struct ssh_conn *sshc = &conn->proto.sshc;
2566 CURLcode result = CURLE_OK;
2567 struct SessionHandle *data = conn->data;
2569 while((sshc->state != SSH_STOP) && !result) {
2573 result = ssh_statemach_act(conn, &block);
2577 if(Curl_pgrsUpdate(conn))
2578 return CURLE_ABORTED_BY_CALLBACK;
2580 struct timeval now = Curl_tvnow();
2581 result = Curl_speedcheck(data, now);
2586 left = Curl_timeleft(data, NULL, duringconnect);
2588 failf(data, "Operation timed out\n");
2589 return CURLE_OPERATION_TIMEDOUT;
2592 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2593 if((CURLE_OK == result) && block) {
2594 int dir = libssh2_session_block_directions(sshc->ssh_session);
2595 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2596 curl_socket_t fd_read = CURL_SOCKET_BAD;
2597 curl_socket_t fd_write = CURL_SOCKET_BAD;
2598 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2600 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2602 /* wait for the socket to become ready */
2603 Curl_socket_ready(fd_read, fd_write,
2604 left>1000?1000:left); /* ignore result */
2614 * SSH setup and connection
2616 static CURLcode ssh_init(struct connectdata *conn)
2618 struct SessionHandle *data = conn->data;
2619 struct SSHPROTO *ssh;
2620 struct ssh_conn *sshc = &conn->proto.sshc;
2622 sshc->actualcode = CURLE_OK; /* reset error code */
2623 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2626 if(data->state.proto.ssh)
2629 ssh = calloc(1, sizeof(struct SSHPROTO));
2631 return CURLE_OUT_OF_MEMORY;
2633 data->state.proto.ssh = ssh;
2638 static Curl_recv scp_recv, sftp_recv;
2639 static Curl_send scp_send, sftp_send;
2642 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2643 * do protocol-specific actions at connect-time.
2645 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2647 #ifdef CURL_LIBSSH2_DEBUG
2650 struct ssh_conn *ssh;
2652 struct SessionHandle *data = conn->data;
2654 /* We default to persistent connections. We set this already in this connect
2655 function to make the re-use checks properly be able to check this bit. */
2656 conn->bits.close = FALSE;
2658 /* If there already is a protocol-specific struct allocated for this
2659 sessionhandle, deal with it */
2660 Curl_reset_reqproto(conn);
2662 result = ssh_init(conn);
2666 if(conn->handler->protocol & CURLPROTO_SCP) {
2667 conn->recv[FIRSTSOCKET] = scp_recv;
2668 conn->send[FIRSTSOCKET] = scp_send;
2671 conn->recv[FIRSTSOCKET] = sftp_recv;
2672 conn->send[FIRSTSOCKET] = sftp_send;
2674 ssh = &conn->proto.sshc;
2676 #ifdef CURL_LIBSSH2_DEBUG
2678 infof(data, "User: %s\n", conn->user);
2681 infof(data, "Password: %s\n", conn->passwd);
2683 sock = conn->sock[FIRSTSOCKET];
2684 #endif /* CURL_LIBSSH2_DEBUG */
2686 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2688 my_libssh2_realloc, conn);
2689 if(ssh->ssh_session == NULL) {
2690 failf(data, "Failure initialising ssh session");
2691 return CURLE_FAILED_INIT;
2694 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2695 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2697 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2699 /* eeek. TODO: free the ssh_session! */
2700 return CURLE_FAILED_INIT;
2703 /* read all known hosts from there */
2704 rc = libssh2_knownhost_readfile(ssh->kh,
2705 data->set.str[STRING_SSH_KNOWNHOSTS],
2706 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2708 infof(data, "Failed to read known hosts from %s\n",
2709 data->set.str[STRING_SSH_KNOWNHOSTS]);
2711 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2713 #ifdef CURL_LIBSSH2_DEBUG
2714 libssh2_trace(ssh->ssh_session, ~0);
2715 infof(data, "SSH socket: %d\n", (int)sock);
2716 #endif /* CURL_LIBSSH2_DEBUG */
2718 state(conn, SSH_INIT);
2720 if(data->state.used_interface == Curl_if_multi)
2721 result = ssh_multi_statemach(conn, done);
2723 result = ssh_easy_statemach(conn, TRUE);
2732 ***********************************************************************
2736 * This is the actual DO function for SCP. Get a file according to
2737 * the options previously setup.
2741 CURLcode scp_perform(struct connectdata *conn,
2745 CURLcode result = CURLE_OK;
2747 DEBUGF(infof(conn->data, "DO phase starts\n"));
2749 *dophase_done = FALSE; /* not done yet */
2751 /* start the first command in the DO phase */
2752 state(conn, SSH_SCP_TRANS_INIT);
2754 /* run the state-machine */
2755 if(conn->data->state.used_interface == Curl_if_multi) {
2756 result = ssh_multi_statemach(conn, dophase_done);
2759 result = ssh_easy_statemach(conn, FALSE);
2760 *dophase_done = TRUE; /* with the easy interface we are done here */
2762 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2765 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2771 /* called from multi.c while DOing */
2772 static CURLcode scp_doing(struct connectdata *conn,
2776 result = ssh_multi_statemach(conn, dophase_done);
2779 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2785 * The DO function is generic for both protocols. There was previously two
2786 * separate ones but this way means less duplicated code.
2789 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2793 struct SessionHandle *data = conn->data;
2795 *done = FALSE; /* default to false */
2798 Since connections can be re-used between SessionHandles, this might be a
2799 connection already existing but on a fresh SessionHandle struct so we must
2800 make sure we have a good 'struct SSHPROTO' to play with. For new
2801 connections, the struct SSHPROTO is allocated and setup in the
2802 ssh_connect() function.
2804 Curl_reset_reqproto(conn);
2805 res = ssh_init(conn);
2809 data->req.size = -1; /* make sure this is unknown at this point */
2811 Curl_pgrsSetUploadCounter(data, 0);
2812 Curl_pgrsSetDownloadCounter(data, 0);
2813 Curl_pgrsSetUploadSize(data, 0);
2814 Curl_pgrsSetDownloadSize(data, 0);
2816 if(conn->handler->protocol & CURLPROTO_SCP)
2817 res = scp_perform(conn, &connected, done);
2819 res = sftp_perform(conn, &connected, done);
2824 /* BLOCKING, but the function is using the state machine so the only reason
2825 this is still blocking is that the multi interface code has no support for
2826 disconnecting operations that takes a while */
2827 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2829 CURLcode result = CURLE_OK;
2830 struct ssh_conn *ssh = &conn->proto.sshc;
2831 (void) dead_connection;
2833 Curl_safefree(conn->data->state.proto.ssh);
2834 conn->data->state.proto.ssh = NULL;
2836 if(ssh->ssh_session) {
2837 /* only if there's a session still around to use! */
2839 state(conn, SSH_SESSION_DISCONNECT);
2841 result = ssh_easy_statemach(conn, FALSE);
2847 /* generic done function for both SCP and SFTP called from their specific
2849 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2851 CURLcode result = CURLE_OK;
2852 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2854 if(status == CURLE_OK) {
2855 /* run the state-machine
2857 TODO: when the multi interface is used, this _really_ should be using
2858 the ssh_multi_statemach function but we have no general support for
2859 non-blocking DONE operations, not in the multi state machine and with
2860 Curl_done() invokes on several places in the code!
2862 result = ssh_easy_statemach(conn, FALSE);
2868 Curl_safefree(sftp_scp->path);
2869 sftp_scp->path = NULL;
2871 Curl_pgrsDone(conn);
2873 conn->data->req.keepon = 0; /* clear all bits */
2878 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2881 (void)premature; /* not used */
2883 if(status == CURLE_OK)
2884 state(conn, SSH_SCP_DONE);
2886 return ssh_done(conn, status);
2890 /* return number of received (decrypted) bytes */
2891 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2892 const void *mem, size_t len, CURLcode *err)
2895 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2897 /* libssh2_channel_write() returns int! */
2899 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2901 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2903 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2912 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2913 * a regular CURLcode value.
2915 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2916 char *mem, size_t len, CURLcode *err)
2919 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2921 /* libssh2_channel_read() returns int */
2923 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2925 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2926 if(nread == LIBSSH2_ERROR_EAGAIN) {
2935 * =============== SFTP ===============
2939 ***********************************************************************
2943 * This is the actual DO function for SFTP. Get a file/directory according to
2944 * the options previously setup.
2948 CURLcode sftp_perform(struct connectdata *conn,
2952 CURLcode result = CURLE_OK;
2954 DEBUGF(infof(conn->data, "DO phase starts\n"));
2956 *dophase_done = FALSE; /* not done yet */
2958 /* start the first command in the DO phase */
2959 state(conn, SSH_SFTP_QUOTE_INIT);
2961 /* run the state-machine */
2962 if(conn->data->state.used_interface == Curl_if_multi) {
2963 result = ssh_multi_statemach(conn, dophase_done);
2966 result = ssh_easy_statemach(conn, FALSE);
2967 *dophase_done = TRUE; /* with the easy interface we are done here */
2969 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2972 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2978 /* called from multi.c while DOing */
2979 static CURLcode sftp_doing(struct connectdata *conn,
2983 result = ssh_multi_statemach(conn, dophase_done);
2986 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2991 /* BLOCKING, but the function is using the state machine so the only reason
2992 this is still blocking is that the multi interface code has no support for
2993 disconnecting operations that takes a while */
2994 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
2996 CURLcode result = CURLE_OK;
2997 (void) dead_connection;
2999 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3001 Curl_safefree(conn->data->state.proto.ssh);
3002 conn->data->state.proto.ssh = NULL;
3004 if(conn->proto.sshc.ssh_session) {
3005 /* only if there's a session still around to use! */
3006 state(conn, SSH_SFTP_SHUTDOWN);
3007 result = ssh_easy_statemach(conn, FALSE);
3010 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3016 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3019 struct ssh_conn *sshc = &conn->proto.sshc;
3021 if(status == CURLE_OK) {
3022 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3023 errors that could happen due to open file handles during POSTQUOTE
3025 if(!status && !premature && conn->data->set.postquote) {
3026 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3027 state(conn, SSH_SFTP_CLOSE);
3030 state(conn, SSH_SFTP_CLOSE);
3032 return ssh_done(conn, status);
3035 /* return number of sent bytes */
3036 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3037 const void *mem, size_t len, CURLcode *err)
3039 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3040 but is changed to ssize_t in 0.15. These days we don't
3041 support libssh2 0.15*/
3044 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3046 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3048 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3057 * Return number of received (decrypted) bytes
3059 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3060 char *mem, size_t len, CURLcode *err)
3065 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3067 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3069 if(nread == LIBSSH2_ERROR_EAGAIN) {
3076 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3079 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3081 * Permission to use, copy, modify, and distribute this software for any
3082 * purpose with or without fee is hereby granted, provided that the above
3083 * copyright notice and this permission notice appear in all copies.
3085 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3086 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3087 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3088 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3089 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3090 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3091 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3094 get_pathname(const char **cpp, char **path)
3096 const char *cp = *cpp, *end;
3099 static const char WHITESPACE[] = " \t\r\n";
3101 cp += strspn(cp, WHITESPACE);
3105 return CURLE_QUOTE_ERROR;
3108 *path = malloc(strlen(cp) + 1);
3110 return CURLE_OUT_OF_MEMORY;
3112 /* Check for quoted filenames */
3113 if(*cp == '\"' || *cp == '\'') {
3116 /* Search for terminating quote, unescape some chars */
3117 for(i = j = 0; i <= strlen(cp); i++) {
3118 if(cp[i] == quot) { /* Found quote */
3123 if(cp[i] == '\0') { /* End of string */
3124 /*error("Unterminated quote");*/
3127 if(cp[i] == '\\') { /* Escaped characters */
3129 if(cp[i] != '\'' && cp[i] != '\"' &&
3131 /*error("Bad escaped character '\\%c'",
3136 (*path)[j++] = cp[i];
3140 /*error("Empty quotes");*/
3143 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3146 /* Read to end of filename */
3147 end = strpbrk(cp, WHITESPACE);
3149 end = strchr(cp, '\0');
3150 *cpp = end + strspn(end, WHITESPACE);
3152 memcpy(*path, cp, end - cp);
3153 (*path)[end - cp] = '\0';
3158 Curl_safefree(*path);
3160 return CURLE_QUOTE_ERROR;
3164 static const char *sftp_libssh2_strerror(unsigned long err)
3167 case LIBSSH2_FX_NO_SUCH_FILE:
3168 return "No such file or directory";
3170 case LIBSSH2_FX_PERMISSION_DENIED:
3171 return "Permission denied";
3173 case LIBSSH2_FX_FAILURE:
3174 return "Operation failed";
3176 case LIBSSH2_FX_BAD_MESSAGE:
3177 return "Bad message from SFTP server";
3179 case LIBSSH2_FX_NO_CONNECTION:
3180 return "Not connected to SFTP server";
3182 case LIBSSH2_FX_CONNECTION_LOST:
3183 return "Connection to SFTP server lost";
3185 case LIBSSH2_FX_OP_UNSUPPORTED:
3186 return "Operation not supported by SFTP server";
3188 case LIBSSH2_FX_INVALID_HANDLE:
3189 return "Invalid handle";
3191 case LIBSSH2_FX_NO_SUCH_PATH:
3192 return "No such file or directory";
3194 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3195 return "File already exists";
3197 case LIBSSH2_FX_WRITE_PROTECT:
3198 return "File is write protected";
3200 case LIBSSH2_FX_NO_MEDIA:
3203 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3206 case LIBSSH2_FX_QUOTA_EXCEEDED:
3207 return "User quota exceeded";
3209 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3210 return "Unknown principle";
3212 case LIBSSH2_FX_LOCK_CONFlICT:
3213 return "File lock conflict";
3215 case LIBSSH2_FX_DIR_NOT_EMPTY:
3216 return "Directory not empty";
3218 case LIBSSH2_FX_NOT_A_DIRECTORY:
3219 return "Not a directory";
3221 case LIBSSH2_FX_INVALID_FILENAME:
3222 return "Invalid filename";
3224 case LIBSSH2_FX_LINK_LOOP:
3225 return "Link points to itself";
3227 return "Unknown error in libssh2";
3230 #endif /* USE_LIBSSH2 */