1 /* $OpenBSD: sftp-server.c,v 1.119 2020/07/17 03:51:32 djm Exp $ */ 2 /* 3 * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. 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 #include <sys/types.h> 19 #include <sys/stat.h> 20 #include <sys/time.h> 21 #include <sys/mount.h> 22 #include <sys/statvfs.h> 23 24 #include <dirent.h> 25 #include <errno.h> 26 #include <fcntl.h> 27 #include <stdlib.h> 28 #include <stdio.h> 29 #include <string.h> 30 #include <pwd.h> 31 #include <time.h> 32 #include <unistd.h> 33 #include <stdarg.h> 34 35 #include "xmalloc.h" 36 #include "sshbuf.h" 37 #include "ssherr.h" 38 #include "log.h" 39 #include "misc.h" 40 #include "match.h" 41 #include "uidswap.h" 42 43 #include "sftp.h" 44 #include "sftp-common.h" 45 46 char *sftp_realpath(const char *, char *); /* sftp-realpath.c */ 47 48 /* Our verbosity */ 49 static LogLevel log_level = SYSLOG_LEVEL_ERROR; 50 51 /* Our client */ 52 static struct passwd *pw = NULL; 53 static char *client_addr = NULL; 54 55 /* input and output queue */ 56 struct sshbuf *iqueue; 57 struct sshbuf *oqueue; 58 59 /* Version of client */ 60 static u_int version; 61 62 /* SSH2_FXP_INIT received */ 63 static int init_done; 64 65 /* Disable writes */ 66 static int readonly; 67 68 /* Requests that are allowed/denied */ 69 static char *request_allowlist, *request_denylist; 70 71 /* portable attributes, etc. */ 72 typedef struct Stat Stat; 73 74 struct Stat { 75 char *name; 76 char *long_name; 77 Attrib attrib; 78 }; 79 80 /* Packet handlers */ 81 static void process_open(u_int32_t id); 82 static void process_close(u_int32_t id); 83 static void process_read(u_int32_t id); 84 static void process_write(u_int32_t id); 85 static void process_stat(u_int32_t id); 86 static void process_lstat(u_int32_t id); 87 static void process_fstat(u_int32_t id); 88 static void process_setstat(u_int32_t id); 89 static void process_fsetstat(u_int32_t id); 90 static void process_opendir(u_int32_t id); 91 static void process_readdir(u_int32_t id); 92 static void process_remove(u_int32_t id); 93 static void process_mkdir(u_int32_t id); 94 static void process_rmdir(u_int32_t id); 95 static void process_realpath(u_int32_t id); 96 static void process_rename(u_int32_t id); 97 static void process_readlink(u_int32_t id); 98 static void process_symlink(u_int32_t id); 99 static void process_extended_posix_rename(u_int32_t id); 100 static void process_extended_statvfs(u_int32_t id); 101 static void process_extended_fstatvfs(u_int32_t id); 102 static void process_extended_hardlink(u_int32_t id); 103 static void process_extended_fsync(u_int32_t id); 104 static void process_extended_lsetstat(u_int32_t id); 105 static void process_extended(u_int32_t id); 106 107 struct sftp_handler { 108 const char *name; /* user-visible name for fine-grained perms */ 109 const char *ext_name; /* extended request name */ 110 u_int type; /* packet type, for non extended packets */ 111 void (*handler)(u_int32_t); 112 int does_write; /* if nonzero, banned for readonly mode */ 113 }; 114 115 static const struct sftp_handler handlers[] = { 116 /* NB. SSH2_FXP_OPEN does the readonly check in the handler itself */ 117 { "open", NULL, SSH2_FXP_OPEN, process_open, 0 }, 118 { "close", NULL, SSH2_FXP_CLOSE, process_close, 0 }, 119 { "read", NULL, SSH2_FXP_READ, process_read, 0 }, 120 { "write", NULL, SSH2_FXP_WRITE, process_write, 1 }, 121 { "lstat", NULL, SSH2_FXP_LSTAT, process_lstat, 0 }, 122 { "fstat", NULL, SSH2_FXP_FSTAT, process_fstat, 0 }, 123 { "setstat", NULL, SSH2_FXP_SETSTAT, process_setstat, 1 }, 124 { "fsetstat", NULL, SSH2_FXP_FSETSTAT, process_fsetstat, 1 }, 125 { "opendir", NULL, SSH2_FXP_OPENDIR, process_opendir, 0 }, 126 { "readdir", NULL, SSH2_FXP_READDIR, process_readdir, 0 }, 127 { "remove", NULL, SSH2_FXP_REMOVE, process_remove, 1 }, 128 { "mkdir", NULL, SSH2_FXP_MKDIR, process_mkdir, 1 }, 129 { "rmdir", NULL, SSH2_FXP_RMDIR, process_rmdir, 1 }, 130 { "realpath", NULL, SSH2_FXP_REALPATH, process_realpath, 0 }, 131 { "stat", NULL, SSH2_FXP_STAT, process_stat, 0 }, 132 { "rename", NULL, SSH2_FXP_RENAME, process_rename, 1 }, 133 { "readlink", NULL, SSH2_FXP_READLINK, process_readlink, 0 }, 134 { "symlink", NULL, SSH2_FXP_SYMLINK, process_symlink, 1 }, 135 { NULL, NULL, 0, NULL, 0 } 136 }; 137 138 /* SSH2_FXP_EXTENDED submessages */ 139 static const struct sftp_handler extended_handlers[] = { 140 { "posix-rename", "posix-rename@openssh.com", 0, 141 process_extended_posix_rename, 1 }, 142 { "statvfs", "statvfs@openssh.com", 0, process_extended_statvfs, 0 }, 143 { "fstatvfs", "fstatvfs@openssh.com", 0, process_extended_fstatvfs, 0 }, 144 { "hardlink", "hardlink@openssh.com", 0, process_extended_hardlink, 1 }, 145 { "fsync", "fsync@openssh.com", 0, process_extended_fsync, 1 }, 146 { "lsetstat", "lsetstat@openssh.com", 0, process_extended_lsetstat, 1 }, 147 { NULL, NULL, 0, NULL, 0 } 148 }; 149 150 static int 151 request_permitted(const struct sftp_handler *h) 152 { 153 char *result; 154 155 if (readonly && h->does_write) { 156 verbose("Refusing %s request in read-only mode", h->name); 157 return 0; 158 } 159 if (request_denylist != NULL && 160 ((result = match_list(h->name, request_denylist, NULL))) != NULL) { 161 free(result); 162 verbose("Refusing denylisted %s request", h->name); 163 return 0; 164 } 165 if (request_allowlist != NULL && 166 ((result = match_list(h->name, request_allowlist, NULL))) != NULL) { 167 free(result); 168 debug2("Permitting allowlisted %s request", h->name); 169 return 1; 170 } 171 if (request_allowlist != NULL) { 172 verbose("Refusing non-allowlisted %s request", h->name); 173 return 0; 174 } 175 return 1; 176 } 177 178 static int 179 errno_to_portable(int unixerrno) 180 { 181 int ret = 0; 182 183 switch (unixerrno) { 184 case 0: 185 ret = SSH2_FX_OK; 186 break; 187 case ENOENT: 188 case ENOTDIR: 189 case EBADF: 190 case ELOOP: 191 ret = SSH2_FX_NO_SUCH_FILE; 192 break; 193 case EPERM: 194 case EACCES: 195 case EFAULT: 196 ret = SSH2_FX_PERMISSION_DENIED; 197 break; 198 case ENAMETOOLONG: 199 case EINVAL: 200 ret = SSH2_FX_BAD_MESSAGE; 201 break; 202 case ENOSYS: 203 ret = SSH2_FX_OP_UNSUPPORTED; 204 break; 205 default: 206 ret = SSH2_FX_FAILURE; 207 break; 208 } 209 return ret; 210 } 211 212 static int 213 flags_from_portable(int pflags) 214 { 215 int flags = 0; 216 217 if ((pflags & SSH2_FXF_READ) && 218 (pflags & SSH2_FXF_WRITE)) { 219 flags = O_RDWR; 220 } else if (pflags & SSH2_FXF_READ) { 221 flags = O_RDONLY; 222 } else if (pflags & SSH2_FXF_WRITE) { 223 flags = O_WRONLY; 224 } 225 if (pflags & SSH2_FXF_APPEND) 226 flags |= O_APPEND; 227 if (pflags & SSH2_FXF_CREAT) 228 flags |= O_CREAT; 229 if (pflags & SSH2_FXF_TRUNC) 230 flags |= O_TRUNC; 231 if (pflags & SSH2_FXF_EXCL) 232 flags |= O_EXCL; 233 return flags; 234 } 235 236 static const char * 237 string_from_portable(int pflags) 238 { 239 static char ret[128]; 240 241 *ret = '\0'; 242 243 #define PAPPEND(str) { \ 244 if (*ret != '\0') \ 245 strlcat(ret, ",", sizeof(ret)); \ 246 strlcat(ret, str, sizeof(ret)); \ 247 } 248 249 if (pflags & SSH2_FXF_READ) 250 PAPPEND("READ") 251 if (pflags & SSH2_FXF_WRITE) 252 PAPPEND("WRITE") 253 if (pflags & SSH2_FXF_APPEND) 254 PAPPEND("APPEND") 255 if (pflags & SSH2_FXF_CREAT) 256 PAPPEND("CREATE") 257 if (pflags & SSH2_FXF_TRUNC) 258 PAPPEND("TRUNCATE") 259 if (pflags & SSH2_FXF_EXCL) 260 PAPPEND("EXCL") 261 262 return ret; 263 } 264 265 /* handle handles */ 266 267 typedef struct Handle Handle; 268 struct Handle { 269 int use; 270 DIR *dirp; 271 int fd; 272 int flags; 273 char *name; 274 u_int64_t bytes_read, bytes_write; 275 int next_unused; 276 }; 277 278 enum { 279 HANDLE_UNUSED, 280 HANDLE_DIR, 281 HANDLE_FILE 282 }; 283 284 static Handle *handles = NULL; 285 static u_int num_handles = 0; 286 static int first_unused_handle = -1; 287 288 static void handle_unused(int i) 289 { 290 handles[i].use = HANDLE_UNUSED; 291 handles[i].next_unused = first_unused_handle; 292 first_unused_handle = i; 293 } 294 295 static int 296 handle_new(int use, const char *name, int fd, int flags, DIR *dirp) 297 { 298 int i; 299 300 if (first_unused_handle == -1) { 301 if (num_handles + 1 <= num_handles) 302 return -1; 303 num_handles++; 304 handles = xreallocarray(handles, num_handles, sizeof(Handle)); 305 handle_unused(num_handles - 1); 306 } 307 308 i = first_unused_handle; 309 first_unused_handle = handles[i].next_unused; 310 311 handles[i].use = use; 312 handles[i].dirp = dirp; 313 handles[i].fd = fd; 314 handles[i].flags = flags; 315 handles[i].name = xstrdup(name); 316 handles[i].bytes_read = handles[i].bytes_write = 0; 317 318 return i; 319 } 320 321 static int 322 handle_is_ok(int i, int type) 323 { 324 return i >= 0 && (u_int)i < num_handles && handles[i].use == type; 325 } 326 327 static int 328 handle_to_string(int handle, u_char **stringp, int *hlenp) 329 { 330 if (stringp == NULL || hlenp == NULL) 331 return -1; 332 *stringp = xmalloc(sizeof(int32_t)); 333 put_u32(*stringp, handle); 334 *hlenp = sizeof(int32_t); 335 return 0; 336 } 337 338 static int 339 handle_from_string(const u_char *handle, u_int hlen) 340 { 341 int val; 342 343 if (hlen != sizeof(int32_t)) 344 return -1; 345 val = get_u32(handle); 346 if (handle_is_ok(val, HANDLE_FILE) || 347 handle_is_ok(val, HANDLE_DIR)) 348 return val; 349 return -1; 350 } 351 352 static char * 353 handle_to_name(int handle) 354 { 355 if (handle_is_ok(handle, HANDLE_DIR)|| 356 handle_is_ok(handle, HANDLE_FILE)) 357 return handles[handle].name; 358 return NULL; 359 } 360 361 static DIR * 362 handle_to_dir(int handle) 363 { 364 if (handle_is_ok(handle, HANDLE_DIR)) 365 return handles[handle].dirp; 366 return NULL; 367 } 368 369 static int 370 handle_to_fd(int handle) 371 { 372 if (handle_is_ok(handle, HANDLE_FILE)) 373 return handles[handle].fd; 374 return -1; 375 } 376 377 static int 378 handle_to_flags(int handle) 379 { 380 if (handle_is_ok(handle, HANDLE_FILE)) 381 return handles[handle].flags; 382 return 0; 383 } 384 385 static void 386 handle_update_read(int handle, ssize_t bytes) 387 { 388 if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0) 389 handles[handle].bytes_read += bytes; 390 } 391 392 static void 393 handle_update_write(int handle, ssize_t bytes) 394 { 395 if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0) 396 handles[handle].bytes_write += bytes; 397 } 398 399 static u_int64_t 400 handle_bytes_read(int handle) 401 { 402 if (handle_is_ok(handle, HANDLE_FILE)) 403 return (handles[handle].bytes_read); 404 return 0; 405 } 406 407 static u_int64_t 408 handle_bytes_write(int handle) 409 { 410 if (handle_is_ok(handle, HANDLE_FILE)) 411 return (handles[handle].bytes_write); 412 return 0; 413 } 414 415 static int 416 handle_close(int handle) 417 { 418 int ret = -1; 419 420 if (handle_is_ok(handle, HANDLE_FILE)) { 421 ret = close(handles[handle].fd); 422 free(handles[handle].name); 423 handle_unused(handle); 424 } else if (handle_is_ok(handle, HANDLE_DIR)) { 425 ret = closedir(handles[handle].dirp); 426 free(handles[handle].name); 427 handle_unused(handle); 428 } else { 429 errno = ENOENT; 430 } 431 return ret; 432 } 433 434 static void 435 handle_log_close(int handle, char *emsg) 436 { 437 if (handle_is_ok(handle, HANDLE_FILE)) { 438 logit("%s%sclose \"%s\" bytes read %llu written %llu", 439 emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ", 440 handle_to_name(handle), 441 (unsigned long long)handle_bytes_read(handle), 442 (unsigned long long)handle_bytes_write(handle)); 443 } else { 444 logit("%s%sclosedir \"%s\"", 445 emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ", 446 handle_to_name(handle)); 447 } 448 } 449 450 static void 451 handle_log_exit(void) 452 { 453 u_int i; 454 455 for (i = 0; i < num_handles; i++) 456 if (handles[i].use != HANDLE_UNUSED) 457 handle_log_close(i, "forced"); 458 } 459 460 static int 461 get_handle(struct sshbuf *queue, int *hp) 462 { 463 u_char *handle; 464 int r; 465 size_t hlen; 466 467 *hp = -1; 468 if ((r = sshbuf_get_string(queue, &handle, &hlen)) != 0) 469 return r; 470 if (hlen < 256) 471 *hp = handle_from_string(handle, hlen); 472 free(handle); 473 return 0; 474 } 475 476 /* send replies */ 477 478 static void 479 send_msg(struct sshbuf *m) 480 { 481 int r; 482 483 if ((r = sshbuf_put_stringb(oqueue, m)) != 0) 484 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 485 sshbuf_reset(m); 486 } 487 488 static const char * 489 status_to_message(u_int32_t status) 490 { 491 const char *status_messages[] = { 492 "Success", /* SSH_FX_OK */ 493 "End of file", /* SSH_FX_EOF */ 494 "No such file", /* SSH_FX_NO_SUCH_FILE */ 495 "Permission denied", /* SSH_FX_PERMISSION_DENIED */ 496 "Failure", /* SSH_FX_FAILURE */ 497 "Bad message", /* SSH_FX_BAD_MESSAGE */ 498 "No connection", /* SSH_FX_NO_CONNECTION */ 499 "Connection lost", /* SSH_FX_CONNECTION_LOST */ 500 "Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */ 501 "Unknown error" /* Others */ 502 }; 503 return (status_messages[MINIMUM(status,SSH2_FX_MAX)]); 504 } 505 506 static void 507 send_status(u_int32_t id, u_int32_t status) 508 { 509 struct sshbuf *msg; 510 int r; 511 512 debug3("request %u: sent status %u", id, status); 513 if (log_level > SYSLOG_LEVEL_VERBOSE || 514 (status != SSH2_FX_OK && status != SSH2_FX_EOF)) 515 logit("sent status %s", status_to_message(status)); 516 if ((msg = sshbuf_new()) == NULL) 517 fatal("%s: sshbuf_new failed", __func__); 518 if ((r = sshbuf_put_u8(msg, SSH2_FXP_STATUS)) != 0 || 519 (r = sshbuf_put_u32(msg, id)) != 0 || 520 (r = sshbuf_put_u32(msg, status)) != 0) 521 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 522 if (version >= 3) { 523 if ((r = sshbuf_put_cstring(msg, 524 status_to_message(status))) != 0 || 525 (r = sshbuf_put_cstring(msg, "")) != 0) 526 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 527 } 528 send_msg(msg); 529 sshbuf_free(msg); 530 } 531 static void 532 send_data_or_handle(char type, u_int32_t id, const u_char *data, int dlen) 533 { 534 struct sshbuf *msg; 535 int r; 536 537 if ((msg = sshbuf_new()) == NULL) 538 fatal("%s: sshbuf_new failed", __func__); 539 if ((r = sshbuf_put_u8(msg, type)) != 0 || 540 (r = sshbuf_put_u32(msg, id)) != 0 || 541 (r = sshbuf_put_string(msg, data, dlen)) != 0) 542 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 543 send_msg(msg); 544 sshbuf_free(msg); 545 } 546 547 static void 548 send_data(u_int32_t id, const u_char *data, int dlen) 549 { 550 debug("request %u: sent data len %d", id, dlen); 551 send_data_or_handle(SSH2_FXP_DATA, id, data, dlen); 552 } 553 554 static void 555 send_handle(u_int32_t id, int handle) 556 { 557 u_char *string; 558 int hlen; 559 560 handle_to_string(handle, &string, &hlen); 561 debug("request %u: sent handle handle %d", id, handle); 562 send_data_or_handle(SSH2_FXP_HANDLE, id, string, hlen); 563 free(string); 564 } 565 566 static void 567 send_names(u_int32_t id, int count, const Stat *stats) 568 { 569 struct sshbuf *msg; 570 int i, r; 571 572 if ((msg = sshbuf_new()) == NULL) 573 fatal("%s: sshbuf_new failed", __func__); 574 if ((r = sshbuf_put_u8(msg, SSH2_FXP_NAME)) != 0 || 575 (r = sshbuf_put_u32(msg, id)) != 0 || 576 (r = sshbuf_put_u32(msg, count)) != 0) 577 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 578 debug("request %u: sent names count %d", id, count); 579 for (i = 0; i < count; i++) { 580 if ((r = sshbuf_put_cstring(msg, stats[i].name)) != 0 || 581 (r = sshbuf_put_cstring(msg, stats[i].long_name)) != 0 || 582 (r = encode_attrib(msg, &stats[i].attrib)) != 0) 583 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 584 } 585 send_msg(msg); 586 sshbuf_free(msg); 587 } 588 589 static void 590 send_attrib(u_int32_t id, const Attrib *a) 591 { 592 struct sshbuf *msg; 593 int r; 594 595 debug("request %u: sent attrib have 0x%x", id, a->flags); 596 if ((msg = sshbuf_new()) == NULL) 597 fatal("%s: sshbuf_new failed", __func__); 598 if ((r = sshbuf_put_u8(msg, SSH2_FXP_ATTRS)) != 0 || 599 (r = sshbuf_put_u32(msg, id)) != 0 || 600 (r = encode_attrib(msg, a)) != 0) 601 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 602 send_msg(msg); 603 sshbuf_free(msg); 604 } 605 606 static void 607 send_statvfs(u_int32_t id, struct statvfs *st) 608 { 609 struct sshbuf *msg; 610 u_int64_t flag; 611 int r; 612 613 flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0; 614 flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0; 615 616 if ((msg = sshbuf_new()) == NULL) 617 fatal("%s: sshbuf_new failed", __func__); 618 if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED_REPLY)) != 0 || 619 (r = sshbuf_put_u32(msg, id)) != 0 || 620 (r = sshbuf_put_u64(msg, st->f_bsize)) != 0 || 621 (r = sshbuf_put_u64(msg, st->f_frsize)) != 0 || 622 (r = sshbuf_put_u64(msg, st->f_blocks)) != 0 || 623 (r = sshbuf_put_u64(msg, st->f_bfree)) != 0 || 624 (r = sshbuf_put_u64(msg, st->f_bavail)) != 0 || 625 (r = sshbuf_put_u64(msg, st->f_files)) != 0 || 626 (r = sshbuf_put_u64(msg, st->f_ffree)) != 0 || 627 (r = sshbuf_put_u64(msg, st->f_favail)) != 0 || 628 (r = sshbuf_put_u64(msg, st->f_fsid)) != 0 || 629 (r = sshbuf_put_u64(msg, flag)) != 0 || 630 (r = sshbuf_put_u64(msg, st->f_namemax)) != 0) 631 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 632 send_msg(msg); 633 sshbuf_free(msg); 634 } 635 636 /* parse incoming */ 637 638 static void 639 process_init(void) 640 { 641 struct sshbuf *msg; 642 int r; 643 644 if ((r = sshbuf_get_u32(iqueue, &version)) != 0) 645 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 646 verbose("received client version %u", version); 647 if ((msg = sshbuf_new()) == NULL) 648 fatal("%s: sshbuf_new failed", __func__); 649 if ((r = sshbuf_put_u8(msg, SSH2_FXP_VERSION)) != 0 || 650 (r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0 || 651 /* POSIX rename extension */ 652 (r = sshbuf_put_cstring(msg, "posix-rename@openssh.com")) != 0 || 653 (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */ 654 /* statvfs extension */ 655 (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 || 656 (r = sshbuf_put_cstring(msg, "2")) != 0 || /* version */ 657 /* fstatvfs extension */ 658 (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 || 659 (r = sshbuf_put_cstring(msg, "2")) != 0 || /* version */ 660 /* hardlink extension */ 661 (r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 || 662 (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */ 663 /* fsync extension */ 664 (r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 || 665 (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */ 666 (r = sshbuf_put_cstring(msg, "lsetstat@openssh.com")) != 0 || 667 (r = sshbuf_put_cstring(msg, "1")) != 0) /* version */ 668 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 669 send_msg(msg); 670 sshbuf_free(msg); 671 } 672 673 static void 674 process_open(u_int32_t id) 675 { 676 u_int32_t pflags; 677 Attrib a; 678 char *name; 679 int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; 680 681 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || 682 (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ 683 (r = decode_attrib(iqueue, &a)) != 0) 684 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 685 686 debug3("request %u: open flags %d", id, pflags); 687 flags = flags_from_portable(pflags); 688 mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666; 689 logit("open \"%s\" flags %s mode 0%o", 690 name, string_from_portable(pflags), mode); 691 if (readonly && 692 ((flags & O_ACCMODE) != O_RDONLY || 693 (flags & (O_CREAT|O_TRUNC)) != 0)) { 694 verbose("Refusing open request in read-only mode"); 695 status = SSH2_FX_PERMISSION_DENIED; 696 } else { 697 fd = open(name, flags, mode); 698 if (fd == -1) { 699 status = errno_to_portable(errno); 700 } else { 701 handle = handle_new(HANDLE_FILE, name, fd, flags, NULL); 702 if (handle < 0) { 703 close(fd); 704 } else { 705 send_handle(id, handle); 706 status = SSH2_FX_OK; 707 } 708 } 709 } 710 if (status != SSH2_FX_OK) 711 send_status(id, status); 712 free(name); 713 } 714 715 static void 716 process_close(u_int32_t id) 717 { 718 int r, handle, ret, status = SSH2_FX_FAILURE; 719 720 if ((r = get_handle(iqueue, &handle)) != 0) 721 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 722 723 debug3("request %u: close handle %u", id, handle); 724 handle_log_close(handle, NULL); 725 ret = handle_close(handle); 726 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; 727 send_status(id, status); 728 } 729 730 static void 731 process_read(u_int32_t id) 732 { 733 u_char buf[64*1024]; 734 u_int32_t len; 735 int r, handle, fd, ret, status = SSH2_FX_FAILURE; 736 u_int64_t off; 737 738 if ((r = get_handle(iqueue, &handle)) != 0 || 739 (r = sshbuf_get_u64(iqueue, &off)) != 0 || 740 (r = sshbuf_get_u32(iqueue, &len)) != 0) 741 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 742 743 debug("request %u: read \"%s\" (handle %d) off %llu len %d", 744 id, handle_to_name(handle), handle, (unsigned long long)off, len); 745 if (len > sizeof buf) { 746 len = sizeof buf; 747 debug2("read change len %d", len); 748 } 749 fd = handle_to_fd(handle); 750 if (fd >= 0) { 751 if (lseek(fd, off, SEEK_SET) == -1) { 752 error("process_read: seek failed"); 753 status = errno_to_portable(errno); 754 } else { 755 ret = read(fd, buf, len); 756 if (ret == -1) { 757 status = errno_to_portable(errno); 758 } else if (ret == 0) { 759 status = SSH2_FX_EOF; 760 } else { 761 send_data(id, buf, ret); 762 status = SSH2_FX_OK; 763 handle_update_read(handle, ret); 764 } 765 } 766 } 767 if (status != SSH2_FX_OK) 768 send_status(id, status); 769 } 770 771 static void 772 process_write(u_int32_t id) 773 { 774 u_int64_t off; 775 size_t len; 776 int r, handle, fd, ret, status; 777 u_char *data; 778 779 if ((r = get_handle(iqueue, &handle)) != 0 || 780 (r = sshbuf_get_u64(iqueue, &off)) != 0 || 781 (r = sshbuf_get_string(iqueue, &data, &len)) != 0) 782 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 783 784 debug("request %u: write \"%s\" (handle %d) off %llu len %zu", 785 id, handle_to_name(handle), handle, (unsigned long long)off, len); 786 fd = handle_to_fd(handle); 787 788 if (fd < 0) 789 status = SSH2_FX_FAILURE; 790 else { 791 if (!(handle_to_flags(handle) & O_APPEND) && 792 lseek(fd, off, SEEK_SET) == -1) { 793 status = errno_to_portable(errno); 794 error("%s: seek failed", __func__); 795 } else { 796 /* XXX ATOMICIO ? */ 797 ret = write(fd, data, len); 798 if (ret == -1) { 799 error("%s: write: %s", __func__, 800 strerror(errno)); 801 status = errno_to_portable(errno); 802 } else if ((size_t)ret == len) { 803 status = SSH2_FX_OK; 804 handle_update_write(handle, ret); 805 } else { 806 debug2("%s: nothing at all written", __func__); 807 status = SSH2_FX_FAILURE; 808 } 809 } 810 } 811 send_status(id, status); 812 free(data); 813 } 814 815 static void 816 process_do_stat(u_int32_t id, int do_lstat) 817 { 818 Attrib a; 819 struct stat st; 820 char *name; 821 int r, status = SSH2_FX_FAILURE; 822 823 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) 824 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 825 826 debug3("request %u: %sstat", id, do_lstat ? "l" : ""); 827 verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name); 828 r = do_lstat ? lstat(name, &st) : stat(name, &st); 829 if (r == -1) { 830 status = errno_to_portable(errno); 831 } else { 832 stat_to_attrib(&st, &a); 833 send_attrib(id, &a); 834 status = SSH2_FX_OK; 835 } 836 if (status != SSH2_FX_OK) 837 send_status(id, status); 838 free(name); 839 } 840 841 static void 842 process_stat(u_int32_t id) 843 { 844 process_do_stat(id, 0); 845 } 846 847 static void 848 process_lstat(u_int32_t id) 849 { 850 process_do_stat(id, 1); 851 } 852 853 static void 854 process_fstat(u_int32_t id) 855 { 856 Attrib a; 857 struct stat st; 858 int fd, r, handle, status = SSH2_FX_FAILURE; 859 860 if ((r = get_handle(iqueue, &handle)) != 0) 861 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 862 debug("request %u: fstat \"%s\" (handle %u)", 863 id, handle_to_name(handle), handle); 864 fd = handle_to_fd(handle); 865 if (fd >= 0) { 866 r = fstat(fd, &st); 867 if (r == -1) { 868 status = errno_to_portable(errno); 869 } else { 870 stat_to_attrib(&st, &a); 871 send_attrib(id, &a); 872 status = SSH2_FX_OK; 873 } 874 } 875 if (status != SSH2_FX_OK) 876 send_status(id, status); 877 } 878 879 static struct timeval * 880 attrib_to_tv(const Attrib *a) 881 { 882 static struct timeval tv[2]; 883 884 tv[0].tv_sec = a->atime; 885 tv[0].tv_usec = 0; 886 tv[1].tv_sec = a->mtime; 887 tv[1].tv_usec = 0; 888 return tv; 889 } 890 891 static struct timespec * 892 attrib_to_ts(const Attrib *a) 893 { 894 static struct timespec ts[2]; 895 896 ts[0].tv_sec = a->atime; 897 ts[0].tv_nsec = 0; 898 ts[1].tv_sec = a->mtime; 899 ts[1].tv_nsec = 0; 900 return ts; 901 } 902 903 static void 904 process_setstat(u_int32_t id) 905 { 906 Attrib a; 907 char *name; 908 int r, status = SSH2_FX_OK; 909 910 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || 911 (r = decode_attrib(iqueue, &a)) != 0) 912 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 913 914 debug("request %u: setstat name \"%s\"", id, name); 915 if (a.flags & SSH2_FILEXFER_ATTR_SIZE) { 916 logit("set \"%s\" size %llu", 917 name, (unsigned long long)a.size); 918 r = truncate(name, a.size); 919 if (r == -1) 920 status = errno_to_portable(errno); 921 } 922 if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { 923 logit("set \"%s\" mode %04o", name, a.perm); 924 r = chmod(name, a.perm & 07777); 925 if (r == -1) 926 status = errno_to_portable(errno); 927 } 928 if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 929 char buf[64]; 930 time_t t = a.mtime; 931 932 strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S", 933 localtime(&t)); 934 logit("set \"%s\" modtime %s", name, buf); 935 r = utimes(name, attrib_to_tv(&a)); 936 if (r == -1) 937 status = errno_to_portable(errno); 938 } 939 if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { 940 logit("set \"%s\" owner %lu group %lu", name, 941 (u_long)a.uid, (u_long)a.gid); 942 r = chown(name, a.uid, a.gid); 943 if (r == -1) 944 status = errno_to_portable(errno); 945 } 946 send_status(id, status); 947 free(name); 948 } 949 950 static void 951 process_fsetstat(u_int32_t id) 952 { 953 Attrib a; 954 int handle, fd, r; 955 int status = SSH2_FX_OK; 956 957 if ((r = get_handle(iqueue, &handle)) != 0 || 958 (r = decode_attrib(iqueue, &a)) != 0) 959 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 960 961 debug("request %u: fsetstat handle %d", id, handle); 962 fd = handle_to_fd(handle); 963 if (fd < 0) 964 status = SSH2_FX_FAILURE; 965 else { 966 char *name = handle_to_name(handle); 967 968 if (a.flags & SSH2_FILEXFER_ATTR_SIZE) { 969 logit("set \"%s\" size %llu", 970 name, (unsigned long long)a.size); 971 r = ftruncate(fd, a.size); 972 if (r == -1) 973 status = errno_to_portable(errno); 974 } 975 if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { 976 logit("set \"%s\" mode %04o", name, a.perm); 977 r = fchmod(fd, a.perm & 07777); 978 if (r == -1) 979 status = errno_to_portable(errno); 980 } 981 if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 982 char buf[64]; 983 time_t t = a.mtime; 984 985 strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S", 986 localtime(&t)); 987 logit("set \"%s\" modtime %s", name, buf); 988 r = futimes(fd, attrib_to_tv(&a)); 989 if (r == -1) 990 status = errno_to_portable(errno); 991 } 992 if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { 993 logit("set \"%s\" owner %lu group %lu", name, 994 (u_long)a.uid, (u_long)a.gid); 995 r = fchown(fd, a.uid, a.gid); 996 if (r == -1) 997 status = errno_to_portable(errno); 998 } 999 } 1000 send_status(id, status); 1001 } 1002 1003 static void 1004 process_opendir(u_int32_t id) 1005 { 1006 DIR *dirp = NULL; 1007 char *path; 1008 int r, handle, status = SSH2_FX_FAILURE; 1009 1010 if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) 1011 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1012 1013 debug3("request %u: opendir", id); 1014 logit("opendir \"%s\"", path); 1015 dirp = opendir(path); 1016 if (dirp == NULL) { 1017 status = errno_to_portable(errno); 1018 } else { 1019 handle = handle_new(HANDLE_DIR, path, 0, 0, dirp); 1020 if (handle < 0) { 1021 closedir(dirp); 1022 } else { 1023 send_handle(id, handle); 1024 status = SSH2_FX_OK; 1025 } 1026 1027 } 1028 if (status != SSH2_FX_OK) 1029 send_status(id, status); 1030 free(path); 1031 } 1032 1033 static void 1034 process_readdir(u_int32_t id) 1035 { 1036 DIR *dirp; 1037 struct dirent *dp; 1038 char *path; 1039 int r, handle; 1040 1041 if ((r = get_handle(iqueue, &handle)) != 0) 1042 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1043 1044 debug("request %u: readdir \"%s\" (handle %d)", id, 1045 handle_to_name(handle), handle); 1046 dirp = handle_to_dir(handle); 1047 path = handle_to_name(handle); 1048 if (dirp == NULL || path == NULL) { 1049 send_status(id, SSH2_FX_FAILURE); 1050 } else { 1051 struct stat st; 1052 char pathname[PATH_MAX]; 1053 Stat *stats; 1054 int nstats = 10, count = 0, i; 1055 1056 stats = xcalloc(nstats, sizeof(Stat)); 1057 while ((dp = readdir(dirp)) != NULL) { 1058 if (count >= nstats) { 1059 nstats *= 2; 1060 stats = xreallocarray(stats, nstats, sizeof(Stat)); 1061 } 1062 /* XXX OVERFLOW ? */ 1063 snprintf(pathname, sizeof pathname, "%s%s%s", path, 1064 strcmp(path, "/") ? "/" : "", dp->d_name); 1065 if (lstat(pathname, &st) == -1) 1066 continue; 1067 stat_to_attrib(&st, &(stats[count].attrib)); 1068 stats[count].name = xstrdup(dp->d_name); 1069 stats[count].long_name = ls_file(dp->d_name, &st, 0, 0); 1070 count++; 1071 /* send up to 100 entries in one message */ 1072 /* XXX check packet size instead */ 1073 if (count == 100) 1074 break; 1075 } 1076 if (count > 0) { 1077 send_names(id, count, stats); 1078 for (i = 0; i < count; i++) { 1079 free(stats[i].name); 1080 free(stats[i].long_name); 1081 } 1082 } else { 1083 send_status(id, SSH2_FX_EOF); 1084 } 1085 free(stats); 1086 } 1087 } 1088 1089 static void 1090 process_remove(u_int32_t id) 1091 { 1092 char *name; 1093 int r, status = SSH2_FX_FAILURE; 1094 1095 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) 1096 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1097 1098 debug3("request %u: remove", id); 1099 logit("remove name \"%s\"", name); 1100 r = unlink(name); 1101 status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; 1102 send_status(id, status); 1103 free(name); 1104 } 1105 1106 static void 1107 process_mkdir(u_int32_t id) 1108 { 1109 Attrib a; 1110 char *name; 1111 int r, mode, status = SSH2_FX_FAILURE; 1112 1113 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || 1114 (r = decode_attrib(iqueue, &a)) != 0) 1115 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1116 1117 mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? 1118 a.perm & 07777 : 0777; 1119 debug3("request %u: mkdir", id); 1120 logit("mkdir name \"%s\" mode 0%o", name, mode); 1121 r = mkdir(name, mode); 1122 status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; 1123 send_status(id, status); 1124 free(name); 1125 } 1126 1127 static void 1128 process_rmdir(u_int32_t id) 1129 { 1130 char *name; 1131 int r, status; 1132 1133 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) 1134 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1135 1136 debug3("request %u: rmdir", id); 1137 logit("rmdir name \"%s\"", name); 1138 r = rmdir(name); 1139 status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; 1140 send_status(id, status); 1141 free(name); 1142 } 1143 1144 static void 1145 process_realpath(u_int32_t id) 1146 { 1147 char resolvedname[PATH_MAX]; 1148 char *path; 1149 int r; 1150 1151 if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) 1152 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1153 1154 if (path[0] == '\0') { 1155 free(path); 1156 path = xstrdup("."); 1157 } 1158 debug3("request %u: realpath", id); 1159 verbose("realpath \"%s\"", path); 1160 if (sftp_realpath(path, resolvedname) == NULL) { 1161 send_status(id, errno_to_portable(errno)); 1162 } else { 1163 Stat s; 1164 attrib_clear(&s.attrib); 1165 s.name = s.long_name = resolvedname; 1166 send_names(id, 1, &s); 1167 } 1168 free(path); 1169 } 1170 1171 static void 1172 process_rename(u_int32_t id) 1173 { 1174 char *oldpath, *newpath; 1175 int r, status; 1176 struct stat sb; 1177 1178 if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || 1179 (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) 1180 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1181 1182 debug3("request %u: rename", id); 1183 logit("rename old \"%s\" new \"%s\"", oldpath, newpath); 1184 status = SSH2_FX_FAILURE; 1185 if (lstat(oldpath, &sb) == -1) 1186 status = errno_to_portable(errno); 1187 else if (S_ISREG(sb.st_mode)) { 1188 /* Race-free rename of regular files */ 1189 if (link(oldpath, newpath) == -1) { 1190 if (errno == EOPNOTSUPP) { 1191 struct stat st; 1192 1193 /* 1194 * fs doesn't support links, so fall back to 1195 * stat+rename. This is racy. 1196 */ 1197 if (stat(newpath, &st) == -1) { 1198 if (rename(oldpath, newpath) == -1) 1199 status = 1200 errno_to_portable(errno); 1201 else 1202 status = SSH2_FX_OK; 1203 } 1204 } else { 1205 status = errno_to_portable(errno); 1206 } 1207 } else if (unlink(oldpath) == -1) { 1208 status = errno_to_portable(errno); 1209 /* clean spare link */ 1210 unlink(newpath); 1211 } else 1212 status = SSH2_FX_OK; 1213 } else if (stat(newpath, &sb) == -1) { 1214 if (rename(oldpath, newpath) == -1) 1215 status = errno_to_portable(errno); 1216 else 1217 status = SSH2_FX_OK; 1218 } 1219 send_status(id, status); 1220 free(oldpath); 1221 free(newpath); 1222 } 1223 1224 static void 1225 process_readlink(u_int32_t id) 1226 { 1227 int r, len; 1228 char buf[PATH_MAX]; 1229 char *path; 1230 1231 if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) 1232 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1233 1234 debug3("request %u: readlink", id); 1235 verbose("readlink \"%s\"", path); 1236 if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1) 1237 send_status(id, errno_to_portable(errno)); 1238 else { 1239 Stat s; 1240 1241 buf[len] = '\0'; 1242 attrib_clear(&s.attrib); 1243 s.name = s.long_name = buf; 1244 send_names(id, 1, &s); 1245 } 1246 free(path); 1247 } 1248 1249 static void 1250 process_symlink(u_int32_t id) 1251 { 1252 char *oldpath, *newpath; 1253 int r, status; 1254 1255 if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || 1256 (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) 1257 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1258 1259 debug3("request %u: symlink", id); 1260 logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); 1261 /* this will fail if 'newpath' exists */ 1262 r = symlink(oldpath, newpath); 1263 status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; 1264 send_status(id, status); 1265 free(oldpath); 1266 free(newpath); 1267 } 1268 1269 static void 1270 process_extended_posix_rename(u_int32_t id) 1271 { 1272 char *oldpath, *newpath; 1273 int r, status; 1274 1275 if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || 1276 (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) 1277 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1278 1279 debug3("request %u: posix-rename", id); 1280 logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); 1281 r = rename(oldpath, newpath); 1282 status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; 1283 send_status(id, status); 1284 free(oldpath); 1285 free(newpath); 1286 } 1287 1288 static void 1289 process_extended_statvfs(u_int32_t id) 1290 { 1291 char *path; 1292 struct statvfs st; 1293 int r; 1294 1295 if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) 1296 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1297 debug3("request %u: statvfs", id); 1298 logit("statvfs \"%s\"", path); 1299 1300 if (statvfs(path, &st) != 0) 1301 send_status(id, errno_to_portable(errno)); 1302 else 1303 send_statvfs(id, &st); 1304 free(path); 1305 } 1306 1307 static void 1308 process_extended_fstatvfs(u_int32_t id) 1309 { 1310 int r, handle, fd; 1311 struct statvfs st; 1312 1313 if ((r = get_handle(iqueue, &handle)) != 0) 1314 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1315 debug("request %u: fstatvfs \"%s\" (handle %u)", 1316 id, handle_to_name(handle), handle); 1317 if ((fd = handle_to_fd(handle)) < 0) { 1318 send_status(id, SSH2_FX_FAILURE); 1319 return; 1320 } 1321 if (fstatvfs(fd, &st) != 0) 1322 send_status(id, errno_to_portable(errno)); 1323 else 1324 send_statvfs(id, &st); 1325 } 1326 1327 static void 1328 process_extended_hardlink(u_int32_t id) 1329 { 1330 char *oldpath, *newpath; 1331 int r, status; 1332 1333 if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || 1334 (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) 1335 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1336 1337 debug3("request %u: hardlink", id); 1338 logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath); 1339 r = link(oldpath, newpath); 1340 status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; 1341 send_status(id, status); 1342 free(oldpath); 1343 free(newpath); 1344 } 1345 1346 static void 1347 process_extended_fsync(u_int32_t id) 1348 { 1349 int handle, fd, r, status = SSH2_FX_OP_UNSUPPORTED; 1350 1351 if ((r = get_handle(iqueue, &handle)) != 0) 1352 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1353 debug3("request %u: fsync (handle %u)", id, handle); 1354 verbose("fsync \"%s\"", handle_to_name(handle)); 1355 if ((fd = handle_to_fd(handle)) < 0) 1356 status = SSH2_FX_NO_SUCH_FILE; 1357 else if (handle_is_ok(handle, HANDLE_FILE)) { 1358 r = fsync(fd); 1359 status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; 1360 } 1361 send_status(id, status); 1362 } 1363 1364 static void 1365 process_extended_lsetstat(u_int32_t id) 1366 { 1367 Attrib a; 1368 char *name; 1369 int r, status = SSH2_FX_OK; 1370 1371 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || 1372 (r = decode_attrib(iqueue, &a)) != 0) 1373 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1374 1375 debug("request %u: lsetstat name \"%s\"", id, name); 1376 if (a.flags & SSH2_FILEXFER_ATTR_SIZE) { 1377 /* nonsensical for links */ 1378 status = SSH2_FX_BAD_MESSAGE; 1379 goto out; 1380 } 1381 if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { 1382 logit("set \"%s\" mode %04o", name, a.perm); 1383 r = fchmodat(AT_FDCWD, name, 1384 a.perm & 07777, AT_SYMLINK_NOFOLLOW); 1385 if (r == -1) 1386 status = errno_to_portable(errno); 1387 } 1388 if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 1389 char buf[64]; 1390 time_t t = a.mtime; 1391 1392 strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S", 1393 localtime(&t)); 1394 logit("set \"%s\" modtime %s", name, buf); 1395 r = utimensat(AT_FDCWD, name, 1396 attrib_to_ts(&a), AT_SYMLINK_NOFOLLOW); 1397 if (r == -1) 1398 status = errno_to_portable(errno); 1399 } 1400 if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { 1401 logit("set \"%s\" owner %lu group %lu", name, 1402 (u_long)a.uid, (u_long)a.gid); 1403 r = fchownat(AT_FDCWD, name, a.uid, a.gid, 1404 AT_SYMLINK_NOFOLLOW); 1405 if (r == -1) 1406 status = errno_to_portable(errno); 1407 } 1408 out: 1409 send_status(id, status); 1410 free(name); 1411 } 1412 1413 static void 1414 process_extended(u_int32_t id) 1415 { 1416 char *request; 1417 int i, r; 1418 1419 if ((r = sshbuf_get_cstring(iqueue, &request, NULL)) != 0) 1420 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1421 for (i = 0; extended_handlers[i].handler != NULL; i++) { 1422 if (strcmp(request, extended_handlers[i].ext_name) == 0) { 1423 if (!request_permitted(&extended_handlers[i])) 1424 send_status(id, SSH2_FX_PERMISSION_DENIED); 1425 else 1426 extended_handlers[i].handler(id); 1427 break; 1428 } 1429 } 1430 if (extended_handlers[i].handler == NULL) { 1431 error("Unknown extended request \"%.100s\"", request); 1432 send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ 1433 } 1434 free(request); 1435 } 1436 1437 /* stolen from ssh-agent */ 1438 1439 static void 1440 process(void) 1441 { 1442 u_int msg_len; 1443 u_int buf_len; 1444 u_int consumed; 1445 u_char type; 1446 const u_char *cp; 1447 int i, r; 1448 u_int32_t id; 1449 1450 buf_len = sshbuf_len(iqueue); 1451 if (buf_len < 5) 1452 return; /* Incomplete message. */ 1453 cp = sshbuf_ptr(iqueue); 1454 msg_len = get_u32(cp); 1455 if (msg_len > SFTP_MAX_MSG_LENGTH) { 1456 error("bad message from %s local user %s", 1457 client_addr, pw->pw_name); 1458 sftp_server_cleanup_exit(11); 1459 } 1460 if (buf_len < msg_len + 4) 1461 return; 1462 if ((r = sshbuf_consume(iqueue, 4)) != 0) 1463 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1464 buf_len -= 4; 1465 if ((r = sshbuf_get_u8(iqueue, &type)) != 0) 1466 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1467 1468 switch (type) { 1469 case SSH2_FXP_INIT: 1470 process_init(); 1471 init_done = 1; 1472 break; 1473 case SSH2_FXP_EXTENDED: 1474 if (!init_done) 1475 fatal("Received extended request before init"); 1476 if ((r = sshbuf_get_u32(iqueue, &id)) != 0) 1477 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1478 process_extended(id); 1479 break; 1480 default: 1481 if (!init_done) 1482 fatal("Received %u request before init", type); 1483 if ((r = sshbuf_get_u32(iqueue, &id)) != 0) 1484 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1485 for (i = 0; handlers[i].handler != NULL; i++) { 1486 if (type == handlers[i].type) { 1487 if (!request_permitted(&handlers[i])) { 1488 send_status(id, 1489 SSH2_FX_PERMISSION_DENIED); 1490 } else { 1491 handlers[i].handler(id); 1492 } 1493 break; 1494 } 1495 } 1496 if (handlers[i].handler == NULL) 1497 error("Unknown message %u", type); 1498 } 1499 /* discard the remaining bytes from the current packet */ 1500 if (buf_len < sshbuf_len(iqueue)) { 1501 error("iqueue grew unexpectedly"); 1502 sftp_server_cleanup_exit(255); 1503 } 1504 consumed = buf_len - sshbuf_len(iqueue); 1505 if (msg_len < consumed) { 1506 error("msg_len %u < consumed %u", msg_len, consumed); 1507 sftp_server_cleanup_exit(255); 1508 } 1509 if (msg_len > consumed && 1510 (r = sshbuf_consume(iqueue, msg_len - consumed)) != 0) 1511 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1512 } 1513 1514 /* Cleanup handler that logs active handles upon normal exit */ 1515 void 1516 sftp_server_cleanup_exit(int i) 1517 { 1518 if (pw != NULL && client_addr != NULL) { 1519 handle_log_exit(); 1520 logit("session closed for local user %s from [%s]", 1521 pw->pw_name, client_addr); 1522 } 1523 _exit(i); 1524 } 1525 1526 static void 1527 sftp_server_usage(void) 1528 { 1529 extern char *__progname; 1530 1531 fprintf(stderr, 1532 "usage: %s [-ehR] [-d start_directory] [-f log_facility] " 1533 "[-l log_level]\n\t[-P denied_requests] " 1534 "[-p allowed_requests] [-u umask]\n" 1535 " %s -Q protocol_feature\n", 1536 __progname, __progname); 1537 exit(1); 1538 } 1539 1540 int 1541 sftp_server_main(int argc, char **argv, struct passwd *user_pw) 1542 { 1543 fd_set *rset, *wset; 1544 int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; 1545 ssize_t len, olen, set_size; 1546 SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; 1547 char *cp, *homedir = NULL, uidstr[32], buf[4*4096]; 1548 long mask; 1549 1550 extern char *optarg; 1551 extern char *__progname; 1552 1553 log_init(__progname, log_level, log_facility, log_stderr); 1554 1555 pw = pwcopy(user_pw); 1556 1557 while (!skipargs && (ch = getopt(argc, argv, 1558 "d:f:l:P:p:Q:u:cehR")) != -1) { 1559 switch (ch) { 1560 case 'Q': 1561 if (strcasecmp(optarg, "requests") != 0) { 1562 fprintf(stderr, "Invalid query type\n"); 1563 exit(1); 1564 } 1565 for (i = 0; handlers[i].handler != NULL; i++) 1566 printf("%s\n", handlers[i].name); 1567 for (i = 0; extended_handlers[i].handler != NULL; i++) 1568 printf("%s\n", extended_handlers[i].name); 1569 exit(0); 1570 break; 1571 case 'R': 1572 readonly = 1; 1573 break; 1574 case 'c': 1575 /* 1576 * Ignore all arguments if we are invoked as a 1577 * shell using "sftp-server -c command" 1578 */ 1579 skipargs = 1; 1580 break; 1581 case 'e': 1582 log_stderr = 1; 1583 break; 1584 case 'l': 1585 log_level = log_level_number(optarg); 1586 if (log_level == SYSLOG_LEVEL_NOT_SET) 1587 error("Invalid log level \"%s\"", optarg); 1588 break; 1589 case 'f': 1590 log_facility = log_facility_number(optarg); 1591 if (log_facility == SYSLOG_FACILITY_NOT_SET) 1592 error("Invalid log facility \"%s\"", optarg); 1593 break; 1594 case 'd': 1595 cp = tilde_expand_filename(optarg, user_pw->pw_uid); 1596 snprintf(uidstr, sizeof(uidstr), "%llu", 1597 (unsigned long long)pw->pw_uid); 1598 homedir = percent_expand(cp, "d", user_pw->pw_dir, 1599 "u", user_pw->pw_name, "U", uidstr, (char *)NULL); 1600 free(cp); 1601 break; 1602 case 'p': 1603 if (request_allowlist != NULL) 1604 fatal("Permitted requests already set"); 1605 request_allowlist = xstrdup(optarg); 1606 break; 1607 case 'P': 1608 if (request_denylist != NULL) 1609 fatal("Refused requests already set"); 1610 request_denylist = xstrdup(optarg); 1611 break; 1612 case 'u': 1613 errno = 0; 1614 mask = strtol(optarg, &cp, 8); 1615 if (mask < 0 || mask > 0777 || *cp != '\0' || 1616 cp == optarg || (mask == 0 && errno != 0)) 1617 fatal("Invalid umask \"%s\"", optarg); 1618 (void)umask((mode_t)mask); 1619 break; 1620 case 'h': 1621 default: 1622 sftp_server_usage(); 1623 } 1624 } 1625 1626 log_init(__progname, log_level, log_facility, log_stderr); 1627 1628 if ((cp = getenv("SSH_CONNECTION")) != NULL) { 1629 client_addr = xstrdup(cp); 1630 if ((cp = strchr(client_addr, ' ')) == NULL) { 1631 error("Malformed SSH_CONNECTION variable: \"%s\"", 1632 getenv("SSH_CONNECTION")); 1633 sftp_server_cleanup_exit(255); 1634 } 1635 *cp = '\0'; 1636 } else 1637 client_addr = xstrdup("UNKNOWN"); 1638 1639 logit("session opened for local user %s from [%s]", 1640 pw->pw_name, client_addr); 1641 1642 in = STDIN_FILENO; 1643 out = STDOUT_FILENO; 1644 1645 max = 0; 1646 if (in > max) 1647 max = in; 1648 if (out > max) 1649 max = out; 1650 1651 if ((iqueue = sshbuf_new()) == NULL) 1652 fatal("%s: sshbuf_new failed", __func__); 1653 if ((oqueue = sshbuf_new()) == NULL) 1654 fatal("%s: sshbuf_new failed", __func__); 1655 1656 rset = xcalloc(howmany(max + 1, NFDBITS), sizeof(fd_mask)); 1657 wset = xcalloc(howmany(max + 1, NFDBITS), sizeof(fd_mask)); 1658 1659 if (homedir != NULL) { 1660 if (chdir(homedir) != 0) { 1661 error("chdir to \"%s\" failed: %s", homedir, 1662 strerror(errno)); 1663 } 1664 } 1665 1666 set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask); 1667 for (;;) { 1668 memset(rset, 0, set_size); 1669 memset(wset, 0, set_size); 1670 1671 /* 1672 * Ensure that we can read a full buffer and handle 1673 * the worst-case length packet it can generate, 1674 * otherwise apply backpressure by stopping reads. 1675 */ 1676 if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 && 1677 (r = sshbuf_check_reserve(oqueue, 1678 SFTP_MAX_MSG_LENGTH)) == 0) 1679 FD_SET(in, rset); 1680 else if (r != SSH_ERR_NO_BUFFER_SPACE) 1681 fatal("%s: sshbuf_check_reserve failed: %s", 1682 __func__, ssh_err(r)); 1683 1684 olen = sshbuf_len(oqueue); 1685 if (olen > 0) 1686 FD_SET(out, wset); 1687 1688 if (select(max+1, rset, wset, NULL, NULL) == -1) { 1689 if (errno == EINTR) 1690 continue; 1691 error("select: %s", strerror(errno)); 1692 sftp_server_cleanup_exit(2); 1693 } 1694 1695 /* copy stdin to iqueue */ 1696 if (FD_ISSET(in, rset)) { 1697 len = read(in, buf, sizeof buf); 1698 if (len == 0) { 1699 debug("read eof"); 1700 sftp_server_cleanup_exit(0); 1701 } else if (len == -1) { 1702 error("read: %s", strerror(errno)); 1703 sftp_server_cleanup_exit(1); 1704 } else if ((r = sshbuf_put(iqueue, buf, len)) != 0) { 1705 fatal("%s: buffer error: %s", 1706 __func__, ssh_err(r)); 1707 } 1708 } 1709 /* send oqueue to stdout */ 1710 if (FD_ISSET(out, wset)) { 1711 len = write(out, sshbuf_ptr(oqueue), olen); 1712 if (len == -1) { 1713 error("write: %s", strerror(errno)); 1714 sftp_server_cleanup_exit(1); 1715 } else if ((r = sshbuf_consume(oqueue, len)) != 0) { 1716 fatal("%s: buffer error: %s", 1717 __func__, ssh_err(r)); 1718 } 1719 } 1720 1721 /* 1722 * Process requests from client if we can fit the results 1723 * into the output buffer, otherwise stop processing input 1724 * and let the output queue drain. 1725 */ 1726 r = sshbuf_check_reserve(oqueue, SFTP_MAX_MSG_LENGTH); 1727 if (r == 0) 1728 process(); 1729 else if (r != SSH_ERR_NO_BUFFER_SPACE) 1730 fatal("%s: sshbuf_check_reserve: %s", 1731 __func__, ssh_err(r)); 1732 } 1733 } 1734