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