OpenCoverage

sftp-server.c

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

Generated by Squish Coco 4.2.2