Merge branch 'vendor/DHCPCD'
[dragonfly.git] / crypto / openssh / sftp-server.c
1 /* $OpenBSD: sftp-server.c,v 1.111 2017/04/04 00:24:56 djm Exp $ */
2 /*
3  * Copyright (c) 2000-2004 Markus Friedl.  All rights reserved.
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 #include "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@openssh.com", 0,
146            process_extended_posix_rename, 1 },
147         { "statvfs", "statvfs@openssh.com", 0, process_extended_statvfs, 0 },
148         { "fstatvfs", "fstatvfs@openssh.com", 0, process_extended_fstatvfs, 0 },
149         { "hardlink", "hardlink@openssh.com", 0, process_extended_hardlink, 1 },
150         { "fsync", "fsync@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@openssh.com")) != 0 ||
657             (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */
658             /* statvfs extension */
659             (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 ||
660             (r = sshbuf_put_cstring(msg, "2")) != 0 || /* version */
661             /* fstatvfs extension */
662             (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 ||
663             (r = sshbuf_put_cstring(msg, "2")) != 0 || /* version */
664             /* hardlink extension */
665             (r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 ||
666             (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */
667             /* fsync extension */
668             (r = sshbuf_put_cstring(msg, "fsync@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_RDONLY ||
695             (flags & (O_CREAT|O_TRUNC)) != 0)) {
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 }