1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2009, 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.
22 ***************************************************************************/
24 /* #define CURL_LIBSSH2_DEBUG */
39 #include <libssh2_sftp.h>
54 #ifdef HAVE_SYS_SOCKET_H
55 #include <sys/socket.h>
57 #ifdef HAVE_NETINET_IN_H
58 #include <netinet/in.h>
60 #ifdef HAVE_ARPA_INET_H
61 #include <arpa/inet.h>
64 #include <sys/utsname.h>
75 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
77 #define in_addr_t unsigned long
80 #include <curl/curl.h>
83 #include "easyif.h" /* for Curl_convert_... prototypes */
89 #include "http.h" /* for HTTP proxy tunnel stuff */
92 #include "speedcheck.h"
99 #include "inet_ntop.h"
100 #include "parsedate.h" /* for the week day and month names */
101 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
102 #include "strtoofft.h"
106 #define _MPRINTF_REPLACE /* use our functions only */
107 #include <curl/mprintf.h>
109 #include "curl_memory.h"
110 /* The last #include file should be: */
111 #include "memdebug.h"
114 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
115 have their definition hidden well */
118 /* Local functions: */
119 static const char *sftp_libssh2_strerror(unsigned long err);
120 static LIBSSH2_ALLOC_FUNC(libssh2_malloc);
121 static LIBSSH2_REALLOC_FUNC(libssh2_realloc);
122 static LIBSSH2_FREE_FUNC(libssh2_free);
124 static CURLcode get_pathname(const char **cpp, char **path);
126 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
127 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
128 static CURLcode ssh_do(struct connectdata *conn, bool *done);
130 static CURLcode ssh_getworkingpath(struct connectdata *conn,
131 char *homedir, /* when SFTP is used */
134 static CURLcode scp_done(struct connectdata *conn,
135 CURLcode, bool premature);
136 static CURLcode scp_doing(struct connectdata *conn,
138 static CURLcode scp_disconnect(struct connectdata *conn);
140 static CURLcode sftp_done(struct connectdata *conn,
141 CURLcode, bool premature);
142 static CURLcode sftp_doing(struct connectdata *conn,
144 static CURLcode sftp_disconnect(struct connectdata *conn);
146 CURLcode sftp_perform(struct connectdata *conn,
150 static int ssh_getsock(struct connectdata *conn,
151 curl_socket_t *sock, /* points to numsocks number
155 static int ssh_perform_getsock(const struct connectdata *conn,
156 curl_socket_t *sock, /* points to numsocks
161 * SCP protocol handler.
164 const struct Curl_handler Curl_handler_scp = {
166 ZERO_NULL, /* setup_connection */
169 ZERO_NULL, /* do_more */
170 ssh_connect, /* connect_it */
171 ssh_multi_statemach, /* connecting */
172 scp_doing, /* doing */
173 ssh_getsock, /* proto_getsock */
174 ssh_getsock, /* doing_getsock */
175 ssh_perform_getsock, /* perform_getsock */
176 scp_disconnect, /* disconnect */
177 PORT_SSH, /* defport */
178 PROT_SCP /* protocol */
183 * SFTP protocol handler.
186 const struct Curl_handler Curl_handler_sftp = {
188 ZERO_NULL, /* setup_connection */
190 sftp_done, /* done */
191 ZERO_NULL, /* do_more */
192 ssh_connect, /* connect_it */
193 ssh_multi_statemach, /* connecting */
194 sftp_doing, /* doing */
195 ssh_getsock, /* proto_getsock */
196 ssh_getsock, /* doing_getsock */
197 ssh_perform_getsock, /* perform_getsock */
198 sftp_disconnect, /* disconnect */
199 PORT_SSH, /* defport */
200 PROT_SFTP /* protocol */
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 = 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)
267 if(err == LIBSSH2_ERROR_ALLOC)
268 return CURLE_OUT_OF_MEMORY;
270 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
271 error code, and possibly add a few new SSH-related one. We must however
272 not return or even depend on libssh2 errors in the public libcurl API */
277 static LIBSSH2_ALLOC_FUNC(libssh2_malloc)
279 (void)abstract; /* arg not used */
280 return malloc(count);
283 static LIBSSH2_REALLOC_FUNC(libssh2_realloc)
285 (void)abstract; /* arg not used */
286 return realloc(ptr, count);
289 static LIBSSH2_FREE_FUNC(libssh2_free)
291 (void)abstract; /* arg not used */
296 * SSH State machine related code
298 /* This is the ONLY way to change SSH state! */
299 static void state(struct connectdata *conn, sshstate nowstate)
301 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
302 /* for debug purposes */
303 static const char * const names[] = {
308 "SSH_AUTH_PKEY_INIT",
310 "SSH_AUTH_PASS_INIT",
312 "SSH_AUTH_HOST_INIT",
319 "SSH_SFTP_QUOTE_INIT",
320 "SSH_SFTP_POSTQUOTE_INIT",
322 "SSH_SFTP_NEXT_QUOTE",
323 "SSH_SFTP_QUOTE_STAT",
324 "SSH_SFTP_QUOTE_SETSTAT",
325 "SSH_SFTP_QUOTE_SYMLINK",
326 "SSH_SFTP_QUOTE_MKDIR",
327 "SSH_SFTP_QUOTE_RENAME",
328 "SSH_SFTP_QUOTE_RMDIR",
329 "SSH_SFTP_QUOTE_UNLINK",
330 "SSH_SFTP_TRANS_INIT",
331 "SSH_SFTP_UPLOAD_INIT",
332 "SSH_SFTP_CREATE_DIRS_INIT",
333 "SSH_SFTP_CREATE_DIRS",
334 "SSH_SFTP_CREATE_DIRS_MKDIR",
335 "SSH_SFTP_READDIR_INIT",
337 "SSH_SFTP_READDIR_LINK",
338 "SSH_SFTP_READDIR_BOTTOM",
339 "SSH_SFTP_READDIR_DONE",
340 "SSH_SFTP_DOWNLOAD_INIT",
341 "SSH_SFTP_DOWNLOAD_STAT",
344 "SSH_SCP_TRANS_INIT",
345 "SSH_SCP_UPLOAD_INIT",
346 "SSH_SCP_DOWNLOAD_INIT",
350 "SSH_SCP_WAIT_CLOSE",
351 "SSH_SCP_CHANNEL_FREE",
352 "SSH_SESSION_DISCONNECT",
357 struct ssh_conn *sshc = &conn->proto.sshc;
359 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
360 if(sshc->state != nowstate) {
361 infof(conn->data, "SFTP %p state change from %s to %s\n",
362 sshc, names[sshc->state], names[nowstate]);
366 sshc->state = nowstate;
369 /* figure out the path to work with in this particular request */
370 static CURLcode ssh_getworkingpath(struct connectdata *conn,
371 char *homedir, /* when SFTP is used */
372 char **path) /* returns the allocated
373 real path to work with */
375 struct SessionHandle *data = conn->data;
376 char *real_path = NULL;
378 int working_path_len;
380 working_path = curl_easy_unescape(data, data->state.path, 0,
383 return CURLE_OUT_OF_MEMORY;
385 /* Check for /~/ , indicating relative to the user's home directory */
386 if(conn->protocol & PROT_SCP) {
387 real_path = malloc(working_path_len+1);
388 if(real_path == NULL) {
390 return CURLE_OUT_OF_MEMORY;
392 if((working_path_len > 1) && (working_path[1] == '~'))
393 /* It is referenced to the home directory, so strip the leading '/' */
394 memcpy(real_path, working_path+1, 1 + working_path_len-1);
396 memcpy(real_path, working_path, 1 + working_path_len);
398 else if(conn->protocol & PROT_SFTP) {
399 if((working_path_len > 1) && (working_path[1] == '~')) {
400 size_t homelen = strlen(homedir);
401 real_path = malloc(homelen + working_path_len + 1);
402 if(real_path == NULL) {
404 return CURLE_OUT_OF_MEMORY;
406 /* It is referenced to the home directory, so strip the
408 memcpy(real_path, homedir, homelen);
409 real_path[homelen] = '/';
410 real_path[homelen+1] = '\0';
411 if(working_path_len > 3) {
412 memcpy(real_path+homelen+1, working_path + 3,
413 1 + working_path_len -3);
417 real_path = malloc(working_path_len+1);
418 if(real_path == NULL) {
420 return CURLE_OUT_OF_MEMORY;
422 memcpy(real_path, working_path, 1+working_path_len);
428 /* store the pointer for the caller to receive */
434 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
435 static int sshkeycallback(CURL *easy,
436 const struct curl_khkey *knownkey, /* known */
437 const struct curl_khkey *foundkey, /* found */
438 enum curl_khmatch match,
446 /* we only allow perfect matches, and we reject everything else */
447 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
452 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
455 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
456 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
458 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
462 * ssh_statemach_act() runs the SSH statemachine "one round" and returns. The
463 * data the pointer 'block' points to will be set to TRUE if the libssh2
464 * function returns LIBSSH2_ERROR_EAGAIN meaning it wants to be called again
465 * when the socket is ready
468 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
470 CURLcode result = CURLE_OK;
471 struct SessionHandle *data = conn->data;
472 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
473 struct ssh_conn *sshc = &conn->proto.sshc;
474 curl_socket_t sock = conn->sock[FIRSTSOCKET];
475 #ifdef CURL_LIBSSH2_DEBUG
476 const char *fingerprint;
477 #endif /* CURL_LIBSSH2_DEBUG */
478 const char *host_public_key_md5;
479 int rc = LIBSSH2_ERROR_NONE, i;
481 int seekerr = CURL_SEEKFUNC_OK;
482 *block = 0; /* we're not blocking by default */
484 switch(sshc->state) {
486 sshc->secondCreateDirs = 0;
487 sshc->nextstate = SSH_NO_STATE;
488 sshc->actualcode = CURLE_OK;
490 rc = libssh2_session_startup(sshc->ssh_session, sock);
491 if(rc == LIBSSH2_ERROR_EAGAIN) {
495 failf(data, "Failure establishing ssh session");
496 state(conn, SSH_SESSION_FREE);
497 sshc->actualcode = CURLE_FAILED_INIT;
501 /* Set libssh2 to non-blocking, since everything internally is
503 libssh2_session_set_blocking(sshc->ssh_session, 0);
505 state(conn, SSH_HOSTKEY);
510 #ifdef CURL_LIBSSH2_DEBUG
512 * Before we authenticate we should check the hostkey's fingerprint
513 * against our known hosts. How that is handled (reading from file,
514 * whatever) is up to us. As for know not much is implemented, besides
515 * showing how to get the fingerprint.
517 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
518 LIBSSH2_HOSTKEY_HASH_MD5);
520 /* The fingerprint points to static storage (!), don't free() it. */
521 infof(data, "Fingerprint: ");
522 for (rc = 0; rc < 16; rc++) {
523 infof(data, "%02X ", (unsigned char) fingerprint[rc]);
526 #endif /* CURL_LIBSSH2_DEBUG */
528 /* Before we authenticate we check the hostkey's MD5 fingerprint
529 * against a known fingerprint, if available. This implementation pulls
530 * it from the curl option.
532 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
533 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
535 host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
536 LIBSSH2_HOSTKEY_HASH_MD5);
537 for (i = 0; i < 16; i++)
538 snprintf(&buf[i*2], 3, "%02x",
539 (unsigned char) host_public_key_md5[i]);
540 if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
542 "Denied establishing ssh session: mismatch md5 fingerprint. "
543 "Remote %s is not equal to %s",
544 buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
545 state(conn, SSH_SESSION_FREE);
546 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
551 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
552 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
553 /* we're asked to verify the host against a file */
556 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
563 * A subject to figure out is what host name we need to pass in here.
564 * What host name does OpenSSH store in its file if an IDN name is
567 struct libssh2_knownhost *host;
568 enum curl_khmatch keymatch;
569 curl_sshkeycallback func =
570 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
571 struct curl_khkey knownkey;
572 struct curl_khkey *knownkeyp = NULL;
573 struct curl_khkey foundkey;
575 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
576 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
578 keycheck = libssh2_knownhost_check(sshc->kh,
581 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
582 LIBSSH2_KNOWNHOST_KEYENC_RAW|
586 infof(data, "SSH host check: %d, key: %s\n", keycheck,
587 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
590 /* setup 'knownkey' */
591 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
592 knownkey.key = host->key;
594 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
595 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
596 knownkeyp = &knownkey;
599 /* setup 'foundkey' */
600 foundkey.key = remotekey;
601 foundkey.len = keylen;
602 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
603 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
606 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
607 * curl_khmatch enum are ever modified, we need to introduce a
608 * translation table here!
610 keymatch = (enum curl_khmatch)keycheck;
612 /* Ask the callback how to behave */
613 rc = func(data, knownkeyp, /* from the knownhosts file */
614 &foundkey, /* from the remote host */
615 keymatch, data->set.ssh_keyfunc_userp);
618 /* no remotekey means failure! */
619 rc = CURLKHSTAT_REJECT;
622 default: /* unknown return codes will equal reject */
623 case CURLKHSTAT_REJECT:
624 state(conn, SSH_SESSION_FREE);
625 case CURLKHSTAT_DEFER:
626 /* DEFER means bail out but keep the SSH_HOSTKEY state */
627 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
629 case CURLKHSTAT_FINE:
630 case CURLKHSTAT_FINE_ADD_TO_FILE:
632 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
633 /* the found host+key didn't match but has been told to be fine
634 anyway so we add it in memory */
635 int addrc = libssh2_knownhost_add(sshc->kh,
636 conn->host.name, NULL,
638 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
639 LIBSSH2_KNOWNHOST_KEYENC_RAW|
642 infof(data, "Warning adding the known host %s failed!\n",
644 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
645 /* now we write the entire in-memory list of known hosts to the
648 libssh2_knownhost_writefile(sshc->kh,
649 data->set.str[STRING_SSH_KNOWNHOSTS],
650 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
652 infof(data, "Warning, writing %s failed!\n",
653 data->set.str[STRING_SSH_KNOWNHOSTS]);
660 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
662 state(conn, SSH_AUTHLIST);
667 * Figure out authentication methods
668 * NB: As soon as we have provided a username to an openssh server we
669 * must never change it later. Thus, always specify the correct username
670 * here, even though the libssh2 docs kind of indicate that it should be
671 * possible to get a 'generic' list (not user-specific) of authentication
672 * methods, presumably with a blank username. That won't work in my
674 * So always specify it here.
676 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
680 if(!sshc->authlist) {
681 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
682 LIBSSH2_ERROR_EAGAIN) {
683 rc = LIBSSH2_ERROR_EAGAIN;
687 state(conn, SSH_SESSION_FREE);
688 sshc->actualcode = libssh2_session_error_to_CURLE(err);
692 infof(data, "SSH authentication methods available: %s\n", sshc->authlist);
694 state(conn, SSH_AUTH_PKEY_INIT);
697 case SSH_AUTH_PKEY_INIT:
699 * Check the supported auth types in the order I feel is most secure
700 * with the requested type of authentication
702 sshc->authed = FALSE;
704 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
705 (strstr(sshc->authlist, "publickey") != NULL)) {
708 sshc->rsa_pub = sshc->rsa = NULL;
710 /* To ponder about: should really the lib be messing about with the
711 HOME environment variable etc? */
712 home = curl_getenv("HOME");
714 if(data->set.str[STRING_SSH_PUBLIC_KEY])
715 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
717 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
719 /* as a final resort, try current dir! */
720 sshc->rsa_pub = strdup("id_dsa.pub");
722 if(sshc->rsa_pub == NULL) {
725 state(conn, SSH_SESSION_FREE);
726 sshc->actualcode = CURLE_OUT_OF_MEMORY;
730 if(data->set.str[STRING_SSH_PRIVATE_KEY])
731 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
733 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
735 /* as a final resort, try current dir! */
736 sshc->rsa = strdup("id_dsa");
738 if(sshc->rsa == NULL) {
741 Curl_safefree(sshc->rsa_pub);
742 sshc->rsa_pub = NULL;
743 state(conn, SSH_SESSION_FREE);
744 sshc->actualcode = CURLE_OUT_OF_MEMORY;
748 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
749 if(!sshc->passphrase)
750 sshc->passphrase = "";
755 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
756 infof(data, "Using ssh private key file %s\n", sshc->rsa);
758 state(conn, SSH_AUTH_PKEY);
761 state(conn, SSH_AUTH_PASS_INIT);
766 /* The function below checks if the files exists, no need to stat() here.
768 rc = libssh2_userauth_publickey_fromfile(sshc->ssh_session,
769 conn->user, sshc->rsa_pub,
770 sshc->rsa, sshc->passphrase);
771 if(rc == LIBSSH2_ERROR_EAGAIN) {
775 Curl_safefree(sshc->rsa_pub);
776 sshc->rsa_pub = NULL;
777 Curl_safefree(sshc->rsa);
782 infof(data, "Initialized SSH public key authentication\n");
783 state(conn, SSH_AUTH_DONE);
787 (void)libssh2_session_last_error(sshc->ssh_session,
789 infof(data, "SSH public key authentication failed: %s\n", err_msg);
790 state(conn, SSH_AUTH_PASS_INIT);
794 case SSH_AUTH_PASS_INIT:
795 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
796 (strstr(sshc->authlist, "password") != NULL)) {
797 state(conn, SSH_AUTH_PASS);
800 state(conn, SSH_AUTH_HOST_INIT);
805 rc = libssh2_userauth_password(sshc->ssh_session, conn->user,
807 if(rc == LIBSSH2_ERROR_EAGAIN) {
812 infof(data, "Initialized password authentication\n");
813 state(conn, SSH_AUTH_DONE);
816 state(conn, SSH_AUTH_HOST_INIT);
820 case SSH_AUTH_HOST_INIT:
821 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
822 (strstr(sshc->authlist, "hostbased") != NULL)) {
823 state(conn, SSH_AUTH_HOST);
826 state(conn, SSH_AUTH_KEY_INIT);
831 state(conn, SSH_AUTH_KEY_INIT);
834 case SSH_AUTH_KEY_INIT:
835 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
836 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
837 state(conn, SSH_AUTH_KEY);
840 state(conn, SSH_AUTH_DONE);
845 /* Authentication failed. Continue with keyboard-interactive now. */
846 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
850 if(rc == LIBSSH2_ERROR_EAGAIN) {
855 infof(data, "Initialized keyboard interactive authentication\n");
857 state(conn, SSH_AUTH_DONE);
862 failf(data, "Authentication failure");
863 state(conn, SSH_SESSION_FREE);
864 sshc->actualcode = CURLE_LOGIN_DENIED;
869 * At this point we have an authenticated ssh session.
871 infof(data, "Authentication complete\n");
873 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
876 conn->writesockfd = CURL_SOCKET_BAD;
878 if(conn->protocol == PROT_SFTP) {
879 state(conn, SSH_SFTP_INIT);
882 infof(data, "SSH CONNECT phase done\n");
883 state(conn, SSH_STOP);
888 * Start the libssh2 sftp session
890 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
891 if(!sshc->sftp_session) {
892 if(libssh2_session_last_errno(sshc->ssh_session) ==
893 LIBSSH2_ERROR_EAGAIN) {
894 rc = LIBSSH2_ERROR_EAGAIN;
900 (void)libssh2_session_last_error(sshc->ssh_session,
902 failf(data, "Failure initializing sftp session: %s", err_msg);
903 state(conn, SSH_SESSION_FREE);
904 sshc->actualcode = CURLE_FAILED_INIT;
908 state(conn, SSH_SFTP_REALPATH);
911 case SSH_SFTP_REALPATH:
913 char tempHome[PATH_MAX];
916 * Get the "home" directory
918 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
919 tempHome, PATH_MAX-1);
920 if(rc == LIBSSH2_ERROR_EAGAIN) {
924 /* It seems that this string is not always NULL terminated */
926 sshc->homedir = strdup(tempHome);
928 state(conn, SSH_SFTP_CLOSE);
929 sshc->actualcode = CURLE_OUT_OF_MEMORY;
934 /* Return the error type */
935 err = libssh2_sftp_last_error(sshc->sftp_session);
936 result = sftp_libssh2_error_to_CURLE(err);
937 sshc->actualcode = result?result:CURLE_SSH;
938 DEBUGF(infof(data, "error = %d makes libcurl = %d\n", err, result));
939 state(conn, SSH_STOP);
943 /* This is the last step in the SFTP connect phase. Do note that while
944 we get the homedir here, we get the "workingpath" in the DO action
945 since the homedir will remain the same between request but the
946 working path will not. */
947 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
948 state(conn, SSH_STOP);
951 case SSH_SFTP_QUOTE_INIT:
953 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
955 sshc->actualcode = result;
956 state(conn, SSH_STOP);
960 if(data->set.quote) {
961 infof(data, "Sending quote commands\n");
962 sshc->quote_item = data->set.quote;
963 state(conn, SSH_SFTP_QUOTE);
966 state(conn, SSH_SFTP_TRANS_INIT);
970 case SSH_SFTP_POSTQUOTE_INIT:
971 if(data->set.postquote) {
972 infof(data, "Sending quote commands\n");
973 sshc->quote_item = data->set.postquote;
974 state(conn, SSH_SFTP_QUOTE);
977 state(conn, SSH_STOP);
982 /* Send any quote commands */
987 * Support some of the "FTP" commands
989 if(curl_strequal("pwd", sshc->quote_item->data)) {
990 /* output debug output if that is requested */
991 if(data->set.verbose) {
992 char tmp[PATH_MAX+1];
994 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
995 snprintf(tmp, PATH_MAX, "257 \"%s\" is current directory.\n",
997 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
999 state(conn, SSH_SFTP_NEXT_QUOTE);
1002 else if(sshc->quote_item->data) {
1004 * the arguments following the command must be separated from the
1005 * command with a space so we can check for it unconditionally
1007 cp = strchr(sshc->quote_item->data, ' ');
1009 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1010 state(conn, SSH_SFTP_CLOSE);
1011 sshc->actualcode = CURLE_QUOTE_ERROR;
1016 * also, every command takes at least one argument so we get that
1017 * first argument right now
1019 result = get_pathname(&cp, &sshc->quote_path1);
1021 if(result == CURLE_OUT_OF_MEMORY)
1022 failf(data, "Out of memory");
1024 failf(data, "Syntax error: Bad first parameter");
1025 state(conn, SSH_SFTP_CLOSE);
1026 sshc->actualcode = result;
1031 * SFTP is a binary protocol, so we don't send text commands to
1032 * the server. Instead, we scan for commands for commands used by
1033 * OpenSSH's sftp program and call the appropriate libssh2
1036 if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
1037 curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
1038 curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
1039 /* attribute change */
1041 /* sshc->quote_path1 contains the mode to set */
1042 /* get the destination */
1043 result = get_pathname(&cp, &sshc->quote_path2);
1045 if(result == CURLE_OUT_OF_MEMORY)
1046 failf(data, "Out of memory");
1048 failf(data, "Syntax error in chgrp/chmod/chown: "
1049 "Bad second parameter");
1050 Curl_safefree(sshc->quote_path1);
1051 sshc->quote_path1 = NULL;
1052 state(conn, SSH_SFTP_CLOSE);
1053 sshc->actualcode = result;
1056 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1057 state(conn, SSH_SFTP_QUOTE_STAT);
1060 else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
1061 curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
1062 /* symbolic linking */
1063 /* sshc->quote_path1 is the source */
1064 /* get the destination */
1065 result = get_pathname(&cp, &sshc->quote_path2);
1067 if(result == CURLE_OUT_OF_MEMORY)
1068 failf(data, "Out of memory");
1071 "Syntax error in ln/symlink: Bad second parameter");
1072 Curl_safefree(sshc->quote_path1);
1073 sshc->quote_path1 = NULL;
1074 state(conn, SSH_SFTP_CLOSE);
1075 sshc->actualcode = result;
1078 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1081 else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
1083 state(conn, SSH_SFTP_QUOTE_MKDIR);
1086 else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
1088 /* first param is the source path */
1089 /* second param is the dest. path */
1090 result = get_pathname(&cp, &sshc->quote_path2);
1092 if(result == CURLE_OUT_OF_MEMORY)
1093 failf(data, "Out of memory");
1095 failf(data, "Syntax error in rename: Bad second parameter");
1096 Curl_safefree(sshc->quote_path1);
1097 sshc->quote_path1 = NULL;
1098 state(conn, SSH_SFTP_CLOSE);
1099 sshc->actualcode = result;
1102 state(conn, SSH_SFTP_QUOTE_RENAME);
1105 else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
1107 state(conn, SSH_SFTP_QUOTE_RMDIR);
1110 else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
1111 state(conn, SSH_SFTP_QUOTE_UNLINK);
1115 failf(data, "Unknown SFTP command");
1116 Curl_safefree(sshc->quote_path1);
1117 sshc->quote_path1 = NULL;
1118 Curl_safefree(sshc->quote_path2);
1119 sshc->quote_path2 = NULL;
1120 state(conn, SSH_SFTP_CLOSE);
1121 sshc->actualcode = CURLE_QUOTE_ERROR;
1125 if(!sshc->quote_item) {
1126 state(conn, SSH_SFTP_TRANS_INIT);
1130 case SSH_SFTP_NEXT_QUOTE:
1131 if(sshc->quote_path1) {
1132 Curl_safefree(sshc->quote_path1);
1133 sshc->quote_path1 = NULL;
1135 if(sshc->quote_path2) {
1136 Curl_safefree(sshc->quote_path2);
1137 sshc->quote_path2 = NULL;
1140 sshc->quote_item = sshc->quote_item->next;
1142 if(sshc->quote_item) {
1143 state(conn, SSH_SFTP_QUOTE);
1146 if(sshc->nextstate != SSH_NO_STATE) {
1147 state(conn, sshc->nextstate);
1148 sshc->nextstate = SSH_NO_STATE;
1151 state(conn, SSH_SFTP_TRANS_INIT);
1156 case SSH_SFTP_QUOTE_STAT:
1157 if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1158 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1159 * set them both at once, we need to obtain the current ownership first.
1160 * This takes an extra protocol round trip.
1162 rc = libssh2_sftp_stat(sshc->sftp_session, sshc->quote_path2,
1163 &sshc->quote_attrs);
1164 if(rc == LIBSSH2_ERROR_EAGAIN) {
1167 else if(rc != 0) { /* get those attributes */
1168 err = libssh2_sftp_last_error(sshc->sftp_session);
1169 Curl_safefree(sshc->quote_path1);
1170 sshc->quote_path1 = NULL;
1171 Curl_safefree(sshc->quote_path2);
1172 sshc->quote_path2 = NULL;
1173 failf(data, "Attempt to get SFTP stats failed: %s",
1174 sftp_libssh2_strerror(err));
1175 state(conn, SSH_SFTP_CLOSE);
1176 sshc->actualcode = CURLE_QUOTE_ERROR;
1181 /* Now set the new attributes... */
1182 if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
1183 sshc->quote_attrs.gid = strtol(sshc->quote_path1, NULL, 10);
1184 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1185 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1186 Curl_safefree(sshc->quote_path1);
1187 sshc->quote_path1 = NULL;
1188 Curl_safefree(sshc->quote_path2);
1189 sshc->quote_path2 = NULL;
1190 failf(data, "Syntax error: chgrp gid not a number");
1191 state(conn, SSH_SFTP_CLOSE);
1192 sshc->actualcode = CURLE_QUOTE_ERROR;
1196 else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1197 sshc->quote_attrs.permissions = strtol(sshc->quote_path1, NULL, 8);
1198 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1199 /* permissions are octal */
1200 if(sshc->quote_attrs.permissions == 0 &&
1201 !ISDIGIT(sshc->quote_path1[0])) {
1202 Curl_safefree(sshc->quote_path1);
1203 sshc->quote_path1 = NULL;
1204 Curl_safefree(sshc->quote_path2);
1205 sshc->quote_path2 = NULL;
1206 failf(data, "Syntax error: chmod permissions not a number");
1207 state(conn, SSH_SFTP_CLOSE);
1208 sshc->actualcode = CURLE_QUOTE_ERROR;
1212 else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
1213 sshc->quote_attrs.uid = strtol(sshc->quote_path1, NULL, 10);
1214 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1215 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1216 Curl_safefree(sshc->quote_path1);
1217 sshc->quote_path1 = NULL;
1218 Curl_safefree(sshc->quote_path2);
1219 sshc->quote_path2 = NULL;
1220 failf(data, "Syntax error: chown uid not a number");
1221 state(conn, SSH_SFTP_CLOSE);
1222 sshc->actualcode = CURLE_QUOTE_ERROR;
1227 /* Now send the completed structure... */
1228 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1231 case SSH_SFTP_QUOTE_SETSTAT:
1232 rc = libssh2_sftp_setstat(sshc->sftp_session, sshc->quote_path2,
1233 &sshc->quote_attrs);
1234 if(rc == LIBSSH2_ERROR_EAGAIN) {
1238 err = libssh2_sftp_last_error(sshc->sftp_session);
1239 Curl_safefree(sshc->quote_path1);
1240 sshc->quote_path1 = NULL;
1241 Curl_safefree(sshc->quote_path2);
1242 sshc->quote_path2 = NULL;
1243 failf(data, "Attempt to set SFTP stats failed: %s",
1244 sftp_libssh2_strerror(err));
1245 state(conn, SSH_SFTP_CLOSE);
1246 sshc->actualcode = CURLE_QUOTE_ERROR;
1249 state(conn, SSH_SFTP_NEXT_QUOTE);
1252 case SSH_SFTP_QUOTE_SYMLINK:
1253 rc = libssh2_sftp_symlink(sshc->sftp_session, sshc->quote_path1,
1255 if(rc == LIBSSH2_ERROR_EAGAIN) {
1259 err = libssh2_sftp_last_error(sshc->sftp_session);
1260 Curl_safefree(sshc->quote_path1);
1261 sshc->quote_path1 = NULL;
1262 Curl_safefree(sshc->quote_path2);
1263 sshc->quote_path2 = NULL;
1264 failf(data, "symlink command failed: %s",
1265 sftp_libssh2_strerror(err));
1266 state(conn, SSH_SFTP_CLOSE);
1267 sshc->actualcode = CURLE_QUOTE_ERROR;
1270 state(conn, SSH_SFTP_NEXT_QUOTE);
1273 case SSH_SFTP_QUOTE_MKDIR:
1274 rc = libssh2_sftp_mkdir(sshc->sftp_session, sshc->quote_path1, 0755);
1275 if(rc == LIBSSH2_ERROR_EAGAIN) {
1279 err = libssh2_sftp_last_error(sshc->sftp_session);
1280 Curl_safefree(sshc->quote_path1);
1281 sshc->quote_path1 = NULL;
1282 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1283 state(conn, SSH_SFTP_CLOSE);
1284 sshc->actualcode = CURLE_QUOTE_ERROR;
1287 state(conn, SSH_SFTP_NEXT_QUOTE);
1290 case SSH_SFTP_QUOTE_RENAME:
1291 rc = libssh2_sftp_rename(sshc->sftp_session, sshc->quote_path1,
1293 if(rc == LIBSSH2_ERROR_EAGAIN) {
1297 err = libssh2_sftp_last_error(sshc->sftp_session);
1298 Curl_safefree(sshc->quote_path1);
1299 sshc->quote_path1 = NULL;
1300 Curl_safefree(sshc->quote_path2);
1301 sshc->quote_path2 = NULL;
1302 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1303 state(conn, SSH_SFTP_CLOSE);
1304 sshc->actualcode = CURLE_QUOTE_ERROR;
1307 state(conn, SSH_SFTP_NEXT_QUOTE);
1310 case SSH_SFTP_QUOTE_RMDIR:
1311 rc = libssh2_sftp_rmdir(sshc->sftp_session, sshc->quote_path1);
1312 if(rc == LIBSSH2_ERROR_EAGAIN) {
1316 err = libssh2_sftp_last_error(sshc->sftp_session);
1317 Curl_safefree(sshc->quote_path1);
1318 sshc->quote_path1 = NULL;
1319 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1320 state(conn, SSH_SFTP_CLOSE);
1321 sshc->actualcode = CURLE_QUOTE_ERROR;
1324 state(conn, SSH_SFTP_NEXT_QUOTE);
1327 case SSH_SFTP_QUOTE_UNLINK:
1328 rc = libssh2_sftp_unlink(sshc->sftp_session, sshc->quote_path1);
1329 if(rc == LIBSSH2_ERROR_EAGAIN) {
1333 err = libssh2_sftp_last_error(sshc->sftp_session);
1334 Curl_safefree(sshc->quote_path1);
1335 sshc->quote_path1 = NULL;
1336 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1337 state(conn, SSH_SFTP_CLOSE);
1338 sshc->actualcode = CURLE_QUOTE_ERROR;
1341 state(conn, SSH_SFTP_NEXT_QUOTE);
1344 case SSH_SFTP_TRANS_INIT:
1345 if(data->set.upload)
1346 state(conn, SSH_SFTP_UPLOAD_INIT);
1348 if(data->set.opt_no_body)
1349 state(conn, SSH_STOP);
1350 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1351 state(conn, SSH_SFTP_READDIR_INIT);
1353 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1357 case SSH_SFTP_UPLOAD_INIT:
1359 unsigned long flags;
1361 * NOTE!!! libssh2 requires that the destination path is a full path
1362 * that includes the destination file and name OR ends in a "/"
1363 * If this is not done the destination file will be named the
1364 * same name as the last directory in the path.
1367 if(data->state.resume_from != 0) {
1368 LIBSSH2_SFTP_ATTRIBUTES attrs;
1369 if(data->state.resume_from< 0) {
1370 rc = libssh2_sftp_stat(sshc->sftp_session, sftp_scp->path, &attrs);
1371 if(rc == LIBSSH2_ERROR_EAGAIN) {
1375 data->state.resume_from = 0;
1378 data->state.resume_from = attrs.filesize;
1383 if(data->set.ftp_append)
1384 /* Try to open for append, but create if nonexisting */
1385 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1386 else if (data->state.resume_from > 0)
1387 /* If we have restart position then open for append */
1388 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1390 /* Clear file before writing (normal behaviour) */
1391 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1394 libssh2_sftp_open(sshc->sftp_session, sftp_scp->path,
1395 flags, data->set.new_file_perms);
1397 if(!sshc->sftp_handle) {
1398 rc = libssh2_session_last_errno(sshc->ssh_session);
1400 if(LIBSSH2_ERROR_EAGAIN == rc)
1403 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1404 /* only when there was an SFTP protocol error can we extract
1406 err = libssh2_sftp_last_error(sshc->sftp_session);
1408 err = -1; /* not an sftp error at all */
1410 if(sshc->secondCreateDirs) {
1411 state(conn, SSH_SFTP_CLOSE);
1412 sshc->actualcode = err>= LIBSSH2_FX_OK?
1413 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1414 failf(data, "Creating the dir/file failed: %s",
1415 sftp_libssh2_strerror(err));
1418 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1419 (err == LIBSSH2_FX_FAILURE) ||
1420 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1421 (data->set.ftp_create_missing_dirs &&
1422 (strlen(sftp_scp->path) > 1))) {
1423 /* try to create the path remotely */
1424 sshc->secondCreateDirs = 1;
1425 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1428 state(conn, SSH_SFTP_CLOSE);
1429 sshc->actualcode = err>= LIBSSH2_FX_OK?
1430 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1431 if(!sshc->actualcode) {
1432 /* Sometimes, for some reason libssh2_sftp_last_error() returns zero
1433 even though libssh2_sftp_open() failed previously! We need to
1434 work around that! */
1435 sshc->actualcode = CURLE_SSH;
1438 failf(data, "Upload failed: %s (%d/%d)",
1439 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1445 /* If we have restart point then we need to seek to the correct position. */
1446 if(data->state.resume_from > 0) {
1447 /* Let's read off the proper amount of bytes from the input. */
1448 if(conn->seek_func) {
1449 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1453 if(seekerr != CURL_SEEKFUNC_OK){
1455 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1456 failf(data, "Could not seek stream");
1457 return CURLE_FTP_COULDNT_USE_REST;
1459 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1461 curl_off_t passed=0;
1462 curl_off_t readthisamountnow;
1463 curl_off_t actuallyread;
1465 readthisamountnow = (data->state.resume_from - passed);
1467 if(readthisamountnow > BUFSIZE)
1468 readthisamountnow = BUFSIZE;
1471 (curl_off_t) conn->fread_func(data->state.buffer, 1,
1472 (size_t)readthisamountnow,
1475 passed += actuallyread;
1476 if((actuallyread <= 0) || (actuallyread > readthisamountnow)) {
1477 /* this checks for greater-than only to make sure that the
1478 CURL_READFUNC_ABORT return code still aborts */
1479 failf(data, "Failed to read data");
1480 return CURLE_FTP_COULDNT_USE_REST;
1482 } while(passed < data->state.resume_from);
1486 /* now, decrease the size of the read */
1487 if(data->set.infilesize>0) {
1488 data->set.infilesize -= data->state.resume_from;
1489 data->req.size = data->set.infilesize;
1490 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1493 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1495 if(data->set.infilesize>0) {
1496 data->req.size = data->set.infilesize;
1497 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1500 result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL,
1503 /* not set by Curl_setup_transfer to preserve keepon bits */
1504 conn->sockfd = conn->writesockfd;
1507 state(conn, SSH_SFTP_CLOSE);
1508 sshc->actualcode = result;
1511 /* store this original bitmask setup to use later on if we can't figure
1512 out a "real" bitmask */
1513 sshc->orig_waitfor = data->req.keepon;
1515 state(conn, SSH_STOP);
1520 case SSH_SFTP_CREATE_DIRS_INIT:
1521 if(strlen(sftp_scp->path) > 1) {
1522 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1523 state(conn, SSH_SFTP_CREATE_DIRS);
1526 state(conn, SSH_SFTP_UPLOAD_INIT);
1530 case SSH_SFTP_CREATE_DIRS:
1531 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1532 *sshc->slash_pos = 0;
1534 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1535 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1539 state(conn, SSH_SFTP_UPLOAD_INIT);
1543 case SSH_SFTP_CREATE_DIRS_MKDIR:
1544 /* 'mode' - parameter is preliminary - default to 0644 */
1545 rc = libssh2_sftp_mkdir(sshc->sftp_session, sftp_scp->path,
1546 data->set.new_directory_perms);
1547 if(rc == LIBSSH2_ERROR_EAGAIN) {
1550 *sshc->slash_pos = '/';
1553 unsigned int sftp_err = 0;
1555 * abort if failure wasn't that the dir already exists or the
1556 * permission was denied (creation might succeed further
1557 * down the path) - retry on unspecific FAILURE also
1559 sftp_err = libssh2_sftp_last_error(sshc->sftp_session);
1560 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1561 (sftp_err != LIBSSH2_FX_FAILURE) &&
1562 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1563 result = sftp_libssh2_error_to_CURLE(sftp_err);
1564 state(conn, SSH_SFTP_CLOSE);
1565 sshc->actualcode = result?result:CURLE_SSH;
1569 state(conn, SSH_SFTP_CREATE_DIRS);
1572 case SSH_SFTP_READDIR_INIT:
1574 * This is a directory that we are trying to get, so produce a
1577 sshc->sftp_handle = libssh2_sftp_opendir(sshc->sftp_session,
1579 if(!sshc->sftp_handle) {
1580 if(libssh2_session_last_errno(sshc->ssh_session) ==
1581 LIBSSH2_ERROR_EAGAIN) {
1582 rc = LIBSSH2_ERROR_EAGAIN;
1586 err = libssh2_sftp_last_error(sshc->sftp_session);
1587 failf(data, "Could not open directory for reading: %s",
1588 sftp_libssh2_strerror(err));
1589 state(conn, SSH_SFTP_CLOSE);
1590 result = sftp_libssh2_error_to_CURLE(err);
1591 sshc->actualcode = result?result:CURLE_SSH;
1595 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1596 state(conn, SSH_SFTP_CLOSE);
1597 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1600 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1601 Curl_safefree(sshc->readdir_filename);
1602 sshc->readdir_filename = NULL;
1603 state(conn, SSH_SFTP_CLOSE);
1604 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1607 state(conn, SSH_SFTP_READDIR);
1610 case SSH_SFTP_READDIR:
1611 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1612 sshc->readdir_filename,
1614 sshc->readdir_longentry,
1616 &sshc->readdir_attrs);
1617 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1618 rc = LIBSSH2_ERROR_EAGAIN;
1621 if(sshc->readdir_len > 0) {
1622 sshc->readdir_filename[sshc->readdir_len] = '\0';
1624 if(data->set.ftp_list_only) {
1627 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1628 if(tmpLine == NULL) {
1629 state(conn, SSH_SFTP_CLOSE);
1630 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1633 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1634 tmpLine, sshc->readdir_len+1);
1635 Curl_safefree(tmpLine);
1638 state(conn, SSH_STOP);
1641 /* since this counts what we send to the client, we include the newline
1643 data->req.bytecount += sshc->readdir_len+1;
1645 /* output debug output if that is requested */
1646 if(data->set.verbose) {
1647 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1648 sshc->readdir_len, conn);
1652 sshc->readdir_currLen = strlen(sshc->readdir_longentry);
1653 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1654 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1655 if(!sshc->readdir_line) {
1656 Curl_safefree(sshc->readdir_filename);
1657 sshc->readdir_filename = NULL;
1658 Curl_safefree(sshc->readdir_longentry);
1659 sshc->readdir_longentry = NULL;
1660 state(conn, SSH_SFTP_CLOSE);
1661 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1665 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1666 sshc->readdir_currLen);
1667 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1668 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1669 LIBSSH2_SFTP_S_IFLNK)) {
1670 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1671 if(sshc->readdir_linkPath == NULL) {
1672 Curl_safefree(sshc->readdir_filename);
1673 sshc->readdir_filename = NULL;
1674 Curl_safefree(sshc->readdir_longentry);
1675 sshc->readdir_longentry = NULL;
1676 state(conn, SSH_SFTP_CLOSE);
1677 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1681 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1682 sshc->readdir_filename);
1683 state(conn, SSH_SFTP_READDIR_LINK);
1686 state(conn, SSH_SFTP_READDIR_BOTTOM);
1690 else if(sshc->readdir_len == 0) {
1691 Curl_safefree(sshc->readdir_filename);
1692 sshc->readdir_filename = NULL;
1693 Curl_safefree(sshc->readdir_longentry);
1694 sshc->readdir_longentry = NULL;
1695 state(conn, SSH_SFTP_READDIR_DONE);
1698 else if(sshc->readdir_len <= 0) {
1699 err = libssh2_sftp_last_error(sshc->sftp_session);
1700 result = sftp_libssh2_error_to_CURLE(err);
1701 sshc->actualcode = result?result:CURLE_SSH;
1702 failf(data, "Could not open remote file for reading: %s :: %d",
1703 sftp_libssh2_strerror(err),
1704 libssh2_session_last_errno(sshc->ssh_session));
1705 Curl_safefree(sshc->readdir_filename);
1706 sshc->readdir_filename = NULL;
1707 Curl_safefree(sshc->readdir_longentry);
1708 sshc->readdir_longentry = NULL;
1709 state(conn, SSH_SFTP_CLOSE);
1714 case SSH_SFTP_READDIR_LINK:
1715 sshc->readdir_len = libssh2_sftp_readlink(sshc->sftp_session,
1716 sshc->readdir_linkPath,
1717 sshc->readdir_filename,
1719 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1720 rc = LIBSSH2_ERROR_EAGAIN;
1723 Curl_safefree(sshc->readdir_linkPath);
1724 sshc->readdir_linkPath = NULL;
1725 sshc->readdir_line = realloc(sshc->readdir_line,
1726 sshc->readdir_totalLen + 4 +
1728 if(!sshc->readdir_line) {
1729 Curl_safefree(sshc->readdir_filename);
1730 sshc->readdir_filename = NULL;
1731 Curl_safefree(sshc->readdir_longentry);
1732 sshc->readdir_longentry = NULL;
1733 state(conn, SSH_SFTP_CLOSE);
1734 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1738 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1739 sshc->readdir_currLen,
1740 sshc->readdir_totalLen -
1741 sshc->readdir_currLen,
1743 sshc->readdir_filename);
1745 state(conn, SSH_SFTP_READDIR_BOTTOM);
1748 case SSH_SFTP_READDIR_BOTTOM:
1749 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1750 sshc->readdir_currLen,
1751 sshc->readdir_totalLen -
1752 sshc->readdir_currLen, "\n");
1753 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1755 sshc->readdir_currLen);
1757 if(result == CURLE_OK) {
1759 /* output debug output if that is requested */
1760 if(data->set.verbose) {
1761 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1762 sshc->readdir_currLen, conn);
1764 data->req.bytecount += sshc->readdir_currLen;
1766 Curl_safefree(sshc->readdir_line);
1767 sshc->readdir_line = NULL;
1769 state(conn, SSH_STOP);
1772 state(conn, SSH_SFTP_READDIR);
1775 case SSH_SFTP_READDIR_DONE:
1776 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1777 LIBSSH2_ERROR_EAGAIN) {
1778 rc = LIBSSH2_ERROR_EAGAIN;
1781 sshc->sftp_handle = NULL;
1782 Curl_safefree(sshc->readdir_filename);
1783 sshc->readdir_filename = NULL;
1784 Curl_safefree(sshc->readdir_longentry);
1785 sshc->readdir_longentry = NULL;
1787 /* no data to transfer */
1788 result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1789 state(conn, SSH_STOP);
1792 case SSH_SFTP_DOWNLOAD_INIT:
1794 * Work on getting the specified file
1797 libssh2_sftp_open(sshc->sftp_session, sftp_scp->path,
1798 LIBSSH2_FXF_READ, data->set.new_file_perms);
1799 if(!sshc->sftp_handle) {
1800 if(libssh2_session_last_errno(sshc->ssh_session) ==
1801 LIBSSH2_ERROR_EAGAIN) {
1802 rc = LIBSSH2_ERROR_EAGAIN;
1806 err = libssh2_sftp_last_error(sshc->sftp_session);
1807 failf(data, "Could not open remote file for reading: %s",
1808 sftp_libssh2_strerror(err));
1809 state(conn, SSH_SFTP_CLOSE);
1810 result = sftp_libssh2_error_to_CURLE(err);
1811 sshc->actualcode = result?result:CURLE_SSH;
1815 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1818 case SSH_SFTP_DOWNLOAD_STAT:
1820 LIBSSH2_SFTP_ATTRIBUTES attrs;
1822 rc = libssh2_sftp_stat(sshc->sftp_session, sftp_scp->path, &attrs);
1823 if(rc == LIBSSH2_ERROR_EAGAIN) {
1828 * libssh2_sftp_open() didn't return an error, so maybe the server
1829 * just doesn't support stat()
1831 data->req.size = -1;
1832 data->req.maxdownload = -1;
1837 size = attrs.filesize;
1838 if(conn->data->state.use_range) {
1839 curl_off_t from, to;
1843 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1844 while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-')))
1846 to=curlx_strtoofft(ptr, &ptr2, 0);
1847 if((ptr == ptr2) /* no "to" value given */
1852 /* from is relative to end of file */
1856 failf(data, "Offset (%"
1857 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1858 from, attrs.filesize);
1859 return CURLE_BAD_DOWNLOAD_RESUME;
1866 size = to - from + 1;
1869 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
1871 data->req.size = size;
1872 data->req.maxdownload = size;
1873 Curl_pgrsSetDownloadSize(data, size);
1876 /* We can resume if we can seek to the resume position */
1877 if(data->state.resume_from) {
1878 if(data->state.resume_from< 0) {
1879 /* We're supposed to download the last abs(from) bytes */
1880 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
1881 failf(data, "Offset (%"
1882 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1883 data->state.resume_from, attrs.filesize);
1884 return CURLE_BAD_DOWNLOAD_RESUME;
1886 /* download from where? */
1887 data->state.resume_from = attrs.filesize - data->state.resume_from;
1890 if((curl_off_t)attrs.filesize < data->state.resume_from) {
1891 failf(data, "Offset (%" FORMAT_OFF_T
1892 ") was beyond file size (%" FORMAT_OFF_T ")",
1893 data->state.resume_from, attrs.filesize);
1894 return CURLE_BAD_DOWNLOAD_RESUME;
1897 /* Does a completed file need to be seeked and started or closed ? */
1898 /* Now store the number of bytes we are expected to download */
1899 data->req.size = attrs.filesize - data->state.resume_from;
1900 data->req.maxdownload = attrs.filesize - data->state.resume_from;
1901 Curl_pgrsSetDownloadSize(data,
1902 attrs.filesize - data->state.resume_from);
1903 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1906 /* Setup the actual download */
1907 if(data->req.size == 0) {
1908 /* no data to transfer */
1909 result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1910 infof(data, "File already completely downloaded\n");
1911 state(conn, SSH_STOP);
1915 result = Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
1916 FALSE, NULL, -1, NULL);
1918 /* not set by Curl_setup_transfer to preserve keepon bits */
1919 conn->writesockfd = conn->sockfd;
1921 /* FIXME: here should be explained why we need it to start the download */
1922 conn->cselect_bits = CURL_CSELECT_IN;
1925 state(conn, SSH_SFTP_CLOSE);
1926 sshc->actualcode = result;
1929 state(conn, SSH_STOP);
1933 case SSH_SFTP_CLOSE:
1934 if(sshc->sftp_handle) {
1935 rc = libssh2_sftp_close(sshc->sftp_handle);
1936 if(rc == LIBSSH2_ERROR_EAGAIN) {
1940 infof(data, "Failed to close libssh2 file\n");
1942 sshc->sftp_handle = NULL;
1944 Curl_safefree(sftp_scp->path);
1945 sftp_scp->path = NULL;
1947 DEBUGF(infof(data, "SFTP DONE done\n"));
1949 state(conn, SSH_SFTP_SHUTDOWN);
1951 state(conn, SSH_STOP);
1952 result = sshc->actualcode;
1955 case SSH_SFTP_SHUTDOWN:
1956 /* during times we get here due to a broken transfer and then the
1957 sftp_handle might not have been taken down so make sure that is done
1958 before we proceed */
1960 if(sshc->sftp_handle) {
1961 rc = libssh2_sftp_close(sshc->sftp_handle);
1962 if(rc == LIBSSH2_ERROR_EAGAIN) {
1966 infof(data, "Failed to close libssh2 file\n");
1968 sshc->sftp_handle = NULL;
1970 if(sshc->sftp_session) {
1971 rc = libssh2_sftp_shutdown(sshc->sftp_session);
1972 if(rc == LIBSSH2_ERROR_EAGAIN) {
1976 infof(data, "Failed to stop libssh2 sftp subsystem\n");
1978 sshc->sftp_session = NULL;
1981 Curl_safefree(sshc->homedir);
1982 sshc->homedir = NULL;
1984 state(conn, SSH_SESSION_DISCONNECT);
1987 case SSH_SCP_TRANS_INIT:
1988 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1990 sshc->actualcode = result;
1991 state(conn, SSH_STOP);
1995 if(data->set.upload) {
1996 if(data->set.infilesize < 0) {
1997 failf(data, "SCP requires a known file size for upload");
1998 sshc->actualcode = CURLE_UPLOAD_FAILED;
1999 state(conn, SSH_SCP_CHANNEL_FREE);
2002 state(conn, SSH_SCP_UPLOAD_INIT);
2005 state(conn, SSH_SCP_DOWNLOAD_INIT);
2009 case SSH_SCP_UPLOAD_INIT:
2011 * libssh2 requires that the destination path is a full path that
2012 * includes the destination file and name OR ends in a "/" . If this is
2013 * not done the destination file will be named the same name as the last
2014 * directory in the path.
2017 libssh2_scp_send_ex(sshc->ssh_session, sftp_scp->path,
2018 data->set.new_file_perms,
2019 (size_t)data->set.infilesize, 0, 0);
2020 if(!sshc->ssh_channel) {
2021 if(libssh2_session_last_errno(sshc->ssh_session) ==
2022 LIBSSH2_ERROR_EAGAIN) {
2023 rc = LIBSSH2_ERROR_EAGAIN;
2030 ssh_err = libssh2_session_last_error(sshc->ssh_session,
2032 failf(conn->data, "%s", err_msg);
2033 state(conn, SSH_SCP_CHANNEL_FREE);
2034 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2040 result = Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2043 /* not set by Curl_setup_transfer to preserve keepon bits */
2044 conn->sockfd = conn->writesockfd;
2047 state(conn, SSH_SCP_CHANNEL_FREE);
2048 sshc->actualcode = result;
2051 state(conn, SSH_STOP);
2055 case SSH_SCP_DOWNLOAD_INIT:
2058 * We must check the remote file; if it is a directory no values will
2062 curl_off_t bytecount;
2064 /* clear the struct scp recv will fill in */
2065 memset(&sb, 0, sizeof(struct stat));
2067 /* get a fresh new channel from the ssh layer */
2068 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2069 sftp_scp->path, &sb);
2070 if(!sshc->ssh_channel) {
2071 if(libssh2_session_last_errno(sshc->ssh_session) ==
2072 LIBSSH2_ERROR_EAGAIN) {
2073 rc = LIBSSH2_ERROR_EAGAIN;
2080 ssh_err = libssh2_session_last_error(sshc->ssh_session,
2082 failf(conn->data, "%s", err_msg);
2083 state(conn, SSH_SCP_CHANNEL_FREE);
2084 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2090 bytecount = (curl_off_t)sb.st_size;
2091 data->req.maxdownload = (curl_off_t)sb.st_size;
2092 result = Curl_setup_transfer(conn, FIRSTSOCKET,
2093 bytecount, FALSE, NULL, -1, NULL);
2095 /* not set by Curl_setup_transfer to preserve keepon bits */
2096 conn->writesockfd = conn->sockfd;
2098 /* FIXME: here should be explained why we need it to start the download */
2099 conn->cselect_bits = CURL_CSELECT_IN;
2102 state(conn, SSH_SCP_CHANNEL_FREE);
2103 sshc->actualcode = result;
2106 state(conn, SSH_STOP);
2111 if(data->set.upload)
2112 state(conn, SSH_SCP_SEND_EOF);
2114 state(conn, SSH_SCP_CHANNEL_FREE);
2117 case SSH_SCP_SEND_EOF:
2118 if(sshc->ssh_channel) {
2119 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2120 if(rc == LIBSSH2_ERROR_EAGAIN) {
2124 infof(data, "Failed to send libssh2 channel EOF\n");
2127 state(conn, SSH_SCP_WAIT_EOF);
2130 case SSH_SCP_WAIT_EOF:
2131 if(sshc->ssh_channel) {
2132 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2133 if(rc == LIBSSH2_ERROR_EAGAIN) {
2137 infof(data, "Failed to get channel EOF: %d\n", rc);
2140 state(conn, SSH_SCP_WAIT_CLOSE);
2143 case SSH_SCP_WAIT_CLOSE:
2144 if(sshc->ssh_channel) {
2145 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2146 if(rc == LIBSSH2_ERROR_EAGAIN) {
2150 infof(data, "Channel failed to close: %d\n", rc);
2153 state(conn, SSH_SCP_CHANNEL_FREE);
2156 case SSH_SCP_CHANNEL_FREE:
2157 if(sshc->ssh_channel) {
2158 rc = libssh2_channel_free(sshc->ssh_channel);
2159 if(rc == LIBSSH2_ERROR_EAGAIN) {
2163 infof(data, "Failed to free libssh2 scp subsystem\n");
2165 sshc->ssh_channel = NULL;
2167 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2169 state(conn, SSH_SESSION_DISCONNECT);
2171 state(conn, SSH_STOP);
2172 result = sshc->actualcode;
2175 case SSH_SESSION_DISCONNECT:
2176 /* during weird times when we've been prematurely aborted, the channel
2177 is still alive when we reach this state and we MUST kill the channel
2179 if(sshc->ssh_channel) {
2180 rc = libssh2_channel_free(sshc->ssh_channel);
2181 if(rc == LIBSSH2_ERROR_EAGAIN) {
2185 infof(data, "Failed to free libssh2 scp subsystem\n");
2187 sshc->ssh_channel = NULL;
2190 if(sshc->ssh_session) {
2191 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2192 if(rc == LIBSSH2_ERROR_EAGAIN) {
2196 infof(data, "Failed to disconnect libssh2 session\n");
2200 Curl_safefree(sshc->homedir);
2201 sshc->homedir = NULL;
2203 state(conn, SSH_SESSION_FREE);
2206 case SSH_SESSION_FREE:
2207 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2209 libssh2_knownhost_free(sshc->kh);
2214 if(sshc->ssh_session) {
2215 rc = libssh2_session_free(sshc->ssh_session);
2216 if(rc == LIBSSH2_ERROR_EAGAIN) {
2220 infof(data, "Failed to free libssh2 session\n");
2222 sshc->ssh_session = NULL;
2224 conn->bits.close = TRUE;
2225 sshc->nextstate = SSH_NO_STATE;
2226 state(conn, SSH_STOP);
2227 result = sshc->actualcode;
2231 /* fallthrough, just stop! */
2233 /* internal error */
2234 sshc->nextstate = SSH_NO_STATE;
2235 state(conn, SSH_STOP);
2239 if(rc == LIBSSH2_ERROR_EAGAIN) {
2240 /* we would block, we need to wait for the socket to be ready (in the
2241 right direction too)! */
2248 /* called by the multi interface to figure out what socket(s) to wait for and
2249 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2250 static int ssh_perform_getsock(const struct connectdata *conn,
2251 curl_socket_t *sock, /* points to numsocks
2252 number of sockets */
2255 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2256 int bitmap = GETSOCK_BLANK;
2259 sock[0] = conn->sock[FIRSTSOCKET];
2261 if(conn->waitfor & KEEP_RECV)
2262 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2264 if(conn->waitfor & KEEP_SEND)
2265 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2269 /* if we don't know the direction we can use the generic *_getsock()
2270 function even for the protocol_connect and doing states */
2271 return Curl_single_getsock(conn, sock, numsocks);
2275 /* Generic function called by the multi interface to figure out what socket(s)
2276 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2277 static int ssh_getsock(struct connectdata *conn,
2278 curl_socket_t *sock, /* points to numsocks number
2282 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2286 /* if we don't know any direction we can just play along as we used to and
2287 not provide any sensible info */
2288 return GETSOCK_BLANK;
2290 /* if we know the direction we can use the generic *_getsock() function even
2291 for the protocol_connect and doing states */
2292 return ssh_perform_getsock(conn, sock, numsocks);
2296 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2298 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2299 * function is used to figure out in what direction and stores this info so
2300 * that the multi interface can take advantage of it. Make sure to call this
2301 * function in all cases so that when it _doesn't_ return EAGAIN we can
2302 * restore the default wait bits.
2304 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2306 struct ssh_conn *sshc = &conn->proto.sshc;
2310 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2311 /* translate the libssh2 define bits into our own bit defines */
2312 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2313 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2316 /* It didn't block or libssh2 didn't reveal in which direction, put back
2318 conn->waitfor = sshc->orig_waitfor;
2321 /* no libssh2 directional support so we simply don't know */
2322 #define ssh_block2waitfor(x,y)
2325 /* called repeatedly until done from multi.c */
2326 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2328 struct ssh_conn *sshc = &conn->proto.sshc;
2329 CURLcode result = CURLE_OK;
2330 bool block; /* we store the status and use that to provide a ssh_getsock()
2333 result = ssh_statemach_act(conn, &block);
2334 *done = (bool)(sshc->state == SSH_STOP);
2335 ssh_block2waitfor(conn, block);
2340 static CURLcode ssh_easy_statemach(struct connectdata *conn)
2342 struct ssh_conn *sshc = &conn->proto.sshc;
2343 CURLcode result = CURLE_OK;
2345 while((sshc->state != SSH_STOP) && !result) {
2347 result = ssh_statemach_act(conn, &block);
2349 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2350 if((CURLE_OK == result) && block) {
2351 int dir = libssh2_session_block_directions(sshc->ssh_session);
2352 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2353 curl_socket_t fd_read = CURL_SOCKET_BAD;
2354 curl_socket_t fd_write = CURL_SOCKET_BAD;
2355 if (LIBSSH2_SESSION_BLOCK_INBOUND & dir) {
2358 if (LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) {
2361 /* wait for the socket to become ready */
2362 Curl_socket_ready(fd_read, fd_write, 1000); /* ignore result */
2372 * SSH setup and connection
2374 static CURLcode ssh_init(struct connectdata *conn)
2376 struct SessionHandle *data = conn->data;
2377 struct SSHPROTO *ssh;
2378 struct ssh_conn *sshc = &conn->proto.sshc;
2380 sshc->actualcode = CURLE_OK; /* reset error code */
2381 sshc->secondCreateDirs =0; /* reset the create dir attempt state variable */
2383 if(data->state.proto.ssh)
2386 ssh = calloc(1, sizeof(struct SSHPROTO));
2388 return CURLE_OUT_OF_MEMORY;
2390 data->state.proto.ssh = ssh;
2396 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2397 * do protocol-specific actions at connect-time.
2399 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2401 #ifdef CURL_LIBSSH2_DEBUG
2404 struct ssh_conn *ssh;
2406 struct SessionHandle *data = conn->data;
2408 /* We default to persistent connections. We set this already in this connect
2409 function to make the re-use checks properly be able to check this bit. */
2410 conn->bits.close = FALSE;
2412 /* If there already is a protocol-specific struct allocated for this
2413 sessionhandle, deal with it */
2414 Curl_reset_reqproto(conn);
2416 result = ssh_init(conn);
2420 ssh = &conn->proto.sshc;
2422 #ifdef CURL_LIBSSH2_DEBUG
2424 infof(data, "User: %s\n", conn->user);
2427 infof(data, "Password: %s\n", conn->passwd);
2429 sock = conn->sock[FIRSTSOCKET];
2430 #endif /* CURL_LIBSSH2_DEBUG */
2432 ssh->ssh_session = libssh2_session_init_ex(libssh2_malloc, libssh2_free,
2433 libssh2_realloc, conn);
2434 if(ssh->ssh_session == NULL) {
2435 failf(data, "Failure initialising ssh session");
2436 return CURLE_FAILED_INIT;
2439 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2440 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2442 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2444 /* eeek. TODO: free the ssh_session! */
2445 return CURLE_FAILED_INIT;
2448 /* read all known hosts from there */
2449 rc = libssh2_knownhost_readfile(ssh->kh,
2450 data->set.str[STRING_SSH_KNOWNHOSTS],
2451 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2453 infof(data, "Failed to read known hosts from %s\n",
2454 data->set.str[STRING_SSH_KNOWNHOSTS]);
2457 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2459 #ifdef CURL_LIBSSH2_DEBUG
2460 libssh2_trace(ssh->ssh_session, ~0);
2461 infof(data, "SSH socket: %d\n", sock);
2462 #endif /* CURL_LIBSSH2_DEBUG */
2464 state(conn, SSH_S_STARTUP);
2466 if(data->state.used_interface == Curl_if_multi)
2467 result = ssh_multi_statemach(conn, done);
2469 result = ssh_easy_statemach(conn);
2478 ***********************************************************************
2482 * This is the actual DO function for SCP. Get a file according to
2483 * the options previously setup.
2487 CURLcode scp_perform(struct connectdata *conn,
2491 CURLcode result = CURLE_OK;
2493 DEBUGF(infof(conn->data, "DO phase starts\n"));
2495 *dophase_done = FALSE; /* not done yet */
2497 /* start the first command in the DO phase */
2498 state(conn, SSH_SCP_TRANS_INIT);
2500 /* run the state-machine */
2501 if(conn->data->state.used_interface == Curl_if_multi) {
2502 result = ssh_multi_statemach(conn, dophase_done);
2505 result = ssh_easy_statemach(conn);
2506 *dophase_done = TRUE; /* with the easy interface we are done here */
2508 *connected = conn->bits.tcpconnect;
2511 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2517 /* called from multi.c while DOing */
2518 static CURLcode scp_doing(struct connectdata *conn,
2522 result = ssh_multi_statemach(conn, dophase_done);
2525 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2531 * The DO function is generic for both protocols. There was previously two
2532 * separate ones but this way means less duplicated code.
2535 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2539 struct SessionHandle *data = conn->data;
2541 *done = FALSE; /* default to false */
2544 Since connections can be re-used between SessionHandles, this might be a
2545 connection already existing but on a fresh SessionHandle struct so we must
2546 make sure we have a good 'struct SSHPROTO' to play with. For new
2547 connections, the struct SSHPROTO is allocated and setup in the
2548 ssh_connect() function.
2550 Curl_reset_reqproto(conn);
2551 res = ssh_init(conn);
2555 data->req.size = -1; /* make sure this is unknown at this point */
2557 Curl_pgrsSetUploadCounter(data, 0);
2558 Curl_pgrsSetDownloadCounter(data, 0);
2559 Curl_pgrsSetUploadSize(data, 0);
2560 Curl_pgrsSetDownloadSize(data, 0);
2562 if(conn->protocol & PROT_SCP)
2563 res = scp_perform(conn, &connected, done);
2565 res = sftp_perform(conn, &connected, done);
2570 /* BLOCKING, but the function is using the state machine so the only reason this
2571 is still blocking is that the multi interface code has no support for
2572 disconnecting operations that takes a while */
2573 static CURLcode scp_disconnect(struct connectdata *conn)
2575 CURLcode result = CURLE_OK;
2576 struct ssh_conn *ssh = &conn->proto.sshc;
2578 Curl_safefree(conn->data->state.proto.ssh);
2579 conn->data->state.proto.ssh = NULL;
2581 if(ssh->ssh_session) {
2582 /* only if there's a session still around to use! */
2584 state(conn, SSH_SESSION_DISCONNECT);
2586 result = ssh_easy_statemach(conn);
2592 /* generic done function for both SCP and SFTP called from their specific
2594 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2596 CURLcode result = CURLE_OK;
2597 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2599 if(status == CURLE_OK) {
2600 /* run the state-machine
2602 TODO: when the multi interface this _really_ should be using the
2603 ssh_multi_statemach function but we have no general support for
2604 non-blocking DONE operations, not in the multi state machine and with
2605 Curl_done() invokes on several places in the code!
2607 result = ssh_easy_statemach(conn);
2612 Curl_safefree(sftp_scp->path);
2613 sftp_scp->path = NULL;
2614 Curl_pgrsDone(conn);
2616 conn->data->req.keepon = 0; /* clear all bits */
2621 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2624 (void)premature; /* not used */
2626 if(status == CURLE_OK)
2627 state(conn, SSH_SCP_DONE);
2629 return ssh_done(conn, status);
2633 /* return number of received (decrypted) bytes */
2634 ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
2635 const void *mem, size_t len)
2638 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2640 /* libssh2_channel_write() returns int! */
2642 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2644 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2646 if(nwrite == LIBSSH2_ERROR_EAGAIN)
2653 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2654 * a regular CURLcode value.
2656 ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex,
2657 char *mem, size_t len)
2660 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2662 /* libssh2_channel_read() returns int */
2664 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2666 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2672 * =============== SFTP ===============
2676 ***********************************************************************
2680 * This is the actual DO function for SFTP. Get a file/directory according to
2681 * the options previously setup.
2685 CURLcode sftp_perform(struct connectdata *conn,
2689 CURLcode result = CURLE_OK;
2691 DEBUGF(infof(conn->data, "DO phase starts\n"));
2693 *dophase_done = FALSE; /* not done yet */
2695 /* start the first command in the DO phase */
2696 state(conn, SSH_SFTP_QUOTE_INIT);
2698 /* run the state-machine */
2699 if(conn->data->state.used_interface == Curl_if_multi) {
2700 result = ssh_multi_statemach(conn, dophase_done);
2703 result = ssh_easy_statemach(conn);
2704 *dophase_done = TRUE; /* with the easy interface we are done here */
2706 *connected = conn->bits.tcpconnect;
2709 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2715 /* called from multi.c while DOing */
2716 static CURLcode sftp_doing(struct connectdata *conn,
2720 result = ssh_multi_statemach(conn, dophase_done);
2723 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2728 /* BLOCKING, but the function is using the state machine so the only reason this
2729 is still blocking is that the multi interface code has no support for
2730 disconnecting operations that takes a while */
2731 static CURLcode sftp_disconnect(struct connectdata *conn)
2733 CURLcode result = CURLE_OK;
2735 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2737 Curl_safefree(conn->data->state.proto.ssh);
2738 conn->data->state.proto.ssh = NULL;
2740 if(conn->proto.sshc.ssh_session) {
2741 /* only if there's a session still around to use! */
2742 state(conn, SSH_SFTP_SHUTDOWN);
2743 result = ssh_easy_statemach(conn);
2746 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2752 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2755 struct ssh_conn *sshc = &conn->proto.sshc;
2757 if(status == CURLE_OK) {
2758 /* Before we shut down, see if there are any post-quote commands to send: */
2759 if(!status && !premature && conn->data->set.postquote) {
2760 sshc->nextstate = SSH_SFTP_CLOSE;
2761 state(conn, SSH_SFTP_POSTQUOTE_INIT);
2764 state(conn, SSH_SFTP_CLOSE);
2766 return ssh_done(conn, status);
2769 /* return number of sent bytes */
2770 ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
2771 const void *mem, size_t len)
2773 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2774 but is changed to ssize_t in 0.15. These days we don't
2775 support libssh2 0.15*/
2778 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2780 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2782 if(nwrite == LIBSSH2_ERROR_EAGAIN)
2789 * Return number of received (decrypted) bytes
2791 ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
2792 char *mem, size_t len)
2797 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
2799 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2804 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
2807 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
2809 * Permission to use, copy, modify, and distribute this software for any
2810 * purpose with or without fee is hereby granted, provided that the above
2811 * copyright notice and this permission notice appear in all copies.
2813 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2814 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2815 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2816 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2817 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2818 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2819 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2822 get_pathname(const char **cpp, char **path)
2824 const char *cp = *cpp, *end;
2827 static const char WHITESPACE[] = " \t\r\n";
2829 cp += strspn(cp, WHITESPACE);
2833 return CURLE_QUOTE_ERROR;
2836 *path = malloc(strlen(cp) + 1);
2838 return CURLE_OUT_OF_MEMORY;
2840 /* Check for quoted filenames */
2841 if(*cp == '\"' || *cp == '\'') {
2844 /* Search for terminating quote, unescape some chars */
2845 for (i = j = 0; i <= strlen(cp); i++) {
2846 if(cp[i] == quot) { /* Found quote */
2851 if(cp[i] == '\0') { /* End of string */
2852 /*error("Unterminated quote");*/
2855 if(cp[i] == '\\') { /* Escaped characters */
2857 if(cp[i] != '\'' && cp[i] != '\"' &&
2859 /*error("Bad escaped character '\\%c'",
2864 (*path)[j++] = cp[i];
2868 /*error("Empty quotes");*/
2871 *cpp = cp + i + strspn(cp + i, WHITESPACE);
2874 /* Read to end of filename */
2875 end = strpbrk(cp, WHITESPACE);
2877 end = strchr(cp, '\0');
2878 *cpp = end + strspn(end, WHITESPACE);
2880 memcpy(*path, cp, end - cp);
2881 (*path)[end - cp] = '\0';
2886 Curl_safefree(*path);
2888 return CURLE_QUOTE_ERROR;
2892 static const char *sftp_libssh2_strerror(unsigned long err)
2895 case LIBSSH2_FX_NO_SUCH_FILE:
2896 return "No such file or directory";
2898 case LIBSSH2_FX_PERMISSION_DENIED:
2899 return "Permission denied";
2901 case LIBSSH2_FX_FAILURE:
2902 return "Operation failed";
2904 case LIBSSH2_FX_BAD_MESSAGE:
2905 return "Bad message from SFTP server";
2907 case LIBSSH2_FX_NO_CONNECTION:
2908 return "Not connected to SFTP server";
2910 case LIBSSH2_FX_CONNECTION_LOST:
2911 return "Connection to SFTP server lost";
2913 case LIBSSH2_FX_OP_UNSUPPORTED:
2914 return "Operation not supported by SFTP server";
2916 case LIBSSH2_FX_INVALID_HANDLE:
2917 return "Invalid handle";
2919 case LIBSSH2_FX_NO_SUCH_PATH:
2920 return "No such file or directory";
2922 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
2923 return "File already exists";
2925 case LIBSSH2_FX_WRITE_PROTECT:
2926 return "File is write protected";
2928 case LIBSSH2_FX_NO_MEDIA:
2931 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
2934 case LIBSSH2_FX_QUOTA_EXCEEDED:
2935 return "User quota exceeded";
2937 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
2938 return "Unknown principle";
2940 case LIBSSH2_FX_LOCK_CONFlICT:
2941 return "File lock conflict";
2943 case LIBSSH2_FX_DIR_NOT_EMPTY:
2944 return "Directory not empty";
2946 case LIBSSH2_FX_NOT_A_DIRECTORY:
2947 return "Not a directory";
2949 case LIBSSH2_FX_INVALID_FILENAME:
2950 return "Invalid filename";
2952 case LIBSSH2_FX_LINK_LOOP:
2953 return "Link points to itself";
2955 return "Unknown error in libssh2";
2958 #endif /* USE_LIBSSH2 */