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