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