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