1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2010, 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 */
38 #include <libssh2_sftp.h>
53 #ifdef HAVE_SYS_SOCKET_H
54 #include <sys/socket.h>
56 #ifdef HAVE_NETINET_IN_H
57 #include <netinet/in.h>
59 #ifdef HAVE_ARPA_INET_H
60 #include <arpa/inet.h>
63 #include <sys/utsname.h>
74 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
76 #define in_addr_t unsigned long
79 #include <curl/curl.h>
82 #include "easyif.h" /* for Curl_convert_... prototypes */
88 #include "http.h" /* for HTTP proxy tunnel stuff */
91 #include "speedcheck.h"
98 #include "inet_ntop.h"
99 #include "parsedate.h" /* for the week day and month names */
100 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
101 #include "strtoofft.h"
105 #define _MPRINTF_REPLACE /* use our functions only */
106 #include <curl/mprintf.h>
108 #include "curl_memory.h"
109 /* The last #include file should be: */
110 #include "memdebug.h"
113 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
114 have their definition hidden well */
117 /* Local functions: */
118 static const char *sftp_libssh2_strerror(unsigned long err);
119 static LIBSSH2_ALLOC_FUNC(libssh2_malloc);
120 static LIBSSH2_REALLOC_FUNC(libssh2_realloc);
121 static LIBSSH2_FREE_FUNC(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);
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);
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 ssh_perform_getsock, /* perform_getsock */
175 scp_disconnect, /* disconnect */
176 PORT_SSH, /* defport */
177 PROT_SCP /* protocol */
182 * SFTP protocol handler.
185 const struct Curl_handler Curl_handler_sftp = {
187 ZERO_NULL, /* setup_connection */
189 sftp_done, /* done */
190 ZERO_NULL, /* do_more */
191 ssh_connect, /* connect_it */
192 ssh_multi_statemach, /* connecting */
193 sftp_doing, /* doing */
194 ssh_getsock, /* proto_getsock */
195 ssh_getsock, /* doing_getsock */
196 ssh_perform_getsock, /* perform_getsock */
197 sftp_disconnect, /* disconnect */
198 PORT_SSH, /* defport */
199 PROT_SFTP /* protocol */
204 kbd_callback(const char *name, int name_len, const char *instruction,
205 int instruction_len, int num_prompts,
206 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
207 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
210 struct connectdata *conn = (struct connectdata *)*abstract;
212 #ifdef CURL_LIBSSH2_DEBUG
213 fprintf(stderr, "name=%s\n", name);
214 fprintf(stderr, "name_len=%d\n", name_len);
215 fprintf(stderr, "instruction=%s\n", instruction);
216 fprintf(stderr, "instruction_len=%d\n", instruction_len);
217 fprintf(stderr, "num_prompts=%d\n", num_prompts);
222 (void)instruction_len;
223 #endif /* CURL_LIBSSH2_DEBUG */
224 if(num_prompts == 1) {
225 responses[0].text = strdup(conn->passwd);
226 responses[0].length = (unsigned int)strlen(conn->passwd);
232 static CURLcode sftp_libssh2_error_to_CURLE(int err)
238 case LIBSSH2_FX_NO_SUCH_FILE:
239 case LIBSSH2_FX_NO_SUCH_PATH:
240 return CURLE_REMOTE_FILE_NOT_FOUND;
242 case LIBSSH2_FX_PERMISSION_DENIED:
243 case LIBSSH2_FX_WRITE_PROTECT:
244 case LIBSSH2_FX_LOCK_CONFlICT:
245 return CURLE_REMOTE_ACCESS_DENIED;
247 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
248 case LIBSSH2_FX_QUOTA_EXCEEDED:
249 return CURLE_REMOTE_DISK_FULL;
251 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
252 return CURLE_REMOTE_FILE_EXISTS;
254 case LIBSSH2_FX_DIR_NOT_EMPTY:
255 return CURLE_QUOTE_ERROR;
264 static CURLcode libssh2_session_error_to_CURLE(int err)
267 /* Ordered by order of appearance in libssh2.h */
268 case LIBSSH2_ERROR_NONE:
271 case LIBSSH2_ERROR_SOCKET_NONE:
272 return CURLE_COULDNT_CONNECT;
274 case LIBSSH2_ERROR_ALLOC:
275 return CURLE_OUT_OF_MEMORY;
277 case LIBSSH2_ERROR_SOCKET_SEND:
278 return CURLE_SEND_ERROR;
280 case LIBSSH2_ERROR_HOSTKEY_INIT:
281 case LIBSSH2_ERROR_HOSTKEY_SIGN:
282 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
283 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
284 return CURLE_PEER_FAILED_VERIFICATION;
286 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
287 return CURLE_LOGIN_DENIED;
289 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
290 case LIBSSH2_ERROR_TIMEOUT:
291 return CURLE_OPERATION_TIMEDOUT;
293 case LIBSSH2_ERROR_EAGAIN:
297 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
298 error code, and possibly add a few new SSH-related one. We must however
299 not return or even depend on libssh2 errors in the public libcurl API */
304 static LIBSSH2_ALLOC_FUNC(libssh2_malloc)
306 (void)abstract; /* arg not used */
307 return malloc(count);
310 static LIBSSH2_REALLOC_FUNC(libssh2_realloc)
312 (void)abstract; /* arg not used */
313 return realloc(ptr, count);
316 static LIBSSH2_FREE_FUNC(libssh2_free)
318 (void)abstract; /* arg not used */
323 * SSH State machine related code
325 /* This is the ONLY way to change SSH state! */
326 static void state(struct connectdata *conn, sshstate nowstate)
328 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
329 /* for debug purposes */
330 static const char * const names[] = {
335 "SSH_AUTH_PKEY_INIT",
337 "SSH_AUTH_PASS_INIT",
339 "SSH_AUTH_HOST_INIT",
346 "SSH_SFTP_QUOTE_INIT",
347 "SSH_SFTP_POSTQUOTE_INIT",
349 "SSH_SFTP_NEXT_QUOTE",
350 "SSH_SFTP_QUOTE_STAT",
351 "SSH_SFTP_QUOTE_SETSTAT",
352 "SSH_SFTP_QUOTE_SYMLINK",
353 "SSH_SFTP_QUOTE_MKDIR",
354 "SSH_SFTP_QUOTE_RENAME",
355 "SSH_SFTP_QUOTE_RMDIR",
356 "SSH_SFTP_QUOTE_UNLINK",
357 "SSH_SFTP_TRANS_INIT",
358 "SSH_SFTP_UPLOAD_INIT",
359 "SSH_SFTP_CREATE_DIRS_INIT",
360 "SSH_SFTP_CREATE_DIRS",
361 "SSH_SFTP_CREATE_DIRS_MKDIR",
362 "SSH_SFTP_READDIR_INIT",
364 "SSH_SFTP_READDIR_LINK",
365 "SSH_SFTP_READDIR_BOTTOM",
366 "SSH_SFTP_READDIR_DONE",
367 "SSH_SFTP_DOWNLOAD_INIT",
368 "SSH_SFTP_DOWNLOAD_STAT",
371 "SSH_SCP_TRANS_INIT",
372 "SSH_SCP_UPLOAD_INIT",
373 "SSH_SCP_DOWNLOAD_INIT",
377 "SSH_SCP_WAIT_CLOSE",
378 "SSH_SCP_CHANNEL_FREE",
379 "SSH_SESSION_DISCONNECT",
384 struct ssh_conn *sshc = &conn->proto.sshc;
386 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
387 if(sshc->state != nowstate) {
388 infof(conn->data, "SFTP %p state change from %s to %s\n",
389 sshc, names[sshc->state], names[nowstate]);
393 sshc->state = nowstate;
396 /* figure out the path to work with in this particular request */
397 static CURLcode ssh_getworkingpath(struct connectdata *conn,
398 char *homedir, /* when SFTP is used */
399 char **path) /* returns the allocated
400 real path to work with */
402 struct SessionHandle *data = conn->data;
403 char *real_path = NULL;
405 int working_path_len;
407 working_path = curl_easy_unescape(data, data->state.path, 0,
410 return CURLE_OUT_OF_MEMORY;
412 /* Check for /~/ , indicating relative to the user's home directory */
413 if(conn->protocol & PROT_SCP) {
414 real_path = malloc(working_path_len+1);
415 if(real_path == NULL) {
417 return CURLE_OUT_OF_MEMORY;
419 if((working_path_len > 1) && (working_path[1] == '~'))
420 /* It is referenced to the home directory, so strip the leading '/' */
421 memcpy(real_path, working_path+1, 1 + working_path_len-1);
423 memcpy(real_path, working_path, 1 + working_path_len);
425 else if(conn->protocol & PROT_SFTP) {
426 if((working_path_len > 1) && (working_path[1] == '~')) {
427 size_t homelen = strlen(homedir);
428 real_path = malloc(homelen + working_path_len + 1);
429 if(real_path == NULL) {
431 return CURLE_OUT_OF_MEMORY;
433 /* It is referenced to the home directory, so strip the
435 memcpy(real_path, homedir, homelen);
436 real_path[homelen] = '/';
437 real_path[homelen+1] = '\0';
438 if(working_path_len > 3) {
439 memcpy(real_path+homelen+1, working_path + 3,
440 1 + working_path_len -3);
444 real_path = malloc(working_path_len+1);
445 if(real_path == NULL) {
447 return CURLE_OUT_OF_MEMORY;
449 memcpy(real_path, working_path, 1+working_path_len);
455 /* store the pointer for the caller to receive */
461 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
462 static int sshkeycallback(CURL *easy,
463 const struct curl_khkey *knownkey, /* known */
464 const struct curl_khkey *foundkey, /* found */
465 enum curl_khmatch match,
473 /* we only allow perfect matches, and we reject everything else */
474 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
479 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
482 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
483 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
485 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
489 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
490 * architectures so we check of the necessary function is present.
492 #ifndef HAVE_LIBSSH2_SCP_SEND64
493 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
495 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
496 (libssh2_uint64_t)d, 0, 0)
500 * ssh_statemach_act() runs the SSH state machine as far as it can without
501 * blocking and without reaching the end. The data the pointer 'block' points
502 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
503 * meaning it wants to be called again when the socket is ready
506 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
508 CURLcode result = CURLE_OK;
509 struct SessionHandle *data = conn->data;
510 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
511 struct ssh_conn *sshc = &conn->proto.sshc;
512 curl_socket_t sock = conn->sock[FIRSTSOCKET];
513 #ifdef CURL_LIBSSH2_DEBUG
514 const char *fingerprint;
515 #endif /* CURL_LIBSSH2_DEBUG */
516 const char *host_public_key_md5;
517 int rc = LIBSSH2_ERROR_NONE, i;
519 int seekerr = CURL_SEEKFUNC_OK;
520 *block = 0; /* we're not blocking by default */
524 switch(sshc->state) {
526 sshc->secondCreateDirs = 0;
527 sshc->nextstate = SSH_NO_STATE;
528 sshc->actualcode = CURLE_OK;
530 rc = libssh2_session_startup(sshc->ssh_session, sock);
531 if(rc == LIBSSH2_ERROR_EAGAIN) {
535 failf(data, "Failure establishing ssh session");
536 state(conn, SSH_SESSION_FREE);
537 sshc->actualcode = CURLE_FAILED_INIT;
541 /* Set libssh2 to non-blocking, since everything internally is
543 libssh2_session_set_blocking(sshc->ssh_session, 0);
545 state(conn, SSH_HOSTKEY);
550 #ifdef CURL_LIBSSH2_DEBUG
552 * Before we authenticate we should check the hostkey's fingerprint
553 * against our known hosts. How that is handled (reading from file,
554 * whatever) is up to us. As for know not much is implemented, besides
555 * showing how to get the fingerprint.
557 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
558 LIBSSH2_HOSTKEY_HASH_MD5);
560 /* The fingerprint points to static storage (!), don't free() it. */
561 infof(data, "Fingerprint: ");
562 for (rc = 0; rc < 16; rc++) {
563 infof(data, "%02X ", (unsigned char) fingerprint[rc]);
566 #endif /* CURL_LIBSSH2_DEBUG */
568 /* Before we authenticate we check the hostkey's MD5 fingerprint
569 * against a known fingerprint, if available. This implementation pulls
570 * it from the curl option.
572 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
573 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
575 host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
576 LIBSSH2_HOSTKEY_HASH_MD5);
577 for (i = 0; i < 16; i++)
578 snprintf(&buf[i*2], 3, "%02x",
579 (unsigned char) host_public_key_md5[i]);
580 if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
582 "Denied establishing ssh session: mismatch md5 fingerprint. "
583 "Remote %s is not equal to %s",
584 buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
585 state(conn, SSH_SESSION_FREE);
586 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
591 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
592 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
593 /* we're asked to verify the host against a file */
596 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
603 * A subject to figure out is what host name we need to pass in here.
604 * What host name does OpenSSH store in its file if an IDN name is
607 struct libssh2_knownhost *host;
608 enum curl_khmatch keymatch;
609 curl_sshkeycallback func =
610 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
611 struct curl_khkey knownkey;
612 struct curl_khkey *knownkeyp = NULL;
613 struct curl_khkey foundkey;
615 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
616 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
618 keycheck = libssh2_knownhost_check(sshc->kh,
621 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
622 LIBSSH2_KNOWNHOST_KEYENC_RAW|
626 infof(data, "SSH host check: %d, key: %s\n", keycheck,
627 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
630 /* setup 'knownkey' */
631 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
632 knownkey.key = host->key;
634 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
635 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
636 knownkeyp = &knownkey;
639 /* setup 'foundkey' */
640 foundkey.key = remotekey;
641 foundkey.len = keylen;
642 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
643 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
646 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
647 * curl_khmatch enum are ever modified, we need to introduce a
648 * translation table here!
650 keymatch = (enum curl_khmatch)keycheck;
652 /* Ask the callback how to behave */
653 rc = func(data, knownkeyp, /* from the knownhosts file */
654 &foundkey, /* from the remote host */
655 keymatch, data->set.ssh_keyfunc_userp);
658 /* no remotekey means failure! */
659 rc = CURLKHSTAT_REJECT;
662 default: /* unknown return codes will equal reject */
663 case CURLKHSTAT_REJECT:
664 state(conn, SSH_SESSION_FREE);
665 case CURLKHSTAT_DEFER:
666 /* DEFER means bail out but keep the SSH_HOSTKEY state */
667 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
669 case CURLKHSTAT_FINE:
670 case CURLKHSTAT_FINE_ADD_TO_FILE:
672 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
673 /* the found host+key didn't match but has been told to be fine
674 anyway so we add it in memory */
675 int addrc = libssh2_knownhost_add(sshc->kh,
676 conn->host.name, NULL,
678 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
679 LIBSSH2_KNOWNHOST_KEYENC_RAW|
682 infof(data, "Warning adding the known host %s failed!\n",
684 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
685 /* now we write the entire in-memory list of known hosts to the
688 libssh2_knownhost_writefile(sshc->kh,
689 data->set.str[STRING_SSH_KNOWNHOSTS],
690 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
692 infof(data, "Warning, writing %s failed!\n",
693 data->set.str[STRING_SSH_KNOWNHOSTS]);
700 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
702 state(conn, SSH_AUTHLIST);
707 * Figure out authentication methods
708 * NB: As soon as we have provided a username to an openssh server we
709 * must never change it later. Thus, always specify the correct username
710 * here, even though the libssh2 docs kind of indicate that it should be
711 * possible to get a 'generic' list (not user-specific) of authentication
712 * methods, presumably with a blank username. That won't work in my
714 * So always specify it here.
716 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
718 (unsigned int)strlen(conn->user));
720 if(!sshc->authlist) {
721 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
722 LIBSSH2_ERROR_EAGAIN) {
723 rc = LIBSSH2_ERROR_EAGAIN;
727 state(conn, SSH_SESSION_FREE);
728 sshc->actualcode = libssh2_session_error_to_CURLE(err);
732 infof(data, "SSH authentication methods available: %s\n",
735 state(conn, SSH_AUTH_PKEY_INIT);
738 case SSH_AUTH_PKEY_INIT:
740 * Check the supported auth types in the order I feel is most secure
741 * with the requested type of authentication
743 sshc->authed = FALSE;
745 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
746 (strstr(sshc->authlist, "publickey") != NULL)) {
749 sshc->rsa_pub = sshc->rsa = NULL;
751 /* To ponder about: should really the lib be messing about with the
752 HOME environment variable etc? */
753 home = curl_getenv("HOME");
755 if(data->set.str[STRING_SSH_PUBLIC_KEY])
756 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
758 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
760 /* as a final resort, try current dir! */
761 sshc->rsa_pub = strdup("id_dsa.pub");
763 if(sshc->rsa_pub == NULL) {
766 state(conn, SSH_SESSION_FREE);
767 sshc->actualcode = CURLE_OUT_OF_MEMORY;
771 if(data->set.str[STRING_SSH_PRIVATE_KEY])
772 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
774 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
776 /* as a final resort, try current dir! */
777 sshc->rsa = strdup("id_dsa");
779 if(sshc->rsa == NULL) {
782 Curl_safefree(sshc->rsa_pub);
783 sshc->rsa_pub = NULL;
784 state(conn, SSH_SESSION_FREE);
785 sshc->actualcode = CURLE_OUT_OF_MEMORY;
789 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
790 if(!sshc->passphrase)
791 sshc->passphrase = "";
796 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
797 infof(data, "Using ssh private key file %s\n", sshc->rsa);
799 state(conn, SSH_AUTH_PKEY);
802 state(conn, SSH_AUTH_PASS_INIT);
807 /* The function below checks if the files exists, no need to stat() here.
809 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
814 sshc->rsa, sshc->passphrase);
815 if(rc == LIBSSH2_ERROR_EAGAIN) {
819 Curl_safefree(sshc->rsa_pub);
820 sshc->rsa_pub = NULL;
821 Curl_safefree(sshc->rsa);
826 infof(data, "Initialized SSH public key authentication\n");
827 state(conn, SSH_AUTH_DONE);
831 (void)libssh2_session_last_error(sshc->ssh_session,
833 infof(data, "SSH public key authentication failed: %s\n", err_msg);
834 state(conn, SSH_AUTH_PASS_INIT);
838 case SSH_AUTH_PASS_INIT:
839 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
840 (strstr(sshc->authlist, "password") != NULL)) {
841 state(conn, SSH_AUTH_PASS);
844 state(conn, SSH_AUTH_HOST_INIT);
849 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
850 (unsigned int)strlen(conn->user),
852 (unsigned int)strlen(conn->passwd),
854 if(rc == LIBSSH2_ERROR_EAGAIN) {
859 infof(data, "Initialized password authentication\n");
860 state(conn, SSH_AUTH_DONE);
863 state(conn, SSH_AUTH_HOST_INIT);
867 case SSH_AUTH_HOST_INIT:
868 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
869 (strstr(sshc->authlist, "hostbased") != NULL)) {
870 state(conn, SSH_AUTH_HOST);
873 state(conn, SSH_AUTH_KEY_INIT);
878 state(conn, SSH_AUTH_KEY_INIT);
881 case SSH_AUTH_KEY_INIT:
882 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
883 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
884 state(conn, SSH_AUTH_KEY);
887 state(conn, SSH_AUTH_DONE);
892 /* Authentication failed. Continue with keyboard-interactive now. */
893 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
898 if(rc == LIBSSH2_ERROR_EAGAIN) {
903 infof(data, "Initialized keyboard interactive authentication\n");
905 state(conn, SSH_AUTH_DONE);
910 failf(data, "Authentication failure");
911 state(conn, SSH_SESSION_FREE);
912 sshc->actualcode = CURLE_LOGIN_DENIED;
917 * At this point we have an authenticated ssh session.
919 infof(data, "Authentication complete\n");
921 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
924 conn->writesockfd = CURL_SOCKET_BAD;
926 if(conn->protocol == PROT_SFTP) {
927 state(conn, SSH_SFTP_INIT);
930 infof(data, "SSH CONNECT phase done\n");
931 state(conn, SSH_STOP);
936 * Start the libssh2 sftp session
938 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
939 if(!sshc->sftp_session) {
940 if(libssh2_session_last_errno(sshc->ssh_session) ==
941 LIBSSH2_ERROR_EAGAIN) {
942 rc = LIBSSH2_ERROR_EAGAIN;
948 (void)libssh2_session_last_error(sshc->ssh_session,
950 failf(data, "Failure initializing sftp session: %s", err_msg);
951 state(conn, SSH_SESSION_FREE);
952 sshc->actualcode = CURLE_FAILED_INIT;
956 state(conn, SSH_SFTP_REALPATH);
959 case SSH_SFTP_REALPATH:
961 char tempHome[PATH_MAX];
964 * Get the "home" directory
966 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
967 tempHome, PATH_MAX-1);
968 if(rc == LIBSSH2_ERROR_EAGAIN) {
972 /* It seems that this string is not always NULL terminated */
974 sshc->homedir = strdup(tempHome);
976 state(conn, SSH_SFTP_CLOSE);
977 sshc->actualcode = CURLE_OUT_OF_MEMORY;
982 /* Return the error type */
983 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
984 result = sftp_libssh2_error_to_CURLE(err);
985 sshc->actualcode = result?result:CURLE_SSH;
986 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
988 state(conn, SSH_STOP);
992 /* This is the last step in the SFTP connect phase. Do note that while
993 we get the homedir here, we get the "workingpath" in the DO action
994 since the homedir will remain the same between request but the
995 working path will not. */
996 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
997 state(conn, SSH_STOP);
1000 case SSH_SFTP_QUOTE_INIT:
1002 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1004 sshc->actualcode = result;
1005 state(conn, SSH_STOP);
1009 if(data->set.quote) {
1010 infof(data, "Sending quote commands\n");
1011 sshc->quote_item = data->set.quote;
1012 state(conn, SSH_SFTP_QUOTE);
1015 state(conn, SSH_SFTP_TRANS_INIT);
1019 case SSH_SFTP_POSTQUOTE_INIT:
1020 if(data->set.postquote) {
1021 infof(data, "Sending quote commands\n");
1022 sshc->quote_item = data->set.postquote;
1023 state(conn, SSH_SFTP_QUOTE);
1026 state(conn, SSH_STOP);
1030 case SSH_SFTP_QUOTE:
1031 /* Send any quote commands */
1036 * Support some of the "FTP" commands
1038 if(curl_strequal("pwd", sshc->quote_item->data)) {
1039 /* output debug output if that is requested */
1040 if(data->set.verbose) {
1041 char tmp[PATH_MAX+1];
1043 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1044 snprintf(tmp, PATH_MAX, "257 \"%s\" is current directory.\n",
1046 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1048 state(conn, SSH_SFTP_NEXT_QUOTE);
1051 else if(sshc->quote_item->data) {
1053 * the arguments following the command must be separated from the
1054 * command with a space so we can check for it unconditionally
1056 cp = strchr(sshc->quote_item->data, ' ');
1058 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1059 state(conn, SSH_SFTP_CLOSE);
1060 sshc->actualcode = CURLE_QUOTE_ERROR;
1065 * also, every command takes at least one argument so we get that
1066 * first argument right now
1068 result = get_pathname(&cp, &sshc->quote_path1);
1070 if(result == CURLE_OUT_OF_MEMORY)
1071 failf(data, "Out of memory");
1073 failf(data, "Syntax error: Bad first parameter");
1074 state(conn, SSH_SFTP_CLOSE);
1075 sshc->actualcode = result;
1080 * SFTP is a binary protocol, so we don't send text commands to
1081 * the server. Instead, we scan for commands for commands used by
1082 * OpenSSH's sftp program and call the appropriate libssh2
1085 if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
1086 curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
1087 curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
1088 /* attribute change */
1090 /* sshc->quote_path1 contains the mode to set */
1091 /* get the destination */
1092 result = get_pathname(&cp, &sshc->quote_path2);
1094 if(result == CURLE_OUT_OF_MEMORY)
1095 failf(data, "Out of memory");
1097 failf(data, "Syntax error in chgrp/chmod/chown: "
1098 "Bad second parameter");
1099 Curl_safefree(sshc->quote_path1);
1100 sshc->quote_path1 = NULL;
1101 state(conn, SSH_SFTP_CLOSE);
1102 sshc->actualcode = result;
1105 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1106 state(conn, SSH_SFTP_QUOTE_STAT);
1109 else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
1110 curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
1111 /* symbolic linking */
1112 /* sshc->quote_path1 is the source */
1113 /* get the destination */
1114 result = get_pathname(&cp, &sshc->quote_path2);
1116 if(result == CURLE_OUT_OF_MEMORY)
1117 failf(data, "Out of memory");
1120 "Syntax error in ln/symlink: Bad second parameter");
1121 Curl_safefree(sshc->quote_path1);
1122 sshc->quote_path1 = NULL;
1123 state(conn, SSH_SFTP_CLOSE);
1124 sshc->actualcode = result;
1127 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1130 else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
1132 state(conn, SSH_SFTP_QUOTE_MKDIR);
1135 else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
1137 /* first param is the source path */
1138 /* second param is the dest. path */
1139 result = get_pathname(&cp, &sshc->quote_path2);
1141 if(result == CURLE_OUT_OF_MEMORY)
1142 failf(data, "Out of memory");
1144 failf(data, "Syntax error in rename: Bad second parameter");
1145 Curl_safefree(sshc->quote_path1);
1146 sshc->quote_path1 = NULL;
1147 state(conn, SSH_SFTP_CLOSE);
1148 sshc->actualcode = result;
1151 state(conn, SSH_SFTP_QUOTE_RENAME);
1154 else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
1156 state(conn, SSH_SFTP_QUOTE_RMDIR);
1159 else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
1160 state(conn, SSH_SFTP_QUOTE_UNLINK);
1164 failf(data, "Unknown SFTP command");
1165 Curl_safefree(sshc->quote_path1);
1166 sshc->quote_path1 = NULL;
1167 Curl_safefree(sshc->quote_path2);
1168 sshc->quote_path2 = NULL;
1169 state(conn, SSH_SFTP_CLOSE);
1170 sshc->actualcode = CURLE_QUOTE_ERROR;
1174 if(!sshc->quote_item) {
1175 state(conn, SSH_SFTP_TRANS_INIT);
1179 case SSH_SFTP_NEXT_QUOTE:
1180 if(sshc->quote_path1) {
1181 Curl_safefree(sshc->quote_path1);
1182 sshc->quote_path1 = NULL;
1184 if(sshc->quote_path2) {
1185 Curl_safefree(sshc->quote_path2);
1186 sshc->quote_path2 = NULL;
1189 sshc->quote_item = sshc->quote_item->next;
1191 if(sshc->quote_item) {
1192 state(conn, SSH_SFTP_QUOTE);
1195 if(sshc->nextstate != SSH_NO_STATE) {
1196 state(conn, sshc->nextstate);
1197 sshc->nextstate = SSH_NO_STATE;
1200 state(conn, SSH_SFTP_TRANS_INIT);
1205 case SSH_SFTP_QUOTE_STAT:
1206 if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1207 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1208 * set them both at once, we need to obtain the current ownership
1209 * first. This takes an extra protocol round trip.
1211 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1212 (unsigned int)strlen(sshc->quote_path2),
1214 &sshc->quote_attrs);
1215 if(rc == LIBSSH2_ERROR_EAGAIN) {
1218 else if(rc != 0) { /* get those attributes */
1219 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1220 Curl_safefree(sshc->quote_path1);
1221 sshc->quote_path1 = NULL;
1222 Curl_safefree(sshc->quote_path2);
1223 sshc->quote_path2 = NULL;
1224 failf(data, "Attempt to get SFTP stats failed: %s",
1225 sftp_libssh2_strerror(err));
1226 state(conn, SSH_SFTP_CLOSE);
1227 sshc->actualcode = CURLE_QUOTE_ERROR;
1232 /* Now set the new attributes... */
1233 if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
1234 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1235 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1236 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1237 Curl_safefree(sshc->quote_path1);
1238 sshc->quote_path1 = NULL;
1239 Curl_safefree(sshc->quote_path2);
1240 sshc->quote_path2 = NULL;
1241 failf(data, "Syntax error: chgrp gid not a number");
1242 state(conn, SSH_SFTP_CLOSE);
1243 sshc->actualcode = CURLE_QUOTE_ERROR;
1247 else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1248 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1249 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1250 /* permissions are octal */
1251 if(sshc->quote_attrs.permissions == 0 &&
1252 !ISDIGIT(sshc->quote_path1[0])) {
1253 Curl_safefree(sshc->quote_path1);
1254 sshc->quote_path1 = NULL;
1255 Curl_safefree(sshc->quote_path2);
1256 sshc->quote_path2 = NULL;
1257 failf(data, "Syntax error: chmod permissions not a number");
1258 state(conn, SSH_SFTP_CLOSE);
1259 sshc->actualcode = CURLE_QUOTE_ERROR;
1263 else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
1264 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1265 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1266 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1267 Curl_safefree(sshc->quote_path1);
1268 sshc->quote_path1 = NULL;
1269 Curl_safefree(sshc->quote_path2);
1270 sshc->quote_path2 = NULL;
1271 failf(data, "Syntax error: chown uid not a number");
1272 state(conn, SSH_SFTP_CLOSE);
1273 sshc->actualcode = CURLE_QUOTE_ERROR;
1278 /* Now send the completed structure... */
1279 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1282 case SSH_SFTP_QUOTE_SETSTAT:
1283 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1284 (unsigned int)strlen(sshc->quote_path2),
1285 LIBSSH2_SFTP_SETSTAT,
1286 &sshc->quote_attrs);
1287 if(rc == LIBSSH2_ERROR_EAGAIN) {
1291 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1292 Curl_safefree(sshc->quote_path1);
1293 sshc->quote_path1 = NULL;
1294 Curl_safefree(sshc->quote_path2);
1295 sshc->quote_path2 = NULL;
1296 failf(data, "Attempt to set SFTP stats failed: %s",
1297 sftp_libssh2_strerror(err));
1298 state(conn, SSH_SFTP_CLOSE);
1299 sshc->actualcode = CURLE_QUOTE_ERROR;
1302 state(conn, SSH_SFTP_NEXT_QUOTE);
1305 case SSH_SFTP_QUOTE_SYMLINK:
1306 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1307 (unsigned int)strlen(sshc->quote_path1),
1309 (unsigned int)strlen(sshc->quote_path2),
1310 LIBSSH2_SFTP_SYMLINK);
1311 if(rc == LIBSSH2_ERROR_EAGAIN) {
1315 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1316 Curl_safefree(sshc->quote_path1);
1317 sshc->quote_path1 = NULL;
1318 Curl_safefree(sshc->quote_path2);
1319 sshc->quote_path2 = NULL;
1320 failf(data, "symlink command failed: %s",
1321 sftp_libssh2_strerror(err));
1322 state(conn, SSH_SFTP_CLOSE);
1323 sshc->actualcode = CURLE_QUOTE_ERROR;
1326 state(conn, SSH_SFTP_NEXT_QUOTE);
1329 case SSH_SFTP_QUOTE_MKDIR:
1330 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1331 (unsigned int)strlen(sshc->quote_path1),
1333 if(rc == LIBSSH2_ERROR_EAGAIN) {
1337 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1338 Curl_safefree(sshc->quote_path1);
1339 sshc->quote_path1 = NULL;
1340 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1341 state(conn, SSH_SFTP_CLOSE);
1342 sshc->actualcode = CURLE_QUOTE_ERROR;
1345 state(conn, SSH_SFTP_NEXT_QUOTE);
1348 case SSH_SFTP_QUOTE_RENAME:
1349 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1350 (unsigned int)strlen(sshc->quote_path1),
1352 (unsigned int)strlen(sshc->quote_path2),
1353 LIBSSH2_SFTP_RENAME_OVERWRITE |
1354 LIBSSH2_SFTP_RENAME_ATOMIC |
1355 LIBSSH2_SFTP_RENAME_NATIVE);
1356 if(rc == LIBSSH2_ERROR_EAGAIN) {
1360 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1361 Curl_safefree(sshc->quote_path1);
1362 sshc->quote_path1 = NULL;
1363 Curl_safefree(sshc->quote_path2);
1364 sshc->quote_path2 = NULL;
1365 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1366 state(conn, SSH_SFTP_CLOSE);
1367 sshc->actualcode = CURLE_QUOTE_ERROR;
1370 state(conn, SSH_SFTP_NEXT_QUOTE);
1373 case SSH_SFTP_QUOTE_RMDIR:
1374 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1375 (unsigned int)strlen(sshc->quote_path1));
1376 if(rc == LIBSSH2_ERROR_EAGAIN) {
1380 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1381 Curl_safefree(sshc->quote_path1);
1382 sshc->quote_path1 = NULL;
1383 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1384 state(conn, SSH_SFTP_CLOSE);
1385 sshc->actualcode = CURLE_QUOTE_ERROR;
1388 state(conn, SSH_SFTP_NEXT_QUOTE);
1391 case SSH_SFTP_QUOTE_UNLINK:
1392 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1393 (unsigned int)strlen(sshc->quote_path1));
1394 if(rc == LIBSSH2_ERROR_EAGAIN) {
1398 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1399 Curl_safefree(sshc->quote_path1);
1400 sshc->quote_path1 = NULL;
1401 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1402 state(conn, SSH_SFTP_CLOSE);
1403 sshc->actualcode = CURLE_QUOTE_ERROR;
1406 state(conn, SSH_SFTP_NEXT_QUOTE);
1409 case SSH_SFTP_TRANS_INIT:
1410 if(data->set.upload)
1411 state(conn, SSH_SFTP_UPLOAD_INIT);
1413 if(data->set.opt_no_body)
1414 state(conn, SSH_STOP);
1415 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1416 state(conn, SSH_SFTP_READDIR_INIT);
1418 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1422 case SSH_SFTP_UPLOAD_INIT:
1424 unsigned long flags;
1426 * NOTE!!! libssh2 requires that the destination path is a full path
1427 * that includes the destination file and name OR ends in a "/"
1428 * If this is not done the destination file will be named the
1429 * same name as the last directory in the path.
1432 if(data->state.resume_from != 0) {
1433 LIBSSH2_SFTP_ATTRIBUTES attrs;
1434 if(data->state.resume_from< 0) {
1435 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1436 (unsigned int)strlen(sftp_scp->path),
1437 LIBSSH2_SFTP_STAT, &attrs);
1438 if(rc == LIBSSH2_ERROR_EAGAIN) {
1442 data->state.resume_from = 0;
1445 curl_off_t size = attrs.filesize;
1447 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1448 return CURLE_BAD_DOWNLOAD_RESUME;
1450 data->state.resume_from = attrs.filesize;
1455 if(data->set.ftp_append)
1456 /* Try to open for append, but create if nonexisting */
1457 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1458 else if (data->state.resume_from > 0)
1459 /* If we have restart position then open for append */
1460 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1462 /* Clear file before writing (normal behaviour) */
1463 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1466 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1467 (unsigned int)strlen(sftp_scp->path),
1468 flags, data->set.new_file_perms,
1469 LIBSSH2_SFTP_OPENFILE);
1471 if(!sshc->sftp_handle) {
1472 rc = libssh2_session_last_errno(sshc->ssh_session);
1474 if(LIBSSH2_ERROR_EAGAIN == rc)
1477 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1478 /* only when there was an SFTP protocol error can we extract
1480 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1482 err = -1; /* not an sftp error at all */
1484 if(sshc->secondCreateDirs) {
1485 state(conn, SSH_SFTP_CLOSE);
1486 sshc->actualcode = err>= LIBSSH2_FX_OK?
1487 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1488 failf(data, "Creating the dir/file failed: %s",
1489 sftp_libssh2_strerror(err));
1492 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1493 (err == LIBSSH2_FX_FAILURE) ||
1494 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1495 (data->set.ftp_create_missing_dirs &&
1496 (strlen(sftp_scp->path) > 1))) {
1497 /* try to create the path remotely */
1498 sshc->secondCreateDirs = 1;
1499 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1502 state(conn, SSH_SFTP_CLOSE);
1503 sshc->actualcode = err>= LIBSSH2_FX_OK?
1504 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1505 if(!sshc->actualcode) {
1506 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1507 zero even though libssh2_sftp_open() failed previously! We need
1508 to work around that! */
1509 sshc->actualcode = CURLE_SSH;
1512 failf(data, "Upload failed: %s (%d/%d)",
1513 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1519 /* If we have restart point then we need to seek to the correct
1521 if(data->state.resume_from > 0) {
1522 /* Let's read off the proper amount of bytes from the input. */
1523 if(conn->seek_func) {
1524 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1528 if(seekerr != CURL_SEEKFUNC_OK){
1530 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1531 failf(data, "Could not seek stream");
1532 return CURLE_FTP_COULDNT_USE_REST;
1534 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1536 curl_off_t passed=0;
1537 curl_off_t readthisamountnow;
1538 curl_off_t actuallyread;
1540 readthisamountnow = (data->state.resume_from - passed);
1542 if(readthisamountnow > BUFSIZE)
1543 readthisamountnow = BUFSIZE;
1546 (curl_off_t) conn->fread_func(data->state.buffer, 1,
1547 (size_t)readthisamountnow,
1550 passed += actuallyread;
1551 if((actuallyread <= 0) || (actuallyread > readthisamountnow)) {
1552 /* this checks for greater-than only to make sure that the
1553 CURL_READFUNC_ABORT return code still aborts */
1554 failf(data, "Failed to read data");
1555 return CURLE_FTP_COULDNT_USE_REST;
1557 } while(passed < data->state.resume_from);
1561 /* now, decrease the size of the read */
1562 if(data->set.infilesize>0) {
1563 data->set.infilesize -= data->state.resume_from;
1564 data->req.size = data->set.infilesize;
1565 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1568 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1570 if(data->set.infilesize>0) {
1571 data->req.size = data->set.infilesize;
1572 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1575 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1577 /* not set by Curl_setup_transfer to preserve keepon bits */
1578 conn->sockfd = conn->writesockfd;
1581 state(conn, SSH_SFTP_CLOSE);
1582 sshc->actualcode = result;
1585 /* store this original bitmask setup to use later on if we can't
1586 figure out a "real" bitmask */
1587 sshc->orig_waitfor = data->req.keepon;
1589 state(conn, SSH_STOP);
1594 case SSH_SFTP_CREATE_DIRS_INIT:
1595 if(strlen(sftp_scp->path) > 1) {
1596 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1597 state(conn, SSH_SFTP_CREATE_DIRS);
1600 state(conn, SSH_SFTP_UPLOAD_INIT);
1604 case SSH_SFTP_CREATE_DIRS:
1605 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1606 *sshc->slash_pos = 0;
1608 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1609 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1613 state(conn, SSH_SFTP_UPLOAD_INIT);
1617 case SSH_SFTP_CREATE_DIRS_MKDIR:
1618 /* 'mode' - parameter is preliminary - default to 0644 */
1619 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1620 (unsigned int)strlen(sftp_scp->path),
1621 data->set.new_directory_perms);
1622 if(rc == LIBSSH2_ERROR_EAGAIN) {
1625 *sshc->slash_pos = '/';
1628 unsigned int sftp_err = 0;
1630 * Abort if failure wasn't that the dir already exists or the
1631 * permission was denied (creation might succeed further down the
1632 * path) - retry on unspecific FAILURE also
1634 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1635 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1636 (sftp_err != LIBSSH2_FX_FAILURE) &&
1637 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1638 result = sftp_libssh2_error_to_CURLE(sftp_err);
1639 state(conn, SSH_SFTP_CLOSE);
1640 sshc->actualcode = result?result:CURLE_SSH;
1644 state(conn, SSH_SFTP_CREATE_DIRS);
1647 case SSH_SFTP_READDIR_INIT:
1649 * This is a directory that we are trying to get, so produce a directory
1652 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1655 strlen(sftp_scp->path),
1656 0, 0, LIBSSH2_SFTP_OPENDIR);
1657 if(!sshc->sftp_handle) {
1658 if(libssh2_session_last_errno(sshc->ssh_session) ==
1659 LIBSSH2_ERROR_EAGAIN) {
1660 rc = LIBSSH2_ERROR_EAGAIN;
1664 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1665 failf(data, "Could not open directory for reading: %s",
1666 sftp_libssh2_strerror(err));
1667 state(conn, SSH_SFTP_CLOSE);
1668 result = sftp_libssh2_error_to_CURLE(err);
1669 sshc->actualcode = result?result:CURLE_SSH;
1673 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1674 state(conn, SSH_SFTP_CLOSE);
1675 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1678 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1679 Curl_safefree(sshc->readdir_filename);
1680 sshc->readdir_filename = NULL;
1681 state(conn, SSH_SFTP_CLOSE);
1682 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1685 state(conn, SSH_SFTP_READDIR);
1688 case SSH_SFTP_READDIR:
1689 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1690 sshc->readdir_filename,
1692 sshc->readdir_longentry,
1694 &sshc->readdir_attrs);
1695 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1696 rc = LIBSSH2_ERROR_EAGAIN;
1699 if(sshc->readdir_len > 0) {
1700 sshc->readdir_filename[sshc->readdir_len] = '\0';
1702 if(data->set.ftp_list_only) {
1705 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1706 if(tmpLine == NULL) {
1707 state(conn, SSH_SFTP_CLOSE);
1708 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1711 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1712 tmpLine, sshc->readdir_len+1);
1713 Curl_safefree(tmpLine);
1716 state(conn, SSH_STOP);
1719 /* since this counts what we send to the client, we include the
1720 newline in this counter */
1721 data->req.bytecount += sshc->readdir_len+1;
1723 /* output debug output if that is requested */
1724 if(data->set.verbose) {
1725 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1726 sshc->readdir_len, conn);
1730 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1731 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1732 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1733 if(!sshc->readdir_line) {
1734 Curl_safefree(sshc->readdir_filename);
1735 sshc->readdir_filename = NULL;
1736 Curl_safefree(sshc->readdir_longentry);
1737 sshc->readdir_longentry = NULL;
1738 state(conn, SSH_SFTP_CLOSE);
1739 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1743 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1744 sshc->readdir_currLen);
1745 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1746 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1747 LIBSSH2_SFTP_S_IFLNK)) {
1748 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1749 if(sshc->readdir_linkPath == NULL) {
1750 Curl_safefree(sshc->readdir_filename);
1751 sshc->readdir_filename = NULL;
1752 Curl_safefree(sshc->readdir_longentry);
1753 sshc->readdir_longentry = NULL;
1754 state(conn, SSH_SFTP_CLOSE);
1755 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1759 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1760 sshc->readdir_filename);
1761 state(conn, SSH_SFTP_READDIR_LINK);
1764 state(conn, SSH_SFTP_READDIR_BOTTOM);
1768 else if(sshc->readdir_len == 0) {
1769 Curl_safefree(sshc->readdir_filename);
1770 sshc->readdir_filename = NULL;
1771 Curl_safefree(sshc->readdir_longentry);
1772 sshc->readdir_longentry = NULL;
1773 state(conn, SSH_SFTP_READDIR_DONE);
1776 else if(sshc->readdir_len <= 0) {
1777 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1778 result = sftp_libssh2_error_to_CURLE(err);
1779 sshc->actualcode = result?result:CURLE_SSH;
1780 failf(data, "Could not open remote file for reading: %s :: %d",
1781 sftp_libssh2_strerror(err),
1782 libssh2_session_last_errno(sshc->ssh_session));
1783 Curl_safefree(sshc->readdir_filename);
1784 sshc->readdir_filename = NULL;
1785 Curl_safefree(sshc->readdir_longentry);
1786 sshc->readdir_longentry = NULL;
1787 state(conn, SSH_SFTP_CLOSE);
1792 case SSH_SFTP_READDIR_LINK:
1794 libssh2_sftp_symlink_ex(sshc->sftp_session,
1795 sshc->readdir_linkPath,
1796 (unsigned int) strlen(sshc->readdir_linkPath),
1797 sshc->readdir_filename,
1798 PATH_MAX, LIBSSH2_SFTP_READLINK);
1799 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1800 rc = LIBSSH2_ERROR_EAGAIN;
1803 Curl_safefree(sshc->readdir_linkPath);
1804 sshc->readdir_linkPath = NULL;
1805 sshc->readdir_line = realloc(sshc->readdir_line,
1806 sshc->readdir_totalLen + 4 +
1808 if(!sshc->readdir_line) {
1809 Curl_safefree(sshc->readdir_filename);
1810 sshc->readdir_filename = NULL;
1811 Curl_safefree(sshc->readdir_longentry);
1812 sshc->readdir_longentry = NULL;
1813 state(conn, SSH_SFTP_CLOSE);
1814 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1818 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1819 sshc->readdir_currLen,
1820 sshc->readdir_totalLen -
1821 sshc->readdir_currLen,
1823 sshc->readdir_filename);
1825 state(conn, SSH_SFTP_READDIR_BOTTOM);
1828 case SSH_SFTP_READDIR_BOTTOM:
1829 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1830 sshc->readdir_currLen,
1831 sshc->readdir_totalLen -
1832 sshc->readdir_currLen, "\n");
1833 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1835 sshc->readdir_currLen);
1837 if(result == CURLE_OK) {
1839 /* output debug output if that is requested */
1840 if(data->set.verbose) {
1841 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1842 sshc->readdir_currLen, conn);
1844 data->req.bytecount += sshc->readdir_currLen;
1846 Curl_safefree(sshc->readdir_line);
1847 sshc->readdir_line = NULL;
1849 state(conn, SSH_STOP);
1852 state(conn, SSH_SFTP_READDIR);
1855 case SSH_SFTP_READDIR_DONE:
1856 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1857 LIBSSH2_ERROR_EAGAIN) {
1858 rc = LIBSSH2_ERROR_EAGAIN;
1861 sshc->sftp_handle = NULL;
1862 Curl_safefree(sshc->readdir_filename);
1863 sshc->readdir_filename = NULL;
1864 Curl_safefree(sshc->readdir_longentry);
1865 sshc->readdir_longentry = NULL;
1867 /* no data to transfer */
1868 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1869 state(conn, SSH_STOP);
1872 case SSH_SFTP_DOWNLOAD_INIT:
1874 * Work on getting the specified file
1877 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1878 (unsigned int)strlen(sftp_scp->path),
1879 LIBSSH2_FXF_READ, data->set.new_file_perms,
1880 LIBSSH2_SFTP_OPENFILE);
1881 if(!sshc->sftp_handle) {
1882 if(libssh2_session_last_errno(sshc->ssh_session) ==
1883 LIBSSH2_ERROR_EAGAIN) {
1884 rc = LIBSSH2_ERROR_EAGAIN;
1888 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1889 failf(data, "Could not open remote file for reading: %s",
1890 sftp_libssh2_strerror(err));
1891 state(conn, SSH_SFTP_CLOSE);
1892 result = sftp_libssh2_error_to_CURLE(err);
1893 sshc->actualcode = result?result:CURLE_SSH;
1897 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1900 case SSH_SFTP_DOWNLOAD_STAT:
1902 LIBSSH2_SFTP_ATTRIBUTES attrs;
1904 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1905 (unsigned int)strlen(sftp_scp->path),
1906 LIBSSH2_SFTP_STAT, &attrs);
1907 if(rc == LIBSSH2_ERROR_EAGAIN) {
1912 * libssh2_sftp_open() didn't return an error, so maybe the server
1913 * just doesn't support stat()
1915 data->req.size = -1;
1916 data->req.maxdownload = -1;
1919 curl_off_t size = attrs.filesize;
1922 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1923 return CURLE_BAD_DOWNLOAD_RESUME;
1925 if(conn->data->state.use_range) {
1926 curl_off_t from, to;
1930 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1931 while(*ptr && (isspace((int)*ptr) || (*ptr=='-')))
1933 to=curlx_strtoofft(ptr, &ptr2, 0);
1934 if((ptr == ptr2) /* no "to" value given */
1939 /* from is relative to end of file */
1943 failf(data, "Offset (%"
1944 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1945 from, attrs.filesize);
1946 return CURLE_BAD_DOWNLOAD_RESUME;
1953 size = to - from + 1;
1956 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
1958 data->req.size = size;
1959 data->req.maxdownload = size;
1960 Curl_pgrsSetDownloadSize(data, size);
1963 /* We can resume if we can seek to the resume position */
1964 if(data->state.resume_from) {
1965 if(data->state.resume_from< 0) {
1966 /* We're supposed to download the last abs(from) bytes */
1967 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
1968 failf(data, "Offset (%"
1969 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1970 data->state.resume_from, attrs.filesize);
1971 return CURLE_BAD_DOWNLOAD_RESUME;
1973 /* download from where? */
1974 data->state.resume_from = attrs.filesize - data->state.resume_from;
1977 if((curl_off_t)attrs.filesize < data->state.resume_from) {
1978 failf(data, "Offset (%" FORMAT_OFF_T
1979 ") was beyond file size (%" FORMAT_OFF_T ")",
1980 data->state.resume_from, attrs.filesize);
1981 return CURLE_BAD_DOWNLOAD_RESUME;
1984 /* Does a completed file need to be seeked and started or closed ? */
1985 /* Now store the number of bytes we are expected to download */
1986 data->req.size = attrs.filesize - data->state.resume_from;
1987 data->req.maxdownload = attrs.filesize - data->state.resume_from;
1988 Curl_pgrsSetDownloadSize(data,
1989 attrs.filesize - data->state.resume_from);
1990 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1993 /* Setup the actual download */
1994 if(data->req.size == 0) {
1995 /* no data to transfer */
1996 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1997 infof(data, "File already completely downloaded\n");
1998 state(conn, SSH_STOP);
2002 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2003 FALSE, NULL, -1, NULL);
2005 /* not set by Curl_setup_transfer to preserve keepon bits */
2006 conn->writesockfd = conn->sockfd;
2008 /* FIXME: here should be explained why we need it to start the
2010 conn->cselect_bits = CURL_CSELECT_IN;
2013 state(conn, SSH_SFTP_CLOSE);
2014 sshc->actualcode = result;
2017 state(conn, SSH_STOP);
2021 case SSH_SFTP_CLOSE:
2022 if(sshc->sftp_handle) {
2023 rc = libssh2_sftp_close(sshc->sftp_handle);
2024 if(rc == LIBSSH2_ERROR_EAGAIN) {
2028 infof(data, "Failed to close libssh2 file\n");
2030 sshc->sftp_handle = NULL;
2032 Curl_safefree(sftp_scp->path);
2033 sftp_scp->path = NULL;
2035 DEBUGF(infof(data, "SFTP DONE done\n"));
2037 state(conn, SSH_SFTP_SHUTDOWN);
2039 state(conn, SSH_STOP);
2040 result = sshc->actualcode;
2043 case SSH_SFTP_SHUTDOWN:
2044 /* during times we get here due to a broken transfer and then the
2045 sftp_handle might not have been taken down so make sure that is done
2046 before we proceed */
2048 if(sshc->sftp_handle) {
2049 rc = libssh2_sftp_close(sshc->sftp_handle);
2050 if(rc == LIBSSH2_ERROR_EAGAIN) {
2054 infof(data, "Failed to close libssh2 file\n");
2056 sshc->sftp_handle = NULL;
2058 if(sshc->sftp_session) {
2059 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2060 if(rc == LIBSSH2_ERROR_EAGAIN) {
2064 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2066 sshc->sftp_session = NULL;
2069 Curl_safefree(sshc->homedir);
2070 sshc->homedir = NULL;
2072 state(conn, SSH_SESSION_DISCONNECT);
2075 case SSH_SCP_TRANS_INIT:
2076 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2078 sshc->actualcode = result;
2079 state(conn, SSH_STOP);
2083 if(data->set.upload) {
2084 if(data->set.infilesize < 0) {
2085 failf(data, "SCP requires a known file size for upload");
2086 sshc->actualcode = CURLE_UPLOAD_FAILED;
2087 state(conn, SSH_SCP_CHANNEL_FREE);
2090 state(conn, SSH_SCP_UPLOAD_INIT);
2093 state(conn, SSH_SCP_DOWNLOAD_INIT);
2097 case SSH_SCP_UPLOAD_INIT:
2099 * libssh2 requires that the destination path is a full path that
2100 * includes the destination file and name OR ends in a "/" . If this is
2101 * not done the destination file will be named the same name as the last
2102 * directory in the path.
2105 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2106 data->set.infilesize);
2107 if(!sshc->ssh_channel) {
2108 if(libssh2_session_last_errno(sshc->ssh_session) ==
2109 LIBSSH2_ERROR_EAGAIN) {
2110 rc = LIBSSH2_ERROR_EAGAIN;
2117 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2118 &err_msg, NULL, 0));
2119 failf(conn->data, "%s", err_msg);
2120 state(conn, SSH_SCP_CHANNEL_FREE);
2121 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2127 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2130 /* not set by Curl_setup_transfer to preserve keepon bits */
2131 conn->sockfd = conn->writesockfd;
2134 state(conn, SSH_SCP_CHANNEL_FREE);
2135 sshc->actualcode = result;
2138 state(conn, SSH_STOP);
2142 case SSH_SCP_DOWNLOAD_INIT:
2145 * We must check the remote file; if it is a directory no values will
2149 curl_off_t bytecount;
2151 /* clear the struct scp recv will fill in */
2152 memset(&sb, 0, sizeof(struct stat));
2154 /* get a fresh new channel from the ssh layer */
2155 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2156 sftp_scp->path, &sb);
2157 if(!sshc->ssh_channel) {
2158 if(libssh2_session_last_errno(sshc->ssh_session) ==
2159 LIBSSH2_ERROR_EAGAIN) {
2160 rc = LIBSSH2_ERROR_EAGAIN;
2167 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2168 &err_msg, NULL, 0));
2169 failf(conn->data, "%s", err_msg);
2170 state(conn, SSH_SCP_CHANNEL_FREE);
2171 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2177 bytecount = (curl_off_t)sb.st_size;
2178 data->req.maxdownload = (curl_off_t)sb.st_size;
2179 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2181 /* not set by Curl_setup_transfer to preserve keepon bits */
2182 conn->writesockfd = conn->sockfd;
2184 /* FIXME: here should be explained why we need it to start the
2186 conn->cselect_bits = CURL_CSELECT_IN;
2189 state(conn, SSH_SCP_CHANNEL_FREE);
2190 sshc->actualcode = result;
2193 state(conn, SSH_STOP);
2198 if(data->set.upload)
2199 state(conn, SSH_SCP_SEND_EOF);
2201 state(conn, SSH_SCP_CHANNEL_FREE);
2204 case SSH_SCP_SEND_EOF:
2205 if(sshc->ssh_channel) {
2206 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2207 if(rc == LIBSSH2_ERROR_EAGAIN) {
2211 infof(data, "Failed to send libssh2 channel EOF\n");
2214 state(conn, SSH_SCP_WAIT_EOF);
2217 case SSH_SCP_WAIT_EOF:
2218 if(sshc->ssh_channel) {
2219 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2220 if(rc == LIBSSH2_ERROR_EAGAIN) {
2224 infof(data, "Failed to get channel EOF: %d\n", rc);
2227 state(conn, SSH_SCP_WAIT_CLOSE);
2230 case SSH_SCP_WAIT_CLOSE:
2231 if(sshc->ssh_channel) {
2232 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2233 if(rc == LIBSSH2_ERROR_EAGAIN) {
2237 infof(data, "Channel failed to close: %d\n", rc);
2240 state(conn, SSH_SCP_CHANNEL_FREE);
2243 case SSH_SCP_CHANNEL_FREE:
2244 if(sshc->ssh_channel) {
2245 rc = libssh2_channel_free(sshc->ssh_channel);
2246 if(rc == LIBSSH2_ERROR_EAGAIN) {
2250 infof(data, "Failed to free libssh2 scp subsystem\n");
2252 sshc->ssh_channel = NULL;
2254 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2256 state(conn, SSH_SESSION_DISCONNECT);
2258 state(conn, SSH_STOP);
2259 result = sshc->actualcode;
2262 case SSH_SESSION_DISCONNECT:
2263 /* during weird times when we've been prematurely aborted, the channel
2264 is still alive when we reach this state and we MUST kill the channel
2266 if(sshc->ssh_channel) {
2267 rc = libssh2_channel_free(sshc->ssh_channel);
2268 if(rc == LIBSSH2_ERROR_EAGAIN) {
2272 infof(data, "Failed to free libssh2 scp subsystem\n");
2274 sshc->ssh_channel = NULL;
2277 if(sshc->ssh_session) {
2278 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2279 if(rc == LIBSSH2_ERROR_EAGAIN) {
2283 infof(data, "Failed to disconnect libssh2 session\n");
2287 Curl_safefree(sshc->homedir);
2288 sshc->homedir = NULL;
2290 state(conn, SSH_SESSION_FREE);
2293 case SSH_SESSION_FREE:
2294 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2296 libssh2_knownhost_free(sshc->kh);
2301 if(sshc->ssh_session) {
2302 rc = libssh2_session_free(sshc->ssh_session);
2303 if(rc == LIBSSH2_ERROR_EAGAIN) {
2307 infof(data, "Failed to free libssh2 session\n");
2309 sshc->ssh_session = NULL;
2311 conn->bits.close = TRUE;
2312 sshc->nextstate = SSH_NO_STATE;
2313 state(conn, SSH_STOP);
2314 result = sshc->actualcode;
2318 /* fallthrough, just stop! */
2320 /* internal error */
2321 sshc->nextstate = SSH_NO_STATE;
2322 state(conn, SSH_STOP);
2326 } while(!rc && (sshc->state != SSH_STOP));
2328 if(rc == LIBSSH2_ERROR_EAGAIN) {
2329 /* we would block, we need to wait for the socket to be ready (in the
2330 right direction too)! */
2337 /* called by the multi interface to figure out what socket(s) to wait for and
2338 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2339 static int ssh_perform_getsock(const struct connectdata *conn,
2340 curl_socket_t *sock, /* points to numsocks
2341 number of sockets */
2344 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2345 int bitmap = GETSOCK_BLANK;
2348 sock[0] = conn->sock[FIRSTSOCKET];
2350 if(conn->waitfor & KEEP_RECV)
2351 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2353 if(conn->waitfor & KEEP_SEND)
2354 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2358 /* if we don't know the direction we can use the generic *_getsock()
2359 function even for the protocol_connect and doing states */
2360 return Curl_single_getsock(conn, sock, numsocks);
2364 /* Generic function called by the multi interface to figure out what socket(s)
2365 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2366 static int ssh_getsock(struct connectdata *conn,
2367 curl_socket_t *sock, /* points to numsocks number
2371 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2375 /* if we don't know any direction we can just play along as we used to and
2376 not provide any sensible info */
2377 return GETSOCK_BLANK;
2379 /* if we know the direction we can use the generic *_getsock() function even
2380 for the protocol_connect and doing states */
2381 return ssh_perform_getsock(conn, sock, numsocks);
2385 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2387 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2388 * function is used to figure out in what direction and stores this info so
2389 * that the multi interface can take advantage of it. Make sure to call this
2390 * function in all cases so that when it _doesn't_ return EAGAIN we can
2391 * restore the default wait bits.
2393 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2395 struct ssh_conn *sshc = &conn->proto.sshc;
2399 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2400 /* translate the libssh2 define bits into our own bit defines */
2401 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2402 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2405 /* It didn't block or libssh2 didn't reveal in which direction, put back
2407 conn->waitfor = sshc->orig_waitfor;
2410 /* no libssh2 directional support so we simply don't know */
2411 #define ssh_block2waitfor(x,y)
2414 /* called repeatedly until done from multi.c */
2415 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2417 struct ssh_conn *sshc = &conn->proto.sshc;
2418 CURLcode result = CURLE_OK;
2419 bool block; /* we store the status and use that to provide a ssh_getsock()
2422 result = ssh_statemach_act(conn, &block);
2423 *done = (bool)(sshc->state == SSH_STOP);
2424 ssh_block2waitfor(conn, block);
2429 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2432 struct ssh_conn *sshc = &conn->proto.sshc;
2433 CURLcode result = CURLE_OK;
2434 struct SessionHandle *data = conn->data;
2436 while((sshc->state != SSH_STOP) && !result) {
2440 result = ssh_statemach_act(conn, &block);
2442 if(Curl_pgrsUpdate(conn))
2443 return CURLE_ABORTED_BY_CALLBACK;
2445 left = Curl_timeleft(conn, NULL, duringconnect);
2447 failf(data, "Operation timed out\n");
2448 return CURLE_OPERATION_TIMEDOUT;
2451 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2452 if((CURLE_OK == result) && block) {
2453 int dir = libssh2_session_block_directions(sshc->ssh_session);
2454 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2455 curl_socket_t fd_read = CURL_SOCKET_BAD;
2456 curl_socket_t fd_write = CURL_SOCKET_BAD;
2457 if (LIBSSH2_SESSION_BLOCK_INBOUND & dir) {
2460 if (LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) {
2463 /* wait for the socket to become ready */
2464 Curl_socket_ready(fd_read, fd_write,
2465 (int)(left>1000?1000:left)); /* ignore result */
2475 * SSH setup and connection
2477 static CURLcode ssh_init(struct connectdata *conn)
2479 struct SessionHandle *data = conn->data;
2480 struct SSHPROTO *ssh;
2481 struct ssh_conn *sshc = &conn->proto.sshc;
2483 sshc->actualcode = CURLE_OK; /* reset error code */
2484 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2487 if(data->state.proto.ssh)
2490 ssh = calloc(1, sizeof(struct SSHPROTO));
2492 return CURLE_OUT_OF_MEMORY;
2494 data->state.proto.ssh = ssh;
2499 static Curl_recv scp_recv, sftp_recv;
2500 static Curl_send scp_send, sftp_send;
2503 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2504 * do protocol-specific actions at connect-time.
2506 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2508 #ifdef CURL_LIBSSH2_DEBUG
2511 struct ssh_conn *ssh;
2513 struct SessionHandle *data = conn->data;
2515 /* We default to persistent connections. We set this already in this connect
2516 function to make the re-use checks properly be able to check this bit. */
2517 conn->bits.close = FALSE;
2519 /* If there already is a protocol-specific struct allocated for this
2520 sessionhandle, deal with it */
2521 Curl_reset_reqproto(conn);
2523 result = ssh_init(conn);
2527 if(conn->protocol & PROT_SCP) {
2528 conn->recv[FIRSTSOCKET] = scp_recv;
2529 conn->send[FIRSTSOCKET] = scp_send;
2531 conn->recv[FIRSTSOCKET] = sftp_recv;
2532 conn->send[FIRSTSOCKET] = sftp_send;
2534 ssh = &conn->proto.sshc;
2536 #ifdef CURL_LIBSSH2_DEBUG
2538 infof(data, "User: %s\n", conn->user);
2541 infof(data, "Password: %s\n", conn->passwd);
2543 sock = conn->sock[FIRSTSOCKET];
2544 #endif /* CURL_LIBSSH2_DEBUG */
2546 ssh->ssh_session = libssh2_session_init_ex(libssh2_malloc, libssh2_free,
2547 libssh2_realloc, conn);
2548 if(ssh->ssh_session == NULL) {
2549 failf(data, "Failure initialising ssh session");
2550 return CURLE_FAILED_INIT;
2553 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2554 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2556 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2558 /* eeek. TODO: free the ssh_session! */
2559 return CURLE_FAILED_INIT;
2562 /* read all known hosts from there */
2563 rc = libssh2_knownhost_readfile(ssh->kh,
2564 data->set.str[STRING_SSH_KNOWNHOSTS],
2565 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2567 infof(data, "Failed to read known hosts from %s\n",
2568 data->set.str[STRING_SSH_KNOWNHOSTS]);
2571 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2573 #ifdef CURL_LIBSSH2_DEBUG
2574 libssh2_trace(ssh->ssh_session, ~0);
2575 infof(data, "SSH socket: %d\n", (int)sock);
2576 #endif /* CURL_LIBSSH2_DEBUG */
2578 state(conn, SSH_S_STARTUP);
2580 if(data->state.used_interface == Curl_if_multi)
2581 result = ssh_multi_statemach(conn, done);
2583 result = ssh_easy_statemach(conn, TRUE);
2592 ***********************************************************************
2596 * This is the actual DO function for SCP. Get a file according to
2597 * the options previously setup.
2601 CURLcode scp_perform(struct connectdata *conn,
2605 CURLcode result = CURLE_OK;
2607 DEBUGF(infof(conn->data, "DO phase starts\n"));
2609 *dophase_done = FALSE; /* not done yet */
2611 /* start the first command in the DO phase */
2612 state(conn, SSH_SCP_TRANS_INIT);
2614 /* run the state-machine */
2615 if(conn->data->state.used_interface == Curl_if_multi) {
2616 result = ssh_multi_statemach(conn, dophase_done);
2619 result = ssh_easy_statemach(conn, FALSE);
2620 *dophase_done = TRUE; /* with the easy interface we are done here */
2622 *connected = conn->bits.tcpconnect;
2625 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2631 /* called from multi.c while DOing */
2632 static CURLcode scp_doing(struct connectdata *conn,
2636 result = ssh_multi_statemach(conn, dophase_done);
2639 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2645 * The DO function is generic for both protocols. There was previously two
2646 * separate ones but this way means less duplicated code.
2649 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2653 struct SessionHandle *data = conn->data;
2655 *done = FALSE; /* default to false */
2658 Since connections can be re-used between SessionHandles, this might be a
2659 connection already existing but on a fresh SessionHandle struct so we must
2660 make sure we have a good 'struct SSHPROTO' to play with. For new
2661 connections, the struct SSHPROTO is allocated and setup in the
2662 ssh_connect() function.
2664 Curl_reset_reqproto(conn);
2665 res = ssh_init(conn);
2669 data->req.size = -1; /* make sure this is unknown at this point */
2671 Curl_pgrsSetUploadCounter(data, 0);
2672 Curl_pgrsSetDownloadCounter(data, 0);
2673 Curl_pgrsSetUploadSize(data, 0);
2674 Curl_pgrsSetDownloadSize(data, 0);
2676 if(conn->protocol & PROT_SCP)
2677 res = scp_perform(conn, &connected, done);
2679 res = sftp_perform(conn, &connected, done);
2684 /* BLOCKING, but the function is using the state machine so the only reason
2685 this is still blocking is that the multi interface code has no support for
2686 disconnecting operations that takes a while */
2687 static CURLcode scp_disconnect(struct connectdata *conn)
2689 CURLcode result = CURLE_OK;
2690 struct ssh_conn *ssh = &conn->proto.sshc;
2692 Curl_safefree(conn->data->state.proto.ssh);
2693 conn->data->state.proto.ssh = NULL;
2695 if(ssh->ssh_session) {
2696 /* only if there's a session still around to use! */
2698 state(conn, SSH_SESSION_DISCONNECT);
2700 result = ssh_easy_statemach(conn, FALSE);
2706 /* generic done function for both SCP and SFTP called from their specific
2708 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2710 CURLcode result = CURLE_OK;
2711 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2713 if(status == CURLE_OK) {
2714 /* run the state-machine
2716 TODO: when the multi interface is used, this _really_ should be using
2717 the ssh_multi_statemach function but we have no general support for
2718 non-blocking DONE operations, not in the multi state machine and with
2719 Curl_done() invokes on several places in the code!
2721 result = ssh_easy_statemach(conn, FALSE);
2726 Curl_safefree(sftp_scp->path);
2727 sftp_scp->path = NULL;
2728 Curl_pgrsDone(conn);
2730 conn->data->req.keepon = 0; /* clear all bits */
2735 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2738 (void)premature; /* not used */
2740 if(status == CURLE_OK)
2741 state(conn, SSH_SCP_DONE);
2743 return ssh_done(conn, status);
2747 /* return number of received (decrypted) bytes */
2748 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2749 const void *mem, size_t len, CURLcode *err)
2752 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2754 /* libssh2_channel_write() returns int! */
2756 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2758 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2760 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2769 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2770 * a regular CURLcode value.
2772 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2773 char *mem, size_t len, CURLcode *err)
2776 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2778 /* libssh2_channel_read() returns int */
2780 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2782 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2783 if (nread == LIBSSH2_ERROR_EAGAIN) {
2792 * =============== SFTP ===============
2796 ***********************************************************************
2800 * This is the actual DO function for SFTP. Get a file/directory according to
2801 * the options previously setup.
2805 CURLcode sftp_perform(struct connectdata *conn,
2809 CURLcode result = CURLE_OK;
2811 DEBUGF(infof(conn->data, "DO phase starts\n"));
2813 *dophase_done = FALSE; /* not done yet */
2815 /* start the first command in the DO phase */
2816 state(conn, SSH_SFTP_QUOTE_INIT);
2818 /* run the state-machine */
2819 if(conn->data->state.used_interface == Curl_if_multi) {
2820 result = ssh_multi_statemach(conn, dophase_done);
2823 result = ssh_easy_statemach(conn, FALSE);
2824 *dophase_done = TRUE; /* with the easy interface we are done here */
2826 *connected = conn->bits.tcpconnect;
2829 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2835 /* called from multi.c while DOing */
2836 static CURLcode sftp_doing(struct connectdata *conn,
2840 result = ssh_multi_statemach(conn, dophase_done);
2843 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2848 /* BLOCKING, but the function is using the state machine so the only reason
2849 this is still blocking is that the multi interface code has no support for
2850 disconnecting operations that takes a while */
2851 static CURLcode sftp_disconnect(struct connectdata *conn)
2853 CURLcode result = CURLE_OK;
2855 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2857 Curl_safefree(conn->data->state.proto.ssh);
2858 conn->data->state.proto.ssh = NULL;
2860 if(conn->proto.sshc.ssh_session) {
2861 /* only if there's a session still around to use! */
2862 state(conn, SSH_SFTP_SHUTDOWN);
2863 result = ssh_easy_statemach(conn, FALSE);
2866 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2872 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2875 struct ssh_conn *sshc = &conn->proto.sshc;
2877 if(status == CURLE_OK) {
2878 /* Before we shut down, see if there are any post-quote commands to
2880 if(!status && !premature && conn->data->set.postquote) {
2881 sshc->nextstate = SSH_SFTP_CLOSE;
2882 state(conn, SSH_SFTP_POSTQUOTE_INIT);
2885 state(conn, SSH_SFTP_CLOSE);
2887 return ssh_done(conn, status);
2890 /* return number of sent bytes */
2891 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
2892 const void *mem, size_t len, CURLcode *err)
2894 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2895 but is changed to ssize_t in 0.15. These days we don't
2896 support libssh2 0.15*/
2899 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2901 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2903 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2912 * Return number of received (decrypted) bytes
2914 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
2915 char *mem, size_t len, CURLcode *err)
2920 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
2922 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2924 if(nread == LIBSSH2_ERROR_EAGAIN) {
2931 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
2934 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
2936 * Permission to use, copy, modify, and distribute this software for any
2937 * purpose with or without fee is hereby granted, provided that the above
2938 * copyright notice and this permission notice appear in all copies.
2940 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2941 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2942 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2943 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2944 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2945 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2946 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2949 get_pathname(const char **cpp, char **path)
2951 const char *cp = *cpp, *end;
2954 static const char WHITESPACE[] = " \t\r\n";
2956 cp += strspn(cp, WHITESPACE);
2960 return CURLE_QUOTE_ERROR;
2963 *path = malloc(strlen(cp) + 1);
2965 return CURLE_OUT_OF_MEMORY;
2967 /* Check for quoted filenames */
2968 if(*cp == '\"' || *cp == '\'') {
2971 /* Search for terminating quote, unescape some chars */
2972 for (i = j = 0; i <= strlen(cp); i++) {
2973 if(cp[i] == quot) { /* Found quote */
2978 if(cp[i] == '\0') { /* End of string */
2979 /*error("Unterminated quote");*/
2982 if(cp[i] == '\\') { /* Escaped characters */
2984 if(cp[i] != '\'' && cp[i] != '\"' &&
2986 /*error("Bad escaped character '\\%c'",
2991 (*path)[j++] = cp[i];
2995 /*error("Empty quotes");*/
2998 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3001 /* Read to end of filename */
3002 end = strpbrk(cp, WHITESPACE);
3004 end = strchr(cp, '\0');
3005 *cpp = end + strspn(end, WHITESPACE);
3007 memcpy(*path, cp, end - cp);
3008 (*path)[end - cp] = '\0';
3013 Curl_safefree(*path);
3015 return CURLE_QUOTE_ERROR;
3019 static const char *sftp_libssh2_strerror(unsigned long err)
3022 case LIBSSH2_FX_NO_SUCH_FILE:
3023 return "No such file or directory";
3025 case LIBSSH2_FX_PERMISSION_DENIED:
3026 return "Permission denied";
3028 case LIBSSH2_FX_FAILURE:
3029 return "Operation failed";
3031 case LIBSSH2_FX_BAD_MESSAGE:
3032 return "Bad message from SFTP server";
3034 case LIBSSH2_FX_NO_CONNECTION:
3035 return "Not connected to SFTP server";
3037 case LIBSSH2_FX_CONNECTION_LOST:
3038 return "Connection to SFTP server lost";
3040 case LIBSSH2_FX_OP_UNSUPPORTED:
3041 return "Operation not supported by SFTP server";
3043 case LIBSSH2_FX_INVALID_HANDLE:
3044 return "Invalid handle";
3046 case LIBSSH2_FX_NO_SUCH_PATH:
3047 return "No such file or directory";
3049 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3050 return "File already exists";
3052 case LIBSSH2_FX_WRITE_PROTECT:
3053 return "File is write protected";
3055 case LIBSSH2_FX_NO_MEDIA:
3058 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3061 case LIBSSH2_FX_QUOTA_EXCEEDED:
3062 return "User quota exceeded";
3064 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3065 return "Unknown principle";
3067 case LIBSSH2_FX_LOCK_CONFlICT:
3068 return "File lock conflict";
3070 case LIBSSH2_FX_DIR_NOT_EMPTY:
3071 return "Directory not empty";
3073 case LIBSSH2_FX_NOT_A_DIRECTORY:
3074 return "Not a directory";
3076 case LIBSSH2_FX_INVALID_FILENAME:
3077 return "Invalid filename";
3079 case LIBSSH2_FX_LINK_LOOP:
3080 return "Link points to itself";
3082 return "Unknown error in libssh2";
3085 #endif /* USE_LIBSSH2 */