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