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