1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 /* #define CURL_LIBSSH2_DEBUG */
34 #include <libssh2_sftp.h>
44 #ifdef HAVE_SYS_SOCKET_H
45 #include <sys/socket.h>
47 #ifdef HAVE_NETINET_IN_H
48 #include <netinet/in.h>
50 #ifdef HAVE_ARPA_INET_H
51 #include <arpa/inet.h>
54 #include <sys/utsname.h>
64 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
66 #define in_addr_t unsigned long
69 #include <curl/curl.h>
76 #include "http.h" /* for HTTP proxy tunnel stuff */
79 #include "speedcheck.h"
86 #include "inet_ntop.h"
87 #include "parsedate.h" /* for the week day and month names */
88 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
89 #include "strtoofft.h"
94 #define _MPRINTF_REPLACE /* use our functions only */
95 #include <curl/mprintf.h>
97 #include "curl_memory.h"
98 /* The last #include file should be: */
103 # define PATH_MAX MAX_PATH
107 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
108 have their definition hidden well */
111 #define sftp_libssh2_realpath(s,p,t,m) \
112 libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
113 (t), (m), LIBSSH2_SFTP_REALPATH)
115 /* Local functions: */
116 static const char *sftp_libssh2_strerror(unsigned long err);
117 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
118 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
119 static LIBSSH2_FREE_FUNC(my_libssh2_free);
121 static CURLcode get_pathname(const char **cpp, char **path);
123 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
124 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
125 static CURLcode ssh_do(struct connectdata *conn, bool *done);
127 static CURLcode ssh_getworkingpath(struct connectdata *conn,
128 char *homedir, /* when SFTP is used */
131 static CURLcode scp_done(struct connectdata *conn,
132 CURLcode, bool premature);
133 static CURLcode scp_doing(struct connectdata *conn,
135 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
137 static CURLcode sftp_done(struct connectdata *conn,
138 CURLcode, bool premature);
139 static CURLcode sftp_doing(struct connectdata *conn,
141 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
143 CURLcode sftp_perform(struct connectdata *conn,
147 static int ssh_getsock(struct connectdata *conn,
148 curl_socket_t *sock, /* points to numsocks number
152 static int ssh_perform_getsock(const struct connectdata *conn,
153 curl_socket_t *sock, /* points to numsocks
158 * SCP protocol handler.
161 const struct Curl_handler Curl_handler_scp = {
163 ZERO_NULL, /* 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 ZERO_NULL, /* 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 */
210 kbd_callback(const char *name, int name_len, const char *instruction,
211 int instruction_len, int num_prompts,
212 const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
213 LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
216 struct connectdata *conn = (struct connectdata *)*abstract;
218 #ifdef CURL_LIBSSH2_DEBUG
219 fprintf(stderr, "name=%s\n", name);
220 fprintf(stderr, "name_len=%d\n", name_len);
221 fprintf(stderr, "instruction=%s\n", instruction);
222 fprintf(stderr, "instruction_len=%d\n", instruction_len);
223 fprintf(stderr, "num_prompts=%d\n", num_prompts);
228 (void)instruction_len;
229 #endif /* CURL_LIBSSH2_DEBUG */
230 if(num_prompts == 1) {
231 responses[0].text = strdup(conn->passwd);
232 responses[0].length = curlx_uztoui(strlen(conn->passwd));
238 static CURLcode sftp_libssh2_error_to_CURLE(int err)
244 case LIBSSH2_FX_NO_SUCH_FILE:
245 case LIBSSH2_FX_NO_SUCH_PATH:
246 return CURLE_REMOTE_FILE_NOT_FOUND;
248 case LIBSSH2_FX_PERMISSION_DENIED:
249 case LIBSSH2_FX_WRITE_PROTECT:
250 case LIBSSH2_FX_LOCK_CONFlICT:
251 return CURLE_REMOTE_ACCESS_DENIED;
253 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
254 case LIBSSH2_FX_QUOTA_EXCEEDED:
255 return CURLE_REMOTE_DISK_FULL;
257 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
258 return CURLE_REMOTE_FILE_EXISTS;
260 case LIBSSH2_FX_DIR_NOT_EMPTY:
261 return CURLE_QUOTE_ERROR;
270 static CURLcode libssh2_session_error_to_CURLE(int err)
273 /* Ordered by order of appearance in libssh2.h */
274 case LIBSSH2_ERROR_NONE:
277 case LIBSSH2_ERROR_SOCKET_NONE:
278 return CURLE_COULDNT_CONNECT;
280 case LIBSSH2_ERROR_ALLOC:
281 return CURLE_OUT_OF_MEMORY;
283 case LIBSSH2_ERROR_SOCKET_SEND:
284 return CURLE_SEND_ERROR;
286 case LIBSSH2_ERROR_HOSTKEY_INIT:
287 case LIBSSH2_ERROR_HOSTKEY_SIGN:
288 case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
289 case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
290 return CURLE_PEER_FAILED_VERIFICATION;
292 case LIBSSH2_ERROR_PASSWORD_EXPIRED:
293 return CURLE_LOGIN_DENIED;
295 case LIBSSH2_ERROR_SOCKET_TIMEOUT:
296 case LIBSSH2_ERROR_TIMEOUT:
297 return CURLE_OPERATION_TIMEDOUT;
299 case LIBSSH2_ERROR_EAGAIN:
303 /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
304 error code, and possibly add a few new SSH-related one. We must however
305 not return or even depend on libssh2 errors in the public libcurl API */
310 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
312 (void)abstract; /* arg not used */
313 return malloc(count);
316 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
318 (void)abstract; /* arg not used */
319 return realloc(ptr, count);
322 static LIBSSH2_FREE_FUNC(my_libssh2_free)
324 (void)abstract; /* arg not used */
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 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
335 /* for debug purposes */
336 static const char * const names[] = {
342 "SSH_AUTH_PKEY_INIT",
344 "SSH_AUTH_PASS_INIT",
346 "SSH_AUTH_HOST_INIT",
353 "SSH_SFTP_QUOTE_INIT",
354 "SSH_SFTP_POSTQUOTE_INIT",
356 "SSH_SFTP_NEXT_QUOTE",
357 "SSH_SFTP_QUOTE_STAT",
358 "SSH_SFTP_QUOTE_SETSTAT",
359 "SSH_SFTP_QUOTE_SYMLINK",
360 "SSH_SFTP_QUOTE_MKDIR",
361 "SSH_SFTP_QUOTE_RENAME",
362 "SSH_SFTP_QUOTE_RMDIR",
363 "SSH_SFTP_QUOTE_UNLINK",
364 "SSH_SFTP_TRANS_INIT",
365 "SSH_SFTP_UPLOAD_INIT",
366 "SSH_SFTP_CREATE_DIRS_INIT",
367 "SSH_SFTP_CREATE_DIRS",
368 "SSH_SFTP_CREATE_DIRS_MKDIR",
369 "SSH_SFTP_READDIR_INIT",
371 "SSH_SFTP_READDIR_LINK",
372 "SSH_SFTP_READDIR_BOTTOM",
373 "SSH_SFTP_READDIR_DONE",
374 "SSH_SFTP_DOWNLOAD_INIT",
375 "SSH_SFTP_DOWNLOAD_STAT",
378 "SSH_SCP_TRANS_INIT",
379 "SSH_SCP_UPLOAD_INIT",
380 "SSH_SCP_DOWNLOAD_INIT",
384 "SSH_SCP_WAIT_CLOSE",
385 "SSH_SCP_CHANNEL_FREE",
386 "SSH_SESSION_DISCONNECT",
391 struct ssh_conn *sshc = &conn->proto.sshc;
393 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
394 if(sshc->state != nowstate) {
395 infof(conn->data, "SFTP %p state change from %s to %s\n",
396 sshc, names[sshc->state], names[nowstate]);
400 sshc->state = nowstate;
403 /* figure out the path to work with in this particular request */
404 static CURLcode ssh_getworkingpath(struct connectdata *conn,
405 char *homedir, /* when SFTP is used */
406 char **path) /* returns the allocated
407 real path to work with */
409 struct SessionHandle *data = conn->data;
410 char *real_path = NULL;
412 int working_path_len;
414 working_path = curl_easy_unescape(data, data->state.path, 0,
417 return CURLE_OUT_OF_MEMORY;
419 /* Check for /~/ , indicating relative to the user's home directory */
420 if(conn->handler->protocol & CURLPROTO_SCP) {
421 real_path = malloc(working_path_len+1);
422 if(real_path == NULL) {
424 return CURLE_OUT_OF_MEMORY;
426 if((working_path_len > 1) && (working_path[1] == '~'))
427 /* It is referenced to the home directory, so strip the leading '/' */
428 memcpy(real_path, working_path+1, 1 + working_path_len-1);
430 memcpy(real_path, working_path, 1 + working_path_len);
432 else if(conn->handler->protocol & CURLPROTO_SFTP) {
433 if((working_path_len > 1) && (working_path[1] == '~')) {
434 size_t homelen = strlen(homedir);
435 real_path = malloc(homelen + working_path_len + 1);
436 if(real_path == NULL) {
438 return CURLE_OUT_OF_MEMORY;
440 /* It is referenced to the home directory, so strip the
442 memcpy(real_path, homedir, homelen);
443 real_path[homelen] = '/';
444 real_path[homelen+1] = '\0';
445 if(working_path_len > 3) {
446 memcpy(real_path+homelen+1, working_path + 3,
447 1 + working_path_len -3);
451 real_path = malloc(working_path_len+1);
452 if(real_path == NULL) {
454 return CURLE_OUT_OF_MEMORY;
456 memcpy(real_path, working_path, 1+working_path_len);
462 /* store the pointer for the caller to receive */
468 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
469 static int sshkeycallback(CURL *easy,
470 const struct curl_khkey *knownkey, /* known */
471 const struct curl_khkey *foundkey, /* found */
472 enum curl_khmatch match,
480 /* we only allow perfect matches, and we reject everything else */
481 return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
486 * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
489 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
490 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
492 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
496 * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
497 * architectures so we check of the necessary function is present.
499 #ifndef HAVE_LIBSSH2_SCP_SEND64
500 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
502 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
503 (libssh2_uint64_t)d, 0, 0)
507 * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
509 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
510 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
513 static CURLcode ssh_knownhost(struct connectdata *conn)
515 CURLcode result = CURLE_OK;
517 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
518 struct SessionHandle *data = conn->data;
520 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
521 /* we're asked to verify the host against a file */
522 struct ssh_conn *sshc = &conn->proto.sshc;
526 const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
528 int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
533 * A subject to figure out is what host name we need to pass in here.
534 * What host name does OpenSSH store in its file if an IDN name is
537 struct libssh2_knownhost *host;
538 enum curl_khmatch keymatch;
539 curl_sshkeycallback func =
540 data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
541 struct curl_khkey knownkey;
542 struct curl_khkey *knownkeyp = NULL;
543 struct curl_khkey foundkey;
545 keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
546 LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
548 keycheck = libssh2_knownhost_check(sshc->kh,
551 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
552 LIBSSH2_KNOWNHOST_KEYENC_RAW|
556 infof(data, "SSH host check: %d, key: %s\n", keycheck,
557 (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
560 /* setup 'knownkey' */
561 if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
562 knownkey.key = host->key;
564 knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
565 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
566 knownkeyp = &knownkey;
569 /* setup 'foundkey' */
570 foundkey.key = remotekey;
571 foundkey.len = keylen;
572 foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
573 CURLKHTYPE_RSA : CURLKHTYPE_DSS;
576 * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
577 * curl_khmatch enum are ever modified, we need to introduce a
578 * translation table here!
580 keymatch = (enum curl_khmatch)keycheck;
582 /* Ask the callback how to behave */
583 rc = func(data, knownkeyp, /* from the knownhosts file */
584 &foundkey, /* from the remote host */
585 keymatch, data->set.ssh_keyfunc_userp);
588 /* no remotekey means failure! */
589 rc = CURLKHSTAT_REJECT;
592 default: /* unknown return codes will equal reject */
593 case CURLKHSTAT_REJECT:
594 state(conn, SSH_SESSION_FREE);
595 case CURLKHSTAT_DEFER:
596 /* DEFER means bail out but keep the SSH_HOSTKEY state */
597 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
599 case CURLKHSTAT_FINE:
600 case CURLKHSTAT_FINE_ADD_TO_FILE:
602 if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
603 /* the found host+key didn't match but has been told to be fine
604 anyway so we add it in memory */
605 int addrc = libssh2_knownhost_add(sshc->kh,
606 conn->host.name, NULL,
608 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
609 LIBSSH2_KNOWNHOST_KEYENC_RAW|
612 infof(data, "Warning adding the known host %s failed!\n",
614 else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
615 /* now we write the entire in-memory list of known hosts to the
618 libssh2_knownhost_writefile(sshc->kh,
619 data->set.str[STRING_SSH_KNOWNHOSTS],
620 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
622 infof(data, "Warning, writing %s failed!\n",
623 data->set.str[STRING_SSH_KNOWNHOSTS]);
630 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
638 * ssh_statemach_act() runs the SSH state machine as far as it can without
639 * blocking and without reaching the end. The data the pointer 'block' points
640 * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
641 * meaning it wants to be called again when the socket is ready
644 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
646 CURLcode result = CURLE_OK;
647 struct SessionHandle *data = conn->data;
648 struct SSHPROTO *sftp_scp = data->state.proto.ssh;
649 struct ssh_conn *sshc = &conn->proto.sshc;
650 curl_socket_t sock = conn->sock[FIRSTSOCKET];
651 const char *fingerprint;
653 char *new_readdir_line;
654 int rc = LIBSSH2_ERROR_NONE, i;
656 int seekerr = CURL_SEEKFUNC_OK;
657 *block = 0; /* we're not blocking by default */
661 switch(sshc->state) {
663 sshc->secondCreateDirs = 0;
664 sshc->nextstate = SSH_NO_STATE;
665 sshc->actualcode = CURLE_OK;
667 /* Set libssh2 to non-blocking, since everything internally is
669 libssh2_session_set_blocking(sshc->ssh_session, 0);
671 state(conn, SSH_S_STARTUP);
675 rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
676 if(rc == LIBSSH2_ERROR_EAGAIN) {
680 failf(data, "Failure establishing ssh session");
681 state(conn, SSH_SESSION_FREE);
682 sshc->actualcode = CURLE_FAILED_INIT;
686 state(conn, SSH_HOSTKEY);
691 * Before we authenticate we should check the hostkey's fingerprint
692 * against our known hosts. How that is handled (reading from file,
693 * whatever) is up to us.
695 fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
696 LIBSSH2_HOSTKEY_HASH_MD5);
698 /* The fingerprint points to static storage (!), don't free() it. */
699 for(i = 0; i < 16; i++)
700 snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
701 infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
703 /* Before we authenticate we check the hostkey's MD5 fingerprint
704 * against a known fingerprint, if available.
706 if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
707 strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
708 if(!strequal(md5buffer,
709 data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
711 "Denied establishing ssh session: mismatch md5 fingerprint. "
712 "Remote %s is not equal to %s",
713 md5buffer, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
714 state(conn, SSH_SESSION_FREE);
715 result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
718 infof(data, "MD5 checksum match!\n");
719 /* as we already matched, we skip the check for known hosts */
722 result = ssh_knownhost(conn);
725 state(conn, SSH_AUTHLIST);
730 * Figure out authentication methods
731 * NB: As soon as we have provided a username to an openssh server we
732 * must never change it later. Thus, always specify the correct username
733 * here, even though the libssh2 docs kind of indicate that it should be
734 * possible to get a 'generic' list (not user-specific) of authentication
735 * methods, presumably with a blank username. That won't work in my
737 * So always specify it here.
739 sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
741 curlx_uztoui(strlen(conn->user)));
743 if(!sshc->authlist) {
744 if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
745 LIBSSH2_ERROR_EAGAIN) {
746 rc = LIBSSH2_ERROR_EAGAIN;
750 state(conn, SSH_SESSION_FREE);
751 sshc->actualcode = libssh2_session_error_to_CURLE(err);
755 infof(data, "SSH authentication methods available: %s\n",
758 state(conn, SSH_AUTH_PKEY_INIT);
761 case SSH_AUTH_PKEY_INIT:
763 * Check the supported auth types in the order I feel is most secure
764 * with the requested type of authentication
766 sshc->authed = FALSE;
768 if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
769 (strstr(sshc->authlist, "publickey") != NULL)) {
772 sshc->rsa_pub = sshc->rsa = NULL;
774 /* To ponder about: should really the lib be messing about with the
775 HOME environment variable etc? */
776 home = curl_getenv("HOME");
778 if(data->set.str[STRING_SSH_PUBLIC_KEY])
779 sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
781 sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
783 /* as a final resort, try current dir! */
784 sshc->rsa_pub = strdup("id_dsa.pub");
786 if(sshc->rsa_pub == NULL) {
789 state(conn, SSH_SESSION_FREE);
790 sshc->actualcode = CURLE_OUT_OF_MEMORY;
794 if(data->set.str[STRING_SSH_PRIVATE_KEY])
795 sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
797 sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
799 /* as a final resort, try current dir! */
800 sshc->rsa = strdup("id_dsa");
802 if(sshc->rsa == NULL) {
805 Curl_safefree(sshc->rsa_pub);
806 sshc->rsa_pub = NULL;
807 state(conn, SSH_SESSION_FREE);
808 sshc->actualcode = CURLE_OUT_OF_MEMORY;
812 sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
813 if(!sshc->passphrase)
814 sshc->passphrase = "";
819 infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
820 infof(data, "Using ssh private key file %s\n", sshc->rsa);
822 state(conn, SSH_AUTH_PKEY);
825 state(conn, SSH_AUTH_PASS_INIT);
830 /* The function below checks if the files exists, no need to stat() here.
832 rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
837 sshc->rsa, sshc->passphrase);
838 if(rc == LIBSSH2_ERROR_EAGAIN) {
842 Curl_safefree(sshc->rsa_pub);
843 sshc->rsa_pub = NULL;
844 Curl_safefree(sshc->rsa);
849 infof(data, "Initialized SSH public key authentication\n");
850 state(conn, SSH_AUTH_DONE);
854 (void)libssh2_session_last_error(sshc->ssh_session,
856 infof(data, "SSH public key authentication failed: %s\n", err_msg);
857 state(conn, SSH_AUTH_PASS_INIT);
861 case SSH_AUTH_PASS_INIT:
862 if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
863 (strstr(sshc->authlist, "password") != NULL)) {
864 state(conn, SSH_AUTH_PASS);
867 state(conn, SSH_AUTH_HOST_INIT);
872 rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
873 curlx_uztoui(strlen(conn->user)),
875 curlx_uztoui(strlen(conn->passwd)),
877 if(rc == LIBSSH2_ERROR_EAGAIN) {
882 infof(data, "Initialized password authentication\n");
883 state(conn, SSH_AUTH_DONE);
886 state(conn, SSH_AUTH_HOST_INIT);
890 case SSH_AUTH_HOST_INIT:
891 if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
892 (strstr(sshc->authlist, "hostbased") != NULL)) {
893 state(conn, SSH_AUTH_HOST);
896 state(conn, SSH_AUTH_KEY_INIT);
901 state(conn, SSH_AUTH_KEY_INIT);
904 case SSH_AUTH_KEY_INIT:
905 if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
906 && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
907 state(conn, SSH_AUTH_KEY);
910 state(conn, SSH_AUTH_DONE);
915 /* Authentication failed. Continue with keyboard-interactive now. */
916 rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
921 if(rc == LIBSSH2_ERROR_EAGAIN) {
926 infof(data, "Initialized keyboard interactive authentication\n");
928 state(conn, SSH_AUTH_DONE);
933 failf(data, "Authentication failure");
934 state(conn, SSH_SESSION_FREE);
935 sshc->actualcode = CURLE_LOGIN_DENIED;
940 * At this point we have an authenticated ssh session.
942 infof(data, "Authentication complete\n");
944 Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
947 conn->writesockfd = CURL_SOCKET_BAD;
949 if(conn->handler->protocol == CURLPROTO_SFTP) {
950 state(conn, SSH_SFTP_INIT);
953 infof(data, "SSH CONNECT phase done\n");
954 state(conn, SSH_STOP);
959 * Start the libssh2 sftp session
961 sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
962 if(!sshc->sftp_session) {
963 if(libssh2_session_last_errno(sshc->ssh_session) ==
964 LIBSSH2_ERROR_EAGAIN) {
965 rc = LIBSSH2_ERROR_EAGAIN;
971 (void)libssh2_session_last_error(sshc->ssh_session,
973 failf(data, "Failure initializing sftp session: %s", err_msg);
974 state(conn, SSH_SESSION_FREE);
975 sshc->actualcode = CURLE_FAILED_INIT;
979 state(conn, SSH_SFTP_REALPATH);
982 case SSH_SFTP_REALPATH:
984 char tempHome[PATH_MAX];
987 * Get the "home" directory
989 rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
990 tempHome, PATH_MAX-1);
991 if(rc == LIBSSH2_ERROR_EAGAIN) {
995 /* It seems that this string is not always NULL terminated */
997 sshc->homedir = strdup(tempHome);
999 state(conn, SSH_SFTP_CLOSE);
1000 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1003 conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1006 /* Return the error type */
1007 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1008 result = sftp_libssh2_error_to_CURLE(err);
1009 sshc->actualcode = result?result:CURLE_SSH;
1010 DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1012 state(conn, SSH_STOP);
1016 /* This is the last step in the SFTP connect phase. Do note that while
1017 we get the homedir here, we get the "workingpath" in the DO action
1018 since the homedir will remain the same between request but the
1019 working path will not. */
1020 DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1021 state(conn, SSH_STOP);
1024 case SSH_SFTP_QUOTE_INIT:
1026 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1028 sshc->actualcode = result;
1029 state(conn, SSH_STOP);
1033 if(data->set.quote) {
1034 infof(data, "Sending quote commands\n");
1035 sshc->quote_item = data->set.quote;
1036 state(conn, SSH_SFTP_QUOTE);
1039 state(conn, SSH_SFTP_TRANS_INIT);
1043 case SSH_SFTP_POSTQUOTE_INIT:
1044 if(data->set.postquote) {
1045 infof(data, "Sending quote commands\n");
1046 sshc->quote_item = data->set.postquote;
1047 state(conn, SSH_SFTP_QUOTE);
1050 state(conn, SSH_STOP);
1054 case SSH_SFTP_QUOTE:
1055 /* Send any quote commands */
1060 * Support some of the "FTP" commands
1062 char *cmd = sshc->quote_item->data;
1063 sshc->acceptfail = FALSE;
1065 /* if a command starts with an asterisk, which a legal SFTP command never
1066 can, the command will be allowed to fail without it causing any
1067 aborts or cancels etc. It will cause libcurl to act as if the command
1068 is successful, whatever the server reponds. */
1072 sshc->acceptfail = TRUE;
1075 if(curl_strequal("pwd", cmd)) {
1076 /* output debug output if that is requested */
1077 char *tmp = aprintf("257 \"%s\" is current directory.\n",
1080 result = CURLE_OUT_OF_MEMORY;
1081 state(conn, SSH_SFTP_CLOSE);
1082 sshc->nextstate = SSH_NO_STATE;
1085 if(data->set.verbose) {
1086 Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1087 Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1089 /* this sends an FTP-like "header" to the header callback so that the
1090 current directory can be read very similar to how it is read when
1091 using ordinary FTP. */
1092 result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1094 state(conn, SSH_SFTP_NEXT_QUOTE);
1099 * the arguments following the command must be separated from the
1100 * command with a space so we can check for it unconditionally
1102 cp = strchr(cmd, ' ');
1104 failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1105 state(conn, SSH_SFTP_CLOSE);
1106 sshc->nextstate = SSH_NO_STATE;
1107 sshc->actualcode = CURLE_QUOTE_ERROR;
1112 * also, every command takes at least one argument so we get that
1113 * first argument right now
1115 result = get_pathname(&cp, &sshc->quote_path1);
1117 if(result == CURLE_OUT_OF_MEMORY)
1118 failf(data, "Out of memory");
1120 failf(data, "Syntax error: Bad first parameter");
1121 state(conn, SSH_SFTP_CLOSE);
1122 sshc->nextstate = SSH_NO_STATE;
1123 sshc->actualcode = result;
1128 * SFTP is a binary protocol, so we don't send text commands to
1129 * the server. Instead, we scan for commands for commands used by
1130 * OpenSSH's sftp program and call the appropriate libssh2
1133 if(curl_strnequal(cmd, "chgrp ", 6) ||
1134 curl_strnequal(cmd, "chmod ", 6) ||
1135 curl_strnequal(cmd, "chown ", 6) ) {
1136 /* attribute change */
1138 /* sshc->quote_path1 contains the mode to set */
1139 /* get the destination */
1140 result = get_pathname(&cp, &sshc->quote_path2);
1142 if(result == CURLE_OUT_OF_MEMORY)
1143 failf(data, "Out of memory");
1145 failf(data, "Syntax error in chgrp/chmod/chown: "
1146 "Bad second parameter");
1147 Curl_safefree(sshc->quote_path1);
1148 sshc->quote_path1 = NULL;
1149 state(conn, SSH_SFTP_CLOSE);
1150 sshc->nextstate = SSH_NO_STATE;
1151 sshc->actualcode = result;
1154 memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1155 state(conn, SSH_SFTP_QUOTE_STAT);
1158 else if(curl_strnequal(cmd, "ln ", 3) ||
1159 curl_strnequal(cmd, "symlink ", 8)) {
1160 /* symbolic linking */
1161 /* sshc->quote_path1 is the source */
1162 /* get the destination */
1163 result = get_pathname(&cp, &sshc->quote_path2);
1165 if(result == CURLE_OUT_OF_MEMORY)
1166 failf(data, "Out of memory");
1169 "Syntax error in ln/symlink: Bad second parameter");
1170 Curl_safefree(sshc->quote_path1);
1171 sshc->quote_path1 = NULL;
1172 state(conn, SSH_SFTP_CLOSE);
1173 sshc->nextstate = SSH_NO_STATE;
1174 sshc->actualcode = result;
1177 state(conn, SSH_SFTP_QUOTE_SYMLINK);
1180 else if(curl_strnequal(cmd, "mkdir ", 6)) {
1182 state(conn, SSH_SFTP_QUOTE_MKDIR);
1185 else if(curl_strnequal(cmd, "rename ", 7)) {
1187 /* first param is the source path */
1188 /* second param is the dest. path */
1189 result = get_pathname(&cp, &sshc->quote_path2);
1191 if(result == CURLE_OUT_OF_MEMORY)
1192 failf(data, "Out of memory");
1194 failf(data, "Syntax error in rename: Bad second parameter");
1195 Curl_safefree(sshc->quote_path1);
1196 sshc->quote_path1 = NULL;
1197 state(conn, SSH_SFTP_CLOSE);
1198 sshc->nextstate = SSH_NO_STATE;
1199 sshc->actualcode = result;
1202 state(conn, SSH_SFTP_QUOTE_RENAME);
1205 else if(curl_strnequal(cmd, "rmdir ", 6)) {
1207 state(conn, SSH_SFTP_QUOTE_RMDIR);
1210 else if(curl_strnequal(cmd, "rm ", 3)) {
1211 state(conn, SSH_SFTP_QUOTE_UNLINK);
1215 failf(data, "Unknown SFTP command");
1216 Curl_safefree(sshc->quote_path1);
1217 sshc->quote_path1 = NULL;
1218 Curl_safefree(sshc->quote_path2);
1219 sshc->quote_path2 = NULL;
1220 state(conn, SSH_SFTP_CLOSE);
1221 sshc->nextstate = SSH_NO_STATE;
1222 sshc->actualcode = CURLE_QUOTE_ERROR;
1226 if(!sshc->quote_item) {
1227 state(conn, SSH_SFTP_TRANS_INIT);
1231 case SSH_SFTP_NEXT_QUOTE:
1232 if(sshc->quote_path1) {
1233 Curl_safefree(sshc->quote_path1);
1234 sshc->quote_path1 = NULL;
1236 if(sshc->quote_path2) {
1237 Curl_safefree(sshc->quote_path2);
1238 sshc->quote_path2 = NULL;
1241 sshc->quote_item = sshc->quote_item->next;
1243 if(sshc->quote_item) {
1244 state(conn, SSH_SFTP_QUOTE);
1247 if(sshc->nextstate != SSH_NO_STATE) {
1248 state(conn, sshc->nextstate);
1249 sshc->nextstate = SSH_NO_STATE;
1252 state(conn, SSH_SFTP_TRANS_INIT);
1257 case SSH_SFTP_QUOTE_STAT:
1259 char *cmd = sshc->quote_item->data;
1260 sshc->acceptfail = FALSE;
1262 /* if a command starts with an asterisk, which a legal SFTP command never
1263 can, the command will be allowed to fail without it causing any
1264 aborts or cancels etc. It will cause libcurl to act as if the command
1265 is successful, whatever the server reponds. */
1269 sshc->acceptfail = TRUE;
1272 if(!curl_strnequal(cmd, "chmod", 5)) {
1273 /* Since chown and chgrp only set owner OR group but libssh2 wants to
1274 * set them both at once, we need to obtain the current ownership
1275 * first. This takes an extra protocol round trip.
1277 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1278 curlx_uztoui(strlen(sshc->quote_path2)),
1280 &sshc->quote_attrs);
1281 if(rc == LIBSSH2_ERROR_EAGAIN) {
1284 else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1285 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1286 Curl_safefree(sshc->quote_path1);
1287 sshc->quote_path1 = NULL;
1288 Curl_safefree(sshc->quote_path2);
1289 sshc->quote_path2 = NULL;
1290 failf(data, "Attempt to get SFTP stats failed: %s",
1291 sftp_libssh2_strerror(err));
1292 state(conn, SSH_SFTP_CLOSE);
1293 sshc->nextstate = SSH_NO_STATE;
1294 sshc->actualcode = CURLE_QUOTE_ERROR;
1299 /* Now set the new attributes... */
1300 if(curl_strnequal(cmd, "chgrp", 5)) {
1301 sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1302 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1303 if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1304 !sshc->acceptfail) {
1305 Curl_safefree(sshc->quote_path1);
1306 sshc->quote_path1 = NULL;
1307 Curl_safefree(sshc->quote_path2);
1308 sshc->quote_path2 = NULL;
1309 failf(data, "Syntax error: chgrp gid not a number");
1310 state(conn, SSH_SFTP_CLOSE);
1311 sshc->nextstate = SSH_NO_STATE;
1312 sshc->actualcode = CURLE_QUOTE_ERROR;
1316 else if(curl_strnequal(cmd, "chmod", 5)) {
1317 sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1318 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1319 /* permissions are octal */
1320 if(sshc->quote_attrs.permissions == 0 &&
1321 !ISDIGIT(sshc->quote_path1[0])) {
1322 Curl_safefree(sshc->quote_path1);
1323 sshc->quote_path1 = NULL;
1324 Curl_safefree(sshc->quote_path2);
1325 sshc->quote_path2 = NULL;
1326 failf(data, "Syntax error: chmod permissions not a number");
1327 state(conn, SSH_SFTP_CLOSE);
1328 sshc->nextstate = SSH_NO_STATE;
1329 sshc->actualcode = CURLE_QUOTE_ERROR;
1333 else if(curl_strnequal(cmd, "chown", 5)) {
1334 sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1335 sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1336 if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1337 !sshc->acceptfail) {
1338 Curl_safefree(sshc->quote_path1);
1339 sshc->quote_path1 = NULL;
1340 Curl_safefree(sshc->quote_path2);
1341 sshc->quote_path2 = NULL;
1342 failf(data, "Syntax error: chown uid not a number");
1343 state(conn, SSH_SFTP_CLOSE);
1344 sshc->nextstate = SSH_NO_STATE;
1345 sshc->actualcode = CURLE_QUOTE_ERROR;
1350 /* Now send the completed structure... */
1351 state(conn, SSH_SFTP_QUOTE_SETSTAT);
1355 case SSH_SFTP_QUOTE_SETSTAT:
1356 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1357 curlx_uztoui(strlen(sshc->quote_path2)),
1358 LIBSSH2_SFTP_SETSTAT,
1359 &sshc->quote_attrs);
1360 if(rc == LIBSSH2_ERROR_EAGAIN) {
1363 else if(rc != 0 && !sshc->acceptfail) {
1364 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1365 Curl_safefree(sshc->quote_path1);
1366 sshc->quote_path1 = NULL;
1367 Curl_safefree(sshc->quote_path2);
1368 sshc->quote_path2 = NULL;
1369 failf(data, "Attempt to set SFTP stats failed: %s",
1370 sftp_libssh2_strerror(err));
1371 state(conn, SSH_SFTP_CLOSE);
1372 sshc->nextstate = SSH_NO_STATE;
1373 sshc->actualcode = CURLE_QUOTE_ERROR;
1376 state(conn, SSH_SFTP_NEXT_QUOTE);
1379 case SSH_SFTP_QUOTE_SYMLINK:
1380 rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1381 curlx_uztoui(strlen(sshc->quote_path1)),
1383 curlx_uztoui(strlen(sshc->quote_path2)),
1384 LIBSSH2_SFTP_SYMLINK);
1385 if(rc == LIBSSH2_ERROR_EAGAIN) {
1388 else if(rc != 0 && !sshc->acceptfail) {
1389 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1390 Curl_safefree(sshc->quote_path1);
1391 sshc->quote_path1 = NULL;
1392 Curl_safefree(sshc->quote_path2);
1393 sshc->quote_path2 = NULL;
1394 failf(data, "symlink command failed: %s",
1395 sftp_libssh2_strerror(err));
1396 state(conn, SSH_SFTP_CLOSE);
1397 sshc->nextstate = SSH_NO_STATE;
1398 sshc->actualcode = CURLE_QUOTE_ERROR;
1401 state(conn, SSH_SFTP_NEXT_QUOTE);
1404 case SSH_SFTP_QUOTE_MKDIR:
1405 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1406 curlx_uztoui(strlen(sshc->quote_path1)),
1407 data->set.new_directory_perms);
1408 if(rc == LIBSSH2_ERROR_EAGAIN) {
1411 else if(rc != 0 && !sshc->acceptfail) {
1412 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1413 Curl_safefree(sshc->quote_path1);
1414 sshc->quote_path1 = NULL;
1415 failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1416 state(conn, SSH_SFTP_CLOSE);
1417 sshc->nextstate = SSH_NO_STATE;
1418 sshc->actualcode = CURLE_QUOTE_ERROR;
1421 state(conn, SSH_SFTP_NEXT_QUOTE);
1424 case SSH_SFTP_QUOTE_RENAME:
1425 rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1426 curlx_uztoui(strlen(sshc->quote_path1)),
1428 curlx_uztoui(strlen(sshc->quote_path2)),
1429 LIBSSH2_SFTP_RENAME_OVERWRITE |
1430 LIBSSH2_SFTP_RENAME_ATOMIC |
1431 LIBSSH2_SFTP_RENAME_NATIVE);
1433 if(rc == LIBSSH2_ERROR_EAGAIN) {
1436 else if(rc != 0 && !sshc->acceptfail) {
1437 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1438 Curl_safefree(sshc->quote_path1);
1439 sshc->quote_path1 = NULL;
1440 Curl_safefree(sshc->quote_path2);
1441 sshc->quote_path2 = NULL;
1442 failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1443 state(conn, SSH_SFTP_CLOSE);
1444 sshc->nextstate = SSH_NO_STATE;
1445 sshc->actualcode = CURLE_QUOTE_ERROR;
1448 state(conn, SSH_SFTP_NEXT_QUOTE);
1451 case SSH_SFTP_QUOTE_RMDIR:
1452 rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1453 curlx_uztoui(strlen(sshc->quote_path1)));
1454 if(rc == LIBSSH2_ERROR_EAGAIN) {
1457 else if(rc != 0 && !sshc->acceptfail) {
1458 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1459 Curl_safefree(sshc->quote_path1);
1460 sshc->quote_path1 = NULL;
1461 failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1462 state(conn, SSH_SFTP_CLOSE);
1463 sshc->nextstate = SSH_NO_STATE;
1464 sshc->actualcode = CURLE_QUOTE_ERROR;
1467 state(conn, SSH_SFTP_NEXT_QUOTE);
1470 case SSH_SFTP_QUOTE_UNLINK:
1471 rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1472 curlx_uztoui(strlen(sshc->quote_path1)));
1473 if(rc == LIBSSH2_ERROR_EAGAIN) {
1476 else if(rc != 0 && !sshc->acceptfail) {
1477 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1478 Curl_safefree(sshc->quote_path1);
1479 sshc->quote_path1 = NULL;
1480 failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1481 state(conn, SSH_SFTP_CLOSE);
1482 sshc->nextstate = SSH_NO_STATE;
1483 sshc->actualcode = CURLE_QUOTE_ERROR;
1486 state(conn, SSH_SFTP_NEXT_QUOTE);
1489 case SSH_SFTP_TRANS_INIT:
1490 if(data->set.upload)
1491 state(conn, SSH_SFTP_UPLOAD_INIT);
1493 if(data->set.opt_no_body)
1494 state(conn, SSH_STOP);
1495 else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1496 state(conn, SSH_SFTP_READDIR_INIT);
1498 state(conn, SSH_SFTP_DOWNLOAD_INIT);
1502 case SSH_SFTP_UPLOAD_INIT:
1504 unsigned long flags;
1506 * NOTE!!! libssh2 requires that the destination path is a full path
1507 * that includes the destination file and name OR ends in a "/"
1508 * If this is not done the destination file will be named the
1509 * same name as the last directory in the path.
1512 if(data->state.resume_from != 0) {
1513 LIBSSH2_SFTP_ATTRIBUTES attrs;
1514 if(data->state.resume_from < 0) {
1515 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1516 curlx_uztoui(strlen(sftp_scp->path)),
1517 LIBSSH2_SFTP_STAT, &attrs);
1518 if(rc == LIBSSH2_ERROR_EAGAIN) {
1522 data->state.resume_from = 0;
1525 curl_off_t size = attrs.filesize;
1527 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
1528 return CURLE_BAD_DOWNLOAD_RESUME;
1530 data->state.resume_from = attrs.filesize;
1535 if(data->set.ftp_append)
1536 /* Try to open for append, but create if nonexisting */
1537 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1538 else if(data->state.resume_from > 0)
1539 /* If we have restart position then open for append */
1540 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1542 /* Clear file before writing (normal behaviour) */
1543 flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1546 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1547 curlx_uztoui(strlen(sftp_scp->path)),
1548 flags, data->set.new_file_perms,
1549 LIBSSH2_SFTP_OPENFILE);
1551 if(!sshc->sftp_handle) {
1552 rc = libssh2_session_last_errno(sshc->ssh_session);
1554 if(LIBSSH2_ERROR_EAGAIN == rc)
1557 if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1558 /* only when there was an SFTP protocol error can we extract
1560 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1562 err = -1; /* not an sftp error at all */
1564 if(sshc->secondCreateDirs) {
1565 state(conn, SSH_SFTP_CLOSE);
1566 sshc->actualcode = err>= LIBSSH2_FX_OK?
1567 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1568 failf(data, "Creating the dir/file failed: %s",
1569 sftp_libssh2_strerror(err));
1572 else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1573 (err == LIBSSH2_FX_FAILURE) ||
1574 (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1575 (data->set.ftp_create_missing_dirs &&
1576 (strlen(sftp_scp->path) > 1))) {
1577 /* try to create the path remotely */
1578 sshc->secondCreateDirs = 1;
1579 state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1582 state(conn, SSH_SFTP_CLOSE);
1583 sshc->actualcode = err>= LIBSSH2_FX_OK?
1584 sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1585 if(!sshc->actualcode) {
1586 /* Sometimes, for some reason libssh2_sftp_last_error() returns
1587 zero even though libssh2_sftp_open() failed previously! We need
1588 to work around that! */
1589 sshc->actualcode = CURLE_SSH;
1592 failf(data, "Upload failed: %s (%d/%d)",
1593 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1599 /* If we have restart point then we need to seek to the correct
1601 if(data->state.resume_from > 0) {
1602 /* Let's read off the proper amount of bytes from the input. */
1603 if(conn->seek_func) {
1604 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1608 if(seekerr != CURL_SEEKFUNC_OK) {
1610 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1611 failf(data, "Could not seek stream");
1612 return CURLE_FTP_COULDNT_USE_REST;
1614 /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1616 curl_off_t passed=0;
1618 size_t readthisamountnow =
1619 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1620 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1622 size_t actuallyread =
1623 conn->fread_func(data->state.buffer, 1, readthisamountnow,
1626 passed += actuallyread;
1627 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1628 /* this checks for greater-than only to make sure that the
1629 CURL_READFUNC_ABORT return code still aborts */
1630 failf(data, "Failed to read data");
1631 return CURLE_FTP_COULDNT_USE_REST;
1633 } while(passed < data->state.resume_from);
1637 /* now, decrease the size of the read */
1638 if(data->set.infilesize > 0) {
1639 data->set.infilesize -= data->state.resume_from;
1640 data->req.size = data->set.infilesize;
1641 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1644 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1646 if(data->set.infilesize > 0) {
1647 data->req.size = data->set.infilesize;
1648 Curl_pgrsSetUploadSize(data, data->set.infilesize);
1651 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1653 /* not set by Curl_setup_transfer to preserve keepon bits */
1654 conn->sockfd = conn->writesockfd;
1657 state(conn, SSH_SFTP_CLOSE);
1658 sshc->actualcode = result;
1661 /* store this original bitmask setup to use later on if we can't
1662 figure out a "real" bitmask */
1663 sshc->orig_waitfor = data->req.keepon;
1665 /* we want to use the _sending_ function even when the socket turns
1666 out readable as the underlying libssh2 sftp send function will deal
1667 with both accordingly */
1668 conn->cselect_bits = CURL_CSELECT_OUT;
1670 /* since we don't really wait for anything at this point, we want the
1671 state machine to move on as soon as possible so we set a very short
1673 Curl_expire(data, 1);
1675 state(conn, SSH_STOP);
1680 case SSH_SFTP_CREATE_DIRS_INIT:
1681 if(strlen(sftp_scp->path) > 1) {
1682 sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1683 state(conn, SSH_SFTP_CREATE_DIRS);
1686 state(conn, SSH_SFTP_UPLOAD_INIT);
1690 case SSH_SFTP_CREATE_DIRS:
1691 if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
1692 *sshc->slash_pos = 0;
1694 infof(data, "Creating directory '%s'\n", sftp_scp->path);
1695 state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1699 state(conn, SSH_SFTP_UPLOAD_INIT);
1703 case SSH_SFTP_CREATE_DIRS_MKDIR:
1704 /* 'mode' - parameter is preliminary - default to 0644 */
1705 rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1706 curlx_uztoui(strlen(sftp_scp->path)),
1707 data->set.new_directory_perms);
1708 if(rc == LIBSSH2_ERROR_EAGAIN) {
1711 *sshc->slash_pos = '/';
1714 unsigned int sftp_err = 0;
1716 * Abort if failure wasn't that the dir already exists or the
1717 * permission was denied (creation might succeed further down the
1718 * path) - retry on unspecific FAILURE also
1720 sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session));
1721 if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1722 (sftp_err != LIBSSH2_FX_FAILURE) &&
1723 (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
1724 result = sftp_libssh2_error_to_CURLE(sftp_err);
1725 state(conn, SSH_SFTP_CLOSE);
1726 sshc->actualcode = result?result:CURLE_SSH;
1730 state(conn, SSH_SFTP_CREATE_DIRS);
1733 case SSH_SFTP_READDIR_INIT:
1735 * This is a directory that we are trying to get, so produce a directory
1738 sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1741 strlen(sftp_scp->path)),
1742 0, 0, LIBSSH2_SFTP_OPENDIR);
1743 if(!sshc->sftp_handle) {
1744 if(libssh2_session_last_errno(sshc->ssh_session) ==
1745 LIBSSH2_ERROR_EAGAIN) {
1746 rc = LIBSSH2_ERROR_EAGAIN;
1750 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1751 failf(data, "Could not open directory for reading: %s",
1752 sftp_libssh2_strerror(err));
1753 state(conn, SSH_SFTP_CLOSE);
1754 result = sftp_libssh2_error_to_CURLE(err);
1755 sshc->actualcode = result?result:CURLE_SSH;
1759 if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1760 state(conn, SSH_SFTP_CLOSE);
1761 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1764 if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1765 Curl_safefree(sshc->readdir_filename);
1766 sshc->readdir_filename = NULL;
1767 state(conn, SSH_SFTP_CLOSE);
1768 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1771 state(conn, SSH_SFTP_READDIR);
1774 case SSH_SFTP_READDIR:
1775 sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1776 sshc->readdir_filename,
1778 sshc->readdir_longentry,
1780 &sshc->readdir_attrs);
1781 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1782 rc = LIBSSH2_ERROR_EAGAIN;
1785 if(sshc->readdir_len > 0) {
1786 sshc->readdir_filename[sshc->readdir_len] = '\0';
1788 if(data->set.ftp_list_only) {
1791 tmpLine = aprintf("%s\n", sshc->readdir_filename);
1792 if(tmpLine == NULL) {
1793 state(conn, SSH_SFTP_CLOSE);
1794 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1797 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1798 tmpLine, sshc->readdir_len+1);
1799 Curl_safefree(tmpLine);
1802 state(conn, SSH_STOP);
1805 /* since this counts what we send to the client, we include the
1806 newline in this counter */
1807 data->req.bytecount += sshc->readdir_len+1;
1809 /* output debug output if that is requested */
1810 if(data->set.verbose) {
1811 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1812 sshc->readdir_len, conn);
1816 sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1817 sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1818 sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1819 if(!sshc->readdir_line) {
1820 Curl_safefree(sshc->readdir_filename);
1821 sshc->readdir_filename = NULL;
1822 Curl_safefree(sshc->readdir_longentry);
1823 sshc->readdir_longentry = NULL;
1824 state(conn, SSH_SFTP_CLOSE);
1825 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1829 memcpy(sshc->readdir_line, sshc->readdir_longentry,
1830 sshc->readdir_currLen);
1831 if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1832 ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1833 LIBSSH2_SFTP_S_IFLNK)) {
1834 sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1835 if(sshc->readdir_linkPath == NULL) {
1836 Curl_safefree(sshc->readdir_filename);
1837 sshc->readdir_filename = NULL;
1838 Curl_safefree(sshc->readdir_longentry);
1839 sshc->readdir_longentry = NULL;
1840 state(conn, SSH_SFTP_CLOSE);
1841 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1845 snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1846 sshc->readdir_filename);
1847 state(conn, SSH_SFTP_READDIR_LINK);
1850 state(conn, SSH_SFTP_READDIR_BOTTOM);
1854 else if(sshc->readdir_len == 0) {
1855 Curl_safefree(sshc->readdir_filename);
1856 sshc->readdir_filename = NULL;
1857 Curl_safefree(sshc->readdir_longentry);
1858 sshc->readdir_longentry = NULL;
1859 state(conn, SSH_SFTP_READDIR_DONE);
1862 else if(sshc->readdir_len <= 0) {
1863 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1864 result = sftp_libssh2_error_to_CURLE(err);
1865 sshc->actualcode = result?result:CURLE_SSH;
1866 failf(data, "Could not open remote file for reading: %s :: %d",
1867 sftp_libssh2_strerror(err),
1868 libssh2_session_last_errno(sshc->ssh_session));
1869 Curl_safefree(sshc->readdir_filename);
1870 sshc->readdir_filename = NULL;
1871 Curl_safefree(sshc->readdir_longentry);
1872 sshc->readdir_longentry = NULL;
1873 state(conn, SSH_SFTP_CLOSE);
1878 case SSH_SFTP_READDIR_LINK:
1880 libssh2_sftp_symlink_ex(sshc->sftp_session,
1881 sshc->readdir_linkPath,
1882 curlx_uztoui(strlen(sshc->readdir_linkPath)),
1883 sshc->readdir_filename,
1884 PATH_MAX, LIBSSH2_SFTP_READLINK);
1885 if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1886 rc = LIBSSH2_ERROR_EAGAIN;
1889 Curl_safefree(sshc->readdir_linkPath);
1890 sshc->readdir_linkPath = NULL;
1892 /* get room for the filename and extra output */
1893 sshc->readdir_totalLen += 4 + sshc->readdir_len;
1894 new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
1895 if(!new_readdir_line) {
1896 Curl_safefree(sshc->readdir_line);
1897 sshc->readdir_line = NULL;
1898 Curl_safefree(sshc->readdir_filename);
1899 sshc->readdir_filename = NULL;
1900 Curl_safefree(sshc->readdir_longentry);
1901 sshc->readdir_longentry = NULL;
1902 state(conn, SSH_SFTP_CLOSE);
1903 sshc->actualcode = CURLE_OUT_OF_MEMORY;
1906 sshc->readdir_line = new_readdir_line;
1908 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1909 sshc->readdir_currLen,
1910 sshc->readdir_totalLen -
1911 sshc->readdir_currLen,
1913 sshc->readdir_filename);
1915 state(conn, SSH_SFTP_READDIR_BOTTOM);
1918 case SSH_SFTP_READDIR_BOTTOM:
1919 sshc->readdir_currLen += snprintf(sshc->readdir_line +
1920 sshc->readdir_currLen,
1921 sshc->readdir_totalLen -
1922 sshc->readdir_currLen, "\n");
1923 result = Curl_client_write(conn, CLIENTWRITE_BODY,
1925 sshc->readdir_currLen);
1927 if(result == CURLE_OK) {
1929 /* output debug output if that is requested */
1930 if(data->set.verbose) {
1931 Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
1932 sshc->readdir_currLen, conn);
1934 data->req.bytecount += sshc->readdir_currLen;
1936 Curl_safefree(sshc->readdir_line);
1937 sshc->readdir_line = NULL;
1939 state(conn, SSH_STOP);
1942 state(conn, SSH_SFTP_READDIR);
1945 case SSH_SFTP_READDIR_DONE:
1946 if(libssh2_sftp_closedir(sshc->sftp_handle) ==
1947 LIBSSH2_ERROR_EAGAIN) {
1948 rc = LIBSSH2_ERROR_EAGAIN;
1951 sshc->sftp_handle = NULL;
1952 Curl_safefree(sshc->readdir_filename);
1953 sshc->readdir_filename = NULL;
1954 Curl_safefree(sshc->readdir_longentry);
1955 sshc->readdir_longentry = NULL;
1957 /* no data to transfer */
1958 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
1959 state(conn, SSH_STOP);
1962 case SSH_SFTP_DOWNLOAD_INIT:
1964 * Work on getting the specified file
1967 libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1968 curlx_uztoui(strlen(sftp_scp->path)),
1969 LIBSSH2_FXF_READ, data->set.new_file_perms,
1970 LIBSSH2_SFTP_OPENFILE);
1971 if(!sshc->sftp_handle) {
1972 if(libssh2_session_last_errno(sshc->ssh_session) ==
1973 LIBSSH2_ERROR_EAGAIN) {
1974 rc = LIBSSH2_ERROR_EAGAIN;
1978 err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
1979 failf(data, "Could not open remote file for reading: %s",
1980 sftp_libssh2_strerror(err));
1981 state(conn, SSH_SFTP_CLOSE);
1982 result = sftp_libssh2_error_to_CURLE(err);
1983 sshc->actualcode = result?result:CURLE_SSH;
1987 state(conn, SSH_SFTP_DOWNLOAD_STAT);
1990 case SSH_SFTP_DOWNLOAD_STAT:
1992 LIBSSH2_SFTP_ATTRIBUTES attrs;
1994 rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1995 curlx_uztoui(strlen(sftp_scp->path)),
1996 LIBSSH2_SFTP_STAT, &attrs);
1997 if(rc == LIBSSH2_ERROR_EAGAIN) {
2002 * libssh2_sftp_open() didn't return an error, so maybe the server
2003 * just doesn't support stat()
2005 data->req.size = -1;
2006 data->req.maxdownload = -1;
2009 curl_off_t size = attrs.filesize;
2012 failf(data, "Bad file size (%" FORMAT_OFF_T ")", size);
2013 return CURLE_BAD_DOWNLOAD_RESUME;
2015 if(conn->data->state.use_range) {
2016 curl_off_t from, to;
2020 from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2021 while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2023 to=curlx_strtoofft(ptr, &ptr2, 0);
2024 if((ptr == ptr2) /* no "to" value given */
2029 /* from is relative to end of file */
2033 failf(data, "Offset (%"
2034 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2035 from, attrs.filesize);
2036 return CURLE_BAD_DOWNLOAD_RESUME;
2043 size = to - from + 1;
2046 SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2048 data->req.size = size;
2049 data->req.maxdownload = size;
2050 Curl_pgrsSetDownloadSize(data, size);
2053 /* We can resume if we can seek to the resume position */
2054 if(data->state.resume_from) {
2055 if(data->state.resume_from < 0) {
2056 /* We're supposed to download the last abs(from) bytes */
2057 if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2058 failf(data, "Offset (%"
2059 FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
2060 data->state.resume_from, attrs.filesize);
2061 return CURLE_BAD_DOWNLOAD_RESUME;
2063 /* download from where? */
2064 data->state.resume_from += attrs.filesize;
2067 if((curl_off_t)attrs.filesize < data->state.resume_from) {
2068 failf(data, "Offset (%" FORMAT_OFF_T
2069 ") was beyond file size (%" FORMAT_OFF_T ")",
2070 data->state.resume_from, attrs.filesize);
2071 return CURLE_BAD_DOWNLOAD_RESUME;
2074 /* Does a completed file need to be seeked and started or closed ? */
2075 /* Now store the number of bytes we are expected to download */
2076 data->req.size = attrs.filesize - data->state.resume_from;
2077 data->req.maxdownload = attrs.filesize - data->state.resume_from;
2078 Curl_pgrsSetDownloadSize(data,
2079 attrs.filesize - data->state.resume_from);
2080 SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2083 /* Setup the actual download */
2084 if(data->req.size == 0) {
2085 /* no data to transfer */
2086 Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2087 infof(data, "File already completely downloaded\n");
2088 state(conn, SSH_STOP);
2092 Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2093 FALSE, NULL, -1, NULL);
2095 /* not set by Curl_setup_transfer to preserve keepon bits */
2096 conn->writesockfd = conn->sockfd;
2098 /* we want to use the _receiving_ function even when the socket turns
2099 out writableable as the underlying libssh2 recv function will deal
2100 with both accordingly */
2101 conn->cselect_bits = CURL_CSELECT_IN;
2104 state(conn, SSH_SFTP_CLOSE);
2105 sshc->actualcode = result;
2108 state(conn, SSH_STOP);
2112 case SSH_SFTP_CLOSE:
2113 if(sshc->sftp_handle) {
2114 rc = libssh2_sftp_close(sshc->sftp_handle);
2115 if(rc == LIBSSH2_ERROR_EAGAIN) {
2119 infof(data, "Failed to close libssh2 file\n");
2121 sshc->sftp_handle = NULL;
2124 Curl_safefree(sftp_scp->path);
2125 sftp_scp->path = NULL;
2128 DEBUGF(infof(data, "SFTP DONE done\n"));
2130 /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2131 After nextstate is executed,the control should come back to
2132 SSH_SFTP_CLOSE to pass the correct result back */
2133 if(sshc->nextstate != SSH_NO_STATE) {
2134 state(conn, sshc->nextstate);
2135 sshc->nextstate = SSH_SFTP_CLOSE;
2138 state(conn, SSH_STOP);
2139 result = sshc->actualcode;
2143 case SSH_SFTP_SHUTDOWN:
2144 /* during times we get here due to a broken transfer and then the
2145 sftp_handle might not have been taken down so make sure that is done
2146 before we proceed */
2148 if(sshc->sftp_handle) {
2149 rc = libssh2_sftp_close(sshc->sftp_handle);
2150 if(rc == LIBSSH2_ERROR_EAGAIN) {
2154 infof(data, "Failed to close libssh2 file\n");
2156 sshc->sftp_handle = NULL;
2158 if(sshc->sftp_session) {
2159 rc = libssh2_sftp_shutdown(sshc->sftp_session);
2160 if(rc == LIBSSH2_ERROR_EAGAIN) {
2164 infof(data, "Failed to stop libssh2 sftp subsystem\n");
2166 sshc->sftp_session = NULL;
2169 Curl_safefree(sshc->homedir);
2170 sshc->homedir = NULL;
2171 conn->data->state.most_recent_ftp_entrypath = NULL;
2173 state(conn, SSH_SESSION_DISCONNECT);
2176 case SSH_SCP_TRANS_INIT:
2177 result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2179 sshc->actualcode = result;
2180 state(conn, SSH_STOP);
2184 if(data->set.upload) {
2185 if(data->set.infilesize < 0) {
2186 failf(data, "SCP requires a known file size for upload");
2187 sshc->actualcode = CURLE_UPLOAD_FAILED;
2188 state(conn, SSH_SCP_CHANNEL_FREE);
2191 state(conn, SSH_SCP_UPLOAD_INIT);
2194 state(conn, SSH_SCP_DOWNLOAD_INIT);
2198 case SSH_SCP_UPLOAD_INIT:
2200 * libssh2 requires that the destination path is a full path that
2201 * includes the destination file and name OR ends in a "/" . If this is
2202 * not done the destination file will be named the same name as the last
2203 * directory in the path.
2206 SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2207 data->set.infilesize);
2208 if(!sshc->ssh_channel) {
2209 if(libssh2_session_last_errno(sshc->ssh_session) ==
2210 LIBSSH2_ERROR_EAGAIN) {
2211 rc = LIBSSH2_ERROR_EAGAIN;
2218 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2219 &err_msg, NULL, 0));
2220 failf(conn->data, "%s", err_msg);
2221 state(conn, SSH_SCP_CHANNEL_FREE);
2222 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2228 Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2231 /* not set by Curl_setup_transfer to preserve keepon bits */
2232 conn->sockfd = conn->writesockfd;
2235 state(conn, SSH_SCP_CHANNEL_FREE);
2236 sshc->actualcode = result;
2239 /* we want to use the _sending_ function even when the socket turns
2240 out readable as the underlying libssh2 scp send function will deal
2241 with both accordingly */
2242 conn->cselect_bits = CURL_CSELECT_OUT;
2244 state(conn, SSH_STOP);
2248 case SSH_SCP_DOWNLOAD_INIT:
2251 * We must check the remote file; if it is a directory no values will
2255 curl_off_t bytecount;
2257 /* clear the struct scp recv will fill in */
2258 memset(&sb, 0, sizeof(struct stat));
2260 /* get a fresh new channel from the ssh layer */
2261 sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2262 sftp_scp->path, &sb);
2263 if(!sshc->ssh_channel) {
2264 if(libssh2_session_last_errno(sshc->ssh_session) ==
2265 LIBSSH2_ERROR_EAGAIN) {
2266 rc = LIBSSH2_ERROR_EAGAIN;
2273 ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2274 &err_msg, NULL, 0));
2275 failf(conn->data, "%s", err_msg);
2276 state(conn, SSH_SCP_CHANNEL_FREE);
2277 sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2283 bytecount = (curl_off_t)sb.st_size;
2284 data->req.maxdownload = (curl_off_t)sb.st_size;
2285 Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2287 /* not set by Curl_setup_transfer to preserve keepon bits */
2288 conn->writesockfd = conn->sockfd;
2290 /* we want to use the _receiving_ function even when the socket turns
2291 out writableable as the underlying libssh2 recv function will deal
2292 with both accordingly */
2293 conn->cselect_bits = CURL_CSELECT_IN;
2296 state(conn, SSH_SCP_CHANNEL_FREE);
2297 sshc->actualcode = result;
2300 state(conn, SSH_STOP);
2305 if(data->set.upload)
2306 state(conn, SSH_SCP_SEND_EOF);
2308 state(conn, SSH_SCP_CHANNEL_FREE);
2311 case SSH_SCP_SEND_EOF:
2312 if(sshc->ssh_channel) {
2313 rc = libssh2_channel_send_eof(sshc->ssh_channel);
2314 if(rc == LIBSSH2_ERROR_EAGAIN) {
2318 infof(data, "Failed to send libssh2 channel EOF\n");
2321 state(conn, SSH_SCP_WAIT_EOF);
2324 case SSH_SCP_WAIT_EOF:
2325 if(sshc->ssh_channel) {
2326 rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2327 if(rc == LIBSSH2_ERROR_EAGAIN) {
2331 infof(data, "Failed to get channel EOF: %d\n", rc);
2334 state(conn, SSH_SCP_WAIT_CLOSE);
2337 case SSH_SCP_WAIT_CLOSE:
2338 if(sshc->ssh_channel) {
2339 rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2340 if(rc == LIBSSH2_ERROR_EAGAIN) {
2344 infof(data, "Channel failed to close: %d\n", rc);
2347 state(conn, SSH_SCP_CHANNEL_FREE);
2350 case SSH_SCP_CHANNEL_FREE:
2351 if(sshc->ssh_channel) {
2352 rc = libssh2_channel_free(sshc->ssh_channel);
2353 if(rc == LIBSSH2_ERROR_EAGAIN) {
2357 infof(data, "Failed to free libssh2 scp subsystem\n");
2359 sshc->ssh_channel = NULL;
2361 DEBUGF(infof(data, "SCP DONE phase complete\n"));
2363 state(conn, SSH_SESSION_DISCONNECT);
2365 state(conn, SSH_STOP);
2366 result = sshc->actualcode;
2369 case SSH_SESSION_DISCONNECT:
2370 /* during weird times when we've been prematurely aborted, the channel
2371 is still alive when we reach this state and we MUST kill the channel
2373 if(sshc->ssh_channel) {
2374 rc = libssh2_channel_free(sshc->ssh_channel);
2375 if(rc == LIBSSH2_ERROR_EAGAIN) {
2379 infof(data, "Failed to free libssh2 scp subsystem\n");
2381 sshc->ssh_channel = NULL;
2384 if(sshc->ssh_session) {
2385 rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2386 if(rc == LIBSSH2_ERROR_EAGAIN) {
2390 infof(data, "Failed to disconnect libssh2 session\n");
2394 Curl_safefree(sshc->homedir);
2395 sshc->homedir = NULL;
2396 conn->data->state.most_recent_ftp_entrypath = NULL;
2398 state(conn, SSH_SESSION_FREE);
2401 case SSH_SESSION_FREE:
2402 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2404 libssh2_knownhost_free(sshc->kh);
2409 if(sshc->ssh_session) {
2410 rc = libssh2_session_free(sshc->ssh_session);
2411 if(rc == LIBSSH2_ERROR_EAGAIN) {
2415 infof(data, "Failed to free libssh2 session\n");
2417 sshc->ssh_session = NULL;
2420 /* worst-case scenario cleanup */
2422 DEBUGASSERT(sshc->ssh_session == NULL);
2423 DEBUGASSERT(sshc->ssh_channel == NULL);
2424 DEBUGASSERT(sshc->sftp_session == NULL);
2425 DEBUGASSERT(sshc->sftp_handle == NULL);
2426 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2427 DEBUGASSERT(sshc->kh == NULL);
2430 Curl_safefree(sshc->rsa_pub);
2431 Curl_safefree(sshc->rsa);
2433 Curl_safefree(sshc->quote_path1);
2434 Curl_safefree(sshc->quote_path2);
2436 Curl_safefree(sshc->homedir);
2438 Curl_safefree(sshc->readdir_filename);
2439 Curl_safefree(sshc->readdir_longentry);
2440 Curl_safefree(sshc->readdir_line);
2441 Curl_safefree(sshc->readdir_linkPath);
2443 /* the code we are about to return */
2444 result = sshc->actualcode;
2446 memset(sshc, 0, sizeof(struct ssh_conn));
2448 conn->bits.close = TRUE;
2449 sshc->state = SSH_SESSION_FREE; /* current */
2450 sshc->nextstate = SSH_NO_STATE;
2451 state(conn, SSH_STOP);
2455 /* fallthrough, just stop! */
2457 /* internal error */
2458 sshc->nextstate = SSH_NO_STATE;
2459 state(conn, SSH_STOP);
2463 } while(!rc && (sshc->state != SSH_STOP));
2465 if(rc == LIBSSH2_ERROR_EAGAIN) {
2466 /* we would block, we need to wait for the socket to be ready (in the
2467 right direction too)! */
2474 /* called by the multi interface to figure out what socket(s) to wait for and
2475 for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
2476 static int ssh_perform_getsock(const struct connectdata *conn,
2477 curl_socket_t *sock, /* points to numsocks
2478 number of sockets */
2481 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2482 int bitmap = GETSOCK_BLANK;
2485 sock[0] = conn->sock[FIRSTSOCKET];
2487 if(conn->waitfor & KEEP_RECV)
2488 bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2490 if(conn->waitfor & KEEP_SEND)
2491 bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2495 /* if we don't know the direction we can use the generic *_getsock()
2496 function even for the protocol_connect and doing states */
2497 return Curl_single_getsock(conn, sock, numsocks);
2501 /* Generic function called by the multi interface to figure out what socket(s)
2502 to wait for and for what actions during the DOING and PROTOCONNECT states*/
2503 static int ssh_getsock(struct connectdata *conn,
2504 curl_socket_t *sock, /* points to numsocks number
2508 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2512 /* if we don't know any direction we can just play along as we used to and
2513 not provide any sensible info */
2514 return GETSOCK_BLANK;
2516 /* if we know the direction we can use the generic *_getsock() function even
2517 for the protocol_connect and doing states */
2518 return ssh_perform_getsock(conn, sock, numsocks);
2522 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2524 * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2525 * function is used to figure out in what direction and stores this info so
2526 * that the multi interface can take advantage of it. Make sure to call this
2527 * function in all cases so that when it _doesn't_ return EAGAIN we can
2528 * restore the default wait bits.
2530 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2532 struct ssh_conn *sshc = &conn->proto.sshc;
2536 else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
2537 /* translate the libssh2 define bits into our own bit defines */
2538 conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2539 ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2542 /* It didn't block or libssh2 didn't reveal in which direction, put back
2544 conn->waitfor = sshc->orig_waitfor;
2547 /* no libssh2 directional support so we simply don't know */
2548 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2551 /* called repeatedly until done from multi.c */
2552 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2554 struct ssh_conn *sshc = &conn->proto.sshc;
2555 CURLcode result = CURLE_OK;
2556 bool block; /* we store the status and use that to provide a ssh_getsock()
2559 result = ssh_statemach_act(conn, &block);
2560 *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2561 ssh_block2waitfor(conn, block);
2566 static CURLcode ssh_easy_statemach(struct connectdata *conn,
2569 struct ssh_conn *sshc = &conn->proto.sshc;
2570 CURLcode result = CURLE_OK;
2571 struct SessionHandle *data = conn->data;
2573 while((sshc->state != SSH_STOP) && !result) {
2577 result = ssh_statemach_act(conn, &block);
2581 if(Curl_pgrsUpdate(conn))
2582 return CURLE_ABORTED_BY_CALLBACK;
2584 struct timeval now = Curl_tvnow();
2585 result = Curl_speedcheck(data, now);
2590 left = Curl_timeleft(data, NULL, duringconnect);
2592 failf(data, "Operation timed out\n");
2593 return CURLE_OPERATION_TIMEDOUT;
2596 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2597 if((CURLE_OK == result) && block) {
2598 int dir = libssh2_session_block_directions(sshc->ssh_session);
2599 curl_socket_t sock = conn->sock[FIRSTSOCKET];
2600 curl_socket_t fd_read = CURL_SOCKET_BAD;
2601 curl_socket_t fd_write = CURL_SOCKET_BAD;
2602 if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2604 if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2606 /* wait for the socket to become ready */
2607 Curl_socket_ready(fd_read, fd_write,
2608 left>1000?1000:left); /* ignore result */
2618 * SSH setup and connection
2620 static CURLcode ssh_init(struct connectdata *conn)
2622 struct SessionHandle *data = conn->data;
2623 struct SSHPROTO *ssh;
2624 struct ssh_conn *sshc = &conn->proto.sshc;
2626 sshc->actualcode = CURLE_OK; /* reset error code */
2627 sshc->secondCreateDirs =0; /* reset the create dir attempt state
2630 if(data->state.proto.ssh)
2633 ssh = calloc(1, sizeof(struct SSHPROTO));
2635 return CURLE_OUT_OF_MEMORY;
2637 data->state.proto.ssh = ssh;
2642 static Curl_recv scp_recv, sftp_recv;
2643 static Curl_send scp_send, sftp_send;
2646 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2647 * do protocol-specific actions at connect-time.
2649 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2651 #ifdef CURL_LIBSSH2_DEBUG
2654 struct ssh_conn *ssh;
2656 struct SessionHandle *data = conn->data;
2658 /* We default to persistent connections. We set this already in this connect
2659 function to make the re-use checks properly be able to check this bit. */
2660 conn->bits.close = FALSE;
2662 /* If there already is a protocol-specific struct allocated for this
2663 sessionhandle, deal with it */
2664 Curl_reset_reqproto(conn);
2666 result = ssh_init(conn);
2670 if(conn->handler->protocol & CURLPROTO_SCP) {
2671 conn->recv[FIRSTSOCKET] = scp_recv;
2672 conn->send[FIRSTSOCKET] = scp_send;
2675 conn->recv[FIRSTSOCKET] = sftp_recv;
2676 conn->send[FIRSTSOCKET] = sftp_send;
2678 ssh = &conn->proto.sshc;
2680 #ifdef CURL_LIBSSH2_DEBUG
2682 infof(data, "User: %s\n", conn->user);
2685 infof(data, "Password: %s\n", conn->passwd);
2687 sock = conn->sock[FIRSTSOCKET];
2688 #endif /* CURL_LIBSSH2_DEBUG */
2690 ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2692 my_libssh2_realloc, conn);
2693 if(ssh->ssh_session == NULL) {
2694 failf(data, "Failure initialising ssh session");
2695 return CURLE_FAILED_INIT;
2698 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2699 if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2701 ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2703 /* eeek. TODO: free the ssh_session! */
2704 return CURLE_FAILED_INIT;
2707 /* read all known hosts from there */
2708 rc = libssh2_knownhost_readfile(ssh->kh,
2709 data->set.str[STRING_SSH_KNOWNHOSTS],
2710 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2712 infof(data, "Failed to read known hosts from %s\n",
2713 data->set.str[STRING_SSH_KNOWNHOSTS]);
2715 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2717 #ifdef CURL_LIBSSH2_DEBUG
2718 libssh2_trace(ssh->ssh_session, ~0);
2719 infof(data, "SSH socket: %d\n", (int)sock);
2720 #endif /* CURL_LIBSSH2_DEBUG */
2722 state(conn, SSH_INIT);
2724 if(data->state.used_interface == Curl_if_multi)
2725 result = ssh_multi_statemach(conn, done);
2727 result = ssh_easy_statemach(conn, TRUE);
2736 ***********************************************************************
2740 * This is the actual DO function for SCP. Get a file according to
2741 * the options previously setup.
2745 CURLcode scp_perform(struct connectdata *conn,
2749 CURLcode result = CURLE_OK;
2751 DEBUGF(infof(conn->data, "DO phase starts\n"));
2753 *dophase_done = FALSE; /* not done yet */
2755 /* start the first command in the DO phase */
2756 state(conn, SSH_SCP_TRANS_INIT);
2758 /* run the state-machine */
2759 if(conn->data->state.used_interface == Curl_if_multi) {
2760 result = ssh_multi_statemach(conn, dophase_done);
2763 result = ssh_easy_statemach(conn, FALSE);
2764 *dophase_done = TRUE; /* with the easy interface we are done here */
2766 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2769 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2775 /* called from multi.c while DOing */
2776 static CURLcode scp_doing(struct connectdata *conn,
2780 result = ssh_multi_statemach(conn, dophase_done);
2783 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2789 * The DO function is generic for both protocols. There was previously two
2790 * separate ones but this way means less duplicated code.
2793 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2797 struct SessionHandle *data = conn->data;
2799 *done = FALSE; /* default to false */
2802 Since connections can be re-used between SessionHandles, this might be a
2803 connection already existing but on a fresh SessionHandle struct so we must
2804 make sure we have a good 'struct SSHPROTO' to play with. For new
2805 connections, the struct SSHPROTO is allocated and setup in the
2806 ssh_connect() function.
2808 Curl_reset_reqproto(conn);
2809 res = ssh_init(conn);
2813 data->req.size = -1; /* make sure this is unknown at this point */
2815 Curl_pgrsSetUploadCounter(data, 0);
2816 Curl_pgrsSetDownloadCounter(data, 0);
2817 Curl_pgrsSetUploadSize(data, 0);
2818 Curl_pgrsSetDownloadSize(data, 0);
2820 if(conn->handler->protocol & CURLPROTO_SCP)
2821 res = scp_perform(conn, &connected, done);
2823 res = sftp_perform(conn, &connected, done);
2828 /* BLOCKING, but the function is using the state machine so the only reason
2829 this is still blocking is that the multi interface code has no support for
2830 disconnecting operations that takes a while */
2831 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2833 CURLcode result = CURLE_OK;
2834 struct ssh_conn *ssh = &conn->proto.sshc;
2835 (void) dead_connection;
2837 Curl_safefree(conn->data->state.proto.ssh);
2838 conn->data->state.proto.ssh = NULL;
2840 if(ssh->ssh_session) {
2841 /* only if there's a session still around to use! */
2843 state(conn, SSH_SESSION_DISCONNECT);
2845 result = ssh_easy_statemach(conn, FALSE);
2851 /* generic done function for both SCP and SFTP called from their specific
2853 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2855 CURLcode result = CURLE_OK;
2856 struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
2858 if(status == CURLE_OK) {
2859 /* run the state-machine
2861 TODO: when the multi interface is used, this _really_ should be using
2862 the ssh_multi_statemach function but we have no general support for
2863 non-blocking DONE operations, not in the multi state machine and with
2864 Curl_done() invokes on several places in the code!
2866 result = ssh_easy_statemach(conn, FALSE);
2872 Curl_safefree(sftp_scp->path);
2873 sftp_scp->path = NULL;
2875 Curl_pgrsDone(conn);
2877 conn->data->req.keepon = 0; /* clear all bits */
2882 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2885 (void)premature; /* not used */
2887 if(status == CURLE_OK)
2888 state(conn, SSH_SCP_DONE);
2890 return ssh_done(conn, status);
2894 /* return number of received (decrypted) bytes */
2895 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2896 const void *mem, size_t len, CURLcode *err)
2899 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2901 /* libssh2_channel_write() returns int! */
2903 libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
2905 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2907 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
2916 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
2917 * a regular CURLcode value.
2919 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
2920 char *mem, size_t len, CURLcode *err)
2923 (void)sockindex; /* we only support SCP on the fixed known primary socket */
2925 /* libssh2_channel_read() returns int */
2927 libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
2929 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
2930 if(nread == LIBSSH2_ERROR_EAGAIN) {
2939 * =============== SFTP ===============
2943 ***********************************************************************
2947 * This is the actual DO function for SFTP. Get a file/directory according to
2948 * the options previously setup.
2952 CURLcode sftp_perform(struct connectdata *conn,
2956 CURLcode result = CURLE_OK;
2958 DEBUGF(infof(conn->data, "DO phase starts\n"));
2960 *dophase_done = FALSE; /* not done yet */
2962 /* start the first command in the DO phase */
2963 state(conn, SSH_SFTP_QUOTE_INIT);
2965 /* run the state-machine */
2966 if(conn->data->state.used_interface == Curl_if_multi) {
2967 result = ssh_multi_statemach(conn, dophase_done);
2970 result = ssh_easy_statemach(conn, FALSE);
2971 *dophase_done = TRUE; /* with the easy interface we are done here */
2973 *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2976 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2982 /* called from multi.c while DOing */
2983 static CURLcode sftp_doing(struct connectdata *conn,
2987 result = ssh_multi_statemach(conn, dophase_done);
2990 DEBUGF(infof(conn->data, "DO phase is complete\n"));
2995 /* BLOCKING, but the function is using the state machine so the only reason
2996 this is still blocking is that the multi interface code has no support for
2997 disconnecting operations that takes a while */
2998 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
3000 CURLcode result = CURLE_OK;
3001 (void) dead_connection;
3003 DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3005 Curl_safefree(conn->data->state.proto.ssh);
3006 conn->data->state.proto.ssh = NULL;
3008 if(conn->proto.sshc.ssh_session) {
3009 /* only if there's a session still around to use! */
3010 state(conn, SSH_SFTP_SHUTDOWN);
3011 result = ssh_easy_statemach(conn, FALSE);
3014 DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3020 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3023 struct ssh_conn *sshc = &conn->proto.sshc;
3025 if(status == CURLE_OK) {
3026 /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3027 errors that could happen due to open file handles during POSTQUOTE
3029 if(!status && !premature && conn->data->set.postquote) {
3030 sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3031 state(conn, SSH_SFTP_CLOSE);
3034 state(conn, SSH_SFTP_CLOSE);
3036 return ssh_done(conn, status);
3039 /* return number of sent bytes */
3040 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3041 const void *mem, size_t len, CURLcode *err)
3043 ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
3044 but is changed to ssize_t in 0.15. These days we don't
3045 support libssh2 0.15*/
3048 nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3050 ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3052 if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3061 * Return number of received (decrypted) bytes
3063 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3064 char *mem, size_t len, CURLcode *err)
3069 nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3071 ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3073 if(nread == LIBSSH2_ERROR_EAGAIN) {
3080 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3083 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3085 * Permission to use, copy, modify, and distribute this software for any
3086 * purpose with or without fee is hereby granted, provided that the above
3087 * copyright notice and this permission notice appear in all copies.
3089 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3090 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3091 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3092 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3093 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3094 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3095 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3098 get_pathname(const char **cpp, char **path)
3100 const char *cp = *cpp, *end;
3103 static const char WHITESPACE[] = " \t\r\n";
3105 cp += strspn(cp, WHITESPACE);
3109 return CURLE_QUOTE_ERROR;
3112 *path = malloc(strlen(cp) + 1);
3114 return CURLE_OUT_OF_MEMORY;
3116 /* Check for quoted filenames */
3117 if(*cp == '\"' || *cp == '\'') {
3120 /* Search for terminating quote, unescape some chars */
3121 for(i = j = 0; i <= strlen(cp); i++) {
3122 if(cp[i] == quot) { /* Found quote */
3127 if(cp[i] == '\0') { /* End of string */
3128 /*error("Unterminated quote");*/
3131 if(cp[i] == '\\') { /* Escaped characters */
3133 if(cp[i] != '\'' && cp[i] != '\"' &&
3135 /*error("Bad escaped character '\\%c'",
3140 (*path)[j++] = cp[i];
3144 /*error("Empty quotes");*/
3147 *cpp = cp + i + strspn(cp + i, WHITESPACE);
3150 /* Read to end of filename */
3151 end = strpbrk(cp, WHITESPACE);
3153 end = strchr(cp, '\0');
3154 *cpp = end + strspn(end, WHITESPACE);
3156 memcpy(*path, cp, end - cp);
3157 (*path)[end - cp] = '\0';
3162 Curl_safefree(*path);
3164 return CURLE_QUOTE_ERROR;
3168 static const char *sftp_libssh2_strerror(unsigned long err)
3171 case LIBSSH2_FX_NO_SUCH_FILE:
3172 return "No such file or directory";
3174 case LIBSSH2_FX_PERMISSION_DENIED:
3175 return "Permission denied";
3177 case LIBSSH2_FX_FAILURE:
3178 return "Operation failed";
3180 case LIBSSH2_FX_BAD_MESSAGE:
3181 return "Bad message from SFTP server";
3183 case LIBSSH2_FX_NO_CONNECTION:
3184 return "Not connected to SFTP server";
3186 case LIBSSH2_FX_CONNECTION_LOST:
3187 return "Connection to SFTP server lost";
3189 case LIBSSH2_FX_OP_UNSUPPORTED:
3190 return "Operation not supported by SFTP server";
3192 case LIBSSH2_FX_INVALID_HANDLE:
3193 return "Invalid handle";
3195 case LIBSSH2_FX_NO_SUCH_PATH:
3196 return "No such file or directory";
3198 case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3199 return "File already exists";
3201 case LIBSSH2_FX_WRITE_PROTECT:
3202 return "File is write protected";
3204 case LIBSSH2_FX_NO_MEDIA:
3207 case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3210 case LIBSSH2_FX_QUOTA_EXCEEDED:
3211 return "User quota exceeded";
3213 case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3214 return "Unknown principle";
3216 case LIBSSH2_FX_LOCK_CONFlICT:
3217 return "File lock conflict";
3219 case LIBSSH2_FX_DIR_NOT_EMPTY:
3220 return "Directory not empty";
3222 case LIBSSH2_FX_NOT_A_DIRECTORY:
3223 return "Not a directory";
3225 case LIBSSH2_FX_INVALID_FILENAME:
3226 return "Invalid filename";
3228 case LIBSSH2_FX_LINK_LOOP:
3229 return "Link points to itself";
3231 return "Unknown error in libssh2";
3234 #endif /* USE_LIBSSH2 */