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