1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2010, 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)
268 /* Ordered by order of appearance in libssh2.h */
269 case LIBSSH2_ERROR_NONE:
272 case LIBSSH2_ERROR_SOCKET_NONE:
273 return CURLE_COULDNT_CONNECT;
275 case LIBSSH2_ERROR_ALLOC:
276 return CURLE_OUT_OF_MEMORY;
278 case LIBSSH2_ERROR_SOCKET_SEND:
279 return CURLE_SEND_ERROR;
281 case LIBSSH2_ERROR_HOSTKEY_INIT:
282 case LIBSSH2_ERROR_HOSTKEY_SIGN:
283 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
284 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
285 return CURLE_PEER_FAILED_VERIFICATION;
287 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
288 return CURLE_LOGIN_DENIED;
290 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
291 case LIBSSH2_ERROR_TIMEOUT:
292 return CURLE_OPERATION_TIMEDOUT;
294 case LIBSSH2_ERROR_EAGAIN:
298 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
299 error code, and possibly add a few new SSH-related one. We must however
300 not return or even depend on libssh2 errors in the public libcurl API */
305 static LIBSSH2_ALLOC_FUNC(libssh2_malloc)
307 (void)abstract; /* arg not used */
308 return malloc(count);
311 static LIBSSH2_REALLOC_FUNC(libssh2_realloc)
313 (void)abstract; /* arg not used */
314 return realloc(ptr, count);
317 static LIBSSH2_FREE_FUNC(libssh2_free)
319 (void)abstract; /* arg not used */
324 * SSH State machine related code
326 /* This is the ONLY way to change SSH state! */
327 static void state(struct connectdata *conn, sshstate nowstate)
329 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
330 /* for debug purposes */
331 static const char * const names[] = {
336 "SSH_AUTH_PKEY_INIT",
338 "SSH_AUTH_PASS_INIT",
340 "SSH_AUTH_HOST_INIT",
347 "SSH_SFTP_QUOTE_INIT",
348 "SSH_SFTP_POSTQUOTE_INIT",
350 "SSH_SFTP_NEXT_QUOTE",
351 "SSH_SFTP_QUOTE_STAT",
352 "SSH_SFTP_QUOTE_SETSTAT",
353 "SSH_SFTP_QUOTE_SYMLINK",
354 "SSH_SFTP_QUOTE_MKDIR",
355 "SSH_SFTP_QUOTE_RENAME",
356 "SSH_SFTP_QUOTE_RMDIR",
357 "SSH_SFTP_QUOTE_UNLINK",
358 "SSH_SFTP_TRANS_INIT",
359 "SSH_SFTP_UPLOAD_INIT",
360 "SSH_SFTP_CREATE_DIRS_INIT",
361 "SSH_SFTP_CREATE_DIRS",
362 "SSH_SFTP_CREATE_DIRS_MKDIR",
363 "SSH_SFTP_READDIR_INIT",
365 "SSH_SFTP_READDIR_LINK",
366 "SSH_SFTP_READDIR_BOTTOM",
367 "SSH_SFTP_READDIR_DONE",
368 "SSH_SFTP_DOWNLOAD_INIT",
369 "SSH_SFTP_DOWNLOAD_STAT",
372 "SSH_SCP_TRANS_INIT",
373 "SSH_SCP_UPLOAD_INIT",
374 "SSH_SCP_DOWNLOAD_INIT",
378 "SSH_SCP_WAIT_CLOSE",
379 "SSH_SCP_CHANNEL_FREE",
380 "SSH_SESSION_DISCONNECT",
385 struct ssh_conn *sshc = &conn->proto.sshc;
387 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
388 if(sshc->state != nowstate) {
389 infof(conn->data, "SFTP %p state change from %s to %s\n",
390 sshc, names[sshc->state], names[nowstate]);
394 sshc->state = nowstate;
397 /* figure out the path to work with in this particular request */
398 static CURLcode ssh_getworkingpath(struct connectdata *conn,
399 char *homedir, /* when SFTP is used */
400 char **path) /* returns the allocated
401 real path to work with */
403 struct SessionHandle *data = conn->data;
404 char *real_path = NULL;
406 int working_path_len;
408 working_path = curl_easy_unescape(data, data->state.path, 0,
411 return CURLE_OUT_OF_MEMORY;
413 /* Check for /~/ , indicating relative to the user's home directory */
414 if(conn->protocol & PROT_SCP) {
415 real_path = malloc(working_path_len+1);
416 if(real_path == NULL) {
418 return CURLE_OUT_OF_MEMORY;
420 if((working_path_len > 1) && (working_path[1] == '~'))
421 /* It is referenced to the home directory, so strip the leading '/' */
422 memcpy(real_path, working_path+1, 1 + working_path_len-1);
424 memcpy(real_path, working_path, 1 + working_path_len);
426 else if(conn->protocol & PROT_SFTP) {
427 if((working_path_len > 1) && (working_path[1] == '~')) {
428 size_t homelen = strlen(homedir);
429 real_path = malloc(homelen + working_path_len + 1);
430 if(real_path == NULL) {
432 return CURLE_OUT_OF_MEMORY;
434 /* It is referenced to the home directory, so strip the
436 memcpy(real_path, homedir, homelen);
437 real_path[homelen] = '/';
438 real_path[homelen+1] = '\0';
439 if(working_path_len > 3) {
440 memcpy(real_path+homelen+1, working_path + 3,
441 1 + working_path_len -3);
445 real_path = malloc(working_path_len+1);
446 if(real_path == NULL) {
448 return CURLE_OUT_OF_MEMORY;
450 memcpy(real_path, working_path, 1+working_path_len);
456 /* store the pointer for the caller to receive */
462 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
463 static int sshkeycallback(CURL *easy,
464 const struct curl_khkey *knownkey, /* known */
465 const struct curl_khkey *foundkey, /* found */
466 enum curl_khmatch match,
474 /* we only allow perfect matches, and we reject everything else */
475 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
480 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
483 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
484 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
486 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
490 * ssh_statemach_act() runs the SSH state machine as far as it can without
491 * blocking and without reaching the end. The data the pointer 'block' points
492 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
493 * meaning it wants to be called again when the socket is ready
496 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
498 CURLcode result = CURLE_OK;
499 struct SessionHandle *data = conn->data;
500 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
501 struct ssh_conn *sshc = &conn->proto.sshc;
502 curl_socket_t sock = conn->sock[FIRSTSOCKET];
503 #ifdef CURL_LIBSSH2_DEBUG
504 const char *fingerprint;
505 #endif /* CURL_LIBSSH2_DEBUG */
506 const char *host_public_key_md5;
507 int rc = LIBSSH2_ERROR_NONE, i;
509 int seekerr = CURL_SEEKFUNC_OK;
510 *block = 0; /* we're not blocking by default */
514 switch(sshc->state) {
516 sshc->secondCreateDirs = 0;
517 sshc->nextstate = SSH_NO_STATE;
518 sshc->actualcode = CURLE_OK;
520 rc = libssh2_session_startup(sshc->ssh_session, sock);
521 if(rc == LIBSSH2_ERROR_EAGAIN) {
525 failf(data, "Failure establishing ssh session");
526 state(conn, SSH_SESSION_FREE);
527 sshc->actualcode = CURLE_FAILED_INIT;
531 /* Set libssh2 to non-blocking, since everything internally is
533 libssh2_session_set_blocking(sshc->ssh_session, 0);
535 state(conn, SSH_HOSTKEY);
540 #ifdef CURL_LIBSSH2_DEBUG
542 * Before we authenticate we should check the hostkey's fingerprint
543 * against our known hosts. How that is handled (reading from file,
544 * whatever) is up to us. As for know not much is implemented, besides
545 * showing how to get the fingerprint.
547 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
548 LIBSSH2_HOSTKEY_HASH_MD5);
550 /* The fingerprint points to static storage (!), don't free() it. */
551 infof(data, "Fingerprint: ");
552 for (rc = 0; rc < 16; rc++) {
553 infof(data, "%02X ", (unsigned char) fingerprint[rc]);
556 #endif /* CURL_LIBSSH2_DEBUG */
558 /* Before we authenticate we check the hostkey's MD5 fingerprint
559 * against a known fingerprint, if available. This implementation pulls
560 * it from the curl option.
562 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
563 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
565 host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
566 LIBSSH2_HOSTKEY_HASH_MD5);
567 for (i = 0; i < 16; i++)
568 snprintf(&buf[i*2], 3, "%02x",
569 (unsigned char) host_public_key_md5[i]);
570 if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
572 "Denied establishing ssh session: mismatch md5 fingerprint. "
573 "Remote %s is not equal to %s",
574 buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
575 state(conn, SSH_SESSION_FREE);
576 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
581 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
582 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
583 /* we're asked to verify the host against a file */
586 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
593 * A subject to figure out is what host name we need to pass in here.
594 * What host name does OpenSSH store in its file if an IDN name is
597 struct libssh2_knownhost *host;
598 enum curl_khmatch keymatch;
599 curl_sshkeycallback func =
600 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
601 struct curl_khkey knownkey;
602 struct curl_khkey *knownkeyp = NULL;
603 struct curl_khkey foundkey;
605 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
606 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
608 keycheck = libssh2_knownhost_check(sshc->kh,
611 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
612 LIBSSH2_KNOWNHOST_KEYENC_RAW|
616 infof(data, "SSH host check: %d, key: %s\n", keycheck,
617 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
620 /* setup 'knownkey' */
621 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
622 knownkey.key = host->key;
624 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
625 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
626 knownkeyp = &knownkey;
629 /* setup 'foundkey' */
630 foundkey.key = remotekey;
631 foundkey.len = keylen;
632 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
633 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
636 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
637 * curl_khmatch enum are ever modified, we need to introduce a
638 * translation table here!
640 keymatch = (enum curl_khmatch)keycheck;
642 /* Ask the callback how to behave */
643 rc = func(data, knownkeyp, /* from the knownhosts file */
644 &foundkey, /* from the remote host */
645 keymatch, data->set.ssh_keyfunc_userp);
648 /* no remotekey means failure! */
649 rc = CURLKHSTAT_REJECT;
652 default: /* unknown return codes will equal reject */
653 case CURLKHSTAT_REJECT:
654 state(conn, SSH_SESSION_FREE);
655 case CURLKHSTAT_DEFER:
656 /* DEFER means bail out but keep the SSH_HOSTKEY state */
657 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
659 case CURLKHSTAT_FINE:
660 case CURLKHSTAT_FINE_ADD_TO_FILE:
662 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
663 /* the found host+key didn't match but has been told to be fine
664 anyway so we add it in memory */
665 int addrc = libssh2_knownhost_add(sshc->kh,
666 conn->host.name, NULL,
668 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
669 LIBSSH2_KNOWNHOST_KEYENC_RAW|
672 infof(data, "Warning adding the known host %s failed!\n",
674 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
675 /* now we write the entire in-memory list of known hosts to the
678 libssh2_knownhost_writefile(sshc->kh,
679 data->set.str[STRING_SSH_KNOWNHOSTS],
680 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
682 infof(data, "Warning, writing %s failed!\n",
683 data->set.str[STRING_SSH_KNOWNHOSTS]);
690 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
692 state(conn, SSH_AUTHLIST);
697 * Figure out authentication methods
698 * NB: As soon as we have provided a username to an openssh server we
699 * must never change it later. Thus, always specify the correct username
700 * here, even though the libssh2 docs kind of indicate that it should be
701 * possible to get a 'generic' list (not user-specific) of authentication
702 * methods, presumably with a blank username. That won't work in my
704 * So always specify it here.
706 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
710 if(!sshc->authlist) {
711 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
712 LIBSSH2_ERROR_EAGAIN) {
713 rc = LIBSSH2_ERROR_EAGAIN;
717 state(conn, SSH_SESSION_FREE);
718 sshc->actualcode = libssh2_session_error_to_CURLE(err);
722 infof(data, "SSH authentication methods available: %s\n", sshc->authlist);
724 state(conn, SSH_AUTH_PKEY_INIT);
727 case SSH_AUTH_PKEY_INIT:
729 * Check the supported auth types in the order I feel is most secure
730 * with the requested type of authentication
732 sshc->authed = FALSE;
734 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
735 (strstr(sshc->authlist, "publickey") != NULL)) {
738 sshc->rsa_pub = sshc->rsa = NULL;
740 /* To ponder about: should really the lib be messing about with the
741 HOME environment variable etc? */
742 home = curl_getenv("HOME");
744 if(data->set.str[STRING_SSH_PUBLIC_KEY])
745 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
747 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
749 /* as a final resort, try current dir! */
750 sshc->rsa_pub = strdup("id_dsa.pub");
752 if(sshc->rsa_pub == NULL) {
755 state(conn, SSH_SESSION_FREE);
756 sshc->actualcode = CURLE_OUT_OF_MEMORY;
760 if(data->set.str[STRING_SSH_PRIVATE_KEY])
761 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
763 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
765 /* as a final resort, try current dir! */
766 sshc->rsa = strdup("id_dsa");
768 if(sshc->rsa == NULL) {
771 Curl_safefree(sshc->rsa_pub);
772 sshc->rsa_pub = NULL;
773 state(conn, SSH_SESSION_FREE);
774 sshc->actualcode = CURLE_OUT_OF_MEMORY;
778 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
779 if(!sshc->passphrase)
780 sshc->passphrase = "";
785 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
786 infof(data, "Using ssh private key file %s\n", sshc->rsa);
788 state(conn, SSH_AUTH_PKEY);
791 state(conn, SSH_AUTH_PASS_INIT);
796 /* The function below checks if the files exists, no need to stat() here.
798 rc = libssh2_userauth_publickey_fromfile(sshc->ssh_session,
799 conn->user, sshc->rsa_pub,
800 sshc->rsa, sshc->passphrase);
801 if(rc == LIBSSH2_ERROR_EAGAIN) {
805 Curl_safefree(sshc->rsa_pub);
806 sshc->rsa_pub = NULL;
807 Curl_safefree(sshc->rsa);
812 infof(data, "Initialized SSH public key authentication\n");
813 state(conn, SSH_AUTH_DONE);
817 (void)libssh2_session_last_error(sshc->ssh_session,
819 infof(data, "SSH public key authentication failed: %s\n", err_msg);
820 state(conn, SSH_AUTH_PASS_INIT);
824 case SSH_AUTH_PASS_INIT:
825 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
826 (strstr(sshc->authlist, "password") != NULL)) {
827 state(conn, SSH_AUTH_PASS);
830 state(conn, SSH_AUTH_HOST_INIT);
835 rc = libssh2_userauth_password(sshc->ssh_session, conn->user,
837 if(rc == LIBSSH2_ERROR_EAGAIN) {
842 infof(data, "Initialized password authentication\n");
843 state(conn, SSH_AUTH_DONE);
846 state(conn, SSH_AUTH_HOST_INIT);
850 case SSH_AUTH_HOST_INIT:
851 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
852 (strstr(sshc->authlist, "hostbased") != NULL)) {
853 state(conn, SSH_AUTH_HOST);
856 state(conn, SSH_AUTH_KEY_INIT);
861 state(conn, SSH_AUTH_KEY_INIT);
864 case SSH_AUTH_KEY_INIT:
865 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
866 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
867 state(conn, SSH_AUTH_KEY);
870 state(conn, SSH_AUTH_DONE);
875 /* Authentication failed. Continue with keyboard-interactive now. */
876 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
880 if(rc == LIBSSH2_ERROR_EAGAIN) {
885 infof(data, "Initialized keyboard interactive authentication\n");
887 state(conn, SSH_AUTH_DONE);
892 failf(data, "Authentication failure");
893 state(conn, SSH_SESSION_FREE);
894 sshc->actualcode = CURLE_LOGIN_DENIED;
899 * At this point we have an authenticated ssh session.
901 infof(data, "Authentication complete\n");
903 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
906 conn->writesockfd = CURL_SOCKET_BAD;
908 if(conn->protocol == PROT_SFTP) {
909 state(conn, SSH_SFTP_INIT);
912 infof(data, "SSH CONNECT phase done\n");
913 state(conn, SSH_STOP);
918 * Start the libssh2 sftp session
920 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
921 if(!sshc->sftp_session) {
922 if(libssh2_session_last_errno(sshc->ssh_session) ==
923 LIBSSH2_ERROR_EAGAIN) {
924 rc = LIBSSH2_ERROR_EAGAIN;
930 (void)libssh2_session_last_error(sshc->ssh_session,
932 failf(data, "Failure initializing sftp session: %s", err_msg);
933 state(conn, SSH_SESSION_FREE);
934 sshc->actualcode = CURLE_FAILED_INIT;
938 state(conn, SSH_SFTP_REALPATH);
941 case SSH_SFTP_REALPATH:
943 char tempHome[PATH_MAX];
946 * Get the "home" directory
948 rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
949 tempHome, PATH_MAX-1);
950 if(rc == LIBSSH2_ERROR_EAGAIN) {
954 /* It seems that this string is not always NULL terminated */
956 sshc->homedir = strdup(tempHome);
958 state(conn, SSH_SFTP_CLOSE);
959 sshc->actualcode = CURLE_OUT_OF_MEMORY;
964 /* Return the error type */
965 err = libssh2_sftp_last_error(sshc->sftp_session);
966 result = sftp_libssh2_error_to_CURLE(err);
967 sshc->actualcode = result?result:CURLE_SSH;
968 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
970 state(conn, SSH_STOP);
974 /* This is the last step in the SFTP connect phase. Do note that while
975 we get the homedir here, we get the "workingpath" in the DO action
976 since the homedir will remain the same between request but the
977 working path will not. */
978 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
979 state(conn, SSH_STOP);
982 case SSH_SFTP_QUOTE_INIT:
984 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
986 sshc->actualcode = result;
987 state(conn, SSH_STOP);
991 if(data->set.quote) {
992 infof(data, "Sending quote commands\n");
993 sshc->quote_item = data->set.quote;
994 state(conn, SSH_SFTP_QUOTE);
997 state(conn, SSH_SFTP_TRANS_INIT);
1001 case SSH_SFTP_POSTQUOTE_INIT:
1002 if(data->set.postquote) {
1003 infof(data, "Sending quote commands\n");
1004 sshc->quote_item = data->set.postquote;
1005 state(conn, SSH_SFTP_QUOTE);
1008 state(conn, SSH_STOP);
1012 case SSH_SFTP_QUOTE:
1013 /* Send any quote commands */
1018 * Support some of the "FTP" commands
1020 if(curl_strequal("pwd", sshc->quote_item->data)) {
1021 /* output debug output if that is requested */
1022 if(data->set.verbose) {
1023 char tmp[PATH_MAX+1];
1025 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1026 snprintf(tmp, PATH_MAX, "257 \"%s\" is current directory.\n",
1028 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1030 state(conn, SSH_SFTP_NEXT_QUOTE);
1033 else if(sshc->quote_item->data) {
1035 * the arguments following the command must be separated from the
1036 * command with a space so we can check for it unconditionally
1038 cp = strchr(sshc->quote_item->data, ' ');
1040 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1041 state(conn, SSH_SFTP_CLOSE);
1042 sshc->actualcode = CURLE_QUOTE_ERROR;
1047 * also, every command takes at least one argument so we get that
1048 * first argument right now
1050 result = get_pathname(&cp, &sshc->quote_path1);
1052 if(result == CURLE_OUT_OF_MEMORY)
1053 failf(data, "Out of memory");
1055 failf(data, "Syntax error: Bad first parameter");
1056 state(conn, SSH_SFTP_CLOSE);
1057 sshc->actualcode = result;
1062 * SFTP is a binary protocol, so we don't send text commands to
1063 * the server. Instead, we scan for commands for commands used by
1064 * OpenSSH's sftp program and call the appropriate libssh2
1067 if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
1068 curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
1069 curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
1070 /* attribute change */
1072 /* sshc->quote_path1 contains the mode to set */
1073 /* get the destination */
1074 result = get_pathname(&cp, &sshc->quote_path2);
1076 if(result == CURLE_OUT_OF_MEMORY)
1077 failf(data, "Out of memory");
1079 failf(data, "Syntax error in chgrp/chmod/chown: "
1080 "Bad second parameter");
1081 Curl_safefree(sshc->quote_path1);
1082 sshc->quote_path1 = NULL;
1083 state(conn, SSH_SFTP_CLOSE);
1084 sshc->actualcode = result;
1087 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1088 state(conn, SSH_SFTP_QUOTE_STAT);
1091 else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
1092 curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
1093 /* symbolic linking */
1094 /* sshc->quote_path1 is the source */
1095 /* get the destination */
1096 result = get_pathname(&cp, &sshc->quote_path2);
1098 if(result == CURLE_OUT_OF_MEMORY)
1099 failf(data, "Out of memory");
1102 "Syntax error in ln/symlink: Bad second parameter");
1103 Curl_safefree(sshc->quote_path1);
1104 sshc->quote_path1 = NULL;
1105 state(conn, SSH_SFTP_CLOSE);
1106 sshc->actualcode = result;
1109 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1112 else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
1114 state(conn, SSH_SFTP_QUOTE_MKDIR);
1117 else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
1119 /* first param is the source path */
1120 /* second param is the dest. path */
1121 result = get_pathname(&cp, &sshc->quote_path2);
1123 if(result == CURLE_OUT_OF_MEMORY)
1124 failf(data, "Out of memory");
1126 failf(data, "Syntax error in rename: Bad second parameter");
1127 Curl_safefree(sshc->quote_path1);
1128 sshc->quote_path1 = NULL;
1129 state(conn, SSH_SFTP_CLOSE);
1130 sshc->actualcode = result;
1133 state(conn, SSH_SFTP_QUOTE_RENAME);
1136 else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
1138 state(conn, SSH_SFTP_QUOTE_RMDIR);
1141 else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
1142 state(conn, SSH_SFTP_QUOTE_UNLINK);
1146 failf(data, "Unknown SFTP command");
1147 Curl_safefree(sshc->quote_path1);
1148 sshc->quote_path1 = NULL;
1149 Curl_safefree(sshc->quote_path2);
1150 sshc->quote_path2 = NULL;
1151 state(conn, SSH_SFTP_CLOSE);
1152 sshc->actualcode = CURLE_QUOTE_ERROR;
1156 if(!sshc->quote_item) {
1157 state(conn, SSH_SFTP_TRANS_INIT);
1161 case SSH_SFTP_NEXT_QUOTE:
1162 if(sshc->quote_path1) {
1163 Curl_safefree(sshc->quote_path1);
1164 sshc->quote_path1 = NULL;
1166 if(sshc->quote_path2) {
1167 Curl_safefree(sshc->quote_path2);
1168 sshc->quote_path2 = NULL;
1171 sshc->quote_item = sshc->quote_item->next;
1173 if(sshc->quote_item) {
1174 state(conn, SSH_SFTP_QUOTE);
1177 if(sshc->nextstate != SSH_NO_STATE) {
1178 state(conn, sshc->nextstate);
1179 sshc->nextstate = SSH_NO_STATE;
1182 state(conn, SSH_SFTP_TRANS_INIT);
1187 case SSH_SFTP_QUOTE_STAT:
1188 if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1189 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1190 * set them both at once, we need to obtain the current ownership first.
1191 * This takes an extra protocol round trip.
1193 rc = libssh2_sftp_stat(sshc->sftp_session, sshc->quote_path2,
1194 &sshc->quote_attrs);
1195 if(rc == LIBSSH2_ERROR_EAGAIN) {
1198 else if(rc != 0) { /* get those attributes */
1199 err = libssh2_sftp_last_error(sshc->sftp_session);
1200 Curl_safefree(sshc->quote_path1);
1201 sshc->quote_path1 = NULL;
1202 Curl_safefree(sshc->quote_path2);
1203 sshc->quote_path2 = NULL;
1204 failf(data, "Attempt to get SFTP stats failed: %s",
1205 sftp_libssh2_strerror(err));
1206 state(conn, SSH_SFTP_CLOSE);
1207 sshc->actualcode = CURLE_QUOTE_ERROR;
1212 /* Now set the new attributes... */
1213 if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
1214 sshc->quote_attrs.gid = strtol(sshc->quote_path1, NULL, 10);
1215 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1216 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1217 Curl_safefree(sshc->quote_path1);
1218 sshc->quote_path1 = NULL;
1219 Curl_safefree(sshc->quote_path2);
1220 sshc->quote_path2 = NULL;
1221 failf(data, "Syntax error: chgrp gid not a number");
1222 state(conn, SSH_SFTP_CLOSE);
1223 sshc->actualcode = CURLE_QUOTE_ERROR;
1227 else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
1228 sshc->quote_attrs.permissions = strtol(sshc->quote_path1, NULL, 8);
1229 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1230 /* permissions are octal */
1231 if(sshc->quote_attrs.permissions == 0 &&
1232 !ISDIGIT(sshc->quote_path1[0])) {
1233 Curl_safefree(sshc->quote_path1);
1234 sshc->quote_path1 = NULL;
1235 Curl_safefree(sshc->quote_path2);
1236 sshc->quote_path2 = NULL;
1237 failf(data, "Syntax error: chmod permissions not a number");
1238 state(conn, SSH_SFTP_CLOSE);
1239 sshc->actualcode = CURLE_QUOTE_ERROR;
1243 else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
1244 sshc->quote_attrs.uid = strtol(sshc->quote_path1, NULL, 10);
1245 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1246 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
1247 Curl_safefree(sshc->quote_path1);
1248 sshc->quote_path1 = NULL;
1249 Curl_safefree(sshc->quote_path2);
1250 sshc->quote_path2 = NULL;
1251 failf(data, "Syntax error: chown uid not a number");
1252 state(conn, SSH_SFTP_CLOSE);
1253 sshc->actualcode = CURLE_QUOTE_ERROR;
1258 /* Now send the completed structure... */
1259 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1262 case SSH_SFTP_QUOTE_SETSTAT:
1263 rc = libssh2_sftp_setstat(sshc->sftp_session, sshc->quote_path2,
1264 &sshc->quote_attrs);
1265 if(rc == LIBSSH2_ERROR_EAGAIN) {
1269 err = libssh2_sftp_last_error(sshc->sftp_session);
1270 Curl_safefree(sshc->quote_path1);
1271 sshc->quote_path1 = NULL;
1272 Curl_safefree(sshc->quote_path2);
1273 sshc->quote_path2 = NULL;
1274 failf(data, "Attempt to set SFTP stats failed: %s",
1275 sftp_libssh2_strerror(err));
1276 state(conn, SSH_SFTP_CLOSE);
1277 sshc->actualcode = CURLE_QUOTE_ERROR;
1280 state(conn, SSH_SFTP_NEXT_QUOTE);
1283 case SSH_SFTP_QUOTE_SYMLINK:
1284 rc = libssh2_sftp_symlink(sshc->sftp_session, sshc->quote_path1,
1286 if(rc == LIBSSH2_ERROR_EAGAIN) {
1290 err = libssh2_sftp_last_error(sshc->sftp_session);
1291 Curl_safefree(sshc->quote_path1);
1292 sshc->quote_path1 = NULL;
1293 Curl_safefree(sshc->quote_path2);
1294 sshc->quote_path2 = NULL;
1295 failf(data, "symlink command failed: %s",
1296 sftp_libssh2_strerror(err));
1297 state(conn, SSH_SFTP_CLOSE);
1298 sshc->actualcode = CURLE_QUOTE_ERROR;
1301 state(conn, SSH_SFTP_NEXT_QUOTE);
1304 case SSH_SFTP_QUOTE_MKDIR:
1305 rc = libssh2_sftp_mkdir(sshc->sftp_session, sshc->quote_path1, 0755);
1306 if(rc == LIBSSH2_ERROR_EAGAIN) {
1310 err = libssh2_sftp_last_error(sshc->sftp_session);
1311 Curl_safefree(sshc->quote_path1);
1312 sshc->quote_path1 = NULL;
1313 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1314 state(conn, SSH_SFTP_CLOSE);
1315 sshc->actualcode = CURLE_QUOTE_ERROR;
1318 state(conn, SSH_SFTP_NEXT_QUOTE);
1321 case SSH_SFTP_QUOTE_RENAME:
1322 rc = libssh2_sftp_rename(sshc->sftp_session, sshc->quote_path1,
1324 if(rc == LIBSSH2_ERROR_EAGAIN) {
1328 err = libssh2_sftp_last_error(sshc->sftp_session);
1329 Curl_safefree(sshc->quote_path1);
1330 sshc->quote_path1 = NULL;
1331 Curl_safefree(sshc->quote_path2);
1332 sshc->quote_path2 = NULL;
1333 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1334 state(conn, SSH_SFTP_CLOSE);
1335 sshc->actualcode = CURLE_QUOTE_ERROR;
1338 state(conn, SSH_SFTP_NEXT_QUOTE);
1341 case SSH_SFTP_QUOTE_RMDIR:
1342 rc = libssh2_sftp_rmdir(sshc->sftp_session, sshc->quote_path1);
1343 if(rc == LIBSSH2_ERROR_EAGAIN) {
1347 err = libssh2_sftp_last_error(sshc->sftp_session);
1348 Curl_safefree(sshc->quote_path1);
1349 sshc->quote_path1 = NULL;
1350 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1351 state(conn, SSH_SFTP_CLOSE);
1352 sshc->actualcode = CURLE_QUOTE_ERROR;
1355 state(conn, SSH_SFTP_NEXT_QUOTE);
1358 case SSH_SFTP_QUOTE_UNLINK:
1359 rc = libssh2_sftp_unlink(sshc->sftp_session, sshc->quote_path1);
1360 if(rc == LIBSSH2_ERROR_EAGAIN) {
1364 err = libssh2_sftp_last_error(sshc->sftp_session);
1365 Curl_safefree(sshc->quote_path1);
1366 sshc->quote_path1 = NULL;
1367 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1368 state(conn, SSH_SFTP_CLOSE);
1369 sshc->actualcode = CURLE_QUOTE_ERROR;
1372 state(conn, SSH_SFTP_NEXT_QUOTE);
1375 case SSH_SFTP_TRANS_INIT:
1376 if(data->set.upload)
1377 state(conn, SSH_SFTP_UPLOAD_INIT);
1379 if(data->set.opt_no_body)
1380 state(conn, SSH_STOP);
1381 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1382 state(conn, SSH_SFTP_READDIR_INIT);
1384 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1388 case SSH_SFTP_UPLOAD_INIT:
1390 unsigned long flags;
1392 * NOTE!!! libssh2 requires that the destination path is a full path
1393 * that includes the destination file and name OR ends in a "/"
1394 * If this is not done the destination file will be named the
1395 * same name as the last directory in the path.
1398 if(data->state.resume_from != 0) {
1399 LIBSSH2_SFTP_ATTRIBUTES attrs;
1400 if(data->state.resume_from< 0) {
1401 rc = libssh2_sftp_stat(sshc->sftp_session, sftp_scp->path, &attrs);
1402 if(rc == LIBSSH2_ERROR_EAGAIN) {
1406 data->state.resume_from = 0;
1409 data->state.resume_from = attrs.filesize;
1414 if(data->set.ftp_append)
1415 /* Try to open for append, but create if nonexisting */
1416 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1417 else if (data->state.resume_from > 0)
1418 /* If we have restart position then open for append */
1419 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1421 /* Clear file before writing (normal behaviour) */
1422 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1425 libssh2_sftp_open(sshc->sftp_session, sftp_scp->path,
1426 flags, data->set.new_file_perms);
1428 if(!sshc->sftp_handle) {
1429 rc = libssh2_session_last_errno(sshc->ssh_session);
1431 if(LIBSSH2_ERROR_EAGAIN == rc)
1434 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1435 /* only when there was an SFTP protocol error can we extract
1437 err = libssh2_sftp_last_error(sshc->sftp_session);
1439 err = -1; /* not an sftp error at all */
1441 if(sshc->secondCreateDirs) {
1442 state(conn, SSH_SFTP_CLOSE);
1443 sshc->actualcode = err>= LIBSSH2_FX_OK?
1444 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1445 failf(data, "Creating the dir/file failed: %s",
1446 sftp_libssh2_strerror(err));
1449 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1450 (err == LIBSSH2_FX_FAILURE) ||
1451 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1452 (data->set.ftp_create_missing_dirs &&
1453 (strlen(sftp_scp->path) > 1))) {
1454 /* try to create the path remotely */
1455 sshc->secondCreateDirs = 1;
1456 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1459 state(conn, SSH_SFTP_CLOSE);
1460 sshc->actualcode = err>= LIBSSH2_FX_OK?
1461 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1462 if(!sshc->actualcode) {
1463 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1464 zero even though libssh2_sftp_open() failed previously! We need
1465 to work around that! */
1466 sshc->actualcode = CURLE_SSH;
1469 failf(data, "Upload failed: %s (%d/%d)",
1470 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1476 /* If we have restart point then we need to seek to the correct
1478 if(data->state.resume_from > 0) {
1479 /* Let's read off the proper amount of bytes from the input. */
1480 if(conn->seek_func) {
1481 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1485 if(seekerr != CURL_SEEKFUNC_OK){
1487 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1488 failf(data, "Could not seek stream");
1489 return CURLE_FTP_COULDNT_USE_REST;
1491 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1493 curl_off_t passed=0;
1494 curl_off_t readthisamountnow;
1495 curl_off_t actuallyread;
1497 readthisamountnow = (data->state.resume_from - passed);
1499 if(readthisamountnow > BUFSIZE)
1500 readthisamountnow = BUFSIZE;
1503 (curl_off_t) conn->fread_func(data->state.buffer, 1,
1504 (size_t)readthisamountnow,
1507 passed += actuallyread;
1508 if((actuallyread <= 0) || (actuallyread > readthisamountnow)) {
1509 /* this checks for greater-than only to make sure that the
1510 CURL_READFUNC_ABORT return code still aborts */
1511 failf(data, "Failed to read data");
1512 return CURLE_FTP_COULDNT_USE_REST;
1514 } while(passed < data->state.resume_from);
1518 /* now, decrease the size of the read */
1519 if(data->set.infilesize>0) {
1520 data->set.infilesize -= data->state.resume_from;
1521 data->req.size = data->set.infilesize;
1522 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1525 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1527 if(data->set.infilesize>0) {
1528 data->req.size = data->set.infilesize;
1529 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1532 result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL,
1535 /* not set by Curl_setup_transfer to preserve keepon bits */
1536 conn->sockfd = conn->writesockfd;
1539 state(conn, SSH_SFTP_CLOSE);
1540 sshc->actualcode = result;
1543 /* store this original bitmask setup to use later on if we can't
1544 figure out a "real" bitmask */
1545 sshc->orig_waitfor = data->req.keepon;
1547 state(conn, SSH_STOP);
1552 case SSH_SFTP_CREATE_DIRS_INIT:
1553 if(strlen(sftp_scp->path) > 1) {
1554 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1555 state(conn, SSH_SFTP_CREATE_DIRS);
1558 state(conn, SSH_SFTP_UPLOAD_INIT);
1562 case SSH_SFTP_CREATE_DIRS:
1563 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1564 *sshc->slash_pos = 0;
1566 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1567 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1571 state(conn, SSH_SFTP_UPLOAD_INIT);
1575 case SSH_SFTP_CREATE_DIRS_MKDIR:
1576 /* 'mode' - parameter is preliminary - default to 0644 */
1577 rc = libssh2_sftp_mkdir(sshc->sftp_session, sftp_scp->path,
1578 data->set.new_directory_perms);
1579 if(rc == LIBSSH2_ERROR_EAGAIN) {
1582 *sshc->slash_pos = '/';
1585 unsigned int sftp_err = 0;
1587 * Abort if failure wasn't that the dir already exists or the
1588 * permission was denied (creation might succeed further down the
1589 * path) - retry on unspecific FAILURE also
1591 sftp_err = libssh2_sftp_last_error(sshc->sftp_session);
1592 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1593 (sftp_err != LIBSSH2_FX_FAILURE) &&
1594 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1595 result = sftp_libssh2_error_to_CURLE(sftp_err);
1596 state(conn, SSH_SFTP_CLOSE);
1597 sshc->actualcode = result?result:CURLE_SSH;
1601 state(conn, SSH_SFTP_CREATE_DIRS);
1604 case SSH_SFTP_READDIR_INIT:
1606 * This is a directory that we are trying to get, so produce a directory
1609 sshc->sftp_handle = libssh2_sftp_opendir(sshc->sftp_session,
1611 if(!sshc->sftp_handle) {
1612 if(libssh2_session_last_errno(sshc->ssh_session) ==
1613 LIBSSH2_ERROR_EAGAIN) {
1614 rc = LIBSSH2_ERROR_EAGAIN;
1618 err = libssh2_sftp_last_error(sshc->sftp_session);
1619 failf(data, "Could not open directory for reading: %s",
1620 sftp_libssh2_strerror(err));
1621 state(conn, SSH_SFTP_CLOSE);
1622 result = sftp_libssh2_error_to_CURLE(err);
1623 sshc->actualcode = result?result:CURLE_SSH;
1627 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1628 state(conn, SSH_SFTP_CLOSE);
1629 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1632 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1633 Curl_safefree(sshc->readdir_filename);
1634 sshc->readdir_filename = NULL;
1635 state(conn, SSH_SFTP_CLOSE);
1636 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1639 state(conn, SSH_SFTP_READDIR);
1642 case SSH_SFTP_READDIR:
1643 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1644 sshc->readdir_filename,
1646 sshc->readdir_longentry,
1648 &sshc->readdir_attrs);
1649 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1650 rc = LIBSSH2_ERROR_EAGAIN;
1653 if(sshc->readdir_len > 0) {
1654 sshc->readdir_filename[sshc->readdir_len] = '\0';
1656 if(data->set.ftp_list_only) {
1659 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1660 if(tmpLine == NULL) {
1661 state(conn, SSH_SFTP_CLOSE);
1662 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1665 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1666 tmpLine, sshc->readdir_len+1);
1667 Curl_safefree(tmpLine);
1670 state(conn, SSH_STOP);
1673 /* since this counts what we send to the client, we include the
1674 newline in this counter */
1675 data->req.bytecount += sshc->readdir_len+1;
1677 /* output debug output if that is requested */
1678 if(data->set.verbose) {
1679 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1680 sshc->readdir_len, conn);
1684 sshc->readdir_currLen = strlen(sshc->readdir_longentry);
1685 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1686 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1687 if(!sshc->readdir_line) {
1688 Curl_safefree(sshc->readdir_filename);
1689 sshc->readdir_filename = NULL;
1690 Curl_safefree(sshc->readdir_longentry);
1691 sshc->readdir_longentry = NULL;
1692 state(conn, SSH_SFTP_CLOSE);
1693 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1697 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1698 sshc->readdir_currLen);
1699 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1700 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1701 LIBSSH2_SFTP_S_IFLNK)) {
1702 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1703 if(sshc->readdir_linkPath == NULL) {
1704 Curl_safefree(sshc->readdir_filename);
1705 sshc->readdir_filename = NULL;
1706 Curl_safefree(sshc->readdir_longentry);
1707 sshc->readdir_longentry = NULL;
1708 state(conn, SSH_SFTP_CLOSE);
1709 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1713 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1714 sshc->readdir_filename);
1715 state(conn, SSH_SFTP_READDIR_LINK);
1718 state(conn, SSH_SFTP_READDIR_BOTTOM);
1722 else if(sshc->readdir_len == 0) {
1723 Curl_safefree(sshc->readdir_filename);
1724 sshc->readdir_filename = NULL;
1725 Curl_safefree(sshc->readdir_longentry);
1726 sshc->readdir_longentry = NULL;
1727 state(conn, SSH_SFTP_READDIR_DONE);
1730 else if(sshc->readdir_len <= 0) {
1731 err = libssh2_sftp_last_error(sshc->sftp_session);
1732 result = sftp_libssh2_error_to_CURLE(err);
1733 sshc->actualcode = result?result:CURLE_SSH;
1734 failf(data, "Could not open remote file for reading: %s :: %d",
1735 sftp_libssh2_strerror(err),
1736 libssh2_session_last_errno(sshc->ssh_session));
1737 Curl_safefree(sshc->readdir_filename);
1738 sshc->readdir_filename = NULL;
1739 Curl_safefree(sshc->readdir_longentry);
1740 sshc->readdir_longentry = NULL;
1741 state(conn, SSH_SFTP_CLOSE);
1746 case SSH_SFTP_READDIR_LINK:
1747 sshc->readdir_len = libssh2_sftp_readlink(sshc->sftp_session,
1748 sshc->readdir_linkPath,
1749 sshc->readdir_filename,
1751 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1752 rc = LIBSSH2_ERROR_EAGAIN;
1755 Curl_safefree(sshc->readdir_linkPath);
1756 sshc->readdir_linkPath = NULL;
1757 sshc->readdir_line = realloc(sshc->readdir_line,
1758 sshc->readdir_totalLen + 4 +
1760 if(!sshc->readdir_line) {
1761 Curl_safefree(sshc->readdir_filename);
1762 sshc->readdir_filename = NULL;
1763 Curl_safefree(sshc->readdir_longentry);
1764 sshc->readdir_longentry = NULL;
1765 state(conn, SSH_SFTP_CLOSE);
1766 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1770 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1771 sshc->readdir_currLen,
1772 sshc->readdir_totalLen -
1773 sshc->readdir_currLen,
1775 sshc->readdir_filename);
1777 state(conn, SSH_SFTP_READDIR_BOTTOM);
1780 case SSH_SFTP_READDIR_BOTTOM:
1781 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1782 sshc->readdir_currLen,
1783 sshc->readdir_totalLen -
1784 sshc->readdir_currLen, "\n");
1785 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1787 sshc->readdir_currLen);
1789 if(result == CURLE_OK) {
1791 /* output debug output if that is requested */
1792 if(data->set.verbose) {
1793 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1794 sshc->readdir_currLen, conn);
1796 data->req.bytecount += sshc->readdir_currLen;
1798 Curl_safefree(sshc->readdir_line);
1799 sshc->readdir_line = NULL;
1801 state(conn, SSH_STOP);
1804 state(conn, SSH_SFTP_READDIR);
1807 case SSH_SFTP_READDIR_DONE:
1808 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1809 LIBSSH2_ERROR_EAGAIN) {
1810 rc = LIBSSH2_ERROR_EAGAIN;
1813 sshc->sftp_handle = NULL;
1814 Curl_safefree(sshc->readdir_filename);
1815 sshc->readdir_filename = NULL;
1816 Curl_safefree(sshc->readdir_longentry);
1817 sshc->readdir_longentry = NULL;
1819 /* no data to transfer */
1820 result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1821 state(conn, SSH_STOP);
1824 case SSH_SFTP_DOWNLOAD_INIT:
1826 * Work on getting the specified file
1829 libssh2_sftp_open(sshc->sftp_session, sftp_scp->path,
1830 LIBSSH2_FXF_READ, data->set.new_file_perms);
1831 if(!sshc->sftp_handle) {
1832 if(libssh2_session_last_errno(sshc->ssh_session) ==
1833 LIBSSH2_ERROR_EAGAIN) {
1834 rc = LIBSSH2_ERROR_EAGAIN;
1838 err = libssh2_sftp_last_error(sshc->sftp_session);
1839 failf(data, "Could not open remote file for reading: %s",
1840 sftp_libssh2_strerror(err));
1841 state(conn, SSH_SFTP_CLOSE);
1842 result = sftp_libssh2_error_to_CURLE(err);
1843 sshc->actualcode = result?result:CURLE_SSH;
1847 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1850 case SSH_SFTP_DOWNLOAD_STAT:
1852 LIBSSH2_SFTP_ATTRIBUTES attrs;
1854 rc = libssh2_sftp_stat(sshc->sftp_session, sftp_scp->path, &attrs);
1855 if(rc == LIBSSH2_ERROR_EAGAIN) {
1860 * libssh2_sftp_open() didn't return an error, so maybe the server
1861 * just doesn't support stat()
1863 data->req.size = -1;
1864 data->req.maxdownload = -1;
1869 size = attrs.filesize;
1870 if(conn->data->state.use_range) {
1871 curl_off_t from, to;
1875 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
1876 while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-')))
1878 to=curlx_strtoofft(ptr, &ptr2, 0);
1879 if((ptr == ptr2) /* no "to" value given */
1884 /* from is relative to end of file */
1888 failf(data, "Offset (%"
1889 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1890 from, attrs.filesize);
1891 return CURLE_BAD_DOWNLOAD_RESUME;
1898 size = to - from + 1;
1901 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
1903 data->req.size = size;
1904 data->req.maxdownload = size;
1905 Curl_pgrsSetDownloadSize(data, size);
1908 /* We can resume if we can seek to the resume position */
1909 if(data->state.resume_from) {
1910 if(data->state.resume_from< 0) {
1911 /* We're supposed to download the last abs(from) bytes */
1912 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
1913 failf(data, "Offset (%"
1914 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
1915 data->state.resume_from, attrs.filesize);
1916 return CURLE_BAD_DOWNLOAD_RESUME;
1918 /* download from where? */
1919 data->state.resume_from = attrs.filesize - data->state.resume_from;
1922 if((curl_off_t)attrs.filesize < data->state.resume_from) {
1923 failf(data, "Offset (%" FORMAT_OFF_T
1924 ") was beyond file size (%" FORMAT_OFF_T ")",
1925 data->state.resume_from, attrs.filesize);
1926 return CURLE_BAD_DOWNLOAD_RESUME;
1929 /* Does a completed file need to be seeked and started or closed ? */
1930 /* Now store the number of bytes we are expected to download */
1931 data->req.size = attrs.filesize - data->state.resume_from;
1932 data->req.maxdownload = attrs.filesize - data->state.resume_from;
1933 Curl_pgrsSetDownloadSize(data,
1934 attrs.filesize - data->state.resume_from);
1935 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1938 /* Setup the actual download */
1939 if(data->req.size == 0) {
1940 /* no data to transfer */
1941 result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1942 infof(data, "File already completely downloaded\n");
1943 state(conn, SSH_STOP);
1947 result = Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
1948 FALSE, NULL, -1, NULL);
1950 /* not set by Curl_setup_transfer to preserve keepon bits */
1951 conn->writesockfd = conn->sockfd;
1953 /* FIXME: here should be explained why we need it to start the download */
1954 conn->cselect_bits = CURL_CSELECT_IN;
1957 state(conn, SSH_SFTP_CLOSE);
1958 sshc->actualcode = result;
1961 state(conn, SSH_STOP);
1965 case SSH_SFTP_CLOSE:
1966 if(sshc->sftp_handle) {
1967 rc = libssh2_sftp_close(sshc->sftp_handle);
1968 if(rc == LIBSSH2_ERROR_EAGAIN) {
1972 infof(data, "Failed to close libssh2 file\n");
1974 sshc->sftp_handle = NULL;
1976 Curl_safefree(sftp_scp->path);
1977 sftp_scp->path = NULL;
1979 DEBUGF(infof(data, "SFTP DONE done\n"));
1981 state(conn, SSH_SFTP_SHUTDOWN);
1983 state(conn, SSH_STOP);
1984 result = sshc->actualcode;
1987 case SSH_SFTP_SHUTDOWN:
1988 /* during times we get here due to a broken transfer and then the
1989 sftp_handle might not have been taken down so make sure that is done
1990 before we proceed */
1992 if(sshc->sftp_handle) {
1993 rc = libssh2_sftp_close(sshc->sftp_handle);
1994 if(rc == LIBSSH2_ERROR_EAGAIN) {
1998 infof(data, "Failed to close libssh2 file\n");
2000 sshc->sftp_handle = NULL;
2002 if(sshc->sftp_session) {
2003 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2004 if(rc == LIBSSH2_ERROR_EAGAIN) {
2008 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2010 sshc->sftp_session = NULL;
2013 Curl_safefree(sshc->homedir);
2014 sshc->homedir = NULL;
2016 state(conn, SSH_SESSION_DISCONNECT);
2019 case SSH_SCP_TRANS_INIT:
2020 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2022 sshc->actualcode = result;
2023 state(conn, SSH_STOP);
2027 if(data->set.upload) {
2028 if(data->set.infilesize < 0) {
2029 failf(data, "SCP requires a known file size for upload");
2030 sshc->actualcode = CURLE_UPLOAD_FAILED;
2031 state(conn, SSH_SCP_CHANNEL_FREE);
2034 state(conn, SSH_SCP_UPLOAD_INIT);
2037 state(conn, SSH_SCP_DOWNLOAD_INIT);
2041 case SSH_SCP_UPLOAD_INIT:
2043 * libssh2 requires that the destination path is a full path that
2044 * includes the destination file and name OR ends in a "/" . If this is
2045 * not done the destination file will be named the same name as the last
2046 * directory in the path.
2049 libssh2_scp_send_ex(sshc->ssh_session, sftp_scp->path,
2050 data->set.new_file_perms,
2051 (size_t)data->set.infilesize, 0, 0);
2052 if(!sshc->ssh_channel) {
2053 if(libssh2_session_last_errno(sshc->ssh_session) ==
2054 LIBSSH2_ERROR_EAGAIN) {
2055 rc = LIBSSH2_ERROR_EAGAIN;
2062 ssh_err = libssh2_session_last_error(sshc->ssh_session,
2064 failf(conn->data, "%s", err_msg);
2065 state(conn, SSH_SCP_CHANNEL_FREE);
2066 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2072 result = Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2075 /* not set by Curl_setup_transfer to preserve keepon bits */
2076 conn->sockfd = conn->writesockfd;
2079 state(conn, SSH_SCP_CHANNEL_FREE);
2080 sshc->actualcode = result;
2083 state(conn, SSH_STOP);
2087 case SSH_SCP_DOWNLOAD_INIT:
2090 * We must check the remote file; if it is a directory no values will
2094 curl_off_t bytecount;
2096 /* clear the struct scp recv will fill in */
2097 memset(&sb, 0, sizeof(struct stat));
2099 /* get a fresh new channel from the ssh layer */
2100 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2101 sftp_scp->path, &sb);
2102 if(!sshc->ssh_channel) {
2103 if(libssh2_session_last_errno(sshc->ssh_session) ==
2104 LIBSSH2_ERROR_EAGAIN) {
2105 rc = LIBSSH2_ERROR_EAGAIN;
2112 ssh_err = libssh2_session_last_error(sshc->ssh_session,
2114 failf(conn->data, "%s", err_msg);
2115 state(conn, SSH_SCP_CHANNEL_FREE);
2116 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2122 bytecount = (curl_off_t)sb.st_size;
2123 data->req.maxdownload = (curl_off_t)sb.st_size;
2124 result = Curl_setup_transfer(conn, FIRSTSOCKET,
2125 bytecount, FALSE, NULL, -1, NULL);
2127 /* not set by Curl_setup_transfer to preserve keepon bits */
2128 conn->writesockfd = conn->sockfd;
2130 /* FIXME: here should be explained why we need it to start the download */
2131 conn->cselect_bits = CURL_CSELECT_IN;
2134 state(conn, SSH_SCP_CHANNEL_FREE);
2135 sshc->actualcode = result;
2138 state(conn, SSH_STOP);
2143 if(data->set.upload)
2144 state(conn, SSH_SCP_SEND_EOF);
2146 state(conn, SSH_SCP_CHANNEL_FREE);
2149 case SSH_SCP_SEND_EOF:
2150 if(sshc->ssh_channel) {
2151 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2152 if(rc == LIBSSH2_ERROR_EAGAIN) {
2156 infof(data, "Failed to send libssh2 channel EOF\n");
2159 state(conn, SSH_SCP_WAIT_EOF);
2162 case SSH_SCP_WAIT_EOF:
2163 if(sshc->ssh_channel) {
2164 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2165 if(rc == LIBSSH2_ERROR_EAGAIN) {
2169 infof(data, "Failed to get channel EOF: %d\n", rc);
2172 state(conn, SSH_SCP_WAIT_CLOSE);
2175 case SSH_SCP_WAIT_CLOSE:
2176 if(sshc->ssh_channel) {
2177 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2178 if(rc == LIBSSH2_ERROR_EAGAIN) {
2182 infof(data, "Channel failed to close: %d\n", rc);
2185 state(conn, SSH_SCP_CHANNEL_FREE);
2188 case SSH_SCP_CHANNEL_FREE:
2189 if(sshc->ssh_channel) {
2190 rc = libssh2_channel_free(sshc->ssh_channel);
2191 if(rc == LIBSSH2_ERROR_EAGAIN) {
2195 infof(data, "Failed to free libssh2 scp subsystem\n");
2197 sshc->ssh_channel = NULL;
2199 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2201 state(conn, SSH_SESSION_DISCONNECT);
2203 state(conn, SSH_STOP);
2204 result = sshc->actualcode;
2207 case SSH_SESSION_DISCONNECT:
2208 /* during weird times when we've been prematurely aborted, the channel
2209 is still alive when we reach this state and we MUST kill the channel
2211 if(sshc->ssh_channel) {
2212 rc = libssh2_channel_free(sshc->ssh_channel);
2213 if(rc == LIBSSH2_ERROR_EAGAIN) {
2217 infof(data, "Failed to free libssh2 scp subsystem\n");
2219 sshc->ssh_channel = NULL;
2222 if(sshc->ssh_session) {
2223 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2224 if(rc == LIBSSH2_ERROR_EAGAIN) {
2228 infof(data, "Failed to disconnect libssh2 session\n");
2232 Curl_safefree(sshc->homedir);
2233 sshc->homedir = NULL;
2235 state(conn, SSH_SESSION_FREE);
2238 case SSH_SESSION_FREE:
2239 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2241 libssh2_knownhost_free(sshc->kh);
2246 if(sshc->ssh_session) {
2247 rc = libssh2_session_free(sshc->ssh_session);
2248 if(rc == LIBSSH2_ERROR_EAGAIN) {
2252 infof(data, "Failed to free libssh2 session\n");
2254 sshc->ssh_session = NULL;
2256 conn->bits.close = TRUE;
2257 sshc->nextstate = SSH_NO_STATE;
2258 state(conn, SSH_STOP);
2259 result = sshc->actualcode;
2263 /* fallthrough, just stop! */
2265 /* internal error */
2266 sshc->nextstate = SSH_NO_STATE;
2267 state(conn, SSH_STOP);
2271 } while(!rc && (sshc->state != SSH_STOP));
2273 if(rc == LIBSSH2_ERROR_EAGAIN) {
2274 /* we would block, we need to wait for the socket to be ready (in the
2275 right direction too)! */
2282 /* called by the multi interface to figure out what socket(s) to wait for and
2283 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2284 static int ssh_perform_getsock(const struct connectdata *conn,
2285 curl_socket_t *sock, /* points to numsocks
2286 number of sockets */
2289 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2290 int bitmap = GETSOCK_BLANK;
2293 sock[0] = conn->sock[FIRSTSOCKET];
2295 if(conn->waitfor & KEEP_RECV)
2296 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2298 if(conn->waitfor & KEEP_SEND)
2299 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2303 /* if we don't know the direction we can use the generic *_getsock()
2304 function even for the protocol_connect and doing states */
2305 return Curl_single_getsock(conn, sock, numsocks);
2309 /* Generic function called by the multi interface to figure out what socket(s)
2310 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2311 static int ssh_getsock(struct connectdata *conn,
2312 curl_socket_t *sock, /* points to numsocks number
2316 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2320 /* if we don't know any direction we can just play along as we used to and
2321 not provide any sensible info */
2322 return GETSOCK_BLANK;
2324 /* if we know the direction we can use the generic *_getsock() function even
2325 for the protocol_connect and doing states */
2326 return ssh_perform_getsock(conn, sock, numsocks);
2330 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2332 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2333 * function is used to figure out in what direction and stores this info so
2334 * that the multi interface can take advantage of it. Make sure to call this
2335 * function in all cases so that when it _doesn't_ return EAGAIN we can
2336 * restore the default wait bits.
2338 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2340 struct ssh_conn *sshc = &conn->proto.sshc;
2344 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2345 /* translate the libssh2 define bits into our own bit defines */
2346 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2347 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2350 /* It didn't block or libssh2 didn't reveal in which direction, put back
2352 conn->waitfor = sshc->orig_waitfor;
2355 /* no libssh2 directional support so we simply don't know */
2356 #define ssh_block2waitfor(x,y)
2359 /* called repeatedly until done from multi.c */
2360 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2362 struct ssh_conn *sshc = &conn->proto.sshc;
2363 CURLcode result = CURLE_OK;
2364 bool block; /* we store the status and use that to provide a ssh_getsock()
2367 result = ssh_statemach_act(conn, &block);
2368 *done = (bool)(sshc->state == SSH_STOP);
2369 ssh_block2waitfor(conn, block);
2374 static CURLcode ssh_easy_statemach(struct connectdata *conn)
2376 struct ssh_conn *sshc = &conn->proto.sshc;
2377 CURLcode result = CURLE_OK;
2379 while((sshc->state != SSH_STOP) && !result) {
2381 result = ssh_statemach_act(conn, &block);
2383 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2384 if((CURLE_OK == result) && block) {
2385 int dir = libssh2_session_block_directions(sshc->ssh_session);
2386 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2387 curl_socket_t fd_read = CURL_SOCKET_BAD;
2388 curl_socket_t fd_write = CURL_SOCKET_BAD;
2389 if (LIBSSH2_SESSION_BLOCK_INBOUND & dir) {
2392 if (LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) {
2395 /* wait for the socket to become ready */
2396 Curl_socket_ready(fd_read, fd_write, 1000); /* ignore result */
2406 * SSH setup and connection
2408 static CURLcode ssh_init(struct connectdata *conn)
2410 struct SessionHandle *data = conn->data;
2411 struct SSHPROTO *ssh;
2412 struct ssh_conn *sshc = &conn->proto.sshc;
2414 sshc->actualcode = CURLE_OK; /* reset error code */
2415 sshc->secondCreateDirs =0; /* reset the create dir attempt state variable */
2417 if(data->state.proto.ssh)
2420 ssh = calloc(1, sizeof(struct SSHPROTO));
2422 return CURLE_OUT_OF_MEMORY;
2424 data->state.proto.ssh = ssh;
2430 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2431 * do protocol-specific actions at connect-time.
2433 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2435 #ifdef CURL_LIBSSH2_DEBUG
2438 struct ssh_conn *ssh;
2440 struct SessionHandle *data = conn->data;
2442 /* We default to persistent connections. We set this already in this connect
2443 function to make the re-use checks properly be able to check this bit. */
2444 conn->bits.close = FALSE;
2446 /* If there already is a protocol-specific struct allocated for this
2447 sessionhandle, deal with it */
2448 Curl_reset_reqproto(conn);
2450 result = ssh_init(conn);
2454 ssh = &conn->proto.sshc;
2456 #ifdef CURL_LIBSSH2_DEBUG
2458 infof(data, "User: %s\n", conn->user);
2461 infof(data, "Password: %s\n", conn->passwd);
2463 sock = conn->sock[FIRSTSOCKET];
2464 #endif /* CURL_LIBSSH2_DEBUG */
2466 ssh->ssh_session = libssh2_session_init_ex(libssh2_malloc, libssh2_free,
2467 libssh2_realloc, conn);
2468 if(ssh->ssh_session == NULL) {
2469 failf(data, "Failure initialising ssh session");
2470 return CURLE_FAILED_INIT;
2473 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2474 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2476 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2478 /* eeek. TODO: free the ssh_session! */
2479 return CURLE_FAILED_INIT;
2482 /* read all known hosts from there */
2483 rc = libssh2_knownhost_readfile(ssh->kh,
2484 data->set.str[STRING_SSH_KNOWNHOSTS],
2485 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2487 infof(data, "Failed to read known hosts from %s\n",
2488 data->set.str[STRING_SSH_KNOWNHOSTS]);
2491 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2493 #ifdef CURL_LIBSSH2_DEBUG
2494 libssh2_trace(ssh->ssh_session, ~0);
2495 infof(data, "SSH socket: %d\n", (int)sock);
2496 #endif /* CURL_LIBSSH2_DEBUG */
2498 state(conn, SSH_S_STARTUP);
2500 if(data->state.used_interface == Curl_if_multi)
2501 result = ssh_multi_statemach(conn, done);
2503 result = ssh_easy_statemach(conn);
2512 ***********************************************************************
2516 * This is the actual DO function for SCP. Get a file according to
2517 * the options previously setup.
2521 CURLcode scp_perform(struct connectdata *conn,
2525 CURLcode result = CURLE_OK;
2527 DEBUGF(infof(conn->data, "DO phase starts\n"));
2529 *dophase_done = FALSE; /* not done yet */
2531 /* start the first command in the DO phase */
2532 state(conn, SSH_SCP_TRANS_INIT);
2534 /* run the state-machine */
2535 if(conn->data->state.used_interface == Curl_if_multi) {
2536 result = ssh_multi_statemach(conn, dophase_done);
2539 result = ssh_easy_statemach(conn);
2540 *dophase_done = TRUE; /* with the easy interface we are done here */
2542 *connected = conn->bits.tcpconnect;
2545 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2551 /* called from multi.c while DOing */
2552 static CURLcode scp_doing(struct connectdata *conn,
2556 result = ssh_multi_statemach(conn, dophase_done);
2559 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2565 * The DO function is generic for both protocols. There was previously two
2566 * separate ones but this way means less duplicated code.
2569 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2573 struct SessionHandle *data = conn->data;
2575 *done = FALSE; /* default to false */
2578 Since connections can be re-used between SessionHandles, this might be a
2579 connection already existing but on a fresh SessionHandle struct so we must
2580 make sure we have a good 'struct SSHPROTO' to play with. For new
2581 connections, the struct SSHPROTO is allocated and setup in the
2582 ssh_connect() function.
2584 Curl_reset_reqproto(conn);
2585 res = ssh_init(conn);
2589 data->req.size = -1; /* make sure this is unknown at this point */
2591 Curl_pgrsSetUploadCounter(data, 0);
2592 Curl_pgrsSetDownloadCounter(data, 0);
2593 Curl_pgrsSetUploadSize(data, 0);
2594 Curl_pgrsSetDownloadSize(data, 0);
2596 if(conn->protocol & PROT_SCP)
2597 res = scp_perform(conn, &connected, done);
2599 res = sftp_perform(conn, &connected, done);
2604 /* BLOCKING, but the function is using the state machine so the only reason this
2605 is still blocking is that the multi interface code has no support for
2606 disconnecting operations that takes a while */
2607 static CURLcode scp_disconnect(struct connectdata *conn)
2609 CURLcode result = CURLE_OK;
2610 struct ssh_conn *ssh = &conn->proto.sshc;
2612 Curl_safefree(conn->data->state.proto.ssh);
2613 conn->data->state.proto.ssh = NULL;
2615 if(ssh->ssh_session) {
2616 /* only if there's a session still around to use! */
2618 state(conn, SSH_SESSION_DISCONNECT);
2620 result = ssh_easy_statemach(conn);
2626 /* generic done function for both SCP and SFTP called from their specific
2628 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2630 CURLcode result = CURLE_OK;
2631 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2633 if(status == CURLE_OK) {
2634 /* run the state-machine
2636 TODO: when the multi interface this _really_ should be using the
2637 ssh_multi_statemach function but we have no general support for
2638 non-blocking DONE operations, not in the multi state machine and with
2639 Curl_done() invokes on several places in the code!
2641 result = ssh_easy_statemach(conn);
2646 Curl_safefree(sftp_scp->path);
2647 sftp_scp->path = NULL;
2648 Curl_pgrsDone(conn);
2650 conn->data->req.keepon = 0; /* clear all bits */
2655 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2658 (void)premature; /* not used */
2660 if(status == CURLE_OK)
2661 state(conn, SSH_SCP_DONE);
2663 return ssh_done(conn, status);
2667 /* return number of received (decrypted) bytes */
2668 ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
2669 const void *mem, size_t len)
2672 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2674 /* libssh2_channel_write() returns int! */
2676 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2678 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2680 if(nwrite == LIBSSH2_ERROR_EAGAIN)
2687 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2688 * a regular CURLcode value.
2690 ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex,
2691 char *mem, size_t len)
2694 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2696 /* libssh2_channel_read() returns int */
2698 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2700 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2706 * =============== SFTP ===============
2710 ***********************************************************************
2714 * This is the actual DO function for SFTP. Get a file/directory according to
2715 * the options previously setup.
2719 CURLcode sftp_perform(struct connectdata *conn,
2723 CURLcode result = CURLE_OK;
2725 DEBUGF(infof(conn->data, "DO phase starts\n"));
2727 *dophase_done = FALSE; /* not done yet */
2729 /* start the first command in the DO phase */
2730 state(conn, SSH_SFTP_QUOTE_INIT);
2732 /* run the state-machine */
2733 if(conn->data->state.used_interface == Curl_if_multi) {
2734 result = ssh_multi_statemach(conn, dophase_done);
2737 result = ssh_easy_statemach(conn);
2738 *dophase_done = TRUE; /* with the easy interface we are done here */
2740 *connected = conn->bits.tcpconnect;
2743 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2749 /* called from multi.c while DOing */
2750 static CURLcode sftp_doing(struct connectdata *conn,
2754 result = ssh_multi_statemach(conn, dophase_done);
2757 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2762 /* BLOCKING, but the function is using the state machine so the only reason this
2763 is still blocking is that the multi interface code has no support for
2764 disconnecting operations that takes a while */
2765 static CURLcode sftp_disconnect(struct connectdata *conn)
2767 CURLcode result = CURLE_OK;
2769 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
2771 Curl_safefree(conn->data->state.proto.ssh);
2772 conn->data->state.proto.ssh = NULL;
2774 if(conn->proto.sshc.ssh_session) {
2775 /* only if there's a session still around to use! */
2776 state(conn, SSH_SFTP_SHUTDOWN);
2777 result = ssh_easy_statemach(conn);
2780 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
2786 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
2789 struct ssh_conn *sshc = &conn->proto.sshc;
2791 if(status == CURLE_OK) {
2792 /* Before we shut down, see if there are any post-quote commands to send: */
2793 if(!status && !premature && conn->data->set.postquote) {
2794 sshc->nextstate = SSH_SFTP_CLOSE;
2795 state(conn, SSH_SFTP_POSTQUOTE_INIT);
2798 state(conn, SSH_SFTP_CLOSE);
2800 return ssh_done(conn, status);
2803 /* return number of sent bytes */
2804 ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
2805 const void *mem, size_t len)
2807 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
2808 but is changed to ssize_t in 0.15. These days we don't
2809 support libssh2 0.15*/
2812 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
2814 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2816 if(nwrite == LIBSSH2_ERROR_EAGAIN)
2823 * Return number of received (decrypted) bytes
2825 ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
2826 char *mem, size_t len)
2831 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
2833 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2838 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
2841 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
2843 * Permission to use, copy, modify, and distribute this software for any
2844 * purpose with or without fee is hereby granted, provided that the above
2845 * copyright notice and this permission notice appear in all copies.
2847 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2848 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2849 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2850 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2851 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2852 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2853 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2856 get_pathname(const char **cpp, char **path)
2858 const char *cp = *cpp, *end;
2861 static const char WHITESPACE[] = " \t\r\n";
2863 cp += strspn(cp, WHITESPACE);
2867 return CURLE_QUOTE_ERROR;
2870 *path = malloc(strlen(cp) + 1);
2872 return CURLE_OUT_OF_MEMORY;
2874 /* Check for quoted filenames */
2875 if(*cp == '\"' || *cp == '\'') {
2878 /* Search for terminating quote, unescape some chars */
2879 for (i = j = 0; i <= strlen(cp); i++) {
2880 if(cp[i] == quot) { /* Found quote */
2885 if(cp[i] == '\0') { /* End of string */
2886 /*error("Unterminated quote");*/
2889 if(cp[i] == '\\') { /* Escaped characters */
2891 if(cp[i] != '\'' && cp[i] != '\"' &&
2893 /*error("Bad escaped character '\\%c'",
2898 (*path)[j++] = cp[i];
2902 /*error("Empty quotes");*/
2905 *cpp = cp + i + strspn(cp + i, WHITESPACE);
2908 /* Read to end of filename */
2909 end = strpbrk(cp, WHITESPACE);
2911 end = strchr(cp, '\0');
2912 *cpp = end + strspn(end, WHITESPACE);
2914 memcpy(*path, cp, end - cp);
2915 (*path)[end - cp] = '\0';
2920 Curl_safefree(*path);
2922 return CURLE_QUOTE_ERROR;
2926 static const char *sftp_libssh2_strerror(unsigned long err)
2929 case LIBSSH2_FX_NO_SUCH_FILE:
2930 return "No such file or directory";
2932 case LIBSSH2_FX_PERMISSION_DENIED:
2933 return "Permission denied";
2935 case LIBSSH2_FX_FAILURE:
2936 return "Operation failed";
2938 case LIBSSH2_FX_BAD_MESSAGE:
2939 return "Bad message from SFTP server";
2941 case LIBSSH2_FX_NO_CONNECTION:
2942 return "Not connected to SFTP server";
2944 case LIBSSH2_FX_CONNECTION_LOST:
2945 return "Connection to SFTP server lost";
2947 case LIBSSH2_FX_OP_UNSUPPORTED:
2948 return "Operation not supported by SFTP server";
2950 case LIBSSH2_FX_INVALID_HANDLE:
2951 return "Invalid handle";
2953 case LIBSSH2_FX_NO_SUCH_PATH:
2954 return "No such file or directory";
2956 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
2957 return "File already exists";
2959 case LIBSSH2_FX_WRITE_PROTECT:
2960 return "File is write protected";
2962 case LIBSSH2_FX_NO_MEDIA:
2965 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
2968 case LIBSSH2_FX_QUOTA_EXCEEDED:
2969 return "User quota exceeded";
2971 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
2972 return "Unknown principle";
2974 case LIBSSH2_FX_LOCK_CONFlICT:
2975 return "File lock conflict";
2977 case LIBSSH2_FX_DIR_NOT_EMPTY:
2978 return "Directory not empty";
2980 case LIBSSH2_FX_NOT_A_DIRECTORY:
2981 return "Not a directory";
2983 case LIBSSH2_FX_INVALID_FILENAME:
2984 return "Invalid filename";
2986 case LIBSSH2_FX_LINK_LOOP:
2987 return "Link points to itself";
2989 return "Unknown error in libssh2";
2992 #endif /* USE_LIBSSH2 */