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