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