1 /* $OpenBSD: sftp-server.c,v 1.111 2017/04/04 00:24:56 djm Exp $ */
3 * Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
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.
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.
20 #include <sys/types.h>
22 #ifdef HAVE_SYS_TIME_H
23 # include <sys/time.h>
25 #ifdef HAVE_SYS_MOUNT_H
26 #include <sys/mount.h>
28 #ifdef HAVE_SYS_STATVFS_H
29 #include <sys/statvfs.h>
52 #include "sftp-common.h"
55 static LogLevel log_level
= SYSLOG_LEVEL_ERROR
;
58 static struct passwd
*pw
= NULL
;
59 static char *client_addr
= NULL
;
61 /* input and output queue */
62 struct sshbuf
*iqueue
;
63 struct sshbuf
*oqueue
;
65 /* Version of client */
68 /* SSH2_FXP_INIT received */
74 /* Requests that are allowed/denied */
75 static char *request_whitelist
, *request_blacklist
;
77 /* portable attributes, etc. */
78 typedef struct Stat Stat
;
87 static void process_open(u_int32_t id
);
88 static void process_close(u_int32_t id
);
89 static void process_read(u_int32_t id
);
90 static void process_write(u_int32_t id
);
91 static void process_stat(u_int32_t id
);
92 static void process_lstat(u_int32_t id
);
93 static void process_fstat(u_int32_t id
);
94 static void process_setstat(u_int32_t id
);
95 static void process_fsetstat(u_int32_t id
);
96 static void process_opendir(u_int32_t id
);
97 static void process_readdir(u_int32_t id
);
98 static void process_remove(u_int32_t id
);
99 static void process_mkdir(u_int32_t id
);
100 static void process_rmdir(u_int32_t id
);
101 static void process_realpath(u_int32_t id
);
102 static void process_rename(u_int32_t id
);
103 static void process_readlink(u_int32_t id
);
104 static void process_symlink(u_int32_t id
);
105 static void process_extended_posix_rename(u_int32_t id
);
106 static void process_extended_statvfs(u_int32_t id
);
107 static void process_extended_fstatvfs(u_int32_t id
);
108 static void process_extended_hardlink(u_int32_t id
);
109 static void process_extended_fsync(u_int32_t id
);
110 static void process_extended(u_int32_t id
);
112 struct sftp_handler
{
113 const char *name
; /* user-visible name for fine-grained perms */
114 const char *ext_name
; /* extended request name */
115 u_int type
; /* packet type, for non extended packets */
116 void (*handler
)(u_int32_t
);
117 int does_write
; /* if nonzero, banned for readonly mode */
120 struct sftp_handler handlers
[] = {
121 /* NB. SSH2_FXP_OPEN does the readonly check in the handler itself */
122 { "open", NULL
, SSH2_FXP_OPEN
, process_open
, 0 },
123 { "close", NULL
, SSH2_FXP_CLOSE
, process_close
, 0 },
124 { "read", NULL
, SSH2_FXP_READ
, process_read
, 0 },
125 { "write", NULL
, SSH2_FXP_WRITE
, process_write
, 1 },
126 { "lstat", NULL
, SSH2_FXP_LSTAT
, process_lstat
, 0 },
127 { "fstat", NULL
, SSH2_FXP_FSTAT
, process_fstat
, 0 },
128 { "setstat", NULL
, SSH2_FXP_SETSTAT
, process_setstat
, 1 },
129 { "fsetstat", NULL
, SSH2_FXP_FSETSTAT
, process_fsetstat
, 1 },
130 { "opendir", NULL
, SSH2_FXP_OPENDIR
, process_opendir
, 0 },
131 { "readdir", NULL
, SSH2_FXP_READDIR
, process_readdir
, 0 },
132 { "remove", NULL
, SSH2_FXP_REMOVE
, process_remove
, 1 },
133 { "mkdir", NULL
, SSH2_FXP_MKDIR
, process_mkdir
, 1 },
134 { "rmdir", NULL
, SSH2_FXP_RMDIR
, process_rmdir
, 1 },
135 { "realpath", NULL
, SSH2_FXP_REALPATH
, process_realpath
, 0 },
136 { "stat", NULL
, SSH2_FXP_STAT
, process_stat
, 0 },
137 { "rename", NULL
, SSH2_FXP_RENAME
, process_rename
, 1 },
138 { "readlink", NULL
, SSH2_FXP_READLINK
, process_readlink
, 0 },
139 { "symlink", NULL
, SSH2_FXP_SYMLINK
, process_symlink
, 1 },
140 { NULL
, NULL
, 0, NULL
, 0 }
143 /* SSH2_FXP_EXTENDED submessages */
144 struct sftp_handler extended_handlers
[] = {
145 { "posix-rename", "posix-rename@openssh.com", 0,
146 process_extended_posix_rename
, 1 },
147 { "statvfs", "statvfs@openssh.com", 0, process_extended_statvfs
, 0 },
148 { "fstatvfs", "fstatvfs@openssh.com", 0, process_extended_fstatvfs
, 0 },
149 { "hardlink", "hardlink@openssh.com", 0, process_extended_hardlink
, 1 },
150 { "fsync", "fsync@openssh.com", 0, process_extended_fsync
, 1 },
151 { NULL
, NULL
, 0, NULL
, 0 }
155 request_permitted(struct sftp_handler
*h
)
159 if (readonly
&& h
->does_write
) {
160 verbose("Refusing %s request in read-only mode", h
->name
);
163 if (request_blacklist
!= NULL
&&
164 ((result
= match_list(h
->name
, request_blacklist
, NULL
))) != NULL
) {
166 verbose("Refusing blacklisted %s request", h
->name
);
169 if (request_whitelist
!= NULL
&&
170 ((result
= match_list(h
->name
, request_whitelist
, NULL
))) != NULL
) {
172 debug2("Permitting whitelisted %s request", h
->name
);
175 if (request_whitelist
!= NULL
) {
176 verbose("Refusing non-whitelisted %s request", h
->name
);
183 errno_to_portable(int unixerrno
)
195 ret
= SSH2_FX_NO_SUCH_FILE
;
200 ret
= SSH2_FX_PERMISSION_DENIED
;
204 ret
= SSH2_FX_BAD_MESSAGE
;
207 ret
= SSH2_FX_OP_UNSUPPORTED
;
210 ret
= SSH2_FX_FAILURE
;
217 flags_from_portable(int pflags
)
221 if ((pflags
& SSH2_FXF_READ
) &&
222 (pflags
& SSH2_FXF_WRITE
)) {
224 } else if (pflags
& SSH2_FXF_READ
) {
226 } else if (pflags
& SSH2_FXF_WRITE
) {
229 if (pflags
& SSH2_FXF_APPEND
)
231 if (pflags
& SSH2_FXF_CREAT
)
233 if (pflags
& SSH2_FXF_TRUNC
)
235 if (pflags
& SSH2_FXF_EXCL
)
241 string_from_portable(int pflags
)
243 static char ret
[128];
247 #define PAPPEND(str) { \
249 strlcat(ret, ",", sizeof(ret)); \
250 strlcat(ret, str, sizeof(ret)); \
253 if (pflags
& SSH2_FXF_READ
)
255 if (pflags
& SSH2_FXF_WRITE
)
257 if (pflags
& SSH2_FXF_APPEND
)
259 if (pflags
& SSH2_FXF_CREAT
)
261 if (pflags
& SSH2_FXF_TRUNC
)
263 if (pflags
& SSH2_FXF_EXCL
)
271 typedef struct Handle Handle
;
278 u_int64_t bytes_read
, bytes_write
;
288 Handle
*handles
= NULL
;
289 u_int num_handles
= 0;
290 int first_unused_handle
= -1;
292 static void handle_unused(int i
)
294 handles
[i
].use
= HANDLE_UNUSED
;
295 handles
[i
].next_unused
= first_unused_handle
;
296 first_unused_handle
= i
;
300 handle_new(int use
, const char *name
, int fd
, int flags
, DIR *dirp
)
304 if (first_unused_handle
== -1) {
305 if (num_handles
+ 1 <= num_handles
)
308 handles
= xreallocarray(handles
, num_handles
, sizeof(Handle
));
309 handle_unused(num_handles
- 1);
312 i
= first_unused_handle
;
313 first_unused_handle
= handles
[i
].next_unused
;
315 handles
[i
].use
= use
;
316 handles
[i
].dirp
= dirp
;
318 handles
[i
].flags
= flags
;
319 handles
[i
].name
= xstrdup(name
);
320 handles
[i
].bytes_read
= handles
[i
].bytes_write
= 0;
326 handle_is_ok(int i
, int type
)
328 return i
>= 0 && (u_int
)i
< num_handles
&& handles
[i
].use
== type
;
332 handle_to_string(int handle
, u_char
**stringp
, int *hlenp
)
334 if (stringp
== NULL
|| hlenp
== NULL
)
336 *stringp
= xmalloc(sizeof(int32_t));
337 put_u32(*stringp
, handle
);
338 *hlenp
= sizeof(int32_t);
343 handle_from_string(const u_char
*handle
, u_int hlen
)
347 if (hlen
!= sizeof(int32_t))
349 val
= get_u32(handle
);
350 if (handle_is_ok(val
, HANDLE_FILE
) ||
351 handle_is_ok(val
, HANDLE_DIR
))
357 handle_to_name(int handle
)
359 if (handle_is_ok(handle
, HANDLE_DIR
)||
360 handle_is_ok(handle
, HANDLE_FILE
))
361 return handles
[handle
].name
;
366 handle_to_dir(int handle
)
368 if (handle_is_ok(handle
, HANDLE_DIR
))
369 return handles
[handle
].dirp
;
374 handle_to_fd(int handle
)
376 if (handle_is_ok(handle
, HANDLE_FILE
))
377 return handles
[handle
].fd
;
382 handle_to_flags(int handle
)
384 if (handle_is_ok(handle
, HANDLE_FILE
))
385 return handles
[handle
].flags
;
390 handle_update_read(int handle
, ssize_t bytes
)
392 if (handle_is_ok(handle
, HANDLE_FILE
) && bytes
> 0)
393 handles
[handle
].bytes_read
+= bytes
;
397 handle_update_write(int handle
, ssize_t bytes
)
399 if (handle_is_ok(handle
, HANDLE_FILE
) && bytes
> 0)
400 handles
[handle
].bytes_write
+= bytes
;
404 handle_bytes_read(int handle
)
406 if (handle_is_ok(handle
, HANDLE_FILE
))
407 return (handles
[handle
].bytes_read
);
412 handle_bytes_write(int handle
)
414 if (handle_is_ok(handle
, HANDLE_FILE
))
415 return (handles
[handle
].bytes_write
);
420 handle_close(int handle
)
424 if (handle_is_ok(handle
, HANDLE_FILE
)) {
425 ret
= close(handles
[handle
].fd
);
426 free(handles
[handle
].name
);
427 handle_unused(handle
);
428 } else if (handle_is_ok(handle
, HANDLE_DIR
)) {
429 ret
= closedir(handles
[handle
].dirp
);
430 free(handles
[handle
].name
);
431 handle_unused(handle
);
439 handle_log_close(int handle
, char *emsg
)
441 if (handle_is_ok(handle
, HANDLE_FILE
)) {
442 logit("%s%sclose \"%s\" bytes read %llu written %llu",
443 emsg
== NULL
? "" : emsg
, emsg
== NULL
? "" : " ",
444 handle_to_name(handle
),
445 (unsigned long long)handle_bytes_read(handle
),
446 (unsigned long long)handle_bytes_write(handle
));
448 logit("%s%sclosedir \"%s\"",
449 emsg
== NULL
? "" : emsg
, emsg
== NULL
? "" : " ",
450 handle_to_name(handle
));
455 handle_log_exit(void)
459 for (i
= 0; i
< num_handles
; i
++)
460 if (handles
[i
].use
!= HANDLE_UNUSED
)
461 handle_log_close(i
, "forced");
465 get_handle(struct sshbuf
*queue
, int *hp
)
472 if ((r
= sshbuf_get_string(queue
, &handle
, &hlen
)) != 0)
475 *hp
= handle_from_string(handle
, hlen
);
483 send_msg(struct sshbuf
*m
)
487 if ((r
= sshbuf_put_stringb(oqueue
, m
)) != 0)
488 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
493 status_to_message(u_int32_t status
)
495 const char *status_messages
[] = {
496 "Success", /* SSH_FX_OK */
497 "End of file", /* SSH_FX_EOF */
498 "No such file", /* SSH_FX_NO_SUCH_FILE */
499 "Permission denied", /* SSH_FX_PERMISSION_DENIED */
500 "Failure", /* SSH_FX_FAILURE */
501 "Bad message", /* SSH_FX_BAD_MESSAGE */
502 "No connection", /* SSH_FX_NO_CONNECTION */
503 "Connection lost", /* SSH_FX_CONNECTION_LOST */
504 "Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */
505 "Unknown error" /* Others */
507 return (status_messages
[MINIMUM(status
,SSH2_FX_MAX
)]);
511 send_status(u_int32_t id
, u_int32_t status
)
516 debug3("request %u: sent status %u", id
, status
);
517 if (log_level
> SYSLOG_LEVEL_VERBOSE
||
518 (status
!= SSH2_FX_OK
&& status
!= SSH2_FX_EOF
))
519 logit("sent status %s", status_to_message(status
));
520 if ((msg
= sshbuf_new()) == NULL
)
521 fatal("%s: sshbuf_new failed", __func__
);
522 if ((r
= sshbuf_put_u8(msg
, SSH2_FXP_STATUS
)) != 0 ||
523 (r
= sshbuf_put_u32(msg
, id
)) != 0 ||
524 (r
= sshbuf_put_u32(msg
, status
)) != 0)
525 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
527 if ((r
= sshbuf_put_cstring(msg
,
528 status_to_message(status
))) != 0 ||
529 (r
= sshbuf_put_cstring(msg
, "")) != 0)
530 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
536 send_data_or_handle(char type
, u_int32_t id
, const u_char
*data
, int dlen
)
541 if ((msg
= sshbuf_new()) == NULL
)
542 fatal("%s: sshbuf_new failed", __func__
);
543 if ((r
= sshbuf_put_u8(msg
, type
)) != 0 ||
544 (r
= sshbuf_put_u32(msg
, id
)) != 0 ||
545 (r
= sshbuf_put_string(msg
, data
, dlen
)) != 0)
546 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
552 send_data(u_int32_t id
, const u_char
*data
, int dlen
)
554 debug("request %u: sent data len %d", id
, dlen
);
555 send_data_or_handle(SSH2_FXP_DATA
, id
, data
, dlen
);
559 send_handle(u_int32_t id
, int handle
)
564 handle_to_string(handle
, &string
, &hlen
);
565 debug("request %u: sent handle handle %d", id
, handle
);
566 send_data_or_handle(SSH2_FXP_HANDLE
, id
, string
, hlen
);
571 send_names(u_int32_t id
, int count
, const Stat
*stats
)
576 if ((msg
= sshbuf_new()) == NULL
)
577 fatal("%s: sshbuf_new failed", __func__
);
578 if ((r
= sshbuf_put_u8(msg
, SSH2_FXP_NAME
)) != 0 ||
579 (r
= sshbuf_put_u32(msg
, id
)) != 0 ||
580 (r
= sshbuf_put_u32(msg
, count
)) != 0)
581 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
582 debug("request %u: sent names count %d", id
, count
);
583 for (i
= 0; i
< count
; i
++) {
584 if ((r
= sshbuf_put_cstring(msg
, stats
[i
].name
)) != 0 ||
585 (r
= sshbuf_put_cstring(msg
, stats
[i
].long_name
)) != 0 ||
586 (r
= encode_attrib(msg
, &stats
[i
].attrib
)) != 0)
587 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
594 send_attrib(u_int32_t id
, const Attrib
*a
)
599 debug("request %u: sent attrib have 0x%x", id
, a
->flags
);
600 if ((msg
= sshbuf_new()) == NULL
)
601 fatal("%s: sshbuf_new failed", __func__
);
602 if ((r
= sshbuf_put_u8(msg
, SSH2_FXP_ATTRS
)) != 0 ||
603 (r
= sshbuf_put_u32(msg
, id
)) != 0 ||
604 (r
= encode_attrib(msg
, a
)) != 0)
605 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
611 send_statvfs(u_int32_t id
, struct statvfs
*st
)
617 flag
= (st
->f_flag
& ST_RDONLY
) ? SSH2_FXE_STATVFS_ST_RDONLY
: 0;
618 flag
|= (st
->f_flag
& ST_NOSUID
) ? SSH2_FXE_STATVFS_ST_NOSUID
: 0;
620 if ((msg
= sshbuf_new()) == NULL
)
621 fatal("%s: sshbuf_new failed", __func__
);
622 if ((r
= sshbuf_put_u8(msg
, SSH2_FXP_EXTENDED_REPLY
)) != 0 ||
623 (r
= sshbuf_put_u32(msg
, id
)) != 0 ||
624 (r
= sshbuf_put_u64(msg
, st
->f_bsize
)) != 0 ||
625 (r
= sshbuf_put_u64(msg
, st
->f_frsize
)) != 0 ||
626 (r
= sshbuf_put_u64(msg
, st
->f_blocks
)) != 0 ||
627 (r
= sshbuf_put_u64(msg
, st
->f_bfree
)) != 0 ||
628 (r
= sshbuf_put_u64(msg
, st
->f_bavail
)) != 0 ||
629 (r
= sshbuf_put_u64(msg
, st
->f_files
)) != 0 ||
630 (r
= sshbuf_put_u64(msg
, st
->f_ffree
)) != 0 ||
631 (r
= sshbuf_put_u64(msg
, st
->f_favail
)) != 0 ||
632 (r
= sshbuf_put_u64(msg
, FSID_TO_ULONG(st
->f_fsid
))) != 0 ||
633 (r
= sshbuf_put_u64(msg
, flag
)) != 0 ||
634 (r
= sshbuf_put_u64(msg
, st
->f_namemax
)) != 0)
635 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
648 if ((r
= sshbuf_get_u32(iqueue
, &version
)) != 0)
649 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
650 verbose("received client version %u", version
);
651 if ((msg
= sshbuf_new()) == NULL
)
652 fatal("%s: sshbuf_new failed", __func__
);
653 if ((r
= sshbuf_put_u8(msg
, SSH2_FXP_VERSION
)) != 0 ||
654 (r
= sshbuf_put_u32(msg
, SSH2_FILEXFER_VERSION
)) != 0 ||
655 /* POSIX rename extension */
656 (r
= sshbuf_put_cstring(msg
, "posix-rename@openssh.com")) != 0 ||
657 (r
= sshbuf_put_cstring(msg
, "1")) != 0 || /* version */
658 /* statvfs extension */
659 (r
= sshbuf_put_cstring(msg
, "statvfs@openssh.com")) != 0 ||
660 (r
= sshbuf_put_cstring(msg
, "2")) != 0 || /* version */
661 /* fstatvfs extension */
662 (r
= sshbuf_put_cstring(msg
, "fstatvfs@openssh.com")) != 0 ||
663 (r
= sshbuf_put_cstring(msg
, "2")) != 0 || /* version */
664 /* hardlink extension */
665 (r
= sshbuf_put_cstring(msg
, "hardlink@openssh.com")) != 0 ||
666 (r
= sshbuf_put_cstring(msg
, "1")) != 0 || /* version */
667 /* fsync extension */
668 (r
= sshbuf_put_cstring(msg
, "fsync@openssh.com")) != 0 ||
669 (r
= sshbuf_put_cstring(msg
, "1")) != 0) /* version */
670 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
676 process_open(u_int32_t id
)
681 int r
, handle
, fd
, flags
, mode
, status
= SSH2_FX_FAILURE
;
683 if ((r
= sshbuf_get_cstring(iqueue
, &name
, NULL
)) != 0 ||
684 (r
= sshbuf_get_u32(iqueue
, &pflags
)) != 0 || /* portable flags */
685 (r
= decode_attrib(iqueue
, &a
)) != 0)
686 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
688 debug3("request %u: open flags %d", id
, pflags
);
689 flags
= flags_from_portable(pflags
);
690 mode
= (a
.flags
& SSH2_FILEXFER_ATTR_PERMISSIONS
) ? a
.perm
: 0666;
691 logit("open \"%s\" flags %s mode 0%o",
692 name
, string_from_portable(pflags
), mode
);
694 ((flags
& O_ACCMODE
) != O_RDONLY
||
695 (flags
& (O_CREAT
|O_TRUNC
)) != 0)) {
696 verbose("Refusing open request in read-only mode");
697 status
= SSH2_FX_PERMISSION_DENIED
;
699 fd
= open(name
, flags
, mode
);
701 status
= errno_to_portable(errno
);
703 handle
= handle_new(HANDLE_FILE
, name
, fd
, flags
, NULL
);
707 send_handle(id
, handle
);
712 if (status
!= SSH2_FX_OK
)
713 send_status(id
, status
);
718 process_close(u_int32_t id
)
720 int r
, handle
, ret
, status
= SSH2_FX_FAILURE
;
722 if ((r
= get_handle(iqueue
, &handle
)) != 0)
723 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
725 debug3("request %u: close handle %u", id
, handle
);
726 handle_log_close(handle
, NULL
);
727 ret
= handle_close(handle
);
728 status
= (ret
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
729 send_status(id
, status
);
733 process_read(u_int32_t id
)
737 int r
, handle
, fd
, ret
, status
= SSH2_FX_FAILURE
;
740 if ((r
= get_handle(iqueue
, &handle
)) != 0 ||
741 (r
= sshbuf_get_u64(iqueue
, &off
)) != 0 ||
742 (r
= sshbuf_get_u32(iqueue
, &len
)) != 0)
743 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
745 debug("request %u: read \"%s\" (handle %d) off %llu len %d",
746 id
, handle_to_name(handle
), handle
, (unsigned long long)off
, len
);
747 if (len
> sizeof buf
) {
749 debug2("read change len %d", len
);
751 fd
= handle_to_fd(handle
);
753 if (lseek(fd
, off
, SEEK_SET
) < 0) {
754 error("process_read: seek failed");
755 status
= errno_to_portable(errno
);
757 ret
= read(fd
, buf
, len
);
759 status
= errno_to_portable(errno
);
760 } else if (ret
== 0) {
761 status
= SSH2_FX_EOF
;
763 send_data(id
, buf
, ret
);
765 handle_update_read(handle
, ret
);
769 if (status
!= SSH2_FX_OK
)
770 send_status(id
, status
);
774 process_write(u_int32_t id
)
778 int r
, handle
, fd
, ret
, status
;
781 if ((r
= get_handle(iqueue
, &handle
)) != 0 ||
782 (r
= sshbuf_get_u64(iqueue
, &off
)) != 0 ||
783 (r
= sshbuf_get_string(iqueue
, &data
, &len
)) != 0)
784 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
786 debug("request %u: write \"%s\" (handle %d) off %llu len %zu",
787 id
, handle_to_name(handle
), handle
, (unsigned long long)off
, len
);
788 fd
= handle_to_fd(handle
);
791 status
= SSH2_FX_FAILURE
;
793 if (!(handle_to_flags(handle
) & O_APPEND
) &&
794 lseek(fd
, off
, SEEK_SET
) < 0) {
795 status
= errno_to_portable(errno
);
796 error("process_write: seek failed");
799 ret
= write(fd
, data
, len
);
801 error("process_write: write failed");
802 status
= errno_to_portable(errno
);
803 } else if ((size_t)ret
== len
) {
805 handle_update_write(handle
, ret
);
807 debug2("nothing at all written");
808 status
= SSH2_FX_FAILURE
;
812 send_status(id
, status
);
817 process_do_stat(u_int32_t id
, int do_lstat
)
822 int r
, status
= SSH2_FX_FAILURE
;
824 if ((r
= sshbuf_get_cstring(iqueue
, &name
, NULL
)) != 0)
825 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
827 debug3("request %u: %sstat", id
, do_lstat
? "l" : "");
828 verbose("%sstat name \"%s\"", do_lstat
? "l" : "", name
);
829 r
= do_lstat
? lstat(name
, &st
) : stat(name
, &st
);
831 status
= errno_to_portable(errno
);
833 stat_to_attrib(&st
, &a
);
837 if (status
!= SSH2_FX_OK
)
838 send_status(id
, status
);
843 process_stat(u_int32_t id
)
845 process_do_stat(id
, 0);
849 process_lstat(u_int32_t id
)
851 process_do_stat(id
, 1);
855 process_fstat(u_int32_t id
)
859 int fd
, r
, handle
, status
= SSH2_FX_FAILURE
;
861 if ((r
= get_handle(iqueue
, &handle
)) != 0)
862 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
863 debug("request %u: fstat \"%s\" (handle %u)",
864 id
, handle_to_name(handle
), handle
);
865 fd
= handle_to_fd(handle
);
869 status
= errno_to_portable(errno
);
871 stat_to_attrib(&st
, &a
);
876 if (status
!= SSH2_FX_OK
)
877 send_status(id
, status
);
880 static struct timeval
*
881 attrib_to_tv(const Attrib
*a
)
883 static struct timeval tv
[2];
885 tv
[0].tv_sec
= a
->atime
;
887 tv
[1].tv_sec
= a
->mtime
;
893 process_setstat(u_int32_t id
)
897 int r
, status
= SSH2_FX_OK
;
899 if ((r
= sshbuf_get_cstring(iqueue
, &name
, NULL
)) != 0 ||
900 (r
= decode_attrib(iqueue
, &a
)) != 0)
901 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
903 debug("request %u: setstat name \"%s\"", id
, name
);
904 if (a
.flags
& SSH2_FILEXFER_ATTR_SIZE
) {
905 logit("set \"%s\" size %llu",
906 name
, (unsigned long long)a
.size
);
907 r
= truncate(name
, a
.size
);
909 status
= errno_to_portable(errno
);
911 if (a
.flags
& SSH2_FILEXFER_ATTR_PERMISSIONS
) {
912 logit("set \"%s\" mode %04o", name
, a
.perm
);
913 r
= chmod(name
, a
.perm
& 07777);
915 status
= errno_to_portable(errno
);
917 if (a
.flags
& SSH2_FILEXFER_ATTR_ACMODTIME
) {
921 strftime(buf
, sizeof(buf
), "%Y%m%d-%H:%M:%S",
923 logit("set \"%s\" modtime %s", name
, buf
);
924 r
= utimes(name
, attrib_to_tv(&a
));
926 status
= errno_to_portable(errno
);
928 if (a
.flags
& SSH2_FILEXFER_ATTR_UIDGID
) {
929 logit("set \"%s\" owner %lu group %lu", name
,
930 (u_long
)a
.uid
, (u_long
)a
.gid
);
931 r
= chown(name
, a
.uid
, a
.gid
);
933 status
= errno_to_portable(errno
);
935 send_status(id
, status
);
940 process_fsetstat(u_int32_t id
)
944 int status
= SSH2_FX_OK
;
946 if ((r
= get_handle(iqueue
, &handle
)) != 0 ||
947 (r
= decode_attrib(iqueue
, &a
)) != 0)
948 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
950 debug("request %u: fsetstat handle %d", id
, handle
);
951 fd
= handle_to_fd(handle
);
953 status
= SSH2_FX_FAILURE
;
955 char *name
= handle_to_name(handle
);
957 if (a
.flags
& SSH2_FILEXFER_ATTR_SIZE
) {
958 logit("set \"%s\" size %llu",
959 name
, (unsigned long long)a
.size
);
960 r
= ftruncate(fd
, a
.size
);
962 status
= errno_to_portable(errno
);
964 if (a
.flags
& SSH2_FILEXFER_ATTR_PERMISSIONS
) {
965 logit("set \"%s\" mode %04o", name
, a
.perm
);
967 r
= fchmod(fd
, a
.perm
& 07777);
969 r
= chmod(name
, a
.perm
& 07777);
972 status
= errno_to_portable(errno
);
974 if (a
.flags
& SSH2_FILEXFER_ATTR_ACMODTIME
) {
978 strftime(buf
, sizeof(buf
), "%Y%m%d-%H:%M:%S",
980 logit("set \"%s\" modtime %s", name
, buf
);
982 r
= futimes(fd
, attrib_to_tv(&a
));
984 r
= utimes(name
, attrib_to_tv(&a
));
987 status
= errno_to_portable(errno
);
989 if (a
.flags
& SSH2_FILEXFER_ATTR_UIDGID
) {
990 logit("set \"%s\" owner %lu group %lu", name
,
991 (u_long
)a
.uid
, (u_long
)a
.gid
);
993 r
= fchown(fd
, a
.uid
, a
.gid
);
995 r
= chown(name
, a
.uid
, a
.gid
);
998 status
= errno_to_portable(errno
);
1001 send_status(id
, status
);
1005 process_opendir(u_int32_t id
)
1009 int r
, handle
, status
= SSH2_FX_FAILURE
;
1011 if ((r
= sshbuf_get_cstring(iqueue
, &path
, NULL
)) != 0)
1012 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1014 debug3("request %u: opendir", id
);
1015 logit("opendir \"%s\"", path
);
1016 dirp
= opendir(path
);
1018 status
= errno_to_portable(errno
);
1020 handle
= handle_new(HANDLE_DIR
, path
, 0, 0, dirp
);
1024 send_handle(id
, handle
);
1025 status
= SSH2_FX_OK
;
1029 if (status
!= SSH2_FX_OK
)
1030 send_status(id
, status
);
1035 process_readdir(u_int32_t id
)
1042 if ((r
= get_handle(iqueue
, &handle
)) != 0)
1043 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1045 debug("request %u: readdir \"%s\" (handle %d)", id
,
1046 handle_to_name(handle
), handle
);
1047 dirp
= handle_to_dir(handle
);
1048 path
= handle_to_name(handle
);
1049 if (dirp
== NULL
|| path
== NULL
) {
1050 send_status(id
, SSH2_FX_FAILURE
);
1053 char pathname
[PATH_MAX
];
1055 int nstats
= 10, count
= 0, i
;
1057 stats
= xcalloc(nstats
, sizeof(Stat
));
1058 while ((dp
= readdir(dirp
)) != NULL
) {
1059 if (count
>= nstats
) {
1061 stats
= xreallocarray(stats
, nstats
, sizeof(Stat
));
1063 /* XXX OVERFLOW ? */
1064 snprintf(pathname
, sizeof pathname
, "%s%s%s", path
,
1065 strcmp(path
, "/") ? "/" : "", dp
->d_name
);
1066 if (lstat(pathname
, &st
) < 0)
1068 stat_to_attrib(&st
, &(stats
[count
].attrib
));
1069 stats
[count
].name
= xstrdup(dp
->d_name
);
1070 stats
[count
].long_name
= ls_file(dp
->d_name
, &st
, 0, 0);
1072 /* send up to 100 entries in one message */
1073 /* XXX check packet size instead */
1078 send_names(id
, count
, stats
);
1079 for (i
= 0; i
< count
; i
++) {
1080 free(stats
[i
].name
);
1081 free(stats
[i
].long_name
);
1084 send_status(id
, SSH2_FX_EOF
);
1091 process_remove(u_int32_t id
)
1094 int r
, status
= SSH2_FX_FAILURE
;
1096 if ((r
= sshbuf_get_cstring(iqueue
, &name
, NULL
)) != 0)
1097 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1099 debug3("request %u: remove", id
);
1100 logit("remove name \"%s\"", name
);
1102 status
= (r
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1103 send_status(id
, status
);
1108 process_mkdir(u_int32_t id
)
1112 int r
, mode
, status
= SSH2_FX_FAILURE
;
1114 if ((r
= sshbuf_get_cstring(iqueue
, &name
, NULL
)) != 0 ||
1115 (r
= decode_attrib(iqueue
, &a
)) != 0)
1116 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1118 mode
= (a
.flags
& SSH2_FILEXFER_ATTR_PERMISSIONS
) ?
1119 a
.perm
& 07777 : 0777;
1120 debug3("request %u: mkdir", id
);
1121 logit("mkdir name \"%s\" mode 0%o", name
, mode
);
1122 r
= mkdir(name
, mode
);
1123 status
= (r
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1124 send_status(id
, status
);
1129 process_rmdir(u_int32_t id
)
1134 if ((r
= sshbuf_get_cstring(iqueue
, &name
, NULL
)) != 0)
1135 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1137 debug3("request %u: rmdir", id
);
1138 logit("rmdir name \"%s\"", name
);
1140 status
= (r
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1141 send_status(id
, status
);
1146 process_realpath(u_int32_t id
)
1148 char resolvedname
[PATH_MAX
];
1152 if ((r
= sshbuf_get_cstring(iqueue
, &path
, NULL
)) != 0)
1153 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1155 if (path
[0] == '\0') {
1157 path
= xstrdup(".");
1159 debug3("request %u: realpath", id
);
1160 verbose("realpath \"%s\"", path
);
1161 if (realpath(path
, resolvedname
) == NULL
) {
1162 send_status(id
, errno_to_portable(errno
));
1165 attrib_clear(&s
.attrib
);
1166 s
.name
= s
.long_name
= resolvedname
;
1167 send_names(id
, 1, &s
);
1173 process_rename(u_int32_t id
)
1175 char *oldpath
, *newpath
;
1179 if ((r
= sshbuf_get_cstring(iqueue
, &oldpath
, NULL
)) != 0 ||
1180 (r
= sshbuf_get_cstring(iqueue
, &newpath
, NULL
)) != 0)
1181 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1183 debug3("request %u: rename", id
);
1184 logit("rename old \"%s\" new \"%s\"", oldpath
, newpath
);
1185 status
= SSH2_FX_FAILURE
;
1186 if (lstat(oldpath
, &sb
) == -1)
1187 status
= errno_to_portable(errno
);
1188 else if (S_ISREG(sb
.st_mode
)) {
1189 /* Race-free rename of regular files */
1190 if (link(oldpath
, newpath
) == -1) {
1191 if (errno
== EOPNOTSUPP
|| errno
== ENOSYS
1195 #ifdef LINK_OPNOTSUPP_ERRNO
1196 || errno
== LINK_OPNOTSUPP_ERRNO
1202 * fs doesn't support links, so fall back to
1203 * stat+rename. This is racy.
1205 if (stat(newpath
, &st
) == -1) {
1206 if (rename(oldpath
, newpath
) == -1)
1208 errno_to_portable(errno
);
1210 status
= SSH2_FX_OK
;
1213 status
= errno_to_portable(errno
);
1215 } else if (unlink(oldpath
) == -1) {
1216 status
= errno_to_portable(errno
);
1217 /* clean spare link */
1220 status
= SSH2_FX_OK
;
1221 } else if (stat(newpath
, &sb
) == -1) {
1222 if (rename(oldpath
, newpath
) == -1)
1223 status
= errno_to_portable(errno
);
1225 status
= SSH2_FX_OK
;
1227 send_status(id
, status
);
1233 process_readlink(u_int32_t id
)
1239 if ((r
= sshbuf_get_cstring(iqueue
, &path
, NULL
)) != 0)
1240 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1242 debug3("request %u: readlink", id
);
1243 verbose("readlink \"%s\"", path
);
1244 if ((len
= readlink(path
, buf
, sizeof(buf
) - 1)) == -1)
1245 send_status(id
, errno_to_portable(errno
));
1250 attrib_clear(&s
.attrib
);
1251 s
.name
= s
.long_name
= buf
;
1252 send_names(id
, 1, &s
);
1258 process_symlink(u_int32_t id
)
1260 char *oldpath
, *newpath
;
1263 if ((r
= sshbuf_get_cstring(iqueue
, &oldpath
, NULL
)) != 0 ||
1264 (r
= sshbuf_get_cstring(iqueue
, &newpath
, NULL
)) != 0)
1265 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1267 debug3("request %u: symlink", id
);
1268 logit("symlink old \"%s\" new \"%s\"", oldpath
, newpath
);
1269 /* this will fail if 'newpath' exists */
1270 r
= symlink(oldpath
, newpath
);
1271 status
= (r
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1272 send_status(id
, status
);
1278 process_extended_posix_rename(u_int32_t id
)
1280 char *oldpath
, *newpath
;
1283 if ((r
= sshbuf_get_cstring(iqueue
, &oldpath
, NULL
)) != 0 ||
1284 (r
= sshbuf_get_cstring(iqueue
, &newpath
, NULL
)) != 0)
1285 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1287 debug3("request %u: posix-rename", id
);
1288 logit("posix-rename old \"%s\" new \"%s\"", oldpath
, newpath
);
1289 r
= rename(oldpath
, newpath
);
1290 status
= (r
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1291 send_status(id
, status
);
1297 process_extended_statvfs(u_int32_t id
)
1303 if ((r
= sshbuf_get_cstring(iqueue
, &path
, NULL
)) != 0)
1304 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1305 debug3("request %u: statvfs", id
);
1306 logit("statvfs \"%s\"", path
);
1308 if (statvfs(path
, &st
) != 0)
1309 send_status(id
, errno_to_portable(errno
));
1311 send_statvfs(id
, &st
);
1316 process_extended_fstatvfs(u_int32_t id
)
1321 if ((r
= get_handle(iqueue
, &handle
)) != 0)
1322 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1323 debug("request %u: fstatvfs \"%s\" (handle %u)",
1324 id
, handle_to_name(handle
), handle
);
1325 if ((fd
= handle_to_fd(handle
)) < 0) {
1326 send_status(id
, SSH2_FX_FAILURE
);
1329 if (fstatvfs(fd
, &st
) != 0)
1330 send_status(id
, errno_to_portable(errno
));
1332 send_statvfs(id
, &st
);
1336 process_extended_hardlink(u_int32_t id
)
1338 char *oldpath
, *newpath
;
1341 if ((r
= sshbuf_get_cstring(iqueue
, &oldpath
, NULL
)) != 0 ||
1342 (r
= sshbuf_get_cstring(iqueue
, &newpath
, NULL
)) != 0)
1343 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1345 debug3("request %u: hardlink", id
);
1346 logit("hardlink old \"%s\" new \"%s\"", oldpath
, newpath
);
1347 r
= link(oldpath
, newpath
);
1348 status
= (r
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1349 send_status(id
, status
);
1355 process_extended_fsync(u_int32_t id
)
1357 int handle
, fd
, r
, status
= SSH2_FX_OP_UNSUPPORTED
;
1359 if ((r
= get_handle(iqueue
, &handle
)) != 0)
1360 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1361 debug3("request %u: fsync (handle %u)", id
, handle
);
1362 verbose("fsync \"%s\"", handle_to_name(handle
));
1363 if ((fd
= handle_to_fd(handle
)) < 0)
1364 status
= SSH2_FX_NO_SUCH_FILE
;
1365 else if (handle_is_ok(handle
, HANDLE_FILE
)) {
1367 status
= (r
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1369 send_status(id
, status
);
1373 process_extended(u_int32_t id
)
1378 if ((r
= sshbuf_get_cstring(iqueue
, &request
, NULL
)) != 0)
1379 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1380 for (i
= 0; extended_handlers
[i
].handler
!= NULL
; i
++) {
1381 if (strcmp(request
, extended_handlers
[i
].ext_name
) == 0) {
1382 if (!request_permitted(&extended_handlers
[i
]))
1383 send_status(id
, SSH2_FX_PERMISSION_DENIED
);
1385 extended_handlers
[i
].handler(id
);
1389 if (extended_handlers
[i
].handler
== NULL
) {
1390 error("Unknown extended request \"%.100s\"", request
);
1391 send_status(id
, SSH2_FX_OP_UNSUPPORTED
); /* MUST */
1396 /* stolen from ssh-agent */
1409 buf_len
= sshbuf_len(iqueue
);
1411 return; /* Incomplete message. */
1412 cp
= sshbuf_ptr(iqueue
);
1413 msg_len
= get_u32(cp
);
1414 if (msg_len
> SFTP_MAX_MSG_LENGTH
) {
1415 error("bad message from %s local user %s",
1416 client_addr
, pw
->pw_name
);
1417 sftp_server_cleanup_exit(11);
1419 if (buf_len
< msg_len
+ 4)
1421 if ((r
= sshbuf_consume(iqueue
, 4)) != 0)
1422 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1424 if ((r
= sshbuf_get_u8(iqueue
, &type
)) != 0)
1425 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1432 case SSH2_FXP_EXTENDED
:
1434 fatal("Received extended request before init");
1435 if ((r
= sshbuf_get_u32(iqueue
, &id
)) != 0)
1436 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1437 process_extended(id
);
1441 fatal("Received %u request before init", type
);
1442 if ((r
= sshbuf_get_u32(iqueue
, &id
)) != 0)
1443 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1444 for (i
= 0; handlers
[i
].handler
!= NULL
; i
++) {
1445 if (type
== handlers
[i
].type
) {
1446 if (!request_permitted(&handlers
[i
])) {
1448 SSH2_FX_PERMISSION_DENIED
);
1450 handlers
[i
].handler(id
);
1455 if (handlers
[i
].handler
== NULL
)
1456 error("Unknown message %u", type
);
1458 /* discard the remaining bytes from the current packet */
1459 if (buf_len
< sshbuf_len(iqueue
)) {
1460 error("iqueue grew unexpectedly");
1461 sftp_server_cleanup_exit(255);
1463 consumed
= buf_len
- sshbuf_len(iqueue
);
1464 if (msg_len
< consumed
) {
1465 error("msg_len %u < consumed %u", msg_len
, consumed
);
1466 sftp_server_cleanup_exit(255);
1468 if (msg_len
> consumed
&&
1469 (r
= sshbuf_consume(iqueue
, msg_len
- consumed
)) != 0)
1470 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1473 /* Cleanup handler that logs active handles upon normal exit */
1475 sftp_server_cleanup_exit(int i
)
1477 if (pw
!= NULL
&& client_addr
!= NULL
) {
1479 logit("session closed for local user %s from [%s]",
1480 pw
->pw_name
, client_addr
);
1486 sftp_server_usage(void)
1488 extern char *__progname
;
1491 "usage: %s [-ehR] [-d start_directory] [-f log_facility] "
1492 "[-l log_level]\n\t[-P blacklisted_requests] "
1493 "[-p whitelisted_requests] [-u umask]\n"
1494 " %s -Q protocol_feature\n",
1495 __progname
, __progname
);
1500 sftp_server_main(int argc
, char **argv
, struct passwd
*user_pw
)
1502 fd_set
*rset
, *wset
;
1503 int i
, r
, in
, out
, max
, ch
, skipargs
= 0, log_stderr
= 0;
1504 ssize_t len
, olen
, set_size
;
1505 SyslogFacility log_facility
= SYSLOG_FACILITY_AUTH
;
1506 char *cp
, *homedir
= NULL
, buf
[4*4096];
1509 extern char *optarg
;
1510 extern char *__progname
;
1512 ssh_malloc_init(); /* must be called before any mallocs */
1513 __progname
= ssh_get_progname(argv
[0]);
1514 log_init(__progname
, log_level
, log_facility
, log_stderr
);
1516 pw
= pwcopy(user_pw
);
1518 while (!skipargs
&& (ch
= getopt(argc
, argv
,
1519 "d:f:l:P:p:Q:u:cehR")) != -1) {
1522 if (strcasecmp(optarg
, "requests") != 0) {
1523 fprintf(stderr
, "Invalid query type\n");
1526 for (i
= 0; handlers
[i
].handler
!= NULL
; i
++)
1527 printf("%s\n", handlers
[i
].name
);
1528 for (i
= 0; extended_handlers
[i
].handler
!= NULL
; i
++)
1529 printf("%s\n", extended_handlers
[i
].name
);
1537 * Ignore all arguments if we are invoked as a
1538 * shell using "sftp-server -c command"
1546 log_level
= log_level_number(optarg
);
1547 if (log_level
== SYSLOG_LEVEL_NOT_SET
)
1548 error("Invalid log level \"%s\"", optarg
);
1551 log_facility
= log_facility_number(optarg
);
1552 if (log_facility
== SYSLOG_FACILITY_NOT_SET
)
1553 error("Invalid log facility \"%s\"", optarg
);
1556 cp
= tilde_expand_filename(optarg
, user_pw
->pw_uid
);
1557 homedir
= percent_expand(cp
, "d", user_pw
->pw_dir
,
1558 "u", user_pw
->pw_name
, (char *)NULL
);
1562 if (request_whitelist
!= NULL
)
1563 fatal("Permitted requests already set");
1564 request_whitelist
= xstrdup(optarg
);
1567 if (request_blacklist
!= NULL
)
1568 fatal("Refused requests already set");
1569 request_blacklist
= xstrdup(optarg
);
1573 mask
= strtol(optarg
, &cp
, 8);
1574 if (mask
< 0 || mask
> 0777 || *cp
!= '\0' ||
1575 cp
== optarg
|| (mask
== 0 && errno
!= 0))
1576 fatal("Invalid umask \"%s\"", optarg
);
1577 (void)umask((mode_t
)mask
);
1581 sftp_server_usage();
1585 log_init(__progname
, log_level
, log_facility
, log_stderr
);
1588 * On platforms where we can, avoid making /proc/self/{mem,maps}
1589 * available to the user so that sftp access doesn't automatically
1590 * imply arbitrary code execution access that will break
1591 * restricted configurations.
1593 platform_disable_tracing(1); /* strict */
1595 /* Drop any fine-grained privileges we don't need */
1596 platform_pledge_sftp_server();
1598 if ((cp
= getenv("SSH_CONNECTION")) != NULL
) {
1599 client_addr
= xstrdup(cp
);
1600 if ((cp
= strchr(client_addr
, ' ')) == NULL
) {
1601 error("Malformed SSH_CONNECTION variable: \"%s\"",
1602 getenv("SSH_CONNECTION"));
1603 sftp_server_cleanup_exit(255);
1607 client_addr
= xstrdup("UNKNOWN");
1609 logit("session opened for local user %s from [%s]",
1610 pw
->pw_name
, client_addr
);
1613 out
= STDOUT_FILENO
;
1616 setmode(in
, O_BINARY
);
1617 setmode(out
, O_BINARY
);
1626 if ((iqueue
= sshbuf_new()) == NULL
)
1627 fatal("%s: sshbuf_new failed", __func__
);
1628 if ((oqueue
= sshbuf_new()) == NULL
)
1629 fatal("%s: sshbuf_new failed", __func__
);
1631 rset
= xcalloc(howmany(max
+ 1, NFDBITS
), sizeof(fd_mask
));
1632 wset
= xcalloc(howmany(max
+ 1, NFDBITS
), sizeof(fd_mask
));
1634 if (homedir
!= NULL
) {
1635 if (chdir(homedir
) != 0) {
1636 error("chdir to \"%s\" failed: %s", homedir
,
1641 set_size
= howmany(max
+ 1, NFDBITS
) * sizeof(fd_mask
);
1643 memset(rset
, 0, set_size
);
1644 memset(wset
, 0, set_size
);
1647 * Ensure that we can read a full buffer and handle
1648 * the worst-case length packet it can generate,
1649 * otherwise apply backpressure by stopping reads.
1651 if ((r
= sshbuf_check_reserve(iqueue
, sizeof(buf
))) == 0 &&
1652 (r
= sshbuf_check_reserve(oqueue
,
1653 SFTP_MAX_MSG_LENGTH
)) == 0)
1655 else if (r
!= SSH_ERR_NO_BUFFER_SPACE
)
1656 fatal("%s: sshbuf_check_reserve failed: %s",
1657 __func__
, ssh_err(r
));
1659 olen
= sshbuf_len(oqueue
);
1663 if (select(max
+1, rset
, wset
, NULL
, NULL
) < 0) {
1666 error("select: %s", strerror(errno
));
1667 sftp_server_cleanup_exit(2);
1670 /* copy stdin to iqueue */
1671 if (FD_ISSET(in
, rset
)) {
1672 len
= read(in
, buf
, sizeof buf
);
1675 sftp_server_cleanup_exit(0);
1676 } else if (len
< 0) {
1677 error("read: %s", strerror(errno
));
1678 sftp_server_cleanup_exit(1);
1679 } else if ((r
= sshbuf_put(iqueue
, buf
, len
)) != 0) {
1680 fatal("%s: buffer error: %s",
1681 __func__
, ssh_err(r
));
1684 /* send oqueue to stdout */
1685 if (FD_ISSET(out
, wset
)) {
1686 len
= write(out
, sshbuf_ptr(oqueue
), olen
);
1688 error("write: %s", strerror(errno
));
1689 sftp_server_cleanup_exit(1);
1690 } else if ((r
= sshbuf_consume(oqueue
, len
)) != 0) {
1691 fatal("%s: buffer error: %s",
1692 __func__
, ssh_err(r
));
1697 * Process requests from client if we can fit the results
1698 * into the output buffer, otherwise stop processing input
1699 * and let the output queue drain.
1701 r
= sshbuf_check_reserve(oqueue
, SFTP_MAX_MSG_LENGTH
);
1704 else if (r
!= SSH_ERR_NO_BUFFER_SPACE
)
1705 fatal("%s: sshbuf_check_reserve: %s",
1706 __func__
, ssh_err(r
));