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