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