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


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:16