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