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