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 size_t working_path_len;
421 Curl_urldecode(data, data->state.path, 0, &working_path,
422 &working_path_len, FALSE);
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 || !strcasecompare(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);
786 err = libssh2_session_last_errno(sshc->ssh_session);
787 if(err == LIBSSH2_ERROR_EAGAIN)
788 rc = LIBSSH2_ERROR_EAGAIN;
790 state(conn, SSH_SESSION_FREE);
791 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.ssl.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);
921 rc = 0; /* clear rc and continue */
925 case SSH_AUTH_PASS_INIT:
926 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
927 (strstr(sshc->authlist, "password") != NULL)) {
928 state(conn, SSH_AUTH_PASS);
931 state(conn, SSH_AUTH_HOST_INIT);
932 rc = 0; /* clear rc and continue */
937 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
938 curlx_uztoui(strlen(conn->user)),
940 curlx_uztoui(strlen(conn->passwd)),
942 if(rc == LIBSSH2_ERROR_EAGAIN) {
947 infof(data, "Initialized password authentication\n");
948 state(conn, SSH_AUTH_DONE);
951 state(conn, SSH_AUTH_HOST_INIT);
952 rc = 0; /* clear rc and continue */
956 case SSH_AUTH_HOST_INIT:
957 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
958 (strstr(sshc->authlist, "hostbased") != NULL)) {
959 state(conn, SSH_AUTH_HOST);
962 state(conn, SSH_AUTH_AGENT_INIT);
967 state(conn, SSH_AUTH_AGENT_INIT);
970 case SSH_AUTH_AGENT_INIT:
971 #ifdef HAVE_LIBSSH2_AGENT_API
972 if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
973 && (strstr(sshc->authlist, "publickey") != NULL)) {
975 /* Connect to the ssh-agent */
976 /* The agent could be shared by a curl thread i believe
977 but nothing obvious as keys can be added/removed at any time */
978 if(!sshc->ssh_agent) {
979 sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
980 if(!sshc->ssh_agent) {
981 infof(data, "Could not create agent object\n");
983 state(conn, SSH_AUTH_KEY_INIT);
988 rc = libssh2_agent_connect(sshc->ssh_agent);
989 if(rc == LIBSSH2_ERROR_EAGAIN)
992 infof(data, "Failure connecting to agent\n");
993 state(conn, SSH_AUTH_KEY_INIT);
994 rc = 0; /* clear rc and continue */
997 state(conn, SSH_AUTH_AGENT_LIST);
1001 #endif /* HAVE_LIBSSH2_AGENT_API */
1002 state(conn, SSH_AUTH_KEY_INIT);
1005 case SSH_AUTH_AGENT_LIST:
1006 #ifdef HAVE_LIBSSH2_AGENT_API
1007 rc = libssh2_agent_list_identities(sshc->ssh_agent);
1009 if(rc == LIBSSH2_ERROR_EAGAIN)
1012 infof(data, "Failure requesting identities to agent\n");
1013 state(conn, SSH_AUTH_KEY_INIT);
1014 rc = 0; /* clear rc and continue */
1017 state(conn, SSH_AUTH_AGENT);
1018 sshc->sshagent_prev_identity = NULL;
1023 case SSH_AUTH_AGENT:
1024 #ifdef HAVE_LIBSSH2_AGENT_API
1025 /* as prev_identity evolves only after an identity user auth finished we
1026 can safely request it again as long as EAGAIN is returned here or by
1027 libssh2_agent_userauth */
1028 rc = libssh2_agent_get_identity(sshc->ssh_agent,
1029 &sshc->sshagent_identity,
1030 sshc->sshagent_prev_identity);
1031 if(rc == LIBSSH2_ERROR_EAGAIN)
1035 rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
1036 sshc->sshagent_identity);
1039 if(rc != LIBSSH2_ERROR_EAGAIN)
1040 /* tried and failed? go to next identity */
1041 sshc->sshagent_prev_identity = sshc->sshagent_identity;
1048 infof(data, "Failure requesting identities to agent\n");
1050 infof(data, "No identity would match\n");
1052 if(rc == LIBSSH2_ERROR_NONE) {
1053 sshc->authed = TRUE;
1054 infof(data, "Agent based authentication successful\n");
1055 state(conn, SSH_AUTH_DONE);
1058 state(conn, SSH_AUTH_KEY_INIT);
1059 rc = 0; /* clear rc and continue */
1064 case SSH_AUTH_KEY_INIT:
1065 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
1066 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
1067 state(conn, SSH_AUTH_KEY);
1070 state(conn, SSH_AUTH_DONE);
1075 /* Authentication failed. Continue with keyboard-interactive now. */
1076 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
1079 strlen(conn->user)),
1081 if(rc == LIBSSH2_ERROR_EAGAIN) {
1085 sshc->authed = TRUE;
1086 infof(data, "Initialized keyboard interactive authentication\n");
1088 state(conn, SSH_AUTH_DONE);
1093 failf(data, "Authentication failure");
1094 state(conn, SSH_SESSION_FREE);
1095 sshc->actualcode = CURLE_LOGIN_DENIED;
1100 * At this point we have an authenticated ssh session.
1102 infof(data, "Authentication complete\n");
1104 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
1106 conn->sockfd = sock;
1107 conn->writesockfd = CURL_SOCKET_BAD;
1109 if(conn->handler->protocol == CURLPROTO_SFTP) {
1110 state(conn, SSH_SFTP_INIT);
1113 infof(data, "SSH CONNECT phase done\n");
1114 state(conn, SSH_STOP);
1119 * Start the libssh2 sftp session
1121 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
1122 if(!sshc->sftp_session) {
1123 if(libssh2_session_last_errno(sshc->ssh_session) ==
1124 LIBSSH2_ERROR_EAGAIN) {
1125 rc = LIBSSH2_ERROR_EAGAIN;
1131 (void)libssh2_session_last_error(sshc->ssh_session,
1133 failf(data, "Failure initializing sftp session: %s", err_msg);
1134 state(conn, SSH_SESSION_FREE);
1135 sshc->actualcode = CURLE_FAILED_INIT;
1139 state(conn, SSH_SFTP_REALPATH);
1142 case SSH_SFTP_REALPATH:
1144 char tempHome[PATH_MAX];
1147 * Get the "home" directory
1149 rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
1150 tempHome, PATH_MAX-1);
1151 if(rc == LIBSSH2_ERROR_EAGAIN) {
1155 /* It seems that this string is not always NULL terminated */
1156 tempHome[rc] = '\0';
1157 sshc->homedir = strdup(tempHome);
1158 if(!sshc->homedir) {
1159 state(conn, SSH_SFTP_CLOSE);
1160 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1163 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1166 /* Return the error type */
1167 err = sftp_libssh2_last_error(sshc->sftp_session);
1169 result = sftp_libssh2_error_to_CURLE(err);
1171 /* in this case, the error wasn't in the SFTP level but for example
1172 a time-out or similar */
1174 sshc->actualcode = result;
1175 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1177 state(conn, SSH_STOP);
1181 /* This is the last step in the SFTP connect phase. Do note that while
1182 we get the homedir here, we get the "workingpath" in the DO action
1183 since the homedir will remain the same between request but the
1184 working path will not. */
1185 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1186 state(conn, SSH_STOP);
1189 case SSH_SFTP_QUOTE_INIT:
1191 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1193 sshc->actualcode = result;
1194 state(conn, SSH_STOP);
1198 if(data->set.quote) {
1199 infof(data, "Sending quote commands\n");
1200 sshc->quote_item = data->set.quote;
1201 state(conn, SSH_SFTP_QUOTE);
1204 state(conn, SSH_SFTP_GETINFO);
1208 case SSH_SFTP_POSTQUOTE_INIT:
1209 if(data->set.postquote) {
1210 infof(data, "Sending quote commands\n");
1211 sshc->quote_item = data->set.postquote;
1212 state(conn, SSH_SFTP_QUOTE);
1215 state(conn, SSH_STOP);
1219 case SSH_SFTP_QUOTE:
1220 /* Send any quote commands */
1225 * Support some of the "FTP" commands
1227 char *cmd = sshc->quote_item->data;
1228 sshc->acceptfail = FALSE;
1230 /* if a command starts with an asterisk, which a legal SFTP command never
1231 can, the command will be allowed to fail without it causing any
1232 aborts or cancels etc. It will cause libcurl to act as if the command
1233 is successful, whatever the server reponds. */
1237 sshc->acceptfail = TRUE;
1240 if(strcasecompare("pwd", cmd)) {
1241 /* output debug output if that is requested */
1242 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1245 result = CURLE_OUT_OF_MEMORY;
1246 state(conn, SSH_SFTP_CLOSE);
1247 sshc->nextstate = SSH_NO_STATE;
1250 if(data->set.verbose) {
1251 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1252 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1254 /* this sends an FTP-like "header" to the header callback so that the
1255 current directory can be read very similar to how it is read when
1256 using ordinary FTP. */
1257 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1260 state(conn, SSH_SFTP_CLOSE);
1261 sshc->nextstate = SSH_NO_STATE;
1262 sshc->actualcode = result;
1265 state(conn, SSH_SFTP_NEXT_QUOTE);
1270 * the arguments following the command must be separated from the
1271 * command with a space so we can check for it unconditionally
1273 cp = strchr(cmd, ' ');
1275 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1276 state(conn, SSH_SFTP_CLOSE);
1277 sshc->nextstate = SSH_NO_STATE;
1278 sshc->actualcode = CURLE_QUOTE_ERROR;
1283 * also, every command takes at least one argument so we get that
1284 * first argument right now
1286 result = get_pathname(&cp, &sshc->quote_path1);
1288 if(result == CURLE_OUT_OF_MEMORY)
1289 failf(data, "Out of memory");
1291 failf(data, "Syntax error: Bad first parameter");
1292 state(conn, SSH_SFTP_CLOSE);
1293 sshc->nextstate = SSH_NO_STATE;
1294 sshc->actualcode = result;
1299 * SFTP is a binary protocol, so we don't send text commands
1300 * to the server. Instead, we scan for commands used by
1301 * OpenSSH's sftp program and call the appropriate libssh2
1304 if(strncasecompare(cmd, "chgrp ", 6) ||
1305 strncasecompare(cmd, "chmod ", 6) ||
1306 strncasecompare(cmd, "chown ", 6) ) {
1307 /* attribute change */
1309 /* sshc->quote_path1 contains the mode to set */
1310 /* get the destination */
1311 result = get_pathname(&cp, &sshc->quote_path2);
1313 if(result == CURLE_OUT_OF_MEMORY)
1314 failf(data, "Out of memory");
1316 failf(data, "Syntax error in chgrp/chmod/chown: "
1317 "Bad second parameter");
1318 Curl_safefree(sshc->quote_path1);
1319 state(conn, SSH_SFTP_CLOSE);
1320 sshc->nextstate = SSH_NO_STATE;
1321 sshc->actualcode = result;
1324 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1325 state(conn, SSH_SFTP_QUOTE_STAT);
1328 else if(strncasecompare(cmd, "ln ", 3) ||
1329 strncasecompare(cmd, "symlink ", 8)) {
1330 /* symbolic linking */
1331 /* sshc->quote_path1 is the source */
1332 /* get the destination */
1333 result = get_pathname(&cp, &sshc->quote_path2);
1335 if(result == CURLE_OUT_OF_MEMORY)
1336 failf(data, "Out of memory");
1339 "Syntax error in ln/symlink: Bad second parameter");
1340 Curl_safefree(sshc->quote_path1);
1341 state(conn, SSH_SFTP_CLOSE);
1342 sshc->nextstate = SSH_NO_STATE;
1343 sshc->actualcode = result;
1346 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1349 else if(strncasecompare(cmd, "mkdir ", 6)) {
1351 state(conn, SSH_SFTP_QUOTE_MKDIR);
1354 else if(strncasecompare(cmd, "rename ", 7)) {
1356 /* first param is the source path */
1357 /* second param is the dest. path */
1358 result = get_pathname(&cp, &sshc->quote_path2);
1360 if(result == CURLE_OUT_OF_MEMORY)
1361 failf(data, "Out of memory");
1363 failf(data, "Syntax error in rename: Bad second parameter");
1364 Curl_safefree(sshc->quote_path1);
1365 state(conn, SSH_SFTP_CLOSE);
1366 sshc->nextstate = SSH_NO_STATE;
1367 sshc->actualcode = result;
1370 state(conn, SSH_SFTP_QUOTE_RENAME);
1373 else if(strncasecompare(cmd, "rmdir ", 6)) {
1375 state(conn, SSH_SFTP_QUOTE_RMDIR);
1378 else if(strncasecompare(cmd, "rm ", 3)) {
1379 state(conn, SSH_SFTP_QUOTE_UNLINK);
1382 #ifdef HAS_STATVFS_SUPPORT
1383 else if(strncasecompare(cmd, "statvfs ", 8)) {
1384 state(conn, SSH_SFTP_QUOTE_STATVFS);
1389 failf(data, "Unknown SFTP command");
1390 Curl_safefree(sshc->quote_path1);
1391 Curl_safefree(sshc->quote_path2);
1392 state(conn, SSH_SFTP_CLOSE);
1393 sshc->nextstate = SSH_NO_STATE;
1394 sshc->actualcode = CURLE_QUOTE_ERROR;
1398 if(!sshc->quote_item) {
1399 state(conn, SSH_SFTP_GETINFO);
1403 case SSH_SFTP_NEXT_QUOTE:
1404 Curl_safefree(sshc->quote_path1);
1405 Curl_safefree(sshc->quote_path2);
1407 sshc->quote_item = sshc->quote_item->next;
1409 if(sshc->quote_item) {
1410 state(conn, SSH_SFTP_QUOTE);
1413 if(sshc->nextstate != SSH_NO_STATE) {
1414 state(conn, sshc->nextstate);
1415 sshc->nextstate = SSH_NO_STATE;
1418 state(conn, SSH_SFTP_GETINFO);
1423 case SSH_SFTP_QUOTE_STAT:
1425 char *cmd = sshc->quote_item->data;
1426 sshc->acceptfail = FALSE;
1428 /* if a command starts with an asterisk, which a legal SFTP command never
1429 can, the command will be allowed to fail without it causing any
1430 aborts or cancels etc. It will cause libcurl to act as if the command
1431 is successful, whatever the server reponds. */
1435 sshc->acceptfail = TRUE;
1438 if(!strncasecompare(cmd, "chmod", 5)) {
1439 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1440 * set them both at once, we need to obtain the current ownership
1441 * first. This takes an extra protocol round trip.
1443 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1444 curlx_uztoui(strlen(sshc->quote_path2)),
1446 &sshc->quote_attrs);
1447 if(rc == LIBSSH2_ERROR_EAGAIN) {
1450 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1451 err = sftp_libssh2_last_error(sshc->sftp_session);
1452 Curl_safefree(sshc->quote_path1);
1453 Curl_safefree(sshc->quote_path2);
1454 failf(data, "Attempt to get SFTP stats failed: %s",
1455 sftp_libssh2_strerror(err));
1456 state(conn, SSH_SFTP_CLOSE);
1457 sshc->nextstate = SSH_NO_STATE;
1458 sshc->actualcode = CURLE_QUOTE_ERROR;
1463 /* Now set the new attributes... */
1464 if(strncasecompare(cmd, "chgrp", 5)) {
1465 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1466 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1467 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1468 !sshc->acceptfail) {
1469 Curl_safefree(sshc->quote_path1);
1470 Curl_safefree(sshc->quote_path2);
1471 failf(data, "Syntax error: chgrp gid not a number");
1472 state(conn, SSH_SFTP_CLOSE);
1473 sshc->nextstate = SSH_NO_STATE;
1474 sshc->actualcode = CURLE_QUOTE_ERROR;
1478 else if(strncasecompare(cmd, "chmod", 5)) {
1479 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1480 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1481 /* permissions are octal */
1482 if(sshc->quote_attrs.permissions == 0 &&
1483 !ISDIGIT(sshc->quote_path1[0])) {
1484 Curl_safefree(sshc->quote_path1);
1485 Curl_safefree(sshc->quote_path2);
1486 failf(data, "Syntax error: chmod permissions not a number");
1487 state(conn, SSH_SFTP_CLOSE);
1488 sshc->nextstate = SSH_NO_STATE;
1489 sshc->actualcode = CURLE_QUOTE_ERROR;
1493 else if(strncasecompare(cmd, "chown", 5)) {
1494 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1495 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1496 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1497 !sshc->acceptfail) {
1498 Curl_safefree(sshc->quote_path1);
1499 Curl_safefree(sshc->quote_path2);
1500 failf(data, "Syntax error: chown uid not a number");
1501 state(conn, SSH_SFTP_CLOSE);
1502 sshc->nextstate = SSH_NO_STATE;
1503 sshc->actualcode = CURLE_QUOTE_ERROR;
1508 /* Now send the completed structure... */
1509 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1513 case SSH_SFTP_QUOTE_SETSTAT:
1514 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1515 curlx_uztoui(strlen(sshc->quote_path2)),
1516 LIBSSH2_SFTP_SETSTAT,
1517 &sshc->quote_attrs);
1518 if(rc == LIBSSH2_ERROR_EAGAIN) {
1521 else if(rc != 0 && !sshc->acceptfail) {
1522 err = sftp_libssh2_last_error(sshc->sftp_session);
1523 Curl_safefree(sshc->quote_path1);
1524 Curl_safefree(sshc->quote_path2);
1525 failf(data, "Attempt to set SFTP stats failed: %s",
1526 sftp_libssh2_strerror(err));
1527 state(conn, SSH_SFTP_CLOSE);
1528 sshc->nextstate = SSH_NO_STATE;
1529 sshc->actualcode = CURLE_QUOTE_ERROR;
1532 state(conn, SSH_SFTP_NEXT_QUOTE);
1535 case SSH_SFTP_QUOTE_SYMLINK:
1536 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1537 curlx_uztoui(strlen(sshc->quote_path1)),
1539 curlx_uztoui(strlen(sshc->quote_path2)),
1540 LIBSSH2_SFTP_SYMLINK);
1541 if(rc == LIBSSH2_ERROR_EAGAIN) {
1544 else if(rc != 0 && !sshc->acceptfail) {
1545 err = sftp_libssh2_last_error(sshc->sftp_session);
1546 Curl_safefree(sshc->quote_path1);
1547 Curl_safefree(sshc->quote_path2);
1548 failf(data, "symlink command failed: %s",
1549 sftp_libssh2_strerror(err));
1550 state(conn, SSH_SFTP_CLOSE);
1551 sshc->nextstate = SSH_NO_STATE;
1552 sshc->actualcode = CURLE_QUOTE_ERROR;
1555 state(conn, SSH_SFTP_NEXT_QUOTE);
1558 case SSH_SFTP_QUOTE_MKDIR:
1559 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1560 curlx_uztoui(strlen(sshc->quote_path1)),
1561 data->set.new_directory_perms);
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 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1569 state(conn, SSH_SFTP_CLOSE);
1570 sshc->nextstate = SSH_NO_STATE;
1571 sshc->actualcode = CURLE_QUOTE_ERROR;
1574 state(conn, SSH_SFTP_NEXT_QUOTE);
1577 case SSH_SFTP_QUOTE_RENAME:
1578 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1579 curlx_uztoui(strlen(sshc->quote_path1)),
1581 curlx_uztoui(strlen(sshc->quote_path2)),
1582 LIBSSH2_SFTP_RENAME_OVERWRITE |
1583 LIBSSH2_SFTP_RENAME_ATOMIC |
1584 LIBSSH2_SFTP_RENAME_NATIVE);
1586 if(rc == LIBSSH2_ERROR_EAGAIN) {
1589 else if(rc != 0 && !sshc->acceptfail) {
1590 err = sftp_libssh2_last_error(sshc->sftp_session);
1591 Curl_safefree(sshc->quote_path1);
1592 Curl_safefree(sshc->quote_path2);
1593 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1594 state(conn, SSH_SFTP_CLOSE);
1595 sshc->nextstate = SSH_NO_STATE;
1596 sshc->actualcode = CURLE_QUOTE_ERROR;
1599 state(conn, SSH_SFTP_NEXT_QUOTE);
1602 case SSH_SFTP_QUOTE_RMDIR:
1603 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1604 curlx_uztoui(strlen(sshc->quote_path1)));
1605 if(rc == LIBSSH2_ERROR_EAGAIN) {
1608 else if(rc != 0 && !sshc->acceptfail) {
1609 err = sftp_libssh2_last_error(sshc->sftp_session);
1610 Curl_safefree(sshc->quote_path1);
1611 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1612 state(conn, SSH_SFTP_CLOSE);
1613 sshc->nextstate = SSH_NO_STATE;
1614 sshc->actualcode = CURLE_QUOTE_ERROR;
1617 state(conn, SSH_SFTP_NEXT_QUOTE);
1620 case SSH_SFTP_QUOTE_UNLINK:
1621 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1622 curlx_uztoui(strlen(sshc->quote_path1)));
1623 if(rc == LIBSSH2_ERROR_EAGAIN) {
1626 else if(rc != 0 && !sshc->acceptfail) {
1627 err = sftp_libssh2_last_error(sshc->sftp_session);
1628 Curl_safefree(sshc->quote_path1);
1629 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1630 state(conn, SSH_SFTP_CLOSE);
1631 sshc->nextstate = SSH_NO_STATE;
1632 sshc->actualcode = CURLE_QUOTE_ERROR;
1635 state(conn, SSH_SFTP_NEXT_QUOTE);
1638 #ifdef HAS_STATVFS_SUPPORT
1639 case SSH_SFTP_QUOTE_STATVFS:
1641 LIBSSH2_SFTP_STATVFS statvfs;
1642 rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1,
1643 curlx_uztoui(strlen(sshc->quote_path1)),
1646 if(rc == LIBSSH2_ERROR_EAGAIN) {
1649 else if(rc != 0 && !sshc->acceptfail) {
1650 err = sftp_libssh2_last_error(sshc->sftp_session);
1651 Curl_safefree(sshc->quote_path1);
1652 failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(err));
1653 state(conn, SSH_SFTP_CLOSE);
1654 sshc->nextstate = SSH_NO_STATE;
1655 sshc->actualcode = CURLE_QUOTE_ERROR;
1659 char *tmp = aprintf("statvfs:\n"
1660 "f_bsize: %llu\n" "f_frsize: %llu\n"
1661 "f_blocks: %llu\n" "f_bfree: %llu\n"
1662 "f_bavail: %llu\n" "f_files: %llu\n"
1663 "f_ffree: %llu\n" "f_favail: %llu\n"
1664 "f_fsid: %llu\n" "f_flag: %llu\n"
1665 "f_namemax: %llu\n",
1666 statvfs.f_bsize, statvfs.f_frsize,
1667 statvfs.f_blocks, statvfs.f_bfree,
1668 statvfs.f_bavail, statvfs.f_files,
1669 statvfs.f_ffree, statvfs.f_favail,
1670 statvfs.f_fsid, statvfs.f_flag,
1673 result = CURLE_OUT_OF_MEMORY;
1674 state(conn, SSH_SFTP_CLOSE);
1675 sshc->nextstate = SSH_NO_STATE;
1679 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1682 state(conn, SSH_SFTP_CLOSE);
1683 sshc->nextstate = SSH_NO_STATE;
1684 sshc->actualcode = result;
1687 state(conn, SSH_SFTP_NEXT_QUOTE);
1691 case SSH_SFTP_GETINFO:
1693 if(data->set.get_filetime) {
1694 state(conn, SSH_SFTP_FILETIME);
1697 state(conn, SSH_SFTP_TRANS_INIT);
1702 case SSH_SFTP_FILETIME:
1704 LIBSSH2_SFTP_ATTRIBUTES attrs;
1706 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1707 curlx_uztoui(strlen(sftp_scp->path)),
1708 LIBSSH2_SFTP_STAT, &attrs);
1709 if(rc == LIBSSH2_ERROR_EAGAIN) {
1713 data->info.filetime = (long)attrs.mtime;
1716 state(conn, SSH_SFTP_TRANS_INIT);
1720 case SSH_SFTP_TRANS_INIT:
1721 if(data->set.upload)
1722 state(conn, SSH_SFTP_UPLOAD_INIT);
1724 if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1725 state(conn, SSH_SFTP_READDIR_INIT);
1727 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1731 case SSH_SFTP_UPLOAD_INIT:
1733 unsigned long flags;
1735 * NOTE!!! libssh2 requires that the destination path is a full path
1736 * that includes the destination file and name OR ends in a "/"
1737 * If this is not done the destination file will be named the
1738 * same name as the last directory in the path.
1741 if(data->state.resume_from != 0) {
1742 LIBSSH2_SFTP_ATTRIBUTES attrs;
1743 if(data->state.resume_from < 0) {
1744 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1745 curlx_uztoui(strlen(sftp_scp->path)),
1746 LIBSSH2_SFTP_STAT, &attrs);
1747 if(rc == LIBSSH2_ERROR_EAGAIN) {
1751 data->state.resume_from = 0;
1754 curl_off_t size = attrs.filesize;
1756 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
1757 return CURLE_BAD_DOWNLOAD_RESUME;
1759 data->state.resume_from = attrs.filesize;
1764 if(data->set.ftp_append)
1765 /* Try to open for append, but create if nonexisting */
1766 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1767 else if(data->state.resume_from > 0)
1768 /* If we have restart position then open for append */
1769 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1771 /* Clear file before writing (normal behaviour) */
1772 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1775 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1776 curlx_uztoui(strlen(sftp_scp->path)),
1777 flags, data->set.new_file_perms,
1778 LIBSSH2_SFTP_OPENFILE);
1780 if(!sshc->sftp_handle) {
1781 rc = libssh2_session_last_errno(sshc->ssh_session);
1783 if(LIBSSH2_ERROR_EAGAIN == rc)
1786 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1787 /* only when there was an SFTP protocol error can we extract
1789 err = sftp_libssh2_last_error(sshc->sftp_session);
1791 err = -1; /* not an sftp error at all */
1793 if(sshc->secondCreateDirs) {
1794 state(conn, SSH_SFTP_CLOSE);
1795 sshc->actualcode = err>= LIBSSH2_FX_OK?
1796 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1797 failf(data, "Creating the dir/file failed: %s",
1798 sftp_libssh2_strerror(err));
1801 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1802 (err == LIBSSH2_FX_FAILURE) ||
1803 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1804 (data->set.ftp_create_missing_dirs &&
1805 (strlen(sftp_scp->path) > 1))) {
1806 /* try to create the path remotely */
1807 rc = 0; /* clear rc and continue */
1808 sshc->secondCreateDirs = 1;
1809 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1812 state(conn, SSH_SFTP_CLOSE);
1813 sshc->actualcode = err>= LIBSSH2_FX_OK?
1814 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1815 if(!sshc->actualcode) {
1816 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1817 zero even though libssh2_sftp_open() failed previously! We need
1818 to work around that! */
1819 sshc->actualcode = CURLE_SSH;
1822 failf(data, "Upload failed: %s (%d/%d)",
1823 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1829 /* If we have a restart point then we need to seek to the correct
1831 if(data->state.resume_from > 0) {
1832 /* Let's read off the proper amount of bytes from the input. */
1833 if(conn->seek_func) {
1834 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1838 if(seekerr != CURL_SEEKFUNC_OK) {
1840 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1841 failf(data, "Could not seek stream");
1842 return CURLE_FTP_COULDNT_USE_REST;
1844 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1846 curl_off_t passed=0;
1848 size_t readthisamountnow =
1849 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1850 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1852 size_t actuallyread =
1853 data->state.fread_func(data->state.buffer, 1,
1854 readthisamountnow, data->state.in);
1856 passed += actuallyread;
1857 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1858 /* this checks for greater-than only to make sure that the
1859 CURL_READFUNC_ABORT return code still aborts */
1860 failf(data, "Failed to read data");
1861 return CURLE_FTP_COULDNT_USE_REST;
1863 } while(passed < data->state.resume_from);
1867 /* now, decrease the size of the read */
1868 if(data->state.infilesize > 0) {
1869 data->state.infilesize -= data->state.resume_from;
1870 data->req.size = data->state.infilesize;
1871 Curl_pgrsSetUploadSize(data, data->state.infilesize);
1874 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1876 if(data->state.infilesize > 0) {
1877 data->req.size = data->state.infilesize;
1878 Curl_pgrsSetUploadSize(data, data->state.infilesize);
1881 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1883 /* not set by Curl_setup_transfer to preserve keepon bits */
1884 conn->sockfd = conn->writesockfd;
1887 state(conn, SSH_SFTP_CLOSE);
1888 sshc->actualcode = result;
1891 /* store this original bitmask setup to use later on if we can't
1892 figure out a "real" bitmask */
1893 sshc->orig_waitfor = data->req.keepon;
1895 /* we want to use the _sending_ function even when the socket turns
1896 out readable as the underlying libssh2 sftp send function will deal
1897 with both accordingly */
1898 conn->cselect_bits = CURL_CSELECT_OUT;
1900 /* since we don't really wait for anything at this point, we want the
1901 state machine to move on as soon as possible so we set a very short
1903 Curl_expire(data, 0);
1905 state(conn, SSH_STOP);
1910 case SSH_SFTP_CREATE_DIRS_INIT:
1911 if(strlen(sftp_scp->path) > 1) {
1912 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1913 state(conn, SSH_SFTP_CREATE_DIRS);
1916 state(conn, SSH_SFTP_UPLOAD_INIT);
1920 case SSH_SFTP_CREATE_DIRS:
1921 sshc->slash_pos = strchr(sshc->slash_pos, '/');
1922 if(sshc->slash_pos) {
1923 *sshc->slash_pos = 0;
1925 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1926 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1930 state(conn, SSH_SFTP_UPLOAD_INIT);
1934 case SSH_SFTP_CREATE_DIRS_MKDIR:
1935 /* 'mode' - parameter is preliminary - default to 0644 */
1936 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1937 curlx_uztoui(strlen(sftp_scp->path)),
1938 data->set.new_directory_perms);
1939 if(rc == LIBSSH2_ERROR_EAGAIN) {
1942 *sshc->slash_pos = '/';
1946 * Abort if failure wasn't that the dir already exists or the
1947 * permission was denied (creation might succeed further down the
1948 * path) - retry on unspecific FAILURE also
1950 err = sftp_libssh2_last_error(sshc->sftp_session);
1951 if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1952 (err != LIBSSH2_FX_FAILURE) &&
1953 (err != LIBSSH2_FX_PERMISSION_DENIED)) {
1954 result = sftp_libssh2_error_to_CURLE(err);
1955 state(conn, SSH_SFTP_CLOSE);
1956 sshc->actualcode = result?result:CURLE_SSH;
1960 rc = 0; /* clear rc and continue */
1963 state(conn, SSH_SFTP_CREATE_DIRS);
1966 case SSH_SFTP_READDIR_INIT:
1967 Curl_pgrsSetDownloadSize(data, -1);
1968 if(data->set.opt_no_body) {
1969 state(conn, SSH_STOP);
1974 * This is a directory that we are trying to get, so produce a directory
1977 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1980 strlen(sftp_scp->path)),
1981 0, 0, LIBSSH2_SFTP_OPENDIR);
1982 if(!sshc->sftp_handle) {
1983 if(libssh2_session_last_errno(sshc->ssh_session) ==
1984 LIBSSH2_ERROR_EAGAIN) {
1985 rc = LIBSSH2_ERROR_EAGAIN;
1989 err = sftp_libssh2_last_error(sshc->sftp_session);
1990 failf(data, "Could not open directory for reading: %s",
1991 sftp_libssh2_strerror(err));
1992 state(conn, SSH_SFTP_CLOSE);
1993 result = sftp_libssh2_error_to_CURLE(err);
1994 sshc->actualcode = result?result:CURLE_SSH;
1998 sshc->readdir_filename = malloc(PATH_MAX+1);
1999 if(!sshc->readdir_filename) {
2000 state(conn, SSH_SFTP_CLOSE);
2001 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2004 sshc->readdir_longentry = malloc(PATH_MAX+1);
2005 if(!sshc->readdir_longentry) {
2006 Curl_safefree(sshc->readdir_filename);
2007 state(conn, SSH_SFTP_CLOSE);
2008 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2011 state(conn, SSH_SFTP_READDIR);
2014 case SSH_SFTP_READDIR:
2015 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
2016 sshc->readdir_filename,
2018 sshc->readdir_longentry,
2020 &sshc->readdir_attrs);
2021 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
2022 rc = LIBSSH2_ERROR_EAGAIN;
2025 if(sshc->readdir_len > 0) {
2026 sshc->readdir_filename[sshc->readdir_len] = '\0';
2028 if(data->set.ftp_list_only) {
2031 tmpLine = aprintf("%s\n", sshc->readdir_filename);
2032 if(tmpLine == NULL) {
2033 state(conn, SSH_SFTP_CLOSE);
2034 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2037 result = Curl_client_write(conn, CLIENTWRITE_BODY,
2038 tmpLine, sshc->readdir_len+1);
2042 state(conn, SSH_STOP);
2045 /* since this counts what we send to the client, we include the
2046 newline in this counter */
2047 data->req.bytecount += sshc->readdir_len+1;
2049 /* output debug output if that is requested */
2050 if(data->set.verbose) {
2051 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
2052 sshc->readdir_len, conn);
2056 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
2057 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
2058 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
2059 if(!sshc->readdir_line) {
2060 Curl_safefree(sshc->readdir_filename);
2061 Curl_safefree(sshc->readdir_longentry);
2062 state(conn, SSH_SFTP_CLOSE);
2063 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2067 memcpy(sshc->readdir_line, sshc->readdir_longentry,
2068 sshc->readdir_currLen);
2069 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
2070 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
2071 LIBSSH2_SFTP_S_IFLNK)) {
2072 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
2073 if(sshc->readdir_linkPath == NULL) {
2074 Curl_safefree(sshc->readdir_filename);
2075 Curl_safefree(sshc->readdir_longentry);
2076 state(conn, SSH_SFTP_CLOSE);
2077 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2081 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
2082 sshc->readdir_filename);
2083 state(conn, SSH_SFTP_READDIR_LINK);
2086 state(conn, SSH_SFTP_READDIR_BOTTOM);
2090 else if(sshc->readdir_len == 0) {
2091 Curl_safefree(sshc->readdir_filename);
2092 Curl_safefree(sshc->readdir_longentry);
2093 state(conn, SSH_SFTP_READDIR_DONE);
2096 else if(sshc->readdir_len <= 0) {
2097 err = sftp_libssh2_last_error(sshc->sftp_session);
2098 result = sftp_libssh2_error_to_CURLE(err);
2099 sshc->actualcode = result?result:CURLE_SSH;
2100 failf(data, "Could not open remote file for reading: %s :: %d",
2101 sftp_libssh2_strerror(err),
2102 libssh2_session_last_errno(sshc->ssh_session));
2103 Curl_safefree(sshc->readdir_filename);
2104 Curl_safefree(sshc->readdir_longentry);
2105 state(conn, SSH_SFTP_CLOSE);
2110 case SSH_SFTP_READDIR_LINK:
2112 libssh2_sftp_symlink_ex(sshc->sftp_session,
2113 sshc->readdir_linkPath,
2114 curlx_uztoui(strlen(sshc->readdir_linkPath)),
2115 sshc->readdir_filename,
2116 PATH_MAX, LIBSSH2_SFTP_READLINK);
2117 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
2118 rc = LIBSSH2_ERROR_EAGAIN;
2121 Curl_safefree(sshc->readdir_linkPath);
2123 /* get room for the filename and extra output */
2124 sshc->readdir_totalLen += 4 + sshc->readdir_len;
2125 new_readdir_line = Curl_saferealloc(sshc->readdir_line,
2126 sshc->readdir_totalLen);
2127 if(!new_readdir_line) {
2128 sshc->readdir_line = NULL;
2129 Curl_safefree(sshc->readdir_filename);
2130 Curl_safefree(sshc->readdir_longentry);
2131 state(conn, SSH_SFTP_CLOSE);
2132 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2135 sshc->readdir_line = new_readdir_line;
2137 sshc->readdir_currLen += snprintf(sshc->readdir_line +
2138 sshc->readdir_currLen,
2139 sshc->readdir_totalLen -
2140 sshc->readdir_currLen,
2142 sshc->readdir_filename);
2144 state(conn, SSH_SFTP_READDIR_BOTTOM);
2147 case SSH_SFTP_READDIR_BOTTOM:
2148 sshc->readdir_currLen += snprintf(sshc->readdir_line +
2149 sshc->readdir_currLen,
2150 sshc->readdir_totalLen -
2151 sshc->readdir_currLen, "\n");
2152 result = Curl_client_write(conn, CLIENTWRITE_BODY,
2154 sshc->readdir_currLen);
2158 /* output debug output if that is requested */
2159 if(data->set.verbose) {
2160 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
2161 sshc->readdir_currLen, conn);
2163 data->req.bytecount += sshc->readdir_currLen;
2165 Curl_safefree(sshc->readdir_line);
2167 state(conn, SSH_STOP);
2170 state(conn, SSH_SFTP_READDIR);
2173 case SSH_SFTP_READDIR_DONE:
2174 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
2175 LIBSSH2_ERROR_EAGAIN) {
2176 rc = LIBSSH2_ERROR_EAGAIN;
2179 sshc->sftp_handle = NULL;
2180 Curl_safefree(sshc->readdir_filename);
2181 Curl_safefree(sshc->readdir_longentry);
2183 /* no data to transfer */
2184 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2185 state(conn, SSH_STOP);
2188 case SSH_SFTP_DOWNLOAD_INIT:
2190 * Work on getting the specified file
2193 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
2194 curlx_uztoui(strlen(sftp_scp->path)),
2195 LIBSSH2_FXF_READ, data->set.new_file_perms,
2196 LIBSSH2_SFTP_OPENFILE);
2197 if(!sshc->sftp_handle) {
2198 if(libssh2_session_last_errno(sshc->ssh_session) ==
2199 LIBSSH2_ERROR_EAGAIN) {
2200 rc = LIBSSH2_ERROR_EAGAIN;
2204 err = sftp_libssh2_last_error(sshc->sftp_session);
2205 failf(data, "Could not open remote file for reading: %s",
2206 sftp_libssh2_strerror(err));
2207 state(conn, SSH_SFTP_CLOSE);
2208 result = sftp_libssh2_error_to_CURLE(err);
2209 sshc->actualcode = result?result:CURLE_SSH;
2213 state(conn, SSH_SFTP_DOWNLOAD_STAT);
2216 case SSH_SFTP_DOWNLOAD_STAT:
2218 LIBSSH2_SFTP_ATTRIBUTES attrs;
2220 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
2221 curlx_uztoui(strlen(sftp_scp->path)),
2222 LIBSSH2_SFTP_STAT, &attrs);
2223 if(rc == LIBSSH2_ERROR_EAGAIN) {
2227 !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
2228 (attrs.filesize == 0)) {
2230 * libssh2_sftp_open() didn't return an error, so maybe the server
2231 * just doesn't support stat()
2232 * OR the server doesn't return a file size with a stat()
2235 data->req.size = -1;
2236 data->req.maxdownload = -1;
2237 Curl_pgrsSetDownloadSize(data, -1);
2240 curl_off_t size = attrs.filesize;
2243 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
2244 return CURLE_BAD_DOWNLOAD_RESUME;
2246 if(conn->data->state.use_range) {
2247 curl_off_t from, to;
2251 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2252 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2254 to=curlx_strtoofft(ptr, &ptr2, 0);
2255 if((ptr == ptr2) /* no "to" value given */
2260 /* from is relative to end of file */
2264 failf(data, "Offset (%"
2265 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2266 CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
2267 return CURLE_BAD_DOWNLOAD_RESUME;
2274 size = to - from + 1;
2277 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2279 data->req.size = size;
2280 data->req.maxdownload = size;
2281 Curl_pgrsSetDownloadSize(data, size);
2284 /* We can resume if we can seek to the resume position */
2285 if(data->state.resume_from) {
2286 if(data->state.resume_from < 0) {
2287 /* We're supposed to download the last abs(from) bytes */
2288 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2289 failf(data, "Offset (%"
2290 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2291 CURL_FORMAT_CURL_OFF_T ")",
2292 data->state.resume_from, attrs.filesize);
2293 return CURLE_BAD_DOWNLOAD_RESUME;
2295 /* download from where? */
2296 data->state.resume_from += attrs.filesize;
2299 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2300 failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
2301 ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
2302 data->state.resume_from, attrs.filesize);
2303 return CURLE_BAD_DOWNLOAD_RESUME;
2306 /* Does a completed file need to be seeked and started or closed ? */
2307 /* Now store the number of bytes we are expected to download */
2308 data->req.size = attrs.filesize - data->state.resume_from;
2309 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2310 Curl_pgrsSetDownloadSize(data,
2311 attrs.filesize - data->state.resume_from);
2312 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2316 /* Setup the actual download */
2317 if(data->req.size == 0) {
2318 /* no data to transfer */
2319 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2320 infof(data, "File already completely downloaded\n");
2321 state(conn, SSH_STOP);
2325 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2326 FALSE, NULL, -1, NULL);
2328 /* not set by Curl_setup_transfer to preserve keepon bits */
2329 conn->writesockfd = conn->sockfd;
2331 /* we want to use the _receiving_ function even when the socket turns
2332 out writableable as the underlying libssh2 recv function will deal
2333 with both accordingly */
2334 conn->cselect_bits = CURL_CSELECT_IN;
2337 /* this should never occur; the close state should be entered
2338 at the time the error occurs */
2339 state(conn, SSH_SFTP_CLOSE);
2340 sshc->actualcode = result;
2343 state(conn, SSH_STOP);
2347 case SSH_SFTP_CLOSE:
2348 if(sshc->sftp_handle) {
2349 rc = libssh2_sftp_close(sshc->sftp_handle);
2350 if(rc == LIBSSH2_ERROR_EAGAIN) {
2354 infof(data, "Failed to close libssh2 file\n");
2356 sshc->sftp_handle = NULL;
2359 Curl_safefree(sftp_scp->path);
2361 DEBUGF(infof(data, "SFTP DONE done\n"));
2363 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2364 After nextstate is executed, the control should come back to
2365 SSH_SFTP_CLOSE to pass the correct result back */
2366 if(sshc->nextstate != SSH_NO_STATE &&
2367 sshc->nextstate != SSH_SFTP_CLOSE) {
2368 state(conn, sshc->nextstate);
2369 sshc->nextstate = SSH_SFTP_CLOSE;
2372 state(conn, SSH_STOP);
2373 result = sshc->actualcode;
2377 case SSH_SFTP_SHUTDOWN:
2378 /* during times we get here due to a broken transfer and then the
2379 sftp_handle might not have been taken down so make sure that is done
2380 before we proceed */
2382 if(sshc->sftp_handle) {
2383 rc = libssh2_sftp_close(sshc->sftp_handle);
2384 if(rc == LIBSSH2_ERROR_EAGAIN) {
2388 infof(data, "Failed to close libssh2 file\n");
2390 sshc->sftp_handle = NULL;
2392 if(sshc->sftp_session) {
2393 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2394 if(rc == LIBSSH2_ERROR_EAGAIN) {
2398 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2400 sshc->sftp_session = NULL;
2403 Curl_safefree(sshc->homedir);
2404 conn->data->state.most_recent_ftp_entrypath = NULL;
2406 state(conn, SSH_SESSION_DISCONNECT);
2409 case SSH_SCP_TRANS_INIT:
2410 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2412 sshc->actualcode = result;
2413 state(conn, SSH_STOP);
2417 if(data->set.upload) {
2418 if(data->state.infilesize < 0) {
2419 failf(data, "SCP requires a known file size for upload");
2420 sshc->actualcode = CURLE_UPLOAD_FAILED;
2421 state(conn, SSH_SCP_CHANNEL_FREE);
2424 state(conn, SSH_SCP_UPLOAD_INIT);
2427 state(conn, SSH_SCP_DOWNLOAD_INIT);
2431 case SSH_SCP_UPLOAD_INIT:
2433 * libssh2 requires that the destination path is a full path that
2434 * includes the destination file and name OR ends in a "/" . If this is
2435 * not done the destination file will be named the same name as the last
2436 * directory in the path.
2439 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2440 data->state.infilesize);
2441 if(!sshc->ssh_channel) {
2442 if(libssh2_session_last_errno(sshc->ssh_session) ==
2443 LIBSSH2_ERROR_EAGAIN) {
2444 rc = LIBSSH2_ERROR_EAGAIN;
2451 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2452 &err_msg, NULL, 0));
2453 failf(conn->data, "%s", err_msg);
2454 state(conn, SSH_SCP_CHANNEL_FREE);
2455 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2461 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2464 /* not set by Curl_setup_transfer to preserve keepon bits */
2465 conn->sockfd = conn->writesockfd;
2468 state(conn, SSH_SCP_CHANNEL_FREE);
2469 sshc->actualcode = result;
2472 /* store this original bitmask setup to use later on if we can't
2473 figure out a "real" bitmask */
2474 sshc->orig_waitfor = data->req.keepon;
2476 /* we want to use the _sending_ function even when the socket turns
2477 out readable as the underlying libssh2 scp send function will deal
2478 with both accordingly */
2479 conn->cselect_bits = CURL_CSELECT_OUT;
2481 state(conn, SSH_STOP);
2485 case SSH_SCP_DOWNLOAD_INIT:
2487 curl_off_t bytecount;
2490 * We must check the remote file; if it is a directory no values will
2495 * If support for >2GB files exists, use it.
2498 /* get a fresh new channel from the ssh layer */
2499 #if LIBSSH2_VERSION_NUM < 0x010700
2501 memset(&sb, 0, sizeof(struct stat));
2502 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2503 sftp_scp->path, &sb);
2505 libssh2_struct_stat sb;
2506 memset(&sb, 0, sizeof(libssh2_struct_stat));
2507 sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session,
2508 sftp_scp->path, &sb);
2511 if(!sshc->ssh_channel) {
2512 if(libssh2_session_last_errno(sshc->ssh_session) ==
2513 LIBSSH2_ERROR_EAGAIN) {
2514 rc = LIBSSH2_ERROR_EAGAIN;
2521 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2522 &err_msg, NULL, 0));
2523 failf(conn->data, "%s", err_msg);
2524 state(conn, SSH_SCP_CHANNEL_FREE);
2525 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2531 bytecount = (curl_off_t)sb.st_size;
2532 data->req.maxdownload = (curl_off_t)sb.st_size;
2533 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2535 /* not set by Curl_setup_transfer to preserve keepon bits */
2536 conn->writesockfd = conn->sockfd;
2538 /* we want to use the _receiving_ function even when the socket turns
2539 out writableable as the underlying libssh2 recv function will deal
2540 with both accordingly */
2541 conn->cselect_bits = CURL_CSELECT_IN;
2544 state(conn, SSH_SCP_CHANNEL_FREE);
2545 sshc->actualcode = result;
2548 state(conn, SSH_STOP);
2553 if(data->set.upload)
2554 state(conn, SSH_SCP_SEND_EOF);
2556 state(conn, SSH_SCP_CHANNEL_FREE);
2559 case SSH_SCP_SEND_EOF:
2560 if(sshc->ssh_channel) {
2561 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2562 if(rc == LIBSSH2_ERROR_EAGAIN) {
2566 infof(data, "Failed to send libssh2 channel EOF\n");
2569 state(conn, SSH_SCP_WAIT_EOF);
2572 case SSH_SCP_WAIT_EOF:
2573 if(sshc->ssh_channel) {
2574 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2575 if(rc == LIBSSH2_ERROR_EAGAIN) {
2579 infof(data, "Failed to get channel EOF: %d\n", rc);
2582 state(conn, SSH_SCP_WAIT_CLOSE);
2585 case SSH_SCP_WAIT_CLOSE:
2586 if(sshc->ssh_channel) {
2587 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2588 if(rc == LIBSSH2_ERROR_EAGAIN) {
2592 infof(data, "Channel failed to close: %d\n", rc);
2595 state(conn, SSH_SCP_CHANNEL_FREE);
2598 case SSH_SCP_CHANNEL_FREE:
2599 if(sshc->ssh_channel) {
2600 rc = libssh2_channel_free(sshc->ssh_channel);
2601 if(rc == LIBSSH2_ERROR_EAGAIN) {
2605 infof(data, "Failed to free libssh2 scp subsystem\n");
2607 sshc->ssh_channel = NULL;
2609 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2611 state(conn, SSH_SESSION_DISCONNECT);
2613 state(conn, SSH_STOP);
2614 result = sshc->actualcode;
2617 case SSH_SESSION_DISCONNECT:
2618 /* during weird times when we've been prematurely aborted, the channel
2619 is still alive when we reach this state and we MUST kill the channel
2621 if(sshc->ssh_channel) {
2622 rc = libssh2_channel_free(sshc->ssh_channel);
2623 if(rc == LIBSSH2_ERROR_EAGAIN) {
2627 infof(data, "Failed to free libssh2 scp subsystem\n");
2629 sshc->ssh_channel = NULL;
2632 if(sshc->ssh_session) {
2633 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2634 if(rc == LIBSSH2_ERROR_EAGAIN) {
2638 infof(data, "Failed to disconnect libssh2 session\n");
2642 Curl_safefree(sshc->homedir);
2643 conn->data->state.most_recent_ftp_entrypath = NULL;
2645 state(conn, SSH_SESSION_FREE);
2648 case SSH_SESSION_FREE:
2649 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2651 libssh2_knownhost_free(sshc->kh);
2656 #ifdef HAVE_LIBSSH2_AGENT_API
2657 if(sshc->ssh_agent) {
2658 rc = libssh2_agent_disconnect(sshc->ssh_agent);
2659 if(rc == LIBSSH2_ERROR_EAGAIN) {
2663 infof(data, "Failed to disconnect from libssh2 agent\n");
2665 libssh2_agent_free(sshc->ssh_agent);
2666 sshc->ssh_agent = NULL;
2668 /* NB: there is no need to free identities, they are part of internal
2670 sshc->sshagent_identity = NULL;
2671 sshc->sshagent_prev_identity = NULL;
2675 if(sshc->ssh_session) {
2676 rc = libssh2_session_free(sshc->ssh_session);
2677 if(rc == LIBSSH2_ERROR_EAGAIN) {
2681 infof(data, "Failed to free libssh2 session\n");
2683 sshc->ssh_session = NULL;
2686 /* worst-case scenario cleanup */
2688 DEBUGASSERT(sshc->ssh_session == NULL);
2689 DEBUGASSERT(sshc->ssh_channel == NULL);
2690 DEBUGASSERT(sshc->sftp_session == NULL);
2691 DEBUGASSERT(sshc->sftp_handle == NULL);
2692 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2693 DEBUGASSERT(sshc->kh == NULL);
2695 #ifdef HAVE_LIBSSH2_AGENT_API
2696 DEBUGASSERT(sshc->ssh_agent == NULL);
2699 Curl_safefree(sshc->rsa_pub);
2700 Curl_safefree(sshc->rsa);
2702 Curl_safefree(sshc->quote_path1);
2703 Curl_safefree(sshc->quote_path2);
2705 Curl_safefree(sshc->homedir);
2707 Curl_safefree(sshc->readdir_filename);
2708 Curl_safefree(sshc->readdir_longentry);
2709 Curl_safefree(sshc->readdir_line);
2710 Curl_safefree(sshc->readdir_linkPath);
2712 /* the code we are about to return */
2713 result = sshc->actualcode;
2715 memset(sshc, 0, sizeof(struct ssh_conn));
2717 connclose(conn, "SSH session free");
2718 sshc->state = SSH_SESSION_FREE; /* current */
2719 sshc->nextstate = SSH_NO_STATE;
2720 state(conn, SSH_STOP);
2724 /* fallthrough, just stop! */
2726 /* internal error */
2727 sshc->nextstate = SSH_NO_STATE;
2728 state(conn, SSH_STOP);
2732 } while(!rc && (sshc->state != SSH_STOP));
2734 if(rc == LIBSSH2_ERROR_EAGAIN) {
2735 /* we would block, we need to wait for the socket to be ready (in the
2736 right direction too)! */
2743 /* called by the multi interface to figure out what socket(s) to wait for and
2744 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2745 static int ssh_perform_getsock(const struct connectdata *conn,
2746 curl_socket_t *sock, /* points to numsocks
2747 number of sockets */
2750 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2751 int bitmap = GETSOCK_BLANK;
2754 sock[0] = conn->sock[FIRSTSOCKET];
2756 if(conn->waitfor & KEEP_RECV)
2757 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2759 if(conn->waitfor & KEEP_SEND)
2760 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2764 /* if we don't know the direction we can use the generic *_getsock()
2765 function even for the protocol_connect and doing states */
2766 return Curl_single_getsock(conn, sock, numsocks);
2770 /* Generic function called by the multi interface to figure out what socket(s)
2771 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2772 static int ssh_getsock(struct connectdata *conn,
2773 curl_socket_t *sock, /* points to numsocks number
2777 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2781 /* if we don't know any direction we can just play along as we used to and
2782 not provide any sensible info */
2783 return GETSOCK_BLANK;
2785 /* if we know the direction we can use the generic *_getsock() function even
2786 for the protocol_connect and doing states */
2787 return ssh_perform_getsock(conn, sock, numsocks);
2791 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2793 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2794 * function is used to figure out in what direction and stores this info so
2795 * that the multi interface can take advantage of it. Make sure to call this
2796 * function in all cases so that when it _doesn't_ return EAGAIN we can
2797 * restore the default wait bits.
2799 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2801 struct ssh_conn *sshc = &conn->proto.sshc;
2804 dir = libssh2_session_block_directions(sshc->ssh_session);
2806 /* translate the libssh2 define bits into our own bit defines */
2807 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2808 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2812 /* It didn't block or libssh2 didn't reveal in which direction, put back
2814 conn->waitfor = sshc->orig_waitfor;
2817 /* no libssh2 directional support so we simply don't know */
2818 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2821 /* called repeatedly until done from multi.c */
2822 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2824 struct ssh_conn *sshc = &conn->proto.sshc;
2825 CURLcode result = CURLE_OK;
2826 bool block; /* we store the status and use that to provide a ssh_getsock()
2829 result = ssh_statemach_act(conn, &block);
2830 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2831 ssh_block2waitfor(conn, block);
2836 static CURLcode ssh_block_statemach(struct connectdata *conn,
2839 struct ssh_conn *sshc = &conn->proto.sshc;
2840 CURLcode result = CURLE_OK;
2841 struct Curl_easy *data = conn->data;
2843 while((sshc->state != SSH_STOP) && !result) {
2847 result = ssh_statemach_act(conn, &block);
2851 if(Curl_pgrsUpdate(conn))
2852 return CURLE_ABORTED_BY_CALLBACK;
2854 struct timeval now = Curl_tvnow();
2855 result = Curl_speedcheck(data, now);
2860 left = Curl_timeleft(data, NULL, duringconnect);
2862 failf(data, "Operation timed out");
2863 return CURLE_OPERATION_TIMEDOUT;
2866 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2867 if(!result && block) {
2868 int dir = libssh2_session_block_directions(sshc->ssh_session);
2869 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2870 curl_socket_t fd_read = CURL_SOCKET_BAD;
2871 curl_socket_t fd_write = CURL_SOCKET_BAD;
2872 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2874 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2876 /* wait for the socket to become ready */
2877 (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
2878 left>1000?1000:left); /* ignore result */
2888 * SSH setup and connection
2890 static CURLcode ssh_setup_connection(struct connectdata *conn)
2892 struct SSHPROTO *ssh;
2894 conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
2896 return CURLE_OUT_OF_MEMORY;
2901 static Curl_recv scp_recv, sftp_recv;
2902 static Curl_send scp_send, sftp_send;
2905 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2906 * do protocol-specific actions at connect-time.
2908 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2910 #ifdef CURL_LIBSSH2_DEBUG
2913 struct ssh_conn *ssh;
2915 struct Curl_easy *data = conn->data;
2917 /* initialize per-handle data if not already */
2918 if(!data->req.protop)
2919 ssh_setup_connection(conn);
2921 /* We default to persistent connections. We set this already in this connect
2922 function to make the re-use checks properly be able to check this bit. */
2923 connkeep(conn, "SSH default");
2925 if(conn->handler->protocol & CURLPROTO_SCP) {
2926 conn->recv[FIRSTSOCKET] = scp_recv;
2927 conn->send[FIRSTSOCKET] = scp_send;
2930 conn->recv[FIRSTSOCKET] = sftp_recv;
2931 conn->send[FIRSTSOCKET] = sftp_send;
2933 ssh = &conn->proto.sshc;
2935 #ifdef CURL_LIBSSH2_DEBUG
2937 infof(data, "User: %s\n", conn->user);
2940 infof(data, "Password: %s\n", conn->passwd);
2942 sock = conn->sock[FIRSTSOCKET];
2943 #endif /* CURL_LIBSSH2_DEBUG */
2945 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2947 my_libssh2_realloc, conn);
2948 if(ssh->ssh_session == NULL) {
2949 failf(data, "Failure initialising ssh session");
2950 return CURLE_FAILED_INIT;
2953 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2954 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2956 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2958 /* eeek. TODO: free the ssh_session! */
2959 return CURLE_FAILED_INIT;
2962 /* read all known hosts from there */
2963 rc = libssh2_knownhost_readfile(ssh->kh,
2964 data->set.str[STRING_SSH_KNOWNHOSTS],
2965 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2967 infof(data, "Failed to read known hosts from %s\n",
2968 data->set.str[STRING_SSH_KNOWNHOSTS]);
2970 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2972 #ifdef CURL_LIBSSH2_DEBUG
2973 libssh2_trace(ssh->ssh_session, ~0);
2974 infof(data, "SSH socket: %d\n", (int)sock);
2975 #endif /* CURL_LIBSSH2_DEBUG */
2977 state(conn, SSH_INIT);
2979 result = ssh_multi_statemach(conn, done);
2985 ***********************************************************************
2989 * This is the actual DO function for SCP. Get a file according to
2990 * the options previously setup.
2994 CURLcode scp_perform(struct connectdata *conn,
2998 CURLcode result = CURLE_OK;
3000 DEBUGF(infof(conn->data, "DO phase starts\n"));
3002 *dophase_done = FALSE; /* not done yet */
3004 /* start the first command in the DO phase */
3005 state(conn, SSH_SCP_TRANS_INIT);
3007 /* run the state-machine */
3008 result = ssh_multi_statemach(conn, dophase_done);
3010 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3013 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3019 /* called from multi.c while DOing */
3020 static CURLcode scp_doing(struct connectdata *conn,
3024 result = ssh_multi_statemach(conn, dophase_done);
3027 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3033 * The DO function is generic for both protocols. There was previously two
3034 * separate ones but this way means less duplicated code.
3037 static CURLcode ssh_do(struct connectdata *conn, bool *done)
3041 struct Curl_easy *data = conn->data;
3042 struct ssh_conn *sshc = &conn->proto.sshc;
3044 *done = FALSE; /* default to false */
3046 data->req.size = -1; /* make sure this is unknown at this point */
3048 sshc->actualcode = CURLE_OK; /* reset error code */
3049 sshc->secondCreateDirs =0; /* reset the create dir attempt state
3052 Curl_pgrsSetUploadCounter(data, 0);
3053 Curl_pgrsSetDownloadCounter(data, 0);
3054 Curl_pgrsSetUploadSize(data, -1);
3055 Curl_pgrsSetDownloadSize(data, -1);
3057 if(conn->handler->protocol & CURLPROTO_SCP)
3058 result = scp_perform(conn, &connected, done);
3060 result = sftp_perform(conn, &connected, done);
3065 /* BLOCKING, but the function is using the state machine so the only reason
3066 this is still blocking is that the multi interface code has no support for
3067 disconnecting operations that takes a while */
3068 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
3070 CURLcode result = CURLE_OK;
3071 struct ssh_conn *ssh = &conn->proto.sshc;
3072 (void) dead_connection;
3074 if(ssh->ssh_session) {
3075 /* only if there's a session still around to use! */
3077 state(conn, SSH_SESSION_DISCONNECT);
3079 result = ssh_block_statemach(conn, FALSE);
3085 /* generic done function for both SCP and SFTP called from their specific
3087 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
3089 CURLcode result = CURLE_OK;
3090 struct SSHPROTO *sftp_scp = conn->data->req.protop;
3093 /* run the state-machine
3095 TODO: when the multi interface is used, this _really_ should be using
3096 the ssh_multi_statemach function but we have no general support for
3097 non-blocking DONE operations!
3099 result = ssh_block_statemach(conn, FALSE);
3105 Curl_safefree(sftp_scp->path);
3106 if(Curl_pgrsDone(conn))
3107 return CURLE_ABORTED_BY_CALLBACK;
3109 conn->data->req.keepon = 0; /* clear all bits */
3114 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
3117 (void)premature; /* not used */
3120 state(conn, SSH_SCP_DONE);
3122 return ssh_done(conn, status);
3126 static ssize_t scp_send(struct connectdata *conn, int sockindex,
3127 const void *mem, size_t len, CURLcode *err)
3130 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3132 /* libssh2_channel_write() returns int! */
3134 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
3136 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3138 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3142 else if(nwrite < LIBSSH2_ERROR_NONE) {
3143 *err = libssh2_session_error_to_CURLE((int)nwrite);
3150 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
3151 char *mem, size_t len, CURLcode *err)
3154 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3156 /* libssh2_channel_read() returns int */
3158 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
3160 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3161 if(nread == LIBSSH2_ERROR_EAGAIN) {
3170 * =============== SFTP ===============
3174 ***********************************************************************
3178 * This is the actual DO function for SFTP. Get a file/directory according to
3179 * the options previously setup.
3183 CURLcode sftp_perform(struct connectdata *conn,
3187 CURLcode result = CURLE_OK;
3189 DEBUGF(infof(conn->data, "DO phase starts\n"));
3191 *dophase_done = FALSE; /* not done yet */
3193 /* start the first command in the DO phase */
3194 state(conn, SSH_SFTP_QUOTE_INIT);
3196 /* run the state-machine */
3197 result = ssh_multi_statemach(conn, dophase_done);
3199 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3202 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3208 /* called from multi.c while DOing */
3209 static CURLcode sftp_doing(struct connectdata *conn,
3212 CURLcode result = ssh_multi_statemach(conn, dophase_done);
3215 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3220 /* BLOCKING, but the function is using the state machine so the only reason
3221 this is still blocking is that the multi interface code has no support for
3222 disconnecting operations that takes a while */
3223 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
3225 CURLcode result = CURLE_OK;
3226 (void) dead_connection;
3228 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3230 if(conn->proto.sshc.ssh_session) {
3231 /* only if there's a session still around to use! */
3232 state(conn, SSH_SFTP_SHUTDOWN);
3233 result = ssh_block_statemach(conn, FALSE);
3236 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3242 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3245 struct ssh_conn *sshc = &conn->proto.sshc;
3248 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3249 errors that could happen due to open file handles during POSTQUOTE
3251 if(!status && !premature && conn->data->set.postquote) {
3252 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3253 state(conn, SSH_SFTP_CLOSE);
3256 state(conn, SSH_SFTP_CLOSE);
3258 return ssh_done(conn, status);
3261 /* return number of sent bytes */
3262 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3263 const void *mem, size_t len, CURLcode *err)
3265 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3266 but is changed to ssize_t in 0.15. These days we don't
3267 support libssh2 0.15*/
3270 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3272 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3274 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3278 else if(nwrite < LIBSSH2_ERROR_NONE) {
3279 *err = libssh2_session_error_to_CURLE((int)nwrite);
3287 * Return number of received (decrypted) bytes
3290 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3291 char *mem, size_t len, CURLcode *err)
3296 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3298 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3300 if(nread == LIBSSH2_ERROR_EAGAIN) {
3305 else if(nread < 0) {
3306 *err = libssh2_session_error_to_CURLE((int)nread);
3311 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3314 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3316 * Permission to use, copy, modify, and distribute this software for any
3317 * purpose with or without fee is hereby granted, provided that the above
3318 * copyright notice and this permission notice appear in all copies.
3320 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3321 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3322 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3323 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3324 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3325 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3326 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3329 get_pathname(const char **cpp, char **path)
3331 const char *cp = *cpp, *end;
3334 static const char WHITESPACE[] = " \t\r\n";
3336 cp += strspn(cp, WHITESPACE);
3340 return CURLE_QUOTE_ERROR;
3343 *path = malloc(strlen(cp) + 1);
3345 return CURLE_OUT_OF_MEMORY;
3347 /* Check for quoted filenames */
3348 if(*cp == '\"' || *cp == '\'') {
3351 /* Search for terminating quote, unescape some chars */
3352 for(i = j = 0; i <= strlen(cp); i++) {
3353 if(cp[i] == quot) { /* Found quote */
3358 if(cp[i] == '\0') { /* End of string */
3359 /*error("Unterminated quote");*/
3362 if(cp[i] == '\\') { /* Escaped characters */
3364 if(cp[i] != '\'' && cp[i] != '\"' &&
3366 /*error("Bad escaped character '\\%c'",
3371 (*path)[j++] = cp[i];
3375 /*error("Empty quotes");*/
3378 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3381 /* Read to end of filename */
3382 end = strpbrk(cp, WHITESPACE);
3384 end = strchr(cp, '\0');
3385 *cpp = end + strspn(end, WHITESPACE);
3387 memcpy(*path, cp, end - cp);
3388 (*path)[end - cp] = '\0';
3393 Curl_safefree(*path);
3394 return CURLE_QUOTE_ERROR;
3398 static const char *sftp_libssh2_strerror(int err)
3401 case LIBSSH2_FX_NO_SUCH_FILE:
3402 return "No such file or directory";
3404 case LIBSSH2_FX_PERMISSION_DENIED:
3405 return "Permission denied";
3407 case LIBSSH2_FX_FAILURE:
3408 return "Operation failed";
3410 case LIBSSH2_FX_BAD_MESSAGE:
3411 return "Bad message from SFTP server";
3413 case LIBSSH2_FX_NO_CONNECTION:
3414 return "Not connected to SFTP server";
3416 case LIBSSH2_FX_CONNECTION_LOST:
3417 return "Connection to SFTP server lost";
3419 case LIBSSH2_FX_OP_UNSUPPORTED:
3420 return "Operation not supported by SFTP server";
3422 case LIBSSH2_FX_INVALID_HANDLE:
3423 return "Invalid handle";
3425 case LIBSSH2_FX_NO_SUCH_PATH:
3426 return "No such file or directory";
3428 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3429 return "File already exists";
3431 case LIBSSH2_FX_WRITE_PROTECT:
3432 return "File is write protected";
3434 case LIBSSH2_FX_NO_MEDIA:
3437 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3440 case LIBSSH2_FX_QUOTA_EXCEEDED:
3441 return "User quota exceeded";
3443 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3444 return "Unknown principle";
3446 case LIBSSH2_FX_LOCK_CONFlICT:
3447 return "File lock conflict";
3449 case LIBSSH2_FX_DIR_NOT_EMPTY:
3450 return "Directory not empty";
3452 case LIBSSH2_FX_NOT_A_DIRECTORY:
3453 return "Not a directory";
3455 case LIBSSH2_FX_INVALID_FILENAME:
3456 return "Invalid filename";
3458 case LIBSSH2_FX_LINK_LOOP:
3459 return "Link points to itself";
3461 return "Unknown error in libssh2";
3464 #endif /* USE_LIBSSH2 */