1 /* $OpenBSD: sftp-client.c,v 1.143 2021/06/06 03:17:02 djm Exp $ */ 2 /* 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /* XXX: memleaks */ 19 /* XXX: signed vs unsigned */ 20 /* XXX: remove all logging, only return status codes */ 21 /* XXX: copy between two remote sites */ 22 23 #include <sys/types.h> 24 #include <sys/poll.h> 25 #include <sys/queue.h> 26 #include <sys/stat.h> 27 #include <sys/time.h> 28 #include <sys/statvfs.h> 29 #include <sys/uio.h> 30 31 #include <dirent.h> 32 #include <errno.h> 33 #include <fcntl.h> 34 #include <signal.h> 35 #include <stdarg.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <unistd.h> 40 41 #include "xmalloc.h" 42 #include "ssherr.h" 43 #include "sshbuf.h" 44 #include "log.h" 45 #include "atomicio.h" 46 #include "progressmeter.h" 47 #include "misc.h" 48 #include "utf8.h" 49 50 #include "sftp.h" 51 #include "sftp-common.h" 52 #include "sftp-client.h" 53 54 extern volatile sig_atomic_t interrupted; 55 extern int showprogress; 56 57 /* Default size of buffer for up/download */ 58 #define DEFAULT_COPY_BUFLEN 32768 59 60 /* Default number of concurrent outstanding requests */ 61 #define DEFAULT_NUM_REQUESTS 64 62 63 /* Minimum amount of data to read at a time */ 64 #define MIN_READ_SIZE 512 65 66 /* Maximum depth to descend in directory trees */ 67 #define MAX_DIR_DEPTH 64 68 69 struct sftp_conn { 70 int fd_in; 71 int fd_out; 72 u_int download_buflen; 73 u_int upload_buflen; 74 u_int num_requests; 75 u_int version; 76 u_int msg_id; 77 #define SFTP_EXT_POSIX_RENAME 0x00000001 78 #define SFTP_EXT_STATVFS 0x00000002 79 #define SFTP_EXT_FSTATVFS 0x00000004 80 #define SFTP_EXT_HARDLINK 0x00000008 81 #define SFTP_EXT_FSYNC 0x00000010 82 #define SFTP_EXT_LSETSTAT 0x00000020 83 #define SFTP_EXT_LIMITS 0x00000040 84 u_int exts; 85 u_int64_t limit_kbps; 86 struct bwlimit bwlimit_in, bwlimit_out; 87 }; 88 89 static u_char * 90 get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len, 91 const char *errfmt, ...) __attribute__((format(printf, 4, 5))); 92 93 /* ARGSUSED */ 94 static int 95 sftpio(void *_bwlimit, size_t amount) 96 { 97 struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit; 98 99 refresh_progress_meter(0); 100 if (bwlimit != NULL) 101 bandwidth_limit(bwlimit, amount); 102 return 0; 103 } 104 105 static void 106 send_msg(struct sftp_conn *conn, struct sshbuf *m) 107 { 108 u_char mlen[4]; 109 struct iovec iov[2]; 110 111 if (sshbuf_len(m) > SFTP_MAX_MSG_LENGTH) 112 fatal("Outbound message too long %zu", sshbuf_len(m)); 113 114 /* Send length first */ 115 put_u32(mlen, sshbuf_len(m)); 116 iov[0].iov_base = mlen; 117 iov[0].iov_len = sizeof(mlen); 118 iov[1].iov_base = (u_char *)sshbuf_ptr(m); 119 iov[1].iov_len = sshbuf_len(m); 120 121 if (atomiciov6(writev, conn->fd_out, iov, 2, sftpio, 122 conn->limit_kbps > 0 ? &conn->bwlimit_out : NULL) != 123 sshbuf_len(m) + sizeof(mlen)) 124 fatal("Couldn't send packet: %s", strerror(errno)); 125 126 sshbuf_reset(m); 127 } 128 129 static void 130 get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial) 131 { 132 u_int msg_len; 133 u_char *p; 134 int r; 135 136 if ((r = sshbuf_reserve(m, 4, &p)) != 0) 137 fatal_fr(r, "reserve"); 138 if (atomicio6(read, conn->fd_in, p, 4, sftpio, 139 conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) != 4) { 140 if (errno == EPIPE || errno == ECONNRESET) 141 fatal("Connection closed"); 142 else 143 fatal("Couldn't read packet: %s", strerror(errno)); 144 } 145 146 if ((r = sshbuf_get_u32(m, &msg_len)) != 0) 147 fatal_fr(r, "sshbuf_get_u32"); 148 if (msg_len > SFTP_MAX_MSG_LENGTH) { 149 do_log2(initial ? SYSLOG_LEVEL_ERROR : SYSLOG_LEVEL_FATAL, 150 "Received message too long %u", msg_len); 151 fatal("Ensure the remote shell produces no output " 152 "for non-interactive sessions."); 153 } 154 155 if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) 156 fatal_fr(r, "reserve"); 157 if (atomicio6(read, conn->fd_in, p, msg_len, sftpio, 158 conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) 159 != msg_len) { 160 if (errno == EPIPE) 161 fatal("Connection closed"); 162 else 163 fatal("Read packet: %s", strerror(errno)); 164 } 165 } 166 167 static void 168 get_msg(struct sftp_conn *conn, struct sshbuf *m) 169 { 170 get_msg_extended(conn, m, 0); 171 } 172 173 static void 174 send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s, 175 u_int len) 176 { 177 struct sshbuf *msg; 178 int r; 179 180 if ((msg = sshbuf_new()) == NULL) 181 fatal_f("sshbuf_new failed"); 182 if ((r = sshbuf_put_u8(msg, code)) != 0 || 183 (r = sshbuf_put_u32(msg, id)) != 0 || 184 (r = sshbuf_put_string(msg, s, len)) != 0) 185 fatal_fr(r, "compose"); 186 send_msg(conn, msg); 187 debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id); 188 sshbuf_free(msg); 189 } 190 191 static void 192 send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code, 193 const void *s, u_int len, Attrib *a) 194 { 195 struct sshbuf *msg; 196 int r; 197 198 if ((msg = sshbuf_new()) == NULL) 199 fatal_f("sshbuf_new failed"); 200 if ((r = sshbuf_put_u8(msg, code)) != 0 || 201 (r = sshbuf_put_u32(msg, id)) != 0 || 202 (r = sshbuf_put_string(msg, s, len)) != 0 || 203 (r = encode_attrib(msg, a)) != 0) 204 fatal_fr(r, "compose"); 205 send_msg(conn, msg); 206 debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id); 207 sshbuf_free(msg); 208 } 209 210 static u_int 211 get_status(struct sftp_conn *conn, u_int expected_id) 212 { 213 struct sshbuf *msg; 214 u_char type; 215 u_int id, status; 216 int r; 217 218 if ((msg = sshbuf_new()) == NULL) 219 fatal_f("sshbuf_new failed"); 220 get_msg(conn, msg); 221 if ((r = sshbuf_get_u8(msg, &type)) != 0 || 222 (r = sshbuf_get_u32(msg, &id)) != 0) 223 fatal_fr(r, "compose"); 224 225 if (id != expected_id) 226 fatal("ID mismatch (%u != %u)", id, expected_id); 227 if (type != SSH2_FXP_STATUS) 228 fatal("Expected SSH2_FXP_STATUS(%u) packet, got %u", 229 SSH2_FXP_STATUS, type); 230 231 if ((r = sshbuf_get_u32(msg, &status)) != 0) 232 fatal_fr(r, "parse"); 233 sshbuf_free(msg); 234 235 debug3("SSH2_FXP_STATUS %u", status); 236 237 return status; 238 } 239 240 static u_char * 241 get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len, 242 const char *errfmt, ...) 243 { 244 struct sshbuf *msg; 245 u_int id, status; 246 u_char type; 247 u_char *handle; 248 char errmsg[256]; 249 va_list args; 250 int r; 251 252 va_start(args, errfmt); 253 if (errfmt != NULL) 254 vsnprintf(errmsg, sizeof(errmsg), errfmt, args); 255 va_end(args); 256 257 if ((msg = sshbuf_new()) == NULL) 258 fatal_f("sshbuf_new failed"); 259 get_msg(conn, msg); 260 if ((r = sshbuf_get_u8(msg, &type)) != 0 || 261 (r = sshbuf_get_u32(msg, &id)) != 0) 262 fatal_fr(r, "parse"); 263 264 if (id != expected_id) 265 fatal("%s: ID mismatch (%u != %u)", 266 errfmt == NULL ? __func__ : errmsg, id, expected_id); 267 if (type == SSH2_FXP_STATUS) { 268 if ((r = sshbuf_get_u32(msg, &status)) != 0) 269 fatal_fr(r, "parse status"); 270 if (errfmt != NULL) 271 error("%s: %s", errmsg, fx2txt(status)); 272 sshbuf_free(msg); 273 return(NULL); 274 } else if (type != SSH2_FXP_HANDLE) 275 fatal("%s: Expected SSH2_FXP_HANDLE(%u) packet, got %u", 276 errfmt == NULL ? __func__ : errmsg, SSH2_FXP_HANDLE, type); 277 278 if ((r = sshbuf_get_string(msg, &handle, len)) != 0) 279 fatal_fr(r, "parse handle"); 280 sshbuf_free(msg); 281 282 return handle; 283 } 284 285 static Attrib * 286 get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet) 287 { 288 struct sshbuf *msg; 289 u_int id; 290 u_char type; 291 int r; 292 static Attrib a; 293 294 if ((msg = sshbuf_new()) == NULL) 295 fatal_f("sshbuf_new failed"); 296 get_msg(conn, msg); 297 298 if ((r = sshbuf_get_u8(msg, &type)) != 0 || 299 (r = sshbuf_get_u32(msg, &id)) != 0) 300 fatal_fr(r, "parse"); 301 302 debug3("Received stat reply T:%u I:%u", type, id); 303 if (id != expected_id) 304 fatal("ID mismatch (%u != %u)", id, expected_id); 305 if (type == SSH2_FXP_STATUS) { 306 u_int status; 307 308 if ((r = sshbuf_get_u32(msg, &status)) != 0) 309 fatal_fr(r, "parse status"); 310 if (quiet) 311 debug("Couldn't stat remote file: %s", fx2txt(status)); 312 else 313 error("Couldn't stat remote file: %s", fx2txt(status)); 314 sshbuf_free(msg); 315 return(NULL); 316 } else if (type != SSH2_FXP_ATTRS) { 317 fatal("Expected SSH2_FXP_ATTRS(%u) packet, got %u", 318 SSH2_FXP_ATTRS, type); 319 } 320 if ((r = decode_attrib(msg, &a)) != 0) { 321 error_fr(r, "decode_attrib"); 322 sshbuf_free(msg); 323 return NULL; 324 } 325 sshbuf_free(msg); 326 327 return &a; 328 } 329 330 static int 331 get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st, 332 u_int expected_id, int quiet) 333 { 334 struct sshbuf *msg; 335 u_char type; 336 u_int id; 337 u_int64_t flag; 338 int r; 339 340 if ((msg = sshbuf_new()) == NULL) 341 fatal_f("sshbuf_new failed"); 342 get_msg(conn, msg); 343 344 if ((r = sshbuf_get_u8(msg, &type)) != 0 || 345 (r = sshbuf_get_u32(msg, &id)) != 0) 346 fatal_fr(r, "parse"); 347 348 debug3("Received statvfs reply T:%u I:%u", type, id); 349 if (id != expected_id) 350 fatal("ID mismatch (%u != %u)", id, expected_id); 351 if (type == SSH2_FXP_STATUS) { 352 u_int status; 353 354 if ((r = sshbuf_get_u32(msg, &status)) != 0) 355 fatal_fr(r, "parse status"); 356 if (quiet) 357 debug("Couldn't statvfs: %s", fx2txt(status)); 358 else 359 error("Couldn't statvfs: %s", fx2txt(status)); 360 sshbuf_free(msg); 361 return -1; 362 } else if (type != SSH2_FXP_EXTENDED_REPLY) { 363 fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u", 364 SSH2_FXP_EXTENDED_REPLY, type); 365 } 366 367 memset(st, 0, sizeof(*st)); 368 if ((r = sshbuf_get_u64(msg, &st->f_bsize)) != 0 || 369 (r = sshbuf_get_u64(msg, &st->f_frsize)) != 0 || 370 (r = sshbuf_get_u64(msg, &st->f_blocks)) != 0 || 371 (r = sshbuf_get_u64(msg, &st->f_bfree)) != 0 || 372 (r = sshbuf_get_u64(msg, &st->f_bavail)) != 0 || 373 (r = sshbuf_get_u64(msg, &st->f_files)) != 0 || 374 (r = sshbuf_get_u64(msg, &st->f_ffree)) != 0 || 375 (r = sshbuf_get_u64(msg, &st->f_favail)) != 0 || 376 (r = sshbuf_get_u64(msg, &st->f_fsid)) != 0 || 377 (r = sshbuf_get_u64(msg, &flag)) != 0 || 378 (r = sshbuf_get_u64(msg, &st->f_namemax)) != 0) 379 fatal_fr(r, "parse statvfs"); 380 381 st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0; 382 st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0; 383 384 sshbuf_free(msg); 385 386 return 0; 387 } 388 389 struct sftp_conn * 390 do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, 391 u_int64_t limit_kbps) 392 { 393 u_char type; 394 struct sshbuf *msg; 395 struct sftp_conn *ret; 396 int r; 397 398 ret = xcalloc(1, sizeof(*ret)); 399 ret->msg_id = 1; 400 ret->fd_in = fd_in; 401 ret->fd_out = fd_out; 402 ret->download_buflen = ret->upload_buflen = 403 transfer_buflen ? transfer_buflen : DEFAULT_COPY_BUFLEN; 404 ret->num_requests = 405 num_requests ? num_requests : DEFAULT_NUM_REQUESTS; 406 ret->exts = 0; 407 ret->limit_kbps = 0; 408 409 if ((msg = sshbuf_new()) == NULL) 410 fatal_f("sshbuf_new failed"); 411 if ((r = sshbuf_put_u8(msg, SSH2_FXP_INIT)) != 0 || 412 (r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0) 413 fatal_fr(r, "parse"); 414 415 send_msg(ret, msg); 416 417 get_msg_extended(ret, msg, 1); 418 419 /* Expecting a VERSION reply */ 420 if ((r = sshbuf_get_u8(msg, &type)) != 0) 421 fatal_fr(r, "parse type"); 422 if (type != SSH2_FXP_VERSION) { 423 error("Invalid packet back from SSH2_FXP_INIT (type %u)", 424 type); 425 sshbuf_free(msg); 426 free(ret); 427 return(NULL); 428 } 429 if ((r = sshbuf_get_u32(msg, &ret->version)) != 0) 430 fatal_fr(r, "parse version"); 431 432 debug2("Remote version: %u", ret->version); 433 434 /* Check for extensions */ 435 while (sshbuf_len(msg) > 0) { 436 char *name; 437 u_char *value; 438 size_t vlen; 439 int known = 0; 440 441 if ((r = sshbuf_get_cstring(msg, &name, NULL)) != 0 || 442 (r = sshbuf_get_string(msg, &value, &vlen)) != 0) 443 fatal_fr(r, "parse extension"); 444 if (strcmp(name, "posix-rename@openssh.com") == 0 && 445 strcmp((char *)value, "1") == 0) { 446 ret->exts |= SFTP_EXT_POSIX_RENAME; 447 known = 1; 448 } else if (strcmp(name, "statvfs@openssh.com") == 0 && 449 strcmp((char *)value, "2") == 0) { 450 ret->exts |= SFTP_EXT_STATVFS; 451 known = 1; 452 } else if (strcmp(name, "fstatvfs@openssh.com") == 0 && 453 strcmp((char *)value, "2") == 0) { 454 ret->exts |= SFTP_EXT_FSTATVFS; 455 known = 1; 456 } else if (strcmp(name, "hardlink@openssh.com") == 0 && 457 strcmp((char *)value, "1") == 0) { 458 ret->exts |= SFTP_EXT_HARDLINK; 459 known = 1; 460 } else if (strcmp(name, "fsync@openssh.com") == 0 && 461 strcmp((char *)value, "1") == 0) { 462 ret->exts |= SFTP_EXT_FSYNC; 463 known = 1; 464 } else if (strcmp(name, "lsetstat@openssh.com") == 0 && 465 strcmp((char *)value, "1") == 0) { 466 ret->exts |= SFTP_EXT_LSETSTAT; 467 known = 1; 468 } else if (strcmp(name, "limits@openssh.com") == 0 && 469 strcmp((char *)value, "1") == 0) { 470 ret->exts |= SFTP_EXT_LIMITS; 471 known = 1; 472 } 473 if (known) { 474 debug2("Server supports extension \"%s\" revision %s", 475 name, value); 476 } else { 477 debug2("Unrecognised server extension \"%s\"", name); 478 } 479 free(name); 480 free(value); 481 } 482 483 sshbuf_free(msg); 484 485 /* Query the server for its limits */ 486 if (ret->exts & SFTP_EXT_LIMITS) { 487 struct sftp_limits limits; 488 if (do_limits(ret, &limits) != 0) 489 fatal_f("limits failed"); 490 491 /* If the caller did not specify, find a good value */ 492 if (transfer_buflen == 0) { 493 ret->download_buflen = limits.read_length; 494 ret->upload_buflen = limits.write_length; 495 debug("Using server download size %u", ret->download_buflen); 496 debug("Using server upload size %u", ret->upload_buflen); 497 } 498 499 /* Use the server limit to scale down our value only */ 500 if (num_requests == 0 && limits.open_handles) { 501 ret->num_requests = 502 MINIMUM(DEFAULT_NUM_REQUESTS, limits.open_handles); 503 debug("Server handle limit %llu; using %u", 504 (unsigned long long)limits.open_handles, 505 ret->num_requests); 506 } 507 } 508 509 /* Some filexfer v.0 servers don't support large packets */ 510 if (ret->version == 0) { 511 ret->download_buflen = MINIMUM(ret->download_buflen, 20480); 512 ret->upload_buflen = MINIMUM(ret->upload_buflen, 20480); 513 } 514 515 ret->limit_kbps = limit_kbps; 516 if (ret->limit_kbps > 0) { 517 bandwidth_limit_init(&ret->bwlimit_in, ret->limit_kbps, 518 ret->download_buflen); 519 bandwidth_limit_init(&ret->bwlimit_out, ret->limit_kbps, 520 ret->upload_buflen); 521 } 522 523 return ret; 524 } 525 526 u_int 527 sftp_proto_version(struct sftp_conn *conn) 528 { 529 return conn->version; 530 } 531 532 int 533 do_limits(struct sftp_conn *conn, struct sftp_limits *limits) 534 { 535 u_int id, msg_id; 536 u_char type; 537 struct sshbuf *msg; 538 int r; 539 540 if ((conn->exts & SFTP_EXT_LIMITS) == 0) { 541 error("Server does not support limits@openssh.com extension"); 542 return -1; 543 } 544 545 if ((msg = sshbuf_new()) == NULL) 546 fatal_f("sshbuf_new failed"); 547 548 id = conn->msg_id++; 549 if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || 550 (r = sshbuf_put_u32(msg, id)) != 0 || 551 (r = sshbuf_put_cstring(msg, "limits@openssh.com")) != 0) 552 fatal_fr(r, "compose"); 553 send_msg(conn, msg); 554 debug3("Sent message limits@openssh.com I:%u", id); 555 556 get_msg(conn, msg); 557 558 if ((r = sshbuf_get_u8(msg, &type)) != 0 || 559 (r = sshbuf_get_u32(msg, &msg_id)) != 0) 560 fatal_fr(r, "parse"); 561 562 debug3("Received limits reply T:%u I:%u", type, msg_id); 563 if (id != msg_id) 564 fatal("ID mismatch (%u != %u)", msg_id, id); 565 if (type != SSH2_FXP_EXTENDED_REPLY) { 566 debug_f("expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u", 567 SSH2_FXP_EXTENDED_REPLY, type); 568 /* Disable the limits extension */ 569 conn->exts &= ~SFTP_EXT_LIMITS; 570 sshbuf_free(msg); 571 return 0; 572 } 573 574 memset(limits, 0, sizeof(*limits)); 575 if ((r = sshbuf_get_u64(msg, &limits->packet_length)) != 0 || 576 (r = sshbuf_get_u64(msg, &limits->read_length)) != 0 || 577 (r = sshbuf_get_u64(msg, &limits->write_length)) != 0 || 578 (r = sshbuf_get_u64(msg, &limits->open_handles)) != 0) 579 fatal_fr(r, "parse limits"); 580 581 sshbuf_free(msg); 582 583 return 0; 584 } 585 586 int 587 do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len) 588 { 589 u_int id, status; 590 struct sshbuf *msg; 591 int r; 592 593 if ((msg = sshbuf_new()) == NULL) 594 fatal_f("sshbuf_new failed"); 595 596 id = conn->msg_id++; 597 if ((r = sshbuf_put_u8(msg, SSH2_FXP_CLOSE)) != 0 || 598 (r = sshbuf_put_u32(msg, id)) != 0 || 599 (r = sshbuf_put_string(msg, handle, handle_len)) != 0) 600 fatal_fr(r, "parse"); 601 send_msg(conn, msg); 602 debug3("Sent message SSH2_FXP_CLOSE I:%u", id); 603 604 status = get_status(conn, id); 605 if (status != SSH2_FX_OK) 606 error("Couldn't close file: %s", fx2txt(status)); 607 608 sshbuf_free(msg); 609 610 return status == SSH2_FX_OK ? 0 : -1; 611 } 612 613 614 static int 615 do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag, 616 SFTP_DIRENT ***dir) 617 { 618 struct sshbuf *msg; 619 u_int count, id, i, expected_id, ents = 0; 620 size_t handle_len; 621 u_char type, *handle; 622 int status = SSH2_FX_FAILURE; 623 int r; 624 625 if (dir) 626 *dir = NULL; 627 628 id = conn->msg_id++; 629 630 if ((msg = sshbuf_new()) == NULL) 631 fatal_f("sshbuf_new failed"); 632 if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPENDIR)) != 0 || 633 (r = sshbuf_put_u32(msg, id)) != 0 || 634 (r = sshbuf_put_cstring(msg, path)) != 0) 635 fatal_fr(r, "compose OPENDIR"); 636 send_msg(conn, msg); 637 638 handle = get_handle(conn, id, &handle_len, 639 "remote readdir(\"%s\")", path); 640 if (handle == NULL) { 641 sshbuf_free(msg); 642 return -1; 643 } 644 645 if (dir) { 646 ents = 0; 647 *dir = xcalloc(1, sizeof(**dir)); 648 (*dir)[0] = NULL; 649 } 650 651 for (; !interrupted;) { 652 id = expected_id = conn->msg_id++; 653 654 debug3("Sending SSH2_FXP_READDIR I:%u", id); 655 656 sshbuf_reset(msg); 657 if ((r = sshbuf_put_u8(msg, SSH2_FXP_READDIR)) != 0 || 658 (r = sshbuf_put_u32(msg, id)) != 0 || 659 (r = sshbuf_put_string(msg, handle, handle_len)) != 0) 660 fatal_fr(r, "compose READDIR"); 661 send_msg(conn, msg); 662 663 sshbuf_reset(msg); 664 665 get_msg(conn, msg); 666 667 if ((r = sshbuf_get_u8(msg, &type)) != 0 || 668 (r = sshbuf_get_u32(msg, &id)) != 0) 669 fatal_fr(r, "parse"); 670 671 debug3("Received reply T:%u I:%u", type, id); 672 673 if (id != expected_id) 674 fatal("ID mismatch (%u != %u)", id, expected_id); 675 676 if (type == SSH2_FXP_STATUS) { 677 u_int rstatus; 678 679 if ((r = sshbuf_get_u32(msg, &rstatus)) != 0) 680 fatal_fr(r, "parse status"); 681 debug3("Received SSH2_FXP_STATUS %d", rstatus); 682 if (rstatus == SSH2_FX_EOF) 683 break; 684 error("Couldn't read directory: %s", fx2txt(rstatus)); 685 goto out; 686 } else if (type != SSH2_FXP_NAME) 687 fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", 688 SSH2_FXP_NAME, type); 689 690 if ((r = sshbuf_get_u32(msg, &count)) != 0) 691 fatal_fr(r, "parse count"); 692 if (count > SSHBUF_SIZE_MAX) 693 fatal_f("nonsensical number of entries"); 694 if (count == 0) 695 break; 696 debug3("Received %d SSH2_FXP_NAME responses", count); 697 for (i = 0; i < count; i++) { 698 char *filename, *longname; 699 Attrib a; 700 701 if ((r = sshbuf_get_cstring(msg, &filename, 702 NULL)) != 0 || 703 (r = sshbuf_get_cstring(msg, &longname, 704 NULL)) != 0) 705 fatal_fr(r, "parse filenames"); 706 if ((r = decode_attrib(msg, &a)) != 0) { 707 error_fr(r, "couldn't decode attrib"); 708 free(filename); 709 free(longname); 710 goto out; 711 } 712 713 if (print_flag) 714 mprintf("%s\n", longname); 715 716 /* 717 * Directory entries should never contain '/' 718 * These can be used to attack recursive ops 719 * (e.g. send '../../../../etc/passwd') 720 */ 721 if (strchr(filename, '/') != NULL) { 722 error("Server sent suspect path \"%s\" " 723 "during readdir of \"%s\"", filename, path); 724 } else if (dir) { 725 *dir = xreallocarray(*dir, ents + 2, sizeof(**dir)); 726 (*dir)[ents] = xcalloc(1, sizeof(***dir)); 727 (*dir)[ents]->filename = xstrdup(filename); 728 (*dir)[ents]->longname = xstrdup(longname); 729 memcpy(&(*dir)[ents]->a, &a, sizeof(a)); 730 (*dir)[++ents] = NULL; 731 } 732 free(filename); 733 free(longname); 734 } 735 } 736 status = 0; 737 738 out: 739 sshbuf_free(msg); 740 do_close(conn, handle, handle_len); 741 free(handle); 742 743 if (status != 0 && dir != NULL) { 744 /* Don't return results on error */ 745 free_sftp_dirents(*dir); 746 *dir = NULL; 747 } else if (interrupted && dir != NULL && *dir != NULL) { 748 /* Don't return partial matches on interrupt */ 749 free_sftp_dirents(*dir); 750 *dir = xcalloc(1, sizeof(**dir)); 751 **dir = NULL; 752 } 753 754 return status == SSH2_FX_OK ? 0 : -1; 755 } 756 757 int 758 do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir) 759 { 760 return(do_lsreaddir(conn, path, 0, dir)); 761 } 762 763 void free_sftp_dirents(SFTP_DIRENT **s) 764 { 765 int i; 766 767 if (s == NULL) 768 return; 769 for (i = 0; s[i]; i++) { 770 free(s[i]->filename); 771 free(s[i]->longname); 772 free(s[i]); 773 } 774 free(s); 775 } 776 777 int 778 do_rm(struct sftp_conn *conn, const char *path) 779 { 780 u_int status, id; 781 782 debug2("Sending SSH2_FXP_REMOVE \"%s\"", path); 783 784 id = conn->msg_id++; 785 send_string_request(conn, id, SSH2_FXP_REMOVE, path, strlen(path)); 786 status = get_status(conn, id); 787 if (status != SSH2_FX_OK) 788 error("Couldn't delete file: %s", fx2txt(status)); 789 return status == SSH2_FX_OK ? 0 : -1; 790 } 791 792 int 793 do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag) 794 { 795 u_int status, id; 796 797 id = conn->msg_id++; 798 send_string_attrs_request(conn, id, SSH2_FXP_MKDIR, path, 799 strlen(path), a); 800 801 status = get_status(conn, id); 802 if (status != SSH2_FX_OK && print_flag) 803 error("Couldn't create directory: %s", fx2txt(status)); 804 805 return status == SSH2_FX_OK ? 0 : -1; 806 } 807 808 int 809 do_rmdir(struct sftp_conn *conn, const char *path) 810 { 811 u_int status, id; 812 813 id = conn->msg_id++; 814 send_string_request(conn, id, SSH2_FXP_RMDIR, path, 815 strlen(path)); 816 817 status = get_status(conn, id); 818 if (status != SSH2_FX_OK) 819 error("Couldn't remove directory: %s", fx2txt(status)); 820 821 return status == SSH2_FX_OK ? 0 : -1; 822 } 823 824 Attrib * 825 do_stat(struct sftp_conn *conn, const char *path, int quiet) 826 { 827 u_int id; 828 829 id = conn->msg_id++; 830 831 send_string_request(conn, id, 832 conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT, 833 path, strlen(path)); 834 835 return(get_decode_stat(conn, id, quiet)); 836 } 837 838 Attrib * 839 do_lstat(struct sftp_conn *conn, const char *path, int quiet) 840 { 841 u_int id; 842 843 if (conn->version == 0) { 844 if (quiet) 845 debug("Server version does not support lstat operation"); 846 else 847 logit("Server version does not support lstat operation"); 848 return(do_stat(conn, path, quiet)); 849 } 850 851 id = conn->msg_id++; 852 send_string_request(conn, id, SSH2_FXP_LSTAT, path, 853 strlen(path)); 854 855 return(get_decode_stat(conn, id, quiet)); 856 } 857 858 #ifdef notyet 859 Attrib * 860 do_fstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len, 861 int quiet) 862 { 863 u_int id; 864 865 id = conn->msg_id++; 866 send_string_request(conn, id, SSH2_FXP_FSTAT, handle, 867 handle_len); 868 869 return(get_decode_stat(conn, id, quiet)); 870 } 871 #endif 872 873 int 874 do_setstat(struct sftp_conn *conn, const char *path, Attrib *a) 875 { 876 u_int status, id; 877 878 id = conn->msg_id++; 879 send_string_attrs_request(conn, id, SSH2_FXP_SETSTAT, path, 880 strlen(path), a); 881 882 status = get_status(conn, id); 883 if (status != SSH2_FX_OK) 884 error("Couldn't setstat on \"%s\": %s", path, 885 fx2txt(status)); 886 887 return status == SSH2_FX_OK ? 0 : -1; 888 } 889 890 int 891 do_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len, 892 Attrib *a) 893 { 894 u_int status, id; 895 896 id = conn->msg_id++; 897 send_string_attrs_request(conn, id, SSH2_FXP_FSETSTAT, handle, 898 handle_len, a); 899 900 status = get_status(conn, id); 901 if (status != SSH2_FX_OK) 902 error("Couldn't fsetstat: %s", fx2txt(status)); 903 904 return status == SSH2_FX_OK ? 0 : -1; 905 } 906 907 char * 908 do_realpath(struct sftp_conn *conn, const char *path) 909 { 910 struct sshbuf *msg; 911 u_int expected_id, count, id; 912 char *filename, *longname; 913 Attrib a; 914 u_char type; 915 int r; 916 917 expected_id = id = conn->msg_id++; 918 send_string_request(conn, id, SSH2_FXP_REALPATH, path, 919 strlen(path)); 920 921 if ((msg = sshbuf_new()) == NULL) 922 fatal_f("sshbuf_new failed"); 923 924 get_msg(conn, msg); 925 if ((r = sshbuf_get_u8(msg, &type)) != 0 || 926 (r = sshbuf_get_u32(msg, &id)) != 0) 927 fatal_fr(r, "parse"); 928 929 if (id != expected_id) 930 fatal("ID mismatch (%u != %u)", id, expected_id); 931 932 if (type == SSH2_FXP_STATUS) { 933 u_int status; 934 935 if ((r = sshbuf_get_u32(msg, &status)) != 0) 936 fatal_fr(r, "parse status"); 937 error("Couldn't canonicalize: %s", fx2txt(status)); 938 sshbuf_free(msg); 939 return NULL; 940 } else if (type != SSH2_FXP_NAME) 941 fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", 942 SSH2_FXP_NAME, type); 943 944 if ((r = sshbuf_get_u32(msg, &count)) != 0) 945 fatal_fr(r, "parse count"); 946 if (count != 1) 947 fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count); 948 949 if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || 950 (r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 || 951 (r = decode_attrib(msg, &a)) != 0) 952 fatal_fr(r, "parse filename/attrib"); 953 954 debug3("SSH_FXP_REALPATH %s -> %s size %lu", path, filename, 955 (unsigned long)a.size); 956 957 free(longname); 958 959 sshbuf_free(msg); 960 961 return(filename); 962 } 963 964 int 965 do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath, 966 int force_legacy) 967 { 968 struct sshbuf *msg; 969 u_int status, id; 970 int r, use_ext = (conn->exts & SFTP_EXT_POSIX_RENAME) && !force_legacy; 971 972 if ((msg = sshbuf_new()) == NULL) 973 fatal_f("sshbuf_new failed"); 974 975 /* Send rename request */ 976 id = conn->msg_id++; 977 if (use_ext) { 978 if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || 979 (r = sshbuf_put_u32(msg, id)) != 0 || 980 (r = sshbuf_put_cstring(msg, 981 "posix-rename@openssh.com")) != 0) 982 fatal_fr(r, "compose posix-rename"); 983 } else { 984 if ((r = sshbuf_put_u8(msg, SSH2_FXP_RENAME)) != 0 || 985 (r = sshbuf_put_u32(msg, id)) != 0) 986 fatal_fr(r, "compose rename"); 987 } 988 if ((r = sshbuf_put_cstring(msg, oldpath)) != 0 || 989 (r = sshbuf_put_cstring(msg, newpath)) != 0) 990 fatal_fr(r, "compose paths"); 991 send_msg(conn, msg); 992 debug3("Sent message %s \"%s\" -> \"%s\"", 993 use_ext ? "posix-rename@openssh.com" : 994 "SSH2_FXP_RENAME", oldpath, newpath); 995 sshbuf_free(msg); 996 997 status = get_status(conn, id); 998 if (status != SSH2_FX_OK) 999 error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, 1000 newpath, fx2txt(status)); 1001 1002 return status == SSH2_FX_OK ? 0 : -1; 1003 } 1004 1005 int 1006 do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) 1007 { 1008 struct sshbuf *msg; 1009 u_int status, id; 1010 int r; 1011 1012 if ((conn->exts & SFTP_EXT_HARDLINK) == 0) { 1013 error("Server does not support hardlink@openssh.com extension"); 1014 return -1; 1015 } 1016 1017 if ((msg = sshbuf_new()) == NULL) 1018 fatal_f("sshbuf_new failed"); 1019 1020 /* Send link request */ 1021 id = conn->msg_id++; 1022 if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || 1023 (r = sshbuf_put_u32(msg, id)) != 0 || 1024 (r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 || 1025 (r = sshbuf_put_cstring(msg, oldpath)) != 0 || 1026 (r = sshbuf_put_cstring(msg, newpath)) != 0) 1027 fatal_fr(r, "compose"); 1028 send_msg(conn, msg); 1029 debug3("Sent message hardlink@openssh.com \"%s\" -> \"%s\"", 1030 oldpath, newpath); 1031 sshbuf_free(msg); 1032 1033 status = get_status(conn, id); 1034 if (status != SSH2_FX_OK) 1035 error("Couldn't link file \"%s\" to \"%s\": %s", oldpath, 1036 newpath, fx2txt(status)); 1037 1038 return status == SSH2_FX_OK ? 0 : -1; 1039 } 1040 1041 int 1042 do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) 1043 { 1044 struct sshbuf *msg; 1045 u_int status, id; 1046 int r; 1047 1048 if (conn->version < 3) { 1049 error("This server does not support the symlink operation"); 1050 return(SSH2_FX_OP_UNSUPPORTED); 1051 } 1052 1053 if ((msg = sshbuf_new()) == NULL) 1054 fatal_f("sshbuf_new failed"); 1055 1056 /* Send symlink request */ 1057 id = conn->msg_id++; 1058 if ((r = sshbuf_put_u8(msg, SSH2_FXP_SYMLINK)) != 0 || 1059 (r = sshbuf_put_u32(msg, id)) != 0 || 1060 (r = sshbuf_put_cstring(msg, oldpath)) != 0 || 1061 (r = sshbuf_put_cstring(msg, newpath)) != 0) 1062 fatal_fr(r, "compose"); 1063 send_msg(conn, msg); 1064 debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath, 1065 newpath); 1066 sshbuf_free(msg); 1067 1068 status = get_status(conn, id); 1069 if (status != SSH2_FX_OK) 1070 error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath, 1071 newpath, fx2txt(status)); 1072 1073 return status == SSH2_FX_OK ? 0 : -1; 1074 } 1075 1076 int 1077 do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len) 1078 { 1079 struct sshbuf *msg; 1080 u_int status, id; 1081 int r; 1082 1083 /* Silently return if the extension is not supported */ 1084 if ((conn->exts & SFTP_EXT_FSYNC) == 0) 1085 return -1; 1086 1087 /* Send fsync request */ 1088 if ((msg = sshbuf_new()) == NULL) 1089 fatal_f("sshbuf_new failed"); 1090 id = conn->msg_id++; 1091 if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || 1092 (r = sshbuf_put_u32(msg, id)) != 0 || 1093 (r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 || 1094 (r = sshbuf_put_string(msg, handle, handle_len)) != 0) 1095 fatal_fr(r, "compose"); 1096 send_msg(conn, msg); 1097 debug3("Sent message fsync@openssh.com I:%u", id); 1098 sshbuf_free(msg); 1099 1100 status = get_status(conn, id); 1101 if (status != SSH2_FX_OK) 1102 error("Couldn't sync file: %s", fx2txt(status)); 1103 1104 return status == SSH2_FX_OK ? 0 : -1; 1105 } 1106 1107 #ifdef notyet 1108 char * 1109 do_readlink(struct sftp_conn *conn, const char *path) 1110 { 1111 struct sshbuf *msg; 1112 u_int expected_id, count, id; 1113 char *filename, *longname; 1114 Attrib a; 1115 u_char type; 1116 int r; 1117 1118 expected_id = id = conn->msg_id++; 1119 send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path)); 1120 1121 if ((msg = sshbuf_new()) == NULL) 1122 fatal_f("sshbuf_new failed"); 1123 1124 get_msg(conn, msg); 1125 if ((r = sshbuf_get_u8(msg, &type)) != 0 || 1126 (r = sshbuf_get_u32(msg, &id)) != 0) 1127 fatal_fr(r, "parse"); 1128 1129 if (id != expected_id) 1130 fatal("ID mismatch (%u != %u)", id, expected_id); 1131 1132 if (type == SSH2_FXP_STATUS) { 1133 u_int status; 1134 1135 if ((r = sshbuf_get_u32(msg, &status)) != 0) 1136 fatal_fr(r, "parse status"); 1137 error("Couldn't readlink: %s", fx2txt(status)); 1138 sshbuf_free(msg); 1139 return(NULL); 1140 } else if (type != SSH2_FXP_NAME) 1141 fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", 1142 SSH2_FXP_NAME, type); 1143 1144 if ((r = sshbuf_get_u32(msg, &count)) != 0) 1145 fatal_fr(r, "parse count"); 1146 if (count != 1) 1147 fatal("Got multiple names (%d) from SSH_FXP_READLINK", count); 1148 1149 if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || 1150 (r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 || 1151 (r = decode_attrib(msg, &a)) != 0) 1152 fatal_fr(r, "parse filenames/attrib"); 1153 1154 debug3("SSH_FXP_READLINK %s -> %s", path, filename); 1155 1156 free(longname); 1157 1158 sshbuf_free(msg); 1159 1160 return filename; 1161 } 1162 #endif 1163 1164 int 1165 do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st, 1166 int quiet) 1167 { 1168 struct sshbuf *msg; 1169 u_int id; 1170 int r; 1171 1172 if ((conn->exts & SFTP_EXT_STATVFS) == 0) { 1173 error("Server does not support statvfs@openssh.com extension"); 1174 return -1; 1175 } 1176 1177 id = conn->msg_id++; 1178 1179 if ((msg = sshbuf_new()) == NULL) 1180 fatal_f("sshbuf_new failed"); 1181 if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || 1182 (r = sshbuf_put_u32(msg, id)) != 0 || 1183 (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 || 1184 (r = sshbuf_put_cstring(msg, path)) != 0) 1185 fatal_fr(r, "compose"); 1186 send_msg(conn, msg); 1187 sshbuf_free(msg); 1188 1189 return get_decode_statvfs(conn, st, id, quiet); 1190 } 1191 1192 #ifdef notyet 1193 int 1194 do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len, 1195 struct sftp_statvfs *st, int quiet) 1196 { 1197 struct sshbuf *msg; 1198 u_int id; 1199 1200 if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) { 1201 error("Server does not support fstatvfs@openssh.com extension"); 1202 return -1; 1203 } 1204 1205 id = conn->msg_id++; 1206 1207 if ((msg = sshbuf_new()) == NULL) 1208 fatal_f("sshbuf_new failed"); 1209 if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || 1210 (r = sshbuf_put_u32(msg, id)) != 0 || 1211 (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 || 1212 (r = sshbuf_put_string(msg, handle, handle_len)) != 0) 1213 fatal_fr(r, "compose"); 1214 send_msg(conn, msg); 1215 sshbuf_free(msg); 1216 1217 return get_decode_statvfs(conn, st, id, quiet); 1218 } 1219 #endif 1220 1221 int 1222 do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a) 1223 { 1224 struct sshbuf *msg; 1225 u_int status, id; 1226 int r; 1227 1228 if ((conn->exts & SFTP_EXT_LSETSTAT) == 0) { 1229 error("Server does not support lsetstat@openssh.com extension"); 1230 return -1; 1231 } 1232 1233 id = conn->msg_id++; 1234 if ((msg = sshbuf_new()) == NULL) 1235 fatal_f("sshbuf_new failed"); 1236 if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || 1237 (r = sshbuf_put_u32(msg, id)) != 0 || 1238 (r = sshbuf_put_cstring(msg, "lsetstat@openssh.com")) != 0 || 1239 (r = sshbuf_put_cstring(msg, path)) != 0 || 1240 (r = encode_attrib(msg, a)) != 0) 1241 fatal_fr(r, "compose"); 1242 send_msg(conn, msg); 1243 sshbuf_free(msg); 1244 1245 status = get_status(conn, id); 1246 if (status != SSH2_FX_OK) 1247 error("Couldn't setstat on \"%s\": %s", path, 1248 fx2txt(status)); 1249 1250 return status == SSH2_FX_OK ? 0 : -1; 1251 } 1252 1253 static void 1254 send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, 1255 u_int len, const u_char *handle, u_int handle_len) 1256 { 1257 struct sshbuf *msg; 1258 int r; 1259 1260 if ((msg = sshbuf_new()) == NULL) 1261 fatal_f("sshbuf_new failed"); 1262 if ((r = sshbuf_put_u8(msg, SSH2_FXP_READ)) != 0 || 1263 (r = sshbuf_put_u32(msg, id)) != 0 || 1264 (r = sshbuf_put_string(msg, handle, handle_len)) != 0 || 1265 (r = sshbuf_put_u64(msg, offset)) != 0 || 1266 (r = sshbuf_put_u32(msg, len)) != 0) 1267 fatal_fr(r, "compose"); 1268 send_msg(conn, msg); 1269 sshbuf_free(msg); 1270 } 1271 1272 int 1273 do_download(struct sftp_conn *conn, const char *remote_path, 1274 const char *local_path, Attrib *a, int preserve_flag, int resume_flag, 1275 int fsync_flag) 1276 { 1277 Attrib junk; 1278 struct sshbuf *msg; 1279 u_char *handle; 1280 int local_fd = -1, write_error; 1281 int read_error, write_errno, lmodified = 0, reordered = 0, r; 1282 u_int64_t offset = 0, size, highwater; 1283 u_int mode, id, buflen, num_req, max_req, status = SSH2_FX_OK; 1284 off_t progress_counter; 1285 size_t handle_len; 1286 struct stat st; 1287 struct request { 1288 u_int id; 1289 size_t len; 1290 u_int64_t offset; 1291 TAILQ_ENTRY(request) tq; 1292 }; 1293 TAILQ_HEAD(reqhead, request) requests; 1294 struct request *req; 1295 u_char type; 1296 1297 TAILQ_INIT(&requests); 1298 1299 if (a == NULL && (a = do_stat(conn, remote_path, 0)) == NULL) 1300 return -1; 1301 1302 /* Do not preserve set[ug]id here, as we do not preserve ownership */ 1303 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) 1304 mode = a->perm & 0777; 1305 else 1306 mode = 0666; 1307 1308 if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && 1309 (!S_ISREG(a->perm))) { 1310 error("Cannot download non-regular file: %s", remote_path); 1311 return(-1); 1312 } 1313 1314 if (a->flags & SSH2_FILEXFER_ATTR_SIZE) 1315 size = a->size; 1316 else 1317 size = 0; 1318 1319 buflen = conn->download_buflen; 1320 if ((msg = sshbuf_new()) == NULL) 1321 fatal_f("sshbuf_new failed"); 1322 1323 attrib_clear(&junk); /* Send empty attributes */ 1324 1325 /* Send open request */ 1326 id = conn->msg_id++; 1327 if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 || 1328 (r = sshbuf_put_u32(msg, id)) != 0 || 1329 (r = sshbuf_put_cstring(msg, remote_path)) != 0 || 1330 (r = sshbuf_put_u32(msg, SSH2_FXF_READ)) != 0 || 1331 (r = encode_attrib(msg, &junk)) != 0) 1332 fatal_fr(r, "compose"); 1333 send_msg(conn, msg); 1334 debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); 1335 1336 handle = get_handle(conn, id, &handle_len, 1337 "remote open(\"%s\")", remote_path); 1338 if (handle == NULL) { 1339 sshbuf_free(msg); 1340 return(-1); 1341 } 1342 1343 local_fd = open(local_path, 1344 O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR); 1345 if (local_fd == -1) { 1346 error("Couldn't open local file \"%s\" for writing: %s", 1347 local_path, strerror(errno)); 1348 goto fail; 1349 } 1350 offset = highwater = 0; 1351 if (resume_flag) { 1352 if (fstat(local_fd, &st) == -1) { 1353 error("Unable to stat local file \"%s\": %s", 1354 local_path, strerror(errno)); 1355 goto fail; 1356 } 1357 if (st.st_size < 0) { 1358 error("\"%s\" has negative size", local_path); 1359 goto fail; 1360 } 1361 if ((u_int64_t)st.st_size > size) { 1362 error("Unable to resume download of \"%s\": " 1363 "local file is larger than remote", local_path); 1364 fail: 1365 do_close(conn, handle, handle_len); 1366 sshbuf_free(msg); 1367 free(handle); 1368 if (local_fd != -1) 1369 close(local_fd); 1370 return -1; 1371 } 1372 offset = highwater = st.st_size; 1373 } 1374 1375 /* Read from remote and write to local */ 1376 write_error = read_error = write_errno = num_req = 0; 1377 max_req = 1; 1378 progress_counter = offset; 1379 1380 if (showprogress && size != 0) 1381 start_progress_meter(remote_path, size, &progress_counter); 1382 1383 while (num_req > 0 || max_req > 0) { 1384 u_char *data; 1385 size_t len; 1386 1387 /* 1388 * Simulate EOF on interrupt: stop sending new requests and 1389 * allow outstanding requests to drain gracefully 1390 */ 1391 if (interrupted) { 1392 if (num_req == 0) /* If we haven't started yet... */ 1393 break; 1394 max_req = 0; 1395 } 1396 1397 /* Send some more requests */ 1398 while (num_req < max_req) { 1399 debug3("Request range %llu -> %llu (%d/%d)", 1400 (unsigned long long)offset, 1401 (unsigned long long)offset + buflen - 1, 1402 num_req, max_req); 1403 req = xcalloc(1, sizeof(*req)); 1404 req->id = conn->msg_id++; 1405 req->len = buflen; 1406 req->offset = offset; 1407 offset += buflen; 1408 num_req++; 1409 TAILQ_INSERT_TAIL(&requests, req, tq); 1410 send_read_request(conn, req->id, req->offset, 1411 req->len, handle, handle_len); 1412 } 1413 1414 sshbuf_reset(msg); 1415 get_msg(conn, msg); 1416 if ((r = sshbuf_get_u8(msg, &type)) != 0 || 1417 (r = sshbuf_get_u32(msg, &id)) != 0) 1418 fatal_fr(r, "parse"); 1419 debug3("Received reply T:%u I:%u R:%d", type, id, max_req); 1420 1421 /* Find the request in our queue */ 1422 for (req = TAILQ_FIRST(&requests); 1423 req != NULL && req->id != id; 1424 req = TAILQ_NEXT(req, tq)) 1425 ; 1426 if (req == NULL) 1427 fatal("Unexpected reply %u", id); 1428 1429 switch (type) { 1430 case SSH2_FXP_STATUS: 1431 if ((r = sshbuf_get_u32(msg, &status)) != 0) 1432 fatal_fr(r, "parse status"); 1433 if (status != SSH2_FX_EOF) 1434 read_error = 1; 1435 max_req = 0; 1436 TAILQ_REMOVE(&requests, req, tq); 1437 free(req); 1438 num_req--; 1439 break; 1440 case SSH2_FXP_DATA: 1441 if ((r = sshbuf_get_string(msg, &data, &len)) != 0) 1442 fatal_fr(r, "parse data"); 1443 debug3("Received data %llu -> %llu", 1444 (unsigned long long)req->offset, 1445 (unsigned long long)req->offset + len - 1); 1446 if (len > req->len) 1447 fatal("Received more data than asked for " 1448 "%zu > %zu", len, req->len); 1449 lmodified = 1; 1450 if ((lseek(local_fd, req->offset, SEEK_SET) == -1 || 1451 atomicio(vwrite, local_fd, data, len) != len) && 1452 !write_error) { 1453 write_errno = errno; 1454 write_error = 1; 1455 max_req = 0; 1456 } 1457 else if (!reordered && req->offset <= highwater) 1458 highwater = req->offset + len; 1459 else if (!reordered && req->offset > highwater) 1460 reordered = 1; 1461 progress_counter += len; 1462 free(data); 1463 1464 if (len == req->len) { 1465 TAILQ_REMOVE(&requests, req, tq); 1466 free(req); 1467 num_req--; 1468 } else { 1469 /* Resend the request for the missing data */ 1470 debug3("Short data block, re-requesting " 1471 "%llu -> %llu (%2d)", 1472 (unsigned long long)req->offset + len, 1473 (unsigned long long)req->offset + 1474 req->len - 1, num_req); 1475 req->id = conn->msg_id++; 1476 req->len -= len; 1477 req->offset += len; 1478 send_read_request(conn, req->id, 1479 req->offset, req->len, handle, handle_len); 1480 /* Reduce the request size */ 1481 if (len < buflen) 1482 buflen = MAXIMUM(MIN_READ_SIZE, len); 1483 } 1484 if (max_req > 0) { /* max_req = 0 iff EOF received */ 1485 if (size > 0 && offset > size) { 1486 /* Only one request at a time 1487 * after the expected EOF */ 1488 debug3("Finish at %llu (%2d)", 1489 (unsigned long long)offset, 1490 num_req); 1491 max_req = 1; 1492 } else if (max_req < conn->num_requests) { 1493 ++max_req; 1494 } 1495 } 1496 break; 1497 default: 1498 fatal("Expected SSH2_FXP_DATA(%u) packet, got %u", 1499 SSH2_FXP_DATA, type); 1500 } 1501 } 1502 1503 if (showprogress && size) 1504 stop_progress_meter(); 1505 1506 /* Sanity check */ 1507 if (TAILQ_FIRST(&requests) != NULL) 1508 fatal("Transfer complete, but requests still in queue"); 1509 /* Truncate at highest contiguous point to avoid holes on interrupt */ 1510 if (read_error || write_error || interrupted) { 1511 if (reordered && resume_flag) { 1512 error("Unable to resume download of \"%s\": " 1513 "server reordered requests", local_path); 1514 } 1515 debug("truncating at %llu", (unsigned long long)highwater); 1516 if (ftruncate(local_fd, highwater) == -1) 1517 error("ftruncate \"%s\": %s", local_path, 1518 strerror(errno)); 1519 } 1520 if (read_error) { 1521 error("Couldn't read from remote file \"%s\" : %s", 1522 remote_path, fx2txt(status)); 1523 status = -1; 1524 do_close(conn, handle, handle_len); 1525 } else if (write_error) { 1526 error("Couldn't write to \"%s\": %s", local_path, 1527 strerror(write_errno)); 1528 status = SSH2_FX_FAILURE; 1529 do_close(conn, handle, handle_len); 1530 } else { 1531 if (do_close(conn, handle, handle_len) != 0 || interrupted) 1532 status = SSH2_FX_FAILURE; 1533 else 1534 status = SSH2_FX_OK; 1535 /* Override umask and utimes if asked */ 1536 if (preserve_flag && fchmod(local_fd, mode) == -1) 1537 error("Couldn't set mode on \"%s\": %s", local_path, 1538 strerror(errno)); 1539 if (preserve_flag && 1540 (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) { 1541 struct timeval tv[2]; 1542 tv[0].tv_sec = a->atime; 1543 tv[1].tv_sec = a->mtime; 1544 tv[0].tv_usec = tv[1].tv_usec = 0; 1545 if (utimes(local_path, tv) == -1) 1546 error("Can't set times on \"%s\": %s", 1547 local_path, strerror(errno)); 1548 } 1549 if (resume_flag && !lmodified) 1550 logit("File \"%s\" was not modified", local_path); 1551 else if (fsync_flag) { 1552 debug("syncing \"%s\"", local_path); 1553 if (fsync(local_fd) == -1) 1554 error("Couldn't sync file \"%s\": %s", 1555 local_path, strerror(errno)); 1556 } 1557 } 1558 close(local_fd); 1559 sshbuf_free(msg); 1560 free(handle); 1561 1562 return status == SSH2_FX_OK ? 0 : -1; 1563 } 1564 1565 static int 1566 download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, 1567 int depth, Attrib *dirattrib, int preserve_flag, int print_flag, 1568 int resume_flag, int fsync_flag) 1569 { 1570 int i, ret = 0; 1571 SFTP_DIRENT **dir_entries; 1572 char *filename, *new_src = NULL, *new_dst = NULL; 1573 mode_t mode = 0777, tmpmode = mode; 1574 1575 if (depth >= MAX_DIR_DEPTH) { 1576 error("Maximum directory depth exceeded: %d levels", depth); 1577 return -1; 1578 } 1579 1580 if (dirattrib == NULL && 1581 (dirattrib = do_stat(conn, src, 1)) == NULL) { 1582 error("Unable to stat remote directory \"%s\"", src); 1583 return -1; 1584 } 1585 if (!S_ISDIR(dirattrib->perm)) { 1586 error("\"%s\" is not a directory", src); 1587 return -1; 1588 } 1589 if (print_flag) 1590 mprintf("Retrieving %s\n", src); 1591 1592 if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { 1593 mode = dirattrib->perm & 01777; 1594 tmpmode = mode | (S_IWUSR|S_IXUSR); 1595 } else { 1596 debug("Server did not send permissions for " 1597 "directory \"%s\"", dst); 1598 } 1599 1600 if (mkdir(dst, tmpmode) == -1 && errno != EEXIST) { 1601 error("mkdir %s: %s", dst, strerror(errno)); 1602 return -1; 1603 } 1604 1605 if (do_readdir(conn, src, &dir_entries) == -1) { 1606 error("%s: Failed to get directory contents", src); 1607 return -1; 1608 } 1609 1610 for (i = 0; dir_entries[i] != NULL && !interrupted; i++) { 1611 free(new_dst); 1612 free(new_src); 1613 1614 filename = dir_entries[i]->filename; 1615 new_dst = path_append(dst, filename); 1616 new_src = path_append(src, filename); 1617 1618 if (S_ISDIR(dir_entries[i]->a.perm)) { 1619 if (strcmp(filename, ".") == 0 || 1620 strcmp(filename, "..") == 0) 1621 continue; 1622 if (download_dir_internal(conn, new_src, new_dst, 1623 depth + 1, &(dir_entries[i]->a), preserve_flag, 1624 print_flag, resume_flag, fsync_flag) == -1) 1625 ret = -1; 1626 } else if (S_ISREG(dir_entries[i]->a.perm) ) { 1627 if (do_download(conn, new_src, new_dst, 1628 &(dir_entries[i]->a), preserve_flag, 1629 resume_flag, fsync_flag) == -1) { 1630 error("Download of file %s to %s failed", 1631 new_src, new_dst); 1632 ret = -1; 1633 } 1634 } else 1635 logit("%s: not a regular file\n", new_src); 1636 1637 } 1638 free(new_dst); 1639 free(new_src); 1640 1641 if (preserve_flag) { 1642 if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 1643 struct timeval tv[2]; 1644 tv[0].tv_sec = dirattrib->atime; 1645 tv[1].tv_sec = dirattrib->mtime; 1646 tv[0].tv_usec = tv[1].tv_usec = 0; 1647 if (utimes(dst, tv) == -1) 1648 error("Can't set times on \"%s\": %s", 1649 dst, strerror(errno)); 1650 } else 1651 debug("Server did not send times for directory " 1652 "\"%s\"", dst); 1653 } 1654 1655 if (mode != tmpmode && chmod(dst, mode) == -1) 1656 error("Can't set final mode on \"%s\": %s", dst, 1657 strerror(errno)); 1658 1659 free_sftp_dirents(dir_entries); 1660 1661 return ret; 1662 } 1663 1664 int 1665 download_dir(struct sftp_conn *conn, const char *src, const char *dst, 1666 Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag, 1667 int fsync_flag) 1668 { 1669 char *src_canon; 1670 int ret; 1671 1672 if ((src_canon = do_realpath(conn, src)) == NULL) { 1673 error("Unable to canonicalize path \"%s\"", src); 1674 return -1; 1675 } 1676 1677 ret = download_dir_internal(conn, src_canon, dst, 0, 1678 dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag); 1679 free(src_canon); 1680 return ret; 1681 } 1682 1683 int 1684 do_upload(struct sftp_conn *conn, const char *local_path, 1685 const char *remote_path, int preserve_flag, int resume, int fsync_flag) 1686 { 1687 int r, local_fd; 1688 u_int status = SSH2_FX_OK; 1689 u_int id; 1690 u_char type; 1691 off_t offset, progress_counter; 1692 u_char *handle, *data; 1693 struct sshbuf *msg; 1694 struct stat sb; 1695 Attrib a, *c = NULL; 1696 u_int32_t startid; 1697 u_int32_t ackid; 1698 struct outstanding_ack { 1699 u_int id; 1700 u_int len; 1701 off_t offset; 1702 TAILQ_ENTRY(outstanding_ack) tq; 1703 }; 1704 TAILQ_HEAD(ackhead, outstanding_ack) acks; 1705 struct outstanding_ack *ack = NULL; 1706 size_t handle_len; 1707 1708 TAILQ_INIT(&acks); 1709 1710 if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) { 1711 error("Couldn't open local file \"%s\" for reading: %s", 1712 local_path, strerror(errno)); 1713 return(-1); 1714 } 1715 if (fstat(local_fd, &sb) == -1) { 1716 error("Couldn't fstat local file \"%s\": %s", 1717 local_path, strerror(errno)); 1718 close(local_fd); 1719 return(-1); 1720 } 1721 if (!S_ISREG(sb.st_mode)) { 1722 error("%s is not a regular file", local_path); 1723 close(local_fd); 1724 return(-1); 1725 } 1726 stat_to_attrib(&sb, &a); 1727 1728 a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; 1729 a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; 1730 a.perm &= 0777; 1731 if (!preserve_flag) 1732 a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; 1733 1734 if (resume) { 1735 /* Get remote file size if it exists */ 1736 if ((c = do_stat(conn, remote_path, 0)) == NULL) { 1737 close(local_fd); 1738 return -1; 1739 } 1740 1741 if ((off_t)c->size >= sb.st_size) { 1742 error("destination file bigger or same size as " 1743 "source file"); 1744 close(local_fd); 1745 return -1; 1746 } 1747 1748 if (lseek(local_fd, (off_t)c->size, SEEK_SET) == -1) { 1749 close(local_fd); 1750 return -1; 1751 } 1752 } 1753 1754 if ((msg = sshbuf_new()) == NULL) 1755 fatal_f("sshbuf_new failed"); 1756 1757 /* Send open request */ 1758 id = conn->msg_id++; 1759 if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 || 1760 (r = sshbuf_put_u32(msg, id)) != 0 || 1761 (r = sshbuf_put_cstring(msg, remote_path)) != 0 || 1762 (r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT| 1763 (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC))) != 0 || 1764 (r = encode_attrib(msg, &a)) != 0) 1765 fatal_fr(r, "compose"); 1766 send_msg(conn, msg); 1767 debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); 1768 1769 sshbuf_reset(msg); 1770 1771 handle = get_handle(conn, id, &handle_len, 1772 "remote open(\"%s\")", remote_path); 1773 if (handle == NULL) { 1774 close(local_fd); 1775 sshbuf_free(msg); 1776 return -1; 1777 } 1778 1779 startid = ackid = id + 1; 1780 data = xmalloc(conn->upload_buflen); 1781 1782 /* Read from local and write to remote */ 1783 offset = progress_counter = (resume ? c->size : 0); 1784 if (showprogress) 1785 start_progress_meter(local_path, sb.st_size, 1786 &progress_counter); 1787 1788 for (;;) { 1789 int len; 1790 1791 /* 1792 * Can't use atomicio here because it returns 0 on EOF, 1793 * thus losing the last block of the file. 1794 * Simulate an EOF on interrupt, allowing ACKs from the 1795 * server to drain. 1796 */ 1797 if (interrupted || status != SSH2_FX_OK) 1798 len = 0; 1799 else do 1800 len = read(local_fd, data, conn->upload_buflen); 1801 while ((len == -1) && (errno == EINTR || errno == EAGAIN)); 1802 1803 if (len == -1) 1804 fatal("Couldn't read from \"%s\": %s", local_path, 1805 strerror(errno)); 1806 1807 if (len != 0) { 1808 ack = xcalloc(1, sizeof(*ack)); 1809 ack->id = ++id; 1810 ack->offset = offset; 1811 ack->len = len; 1812 TAILQ_INSERT_TAIL(&acks, ack, tq); 1813 1814 sshbuf_reset(msg); 1815 if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 || 1816 (r = sshbuf_put_u32(msg, ack->id)) != 0 || 1817 (r = sshbuf_put_string(msg, handle, 1818 handle_len)) != 0 || 1819 (r = sshbuf_put_u64(msg, offset)) != 0 || 1820 (r = sshbuf_put_string(msg, data, len)) != 0) 1821 fatal_fr(r, "compose"); 1822 send_msg(conn, msg); 1823 debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u", 1824 id, (unsigned long long)offset, len); 1825 } else if (TAILQ_FIRST(&acks) == NULL) 1826 break; 1827 1828 if (ack == NULL) 1829 fatal("Unexpected ACK %u", id); 1830 1831 if (id == startid || len == 0 || 1832 id - ackid >= conn->num_requests) { 1833 u_int rid; 1834 1835 sshbuf_reset(msg); 1836 get_msg(conn, msg); 1837 if ((r = sshbuf_get_u8(msg, &type)) != 0 || 1838 (r = sshbuf_get_u32(msg, &rid)) != 0) 1839 fatal_fr(r, "parse"); 1840 1841 if (type != SSH2_FXP_STATUS) 1842 fatal("Expected SSH2_FXP_STATUS(%d) packet, " 1843 "got %d", SSH2_FXP_STATUS, type); 1844 1845 if ((r = sshbuf_get_u32(msg, &status)) != 0) 1846 fatal_fr(r, "parse status"); 1847 debug3("SSH2_FXP_STATUS %u", status); 1848 1849 /* Find the request in our queue */ 1850 for (ack = TAILQ_FIRST(&acks); 1851 ack != NULL && ack->id != rid; 1852 ack = TAILQ_NEXT(ack, tq)) 1853 ; 1854 if (ack == NULL) 1855 fatal("Can't find request for ID %u", rid); 1856 TAILQ_REMOVE(&acks, ack, tq); 1857 debug3("In write loop, ack for %u %u bytes at %lld", 1858 ack->id, ack->len, (long long)ack->offset); 1859 ++ackid; 1860 progress_counter += ack->len; 1861 free(ack); 1862 } 1863 offset += len; 1864 if (offset < 0) 1865 fatal_f("offset < 0"); 1866 } 1867 sshbuf_free(msg); 1868 1869 if (showprogress) 1870 stop_progress_meter(); 1871 free(data); 1872 1873 if (status != SSH2_FX_OK) { 1874 error("Couldn't write to remote file \"%s\": %s", 1875 remote_path, fx2txt(status)); 1876 status = SSH2_FX_FAILURE; 1877 } 1878 1879 if (close(local_fd) == -1) { 1880 error("Couldn't close local file \"%s\": %s", local_path, 1881 strerror(errno)); 1882 status = SSH2_FX_FAILURE; 1883 } 1884 1885 /* Override umask and utimes if asked */ 1886 if (preserve_flag) 1887 do_fsetstat(conn, handle, handle_len, &a); 1888 1889 if (fsync_flag) 1890 (void)do_fsync(conn, handle, handle_len); 1891 1892 if (do_close(conn, handle, handle_len) != 0) 1893 status = SSH2_FX_FAILURE; 1894 1895 free(handle); 1896 1897 return status == SSH2_FX_OK ? 0 : -1; 1898 } 1899 1900 static int 1901 upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, 1902 int depth, int preserve_flag, int print_flag, int resume, int fsync_flag) 1903 { 1904 int ret = 0; 1905 DIR *dirp; 1906 struct dirent *dp; 1907 char *filename, *new_src = NULL, *new_dst = NULL; 1908 struct stat sb; 1909 Attrib a, *dirattrib; 1910 u_int32_t saved_perm; 1911 1912 if (depth >= MAX_DIR_DEPTH) { 1913 error("Maximum directory depth exceeded: %d levels", depth); 1914 return -1; 1915 } 1916 1917 if (stat(src, &sb) == -1) { 1918 error("Couldn't stat directory \"%s\": %s", 1919 src, strerror(errno)); 1920 return -1; 1921 } 1922 if (!S_ISDIR(sb.st_mode)) { 1923 error("\"%s\" is not a directory", src); 1924 return -1; 1925 } 1926 if (print_flag) 1927 mprintf("Entering %s\n", src); 1928 1929 attrib_clear(&a); 1930 stat_to_attrib(&sb, &a); 1931 a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; 1932 a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; 1933 a.perm &= 01777; 1934 if (!preserve_flag) 1935 a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; 1936 1937 /* 1938 * sftp lacks a portable status value to match errno EEXIST, 1939 * so if we get a failure back then we must check whether 1940 * the path already existed and is a directory. Ensure we can 1941 * write to the directory we create for the duration of the transfer. 1942 */ 1943 saved_perm = a.perm; 1944 a.perm |= (S_IWUSR|S_IXUSR); 1945 if (do_mkdir(conn, dst, &a, 0) != 0) { 1946 if ((dirattrib = do_stat(conn, dst, 0)) == NULL) 1947 return -1; 1948 if (!S_ISDIR(dirattrib->perm)) { 1949 error("\"%s\" exists but is not a directory", dst); 1950 return -1; 1951 } 1952 } 1953 a.perm = saved_perm; 1954 1955 if ((dirp = opendir(src)) == NULL) { 1956 error("Failed to open dir \"%s\": %s", src, strerror(errno)); 1957 return -1; 1958 } 1959 1960 while (((dp = readdir(dirp)) != NULL) && !interrupted) { 1961 if (dp->d_ino == 0) 1962 continue; 1963 free(new_dst); 1964 free(new_src); 1965 filename = dp->d_name; 1966 new_dst = path_append(dst, filename); 1967 new_src = path_append(src, filename); 1968 1969 if (lstat(new_src, &sb) == -1) { 1970 logit("%s: lstat failed: %s", filename, 1971 strerror(errno)); 1972 ret = -1; 1973 } else if (S_ISDIR(sb.st_mode)) { 1974 if (strcmp(filename, ".") == 0 || 1975 strcmp(filename, "..") == 0) 1976 continue; 1977 1978 if (upload_dir_internal(conn, new_src, new_dst, 1979 depth + 1, preserve_flag, print_flag, resume, 1980 fsync_flag) == -1) 1981 ret = -1; 1982 } else if (S_ISREG(sb.st_mode)) { 1983 if (do_upload(conn, new_src, new_dst, 1984 preserve_flag, resume, fsync_flag) == -1) { 1985 error("Uploading of file %s to %s failed!", 1986 new_src, new_dst); 1987 ret = -1; 1988 } 1989 } else 1990 logit("%s: not a regular file\n", filename); 1991 } 1992 free(new_dst); 1993 free(new_src); 1994 1995 do_setstat(conn, dst, &a); 1996 1997 (void) closedir(dirp); 1998 return ret; 1999 } 2000 2001 int 2002 upload_dir(struct sftp_conn *conn, const char *src, const char *dst, 2003 int preserve_flag, int print_flag, int resume, int fsync_flag) 2004 { 2005 char *dst_canon; 2006 int ret; 2007 2008 if ((dst_canon = do_realpath(conn, dst)) == NULL) { 2009 error("Unable to canonicalize path \"%s\"", dst); 2010 return -1; 2011 } 2012 2013 ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag, 2014 print_flag, resume, fsync_flag); 2015 2016 free(dst_canon); 2017 return ret; 2018 } 2019 2020 char * 2021 path_append(const char *p1, const char *p2) 2022 { 2023 char *ret; 2024 size_t len = strlen(p1) + strlen(p2) + 2; 2025 2026 ret = xmalloc(len); 2027 strlcpy(ret, p1, len); 2028 if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/') 2029 strlcat(ret, "/", len); 2030 strlcat(ret, p2, len); 2031 2032 return(ret); 2033 } 2034 2035 char * 2036 make_absolute(char *p, const char *pwd) 2037 { 2038 char *abs_str; 2039 2040 /* Derelativise */ 2041 if (p && !path_absolute(p)) { 2042 abs_str = path_append(pwd, p); 2043 free(p); 2044 return(abs_str); 2045 } else 2046 return(p); 2047 } 2048 2049 int 2050 remote_is_dir(struct sftp_conn *conn, const char *path) 2051 { 2052 Attrib *a; 2053 2054 /* XXX: report errors? */ 2055 if ((a = do_stat(conn, path, 1)) == NULL) 2056 return(0); 2057 if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) 2058 return(0); 2059 return(S_ISDIR(a->perm)); 2060 } 2061 2062 2063 int 2064 local_is_dir(const char *path) 2065 { 2066 struct stat sb; 2067 2068 /* XXX: report errors? */ 2069 if (stat(path, &sb) == -1) 2070 return(0); 2071 2072 return(S_ISDIR(sb.st_mode)); 2073 } 2074 2075 /* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */ 2076 int 2077 globpath_is_dir(const char *pathname) 2078 { 2079 size_t l = strlen(pathname); 2080 2081 return l > 0 && pathname[l - 1] == '/'; 2082 } 2083 2084