1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2012, 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 #define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
113 #define sftp_libssh2_realpath(s,p,t,m) \
114 libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
115 (t), (m), LIBSSH2_SFTP_REALPATH)
117 /* Local functions: */
118 static const char *sftp_libssh2_strerror(int err);
119 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
120 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
121 static LIBSSH2_FREE_FUNC(my_libssh2_free);
123 static CURLcode get_pathname(const char **cpp, char **path);
125 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
126 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
127 static CURLcode ssh_do(struct connectdata *conn, bool *done);
129 static CURLcode ssh_getworkingpath(struct connectdata *conn,
130 char *homedir, /* when SFTP is used */
133 static CURLcode scp_done(struct connectdata *conn,
134 CURLcode, bool premature);
135 static CURLcode scp_doing(struct connectdata *conn,
137 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
139 static CURLcode sftp_done(struct connectdata *conn,
140 CURLcode, bool premature);
141 static CURLcode sftp_doing(struct connectdata *conn,
143 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
145 CURLcode sftp_perform(struct connectdata *conn,
149 static int ssh_getsock(struct connectdata *conn,
150 curl_socket_t *sock, /* points to numsocks number
154 static int ssh_perform_getsock(const struct connectdata *conn,
155 curl_socket_t *sock, /* points to numsocks
160 * SCP protocol handler.
163 const struct Curl_handler Curl_handler_scp = {
165 ZERO_NULL, /* setup_connection */
168 ZERO_NULL, /* do_more */
169 ssh_connect, /* connect_it */
170 ssh_multi_statemach, /* connecting */
171 scp_doing, /* doing */
172 ssh_getsock, /* proto_getsock */
173 ssh_getsock, /* doing_getsock */
174 ZERO_NULL, /* domore_getsock */
175 ssh_perform_getsock, /* perform_getsock */
176 scp_disconnect, /* disconnect */
177 ZERO_NULL, /* readwrite */
178 PORT_SSH, /* defport */
179 CURLPROTO_SCP, /* protocol */
180 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
181 | PROTOPT_NOURLQUERY /* flags */
186 * SFTP protocol handler.
189 const struct Curl_handler Curl_handler_sftp = {
191 ZERO_NULL, /* setup_connection */
193 sftp_done, /* done */
194 ZERO_NULL, /* do_more */
195 ssh_connect, /* connect_it */
196 ssh_multi_statemach, /* connecting */
197 sftp_doing, /* doing */
198 ssh_getsock, /* proto_getsock */
199 ssh_getsock, /* doing_getsock */
200 ZERO_NULL, /* domore_getsock */
201 ssh_perform_getsock, /* perform_getsock */
202 sftp_disconnect, /* disconnect */
203 ZERO_NULL, /* readwrite */
204 PORT_SSH, /* defport */
205 CURLPROTO_SFTP, /* protocol */
206 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
207 | PROTOPT_NOURLQUERY /* flags */
212 kbd_callback(const char *name, int name_len, const char *instruction,
213 int instruction_len, int num_prompts,
214 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
215 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
218 struct connectdata *conn = (struct connectdata *)*abstract;
220 #ifdef CURL_LIBSSH2_DEBUG
221 fprintf(stderr, "name=%s\n", name);
222 fprintf(stderr, "name_len=%d\n", name_len);
223 fprintf(stderr, "instruction=%s\n", instruction);
224 fprintf(stderr, "instruction_len=%d\n", instruction_len);
225 fprintf(stderr, "num_prompts=%d\n", num_prompts);
230 (void)instruction_len;
231 #endif /* CURL_LIBSSH2_DEBUG */
232 if(num_prompts == 1) {
233 responses[0].text = strdup(conn->passwd);
234 responses[0].length = curlx_uztoui(strlen(conn->passwd));
240 static CURLcode sftp_libssh2_error_to_CURLE(int err)
246 case LIBSSH2_FX_NO_SUCH_FILE:
247 case LIBSSH2_FX_NO_SUCH_PATH:
248 return CURLE_REMOTE_FILE_NOT_FOUND;
250 case LIBSSH2_FX_PERMISSION_DENIED:
251 case LIBSSH2_FX_WRITE_PROTECT:
252 case LIBSSH2_FX_LOCK_CONFlICT:
253 return CURLE_REMOTE_ACCESS_DENIED;
255 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
256 case LIBSSH2_FX_QUOTA_EXCEEDED:
257 return CURLE_REMOTE_DISK_FULL;
259 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
260 return CURLE_REMOTE_FILE_EXISTS;
262 case LIBSSH2_FX_DIR_NOT_EMPTY:
263 return CURLE_QUOTE_ERROR;
272 static CURLcode libssh2_session_error_to_CURLE(int err)
275 /* Ordered by order of appearance in libssh2.h */
276 case LIBSSH2_ERROR_NONE:
279 case LIBSSH2_ERROR_SOCKET_NONE:
280 return CURLE_COULDNT_CONNECT;
282 case LIBSSH2_ERROR_ALLOC:
283 return CURLE_OUT_OF_MEMORY;
285 case LIBSSH2_ERROR_SOCKET_SEND:
286 return CURLE_SEND_ERROR;
288 case LIBSSH2_ERROR_HOSTKEY_INIT:
289 case LIBSSH2_ERROR_HOSTKEY_SIGN:
290 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
291 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
292 return CURLE_PEER_FAILED_VERIFICATION;
294 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
295 return CURLE_LOGIN_DENIED;
297 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
298 case LIBSSH2_ERROR_TIMEOUT:
299 return CURLE_OPERATION_TIMEDOUT;
301 case LIBSSH2_ERROR_EAGAIN:
305 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
306 error code, and possibly add a few new SSH-related one. We must however
307 not return or even depend on libssh2 errors in the public libcurl API */
312 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
314 (void)abstract; /* arg not used */
315 return malloc(count);
318 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
320 (void)abstract; /* arg not used */
321 return realloc(ptr, count);
324 static LIBSSH2_FREE_FUNC(my_libssh2_free)
326 (void)abstract; /* arg not used */
331 * SSH State machine related code
333 /* This is the ONLY way to change SSH state! */
334 static void state(struct connectdata *conn, sshstate nowstate)
336 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
337 /* for debug purposes */
338 static const char * const names[] = {
344 "SSH_AUTH_PKEY_INIT",
346 "SSH_AUTH_PASS_INIT",
348 "SSH_AUTH_HOST_INIT",
355 "SSH_SFTP_QUOTE_INIT",
356 "SSH_SFTP_POSTQUOTE_INIT",
358 "SSH_SFTP_NEXT_QUOTE",
359 "SSH_SFTP_QUOTE_STAT",
360 "SSH_SFTP_QUOTE_SETSTAT",
361 "SSH_SFTP_QUOTE_SYMLINK",
362 "SSH_SFTP_QUOTE_MKDIR",
363 "SSH_SFTP_QUOTE_RENAME",
364 "SSH_SFTP_QUOTE_RMDIR",
365 "SSH_SFTP_QUOTE_UNLINK",
366 "SSH_SFTP_TRANS_INIT",
367 "SSH_SFTP_UPLOAD_INIT",
368 "SSH_SFTP_CREATE_DIRS_INIT",
369 "SSH_SFTP_CREATE_DIRS",
370 "SSH_SFTP_CREATE_DIRS_MKDIR",
371 "SSH_SFTP_READDIR_INIT",
373 "SSH_SFTP_READDIR_LINK",
374 "SSH_SFTP_READDIR_BOTTOM",
375 "SSH_SFTP_READDIR_DONE",
376 "SSH_SFTP_DOWNLOAD_INIT",
377 "SSH_SFTP_DOWNLOAD_STAT",
380 "SSH_SCP_TRANS_INIT",
381 "SSH_SCP_UPLOAD_INIT",
382 "SSH_SCP_DOWNLOAD_INIT",
386 "SSH_SCP_WAIT_CLOSE",
387 "SSH_SCP_CHANNEL_FREE",
388 "SSH_SESSION_DISCONNECT",
393 struct ssh_conn *sshc = &conn->proto.sshc;
395 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
396 if(sshc->state != nowstate) {
397 infof(conn->data, "SFTP %p state change from %s to %s\n",
398 sshc, names[sshc->state], names[nowstate]);
402 sshc->state = nowstate;
405 /* figure out the path to work with in this particular request */
406 static CURLcode ssh_getworkingpath(struct connectdata *conn,
407 char *homedir, /* when SFTP is used */
408 char **path) /* returns the allocated
409 real path to work with */
411 struct SessionHandle *data = conn->data;
412 char *real_path = NULL;
414 int working_path_len;
416 working_path = curl_easy_unescape(data, data->state.path, 0,
419 return CURLE_OUT_OF_MEMORY;
421 /* Check for /~/ , indicating relative to the user's home directory */
422 if(conn->handler->protocol & CURLPROTO_SCP) {
423 real_path = malloc(working_path_len+1);
424 if(real_path == NULL) {
426 return CURLE_OUT_OF_MEMORY;
428 if((working_path_len > 1) && (working_path[1] == '~'))
429 /* It is referenced to the home directory, so strip the leading '/' */
430 memcpy(real_path, working_path+1, 1 + working_path_len-1);
432 memcpy(real_path, working_path, 1 + working_path_len);
434 else if(conn->handler->protocol & CURLPROTO_SFTP) {
435 if((working_path_len > 1) && (working_path[1] == '~')) {
436 size_t homelen = strlen(homedir);
437 real_path = malloc(homelen + working_path_len + 1);
438 if(real_path == NULL) {
440 return CURLE_OUT_OF_MEMORY;
442 /* It is referenced to the home directory, so strip the
444 memcpy(real_path, homedir, homelen);
445 real_path[homelen] = '/';
446 real_path[homelen+1] = '\0';
447 if(working_path_len > 3) {
448 memcpy(real_path+homelen+1, working_path + 3,
449 1 + working_path_len -3);
453 real_path = malloc(working_path_len+1);
454 if(real_path == NULL) {
456 return CURLE_OUT_OF_MEMORY;
458 memcpy(real_path, working_path, 1+working_path_len);
464 /* store the pointer for the caller to receive */
470 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
471 static int sshkeycallback(CURL *easy,
472 const struct curl_khkey *knownkey, /* known */
473 const struct curl_khkey *foundkey, /* found */
474 enum curl_khmatch match,
482 /* we only allow perfect matches, and we reject everything else */
483 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
488 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
491 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
492 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
494 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
498 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
499 * architectures so we check of the necessary function is present.
501 #ifndef HAVE_LIBSSH2_SCP_SEND64
502 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
504 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
505 (libssh2_uint64_t)d, 0, 0)
509 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
511 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
512 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
515 static CURLcode ssh_knownhost(struct connectdata *conn)
517 CURLcode result = CURLE_OK;
519 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
520 struct SessionHandle *data = conn->data;
522 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
523 /* we're asked to verify the host against a file */
524 struct ssh_conn *sshc = &conn->proto.sshc;
528 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
530 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
535 * A subject to figure out is what host name we need to pass in here.
536 * What host name does OpenSSH store in its file if an IDN name is
539 struct libssh2_knownhost *host;
540 enum curl_khmatch keymatch;
541 curl_sshkeycallback func =
542 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
543 struct curl_khkey knownkey;
544 struct curl_khkey *knownkeyp = NULL;
545 struct curl_khkey foundkey;
547 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
548 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
550 keycheck = libssh2_knownhost_check(sshc->kh,
553 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
554 LIBSSH2_KNOWNHOST_KEYENC_RAW|
558 infof(data, "SSH host check: %d, key: %s\n", keycheck,
559 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
562 /* setup 'knownkey' */
563 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
564 knownkey.key = host->key;
566 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
567 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
568 knownkeyp = &knownkey;
571 /* setup 'foundkey' */
572 foundkey.key = remotekey;
573 foundkey.len = keylen;
574 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
575 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
578 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
579 * curl_khmatch enum are ever modified, we need to introduce a
580 * translation table here!
582 keymatch = (enum curl_khmatch)keycheck;
584 /* Ask the callback how to behave */
585 rc = func(data, knownkeyp, /* from the knownhosts file */
586 &foundkey, /* from the remote host */
587 keymatch, data->set.ssh_keyfunc_userp);
590 /* no remotekey means failure! */
591 rc = CURLKHSTAT_REJECT;
594 default: /* unknown return codes will equal reject */
595 case CURLKHSTAT_REJECT:
596 state(conn, SSH_SESSION_FREE);
597 case CURLKHSTAT_DEFER:
598 /* DEFER means bail out but keep the SSH_HOSTKEY state */
599 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
601 case CURLKHSTAT_FINE:
602 case CURLKHSTAT_FINE_ADD_TO_FILE:
604 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
605 /* the found host+key didn't match but has been told to be fine
606 anyway so we add it in memory */
607 int addrc = libssh2_knownhost_add(sshc->kh,
608 conn->host.name, NULL,
610 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
611 LIBSSH2_KNOWNHOST_KEYENC_RAW|
614 infof(data, "Warning adding the known host %s failed!\n",
616 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
617 /* now we write the entire in-memory list of known hosts to the
620 libssh2_knownhost_writefile(sshc->kh,
621 data->set.str[STRING_SSH_KNOWNHOSTS],
622 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
624 infof(data, "Warning, writing %s failed!\n",
625 data->set.str[STRING_SSH_KNOWNHOSTS]);
632 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
640 * ssh_statemach_act() runs the SSH state machine as far as it can without
641 * blocking and without reaching the end. The data the pointer 'block' points
642 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
643 * meaning it wants to be called again when the socket is ready
646 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
648 CURLcode result = CURLE_OK;
649 struct SessionHandle *data = conn->data;
650 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
651 struct ssh_conn *sshc = &conn->proto.sshc;
652 curl_socket_t sock = conn->sock[FIRSTSOCKET];
653 const char *fingerprint;
655 char *new_readdir_line;
656 int rc = LIBSSH2_ERROR_NONE, i;
658 int seekerr = CURL_SEEKFUNC_OK;
659 *block = 0; /* we're not blocking by default */
663 switch(sshc->state) {
665 sshc->secondCreateDirs = 0;
666 sshc->nextstate = SSH_NO_STATE;
667 sshc->actualcode = CURLE_OK;
669 /* Set libssh2 to non-blocking, since everything internally is
671 libssh2_session_set_blocking(sshc->ssh_session, 0);
673 state(conn, SSH_S_STARTUP);
677 rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
678 if(rc == LIBSSH2_ERROR_EAGAIN) {
682 failf(data, "Failure establishing ssh session");
683 state(conn, SSH_SESSION_FREE);
684 sshc->actualcode = CURLE_FAILED_INIT;
688 state(conn, SSH_HOSTKEY);
693 * Before we authenticate we should check the hostkey's fingerprint
694 * against our known hosts. How that is handled (reading from file,
695 * whatever) is up to us.
697 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
698 LIBSSH2_HOSTKEY_HASH_MD5);
700 /* The fingerprint points to static storage (!), don't free() it. */
701 for(i = 0; i < 16; i++)
702 snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
703 infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
705 /* Before we authenticate we check the hostkey's MD5 fingerprint
706 * against a known fingerprint, if available.
708 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
709 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
710 if(!strequal(md5buffer,
711 data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
713 "Denied establishing ssh session: mismatch md5 fingerprint. "
714 "Remote %s is not equal to %s",
715 md5buffer, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
716 state(conn, SSH_SESSION_FREE);
717 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
720 infof(data, "MD5 checksum match!\n");
721 /* as we already matched, we skip the check for known hosts */
724 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 curlx_uztoui(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)) {
773 bool rsa_pub_empty_but_ok = FALSE;
775 sshc->rsa_pub = sshc->rsa = NULL;
777 /* To ponder about: should really the lib be messing about with the
778 HOME environment variable etc? */
779 home = curl_getenv("HOME");
781 if(data->set.str[STRING_SSH_PUBLIC_KEY] &&
782 !*data->set.str[STRING_SSH_PUBLIC_KEY])
783 rsa_pub_empty_but_ok = true;
784 else if(data->set.str[STRING_SSH_PUBLIC_KEY])
785 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
787 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
789 /* as a final resort, try current dir! */
790 sshc->rsa_pub = strdup("id_dsa.pub");
792 if(!rsa_pub_empty_but_ok && (sshc->rsa_pub == NULL)) {
794 state(conn, SSH_SESSION_FREE);
795 sshc->actualcode = CURLE_OUT_OF_MEMORY;
799 if(data->set.str[STRING_SSH_PRIVATE_KEY])
800 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
802 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
804 /* as a final resort, try current dir! */
805 sshc->rsa = strdup("id_dsa");
807 if(sshc->rsa == NULL) {
809 Curl_safefree(sshc->rsa_pub);
810 state(conn, SSH_SESSION_FREE);
811 sshc->actualcode = CURLE_OUT_OF_MEMORY;
815 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
816 if(!sshc->passphrase)
817 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 Curl_safefree(sshc->rsa);
849 infof(data, "Initialized SSH public key authentication\n");
850 state(conn, SSH_AUTH_DONE);
854 (void)libssh2_session_last_error(sshc->ssh_session,
856 infof(data, "SSH public key authentication failed: %s\n", err_msg);
857 state(conn, SSH_AUTH_PASS_INIT);
861 case SSH_AUTH_PASS_INIT:
862 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
863 (strstr(sshc->authlist, "password") != NULL)) {
864 state(conn, SSH_AUTH_PASS);
867 state(conn, SSH_AUTH_HOST_INIT);
872 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
873 curlx_uztoui(strlen(conn->user)),
875 curlx_uztoui(strlen(conn->passwd)),
877 if(rc == LIBSSH2_ERROR_EAGAIN) {
882 infof(data, "Initialized password authentication\n");
883 state(conn, SSH_AUTH_DONE);
886 state(conn, SSH_AUTH_HOST_INIT);
890 case SSH_AUTH_HOST_INIT:
891 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
892 (strstr(sshc->authlist, "hostbased") != NULL)) {
893 state(conn, SSH_AUTH_HOST);
896 state(conn, SSH_AUTH_KEY_INIT);
901 state(conn, SSH_AUTH_KEY_INIT);
904 case SSH_AUTH_KEY_INIT:
905 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
906 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
907 state(conn, SSH_AUTH_KEY);
910 state(conn, SSH_AUTH_DONE);
915 /* Authentication failed. Continue with keyboard-interactive now. */
916 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
921 if(rc == LIBSSH2_ERROR_EAGAIN) {
926 infof(data, "Initialized keyboard interactive authentication\n");
928 state(conn, SSH_AUTH_DONE);
933 failf(data, "Authentication failure");
934 state(conn, SSH_SESSION_FREE);
935 sshc->actualcode = CURLE_LOGIN_DENIED;
940 * At this point we have an authenticated ssh session.
942 infof(data, "Authentication complete\n");
944 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
947 conn->writesockfd = CURL_SOCKET_BAD;
949 if(conn->handler->protocol == CURLPROTO_SFTP) {
950 state(conn, SSH_SFTP_INIT);
953 infof(data, "SSH CONNECT phase done\n");
954 state(conn, SSH_STOP);
959 * Start the libssh2 sftp session
961 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
962 if(!sshc->sftp_session) {
963 if(libssh2_session_last_errno(sshc->ssh_session) ==
964 LIBSSH2_ERROR_EAGAIN) {
965 rc = LIBSSH2_ERROR_EAGAIN;
971 (void)libssh2_session_last_error(sshc->ssh_session,
973 failf(data, "Failure initializing sftp session: %s", err_msg);
974 state(conn, SSH_SESSION_FREE);
975 sshc->actualcode = CURLE_FAILED_INIT;
979 state(conn, SSH_SFTP_REALPATH);
982 case SSH_SFTP_REALPATH:
984 char tempHome[PATH_MAX];
987 * Get the "home" directory
989 rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
990 tempHome, PATH_MAX-1);
991 if(rc == LIBSSH2_ERROR_EAGAIN) {
995 /* It seems that this string is not always NULL terminated */
997 sshc->homedir = strdup(tempHome);
999 state(conn, SSH_SFTP_CLOSE);
1000 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1003 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1006 /* Return the error type */
1007 err = sftp_libssh2_last_error(sshc->sftp_session);
1008 result = sftp_libssh2_error_to_CURLE(err);
1009 sshc->actualcode = result?result:CURLE_SSH;
1010 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1012 state(conn, SSH_STOP);
1016 /* This is the last step in the SFTP connect phase. Do note that while
1017 we get the homedir here, we get the "workingpath" in the DO action
1018 since the homedir will remain the same between request but the
1019 working path will not. */
1020 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1021 state(conn, SSH_STOP);
1024 case SSH_SFTP_QUOTE_INIT:
1026 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1028 sshc->actualcode = result;
1029 state(conn, SSH_STOP);
1033 if(data->set.quote) {
1034 infof(data, "Sending quote commands\n");
1035 sshc->quote_item = data->set.quote;
1036 state(conn, SSH_SFTP_QUOTE);
1039 state(conn, SSH_SFTP_TRANS_INIT);
1043 case SSH_SFTP_POSTQUOTE_INIT:
1044 if(data->set.postquote) {
1045 infof(data, "Sending quote commands\n");
1046 sshc->quote_item = data->set.postquote;
1047 state(conn, SSH_SFTP_QUOTE);
1050 state(conn, SSH_STOP);
1054 case SSH_SFTP_QUOTE:
1055 /* Send any quote commands */
1060 * Support some of the "FTP" commands
1062 char *cmd = sshc->quote_item->data;
1063 sshc->acceptfail = FALSE;
1065 /* if a command starts with an asterisk, which a legal SFTP command never
1066 can, the command will be allowed to fail without it causing any
1067 aborts or cancels etc. It will cause libcurl to act as if the command
1068 is successful, whatever the server reponds. */
1072 sshc->acceptfail = TRUE;
1075 if(curl_strequal("pwd", cmd)) {
1076 /* output debug output if that is requested */
1077 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1080 result = CURLE_OUT_OF_MEMORY;
1081 state(conn, SSH_SFTP_CLOSE);
1082 sshc->nextstate = SSH_NO_STATE;
1085 if(data->set.verbose) {
1086 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1087 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1089 /* this sends an FTP-like "header" to the header callback so that the
1090 current directory can be read very similar to how it is read when
1091 using ordinary FTP. */
1092 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1094 state(conn, SSH_SFTP_NEXT_QUOTE);
1099 * the arguments following the command must be separated from the
1100 * command with a space so we can check for it unconditionally
1102 cp = strchr(cmd, ' ');
1104 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1105 state(conn, SSH_SFTP_CLOSE);
1106 sshc->nextstate = SSH_NO_STATE;
1107 sshc->actualcode = CURLE_QUOTE_ERROR;
1112 * also, every command takes at least one argument so we get that
1113 * first argument right now
1115 result = get_pathname(&cp, &sshc->quote_path1);
1117 if(result == CURLE_OUT_OF_MEMORY)
1118 failf(data, "Out of memory");
1120 failf(data, "Syntax error: Bad first parameter");
1121 state(conn, SSH_SFTP_CLOSE);
1122 sshc->nextstate = SSH_NO_STATE;
1123 sshc->actualcode = result;
1128 * SFTP is a binary protocol, so we don't send text commands to
1129 * the server. Instead, we scan for commands for commands used by
1130 * OpenSSH's sftp program and call the appropriate libssh2
1133 if(curl_strnequal(cmd, "chgrp ", 6) ||
1134 curl_strnequal(cmd, "chmod ", 6) ||
1135 curl_strnequal(cmd, "chown ", 6) ) {
1136 /* attribute change */
1138 /* sshc->quote_path1 contains the mode to set */
1139 /* get the destination */
1140 result = get_pathname(&cp, &sshc->quote_path2);
1142 if(result == CURLE_OUT_OF_MEMORY)
1143 failf(data, "Out of memory");
1145 failf(data, "Syntax error in chgrp/chmod/chown: "
1146 "Bad second parameter");
1147 Curl_safefree(sshc->quote_path1);
1148 state(conn, SSH_SFTP_CLOSE);
1149 sshc->nextstate = SSH_NO_STATE;
1150 sshc->actualcode = result;
1153 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1154 state(conn, SSH_SFTP_QUOTE_STAT);
1157 else if(curl_strnequal(cmd, "ln ", 3) ||
1158 curl_strnequal(cmd, "symlink ", 8)) {
1159 /* symbolic linking */
1160 /* sshc->quote_path1 is the source */
1161 /* get the destination */
1162 result = get_pathname(&cp, &sshc->quote_path2);
1164 if(result == CURLE_OUT_OF_MEMORY)
1165 failf(data, "Out of memory");
1168 "Syntax error in ln/symlink: Bad second parameter");
1169 Curl_safefree(sshc->quote_path1);
1170 state(conn, SSH_SFTP_CLOSE);
1171 sshc->nextstate = SSH_NO_STATE;
1172 sshc->actualcode = result;
1175 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1178 else if(curl_strnequal(cmd, "mkdir ", 6)) {
1180 state(conn, SSH_SFTP_QUOTE_MKDIR);
1183 else if(curl_strnequal(cmd, "rename ", 7)) {
1185 /* first param is the source path */
1186 /* second param is the dest. path */
1187 result = get_pathname(&cp, &sshc->quote_path2);
1189 if(result == CURLE_OUT_OF_MEMORY)
1190 failf(data, "Out of memory");
1192 failf(data, "Syntax error in rename: Bad second parameter");
1193 Curl_safefree(sshc->quote_path1);
1194 state(conn, SSH_SFTP_CLOSE);
1195 sshc->nextstate = SSH_NO_STATE;
1196 sshc->actualcode = result;
1199 state(conn, SSH_SFTP_QUOTE_RENAME);
1202 else if(curl_strnequal(cmd, "rmdir ", 6)) {
1204 state(conn, SSH_SFTP_QUOTE_RMDIR);
1207 else if(curl_strnequal(cmd, "rm ", 3)) {
1208 state(conn, SSH_SFTP_QUOTE_UNLINK);
1212 failf(data, "Unknown SFTP command");
1213 Curl_safefree(sshc->quote_path1);
1214 Curl_safefree(sshc->quote_path2);
1215 state(conn, SSH_SFTP_CLOSE);
1216 sshc->nextstate = SSH_NO_STATE;
1217 sshc->actualcode = CURLE_QUOTE_ERROR;
1221 if(!sshc->quote_item) {
1222 state(conn, SSH_SFTP_TRANS_INIT);
1226 case SSH_SFTP_NEXT_QUOTE:
1227 Curl_safefree(sshc->quote_path1);
1228 Curl_safefree(sshc->quote_path2);
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:
1248 char *cmd = sshc->quote_item->data;
1249 sshc->acceptfail = FALSE;
1251 /* if a command starts with an asterisk, which a legal SFTP command never
1252 can, the command will be allowed to fail without it causing any
1253 aborts or cancels etc. It will cause libcurl to act as if the command
1254 is successful, whatever the server reponds. */
1258 sshc->acceptfail = TRUE;
1261 if(!curl_strnequal(cmd, "chmod", 5)) {
1262 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1263 * set them both at once, we need to obtain the current ownership
1264 * first. This takes an extra protocol round trip.
1266 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1267 curlx_uztoui(strlen(sshc->quote_path2)),
1269 &sshc->quote_attrs);
1270 if(rc == LIBSSH2_ERROR_EAGAIN) {
1273 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1274 err = sftp_libssh2_last_error(sshc->sftp_session);
1275 Curl_safefree(sshc->quote_path1);
1276 Curl_safefree(sshc->quote_path2);
1277 failf(data, "Attempt to get SFTP stats failed: %s",
1278 sftp_libssh2_strerror(err));
1279 state(conn, SSH_SFTP_CLOSE);
1280 sshc->nextstate = SSH_NO_STATE;
1281 sshc->actualcode = CURLE_QUOTE_ERROR;
1286 /* Now set the new attributes... */
1287 if(curl_strnequal(cmd, "chgrp", 5)) {
1288 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1289 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1290 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1291 !sshc->acceptfail) {
1292 Curl_safefree(sshc->quote_path1);
1293 Curl_safefree(sshc->quote_path2);
1294 failf(data, "Syntax error: chgrp gid not a number");
1295 state(conn, SSH_SFTP_CLOSE);
1296 sshc->nextstate = SSH_NO_STATE;
1297 sshc->actualcode = CURLE_QUOTE_ERROR;
1301 else if(curl_strnequal(cmd, "chmod", 5)) {
1302 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1303 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1304 /* permissions are octal */
1305 if(sshc->quote_attrs.permissions == 0 &&
1306 !ISDIGIT(sshc->quote_path1[0])) {
1307 Curl_safefree(sshc->quote_path1);
1308 Curl_safefree(sshc->quote_path2);
1309 failf(data, "Syntax error: chmod permissions not a number");
1310 state(conn, SSH_SFTP_CLOSE);
1311 sshc->nextstate = SSH_NO_STATE;
1312 sshc->actualcode = CURLE_QUOTE_ERROR;
1316 else if(curl_strnequal(cmd, "chown", 5)) {
1317 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1318 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1319 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1320 !sshc->acceptfail) {
1321 Curl_safefree(sshc->quote_path1);
1322 Curl_safefree(sshc->quote_path2);
1323 failf(data, "Syntax error: chown uid not a number");
1324 state(conn, SSH_SFTP_CLOSE);
1325 sshc->nextstate = SSH_NO_STATE;
1326 sshc->actualcode = CURLE_QUOTE_ERROR;
1331 /* Now send the completed structure... */
1332 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1336 case SSH_SFTP_QUOTE_SETSTAT:
1337 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1338 curlx_uztoui(strlen(sshc->quote_path2)),
1339 LIBSSH2_SFTP_SETSTAT,
1340 &sshc->quote_attrs);
1341 if(rc == LIBSSH2_ERROR_EAGAIN) {
1344 else if(rc != 0 && !sshc->acceptfail) {
1345 err = sftp_libssh2_last_error(sshc->sftp_session);
1346 Curl_safefree(sshc->quote_path1);
1347 Curl_safefree(sshc->quote_path2);
1348 failf(data, "Attempt to set SFTP stats failed: %s",
1349 sftp_libssh2_strerror(err));
1350 state(conn, SSH_SFTP_CLOSE);
1351 sshc->nextstate = SSH_NO_STATE;
1352 sshc->actualcode = CURLE_QUOTE_ERROR;
1355 state(conn, SSH_SFTP_NEXT_QUOTE);
1358 case SSH_SFTP_QUOTE_SYMLINK:
1359 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1360 curlx_uztoui(strlen(sshc->quote_path1)),
1362 curlx_uztoui(strlen(sshc->quote_path2)),
1363 LIBSSH2_SFTP_SYMLINK);
1364 if(rc == LIBSSH2_ERROR_EAGAIN) {
1367 else if(rc != 0 && !sshc->acceptfail) {
1368 err = sftp_libssh2_last_error(sshc->sftp_session);
1369 Curl_safefree(sshc->quote_path1);
1370 Curl_safefree(sshc->quote_path2);
1371 failf(data, "symlink command failed: %s",
1372 sftp_libssh2_strerror(err));
1373 state(conn, SSH_SFTP_CLOSE);
1374 sshc->nextstate = SSH_NO_STATE;
1375 sshc->actualcode = CURLE_QUOTE_ERROR;
1378 state(conn, SSH_SFTP_NEXT_QUOTE);
1381 case SSH_SFTP_QUOTE_MKDIR:
1382 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1383 curlx_uztoui(strlen(sshc->quote_path1)),
1384 data->set.new_directory_perms);
1385 if(rc == LIBSSH2_ERROR_EAGAIN) {
1388 else if(rc != 0 && !sshc->acceptfail) {
1389 err = sftp_libssh2_last_error(sshc->sftp_session);
1390 Curl_safefree(sshc->quote_path1);
1391 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1392 state(conn, SSH_SFTP_CLOSE);
1393 sshc->nextstate = SSH_NO_STATE;
1394 sshc->actualcode = CURLE_QUOTE_ERROR;
1397 state(conn, SSH_SFTP_NEXT_QUOTE);
1400 case SSH_SFTP_QUOTE_RENAME:
1401 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1402 curlx_uztoui(strlen(sshc->quote_path1)),
1404 curlx_uztoui(strlen(sshc->quote_path2)),
1405 LIBSSH2_SFTP_RENAME_OVERWRITE |
1406 LIBSSH2_SFTP_RENAME_ATOMIC |
1407 LIBSSH2_SFTP_RENAME_NATIVE);
1409 if(rc == LIBSSH2_ERROR_EAGAIN) {
1412 else if(rc != 0 && !sshc->acceptfail) {
1413 err = sftp_libssh2_last_error(sshc->sftp_session);
1414 Curl_safefree(sshc->quote_path1);
1415 Curl_safefree(sshc->quote_path2);
1416 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1417 state(conn, SSH_SFTP_CLOSE);
1418 sshc->nextstate = SSH_NO_STATE;
1419 sshc->actualcode = CURLE_QUOTE_ERROR;
1422 state(conn, SSH_SFTP_NEXT_QUOTE);
1425 case SSH_SFTP_QUOTE_RMDIR:
1426 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1427 curlx_uztoui(strlen(sshc->quote_path1)));
1428 if(rc == LIBSSH2_ERROR_EAGAIN) {
1431 else if(rc != 0 && !sshc->acceptfail) {
1432 err = sftp_libssh2_last_error(sshc->sftp_session);
1433 Curl_safefree(sshc->quote_path1);
1434 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1435 state(conn, SSH_SFTP_CLOSE);
1436 sshc->nextstate = SSH_NO_STATE;
1437 sshc->actualcode = CURLE_QUOTE_ERROR;
1440 state(conn, SSH_SFTP_NEXT_QUOTE);
1443 case SSH_SFTP_QUOTE_UNLINK:
1444 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1445 curlx_uztoui(strlen(sshc->quote_path1)));
1446 if(rc == LIBSSH2_ERROR_EAGAIN) {
1449 else if(rc != 0 && !sshc->acceptfail) {
1450 err = sftp_libssh2_last_error(sshc->sftp_session);
1451 Curl_safefree(sshc->quote_path1);
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 curlx_uztoui(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 curlx_uztoui(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 = sftp_libssh2_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 curlx_uztoui(strlen(sftp_scp->path)),
1679 data->set.new_directory_perms);
1680 if(rc == LIBSSH2_ERROR_EAGAIN) {
1683 *sshc->slash_pos = '/';
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 err = sftp_libssh2_last_error(sshc->sftp_session);
1692 if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1693 (err != LIBSSH2_FX_FAILURE) &&
1694 (err != LIBSSH2_FX_PERMISSION_DENIED)) {
1695 result = sftp_libssh2_error_to_CURLE(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 = sftp_libssh2_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 state(conn, SSH_SFTP_CLOSE);
1738 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1741 state(conn, SSH_SFTP_READDIR);
1744 case SSH_SFTP_READDIR:
1745 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1746 sshc->readdir_filename,
1748 sshc->readdir_longentry,
1750 &sshc->readdir_attrs);
1751 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1752 rc = LIBSSH2_ERROR_EAGAIN;
1755 if(sshc->readdir_len > 0) {
1756 sshc->readdir_filename[sshc->readdir_len] = '\0';
1758 if(data->set.ftp_list_only) {
1761 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1762 if(tmpLine == NULL) {
1763 state(conn, SSH_SFTP_CLOSE);
1764 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1767 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1768 tmpLine, sshc->readdir_len+1);
1769 Curl_safefree(tmpLine);
1772 state(conn, SSH_STOP);
1775 /* since this counts what we send to the client, we include the
1776 newline in this counter */
1777 data->req.bytecount += sshc->readdir_len+1;
1779 /* output debug output if that is requested */
1780 if(data->set.verbose) {
1781 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1782 sshc->readdir_len, conn);
1786 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1787 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1788 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1789 if(!sshc->readdir_line) {
1790 Curl_safefree(sshc->readdir_filename);
1791 Curl_safefree(sshc->readdir_longentry);
1792 state(conn, SSH_SFTP_CLOSE);
1793 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1797 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1798 sshc->readdir_currLen);
1799 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1800 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1801 LIBSSH2_SFTP_S_IFLNK)) {
1802 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1803 if(sshc->readdir_linkPath == NULL) {
1804 Curl_safefree(sshc->readdir_filename);
1805 Curl_safefree(sshc->readdir_longentry);
1806 state(conn, SSH_SFTP_CLOSE);
1807 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1811 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1812 sshc->readdir_filename);
1813 state(conn, SSH_SFTP_READDIR_LINK);
1816 state(conn, SSH_SFTP_READDIR_BOTTOM);
1820 else if(sshc->readdir_len == 0) {
1821 Curl_safefree(sshc->readdir_filename);
1822 Curl_safefree(sshc->readdir_longentry);
1823 state(conn, SSH_SFTP_READDIR_DONE);
1826 else if(sshc->readdir_len <= 0) {
1827 err = sftp_libssh2_last_error(sshc->sftp_session);
1828 result = sftp_libssh2_error_to_CURLE(err);
1829 sshc->actualcode = result?result:CURLE_SSH;
1830 failf(data, "Could not open remote file for reading: %s :: %d",
1831 sftp_libssh2_strerror(err),
1832 libssh2_session_last_errno(sshc->ssh_session));
1833 Curl_safefree(sshc->readdir_filename);
1834 Curl_safefree(sshc->readdir_longentry);
1835 state(conn, SSH_SFTP_CLOSE);
1840 case SSH_SFTP_READDIR_LINK:
1842 libssh2_sftp_symlink_ex(sshc->sftp_session,
1843 sshc->readdir_linkPath,
1844 curlx_uztoui(strlen(sshc->readdir_linkPath)),
1845 sshc->readdir_filename,
1846 PATH_MAX, LIBSSH2_SFTP_READLINK);
1847 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1848 rc = LIBSSH2_ERROR_EAGAIN;
1851 Curl_safefree(sshc->readdir_linkPath);
1853 /* get room for the filename and extra output */
1854 sshc->readdir_totalLen += 4 + sshc->readdir_len;
1855 new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
1856 if(!new_readdir_line) {
1857 Curl_safefree(sshc->readdir_line);
1858 Curl_safefree(sshc->readdir_filename);
1859 Curl_safefree(sshc->readdir_longentry);
1860 state(conn, SSH_SFTP_CLOSE);
1861 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1864 sshc->readdir_line = new_readdir_line;
1866 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1867 sshc->readdir_currLen,
1868 sshc->readdir_totalLen -
1869 sshc->readdir_currLen,
1871 sshc->readdir_filename);
1873 state(conn, SSH_SFTP_READDIR_BOTTOM);
1876 case SSH_SFTP_READDIR_BOTTOM:
1877 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1878 sshc->readdir_currLen,
1879 sshc->readdir_totalLen -
1880 sshc->readdir_currLen, "\n");
1881 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1883 sshc->readdir_currLen);
1885 if(result == CURLE_OK) {
1887 /* output debug output if that is requested */
1888 if(data->set.verbose) {
1889 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1890 sshc->readdir_currLen, conn);
1892 data->req.bytecount += sshc->readdir_currLen;
1894 Curl_safefree(sshc->readdir_line);
1896 state(conn, SSH_STOP);
1899 state(conn, SSH_SFTP_READDIR);
1902 case SSH_SFTP_READDIR_DONE:
1903 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1904 LIBSSH2_ERROR_EAGAIN) {
1905 rc = LIBSSH2_ERROR_EAGAIN;
1908 sshc->sftp_handle = NULL;
1909 Curl_safefree(sshc->readdir_filename);
1910 Curl_safefree(sshc->readdir_longentry);
1912 /* no data to transfer */
1913 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1914 state(conn, SSH_STOP);
1917 case SSH_SFTP_DOWNLOAD_INIT:
1919 * Work on getting the specified file
1922 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1923 curlx_uztoui(strlen(sftp_scp->path)),
1924 LIBSSH2_FXF_READ, data->set.new_file_perms,
1925 LIBSSH2_SFTP_OPENFILE);
1926 if(!sshc->sftp_handle) {
1927 if(libssh2_session_last_errno(sshc->ssh_session) ==
1928 LIBSSH2_ERROR_EAGAIN) {
1929 rc = LIBSSH2_ERROR_EAGAIN;
1933 err = sftp_libssh2_last_error(sshc->sftp_session);
1934 failf(data, "Could not open remote file for reading: %s",
1935 sftp_libssh2_strerror(err));
1936 state(conn, SSH_SFTP_CLOSE);
1937 result = sftp_libssh2_error_to_CURLE(err);
1938 sshc->actualcode = result?result:CURLE_SSH;
1942 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1945 case SSH_SFTP_DOWNLOAD_STAT:
1947 LIBSSH2_SFTP_ATTRIBUTES attrs;
1949 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1950 curlx_uztoui(strlen(sftp_scp->path)),
1951 LIBSSH2_SFTP_STAT, &attrs);
1952 if(rc == LIBSSH2_ERROR_EAGAIN) {
1957 * libssh2_sftp_open() didn't return an error, so maybe the server
1958 * just doesn't support stat()
1960 data->req.size = -1;
1961 data->req.maxdownload = -1;
1964 curl_off_t size = attrs.filesize;
1967 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1968 return CURLE_BAD_DOWNLOAD_RESUME;
1970 if(conn->data->state.use_range) {
1971 curl_off_t from, to;
1975 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1976 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
1978 to=curlx_strtoofft(ptr, &ptr2, 0);
1979 if((ptr == ptr2) /* no "to" value given */
1984 /* from is relative to end of file */
1988 failf(data, "Offset (%"
1989 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1990 from, attrs.filesize);
1991 return CURLE_BAD_DOWNLOAD_RESUME;
1998 size = to - from + 1;
2001 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2003 data->req.size = size;
2004 data->req.maxdownload = size;
2005 Curl_pgrsSetDownloadSize(data, size);
2008 /* We can resume if we can seek to the resume position */
2009 if(data->state.resume_from) {
2010 if(data->state.resume_from < 0) {
2011 /* We're supposed to download the last abs(from) bytes */
2012 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2013 failf(data, "Offset (%"
2014 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2015 data->state.resume_from, attrs.filesize);
2016 return CURLE_BAD_DOWNLOAD_RESUME;
2018 /* download from where? */
2019 data->state.resume_from += attrs.filesize;
2022 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2023 failf(data, "Offset (%" FORMAT_OFF_T
2024 ") was beyond file size (%" FORMAT_OFF_T ")",
2025 data->state.resume_from, attrs.filesize);
2026 return CURLE_BAD_DOWNLOAD_RESUME;
2029 /* Does a completed file need to be seeked and started or closed ? */
2030 /* Now store the number of bytes we are expected to download */
2031 data->req.size = attrs.filesize - data->state.resume_from;
2032 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2033 Curl_pgrsSetDownloadSize(data,
2034 attrs.filesize - data->state.resume_from);
2035 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2038 /* Setup the actual download */
2039 if(data->req.size == 0) {
2040 /* no data to transfer */
2041 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2042 infof(data, "File already completely downloaded\n");
2043 state(conn, SSH_STOP);
2047 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2048 FALSE, NULL, -1, NULL);
2050 /* not set by Curl_setup_transfer to preserve keepon bits */
2051 conn->writesockfd = conn->sockfd;
2053 /* we want to use the _receiving_ function even when the socket turns
2054 out writableable as the underlying libssh2 recv function will deal
2055 with both accordingly */
2056 conn->cselect_bits = CURL_CSELECT_IN;
2059 state(conn, SSH_SFTP_CLOSE);
2060 sshc->actualcode = result;
2063 state(conn, SSH_STOP);
2067 case SSH_SFTP_CLOSE:
2068 if(sshc->sftp_handle) {
2069 rc = libssh2_sftp_close(sshc->sftp_handle);
2070 if(rc == LIBSSH2_ERROR_EAGAIN) {
2074 infof(data, "Failed to close libssh2 file\n");
2076 sshc->sftp_handle = NULL;
2079 Curl_safefree(sftp_scp->path);
2081 DEBUGF(infof(data, "SFTP DONE done\n"));
2083 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2084 After nextstate is executed,the control should come back to
2085 SSH_SFTP_CLOSE to pass the correct result back */
2086 if(sshc->nextstate != SSH_NO_STATE) {
2087 state(conn, sshc->nextstate);
2088 sshc->nextstate = SSH_SFTP_CLOSE;
2091 state(conn, SSH_STOP);
2092 result = sshc->actualcode;
2096 case SSH_SFTP_SHUTDOWN:
2097 /* during times we get here due to a broken transfer and then the
2098 sftp_handle might not have been taken down so make sure that is done
2099 before we proceed */
2101 if(sshc->sftp_handle) {
2102 rc = libssh2_sftp_close(sshc->sftp_handle);
2103 if(rc == LIBSSH2_ERROR_EAGAIN) {
2107 infof(data, "Failed to close libssh2 file\n");
2109 sshc->sftp_handle = NULL;
2111 if(sshc->sftp_session) {
2112 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2113 if(rc == LIBSSH2_ERROR_EAGAIN) {
2117 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2119 sshc->sftp_session = NULL;
2122 Curl_safefree(sshc->homedir);
2123 conn->data->state.most_recent_ftp_entrypath = NULL;
2125 state(conn, SSH_SESSION_DISCONNECT);
2128 case SSH_SCP_TRANS_INIT:
2129 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2131 sshc->actualcode = result;
2132 state(conn, SSH_STOP);
2136 if(data->set.upload) {
2137 if(data->set.infilesize < 0) {
2138 failf(data, "SCP requires a known file size for upload");
2139 sshc->actualcode = CURLE_UPLOAD_FAILED;
2140 state(conn, SSH_SCP_CHANNEL_FREE);
2143 state(conn, SSH_SCP_UPLOAD_INIT);
2146 state(conn, SSH_SCP_DOWNLOAD_INIT);
2150 case SSH_SCP_UPLOAD_INIT:
2152 * libssh2 requires that the destination path is a full path that
2153 * includes the destination file and name OR ends in a "/" . If this is
2154 * not done the destination file will be named the same name as the last
2155 * directory in the path.
2158 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2159 data->set.infilesize);
2160 if(!sshc->ssh_channel) {
2161 if(libssh2_session_last_errno(sshc->ssh_session) ==
2162 LIBSSH2_ERROR_EAGAIN) {
2163 rc = LIBSSH2_ERROR_EAGAIN;
2170 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2171 &err_msg, NULL, 0));
2172 failf(conn->data, "%s", err_msg);
2173 state(conn, SSH_SCP_CHANNEL_FREE);
2174 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2180 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2183 /* not set by Curl_setup_transfer to preserve keepon bits */
2184 conn->sockfd = conn->writesockfd;
2187 state(conn, SSH_SCP_CHANNEL_FREE);
2188 sshc->actualcode = result;
2191 /* we want to use the _sending_ function even when the socket turns
2192 out readable as the underlying libssh2 scp send function will deal
2193 with both accordingly */
2194 conn->cselect_bits = CURL_CSELECT_OUT;
2196 state(conn, SSH_STOP);
2200 case SSH_SCP_DOWNLOAD_INIT:
2203 * We must check the remote file; if it is a directory no values will
2207 curl_off_t bytecount;
2209 /* clear the struct scp recv will fill in */
2210 memset(&sb, 0, sizeof(struct stat));
2212 /* get a fresh new channel from the ssh layer */
2213 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2214 sftp_scp->path, &sb);
2215 if(!sshc->ssh_channel) {
2216 if(libssh2_session_last_errno(sshc->ssh_session) ==
2217 LIBSSH2_ERROR_EAGAIN) {
2218 rc = LIBSSH2_ERROR_EAGAIN;
2225 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2226 &err_msg, NULL, 0));
2227 failf(conn->data, "%s", err_msg);
2228 state(conn, SSH_SCP_CHANNEL_FREE);
2229 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2235 bytecount = (curl_off_t)sb.st_size;
2236 data->req.maxdownload = (curl_off_t)sb.st_size;
2237 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2239 /* not set by Curl_setup_transfer to preserve keepon bits */
2240 conn->writesockfd = conn->sockfd;
2242 /* we want to use the _receiving_ function even when the socket turns
2243 out writableable as the underlying libssh2 recv function will deal
2244 with both accordingly */
2245 conn->cselect_bits = CURL_CSELECT_IN;
2248 state(conn, SSH_SCP_CHANNEL_FREE);
2249 sshc->actualcode = result;
2252 state(conn, SSH_STOP);
2257 if(data->set.upload)
2258 state(conn, SSH_SCP_SEND_EOF);
2260 state(conn, SSH_SCP_CHANNEL_FREE);
2263 case SSH_SCP_SEND_EOF:
2264 if(sshc->ssh_channel) {
2265 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2266 if(rc == LIBSSH2_ERROR_EAGAIN) {
2270 infof(data, "Failed to send libssh2 channel EOF\n");
2273 state(conn, SSH_SCP_WAIT_EOF);
2276 case SSH_SCP_WAIT_EOF:
2277 if(sshc->ssh_channel) {
2278 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2279 if(rc == LIBSSH2_ERROR_EAGAIN) {
2283 infof(data, "Failed to get channel EOF: %d\n", rc);
2286 state(conn, SSH_SCP_WAIT_CLOSE);
2289 case SSH_SCP_WAIT_CLOSE:
2290 if(sshc->ssh_channel) {
2291 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2292 if(rc == LIBSSH2_ERROR_EAGAIN) {
2296 infof(data, "Channel failed to close: %d\n", rc);
2299 state(conn, SSH_SCP_CHANNEL_FREE);
2302 case SSH_SCP_CHANNEL_FREE:
2303 if(sshc->ssh_channel) {
2304 rc = libssh2_channel_free(sshc->ssh_channel);
2305 if(rc == LIBSSH2_ERROR_EAGAIN) {
2309 infof(data, "Failed to free libssh2 scp subsystem\n");
2311 sshc->ssh_channel = NULL;
2313 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2315 state(conn, SSH_SESSION_DISCONNECT);
2317 state(conn, SSH_STOP);
2318 result = sshc->actualcode;
2321 case SSH_SESSION_DISCONNECT:
2322 /* during weird times when we've been prematurely aborted, the channel
2323 is still alive when we reach this state and we MUST kill the channel
2325 if(sshc->ssh_channel) {
2326 rc = libssh2_channel_free(sshc->ssh_channel);
2327 if(rc == LIBSSH2_ERROR_EAGAIN) {
2331 infof(data, "Failed to free libssh2 scp subsystem\n");
2333 sshc->ssh_channel = NULL;
2336 if(sshc->ssh_session) {
2337 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2338 if(rc == LIBSSH2_ERROR_EAGAIN) {
2342 infof(data, "Failed to disconnect libssh2 session\n");
2346 Curl_safefree(sshc->homedir);
2347 conn->data->state.most_recent_ftp_entrypath = NULL;
2349 state(conn, SSH_SESSION_FREE);
2352 case SSH_SESSION_FREE:
2353 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2355 libssh2_knownhost_free(sshc->kh);
2360 if(sshc->ssh_session) {
2361 rc = libssh2_session_free(sshc->ssh_session);
2362 if(rc == LIBSSH2_ERROR_EAGAIN) {
2366 infof(data, "Failed to free libssh2 session\n");
2368 sshc->ssh_session = NULL;
2371 /* worst-case scenario cleanup */
2373 DEBUGASSERT(sshc->ssh_session == NULL);
2374 DEBUGASSERT(sshc->ssh_channel == NULL);
2375 DEBUGASSERT(sshc->sftp_session == NULL);
2376 DEBUGASSERT(sshc->sftp_handle == NULL);
2377 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2378 DEBUGASSERT(sshc->kh == NULL);
2381 Curl_safefree(sshc->rsa_pub);
2382 Curl_safefree(sshc->rsa);
2384 Curl_safefree(sshc->quote_path1);
2385 Curl_safefree(sshc->quote_path2);
2387 Curl_safefree(sshc->homedir);
2389 Curl_safefree(sshc->readdir_filename);
2390 Curl_safefree(sshc->readdir_longentry);
2391 Curl_safefree(sshc->readdir_line);
2392 Curl_safefree(sshc->readdir_linkPath);
2394 /* the code we are about to return */
2395 result = sshc->actualcode;
2397 memset(sshc, 0, sizeof(struct ssh_conn));
2399 conn->bits.close = TRUE;
2400 sshc->state = SSH_SESSION_FREE; /* current */
2401 sshc->nextstate = SSH_NO_STATE;
2402 state(conn, SSH_STOP);
2406 /* fallthrough, just stop! */
2408 /* internal error */
2409 sshc->nextstate = SSH_NO_STATE;
2410 state(conn, SSH_STOP);
2414 } while(!rc && (sshc->state != SSH_STOP));
2416 if(rc == LIBSSH2_ERROR_EAGAIN) {
2417 /* we would block, we need to wait for the socket to be ready (in the
2418 right direction too)! */
2425 /* called by the multi interface to figure out what socket(s) to wait for and
2426 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2427 static int ssh_perform_getsock(const struct connectdata *conn,
2428 curl_socket_t *sock, /* points to numsocks
2429 number of sockets */
2432 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2433 int bitmap = GETSOCK_BLANK;
2436 sock[0] = conn->sock[FIRSTSOCKET];
2438 if(conn->waitfor & KEEP_RECV)
2439 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2441 if(conn->waitfor & KEEP_SEND)
2442 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2446 /* if we don't know the direction we can use the generic *_getsock()
2447 function even for the protocol_connect and doing states */
2448 return Curl_single_getsock(conn, sock, numsocks);
2452 /* Generic function called by the multi interface to figure out what socket(s)
2453 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2454 static int ssh_getsock(struct connectdata *conn,
2455 curl_socket_t *sock, /* points to numsocks number
2459 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2463 /* if we don't know any direction we can just play along as we used to and
2464 not provide any sensible info */
2465 return GETSOCK_BLANK;
2467 /* if we know the direction we can use the generic *_getsock() function even
2468 for the protocol_connect and doing states */
2469 return ssh_perform_getsock(conn, sock, numsocks);
2473 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2475 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2476 * function is used to figure out in what direction and stores this info so
2477 * that the multi interface can take advantage of it. Make sure to call this
2478 * function in all cases so that when it _doesn't_ return EAGAIN we can
2479 * restore the default wait bits.
2481 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2483 struct ssh_conn *sshc = &conn->proto.sshc;
2487 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2488 /* translate the libssh2 define bits into our own bit defines */
2489 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2490 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2493 /* It didn't block or libssh2 didn't reveal in which direction, put back
2495 conn->waitfor = sshc->orig_waitfor;
2498 /* no libssh2 directional support so we simply don't know */
2499 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2502 /* called repeatedly until done from multi.c */
2503 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2505 struct ssh_conn *sshc = &conn->proto.sshc;
2506 CURLcode result = CURLE_OK;
2507 bool block; /* we store the status and use that to provide a ssh_getsock()
2510 result = ssh_statemach_act(conn, &block);
2511 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2512 ssh_block2waitfor(conn, block);
2517 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2520 struct ssh_conn *sshc = &conn->proto.sshc;
2521 CURLcode result = CURLE_OK;
2522 struct SessionHandle *data = conn->data;
2524 while((sshc->state != SSH_STOP) && !result) {
2528 result = ssh_statemach_act(conn, &block);
2532 if(Curl_pgrsUpdate(conn))
2533 return CURLE_ABORTED_BY_CALLBACK;
2535 struct timeval now = Curl_tvnow();
2536 result = Curl_speedcheck(data, now);
2541 left = Curl_timeleft(data, NULL, duringconnect);
2543 failf(data, "Operation timed out\n");
2544 return CURLE_OPERATION_TIMEDOUT;
2547 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2548 if((CURLE_OK == result) && block) {
2549 int dir = libssh2_session_block_directions(sshc->ssh_session);
2550 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2551 curl_socket_t fd_read = CURL_SOCKET_BAD;
2552 curl_socket_t fd_write = CURL_SOCKET_BAD;
2553 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2555 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2557 /* wait for the socket to become ready */
2558 Curl_socket_ready(fd_read, fd_write,
2559 left>1000?1000:left); /* ignore result */
2569 * SSH setup and connection
2571 static CURLcode ssh_init(struct connectdata *conn)
2573 struct SessionHandle *data = conn->data;
2574 struct SSHPROTO *ssh;
2575 struct ssh_conn *sshc = &conn->proto.sshc;
2577 sshc->actualcode = CURLE_OK; /* reset error code */
2578 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2581 if(data->state.proto.ssh)
2584 ssh = calloc(1, sizeof(struct SSHPROTO));
2586 return CURLE_OUT_OF_MEMORY;
2588 data->state.proto.ssh = ssh;
2593 static Curl_recv scp_recv, sftp_recv;
2594 static Curl_send scp_send, sftp_send;
2597 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2598 * do protocol-specific actions at connect-time.
2600 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2602 #ifdef CURL_LIBSSH2_DEBUG
2605 struct ssh_conn *ssh;
2607 struct SessionHandle *data = conn->data;
2609 /* We default to persistent connections. We set this already in this connect
2610 function to make the re-use checks properly be able to check this bit. */
2611 conn->bits.close = FALSE;
2613 /* If there already is a protocol-specific struct allocated for this
2614 sessionhandle, deal with it */
2615 Curl_reset_reqproto(conn);
2617 result = ssh_init(conn);
2621 if(conn->handler->protocol & CURLPROTO_SCP) {
2622 conn->recv[FIRSTSOCKET] = scp_recv;
2623 conn->send[FIRSTSOCKET] = scp_send;
2626 conn->recv[FIRSTSOCKET] = sftp_recv;
2627 conn->send[FIRSTSOCKET] = sftp_send;
2629 ssh = &conn->proto.sshc;
2631 #ifdef CURL_LIBSSH2_DEBUG
2633 infof(data, "User: %s\n", conn->user);
2636 infof(data, "Password: %s\n", conn->passwd);
2638 sock = conn->sock[FIRSTSOCKET];
2639 #endif /* CURL_LIBSSH2_DEBUG */
2641 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2643 my_libssh2_realloc, conn);
2644 if(ssh->ssh_session == NULL) {
2645 failf(data, "Failure initialising ssh session");
2646 return CURLE_FAILED_INIT;
2649 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2650 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2652 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2654 /* eeek. TODO: free the ssh_session! */
2655 return CURLE_FAILED_INIT;
2658 /* read all known hosts from there */
2659 rc = libssh2_knownhost_readfile(ssh->kh,
2660 data->set.str[STRING_SSH_KNOWNHOSTS],
2661 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2663 infof(data, "Failed to read known hosts from %s\n",
2664 data->set.str[STRING_SSH_KNOWNHOSTS]);
2666 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2668 #ifdef CURL_LIBSSH2_DEBUG
2669 libssh2_trace(ssh->ssh_session, ~0);
2670 infof(data, "SSH socket: %d\n", (int)sock);
2671 #endif /* CURL_LIBSSH2_DEBUG */
2673 state(conn, SSH_INIT);
2675 if(data->state.used_interface == Curl_if_multi)
2676 result = ssh_multi_statemach(conn, done);
2678 result = ssh_easy_statemach(conn, TRUE);
2687 ***********************************************************************
2691 * This is the actual DO function for SCP. Get a file according to
2692 * the options previously setup.
2696 CURLcode scp_perform(struct connectdata *conn,
2700 CURLcode result = CURLE_OK;
2702 DEBUGF(infof(conn->data, "DO phase starts\n"));
2704 *dophase_done = FALSE; /* not done yet */
2706 /* start the first command in the DO phase */
2707 state(conn, SSH_SCP_TRANS_INIT);
2709 /* run the state-machine */
2710 if(conn->data->state.used_interface == Curl_if_multi) {
2711 result = ssh_multi_statemach(conn, dophase_done);
2714 result = ssh_easy_statemach(conn, FALSE);
2715 *dophase_done = TRUE; /* with the easy interface we are done here */
2717 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2720 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2726 /* called from multi.c while DOing */
2727 static CURLcode scp_doing(struct connectdata *conn,
2731 result = ssh_multi_statemach(conn, dophase_done);
2734 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2740 * The DO function is generic for both protocols. There was previously two
2741 * separate ones but this way means less duplicated code.
2744 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2748 struct SessionHandle *data = conn->data;
2750 *done = FALSE; /* default to false */
2753 Since connections can be re-used between SessionHandles, this might be a
2754 connection already existing but on a fresh SessionHandle struct so we must
2755 make sure we have a good 'struct SSHPROTO' to play with. For new
2756 connections, the struct SSHPROTO is allocated and setup in the
2757 ssh_connect() function.
2759 Curl_reset_reqproto(conn);
2760 res = ssh_init(conn);
2764 data->req.size = -1; /* make sure this is unknown at this point */
2766 Curl_pgrsSetUploadCounter(data, 0);
2767 Curl_pgrsSetDownloadCounter(data, 0);
2768 Curl_pgrsSetUploadSize(data, 0);
2769 Curl_pgrsSetDownloadSize(data, 0);
2771 if(conn->handler->protocol & CURLPROTO_SCP)
2772 res = scp_perform(conn, &connected, done);
2774 res = sftp_perform(conn, &connected, done);
2779 /* BLOCKING, but the function is using the state machine so the only reason
2780 this is still blocking is that the multi interface code has no support for
2781 disconnecting operations that takes a while */
2782 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2784 CURLcode result = CURLE_OK;
2785 struct ssh_conn *ssh = &conn->proto.sshc;
2786 (void) dead_connection;
2788 Curl_safefree(conn->data->state.proto.ssh);
2790 if(ssh->ssh_session) {
2791 /* only if there's a session still around to use! */
2793 state(conn, SSH_SESSION_DISCONNECT);
2795 result = ssh_easy_statemach(conn, FALSE);
2801 /* generic done function for both SCP and SFTP called from their specific
2803 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2805 CURLcode result = CURLE_OK;
2806 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2808 if(status == CURLE_OK) {
2809 /* run the state-machine
2811 TODO: when the multi interface is used, this _really_ should be using
2812 the ssh_multi_statemach function but we have no general support for
2813 non-blocking DONE operations, not in the multi state machine and with
2814 Curl_done() invokes on several places in the code!
2816 result = ssh_easy_statemach(conn, FALSE);
2822 Curl_safefree(sftp_scp->path);
2823 if(Curl_pgrsDone(conn))
2824 return CURLE_ABORTED_BY_CALLBACK;
2826 conn->data->req.keepon = 0; /* clear all bits */
2831 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2834 (void)premature; /* not used */
2836 if(status == CURLE_OK)
2837 state(conn, SSH_SCP_DONE);
2839 return ssh_done(conn, status);
2843 /* return number of received (decrypted) bytes */
2844 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2845 const void *mem, size_t len, CURLcode *err)
2848 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2850 /* libssh2_channel_write() returns int! */
2852 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2854 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2856 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2865 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2866 * a regular CURLcode value.
2868 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2869 char *mem, size_t len, CURLcode *err)
2872 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2874 /* libssh2_channel_read() returns int */
2876 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2878 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2879 if(nread == LIBSSH2_ERROR_EAGAIN) {
2888 * =============== SFTP ===============
2892 ***********************************************************************
2896 * This is the actual DO function for SFTP. Get a file/directory according to
2897 * the options previously setup.
2901 CURLcode sftp_perform(struct connectdata *conn,
2905 CURLcode result = CURLE_OK;
2907 DEBUGF(infof(conn->data, "DO phase starts\n"));
2909 *dophase_done = FALSE; /* not done yet */
2911 /* start the first command in the DO phase */
2912 state(conn, SSH_SFTP_QUOTE_INIT);
2914 /* run the state-machine */
2915 if(conn->data->state.used_interface == Curl_if_multi) {
2916 result = ssh_multi_statemach(conn, dophase_done);
2919 result = ssh_easy_statemach(conn, FALSE);
2920 *dophase_done = TRUE; /* with the easy interface we are done here */
2922 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2925 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2931 /* called from multi.c while DOing */
2932 static CURLcode sftp_doing(struct connectdata *conn,
2936 result = ssh_multi_statemach(conn, dophase_done);
2939 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2944 /* BLOCKING, but the function is using the state machine so the only reason
2945 this is still blocking is that the multi interface code has no support for
2946 disconnecting operations that takes a while */
2947 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
2949 CURLcode result = CURLE_OK;
2950 (void) dead_connection;
2952 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2954 Curl_safefree(conn->data->state.proto.ssh);
2956 if(conn->proto.sshc.ssh_session) {
2957 /* only if there's a session still around to use! */
2958 state(conn, SSH_SFTP_SHUTDOWN);
2959 result = ssh_easy_statemach(conn, FALSE);
2962 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2968 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2971 struct ssh_conn *sshc = &conn->proto.sshc;
2973 if(status == CURLE_OK) {
2974 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
2975 errors that could happen due to open file handles during POSTQUOTE
2977 if(!status && !premature && conn->data->set.postquote) {
2978 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
2979 state(conn, SSH_SFTP_CLOSE);
2982 state(conn, SSH_SFTP_CLOSE);
2984 return ssh_done(conn, status);
2987 /* return number of sent bytes */
2988 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
2989 const void *mem, size_t len, CURLcode *err)
2991 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2992 but is changed to ssize_t in 0.15. These days we don't
2993 support libssh2 0.15*/
2996 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2998 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3000 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3009 * Return number of received (decrypted) bytes
3011 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3012 char *mem, size_t len, CURLcode *err)
3017 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3019 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3021 if(nread == LIBSSH2_ERROR_EAGAIN) {
3028 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3031 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3033 * Permission to use, copy, modify, and distribute this software for any
3034 * purpose with or without fee is hereby granted, provided that the above
3035 * copyright notice and this permission notice appear in all copies.
3037 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3038 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3039 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3040 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3041 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3042 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3043 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3046 get_pathname(const char **cpp, char **path)
3048 const char *cp = *cpp, *end;
3051 static const char WHITESPACE[] = " \t\r\n";
3053 cp += strspn(cp, WHITESPACE);
3057 return CURLE_QUOTE_ERROR;
3060 *path = malloc(strlen(cp) + 1);
3062 return CURLE_OUT_OF_MEMORY;
3064 /* Check for quoted filenames */
3065 if(*cp == '\"' || *cp == '\'') {
3068 /* Search for terminating quote, unescape some chars */
3069 for(i = j = 0; i <= strlen(cp); i++) {
3070 if(cp[i] == quot) { /* Found quote */
3075 if(cp[i] == '\0') { /* End of string */
3076 /*error("Unterminated quote");*/
3079 if(cp[i] == '\\') { /* Escaped characters */
3081 if(cp[i] != '\'' && cp[i] != '\"' &&
3083 /*error("Bad escaped character '\\%c'",
3088 (*path)[j++] = cp[i];
3092 /*error("Empty quotes");*/
3095 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3098 /* Read to end of filename */
3099 end = strpbrk(cp, WHITESPACE);
3101 end = strchr(cp, '\0');
3102 *cpp = end + strspn(end, WHITESPACE);
3104 memcpy(*path, cp, end - cp);
3105 (*path)[end - cp] = '\0';
3110 Curl_safefree(*path);
3111 return CURLE_QUOTE_ERROR;
3115 static const char *sftp_libssh2_strerror(int err)
3118 case LIBSSH2_FX_NO_SUCH_FILE:
3119 return "No such file or directory";
3121 case LIBSSH2_FX_PERMISSION_DENIED:
3122 return "Permission denied";
3124 case LIBSSH2_FX_FAILURE:
3125 return "Operation failed";
3127 case LIBSSH2_FX_BAD_MESSAGE:
3128 return "Bad message from SFTP server";
3130 case LIBSSH2_FX_NO_CONNECTION:
3131 return "Not connected to SFTP server";
3133 case LIBSSH2_FX_CONNECTION_LOST:
3134 return "Connection to SFTP server lost";
3136 case LIBSSH2_FX_OP_UNSUPPORTED:
3137 return "Operation not supported by SFTP server";
3139 case LIBSSH2_FX_INVALID_HANDLE:
3140 return "Invalid handle";
3142 case LIBSSH2_FX_NO_SUCH_PATH:
3143 return "No such file or directory";
3145 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3146 return "File already exists";
3148 case LIBSSH2_FX_WRITE_PROTECT:
3149 return "File is write protected";
3151 case LIBSSH2_FX_NO_MEDIA:
3154 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3157 case LIBSSH2_FX_QUOTA_EXCEEDED:
3158 return "User quota exceeded";
3160 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3161 return "Unknown principle";
3163 case LIBSSH2_FX_LOCK_CONFlICT:
3164 return "File lock conflict";
3166 case LIBSSH2_FX_DIR_NOT_EMPTY:
3167 return "Directory not empty";
3169 case LIBSSH2_FX_NOT_A_DIRECTORY:
3170 return "Not a directory";
3172 case LIBSSH2_FX_INVALID_FILENAME:
3173 return "Invalid filename";
3175 case LIBSSH2_FX_LINK_LOOP:
3176 return "Link points to itself";
3178 return "Unknown error in libssh2";
3181 #endif /* USE_LIBSSH2 */