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