1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 /* #define CURL_LIBSSH2_DEBUG */
34 #include <libssh2_sftp.h>
44 #ifdef HAVE_SYS_SOCKET_H
45 #include <sys/socket.h>
47 #ifdef HAVE_NETINET_IN_H
48 #include <netinet/in.h>
50 #ifdef HAVE_ARPA_INET_H
51 #include <arpa/inet.h>
54 #include <sys/utsname.h>
64 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
66 #define in_addr_t unsigned long
69 #include <curl/curl.h>
76 #include "http.h" /* for HTTP proxy tunnel stuff */
79 #include "speedcheck.h"
86 #include "inet_ntop.h"
87 #include "parsedate.h" /* for the week day and month names */
88 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
89 #include "strtoofft.h"
94 #define _MPRINTF_REPLACE /* use our functions only */
95 #include <curl/mprintf.h>
97 #include "curl_memory.h"
98 /* The last #include file should be: */
103 # define PATH_MAX MAX_PATH
107 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
108 have their definition hidden well */
111 #define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
113 #define sftp_libssh2_realpath(s,p,t,m) \
114 libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
115 (t), (m), LIBSSH2_SFTP_REALPATH)
117 /* Local functions: */
118 static const char *sftp_libssh2_strerror(int err);
119 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
120 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
121 static LIBSSH2_FREE_FUNC(my_libssh2_free);
123 static CURLcode get_pathname(const char **cpp, char **path);
125 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
126 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
127 static CURLcode ssh_do(struct connectdata *conn, bool *done);
129 static CURLcode ssh_getworkingpath(struct connectdata *conn,
130 char *homedir, /* when SFTP is used */
133 static CURLcode scp_done(struct connectdata *conn,
134 CURLcode, bool premature);
135 static CURLcode scp_doing(struct connectdata *conn,
137 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
139 static CURLcode sftp_done(struct connectdata *conn,
140 CURLcode, bool premature);
141 static CURLcode sftp_doing(struct connectdata *conn,
143 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
145 CURLcode sftp_perform(struct connectdata *conn,
149 static int ssh_getsock(struct connectdata *conn,
150 curl_socket_t *sock, /* points to numsocks number
154 static int ssh_perform_getsock(const struct connectdata *conn,
155 curl_socket_t *sock, /* points to numsocks
160 * SCP protocol handler.
163 const struct Curl_handler Curl_handler_scp = {
165 ZERO_NULL, /* setup_connection */
168 ZERO_NULL, /* do_more */
169 ssh_connect, /* connect_it */
170 ssh_multi_statemach, /* connecting */
171 scp_doing, /* doing */
172 ssh_getsock, /* proto_getsock */
173 ssh_getsock, /* doing_getsock */
174 ZERO_NULL, /* domore_getsock */
175 ssh_perform_getsock, /* perform_getsock */
176 scp_disconnect, /* disconnect */
177 ZERO_NULL, /* readwrite */
178 PORT_SSH, /* defport */
179 CURLPROTO_SCP, /* protocol */
180 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
181 | PROTOPT_NOURLQUERY /* flags */
186 * SFTP protocol handler.
189 const struct Curl_handler Curl_handler_sftp = {
191 ZERO_NULL, /* setup_connection */
193 sftp_done, /* done */
194 ZERO_NULL, /* do_more */
195 ssh_connect, /* connect_it */
196 ssh_multi_statemach, /* connecting */
197 sftp_doing, /* doing */
198 ssh_getsock, /* proto_getsock */
199 ssh_getsock, /* doing_getsock */
200 ZERO_NULL, /* domore_getsock */
201 ssh_perform_getsock, /* perform_getsock */
202 sftp_disconnect, /* disconnect */
203 ZERO_NULL, /* readwrite */
204 PORT_SSH, /* defport */
205 CURLPROTO_SFTP, /* protocol */
206 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
207 | PROTOPT_NOURLQUERY /* flags */
212 kbd_callback(const char *name, int name_len, const char *instruction,
213 int instruction_len, int num_prompts,
214 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
215 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
218 struct connectdata *conn = (struct connectdata *)*abstract;
220 #ifdef CURL_LIBSSH2_DEBUG
221 fprintf(stderr, "name=%s\n", name);
222 fprintf(stderr, "name_len=%d\n", name_len);
223 fprintf(stderr, "instruction=%s\n", instruction);
224 fprintf(stderr, "instruction_len=%d\n", instruction_len);
225 fprintf(stderr, "num_prompts=%d\n", num_prompts);
230 (void)instruction_len;
231 #endif /* CURL_LIBSSH2_DEBUG */
232 if(num_prompts == 1) {
233 responses[0].text = strdup(conn->passwd);
234 responses[0].length = curlx_uztoui(strlen(conn->passwd));
240 static CURLcode sftp_libssh2_error_to_CURLE(int err)
246 case LIBSSH2_FX_NO_SUCH_FILE:
247 case LIBSSH2_FX_NO_SUCH_PATH:
248 return CURLE_REMOTE_FILE_NOT_FOUND;
250 case LIBSSH2_FX_PERMISSION_DENIED:
251 case LIBSSH2_FX_WRITE_PROTECT:
252 case LIBSSH2_FX_LOCK_CONFlICT:
253 return CURLE_REMOTE_ACCESS_DENIED;
255 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
256 case LIBSSH2_FX_QUOTA_EXCEEDED:
257 return CURLE_REMOTE_DISK_FULL;
259 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
260 return CURLE_REMOTE_FILE_EXISTS;
262 case LIBSSH2_FX_DIR_NOT_EMPTY:
263 return CURLE_QUOTE_ERROR;
272 static CURLcode libssh2_session_error_to_CURLE(int err)
275 /* Ordered by order of appearance in libssh2.h */
276 case LIBSSH2_ERROR_NONE:
279 case LIBSSH2_ERROR_SOCKET_NONE:
280 return CURLE_COULDNT_CONNECT;
282 case LIBSSH2_ERROR_ALLOC:
283 return CURLE_OUT_OF_MEMORY;
285 case LIBSSH2_ERROR_SOCKET_SEND:
286 return CURLE_SEND_ERROR;
288 case LIBSSH2_ERROR_HOSTKEY_INIT:
289 case LIBSSH2_ERROR_HOSTKEY_SIGN:
290 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
291 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
292 return CURLE_PEER_FAILED_VERIFICATION;
294 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
295 return CURLE_LOGIN_DENIED;
297 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
298 case LIBSSH2_ERROR_TIMEOUT:
299 return CURLE_OPERATION_TIMEDOUT;
301 case LIBSSH2_ERROR_EAGAIN:
305 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
306 error code, and possibly add a few new SSH-related one. We must however
307 not return or even depend on libssh2 errors in the public libcurl API */
312 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
314 (void)abstract; /* arg not used */
315 return malloc(count);
318 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
320 (void)abstract; /* arg not used */
321 return realloc(ptr, count);
324 static LIBSSH2_FREE_FUNC(my_libssh2_free)
326 (void)abstract; /* arg not used */
327 if(ptr) /* ssh2 agent sometimes call free with null ptr */
332 * SSH State machine related code
334 /* This is the ONLY way to change SSH state! */
335 static void state(struct connectdata *conn, sshstate nowstate)
337 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
338 /* for debug purposes */
339 static const char * const names[] = {
345 "SSH_AUTH_PKEY_INIT",
347 "SSH_AUTH_PASS_INIT",
349 "SSH_AUTH_AGENT_INIT",
350 "SSH_AUTH_AGENT_LIST",
352 "SSH_AUTH_HOST_INIT",
359 "SSH_SFTP_QUOTE_INIT",
360 "SSH_SFTP_POSTQUOTE_INIT",
362 "SSH_SFTP_NEXT_QUOTE",
363 "SSH_SFTP_QUOTE_STAT",
364 "SSH_SFTP_QUOTE_SETSTAT",
365 "SSH_SFTP_QUOTE_SYMLINK",
366 "SSH_SFTP_QUOTE_MKDIR",
367 "SSH_SFTP_QUOTE_RENAME",
368 "SSH_SFTP_QUOTE_RMDIR",
369 "SSH_SFTP_QUOTE_UNLINK",
370 "SSH_SFTP_TRANS_INIT",
371 "SSH_SFTP_UPLOAD_INIT",
372 "SSH_SFTP_CREATE_DIRS_INIT",
373 "SSH_SFTP_CREATE_DIRS",
374 "SSH_SFTP_CREATE_DIRS_MKDIR",
375 "SSH_SFTP_READDIR_INIT",
377 "SSH_SFTP_READDIR_LINK",
378 "SSH_SFTP_READDIR_BOTTOM",
379 "SSH_SFTP_READDIR_DONE",
380 "SSH_SFTP_DOWNLOAD_INIT",
381 "SSH_SFTP_DOWNLOAD_STAT",
384 "SSH_SCP_TRANS_INIT",
385 "SSH_SCP_UPLOAD_INIT",
386 "SSH_SCP_DOWNLOAD_INIT",
390 "SSH_SCP_WAIT_CLOSE",
391 "SSH_SCP_CHANNEL_FREE",
392 "SSH_SESSION_DISCONNECT",
397 struct ssh_conn *sshc = &conn->proto.sshc;
399 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
400 if(sshc->state != nowstate) {
401 infof(conn->data, "SFTP %p state change from %s to %s\n",
402 sshc, names[sshc->state], names[nowstate]);
406 sshc->state = nowstate;
409 /* figure out the path to work with in this particular request */
410 static CURLcode ssh_getworkingpath(struct connectdata *conn,
411 char *homedir, /* when SFTP is used */
412 char **path) /* returns the allocated
413 real path to work with */
415 struct SessionHandle *data = conn->data;
416 char *real_path = NULL;
418 int working_path_len;
420 working_path = curl_easy_unescape(data, data->state.path, 0,
423 return CURLE_OUT_OF_MEMORY;
425 /* Check for /~/ , indicating relative to the user's home directory */
426 if(conn->handler->protocol & CURLPROTO_SCP) {
427 real_path = malloc(working_path_len+1);
428 if(real_path == NULL) {
430 return CURLE_OUT_OF_MEMORY;
432 if((working_path_len > 1) && (working_path[1] == '~'))
433 /* It is referenced to the home directory, so strip the leading '/' */
434 memcpy(real_path, working_path+1, 1 + working_path_len-1);
436 memcpy(real_path, working_path, 1 + working_path_len);
438 else if(conn->handler->protocol & CURLPROTO_SFTP) {
439 if((working_path_len > 1) && (working_path[1] == '~')) {
440 size_t homelen = strlen(homedir);
441 real_path = malloc(homelen + working_path_len + 1);
442 if(real_path == NULL) {
444 return CURLE_OUT_OF_MEMORY;
446 /* It is referenced to the home directory, so strip the
448 memcpy(real_path, homedir, homelen);
449 real_path[homelen] = '/';
450 real_path[homelen+1] = '\0';
451 if(working_path_len > 3) {
452 memcpy(real_path+homelen+1, working_path + 3,
453 1 + working_path_len -3);
457 real_path = malloc(working_path_len+1);
458 if(real_path == NULL) {
460 return CURLE_OUT_OF_MEMORY;
462 memcpy(real_path, working_path, 1+working_path_len);
468 /* store the pointer for the caller to receive */
474 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
475 static int sshkeycallback(CURL *easy,
476 const struct curl_khkey *knownkey, /* known */
477 const struct curl_khkey *foundkey, /* found */
478 enum curl_khmatch match,
486 /* we only allow perfect matches, and we reject everything else */
487 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
492 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
495 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
496 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
498 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
502 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
503 * architectures so we check of the necessary function is present.
505 #ifndef HAVE_LIBSSH2_SCP_SEND64
506 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
508 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
509 (libssh2_uint64_t)d, 0, 0)
513 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
515 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
516 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
519 static CURLcode ssh_knownhost(struct connectdata *conn)
521 CURLcode result = CURLE_OK;
523 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
524 struct SessionHandle *data = conn->data;
526 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
527 /* we're asked to verify the host against a file */
528 struct ssh_conn *sshc = &conn->proto.sshc;
532 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
534 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
539 * A subject to figure out is what host name we need to pass in here.
540 * What host name does OpenSSH store in its file if an IDN name is
543 struct libssh2_knownhost *host;
544 enum curl_khmatch keymatch;
545 curl_sshkeycallback func =
546 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
547 struct curl_khkey knownkey;
548 struct curl_khkey *knownkeyp = NULL;
549 struct curl_khkey foundkey;
551 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
552 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
554 keycheck = libssh2_knownhost_check(sshc->kh,
557 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
558 LIBSSH2_KNOWNHOST_KEYENC_RAW|
562 infof(data, "SSH host check: %d, key: %s\n", keycheck,
563 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
566 /* setup 'knownkey' */
567 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
568 knownkey.key = host->key;
570 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
571 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
572 knownkeyp = &knownkey;
575 /* setup 'foundkey' */
576 foundkey.key = remotekey;
577 foundkey.len = keylen;
578 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
579 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
582 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
583 * curl_khmatch enum are ever modified, we need to introduce a
584 * translation table here!
586 keymatch = (enum curl_khmatch)keycheck;
588 /* Ask the callback how to behave */
589 rc = func(data, knownkeyp, /* from the knownhosts file */
590 &foundkey, /* from the remote host */
591 keymatch, data->set.ssh_keyfunc_userp);
594 /* no remotekey means failure! */
595 rc = CURLKHSTAT_REJECT;
598 default: /* unknown return codes will equal reject */
599 case CURLKHSTAT_REJECT:
600 state(conn, SSH_SESSION_FREE);
601 case CURLKHSTAT_DEFER:
602 /* DEFER means bail out but keep the SSH_HOSTKEY state */
603 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
605 case CURLKHSTAT_FINE:
606 case CURLKHSTAT_FINE_ADD_TO_FILE:
608 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
609 /* the found host+key didn't match but has been told to be fine
610 anyway so we add it in memory */
611 int addrc = libssh2_knownhost_add(sshc->kh,
612 conn->host.name, NULL,
614 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
615 LIBSSH2_KNOWNHOST_KEYENC_RAW|
618 infof(data, "Warning adding the known host %s failed!\n",
620 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
621 /* now we write the entire in-memory list of known hosts to the
624 libssh2_knownhost_writefile(sshc->kh,
625 data->set.str[STRING_SSH_KNOWNHOSTS],
626 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
628 infof(data, "Warning, writing %s failed!\n",
629 data->set.str[STRING_SSH_KNOWNHOSTS]);
636 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
642 static CURLcode ssh_check_fingerprint(struct connectdata *conn)
644 struct ssh_conn *sshc = &conn->proto.sshc;
645 struct SessionHandle *data = conn->data;
646 const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
650 const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
651 LIBSSH2_HOSTKEY_HASH_MD5);
654 /* The fingerprint points to static storage (!), don't free() it. */
655 for(i = 0; i < 16; i++)
656 snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
657 infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
660 /* Before we authenticate we check the hostkey's MD5 fingerprint
661 * against a known fingerprint, if available.
663 if(pubkey_md5 && strlen(pubkey_md5) == 32) {
664 if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
667 "Denied establishing ssh session: mismatch md5 fingerprint. "
668 "Remote %s is not equal to %s", md5buffer, pubkey_md5);
671 "Denied establishing ssh session: md5 fingerprint not available");
672 state(conn, SSH_SESSION_FREE);
673 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
674 return sshc->actualcode;
677 infof(data, "MD5 checksum match!\n");
678 /* as we already matched, we skip the check for known hosts */
683 return ssh_knownhost(conn);
687 * ssh_statemach_act() runs the SSH state machine as far as it can without
688 * blocking and without reaching the end. The data the pointer 'block' points
689 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
690 * meaning it wants to be called again when the socket is ready
693 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
695 CURLcode result = CURLE_OK;
696 struct SessionHandle *data = conn->data;
697 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
698 struct ssh_conn *sshc = &conn->proto.sshc;
699 curl_socket_t sock = conn->sock[FIRSTSOCKET];
700 char *new_readdir_line;
701 int rc = LIBSSH2_ERROR_NONE;
703 int seekerr = CURL_SEEKFUNC_OK;
704 *block = 0; /* we're not blocking by default */
708 switch(sshc->state) {
710 sshc->secondCreateDirs = 0;
711 sshc->nextstate = SSH_NO_STATE;
712 sshc->actualcode = CURLE_OK;
714 /* Set libssh2 to non-blocking, since everything internally is
716 libssh2_session_set_blocking(sshc->ssh_session, 0);
718 state(conn, SSH_S_STARTUP);
722 rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
723 if(rc == LIBSSH2_ERROR_EAGAIN) {
727 failf(data, "Failure establishing ssh session");
728 state(conn, SSH_SESSION_FREE);
729 sshc->actualcode = CURLE_FAILED_INIT;
733 state(conn, SSH_HOSTKEY);
738 * Before we authenticate we should check the hostkey's fingerprint
739 * against our known hosts. How that is handled (reading from file,
740 * whatever) is up to us.
742 result = ssh_check_fingerprint(conn);
743 if(result == CURLE_OK)
744 state(conn, SSH_AUTHLIST);
749 * Figure out authentication methods
750 * NB: As soon as we have provided a username to an openssh server we
751 * must never change it later. Thus, always specify the correct username
752 * here, even though the libssh2 docs kind of indicate that it should be
753 * possible to get a 'generic' list (not user-specific) of authentication
754 * methods, presumably with a blank username. That won't work in my
756 * So always specify it here.
758 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
760 curlx_uztoui(strlen(conn->user)));
762 if(!sshc->authlist) {
763 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
764 LIBSSH2_ERROR_EAGAIN) {
765 rc = LIBSSH2_ERROR_EAGAIN;
769 state(conn, SSH_SESSION_FREE);
770 sshc->actualcode = libssh2_session_error_to_CURLE(err);
774 infof(data, "SSH authentication methods available: %s\n",
777 state(conn, SSH_AUTH_PKEY_INIT);
780 case SSH_AUTH_PKEY_INIT:
782 * Check the supported auth types in the order I feel is most secure
783 * with the requested type of authentication
785 sshc->authed = FALSE;
787 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
788 (strstr(sshc->authlist, "publickey") != NULL)) {
790 bool rsa_pub_empty_but_ok = FALSE;
792 sshc->rsa_pub = sshc->rsa = NULL;
794 /* To ponder about: should really the lib be messing about with the
795 HOME environment variable etc? */
796 home = curl_getenv("HOME");
798 if(data->set.str[STRING_SSH_PUBLIC_KEY] &&
799 !*data->set.str[STRING_SSH_PUBLIC_KEY])
800 rsa_pub_empty_but_ok = true;
801 else if(data->set.str[STRING_SSH_PUBLIC_KEY])
802 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
804 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
806 /* as a final resort, try current dir! */
807 sshc->rsa_pub = strdup("id_dsa.pub");
809 if(!rsa_pub_empty_but_ok && (sshc->rsa_pub == NULL)) {
811 state(conn, SSH_SESSION_FREE);
812 sshc->actualcode = CURLE_OUT_OF_MEMORY;
816 if(data->set.str[STRING_SSH_PRIVATE_KEY])
817 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
819 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
821 /* as a final resort, try current dir! */
822 sshc->rsa = strdup("id_dsa");
824 if(sshc->rsa == NULL) {
826 Curl_safefree(sshc->rsa_pub);
827 state(conn, SSH_SESSION_FREE);
828 sshc->actualcode = CURLE_OUT_OF_MEMORY;
832 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
833 if(!sshc->passphrase)
834 sshc->passphrase = "";
838 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
839 infof(data, "Using ssh private key file %s\n", sshc->rsa);
841 state(conn, SSH_AUTH_PKEY);
844 state(conn, SSH_AUTH_PASS_INIT);
849 /* The function below checks if the files exists, no need to stat() here.
851 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
856 sshc->rsa, sshc->passphrase);
857 if(rc == LIBSSH2_ERROR_EAGAIN) {
861 Curl_safefree(sshc->rsa_pub);
862 Curl_safefree(sshc->rsa);
866 infof(data, "Initialized SSH public key authentication\n");
867 state(conn, SSH_AUTH_DONE);
871 (void)libssh2_session_last_error(sshc->ssh_session,
873 infof(data, "SSH public key authentication failed: %s\n", err_msg);
874 state(conn, SSH_AUTH_PASS_INIT);
878 case SSH_AUTH_PASS_INIT:
879 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
880 (strstr(sshc->authlist, "password") != NULL)) {
881 state(conn, SSH_AUTH_PASS);
884 state(conn, SSH_AUTH_HOST_INIT);
889 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
890 curlx_uztoui(strlen(conn->user)),
892 curlx_uztoui(strlen(conn->passwd)),
894 if(rc == LIBSSH2_ERROR_EAGAIN) {
899 infof(data, "Initialized password authentication\n");
900 state(conn, SSH_AUTH_DONE);
903 state(conn, SSH_AUTH_HOST_INIT);
907 case SSH_AUTH_HOST_INIT:
908 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
909 (strstr(sshc->authlist, "hostbased") != NULL)) {
910 state(conn, SSH_AUTH_HOST);
913 state(conn, SSH_AUTH_AGENT_INIT);
918 state(conn, SSH_AUTH_AGENT_INIT);
921 case SSH_AUTH_AGENT_INIT:
922 #ifdef HAVE_LIBSSH2_AGENT_API
923 if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
924 && (strstr(sshc->authlist, "publickey") != NULL)) {
926 /* Connect to the ssh-agent */
927 /* The agent could be shared by a curl thread i believe
928 but nothing obvious as keys can be added/removed at any time */
929 if(!sshc->ssh_agent) {
930 sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
931 if(!sshc->ssh_agent) {
932 infof(data, "Could not create agent object\n");
934 state(conn, SSH_AUTH_KEY_INIT);
938 rc = libssh2_agent_connect(sshc->ssh_agent);
939 if(rc == LIBSSH2_ERROR_EAGAIN)
942 infof(data, "Failure connecting to agent\n");
943 state(conn, SSH_AUTH_KEY_INIT);
946 state(conn, SSH_AUTH_AGENT_LIST);
950 #endif /* HAVE_LIBSSH2_AGENT_API */
951 state(conn, SSH_AUTH_KEY_INIT);
954 case SSH_AUTH_AGENT_LIST:
955 #ifdef HAVE_LIBSSH2_AGENT_API
956 rc = libssh2_agent_list_identities(sshc->ssh_agent);
958 if(rc == LIBSSH2_ERROR_EAGAIN)
961 infof(data, "Failure requesting identities to agent\n");
962 state(conn, SSH_AUTH_KEY_INIT);
965 state(conn, SSH_AUTH_AGENT);
966 sshc->sshagent_prev_identity = NULL;
972 #ifdef HAVE_LIBSSH2_AGENT_API
973 /* as prev_identity evolves only after an identity user auth finished we
974 can safely request it again as long as EAGAIN is returned here or by
975 libssh2_agent_userauth */
976 rc = libssh2_agent_get_identity(sshc->ssh_agent,
977 &sshc->sshagent_identity,
978 sshc->sshagent_prev_identity);
979 if(rc == LIBSSH2_ERROR_EAGAIN)
983 rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
984 sshc->sshagent_identity);
987 if(rc != LIBSSH2_ERROR_EAGAIN) {
988 /* tried and failed? go to next identity */
989 sshc->sshagent_prev_identity = sshc->sshagent_identity;
996 infof(data, "Failure requesting identities to agent\n");
998 infof(data, "No identity would match\n");
1000 if(rc == LIBSSH2_ERROR_NONE) {
1001 sshc->authed = TRUE;
1002 infof(data, "Agent based authentication successful\n");
1003 state(conn, SSH_AUTH_DONE);
1006 state(conn, SSH_AUTH_KEY_INIT);
1010 case SSH_AUTH_KEY_INIT:
1011 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
1012 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
1013 state(conn, SSH_AUTH_KEY);
1016 state(conn, SSH_AUTH_DONE);
1021 /* Authentication failed. Continue with keyboard-interactive now. */
1022 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
1025 strlen(conn->user)),
1027 if(rc == LIBSSH2_ERROR_EAGAIN) {
1031 sshc->authed = TRUE;
1032 infof(data, "Initialized keyboard interactive authentication\n");
1034 state(conn, SSH_AUTH_DONE);
1039 failf(data, "Authentication failure");
1040 state(conn, SSH_SESSION_FREE);
1041 sshc->actualcode = CURLE_LOGIN_DENIED;
1046 * At this point we have an authenticated ssh session.
1048 infof(data, "Authentication complete\n");
1050 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
1052 conn->sockfd = sock;
1053 conn->writesockfd = CURL_SOCKET_BAD;
1055 if(conn->handler->protocol == CURLPROTO_SFTP) {
1056 state(conn, SSH_SFTP_INIT);
1059 infof(data, "SSH CONNECT phase done\n");
1060 state(conn, SSH_STOP);
1065 * Start the libssh2 sftp session
1067 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
1068 if(!sshc->sftp_session) {
1069 if(libssh2_session_last_errno(sshc->ssh_session) ==
1070 LIBSSH2_ERROR_EAGAIN) {
1071 rc = LIBSSH2_ERROR_EAGAIN;
1077 (void)libssh2_session_last_error(sshc->ssh_session,
1079 failf(data, "Failure initializing sftp session: %s", err_msg);
1080 state(conn, SSH_SESSION_FREE);
1081 sshc->actualcode = CURLE_FAILED_INIT;
1085 state(conn, SSH_SFTP_REALPATH);
1088 case SSH_SFTP_REALPATH:
1090 char tempHome[PATH_MAX];
1093 * Get the "home" directory
1095 rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
1096 tempHome, PATH_MAX-1);
1097 if(rc == LIBSSH2_ERROR_EAGAIN) {
1101 /* It seems that this string is not always NULL terminated */
1102 tempHome[rc] = '\0';
1103 sshc->homedir = strdup(tempHome);
1104 if(!sshc->homedir) {
1105 state(conn, SSH_SFTP_CLOSE);
1106 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1109 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1112 /* Return the error type */
1113 err = sftp_libssh2_last_error(sshc->sftp_session);
1114 result = sftp_libssh2_error_to_CURLE(err);
1115 sshc->actualcode = result?result:CURLE_SSH;
1116 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1118 state(conn, SSH_STOP);
1122 /* This is the last step in the SFTP connect phase. Do note that while
1123 we get the homedir here, we get the "workingpath" in the DO action
1124 since the homedir will remain the same between request but the
1125 working path will not. */
1126 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1127 state(conn, SSH_STOP);
1130 case SSH_SFTP_QUOTE_INIT:
1132 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1134 sshc->actualcode = result;
1135 state(conn, SSH_STOP);
1139 if(data->set.quote) {
1140 infof(data, "Sending quote commands\n");
1141 sshc->quote_item = data->set.quote;
1142 state(conn, SSH_SFTP_QUOTE);
1145 state(conn, SSH_SFTP_TRANS_INIT);
1149 case SSH_SFTP_POSTQUOTE_INIT:
1150 if(data->set.postquote) {
1151 infof(data, "Sending quote commands\n");
1152 sshc->quote_item = data->set.postquote;
1153 state(conn, SSH_SFTP_QUOTE);
1156 state(conn, SSH_STOP);
1160 case SSH_SFTP_QUOTE:
1161 /* Send any quote commands */
1166 * Support some of the "FTP" commands
1168 char *cmd = sshc->quote_item->data;
1169 sshc->acceptfail = FALSE;
1171 /* if a command starts with an asterisk, which a legal SFTP command never
1172 can, the command will be allowed to fail without it causing any
1173 aborts or cancels etc. It will cause libcurl to act as if the command
1174 is successful, whatever the server reponds. */
1178 sshc->acceptfail = TRUE;
1181 if(curl_strequal("pwd", cmd)) {
1182 /* output debug output if that is requested */
1183 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1186 result = CURLE_OUT_OF_MEMORY;
1187 state(conn, SSH_SFTP_CLOSE);
1188 sshc->nextstate = SSH_NO_STATE;
1191 if(data->set.verbose) {
1192 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1193 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1195 /* this sends an FTP-like "header" to the header callback so that the
1196 current directory can be read very similar to how it is read when
1197 using ordinary FTP. */
1198 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1200 state(conn, SSH_SFTP_NEXT_QUOTE);
1205 * the arguments following the command must be separated from the
1206 * command with a space so we can check for it unconditionally
1208 cp = strchr(cmd, ' ');
1210 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1211 state(conn, SSH_SFTP_CLOSE);
1212 sshc->nextstate = SSH_NO_STATE;
1213 sshc->actualcode = CURLE_QUOTE_ERROR;
1218 * also, every command takes at least one argument so we get that
1219 * first argument right now
1221 result = get_pathname(&cp, &sshc->quote_path1);
1223 if(result == CURLE_OUT_OF_MEMORY)
1224 failf(data, "Out of memory");
1226 failf(data, "Syntax error: Bad first parameter");
1227 state(conn, SSH_SFTP_CLOSE);
1228 sshc->nextstate = SSH_NO_STATE;
1229 sshc->actualcode = result;
1234 * SFTP is a binary protocol, so we don't send text commands to
1235 * the server. Instead, we scan for commands for commands used by
1236 * OpenSSH's sftp program and call the appropriate libssh2
1239 if(curl_strnequal(cmd, "chgrp ", 6) ||
1240 curl_strnequal(cmd, "chmod ", 6) ||
1241 curl_strnequal(cmd, "chown ", 6) ) {
1242 /* attribute change */
1244 /* sshc->quote_path1 contains the mode to set */
1245 /* get the destination */
1246 result = get_pathname(&cp, &sshc->quote_path2);
1248 if(result == CURLE_OUT_OF_MEMORY)
1249 failf(data, "Out of memory");
1251 failf(data, "Syntax error in chgrp/chmod/chown: "
1252 "Bad second parameter");
1253 Curl_safefree(sshc->quote_path1);
1254 state(conn, SSH_SFTP_CLOSE);
1255 sshc->nextstate = SSH_NO_STATE;
1256 sshc->actualcode = result;
1259 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1260 state(conn, SSH_SFTP_QUOTE_STAT);
1263 else if(curl_strnequal(cmd, "ln ", 3) ||
1264 curl_strnequal(cmd, "symlink ", 8)) {
1265 /* symbolic linking */
1266 /* sshc->quote_path1 is the source */
1267 /* get the destination */
1268 result = get_pathname(&cp, &sshc->quote_path2);
1270 if(result == CURLE_OUT_OF_MEMORY)
1271 failf(data, "Out of memory");
1274 "Syntax error in ln/symlink: Bad second parameter");
1275 Curl_safefree(sshc->quote_path1);
1276 state(conn, SSH_SFTP_CLOSE);
1277 sshc->nextstate = SSH_NO_STATE;
1278 sshc->actualcode = result;
1281 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1284 else if(curl_strnequal(cmd, "mkdir ", 6)) {
1286 state(conn, SSH_SFTP_QUOTE_MKDIR);
1289 else if(curl_strnequal(cmd, "rename ", 7)) {
1291 /* first param is the source path */
1292 /* second param is the dest. path */
1293 result = get_pathname(&cp, &sshc->quote_path2);
1295 if(result == CURLE_OUT_OF_MEMORY)
1296 failf(data, "Out of memory");
1298 failf(data, "Syntax error in rename: Bad second parameter");
1299 Curl_safefree(sshc->quote_path1);
1300 state(conn, SSH_SFTP_CLOSE);
1301 sshc->nextstate = SSH_NO_STATE;
1302 sshc->actualcode = result;
1305 state(conn, SSH_SFTP_QUOTE_RENAME);
1308 else if(curl_strnequal(cmd, "rmdir ", 6)) {
1310 state(conn, SSH_SFTP_QUOTE_RMDIR);
1313 else if(curl_strnequal(cmd, "rm ", 3)) {
1314 state(conn, SSH_SFTP_QUOTE_UNLINK);
1318 failf(data, "Unknown SFTP command");
1319 Curl_safefree(sshc->quote_path1);
1320 Curl_safefree(sshc->quote_path2);
1321 state(conn, SSH_SFTP_CLOSE);
1322 sshc->nextstate = SSH_NO_STATE;
1323 sshc->actualcode = CURLE_QUOTE_ERROR;
1327 if(!sshc->quote_item) {
1328 state(conn, SSH_SFTP_TRANS_INIT);
1332 case SSH_SFTP_NEXT_QUOTE:
1333 Curl_safefree(sshc->quote_path1);
1334 Curl_safefree(sshc->quote_path2);
1336 sshc->quote_item = sshc->quote_item->next;
1338 if(sshc->quote_item) {
1339 state(conn, SSH_SFTP_QUOTE);
1342 if(sshc->nextstate != SSH_NO_STATE) {
1343 state(conn, sshc->nextstate);
1344 sshc->nextstate = SSH_NO_STATE;
1347 state(conn, SSH_SFTP_TRANS_INIT);
1352 case SSH_SFTP_QUOTE_STAT:
1354 char *cmd = sshc->quote_item->data;
1355 sshc->acceptfail = FALSE;
1357 /* if a command starts with an asterisk, which a legal SFTP command never
1358 can, the command will be allowed to fail without it causing any
1359 aborts or cancels etc. It will cause libcurl to act as if the command
1360 is successful, whatever the server reponds. */
1364 sshc->acceptfail = TRUE;
1367 if(!curl_strnequal(cmd, "chmod", 5)) {
1368 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1369 * set them both at once, we need to obtain the current ownership
1370 * first. This takes an extra protocol round trip.
1372 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1373 curlx_uztoui(strlen(sshc->quote_path2)),
1375 &sshc->quote_attrs);
1376 if(rc == LIBSSH2_ERROR_EAGAIN) {
1379 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1380 err = sftp_libssh2_last_error(sshc->sftp_session);
1381 Curl_safefree(sshc->quote_path1);
1382 Curl_safefree(sshc->quote_path2);
1383 failf(data, "Attempt to get SFTP stats failed: %s",
1384 sftp_libssh2_strerror(err));
1385 state(conn, SSH_SFTP_CLOSE);
1386 sshc->nextstate = SSH_NO_STATE;
1387 sshc->actualcode = CURLE_QUOTE_ERROR;
1392 /* Now set the new attributes... */
1393 if(curl_strnequal(cmd, "chgrp", 5)) {
1394 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1395 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1396 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1397 !sshc->acceptfail) {
1398 Curl_safefree(sshc->quote_path1);
1399 Curl_safefree(sshc->quote_path2);
1400 failf(data, "Syntax error: chgrp gid not a number");
1401 state(conn, SSH_SFTP_CLOSE);
1402 sshc->nextstate = SSH_NO_STATE;
1403 sshc->actualcode = CURLE_QUOTE_ERROR;
1407 else if(curl_strnequal(cmd, "chmod", 5)) {
1408 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1409 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1410 /* permissions are octal */
1411 if(sshc->quote_attrs.permissions == 0 &&
1412 !ISDIGIT(sshc->quote_path1[0])) {
1413 Curl_safefree(sshc->quote_path1);
1414 Curl_safefree(sshc->quote_path2);
1415 failf(data, "Syntax error: chmod permissions not a number");
1416 state(conn, SSH_SFTP_CLOSE);
1417 sshc->nextstate = SSH_NO_STATE;
1418 sshc->actualcode = CURLE_QUOTE_ERROR;
1422 else if(curl_strnequal(cmd, "chown", 5)) {
1423 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1424 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1425 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1426 !sshc->acceptfail) {
1427 Curl_safefree(sshc->quote_path1);
1428 Curl_safefree(sshc->quote_path2);
1429 failf(data, "Syntax error: chown uid not a number");
1430 state(conn, SSH_SFTP_CLOSE);
1431 sshc->nextstate = SSH_NO_STATE;
1432 sshc->actualcode = CURLE_QUOTE_ERROR;
1437 /* Now send the completed structure... */
1438 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1442 case SSH_SFTP_QUOTE_SETSTAT:
1443 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1444 curlx_uztoui(strlen(sshc->quote_path2)),
1445 LIBSSH2_SFTP_SETSTAT,
1446 &sshc->quote_attrs);
1447 if(rc == LIBSSH2_ERROR_EAGAIN) {
1450 else if(rc != 0 && !sshc->acceptfail) {
1451 err = sftp_libssh2_last_error(sshc->sftp_session);
1452 Curl_safefree(sshc->quote_path1);
1453 Curl_safefree(sshc->quote_path2);
1454 failf(data, "Attempt to set SFTP stats failed: %s",
1455 sftp_libssh2_strerror(err));
1456 state(conn, SSH_SFTP_CLOSE);
1457 sshc->nextstate = SSH_NO_STATE;
1458 sshc->actualcode = CURLE_QUOTE_ERROR;
1461 state(conn, SSH_SFTP_NEXT_QUOTE);
1464 case SSH_SFTP_QUOTE_SYMLINK:
1465 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1466 curlx_uztoui(strlen(sshc->quote_path1)),
1468 curlx_uztoui(strlen(sshc->quote_path2)),
1469 LIBSSH2_SFTP_SYMLINK);
1470 if(rc == LIBSSH2_ERROR_EAGAIN) {
1473 else if(rc != 0 && !sshc->acceptfail) {
1474 err = sftp_libssh2_last_error(sshc->sftp_session);
1475 Curl_safefree(sshc->quote_path1);
1476 Curl_safefree(sshc->quote_path2);
1477 failf(data, "symlink command failed: %s",
1478 sftp_libssh2_strerror(err));
1479 state(conn, SSH_SFTP_CLOSE);
1480 sshc->nextstate = SSH_NO_STATE;
1481 sshc->actualcode = CURLE_QUOTE_ERROR;
1484 state(conn, SSH_SFTP_NEXT_QUOTE);
1487 case SSH_SFTP_QUOTE_MKDIR:
1488 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1489 curlx_uztoui(strlen(sshc->quote_path1)),
1490 data->set.new_directory_perms);
1491 if(rc == LIBSSH2_ERROR_EAGAIN) {
1494 else if(rc != 0 && !sshc->acceptfail) {
1495 err = sftp_libssh2_last_error(sshc->sftp_session);
1496 Curl_safefree(sshc->quote_path1);
1497 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1498 state(conn, SSH_SFTP_CLOSE);
1499 sshc->nextstate = SSH_NO_STATE;
1500 sshc->actualcode = CURLE_QUOTE_ERROR;
1503 state(conn, SSH_SFTP_NEXT_QUOTE);
1506 case SSH_SFTP_QUOTE_RENAME:
1507 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1508 curlx_uztoui(strlen(sshc->quote_path1)),
1510 curlx_uztoui(strlen(sshc->quote_path2)),
1511 LIBSSH2_SFTP_RENAME_OVERWRITE |
1512 LIBSSH2_SFTP_RENAME_ATOMIC |
1513 LIBSSH2_SFTP_RENAME_NATIVE);
1515 if(rc == LIBSSH2_ERROR_EAGAIN) {
1518 else if(rc != 0 && !sshc->acceptfail) {
1519 err = sftp_libssh2_last_error(sshc->sftp_session);
1520 Curl_safefree(sshc->quote_path1);
1521 Curl_safefree(sshc->quote_path2);
1522 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1523 state(conn, SSH_SFTP_CLOSE);
1524 sshc->nextstate = SSH_NO_STATE;
1525 sshc->actualcode = CURLE_QUOTE_ERROR;
1528 state(conn, SSH_SFTP_NEXT_QUOTE);
1531 case SSH_SFTP_QUOTE_RMDIR:
1532 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1533 curlx_uztoui(strlen(sshc->quote_path1)));
1534 if(rc == LIBSSH2_ERROR_EAGAIN) {
1537 else if(rc != 0 && !sshc->acceptfail) {
1538 err = sftp_libssh2_last_error(sshc->sftp_session);
1539 Curl_safefree(sshc->quote_path1);
1540 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1541 state(conn, SSH_SFTP_CLOSE);
1542 sshc->nextstate = SSH_NO_STATE;
1543 sshc->actualcode = CURLE_QUOTE_ERROR;
1546 state(conn, SSH_SFTP_NEXT_QUOTE);
1549 case SSH_SFTP_QUOTE_UNLINK:
1550 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1551 curlx_uztoui(strlen(sshc->quote_path1)));
1552 if(rc == LIBSSH2_ERROR_EAGAIN) {
1555 else if(rc != 0 && !sshc->acceptfail) {
1556 err = sftp_libssh2_last_error(sshc->sftp_session);
1557 Curl_safefree(sshc->quote_path1);
1558 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1559 state(conn, SSH_SFTP_CLOSE);
1560 sshc->nextstate = SSH_NO_STATE;
1561 sshc->actualcode = CURLE_QUOTE_ERROR;
1564 state(conn, SSH_SFTP_NEXT_QUOTE);
1567 case SSH_SFTP_TRANS_INIT:
1568 if(data->set.upload)
1569 state(conn, SSH_SFTP_UPLOAD_INIT);
1571 if(data->set.opt_no_body)
1572 state(conn, SSH_STOP);
1573 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1574 state(conn, SSH_SFTP_READDIR_INIT);
1576 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1580 case SSH_SFTP_UPLOAD_INIT:
1582 unsigned long flags;
1584 * NOTE!!! libssh2 requires that the destination path is a full path
1585 * that includes the destination file and name OR ends in a "/"
1586 * If this is not done the destination file will be named the
1587 * same name as the last directory in the path.
1590 if(data->state.resume_from != 0) {
1591 LIBSSH2_SFTP_ATTRIBUTES attrs;
1592 if(data->state.resume_from < 0) {
1593 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1594 curlx_uztoui(strlen(sftp_scp->path)),
1595 LIBSSH2_SFTP_STAT, &attrs);
1596 if(rc == LIBSSH2_ERROR_EAGAIN) {
1600 data->state.resume_from = 0;
1603 curl_off_t size = attrs.filesize;
1605 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1606 return CURLE_BAD_DOWNLOAD_RESUME;
1608 data->state.resume_from = attrs.filesize;
1613 if(data->set.ftp_append)
1614 /* Try to open for append, but create if nonexisting */
1615 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1616 else if(data->state.resume_from > 0)
1617 /* If we have restart position then open for append */
1618 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1620 /* Clear file before writing (normal behaviour) */
1621 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1624 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1625 curlx_uztoui(strlen(sftp_scp->path)),
1626 flags, data->set.new_file_perms,
1627 LIBSSH2_SFTP_OPENFILE);
1629 if(!sshc->sftp_handle) {
1630 rc = libssh2_session_last_errno(sshc->ssh_session);
1632 if(LIBSSH2_ERROR_EAGAIN == rc)
1635 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1636 /* only when there was an SFTP protocol error can we extract
1638 err = sftp_libssh2_last_error(sshc->sftp_session);
1640 err = -1; /* not an sftp error at all */
1642 if(sshc->secondCreateDirs) {
1643 state(conn, SSH_SFTP_CLOSE);
1644 sshc->actualcode = err>= LIBSSH2_FX_OK?
1645 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1646 failf(data, "Creating the dir/file failed: %s",
1647 sftp_libssh2_strerror(err));
1650 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1651 (err == LIBSSH2_FX_FAILURE) ||
1652 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1653 (data->set.ftp_create_missing_dirs &&
1654 (strlen(sftp_scp->path) > 1))) {
1655 /* try to create the path remotely */
1656 sshc->secondCreateDirs = 1;
1657 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1660 state(conn, SSH_SFTP_CLOSE);
1661 sshc->actualcode = err>= LIBSSH2_FX_OK?
1662 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1663 if(!sshc->actualcode) {
1664 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1665 zero even though libssh2_sftp_open() failed previously! We need
1666 to work around that! */
1667 sshc->actualcode = CURLE_SSH;
1670 failf(data, "Upload failed: %s (%d/%d)",
1671 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1677 /* If we have restart point then we need to seek to the correct
1679 if(data->state.resume_from > 0) {
1680 /* Let's read off the proper amount of bytes from the input. */
1681 if(conn->seek_func) {
1682 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1686 if(seekerr != CURL_SEEKFUNC_OK) {
1688 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1689 failf(data, "Could not seek stream");
1690 return CURLE_FTP_COULDNT_USE_REST;
1692 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1694 curl_off_t passed=0;
1696 size_t readthisamountnow =
1697 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1698 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1700 size_t actuallyread =
1701 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1704 passed += actuallyread;
1705 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1706 /* this checks for greater-than only to make sure that the
1707 CURL_READFUNC_ABORT return code still aborts */
1708 failf(data, "Failed to read data");
1709 return CURLE_FTP_COULDNT_USE_REST;
1711 } while(passed < data->state.resume_from);
1715 /* now, decrease the size of the read */
1716 if(data->set.infilesize > 0) {
1717 data->set.infilesize -= data->state.resume_from;
1718 data->req.size = data->set.infilesize;
1719 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1722 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1724 if(data->set.infilesize > 0) {
1725 data->req.size = data->set.infilesize;
1726 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1729 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1731 /* not set by Curl_setup_transfer to preserve keepon bits */
1732 conn->sockfd = conn->writesockfd;
1735 state(conn, SSH_SFTP_CLOSE);
1736 sshc->actualcode = result;
1739 /* store this original bitmask setup to use later on if we can't
1740 figure out a "real" bitmask */
1741 sshc->orig_waitfor = data->req.keepon;
1743 /* we want to use the _sending_ function even when the socket turns
1744 out readable as the underlying libssh2 sftp send function will deal
1745 with both accordingly */
1746 conn->cselect_bits = CURL_CSELECT_OUT;
1748 /* since we don't really wait for anything at this point, we want the
1749 state machine to move on as soon as possible so we set a very short
1751 Curl_expire(data, 1);
1753 state(conn, SSH_STOP);
1758 case SSH_SFTP_CREATE_DIRS_INIT:
1759 if(strlen(sftp_scp->path) > 1) {
1760 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1761 state(conn, SSH_SFTP_CREATE_DIRS);
1764 state(conn, SSH_SFTP_UPLOAD_INIT);
1768 case SSH_SFTP_CREATE_DIRS:
1769 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1770 *sshc->slash_pos = 0;
1772 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1773 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1777 state(conn, SSH_SFTP_UPLOAD_INIT);
1781 case SSH_SFTP_CREATE_DIRS_MKDIR:
1782 /* 'mode' - parameter is preliminary - default to 0644 */
1783 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1784 curlx_uztoui(strlen(sftp_scp->path)),
1785 data->set.new_directory_perms);
1786 if(rc == LIBSSH2_ERROR_EAGAIN) {
1789 *sshc->slash_pos = '/';
1793 * Abort if failure wasn't that the dir already exists or the
1794 * permission was denied (creation might succeed further down the
1795 * path) - retry on unspecific FAILURE also
1797 err = sftp_libssh2_last_error(sshc->sftp_session);
1798 if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1799 (err != LIBSSH2_FX_FAILURE) &&
1800 (err != LIBSSH2_FX_PERMISSION_DENIED)) {
1801 result = sftp_libssh2_error_to_CURLE(err);
1802 state(conn, SSH_SFTP_CLOSE);
1803 sshc->actualcode = result?result:CURLE_SSH;
1807 state(conn, SSH_SFTP_CREATE_DIRS);
1810 case SSH_SFTP_READDIR_INIT:
1812 * This is a directory that we are trying to get, so produce a directory
1815 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1818 strlen(sftp_scp->path)),
1819 0, 0, LIBSSH2_SFTP_OPENDIR);
1820 if(!sshc->sftp_handle) {
1821 if(libssh2_session_last_errno(sshc->ssh_session) ==
1822 LIBSSH2_ERROR_EAGAIN) {
1823 rc = LIBSSH2_ERROR_EAGAIN;
1827 err = sftp_libssh2_last_error(sshc->sftp_session);
1828 failf(data, "Could not open directory for reading: %s",
1829 sftp_libssh2_strerror(err));
1830 state(conn, SSH_SFTP_CLOSE);
1831 result = sftp_libssh2_error_to_CURLE(err);
1832 sshc->actualcode = result?result:CURLE_SSH;
1836 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1837 state(conn, SSH_SFTP_CLOSE);
1838 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1841 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1842 Curl_safefree(sshc->readdir_filename);
1843 state(conn, SSH_SFTP_CLOSE);
1844 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1847 state(conn, SSH_SFTP_READDIR);
1850 case SSH_SFTP_READDIR:
1851 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1852 sshc->readdir_filename,
1854 sshc->readdir_longentry,
1856 &sshc->readdir_attrs);
1857 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1858 rc = LIBSSH2_ERROR_EAGAIN;
1861 if(sshc->readdir_len > 0) {
1862 sshc->readdir_filename[sshc->readdir_len] = '\0';
1864 if(data->set.ftp_list_only) {
1867 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1868 if(tmpLine == NULL) {
1869 state(conn, SSH_SFTP_CLOSE);
1870 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1873 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1874 tmpLine, sshc->readdir_len+1);
1875 Curl_safefree(tmpLine);
1878 state(conn, SSH_STOP);
1881 /* since this counts what we send to the client, we include the
1882 newline in this counter */
1883 data->req.bytecount += sshc->readdir_len+1;
1885 /* output debug output if that is requested */
1886 if(data->set.verbose) {
1887 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1888 sshc->readdir_len, conn);
1892 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1893 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1894 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1895 if(!sshc->readdir_line) {
1896 Curl_safefree(sshc->readdir_filename);
1897 Curl_safefree(sshc->readdir_longentry);
1898 state(conn, SSH_SFTP_CLOSE);
1899 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1903 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1904 sshc->readdir_currLen);
1905 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1906 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1907 LIBSSH2_SFTP_S_IFLNK)) {
1908 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1909 if(sshc->readdir_linkPath == NULL) {
1910 Curl_safefree(sshc->readdir_filename);
1911 Curl_safefree(sshc->readdir_longentry);
1912 state(conn, SSH_SFTP_CLOSE);
1913 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1917 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1918 sshc->readdir_filename);
1919 state(conn, SSH_SFTP_READDIR_LINK);
1922 state(conn, SSH_SFTP_READDIR_BOTTOM);
1926 else if(sshc->readdir_len == 0) {
1927 Curl_safefree(sshc->readdir_filename);
1928 Curl_safefree(sshc->readdir_longentry);
1929 state(conn, SSH_SFTP_READDIR_DONE);
1932 else if(sshc->readdir_len <= 0) {
1933 err = sftp_libssh2_last_error(sshc->sftp_session);
1934 result = sftp_libssh2_error_to_CURLE(err);
1935 sshc->actualcode = result?result:CURLE_SSH;
1936 failf(data, "Could not open remote file for reading: %s :: %d",
1937 sftp_libssh2_strerror(err),
1938 libssh2_session_last_errno(sshc->ssh_session));
1939 Curl_safefree(sshc->readdir_filename);
1940 Curl_safefree(sshc->readdir_longentry);
1941 state(conn, SSH_SFTP_CLOSE);
1946 case SSH_SFTP_READDIR_LINK:
1948 libssh2_sftp_symlink_ex(sshc->sftp_session,
1949 sshc->readdir_linkPath,
1950 curlx_uztoui(strlen(sshc->readdir_linkPath)),
1951 sshc->readdir_filename,
1952 PATH_MAX, LIBSSH2_SFTP_READLINK);
1953 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1954 rc = LIBSSH2_ERROR_EAGAIN;
1957 Curl_safefree(sshc->readdir_linkPath);
1959 /* get room for the filename and extra output */
1960 sshc->readdir_totalLen += 4 + sshc->readdir_len;
1961 new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
1962 if(!new_readdir_line) {
1963 Curl_safefree(sshc->readdir_line);
1964 Curl_safefree(sshc->readdir_filename);
1965 Curl_safefree(sshc->readdir_longentry);
1966 state(conn, SSH_SFTP_CLOSE);
1967 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1970 sshc->readdir_line = new_readdir_line;
1972 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1973 sshc->readdir_currLen,
1974 sshc->readdir_totalLen -
1975 sshc->readdir_currLen,
1977 sshc->readdir_filename);
1979 state(conn, SSH_SFTP_READDIR_BOTTOM);
1982 case SSH_SFTP_READDIR_BOTTOM:
1983 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1984 sshc->readdir_currLen,
1985 sshc->readdir_totalLen -
1986 sshc->readdir_currLen, "\n");
1987 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1989 sshc->readdir_currLen);
1991 if(result == CURLE_OK) {
1993 /* output debug output if that is requested */
1994 if(data->set.verbose) {
1995 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1996 sshc->readdir_currLen, conn);
1998 data->req.bytecount += sshc->readdir_currLen;
2000 Curl_safefree(sshc->readdir_line);
2002 state(conn, SSH_STOP);
2005 state(conn, SSH_SFTP_READDIR);
2008 case SSH_SFTP_READDIR_DONE:
2009 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
2010 LIBSSH2_ERROR_EAGAIN) {
2011 rc = LIBSSH2_ERROR_EAGAIN;
2014 sshc->sftp_handle = NULL;
2015 Curl_safefree(sshc->readdir_filename);
2016 Curl_safefree(sshc->readdir_longentry);
2018 /* no data to transfer */
2019 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2020 state(conn, SSH_STOP);
2023 case SSH_SFTP_DOWNLOAD_INIT:
2025 * Work on getting the specified file
2028 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
2029 curlx_uztoui(strlen(sftp_scp->path)),
2030 LIBSSH2_FXF_READ, data->set.new_file_perms,
2031 LIBSSH2_SFTP_OPENFILE);
2032 if(!sshc->sftp_handle) {
2033 if(libssh2_session_last_errno(sshc->ssh_session) ==
2034 LIBSSH2_ERROR_EAGAIN) {
2035 rc = LIBSSH2_ERROR_EAGAIN;
2039 err = sftp_libssh2_last_error(sshc->sftp_session);
2040 failf(data, "Could not open remote file for reading: %s",
2041 sftp_libssh2_strerror(err));
2042 state(conn, SSH_SFTP_CLOSE);
2043 result = sftp_libssh2_error_to_CURLE(err);
2044 sshc->actualcode = result?result:CURLE_SSH;
2048 state(conn, SSH_SFTP_DOWNLOAD_STAT);
2051 case SSH_SFTP_DOWNLOAD_STAT:
2053 LIBSSH2_SFTP_ATTRIBUTES attrs;
2055 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
2056 curlx_uztoui(strlen(sftp_scp->path)),
2057 LIBSSH2_SFTP_STAT, &attrs);
2058 if(rc == LIBSSH2_ERROR_EAGAIN) {
2063 * libssh2_sftp_open() didn't return an error, so maybe the server
2064 * just doesn't support stat()
2066 data->req.size = -1;
2067 data->req.maxdownload = -1;
2070 curl_off_t size = attrs.filesize;
2073 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
2074 return CURLE_BAD_DOWNLOAD_RESUME;
2076 if(conn->data->state.use_range) {
2077 curl_off_t from, to;
2081 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2082 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2084 to=curlx_strtoofft(ptr, &ptr2, 0);
2085 if((ptr == ptr2) /* no "to" value given */
2090 /* from is relative to end of file */
2094 failf(data, "Offset (%"
2095 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2096 from, attrs.filesize);
2097 return CURLE_BAD_DOWNLOAD_RESUME;
2104 size = to - from + 1;
2107 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2109 data->req.size = size;
2110 data->req.maxdownload = size;
2111 Curl_pgrsSetDownloadSize(data, size);
2114 /* We can resume if we can seek to the resume position */
2115 if(data->state.resume_from) {
2116 if(data->state.resume_from < 0) {
2117 /* We're supposed to download the last abs(from) bytes */
2118 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2119 failf(data, "Offset (%"
2120 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2121 data->state.resume_from, attrs.filesize);
2122 return CURLE_BAD_DOWNLOAD_RESUME;
2124 /* download from where? */
2125 data->state.resume_from += attrs.filesize;
2128 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2129 failf(data, "Offset (%" FORMAT_OFF_T
2130 ") was beyond file size (%" FORMAT_OFF_T ")",
2131 data->state.resume_from, attrs.filesize);
2132 return CURLE_BAD_DOWNLOAD_RESUME;
2135 /* Does a completed file need to be seeked and started or closed ? */
2136 /* Now store the number of bytes we are expected to download */
2137 data->req.size = attrs.filesize - data->state.resume_from;
2138 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2139 Curl_pgrsSetDownloadSize(data,
2140 attrs.filesize - data->state.resume_from);
2141 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2144 /* Setup the actual download */
2145 if(data->req.size == 0) {
2146 /* no data to transfer */
2147 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2148 infof(data, "File already completely downloaded\n");
2149 state(conn, SSH_STOP);
2153 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2154 FALSE, NULL, -1, NULL);
2156 /* not set by Curl_setup_transfer to preserve keepon bits */
2157 conn->writesockfd = conn->sockfd;
2159 /* we want to use the _receiving_ function even when the socket turns
2160 out writableable as the underlying libssh2 recv function will deal
2161 with both accordingly */
2162 conn->cselect_bits = CURL_CSELECT_IN;
2165 state(conn, SSH_SFTP_CLOSE);
2166 sshc->actualcode = result;
2169 state(conn, SSH_STOP);
2173 case SSH_SFTP_CLOSE:
2174 if(sshc->sftp_handle) {
2175 rc = libssh2_sftp_close(sshc->sftp_handle);
2176 if(rc == LIBSSH2_ERROR_EAGAIN) {
2180 infof(data, "Failed to close libssh2 file\n");
2182 sshc->sftp_handle = NULL;
2185 Curl_safefree(sftp_scp->path);
2187 DEBUGF(infof(data, "SFTP DONE done\n"));
2189 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2190 After nextstate is executed,the control should come back to
2191 SSH_SFTP_CLOSE to pass the correct result back */
2192 if(sshc->nextstate != SSH_NO_STATE) {
2193 state(conn, sshc->nextstate);
2194 sshc->nextstate = SSH_SFTP_CLOSE;
2197 state(conn, SSH_STOP);
2198 result = sshc->actualcode;
2202 case SSH_SFTP_SHUTDOWN:
2203 /* during times we get here due to a broken transfer and then the
2204 sftp_handle might not have been taken down so make sure that is done
2205 before we proceed */
2207 if(sshc->sftp_handle) {
2208 rc = libssh2_sftp_close(sshc->sftp_handle);
2209 if(rc == LIBSSH2_ERROR_EAGAIN) {
2213 infof(data, "Failed to close libssh2 file\n");
2215 sshc->sftp_handle = NULL;
2217 if(sshc->sftp_session) {
2218 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2219 if(rc == LIBSSH2_ERROR_EAGAIN) {
2223 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2225 sshc->sftp_session = NULL;
2228 Curl_safefree(sshc->homedir);
2229 conn->data->state.most_recent_ftp_entrypath = NULL;
2231 state(conn, SSH_SESSION_DISCONNECT);
2234 case SSH_SCP_TRANS_INIT:
2235 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2237 sshc->actualcode = result;
2238 state(conn, SSH_STOP);
2242 if(data->set.upload) {
2243 if(data->set.infilesize < 0) {
2244 failf(data, "SCP requires a known file size for upload");
2245 sshc->actualcode = CURLE_UPLOAD_FAILED;
2246 state(conn, SSH_SCP_CHANNEL_FREE);
2249 state(conn, SSH_SCP_UPLOAD_INIT);
2252 state(conn, SSH_SCP_DOWNLOAD_INIT);
2256 case SSH_SCP_UPLOAD_INIT:
2258 * libssh2 requires that the destination path is a full path that
2259 * includes the destination file and name OR ends in a "/" . If this is
2260 * not done the destination file will be named the same name as the last
2261 * directory in the path.
2264 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2265 data->set.infilesize);
2266 if(!sshc->ssh_channel) {
2267 if(libssh2_session_last_errno(sshc->ssh_session) ==
2268 LIBSSH2_ERROR_EAGAIN) {
2269 rc = LIBSSH2_ERROR_EAGAIN;
2276 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2277 &err_msg, NULL, 0));
2278 failf(conn->data, "%s", err_msg);
2279 state(conn, SSH_SCP_CHANNEL_FREE);
2280 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2286 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2289 /* not set by Curl_setup_transfer to preserve keepon bits */
2290 conn->sockfd = conn->writesockfd;
2293 state(conn, SSH_SCP_CHANNEL_FREE);
2294 sshc->actualcode = result;
2297 /* we want to use the _sending_ function even when the socket turns
2298 out readable as the underlying libssh2 scp send function will deal
2299 with both accordingly */
2300 conn->cselect_bits = CURL_CSELECT_OUT;
2302 state(conn, SSH_STOP);
2306 case SSH_SCP_DOWNLOAD_INIT:
2309 * We must check the remote file; if it is a directory no values will
2313 curl_off_t bytecount;
2315 /* clear the struct scp recv will fill in */
2316 memset(&sb, 0, sizeof(struct stat));
2318 /* get a fresh new channel from the ssh layer */
2319 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2320 sftp_scp->path, &sb);
2321 if(!sshc->ssh_channel) {
2322 if(libssh2_session_last_errno(sshc->ssh_session) ==
2323 LIBSSH2_ERROR_EAGAIN) {
2324 rc = LIBSSH2_ERROR_EAGAIN;
2331 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2332 &err_msg, NULL, 0));
2333 failf(conn->data, "%s", err_msg);
2334 state(conn, SSH_SCP_CHANNEL_FREE);
2335 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2341 bytecount = (curl_off_t)sb.st_size;
2342 data->req.maxdownload = (curl_off_t)sb.st_size;
2343 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2345 /* not set by Curl_setup_transfer to preserve keepon bits */
2346 conn->writesockfd = conn->sockfd;
2348 /* we want to use the _receiving_ function even when the socket turns
2349 out writableable as the underlying libssh2 recv function will deal
2350 with both accordingly */
2351 conn->cselect_bits = CURL_CSELECT_IN;
2354 state(conn, SSH_SCP_CHANNEL_FREE);
2355 sshc->actualcode = result;
2358 state(conn, SSH_STOP);
2363 if(data->set.upload)
2364 state(conn, SSH_SCP_SEND_EOF);
2366 state(conn, SSH_SCP_CHANNEL_FREE);
2369 case SSH_SCP_SEND_EOF:
2370 if(sshc->ssh_channel) {
2371 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2372 if(rc == LIBSSH2_ERROR_EAGAIN) {
2376 infof(data, "Failed to send libssh2 channel EOF\n");
2379 state(conn, SSH_SCP_WAIT_EOF);
2382 case SSH_SCP_WAIT_EOF:
2383 if(sshc->ssh_channel) {
2384 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2385 if(rc == LIBSSH2_ERROR_EAGAIN) {
2389 infof(data, "Failed to get channel EOF: %d\n", rc);
2392 state(conn, SSH_SCP_WAIT_CLOSE);
2395 case SSH_SCP_WAIT_CLOSE:
2396 if(sshc->ssh_channel) {
2397 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2398 if(rc == LIBSSH2_ERROR_EAGAIN) {
2402 infof(data, "Channel failed to close: %d\n", rc);
2405 state(conn, SSH_SCP_CHANNEL_FREE);
2408 case SSH_SCP_CHANNEL_FREE:
2409 if(sshc->ssh_channel) {
2410 rc = libssh2_channel_free(sshc->ssh_channel);
2411 if(rc == LIBSSH2_ERROR_EAGAIN) {
2415 infof(data, "Failed to free libssh2 scp subsystem\n");
2417 sshc->ssh_channel = NULL;
2419 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2421 state(conn, SSH_SESSION_DISCONNECT);
2423 state(conn, SSH_STOP);
2424 result = sshc->actualcode;
2427 case SSH_SESSION_DISCONNECT:
2428 /* during weird times when we've been prematurely aborted, the channel
2429 is still alive when we reach this state and we MUST kill the channel
2431 if(sshc->ssh_channel) {
2432 rc = libssh2_channel_free(sshc->ssh_channel);
2433 if(rc == LIBSSH2_ERROR_EAGAIN) {
2437 infof(data, "Failed to free libssh2 scp subsystem\n");
2439 sshc->ssh_channel = NULL;
2442 if(sshc->ssh_session) {
2443 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2444 if(rc == LIBSSH2_ERROR_EAGAIN) {
2448 infof(data, "Failed to disconnect libssh2 session\n");
2452 Curl_safefree(sshc->homedir);
2453 conn->data->state.most_recent_ftp_entrypath = NULL;
2455 state(conn, SSH_SESSION_FREE);
2458 case SSH_SESSION_FREE:
2459 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2461 libssh2_knownhost_free(sshc->kh);
2466 #ifdef HAVE_LIBSSH2_AGENT_API
2467 if(sshc->ssh_agent) {
2468 rc = libssh2_agent_disconnect(sshc->ssh_agent);
2469 if(rc == LIBSSH2_ERROR_EAGAIN) {
2473 infof(data, "Failed to disconnect from libssh2 agent\n");
2475 libssh2_agent_free (sshc->ssh_agent);
2476 sshc->ssh_agent = NULL;
2478 /* NB: there is no need to free identities, they are part of internal
2480 sshc->sshagent_identity = NULL;
2481 sshc->sshagent_prev_identity = NULL;
2485 if(sshc->ssh_session) {
2486 rc = libssh2_session_free(sshc->ssh_session);
2487 if(rc == LIBSSH2_ERROR_EAGAIN) {
2491 infof(data, "Failed to free libssh2 session\n");
2493 sshc->ssh_session = NULL;
2496 /* worst-case scenario cleanup */
2498 DEBUGASSERT(sshc->ssh_session == NULL);
2499 DEBUGASSERT(sshc->ssh_channel == NULL);
2500 DEBUGASSERT(sshc->sftp_session == NULL);
2501 DEBUGASSERT(sshc->sftp_handle == NULL);
2502 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2503 DEBUGASSERT(sshc->kh == NULL);
2506 Curl_safefree(sshc->rsa_pub);
2507 Curl_safefree(sshc->rsa);
2509 Curl_safefree(sshc->quote_path1);
2510 Curl_safefree(sshc->quote_path2);
2512 Curl_safefree(sshc->homedir);
2514 Curl_safefree(sshc->readdir_filename);
2515 Curl_safefree(sshc->readdir_longentry);
2516 Curl_safefree(sshc->readdir_line);
2517 Curl_safefree(sshc->readdir_linkPath);
2519 /* the code we are about to return */
2520 result = sshc->actualcode;
2522 memset(sshc, 0, sizeof(struct ssh_conn));
2524 conn->bits.close = TRUE;
2525 sshc->state = SSH_SESSION_FREE; /* current */
2526 sshc->nextstate = SSH_NO_STATE;
2527 state(conn, SSH_STOP);
2531 /* fallthrough, just stop! */
2533 /* internal error */
2534 sshc->nextstate = SSH_NO_STATE;
2535 state(conn, SSH_STOP);
2539 } while(!rc && (sshc->state != SSH_STOP));
2541 if(rc == LIBSSH2_ERROR_EAGAIN) {
2542 /* we would block, we need to wait for the socket to be ready (in the
2543 right direction too)! */
2550 /* called by the multi interface to figure out what socket(s) to wait for and
2551 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2552 static int ssh_perform_getsock(const struct connectdata *conn,
2553 curl_socket_t *sock, /* points to numsocks
2554 number of sockets */
2557 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2558 int bitmap = GETSOCK_BLANK;
2561 sock[0] = conn->sock[FIRSTSOCKET];
2563 if(conn->waitfor & KEEP_RECV)
2564 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2566 if(conn->waitfor & KEEP_SEND)
2567 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2571 /* if we don't know the direction we can use the generic *_getsock()
2572 function even for the protocol_connect and doing states */
2573 return Curl_single_getsock(conn, sock, numsocks);
2577 /* Generic function called by the multi interface to figure out what socket(s)
2578 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2579 static int ssh_getsock(struct connectdata *conn,
2580 curl_socket_t *sock, /* points to numsocks number
2584 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2588 /* if we don't know any direction we can just play along as we used to and
2589 not provide any sensible info */
2590 return GETSOCK_BLANK;
2592 /* if we know the direction we can use the generic *_getsock() function even
2593 for the protocol_connect and doing states */
2594 return ssh_perform_getsock(conn, sock, numsocks);
2598 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2600 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2601 * function is used to figure out in what direction and stores this info so
2602 * that the multi interface can take advantage of it. Make sure to call this
2603 * function in all cases so that when it _doesn't_ return EAGAIN we can
2604 * restore the default wait bits.
2606 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2608 struct ssh_conn *sshc = &conn->proto.sshc;
2612 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2613 /* translate the libssh2 define bits into our own bit defines */
2614 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2615 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2618 /* It didn't block or libssh2 didn't reveal in which direction, put back
2620 conn->waitfor = sshc->orig_waitfor;
2623 /* no libssh2 directional support so we simply don't know */
2624 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2627 /* called repeatedly until done from multi.c */
2628 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2630 struct ssh_conn *sshc = &conn->proto.sshc;
2631 CURLcode result = CURLE_OK;
2632 bool block; /* we store the status and use that to provide a ssh_getsock()
2635 result = ssh_statemach_act(conn, &block);
2636 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2637 ssh_block2waitfor(conn, block);
2642 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2645 struct ssh_conn *sshc = &conn->proto.sshc;
2646 CURLcode result = CURLE_OK;
2647 struct SessionHandle *data = conn->data;
2649 while((sshc->state != SSH_STOP) && !result) {
2653 result = ssh_statemach_act(conn, &block);
2657 if(Curl_pgrsUpdate(conn))
2658 return CURLE_ABORTED_BY_CALLBACK;
2660 struct timeval now = Curl_tvnow();
2661 result = Curl_speedcheck(data, now);
2666 left = Curl_timeleft(data, NULL, duringconnect);
2668 failf(data, "Operation timed out");
2669 return CURLE_OPERATION_TIMEDOUT;
2672 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2673 if((CURLE_OK == result) && block) {
2674 int dir = libssh2_session_block_directions(sshc->ssh_session);
2675 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2676 curl_socket_t fd_read = CURL_SOCKET_BAD;
2677 curl_socket_t fd_write = CURL_SOCKET_BAD;
2678 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2680 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2682 /* wait for the socket to become ready */
2683 Curl_socket_ready(fd_read, fd_write,
2684 left>1000?1000:left); /* ignore result */
2694 * SSH setup and connection
2696 static CURLcode ssh_init(struct connectdata *conn)
2698 struct SessionHandle *data = conn->data;
2699 struct SSHPROTO *ssh;
2700 struct ssh_conn *sshc = &conn->proto.sshc;
2702 sshc->actualcode = CURLE_OK; /* reset error code */
2703 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2706 if(data->state.proto.ssh)
2709 ssh = calloc(1, sizeof(struct SSHPROTO));
2711 return CURLE_OUT_OF_MEMORY;
2713 data->state.proto.ssh = ssh;
2718 static Curl_recv scp_recv, sftp_recv;
2719 static Curl_send scp_send, sftp_send;
2722 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2723 * do protocol-specific actions at connect-time.
2725 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2727 #ifdef CURL_LIBSSH2_DEBUG
2730 struct ssh_conn *ssh;
2732 struct SessionHandle *data = conn->data;
2734 /* We default to persistent connections. We set this already in this connect
2735 function to make the re-use checks properly be able to check this bit. */
2736 conn->bits.close = FALSE;
2738 /* If there already is a protocol-specific struct allocated for this
2739 sessionhandle, deal with it */
2740 Curl_reset_reqproto(conn);
2742 result = ssh_init(conn);
2746 if(conn->handler->protocol & CURLPROTO_SCP) {
2747 conn->recv[FIRSTSOCKET] = scp_recv;
2748 conn->send[FIRSTSOCKET] = scp_send;
2751 conn->recv[FIRSTSOCKET] = sftp_recv;
2752 conn->send[FIRSTSOCKET] = sftp_send;
2754 ssh = &conn->proto.sshc;
2756 #ifdef CURL_LIBSSH2_DEBUG
2758 infof(data, "User: %s\n", conn->user);
2761 infof(data, "Password: %s\n", conn->passwd);
2763 sock = conn->sock[FIRSTSOCKET];
2764 #endif /* CURL_LIBSSH2_DEBUG */
2766 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2768 my_libssh2_realloc, conn);
2769 if(ssh->ssh_session == NULL) {
2770 failf(data, "Failure initialising ssh session");
2771 return CURLE_FAILED_INIT;
2774 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2775 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2777 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2779 /* eeek. TODO: free the ssh_session! */
2780 return CURLE_FAILED_INIT;
2783 /* read all known hosts from there */
2784 rc = libssh2_knownhost_readfile(ssh->kh,
2785 data->set.str[STRING_SSH_KNOWNHOSTS],
2786 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2788 infof(data, "Failed to read known hosts from %s\n",
2789 data->set.str[STRING_SSH_KNOWNHOSTS]);
2791 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2793 #ifdef CURL_LIBSSH2_DEBUG
2794 libssh2_trace(ssh->ssh_session, ~0);
2795 infof(data, "SSH socket: %d\n", (int)sock);
2796 #endif /* CURL_LIBSSH2_DEBUG */
2798 state(conn, SSH_INIT);
2800 if(data->state.used_interface == Curl_if_multi)
2801 result = ssh_multi_statemach(conn, done);
2803 result = ssh_easy_statemach(conn, TRUE);
2812 ***********************************************************************
2816 * This is the actual DO function for SCP. Get a file according to
2817 * the options previously setup.
2821 CURLcode scp_perform(struct connectdata *conn,
2825 CURLcode result = CURLE_OK;
2827 DEBUGF(infof(conn->data, "DO phase starts\n"));
2829 *dophase_done = FALSE; /* not done yet */
2831 /* start the first command in the DO phase */
2832 state(conn, SSH_SCP_TRANS_INIT);
2834 /* run the state-machine */
2835 if(conn->data->state.used_interface == Curl_if_multi) {
2836 result = ssh_multi_statemach(conn, dophase_done);
2839 result = ssh_easy_statemach(conn, FALSE);
2840 *dophase_done = TRUE; /* with the easy interface we are done here */
2842 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2845 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2851 /* called from multi.c while DOing */
2852 static CURLcode scp_doing(struct connectdata *conn,
2856 result = ssh_multi_statemach(conn, dophase_done);
2859 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2865 * The DO function is generic for both protocols. There was previously two
2866 * separate ones but this way means less duplicated code.
2869 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2873 struct SessionHandle *data = conn->data;
2875 *done = FALSE; /* default to false */
2878 Since connections can be re-used between SessionHandles, this might be a
2879 connection already existing but on a fresh SessionHandle struct so we must
2880 make sure we have a good 'struct SSHPROTO' to play with. For new
2881 connections, the struct SSHPROTO is allocated and setup in the
2882 ssh_connect() function.
2884 Curl_reset_reqproto(conn);
2885 res = ssh_init(conn);
2889 data->req.size = -1; /* make sure this is unknown at this point */
2891 Curl_pgrsSetUploadCounter(data, 0);
2892 Curl_pgrsSetDownloadCounter(data, 0);
2893 Curl_pgrsSetUploadSize(data, 0);
2894 Curl_pgrsSetDownloadSize(data, 0);
2896 if(conn->handler->protocol & CURLPROTO_SCP)
2897 res = scp_perform(conn, &connected, done);
2899 res = sftp_perform(conn, &connected, done);
2904 /* BLOCKING, but the function is using the state machine so the only reason
2905 this is still blocking is that the multi interface code has no support for
2906 disconnecting operations that takes a while */
2907 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2909 CURLcode result = CURLE_OK;
2910 struct ssh_conn *ssh = &conn->proto.sshc;
2911 (void) dead_connection;
2913 Curl_safefree(conn->data->state.proto.ssh);
2915 if(ssh->ssh_session) {
2916 /* only if there's a session still around to use! */
2918 state(conn, SSH_SESSION_DISCONNECT);
2920 result = ssh_easy_statemach(conn, FALSE);
2926 /* generic done function for both SCP and SFTP called from their specific
2928 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2930 CURLcode result = CURLE_OK;
2931 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2933 if(status == CURLE_OK) {
2934 /* run the state-machine
2936 TODO: when the multi interface is used, this _really_ should be using
2937 the ssh_multi_statemach function but we have no general support for
2938 non-blocking DONE operations, not in the multi state machine and with
2939 Curl_done() invokes on several places in the code!
2941 result = ssh_easy_statemach(conn, FALSE);
2947 Curl_safefree(sftp_scp->path);
2948 if(Curl_pgrsDone(conn))
2949 return CURLE_ABORTED_BY_CALLBACK;
2951 conn->data->req.keepon = 0; /* clear all bits */
2956 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2959 (void)premature; /* not used */
2961 if(status == CURLE_OK)
2962 state(conn, SSH_SCP_DONE);
2964 return ssh_done(conn, status);
2968 /* return number of received (decrypted) bytes */
2969 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2970 const void *mem, size_t len, CURLcode *err)
2973 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2975 /* libssh2_channel_write() returns int! */
2977 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2979 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2981 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2985 else if(nwrite < LIBSSH2_ERROR_NONE) {
2986 *err = libssh2_session_error_to_CURLE((int)nwrite);
2994 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2995 * a regular CURLcode value.
2997 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2998 char *mem, size_t len, CURLcode *err)
3001 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3003 /* libssh2_channel_read() returns int */
3005 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
3007 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3008 if(nread == LIBSSH2_ERROR_EAGAIN) {
3017 * =============== SFTP ===============
3021 ***********************************************************************
3025 * This is the actual DO function for SFTP. Get a file/directory according to
3026 * the options previously setup.
3030 CURLcode sftp_perform(struct connectdata *conn,
3034 CURLcode result = CURLE_OK;
3036 DEBUGF(infof(conn->data, "DO phase starts\n"));
3038 *dophase_done = FALSE; /* not done yet */
3040 /* start the first command in the DO phase */
3041 state(conn, SSH_SFTP_QUOTE_INIT);
3043 /* run the state-machine */
3044 if(conn->data->state.used_interface == Curl_if_multi) {
3045 result = ssh_multi_statemach(conn, dophase_done);
3048 result = ssh_easy_statemach(conn, FALSE);
3049 *dophase_done = TRUE; /* with the easy interface we are done here */
3051 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3054 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3060 /* called from multi.c while DOing */
3061 static CURLcode sftp_doing(struct connectdata *conn,
3065 result = ssh_multi_statemach(conn, dophase_done);
3068 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3073 /* BLOCKING, but the function is using the state machine so the only reason
3074 this is still blocking is that the multi interface code has no support for
3075 disconnecting operations that takes a while */
3076 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
3078 CURLcode result = CURLE_OK;
3079 (void) dead_connection;
3081 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3083 Curl_safefree(conn->data->state.proto.ssh);
3085 if(conn->proto.sshc.ssh_session) {
3086 /* only if there's a session still around to use! */
3087 state(conn, SSH_SFTP_SHUTDOWN);
3088 result = ssh_easy_statemach(conn, FALSE);
3091 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3097 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3100 struct ssh_conn *sshc = &conn->proto.sshc;
3102 if(status == CURLE_OK) {
3103 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3104 errors that could happen due to open file handles during POSTQUOTE
3106 if(!status && !premature && conn->data->set.postquote) {
3107 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3108 state(conn, SSH_SFTP_CLOSE);
3111 state(conn, SSH_SFTP_CLOSE);
3113 return ssh_done(conn, status);
3116 /* return number of sent bytes */
3117 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3118 const void *mem, size_t len, CURLcode *err)
3120 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3121 but is changed to ssize_t in 0.15. These days we don't
3122 support libssh2 0.15*/
3125 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3127 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3129 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3133 else if(nwrite < LIBSSH2_ERROR_NONE) {
3134 *err = libssh2_session_error_to_CURLE((int)nwrite);
3142 * Return number of received (decrypted) bytes
3144 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3145 char *mem, size_t len, CURLcode *err)
3150 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3152 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3154 if(nread == LIBSSH2_ERROR_EAGAIN) {
3161 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3164 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3166 * Permission to use, copy, modify, and distribute this software for any
3167 * purpose with or without fee is hereby granted, provided that the above
3168 * copyright notice and this permission notice appear in all copies.
3170 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3171 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3172 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3173 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3174 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3175 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3176 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3179 get_pathname(const char **cpp, char **path)
3181 const char *cp = *cpp, *end;
3184 static const char WHITESPACE[] = " \t\r\n";
3186 cp += strspn(cp, WHITESPACE);
3190 return CURLE_QUOTE_ERROR;
3193 *path = malloc(strlen(cp) + 1);
3195 return CURLE_OUT_OF_MEMORY;
3197 /* Check for quoted filenames */
3198 if(*cp == '\"' || *cp == '\'') {
3201 /* Search for terminating quote, unescape some chars */
3202 for(i = j = 0; i <= strlen(cp); i++) {
3203 if(cp[i] == quot) { /* Found quote */
3208 if(cp[i] == '\0') { /* End of string */
3209 /*error("Unterminated quote");*/
3212 if(cp[i] == '\\') { /* Escaped characters */
3214 if(cp[i] != '\'' && cp[i] != '\"' &&
3216 /*error("Bad escaped character '\\%c'",
3221 (*path)[j++] = cp[i];
3225 /*error("Empty quotes");*/
3228 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3231 /* Read to end of filename */
3232 end = strpbrk(cp, WHITESPACE);
3234 end = strchr(cp, '\0');
3235 *cpp = end + strspn(end, WHITESPACE);
3237 memcpy(*path, cp, end - cp);
3238 (*path)[end - cp] = '\0';
3243 Curl_safefree(*path);
3244 return CURLE_QUOTE_ERROR;
3248 static const char *sftp_libssh2_strerror(int err)
3251 case LIBSSH2_FX_NO_SUCH_FILE:
3252 return "No such file or directory";
3254 case LIBSSH2_FX_PERMISSION_DENIED:
3255 return "Permission denied";
3257 case LIBSSH2_FX_FAILURE:
3258 return "Operation failed";
3260 case LIBSSH2_FX_BAD_MESSAGE:
3261 return "Bad message from SFTP server";
3263 case LIBSSH2_FX_NO_CONNECTION:
3264 return "Not connected to SFTP server";
3266 case LIBSSH2_FX_CONNECTION_LOST:
3267 return "Connection to SFTP server lost";
3269 case LIBSSH2_FX_OP_UNSUPPORTED:
3270 return "Operation not supported by SFTP server";
3272 case LIBSSH2_FX_INVALID_HANDLE:
3273 return "Invalid handle";
3275 case LIBSSH2_FX_NO_SUCH_PATH:
3276 return "No such file or directory";
3278 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3279 return "File already exists";
3281 case LIBSSH2_FX_WRITE_PROTECT:
3282 return "File is write protected";
3284 case LIBSSH2_FX_NO_MEDIA:
3287 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3290 case LIBSSH2_FX_QUOTA_EXCEEDED:
3291 return "User quota exceeded";
3293 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3294 return "Unknown principle";
3296 case LIBSSH2_FX_LOCK_CONFlICT:
3297 return "File lock conflict";
3299 case LIBSSH2_FX_DIR_NOT_EMPTY:
3300 return "Directory not empty";
3302 case LIBSSH2_FX_NOT_A_DIRECTORY:
3303 return "Not a directory";
3305 case LIBSSH2_FX_INVALID_FILENAME:
3306 return "Invalid filename";
3308 case LIBSSH2_FX_LINK_LOOP:
3309 return "Link points to itself";
3311 return "Unknown error in libssh2";
3314 #endif /* USE_LIBSSH2 */