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