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