1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2016, 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"
87 /* The last 3 #include files should be in this order */
88 #include "curl_printf.h"
89 #include "curl_memory.h"
94 # define PATH_MAX MAX_PATH
101 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
102 have their definition hidden well */
105 #if LIBSSH2_VERSION_NUM >= 0x010206
106 /* libssh2_sftp_statvfs and friends were added in 1.2.6 */
107 #define HAS_STATVFS_SUPPORT 1
110 #define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
112 #define sftp_libssh2_realpath(s,p,t,m) \
113 libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
114 (t), (m), LIBSSH2_SFTP_REALPATH)
116 /* Local functions: */
117 static const char *sftp_libssh2_strerror(int err);
118 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
119 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
120 static LIBSSH2_FREE_FUNC(my_libssh2_free);
122 static CURLcode get_pathname(const char **cpp, char **path);
124 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
125 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
126 static CURLcode ssh_do(struct connectdata *conn, bool *done);
128 static CURLcode ssh_getworkingpath(struct connectdata *conn,
129 char *homedir, /* when SFTP is used */
132 static CURLcode scp_done(struct connectdata *conn,
133 CURLcode, bool premature);
134 static CURLcode scp_doing(struct connectdata *conn,
136 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
138 static CURLcode sftp_done(struct connectdata *conn,
139 CURLcode, bool premature);
140 static CURLcode sftp_doing(struct connectdata *conn,
142 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
144 CURLcode sftp_perform(struct connectdata *conn,
148 static int ssh_getsock(struct connectdata *conn,
149 curl_socket_t *sock, /* points to numsocks number
153 static int ssh_perform_getsock(const struct connectdata *conn,
154 curl_socket_t *sock, /* points to numsocks
158 static CURLcode ssh_setup_connection(struct connectdata *conn);
161 * SCP protocol handler.
164 const struct Curl_handler Curl_handler_scp = {
166 ssh_setup_connection, /* setup_connection */
169 ZERO_NULL, /* do_more */
170 ssh_connect, /* connect_it */
171 ssh_multi_statemach, /* connecting */
172 scp_doing, /* doing */
173 ssh_getsock, /* proto_getsock */
174 ssh_getsock, /* doing_getsock */
175 ZERO_NULL, /* domore_getsock */
176 ssh_perform_getsock, /* perform_getsock */
177 scp_disconnect, /* disconnect */
178 ZERO_NULL, /* readwrite */
179 PORT_SSH, /* defport */
180 CURLPROTO_SCP, /* protocol */
181 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
182 | PROTOPT_NOURLQUERY /* flags */
187 * SFTP protocol handler.
190 const struct Curl_handler Curl_handler_sftp = {
192 ssh_setup_connection, /* setup_connection */
194 sftp_done, /* done */
195 ZERO_NULL, /* do_more */
196 ssh_connect, /* connect_it */
197 ssh_multi_statemach, /* connecting */
198 sftp_doing, /* doing */
199 ssh_getsock, /* proto_getsock */
200 ssh_getsock, /* doing_getsock */
201 ZERO_NULL, /* domore_getsock */
202 ssh_perform_getsock, /* perform_getsock */
203 sftp_disconnect, /* disconnect */
204 ZERO_NULL, /* readwrite */
205 PORT_SSH, /* defport */
206 CURLPROTO_SFTP, /* protocol */
207 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
208 | PROTOPT_NOURLQUERY /* flags */
212 kbd_callback(const char *name, int name_len, const char *instruction,
213 int instruction_len, int num_prompts,
214 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
215 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
218 struct connectdata *conn = (struct connectdata *)*abstract;
220 #ifdef CURL_LIBSSH2_DEBUG
221 fprintf(stderr, "name=%s\n", name);
222 fprintf(stderr, "name_len=%d\n", name_len);
223 fprintf(stderr, "instruction=%s\n", instruction);
224 fprintf(stderr, "instruction_len=%d\n", instruction_len);
225 fprintf(stderr, "num_prompts=%d\n", num_prompts);
230 (void)instruction_len;
231 #endif /* CURL_LIBSSH2_DEBUG */
232 if(num_prompts == 1) {
233 responses[0].text = strdup(conn->passwd);
234 responses[0].length = curlx_uztoui(strlen(conn->passwd));
240 static CURLcode sftp_libssh2_error_to_CURLE(int err)
246 case LIBSSH2_FX_NO_SUCH_FILE:
247 case LIBSSH2_FX_NO_SUCH_PATH:
248 return CURLE_REMOTE_FILE_NOT_FOUND;
250 case LIBSSH2_FX_PERMISSION_DENIED:
251 case LIBSSH2_FX_WRITE_PROTECT:
252 case LIBSSH2_FX_LOCK_CONFlICT:
253 return CURLE_REMOTE_ACCESS_DENIED;
255 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
256 case LIBSSH2_FX_QUOTA_EXCEEDED:
257 return CURLE_REMOTE_DISK_FULL;
259 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
260 return CURLE_REMOTE_FILE_EXISTS;
262 case LIBSSH2_FX_DIR_NOT_EMPTY:
263 return CURLE_QUOTE_ERROR;
272 static CURLcode libssh2_session_error_to_CURLE(int err)
275 /* Ordered by order of appearance in libssh2.h */
276 case LIBSSH2_ERROR_NONE:
279 case LIBSSH2_ERROR_SOCKET_NONE:
280 return CURLE_COULDNT_CONNECT;
282 case LIBSSH2_ERROR_ALLOC:
283 return CURLE_OUT_OF_MEMORY;
285 case LIBSSH2_ERROR_SOCKET_SEND:
286 return CURLE_SEND_ERROR;
288 case LIBSSH2_ERROR_HOSTKEY_INIT:
289 case LIBSSH2_ERROR_HOSTKEY_SIGN:
290 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
291 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
292 return CURLE_PEER_FAILED_VERIFICATION;
294 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
295 return CURLE_LOGIN_DENIED;
297 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
298 case LIBSSH2_ERROR_TIMEOUT:
299 return CURLE_OPERATION_TIMEDOUT;
301 case LIBSSH2_ERROR_EAGAIN:
305 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
306 error code, and possibly add a few new SSH-related one. We must however
307 not return or even depend on libssh2 errors in the public libcurl API */
312 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
314 (void)abstract; /* arg not used */
315 return malloc(count);
318 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
320 (void)abstract; /* arg not used */
321 return realloc(ptr, count);
324 static LIBSSH2_FREE_FUNC(my_libssh2_free)
326 (void)abstract; /* arg not used */
327 if(ptr) /* ssh2 agent sometimes call free with null ptr */
332 * SSH State machine related code
334 /* This is the ONLY way to change SSH state! */
335 static void state(struct connectdata *conn, sshstate nowstate)
337 struct ssh_conn *sshc = &conn->proto.sshc;
338 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
339 /* for debug purposes */
340 static const char * const names[] = {
346 "SSH_AUTH_PKEY_INIT",
348 "SSH_AUTH_PASS_INIT",
350 "SSH_AUTH_AGENT_INIT",
351 "SSH_AUTH_AGENT_LIST",
353 "SSH_AUTH_HOST_INIT",
360 "SSH_SFTP_QUOTE_INIT",
361 "SSH_SFTP_POSTQUOTE_INIT",
363 "SSH_SFTP_NEXT_QUOTE",
364 "SSH_SFTP_QUOTE_STAT",
365 "SSH_SFTP_QUOTE_SETSTAT",
366 "SSH_SFTP_QUOTE_SYMLINK",
367 "SSH_SFTP_QUOTE_MKDIR",
368 "SSH_SFTP_QUOTE_RENAME",
369 "SSH_SFTP_QUOTE_RMDIR",
370 "SSH_SFTP_QUOTE_UNLINK",
371 "SSH_SFTP_QUOTE_STATVFS",
374 "SSH_SFTP_TRANS_INIT",
375 "SSH_SFTP_UPLOAD_INIT",
376 "SSH_SFTP_CREATE_DIRS_INIT",
377 "SSH_SFTP_CREATE_DIRS",
378 "SSH_SFTP_CREATE_DIRS_MKDIR",
379 "SSH_SFTP_READDIR_INIT",
381 "SSH_SFTP_READDIR_LINK",
382 "SSH_SFTP_READDIR_BOTTOM",
383 "SSH_SFTP_READDIR_DONE",
384 "SSH_SFTP_DOWNLOAD_INIT",
385 "SSH_SFTP_DOWNLOAD_STAT",
388 "SSH_SCP_TRANS_INIT",
389 "SSH_SCP_UPLOAD_INIT",
390 "SSH_SCP_DOWNLOAD_INIT",
394 "SSH_SCP_WAIT_CLOSE",
395 "SSH_SCP_CHANNEL_FREE",
396 "SSH_SESSION_DISCONNECT",
401 if(sshc->state != nowstate) {
402 infof(conn->data, "SFTP %p state change from %s to %s\n",
403 (void *)sshc, names[sshc->state], names[nowstate]);
407 sshc->state = nowstate;
410 /* figure out the path to work with in this particular request */
411 static CURLcode ssh_getworkingpath(struct connectdata *conn,
412 char *homedir, /* when SFTP is used */
413 char **path) /* returns the allocated
414 real path to work with */
416 struct Curl_easy *data = conn->data;
417 char *real_path = NULL;
419 int working_path_len;
421 working_path = curl_easy_unescape(data, data->state.path, 0,
424 return CURLE_OUT_OF_MEMORY;
426 /* Check for /~/, indicating relative to the user's home directory */
427 if(conn->handler->protocol & CURLPROTO_SCP) {
428 real_path = malloc(working_path_len+1);
429 if(real_path == NULL) {
431 return CURLE_OUT_OF_MEMORY;
433 if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
434 /* It is referenced to the home directory, so strip the leading '/~/' */
435 memcpy(real_path, working_path+3, 4 + working_path_len-3);
437 memcpy(real_path, working_path, 1 + working_path_len);
439 else if(conn->handler->protocol & CURLPROTO_SFTP) {
440 if((working_path_len > 1) && (working_path[1] == '~')) {
441 size_t homelen = strlen(homedir);
442 real_path = malloc(homelen + working_path_len + 1);
443 if(real_path == NULL) {
445 return CURLE_OUT_OF_MEMORY;
447 /* It is referenced to the home directory, so strip the
449 memcpy(real_path, homedir, homelen);
450 real_path[homelen] = '/';
451 real_path[homelen+1] = '\0';
452 if(working_path_len > 3) {
453 memcpy(real_path+homelen+1, working_path + 3,
454 1 + working_path_len -3);
458 real_path = malloc(working_path_len+1);
459 if(real_path == NULL) {
461 return CURLE_OUT_OF_MEMORY;
463 memcpy(real_path, working_path, 1+working_path_len);
469 /* store the pointer for the caller to receive */
475 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
476 static int sshkeycallback(struct Curl_easy *easy,
477 const struct curl_khkey *knownkey, /* known */
478 const struct curl_khkey *foundkey, /* found */
479 enum curl_khmatch match,
487 /* we only allow perfect matches, and we reject everything else */
488 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
493 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
496 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
497 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
499 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
503 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
504 * architectures so we check of the necessary function is present.
506 #ifndef HAVE_LIBSSH2_SCP_SEND64
507 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
509 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
510 (libssh2_uint64_t)d, 0, 0)
514 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
516 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
517 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
520 static CURLcode ssh_knownhost(struct connectdata *conn)
522 CURLcode result = CURLE_OK;
524 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
525 struct Curl_easy *data = conn->data;
527 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
528 /* we're asked to verify the host against a file */
529 struct ssh_conn *sshc = &conn->proto.sshc;
533 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
535 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
540 * A subject to figure out is what host name we need to pass in here.
541 * What host name does OpenSSH store in its file if an IDN name is
544 struct libssh2_knownhost *host;
545 enum curl_khmatch keymatch;
546 curl_sshkeycallback func =
547 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
548 struct curl_khkey knownkey;
549 struct curl_khkey *knownkeyp = NULL;
550 struct curl_khkey foundkey;
552 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
553 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
555 #ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
556 keycheck = libssh2_knownhost_checkp(sshc->kh,
558 (conn->remote_port != PORT_SSH)?
559 conn->remote_port:-1,
561 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
562 LIBSSH2_KNOWNHOST_KEYENC_RAW|
566 keycheck = libssh2_knownhost_check(sshc->kh,
569 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
570 LIBSSH2_KNOWNHOST_KEYENC_RAW|
575 infof(data, "SSH host check: %d, key: %s\n", keycheck,
576 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
579 /* setup 'knownkey' */
580 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
581 knownkey.key = host->key;
583 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
584 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
585 knownkeyp = &knownkey;
588 /* setup 'foundkey' */
589 foundkey.key = remotekey;
590 foundkey.len = keylen;
591 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
592 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
595 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
596 * curl_khmatch enum are ever modified, we need to introduce a
597 * translation table here!
599 keymatch = (enum curl_khmatch)keycheck;
601 /* Ask the callback how to behave */
602 rc = func(data, knownkeyp, /* from the knownhosts file */
603 &foundkey, /* from the remote host */
604 keymatch, data->set.ssh_keyfunc_userp);
607 /* no remotekey means failure! */
608 rc = CURLKHSTAT_REJECT;
611 default: /* unknown return codes will equal reject */
613 case CURLKHSTAT_REJECT:
614 state(conn, SSH_SESSION_FREE);
616 case CURLKHSTAT_DEFER:
617 /* DEFER means bail out but keep the SSH_HOSTKEY state */
618 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
620 case CURLKHSTAT_FINE:
621 case CURLKHSTAT_FINE_ADD_TO_FILE:
623 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
624 /* the found host+key didn't match but has been told to be fine
625 anyway so we add it in memory */
626 int addrc = libssh2_knownhost_add(sshc->kh,
627 conn->host.name, NULL,
629 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
630 LIBSSH2_KNOWNHOST_KEYENC_RAW|
633 infof(data, "Warning adding the known host %s failed!\n",
635 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
636 /* now we write the entire in-memory list of known hosts to the
639 libssh2_knownhost_writefile(sshc->kh,
640 data->set.str[STRING_SSH_KNOWNHOSTS],
641 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
643 infof(data, "Warning, writing %s failed!\n",
644 data->set.str[STRING_SSH_KNOWNHOSTS]);
651 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
657 static CURLcode ssh_check_fingerprint(struct connectdata *conn)
659 struct ssh_conn *sshc = &conn->proto.sshc;
660 struct Curl_easy *data = conn->data;
661 const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
665 const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
666 LIBSSH2_HOSTKEY_HASH_MD5);
669 /* The fingerprint points to static storage (!), don't free() it. */
670 for(i = 0; i < 16; i++)
671 snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
672 infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
675 /* Before we authenticate we check the hostkey's MD5 fingerprint
676 * against a known fingerprint, if available.
678 if(pubkey_md5 && strlen(pubkey_md5) == 32) {
679 if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
682 "Denied establishing ssh session: mismatch md5 fingerprint. "
683 "Remote %s is not equal to %s", md5buffer, pubkey_md5);
686 "Denied establishing ssh session: md5 fingerprint not available");
687 state(conn, SSH_SESSION_FREE);
688 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
689 return sshc->actualcode;
692 infof(data, "MD5 checksum match!\n");
693 /* as we already matched, we skip the check for known hosts */
698 return ssh_knownhost(conn);
702 * ssh_statemach_act() runs the SSH state machine as far as it can without
703 * blocking and without reaching the end. The data the pointer 'block' points
704 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
705 * meaning it wants to be called again when the socket is ready
708 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
710 CURLcode result = CURLE_OK;
711 struct Curl_easy *data = conn->data;
712 struct SSHPROTO *sftp_scp = data->req.protop;
713 struct ssh_conn *sshc = &conn->proto.sshc;
714 curl_socket_t sock = conn->sock[FIRSTSOCKET];
715 char *new_readdir_line;
716 int rc = LIBSSH2_ERROR_NONE;
718 int seekerr = CURL_SEEKFUNC_OK;
719 *block = 0; /* we're not blocking by default */
723 switch(sshc->state) {
725 sshc->secondCreateDirs = 0;
726 sshc->nextstate = SSH_NO_STATE;
727 sshc->actualcode = CURLE_OK;
729 /* Set libssh2 to non-blocking, since everything internally is
731 libssh2_session_set_blocking(sshc->ssh_session, 0);
733 state(conn, SSH_S_STARTUP);
737 rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
738 if(rc == LIBSSH2_ERROR_EAGAIN) {
742 failf(data, "Failure establishing ssh session");
743 state(conn, SSH_SESSION_FREE);
744 sshc->actualcode = CURLE_FAILED_INIT;
748 state(conn, SSH_HOSTKEY);
753 * Before we authenticate we should check the hostkey's fingerprint
754 * against our known hosts. How that is handled (reading from file,
755 * whatever) is up to us.
757 result = ssh_check_fingerprint(conn);
759 state(conn, SSH_AUTHLIST);
760 /* ssh_check_fingerprint sets state appropriately on error */
765 * Figure out authentication methods
766 * NB: As soon as we have provided a username to an openssh server we
767 * must never change it later. Thus, always specify the correct username
768 * here, even though the libssh2 docs kind of indicate that it should be
769 * possible to get a 'generic' list (not user-specific) of authentication
770 * methods, presumably with a blank username. That won't work in my
772 * So always specify it here.
774 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
776 curlx_uztoui(strlen(conn->user)));
778 if(!sshc->authlist) {
779 if(libssh2_userauth_authenticated(sshc->ssh_session)) {
781 infof(data, "SSH user accepted with no authentication\n");
782 state(conn, SSH_AUTH_DONE);
785 else if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
786 LIBSSH2_ERROR_EAGAIN) {
787 rc = LIBSSH2_ERROR_EAGAIN;
791 state(conn, SSH_SESSION_FREE);
792 sshc->actualcode = libssh2_session_error_to_CURLE(err);
796 infof(data, "SSH authentication methods available: %s\n",
799 state(conn, SSH_AUTH_PKEY_INIT);
802 case SSH_AUTH_PKEY_INIT:
804 * Check the supported auth types in the order I feel is most secure
805 * with the requested type of authentication
807 sshc->authed = FALSE;
809 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
810 (strstr(sshc->authlist, "publickey") != NULL)) {
812 bool out_of_memory = FALSE;
814 sshc->rsa_pub = sshc->rsa = NULL;
816 /* To ponder about: should really the lib be messing about with the
817 HOME environment variable etc? */
818 home = curl_getenv("HOME");
820 if(data->set.str[STRING_SSH_PRIVATE_KEY])
821 sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
823 /* If no private key file is specified, try some common paths. */
825 /* Try ~/.ssh first. */
826 sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
828 out_of_memory = TRUE;
829 else if(access(sshc->rsa, R_OK) != 0) {
830 Curl_safefree(sshc->rsa);
831 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
833 out_of_memory = TRUE;
834 else if(access(sshc->rsa, R_OK) != 0) {
835 Curl_safefree(sshc->rsa);
839 if(!out_of_memory && !sshc->rsa) {
840 /* Nothing found; try the current dir. */
841 sshc->rsa = strdup("id_rsa");
842 if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
843 Curl_safefree(sshc->rsa);
844 sshc->rsa = strdup("id_dsa");
845 if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
846 Curl_safefree(sshc->rsa);
847 /* Out of guesses. Set to the empty string to avoid
848 * surprising info messages. */
849 sshc->rsa = strdup("");
856 * Unless the user explicitly specifies a public key file, let
857 * libssh2 extract the public key from the private key file.
858 * This is done by simply passing sshc->rsa_pub = NULL.
860 if(data->set.str[STRING_SSH_PUBLIC_KEY]
861 /* treat empty string the same way as NULL */
862 && data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
863 sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
865 out_of_memory = TRUE;
868 if(out_of_memory || sshc->rsa == NULL) {
870 Curl_safefree(sshc->rsa);
871 Curl_safefree(sshc->rsa_pub);
872 state(conn, SSH_SESSION_FREE);
873 sshc->actualcode = CURLE_OUT_OF_MEMORY;
877 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
878 if(!sshc->passphrase)
879 sshc->passphrase = "";
884 infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
885 infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
887 state(conn, SSH_AUTH_PKEY);
890 state(conn, SSH_AUTH_PASS_INIT);
895 /* The function below checks if the files exists, no need to stat() here.
897 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
902 sshc->rsa, sshc->passphrase);
903 if(rc == LIBSSH2_ERROR_EAGAIN) {
907 Curl_safefree(sshc->rsa_pub);
908 Curl_safefree(sshc->rsa);
912 infof(data, "Initialized SSH public key authentication\n");
913 state(conn, SSH_AUTH_DONE);
917 (void)libssh2_session_last_error(sshc->ssh_session,
919 infof(data, "SSH public key authentication failed: %s\n", err_msg);
920 state(conn, SSH_AUTH_PASS_INIT);
924 case SSH_AUTH_PASS_INIT:
925 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
926 (strstr(sshc->authlist, "password") != NULL)) {
927 state(conn, SSH_AUTH_PASS);
930 state(conn, SSH_AUTH_HOST_INIT);
935 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
936 curlx_uztoui(strlen(conn->user)),
938 curlx_uztoui(strlen(conn->passwd)),
940 if(rc == LIBSSH2_ERROR_EAGAIN) {
945 infof(data, "Initialized password authentication\n");
946 state(conn, SSH_AUTH_DONE);
949 state(conn, SSH_AUTH_HOST_INIT);
950 rc = 0; /* clear rc and continue */
954 case SSH_AUTH_HOST_INIT:
955 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
956 (strstr(sshc->authlist, "hostbased") != NULL)) {
957 state(conn, SSH_AUTH_HOST);
960 state(conn, SSH_AUTH_AGENT_INIT);
965 state(conn, SSH_AUTH_AGENT_INIT);
968 case SSH_AUTH_AGENT_INIT:
969 #ifdef HAVE_LIBSSH2_AGENT_API
970 if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
971 && (strstr(sshc->authlist, "publickey") != NULL)) {
973 /* Connect to the ssh-agent */
974 /* The agent could be shared by a curl thread i believe
975 but nothing obvious as keys can be added/removed at any time */
976 if(!sshc->ssh_agent) {
977 sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
978 if(!sshc->ssh_agent) {
979 infof(data, "Could not create agent object\n");
981 state(conn, SSH_AUTH_KEY_INIT);
986 rc = libssh2_agent_connect(sshc->ssh_agent);
987 if(rc == LIBSSH2_ERROR_EAGAIN)
990 infof(data, "Failure connecting to agent\n");
991 state(conn, SSH_AUTH_KEY_INIT);
994 state(conn, SSH_AUTH_AGENT_LIST);
998 #endif /* HAVE_LIBSSH2_AGENT_API */
999 state(conn, SSH_AUTH_KEY_INIT);
1002 case SSH_AUTH_AGENT_LIST:
1003 #ifdef HAVE_LIBSSH2_AGENT_API
1004 rc = libssh2_agent_list_identities(sshc->ssh_agent);
1006 if(rc == LIBSSH2_ERROR_EAGAIN)
1009 infof(data, "Failure requesting identities to agent\n");
1010 state(conn, SSH_AUTH_KEY_INIT);
1013 state(conn, SSH_AUTH_AGENT);
1014 sshc->sshagent_prev_identity = NULL;
1019 case SSH_AUTH_AGENT:
1020 #ifdef HAVE_LIBSSH2_AGENT_API
1021 /* as prev_identity evolves only after an identity user auth finished we
1022 can safely request it again as long as EAGAIN is returned here or by
1023 libssh2_agent_userauth */
1024 rc = libssh2_agent_get_identity(sshc->ssh_agent,
1025 &sshc->sshagent_identity,
1026 sshc->sshagent_prev_identity);
1027 if(rc == LIBSSH2_ERROR_EAGAIN)
1031 rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
1032 sshc->sshagent_identity);
1035 if(rc != LIBSSH2_ERROR_EAGAIN)
1036 /* tried and failed? go to next identity */
1037 sshc->sshagent_prev_identity = sshc->sshagent_identity;
1044 infof(data, "Failure requesting identities to agent\n");
1046 infof(data, "No identity would match\n");
1048 if(rc == LIBSSH2_ERROR_NONE) {
1049 sshc->authed = TRUE;
1050 infof(data, "Agent based authentication successful\n");
1051 state(conn, SSH_AUTH_DONE);
1054 state(conn, SSH_AUTH_KEY_INIT);
1055 rc = 0; /* clear rc and continue */
1060 case SSH_AUTH_KEY_INIT:
1061 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
1062 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
1063 state(conn, SSH_AUTH_KEY);
1066 state(conn, SSH_AUTH_DONE);
1071 /* Authentication failed. Continue with keyboard-interactive now. */
1072 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
1075 strlen(conn->user)),
1077 if(rc == LIBSSH2_ERROR_EAGAIN) {
1081 sshc->authed = TRUE;
1082 infof(data, "Initialized keyboard interactive authentication\n");
1084 state(conn, SSH_AUTH_DONE);
1089 failf(data, "Authentication failure");
1090 state(conn, SSH_SESSION_FREE);
1091 sshc->actualcode = CURLE_LOGIN_DENIED;
1096 * At this point we have an authenticated ssh session.
1098 infof(data, "Authentication complete\n");
1100 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
1102 conn->sockfd = sock;
1103 conn->writesockfd = CURL_SOCKET_BAD;
1105 if(conn->handler->protocol == CURLPROTO_SFTP) {
1106 state(conn, SSH_SFTP_INIT);
1109 infof(data, "SSH CONNECT phase done\n");
1110 state(conn, SSH_STOP);
1115 * Start the libssh2 sftp session
1117 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
1118 if(!sshc->sftp_session) {
1119 if(libssh2_session_last_errno(sshc->ssh_session) ==
1120 LIBSSH2_ERROR_EAGAIN) {
1121 rc = LIBSSH2_ERROR_EAGAIN;
1127 (void)libssh2_session_last_error(sshc->ssh_session,
1129 failf(data, "Failure initializing sftp session: %s", err_msg);
1130 state(conn, SSH_SESSION_FREE);
1131 sshc->actualcode = CURLE_FAILED_INIT;
1135 state(conn, SSH_SFTP_REALPATH);
1138 case SSH_SFTP_REALPATH:
1140 char tempHome[PATH_MAX];
1143 * Get the "home" directory
1145 rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
1146 tempHome, PATH_MAX-1);
1147 if(rc == LIBSSH2_ERROR_EAGAIN) {
1151 /* It seems that this string is not always NULL terminated */
1152 tempHome[rc] = '\0';
1153 sshc->homedir = strdup(tempHome);
1154 if(!sshc->homedir) {
1155 state(conn, SSH_SFTP_CLOSE);
1156 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1159 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1162 /* Return the error type */
1163 err = sftp_libssh2_last_error(sshc->sftp_session);
1165 result = sftp_libssh2_error_to_CURLE(err);
1167 /* in this case, the error wasn't in the SFTP level but for example
1168 a time-out or similar */
1170 sshc->actualcode = result;
1171 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1173 state(conn, SSH_STOP);
1177 /* This is the last step in the SFTP connect phase. Do note that while
1178 we get the homedir here, we get the "workingpath" in the DO action
1179 since the homedir will remain the same between request but the
1180 working path will not. */
1181 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1182 state(conn, SSH_STOP);
1185 case SSH_SFTP_QUOTE_INIT:
1187 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1189 sshc->actualcode = result;
1190 state(conn, SSH_STOP);
1194 if(data->set.quote) {
1195 infof(data, "Sending quote commands\n");
1196 sshc->quote_item = data->set.quote;
1197 state(conn, SSH_SFTP_QUOTE);
1200 state(conn, SSH_SFTP_GETINFO);
1204 case SSH_SFTP_POSTQUOTE_INIT:
1205 if(data->set.postquote) {
1206 infof(data, "Sending quote commands\n");
1207 sshc->quote_item = data->set.postquote;
1208 state(conn, SSH_SFTP_QUOTE);
1211 state(conn, SSH_STOP);
1215 case SSH_SFTP_QUOTE:
1216 /* Send any quote commands */
1221 * Support some of the "FTP" commands
1223 char *cmd = sshc->quote_item->data;
1224 sshc->acceptfail = FALSE;
1226 /* if a command starts with an asterisk, which a legal SFTP command never
1227 can, the command will be allowed to fail without it causing any
1228 aborts or cancels etc. It will cause libcurl to act as if the command
1229 is successful, whatever the server reponds. */
1233 sshc->acceptfail = TRUE;
1236 if(curl_strequal("pwd", cmd)) {
1237 /* output debug output if that is requested */
1238 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1241 result = CURLE_OUT_OF_MEMORY;
1242 state(conn, SSH_SFTP_CLOSE);
1243 sshc->nextstate = SSH_NO_STATE;
1246 if(data->set.verbose) {
1247 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1248 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1250 /* this sends an FTP-like "header" to the header callback so that the
1251 current directory can be read very similar to how it is read when
1252 using ordinary FTP. */
1253 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1256 state(conn, SSH_SFTP_CLOSE);
1257 sshc->nextstate = SSH_NO_STATE;
1258 sshc->actualcode = result;
1261 state(conn, SSH_SFTP_NEXT_QUOTE);
1266 * the arguments following the command must be separated from the
1267 * command with a space so we can check for it unconditionally
1269 cp = strchr(cmd, ' ');
1271 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1272 state(conn, SSH_SFTP_CLOSE);
1273 sshc->nextstate = SSH_NO_STATE;
1274 sshc->actualcode = CURLE_QUOTE_ERROR;
1279 * also, every command takes at least one argument so we get that
1280 * first argument right now
1282 result = get_pathname(&cp, &sshc->quote_path1);
1284 if(result == CURLE_OUT_OF_MEMORY)
1285 failf(data, "Out of memory");
1287 failf(data, "Syntax error: Bad first parameter");
1288 state(conn, SSH_SFTP_CLOSE);
1289 sshc->nextstate = SSH_NO_STATE;
1290 sshc->actualcode = result;
1295 * SFTP is a binary protocol, so we don't send text commands
1296 * to the server. Instead, we scan for commands used by
1297 * OpenSSH's sftp program and call the appropriate libssh2
1300 if(curl_strnequal(cmd, "chgrp ", 6) ||
1301 curl_strnequal(cmd, "chmod ", 6) ||
1302 curl_strnequal(cmd, "chown ", 6) ) {
1303 /* attribute change */
1305 /* sshc->quote_path1 contains the mode to set */
1306 /* get the destination */
1307 result = get_pathname(&cp, &sshc->quote_path2);
1309 if(result == CURLE_OUT_OF_MEMORY)
1310 failf(data, "Out of memory");
1312 failf(data, "Syntax error in chgrp/chmod/chown: "
1313 "Bad second parameter");
1314 Curl_safefree(sshc->quote_path1);
1315 state(conn, SSH_SFTP_CLOSE);
1316 sshc->nextstate = SSH_NO_STATE;
1317 sshc->actualcode = result;
1320 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1321 state(conn, SSH_SFTP_QUOTE_STAT);
1324 else if(curl_strnequal(cmd, "ln ", 3) ||
1325 curl_strnequal(cmd, "symlink ", 8)) {
1326 /* symbolic linking */
1327 /* sshc->quote_path1 is the source */
1328 /* get the destination */
1329 result = get_pathname(&cp, &sshc->quote_path2);
1331 if(result == CURLE_OUT_OF_MEMORY)
1332 failf(data, "Out of memory");
1335 "Syntax error in ln/symlink: Bad second parameter");
1336 Curl_safefree(sshc->quote_path1);
1337 state(conn, SSH_SFTP_CLOSE);
1338 sshc->nextstate = SSH_NO_STATE;
1339 sshc->actualcode = result;
1342 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1345 else if(curl_strnequal(cmd, "mkdir ", 6)) {
1347 state(conn, SSH_SFTP_QUOTE_MKDIR);
1350 else if(curl_strnequal(cmd, "rename ", 7)) {
1352 /* first param is the source path */
1353 /* second param is the dest. path */
1354 result = get_pathname(&cp, &sshc->quote_path2);
1356 if(result == CURLE_OUT_OF_MEMORY)
1357 failf(data, "Out of memory");
1359 failf(data, "Syntax error in rename: Bad second parameter");
1360 Curl_safefree(sshc->quote_path1);
1361 state(conn, SSH_SFTP_CLOSE);
1362 sshc->nextstate = SSH_NO_STATE;
1363 sshc->actualcode = result;
1366 state(conn, SSH_SFTP_QUOTE_RENAME);
1369 else if(curl_strnequal(cmd, "rmdir ", 6)) {
1371 state(conn, SSH_SFTP_QUOTE_RMDIR);
1374 else if(curl_strnequal(cmd, "rm ", 3)) {
1375 state(conn, SSH_SFTP_QUOTE_UNLINK);
1378 #ifdef HAS_STATVFS_SUPPORT
1379 else if(curl_strnequal(cmd, "statvfs ", 8)) {
1380 state(conn, SSH_SFTP_QUOTE_STATVFS);
1385 failf(data, "Unknown SFTP command");
1386 Curl_safefree(sshc->quote_path1);
1387 Curl_safefree(sshc->quote_path2);
1388 state(conn, SSH_SFTP_CLOSE);
1389 sshc->nextstate = SSH_NO_STATE;
1390 sshc->actualcode = CURLE_QUOTE_ERROR;
1394 if(!sshc->quote_item) {
1395 state(conn, SSH_SFTP_GETINFO);
1399 case SSH_SFTP_NEXT_QUOTE:
1400 Curl_safefree(sshc->quote_path1);
1401 Curl_safefree(sshc->quote_path2);
1403 sshc->quote_item = sshc->quote_item->next;
1405 if(sshc->quote_item) {
1406 state(conn, SSH_SFTP_QUOTE);
1409 if(sshc->nextstate != SSH_NO_STATE) {
1410 state(conn, sshc->nextstate);
1411 sshc->nextstate = SSH_NO_STATE;
1414 state(conn, SSH_SFTP_GETINFO);
1419 case SSH_SFTP_QUOTE_STAT:
1421 char *cmd = sshc->quote_item->data;
1422 sshc->acceptfail = FALSE;
1424 /* if a command starts with an asterisk, which a legal SFTP command never
1425 can, the command will be allowed to fail without it causing any
1426 aborts or cancels etc. It will cause libcurl to act as if the command
1427 is successful, whatever the server reponds. */
1431 sshc->acceptfail = TRUE;
1434 if(!curl_strnequal(cmd, "chmod", 5)) {
1435 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1436 * set them both at once, we need to obtain the current ownership
1437 * first. This takes an extra protocol round trip.
1439 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1440 curlx_uztoui(strlen(sshc->quote_path2)),
1442 &sshc->quote_attrs);
1443 if(rc == LIBSSH2_ERROR_EAGAIN) {
1446 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1447 err = sftp_libssh2_last_error(sshc->sftp_session);
1448 Curl_safefree(sshc->quote_path1);
1449 Curl_safefree(sshc->quote_path2);
1450 failf(data, "Attempt to get SFTP stats failed: %s",
1451 sftp_libssh2_strerror(err));
1452 state(conn, SSH_SFTP_CLOSE);
1453 sshc->nextstate = SSH_NO_STATE;
1454 sshc->actualcode = CURLE_QUOTE_ERROR;
1459 /* Now set the new attributes... */
1460 if(curl_strnequal(cmd, "chgrp", 5)) {
1461 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1462 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1463 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1464 !sshc->acceptfail) {
1465 Curl_safefree(sshc->quote_path1);
1466 Curl_safefree(sshc->quote_path2);
1467 failf(data, "Syntax error: chgrp gid not a number");
1468 state(conn, SSH_SFTP_CLOSE);
1469 sshc->nextstate = SSH_NO_STATE;
1470 sshc->actualcode = CURLE_QUOTE_ERROR;
1474 else if(curl_strnequal(cmd, "chmod", 5)) {
1475 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1476 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1477 /* permissions are octal */
1478 if(sshc->quote_attrs.permissions == 0 &&
1479 !ISDIGIT(sshc->quote_path1[0])) {
1480 Curl_safefree(sshc->quote_path1);
1481 Curl_safefree(sshc->quote_path2);
1482 failf(data, "Syntax error: chmod permissions not a number");
1483 state(conn, SSH_SFTP_CLOSE);
1484 sshc->nextstate = SSH_NO_STATE;
1485 sshc->actualcode = CURLE_QUOTE_ERROR;
1489 else if(curl_strnequal(cmd, "chown", 5)) {
1490 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1491 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1492 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1493 !sshc->acceptfail) {
1494 Curl_safefree(sshc->quote_path1);
1495 Curl_safefree(sshc->quote_path2);
1496 failf(data, "Syntax error: chown uid not a number");
1497 state(conn, SSH_SFTP_CLOSE);
1498 sshc->nextstate = SSH_NO_STATE;
1499 sshc->actualcode = CURLE_QUOTE_ERROR;
1504 /* Now send the completed structure... */
1505 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1509 case SSH_SFTP_QUOTE_SETSTAT:
1510 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1511 curlx_uztoui(strlen(sshc->quote_path2)),
1512 LIBSSH2_SFTP_SETSTAT,
1513 &sshc->quote_attrs);
1514 if(rc == LIBSSH2_ERROR_EAGAIN) {
1517 else if(rc != 0 && !sshc->acceptfail) {
1518 err = sftp_libssh2_last_error(sshc->sftp_session);
1519 Curl_safefree(sshc->quote_path1);
1520 Curl_safefree(sshc->quote_path2);
1521 failf(data, "Attempt to set SFTP stats failed: %s",
1522 sftp_libssh2_strerror(err));
1523 state(conn, SSH_SFTP_CLOSE);
1524 sshc->nextstate = SSH_NO_STATE;
1525 sshc->actualcode = CURLE_QUOTE_ERROR;
1528 state(conn, SSH_SFTP_NEXT_QUOTE);
1531 case SSH_SFTP_QUOTE_SYMLINK:
1532 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1533 curlx_uztoui(strlen(sshc->quote_path1)),
1535 curlx_uztoui(strlen(sshc->quote_path2)),
1536 LIBSSH2_SFTP_SYMLINK);
1537 if(rc == LIBSSH2_ERROR_EAGAIN) {
1540 else if(rc != 0 && !sshc->acceptfail) {
1541 err = sftp_libssh2_last_error(sshc->sftp_session);
1542 Curl_safefree(sshc->quote_path1);
1543 Curl_safefree(sshc->quote_path2);
1544 failf(data, "symlink command failed: %s",
1545 sftp_libssh2_strerror(err));
1546 state(conn, SSH_SFTP_CLOSE);
1547 sshc->nextstate = SSH_NO_STATE;
1548 sshc->actualcode = CURLE_QUOTE_ERROR;
1551 state(conn, SSH_SFTP_NEXT_QUOTE);
1554 case SSH_SFTP_QUOTE_MKDIR:
1555 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1556 curlx_uztoui(strlen(sshc->quote_path1)),
1557 data->set.new_directory_perms);
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, "mkdir 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_QUOTE_RENAME:
1574 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1575 curlx_uztoui(strlen(sshc->quote_path1)),
1577 curlx_uztoui(strlen(sshc->quote_path2)),
1578 LIBSSH2_SFTP_RENAME_OVERWRITE |
1579 LIBSSH2_SFTP_RENAME_ATOMIC |
1580 LIBSSH2_SFTP_RENAME_NATIVE);
1582 if(rc == LIBSSH2_ERROR_EAGAIN) {
1585 else if(rc != 0 && !sshc->acceptfail) {
1586 err = sftp_libssh2_last_error(sshc->sftp_session);
1587 Curl_safefree(sshc->quote_path1);
1588 Curl_safefree(sshc->quote_path2);
1589 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1590 state(conn, SSH_SFTP_CLOSE);
1591 sshc->nextstate = SSH_NO_STATE;
1592 sshc->actualcode = CURLE_QUOTE_ERROR;
1595 state(conn, SSH_SFTP_NEXT_QUOTE);
1598 case SSH_SFTP_QUOTE_RMDIR:
1599 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1600 curlx_uztoui(strlen(sshc->quote_path1)));
1601 if(rc == LIBSSH2_ERROR_EAGAIN) {
1604 else if(rc != 0 && !sshc->acceptfail) {
1605 err = sftp_libssh2_last_error(sshc->sftp_session);
1606 Curl_safefree(sshc->quote_path1);
1607 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1608 state(conn, SSH_SFTP_CLOSE);
1609 sshc->nextstate = SSH_NO_STATE;
1610 sshc->actualcode = CURLE_QUOTE_ERROR;
1613 state(conn, SSH_SFTP_NEXT_QUOTE);
1616 case SSH_SFTP_QUOTE_UNLINK:
1617 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1618 curlx_uztoui(strlen(sshc->quote_path1)));
1619 if(rc == LIBSSH2_ERROR_EAGAIN) {
1622 else if(rc != 0 && !sshc->acceptfail) {
1623 err = sftp_libssh2_last_error(sshc->sftp_session);
1624 Curl_safefree(sshc->quote_path1);
1625 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1626 state(conn, SSH_SFTP_CLOSE);
1627 sshc->nextstate = SSH_NO_STATE;
1628 sshc->actualcode = CURLE_QUOTE_ERROR;
1631 state(conn, SSH_SFTP_NEXT_QUOTE);
1634 #ifdef HAS_STATVFS_SUPPORT
1635 case SSH_SFTP_QUOTE_STATVFS:
1637 LIBSSH2_SFTP_STATVFS statvfs;
1638 rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1,
1639 curlx_uztoui(strlen(sshc->quote_path1)),
1642 if(rc == LIBSSH2_ERROR_EAGAIN) {
1645 else if(rc != 0 && !sshc->acceptfail) {
1646 err = sftp_libssh2_last_error(sshc->sftp_session);
1647 Curl_safefree(sshc->quote_path1);
1648 failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(err));
1649 state(conn, SSH_SFTP_CLOSE);
1650 sshc->nextstate = SSH_NO_STATE;
1651 sshc->actualcode = CURLE_QUOTE_ERROR;
1655 char *tmp = aprintf("statvfs:\n"
1656 "f_bsize: %llu\n" "f_frsize: %llu\n"
1657 "f_blocks: %llu\n" "f_bfree: %llu\n"
1658 "f_bavail: %llu\n" "f_files: %llu\n"
1659 "f_ffree: %llu\n" "f_favail: %llu\n"
1660 "f_fsid: %llu\n" "f_flag: %llu\n"
1661 "f_namemax: %llu\n",
1662 statvfs.f_bsize, statvfs.f_frsize,
1663 statvfs.f_blocks, statvfs.f_bfree,
1664 statvfs.f_bavail, statvfs.f_files,
1665 statvfs.f_ffree, statvfs.f_favail,
1666 statvfs.f_fsid, statvfs.f_flag,
1669 result = CURLE_OUT_OF_MEMORY;
1670 state(conn, SSH_SFTP_CLOSE);
1671 sshc->nextstate = SSH_NO_STATE;
1675 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1678 state(conn, SSH_SFTP_CLOSE);
1679 sshc->nextstate = SSH_NO_STATE;
1680 sshc->actualcode = result;
1683 state(conn, SSH_SFTP_NEXT_QUOTE);
1687 case SSH_SFTP_GETINFO:
1689 if(data->set.get_filetime) {
1690 state(conn, SSH_SFTP_FILETIME);
1693 state(conn, SSH_SFTP_TRANS_INIT);
1698 case SSH_SFTP_FILETIME:
1700 LIBSSH2_SFTP_ATTRIBUTES attrs;
1702 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1703 curlx_uztoui(strlen(sftp_scp->path)),
1704 LIBSSH2_SFTP_STAT, &attrs);
1705 if(rc == LIBSSH2_ERROR_EAGAIN) {
1709 data->info.filetime = (long)attrs.mtime;
1712 state(conn, SSH_SFTP_TRANS_INIT);
1716 case SSH_SFTP_TRANS_INIT:
1717 if(data->set.upload)
1718 state(conn, SSH_SFTP_UPLOAD_INIT);
1720 if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1721 state(conn, SSH_SFTP_READDIR_INIT);
1723 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1727 case SSH_SFTP_UPLOAD_INIT:
1729 unsigned long flags;
1731 * NOTE!!! libssh2 requires that the destination path is a full path
1732 * that includes the destination file and name OR ends in a "/"
1733 * If this is not done the destination file will be named the
1734 * same name as the last directory in the path.
1737 if(data->state.resume_from != 0) {
1738 LIBSSH2_SFTP_ATTRIBUTES attrs;
1739 if(data->state.resume_from < 0) {
1740 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1741 curlx_uztoui(strlen(sftp_scp->path)),
1742 LIBSSH2_SFTP_STAT, &attrs);
1743 if(rc == LIBSSH2_ERROR_EAGAIN) {
1747 data->state.resume_from = 0;
1750 curl_off_t size = attrs.filesize;
1752 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
1753 return CURLE_BAD_DOWNLOAD_RESUME;
1755 data->state.resume_from = attrs.filesize;
1760 if(data->set.ftp_append)
1761 /* Try to open for append, but create if nonexisting */
1762 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1763 else if(data->state.resume_from > 0)
1764 /* If we have restart position then open for append */
1765 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1767 /* Clear file before writing (normal behaviour) */
1768 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1771 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1772 curlx_uztoui(strlen(sftp_scp->path)),
1773 flags, data->set.new_file_perms,
1774 LIBSSH2_SFTP_OPENFILE);
1776 if(!sshc->sftp_handle) {
1777 rc = libssh2_session_last_errno(sshc->ssh_session);
1779 if(LIBSSH2_ERROR_EAGAIN == rc)
1782 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1783 /* only when there was an SFTP protocol error can we extract
1785 err = sftp_libssh2_last_error(sshc->sftp_session);
1787 err = -1; /* not an sftp error at all */
1789 if(sshc->secondCreateDirs) {
1790 state(conn, SSH_SFTP_CLOSE);
1791 sshc->actualcode = err>= LIBSSH2_FX_OK?
1792 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1793 failf(data, "Creating the dir/file failed: %s",
1794 sftp_libssh2_strerror(err));
1797 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1798 (err == LIBSSH2_FX_FAILURE) ||
1799 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1800 (data->set.ftp_create_missing_dirs &&
1801 (strlen(sftp_scp->path) > 1))) {
1802 /* try to create the path remotely */
1803 sshc->secondCreateDirs = 1;
1804 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1807 state(conn, SSH_SFTP_CLOSE);
1808 sshc->actualcode = err>= LIBSSH2_FX_OK?
1809 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1810 if(!sshc->actualcode) {
1811 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1812 zero even though libssh2_sftp_open() failed previously! We need
1813 to work around that! */
1814 sshc->actualcode = CURLE_SSH;
1817 failf(data, "Upload failed: %s (%d/%d)",
1818 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1824 /* If we have a restart point then we need to seek to the correct
1826 if(data->state.resume_from > 0) {
1827 /* Let's read off the proper amount of bytes from the input. */
1828 if(conn->seek_func) {
1829 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1833 if(seekerr != CURL_SEEKFUNC_OK) {
1835 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1836 failf(data, "Could not seek stream");
1837 return CURLE_FTP_COULDNT_USE_REST;
1839 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1841 curl_off_t passed=0;
1843 size_t readthisamountnow =
1844 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1845 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1847 size_t actuallyread =
1848 data->state.fread_func(data->state.buffer, 1,
1849 readthisamountnow, data->state.in);
1851 passed += actuallyread;
1852 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1853 /* this checks for greater-than only to make sure that the
1854 CURL_READFUNC_ABORT return code still aborts */
1855 failf(data, "Failed to read data");
1856 return CURLE_FTP_COULDNT_USE_REST;
1858 } while(passed < data->state.resume_from);
1862 /* now, decrease the size of the read */
1863 if(data->state.infilesize > 0) {
1864 data->state.infilesize -= data->state.resume_from;
1865 data->req.size = data->state.infilesize;
1866 Curl_pgrsSetUploadSize(data, data->state.infilesize);
1869 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1871 if(data->state.infilesize > 0) {
1872 data->req.size = data->state.infilesize;
1873 Curl_pgrsSetUploadSize(data, data->state.infilesize);
1876 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1878 /* not set by Curl_setup_transfer to preserve keepon bits */
1879 conn->sockfd = conn->writesockfd;
1882 state(conn, SSH_SFTP_CLOSE);
1883 sshc->actualcode = result;
1886 /* store this original bitmask setup to use later on if we can't
1887 figure out a "real" bitmask */
1888 sshc->orig_waitfor = data->req.keepon;
1890 /* we want to use the _sending_ function even when the socket turns
1891 out readable as the underlying libssh2 sftp send function will deal
1892 with both accordingly */
1893 conn->cselect_bits = CURL_CSELECT_OUT;
1895 /* since we don't really wait for anything at this point, we want the
1896 state machine to move on as soon as possible so we set a very short
1898 Curl_expire(data, 0);
1900 state(conn, SSH_STOP);
1905 case SSH_SFTP_CREATE_DIRS_INIT:
1906 if(strlen(sftp_scp->path) > 1) {
1907 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1908 state(conn, SSH_SFTP_CREATE_DIRS);
1911 state(conn, SSH_SFTP_UPLOAD_INIT);
1915 case SSH_SFTP_CREATE_DIRS:
1916 sshc->slash_pos = strchr(sshc->slash_pos, '/');
1917 if(sshc->slash_pos) {
1918 *sshc->slash_pos = 0;
1920 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1921 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1925 state(conn, SSH_SFTP_UPLOAD_INIT);
1929 case SSH_SFTP_CREATE_DIRS_MKDIR:
1930 /* 'mode' - parameter is preliminary - default to 0644 */
1931 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1932 curlx_uztoui(strlen(sftp_scp->path)),
1933 data->set.new_directory_perms);
1934 if(rc == LIBSSH2_ERROR_EAGAIN) {
1937 *sshc->slash_pos = '/';
1941 * Abort if failure wasn't that the dir already exists or the
1942 * permission was denied (creation might succeed further down the
1943 * path) - retry on unspecific FAILURE also
1945 err = sftp_libssh2_last_error(sshc->sftp_session);
1946 if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1947 (err != LIBSSH2_FX_FAILURE) &&
1948 (err != LIBSSH2_FX_PERMISSION_DENIED)) {
1949 result = sftp_libssh2_error_to_CURLE(err);
1950 state(conn, SSH_SFTP_CLOSE);
1951 sshc->actualcode = result?result:CURLE_SSH;
1955 state(conn, SSH_SFTP_CREATE_DIRS);
1958 case SSH_SFTP_READDIR_INIT:
1959 Curl_pgrsSetDownloadSize(data, -1);
1960 if(data->set.opt_no_body) {
1961 state(conn, SSH_STOP);
1966 * This is a directory that we are trying to get, so produce a directory
1969 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1972 strlen(sftp_scp->path)),
1973 0, 0, LIBSSH2_SFTP_OPENDIR);
1974 if(!sshc->sftp_handle) {
1975 if(libssh2_session_last_errno(sshc->ssh_session) ==
1976 LIBSSH2_ERROR_EAGAIN) {
1977 rc = LIBSSH2_ERROR_EAGAIN;
1981 err = sftp_libssh2_last_error(sshc->sftp_session);
1982 failf(data, "Could not open directory for reading: %s",
1983 sftp_libssh2_strerror(err));
1984 state(conn, SSH_SFTP_CLOSE);
1985 result = sftp_libssh2_error_to_CURLE(err);
1986 sshc->actualcode = result?result:CURLE_SSH;
1990 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1991 state(conn, SSH_SFTP_CLOSE);
1992 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1995 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1996 Curl_safefree(sshc->readdir_filename);
1997 state(conn, SSH_SFTP_CLOSE);
1998 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2001 state(conn, SSH_SFTP_READDIR);
2004 case SSH_SFTP_READDIR:
2005 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
2006 sshc->readdir_filename,
2008 sshc->readdir_longentry,
2010 &sshc->readdir_attrs);
2011 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
2012 rc = LIBSSH2_ERROR_EAGAIN;
2015 if(sshc->readdir_len > 0) {
2016 sshc->readdir_filename[sshc->readdir_len] = '\0';
2018 if(data->set.ftp_list_only) {
2021 tmpLine = aprintf("%s\n", sshc->readdir_filename);
2022 if(tmpLine == NULL) {
2023 state(conn, SSH_SFTP_CLOSE);
2024 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2027 result = Curl_client_write(conn, CLIENTWRITE_BODY,
2028 tmpLine, sshc->readdir_len+1);
2032 state(conn, SSH_STOP);
2035 /* since this counts what we send to the client, we include the
2036 newline in this counter */
2037 data->req.bytecount += sshc->readdir_len+1;
2039 /* output debug output if that is requested */
2040 if(data->set.verbose) {
2041 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
2042 sshc->readdir_len, conn);
2046 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
2047 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
2048 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
2049 if(!sshc->readdir_line) {
2050 Curl_safefree(sshc->readdir_filename);
2051 Curl_safefree(sshc->readdir_longentry);
2052 state(conn, SSH_SFTP_CLOSE);
2053 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2057 memcpy(sshc->readdir_line, sshc->readdir_longentry,
2058 sshc->readdir_currLen);
2059 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
2060 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
2061 LIBSSH2_SFTP_S_IFLNK)) {
2062 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
2063 if(sshc->readdir_linkPath == NULL) {
2064 Curl_safefree(sshc->readdir_filename);
2065 Curl_safefree(sshc->readdir_longentry);
2066 state(conn, SSH_SFTP_CLOSE);
2067 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2071 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
2072 sshc->readdir_filename);
2073 state(conn, SSH_SFTP_READDIR_LINK);
2076 state(conn, SSH_SFTP_READDIR_BOTTOM);
2080 else if(sshc->readdir_len == 0) {
2081 Curl_safefree(sshc->readdir_filename);
2082 Curl_safefree(sshc->readdir_longentry);
2083 state(conn, SSH_SFTP_READDIR_DONE);
2086 else if(sshc->readdir_len <= 0) {
2087 err = sftp_libssh2_last_error(sshc->sftp_session);
2088 result = sftp_libssh2_error_to_CURLE(err);
2089 sshc->actualcode = result?result:CURLE_SSH;
2090 failf(data, "Could not open remote file for reading: %s :: %d",
2091 sftp_libssh2_strerror(err),
2092 libssh2_session_last_errno(sshc->ssh_session));
2093 Curl_safefree(sshc->readdir_filename);
2094 Curl_safefree(sshc->readdir_longentry);
2095 state(conn, SSH_SFTP_CLOSE);
2100 case SSH_SFTP_READDIR_LINK:
2102 libssh2_sftp_symlink_ex(sshc->sftp_session,
2103 sshc->readdir_linkPath,
2104 curlx_uztoui(strlen(sshc->readdir_linkPath)),
2105 sshc->readdir_filename,
2106 PATH_MAX, LIBSSH2_SFTP_READLINK);
2107 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
2108 rc = LIBSSH2_ERROR_EAGAIN;
2111 Curl_safefree(sshc->readdir_linkPath);
2113 /* get room for the filename and extra output */
2114 sshc->readdir_totalLen += 4 + sshc->readdir_len;
2115 new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
2116 if(!new_readdir_line) {
2117 Curl_safefree(sshc->readdir_line);
2118 Curl_safefree(sshc->readdir_filename);
2119 Curl_safefree(sshc->readdir_longentry);
2120 state(conn, SSH_SFTP_CLOSE);
2121 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2124 sshc->readdir_line = new_readdir_line;
2126 sshc->readdir_currLen += snprintf(sshc->readdir_line +
2127 sshc->readdir_currLen,
2128 sshc->readdir_totalLen -
2129 sshc->readdir_currLen,
2131 sshc->readdir_filename);
2133 state(conn, SSH_SFTP_READDIR_BOTTOM);
2136 case SSH_SFTP_READDIR_BOTTOM:
2137 sshc->readdir_currLen += snprintf(sshc->readdir_line +
2138 sshc->readdir_currLen,
2139 sshc->readdir_totalLen -
2140 sshc->readdir_currLen, "\n");
2141 result = Curl_client_write(conn, CLIENTWRITE_BODY,
2143 sshc->readdir_currLen);
2147 /* output debug output if that is requested */
2148 if(data->set.verbose) {
2149 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
2150 sshc->readdir_currLen, conn);
2152 data->req.bytecount += sshc->readdir_currLen;
2154 Curl_safefree(sshc->readdir_line);
2156 state(conn, SSH_STOP);
2159 state(conn, SSH_SFTP_READDIR);
2162 case SSH_SFTP_READDIR_DONE:
2163 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
2164 LIBSSH2_ERROR_EAGAIN) {
2165 rc = LIBSSH2_ERROR_EAGAIN;
2168 sshc->sftp_handle = NULL;
2169 Curl_safefree(sshc->readdir_filename);
2170 Curl_safefree(sshc->readdir_longentry);
2172 /* no data to transfer */
2173 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2174 state(conn, SSH_STOP);
2177 case SSH_SFTP_DOWNLOAD_INIT:
2179 * Work on getting the specified file
2182 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
2183 curlx_uztoui(strlen(sftp_scp->path)),
2184 LIBSSH2_FXF_READ, data->set.new_file_perms,
2185 LIBSSH2_SFTP_OPENFILE);
2186 if(!sshc->sftp_handle) {
2187 if(libssh2_session_last_errno(sshc->ssh_session) ==
2188 LIBSSH2_ERROR_EAGAIN) {
2189 rc = LIBSSH2_ERROR_EAGAIN;
2193 err = sftp_libssh2_last_error(sshc->sftp_session);
2194 failf(data, "Could not open remote file for reading: %s",
2195 sftp_libssh2_strerror(err));
2196 state(conn, SSH_SFTP_CLOSE);
2197 result = sftp_libssh2_error_to_CURLE(err);
2198 sshc->actualcode = result?result:CURLE_SSH;
2202 state(conn, SSH_SFTP_DOWNLOAD_STAT);
2205 case SSH_SFTP_DOWNLOAD_STAT:
2207 LIBSSH2_SFTP_ATTRIBUTES attrs;
2209 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
2210 curlx_uztoui(strlen(sftp_scp->path)),
2211 LIBSSH2_SFTP_STAT, &attrs);
2212 if(rc == LIBSSH2_ERROR_EAGAIN) {
2216 !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
2217 (attrs.filesize == 0)) {
2219 * libssh2_sftp_open() didn't return an error, so maybe the server
2220 * just doesn't support stat()
2221 * OR the server doesn't return a file size with a stat()
2224 data->req.size = -1;
2225 data->req.maxdownload = -1;
2226 Curl_pgrsSetDownloadSize(data, -1);
2229 curl_off_t size = attrs.filesize;
2232 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
2233 return CURLE_BAD_DOWNLOAD_RESUME;
2235 if(conn->data->state.use_range) {
2236 curl_off_t from, to;
2240 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2241 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2243 to=curlx_strtoofft(ptr, &ptr2, 0);
2244 if((ptr == ptr2) /* no "to" value given */
2249 /* from is relative to end of file */
2253 failf(data, "Offset (%"
2254 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2255 CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
2256 return CURLE_BAD_DOWNLOAD_RESUME;
2263 size = to - from + 1;
2266 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2268 data->req.size = size;
2269 data->req.maxdownload = size;
2270 Curl_pgrsSetDownloadSize(data, size);
2273 /* We can resume if we can seek to the resume position */
2274 if(data->state.resume_from) {
2275 if(data->state.resume_from < 0) {
2276 /* We're supposed to download the last abs(from) bytes */
2277 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2278 failf(data, "Offset (%"
2279 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2280 CURL_FORMAT_CURL_OFF_T ")",
2281 data->state.resume_from, attrs.filesize);
2282 return CURLE_BAD_DOWNLOAD_RESUME;
2284 /* download from where? */
2285 data->state.resume_from += attrs.filesize;
2288 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2289 failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
2290 ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
2291 data->state.resume_from, attrs.filesize);
2292 return CURLE_BAD_DOWNLOAD_RESUME;
2295 /* Does a completed file need to be seeked and started or closed ? */
2296 /* Now store the number of bytes we are expected to download */
2297 data->req.size = attrs.filesize - data->state.resume_from;
2298 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2299 Curl_pgrsSetDownloadSize(data,
2300 attrs.filesize - data->state.resume_from);
2301 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2305 /* Setup the actual download */
2306 if(data->req.size == 0) {
2307 /* no data to transfer */
2308 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2309 infof(data, "File already completely downloaded\n");
2310 state(conn, SSH_STOP);
2314 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2315 FALSE, NULL, -1, NULL);
2317 /* not set by Curl_setup_transfer to preserve keepon bits */
2318 conn->writesockfd = conn->sockfd;
2320 /* we want to use the _receiving_ function even when the socket turns
2321 out writableable as the underlying libssh2 recv function will deal
2322 with both accordingly */
2323 conn->cselect_bits = CURL_CSELECT_IN;
2326 /* this should never occur; the close state should be entered
2327 at the time the error occurs */
2328 state(conn, SSH_SFTP_CLOSE);
2329 sshc->actualcode = result;
2332 state(conn, SSH_STOP);
2336 case SSH_SFTP_CLOSE:
2337 if(sshc->sftp_handle) {
2338 rc = libssh2_sftp_close(sshc->sftp_handle);
2339 if(rc == LIBSSH2_ERROR_EAGAIN) {
2343 infof(data, "Failed to close libssh2 file\n");
2345 sshc->sftp_handle = NULL;
2348 Curl_safefree(sftp_scp->path);
2350 DEBUGF(infof(data, "SFTP DONE done\n"));
2352 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2353 After nextstate is executed, the control should come back to
2354 SSH_SFTP_CLOSE to pass the correct result back */
2355 if(sshc->nextstate != SSH_NO_STATE &&
2356 sshc->nextstate != SSH_SFTP_CLOSE) {
2357 state(conn, sshc->nextstate);
2358 sshc->nextstate = SSH_SFTP_CLOSE;
2361 state(conn, SSH_STOP);
2362 result = sshc->actualcode;
2366 case SSH_SFTP_SHUTDOWN:
2367 /* during times we get here due to a broken transfer and then the
2368 sftp_handle might not have been taken down so make sure that is done
2369 before we proceed */
2371 if(sshc->sftp_handle) {
2372 rc = libssh2_sftp_close(sshc->sftp_handle);
2373 if(rc == LIBSSH2_ERROR_EAGAIN) {
2377 infof(data, "Failed to close libssh2 file\n");
2379 sshc->sftp_handle = NULL;
2381 if(sshc->sftp_session) {
2382 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2383 if(rc == LIBSSH2_ERROR_EAGAIN) {
2387 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2389 sshc->sftp_session = NULL;
2392 Curl_safefree(sshc->homedir);
2393 conn->data->state.most_recent_ftp_entrypath = NULL;
2395 state(conn, SSH_SESSION_DISCONNECT);
2398 case SSH_SCP_TRANS_INIT:
2399 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2401 sshc->actualcode = result;
2402 state(conn, SSH_STOP);
2406 if(data->set.upload) {
2407 if(data->state.infilesize < 0) {
2408 failf(data, "SCP requires a known file size for upload");
2409 sshc->actualcode = CURLE_UPLOAD_FAILED;
2410 state(conn, SSH_SCP_CHANNEL_FREE);
2413 state(conn, SSH_SCP_UPLOAD_INIT);
2416 state(conn, SSH_SCP_DOWNLOAD_INIT);
2420 case SSH_SCP_UPLOAD_INIT:
2422 * libssh2 requires that the destination path is a full path that
2423 * includes the destination file and name OR ends in a "/" . If this is
2424 * not done the destination file will be named the same name as the last
2425 * directory in the path.
2428 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2429 data->state.infilesize);
2430 if(!sshc->ssh_channel) {
2431 if(libssh2_session_last_errno(sshc->ssh_session) ==
2432 LIBSSH2_ERROR_EAGAIN) {
2433 rc = LIBSSH2_ERROR_EAGAIN;
2440 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2441 &err_msg, NULL, 0));
2442 failf(conn->data, "%s", err_msg);
2443 state(conn, SSH_SCP_CHANNEL_FREE);
2444 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2450 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2453 /* not set by Curl_setup_transfer to preserve keepon bits */
2454 conn->sockfd = conn->writesockfd;
2457 state(conn, SSH_SCP_CHANNEL_FREE);
2458 sshc->actualcode = result;
2461 /* store this original bitmask setup to use later on if we can't
2462 figure out a "real" bitmask */
2463 sshc->orig_waitfor = data->req.keepon;
2465 /* we want to use the _sending_ function even when the socket turns
2466 out readable as the underlying libssh2 scp send function will deal
2467 with both accordingly */
2468 conn->cselect_bits = CURL_CSELECT_OUT;
2470 state(conn, SSH_STOP);
2474 case SSH_SCP_DOWNLOAD_INIT:
2476 curl_off_t bytecount;
2479 * We must check the remote file; if it is a directory no values will
2484 * If support for >2GB files exists, use it.
2487 /* get a fresh new channel from the ssh layer */
2488 #if LIBSSH2_VERSION_NUM < 0x010700
2490 memset(&sb, 0, sizeof(struct stat));
2491 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2492 sftp_scp->path, &sb);
2494 libssh2_struct_stat sb;
2495 memset(&sb, 0, sizeof(libssh2_struct_stat));
2496 sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session,
2497 sftp_scp->path, &sb);
2500 if(!sshc->ssh_channel) {
2501 if(libssh2_session_last_errno(sshc->ssh_session) ==
2502 LIBSSH2_ERROR_EAGAIN) {
2503 rc = LIBSSH2_ERROR_EAGAIN;
2510 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2511 &err_msg, NULL, 0));
2512 failf(conn->data, "%s", err_msg);
2513 state(conn, SSH_SCP_CHANNEL_FREE);
2514 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2520 bytecount = (curl_off_t)sb.st_size;
2521 data->req.maxdownload = (curl_off_t)sb.st_size;
2522 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2524 /* not set by Curl_setup_transfer to preserve keepon bits */
2525 conn->writesockfd = conn->sockfd;
2527 /* we want to use the _receiving_ function even when the socket turns
2528 out writableable as the underlying libssh2 recv function will deal
2529 with both accordingly */
2530 conn->cselect_bits = CURL_CSELECT_IN;
2533 state(conn, SSH_SCP_CHANNEL_FREE);
2534 sshc->actualcode = result;
2537 state(conn, SSH_STOP);
2542 if(data->set.upload)
2543 state(conn, SSH_SCP_SEND_EOF);
2545 state(conn, SSH_SCP_CHANNEL_FREE);
2548 case SSH_SCP_SEND_EOF:
2549 if(sshc->ssh_channel) {
2550 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2551 if(rc == LIBSSH2_ERROR_EAGAIN) {
2555 infof(data, "Failed to send libssh2 channel EOF\n");
2558 state(conn, SSH_SCP_WAIT_EOF);
2561 case SSH_SCP_WAIT_EOF:
2562 if(sshc->ssh_channel) {
2563 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2564 if(rc == LIBSSH2_ERROR_EAGAIN) {
2568 infof(data, "Failed to get channel EOF: %d\n", rc);
2571 state(conn, SSH_SCP_WAIT_CLOSE);
2574 case SSH_SCP_WAIT_CLOSE:
2575 if(sshc->ssh_channel) {
2576 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2577 if(rc == LIBSSH2_ERROR_EAGAIN) {
2581 infof(data, "Channel failed to close: %d\n", rc);
2584 state(conn, SSH_SCP_CHANNEL_FREE);
2587 case SSH_SCP_CHANNEL_FREE:
2588 if(sshc->ssh_channel) {
2589 rc = libssh2_channel_free(sshc->ssh_channel);
2590 if(rc == LIBSSH2_ERROR_EAGAIN) {
2594 infof(data, "Failed to free libssh2 scp subsystem\n");
2596 sshc->ssh_channel = NULL;
2598 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2600 state(conn, SSH_SESSION_DISCONNECT);
2602 state(conn, SSH_STOP);
2603 result = sshc->actualcode;
2606 case SSH_SESSION_DISCONNECT:
2607 /* during weird times when we've been prematurely aborted, the channel
2608 is still alive when we reach this state and we MUST kill the channel
2610 if(sshc->ssh_channel) {
2611 rc = libssh2_channel_free(sshc->ssh_channel);
2612 if(rc == LIBSSH2_ERROR_EAGAIN) {
2616 infof(data, "Failed to free libssh2 scp subsystem\n");
2618 sshc->ssh_channel = NULL;
2621 if(sshc->ssh_session) {
2622 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2623 if(rc == LIBSSH2_ERROR_EAGAIN) {
2627 infof(data, "Failed to disconnect libssh2 session\n");
2631 Curl_safefree(sshc->homedir);
2632 conn->data->state.most_recent_ftp_entrypath = NULL;
2634 state(conn, SSH_SESSION_FREE);
2637 case SSH_SESSION_FREE:
2638 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2640 libssh2_knownhost_free(sshc->kh);
2645 #ifdef HAVE_LIBSSH2_AGENT_API
2646 if(sshc->ssh_agent) {
2647 rc = libssh2_agent_disconnect(sshc->ssh_agent);
2648 if(rc == LIBSSH2_ERROR_EAGAIN) {
2652 infof(data, "Failed to disconnect from libssh2 agent\n");
2654 libssh2_agent_free (sshc->ssh_agent);
2655 sshc->ssh_agent = NULL;
2657 /* NB: there is no need to free identities, they are part of internal
2659 sshc->sshagent_identity = NULL;
2660 sshc->sshagent_prev_identity = NULL;
2664 if(sshc->ssh_session) {
2665 rc = libssh2_session_free(sshc->ssh_session);
2666 if(rc == LIBSSH2_ERROR_EAGAIN) {
2670 infof(data, "Failed to free libssh2 session\n");
2672 sshc->ssh_session = NULL;
2675 /* worst-case scenario cleanup */
2677 DEBUGASSERT(sshc->ssh_session == NULL);
2678 DEBUGASSERT(sshc->ssh_channel == NULL);
2679 DEBUGASSERT(sshc->sftp_session == NULL);
2680 DEBUGASSERT(sshc->sftp_handle == NULL);
2681 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2682 DEBUGASSERT(sshc->kh == NULL);
2684 #ifdef HAVE_LIBSSH2_AGENT_API
2685 DEBUGASSERT(sshc->ssh_agent == NULL);
2688 Curl_safefree(sshc->rsa_pub);
2689 Curl_safefree(sshc->rsa);
2691 Curl_safefree(sshc->quote_path1);
2692 Curl_safefree(sshc->quote_path2);
2694 Curl_safefree(sshc->homedir);
2696 Curl_safefree(sshc->readdir_filename);
2697 Curl_safefree(sshc->readdir_longentry);
2698 Curl_safefree(sshc->readdir_line);
2699 Curl_safefree(sshc->readdir_linkPath);
2701 /* the code we are about to return */
2702 result = sshc->actualcode;
2704 memset(sshc, 0, sizeof(struct ssh_conn));
2706 connclose(conn, "SSH session free");
2707 sshc->state = SSH_SESSION_FREE; /* current */
2708 sshc->nextstate = SSH_NO_STATE;
2709 state(conn, SSH_STOP);
2713 /* fallthrough, just stop! */
2715 /* internal error */
2716 sshc->nextstate = SSH_NO_STATE;
2717 state(conn, SSH_STOP);
2721 } while(!rc && (sshc->state != SSH_STOP));
2723 if(rc == LIBSSH2_ERROR_EAGAIN) {
2724 /* we would block, we need to wait for the socket to be ready (in the
2725 right direction too)! */
2732 /* called by the multi interface to figure out what socket(s) to wait for and
2733 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2734 static int ssh_perform_getsock(const struct connectdata *conn,
2735 curl_socket_t *sock, /* points to numsocks
2736 number of sockets */
2739 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2740 int bitmap = GETSOCK_BLANK;
2743 sock[0] = conn->sock[FIRSTSOCKET];
2745 if(conn->waitfor & KEEP_RECV)
2746 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2748 if(conn->waitfor & KEEP_SEND)
2749 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2753 /* if we don't know the direction we can use the generic *_getsock()
2754 function even for the protocol_connect and doing states */
2755 return Curl_single_getsock(conn, sock, numsocks);
2759 /* Generic function called by the multi interface to figure out what socket(s)
2760 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2761 static int ssh_getsock(struct connectdata *conn,
2762 curl_socket_t *sock, /* points to numsocks number
2766 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2770 /* if we don't know any direction we can just play along as we used to and
2771 not provide any sensible info */
2772 return GETSOCK_BLANK;
2774 /* if we know the direction we can use the generic *_getsock() function even
2775 for the protocol_connect and doing states */
2776 return ssh_perform_getsock(conn, sock, numsocks);
2780 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2782 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2783 * function is used to figure out in what direction and stores this info so
2784 * that the multi interface can take advantage of it. Make sure to call this
2785 * function in all cases so that when it _doesn't_ return EAGAIN we can
2786 * restore the default wait bits.
2788 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2790 struct ssh_conn *sshc = &conn->proto.sshc;
2792 if(block && (dir = libssh2_session_block_directions(sshc->ssh_session))) {
2793 /* translate the libssh2 define bits into our own bit defines */
2794 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2795 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2798 /* It didn't block or libssh2 didn't reveal in which direction, put back
2800 conn->waitfor = sshc->orig_waitfor;
2803 /* no libssh2 directional support so we simply don't know */
2804 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2807 /* called repeatedly until done from multi.c */
2808 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2810 struct ssh_conn *sshc = &conn->proto.sshc;
2811 CURLcode result = CURLE_OK;
2812 bool block; /* we store the status and use that to provide a ssh_getsock()
2815 result = ssh_statemach_act(conn, &block);
2816 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2817 ssh_block2waitfor(conn, block);
2822 static CURLcode ssh_block_statemach(struct connectdata *conn,
2825 struct ssh_conn *sshc = &conn->proto.sshc;
2826 CURLcode result = CURLE_OK;
2827 struct Curl_easy *data = conn->data;
2829 while((sshc->state != SSH_STOP) && !result) {
2833 result = ssh_statemach_act(conn, &block);
2837 if(Curl_pgrsUpdate(conn))
2838 return CURLE_ABORTED_BY_CALLBACK;
2840 struct timeval now = Curl_tvnow();
2841 result = Curl_speedcheck(data, now);
2846 left = Curl_timeleft(data, NULL, duringconnect);
2848 failf(data, "Operation timed out");
2849 return CURLE_OPERATION_TIMEDOUT;
2852 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2853 if(!result && block) {
2854 int dir = libssh2_session_block_directions(sshc->ssh_session);
2855 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2856 curl_socket_t fd_read = CURL_SOCKET_BAD;
2857 curl_socket_t fd_write = CURL_SOCKET_BAD;
2858 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2860 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2862 /* wait for the socket to become ready */
2863 Curl_socket_ready(fd_read, fd_write,
2864 left>1000?1000:left); /* ignore result */
2874 * SSH setup and connection
2876 static CURLcode ssh_setup_connection(struct connectdata *conn)
2878 struct SSHPROTO *ssh;
2880 conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
2882 return CURLE_OUT_OF_MEMORY;
2887 static Curl_recv scp_recv, sftp_recv;
2888 static Curl_send scp_send, sftp_send;
2891 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2892 * do protocol-specific actions at connect-time.
2894 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2896 #ifdef CURL_LIBSSH2_DEBUG
2899 struct ssh_conn *ssh;
2901 struct Curl_easy *data = conn->data;
2903 /* initialize per-handle data if not already */
2904 if(!data->req.protop)
2905 ssh_setup_connection(conn);
2907 /* We default to persistent connections. We set this already in this connect
2908 function to make the re-use checks properly be able to check this bit. */
2909 connkeep(conn, "SSH default");
2911 if(conn->handler->protocol & CURLPROTO_SCP) {
2912 conn->recv[FIRSTSOCKET] = scp_recv;
2913 conn->send[FIRSTSOCKET] = scp_send;
2916 conn->recv[FIRSTSOCKET] = sftp_recv;
2917 conn->send[FIRSTSOCKET] = sftp_send;
2919 ssh = &conn->proto.sshc;
2921 #ifdef CURL_LIBSSH2_DEBUG
2923 infof(data, "User: %s\n", conn->user);
2926 infof(data, "Password: %s\n", conn->passwd);
2928 sock = conn->sock[FIRSTSOCKET];
2929 #endif /* CURL_LIBSSH2_DEBUG */
2931 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2933 my_libssh2_realloc, conn);
2934 if(ssh->ssh_session == NULL) {
2935 failf(data, "Failure initialising ssh session");
2936 return CURLE_FAILED_INIT;
2939 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2940 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2942 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2944 /* eeek. TODO: free the ssh_session! */
2945 return CURLE_FAILED_INIT;
2948 /* read all known hosts from there */
2949 rc = libssh2_knownhost_readfile(ssh->kh,
2950 data->set.str[STRING_SSH_KNOWNHOSTS],
2951 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2953 infof(data, "Failed to read known hosts from %s\n",
2954 data->set.str[STRING_SSH_KNOWNHOSTS]);
2956 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2958 #ifdef CURL_LIBSSH2_DEBUG
2959 libssh2_trace(ssh->ssh_session, ~0);
2960 infof(data, "SSH socket: %d\n", (int)sock);
2961 #endif /* CURL_LIBSSH2_DEBUG */
2963 state(conn, SSH_INIT);
2965 result = ssh_multi_statemach(conn, done);
2971 ***********************************************************************
2975 * This is the actual DO function for SCP. Get a file according to
2976 * the options previously setup.
2980 CURLcode scp_perform(struct connectdata *conn,
2984 CURLcode result = CURLE_OK;
2986 DEBUGF(infof(conn->data, "DO phase starts\n"));
2988 *dophase_done = FALSE; /* not done yet */
2990 /* start the first command in the DO phase */
2991 state(conn, SSH_SCP_TRANS_INIT);
2993 /* run the state-machine */
2994 result = ssh_multi_statemach(conn, dophase_done);
2996 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2999 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3005 /* called from multi.c while DOing */
3006 static CURLcode scp_doing(struct connectdata *conn,
3010 result = ssh_multi_statemach(conn, dophase_done);
3013 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3019 * The DO function is generic for both protocols. There was previously two
3020 * separate ones but this way means less duplicated code.
3023 static CURLcode ssh_do(struct connectdata *conn, bool *done)
3027 struct Curl_easy *data = conn->data;
3028 struct ssh_conn *sshc = &conn->proto.sshc;
3030 *done = FALSE; /* default to false */
3032 data->req.size = -1; /* make sure this is unknown at this point */
3034 sshc->actualcode = CURLE_OK; /* reset error code */
3035 sshc->secondCreateDirs =0; /* reset the create dir attempt state
3038 Curl_pgrsSetUploadCounter(data, 0);
3039 Curl_pgrsSetDownloadCounter(data, 0);
3040 Curl_pgrsSetUploadSize(data, -1);
3041 Curl_pgrsSetDownloadSize(data, -1);
3043 if(conn->handler->protocol & CURLPROTO_SCP)
3044 result = scp_perform(conn, &connected, done);
3046 result = sftp_perform(conn, &connected, done);
3051 /* BLOCKING, but the function is using the state machine so the only reason
3052 this is still blocking is that the multi interface code has no support for
3053 disconnecting operations that takes a while */
3054 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
3056 CURLcode result = CURLE_OK;
3057 struct ssh_conn *ssh = &conn->proto.sshc;
3058 (void) dead_connection;
3060 if(ssh->ssh_session) {
3061 /* only if there's a session still around to use! */
3063 state(conn, SSH_SESSION_DISCONNECT);
3065 result = ssh_block_statemach(conn, FALSE);
3071 /* generic done function for both SCP and SFTP called from their specific
3073 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
3075 CURLcode result = CURLE_OK;
3076 struct SSHPROTO *sftp_scp = conn->data->req.protop;
3079 /* run the state-machine
3081 TODO: when the multi interface is used, this _really_ should be using
3082 the ssh_multi_statemach function but we have no general support for
3083 non-blocking DONE operations!
3085 result = ssh_block_statemach(conn, FALSE);
3091 Curl_safefree(sftp_scp->path);
3092 if(Curl_pgrsDone(conn))
3093 return CURLE_ABORTED_BY_CALLBACK;
3095 conn->data->req.keepon = 0; /* clear all bits */
3100 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
3103 (void)premature; /* not used */
3106 state(conn, SSH_SCP_DONE);
3108 return ssh_done(conn, status);
3112 static ssize_t scp_send(struct connectdata *conn, int sockindex,
3113 const void *mem, size_t len, CURLcode *err)
3116 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3118 /* libssh2_channel_write() returns int! */
3120 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
3122 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3124 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3128 else if(nwrite < LIBSSH2_ERROR_NONE) {
3129 *err = libssh2_session_error_to_CURLE((int)nwrite);
3136 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
3137 char *mem, size_t len, CURLcode *err)
3140 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3142 /* libssh2_channel_read() returns int */
3144 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
3146 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3147 if(nread == LIBSSH2_ERROR_EAGAIN) {
3156 * =============== SFTP ===============
3160 ***********************************************************************
3164 * This is the actual DO function for SFTP. Get a file/directory according to
3165 * the options previously setup.
3169 CURLcode sftp_perform(struct connectdata *conn,
3173 CURLcode result = CURLE_OK;
3175 DEBUGF(infof(conn->data, "DO phase starts\n"));
3177 *dophase_done = FALSE; /* not done yet */
3179 /* start the first command in the DO phase */
3180 state(conn, SSH_SFTP_QUOTE_INIT);
3182 /* run the state-machine */
3183 result = ssh_multi_statemach(conn, dophase_done);
3185 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3188 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3194 /* called from multi.c while DOing */
3195 static CURLcode sftp_doing(struct connectdata *conn,
3198 CURLcode result = ssh_multi_statemach(conn, dophase_done);
3201 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3206 /* BLOCKING, but the function is using the state machine so the only reason
3207 this is still blocking is that the multi interface code has no support for
3208 disconnecting operations that takes a while */
3209 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
3211 CURLcode result = CURLE_OK;
3212 (void) dead_connection;
3214 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3216 if(conn->proto.sshc.ssh_session) {
3217 /* only if there's a session still around to use! */
3218 state(conn, SSH_SFTP_SHUTDOWN);
3219 result = ssh_block_statemach(conn, FALSE);
3222 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3228 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3231 struct ssh_conn *sshc = &conn->proto.sshc;
3234 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3235 errors that could happen due to open file handles during POSTQUOTE
3237 if(!status && !premature && conn->data->set.postquote) {
3238 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3239 state(conn, SSH_SFTP_CLOSE);
3242 state(conn, SSH_SFTP_CLOSE);
3244 return ssh_done(conn, status);
3247 /* return number of sent bytes */
3248 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3249 const void *mem, size_t len, CURLcode *err)
3251 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3252 but is changed to ssize_t in 0.15. These days we don't
3253 support libssh2 0.15*/
3256 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3258 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3260 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3264 else if(nwrite < LIBSSH2_ERROR_NONE) {
3265 *err = libssh2_session_error_to_CURLE((int)nwrite);
3273 * Return number of received (decrypted) bytes
3276 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3277 char *mem, size_t len, CURLcode *err)
3282 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3284 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3286 if(nread == LIBSSH2_ERROR_EAGAIN) {
3291 else if(nread < 0) {
3292 *err = libssh2_session_error_to_CURLE((int)nread);
3297 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3300 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3302 * Permission to use, copy, modify, and distribute this software for any
3303 * purpose with or without fee is hereby granted, provided that the above
3304 * copyright notice and this permission notice appear in all copies.
3306 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3307 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3308 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3309 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3310 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3311 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3312 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3315 get_pathname(const char **cpp, char **path)
3317 const char *cp = *cpp, *end;
3320 static const char WHITESPACE[] = " \t\r\n";
3322 cp += strspn(cp, WHITESPACE);
3326 return CURLE_QUOTE_ERROR;
3329 *path = malloc(strlen(cp) + 1);
3331 return CURLE_OUT_OF_MEMORY;
3333 /* Check for quoted filenames */
3334 if(*cp == '\"' || *cp == '\'') {
3337 /* Search for terminating quote, unescape some chars */
3338 for(i = j = 0; i <= strlen(cp); i++) {
3339 if(cp[i] == quot) { /* Found quote */
3344 if(cp[i] == '\0') { /* End of string */
3345 /*error("Unterminated quote");*/
3348 if(cp[i] == '\\') { /* Escaped characters */
3350 if(cp[i] != '\'' && cp[i] != '\"' &&
3352 /*error("Bad escaped character '\\%c'",
3357 (*path)[j++] = cp[i];
3361 /*error("Empty quotes");*/
3364 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3367 /* Read to end of filename */
3368 end = strpbrk(cp, WHITESPACE);
3370 end = strchr(cp, '\0');
3371 *cpp = end + strspn(end, WHITESPACE);
3373 memcpy(*path, cp, end - cp);
3374 (*path)[end - cp] = '\0';
3379 Curl_safefree(*path);
3380 return CURLE_QUOTE_ERROR;
3384 static const char *sftp_libssh2_strerror(int err)
3387 case LIBSSH2_FX_NO_SUCH_FILE:
3388 return "No such file or directory";
3390 case LIBSSH2_FX_PERMISSION_DENIED:
3391 return "Permission denied";
3393 case LIBSSH2_FX_FAILURE:
3394 return "Operation failed";
3396 case LIBSSH2_FX_BAD_MESSAGE:
3397 return "Bad message from SFTP server";
3399 case LIBSSH2_FX_NO_CONNECTION:
3400 return "Not connected to SFTP server";
3402 case LIBSSH2_FX_CONNECTION_LOST:
3403 return "Connection to SFTP server lost";
3405 case LIBSSH2_FX_OP_UNSUPPORTED:
3406 return "Operation not supported by SFTP server";
3408 case LIBSSH2_FX_INVALID_HANDLE:
3409 return "Invalid handle";
3411 case LIBSSH2_FX_NO_SUCH_PATH:
3412 return "No such file or directory";
3414 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3415 return "File already exists";
3417 case LIBSSH2_FX_WRITE_PROTECT:
3418 return "File is write protected";
3420 case LIBSSH2_FX_NO_MEDIA:
3423 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3426 case LIBSSH2_FX_QUOTA_EXCEEDED:
3427 return "User quota exceeded";
3429 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3430 return "Unknown principle";
3432 case LIBSSH2_FX_LOCK_CONFlICT:
3433 return "File lock conflict";
3435 case LIBSSH2_FX_DIR_NOT_EMPTY:
3436 return "Directory not empty";
3438 case LIBSSH2_FX_NOT_A_DIRECTORY:
3439 return "Not a directory";
3441 case LIBSSH2_FX_INVALID_FILENAME:
3442 return "Invalid filename";
3444 case LIBSSH2_FX_LINK_LOOP:
3445 return "Link points to itself";
3447 return "Unknown error in libssh2";
3450 #endif /* USE_LIBSSH2 */