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