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