quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

libssh2.c (128003B)


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