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