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