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