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