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"
93 #include "http_proxy.h"
95 #define _MPRINTF_REPLACE /* use our functions only */
96 #include <curl/mprintf.h>
98 #include "curl_memory.h"
99 /* The last #include file should be: */
100 #include "memdebug.h"
104 # define PATH_MAX MAX_PATH
108 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
109 have their definition hidden well */
112 /* Local functions: */
113 static const char *sftp_libssh2_strerror(unsigned long err);
114 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
115 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
116 static LIBSSH2_FREE_FUNC(my_libssh2_free);
118 static CURLcode get_pathname(const char **cpp, char **path);
120 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
121 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
122 static CURLcode ssh_do(struct connectdata *conn, bool *done);
124 static CURLcode ssh_getworkingpath(struct connectdata *conn,
125 char *homedir, /* when SFTP is used */
128 static CURLcode scp_done(struct connectdata *conn,
129 CURLcode, bool premature);
130 static CURLcode scp_doing(struct connectdata *conn,
132 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
134 static CURLcode sftp_done(struct connectdata *conn,
135 CURLcode, bool premature);
136 static CURLcode sftp_doing(struct connectdata *conn,
138 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
140 CURLcode sftp_perform(struct connectdata *conn,
144 static int ssh_getsock(struct connectdata *conn,
145 curl_socket_t *sock, /* points to numsocks number
149 static int ssh_perform_getsock(const struct connectdata *conn,
150 curl_socket_t *sock, /* points to numsocks
155 * SCP protocol handler.
158 const struct Curl_handler Curl_handler_scp = {
160 ZERO_NULL, /* setup_connection */
163 ZERO_NULL, /* do_more */
164 ssh_connect, /* connect_it */
165 ssh_multi_statemach, /* connecting */
166 scp_doing, /* doing */
167 ssh_getsock, /* proto_getsock */
168 ssh_getsock, /* doing_getsock */
169 ZERO_NULL, /* domore_getsock */
170 ssh_perform_getsock, /* perform_getsock */
171 scp_disconnect, /* disconnect */
172 ZERO_NULL, /* readwrite */
173 PORT_SSH, /* defport */
174 CURLPROTO_SCP, /* protocol */
175 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
176 | PROTOPT_NOURLQUERY /* flags */
181 * SFTP protocol handler.
184 const struct Curl_handler Curl_handler_sftp = {
186 ZERO_NULL, /* setup_connection */
188 sftp_done, /* done */
189 ZERO_NULL, /* do_more */
190 ssh_connect, /* connect_it */
191 ssh_multi_statemach, /* connecting */
192 sftp_doing, /* doing */
193 ssh_getsock, /* proto_getsock */
194 ssh_getsock, /* doing_getsock */
195 ZERO_NULL, /* domore_getsock */
196 ssh_perform_getsock, /* perform_getsock */
197 sftp_disconnect, /* disconnect */
198 ZERO_NULL, /* readwrite */
199 PORT_SSH, /* defport */
200 CURLPROTO_SFTP, /* protocol */
201 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
202 | PROTOPT_NOURLQUERY /* flags */
207 kbd_callback(const char *name, int name_len, const char *instruction,
208 int instruction_len, int num_prompts,
209 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
210 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
213 struct connectdata *conn = (struct connectdata *)*abstract;
215 #ifdef CURL_LIBSSH2_DEBUG
216 fprintf(stderr, "name=%s\n", name);
217 fprintf(stderr, "name_len=%d\n", name_len);
218 fprintf(stderr, "instruction=%s\n", instruction);
219 fprintf(stderr, "instruction_len=%d\n", instruction_len);
220 fprintf(stderr, "num_prompts=%d\n", num_prompts);
225 (void)instruction_len;
226 #endif /* CURL_LIBSSH2_DEBUG */
227 if(num_prompts == 1) {
228 responses[0].text = strdup(conn->passwd);
229 responses[0].length = (unsigned int)strlen(conn->passwd);
235 static CURLcode sftp_libssh2_error_to_CURLE(int err)
241 case LIBSSH2_FX_NO_SUCH_FILE:
242 case LIBSSH2_FX_NO_SUCH_PATH:
243 return CURLE_REMOTE_FILE_NOT_FOUND;
245 case LIBSSH2_FX_PERMISSION_DENIED:
246 case LIBSSH2_FX_WRITE_PROTECT:
247 case LIBSSH2_FX_LOCK_CONFlICT:
248 return CURLE_REMOTE_ACCESS_DENIED;
250 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
251 case LIBSSH2_FX_QUOTA_EXCEEDED:
252 return CURLE_REMOTE_DISK_FULL;
254 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
255 return CURLE_REMOTE_FILE_EXISTS;
257 case LIBSSH2_FX_DIR_NOT_EMPTY:
258 return CURLE_QUOTE_ERROR;
267 static CURLcode libssh2_session_error_to_CURLE(int err)
270 /* Ordered by order of appearance in libssh2.h */
271 case LIBSSH2_ERROR_NONE:
274 case LIBSSH2_ERROR_SOCKET_NONE:
275 return CURLE_COULDNT_CONNECT;
277 case LIBSSH2_ERROR_ALLOC:
278 return CURLE_OUT_OF_MEMORY;
280 case LIBSSH2_ERROR_SOCKET_SEND:
281 return CURLE_SEND_ERROR;
283 case LIBSSH2_ERROR_HOSTKEY_INIT:
284 case LIBSSH2_ERROR_HOSTKEY_SIGN:
285 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
286 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
287 return CURLE_PEER_FAILED_VERIFICATION;
289 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
290 return CURLE_LOGIN_DENIED;
292 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
293 case LIBSSH2_ERROR_TIMEOUT:
294 return CURLE_OPERATION_TIMEDOUT;
296 case LIBSSH2_ERROR_EAGAIN:
300 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
301 error code, and possibly add a few new SSH-related one. We must however
302 not return or even depend on libssh2 errors in the public libcurl API */
307 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
309 (void)abstract; /* arg not used */
310 return malloc(count);
313 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
315 (void)abstract; /* arg not used */
316 return realloc(ptr, count);
319 static LIBSSH2_FREE_FUNC(my_libssh2_free)
321 (void)abstract; /* arg not used */
326 * SSH State machine related code
328 /* This is the ONLY way to change SSH state! */
329 static void state(struct connectdata *conn, sshstate nowstate)
331 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
332 /* for debug purposes */
333 static const char * const names[] = {
339 "SSH_AUTH_PKEY_INIT",
341 "SSH_AUTH_PASS_INIT",
343 "SSH_AUTH_HOST_INIT",
350 "SSH_SFTP_QUOTE_INIT",
351 "SSH_SFTP_POSTQUOTE_INIT",
353 "SSH_SFTP_NEXT_QUOTE",
354 "SSH_SFTP_QUOTE_STAT",
355 "SSH_SFTP_QUOTE_SETSTAT",
356 "SSH_SFTP_QUOTE_SYMLINK",
357 "SSH_SFTP_QUOTE_MKDIR",
358 "SSH_SFTP_QUOTE_RENAME",
359 "SSH_SFTP_QUOTE_RMDIR",
360 "SSH_SFTP_QUOTE_UNLINK",
361 "SSH_SFTP_TRANS_INIT",
362 "SSH_SFTP_UPLOAD_INIT",
363 "SSH_SFTP_CREATE_DIRS_INIT",
364 "SSH_SFTP_CREATE_DIRS",
365 "SSH_SFTP_CREATE_DIRS_MKDIR",
366 "SSH_SFTP_READDIR_INIT",
368 "SSH_SFTP_READDIR_LINK",
369 "SSH_SFTP_READDIR_BOTTOM",
370 "SSH_SFTP_READDIR_DONE",
371 "SSH_SFTP_DOWNLOAD_INIT",
372 "SSH_SFTP_DOWNLOAD_STAT",
375 "SSH_SCP_TRANS_INIT",
376 "SSH_SCP_UPLOAD_INIT",
377 "SSH_SCP_DOWNLOAD_INIT",
381 "SSH_SCP_WAIT_CLOSE",
382 "SSH_SCP_CHANNEL_FREE",
383 "SSH_SESSION_DISCONNECT",
388 struct ssh_conn *sshc = &conn->proto.sshc;
390 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
391 if(sshc->state != nowstate) {
392 infof(conn->data, "SFTP %p state change from %s to %s\n",
393 sshc, names[sshc->state], names[nowstate]);
397 sshc->state = nowstate;
400 /* figure out the path to work with in this particular request */
401 static CURLcode ssh_getworkingpath(struct connectdata *conn,
402 char *homedir, /* when SFTP is used */
403 char **path) /* returns the allocated
404 real path to work with */
406 struct SessionHandle *data = conn->data;
407 char *real_path = NULL;
409 int working_path_len;
411 working_path = curl_easy_unescape(data, data->state.path, 0,
414 return CURLE_OUT_OF_MEMORY;
416 /* Check for /~/ , indicating relative to the user's home directory */
417 if(conn->handler->protocol & CURLPROTO_SCP) {
418 real_path = malloc(working_path_len+1);
419 if(real_path == NULL) {
421 return CURLE_OUT_OF_MEMORY;
423 if((working_path_len > 1) && (working_path[1] == '~'))
424 /* It is referenced to the home directory, so strip the leading '/' */
425 memcpy(real_path, working_path+1, 1 + working_path_len-1);
427 memcpy(real_path, working_path, 1 + working_path_len);
429 else if(conn->handler->protocol & CURLPROTO_SFTP) {
430 if((working_path_len > 1) && (working_path[1] == '~')) {
431 size_t homelen = strlen(homedir);
432 real_path = malloc(homelen + working_path_len + 1);
433 if(real_path == NULL) {
435 return CURLE_OUT_OF_MEMORY;
437 /* It is referenced to the home directory, so strip the
439 memcpy(real_path, homedir, homelen);
440 real_path[homelen] = '/';
441 real_path[homelen+1] = '\0';
442 if(working_path_len > 3) {
443 memcpy(real_path+homelen+1, working_path + 3,
444 1 + working_path_len -3);
448 real_path = malloc(working_path_len+1);
449 if(real_path == NULL) {
451 return CURLE_OUT_OF_MEMORY;
453 memcpy(real_path, working_path, 1+working_path_len);
459 /* store the pointer for the caller to receive */
465 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
466 static int sshkeycallback(CURL *easy,
467 const struct curl_khkey *knownkey, /* known */
468 const struct curl_khkey *foundkey, /* found */
469 enum curl_khmatch match,
477 /* we only allow perfect matches, and we reject everything else */
478 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
483 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
486 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
487 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
489 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
493 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
494 * architectures so we check of the necessary function is present.
496 #ifndef HAVE_LIBSSH2_SCP_SEND64
497 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
499 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
500 (libssh2_uint64_t)d, 0, 0)
504 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
506 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
507 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
510 static CURLcode ssh_knownhost(struct connectdata *conn)
512 CURLcode result = CURLE_OK;
514 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
515 struct SessionHandle *data = conn->data;
517 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
518 /* we're asked to verify the host against a file */
519 struct ssh_conn *sshc = &conn->proto.sshc;
523 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
525 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
530 * A subject to figure out is what host name we need to pass in here.
531 * What host name does OpenSSH store in its file if an IDN name is
534 struct libssh2_knownhost *host;
535 enum curl_khmatch keymatch;
536 curl_sshkeycallback func =
537 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
538 struct curl_khkey knownkey;
539 struct curl_khkey *knownkeyp = NULL;
540 struct curl_khkey foundkey;
542 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
543 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
545 keycheck = libssh2_knownhost_check(sshc->kh,
548 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
549 LIBSSH2_KNOWNHOST_KEYENC_RAW|
553 infof(data, "SSH host check: %d, key: %s\n", keycheck,
554 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
557 /* setup 'knownkey' */
558 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
559 knownkey.key = host->key;
561 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
562 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
563 knownkeyp = &knownkey;
566 /* setup 'foundkey' */
567 foundkey.key = remotekey;
568 foundkey.len = keylen;
569 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
570 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
573 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
574 * curl_khmatch enum are ever modified, we need to introduce a
575 * translation table here!
577 keymatch = (enum curl_khmatch)keycheck;
579 /* Ask the callback how to behave */
580 rc = func(data, knownkeyp, /* from the knownhosts file */
581 &foundkey, /* from the remote host */
582 keymatch, data->set.ssh_keyfunc_userp);
585 /* no remotekey means failure! */
586 rc = CURLKHSTAT_REJECT;
589 default: /* unknown return codes will equal reject */
590 case CURLKHSTAT_REJECT:
591 state(conn, SSH_SESSION_FREE);
592 case CURLKHSTAT_DEFER:
593 /* DEFER means bail out but keep the SSH_HOSTKEY state */
594 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
596 case CURLKHSTAT_FINE:
597 case CURLKHSTAT_FINE_ADD_TO_FILE:
599 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
600 /* the found host+key didn't match but has been told to be fine
601 anyway so we add it in memory */
602 int addrc = libssh2_knownhost_add(sshc->kh,
603 conn->host.name, NULL,
605 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
606 LIBSSH2_KNOWNHOST_KEYENC_RAW|
609 infof(data, "Warning adding the known host %s failed!\n",
611 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
612 /* now we write the entire in-memory list of known hosts to the
615 libssh2_knownhost_writefile(sshc->kh,
616 data->set.str[STRING_SSH_KNOWNHOSTS],
617 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
619 infof(data, "Warning, writing %s failed!\n",
620 data->set.str[STRING_SSH_KNOWNHOSTS]);
627 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
635 * ssh_statemach_act() runs the SSH state machine as far as it can without
636 * blocking and without reaching the end. The data the pointer 'block' points
637 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
638 * meaning it wants to be called again when the socket is ready
641 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
643 CURLcode result = CURLE_OK;
644 struct SessionHandle *data = conn->data;
645 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
646 struct ssh_conn *sshc = &conn->proto.sshc;
647 curl_socket_t sock = conn->sock[FIRSTSOCKET];
648 const char *fingerprint;
650 char *new_readdir_line;
651 int rc = LIBSSH2_ERROR_NONE, i;
653 int seekerr = CURL_SEEKFUNC_OK;
654 *block = 0; /* we're not blocking by default */
658 switch(sshc->state) {
660 sshc->secondCreateDirs = 0;
661 sshc->nextstate = SSH_NO_STATE;
662 sshc->actualcode = CURLE_OK;
664 /* Set libssh2 to non-blocking, since everything internally is
666 libssh2_session_set_blocking(sshc->ssh_session, 0);
668 state(conn, SSH_S_STARTUP);
672 rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
673 if(rc == LIBSSH2_ERROR_EAGAIN) {
677 failf(data, "Failure establishing ssh session");
678 state(conn, SSH_SESSION_FREE);
679 sshc->actualcode = CURLE_FAILED_INIT;
683 state(conn, SSH_HOSTKEY);
688 * Before we authenticate we should check the hostkey's fingerprint
689 * against our known hosts. How that is handled (reading from file,
690 * whatever) is up to us.
692 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
693 LIBSSH2_HOSTKEY_HASH_MD5);
695 /* The fingerprint points to static storage (!), don't free() it. */
696 for(i = 0; i < 16; i++)
697 snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
698 infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
700 /* Before we authenticate we check the hostkey's MD5 fingerprint
701 * against a known fingerprint, if available.
703 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
704 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
705 if(!strequal(md5buffer,
706 data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
708 "Denied establishing ssh session: mismatch md5 fingerprint. "
709 "Remote %s is not equal to %s",
710 md5buffer, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
711 state(conn, SSH_SESSION_FREE);
712 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
715 infof(data, "MD5 checksum match!\n");
716 /* as we already matched, we skip the check for known hosts */
719 result = ssh_knownhost(conn);
722 state(conn, SSH_AUTHLIST);
727 * Figure out authentication methods
728 * NB: As soon as we have provided a username to an openssh server we
729 * must never change it later. Thus, always specify the correct username
730 * here, even though the libssh2 docs kind of indicate that it should be
731 * possible to get a 'generic' list (not user-specific) of authentication
732 * methods, presumably with a blank username. That won't work in my
734 * So always specify it here.
736 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
738 (unsigned int)strlen(conn->user));
740 if(!sshc->authlist) {
741 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
742 LIBSSH2_ERROR_EAGAIN) {
743 rc = LIBSSH2_ERROR_EAGAIN;
747 state(conn, SSH_SESSION_FREE);
748 sshc->actualcode = libssh2_session_error_to_CURLE(err);
752 infof(data, "SSH authentication methods available: %s\n",
755 state(conn, SSH_AUTH_PKEY_INIT);
758 case SSH_AUTH_PKEY_INIT:
760 * Check the supported auth types in the order I feel is most secure
761 * with the requested type of authentication
763 sshc->authed = FALSE;
765 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
766 (strstr(sshc->authlist, "publickey") != NULL)) {
769 sshc->rsa_pub = sshc->rsa = NULL;
771 /* To ponder about: should really the lib be messing about with the
772 HOME environment variable etc? */
773 home = curl_getenv("HOME");
775 if(data->set.str[STRING_SSH_PUBLIC_KEY])
776 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
778 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
780 /* as a final resort, try current dir! */
781 sshc->rsa_pub = strdup("id_dsa.pub");
783 if(sshc->rsa_pub == NULL) {
786 state(conn, SSH_SESSION_FREE);
787 sshc->actualcode = CURLE_OUT_OF_MEMORY;
791 if(data->set.str[STRING_SSH_PRIVATE_KEY])
792 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
794 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
796 /* as a final resort, try current dir! */
797 sshc->rsa = strdup("id_dsa");
799 if(sshc->rsa == NULL) {
802 Curl_safefree(sshc->rsa_pub);
803 sshc->rsa_pub = NULL;
804 state(conn, SSH_SESSION_FREE);
805 sshc->actualcode = CURLE_OUT_OF_MEMORY;
809 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
810 if(!sshc->passphrase)
811 sshc->passphrase = "";
816 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
817 infof(data, "Using ssh private key file %s\n", sshc->rsa);
819 state(conn, SSH_AUTH_PKEY);
822 state(conn, SSH_AUTH_PASS_INIT);
827 /* The function below checks if the files exists, no need to stat() here.
829 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
834 sshc->rsa, sshc->passphrase);
835 if(rc == LIBSSH2_ERROR_EAGAIN) {
839 Curl_safefree(sshc->rsa_pub);
840 sshc->rsa_pub = NULL;
841 Curl_safefree(sshc->rsa);
846 infof(data, "Initialized SSH public key authentication\n");
847 state(conn, SSH_AUTH_DONE);
851 (void)libssh2_session_last_error(sshc->ssh_session,
853 infof(data, "SSH public key authentication failed: %s\n", err_msg);
854 state(conn, SSH_AUTH_PASS_INIT);
858 case SSH_AUTH_PASS_INIT:
859 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
860 (strstr(sshc->authlist, "password") != NULL)) {
861 state(conn, SSH_AUTH_PASS);
864 state(conn, SSH_AUTH_HOST_INIT);
869 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
870 (unsigned int)strlen(conn->user),
872 (unsigned int)strlen(conn->passwd),
874 if(rc == LIBSSH2_ERROR_EAGAIN) {
879 infof(data, "Initialized password authentication\n");
880 state(conn, SSH_AUTH_DONE);
883 state(conn, SSH_AUTH_HOST_INIT);
887 case SSH_AUTH_HOST_INIT:
888 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
889 (strstr(sshc->authlist, "hostbased") != NULL)) {
890 state(conn, SSH_AUTH_HOST);
893 state(conn, SSH_AUTH_KEY_INIT);
898 state(conn, SSH_AUTH_KEY_INIT);
901 case SSH_AUTH_KEY_INIT:
902 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
903 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
904 state(conn, SSH_AUTH_KEY);
907 state(conn, SSH_AUTH_DONE);
912 /* Authentication failed. Continue with keyboard-interactive now. */
913 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
918 if(rc == LIBSSH2_ERROR_EAGAIN) {
923 infof(data, "Initialized keyboard interactive authentication\n");
925 state(conn, SSH_AUTH_DONE);
930 failf(data, "Authentication failure");
931 state(conn, SSH_SESSION_FREE);
932 sshc->actualcode = CURLE_LOGIN_DENIED;
937 * At this point we have an authenticated ssh session.
939 infof(data, "Authentication complete\n");
941 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
944 conn->writesockfd = CURL_SOCKET_BAD;
946 if(conn->handler->protocol == CURLPROTO_SFTP) {
947 state(conn, SSH_SFTP_INIT);
950 infof(data, "SSH CONNECT phase done\n");
951 state(conn, SSH_STOP);
956 * Start the libssh2 sftp session
958 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
959 if(!sshc->sftp_session) {
960 if(libssh2_session_last_errno(sshc->ssh_session) ==
961 LIBSSH2_ERROR_EAGAIN) {
962 rc = LIBSSH2_ERROR_EAGAIN;
968 (void)libssh2_session_last_error(sshc->ssh_session,
970 failf(data, "Failure initializing sftp session: %s", err_msg);
971 state(conn, SSH_SESSION_FREE);
972 sshc->actualcode = CURLE_FAILED_INIT;
976 state(conn, SSH_SFTP_REALPATH);
979 case SSH_SFTP_REALPATH:
981 char tempHome[PATH_MAX];
984 * Get the "home" directory
986 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
987 tempHome, PATH_MAX-1);
988 if(rc == LIBSSH2_ERROR_EAGAIN) {
992 /* It seems that this string is not always NULL terminated */
994 sshc->homedir = strdup(tempHome);
996 state(conn, SSH_SFTP_CLOSE);
997 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1000 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1003 /* Return the error type */
1004 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1005 result = sftp_libssh2_error_to_CURLE(err);
1006 sshc->actualcode = result?result:CURLE_SSH;
1007 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1009 state(conn, SSH_STOP);
1013 /* This is the last step in the SFTP connect phase. Do note that while
1014 we get the homedir here, we get the "workingpath" in the DO action
1015 since the homedir will remain the same between request but the
1016 working path will not. */
1017 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1018 state(conn, SSH_STOP);
1021 case SSH_SFTP_QUOTE_INIT:
1023 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1025 sshc->actualcode = result;
1026 state(conn, SSH_STOP);
1030 if(data->set.quote) {
1031 infof(data, "Sending quote commands\n");
1032 sshc->quote_item = data->set.quote;
1033 state(conn, SSH_SFTP_QUOTE);
1036 state(conn, SSH_SFTP_TRANS_INIT);
1040 case SSH_SFTP_POSTQUOTE_INIT:
1041 if(data->set.postquote) {
1042 infof(data, "Sending quote commands\n");
1043 sshc->quote_item = data->set.postquote;
1044 state(conn, SSH_SFTP_QUOTE);
1047 state(conn, SSH_STOP);
1051 case SSH_SFTP_QUOTE:
1052 /* Send any quote commands */
1057 * Support some of the "FTP" commands
1059 char *cmd = sshc->quote_item->data;
1060 sshc->acceptfail = FALSE;
1062 /* if a command starts with an asterisk, which a legal SFTP command never
1063 can, the command will be allowed to fail without it causing any
1064 aborts or cancels etc. It will cause libcurl to act as if the command
1065 is successful, whatever the server reponds. */
1069 sshc->acceptfail = TRUE;
1072 if(curl_strequal("pwd", cmd)) {
1073 /* output debug output if that is requested */
1074 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1077 result = CURLE_OUT_OF_MEMORY;
1078 state(conn, SSH_SFTP_CLOSE);
1079 sshc->nextstate = SSH_NO_STATE;
1082 if(data->set.verbose) {
1083 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1084 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1086 /* this sends an FTP-like "header" to the header callback so that the
1087 current directory can be read very similar to how it is read when
1088 using ordinary FTP. */
1089 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1091 state(conn, SSH_SFTP_NEXT_QUOTE);
1096 * the arguments following the command must be separated from the
1097 * command with a space so we can check for it unconditionally
1099 cp = strchr(cmd, ' ');
1101 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1102 state(conn, SSH_SFTP_CLOSE);
1103 sshc->nextstate = SSH_NO_STATE;
1104 sshc->actualcode = CURLE_QUOTE_ERROR;
1109 * also, every command takes at least one argument so we get that
1110 * first argument right now
1112 result = get_pathname(&cp, &sshc->quote_path1);
1114 if(result == CURLE_OUT_OF_MEMORY)
1115 failf(data, "Out of memory");
1117 failf(data, "Syntax error: Bad first parameter");
1118 state(conn, SSH_SFTP_CLOSE);
1119 sshc->nextstate = SSH_NO_STATE;
1120 sshc->actualcode = result;
1125 * SFTP is a binary protocol, so we don't send text commands to
1126 * the server. Instead, we scan for commands for commands used by
1127 * OpenSSH's sftp program and call the appropriate libssh2
1130 if(curl_strnequal(cmd, "chgrp ", 6) ||
1131 curl_strnequal(cmd, "chmod ", 6) ||
1132 curl_strnequal(cmd, "chown ", 6) ) {
1133 /* attribute change */
1135 /* sshc->quote_path1 contains the mode to set */
1136 /* get the destination */
1137 result = get_pathname(&cp, &sshc->quote_path2);
1139 if(result == CURLE_OUT_OF_MEMORY)
1140 failf(data, "Out of memory");
1142 failf(data, "Syntax error in chgrp/chmod/chown: "
1143 "Bad second parameter");
1144 Curl_safefree(sshc->quote_path1);
1145 sshc->quote_path1 = NULL;
1146 state(conn, SSH_SFTP_CLOSE);
1147 sshc->nextstate = SSH_NO_STATE;
1148 sshc->actualcode = result;
1151 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1152 state(conn, SSH_SFTP_QUOTE_STAT);
1155 else if(curl_strnequal(cmd, "ln ", 3) ||
1156 curl_strnequal(cmd, "symlink ", 8)) {
1157 /* symbolic linking */
1158 /* sshc->quote_path1 is the source */
1159 /* get the destination */
1160 result = get_pathname(&cp, &sshc->quote_path2);
1162 if(result == CURLE_OUT_OF_MEMORY)
1163 failf(data, "Out of memory");
1166 "Syntax error in ln/symlink: Bad second parameter");
1167 Curl_safefree(sshc->quote_path1);
1168 sshc->quote_path1 = NULL;
1169 state(conn, SSH_SFTP_CLOSE);
1170 sshc->nextstate = SSH_NO_STATE;
1171 sshc->actualcode = result;
1174 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1177 else if(curl_strnequal(cmd, "mkdir ", 6)) {
1179 state(conn, SSH_SFTP_QUOTE_MKDIR);
1182 else if(curl_strnequal(cmd, "rename ", 7)) {
1184 /* first param is the source path */
1185 /* second param is the dest. path */
1186 result = get_pathname(&cp, &sshc->quote_path2);
1188 if(result == CURLE_OUT_OF_MEMORY)
1189 failf(data, "Out of memory");
1191 failf(data, "Syntax error in rename: Bad second parameter");
1192 Curl_safefree(sshc->quote_path1);
1193 sshc->quote_path1 = NULL;
1194 state(conn, SSH_SFTP_CLOSE);
1195 sshc->nextstate = SSH_NO_STATE;
1196 sshc->actualcode = result;
1199 state(conn, SSH_SFTP_QUOTE_RENAME);
1202 else if(curl_strnequal(cmd, "rmdir ", 6)) {
1204 state(conn, SSH_SFTP_QUOTE_RMDIR);
1207 else if(curl_strnequal(cmd, "rm ", 3)) {
1208 state(conn, SSH_SFTP_QUOTE_UNLINK);
1212 failf(data, "Unknown SFTP command");
1213 Curl_safefree(sshc->quote_path1);
1214 sshc->quote_path1 = NULL;
1215 Curl_safefree(sshc->quote_path2);
1216 sshc->quote_path2 = NULL;
1217 state(conn, SSH_SFTP_CLOSE);
1218 sshc->nextstate = SSH_NO_STATE;
1219 sshc->actualcode = CURLE_QUOTE_ERROR;
1223 if(!sshc->quote_item) {
1224 state(conn, SSH_SFTP_TRANS_INIT);
1228 case SSH_SFTP_NEXT_QUOTE:
1229 if(sshc->quote_path1) {
1230 Curl_safefree(sshc->quote_path1);
1231 sshc->quote_path1 = NULL;
1233 if(sshc->quote_path2) {
1234 Curl_safefree(sshc->quote_path2);
1235 sshc->quote_path2 = NULL;
1238 sshc->quote_item = sshc->quote_item->next;
1240 if(sshc->quote_item) {
1241 state(conn, SSH_SFTP_QUOTE);
1244 if(sshc->nextstate != SSH_NO_STATE) {
1245 state(conn, sshc->nextstate);
1246 sshc->nextstate = SSH_NO_STATE;
1249 state(conn, SSH_SFTP_TRANS_INIT);
1254 case SSH_SFTP_QUOTE_STAT:
1256 char *cmd = sshc->quote_item->data;
1257 sshc->acceptfail = FALSE;
1259 /* if a command starts with an asterisk, which a legal SFTP command never
1260 can, the command will be allowed to fail without it causing any
1261 aborts or cancels etc. It will cause libcurl to act as if the command
1262 is successful, whatever the server reponds. */
1266 sshc->acceptfail = TRUE;
1269 if(!curl_strnequal(cmd, "chmod", 5)) {
1270 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1271 * set them both at once, we need to obtain the current ownership
1272 * first. This takes an extra protocol round trip.
1274 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1275 (unsigned int)strlen(sshc->quote_path2),
1277 &sshc->quote_attrs);
1278 if(rc == LIBSSH2_ERROR_EAGAIN) {
1281 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1282 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1283 Curl_safefree(sshc->quote_path1);
1284 sshc->quote_path1 = NULL;
1285 Curl_safefree(sshc->quote_path2);
1286 sshc->quote_path2 = NULL;
1287 failf(data, "Attempt to get SFTP stats failed: %s",
1288 sftp_libssh2_strerror(err));
1289 state(conn, SSH_SFTP_CLOSE);
1290 sshc->nextstate = SSH_NO_STATE;
1291 sshc->actualcode = CURLE_QUOTE_ERROR;
1296 /* Now set the new attributes... */
1297 if(curl_strnequal(cmd, "chgrp", 5)) {
1298 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1299 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1300 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1301 !sshc->acceptfail) {
1302 Curl_safefree(sshc->quote_path1);
1303 sshc->quote_path1 = NULL;
1304 Curl_safefree(sshc->quote_path2);
1305 sshc->quote_path2 = NULL;
1306 failf(data, "Syntax error: chgrp gid not a number");
1307 state(conn, SSH_SFTP_CLOSE);
1308 sshc->nextstate = SSH_NO_STATE;
1309 sshc->actualcode = CURLE_QUOTE_ERROR;
1313 else if(curl_strnequal(cmd, "chmod", 5)) {
1314 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1315 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1316 /* permissions are octal */
1317 if(sshc->quote_attrs.permissions == 0 &&
1318 !ISDIGIT(sshc->quote_path1[0])) {
1319 Curl_safefree(sshc->quote_path1);
1320 sshc->quote_path1 = NULL;
1321 Curl_safefree(sshc->quote_path2);
1322 sshc->quote_path2 = NULL;
1323 failf(data, "Syntax error: chmod permissions not a number");
1324 state(conn, SSH_SFTP_CLOSE);
1325 sshc->nextstate = SSH_NO_STATE;
1326 sshc->actualcode = CURLE_QUOTE_ERROR;
1330 else if(curl_strnequal(cmd, "chown", 5)) {
1331 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1332 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1333 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1334 !sshc->acceptfail) {
1335 Curl_safefree(sshc->quote_path1);
1336 sshc->quote_path1 = NULL;
1337 Curl_safefree(sshc->quote_path2);
1338 sshc->quote_path2 = NULL;
1339 failf(data, "Syntax error: chown uid not a number");
1340 state(conn, SSH_SFTP_CLOSE);
1341 sshc->nextstate = SSH_NO_STATE;
1342 sshc->actualcode = CURLE_QUOTE_ERROR;
1347 /* Now send the completed structure... */
1348 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1352 case SSH_SFTP_QUOTE_SETSTAT:
1353 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1354 (unsigned int)strlen(sshc->quote_path2),
1355 LIBSSH2_SFTP_SETSTAT,
1356 &sshc->quote_attrs);
1357 if(rc == LIBSSH2_ERROR_EAGAIN) {
1360 else if(rc != 0 && !sshc->acceptfail) {
1361 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1362 Curl_safefree(sshc->quote_path1);
1363 sshc->quote_path1 = NULL;
1364 Curl_safefree(sshc->quote_path2);
1365 sshc->quote_path2 = NULL;
1366 failf(data, "Attempt to set SFTP stats failed: %s",
1367 sftp_libssh2_strerror(err));
1368 state(conn, SSH_SFTP_CLOSE);
1369 sshc->nextstate = SSH_NO_STATE;
1370 sshc->actualcode = CURLE_QUOTE_ERROR;
1373 state(conn, SSH_SFTP_NEXT_QUOTE);
1376 case SSH_SFTP_QUOTE_SYMLINK:
1377 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1378 (unsigned int)strlen(sshc->quote_path1),
1380 (unsigned int)strlen(sshc->quote_path2),
1381 LIBSSH2_SFTP_SYMLINK);
1382 if(rc == LIBSSH2_ERROR_EAGAIN) {
1385 else if(rc != 0 && !sshc->acceptfail) {
1386 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1387 Curl_safefree(sshc->quote_path1);
1388 sshc->quote_path1 = NULL;
1389 Curl_safefree(sshc->quote_path2);
1390 sshc->quote_path2 = NULL;
1391 failf(data, "symlink command failed: %s",
1392 sftp_libssh2_strerror(err));
1393 state(conn, SSH_SFTP_CLOSE);
1394 sshc->nextstate = SSH_NO_STATE;
1395 sshc->actualcode = CURLE_QUOTE_ERROR;
1398 state(conn, SSH_SFTP_NEXT_QUOTE);
1401 case SSH_SFTP_QUOTE_MKDIR:
1402 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1403 (unsigned int)strlen(sshc->quote_path1),
1404 data->set.new_directory_perms);
1405 if(rc == LIBSSH2_ERROR_EAGAIN) {
1408 else if(rc != 0 && !sshc->acceptfail) {
1409 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1410 Curl_safefree(sshc->quote_path1);
1411 sshc->quote_path1 = NULL;
1412 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1413 state(conn, SSH_SFTP_CLOSE);
1414 sshc->nextstate = SSH_NO_STATE;
1415 sshc->actualcode = CURLE_QUOTE_ERROR;
1418 state(conn, SSH_SFTP_NEXT_QUOTE);
1421 case SSH_SFTP_QUOTE_RENAME:
1422 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1423 (unsigned int)strlen(sshc->quote_path1),
1425 (unsigned int)strlen(sshc->quote_path2),
1426 LIBSSH2_SFTP_RENAME_OVERWRITE |
1427 LIBSSH2_SFTP_RENAME_ATOMIC |
1428 LIBSSH2_SFTP_RENAME_NATIVE);
1430 if(rc == LIBSSH2_ERROR_EAGAIN) {
1433 else if(rc != 0 && !sshc->acceptfail) {
1434 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1435 Curl_safefree(sshc->quote_path1);
1436 sshc->quote_path1 = NULL;
1437 Curl_safefree(sshc->quote_path2);
1438 sshc->quote_path2 = NULL;
1439 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1440 state(conn, SSH_SFTP_CLOSE);
1441 sshc->nextstate = SSH_NO_STATE;
1442 sshc->actualcode = CURLE_QUOTE_ERROR;
1445 state(conn, SSH_SFTP_NEXT_QUOTE);
1448 case SSH_SFTP_QUOTE_RMDIR:
1449 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1450 (unsigned int)strlen(sshc->quote_path1));
1451 if(rc == LIBSSH2_ERROR_EAGAIN) {
1454 else if(rc != 0 && !sshc->acceptfail) {
1455 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1456 Curl_safefree(sshc->quote_path1);
1457 sshc->quote_path1 = NULL;
1458 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1459 state(conn, SSH_SFTP_CLOSE);
1460 sshc->nextstate = SSH_NO_STATE;
1461 sshc->actualcode = CURLE_QUOTE_ERROR;
1464 state(conn, SSH_SFTP_NEXT_QUOTE);
1467 case SSH_SFTP_QUOTE_UNLINK:
1468 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1469 (unsigned int)strlen(sshc->quote_path1));
1470 if(rc == LIBSSH2_ERROR_EAGAIN) {
1473 else if(rc != 0 && !sshc->acceptfail) {
1474 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1475 Curl_safefree(sshc->quote_path1);
1476 sshc->quote_path1 = NULL;
1477 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1478 state(conn, SSH_SFTP_CLOSE);
1479 sshc->nextstate = SSH_NO_STATE;
1480 sshc->actualcode = CURLE_QUOTE_ERROR;
1483 state(conn, SSH_SFTP_NEXT_QUOTE);
1486 case SSH_SFTP_TRANS_INIT:
1487 if(data->set.upload)
1488 state(conn, SSH_SFTP_UPLOAD_INIT);
1490 if(data->set.opt_no_body)
1491 state(conn, SSH_STOP);
1492 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1493 state(conn, SSH_SFTP_READDIR_INIT);
1495 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1499 case SSH_SFTP_UPLOAD_INIT:
1501 unsigned long flags;
1503 * NOTE!!! libssh2 requires that the destination path is a full path
1504 * that includes the destination file and name OR ends in a "/"
1505 * If this is not done the destination file will be named the
1506 * same name as the last directory in the path.
1509 if(data->state.resume_from != 0) {
1510 LIBSSH2_SFTP_ATTRIBUTES attrs;
1511 if(data->state.resume_from < 0) {
1512 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1513 (unsigned int)strlen(sftp_scp->path),
1514 LIBSSH2_SFTP_STAT, &attrs);
1515 if(rc == LIBSSH2_ERROR_EAGAIN) {
1519 data->state.resume_from = 0;
1522 curl_off_t size = attrs.filesize;
1524 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1525 return CURLE_BAD_DOWNLOAD_RESUME;
1527 data->state.resume_from = attrs.filesize;
1532 if(data->set.ftp_append)
1533 /* Try to open for append, but create if nonexisting */
1534 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1535 else if(data->state.resume_from > 0)
1536 /* If we have restart position then open for append */
1537 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1539 /* Clear file before writing (normal behaviour) */
1540 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1543 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1544 (unsigned int)strlen(sftp_scp->path),
1545 flags, data->set.new_file_perms,
1546 LIBSSH2_SFTP_OPENFILE);
1548 if(!sshc->sftp_handle) {
1549 rc = libssh2_session_last_errno(sshc->ssh_session);
1551 if(LIBSSH2_ERROR_EAGAIN == rc)
1554 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1555 /* only when there was an SFTP protocol error can we extract
1557 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1559 err = -1; /* not an sftp error at all */
1561 if(sshc->secondCreateDirs) {
1562 state(conn, SSH_SFTP_CLOSE);
1563 sshc->actualcode = err>= LIBSSH2_FX_OK?
1564 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1565 failf(data, "Creating the dir/file failed: %s",
1566 sftp_libssh2_strerror(err));
1569 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1570 (err == LIBSSH2_FX_FAILURE) ||
1571 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1572 (data->set.ftp_create_missing_dirs &&
1573 (strlen(sftp_scp->path) > 1))) {
1574 /* try to create the path remotely */
1575 sshc->secondCreateDirs = 1;
1576 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1579 state(conn, SSH_SFTP_CLOSE);
1580 sshc->actualcode = err>= LIBSSH2_FX_OK?
1581 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1582 if(!sshc->actualcode) {
1583 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1584 zero even though libssh2_sftp_open() failed previously! We need
1585 to work around that! */
1586 sshc->actualcode = CURLE_SSH;
1589 failf(data, "Upload failed: %s (%d/%d)",
1590 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1596 /* If we have restart point then we need to seek to the correct
1598 if(data->state.resume_from > 0) {
1599 /* Let's read off the proper amount of bytes from the input. */
1600 if(conn->seek_func) {
1601 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1605 if(seekerr != CURL_SEEKFUNC_OK) {
1607 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1608 failf(data, "Could not seek stream");
1609 return CURLE_FTP_COULDNT_USE_REST;
1611 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1613 curl_off_t passed=0;
1615 size_t readthisamountnow =
1616 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1617 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1619 size_t actuallyread =
1620 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1623 passed += actuallyread;
1624 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1625 /* this checks for greater-than only to make sure that the
1626 CURL_READFUNC_ABORT return code still aborts */
1627 failf(data, "Failed to read data");
1628 return CURLE_FTP_COULDNT_USE_REST;
1630 } while(passed < data->state.resume_from);
1634 /* now, decrease the size of the read */
1635 if(data->set.infilesize > 0) {
1636 data->set.infilesize -= data->state.resume_from;
1637 data->req.size = data->set.infilesize;
1638 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1641 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1643 if(data->set.infilesize > 0) {
1644 data->req.size = data->set.infilesize;
1645 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1648 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1650 /* not set by Curl_setup_transfer to preserve keepon bits */
1651 conn->sockfd = conn->writesockfd;
1654 state(conn, SSH_SFTP_CLOSE);
1655 sshc->actualcode = result;
1658 /* store this original bitmask setup to use later on if we can't
1659 figure out a "real" bitmask */
1660 sshc->orig_waitfor = data->req.keepon;
1662 /* we want to use the _sending_ function even when the socket turns
1663 out readable as the underlying libssh2 sftp send function will deal
1664 with both accordingly */
1665 conn->cselect_bits = CURL_CSELECT_OUT;
1667 /* since we don't really wait for anything at this point, we want the
1668 state machine to move on as soon as possible so we set a very short
1670 Curl_expire(data, 1);
1672 state(conn, SSH_STOP);
1677 case SSH_SFTP_CREATE_DIRS_INIT:
1678 if(strlen(sftp_scp->path) > 1) {
1679 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1680 state(conn, SSH_SFTP_CREATE_DIRS);
1683 state(conn, SSH_SFTP_UPLOAD_INIT);
1687 case SSH_SFTP_CREATE_DIRS:
1688 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1689 *sshc->slash_pos = 0;
1691 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1692 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1696 state(conn, SSH_SFTP_UPLOAD_INIT);
1700 case SSH_SFTP_CREATE_DIRS_MKDIR:
1701 /* 'mode' - parameter is preliminary - default to 0644 */
1702 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1703 (unsigned int)strlen(sftp_scp->path),
1704 data->set.new_directory_perms);
1705 if(rc == LIBSSH2_ERROR_EAGAIN) {
1708 *sshc->slash_pos = '/';
1711 unsigned int sftp_err = 0;
1713 * Abort if failure wasn't that the dir already exists or the
1714 * permission was denied (creation might succeed further down the
1715 * path) - retry on unspecific FAILURE also
1717 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1718 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1719 (sftp_err != LIBSSH2_FX_FAILURE) &&
1720 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1721 result = sftp_libssh2_error_to_CURLE(sftp_err);
1722 state(conn, SSH_SFTP_CLOSE);
1723 sshc->actualcode = result?result:CURLE_SSH;
1727 state(conn, SSH_SFTP_CREATE_DIRS);
1730 case SSH_SFTP_READDIR_INIT:
1732 * This is a directory that we are trying to get, so produce a directory
1735 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1738 strlen(sftp_scp->path),
1739 0, 0, LIBSSH2_SFTP_OPENDIR);
1740 if(!sshc->sftp_handle) {
1741 if(libssh2_session_last_errno(sshc->ssh_session) ==
1742 LIBSSH2_ERROR_EAGAIN) {
1743 rc = LIBSSH2_ERROR_EAGAIN;
1747 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1748 failf(data, "Could not open directory for reading: %s",
1749 sftp_libssh2_strerror(err));
1750 state(conn, SSH_SFTP_CLOSE);
1751 result = sftp_libssh2_error_to_CURLE(err);
1752 sshc->actualcode = result?result:CURLE_SSH;
1756 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1757 state(conn, SSH_SFTP_CLOSE);
1758 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1761 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1762 Curl_safefree(sshc->readdir_filename);
1763 sshc->readdir_filename = NULL;
1764 state(conn, SSH_SFTP_CLOSE);
1765 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1768 state(conn, SSH_SFTP_READDIR);
1771 case SSH_SFTP_READDIR:
1772 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1773 sshc->readdir_filename,
1775 sshc->readdir_longentry,
1777 &sshc->readdir_attrs);
1778 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1779 rc = LIBSSH2_ERROR_EAGAIN;
1782 if(sshc->readdir_len > 0) {
1783 sshc->readdir_filename[sshc->readdir_len] = '\0';
1785 if(data->set.ftp_list_only) {
1788 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1789 if(tmpLine == NULL) {
1790 state(conn, SSH_SFTP_CLOSE);
1791 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1794 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1795 tmpLine, sshc->readdir_len+1);
1796 Curl_safefree(tmpLine);
1799 state(conn, SSH_STOP);
1802 /* since this counts what we send to the client, we include the
1803 newline in this counter */
1804 data->req.bytecount += sshc->readdir_len+1;
1806 /* output debug output if that is requested */
1807 if(data->set.verbose) {
1808 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1809 sshc->readdir_len, conn);
1813 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1814 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1815 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1816 if(!sshc->readdir_line) {
1817 Curl_safefree(sshc->readdir_filename);
1818 sshc->readdir_filename = NULL;
1819 Curl_safefree(sshc->readdir_longentry);
1820 sshc->readdir_longentry = NULL;
1821 state(conn, SSH_SFTP_CLOSE);
1822 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1826 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1827 sshc->readdir_currLen);
1828 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1829 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1830 LIBSSH2_SFTP_S_IFLNK)) {
1831 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1832 if(sshc->readdir_linkPath == NULL) {
1833 Curl_safefree(sshc->readdir_filename);
1834 sshc->readdir_filename = NULL;
1835 Curl_safefree(sshc->readdir_longentry);
1836 sshc->readdir_longentry = NULL;
1837 state(conn, SSH_SFTP_CLOSE);
1838 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1842 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1843 sshc->readdir_filename);
1844 state(conn, SSH_SFTP_READDIR_LINK);
1847 state(conn, SSH_SFTP_READDIR_BOTTOM);
1851 else if(sshc->readdir_len == 0) {
1852 Curl_safefree(sshc->readdir_filename);
1853 sshc->readdir_filename = NULL;
1854 Curl_safefree(sshc->readdir_longentry);
1855 sshc->readdir_longentry = NULL;
1856 state(conn, SSH_SFTP_READDIR_DONE);
1859 else if(sshc->readdir_len <= 0) {
1860 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1861 result = sftp_libssh2_error_to_CURLE(err);
1862 sshc->actualcode = result?result:CURLE_SSH;
1863 failf(data, "Could not open remote file for reading: %s :: %d",
1864 sftp_libssh2_strerror(err),
1865 libssh2_session_last_errno(sshc->ssh_session));
1866 Curl_safefree(sshc->readdir_filename);
1867 sshc->readdir_filename = NULL;
1868 Curl_safefree(sshc->readdir_longentry);
1869 sshc->readdir_longentry = NULL;
1870 state(conn, SSH_SFTP_CLOSE);
1875 case SSH_SFTP_READDIR_LINK:
1877 libssh2_sftp_symlink_ex(sshc->sftp_session,
1878 sshc->readdir_linkPath,
1879 (unsigned int) strlen(sshc->readdir_linkPath),
1880 sshc->readdir_filename,
1881 PATH_MAX, LIBSSH2_SFTP_READLINK);
1882 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1883 rc = LIBSSH2_ERROR_EAGAIN;
1886 Curl_safefree(sshc->readdir_linkPath);
1887 sshc->readdir_linkPath = NULL;
1889 /* get room for the filename and extra output */
1890 sshc->readdir_totalLen += 4 + sshc->readdir_len;
1891 new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
1892 if(!new_readdir_line) {
1893 Curl_safefree(sshc->readdir_line);
1894 sshc->readdir_line = NULL;
1895 Curl_safefree(sshc->readdir_filename);
1896 sshc->readdir_filename = NULL;
1897 Curl_safefree(sshc->readdir_longentry);
1898 sshc->readdir_longentry = NULL;
1899 state(conn, SSH_SFTP_CLOSE);
1900 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1903 sshc->readdir_line = new_readdir_line;
1905 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1906 sshc->readdir_currLen,
1907 sshc->readdir_totalLen -
1908 sshc->readdir_currLen,
1910 sshc->readdir_filename);
1912 state(conn, SSH_SFTP_READDIR_BOTTOM);
1915 case SSH_SFTP_READDIR_BOTTOM:
1916 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1917 sshc->readdir_currLen,
1918 sshc->readdir_totalLen -
1919 sshc->readdir_currLen, "\n");
1920 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1922 sshc->readdir_currLen);
1924 if(result == CURLE_OK) {
1926 /* output debug output if that is requested */
1927 if(data->set.verbose) {
1928 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1929 sshc->readdir_currLen, conn);
1931 data->req.bytecount += sshc->readdir_currLen;
1933 Curl_safefree(sshc->readdir_line);
1934 sshc->readdir_line = NULL;
1936 state(conn, SSH_STOP);
1939 state(conn, SSH_SFTP_READDIR);
1942 case SSH_SFTP_READDIR_DONE:
1943 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1944 LIBSSH2_ERROR_EAGAIN) {
1945 rc = LIBSSH2_ERROR_EAGAIN;
1948 sshc->sftp_handle = NULL;
1949 Curl_safefree(sshc->readdir_filename);
1950 sshc->readdir_filename = NULL;
1951 Curl_safefree(sshc->readdir_longentry);
1952 sshc->readdir_longentry = NULL;
1954 /* no data to transfer */
1955 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1956 state(conn, SSH_STOP);
1959 case SSH_SFTP_DOWNLOAD_INIT:
1961 * Work on getting the specified file
1964 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1965 (unsigned int)strlen(sftp_scp->path),
1966 LIBSSH2_FXF_READ, data->set.new_file_perms,
1967 LIBSSH2_SFTP_OPENFILE);
1968 if(!sshc->sftp_handle) {
1969 if(libssh2_session_last_errno(sshc->ssh_session) ==
1970 LIBSSH2_ERROR_EAGAIN) {
1971 rc = LIBSSH2_ERROR_EAGAIN;
1975 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1976 failf(data, "Could not open remote file for reading: %s",
1977 sftp_libssh2_strerror(err));
1978 state(conn, SSH_SFTP_CLOSE);
1979 result = sftp_libssh2_error_to_CURLE(err);
1980 sshc->actualcode = result?result:CURLE_SSH;
1984 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1987 case SSH_SFTP_DOWNLOAD_STAT:
1989 LIBSSH2_SFTP_ATTRIBUTES attrs;
1991 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1992 (unsigned int)strlen(sftp_scp->path),
1993 LIBSSH2_SFTP_STAT, &attrs);
1994 if(rc == LIBSSH2_ERROR_EAGAIN) {
1999 * libssh2_sftp_open() didn't return an error, so maybe the server
2000 * just doesn't support stat()
2002 data->req.size = -1;
2003 data->req.maxdownload = -1;
2006 curl_off_t size = attrs.filesize;
2009 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
2010 return CURLE_BAD_DOWNLOAD_RESUME;
2012 if(conn->data->state.use_range) {
2013 curl_off_t from, to;
2017 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2018 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2020 to=curlx_strtoofft(ptr, &ptr2, 0);
2021 if((ptr == ptr2) /* no "to" value given */
2026 /* from is relative to end of file */
2030 failf(data, "Offset (%"
2031 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2032 from, attrs.filesize);
2033 return CURLE_BAD_DOWNLOAD_RESUME;
2040 size = to - from + 1;
2043 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2045 data->req.size = size;
2046 data->req.maxdownload = size;
2047 Curl_pgrsSetDownloadSize(data, size);
2050 /* We can resume if we can seek to the resume position */
2051 if(data->state.resume_from) {
2052 if(data->state.resume_from < 0) {
2053 /* We're supposed to download the last abs(from) bytes */
2054 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2055 failf(data, "Offset (%"
2056 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2057 data->state.resume_from, attrs.filesize);
2058 return CURLE_BAD_DOWNLOAD_RESUME;
2060 /* download from where? */
2061 data->state.resume_from += attrs.filesize;
2064 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2065 failf(data, "Offset (%" FORMAT_OFF_T
2066 ") was beyond file size (%" FORMAT_OFF_T ")",
2067 data->state.resume_from, attrs.filesize);
2068 return CURLE_BAD_DOWNLOAD_RESUME;
2071 /* Does a completed file need to be seeked and started or closed ? */
2072 /* Now store the number of bytes we are expected to download */
2073 data->req.size = attrs.filesize - data->state.resume_from;
2074 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2075 Curl_pgrsSetDownloadSize(data,
2076 attrs.filesize - data->state.resume_from);
2077 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2080 /* Setup the actual download */
2081 if(data->req.size == 0) {
2082 /* no data to transfer */
2083 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2084 infof(data, "File already completely downloaded\n");
2085 state(conn, SSH_STOP);
2089 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2090 FALSE, NULL, -1, NULL);
2092 /* not set by Curl_setup_transfer to preserve keepon bits */
2093 conn->writesockfd = conn->sockfd;
2095 /* we want to use the _receiving_ function even when the socket turns
2096 out writableable as the underlying libssh2 recv function will deal
2097 with both accordingly */
2098 conn->cselect_bits = CURL_CSELECT_IN;
2101 state(conn, SSH_SFTP_CLOSE);
2102 sshc->actualcode = result;
2105 state(conn, SSH_STOP);
2109 case SSH_SFTP_CLOSE:
2110 if(sshc->sftp_handle) {
2111 rc = libssh2_sftp_close(sshc->sftp_handle);
2112 if(rc == LIBSSH2_ERROR_EAGAIN) {
2116 infof(data, "Failed to close libssh2 file\n");
2118 sshc->sftp_handle = NULL;
2121 Curl_safefree(sftp_scp->path);
2122 sftp_scp->path = NULL;
2125 DEBUGF(infof(data, "SFTP DONE done\n"));
2127 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2128 After nextstate is executed,the control should come back to
2129 SSH_SFTP_CLOSE to pass the correct result back */
2130 if(sshc->nextstate != SSH_NO_STATE) {
2131 state(conn, sshc->nextstate);
2132 sshc->nextstate = SSH_SFTP_CLOSE;
2135 state(conn, SSH_STOP);
2136 result = sshc->actualcode;
2140 case SSH_SFTP_SHUTDOWN:
2141 /* during times we get here due to a broken transfer and then the
2142 sftp_handle might not have been taken down so make sure that is done
2143 before we proceed */
2145 if(sshc->sftp_handle) {
2146 rc = libssh2_sftp_close(sshc->sftp_handle);
2147 if(rc == LIBSSH2_ERROR_EAGAIN) {
2151 infof(data, "Failed to close libssh2 file\n");
2153 sshc->sftp_handle = NULL;
2155 if(sshc->sftp_session) {
2156 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2157 if(rc == LIBSSH2_ERROR_EAGAIN) {
2161 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2163 sshc->sftp_session = NULL;
2166 Curl_safefree(sshc->homedir);
2167 sshc->homedir = NULL;
2168 conn->data->state.most_recent_ftp_entrypath = NULL;
2170 state(conn, SSH_SESSION_DISCONNECT);
2173 case SSH_SCP_TRANS_INIT:
2174 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2176 sshc->actualcode = result;
2177 state(conn, SSH_STOP);
2181 if(data->set.upload) {
2182 if(data->set.infilesize < 0) {
2183 failf(data, "SCP requires a known file size for upload");
2184 sshc->actualcode = CURLE_UPLOAD_FAILED;
2185 state(conn, SSH_SCP_CHANNEL_FREE);
2188 state(conn, SSH_SCP_UPLOAD_INIT);
2191 state(conn, SSH_SCP_DOWNLOAD_INIT);
2195 case SSH_SCP_UPLOAD_INIT:
2197 * libssh2 requires that the destination path is a full path that
2198 * includes the destination file and name OR ends in a "/" . If this is
2199 * not done the destination file will be named the same name as the last
2200 * directory in the path.
2203 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2204 data->set.infilesize);
2205 if(!sshc->ssh_channel) {
2206 if(libssh2_session_last_errno(sshc->ssh_session) ==
2207 LIBSSH2_ERROR_EAGAIN) {
2208 rc = LIBSSH2_ERROR_EAGAIN;
2215 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2216 &err_msg, NULL, 0));
2217 failf(conn->data, "%s", err_msg);
2218 state(conn, SSH_SCP_CHANNEL_FREE);
2219 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2225 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2228 /* not set by Curl_setup_transfer to preserve keepon bits */
2229 conn->sockfd = conn->writesockfd;
2232 state(conn, SSH_SCP_CHANNEL_FREE);
2233 sshc->actualcode = result;
2236 /* we want to use the _sending_ function even when the socket turns
2237 out readable as the underlying libssh2 scp send function will deal
2238 with both accordingly */
2239 conn->cselect_bits = CURL_CSELECT_OUT;
2241 state(conn, SSH_STOP);
2245 case SSH_SCP_DOWNLOAD_INIT:
2248 * We must check the remote file; if it is a directory no values will
2252 curl_off_t bytecount;
2254 /* clear the struct scp recv will fill in */
2255 memset(&sb, 0, sizeof(struct stat));
2257 /* get a fresh new channel from the ssh layer */
2258 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2259 sftp_scp->path, &sb);
2260 if(!sshc->ssh_channel) {
2261 if(libssh2_session_last_errno(sshc->ssh_session) ==
2262 LIBSSH2_ERROR_EAGAIN) {
2263 rc = LIBSSH2_ERROR_EAGAIN;
2270 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2271 &err_msg, NULL, 0));
2272 failf(conn->data, "%s", err_msg);
2273 state(conn, SSH_SCP_CHANNEL_FREE);
2274 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2280 bytecount = (curl_off_t)sb.st_size;
2281 data->req.maxdownload = (curl_off_t)sb.st_size;
2282 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2284 /* not set by Curl_setup_transfer to preserve keepon bits */
2285 conn->writesockfd = conn->sockfd;
2287 /* we want to use the _receiving_ function even when the socket turns
2288 out writableable as the underlying libssh2 recv function will deal
2289 with both accordingly */
2290 conn->cselect_bits = CURL_CSELECT_IN;
2293 state(conn, SSH_SCP_CHANNEL_FREE);
2294 sshc->actualcode = result;
2297 state(conn, SSH_STOP);
2302 if(data->set.upload)
2303 state(conn, SSH_SCP_SEND_EOF);
2305 state(conn, SSH_SCP_CHANNEL_FREE);
2308 case SSH_SCP_SEND_EOF:
2309 if(sshc->ssh_channel) {
2310 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2311 if(rc == LIBSSH2_ERROR_EAGAIN) {
2315 infof(data, "Failed to send libssh2 channel EOF\n");
2318 state(conn, SSH_SCP_WAIT_EOF);
2321 case SSH_SCP_WAIT_EOF:
2322 if(sshc->ssh_channel) {
2323 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2324 if(rc == LIBSSH2_ERROR_EAGAIN) {
2328 infof(data, "Failed to get channel EOF: %d\n", rc);
2331 state(conn, SSH_SCP_WAIT_CLOSE);
2334 case SSH_SCP_WAIT_CLOSE:
2335 if(sshc->ssh_channel) {
2336 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2337 if(rc == LIBSSH2_ERROR_EAGAIN) {
2341 infof(data, "Channel failed to close: %d\n", rc);
2344 state(conn, SSH_SCP_CHANNEL_FREE);
2347 case SSH_SCP_CHANNEL_FREE:
2348 if(sshc->ssh_channel) {
2349 rc = libssh2_channel_free(sshc->ssh_channel);
2350 if(rc == LIBSSH2_ERROR_EAGAIN) {
2354 infof(data, "Failed to free libssh2 scp subsystem\n");
2356 sshc->ssh_channel = NULL;
2358 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2360 state(conn, SSH_SESSION_DISCONNECT);
2362 state(conn, SSH_STOP);
2363 result = sshc->actualcode;
2366 case SSH_SESSION_DISCONNECT:
2367 /* during weird times when we've been prematurely aborted, the channel
2368 is still alive when we reach this state and we MUST kill the channel
2370 if(sshc->ssh_channel) {
2371 rc = libssh2_channel_free(sshc->ssh_channel);
2372 if(rc == LIBSSH2_ERROR_EAGAIN) {
2376 infof(data, "Failed to free libssh2 scp subsystem\n");
2378 sshc->ssh_channel = NULL;
2381 if(sshc->ssh_session) {
2382 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2383 if(rc == LIBSSH2_ERROR_EAGAIN) {
2387 infof(data, "Failed to disconnect libssh2 session\n");
2391 Curl_safefree(sshc->homedir);
2392 sshc->homedir = NULL;
2393 conn->data->state.most_recent_ftp_entrypath = NULL;
2395 state(conn, SSH_SESSION_FREE);
2398 case SSH_SESSION_FREE:
2399 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2401 libssh2_knownhost_free(sshc->kh);
2406 if(sshc->ssh_session) {
2407 rc = libssh2_session_free(sshc->ssh_session);
2408 if(rc == LIBSSH2_ERROR_EAGAIN) {
2412 infof(data, "Failed to free libssh2 session\n");
2414 sshc->ssh_session = NULL;
2417 /* worst-case scenario cleanup */
2419 DEBUGASSERT(sshc->ssh_session == NULL);
2420 DEBUGASSERT(sshc->ssh_channel == NULL);
2421 DEBUGASSERT(sshc->sftp_session == NULL);
2422 DEBUGASSERT(sshc->sftp_handle == NULL);
2423 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2424 DEBUGASSERT(sshc->kh == NULL);
2427 Curl_safefree(sshc->rsa_pub);
2428 Curl_safefree(sshc->rsa);
2430 Curl_safefree(sshc->quote_path1);
2431 Curl_safefree(sshc->quote_path2);
2433 Curl_safefree(sshc->homedir);
2435 Curl_safefree(sshc->readdir_filename);
2436 Curl_safefree(sshc->readdir_longentry);
2437 Curl_safefree(sshc->readdir_line);
2438 Curl_safefree(sshc->readdir_linkPath);
2440 /* the code we are about to return */
2441 result = sshc->actualcode;
2443 memset(sshc, 0, sizeof(struct ssh_conn));
2445 conn->bits.close = TRUE;
2446 sshc->state = SSH_SESSION_FREE; /* current */
2447 sshc->nextstate = SSH_NO_STATE;
2448 state(conn, SSH_STOP);
2452 /* fallthrough, just stop! */
2454 /* internal error */
2455 sshc->nextstate = SSH_NO_STATE;
2456 state(conn, SSH_STOP);
2460 } while(!rc && (sshc->state != SSH_STOP));
2462 if(rc == LIBSSH2_ERROR_EAGAIN) {
2463 /* we would block, we need to wait for the socket to be ready (in the
2464 right direction too)! */
2471 /* called by the multi interface to figure out what socket(s) to wait for and
2472 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2473 static int ssh_perform_getsock(const struct connectdata *conn,
2474 curl_socket_t *sock, /* points to numsocks
2475 number of sockets */
2478 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2479 int bitmap = GETSOCK_BLANK;
2482 sock[0] = conn->sock[FIRSTSOCKET];
2484 if(conn->waitfor & KEEP_RECV)
2485 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2487 if(conn->waitfor & KEEP_SEND)
2488 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2492 /* if we don't know the direction we can use the generic *_getsock()
2493 function even for the protocol_connect and doing states */
2494 return Curl_single_getsock(conn, sock, numsocks);
2498 /* Generic function called by the multi interface to figure out what socket(s)
2499 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2500 static int ssh_getsock(struct connectdata *conn,
2501 curl_socket_t *sock, /* points to numsocks number
2505 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2509 /* if we don't know any direction we can just play along as we used to and
2510 not provide any sensible info */
2511 return GETSOCK_BLANK;
2513 /* if we know the direction we can use the generic *_getsock() function even
2514 for the protocol_connect and doing states */
2515 return ssh_perform_getsock(conn, sock, numsocks);
2519 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2521 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2522 * function is used to figure out in what direction and stores this info so
2523 * that the multi interface can take advantage of it. Make sure to call this
2524 * function in all cases so that when it _doesn't_ return EAGAIN we can
2525 * restore the default wait bits.
2527 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2529 struct ssh_conn *sshc = &conn->proto.sshc;
2533 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2534 /* translate the libssh2 define bits into our own bit defines */
2535 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2536 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2539 /* It didn't block or libssh2 didn't reveal in which direction, put back
2541 conn->waitfor = sshc->orig_waitfor;
2544 /* no libssh2 directional support so we simply don't know */
2545 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2548 /* called repeatedly until done from multi.c */
2549 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2551 struct ssh_conn *sshc = &conn->proto.sshc;
2552 CURLcode result = CURLE_OK;
2553 bool block; /* we store the status and use that to provide a ssh_getsock()
2556 result = ssh_statemach_act(conn, &block);
2557 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2558 ssh_block2waitfor(conn, block);
2563 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2566 struct ssh_conn *sshc = &conn->proto.sshc;
2567 CURLcode result = CURLE_OK;
2568 struct SessionHandle *data = conn->data;
2570 while((sshc->state != SSH_STOP) && !result) {
2574 result = ssh_statemach_act(conn, &block);
2578 if(Curl_pgrsUpdate(conn))
2579 return CURLE_ABORTED_BY_CALLBACK;
2581 struct timeval now = Curl_tvnow();
2582 result = Curl_speedcheck(data, now);
2587 left = Curl_timeleft(data, NULL, duringconnect);
2589 failf(data, "Operation timed out\n");
2590 return CURLE_OPERATION_TIMEDOUT;
2593 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2594 if((CURLE_OK == result) && block) {
2595 int dir = libssh2_session_block_directions(sshc->ssh_session);
2596 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2597 curl_socket_t fd_read = CURL_SOCKET_BAD;
2598 curl_socket_t fd_write = CURL_SOCKET_BAD;
2599 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2601 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2603 /* wait for the socket to become ready */
2604 Curl_socket_ready(fd_read, fd_write,
2605 left>1000?1000:left); /* ignore result */
2615 * SSH setup and connection
2617 static CURLcode ssh_init(struct connectdata *conn)
2619 struct SessionHandle *data = conn->data;
2620 struct SSHPROTO *ssh;
2621 struct ssh_conn *sshc = &conn->proto.sshc;
2623 sshc->actualcode = CURLE_OK; /* reset error code */
2624 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2627 if(data->state.proto.ssh)
2630 ssh = calloc(1, sizeof(struct SSHPROTO));
2632 return CURLE_OUT_OF_MEMORY;
2634 data->state.proto.ssh = ssh;
2639 static Curl_recv scp_recv, sftp_recv;
2640 static Curl_send scp_send, sftp_send;
2643 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2644 * do protocol-specific actions at connect-time.
2646 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2648 #ifdef CURL_LIBSSH2_DEBUG
2651 struct ssh_conn *ssh;
2653 struct SessionHandle *data = conn->data;
2655 /* We default to persistent connections. We set this already in this connect
2656 function to make the re-use checks properly be able to check this bit. */
2657 conn->bits.close = FALSE;
2659 /* If there already is a protocol-specific struct allocated for this
2660 sessionhandle, deal with it */
2661 Curl_reset_reqproto(conn);
2663 if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
2664 /* for SSH over HTTP proxy */
2665 struct HTTP http_proxy;
2666 struct SSHPROTO *ssh_save;
2669 /* We want "seamless" SSH operations through HTTP proxy tunnel */
2671 /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member
2672 * conn->proto.http; we want SSH through HTTP and we have to change the
2673 * member temporarily for connecting to the HTTP proxy. After
2674 * Curl_proxyCONNECT we have to set back the member to the original struct
2677 ssh_save = data->state.proto.ssh;
2678 memset(&http_proxy, 0, sizeof(http_proxy));
2679 data->state.proto.http = &http_proxy;
2681 result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
2682 conn->host.name, conn->remote_port);
2684 data->state.proto.ssh = ssh_save;
2686 if(CURLE_OK != result)
2690 result = ssh_init(conn);
2694 if(conn->handler->protocol & CURLPROTO_SCP) {
2695 conn->recv[FIRSTSOCKET] = scp_recv;
2696 conn->send[FIRSTSOCKET] = scp_send;
2699 conn->recv[FIRSTSOCKET] = sftp_recv;
2700 conn->send[FIRSTSOCKET] = sftp_send;
2702 ssh = &conn->proto.sshc;
2704 #ifdef CURL_LIBSSH2_DEBUG
2706 infof(data, "User: %s\n", conn->user);
2709 infof(data, "Password: %s\n", conn->passwd);
2711 sock = conn->sock[FIRSTSOCKET];
2712 #endif /* CURL_LIBSSH2_DEBUG */
2714 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2716 my_libssh2_realloc, conn);
2717 if(ssh->ssh_session == NULL) {
2718 failf(data, "Failure initialising ssh session");
2719 return CURLE_FAILED_INIT;
2722 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2723 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2725 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2727 /* eeek. TODO: free the ssh_session! */
2728 return CURLE_FAILED_INIT;
2731 /* read all known hosts from there */
2732 rc = libssh2_knownhost_readfile(ssh->kh,
2733 data->set.str[STRING_SSH_KNOWNHOSTS],
2734 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2736 infof(data, "Failed to read known hosts from %s\n",
2737 data->set.str[STRING_SSH_KNOWNHOSTS]);
2739 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2741 #ifdef CURL_LIBSSH2_DEBUG
2742 libssh2_trace(ssh->ssh_session, ~0);
2743 infof(data, "SSH socket: %d\n", (int)sock);
2744 #endif /* CURL_LIBSSH2_DEBUG */
2746 state(conn, SSH_INIT);
2748 if(data->state.used_interface == Curl_if_multi)
2749 result = ssh_multi_statemach(conn, done);
2751 result = ssh_easy_statemach(conn, TRUE);
2760 ***********************************************************************
2764 * This is the actual DO function for SCP. Get a file according to
2765 * the options previously setup.
2769 CURLcode scp_perform(struct connectdata *conn,
2773 CURLcode result = CURLE_OK;
2775 DEBUGF(infof(conn->data, "DO phase starts\n"));
2777 *dophase_done = FALSE; /* not done yet */
2779 /* start the first command in the DO phase */
2780 state(conn, SSH_SCP_TRANS_INIT);
2782 /* run the state-machine */
2783 if(conn->data->state.used_interface == Curl_if_multi) {
2784 result = ssh_multi_statemach(conn, dophase_done);
2787 result = ssh_easy_statemach(conn, FALSE);
2788 *dophase_done = TRUE; /* with the easy interface we are done here */
2790 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2793 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2799 /* called from multi.c while DOing */
2800 static CURLcode scp_doing(struct connectdata *conn,
2804 result = ssh_multi_statemach(conn, dophase_done);
2807 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2813 * The DO function is generic for both protocols. There was previously two
2814 * separate ones but this way means less duplicated code.
2817 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2821 struct SessionHandle *data = conn->data;
2823 *done = FALSE; /* default to false */
2826 Since connections can be re-used between SessionHandles, this might be a
2827 connection already existing but on a fresh SessionHandle struct so we must
2828 make sure we have a good 'struct SSHPROTO' to play with. For new
2829 connections, the struct SSHPROTO is allocated and setup in the
2830 ssh_connect() function.
2832 Curl_reset_reqproto(conn);
2833 res = ssh_init(conn);
2837 data->req.size = -1; /* make sure this is unknown at this point */
2839 Curl_pgrsSetUploadCounter(data, 0);
2840 Curl_pgrsSetDownloadCounter(data, 0);
2841 Curl_pgrsSetUploadSize(data, 0);
2842 Curl_pgrsSetDownloadSize(data, 0);
2844 if(conn->handler->protocol & CURLPROTO_SCP)
2845 res = scp_perform(conn, &connected, done);
2847 res = sftp_perform(conn, &connected, done);
2852 /* BLOCKING, but the function is using the state machine so the only reason
2853 this is still blocking is that the multi interface code has no support for
2854 disconnecting operations that takes a while */
2855 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2857 CURLcode result = CURLE_OK;
2858 struct ssh_conn *ssh = &conn->proto.sshc;
2859 (void) dead_connection;
2861 Curl_safefree(conn->data->state.proto.ssh);
2862 conn->data->state.proto.ssh = NULL;
2864 if(ssh->ssh_session) {
2865 /* only if there's a session still around to use! */
2867 state(conn, SSH_SESSION_DISCONNECT);
2869 result = ssh_easy_statemach(conn, FALSE);
2875 /* generic done function for both SCP and SFTP called from their specific
2877 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2879 CURLcode result = CURLE_OK;
2880 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2882 if(status == CURLE_OK) {
2883 /* run the state-machine
2885 TODO: when the multi interface is used, this _really_ should be using
2886 the ssh_multi_statemach function but we have no general support for
2887 non-blocking DONE operations, not in the multi state machine and with
2888 Curl_done() invokes on several places in the code!
2890 result = ssh_easy_statemach(conn, FALSE);
2896 Curl_safefree(sftp_scp->path);
2897 sftp_scp->path = NULL;
2899 Curl_pgrsDone(conn);
2901 conn->data->req.keepon = 0; /* clear all bits */
2906 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2909 (void)premature; /* not used */
2911 if(status == CURLE_OK)
2912 state(conn, SSH_SCP_DONE);
2914 return ssh_done(conn, status);
2918 /* return number of received (decrypted) bytes */
2919 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2920 const void *mem, size_t len, CURLcode *err)
2923 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2925 /* libssh2_channel_write() returns int! */
2927 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2929 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2931 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2940 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2941 * a regular CURLcode value.
2943 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2944 char *mem, size_t len, CURLcode *err)
2947 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2949 /* libssh2_channel_read() returns int */
2951 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2953 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2954 if(nread == LIBSSH2_ERROR_EAGAIN) {
2963 * =============== SFTP ===============
2967 ***********************************************************************
2971 * This is the actual DO function for SFTP. Get a file/directory according to
2972 * the options previously setup.
2976 CURLcode sftp_perform(struct connectdata *conn,
2980 CURLcode result = CURLE_OK;
2982 DEBUGF(infof(conn->data, "DO phase starts\n"));
2984 *dophase_done = FALSE; /* not done yet */
2986 /* start the first command in the DO phase */
2987 state(conn, SSH_SFTP_QUOTE_INIT);
2989 /* run the state-machine */
2990 if(conn->data->state.used_interface == Curl_if_multi) {
2991 result = ssh_multi_statemach(conn, dophase_done);
2994 result = ssh_easy_statemach(conn, FALSE);
2995 *dophase_done = TRUE; /* with the easy interface we are done here */
2997 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3000 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3006 /* called from multi.c while DOing */
3007 static CURLcode sftp_doing(struct connectdata *conn,
3011 result = ssh_multi_statemach(conn, dophase_done);
3014 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3019 /* BLOCKING, but the function is using the state machine so the only reason
3020 this is still blocking is that the multi interface code has no support for
3021 disconnecting operations that takes a while */
3022 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
3024 CURLcode result = CURLE_OK;
3025 (void) dead_connection;
3027 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3029 Curl_safefree(conn->data->state.proto.ssh);
3030 conn->data->state.proto.ssh = NULL;
3032 if(conn->proto.sshc.ssh_session) {
3033 /* only if there's a session still around to use! */
3034 state(conn, SSH_SFTP_SHUTDOWN);
3035 result = ssh_easy_statemach(conn, FALSE);
3038 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3044 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3047 struct ssh_conn *sshc = &conn->proto.sshc;
3049 if(status == CURLE_OK) {
3050 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3051 errors that could happen due to open file handles during POSTQUOTE
3053 if(!status && !premature && conn->data->set.postquote) {
3054 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3055 state(conn, SSH_SFTP_CLOSE);
3058 state(conn, SSH_SFTP_CLOSE);
3060 return ssh_done(conn, status);
3063 /* return number of sent bytes */
3064 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3065 const void *mem, size_t len, CURLcode *err)
3067 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3068 but is changed to ssize_t in 0.15. These days we don't
3069 support libssh2 0.15*/
3072 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3074 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3076 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3085 * Return number of received (decrypted) bytes
3087 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3088 char *mem, size_t len, CURLcode *err)
3093 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3095 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3097 if(nread == LIBSSH2_ERROR_EAGAIN) {
3104 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3107 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3109 * Permission to use, copy, modify, and distribute this software for any
3110 * purpose with or without fee is hereby granted, provided that the above
3111 * copyright notice and this permission notice appear in all copies.
3113 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3114 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3115 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3116 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3117 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3118 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3119 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3122 get_pathname(const char **cpp, char **path)
3124 const char *cp = *cpp, *end;
3127 static const char WHITESPACE[] = " \t\r\n";
3129 cp += strspn(cp, WHITESPACE);
3133 return CURLE_QUOTE_ERROR;
3136 *path = malloc(strlen(cp) + 1);
3138 return CURLE_OUT_OF_MEMORY;
3140 /* Check for quoted filenames */
3141 if(*cp == '\"' || *cp == '\'') {
3144 /* Search for terminating quote, unescape some chars */
3145 for(i = j = 0; i <= strlen(cp); i++) {
3146 if(cp[i] == quot) { /* Found quote */
3151 if(cp[i] == '\0') { /* End of string */
3152 /*error("Unterminated quote");*/
3155 if(cp[i] == '\\') { /* Escaped characters */
3157 if(cp[i] != '\'' && cp[i] != '\"' &&
3159 /*error("Bad escaped character '\\%c'",
3164 (*path)[j++] = cp[i];
3168 /*error("Empty quotes");*/
3171 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3174 /* Read to end of filename */
3175 end = strpbrk(cp, WHITESPACE);
3177 end = strchr(cp, '\0');
3178 *cpp = end + strspn(end, WHITESPACE);
3180 memcpy(*path, cp, end - cp);
3181 (*path)[end - cp] = '\0';
3186 Curl_safefree(*path);
3188 return CURLE_QUOTE_ERROR;
3192 static const char *sftp_libssh2_strerror(unsigned long err)
3195 case LIBSSH2_FX_NO_SUCH_FILE:
3196 return "No such file or directory";
3198 case LIBSSH2_FX_PERMISSION_DENIED:
3199 return "Permission denied";
3201 case LIBSSH2_FX_FAILURE:
3202 return "Operation failed";
3204 case LIBSSH2_FX_BAD_MESSAGE:
3205 return "Bad message from SFTP server";
3207 case LIBSSH2_FX_NO_CONNECTION:
3208 return "Not connected to SFTP server";
3210 case LIBSSH2_FX_CONNECTION_LOST:
3211 return "Connection to SFTP server lost";
3213 case LIBSSH2_FX_OP_UNSUPPORTED:
3214 return "Operation not supported by SFTP server";
3216 case LIBSSH2_FX_INVALID_HANDLE:
3217 return "Invalid handle";
3219 case LIBSSH2_FX_NO_SUCH_PATH:
3220 return "No such file or directory";
3222 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3223 return "File already exists";
3225 case LIBSSH2_FX_WRITE_PROTECT:
3226 return "File is write protected";
3228 case LIBSSH2_FX_NO_MEDIA:
3231 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3234 case LIBSSH2_FX_QUOTA_EXCEEDED:
3235 return "User quota exceeded";
3237 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3238 return "Unknown principle";
3240 case LIBSSH2_FX_LOCK_CONFlICT:
3241 return "File lock conflict";
3243 case LIBSSH2_FX_DIR_NOT_EMPTY:
3244 return "Directory not empty";
3246 case LIBSSH2_FX_NOT_A_DIRECTORY:
3247 return "Not a directory";
3249 case LIBSSH2_FX_INVALID_FILENAME:
3250 return "Invalid filename";
3252 case LIBSSH2_FX_LINK_LOOP:
3253 return "Link points to itself";
3255 return "Unknown error in libssh2";
3258 #endif /* USE_LIBSSH2 */