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