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