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