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