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