OSDN Git Service

Make the sshd directory configurable am: 3337c7067d
[android-x86/external-openssh.git] / sftp-server.c
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
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
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
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 *
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
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
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
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
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
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 *
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 *
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
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
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
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
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
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
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
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
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
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
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
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
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
848 process_stat(u_int32_t id)
849 {
850         process_do_stat(id, 0);
851 }
852
853 static void
854 process_lstat(u_int32_t id)
855 {
856         process_do_stat(id, 1);
857 }
858
859 static void
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }