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