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