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