1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2013, 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 */
25 #include "curl_setup.h"
34 #include <libssh2_sftp.h>
40 #ifdef HAVE_NETINET_IN_H
41 #include <netinet/in.h>
43 #ifdef HAVE_ARPA_INET_H
44 #include <arpa/inet.h>
47 #include <sys/utsname.h>
57 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
59 #define in_addr_t unsigned long
62 #include <curl/curl.h>
69 #include "http.h" /* for HTTP proxy tunnel stuff */
72 #include "speedcheck.h"
79 #include "inet_ntop.h"
80 #include "parsedate.h" /* for the week day and month names */
81 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
82 #include "strtoofft.h"
87 #define _MPRINTF_REPLACE /* use our functions only */
88 #include <curl/mprintf.h>
90 #include "curl_memory.h"
91 /* The last #include file should be: */
96 # define PATH_MAX MAX_PATH
100 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
101 have their definition hidden well */
104 #define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
106 #define sftp_libssh2_realpath(s,p,t,m) \
107 libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
108 (t), (m), LIBSSH2_SFTP_REALPATH)
110 /* Local functions: */
111 static const char *sftp_libssh2_strerror(int err);
112 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
113 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
114 static LIBSSH2_FREE_FUNC(my_libssh2_free);
116 static CURLcode get_pathname(const char **cpp, char **path);
118 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
119 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
120 static CURLcode ssh_do(struct connectdata *conn, bool *done);
122 static CURLcode ssh_getworkingpath(struct connectdata *conn,
123 char *homedir, /* when SFTP is used */
126 static CURLcode scp_done(struct connectdata *conn,
127 CURLcode, bool premature);
128 static CURLcode scp_doing(struct connectdata *conn,
130 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
132 static CURLcode sftp_done(struct connectdata *conn,
133 CURLcode, bool premature);
134 static CURLcode sftp_doing(struct connectdata *conn,
136 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
138 CURLcode sftp_perform(struct connectdata *conn,
142 static int ssh_getsock(struct connectdata *conn,
143 curl_socket_t *sock, /* points to numsocks number
147 static int ssh_perform_getsock(const struct connectdata *conn,
148 curl_socket_t *sock, /* points to numsocks
153 * SCP protocol handler.
156 const struct Curl_handler Curl_handler_scp = {
158 ZERO_NULL, /* setup_connection */
161 ZERO_NULL, /* do_more */
162 ssh_connect, /* connect_it */
163 ssh_multi_statemach, /* connecting */
164 scp_doing, /* doing */
165 ssh_getsock, /* proto_getsock */
166 ssh_getsock, /* doing_getsock */
167 ZERO_NULL, /* domore_getsock */
168 ssh_perform_getsock, /* perform_getsock */
169 scp_disconnect, /* disconnect */
170 ZERO_NULL, /* readwrite */
171 PORT_SSH, /* defport */
172 CURLPROTO_SCP, /* protocol */
173 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
174 | PROTOPT_NOURLQUERY /* flags */
179 * SFTP protocol handler.
182 const struct Curl_handler Curl_handler_sftp = {
184 ZERO_NULL, /* setup_connection */
186 sftp_done, /* done */
187 ZERO_NULL, /* do_more */
188 ssh_connect, /* connect_it */
189 ssh_multi_statemach, /* connecting */
190 sftp_doing, /* doing */
191 ssh_getsock, /* proto_getsock */
192 ssh_getsock, /* doing_getsock */
193 ZERO_NULL, /* domore_getsock */
194 ssh_perform_getsock, /* perform_getsock */
195 sftp_disconnect, /* disconnect */
196 ZERO_NULL, /* readwrite */
197 PORT_SSH, /* defport */
198 CURLPROTO_SFTP, /* protocol */
199 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
200 | PROTOPT_NOURLQUERY /* flags */
205 kbd_callback(const char *name, int name_len, const char *instruction,
206 int instruction_len, int num_prompts,
207 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
208 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
211 struct connectdata *conn = (struct connectdata *)*abstract;
213 #ifdef CURL_LIBSSH2_DEBUG
214 fprintf(stderr, "name=%s\n", name);
215 fprintf(stderr, "name_len=%d\n", name_len);
216 fprintf(stderr, "instruction=%s\n", instruction);
217 fprintf(stderr, "instruction_len=%d\n", instruction_len);
218 fprintf(stderr, "num_prompts=%d\n", num_prompts);
223 (void)instruction_len;
224 #endif /* CURL_LIBSSH2_DEBUG */
225 if(num_prompts == 1) {
226 responses[0].text = strdup(conn->passwd);
227 responses[0].length = curlx_uztoui(strlen(conn->passwd));
233 static CURLcode sftp_libssh2_error_to_CURLE(int err)
239 case LIBSSH2_FX_NO_SUCH_FILE:
240 case LIBSSH2_FX_NO_SUCH_PATH:
241 return CURLE_REMOTE_FILE_NOT_FOUND;
243 case LIBSSH2_FX_PERMISSION_DENIED:
244 case LIBSSH2_FX_WRITE_PROTECT:
245 case LIBSSH2_FX_LOCK_CONFlICT:
246 return CURLE_REMOTE_ACCESS_DENIED;
248 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
249 case LIBSSH2_FX_QUOTA_EXCEEDED:
250 return CURLE_REMOTE_DISK_FULL;
252 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
253 return CURLE_REMOTE_FILE_EXISTS;
255 case LIBSSH2_FX_DIR_NOT_EMPTY:
256 return CURLE_QUOTE_ERROR;
265 static CURLcode libssh2_session_error_to_CURLE(int err)
268 /* Ordered by order of appearance in libssh2.h */
269 case LIBSSH2_ERROR_NONE:
272 case LIBSSH2_ERROR_SOCKET_NONE:
273 return CURLE_COULDNT_CONNECT;
275 case LIBSSH2_ERROR_ALLOC:
276 return CURLE_OUT_OF_MEMORY;
278 case LIBSSH2_ERROR_SOCKET_SEND:
279 return CURLE_SEND_ERROR;
281 case LIBSSH2_ERROR_HOSTKEY_INIT:
282 case LIBSSH2_ERROR_HOSTKEY_SIGN:
283 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
284 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
285 return CURLE_PEER_FAILED_VERIFICATION;
287 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
288 return CURLE_LOGIN_DENIED;
290 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
291 case LIBSSH2_ERROR_TIMEOUT:
292 return CURLE_OPERATION_TIMEDOUT;
294 case LIBSSH2_ERROR_EAGAIN:
298 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
299 error code, and possibly add a few new SSH-related one. We must however
300 not return or even depend on libssh2 errors in the public libcurl API */
305 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
307 (void)abstract; /* arg not used */
308 return malloc(count);
311 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
313 (void)abstract; /* arg not used */
314 return realloc(ptr, count);
317 static LIBSSH2_FREE_FUNC(my_libssh2_free)
319 (void)abstract; /* arg not used */
320 if(ptr) /* ssh2 agent sometimes call free with null ptr */
325 * SSH State machine related code
327 /* This is the ONLY way to change SSH state! */
328 static void state(struct connectdata *conn, sshstate nowstate)
330 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
331 /* for debug purposes */
332 static const char * const names[] = {
338 "SSH_AUTH_PKEY_INIT",
340 "SSH_AUTH_PASS_INIT",
342 "SSH_AUTH_AGENT_INIT",
343 "SSH_AUTH_AGENT_LIST",
345 "SSH_AUTH_HOST_INIT",
352 "SSH_SFTP_QUOTE_INIT",
353 "SSH_SFTP_POSTQUOTE_INIT",
355 "SSH_SFTP_NEXT_QUOTE",
356 "SSH_SFTP_QUOTE_STAT",
357 "SSH_SFTP_QUOTE_SETSTAT",
358 "SSH_SFTP_QUOTE_SYMLINK",
359 "SSH_SFTP_QUOTE_MKDIR",
360 "SSH_SFTP_QUOTE_RENAME",
361 "SSH_SFTP_QUOTE_RMDIR",
362 "SSH_SFTP_QUOTE_UNLINK",
363 "SSH_SFTP_TRANS_INIT",
364 "SSH_SFTP_UPLOAD_INIT",
365 "SSH_SFTP_CREATE_DIRS_INIT",
366 "SSH_SFTP_CREATE_DIRS",
367 "SSH_SFTP_CREATE_DIRS_MKDIR",
368 "SSH_SFTP_READDIR_INIT",
370 "SSH_SFTP_READDIR_LINK",
371 "SSH_SFTP_READDIR_BOTTOM",
372 "SSH_SFTP_READDIR_DONE",
373 "SSH_SFTP_DOWNLOAD_INIT",
374 "SSH_SFTP_DOWNLOAD_STAT",
377 "SSH_SCP_TRANS_INIT",
378 "SSH_SCP_UPLOAD_INIT",
379 "SSH_SCP_DOWNLOAD_INIT",
383 "SSH_SCP_WAIT_CLOSE",
384 "SSH_SCP_CHANNEL_FREE",
385 "SSH_SESSION_DISCONNECT",
390 struct ssh_conn *sshc = &conn->proto.sshc;
392 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
393 if(sshc->state != nowstate) {
394 infof(conn->data, "SFTP %p state change from %s to %s\n",
395 sshc, names[sshc->state], names[nowstate]);
399 sshc->state = nowstate;
402 /* figure out the path to work with in this particular request */
403 static CURLcode ssh_getworkingpath(struct connectdata *conn,
404 char *homedir, /* when SFTP is used */
405 char **path) /* returns the allocated
406 real path to work with */
408 struct SessionHandle *data = conn->data;
409 char *real_path = NULL;
411 int working_path_len;
413 working_path = curl_easy_unescape(data, data->state.path, 0,
416 return CURLE_OUT_OF_MEMORY;
418 /* Check for /~/ , indicating relative to the user's home directory */
419 if(conn->handler->protocol & CURLPROTO_SCP) {
420 real_path = malloc(working_path_len+1);
421 if(real_path == NULL) {
423 return CURLE_OUT_OF_MEMORY;
425 if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
426 /* It is referenced to the home directory, so strip the leading '/~/' */
427 memcpy(real_path, working_path+3, 4 + working_path_len-3);
429 memcpy(real_path, working_path, 1 + working_path_len);
431 else if(conn->handler->protocol & CURLPROTO_SFTP) {
432 if((working_path_len > 1) && (working_path[1] == '~')) {
433 size_t homelen = strlen(homedir);
434 real_path = malloc(homelen + working_path_len + 1);
435 if(real_path == NULL) {
437 return CURLE_OUT_OF_MEMORY;
439 /* It is referenced to the home directory, so strip the
441 memcpy(real_path, homedir, homelen);
442 real_path[homelen] = '/';
443 real_path[homelen+1] = '\0';
444 if(working_path_len > 3) {
445 memcpy(real_path+homelen+1, working_path + 3,
446 1 + working_path_len -3);
450 real_path = malloc(working_path_len+1);
451 if(real_path == NULL) {
453 return CURLE_OUT_OF_MEMORY;
455 memcpy(real_path, working_path, 1+working_path_len);
461 /* store the pointer for the caller to receive */
467 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
468 static int sshkeycallback(CURL *easy,
469 const struct curl_khkey *knownkey, /* known */
470 const struct curl_khkey *foundkey, /* found */
471 enum curl_khmatch match,
479 /* we only allow perfect matches, and we reject everything else */
480 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
485 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
488 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
489 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
491 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
495 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
496 * architectures so we check of the necessary function is present.
498 #ifndef HAVE_LIBSSH2_SCP_SEND64
499 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
501 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
502 (libssh2_uint64_t)d, 0, 0)
506 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
508 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
509 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
512 static CURLcode ssh_knownhost(struct connectdata *conn)
514 CURLcode result = CURLE_OK;
516 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
517 struct SessionHandle *data = conn->data;
519 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
520 /* we're asked to verify the host against a file */
521 struct ssh_conn *sshc = &conn->proto.sshc;
525 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
527 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
532 * A subject to figure out is what host name we need to pass in here.
533 * What host name does OpenSSH store in its file if an IDN name is
536 struct libssh2_knownhost *host;
537 enum curl_khmatch keymatch;
538 curl_sshkeycallback func =
539 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
540 struct curl_khkey knownkey;
541 struct curl_khkey *knownkeyp = NULL;
542 struct curl_khkey foundkey;
544 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
545 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
547 keycheck = libssh2_knownhost_check(sshc->kh,
550 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
551 LIBSSH2_KNOWNHOST_KEYENC_RAW|
555 infof(data, "SSH host check: %d, key: %s\n", keycheck,
556 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
559 /* setup 'knownkey' */
560 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
561 knownkey.key = host->key;
563 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
564 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
565 knownkeyp = &knownkey;
568 /* setup 'foundkey' */
569 foundkey.key = remotekey;
570 foundkey.len = keylen;
571 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
572 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
575 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
576 * curl_khmatch enum are ever modified, we need to introduce a
577 * translation table here!
579 keymatch = (enum curl_khmatch)keycheck;
581 /* Ask the callback how to behave */
582 rc = func(data, knownkeyp, /* from the knownhosts file */
583 &foundkey, /* from the remote host */
584 keymatch, data->set.ssh_keyfunc_userp);
587 /* no remotekey means failure! */
588 rc = CURLKHSTAT_REJECT;
591 default: /* unknown return codes will equal reject */
592 case CURLKHSTAT_REJECT:
593 state(conn, SSH_SESSION_FREE);
594 case CURLKHSTAT_DEFER:
595 /* DEFER means bail out but keep the SSH_HOSTKEY state */
596 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
598 case CURLKHSTAT_FINE:
599 case CURLKHSTAT_FINE_ADD_TO_FILE:
601 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
602 /* the found host+key didn't match but has been told to be fine
603 anyway so we add it in memory */
604 int addrc = libssh2_knownhost_add(sshc->kh,
605 conn->host.name, NULL,
607 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
608 LIBSSH2_KNOWNHOST_KEYENC_RAW|
611 infof(data, "Warning adding the known host %s failed!\n",
613 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
614 /* now we write the entire in-memory list of known hosts to the
617 libssh2_knownhost_writefile(sshc->kh,
618 data->set.str[STRING_SSH_KNOWNHOSTS],
619 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
621 infof(data, "Warning, writing %s failed!\n",
622 data->set.str[STRING_SSH_KNOWNHOSTS]);
629 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
635 static CURLcode ssh_check_fingerprint(struct connectdata *conn)
637 struct ssh_conn *sshc = &conn->proto.sshc;
638 struct SessionHandle *data = conn->data;
639 const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
643 const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
644 LIBSSH2_HOSTKEY_HASH_MD5);
647 /* The fingerprint points to static storage (!), don't free() it. */
648 for(i = 0; i < 16; i++)
649 snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
650 infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
653 /* Before we authenticate we check the hostkey's MD5 fingerprint
654 * against a known fingerprint, if available.
656 if(pubkey_md5 && strlen(pubkey_md5) == 32) {
657 if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
660 "Denied establishing ssh session: mismatch md5 fingerprint. "
661 "Remote %s is not equal to %s", md5buffer, pubkey_md5);
664 "Denied establishing ssh session: md5 fingerprint not available");
665 state(conn, SSH_SESSION_FREE);
666 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
667 return sshc->actualcode;
670 infof(data, "MD5 checksum match!\n");
671 /* as we already matched, we skip the check for known hosts */
676 return ssh_knownhost(conn);
680 * ssh_statemach_act() runs the SSH state machine as far as it can without
681 * blocking and without reaching the end. The data the pointer 'block' points
682 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
683 * meaning it wants to be called again when the socket is ready
686 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
688 CURLcode result = CURLE_OK;
689 struct SessionHandle *data = conn->data;
690 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
691 struct ssh_conn *sshc = &conn->proto.sshc;
692 curl_socket_t sock = conn->sock[FIRSTSOCKET];
693 char *new_readdir_line;
694 int rc = LIBSSH2_ERROR_NONE;
696 int seekerr = CURL_SEEKFUNC_OK;
697 *block = 0; /* we're not blocking by default */
701 switch(sshc->state) {
703 sshc->secondCreateDirs = 0;
704 sshc->nextstate = SSH_NO_STATE;
705 sshc->actualcode = CURLE_OK;
707 /* Set libssh2 to non-blocking, since everything internally is
709 libssh2_session_set_blocking(sshc->ssh_session, 0);
711 state(conn, SSH_S_STARTUP);
715 rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
716 if(rc == LIBSSH2_ERROR_EAGAIN) {
720 failf(data, "Failure establishing ssh session");
721 state(conn, SSH_SESSION_FREE);
722 sshc->actualcode = CURLE_FAILED_INIT;
726 state(conn, SSH_HOSTKEY);
731 * Before we authenticate we should check the hostkey's fingerprint
732 * against our known hosts. How that is handled (reading from file,
733 * whatever) is up to us.
735 result = ssh_check_fingerprint(conn);
736 if(result == CURLE_OK)
737 state(conn, SSH_AUTHLIST);
742 * Figure out authentication methods
743 * NB: As soon as we have provided a username to an openssh server we
744 * must never change it later. Thus, always specify the correct username
745 * here, even though the libssh2 docs kind of indicate that it should be
746 * possible to get a 'generic' list (not user-specific) of authentication
747 * methods, presumably with a blank username. That won't work in my
749 * So always specify it here.
751 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
753 curlx_uztoui(strlen(conn->user)));
755 if(!sshc->authlist) {
756 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
757 LIBSSH2_ERROR_EAGAIN) {
758 rc = LIBSSH2_ERROR_EAGAIN;
762 state(conn, SSH_SESSION_FREE);
763 sshc->actualcode = libssh2_session_error_to_CURLE(err);
767 infof(data, "SSH authentication methods available: %s\n",
770 state(conn, SSH_AUTH_PKEY_INIT);
773 case SSH_AUTH_PKEY_INIT:
775 * Check the supported auth types in the order I feel is most secure
776 * with the requested type of authentication
778 sshc->authed = FALSE;
780 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
781 (strstr(sshc->authlist, "publickey") != NULL)) {
783 bool rsa_pub_empty_but_ok = FALSE;
785 sshc->rsa_pub = sshc->rsa = NULL;
787 /* To ponder about: should really the lib be messing about with the
788 HOME environment variable etc? */
789 home = curl_getenv("HOME");
791 if(data->set.str[STRING_SSH_PUBLIC_KEY] &&
792 !*data->set.str[STRING_SSH_PUBLIC_KEY])
793 rsa_pub_empty_but_ok = true;
794 else if(data->set.str[STRING_SSH_PUBLIC_KEY])
795 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
797 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
799 /* as a final resort, try current dir! */
800 sshc->rsa_pub = strdup("id_dsa.pub");
802 if(!rsa_pub_empty_but_ok && (sshc->rsa_pub == NULL)) {
804 state(conn, SSH_SESSION_FREE);
805 sshc->actualcode = CURLE_OUT_OF_MEMORY;
809 if(data->set.str[STRING_SSH_PRIVATE_KEY])
810 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
812 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
814 /* as a final resort, try current dir! */
815 sshc->rsa = strdup("id_dsa");
817 if(sshc->rsa == NULL) {
819 Curl_safefree(sshc->rsa_pub);
820 state(conn, SSH_SESSION_FREE);
821 sshc->actualcode = CURLE_OUT_OF_MEMORY;
825 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
826 if(!sshc->passphrase)
827 sshc->passphrase = "";
831 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
832 infof(data, "Using ssh private key file %s\n", sshc->rsa);
834 state(conn, SSH_AUTH_PKEY);
837 state(conn, SSH_AUTH_PASS_INIT);
842 /* The function below checks if the files exists, no need to stat() here.
844 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
849 sshc->rsa, sshc->passphrase);
850 if(rc == LIBSSH2_ERROR_EAGAIN) {
854 Curl_safefree(sshc->rsa_pub);
855 Curl_safefree(sshc->rsa);
859 infof(data, "Initialized SSH public key authentication\n");
860 state(conn, SSH_AUTH_DONE);
864 (void)libssh2_session_last_error(sshc->ssh_session,
866 infof(data, "SSH public key authentication failed: %s\n", err_msg);
867 state(conn, SSH_AUTH_PASS_INIT);
871 case SSH_AUTH_PASS_INIT:
872 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
873 (strstr(sshc->authlist, "password") != NULL)) {
874 state(conn, SSH_AUTH_PASS);
877 state(conn, SSH_AUTH_HOST_INIT);
882 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
883 curlx_uztoui(strlen(conn->user)),
885 curlx_uztoui(strlen(conn->passwd)),
887 if(rc == LIBSSH2_ERROR_EAGAIN) {
892 infof(data, "Initialized password authentication\n");
893 state(conn, SSH_AUTH_DONE);
896 state(conn, SSH_AUTH_HOST_INIT);
900 case SSH_AUTH_HOST_INIT:
901 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
902 (strstr(sshc->authlist, "hostbased") != NULL)) {
903 state(conn, SSH_AUTH_HOST);
906 state(conn, SSH_AUTH_AGENT_INIT);
911 state(conn, SSH_AUTH_AGENT_INIT);
914 case SSH_AUTH_AGENT_INIT:
915 #ifdef HAVE_LIBSSH2_AGENT_API
916 if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
917 && (strstr(sshc->authlist, "publickey") != NULL)) {
919 /* Connect to the ssh-agent */
920 /* The agent could be shared by a curl thread i believe
921 but nothing obvious as keys can be added/removed at any time */
922 if(!sshc->ssh_agent) {
923 sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
924 if(!sshc->ssh_agent) {
925 infof(data, "Could not create agent object\n");
927 state(conn, SSH_AUTH_KEY_INIT);
931 rc = libssh2_agent_connect(sshc->ssh_agent);
932 if(rc == LIBSSH2_ERROR_EAGAIN)
935 infof(data, "Failure connecting to agent\n");
936 state(conn, SSH_AUTH_KEY_INIT);
939 state(conn, SSH_AUTH_AGENT_LIST);
943 #endif /* HAVE_LIBSSH2_AGENT_API */
944 state(conn, SSH_AUTH_KEY_INIT);
947 case SSH_AUTH_AGENT_LIST:
948 #ifdef HAVE_LIBSSH2_AGENT_API
949 rc = libssh2_agent_list_identities(sshc->ssh_agent);
951 if(rc == LIBSSH2_ERROR_EAGAIN)
954 infof(data, "Failure requesting identities to agent\n");
955 state(conn, SSH_AUTH_KEY_INIT);
958 state(conn, SSH_AUTH_AGENT);
959 sshc->sshagent_prev_identity = NULL;
965 #ifdef HAVE_LIBSSH2_AGENT_API
966 /* as prev_identity evolves only after an identity user auth finished we
967 can safely request it again as long as EAGAIN is returned here or by
968 libssh2_agent_userauth */
969 rc = libssh2_agent_get_identity(sshc->ssh_agent,
970 &sshc->sshagent_identity,
971 sshc->sshagent_prev_identity);
972 if(rc == LIBSSH2_ERROR_EAGAIN)
976 rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
977 sshc->sshagent_identity);
980 if(rc != LIBSSH2_ERROR_EAGAIN) {
981 /* tried and failed? go to next identity */
982 sshc->sshagent_prev_identity = sshc->sshagent_identity;
989 infof(data, "Failure requesting identities to agent\n");
991 infof(data, "No identity would match\n");
993 if(rc == LIBSSH2_ERROR_NONE) {
995 infof(data, "Agent based authentication successful\n");
996 state(conn, SSH_AUTH_DONE);
999 state(conn, SSH_AUTH_KEY_INIT);
1003 case SSH_AUTH_KEY_INIT:
1004 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
1005 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
1006 state(conn, SSH_AUTH_KEY);
1009 state(conn, SSH_AUTH_DONE);
1014 /* Authentication failed. Continue with keyboard-interactive now. */
1015 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
1018 strlen(conn->user)),
1020 if(rc == LIBSSH2_ERROR_EAGAIN) {
1024 sshc->authed = TRUE;
1025 infof(data, "Initialized keyboard interactive authentication\n");
1027 state(conn, SSH_AUTH_DONE);
1032 failf(data, "Authentication failure");
1033 state(conn, SSH_SESSION_FREE);
1034 sshc->actualcode = CURLE_LOGIN_DENIED;
1039 * At this point we have an authenticated ssh session.
1041 infof(data, "Authentication complete\n");
1043 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
1045 conn->sockfd = sock;
1046 conn->writesockfd = CURL_SOCKET_BAD;
1048 if(conn->handler->protocol == CURLPROTO_SFTP) {
1049 state(conn, SSH_SFTP_INIT);
1052 infof(data, "SSH CONNECT phase done\n");
1053 state(conn, SSH_STOP);
1058 * Start the libssh2 sftp session
1060 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
1061 if(!sshc->sftp_session) {
1062 if(libssh2_session_last_errno(sshc->ssh_session) ==
1063 LIBSSH2_ERROR_EAGAIN) {
1064 rc = LIBSSH2_ERROR_EAGAIN;
1070 (void)libssh2_session_last_error(sshc->ssh_session,
1072 failf(data, "Failure initializing sftp session: %s", err_msg);
1073 state(conn, SSH_SESSION_FREE);
1074 sshc->actualcode = CURLE_FAILED_INIT;
1078 state(conn, SSH_SFTP_REALPATH);
1081 case SSH_SFTP_REALPATH:
1083 char tempHome[PATH_MAX];
1086 * Get the "home" directory
1088 rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
1089 tempHome, PATH_MAX-1);
1090 if(rc == LIBSSH2_ERROR_EAGAIN) {
1094 /* It seems that this string is not always NULL terminated */
1095 tempHome[rc] = '\0';
1096 sshc->homedir = strdup(tempHome);
1097 if(!sshc->homedir) {
1098 state(conn, SSH_SFTP_CLOSE);
1099 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1102 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1105 /* Return the error type */
1106 err = sftp_libssh2_last_error(sshc->sftp_session);
1107 result = sftp_libssh2_error_to_CURLE(err);
1108 sshc->actualcode = result?result:CURLE_SSH;
1109 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1111 state(conn, SSH_STOP);
1115 /* This is the last step in the SFTP connect phase. Do note that while
1116 we get the homedir here, we get the "workingpath" in the DO action
1117 since the homedir will remain the same between request but the
1118 working path will not. */
1119 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1120 state(conn, SSH_STOP);
1123 case SSH_SFTP_QUOTE_INIT:
1125 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1127 sshc->actualcode = result;
1128 state(conn, SSH_STOP);
1132 if(data->set.quote) {
1133 infof(data, "Sending quote commands\n");
1134 sshc->quote_item = data->set.quote;
1135 state(conn, SSH_SFTP_QUOTE);
1138 state(conn, SSH_SFTP_TRANS_INIT);
1142 case SSH_SFTP_POSTQUOTE_INIT:
1143 if(data->set.postquote) {
1144 infof(data, "Sending quote commands\n");
1145 sshc->quote_item = data->set.postquote;
1146 state(conn, SSH_SFTP_QUOTE);
1149 state(conn, SSH_STOP);
1153 case SSH_SFTP_QUOTE:
1154 /* Send any quote commands */
1159 * Support some of the "FTP" commands
1161 char *cmd = sshc->quote_item->data;
1162 sshc->acceptfail = FALSE;
1164 /* if a command starts with an asterisk, which a legal SFTP command never
1165 can, the command will be allowed to fail without it causing any
1166 aborts or cancels etc. It will cause libcurl to act as if the command
1167 is successful, whatever the server reponds. */
1171 sshc->acceptfail = TRUE;
1174 if(curl_strequal("pwd", cmd)) {
1175 /* output debug output if that is requested */
1176 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1179 result = CURLE_OUT_OF_MEMORY;
1180 state(conn, SSH_SFTP_CLOSE);
1181 sshc->nextstate = SSH_NO_STATE;
1184 if(data->set.verbose) {
1185 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1186 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1188 /* this sends an FTP-like "header" to the header callback so that the
1189 current directory can be read very similar to how it is read when
1190 using ordinary FTP. */
1191 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1193 state(conn, SSH_SFTP_NEXT_QUOTE);
1198 * the arguments following the command must be separated from the
1199 * command with a space so we can check for it unconditionally
1201 cp = strchr(cmd, ' ');
1203 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1204 state(conn, SSH_SFTP_CLOSE);
1205 sshc->nextstate = SSH_NO_STATE;
1206 sshc->actualcode = CURLE_QUOTE_ERROR;
1211 * also, every command takes at least one argument so we get that
1212 * first argument right now
1214 result = get_pathname(&cp, &sshc->quote_path1);
1216 if(result == CURLE_OUT_OF_MEMORY)
1217 failf(data, "Out of memory");
1219 failf(data, "Syntax error: Bad first parameter");
1220 state(conn, SSH_SFTP_CLOSE);
1221 sshc->nextstate = SSH_NO_STATE;
1222 sshc->actualcode = result;
1227 * SFTP is a binary protocol, so we don't send text commands to
1228 * the server. Instead, we scan for commands for commands used by
1229 * OpenSSH's sftp program and call the appropriate libssh2
1232 if(curl_strnequal(cmd, "chgrp ", 6) ||
1233 curl_strnequal(cmd, "chmod ", 6) ||
1234 curl_strnequal(cmd, "chown ", 6) ) {
1235 /* attribute change */
1237 /* sshc->quote_path1 contains the mode to set */
1238 /* get the destination */
1239 result = get_pathname(&cp, &sshc->quote_path2);
1241 if(result == CURLE_OUT_OF_MEMORY)
1242 failf(data, "Out of memory");
1244 failf(data, "Syntax error in chgrp/chmod/chown: "
1245 "Bad second parameter");
1246 Curl_safefree(sshc->quote_path1);
1247 state(conn, SSH_SFTP_CLOSE);
1248 sshc->nextstate = SSH_NO_STATE;
1249 sshc->actualcode = result;
1252 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1253 state(conn, SSH_SFTP_QUOTE_STAT);
1256 else if(curl_strnequal(cmd, "ln ", 3) ||
1257 curl_strnequal(cmd, "symlink ", 8)) {
1258 /* symbolic linking */
1259 /* sshc->quote_path1 is the source */
1260 /* get the destination */
1261 result = get_pathname(&cp, &sshc->quote_path2);
1263 if(result == CURLE_OUT_OF_MEMORY)
1264 failf(data, "Out of memory");
1267 "Syntax error in ln/symlink: Bad second parameter");
1268 Curl_safefree(sshc->quote_path1);
1269 state(conn, SSH_SFTP_CLOSE);
1270 sshc->nextstate = SSH_NO_STATE;
1271 sshc->actualcode = result;
1274 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1277 else if(curl_strnequal(cmd, "mkdir ", 6)) {
1279 state(conn, SSH_SFTP_QUOTE_MKDIR);
1282 else if(curl_strnequal(cmd, "rename ", 7)) {
1284 /* first param is the source path */
1285 /* second param is the dest. path */
1286 result = get_pathname(&cp, &sshc->quote_path2);
1288 if(result == CURLE_OUT_OF_MEMORY)
1289 failf(data, "Out of memory");
1291 failf(data, "Syntax error in rename: Bad second parameter");
1292 Curl_safefree(sshc->quote_path1);
1293 state(conn, SSH_SFTP_CLOSE);
1294 sshc->nextstate = SSH_NO_STATE;
1295 sshc->actualcode = result;
1298 state(conn, SSH_SFTP_QUOTE_RENAME);
1301 else if(curl_strnequal(cmd, "rmdir ", 6)) {
1303 state(conn, SSH_SFTP_QUOTE_RMDIR);
1306 else if(curl_strnequal(cmd, "rm ", 3)) {
1307 state(conn, SSH_SFTP_QUOTE_UNLINK);
1311 failf(data, "Unknown SFTP command");
1312 Curl_safefree(sshc->quote_path1);
1313 Curl_safefree(sshc->quote_path2);
1314 state(conn, SSH_SFTP_CLOSE);
1315 sshc->nextstate = SSH_NO_STATE;
1316 sshc->actualcode = CURLE_QUOTE_ERROR;
1320 if(!sshc->quote_item) {
1321 state(conn, SSH_SFTP_TRANS_INIT);
1325 case SSH_SFTP_NEXT_QUOTE:
1326 Curl_safefree(sshc->quote_path1);
1327 Curl_safefree(sshc->quote_path2);
1329 sshc->quote_item = sshc->quote_item->next;
1331 if(sshc->quote_item) {
1332 state(conn, SSH_SFTP_QUOTE);
1335 if(sshc->nextstate != SSH_NO_STATE) {
1336 state(conn, sshc->nextstate);
1337 sshc->nextstate = SSH_NO_STATE;
1340 state(conn, SSH_SFTP_TRANS_INIT);
1345 case SSH_SFTP_QUOTE_STAT:
1347 char *cmd = sshc->quote_item->data;
1348 sshc->acceptfail = FALSE;
1350 /* if a command starts with an asterisk, which a legal SFTP command never
1351 can, the command will be allowed to fail without it causing any
1352 aborts or cancels etc. It will cause libcurl to act as if the command
1353 is successful, whatever the server reponds. */
1357 sshc->acceptfail = TRUE;
1360 if(!curl_strnequal(cmd, "chmod", 5)) {
1361 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1362 * set them both at once, we need to obtain the current ownership
1363 * first. This takes an extra protocol round trip.
1365 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1366 curlx_uztoui(strlen(sshc->quote_path2)),
1368 &sshc->quote_attrs);
1369 if(rc == LIBSSH2_ERROR_EAGAIN) {
1372 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1373 err = sftp_libssh2_last_error(sshc->sftp_session);
1374 Curl_safefree(sshc->quote_path1);
1375 Curl_safefree(sshc->quote_path2);
1376 failf(data, "Attempt to get SFTP stats failed: %s",
1377 sftp_libssh2_strerror(err));
1378 state(conn, SSH_SFTP_CLOSE);
1379 sshc->nextstate = SSH_NO_STATE;
1380 sshc->actualcode = CURLE_QUOTE_ERROR;
1385 /* Now set the new attributes... */
1386 if(curl_strnequal(cmd, "chgrp", 5)) {
1387 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1388 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1389 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1390 !sshc->acceptfail) {
1391 Curl_safefree(sshc->quote_path1);
1392 Curl_safefree(sshc->quote_path2);
1393 failf(data, "Syntax error: chgrp gid not a number");
1394 state(conn, SSH_SFTP_CLOSE);
1395 sshc->nextstate = SSH_NO_STATE;
1396 sshc->actualcode = CURLE_QUOTE_ERROR;
1400 else if(curl_strnequal(cmd, "chmod", 5)) {
1401 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1402 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1403 /* permissions are octal */
1404 if(sshc->quote_attrs.permissions == 0 &&
1405 !ISDIGIT(sshc->quote_path1[0])) {
1406 Curl_safefree(sshc->quote_path1);
1407 Curl_safefree(sshc->quote_path2);
1408 failf(data, "Syntax error: chmod permissions not a number");
1409 state(conn, SSH_SFTP_CLOSE);
1410 sshc->nextstate = SSH_NO_STATE;
1411 sshc->actualcode = CURLE_QUOTE_ERROR;
1415 else if(curl_strnequal(cmd, "chown", 5)) {
1416 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1417 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1418 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1419 !sshc->acceptfail) {
1420 Curl_safefree(sshc->quote_path1);
1421 Curl_safefree(sshc->quote_path2);
1422 failf(data, "Syntax error: chown uid not a number");
1423 state(conn, SSH_SFTP_CLOSE);
1424 sshc->nextstate = SSH_NO_STATE;
1425 sshc->actualcode = CURLE_QUOTE_ERROR;
1430 /* Now send the completed structure... */
1431 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1435 case SSH_SFTP_QUOTE_SETSTAT:
1436 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1437 curlx_uztoui(strlen(sshc->quote_path2)),
1438 LIBSSH2_SFTP_SETSTAT,
1439 &sshc->quote_attrs);
1440 if(rc == LIBSSH2_ERROR_EAGAIN) {
1443 else if(rc != 0 && !sshc->acceptfail) {
1444 err = sftp_libssh2_last_error(sshc->sftp_session);
1445 Curl_safefree(sshc->quote_path1);
1446 Curl_safefree(sshc->quote_path2);
1447 failf(data, "Attempt to set SFTP stats failed: %s",
1448 sftp_libssh2_strerror(err));
1449 state(conn, SSH_SFTP_CLOSE);
1450 sshc->nextstate = SSH_NO_STATE;
1451 sshc->actualcode = CURLE_QUOTE_ERROR;
1454 state(conn, SSH_SFTP_NEXT_QUOTE);
1457 case SSH_SFTP_QUOTE_SYMLINK:
1458 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1459 curlx_uztoui(strlen(sshc->quote_path1)),
1461 curlx_uztoui(strlen(sshc->quote_path2)),
1462 LIBSSH2_SFTP_SYMLINK);
1463 if(rc == LIBSSH2_ERROR_EAGAIN) {
1466 else if(rc != 0 && !sshc->acceptfail) {
1467 err = sftp_libssh2_last_error(sshc->sftp_session);
1468 Curl_safefree(sshc->quote_path1);
1469 Curl_safefree(sshc->quote_path2);
1470 failf(data, "symlink command failed: %s",
1471 sftp_libssh2_strerror(err));
1472 state(conn, SSH_SFTP_CLOSE);
1473 sshc->nextstate = SSH_NO_STATE;
1474 sshc->actualcode = CURLE_QUOTE_ERROR;
1477 state(conn, SSH_SFTP_NEXT_QUOTE);
1480 case SSH_SFTP_QUOTE_MKDIR:
1481 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1482 curlx_uztoui(strlen(sshc->quote_path1)),
1483 data->set.new_directory_perms);
1484 if(rc == LIBSSH2_ERROR_EAGAIN) {
1487 else if(rc != 0 && !sshc->acceptfail) {
1488 err = sftp_libssh2_last_error(sshc->sftp_session);
1489 Curl_safefree(sshc->quote_path1);
1490 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1491 state(conn, SSH_SFTP_CLOSE);
1492 sshc->nextstate = SSH_NO_STATE;
1493 sshc->actualcode = CURLE_QUOTE_ERROR;
1496 state(conn, SSH_SFTP_NEXT_QUOTE);
1499 case SSH_SFTP_QUOTE_RENAME:
1500 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1501 curlx_uztoui(strlen(sshc->quote_path1)),
1503 curlx_uztoui(strlen(sshc->quote_path2)),
1504 LIBSSH2_SFTP_RENAME_OVERWRITE |
1505 LIBSSH2_SFTP_RENAME_ATOMIC |
1506 LIBSSH2_SFTP_RENAME_NATIVE);
1508 if(rc == LIBSSH2_ERROR_EAGAIN) {
1511 else if(rc != 0 && !sshc->acceptfail) {
1512 err = sftp_libssh2_last_error(sshc->sftp_session);
1513 Curl_safefree(sshc->quote_path1);
1514 Curl_safefree(sshc->quote_path2);
1515 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1516 state(conn, SSH_SFTP_CLOSE);
1517 sshc->nextstate = SSH_NO_STATE;
1518 sshc->actualcode = CURLE_QUOTE_ERROR;
1521 state(conn, SSH_SFTP_NEXT_QUOTE);
1524 case SSH_SFTP_QUOTE_RMDIR:
1525 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1526 curlx_uztoui(strlen(sshc->quote_path1)));
1527 if(rc == LIBSSH2_ERROR_EAGAIN) {
1530 else if(rc != 0 && !sshc->acceptfail) {
1531 err = sftp_libssh2_last_error(sshc->sftp_session);
1532 Curl_safefree(sshc->quote_path1);
1533 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1534 state(conn, SSH_SFTP_CLOSE);
1535 sshc->nextstate = SSH_NO_STATE;
1536 sshc->actualcode = CURLE_QUOTE_ERROR;
1539 state(conn, SSH_SFTP_NEXT_QUOTE);
1542 case SSH_SFTP_QUOTE_UNLINK:
1543 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1544 curlx_uztoui(strlen(sshc->quote_path1)));
1545 if(rc == LIBSSH2_ERROR_EAGAIN) {
1548 else if(rc != 0 && !sshc->acceptfail) {
1549 err = sftp_libssh2_last_error(sshc->sftp_session);
1550 Curl_safefree(sshc->quote_path1);
1551 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1552 state(conn, SSH_SFTP_CLOSE);
1553 sshc->nextstate = SSH_NO_STATE;
1554 sshc->actualcode = CURLE_QUOTE_ERROR;
1557 state(conn, SSH_SFTP_NEXT_QUOTE);
1560 case SSH_SFTP_TRANS_INIT:
1561 if(data->set.upload)
1562 state(conn, SSH_SFTP_UPLOAD_INIT);
1564 if(data->set.opt_no_body)
1565 state(conn, SSH_STOP);
1566 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1567 state(conn, SSH_SFTP_READDIR_INIT);
1569 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1573 case SSH_SFTP_UPLOAD_INIT:
1575 unsigned long flags;
1577 * NOTE!!! libssh2 requires that the destination path is a full path
1578 * that includes the destination file and name OR ends in a "/"
1579 * If this is not done the destination file will be named the
1580 * same name as the last directory in the path.
1583 if(data->state.resume_from != 0) {
1584 LIBSSH2_SFTP_ATTRIBUTES attrs;
1585 if(data->state.resume_from < 0) {
1586 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1587 curlx_uztoui(strlen(sftp_scp->path)),
1588 LIBSSH2_SFTP_STAT, &attrs);
1589 if(rc == LIBSSH2_ERROR_EAGAIN) {
1593 data->state.resume_from = 0;
1596 curl_off_t size = attrs.filesize;
1598 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1599 return CURLE_BAD_DOWNLOAD_RESUME;
1601 data->state.resume_from = attrs.filesize;
1606 if(data->set.ftp_append)
1607 /* Try to open for append, but create if nonexisting */
1608 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1609 else if(data->state.resume_from > 0)
1610 /* If we have restart position then open for append */
1611 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1613 /* Clear file before writing (normal behaviour) */
1614 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1617 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1618 curlx_uztoui(strlen(sftp_scp->path)),
1619 flags, data->set.new_file_perms,
1620 LIBSSH2_SFTP_OPENFILE);
1622 if(!sshc->sftp_handle) {
1623 rc = libssh2_session_last_errno(sshc->ssh_session);
1625 if(LIBSSH2_ERROR_EAGAIN == rc)
1628 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1629 /* only when there was an SFTP protocol error can we extract
1631 err = sftp_libssh2_last_error(sshc->sftp_session);
1633 err = -1; /* not an sftp error at all */
1635 if(sshc->secondCreateDirs) {
1636 state(conn, SSH_SFTP_CLOSE);
1637 sshc->actualcode = err>= LIBSSH2_FX_OK?
1638 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1639 failf(data, "Creating the dir/file failed: %s",
1640 sftp_libssh2_strerror(err));
1643 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1644 (err == LIBSSH2_FX_FAILURE) ||
1645 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1646 (data->set.ftp_create_missing_dirs &&
1647 (strlen(sftp_scp->path) > 1))) {
1648 /* try to create the path remotely */
1649 sshc->secondCreateDirs = 1;
1650 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1653 state(conn, SSH_SFTP_CLOSE);
1654 sshc->actualcode = err>= LIBSSH2_FX_OK?
1655 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1656 if(!sshc->actualcode) {
1657 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1658 zero even though libssh2_sftp_open() failed previously! We need
1659 to work around that! */
1660 sshc->actualcode = CURLE_SSH;
1663 failf(data, "Upload failed: %s (%d/%d)",
1664 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1670 /* If we have restart point then we need to seek to the correct
1672 if(data->state.resume_from > 0) {
1673 /* Let's read off the proper amount of bytes from the input. */
1674 if(conn->seek_func) {
1675 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1679 if(seekerr != CURL_SEEKFUNC_OK) {
1681 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1682 failf(data, "Could not seek stream");
1683 return CURLE_FTP_COULDNT_USE_REST;
1685 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1687 curl_off_t passed=0;
1689 size_t readthisamountnow =
1690 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1691 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1693 size_t actuallyread =
1694 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1697 passed += actuallyread;
1698 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1699 /* this checks for greater-than only to make sure that the
1700 CURL_READFUNC_ABORT return code still aborts */
1701 failf(data, "Failed to read data");
1702 return CURLE_FTP_COULDNT_USE_REST;
1704 } while(passed < data->state.resume_from);
1708 /* now, decrease the size of the read */
1709 if(data->set.infilesize > 0) {
1710 data->set.infilesize -= data->state.resume_from;
1711 data->req.size = data->set.infilesize;
1712 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1715 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1717 if(data->set.infilesize > 0) {
1718 data->req.size = data->set.infilesize;
1719 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1722 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1724 /* not set by Curl_setup_transfer to preserve keepon bits */
1725 conn->sockfd = conn->writesockfd;
1728 state(conn, SSH_SFTP_CLOSE);
1729 sshc->actualcode = result;
1732 /* store this original bitmask setup to use later on if we can't
1733 figure out a "real" bitmask */
1734 sshc->orig_waitfor = data->req.keepon;
1736 /* we want to use the _sending_ function even when the socket turns
1737 out readable as the underlying libssh2 sftp send function will deal
1738 with both accordingly */
1739 conn->cselect_bits = CURL_CSELECT_OUT;
1741 /* since we don't really wait for anything at this point, we want the
1742 state machine to move on as soon as possible so we set a very short
1744 Curl_expire(data, 1);
1746 state(conn, SSH_STOP);
1751 case SSH_SFTP_CREATE_DIRS_INIT:
1752 if(strlen(sftp_scp->path) > 1) {
1753 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1754 state(conn, SSH_SFTP_CREATE_DIRS);
1757 state(conn, SSH_SFTP_UPLOAD_INIT);
1761 case SSH_SFTP_CREATE_DIRS:
1762 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1763 *sshc->slash_pos = 0;
1765 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1766 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1770 state(conn, SSH_SFTP_UPLOAD_INIT);
1774 case SSH_SFTP_CREATE_DIRS_MKDIR:
1775 /* 'mode' - parameter is preliminary - default to 0644 */
1776 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1777 curlx_uztoui(strlen(sftp_scp->path)),
1778 data->set.new_directory_perms);
1779 if(rc == LIBSSH2_ERROR_EAGAIN) {
1782 *sshc->slash_pos = '/';
1786 * Abort if failure wasn't that the dir already exists or the
1787 * permission was denied (creation might succeed further down the
1788 * path) - retry on unspecific FAILURE also
1790 err = sftp_libssh2_last_error(sshc->sftp_session);
1791 if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1792 (err != LIBSSH2_FX_FAILURE) &&
1793 (err != LIBSSH2_FX_PERMISSION_DENIED)) {
1794 result = sftp_libssh2_error_to_CURLE(err);
1795 state(conn, SSH_SFTP_CLOSE);
1796 sshc->actualcode = result?result:CURLE_SSH;
1800 state(conn, SSH_SFTP_CREATE_DIRS);
1803 case SSH_SFTP_READDIR_INIT:
1805 * This is a directory that we are trying to get, so produce a directory
1808 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1811 strlen(sftp_scp->path)),
1812 0, 0, LIBSSH2_SFTP_OPENDIR);
1813 if(!sshc->sftp_handle) {
1814 if(libssh2_session_last_errno(sshc->ssh_session) ==
1815 LIBSSH2_ERROR_EAGAIN) {
1816 rc = LIBSSH2_ERROR_EAGAIN;
1820 err = sftp_libssh2_last_error(sshc->sftp_session);
1821 failf(data, "Could not open directory for reading: %s",
1822 sftp_libssh2_strerror(err));
1823 state(conn, SSH_SFTP_CLOSE);
1824 result = sftp_libssh2_error_to_CURLE(err);
1825 sshc->actualcode = result?result:CURLE_SSH;
1829 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1830 state(conn, SSH_SFTP_CLOSE);
1831 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1834 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1835 Curl_safefree(sshc->readdir_filename);
1836 state(conn, SSH_SFTP_CLOSE);
1837 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1840 state(conn, SSH_SFTP_READDIR);
1843 case SSH_SFTP_READDIR:
1844 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1845 sshc->readdir_filename,
1847 sshc->readdir_longentry,
1849 &sshc->readdir_attrs);
1850 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1851 rc = LIBSSH2_ERROR_EAGAIN;
1854 if(sshc->readdir_len > 0) {
1855 sshc->readdir_filename[sshc->readdir_len] = '\0';
1857 if(data->set.ftp_list_only) {
1860 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1861 if(tmpLine == NULL) {
1862 state(conn, SSH_SFTP_CLOSE);
1863 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1866 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1867 tmpLine, sshc->readdir_len+1);
1868 Curl_safefree(tmpLine);
1871 state(conn, SSH_STOP);
1874 /* since this counts what we send to the client, we include the
1875 newline in this counter */
1876 data->req.bytecount += sshc->readdir_len+1;
1878 /* output debug output if that is requested */
1879 if(data->set.verbose) {
1880 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1881 sshc->readdir_len, conn);
1885 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1886 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1887 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1888 if(!sshc->readdir_line) {
1889 Curl_safefree(sshc->readdir_filename);
1890 Curl_safefree(sshc->readdir_longentry);
1891 state(conn, SSH_SFTP_CLOSE);
1892 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1896 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1897 sshc->readdir_currLen);
1898 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1899 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1900 LIBSSH2_SFTP_S_IFLNK)) {
1901 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1902 if(sshc->readdir_linkPath == NULL) {
1903 Curl_safefree(sshc->readdir_filename);
1904 Curl_safefree(sshc->readdir_longentry);
1905 state(conn, SSH_SFTP_CLOSE);
1906 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1910 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1911 sshc->readdir_filename);
1912 state(conn, SSH_SFTP_READDIR_LINK);
1915 state(conn, SSH_SFTP_READDIR_BOTTOM);
1919 else if(sshc->readdir_len == 0) {
1920 Curl_safefree(sshc->readdir_filename);
1921 Curl_safefree(sshc->readdir_longentry);
1922 state(conn, SSH_SFTP_READDIR_DONE);
1925 else if(sshc->readdir_len <= 0) {
1926 err = sftp_libssh2_last_error(sshc->sftp_session);
1927 result = sftp_libssh2_error_to_CURLE(err);
1928 sshc->actualcode = result?result:CURLE_SSH;
1929 failf(data, "Could not open remote file for reading: %s :: %d",
1930 sftp_libssh2_strerror(err),
1931 libssh2_session_last_errno(sshc->ssh_session));
1932 Curl_safefree(sshc->readdir_filename);
1933 Curl_safefree(sshc->readdir_longentry);
1934 state(conn, SSH_SFTP_CLOSE);
1939 case SSH_SFTP_READDIR_LINK:
1941 libssh2_sftp_symlink_ex(sshc->sftp_session,
1942 sshc->readdir_linkPath,
1943 curlx_uztoui(strlen(sshc->readdir_linkPath)),
1944 sshc->readdir_filename,
1945 PATH_MAX, LIBSSH2_SFTP_READLINK);
1946 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1947 rc = LIBSSH2_ERROR_EAGAIN;
1950 Curl_safefree(sshc->readdir_linkPath);
1952 /* get room for the filename and extra output */
1953 sshc->readdir_totalLen += 4 + sshc->readdir_len;
1954 new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
1955 if(!new_readdir_line) {
1956 Curl_safefree(sshc->readdir_line);
1957 Curl_safefree(sshc->readdir_filename);
1958 Curl_safefree(sshc->readdir_longentry);
1959 state(conn, SSH_SFTP_CLOSE);
1960 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1963 sshc->readdir_line = new_readdir_line;
1965 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1966 sshc->readdir_currLen,
1967 sshc->readdir_totalLen -
1968 sshc->readdir_currLen,
1970 sshc->readdir_filename);
1972 state(conn, SSH_SFTP_READDIR_BOTTOM);
1975 case SSH_SFTP_READDIR_BOTTOM:
1976 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1977 sshc->readdir_currLen,
1978 sshc->readdir_totalLen -
1979 sshc->readdir_currLen, "\n");
1980 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1982 sshc->readdir_currLen);
1984 if(result == CURLE_OK) {
1986 /* output debug output if that is requested */
1987 if(data->set.verbose) {
1988 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1989 sshc->readdir_currLen, conn);
1991 data->req.bytecount += sshc->readdir_currLen;
1993 Curl_safefree(sshc->readdir_line);
1995 state(conn, SSH_STOP);
1998 state(conn, SSH_SFTP_READDIR);
2001 case SSH_SFTP_READDIR_DONE:
2002 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
2003 LIBSSH2_ERROR_EAGAIN) {
2004 rc = LIBSSH2_ERROR_EAGAIN;
2007 sshc->sftp_handle = NULL;
2008 Curl_safefree(sshc->readdir_filename);
2009 Curl_safefree(sshc->readdir_longentry);
2011 /* no data to transfer */
2012 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2013 state(conn, SSH_STOP);
2016 case SSH_SFTP_DOWNLOAD_INIT:
2018 * Work on getting the specified file
2021 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
2022 curlx_uztoui(strlen(sftp_scp->path)),
2023 LIBSSH2_FXF_READ, data->set.new_file_perms,
2024 LIBSSH2_SFTP_OPENFILE);
2025 if(!sshc->sftp_handle) {
2026 if(libssh2_session_last_errno(sshc->ssh_session) ==
2027 LIBSSH2_ERROR_EAGAIN) {
2028 rc = LIBSSH2_ERROR_EAGAIN;
2032 err = sftp_libssh2_last_error(sshc->sftp_session);
2033 failf(data, "Could not open remote file for reading: %s",
2034 sftp_libssh2_strerror(err));
2035 state(conn, SSH_SFTP_CLOSE);
2036 result = sftp_libssh2_error_to_CURLE(err);
2037 sshc->actualcode = result?result:CURLE_SSH;
2041 state(conn, SSH_SFTP_DOWNLOAD_STAT);
2044 case SSH_SFTP_DOWNLOAD_STAT:
2046 LIBSSH2_SFTP_ATTRIBUTES attrs;
2048 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
2049 curlx_uztoui(strlen(sftp_scp->path)),
2050 LIBSSH2_SFTP_STAT, &attrs);
2051 if(rc == LIBSSH2_ERROR_EAGAIN) {
2056 * libssh2_sftp_open() didn't return an error, so maybe the server
2057 * just doesn't support stat()
2059 data->req.size = -1;
2060 data->req.maxdownload = -1;
2063 curl_off_t size = attrs.filesize;
2066 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
2067 return CURLE_BAD_DOWNLOAD_RESUME;
2069 if(conn->data->state.use_range) {
2070 curl_off_t from, to;
2074 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2075 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2077 to=curlx_strtoofft(ptr, &ptr2, 0);
2078 if((ptr == ptr2) /* no "to" value given */
2083 /* from is relative to end of file */
2087 failf(data, "Offset (%"
2088 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2089 from, attrs.filesize);
2090 return CURLE_BAD_DOWNLOAD_RESUME;
2097 size = to - from + 1;
2100 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2102 data->req.size = size;
2103 data->req.maxdownload = size;
2104 Curl_pgrsSetDownloadSize(data, size);
2107 /* We can resume if we can seek to the resume position */
2108 if(data->state.resume_from) {
2109 if(data->state.resume_from < 0) {
2110 /* We're supposed to download the last abs(from) bytes */
2111 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2112 failf(data, "Offset (%"
2113 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2114 data->state.resume_from, attrs.filesize);
2115 return CURLE_BAD_DOWNLOAD_RESUME;
2117 /* download from where? */
2118 data->state.resume_from += attrs.filesize;
2121 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2122 failf(data, "Offset (%" FORMAT_OFF_T
2123 ") was beyond file size (%" FORMAT_OFF_T ")",
2124 data->state.resume_from, attrs.filesize);
2125 return CURLE_BAD_DOWNLOAD_RESUME;
2128 /* Does a completed file need to be seeked and started or closed ? */
2129 /* Now store the number of bytes we are expected to download */
2130 data->req.size = attrs.filesize - data->state.resume_from;
2131 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2132 Curl_pgrsSetDownloadSize(data,
2133 attrs.filesize - data->state.resume_from);
2134 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2137 /* Setup the actual download */
2138 if(data->req.size == 0) {
2139 /* no data to transfer */
2140 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2141 infof(data, "File already completely downloaded\n");
2142 state(conn, SSH_STOP);
2146 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2147 FALSE, NULL, -1, NULL);
2149 /* not set by Curl_setup_transfer to preserve keepon bits */
2150 conn->writesockfd = conn->sockfd;
2152 /* we want to use the _receiving_ function even when the socket turns
2153 out writableable as the underlying libssh2 recv function will deal
2154 with both accordingly */
2155 conn->cselect_bits = CURL_CSELECT_IN;
2158 state(conn, SSH_SFTP_CLOSE);
2159 sshc->actualcode = result;
2162 state(conn, SSH_STOP);
2166 case SSH_SFTP_CLOSE:
2167 if(sshc->sftp_handle) {
2168 rc = libssh2_sftp_close(sshc->sftp_handle);
2169 if(rc == LIBSSH2_ERROR_EAGAIN) {
2173 infof(data, "Failed to close libssh2 file\n");
2175 sshc->sftp_handle = NULL;
2178 Curl_safefree(sftp_scp->path);
2180 DEBUGF(infof(data, "SFTP DONE done\n"));
2182 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2183 After nextstate is executed,the control should come back to
2184 SSH_SFTP_CLOSE to pass the correct result back */
2185 if(sshc->nextstate != SSH_NO_STATE) {
2186 state(conn, sshc->nextstate);
2187 sshc->nextstate = SSH_SFTP_CLOSE;
2190 state(conn, SSH_STOP);
2191 result = sshc->actualcode;
2195 case SSH_SFTP_SHUTDOWN:
2196 /* during times we get here due to a broken transfer and then the
2197 sftp_handle might not have been taken down so make sure that is done
2198 before we proceed */
2200 if(sshc->sftp_handle) {
2201 rc = libssh2_sftp_close(sshc->sftp_handle);
2202 if(rc == LIBSSH2_ERROR_EAGAIN) {
2206 infof(data, "Failed to close libssh2 file\n");
2208 sshc->sftp_handle = NULL;
2210 if(sshc->sftp_session) {
2211 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2212 if(rc == LIBSSH2_ERROR_EAGAIN) {
2216 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2218 sshc->sftp_session = NULL;
2221 Curl_safefree(sshc->homedir);
2222 conn->data->state.most_recent_ftp_entrypath = NULL;
2224 state(conn, SSH_SESSION_DISCONNECT);
2227 case SSH_SCP_TRANS_INIT:
2228 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2230 sshc->actualcode = result;
2231 state(conn, SSH_STOP);
2235 if(data->set.upload) {
2236 if(data->set.infilesize < 0) {
2237 failf(data, "SCP requires a known file size for upload");
2238 sshc->actualcode = CURLE_UPLOAD_FAILED;
2239 state(conn, SSH_SCP_CHANNEL_FREE);
2242 state(conn, SSH_SCP_UPLOAD_INIT);
2245 state(conn, SSH_SCP_DOWNLOAD_INIT);
2249 case SSH_SCP_UPLOAD_INIT:
2251 * libssh2 requires that the destination path is a full path that
2252 * includes the destination file and name OR ends in a "/" . If this is
2253 * not done the destination file will be named the same name as the last
2254 * directory in the path.
2257 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2258 data->set.infilesize);
2259 if(!sshc->ssh_channel) {
2260 if(libssh2_session_last_errno(sshc->ssh_session) ==
2261 LIBSSH2_ERROR_EAGAIN) {
2262 rc = LIBSSH2_ERROR_EAGAIN;
2269 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2270 &err_msg, NULL, 0));
2271 failf(conn->data, "%s", err_msg);
2272 state(conn, SSH_SCP_CHANNEL_FREE);
2273 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2279 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2282 /* not set by Curl_setup_transfer to preserve keepon bits */
2283 conn->sockfd = conn->writesockfd;
2286 state(conn, SSH_SCP_CHANNEL_FREE);
2287 sshc->actualcode = result;
2290 /* we want to use the _sending_ function even when the socket turns
2291 out readable as the underlying libssh2 scp send function will deal
2292 with both accordingly */
2293 conn->cselect_bits = CURL_CSELECT_OUT;
2295 state(conn, SSH_STOP);
2299 case SSH_SCP_DOWNLOAD_INIT:
2302 * We must check the remote file; if it is a directory no values will
2306 curl_off_t bytecount;
2308 /* clear the struct scp recv will fill in */
2309 memset(&sb, 0, sizeof(struct stat));
2311 /* get a fresh new channel from the ssh layer */
2312 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2313 sftp_scp->path, &sb);
2314 if(!sshc->ssh_channel) {
2315 if(libssh2_session_last_errno(sshc->ssh_session) ==
2316 LIBSSH2_ERROR_EAGAIN) {
2317 rc = LIBSSH2_ERROR_EAGAIN;
2324 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2325 &err_msg, NULL, 0));
2326 failf(conn->data, "%s", err_msg);
2327 state(conn, SSH_SCP_CHANNEL_FREE);
2328 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2334 bytecount = (curl_off_t)sb.st_size;
2335 data->req.maxdownload = (curl_off_t)sb.st_size;
2336 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2338 /* not set by Curl_setup_transfer to preserve keepon bits */
2339 conn->writesockfd = conn->sockfd;
2341 /* we want to use the _receiving_ function even when the socket turns
2342 out writableable as the underlying libssh2 recv function will deal
2343 with both accordingly */
2344 conn->cselect_bits = CURL_CSELECT_IN;
2347 state(conn, SSH_SCP_CHANNEL_FREE);
2348 sshc->actualcode = result;
2351 state(conn, SSH_STOP);
2356 if(data->set.upload)
2357 state(conn, SSH_SCP_SEND_EOF);
2359 state(conn, SSH_SCP_CHANNEL_FREE);
2362 case SSH_SCP_SEND_EOF:
2363 if(sshc->ssh_channel) {
2364 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2365 if(rc == LIBSSH2_ERROR_EAGAIN) {
2369 infof(data, "Failed to send libssh2 channel EOF\n");
2372 state(conn, SSH_SCP_WAIT_EOF);
2375 case SSH_SCP_WAIT_EOF:
2376 if(sshc->ssh_channel) {
2377 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2378 if(rc == LIBSSH2_ERROR_EAGAIN) {
2382 infof(data, "Failed to get channel EOF: %d\n", rc);
2385 state(conn, SSH_SCP_WAIT_CLOSE);
2388 case SSH_SCP_WAIT_CLOSE:
2389 if(sshc->ssh_channel) {
2390 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2391 if(rc == LIBSSH2_ERROR_EAGAIN) {
2395 infof(data, "Channel failed to close: %d\n", rc);
2398 state(conn, SSH_SCP_CHANNEL_FREE);
2401 case SSH_SCP_CHANNEL_FREE:
2402 if(sshc->ssh_channel) {
2403 rc = libssh2_channel_free(sshc->ssh_channel);
2404 if(rc == LIBSSH2_ERROR_EAGAIN) {
2408 infof(data, "Failed to free libssh2 scp subsystem\n");
2410 sshc->ssh_channel = NULL;
2412 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2414 state(conn, SSH_SESSION_DISCONNECT);
2416 state(conn, SSH_STOP);
2417 result = sshc->actualcode;
2420 case SSH_SESSION_DISCONNECT:
2421 /* during weird times when we've been prematurely aborted, the channel
2422 is still alive when we reach this state and we MUST kill the channel
2424 if(sshc->ssh_channel) {
2425 rc = libssh2_channel_free(sshc->ssh_channel);
2426 if(rc == LIBSSH2_ERROR_EAGAIN) {
2430 infof(data, "Failed to free libssh2 scp subsystem\n");
2432 sshc->ssh_channel = NULL;
2435 if(sshc->ssh_session) {
2436 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2437 if(rc == LIBSSH2_ERROR_EAGAIN) {
2441 infof(data, "Failed to disconnect libssh2 session\n");
2445 Curl_safefree(sshc->homedir);
2446 conn->data->state.most_recent_ftp_entrypath = NULL;
2448 state(conn, SSH_SESSION_FREE);
2451 case SSH_SESSION_FREE:
2452 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2454 libssh2_knownhost_free(sshc->kh);
2459 #ifdef HAVE_LIBSSH2_AGENT_API
2460 if(sshc->ssh_agent) {
2461 rc = libssh2_agent_disconnect(sshc->ssh_agent);
2462 if(rc == LIBSSH2_ERROR_EAGAIN) {
2466 infof(data, "Failed to disconnect from libssh2 agent\n");
2468 libssh2_agent_free (sshc->ssh_agent);
2469 sshc->ssh_agent = NULL;
2471 /* NB: there is no need to free identities, they are part of internal
2473 sshc->sshagent_identity = NULL;
2474 sshc->sshagent_prev_identity = NULL;
2478 if(sshc->ssh_session) {
2479 rc = libssh2_session_free(sshc->ssh_session);
2480 if(rc == LIBSSH2_ERROR_EAGAIN) {
2484 infof(data, "Failed to free libssh2 session\n");
2486 sshc->ssh_session = NULL;
2489 /* worst-case scenario cleanup */
2491 DEBUGASSERT(sshc->ssh_session == NULL);
2492 DEBUGASSERT(sshc->ssh_channel == NULL);
2493 DEBUGASSERT(sshc->sftp_session == NULL);
2494 DEBUGASSERT(sshc->sftp_handle == NULL);
2495 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2496 DEBUGASSERT(sshc->kh == NULL);
2498 #ifdef HAVE_LIBSSH2_AGENT_API
2499 DEBUGASSERT(sshc->ssh_agent == NULL);
2502 Curl_safefree(sshc->rsa_pub);
2503 Curl_safefree(sshc->rsa);
2505 Curl_safefree(sshc->quote_path1);
2506 Curl_safefree(sshc->quote_path2);
2508 Curl_safefree(sshc->homedir);
2510 Curl_safefree(sshc->readdir_filename);
2511 Curl_safefree(sshc->readdir_longentry);
2512 Curl_safefree(sshc->readdir_line);
2513 Curl_safefree(sshc->readdir_linkPath);
2515 /* the code we are about to return */
2516 result = sshc->actualcode;
2518 memset(sshc, 0, sizeof(struct ssh_conn));
2520 conn->bits.close = TRUE;
2521 sshc->state = SSH_SESSION_FREE; /* current */
2522 sshc->nextstate = SSH_NO_STATE;
2523 state(conn, SSH_STOP);
2527 /* fallthrough, just stop! */
2529 /* internal error */
2530 sshc->nextstate = SSH_NO_STATE;
2531 state(conn, SSH_STOP);
2535 } while(!rc && (sshc->state != SSH_STOP));
2537 if(rc == LIBSSH2_ERROR_EAGAIN) {
2538 /* we would block, we need to wait for the socket to be ready (in the
2539 right direction too)! */
2546 /* called by the multi interface to figure out what socket(s) to wait for and
2547 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2548 static int ssh_perform_getsock(const struct connectdata *conn,
2549 curl_socket_t *sock, /* points to numsocks
2550 number of sockets */
2553 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2554 int bitmap = GETSOCK_BLANK;
2557 sock[0] = conn->sock[FIRSTSOCKET];
2559 if(conn->waitfor & KEEP_RECV)
2560 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2562 if(conn->waitfor & KEEP_SEND)
2563 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2567 /* if we don't know the direction we can use the generic *_getsock()
2568 function even for the protocol_connect and doing states */
2569 return Curl_single_getsock(conn, sock, numsocks);
2573 /* Generic function called by the multi interface to figure out what socket(s)
2574 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2575 static int ssh_getsock(struct connectdata *conn,
2576 curl_socket_t *sock, /* points to numsocks number
2580 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2584 /* if we don't know any direction we can just play along as we used to and
2585 not provide any sensible info */
2586 return GETSOCK_BLANK;
2588 /* if we know the direction we can use the generic *_getsock() function even
2589 for the protocol_connect and doing states */
2590 return ssh_perform_getsock(conn, sock, numsocks);
2594 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2596 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2597 * function is used to figure out in what direction and stores this info so
2598 * that the multi interface can take advantage of it. Make sure to call this
2599 * function in all cases so that when it _doesn't_ return EAGAIN we can
2600 * restore the default wait bits.
2602 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2604 struct ssh_conn *sshc = &conn->proto.sshc;
2608 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2609 /* translate the libssh2 define bits into our own bit defines */
2610 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2611 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2614 /* It didn't block or libssh2 didn't reveal in which direction, put back
2616 conn->waitfor = sshc->orig_waitfor;
2619 /* no libssh2 directional support so we simply don't know */
2620 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2623 /* called repeatedly until done from multi.c */
2624 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2626 struct ssh_conn *sshc = &conn->proto.sshc;
2627 CURLcode result = CURLE_OK;
2628 bool block; /* we store the status and use that to provide a ssh_getsock()
2631 result = ssh_statemach_act(conn, &block);
2632 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2633 ssh_block2waitfor(conn, block);
2638 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2641 struct ssh_conn *sshc = &conn->proto.sshc;
2642 CURLcode result = CURLE_OK;
2643 struct SessionHandle *data = conn->data;
2645 while((sshc->state != SSH_STOP) && !result) {
2649 result = ssh_statemach_act(conn, &block);
2653 if(Curl_pgrsUpdate(conn))
2654 return CURLE_ABORTED_BY_CALLBACK;
2656 struct timeval now = Curl_tvnow();
2657 result = Curl_speedcheck(data, now);
2662 left = Curl_timeleft(data, NULL, duringconnect);
2664 failf(data, "Operation timed out");
2665 return CURLE_OPERATION_TIMEDOUT;
2668 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2669 if((CURLE_OK == result) && block) {
2670 int dir = libssh2_session_block_directions(sshc->ssh_session);
2671 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2672 curl_socket_t fd_read = CURL_SOCKET_BAD;
2673 curl_socket_t fd_write = CURL_SOCKET_BAD;
2674 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2676 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2678 /* wait for the socket to become ready */
2679 Curl_socket_ready(fd_read, fd_write,
2680 left>1000?1000:left); /* ignore result */
2690 * SSH setup and connection
2692 static CURLcode ssh_init(struct connectdata *conn)
2694 struct SessionHandle *data = conn->data;
2695 struct SSHPROTO *ssh;
2696 struct ssh_conn *sshc = &conn->proto.sshc;
2698 sshc->actualcode = CURLE_OK; /* reset error code */
2699 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2702 if(data->state.proto.ssh)
2705 ssh = calloc(1, sizeof(struct SSHPROTO));
2707 return CURLE_OUT_OF_MEMORY;
2709 data->state.proto.ssh = ssh;
2714 static Curl_recv scp_recv, sftp_recv;
2715 static Curl_send scp_send, sftp_send;
2718 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2719 * do protocol-specific actions at connect-time.
2721 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2723 #ifdef CURL_LIBSSH2_DEBUG
2726 struct ssh_conn *ssh;
2728 struct SessionHandle *data = conn->data;
2730 /* We default to persistent connections. We set this already in this connect
2731 function to make the re-use checks properly be able to check this bit. */
2732 conn->bits.close = FALSE;
2734 /* If there already is a protocol-specific struct allocated for this
2735 sessionhandle, deal with it */
2736 Curl_reset_reqproto(conn);
2738 result = ssh_init(conn);
2742 if(conn->handler->protocol & CURLPROTO_SCP) {
2743 conn->recv[FIRSTSOCKET] = scp_recv;
2744 conn->send[FIRSTSOCKET] = scp_send;
2747 conn->recv[FIRSTSOCKET] = sftp_recv;
2748 conn->send[FIRSTSOCKET] = sftp_send;
2750 ssh = &conn->proto.sshc;
2752 #ifdef CURL_LIBSSH2_DEBUG
2754 infof(data, "User: %s\n", conn->user);
2757 infof(data, "Password: %s\n", conn->passwd);
2759 sock = conn->sock[FIRSTSOCKET];
2760 #endif /* CURL_LIBSSH2_DEBUG */
2762 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2764 my_libssh2_realloc, conn);
2765 if(ssh->ssh_session == NULL) {
2766 failf(data, "Failure initialising ssh session");
2767 return CURLE_FAILED_INIT;
2770 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2771 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2773 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2775 /* eeek. TODO: free the ssh_session! */
2776 return CURLE_FAILED_INIT;
2779 /* read all known hosts from there */
2780 rc = libssh2_knownhost_readfile(ssh->kh,
2781 data->set.str[STRING_SSH_KNOWNHOSTS],
2782 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2784 infof(data, "Failed to read known hosts from %s\n",
2785 data->set.str[STRING_SSH_KNOWNHOSTS]);
2787 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2789 #ifdef CURL_LIBSSH2_DEBUG
2790 libssh2_trace(ssh->ssh_session, ~0);
2791 infof(data, "SSH socket: %d\n", (int)sock);
2792 #endif /* CURL_LIBSSH2_DEBUG */
2794 state(conn, SSH_INIT);
2796 result = ssh_multi_statemach(conn, done);
2802 ***********************************************************************
2806 * This is the actual DO function for SCP. Get a file according to
2807 * the options previously setup.
2811 CURLcode scp_perform(struct connectdata *conn,
2815 CURLcode result = CURLE_OK;
2817 DEBUGF(infof(conn->data, "DO phase starts\n"));
2819 *dophase_done = FALSE; /* not done yet */
2821 /* start the first command in the DO phase */
2822 state(conn, SSH_SCP_TRANS_INIT);
2824 /* run the state-machine */
2825 result = ssh_multi_statemach(conn, dophase_done);
2827 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2830 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2836 /* called from multi.c while DOing */
2837 static CURLcode scp_doing(struct connectdata *conn,
2841 result = ssh_multi_statemach(conn, dophase_done);
2844 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2850 * The DO function is generic for both protocols. There was previously two
2851 * separate ones but this way means less duplicated code.
2854 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2858 struct SessionHandle *data = conn->data;
2860 *done = FALSE; /* default to false */
2863 Since connections can be re-used between SessionHandles, this might be a
2864 connection already existing but on a fresh SessionHandle struct so we must
2865 make sure we have a good 'struct SSHPROTO' to play with. For new
2866 connections, the struct SSHPROTO is allocated and setup in the
2867 ssh_connect() function.
2869 Curl_reset_reqproto(conn);
2870 res = ssh_init(conn);
2874 data->req.size = -1; /* make sure this is unknown at this point */
2876 Curl_pgrsSetUploadCounter(data, 0);
2877 Curl_pgrsSetDownloadCounter(data, 0);
2878 Curl_pgrsSetUploadSize(data, 0);
2879 Curl_pgrsSetDownloadSize(data, 0);
2881 if(conn->handler->protocol & CURLPROTO_SCP)
2882 res = scp_perform(conn, &connected, done);
2884 res = sftp_perform(conn, &connected, done);
2889 /* BLOCKING, but the function is using the state machine so the only reason
2890 this is still blocking is that the multi interface code has no support for
2891 disconnecting operations that takes a while */
2892 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2894 CURLcode result = CURLE_OK;
2895 struct ssh_conn *ssh = &conn->proto.sshc;
2896 (void) dead_connection;
2898 Curl_safefree(conn->data->state.proto.ssh);
2900 if(ssh->ssh_session) {
2901 /* only if there's a session still around to use! */
2903 state(conn, SSH_SESSION_DISCONNECT);
2905 result = ssh_easy_statemach(conn, FALSE);
2911 /* generic done function for both SCP and SFTP called from their specific
2913 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2915 CURLcode result = CURLE_OK;
2916 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2918 if(status == CURLE_OK) {
2919 /* run the state-machine
2921 TODO: when the multi interface is used, this _really_ should be using
2922 the ssh_multi_statemach function but we have no general support for
2923 non-blocking DONE operations, not in the multi state machine and with
2924 Curl_done() invokes on several places in the code!
2926 result = ssh_easy_statemach(conn, FALSE);
2932 Curl_safefree(sftp_scp->path);
2933 if(Curl_pgrsDone(conn))
2934 return CURLE_ABORTED_BY_CALLBACK;
2936 conn->data->req.keepon = 0; /* clear all bits */
2941 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2944 (void)premature; /* not used */
2946 if(status == CURLE_OK)
2947 state(conn, SSH_SCP_DONE);
2949 return ssh_done(conn, status);
2953 /* return number of received (decrypted) bytes */
2954 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2955 const void *mem, size_t len, CURLcode *err)
2958 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2960 /* libssh2_channel_write() returns int! */
2962 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2964 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2966 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2970 else if(nwrite < LIBSSH2_ERROR_NONE) {
2971 *err = libssh2_session_error_to_CURLE((int)nwrite);
2979 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2980 * a regular CURLcode value.
2982 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2983 char *mem, size_t len, CURLcode *err)
2986 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2988 /* libssh2_channel_read() returns int */
2990 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2992 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2993 if(nread == LIBSSH2_ERROR_EAGAIN) {
3002 * =============== SFTP ===============
3006 ***********************************************************************
3010 * This is the actual DO function for SFTP. Get a file/directory according to
3011 * the options previously setup.
3015 CURLcode sftp_perform(struct connectdata *conn,
3019 CURLcode result = CURLE_OK;
3021 DEBUGF(infof(conn->data, "DO phase starts\n"));
3023 *dophase_done = FALSE; /* not done yet */
3025 /* start the first command in the DO phase */
3026 state(conn, SSH_SFTP_QUOTE_INIT);
3028 /* run the state-machine */
3029 result = ssh_multi_statemach(conn, dophase_done);
3031 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3034 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3040 /* called from multi.c while DOing */
3041 static CURLcode sftp_doing(struct connectdata *conn,
3045 result = ssh_multi_statemach(conn, dophase_done);
3048 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3053 /* BLOCKING, but the function is using the state machine so the only reason
3054 this is still blocking is that the multi interface code has no support for
3055 disconnecting operations that takes a while */
3056 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
3058 CURLcode result = CURLE_OK;
3059 (void) dead_connection;
3061 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3063 Curl_safefree(conn->data->state.proto.ssh);
3065 if(conn->proto.sshc.ssh_session) {
3066 /* only if there's a session still around to use! */
3067 state(conn, SSH_SFTP_SHUTDOWN);
3068 result = ssh_easy_statemach(conn, FALSE);
3071 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3077 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3080 struct ssh_conn *sshc = &conn->proto.sshc;
3082 if(status == CURLE_OK) {
3083 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3084 errors that could happen due to open file handles during POSTQUOTE
3086 if(!status && !premature && conn->data->set.postquote) {
3087 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3088 state(conn, SSH_SFTP_CLOSE);
3091 state(conn, SSH_SFTP_CLOSE);
3093 return ssh_done(conn, status);
3096 /* return number of sent bytes */
3097 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3098 const void *mem, size_t len, CURLcode *err)
3100 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3101 but is changed to ssize_t in 0.15. These days we don't
3102 support libssh2 0.15*/
3105 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3107 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3109 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3113 else if(nwrite < LIBSSH2_ERROR_NONE) {
3114 *err = libssh2_session_error_to_CURLE((int)nwrite);
3122 * Return number of received (decrypted) bytes
3124 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3125 char *mem, size_t len, CURLcode *err)
3130 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3132 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3134 if(nread == LIBSSH2_ERROR_EAGAIN) {
3141 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3144 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3146 * Permission to use, copy, modify, and distribute this software for any
3147 * purpose with or without fee is hereby granted, provided that the above
3148 * copyright notice and this permission notice appear in all copies.
3150 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3151 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3152 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3153 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3154 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3155 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3156 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3159 get_pathname(const char **cpp, char **path)
3161 const char *cp = *cpp, *end;
3164 static const char WHITESPACE[] = " \t\r\n";
3166 cp += strspn(cp, WHITESPACE);
3170 return CURLE_QUOTE_ERROR;
3173 *path = malloc(strlen(cp) + 1);
3175 return CURLE_OUT_OF_MEMORY;
3177 /* Check for quoted filenames */
3178 if(*cp == '\"' || *cp == '\'') {
3181 /* Search for terminating quote, unescape some chars */
3182 for(i = j = 0; i <= strlen(cp); i++) {
3183 if(cp[i] == quot) { /* Found quote */
3188 if(cp[i] == '\0') { /* End of string */
3189 /*error("Unterminated quote");*/
3192 if(cp[i] == '\\') { /* Escaped characters */
3194 if(cp[i] != '\'' && cp[i] != '\"' &&
3196 /*error("Bad escaped character '\\%c'",
3201 (*path)[j++] = cp[i];
3205 /*error("Empty quotes");*/
3208 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3211 /* Read to end of filename */
3212 end = strpbrk(cp, WHITESPACE);
3214 end = strchr(cp, '\0');
3215 *cpp = end + strspn(end, WHITESPACE);
3217 memcpy(*path, cp, end - cp);
3218 (*path)[end - cp] = '\0';
3223 Curl_safefree(*path);
3224 return CURLE_QUOTE_ERROR;
3228 static const char *sftp_libssh2_strerror(int err)
3231 case LIBSSH2_FX_NO_SUCH_FILE:
3232 return "No such file or directory";
3234 case LIBSSH2_FX_PERMISSION_DENIED:
3235 return "Permission denied";
3237 case LIBSSH2_FX_FAILURE:
3238 return "Operation failed";
3240 case LIBSSH2_FX_BAD_MESSAGE:
3241 return "Bad message from SFTP server";
3243 case LIBSSH2_FX_NO_CONNECTION:
3244 return "Not connected to SFTP server";
3246 case LIBSSH2_FX_CONNECTION_LOST:
3247 return "Connection to SFTP server lost";
3249 case LIBSSH2_FX_OP_UNSUPPORTED:
3250 return "Operation not supported by SFTP server";
3252 case LIBSSH2_FX_INVALID_HANDLE:
3253 return "Invalid handle";
3255 case LIBSSH2_FX_NO_SUCH_PATH:
3256 return "No such file or directory";
3258 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3259 return "File already exists";
3261 case LIBSSH2_FX_WRITE_PROTECT:
3262 return "File is write protected";
3264 case LIBSSH2_FX_NO_MEDIA:
3267 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3270 case LIBSSH2_FX_QUOTA_EXCEEDED:
3271 return "User quota exceeded";
3273 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3274 return "Unknown principle";
3276 case LIBSSH2_FX_LOCK_CONFlICT:
3277 return "File lock conflict";
3279 case LIBSSH2_FX_DIR_NOT_EMPTY:
3280 return "Directory not empty";
3282 case LIBSSH2_FX_NOT_A_DIRECTORY:
3283 return "Not a directory";
3285 case LIBSSH2_FX_INVALID_FILENAME:
3286 return "Invalid filename";
3288 case LIBSSH2_FX_LINK_LOOP:
3289 return "Link points to itself";
3291 return "Unknown error in libssh2";
3294 #endif /* USE_LIBSSH2 */