1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 /* #define CURL_LIBSSH2_DEBUG */
25 #include "curl_setup.h"
34 #include <libssh2_sftp.h>
40 #ifdef HAVE_NETINET_IN_H
41 #include <netinet/in.h>
43 #ifdef HAVE_ARPA_INET_H
44 #include <arpa/inet.h>
47 #include <sys/utsname.h>
57 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
59 #define in_addr_t unsigned long
62 #include <curl/curl.h>
69 #include "http.h" /* for HTTP proxy tunnel stuff */
72 #include "speedcheck.h"
76 #include "vtls/vtls.h"
79 #include "inet_ntop.h"
80 #include "parsedate.h" /* for the week day and month names */
81 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
82 #include "strtoofft.h"
87 #define _MPRINTF_REPLACE /* use our functions only */
88 #include <curl/mprintf.h>
90 #include "curl_memory.h"
91 /* The last #include file should be: */
96 # define PATH_MAX MAX_PATH
103 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
104 have their definition hidden well */
107 #define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
109 #define sftp_libssh2_realpath(s,p,t,m) \
110 libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
111 (t), (m), LIBSSH2_SFTP_REALPATH)
113 /* Local functions: */
114 static const char *sftp_libssh2_strerror(int err);
115 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
116 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
117 static LIBSSH2_FREE_FUNC(my_libssh2_free);
119 static CURLcode get_pathname(const char **cpp, char **path);
121 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
122 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
123 static CURLcode ssh_do(struct connectdata *conn, bool *done);
125 static CURLcode ssh_getworkingpath(struct connectdata *conn,
126 char *homedir, /* when SFTP is used */
129 static CURLcode scp_done(struct connectdata *conn,
130 CURLcode, bool premature);
131 static CURLcode scp_doing(struct connectdata *conn,
133 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
135 static CURLcode sftp_done(struct connectdata *conn,
136 CURLcode, bool premature);
137 static CURLcode sftp_doing(struct connectdata *conn,
139 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
141 CURLcode sftp_perform(struct connectdata *conn,
145 static int ssh_getsock(struct connectdata *conn,
146 curl_socket_t *sock, /* points to numsocks number
150 static int ssh_perform_getsock(const struct connectdata *conn,
151 curl_socket_t *sock, /* points to numsocks
155 static CURLcode ssh_setup_connection(struct connectdata *conn);
158 * SCP protocol handler.
161 const struct Curl_handler Curl_handler_scp = {
163 ssh_setup_connection, /* setup_connection */
166 ZERO_NULL, /* do_more */
167 ssh_connect, /* connect_it */
168 ssh_multi_statemach, /* connecting */
169 scp_doing, /* doing */
170 ssh_getsock, /* proto_getsock */
171 ssh_getsock, /* doing_getsock */
172 ZERO_NULL, /* domore_getsock */
173 ssh_perform_getsock, /* perform_getsock */
174 scp_disconnect, /* disconnect */
175 ZERO_NULL, /* readwrite */
176 PORT_SSH, /* defport */
177 CURLPROTO_SCP, /* protocol */
178 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
179 | PROTOPT_NOURLQUERY /* flags */
184 * SFTP protocol handler.
187 const struct Curl_handler Curl_handler_sftp = {
189 ssh_setup_connection, /* setup_connection */
191 sftp_done, /* done */
192 ZERO_NULL, /* do_more */
193 ssh_connect, /* connect_it */
194 ssh_multi_statemach, /* connecting */
195 sftp_doing, /* doing */
196 ssh_getsock, /* proto_getsock */
197 ssh_getsock, /* doing_getsock */
198 ZERO_NULL, /* domore_getsock */
199 ssh_perform_getsock, /* perform_getsock */
200 sftp_disconnect, /* disconnect */
201 ZERO_NULL, /* readwrite */
202 PORT_SSH, /* defport */
203 CURLPROTO_SFTP, /* protocol */
204 PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
205 | PROTOPT_NOURLQUERY /* flags */
209 kbd_callback(const char *name, int name_len, const char *instruction,
210 int instruction_len, int num_prompts,
211 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
212 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
215 struct connectdata *conn = (struct connectdata *)*abstract;
217 #ifdef CURL_LIBSSH2_DEBUG
218 fprintf(stderr, "name=%s\n", name);
219 fprintf(stderr, "name_len=%d\n", name_len);
220 fprintf(stderr, "instruction=%s\n", instruction);
221 fprintf(stderr, "instruction_len=%d\n", instruction_len);
222 fprintf(stderr, "num_prompts=%d\n", num_prompts);
227 (void)instruction_len;
228 #endif /* CURL_LIBSSH2_DEBUG */
229 if(num_prompts == 1) {
230 responses[0].text = strdup(conn->passwd);
231 responses[0].length = curlx_uztoui(strlen(conn->passwd));
237 static CURLcode sftp_libssh2_error_to_CURLE(int err)
243 case LIBSSH2_FX_NO_SUCH_FILE:
244 case LIBSSH2_FX_NO_SUCH_PATH:
245 return CURLE_REMOTE_FILE_NOT_FOUND;
247 case LIBSSH2_FX_PERMISSION_DENIED:
248 case LIBSSH2_FX_WRITE_PROTECT:
249 case LIBSSH2_FX_LOCK_CONFlICT:
250 return CURLE_REMOTE_ACCESS_DENIED;
252 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
253 case LIBSSH2_FX_QUOTA_EXCEEDED:
254 return CURLE_REMOTE_DISK_FULL;
256 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
257 return CURLE_REMOTE_FILE_EXISTS;
259 case LIBSSH2_FX_DIR_NOT_EMPTY:
260 return CURLE_QUOTE_ERROR;
269 static CURLcode libssh2_session_error_to_CURLE(int err)
272 /* Ordered by order of appearance in libssh2.h */
273 case LIBSSH2_ERROR_NONE:
276 case LIBSSH2_ERROR_SOCKET_NONE:
277 return CURLE_COULDNT_CONNECT;
279 case LIBSSH2_ERROR_ALLOC:
280 return CURLE_OUT_OF_MEMORY;
282 case LIBSSH2_ERROR_SOCKET_SEND:
283 return CURLE_SEND_ERROR;
285 case LIBSSH2_ERROR_HOSTKEY_INIT:
286 case LIBSSH2_ERROR_HOSTKEY_SIGN:
287 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
288 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
289 return CURLE_PEER_FAILED_VERIFICATION;
291 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
292 return CURLE_LOGIN_DENIED;
294 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
295 case LIBSSH2_ERROR_TIMEOUT:
296 return CURLE_OPERATION_TIMEDOUT;
298 case LIBSSH2_ERROR_EAGAIN:
302 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
303 error code, and possibly add a few new SSH-related one. We must however
304 not return or even depend on libssh2 errors in the public libcurl API */
309 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
311 (void)abstract; /* arg not used */
312 return malloc(count);
315 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
317 (void)abstract; /* arg not used */
318 return realloc(ptr, count);
321 static LIBSSH2_FREE_FUNC(my_libssh2_free)
323 (void)abstract; /* arg not used */
324 if(ptr) /* ssh2 agent sometimes call free with null ptr */
329 * SSH State machine related code
331 /* This is the ONLY way to change SSH state! */
332 static void state(struct connectdata *conn, sshstate nowstate)
334 struct ssh_conn *sshc = &conn->proto.sshc;
335 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
336 /* for debug purposes */
337 static const char * const names[] = {
343 "SSH_AUTH_PKEY_INIT",
345 "SSH_AUTH_PASS_INIT",
347 "SSH_AUTH_AGENT_INIT",
348 "SSH_AUTH_AGENT_LIST",
350 "SSH_AUTH_HOST_INIT",
357 "SSH_SFTP_QUOTE_INIT",
358 "SSH_SFTP_POSTQUOTE_INIT",
360 "SSH_SFTP_NEXT_QUOTE",
361 "SSH_SFTP_QUOTE_STAT",
362 "SSH_SFTP_QUOTE_SETSTAT",
363 "SSH_SFTP_QUOTE_SYMLINK",
364 "SSH_SFTP_QUOTE_MKDIR",
365 "SSH_SFTP_QUOTE_RENAME",
366 "SSH_SFTP_QUOTE_RMDIR",
367 "SSH_SFTP_QUOTE_UNLINK",
368 "SSH_SFTP_TRANS_INIT",
369 "SSH_SFTP_UPLOAD_INIT",
370 "SSH_SFTP_CREATE_DIRS_INIT",
371 "SSH_SFTP_CREATE_DIRS",
372 "SSH_SFTP_CREATE_DIRS_MKDIR",
373 "SSH_SFTP_READDIR_INIT",
375 "SSH_SFTP_READDIR_LINK",
376 "SSH_SFTP_READDIR_BOTTOM",
377 "SSH_SFTP_READDIR_DONE",
378 "SSH_SFTP_DOWNLOAD_INIT",
379 "SSH_SFTP_DOWNLOAD_STAT",
382 "SSH_SCP_TRANS_INIT",
383 "SSH_SCP_UPLOAD_INIT",
384 "SSH_SCP_DOWNLOAD_INIT",
388 "SSH_SCP_WAIT_CLOSE",
389 "SSH_SCP_CHANNEL_FREE",
390 "SSH_SESSION_DISCONNECT",
395 if(sshc->state != nowstate) {
396 infof(conn->data, "SFTP %p state change from %s to %s\n",
397 (void *)sshc, names[sshc->state], names[nowstate]);
401 sshc->state = nowstate;
404 /* figure out the path to work with in this particular request */
405 static CURLcode ssh_getworkingpath(struct connectdata *conn,
406 char *homedir, /* when SFTP is used */
407 char **path) /* returns the allocated
408 real path to work with */
410 struct SessionHandle *data = conn->data;
411 char *real_path = NULL;
413 int working_path_len;
415 working_path = curl_easy_unescape(data, data->state.path, 0,
418 return CURLE_OUT_OF_MEMORY;
420 /* Check for /~/ , indicating relative to the user's home directory */
421 if(conn->handler->protocol & CURLPROTO_SCP) {
422 real_path = malloc(working_path_len+1);
423 if(real_path == NULL) {
425 return CURLE_OUT_OF_MEMORY;
427 if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
428 /* It is referenced to the home directory, so strip the leading '/~/' */
429 memcpy(real_path, working_path+3, 4 + working_path_len-3);
431 memcpy(real_path, working_path, 1 + working_path_len);
433 else if(conn->handler->protocol & CURLPROTO_SFTP) {
434 if((working_path_len > 1) && (working_path[1] == '~')) {
435 size_t homelen = strlen(homedir);
436 real_path = malloc(homelen + working_path_len + 1);
437 if(real_path == NULL) {
439 return CURLE_OUT_OF_MEMORY;
441 /* It is referenced to the home directory, so strip the
443 memcpy(real_path, homedir, homelen);
444 real_path[homelen] = '/';
445 real_path[homelen+1] = '\0';
446 if(working_path_len > 3) {
447 memcpy(real_path+homelen+1, working_path + 3,
448 1 + working_path_len -3);
452 real_path = malloc(working_path_len+1);
453 if(real_path == NULL) {
455 return CURLE_OUT_OF_MEMORY;
457 memcpy(real_path, working_path, 1+working_path_len);
463 /* store the pointer for the caller to receive */
469 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
470 static int sshkeycallback(CURL *easy,
471 const struct curl_khkey *knownkey, /* known */
472 const struct curl_khkey *foundkey, /* found */
473 enum curl_khmatch match,
481 /* we only allow perfect matches, and we reject everything else */
482 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
487 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
490 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
491 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
493 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
497 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
498 * architectures so we check of the necessary function is present.
500 #ifndef HAVE_LIBSSH2_SCP_SEND64
501 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
503 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
504 (libssh2_uint64_t)d, 0, 0)
508 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
510 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
511 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
514 static CURLcode ssh_knownhost(struct connectdata *conn)
516 CURLcode result = CURLE_OK;
518 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
519 struct SessionHandle *data = conn->data;
521 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
522 /* we're asked to verify the host against a file */
523 struct ssh_conn *sshc = &conn->proto.sshc;
527 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
529 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
534 * A subject to figure out is what host name we need to pass in here.
535 * What host name does OpenSSH store in its file if an IDN name is
538 struct libssh2_knownhost *host;
539 enum curl_khmatch keymatch;
540 curl_sshkeycallback func =
541 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
542 struct curl_khkey knownkey;
543 struct curl_khkey *knownkeyp = NULL;
544 struct curl_khkey foundkey;
546 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
547 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
549 #ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
550 keycheck = libssh2_knownhost_checkp(sshc->kh,
552 (conn->remote_port != PORT_SSH)?
553 conn->remote_port:-1,
555 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
556 LIBSSH2_KNOWNHOST_KEYENC_RAW|
560 keycheck = libssh2_knownhost_check(sshc->kh,
563 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
564 LIBSSH2_KNOWNHOST_KEYENC_RAW|
569 infof(data, "SSH host check: %d, key: %s\n", keycheck,
570 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
573 /* setup 'knownkey' */
574 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
575 knownkey.key = host->key;
577 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
578 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
579 knownkeyp = &knownkey;
582 /* setup 'foundkey' */
583 foundkey.key = remotekey;
584 foundkey.len = keylen;
585 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
586 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
589 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
590 * curl_khmatch enum are ever modified, we need to introduce a
591 * translation table here!
593 keymatch = (enum curl_khmatch)keycheck;
595 /* Ask the callback how to behave */
596 rc = func(data, knownkeyp, /* from the knownhosts file */
597 &foundkey, /* from the remote host */
598 keymatch, data->set.ssh_keyfunc_userp);
601 /* no remotekey means failure! */
602 rc = CURLKHSTAT_REJECT;
605 default: /* unknown return codes will equal reject */
607 case CURLKHSTAT_REJECT:
608 state(conn, SSH_SESSION_FREE);
610 case CURLKHSTAT_DEFER:
611 /* DEFER means bail out but keep the SSH_HOSTKEY state */
612 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
614 case CURLKHSTAT_FINE:
615 case CURLKHSTAT_FINE_ADD_TO_FILE:
617 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
618 /* the found host+key didn't match but has been told to be fine
619 anyway so we add it in memory */
620 int addrc = libssh2_knownhost_add(sshc->kh,
621 conn->host.name, NULL,
623 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
624 LIBSSH2_KNOWNHOST_KEYENC_RAW|
627 infof(data, "Warning adding the known host %s failed!\n",
629 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
630 /* now we write the entire in-memory list of known hosts to the
633 libssh2_knownhost_writefile(sshc->kh,
634 data->set.str[STRING_SSH_KNOWNHOSTS],
635 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
637 infof(data, "Warning, writing %s failed!\n",
638 data->set.str[STRING_SSH_KNOWNHOSTS]);
645 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
651 static CURLcode ssh_check_fingerprint(struct connectdata *conn)
653 struct ssh_conn *sshc = &conn->proto.sshc;
654 struct SessionHandle *data = conn->data;
655 const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
659 const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
660 LIBSSH2_HOSTKEY_HASH_MD5);
663 /* The fingerprint points to static storage (!), don't free() it. */
664 for(i = 0; i < 16; i++)
665 snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
666 infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
669 /* Before we authenticate we check the hostkey's MD5 fingerprint
670 * against a known fingerprint, if available.
672 if(pubkey_md5 && strlen(pubkey_md5) == 32) {
673 if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
676 "Denied establishing ssh session: mismatch md5 fingerprint. "
677 "Remote %s is not equal to %s", md5buffer, pubkey_md5);
680 "Denied establishing ssh session: md5 fingerprint not available");
681 state(conn, SSH_SESSION_FREE);
682 sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
683 return sshc->actualcode;
686 infof(data, "MD5 checksum match!\n");
687 /* as we already matched, we skip the check for known hosts */
692 return ssh_knownhost(conn);
696 * ssh_statemach_act() runs the SSH state machine as far as it can without
697 * blocking and without reaching the end. The data the pointer 'block' points
698 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
699 * meaning it wants to be called again when the socket is ready
702 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
704 CURLcode result = CURLE_OK;
705 struct SessionHandle *data = conn->data;
706 struct SSHPROTO *sftp_scp = data->req.protop;
707 struct ssh_conn *sshc = &conn->proto.sshc;
708 curl_socket_t sock = conn->sock[FIRSTSOCKET];
709 char *new_readdir_line;
710 int rc = LIBSSH2_ERROR_NONE;
712 int seekerr = CURL_SEEKFUNC_OK;
713 *block = 0; /* we're not blocking by default */
717 switch(sshc->state) {
719 sshc->secondCreateDirs = 0;
720 sshc->nextstate = SSH_NO_STATE;
721 sshc->actualcode = CURLE_OK;
723 /* Set libssh2 to non-blocking, since everything internally is
725 libssh2_session_set_blocking(sshc->ssh_session, 0);
727 state(conn, SSH_S_STARTUP);
731 rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
732 if(rc == LIBSSH2_ERROR_EAGAIN) {
736 failf(data, "Failure establishing ssh session");
737 state(conn, SSH_SESSION_FREE);
738 sshc->actualcode = CURLE_FAILED_INIT;
742 state(conn, SSH_HOSTKEY);
747 * Before we authenticate we should check the hostkey's fingerprint
748 * against our known hosts. How that is handled (reading from file,
749 * whatever) is up to us.
751 result = ssh_check_fingerprint(conn);
753 state(conn, SSH_AUTHLIST);
754 /* ssh_check_fingerprint sets state appropriately on error */
759 * Figure out authentication methods
760 * NB: As soon as we have provided a username to an openssh server we
761 * must never change it later. Thus, always specify the correct username
762 * here, even though the libssh2 docs kind of indicate that it should be
763 * possible to get a 'generic' list (not user-specific) of authentication
764 * methods, presumably with a blank username. That won't work in my
766 * So always specify it here.
768 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
770 curlx_uztoui(strlen(conn->user)));
772 if(!sshc->authlist) {
773 if(libssh2_userauth_authenticated(sshc->ssh_session)) {
775 infof(data, "SSH user accepted with no authentication\n");
776 state(conn, SSH_AUTH_DONE);
779 else if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
780 LIBSSH2_ERROR_EAGAIN) {
781 rc = LIBSSH2_ERROR_EAGAIN;
785 state(conn, SSH_SESSION_FREE);
786 sshc->actualcode = libssh2_session_error_to_CURLE(err);
790 infof(data, "SSH authentication methods available: %s\n",
793 state(conn, SSH_AUTH_PKEY_INIT);
796 case SSH_AUTH_PKEY_INIT:
798 * Check the supported auth types in the order I feel is most secure
799 * with the requested type of authentication
801 sshc->authed = FALSE;
803 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
804 (strstr(sshc->authlist, "publickey") != NULL)) {
806 bool out_of_memory = FALSE;
808 sshc->rsa_pub = sshc->rsa = NULL;
810 /* To ponder about: should really the lib be messing about with the
811 HOME environment variable etc? */
812 home = curl_getenv("HOME");
814 if(data->set.str[STRING_SSH_PRIVATE_KEY])
815 sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
817 /* If no private key file is specified, try some common paths. */
819 /* Try ~/.ssh first. */
820 sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
822 out_of_memory = TRUE;
823 else if(access(sshc->rsa, R_OK) != 0) {
824 Curl_safefree(sshc->rsa);
825 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
827 out_of_memory = TRUE;
828 else if(access(sshc->rsa, R_OK) != 0) {
829 Curl_safefree(sshc->rsa);
833 if(!out_of_memory && !sshc->rsa) {
834 /* Nothing found; try the current dir. */
835 sshc->rsa = strdup("id_rsa");
836 if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
837 Curl_safefree(sshc->rsa);
838 sshc->rsa = strdup("id_dsa");
839 if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
840 Curl_safefree(sshc->rsa);
841 /* Out of guesses. Set to the empty string to avoid
842 * surprising info messages. */
843 sshc->rsa = strdup("");
850 * Unless the user explicitly specifies a public key file, let
851 * libssh2 extract the public key from the private key file.
852 * This is done by simply passing sshc->rsa_pub = NULL.
854 if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
855 sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
857 out_of_memory = TRUE;
860 if(out_of_memory || sshc->rsa == NULL) {
862 Curl_safefree(sshc->rsa);
863 Curl_safefree(sshc->rsa_pub);
864 state(conn, SSH_SESSION_FREE);
865 sshc->actualcode = CURLE_OUT_OF_MEMORY;
869 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
870 if(!sshc->passphrase)
871 sshc->passphrase = "";
875 infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
876 infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
878 state(conn, SSH_AUTH_PKEY);
881 state(conn, SSH_AUTH_PASS_INIT);
886 /* The function below checks if the files exists, no need to stat() here.
888 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
893 sshc->rsa, sshc->passphrase);
894 if(rc == LIBSSH2_ERROR_EAGAIN) {
898 Curl_safefree(sshc->rsa_pub);
899 Curl_safefree(sshc->rsa);
903 infof(data, "Initialized SSH public key authentication\n");
904 state(conn, SSH_AUTH_DONE);
908 (void)libssh2_session_last_error(sshc->ssh_session,
910 infof(data, "SSH public key authentication failed: %s\n", err_msg);
911 state(conn, SSH_AUTH_PASS_INIT);
915 case SSH_AUTH_PASS_INIT:
916 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
917 (strstr(sshc->authlist, "password") != NULL)) {
918 state(conn, SSH_AUTH_PASS);
921 state(conn, SSH_AUTH_HOST_INIT);
926 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
927 curlx_uztoui(strlen(conn->user)),
929 curlx_uztoui(strlen(conn->passwd)),
931 if(rc == LIBSSH2_ERROR_EAGAIN) {
936 infof(data, "Initialized password authentication\n");
937 state(conn, SSH_AUTH_DONE);
940 state(conn, SSH_AUTH_HOST_INIT);
944 case SSH_AUTH_HOST_INIT:
945 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
946 (strstr(sshc->authlist, "hostbased") != NULL)) {
947 state(conn, SSH_AUTH_HOST);
950 state(conn, SSH_AUTH_AGENT_INIT);
955 state(conn, SSH_AUTH_AGENT_INIT);
958 case SSH_AUTH_AGENT_INIT:
959 #ifdef HAVE_LIBSSH2_AGENT_API
960 if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
961 && (strstr(sshc->authlist, "publickey") != NULL)) {
963 /* Connect to the ssh-agent */
964 /* The agent could be shared by a curl thread i believe
965 but nothing obvious as keys can be added/removed at any time */
966 if(!sshc->ssh_agent) {
967 sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
968 if(!sshc->ssh_agent) {
969 infof(data, "Could not create agent object\n");
971 state(conn, SSH_AUTH_KEY_INIT);
976 rc = libssh2_agent_connect(sshc->ssh_agent);
977 if(rc == LIBSSH2_ERROR_EAGAIN)
980 infof(data, "Failure connecting to agent\n");
981 state(conn, SSH_AUTH_KEY_INIT);
984 state(conn, SSH_AUTH_AGENT_LIST);
988 #endif /* HAVE_LIBSSH2_AGENT_API */
989 state(conn, SSH_AUTH_KEY_INIT);
992 case SSH_AUTH_AGENT_LIST:
993 #ifdef HAVE_LIBSSH2_AGENT_API
994 rc = libssh2_agent_list_identities(sshc->ssh_agent);
996 if(rc == LIBSSH2_ERROR_EAGAIN)
999 infof(data, "Failure requesting identities to agent\n");
1000 state(conn, SSH_AUTH_KEY_INIT);
1003 state(conn, SSH_AUTH_AGENT);
1004 sshc->sshagent_prev_identity = NULL;
1009 case SSH_AUTH_AGENT:
1010 #ifdef HAVE_LIBSSH2_AGENT_API
1011 /* as prev_identity evolves only after an identity user auth finished we
1012 can safely request it again as long as EAGAIN is returned here or by
1013 libssh2_agent_userauth */
1014 rc = libssh2_agent_get_identity(sshc->ssh_agent,
1015 &sshc->sshagent_identity,
1016 sshc->sshagent_prev_identity);
1017 if(rc == LIBSSH2_ERROR_EAGAIN)
1021 rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
1022 sshc->sshagent_identity);
1025 if(rc != LIBSSH2_ERROR_EAGAIN) {
1026 /* tried and failed? go to next identity */
1027 sshc->sshagent_prev_identity = sshc->sshagent_identity;
1034 infof(data, "Failure requesting identities to agent\n");
1036 infof(data, "No identity would match\n");
1038 if(rc == LIBSSH2_ERROR_NONE) {
1039 sshc->authed = TRUE;
1040 infof(data, "Agent based authentication successful\n");
1041 state(conn, SSH_AUTH_DONE);
1044 state(conn, SSH_AUTH_KEY_INIT);
1048 case SSH_AUTH_KEY_INIT:
1049 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
1050 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
1051 state(conn, SSH_AUTH_KEY);
1054 state(conn, SSH_AUTH_DONE);
1059 /* Authentication failed. Continue with keyboard-interactive now. */
1060 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
1063 strlen(conn->user)),
1065 if(rc == LIBSSH2_ERROR_EAGAIN) {
1069 sshc->authed = TRUE;
1070 infof(data, "Initialized keyboard interactive authentication\n");
1072 state(conn, SSH_AUTH_DONE);
1077 failf(data, "Authentication failure");
1078 state(conn, SSH_SESSION_FREE);
1079 sshc->actualcode = CURLE_LOGIN_DENIED;
1084 * At this point we have an authenticated ssh session.
1086 infof(data, "Authentication complete\n");
1088 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
1090 conn->sockfd = sock;
1091 conn->writesockfd = CURL_SOCKET_BAD;
1093 if(conn->handler->protocol == CURLPROTO_SFTP) {
1094 state(conn, SSH_SFTP_INIT);
1097 infof(data, "SSH CONNECT phase done\n");
1098 state(conn, SSH_STOP);
1103 * Start the libssh2 sftp session
1105 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
1106 if(!sshc->sftp_session) {
1107 if(libssh2_session_last_errno(sshc->ssh_session) ==
1108 LIBSSH2_ERROR_EAGAIN) {
1109 rc = LIBSSH2_ERROR_EAGAIN;
1115 (void)libssh2_session_last_error(sshc->ssh_session,
1117 failf(data, "Failure initializing sftp session: %s", err_msg);
1118 state(conn, SSH_SESSION_FREE);
1119 sshc->actualcode = CURLE_FAILED_INIT;
1123 state(conn, SSH_SFTP_REALPATH);
1126 case SSH_SFTP_REALPATH:
1128 char tempHome[PATH_MAX];
1131 * Get the "home" directory
1133 rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
1134 tempHome, PATH_MAX-1);
1135 if(rc == LIBSSH2_ERROR_EAGAIN) {
1139 /* It seems that this string is not always NULL terminated */
1140 tempHome[rc] = '\0';
1141 sshc->homedir = strdup(tempHome);
1142 if(!sshc->homedir) {
1143 state(conn, SSH_SFTP_CLOSE);
1144 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1147 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1150 /* Return the error type */
1151 err = sftp_libssh2_last_error(sshc->sftp_session);
1152 result = sftp_libssh2_error_to_CURLE(err);
1153 sshc->actualcode = result?result:CURLE_SSH;
1154 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1156 state(conn, SSH_STOP);
1160 /* This is the last step in the SFTP connect phase. Do note that while
1161 we get the homedir here, we get the "workingpath" in the DO action
1162 since the homedir will remain the same between request but the
1163 working path will not. */
1164 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1165 state(conn, SSH_STOP);
1168 case SSH_SFTP_QUOTE_INIT:
1170 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1172 sshc->actualcode = result;
1173 state(conn, SSH_STOP);
1177 if(data->set.quote) {
1178 infof(data, "Sending quote commands\n");
1179 sshc->quote_item = data->set.quote;
1180 state(conn, SSH_SFTP_QUOTE);
1183 state(conn, SSH_SFTP_TRANS_INIT);
1187 case SSH_SFTP_POSTQUOTE_INIT:
1188 if(data->set.postquote) {
1189 infof(data, "Sending quote commands\n");
1190 sshc->quote_item = data->set.postquote;
1191 state(conn, SSH_SFTP_QUOTE);
1194 state(conn, SSH_STOP);
1198 case SSH_SFTP_QUOTE:
1199 /* Send any quote commands */
1204 * Support some of the "FTP" commands
1206 char *cmd = sshc->quote_item->data;
1207 sshc->acceptfail = FALSE;
1209 /* if a command starts with an asterisk, which a legal SFTP command never
1210 can, the command will be allowed to fail without it causing any
1211 aborts or cancels etc. It will cause libcurl to act as if the command
1212 is successful, whatever the server reponds. */
1216 sshc->acceptfail = TRUE;
1219 if(curl_strequal("pwd", cmd)) {
1220 /* output debug output if that is requested */
1221 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1224 result = CURLE_OUT_OF_MEMORY;
1225 state(conn, SSH_SFTP_CLOSE);
1226 sshc->nextstate = SSH_NO_STATE;
1229 if(data->set.verbose) {
1230 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1231 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1233 /* this sends an FTP-like "header" to the header callback so that the
1234 current directory can be read very similar to how it is read when
1235 using ordinary FTP. */
1236 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1239 state(conn, SSH_SFTP_CLOSE);
1240 sshc->nextstate = SSH_NO_STATE;
1241 sshc->actualcode = result;
1244 state(conn, SSH_SFTP_NEXT_QUOTE);
1249 * the arguments following the command must be separated from the
1250 * command with a space so we can check for it unconditionally
1252 cp = strchr(cmd, ' ');
1254 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1255 state(conn, SSH_SFTP_CLOSE);
1256 sshc->nextstate = SSH_NO_STATE;
1257 sshc->actualcode = CURLE_QUOTE_ERROR;
1262 * also, every command takes at least one argument so we get that
1263 * first argument right now
1265 result = get_pathname(&cp, &sshc->quote_path1);
1267 if(result == CURLE_OUT_OF_MEMORY)
1268 failf(data, "Out of memory");
1270 failf(data, "Syntax error: Bad first parameter");
1271 state(conn, SSH_SFTP_CLOSE);
1272 sshc->nextstate = SSH_NO_STATE;
1273 sshc->actualcode = result;
1278 * SFTP is a binary protocol, so we don't send text commands
1279 * to the server. Instead, we scan for commands used by
1280 * OpenSSH's sftp program and call the appropriate libssh2
1283 if(curl_strnequal(cmd, "chgrp ", 6) ||
1284 curl_strnequal(cmd, "chmod ", 6) ||
1285 curl_strnequal(cmd, "chown ", 6) ) {
1286 /* attribute change */
1288 /* sshc->quote_path1 contains the mode to set */
1289 /* get the destination */
1290 result = get_pathname(&cp, &sshc->quote_path2);
1292 if(result == CURLE_OUT_OF_MEMORY)
1293 failf(data, "Out of memory");
1295 failf(data, "Syntax error in chgrp/chmod/chown: "
1296 "Bad second parameter");
1297 Curl_safefree(sshc->quote_path1);
1298 state(conn, SSH_SFTP_CLOSE);
1299 sshc->nextstate = SSH_NO_STATE;
1300 sshc->actualcode = result;
1303 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1304 state(conn, SSH_SFTP_QUOTE_STAT);
1307 else if(curl_strnequal(cmd, "ln ", 3) ||
1308 curl_strnequal(cmd, "symlink ", 8)) {
1309 /* symbolic linking */
1310 /* sshc->quote_path1 is the source */
1311 /* get the destination */
1312 result = get_pathname(&cp, &sshc->quote_path2);
1314 if(result == CURLE_OUT_OF_MEMORY)
1315 failf(data, "Out of memory");
1318 "Syntax error in ln/symlink: Bad second parameter");
1319 Curl_safefree(sshc->quote_path1);
1320 state(conn, SSH_SFTP_CLOSE);
1321 sshc->nextstate = SSH_NO_STATE;
1322 sshc->actualcode = result;
1325 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1328 else if(curl_strnequal(cmd, "mkdir ", 6)) {
1330 state(conn, SSH_SFTP_QUOTE_MKDIR);
1333 else if(curl_strnequal(cmd, "rename ", 7)) {
1335 /* first param is the source path */
1336 /* second param is the dest. path */
1337 result = get_pathname(&cp, &sshc->quote_path2);
1339 if(result == CURLE_OUT_OF_MEMORY)
1340 failf(data, "Out of memory");
1342 failf(data, "Syntax error in rename: Bad second parameter");
1343 Curl_safefree(sshc->quote_path1);
1344 state(conn, SSH_SFTP_CLOSE);
1345 sshc->nextstate = SSH_NO_STATE;
1346 sshc->actualcode = result;
1349 state(conn, SSH_SFTP_QUOTE_RENAME);
1352 else if(curl_strnequal(cmd, "rmdir ", 6)) {
1354 state(conn, SSH_SFTP_QUOTE_RMDIR);
1357 else if(curl_strnequal(cmd, "rm ", 3)) {
1358 state(conn, SSH_SFTP_QUOTE_UNLINK);
1362 failf(data, "Unknown SFTP command");
1363 Curl_safefree(sshc->quote_path1);
1364 Curl_safefree(sshc->quote_path2);
1365 state(conn, SSH_SFTP_CLOSE);
1366 sshc->nextstate = SSH_NO_STATE;
1367 sshc->actualcode = CURLE_QUOTE_ERROR;
1371 if(!sshc->quote_item) {
1372 state(conn, SSH_SFTP_TRANS_INIT);
1376 case SSH_SFTP_NEXT_QUOTE:
1377 Curl_safefree(sshc->quote_path1);
1378 Curl_safefree(sshc->quote_path2);
1380 sshc->quote_item = sshc->quote_item->next;
1382 if(sshc->quote_item) {
1383 state(conn, SSH_SFTP_QUOTE);
1386 if(sshc->nextstate != SSH_NO_STATE) {
1387 state(conn, sshc->nextstate);
1388 sshc->nextstate = SSH_NO_STATE;
1391 state(conn, SSH_SFTP_TRANS_INIT);
1396 case SSH_SFTP_QUOTE_STAT:
1398 char *cmd = sshc->quote_item->data;
1399 sshc->acceptfail = FALSE;
1401 /* if a command starts with an asterisk, which a legal SFTP command never
1402 can, the command will be allowed to fail without it causing any
1403 aborts or cancels etc. It will cause libcurl to act as if the command
1404 is successful, whatever the server reponds. */
1408 sshc->acceptfail = TRUE;
1411 if(!curl_strnequal(cmd, "chmod", 5)) {
1412 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1413 * set them both at once, we need to obtain the current ownership
1414 * first. This takes an extra protocol round trip.
1416 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1417 curlx_uztoui(strlen(sshc->quote_path2)),
1419 &sshc->quote_attrs);
1420 if(rc == LIBSSH2_ERROR_EAGAIN) {
1423 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1424 err = sftp_libssh2_last_error(sshc->sftp_session);
1425 Curl_safefree(sshc->quote_path1);
1426 Curl_safefree(sshc->quote_path2);
1427 failf(data, "Attempt to get SFTP stats failed: %s",
1428 sftp_libssh2_strerror(err));
1429 state(conn, SSH_SFTP_CLOSE);
1430 sshc->nextstate = SSH_NO_STATE;
1431 sshc->actualcode = CURLE_QUOTE_ERROR;
1436 /* Now set the new attributes... */
1437 if(curl_strnequal(cmd, "chgrp", 5)) {
1438 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1439 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1440 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1441 !sshc->acceptfail) {
1442 Curl_safefree(sshc->quote_path1);
1443 Curl_safefree(sshc->quote_path2);
1444 failf(data, "Syntax error: chgrp gid not a number");
1445 state(conn, SSH_SFTP_CLOSE);
1446 sshc->nextstate = SSH_NO_STATE;
1447 sshc->actualcode = CURLE_QUOTE_ERROR;
1451 else if(curl_strnequal(cmd, "chmod", 5)) {
1452 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1453 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1454 /* permissions are octal */
1455 if(sshc->quote_attrs.permissions == 0 &&
1456 !ISDIGIT(sshc->quote_path1[0])) {
1457 Curl_safefree(sshc->quote_path1);
1458 Curl_safefree(sshc->quote_path2);
1459 failf(data, "Syntax error: chmod permissions not a number");
1460 state(conn, SSH_SFTP_CLOSE);
1461 sshc->nextstate = SSH_NO_STATE;
1462 sshc->actualcode = CURLE_QUOTE_ERROR;
1466 else if(curl_strnequal(cmd, "chown", 5)) {
1467 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1468 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1469 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1470 !sshc->acceptfail) {
1471 Curl_safefree(sshc->quote_path1);
1472 Curl_safefree(sshc->quote_path2);
1473 failf(data, "Syntax error: chown uid not a number");
1474 state(conn, SSH_SFTP_CLOSE);
1475 sshc->nextstate = SSH_NO_STATE;
1476 sshc->actualcode = CURLE_QUOTE_ERROR;
1481 /* Now send the completed structure... */
1482 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1486 case SSH_SFTP_QUOTE_SETSTAT:
1487 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1488 curlx_uztoui(strlen(sshc->quote_path2)),
1489 LIBSSH2_SFTP_SETSTAT,
1490 &sshc->quote_attrs);
1491 if(rc == LIBSSH2_ERROR_EAGAIN) {
1494 else if(rc != 0 && !sshc->acceptfail) {
1495 err = sftp_libssh2_last_error(sshc->sftp_session);
1496 Curl_safefree(sshc->quote_path1);
1497 Curl_safefree(sshc->quote_path2);
1498 failf(data, "Attempt to set SFTP stats failed: %s",
1499 sftp_libssh2_strerror(err));
1500 state(conn, SSH_SFTP_CLOSE);
1501 sshc->nextstate = SSH_NO_STATE;
1502 sshc->actualcode = CURLE_QUOTE_ERROR;
1505 state(conn, SSH_SFTP_NEXT_QUOTE);
1508 case SSH_SFTP_QUOTE_SYMLINK:
1509 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1510 curlx_uztoui(strlen(sshc->quote_path1)),
1512 curlx_uztoui(strlen(sshc->quote_path2)),
1513 LIBSSH2_SFTP_SYMLINK);
1514 if(rc == LIBSSH2_ERROR_EAGAIN) {
1517 else if(rc != 0 && !sshc->acceptfail) {
1518 err = sftp_libssh2_last_error(sshc->sftp_session);
1519 Curl_safefree(sshc->quote_path1);
1520 Curl_safefree(sshc->quote_path2);
1521 failf(data, "symlink command failed: %s",
1522 sftp_libssh2_strerror(err));
1523 state(conn, SSH_SFTP_CLOSE);
1524 sshc->nextstate = SSH_NO_STATE;
1525 sshc->actualcode = CURLE_QUOTE_ERROR;
1528 state(conn, SSH_SFTP_NEXT_QUOTE);
1531 case SSH_SFTP_QUOTE_MKDIR:
1532 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1533 curlx_uztoui(strlen(sshc->quote_path1)),
1534 data->set.new_directory_perms);
1535 if(rc == LIBSSH2_ERROR_EAGAIN) {
1538 else if(rc != 0 && !sshc->acceptfail) {
1539 err = sftp_libssh2_last_error(sshc->sftp_session);
1540 Curl_safefree(sshc->quote_path1);
1541 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1542 state(conn, SSH_SFTP_CLOSE);
1543 sshc->nextstate = SSH_NO_STATE;
1544 sshc->actualcode = CURLE_QUOTE_ERROR;
1547 state(conn, SSH_SFTP_NEXT_QUOTE);
1550 case SSH_SFTP_QUOTE_RENAME:
1551 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1552 curlx_uztoui(strlen(sshc->quote_path1)),
1554 curlx_uztoui(strlen(sshc->quote_path2)),
1555 LIBSSH2_SFTP_RENAME_OVERWRITE |
1556 LIBSSH2_SFTP_RENAME_ATOMIC |
1557 LIBSSH2_SFTP_RENAME_NATIVE);
1559 if(rc == LIBSSH2_ERROR_EAGAIN) {
1562 else if(rc != 0 && !sshc->acceptfail) {
1563 err = sftp_libssh2_last_error(sshc->sftp_session);
1564 Curl_safefree(sshc->quote_path1);
1565 Curl_safefree(sshc->quote_path2);
1566 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1567 state(conn, SSH_SFTP_CLOSE);
1568 sshc->nextstate = SSH_NO_STATE;
1569 sshc->actualcode = CURLE_QUOTE_ERROR;
1572 state(conn, SSH_SFTP_NEXT_QUOTE);
1575 case SSH_SFTP_QUOTE_RMDIR:
1576 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1577 curlx_uztoui(strlen(sshc->quote_path1)));
1578 if(rc == LIBSSH2_ERROR_EAGAIN) {
1581 else if(rc != 0 && !sshc->acceptfail) {
1582 err = sftp_libssh2_last_error(sshc->sftp_session);
1583 Curl_safefree(sshc->quote_path1);
1584 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1585 state(conn, SSH_SFTP_CLOSE);
1586 sshc->nextstate = SSH_NO_STATE;
1587 sshc->actualcode = CURLE_QUOTE_ERROR;
1590 state(conn, SSH_SFTP_NEXT_QUOTE);
1593 case SSH_SFTP_QUOTE_UNLINK:
1594 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1595 curlx_uztoui(strlen(sshc->quote_path1)));
1596 if(rc == LIBSSH2_ERROR_EAGAIN) {
1599 else if(rc != 0 && !sshc->acceptfail) {
1600 err = sftp_libssh2_last_error(sshc->sftp_session);
1601 Curl_safefree(sshc->quote_path1);
1602 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1603 state(conn, SSH_SFTP_CLOSE);
1604 sshc->nextstate = SSH_NO_STATE;
1605 sshc->actualcode = CURLE_QUOTE_ERROR;
1608 state(conn, SSH_SFTP_NEXT_QUOTE);
1611 case SSH_SFTP_TRANS_INIT:
1612 if(data->set.upload)
1613 state(conn, SSH_SFTP_UPLOAD_INIT);
1615 if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1616 state(conn, SSH_SFTP_READDIR_INIT);
1618 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1622 case SSH_SFTP_UPLOAD_INIT:
1624 unsigned long flags;
1626 * NOTE!!! libssh2 requires that the destination path is a full path
1627 * that includes the destination file and name OR ends in a "/"
1628 * If this is not done the destination file will be named the
1629 * same name as the last directory in the path.
1632 if(data->state.resume_from != 0) {
1633 LIBSSH2_SFTP_ATTRIBUTES attrs;
1634 if(data->state.resume_from < 0) {
1635 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1636 curlx_uztoui(strlen(sftp_scp->path)),
1637 LIBSSH2_SFTP_STAT, &attrs);
1638 if(rc == LIBSSH2_ERROR_EAGAIN) {
1642 data->state.resume_from = 0;
1645 curl_off_t size = attrs.filesize;
1647 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
1648 return CURLE_BAD_DOWNLOAD_RESUME;
1650 data->state.resume_from = attrs.filesize;
1655 if(data->set.ftp_append)
1656 /* Try to open for append, but create if nonexisting */
1657 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1658 else if(data->state.resume_from > 0)
1659 /* If we have restart position then open for append */
1660 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1662 /* Clear file before writing (normal behaviour) */
1663 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1666 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1667 curlx_uztoui(strlen(sftp_scp->path)),
1668 flags, data->set.new_file_perms,
1669 LIBSSH2_SFTP_OPENFILE);
1671 if(!sshc->sftp_handle) {
1672 rc = libssh2_session_last_errno(sshc->ssh_session);
1674 if(LIBSSH2_ERROR_EAGAIN == rc)
1677 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1678 /* only when there was an SFTP protocol error can we extract
1680 err = sftp_libssh2_last_error(sshc->sftp_session);
1682 err = -1; /* not an sftp error at all */
1684 if(sshc->secondCreateDirs) {
1685 state(conn, SSH_SFTP_CLOSE);
1686 sshc->actualcode = err>= LIBSSH2_FX_OK?
1687 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1688 failf(data, "Creating the dir/file failed: %s",
1689 sftp_libssh2_strerror(err));
1692 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1693 (err == LIBSSH2_FX_FAILURE) ||
1694 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1695 (data->set.ftp_create_missing_dirs &&
1696 (strlen(sftp_scp->path) > 1))) {
1697 /* try to create the path remotely */
1698 sshc->secondCreateDirs = 1;
1699 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1702 state(conn, SSH_SFTP_CLOSE);
1703 sshc->actualcode = err>= LIBSSH2_FX_OK?
1704 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1705 if(!sshc->actualcode) {
1706 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1707 zero even though libssh2_sftp_open() failed previously! We need
1708 to work around that! */
1709 sshc->actualcode = CURLE_SSH;
1712 failf(data, "Upload failed: %s (%d/%d)",
1713 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1719 /* If we have a restart point then we need to seek to the correct
1721 if(data->state.resume_from > 0) {
1722 /* Let's read off the proper amount of bytes from the input. */
1723 if(conn->seek_func) {
1724 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1728 if(seekerr != CURL_SEEKFUNC_OK) {
1730 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1731 failf(data, "Could not seek stream");
1732 return CURLE_FTP_COULDNT_USE_REST;
1734 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1736 curl_off_t passed=0;
1738 size_t readthisamountnow =
1739 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1740 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1742 size_t actuallyread =
1743 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1746 passed += actuallyread;
1747 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1748 /* this checks for greater-than only to make sure that the
1749 CURL_READFUNC_ABORT return code still aborts */
1750 failf(data, "Failed to read data");
1751 return CURLE_FTP_COULDNT_USE_REST;
1753 } while(passed < data->state.resume_from);
1757 /* now, decrease the size of the read */
1758 if(data->state.infilesize > 0) {
1759 data->state.infilesize -= data->state.resume_from;
1760 data->req.size = data->state.infilesize;
1761 Curl_pgrsSetUploadSize(data, data->state.infilesize);
1764 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1766 if(data->state.infilesize > 0) {
1767 data->req.size = data->state.infilesize;
1768 Curl_pgrsSetUploadSize(data, data->state.infilesize);
1771 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1773 /* not set by Curl_setup_transfer to preserve keepon bits */
1774 conn->sockfd = conn->writesockfd;
1777 state(conn, SSH_SFTP_CLOSE);
1778 sshc->actualcode = result;
1781 /* store this original bitmask setup to use later on if we can't
1782 figure out a "real" bitmask */
1783 sshc->orig_waitfor = data->req.keepon;
1785 /* we want to use the _sending_ function even when the socket turns
1786 out readable as the underlying libssh2 sftp send function will deal
1787 with both accordingly */
1788 conn->cselect_bits = CURL_CSELECT_OUT;
1790 /* since we don't really wait for anything at this point, we want the
1791 state machine to move on as soon as possible so we set a very short
1793 Curl_expire(data, 1);
1795 state(conn, SSH_STOP);
1800 case SSH_SFTP_CREATE_DIRS_INIT:
1801 if(strlen(sftp_scp->path) > 1) {
1802 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1803 state(conn, SSH_SFTP_CREATE_DIRS);
1806 state(conn, SSH_SFTP_UPLOAD_INIT);
1810 case SSH_SFTP_CREATE_DIRS:
1811 sshc->slash_pos = strchr(sshc->slash_pos, '/');
1812 if(sshc->slash_pos) {
1813 *sshc->slash_pos = 0;
1815 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1816 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1820 state(conn, SSH_SFTP_UPLOAD_INIT);
1824 case SSH_SFTP_CREATE_DIRS_MKDIR:
1825 /* 'mode' - parameter is preliminary - default to 0644 */
1826 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1827 curlx_uztoui(strlen(sftp_scp->path)),
1828 data->set.new_directory_perms);
1829 if(rc == LIBSSH2_ERROR_EAGAIN) {
1832 *sshc->slash_pos = '/';
1836 * Abort if failure wasn't that the dir already exists or the
1837 * permission was denied (creation might succeed further down the
1838 * path) - retry on unspecific FAILURE also
1840 err = sftp_libssh2_last_error(sshc->sftp_session);
1841 if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1842 (err != LIBSSH2_FX_FAILURE) &&
1843 (err != LIBSSH2_FX_PERMISSION_DENIED)) {
1844 result = sftp_libssh2_error_to_CURLE(err);
1845 state(conn, SSH_SFTP_CLOSE);
1846 sshc->actualcode = result?result:CURLE_SSH;
1850 state(conn, SSH_SFTP_CREATE_DIRS);
1853 case SSH_SFTP_READDIR_INIT:
1854 Curl_pgrsSetDownloadSize(data, -1);
1855 if(data->set.opt_no_body) {
1856 state(conn, SSH_STOP);
1861 * This is a directory that we are trying to get, so produce a directory
1864 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1867 strlen(sftp_scp->path)),
1868 0, 0, LIBSSH2_SFTP_OPENDIR);
1869 if(!sshc->sftp_handle) {
1870 if(libssh2_session_last_errno(sshc->ssh_session) ==
1871 LIBSSH2_ERROR_EAGAIN) {
1872 rc = LIBSSH2_ERROR_EAGAIN;
1876 err = sftp_libssh2_last_error(sshc->sftp_session);
1877 failf(data, "Could not open directory for reading: %s",
1878 sftp_libssh2_strerror(err));
1879 state(conn, SSH_SFTP_CLOSE);
1880 result = sftp_libssh2_error_to_CURLE(err);
1881 sshc->actualcode = result?result:CURLE_SSH;
1885 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1886 state(conn, SSH_SFTP_CLOSE);
1887 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1890 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1891 Curl_safefree(sshc->readdir_filename);
1892 state(conn, SSH_SFTP_CLOSE);
1893 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1896 state(conn, SSH_SFTP_READDIR);
1899 case SSH_SFTP_READDIR:
1900 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1901 sshc->readdir_filename,
1903 sshc->readdir_longentry,
1905 &sshc->readdir_attrs);
1906 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1907 rc = LIBSSH2_ERROR_EAGAIN;
1910 if(sshc->readdir_len > 0) {
1911 sshc->readdir_filename[sshc->readdir_len] = '\0';
1913 if(data->set.ftp_list_only) {
1916 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1917 if(tmpLine == NULL) {
1918 state(conn, SSH_SFTP_CLOSE);
1919 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1922 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1923 tmpLine, sshc->readdir_len+1);
1924 Curl_safefree(tmpLine);
1927 state(conn, SSH_STOP);
1930 /* since this counts what we send to the client, we include the
1931 newline in this counter */
1932 data->req.bytecount += sshc->readdir_len+1;
1934 /* output debug output if that is requested */
1935 if(data->set.verbose) {
1936 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1937 sshc->readdir_len, conn);
1941 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1942 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1943 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1944 if(!sshc->readdir_line) {
1945 Curl_safefree(sshc->readdir_filename);
1946 Curl_safefree(sshc->readdir_longentry);
1947 state(conn, SSH_SFTP_CLOSE);
1948 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1952 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1953 sshc->readdir_currLen);
1954 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1955 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1956 LIBSSH2_SFTP_S_IFLNK)) {
1957 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1958 if(sshc->readdir_linkPath == NULL) {
1959 Curl_safefree(sshc->readdir_filename);
1960 Curl_safefree(sshc->readdir_longentry);
1961 state(conn, SSH_SFTP_CLOSE);
1962 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1966 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1967 sshc->readdir_filename);
1968 state(conn, SSH_SFTP_READDIR_LINK);
1971 state(conn, SSH_SFTP_READDIR_BOTTOM);
1975 else if(sshc->readdir_len == 0) {
1976 Curl_safefree(sshc->readdir_filename);
1977 Curl_safefree(sshc->readdir_longentry);
1978 state(conn, SSH_SFTP_READDIR_DONE);
1981 else if(sshc->readdir_len <= 0) {
1982 err = sftp_libssh2_last_error(sshc->sftp_session);
1983 result = sftp_libssh2_error_to_CURLE(err);
1984 sshc->actualcode = result?result:CURLE_SSH;
1985 failf(data, "Could not open remote file for reading: %s :: %d",
1986 sftp_libssh2_strerror(err),
1987 libssh2_session_last_errno(sshc->ssh_session));
1988 Curl_safefree(sshc->readdir_filename);
1989 Curl_safefree(sshc->readdir_longentry);
1990 state(conn, SSH_SFTP_CLOSE);
1995 case SSH_SFTP_READDIR_LINK:
1997 libssh2_sftp_symlink_ex(sshc->sftp_session,
1998 sshc->readdir_linkPath,
1999 curlx_uztoui(strlen(sshc->readdir_linkPath)),
2000 sshc->readdir_filename,
2001 PATH_MAX, LIBSSH2_SFTP_READLINK);
2002 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
2003 rc = LIBSSH2_ERROR_EAGAIN;
2006 Curl_safefree(sshc->readdir_linkPath);
2008 /* get room for the filename and extra output */
2009 sshc->readdir_totalLen += 4 + sshc->readdir_len;
2010 new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
2011 if(!new_readdir_line) {
2012 Curl_safefree(sshc->readdir_line);
2013 Curl_safefree(sshc->readdir_filename);
2014 Curl_safefree(sshc->readdir_longentry);
2015 state(conn, SSH_SFTP_CLOSE);
2016 sshc->actualcode = CURLE_OUT_OF_MEMORY;
2019 sshc->readdir_line = new_readdir_line;
2021 sshc->readdir_currLen += snprintf(sshc->readdir_line +
2022 sshc->readdir_currLen,
2023 sshc->readdir_totalLen -
2024 sshc->readdir_currLen,
2026 sshc->readdir_filename);
2028 state(conn, SSH_SFTP_READDIR_BOTTOM);
2031 case SSH_SFTP_READDIR_BOTTOM:
2032 sshc->readdir_currLen += snprintf(sshc->readdir_line +
2033 sshc->readdir_currLen,
2034 sshc->readdir_totalLen -
2035 sshc->readdir_currLen, "\n");
2036 result = Curl_client_write(conn, CLIENTWRITE_BODY,
2038 sshc->readdir_currLen);
2042 /* output debug output if that is requested */
2043 if(data->set.verbose) {
2044 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
2045 sshc->readdir_currLen, conn);
2047 data->req.bytecount += sshc->readdir_currLen;
2049 Curl_safefree(sshc->readdir_line);
2051 state(conn, SSH_STOP);
2054 state(conn, SSH_SFTP_READDIR);
2057 case SSH_SFTP_READDIR_DONE:
2058 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
2059 LIBSSH2_ERROR_EAGAIN) {
2060 rc = LIBSSH2_ERROR_EAGAIN;
2063 sshc->sftp_handle = NULL;
2064 Curl_safefree(sshc->readdir_filename);
2065 Curl_safefree(sshc->readdir_longentry);
2067 /* no data to transfer */
2068 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2069 state(conn, SSH_STOP);
2072 case SSH_SFTP_DOWNLOAD_INIT:
2074 * Work on getting the specified file
2077 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
2078 curlx_uztoui(strlen(sftp_scp->path)),
2079 LIBSSH2_FXF_READ, data->set.new_file_perms,
2080 LIBSSH2_SFTP_OPENFILE);
2081 if(!sshc->sftp_handle) {
2082 if(libssh2_session_last_errno(sshc->ssh_session) ==
2083 LIBSSH2_ERROR_EAGAIN) {
2084 rc = LIBSSH2_ERROR_EAGAIN;
2088 err = sftp_libssh2_last_error(sshc->sftp_session);
2089 failf(data, "Could not open remote file for reading: %s",
2090 sftp_libssh2_strerror(err));
2091 state(conn, SSH_SFTP_CLOSE);
2092 result = sftp_libssh2_error_to_CURLE(err);
2093 sshc->actualcode = result?result:CURLE_SSH;
2097 state(conn, SSH_SFTP_DOWNLOAD_STAT);
2100 case SSH_SFTP_DOWNLOAD_STAT:
2102 LIBSSH2_SFTP_ATTRIBUTES attrs;
2104 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
2105 curlx_uztoui(strlen(sftp_scp->path)),
2106 LIBSSH2_SFTP_STAT, &attrs);
2107 if(rc == LIBSSH2_ERROR_EAGAIN) {
2111 !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
2112 (attrs.filesize == 0)) {
2114 * libssh2_sftp_open() didn't return an error, so maybe the server
2115 * just doesn't support stat()
2116 * OR the server doesn't return a file size with a stat()
2119 data->req.size = -1;
2120 data->req.maxdownload = -1;
2121 Curl_pgrsSetDownloadSize(data, -1);
2124 curl_off_t size = attrs.filesize;
2127 failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
2128 return CURLE_BAD_DOWNLOAD_RESUME;
2130 if(conn->data->state.use_range) {
2131 curl_off_t from, to;
2135 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2136 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2138 to=curlx_strtoofft(ptr, &ptr2, 0);
2139 if((ptr == ptr2) /* no "to" value given */
2144 /* from is relative to end of file */
2148 failf(data, "Offset (%"
2149 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2150 CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
2151 return CURLE_BAD_DOWNLOAD_RESUME;
2158 size = to - from + 1;
2161 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2163 data->req.size = size;
2164 data->req.maxdownload = size;
2165 Curl_pgrsSetDownloadSize(data, size);
2168 /* We can resume if we can seek to the resume position */
2169 if(data->state.resume_from) {
2170 if(data->state.resume_from < 0) {
2171 /* We're supposed to download the last abs(from) bytes */
2172 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2173 failf(data, "Offset (%"
2174 CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2175 CURL_FORMAT_CURL_OFF_T ")",
2176 data->state.resume_from, attrs.filesize);
2177 return CURLE_BAD_DOWNLOAD_RESUME;
2179 /* download from where? */
2180 data->state.resume_from += attrs.filesize;
2183 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2184 failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
2185 ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
2186 data->state.resume_from, attrs.filesize);
2187 return CURLE_BAD_DOWNLOAD_RESUME;
2190 /* Does a completed file need to be seeked and started or closed ? */
2191 /* Now store the number of bytes we are expected to download */
2192 data->req.size = attrs.filesize - data->state.resume_from;
2193 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2194 Curl_pgrsSetDownloadSize(data,
2195 attrs.filesize - data->state.resume_from);
2196 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2200 /* Setup the actual download */
2201 if(data->req.size == 0) {
2202 /* no data to transfer */
2203 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2204 infof(data, "File already completely downloaded\n");
2205 state(conn, SSH_STOP);
2209 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2210 FALSE, NULL, -1, NULL);
2212 /* not set by Curl_setup_transfer to preserve keepon bits */
2213 conn->writesockfd = conn->sockfd;
2215 /* we want to use the _receiving_ function even when the socket turns
2216 out writableable as the underlying libssh2 recv function will deal
2217 with both accordingly */
2218 conn->cselect_bits = CURL_CSELECT_IN;
2221 /* this should never occur; the close state should be entered
2222 at the time the error occurs */
2223 state(conn, SSH_SFTP_CLOSE);
2224 sshc->actualcode = result;
2227 state(conn, SSH_STOP);
2231 case SSH_SFTP_CLOSE:
2232 if(sshc->sftp_handle) {
2233 rc = libssh2_sftp_close(sshc->sftp_handle);
2234 if(rc == LIBSSH2_ERROR_EAGAIN) {
2238 infof(data, "Failed to close libssh2 file\n");
2240 sshc->sftp_handle = NULL;
2243 Curl_safefree(sftp_scp->path);
2245 DEBUGF(infof(data, "SFTP DONE done\n"));
2247 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2248 After nextstate is executed,the control should come back to
2249 SSH_SFTP_CLOSE to pass the correct result back */
2250 if(sshc->nextstate != SSH_NO_STATE &&
2251 sshc->nextstate != SSH_SFTP_CLOSE) {
2252 state(conn, sshc->nextstate);
2253 sshc->nextstate = SSH_SFTP_CLOSE;
2256 state(conn, SSH_STOP);
2257 result = sshc->actualcode;
2261 case SSH_SFTP_SHUTDOWN:
2262 /* during times we get here due to a broken transfer and then the
2263 sftp_handle might not have been taken down so make sure that is done
2264 before we proceed */
2266 if(sshc->sftp_handle) {
2267 rc = libssh2_sftp_close(sshc->sftp_handle);
2268 if(rc == LIBSSH2_ERROR_EAGAIN) {
2272 infof(data, "Failed to close libssh2 file\n");
2274 sshc->sftp_handle = NULL;
2276 if(sshc->sftp_session) {
2277 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2278 if(rc == LIBSSH2_ERROR_EAGAIN) {
2282 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2284 sshc->sftp_session = NULL;
2287 Curl_safefree(sshc->homedir);
2288 conn->data->state.most_recent_ftp_entrypath = NULL;
2290 state(conn, SSH_SESSION_DISCONNECT);
2293 case SSH_SCP_TRANS_INIT:
2294 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2296 sshc->actualcode = result;
2297 state(conn, SSH_STOP);
2301 if(data->set.upload) {
2302 if(data->state.infilesize < 0) {
2303 failf(data, "SCP requires a known file size for upload");
2304 sshc->actualcode = CURLE_UPLOAD_FAILED;
2305 state(conn, SSH_SCP_CHANNEL_FREE);
2308 state(conn, SSH_SCP_UPLOAD_INIT);
2311 state(conn, SSH_SCP_DOWNLOAD_INIT);
2315 case SSH_SCP_UPLOAD_INIT:
2317 * libssh2 requires that the destination path is a full path that
2318 * includes the destination file and name OR ends in a "/" . If this is
2319 * not done the destination file will be named the same name as the last
2320 * directory in the path.
2323 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2324 data->state.infilesize);
2325 if(!sshc->ssh_channel) {
2326 if(libssh2_session_last_errno(sshc->ssh_session) ==
2327 LIBSSH2_ERROR_EAGAIN) {
2328 rc = LIBSSH2_ERROR_EAGAIN;
2335 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2336 &err_msg, NULL, 0));
2337 failf(conn->data, "%s", err_msg);
2338 state(conn, SSH_SCP_CHANNEL_FREE);
2339 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2345 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2348 /* not set by Curl_setup_transfer to preserve keepon bits */
2349 conn->sockfd = conn->writesockfd;
2352 state(conn, SSH_SCP_CHANNEL_FREE);
2353 sshc->actualcode = result;
2356 /* store this original bitmask setup to use later on if we can't
2357 figure out a "real" bitmask */
2358 sshc->orig_waitfor = data->req.keepon;
2360 /* we want to use the _sending_ function even when the socket turns
2361 out readable as the underlying libssh2 scp send function will deal
2362 with both accordingly */
2363 conn->cselect_bits = CURL_CSELECT_OUT;
2365 state(conn, SSH_STOP);
2369 case SSH_SCP_DOWNLOAD_INIT:
2372 * We must check the remote file; if it is a directory no values will
2376 curl_off_t bytecount;
2378 /* clear the struct scp recv will fill in */
2379 memset(&sb, 0, sizeof(struct stat));
2381 /* get a fresh new channel from the ssh layer */
2382 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2383 sftp_scp->path, &sb);
2384 if(!sshc->ssh_channel) {
2385 if(libssh2_session_last_errno(sshc->ssh_session) ==
2386 LIBSSH2_ERROR_EAGAIN) {
2387 rc = LIBSSH2_ERROR_EAGAIN;
2394 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2395 &err_msg, NULL, 0));
2396 failf(conn->data, "%s", err_msg);
2397 state(conn, SSH_SCP_CHANNEL_FREE);
2398 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2404 bytecount = (curl_off_t)sb.st_size;
2405 data->req.maxdownload = (curl_off_t)sb.st_size;
2406 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2408 /* not set by Curl_setup_transfer to preserve keepon bits */
2409 conn->writesockfd = conn->sockfd;
2411 /* we want to use the _receiving_ function even when the socket turns
2412 out writableable as the underlying libssh2 recv function will deal
2413 with both accordingly */
2414 conn->cselect_bits = CURL_CSELECT_IN;
2417 state(conn, SSH_SCP_CHANNEL_FREE);
2418 sshc->actualcode = result;
2421 state(conn, SSH_STOP);
2426 if(data->set.upload)
2427 state(conn, SSH_SCP_SEND_EOF);
2429 state(conn, SSH_SCP_CHANNEL_FREE);
2432 case SSH_SCP_SEND_EOF:
2433 if(sshc->ssh_channel) {
2434 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2435 if(rc == LIBSSH2_ERROR_EAGAIN) {
2439 infof(data, "Failed to send libssh2 channel EOF\n");
2442 state(conn, SSH_SCP_WAIT_EOF);
2445 case SSH_SCP_WAIT_EOF:
2446 if(sshc->ssh_channel) {
2447 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2448 if(rc == LIBSSH2_ERROR_EAGAIN) {
2452 infof(data, "Failed to get channel EOF: %d\n", rc);
2455 state(conn, SSH_SCP_WAIT_CLOSE);
2458 case SSH_SCP_WAIT_CLOSE:
2459 if(sshc->ssh_channel) {
2460 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2461 if(rc == LIBSSH2_ERROR_EAGAIN) {
2465 infof(data, "Channel failed to close: %d\n", rc);
2468 state(conn, SSH_SCP_CHANNEL_FREE);
2471 case SSH_SCP_CHANNEL_FREE:
2472 if(sshc->ssh_channel) {
2473 rc = libssh2_channel_free(sshc->ssh_channel);
2474 if(rc == LIBSSH2_ERROR_EAGAIN) {
2478 infof(data, "Failed to free libssh2 scp subsystem\n");
2480 sshc->ssh_channel = NULL;
2482 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2484 state(conn, SSH_SESSION_DISCONNECT);
2486 state(conn, SSH_STOP);
2487 result = sshc->actualcode;
2490 case SSH_SESSION_DISCONNECT:
2491 /* during weird times when we've been prematurely aborted, the channel
2492 is still alive when we reach this state and we MUST kill the channel
2494 if(sshc->ssh_channel) {
2495 rc = libssh2_channel_free(sshc->ssh_channel);
2496 if(rc == LIBSSH2_ERROR_EAGAIN) {
2500 infof(data, "Failed to free libssh2 scp subsystem\n");
2502 sshc->ssh_channel = NULL;
2505 if(sshc->ssh_session) {
2506 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2507 if(rc == LIBSSH2_ERROR_EAGAIN) {
2511 infof(data, "Failed to disconnect libssh2 session\n");
2515 Curl_safefree(sshc->homedir);
2516 conn->data->state.most_recent_ftp_entrypath = NULL;
2518 state(conn, SSH_SESSION_FREE);
2521 case SSH_SESSION_FREE:
2522 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2524 libssh2_knownhost_free(sshc->kh);
2529 #ifdef HAVE_LIBSSH2_AGENT_API
2530 if(sshc->ssh_agent) {
2531 rc = libssh2_agent_disconnect(sshc->ssh_agent);
2532 if(rc == LIBSSH2_ERROR_EAGAIN) {
2536 infof(data, "Failed to disconnect from libssh2 agent\n");
2538 libssh2_agent_free (sshc->ssh_agent);
2539 sshc->ssh_agent = NULL;
2541 /* NB: there is no need to free identities, they are part of internal
2543 sshc->sshagent_identity = NULL;
2544 sshc->sshagent_prev_identity = NULL;
2548 if(sshc->ssh_session) {
2549 rc = libssh2_session_free(sshc->ssh_session);
2550 if(rc == LIBSSH2_ERROR_EAGAIN) {
2554 infof(data, "Failed to free libssh2 session\n");
2556 sshc->ssh_session = NULL;
2559 /* worst-case scenario cleanup */
2561 DEBUGASSERT(sshc->ssh_session == NULL);
2562 DEBUGASSERT(sshc->ssh_channel == NULL);
2563 DEBUGASSERT(sshc->sftp_session == NULL);
2564 DEBUGASSERT(sshc->sftp_handle == NULL);
2565 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2566 DEBUGASSERT(sshc->kh == NULL);
2568 #ifdef HAVE_LIBSSH2_AGENT_API
2569 DEBUGASSERT(sshc->ssh_agent == NULL);
2572 Curl_safefree(sshc->rsa_pub);
2573 Curl_safefree(sshc->rsa);
2575 Curl_safefree(sshc->quote_path1);
2576 Curl_safefree(sshc->quote_path2);
2578 Curl_safefree(sshc->homedir);
2580 Curl_safefree(sshc->readdir_filename);
2581 Curl_safefree(sshc->readdir_longentry);
2582 Curl_safefree(sshc->readdir_line);
2583 Curl_safefree(sshc->readdir_linkPath);
2585 /* the code we are about to return */
2586 result = sshc->actualcode;
2588 memset(sshc, 0, sizeof(struct ssh_conn));
2590 connclose(conn, "SSH session free");
2591 sshc->state = SSH_SESSION_FREE; /* current */
2592 sshc->nextstate = SSH_NO_STATE;
2593 state(conn, SSH_STOP);
2597 /* fallthrough, just stop! */
2599 /* internal error */
2600 sshc->nextstate = SSH_NO_STATE;
2601 state(conn, SSH_STOP);
2605 } while(!rc && (sshc->state != SSH_STOP));
2607 if(rc == LIBSSH2_ERROR_EAGAIN) {
2608 /* we would block, we need to wait for the socket to be ready (in the
2609 right direction too)! */
2616 /* called by the multi interface to figure out what socket(s) to wait for and
2617 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2618 static int ssh_perform_getsock(const struct connectdata *conn,
2619 curl_socket_t *sock, /* points to numsocks
2620 number of sockets */
2623 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2624 int bitmap = GETSOCK_BLANK;
2627 sock[0] = conn->sock[FIRSTSOCKET];
2629 if(conn->waitfor & KEEP_RECV)
2630 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2632 if(conn->waitfor & KEEP_SEND)
2633 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2637 /* if we don't know the direction we can use the generic *_getsock()
2638 function even for the protocol_connect and doing states */
2639 return Curl_single_getsock(conn, sock, numsocks);
2643 /* Generic function called by the multi interface to figure out what socket(s)
2644 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2645 static int ssh_getsock(struct connectdata *conn,
2646 curl_socket_t *sock, /* points to numsocks number
2650 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2654 /* if we don't know any direction we can just play along as we used to and
2655 not provide any sensible info */
2656 return GETSOCK_BLANK;
2658 /* if we know the direction we can use the generic *_getsock() function even
2659 for the protocol_connect and doing states */
2660 return ssh_perform_getsock(conn, sock, numsocks);
2664 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2666 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2667 * function is used to figure out in what direction and stores this info so
2668 * that the multi interface can take advantage of it. Make sure to call this
2669 * function in all cases so that when it _doesn't_ return EAGAIN we can
2670 * restore the default wait bits.
2672 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2674 struct ssh_conn *sshc = &conn->proto.sshc;
2676 if(block && (dir = libssh2_session_block_directions(sshc->ssh_session))) {
2677 /* translate the libssh2 define bits into our own bit defines */
2678 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2679 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2682 /* It didn't block or libssh2 didn't reveal in which direction, put back
2684 conn->waitfor = sshc->orig_waitfor;
2687 /* no libssh2 directional support so we simply don't know */
2688 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2691 /* called repeatedly until done from multi.c */
2692 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2694 struct ssh_conn *sshc = &conn->proto.sshc;
2695 CURLcode result = CURLE_OK;
2696 bool block; /* we store the status and use that to provide a ssh_getsock()
2699 result = ssh_statemach_act(conn, &block);
2700 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2701 ssh_block2waitfor(conn, block);
2706 static CURLcode ssh_block_statemach(struct connectdata *conn,
2709 struct ssh_conn *sshc = &conn->proto.sshc;
2710 CURLcode result = CURLE_OK;
2711 struct SessionHandle *data = conn->data;
2713 while((sshc->state != SSH_STOP) && !result) {
2717 result = ssh_statemach_act(conn, &block);
2721 if(Curl_pgrsUpdate(conn))
2722 return CURLE_ABORTED_BY_CALLBACK;
2724 struct timeval now = Curl_tvnow();
2725 result = Curl_speedcheck(data, now);
2730 left = Curl_timeleft(data, NULL, duringconnect);
2732 failf(data, "Operation timed out");
2733 return CURLE_OPERATION_TIMEDOUT;
2736 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2737 if(!result && block) {
2738 int dir = libssh2_session_block_directions(sshc->ssh_session);
2739 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2740 curl_socket_t fd_read = CURL_SOCKET_BAD;
2741 curl_socket_t fd_write = CURL_SOCKET_BAD;
2742 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2744 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2746 /* wait for the socket to become ready */
2747 Curl_socket_ready(fd_read, fd_write,
2748 left>1000?1000:left); /* ignore result */
2758 * SSH setup and connection
2760 static CURLcode ssh_setup_connection(struct connectdata *conn)
2762 struct SSHPROTO *ssh;
2764 conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
2766 return CURLE_OUT_OF_MEMORY;
2771 static Curl_recv scp_recv, sftp_recv;
2772 static Curl_send scp_send, sftp_send;
2775 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2776 * do protocol-specific actions at connect-time.
2778 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2780 #ifdef CURL_LIBSSH2_DEBUG
2783 struct ssh_conn *ssh;
2785 struct SessionHandle *data = conn->data;
2787 /* initialize per-handle data if not already */
2788 if(!data->req.protop)
2789 ssh_setup_connection(conn);
2791 /* We default to persistent connections. We set this already in this connect
2792 function to make the re-use checks properly be able to check this bit. */
2793 connkeep(conn, "SSH default");
2795 if(conn->handler->protocol & CURLPROTO_SCP) {
2796 conn->recv[FIRSTSOCKET] = scp_recv;
2797 conn->send[FIRSTSOCKET] = scp_send;
2800 conn->recv[FIRSTSOCKET] = sftp_recv;
2801 conn->send[FIRSTSOCKET] = sftp_send;
2803 ssh = &conn->proto.sshc;
2805 #ifdef CURL_LIBSSH2_DEBUG
2807 infof(data, "User: %s\n", conn->user);
2810 infof(data, "Password: %s\n", conn->passwd);
2812 sock = conn->sock[FIRSTSOCKET];
2813 #endif /* CURL_LIBSSH2_DEBUG */
2815 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2817 my_libssh2_realloc, conn);
2818 if(ssh->ssh_session == NULL) {
2819 failf(data, "Failure initialising ssh session");
2820 return CURLE_FAILED_INIT;
2823 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2824 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2826 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2828 /* eeek. TODO: free the ssh_session! */
2829 return CURLE_FAILED_INIT;
2832 /* read all known hosts from there */
2833 rc = libssh2_knownhost_readfile(ssh->kh,
2834 data->set.str[STRING_SSH_KNOWNHOSTS],
2835 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2837 infof(data, "Failed to read known hosts from %s\n",
2838 data->set.str[STRING_SSH_KNOWNHOSTS]);
2840 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2842 #ifdef CURL_LIBSSH2_DEBUG
2843 libssh2_trace(ssh->ssh_session, ~0);
2844 infof(data, "SSH socket: %d\n", (int)sock);
2845 #endif /* CURL_LIBSSH2_DEBUG */
2847 state(conn, SSH_INIT);
2849 result = ssh_multi_statemach(conn, done);
2855 ***********************************************************************
2859 * This is the actual DO function for SCP. Get a file according to
2860 * the options previously setup.
2864 CURLcode scp_perform(struct connectdata *conn,
2868 CURLcode result = CURLE_OK;
2870 DEBUGF(infof(conn->data, "DO phase starts\n"));
2872 *dophase_done = FALSE; /* not done yet */
2874 /* start the first command in the DO phase */
2875 state(conn, SSH_SCP_TRANS_INIT);
2877 /* run the state-machine */
2878 result = ssh_multi_statemach(conn, dophase_done);
2880 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2883 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2889 /* called from multi.c while DOing */
2890 static CURLcode scp_doing(struct connectdata *conn,
2894 result = ssh_multi_statemach(conn, dophase_done);
2897 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2903 * The DO function is generic for both protocols. There was previously two
2904 * separate ones but this way means less duplicated code.
2907 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2911 struct SessionHandle *data = conn->data;
2912 struct ssh_conn *sshc = &conn->proto.sshc;
2914 *done = FALSE; /* default to false */
2916 data->req.size = -1; /* make sure this is unknown at this point */
2918 sshc->actualcode = CURLE_OK; /* reset error code */
2919 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2922 Curl_pgrsSetUploadCounter(data, 0);
2923 Curl_pgrsSetDownloadCounter(data, 0);
2924 Curl_pgrsSetUploadSize(data, -1);
2925 Curl_pgrsSetDownloadSize(data, -1);
2927 if(conn->handler->protocol & CURLPROTO_SCP)
2928 result = scp_perform(conn, &connected, done);
2930 result = sftp_perform(conn, &connected, done);
2935 /* BLOCKING, but the function is using the state machine so the only reason
2936 this is still blocking is that the multi interface code has no support for
2937 disconnecting operations that takes a while */
2938 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2940 CURLcode result = CURLE_OK;
2941 struct ssh_conn *ssh = &conn->proto.sshc;
2942 (void) dead_connection;
2944 Curl_safefree(conn->data->req.protop);
2946 if(ssh->ssh_session) {
2947 /* only if there's a session still around to use! */
2949 state(conn, SSH_SESSION_DISCONNECT);
2951 result = ssh_block_statemach(conn, FALSE);
2957 /* generic done function for both SCP and SFTP called from their specific
2959 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2961 CURLcode result = CURLE_OK;
2962 struct SSHPROTO *sftp_scp = conn->data->req.protop;
2965 /* run the state-machine
2967 TODO: when the multi interface is used, this _really_ should be using
2968 the ssh_multi_statemach function but we have no general support for
2969 non-blocking DONE operations, not in the multi state machine and with
2970 Curl_done() invokes on several places in the code!
2972 result = ssh_block_statemach(conn, FALSE);
2978 Curl_safefree(sftp_scp->path);
2979 if(Curl_pgrsDone(conn))
2980 return CURLE_ABORTED_BY_CALLBACK;
2982 conn->data->req.keepon = 0; /* clear all bits */
2987 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2990 (void)premature; /* not used */
2993 state(conn, SSH_SCP_DONE);
2995 return ssh_done(conn, status);
2999 /* return number of received (decrypted) bytes */
3000 static ssize_t scp_send(struct connectdata *conn, int sockindex,
3001 const void *mem, size_t len, CURLcode *err)
3004 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3006 /* libssh2_channel_write() returns int! */
3008 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
3010 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3012 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3016 else if(nwrite < LIBSSH2_ERROR_NONE) {
3017 *err = libssh2_session_error_to_CURLE((int)nwrite);
3025 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
3026 * a regular CURLcode value.
3028 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
3029 char *mem, size_t len, CURLcode *err)
3032 (void)sockindex; /* we only support SCP on the fixed known primary socket */
3034 /* libssh2_channel_read() returns int */
3036 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
3038 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3039 if(nread == LIBSSH2_ERROR_EAGAIN) {
3048 * =============== SFTP ===============
3052 ***********************************************************************
3056 * This is the actual DO function for SFTP. Get a file/directory according to
3057 * the options previously setup.
3061 CURLcode sftp_perform(struct connectdata *conn,
3065 CURLcode result = CURLE_OK;
3067 DEBUGF(infof(conn->data, "DO phase starts\n"));
3069 *dophase_done = FALSE; /* not done yet */
3071 /* start the first command in the DO phase */
3072 state(conn, SSH_SFTP_QUOTE_INIT);
3074 /* run the state-machine */
3075 result = ssh_multi_statemach(conn, dophase_done);
3077 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3080 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3086 /* called from multi.c while DOing */
3087 static CURLcode sftp_doing(struct connectdata *conn,
3090 CURLcode result = ssh_multi_statemach(conn, dophase_done);
3093 DEBUGF(infof(conn->data, "DO phase is complete\n"));
3098 /* BLOCKING, but the function is using the state machine so the only reason
3099 this is still blocking is that the multi interface code has no support for
3100 disconnecting operations that takes a while */
3101 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
3103 CURLcode result = CURLE_OK;
3104 (void) dead_connection;
3106 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3108 Curl_safefree(conn->data->req.protop);
3110 if(conn->proto.sshc.ssh_session) {
3111 /* only if there's a session still around to use! */
3112 state(conn, SSH_SFTP_SHUTDOWN);
3113 result = ssh_block_statemach(conn, FALSE);
3116 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3122 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3125 struct ssh_conn *sshc = &conn->proto.sshc;
3128 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3129 errors that could happen due to open file handles during POSTQUOTE
3131 if(!status && !premature && conn->data->set.postquote) {
3132 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3133 state(conn, SSH_SFTP_CLOSE);
3136 state(conn, SSH_SFTP_CLOSE);
3138 return ssh_done(conn, status);
3141 /* return number of sent bytes */
3142 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3143 const void *mem, size_t len, CURLcode *err)
3145 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3146 but is changed to ssize_t in 0.15. These days we don't
3147 support libssh2 0.15*/
3150 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3152 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3154 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3158 else if(nwrite < LIBSSH2_ERROR_NONE) {
3159 *err = libssh2_session_error_to_CURLE((int)nwrite);
3167 * Return number of received (decrypted) bytes
3170 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3171 char *mem, size_t len, CURLcode *err)
3176 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3178 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3180 if(nread == LIBSSH2_ERROR_EAGAIN) {
3185 else if(nread < 0) {
3186 *err = libssh2_session_error_to_CURLE((int)nread);
3191 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3194 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3196 * Permission to use, copy, modify, and distribute this software for any
3197 * purpose with or without fee is hereby granted, provided that the above
3198 * copyright notice and this permission notice appear in all copies.
3200 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3201 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3202 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3203 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3204 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3205 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3206 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3209 get_pathname(const char **cpp, char **path)
3211 const char *cp = *cpp, *end;
3214 static const char WHITESPACE[] = " \t\r\n";
3216 cp += strspn(cp, WHITESPACE);
3220 return CURLE_QUOTE_ERROR;
3223 *path = malloc(strlen(cp) + 1);
3225 return CURLE_OUT_OF_MEMORY;
3227 /* Check for quoted filenames */
3228 if(*cp == '\"' || *cp == '\'') {
3231 /* Search for terminating quote, unescape some chars */
3232 for(i = j = 0; i <= strlen(cp); i++) {
3233 if(cp[i] == quot) { /* Found quote */
3238 if(cp[i] == '\0') { /* End of string */
3239 /*error("Unterminated quote");*/
3242 if(cp[i] == '\\') { /* Escaped characters */
3244 if(cp[i] != '\'' && cp[i] != '\"' &&
3246 /*error("Bad escaped character '\\%c'",
3251 (*path)[j++] = cp[i];
3255 /*error("Empty quotes");*/
3258 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3261 /* Read to end of filename */
3262 end = strpbrk(cp, WHITESPACE);
3264 end = strchr(cp, '\0');
3265 *cpp = end + strspn(end, WHITESPACE);
3267 memcpy(*path, cp, end - cp);
3268 (*path)[end - cp] = '\0';
3273 Curl_safefree(*path);
3274 return CURLE_QUOTE_ERROR;
3278 static const char *sftp_libssh2_strerror(int err)
3281 case LIBSSH2_FX_NO_SUCH_FILE:
3282 return "No such file or directory";
3284 case LIBSSH2_FX_PERMISSION_DENIED:
3285 return "Permission denied";
3287 case LIBSSH2_FX_FAILURE:
3288 return "Operation failed";
3290 case LIBSSH2_FX_BAD_MESSAGE:
3291 return "Bad message from SFTP server";
3293 case LIBSSH2_FX_NO_CONNECTION:
3294 return "Not connected to SFTP server";
3296 case LIBSSH2_FX_CONNECTION_LOST:
3297 return "Connection to SFTP server lost";
3299 case LIBSSH2_FX_OP_UNSUPPORTED:
3300 return "Operation not supported by SFTP server";
3302 case LIBSSH2_FX_INVALID_HANDLE:
3303 return "Invalid handle";
3305 case LIBSSH2_FX_NO_SUCH_PATH:
3306 return "No such file or directory";
3308 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3309 return "File already exists";
3311 case LIBSSH2_FX_WRITE_PROTECT:
3312 return "File is write protected";
3314 case LIBSSH2_FX_NO_MEDIA:
3317 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3320 case LIBSSH2_FX_QUOTA_EXCEEDED:
3321 return "User quota exceeded";
3323 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3324 return "Unknown principle";
3326 case LIBSSH2_FX_LOCK_CONFlICT:
3327 return "File lock conflict";
3329 case LIBSSH2_FX_DIR_NOT_EMPTY:
3330 return "Directory not empty";
3332 case LIBSSH2_FX_NOT_A_DIRECTORY:
3333 return "Not a directory";
3335 case LIBSSH2_FX_INVALID_FILENAME:
3336 return "Invalid filename";
3338 case LIBSSH2_FX_LINK_LOOP:
3339 return "Link points to itself";
3341 return "Unknown error in libssh2";
3344 #endif /* USE_LIBSSH2 */