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