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