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 ssh_perform_getsock, /* perform_getsock */
169 scp_disconnect, /* disconnect */
170 ZERO_NULL, /* readwrite */
171 PORT_SSH, /* defport */
172 CURLPROTO_SCP, /* protocol */
173 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
178 * SFTP protocol handler.
181 const struct Curl_handler Curl_handler_sftp = {
183 ZERO_NULL, /* setup_connection */
185 sftp_done, /* done */
186 ZERO_NULL, /* do_more */
187 ssh_connect, /* connect_it */
188 ssh_multi_statemach, /* connecting */
189 sftp_doing, /* doing */
190 ssh_getsock, /* proto_getsock */
191 ssh_getsock, /* doing_getsock */
192 ssh_perform_getsock, /* perform_getsock */
193 sftp_disconnect, /* disconnect */
194 ZERO_NULL, /* readwrite */
195 PORT_SSH, /* defport */
196 CURLPROTO_SFTP, /* protocol */
197 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
202 kbd_callback(const char *name, int name_len, const char *instruction,
203 int instruction_len, int num_prompts,
204 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
205 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
208 struct connectdata *conn = (struct connectdata *)*abstract;
210 #ifdef CURL_LIBSSH2_DEBUG
211 fprintf(stderr, "name=%s\n", name);
212 fprintf(stderr, "name_len=%d\n", name_len);
213 fprintf(stderr, "instruction=%s\n", instruction);
214 fprintf(stderr, "instruction_len=%d\n", instruction_len);
215 fprintf(stderr, "num_prompts=%d\n", num_prompts);
220 (void)instruction_len;
221 #endif /* CURL_LIBSSH2_DEBUG */
222 if(num_prompts == 1) {
223 responses[0].text = strdup(conn->passwd);
224 responses[0].length = (unsigned int)strlen(conn->passwd);
230 static CURLcode sftp_libssh2_error_to_CURLE(int err)
236 case LIBSSH2_FX_NO_SUCH_FILE:
237 case LIBSSH2_FX_NO_SUCH_PATH:
238 return CURLE_REMOTE_FILE_NOT_FOUND;
240 case LIBSSH2_FX_PERMISSION_DENIED:
241 case LIBSSH2_FX_WRITE_PROTECT:
242 case LIBSSH2_FX_LOCK_CONFlICT:
243 return CURLE_REMOTE_ACCESS_DENIED;
245 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
246 case LIBSSH2_FX_QUOTA_EXCEEDED:
247 return CURLE_REMOTE_DISK_FULL;
249 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
250 return CURLE_REMOTE_FILE_EXISTS;
252 case LIBSSH2_FX_DIR_NOT_EMPTY:
253 return CURLE_QUOTE_ERROR;
262 static CURLcode libssh2_session_error_to_CURLE(int err)
265 /* Ordered by order of appearance in libssh2.h */
266 case LIBSSH2_ERROR_NONE:
269 case LIBSSH2_ERROR_SOCKET_NONE:
270 return CURLE_COULDNT_CONNECT;
272 case LIBSSH2_ERROR_ALLOC:
273 return CURLE_OUT_OF_MEMORY;
275 case LIBSSH2_ERROR_SOCKET_SEND:
276 return CURLE_SEND_ERROR;
278 case LIBSSH2_ERROR_HOSTKEY_INIT:
279 case LIBSSH2_ERROR_HOSTKEY_SIGN:
280 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
281 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
282 return CURLE_PEER_FAILED_VERIFICATION;
284 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
285 return CURLE_LOGIN_DENIED;
287 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
288 case LIBSSH2_ERROR_TIMEOUT:
289 return CURLE_OPERATION_TIMEDOUT;
291 case LIBSSH2_ERROR_EAGAIN:
295 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
296 error code, and possibly add a few new SSH-related one. We must however
297 not return or even depend on libssh2 errors in the public libcurl API */
302 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
304 (void)abstract; /* arg not used */
305 return malloc(count);
308 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
310 (void)abstract; /* arg not used */
311 return realloc(ptr, count);
314 static LIBSSH2_FREE_FUNC(my_libssh2_free)
316 (void)abstract; /* arg not used */
321 * SSH State machine related code
323 /* This is the ONLY way to change SSH state! */
324 static void state(struct connectdata *conn, sshstate nowstate)
326 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
327 /* for debug purposes */
328 static const char * const names[] = {
334 "SSH_AUTH_PKEY_INIT",
336 "SSH_AUTH_PASS_INIT",
338 "SSH_AUTH_HOST_INIT",
345 "SSH_SFTP_QUOTE_INIT",
346 "SSH_SFTP_POSTQUOTE_INIT",
348 "SSH_SFTP_NEXT_QUOTE",
349 "SSH_SFTP_QUOTE_STAT",
350 "SSH_SFTP_QUOTE_SETSTAT",
351 "SSH_SFTP_QUOTE_SYMLINK",
352 "SSH_SFTP_QUOTE_MKDIR",
353 "SSH_SFTP_QUOTE_RENAME",
354 "SSH_SFTP_QUOTE_RMDIR",
355 "SSH_SFTP_QUOTE_UNLINK",
356 "SSH_SFTP_TRANS_INIT",
357 "SSH_SFTP_UPLOAD_INIT",
358 "SSH_SFTP_CREATE_DIRS_INIT",
359 "SSH_SFTP_CREATE_DIRS",
360 "SSH_SFTP_CREATE_DIRS_MKDIR",
361 "SSH_SFTP_READDIR_INIT",
363 "SSH_SFTP_READDIR_LINK",
364 "SSH_SFTP_READDIR_BOTTOM",
365 "SSH_SFTP_READDIR_DONE",
366 "SSH_SFTP_DOWNLOAD_INIT",
367 "SSH_SFTP_DOWNLOAD_STAT",
370 "SSH_SCP_TRANS_INIT",
371 "SSH_SCP_UPLOAD_INIT",
372 "SSH_SCP_DOWNLOAD_INIT",
376 "SSH_SCP_WAIT_CLOSE",
377 "SSH_SCP_CHANNEL_FREE",
378 "SSH_SESSION_DISCONNECT",
383 struct ssh_conn *sshc = &conn->proto.sshc;
385 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
386 if(sshc->state != nowstate) {
387 infof(conn->data, "SFTP %p state change from %s to %s\n",
388 sshc, names[sshc->state], names[nowstate]);
392 sshc->state = nowstate;
395 /* figure out the path to work with in this particular request */
396 static CURLcode ssh_getworkingpath(struct connectdata *conn,
397 char *homedir, /* when SFTP is used */
398 char **path) /* returns the allocated
399 real path to work with */
401 struct SessionHandle *data = conn->data;
402 char *real_path = NULL;
404 int working_path_len;
406 working_path = curl_easy_unescape(data, data->state.path, 0,
409 return CURLE_OUT_OF_MEMORY;
411 /* Check for /~/ , indicating relative to the user's home directory */
412 if(conn->handler->protocol & CURLPROTO_SCP) {
413 real_path = malloc(working_path_len+1);
414 if(real_path == NULL) {
416 return CURLE_OUT_OF_MEMORY;
418 if((working_path_len > 1) && (working_path[1] == '~'))
419 /* It is referenced to the home directory, so strip the leading '/' */
420 memcpy(real_path, working_path+1, 1 + working_path_len-1);
422 memcpy(real_path, working_path, 1 + working_path_len);
424 else if(conn->handler->protocol & CURLPROTO_SFTP) {
425 if((working_path_len > 1) && (working_path[1] == '~')) {
426 size_t homelen = strlen(homedir);
427 real_path = malloc(homelen + working_path_len + 1);
428 if(real_path == NULL) {
430 return CURLE_OUT_OF_MEMORY;
432 /* It is referenced to the home directory, so strip the
434 memcpy(real_path, homedir, homelen);
435 real_path[homelen] = '/';
436 real_path[homelen+1] = '\0';
437 if(working_path_len > 3) {
438 memcpy(real_path+homelen+1, working_path + 3,
439 1 + working_path_len -3);
443 real_path = malloc(working_path_len+1);
444 if(real_path == NULL) {
446 return CURLE_OUT_OF_MEMORY;
448 memcpy(real_path, working_path, 1+working_path_len);
454 /* store the pointer for the caller to receive */
460 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
461 static int sshkeycallback(CURL *easy,
462 const struct curl_khkey *knownkey, /* known */
463 const struct curl_khkey *foundkey, /* found */
464 enum curl_khmatch match,
472 /* we only allow perfect matches, and we reject everything else */
473 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
478 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
481 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
482 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
484 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
488 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
489 * architectures so we check of the necessary function is present.
491 #ifndef HAVE_LIBSSH2_SCP_SEND64
492 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
494 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
495 (libssh2_uint64_t)d, 0, 0)
499 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
501 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
502 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
505 static CURLcode ssh_knownhost(struct connectdata *conn)
507 CURLcode result = CURLE_OK;
509 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
510 struct SessionHandle *data = conn->data;
512 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
513 /* we're asked to verify the host against a file */
514 struct ssh_conn *sshc = &conn->proto.sshc;
518 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
520 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
525 * A subject to figure out is what host name we need to pass in here.
526 * What host name does OpenSSH store in its file if an IDN name is
529 struct libssh2_knownhost *host;
530 enum curl_khmatch keymatch;
531 curl_sshkeycallback func =
532 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
533 struct curl_khkey knownkey;
534 struct curl_khkey *knownkeyp = NULL;
535 struct curl_khkey foundkey;
537 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
538 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
540 keycheck = libssh2_knownhost_check(sshc->kh,
543 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
544 LIBSSH2_KNOWNHOST_KEYENC_RAW|
548 infof(data, "SSH host check: %d, key: %s\n", keycheck,
549 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
552 /* setup 'knownkey' */
553 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
554 knownkey.key = host->key;
556 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
557 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
558 knownkeyp = &knownkey;
561 /* setup 'foundkey' */
562 foundkey.key = remotekey;
563 foundkey.len = keylen;
564 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
565 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
568 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
569 * curl_khmatch enum are ever modified, we need to introduce a
570 * translation table here!
572 keymatch = (enum curl_khmatch)keycheck;
574 /* Ask the callback how to behave */
575 rc = func(data, knownkeyp, /* from the knownhosts file */
576 &foundkey, /* from the remote host */
577 keymatch, data->set.ssh_keyfunc_userp);
580 /* no remotekey means failure! */
581 rc = CURLKHSTAT_REJECT;
584 default: /* unknown return codes will equal reject */
585 case CURLKHSTAT_REJECT:
586 state(conn, SSH_SESSION_FREE);
587 case CURLKHSTAT_DEFER:
588 /* DEFER means bail out but keep the SSH_HOSTKEY state */
589 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
591 case CURLKHSTAT_FINE:
592 case CURLKHSTAT_FINE_ADD_TO_FILE:
594 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
595 /* the found host+key didn't match but has been told to be fine
596 anyway so we add it in memory */
597 int addrc = libssh2_knownhost_add(sshc->kh,
598 conn->host.name, NULL,
600 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
601 LIBSSH2_KNOWNHOST_KEYENC_RAW|
604 infof(data, "Warning adding the known host %s failed!\n",
606 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
607 /* now we write the entire in-memory list of known hosts to the
610 libssh2_knownhost_writefile(sshc->kh,
611 data->set.str[STRING_SSH_KNOWNHOSTS],
612 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
614 infof(data, "Warning, writing %s failed!\n",
615 data->set.str[STRING_SSH_KNOWNHOSTS]);
622 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
630 * ssh_statemach_act() runs the SSH state machine as far as it can without
631 * blocking and without reaching the end. The data the pointer 'block' points
632 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
633 * meaning it wants to be called again when the socket is ready
636 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
638 CURLcode result = CURLE_OK;
639 struct SessionHandle *data = conn->data;
640 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
641 struct ssh_conn *sshc = &conn->proto.sshc;
642 curl_socket_t sock = conn->sock[FIRSTSOCKET];
643 #ifdef CURL_LIBSSH2_DEBUG
644 const char *fingerprint;
645 #endif /* CURL_LIBSSH2_DEBUG */
646 const char *host_public_key_md5;
647 int rc = LIBSSH2_ERROR_NONE, i;
649 int seekerr = CURL_SEEKFUNC_OK;
650 *block = 0; /* we're not blocking by default */
654 switch(sshc->state) {
656 sshc->secondCreateDirs = 0;
657 sshc->nextstate = SSH_NO_STATE;
658 sshc->actualcode = CURLE_OK;
660 /* Set libssh2 to non-blocking, since everything internally is
662 libssh2_session_set_blocking(sshc->ssh_session, 0);
664 state(conn, SSH_S_STARTUP);
668 rc = libssh2_session_startup(sshc->ssh_session, sock);
669 if(rc == LIBSSH2_ERROR_EAGAIN) {
673 failf(data, "Failure establishing ssh session");
674 state(conn, SSH_SESSION_FREE);
675 sshc->actualcode = CURLE_FAILED_INIT;
679 state(conn, SSH_HOSTKEY);
684 #ifdef CURL_LIBSSH2_DEBUG
686 * Before we authenticate we should check the hostkey's fingerprint
687 * against our known hosts. How that is handled (reading from file,
688 * whatever) is up to us. As for know not much is implemented, besides
689 * showing how to get the fingerprint.
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 infof(data, "Fingerprint: ");
696 for(rc = 0; rc < 16; rc++)
697 infof(data, "%02X ", (unsigned char) fingerprint[rc]);
699 #endif /* CURL_LIBSSH2_DEBUG */
701 /* Before we authenticate we check the hostkey's MD5 fingerprint
702 * against a known fingerprint, if available. This implementation pulls
703 * it from the curl option.
705 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
706 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
708 host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
709 LIBSSH2_HOSTKEY_HASH_MD5);
710 for(i = 0; i < 16; i++)
711 snprintf(&buf[i*2], 3, "%02x",
712 (unsigned char) host_public_key_md5[i]);
713 if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
715 "Denied establishing ssh session: mismatch md5 fingerprint. "
716 "Remote %s is not equal to %s",
717 buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
718 state(conn, SSH_SESSION_FREE);
719 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
724 result = ssh_knownhost(conn);
726 state(conn, SSH_AUTHLIST);
731 * Figure out authentication methods
732 * NB: As soon as we have provided a username to an openssh server we
733 * must never change it later. Thus, always specify the correct username
734 * here, even though the libssh2 docs kind of indicate that it should be
735 * possible to get a 'generic' list (not user-specific) of authentication
736 * methods, presumably with a blank username. That won't work in my
738 * So always specify it here.
740 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
742 (unsigned int)strlen(conn->user));
744 if(!sshc->authlist) {
745 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
746 LIBSSH2_ERROR_EAGAIN) {
747 rc = LIBSSH2_ERROR_EAGAIN;
751 state(conn, SSH_SESSION_FREE);
752 sshc->actualcode = libssh2_session_error_to_CURLE(err);
756 infof(data, "SSH authentication methods available: %s\n",
759 state(conn, SSH_AUTH_PKEY_INIT);
762 case SSH_AUTH_PKEY_INIT:
764 * Check the supported auth types in the order I feel is most secure
765 * with the requested type of authentication
767 sshc->authed = FALSE;
769 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
770 (strstr(sshc->authlist, "publickey") != NULL)) {
773 sshc->rsa_pub = sshc->rsa = NULL;
775 /* To ponder about: should really the lib be messing about with the
776 HOME environment variable etc? */
777 home = curl_getenv("HOME");
779 if(data->set.str[STRING_SSH_PUBLIC_KEY])
780 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
782 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
784 /* as a final resort, try current dir! */
785 sshc->rsa_pub = strdup("id_dsa.pub");
787 if(sshc->rsa_pub == NULL) {
790 state(conn, SSH_SESSION_FREE);
791 sshc->actualcode = CURLE_OUT_OF_MEMORY;
795 if(data->set.str[STRING_SSH_PRIVATE_KEY])
796 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
798 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
800 /* as a final resort, try current dir! */
801 sshc->rsa = strdup("id_dsa");
803 if(sshc->rsa == NULL) {
806 Curl_safefree(sshc->rsa_pub);
807 sshc->rsa_pub = NULL;
808 state(conn, SSH_SESSION_FREE);
809 sshc->actualcode = CURLE_OUT_OF_MEMORY;
813 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
814 if(!sshc->passphrase)
815 sshc->passphrase = "";
820 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
821 infof(data, "Using ssh private key file %s\n", sshc->rsa);
823 state(conn, SSH_AUTH_PKEY);
826 state(conn, SSH_AUTH_PASS_INIT);
831 /* The function below checks if the files exists, no need to stat() here.
833 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
838 sshc->rsa, sshc->passphrase);
839 if(rc == LIBSSH2_ERROR_EAGAIN) {
843 Curl_safefree(sshc->rsa_pub);
844 sshc->rsa_pub = NULL;
845 Curl_safefree(sshc->rsa);
850 infof(data, "Initialized SSH public key authentication\n");
851 state(conn, SSH_AUTH_DONE);
855 (void)libssh2_session_last_error(sshc->ssh_session,
857 infof(data, "SSH public key authentication failed: %s\n", err_msg);
858 state(conn, SSH_AUTH_PASS_INIT);
862 case SSH_AUTH_PASS_INIT:
863 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
864 (strstr(sshc->authlist, "password") != NULL)) {
865 state(conn, SSH_AUTH_PASS);
868 state(conn, SSH_AUTH_HOST_INIT);
873 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
874 (unsigned int)strlen(conn->user),
876 (unsigned int)strlen(conn->passwd),
878 if(rc == LIBSSH2_ERROR_EAGAIN) {
883 infof(data, "Initialized password authentication\n");
884 state(conn, SSH_AUTH_DONE);
887 state(conn, SSH_AUTH_HOST_INIT);
891 case SSH_AUTH_HOST_INIT:
892 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
893 (strstr(sshc->authlist, "hostbased") != NULL)) {
894 state(conn, SSH_AUTH_HOST);
897 state(conn, SSH_AUTH_KEY_INIT);
902 state(conn, SSH_AUTH_KEY_INIT);
905 case SSH_AUTH_KEY_INIT:
906 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
907 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
908 state(conn, SSH_AUTH_KEY);
911 state(conn, SSH_AUTH_DONE);
916 /* Authentication failed. Continue with keyboard-interactive now. */
917 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
922 if(rc == LIBSSH2_ERROR_EAGAIN) {
927 infof(data, "Initialized keyboard interactive authentication\n");
929 state(conn, SSH_AUTH_DONE);
934 failf(data, "Authentication failure");
935 state(conn, SSH_SESSION_FREE);
936 sshc->actualcode = CURLE_LOGIN_DENIED;
941 * At this point we have an authenticated ssh session.
943 infof(data, "Authentication complete\n");
945 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
948 conn->writesockfd = CURL_SOCKET_BAD;
950 if(conn->handler->protocol == CURLPROTO_SFTP) {
951 state(conn, SSH_SFTP_INIT);
954 infof(data, "SSH CONNECT phase done\n");
955 state(conn, SSH_STOP);
960 * Start the libssh2 sftp session
962 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
963 if(!sshc->sftp_session) {
964 if(libssh2_session_last_errno(sshc->ssh_session) ==
965 LIBSSH2_ERROR_EAGAIN) {
966 rc = LIBSSH2_ERROR_EAGAIN;
972 (void)libssh2_session_last_error(sshc->ssh_session,
974 failf(data, "Failure initializing sftp session: %s", err_msg);
975 state(conn, SSH_SESSION_FREE);
976 sshc->actualcode = CURLE_FAILED_INIT;
980 state(conn, SSH_SFTP_REALPATH);
983 case SSH_SFTP_REALPATH:
985 char tempHome[PATH_MAX];
988 * Get the "home" directory
990 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
991 tempHome, PATH_MAX-1);
992 if(rc == LIBSSH2_ERROR_EAGAIN) {
996 /* It seems that this string is not always NULL terminated */
998 sshc->homedir = strdup(tempHome);
1000 state(conn, SSH_SFTP_CLOSE);
1001 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1004 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1007 /* Return the error type */
1008 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1009 result = sftp_libssh2_error_to_CURLE(err);
1010 sshc->actualcode = result?result:CURLE_SSH;
1011 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1013 state(conn, SSH_STOP);
1017 /* This is the last step in the SFTP connect phase. Do note that while
1018 we get the homedir here, we get the "workingpath" in the DO action
1019 since the homedir will remain the same between request but the
1020 working path will not. */
1021 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1022 state(conn, SSH_STOP);
1025 case SSH_SFTP_QUOTE_INIT:
1027 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1029 sshc->actualcode = result;
1030 state(conn, SSH_STOP);
1034 if(data->set.quote) {
1035 infof(data, "Sending quote commands\n");
1036 sshc->quote_item = data->set.quote;
1037 state(conn, SSH_SFTP_QUOTE);
1040 state(conn, SSH_SFTP_TRANS_INIT);
1044 case SSH_SFTP_POSTQUOTE_INIT:
1045 if(data->set.postquote) {
1046 infof(data, "Sending quote commands\n");
1047 sshc->quote_item = data->set.postquote;
1048 state(conn, SSH_SFTP_QUOTE);
1051 state(conn, SSH_STOP);
1055 case SSH_SFTP_QUOTE:
1056 /* Send any quote commands */
1061 * Support some of the "FTP" commands
1063 if(curl_strequal("pwd", sshc->quote_item->data)) {
1064 /* output debug output if that is requested */
1065 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1068 result = CURLE_OUT_OF_MEMORY;
1069 state(conn, SSH_SFTP_CLOSE);
1070 sshc->nextstate = SSH_NO_STATE;
1073 if(data->set.verbose) {
1074 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1075 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1077 /* this sends an FTP-like "header" to the header callback so that the
1078 current directory can be read very similar to how it is read when
1079 using ordinary FTP. */
1080 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1082 state(conn, SSH_SFTP_NEXT_QUOTE);
1085 else if(sshc->quote_item->data) {
1087 * the arguments following the command must be separated from the
1088 * command with a space so we can check for it unconditionally
1090 cp = strchr(sshc->quote_item->data, ' ');
1092 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1093 state(conn, SSH_SFTP_CLOSE);
1094 sshc->nextstate = SSH_NO_STATE;
1095 sshc->actualcode = CURLE_QUOTE_ERROR;
1100 * also, every command takes at least one argument so we get that
1101 * first argument right now
1103 result = get_pathname(&cp, &sshc->quote_path1);
1105 if(result == CURLE_OUT_OF_MEMORY)
1106 failf(data, "Out of memory");
1108 failf(data, "Syntax error: Bad first parameter");
1109 state(conn, SSH_SFTP_CLOSE);
1110 sshc->nextstate = SSH_NO_STATE;
1111 sshc->actualcode = result;
1116 * SFTP is a binary protocol, so we don't send text commands to
1117 * the server. Instead, we scan for commands for commands used by
1118 * OpenSSH's sftp program and call the appropriate libssh2
1121 if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
1122 curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
1123 curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
1124 /* attribute change */
1126 /* sshc->quote_path1 contains the mode to set */
1127 /* get the destination */
1128 result = get_pathname(&cp, &sshc->quote_path2);
1130 if(result == CURLE_OUT_OF_MEMORY)
1131 failf(data, "Out of memory");
1133 failf(data, "Syntax error in chgrp/chmod/chown: "
1134 "Bad second parameter");
1135 Curl_safefree(sshc->quote_path1);
1136 sshc->quote_path1 = NULL;
1137 state(conn, SSH_SFTP_CLOSE);
1138 sshc->nextstate = SSH_NO_STATE;
1139 sshc->actualcode = result;
1142 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1143 state(conn, SSH_SFTP_QUOTE_STAT);
1146 else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
1147 curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
1148 /* symbolic linking */
1149 /* sshc->quote_path1 is the source */
1150 /* get the destination */
1151 result = get_pathname(&cp, &sshc->quote_path2);
1153 if(result == CURLE_OUT_OF_MEMORY)
1154 failf(data, "Out of memory");
1157 "Syntax error in ln/symlink: Bad second parameter");
1158 Curl_safefree(sshc->quote_path1);
1159 sshc->quote_path1 = NULL;
1160 state(conn, SSH_SFTP_CLOSE);
1161 sshc->nextstate = SSH_NO_STATE;
1162 sshc->actualcode = result;
1165 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1168 else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
1170 state(conn, SSH_SFTP_QUOTE_MKDIR);
1173 else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
1175 /* first param is the source path */
1176 /* second param is the dest. path */
1177 result = get_pathname(&cp, &sshc->quote_path2);
1179 if(result == CURLE_OUT_OF_MEMORY)
1180 failf(data, "Out of memory");
1182 failf(data, "Syntax error in rename: Bad second parameter");
1183 Curl_safefree(sshc->quote_path1);
1184 sshc->quote_path1 = NULL;
1185 state(conn, SSH_SFTP_CLOSE);
1186 sshc->nextstate = SSH_NO_STATE;
1187 sshc->actualcode = result;
1190 state(conn, SSH_SFTP_QUOTE_RENAME);
1193 else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
1195 state(conn, SSH_SFTP_QUOTE_RMDIR);
1198 else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
1199 state(conn, SSH_SFTP_QUOTE_UNLINK);
1203 failf(data, "Unknown SFTP command");
1204 Curl_safefree(sshc->quote_path1);
1205 sshc->quote_path1 = NULL;
1206 Curl_safefree(sshc->quote_path2);
1207 sshc->quote_path2 = NULL;
1208 state(conn, SSH_SFTP_CLOSE);
1209 sshc->nextstate = SSH_NO_STATE;
1210 sshc->actualcode = CURLE_QUOTE_ERROR;
1214 if(!sshc->quote_item) {
1215 state(conn, SSH_SFTP_TRANS_INIT);
1219 case SSH_SFTP_NEXT_QUOTE:
1220 if(sshc->quote_path1) {
1221 Curl_safefree(sshc->quote_path1);
1222 sshc->quote_path1 = NULL;
1224 if(sshc->quote_path2) {
1225 Curl_safefree(sshc->quote_path2);
1226 sshc->quote_path2 = NULL;
1229 sshc->quote_item = sshc->quote_item->next;
1231 if(sshc->quote_item) {
1232 state(conn, SSH_SFTP_QUOTE);
1235 if(sshc->nextstate != SSH_NO_STATE) {
1236 state(conn, sshc->nextstate);
1237 sshc->nextstate = SSH_NO_STATE;
1240 state(conn, SSH_SFTP_TRANS_INIT);
1245 case SSH_SFTP_QUOTE_STAT:
1246 if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1247 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1248 * set them both at once, we need to obtain the current ownership
1249 * first. This takes an extra protocol round trip.
1251 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1252 (unsigned int)strlen(sshc->quote_path2),
1254 &sshc->quote_attrs);
1255 if(rc == LIBSSH2_ERROR_EAGAIN) {
1258 else if(rc != 0) { /* get those attributes */
1259 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1260 Curl_safefree(sshc->quote_path1);
1261 sshc->quote_path1 = NULL;
1262 Curl_safefree(sshc->quote_path2);
1263 sshc->quote_path2 = NULL;
1264 failf(data, "Attempt to get SFTP stats failed: %s",
1265 sftp_libssh2_strerror(err));
1266 state(conn, SSH_SFTP_CLOSE);
1267 sshc->nextstate = SSH_NO_STATE;
1268 sshc->actualcode = CURLE_QUOTE_ERROR;
1273 /* Now set the new attributes... */
1274 if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
1275 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1276 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1277 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1278 Curl_safefree(sshc->quote_path1);
1279 sshc->quote_path1 = NULL;
1280 Curl_safefree(sshc->quote_path2);
1281 sshc->quote_path2 = NULL;
1282 failf(data, "Syntax error: chgrp gid not a number");
1283 state(conn, SSH_SFTP_CLOSE);
1284 sshc->nextstate = SSH_NO_STATE;
1285 sshc->actualcode = CURLE_QUOTE_ERROR;
1289 else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1290 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1291 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1292 /* permissions are octal */
1293 if(sshc->quote_attrs.permissions == 0 &&
1294 !ISDIGIT(sshc->quote_path1[0])) {
1295 Curl_safefree(sshc->quote_path1);
1296 sshc->quote_path1 = NULL;
1297 Curl_safefree(sshc->quote_path2);
1298 sshc->quote_path2 = NULL;
1299 failf(data, "Syntax error: chmod permissions not a number");
1300 state(conn, SSH_SFTP_CLOSE);
1301 sshc->nextstate = SSH_NO_STATE;
1302 sshc->actualcode = CURLE_QUOTE_ERROR;
1306 else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
1307 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1308 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1309 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1310 Curl_safefree(sshc->quote_path1);
1311 sshc->quote_path1 = NULL;
1312 Curl_safefree(sshc->quote_path2);
1313 sshc->quote_path2 = NULL;
1314 failf(data, "Syntax error: chown uid not a number");
1315 state(conn, SSH_SFTP_CLOSE);
1316 sshc->nextstate = SSH_NO_STATE;
1317 sshc->actualcode = CURLE_QUOTE_ERROR;
1322 /* Now send the completed structure... */
1323 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1326 case SSH_SFTP_QUOTE_SETSTAT:
1327 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1328 (unsigned int)strlen(sshc->quote_path2),
1329 LIBSSH2_SFTP_SETSTAT,
1330 &sshc->quote_attrs);
1331 if(rc == LIBSSH2_ERROR_EAGAIN) {
1335 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1336 Curl_safefree(sshc->quote_path1);
1337 sshc->quote_path1 = NULL;
1338 Curl_safefree(sshc->quote_path2);
1339 sshc->quote_path2 = NULL;
1340 failf(data, "Attempt to set SFTP stats failed: %s",
1341 sftp_libssh2_strerror(err));
1342 state(conn, SSH_SFTP_CLOSE);
1343 sshc->nextstate = SSH_NO_STATE;
1344 sshc->actualcode = CURLE_QUOTE_ERROR;
1347 state(conn, SSH_SFTP_NEXT_QUOTE);
1350 case SSH_SFTP_QUOTE_SYMLINK:
1351 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1352 (unsigned int)strlen(sshc->quote_path1),
1354 (unsigned int)strlen(sshc->quote_path2),
1355 LIBSSH2_SFTP_SYMLINK);
1356 if(rc == LIBSSH2_ERROR_EAGAIN) {
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, "symlink command 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_MKDIR:
1376 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1377 (unsigned int)strlen(sshc->quote_path1),
1379 if(rc == LIBSSH2_ERROR_EAGAIN) {
1383 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1384 Curl_safefree(sshc->quote_path1);
1385 sshc->quote_path1 = NULL;
1386 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1387 state(conn, SSH_SFTP_CLOSE);
1388 sshc->nextstate = SSH_NO_STATE;
1389 sshc->actualcode = CURLE_QUOTE_ERROR;
1392 state(conn, SSH_SFTP_NEXT_QUOTE);
1395 case SSH_SFTP_QUOTE_RENAME:
1396 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1397 (unsigned int)strlen(sshc->quote_path1),
1399 (unsigned int)strlen(sshc->quote_path2),
1400 LIBSSH2_SFTP_RENAME_OVERWRITE |
1401 LIBSSH2_SFTP_RENAME_ATOMIC |
1402 LIBSSH2_SFTP_RENAME_NATIVE);
1404 if(rc == LIBSSH2_ERROR_EAGAIN) {
1408 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1409 Curl_safefree(sshc->quote_path1);
1410 sshc->quote_path1 = NULL;
1411 Curl_safefree(sshc->quote_path2);
1412 sshc->quote_path2 = NULL;
1413 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1414 state(conn, SSH_SFTP_CLOSE);
1415 sshc->nextstate = SSH_NO_STATE;
1416 sshc->actualcode = CURLE_QUOTE_ERROR;
1419 state(conn, SSH_SFTP_NEXT_QUOTE);
1422 case SSH_SFTP_QUOTE_RMDIR:
1423 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1424 (unsigned int)strlen(sshc->quote_path1));
1425 if(rc == LIBSSH2_ERROR_EAGAIN) {
1429 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1430 Curl_safefree(sshc->quote_path1);
1431 sshc->quote_path1 = NULL;
1432 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1433 state(conn, SSH_SFTP_CLOSE);
1434 sshc->nextstate = SSH_NO_STATE;
1435 sshc->actualcode = CURLE_QUOTE_ERROR;
1438 state(conn, SSH_SFTP_NEXT_QUOTE);
1441 case SSH_SFTP_QUOTE_UNLINK:
1442 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1443 (unsigned int)strlen(sshc->quote_path1));
1444 if(rc == LIBSSH2_ERROR_EAGAIN) {
1448 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1449 Curl_safefree(sshc->quote_path1);
1450 sshc->quote_path1 = NULL;
1451 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1452 state(conn, SSH_SFTP_CLOSE);
1453 sshc->nextstate = SSH_NO_STATE;
1454 sshc->actualcode = CURLE_QUOTE_ERROR;
1457 state(conn, SSH_SFTP_NEXT_QUOTE);
1460 case SSH_SFTP_TRANS_INIT:
1461 if(data->set.upload)
1462 state(conn, SSH_SFTP_UPLOAD_INIT);
1464 if(data->set.opt_no_body)
1465 state(conn, SSH_STOP);
1466 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1467 state(conn, SSH_SFTP_READDIR_INIT);
1469 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1473 case SSH_SFTP_UPLOAD_INIT:
1475 unsigned long flags;
1477 * NOTE!!! libssh2 requires that the destination path is a full path
1478 * that includes the destination file and name OR ends in a "/"
1479 * If this is not done the destination file will be named the
1480 * same name as the last directory in the path.
1483 if(data->state.resume_from != 0) {
1484 LIBSSH2_SFTP_ATTRIBUTES attrs;
1485 if(data->state.resume_from < 0) {
1486 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1487 (unsigned int)strlen(sftp_scp->path),
1488 LIBSSH2_SFTP_STAT, &attrs);
1489 if(rc == LIBSSH2_ERROR_EAGAIN) {
1493 data->state.resume_from = 0;
1496 curl_off_t size = attrs.filesize;
1498 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1499 return CURLE_BAD_DOWNLOAD_RESUME;
1501 data->state.resume_from = attrs.filesize;
1506 if(data->set.ftp_append)
1507 /* Try to open for append, but create if nonexisting */
1508 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1509 else if(data->state.resume_from > 0)
1510 /* If we have restart position then open for append */
1511 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1513 /* Clear file before writing (normal behaviour) */
1514 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1517 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1518 (unsigned int)strlen(sftp_scp->path),
1519 flags, data->set.new_file_perms,
1520 LIBSSH2_SFTP_OPENFILE);
1522 if(!sshc->sftp_handle) {
1523 rc = libssh2_session_last_errno(sshc->ssh_session);
1525 if(LIBSSH2_ERROR_EAGAIN == rc)
1528 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1529 /* only when there was an SFTP protocol error can we extract
1531 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1533 err = -1; /* not an sftp error at all */
1535 if(sshc->secondCreateDirs) {
1536 state(conn, SSH_SFTP_CLOSE);
1537 sshc->actualcode = err>= LIBSSH2_FX_OK?
1538 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1539 failf(data, "Creating the dir/file failed: %s",
1540 sftp_libssh2_strerror(err));
1543 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1544 (err == LIBSSH2_FX_FAILURE) ||
1545 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1546 (data->set.ftp_create_missing_dirs &&
1547 (strlen(sftp_scp->path) > 1))) {
1548 /* try to create the path remotely */
1549 sshc->secondCreateDirs = 1;
1550 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1553 state(conn, SSH_SFTP_CLOSE);
1554 sshc->actualcode = err>= LIBSSH2_FX_OK?
1555 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1556 if(!sshc->actualcode) {
1557 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1558 zero even though libssh2_sftp_open() failed previously! We need
1559 to work around that! */
1560 sshc->actualcode = CURLE_SSH;
1563 failf(data, "Upload failed: %s (%d/%d)",
1564 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1570 /* If we have restart point then we need to seek to the correct
1572 if(data->state.resume_from > 0) {
1573 /* Let's read off the proper amount of bytes from the input. */
1574 if(conn->seek_func) {
1575 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1579 if(seekerr != CURL_SEEKFUNC_OK) {
1581 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1582 failf(data, "Could not seek stream");
1583 return CURLE_FTP_COULDNT_USE_REST;
1585 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1587 curl_off_t passed=0;
1589 size_t readthisamountnow =
1590 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1591 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1593 size_t actuallyread =
1594 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1597 passed += actuallyread;
1598 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1599 /* this checks for greater-than only to make sure that the
1600 CURL_READFUNC_ABORT return code still aborts */
1601 failf(data, "Failed to read data");
1602 return CURLE_FTP_COULDNT_USE_REST;
1604 } while(passed < data->state.resume_from);
1608 /* now, decrease the size of the read */
1609 if(data->set.infilesize > 0) {
1610 data->set.infilesize -= data->state.resume_from;
1611 data->req.size = data->set.infilesize;
1612 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1615 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1617 if(data->set.infilesize > 0) {
1618 data->req.size = data->set.infilesize;
1619 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1622 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1624 /* not set by Curl_setup_transfer to preserve keepon bits */
1625 conn->sockfd = conn->writesockfd;
1628 state(conn, SSH_SFTP_CLOSE);
1629 sshc->actualcode = result;
1632 /* store this original bitmask setup to use later on if we can't
1633 figure out a "real" bitmask */
1634 sshc->orig_waitfor = data->req.keepon;
1636 /* we want to use the _sending_ function even when the socket turns
1637 out readable as the underlying libssh2 sftp send function will deal
1638 with both accordingly */
1639 conn->cselect_bits = CURL_CSELECT_OUT;
1641 /* since we don't really wait for anything at this point, we want the
1642 state machine to move on as soon as possible so we set a very short
1644 Curl_expire(data, 1);
1646 state(conn, SSH_STOP);
1651 case SSH_SFTP_CREATE_DIRS_INIT:
1652 if(strlen(sftp_scp->path) > 1) {
1653 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1654 state(conn, SSH_SFTP_CREATE_DIRS);
1657 state(conn, SSH_SFTP_UPLOAD_INIT);
1661 case SSH_SFTP_CREATE_DIRS:
1662 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1663 *sshc->slash_pos = 0;
1665 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1666 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1670 state(conn, SSH_SFTP_UPLOAD_INIT);
1674 case SSH_SFTP_CREATE_DIRS_MKDIR:
1675 /* 'mode' - parameter is preliminary - default to 0644 */
1676 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1677 (unsigned int)strlen(sftp_scp->path),
1678 data->set.new_directory_perms);
1679 if(rc == LIBSSH2_ERROR_EAGAIN) {
1682 *sshc->slash_pos = '/';
1685 unsigned int sftp_err = 0;
1687 * Abort if failure wasn't that the dir already exists or the
1688 * permission was denied (creation might succeed further down the
1689 * path) - retry on unspecific FAILURE also
1691 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1692 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1693 (sftp_err != LIBSSH2_FX_FAILURE) &&
1694 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1695 result = sftp_libssh2_error_to_CURLE(sftp_err);
1696 state(conn, SSH_SFTP_CLOSE);
1697 sshc->actualcode = result?result:CURLE_SSH;
1701 state(conn, SSH_SFTP_CREATE_DIRS);
1704 case SSH_SFTP_READDIR_INIT:
1706 * This is a directory that we are trying to get, so produce a directory
1709 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1712 strlen(sftp_scp->path),
1713 0, 0, LIBSSH2_SFTP_OPENDIR);
1714 if(!sshc->sftp_handle) {
1715 if(libssh2_session_last_errno(sshc->ssh_session) ==
1716 LIBSSH2_ERROR_EAGAIN) {
1717 rc = LIBSSH2_ERROR_EAGAIN;
1721 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1722 failf(data, "Could not open directory for reading: %s",
1723 sftp_libssh2_strerror(err));
1724 state(conn, SSH_SFTP_CLOSE);
1725 result = sftp_libssh2_error_to_CURLE(err);
1726 sshc->actualcode = result?result:CURLE_SSH;
1730 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1731 state(conn, SSH_SFTP_CLOSE);
1732 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1735 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1736 Curl_safefree(sshc->readdir_filename);
1737 sshc->readdir_filename = NULL;
1738 state(conn, SSH_SFTP_CLOSE);
1739 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1742 state(conn, SSH_SFTP_READDIR);
1745 case SSH_SFTP_READDIR:
1746 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1747 sshc->readdir_filename,
1749 sshc->readdir_longentry,
1751 &sshc->readdir_attrs);
1752 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1753 rc = LIBSSH2_ERROR_EAGAIN;
1756 if(sshc->readdir_len > 0) {
1757 sshc->readdir_filename[sshc->readdir_len] = '\0';
1759 if(data->set.ftp_list_only) {
1762 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1763 if(tmpLine == NULL) {
1764 state(conn, SSH_SFTP_CLOSE);
1765 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1768 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1769 tmpLine, sshc->readdir_len+1);
1770 Curl_safefree(tmpLine);
1773 state(conn, SSH_STOP);
1776 /* since this counts what we send to the client, we include the
1777 newline in this counter */
1778 data->req.bytecount += sshc->readdir_len+1;
1780 /* output debug output if that is requested */
1781 if(data->set.verbose) {
1782 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1783 sshc->readdir_len, conn);
1787 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1788 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1789 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1790 if(!sshc->readdir_line) {
1791 Curl_safefree(sshc->readdir_filename);
1792 sshc->readdir_filename = NULL;
1793 Curl_safefree(sshc->readdir_longentry);
1794 sshc->readdir_longentry = NULL;
1795 state(conn, SSH_SFTP_CLOSE);
1796 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1800 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1801 sshc->readdir_currLen);
1802 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1803 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1804 LIBSSH2_SFTP_S_IFLNK)) {
1805 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1806 if(sshc->readdir_linkPath == NULL) {
1807 Curl_safefree(sshc->readdir_filename);
1808 sshc->readdir_filename = NULL;
1809 Curl_safefree(sshc->readdir_longentry);
1810 sshc->readdir_longentry = NULL;
1811 state(conn, SSH_SFTP_CLOSE);
1812 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1816 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1817 sshc->readdir_filename);
1818 state(conn, SSH_SFTP_READDIR_LINK);
1821 state(conn, SSH_SFTP_READDIR_BOTTOM);
1825 else if(sshc->readdir_len == 0) {
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_READDIR_DONE);
1833 else if(sshc->readdir_len <= 0) {
1834 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1835 result = sftp_libssh2_error_to_CURLE(err);
1836 sshc->actualcode = result?result:CURLE_SSH;
1837 failf(data, "Could not open remote file for reading: %s :: %d",
1838 sftp_libssh2_strerror(err),
1839 libssh2_session_last_errno(sshc->ssh_session));
1840 Curl_safefree(sshc->readdir_filename);
1841 sshc->readdir_filename = NULL;
1842 Curl_safefree(sshc->readdir_longentry);
1843 sshc->readdir_longentry = NULL;
1844 state(conn, SSH_SFTP_CLOSE);
1849 case SSH_SFTP_READDIR_LINK:
1851 libssh2_sftp_symlink_ex(sshc->sftp_session,
1852 sshc->readdir_linkPath,
1853 (unsigned int) strlen(sshc->readdir_linkPath),
1854 sshc->readdir_filename,
1855 PATH_MAX, LIBSSH2_SFTP_READLINK);
1856 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1857 rc = LIBSSH2_ERROR_EAGAIN;
1860 Curl_safefree(sshc->readdir_linkPath);
1861 sshc->readdir_linkPath = NULL;
1862 sshc->readdir_line = realloc(sshc->readdir_line,
1863 sshc->readdir_totalLen + 4 +
1865 if(!sshc->readdir_line) {
1866 Curl_safefree(sshc->readdir_filename);
1867 sshc->readdir_filename = NULL;
1868 Curl_safefree(sshc->readdir_longentry);
1869 sshc->readdir_longentry = NULL;
1870 state(conn, SSH_SFTP_CLOSE);
1871 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1875 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1876 sshc->readdir_currLen,
1877 sshc->readdir_totalLen -
1878 sshc->readdir_currLen,
1880 sshc->readdir_filename);
1882 state(conn, SSH_SFTP_READDIR_BOTTOM);
1885 case SSH_SFTP_READDIR_BOTTOM:
1886 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1887 sshc->readdir_currLen,
1888 sshc->readdir_totalLen -
1889 sshc->readdir_currLen, "\n");
1890 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1892 sshc->readdir_currLen);
1894 if(result == CURLE_OK) {
1896 /* output debug output if that is requested */
1897 if(data->set.verbose) {
1898 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1899 sshc->readdir_currLen, conn);
1901 data->req.bytecount += sshc->readdir_currLen;
1903 Curl_safefree(sshc->readdir_line);
1904 sshc->readdir_line = NULL;
1906 state(conn, SSH_STOP);
1909 state(conn, SSH_SFTP_READDIR);
1912 case SSH_SFTP_READDIR_DONE:
1913 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1914 LIBSSH2_ERROR_EAGAIN) {
1915 rc = LIBSSH2_ERROR_EAGAIN;
1918 sshc->sftp_handle = NULL;
1919 Curl_safefree(sshc->readdir_filename);
1920 sshc->readdir_filename = NULL;
1921 Curl_safefree(sshc->readdir_longentry);
1922 sshc->readdir_longentry = NULL;
1924 /* no data to transfer */
1925 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1926 state(conn, SSH_STOP);
1929 case SSH_SFTP_DOWNLOAD_INIT:
1931 * Work on getting the specified file
1934 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1935 (unsigned int)strlen(sftp_scp->path),
1936 LIBSSH2_FXF_READ, data->set.new_file_perms,
1937 LIBSSH2_SFTP_OPENFILE);
1938 if(!sshc->sftp_handle) {
1939 if(libssh2_session_last_errno(sshc->ssh_session) ==
1940 LIBSSH2_ERROR_EAGAIN) {
1941 rc = LIBSSH2_ERROR_EAGAIN;
1945 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1946 failf(data, "Could not open remote file for reading: %s",
1947 sftp_libssh2_strerror(err));
1948 state(conn, SSH_SFTP_CLOSE);
1949 result = sftp_libssh2_error_to_CURLE(err);
1950 sshc->actualcode = result?result:CURLE_SSH;
1954 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1957 case SSH_SFTP_DOWNLOAD_STAT:
1959 LIBSSH2_SFTP_ATTRIBUTES attrs;
1961 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1962 (unsigned int)strlen(sftp_scp->path),
1963 LIBSSH2_SFTP_STAT, &attrs);
1964 if(rc == LIBSSH2_ERROR_EAGAIN) {
1969 * libssh2_sftp_open() didn't return an error, so maybe the server
1970 * just doesn't support stat()
1972 data->req.size = -1;
1973 data->req.maxdownload = -1;
1976 curl_off_t size = attrs.filesize;
1979 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1980 return CURLE_BAD_DOWNLOAD_RESUME;
1982 if(conn->data->state.use_range) {
1983 curl_off_t from, to;
1987 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1988 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
1990 to=curlx_strtoofft(ptr, &ptr2, 0);
1991 if((ptr == ptr2) /* no "to" value given */
1996 /* from is relative to end of file */
2000 failf(data, "Offset (%"
2001 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2002 from, attrs.filesize);
2003 return CURLE_BAD_DOWNLOAD_RESUME;
2010 size = to - from + 1;
2013 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2015 data->req.size = size;
2016 data->req.maxdownload = size;
2017 Curl_pgrsSetDownloadSize(data, size);
2020 /* We can resume if we can seek to the resume position */
2021 if(data->state.resume_from) {
2022 if(data->state.resume_from < 0) {
2023 /* We're supposed to download the last abs(from) bytes */
2024 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2025 failf(data, "Offset (%"
2026 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2027 data->state.resume_from, attrs.filesize);
2028 return CURLE_BAD_DOWNLOAD_RESUME;
2030 /* download from where? */
2031 data->state.resume_from += attrs.filesize;
2034 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2035 failf(data, "Offset (%" FORMAT_OFF_T
2036 ") was beyond file size (%" FORMAT_OFF_T ")",
2037 data->state.resume_from, attrs.filesize);
2038 return CURLE_BAD_DOWNLOAD_RESUME;
2041 /* Does a completed file need to be seeked and started or closed ? */
2042 /* Now store the number of bytes we are expected to download */
2043 data->req.size = attrs.filesize - data->state.resume_from;
2044 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2045 Curl_pgrsSetDownloadSize(data,
2046 attrs.filesize - data->state.resume_from);
2047 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2050 /* Setup the actual download */
2051 if(data->req.size == 0) {
2052 /* no data to transfer */
2053 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2054 infof(data, "File already completely downloaded\n");
2055 state(conn, SSH_STOP);
2059 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2060 FALSE, NULL, -1, NULL);
2062 /* not set by Curl_setup_transfer to preserve keepon bits */
2063 conn->writesockfd = conn->sockfd;
2065 /* we want to use the _receiving_ function even when the socket turns
2066 out writableable as the underlying libssh2 recv function will deal
2067 with both accordingly */
2068 conn->cselect_bits = CURL_CSELECT_IN;
2071 state(conn, SSH_SFTP_CLOSE);
2072 sshc->actualcode = result;
2075 state(conn, SSH_STOP);
2079 case SSH_SFTP_CLOSE:
2080 if(sshc->sftp_handle) {
2081 rc = libssh2_sftp_close(sshc->sftp_handle);
2082 if(rc == LIBSSH2_ERROR_EAGAIN) {
2086 infof(data, "Failed to close libssh2 file\n");
2088 sshc->sftp_handle = NULL;
2091 Curl_safefree(sftp_scp->path);
2092 sftp_scp->path = NULL;
2095 DEBUGF(infof(data, "SFTP DONE done\n"));
2097 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2098 After nextstate is executed,the control should come back to
2099 SSH_SFTP_CLOSE to pass the correct result back */
2100 if(sshc->nextstate != SSH_NO_STATE) {
2101 state(conn, sshc->nextstate);
2102 sshc->nextstate = SSH_SFTP_CLOSE;
2105 state(conn, SSH_STOP);
2106 result = sshc->actualcode;
2110 case SSH_SFTP_SHUTDOWN:
2111 /* during times we get here due to a broken transfer and then the
2112 sftp_handle might not have been taken down so make sure that is done
2113 before we proceed */
2115 if(sshc->sftp_handle) {
2116 rc = libssh2_sftp_close(sshc->sftp_handle);
2117 if(rc == LIBSSH2_ERROR_EAGAIN) {
2121 infof(data, "Failed to close libssh2 file\n");
2123 sshc->sftp_handle = NULL;
2125 if(sshc->sftp_session) {
2126 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2127 if(rc == LIBSSH2_ERROR_EAGAIN) {
2131 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2133 sshc->sftp_session = NULL;
2136 Curl_safefree(sshc->homedir);
2137 sshc->homedir = NULL;
2138 conn->data->state.most_recent_ftp_entrypath = NULL;
2140 state(conn, SSH_SESSION_DISCONNECT);
2143 case SSH_SCP_TRANS_INIT:
2144 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2146 sshc->actualcode = result;
2147 state(conn, SSH_STOP);
2151 if(data->set.upload) {
2152 if(data->set.infilesize < 0) {
2153 failf(data, "SCP requires a known file size for upload");
2154 sshc->actualcode = CURLE_UPLOAD_FAILED;
2155 state(conn, SSH_SCP_CHANNEL_FREE);
2158 state(conn, SSH_SCP_UPLOAD_INIT);
2161 state(conn, SSH_SCP_DOWNLOAD_INIT);
2165 case SSH_SCP_UPLOAD_INIT:
2167 * libssh2 requires that the destination path is a full path that
2168 * includes the destination file and name OR ends in a "/" . If this is
2169 * not done the destination file will be named the same name as the last
2170 * directory in the path.
2173 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2174 data->set.infilesize);
2175 if(!sshc->ssh_channel) {
2176 if(libssh2_session_last_errno(sshc->ssh_session) ==
2177 LIBSSH2_ERROR_EAGAIN) {
2178 rc = LIBSSH2_ERROR_EAGAIN;
2185 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2186 &err_msg, NULL, 0));
2187 failf(conn->data, "%s", err_msg);
2188 state(conn, SSH_SCP_CHANNEL_FREE);
2189 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2195 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2198 /* not set by Curl_setup_transfer to preserve keepon bits */
2199 conn->sockfd = conn->writesockfd;
2202 state(conn, SSH_SCP_CHANNEL_FREE);
2203 sshc->actualcode = result;
2206 /* we want to use the _sending_ function even when the socket turns
2207 out readable as the underlying libssh2 scp send function will deal
2208 with both accordingly */
2209 conn->cselect_bits = CURL_CSELECT_OUT;
2211 state(conn, SSH_STOP);
2215 case SSH_SCP_DOWNLOAD_INIT:
2218 * We must check the remote file; if it is a directory no values will
2222 curl_off_t bytecount;
2224 /* clear the struct scp recv will fill in */
2225 memset(&sb, 0, sizeof(struct stat));
2227 /* get a fresh new channel from the ssh layer */
2228 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2229 sftp_scp->path, &sb);
2230 if(!sshc->ssh_channel) {
2231 if(libssh2_session_last_errno(sshc->ssh_session) ==
2232 LIBSSH2_ERROR_EAGAIN) {
2233 rc = LIBSSH2_ERROR_EAGAIN;
2240 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2241 &err_msg, NULL, 0));
2242 failf(conn->data, "%s", err_msg);
2243 state(conn, SSH_SCP_CHANNEL_FREE);
2244 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2250 bytecount = (curl_off_t)sb.st_size;
2251 data->req.maxdownload = (curl_off_t)sb.st_size;
2252 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2254 /* not set by Curl_setup_transfer to preserve keepon bits */
2255 conn->writesockfd = conn->sockfd;
2257 /* we want to use the _receiving_ function even when the socket turns
2258 out writableable as the underlying libssh2 recv function will deal
2259 with both accordingly */
2260 conn->cselect_bits = CURL_CSELECT_IN;
2263 state(conn, SSH_SCP_CHANNEL_FREE);
2264 sshc->actualcode = result;
2267 state(conn, SSH_STOP);
2272 if(data->set.upload)
2273 state(conn, SSH_SCP_SEND_EOF);
2275 state(conn, SSH_SCP_CHANNEL_FREE);
2278 case SSH_SCP_SEND_EOF:
2279 if(sshc->ssh_channel) {
2280 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2281 if(rc == LIBSSH2_ERROR_EAGAIN) {
2285 infof(data, "Failed to send libssh2 channel EOF\n");
2288 state(conn, SSH_SCP_WAIT_EOF);
2291 case SSH_SCP_WAIT_EOF:
2292 if(sshc->ssh_channel) {
2293 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2294 if(rc == LIBSSH2_ERROR_EAGAIN) {
2298 infof(data, "Failed to get channel EOF: %d\n", rc);
2301 state(conn, SSH_SCP_WAIT_CLOSE);
2304 case SSH_SCP_WAIT_CLOSE:
2305 if(sshc->ssh_channel) {
2306 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2307 if(rc == LIBSSH2_ERROR_EAGAIN) {
2311 infof(data, "Channel failed to close: %d\n", rc);
2314 state(conn, SSH_SCP_CHANNEL_FREE);
2317 case SSH_SCP_CHANNEL_FREE:
2318 if(sshc->ssh_channel) {
2319 rc = libssh2_channel_free(sshc->ssh_channel);
2320 if(rc == LIBSSH2_ERROR_EAGAIN) {
2324 infof(data, "Failed to free libssh2 scp subsystem\n");
2326 sshc->ssh_channel = NULL;
2328 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2330 state(conn, SSH_SESSION_DISCONNECT);
2332 state(conn, SSH_STOP);
2333 result = sshc->actualcode;
2336 case SSH_SESSION_DISCONNECT:
2337 /* during weird times when we've been prematurely aborted, the channel
2338 is still alive when we reach this state and we MUST kill the channel
2340 if(sshc->ssh_channel) {
2341 rc = libssh2_channel_free(sshc->ssh_channel);
2342 if(rc == LIBSSH2_ERROR_EAGAIN) {
2346 infof(data, "Failed to free libssh2 scp subsystem\n");
2348 sshc->ssh_channel = NULL;
2351 if(sshc->ssh_session) {
2352 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2353 if(rc == LIBSSH2_ERROR_EAGAIN) {
2357 infof(data, "Failed to disconnect libssh2 session\n");
2361 Curl_safefree(sshc->homedir);
2362 sshc->homedir = NULL;
2363 conn->data->state.most_recent_ftp_entrypath = NULL;
2365 state(conn, SSH_SESSION_FREE);
2368 case SSH_SESSION_FREE:
2369 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2371 libssh2_knownhost_free(sshc->kh);
2376 if(sshc->ssh_session) {
2377 rc = libssh2_session_free(sshc->ssh_session);
2378 if(rc == LIBSSH2_ERROR_EAGAIN) {
2382 infof(data, "Failed to free libssh2 session\n");
2384 sshc->ssh_session = NULL;
2386 conn->bits.close = TRUE;
2387 sshc->nextstate = SSH_NO_STATE;
2388 state(conn, SSH_STOP);
2389 result = sshc->actualcode;
2393 /* fallthrough, just stop! */
2395 /* internal error */
2396 sshc->nextstate = SSH_NO_STATE;
2397 state(conn, SSH_STOP);
2401 } while(!rc && (sshc->state != SSH_STOP));
2403 if(rc == LIBSSH2_ERROR_EAGAIN) {
2404 /* we would block, we need to wait for the socket to be ready (in the
2405 right direction too)! */
2412 /* called by the multi interface to figure out what socket(s) to wait for and
2413 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2414 static int ssh_perform_getsock(const struct connectdata *conn,
2415 curl_socket_t *sock, /* points to numsocks
2416 number of sockets */
2419 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2420 int bitmap = GETSOCK_BLANK;
2423 sock[0] = conn->sock[FIRSTSOCKET];
2425 if(conn->waitfor & KEEP_RECV)
2426 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2428 if(conn->waitfor & KEEP_SEND)
2429 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2433 /* if we don't know the direction we can use the generic *_getsock()
2434 function even for the protocol_connect and doing states */
2435 return Curl_single_getsock(conn, sock, numsocks);
2439 /* Generic function called by the multi interface to figure out what socket(s)
2440 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2441 static int ssh_getsock(struct connectdata *conn,
2442 curl_socket_t *sock, /* points to numsocks number
2446 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2450 /* if we don't know any direction we can just play along as we used to and
2451 not provide any sensible info */
2452 return GETSOCK_BLANK;
2454 /* if we know the direction we can use the generic *_getsock() function even
2455 for the protocol_connect and doing states */
2456 return ssh_perform_getsock(conn, sock, numsocks);
2460 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2462 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2463 * function is used to figure out in what direction and stores this info so
2464 * that the multi interface can take advantage of it. Make sure to call this
2465 * function in all cases so that when it _doesn't_ return EAGAIN we can
2466 * restore the default wait bits.
2468 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2470 struct ssh_conn *sshc = &conn->proto.sshc;
2474 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2475 /* translate the libssh2 define bits into our own bit defines */
2476 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2477 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2480 /* It didn't block or libssh2 didn't reveal in which direction, put back
2482 conn->waitfor = sshc->orig_waitfor;
2485 /* no libssh2 directional support so we simply don't know */
2486 #define ssh_block2waitfor(x,y)
2489 /* called repeatedly until done from multi.c */
2490 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2492 struct ssh_conn *sshc = &conn->proto.sshc;
2493 CURLcode result = CURLE_OK;
2494 bool block; /* we store the status and use that to provide a ssh_getsock()
2497 result = ssh_statemach_act(conn, &block);
2498 *done = (bool)(sshc->state == SSH_STOP);
2499 ssh_block2waitfor(conn, block);
2504 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2507 struct ssh_conn *sshc = &conn->proto.sshc;
2508 CURLcode result = CURLE_OK;
2509 struct SessionHandle *data = conn->data;
2511 while((sshc->state != SSH_STOP) && !result) {
2515 result = ssh_statemach_act(conn, &block);
2519 if(Curl_pgrsUpdate(conn))
2520 return CURLE_ABORTED_BY_CALLBACK;
2522 struct timeval now = Curl_tvnow();
2523 result = Curl_speedcheck(data, now);
2528 left = Curl_timeleft(data, NULL, duringconnect);
2530 failf(data, "Operation timed out\n");
2531 return CURLE_OPERATION_TIMEDOUT;
2534 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2535 if((CURLE_OK == result) && block) {
2536 int dir = libssh2_session_block_directions(sshc->ssh_session);
2537 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2538 curl_socket_t fd_read = CURL_SOCKET_BAD;
2539 curl_socket_t fd_write = CURL_SOCKET_BAD;
2540 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2542 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2544 /* wait for the socket to become ready */
2545 Curl_socket_ready(fd_read, fd_write,
2546 left>1000?1000:left); /* ignore result */
2556 * SSH setup and connection
2558 static CURLcode ssh_init(struct connectdata *conn)
2560 struct SessionHandle *data = conn->data;
2561 struct SSHPROTO *ssh;
2562 struct ssh_conn *sshc = &conn->proto.sshc;
2564 sshc->actualcode = CURLE_OK; /* reset error code */
2565 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2568 if(data->state.proto.ssh)
2571 ssh = calloc(1, sizeof(struct SSHPROTO));
2573 return CURLE_OUT_OF_MEMORY;
2575 data->state.proto.ssh = ssh;
2580 static Curl_recv scp_recv, sftp_recv;
2581 static Curl_send scp_send, sftp_send;
2584 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2585 * do protocol-specific actions at connect-time.
2587 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2589 #ifdef CURL_LIBSSH2_DEBUG
2592 struct ssh_conn *ssh;
2594 struct SessionHandle *data = conn->data;
2596 /* We default to persistent connections. We set this already in this connect
2597 function to make the re-use checks properly be able to check this bit. */
2598 conn->bits.close = FALSE;
2600 /* If there already is a protocol-specific struct allocated for this
2601 sessionhandle, deal with it */
2602 Curl_reset_reqproto(conn);
2604 result = ssh_init(conn);
2608 if(conn->handler->protocol & CURLPROTO_SCP) {
2609 conn->recv[FIRSTSOCKET] = scp_recv;
2610 conn->send[FIRSTSOCKET] = scp_send;
2613 conn->recv[FIRSTSOCKET] = sftp_recv;
2614 conn->send[FIRSTSOCKET] = sftp_send;
2616 ssh = &conn->proto.sshc;
2618 #ifdef CURL_LIBSSH2_DEBUG
2620 infof(data, "User: %s\n", conn->user);
2623 infof(data, "Password: %s\n", conn->passwd);
2625 sock = conn->sock[FIRSTSOCKET];
2626 #endif /* CURL_LIBSSH2_DEBUG */
2628 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2630 my_libssh2_realloc, conn);
2631 if(ssh->ssh_session == NULL) {
2632 failf(data, "Failure initialising ssh session");
2633 return CURLE_FAILED_INIT;
2636 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2637 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2639 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2641 /* eeek. TODO: free the ssh_session! */
2642 return CURLE_FAILED_INIT;
2645 /* read all known hosts from there */
2646 rc = libssh2_knownhost_readfile(ssh->kh,
2647 data->set.str[STRING_SSH_KNOWNHOSTS],
2648 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2650 infof(data, "Failed to read known hosts from %s\n",
2651 data->set.str[STRING_SSH_KNOWNHOSTS]);
2653 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2655 #ifdef CURL_LIBSSH2_DEBUG
2656 libssh2_trace(ssh->ssh_session, ~0);
2657 infof(data, "SSH socket: %d\n", (int)sock);
2658 #endif /* CURL_LIBSSH2_DEBUG */
2660 state(conn, SSH_INIT);
2662 if(data->state.used_interface == Curl_if_multi)
2663 result = ssh_multi_statemach(conn, done);
2665 result = ssh_easy_statemach(conn, TRUE);
2674 ***********************************************************************
2678 * This is the actual DO function for SCP. Get a file according to
2679 * the options previously setup.
2683 CURLcode scp_perform(struct connectdata *conn,
2687 CURLcode result = CURLE_OK;
2689 DEBUGF(infof(conn->data, "DO phase starts\n"));
2691 *dophase_done = FALSE; /* not done yet */
2693 /* start the first command in the DO phase */
2694 state(conn, SSH_SCP_TRANS_INIT);
2696 /* run the state-machine */
2697 if(conn->data->state.used_interface == Curl_if_multi) {
2698 result = ssh_multi_statemach(conn, dophase_done);
2701 result = ssh_easy_statemach(conn, FALSE);
2702 *dophase_done = TRUE; /* with the easy interface we are done here */
2704 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2707 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2713 /* called from multi.c while DOing */
2714 static CURLcode scp_doing(struct connectdata *conn,
2718 result = ssh_multi_statemach(conn, dophase_done);
2721 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2727 * The DO function is generic for both protocols. There was previously two
2728 * separate ones but this way means less duplicated code.
2731 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2735 struct SessionHandle *data = conn->data;
2737 *done = FALSE; /* default to false */
2740 Since connections can be re-used between SessionHandles, this might be a
2741 connection already existing but on a fresh SessionHandle struct so we must
2742 make sure we have a good 'struct SSHPROTO' to play with. For new
2743 connections, the struct SSHPROTO is allocated and setup in the
2744 ssh_connect() function.
2746 Curl_reset_reqproto(conn);
2747 res = ssh_init(conn);
2751 data->req.size = -1; /* make sure this is unknown at this point */
2753 Curl_pgrsSetUploadCounter(data, 0);
2754 Curl_pgrsSetDownloadCounter(data, 0);
2755 Curl_pgrsSetUploadSize(data, 0);
2756 Curl_pgrsSetDownloadSize(data, 0);
2758 if(conn->handler->protocol & CURLPROTO_SCP)
2759 res = scp_perform(conn, &connected, done);
2761 res = sftp_perform(conn, &connected, done);
2766 /* BLOCKING, but the function is using the state machine so the only reason
2767 this is still blocking is that the multi interface code has no support for
2768 disconnecting operations that takes a while */
2769 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2771 CURLcode result = CURLE_OK;
2772 struct ssh_conn *ssh = &conn->proto.sshc;
2773 (void) dead_connection;
2775 Curl_safefree(conn->data->state.proto.ssh);
2776 conn->data->state.proto.ssh = NULL;
2778 if(ssh->ssh_session) {
2779 /* only if there's a session still around to use! */
2781 state(conn, SSH_SESSION_DISCONNECT);
2783 result = ssh_easy_statemach(conn, FALSE);
2789 /* generic done function for both SCP and SFTP called from their specific
2791 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2793 CURLcode result = CURLE_OK;
2794 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2796 if(status == CURLE_OK) {
2797 /* run the state-machine
2799 TODO: when the multi interface is used, this _really_ should be using
2800 the ssh_multi_statemach function but we have no general support for
2801 non-blocking DONE operations, not in the multi state machine and with
2802 Curl_done() invokes on several places in the code!
2804 result = ssh_easy_statemach(conn, FALSE);
2810 Curl_safefree(sftp_scp->path);
2811 sftp_scp->path = NULL;
2813 Curl_pgrsDone(conn);
2815 conn->data->req.keepon = 0; /* clear all bits */
2820 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2823 (void)premature; /* not used */
2825 if(status == CURLE_OK)
2826 state(conn, SSH_SCP_DONE);
2828 return ssh_done(conn, status);
2832 /* return number of received (decrypted) bytes */
2833 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2834 const void *mem, size_t len, CURLcode *err)
2837 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2839 /* libssh2_channel_write() returns int! */
2841 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2843 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2845 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2854 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2855 * a regular CURLcode value.
2857 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2858 char *mem, size_t len, CURLcode *err)
2861 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2863 /* libssh2_channel_read() returns int */
2865 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2867 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2868 if(nread == LIBSSH2_ERROR_EAGAIN) {
2877 * =============== SFTP ===============
2881 ***********************************************************************
2885 * This is the actual DO function for SFTP. Get a file/directory according to
2886 * the options previously setup.
2890 CURLcode sftp_perform(struct connectdata *conn,
2894 CURLcode result = CURLE_OK;
2896 DEBUGF(infof(conn->data, "DO phase starts\n"));
2898 *dophase_done = FALSE; /* not done yet */
2900 /* start the first command in the DO phase */
2901 state(conn, SSH_SFTP_QUOTE_INIT);
2903 /* run the state-machine */
2904 if(conn->data->state.used_interface == Curl_if_multi) {
2905 result = ssh_multi_statemach(conn, dophase_done);
2908 result = ssh_easy_statemach(conn, FALSE);
2909 *dophase_done = TRUE; /* with the easy interface we are done here */
2911 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2914 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2920 /* called from multi.c while DOing */
2921 static CURLcode sftp_doing(struct connectdata *conn,
2925 result = ssh_multi_statemach(conn, dophase_done);
2928 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2933 /* BLOCKING, but the function is using the state machine so the only reason
2934 this is still blocking is that the multi interface code has no support for
2935 disconnecting operations that takes a while */
2936 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
2938 CURLcode result = CURLE_OK;
2939 (void) dead_connection;
2941 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2943 Curl_safefree(conn->data->state.proto.ssh);
2944 conn->data->state.proto.ssh = NULL;
2946 if(conn->proto.sshc.ssh_session) {
2947 /* only if there's a session still around to use! */
2948 state(conn, SSH_SFTP_SHUTDOWN);
2949 result = ssh_easy_statemach(conn, FALSE);
2952 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2958 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2961 struct ssh_conn *sshc = &conn->proto.sshc;
2963 if(status == CURLE_OK) {
2964 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
2965 errors that could happen due to open file handles during POSTQUOTE
2967 if(!status && !premature && conn->data->set.postquote) {
2968 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
2969 state(conn, SSH_SFTP_CLOSE);
2972 state(conn, SSH_SFTP_CLOSE);
2974 return ssh_done(conn, status);
2977 /* return number of sent bytes */
2978 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
2979 const void *mem, size_t len, CURLcode *err)
2981 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2982 but is changed to ssize_t in 0.15. These days we don't
2983 support libssh2 0.15*/
2986 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2988 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2990 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2999 * Return number of received (decrypted) bytes
3001 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3002 char *mem, size_t len, CURLcode *err)
3007 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3009 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3011 if(nread == LIBSSH2_ERROR_EAGAIN) {
3018 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3021 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3023 * Permission to use, copy, modify, and distribute this software for any
3024 * purpose with or without fee is hereby granted, provided that the above
3025 * copyright notice and this permission notice appear in all copies.
3027 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3028 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3029 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3030 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3031 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3032 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3033 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3036 get_pathname(const char **cpp, char **path)
3038 const char *cp = *cpp, *end;
3041 static const char WHITESPACE[] = " \t\r\n";
3043 cp += strspn(cp, WHITESPACE);
3047 return CURLE_QUOTE_ERROR;
3050 *path = malloc(strlen(cp) + 1);
3052 return CURLE_OUT_OF_MEMORY;
3054 /* Check for quoted filenames */
3055 if(*cp == '\"' || *cp == '\'') {
3058 /* Search for terminating quote, unescape some chars */
3059 for(i = j = 0; i <= strlen(cp); i++) {
3060 if(cp[i] == quot) { /* Found quote */
3065 if(cp[i] == '\0') { /* End of string */
3066 /*error("Unterminated quote");*/
3069 if(cp[i] == '\\') { /* Escaped characters */
3071 if(cp[i] != '\'' && cp[i] != '\"' &&
3073 /*error("Bad escaped character '\\%c'",
3078 (*path)[j++] = cp[i];
3082 /*error("Empty quotes");*/
3085 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3088 /* Read to end of filename */
3089 end = strpbrk(cp, WHITESPACE);
3091 end = strchr(cp, '\0');
3092 *cpp = end + strspn(end, WHITESPACE);
3094 memcpy(*path, cp, end - cp);
3095 (*path)[end - cp] = '\0';
3100 Curl_safefree(*path);
3102 return CURLE_QUOTE_ERROR;
3106 static const char *sftp_libssh2_strerror(unsigned long err)
3109 case LIBSSH2_FX_NO_SUCH_FILE:
3110 return "No such file or directory";
3112 case LIBSSH2_FX_PERMISSION_DENIED:
3113 return "Permission denied";
3115 case LIBSSH2_FX_FAILURE:
3116 return "Operation failed";
3118 case LIBSSH2_FX_BAD_MESSAGE:
3119 return "Bad message from SFTP server";
3121 case LIBSSH2_FX_NO_CONNECTION:
3122 return "Not connected to SFTP server";
3124 case LIBSSH2_FX_CONNECTION_LOST:
3125 return "Connection to SFTP server lost";
3127 case LIBSSH2_FX_OP_UNSUPPORTED:
3128 return "Operation not supported by SFTP server";
3130 case LIBSSH2_FX_INVALID_HANDLE:
3131 return "Invalid handle";
3133 case LIBSSH2_FX_NO_SUCH_PATH:
3134 return "No such file or directory";
3136 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3137 return "File already exists";
3139 case LIBSSH2_FX_WRITE_PROTECT:
3140 return "File is write protected";
3142 case LIBSSH2_FX_NO_MEDIA:
3145 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3148 case LIBSSH2_FX_QUOTA_EXCEEDED:
3149 return "User quota exceeded";
3151 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3152 return "Unknown principle";
3154 case LIBSSH2_FX_LOCK_CONFlICT:
3155 return "File lock conflict";
3157 case LIBSSH2_FX_DIR_NOT_EMPTY:
3158 return "Directory not empty";
3160 case LIBSSH2_FX_NOT_A_DIRECTORY:
3161 return "Not a directory";
3163 case LIBSSH2_FX_INVALID_FILENAME:
3164 return "Invalid filename";
3166 case LIBSSH2_FX_LINK_LOOP:
3167 return "Link points to itself";
3169 return "Unknown error in libssh2";
3172 #endif /* USE_LIBSSH2 */