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