1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2015, 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 https://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"
86 #include "curl_printf.h"
87 #include "curl_memory.h"
88 /* The last #include file should be: */
93 # 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 #ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
547 keycheck = libssh2_knownhost_checkp(sshc->kh,
549 (conn->remote_port != PORT_SSH)?
550 conn->remote_port:-1,
552 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
553 LIBSSH2_KNOWNHOST_KEYENC_RAW|
557 keycheck = libssh2_knownhost_check(sshc->kh,
560 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
561 LIBSSH2_KNOWNHOST_KEYENC_RAW|
566 infof(data, "SSH host check: %d, key: %s\n", keycheck,
567 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
570 /* setup 'knownkey' */
571 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
572 knownkey.key = host->key;
574 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
575 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
576 knownkeyp = &knownkey;
579 /* setup 'foundkey' */
580 foundkey.key = remotekey;
581 foundkey.len = keylen;
582 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
583 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
586 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
587 * curl_khmatch enum are ever modified, we need to introduce a
588 * translation table here!
590 keymatch = (enum curl_khmatch)keycheck;
592 /* Ask the callback how to behave */
593 rc = func(data, knownkeyp, /* from the knownhosts file */
594 &foundkey, /* from the remote host */
595 keymatch, data->set.ssh_keyfunc_userp);
598 /* no remotekey means failure! */
599 rc = CURLKHSTAT_REJECT;
602 default: /* unknown return codes will equal reject */
604 case CURLKHSTAT_REJECT:
605 state(conn, SSH_SESSION_FREE);
607 case CURLKHSTAT_DEFER:
608 /* DEFER means bail out but keep the SSH_HOSTKEY state */
609 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
611 case CURLKHSTAT_FINE:
612 case CURLKHSTAT_FINE_ADD_TO_FILE:
614 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
615 /* the found host+key didn't match but has been told to be fine
616 anyway so we add it in memory */
617 int addrc = libssh2_knownhost_add(sshc->kh,
618 conn->host.name, NULL,
620 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
621 LIBSSH2_KNOWNHOST_KEYENC_RAW|
624 infof(data, "Warning adding the known host %s failed!\n",
626 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
627 /* now we write the entire in-memory list of known hosts to the
630 libssh2_knownhost_writefile(sshc->kh,
631 data->set.str[STRING_SSH_KNOWNHOSTS],
632 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
634 infof(data, "Warning, writing %s failed!\n",
635 data->set.str[STRING_SSH_KNOWNHOSTS]);
642 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
648 static CURLcode ssh_check_fingerprint(struct connectdata *conn)
650 struct ssh_conn *sshc = &conn->proto.sshc;
651 struct SessionHandle *data = conn->data;
652 const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
656 const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
657 LIBSSH2_HOSTKEY_HASH_MD5);
660 /* The fingerprint points to static storage (!), don't free() it. */
661 for(i = 0; i < 16; i++)
662 snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
663 infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
666 /* Before we authenticate we check the hostkey's MD5 fingerprint
667 * against a known fingerprint, if available.
669 if(pubkey_md5 && strlen(pubkey_md5) == 32) {
670 if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
673 "Denied establishing ssh session: mismatch md5 fingerprint. "
674 "Remote %s is not equal to %s", md5buffer, pubkey_md5);
677 "Denied establishing ssh session: md5 fingerprint not available");
678 state(conn, SSH_SESSION_FREE);
679 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
680 return sshc->actualcode;
683 infof(data, "MD5 checksum match!\n");
684 /* as we already matched, we skip the check for known hosts */
689 return ssh_knownhost(conn);
693 * ssh_statemach_act() runs the SSH state machine as far as it can without
694 * blocking and without reaching the end. The data the pointer 'block' points
695 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
696 * meaning it wants to be called again when the socket is ready
699 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
701 CURLcode result = CURLE_OK;
702 struct SessionHandle *data = conn->data;
703 struct SSHPROTO *sftp_scp = data->req.protop;
704 struct ssh_conn *sshc = &conn->proto.sshc;
705 curl_socket_t sock = conn->sock[FIRSTSOCKET];
706 char *new_readdir_line;
707 int rc = LIBSSH2_ERROR_NONE;
709 int seekerr = CURL_SEEKFUNC_OK;
710 *block = 0; /* we're not blocking by default */
714 switch(sshc->state) {
716 sshc->secondCreateDirs = 0;
717 sshc->nextstate = SSH_NO_STATE;
718 sshc->actualcode = CURLE_OK;
720 /* Set libssh2 to non-blocking, since everything internally is
722 libssh2_session_set_blocking(sshc->ssh_session, 0);
724 state(conn, SSH_S_STARTUP);
728 rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
729 if(rc == LIBSSH2_ERROR_EAGAIN) {
733 failf(data, "Failure establishing ssh session");
734 state(conn, SSH_SESSION_FREE);
735 sshc->actualcode = CURLE_FAILED_INIT;
739 state(conn, SSH_HOSTKEY);
744 * Before we authenticate we should check the hostkey's fingerprint
745 * against our known hosts. How that is handled (reading from file,
746 * whatever) is up to us.
748 result = ssh_check_fingerprint(conn);
750 state(conn, SSH_AUTHLIST);
751 /* ssh_check_fingerprint sets state appropriately on error */
756 * Figure out authentication methods
757 * NB: As soon as we have provided a username to an openssh server we
758 * must never change it later. Thus, always specify the correct username
759 * here, even though the libssh2 docs kind of indicate that it should be
760 * possible to get a 'generic' list (not user-specific) of authentication
761 * methods, presumably with a blank username. That won't work in my
763 * So always specify it here.
765 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
767 curlx_uztoui(strlen(conn->user)));
769 if(!sshc->authlist) {
770 if(libssh2_userauth_authenticated(sshc->ssh_session)) {
772 infof(data, "SSH user accepted with no authentication\n");
773 state(conn, SSH_AUTH_DONE);
776 else if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
777 LIBSSH2_ERROR_EAGAIN) {
778 rc = LIBSSH2_ERROR_EAGAIN;
782 state(conn, SSH_SESSION_FREE);
783 sshc->actualcode = libssh2_session_error_to_CURLE(err);
787 infof(data, "SSH authentication methods available: %s\n",
790 state(conn, SSH_AUTH_PKEY_INIT);
793 case SSH_AUTH_PKEY_INIT:
795 * Check the supported auth types in the order I feel is most secure
796 * with the requested type of authentication
798 sshc->authed = FALSE;
800 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
801 (strstr(sshc->authlist, "publickey") != NULL)) {
803 bool out_of_memory = FALSE;
805 sshc->rsa_pub = sshc->rsa = NULL;
807 /* To ponder about: should really the lib be messing about with the
808 HOME environment variable etc? */
809 home = curl_getenv("HOME");
811 if(data->set.str[STRING_SSH_PRIVATE_KEY])
812 sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
814 /* If no private key file is specified, try some common paths. */
816 /* Try ~/.ssh first. */
817 sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
819 out_of_memory = TRUE;
820 else if(access(sshc->rsa, R_OK) != 0) {
821 Curl_safefree(sshc->rsa);
822 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
824 out_of_memory = TRUE;
825 else if(access(sshc->rsa, R_OK) != 0) {
826 Curl_safefree(sshc->rsa);
830 if(!out_of_memory && !sshc->rsa) {
831 /* Nothing found; try the current dir. */
832 sshc->rsa = strdup("id_rsa");
833 if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
834 Curl_safefree(sshc->rsa);
835 sshc->rsa = strdup("id_dsa");
836 if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
837 Curl_safefree(sshc->rsa);
838 /* Out of guesses. Set to the empty string to avoid
839 * surprising info messages. */
840 sshc->rsa = strdup("");
847 * Unless the user explicitly specifies a public key file, let
848 * libssh2 extract the public key from the private key file.
849 * This is done by simply passing sshc->rsa_pub = NULL.
851 if(data->set.str[STRING_SSH_PUBLIC_KEY]
852 /* treat empty string the same way as NULL */
853 && data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
854 sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
856 out_of_memory = TRUE;
859 if(out_of_memory || sshc->rsa == NULL) {
861 Curl_safefree(sshc->rsa);
862 Curl_safefree(sshc->rsa_pub);
863 state(conn, SSH_SESSION_FREE);
864 sshc->actualcode = CURLE_OUT_OF_MEMORY;
868 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
869 if(!sshc->passphrase)
870 sshc->passphrase = "";
875 infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
876 infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
878 state(conn, SSH_AUTH_PKEY);
881 state(conn, SSH_AUTH_PASS_INIT);
886 /* The function below checks if the files exists, no need to stat() here.
888 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
893 sshc->rsa, sshc->passphrase);
894 if(rc == LIBSSH2_ERROR_EAGAIN) {
898 Curl_safefree(sshc->rsa_pub);
899 Curl_safefree(sshc->rsa);
903 infof(data, "Initialized SSH public key authentication\n");
904 state(conn, SSH_AUTH_DONE);
908 (void)libssh2_session_last_error(sshc->ssh_session,
910 infof(data, "SSH public key authentication failed: %s\n", err_msg);
911 state(conn, SSH_AUTH_PASS_INIT);
915 case SSH_AUTH_PASS_INIT:
916 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
917 (strstr(sshc->authlist, "password") != NULL)) {
918 state(conn, SSH_AUTH_PASS);
921 state(conn, SSH_AUTH_HOST_INIT);
926 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
927 curlx_uztoui(strlen(conn->user)),
929 curlx_uztoui(strlen(conn->passwd)),
931 if(rc == LIBSSH2_ERROR_EAGAIN) {
936 infof(data, "Initialized password authentication\n");
937 state(conn, SSH_AUTH_DONE);
940 state(conn, SSH_AUTH_HOST_INIT);
941 rc = 0; /* clear rc and continue */
945 case SSH_AUTH_HOST_INIT:
946 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
947 (strstr(sshc->authlist, "hostbased") != NULL)) {
948 state(conn, SSH_AUTH_HOST);
951 state(conn, SSH_AUTH_AGENT_INIT);
956 state(conn, SSH_AUTH_AGENT_INIT);
959 case SSH_AUTH_AGENT_INIT:
960 #ifdef HAVE_LIBSSH2_AGENT_API
961 if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
962 && (strstr(sshc->authlist, "publickey") != NULL)) {
964 /* Connect to the ssh-agent */
965 /* The agent could be shared by a curl thread i believe
966 but nothing obvious as keys can be added/removed at any time */
967 if(!sshc->ssh_agent) {
968 sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
969 if(!sshc->ssh_agent) {
970 infof(data, "Could not create agent object\n");
972 state(conn, SSH_AUTH_KEY_INIT);
977 rc = libssh2_agent_connect(sshc->ssh_agent);
978 if(rc == LIBSSH2_ERROR_EAGAIN)
981 infof(data, "Failure connecting to agent\n");
982 state(conn, SSH_AUTH_KEY_INIT);
985 state(conn, SSH_AUTH_AGENT_LIST);
989 #endif /* HAVE_LIBSSH2_AGENT_API */
990 state(conn, SSH_AUTH_KEY_INIT);
993 case SSH_AUTH_AGENT_LIST:
994 #ifdef HAVE_LIBSSH2_AGENT_API
995 rc = libssh2_agent_list_identities(sshc->ssh_agent);
997 if(rc == LIBSSH2_ERROR_EAGAIN)
1000 infof(data, "Failure requesting identities to agent\n");
1001 state(conn, SSH_AUTH_KEY_INIT);
1004 state(conn, SSH_AUTH_AGENT);
1005 sshc->sshagent_prev_identity = NULL;
1010 case SSH_AUTH_AGENT:
1011 #ifdef HAVE_LIBSSH2_AGENT_API
1012 /* as prev_identity evolves only after an identity user auth finished we
1013 can safely request it again as long as EAGAIN is returned here or by
1014 libssh2_agent_userauth */
1015 rc = libssh2_agent_get_identity(sshc->ssh_agent,
1016 &sshc->sshagent_identity,
1017 sshc->sshagent_prev_identity);
1018 if(rc == LIBSSH2_ERROR_EAGAIN)
1022 rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
1023 sshc->sshagent_identity);
1026 if(rc != LIBSSH2_ERROR_EAGAIN)
1027 /* tried and failed? go to next identity */
1028 sshc->sshagent_prev_identity = sshc->sshagent_identity;
1035 infof(data, "Failure requesting identities to agent\n");
1037 infof(data, "No identity would match\n");
1039 if(rc == LIBSSH2_ERROR_NONE) {
1040 sshc->authed = TRUE;
1041 infof(data, "Agent based authentication successful\n");
1042 state(conn, SSH_AUTH_DONE);
1045 state(conn, SSH_AUTH_KEY_INIT);
1046 rc = 0; /* clear rc and continue */
1051 case SSH_AUTH_KEY_INIT:
1052 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
1053 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
1054 state(conn, SSH_AUTH_KEY);
1057 state(conn, SSH_AUTH_DONE);
1062 /* Authentication failed. Continue with keyboard-interactive now. */
1063 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
1066 strlen(conn->user)),
1068 if(rc == LIBSSH2_ERROR_EAGAIN) {
1072 sshc->authed = TRUE;
1073 infof(data, "Initialized keyboard interactive authentication\n");
1075 state(conn, SSH_AUTH_DONE);
1080 failf(data, "Authentication failure");
1081 state(conn, SSH_SESSION_FREE);
1082 sshc->actualcode = CURLE_LOGIN_DENIED;
1087 * At this point we have an authenticated ssh session.
1089 infof(data, "Authentication complete\n");
1091 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
1093 conn->sockfd = sock;
1094 conn->writesockfd = CURL_SOCKET_BAD;
1096 if(conn->handler->protocol == CURLPROTO_SFTP) {
1097 state(conn, SSH_SFTP_INIT);
1100 infof(data, "SSH CONNECT phase done\n");
1101 state(conn, SSH_STOP);
1106 * Start the libssh2 sftp session
1108 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
1109 if(!sshc->sftp_session) {
1110 if(libssh2_session_last_errno(sshc->ssh_session) ==
1111 LIBSSH2_ERROR_EAGAIN) {
1112 rc = LIBSSH2_ERROR_EAGAIN;
1118 (void)libssh2_session_last_error(sshc->ssh_session,
1120 failf(data, "Failure initializing sftp session: %s", err_msg);
1121 state(conn, SSH_SESSION_FREE);
1122 sshc->actualcode = CURLE_FAILED_INIT;
1126 state(conn, SSH_SFTP_REALPATH);
1129 case SSH_SFTP_REALPATH:
1131 char tempHome[PATH_MAX];
1134 * Get the "home" directory
1136 rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
1137 tempHome, PATH_MAX-1);
1138 if(rc == LIBSSH2_ERROR_EAGAIN) {
1142 /* It seems that this string is not always NULL terminated */
1143 tempHome[rc] = '\0';
1144 sshc->homedir = strdup(tempHome);
1145 if(!sshc->homedir) {
1146 state(conn, SSH_SFTP_CLOSE);
1147 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1150 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1153 /* Return the error type */
1154 err = sftp_libssh2_last_error(sshc->sftp_session);
1155 result = sftp_libssh2_error_to_CURLE(err);
1156 sshc->actualcode = result?result:CURLE_SSH;
1157 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1159 state(conn, SSH_STOP);
1163 /* This is the last step in the SFTP connect phase. Do note that while
1164 we get the homedir here, we get the "workingpath" in the DO action
1165 since the homedir will remain the same between request but the
1166 working path will not. */
1167 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1168 state(conn, SSH_STOP);
1171 case SSH_SFTP_QUOTE_INIT:
1173 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1175 sshc->actualcode = result;
1176 state(conn, SSH_STOP);
1180 if(data->set.quote) {
1181 infof(data, "Sending quote commands\n");
1182 sshc->quote_item = data->set.quote;
1183 state(conn, SSH_SFTP_QUOTE);
1186 state(conn, SSH_SFTP_TRANS_INIT);
1190 case SSH_SFTP_POSTQUOTE_INIT:
1191 if(data->set.postquote) {
1192 infof(data, "Sending quote commands\n");
1193 sshc->quote_item = data->set.postquote;
1194 state(conn, SSH_SFTP_QUOTE);
1197 state(conn, SSH_STOP);
1201 case SSH_SFTP_QUOTE:
1202 /* Send any quote commands */
1207 * Support some of the "FTP" commands
1209 char *cmd = sshc->quote_item->data;
1210 sshc->acceptfail = FALSE;
1212 /* if a command starts with an asterisk, which a legal SFTP command never
1213 can, the command will be allowed to fail without it causing any
1214 aborts or cancels etc. It will cause libcurl to act as if the command
1215 is successful, whatever the server reponds. */
1219 sshc->acceptfail = TRUE;
1222 if(curl_strequal("pwd", cmd)) {
1223 /* output debug output if that is requested */
1224 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1227 result = CURLE_OUT_OF_MEMORY;
1228 state(conn, SSH_SFTP_CLOSE);
1229 sshc->nextstate = SSH_NO_STATE;
1232 if(data->set.verbose) {
1233 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1234 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1236 /* this sends an FTP-like "header" to the header callback so that the
1237 current directory can be read very similar to how it is read when
1238 using ordinary FTP. */
1239 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1242 state(conn, SSH_SFTP_CLOSE);
1243 sshc->nextstate = SSH_NO_STATE;
1244 sshc->actualcode = result;
1247 state(conn, SSH_SFTP_NEXT_QUOTE);
1252 * the arguments following the command must be separated from the
1253 * command with a space so we can check for it unconditionally
1255 cp = strchr(cmd, ' ');
1257 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1258 state(conn, SSH_SFTP_CLOSE);
1259 sshc->nextstate = SSH_NO_STATE;
1260 sshc->actualcode = CURLE_QUOTE_ERROR;
1265 * also, every command takes at least one argument so we get that
1266 * first argument right now
1268 result = get_pathname(&cp, &sshc->quote_path1);
1270 if(result == CURLE_OUT_OF_MEMORY)
1271 failf(data, "Out of memory");
1273 failf(data, "Syntax error: Bad first parameter");
1274 state(conn, SSH_SFTP_CLOSE);
1275 sshc->nextstate = SSH_NO_STATE;
1276 sshc->actualcode = result;
1281 * SFTP is a binary protocol, so we don't send text commands
1282 * to the server. Instead, we scan for commands used by
1283 * OpenSSH's sftp program and call the appropriate libssh2
1286 if(curl_strnequal(cmd, "chgrp ", 6) ||
1287 curl_strnequal(cmd, "chmod ", 6) ||
1288 curl_strnequal(cmd, "chown ", 6) ) {
1289 /* attribute change */
1291 /* sshc->quote_path1 contains the mode to set */
1292 /* get the destination */
1293 result = get_pathname(&cp, &sshc->quote_path2);
1295 if(result == CURLE_OUT_OF_MEMORY)
1296 failf(data, "Out of memory");
1298 failf(data, "Syntax error in chgrp/chmod/chown: "
1299 "Bad second parameter");
1300 Curl_safefree(sshc->quote_path1);
1301 state(conn, SSH_SFTP_CLOSE);
1302 sshc->nextstate = SSH_NO_STATE;
1303 sshc->actualcode = result;
1306 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1307 state(conn, SSH_SFTP_QUOTE_STAT);
1310 else if(curl_strnequal(cmd, "ln ", 3) ||
1311 curl_strnequal(cmd, "symlink ", 8)) {
1312 /* symbolic linking */
1313 /* sshc->quote_path1 is the source */
1314 /* get the destination */
1315 result = get_pathname(&cp, &sshc->quote_path2);
1317 if(result == CURLE_OUT_OF_MEMORY)
1318 failf(data, "Out of memory");
1321 "Syntax error in ln/symlink: Bad second parameter");
1322 Curl_safefree(sshc->quote_path1);
1323 state(conn, SSH_SFTP_CLOSE);
1324 sshc->nextstate = SSH_NO_STATE;
1325 sshc->actualcode = result;
1328 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1331 else if(curl_strnequal(cmd, "mkdir ", 6)) {
1333 state(conn, SSH_SFTP_QUOTE_MKDIR);
1336 else if(curl_strnequal(cmd, "rename ", 7)) {
1338 /* first param is the source path */
1339 /* second param is the dest. path */
1340 result = get_pathname(&cp, &sshc->quote_path2);
1342 if(result == CURLE_OUT_OF_MEMORY)
1343 failf(data, "Out of memory");
1345 failf(data, "Syntax error in rename: Bad second parameter");
1346 Curl_safefree(sshc->quote_path1);
1347 state(conn, SSH_SFTP_CLOSE);
1348 sshc->nextstate = SSH_NO_STATE;
1349 sshc->actualcode = result;
1352 state(conn, SSH_SFTP_QUOTE_RENAME);
1355 else if(curl_strnequal(cmd, "rmdir ", 6)) {
1357 state(conn, SSH_SFTP_QUOTE_RMDIR);
1360 else if(curl_strnequal(cmd, "rm ", 3)) {
1361 state(conn, SSH_SFTP_QUOTE_UNLINK);
1365 failf(data, "Unknown SFTP command");
1366 Curl_safefree(sshc->quote_path1);
1367 Curl_safefree(sshc->quote_path2);
1368 state(conn, SSH_SFTP_CLOSE);
1369 sshc->nextstate = SSH_NO_STATE;
1370 sshc->actualcode = CURLE_QUOTE_ERROR;
1374 if(!sshc->quote_item) {
1375 state(conn, SSH_SFTP_TRANS_INIT);
1379 case SSH_SFTP_NEXT_QUOTE:
1380 Curl_safefree(sshc->quote_path1);
1381 Curl_safefree(sshc->quote_path2);
1383 sshc->quote_item = sshc->quote_item->next;
1385 if(sshc->quote_item) {
1386 state(conn, SSH_SFTP_QUOTE);
1389 if(sshc->nextstate != SSH_NO_STATE) {
1390 state(conn, sshc->nextstate);
1391 sshc->nextstate = SSH_NO_STATE;
1394 state(conn, SSH_SFTP_TRANS_INIT);
1399 case SSH_SFTP_QUOTE_STAT:
1401 char *cmd = sshc->quote_item->data;
1402 sshc->acceptfail = FALSE;
1404 /* if a command starts with an asterisk, which a legal SFTP command never
1405 can, the command will be allowed to fail without it causing any
1406 aborts or cancels etc. It will cause libcurl to act as if the command
1407 is successful, whatever the server reponds. */
1411 sshc->acceptfail = TRUE;
1414 if(!curl_strnequal(cmd, "chmod", 5)) {
1415 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1416 * set them both at once, we need to obtain the current ownership
1417 * first. This takes an extra protocol round trip.
1419 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1420 curlx_uztoui(strlen(sshc->quote_path2)),
1422 &sshc->quote_attrs);
1423 if(rc == LIBSSH2_ERROR_EAGAIN) {
1426 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1427 err = sftp_libssh2_last_error(sshc->sftp_session);
1428 Curl_safefree(sshc->quote_path1);
1429 Curl_safefree(sshc->quote_path2);
1430 failf(data, "Attempt to get SFTP stats failed: %s",
1431 sftp_libssh2_strerror(err));
1432 state(conn, SSH_SFTP_CLOSE);
1433 sshc->nextstate = SSH_NO_STATE;
1434 sshc->actualcode = CURLE_QUOTE_ERROR;
1439 /* Now set the new attributes... */
1440 if(curl_strnequal(cmd, "chgrp", 5)) {
1441 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1442 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1443 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1444 !sshc->acceptfail) {
1445 Curl_safefree(sshc->quote_path1);
1446 Curl_safefree(sshc->quote_path2);
1447 failf(data, "Syntax error: chgrp gid not a number");
1448 state(conn, SSH_SFTP_CLOSE);
1449 sshc->nextstate = SSH_NO_STATE;
1450 sshc->actualcode = CURLE_QUOTE_ERROR;
1454 else if(curl_strnequal(cmd, "chmod", 5)) {
1455 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1456 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1457 /* permissions are octal */
1458 if(sshc->quote_attrs.permissions == 0 &&
1459 !ISDIGIT(sshc->quote_path1[0])) {
1460 Curl_safefree(sshc->quote_path1);
1461 Curl_safefree(sshc->quote_path2);
1462 failf(data, "Syntax error: chmod permissions not a number");
1463 state(conn, SSH_SFTP_CLOSE);
1464 sshc->nextstate = SSH_NO_STATE;
1465 sshc->actualcode = CURLE_QUOTE_ERROR;
1469 else if(curl_strnequal(cmd, "chown", 5)) {
1470 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1471 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1472 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1473 !sshc->acceptfail) {
1474 Curl_safefree(sshc->quote_path1);
1475 Curl_safefree(sshc->quote_path2);
1476 failf(data, "Syntax error: chown uid not a number");
1477 state(conn, SSH_SFTP_CLOSE);
1478 sshc->nextstate = SSH_NO_STATE;
1479 sshc->actualcode = CURLE_QUOTE_ERROR;
1484 /* Now send the completed structure... */
1485 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1489 case SSH_SFTP_QUOTE_SETSTAT:
1490 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1491 curlx_uztoui(strlen(sshc->quote_path2)),
1492 LIBSSH2_SFTP_SETSTAT,
1493 &sshc->quote_attrs);
1494 if(rc == LIBSSH2_ERROR_EAGAIN) {
1497 else if(rc != 0 && !sshc->acceptfail) {
1498 err = sftp_libssh2_last_error(sshc->sftp_session);
1499 Curl_safefree(sshc->quote_path1);
1500 Curl_safefree(sshc->quote_path2);
1501 failf(data, "Attempt to set SFTP stats failed: %s",
1502 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_SYMLINK:
1512 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1513 curlx_uztoui(strlen(sshc->quote_path1)),
1515 curlx_uztoui(strlen(sshc->quote_path2)),
1516 LIBSSH2_SFTP_SYMLINK);
1517 if(rc == LIBSSH2_ERROR_EAGAIN) {
1520 else if(rc != 0 && !sshc->acceptfail) {
1521 err = sftp_libssh2_last_error(sshc->sftp_session);
1522 Curl_safefree(sshc->quote_path1);
1523 Curl_safefree(sshc->quote_path2);
1524 failf(data, "symlink command failed: %s",
1525 sftp_libssh2_strerror(err));
1526 state(conn, SSH_SFTP_CLOSE);
1527 sshc->nextstate = SSH_NO_STATE;
1528 sshc->actualcode = CURLE_QUOTE_ERROR;
1531 state(conn, SSH_SFTP_NEXT_QUOTE);
1534 case SSH_SFTP_QUOTE_MKDIR:
1535 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1536 curlx_uztoui(strlen(sshc->quote_path1)),
1537 data->set.new_directory_perms);
1538 if(rc == LIBSSH2_ERROR_EAGAIN) {
1541 else if(rc != 0 && !sshc->acceptfail) {
1542 err = sftp_libssh2_last_error(sshc->sftp_session);
1543 Curl_safefree(sshc->quote_path1);
1544 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1545 state(conn, SSH_SFTP_CLOSE);
1546 sshc->nextstate = SSH_NO_STATE;
1547 sshc->actualcode = CURLE_QUOTE_ERROR;
1550 state(conn, SSH_SFTP_NEXT_QUOTE);
1553 case SSH_SFTP_QUOTE_RENAME:
1554 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1555 curlx_uztoui(strlen(sshc->quote_path1)),
1557 curlx_uztoui(strlen(sshc->quote_path2)),
1558 LIBSSH2_SFTP_RENAME_OVERWRITE |
1559 LIBSSH2_SFTP_RENAME_ATOMIC |
1560 LIBSSH2_SFTP_RENAME_NATIVE);
1562 if(rc == LIBSSH2_ERROR_EAGAIN) {
1565 else if(rc != 0 && !sshc->acceptfail) {
1566 err = sftp_libssh2_last_error(sshc->sftp_session);
1567 Curl_safefree(sshc->quote_path1);
1568 Curl_safefree(sshc->quote_path2);
1569 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1570 state(conn, SSH_SFTP_CLOSE);
1571 sshc->nextstate = SSH_NO_STATE;
1572 sshc->actualcode = CURLE_QUOTE_ERROR;
1575 state(conn, SSH_SFTP_NEXT_QUOTE);
1578 case SSH_SFTP_QUOTE_RMDIR:
1579 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1580 curlx_uztoui(strlen(sshc->quote_path1)));
1581 if(rc == LIBSSH2_ERROR_EAGAIN) {
1584 else if(rc != 0 && !sshc->acceptfail) {
1585 err = sftp_libssh2_last_error(sshc->sftp_session);
1586 Curl_safefree(sshc->quote_path1);
1587 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1588 state(conn, SSH_SFTP_CLOSE);
1589 sshc->nextstate = SSH_NO_STATE;
1590 sshc->actualcode = CURLE_QUOTE_ERROR;
1593 state(conn, SSH_SFTP_NEXT_QUOTE);
1596 case SSH_SFTP_QUOTE_UNLINK:
1597 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1598 curlx_uztoui(strlen(sshc->quote_path1)));
1599 if(rc == LIBSSH2_ERROR_EAGAIN) {
1602 else if(rc != 0 && !sshc->acceptfail) {
1603 err = sftp_libssh2_last_error(sshc->sftp_session);
1604 Curl_safefree(sshc->quote_path1);
1605 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1606 state(conn, SSH_SFTP_CLOSE);
1607 sshc->nextstate = SSH_NO_STATE;
1608 sshc->actualcode = CURLE_QUOTE_ERROR;
1611 state(conn, SSH_SFTP_NEXT_QUOTE);
1614 case SSH_SFTP_TRANS_INIT:
1615 if(data->set.upload)
1616 state(conn, SSH_SFTP_UPLOAD_INIT);
1618 if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1619 state(conn, SSH_SFTP_READDIR_INIT);
1621 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1625 case SSH_SFTP_UPLOAD_INIT:
1627 unsigned long flags;
1629 * NOTE!!! libssh2 requires that the destination path is a full path
1630 * that includes the destination file and name OR ends in a "/"
1631 * If this is not done the destination file will be named the
1632 * same name as the last directory in the path.
1635 if(data->state.resume_from != 0) {
1636 LIBSSH2_SFTP_ATTRIBUTES attrs;
1637 if(data->state.resume_from < 0) {
1638 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1639 curlx_uztoui(strlen(sftp_scp->path)),
1640 LIBSSH2_SFTP_STAT, &attrs);
1641 if(rc == LIBSSH2_ERROR_EAGAIN) {
1645 data->state.resume_from = 0;
1648 curl_off_t size = attrs.filesize;
1650 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
1651 return CURLE_BAD_DOWNLOAD_RESUME;
1653 data->state.resume_from = attrs.filesize;
1658 if(data->set.ftp_append)
1659 /* Try to open for append, but create if nonexisting */
1660 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1661 else if(data->state.resume_from > 0)
1662 /* If we have restart position then open for append */
1663 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1665 /* Clear file before writing (normal behaviour) */
1666 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1669 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1670 curlx_uztoui(strlen(sftp_scp->path)),
1671 flags, data->set.new_file_perms,
1672 LIBSSH2_SFTP_OPENFILE);
1674 if(!sshc->sftp_handle) {
1675 rc = libssh2_session_last_errno(sshc->ssh_session);
1677 if(LIBSSH2_ERROR_EAGAIN == rc)
1680 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1681 /* only when there was an SFTP protocol error can we extract
1683 err = sftp_libssh2_last_error(sshc->sftp_session);
1685 err = -1; /* not an sftp error at all */
1687 if(sshc->secondCreateDirs) {
1688 state(conn, SSH_SFTP_CLOSE);
1689 sshc->actualcode = err>= LIBSSH2_FX_OK?
1690 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1691 failf(data, "Creating the dir/file failed: %s",
1692 sftp_libssh2_strerror(err));
1695 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1696 (err == LIBSSH2_FX_FAILURE) ||
1697 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1698 (data->set.ftp_create_missing_dirs &&
1699 (strlen(sftp_scp->path) > 1))) {
1700 /* try to create the path remotely */
1701 sshc->secondCreateDirs = 1;
1702 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1705 state(conn, SSH_SFTP_CLOSE);
1706 sshc->actualcode = err>= LIBSSH2_FX_OK?
1707 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1708 if(!sshc->actualcode) {
1709 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1710 zero even though libssh2_sftp_open() failed previously! We need
1711 to work around that! */
1712 sshc->actualcode = CURLE_SSH;
1715 failf(data, "Upload failed: %s (%d/%d)",
1716 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1722 /* If we have a restart point then we need to seek to the correct
1724 if(data->state.resume_from > 0) {
1725 /* Let's read off the proper amount of bytes from the input. */
1726 if(conn->seek_func) {
1727 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1731 if(seekerr != CURL_SEEKFUNC_OK) {
1733 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1734 failf(data, "Could not seek stream");
1735 return CURLE_FTP_COULDNT_USE_REST;
1737 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1739 curl_off_t passed=0;
1741 size_t readthisamountnow =
1742 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1743 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1745 size_t actuallyread =
1746 data->state.fread_func(data->state.buffer, 1,
1747 readthisamountnow, data->state.in);
1749 passed += actuallyread;
1750 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1751 /* this checks for greater-than only to make sure that the
1752 CURL_READFUNC_ABORT return code still aborts */
1753 failf(data, "Failed to read data");
1754 return CURLE_FTP_COULDNT_USE_REST;
1756 } while(passed < data->state.resume_from);
1760 /* now, decrease the size of the read */
1761 if(data->state.infilesize > 0) {
1762 data->state.infilesize -= data->state.resume_from;
1763 data->req.size = data->state.infilesize;
1764 Curl_pgrsSetUploadSize(data, data->state.infilesize);
1767 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1769 if(data->state.infilesize > 0) {
1770 data->req.size = data->state.infilesize;
1771 Curl_pgrsSetUploadSize(data, data->state.infilesize);
1774 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1776 /* not set by Curl_setup_transfer to preserve keepon bits */
1777 conn->sockfd = conn->writesockfd;
1780 state(conn, SSH_SFTP_CLOSE);
1781 sshc->actualcode = result;
1784 /* store this original bitmask setup to use later on if we can't
1785 figure out a "real" bitmask */
1786 sshc->orig_waitfor = data->req.keepon;
1788 /* we want to use the _sending_ function even when the socket turns
1789 out readable as the underlying libssh2 sftp send function will deal
1790 with both accordingly */
1791 conn->cselect_bits = CURL_CSELECT_OUT;
1793 /* since we don't really wait for anything at this point, we want the
1794 state machine to move on as soon as possible so we set a very short
1796 Curl_expire(data, 1);
1798 state(conn, SSH_STOP);
1803 case SSH_SFTP_CREATE_DIRS_INIT:
1804 if(strlen(sftp_scp->path) > 1) {
1805 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1806 state(conn, SSH_SFTP_CREATE_DIRS);
1809 state(conn, SSH_SFTP_UPLOAD_INIT);
1813 case SSH_SFTP_CREATE_DIRS:
1814 sshc->slash_pos = strchr(sshc->slash_pos, '/');
1815 if(sshc->slash_pos) {
1816 *sshc->slash_pos = 0;
1818 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1819 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1823 state(conn, SSH_SFTP_UPLOAD_INIT);
1827 case SSH_SFTP_CREATE_DIRS_MKDIR:
1828 /* 'mode' - parameter is preliminary - default to 0644 */
1829 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1830 curlx_uztoui(strlen(sftp_scp->path)),
1831 data->set.new_directory_perms);
1832 if(rc == LIBSSH2_ERROR_EAGAIN) {
1835 *sshc->slash_pos = '/';
1839 * Abort if failure wasn't that the dir already exists or the
1840 * permission was denied (creation might succeed further down the
1841 * path) - retry on unspecific FAILURE also
1843 err = sftp_libssh2_last_error(sshc->sftp_session);
1844 if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1845 (err != LIBSSH2_FX_FAILURE) &&
1846 (err != LIBSSH2_FX_PERMISSION_DENIED)) {
1847 result = sftp_libssh2_error_to_CURLE(err);
1848 state(conn, SSH_SFTP_CLOSE);
1849 sshc->actualcode = result?result:CURLE_SSH;
1853 state(conn, SSH_SFTP_CREATE_DIRS);
1856 case SSH_SFTP_READDIR_INIT:
1857 Curl_pgrsSetDownloadSize(data, -1);
1858 if(data->set.opt_no_body) {
1859 state(conn, SSH_STOP);
1864 * This is a directory that we are trying to get, so produce a directory
1867 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1870 strlen(sftp_scp->path)),
1871 0, 0, LIBSSH2_SFTP_OPENDIR);
1872 if(!sshc->sftp_handle) {
1873 if(libssh2_session_last_errno(sshc->ssh_session) ==
1874 LIBSSH2_ERROR_EAGAIN) {
1875 rc = LIBSSH2_ERROR_EAGAIN;
1879 err = sftp_libssh2_last_error(sshc->sftp_session);
1880 failf(data, "Could not open directory for reading: %s",
1881 sftp_libssh2_strerror(err));
1882 state(conn, SSH_SFTP_CLOSE);
1883 result = sftp_libssh2_error_to_CURLE(err);
1884 sshc->actualcode = result?result:CURLE_SSH;
1888 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1889 state(conn, SSH_SFTP_CLOSE);
1890 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1893 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1894 Curl_safefree(sshc->readdir_filename);
1895 state(conn, SSH_SFTP_CLOSE);
1896 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1899 state(conn, SSH_SFTP_READDIR);
1902 case SSH_SFTP_READDIR:
1903 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1904 sshc->readdir_filename,
1906 sshc->readdir_longentry,
1908 &sshc->readdir_attrs);
1909 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1910 rc = LIBSSH2_ERROR_EAGAIN;
1913 if(sshc->readdir_len > 0) {
1914 sshc->readdir_filename[sshc->readdir_len] = '\0';
1916 if(data->set.ftp_list_only) {
1919 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1920 if(tmpLine == NULL) {
1921 state(conn, SSH_SFTP_CLOSE);
1922 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1925 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1926 tmpLine, sshc->readdir_len+1);
1930 state(conn, SSH_STOP);
1933 /* since this counts what we send to the client, we include the
1934 newline in this counter */
1935 data->req.bytecount += sshc->readdir_len+1;
1937 /* output debug output if that is requested */
1938 if(data->set.verbose) {
1939 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1940 sshc->readdir_len, conn);
1944 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1945 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1946 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1947 if(!sshc->readdir_line) {
1948 Curl_safefree(sshc->readdir_filename);
1949 Curl_safefree(sshc->readdir_longentry);
1950 state(conn, SSH_SFTP_CLOSE);
1951 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1955 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1956 sshc->readdir_currLen);
1957 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1958 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1959 LIBSSH2_SFTP_S_IFLNK)) {
1960 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1961 if(sshc->readdir_linkPath == NULL) {
1962 Curl_safefree(sshc->readdir_filename);
1963 Curl_safefree(sshc->readdir_longentry);
1964 state(conn, SSH_SFTP_CLOSE);
1965 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1969 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1970 sshc->readdir_filename);
1971 state(conn, SSH_SFTP_READDIR_LINK);
1974 state(conn, SSH_SFTP_READDIR_BOTTOM);
1978 else if(sshc->readdir_len == 0) {
1979 Curl_safefree(sshc->readdir_filename);
1980 Curl_safefree(sshc->readdir_longentry);
1981 state(conn, SSH_SFTP_READDIR_DONE);
1984 else if(sshc->readdir_len <= 0) {
1985 err = sftp_libssh2_last_error(sshc->sftp_session);
1986 result = sftp_libssh2_error_to_CURLE(err);
1987 sshc->actualcode = result?result:CURLE_SSH;
1988 failf(data, "Could not open remote file for reading: %s :: %d",
1989 sftp_libssh2_strerror(err),
1990 libssh2_session_last_errno(sshc->ssh_session));
1991 Curl_safefree(sshc->readdir_filename);
1992 Curl_safefree(sshc->readdir_longentry);
1993 state(conn, SSH_SFTP_CLOSE);
1998 case SSH_SFTP_READDIR_LINK:
2000 libssh2_sftp_symlink_ex(sshc->sftp_session,
2001 sshc->readdir_linkPath,
2002 curlx_uztoui(strlen(sshc->readdir_linkPath)),
2003 sshc->readdir_filename,
2004 PATH_MAX, LIBSSH2_SFTP_READLINK);
2005 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
2006 rc = LIBSSH2_ERROR_EAGAIN;
2009 Curl_safefree(sshc->readdir_linkPath);
2011 /* get room for the filename and extra output */
2012 sshc->readdir_totalLen += 4 + sshc->readdir_len;
2013 new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
2014 if(!new_readdir_line) {
2015 Curl_safefree(sshc->readdir_line);
2016 Curl_safefree(sshc->readdir_filename);
2017 Curl_safefree(sshc->readdir_longentry);
2018 state(conn, SSH_SFTP_CLOSE);
2019 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2022 sshc->readdir_line = new_readdir_line;
2024 sshc->readdir_currLen += snprintf(sshc->readdir_line +
2025 sshc->readdir_currLen,
2026 sshc->readdir_totalLen -
2027 sshc->readdir_currLen,
2029 sshc->readdir_filename);
2031 state(conn, SSH_SFTP_READDIR_BOTTOM);
2034 case SSH_SFTP_READDIR_BOTTOM:
2035 sshc->readdir_currLen += snprintf(sshc->readdir_line +
2036 sshc->readdir_currLen,
2037 sshc->readdir_totalLen -
2038 sshc->readdir_currLen, "\n");
2039 result = Curl_client_write(conn, CLIENTWRITE_BODY,
2041 sshc->readdir_currLen);
2045 /* output debug output if that is requested */
2046 if(data->set.verbose) {
2047 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
2048 sshc->readdir_currLen, conn);
2050 data->req.bytecount += sshc->readdir_currLen;
2052 Curl_safefree(sshc->readdir_line);
2054 state(conn, SSH_STOP);
2057 state(conn, SSH_SFTP_READDIR);
2060 case SSH_SFTP_READDIR_DONE:
2061 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
2062 LIBSSH2_ERROR_EAGAIN) {
2063 rc = LIBSSH2_ERROR_EAGAIN;
2066 sshc->sftp_handle = NULL;
2067 Curl_safefree(sshc->readdir_filename);
2068 Curl_safefree(sshc->readdir_longentry);
2070 /* no data to transfer */
2071 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2072 state(conn, SSH_STOP);
2075 case SSH_SFTP_DOWNLOAD_INIT:
2077 * Work on getting the specified file
2080 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
2081 curlx_uztoui(strlen(sftp_scp->path)),
2082 LIBSSH2_FXF_READ, data->set.new_file_perms,
2083 LIBSSH2_SFTP_OPENFILE);
2084 if(!sshc->sftp_handle) {
2085 if(libssh2_session_last_errno(sshc->ssh_session) ==
2086 LIBSSH2_ERROR_EAGAIN) {
2087 rc = LIBSSH2_ERROR_EAGAIN;
2091 err = sftp_libssh2_last_error(sshc->sftp_session);
2092 failf(data, "Could not open remote file for reading: %s",
2093 sftp_libssh2_strerror(err));
2094 state(conn, SSH_SFTP_CLOSE);
2095 result = sftp_libssh2_error_to_CURLE(err);
2096 sshc->actualcode = result?result:CURLE_SSH;
2100 state(conn, SSH_SFTP_DOWNLOAD_STAT);
2103 case SSH_SFTP_DOWNLOAD_STAT:
2105 LIBSSH2_SFTP_ATTRIBUTES attrs;
2107 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
2108 curlx_uztoui(strlen(sftp_scp->path)),
2109 LIBSSH2_SFTP_STAT, &attrs);
2110 if(rc == LIBSSH2_ERROR_EAGAIN) {
2114 !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
2115 (attrs.filesize == 0)) {
2117 * libssh2_sftp_open() didn't return an error, so maybe the server
2118 * just doesn't support stat()
2119 * OR the server doesn't return a file size with a stat()
2122 data->req.size = -1;
2123 data->req.maxdownload = -1;
2124 Curl_pgrsSetDownloadSize(data, -1);
2127 curl_off_t size = attrs.filesize;
2130 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
2131 return CURLE_BAD_DOWNLOAD_RESUME;
2133 if(conn->data->state.use_range) {
2134 curl_off_t from, to;
2138 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2139 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2141 to=curlx_strtoofft(ptr, &ptr2, 0);
2142 if((ptr == ptr2) /* no "to" value given */
2147 /* from is relative to end of file */
2151 failf(data, "Offset (%"
2152 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2153 CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
2154 return CURLE_BAD_DOWNLOAD_RESUME;
2161 size = to - from + 1;
2164 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2166 data->req.size = size;
2167 data->req.maxdownload = size;
2168 Curl_pgrsSetDownloadSize(data, size);
2171 /* We can resume if we can seek to the resume position */
2172 if(data->state.resume_from) {
2173 if(data->state.resume_from < 0) {
2174 /* We're supposed to download the last abs(from) bytes */
2175 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2176 failf(data, "Offset (%"
2177 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2178 CURL_FORMAT_CURL_OFF_T ")",
2179 data->state.resume_from, attrs.filesize);
2180 return CURLE_BAD_DOWNLOAD_RESUME;
2182 /* download from where? */
2183 data->state.resume_from += attrs.filesize;
2186 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2187 failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
2188 ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
2189 data->state.resume_from, attrs.filesize);
2190 return CURLE_BAD_DOWNLOAD_RESUME;
2193 /* Does a completed file need to be seeked and started or closed ? */
2194 /* Now store the number of bytes we are expected to download */
2195 data->req.size = attrs.filesize - data->state.resume_from;
2196 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2197 Curl_pgrsSetDownloadSize(data,
2198 attrs.filesize - data->state.resume_from);
2199 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2203 /* Setup the actual download */
2204 if(data->req.size == 0) {
2205 /* no data to transfer */
2206 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2207 infof(data, "File already completely downloaded\n");
2208 state(conn, SSH_STOP);
2212 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2213 FALSE, NULL, -1, NULL);
2215 /* not set by Curl_setup_transfer to preserve keepon bits */
2216 conn->writesockfd = conn->sockfd;
2218 /* we want to use the _receiving_ function even when the socket turns
2219 out writableable as the underlying libssh2 recv function will deal
2220 with both accordingly */
2221 conn->cselect_bits = CURL_CSELECT_IN;
2224 /* this should never occur; the close state should be entered
2225 at the time the error occurs */
2226 state(conn, SSH_SFTP_CLOSE);
2227 sshc->actualcode = result;
2230 state(conn, SSH_STOP);
2234 case SSH_SFTP_CLOSE:
2235 if(sshc->sftp_handle) {
2236 rc = libssh2_sftp_close(sshc->sftp_handle);
2237 if(rc == LIBSSH2_ERROR_EAGAIN) {
2241 infof(data, "Failed to close libssh2 file\n");
2243 sshc->sftp_handle = NULL;
2246 Curl_safefree(sftp_scp->path);
2248 DEBUGF(infof(data, "SFTP DONE done\n"));
2250 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2251 After nextstate is executed, the control should come back to
2252 SSH_SFTP_CLOSE to pass the correct result back */
2253 if(sshc->nextstate != SSH_NO_STATE &&
2254 sshc->nextstate != SSH_SFTP_CLOSE) {
2255 state(conn, sshc->nextstate);
2256 sshc->nextstate = SSH_SFTP_CLOSE;
2259 state(conn, SSH_STOP);
2260 result = sshc->actualcode;
2264 case SSH_SFTP_SHUTDOWN:
2265 /* during times we get here due to a broken transfer and then the
2266 sftp_handle might not have been taken down so make sure that is done
2267 before we proceed */
2269 if(sshc->sftp_handle) {
2270 rc = libssh2_sftp_close(sshc->sftp_handle);
2271 if(rc == LIBSSH2_ERROR_EAGAIN) {
2275 infof(data, "Failed to close libssh2 file\n");
2277 sshc->sftp_handle = NULL;
2279 if(sshc->sftp_session) {
2280 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2281 if(rc == LIBSSH2_ERROR_EAGAIN) {
2285 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2287 sshc->sftp_session = NULL;
2290 Curl_safefree(sshc->homedir);
2291 conn->data->state.most_recent_ftp_entrypath = NULL;
2293 state(conn, SSH_SESSION_DISCONNECT);
2296 case SSH_SCP_TRANS_INIT:
2297 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2299 sshc->actualcode = result;
2300 state(conn, SSH_STOP);
2304 if(data->set.upload) {
2305 if(data->state.infilesize < 0) {
2306 failf(data, "SCP requires a known file size for upload");
2307 sshc->actualcode = CURLE_UPLOAD_FAILED;
2308 state(conn, SSH_SCP_CHANNEL_FREE);
2311 state(conn, SSH_SCP_UPLOAD_INIT);
2314 state(conn, SSH_SCP_DOWNLOAD_INIT);
2318 case SSH_SCP_UPLOAD_INIT:
2320 * libssh2 requires that the destination path is a full path that
2321 * includes the destination file and name OR ends in a "/" . If this is
2322 * not done the destination file will be named the same name as the last
2323 * directory in the path.
2326 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2327 data->state.infilesize);
2328 if(!sshc->ssh_channel) {
2329 if(libssh2_session_last_errno(sshc->ssh_session) ==
2330 LIBSSH2_ERROR_EAGAIN) {
2331 rc = LIBSSH2_ERROR_EAGAIN;
2338 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2339 &err_msg, NULL, 0));
2340 failf(conn->data, "%s", err_msg);
2341 state(conn, SSH_SCP_CHANNEL_FREE);
2342 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2348 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2351 /* not set by Curl_setup_transfer to preserve keepon bits */
2352 conn->sockfd = conn->writesockfd;
2355 state(conn, SSH_SCP_CHANNEL_FREE);
2356 sshc->actualcode = result;
2359 /* store this original bitmask setup to use later on if we can't
2360 figure out a "real" bitmask */
2361 sshc->orig_waitfor = data->req.keepon;
2363 /* we want to use the _sending_ function even when the socket turns
2364 out readable as the underlying libssh2 scp send function will deal
2365 with both accordingly */
2366 conn->cselect_bits = CURL_CSELECT_OUT;
2368 state(conn, SSH_STOP);
2372 case SSH_SCP_DOWNLOAD_INIT:
2374 curl_off_t bytecount;
2377 * We must check the remote file; if it is a directory no values will
2382 * If support for >2GB files exists, use it.
2385 /* get a fresh new channel from the ssh layer */
2386 #if LIBSSH2_VERSION_NUM < 0x010700
2388 memset(&sb, 0, sizeof(struct stat));
2389 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2390 sftp_scp->path, &sb);
2392 libssh2_struct_stat sb;
2393 memset(&sb, 0, sizeof(libssh2_struct_stat));
2394 sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session,
2395 sftp_scp->path, &sb);
2398 if(!sshc->ssh_channel) {
2399 if(libssh2_session_last_errno(sshc->ssh_session) ==
2400 LIBSSH2_ERROR_EAGAIN) {
2401 rc = LIBSSH2_ERROR_EAGAIN;
2408 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2409 &err_msg, NULL, 0));
2410 failf(conn->data, "%s", err_msg);
2411 state(conn, SSH_SCP_CHANNEL_FREE);
2412 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2418 bytecount = (curl_off_t)sb.st_size;
2419 data->req.maxdownload = (curl_off_t)sb.st_size;
2420 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2422 /* not set by Curl_setup_transfer to preserve keepon bits */
2423 conn->writesockfd = conn->sockfd;
2425 /* we want to use the _receiving_ function even when the socket turns
2426 out writableable as the underlying libssh2 recv function will deal
2427 with both accordingly */
2428 conn->cselect_bits = CURL_CSELECT_IN;
2431 state(conn, SSH_SCP_CHANNEL_FREE);
2432 sshc->actualcode = result;
2435 state(conn, SSH_STOP);
2440 if(data->set.upload)
2441 state(conn, SSH_SCP_SEND_EOF);
2443 state(conn, SSH_SCP_CHANNEL_FREE);
2446 case SSH_SCP_SEND_EOF:
2447 if(sshc->ssh_channel) {
2448 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2449 if(rc == LIBSSH2_ERROR_EAGAIN) {
2453 infof(data, "Failed to send libssh2 channel EOF\n");
2456 state(conn, SSH_SCP_WAIT_EOF);
2459 case SSH_SCP_WAIT_EOF:
2460 if(sshc->ssh_channel) {
2461 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2462 if(rc == LIBSSH2_ERROR_EAGAIN) {
2466 infof(data, "Failed to get channel EOF: %d\n", rc);
2469 state(conn, SSH_SCP_WAIT_CLOSE);
2472 case SSH_SCP_WAIT_CLOSE:
2473 if(sshc->ssh_channel) {
2474 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2475 if(rc == LIBSSH2_ERROR_EAGAIN) {
2479 infof(data, "Channel failed to close: %d\n", rc);
2482 state(conn, SSH_SCP_CHANNEL_FREE);
2485 case SSH_SCP_CHANNEL_FREE:
2486 if(sshc->ssh_channel) {
2487 rc = libssh2_channel_free(sshc->ssh_channel);
2488 if(rc == LIBSSH2_ERROR_EAGAIN) {
2492 infof(data, "Failed to free libssh2 scp subsystem\n");
2494 sshc->ssh_channel = NULL;
2496 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2498 state(conn, SSH_SESSION_DISCONNECT);
2500 state(conn, SSH_STOP);
2501 result = sshc->actualcode;
2504 case SSH_SESSION_DISCONNECT:
2505 /* during weird times when we've been prematurely aborted, the channel
2506 is still alive when we reach this state and we MUST kill the channel
2508 if(sshc->ssh_channel) {
2509 rc = libssh2_channel_free(sshc->ssh_channel);
2510 if(rc == LIBSSH2_ERROR_EAGAIN) {
2514 infof(data, "Failed to free libssh2 scp subsystem\n");
2516 sshc->ssh_channel = NULL;
2519 if(sshc->ssh_session) {
2520 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2521 if(rc == LIBSSH2_ERROR_EAGAIN) {
2525 infof(data, "Failed to disconnect libssh2 session\n");
2529 Curl_safefree(sshc->homedir);
2530 conn->data->state.most_recent_ftp_entrypath = NULL;
2532 state(conn, SSH_SESSION_FREE);
2535 case SSH_SESSION_FREE:
2536 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2538 libssh2_knownhost_free(sshc->kh);
2543 #ifdef HAVE_LIBSSH2_AGENT_API
2544 if(sshc->ssh_agent) {
2545 rc = libssh2_agent_disconnect(sshc->ssh_agent);
2546 if(rc == LIBSSH2_ERROR_EAGAIN) {
2550 infof(data, "Failed to disconnect from libssh2 agent\n");
2552 libssh2_agent_free (sshc->ssh_agent);
2553 sshc->ssh_agent = NULL;
2555 /* NB: there is no need to free identities, they are part of internal
2557 sshc->sshagent_identity = NULL;
2558 sshc->sshagent_prev_identity = NULL;
2562 if(sshc->ssh_session) {
2563 rc = libssh2_session_free(sshc->ssh_session);
2564 if(rc == LIBSSH2_ERROR_EAGAIN) {
2568 infof(data, "Failed to free libssh2 session\n");
2570 sshc->ssh_session = NULL;
2573 /* worst-case scenario cleanup */
2575 DEBUGASSERT(sshc->ssh_session == NULL);
2576 DEBUGASSERT(sshc->ssh_channel == NULL);
2577 DEBUGASSERT(sshc->sftp_session == NULL);
2578 DEBUGASSERT(sshc->sftp_handle == NULL);
2579 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2580 DEBUGASSERT(sshc->kh == NULL);
2582 #ifdef HAVE_LIBSSH2_AGENT_API
2583 DEBUGASSERT(sshc->ssh_agent == NULL);
2586 Curl_safefree(sshc->rsa_pub);
2587 Curl_safefree(sshc->rsa);
2589 Curl_safefree(sshc->quote_path1);
2590 Curl_safefree(sshc->quote_path2);
2592 Curl_safefree(sshc->homedir);
2594 Curl_safefree(sshc->readdir_filename);
2595 Curl_safefree(sshc->readdir_longentry);
2596 Curl_safefree(sshc->readdir_line);
2597 Curl_safefree(sshc->readdir_linkPath);
2599 /* the code we are about to return */
2600 result = sshc->actualcode;
2602 memset(sshc, 0, sizeof(struct ssh_conn));
2604 connclose(conn, "SSH session free");
2605 sshc->state = SSH_SESSION_FREE; /* current */
2606 sshc->nextstate = SSH_NO_STATE;
2607 state(conn, SSH_STOP);
2611 /* fallthrough, just stop! */
2613 /* internal error */
2614 sshc->nextstate = SSH_NO_STATE;
2615 state(conn, SSH_STOP);
2619 } while(!rc && (sshc->state != SSH_STOP));
2621 if(rc == LIBSSH2_ERROR_EAGAIN) {
2622 /* we would block, we need to wait for the socket to be ready (in the
2623 right direction too)! */
2630 /* called by the multi interface to figure out what socket(s) to wait for and
2631 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2632 static int ssh_perform_getsock(const struct connectdata *conn,
2633 curl_socket_t *sock, /* points to numsocks
2634 number of sockets */
2637 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2638 int bitmap = GETSOCK_BLANK;
2641 sock[0] = conn->sock[FIRSTSOCKET];
2643 if(conn->waitfor & KEEP_RECV)
2644 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2646 if(conn->waitfor & KEEP_SEND)
2647 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2651 /* if we don't know the direction we can use the generic *_getsock()
2652 function even for the protocol_connect and doing states */
2653 return Curl_single_getsock(conn, sock, numsocks);
2657 /* Generic function called by the multi interface to figure out what socket(s)
2658 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2659 static int ssh_getsock(struct connectdata *conn,
2660 curl_socket_t *sock, /* points to numsocks number
2664 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2668 /* if we don't know any direction we can just play along as we used to and
2669 not provide any sensible info */
2670 return GETSOCK_BLANK;
2672 /* if we know the direction we can use the generic *_getsock() function even
2673 for the protocol_connect and doing states */
2674 return ssh_perform_getsock(conn, sock, numsocks);
2678 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2680 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2681 * function is used to figure out in what direction and stores this info so
2682 * that the multi interface can take advantage of it. Make sure to call this
2683 * function in all cases so that when it _doesn't_ return EAGAIN we can
2684 * restore the default wait bits.
2686 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2688 struct ssh_conn *sshc = &conn->proto.sshc;
2690 if(block && (dir = libssh2_session_block_directions(sshc->ssh_session))) {
2691 /* translate the libssh2 define bits into our own bit defines */
2692 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2693 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2696 /* It didn't block or libssh2 didn't reveal in which direction, put back
2698 conn->waitfor = sshc->orig_waitfor;
2701 /* no libssh2 directional support so we simply don't know */
2702 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2705 /* called repeatedly until done from multi.c */
2706 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2708 struct ssh_conn *sshc = &conn->proto.sshc;
2709 CURLcode result = CURLE_OK;
2710 bool block; /* we store the status and use that to provide a ssh_getsock()
2713 result = ssh_statemach_act(conn, &block);
2714 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2715 ssh_block2waitfor(conn, block);
2720 static CURLcode ssh_block_statemach(struct connectdata *conn,
2723 struct ssh_conn *sshc = &conn->proto.sshc;
2724 CURLcode result = CURLE_OK;
2725 struct SessionHandle *data = conn->data;
2727 while((sshc->state != SSH_STOP) && !result) {
2731 result = ssh_statemach_act(conn, &block);
2735 if(Curl_pgrsUpdate(conn))
2736 return CURLE_ABORTED_BY_CALLBACK;
2738 struct timeval now = Curl_tvnow();
2739 result = Curl_speedcheck(data, now);
2744 left = Curl_timeleft(data, NULL, duringconnect);
2746 failf(data, "Operation timed out");
2747 return CURLE_OPERATION_TIMEDOUT;
2750 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2751 if(!result && block) {
2752 int dir = libssh2_session_block_directions(sshc->ssh_session);
2753 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2754 curl_socket_t fd_read = CURL_SOCKET_BAD;
2755 curl_socket_t fd_write = CURL_SOCKET_BAD;
2756 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2758 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2760 /* wait for the socket to become ready */
2761 Curl_socket_ready(fd_read, fd_write,
2762 left>1000?1000:left); /* ignore result */
2772 * SSH setup and connection
2774 static CURLcode ssh_setup_connection(struct connectdata *conn)
2776 struct SSHPROTO *ssh;
2778 conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
2780 return CURLE_OUT_OF_MEMORY;
2785 static Curl_recv scp_recv, sftp_recv;
2786 static Curl_send scp_send, sftp_send;
2789 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2790 * do protocol-specific actions at connect-time.
2792 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2794 #ifdef CURL_LIBSSH2_DEBUG
2797 struct ssh_conn *ssh;
2799 struct SessionHandle *data = conn->data;
2801 /* initialize per-handle data if not already */
2802 if(!data->req.protop)
2803 ssh_setup_connection(conn);
2805 /* We default to persistent connections. We set this already in this connect
2806 function to make the re-use checks properly be able to check this bit. */
2807 connkeep(conn, "SSH default");
2809 if(conn->handler->protocol & CURLPROTO_SCP) {
2810 conn->recv[FIRSTSOCKET] = scp_recv;
2811 conn->send[FIRSTSOCKET] = scp_send;
2814 conn->recv[FIRSTSOCKET] = sftp_recv;
2815 conn->send[FIRSTSOCKET] = sftp_send;
2817 ssh = &conn->proto.sshc;
2819 #ifdef CURL_LIBSSH2_DEBUG
2821 infof(data, "User: %s\n", conn->user);
2824 infof(data, "Password: %s\n", conn->passwd);
2826 sock = conn->sock[FIRSTSOCKET];
2827 #endif /* CURL_LIBSSH2_DEBUG */
2829 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2831 my_libssh2_realloc, conn);
2832 if(ssh->ssh_session == NULL) {
2833 failf(data, "Failure initialising ssh session");
2834 return CURLE_FAILED_INIT;
2837 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2838 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2840 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2842 /* eeek. TODO: free the ssh_session! */
2843 return CURLE_FAILED_INIT;
2846 /* read all known hosts from there */
2847 rc = libssh2_knownhost_readfile(ssh->kh,
2848 data->set.str[STRING_SSH_KNOWNHOSTS],
2849 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2851 infof(data, "Failed to read known hosts from %s\n",
2852 data->set.str[STRING_SSH_KNOWNHOSTS]);
2854 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2856 #ifdef CURL_LIBSSH2_DEBUG
2857 libssh2_trace(ssh->ssh_session, ~0);
2858 infof(data, "SSH socket: %d\n", (int)sock);
2859 #endif /* CURL_LIBSSH2_DEBUG */
2861 state(conn, SSH_INIT);
2863 result = ssh_multi_statemach(conn, done);
2869 ***********************************************************************
2873 * This is the actual DO function for SCP. Get a file according to
2874 * the options previously setup.
2878 CURLcode scp_perform(struct connectdata *conn,
2882 CURLcode result = CURLE_OK;
2884 DEBUGF(infof(conn->data, "DO phase starts\n"));
2886 *dophase_done = FALSE; /* not done yet */
2888 /* start the first command in the DO phase */
2889 state(conn, SSH_SCP_TRANS_INIT);
2891 /* run the state-machine */
2892 result = ssh_multi_statemach(conn, dophase_done);
2894 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2897 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2903 /* called from multi.c while DOing */
2904 static CURLcode scp_doing(struct connectdata *conn,
2908 result = ssh_multi_statemach(conn, dophase_done);
2911 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2917 * The DO function is generic for both protocols. There was previously two
2918 * separate ones but this way means less duplicated code.
2921 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2925 struct SessionHandle *data = conn->data;
2926 struct ssh_conn *sshc = &conn->proto.sshc;
2928 *done = FALSE; /* default to false */
2930 data->req.size = -1; /* make sure this is unknown at this point */
2932 sshc->actualcode = CURLE_OK; /* reset error code */
2933 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2936 Curl_pgrsSetUploadCounter(data, 0);
2937 Curl_pgrsSetDownloadCounter(data, 0);
2938 Curl_pgrsSetUploadSize(data, -1);
2939 Curl_pgrsSetDownloadSize(data, -1);
2941 if(conn->handler->protocol & CURLPROTO_SCP)
2942 result = scp_perform(conn, &connected, done);
2944 result = sftp_perform(conn, &connected, done);
2949 /* BLOCKING, but the function is using the state machine so the only reason
2950 this is still blocking is that the multi interface code has no support for
2951 disconnecting operations that takes a while */
2952 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2954 CURLcode result = CURLE_OK;
2955 struct ssh_conn *ssh = &conn->proto.sshc;
2956 (void) dead_connection;
2958 Curl_safefree(conn->data->req.protop);
2960 if(ssh->ssh_session) {
2961 /* only if there's a session still around to use! */
2963 state(conn, SSH_SESSION_DISCONNECT);
2965 result = ssh_block_statemach(conn, FALSE);
2971 /* generic done function for both SCP and SFTP called from their specific
2973 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2975 CURLcode result = CURLE_OK;
2976 struct SSHPROTO *sftp_scp = conn->data->req.protop;
2979 /* run the state-machine
2981 TODO: when the multi interface is used, this _really_ should be using
2982 the ssh_multi_statemach function but we have no general support for
2983 non-blocking DONE operations, not in the multi state machine and with
2984 Curl_done() invokes on several places in the code!
2986 result = ssh_block_statemach(conn, FALSE);
2992 Curl_safefree(sftp_scp->path);
2993 if(Curl_pgrsDone(conn))
2994 return CURLE_ABORTED_BY_CALLBACK;
2996 conn->data->req.keepon = 0; /* clear all bits */
3001 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
3004 (void)premature; /* not used */
3007 state(conn, SSH_SCP_DONE);
3009 return ssh_done(conn, status);
3013 /* return number of received (decrypted) bytes */
3014 static ssize_t scp_send(struct connectdata *conn, int sockindex,
3015 const void *mem, size_t len, CURLcode *err)
3018 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3020 /* libssh2_channel_write() returns int! */
3022 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
3024 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3026 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3030 else if(nwrite < LIBSSH2_ERROR_NONE) {
3031 *err = libssh2_session_error_to_CURLE((int)nwrite);
3039 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
3040 * a regular CURLcode value.
3042 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
3043 char *mem, size_t len, CURLcode *err)
3046 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3048 /* libssh2_channel_read() returns int */
3050 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
3052 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3053 if(nread == LIBSSH2_ERROR_EAGAIN) {
3062 * =============== SFTP ===============
3066 ***********************************************************************
3070 * This is the actual DO function for SFTP. Get a file/directory according to
3071 * the options previously setup.
3075 CURLcode sftp_perform(struct connectdata *conn,
3079 CURLcode result = CURLE_OK;
3081 DEBUGF(infof(conn->data, "DO phase starts\n"));
3083 *dophase_done = FALSE; /* not done yet */
3085 /* start the first command in the DO phase */
3086 state(conn, SSH_SFTP_QUOTE_INIT);
3088 /* run the state-machine */
3089 result = ssh_multi_statemach(conn, dophase_done);
3091 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3094 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3100 /* called from multi.c while DOing */
3101 static CURLcode sftp_doing(struct connectdata *conn,
3104 CURLcode result = ssh_multi_statemach(conn, dophase_done);
3107 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3112 /* BLOCKING, but the function is using the state machine so the only reason
3113 this is still blocking is that the multi interface code has no support for
3114 disconnecting operations that takes a while */
3115 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
3117 CURLcode result = CURLE_OK;
3118 (void) dead_connection;
3120 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3122 Curl_safefree(conn->data->req.protop);
3124 if(conn->proto.sshc.ssh_session) {
3125 /* only if there's a session still around to use! */
3126 state(conn, SSH_SFTP_SHUTDOWN);
3127 result = ssh_block_statemach(conn, FALSE);
3130 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3136 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3139 struct ssh_conn *sshc = &conn->proto.sshc;
3142 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3143 errors that could happen due to open file handles during POSTQUOTE
3145 if(!status && !premature && conn->data->set.postquote) {
3146 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3147 state(conn, SSH_SFTP_CLOSE);
3150 state(conn, SSH_SFTP_CLOSE);
3152 return ssh_done(conn, status);
3155 /* return number of sent bytes */
3156 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3157 const void *mem, size_t len, CURLcode *err)
3159 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3160 but is changed to ssize_t in 0.15. These days we don't
3161 support libssh2 0.15*/
3164 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3166 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3168 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3172 else if(nwrite < LIBSSH2_ERROR_NONE) {
3173 *err = libssh2_session_error_to_CURLE((int)nwrite);
3181 * Return number of received (decrypted) bytes
3184 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3185 char *mem, size_t len, CURLcode *err)
3190 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3192 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3194 if(nread == LIBSSH2_ERROR_EAGAIN) {
3199 else if(nread < 0) {
3200 *err = libssh2_session_error_to_CURLE((int)nread);
3205 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3208 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3210 * Permission to use, copy, modify, and distribute this software for any
3211 * purpose with or without fee is hereby granted, provided that the above
3212 * copyright notice and this permission notice appear in all copies.
3214 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3215 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3216 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3217 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3218 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3219 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3220 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3223 get_pathname(const char **cpp, char **path)
3225 const char *cp = *cpp, *end;
3228 static const char WHITESPACE[] = " \t\r\n";
3230 cp += strspn(cp, WHITESPACE);
3234 return CURLE_QUOTE_ERROR;
3237 *path = malloc(strlen(cp) + 1);
3239 return CURLE_OUT_OF_MEMORY;
3241 /* Check for quoted filenames */
3242 if(*cp == '\"' || *cp == '\'') {
3245 /* Search for terminating quote, unescape some chars */
3246 for(i = j = 0; i <= strlen(cp); i++) {
3247 if(cp[i] == quot) { /* Found quote */
3252 if(cp[i] == '\0') { /* End of string */
3253 /*error("Unterminated quote");*/
3256 if(cp[i] == '\\') { /* Escaped characters */
3258 if(cp[i] != '\'' && cp[i] != '\"' &&
3260 /*error("Bad escaped character '\\%c'",
3265 (*path)[j++] = cp[i];
3269 /*error("Empty quotes");*/
3272 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3275 /* Read to end of filename */
3276 end = strpbrk(cp, WHITESPACE);
3278 end = strchr(cp, '\0');
3279 *cpp = end + strspn(end, WHITESPACE);
3281 memcpy(*path, cp, end - cp);
3282 (*path)[end - cp] = '\0';
3287 Curl_safefree(*path);
3288 return CURLE_QUOTE_ERROR;
3292 static const char *sftp_libssh2_strerror(int err)
3295 case LIBSSH2_FX_NO_SUCH_FILE:
3296 return "No such file or directory";
3298 case LIBSSH2_FX_PERMISSION_DENIED:
3299 return "Permission denied";
3301 case LIBSSH2_FX_FAILURE:
3302 return "Operation failed";
3304 case LIBSSH2_FX_BAD_MESSAGE:
3305 return "Bad message from SFTP server";
3307 case LIBSSH2_FX_NO_CONNECTION:
3308 return "Not connected to SFTP server";
3310 case LIBSSH2_FX_CONNECTION_LOST:
3311 return "Connection to SFTP server lost";
3313 case LIBSSH2_FX_OP_UNSUPPORTED:
3314 return "Operation not supported by SFTP server";
3316 case LIBSSH2_FX_INVALID_HANDLE:
3317 return "Invalid handle";
3319 case LIBSSH2_FX_NO_SUCH_PATH:
3320 return "No such file or directory";
3322 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3323 return "File already exists";
3325 case LIBSSH2_FX_WRITE_PROTECT:
3326 return "File is write protected";
3328 case LIBSSH2_FX_NO_MEDIA:
3331 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3334 case LIBSSH2_FX_QUOTA_EXCEEDED:
3335 return "User quota exceeded";
3337 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3338 return "Unknown principle";
3340 case LIBSSH2_FX_LOCK_CONFlICT:
3341 return "File lock conflict";
3343 case LIBSSH2_FX_DIR_NOT_EMPTY:
3344 return "Directory not empty";
3346 case LIBSSH2_FX_NOT_A_DIRECTORY:
3347 return "Not a directory";
3349 case LIBSSH2_FX_INVALID_FILENAME:
3350 return "Invalid filename";
3352 case LIBSSH2_FX_LINK_LOOP:
3353 return "Link points to itself";
3355 return "Unknown error in libssh2";
3358 #endif /* USE_LIBSSH2 */