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