1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2022, 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.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"
32 #include <libssh2_sftp.h>
38 #ifdef HAVE_NETINET_IN_H
39 #include <netinet/in.h>
41 #ifdef HAVE_ARPA_INET_H
42 #include <arpa/inet.h>
45 #include <sys/utsname.h>
55 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
57 #define in_addr_t unsigned long
60 #include <curl/curl.h>
67 #include "http.h" /* for HTTP proxy tunnel stuff */
70 #include "speedcheck.h"
74 #include "vtls/vtls.h"
76 #include "inet_ntop.h"
77 #include "parsedate.h" /* for the week day and month names */
78 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
79 #include "strtoofft.h"
83 #include "curl_path.h"
86 #include <curl_base64.h> /* for base64 encoding/decoding */
87 #include <curl_sha256.h>
90 /* The last 3 #include files should be in this order */
91 #include "curl_printf.h"
92 #include "curl_memory.h"
95 #if LIBSSH2_VERSION_NUM >= 0x010206
96 /* libssh2_sftp_statvfs and friends were added in 1.2.6 */
97 #define HAS_STATVFS_SUPPORT 1
100 #define sftp_libssh2_realpath(s,p,t,m) \
101 libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
102 (t), (m), LIBSSH2_SFTP_REALPATH)
104 /* Local functions: */
105 static const char *sftp_libssh2_strerror(unsigned long err);
106 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
107 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
108 static LIBSSH2_FREE_FUNC(my_libssh2_free);
110 static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data);
111 static CURLcode ssh_connect(struct Curl_easy *data, bool *done);
112 static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done);
113 static CURLcode ssh_do(struct Curl_easy *data, bool *done);
114 static CURLcode scp_done(struct Curl_easy *data, CURLcode c, bool premature);
115 static CURLcode scp_doing(struct Curl_easy *data, bool *dophase_done);
116 static CURLcode scp_disconnect(struct Curl_easy *data,
117 struct connectdata *conn, bool dead_connection);
118 static CURLcode sftp_done(struct Curl_easy *data, CURLcode, bool premature);
119 static CURLcode sftp_doing(struct Curl_easy *data, bool *dophase_done);
120 static CURLcode sftp_disconnect(struct Curl_easy *data,
121 struct connectdata *conn, bool dead);
122 static CURLcode sftp_perform(struct Curl_easy *data, bool *connected,
124 static int ssh_getsock(struct Curl_easy *data, struct connectdata *conn,
125 curl_socket_t *sock);
126 static CURLcode ssh_setup_connection(struct Curl_easy *data,
127 struct connectdata *conn);
128 static void ssh_attach(struct Curl_easy *data, struct connectdata *conn);
131 * SCP protocol handler.
134 const struct Curl_handler Curl_handler_scp = {
136 ssh_setup_connection, /* setup_connection */
139 ZERO_NULL, /* do_more */
140 ssh_connect, /* connect_it */
141 ssh_multi_statemach, /* connecting */
142 scp_doing, /* doing */
143 ssh_getsock, /* proto_getsock */
144 ssh_getsock, /* doing_getsock */
145 ZERO_NULL, /* domore_getsock */
146 ssh_getsock, /* perform_getsock */
147 scp_disconnect, /* disconnect */
148 ZERO_NULL, /* readwrite */
149 ZERO_NULL, /* connection_check */
151 PORT_SSH, /* defport */
152 CURLPROTO_SCP, /* protocol */
153 CURLPROTO_SCP, /* family */
154 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
155 | PROTOPT_NOURLQUERY /* flags */
160 * SFTP protocol handler.
163 const struct Curl_handler Curl_handler_sftp = {
165 ssh_setup_connection, /* setup_connection */
167 sftp_done, /* done */
168 ZERO_NULL, /* do_more */
169 ssh_connect, /* connect_it */
170 ssh_multi_statemach, /* connecting */
171 sftp_doing, /* doing */
172 ssh_getsock, /* proto_getsock */
173 ssh_getsock, /* doing_getsock */
174 ZERO_NULL, /* domore_getsock */
175 ssh_getsock, /* perform_getsock */
176 sftp_disconnect, /* disconnect */
177 ZERO_NULL, /* readwrite */
178 ZERO_NULL, /* connection_check */
180 PORT_SSH, /* defport */
181 CURLPROTO_SFTP, /* protocol */
182 CURLPROTO_SFTP, /* family */
183 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
184 | PROTOPT_NOURLQUERY /* flags */
188 kbd_callback(const char *name, int name_len, const char *instruction,
189 int instruction_len, int num_prompts,
190 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
191 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
194 struct Curl_easy *data = (struct Curl_easy *)*abstract;
196 #ifdef CURL_LIBSSH2_DEBUG
197 fprintf(stderr, "name=%s\n", name);
198 fprintf(stderr, "name_len=%d\n", name_len);
199 fprintf(stderr, "instruction=%s\n", instruction);
200 fprintf(stderr, "instruction_len=%d\n", instruction_len);
201 fprintf(stderr, "num_prompts=%d\n", num_prompts);
206 (void)instruction_len;
207 #endif /* CURL_LIBSSH2_DEBUG */
208 if(num_prompts == 1) {
209 struct connectdata *conn = data->conn;
210 responses[0].text = strdup(conn->passwd);
211 responses[0].length = curlx_uztoui(strlen(conn->passwd));
216 static CURLcode sftp_libssh2_error_to_CURLE(unsigned long err)
222 case LIBSSH2_FX_NO_SUCH_FILE:
223 case LIBSSH2_FX_NO_SUCH_PATH:
224 return CURLE_REMOTE_FILE_NOT_FOUND;
226 case LIBSSH2_FX_PERMISSION_DENIED:
227 case LIBSSH2_FX_WRITE_PROTECT:
228 case LIBSSH2_FX_LOCK_CONFlICT:
229 return CURLE_REMOTE_ACCESS_DENIED;
231 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
232 case LIBSSH2_FX_QUOTA_EXCEEDED:
233 return CURLE_REMOTE_DISK_FULL;
235 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
236 return CURLE_REMOTE_FILE_EXISTS;
238 case LIBSSH2_FX_DIR_NOT_EMPTY:
239 return CURLE_QUOTE_ERROR;
248 static CURLcode libssh2_session_error_to_CURLE(int err)
251 /* Ordered by order of appearance in libssh2.h */
252 case LIBSSH2_ERROR_NONE:
255 /* This is the error returned by libssh2_scp_recv2
257 case LIBSSH2_ERROR_SCP_PROTOCOL:
258 return CURLE_REMOTE_FILE_NOT_FOUND;
260 case LIBSSH2_ERROR_SOCKET_NONE:
261 return CURLE_COULDNT_CONNECT;
263 case LIBSSH2_ERROR_ALLOC:
264 return CURLE_OUT_OF_MEMORY;
266 case LIBSSH2_ERROR_SOCKET_SEND:
267 return CURLE_SEND_ERROR;
269 case LIBSSH2_ERROR_HOSTKEY_INIT:
270 case LIBSSH2_ERROR_HOSTKEY_SIGN:
271 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
272 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
273 return CURLE_PEER_FAILED_VERIFICATION;
275 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
276 return CURLE_LOGIN_DENIED;
278 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
279 case LIBSSH2_ERROR_TIMEOUT:
280 return CURLE_OPERATION_TIMEDOUT;
282 case LIBSSH2_ERROR_EAGAIN:
289 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
291 (void)abstract; /* arg not used */
292 return malloc(count);
295 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
297 (void)abstract; /* arg not used */
298 return realloc(ptr, count);
301 static LIBSSH2_FREE_FUNC(my_libssh2_free)
303 (void)abstract; /* arg not used */
304 if(ptr) /* ssh2 agent sometimes call free with null ptr */
309 * SSH State machine related code
311 /* This is the ONLY way to change SSH state! */
312 static void state(struct Curl_easy *data, sshstate nowstate)
314 struct connectdata *conn = data->conn;
315 struct ssh_conn *sshc = &conn->proto.sshc;
316 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
317 /* for debug purposes */
318 static const char * const names[] = {
324 "SSH_AUTH_PKEY_INIT",
326 "SSH_AUTH_PASS_INIT",
328 "SSH_AUTH_AGENT_INIT",
329 "SSH_AUTH_AGENT_LIST",
331 "SSH_AUTH_HOST_INIT",
339 "SSH_SFTP_QUOTE_INIT",
340 "SSH_SFTP_POSTQUOTE_INIT",
342 "SSH_SFTP_NEXT_QUOTE",
343 "SSH_SFTP_QUOTE_STAT",
344 "SSH_SFTP_QUOTE_SETSTAT",
345 "SSH_SFTP_QUOTE_SYMLINK",
346 "SSH_SFTP_QUOTE_MKDIR",
347 "SSH_SFTP_QUOTE_RENAME",
348 "SSH_SFTP_QUOTE_RMDIR",
349 "SSH_SFTP_QUOTE_UNLINK",
350 "SSH_SFTP_QUOTE_STATVFS",
353 "SSH_SFTP_TRANS_INIT",
354 "SSH_SFTP_UPLOAD_INIT",
355 "SSH_SFTP_CREATE_DIRS_INIT",
356 "SSH_SFTP_CREATE_DIRS",
357 "SSH_SFTP_CREATE_DIRS_MKDIR",
358 "SSH_SFTP_READDIR_INIT",
360 "SSH_SFTP_READDIR_LINK",
361 "SSH_SFTP_READDIR_BOTTOM",
362 "SSH_SFTP_READDIR_DONE",
363 "SSH_SFTP_DOWNLOAD_INIT",
364 "SSH_SFTP_DOWNLOAD_STAT",
367 "SSH_SCP_TRANS_INIT",
368 "SSH_SCP_UPLOAD_INIT",
369 "SSH_SCP_DOWNLOAD_INIT",
374 "SSH_SCP_WAIT_CLOSE",
375 "SSH_SCP_CHANNEL_FREE",
376 "SSH_SESSION_DISCONNECT",
381 /* a precaution to make sure the lists are in sync */
382 DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST);
384 if(sshc->state != nowstate) {
385 infof(data, "SFTP %p state change from %s to %s",
386 (void *)sshc, names[sshc->state], names[nowstate]);
390 sshc->state = nowstate;
394 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
395 static int sshkeycallback(struct Curl_easy *easy,
396 const struct curl_khkey *knownkey, /* known */
397 const struct curl_khkey *foundkey, /* found */
398 enum curl_khmatch match,
406 /* we only allow perfect matches, and we reject everything else */
407 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
412 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
415 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
416 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
418 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
422 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
423 * architectures so we check of the necessary function is present.
425 #ifndef HAVE_LIBSSH2_SCP_SEND64
426 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
428 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
429 (libssh2_uint64_t)d, 0, 0)
433 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
435 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
436 #define session_startup(x,y) libssh2_session_handshake(x, y)
438 #define session_startup(x,y) libssh2_session_startup(x, (int)y)
441 static CURLcode ssh_knownhost(struct Curl_easy *data)
443 CURLcode result = CURLE_OK;
445 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
446 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
447 /* we're asked to verify the host against a file */
448 struct connectdata *conn = data->conn;
449 struct ssh_conn *sshc = &conn->proto.sshc;
450 struct libssh2_knownhost *host = NULL;
454 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
456 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
461 * A subject to figure out is what host name we need to pass in here.
462 * What host name does OpenSSH store in its file if an IDN name is
465 enum curl_khmatch keymatch;
466 curl_sshkeycallback func =
467 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
468 struct curl_khkey knownkey;
469 struct curl_khkey *knownkeyp = NULL;
470 struct curl_khkey foundkey;
473 case LIBSSH2_HOSTKEY_TYPE_RSA:
474 keybit = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
476 case LIBSSH2_HOSTKEY_TYPE_DSS:
477 keybit = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
479 #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256
480 case LIBSSH2_HOSTKEY_TYPE_ECDSA_256:
481 keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_256;
484 #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384
485 case LIBSSH2_HOSTKEY_TYPE_ECDSA_384:
486 keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_384;
489 #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521
490 case LIBSSH2_HOSTKEY_TYPE_ECDSA_521:
491 keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_521;
494 #ifdef LIBSSH2_HOSTKEY_TYPE_ED25519
495 case LIBSSH2_HOSTKEY_TYPE_ED25519:
496 keybit = LIBSSH2_KNOWNHOST_KEY_ED25519;
500 infof(data, "unsupported key type, can't check knownhosts");
505 /* no check means failure! */
506 rc = CURLKHSTAT_REJECT;
508 #ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
509 keycheck = libssh2_knownhost_checkp(sshc->kh,
511 (conn->remote_port != PORT_SSH)?
512 conn->remote_port:-1,
514 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
515 LIBSSH2_KNOWNHOST_KEYENC_RAW|
519 keycheck = libssh2_knownhost_check(sshc->kh,
522 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
523 LIBSSH2_KNOWNHOST_KEYENC_RAW|
528 infof(data, "SSH host check: %d, key: %s", keycheck,
529 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
532 /* setup 'knownkey' */
533 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
534 knownkey.key = host->key;
536 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
537 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
538 knownkeyp = &knownkey;
541 /* setup 'foundkey' */
542 foundkey.key = remotekey;
543 foundkey.len = keylen;
544 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
545 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
548 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
549 * curl_khmatch enum are ever modified, we need to introduce a
550 * translation table here!
552 keymatch = (enum curl_khmatch)keycheck;
554 /* Ask the callback how to behave */
555 Curl_set_in_callback(data, true);
556 rc = func(data, knownkeyp, /* from the knownhosts file */
557 &foundkey, /* from the remote host */
558 keymatch, data->set.ssh_keyfunc_userp);
559 Curl_set_in_callback(data, false);
563 /* no remotekey means failure! */
564 rc = CURLKHSTAT_REJECT;
567 default: /* unknown return codes will equal reject */
569 case CURLKHSTAT_REJECT:
570 state(data, SSH_SESSION_FREE);
572 case CURLKHSTAT_DEFER:
573 /* DEFER means bail out but keep the SSH_HOSTKEY state */
574 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
576 case CURLKHSTAT_FINE_REPLACE:
577 /* remove old host+key that doesn't match */
579 libssh2_knownhost_del(sshc->kh, host);
581 case CURLKHSTAT_FINE:
583 case CURLKHSTAT_FINE_ADD_TO_FILE:
585 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
586 /* the found host+key didn't match but has been told to be fine
587 anyway so we add it in memory */
588 int addrc = libssh2_knownhost_add(sshc->kh,
589 conn->host.name, NULL,
591 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
592 LIBSSH2_KNOWNHOST_KEYENC_RAW|
595 infof(data, "WARNING: adding the known host %s failed",
597 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE ||
598 rc == CURLKHSTAT_FINE_REPLACE) {
599 /* now we write the entire in-memory list of known hosts to the
602 libssh2_knownhost_writefile(sshc->kh,
603 data->set.str[STRING_SSH_KNOWNHOSTS],
604 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
606 infof(data, "WARNING: writing %s failed",
607 data->set.str[STRING_SSH_KNOWNHOSTS]);
614 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
620 static CURLcode ssh_check_fingerprint(struct Curl_easy *data)
622 struct connectdata *conn = data->conn;
623 struct ssh_conn *sshc = &conn->proto.sshc;
624 const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
625 const char *pubkey_sha256 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_SHA256];
627 infof(data, "SSH MD5 public key: %s",
628 pubkey_md5 != NULL ? pubkey_md5 : "NULL");
629 infof(data, "SSH SHA256 public key: %s",
630 pubkey_sha256 != NULL ? pubkey_sha256 : "NULL");
633 const char *fingerprint = NULL;
634 char *fingerprint_b64 = NULL;
635 size_t fingerprint_b64_len;
639 #ifdef LIBSSH2_HOSTKEY_HASH_SHA256
640 /* The fingerprint points to static storage (!), don't free() it. */
641 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
642 LIBSSH2_HOSTKEY_HASH_SHA256);
646 unsigned char hash[32];
648 hostkey = libssh2_session_hostkey(sshc->ssh_session, &len, NULL);
650 if(!Curl_sha256it(hash, (const unsigned char *) hostkey, len))
651 fingerprint = (char *) hash;
657 "Denied establishing ssh session: sha256 fingerprint "
659 state(data, SSH_SESSION_FREE);
660 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
661 return sshc->actualcode;
664 /* The length of fingerprint is 32 bytes for SHA256.
665 * See libssh2_hostkey_hash documentation. */
666 if(Curl_base64_encode(fingerprint, 32, &fingerprint_b64,
667 &fingerprint_b64_len) != CURLE_OK) {
668 state(data, SSH_SESSION_FREE);
669 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
670 return sshc->actualcode;
673 if(!fingerprint_b64) {
674 failf(data, "sha256 fingerprint could not be encoded");
675 state(data, SSH_SESSION_FREE);
676 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
677 return sshc->actualcode;
680 infof(data, "SSH SHA256 fingerprint: %s", fingerprint_b64);
682 /* Find the position of any = padding characters in the public key */
683 while((pubkey_sha256[pub_pos] != '=') && pubkey_sha256[pub_pos]) {
687 /* Find the position of any = padding characters in the base64 coded
688 * hostkey fingerprint */
689 while((fingerprint_b64[b64_pos] != '=') && fingerprint_b64[b64_pos]) {
693 /* Before we authenticate we check the hostkey's sha256 fingerprint
694 * against a known fingerprint, if available.
696 if((pub_pos != b64_pos) ||
697 strncmp(fingerprint_b64, pubkey_sha256, pub_pos)) {
698 free(fingerprint_b64);
701 "Denied establishing ssh session: mismatch sha256 fingerprint. "
702 "Remote %s is not equal to %s", fingerprint_b64, pubkey_sha256);
703 state(data, SSH_SESSION_FREE);
704 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
705 return sshc->actualcode;
708 free(fingerprint_b64);
710 infof(data, "SHA256 checksum match");
715 const char *fingerprint = NULL;
717 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
718 LIBSSH2_HOSTKEY_HASH_MD5);
721 /* The fingerprint points to static storage (!), don't free() it. */
723 for(i = 0; i < 16; i++) {
724 msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
727 infof(data, "SSH MD5 fingerprint: %s", md5buffer);
730 /* This does NOT verify the length of 'pubkey_md5' separately, which will
731 make the comparison below fail unless it is exactly 32 characters */
732 if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) {
735 "Denied establishing ssh session: mismatch md5 fingerprint. "
736 "Remote %s is not equal to %s", md5buffer, pubkey_md5);
740 "Denied establishing ssh session: md5 fingerprint "
743 state(data, SSH_SESSION_FREE);
744 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
745 return sshc->actualcode;
747 infof(data, "MD5 checksum match");
750 if(!pubkey_md5 && !pubkey_sha256) {
751 return ssh_knownhost(data);
754 /* as we already matched, we skip the check for known hosts */
760 * ssh_force_knownhost_key_type() will check the known hosts file and try to
761 * force a specific public key type from the server if an entry is found.
763 static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data)
765 CURLcode result = CURLE_OK;
767 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
769 #ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
770 static const char * const hostkey_method_ssh_ed25519
773 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
774 static const char * const hostkey_method_ssh_ecdsa_521
775 = "ecdsa-sha2-nistp521";
777 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
778 static const char * const hostkey_method_ssh_ecdsa_384
779 = "ecdsa-sha2-nistp384";
781 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
782 static const char * const hostkey_method_ssh_ecdsa_256
783 = "ecdsa-sha2-nistp256";
785 static const char * const hostkey_method_ssh_rsa
787 static const char * const hostkey_method_ssh_dss
790 const char *hostkey_method = NULL;
791 struct connectdata *conn = data->conn;
792 struct ssh_conn *sshc = &conn->proto.sshc;
793 struct libssh2_knownhost* store = NULL;
794 const char *kh_name_end = NULL;
795 size_t kh_name_size = 0;
799 if(sshc->kh && !data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) {
800 /* lets try to find our host in the known hosts file */
801 while(!libssh2_knownhost_get(sshc->kh, &store, store)) {
802 /* For non-standard ports, the name will be enclosed in */
803 /* square brackets, followed by a colon and the port */
806 if(store->name[0] == '[') {
807 kh_name_end = strstr(store->name, "]:");
809 infof(data, "Invalid host pattern %s in %s",
810 store->name, data->set.str[STRING_SSH_KNOWNHOSTS]);
813 port = atoi(kh_name_end + 2);
814 if(kh_name_end && (port == conn->remote_port)) {
815 kh_name_size = strlen(store->name) - 1 - strlen(kh_name_end);
816 if(strncmp(store->name + 1,
817 conn->host.name, kh_name_size) == 0) {
823 else if(strcmp(store->name, conn->host.name) == 0) {
836 infof(data, "Found host %s in %s",
837 conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]);
839 switch(store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) {
840 #ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
841 case LIBSSH2_KNOWNHOST_KEY_ED25519:
842 hostkey_method = hostkey_method_ssh_ed25519;
845 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
846 case LIBSSH2_KNOWNHOST_KEY_ECDSA_521:
847 hostkey_method = hostkey_method_ssh_ecdsa_521;
850 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
851 case LIBSSH2_KNOWNHOST_KEY_ECDSA_384:
852 hostkey_method = hostkey_method_ssh_ecdsa_384;
855 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
856 case LIBSSH2_KNOWNHOST_KEY_ECDSA_256:
857 hostkey_method = hostkey_method_ssh_ecdsa_256;
860 case LIBSSH2_KNOWNHOST_KEY_SSHRSA:
861 hostkey_method = hostkey_method_ssh_rsa;
863 case LIBSSH2_KNOWNHOST_KEY_SSHDSS:
864 hostkey_method = hostkey_method_ssh_dss;
866 case LIBSSH2_KNOWNHOST_KEY_RSA1:
867 failf(data, "Found host key type RSA1 which is not supported");
870 failf(data, "Unknown host key type: %i",
871 (store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK));
875 infof(data, "Set \"%s\" as SSH hostkey type", hostkey_method);
876 result = libssh2_session_error_to_CURLE(
877 libssh2_session_method_pref(
878 sshc->ssh_session, LIBSSH2_METHOD_HOSTKEY, hostkey_method));
881 infof(data, "Did not find host %s in %s",
882 conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]);
886 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
892 * ssh_statemach_act() runs the SSH state machine as far as it can without
893 * blocking and without reaching the end. The data the pointer 'block' points
894 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
895 * meaning it wants to be called again when the socket is ready
898 static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
900 CURLcode result = CURLE_OK;
901 struct connectdata *conn = data->conn;
902 struct SSHPROTO *sshp = data->req.p.ssh;
903 struct ssh_conn *sshc = &conn->proto.sshc;
904 curl_socket_t sock = conn->sock[FIRSTSOCKET];
905 int rc = LIBSSH2_ERROR_NONE;
907 unsigned long sftperr;
908 int seekerr = CURL_SEEKFUNC_OK;
910 *block = 0; /* we're not blocking by default */
913 switch(sshc->state) {
915 sshc->secondCreateDirs = 0;
916 sshc->nextstate = SSH_NO_STATE;
917 sshc->actualcode = CURLE_OK;
919 /* Set libssh2 to non-blocking, since everything internally is
921 libssh2_session_set_blocking(sshc->ssh_session, 0);
923 result = ssh_force_knownhost_key_type(data);
925 state(data, SSH_SESSION_FREE);
926 sshc->actualcode = result;
930 state(data, SSH_S_STARTUP);
934 rc = session_startup(sshc->ssh_session, sock);
935 if(rc == LIBSSH2_ERROR_EAGAIN) {
939 char *err_msg = NULL;
940 (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
941 failf(data, "Failure establishing ssh session: %d, %s", rc, err_msg);
943 state(data, SSH_SESSION_FREE);
944 sshc->actualcode = CURLE_FAILED_INIT;
948 state(data, SSH_HOSTKEY);
953 * Before we authenticate we should check the hostkey's fingerprint
954 * against our known hosts. How that is handled (reading from file,
955 * whatever) is up to us.
957 result = ssh_check_fingerprint(data);
959 state(data, SSH_AUTHLIST);
960 /* ssh_check_fingerprint sets state appropriately on error */
965 * Figure out authentication methods
966 * NB: As soon as we have provided a username to an openssh server we
967 * must never change it later. Thus, always specify the correct username
968 * here, even though the libssh2 docs kind of indicate that it should be
969 * possible to get a 'generic' list (not user-specific) of authentication
970 * methods, presumably with a blank username. That won't work in my
972 * So always specify it here.
974 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
976 curlx_uztoui(strlen(conn->user)));
978 if(!sshc->authlist) {
979 if(libssh2_userauth_authenticated(sshc->ssh_session)) {
981 infof(data, "SSH user accepted with no authentication");
982 state(data, SSH_AUTH_DONE);
985 ssherr = libssh2_session_last_errno(sshc->ssh_session);
986 if(ssherr == LIBSSH2_ERROR_EAGAIN)
987 rc = LIBSSH2_ERROR_EAGAIN;
989 state(data, SSH_SESSION_FREE);
990 sshc->actualcode = libssh2_session_error_to_CURLE(ssherr);
994 infof(data, "SSH authentication methods available: %s",
997 state(data, SSH_AUTH_PKEY_INIT);
1000 case SSH_AUTH_PKEY_INIT:
1002 * Check the supported auth types in the order I feel is most secure
1003 * with the requested type of authentication
1005 sshc->authed = FALSE;
1007 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
1008 (strstr(sshc->authlist, "publickey") != NULL)) {
1009 bool out_of_memory = FALSE;
1011 sshc->rsa_pub = sshc->rsa = NULL;
1013 if(data->set.str[STRING_SSH_PRIVATE_KEY])
1014 sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
1016 /* To ponder about: should really the lib be messing about with the
1017 HOME environment variable etc? */
1018 char *home = curl_getenv("HOME");
1020 /* If no private key file is specified, try some common paths. */
1022 /* Try ~/.ssh first. */
1023 sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
1025 out_of_memory = TRUE;
1026 else if(access(sshc->rsa, R_OK) != 0) {
1027 Curl_safefree(sshc->rsa);
1028 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
1030 out_of_memory = TRUE;
1031 else if(access(sshc->rsa, R_OK) != 0) {
1032 Curl_safefree(sshc->rsa);
1037 if(!out_of_memory && !sshc->rsa) {
1038 /* Nothing found; try the current dir. */
1039 sshc->rsa = strdup("id_rsa");
1040 if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
1041 Curl_safefree(sshc->rsa);
1042 sshc->rsa = strdup("id_dsa");
1043 if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
1044 Curl_safefree(sshc->rsa);
1045 /* Out of guesses. Set to the empty string to avoid
1046 * surprising info messages. */
1047 sshc->rsa = strdup("");
1054 * Unless the user explicitly specifies a public key file, let
1055 * libssh2 extract the public key from the private key file.
1056 * This is done by simply passing sshc->rsa_pub = NULL.
1058 if(data->set.str[STRING_SSH_PUBLIC_KEY]
1059 /* treat empty string the same way as NULL */
1060 && data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
1061 sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
1063 out_of_memory = TRUE;
1066 if(out_of_memory || !sshc->rsa) {
1067 Curl_safefree(sshc->rsa);
1068 Curl_safefree(sshc->rsa_pub);
1069 state(data, SSH_SESSION_FREE);
1070 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1074 sshc->passphrase = data->set.ssl.key_passwd;
1075 if(!sshc->passphrase)
1076 sshc->passphrase = "";
1079 infof(data, "Using SSH public key file '%s'", sshc->rsa_pub);
1080 infof(data, "Using SSH private key file '%s'", sshc->rsa);
1082 state(data, SSH_AUTH_PKEY);
1085 state(data, SSH_AUTH_PASS_INIT);
1090 /* The function below checks if the files exists, no need to stat() here.
1092 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
1095 strlen(conn->user)),
1097 sshc->rsa, sshc->passphrase);
1098 if(rc == LIBSSH2_ERROR_EAGAIN) {
1102 Curl_safefree(sshc->rsa_pub);
1103 Curl_safefree(sshc->rsa);
1106 sshc->authed = TRUE;
1107 infof(data, "Initialized SSH public key authentication");
1108 state(data, SSH_AUTH_DONE);
1111 char *err_msg = NULL;
1112 (void)libssh2_session_last_error(sshc->ssh_session,
1114 infof(data, "SSH public key authentication failed: %s", err_msg);
1115 state(data, SSH_AUTH_PASS_INIT);
1116 rc = 0; /* clear rc and continue */
1120 case SSH_AUTH_PASS_INIT:
1121 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
1122 (strstr(sshc->authlist, "password") != NULL)) {
1123 state(data, SSH_AUTH_PASS);
1126 state(data, SSH_AUTH_HOST_INIT);
1127 rc = 0; /* clear rc and continue */
1132 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
1133 curlx_uztoui(strlen(conn->user)),
1135 curlx_uztoui(strlen(conn->passwd)),
1137 if(rc == LIBSSH2_ERROR_EAGAIN) {
1141 sshc->authed = TRUE;
1142 infof(data, "Initialized password authentication");
1143 state(data, SSH_AUTH_DONE);
1146 state(data, SSH_AUTH_HOST_INIT);
1147 rc = 0; /* clear rc and continue */
1151 case SSH_AUTH_HOST_INIT:
1152 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
1153 (strstr(sshc->authlist, "hostbased") != NULL)) {
1154 state(data, SSH_AUTH_HOST);
1157 state(data, SSH_AUTH_AGENT_INIT);
1162 state(data, SSH_AUTH_AGENT_INIT);
1165 case SSH_AUTH_AGENT_INIT:
1166 #ifdef HAVE_LIBSSH2_AGENT_API
1167 if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
1168 && (strstr(sshc->authlist, "publickey") != NULL)) {
1170 /* Connect to the ssh-agent */
1171 /* The agent could be shared by a curl thread i believe
1172 but nothing obvious as keys can be added/removed at any time */
1173 if(!sshc->ssh_agent) {
1174 sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
1175 if(!sshc->ssh_agent) {
1176 infof(data, "Could not create agent object");
1178 state(data, SSH_AUTH_KEY_INIT);
1183 rc = libssh2_agent_connect(sshc->ssh_agent);
1184 if(rc == LIBSSH2_ERROR_EAGAIN)
1187 infof(data, "Failure connecting to agent");
1188 state(data, SSH_AUTH_KEY_INIT);
1189 rc = 0; /* clear rc and continue */
1192 state(data, SSH_AUTH_AGENT_LIST);
1196 #endif /* HAVE_LIBSSH2_AGENT_API */
1197 state(data, SSH_AUTH_KEY_INIT);
1200 case SSH_AUTH_AGENT_LIST:
1201 #ifdef HAVE_LIBSSH2_AGENT_API
1202 rc = libssh2_agent_list_identities(sshc->ssh_agent);
1204 if(rc == LIBSSH2_ERROR_EAGAIN)
1207 infof(data, "Failure requesting identities to agent");
1208 state(data, SSH_AUTH_KEY_INIT);
1209 rc = 0; /* clear rc and continue */
1212 state(data, SSH_AUTH_AGENT);
1213 sshc->sshagent_prev_identity = NULL;
1218 case SSH_AUTH_AGENT:
1219 #ifdef HAVE_LIBSSH2_AGENT_API
1220 /* as prev_identity evolves only after an identity user auth finished we
1221 can safely request it again as long as EAGAIN is returned here or by
1222 libssh2_agent_userauth */
1223 rc = libssh2_agent_get_identity(sshc->ssh_agent,
1224 &sshc->sshagent_identity,
1225 sshc->sshagent_prev_identity);
1226 if(rc == LIBSSH2_ERROR_EAGAIN)
1230 rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
1231 sshc->sshagent_identity);
1234 if(rc != LIBSSH2_ERROR_EAGAIN) {
1235 /* tried and failed? go to next identity */
1236 sshc->sshagent_prev_identity = sshc->sshagent_identity;
1243 infof(data, "Failure requesting identities to agent");
1245 infof(data, "No identity would match");
1247 if(rc == LIBSSH2_ERROR_NONE) {
1248 sshc->authed = TRUE;
1249 infof(data, "Agent based authentication successful");
1250 state(data, SSH_AUTH_DONE);
1253 state(data, SSH_AUTH_KEY_INIT);
1254 rc = 0; /* clear rc and continue */
1259 case SSH_AUTH_KEY_INIT:
1260 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
1261 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
1262 state(data, SSH_AUTH_KEY);
1265 state(data, SSH_AUTH_DONE);
1270 /* Authentication failed. Continue with keyboard-interactive now. */
1271 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
1274 strlen(conn->user)),
1276 if(rc == LIBSSH2_ERROR_EAGAIN) {
1280 sshc->authed = TRUE;
1281 infof(data, "Initialized keyboard interactive authentication");
1283 state(data, SSH_AUTH_DONE);
1288 failf(data, "Authentication failure");
1289 state(data, SSH_SESSION_FREE);
1290 sshc->actualcode = CURLE_LOGIN_DENIED;
1295 * At this point we have an authenticated ssh session.
1297 infof(data, "Authentication complete");
1299 Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */
1301 conn->sockfd = sock;
1302 conn->writesockfd = CURL_SOCKET_BAD;
1304 if(conn->handler->protocol == CURLPROTO_SFTP) {
1305 state(data, SSH_SFTP_INIT);
1308 infof(data, "SSH CONNECT phase done");
1309 state(data, SSH_STOP);
1314 * Start the libssh2 sftp session
1316 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
1317 if(!sshc->sftp_session) {
1318 char *err_msg = NULL;
1319 if(libssh2_session_last_errno(sshc->ssh_session) ==
1320 LIBSSH2_ERROR_EAGAIN) {
1321 rc = LIBSSH2_ERROR_EAGAIN;
1325 (void)libssh2_session_last_error(sshc->ssh_session,
1327 failf(data, "Failure initializing sftp session: %s", err_msg);
1328 state(data, SSH_SESSION_FREE);
1329 sshc->actualcode = CURLE_FAILED_INIT;
1332 state(data, SSH_SFTP_REALPATH);
1335 case SSH_SFTP_REALPATH:
1337 char tempHome[PATH_MAX];
1340 * Get the "home" directory
1342 rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
1343 tempHome, PATH_MAX-1);
1344 if(rc == LIBSSH2_ERROR_EAGAIN) {
1348 /* It seems that this string is not always NULL terminated */
1349 tempHome[rc] = '\0';
1350 sshc->homedir = strdup(tempHome);
1351 if(!sshc->homedir) {
1352 state(data, SSH_SFTP_CLOSE);
1353 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1356 data->state.most_recent_ftp_entrypath = sshc->homedir;
1359 /* Return the error type */
1360 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1362 result = sftp_libssh2_error_to_CURLE(sftperr);
1364 /* in this case, the error wasn't in the SFTP level but for example
1365 a time-out or similar */
1367 sshc->actualcode = result;
1368 DEBUGF(infof(data, "error = %lu makes libcurl = %d",
1369 sftperr, (int)result));
1370 state(data, SSH_STOP);
1374 /* This is the last step in the SFTP connect phase. Do note that while
1375 we get the homedir here, we get the "workingpath" in the DO action
1376 since the homedir will remain the same between request but the
1377 working path will not. */
1378 DEBUGF(infof(data, "SSH CONNECT phase done"));
1379 state(data, SSH_STOP);
1382 case SSH_SFTP_QUOTE_INIT:
1384 result = Curl_getworkingpath(data, sshc->homedir, &sshp->path);
1386 sshc->actualcode = result;
1387 state(data, SSH_STOP);
1391 if(data->set.quote) {
1392 infof(data, "Sending quote commands");
1393 sshc->quote_item = data->set.quote;
1394 state(data, SSH_SFTP_QUOTE);
1397 state(data, SSH_SFTP_GETINFO);
1401 case SSH_SFTP_POSTQUOTE_INIT:
1402 if(data->set.postquote) {
1403 infof(data, "Sending quote commands");
1404 sshc->quote_item = data->set.postquote;
1405 state(data, SSH_SFTP_QUOTE);
1408 state(data, SSH_STOP);
1412 case SSH_SFTP_QUOTE:
1413 /* Send any quote commands */
1418 * Support some of the "FTP" commands
1420 * 'sshc->quote_item' is already verified to be non-NULL before it
1421 * switched to this state.
1423 char *cmd = sshc->quote_item->data;
1424 sshc->acceptfail = FALSE;
1426 /* if a command starts with an asterisk, which a legal SFTP command never
1427 can, the command will be allowed to fail without it causing any
1428 aborts or cancels etc. It will cause libcurl to act as if the command
1429 is successful, whatever the server reponds. */
1433 sshc->acceptfail = TRUE;
1436 if(strcasecompare("pwd", cmd)) {
1437 /* output debug output if that is requested */
1438 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1441 result = CURLE_OUT_OF_MEMORY;
1442 state(data, SSH_SFTP_CLOSE);
1443 sshc->nextstate = SSH_NO_STATE;
1446 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
1447 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
1449 /* this sends an FTP-like "header" to the header callback so that the
1450 current directory can be read very similar to how it is read when
1451 using ordinary FTP. */
1452 result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1455 state(data, SSH_SFTP_CLOSE);
1456 sshc->nextstate = SSH_NO_STATE;
1457 sshc->actualcode = result;
1460 state(data, SSH_SFTP_NEXT_QUOTE);
1465 * the arguments following the command must be separated from the
1466 * command with a space so we can check for it unconditionally
1468 cp = strchr(cmd, ' ');
1470 failf(data, "Syntax error command '%s', missing parameter",
1472 state(data, SSH_SFTP_CLOSE);
1473 sshc->nextstate = SSH_NO_STATE;
1474 sshc->actualcode = CURLE_QUOTE_ERROR;
1479 * also, every command takes at least one argument so we get that
1480 * first argument right now
1482 result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
1484 if(result == CURLE_OUT_OF_MEMORY)
1485 failf(data, "Out of memory");
1487 failf(data, "Syntax error: Bad first parameter to '%s'", cmd);
1488 state(data, SSH_SFTP_CLOSE);
1489 sshc->nextstate = SSH_NO_STATE;
1490 sshc->actualcode = result;
1495 * SFTP is a binary protocol, so we don't send text commands
1496 * to the server. Instead, we scan for commands used by
1497 * OpenSSH's sftp program and call the appropriate libssh2
1500 if(strncasecompare(cmd, "chgrp ", 6) ||
1501 strncasecompare(cmd, "chmod ", 6) ||
1502 strncasecompare(cmd, "chown ", 6) ||
1503 strncasecompare(cmd, "atime ", 6) ||
1504 strncasecompare(cmd, "mtime ", 6)) {
1505 /* attribute change */
1507 /* sshc->quote_path1 contains the mode to set */
1508 /* get the destination */
1509 result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
1511 if(result == CURLE_OUT_OF_MEMORY)
1512 failf(data, "Out of memory");
1514 failf(data, "Syntax error in %s: Bad second parameter", cmd);
1515 Curl_safefree(sshc->quote_path1);
1516 state(data, SSH_SFTP_CLOSE);
1517 sshc->nextstate = SSH_NO_STATE;
1518 sshc->actualcode = result;
1521 memset(&sshp->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1522 state(data, SSH_SFTP_QUOTE_STAT);
1525 if(strncasecompare(cmd, "ln ", 3) ||
1526 strncasecompare(cmd, "symlink ", 8)) {
1527 /* symbolic linking */
1528 /* sshc->quote_path1 is the source */
1529 /* get the destination */
1530 result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
1532 if(result == CURLE_OUT_OF_MEMORY)
1533 failf(data, "Out of memory");
1536 "Syntax error in ln/symlink: Bad second parameter");
1537 Curl_safefree(sshc->quote_path1);
1538 state(data, SSH_SFTP_CLOSE);
1539 sshc->nextstate = SSH_NO_STATE;
1540 sshc->actualcode = result;
1543 state(data, SSH_SFTP_QUOTE_SYMLINK);
1546 else if(strncasecompare(cmd, "mkdir ", 6)) {
1548 state(data, SSH_SFTP_QUOTE_MKDIR);
1551 else if(strncasecompare(cmd, "rename ", 7)) {
1553 /* first param is the source path */
1554 /* second param is the dest. path */
1555 result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
1557 if(result == CURLE_OUT_OF_MEMORY)
1558 failf(data, "Out of memory");
1560 failf(data, "Syntax error in rename: Bad second parameter");
1561 Curl_safefree(sshc->quote_path1);
1562 state(data, SSH_SFTP_CLOSE);
1563 sshc->nextstate = SSH_NO_STATE;
1564 sshc->actualcode = result;
1567 state(data, SSH_SFTP_QUOTE_RENAME);
1570 else if(strncasecompare(cmd, "rmdir ", 6)) {
1572 state(data, SSH_SFTP_QUOTE_RMDIR);
1575 else if(strncasecompare(cmd, "rm ", 3)) {
1576 state(data, SSH_SFTP_QUOTE_UNLINK);
1579 #ifdef HAS_STATVFS_SUPPORT
1580 else if(strncasecompare(cmd, "statvfs ", 8)) {
1581 state(data, SSH_SFTP_QUOTE_STATVFS);
1586 failf(data, "Unknown SFTP command");
1587 Curl_safefree(sshc->quote_path1);
1588 Curl_safefree(sshc->quote_path2);
1589 state(data, SSH_SFTP_CLOSE);
1590 sshc->nextstate = SSH_NO_STATE;
1591 sshc->actualcode = CURLE_QUOTE_ERROR;
1597 case SSH_SFTP_NEXT_QUOTE:
1598 Curl_safefree(sshc->quote_path1);
1599 Curl_safefree(sshc->quote_path2);
1601 sshc->quote_item = sshc->quote_item->next;
1603 if(sshc->quote_item) {
1604 state(data, SSH_SFTP_QUOTE);
1607 if(sshc->nextstate != SSH_NO_STATE) {
1608 state(data, sshc->nextstate);
1609 sshc->nextstate = SSH_NO_STATE;
1612 state(data, SSH_SFTP_GETINFO);
1617 case SSH_SFTP_QUOTE_STAT:
1619 char *cmd = sshc->quote_item->data;
1620 sshc->acceptfail = FALSE;
1622 /* if a command starts with an asterisk, which a legal SFTP command never
1623 can, the command will be allowed to fail without it causing any
1624 aborts or cancels etc. It will cause libcurl to act as if the command
1625 is successful, whatever the server reponds. */
1629 sshc->acceptfail = TRUE;
1632 if(!strncasecompare(cmd, "chmod", 5)) {
1633 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1634 * set them both at once, we need to obtain the current ownership
1635 * first. This takes an extra protocol round trip.
1637 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1638 curlx_uztoui(strlen(sshc->quote_path2)),
1640 &sshp->quote_attrs);
1641 if(rc == LIBSSH2_ERROR_EAGAIN) {
1644 if(rc && !sshc->acceptfail) { /* get those attributes */
1645 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1646 Curl_safefree(sshc->quote_path1);
1647 Curl_safefree(sshc->quote_path2);
1648 failf(data, "Attempt to get SFTP stats failed: %s",
1649 sftp_libssh2_strerror(sftperr));
1650 state(data, SSH_SFTP_CLOSE);
1651 sshc->nextstate = SSH_NO_STATE;
1652 sshc->actualcode = CURLE_QUOTE_ERROR;
1657 /* Now set the new attributes... */
1658 if(strncasecompare(cmd, "chgrp", 5)) {
1659 sshp->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1660 sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1661 if(sshp->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1662 !sshc->acceptfail) {
1663 Curl_safefree(sshc->quote_path1);
1664 Curl_safefree(sshc->quote_path2);
1665 failf(data, "Syntax error: chgrp gid not a number");
1666 state(data, SSH_SFTP_CLOSE);
1667 sshc->nextstate = SSH_NO_STATE;
1668 sshc->actualcode = CURLE_QUOTE_ERROR;
1672 else if(strncasecompare(cmd, "chmod", 5)) {
1673 sshp->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1674 sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1675 /* permissions are octal */
1676 if(sshp->quote_attrs.permissions == 0 &&
1677 !ISDIGIT(sshc->quote_path1[0])) {
1678 Curl_safefree(sshc->quote_path1);
1679 Curl_safefree(sshc->quote_path2);
1680 failf(data, "Syntax error: chmod permissions not a number");
1681 state(data, SSH_SFTP_CLOSE);
1682 sshc->nextstate = SSH_NO_STATE;
1683 sshc->actualcode = CURLE_QUOTE_ERROR;
1687 else if(strncasecompare(cmd, "chown", 5)) {
1688 sshp->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1689 sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1690 if(sshp->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1691 !sshc->acceptfail) {
1692 Curl_safefree(sshc->quote_path1);
1693 Curl_safefree(sshc->quote_path2);
1694 failf(data, "Syntax error: chown uid not a number");
1695 state(data, SSH_SFTP_CLOSE);
1696 sshc->nextstate = SSH_NO_STATE;
1697 sshc->actualcode = CURLE_QUOTE_ERROR;
1701 else if(strncasecompare(cmd, "atime", 5)) {
1702 time_t date = Curl_getdate_capped(sshc->quote_path1);
1704 Curl_safefree(sshc->quote_path1);
1705 Curl_safefree(sshc->quote_path2);
1706 failf(data, "Syntax error: incorrect access date format");
1707 state(data, SSH_SFTP_CLOSE);
1708 sshc->nextstate = SSH_NO_STATE;
1709 sshc->actualcode = CURLE_QUOTE_ERROR;
1712 sshp->quote_attrs.atime = (unsigned long)date;
1713 sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME;
1715 else if(strncasecompare(cmd, "mtime", 5)) {
1716 time_t date = Curl_getdate_capped(sshc->quote_path1);
1718 Curl_safefree(sshc->quote_path1);
1719 Curl_safefree(sshc->quote_path2);
1720 failf(data, "Syntax error: incorrect modification date format");
1721 state(data, SSH_SFTP_CLOSE);
1722 sshc->nextstate = SSH_NO_STATE;
1723 sshc->actualcode = CURLE_QUOTE_ERROR;
1726 sshp->quote_attrs.mtime = (unsigned long)date;
1727 sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME;
1730 /* Now send the completed structure... */
1731 state(data, SSH_SFTP_QUOTE_SETSTAT);
1735 case SSH_SFTP_QUOTE_SETSTAT:
1736 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1737 curlx_uztoui(strlen(sshc->quote_path2)),
1738 LIBSSH2_SFTP_SETSTAT,
1739 &sshp->quote_attrs);
1740 if(rc == LIBSSH2_ERROR_EAGAIN) {
1743 if(rc && !sshc->acceptfail) {
1744 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1745 Curl_safefree(sshc->quote_path1);
1746 Curl_safefree(sshc->quote_path2);
1747 failf(data, "Attempt to set SFTP stats failed: %s",
1748 sftp_libssh2_strerror(sftperr));
1749 state(data, SSH_SFTP_CLOSE);
1750 sshc->nextstate = SSH_NO_STATE;
1751 sshc->actualcode = CURLE_QUOTE_ERROR;
1754 state(data, SSH_SFTP_NEXT_QUOTE);
1757 case SSH_SFTP_QUOTE_SYMLINK:
1758 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1759 curlx_uztoui(strlen(sshc->quote_path1)),
1761 curlx_uztoui(strlen(sshc->quote_path2)),
1762 LIBSSH2_SFTP_SYMLINK);
1763 if(rc == LIBSSH2_ERROR_EAGAIN) {
1766 if(rc && !sshc->acceptfail) {
1767 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1768 Curl_safefree(sshc->quote_path1);
1769 Curl_safefree(sshc->quote_path2);
1770 failf(data, "symlink command failed: %s",
1771 sftp_libssh2_strerror(sftperr));
1772 state(data, SSH_SFTP_CLOSE);
1773 sshc->nextstate = SSH_NO_STATE;
1774 sshc->actualcode = CURLE_QUOTE_ERROR;
1777 state(data, SSH_SFTP_NEXT_QUOTE);
1780 case SSH_SFTP_QUOTE_MKDIR:
1781 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1782 curlx_uztoui(strlen(sshc->quote_path1)),
1783 data->set.new_directory_perms);
1784 if(rc == LIBSSH2_ERROR_EAGAIN) {
1787 if(rc && !sshc->acceptfail) {
1788 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1789 Curl_safefree(sshc->quote_path1);
1790 failf(data, "mkdir command failed: %s",
1791 sftp_libssh2_strerror(sftperr));
1792 state(data, SSH_SFTP_CLOSE);
1793 sshc->nextstate = SSH_NO_STATE;
1794 sshc->actualcode = CURLE_QUOTE_ERROR;
1797 state(data, SSH_SFTP_NEXT_QUOTE);
1800 case SSH_SFTP_QUOTE_RENAME:
1801 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1802 curlx_uztoui(strlen(sshc->quote_path1)),
1804 curlx_uztoui(strlen(sshc->quote_path2)),
1805 LIBSSH2_SFTP_RENAME_OVERWRITE |
1806 LIBSSH2_SFTP_RENAME_ATOMIC |
1807 LIBSSH2_SFTP_RENAME_NATIVE);
1809 if(rc == LIBSSH2_ERROR_EAGAIN) {
1812 if(rc && !sshc->acceptfail) {
1813 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1814 Curl_safefree(sshc->quote_path1);
1815 Curl_safefree(sshc->quote_path2);
1816 failf(data, "rename command failed: %s",
1817 sftp_libssh2_strerror(sftperr));
1818 state(data, SSH_SFTP_CLOSE);
1819 sshc->nextstate = SSH_NO_STATE;
1820 sshc->actualcode = CURLE_QUOTE_ERROR;
1823 state(data, SSH_SFTP_NEXT_QUOTE);
1826 case SSH_SFTP_QUOTE_RMDIR:
1827 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1828 curlx_uztoui(strlen(sshc->quote_path1)));
1829 if(rc == LIBSSH2_ERROR_EAGAIN) {
1832 if(rc && !sshc->acceptfail) {
1833 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1834 Curl_safefree(sshc->quote_path1);
1835 failf(data, "rmdir command failed: %s",
1836 sftp_libssh2_strerror(sftperr));
1837 state(data, SSH_SFTP_CLOSE);
1838 sshc->nextstate = SSH_NO_STATE;
1839 sshc->actualcode = CURLE_QUOTE_ERROR;
1842 state(data, SSH_SFTP_NEXT_QUOTE);
1845 case SSH_SFTP_QUOTE_UNLINK:
1846 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1847 curlx_uztoui(strlen(sshc->quote_path1)));
1848 if(rc == LIBSSH2_ERROR_EAGAIN) {
1851 if(rc && !sshc->acceptfail) {
1852 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1853 Curl_safefree(sshc->quote_path1);
1854 failf(data, "rm command failed: %s", sftp_libssh2_strerror(sftperr));
1855 state(data, SSH_SFTP_CLOSE);
1856 sshc->nextstate = SSH_NO_STATE;
1857 sshc->actualcode = CURLE_QUOTE_ERROR;
1860 state(data, SSH_SFTP_NEXT_QUOTE);
1863 #ifdef HAS_STATVFS_SUPPORT
1864 case SSH_SFTP_QUOTE_STATVFS:
1866 LIBSSH2_SFTP_STATVFS statvfs;
1867 rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1,
1868 curlx_uztoui(strlen(sshc->quote_path1)),
1871 if(rc == LIBSSH2_ERROR_EAGAIN) {
1874 if(rc && !sshc->acceptfail) {
1875 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
1876 Curl_safefree(sshc->quote_path1);
1877 failf(data, "statvfs command failed: %s",
1878 sftp_libssh2_strerror(sftperr));
1879 state(data, SSH_SFTP_CLOSE);
1880 sshc->nextstate = SSH_NO_STATE;
1881 sshc->actualcode = CURLE_QUOTE_ERROR;
1885 char *tmp = aprintf("statvfs:\n"
1886 "f_bsize: %llu\n" "f_frsize: %llu\n"
1887 "f_blocks: %llu\n" "f_bfree: %llu\n"
1888 "f_bavail: %llu\n" "f_files: %llu\n"
1889 "f_ffree: %llu\n" "f_favail: %llu\n"
1890 "f_fsid: %llu\n" "f_flag: %llu\n"
1891 "f_namemax: %llu\n",
1892 statvfs.f_bsize, statvfs.f_frsize,
1893 statvfs.f_blocks, statvfs.f_bfree,
1894 statvfs.f_bavail, statvfs.f_files,
1895 statvfs.f_ffree, statvfs.f_favail,
1896 statvfs.f_fsid, statvfs.f_flag,
1899 result = CURLE_OUT_OF_MEMORY;
1900 state(data, SSH_SFTP_CLOSE);
1901 sshc->nextstate = SSH_NO_STATE;
1905 result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1908 state(data, SSH_SFTP_CLOSE);
1909 sshc->nextstate = SSH_NO_STATE;
1910 sshc->actualcode = result;
1913 state(data, SSH_SFTP_NEXT_QUOTE);
1917 case SSH_SFTP_GETINFO:
1919 if(data->set.get_filetime) {
1920 state(data, SSH_SFTP_FILETIME);
1923 state(data, SSH_SFTP_TRANS_INIT);
1928 case SSH_SFTP_FILETIME:
1930 LIBSSH2_SFTP_ATTRIBUTES attrs;
1932 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path,
1933 curlx_uztoui(strlen(sshp->path)),
1934 LIBSSH2_SFTP_STAT, &attrs);
1935 if(rc == LIBSSH2_ERROR_EAGAIN) {
1939 data->info.filetime = attrs.mtime;
1942 state(data, SSH_SFTP_TRANS_INIT);
1946 case SSH_SFTP_TRANS_INIT:
1947 if(data->set.upload)
1948 state(data, SSH_SFTP_UPLOAD_INIT);
1950 if(sshp->path[strlen(sshp->path)-1] == '/')
1951 state(data, SSH_SFTP_READDIR_INIT);
1953 state(data, SSH_SFTP_DOWNLOAD_INIT);
1957 case SSH_SFTP_UPLOAD_INIT:
1959 unsigned long flags;
1961 * NOTE!!! libssh2 requires that the destination path is a full path
1962 * that includes the destination file and name OR ends in a "/"
1963 * If this is not done the destination file will be named the
1964 * same name as the last directory in the path.
1967 if(data->state.resume_from) {
1968 LIBSSH2_SFTP_ATTRIBUTES attrs;
1969 if(data->state.resume_from < 0) {
1970 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path,
1971 curlx_uztoui(strlen(sshp->path)),
1972 LIBSSH2_SFTP_STAT, &attrs);
1973 if(rc == LIBSSH2_ERROR_EAGAIN) {
1977 data->state.resume_from = 0;
1980 curl_off_t size = attrs.filesize;
1982 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
1983 return CURLE_BAD_DOWNLOAD_RESUME;
1985 data->state.resume_from = attrs.filesize;
1990 if(data->set.remote_append)
1991 /* Try to open for append, but create if nonexisting */
1992 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1993 else if(data->state.resume_from > 0)
1994 /* If we have restart position then open for append */
1995 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1997 /* Clear file before writing (normal behavior) */
1998 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
2001 libssh2_sftp_open_ex(sshc->sftp_session, sshp->path,
2002 curlx_uztoui(strlen(sshp->path)),
2003 flags, data->set.new_file_perms,
2004 LIBSSH2_SFTP_OPENFILE);
2006 if(!sshc->sftp_handle) {
2007 rc = libssh2_session_last_errno(sshc->ssh_session);
2009 if(LIBSSH2_ERROR_EAGAIN == rc)
2012 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
2013 /* only when there was an SFTP protocol error can we extract
2015 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2017 sftperr = LIBSSH2_FX_OK; /* not an sftp error at all */
2019 if(sshc->secondCreateDirs) {
2020 state(data, SSH_SFTP_CLOSE);
2021 sshc->actualcode = sftperr != LIBSSH2_FX_OK ?
2022 sftp_libssh2_error_to_CURLE(sftperr):CURLE_SSH;
2023 failf(data, "Creating the dir/file failed: %s",
2024 sftp_libssh2_strerror(sftperr));
2027 if(((sftperr == LIBSSH2_FX_NO_SUCH_FILE) ||
2028 (sftperr == LIBSSH2_FX_FAILURE) ||
2029 (sftperr == LIBSSH2_FX_NO_SUCH_PATH)) &&
2030 (data->set.ftp_create_missing_dirs &&
2031 (strlen(sshp->path) > 1))) {
2032 /* try to create the path remotely */
2033 rc = 0; /* clear rc and continue */
2034 sshc->secondCreateDirs = 1;
2035 state(data, SSH_SFTP_CREATE_DIRS_INIT);
2038 state(data, SSH_SFTP_CLOSE);
2039 sshc->actualcode = sftperr != LIBSSH2_FX_OK ?
2040 sftp_libssh2_error_to_CURLE(sftperr):CURLE_SSH;
2041 if(!sshc->actualcode) {
2042 /* Sometimes, for some reason libssh2_sftp_last_error() returns zero
2043 even though libssh2_sftp_open() failed previously! We need to
2044 work around that! */
2045 sshc->actualcode = CURLE_SSH;
2046 sftperr = LIBSSH2_FX_OK;
2048 failf(data, "Upload failed: %s (%lu/%d)",
2049 sftperr != LIBSSH2_FX_OK ?
2050 sftp_libssh2_strerror(sftperr):"ssh error",
2055 /* If we have a restart point then we need to seek to the correct
2057 if(data->state.resume_from > 0) {
2058 /* Let's read off the proper amount of bytes from the input. */
2059 if(conn->seek_func) {
2060 Curl_set_in_callback(data, true);
2061 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
2063 Curl_set_in_callback(data, false);
2066 if(seekerr != CURL_SEEKFUNC_OK) {
2067 curl_off_t passed = 0;
2069 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2070 failf(data, "Could not seek stream");
2071 return CURLE_FTP_COULDNT_USE_REST;
2073 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
2075 size_t readthisamountnow =
2076 (data->state.resume_from - passed > data->set.buffer_size) ?
2077 (size_t)data->set.buffer_size :
2078 curlx_sotouz(data->state.resume_from - passed);
2080 size_t actuallyread;
2081 Curl_set_in_callback(data, true);
2082 actuallyread = data->state.fread_func(data->state.buffer, 1,
2085 Curl_set_in_callback(data, false);
2087 passed += actuallyread;
2088 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2089 /* this checks for greater-than only to make sure that the
2090 CURL_READFUNC_ABORT return code still aborts */
2091 failf(data, "Failed to read data");
2092 return CURLE_FTP_COULDNT_USE_REST;
2094 } while(passed < data->state.resume_from);
2097 /* now, decrease the size of the read */
2098 if(data->state.infilesize > 0) {
2099 data->state.infilesize -= data->state.resume_from;
2100 data->req.size = data->state.infilesize;
2101 Curl_pgrsSetUploadSize(data, data->state.infilesize);
2104 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2106 if(data->state.infilesize > 0) {
2107 data->req.size = data->state.infilesize;
2108 Curl_pgrsSetUploadSize(data, data->state.infilesize);
2111 Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
2113 /* not set by Curl_setup_transfer to preserve keepon bits */
2114 conn->sockfd = conn->writesockfd;
2117 state(data, SSH_SFTP_CLOSE);
2118 sshc->actualcode = result;
2121 /* store this original bitmask setup to use later on if we can't
2122 figure out a "real" bitmask */
2123 sshc->orig_waitfor = data->req.keepon;
2125 /* we want to use the _sending_ function even when the socket turns
2126 out readable as the underlying libssh2 sftp send function will deal
2127 with both accordingly */
2128 conn->cselect_bits = CURL_CSELECT_OUT;
2130 /* since we don't really wait for anything at this point, we want the
2131 state machine to move on as soon as possible so we set a very short
2133 Curl_expire(data, 0, EXPIRE_RUN_NOW);
2135 state(data, SSH_STOP);
2140 case SSH_SFTP_CREATE_DIRS_INIT:
2141 if(strlen(sshp->path) > 1) {
2142 sshc->slash_pos = sshp->path + 1; /* ignore the leading '/' */
2143 state(data, SSH_SFTP_CREATE_DIRS);
2146 state(data, SSH_SFTP_UPLOAD_INIT);
2150 case SSH_SFTP_CREATE_DIRS:
2151 sshc->slash_pos = strchr(sshc->slash_pos, '/');
2152 if(sshc->slash_pos) {
2153 *sshc->slash_pos = 0;
2155 infof(data, "Creating directory '%s'", sshp->path);
2156 state(data, SSH_SFTP_CREATE_DIRS_MKDIR);
2159 state(data, SSH_SFTP_UPLOAD_INIT);
2162 case SSH_SFTP_CREATE_DIRS_MKDIR:
2163 /* 'mode' - parameter is preliminary - default to 0644 */
2164 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshp->path,
2165 curlx_uztoui(strlen(sshp->path)),
2166 data->set.new_directory_perms);
2167 if(rc == LIBSSH2_ERROR_EAGAIN) {
2170 *sshc->slash_pos = '/';
2174 * Abort if failure wasn't that the dir already exists or the
2175 * permission was denied (creation might succeed further down the
2176 * path) - retry on unspecific FAILURE also
2178 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2179 if((sftperr != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
2180 (sftperr != LIBSSH2_FX_FAILURE) &&
2181 (sftperr != LIBSSH2_FX_PERMISSION_DENIED)) {
2182 result = sftp_libssh2_error_to_CURLE(sftperr);
2183 state(data, SSH_SFTP_CLOSE);
2184 sshc->actualcode = result?result:CURLE_SSH;
2187 rc = 0; /* clear rc and continue */
2189 state(data, SSH_SFTP_CREATE_DIRS);
2192 case SSH_SFTP_READDIR_INIT:
2193 Curl_pgrsSetDownloadSize(data, -1);
2194 if(data->set.opt_no_body) {
2195 state(data, SSH_STOP);
2200 * This is a directory that we are trying to get, so produce a directory
2203 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
2206 strlen(sshp->path)),
2207 0, 0, LIBSSH2_SFTP_OPENDIR);
2208 if(!sshc->sftp_handle) {
2209 if(libssh2_session_last_errno(sshc->ssh_session) ==
2210 LIBSSH2_ERROR_EAGAIN) {
2211 rc = LIBSSH2_ERROR_EAGAIN;
2214 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2215 failf(data, "Could not open directory for reading: %s",
2216 sftp_libssh2_strerror(sftperr));
2217 state(data, SSH_SFTP_CLOSE);
2218 result = sftp_libssh2_error_to_CURLE(sftperr);
2219 sshc->actualcode = result?result:CURLE_SSH;
2222 sshp->readdir_filename = malloc(PATH_MAX + 1);
2223 if(!sshp->readdir_filename) {
2224 state(data, SSH_SFTP_CLOSE);
2225 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2228 sshp->readdir_longentry = malloc(PATH_MAX + 1);
2229 if(!sshp->readdir_longentry) {
2230 Curl_safefree(sshp->readdir_filename);
2231 state(data, SSH_SFTP_CLOSE);
2232 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2235 Curl_dyn_init(&sshp->readdir, PATH_MAX * 2);
2236 state(data, SSH_SFTP_READDIR);
2239 case SSH_SFTP_READDIR:
2240 rc = libssh2_sftp_readdir_ex(sshc->sftp_handle,
2241 sshp->readdir_filename,
2243 sshp->readdir_longentry,
2245 &sshp->readdir_attrs);
2246 if(rc == LIBSSH2_ERROR_EAGAIN) {
2250 readdir_len = (size_t) rc;
2251 sshp->readdir_filename[readdir_len] = '\0';
2253 if(data->set.list_only) {
2254 result = Curl_client_write(data, CLIENTWRITE_BODY,
2255 sshp->readdir_filename,
2258 result = Curl_client_write(data, CLIENTWRITE_BODY,
2261 state(data, SSH_STOP);
2264 /* since this counts what we send to the client, we include the
2265 newline in this counter */
2266 data->req.bytecount += readdir_len + 1;
2268 /* output debug output if that is requested */
2269 Curl_debug(data, CURLINFO_DATA_IN, sshp->readdir_filename,
2271 Curl_debug(data, CURLINFO_DATA_IN, (char *)"\n", 1);
2274 result = Curl_dyn_add(&sshp->readdir, sshp->readdir_longentry);
2277 if((sshp->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
2278 ((sshp->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
2279 LIBSSH2_SFTP_S_IFLNK)) {
2280 Curl_dyn_init(&sshp->readdir_link, PATH_MAX);
2281 result = Curl_dyn_add(&sshp->readdir_link, sshp->path);
2282 state(data, SSH_SFTP_READDIR_LINK);
2287 state(data, SSH_SFTP_READDIR_BOTTOM);
2291 sshc->actualcode = result;
2292 state(data, SSH_SFTP_CLOSE);
2297 Curl_safefree(sshp->readdir_filename);
2298 Curl_safefree(sshp->readdir_longentry);
2299 state(data, SSH_SFTP_READDIR_DONE);
2303 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2304 result = sftp_libssh2_error_to_CURLE(sftperr);
2305 sshc->actualcode = result?result:CURLE_SSH;
2306 failf(data, "Could not open remote file for reading: %s :: %d",
2307 sftp_libssh2_strerror(sftperr),
2308 libssh2_session_last_errno(sshc->ssh_session));
2309 Curl_safefree(sshp->readdir_filename);
2310 Curl_safefree(sshp->readdir_longentry);
2311 state(data, SSH_SFTP_CLOSE);
2316 case SSH_SFTP_READDIR_LINK:
2318 libssh2_sftp_symlink_ex(sshc->sftp_session,
2319 Curl_dyn_ptr(&sshp->readdir_link),
2320 (int)Curl_dyn_len(&sshp->readdir_link),
2321 sshp->readdir_filename,
2322 PATH_MAX, LIBSSH2_SFTP_READLINK);
2323 if(rc == LIBSSH2_ERROR_EAGAIN) {
2326 Curl_dyn_free(&sshp->readdir_link);
2328 /* append filename and extra output */
2329 result = Curl_dyn_addf(&sshp->readdir, " -> %s", sshp->readdir_filename);
2332 sshc->readdir_line = NULL;
2333 Curl_safefree(sshp->readdir_filename);
2334 Curl_safefree(sshp->readdir_longentry);
2335 state(data, SSH_SFTP_CLOSE);
2336 sshc->actualcode = result;
2340 state(data, SSH_SFTP_READDIR_BOTTOM);
2343 case SSH_SFTP_READDIR_BOTTOM:
2344 result = Curl_dyn_addn(&sshp->readdir, "\n", 1);
2346 result = Curl_client_write(data, CLIENTWRITE_BODY,
2347 Curl_dyn_ptr(&sshp->readdir),
2348 Curl_dyn_len(&sshp->readdir));
2351 /* output debug output if that is requested */
2352 Curl_debug(data, CURLINFO_DATA_IN,
2353 Curl_dyn_ptr(&sshp->readdir),
2354 Curl_dyn_len(&sshp->readdir));
2355 data->req.bytecount += Curl_dyn_len(&sshp->readdir);
2358 Curl_dyn_free(&sshp->readdir);
2359 state(data, SSH_STOP);
2362 Curl_dyn_reset(&sshp->readdir);
2363 state(data, SSH_SFTP_READDIR);
2367 case SSH_SFTP_READDIR_DONE:
2368 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
2369 LIBSSH2_ERROR_EAGAIN) {
2370 rc = LIBSSH2_ERROR_EAGAIN;
2373 sshc->sftp_handle = NULL;
2374 Curl_safefree(sshp->readdir_filename);
2375 Curl_safefree(sshp->readdir_longentry);
2377 /* no data to transfer */
2378 Curl_setup_transfer(data, -1, -1, FALSE, -1);
2379 state(data, SSH_STOP);
2382 case SSH_SFTP_DOWNLOAD_INIT:
2384 * Work on getting the specified file
2387 libssh2_sftp_open_ex(sshc->sftp_session, sshp->path,
2388 curlx_uztoui(strlen(sshp->path)),
2389 LIBSSH2_FXF_READ, data->set.new_file_perms,
2390 LIBSSH2_SFTP_OPENFILE);
2391 if(!sshc->sftp_handle) {
2392 if(libssh2_session_last_errno(sshc->ssh_session) ==
2393 LIBSSH2_ERROR_EAGAIN) {
2394 rc = LIBSSH2_ERROR_EAGAIN;
2397 sftperr = libssh2_sftp_last_error(sshc->sftp_session);
2398 failf(data, "Could not open remote file for reading: %s",
2399 sftp_libssh2_strerror(sftperr));
2400 state(data, SSH_SFTP_CLOSE);
2401 result = sftp_libssh2_error_to_CURLE(sftperr);
2402 sshc->actualcode = result?result:CURLE_SSH;
2405 state(data, SSH_SFTP_DOWNLOAD_STAT);
2408 case SSH_SFTP_DOWNLOAD_STAT:
2410 LIBSSH2_SFTP_ATTRIBUTES attrs;
2412 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path,
2413 curlx_uztoui(strlen(sshp->path)),
2414 LIBSSH2_SFTP_STAT, &attrs);
2415 if(rc == LIBSSH2_ERROR_EAGAIN) {
2419 !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
2420 (attrs.filesize == 0)) {
2422 * libssh2_sftp_open() didn't return an error, so maybe the server
2423 * just doesn't support stat()
2424 * OR the server doesn't return a file size with a stat()
2427 data->req.size = -1;
2428 data->req.maxdownload = -1;
2429 Curl_pgrsSetDownloadSize(data, -1);
2432 curl_off_t size = attrs.filesize;
2435 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
2436 return CURLE_BAD_DOWNLOAD_RESUME;
2438 if(data->state.use_range) {
2439 curl_off_t from, to;
2445 from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from);
2446 if(from_t == CURL_OFFT_FLOW)
2447 return CURLE_RANGE_ERROR;
2448 while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
2450 to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
2451 if(to_t == CURL_OFFT_FLOW)
2452 return CURLE_RANGE_ERROR;
2453 if((to_t == CURL_OFFT_INVAL) /* no "to" value given */
2458 /* from is relative to end of file */
2463 failf(data, "Offset (%"
2464 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2465 CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
2466 return CURLE_BAD_DOWNLOAD_RESUME;
2473 size = to - from + 1;
2476 SFTP_SEEK(sshc->sftp_handle, from);
2478 data->req.size = size;
2479 data->req.maxdownload = size;
2480 Curl_pgrsSetDownloadSize(data, size);
2483 /* We can resume if we can seek to the resume position */
2484 if(data->state.resume_from) {
2485 if(data->state.resume_from < 0) {
2486 /* We're supposed to download the last abs(from) bytes */
2487 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2488 failf(data, "Offset (%"
2489 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2490 CURL_FORMAT_CURL_OFF_T ")",
2491 data->state.resume_from, attrs.filesize);
2492 return CURLE_BAD_DOWNLOAD_RESUME;
2494 /* download from where? */
2495 data->state.resume_from += attrs.filesize;
2498 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2499 failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
2500 ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
2501 data->state.resume_from, attrs.filesize);
2502 return CURLE_BAD_DOWNLOAD_RESUME;
2505 /* Now store the number of bytes we are expected to download */
2506 data->req.size = attrs.filesize - data->state.resume_from;
2507 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2508 Curl_pgrsSetDownloadSize(data,
2509 attrs.filesize - data->state.resume_from);
2510 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2514 /* Setup the actual download */
2515 if(data->req.size == 0) {
2516 /* no data to transfer */
2517 Curl_setup_transfer(data, -1, -1, FALSE, -1);
2518 infof(data, "File already completely downloaded");
2519 state(data, SSH_STOP);
2522 Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
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 /* this should never occur; the close state should be entered
2534 at the time the error occurs */
2535 state(data, SSH_SFTP_CLOSE);
2536 sshc->actualcode = result;
2539 state(data, SSH_STOP);
2543 case SSH_SFTP_CLOSE:
2544 if(sshc->sftp_handle) {
2545 rc = libssh2_sftp_close(sshc->sftp_handle);
2546 if(rc == LIBSSH2_ERROR_EAGAIN) {
2550 char *err_msg = NULL;
2551 (void)libssh2_session_last_error(sshc->ssh_session,
2553 infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg);
2555 sshc->sftp_handle = NULL;
2558 Curl_safefree(sshp->path);
2560 DEBUGF(infof(data, "SFTP DONE done"));
2562 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2563 After nextstate is executed, the control should come back to
2564 SSH_SFTP_CLOSE to pass the correct result back */
2565 if(sshc->nextstate != SSH_NO_STATE &&
2566 sshc->nextstate != SSH_SFTP_CLOSE) {
2567 state(data, sshc->nextstate);
2568 sshc->nextstate = SSH_SFTP_CLOSE;
2571 state(data, SSH_STOP);
2572 result = sshc->actualcode;
2576 case SSH_SFTP_SHUTDOWN:
2577 /* during times we get here due to a broken transfer and then the
2578 sftp_handle might not have been taken down so make sure that is done
2579 before we proceed */
2581 if(sshc->sftp_handle) {
2582 rc = libssh2_sftp_close(sshc->sftp_handle);
2583 if(rc == LIBSSH2_ERROR_EAGAIN) {
2587 char *err_msg = NULL;
2588 (void)libssh2_session_last_error(sshc->ssh_session, &err_msg,
2590 infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg);
2592 sshc->sftp_handle = NULL;
2594 if(sshc->sftp_session) {
2595 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2596 if(rc == LIBSSH2_ERROR_EAGAIN) {
2600 infof(data, "Failed to stop libssh2 sftp subsystem");
2602 sshc->sftp_session = NULL;
2605 Curl_safefree(sshc->homedir);
2606 data->state.most_recent_ftp_entrypath = NULL;
2608 state(data, SSH_SESSION_DISCONNECT);
2611 case SSH_SCP_TRANS_INIT:
2612 result = Curl_getworkingpath(data, sshc->homedir, &sshp->path);
2614 sshc->actualcode = result;
2615 state(data, SSH_STOP);
2619 if(data->set.upload) {
2620 if(data->state.infilesize < 0) {
2621 failf(data, "SCP requires a known file size for upload");
2622 sshc->actualcode = CURLE_UPLOAD_FAILED;
2623 state(data, SSH_SCP_CHANNEL_FREE);
2626 state(data, SSH_SCP_UPLOAD_INIT);
2629 state(data, SSH_SCP_DOWNLOAD_INIT);
2633 case SSH_SCP_UPLOAD_INIT:
2635 * libssh2 requires that the destination path is a full path that
2636 * includes the destination file and name OR ends in a "/" . If this is
2637 * not done the destination file will be named the same name as the last
2638 * directory in the path.
2641 SCP_SEND(sshc->ssh_session, sshp->path, data->set.new_file_perms,
2642 data->state.infilesize);
2643 if(!sshc->ssh_channel) {
2645 char *err_msg = NULL;
2647 if(libssh2_session_last_errno(sshc->ssh_session) ==
2648 LIBSSH2_ERROR_EAGAIN) {
2649 rc = LIBSSH2_ERROR_EAGAIN;
2653 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2654 &err_msg, NULL, 0));
2655 failf(data, "%s", err_msg);
2656 state(data, SSH_SCP_CHANNEL_FREE);
2657 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2658 /* Map generic errors to upload failed */
2659 if(sshc->actualcode == CURLE_SSH ||
2660 sshc->actualcode == CURLE_REMOTE_FILE_NOT_FOUND)
2661 sshc->actualcode = CURLE_UPLOAD_FAILED;
2666 data->req.size = data->state.infilesize;
2667 Curl_pgrsSetUploadSize(data, data->state.infilesize);
2668 Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
2670 /* not set by Curl_setup_transfer to preserve keepon bits */
2671 conn->sockfd = conn->writesockfd;
2674 state(data, SSH_SCP_CHANNEL_FREE);
2675 sshc->actualcode = result;
2678 /* store this original bitmask setup to use later on if we can't
2679 figure out a "real" bitmask */
2680 sshc->orig_waitfor = data->req.keepon;
2682 /* we want to use the _sending_ function even when the socket turns
2683 out readable as the underlying libssh2 scp send function will deal
2684 with both accordingly */
2685 conn->cselect_bits = CURL_CSELECT_OUT;
2687 state(data, SSH_STOP);
2691 case SSH_SCP_DOWNLOAD_INIT:
2693 curl_off_t bytecount;
2696 * We must check the remote file; if it is a directory no values will
2701 * If support for >2GB files exists, use it.
2704 /* get a fresh new channel from the ssh layer */
2705 #if LIBSSH2_VERSION_NUM < 0x010700
2707 memset(&sb, 0, sizeof(struct stat));
2708 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2711 libssh2_struct_stat sb;
2712 memset(&sb, 0, sizeof(libssh2_struct_stat));
2713 sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session,
2717 if(!sshc->ssh_channel) {
2719 char *err_msg = NULL;
2721 if(libssh2_session_last_errno(sshc->ssh_session) ==
2722 LIBSSH2_ERROR_EAGAIN) {
2723 rc = LIBSSH2_ERROR_EAGAIN;
2728 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2729 &err_msg, NULL, 0));
2730 failf(data, "%s", err_msg);
2731 state(data, SSH_SCP_CHANNEL_FREE);
2732 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2737 bytecount = (curl_off_t)sb.st_size;
2738 data->req.maxdownload = (curl_off_t)sb.st_size;
2739 Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1);
2741 /* not set by Curl_setup_transfer to preserve keepon bits */
2742 conn->writesockfd = conn->sockfd;
2744 /* we want to use the _receiving_ function even when the socket turns
2745 out writableable as the underlying libssh2 recv function will deal
2746 with both accordingly */
2747 conn->cselect_bits = CURL_CSELECT_IN;
2750 state(data, SSH_SCP_CHANNEL_FREE);
2751 sshc->actualcode = result;
2754 state(data, SSH_STOP);
2759 if(data->set.upload)
2760 state(data, SSH_SCP_SEND_EOF);
2762 state(data, SSH_SCP_CHANNEL_FREE);
2765 case SSH_SCP_SEND_EOF:
2766 if(sshc->ssh_channel) {
2767 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2768 if(rc == LIBSSH2_ERROR_EAGAIN) {
2772 char *err_msg = NULL;
2773 (void)libssh2_session_last_error(sshc->ssh_session,
2775 infof(data, "Failed to send libssh2 channel EOF: %d %s",
2779 state(data, SSH_SCP_WAIT_EOF);
2782 case SSH_SCP_WAIT_EOF:
2783 if(sshc->ssh_channel) {
2784 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2785 if(rc == LIBSSH2_ERROR_EAGAIN) {
2789 char *err_msg = NULL;
2790 (void)libssh2_session_last_error(sshc->ssh_session,
2792 infof(data, "Failed to get channel EOF: %d %s", rc, err_msg);
2795 state(data, SSH_SCP_WAIT_CLOSE);
2798 case SSH_SCP_WAIT_CLOSE:
2799 if(sshc->ssh_channel) {
2800 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2801 if(rc == LIBSSH2_ERROR_EAGAIN) {
2805 char *err_msg = NULL;
2806 (void)libssh2_session_last_error(sshc->ssh_session,
2808 infof(data, "Channel failed to close: %d %s", rc, err_msg);
2811 state(data, SSH_SCP_CHANNEL_FREE);
2814 case SSH_SCP_CHANNEL_FREE:
2815 if(sshc->ssh_channel) {
2816 rc = libssh2_channel_free(sshc->ssh_channel);
2817 if(rc == LIBSSH2_ERROR_EAGAIN) {
2821 char *err_msg = NULL;
2822 (void)libssh2_session_last_error(sshc->ssh_session,
2824 infof(data, "Failed to free libssh2 scp subsystem: %d %s",
2827 sshc->ssh_channel = NULL;
2829 DEBUGF(infof(data, "SCP DONE phase complete"));
2831 state(data, SSH_SESSION_DISCONNECT);
2833 state(data, SSH_STOP);
2834 result = sshc->actualcode;
2837 case SSH_SESSION_DISCONNECT:
2838 /* during weird times when we've been prematurely aborted, the channel
2839 is still alive when we reach this state and we MUST kill the channel
2841 if(sshc->ssh_channel) {
2842 rc = libssh2_channel_free(sshc->ssh_channel);
2843 if(rc == LIBSSH2_ERROR_EAGAIN) {
2847 char *err_msg = NULL;
2848 (void)libssh2_session_last_error(sshc->ssh_session,
2850 infof(data, "Failed to free libssh2 scp subsystem: %d %s",
2853 sshc->ssh_channel = NULL;
2856 if(sshc->ssh_session) {
2857 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2858 if(rc == LIBSSH2_ERROR_EAGAIN) {
2862 char *err_msg = NULL;
2863 (void)libssh2_session_last_error(sshc->ssh_session,
2865 infof(data, "Failed to disconnect libssh2 session: %d %s",
2870 Curl_safefree(sshc->homedir);
2871 data->state.most_recent_ftp_entrypath = NULL;
2873 state(data, SSH_SESSION_FREE);
2876 case SSH_SESSION_FREE:
2877 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2879 libssh2_knownhost_free(sshc->kh);
2884 #ifdef HAVE_LIBSSH2_AGENT_API
2885 if(sshc->ssh_agent) {
2886 rc = libssh2_agent_disconnect(sshc->ssh_agent);
2887 if(rc == LIBSSH2_ERROR_EAGAIN) {
2891 char *err_msg = NULL;
2892 (void)libssh2_session_last_error(sshc->ssh_session,
2894 infof(data, "Failed to disconnect from libssh2 agent: %d %s",
2897 libssh2_agent_free(sshc->ssh_agent);
2898 sshc->ssh_agent = NULL;
2900 /* NB: there is no need to free identities, they are part of internal
2902 sshc->sshagent_identity = NULL;
2903 sshc->sshagent_prev_identity = NULL;
2907 if(sshc->ssh_session) {
2908 rc = libssh2_session_free(sshc->ssh_session);
2909 if(rc == LIBSSH2_ERROR_EAGAIN) {
2913 char *err_msg = NULL;
2914 (void)libssh2_session_last_error(sshc->ssh_session,
2916 infof(data, "Failed to free libssh2 session: %d %s", rc, err_msg);
2918 sshc->ssh_session = NULL;
2921 /* worst-case scenario cleanup */
2923 DEBUGASSERT(sshc->ssh_session == NULL);
2924 DEBUGASSERT(sshc->ssh_channel == NULL);
2925 DEBUGASSERT(sshc->sftp_session == NULL);
2926 DEBUGASSERT(sshc->sftp_handle == NULL);
2927 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2928 DEBUGASSERT(sshc->kh == NULL);
2930 #ifdef HAVE_LIBSSH2_AGENT_API
2931 DEBUGASSERT(sshc->ssh_agent == NULL);
2934 Curl_safefree(sshc->rsa_pub);
2935 Curl_safefree(sshc->rsa);
2937 Curl_safefree(sshc->quote_path1);
2938 Curl_safefree(sshc->quote_path2);
2940 Curl_safefree(sshc->homedir);
2941 Curl_safefree(sshc->readdir_line);
2943 /* the code we are about to return */
2944 result = sshc->actualcode;
2946 memset(sshc, 0, sizeof(struct ssh_conn));
2948 connclose(conn, "SSH session free");
2949 sshc->state = SSH_SESSION_FREE; /* current */
2950 sshc->nextstate = SSH_NO_STATE;
2951 state(data, SSH_STOP);
2955 /* fallthrough, just stop! */
2957 /* internal error */
2958 sshc->nextstate = SSH_NO_STATE;
2959 state(data, SSH_STOP);
2963 } while(!rc && (sshc->state != SSH_STOP));
2965 if(rc == LIBSSH2_ERROR_EAGAIN) {
2966 /* we would block, we need to wait for the socket to be ready (in the
2967 right direction too)! */
2974 /* called by the multi interface to figure out what socket(s) to wait for and
2975 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2976 static int ssh_getsock(struct Curl_easy *data,
2977 struct connectdata *conn,
2978 curl_socket_t *sock)
2980 int bitmap = GETSOCK_BLANK;
2983 sock[0] = conn->sock[FIRSTSOCKET];
2985 if(conn->waitfor & KEEP_RECV)
2986 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2988 if(conn->waitfor & KEEP_SEND)
2989 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2995 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2996 * function is used to figure out in what direction and stores this info so
2997 * that the multi interface can take advantage of it. Make sure to call this
2998 * function in all cases so that when it _doesn't_ return EAGAIN we can
2999 * restore the default wait bits.
3001 static void ssh_block2waitfor(struct Curl_easy *data, bool block)
3003 struct connectdata *conn = data->conn;
3004 struct ssh_conn *sshc = &conn->proto.sshc;
3007 dir = libssh2_session_block_directions(sshc->ssh_session);
3009 /* translate the libssh2 define bits into our own bit defines */
3010 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
3011 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
3015 /* It didn't block or libssh2 didn't reveal in which direction, put back
3017 conn->waitfor = sshc->orig_waitfor;
3020 /* called repeatedly until done from multi.c */
3021 static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done)
3023 struct connectdata *conn = data->conn;
3024 struct ssh_conn *sshc = &conn->proto.sshc;
3025 CURLcode result = CURLE_OK;
3026 bool block; /* we store the status and use that to provide a ssh_getsock()
3029 result = ssh_statemach_act(data, &block);
3030 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
3031 /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then
3033 } while(!result && !*done && !block);
3034 ssh_block2waitfor(data, block);
3039 static CURLcode ssh_block_statemach(struct Curl_easy *data,
3040 struct connectdata *conn,
3043 struct ssh_conn *sshc = &conn->proto.sshc;
3044 CURLcode result = CURLE_OK;
3045 struct curltime dis = Curl_now();
3047 while((sshc->state != SSH_STOP) && !result) {
3049 timediff_t left = 1000;
3050 struct curltime now = Curl_now();
3052 result = ssh_statemach_act(data, &block);
3057 if(Curl_pgrsUpdate(data))
3058 return CURLE_ABORTED_BY_CALLBACK;
3060 result = Curl_speedcheck(data, now);
3064 left = Curl_timeleft(data, NULL, FALSE);
3066 failf(data, "Operation timed out");
3067 return CURLE_OPERATION_TIMEDOUT;
3070 else if(Curl_timediff(now, dis) > 1000) {
3071 /* disconnect timeout */
3072 failf(data, "Disconnect timed out");
3078 int dir = libssh2_session_block_directions(sshc->ssh_session);
3079 curl_socket_t sock = conn->sock[FIRSTSOCKET];
3080 curl_socket_t fd_read = CURL_SOCKET_BAD;
3081 curl_socket_t fd_write = CURL_SOCKET_BAD;
3082 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
3084 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
3086 /* wait for the socket to become ready */
3087 (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
3088 left>1000?1000:left);
3096 * SSH setup and connection
3098 static CURLcode ssh_setup_connection(struct Curl_easy *data,
3099 struct connectdata *conn)
3101 struct SSHPROTO *ssh;
3104 data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
3106 return CURLE_OUT_OF_MEMORY;
3111 static Curl_recv scp_recv, sftp_recv;
3112 static Curl_send scp_send, sftp_send;
3114 #ifndef CURL_DISABLE_PROXY
3115 static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer,
3116 size_t length, int flags, void **abstract)
3118 struct Curl_easy *data = (struct Curl_easy *)*abstract;
3121 struct connectdata *conn = data->conn;
3122 Curl_recv *backup = conn->recv[0];
3123 struct ssh_conn *ssh = &conn->proto.sshc;
3126 /* swap in the TLS reader function for this call only, and then swap back
3127 the SSH one again */
3128 conn->recv[0] = ssh->tls_recv;
3129 result = Curl_read(data, sock, buffer, length, &nread);
3130 conn->recv[0] = backup;
3131 if(result == CURLE_AGAIN)
3132 return -EAGAIN; /* magic return code for libssh2 */
3134 return -1; /* generic error */
3135 Curl_debug(data, CURLINFO_DATA_IN, (char *)buffer, (size_t)nread);
3139 static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer,
3140 size_t length, int flags, void **abstract)
3142 struct Curl_easy *data = (struct Curl_easy *)*abstract;
3145 struct connectdata *conn = data->conn;
3146 Curl_send *backup = conn->send[0];
3147 struct ssh_conn *ssh = &conn->proto.sshc;
3150 /* swap in the TLS writer function for this call only, and then swap back
3151 the SSH one again */
3152 conn->send[0] = ssh->tls_send;
3153 result = Curl_write(data, sock, buffer, length, &nwrite);
3154 conn->send[0] = backup;
3155 if(result == CURLE_AGAIN)
3156 return -EAGAIN; /* magic return code for libssh2 */
3158 return -1; /* error */
3159 Curl_debug(data, CURLINFO_DATA_OUT, (char *)buffer, (size_t)nwrite);
3165 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
3166 * do protocol-specific actions at connect-time.
3168 static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
3170 #ifdef CURL_LIBSSH2_DEBUG
3173 struct ssh_conn *sshc;
3175 struct connectdata *conn = data->conn;
3177 /* initialize per-handle data if not already */
3178 if(!data->req.p.ssh) {
3179 result = ssh_setup_connection(data, conn);
3184 /* We default to persistent connections. We set this already in this connect
3185 function to make the re-use checks properly be able to check this bit. */
3186 connkeep(conn, "SSH default");
3188 sshc = &conn->proto.sshc;
3190 #ifdef CURL_LIBSSH2_DEBUG
3192 infof(data, "User: %s", conn->user);
3195 infof(data, "Password: %s", conn->passwd);
3197 sock = conn->sock[FIRSTSOCKET];
3198 #endif /* CURL_LIBSSH2_DEBUG */
3200 sshc->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
3202 my_libssh2_realloc, data);
3203 if(!sshc->ssh_session) {
3204 failf(data, "Failure initialising ssh session");
3205 return CURLE_FAILED_INIT;
3208 #ifndef CURL_DISABLE_PROXY
3209 if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
3211 * This crazy union dance is here to avoid assigning a void pointer a
3212 * function pointer as it is invalid C. The problem is of course that
3213 * libssh2 has such an API...
3217 ssize_t (*recvptr)(libssh2_socket_t, void *, size_t, int, void **);
3221 ssize_t (*sendptr)(libssh2_socket_t, const void *, size_t, int, void **);
3223 union receive sshrecv;
3224 union transfer sshsend;
3226 sshrecv.recvptr = ssh_tls_recv;
3227 sshsend.sendptr = ssh_tls_send;
3229 infof(data, "Uses HTTPS proxy");
3231 Setup libssh2 callbacks to make it read/write TLS from the socket.
3234 recvcb(libssh2_socket_t sock, void *buffer, size_t length,
3235 int flags, void **abstract);
3238 sendcb(libssh2_socket_t sock, const void *buffer, size_t length,
3239 int flags, void **abstract);
3242 libssh2_session_callback_set(sshc->ssh_session,
3243 LIBSSH2_CALLBACK_RECV, sshrecv.recvp);
3244 libssh2_session_callback_set(sshc->ssh_session,
3245 LIBSSH2_CALLBACK_SEND, sshsend.sendp);
3247 /* Store the underlying TLS recv/send function pointers to be used when
3248 reading from the proxy */
3249 sshc->tls_recv = conn->recv[FIRSTSOCKET];
3250 sshc->tls_send = conn->send[FIRSTSOCKET];
3253 #endif /* CURL_DISABLE_PROXY */
3254 if(conn->handler->protocol & CURLPROTO_SCP) {
3255 conn->recv[FIRSTSOCKET] = scp_recv;
3256 conn->send[FIRSTSOCKET] = scp_send;
3259 conn->recv[FIRSTSOCKET] = sftp_recv;
3260 conn->send[FIRSTSOCKET] = sftp_send;
3263 if(data->set.ssh_compression) {
3264 #if LIBSSH2_VERSION_NUM >= 0x010208
3265 if(libssh2_session_flag(sshc->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0)
3267 infof(data, "Failed to enable compression for ssh session");
3270 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
3271 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
3273 sshc->kh = libssh2_knownhost_init(sshc->ssh_session);
3275 libssh2_session_free(sshc->ssh_session);
3276 sshc->ssh_session = NULL;
3277 return CURLE_FAILED_INIT;
3280 /* read all known hosts from there */
3281 rc = libssh2_knownhost_readfile(sshc->kh,
3282 data->set.str[STRING_SSH_KNOWNHOSTS],
3283 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
3285 infof(data, "Failed to read known hosts from %s",
3286 data->set.str[STRING_SSH_KNOWNHOSTS]);
3288 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
3290 #ifdef CURL_LIBSSH2_DEBUG
3291 libssh2_trace(sshc->ssh_session, ~0);
3292 infof(data, "SSH socket: %d", (int)sock);
3293 #endif /* CURL_LIBSSH2_DEBUG */
3295 state(data, SSH_INIT);
3297 result = ssh_multi_statemach(data, done);
3303 ***********************************************************************
3307 * This is the actual DO function for SCP. Get a file according to
3308 * the options previously setup.
3312 CURLcode scp_perform(struct Curl_easy *data,
3316 CURLcode result = CURLE_OK;
3317 struct connectdata *conn = data->conn;
3319 DEBUGF(infof(data, "DO phase starts"));
3321 *dophase_done = FALSE; /* not done yet */
3323 /* start the first command in the DO phase */
3324 state(data, SSH_SCP_TRANS_INIT);
3326 /* run the state-machine */
3327 result = ssh_multi_statemach(data, dophase_done);
3329 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3332 DEBUGF(infof(data, "DO phase is complete"));
3338 /* called from multi.c while DOing */
3339 static CURLcode scp_doing(struct Curl_easy *data,
3343 result = ssh_multi_statemach(data, dophase_done);
3346 DEBUGF(infof(data, "DO phase is complete"));
3352 * The DO function is generic for both protocols. There was previously two
3353 * separate ones but this way means less duplicated code.
3356 static CURLcode ssh_do(struct Curl_easy *data, bool *done)
3360 struct connectdata *conn = data->conn;
3361 struct ssh_conn *sshc = &conn->proto.sshc;
3363 *done = FALSE; /* default to false */
3365 data->req.size = -1; /* make sure this is unknown at this point */
3367 sshc->actualcode = CURLE_OK; /* reset error code */
3368 sshc->secondCreateDirs = 0; /* reset the create dir attempt state
3371 Curl_pgrsSetUploadCounter(data, 0);
3372 Curl_pgrsSetDownloadCounter(data, 0);
3373 Curl_pgrsSetUploadSize(data, -1);
3374 Curl_pgrsSetDownloadSize(data, -1);
3376 if(conn->handler->protocol & CURLPROTO_SCP)
3377 result = scp_perform(data, &connected, done);
3379 result = sftp_perform(data, &connected, done);
3384 /* BLOCKING, but the function is using the state machine so the only reason
3385 this is still blocking is that the multi interface code has no support for
3386 disconnecting operations that takes a while */
3387 static CURLcode scp_disconnect(struct Curl_easy *data,
3388 struct connectdata *conn,
3389 bool dead_connection)
3391 CURLcode result = CURLE_OK;
3392 struct ssh_conn *sshc = &conn->proto.sshc;
3393 (void) dead_connection;
3395 if(sshc->ssh_session) {
3396 /* only if there's a session still around to use! */
3397 state(data, SSH_SESSION_DISCONNECT);
3398 result = ssh_block_statemach(data, conn, TRUE);
3404 /* generic done function for both SCP and SFTP called from their specific
3406 static CURLcode ssh_done(struct Curl_easy *data, CURLcode status)
3408 CURLcode result = CURLE_OK;
3409 struct SSHPROTO *sshp = data->req.p.ssh;
3410 struct connectdata *conn = data->conn;
3413 /* run the state-machine */
3414 result = ssh_block_statemach(data, conn, FALSE);
3418 Curl_safefree(sshp->path);
3419 Curl_safefree(sshp->readdir_filename);
3420 Curl_safefree(sshp->readdir_longentry);
3421 Curl_dyn_free(&sshp->readdir);
3423 if(Curl_pgrsDone(data))
3424 return CURLE_ABORTED_BY_CALLBACK;
3426 data->req.keepon = 0; /* clear all bits */
3431 static CURLcode scp_done(struct Curl_easy *data, CURLcode status,
3434 (void)premature; /* not used */
3437 state(data, SSH_SCP_DONE);
3439 return ssh_done(data, status);
3443 static ssize_t scp_send(struct Curl_easy *data, int sockindex,
3444 const void *mem, size_t len, CURLcode *err)
3447 struct connectdata *conn = data->conn;
3448 struct ssh_conn *sshc = &conn->proto.sshc;
3449 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3451 /* libssh2_channel_write() returns int! */
3452 nwrite = (ssize_t) libssh2_channel_write(sshc->ssh_channel, mem, len);
3454 ssh_block2waitfor(data, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3456 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3460 else if(nwrite < LIBSSH2_ERROR_NONE) {
3461 *err = libssh2_session_error_to_CURLE((int)nwrite);
3468 static ssize_t scp_recv(struct Curl_easy *data, int sockindex,
3469 char *mem, size_t len, CURLcode *err)
3472 struct connectdata *conn = data->conn;
3473 struct ssh_conn *sshc = &conn->proto.sshc;
3474 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3476 /* libssh2_channel_read() returns int */
3477 nread = (ssize_t) libssh2_channel_read(sshc->ssh_channel, mem, len);
3479 ssh_block2waitfor(data, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3480 if(nread == LIBSSH2_ERROR_EAGAIN) {
3489 * =============== SFTP ===============
3493 ***********************************************************************
3497 * This is the actual DO function for SFTP. Get a file/directory according to
3498 * the options previously setup.
3502 CURLcode sftp_perform(struct Curl_easy *data,
3506 CURLcode result = CURLE_OK;
3508 DEBUGF(infof(data, "DO phase starts"));
3510 *dophase_done = FALSE; /* not done yet */
3512 /* start the first command in the DO phase */
3513 state(data, SSH_SFTP_QUOTE_INIT);
3515 /* run the state-machine */
3516 result = ssh_multi_statemach(data, dophase_done);
3518 *connected = data->conn->bits.tcpconnect[FIRSTSOCKET];
3521 DEBUGF(infof(data, "DO phase is complete"));
3527 /* called from multi.c while DOing */
3528 static CURLcode sftp_doing(struct Curl_easy *data,
3531 CURLcode result = ssh_multi_statemach(data, dophase_done);
3534 DEBUGF(infof(data, "DO phase is complete"));
3539 /* BLOCKING, but the function is using the state machine so the only reason
3540 this is still blocking is that the multi interface code has no support for
3541 disconnecting operations that takes a while */
3542 static CURLcode sftp_disconnect(struct Curl_easy *data,
3543 struct connectdata *conn, bool dead_connection)
3545 CURLcode result = CURLE_OK;
3546 struct ssh_conn *sshc = &conn->proto.sshc;
3547 (void) dead_connection;
3549 DEBUGF(infof(data, "SSH DISCONNECT starts now"));
3551 if(sshc->ssh_session) {
3552 /* only if there's a session still around to use! */
3553 state(data, SSH_SFTP_SHUTDOWN);
3554 result = ssh_block_statemach(data, conn, TRUE);
3557 DEBUGF(infof(data, "SSH DISCONNECT is done"));
3563 static CURLcode sftp_done(struct Curl_easy *data, CURLcode status,
3566 struct connectdata *conn = data->conn;
3567 struct ssh_conn *sshc = &conn->proto.sshc;
3570 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3571 errors that could happen due to open file handles during POSTQUOTE
3573 if(!premature && data->set.postquote && !conn->bits.retry)
3574 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3575 state(data, SSH_SFTP_CLOSE);
3577 return ssh_done(data, status);
3580 /* return number of sent bytes */
3581 static ssize_t sftp_send(struct Curl_easy *data, int sockindex,
3582 const void *mem, size_t len, CURLcode *err)
3585 struct connectdata *conn = data->conn;
3586 struct ssh_conn *sshc = &conn->proto.sshc;
3589 nwrite = libssh2_sftp_write(sshc->sftp_handle, mem, len);
3591 ssh_block2waitfor(data, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3593 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3597 else if(nwrite < LIBSSH2_ERROR_NONE) {
3598 *err = libssh2_session_error_to_CURLE((int)nwrite);
3606 * Return number of received (decrypted) bytes
3609 static ssize_t sftp_recv(struct Curl_easy *data, int sockindex,
3610 char *mem, size_t len, CURLcode *err)
3613 struct connectdata *conn = data->conn;
3614 struct ssh_conn *sshc = &conn->proto.sshc;
3617 nread = libssh2_sftp_read(sshc->sftp_handle, mem, len);
3619 ssh_block2waitfor(data, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3621 if(nread == LIBSSH2_ERROR_EAGAIN) {
3626 else if(nread < 0) {
3627 *err = libssh2_session_error_to_CURLE((int)nread);
3632 static const char *sftp_libssh2_strerror(unsigned long err)
3635 case LIBSSH2_FX_NO_SUCH_FILE:
3636 return "No such file or directory";
3638 case LIBSSH2_FX_PERMISSION_DENIED:
3639 return "Permission denied";
3641 case LIBSSH2_FX_FAILURE:
3642 return "Operation failed";
3644 case LIBSSH2_FX_BAD_MESSAGE:
3645 return "Bad message from SFTP server";
3647 case LIBSSH2_FX_NO_CONNECTION:
3648 return "Not connected to SFTP server";
3650 case LIBSSH2_FX_CONNECTION_LOST:
3651 return "Connection to SFTP server lost";
3653 case LIBSSH2_FX_OP_UNSUPPORTED:
3654 return "Operation not supported by SFTP server";
3656 case LIBSSH2_FX_INVALID_HANDLE:
3657 return "Invalid handle";
3659 case LIBSSH2_FX_NO_SUCH_PATH:
3660 return "No such file or directory";
3662 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3663 return "File already exists";
3665 case LIBSSH2_FX_WRITE_PROTECT:
3666 return "File is write protected";
3668 case LIBSSH2_FX_NO_MEDIA:
3671 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3674 case LIBSSH2_FX_QUOTA_EXCEEDED:
3675 return "User quota exceeded";
3677 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3678 return "Unknown principle";
3680 case LIBSSH2_FX_LOCK_CONFlICT:
3681 return "File lock conflict";
3683 case LIBSSH2_FX_DIR_NOT_EMPTY:
3684 return "Directory not empty";
3686 case LIBSSH2_FX_NOT_A_DIRECTORY:
3687 return "Not a directory";
3689 case LIBSSH2_FX_INVALID_FILENAME:
3690 return "Invalid filename";
3692 case LIBSSH2_FX_LINK_LOOP:
3693 return "Link points to itself";
3695 return "Unknown error in libssh2";
3698 CURLcode Curl_ssh_init(void)
3700 #ifdef HAVE_LIBSSH2_INIT
3701 if(libssh2_init(0)) {
3702 DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
3703 return CURLE_FAILED_INIT;
3709 void Curl_ssh_cleanup(void)
3711 #ifdef HAVE_LIBSSH2_EXIT
3712 (void)libssh2_exit();
3716 void Curl_ssh_version(char *buffer, size_t buflen)
3718 (void)msnprintf(buffer, buflen, "libssh2/%s", CURL_LIBSSH2_VERSION);
3721 /* The SSH session is associated with the *CONNECTION* but the callback user
3722 * pointer is an easy handle pointer. This function allows us to reassign the
3723 * user pointer to the *CURRENT* (new) easy handle.
3725 static void ssh_attach(struct Curl_easy *data, struct connectdata *conn)
3729 if(conn->handler->protocol & PROTO_FAMILY_SSH) {
3730 struct ssh_conn *sshc = &conn->proto.sshc;
3731 if(sshc->ssh_session) {
3732 /* only re-attach if the session already exists */
3733 void **abstract = libssh2_session_abstract(sshc->ssh_session);
3738 #endif /* USE_LIBSSH2 */