1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2014, 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 */
25 #include "curl_setup.h"
34 #include <libssh2_sftp.h>
40 #ifdef HAVE_NETINET_IN_H
41 #include <netinet/in.h>
43 #ifdef HAVE_ARPA_INET_H
44 #include <arpa/inet.h>
47 #include <sys/utsname.h>
57 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
59 #define in_addr_t unsigned long
62 #include <curl/curl.h>
69 #include "http.h" /* for HTTP proxy tunnel stuff */
72 #include "speedcheck.h"
76 #include "vtls/vtls.h"
79 #include "inet_ntop.h"
80 #include "parsedate.h" /* for the week day and month names */
81 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
82 #include "strtoofft.h"
87 #define _MPRINTF_REPLACE /* use our functions only */
88 #include <curl/mprintf.h>
90 #include "curl_memory.h"
91 /* The last #include file should be: */
96 # define PATH_MAX MAX_PATH
100 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
101 have their definition hidden well */
104 #define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
106 #define sftp_libssh2_realpath(s,p,t,m) \
107 libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
108 (t), (m), LIBSSH2_SFTP_REALPATH)
110 /* Local functions: */
111 static const char *sftp_libssh2_strerror(int err);
112 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
113 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
114 static LIBSSH2_FREE_FUNC(my_libssh2_free);
116 static CURLcode get_pathname(const char **cpp, char **path);
118 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
119 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
120 static CURLcode ssh_do(struct connectdata *conn, bool *done);
122 static CURLcode ssh_getworkingpath(struct connectdata *conn,
123 char *homedir, /* when SFTP is used */
126 static CURLcode scp_done(struct connectdata *conn,
127 CURLcode, bool premature);
128 static CURLcode scp_doing(struct connectdata *conn,
130 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
132 static CURLcode sftp_done(struct connectdata *conn,
133 CURLcode, bool premature);
134 static CURLcode sftp_doing(struct connectdata *conn,
136 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
138 CURLcode sftp_perform(struct connectdata *conn,
142 static int ssh_getsock(struct connectdata *conn,
143 curl_socket_t *sock, /* points to numsocks number
147 static int ssh_perform_getsock(const struct connectdata *conn,
148 curl_socket_t *sock, /* points to numsocks
152 static CURLcode ssh_setup_connection(struct connectdata *conn);
155 * SCP protocol handler.
158 const struct Curl_handler Curl_handler_scp = {
160 ssh_setup_connection, /* setup_connection */
163 ZERO_NULL, /* do_more */
164 ssh_connect, /* connect_it */
165 ssh_multi_statemach, /* connecting */
166 scp_doing, /* doing */
167 ssh_getsock, /* proto_getsock */
168 ssh_getsock, /* doing_getsock */
169 ZERO_NULL, /* domore_getsock */
170 ssh_perform_getsock, /* perform_getsock */
171 scp_disconnect, /* disconnect */
172 ZERO_NULL, /* readwrite */
173 PORT_SSH, /* defport */
174 CURLPROTO_SCP, /* protocol */
175 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
176 | PROTOPT_NOURLQUERY /* flags */
181 * SFTP protocol handler.
184 const struct Curl_handler Curl_handler_sftp = {
186 ssh_setup_connection, /* setup_connection */
188 sftp_done, /* done */
189 ZERO_NULL, /* do_more */
190 ssh_connect, /* connect_it */
191 ssh_multi_statemach, /* connecting */
192 sftp_doing, /* doing */
193 ssh_getsock, /* proto_getsock */
194 ssh_getsock, /* doing_getsock */
195 ZERO_NULL, /* domore_getsock */
196 ssh_perform_getsock, /* perform_getsock */
197 sftp_disconnect, /* disconnect */
198 ZERO_NULL, /* readwrite */
199 PORT_SSH, /* defport */
200 CURLPROTO_SFTP, /* protocol */
201 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
202 | PROTOPT_NOURLQUERY /* flags */
206 kbd_callback(const char *name, int name_len, const char *instruction,
207 int instruction_len, int num_prompts,
208 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
209 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
212 struct connectdata *conn = (struct connectdata *)*abstract;
214 #ifdef CURL_LIBSSH2_DEBUG
215 fprintf(stderr, "name=%s\n", name);
216 fprintf(stderr, "name_len=%d\n", name_len);
217 fprintf(stderr, "instruction=%s\n", instruction);
218 fprintf(stderr, "instruction_len=%d\n", instruction_len);
219 fprintf(stderr, "num_prompts=%d\n", num_prompts);
224 (void)instruction_len;
225 #endif /* CURL_LIBSSH2_DEBUG */
226 if(num_prompts == 1) {
227 responses[0].text = strdup(conn->passwd);
228 responses[0].length = curlx_uztoui(strlen(conn->passwd));
234 static CURLcode sftp_libssh2_error_to_CURLE(int err)
240 case LIBSSH2_FX_NO_SUCH_FILE:
241 case LIBSSH2_FX_NO_SUCH_PATH:
242 return CURLE_REMOTE_FILE_NOT_FOUND;
244 case LIBSSH2_FX_PERMISSION_DENIED:
245 case LIBSSH2_FX_WRITE_PROTECT:
246 case LIBSSH2_FX_LOCK_CONFlICT:
247 return CURLE_REMOTE_ACCESS_DENIED;
249 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
250 case LIBSSH2_FX_QUOTA_EXCEEDED:
251 return CURLE_REMOTE_DISK_FULL;
253 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
254 return CURLE_REMOTE_FILE_EXISTS;
256 case LIBSSH2_FX_DIR_NOT_EMPTY:
257 return CURLE_QUOTE_ERROR;
266 static CURLcode libssh2_session_error_to_CURLE(int err)
269 /* Ordered by order of appearance in libssh2.h */
270 case LIBSSH2_ERROR_NONE:
273 case LIBSSH2_ERROR_SOCKET_NONE:
274 return CURLE_COULDNT_CONNECT;
276 case LIBSSH2_ERROR_ALLOC:
277 return CURLE_OUT_OF_MEMORY;
279 case LIBSSH2_ERROR_SOCKET_SEND:
280 return CURLE_SEND_ERROR;
282 case LIBSSH2_ERROR_HOSTKEY_INIT:
283 case LIBSSH2_ERROR_HOSTKEY_SIGN:
284 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
285 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
286 return CURLE_PEER_FAILED_VERIFICATION;
288 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
289 return CURLE_LOGIN_DENIED;
291 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
292 case LIBSSH2_ERROR_TIMEOUT:
293 return CURLE_OPERATION_TIMEDOUT;
295 case LIBSSH2_ERROR_EAGAIN:
299 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
300 error code, and possibly add a few new SSH-related one. We must however
301 not return or even depend on libssh2 errors in the public libcurl API */
306 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
308 (void)abstract; /* arg not used */
309 return malloc(count);
312 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
314 (void)abstract; /* arg not used */
315 return realloc(ptr, count);
318 static LIBSSH2_FREE_FUNC(my_libssh2_free)
320 (void)abstract; /* arg not used */
321 if(ptr) /* ssh2 agent sometimes call free with null ptr */
326 * SSH State machine related code
328 /* This is the ONLY way to change SSH state! */
329 static void state(struct connectdata *conn, sshstate nowstate)
331 struct ssh_conn *sshc = &conn->proto.sshc;
332 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
333 /* for debug purposes */
334 static const char * const names[] = {
340 "SSH_AUTH_PKEY_INIT",
342 "SSH_AUTH_PASS_INIT",
344 "SSH_AUTH_AGENT_INIT",
345 "SSH_AUTH_AGENT_LIST",
347 "SSH_AUTH_HOST_INIT",
354 "SSH_SFTP_QUOTE_INIT",
355 "SSH_SFTP_POSTQUOTE_INIT",
357 "SSH_SFTP_NEXT_QUOTE",
358 "SSH_SFTP_QUOTE_STAT",
359 "SSH_SFTP_QUOTE_SETSTAT",
360 "SSH_SFTP_QUOTE_SYMLINK",
361 "SSH_SFTP_QUOTE_MKDIR",
362 "SSH_SFTP_QUOTE_RENAME",
363 "SSH_SFTP_QUOTE_RMDIR",
364 "SSH_SFTP_QUOTE_UNLINK",
365 "SSH_SFTP_TRANS_INIT",
366 "SSH_SFTP_UPLOAD_INIT",
367 "SSH_SFTP_CREATE_DIRS_INIT",
368 "SSH_SFTP_CREATE_DIRS",
369 "SSH_SFTP_CREATE_DIRS_MKDIR",
370 "SSH_SFTP_READDIR_INIT",
372 "SSH_SFTP_READDIR_LINK",
373 "SSH_SFTP_READDIR_BOTTOM",
374 "SSH_SFTP_READDIR_DONE",
375 "SSH_SFTP_DOWNLOAD_INIT",
376 "SSH_SFTP_DOWNLOAD_STAT",
379 "SSH_SCP_TRANS_INIT",
380 "SSH_SCP_UPLOAD_INIT",
381 "SSH_SCP_DOWNLOAD_INIT",
385 "SSH_SCP_WAIT_CLOSE",
386 "SSH_SCP_CHANNEL_FREE",
387 "SSH_SESSION_DISCONNECT",
392 if(sshc->state != nowstate) {
393 infof(conn->data, "SFTP %p state change from %s to %s\n",
394 (void *)sshc, names[sshc->state], names[nowstate]);
398 sshc->state = nowstate;
401 /* figure out the path to work with in this particular request */
402 static CURLcode ssh_getworkingpath(struct connectdata *conn,
403 char *homedir, /* when SFTP is used */
404 char **path) /* returns the allocated
405 real path to work with */
407 struct SessionHandle *data = conn->data;
408 char *real_path = NULL;
410 int working_path_len;
412 working_path = curl_easy_unescape(data, data->state.path, 0,
415 return CURLE_OUT_OF_MEMORY;
417 /* Check for /~/ , indicating relative to the user's home directory */
418 if(conn->handler->protocol & CURLPROTO_SCP) {
419 real_path = malloc(working_path_len+1);
420 if(real_path == NULL) {
422 return CURLE_OUT_OF_MEMORY;
424 if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
425 /* It is referenced to the home directory, so strip the leading '/~/' */
426 memcpy(real_path, working_path+3, 4 + working_path_len-3);
428 memcpy(real_path, working_path, 1 + working_path_len);
430 else if(conn->handler->protocol & CURLPROTO_SFTP) {
431 if((working_path_len > 1) && (working_path[1] == '~')) {
432 size_t homelen = strlen(homedir);
433 real_path = malloc(homelen + working_path_len + 1);
434 if(real_path == NULL) {
436 return CURLE_OUT_OF_MEMORY;
438 /* It is referenced to the home directory, so strip the
440 memcpy(real_path, homedir, homelen);
441 real_path[homelen] = '/';
442 real_path[homelen+1] = '\0';
443 if(working_path_len > 3) {
444 memcpy(real_path+homelen+1, working_path + 3,
445 1 + working_path_len -3);
449 real_path = malloc(working_path_len+1);
450 if(real_path == NULL) {
452 return CURLE_OUT_OF_MEMORY;
454 memcpy(real_path, working_path, 1+working_path_len);
460 /* store the pointer for the caller to receive */
466 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
467 static int sshkeycallback(CURL *easy,
468 const struct curl_khkey *knownkey, /* known */
469 const struct curl_khkey *foundkey, /* found */
470 enum curl_khmatch match,
478 /* we only allow perfect matches, and we reject everything else */
479 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
484 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
487 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
488 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
490 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
494 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
495 * architectures so we check of the necessary function is present.
497 #ifndef HAVE_LIBSSH2_SCP_SEND64
498 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
500 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
501 (libssh2_uint64_t)d, 0, 0)
505 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
507 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
508 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
511 static CURLcode ssh_knownhost(struct connectdata *conn)
513 CURLcode result = CURLE_OK;
515 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
516 struct SessionHandle *data = conn->data;
518 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
519 /* we're asked to verify the host against a file */
520 struct ssh_conn *sshc = &conn->proto.sshc;
524 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
526 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
531 * A subject to figure out is what host name we need to pass in here.
532 * What host name does OpenSSH store in its file if an IDN name is
535 struct libssh2_knownhost *host;
536 enum curl_khmatch keymatch;
537 curl_sshkeycallback func =
538 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
539 struct curl_khkey knownkey;
540 struct curl_khkey *knownkeyp = NULL;
541 struct curl_khkey foundkey;
543 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
544 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
546 keycheck = libssh2_knownhost_check(sshc->kh,
549 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
550 LIBSSH2_KNOWNHOST_KEYENC_RAW|
554 infof(data, "SSH host check: %d, key: %s\n", keycheck,
555 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
558 /* setup 'knownkey' */
559 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
560 knownkey.key = host->key;
562 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
563 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
564 knownkeyp = &knownkey;
567 /* setup 'foundkey' */
568 foundkey.key = remotekey;
569 foundkey.len = keylen;
570 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
571 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
574 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
575 * curl_khmatch enum are ever modified, we need to introduce a
576 * translation table here!
578 keymatch = (enum curl_khmatch)keycheck;
580 /* Ask the callback how to behave */
581 rc = func(data, knownkeyp, /* from the knownhosts file */
582 &foundkey, /* from the remote host */
583 keymatch, data->set.ssh_keyfunc_userp);
586 /* no remotekey means failure! */
587 rc = CURLKHSTAT_REJECT;
590 default: /* unknown return codes will equal reject */
591 case CURLKHSTAT_REJECT:
592 state(conn, SSH_SESSION_FREE);
593 case CURLKHSTAT_DEFER:
594 /* DEFER means bail out but keep the SSH_HOSTKEY state */
595 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
597 case CURLKHSTAT_FINE:
598 case CURLKHSTAT_FINE_ADD_TO_FILE:
600 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
601 /* the found host+key didn't match but has been told to be fine
602 anyway so we add it in memory */
603 int addrc = libssh2_knownhost_add(sshc->kh,
604 conn->host.name, NULL,
606 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
607 LIBSSH2_KNOWNHOST_KEYENC_RAW|
610 infof(data, "Warning adding the known host %s failed!\n",
612 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
613 /* now we write the entire in-memory list of known hosts to the
616 libssh2_knownhost_writefile(sshc->kh,
617 data->set.str[STRING_SSH_KNOWNHOSTS],
618 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
620 infof(data, "Warning, writing %s failed!\n",
621 data->set.str[STRING_SSH_KNOWNHOSTS]);
628 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
634 static CURLcode ssh_check_fingerprint(struct connectdata *conn)
636 struct ssh_conn *sshc = &conn->proto.sshc;
637 struct SessionHandle *data = conn->data;
638 const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
642 const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
643 LIBSSH2_HOSTKEY_HASH_MD5);
646 /* The fingerprint points to static storage (!), don't free() it. */
647 for(i = 0; i < 16; i++)
648 snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
649 infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
652 /* Before we authenticate we check the hostkey's MD5 fingerprint
653 * against a known fingerprint, if available.
655 if(pubkey_md5 && strlen(pubkey_md5) == 32) {
656 if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
659 "Denied establishing ssh session: mismatch md5 fingerprint. "
660 "Remote %s is not equal to %s", md5buffer, pubkey_md5);
663 "Denied establishing ssh session: md5 fingerprint not available");
664 state(conn, SSH_SESSION_FREE);
665 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
666 return sshc->actualcode;
669 infof(data, "MD5 checksum match!\n");
670 /* as we already matched, we skip the check for known hosts */
675 return ssh_knownhost(conn);
679 * ssh_statemach_act() runs the SSH state machine as far as it can without
680 * blocking and without reaching the end. The data the pointer 'block' points
681 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
682 * meaning it wants to be called again when the socket is ready
685 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
687 CURLcode result = CURLE_OK;
688 struct SessionHandle *data = conn->data;
689 struct SSHPROTO *sftp_scp = data->req.protop;
690 struct ssh_conn *sshc = &conn->proto.sshc;
691 curl_socket_t sock = conn->sock[FIRSTSOCKET];
692 char *new_readdir_line;
693 int rc = LIBSSH2_ERROR_NONE;
695 int seekerr = CURL_SEEKFUNC_OK;
696 *block = 0; /* we're not blocking by default */
700 switch(sshc->state) {
702 sshc->secondCreateDirs = 0;
703 sshc->nextstate = SSH_NO_STATE;
704 sshc->actualcode = CURLE_OK;
706 /* Set libssh2 to non-blocking, since everything internally is
708 libssh2_session_set_blocking(sshc->ssh_session, 0);
710 state(conn, SSH_S_STARTUP);
714 rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
715 if(rc == LIBSSH2_ERROR_EAGAIN) {
719 failf(data, "Failure establishing ssh session");
720 state(conn, SSH_SESSION_FREE);
721 sshc->actualcode = CURLE_FAILED_INIT;
725 state(conn, SSH_HOSTKEY);
730 * Before we authenticate we should check the hostkey's fingerprint
731 * against our known hosts. How that is handled (reading from file,
732 * whatever) is up to us.
734 result = ssh_check_fingerprint(conn);
735 if(result == CURLE_OK)
736 state(conn, SSH_AUTHLIST);
741 * Figure out authentication methods
742 * NB: As soon as we have provided a username to an openssh server we
743 * must never change it later. Thus, always specify the correct username
744 * here, even though the libssh2 docs kind of indicate that it should be
745 * possible to get a 'generic' list (not user-specific) of authentication
746 * methods, presumably with a blank username. That won't work in my
748 * So always specify it here.
750 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
752 curlx_uztoui(strlen(conn->user)));
754 if(!sshc->authlist) {
755 if(libssh2_userauth_authenticated(sshc->ssh_session)) {
757 infof(data, "SSH user accepted with no authentication\n");
758 state(conn, SSH_AUTH_DONE);
761 else if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
762 LIBSSH2_ERROR_EAGAIN) {
763 rc = LIBSSH2_ERROR_EAGAIN;
767 state(conn, SSH_SESSION_FREE);
768 sshc->actualcode = libssh2_session_error_to_CURLE(err);
772 infof(data, "SSH authentication methods available: %s\n",
775 state(conn, SSH_AUTH_PKEY_INIT);
778 case SSH_AUTH_PKEY_INIT:
780 * Check the supported auth types in the order I feel is most secure
781 * with the requested type of authentication
783 sshc->authed = FALSE;
785 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
786 (strstr(sshc->authlist, "publickey") != NULL)) {
788 bool rsa_pub_empty_but_ok = FALSE;
790 sshc->rsa_pub = sshc->rsa = NULL;
792 /* To ponder about: should really the lib be messing about with the
793 HOME environment variable etc? */
794 home = curl_getenv("HOME");
796 if(data->set.str[STRING_SSH_PUBLIC_KEY] &&
797 !*data->set.str[STRING_SSH_PUBLIC_KEY])
798 rsa_pub_empty_but_ok = true;
799 else if(data->set.str[STRING_SSH_PUBLIC_KEY])
800 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
802 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
804 /* as a final resort, try current dir! */
805 sshc->rsa_pub = strdup("id_dsa.pub");
807 if(!rsa_pub_empty_but_ok && (sshc->rsa_pub == NULL)) {
809 state(conn, SSH_SESSION_FREE);
810 sshc->actualcode = CURLE_OUT_OF_MEMORY;
814 if(data->set.str[STRING_SSH_PRIVATE_KEY])
815 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
817 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
819 /* as a final resort, try current dir! */
820 sshc->rsa = strdup("id_dsa");
822 if(sshc->rsa == NULL) {
824 Curl_safefree(sshc->rsa_pub);
825 state(conn, SSH_SESSION_FREE);
826 sshc->actualcode = CURLE_OUT_OF_MEMORY;
830 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
831 if(!sshc->passphrase)
832 sshc->passphrase = "";
836 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
837 infof(data, "Using ssh private key file %s\n", sshc->rsa);
839 state(conn, SSH_AUTH_PKEY);
842 state(conn, SSH_AUTH_PASS_INIT);
847 /* The function below checks if the files exists, no need to stat() here.
849 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
854 sshc->rsa, sshc->passphrase);
855 if(rc == LIBSSH2_ERROR_EAGAIN) {
859 Curl_safefree(sshc->rsa_pub);
860 Curl_safefree(sshc->rsa);
864 infof(data, "Initialized SSH public key authentication\n");
865 state(conn, SSH_AUTH_DONE);
869 (void)libssh2_session_last_error(sshc->ssh_session,
871 infof(data, "SSH public key authentication failed: %s\n", err_msg);
872 state(conn, SSH_AUTH_PASS_INIT);
876 case SSH_AUTH_PASS_INIT:
877 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
878 (strstr(sshc->authlist, "password") != NULL)) {
879 state(conn, SSH_AUTH_PASS);
882 state(conn, SSH_AUTH_HOST_INIT);
887 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
888 curlx_uztoui(strlen(conn->user)),
890 curlx_uztoui(strlen(conn->passwd)),
892 if(rc == LIBSSH2_ERROR_EAGAIN) {
897 infof(data, "Initialized password authentication\n");
898 state(conn, SSH_AUTH_DONE);
901 state(conn, SSH_AUTH_HOST_INIT);
905 case SSH_AUTH_HOST_INIT:
906 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
907 (strstr(sshc->authlist, "hostbased") != NULL)) {
908 state(conn, SSH_AUTH_HOST);
911 state(conn, SSH_AUTH_AGENT_INIT);
916 state(conn, SSH_AUTH_AGENT_INIT);
919 case SSH_AUTH_AGENT_INIT:
920 #ifdef HAVE_LIBSSH2_AGENT_API
921 if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
922 && (strstr(sshc->authlist, "publickey") != NULL)) {
924 /* Connect to the ssh-agent */
925 /* The agent could be shared by a curl thread i believe
926 but nothing obvious as keys can be added/removed at any time */
927 if(!sshc->ssh_agent) {
928 sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
929 if(!sshc->ssh_agent) {
930 infof(data, "Could not create agent object\n");
932 state(conn, SSH_AUTH_KEY_INIT);
937 rc = libssh2_agent_connect(sshc->ssh_agent);
938 if(rc == LIBSSH2_ERROR_EAGAIN)
941 infof(data, "Failure connecting to agent\n");
942 state(conn, SSH_AUTH_KEY_INIT);
945 state(conn, SSH_AUTH_AGENT_LIST);
949 #endif /* HAVE_LIBSSH2_AGENT_API */
950 state(conn, SSH_AUTH_KEY_INIT);
953 case SSH_AUTH_AGENT_LIST:
954 #ifdef HAVE_LIBSSH2_AGENT_API
955 rc = libssh2_agent_list_identities(sshc->ssh_agent);
957 if(rc == LIBSSH2_ERROR_EAGAIN)
960 infof(data, "Failure requesting identities to agent\n");
961 state(conn, SSH_AUTH_KEY_INIT);
964 state(conn, SSH_AUTH_AGENT);
965 sshc->sshagent_prev_identity = NULL;
971 #ifdef HAVE_LIBSSH2_AGENT_API
972 /* as prev_identity evolves only after an identity user auth finished we
973 can safely request it again as long as EAGAIN is returned here or by
974 libssh2_agent_userauth */
975 rc = libssh2_agent_get_identity(sshc->ssh_agent,
976 &sshc->sshagent_identity,
977 sshc->sshagent_prev_identity);
978 if(rc == LIBSSH2_ERROR_EAGAIN)
982 rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
983 sshc->sshagent_identity);
986 if(rc != LIBSSH2_ERROR_EAGAIN) {
987 /* tried and failed? go to next identity */
988 sshc->sshagent_prev_identity = sshc->sshagent_identity;
995 infof(data, "Failure requesting identities to agent\n");
997 infof(data, "No identity would match\n");
999 if(rc == LIBSSH2_ERROR_NONE) {
1000 sshc->authed = TRUE;
1001 infof(data, "Agent based authentication successful\n");
1002 state(conn, SSH_AUTH_DONE);
1005 state(conn, SSH_AUTH_KEY_INIT);
1009 case SSH_AUTH_KEY_INIT:
1010 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
1011 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
1012 state(conn, SSH_AUTH_KEY);
1015 state(conn, SSH_AUTH_DONE);
1020 /* Authentication failed. Continue with keyboard-interactive now. */
1021 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
1024 strlen(conn->user)),
1026 if(rc == LIBSSH2_ERROR_EAGAIN) {
1030 sshc->authed = TRUE;
1031 infof(data, "Initialized keyboard interactive authentication\n");
1033 state(conn, SSH_AUTH_DONE);
1038 failf(data, "Authentication failure");
1039 state(conn, SSH_SESSION_FREE);
1040 sshc->actualcode = CURLE_LOGIN_DENIED;
1045 * At this point we have an authenticated ssh session.
1047 infof(data, "Authentication complete\n");
1049 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
1051 conn->sockfd = sock;
1052 conn->writesockfd = CURL_SOCKET_BAD;
1054 if(conn->handler->protocol == CURLPROTO_SFTP) {
1055 state(conn, SSH_SFTP_INIT);
1058 infof(data, "SSH CONNECT phase done\n");
1059 state(conn, SSH_STOP);
1064 * Start the libssh2 sftp session
1066 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
1067 if(!sshc->sftp_session) {
1068 if(libssh2_session_last_errno(sshc->ssh_session) ==
1069 LIBSSH2_ERROR_EAGAIN) {
1070 rc = LIBSSH2_ERROR_EAGAIN;
1076 (void)libssh2_session_last_error(sshc->ssh_session,
1078 failf(data, "Failure initializing sftp session: %s", err_msg);
1079 state(conn, SSH_SESSION_FREE);
1080 sshc->actualcode = CURLE_FAILED_INIT;
1084 state(conn, SSH_SFTP_REALPATH);
1087 case SSH_SFTP_REALPATH:
1089 char tempHome[PATH_MAX];
1092 * Get the "home" directory
1094 rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
1095 tempHome, PATH_MAX-1);
1096 if(rc == LIBSSH2_ERROR_EAGAIN) {
1100 /* It seems that this string is not always NULL terminated */
1101 tempHome[rc] = '\0';
1102 sshc->homedir = strdup(tempHome);
1103 if(!sshc->homedir) {
1104 state(conn, SSH_SFTP_CLOSE);
1105 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1108 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1111 /* Return the error type */
1112 err = sftp_libssh2_last_error(sshc->sftp_session);
1113 result = sftp_libssh2_error_to_CURLE(err);
1114 sshc->actualcode = result?result:CURLE_SSH;
1115 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1117 state(conn, SSH_STOP);
1121 /* This is the last step in the SFTP connect phase. Do note that while
1122 we get the homedir here, we get the "workingpath" in the DO action
1123 since the homedir will remain the same between request but the
1124 working path will not. */
1125 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1126 state(conn, SSH_STOP);
1129 case SSH_SFTP_QUOTE_INIT:
1131 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1133 sshc->actualcode = result;
1134 state(conn, SSH_STOP);
1138 if(data->set.quote) {
1139 infof(data, "Sending quote commands\n");
1140 sshc->quote_item = data->set.quote;
1141 state(conn, SSH_SFTP_QUOTE);
1144 state(conn, SSH_SFTP_TRANS_INIT);
1148 case SSH_SFTP_POSTQUOTE_INIT:
1149 if(data->set.postquote) {
1150 infof(data, "Sending quote commands\n");
1151 sshc->quote_item = data->set.postquote;
1152 state(conn, SSH_SFTP_QUOTE);
1155 state(conn, SSH_STOP);
1159 case SSH_SFTP_QUOTE:
1160 /* Send any quote commands */
1165 * Support some of the "FTP" commands
1167 char *cmd = sshc->quote_item->data;
1168 sshc->acceptfail = FALSE;
1170 /* if a command starts with an asterisk, which a legal SFTP command never
1171 can, the command will be allowed to fail without it causing any
1172 aborts or cancels etc. It will cause libcurl to act as if the command
1173 is successful, whatever the server reponds. */
1177 sshc->acceptfail = TRUE;
1180 if(curl_strequal("pwd", cmd)) {
1181 /* output debug output if that is requested */
1182 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1185 result = CURLE_OUT_OF_MEMORY;
1186 state(conn, SSH_SFTP_CLOSE);
1187 sshc->nextstate = SSH_NO_STATE;
1190 if(data->set.verbose) {
1191 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1192 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1194 /* this sends an FTP-like "header" to the header callback so that the
1195 current directory can be read very similar to how it is read when
1196 using ordinary FTP. */
1197 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1200 state(conn, SSH_SFTP_CLOSE);
1201 sshc->nextstate = SSH_NO_STATE;
1202 sshc->actualcode = result;
1205 state(conn, SSH_SFTP_NEXT_QUOTE);
1210 * the arguments following the command must be separated from the
1211 * command with a space so we can check for it unconditionally
1213 cp = strchr(cmd, ' ');
1215 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1216 state(conn, SSH_SFTP_CLOSE);
1217 sshc->nextstate = SSH_NO_STATE;
1218 sshc->actualcode = CURLE_QUOTE_ERROR;
1223 * also, every command takes at least one argument so we get that
1224 * first argument right now
1226 result = get_pathname(&cp, &sshc->quote_path1);
1228 if(result == CURLE_OUT_OF_MEMORY)
1229 failf(data, "Out of memory");
1231 failf(data, "Syntax error: Bad first parameter");
1232 state(conn, SSH_SFTP_CLOSE);
1233 sshc->nextstate = SSH_NO_STATE;
1234 sshc->actualcode = result;
1239 * SFTP is a binary protocol, so we don't send text commands
1240 * to the server. Instead, we scan for commands used by
1241 * OpenSSH's sftp program and call the appropriate libssh2
1244 if(curl_strnequal(cmd, "chgrp ", 6) ||
1245 curl_strnequal(cmd, "chmod ", 6) ||
1246 curl_strnequal(cmd, "chown ", 6) ) {
1247 /* attribute change */
1249 /* sshc->quote_path1 contains the mode to set */
1250 /* get the destination */
1251 result = get_pathname(&cp, &sshc->quote_path2);
1253 if(result == CURLE_OUT_OF_MEMORY)
1254 failf(data, "Out of memory");
1256 failf(data, "Syntax error in chgrp/chmod/chown: "
1257 "Bad second parameter");
1258 Curl_safefree(sshc->quote_path1);
1259 state(conn, SSH_SFTP_CLOSE);
1260 sshc->nextstate = SSH_NO_STATE;
1261 sshc->actualcode = result;
1264 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1265 state(conn, SSH_SFTP_QUOTE_STAT);
1268 else if(curl_strnequal(cmd, "ln ", 3) ||
1269 curl_strnequal(cmd, "symlink ", 8)) {
1270 /* symbolic linking */
1271 /* sshc->quote_path1 is the source */
1272 /* get the destination */
1273 result = get_pathname(&cp, &sshc->quote_path2);
1275 if(result == CURLE_OUT_OF_MEMORY)
1276 failf(data, "Out of memory");
1279 "Syntax error in ln/symlink: Bad second parameter");
1280 Curl_safefree(sshc->quote_path1);
1281 state(conn, SSH_SFTP_CLOSE);
1282 sshc->nextstate = SSH_NO_STATE;
1283 sshc->actualcode = result;
1286 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1289 else if(curl_strnequal(cmd, "mkdir ", 6)) {
1291 state(conn, SSH_SFTP_QUOTE_MKDIR);
1294 else if(curl_strnequal(cmd, "rename ", 7)) {
1296 /* first param is the source path */
1297 /* second param is the dest. path */
1298 result = get_pathname(&cp, &sshc->quote_path2);
1300 if(result == CURLE_OUT_OF_MEMORY)
1301 failf(data, "Out of memory");
1303 failf(data, "Syntax error in rename: Bad second parameter");
1304 Curl_safefree(sshc->quote_path1);
1305 state(conn, SSH_SFTP_CLOSE);
1306 sshc->nextstate = SSH_NO_STATE;
1307 sshc->actualcode = result;
1310 state(conn, SSH_SFTP_QUOTE_RENAME);
1313 else if(curl_strnequal(cmd, "rmdir ", 6)) {
1315 state(conn, SSH_SFTP_QUOTE_RMDIR);
1318 else if(curl_strnequal(cmd, "rm ", 3)) {
1319 state(conn, SSH_SFTP_QUOTE_UNLINK);
1323 failf(data, "Unknown SFTP command");
1324 Curl_safefree(sshc->quote_path1);
1325 Curl_safefree(sshc->quote_path2);
1326 state(conn, SSH_SFTP_CLOSE);
1327 sshc->nextstate = SSH_NO_STATE;
1328 sshc->actualcode = CURLE_QUOTE_ERROR;
1332 if(!sshc->quote_item) {
1333 state(conn, SSH_SFTP_TRANS_INIT);
1337 case SSH_SFTP_NEXT_QUOTE:
1338 Curl_safefree(sshc->quote_path1);
1339 Curl_safefree(sshc->quote_path2);
1341 sshc->quote_item = sshc->quote_item->next;
1343 if(sshc->quote_item) {
1344 state(conn, SSH_SFTP_QUOTE);
1347 if(sshc->nextstate != SSH_NO_STATE) {
1348 state(conn, sshc->nextstate);
1349 sshc->nextstate = SSH_NO_STATE;
1352 state(conn, SSH_SFTP_TRANS_INIT);
1357 case SSH_SFTP_QUOTE_STAT:
1359 char *cmd = sshc->quote_item->data;
1360 sshc->acceptfail = FALSE;
1362 /* if a command starts with an asterisk, which a legal SFTP command never
1363 can, the command will be allowed to fail without it causing any
1364 aborts or cancels etc. It will cause libcurl to act as if the command
1365 is successful, whatever the server reponds. */
1369 sshc->acceptfail = TRUE;
1372 if(!curl_strnequal(cmd, "chmod", 5)) {
1373 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1374 * set them both at once, we need to obtain the current ownership
1375 * first. This takes an extra protocol round trip.
1377 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1378 curlx_uztoui(strlen(sshc->quote_path2)),
1380 &sshc->quote_attrs);
1381 if(rc == LIBSSH2_ERROR_EAGAIN) {
1384 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1385 err = sftp_libssh2_last_error(sshc->sftp_session);
1386 Curl_safefree(sshc->quote_path1);
1387 Curl_safefree(sshc->quote_path2);
1388 failf(data, "Attempt to get SFTP stats failed: %s",
1389 sftp_libssh2_strerror(err));
1390 state(conn, SSH_SFTP_CLOSE);
1391 sshc->nextstate = SSH_NO_STATE;
1392 sshc->actualcode = CURLE_QUOTE_ERROR;
1397 /* Now set the new attributes... */
1398 if(curl_strnequal(cmd, "chgrp", 5)) {
1399 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1400 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1401 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1402 !sshc->acceptfail) {
1403 Curl_safefree(sshc->quote_path1);
1404 Curl_safefree(sshc->quote_path2);
1405 failf(data, "Syntax error: chgrp gid not a number");
1406 state(conn, SSH_SFTP_CLOSE);
1407 sshc->nextstate = SSH_NO_STATE;
1408 sshc->actualcode = CURLE_QUOTE_ERROR;
1412 else if(curl_strnequal(cmd, "chmod", 5)) {
1413 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1414 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1415 /* permissions are octal */
1416 if(sshc->quote_attrs.permissions == 0 &&
1417 !ISDIGIT(sshc->quote_path1[0])) {
1418 Curl_safefree(sshc->quote_path1);
1419 Curl_safefree(sshc->quote_path2);
1420 failf(data, "Syntax error: chmod permissions not a number");
1421 state(conn, SSH_SFTP_CLOSE);
1422 sshc->nextstate = SSH_NO_STATE;
1423 sshc->actualcode = CURLE_QUOTE_ERROR;
1427 else if(curl_strnequal(cmd, "chown", 5)) {
1428 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1429 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1430 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1431 !sshc->acceptfail) {
1432 Curl_safefree(sshc->quote_path1);
1433 Curl_safefree(sshc->quote_path2);
1434 failf(data, "Syntax error: chown uid not a number");
1435 state(conn, SSH_SFTP_CLOSE);
1436 sshc->nextstate = SSH_NO_STATE;
1437 sshc->actualcode = CURLE_QUOTE_ERROR;
1442 /* Now send the completed structure... */
1443 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1447 case SSH_SFTP_QUOTE_SETSTAT:
1448 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1449 curlx_uztoui(strlen(sshc->quote_path2)),
1450 LIBSSH2_SFTP_SETSTAT,
1451 &sshc->quote_attrs);
1452 if(rc == LIBSSH2_ERROR_EAGAIN) {
1455 else if(rc != 0 && !sshc->acceptfail) {
1456 err = sftp_libssh2_last_error(sshc->sftp_session);
1457 Curl_safefree(sshc->quote_path1);
1458 Curl_safefree(sshc->quote_path2);
1459 failf(data, "Attempt to set SFTP stats failed: %s",
1460 sftp_libssh2_strerror(err));
1461 state(conn, SSH_SFTP_CLOSE);
1462 sshc->nextstate = SSH_NO_STATE;
1463 sshc->actualcode = CURLE_QUOTE_ERROR;
1466 state(conn, SSH_SFTP_NEXT_QUOTE);
1469 case SSH_SFTP_QUOTE_SYMLINK:
1470 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1471 curlx_uztoui(strlen(sshc->quote_path1)),
1473 curlx_uztoui(strlen(sshc->quote_path2)),
1474 LIBSSH2_SFTP_SYMLINK);
1475 if(rc == LIBSSH2_ERROR_EAGAIN) {
1478 else if(rc != 0 && !sshc->acceptfail) {
1479 err = sftp_libssh2_last_error(sshc->sftp_session);
1480 Curl_safefree(sshc->quote_path1);
1481 Curl_safefree(sshc->quote_path2);
1482 failf(data, "symlink command failed: %s",
1483 sftp_libssh2_strerror(err));
1484 state(conn, SSH_SFTP_CLOSE);
1485 sshc->nextstate = SSH_NO_STATE;
1486 sshc->actualcode = CURLE_QUOTE_ERROR;
1489 state(conn, SSH_SFTP_NEXT_QUOTE);
1492 case SSH_SFTP_QUOTE_MKDIR:
1493 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1494 curlx_uztoui(strlen(sshc->quote_path1)),
1495 data->set.new_directory_perms);
1496 if(rc == LIBSSH2_ERROR_EAGAIN) {
1499 else if(rc != 0 && !sshc->acceptfail) {
1500 err = sftp_libssh2_last_error(sshc->sftp_session);
1501 Curl_safefree(sshc->quote_path1);
1502 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1503 state(conn, SSH_SFTP_CLOSE);
1504 sshc->nextstate = SSH_NO_STATE;
1505 sshc->actualcode = CURLE_QUOTE_ERROR;
1508 state(conn, SSH_SFTP_NEXT_QUOTE);
1511 case SSH_SFTP_QUOTE_RENAME:
1512 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1513 curlx_uztoui(strlen(sshc->quote_path1)),
1515 curlx_uztoui(strlen(sshc->quote_path2)),
1516 LIBSSH2_SFTP_RENAME_OVERWRITE |
1517 LIBSSH2_SFTP_RENAME_ATOMIC |
1518 LIBSSH2_SFTP_RENAME_NATIVE);
1520 if(rc == LIBSSH2_ERROR_EAGAIN) {
1523 else if(rc != 0 && !sshc->acceptfail) {
1524 err = sftp_libssh2_last_error(sshc->sftp_session);
1525 Curl_safefree(sshc->quote_path1);
1526 Curl_safefree(sshc->quote_path2);
1527 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1528 state(conn, SSH_SFTP_CLOSE);
1529 sshc->nextstate = SSH_NO_STATE;
1530 sshc->actualcode = CURLE_QUOTE_ERROR;
1533 state(conn, SSH_SFTP_NEXT_QUOTE);
1536 case SSH_SFTP_QUOTE_RMDIR:
1537 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1538 curlx_uztoui(strlen(sshc->quote_path1)));
1539 if(rc == LIBSSH2_ERROR_EAGAIN) {
1542 else if(rc != 0 && !sshc->acceptfail) {
1543 err = sftp_libssh2_last_error(sshc->sftp_session);
1544 Curl_safefree(sshc->quote_path1);
1545 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1546 state(conn, SSH_SFTP_CLOSE);
1547 sshc->nextstate = SSH_NO_STATE;
1548 sshc->actualcode = CURLE_QUOTE_ERROR;
1551 state(conn, SSH_SFTP_NEXT_QUOTE);
1554 case SSH_SFTP_QUOTE_UNLINK:
1555 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1556 curlx_uztoui(strlen(sshc->quote_path1)));
1557 if(rc == LIBSSH2_ERROR_EAGAIN) {
1560 else if(rc != 0 && !sshc->acceptfail) {
1561 err = sftp_libssh2_last_error(sshc->sftp_session);
1562 Curl_safefree(sshc->quote_path1);
1563 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1564 state(conn, SSH_SFTP_CLOSE);
1565 sshc->nextstate = SSH_NO_STATE;
1566 sshc->actualcode = CURLE_QUOTE_ERROR;
1569 state(conn, SSH_SFTP_NEXT_QUOTE);
1572 case SSH_SFTP_TRANS_INIT:
1573 if(data->set.upload)
1574 state(conn, SSH_SFTP_UPLOAD_INIT);
1576 if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1577 state(conn, SSH_SFTP_READDIR_INIT);
1579 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1583 case SSH_SFTP_UPLOAD_INIT:
1585 unsigned long flags;
1587 * NOTE!!! libssh2 requires that the destination path is a full path
1588 * that includes the destination file and name OR ends in a "/"
1589 * If this is not done the destination file will be named the
1590 * same name as the last directory in the path.
1593 if(data->state.resume_from != 0) {
1594 LIBSSH2_SFTP_ATTRIBUTES attrs;
1595 if(data->state.resume_from < 0) {
1596 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1597 curlx_uztoui(strlen(sftp_scp->path)),
1598 LIBSSH2_SFTP_STAT, &attrs);
1599 if(rc == LIBSSH2_ERROR_EAGAIN) {
1603 data->state.resume_from = 0;
1606 curl_off_t size = attrs.filesize;
1608 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
1609 return CURLE_BAD_DOWNLOAD_RESUME;
1611 data->state.resume_from = attrs.filesize;
1616 if(data->set.ftp_append)
1617 /* Try to open for append, but create if nonexisting */
1618 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1619 else if(data->state.resume_from > 0)
1620 /* If we have restart position then open for append */
1621 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1623 /* Clear file before writing (normal behaviour) */
1624 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1627 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1628 curlx_uztoui(strlen(sftp_scp->path)),
1629 flags, data->set.new_file_perms,
1630 LIBSSH2_SFTP_OPENFILE);
1632 if(!sshc->sftp_handle) {
1633 rc = libssh2_session_last_errno(sshc->ssh_session);
1635 if(LIBSSH2_ERROR_EAGAIN == rc)
1638 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1639 /* only when there was an SFTP protocol error can we extract
1641 err = sftp_libssh2_last_error(sshc->sftp_session);
1643 err = -1; /* not an sftp error at all */
1645 if(sshc->secondCreateDirs) {
1646 state(conn, SSH_SFTP_CLOSE);
1647 sshc->actualcode = err>= LIBSSH2_FX_OK?
1648 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1649 failf(data, "Creating the dir/file failed: %s",
1650 sftp_libssh2_strerror(err));
1653 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1654 (err == LIBSSH2_FX_FAILURE) ||
1655 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1656 (data->set.ftp_create_missing_dirs &&
1657 (strlen(sftp_scp->path) > 1))) {
1658 /* try to create the path remotely */
1659 sshc->secondCreateDirs = 1;
1660 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1663 state(conn, SSH_SFTP_CLOSE);
1664 sshc->actualcode = err>= LIBSSH2_FX_OK?
1665 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1666 if(!sshc->actualcode) {
1667 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1668 zero even though libssh2_sftp_open() failed previously! We need
1669 to work around that! */
1670 sshc->actualcode = CURLE_SSH;
1673 failf(data, "Upload failed: %s (%d/%d)",
1674 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1680 /* If we have restart point then we need to seek to the correct
1682 if(data->state.resume_from > 0) {
1683 /* Let's read off the proper amount of bytes from the input. */
1684 if(conn->seek_func) {
1685 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1689 if(seekerr != CURL_SEEKFUNC_OK) {
1691 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1692 failf(data, "Could not seek stream");
1693 return CURLE_FTP_COULDNT_USE_REST;
1695 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1697 curl_off_t passed=0;
1699 size_t readthisamountnow =
1700 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1701 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1703 size_t actuallyread =
1704 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1707 passed += actuallyread;
1708 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1709 /* this checks for greater-than only to make sure that the
1710 CURL_READFUNC_ABORT return code still aborts */
1711 failf(data, "Failed to read data");
1712 return CURLE_FTP_COULDNT_USE_REST;
1714 } while(passed < data->state.resume_from);
1718 /* now, decrease the size of the read */
1719 if(data->set.infilesize > 0) {
1720 data->set.infilesize -= data->state.resume_from;
1721 data->req.size = data->set.infilesize;
1722 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1725 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1727 if(data->set.infilesize > 0) {
1728 data->req.size = data->set.infilesize;
1729 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1732 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1734 /* not set by Curl_setup_transfer to preserve keepon bits */
1735 conn->sockfd = conn->writesockfd;
1738 state(conn, SSH_SFTP_CLOSE);
1739 sshc->actualcode = result;
1742 /* store this original bitmask setup to use later on if we can't
1743 figure out a "real" bitmask */
1744 sshc->orig_waitfor = data->req.keepon;
1746 /* we want to use the _sending_ function even when the socket turns
1747 out readable as the underlying libssh2 sftp send function will deal
1748 with both accordingly */
1749 conn->cselect_bits = CURL_CSELECT_OUT;
1751 /* since we don't really wait for anything at this point, we want the
1752 state machine to move on as soon as possible so we set a very short
1754 Curl_expire(data, 1);
1756 state(conn, SSH_STOP);
1761 case SSH_SFTP_CREATE_DIRS_INIT:
1762 if(strlen(sftp_scp->path) > 1) {
1763 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1764 state(conn, SSH_SFTP_CREATE_DIRS);
1767 state(conn, SSH_SFTP_UPLOAD_INIT);
1771 case SSH_SFTP_CREATE_DIRS:
1772 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1773 *sshc->slash_pos = 0;
1775 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1776 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1780 state(conn, SSH_SFTP_UPLOAD_INIT);
1784 case SSH_SFTP_CREATE_DIRS_MKDIR:
1785 /* 'mode' - parameter is preliminary - default to 0644 */
1786 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1787 curlx_uztoui(strlen(sftp_scp->path)),
1788 data->set.new_directory_perms);
1789 if(rc == LIBSSH2_ERROR_EAGAIN) {
1792 *sshc->slash_pos = '/';
1796 * Abort if failure wasn't that the dir already exists or the
1797 * permission was denied (creation might succeed further down the
1798 * path) - retry on unspecific FAILURE also
1800 err = sftp_libssh2_last_error(sshc->sftp_session);
1801 if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1802 (err != LIBSSH2_FX_FAILURE) &&
1803 (err != LIBSSH2_FX_PERMISSION_DENIED)) {
1804 result = sftp_libssh2_error_to_CURLE(err);
1805 state(conn, SSH_SFTP_CLOSE);
1806 sshc->actualcode = result?result:CURLE_SSH;
1810 state(conn, SSH_SFTP_CREATE_DIRS);
1813 case SSH_SFTP_READDIR_INIT:
1814 Curl_pgrsSetDownloadSize(data, -1);
1815 if(data->set.opt_no_body) {
1816 state(conn, SSH_STOP);
1821 * This is a directory that we are trying to get, so produce a directory
1824 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1827 strlen(sftp_scp->path)),
1828 0, 0, LIBSSH2_SFTP_OPENDIR);
1829 if(!sshc->sftp_handle) {
1830 if(libssh2_session_last_errno(sshc->ssh_session) ==
1831 LIBSSH2_ERROR_EAGAIN) {
1832 rc = LIBSSH2_ERROR_EAGAIN;
1836 err = sftp_libssh2_last_error(sshc->sftp_session);
1837 failf(data, "Could not open directory for reading: %s",
1838 sftp_libssh2_strerror(err));
1839 state(conn, SSH_SFTP_CLOSE);
1840 result = sftp_libssh2_error_to_CURLE(err);
1841 sshc->actualcode = result?result:CURLE_SSH;
1845 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1846 state(conn, SSH_SFTP_CLOSE);
1847 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1850 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1851 Curl_safefree(sshc->readdir_filename);
1852 state(conn, SSH_SFTP_CLOSE);
1853 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1856 state(conn, SSH_SFTP_READDIR);
1859 case SSH_SFTP_READDIR:
1860 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1861 sshc->readdir_filename,
1863 sshc->readdir_longentry,
1865 &sshc->readdir_attrs);
1866 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1867 rc = LIBSSH2_ERROR_EAGAIN;
1870 if(sshc->readdir_len > 0) {
1871 sshc->readdir_filename[sshc->readdir_len] = '\0';
1873 if(data->set.ftp_list_only) {
1876 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1877 if(tmpLine == NULL) {
1878 state(conn, SSH_SFTP_CLOSE);
1879 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1882 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1883 tmpLine, sshc->readdir_len+1);
1884 Curl_safefree(tmpLine);
1887 state(conn, SSH_STOP);
1890 /* since this counts what we send to the client, we include the
1891 newline in this counter */
1892 data->req.bytecount += sshc->readdir_len+1;
1894 /* output debug output if that is requested */
1895 if(data->set.verbose) {
1896 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1897 sshc->readdir_len, conn);
1901 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1902 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1903 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1904 if(!sshc->readdir_line) {
1905 Curl_safefree(sshc->readdir_filename);
1906 Curl_safefree(sshc->readdir_longentry);
1907 state(conn, SSH_SFTP_CLOSE);
1908 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1912 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1913 sshc->readdir_currLen);
1914 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1915 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1916 LIBSSH2_SFTP_S_IFLNK)) {
1917 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1918 if(sshc->readdir_linkPath == NULL) {
1919 Curl_safefree(sshc->readdir_filename);
1920 Curl_safefree(sshc->readdir_longentry);
1921 state(conn, SSH_SFTP_CLOSE);
1922 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1926 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1927 sshc->readdir_filename);
1928 state(conn, SSH_SFTP_READDIR_LINK);
1931 state(conn, SSH_SFTP_READDIR_BOTTOM);
1935 else if(sshc->readdir_len == 0) {
1936 Curl_safefree(sshc->readdir_filename);
1937 Curl_safefree(sshc->readdir_longentry);
1938 state(conn, SSH_SFTP_READDIR_DONE);
1941 else if(sshc->readdir_len <= 0) {
1942 err = sftp_libssh2_last_error(sshc->sftp_session);
1943 result = sftp_libssh2_error_to_CURLE(err);
1944 sshc->actualcode = result?result:CURLE_SSH;
1945 failf(data, "Could not open remote file for reading: %s :: %d",
1946 sftp_libssh2_strerror(err),
1947 libssh2_session_last_errno(sshc->ssh_session));
1948 Curl_safefree(sshc->readdir_filename);
1949 Curl_safefree(sshc->readdir_longentry);
1950 state(conn, SSH_SFTP_CLOSE);
1955 case SSH_SFTP_READDIR_LINK:
1957 libssh2_sftp_symlink_ex(sshc->sftp_session,
1958 sshc->readdir_linkPath,
1959 curlx_uztoui(strlen(sshc->readdir_linkPath)),
1960 sshc->readdir_filename,
1961 PATH_MAX, LIBSSH2_SFTP_READLINK);
1962 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1963 rc = LIBSSH2_ERROR_EAGAIN;
1966 Curl_safefree(sshc->readdir_linkPath);
1968 /* get room for the filename and extra output */
1969 sshc->readdir_totalLen += 4 + sshc->readdir_len;
1970 new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
1971 if(!new_readdir_line) {
1972 Curl_safefree(sshc->readdir_line);
1973 Curl_safefree(sshc->readdir_filename);
1974 Curl_safefree(sshc->readdir_longentry);
1975 state(conn, SSH_SFTP_CLOSE);
1976 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1979 sshc->readdir_line = new_readdir_line;
1981 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1982 sshc->readdir_currLen,
1983 sshc->readdir_totalLen -
1984 sshc->readdir_currLen,
1986 sshc->readdir_filename);
1988 state(conn, SSH_SFTP_READDIR_BOTTOM);
1991 case SSH_SFTP_READDIR_BOTTOM:
1992 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1993 sshc->readdir_currLen,
1994 sshc->readdir_totalLen -
1995 sshc->readdir_currLen, "\n");
1996 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1998 sshc->readdir_currLen);
2000 if(result == CURLE_OK) {
2002 /* output debug output if that is requested */
2003 if(data->set.verbose) {
2004 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
2005 sshc->readdir_currLen, conn);
2007 data->req.bytecount += sshc->readdir_currLen;
2009 Curl_safefree(sshc->readdir_line);
2011 state(conn, SSH_STOP);
2014 state(conn, SSH_SFTP_READDIR);
2017 case SSH_SFTP_READDIR_DONE:
2018 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
2019 LIBSSH2_ERROR_EAGAIN) {
2020 rc = LIBSSH2_ERROR_EAGAIN;
2023 sshc->sftp_handle = NULL;
2024 Curl_safefree(sshc->readdir_filename);
2025 Curl_safefree(sshc->readdir_longentry);
2027 /* no data to transfer */
2028 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2029 state(conn, SSH_STOP);
2032 case SSH_SFTP_DOWNLOAD_INIT:
2034 * Work on getting the specified file
2037 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
2038 curlx_uztoui(strlen(sftp_scp->path)),
2039 LIBSSH2_FXF_READ, data->set.new_file_perms,
2040 LIBSSH2_SFTP_OPENFILE);
2041 if(!sshc->sftp_handle) {
2042 if(libssh2_session_last_errno(sshc->ssh_session) ==
2043 LIBSSH2_ERROR_EAGAIN) {
2044 rc = LIBSSH2_ERROR_EAGAIN;
2048 err = sftp_libssh2_last_error(sshc->sftp_session);
2049 failf(data, "Could not open remote file for reading: %s",
2050 sftp_libssh2_strerror(err));
2051 state(conn, SSH_SFTP_CLOSE);
2052 result = sftp_libssh2_error_to_CURLE(err);
2053 sshc->actualcode = result?result:CURLE_SSH;
2057 state(conn, SSH_SFTP_DOWNLOAD_STAT);
2060 case SSH_SFTP_DOWNLOAD_STAT:
2062 LIBSSH2_SFTP_ATTRIBUTES attrs;
2064 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
2065 curlx_uztoui(strlen(sftp_scp->path)),
2066 LIBSSH2_SFTP_STAT, &attrs);
2067 if(rc == LIBSSH2_ERROR_EAGAIN) {
2072 * libssh2_sftp_open() didn't return an error, so maybe the server
2073 * just doesn't support stat()
2075 data->req.size = -1;
2076 data->req.maxdownload = -1;
2077 Curl_pgrsSetDownloadSize(data, -1);
2080 curl_off_t size = attrs.filesize;
2083 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
2084 return CURLE_BAD_DOWNLOAD_RESUME;
2086 if(conn->data->state.use_range) {
2087 curl_off_t from, to;
2091 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2092 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2094 to=curlx_strtoofft(ptr, &ptr2, 0);
2095 if((ptr == ptr2) /* no "to" value given */
2100 /* from is relative to end of file */
2104 failf(data, "Offset (%"
2105 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2106 CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
2107 return CURLE_BAD_DOWNLOAD_RESUME;
2114 size = to - from + 1;
2117 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2119 data->req.size = size;
2120 data->req.maxdownload = size;
2121 Curl_pgrsSetDownloadSize(data, size);
2124 /* We can resume if we can seek to the resume position */
2125 if(data->state.resume_from) {
2126 if(data->state.resume_from < 0) {
2127 /* We're supposed to download the last abs(from) bytes */
2128 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2129 failf(data, "Offset (%"
2130 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2131 CURL_FORMAT_CURL_OFF_T ")",
2132 data->state.resume_from, attrs.filesize);
2133 return CURLE_BAD_DOWNLOAD_RESUME;
2135 /* download from where? */
2136 data->state.resume_from += attrs.filesize;
2139 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2140 failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
2141 ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
2142 data->state.resume_from, attrs.filesize);
2143 return CURLE_BAD_DOWNLOAD_RESUME;
2146 /* Does a completed file need to be seeked and started or closed ? */
2147 /* Now store the number of bytes we are expected to download */
2148 data->req.size = attrs.filesize - data->state.resume_from;
2149 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2150 Curl_pgrsSetDownloadSize(data,
2151 attrs.filesize - data->state.resume_from);
2152 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2156 if(data->set.opt_no_body)
2157 state(conn, SSH_SFTP_CLOSE);
2159 /* Setup the actual download */
2160 if(data->req.size == 0) {
2161 /* no data to transfer */
2162 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2163 infof(data, "File already completely downloaded\n");
2164 state(conn, SSH_STOP);
2168 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2169 FALSE, NULL, -1, NULL);
2171 /* not set by Curl_setup_transfer to preserve keepon bits */
2172 conn->writesockfd = conn->sockfd;
2174 /* we want to use the _receiving_ function even when the socket turns
2175 out writableable as the underlying libssh2 recv function will deal
2176 with both accordingly */
2177 conn->cselect_bits = CURL_CSELECT_IN;
2180 /* this should never occur; the close state should be entered
2181 at the time the error occurs */
2182 state(conn, SSH_SFTP_CLOSE);
2183 sshc->actualcode = result;
2186 state(conn, SSH_STOP);
2190 case SSH_SFTP_CLOSE:
2191 if(sshc->sftp_handle) {
2192 rc = libssh2_sftp_close(sshc->sftp_handle);
2193 if(rc == LIBSSH2_ERROR_EAGAIN) {
2197 infof(data, "Failed to close libssh2 file\n");
2199 sshc->sftp_handle = NULL;
2202 Curl_safefree(sftp_scp->path);
2204 DEBUGF(infof(data, "SFTP DONE done\n"));
2206 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2207 After nextstate is executed,the control should come back to
2208 SSH_SFTP_CLOSE to pass the correct result back */
2209 if(sshc->nextstate != SSH_NO_STATE) {
2210 state(conn, sshc->nextstate);
2211 sshc->nextstate = SSH_SFTP_CLOSE;
2214 state(conn, SSH_STOP);
2215 result = sshc->actualcode;
2219 case SSH_SFTP_SHUTDOWN:
2220 /* during times we get here due to a broken transfer and then the
2221 sftp_handle might not have been taken down so make sure that is done
2222 before we proceed */
2224 if(sshc->sftp_handle) {
2225 rc = libssh2_sftp_close(sshc->sftp_handle);
2226 if(rc == LIBSSH2_ERROR_EAGAIN) {
2230 infof(data, "Failed to close libssh2 file\n");
2232 sshc->sftp_handle = NULL;
2234 if(sshc->sftp_session) {
2235 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2236 if(rc == LIBSSH2_ERROR_EAGAIN) {
2240 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2242 sshc->sftp_session = NULL;
2245 Curl_safefree(sshc->homedir);
2246 conn->data->state.most_recent_ftp_entrypath = NULL;
2248 state(conn, SSH_SESSION_DISCONNECT);
2251 case SSH_SCP_TRANS_INIT:
2252 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2254 sshc->actualcode = result;
2255 state(conn, SSH_STOP);
2259 if(data->set.upload) {
2260 if(data->set.infilesize < 0) {
2261 failf(data, "SCP requires a known file size for upload");
2262 sshc->actualcode = CURLE_UPLOAD_FAILED;
2263 state(conn, SSH_SCP_CHANNEL_FREE);
2266 state(conn, SSH_SCP_UPLOAD_INIT);
2269 state(conn, SSH_SCP_DOWNLOAD_INIT);
2273 case SSH_SCP_UPLOAD_INIT:
2275 * libssh2 requires that the destination path is a full path that
2276 * includes the destination file and name OR ends in a "/" . If this is
2277 * not done the destination file will be named the same name as the last
2278 * directory in the path.
2281 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2282 data->set.infilesize);
2283 if(!sshc->ssh_channel) {
2284 if(libssh2_session_last_errno(sshc->ssh_session) ==
2285 LIBSSH2_ERROR_EAGAIN) {
2286 rc = LIBSSH2_ERROR_EAGAIN;
2293 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2294 &err_msg, NULL, 0));
2295 failf(conn->data, "%s", err_msg);
2296 state(conn, SSH_SCP_CHANNEL_FREE);
2297 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2303 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2306 /* not set by Curl_setup_transfer to preserve keepon bits */
2307 conn->sockfd = conn->writesockfd;
2310 state(conn, SSH_SCP_CHANNEL_FREE);
2311 sshc->actualcode = result;
2314 /* store this original bitmask setup to use later on if we can't
2315 figure out a "real" bitmask */
2316 sshc->orig_waitfor = data->req.keepon;
2318 /* we want to use the _sending_ function even when the socket turns
2319 out readable as the underlying libssh2 scp send function will deal
2320 with both accordingly */
2321 conn->cselect_bits = CURL_CSELECT_OUT;
2323 state(conn, SSH_STOP);
2327 case SSH_SCP_DOWNLOAD_INIT:
2330 * We must check the remote file; if it is a directory no values will
2334 curl_off_t bytecount;
2336 /* clear the struct scp recv will fill in */
2337 memset(&sb, 0, sizeof(struct stat));
2339 /* get a fresh new channel from the ssh layer */
2340 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2341 sftp_scp->path, &sb);
2342 if(!sshc->ssh_channel) {
2343 if(libssh2_session_last_errno(sshc->ssh_session) ==
2344 LIBSSH2_ERROR_EAGAIN) {
2345 rc = LIBSSH2_ERROR_EAGAIN;
2352 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2353 &err_msg, NULL, 0));
2354 failf(conn->data, "%s", err_msg);
2355 state(conn, SSH_SCP_CHANNEL_FREE);
2356 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2362 bytecount = (curl_off_t)sb.st_size;
2363 data->req.maxdownload = (curl_off_t)sb.st_size;
2364 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2366 /* not set by Curl_setup_transfer to preserve keepon bits */
2367 conn->writesockfd = conn->sockfd;
2369 /* we want to use the _receiving_ function even when the socket turns
2370 out writableable as the underlying libssh2 recv function will deal
2371 with both accordingly */
2372 conn->cselect_bits = CURL_CSELECT_IN;
2375 state(conn, SSH_SCP_CHANNEL_FREE);
2376 sshc->actualcode = result;
2379 state(conn, SSH_STOP);
2384 if(data->set.upload)
2385 state(conn, SSH_SCP_SEND_EOF);
2387 state(conn, SSH_SCP_CHANNEL_FREE);
2390 case SSH_SCP_SEND_EOF:
2391 if(sshc->ssh_channel) {
2392 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2393 if(rc == LIBSSH2_ERROR_EAGAIN) {
2397 infof(data, "Failed to send libssh2 channel EOF\n");
2400 state(conn, SSH_SCP_WAIT_EOF);
2403 case SSH_SCP_WAIT_EOF:
2404 if(sshc->ssh_channel) {
2405 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2406 if(rc == LIBSSH2_ERROR_EAGAIN) {
2410 infof(data, "Failed to get channel EOF: %d\n", rc);
2413 state(conn, SSH_SCP_WAIT_CLOSE);
2416 case SSH_SCP_WAIT_CLOSE:
2417 if(sshc->ssh_channel) {
2418 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2419 if(rc == LIBSSH2_ERROR_EAGAIN) {
2423 infof(data, "Channel failed to close: %d\n", rc);
2426 state(conn, SSH_SCP_CHANNEL_FREE);
2429 case SSH_SCP_CHANNEL_FREE:
2430 if(sshc->ssh_channel) {
2431 rc = libssh2_channel_free(sshc->ssh_channel);
2432 if(rc == LIBSSH2_ERROR_EAGAIN) {
2436 infof(data, "Failed to free libssh2 scp subsystem\n");
2438 sshc->ssh_channel = NULL;
2440 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2442 state(conn, SSH_SESSION_DISCONNECT);
2444 state(conn, SSH_STOP);
2445 result = sshc->actualcode;
2448 case SSH_SESSION_DISCONNECT:
2449 /* during weird times when we've been prematurely aborted, the channel
2450 is still alive when we reach this state and we MUST kill the channel
2452 if(sshc->ssh_channel) {
2453 rc = libssh2_channel_free(sshc->ssh_channel);
2454 if(rc == LIBSSH2_ERROR_EAGAIN) {
2458 infof(data, "Failed to free libssh2 scp subsystem\n");
2460 sshc->ssh_channel = NULL;
2463 if(sshc->ssh_session) {
2464 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2465 if(rc == LIBSSH2_ERROR_EAGAIN) {
2469 infof(data, "Failed to disconnect libssh2 session\n");
2473 Curl_safefree(sshc->homedir);
2474 conn->data->state.most_recent_ftp_entrypath = NULL;
2476 state(conn, SSH_SESSION_FREE);
2479 case SSH_SESSION_FREE:
2480 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2482 libssh2_knownhost_free(sshc->kh);
2487 #ifdef HAVE_LIBSSH2_AGENT_API
2488 if(sshc->ssh_agent) {
2489 rc = libssh2_agent_disconnect(sshc->ssh_agent);
2490 if(rc == LIBSSH2_ERROR_EAGAIN) {
2494 infof(data, "Failed to disconnect from libssh2 agent\n");
2496 libssh2_agent_free (sshc->ssh_agent);
2497 sshc->ssh_agent = NULL;
2499 /* NB: there is no need to free identities, they are part of internal
2501 sshc->sshagent_identity = NULL;
2502 sshc->sshagent_prev_identity = NULL;
2506 if(sshc->ssh_session) {
2507 rc = libssh2_session_free(sshc->ssh_session);
2508 if(rc == LIBSSH2_ERROR_EAGAIN) {
2512 infof(data, "Failed to free libssh2 session\n");
2514 sshc->ssh_session = NULL;
2517 /* worst-case scenario cleanup */
2519 DEBUGASSERT(sshc->ssh_session == NULL);
2520 DEBUGASSERT(sshc->ssh_channel == NULL);
2521 DEBUGASSERT(sshc->sftp_session == NULL);
2522 DEBUGASSERT(sshc->sftp_handle == NULL);
2523 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2524 DEBUGASSERT(sshc->kh == NULL);
2526 #ifdef HAVE_LIBSSH2_AGENT_API
2527 DEBUGASSERT(sshc->ssh_agent == NULL);
2530 Curl_safefree(sshc->rsa_pub);
2531 Curl_safefree(sshc->rsa);
2533 Curl_safefree(sshc->quote_path1);
2534 Curl_safefree(sshc->quote_path2);
2536 Curl_safefree(sshc->homedir);
2538 Curl_safefree(sshc->readdir_filename);
2539 Curl_safefree(sshc->readdir_longentry);
2540 Curl_safefree(sshc->readdir_line);
2541 Curl_safefree(sshc->readdir_linkPath);
2543 /* the code we are about to return */
2544 result = sshc->actualcode;
2546 memset(sshc, 0, sizeof(struct ssh_conn));
2548 conn->bits.close = TRUE;
2549 sshc->state = SSH_SESSION_FREE; /* current */
2550 sshc->nextstate = SSH_NO_STATE;
2551 state(conn, SSH_STOP);
2555 /* fallthrough, just stop! */
2557 /* internal error */
2558 sshc->nextstate = SSH_NO_STATE;
2559 state(conn, SSH_STOP);
2563 } while(!rc && (sshc->state != SSH_STOP));
2565 if(rc == LIBSSH2_ERROR_EAGAIN) {
2566 /* we would block, we need to wait for the socket to be ready (in the
2567 right direction too)! */
2574 /* called by the multi interface to figure out what socket(s) to wait for and
2575 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2576 static int ssh_perform_getsock(const struct connectdata *conn,
2577 curl_socket_t *sock, /* points to numsocks
2578 number of sockets */
2581 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2582 int bitmap = GETSOCK_BLANK;
2585 sock[0] = conn->sock[FIRSTSOCKET];
2587 if(conn->waitfor & KEEP_RECV)
2588 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2590 if(conn->waitfor & KEEP_SEND)
2591 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2595 /* if we don't know the direction we can use the generic *_getsock()
2596 function even for the protocol_connect and doing states */
2597 return Curl_single_getsock(conn, sock, numsocks);
2601 /* Generic function called by the multi interface to figure out what socket(s)
2602 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2603 static int ssh_getsock(struct connectdata *conn,
2604 curl_socket_t *sock, /* points to numsocks number
2608 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2612 /* if we don't know any direction we can just play along as we used to and
2613 not provide any sensible info */
2614 return GETSOCK_BLANK;
2616 /* if we know the direction we can use the generic *_getsock() function even
2617 for the protocol_connect and doing states */
2618 return ssh_perform_getsock(conn, sock, numsocks);
2622 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2624 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2625 * function is used to figure out in what direction and stores this info so
2626 * that the multi interface can take advantage of it. Make sure to call this
2627 * function in all cases so that when it _doesn't_ return EAGAIN we can
2628 * restore the default wait bits.
2630 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2632 struct ssh_conn *sshc = &conn->proto.sshc;
2634 if(block && (dir = libssh2_session_block_directions(sshc->ssh_session))) {
2635 /* translate the libssh2 define bits into our own bit defines */
2636 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2637 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2640 /* It didn't block or libssh2 didn't reveal in which direction, put back
2642 conn->waitfor = sshc->orig_waitfor;
2645 /* no libssh2 directional support so we simply don't know */
2646 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2649 /* called repeatedly until done from multi.c */
2650 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2652 struct ssh_conn *sshc = &conn->proto.sshc;
2653 CURLcode result = CURLE_OK;
2654 bool block; /* we store the status and use that to provide a ssh_getsock()
2657 result = ssh_statemach_act(conn, &block);
2658 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2659 ssh_block2waitfor(conn, block);
2664 static CURLcode ssh_block_statemach(struct connectdata *conn,
2667 struct ssh_conn *sshc = &conn->proto.sshc;
2668 CURLcode result = CURLE_OK;
2669 struct SessionHandle *data = conn->data;
2671 while((sshc->state != SSH_STOP) && !result) {
2675 result = ssh_statemach_act(conn, &block);
2679 if(Curl_pgrsUpdate(conn))
2680 return CURLE_ABORTED_BY_CALLBACK;
2682 struct timeval now = Curl_tvnow();
2683 result = Curl_speedcheck(data, now);
2688 left = Curl_timeleft(data, NULL, duringconnect);
2690 failf(data, "Operation timed out");
2691 return CURLE_OPERATION_TIMEDOUT;
2694 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2695 if((CURLE_OK == result) && block) {
2696 int dir = libssh2_session_block_directions(sshc->ssh_session);
2697 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2698 curl_socket_t fd_read = CURL_SOCKET_BAD;
2699 curl_socket_t fd_write = CURL_SOCKET_BAD;
2700 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2702 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2704 /* wait for the socket to become ready */
2705 Curl_socket_ready(fd_read, fd_write,
2706 left>1000?1000:left); /* ignore result */
2716 * SSH setup and connection
2718 static CURLcode ssh_setup_connection(struct connectdata *conn)
2720 struct SSHPROTO *ssh;
2722 conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
2724 return CURLE_OUT_OF_MEMORY;
2729 static Curl_recv scp_recv, sftp_recv;
2730 static Curl_send scp_send, sftp_send;
2733 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2734 * do protocol-specific actions at connect-time.
2736 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2738 #ifdef CURL_LIBSSH2_DEBUG
2741 struct ssh_conn *ssh;
2743 struct SessionHandle *data = conn->data;
2745 /* initialize per-handle data if not already */
2746 if(!data->req.protop)
2747 ssh_setup_connection(conn);
2749 /* We default to persistent connections. We set this already in this connect
2750 function to make the re-use checks properly be able to check this bit. */
2751 conn->bits.close = FALSE;
2753 if(conn->handler->protocol & CURLPROTO_SCP) {
2754 conn->recv[FIRSTSOCKET] = scp_recv;
2755 conn->send[FIRSTSOCKET] = scp_send;
2758 conn->recv[FIRSTSOCKET] = sftp_recv;
2759 conn->send[FIRSTSOCKET] = sftp_send;
2761 ssh = &conn->proto.sshc;
2763 #ifdef CURL_LIBSSH2_DEBUG
2765 infof(data, "User: %s\n", conn->user);
2768 infof(data, "Password: %s\n", conn->passwd);
2770 sock = conn->sock[FIRSTSOCKET];
2771 #endif /* CURL_LIBSSH2_DEBUG */
2773 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2775 my_libssh2_realloc, conn);
2776 if(ssh->ssh_session == NULL) {
2777 failf(data, "Failure initialising ssh session");
2778 return CURLE_FAILED_INIT;
2781 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2782 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2784 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2786 /* eeek. TODO: free the ssh_session! */
2787 return CURLE_FAILED_INIT;
2790 /* read all known hosts from there */
2791 rc = libssh2_knownhost_readfile(ssh->kh,
2792 data->set.str[STRING_SSH_KNOWNHOSTS],
2793 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2795 infof(data, "Failed to read known hosts from %s\n",
2796 data->set.str[STRING_SSH_KNOWNHOSTS]);
2798 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2800 #ifdef CURL_LIBSSH2_DEBUG
2801 libssh2_trace(ssh->ssh_session, ~0);
2802 infof(data, "SSH socket: %d\n", (int)sock);
2803 #endif /* CURL_LIBSSH2_DEBUG */
2805 state(conn, SSH_INIT);
2807 result = ssh_multi_statemach(conn, done);
2813 ***********************************************************************
2817 * This is the actual DO function for SCP. Get a file according to
2818 * the options previously setup.
2822 CURLcode scp_perform(struct connectdata *conn,
2826 CURLcode result = CURLE_OK;
2828 DEBUGF(infof(conn->data, "DO phase starts\n"));
2830 *dophase_done = FALSE; /* not done yet */
2832 /* start the first command in the DO phase */
2833 state(conn, SSH_SCP_TRANS_INIT);
2835 /* run the state-machine */
2836 result = ssh_multi_statemach(conn, dophase_done);
2838 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2841 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2847 /* called from multi.c while DOing */
2848 static CURLcode scp_doing(struct connectdata *conn,
2852 result = ssh_multi_statemach(conn, dophase_done);
2855 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2861 * The DO function is generic for both protocols. There was previously two
2862 * separate ones but this way means less duplicated code.
2865 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2869 struct SessionHandle *data = conn->data;
2870 struct ssh_conn *sshc = &conn->proto.sshc;
2872 *done = FALSE; /* default to false */
2874 data->req.size = -1; /* make sure this is unknown at this point */
2876 sshc->actualcode = CURLE_OK; /* reset error code */
2877 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2880 Curl_pgrsSetUploadCounter(data, 0);
2881 Curl_pgrsSetDownloadCounter(data, 0);
2882 Curl_pgrsSetUploadSize(data, 0);
2883 Curl_pgrsSetDownloadSize(data, 0);
2885 if(conn->handler->protocol & CURLPROTO_SCP)
2886 res = scp_perform(conn, &connected, done);
2888 res = sftp_perform(conn, &connected, done);
2893 /* BLOCKING, but the function is using the state machine so the only reason
2894 this is still blocking is that the multi interface code has no support for
2895 disconnecting operations that takes a while */
2896 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2898 CURLcode result = CURLE_OK;
2899 struct ssh_conn *ssh = &conn->proto.sshc;
2900 (void) dead_connection;
2902 Curl_safefree(conn->data->req.protop);
2904 if(ssh->ssh_session) {
2905 /* only if there's a session still around to use! */
2907 state(conn, SSH_SESSION_DISCONNECT);
2909 result = ssh_block_statemach(conn, FALSE);
2915 /* generic done function for both SCP and SFTP called from their specific
2917 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2919 CURLcode result = CURLE_OK;
2920 struct SSHPROTO *sftp_scp = conn->data->req.protop;
2922 if(status == CURLE_OK) {
2923 /* run the state-machine
2925 TODO: when the multi interface is used, this _really_ should be using
2926 the ssh_multi_statemach function but we have no general support for
2927 non-blocking DONE operations, not in the multi state machine and with
2928 Curl_done() invokes on several places in the code!
2930 result = ssh_block_statemach(conn, FALSE);
2936 Curl_safefree(sftp_scp->path);
2937 if(Curl_pgrsDone(conn))
2938 return CURLE_ABORTED_BY_CALLBACK;
2940 conn->data->req.keepon = 0; /* clear all bits */
2945 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2948 (void)premature; /* not used */
2950 if(status == CURLE_OK)
2951 state(conn, SSH_SCP_DONE);
2953 return ssh_done(conn, status);
2957 /* return number of received (decrypted) bytes */
2958 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2959 const void *mem, size_t len, CURLcode *err)
2962 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2964 /* libssh2_channel_write() returns int! */
2966 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2968 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2970 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2974 else if(nwrite < LIBSSH2_ERROR_NONE) {
2975 *err = libssh2_session_error_to_CURLE((int)nwrite);
2983 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2984 * a regular CURLcode value.
2986 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2987 char *mem, size_t len, CURLcode *err)
2990 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2992 /* libssh2_channel_read() returns int */
2994 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2996 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2997 if(nread == LIBSSH2_ERROR_EAGAIN) {
3006 * =============== SFTP ===============
3010 ***********************************************************************
3014 * This is the actual DO function for SFTP. Get a file/directory according to
3015 * the options previously setup.
3019 CURLcode sftp_perform(struct connectdata *conn,
3023 CURLcode result = CURLE_OK;
3025 DEBUGF(infof(conn->data, "DO phase starts\n"));
3027 *dophase_done = FALSE; /* not done yet */
3029 /* start the first command in the DO phase */
3030 state(conn, SSH_SFTP_QUOTE_INIT);
3032 /* run the state-machine */
3033 result = ssh_multi_statemach(conn, dophase_done);
3035 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3038 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3044 /* called from multi.c while DOing */
3045 static CURLcode sftp_doing(struct connectdata *conn,
3049 result = ssh_multi_statemach(conn, dophase_done);
3052 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3057 /* BLOCKING, but the function is using the state machine so the only reason
3058 this is still blocking is that the multi interface code has no support for
3059 disconnecting operations that takes a while */
3060 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
3062 CURLcode result = CURLE_OK;
3063 (void) dead_connection;
3065 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3067 Curl_safefree(conn->data->req.protop);
3069 if(conn->proto.sshc.ssh_session) {
3070 /* only if there's a session still around to use! */
3071 state(conn, SSH_SFTP_SHUTDOWN);
3072 result = ssh_block_statemach(conn, FALSE);
3075 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3081 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3084 struct ssh_conn *sshc = &conn->proto.sshc;
3086 if(status == CURLE_OK) {
3087 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3088 errors that could happen due to open file handles during POSTQUOTE
3090 if(!status && !premature && conn->data->set.postquote) {
3091 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3092 state(conn, SSH_SFTP_CLOSE);
3095 state(conn, SSH_SFTP_CLOSE);
3097 return ssh_done(conn, status);
3100 /* return number of sent bytes */
3101 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3102 const void *mem, size_t len, CURLcode *err)
3104 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3105 but is changed to ssize_t in 0.15. These days we don't
3106 support libssh2 0.15*/
3109 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3111 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3113 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3117 else if(nwrite < LIBSSH2_ERROR_NONE) {
3118 *err = libssh2_session_error_to_CURLE((int)nwrite);
3126 * Return number of received (decrypted) bytes
3129 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3130 char *mem, size_t len, CURLcode *err)
3135 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3137 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3139 if(nread == LIBSSH2_ERROR_EAGAIN) {
3144 else if(nread < 0) {
3145 *err = libssh2_session_error_to_CURLE((int)nread);
3150 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3153 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3155 * Permission to use, copy, modify, and distribute this software for any
3156 * purpose with or without fee is hereby granted, provided that the above
3157 * copyright notice and this permission notice appear in all copies.
3159 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3160 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3161 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3162 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3163 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3164 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3165 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3168 get_pathname(const char **cpp, char **path)
3170 const char *cp = *cpp, *end;
3173 static const char WHITESPACE[] = " \t\r\n";
3175 cp += strspn(cp, WHITESPACE);
3179 return CURLE_QUOTE_ERROR;
3182 *path = malloc(strlen(cp) + 1);
3184 return CURLE_OUT_OF_MEMORY;
3186 /* Check for quoted filenames */
3187 if(*cp == '\"' || *cp == '\'') {
3190 /* Search for terminating quote, unescape some chars */
3191 for(i = j = 0; i <= strlen(cp); i++) {
3192 if(cp[i] == quot) { /* Found quote */
3197 if(cp[i] == '\0') { /* End of string */
3198 /*error("Unterminated quote");*/
3201 if(cp[i] == '\\') { /* Escaped characters */
3203 if(cp[i] != '\'' && cp[i] != '\"' &&
3205 /*error("Bad escaped character '\\%c'",
3210 (*path)[j++] = cp[i];
3214 /*error("Empty quotes");*/
3217 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3220 /* Read to end of filename */
3221 end = strpbrk(cp, WHITESPACE);
3223 end = strchr(cp, '\0');
3224 *cpp = end + strspn(end, WHITESPACE);
3226 memcpy(*path, cp, end - cp);
3227 (*path)[end - cp] = '\0';
3232 Curl_safefree(*path);
3233 return CURLE_QUOTE_ERROR;
3237 static const char *sftp_libssh2_strerror(int err)
3240 case LIBSSH2_FX_NO_SUCH_FILE:
3241 return "No such file or directory";
3243 case LIBSSH2_FX_PERMISSION_DENIED:
3244 return "Permission denied";
3246 case LIBSSH2_FX_FAILURE:
3247 return "Operation failed";
3249 case LIBSSH2_FX_BAD_MESSAGE:
3250 return "Bad message from SFTP server";
3252 case LIBSSH2_FX_NO_CONNECTION:
3253 return "Not connected to SFTP server";
3255 case LIBSSH2_FX_CONNECTION_LOST:
3256 return "Connection to SFTP server lost";
3258 case LIBSSH2_FX_OP_UNSUPPORTED:
3259 return "Operation not supported by SFTP server";
3261 case LIBSSH2_FX_INVALID_HANDLE:
3262 return "Invalid handle";
3264 case LIBSSH2_FX_NO_SUCH_PATH:
3265 return "No such file or directory";
3267 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3268 return "File already exists";
3270 case LIBSSH2_FX_WRITE_PROTECT:
3271 return "File is write protected";
3273 case LIBSSH2_FX_NO_MEDIA:
3276 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3279 case LIBSSH2_FX_QUOTA_EXCEEDED:
3280 return "User quota exceeded";
3282 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3283 return "Unknown principle";
3285 case LIBSSH2_FX_LOCK_CONFlICT:
3286 return "File lock conflict";
3288 case LIBSSH2_FX_DIR_NOT_EMPTY:
3289 return "Directory not empty";
3291 case LIBSSH2_FX_NOT_A_DIRECTORY:
3292 return "Not a directory";
3294 case LIBSSH2_FX_INVALID_FILENAME:
3295 return "Invalid filename";
3297 case LIBSSH2_FX_LINK_LOOP:
3298 return "Link points to itself";
3300 return "Unknown error in libssh2";
3303 #endif /* USE_LIBSSH2 */