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