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 char *new_readdir_line;
648 int rc = LIBSSH2_ERROR_NONE, i;
650 int seekerr = CURL_SEEKFUNC_OK;
651 *block = 0; /* we're not blocking by default */
655 switch(sshc->state) {
657 sshc->secondCreateDirs = 0;
658 sshc->nextstate = SSH_NO_STATE;
659 sshc->actualcode = CURLE_OK;
661 /* Set libssh2 to non-blocking, since everything internally is
663 libssh2_session_set_blocking(sshc->ssh_session, 0);
665 state(conn, SSH_S_STARTUP);
669 rc = libssh2_session_startup(sshc->ssh_session, sock);
670 if(rc == LIBSSH2_ERROR_EAGAIN) {
674 failf(data, "Failure establishing ssh session");
675 state(conn, SSH_SESSION_FREE);
676 sshc->actualcode = CURLE_FAILED_INIT;
680 state(conn, SSH_HOSTKEY);
685 #ifdef CURL_LIBSSH2_DEBUG
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. As for know not much is implemented, besides
690 * showing how to get the fingerprint.
692 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
693 LIBSSH2_HOSTKEY_HASH_MD5);
695 /* The fingerprint points to static storage (!), don't free() it. */
696 infof(data, "Fingerprint: ");
697 for(rc = 0; rc < 16; rc++)
698 infof(data, "%02X ", (unsigned char) fingerprint[rc]);
700 #endif /* CURL_LIBSSH2_DEBUG */
702 /* Before we authenticate we check the hostkey's MD5 fingerprint
703 * against a known fingerprint, if available. This implementation pulls
704 * it from the curl option.
706 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
707 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
709 host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
710 LIBSSH2_HOSTKEY_HASH_MD5);
711 for(i = 0; i < 16; i++)
712 snprintf(&buf[i*2], 3, "%02x",
713 (unsigned char) host_public_key_md5[i]);
714 if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
716 "Denied establishing ssh session: mismatch md5 fingerprint. "
717 "Remote %s is not equal to %s",
718 buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
719 state(conn, SSH_SESSION_FREE);
720 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
725 result = ssh_knownhost(conn);
727 state(conn, SSH_AUTHLIST);
732 * Figure out authentication methods
733 * NB: As soon as we have provided a username to an openssh server we
734 * must never change it later. Thus, always specify the correct username
735 * here, even though the libssh2 docs kind of indicate that it should be
736 * possible to get a 'generic' list (not user-specific) of authentication
737 * methods, presumably with a blank username. That won't work in my
739 * So always specify it here.
741 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
743 (unsigned int)strlen(conn->user));
745 if(!sshc->authlist) {
746 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
747 LIBSSH2_ERROR_EAGAIN) {
748 rc = LIBSSH2_ERROR_EAGAIN;
752 state(conn, SSH_SESSION_FREE);
753 sshc->actualcode = libssh2_session_error_to_CURLE(err);
757 infof(data, "SSH authentication methods available: %s\n",
760 state(conn, SSH_AUTH_PKEY_INIT);
763 case SSH_AUTH_PKEY_INIT:
765 * Check the supported auth types in the order I feel is most secure
766 * with the requested type of authentication
768 sshc->authed = FALSE;
770 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
771 (strstr(sshc->authlist, "publickey") != NULL)) {
774 sshc->rsa_pub = sshc->rsa = NULL;
776 /* To ponder about: should really the lib be messing about with the
777 HOME environment variable etc? */
778 home = curl_getenv("HOME");
780 if(data->set.str[STRING_SSH_PUBLIC_KEY])
781 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
783 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
785 /* as a final resort, try current dir! */
786 sshc->rsa_pub = strdup("id_dsa.pub");
788 if(sshc->rsa_pub == NULL) {
791 state(conn, SSH_SESSION_FREE);
792 sshc->actualcode = CURLE_OUT_OF_MEMORY;
796 if(data->set.str[STRING_SSH_PRIVATE_KEY])
797 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
799 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
801 /* as a final resort, try current dir! */
802 sshc->rsa = strdup("id_dsa");
804 if(sshc->rsa == NULL) {
807 Curl_safefree(sshc->rsa_pub);
808 sshc->rsa_pub = NULL;
809 state(conn, SSH_SESSION_FREE);
810 sshc->actualcode = CURLE_OUT_OF_MEMORY;
814 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
815 if(!sshc->passphrase)
816 sshc->passphrase = "";
821 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
822 infof(data, "Using ssh private key file %s\n", sshc->rsa);
824 state(conn, SSH_AUTH_PKEY);
827 state(conn, SSH_AUTH_PASS_INIT);
832 /* The function below checks if the files exists, no need to stat() here.
834 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
839 sshc->rsa, sshc->passphrase);
840 if(rc == LIBSSH2_ERROR_EAGAIN) {
844 Curl_safefree(sshc->rsa_pub);
845 sshc->rsa_pub = NULL;
846 Curl_safefree(sshc->rsa);
851 infof(data, "Initialized SSH public key authentication\n");
852 state(conn, SSH_AUTH_DONE);
856 (void)libssh2_session_last_error(sshc->ssh_session,
858 infof(data, "SSH public key authentication failed: %s\n", err_msg);
859 state(conn, SSH_AUTH_PASS_INIT);
863 case SSH_AUTH_PASS_INIT:
864 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
865 (strstr(sshc->authlist, "password") != NULL)) {
866 state(conn, SSH_AUTH_PASS);
869 state(conn, SSH_AUTH_HOST_INIT);
874 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
875 (unsigned int)strlen(conn->user),
877 (unsigned int)strlen(conn->passwd),
879 if(rc == LIBSSH2_ERROR_EAGAIN) {
884 infof(data, "Initialized password authentication\n");
885 state(conn, SSH_AUTH_DONE);
888 state(conn, SSH_AUTH_HOST_INIT);
892 case SSH_AUTH_HOST_INIT:
893 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
894 (strstr(sshc->authlist, "hostbased") != NULL)) {
895 state(conn, SSH_AUTH_HOST);
898 state(conn, SSH_AUTH_KEY_INIT);
903 state(conn, SSH_AUTH_KEY_INIT);
906 case SSH_AUTH_KEY_INIT:
907 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
908 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
909 state(conn, SSH_AUTH_KEY);
912 state(conn, SSH_AUTH_DONE);
917 /* Authentication failed. Continue with keyboard-interactive now. */
918 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
923 if(rc == LIBSSH2_ERROR_EAGAIN) {
928 infof(data, "Initialized keyboard interactive authentication\n");
930 state(conn, SSH_AUTH_DONE);
935 failf(data, "Authentication failure");
936 state(conn, SSH_SESSION_FREE);
937 sshc->actualcode = CURLE_LOGIN_DENIED;
942 * At this point we have an authenticated ssh session.
944 infof(data, "Authentication complete\n");
946 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
949 conn->writesockfd = CURL_SOCKET_BAD;
951 if(conn->handler->protocol == CURLPROTO_SFTP) {
952 state(conn, SSH_SFTP_INIT);
955 infof(data, "SSH CONNECT phase done\n");
956 state(conn, SSH_STOP);
961 * Start the libssh2 sftp session
963 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
964 if(!sshc->sftp_session) {
965 if(libssh2_session_last_errno(sshc->ssh_session) ==
966 LIBSSH2_ERROR_EAGAIN) {
967 rc = LIBSSH2_ERROR_EAGAIN;
973 (void)libssh2_session_last_error(sshc->ssh_session,
975 failf(data, "Failure initializing sftp session: %s", err_msg);
976 state(conn, SSH_SESSION_FREE);
977 sshc->actualcode = CURLE_FAILED_INIT;
981 state(conn, SSH_SFTP_REALPATH);
984 case SSH_SFTP_REALPATH:
986 char tempHome[PATH_MAX];
989 * Get the "home" directory
991 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
992 tempHome, PATH_MAX-1);
993 if(rc == LIBSSH2_ERROR_EAGAIN) {
997 /* It seems that this string is not always NULL terminated */
999 sshc->homedir = strdup(tempHome);
1000 if(!sshc->homedir) {
1001 state(conn, SSH_SFTP_CLOSE);
1002 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1005 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1008 /* Return the error type */
1009 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1010 result = sftp_libssh2_error_to_CURLE(err);
1011 sshc->actualcode = result?result:CURLE_SSH;
1012 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1014 state(conn, SSH_STOP);
1018 /* This is the last step in the SFTP connect phase. Do note that while
1019 we get the homedir here, we get the "workingpath" in the DO action
1020 since the homedir will remain the same between request but the
1021 working path will not. */
1022 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1023 state(conn, SSH_STOP);
1026 case SSH_SFTP_QUOTE_INIT:
1028 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1030 sshc->actualcode = result;
1031 state(conn, SSH_STOP);
1035 if(data->set.quote) {
1036 infof(data, "Sending quote commands\n");
1037 sshc->quote_item = data->set.quote;
1038 state(conn, SSH_SFTP_QUOTE);
1041 state(conn, SSH_SFTP_TRANS_INIT);
1045 case SSH_SFTP_POSTQUOTE_INIT:
1046 if(data->set.postquote) {
1047 infof(data, "Sending quote commands\n");
1048 sshc->quote_item = data->set.postquote;
1049 state(conn, SSH_SFTP_QUOTE);
1052 state(conn, SSH_STOP);
1056 case SSH_SFTP_QUOTE:
1057 /* Send any quote commands */
1062 * Support some of the "FTP" commands
1064 if(curl_strequal("pwd", sshc->quote_item->data)) {
1065 /* output debug output if that is requested */
1066 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1069 result = CURLE_OUT_OF_MEMORY;
1070 state(conn, SSH_SFTP_CLOSE);
1071 sshc->nextstate = SSH_NO_STATE;
1074 if(data->set.verbose) {
1075 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1076 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1078 /* this sends an FTP-like "header" to the header callback so that the
1079 current directory can be read very similar to how it is read when
1080 using ordinary FTP. */
1081 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1083 state(conn, SSH_SFTP_NEXT_QUOTE);
1086 else if(sshc->quote_item->data) {
1088 * the arguments following the command must be separated from the
1089 * command with a space so we can check for it unconditionally
1091 cp = strchr(sshc->quote_item->data, ' ');
1093 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1094 state(conn, SSH_SFTP_CLOSE);
1095 sshc->nextstate = SSH_NO_STATE;
1096 sshc->actualcode = CURLE_QUOTE_ERROR;
1101 * also, every command takes at least one argument so we get that
1102 * first argument right now
1104 result = get_pathname(&cp, &sshc->quote_path1);
1106 if(result == CURLE_OUT_OF_MEMORY)
1107 failf(data, "Out of memory");
1109 failf(data, "Syntax error: Bad first parameter");
1110 state(conn, SSH_SFTP_CLOSE);
1111 sshc->nextstate = SSH_NO_STATE;
1112 sshc->actualcode = result;
1117 * SFTP is a binary protocol, so we don't send text commands to
1118 * the server. Instead, we scan for commands for commands used by
1119 * OpenSSH's sftp program and call the appropriate libssh2
1122 if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
1123 curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
1124 curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
1125 /* attribute change */
1127 /* sshc->quote_path1 contains the mode to set */
1128 /* get the destination */
1129 result = get_pathname(&cp, &sshc->quote_path2);
1131 if(result == CURLE_OUT_OF_MEMORY)
1132 failf(data, "Out of memory");
1134 failf(data, "Syntax error in chgrp/chmod/chown: "
1135 "Bad second parameter");
1136 Curl_safefree(sshc->quote_path1);
1137 sshc->quote_path1 = NULL;
1138 state(conn, SSH_SFTP_CLOSE);
1139 sshc->nextstate = SSH_NO_STATE;
1140 sshc->actualcode = result;
1143 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1144 state(conn, SSH_SFTP_QUOTE_STAT);
1147 else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
1148 curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
1149 /* symbolic linking */
1150 /* sshc->quote_path1 is the source */
1151 /* get the destination */
1152 result = get_pathname(&cp, &sshc->quote_path2);
1154 if(result == CURLE_OUT_OF_MEMORY)
1155 failf(data, "Out of memory");
1158 "Syntax error in ln/symlink: Bad second parameter");
1159 Curl_safefree(sshc->quote_path1);
1160 sshc->quote_path1 = NULL;
1161 state(conn, SSH_SFTP_CLOSE);
1162 sshc->nextstate = SSH_NO_STATE;
1163 sshc->actualcode = result;
1166 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1169 else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
1171 state(conn, SSH_SFTP_QUOTE_MKDIR);
1174 else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
1176 /* first param is the source path */
1177 /* second param is the dest. path */
1178 result = get_pathname(&cp, &sshc->quote_path2);
1180 if(result == CURLE_OUT_OF_MEMORY)
1181 failf(data, "Out of memory");
1183 failf(data, "Syntax error in rename: Bad second parameter");
1184 Curl_safefree(sshc->quote_path1);
1185 sshc->quote_path1 = NULL;
1186 state(conn, SSH_SFTP_CLOSE);
1187 sshc->nextstate = SSH_NO_STATE;
1188 sshc->actualcode = result;
1191 state(conn, SSH_SFTP_QUOTE_RENAME);
1194 else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
1196 state(conn, SSH_SFTP_QUOTE_RMDIR);
1199 else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
1200 state(conn, SSH_SFTP_QUOTE_UNLINK);
1204 failf(data, "Unknown SFTP command");
1205 Curl_safefree(sshc->quote_path1);
1206 sshc->quote_path1 = NULL;
1207 Curl_safefree(sshc->quote_path2);
1208 sshc->quote_path2 = NULL;
1209 state(conn, SSH_SFTP_CLOSE);
1210 sshc->nextstate = SSH_NO_STATE;
1211 sshc->actualcode = CURLE_QUOTE_ERROR;
1215 if(!sshc->quote_item) {
1216 state(conn, SSH_SFTP_TRANS_INIT);
1220 case SSH_SFTP_NEXT_QUOTE:
1221 if(sshc->quote_path1) {
1222 Curl_safefree(sshc->quote_path1);
1223 sshc->quote_path1 = NULL;
1225 if(sshc->quote_path2) {
1226 Curl_safefree(sshc->quote_path2);
1227 sshc->quote_path2 = NULL;
1230 sshc->quote_item = sshc->quote_item->next;
1232 if(sshc->quote_item) {
1233 state(conn, SSH_SFTP_QUOTE);
1236 if(sshc->nextstate != SSH_NO_STATE) {
1237 state(conn, sshc->nextstate);
1238 sshc->nextstate = SSH_NO_STATE;
1241 state(conn, SSH_SFTP_TRANS_INIT);
1246 case SSH_SFTP_QUOTE_STAT:
1247 if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1248 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1249 * set them both at once, we need to obtain the current ownership
1250 * first. This takes an extra protocol round trip.
1252 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1253 (unsigned int)strlen(sshc->quote_path2),
1255 &sshc->quote_attrs);
1256 if(rc == LIBSSH2_ERROR_EAGAIN) {
1259 else if(rc != 0) { /* get those attributes */
1260 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1261 Curl_safefree(sshc->quote_path1);
1262 sshc->quote_path1 = NULL;
1263 Curl_safefree(sshc->quote_path2);
1264 sshc->quote_path2 = NULL;
1265 failf(data, "Attempt to get SFTP stats failed: %s",
1266 sftp_libssh2_strerror(err));
1267 state(conn, SSH_SFTP_CLOSE);
1268 sshc->nextstate = SSH_NO_STATE;
1269 sshc->actualcode = CURLE_QUOTE_ERROR;
1274 /* Now set the new attributes... */
1275 if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
1276 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1277 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1278 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1279 Curl_safefree(sshc->quote_path1);
1280 sshc->quote_path1 = NULL;
1281 Curl_safefree(sshc->quote_path2);
1282 sshc->quote_path2 = NULL;
1283 failf(data, "Syntax error: chgrp gid not a number");
1284 state(conn, SSH_SFTP_CLOSE);
1285 sshc->nextstate = SSH_NO_STATE;
1286 sshc->actualcode = CURLE_QUOTE_ERROR;
1290 else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1291 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1292 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1293 /* permissions are octal */
1294 if(sshc->quote_attrs.permissions == 0 &&
1295 !ISDIGIT(sshc->quote_path1[0])) {
1296 Curl_safefree(sshc->quote_path1);
1297 sshc->quote_path1 = NULL;
1298 Curl_safefree(sshc->quote_path2);
1299 sshc->quote_path2 = NULL;
1300 failf(data, "Syntax error: chmod permissions not a number");
1301 state(conn, SSH_SFTP_CLOSE);
1302 sshc->nextstate = SSH_NO_STATE;
1303 sshc->actualcode = CURLE_QUOTE_ERROR;
1307 else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
1308 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1309 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1310 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1311 Curl_safefree(sshc->quote_path1);
1312 sshc->quote_path1 = NULL;
1313 Curl_safefree(sshc->quote_path2);
1314 sshc->quote_path2 = NULL;
1315 failf(data, "Syntax error: chown uid not a number");
1316 state(conn, SSH_SFTP_CLOSE);
1317 sshc->nextstate = SSH_NO_STATE;
1318 sshc->actualcode = CURLE_QUOTE_ERROR;
1323 /* Now send the completed structure... */
1324 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1327 case SSH_SFTP_QUOTE_SETSTAT:
1328 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1329 (unsigned int)strlen(sshc->quote_path2),
1330 LIBSSH2_SFTP_SETSTAT,
1331 &sshc->quote_attrs);
1332 if(rc == LIBSSH2_ERROR_EAGAIN) {
1336 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1337 Curl_safefree(sshc->quote_path1);
1338 sshc->quote_path1 = NULL;
1339 Curl_safefree(sshc->quote_path2);
1340 sshc->quote_path2 = NULL;
1341 failf(data, "Attempt to set SFTP stats failed: %s",
1342 sftp_libssh2_strerror(err));
1343 state(conn, SSH_SFTP_CLOSE);
1344 sshc->nextstate = SSH_NO_STATE;
1345 sshc->actualcode = CURLE_QUOTE_ERROR;
1348 state(conn, SSH_SFTP_NEXT_QUOTE);
1351 case SSH_SFTP_QUOTE_SYMLINK:
1352 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1353 (unsigned int)strlen(sshc->quote_path1),
1355 (unsigned int)strlen(sshc->quote_path2),
1356 LIBSSH2_SFTP_SYMLINK);
1357 if(rc == LIBSSH2_ERROR_EAGAIN) {
1361 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1362 Curl_safefree(sshc->quote_path1);
1363 sshc->quote_path1 = NULL;
1364 Curl_safefree(sshc->quote_path2);
1365 sshc->quote_path2 = NULL;
1366 failf(data, "symlink command failed: %s",
1367 sftp_libssh2_strerror(err));
1368 state(conn, SSH_SFTP_CLOSE);
1369 sshc->nextstate = SSH_NO_STATE;
1370 sshc->actualcode = CURLE_QUOTE_ERROR;
1373 state(conn, SSH_SFTP_NEXT_QUOTE);
1376 case SSH_SFTP_QUOTE_MKDIR:
1377 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1378 (unsigned int)strlen(sshc->quote_path1),
1380 if(rc == LIBSSH2_ERROR_EAGAIN) {
1384 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1385 Curl_safefree(sshc->quote_path1);
1386 sshc->quote_path1 = NULL;
1387 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1388 state(conn, SSH_SFTP_CLOSE);
1389 sshc->nextstate = SSH_NO_STATE;
1390 sshc->actualcode = CURLE_QUOTE_ERROR;
1393 state(conn, SSH_SFTP_NEXT_QUOTE);
1396 case SSH_SFTP_QUOTE_RENAME:
1397 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1398 (unsigned int)strlen(sshc->quote_path1),
1400 (unsigned int)strlen(sshc->quote_path2),
1401 LIBSSH2_SFTP_RENAME_OVERWRITE |
1402 LIBSSH2_SFTP_RENAME_ATOMIC |
1403 LIBSSH2_SFTP_RENAME_NATIVE);
1405 if(rc == LIBSSH2_ERROR_EAGAIN) {
1409 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1410 Curl_safefree(sshc->quote_path1);
1411 sshc->quote_path1 = NULL;
1412 Curl_safefree(sshc->quote_path2);
1413 sshc->quote_path2 = NULL;
1414 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1415 state(conn, SSH_SFTP_CLOSE);
1416 sshc->nextstate = SSH_NO_STATE;
1417 sshc->actualcode = CURLE_QUOTE_ERROR;
1420 state(conn, SSH_SFTP_NEXT_QUOTE);
1423 case SSH_SFTP_QUOTE_RMDIR:
1424 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1425 (unsigned int)strlen(sshc->quote_path1));
1426 if(rc == LIBSSH2_ERROR_EAGAIN) {
1430 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1431 Curl_safefree(sshc->quote_path1);
1432 sshc->quote_path1 = NULL;
1433 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1434 state(conn, SSH_SFTP_CLOSE);
1435 sshc->nextstate = SSH_NO_STATE;
1436 sshc->actualcode = CURLE_QUOTE_ERROR;
1439 state(conn, SSH_SFTP_NEXT_QUOTE);
1442 case SSH_SFTP_QUOTE_UNLINK:
1443 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1444 (unsigned int)strlen(sshc->quote_path1));
1445 if(rc == LIBSSH2_ERROR_EAGAIN) {
1449 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1450 Curl_safefree(sshc->quote_path1);
1451 sshc->quote_path1 = NULL;
1452 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1453 state(conn, SSH_SFTP_CLOSE);
1454 sshc->nextstate = SSH_NO_STATE;
1455 sshc->actualcode = CURLE_QUOTE_ERROR;
1458 state(conn, SSH_SFTP_NEXT_QUOTE);
1461 case SSH_SFTP_TRANS_INIT:
1462 if(data->set.upload)
1463 state(conn, SSH_SFTP_UPLOAD_INIT);
1465 if(data->set.opt_no_body)
1466 state(conn, SSH_STOP);
1467 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1468 state(conn, SSH_SFTP_READDIR_INIT);
1470 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1474 case SSH_SFTP_UPLOAD_INIT:
1476 unsigned long flags;
1478 * NOTE!!! libssh2 requires that the destination path is a full path
1479 * that includes the destination file and name OR ends in a "/"
1480 * If this is not done the destination file will be named the
1481 * same name as the last directory in the path.
1484 if(data->state.resume_from != 0) {
1485 LIBSSH2_SFTP_ATTRIBUTES attrs;
1486 if(data->state.resume_from < 0) {
1487 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1488 (unsigned int)strlen(sftp_scp->path),
1489 LIBSSH2_SFTP_STAT, &attrs);
1490 if(rc == LIBSSH2_ERROR_EAGAIN) {
1494 data->state.resume_from = 0;
1497 curl_off_t size = attrs.filesize;
1499 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1500 return CURLE_BAD_DOWNLOAD_RESUME;
1502 data->state.resume_from = attrs.filesize;
1507 if(data->set.ftp_append)
1508 /* Try to open for append, but create if nonexisting */
1509 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1510 else if(data->state.resume_from > 0)
1511 /* If we have restart position then open for append */
1512 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1514 /* Clear file before writing (normal behaviour) */
1515 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1518 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1519 (unsigned int)strlen(sftp_scp->path),
1520 flags, data->set.new_file_perms,
1521 LIBSSH2_SFTP_OPENFILE);
1523 if(!sshc->sftp_handle) {
1524 rc = libssh2_session_last_errno(sshc->ssh_session);
1526 if(LIBSSH2_ERROR_EAGAIN == rc)
1529 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1530 /* only when there was an SFTP protocol error can we extract
1532 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1534 err = -1; /* not an sftp error at all */
1536 if(sshc->secondCreateDirs) {
1537 state(conn, SSH_SFTP_CLOSE);
1538 sshc->actualcode = err>= LIBSSH2_FX_OK?
1539 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1540 failf(data, "Creating the dir/file failed: %s",
1541 sftp_libssh2_strerror(err));
1544 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1545 (err == LIBSSH2_FX_FAILURE) ||
1546 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1547 (data->set.ftp_create_missing_dirs &&
1548 (strlen(sftp_scp->path) > 1))) {
1549 /* try to create the path remotely */
1550 sshc->secondCreateDirs = 1;
1551 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1554 state(conn, SSH_SFTP_CLOSE);
1555 sshc->actualcode = err>= LIBSSH2_FX_OK?
1556 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1557 if(!sshc->actualcode) {
1558 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1559 zero even though libssh2_sftp_open() failed previously! We need
1560 to work around that! */
1561 sshc->actualcode = CURLE_SSH;
1564 failf(data, "Upload failed: %s (%d/%d)",
1565 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1571 /* If we have restart point then we need to seek to the correct
1573 if(data->state.resume_from > 0) {
1574 /* Let's read off the proper amount of bytes from the input. */
1575 if(conn->seek_func) {
1576 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1580 if(seekerr != CURL_SEEKFUNC_OK) {
1582 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1583 failf(data, "Could not seek stream");
1584 return CURLE_FTP_COULDNT_USE_REST;
1586 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1588 curl_off_t passed=0;
1590 size_t readthisamountnow =
1591 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1592 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1594 size_t actuallyread =
1595 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1598 passed += actuallyread;
1599 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1600 /* this checks for greater-than only to make sure that the
1601 CURL_READFUNC_ABORT return code still aborts */
1602 failf(data, "Failed to read data");
1603 return CURLE_FTP_COULDNT_USE_REST;
1605 } while(passed < data->state.resume_from);
1609 /* now, decrease the size of the read */
1610 if(data->set.infilesize > 0) {
1611 data->set.infilesize -= data->state.resume_from;
1612 data->req.size = data->set.infilesize;
1613 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1616 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1618 if(data->set.infilesize > 0) {
1619 data->req.size = data->set.infilesize;
1620 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1623 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1625 /* not set by Curl_setup_transfer to preserve keepon bits */
1626 conn->sockfd = conn->writesockfd;
1629 state(conn, SSH_SFTP_CLOSE);
1630 sshc->actualcode = result;
1633 /* store this original bitmask setup to use later on if we can't
1634 figure out a "real" bitmask */
1635 sshc->orig_waitfor = data->req.keepon;
1637 /* we want to use the _sending_ function even when the socket turns
1638 out readable as the underlying libssh2 sftp send function will deal
1639 with both accordingly */
1640 conn->cselect_bits = CURL_CSELECT_OUT;
1642 /* since we don't really wait for anything at this point, we want the
1643 state machine to move on as soon as possible so we set a very short
1645 Curl_expire(data, 1);
1647 state(conn, SSH_STOP);
1652 case SSH_SFTP_CREATE_DIRS_INIT:
1653 if(strlen(sftp_scp->path) > 1) {
1654 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1655 state(conn, SSH_SFTP_CREATE_DIRS);
1658 state(conn, SSH_SFTP_UPLOAD_INIT);
1662 case SSH_SFTP_CREATE_DIRS:
1663 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1664 *sshc->slash_pos = 0;
1666 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1667 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1671 state(conn, SSH_SFTP_UPLOAD_INIT);
1675 case SSH_SFTP_CREATE_DIRS_MKDIR:
1676 /* 'mode' - parameter is preliminary - default to 0644 */
1677 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1678 (unsigned int)strlen(sftp_scp->path),
1679 data->set.new_directory_perms);
1680 if(rc == LIBSSH2_ERROR_EAGAIN) {
1683 *sshc->slash_pos = '/';
1686 unsigned int sftp_err = 0;
1688 * Abort if failure wasn't that the dir already exists or the
1689 * permission was denied (creation might succeed further down the
1690 * path) - retry on unspecific FAILURE also
1692 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1693 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1694 (sftp_err != LIBSSH2_FX_FAILURE) &&
1695 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1696 result = sftp_libssh2_error_to_CURLE(sftp_err);
1697 state(conn, SSH_SFTP_CLOSE);
1698 sshc->actualcode = result?result:CURLE_SSH;
1702 state(conn, SSH_SFTP_CREATE_DIRS);
1705 case SSH_SFTP_READDIR_INIT:
1707 * This is a directory that we are trying to get, so produce a directory
1710 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1713 strlen(sftp_scp->path),
1714 0, 0, LIBSSH2_SFTP_OPENDIR);
1715 if(!sshc->sftp_handle) {
1716 if(libssh2_session_last_errno(sshc->ssh_session) ==
1717 LIBSSH2_ERROR_EAGAIN) {
1718 rc = LIBSSH2_ERROR_EAGAIN;
1722 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1723 failf(data, "Could not open directory for reading: %s",
1724 sftp_libssh2_strerror(err));
1725 state(conn, SSH_SFTP_CLOSE);
1726 result = sftp_libssh2_error_to_CURLE(err);
1727 sshc->actualcode = result?result:CURLE_SSH;
1731 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1732 state(conn, SSH_SFTP_CLOSE);
1733 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1736 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1737 Curl_safefree(sshc->readdir_filename);
1738 sshc->readdir_filename = NULL;
1739 state(conn, SSH_SFTP_CLOSE);
1740 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1743 state(conn, SSH_SFTP_READDIR);
1746 case SSH_SFTP_READDIR:
1747 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1748 sshc->readdir_filename,
1750 sshc->readdir_longentry,
1752 &sshc->readdir_attrs);
1753 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1754 rc = LIBSSH2_ERROR_EAGAIN;
1757 if(sshc->readdir_len > 0) {
1758 sshc->readdir_filename[sshc->readdir_len] = '\0';
1760 if(data->set.ftp_list_only) {
1763 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1764 if(tmpLine == NULL) {
1765 state(conn, SSH_SFTP_CLOSE);
1766 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1769 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1770 tmpLine, sshc->readdir_len+1);
1771 Curl_safefree(tmpLine);
1774 state(conn, SSH_STOP);
1777 /* since this counts what we send to the client, we include the
1778 newline in this counter */
1779 data->req.bytecount += sshc->readdir_len+1;
1781 /* output debug output if that is requested */
1782 if(data->set.verbose) {
1783 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1784 sshc->readdir_len, conn);
1788 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1789 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1790 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1791 if(!sshc->readdir_line) {
1792 Curl_safefree(sshc->readdir_filename);
1793 sshc->readdir_filename = NULL;
1794 Curl_safefree(sshc->readdir_longentry);
1795 sshc->readdir_longentry = NULL;
1796 state(conn, SSH_SFTP_CLOSE);
1797 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1801 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1802 sshc->readdir_currLen);
1803 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1804 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1805 LIBSSH2_SFTP_S_IFLNK)) {
1806 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1807 if(sshc->readdir_linkPath == NULL) {
1808 Curl_safefree(sshc->readdir_filename);
1809 sshc->readdir_filename = NULL;
1810 Curl_safefree(sshc->readdir_longentry);
1811 sshc->readdir_longentry = NULL;
1812 state(conn, SSH_SFTP_CLOSE);
1813 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1817 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1818 sshc->readdir_filename);
1819 state(conn, SSH_SFTP_READDIR_LINK);
1822 state(conn, SSH_SFTP_READDIR_BOTTOM);
1826 else if(sshc->readdir_len == 0) {
1827 Curl_safefree(sshc->readdir_filename);
1828 sshc->readdir_filename = NULL;
1829 Curl_safefree(sshc->readdir_longentry);
1830 sshc->readdir_longentry = NULL;
1831 state(conn, SSH_SFTP_READDIR_DONE);
1834 else if(sshc->readdir_len <= 0) {
1835 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1836 result = sftp_libssh2_error_to_CURLE(err);
1837 sshc->actualcode = result?result:CURLE_SSH;
1838 failf(data, "Could not open remote file for reading: %s :: %d",
1839 sftp_libssh2_strerror(err),
1840 libssh2_session_last_errno(sshc->ssh_session));
1841 Curl_safefree(sshc->readdir_filename);
1842 sshc->readdir_filename = NULL;
1843 Curl_safefree(sshc->readdir_longentry);
1844 sshc->readdir_longentry = NULL;
1845 state(conn, SSH_SFTP_CLOSE);
1850 case SSH_SFTP_READDIR_LINK:
1852 libssh2_sftp_symlink_ex(sshc->sftp_session,
1853 sshc->readdir_linkPath,
1854 (unsigned int) strlen(sshc->readdir_linkPath),
1855 sshc->readdir_filename,
1856 PATH_MAX, LIBSSH2_SFTP_READLINK);
1857 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1858 rc = LIBSSH2_ERROR_EAGAIN;
1861 Curl_safefree(sshc->readdir_linkPath);
1862 sshc->readdir_linkPath = NULL;
1864 new_readdir_line = realloc(sshc->readdir_line,
1865 sshc->readdir_totalLen + 4 +
1867 if(!new_readdir_line) {
1868 Curl_safefree(sshc->readdir_line);
1869 sshc->readdir_line = NULL;
1870 Curl_safefree(sshc->readdir_filename);
1871 sshc->readdir_filename = NULL;
1872 Curl_safefree(sshc->readdir_longentry);
1873 sshc->readdir_longentry = NULL;
1874 state(conn, SSH_SFTP_CLOSE);
1875 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1878 sshc->readdir_line = new_readdir_line;
1880 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1881 sshc->readdir_currLen,
1882 sshc->readdir_totalLen -
1883 sshc->readdir_currLen,
1885 sshc->readdir_filename);
1887 state(conn, SSH_SFTP_READDIR_BOTTOM);
1890 case SSH_SFTP_READDIR_BOTTOM:
1891 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1892 sshc->readdir_currLen,
1893 sshc->readdir_totalLen -
1894 sshc->readdir_currLen, "\n");
1895 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1897 sshc->readdir_currLen);
1899 if(result == CURLE_OK) {
1901 /* output debug output if that is requested */
1902 if(data->set.verbose) {
1903 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1904 sshc->readdir_currLen, conn);
1906 data->req.bytecount += sshc->readdir_currLen;
1908 Curl_safefree(sshc->readdir_line);
1909 sshc->readdir_line = NULL;
1911 state(conn, SSH_STOP);
1914 state(conn, SSH_SFTP_READDIR);
1917 case SSH_SFTP_READDIR_DONE:
1918 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1919 LIBSSH2_ERROR_EAGAIN) {
1920 rc = LIBSSH2_ERROR_EAGAIN;
1923 sshc->sftp_handle = NULL;
1924 Curl_safefree(sshc->readdir_filename);
1925 sshc->readdir_filename = NULL;
1926 Curl_safefree(sshc->readdir_longentry);
1927 sshc->readdir_longentry = NULL;
1929 /* no data to transfer */
1930 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1931 state(conn, SSH_STOP);
1934 case SSH_SFTP_DOWNLOAD_INIT:
1936 * Work on getting the specified file
1939 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1940 (unsigned int)strlen(sftp_scp->path),
1941 LIBSSH2_FXF_READ, data->set.new_file_perms,
1942 LIBSSH2_SFTP_OPENFILE);
1943 if(!sshc->sftp_handle) {
1944 if(libssh2_session_last_errno(sshc->ssh_session) ==
1945 LIBSSH2_ERROR_EAGAIN) {
1946 rc = LIBSSH2_ERROR_EAGAIN;
1950 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1951 failf(data, "Could not open remote file for reading: %s",
1952 sftp_libssh2_strerror(err));
1953 state(conn, SSH_SFTP_CLOSE);
1954 result = sftp_libssh2_error_to_CURLE(err);
1955 sshc->actualcode = result?result:CURLE_SSH;
1959 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1962 case SSH_SFTP_DOWNLOAD_STAT:
1964 LIBSSH2_SFTP_ATTRIBUTES attrs;
1966 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1967 (unsigned int)strlen(sftp_scp->path),
1968 LIBSSH2_SFTP_STAT, &attrs);
1969 if(rc == LIBSSH2_ERROR_EAGAIN) {
1974 * libssh2_sftp_open() didn't return an error, so maybe the server
1975 * just doesn't support stat()
1977 data->req.size = -1;
1978 data->req.maxdownload = -1;
1981 curl_off_t size = attrs.filesize;
1984 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1985 return CURLE_BAD_DOWNLOAD_RESUME;
1987 if(conn->data->state.use_range) {
1988 curl_off_t from, to;
1992 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1993 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
1995 to=curlx_strtoofft(ptr, &ptr2, 0);
1996 if((ptr == ptr2) /* no "to" value given */
2001 /* from is relative to end of file */
2005 failf(data, "Offset (%"
2006 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2007 from, attrs.filesize);
2008 return CURLE_BAD_DOWNLOAD_RESUME;
2015 size = to - from + 1;
2018 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2020 data->req.size = size;
2021 data->req.maxdownload = size;
2022 Curl_pgrsSetDownloadSize(data, size);
2025 /* We can resume if we can seek to the resume position */
2026 if(data->state.resume_from) {
2027 if(data->state.resume_from < 0) {
2028 /* We're supposed to download the last abs(from) bytes */
2029 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2030 failf(data, "Offset (%"
2031 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2032 data->state.resume_from, attrs.filesize);
2033 return CURLE_BAD_DOWNLOAD_RESUME;
2035 /* download from where? */
2036 data->state.resume_from += attrs.filesize;
2039 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2040 failf(data, "Offset (%" FORMAT_OFF_T
2041 ") was beyond file size (%" FORMAT_OFF_T ")",
2042 data->state.resume_from, attrs.filesize);
2043 return CURLE_BAD_DOWNLOAD_RESUME;
2046 /* Does a completed file need to be seeked and started or closed ? */
2047 /* Now store the number of bytes we are expected to download */
2048 data->req.size = attrs.filesize - data->state.resume_from;
2049 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2050 Curl_pgrsSetDownloadSize(data,
2051 attrs.filesize - data->state.resume_from);
2052 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2055 /* Setup the actual download */
2056 if(data->req.size == 0) {
2057 /* no data to transfer */
2058 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2059 infof(data, "File already completely downloaded\n");
2060 state(conn, SSH_STOP);
2064 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2065 FALSE, NULL, -1, NULL);
2067 /* not set by Curl_setup_transfer to preserve keepon bits */
2068 conn->writesockfd = conn->sockfd;
2070 /* we want to use the _receiving_ function even when the socket turns
2071 out writableable as the underlying libssh2 recv function will deal
2072 with both accordingly */
2073 conn->cselect_bits = CURL_CSELECT_IN;
2076 state(conn, SSH_SFTP_CLOSE);
2077 sshc->actualcode = result;
2080 state(conn, SSH_STOP);
2084 case SSH_SFTP_CLOSE:
2085 if(sshc->sftp_handle) {
2086 rc = libssh2_sftp_close(sshc->sftp_handle);
2087 if(rc == LIBSSH2_ERROR_EAGAIN) {
2091 infof(data, "Failed to close libssh2 file\n");
2093 sshc->sftp_handle = NULL;
2096 Curl_safefree(sftp_scp->path);
2097 sftp_scp->path = NULL;
2100 DEBUGF(infof(data, "SFTP DONE done\n"));
2102 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2103 After nextstate is executed,the control should come back to
2104 SSH_SFTP_CLOSE to pass the correct result back */
2105 if(sshc->nextstate != SSH_NO_STATE) {
2106 state(conn, sshc->nextstate);
2107 sshc->nextstate = SSH_SFTP_CLOSE;
2110 state(conn, SSH_STOP);
2111 result = sshc->actualcode;
2115 case SSH_SFTP_SHUTDOWN:
2116 /* during times we get here due to a broken transfer and then the
2117 sftp_handle might not have been taken down so make sure that is done
2118 before we proceed */
2120 if(sshc->sftp_handle) {
2121 rc = libssh2_sftp_close(sshc->sftp_handle);
2122 if(rc == LIBSSH2_ERROR_EAGAIN) {
2126 infof(data, "Failed to close libssh2 file\n");
2128 sshc->sftp_handle = NULL;
2130 if(sshc->sftp_session) {
2131 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2132 if(rc == LIBSSH2_ERROR_EAGAIN) {
2136 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2138 sshc->sftp_session = NULL;
2141 Curl_safefree(sshc->homedir);
2142 sshc->homedir = NULL;
2143 conn->data->state.most_recent_ftp_entrypath = NULL;
2145 state(conn, SSH_SESSION_DISCONNECT);
2148 case SSH_SCP_TRANS_INIT:
2149 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2151 sshc->actualcode = result;
2152 state(conn, SSH_STOP);
2156 if(data->set.upload) {
2157 if(data->set.infilesize < 0) {
2158 failf(data, "SCP requires a known file size for upload");
2159 sshc->actualcode = CURLE_UPLOAD_FAILED;
2160 state(conn, SSH_SCP_CHANNEL_FREE);
2163 state(conn, SSH_SCP_UPLOAD_INIT);
2166 state(conn, SSH_SCP_DOWNLOAD_INIT);
2170 case SSH_SCP_UPLOAD_INIT:
2172 * libssh2 requires that the destination path is a full path that
2173 * includes the destination file and name OR ends in a "/" . If this is
2174 * not done the destination file will be named the same name as the last
2175 * directory in the path.
2178 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2179 data->set.infilesize);
2180 if(!sshc->ssh_channel) {
2181 if(libssh2_session_last_errno(sshc->ssh_session) ==
2182 LIBSSH2_ERROR_EAGAIN) {
2183 rc = LIBSSH2_ERROR_EAGAIN;
2190 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2191 &err_msg, NULL, 0));
2192 failf(conn->data, "%s", err_msg);
2193 state(conn, SSH_SCP_CHANNEL_FREE);
2194 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2200 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2203 /* not set by Curl_setup_transfer to preserve keepon bits */
2204 conn->sockfd = conn->writesockfd;
2207 state(conn, SSH_SCP_CHANNEL_FREE);
2208 sshc->actualcode = result;
2211 /* we want to use the _sending_ function even when the socket turns
2212 out readable as the underlying libssh2 scp send function will deal
2213 with both accordingly */
2214 conn->cselect_bits = CURL_CSELECT_OUT;
2216 state(conn, SSH_STOP);
2220 case SSH_SCP_DOWNLOAD_INIT:
2223 * We must check the remote file; if it is a directory no values will
2227 curl_off_t bytecount;
2229 /* clear the struct scp recv will fill in */
2230 memset(&sb, 0, sizeof(struct stat));
2232 /* get a fresh new channel from the ssh layer */
2233 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2234 sftp_scp->path, &sb);
2235 if(!sshc->ssh_channel) {
2236 if(libssh2_session_last_errno(sshc->ssh_session) ==
2237 LIBSSH2_ERROR_EAGAIN) {
2238 rc = LIBSSH2_ERROR_EAGAIN;
2245 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2246 &err_msg, NULL, 0));
2247 failf(conn->data, "%s", err_msg);
2248 state(conn, SSH_SCP_CHANNEL_FREE);
2249 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2255 bytecount = (curl_off_t)sb.st_size;
2256 data->req.maxdownload = (curl_off_t)sb.st_size;
2257 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2259 /* not set by Curl_setup_transfer to preserve keepon bits */
2260 conn->writesockfd = conn->sockfd;
2262 /* we want to use the _receiving_ function even when the socket turns
2263 out writableable as the underlying libssh2 recv function will deal
2264 with both accordingly */
2265 conn->cselect_bits = CURL_CSELECT_IN;
2268 state(conn, SSH_SCP_CHANNEL_FREE);
2269 sshc->actualcode = result;
2272 state(conn, SSH_STOP);
2277 if(data->set.upload)
2278 state(conn, SSH_SCP_SEND_EOF);
2280 state(conn, SSH_SCP_CHANNEL_FREE);
2283 case SSH_SCP_SEND_EOF:
2284 if(sshc->ssh_channel) {
2285 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2286 if(rc == LIBSSH2_ERROR_EAGAIN) {
2290 infof(data, "Failed to send libssh2 channel EOF\n");
2293 state(conn, SSH_SCP_WAIT_EOF);
2296 case SSH_SCP_WAIT_EOF:
2297 if(sshc->ssh_channel) {
2298 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2299 if(rc == LIBSSH2_ERROR_EAGAIN) {
2303 infof(data, "Failed to get channel EOF: %d\n", rc);
2306 state(conn, SSH_SCP_WAIT_CLOSE);
2309 case SSH_SCP_WAIT_CLOSE:
2310 if(sshc->ssh_channel) {
2311 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2312 if(rc == LIBSSH2_ERROR_EAGAIN) {
2316 infof(data, "Channel failed to close: %d\n", rc);
2319 state(conn, SSH_SCP_CHANNEL_FREE);
2322 case SSH_SCP_CHANNEL_FREE:
2323 if(sshc->ssh_channel) {
2324 rc = libssh2_channel_free(sshc->ssh_channel);
2325 if(rc == LIBSSH2_ERROR_EAGAIN) {
2329 infof(data, "Failed to free libssh2 scp subsystem\n");
2331 sshc->ssh_channel = NULL;
2333 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2335 state(conn, SSH_SESSION_DISCONNECT);
2337 state(conn, SSH_STOP);
2338 result = sshc->actualcode;
2341 case SSH_SESSION_DISCONNECT:
2342 /* during weird times when we've been prematurely aborted, the channel
2343 is still alive when we reach this state and we MUST kill the channel
2345 if(sshc->ssh_channel) {
2346 rc = libssh2_channel_free(sshc->ssh_channel);
2347 if(rc == LIBSSH2_ERROR_EAGAIN) {
2351 infof(data, "Failed to free libssh2 scp subsystem\n");
2353 sshc->ssh_channel = NULL;
2356 if(sshc->ssh_session) {
2357 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2358 if(rc == LIBSSH2_ERROR_EAGAIN) {
2362 infof(data, "Failed to disconnect libssh2 session\n");
2366 Curl_safefree(sshc->homedir);
2367 sshc->homedir = NULL;
2368 conn->data->state.most_recent_ftp_entrypath = NULL;
2370 state(conn, SSH_SESSION_FREE);
2373 case SSH_SESSION_FREE:
2374 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2376 libssh2_knownhost_free(sshc->kh);
2381 if(sshc->ssh_session) {
2382 rc = libssh2_session_free(sshc->ssh_session);
2383 if(rc == LIBSSH2_ERROR_EAGAIN) {
2387 infof(data, "Failed to free libssh2 session\n");
2389 sshc->ssh_session = NULL;
2391 conn->bits.close = TRUE;
2392 sshc->nextstate = SSH_NO_STATE;
2393 state(conn, SSH_STOP);
2394 result = sshc->actualcode;
2398 /* fallthrough, just stop! */
2400 /* internal error */
2401 sshc->nextstate = SSH_NO_STATE;
2402 state(conn, SSH_STOP);
2406 } while(!rc && (sshc->state != SSH_STOP));
2408 if(rc == LIBSSH2_ERROR_EAGAIN) {
2409 /* we would block, we need to wait for the socket to be ready (in the
2410 right direction too)! */
2417 /* called by the multi interface to figure out what socket(s) to wait for and
2418 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2419 static int ssh_perform_getsock(const struct connectdata *conn,
2420 curl_socket_t *sock, /* points to numsocks
2421 number of sockets */
2424 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2425 int bitmap = GETSOCK_BLANK;
2428 sock[0] = conn->sock[FIRSTSOCKET];
2430 if(conn->waitfor & KEEP_RECV)
2431 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2433 if(conn->waitfor & KEEP_SEND)
2434 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2438 /* if we don't know the direction we can use the generic *_getsock()
2439 function even for the protocol_connect and doing states */
2440 return Curl_single_getsock(conn, sock, numsocks);
2444 /* Generic function called by the multi interface to figure out what socket(s)
2445 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2446 static int ssh_getsock(struct connectdata *conn,
2447 curl_socket_t *sock, /* points to numsocks number
2451 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2455 /* if we don't know any direction we can just play along as we used to and
2456 not provide any sensible info */
2457 return GETSOCK_BLANK;
2459 /* if we know the direction we can use the generic *_getsock() function even
2460 for the protocol_connect and doing states */
2461 return ssh_perform_getsock(conn, sock, numsocks);
2465 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2467 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2468 * function is used to figure out in what direction and stores this info so
2469 * that the multi interface can take advantage of it. Make sure to call this
2470 * function in all cases so that when it _doesn't_ return EAGAIN we can
2471 * restore the default wait bits.
2473 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2475 struct ssh_conn *sshc = &conn->proto.sshc;
2479 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2480 /* translate the libssh2 define bits into our own bit defines */
2481 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2482 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2485 /* It didn't block or libssh2 didn't reveal in which direction, put back
2487 conn->waitfor = sshc->orig_waitfor;
2490 /* no libssh2 directional support so we simply don't know */
2491 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2494 /* called repeatedly until done from multi.c */
2495 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2497 struct ssh_conn *sshc = &conn->proto.sshc;
2498 CURLcode result = CURLE_OK;
2499 bool block; /* we store the status and use that to provide a ssh_getsock()
2502 result = ssh_statemach_act(conn, &block);
2503 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2504 ssh_block2waitfor(conn, block);
2509 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2512 struct ssh_conn *sshc = &conn->proto.sshc;
2513 CURLcode result = CURLE_OK;
2514 struct SessionHandle *data = conn->data;
2516 while((sshc->state != SSH_STOP) && !result) {
2520 result = ssh_statemach_act(conn, &block);
2524 if(Curl_pgrsUpdate(conn))
2525 return CURLE_ABORTED_BY_CALLBACK;
2527 struct timeval now = Curl_tvnow();
2528 result = Curl_speedcheck(data, now);
2533 left = Curl_timeleft(data, NULL, duringconnect);
2535 failf(data, "Operation timed out\n");
2536 return CURLE_OPERATION_TIMEDOUT;
2539 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2540 if((CURLE_OK == result) && block) {
2541 int dir = libssh2_session_block_directions(sshc->ssh_session);
2542 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2543 curl_socket_t fd_read = CURL_SOCKET_BAD;
2544 curl_socket_t fd_write = CURL_SOCKET_BAD;
2545 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2547 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2549 /* wait for the socket to become ready */
2550 Curl_socket_ready(fd_read, fd_write,
2551 left>1000?1000:left); /* ignore result */
2561 * SSH setup and connection
2563 static CURLcode ssh_init(struct connectdata *conn)
2565 struct SessionHandle *data = conn->data;
2566 struct SSHPROTO *ssh;
2567 struct ssh_conn *sshc = &conn->proto.sshc;
2569 sshc->actualcode = CURLE_OK; /* reset error code */
2570 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2573 if(data->state.proto.ssh)
2576 ssh = calloc(1, sizeof(struct SSHPROTO));
2578 return CURLE_OUT_OF_MEMORY;
2580 data->state.proto.ssh = ssh;
2585 static Curl_recv scp_recv, sftp_recv;
2586 static Curl_send scp_send, sftp_send;
2589 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2590 * do protocol-specific actions at connect-time.
2592 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2594 #ifdef CURL_LIBSSH2_DEBUG
2597 struct ssh_conn *ssh;
2599 struct SessionHandle *data = conn->data;
2601 /* We default to persistent connections. We set this already in this connect
2602 function to make the re-use checks properly be able to check this bit. */
2603 conn->bits.close = FALSE;
2605 /* If there already is a protocol-specific struct allocated for this
2606 sessionhandle, deal with it */
2607 Curl_reset_reqproto(conn);
2609 result = ssh_init(conn);
2613 if(conn->handler->protocol & CURLPROTO_SCP) {
2614 conn->recv[FIRSTSOCKET] = scp_recv;
2615 conn->send[FIRSTSOCKET] = scp_send;
2618 conn->recv[FIRSTSOCKET] = sftp_recv;
2619 conn->send[FIRSTSOCKET] = sftp_send;
2621 ssh = &conn->proto.sshc;
2623 #ifdef CURL_LIBSSH2_DEBUG
2625 infof(data, "User: %s\n", conn->user);
2628 infof(data, "Password: %s\n", conn->passwd);
2630 sock = conn->sock[FIRSTSOCKET];
2631 #endif /* CURL_LIBSSH2_DEBUG */
2633 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2635 my_libssh2_realloc, conn);
2636 if(ssh->ssh_session == NULL) {
2637 failf(data, "Failure initialising ssh session");
2638 return CURLE_FAILED_INIT;
2641 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2642 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2644 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2646 /* eeek. TODO: free the ssh_session! */
2647 return CURLE_FAILED_INIT;
2650 /* read all known hosts from there */
2651 rc = libssh2_knownhost_readfile(ssh->kh,
2652 data->set.str[STRING_SSH_KNOWNHOSTS],
2653 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2655 infof(data, "Failed to read known hosts from %s\n",
2656 data->set.str[STRING_SSH_KNOWNHOSTS]);
2658 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2660 #ifdef CURL_LIBSSH2_DEBUG
2661 libssh2_trace(ssh->ssh_session, ~0);
2662 infof(data, "SSH socket: %d\n", (int)sock);
2663 #endif /* CURL_LIBSSH2_DEBUG */
2665 state(conn, SSH_INIT);
2667 if(data->state.used_interface == Curl_if_multi)
2668 result = ssh_multi_statemach(conn, done);
2670 result = ssh_easy_statemach(conn, TRUE);
2679 ***********************************************************************
2683 * This is the actual DO function for SCP. Get a file according to
2684 * the options previously setup.
2688 CURLcode scp_perform(struct connectdata *conn,
2692 CURLcode result = CURLE_OK;
2694 DEBUGF(infof(conn->data, "DO phase starts\n"));
2696 *dophase_done = FALSE; /* not done yet */
2698 /* start the first command in the DO phase */
2699 state(conn, SSH_SCP_TRANS_INIT);
2701 /* run the state-machine */
2702 if(conn->data->state.used_interface == Curl_if_multi) {
2703 result = ssh_multi_statemach(conn, dophase_done);
2706 result = ssh_easy_statemach(conn, FALSE);
2707 *dophase_done = TRUE; /* with the easy interface we are done here */
2709 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2712 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2718 /* called from multi.c while DOing */
2719 static CURLcode scp_doing(struct connectdata *conn,
2723 result = ssh_multi_statemach(conn, dophase_done);
2726 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2732 * The DO function is generic for both protocols. There was previously two
2733 * separate ones but this way means less duplicated code.
2736 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2740 struct SessionHandle *data = conn->data;
2742 *done = FALSE; /* default to false */
2745 Since connections can be re-used between SessionHandles, this might be a
2746 connection already existing but on a fresh SessionHandle struct so we must
2747 make sure we have a good 'struct SSHPROTO' to play with. For new
2748 connections, the struct SSHPROTO is allocated and setup in the
2749 ssh_connect() function.
2751 Curl_reset_reqproto(conn);
2752 res = ssh_init(conn);
2756 data->req.size = -1; /* make sure this is unknown at this point */
2758 Curl_pgrsSetUploadCounter(data, 0);
2759 Curl_pgrsSetDownloadCounter(data, 0);
2760 Curl_pgrsSetUploadSize(data, 0);
2761 Curl_pgrsSetDownloadSize(data, 0);
2763 if(conn->handler->protocol & CURLPROTO_SCP)
2764 res = scp_perform(conn, &connected, done);
2766 res = sftp_perform(conn, &connected, done);
2771 /* BLOCKING, but the function is using the state machine so the only reason
2772 this is still blocking is that the multi interface code has no support for
2773 disconnecting operations that takes a while */
2774 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2776 CURLcode result = CURLE_OK;
2777 struct ssh_conn *ssh = &conn->proto.sshc;
2778 (void) dead_connection;
2780 Curl_safefree(conn->data->state.proto.ssh);
2781 conn->data->state.proto.ssh = NULL;
2783 if(ssh->ssh_session) {
2784 /* only if there's a session still around to use! */
2786 state(conn, SSH_SESSION_DISCONNECT);
2788 result = ssh_easy_statemach(conn, FALSE);
2794 /* generic done function for both SCP and SFTP called from their specific
2796 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2798 CURLcode result = CURLE_OK;
2799 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2801 if(status == CURLE_OK) {
2802 /* run the state-machine
2804 TODO: when the multi interface is used, this _really_ should be using
2805 the ssh_multi_statemach function but we have no general support for
2806 non-blocking DONE operations, not in the multi state machine and with
2807 Curl_done() invokes on several places in the code!
2809 result = ssh_easy_statemach(conn, FALSE);
2815 Curl_safefree(sftp_scp->path);
2816 sftp_scp->path = NULL;
2818 Curl_pgrsDone(conn);
2820 conn->data->req.keepon = 0; /* clear all bits */
2825 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2828 (void)premature; /* not used */
2830 if(status == CURLE_OK)
2831 state(conn, SSH_SCP_DONE);
2833 return ssh_done(conn, status);
2837 /* return number of received (decrypted) bytes */
2838 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2839 const void *mem, size_t len, CURLcode *err)
2842 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2844 /* libssh2_channel_write() returns int! */
2846 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2848 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2850 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2859 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2860 * a regular CURLcode value.
2862 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2863 char *mem, size_t len, CURLcode *err)
2866 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2868 /* libssh2_channel_read() returns int */
2870 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2872 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2873 if(nread == LIBSSH2_ERROR_EAGAIN) {
2882 * =============== SFTP ===============
2886 ***********************************************************************
2890 * This is the actual DO function for SFTP. Get a file/directory according to
2891 * the options previously setup.
2895 CURLcode sftp_perform(struct connectdata *conn,
2899 CURLcode result = CURLE_OK;
2901 DEBUGF(infof(conn->data, "DO phase starts\n"));
2903 *dophase_done = FALSE; /* not done yet */
2905 /* start the first command in the DO phase */
2906 state(conn, SSH_SFTP_QUOTE_INIT);
2908 /* run the state-machine */
2909 if(conn->data->state.used_interface == Curl_if_multi) {
2910 result = ssh_multi_statemach(conn, dophase_done);
2913 result = ssh_easy_statemach(conn, FALSE);
2914 *dophase_done = TRUE; /* with the easy interface we are done here */
2916 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2919 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2925 /* called from multi.c while DOing */
2926 static CURLcode sftp_doing(struct connectdata *conn,
2930 result = ssh_multi_statemach(conn, dophase_done);
2933 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2938 /* BLOCKING, but the function is using the state machine so the only reason
2939 this is still blocking is that the multi interface code has no support for
2940 disconnecting operations that takes a while */
2941 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
2943 CURLcode result = CURLE_OK;
2944 (void) dead_connection;
2946 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2948 Curl_safefree(conn->data->state.proto.ssh);
2949 conn->data->state.proto.ssh = NULL;
2951 if(conn->proto.sshc.ssh_session) {
2952 /* only if there's a session still around to use! */
2953 state(conn, SSH_SFTP_SHUTDOWN);
2954 result = ssh_easy_statemach(conn, FALSE);
2957 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2963 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2966 struct ssh_conn *sshc = &conn->proto.sshc;
2968 if(status == CURLE_OK) {
2969 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
2970 errors that could happen due to open file handles during POSTQUOTE
2972 if(!status && !premature && conn->data->set.postquote) {
2973 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
2974 state(conn, SSH_SFTP_CLOSE);
2977 state(conn, SSH_SFTP_CLOSE);
2979 return ssh_done(conn, status);
2982 /* return number of sent bytes */
2983 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
2984 const void *mem, size_t len, CURLcode *err)
2986 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2987 but is changed to ssize_t in 0.15. These days we don't
2988 support libssh2 0.15*/
2991 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2993 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2995 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3004 * Return number of received (decrypted) bytes
3006 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3007 char *mem, size_t len, CURLcode *err)
3012 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3014 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3016 if(nread == LIBSSH2_ERROR_EAGAIN) {
3023 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3026 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3028 * Permission to use, copy, modify, and distribute this software for any
3029 * purpose with or without fee is hereby granted, provided that the above
3030 * copyright notice and this permission notice appear in all copies.
3032 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3033 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3034 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3035 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3036 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3037 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3038 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3041 get_pathname(const char **cpp, char **path)
3043 const char *cp = *cpp, *end;
3046 static const char WHITESPACE[] = " \t\r\n";
3048 cp += strspn(cp, WHITESPACE);
3052 return CURLE_QUOTE_ERROR;
3055 *path = malloc(strlen(cp) + 1);
3057 return CURLE_OUT_OF_MEMORY;
3059 /* Check for quoted filenames */
3060 if(*cp == '\"' || *cp == '\'') {
3063 /* Search for terminating quote, unescape some chars */
3064 for(i = j = 0; i <= strlen(cp); i++) {
3065 if(cp[i] == quot) { /* Found quote */
3070 if(cp[i] == '\0') { /* End of string */
3071 /*error("Unterminated quote");*/
3074 if(cp[i] == '\\') { /* Escaped characters */
3076 if(cp[i] != '\'' && cp[i] != '\"' &&
3078 /*error("Bad escaped character '\\%c'",
3083 (*path)[j++] = cp[i];
3087 /*error("Empty quotes");*/
3090 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3093 /* Read to end of filename */
3094 end = strpbrk(cp, WHITESPACE);
3096 end = strchr(cp, '\0');
3097 *cpp = end + strspn(end, WHITESPACE);
3099 memcpy(*path, cp, end - cp);
3100 (*path)[end - cp] = '\0';
3105 Curl_safefree(*path);
3107 return CURLE_QUOTE_ERROR;
3111 static const char *sftp_libssh2_strerror(unsigned long err)
3114 case LIBSSH2_FX_NO_SUCH_FILE:
3115 return "No such file or directory";
3117 case LIBSSH2_FX_PERMISSION_DENIED:
3118 return "Permission denied";
3120 case LIBSSH2_FX_FAILURE:
3121 return "Operation failed";
3123 case LIBSSH2_FX_BAD_MESSAGE:
3124 return "Bad message from SFTP server";
3126 case LIBSSH2_FX_NO_CONNECTION:
3127 return "Not connected to SFTP server";
3129 case LIBSSH2_FX_CONNECTION_LOST:
3130 return "Connection to SFTP server lost";
3132 case LIBSSH2_FX_OP_UNSUPPORTED:
3133 return "Operation not supported by SFTP server";
3135 case LIBSSH2_FX_INVALID_HANDLE:
3136 return "Invalid handle";
3138 case LIBSSH2_FX_NO_SUCH_PATH:
3139 return "No such file or directory";
3141 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3142 return "File already exists";
3144 case LIBSSH2_FX_WRITE_PROTECT:
3145 return "File is write protected";
3147 case LIBSSH2_FX_NO_MEDIA:
3150 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3153 case LIBSSH2_FX_QUOTA_EXCEEDED:
3154 return "User quota exceeded";
3156 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3157 return "Unknown principle";
3159 case LIBSSH2_FX_LOCK_CONFlICT:
3160 return "File lock conflict";
3162 case LIBSSH2_FX_DIR_NOT_EMPTY:
3163 return "Directory not empty";
3165 case LIBSSH2_FX_NOT_A_DIRECTORY:
3166 return "Not a directory";
3168 case LIBSSH2_FX_INVALID_FILENAME:
3169 return "Invalid filename";
3171 case LIBSSH2_FX_LINK_LOOP:
3172 return "Link points to itself";
3174 return "Unknown error in libssh2";
3177 #endif /* USE_LIBSSH2 */