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