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);
737 /* ssh_check_fingerprint sets state appropriately on error */
742 * Figure out authentication methods
743 * NB: As soon as we have provided a username to an openssh server we
744 * must never change it later. Thus, always specify the correct username
745 * here, even though the libssh2 docs kind of indicate that it should be
746 * possible to get a 'generic' list (not user-specific) of authentication
747 * methods, presumably with a blank username. That won't work in my
749 * So always specify it here.
751 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
753 curlx_uztoui(strlen(conn->user)));
755 if(!sshc->authlist) {
756 if(libssh2_userauth_authenticated(sshc->ssh_session)) {
758 infof(data, "SSH user accepted with no authentication\n");
759 state(conn, SSH_AUTH_DONE);
762 else if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
763 LIBSSH2_ERROR_EAGAIN) {
764 rc = LIBSSH2_ERROR_EAGAIN;
768 state(conn, SSH_SESSION_FREE);
769 sshc->actualcode = libssh2_session_error_to_CURLE(err);
773 infof(data, "SSH authentication methods available: %s\n",
776 state(conn, SSH_AUTH_PKEY_INIT);
779 case SSH_AUTH_PKEY_INIT:
781 * Check the supported auth types in the order I feel is most secure
782 * with the requested type of authentication
784 sshc->authed = FALSE;
786 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
787 (strstr(sshc->authlist, "publickey") != NULL)) {
789 bool rsa_pub_empty_but_ok = FALSE;
791 sshc->rsa_pub = sshc->rsa = NULL;
793 /* To ponder about: should really the lib be messing about with the
794 HOME environment variable etc? */
795 home = curl_getenv("HOME");
797 if(data->set.str[STRING_SSH_PUBLIC_KEY] &&
798 !*data->set.str[STRING_SSH_PUBLIC_KEY])
799 rsa_pub_empty_but_ok = true;
800 else if(data->set.str[STRING_SSH_PUBLIC_KEY])
801 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
803 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
805 /* as a final resort, try current dir! */
806 sshc->rsa_pub = strdup("id_dsa.pub");
808 if(!rsa_pub_empty_but_ok && (sshc->rsa_pub == NULL)) {
810 state(conn, SSH_SESSION_FREE);
811 sshc->actualcode = CURLE_OUT_OF_MEMORY;
815 if(data->set.str[STRING_SSH_PRIVATE_KEY])
816 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
818 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
820 /* as a final resort, try current dir! */
821 sshc->rsa = strdup("id_dsa");
823 if(sshc->rsa == NULL) {
825 Curl_safefree(sshc->rsa_pub);
826 state(conn, SSH_SESSION_FREE);
827 sshc->actualcode = CURLE_OUT_OF_MEMORY;
831 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
832 if(!sshc->passphrase)
833 sshc->passphrase = "";
837 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
838 infof(data, "Using ssh private key file %s\n", sshc->rsa);
840 state(conn, SSH_AUTH_PKEY);
843 state(conn, SSH_AUTH_PASS_INIT);
848 /* The function below checks if the files exists, no need to stat() here.
850 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
855 sshc->rsa, sshc->passphrase);
856 if(rc == LIBSSH2_ERROR_EAGAIN) {
860 Curl_safefree(sshc->rsa_pub);
861 Curl_safefree(sshc->rsa);
865 infof(data, "Initialized SSH public key authentication\n");
866 state(conn, SSH_AUTH_DONE);
870 (void)libssh2_session_last_error(sshc->ssh_session,
872 infof(data, "SSH public key authentication failed: %s\n", err_msg);
873 state(conn, SSH_AUTH_PASS_INIT);
877 case SSH_AUTH_PASS_INIT:
878 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
879 (strstr(sshc->authlist, "password") != NULL)) {
880 state(conn, SSH_AUTH_PASS);
883 state(conn, SSH_AUTH_HOST_INIT);
888 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
889 curlx_uztoui(strlen(conn->user)),
891 curlx_uztoui(strlen(conn->passwd)),
893 if(rc == LIBSSH2_ERROR_EAGAIN) {
898 infof(data, "Initialized password authentication\n");
899 state(conn, SSH_AUTH_DONE);
902 state(conn, SSH_AUTH_HOST_INIT);
906 case SSH_AUTH_HOST_INIT:
907 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
908 (strstr(sshc->authlist, "hostbased") != NULL)) {
909 state(conn, SSH_AUTH_HOST);
912 state(conn, SSH_AUTH_AGENT_INIT);
917 state(conn, SSH_AUTH_AGENT_INIT);
920 case SSH_AUTH_AGENT_INIT:
921 #ifdef HAVE_LIBSSH2_AGENT_API
922 if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
923 && (strstr(sshc->authlist, "publickey") != NULL)) {
925 /* Connect to the ssh-agent */
926 /* The agent could be shared by a curl thread i believe
927 but nothing obvious as keys can be added/removed at any time */
928 if(!sshc->ssh_agent) {
929 sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
930 if(!sshc->ssh_agent) {
931 infof(data, "Could not create agent object\n");
933 state(conn, SSH_AUTH_KEY_INIT);
938 rc = libssh2_agent_connect(sshc->ssh_agent);
939 if(rc == LIBSSH2_ERROR_EAGAIN)
942 infof(data, "Failure connecting to agent\n");
943 state(conn, SSH_AUTH_KEY_INIT);
946 state(conn, SSH_AUTH_AGENT_LIST);
950 #endif /* HAVE_LIBSSH2_AGENT_API */
951 state(conn, SSH_AUTH_KEY_INIT);
954 case SSH_AUTH_AGENT_LIST:
955 #ifdef HAVE_LIBSSH2_AGENT_API
956 rc = libssh2_agent_list_identities(sshc->ssh_agent);
958 if(rc == LIBSSH2_ERROR_EAGAIN)
961 infof(data, "Failure requesting identities to agent\n");
962 state(conn, SSH_AUTH_KEY_INIT);
965 state(conn, SSH_AUTH_AGENT);
966 sshc->sshagent_prev_identity = NULL;
972 #ifdef HAVE_LIBSSH2_AGENT_API
973 /* as prev_identity evolves only after an identity user auth finished we
974 can safely request it again as long as EAGAIN is returned here or by
975 libssh2_agent_userauth */
976 rc = libssh2_agent_get_identity(sshc->ssh_agent,
977 &sshc->sshagent_identity,
978 sshc->sshagent_prev_identity);
979 if(rc == LIBSSH2_ERROR_EAGAIN)
983 rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
984 sshc->sshagent_identity);
987 if(rc != LIBSSH2_ERROR_EAGAIN) {
988 /* tried and failed? go to next identity */
989 sshc->sshagent_prev_identity = sshc->sshagent_identity;
996 infof(data, "Failure requesting identities to agent\n");
998 infof(data, "No identity would match\n");
1000 if(rc == LIBSSH2_ERROR_NONE) {
1001 sshc->authed = TRUE;
1002 infof(data, "Agent based authentication successful\n");
1003 state(conn, SSH_AUTH_DONE);
1006 state(conn, SSH_AUTH_KEY_INIT);
1010 case SSH_AUTH_KEY_INIT:
1011 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
1012 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
1013 state(conn, SSH_AUTH_KEY);
1016 state(conn, SSH_AUTH_DONE);
1021 /* Authentication failed. Continue with keyboard-interactive now. */
1022 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
1025 strlen(conn->user)),
1027 if(rc == LIBSSH2_ERROR_EAGAIN) {
1031 sshc->authed = TRUE;
1032 infof(data, "Initialized keyboard interactive authentication\n");
1034 state(conn, SSH_AUTH_DONE);
1039 failf(data, "Authentication failure");
1040 state(conn, SSH_SESSION_FREE);
1041 sshc->actualcode = CURLE_LOGIN_DENIED;
1046 * At this point we have an authenticated ssh session.
1048 infof(data, "Authentication complete\n");
1050 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
1052 conn->sockfd = sock;
1053 conn->writesockfd = CURL_SOCKET_BAD;
1055 if(conn->handler->protocol == CURLPROTO_SFTP) {
1056 state(conn, SSH_SFTP_INIT);
1059 infof(data, "SSH CONNECT phase done\n");
1060 state(conn, SSH_STOP);
1065 * Start the libssh2 sftp session
1067 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
1068 if(!sshc->sftp_session) {
1069 if(libssh2_session_last_errno(sshc->ssh_session) ==
1070 LIBSSH2_ERROR_EAGAIN) {
1071 rc = LIBSSH2_ERROR_EAGAIN;
1077 (void)libssh2_session_last_error(sshc->ssh_session,
1079 failf(data, "Failure initializing sftp session: %s", err_msg);
1080 state(conn, SSH_SESSION_FREE);
1081 sshc->actualcode = CURLE_FAILED_INIT;
1085 state(conn, SSH_SFTP_REALPATH);
1088 case SSH_SFTP_REALPATH:
1090 char tempHome[PATH_MAX];
1093 * Get the "home" directory
1095 rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
1096 tempHome, PATH_MAX-1);
1097 if(rc == LIBSSH2_ERROR_EAGAIN) {
1101 /* It seems that this string is not always NULL terminated */
1102 tempHome[rc] = '\0';
1103 sshc->homedir = strdup(tempHome);
1104 if(!sshc->homedir) {
1105 state(conn, SSH_SFTP_CLOSE);
1106 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1109 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1112 /* Return the error type */
1113 err = sftp_libssh2_last_error(sshc->sftp_session);
1114 result = sftp_libssh2_error_to_CURLE(err);
1115 sshc->actualcode = result?result:CURLE_SSH;
1116 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1118 state(conn, SSH_STOP);
1122 /* This is the last step in the SFTP connect phase. Do note that while
1123 we get the homedir here, we get the "workingpath" in the DO action
1124 since the homedir will remain the same between request but the
1125 working path will not. */
1126 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1127 state(conn, SSH_STOP);
1130 case SSH_SFTP_QUOTE_INIT:
1132 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1134 sshc->actualcode = result;
1135 state(conn, SSH_STOP);
1139 if(data->set.quote) {
1140 infof(data, "Sending quote commands\n");
1141 sshc->quote_item = data->set.quote;
1142 state(conn, SSH_SFTP_QUOTE);
1145 state(conn, SSH_SFTP_TRANS_INIT);
1149 case SSH_SFTP_POSTQUOTE_INIT:
1150 if(data->set.postquote) {
1151 infof(data, "Sending quote commands\n");
1152 sshc->quote_item = data->set.postquote;
1153 state(conn, SSH_SFTP_QUOTE);
1156 state(conn, SSH_STOP);
1160 case SSH_SFTP_QUOTE:
1161 /* Send any quote commands */
1166 * Support some of the "FTP" commands
1168 char *cmd = sshc->quote_item->data;
1169 sshc->acceptfail = FALSE;
1171 /* if a command starts with an asterisk, which a legal SFTP command never
1172 can, the command will be allowed to fail without it causing any
1173 aborts or cancels etc. It will cause libcurl to act as if the command
1174 is successful, whatever the server reponds. */
1178 sshc->acceptfail = TRUE;
1181 if(curl_strequal("pwd", cmd)) {
1182 /* output debug output if that is requested */
1183 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1186 result = CURLE_OUT_OF_MEMORY;
1187 state(conn, SSH_SFTP_CLOSE);
1188 sshc->nextstate = SSH_NO_STATE;
1191 if(data->set.verbose) {
1192 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1193 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1195 /* this sends an FTP-like "header" to the header callback so that the
1196 current directory can be read very similar to how it is read when
1197 using ordinary FTP. */
1198 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1201 state(conn, SSH_SFTP_CLOSE);
1202 sshc->nextstate = SSH_NO_STATE;
1203 sshc->actualcode = result;
1206 state(conn, SSH_SFTP_NEXT_QUOTE);
1211 * the arguments following the command must be separated from the
1212 * command with a space so we can check for it unconditionally
1214 cp = strchr(cmd, ' ');
1216 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1217 state(conn, SSH_SFTP_CLOSE);
1218 sshc->nextstate = SSH_NO_STATE;
1219 sshc->actualcode = CURLE_QUOTE_ERROR;
1224 * also, every command takes at least one argument so we get that
1225 * first argument right now
1227 result = get_pathname(&cp, &sshc->quote_path1);
1229 if(result == CURLE_OUT_OF_MEMORY)
1230 failf(data, "Out of memory");
1232 failf(data, "Syntax error: Bad first parameter");
1233 state(conn, SSH_SFTP_CLOSE);
1234 sshc->nextstate = SSH_NO_STATE;
1235 sshc->actualcode = result;
1240 * SFTP is a binary protocol, so we don't send text commands
1241 * to the server. Instead, we scan for commands used by
1242 * OpenSSH's sftp program and call the appropriate libssh2
1245 if(curl_strnequal(cmd, "chgrp ", 6) ||
1246 curl_strnequal(cmd, "chmod ", 6) ||
1247 curl_strnequal(cmd, "chown ", 6) ) {
1248 /* attribute change */
1250 /* sshc->quote_path1 contains the mode to set */
1251 /* get the destination */
1252 result = get_pathname(&cp, &sshc->quote_path2);
1254 if(result == CURLE_OUT_OF_MEMORY)
1255 failf(data, "Out of memory");
1257 failf(data, "Syntax error in chgrp/chmod/chown: "
1258 "Bad second parameter");
1259 Curl_safefree(sshc->quote_path1);
1260 state(conn, SSH_SFTP_CLOSE);
1261 sshc->nextstate = SSH_NO_STATE;
1262 sshc->actualcode = result;
1265 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1266 state(conn, SSH_SFTP_QUOTE_STAT);
1269 else if(curl_strnequal(cmd, "ln ", 3) ||
1270 curl_strnequal(cmd, "symlink ", 8)) {
1271 /* symbolic linking */
1272 /* sshc->quote_path1 is the source */
1273 /* get the destination */
1274 result = get_pathname(&cp, &sshc->quote_path2);
1276 if(result == CURLE_OUT_OF_MEMORY)
1277 failf(data, "Out of memory");
1280 "Syntax error in ln/symlink: Bad second parameter");
1281 Curl_safefree(sshc->quote_path1);
1282 state(conn, SSH_SFTP_CLOSE);
1283 sshc->nextstate = SSH_NO_STATE;
1284 sshc->actualcode = result;
1287 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1290 else if(curl_strnequal(cmd, "mkdir ", 6)) {
1292 state(conn, SSH_SFTP_QUOTE_MKDIR);
1295 else if(curl_strnequal(cmd, "rename ", 7)) {
1297 /* first param is the source path */
1298 /* second param is the dest. path */
1299 result = get_pathname(&cp, &sshc->quote_path2);
1301 if(result == CURLE_OUT_OF_MEMORY)
1302 failf(data, "Out of memory");
1304 failf(data, "Syntax error in rename: Bad second parameter");
1305 Curl_safefree(sshc->quote_path1);
1306 state(conn, SSH_SFTP_CLOSE);
1307 sshc->nextstate = SSH_NO_STATE;
1308 sshc->actualcode = result;
1311 state(conn, SSH_SFTP_QUOTE_RENAME);
1314 else if(curl_strnequal(cmd, "rmdir ", 6)) {
1316 state(conn, SSH_SFTP_QUOTE_RMDIR);
1319 else if(curl_strnequal(cmd, "rm ", 3)) {
1320 state(conn, SSH_SFTP_QUOTE_UNLINK);
1324 failf(data, "Unknown SFTP command");
1325 Curl_safefree(sshc->quote_path1);
1326 Curl_safefree(sshc->quote_path2);
1327 state(conn, SSH_SFTP_CLOSE);
1328 sshc->nextstate = SSH_NO_STATE;
1329 sshc->actualcode = CURLE_QUOTE_ERROR;
1333 if(!sshc->quote_item) {
1334 state(conn, SSH_SFTP_TRANS_INIT);
1338 case SSH_SFTP_NEXT_QUOTE:
1339 Curl_safefree(sshc->quote_path1);
1340 Curl_safefree(sshc->quote_path2);
1342 sshc->quote_item = sshc->quote_item->next;
1344 if(sshc->quote_item) {
1345 state(conn, SSH_SFTP_QUOTE);
1348 if(sshc->nextstate != SSH_NO_STATE) {
1349 state(conn, sshc->nextstate);
1350 sshc->nextstate = SSH_NO_STATE;
1353 state(conn, SSH_SFTP_TRANS_INIT);
1358 case SSH_SFTP_QUOTE_STAT:
1360 char *cmd = sshc->quote_item->data;
1361 sshc->acceptfail = FALSE;
1363 /* if a command starts with an asterisk, which a legal SFTP command never
1364 can, the command will be allowed to fail without it causing any
1365 aborts or cancels etc. It will cause libcurl to act as if the command
1366 is successful, whatever the server reponds. */
1370 sshc->acceptfail = TRUE;
1373 if(!curl_strnequal(cmd, "chmod", 5)) {
1374 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1375 * set them both at once, we need to obtain the current ownership
1376 * first. This takes an extra protocol round trip.
1378 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1379 curlx_uztoui(strlen(sshc->quote_path2)),
1381 &sshc->quote_attrs);
1382 if(rc == LIBSSH2_ERROR_EAGAIN) {
1385 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1386 err = sftp_libssh2_last_error(sshc->sftp_session);
1387 Curl_safefree(sshc->quote_path1);
1388 Curl_safefree(sshc->quote_path2);
1389 failf(data, "Attempt to get SFTP stats failed: %s",
1390 sftp_libssh2_strerror(err));
1391 state(conn, SSH_SFTP_CLOSE);
1392 sshc->nextstate = SSH_NO_STATE;
1393 sshc->actualcode = CURLE_QUOTE_ERROR;
1398 /* Now set the new attributes... */
1399 if(curl_strnequal(cmd, "chgrp", 5)) {
1400 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1401 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1402 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1403 !sshc->acceptfail) {
1404 Curl_safefree(sshc->quote_path1);
1405 Curl_safefree(sshc->quote_path2);
1406 failf(data, "Syntax error: chgrp gid not a number");
1407 state(conn, SSH_SFTP_CLOSE);
1408 sshc->nextstate = SSH_NO_STATE;
1409 sshc->actualcode = CURLE_QUOTE_ERROR;
1413 else if(curl_strnequal(cmd, "chmod", 5)) {
1414 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1415 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1416 /* permissions are octal */
1417 if(sshc->quote_attrs.permissions == 0 &&
1418 !ISDIGIT(sshc->quote_path1[0])) {
1419 Curl_safefree(sshc->quote_path1);
1420 Curl_safefree(sshc->quote_path2);
1421 failf(data, "Syntax error: chmod permissions not a number");
1422 state(conn, SSH_SFTP_CLOSE);
1423 sshc->nextstate = SSH_NO_STATE;
1424 sshc->actualcode = CURLE_QUOTE_ERROR;
1428 else if(curl_strnequal(cmd, "chown", 5)) {
1429 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1430 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1431 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1432 !sshc->acceptfail) {
1433 Curl_safefree(sshc->quote_path1);
1434 Curl_safefree(sshc->quote_path2);
1435 failf(data, "Syntax error: chown uid not a number");
1436 state(conn, SSH_SFTP_CLOSE);
1437 sshc->nextstate = SSH_NO_STATE;
1438 sshc->actualcode = CURLE_QUOTE_ERROR;
1443 /* Now send the completed structure... */
1444 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1448 case SSH_SFTP_QUOTE_SETSTAT:
1449 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1450 curlx_uztoui(strlen(sshc->quote_path2)),
1451 LIBSSH2_SFTP_SETSTAT,
1452 &sshc->quote_attrs);
1453 if(rc == LIBSSH2_ERROR_EAGAIN) {
1456 else if(rc != 0 && !sshc->acceptfail) {
1457 err = sftp_libssh2_last_error(sshc->sftp_session);
1458 Curl_safefree(sshc->quote_path1);
1459 Curl_safefree(sshc->quote_path2);
1460 failf(data, "Attempt to set SFTP stats failed: %s",
1461 sftp_libssh2_strerror(err));
1462 state(conn, SSH_SFTP_CLOSE);
1463 sshc->nextstate = SSH_NO_STATE;
1464 sshc->actualcode = CURLE_QUOTE_ERROR;
1467 state(conn, SSH_SFTP_NEXT_QUOTE);
1470 case SSH_SFTP_QUOTE_SYMLINK:
1471 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1472 curlx_uztoui(strlen(sshc->quote_path1)),
1474 curlx_uztoui(strlen(sshc->quote_path2)),
1475 LIBSSH2_SFTP_SYMLINK);
1476 if(rc == LIBSSH2_ERROR_EAGAIN) {
1479 else if(rc != 0 && !sshc->acceptfail) {
1480 err = sftp_libssh2_last_error(sshc->sftp_session);
1481 Curl_safefree(sshc->quote_path1);
1482 Curl_safefree(sshc->quote_path2);
1483 failf(data, "symlink command failed: %s",
1484 sftp_libssh2_strerror(err));
1485 state(conn, SSH_SFTP_CLOSE);
1486 sshc->nextstate = SSH_NO_STATE;
1487 sshc->actualcode = CURLE_QUOTE_ERROR;
1490 state(conn, SSH_SFTP_NEXT_QUOTE);
1493 case SSH_SFTP_QUOTE_MKDIR:
1494 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1495 curlx_uztoui(strlen(sshc->quote_path1)),
1496 data->set.new_directory_perms);
1497 if(rc == LIBSSH2_ERROR_EAGAIN) {
1500 else if(rc != 0 && !sshc->acceptfail) {
1501 err = sftp_libssh2_last_error(sshc->sftp_session);
1502 Curl_safefree(sshc->quote_path1);
1503 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1504 state(conn, SSH_SFTP_CLOSE);
1505 sshc->nextstate = SSH_NO_STATE;
1506 sshc->actualcode = CURLE_QUOTE_ERROR;
1509 state(conn, SSH_SFTP_NEXT_QUOTE);
1512 case SSH_SFTP_QUOTE_RENAME:
1513 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1514 curlx_uztoui(strlen(sshc->quote_path1)),
1516 curlx_uztoui(strlen(sshc->quote_path2)),
1517 LIBSSH2_SFTP_RENAME_OVERWRITE |
1518 LIBSSH2_SFTP_RENAME_ATOMIC |
1519 LIBSSH2_SFTP_RENAME_NATIVE);
1521 if(rc == LIBSSH2_ERROR_EAGAIN) {
1524 else if(rc != 0 && !sshc->acceptfail) {
1525 err = sftp_libssh2_last_error(sshc->sftp_session);
1526 Curl_safefree(sshc->quote_path1);
1527 Curl_safefree(sshc->quote_path2);
1528 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1529 state(conn, SSH_SFTP_CLOSE);
1530 sshc->nextstate = SSH_NO_STATE;
1531 sshc->actualcode = CURLE_QUOTE_ERROR;
1534 state(conn, SSH_SFTP_NEXT_QUOTE);
1537 case SSH_SFTP_QUOTE_RMDIR:
1538 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1539 curlx_uztoui(strlen(sshc->quote_path1)));
1540 if(rc == LIBSSH2_ERROR_EAGAIN) {
1543 else if(rc != 0 && !sshc->acceptfail) {
1544 err = sftp_libssh2_last_error(sshc->sftp_session);
1545 Curl_safefree(sshc->quote_path1);
1546 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1547 state(conn, SSH_SFTP_CLOSE);
1548 sshc->nextstate = SSH_NO_STATE;
1549 sshc->actualcode = CURLE_QUOTE_ERROR;
1552 state(conn, SSH_SFTP_NEXT_QUOTE);
1555 case SSH_SFTP_QUOTE_UNLINK:
1556 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1557 curlx_uztoui(strlen(sshc->quote_path1)));
1558 if(rc == LIBSSH2_ERROR_EAGAIN) {
1561 else if(rc != 0 && !sshc->acceptfail) {
1562 err = sftp_libssh2_last_error(sshc->sftp_session);
1563 Curl_safefree(sshc->quote_path1);
1564 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1565 state(conn, SSH_SFTP_CLOSE);
1566 sshc->nextstate = SSH_NO_STATE;
1567 sshc->actualcode = CURLE_QUOTE_ERROR;
1570 state(conn, SSH_SFTP_NEXT_QUOTE);
1573 case SSH_SFTP_TRANS_INIT:
1574 if(data->set.upload)
1575 state(conn, SSH_SFTP_UPLOAD_INIT);
1577 if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1578 state(conn, SSH_SFTP_READDIR_INIT);
1580 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1584 case SSH_SFTP_UPLOAD_INIT:
1586 unsigned long flags;
1588 * NOTE!!! libssh2 requires that the destination path is a full path
1589 * that includes the destination file and name OR ends in a "/"
1590 * If this is not done the destination file will be named the
1591 * same name as the last directory in the path.
1594 if(data->state.resume_from != 0) {
1595 LIBSSH2_SFTP_ATTRIBUTES attrs;
1596 if(data->state.resume_from < 0) {
1597 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1598 curlx_uztoui(strlen(sftp_scp->path)),
1599 LIBSSH2_SFTP_STAT, &attrs);
1600 if(rc == LIBSSH2_ERROR_EAGAIN) {
1604 data->state.resume_from = 0;
1607 curl_off_t size = attrs.filesize;
1609 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
1610 return CURLE_BAD_DOWNLOAD_RESUME;
1612 data->state.resume_from = attrs.filesize;
1617 if(data->set.ftp_append)
1618 /* Try to open for append, but create if nonexisting */
1619 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1620 else if(data->state.resume_from > 0)
1621 /* If we have restart position then open for append */
1622 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1624 /* Clear file before writing (normal behaviour) */
1625 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1628 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1629 curlx_uztoui(strlen(sftp_scp->path)),
1630 flags, data->set.new_file_perms,
1631 LIBSSH2_SFTP_OPENFILE);
1633 if(!sshc->sftp_handle) {
1634 rc = libssh2_session_last_errno(sshc->ssh_session);
1636 if(LIBSSH2_ERROR_EAGAIN == rc)
1639 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1640 /* only when there was an SFTP protocol error can we extract
1642 err = sftp_libssh2_last_error(sshc->sftp_session);
1644 err = -1; /* not an sftp error at all */
1646 if(sshc->secondCreateDirs) {
1647 state(conn, SSH_SFTP_CLOSE);
1648 sshc->actualcode = err>= LIBSSH2_FX_OK?
1649 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1650 failf(data, "Creating the dir/file failed: %s",
1651 sftp_libssh2_strerror(err));
1654 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1655 (err == LIBSSH2_FX_FAILURE) ||
1656 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1657 (data->set.ftp_create_missing_dirs &&
1658 (strlen(sftp_scp->path) > 1))) {
1659 /* try to create the path remotely */
1660 sshc->secondCreateDirs = 1;
1661 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1664 state(conn, SSH_SFTP_CLOSE);
1665 sshc->actualcode = err>= LIBSSH2_FX_OK?
1666 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1667 if(!sshc->actualcode) {
1668 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1669 zero even though libssh2_sftp_open() failed previously! We need
1670 to work around that! */
1671 sshc->actualcode = CURLE_SSH;
1674 failf(data, "Upload failed: %s (%d/%d)",
1675 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1681 /* If we have a restart point then we need to seek to the correct
1683 if(data->state.resume_from > 0) {
1684 /* Let's read off the proper amount of bytes from the input. */
1685 if(conn->seek_func) {
1686 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1690 if(seekerr != CURL_SEEKFUNC_OK) {
1692 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1693 failf(data, "Could not seek stream");
1694 return CURLE_FTP_COULDNT_USE_REST;
1696 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1698 curl_off_t passed=0;
1700 size_t readthisamountnow =
1701 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1702 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1704 size_t actuallyread =
1705 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1708 passed += actuallyread;
1709 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1710 /* this checks for greater-than only to make sure that the
1711 CURL_READFUNC_ABORT return code still aborts */
1712 failf(data, "Failed to read data");
1713 return CURLE_FTP_COULDNT_USE_REST;
1715 } while(passed < data->state.resume_from);
1719 /* now, decrease the size of the read */
1720 if(data->state.infilesize > 0) {
1721 data->state.infilesize -= data->state.resume_from;
1722 data->req.size = data->state.infilesize;
1723 Curl_pgrsSetUploadSize(data, data->state.infilesize);
1726 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1728 if(data->state.infilesize > 0) {
1729 data->req.size = data->state.infilesize;
1730 Curl_pgrsSetUploadSize(data, data->state.infilesize);
1733 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1735 /* not set by Curl_setup_transfer to preserve keepon bits */
1736 conn->sockfd = conn->writesockfd;
1739 state(conn, SSH_SFTP_CLOSE);
1740 sshc->actualcode = result;
1743 /* store this original bitmask setup to use later on if we can't
1744 figure out a "real" bitmask */
1745 sshc->orig_waitfor = data->req.keepon;
1747 /* we want to use the _sending_ function even when the socket turns
1748 out readable as the underlying libssh2 sftp send function will deal
1749 with both accordingly */
1750 conn->cselect_bits = CURL_CSELECT_OUT;
1752 /* since we don't really wait for anything at this point, we want the
1753 state machine to move on as soon as possible so we set a very short
1755 Curl_expire(data, 1);
1757 state(conn, SSH_STOP);
1762 case SSH_SFTP_CREATE_DIRS_INIT:
1763 if(strlen(sftp_scp->path) > 1) {
1764 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1765 state(conn, SSH_SFTP_CREATE_DIRS);
1768 state(conn, SSH_SFTP_UPLOAD_INIT);
1772 case SSH_SFTP_CREATE_DIRS:
1773 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1774 *sshc->slash_pos = 0;
1776 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1777 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1781 state(conn, SSH_SFTP_UPLOAD_INIT);
1785 case SSH_SFTP_CREATE_DIRS_MKDIR:
1786 /* 'mode' - parameter is preliminary - default to 0644 */
1787 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1788 curlx_uztoui(strlen(sftp_scp->path)),
1789 data->set.new_directory_perms);
1790 if(rc == LIBSSH2_ERROR_EAGAIN) {
1793 *sshc->slash_pos = '/';
1797 * Abort if failure wasn't that the dir already exists or the
1798 * permission was denied (creation might succeed further down the
1799 * path) - retry on unspecific FAILURE also
1801 err = sftp_libssh2_last_error(sshc->sftp_session);
1802 if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1803 (err != LIBSSH2_FX_FAILURE) &&
1804 (err != LIBSSH2_FX_PERMISSION_DENIED)) {
1805 result = sftp_libssh2_error_to_CURLE(err);
1806 state(conn, SSH_SFTP_CLOSE);
1807 sshc->actualcode = result?result:CURLE_SSH;
1811 state(conn, SSH_SFTP_CREATE_DIRS);
1814 case SSH_SFTP_READDIR_INIT:
1815 Curl_pgrsSetDownloadSize(data, -1);
1816 if(data->set.opt_no_body) {
1817 state(conn, SSH_STOP);
1822 * This is a directory that we are trying to get, so produce a directory
1825 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1828 strlen(sftp_scp->path)),
1829 0, 0, LIBSSH2_SFTP_OPENDIR);
1830 if(!sshc->sftp_handle) {
1831 if(libssh2_session_last_errno(sshc->ssh_session) ==
1832 LIBSSH2_ERROR_EAGAIN) {
1833 rc = LIBSSH2_ERROR_EAGAIN;
1837 err = sftp_libssh2_last_error(sshc->sftp_session);
1838 failf(data, "Could not open directory for reading: %s",
1839 sftp_libssh2_strerror(err));
1840 state(conn, SSH_SFTP_CLOSE);
1841 result = sftp_libssh2_error_to_CURLE(err);
1842 sshc->actualcode = result?result:CURLE_SSH;
1846 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1847 state(conn, SSH_SFTP_CLOSE);
1848 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1851 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1852 Curl_safefree(sshc->readdir_filename);
1853 state(conn, SSH_SFTP_CLOSE);
1854 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1857 state(conn, SSH_SFTP_READDIR);
1860 case SSH_SFTP_READDIR:
1861 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1862 sshc->readdir_filename,
1864 sshc->readdir_longentry,
1866 &sshc->readdir_attrs);
1867 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1868 rc = LIBSSH2_ERROR_EAGAIN;
1871 if(sshc->readdir_len > 0) {
1872 sshc->readdir_filename[sshc->readdir_len] = '\0';
1874 if(data->set.ftp_list_only) {
1877 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1878 if(tmpLine == NULL) {
1879 state(conn, SSH_SFTP_CLOSE);
1880 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1883 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1884 tmpLine, sshc->readdir_len+1);
1885 Curl_safefree(tmpLine);
1888 state(conn, SSH_STOP);
1891 /* since this counts what we send to the client, we include the
1892 newline in this counter */
1893 data->req.bytecount += sshc->readdir_len+1;
1895 /* output debug output if that is requested */
1896 if(data->set.verbose) {
1897 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1898 sshc->readdir_len, conn);
1902 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1903 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1904 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1905 if(!sshc->readdir_line) {
1906 Curl_safefree(sshc->readdir_filename);
1907 Curl_safefree(sshc->readdir_longentry);
1908 state(conn, SSH_SFTP_CLOSE);
1909 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1913 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1914 sshc->readdir_currLen);
1915 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1916 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1917 LIBSSH2_SFTP_S_IFLNK)) {
1918 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1919 if(sshc->readdir_linkPath == NULL) {
1920 Curl_safefree(sshc->readdir_filename);
1921 Curl_safefree(sshc->readdir_longentry);
1922 state(conn, SSH_SFTP_CLOSE);
1923 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1927 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1928 sshc->readdir_filename);
1929 state(conn, SSH_SFTP_READDIR_LINK);
1932 state(conn, SSH_SFTP_READDIR_BOTTOM);
1936 else if(sshc->readdir_len == 0) {
1937 Curl_safefree(sshc->readdir_filename);
1938 Curl_safefree(sshc->readdir_longentry);
1939 state(conn, SSH_SFTP_READDIR_DONE);
1942 else if(sshc->readdir_len <= 0) {
1943 err = sftp_libssh2_last_error(sshc->sftp_session);
1944 result = sftp_libssh2_error_to_CURLE(err);
1945 sshc->actualcode = result?result:CURLE_SSH;
1946 failf(data, "Could not open remote file for reading: %s :: %d",
1947 sftp_libssh2_strerror(err),
1948 libssh2_session_last_errno(sshc->ssh_session));
1949 Curl_safefree(sshc->readdir_filename);
1950 Curl_safefree(sshc->readdir_longentry);
1951 state(conn, SSH_SFTP_CLOSE);
1956 case SSH_SFTP_READDIR_LINK:
1958 libssh2_sftp_symlink_ex(sshc->sftp_session,
1959 sshc->readdir_linkPath,
1960 curlx_uztoui(strlen(sshc->readdir_linkPath)),
1961 sshc->readdir_filename,
1962 PATH_MAX, LIBSSH2_SFTP_READLINK);
1963 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1964 rc = LIBSSH2_ERROR_EAGAIN;
1967 Curl_safefree(sshc->readdir_linkPath);
1969 /* get room for the filename and extra output */
1970 sshc->readdir_totalLen += 4 + sshc->readdir_len;
1971 new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
1972 if(!new_readdir_line) {
1973 Curl_safefree(sshc->readdir_line);
1974 Curl_safefree(sshc->readdir_filename);
1975 Curl_safefree(sshc->readdir_longentry);
1976 state(conn, SSH_SFTP_CLOSE);
1977 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1980 sshc->readdir_line = new_readdir_line;
1982 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1983 sshc->readdir_currLen,
1984 sshc->readdir_totalLen -
1985 sshc->readdir_currLen,
1987 sshc->readdir_filename);
1989 state(conn, SSH_SFTP_READDIR_BOTTOM);
1992 case SSH_SFTP_READDIR_BOTTOM:
1993 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1994 sshc->readdir_currLen,
1995 sshc->readdir_totalLen -
1996 sshc->readdir_currLen, "\n");
1997 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1999 sshc->readdir_currLen);
2001 if(result == CURLE_OK) {
2003 /* output debug output if that is requested */
2004 if(data->set.verbose) {
2005 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
2006 sshc->readdir_currLen, conn);
2008 data->req.bytecount += sshc->readdir_currLen;
2010 Curl_safefree(sshc->readdir_line);
2012 state(conn, SSH_STOP);
2015 state(conn, SSH_SFTP_READDIR);
2018 case SSH_SFTP_READDIR_DONE:
2019 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
2020 LIBSSH2_ERROR_EAGAIN) {
2021 rc = LIBSSH2_ERROR_EAGAIN;
2024 sshc->sftp_handle = NULL;
2025 Curl_safefree(sshc->readdir_filename);
2026 Curl_safefree(sshc->readdir_longentry);
2028 /* no data to transfer */
2029 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2030 state(conn, SSH_STOP);
2033 case SSH_SFTP_DOWNLOAD_INIT:
2035 * Work on getting the specified file
2038 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
2039 curlx_uztoui(strlen(sftp_scp->path)),
2040 LIBSSH2_FXF_READ, data->set.new_file_perms,
2041 LIBSSH2_SFTP_OPENFILE);
2042 if(!sshc->sftp_handle) {
2043 if(libssh2_session_last_errno(sshc->ssh_session) ==
2044 LIBSSH2_ERROR_EAGAIN) {
2045 rc = LIBSSH2_ERROR_EAGAIN;
2049 err = sftp_libssh2_last_error(sshc->sftp_session);
2050 failf(data, "Could not open remote file for reading: %s",
2051 sftp_libssh2_strerror(err));
2052 state(conn, SSH_SFTP_CLOSE);
2053 result = sftp_libssh2_error_to_CURLE(err);
2054 sshc->actualcode = result?result:CURLE_SSH;
2058 state(conn, SSH_SFTP_DOWNLOAD_STAT);
2061 case SSH_SFTP_DOWNLOAD_STAT:
2063 LIBSSH2_SFTP_ATTRIBUTES attrs;
2065 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
2066 curlx_uztoui(strlen(sftp_scp->path)),
2067 LIBSSH2_SFTP_STAT, &attrs);
2068 if(rc == LIBSSH2_ERROR_EAGAIN) {
2073 * libssh2_sftp_open() didn't return an error, so maybe the server
2074 * just doesn't support stat()
2076 data->req.size = -1;
2077 data->req.maxdownload = -1;
2078 Curl_pgrsSetDownloadSize(data, -1);
2081 curl_off_t size = attrs.filesize;
2084 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
2085 return CURLE_BAD_DOWNLOAD_RESUME;
2087 if(conn->data->state.use_range) {
2088 curl_off_t from, to;
2092 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2093 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2095 to=curlx_strtoofft(ptr, &ptr2, 0);
2096 if((ptr == ptr2) /* no "to" value given */
2101 /* from is relative to end of file */
2105 failf(data, "Offset (%"
2106 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2107 CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
2108 return CURLE_BAD_DOWNLOAD_RESUME;
2115 size = to - from + 1;
2118 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2120 data->req.size = size;
2121 data->req.maxdownload = size;
2122 Curl_pgrsSetDownloadSize(data, size);
2125 /* We can resume if we can seek to the resume position */
2126 if(data->state.resume_from) {
2127 if(data->state.resume_from < 0) {
2128 /* We're supposed to download the last abs(from) bytes */
2129 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2130 failf(data, "Offset (%"
2131 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2132 CURL_FORMAT_CURL_OFF_T ")",
2133 data->state.resume_from, attrs.filesize);
2134 return CURLE_BAD_DOWNLOAD_RESUME;
2136 /* download from where? */
2137 data->state.resume_from += attrs.filesize;
2140 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2141 failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
2142 ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
2143 data->state.resume_from, attrs.filesize);
2144 return CURLE_BAD_DOWNLOAD_RESUME;
2147 /* Does a completed file need to be seeked and started or closed ? */
2148 /* Now store the number of bytes we are expected to download */
2149 data->req.size = attrs.filesize - data->state.resume_from;
2150 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2151 Curl_pgrsSetDownloadSize(data,
2152 attrs.filesize - data->state.resume_from);
2153 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2157 /* Setup the actual download */
2158 if(data->req.size == 0) {
2159 /* no data to transfer */
2160 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2161 infof(data, "File already completely downloaded\n");
2162 state(conn, SSH_STOP);
2166 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2167 FALSE, NULL, -1, NULL);
2169 /* not set by Curl_setup_transfer to preserve keepon bits */
2170 conn->writesockfd = conn->sockfd;
2172 /* we want to use the _receiving_ function even when the socket turns
2173 out writableable as the underlying libssh2 recv function will deal
2174 with both accordingly */
2175 conn->cselect_bits = CURL_CSELECT_IN;
2178 /* this should never occur; the close state should be entered
2179 at the time the error occurs */
2180 state(conn, SSH_SFTP_CLOSE);
2181 sshc->actualcode = result;
2184 state(conn, SSH_STOP);
2188 case SSH_SFTP_CLOSE:
2189 if(sshc->sftp_handle) {
2190 rc = libssh2_sftp_close(sshc->sftp_handle);
2191 if(rc == LIBSSH2_ERROR_EAGAIN) {
2195 infof(data, "Failed to close libssh2 file\n");
2197 sshc->sftp_handle = NULL;
2200 Curl_safefree(sftp_scp->path);
2202 DEBUGF(infof(data, "SFTP DONE done\n"));
2204 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2205 After nextstate is executed,the control should come back to
2206 SSH_SFTP_CLOSE to pass the correct result back */
2207 if(sshc->nextstate != SSH_NO_STATE &&
2208 sshc->nextstate != SSH_SFTP_CLOSE) {
2209 state(conn, sshc->nextstate);
2210 sshc->nextstate = SSH_SFTP_CLOSE;
2213 state(conn, SSH_STOP);
2214 result = sshc->actualcode;
2218 case SSH_SFTP_SHUTDOWN:
2219 /* during times we get here due to a broken transfer and then the
2220 sftp_handle might not have been taken down so make sure that is done
2221 before we proceed */
2223 if(sshc->sftp_handle) {
2224 rc = libssh2_sftp_close(sshc->sftp_handle);
2225 if(rc == LIBSSH2_ERROR_EAGAIN) {
2229 infof(data, "Failed to close libssh2 file\n");
2231 sshc->sftp_handle = NULL;
2233 if(sshc->sftp_session) {
2234 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2235 if(rc == LIBSSH2_ERROR_EAGAIN) {
2239 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2241 sshc->sftp_session = NULL;
2244 Curl_safefree(sshc->homedir);
2245 conn->data->state.most_recent_ftp_entrypath = NULL;
2247 state(conn, SSH_SESSION_DISCONNECT);
2250 case SSH_SCP_TRANS_INIT:
2251 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2253 sshc->actualcode = result;
2254 state(conn, SSH_STOP);
2258 if(data->set.upload) {
2259 if(data->state.infilesize < 0) {
2260 failf(data, "SCP requires a known file size for upload");
2261 sshc->actualcode = CURLE_UPLOAD_FAILED;
2262 state(conn, SSH_SCP_CHANNEL_FREE);
2265 state(conn, SSH_SCP_UPLOAD_INIT);
2268 state(conn, SSH_SCP_DOWNLOAD_INIT);
2272 case SSH_SCP_UPLOAD_INIT:
2274 * libssh2 requires that the destination path is a full path that
2275 * includes the destination file and name OR ends in a "/" . If this is
2276 * not done the destination file will be named the same name as the last
2277 * directory in the path.
2280 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2281 data->state.infilesize);
2282 if(!sshc->ssh_channel) {
2283 if(libssh2_session_last_errno(sshc->ssh_session) ==
2284 LIBSSH2_ERROR_EAGAIN) {
2285 rc = LIBSSH2_ERROR_EAGAIN;
2292 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2293 &err_msg, NULL, 0));
2294 failf(conn->data, "%s", err_msg);
2295 state(conn, SSH_SCP_CHANNEL_FREE);
2296 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2302 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2305 /* not set by Curl_setup_transfer to preserve keepon bits */
2306 conn->sockfd = conn->writesockfd;
2309 state(conn, SSH_SCP_CHANNEL_FREE);
2310 sshc->actualcode = result;
2313 /* store this original bitmask setup to use later on if we can't
2314 figure out a "real" bitmask */
2315 sshc->orig_waitfor = data->req.keepon;
2317 /* we want to use the _sending_ function even when the socket turns
2318 out readable as the underlying libssh2 scp send function will deal
2319 with both accordingly */
2320 conn->cselect_bits = CURL_CSELECT_OUT;
2322 state(conn, SSH_STOP);
2326 case SSH_SCP_DOWNLOAD_INIT:
2329 * We must check the remote file; if it is a directory no values will
2333 curl_off_t bytecount;
2335 /* clear the struct scp recv will fill in */
2336 memset(&sb, 0, sizeof(struct stat));
2338 /* get a fresh new channel from the ssh layer */
2339 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2340 sftp_scp->path, &sb);
2341 if(!sshc->ssh_channel) {
2342 if(libssh2_session_last_errno(sshc->ssh_session) ==
2343 LIBSSH2_ERROR_EAGAIN) {
2344 rc = LIBSSH2_ERROR_EAGAIN;
2351 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2352 &err_msg, NULL, 0));
2353 failf(conn->data, "%s", err_msg);
2354 state(conn, SSH_SCP_CHANNEL_FREE);
2355 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2361 bytecount = (curl_off_t)sb.st_size;
2362 data->req.maxdownload = (curl_off_t)sb.st_size;
2363 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2365 /* not set by Curl_setup_transfer to preserve keepon bits */
2366 conn->writesockfd = conn->sockfd;
2368 /* we want to use the _receiving_ function even when the socket turns
2369 out writableable as the underlying libssh2 recv function will deal
2370 with both accordingly */
2371 conn->cselect_bits = CURL_CSELECT_IN;
2374 state(conn, SSH_SCP_CHANNEL_FREE);
2375 sshc->actualcode = result;
2378 state(conn, SSH_STOP);
2383 if(data->set.upload)
2384 state(conn, SSH_SCP_SEND_EOF);
2386 state(conn, SSH_SCP_CHANNEL_FREE);
2389 case SSH_SCP_SEND_EOF:
2390 if(sshc->ssh_channel) {
2391 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2392 if(rc == LIBSSH2_ERROR_EAGAIN) {
2396 infof(data, "Failed to send libssh2 channel EOF\n");
2399 state(conn, SSH_SCP_WAIT_EOF);
2402 case SSH_SCP_WAIT_EOF:
2403 if(sshc->ssh_channel) {
2404 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2405 if(rc == LIBSSH2_ERROR_EAGAIN) {
2409 infof(data, "Failed to get channel EOF: %d\n", rc);
2412 state(conn, SSH_SCP_WAIT_CLOSE);
2415 case SSH_SCP_WAIT_CLOSE:
2416 if(sshc->ssh_channel) {
2417 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2418 if(rc == LIBSSH2_ERROR_EAGAIN) {
2422 infof(data, "Channel failed to close: %d\n", rc);
2425 state(conn, SSH_SCP_CHANNEL_FREE);
2428 case SSH_SCP_CHANNEL_FREE:
2429 if(sshc->ssh_channel) {
2430 rc = libssh2_channel_free(sshc->ssh_channel);
2431 if(rc == LIBSSH2_ERROR_EAGAIN) {
2435 infof(data, "Failed to free libssh2 scp subsystem\n");
2437 sshc->ssh_channel = NULL;
2439 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2441 state(conn, SSH_SESSION_DISCONNECT);
2443 state(conn, SSH_STOP);
2444 result = sshc->actualcode;
2447 case SSH_SESSION_DISCONNECT:
2448 /* during weird times when we've been prematurely aborted, the channel
2449 is still alive when we reach this state and we MUST kill the channel
2451 if(sshc->ssh_channel) {
2452 rc = libssh2_channel_free(sshc->ssh_channel);
2453 if(rc == LIBSSH2_ERROR_EAGAIN) {
2457 infof(data, "Failed to free libssh2 scp subsystem\n");
2459 sshc->ssh_channel = NULL;
2462 if(sshc->ssh_session) {
2463 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2464 if(rc == LIBSSH2_ERROR_EAGAIN) {
2468 infof(data, "Failed to disconnect libssh2 session\n");
2472 Curl_safefree(sshc->homedir);
2473 conn->data->state.most_recent_ftp_entrypath = NULL;
2475 state(conn, SSH_SESSION_FREE);
2478 case SSH_SESSION_FREE:
2479 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2481 libssh2_knownhost_free(sshc->kh);
2486 #ifdef HAVE_LIBSSH2_AGENT_API
2487 if(sshc->ssh_agent) {
2488 rc = libssh2_agent_disconnect(sshc->ssh_agent);
2489 if(rc == LIBSSH2_ERROR_EAGAIN) {
2493 infof(data, "Failed to disconnect from libssh2 agent\n");
2495 libssh2_agent_free (sshc->ssh_agent);
2496 sshc->ssh_agent = NULL;
2498 /* NB: there is no need to free identities, they are part of internal
2500 sshc->sshagent_identity = NULL;
2501 sshc->sshagent_prev_identity = NULL;
2505 if(sshc->ssh_session) {
2506 rc = libssh2_session_free(sshc->ssh_session);
2507 if(rc == LIBSSH2_ERROR_EAGAIN) {
2511 infof(data, "Failed to free libssh2 session\n");
2513 sshc->ssh_session = NULL;
2516 /* worst-case scenario cleanup */
2518 DEBUGASSERT(sshc->ssh_session == NULL);
2519 DEBUGASSERT(sshc->ssh_channel == NULL);
2520 DEBUGASSERT(sshc->sftp_session == NULL);
2521 DEBUGASSERT(sshc->sftp_handle == NULL);
2522 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2523 DEBUGASSERT(sshc->kh == NULL);
2525 #ifdef HAVE_LIBSSH2_AGENT_API
2526 DEBUGASSERT(sshc->ssh_agent == NULL);
2529 Curl_safefree(sshc->rsa_pub);
2530 Curl_safefree(sshc->rsa);
2532 Curl_safefree(sshc->quote_path1);
2533 Curl_safefree(sshc->quote_path2);
2535 Curl_safefree(sshc->homedir);
2537 Curl_safefree(sshc->readdir_filename);
2538 Curl_safefree(sshc->readdir_longentry);
2539 Curl_safefree(sshc->readdir_line);
2540 Curl_safefree(sshc->readdir_linkPath);
2542 /* the code we are about to return */
2543 result = sshc->actualcode;
2545 memset(sshc, 0, sizeof(struct ssh_conn));
2547 connclose(conn, "SSH session free");
2548 sshc->state = SSH_SESSION_FREE; /* current */
2549 sshc->nextstate = SSH_NO_STATE;
2550 state(conn, SSH_STOP);
2554 /* fallthrough, just stop! */
2556 /* internal error */
2557 sshc->nextstate = SSH_NO_STATE;
2558 state(conn, SSH_STOP);
2562 } while(!rc && (sshc->state != SSH_STOP));
2564 if(rc == LIBSSH2_ERROR_EAGAIN) {
2565 /* we would block, we need to wait for the socket to be ready (in the
2566 right direction too)! */
2573 /* called by the multi interface to figure out what socket(s) to wait for and
2574 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2575 static int ssh_perform_getsock(const struct connectdata *conn,
2576 curl_socket_t *sock, /* points to numsocks
2577 number of sockets */
2580 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2581 int bitmap = GETSOCK_BLANK;
2584 sock[0] = conn->sock[FIRSTSOCKET];
2586 if(conn->waitfor & KEEP_RECV)
2587 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2589 if(conn->waitfor & KEEP_SEND)
2590 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2594 /* if we don't know the direction we can use the generic *_getsock()
2595 function even for the protocol_connect and doing states */
2596 return Curl_single_getsock(conn, sock, numsocks);
2600 /* Generic function called by the multi interface to figure out what socket(s)
2601 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2602 static int ssh_getsock(struct connectdata *conn,
2603 curl_socket_t *sock, /* points to numsocks number
2607 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2611 /* if we don't know any direction we can just play along as we used to and
2612 not provide any sensible info */
2613 return GETSOCK_BLANK;
2615 /* if we know the direction we can use the generic *_getsock() function even
2616 for the protocol_connect and doing states */
2617 return ssh_perform_getsock(conn, sock, numsocks);
2621 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2623 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2624 * function is used to figure out in what direction and stores this info so
2625 * that the multi interface can take advantage of it. Make sure to call this
2626 * function in all cases so that when it _doesn't_ return EAGAIN we can
2627 * restore the default wait bits.
2629 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2631 struct ssh_conn *sshc = &conn->proto.sshc;
2633 if(block && (dir = libssh2_session_block_directions(sshc->ssh_session))) {
2634 /* translate the libssh2 define bits into our own bit defines */
2635 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2636 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2639 /* It didn't block or libssh2 didn't reveal in which direction, put back
2641 conn->waitfor = sshc->orig_waitfor;
2644 /* no libssh2 directional support so we simply don't know */
2645 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2648 /* called repeatedly until done from multi.c */
2649 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2651 struct ssh_conn *sshc = &conn->proto.sshc;
2652 CURLcode result = CURLE_OK;
2653 bool block; /* we store the status and use that to provide a ssh_getsock()
2656 result = ssh_statemach_act(conn, &block);
2657 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2658 ssh_block2waitfor(conn, block);
2663 static CURLcode ssh_block_statemach(struct connectdata *conn,
2666 struct ssh_conn *sshc = &conn->proto.sshc;
2667 CURLcode result = CURLE_OK;
2668 struct SessionHandle *data = conn->data;
2670 while((sshc->state != SSH_STOP) && !result) {
2674 result = ssh_statemach_act(conn, &block);
2678 if(Curl_pgrsUpdate(conn))
2679 return CURLE_ABORTED_BY_CALLBACK;
2681 struct timeval now = Curl_tvnow();
2682 result = Curl_speedcheck(data, now);
2687 left = Curl_timeleft(data, NULL, duringconnect);
2689 failf(data, "Operation timed out");
2690 return CURLE_OPERATION_TIMEDOUT;
2693 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2694 if((CURLE_OK == result) && block) {
2695 int dir = libssh2_session_block_directions(sshc->ssh_session);
2696 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2697 curl_socket_t fd_read = CURL_SOCKET_BAD;
2698 curl_socket_t fd_write = CURL_SOCKET_BAD;
2699 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2701 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2703 /* wait for the socket to become ready */
2704 Curl_socket_ready(fd_read, fd_write,
2705 left>1000?1000:left); /* ignore result */
2715 * SSH setup and connection
2717 static CURLcode ssh_setup_connection(struct connectdata *conn)
2719 struct SSHPROTO *ssh;
2721 conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
2723 return CURLE_OUT_OF_MEMORY;
2728 static Curl_recv scp_recv, sftp_recv;
2729 static Curl_send scp_send, sftp_send;
2732 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2733 * do protocol-specific actions at connect-time.
2735 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2737 #ifdef CURL_LIBSSH2_DEBUG
2740 struct ssh_conn *ssh;
2742 struct SessionHandle *data = conn->data;
2744 /* initialize per-handle data if not already */
2745 if(!data->req.protop)
2746 ssh_setup_connection(conn);
2748 /* We default to persistent connections. We set this already in this connect
2749 function to make the re-use checks properly be able to check this bit. */
2750 connkeep(conn, "SSH default");
2752 if(conn->handler->protocol & CURLPROTO_SCP) {
2753 conn->recv[FIRSTSOCKET] = scp_recv;
2754 conn->send[FIRSTSOCKET] = scp_send;
2757 conn->recv[FIRSTSOCKET] = sftp_recv;
2758 conn->send[FIRSTSOCKET] = sftp_send;
2760 ssh = &conn->proto.sshc;
2762 #ifdef CURL_LIBSSH2_DEBUG
2764 infof(data, "User: %s\n", conn->user);
2767 infof(data, "Password: %s\n", conn->passwd);
2769 sock = conn->sock[FIRSTSOCKET];
2770 #endif /* CURL_LIBSSH2_DEBUG */
2772 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2774 my_libssh2_realloc, conn);
2775 if(ssh->ssh_session == NULL) {
2776 failf(data, "Failure initialising ssh session");
2777 return CURLE_FAILED_INIT;
2780 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2781 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2783 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2785 /* eeek. TODO: free the ssh_session! */
2786 return CURLE_FAILED_INIT;
2789 /* read all known hosts from there */
2790 rc = libssh2_knownhost_readfile(ssh->kh,
2791 data->set.str[STRING_SSH_KNOWNHOSTS],
2792 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2794 infof(data, "Failed to read known hosts from %s\n",
2795 data->set.str[STRING_SSH_KNOWNHOSTS]);
2797 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2799 #ifdef CURL_LIBSSH2_DEBUG
2800 libssh2_trace(ssh->ssh_session, ~0);
2801 infof(data, "SSH socket: %d\n", (int)sock);
2802 #endif /* CURL_LIBSSH2_DEBUG */
2804 state(conn, SSH_INIT);
2806 result = ssh_multi_statemach(conn, done);
2812 ***********************************************************************
2816 * This is the actual DO function for SCP. Get a file according to
2817 * the options previously setup.
2821 CURLcode scp_perform(struct connectdata *conn,
2825 CURLcode result = CURLE_OK;
2827 DEBUGF(infof(conn->data, "DO phase starts\n"));
2829 *dophase_done = FALSE; /* not done yet */
2831 /* start the first command in the DO phase */
2832 state(conn, SSH_SCP_TRANS_INIT);
2834 /* run the state-machine */
2835 result = ssh_multi_statemach(conn, dophase_done);
2837 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2840 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2846 /* called from multi.c while DOing */
2847 static CURLcode scp_doing(struct connectdata *conn,
2851 result = ssh_multi_statemach(conn, dophase_done);
2854 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2860 * The DO function is generic for both protocols. There was previously two
2861 * separate ones but this way means less duplicated code.
2864 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2868 struct SessionHandle *data = conn->data;
2869 struct ssh_conn *sshc = &conn->proto.sshc;
2871 *done = FALSE; /* default to false */
2873 data->req.size = -1; /* make sure this is unknown at this point */
2875 sshc->actualcode = CURLE_OK; /* reset error code */
2876 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2879 Curl_pgrsSetUploadCounter(data, 0);
2880 Curl_pgrsSetDownloadCounter(data, 0);
2881 Curl_pgrsSetUploadSize(data, 0);
2882 Curl_pgrsSetDownloadSize(data, 0);
2884 if(conn->handler->protocol & CURLPROTO_SCP)
2885 res = scp_perform(conn, &connected, done);
2887 res = sftp_perform(conn, &connected, done);
2892 /* BLOCKING, but the function is using the state machine so the only reason
2893 this is still blocking is that the multi interface code has no support for
2894 disconnecting operations that takes a while */
2895 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2897 CURLcode result = CURLE_OK;
2898 struct ssh_conn *ssh = &conn->proto.sshc;
2899 (void) dead_connection;
2901 Curl_safefree(conn->data->req.protop);
2903 if(ssh->ssh_session) {
2904 /* only if there's a session still around to use! */
2906 state(conn, SSH_SESSION_DISCONNECT);
2908 result = ssh_block_statemach(conn, FALSE);
2914 /* generic done function for both SCP and SFTP called from their specific
2916 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2918 CURLcode result = CURLE_OK;
2919 struct SSHPROTO *sftp_scp = conn->data->req.protop;
2921 if(status == CURLE_OK) {
2922 /* run the state-machine
2924 TODO: when the multi interface is used, this _really_ should be using
2925 the ssh_multi_statemach function but we have no general support for
2926 non-blocking DONE operations, not in the multi state machine and with
2927 Curl_done() invokes on several places in the code!
2929 result = ssh_block_statemach(conn, FALSE);
2935 Curl_safefree(sftp_scp->path);
2936 if(Curl_pgrsDone(conn))
2937 return CURLE_ABORTED_BY_CALLBACK;
2939 conn->data->req.keepon = 0; /* clear all bits */
2944 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2947 (void)premature; /* not used */
2949 if(status == CURLE_OK)
2950 state(conn, SSH_SCP_DONE);
2952 return ssh_done(conn, status);
2956 /* return number of received (decrypted) bytes */
2957 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2958 const void *mem, size_t len, CURLcode *err)
2961 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2963 /* libssh2_channel_write() returns int! */
2965 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2967 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2969 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2973 else if(nwrite < LIBSSH2_ERROR_NONE) {
2974 *err = libssh2_session_error_to_CURLE((int)nwrite);
2982 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2983 * a regular CURLcode value.
2985 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2986 char *mem, size_t len, CURLcode *err)
2989 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2991 /* libssh2_channel_read() returns int */
2993 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2995 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2996 if(nread == LIBSSH2_ERROR_EAGAIN) {
3005 * =============== SFTP ===============
3009 ***********************************************************************
3013 * This is the actual DO function for SFTP. Get a file/directory according to
3014 * the options previously setup.
3018 CURLcode sftp_perform(struct connectdata *conn,
3022 CURLcode result = CURLE_OK;
3024 DEBUGF(infof(conn->data, "DO phase starts\n"));
3026 *dophase_done = FALSE; /* not done yet */
3028 /* start the first command in the DO phase */
3029 state(conn, SSH_SFTP_QUOTE_INIT);
3031 /* run the state-machine */
3032 result = ssh_multi_statemach(conn, dophase_done);
3034 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3037 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3043 /* called from multi.c while DOing */
3044 static CURLcode sftp_doing(struct connectdata *conn,
3048 result = ssh_multi_statemach(conn, dophase_done);
3051 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3056 /* BLOCKING, but the function is using the state machine so the only reason
3057 this is still blocking is that the multi interface code has no support for
3058 disconnecting operations that takes a while */
3059 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
3061 CURLcode result = CURLE_OK;
3062 (void) dead_connection;
3064 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3066 Curl_safefree(conn->data->req.protop);
3068 if(conn->proto.sshc.ssh_session) {
3069 /* only if there's a session still around to use! */
3070 state(conn, SSH_SFTP_SHUTDOWN);
3071 result = ssh_block_statemach(conn, FALSE);
3074 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3080 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3083 struct ssh_conn *sshc = &conn->proto.sshc;
3085 if(status == CURLE_OK) {
3086 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3087 errors that could happen due to open file handles during POSTQUOTE
3089 if(!status && !premature && conn->data->set.postquote) {
3090 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3091 state(conn, SSH_SFTP_CLOSE);
3094 state(conn, SSH_SFTP_CLOSE);
3096 return ssh_done(conn, status);
3099 /* return number of sent bytes */
3100 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3101 const void *mem, size_t len, CURLcode *err)
3103 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3104 but is changed to ssize_t in 0.15. These days we don't
3105 support libssh2 0.15*/
3108 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3110 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3112 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3116 else if(nwrite < LIBSSH2_ERROR_NONE) {
3117 *err = libssh2_session_error_to_CURLE((int)nwrite);
3125 * Return number of received (decrypted) bytes
3128 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3129 char *mem, size_t len, CURLcode *err)
3134 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3136 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3138 if(nread == LIBSSH2_ERROR_EAGAIN) {
3143 else if(nread < 0) {
3144 *err = libssh2_session_error_to_CURLE((int)nread);
3149 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3152 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3154 * Permission to use, copy, modify, and distribute this software for any
3155 * purpose with or without fee is hereby granted, provided that the above
3156 * copyright notice and this permission notice appear in all copies.
3158 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3159 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3160 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3161 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3162 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3163 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3164 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3167 get_pathname(const char **cpp, char **path)
3169 const char *cp = *cpp, *end;
3172 static const char WHITESPACE[] = " \t\r\n";
3174 cp += strspn(cp, WHITESPACE);
3178 return CURLE_QUOTE_ERROR;
3181 *path = malloc(strlen(cp) + 1);
3183 return CURLE_OUT_OF_MEMORY;
3185 /* Check for quoted filenames */
3186 if(*cp == '\"' || *cp == '\'') {
3189 /* Search for terminating quote, unescape some chars */
3190 for(i = j = 0; i <= strlen(cp); i++) {
3191 if(cp[i] == quot) { /* Found quote */
3196 if(cp[i] == '\0') { /* End of string */
3197 /*error("Unterminated quote");*/
3200 if(cp[i] == '\\') { /* Escaped characters */
3202 if(cp[i] != '\'' && cp[i] != '\"' &&
3204 /*error("Bad escaped character '\\%c'",
3209 (*path)[j++] = cp[i];
3213 /*error("Empty quotes");*/
3216 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3219 /* Read to end of filename */
3220 end = strpbrk(cp, WHITESPACE);
3222 end = strchr(cp, '\0');
3223 *cpp = end + strspn(end, WHITESPACE);
3225 memcpy(*path, cp, end - cp);
3226 (*path)[end - cp] = '\0';
3231 Curl_safefree(*path);
3232 return CURLE_QUOTE_ERROR;
3236 static const char *sftp_libssh2_strerror(int err)
3239 case LIBSSH2_FX_NO_SUCH_FILE:
3240 return "No such file or directory";
3242 case LIBSSH2_FX_PERMISSION_DENIED:
3243 return "Permission denied";
3245 case LIBSSH2_FX_FAILURE:
3246 return "Operation failed";
3248 case LIBSSH2_FX_BAD_MESSAGE:
3249 return "Bad message from SFTP server";
3251 case LIBSSH2_FX_NO_CONNECTION:
3252 return "Not connected to SFTP server";
3254 case LIBSSH2_FX_CONNECTION_LOST:
3255 return "Connection to SFTP server lost";
3257 case LIBSSH2_FX_OP_UNSUPPORTED:
3258 return "Operation not supported by SFTP server";
3260 case LIBSSH2_FX_INVALID_HANDLE:
3261 return "Invalid handle";
3263 case LIBSSH2_FX_NO_SUCH_PATH:
3264 return "No such file or directory";
3266 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3267 return "File already exists";
3269 case LIBSSH2_FX_WRITE_PROTECT:
3270 return "File is write protected";
3272 case LIBSSH2_FX_NO_MEDIA:
3275 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3278 case LIBSSH2_FX_QUOTA_EXCEEDED:
3279 return "User quota exceeded";
3281 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3282 return "Unknown principle";
3284 case LIBSSH2_FX_LOCK_CONFlICT:
3285 return "File lock conflict";
3287 case LIBSSH2_FX_DIR_NOT_EMPTY:
3288 return "Directory not empty";
3290 case LIBSSH2_FX_NOT_A_DIRECTORY:
3291 return "Not a directory";
3293 case LIBSSH2_FX_INVALID_FILENAME:
3294 return "Invalid filename";
3296 case LIBSSH2_FX_LINK_LOOP:
3297 return "Link points to itself";
3299 return "Unknown error in libssh2";
3302 #endif /* USE_LIBSSH2 */