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