1 /* $OpenBSD: sftp-server.c,v 1.103 2014/01/17 06:23:24 dtucker 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>
21 #include <sys/param.h>
23 #ifdef HAVE_SYS_TIME_H
24 # include <sys/time.h>
26 #ifdef HAVE_SYS_MOUNT_H
27 #include <sys/mount.h>
29 #ifdef HAVE_SYS_STATVFS_H
30 #include <sys/statvfs.h>
32 #ifdef HAVE_SYS_PRCTL_H
33 #include <sys/prctl.h>
56 #include "sftp-common.h"
59 #define get_int64() buffer_get_int64(&iqueue);
60 #define get_int() buffer_get_int(&iqueue);
61 #define get_string(lenp) buffer_get_string(&iqueue, lenp);
64 static LogLevel log_level
= SYSLOG_LEVEL_ERROR
;
67 static struct passwd
*pw
= NULL
;
68 static char *client_addr
= NULL
;
70 /* input and output queue */
74 /* Version of client */
77 /* SSH2_FXP_INIT received */
83 /* Requests that are allowed/denied */
84 static char *request_whitelist
, *request_blacklist
;
86 /* portable attributes, etc. */
87 typedef struct Stat Stat
;
96 static void process_open(u_int32_t id
);
97 static void process_close(u_int32_t id
);
98 static void process_read(u_int32_t id
);
99 static void process_write(u_int32_t id
);
100 static void process_stat(u_int32_t id
);
101 static void process_lstat(u_int32_t id
);
102 static void process_fstat(u_int32_t id
);
103 static void process_setstat(u_int32_t id
);
104 static void process_fsetstat(u_int32_t id
);
105 static void process_opendir(u_int32_t id
);
106 static void process_readdir(u_int32_t id
);
107 static void process_remove(u_int32_t id
);
108 static void process_mkdir(u_int32_t id
);
109 static void process_rmdir(u_int32_t id
);
110 static void process_realpath(u_int32_t id
);
111 static void process_rename(u_int32_t id
);
112 static void process_readlink(u_int32_t id
);
113 static void process_symlink(u_int32_t id
);
114 static void process_extended_posix_rename(u_int32_t id
);
115 static void process_extended_statvfs(u_int32_t id
);
116 static void process_extended_fstatvfs(u_int32_t id
);
117 static void process_extended_hardlink(u_int32_t id
);
118 static void process_extended_fsync(u_int32_t id
);
119 static void process_extended(u_int32_t id
);
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 */
129 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 }
152 /* SSH2_FXP_EXTENDED submessages */
153 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 { NULL
, NULL
, 0, NULL
, 0 }
164 request_permitted(struct sftp_handler
*h
)
168 if (readonly
&& h
->does_write
) {
169 verbose("Refusing %s request in read-only mode", h
->name
);
172 if (request_blacklist
!= NULL
&&
173 ((result
= match_list(h
->name
, request_blacklist
, NULL
))) != NULL
) {
175 verbose("Refusing blacklisted %s request", h
->name
);
178 if (request_whitelist
!= NULL
&&
179 ((result
= match_list(h
->name
, request_whitelist
, NULL
))) != NULL
) {
181 debug2("Permitting whitelisted %s request", h
->name
);
184 if (request_whitelist
!= NULL
) {
185 verbose("Refusing non-whitelisted %s request", h
->name
);
192 errno_to_portable(int unixerrno
)
204 ret
= SSH2_FX_NO_SUCH_FILE
;
209 ret
= SSH2_FX_PERMISSION_DENIED
;
213 ret
= SSH2_FX_BAD_MESSAGE
;
216 ret
= SSH2_FX_OP_UNSUPPORTED
;
219 ret
= SSH2_FX_FAILURE
;
226 flags_from_portable(int pflags
)
230 if ((pflags
& SSH2_FXF_READ
) &&
231 (pflags
& SSH2_FXF_WRITE
)) {
233 } else if (pflags
& SSH2_FXF_READ
) {
235 } else if (pflags
& SSH2_FXF_WRITE
) {
238 if (pflags
& SSH2_FXF_APPEND
)
240 if (pflags
& SSH2_FXF_CREAT
)
242 if (pflags
& SSH2_FXF_TRUNC
)
244 if (pflags
& SSH2_FXF_EXCL
)
250 string_from_portable(int pflags
)
252 static char ret
[128];
256 #define PAPPEND(str) { \
258 strlcat(ret, ",", sizeof(ret)); \
259 strlcat(ret, str, sizeof(ret)); \
262 if (pflags
& SSH2_FXF_READ
)
264 if (pflags
& SSH2_FXF_WRITE
)
266 if (pflags
& SSH2_FXF_APPEND
)
268 if (pflags
& SSH2_FXF_CREAT
)
270 if (pflags
& SSH2_FXF_TRUNC
)
272 if (pflags
& SSH2_FXF_EXCL
)
281 return decode_attrib(&iqueue
);
286 typedef struct Handle Handle
;
293 u_int64_t bytes_read
, bytes_write
;
303 Handle
*handles
= NULL
;
304 u_int num_handles
= 0;
305 int first_unused_handle
= -1;
307 static void handle_unused(int i
)
309 handles
[i
].use
= HANDLE_UNUSED
;
310 handles
[i
].next_unused
= first_unused_handle
;
311 first_unused_handle
= i
;
315 handle_new(int use
, const char *name
, int fd
, int flags
, DIR *dirp
)
319 if (first_unused_handle
== -1) {
320 if (num_handles
+ 1 <= num_handles
)
323 handles
= xrealloc(handles
, num_handles
, sizeof(Handle
));
324 handle_unused(num_handles
- 1);
327 i
= first_unused_handle
;
328 first_unused_handle
= handles
[i
].next_unused
;
330 handles
[i
].use
= use
;
331 handles
[i
].dirp
= dirp
;
333 handles
[i
].flags
= flags
;
334 handles
[i
].name
= xstrdup(name
);
335 handles
[i
].bytes_read
= handles
[i
].bytes_write
= 0;
341 handle_is_ok(int i
, int type
)
343 return i
>= 0 && (u_int
)i
< num_handles
&& handles
[i
].use
== type
;
347 handle_to_string(int handle
, char **stringp
, int *hlenp
)
349 if (stringp
== NULL
|| hlenp
== NULL
)
351 *stringp
= xmalloc(sizeof(int32_t));
352 put_u32(*stringp
, handle
);
353 *hlenp
= sizeof(int32_t);
358 handle_from_string(const char *handle
, u_int hlen
)
362 if (hlen
!= sizeof(int32_t))
364 val
= get_u32(handle
);
365 if (handle_is_ok(val
, HANDLE_FILE
) ||
366 handle_is_ok(val
, HANDLE_DIR
))
372 handle_to_name(int handle
)
374 if (handle_is_ok(handle
, HANDLE_DIR
)||
375 handle_is_ok(handle
, HANDLE_FILE
))
376 return handles
[handle
].name
;
381 handle_to_dir(int handle
)
383 if (handle_is_ok(handle
, HANDLE_DIR
))
384 return handles
[handle
].dirp
;
389 handle_to_fd(int handle
)
391 if (handle_is_ok(handle
, HANDLE_FILE
))
392 return handles
[handle
].fd
;
397 handle_to_flags(int handle
)
399 if (handle_is_ok(handle
, HANDLE_FILE
))
400 return handles
[handle
].flags
;
405 handle_update_read(int handle
, ssize_t bytes
)
407 if (handle_is_ok(handle
, HANDLE_FILE
) && bytes
> 0)
408 handles
[handle
].bytes_read
+= bytes
;
412 handle_update_write(int handle
, ssize_t bytes
)
414 if (handle_is_ok(handle
, HANDLE_FILE
) && bytes
> 0)
415 handles
[handle
].bytes_write
+= bytes
;
419 handle_bytes_read(int handle
)
421 if (handle_is_ok(handle
, HANDLE_FILE
))
422 return (handles
[handle
].bytes_read
);
427 handle_bytes_write(int handle
)
429 if (handle_is_ok(handle
, HANDLE_FILE
))
430 return (handles
[handle
].bytes_write
);
435 handle_close(int handle
)
439 if (handle_is_ok(handle
, HANDLE_FILE
)) {
440 ret
= close(handles
[handle
].fd
);
441 free(handles
[handle
].name
);
442 handle_unused(handle
);
443 } else if (handle_is_ok(handle
, HANDLE_DIR
)) {
444 ret
= closedir(handles
[handle
].dirp
);
445 free(handles
[handle
].name
);
446 handle_unused(handle
);
454 handle_log_close(int handle
, char *emsg
)
456 if (handle_is_ok(handle
, HANDLE_FILE
)) {
457 logit("%s%sclose \"%s\" bytes read %llu written %llu",
458 emsg
== NULL
? "" : emsg
, emsg
== NULL
? "" : " ",
459 handle_to_name(handle
),
460 (unsigned long long)handle_bytes_read(handle
),
461 (unsigned long long)handle_bytes_write(handle
));
463 logit("%s%sclosedir \"%s\"",
464 emsg
== NULL
? "" : emsg
, emsg
== NULL
? "" : " ",
465 handle_to_name(handle
));
470 handle_log_exit(void)
474 for (i
= 0; i
< num_handles
; i
++)
475 if (handles
[i
].use
!= HANDLE_UNUSED
)
476 handle_log_close(i
, "forced");
486 handle
= get_string(&hlen
);
488 val
= handle_from_string(handle
, hlen
);
498 int mlen
= buffer_len(m
);
500 buffer_put_int(&oqueue
, mlen
);
501 buffer_append(&oqueue
, buffer_ptr(m
), mlen
);
502 buffer_consume(m
, mlen
);
506 status_to_message(u_int32_t status
)
508 const char *status_messages
[] = {
509 "Success", /* SSH_FX_OK */
510 "End of file", /* SSH_FX_EOF */
511 "No such file", /* SSH_FX_NO_SUCH_FILE */
512 "Permission denied", /* SSH_FX_PERMISSION_DENIED */
513 "Failure", /* SSH_FX_FAILURE */
514 "Bad message", /* SSH_FX_BAD_MESSAGE */
515 "No connection", /* SSH_FX_NO_CONNECTION */
516 "Connection lost", /* SSH_FX_CONNECTION_LOST */
517 "Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */
518 "Unknown error" /* Others */
520 return (status_messages
[MIN(status
,SSH2_FX_MAX
)]);
524 send_status(u_int32_t id
, u_int32_t status
)
528 debug3("request %u: sent status %u", id
, status
);
529 if (log_level
> SYSLOG_LEVEL_VERBOSE
||
530 (status
!= SSH2_FX_OK
&& status
!= SSH2_FX_EOF
))
531 logit("sent status %s", status_to_message(status
));
533 buffer_put_char(&msg
, SSH2_FXP_STATUS
);
534 buffer_put_int(&msg
, id
);
535 buffer_put_int(&msg
, status
);
537 buffer_put_cstring(&msg
, status_to_message(status
));
538 buffer_put_cstring(&msg
, "");
544 send_data_or_handle(char type
, u_int32_t id
, const char *data
, int dlen
)
549 buffer_put_char(&msg
, type
);
550 buffer_put_int(&msg
, id
);
551 buffer_put_string(&msg
, data
, dlen
);
557 send_data(u_int32_t id
, const char *data
, int dlen
)
559 debug("request %u: sent data len %d", id
, dlen
);
560 send_data_or_handle(SSH2_FXP_DATA
, id
, data
, dlen
);
564 send_handle(u_int32_t id
, int handle
)
569 handle_to_string(handle
, &string
, &hlen
);
570 debug("request %u: sent handle handle %d", id
, handle
);
571 send_data_or_handle(SSH2_FXP_HANDLE
, id
, string
, hlen
);
576 send_names(u_int32_t id
, int count
, const Stat
*stats
)
582 buffer_put_char(&msg
, SSH2_FXP_NAME
);
583 buffer_put_int(&msg
, id
);
584 buffer_put_int(&msg
, count
);
585 debug("request %u: sent names count %d", id
, count
);
586 for (i
= 0; i
< count
; i
++) {
587 buffer_put_cstring(&msg
, stats
[i
].name
);
588 buffer_put_cstring(&msg
, stats
[i
].long_name
);
589 encode_attrib(&msg
, &stats
[i
].attrib
);
596 send_attrib(u_int32_t id
, const Attrib
*a
)
600 debug("request %u: sent attrib have 0x%x", id
, a
->flags
);
602 buffer_put_char(&msg
, SSH2_FXP_ATTRS
);
603 buffer_put_int(&msg
, id
);
604 encode_attrib(&msg
, a
);
610 send_statvfs(u_int32_t id
, struct statvfs
*st
)
615 flag
= (st
->f_flag
& ST_RDONLY
) ? SSH2_FXE_STATVFS_ST_RDONLY
: 0;
616 flag
|= (st
->f_flag
& ST_NOSUID
) ? SSH2_FXE_STATVFS_ST_NOSUID
: 0;
619 buffer_put_char(&msg
, SSH2_FXP_EXTENDED_REPLY
);
620 buffer_put_int(&msg
, id
);
621 buffer_put_int64(&msg
, st
->f_bsize
);
622 buffer_put_int64(&msg
, st
->f_frsize
);
623 buffer_put_int64(&msg
, st
->f_blocks
);
624 buffer_put_int64(&msg
, st
->f_bfree
);
625 buffer_put_int64(&msg
, st
->f_bavail
);
626 buffer_put_int64(&msg
, st
->f_files
);
627 buffer_put_int64(&msg
, st
->f_ffree
);
628 buffer_put_int64(&msg
, st
->f_favail
);
629 buffer_put_int64(&msg
, FSID_TO_ULONG(st
->f_fsid
));
630 buffer_put_int64(&msg
, flag
);
631 buffer_put_int64(&msg
, st
->f_namemax
);
644 verbose("received client version %u", version
);
646 buffer_put_char(&msg
, SSH2_FXP_VERSION
);
647 buffer_put_int(&msg
, SSH2_FILEXFER_VERSION
);
648 /* POSIX rename extension */
649 buffer_put_cstring(&msg
, "posix-rename@openssh.com");
650 buffer_put_cstring(&msg
, "1"); /* version */
651 /* statvfs extension */
652 buffer_put_cstring(&msg
, "statvfs@openssh.com");
653 buffer_put_cstring(&msg
, "2"); /* version */
654 /* fstatvfs extension */
655 buffer_put_cstring(&msg
, "fstatvfs@openssh.com");
656 buffer_put_cstring(&msg
, "2"); /* version */
657 /* hardlink extension */
658 buffer_put_cstring(&msg
, "hardlink@openssh.com");
659 buffer_put_cstring(&msg
, "1"); /* version */
660 /* fsync extension */
661 buffer_put_cstring(&msg
, "fsync@openssh.com");
662 buffer_put_cstring(&msg
, "1"); /* version */
668 process_open(u_int32_t id
)
673 int handle
, fd
, flags
, mode
, status
= SSH2_FX_FAILURE
;
675 name
= get_string(NULL
);
676 pflags
= get_int(); /* portable flags */
677 debug3("request %u: open flags %d", id
, pflags
);
679 flags
= flags_from_portable(pflags
);
680 mode
= (a
->flags
& SSH2_FILEXFER_ATTR_PERMISSIONS
) ? a
->perm
: 0666;
681 logit("open \"%s\" flags %s mode 0%o",
682 name
, string_from_portable(pflags
), mode
);
684 ((flags
& O_ACCMODE
) == O_WRONLY
||
685 (flags
& O_ACCMODE
) == O_RDWR
)) {
686 verbose("Refusing open request in read-only mode");
687 status
= SSH2_FX_PERMISSION_DENIED
;
689 fd
= open(name
, flags
, mode
);
691 status
= errno_to_portable(errno
);
693 handle
= handle_new(HANDLE_FILE
, name
, fd
, flags
, NULL
);
697 send_handle(id
, handle
);
702 if (status
!= SSH2_FX_OK
)
703 send_status(id
, status
);
708 process_close(u_int32_t id
)
710 int handle
, ret
, status
= SSH2_FX_FAILURE
;
712 handle
= get_handle();
713 debug3("request %u: close handle %u", id
, handle
);
714 handle_log_close(handle
, NULL
);
715 ret
= handle_close(handle
);
716 status
= (ret
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
717 send_status(id
, status
);
721 process_read(u_int32_t id
)
725 int handle
, fd
, ret
, status
= SSH2_FX_FAILURE
;
728 handle
= get_handle();
732 debug("request %u: read \"%s\" (handle %d) off %llu len %d",
733 id
, handle_to_name(handle
), handle
, (unsigned long long)off
, len
);
734 if (len
> sizeof buf
) {
736 debug2("read change len %d", len
);
738 fd
= handle_to_fd(handle
);
740 if (lseek(fd
, off
, SEEK_SET
) < 0) {
741 error("process_read: seek failed");
742 status
= errno_to_portable(errno
);
744 ret
= read(fd
, buf
, len
);
746 status
= errno_to_portable(errno
);
747 } else if (ret
== 0) {
748 status
= SSH2_FX_EOF
;
750 send_data(id
, buf
, ret
);
752 handle_update_read(handle
, ret
);
756 if (status
!= SSH2_FX_OK
)
757 send_status(id
, status
);
761 process_write(u_int32_t id
)
765 int handle
, fd
, ret
, status
;
768 handle
= get_handle();
770 data
= get_string(&len
);
772 debug("request %u: write \"%s\" (handle %d) off %llu len %d",
773 id
, handle_to_name(handle
), handle
, (unsigned long long)off
, len
);
774 fd
= handle_to_fd(handle
);
777 status
= SSH2_FX_FAILURE
;
779 if (!(handle_to_flags(handle
) & O_APPEND
) &&
780 lseek(fd
, off
, SEEK_SET
) < 0) {
781 status
= errno_to_portable(errno
);
782 error("process_write: seek failed");
785 ret
= write(fd
, data
, len
);
787 error("process_write: write failed");
788 status
= errno_to_portable(errno
);
789 } else if ((size_t)ret
== len
) {
791 handle_update_write(handle
, ret
);
793 debug2("nothing at all written");
794 status
= SSH2_FX_FAILURE
;
798 send_status(id
, status
);
803 process_do_stat(u_int32_t id
, int do_lstat
)
808 int ret
, status
= SSH2_FX_FAILURE
;
810 name
= get_string(NULL
);
811 debug3("request %u: %sstat", id
, do_lstat
? "l" : "");
812 verbose("%sstat name \"%s\"", do_lstat
? "l" : "", name
);
813 ret
= do_lstat
? lstat(name
, &st
) : stat(name
, &st
);
815 status
= errno_to_portable(errno
);
817 stat_to_attrib(&st
, &a
);
821 if (status
!= SSH2_FX_OK
)
822 send_status(id
, status
);
827 process_stat(u_int32_t id
)
829 process_do_stat(id
, 0);
833 process_lstat(u_int32_t id
)
835 process_do_stat(id
, 1);
839 process_fstat(u_int32_t id
)
843 int fd
, ret
, handle
, status
= SSH2_FX_FAILURE
;
845 handle
= get_handle();
846 debug("request %u: fstat \"%s\" (handle %u)",
847 id
, handle_to_name(handle
), handle
);
848 fd
= handle_to_fd(handle
);
850 ret
= fstat(fd
, &st
);
852 status
= errno_to_portable(errno
);
854 stat_to_attrib(&st
, &a
);
859 if (status
!= SSH2_FX_OK
)
860 send_status(id
, status
);
863 static struct timeval
*
864 attrib_to_tv(const Attrib
*a
)
866 static struct timeval tv
[2];
868 tv
[0].tv_sec
= a
->atime
;
870 tv
[1].tv_sec
= a
->mtime
;
876 process_setstat(u_int32_t id
)
880 int status
= SSH2_FX_OK
, ret
;
882 name
= get_string(NULL
);
884 debug("request %u: setstat name \"%s\"", id
, name
);
885 if (a
->flags
& SSH2_FILEXFER_ATTR_SIZE
) {
886 logit("set \"%s\" size %llu",
887 name
, (unsigned long long)a
->size
);
888 ret
= truncate(name
, a
->size
);
890 status
= errno_to_portable(errno
);
892 if (a
->flags
& SSH2_FILEXFER_ATTR_PERMISSIONS
) {
893 logit("set \"%s\" mode %04o", name
, a
->perm
);
894 ret
= chmod(name
, a
->perm
& 07777);
896 status
= errno_to_portable(errno
);
898 if (a
->flags
& SSH2_FILEXFER_ATTR_ACMODTIME
) {
902 strftime(buf
, sizeof(buf
), "%Y%m%d-%H:%M:%S",
904 logit("set \"%s\" modtime %s", name
, buf
);
905 ret
= utimes(name
, attrib_to_tv(a
));
907 status
= errno_to_portable(errno
);
909 if (a
->flags
& SSH2_FILEXFER_ATTR_UIDGID
) {
910 logit("set \"%s\" owner %lu group %lu", name
,
911 (u_long
)a
->uid
, (u_long
)a
->gid
);
912 ret
= chown(name
, a
->uid
, a
->gid
);
914 status
= errno_to_portable(errno
);
916 send_status(id
, status
);
921 process_fsetstat(u_int32_t id
)
925 int status
= SSH2_FX_OK
;
927 handle
= get_handle();
929 debug("request %u: fsetstat handle %d", id
, handle
);
930 fd
= handle_to_fd(handle
);
932 status
= SSH2_FX_FAILURE
;
934 char *name
= handle_to_name(handle
);
936 if (a
->flags
& SSH2_FILEXFER_ATTR_SIZE
) {
937 logit("set \"%s\" size %llu",
938 name
, (unsigned long long)a
->size
);
939 ret
= ftruncate(fd
, a
->size
);
941 status
= errno_to_portable(errno
);
943 if (a
->flags
& SSH2_FILEXFER_ATTR_PERMISSIONS
) {
944 logit("set \"%s\" mode %04o", name
, a
->perm
);
946 ret
= fchmod(fd
, a
->perm
& 07777);
948 ret
= chmod(name
, a
->perm
& 07777);
951 status
= errno_to_portable(errno
);
953 if (a
->flags
& SSH2_FILEXFER_ATTR_ACMODTIME
) {
957 strftime(buf
, sizeof(buf
), "%Y%m%d-%H:%M:%S",
959 logit("set \"%s\" modtime %s", name
, buf
);
961 ret
= futimes(fd
, attrib_to_tv(a
));
963 ret
= utimes(name
, attrib_to_tv(a
));
966 status
= errno_to_portable(errno
);
968 if (a
->flags
& SSH2_FILEXFER_ATTR_UIDGID
) {
969 logit("set \"%s\" owner %lu group %lu", name
,
970 (u_long
)a
->uid
, (u_long
)a
->gid
);
972 ret
= fchown(fd
, a
->uid
, a
->gid
);
974 ret
= chown(name
, a
->uid
, a
->gid
);
977 status
= errno_to_portable(errno
);
980 send_status(id
, status
);
984 process_opendir(u_int32_t id
)
988 int handle
, status
= SSH2_FX_FAILURE
;
990 path
= get_string(NULL
);
991 debug3("request %u: opendir", id
);
992 logit("opendir \"%s\"", path
);
993 dirp
= opendir(path
);
995 status
= errno_to_portable(errno
);
997 handle
= handle_new(HANDLE_DIR
, path
, 0, 0, dirp
);
1001 send_handle(id
, handle
);
1002 status
= SSH2_FX_OK
;
1006 if (status
!= SSH2_FX_OK
)
1007 send_status(id
, status
);
1012 process_readdir(u_int32_t id
)
1019 handle
= get_handle();
1020 debug("request %u: readdir \"%s\" (handle %d)", id
,
1021 handle_to_name(handle
), handle
);
1022 dirp
= handle_to_dir(handle
);
1023 path
= handle_to_name(handle
);
1024 if (dirp
== NULL
|| path
== NULL
) {
1025 send_status(id
, SSH2_FX_FAILURE
);
1028 char pathname
[MAXPATHLEN
];
1030 int nstats
= 10, count
= 0, i
;
1032 stats
= xcalloc(nstats
, sizeof(Stat
));
1033 while ((dp
= readdir(dirp
)) != NULL
) {
1034 if (count
>= nstats
) {
1036 stats
= xrealloc(stats
, nstats
, sizeof(Stat
));
1038 /* XXX OVERFLOW ? */
1039 snprintf(pathname
, sizeof pathname
, "%s%s%s", path
,
1040 strcmp(path
, "/") ? "/" : "", dp
->d_name
);
1041 if (lstat(pathname
, &st
) < 0)
1043 stat_to_attrib(&st
, &(stats
[count
].attrib
));
1044 stats
[count
].name
= xstrdup(dp
->d_name
);
1045 stats
[count
].long_name
= ls_file(dp
->d_name
, &st
, 0, 0);
1047 /* send up to 100 entries in one message */
1048 /* XXX check packet size instead */
1053 send_names(id
, count
, stats
);
1054 for (i
= 0; i
< count
; i
++) {
1055 free(stats
[i
].name
);
1056 free(stats
[i
].long_name
);
1059 send_status(id
, SSH2_FX_EOF
);
1066 process_remove(u_int32_t id
)
1069 int status
= SSH2_FX_FAILURE
;
1072 name
= get_string(NULL
);
1073 debug3("request %u: remove", id
);
1074 logit("remove name \"%s\"", name
);
1076 status
= (ret
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1077 send_status(id
, status
);
1082 process_mkdir(u_int32_t id
)
1086 int ret
, mode
, status
= SSH2_FX_FAILURE
;
1088 name
= get_string(NULL
);
1090 mode
= (a
->flags
& SSH2_FILEXFER_ATTR_PERMISSIONS
) ?
1091 a
->perm
& 07777 : 0777;
1092 debug3("request %u: mkdir", id
);
1093 logit("mkdir name \"%s\" mode 0%o", name
, mode
);
1094 ret
= mkdir(name
, mode
);
1095 status
= (ret
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1096 send_status(id
, status
);
1101 process_rmdir(u_int32_t id
)
1106 name
= get_string(NULL
);
1107 debug3("request %u: rmdir", id
);
1108 logit("rmdir name \"%s\"", name
);
1110 status
= (ret
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1111 send_status(id
, status
);
1116 process_realpath(u_int32_t id
)
1118 char resolvedname
[MAXPATHLEN
];
1121 path
= get_string(NULL
);
1122 if (path
[0] == '\0') {
1124 path
= xstrdup(".");
1126 debug3("request %u: realpath", id
);
1127 verbose("realpath \"%s\"", path
);
1128 if (realpath(path
, resolvedname
) == NULL
) {
1129 send_status(id
, errno_to_portable(errno
));
1132 attrib_clear(&s
.attrib
);
1133 s
.name
= s
.long_name
= resolvedname
;
1134 send_names(id
, 1, &s
);
1140 process_rename(u_int32_t id
)
1142 char *oldpath
, *newpath
;
1146 oldpath
= get_string(NULL
);
1147 newpath
= get_string(NULL
);
1148 debug3("request %u: rename", id
);
1149 logit("rename old \"%s\" new \"%s\"", oldpath
, newpath
);
1150 status
= SSH2_FX_FAILURE
;
1151 if (lstat(oldpath
, &sb
) == -1)
1152 status
= errno_to_portable(errno
);
1153 else if (S_ISREG(sb
.st_mode
)) {
1154 /* Race-free rename of regular files */
1155 if (link(oldpath
, newpath
) == -1) {
1156 if (errno
== EOPNOTSUPP
|| errno
== ENOSYS
1160 #ifdef LINK_OPNOTSUPP_ERRNO
1161 || errno
== LINK_OPNOTSUPP_ERRNO
1167 * fs doesn't support links, so fall back to
1168 * stat+rename. This is racy.
1170 if (stat(newpath
, &st
) == -1) {
1171 if (rename(oldpath
, newpath
) == -1)
1173 errno_to_portable(errno
);
1175 status
= SSH2_FX_OK
;
1178 status
= errno_to_portable(errno
);
1180 } else if (unlink(oldpath
) == -1) {
1181 status
= errno_to_portable(errno
);
1182 /* clean spare link */
1185 status
= SSH2_FX_OK
;
1186 } else if (stat(newpath
, &sb
) == -1) {
1187 if (rename(oldpath
, newpath
) == -1)
1188 status
= errno_to_portable(errno
);
1190 status
= SSH2_FX_OK
;
1192 send_status(id
, status
);
1198 process_readlink(u_int32_t id
)
1201 char buf
[MAXPATHLEN
];
1204 path
= get_string(NULL
);
1205 debug3("request %u: readlink", id
);
1206 verbose("readlink \"%s\"", path
);
1207 if ((len
= readlink(path
, buf
, sizeof(buf
) - 1)) == -1)
1208 send_status(id
, errno_to_portable(errno
));
1213 attrib_clear(&s
.attrib
);
1214 s
.name
= s
.long_name
= buf
;
1215 send_names(id
, 1, &s
);
1221 process_symlink(u_int32_t id
)
1223 char *oldpath
, *newpath
;
1226 oldpath
= get_string(NULL
);
1227 newpath
= get_string(NULL
);
1228 debug3("request %u: symlink", id
);
1229 logit("symlink old \"%s\" new \"%s\"", oldpath
, newpath
);
1230 /* this will fail if 'newpath' exists */
1231 ret
= symlink(oldpath
, newpath
);
1232 status
= (ret
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1233 send_status(id
, status
);
1239 process_extended_posix_rename(u_int32_t id
)
1241 char *oldpath
, *newpath
;
1244 oldpath
= get_string(NULL
);
1245 newpath
= get_string(NULL
);
1246 debug3("request %u: posix-rename", id
);
1247 logit("posix-rename old \"%s\" new \"%s\"", oldpath
, newpath
);
1248 ret
= rename(oldpath
, newpath
);
1249 status
= (ret
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1250 send_status(id
, status
);
1256 process_extended_statvfs(u_int32_t id
)
1261 path
= get_string(NULL
);
1262 debug3("request %u: statvfs", id
);
1263 logit("statvfs \"%s\"", path
);
1265 if (statvfs(path
, &st
) != 0)
1266 send_status(id
, errno_to_portable(errno
));
1268 send_statvfs(id
, &st
);
1273 process_extended_fstatvfs(u_int32_t id
)
1278 handle
= get_handle();
1279 debug("request %u: fstatvfs \"%s\" (handle %u)",
1280 id
, handle_to_name(handle
), handle
);
1281 if ((fd
= handle_to_fd(handle
)) < 0) {
1282 send_status(id
, SSH2_FX_FAILURE
);
1285 if (fstatvfs(fd
, &st
) != 0)
1286 send_status(id
, errno_to_portable(errno
));
1288 send_statvfs(id
, &st
);
1292 process_extended_hardlink(u_int32_t id
)
1294 char *oldpath
, *newpath
;
1297 oldpath
= get_string(NULL
);
1298 newpath
= get_string(NULL
);
1299 debug3("request %u: hardlink", id
);
1300 logit("hardlink old \"%s\" new \"%s\"", oldpath
, newpath
);
1301 ret
= link(oldpath
, newpath
);
1302 status
= (ret
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1303 send_status(id
, status
);
1309 process_extended_fsync(u_int32_t id
)
1311 int handle
, fd
, ret
, status
= SSH2_FX_OP_UNSUPPORTED
;
1313 handle
= get_handle();
1314 debug3("request %u: fsync (handle %u)", id
, handle
);
1315 verbose("fsync \"%s\"", handle_to_name(handle
));
1316 if ((fd
= handle_to_fd(handle
)) < 0)
1317 status
= SSH2_FX_NO_SUCH_FILE
;
1318 else if (handle_is_ok(handle
, HANDLE_FILE
)) {
1320 status
= (ret
== -1) ? errno_to_portable(errno
) : SSH2_FX_OK
;
1322 send_status(id
, status
);
1326 process_extended(u_int32_t id
)
1331 request
= get_string(NULL
);
1332 for (i
= 0; extended_handlers
[i
].handler
!= NULL
; i
++) {
1333 if (strcmp(request
, extended_handlers
[i
].ext_name
) == 0) {
1334 if (!request_permitted(&extended_handlers
[i
]))
1335 send_status(id
, SSH2_FX_PERMISSION_DENIED
);
1337 extended_handlers
[i
].handler(id
);
1341 if (extended_handlers
[i
].handler
== NULL
) {
1342 error("Unknown extended request \"%.100s\"", request
);
1343 send_status(id
, SSH2_FX_OP_UNSUPPORTED
); /* MUST */
1348 /* stolen from ssh-agent */
1353 u_int msg_len
, buf_len
, consumed
, type
, i
;
1357 buf_len
= buffer_len(&iqueue
);
1359 return; /* Incomplete message. */
1360 cp
= buffer_ptr(&iqueue
);
1361 msg_len
= get_u32(cp
);
1362 if (msg_len
> SFTP_MAX_MSG_LENGTH
) {
1363 error("bad message from %s local user %s",
1364 client_addr
, pw
->pw_name
);
1365 sftp_server_cleanup_exit(11);
1367 if (buf_len
< msg_len
+ 4)
1369 buffer_consume(&iqueue
, 4);
1371 type
= buffer_get_char(&iqueue
);
1378 case SSH2_FXP_EXTENDED
:
1380 fatal("Received extended request before init");
1382 process_extended(id
);
1386 fatal("Received %u request before init", type
);
1388 for (i
= 0; handlers
[i
].handler
!= NULL
; i
++) {
1389 if (type
== handlers
[i
].type
) {
1390 if (!request_permitted(&handlers
[i
])) {
1392 SSH2_FX_PERMISSION_DENIED
);
1394 handlers
[i
].handler(id
);
1399 if (handlers
[i
].handler
== NULL
)
1400 error("Unknown message %u", type
);
1402 /* discard the remaining bytes from the current packet */
1403 if (buf_len
< buffer_len(&iqueue
)) {
1404 error("iqueue grew unexpectedly");
1405 sftp_server_cleanup_exit(255);
1407 consumed
= buf_len
- buffer_len(&iqueue
);
1408 if (msg_len
< consumed
) {
1409 error("msg_len %u < consumed %u", msg_len
, consumed
);
1410 sftp_server_cleanup_exit(255);
1412 if (msg_len
> consumed
)
1413 buffer_consume(&iqueue
, msg_len
- consumed
);
1416 /* Cleanup handler that logs active handles upon normal exit */
1418 sftp_server_cleanup_exit(int i
)
1420 if (pw
!= NULL
&& client_addr
!= NULL
) {
1422 logit("session closed for local user %s from [%s]",
1423 pw
->pw_name
, client_addr
);
1429 sftp_server_usage(void)
1431 extern char *__progname
;
1434 "usage: %s [-ehR] [-d start_directory] [-f log_facility] "
1435 "[-l log_level]\n\t[-P blacklisted_requests] "
1436 "[-p whitelisted_requests] [-u umask]\n"
1437 " %s -Q protocol_feature\n",
1438 __progname
, __progname
);
1443 sftp_server_main(int argc
, char **argv
, struct passwd
*user_pw
)
1445 fd_set
*rset
, *wset
;
1446 int i
, in
, out
, max
, ch
, skipargs
= 0, log_stderr
= 0;
1447 ssize_t len
, olen
, set_size
;
1448 SyslogFacility log_facility
= SYSLOG_FACILITY_AUTH
;
1449 char *cp
, *homedir
= NULL
, buf
[4*4096];
1452 extern char *optarg
;
1453 extern char *__progname
;
1455 __progname
= ssh_get_progname(argv
[0]);
1456 log_init(__progname
, log_level
, log_facility
, log_stderr
);
1458 pw
= pwcopy(user_pw
);
1460 while (!skipargs
&& (ch
= getopt(argc
, argv
,
1461 "d:f:l:P:p:Q:u:cehR")) != -1) {
1464 if (strcasecmp(optarg
, "requests") != 0) {
1465 fprintf(stderr
, "Invalid query type\n");
1468 for (i
= 0; handlers
[i
].handler
!= NULL
; i
++)
1469 printf("%s\n", handlers
[i
].name
);
1470 for (i
= 0; extended_handlers
[i
].handler
!= NULL
; i
++)
1471 printf("%s\n", extended_handlers
[i
].name
);
1479 * Ignore all arguments if we are invoked as a
1480 * shell using "sftp-server -c command"
1488 log_level
= log_level_number(optarg
);
1489 if (log_level
== SYSLOG_LEVEL_NOT_SET
)
1490 error("Invalid log level \"%s\"", optarg
);
1493 log_facility
= log_facility_number(optarg
);
1494 if (log_facility
== SYSLOG_FACILITY_NOT_SET
)
1495 error("Invalid log facility \"%s\"", optarg
);
1498 cp
= tilde_expand_filename(optarg
, user_pw
->pw_uid
);
1499 homedir
= percent_expand(cp
, "d", user_pw
->pw_dir
,
1500 "u", user_pw
->pw_name
, (char *)NULL
);
1504 if (request_whitelist
!= NULL
)
1505 fatal("Permitted requests already set");
1506 request_whitelist
= xstrdup(optarg
);
1509 if (request_blacklist
!= NULL
)
1510 fatal("Refused requests already set");
1511 request_blacklist
= xstrdup(optarg
);
1515 mask
= strtol(optarg
, &cp
, 8);
1516 if (mask
< 0 || mask
> 0777 || *cp
!= '\0' ||
1517 cp
== optarg
|| (mask
== 0 && errno
!= 0))
1518 fatal("Invalid umask \"%s\"", optarg
);
1519 (void)umask((mode_t
)mask
);
1523 sftp_server_usage();
1527 log_init(__progname
, log_level
, log_facility
, log_stderr
);
1529 #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
1531 * On Linux, we should try to avoid making /proc/self/{mem,maps}
1532 * available to the user so that sftp access doesn't automatically
1533 * imply arbitrary code execution access that will break
1534 * restricted configurations.
1536 if (prctl(PR_SET_DUMPABLE
, 0) != 0)
1537 fatal("unable to make the process undumpable");
1538 #endif /* defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) */
1540 if ((cp
= getenv("SSH_CONNECTION")) != NULL
) {
1541 client_addr
= xstrdup(cp
);
1542 if ((cp
= strchr(client_addr
, ' ')) == NULL
) {
1543 error("Malformed SSH_CONNECTION variable: \"%s\"",
1544 getenv("SSH_CONNECTION"));
1545 sftp_server_cleanup_exit(255);
1549 client_addr
= xstrdup("UNKNOWN");
1551 logit("session opened for local user %s from [%s]",
1552 pw
->pw_name
, client_addr
);
1555 out
= STDOUT_FILENO
;
1558 setmode(in
, O_BINARY
);
1559 setmode(out
, O_BINARY
);
1568 buffer_init(&iqueue
);
1569 buffer_init(&oqueue
);
1571 set_size
= howmany(max
+ 1, NFDBITS
) * sizeof(fd_mask
);
1572 rset
= (fd_set
*)xmalloc(set_size
);
1573 wset
= (fd_set
*)xmalloc(set_size
);
1575 if (homedir
!= NULL
) {
1576 if (chdir(homedir
) != 0) {
1577 error("chdir to \"%s\" failed: %s", homedir
,
1583 memset(rset
, 0, set_size
);
1584 memset(wset
, 0, set_size
);
1587 * Ensure that we can read a full buffer and handle
1588 * the worst-case length packet it can generate,
1589 * otherwise apply backpressure by stopping reads.
1591 if (buffer_check_alloc(&iqueue
, sizeof(buf
)) &&
1592 buffer_check_alloc(&oqueue
, SFTP_MAX_MSG_LENGTH
))
1595 olen
= buffer_len(&oqueue
);
1599 if (select(max
+1, rset
, wset
, NULL
, NULL
) < 0) {
1602 error("select: %s", strerror(errno
));
1603 sftp_server_cleanup_exit(2);
1606 /* copy stdin to iqueue */
1607 if (FD_ISSET(in
, rset
)) {
1608 len
= read(in
, buf
, sizeof buf
);
1611 sftp_server_cleanup_exit(0);
1612 } else if (len
< 0) {
1613 error("read: %s", strerror(errno
));
1614 sftp_server_cleanup_exit(1);
1616 buffer_append(&iqueue
, buf
, len
);
1619 /* send oqueue to stdout */
1620 if (FD_ISSET(out
, wset
)) {
1621 len
= write(out
, buffer_ptr(&oqueue
), olen
);
1623 error("write: %s", strerror(errno
));
1624 sftp_server_cleanup_exit(1);
1626 buffer_consume(&oqueue
, len
);
1631 * Process requests from client if we can fit the results
1632 * into the output buffer, otherwise stop processing input
1633 * and let the output queue drain.
1635 if (buffer_check_alloc(&oqueue
, SFTP_MAX_MSG_LENGTH
))