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