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