1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
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.
13  *
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.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 
23 /* #define CURL_LIBSSH2_DEBUG */
24 
25 #include "curl_setup.h"
26 
27 #ifdef USE_LIBSSH2
28 
29 #ifdef HAVE_LIMITS_H
30 #  include <limits.h>
31 #endif
32 
33 #include <libssh2.h>
34 #include <libssh2_sftp.h>
35 
36 #ifdef HAVE_FCNTL_H
37 #include <fcntl.h>
38 #endif
39 
40 #ifdef HAVE_NETINET_IN_H
41 #include <netinet/in.h>
42 #endif
43 #ifdef HAVE_ARPA_INET_H
44 #include <arpa/inet.h>
45 #endif
46 #ifdef HAVE_UTSNAME_H
47 #include <sys/utsname.h>
48 #endif
49 #ifdef HAVE_NETDB_H
50 #include <netdb.h>
51 #endif
52 #ifdef __VMS
53 #include <in.h>
54 #include <inet.h>
55 #endif
56 
57 #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
58 #undef in_addr_t
59 #define in_addr_t unsigned long
60 #endif
61 
62 #include <curl/curl.h>
63 #include "urldata.h"
64 #include "sendf.h"
65 #include "hostip.h"
66 #include "progress.h"
67 #include "transfer.h"
68 #include "escape.h"
69 #include "http.h" /* for HTTP proxy tunnel stuff */
70 #include "ssh.h"
71 #include "url.h"
72 #include "speedcheck.h"
73 #include "getinfo.h"
74 
75 #include "strequal.h"
76 #include "vtls/vtls.h"
77 #include "connect.h"
78 #include "strerror.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"
83 #include "multiif.h"
84 #include "select.h"
85 #include "warnless.h"
86 #include "curl_printf.h"
87 #include "curl_memory.h"
88 /* The last #include file should be: */
89 #include "memdebug.h"
90 
91 #ifdef WIN32
92 #  undef  PATH_MAX
93 #  define PATH_MAX MAX_PATH
94 #  ifndef R_OK
95 #    define R_OK 4
96 #  endif
97 #endif
98 
99 #ifndef PATH_MAX
100 #define PATH_MAX 1024 /* just an extra precaution since there are systems that
101                          have their definition hidden well */
102 #endif
103 
104 #define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
105 
106 #define sftp_libssh2_realpath(s,p,t,m) \
107         libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
108                                 (t), (m), LIBSSH2_SFTP_REALPATH)
109 
110 /* Local functions: */
111 static const char *sftp_libssh2_strerror(int err);
112 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
113 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
114 static LIBSSH2_FREE_FUNC(my_libssh2_free);
115 
116 static CURLcode get_pathname(const char **cpp, char **path);
117 
118 static CURLcode ssh_connect(struct connectdata *conn, bool *done);
119 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
120 static CURLcode ssh_do(struct connectdata *conn, bool *done);
121 
122 static CURLcode ssh_getworkingpath(struct connectdata *conn,
123                                    char *homedir, /* when SFTP is used */
124                                    char **path);
125 
126 static CURLcode scp_done(struct connectdata *conn,
127                          CURLcode, bool premature);
128 static CURLcode scp_doing(struct connectdata *conn,
129                           bool *dophase_done);
130 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
131 
132 static CURLcode sftp_done(struct connectdata *conn,
133                           CURLcode, bool premature);
134 static CURLcode sftp_doing(struct connectdata *conn,
135                            bool *dophase_done);
136 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
137 static
138 CURLcode sftp_perform(struct connectdata *conn,
139                       bool *connected,
140                       bool *dophase_done);
141 
142 static int ssh_getsock(struct connectdata *conn,
143                        curl_socket_t *sock, /* points to numsocks number
144                                                of sockets */
145                        int numsocks);
146 
147 static int ssh_perform_getsock(const struct connectdata *conn,
148                                curl_socket_t *sock, /* points to numsocks
149                                                        number of sockets */
150                                int numsocks);
151 
152 static CURLcode ssh_setup_connection(struct connectdata *conn);
153 
154 /*
155  * SCP protocol handler.
156  */
157 
158 const struct Curl_handler Curl_handler_scp = {
159   "SCP",                                /* scheme */
160   ssh_setup_connection,                 /* setup_connection */
161   ssh_do,                               /* do_it */
162   scp_done,                             /* done */
163   ZERO_NULL,                            /* do_more */
164   ssh_connect,                          /* connect_it */
165   ssh_multi_statemach,                  /* connecting */
166   scp_doing,                            /* doing */
167   ssh_getsock,                          /* proto_getsock */
168   ssh_getsock,                          /* doing_getsock */
169   ZERO_NULL,                            /* domore_getsock */
170   ssh_perform_getsock,                  /* perform_getsock */
171   scp_disconnect,                       /* disconnect */
172   ZERO_NULL,                            /* readwrite */
173   PORT_SSH,                             /* defport */
174   CURLPROTO_SCP,                        /* protocol */
175   PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
176   | PROTOPT_NOURLQUERY                  /* flags */
177 };
178 
179 
180 /*
181  * SFTP protocol handler.
182  */
183 
184 const struct Curl_handler Curl_handler_sftp = {
185   "SFTP",                               /* scheme */
186   ssh_setup_connection,                 /* setup_connection */
187   ssh_do,                               /* do_it */
188   sftp_done,                            /* done */
189   ZERO_NULL,                            /* do_more */
190   ssh_connect,                          /* connect_it */
191   ssh_multi_statemach,                  /* connecting */
192   sftp_doing,                           /* doing */
193   ssh_getsock,                          /* proto_getsock */
194   ssh_getsock,                          /* doing_getsock */
195   ZERO_NULL,                            /* domore_getsock */
196   ssh_perform_getsock,                  /* perform_getsock */
197   sftp_disconnect,                      /* disconnect */
198   ZERO_NULL,                            /* readwrite */
199   PORT_SSH,                             /* defport */
200   CURLPROTO_SFTP,                       /* protocol */
201   PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
202   | PROTOPT_NOURLQUERY                  /* flags */
203 };
204 
205 static void
kbd_callback(const char * name,int name_len,const char * instruction,int instruction_len,int num_prompts,const LIBSSH2_USERAUTH_KBDINT_PROMPT * prompts,LIBSSH2_USERAUTH_KBDINT_RESPONSE * responses,void ** abstract)206 kbd_callback(const char *name, int name_len, const char *instruction,
207              int instruction_len, int num_prompts,
208              const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
209              LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
210              void **abstract)
211 {
212   struct connectdata *conn = (struct connectdata *)*abstract;
213 
214 #ifdef CURL_LIBSSH2_DEBUG
215   fprintf(stderr, "name=%s\n", name);
216   fprintf(stderr, "name_len=%d\n", name_len);
217   fprintf(stderr, "instruction=%s\n", instruction);
218   fprintf(stderr, "instruction_len=%d\n", instruction_len);
219   fprintf(stderr, "num_prompts=%d\n", num_prompts);
220 #else
221   (void)name;
222   (void)name_len;
223   (void)instruction;
224   (void)instruction_len;
225 #endif  /* CURL_LIBSSH2_DEBUG */
226   if(num_prompts == 1) {
227     responses[0].text = strdup(conn->passwd);
228     responses[0].length = curlx_uztoui(strlen(conn->passwd));
229   }
230   (void)prompts;
231   (void)abstract;
232 } /* kbd_callback */
233 
sftp_libssh2_error_to_CURLE(int err)234 static CURLcode sftp_libssh2_error_to_CURLE(int err)
235 {
236   switch (err) {
237     case LIBSSH2_FX_OK:
238       return CURLE_OK;
239 
240     case LIBSSH2_FX_NO_SUCH_FILE:
241     case LIBSSH2_FX_NO_SUCH_PATH:
242       return CURLE_REMOTE_FILE_NOT_FOUND;
243 
244     case LIBSSH2_FX_PERMISSION_DENIED:
245     case LIBSSH2_FX_WRITE_PROTECT:
246     case LIBSSH2_FX_LOCK_CONFlICT:
247       return CURLE_REMOTE_ACCESS_DENIED;
248 
249     case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
250     case LIBSSH2_FX_QUOTA_EXCEEDED:
251       return CURLE_REMOTE_DISK_FULL;
252 
253     case LIBSSH2_FX_FILE_ALREADY_EXISTS:
254       return CURLE_REMOTE_FILE_EXISTS;
255 
256     case LIBSSH2_FX_DIR_NOT_EMPTY:
257       return CURLE_QUOTE_ERROR;
258 
259     default:
260       break;
261   }
262 
263   return CURLE_SSH;
264 }
265 
libssh2_session_error_to_CURLE(int err)266 static CURLcode libssh2_session_error_to_CURLE(int err)
267 {
268   switch (err) {
269     /* Ordered by order of appearance in libssh2.h */
270     case LIBSSH2_ERROR_NONE:
271       return CURLE_OK;
272 
273     case LIBSSH2_ERROR_SOCKET_NONE:
274       return CURLE_COULDNT_CONNECT;
275 
276     case LIBSSH2_ERROR_ALLOC:
277       return CURLE_OUT_OF_MEMORY;
278 
279     case LIBSSH2_ERROR_SOCKET_SEND:
280       return CURLE_SEND_ERROR;
281 
282     case LIBSSH2_ERROR_HOSTKEY_INIT:
283     case LIBSSH2_ERROR_HOSTKEY_SIGN:
284     case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
285     case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
286       return CURLE_PEER_FAILED_VERIFICATION;
287 
288     case LIBSSH2_ERROR_PASSWORD_EXPIRED:
289       return CURLE_LOGIN_DENIED;
290 
291     case LIBSSH2_ERROR_SOCKET_TIMEOUT:
292     case LIBSSH2_ERROR_TIMEOUT:
293       return CURLE_OPERATION_TIMEDOUT;
294 
295     case LIBSSH2_ERROR_EAGAIN:
296       return CURLE_AGAIN;
297   }
298 
299   /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
300      error code, and possibly add a few new SSH-related one. We must however
301      not return or even depend on libssh2 errors in the public libcurl API */
302 
303   return CURLE_SSH;
304 }
305 
LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)306 static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
307 {
308   (void)abstract; /* arg not used */
309   return malloc(count);
310 }
311 
LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)312 static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
313 {
314   (void)abstract; /* arg not used */
315   return realloc(ptr, count);
316 }
317 
LIBSSH2_FREE_FUNC(my_libssh2_free)318 static LIBSSH2_FREE_FUNC(my_libssh2_free)
319 {
320   (void)abstract; /* arg not used */
321   if(ptr) /* ssh2 agent sometimes call free with null ptr */
322     free(ptr);
323 }
324 
325 /*
326  * SSH State machine related code
327  */
328 /* This is the ONLY way to change SSH state! */
state(struct connectdata * conn,sshstate nowstate)329 static void state(struct connectdata *conn, sshstate nowstate)
330 {
331   struct ssh_conn *sshc = &conn->proto.sshc;
332 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
333   /* for debug purposes */
334   static const char * const names[] = {
335     "SSH_STOP",
336     "SSH_INIT",
337     "SSH_S_STARTUP",
338     "SSH_HOSTKEY",
339     "SSH_AUTHLIST",
340     "SSH_AUTH_PKEY_INIT",
341     "SSH_AUTH_PKEY",
342     "SSH_AUTH_PASS_INIT",
343     "SSH_AUTH_PASS",
344     "SSH_AUTH_AGENT_INIT",
345     "SSH_AUTH_AGENT_LIST",
346     "SSH_AUTH_AGENT",
347     "SSH_AUTH_HOST_INIT",
348     "SSH_AUTH_HOST",
349     "SSH_AUTH_KEY_INIT",
350     "SSH_AUTH_KEY",
351     "SSH_AUTH_DONE",
352     "SSH_SFTP_INIT",
353     "SSH_SFTP_REALPATH",
354     "SSH_SFTP_QUOTE_INIT",
355     "SSH_SFTP_POSTQUOTE_INIT",
356     "SSH_SFTP_QUOTE",
357     "SSH_SFTP_NEXT_QUOTE",
358     "SSH_SFTP_QUOTE_STAT",
359     "SSH_SFTP_QUOTE_SETSTAT",
360     "SSH_SFTP_QUOTE_SYMLINK",
361     "SSH_SFTP_QUOTE_MKDIR",
362     "SSH_SFTP_QUOTE_RENAME",
363     "SSH_SFTP_QUOTE_RMDIR",
364     "SSH_SFTP_QUOTE_UNLINK",
365     "SSH_SFTP_TRANS_INIT",
366     "SSH_SFTP_UPLOAD_INIT",
367     "SSH_SFTP_CREATE_DIRS_INIT",
368     "SSH_SFTP_CREATE_DIRS",
369     "SSH_SFTP_CREATE_DIRS_MKDIR",
370     "SSH_SFTP_READDIR_INIT",
371     "SSH_SFTP_READDIR",
372     "SSH_SFTP_READDIR_LINK",
373     "SSH_SFTP_READDIR_BOTTOM",
374     "SSH_SFTP_READDIR_DONE",
375     "SSH_SFTP_DOWNLOAD_INIT",
376     "SSH_SFTP_DOWNLOAD_STAT",
377     "SSH_SFTP_CLOSE",
378     "SSH_SFTP_SHUTDOWN",
379     "SSH_SCP_TRANS_INIT",
380     "SSH_SCP_UPLOAD_INIT",
381     "SSH_SCP_DOWNLOAD_INIT",
382     "SSH_SCP_DONE",
383     "SSH_SCP_SEND_EOF",
384     "SSH_SCP_WAIT_EOF",
385     "SSH_SCP_WAIT_CLOSE",
386     "SSH_SCP_CHANNEL_FREE",
387     "SSH_SESSION_DISCONNECT",
388     "SSH_SESSION_FREE",
389     "QUIT"
390   };
391 
392   if(sshc->state != nowstate) {
393     infof(conn->data, "SFTP %p state change from %s to %s\n",
394           (void *)sshc, names[sshc->state], names[nowstate]);
395   }
396 #endif
397 
398   sshc->state = nowstate;
399 }
400 
401 /* figure out the path to work with in this particular request */
ssh_getworkingpath(struct connectdata * conn,char * homedir,char ** path)402 static CURLcode ssh_getworkingpath(struct connectdata *conn,
403                                    char *homedir,  /* when SFTP is used */
404                                    char **path) /* returns the  allocated
405                                                    real path to work with */
406 {
407   struct SessionHandle *data = conn->data;
408   char *real_path = NULL;
409   char *working_path;
410   int working_path_len;
411 
412   working_path = curl_easy_unescape(data, data->state.path, 0,
413                                     &working_path_len);
414   if(!working_path)
415     return CURLE_OUT_OF_MEMORY;
416 
417   /* Check for /~/ , indicating relative to the user's home directory */
418   if(conn->handler->protocol & CURLPROTO_SCP) {
419     real_path = malloc(working_path_len+1);
420     if(real_path == NULL) {
421       free(working_path);
422       return CURLE_OUT_OF_MEMORY;
423     }
424     if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
425       /* It is referenced to the home directory, so strip the leading '/~/' */
426       memcpy(real_path, working_path+3, 4 + working_path_len-3);
427     else
428       memcpy(real_path, working_path, 1 + working_path_len);
429   }
430   else if(conn->handler->protocol & CURLPROTO_SFTP) {
431     if((working_path_len > 1) && (working_path[1] == '~')) {
432       size_t homelen = strlen(homedir);
433       real_path = malloc(homelen + working_path_len + 1);
434       if(real_path == NULL) {
435         free(working_path);
436         return CURLE_OUT_OF_MEMORY;
437       }
438       /* It is referenced to the home directory, so strip the
439          leading '/' */
440       memcpy(real_path, homedir, homelen);
441       real_path[homelen] = '/';
442       real_path[homelen+1] = '\0';
443       if(working_path_len > 3) {
444         memcpy(real_path+homelen+1, working_path + 3,
445                1 + working_path_len -3);
446       }
447     }
448     else {
449       real_path = malloc(working_path_len+1);
450       if(real_path == NULL) {
451         free(working_path);
452         return CURLE_OUT_OF_MEMORY;
453       }
454       memcpy(real_path, working_path, 1+working_path_len);
455     }
456   }
457 
458   free(working_path);
459 
460   /* store the pointer for the caller to receive */
461   *path = real_path;
462 
463   return CURLE_OK;
464 }
465 
466 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
sshkeycallback(CURL * easy,const struct curl_khkey * knownkey,const struct curl_khkey * foundkey,enum curl_khmatch match,void * clientp)467 static int sshkeycallback(CURL *easy,
468                           const struct curl_khkey *knownkey, /* known */
469                           const struct curl_khkey *foundkey, /* found */
470                           enum curl_khmatch match,
471                           void *clientp)
472 {
473   (void)easy;
474   (void)knownkey;
475   (void)foundkey;
476   (void)clientp;
477 
478   /* we only allow perfect matches, and we reject everything else */
479   return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
480 }
481 #endif
482 
483 /*
484  * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
485  * with 32bit size_t.
486  */
487 #ifdef HAVE_LIBSSH2_SFTP_SEEK64
488 #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
489 #else
490 #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
491 #endif
492 
493 /*
494  * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
495  * architectures so we check of the necessary function is present.
496  */
497 #ifndef HAVE_LIBSSH2_SCP_SEND64
498 #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
499 #else
500 #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c),            \
501                                              (libssh2_uint64_t)d, 0, 0)
502 #endif
503 
504 /*
505  * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
506  */
507 #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
508 #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
509 #endif
510 
ssh_knownhost(struct connectdata * conn)511 static CURLcode ssh_knownhost(struct connectdata *conn)
512 {
513   CURLcode result = CURLE_OK;
514 
515 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
516   struct SessionHandle *data = conn->data;
517 
518   if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
519     /* we're asked to verify the host against a file */
520     struct ssh_conn *sshc = &conn->proto.sshc;
521     int rc;
522     int keytype;
523     size_t keylen;
524     const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
525                                                     &keylen, &keytype);
526     int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
527     int keybit = 0;
528 
529     if(remotekey) {
530       /*
531        * A subject to figure out is what host name we need to pass in here.
532        * What host name does OpenSSH store in its file if an IDN name is
533        * used?
534        */
535       struct libssh2_knownhost *host;
536       enum curl_khmatch keymatch;
537       curl_sshkeycallback func =
538         data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
539       struct curl_khkey knownkey;
540       struct curl_khkey *knownkeyp = NULL;
541       struct curl_khkey foundkey;
542 
543       keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
544         LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
545 
546 #ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
547       keycheck = libssh2_knownhost_checkp(sshc->kh,
548                                           conn->host.name,
549                                           (conn->remote_port != PORT_SSH)?
550                                           conn->remote_port:-1,
551                                           remotekey, keylen,
552                                           LIBSSH2_KNOWNHOST_TYPE_PLAIN|
553                                           LIBSSH2_KNOWNHOST_KEYENC_RAW|
554                                           keybit,
555                                           &host);
556 #else
557       keycheck = libssh2_knownhost_check(sshc->kh,
558                                          conn->host.name,
559                                          remotekey, keylen,
560                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
561                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
562                                          keybit,
563                                          &host);
564 #endif
565 
566       infof(data, "SSH host check: %d, key: %s\n", keycheck,
567             (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
568             host->key:"<none>");
569 
570       /* setup 'knownkey' */
571       if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
572         knownkey.key = host->key;
573         knownkey.len = 0;
574         knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
575           CURLKHTYPE_RSA : CURLKHTYPE_DSS;
576         knownkeyp = &knownkey;
577       }
578 
579       /* setup 'foundkey' */
580       foundkey.key = remotekey;
581       foundkey.len = keylen;
582       foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
583         CURLKHTYPE_RSA : CURLKHTYPE_DSS;
584 
585       /*
586        * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
587        * curl_khmatch enum are ever modified, we need to introduce a
588        * translation table here!
589        */
590       keymatch = (enum curl_khmatch)keycheck;
591 
592       /* Ask the callback how to behave */
593       rc = func(data, knownkeyp, /* from the knownhosts file */
594                 &foundkey, /* from the remote host */
595                 keymatch, data->set.ssh_keyfunc_userp);
596     }
597     else
598       /* no remotekey means failure! */
599       rc = CURLKHSTAT_REJECT;
600 
601     switch(rc) {
602     default: /* unknown return codes will equal reject */
603       /* FALLTHROUGH */
604     case CURLKHSTAT_REJECT:
605       state(conn, SSH_SESSION_FREE);
606       /* FALLTHROUGH */
607     case CURLKHSTAT_DEFER:
608       /* DEFER means bail out but keep the SSH_HOSTKEY state */
609       result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
610       break;
611     case CURLKHSTAT_FINE:
612     case CURLKHSTAT_FINE_ADD_TO_FILE:
613       /* proceed */
614       if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
615         /* the found host+key didn't match but has been told to be fine
616            anyway so we add it in memory */
617         int addrc = libssh2_knownhost_add(sshc->kh,
618                                           conn->host.name, NULL,
619                                           remotekey, keylen,
620                                           LIBSSH2_KNOWNHOST_TYPE_PLAIN|
621                                           LIBSSH2_KNOWNHOST_KEYENC_RAW|
622                                           keybit, NULL);
623         if(addrc)
624           infof(data, "Warning adding the known host %s failed!\n",
625                 conn->host.name);
626         else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
627           /* now we write the entire in-memory list of known hosts to the
628              known_hosts file */
629           int wrc =
630             libssh2_knownhost_writefile(sshc->kh,
631                                         data->set.str[STRING_SSH_KNOWNHOSTS],
632                                         LIBSSH2_KNOWNHOST_FILE_OPENSSH);
633           if(wrc) {
634             infof(data, "Warning, writing %s failed!\n",
635                   data->set.str[STRING_SSH_KNOWNHOSTS]);
636           }
637         }
638       }
639       break;
640     }
641   }
642 #else /* HAVE_LIBSSH2_KNOWNHOST_API */
643   (void)conn;
644 #endif
645   return result;
646 }
647 
ssh_check_fingerprint(struct connectdata * conn)648 static CURLcode ssh_check_fingerprint(struct connectdata *conn)
649 {
650   struct ssh_conn *sshc = &conn->proto.sshc;
651   struct SessionHandle *data = conn->data;
652   const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
653   char md5buffer[33];
654   int i;
655 
656   const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
657       LIBSSH2_HOSTKEY_HASH_MD5);
658 
659   if(fingerprint) {
660     /* The fingerprint points to static storage (!), don't free() it. */
661     for(i = 0; i < 16; i++)
662       snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
663     infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
664   }
665 
666   /* Before we authenticate we check the hostkey's MD5 fingerprint
667    * against a known fingerprint, if available.
668    */
669   if(pubkey_md5 && strlen(pubkey_md5) == 32) {
670     if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
671       if(fingerprint)
672         failf(data,
673             "Denied establishing ssh session: mismatch md5 fingerprint. "
674             "Remote %s is not equal to %s", md5buffer, pubkey_md5);
675       else
676         failf(data,
677             "Denied establishing ssh session: md5 fingerprint not available");
678       state(conn, SSH_SESSION_FREE);
679       sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
680       return sshc->actualcode;
681     }
682     else {
683       infof(data, "MD5 checksum match!\n");
684       /* as we already matched, we skip the check for known hosts */
685       return CURLE_OK;
686     }
687   }
688   else
689     return ssh_knownhost(conn);
690 }
691 
692 /*
693  * ssh_statemach_act() runs the SSH state machine as far as it can without
694  * blocking and without reaching the end.  The data the pointer 'block' points
695  * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
696  * meaning it wants to be called again when the socket is ready
697  */
698 
ssh_statemach_act(struct connectdata * conn,bool * block)699 static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
700 {
701   CURLcode result = CURLE_OK;
702   struct SessionHandle *data = conn->data;
703   struct SSHPROTO *sftp_scp = data->req.protop;
704   struct ssh_conn *sshc = &conn->proto.sshc;
705   curl_socket_t sock = conn->sock[FIRSTSOCKET];
706   char *new_readdir_line;
707   int rc = LIBSSH2_ERROR_NONE;
708   int err;
709   int seekerr = CURL_SEEKFUNC_OK;
710   *block = 0; /* we're not blocking by default */
711 
712   do {
713 
714     switch(sshc->state) {
715     case SSH_INIT:
716       sshc->secondCreateDirs = 0;
717       sshc->nextstate = SSH_NO_STATE;
718       sshc->actualcode = CURLE_OK;
719 
720       /* Set libssh2 to non-blocking, since everything internally is
721          non-blocking */
722       libssh2_session_set_blocking(sshc->ssh_session, 0);
723 
724       state(conn, SSH_S_STARTUP);
725       /* fall-through */
726 
727     case SSH_S_STARTUP:
728       rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
729       if(rc == LIBSSH2_ERROR_EAGAIN) {
730         break;
731       }
732       else if(rc) {
733         failf(data, "Failure establishing ssh session");
734         state(conn, SSH_SESSION_FREE);
735         sshc->actualcode = CURLE_FAILED_INIT;
736         break;
737       }
738 
739       state(conn, SSH_HOSTKEY);
740 
741       /* fall-through */
742     case SSH_HOSTKEY:
743       /*
744        * Before we authenticate we should check the hostkey's fingerprint
745        * against our known hosts. How that is handled (reading from file,
746        * whatever) is up to us.
747        */
748       result = ssh_check_fingerprint(conn);
749       if(!result)
750         state(conn, SSH_AUTHLIST);
751       /* ssh_check_fingerprint sets state appropriately on error */
752       break;
753 
754     case SSH_AUTHLIST:
755       /*
756        * Figure out authentication methods
757        * NB: As soon as we have provided a username to an openssh server we
758        * must never change it later. Thus, always specify the correct username
759        * here, even though the libssh2 docs kind of indicate that it should be
760        * possible to get a 'generic' list (not user-specific) of authentication
761        * methods, presumably with a blank username. That won't work in my
762        * experience.
763        * So always specify it here.
764        */
765       sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
766                                              conn->user,
767                                              curlx_uztoui(strlen(conn->user)));
768 
769       if(!sshc->authlist) {
770         if(libssh2_userauth_authenticated(sshc->ssh_session)) {
771           sshc->authed = TRUE;
772           infof(data, "SSH user accepted with no authentication\n");
773           state(conn, SSH_AUTH_DONE);
774           break;
775         }
776         else if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
777            LIBSSH2_ERROR_EAGAIN) {
778           rc = LIBSSH2_ERROR_EAGAIN;
779           break;
780         }
781         else {
782           state(conn, SSH_SESSION_FREE);
783           sshc->actualcode = libssh2_session_error_to_CURLE(err);
784           break;
785         }
786       }
787       infof(data, "SSH authentication methods available: %s\n",
788             sshc->authlist);
789 
790       state(conn, SSH_AUTH_PKEY_INIT);
791       break;
792 
793     case SSH_AUTH_PKEY_INIT:
794       /*
795        * Check the supported auth types in the order I feel is most secure
796        * with the requested type of authentication
797        */
798       sshc->authed = FALSE;
799 
800       if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
801          (strstr(sshc->authlist, "publickey") != NULL)) {
802         char *home = NULL;
803         bool out_of_memory = FALSE;
804 
805         sshc->rsa_pub = sshc->rsa = NULL;
806 
807         /* To ponder about: should really the lib be messing about with the
808            HOME environment variable etc? */
809         home = curl_getenv("HOME");
810 
811         if(data->set.str[STRING_SSH_PRIVATE_KEY])
812           sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
813         else {
814           /* If no private key file is specified, try some common paths. */
815           if(home) {
816             /* Try ~/.ssh first. */
817             sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
818             if(!sshc->rsa)
819               out_of_memory = TRUE;
820             else if(access(sshc->rsa, R_OK) != 0) {
821               Curl_safefree(sshc->rsa);
822               sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
823               if(!sshc->rsa)
824                 out_of_memory = TRUE;
825               else if(access(sshc->rsa, R_OK) != 0) {
826                 Curl_safefree(sshc->rsa);
827               }
828             }
829           }
830           if(!out_of_memory && !sshc->rsa) {
831             /* Nothing found; try the current dir. */
832             sshc->rsa = strdup("id_rsa");
833             if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
834               Curl_safefree(sshc->rsa);
835               sshc->rsa = strdup("id_dsa");
836               if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
837                 Curl_safefree(sshc->rsa);
838                 /* Out of guesses. Set to the empty string to avoid
839                  * surprising info messages. */
840                 sshc->rsa = strdup("");
841               }
842             }
843           }
844         }
845 
846         /*
847          * Unless the user explicitly specifies a public key file, let
848          * libssh2 extract the public key from the private key file.
849          * This is done by simply passing sshc->rsa_pub = NULL.
850          */
851         if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
852           sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
853           if(!sshc->rsa_pub)
854             out_of_memory = TRUE;
855         }
856 
857         if(out_of_memory || sshc->rsa == NULL) {
858           free(home);
859           Curl_safefree(sshc->rsa);
860           Curl_safefree(sshc->rsa_pub);
861           state(conn, SSH_SESSION_FREE);
862           sshc->actualcode = CURLE_OUT_OF_MEMORY;
863           break;
864         }
865 
866         sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
867         if(!sshc->passphrase)
868           sshc->passphrase = "";
869 
870         free(home);
871 
872         infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
873         infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
874 
875         state(conn, SSH_AUTH_PKEY);
876       }
877       else {
878         state(conn, SSH_AUTH_PASS_INIT);
879       }
880       break;
881 
882     case SSH_AUTH_PKEY:
883       /* The function below checks if the files exists, no need to stat() here.
884        */
885       rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
886                                                   conn->user,
887                                                   curlx_uztoui(
888                                                     strlen(conn->user)),
889                                                   sshc->rsa_pub,
890                                                   sshc->rsa, sshc->passphrase);
891       if(rc == LIBSSH2_ERROR_EAGAIN) {
892         break;
893       }
894 
895       Curl_safefree(sshc->rsa_pub);
896       Curl_safefree(sshc->rsa);
897 
898       if(rc == 0) {
899         sshc->authed = TRUE;
900         infof(data, "Initialized SSH public key authentication\n");
901         state(conn, SSH_AUTH_DONE);
902       }
903       else {
904         char *err_msg;
905         (void)libssh2_session_last_error(sshc->ssh_session,
906                                          &err_msg, NULL, 0);
907         infof(data, "SSH public key authentication failed: %s\n", err_msg);
908         state(conn, SSH_AUTH_PASS_INIT);
909       }
910       break;
911 
912     case SSH_AUTH_PASS_INIT:
913       if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
914          (strstr(sshc->authlist, "password") != NULL)) {
915         state(conn, SSH_AUTH_PASS);
916       }
917       else {
918         state(conn, SSH_AUTH_HOST_INIT);
919       }
920       break;
921 
922     case SSH_AUTH_PASS:
923       rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
924                                         curlx_uztoui(strlen(conn->user)),
925                                         conn->passwd,
926                                         curlx_uztoui(strlen(conn->passwd)),
927                                         NULL);
928       if(rc == LIBSSH2_ERROR_EAGAIN) {
929         break;
930       }
931       else if(rc == 0) {
932         sshc->authed = TRUE;
933         infof(data, "Initialized password authentication\n");
934         state(conn, SSH_AUTH_DONE);
935       }
936       else {
937         state(conn, SSH_AUTH_HOST_INIT);
938       }
939       break;
940 
941     case SSH_AUTH_HOST_INIT:
942       if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
943          (strstr(sshc->authlist, "hostbased") != NULL)) {
944         state(conn, SSH_AUTH_HOST);
945       }
946       else {
947         state(conn, SSH_AUTH_AGENT_INIT);
948       }
949       break;
950 
951     case SSH_AUTH_HOST:
952       state(conn, SSH_AUTH_AGENT_INIT);
953       break;
954 
955     case SSH_AUTH_AGENT_INIT:
956 #ifdef HAVE_LIBSSH2_AGENT_API
957       if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
958          && (strstr(sshc->authlist, "publickey") != NULL)) {
959 
960         /* Connect to the ssh-agent */
961         /* The agent could be shared by a curl thread i believe
962            but nothing obvious as keys can be added/removed at any time */
963         if(!sshc->ssh_agent) {
964           sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
965           if(!sshc->ssh_agent) {
966             infof(data, "Could not create agent object\n");
967 
968             state(conn, SSH_AUTH_KEY_INIT);
969             break;
970           }
971         }
972 
973         rc = libssh2_agent_connect(sshc->ssh_agent);
974         if(rc == LIBSSH2_ERROR_EAGAIN)
975           break;
976         if(rc < 0) {
977           infof(data, "Failure connecting to agent\n");
978           state(conn, SSH_AUTH_KEY_INIT);
979         }
980         else {
981           state(conn, SSH_AUTH_AGENT_LIST);
982         }
983       }
984       else
985 #endif /* HAVE_LIBSSH2_AGENT_API */
986         state(conn, SSH_AUTH_KEY_INIT);
987       break;
988 
989     case SSH_AUTH_AGENT_LIST:
990 #ifdef HAVE_LIBSSH2_AGENT_API
991       rc = libssh2_agent_list_identities(sshc->ssh_agent);
992 
993       if(rc == LIBSSH2_ERROR_EAGAIN)
994         break;
995       if(rc < 0) {
996         infof(data, "Failure requesting identities to agent\n");
997         state(conn, SSH_AUTH_KEY_INIT);
998       }
999       else {
1000         state(conn, SSH_AUTH_AGENT);
1001         sshc->sshagent_prev_identity = NULL;
1002       }
1003 #endif
1004       break;
1005 
1006     case SSH_AUTH_AGENT:
1007 #ifdef HAVE_LIBSSH2_AGENT_API
1008       /* as prev_identity evolves only after an identity user auth finished we
1009          can safely request it again as long as EAGAIN is returned here or by
1010          libssh2_agent_userauth */
1011       rc = libssh2_agent_get_identity(sshc->ssh_agent,
1012                                       &sshc->sshagent_identity,
1013                                       sshc->sshagent_prev_identity);
1014       if(rc == LIBSSH2_ERROR_EAGAIN)
1015         break;
1016 
1017       if(rc == 0) {
1018         rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
1019                                     sshc->sshagent_identity);
1020 
1021         if(rc < 0) {
1022           if(rc != LIBSSH2_ERROR_EAGAIN) {
1023             /* tried and failed? go to next identity */
1024             sshc->sshagent_prev_identity = sshc->sshagent_identity;
1025           }
1026           break;
1027         }
1028       }
1029 
1030       if(rc < 0)
1031         infof(data, "Failure requesting identities to agent\n");
1032       else if(rc == 1)
1033         infof(data, "No identity would match\n");
1034 
1035       if(rc == LIBSSH2_ERROR_NONE) {
1036         sshc->authed = TRUE;
1037         infof(data, "Agent based authentication successful\n");
1038         state(conn, SSH_AUTH_DONE);
1039       }
1040       else
1041         state(conn, SSH_AUTH_KEY_INIT);
1042 #endif
1043       break;
1044 
1045     case SSH_AUTH_KEY_INIT:
1046       if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
1047          && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
1048         state(conn, SSH_AUTH_KEY);
1049       }
1050       else {
1051         state(conn, SSH_AUTH_DONE);
1052       }
1053       break;
1054 
1055     case SSH_AUTH_KEY:
1056       /* Authentication failed. Continue with keyboard-interactive now. */
1057       rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
1058                                                     conn->user,
1059                                                     curlx_uztoui(
1060                                                       strlen(conn->user)),
1061                                                     &kbd_callback);
1062       if(rc == LIBSSH2_ERROR_EAGAIN) {
1063         break;
1064       }
1065       else if(rc == 0) {
1066         sshc->authed = TRUE;
1067         infof(data, "Initialized keyboard interactive authentication\n");
1068       }
1069       state(conn, SSH_AUTH_DONE);
1070       break;
1071 
1072     case SSH_AUTH_DONE:
1073       if(!sshc->authed) {
1074         failf(data, "Authentication failure");
1075         state(conn, SSH_SESSION_FREE);
1076         sshc->actualcode = CURLE_LOGIN_DENIED;
1077         break;
1078       }
1079 
1080       /*
1081        * At this point we have an authenticated ssh session.
1082        */
1083       infof(data, "Authentication complete\n");
1084 
1085       Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
1086 
1087       conn->sockfd = sock;
1088       conn->writesockfd = CURL_SOCKET_BAD;
1089 
1090       if(conn->handler->protocol == CURLPROTO_SFTP) {
1091         state(conn, SSH_SFTP_INIT);
1092         break;
1093       }
1094       infof(data, "SSH CONNECT phase done\n");
1095       state(conn, SSH_STOP);
1096       break;
1097 
1098     case SSH_SFTP_INIT:
1099       /*
1100        * Start the libssh2 sftp session
1101        */
1102       sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
1103       if(!sshc->sftp_session) {
1104         if(libssh2_session_last_errno(sshc->ssh_session) ==
1105            LIBSSH2_ERROR_EAGAIN) {
1106           rc = LIBSSH2_ERROR_EAGAIN;
1107           break;
1108         }
1109         else {
1110           char *err_msg;
1111 
1112           (void)libssh2_session_last_error(sshc->ssh_session,
1113                                            &err_msg, NULL, 0);
1114           failf(data, "Failure initializing sftp session: %s", err_msg);
1115           state(conn, SSH_SESSION_FREE);
1116           sshc->actualcode = CURLE_FAILED_INIT;
1117           break;
1118         }
1119       }
1120       state(conn, SSH_SFTP_REALPATH);
1121       break;
1122 
1123     case SSH_SFTP_REALPATH:
1124     {
1125       char tempHome[PATH_MAX];
1126 
1127       /*
1128        * Get the "home" directory
1129        */
1130       rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
1131                                  tempHome, PATH_MAX-1);
1132       if(rc == LIBSSH2_ERROR_EAGAIN) {
1133         break;
1134       }
1135       else if(rc > 0) {
1136         /* It seems that this string is not always NULL terminated */
1137         tempHome[rc] = '\0';
1138         sshc->homedir = strdup(tempHome);
1139         if(!sshc->homedir) {
1140           state(conn, SSH_SFTP_CLOSE);
1141           sshc->actualcode = CURLE_OUT_OF_MEMORY;
1142           break;
1143         }
1144         conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
1145       }
1146       else {
1147         /* Return the error type */
1148         err = sftp_libssh2_last_error(sshc->sftp_session);
1149         result = sftp_libssh2_error_to_CURLE(err);
1150         sshc->actualcode = result?result:CURLE_SSH;
1151         DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
1152                      err, (int)result));
1153         state(conn, SSH_STOP);
1154         break;
1155       }
1156     }
1157     /* This is the last step in the SFTP connect phase. Do note that while
1158        we get the homedir here, we get the "workingpath" in the DO action
1159        since the homedir will remain the same between request but the
1160        working path will not. */
1161     DEBUGF(infof(data, "SSH CONNECT phase done\n"));
1162     state(conn, SSH_STOP);
1163     break;
1164 
1165     case SSH_SFTP_QUOTE_INIT:
1166 
1167       result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
1168       if(result) {
1169         sshc->actualcode = result;
1170         state(conn, SSH_STOP);
1171         break;
1172       }
1173 
1174       if(data->set.quote) {
1175         infof(data, "Sending quote commands\n");
1176         sshc->quote_item = data->set.quote;
1177         state(conn, SSH_SFTP_QUOTE);
1178       }
1179       else {
1180         state(conn, SSH_SFTP_TRANS_INIT);
1181       }
1182       break;
1183 
1184     case SSH_SFTP_POSTQUOTE_INIT:
1185       if(data->set.postquote) {
1186         infof(data, "Sending quote commands\n");
1187         sshc->quote_item = data->set.postquote;
1188         state(conn, SSH_SFTP_QUOTE);
1189       }
1190       else {
1191         state(conn, SSH_STOP);
1192       }
1193       break;
1194 
1195     case SSH_SFTP_QUOTE:
1196       /* Send any quote commands */
1197     {
1198       const char *cp;
1199 
1200       /*
1201        * Support some of the "FTP" commands
1202        */
1203       char *cmd = sshc->quote_item->data;
1204       sshc->acceptfail = FALSE;
1205 
1206       /* if a command starts with an asterisk, which a legal SFTP command never
1207          can, the command will be allowed to fail without it causing any
1208          aborts or cancels etc. It will cause libcurl to act as if the command
1209          is successful, whatever the server reponds. */
1210 
1211       if(cmd[0] == '*') {
1212         cmd++;
1213         sshc->acceptfail = TRUE;
1214       }
1215 
1216       if(curl_strequal("pwd", cmd)) {
1217         /* output debug output if that is requested */
1218         char *tmp = aprintf("257 \"%s\" is current directory.\n",
1219                             sftp_scp->path);
1220         if(!tmp) {
1221           result = CURLE_OUT_OF_MEMORY;
1222           state(conn, SSH_SFTP_CLOSE);
1223           sshc->nextstate = SSH_NO_STATE;
1224           break;
1225         }
1226         if(data->set.verbose) {
1227           Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
1228           Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
1229         }
1230         /* this sends an FTP-like "header" to the header callback so that the
1231            current directory can be read very similar to how it is read when
1232            using ordinary FTP. */
1233         result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
1234         free(tmp);
1235         if(result) {
1236           state(conn, SSH_SFTP_CLOSE);
1237           sshc->nextstate = SSH_NO_STATE;
1238           sshc->actualcode = result;
1239         }
1240         else
1241           state(conn, SSH_SFTP_NEXT_QUOTE);
1242         break;
1243       }
1244       else if(cmd) {
1245         /*
1246          * the arguments following the command must be separated from the
1247          * command with a space so we can check for it unconditionally
1248          */
1249         cp = strchr(cmd, ' ');
1250         if(cp == NULL) {
1251           failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
1252           state(conn, SSH_SFTP_CLOSE);
1253           sshc->nextstate = SSH_NO_STATE;
1254           sshc->actualcode = CURLE_QUOTE_ERROR;
1255           break;
1256         }
1257 
1258         /*
1259          * also, every command takes at least one argument so we get that
1260          * first argument right now
1261          */
1262         result = get_pathname(&cp, &sshc->quote_path1);
1263         if(result) {
1264           if(result == CURLE_OUT_OF_MEMORY)
1265             failf(data, "Out of memory");
1266           else
1267             failf(data, "Syntax error: Bad first parameter");
1268           state(conn, SSH_SFTP_CLOSE);
1269           sshc->nextstate = SSH_NO_STATE;
1270           sshc->actualcode = result;
1271           break;
1272         }
1273 
1274         /*
1275          * SFTP is a binary protocol, so we don't send text commands
1276          * to the server. Instead, we scan for commands used by
1277          * OpenSSH's sftp program and call the appropriate libssh2
1278          * functions.
1279          */
1280         if(curl_strnequal(cmd, "chgrp ", 6) ||
1281            curl_strnequal(cmd, "chmod ", 6) ||
1282            curl_strnequal(cmd, "chown ", 6) ) {
1283           /* attribute change */
1284 
1285           /* sshc->quote_path1 contains the mode to set */
1286           /* get the destination */
1287           result = get_pathname(&cp, &sshc->quote_path2);
1288           if(result) {
1289             if(result == CURLE_OUT_OF_MEMORY)
1290               failf(data, "Out of memory");
1291             else
1292               failf(data, "Syntax error in chgrp/chmod/chown: "
1293                     "Bad second parameter");
1294             Curl_safefree(sshc->quote_path1);
1295             state(conn, SSH_SFTP_CLOSE);
1296             sshc->nextstate = SSH_NO_STATE;
1297             sshc->actualcode = result;
1298             break;
1299           }
1300           memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
1301           state(conn, SSH_SFTP_QUOTE_STAT);
1302           break;
1303         }
1304         else if(curl_strnequal(cmd, "ln ", 3) ||
1305                 curl_strnequal(cmd, "symlink ", 8)) {
1306           /* symbolic linking */
1307           /* sshc->quote_path1 is the source */
1308           /* get the destination */
1309           result = get_pathname(&cp, &sshc->quote_path2);
1310           if(result) {
1311             if(result == CURLE_OUT_OF_MEMORY)
1312               failf(data, "Out of memory");
1313             else
1314               failf(data,
1315                     "Syntax error in ln/symlink: Bad second parameter");
1316             Curl_safefree(sshc->quote_path1);
1317             state(conn, SSH_SFTP_CLOSE);
1318             sshc->nextstate = SSH_NO_STATE;
1319             sshc->actualcode = result;
1320             break;
1321           }
1322           state(conn, SSH_SFTP_QUOTE_SYMLINK);
1323           break;
1324         }
1325         else if(curl_strnequal(cmd, "mkdir ", 6)) {
1326           /* create dir */
1327           state(conn, SSH_SFTP_QUOTE_MKDIR);
1328           break;
1329         }
1330         else if(curl_strnequal(cmd, "rename ", 7)) {
1331           /* rename file */
1332           /* first param is the source path */
1333           /* second param is the dest. path */
1334           result = get_pathname(&cp, &sshc->quote_path2);
1335           if(result) {
1336             if(result == CURLE_OUT_OF_MEMORY)
1337               failf(data, "Out of memory");
1338             else
1339               failf(data, "Syntax error in rename: Bad second parameter");
1340             Curl_safefree(sshc->quote_path1);
1341             state(conn, SSH_SFTP_CLOSE);
1342             sshc->nextstate = SSH_NO_STATE;
1343             sshc->actualcode = result;
1344             break;
1345           }
1346           state(conn, SSH_SFTP_QUOTE_RENAME);
1347           break;
1348         }
1349         else if(curl_strnequal(cmd, "rmdir ", 6)) {
1350           /* delete dir */
1351           state(conn, SSH_SFTP_QUOTE_RMDIR);
1352           break;
1353         }
1354         else if(curl_strnequal(cmd, "rm ", 3)) {
1355           state(conn, SSH_SFTP_QUOTE_UNLINK);
1356           break;
1357         }
1358 
1359         failf(data, "Unknown SFTP command");
1360         Curl_safefree(sshc->quote_path1);
1361         Curl_safefree(sshc->quote_path2);
1362         state(conn, SSH_SFTP_CLOSE);
1363         sshc->nextstate = SSH_NO_STATE;
1364         sshc->actualcode = CURLE_QUOTE_ERROR;
1365         break;
1366       }
1367     }
1368     if(!sshc->quote_item) {
1369       state(conn, SSH_SFTP_TRANS_INIT);
1370     }
1371     break;
1372 
1373     case SSH_SFTP_NEXT_QUOTE:
1374       Curl_safefree(sshc->quote_path1);
1375       Curl_safefree(sshc->quote_path2);
1376 
1377       sshc->quote_item = sshc->quote_item->next;
1378 
1379       if(sshc->quote_item) {
1380         state(conn, SSH_SFTP_QUOTE);
1381       }
1382       else {
1383         if(sshc->nextstate != SSH_NO_STATE) {
1384           state(conn, sshc->nextstate);
1385           sshc->nextstate = SSH_NO_STATE;
1386         }
1387         else {
1388           state(conn, SSH_SFTP_TRANS_INIT);
1389         }
1390       }
1391       break;
1392 
1393     case SSH_SFTP_QUOTE_STAT:
1394     {
1395       char *cmd = sshc->quote_item->data;
1396       sshc->acceptfail = FALSE;
1397 
1398       /* if a command starts with an asterisk, which a legal SFTP command never
1399          can, the command will be allowed to fail without it causing any
1400          aborts or cancels etc. It will cause libcurl to act as if the command
1401          is successful, whatever the server reponds. */
1402 
1403       if(cmd[0] == '*') {
1404         cmd++;
1405         sshc->acceptfail = TRUE;
1406       }
1407 
1408       if(!curl_strnequal(cmd, "chmod", 5)) {
1409         /* Since chown and chgrp only set owner OR group but libssh2 wants to
1410          * set them both at once, we need to obtain the current ownership
1411          * first.  This takes an extra protocol round trip.
1412          */
1413         rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1414                                   curlx_uztoui(strlen(sshc->quote_path2)),
1415                                   LIBSSH2_SFTP_STAT,
1416                                   &sshc->quote_attrs);
1417         if(rc == LIBSSH2_ERROR_EAGAIN) {
1418           break;
1419         }
1420         else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
1421           err = sftp_libssh2_last_error(sshc->sftp_session);
1422           Curl_safefree(sshc->quote_path1);
1423           Curl_safefree(sshc->quote_path2);
1424           failf(data, "Attempt to get SFTP stats failed: %s",
1425                 sftp_libssh2_strerror(err));
1426           state(conn, SSH_SFTP_CLOSE);
1427           sshc->nextstate = SSH_NO_STATE;
1428           sshc->actualcode = CURLE_QUOTE_ERROR;
1429           break;
1430         }
1431       }
1432 
1433       /* Now set the new attributes... */
1434       if(curl_strnequal(cmd, "chgrp", 5)) {
1435         sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
1436         sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1437         if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1438            !sshc->acceptfail) {
1439           Curl_safefree(sshc->quote_path1);
1440           Curl_safefree(sshc->quote_path2);
1441           failf(data, "Syntax error: chgrp gid not a number");
1442           state(conn, SSH_SFTP_CLOSE);
1443           sshc->nextstate = SSH_NO_STATE;
1444           sshc->actualcode = CURLE_QUOTE_ERROR;
1445           break;
1446         }
1447       }
1448       else if(curl_strnequal(cmd, "chmod", 5)) {
1449         sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
1450         sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
1451         /* permissions are octal */
1452         if(sshc->quote_attrs.permissions == 0 &&
1453            !ISDIGIT(sshc->quote_path1[0])) {
1454           Curl_safefree(sshc->quote_path1);
1455           Curl_safefree(sshc->quote_path2);
1456           failf(data, "Syntax error: chmod permissions not a number");
1457           state(conn, SSH_SFTP_CLOSE);
1458           sshc->nextstate = SSH_NO_STATE;
1459           sshc->actualcode = CURLE_QUOTE_ERROR;
1460           break;
1461         }
1462       }
1463       else if(curl_strnequal(cmd, "chown", 5)) {
1464         sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
1465         sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
1466         if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
1467            !sshc->acceptfail) {
1468           Curl_safefree(sshc->quote_path1);
1469           Curl_safefree(sshc->quote_path2);
1470           failf(data, "Syntax error: chown uid not a number");
1471           state(conn, SSH_SFTP_CLOSE);
1472           sshc->nextstate = SSH_NO_STATE;
1473           sshc->actualcode = CURLE_QUOTE_ERROR;
1474           break;
1475         }
1476       }
1477 
1478       /* Now send the completed structure... */
1479       state(conn, SSH_SFTP_QUOTE_SETSTAT);
1480       break;
1481     }
1482 
1483     case SSH_SFTP_QUOTE_SETSTAT:
1484       rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
1485                                 curlx_uztoui(strlen(sshc->quote_path2)),
1486                                 LIBSSH2_SFTP_SETSTAT,
1487                                 &sshc->quote_attrs);
1488       if(rc == LIBSSH2_ERROR_EAGAIN) {
1489         break;
1490       }
1491       else if(rc != 0 && !sshc->acceptfail) {
1492         err = sftp_libssh2_last_error(sshc->sftp_session);
1493         Curl_safefree(sshc->quote_path1);
1494         Curl_safefree(sshc->quote_path2);
1495         failf(data, "Attempt to set SFTP stats failed: %s",
1496               sftp_libssh2_strerror(err));
1497         state(conn, SSH_SFTP_CLOSE);
1498         sshc->nextstate = SSH_NO_STATE;
1499         sshc->actualcode = CURLE_QUOTE_ERROR;
1500         break;
1501       }
1502       state(conn, SSH_SFTP_NEXT_QUOTE);
1503       break;
1504 
1505     case SSH_SFTP_QUOTE_SYMLINK:
1506       rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
1507                                    curlx_uztoui(strlen(sshc->quote_path1)),
1508                                    sshc->quote_path2,
1509                                    curlx_uztoui(strlen(sshc->quote_path2)),
1510                                    LIBSSH2_SFTP_SYMLINK);
1511       if(rc == LIBSSH2_ERROR_EAGAIN) {
1512         break;
1513       }
1514       else if(rc != 0 && !sshc->acceptfail) {
1515         err = sftp_libssh2_last_error(sshc->sftp_session);
1516         Curl_safefree(sshc->quote_path1);
1517         Curl_safefree(sshc->quote_path2);
1518         failf(data, "symlink command failed: %s",
1519               sftp_libssh2_strerror(err));
1520         state(conn, SSH_SFTP_CLOSE);
1521         sshc->nextstate = SSH_NO_STATE;
1522         sshc->actualcode = CURLE_QUOTE_ERROR;
1523         break;
1524       }
1525       state(conn, SSH_SFTP_NEXT_QUOTE);
1526       break;
1527 
1528     case SSH_SFTP_QUOTE_MKDIR:
1529       rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
1530                                  curlx_uztoui(strlen(sshc->quote_path1)),
1531                                  data->set.new_directory_perms);
1532       if(rc == LIBSSH2_ERROR_EAGAIN) {
1533         break;
1534       }
1535       else if(rc != 0 && !sshc->acceptfail) {
1536         err = sftp_libssh2_last_error(sshc->sftp_session);
1537         Curl_safefree(sshc->quote_path1);
1538         failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
1539         state(conn, SSH_SFTP_CLOSE);
1540         sshc->nextstate = SSH_NO_STATE;
1541         sshc->actualcode = CURLE_QUOTE_ERROR;
1542         break;
1543       }
1544       state(conn, SSH_SFTP_NEXT_QUOTE);
1545       break;
1546 
1547     case SSH_SFTP_QUOTE_RENAME:
1548       rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
1549                                   curlx_uztoui(strlen(sshc->quote_path1)),
1550                                   sshc->quote_path2,
1551                                   curlx_uztoui(strlen(sshc->quote_path2)),
1552                                   LIBSSH2_SFTP_RENAME_OVERWRITE |
1553                                   LIBSSH2_SFTP_RENAME_ATOMIC |
1554                                   LIBSSH2_SFTP_RENAME_NATIVE);
1555 
1556       if(rc == LIBSSH2_ERROR_EAGAIN) {
1557         break;
1558       }
1559       else if(rc != 0 && !sshc->acceptfail) {
1560         err = sftp_libssh2_last_error(sshc->sftp_session);
1561         Curl_safefree(sshc->quote_path1);
1562         Curl_safefree(sshc->quote_path2);
1563         failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
1564         state(conn, SSH_SFTP_CLOSE);
1565         sshc->nextstate = SSH_NO_STATE;
1566         sshc->actualcode = CURLE_QUOTE_ERROR;
1567         break;
1568       }
1569       state(conn, SSH_SFTP_NEXT_QUOTE);
1570       break;
1571 
1572     case SSH_SFTP_QUOTE_RMDIR:
1573       rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
1574                                  curlx_uztoui(strlen(sshc->quote_path1)));
1575       if(rc == LIBSSH2_ERROR_EAGAIN) {
1576         break;
1577       }
1578       else if(rc != 0 && !sshc->acceptfail) {
1579         err = sftp_libssh2_last_error(sshc->sftp_session);
1580         Curl_safefree(sshc->quote_path1);
1581         failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
1582         state(conn, SSH_SFTP_CLOSE);
1583         sshc->nextstate = SSH_NO_STATE;
1584         sshc->actualcode = CURLE_QUOTE_ERROR;
1585         break;
1586       }
1587       state(conn, SSH_SFTP_NEXT_QUOTE);
1588       break;
1589 
1590     case SSH_SFTP_QUOTE_UNLINK:
1591       rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
1592                                   curlx_uztoui(strlen(sshc->quote_path1)));
1593       if(rc == LIBSSH2_ERROR_EAGAIN) {
1594         break;
1595       }
1596       else if(rc != 0 && !sshc->acceptfail) {
1597         err = sftp_libssh2_last_error(sshc->sftp_session);
1598         Curl_safefree(sshc->quote_path1);
1599         failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
1600         state(conn, SSH_SFTP_CLOSE);
1601         sshc->nextstate = SSH_NO_STATE;
1602         sshc->actualcode = CURLE_QUOTE_ERROR;
1603         break;
1604       }
1605       state(conn, SSH_SFTP_NEXT_QUOTE);
1606       break;
1607 
1608     case SSH_SFTP_TRANS_INIT:
1609       if(data->set.upload)
1610         state(conn, SSH_SFTP_UPLOAD_INIT);
1611       else {
1612         if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
1613           state(conn, SSH_SFTP_READDIR_INIT);
1614         else
1615           state(conn, SSH_SFTP_DOWNLOAD_INIT);
1616       }
1617       break;
1618 
1619     case SSH_SFTP_UPLOAD_INIT:
1620     {
1621       unsigned long flags;
1622       /*
1623        * NOTE!!!  libssh2 requires that the destination path is a full path
1624        *          that includes the destination file and name OR ends in a "/"
1625        *          If this is not done the destination file will be named the
1626        *          same name as the last directory in the path.
1627        */
1628 
1629       if(data->state.resume_from != 0) {
1630         LIBSSH2_SFTP_ATTRIBUTES attrs;
1631         if(data->state.resume_from < 0) {
1632           rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
1633                                     curlx_uztoui(strlen(sftp_scp->path)),
1634                                     LIBSSH2_SFTP_STAT, &attrs);
1635           if(rc == LIBSSH2_ERROR_EAGAIN) {
1636             break;
1637           }
1638           else if(rc) {
1639             data->state.resume_from = 0;
1640           }
1641           else {
1642             curl_off_t size = attrs.filesize;
1643             if(size < 0) {
1644               failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
1645               return CURLE_BAD_DOWNLOAD_RESUME;
1646             }
1647             data->state.resume_from = attrs.filesize;
1648           }
1649         }
1650       }
1651 
1652       if(data->set.ftp_append)
1653         /* Try to open for append, but create if nonexisting */
1654         flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
1655       else if(data->state.resume_from > 0)
1656         /* If we have restart position then open for append */
1657         flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
1658       else
1659         /* Clear file before writing (normal behaviour) */
1660         flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
1661 
1662       sshc->sftp_handle =
1663         libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
1664                              curlx_uztoui(strlen(sftp_scp->path)),
1665                              flags, data->set.new_file_perms,
1666                              LIBSSH2_SFTP_OPENFILE);
1667 
1668       if(!sshc->sftp_handle) {
1669         rc = libssh2_session_last_errno(sshc->ssh_session);
1670 
1671         if(LIBSSH2_ERROR_EAGAIN == rc)
1672           break;
1673         else {
1674           if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
1675             /* only when there was an SFTP protocol error can we extract
1676                the sftp error! */
1677             err = sftp_libssh2_last_error(sshc->sftp_session);
1678           else
1679             err = -1; /* not an sftp error at all */
1680 
1681           if(sshc->secondCreateDirs) {
1682             state(conn, SSH_SFTP_CLOSE);
1683             sshc->actualcode = err>= LIBSSH2_FX_OK?
1684               sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1685             failf(data, "Creating the dir/file failed: %s",
1686                   sftp_libssh2_strerror(err));
1687             break;
1688           }
1689           else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
1690                    (err == LIBSSH2_FX_FAILURE) ||
1691                    (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
1692                   (data->set.ftp_create_missing_dirs &&
1693                    (strlen(sftp_scp->path) > 1))) {
1694             /* try to create the path remotely */
1695             sshc->secondCreateDirs = 1;
1696             state(conn, SSH_SFTP_CREATE_DIRS_INIT);
1697             break;
1698           }
1699           state(conn, SSH_SFTP_CLOSE);
1700           sshc->actualcode = err>= LIBSSH2_FX_OK?
1701             sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
1702           if(!sshc->actualcode) {
1703             /* Sometimes, for some reason libssh2_sftp_last_error() returns
1704                zero even though libssh2_sftp_open() failed previously! We need
1705                to work around that! */
1706             sshc->actualcode = CURLE_SSH;
1707             err=-1;
1708           }
1709           failf(data, "Upload failed: %s (%d/%d)",
1710                 err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
1711                 err, rc);
1712           break;
1713         }
1714       }
1715 
1716       /* If we have a restart point then we need to seek to the correct
1717          position. */
1718       if(data->state.resume_from > 0) {
1719         /* Let's read off the proper amount of bytes from the input. */
1720         if(conn->seek_func) {
1721           seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1722                                     SEEK_SET);
1723         }
1724 
1725         if(seekerr != CURL_SEEKFUNC_OK) {
1726 
1727           if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1728             failf(data, "Could not seek stream");
1729             return CURLE_FTP_COULDNT_USE_REST;
1730           }
1731           /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1732           else {
1733             curl_off_t passed=0;
1734             do {
1735               size_t readthisamountnow =
1736                 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1737                 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1738 
1739               size_t actuallyread =
1740                 data->set.fread_func(data->state.buffer, 1, readthisamountnow,
1741                                      data->set.in);
1742 
1743               passed += actuallyread;
1744               if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1745                 /* this checks for greater-than only to make sure that the
1746                    CURL_READFUNC_ABORT return code still aborts */
1747                 failf(data, "Failed to read data");
1748                 return CURLE_FTP_COULDNT_USE_REST;
1749               }
1750             } while(passed < data->state.resume_from);
1751           }
1752         }
1753 
1754         /* now, decrease the size of the read */
1755         if(data->state.infilesize > 0) {
1756           data->state.infilesize -= data->state.resume_from;
1757           data->req.size = data->state.infilesize;
1758           Curl_pgrsSetUploadSize(data, data->state.infilesize);
1759         }
1760 
1761         SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
1762       }
1763       if(data->state.infilesize > 0) {
1764         data->req.size = data->state.infilesize;
1765         Curl_pgrsSetUploadSize(data, data->state.infilesize);
1766       }
1767       /* upload data */
1768       Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
1769 
1770       /* not set by Curl_setup_transfer to preserve keepon bits */
1771       conn->sockfd = conn->writesockfd;
1772 
1773       if(result) {
1774         state(conn, SSH_SFTP_CLOSE);
1775         sshc->actualcode = result;
1776       }
1777       else {
1778         /* store this original bitmask setup to use later on if we can't
1779            figure out a "real" bitmask */
1780         sshc->orig_waitfor = data->req.keepon;
1781 
1782         /* we want to use the _sending_ function even when the socket turns
1783            out readable as the underlying libssh2 sftp send function will deal
1784            with both accordingly */
1785         conn->cselect_bits = CURL_CSELECT_OUT;
1786 
1787         /* since we don't really wait for anything at this point, we want the
1788            state machine to move on as soon as possible so we set a very short
1789            timeout here */
1790         Curl_expire(data, 1);
1791 
1792         state(conn, SSH_STOP);
1793       }
1794       break;
1795     }
1796 
1797     case SSH_SFTP_CREATE_DIRS_INIT:
1798       if(strlen(sftp_scp->path) > 1) {
1799         sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
1800         state(conn, SSH_SFTP_CREATE_DIRS);
1801       }
1802       else {
1803         state(conn, SSH_SFTP_UPLOAD_INIT);
1804       }
1805       break;
1806 
1807     case SSH_SFTP_CREATE_DIRS:
1808       sshc->slash_pos = strchr(sshc->slash_pos, '/');
1809       if(sshc->slash_pos) {
1810         *sshc->slash_pos = 0;
1811 
1812         infof(data, "Creating directory '%s'\n", sftp_scp->path);
1813         state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
1814         break;
1815       }
1816       else {
1817         state(conn, SSH_SFTP_UPLOAD_INIT);
1818       }
1819       break;
1820 
1821     case SSH_SFTP_CREATE_DIRS_MKDIR:
1822       /* 'mode' - parameter is preliminary - default to 0644 */
1823       rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
1824                                  curlx_uztoui(strlen(sftp_scp->path)),
1825                                  data->set.new_directory_perms);
1826       if(rc == LIBSSH2_ERROR_EAGAIN) {
1827         break;
1828       }
1829       *sshc->slash_pos = '/';
1830       ++sshc->slash_pos;
1831       if(rc == -1) {
1832         /*
1833          * Abort if failure wasn't that the dir already exists or the
1834          * permission was denied (creation might succeed further down the
1835          * path) - retry on unspecific FAILURE also
1836          */
1837         err = sftp_libssh2_last_error(sshc->sftp_session);
1838         if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
1839            (err != LIBSSH2_FX_FAILURE) &&
1840            (err != LIBSSH2_FX_PERMISSION_DENIED)) {
1841           result = sftp_libssh2_error_to_CURLE(err);
1842           state(conn, SSH_SFTP_CLOSE);
1843           sshc->actualcode = result?result:CURLE_SSH;
1844           break;
1845         }
1846       }
1847       state(conn, SSH_SFTP_CREATE_DIRS);
1848       break;
1849 
1850     case SSH_SFTP_READDIR_INIT:
1851       Curl_pgrsSetDownloadSize(data, -1);
1852       if(data->set.opt_no_body) {
1853         state(conn, SSH_STOP);
1854         break;
1855       }
1856 
1857       /*
1858        * This is a directory that we are trying to get, so produce a directory
1859        * listing
1860        */
1861       sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
1862                                                sftp_scp->path,
1863                                                curlx_uztoui(
1864                                                  strlen(sftp_scp->path)),
1865                                                0, 0, LIBSSH2_SFTP_OPENDIR);
1866       if(!sshc->sftp_handle) {
1867         if(libssh2_session_last_errno(sshc->ssh_session) ==
1868            LIBSSH2_ERROR_EAGAIN) {
1869           rc = LIBSSH2_ERROR_EAGAIN;
1870           break;
1871         }
1872         else {
1873           err = sftp_libssh2_last_error(sshc->sftp_session);
1874           failf(data, "Could not open directory for reading: %s",
1875                 sftp_libssh2_strerror(err));
1876           state(conn, SSH_SFTP_CLOSE);
1877           result = sftp_libssh2_error_to_CURLE(err);
1878           sshc->actualcode = result?result:CURLE_SSH;
1879           break;
1880         }
1881       }
1882       if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
1883         state(conn, SSH_SFTP_CLOSE);
1884         sshc->actualcode = CURLE_OUT_OF_MEMORY;
1885         break;
1886       }
1887       if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
1888         Curl_safefree(sshc->readdir_filename);
1889         state(conn, SSH_SFTP_CLOSE);
1890         sshc->actualcode = CURLE_OUT_OF_MEMORY;
1891         break;
1892       }
1893       state(conn, SSH_SFTP_READDIR);
1894       break;
1895 
1896     case SSH_SFTP_READDIR:
1897       sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
1898                                                   sshc->readdir_filename,
1899                                                   PATH_MAX,
1900                                                   sshc->readdir_longentry,
1901                                                   PATH_MAX,
1902                                                   &sshc->readdir_attrs);
1903       if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
1904         rc = LIBSSH2_ERROR_EAGAIN;
1905         break;
1906       }
1907       if(sshc->readdir_len > 0) {
1908         sshc->readdir_filename[sshc->readdir_len] = '\0';
1909 
1910         if(data->set.ftp_list_only) {
1911           char *tmpLine;
1912 
1913           tmpLine = aprintf("%s\n", sshc->readdir_filename);
1914           if(tmpLine == NULL) {
1915             state(conn, SSH_SFTP_CLOSE);
1916             sshc->actualcode = CURLE_OUT_OF_MEMORY;
1917             break;
1918           }
1919           result = Curl_client_write(conn, CLIENTWRITE_BODY,
1920                                      tmpLine, sshc->readdir_len+1);
1921           free(tmpLine);
1922 
1923           if(result) {
1924             state(conn, SSH_STOP);
1925             break;
1926           }
1927           /* since this counts what we send to the client, we include the
1928              newline in this counter */
1929           data->req.bytecount += sshc->readdir_len+1;
1930 
1931           /* output debug output if that is requested */
1932           if(data->set.verbose) {
1933             Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
1934                        sshc->readdir_len, conn);
1935           }
1936         }
1937         else {
1938           sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
1939           sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
1940           sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
1941           if(!sshc->readdir_line) {
1942             Curl_safefree(sshc->readdir_filename);
1943             Curl_safefree(sshc->readdir_longentry);
1944             state(conn, SSH_SFTP_CLOSE);
1945             sshc->actualcode = CURLE_OUT_OF_MEMORY;
1946             break;
1947           }
1948 
1949           memcpy(sshc->readdir_line, sshc->readdir_longentry,
1950                  sshc->readdir_currLen);
1951           if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
1952              ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
1953               LIBSSH2_SFTP_S_IFLNK)) {
1954             sshc->readdir_linkPath = malloc(PATH_MAX + 1);
1955             if(sshc->readdir_linkPath == NULL) {
1956               Curl_safefree(sshc->readdir_filename);
1957               Curl_safefree(sshc->readdir_longentry);
1958               state(conn, SSH_SFTP_CLOSE);
1959               sshc->actualcode = CURLE_OUT_OF_MEMORY;
1960               break;
1961             }
1962 
1963             snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
1964                      sshc->readdir_filename);
1965             state(conn, SSH_SFTP_READDIR_LINK);
1966             break;
1967           }
1968           state(conn, SSH_SFTP_READDIR_BOTTOM);
1969           break;
1970         }
1971       }
1972       else if(sshc->readdir_len == 0) {
1973         Curl_safefree(sshc->readdir_filename);
1974         Curl_safefree(sshc->readdir_longentry);
1975         state(conn, SSH_SFTP_READDIR_DONE);
1976         break;
1977       }
1978       else if(sshc->readdir_len <= 0) {
1979         err = sftp_libssh2_last_error(sshc->sftp_session);
1980         result = sftp_libssh2_error_to_CURLE(err);
1981         sshc->actualcode = result?result:CURLE_SSH;
1982         failf(data, "Could not open remote file for reading: %s :: %d",
1983               sftp_libssh2_strerror(err),
1984               libssh2_session_last_errno(sshc->ssh_session));
1985         Curl_safefree(sshc->readdir_filename);
1986         Curl_safefree(sshc->readdir_longentry);
1987         state(conn, SSH_SFTP_CLOSE);
1988         break;
1989       }
1990       break;
1991 
1992     case SSH_SFTP_READDIR_LINK:
1993       sshc->readdir_len =
1994         libssh2_sftp_symlink_ex(sshc->sftp_session,
1995                                 sshc->readdir_linkPath,
1996                                 curlx_uztoui(strlen(sshc->readdir_linkPath)),
1997                                 sshc->readdir_filename,
1998                                 PATH_MAX, LIBSSH2_SFTP_READLINK);
1999       if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
2000         rc = LIBSSH2_ERROR_EAGAIN;
2001         break;
2002       }
2003       Curl_safefree(sshc->readdir_linkPath);
2004 
2005       /* get room for the filename and extra output */
2006       sshc->readdir_totalLen += 4 + sshc->readdir_len;
2007       new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
2008       if(!new_readdir_line) {
2009         Curl_safefree(sshc->readdir_line);
2010         Curl_safefree(sshc->readdir_filename);
2011         Curl_safefree(sshc->readdir_longentry);
2012         state(conn, SSH_SFTP_CLOSE);
2013         sshc->actualcode = CURLE_OUT_OF_MEMORY;
2014         break;
2015       }
2016       sshc->readdir_line = new_readdir_line;
2017 
2018       sshc->readdir_currLen += snprintf(sshc->readdir_line +
2019                                         sshc->readdir_currLen,
2020                                         sshc->readdir_totalLen -
2021                                         sshc->readdir_currLen,
2022                                         " -> %s",
2023                                         sshc->readdir_filename);
2024 
2025       state(conn, SSH_SFTP_READDIR_BOTTOM);
2026       break;
2027 
2028     case SSH_SFTP_READDIR_BOTTOM:
2029       sshc->readdir_currLen += snprintf(sshc->readdir_line +
2030                                         sshc->readdir_currLen,
2031                                         sshc->readdir_totalLen -
2032                                         sshc->readdir_currLen, "\n");
2033       result = Curl_client_write(conn, CLIENTWRITE_BODY,
2034                                  sshc->readdir_line,
2035                                  sshc->readdir_currLen);
2036 
2037       if(!result) {
2038 
2039         /* output debug output if that is requested */
2040         if(data->set.verbose) {
2041           Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
2042                      sshc->readdir_currLen, conn);
2043         }
2044         data->req.bytecount += sshc->readdir_currLen;
2045       }
2046       Curl_safefree(sshc->readdir_line);
2047       if(result) {
2048         state(conn, SSH_STOP);
2049       }
2050       else
2051         state(conn, SSH_SFTP_READDIR);
2052       break;
2053 
2054     case SSH_SFTP_READDIR_DONE:
2055       if(libssh2_sftp_closedir(sshc->sftp_handle) ==
2056          LIBSSH2_ERROR_EAGAIN) {
2057         rc = LIBSSH2_ERROR_EAGAIN;
2058         break;
2059       }
2060       sshc->sftp_handle = NULL;
2061       Curl_safefree(sshc->readdir_filename);
2062       Curl_safefree(sshc->readdir_longentry);
2063 
2064       /* no data to transfer */
2065       Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2066       state(conn, SSH_STOP);
2067       break;
2068 
2069     case SSH_SFTP_DOWNLOAD_INIT:
2070       /*
2071        * Work on getting the specified file
2072        */
2073       sshc->sftp_handle =
2074         libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
2075                              curlx_uztoui(strlen(sftp_scp->path)),
2076                              LIBSSH2_FXF_READ, data->set.new_file_perms,
2077                              LIBSSH2_SFTP_OPENFILE);
2078       if(!sshc->sftp_handle) {
2079         if(libssh2_session_last_errno(sshc->ssh_session) ==
2080            LIBSSH2_ERROR_EAGAIN) {
2081           rc = LIBSSH2_ERROR_EAGAIN;
2082           break;
2083         }
2084         else {
2085           err = sftp_libssh2_last_error(sshc->sftp_session);
2086           failf(data, "Could not open remote file for reading: %s",
2087                 sftp_libssh2_strerror(err));
2088           state(conn, SSH_SFTP_CLOSE);
2089           result = sftp_libssh2_error_to_CURLE(err);
2090           sshc->actualcode = result?result:CURLE_SSH;
2091           break;
2092         }
2093       }
2094       state(conn, SSH_SFTP_DOWNLOAD_STAT);
2095       break;
2096 
2097     case SSH_SFTP_DOWNLOAD_STAT:
2098     {
2099       LIBSSH2_SFTP_ATTRIBUTES attrs;
2100 
2101       rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
2102                                 curlx_uztoui(strlen(sftp_scp->path)),
2103                                 LIBSSH2_SFTP_STAT, &attrs);
2104       if(rc == LIBSSH2_ERROR_EAGAIN) {
2105         break;
2106       }
2107       else if(rc ||
2108               !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
2109               (attrs.filesize == 0)) {
2110         /*
2111          * libssh2_sftp_open() didn't return an error, so maybe the server
2112          * just doesn't support stat()
2113          * OR the server doesn't return a file size with a stat()
2114          * OR file size is 0
2115          */
2116         data->req.size = -1;
2117         data->req.maxdownload = -1;
2118         Curl_pgrsSetDownloadSize(data, -1);
2119       }
2120       else {
2121         curl_off_t size = attrs.filesize;
2122 
2123         if(size < 0) {
2124           failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
2125           return CURLE_BAD_DOWNLOAD_RESUME;
2126         }
2127         if(conn->data->state.use_range) {
2128           curl_off_t from, to;
2129           char *ptr;
2130           char *ptr2;
2131 
2132           from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
2133           while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
2134             ptr++;
2135           to=curlx_strtoofft(ptr, &ptr2, 0);
2136           if((ptr == ptr2) /* no "to" value given */
2137              || (to >= size)) {
2138             to = size - 1;
2139           }
2140           if(from < 0) {
2141             /* from is relative to end of file */
2142             from += size;
2143           }
2144           if(from >= size) {
2145             failf(data, "Offset (%"
2146                   CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2147                   CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
2148             return CURLE_BAD_DOWNLOAD_RESUME;
2149           }
2150           if(from > to) {
2151             from = to;
2152             size = 0;
2153           }
2154           else {
2155             size = to - from + 1;
2156           }
2157 
2158           SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
2159         }
2160         data->req.size = size;
2161         data->req.maxdownload = size;
2162         Curl_pgrsSetDownloadSize(data, size);
2163       }
2164 
2165       /* We can resume if we can seek to the resume position */
2166       if(data->state.resume_from) {
2167         if(data->state.resume_from < 0) {
2168           /* We're supposed to download the last abs(from) bytes */
2169           if((curl_off_t)attrs.filesize < -data->state.resume_from) {
2170             failf(data, "Offset (%"
2171                   CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
2172                   CURL_FORMAT_CURL_OFF_T ")",
2173                   data->state.resume_from, attrs.filesize);
2174             return CURLE_BAD_DOWNLOAD_RESUME;
2175           }
2176           /* download from where? */
2177           data->state.resume_from += attrs.filesize;
2178         }
2179         else {
2180           if((curl_off_t)attrs.filesize < data->state.resume_from) {
2181             failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
2182                   ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
2183                   data->state.resume_from, attrs.filesize);
2184             return CURLE_BAD_DOWNLOAD_RESUME;
2185           }
2186         }
2187         /* Does a completed file need to be seeked and started or closed ? */
2188         /* Now store the number of bytes we are expected to download */
2189         data->req.size = attrs.filesize - data->state.resume_from;
2190         data->req.maxdownload = attrs.filesize - data->state.resume_from;
2191         Curl_pgrsSetDownloadSize(data,
2192                                  attrs.filesize - data->state.resume_from);
2193         SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
2194       }
2195     }
2196 
2197     /* Setup the actual download */
2198     if(data->req.size == 0) {
2199       /* no data to transfer */
2200       Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
2201       infof(data, "File already completely downloaded\n");
2202       state(conn, SSH_STOP);
2203       break;
2204     }
2205     else {
2206       Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
2207                           FALSE, NULL, -1, NULL);
2208 
2209       /* not set by Curl_setup_transfer to preserve keepon bits */
2210       conn->writesockfd = conn->sockfd;
2211 
2212       /* we want to use the _receiving_ function even when the socket turns
2213          out writableable as the underlying libssh2 recv function will deal
2214          with both accordingly */
2215       conn->cselect_bits = CURL_CSELECT_IN;
2216     }
2217     if(result) {
2218       /* this should never occur; the close state should be entered
2219          at the time the error occurs */
2220       state(conn, SSH_SFTP_CLOSE);
2221       sshc->actualcode = result;
2222     }
2223     else {
2224       state(conn, SSH_STOP);
2225     }
2226     break;
2227 
2228     case SSH_SFTP_CLOSE:
2229       if(sshc->sftp_handle) {
2230         rc = libssh2_sftp_close(sshc->sftp_handle);
2231         if(rc == LIBSSH2_ERROR_EAGAIN) {
2232           break;
2233         }
2234         else if(rc < 0) {
2235           infof(data, "Failed to close libssh2 file\n");
2236         }
2237         sshc->sftp_handle = NULL;
2238       }
2239       if(sftp_scp)
2240         Curl_safefree(sftp_scp->path);
2241 
2242       DEBUGF(infof(data, "SFTP DONE done\n"));
2243 
2244       /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
2245          After nextstate is executed, the control should come back to
2246          SSH_SFTP_CLOSE to pass the correct result back  */
2247       if(sshc->nextstate != SSH_NO_STATE &&
2248          sshc->nextstate != SSH_SFTP_CLOSE) {
2249         state(conn, sshc->nextstate);
2250         sshc->nextstate = SSH_SFTP_CLOSE;
2251       }
2252       else {
2253         state(conn, SSH_STOP);
2254         result = sshc->actualcode;
2255       }
2256       break;
2257 
2258     case SSH_SFTP_SHUTDOWN:
2259       /* during times we get here due to a broken transfer and then the
2260          sftp_handle might not have been taken down so make sure that is done
2261          before we proceed */
2262 
2263       if(sshc->sftp_handle) {
2264         rc = libssh2_sftp_close(sshc->sftp_handle);
2265         if(rc == LIBSSH2_ERROR_EAGAIN) {
2266           break;
2267         }
2268         else if(rc < 0) {
2269           infof(data, "Failed to close libssh2 file\n");
2270         }
2271         sshc->sftp_handle = NULL;
2272       }
2273       if(sshc->sftp_session) {
2274         rc = libssh2_sftp_shutdown(sshc->sftp_session);
2275         if(rc == LIBSSH2_ERROR_EAGAIN) {
2276           break;
2277         }
2278         else if(rc < 0) {
2279           infof(data, "Failed to stop libssh2 sftp subsystem\n");
2280         }
2281         sshc->sftp_session = NULL;
2282       }
2283 
2284       Curl_safefree(sshc->homedir);
2285       conn->data->state.most_recent_ftp_entrypath = NULL;
2286 
2287       state(conn, SSH_SESSION_DISCONNECT);
2288       break;
2289 
2290     case SSH_SCP_TRANS_INIT:
2291       result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
2292       if(result) {
2293         sshc->actualcode = result;
2294         state(conn, SSH_STOP);
2295         break;
2296       }
2297 
2298       if(data->set.upload) {
2299         if(data->state.infilesize < 0) {
2300           failf(data, "SCP requires a known file size for upload");
2301           sshc->actualcode = CURLE_UPLOAD_FAILED;
2302           state(conn, SSH_SCP_CHANNEL_FREE);
2303           break;
2304         }
2305         state(conn, SSH_SCP_UPLOAD_INIT);
2306       }
2307       else {
2308         state(conn, SSH_SCP_DOWNLOAD_INIT);
2309       }
2310       break;
2311 
2312     case SSH_SCP_UPLOAD_INIT:
2313       /*
2314        * libssh2 requires that the destination path is a full path that
2315        * includes the destination file and name OR ends in a "/" .  If this is
2316        * not done the destination file will be named the same name as the last
2317        * directory in the path.
2318        */
2319       sshc->ssh_channel =
2320         SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
2321                  data->state.infilesize);
2322       if(!sshc->ssh_channel) {
2323         if(libssh2_session_last_errno(sshc->ssh_session) ==
2324            LIBSSH2_ERROR_EAGAIN) {
2325           rc = LIBSSH2_ERROR_EAGAIN;
2326           break;
2327         }
2328         else {
2329           int ssh_err;
2330           char *err_msg;
2331 
2332           ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2333                                                      &err_msg, NULL, 0));
2334           failf(conn->data, "%s", err_msg);
2335           state(conn, SSH_SCP_CHANNEL_FREE);
2336           sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2337           break;
2338         }
2339       }
2340 
2341       /* upload data */
2342       Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
2343                           FIRSTSOCKET, NULL);
2344 
2345       /* not set by Curl_setup_transfer to preserve keepon bits */
2346       conn->sockfd = conn->writesockfd;
2347 
2348       if(result) {
2349         state(conn, SSH_SCP_CHANNEL_FREE);
2350         sshc->actualcode = result;
2351       }
2352       else {
2353         /* store this original bitmask setup to use later on if we can't
2354            figure out a "real" bitmask */
2355         sshc->orig_waitfor = data->req.keepon;
2356 
2357         /* we want to use the _sending_ function even when the socket turns
2358            out readable as the underlying libssh2 scp send function will deal
2359            with both accordingly */
2360         conn->cselect_bits = CURL_CSELECT_OUT;
2361 
2362         state(conn, SSH_STOP);
2363       }
2364       break;
2365 
2366     case SSH_SCP_DOWNLOAD_INIT:
2367     {
2368       /*
2369        * We must check the remote file; if it is a directory no values will
2370        * be set in sb
2371        */
2372       struct stat sb;
2373       curl_off_t bytecount;
2374 
2375       /* clear the struct scp recv will fill in */
2376       memset(&sb, 0, sizeof(struct stat));
2377 
2378       /* get a fresh new channel from the ssh layer */
2379       sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
2380                                            sftp_scp->path, &sb);
2381       if(!sshc->ssh_channel) {
2382         if(libssh2_session_last_errno(sshc->ssh_session) ==
2383            LIBSSH2_ERROR_EAGAIN) {
2384           rc = LIBSSH2_ERROR_EAGAIN;
2385           break;
2386         }
2387         else {
2388           int ssh_err;
2389           char *err_msg;
2390 
2391           ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
2392                                                      &err_msg, NULL, 0));
2393           failf(conn->data, "%s", err_msg);
2394           state(conn, SSH_SCP_CHANNEL_FREE);
2395           sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
2396           break;
2397         }
2398       }
2399 
2400       /* download data */
2401       bytecount = (curl_off_t)sb.st_size;
2402       data->req.maxdownload =  (curl_off_t)sb.st_size;
2403       Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
2404 
2405       /* not set by Curl_setup_transfer to preserve keepon bits */
2406       conn->writesockfd = conn->sockfd;
2407 
2408       /* we want to use the _receiving_ function even when the socket turns
2409          out writableable as the underlying libssh2 recv function will deal
2410          with both accordingly */
2411       conn->cselect_bits = CURL_CSELECT_IN;
2412 
2413       if(result) {
2414         state(conn, SSH_SCP_CHANNEL_FREE);
2415         sshc->actualcode = result;
2416       }
2417       else
2418         state(conn, SSH_STOP);
2419     }
2420     break;
2421 
2422     case SSH_SCP_DONE:
2423       if(data->set.upload)
2424         state(conn, SSH_SCP_SEND_EOF);
2425       else
2426         state(conn, SSH_SCP_CHANNEL_FREE);
2427       break;
2428 
2429     case SSH_SCP_SEND_EOF:
2430       if(sshc->ssh_channel) {
2431         rc = libssh2_channel_send_eof(sshc->ssh_channel);
2432         if(rc == LIBSSH2_ERROR_EAGAIN) {
2433           break;
2434         }
2435         else if(rc) {
2436           infof(data, "Failed to send libssh2 channel EOF\n");
2437         }
2438       }
2439       state(conn, SSH_SCP_WAIT_EOF);
2440       break;
2441 
2442     case SSH_SCP_WAIT_EOF:
2443       if(sshc->ssh_channel) {
2444         rc = libssh2_channel_wait_eof(sshc->ssh_channel);
2445         if(rc == LIBSSH2_ERROR_EAGAIN) {
2446           break;
2447         }
2448         else if(rc) {
2449           infof(data, "Failed to get channel EOF: %d\n", rc);
2450         }
2451       }
2452       state(conn, SSH_SCP_WAIT_CLOSE);
2453       break;
2454 
2455     case SSH_SCP_WAIT_CLOSE:
2456       if(sshc->ssh_channel) {
2457         rc = libssh2_channel_wait_closed(sshc->ssh_channel);
2458         if(rc == LIBSSH2_ERROR_EAGAIN) {
2459           break;
2460         }
2461         else if(rc) {
2462           infof(data, "Channel failed to close: %d\n", rc);
2463         }
2464       }
2465       state(conn, SSH_SCP_CHANNEL_FREE);
2466       break;
2467 
2468     case SSH_SCP_CHANNEL_FREE:
2469       if(sshc->ssh_channel) {
2470         rc = libssh2_channel_free(sshc->ssh_channel);
2471         if(rc == LIBSSH2_ERROR_EAGAIN) {
2472           break;
2473         }
2474         else if(rc < 0) {
2475           infof(data, "Failed to free libssh2 scp subsystem\n");
2476         }
2477         sshc->ssh_channel = NULL;
2478       }
2479       DEBUGF(infof(data, "SCP DONE phase complete\n"));
2480 #if 0 /* PREV */
2481       state(conn, SSH_SESSION_DISCONNECT);
2482 #endif
2483       state(conn, SSH_STOP);
2484       result = sshc->actualcode;
2485       break;
2486 
2487     case SSH_SESSION_DISCONNECT:
2488       /* during weird times when we've been prematurely aborted, the channel
2489          is still alive when we reach this state and we MUST kill the channel
2490          properly first */
2491       if(sshc->ssh_channel) {
2492         rc = libssh2_channel_free(sshc->ssh_channel);
2493         if(rc == LIBSSH2_ERROR_EAGAIN) {
2494           break;
2495         }
2496         else if(rc < 0) {
2497           infof(data, "Failed to free libssh2 scp subsystem\n");
2498         }
2499         sshc->ssh_channel = NULL;
2500       }
2501 
2502       if(sshc->ssh_session) {
2503         rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
2504         if(rc == LIBSSH2_ERROR_EAGAIN) {
2505           break;
2506         }
2507         else if(rc < 0) {
2508           infof(data, "Failed to disconnect libssh2 session\n");
2509         }
2510       }
2511 
2512       Curl_safefree(sshc->homedir);
2513       conn->data->state.most_recent_ftp_entrypath = NULL;
2514 
2515       state(conn, SSH_SESSION_FREE);
2516       break;
2517 
2518     case SSH_SESSION_FREE:
2519 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2520       if(sshc->kh) {
2521         libssh2_knownhost_free(sshc->kh);
2522         sshc->kh = NULL;
2523       }
2524 #endif
2525 
2526 #ifdef HAVE_LIBSSH2_AGENT_API
2527       if(sshc->ssh_agent) {
2528         rc = libssh2_agent_disconnect(sshc->ssh_agent);
2529         if(rc == LIBSSH2_ERROR_EAGAIN) {
2530           break;
2531         }
2532         else if(rc < 0) {
2533           infof(data, "Failed to disconnect from libssh2 agent\n");
2534         }
2535         libssh2_agent_free (sshc->ssh_agent);
2536         sshc->ssh_agent = NULL;
2537 
2538         /* NB: there is no need to free identities, they are part of internal
2539            agent stuff */
2540         sshc->sshagent_identity = NULL;
2541         sshc->sshagent_prev_identity = NULL;
2542       }
2543 #endif
2544 
2545       if(sshc->ssh_session) {
2546         rc = libssh2_session_free(sshc->ssh_session);
2547         if(rc == LIBSSH2_ERROR_EAGAIN) {
2548           break;
2549         }
2550         else if(rc < 0) {
2551           infof(data, "Failed to free libssh2 session\n");
2552         }
2553         sshc->ssh_session = NULL;
2554       }
2555 
2556       /* worst-case scenario cleanup */
2557 
2558       DEBUGASSERT(sshc->ssh_session == NULL);
2559       DEBUGASSERT(sshc->ssh_channel == NULL);
2560       DEBUGASSERT(sshc->sftp_session == NULL);
2561       DEBUGASSERT(sshc->sftp_handle == NULL);
2562 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2563       DEBUGASSERT(sshc->kh == NULL);
2564 #endif
2565 #ifdef HAVE_LIBSSH2_AGENT_API
2566       DEBUGASSERT(sshc->ssh_agent == NULL);
2567 #endif
2568 
2569       Curl_safefree(sshc->rsa_pub);
2570       Curl_safefree(sshc->rsa);
2571 
2572       Curl_safefree(sshc->quote_path1);
2573       Curl_safefree(sshc->quote_path2);
2574 
2575       Curl_safefree(sshc->homedir);
2576 
2577       Curl_safefree(sshc->readdir_filename);
2578       Curl_safefree(sshc->readdir_longentry);
2579       Curl_safefree(sshc->readdir_line);
2580       Curl_safefree(sshc->readdir_linkPath);
2581 
2582       /* the code we are about to return */
2583       result = sshc->actualcode;
2584 
2585       memset(sshc, 0, sizeof(struct ssh_conn));
2586 
2587       connclose(conn, "SSH session free");
2588       sshc->state = SSH_SESSION_FREE; /* current */
2589       sshc->nextstate = SSH_NO_STATE;
2590       state(conn, SSH_STOP);
2591       break;
2592 
2593     case SSH_QUIT:
2594       /* fallthrough, just stop! */
2595     default:
2596       /* internal error */
2597       sshc->nextstate = SSH_NO_STATE;
2598       state(conn, SSH_STOP);
2599       break;
2600     }
2601 
2602   } while(!rc && (sshc->state != SSH_STOP));
2603 
2604   if(rc == LIBSSH2_ERROR_EAGAIN) {
2605     /* we would block, we need to wait for the socket to be ready (in the
2606        right direction too)! */
2607     *block = TRUE;
2608   }
2609 
2610   return result;
2611 }
2612 
2613 /* called by the multi interface to figure out what socket(s) to wait for and
2614    for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
ssh_perform_getsock(const struct connectdata * conn,curl_socket_t * sock,int numsocks)2615 static int ssh_perform_getsock(const struct connectdata *conn,
2616                                curl_socket_t *sock, /* points to numsocks
2617                                                        number of sockets */
2618                                int numsocks)
2619 {
2620 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2621   int bitmap = GETSOCK_BLANK;
2622   (void)numsocks;
2623 
2624   sock[0] = conn->sock[FIRSTSOCKET];
2625 
2626   if(conn->waitfor & KEEP_RECV)
2627     bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
2628 
2629   if(conn->waitfor & KEEP_SEND)
2630     bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
2631 
2632   return bitmap;
2633 #else
2634   /* if we don't know the direction we can use the generic *_getsock()
2635      function even for the protocol_connect and doing states */
2636   return Curl_single_getsock(conn, sock, numsocks);
2637 #endif
2638 }
2639 
2640 /* Generic function called by the multi interface to figure out what socket(s)
2641    to wait for and for what actions during the DOING and PROTOCONNECT states*/
ssh_getsock(struct connectdata * conn,curl_socket_t * sock,int numsocks)2642 static int ssh_getsock(struct connectdata *conn,
2643                        curl_socket_t *sock, /* points to numsocks number
2644                                                of sockets */
2645                        int numsocks)
2646 {
2647 #ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2648   (void)conn;
2649   (void)sock;
2650   (void)numsocks;
2651   /* if we don't know any direction we can just play along as we used to and
2652      not provide any sensible info */
2653   return GETSOCK_BLANK;
2654 #else
2655   /* if we know the direction we can use the generic *_getsock() function even
2656      for the protocol_connect and doing states */
2657   return ssh_perform_getsock(conn, sock, numsocks);
2658 #endif
2659 }
2660 
2661 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2662 /*
2663  * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
2664  * function is used to figure out in what direction and stores this info so
2665  * that the multi interface can take advantage of it. Make sure to call this
2666  * function in all cases so that when it _doesn't_ return EAGAIN we can
2667  * restore the default wait bits.
2668  */
ssh_block2waitfor(struct connectdata * conn,bool block)2669 static void ssh_block2waitfor(struct connectdata *conn, bool block)
2670 {
2671   struct ssh_conn *sshc = &conn->proto.sshc;
2672   int dir;
2673   if(block && (dir = libssh2_session_block_directions(sshc->ssh_session))) {
2674     /* translate the libssh2 define bits into our own bit defines */
2675     conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
2676       ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
2677   }
2678   else
2679     /* It didn't block or libssh2 didn't reveal in which direction, put back
2680        the original set */
2681     conn->waitfor = sshc->orig_waitfor;
2682 }
2683 #else
2684   /* no libssh2 directional support so we simply don't know */
2685 #define ssh_block2waitfor(x,y) Curl_nop_stmt
2686 #endif
2687 
2688 /* called repeatedly until done from multi.c */
ssh_multi_statemach(struct connectdata * conn,bool * done)2689 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
2690 {
2691   struct ssh_conn *sshc = &conn->proto.sshc;
2692   CURLcode result = CURLE_OK;
2693   bool block; /* we store the status and use that to provide a ssh_getsock()
2694                  implementation */
2695 
2696   result = ssh_statemach_act(conn, &block);
2697   *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
2698   ssh_block2waitfor(conn, block);
2699 
2700   return result;
2701 }
2702 
ssh_block_statemach(struct connectdata * conn,bool duringconnect)2703 static CURLcode ssh_block_statemach(struct connectdata *conn,
2704                                    bool duringconnect)
2705 {
2706   struct ssh_conn *sshc = &conn->proto.sshc;
2707   CURLcode result = CURLE_OK;
2708   struct SessionHandle *data = conn->data;
2709 
2710   while((sshc->state != SSH_STOP) && !result) {
2711     bool block;
2712     long left;
2713 
2714     result = ssh_statemach_act(conn, &block);
2715     if(result)
2716       break;
2717 
2718     if(Curl_pgrsUpdate(conn))
2719       return CURLE_ABORTED_BY_CALLBACK;
2720     else {
2721       struct timeval now = Curl_tvnow();
2722       result = Curl_speedcheck(data, now);
2723       if(result)
2724         break;
2725     }
2726 
2727     left = Curl_timeleft(data, NULL, duringconnect);
2728     if(left < 0) {
2729       failf(data, "Operation timed out");
2730       return CURLE_OPERATION_TIMEDOUT;
2731     }
2732 
2733 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
2734     if(!result && block) {
2735       int dir = libssh2_session_block_directions(sshc->ssh_session);
2736       curl_socket_t sock = conn->sock[FIRSTSOCKET];
2737       curl_socket_t fd_read = CURL_SOCKET_BAD;
2738       curl_socket_t fd_write = CURL_SOCKET_BAD;
2739       if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
2740         fd_read = sock;
2741       if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
2742         fd_write = sock;
2743       /* wait for the socket to become ready */
2744       Curl_socket_ready(fd_read, fd_write,
2745                         left>1000?1000:left); /* ignore result */
2746     }
2747 #endif
2748 
2749   }
2750 
2751   return result;
2752 }
2753 
2754 /*
2755  * SSH setup and connection
2756  */
ssh_setup_connection(struct connectdata * conn)2757 static CURLcode ssh_setup_connection(struct connectdata *conn)
2758 {
2759   struct SSHPROTO *ssh;
2760 
2761   conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
2762   if(!ssh)
2763     return CURLE_OUT_OF_MEMORY;
2764 
2765   return CURLE_OK;
2766 }
2767 
2768 static Curl_recv scp_recv, sftp_recv;
2769 static Curl_send scp_send, sftp_send;
2770 
2771 /*
2772  * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
2773  * do protocol-specific actions at connect-time.
2774  */
ssh_connect(struct connectdata * conn,bool * done)2775 static CURLcode ssh_connect(struct connectdata *conn, bool *done)
2776 {
2777 #ifdef CURL_LIBSSH2_DEBUG
2778   curl_socket_t sock;
2779 #endif
2780   struct ssh_conn *ssh;
2781   CURLcode result;
2782   struct SessionHandle *data = conn->data;
2783 
2784   /* initialize per-handle data if not already */
2785   if(!data->req.protop)
2786     ssh_setup_connection(conn);
2787 
2788   /* We default to persistent connections. We set this already in this connect
2789      function to make the re-use checks properly be able to check this bit. */
2790   connkeep(conn, "SSH default");
2791 
2792   if(conn->handler->protocol & CURLPROTO_SCP) {
2793     conn->recv[FIRSTSOCKET] = scp_recv;
2794     conn->send[FIRSTSOCKET] = scp_send;
2795   }
2796   else {
2797     conn->recv[FIRSTSOCKET] = sftp_recv;
2798     conn->send[FIRSTSOCKET] = sftp_send;
2799   }
2800   ssh = &conn->proto.sshc;
2801 
2802 #ifdef CURL_LIBSSH2_DEBUG
2803   if(conn->user) {
2804     infof(data, "User: %s\n", conn->user);
2805   }
2806   if(conn->passwd) {
2807     infof(data, "Password: %s\n", conn->passwd);
2808   }
2809   sock = conn->sock[FIRSTSOCKET];
2810 #endif /* CURL_LIBSSH2_DEBUG */
2811 
2812   ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
2813                                              my_libssh2_free,
2814                                              my_libssh2_realloc, conn);
2815   if(ssh->ssh_session == NULL) {
2816     failf(data, "Failure initialising ssh session");
2817     return CURLE_FAILED_INIT;
2818   }
2819 
2820 #ifdef HAVE_LIBSSH2_KNOWNHOST_API
2821   if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
2822     int rc;
2823     ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
2824     if(!ssh->kh) {
2825       /* eeek. TODO: free the ssh_session! */
2826       return CURLE_FAILED_INIT;
2827     }
2828 
2829     /* read all known hosts from there */
2830     rc = libssh2_knownhost_readfile(ssh->kh,
2831                                     data->set.str[STRING_SSH_KNOWNHOSTS],
2832                                     LIBSSH2_KNOWNHOST_FILE_OPENSSH);
2833     if(rc < 0)
2834       infof(data, "Failed to read known hosts from %s\n",
2835             data->set.str[STRING_SSH_KNOWNHOSTS]);
2836   }
2837 #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2838 
2839 #ifdef CURL_LIBSSH2_DEBUG
2840   libssh2_trace(ssh->ssh_session, ~0);
2841   infof(data, "SSH socket: %d\n", (int)sock);
2842 #endif /* CURL_LIBSSH2_DEBUG */
2843 
2844   state(conn, SSH_INIT);
2845 
2846   result = ssh_multi_statemach(conn, done);
2847 
2848   return result;
2849 }
2850 
2851 /*
2852  ***********************************************************************
2853  *
2854  * scp_perform()
2855  *
2856  * This is the actual DO function for SCP. Get a file according to
2857  * the options previously setup.
2858  */
2859 
2860 static
scp_perform(struct connectdata * conn,bool * connected,bool * dophase_done)2861 CURLcode scp_perform(struct connectdata *conn,
2862                       bool *connected,
2863                       bool *dophase_done)
2864 {
2865   CURLcode result = CURLE_OK;
2866 
2867   DEBUGF(infof(conn->data, "DO phase starts\n"));
2868 
2869   *dophase_done = FALSE; /* not done yet */
2870 
2871   /* start the first command in the DO phase */
2872   state(conn, SSH_SCP_TRANS_INIT);
2873 
2874   /* run the state-machine */
2875   result = ssh_multi_statemach(conn, dophase_done);
2876 
2877   *connected = conn->bits.tcpconnect[FIRSTSOCKET];
2878 
2879   if(*dophase_done) {
2880     DEBUGF(infof(conn->data, "DO phase is complete\n"));
2881   }
2882 
2883   return result;
2884 }
2885 
2886 /* called from multi.c while DOing */
scp_doing(struct connectdata * conn,bool * dophase_done)2887 static CURLcode scp_doing(struct connectdata *conn,
2888                                bool *dophase_done)
2889 {
2890   CURLcode result;
2891   result = ssh_multi_statemach(conn, dophase_done);
2892 
2893   if(*dophase_done) {
2894     DEBUGF(infof(conn->data, "DO phase is complete\n"));
2895   }
2896   return result;
2897 }
2898 
2899 /*
2900  * The DO function is generic for both protocols. There was previously two
2901  * separate ones but this way means less duplicated code.
2902  */
2903 
ssh_do(struct connectdata * conn,bool * done)2904 static CURLcode ssh_do(struct connectdata *conn, bool *done)
2905 {
2906   CURLcode result;
2907   bool connected = 0;
2908   struct SessionHandle *data = conn->data;
2909   struct ssh_conn *sshc = &conn->proto.sshc;
2910 
2911   *done = FALSE; /* default to false */
2912 
2913   data->req.size = -1; /* make sure this is unknown at this point */
2914 
2915   sshc->actualcode = CURLE_OK; /* reset error code */
2916   sshc->secondCreateDirs =0;   /* reset the create dir attempt state
2917                                   variable */
2918 
2919   Curl_pgrsSetUploadCounter(data, 0);
2920   Curl_pgrsSetDownloadCounter(data, 0);
2921   Curl_pgrsSetUploadSize(data, -1);
2922   Curl_pgrsSetDownloadSize(data, -1);
2923 
2924   if(conn->handler->protocol & CURLPROTO_SCP)
2925     result = scp_perform(conn, &connected,  done);
2926   else
2927     result = sftp_perform(conn, &connected,  done);
2928 
2929   return result;
2930 }
2931 
2932 /* BLOCKING, but the function is using the state machine so the only reason
2933    this is still blocking is that the multi interface code has no support for
2934    disconnecting operations that takes a while */
scp_disconnect(struct connectdata * conn,bool dead_connection)2935 static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
2936 {
2937   CURLcode result = CURLE_OK;
2938   struct ssh_conn *ssh = &conn->proto.sshc;
2939   (void) dead_connection;
2940 
2941   Curl_safefree(conn->data->req.protop);
2942 
2943   if(ssh->ssh_session) {
2944     /* only if there's a session still around to use! */
2945 
2946     state(conn, SSH_SESSION_DISCONNECT);
2947 
2948     result = ssh_block_statemach(conn, FALSE);
2949   }
2950 
2951   return result;
2952 }
2953 
2954 /* generic done function for both SCP and SFTP called from their specific
2955    done functions */
ssh_done(struct connectdata * conn,CURLcode status)2956 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
2957 {
2958   CURLcode result = CURLE_OK;
2959   struct SSHPROTO *sftp_scp = conn->data->req.protop;
2960 
2961   if(!status) {
2962     /* run the state-machine
2963 
2964        TODO: when the multi interface is used, this _really_ should be using
2965        the ssh_multi_statemach function but we have no general support for
2966        non-blocking DONE operations, not in the multi state machine and with
2967        Curl_done() invokes on several places in the code!
2968     */
2969     result = ssh_block_statemach(conn, FALSE);
2970   }
2971   else
2972     result = status;
2973 
2974   if(sftp_scp)
2975     Curl_safefree(sftp_scp->path);
2976   if(Curl_pgrsDone(conn))
2977     return CURLE_ABORTED_BY_CALLBACK;
2978 
2979   conn->data->req.keepon = 0; /* clear all bits */
2980   return result;
2981 }
2982 
2983 
scp_done(struct connectdata * conn,CURLcode status,bool premature)2984 static CURLcode scp_done(struct connectdata *conn, CURLcode status,
2985                          bool premature)
2986 {
2987   (void)premature; /* not used */
2988 
2989   if(!status)
2990     state(conn, SSH_SCP_DONE);
2991 
2992   return ssh_done(conn, status);
2993 
2994 }
2995 
2996 /* return number of received (decrypted) bytes */
scp_send(struct connectdata * conn,int sockindex,const void * mem,size_t len,CURLcode * err)2997 static ssize_t scp_send(struct connectdata *conn, int sockindex,
2998                         const void *mem, size_t len, CURLcode *err)
2999 {
3000   ssize_t nwrite;
3001   (void)sockindex; /* we only support SCP on the fixed known primary socket */
3002 
3003   /* libssh2_channel_write() returns int! */
3004   nwrite = (ssize_t)
3005     libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
3006 
3007   ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3008 
3009   if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3010     *err = CURLE_AGAIN;
3011     nwrite = 0;
3012   }
3013   else if(nwrite < LIBSSH2_ERROR_NONE) {
3014     *err = libssh2_session_error_to_CURLE((int)nwrite);
3015     nwrite = -1;
3016   }
3017 
3018   return nwrite;
3019 }
3020 
3021 /*
3022  * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
3023  * a regular CURLcode value.
3024  */
scp_recv(struct connectdata * conn,int sockindex,char * mem,size_t len,CURLcode * err)3025 static ssize_t scp_recv(struct connectdata *conn, int sockindex,
3026                         char *mem, size_t len, CURLcode *err)
3027 {
3028   ssize_t nread;
3029   (void)sockindex; /* we only support SCP on the fixed known primary socket */
3030 
3031   /* libssh2_channel_read() returns int */
3032   nread = (ssize_t)
3033     libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
3034 
3035   ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3036   if(nread == LIBSSH2_ERROR_EAGAIN) {
3037     *err = CURLE_AGAIN;
3038     nread = -1;
3039   }
3040 
3041   return nread;
3042 }
3043 
3044 /*
3045  * =============== SFTP ===============
3046  */
3047 
3048 /*
3049  ***********************************************************************
3050  *
3051  * sftp_perform()
3052  *
3053  * This is the actual DO function for SFTP. Get a file/directory according to
3054  * the options previously setup.
3055  */
3056 
3057 static
sftp_perform(struct connectdata * conn,bool * connected,bool * dophase_done)3058 CURLcode sftp_perform(struct connectdata *conn,
3059                       bool *connected,
3060                       bool *dophase_done)
3061 {
3062   CURLcode result = CURLE_OK;
3063 
3064   DEBUGF(infof(conn->data, "DO phase starts\n"));
3065 
3066   *dophase_done = FALSE; /* not done yet */
3067 
3068   /* start the first command in the DO phase */
3069   state(conn, SSH_SFTP_QUOTE_INIT);
3070 
3071   /* run the state-machine */
3072   result = ssh_multi_statemach(conn, dophase_done);
3073 
3074   *connected = conn->bits.tcpconnect[FIRSTSOCKET];
3075 
3076   if(*dophase_done) {
3077     DEBUGF(infof(conn->data, "DO phase is complete\n"));
3078   }
3079 
3080   return result;
3081 }
3082 
3083 /* called from multi.c while DOing */
sftp_doing(struct connectdata * conn,bool * dophase_done)3084 static CURLcode sftp_doing(struct connectdata *conn,
3085                            bool *dophase_done)
3086 {
3087   CURLcode result = ssh_multi_statemach(conn, dophase_done);
3088 
3089   if(*dophase_done) {
3090     DEBUGF(infof(conn->data, "DO phase is complete\n"));
3091   }
3092   return result;
3093 }
3094 
3095 /* BLOCKING, but the function is using the state machine so the only reason
3096    this is still blocking is that the multi interface code has no support for
3097    disconnecting operations that takes a while */
sftp_disconnect(struct connectdata * conn,bool dead_connection)3098 static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
3099 {
3100   CURLcode result = CURLE_OK;
3101   (void) dead_connection;
3102 
3103   DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
3104 
3105   Curl_safefree(conn->data->req.protop);
3106 
3107   if(conn->proto.sshc.ssh_session) {
3108     /* only if there's a session still around to use! */
3109     state(conn, SSH_SFTP_SHUTDOWN);
3110     result = ssh_block_statemach(conn, FALSE);
3111   }
3112 
3113   DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
3114 
3115   return result;
3116 
3117 }
3118 
sftp_done(struct connectdata * conn,CURLcode status,bool premature)3119 static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
3120                                bool premature)
3121 {
3122   struct ssh_conn *sshc = &conn->proto.sshc;
3123 
3124   if(!status) {
3125     /* Post quote commands are executed after the SFTP_CLOSE state to avoid
3126        errors that could happen due to open file handles during POSTQUOTE
3127        operation */
3128     if(!status && !premature && conn->data->set.postquote) {
3129       sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
3130       state(conn, SSH_SFTP_CLOSE);
3131     }
3132     else
3133       state(conn, SSH_SFTP_CLOSE);
3134   }
3135   return ssh_done(conn, status);
3136 }
3137 
3138 /* return number of sent bytes */
sftp_send(struct connectdata * conn,int sockindex,const void * mem,size_t len,CURLcode * err)3139 static ssize_t sftp_send(struct connectdata *conn, int sockindex,
3140                          const void *mem, size_t len, CURLcode *err)
3141 {
3142   ssize_t nwrite;   /* libssh2_sftp_write() used to return size_t in 0.14
3143                        but is changed to ssize_t in 0.15. These days we don't
3144                        support libssh2 0.15*/
3145   (void)sockindex;
3146 
3147   nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
3148 
3149   ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3150 
3151   if(nwrite == LIBSSH2_ERROR_EAGAIN) {
3152     *err = CURLE_AGAIN;
3153     nwrite = 0;
3154   }
3155   else if(nwrite < LIBSSH2_ERROR_NONE) {
3156     *err = libssh2_session_error_to_CURLE((int)nwrite);
3157     nwrite = -1;
3158   }
3159 
3160   return nwrite;
3161 }
3162 
3163 /*
3164  * Return number of received (decrypted) bytes
3165  * or <0 on error
3166  */
sftp_recv(struct connectdata * conn,int sockindex,char * mem,size_t len,CURLcode * err)3167 static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
3168                          char *mem, size_t len, CURLcode *err)
3169 {
3170   ssize_t nread;
3171   (void)sockindex;
3172 
3173   nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
3174 
3175   ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
3176 
3177   if(nread == LIBSSH2_ERROR_EAGAIN) {
3178     *err = CURLE_AGAIN;
3179     nread = -1;
3180 
3181   }
3182   else if(nread < 0) {
3183     *err = libssh2_session_error_to_CURLE((int)nread);
3184   }
3185   return nread;
3186 }
3187 
3188 /* The get_pathname() function is being borrowed from OpenSSH sftp.c
3189    version 4.6p1. */
3190 /*
3191  * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
3192  *
3193  * Permission to use, copy, modify, and distribute this software for any
3194  * purpose with or without fee is hereby granted, provided that the above
3195  * copyright notice and this permission notice appear in all copies.
3196  *
3197  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3198  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3199  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3200  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3201  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3202  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3203  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3204  */
3205 static CURLcode
get_pathname(const char ** cpp,char ** path)3206 get_pathname(const char **cpp, char **path)
3207 {
3208   const char *cp = *cpp, *end;
3209   char quot;
3210   unsigned int i, j;
3211   static const char WHITESPACE[] = " \t\r\n";
3212 
3213   cp += strspn(cp, WHITESPACE);
3214   if(!*cp) {
3215     *cpp = cp;
3216     *path = NULL;
3217     return CURLE_QUOTE_ERROR;
3218   }
3219 
3220   *path = malloc(strlen(cp) + 1);
3221   if(*path == NULL)
3222     return CURLE_OUT_OF_MEMORY;
3223 
3224   /* Check for quoted filenames */
3225   if(*cp == '\"' || *cp == '\'') {
3226     quot = *cp++;
3227 
3228     /* Search for terminating quote, unescape some chars */
3229     for(i = j = 0; i <= strlen(cp); i++) {
3230       if(cp[i] == quot) {  /* Found quote */
3231         i++;
3232         (*path)[j] = '\0';
3233         break;
3234       }
3235       if(cp[i] == '\0') {  /* End of string */
3236         /*error("Unterminated quote");*/
3237         goto fail;
3238       }
3239       if(cp[i] == '\\') {  /* Escaped characters */
3240         i++;
3241         if(cp[i] != '\'' && cp[i] != '\"' &&
3242             cp[i] != '\\') {
3243           /*error("Bad escaped character '\\%c'",
3244               cp[i]);*/
3245           goto fail;
3246         }
3247       }
3248       (*path)[j++] = cp[i];
3249     }
3250 
3251     if(j == 0) {
3252       /*error("Empty quotes");*/
3253       goto fail;
3254     }
3255     *cpp = cp + i + strspn(cp + i, WHITESPACE);
3256   }
3257   else {
3258     /* Read to end of filename */
3259     end = strpbrk(cp, WHITESPACE);
3260     if(end == NULL)
3261       end = strchr(cp, '\0');
3262     *cpp = end + strspn(end, WHITESPACE);
3263 
3264     memcpy(*path, cp, end - cp);
3265     (*path)[end - cp] = '\0';
3266   }
3267   return CURLE_OK;
3268 
3269   fail:
3270   Curl_safefree(*path);
3271   return CURLE_QUOTE_ERROR;
3272 }
3273 
3274 
sftp_libssh2_strerror(int err)3275 static const char *sftp_libssh2_strerror(int err)
3276 {
3277   switch (err) {
3278     case LIBSSH2_FX_NO_SUCH_FILE:
3279       return "No such file or directory";
3280 
3281     case LIBSSH2_FX_PERMISSION_DENIED:
3282       return "Permission denied";
3283 
3284     case LIBSSH2_FX_FAILURE:
3285       return "Operation failed";
3286 
3287     case LIBSSH2_FX_BAD_MESSAGE:
3288       return "Bad message from SFTP server";
3289 
3290     case LIBSSH2_FX_NO_CONNECTION:
3291       return "Not connected to SFTP server";
3292 
3293     case LIBSSH2_FX_CONNECTION_LOST:
3294       return "Connection to SFTP server lost";
3295 
3296     case LIBSSH2_FX_OP_UNSUPPORTED:
3297       return "Operation not supported by SFTP server";
3298 
3299     case LIBSSH2_FX_INVALID_HANDLE:
3300       return "Invalid handle";
3301 
3302     case LIBSSH2_FX_NO_SUCH_PATH:
3303       return "No such file or directory";
3304 
3305     case LIBSSH2_FX_FILE_ALREADY_EXISTS:
3306       return "File already exists";
3307 
3308     case LIBSSH2_FX_WRITE_PROTECT:
3309       return "File is write protected";
3310 
3311     case LIBSSH2_FX_NO_MEDIA:
3312       return "No media";
3313 
3314     case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
3315       return "Disk full";
3316 
3317     case LIBSSH2_FX_QUOTA_EXCEEDED:
3318       return "User quota exceeded";
3319 
3320     case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
3321       return "Unknown principle";
3322 
3323     case LIBSSH2_FX_LOCK_CONFlICT:
3324       return "File lock conflict";
3325 
3326     case LIBSSH2_FX_DIR_NOT_EMPTY:
3327       return "Directory not empty";
3328 
3329     case LIBSSH2_FX_NOT_A_DIRECTORY:
3330       return "Not a directory";
3331 
3332     case LIBSSH2_FX_INVALID_FILENAME:
3333       return "Invalid filename";
3334 
3335     case LIBSSH2_FX_LINK_LOOP:
3336       return "Link points to itself";
3337   }
3338   return "Unknown error in libssh2";
3339 }
3340 
3341 #endif /* USE_LIBSSH2 */
3342