Line | Source | Count |
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | | - |
8 | | - |
9 | | - |
10 | | - |
11 | | - |
12 | | - |
13 | | - |
14 | | - |
15 | | - |
16 | | - |
17 | | - |
18 | | - |
19 | static LogLevel log_level = SYSLOG_LEVEL_ERROR; | - |
20 | | - |
21 | | - |
22 | static struct passwd *pw = | - |
23 | ((void *)0) | - |
24 | ; | - |
25 | static char *client_addr = | - |
26 | ((void *)0) | - |
27 | ; | - |
28 | | - |
29 | | - |
30 | struct sshbuf *iqueue; | - |
31 | struct sshbuf *oqueue; | - |
32 | | - |
33 | | - |
34 | static u_int version; | - |
35 | | - |
36 | | - |
37 | static int init_done; | - |
38 | | - |
39 | | - |
40 | static int readonly; | - |
41 | | - |
42 | | - |
43 | static char *request_whitelist, *request_blacklist; | - |
44 | | - |
45 | | - |
46 | typedef struct Stat Stat; | - |
47 | | - |
48 | struct Stat { | - |
49 | char *name; | - |
50 | char *long_name; | - |
51 | Attrib attrib; | - |
52 | }; | - |
53 | | - |
54 | | - |
55 | static void process_open(u_int32_t id); | - |
56 | static void process_close(u_int32_t id); | - |
57 | static void process_read(u_int32_t id); | - |
58 | static void process_write(u_int32_t id); | - |
59 | static void process_stat(u_int32_t id); | - |
60 | static void process_lstat(u_int32_t id); | - |
61 | static void process_fstat(u_int32_t id); | - |
62 | static void process_setstat(u_int32_t id); | - |
63 | static void process_fsetstat(u_int32_t id); | - |
64 | static void process_opendir(u_int32_t id); | - |
65 | static void process_readdir(u_int32_t id); | - |
66 | static void process_remove(u_int32_t id); | - |
67 | static void process_mkdir(u_int32_t id); | - |
68 | static void process_rmdir(u_int32_t id); | - |
69 | static void process_realpath(u_int32_t id); | - |
70 | static void process_rename(u_int32_t id); | - |
71 | static void process_readlink(u_int32_t id); | - |
72 | static void process_symlink(u_int32_t id); | - |
73 | static void process_extended_posix_rename(u_int32_t id); | - |
74 | static void process_extended_statvfs(u_int32_t id); | - |
75 | static void process_extended_fstatvfs(u_int32_t id); | - |
76 | static void process_extended_hardlink(u_int32_t id); | - |
77 | static void process_extended_fsync(u_int32_t id); | - |
78 | static void process_extended(u_int32_t id); | - |
79 | | - |
80 | struct sftp_handler { | - |
81 | const char *name; | - |
82 | const char *ext_name; | - |
83 | u_int type; | - |
84 | void (*handler)(u_int32_t); | - |
85 | int does_write; | - |
86 | }; | - |
87 | | - |
88 | struct sftp_handler handlers[] = { | - |
89 | | - |
90 | { "open", | - |
91 | ((void *)0) | - |
92 | , 3, process_open, 0 }, | - |
93 | { "close", | - |
94 | ((void *)0) | - |
95 | , 4, process_close, 0 }, | - |
96 | { "read", | - |
97 | ((void *)0) | - |
98 | , 5, process_read, 0 }, | - |
99 | { "write", | - |
100 | ((void *)0) | - |
101 | , 6, process_write, 1 }, | - |
102 | { "lstat", | - |
103 | ((void *)0) | - |
104 | , 7, process_lstat, 0 }, | - |
105 | { "fstat", | - |
106 | ((void *)0) | - |
107 | , 8, process_fstat, 0 }, | - |
108 | { "setstat", | - |
109 | ((void *)0) | - |
110 | , 9, process_setstat, 1 }, | - |
111 | { "fsetstat", | - |
112 | ((void *)0) | - |
113 | , 10, process_fsetstat, 1 }, | - |
114 | { "opendir", | - |
115 | ((void *)0) | - |
116 | , 11, process_opendir, 0 }, | - |
117 | { "readdir", | - |
118 | ((void *)0) | - |
119 | , 12, process_readdir, 0 }, | - |
120 | { "remove", | - |
121 | ((void *)0) | - |
122 | , 13, process_remove, 1 }, | - |
123 | { "mkdir", | - |
124 | ((void *)0) | - |
125 | , 14, process_mkdir, 1 }, | - |
126 | { "rmdir", | - |
127 | ((void *)0) | - |
128 | , 15, process_rmdir, 1 }, | - |
129 | { "realpath", | - |
130 | ((void *)0) | - |
131 | , 16, process_realpath, 0 }, | - |
132 | { "stat", | - |
133 | ((void *)0) | - |
134 | , 17, process_stat, 0 }, | - |
135 | { "rename", | - |
136 | ((void *)0) | - |
137 | , 18, process_rename, 1 }, | - |
138 | { "readlink", | - |
139 | ((void *)0) | - |
140 | , 19, process_readlink, 0 }, | - |
141 | { "symlink", | - |
142 | ((void *)0) | - |
143 | , 20, process_symlink, 1 }, | - |
144 | { | - |
145 | ((void *)0) | - |
146 | , | - |
147 | ((void *)0) | - |
148 | , 0, | - |
149 | ((void *)0) | - |
150 | , 0 } | - |
151 | }; | - |
152 | | - |
153 | | - |
154 | struct sftp_handler extended_handlers[] = { | - |
155 | { "posix-rename", "posix-rename@openssh.com", 0, | - |
156 | process_extended_posix_rename, 1 }, | - |
157 | { "statvfs", "statvfs@openssh.com", 0, process_extended_statvfs, 0 }, | - |
158 | { "fstatvfs", "fstatvfs@openssh.com", 0, process_extended_fstatvfs, 0 }, | - |
159 | { "hardlink", "hardlink@openssh.com", 0, process_extended_hardlink, 1 }, | - |
160 | { "fsync", "fsync@openssh.com", 0, process_extended_fsync, 1 }, | - |
161 | { | - |
162 | ((void *)0) | - |
163 | , | - |
164 | ((void *)0) | - |
165 | , 0, | - |
166 | ((void *)0) | - |
167 | , 0 } | - |
168 | }; | - |
169 | | - |
170 | static int | - |
171 | request_permitted(struct sftp_handler *h) | - |
172 | { | - |
173 | char *result; | - |
174 | | - |
175 | if (readonlyTRUE | never evaluated | FALSE | never evaluated |
&& h->does_writeTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
176 | verbose("Refusing %s request in read-only mode", h->name); | - |
177 | return never executed: return 0; 0;never executed: return 0; | 0 |
178 | } | - |
179 | if (request_blacklist != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
180 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
181 | && | - |
182 | ((TRUE | never evaluated | FALSE | never evaluated |
result = match_list(h->name, request_blacklist, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
183 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
184 | ))) != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
185 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
186 | ) { | - |
187 | free(result); | - |
188 | verbose("Refusing blacklisted %s request", h->name); | - |
189 | return never executed: return 0; 0;never executed: return 0; | 0 |
190 | } | - |
191 | if (request_whitelist != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
192 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
193 | && | - |
194 | ((TRUE | never evaluated | FALSE | never evaluated |
result = match_list(h->name, request_whitelist, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
195 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
196 | ))) != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
197 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
198 | ) { | - |
199 | free(result); | - |
200 | debug2("Permitting whitelisted %s request", h->name); | - |
201 | return never executed: return 1; 1;never executed: return 1; | 0 |
202 | } | - |
203 | if (request_whitelist != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
204 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
205 | ) { | - |
206 | verbose("Refusing non-whitelisted %s request", h->name); | - |
207 | return never executed: return 0; 0;never executed: return 0; | 0 |
208 | } | - |
209 | return never executed: return 1; 1;never executed: return 1; | 0 |
210 | } | - |
211 | | - |
212 | static int | - |
213 | errno_to_portable(int unixerrno) | - |
214 | { | - |
215 | int ret = 0; | - |
216 | | - |
217 | switch (unixerrno) { | - |
218 | case never executed: case 0: 0:never executed: case 0: | 0 |
219 | ret = 0; | - |
220 | break; never executed: break; | 0 |
221 | case never executed: case 2 : never executed: case 2 : | 0 |
222 | 2 never executed: case 2 : | 0 |
223 | : never executed: case 2 : | 0 |
224 | case never executed: case 20 : never executed: case 20 : | 0 |
225 | 20 never executed: case 20 : | 0 |
226 | : never executed: case 20 : | 0 |
227 | case never executed: case 9 : never executed: case 9 : | 0 |
228 | 9 never executed: case 9 : | 0 |
229 | : never executed: case 9 : | 0 |
230 | case never executed: case 40 : never executed: case 40 : | 0 |
231 | 40 never executed: case 40 : | 0 |
232 | : never executed: case 40 : | 0 |
233 | ret = 2; | - |
234 | break; never executed: break; | 0 |
235 | case never executed: case 1 : never executed: case 1 : | 0 |
236 | 1 never executed: case 1 : | 0 |
237 | : never executed: case 1 : | 0 |
238 | case never executed: case 13 : never executed: case 13 : | 0 |
239 | 13 never executed: case 13 : | 0 |
240 | : never executed: case 13 : | 0 |
241 | case never executed: case 14 : never executed: case 14 : | 0 |
242 | 14 never executed: case 14 : | 0 |
243 | : never executed: case 14 : | 0 |
244 | ret = 3; | - |
245 | break; never executed: break; | 0 |
246 | case never executed: case 36 : never executed: case 36 : | 0 |
247 | 36 never executed: case 36 : | 0 |
248 | : never executed: case 36 : | 0 |
249 | case never executed: case 22 : never executed: case 22 : | 0 |
250 | 22 never executed: case 22 : | 0 |
251 | : never executed: case 22 : | 0 |
252 | ret = 5; | - |
253 | break; never executed: break; | 0 |
254 | case never executed: case 38 : never executed: case 38 : | 0 |
255 | 38 never executed: case 38 : | 0 |
256 | : never executed: case 38 : | 0 |
257 | ret = 8; | - |
258 | break; never executed: break; | 0 |
259 | default never executed: default: :never executed: default: | 0 |
260 | ret = 4; | - |
261 | break; never executed: break; | 0 |
262 | } | - |
263 | return never executed: return ret; ret;never executed: return ret; | 0 |
264 | } | - |
265 | | - |
266 | static int | - |
267 | flags_from_portable(int pflags) | - |
268 | { | - |
269 | int flags = 0; | - |
270 | | - |
271 | if ((TRUE | never evaluated | FALSE | never evaluated |
pflags & 0x00000001)TRUE | never evaluated | FALSE | never evaluated |
&& | 0 |
272 | (TRUE | never evaluated | FALSE | never evaluated |
pflags & 0x00000002)TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
273 | flags = | - |
274 | 02 | - |
275 | ; | - |
276 | } never executed: end of block else if (pflags & 0x00000001TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
277 | flags = | - |
278 | 00 | - |
279 | ; | - |
280 | } never executed: end of block else if (pflags & 0x00000002TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
281 | flags = | - |
282 | 01 | - |
283 | ; | - |
284 | } never executed: end of block | 0 |
285 | if (pflags & 0x00000004TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
286 | flags |= never executed: flags |= 02000 ; | 0 |
287 | 02000 never executed: flags |= 02000 ; | 0 |
288 | ; never executed: flags |= 02000 ; | 0 |
289 | if (pflags & 0x00000008TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
290 | flags |= never executed: flags |= 0100 ; | 0 |
291 | 0100 never executed: flags |= 0100 ; | 0 |
292 | ; never executed: flags |= 0100 ; | 0 |
293 | if (pflags & 0x00000010TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
294 | flags |= never executed: flags |= 01000 ; | 0 |
295 | 01000 never executed: flags |= 01000 ; | 0 |
296 | ; never executed: flags |= 01000 ; | 0 |
297 | if (pflags & 0x00000020TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
298 | flags |= never executed: flags |= 0200 ; | 0 |
299 | 0200 never executed: flags |= 0200 ; | 0 |
300 | ; never executed: flags |= 0200 ; | 0 |
301 | return never executed: return flags; flags;never executed: return flags; | 0 |
302 | } | - |
303 | | - |
304 | static const char * | - |
305 | string_from_portable(int pflags) | - |
306 | { | - |
307 | static char ret[128]; | - |
308 | | - |
309 | *ret = '\0'; | - |
310 | | - |
311 | | - |
312 | | - |
313 | | - |
314 | | - |
315 | | - |
316 | | - |
317 | if (pflags & 0x00000001TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
318 | { if (*TRUE | never evaluated | FALSE | never evaluated |
ret != '\0'TRUE | never evaluated | FALSE | never evaluated |
) strlcat(ret, ",", sizeof(ret));never executed: strlcat(ret, ",", sizeof(ret)); strlcat(ret, "READ", sizeof(ret)); }never executed: end of block | 0 |
319 | if (pflags & 0x00000002TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
320 | { if (*TRUE | never evaluated | FALSE | never evaluated |
ret != '\0'TRUE | never evaluated | FALSE | never evaluated |
) strlcat(ret, ",", sizeof(ret));never executed: strlcat(ret, ",", sizeof(ret)); strlcat(ret, "WRITE", sizeof(ret)); }never executed: end of block | 0 |
321 | if (pflags & 0x00000004TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
322 | { if (*TRUE | never evaluated | FALSE | never evaluated |
ret != '\0'TRUE | never evaluated | FALSE | never evaluated |
) strlcat(ret, ",", sizeof(ret));never executed: strlcat(ret, ",", sizeof(ret)); strlcat(ret, "APPEND", sizeof(ret)); }never executed: end of block | 0 |
323 | if (pflags & 0x00000008TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
324 | { if (*TRUE | never evaluated | FALSE | never evaluated |
ret != '\0'TRUE | never evaluated | FALSE | never evaluated |
) strlcat(ret, ",", sizeof(ret));never executed: strlcat(ret, ",", sizeof(ret)); strlcat(ret, "CREATE", sizeof(ret)); }never executed: end of block | 0 |
325 | if (pflags & 0x00000010TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
326 | { if (*TRUE | never evaluated | FALSE | never evaluated |
ret != '\0'TRUE | never evaluated | FALSE | never evaluated |
) strlcat(ret, ",", sizeof(ret));never executed: strlcat(ret, ",", sizeof(ret)); strlcat(ret, "TRUNCATE", sizeof(ret)); }never executed: end of block | 0 |
327 | if (pflags & 0x00000020TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
328 | { if (*TRUE | never evaluated | FALSE | never evaluated |
ret != '\0'TRUE | never evaluated | FALSE | never evaluated |
) strlcat(ret, ",", sizeof(ret));never executed: strlcat(ret, ",", sizeof(ret)); strlcat(ret, "EXCL", sizeof(ret)); }never executed: end of block | 0 |
329 | | - |
330 | return never executed: return ret; ret;never executed: return ret; | 0 |
331 | } | - |
332 | | - |
333 | | - |
334 | | - |
335 | typedef struct Handle Handle; | - |
336 | struct Handle { | - |
337 | int use; | - |
338 | DIR *dirp; | - |
339 | int fd; | - |
340 | int flags; | - |
341 | char *name; | - |
342 | u_int64_t bytes_read, bytes_write; | - |
343 | int next_unused; | - |
344 | }; | - |
345 | | - |
346 | enum { | - |
347 | HANDLE_UNUSED, | - |
348 | HANDLE_DIR, | - |
349 | HANDLE_FILE | - |
350 | }; | - |
351 | | - |
352 | Handle *handles = | - |
353 | ((void *)0) | - |
354 | ; | - |
355 | u_int num_handles = 0; | - |
356 | int first_unused_handle = -1; | - |
357 | | - |
358 | static void handle_unused(int i) | - |
359 | { | - |
360 | handles[i].use = HANDLE_UNUSED; | - |
361 | handles[i].next_unused = first_unused_handle; | - |
362 | first_unused_handle = i; | - |
363 | } never executed: end of block | 0 |
364 | | - |
365 | static int | - |
366 | handle_new(int use, const char *name, int fd, int flags, DIR *dirp) | - |
367 | { | - |
368 | int i; | - |
369 | | - |
370 | if (first_unused_handle == -1TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
371 | if (num_handles + 1 <= num_handlesTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
372 | return never executed: return -1; -1;never executed: return -1; | 0 |
373 | num_handles++; | - |
374 | handles = xreallocarray(handles, num_handles, sizeof(Handle)); | - |
375 | handle_unused(num_handles - 1); | - |
376 | } never executed: end of block | 0 |
377 | | - |
378 | i = first_unused_handle; | - |
379 | first_unused_handle = handles[i].next_unused; | - |
380 | | - |
381 | handles[i].use = use; | - |
382 | handles[i].dirp = dirp; | - |
383 | handles[i].fd = fd; | - |
384 | handles[i].flags = flags; | - |
385 | handles[i].name = xstrdup(name); | - |
386 | handles[i].bytes_read = handles[i].bytes_write = 0; | - |
387 | | - |
388 | return never executed: return i; i;never executed: return i; | 0 |
389 | } | - |
390 | | - |
391 | static int | - |
392 | handle_is_ok(int i, int type) | - |
393 | { | - |
394 | return never executed: return i >= 0 && (u_int)i < num_handles && handles[i].use == type; i >= 0TRUE | never evaluated | FALSE | never evaluated |
&& (TRUE | never evaluated | FALSE | never evaluated |
u_int)i < num_handlesTRUE | never evaluated | FALSE | never evaluated |
&& handles[i].use == typeTRUE | never evaluated | FALSE | never evaluated |
;never executed: return i >= 0 && (u_int)i < num_handles && handles[i].use == type; | 0 |
395 | } | - |
396 | | - |
397 | static int | - |
398 | handle_to_string(int handle, u_char **stringp, int *hlenp) | - |
399 | { | - |
400 | if (stringp == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
401 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
402 | || hlenp == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
403 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
404 | ) | - |
405 | return never executed: return -1; -1;never executed: return -1; | 0 |
406 | *stringp = xmalloc(sizeof(int32_t)); | - |
407 | put_u32(*stringp, handle); | - |
408 | *hlenp = sizeof(int32_t); | - |
409 | return never executed: return 0; 0;never executed: return 0; | 0 |
410 | } | - |
411 | | - |
412 | static int | - |
413 | handle_from_string(const u_char *handle, u_int hlen) | - |
414 | { | - |
415 | int val; | - |
416 | | - |
417 | if (hlen != sizeof(int32_t)TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
418 | return never executed: return -1; -1;never executed: return -1; | 0 |
419 | val = get_u32(handle); | - |
420 | if (handle_is_ok(val, HANDLE_FILE)TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
421 | handle_is_ok(val, HANDLE_DIR)TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
422 | return never executed: return val; val;never executed: return val; | 0 |
423 | return never executed: return -1; -1;never executed: return -1; | 0 |
424 | } | - |
425 | | - |
426 | static char * | - |
427 | handle_to_name(int handle) | - |
428 | { | - |
429 | if (handle_is_ok(handle, HANDLE_DIR)TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
430 | handle_is_ok(handle, HANDLE_FILE)TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
431 | return never executed: return handles[handle].name; handles[handle].name;never executed: return handles[handle].name; | 0 |
432 | return never executed: return ((void *)0) ; never executed: return ((void *)0) ; | 0 |
433 | ((void *)0) never executed: return ((void *)0) ; | 0 |
434 | ; never executed: return ((void *)0) ; | 0 |
435 | } | - |
436 | | - |
437 | static DIR * | - |
438 | handle_to_dir(int handle) | - |
439 | { | - |
440 | if (handle_is_ok(handle, HANDLE_DIR)TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
441 | return never executed: return handles[handle].dirp; handles[handle].dirp;never executed: return handles[handle].dirp; | 0 |
442 | return never executed: return ((void *)0) ; never executed: return ((void *)0) ; | 0 |
443 | ((void *)0) never executed: return ((void *)0) ; | 0 |
444 | ; never executed: return ((void *)0) ; | 0 |
445 | } | - |
446 | | - |
447 | static int | - |
448 | handle_to_fd(int handle) | - |
449 | { | - |
450 | if (handle_is_ok(handle, HANDLE_FILE)TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
451 | return never executed: return handles[handle].fd; handles[handle].fd;never executed: return handles[handle].fd; | 0 |
452 | return never executed: return -1; -1;never executed: return -1; | 0 |
453 | } | - |
454 | | - |
455 | static int | - |
456 | handle_to_flags(int handle) | - |
457 | { | - |
458 | if (handle_is_ok(handle, HANDLE_FILE)TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
459 | return never executed: return handles[handle].flags; handles[handle].flags;never executed: return handles[handle].flags; | 0 |
460 | return never executed: return 0; 0;never executed: return 0; | 0 |
461 | } | - |
462 | | - |
463 | static void | - |
464 | handle_update_read(int handle, ssize_t bytes) | - |
465 | { | - |
466 | if (handle_is_ok(handle, HANDLE_FILE)TRUE | never evaluated | FALSE | never evaluated |
&& bytes > 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
467 | handles[handle].bytes_read += bytes; never executed: handles[handle].bytes_read += bytes; | 0 |
468 | } never executed: end of block | 0 |
469 | | - |
470 | static void | - |
471 | handle_update_write(int handle, ssize_t bytes) | - |
472 | { | - |
473 | if (handle_is_ok(handle, HANDLE_FILE)TRUE | never evaluated | FALSE | never evaluated |
&& bytes > 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
474 | handles[handle].bytes_write += bytes; never executed: handles[handle].bytes_write += bytes; | 0 |
475 | } never executed: end of block | 0 |
476 | | - |
477 | static u_int64_t | - |
478 | handle_bytes_read(int handle) | - |
479 | { | - |
480 | if (handle_is_ok(handle, HANDLE_FILE)TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
481 | return never executed: return (handles[handle].bytes_read); (handles[handle].bytes_read);never executed: return (handles[handle].bytes_read); | 0 |
482 | return never executed: return 0; 0;never executed: return 0; | 0 |
483 | } | - |
484 | | - |
485 | static u_int64_t | - |
486 | handle_bytes_write(int handle) | - |
487 | { | - |
488 | if (handle_is_ok(handle, HANDLE_FILE)TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
489 | return never executed: return (handles[handle].bytes_write); (handles[handle].bytes_write);never executed: return (handles[handle].bytes_write); | 0 |
490 | return never executed: return 0; 0;never executed: return 0; | 0 |
491 | } | - |
492 | | - |
493 | static int | - |
494 | handle_close(int handle) | - |
495 | { | - |
496 | int ret = -1; | - |
497 | | - |
498 | if (handle_is_ok(handle, HANDLE_FILE)TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
499 | ret = close(handles[handle].fd); | - |
500 | free(handles[handle].name); | - |
501 | handle_unused(handle); | - |
502 | } never executed: end of block else if (handle_is_ok(handle, HANDLE_DIR)TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
503 | ret = closedir(handles[handle].dirp); | - |
504 | free(handles[handle].name); | - |
505 | handle_unused(handle); | - |
506 | } never executed: end of block else { | 0 |
507 | | - |
508 | (*__errno_location ()) | - |
509 | = | - |
510 | 2 | - |
511 | ; | - |
512 | } never executed: end of block | 0 |
513 | return never executed: return ret; ret;never executed: return ret; | 0 |
514 | } | - |
515 | | - |
516 | static void | - |
517 | handle_log_close(int handle, char *emsg) | - |
518 | { | - |
519 | if (handle_is_ok(handle, HANDLE_FILE)TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
520 | logit("%s%sclose \"%s\" bytes read %llu written %llu", | - |
521 | emsg == | - |
522 | ((void *)0) | - |
523 | ? "" : emsg, emsg == | - |
524 | ((void *)0) | - |
525 | ? "" : " ", | - |
526 | handle_to_name(handle), | - |
527 | (unsigned long long)handle_bytes_read(handle), | - |
528 | (unsigned long long)handle_bytes_write(handle)); | - |
529 | } never executed: end of block else { | 0 |
530 | logit("%s%sclosedir \"%s\"", | - |
531 | emsg == | - |
532 | ((void *)0) | - |
533 | ? "" : emsg, emsg == | - |
534 | ((void *)0) | - |
535 | ? "" : " ", | - |
536 | handle_to_name(handle)); | - |
537 | } never executed: end of block | 0 |
538 | } | - |
539 | | - |
540 | static void | - |
541 | handle_log_exit(void) | - |
542 | { | - |
543 | u_int i; | - |
544 | | - |
545 | for (i = 0; i < num_handlesTRUE | never evaluated | FALSE | never evaluated |
; i++) | 0 |
546 | if (handles[i].use != HANDLE_UNUSEDTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
547 | handle_log_close(i, "forced"); never executed: handle_log_close(i, "forced"); | 0 |
548 | } never executed: end of block | 0 |
549 | | - |
550 | static int | - |
551 | get_handle(struct sshbuf *queue, int *hp) | - |
552 | { | - |
553 | u_char *handle; | - |
554 | int r; | - |
555 | size_t hlen; | - |
556 | | - |
557 | *hp = -1; | - |
558 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_string(queue, &handle, &hlen)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
559 | return never executed: return r; r;never executed: return r; | 0 |
560 | if (hlen < 256TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
561 | * never executed: *hp = handle_from_string(handle, hlen); hp = handle_from_string(handle, hlen);never executed: *hp = handle_from_string(handle, hlen); | 0 |
562 | free(handle); | - |
563 | return never executed: return 0; 0;never executed: return 0; | 0 |
564 | } | - |
565 | | - |
566 | | - |
567 | | - |
568 | static void | - |
569 | send_msg(struct sshbuf *m) | - |
570 | { | - |
571 | int r; | - |
572 | | - |
573 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_stringb(oqueue, m)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
574 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
575 | sshbuf_reset(m); | - |
576 | } never executed: end of block | 0 |
577 | | - |
578 | static const char * | - |
579 | status_to_message(u_int32_t status) | - |
580 | { | - |
581 | const char *status_messages[] = { | - |
582 | "Success", | - |
583 | "End of file", | - |
584 | "No such file", | - |
585 | "Permission denied", | - |
586 | "Failure", | - |
587 | "Bad message", | - |
588 | "No connection", | - |
589 | "Connection lost", | - |
590 | "Operation unsupported", | - |
591 | "Unknown error" | - |
592 | }; | - |
593 | return never executed: return (status_messages[(((status) < (8)) ? (status) : (8))]); (status_messages[(((status) < (8)) ? (status) : (8))]);never executed: return (status_messages[(((status) < (8)) ? (status) : (8))]); | 0 |
594 | } | - |
595 | | - |
596 | static void | - |
597 | send_status(u_int32_t id, u_int32_t status) | - |
598 | { | - |
599 | struct sshbuf *msg; | - |
600 | int r; | - |
601 | | - |
602 | debug3("request %u: sent status %u", id, status); | - |
603 | if (log_level > SYSLOG_LEVEL_VERBOSETRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
604 | (status != 0TRUE | never evaluated | FALSE | never evaluated |
&& status != 1TRUE | never evaluated | FALSE | never evaluated |
)) | 0 |
605 | logit("sent status %s", status_to_message(status)); never executed: logit("sent status %s", status_to_message(status)); | 0 |
606 | if ((TRUE | never evaluated | FALSE | never evaluated |
msg = sshbuf_new()) == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
607 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
608 | ) | - |
609 | fatal("%s: sshbuf_new failed", __func__); never executed: fatal("%s: sshbuf_new failed", __func__); | 0 |
610 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u8(msg, 101)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
611 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u32(msg, id)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
612 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u32(msg, status)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
613 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
614 | if (version >= 3TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
615 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
616 | status_to_message(status))) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
617 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, "")) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
618 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
619 | } never executed: end of block | 0 |
620 | send_msg(msg); | - |
621 | sshbuf_free(msg); | - |
622 | } never executed: end of block | 0 |
623 | static void | - |
624 | send_data_or_handle(char type, u_int32_t id, const u_char *data, int dlen) | - |
625 | { | - |
626 | struct sshbuf *msg; | - |
627 | int r; | - |
628 | | - |
629 | if ((TRUE | never evaluated | FALSE | never evaluated |
msg = sshbuf_new()) == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
630 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
631 | ) | - |
632 | fatal("%s: sshbuf_new failed", __func__); never executed: fatal("%s: sshbuf_new failed", __func__); | 0 |
633 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u8(msg, type)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
634 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u32(msg, id)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
635 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_string(msg, data, dlen)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
636 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
637 | send_msg(msg); | - |
638 | sshbuf_free(msg); | - |
639 | } never executed: end of block | 0 |
640 | | - |
641 | static void | - |
642 | send_data(u_int32_t id, const u_char *data, int dlen) | - |
643 | { | - |
644 | debug("request %u: sent data len %d", id, dlen); | - |
645 | send_data_or_handle(103, id, data, dlen); | - |
646 | } never executed: end of block | 0 |
647 | | - |
648 | static void | - |
649 | send_handle(u_int32_t id, int handle) | - |
650 | { | - |
651 | u_char *string; | - |
652 | int hlen; | - |
653 | | - |
654 | handle_to_string(handle, &string, &hlen); | - |
655 | debug("request %u: sent handle handle %d", id, handle); | - |
656 | send_data_or_handle(102, id, string, hlen); | - |
657 | free(string); | - |
658 | } never executed: end of block | 0 |
659 | | - |
660 | static void | - |
661 | send_names(u_int32_t id, int count, const Stat *stats) | - |
662 | { | - |
663 | struct sshbuf *msg; | - |
664 | int i, r; | - |
665 | | - |
666 | if ((TRUE | never evaluated | FALSE | never evaluated |
msg = sshbuf_new()) == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
667 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
668 | ) | - |
669 | fatal("%s: sshbuf_new failed", __func__); never executed: fatal("%s: sshbuf_new failed", __func__); | 0 |
670 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u8(msg, 104)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
671 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u32(msg, id)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
672 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u32(msg, count)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
673 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
674 | debug("request %u: sent names count %d", id, count); | - |
675 | for (i = 0; i < countTRUE | never evaluated | FALSE | never evaluated |
; i++) { | 0 |
676 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, stats[i].name)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
677 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, stats[i].long_name)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
678 | (TRUE | never evaluated | FALSE | never evaluated |
r = encode_attrib(msg, &stats[i].attrib)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
679 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
680 | } never executed: end of block | 0 |
681 | send_msg(msg); | - |
682 | sshbuf_free(msg); | - |
683 | } never executed: end of block | 0 |
684 | | - |
685 | static void | - |
686 | send_attrib(u_int32_t id, const Attrib *a) | - |
687 | { | - |
688 | struct sshbuf *msg; | - |
689 | int r; | - |
690 | | - |
691 | debug("request %u: sent attrib have 0x%x", id, a->flags); | - |
692 | if ((TRUE | never evaluated | FALSE | never evaluated |
msg = sshbuf_new()) == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
693 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
694 | ) | - |
695 | fatal("%s: sshbuf_new failed", __func__); never executed: fatal("%s: sshbuf_new failed", __func__); | 0 |
696 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u8(msg, 105)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
697 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u32(msg, id)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
698 | (TRUE | never evaluated | FALSE | never evaluated |
r = encode_attrib(msg, a)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
699 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
700 | send_msg(msg); | - |
701 | sshbuf_free(msg); | - |
702 | } never executed: end of block | 0 |
703 | | - |
704 | static void | - |
705 | send_statvfs(u_int32_t id, struct statvfs *st) | - |
706 | { | - |
707 | struct sshbuf *msg; | - |
708 | u_int64_t flag; | - |
709 | int r; | - |
710 | | - |
711 | flag = (TRUE | never evaluated | FALSE | never evaluated |
st->f_flag & TRUE | never evaluated | FALSE | never evaluated |
| 0 |
712 | ST_RDONLYTRUE | never evaluated | FALSE | never evaluated |
| 0 |
713 | )TRUE | never evaluated | FALSE | never evaluated |
? 0x00000001 : 0; | 0 |
714 | flag |= (TRUE | never evaluated | FALSE | never evaluated |
st->f_flag & TRUE | never evaluated | FALSE | never evaluated |
| 0 |
715 | ST_NOSUIDTRUE | never evaluated | FALSE | never evaluated |
| 0 |
716 | )TRUE | never evaluated | FALSE | never evaluated |
? 0x00000002 : 0; | 0 |
717 | | - |
718 | if ((TRUE | never evaluated | FALSE | never evaluated |
msg = sshbuf_new()) == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
719 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
720 | ) | - |
721 | fatal("%s: sshbuf_new failed", __func__); never executed: fatal("%s: sshbuf_new failed", __func__); | 0 |
722 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u8(msg, 201)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
723 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u32(msg, id)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
724 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u64(msg, st->f_bsize)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
725 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u64(msg, st->f_frsize)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
726 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u64(msg, st->f_blocks)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
727 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u64(msg, st->f_bfree)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
728 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u64(msg, st->f_bavail)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
729 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u64(msg, st->f_files)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
730 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u64(msg, st->f_ffree)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
731 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u64(msg, st->f_favail)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
732 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u64(msg, ((st->f_fsid)))) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
733 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u64(msg, flag)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
734 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u64(msg, st->f_namemax)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
735 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
736 | send_msg(msg); | - |
737 | sshbuf_free(msg); | - |
738 | } never executed: end of block | 0 |
739 | | - |
740 | | - |
741 | | - |
742 | static void | - |
743 | process_init(void) | - |
744 | { | - |
745 | struct sshbuf *msg; | - |
746 | int r; | - |
747 | | - |
748 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_u32(iqueue, &version)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
749 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
750 | verbose("received client version %u", version); | - |
751 | if ((TRUE | never evaluated | FALSE | never evaluated |
msg = sshbuf_new()) == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
752 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
753 | ) | - |
754 | fatal("%s: sshbuf_new failed", __func__); never executed: fatal("%s: sshbuf_new failed", __func__); | 0 |
755 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u8(msg, 2)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
756 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_u32(msg, 3)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
757 | | - |
758 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, "posix-rename@openssh.com")) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
759 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, "1")) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
760 | | - |
761 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
762 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, "2")) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
763 | | - |
764 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
765 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, "2")) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
766 | | - |
767 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
768 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, "1")) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
769 | | - |
770 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
771 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put_cstring(msg, "1")) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
772 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
773 | send_msg(msg); | - |
774 | sshbuf_free(msg); | - |
775 | } never executed: end of block | 0 |
776 | | - |
777 | static void | - |
778 | process_open(u_int32_t id) | - |
779 | { | - |
780 | u_int32_t pflags; | - |
781 | Attrib a; | - |
782 | char *name; | - |
783 | int r, handle, fd, flags, mode, status = 4; | - |
784 | | - |
785 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &name, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
786 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
787 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
788 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_u32(iqueue, &pflags)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
789 | (TRUE | never evaluated | FALSE | never evaluated |
r = decode_attrib(iqueue, &a)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
790 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
791 | | - |
792 | debug3("request %u: open flags %d", id, pflags); | - |
793 | flags = flags_from_portable(pflags); | - |
794 | mode = (TRUE | never evaluated | FALSE | never evaluated |
a.flags & 0x00000004)TRUE | never evaluated | FALSE | never evaluated |
? a.perm : 0666; | 0 |
795 | logit("open \"%s\" flags %s mode 0%o", | - |
796 | name, string_from_portable(pflags), mode); | - |
797 | if (readonlyTRUE | never evaluated | FALSE | never evaluated |
&& | 0 |
798 | ((TRUE | never evaluated | FALSE | never evaluated |
flags & TRUE | never evaluated | FALSE | never evaluated |
| 0 |
799 | 0003TRUE | never evaluated | FALSE | never evaluated |
| 0 |
800 | ) != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
801 | 00TRUE | never evaluated | FALSE | never evaluated |
| 0 |
802 | || | - |
803 | (TRUE | never evaluated | FALSE | never evaluated |
flags & (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
804 | 0100TRUE | never evaluated | FALSE | never evaluated |
| 0 |
805 | |TRUE | never evaluated | FALSE | never evaluated |
| 0 |
806 | 01000TRUE | never evaluated | FALSE | never evaluated |
| 0 |
807 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
)) { | 0 |
808 | verbose("Refusing open request in read-only mode"); | - |
809 | status = 3; | - |
810 | } never executed: end of block else { | 0 |
811 | fd = open(name, flags, mode); | - |
812 | if (fd < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
813 | status = errno_to_portable( | - |
814 | (*__errno_location ()) | - |
815 | ); | - |
816 | } never executed: end of block else { | 0 |
817 | handle = handle_new(HANDLE_FILE, name, fd, flags, | - |
818 | ((void *)0) | - |
819 | ); | - |
820 | if (handle < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
821 | close(fd); | - |
822 | } never executed: end of block else { | 0 |
823 | send_handle(id, handle); | - |
824 | status = 0; | - |
825 | } never executed: end of block | 0 |
826 | } | - |
827 | } | - |
828 | if (status != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
829 | send_status(id, status); never executed: send_status(id, status); | 0 |
830 | free(name); | - |
831 | } never executed: end of block | 0 |
832 | | - |
833 | static void | - |
834 | process_close(u_int32_t id) | - |
835 | { | - |
836 | int r, handle, ret, status = 4; | - |
837 | | - |
838 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = get_handle(iqueue, &handle)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
839 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
840 | | - |
841 | debug3("request %u: close handle %u", id, handle); | - |
842 | handle_log_close(handle, | - |
843 | ((void *)0) | - |
844 | ); | - |
845 | ret = handle_close(handle); | - |
846 | status = (TRUE | never evaluated | FALSE | never evaluated |
ret == -1)TRUE | never evaluated | FALSE | never evaluated |
? errno_to_portable( | 0 |
847 | (*__errno_location ()) | - |
848 | ) : 0; | - |
849 | send_status(id, status); | - |
850 | } never executed: end of block | 0 |
851 | | - |
852 | static void | - |
853 | process_read(u_int32_t id) | - |
854 | { | - |
855 | u_char buf[64*1024]; | - |
856 | u_int32_t len; | - |
857 | int r, handle, fd, ret, status = 4; | - |
858 | u_int64_t off; | - |
859 | | - |
860 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = get_handle(iqueue, &handle)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
861 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_u64(iqueue, &off)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
862 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_u32(iqueue, &len)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
863 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
864 | | - |
865 | debug("request %u: read \"%s\" (handle %d) off %llu len %d", | - |
866 | id, handle_to_name(handle), handle, (unsigned long long)off, len); | - |
867 | if (len > sizeof bufTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
868 | len = sizeof buf; | - |
869 | debug2("read change len %d", len); | - |
870 | } never executed: end of block | 0 |
871 | fd = handle_to_fd(handle); | - |
872 | if (fd >= 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
873 | if (lseek(fd, off, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
874 | 0TRUE | never evaluated | FALSE | never evaluated |
| 0 |
875 | ) < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
876 | error("process_read: seek failed"); | - |
877 | status = errno_to_portable( | - |
878 | (*__errno_location ()) | - |
879 | ); | - |
880 | } never executed: end of block else { | 0 |
881 | ret = read(fd, buf, len); | - |
882 | if (ret < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
883 | status = errno_to_portable( | - |
884 | (*__errno_location ()) | - |
885 | ); | - |
886 | } never executed: end of block else if (ret == 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
887 | status = 1; | - |
888 | } never executed: end of block else { | 0 |
889 | send_data(id, buf, ret); | - |
890 | status = 0; | - |
891 | handle_update_read(handle, ret); | - |
892 | } never executed: end of block | 0 |
893 | } | - |
894 | } | - |
895 | if (status != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
896 | send_status(id, status); never executed: send_status(id, status); | 0 |
897 | } never executed: end of block | 0 |
898 | | - |
899 | static void | - |
900 | process_write(u_int32_t id) | - |
901 | { | - |
902 | u_int64_t off; | - |
903 | size_t len; | - |
904 | int r, handle, fd, ret, status; | - |
905 | u_char *data; | - |
906 | | - |
907 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = get_handle(iqueue, &handle)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
908 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_u64(iqueue, &off)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
909 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_string(iqueue, &data, &len)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
910 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
911 | | - |
912 | debug("request %u: write \"%s\" (handle %d) off %llu len %zu", | - |
913 | id, handle_to_name(handle), handle, (unsigned long long)off, len); | - |
914 | fd = handle_to_fd(handle); | - |
915 | | - |
916 | if (fd < 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
917 | status = 4; never executed: status = 4; | 0 |
918 | else { | - |
919 | if (!(handle_to_flags(handle) & TRUE | never evaluated | FALSE | never evaluated |
| 0 |
920 | 02000TRUE | never evaluated | FALSE | never evaluated |
| 0 |
921 | )TRUE | never evaluated | FALSE | never evaluated |
&& | 0 |
922 | lseek(fd, off, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
923 | 0TRUE | never evaluated | FALSE | never evaluated |
| 0 |
924 | ) < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
925 | status = errno_to_portable( | - |
926 | (*__errno_location ()) | - |
927 | ); | - |
928 | error("process_write: seek failed"); | - |
929 | } never executed: end of block else { | 0 |
930 | | - |
931 | ret = write(fd, data, len); | - |
932 | if (ret < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
933 | error("process_write: write failed"); | - |
934 | status = errno_to_portable( | - |
935 | (*__errno_location ()) | - |
936 | ); | - |
937 | } never executed: end of block else if ((TRUE | never evaluated | FALSE | never evaluated |
size_t)ret == lenTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
938 | status = 0; | - |
939 | handle_update_write(handle, ret); | - |
940 | } never executed: end of block else { | 0 |
941 | debug2("nothing at all written"); | - |
942 | status = 4; | - |
943 | } never executed: end of block | 0 |
944 | } | - |
945 | } | - |
946 | send_status(id, status); | - |
947 | free(data); | - |
948 | } never executed: end of block | 0 |
949 | | - |
950 | static void | - |
951 | process_do_stat(u_int32_t id, int do_lstat) | - |
952 | { | - |
953 | Attrib a; | - |
954 | struct stat st; | - |
955 | char *name; | - |
956 | int r, status = 4; | - |
957 | | - |
958 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &name, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
959 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
960 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
961 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
962 | | - |
963 | debug3("request %u: %sstat", id, do_lstat ? "l" : ""); | - |
964 | verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name); | - |
965 | r = do_lstatTRUE | never evaluated | FALSE | never evaluated |
? lstat(name, &st) : stat(name, &st); | 0 |
966 | if (r < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
967 | status = errno_to_portable( | - |
968 | (*__errno_location ()) | - |
969 | ); | - |
970 | } never executed: end of block else { | 0 |
971 | stat_to_attrib(&st, &a); | - |
972 | send_attrib(id, &a); | - |
973 | status = 0; | - |
974 | } never executed: end of block | 0 |
975 | if (status != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
976 | send_status(id, status); never executed: send_status(id, status); | 0 |
977 | free(name); | - |
978 | } never executed: end of block | 0 |
979 | | - |
980 | static void | - |
981 | process_stat(u_int32_t id) | - |
982 | { | - |
983 | process_do_stat(id, 0); | - |
984 | } never executed: end of block | 0 |
985 | | - |
986 | static void | - |
987 | process_lstat(u_int32_t id) | - |
988 | { | - |
989 | process_do_stat(id, 1); | - |
990 | } never executed: end of block | 0 |
991 | | - |
992 | static void | - |
993 | process_fstat(u_int32_t id) | - |
994 | { | - |
995 | Attrib a; | - |
996 | struct stat st; | - |
997 | int fd, r, handle, status = 4; | - |
998 | | - |
999 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = get_handle(iqueue, &handle)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1000 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1001 | debug("request %u: fstat \"%s\" (handle %u)", | - |
1002 | id, handle_to_name(handle), handle); | - |
1003 | fd = handle_to_fd(handle); | - |
1004 | if (fd >= 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1005 | r = fstat(fd, &st); | - |
1006 | if (r < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1007 | status = errno_to_portable( | - |
1008 | (*__errno_location ()) | - |
1009 | ); | - |
1010 | } never executed: end of block else { | 0 |
1011 | stat_to_attrib(&st, &a); | - |
1012 | send_attrib(id, &a); | - |
1013 | status = 0; | - |
1014 | } never executed: end of block | 0 |
1015 | } | - |
1016 | if (status != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1017 | send_status(id, status); never executed: send_status(id, status); | 0 |
1018 | } never executed: end of block | 0 |
1019 | | - |
1020 | static struct timeval * | - |
1021 | attrib_to_tv(const Attrib *a) | - |
1022 | { | - |
1023 | static struct timeval tv[2]; | - |
1024 | | - |
1025 | tv[0].tv_sec = a->atime; | - |
1026 | tv[0].tv_usec = 0; | - |
1027 | tv[1].tv_sec = a->mtime; | - |
1028 | tv[1].tv_usec = 0; | - |
1029 | return never executed: return tv; tv;never executed: return tv; | 0 |
1030 | } | - |
1031 | | - |
1032 | static void | - |
1033 | process_setstat(u_int32_t id) | - |
1034 | { | - |
1035 | Attrib a; | - |
1036 | char *name; | - |
1037 | int r, status = 0; | - |
1038 | | - |
1039 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &name, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1040 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1041 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
1042 | (TRUE | never evaluated | FALSE | never evaluated |
r = decode_attrib(iqueue, &a)) != 0TRUE | never evaluated | FALSE | never 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: setstat name \"%s\"", id, name); | - |
1046 | if (a.flags & 0x00000001TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1047 | logit("set \"%s\" size %llu", | - |
1048 | name, (unsigned long long)a.size); | - |
1049 | r = truncate(name, a.size); | - |
1050 | if (r == -1TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1051 | status = errno_to_portable( never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1052 | (*__errno_location ()) never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1053 | ); never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1054 | } never executed: end of block | 0 |
1055 | if (a.flags & 0x00000004TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1056 | logit("set \"%s\" mode %04o", name, a.perm); | - |
1057 | r = chmod(name, a.perm & 07777); | - |
1058 | if (r == -1TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1059 | status = errno_to_portable( never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1060 | (*__errno_location ()) never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1061 | ); never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1062 | } never executed: end of block | 0 |
1063 | if (a.flags & 0x00000008TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1064 | char buf[64]; | - |
1065 | time_t t = a.mtime; | - |
1066 | | - |
1067 | strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S", | - |
1068 | localtime(&t)); | - |
1069 | logit("set \"%s\" modtime %s", name, buf); | - |
1070 | r = utimes(name, attrib_to_tv(&a)); | - |
1071 | if (r == -1TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1072 | status = errno_to_portable( never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1073 | (*__errno_location ()) never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1074 | ); never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1075 | } never executed: end of block | 0 |
1076 | if (a.flags & 0x00000002TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1077 | logit("set \"%s\" owner %lu group %lu", name, | - |
1078 | (u_long)a.uid, (u_long)a.gid); | - |
1079 | r = chown(name, a.uid, a.gid); | - |
1080 | if (r == -1TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1081 | status = errno_to_portable( never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1082 | (*__errno_location ()) never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1083 | ); never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1084 | } never executed: end of block | 0 |
1085 | send_status(id, status); | - |
1086 | free(name); | - |
1087 | } never executed: end of block | 0 |
1088 | | - |
1089 | static void | - |
1090 | process_fsetstat(u_int32_t id) | - |
1091 | { | - |
1092 | Attrib a; | - |
1093 | int handle, fd, r; | - |
1094 | int status = 0; | - |
1095 | | - |
1096 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = get_handle(iqueue, &handle)) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
1097 | (TRUE | never evaluated | FALSE | never evaluated |
r = decode_attrib(iqueue, &a)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1098 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1099 | | - |
1100 | debug("request %u: fsetstat handle %d", id, handle); | - |
1101 | fd = handle_to_fd(handle); | - |
1102 | if (fd < 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1103 | status = 4; never executed: status = 4; | 0 |
1104 | else { | - |
1105 | char *name = handle_to_name(handle); | - |
1106 | | - |
1107 | if (a.flags & 0x00000001TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1108 | logit("set \"%s\" size %llu", | - |
1109 | name, (unsigned long long)a.size); | - |
1110 | r = ftruncate(fd, a.size); | - |
1111 | if (r == -1TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1112 | status = errno_to_portable( never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1113 | (*__errno_location ()) never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1114 | ); never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1115 | } never executed: end of block | 0 |
1116 | if (a.flags & 0x00000004TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1117 | logit("set \"%s\" mode %04o", name, a.perm); | - |
1118 | | - |
1119 | r = fchmod(fd, a.perm & 07777); | - |
1120 | | - |
1121 | | - |
1122 | | - |
1123 | if (r == -1TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1124 | status = errno_to_portable( never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1125 | (*__errno_location ()) never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1126 | ); never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1127 | } never executed: end of block | 0 |
1128 | if (a.flags & 0x00000008TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1129 | char buf[64]; | - |
1130 | time_t t = a.mtime; | - |
1131 | | - |
1132 | strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S", | - |
1133 | localtime(&t)); | - |
1134 | logit("set \"%s\" modtime %s", name, buf); | - |
1135 | | - |
1136 | r = futimes(fd, attrib_to_tv(&a)); | - |
1137 | | - |
1138 | | - |
1139 | | - |
1140 | if (r == -1TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1141 | status = errno_to_portable( never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1142 | (*__errno_location ()) never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1143 | ); never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1144 | } never executed: end of block | 0 |
1145 | if (a.flags & 0x00000002TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1146 | logit("set \"%s\" owner %lu group %lu", name, | - |
1147 | (u_long)a.uid, (u_long)a.gid); | - |
1148 | | - |
1149 | r = fchown(fd, a.uid, a.gid); | - |
1150 | | - |
1151 | | - |
1152 | | - |
1153 | if (r == -1TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1154 | status = errno_to_portable( never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1155 | (*__errno_location ()) never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1156 | ); never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1157 | } never executed: end of block | 0 |
1158 | } never executed: end of block | 0 |
1159 | send_status(id, status); | - |
1160 | } never executed: end of block | 0 |
1161 | | - |
1162 | static void | - |
1163 | process_opendir(u_int32_t id) | - |
1164 | { | - |
1165 | DIR *dirp = | - |
1166 | ((void *)0) | - |
1167 | ; | - |
1168 | char *path; | - |
1169 | int r, handle, status = 4; | - |
1170 | | - |
1171 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &path, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1172 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1173 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1174 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1175 | | - |
1176 | debug3("request %u: opendir", id); | - |
1177 | logit("opendir \"%s\"", path); | - |
1178 | dirp = opendir(path); | - |
1179 | if (dirp == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1180 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1181 | ) { | - |
1182 | status = errno_to_portable( | - |
1183 | (*__errno_location ()) | - |
1184 | ); | - |
1185 | } never executed: end of block else { | 0 |
1186 | handle = handle_new(HANDLE_DIR, path, 0, 0, dirp); | - |
1187 | if (handle < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1188 | closedir(dirp); | - |
1189 | } never executed: end of block else { | 0 |
1190 | send_handle(id, handle); | - |
1191 | status = 0; | - |
1192 | } never executed: end of block | 0 |
1193 | | - |
1194 | } | - |
1195 | if (status != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1196 | send_status(id, status); never executed: send_status(id, status); | 0 |
1197 | free(path); | - |
1198 | } never executed: end of block | 0 |
1199 | | - |
1200 | static void | - |
1201 | process_readdir(u_int32_t id) | - |
1202 | { | - |
1203 | DIR *dirp; | - |
1204 | struct dirent *dp; | - |
1205 | char *path; | - |
1206 | int r, handle; | - |
1207 | | - |
1208 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = get_handle(iqueue, &handle)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1209 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1210 | | - |
1211 | debug("request %u: readdir \"%s\" (handle %d)", id, | - |
1212 | handle_to_name(handle), handle); | - |
1213 | dirp = handle_to_dir(handle); | - |
1214 | path = handle_to_name(handle); | - |
1215 | if (dirp == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1216 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1217 | || path == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1218 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1219 | ) { | - |
1220 | send_status(id, 4); | - |
1221 | } never executed: end of block else { | 0 |
1222 | struct stat st; | - |
1223 | char pathname[ | - |
1224 | 4096 | - |
1225 | ]; | - |
1226 | Stat *stats; | - |
1227 | int nstats = 10, count = 0, i; | - |
1228 | | - |
1229 | stats = xcalloc(nstats, sizeof(Stat)); | - |
1230 | while ((TRUE | never evaluated | FALSE | never evaluated |
dp = readdir(dirp)) != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1231 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1232 | ) { | - |
1233 | if (count >= nstatsTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1234 | nstats *= 2; | - |
1235 | stats = xreallocarray(stats, nstats, sizeof(Stat)); | - |
1236 | } never executed: end of block | 0 |
1237 | | - |
1238 | snprintf(pathname, sizeof pathname, "%s%s%s", path, | - |
1239 | | - |
1240 | __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ( | - |
1241 | path | - |
1242 | ) && __builtin_constant_p ( | - |
1243 | "/" | - |
1244 | ) && (__s1_len = __builtin_strlen ( | - |
1245 | path | - |
1246 | ), __s2_len = __builtin_strlen ( | - |
1247 | "/" | - |
1248 | ), (!((size_t)(const void *)(( | - |
1249 | path | - |
1250 | ) + 1) - (size_t)(const void *)( | - |
1251 | path | - |
1252 | ) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(( | - |
1253 | "/" | - |
1254 | ) + 1) - (size_t)(const void *)( | - |
1255 | "/" | - |
1256 | ) == 1) || __s2_len >= 4)) ? __builtin_strcmp ( | - |
1257 | path | - |
1258 | , | - |
1259 | "/" | - |
1260 | ) : (__builtin_constant_p ( | - |
1261 | path | - |
1262 | ) && ((size_t)(const void *)(( | - |
1263 | path | - |
1264 | ) + 1) - (size_t)(const void *)( | - |
1265 | path | - |
1266 | ) == 1) && (__s1_len = __builtin_strlen ( | - |
1267 | path | - |
1268 | ), __s1_len < 4) ? (__builtin_constant_p ( | - |
1269 | "/" | - |
1270 | ) && ((size_t)(const void *)(( | - |
1271 | "/" | - |
1272 | ) + 1) - (size_t)(const void *)( | - |
1273 | "/" | - |
1274 | ) == 1) ? __builtin_strcmp ( | - |
1275 | path | - |
1276 | , | - |
1277 | "/" | - |
1278 | ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ( | - |
1279 | "/" | - |
1280 | ); int __result = (((const unsigned char *) (const char *) ( | - |
1281 | path | - |
1282 | ))[0] - __s2[0]); if (__s1_len > 0TRUE | never evaluated | FALSE | never evaluated |
&& __result == 0TRUE | never evaluated | FALSE | never evaluated |
) { __result = (((const unsigned char *) (const char *) ( | 0 |
1283 | path | - |
1284 | ))[1] - __s2[1]); if (__s1_len > 1TRUE | never evaluated | FALSE | never evaluated |
&& __result == 0TRUE | never evaluated | FALSE | never evaluated |
) { __result = (((const unsigned char *) (const char *) ( | 0 |
1285 | path | - |
1286 | ))[2] - __s2[2]); if (__s1_len > 2TRUE | never evaluated | FALSE | never evaluated |
&& __result == 0TRUE | never evaluated | FALSE | never evaluated |
) __result = (((const unsigned char *) (const char *) (never executed: __result = (((const unsigned char *) (const char *) ( path ))[3] - __s2[3]); | 0 |
1287 | path never executed: __result = (((const unsigned char *) (const char *) ( path ))[3] - __s2[3]); | 0 |
1288 | ))[3] - __s2[3]); never executed: __result = (((const unsigned char *) (const char *) ( path ))[3] - __s2[3]); }never executed: end of block }never executed: end of block __result; }))) : (__builtin_constant_p ( | 0 |
1289 | "/" | - |
1290 | ) && ((size_t)(const void *)(( | - |
1291 | "/" | - |
1292 | ) + 1) - (size_t)(const void *)( | - |
1293 | "/" | - |
1294 | ) == 1) && (__s2_len = __builtin_strlen ( | - |
1295 | "/" | - |
1296 | ), __s2_len < 4) ? (__builtin_constant_p ( | - |
1297 | path | - |
1298 | ) && ((size_t)(const void *)(( | - |
1299 | path | - |
1300 | ) + 1) - (size_t)(const void *)( | - |
1301 | path | - |
1302 | ) == 1) ? __builtin_strcmp ( | - |
1303 | path | - |
1304 | , | - |
1305 | "/" | - |
1306 | ) : -(__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ( | - |
1307 | path | - |
1308 | ); int __result = (((const unsigned char *) (const char *) ( | - |
1309 | "/" | - |
1310 | ))[0] - __s2[0]); if (__s2_len > 0TRUE | never evaluated | FALSE | never evaluated |
&& __result == 0TRUE | never evaluated | FALSE | never evaluated |
) { __result = (((const unsigned char *) (const char *) ( | 0 |
1311 | "/" | - |
1312 | ))[1] - __s2[1]); if (__s2_len > 1TRUE | never evaluated | FALSE | never evaluated |
&& __result == 0TRUE | never evaluated | FALSE | never evaluated |
) { __result = (((const unsigned char *) (const char *) ( | 0 |
1313 | "/" | - |
1314 | ))[2] - __s2[2]); if (__s2_len > 2TRUE | never evaluated | FALSE | never evaluated |
&& __result == 0TRUE | never evaluated | FALSE | never evaluated |
) __result = (((const unsigned char *) (const char *) (never executed: __result = (((const unsigned char *) (const char *) ( "/" ))[3] - __s2[3]); | 0 |
1315 | "/" never executed: __result = (((const unsigned char *) (const char *) ( "/" ))[3] - __s2[3]); | 0 |
1316 | ))[3] - __s2[3]); never executed: __result = (((const unsigned char *) (const char *) ( "/" ))[3] - __s2[3]); }never executed: end of block }never executed: end of block __result; }))) : __builtin_strcmp ( | 0 |
1317 | path | - |
1318 | , | - |
1319 | "/" | - |
1320 | )))); }) | - |
1321 | ? "/" : "", dp->d_name); | - |
1322 | if (lstat(pathname, &st) < 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1323 | continue; never executed: continue; | 0 |
1324 | stat_to_attrib(&st, &(stats[count].attrib)); | - |
1325 | stats[count].name = xstrdup(dp->d_name); | - |
1326 | stats[count].long_name = ls_file(dp->d_name, &st, 0, 0); | - |
1327 | count++; | - |
1328 | | - |
1329 | | - |
1330 | if (count == 100TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1331 | break; never executed: break; | 0 |
1332 | } never executed: end of block | 0 |
1333 | if (count > 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1334 | send_names(id, count, stats); | - |
1335 | for (i = 0; i < countTRUE | never evaluated | FALSE | never evaluated |
; i++) { | 0 |
1336 | free(stats[i].name); | - |
1337 | free(stats[i].long_name); | - |
1338 | } never executed: end of block | 0 |
1339 | } never executed: end of block else { | 0 |
1340 | send_status(id, 1); | - |
1341 | } never executed: end of block | 0 |
1342 | free(stats); | - |
1343 | } never executed: end of block | 0 |
1344 | } | - |
1345 | | - |
1346 | static void | - |
1347 | process_remove(u_int32_t id) | - |
1348 | { | - |
1349 | char *name; | - |
1350 | int r, status = 4; | - |
1351 | | - |
1352 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &name, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1353 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1354 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1355 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1356 | | - |
1357 | debug3("request %u: remove", id); | - |
1358 | logit("remove name \"%s\"", name); | - |
1359 | r = unlink(name); | - |
1360 | status = (TRUE | never evaluated | FALSE | never evaluated |
r == -1)TRUE | never evaluated | FALSE | never evaluated |
? errno_to_portable( | 0 |
1361 | (*__errno_location ()) | - |
1362 | ) : 0; | - |
1363 | send_status(id, status); | - |
1364 | free(name); | - |
1365 | } never executed: end of block | 0 |
1366 | | - |
1367 | static void | - |
1368 | process_mkdir(u_int32_t id) | - |
1369 | { | - |
1370 | Attrib a; | - |
1371 | char *name; | - |
1372 | int r, mode, status = 4; | - |
1373 | | - |
1374 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &name, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1375 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1376 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
1377 | (TRUE | never evaluated | FALSE | never evaluated |
r = decode_attrib(iqueue, &a)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1378 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1379 | | - |
1380 | mode = (TRUE | never evaluated | FALSE | never evaluated |
a.flags & 0x00000004)TRUE | never evaluated | FALSE | never evaluated |
? | 0 |
1381 | a.perm & 07777 : 0777; | - |
1382 | debug3("request %u: mkdir", id); | - |
1383 | logit("mkdir name \"%s\" mode 0%o", name, mode); | - |
1384 | r = mkdir(name, mode); | - |
1385 | status = (TRUE | never evaluated | FALSE | never evaluated |
r == -1)TRUE | never evaluated | FALSE | never evaluated |
? errno_to_portable( | 0 |
1386 | (*__errno_location ()) | - |
1387 | ) : 0; | - |
1388 | send_status(id, status); | - |
1389 | free(name); | - |
1390 | } never executed: end of block | 0 |
1391 | | - |
1392 | static void | - |
1393 | process_rmdir(u_int32_t id) | - |
1394 | { | - |
1395 | char *name; | - |
1396 | int r, status; | - |
1397 | | - |
1398 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &name, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1399 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1400 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1401 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1402 | | - |
1403 | debug3("request %u: rmdir", id); | - |
1404 | logit("rmdir name \"%s\"", name); | - |
1405 | r = rmdir(name); | - |
1406 | status = (TRUE | never evaluated | FALSE | never evaluated |
r == -1)TRUE | never evaluated | FALSE | never evaluated |
? errno_to_portable( | 0 |
1407 | (*__errno_location ()) | - |
1408 | ) : 0; | - |
1409 | send_status(id, status); | - |
1410 | free(name); | - |
1411 | } never executed: end of block | 0 |
1412 | | - |
1413 | static void | - |
1414 | process_realpath(u_int32_t id) | - |
1415 | { | - |
1416 | char resolvedname[ | - |
1417 | 4096 | - |
1418 | ]; | - |
1419 | char *path; | - |
1420 | int r; | - |
1421 | | - |
1422 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &path, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1423 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1424 | )) != 0TRUE | never evaluated | FALSE | never 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 | if (path[0] == '\0'TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1428 | free(path); | - |
1429 | path = xstrdup("."); | - |
1430 | } never executed: end of block | 0 |
1431 | debug3("request %u: realpath", id); | - |
1432 | verbose("realpath \"%s\"", path); | - |
1433 | if (_ssh_compat_realpath(path, resolvedname) == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1434 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1435 | ) { | - |
1436 | send_status(id, errno_to_portable( | - |
1437 | (*__errno_location ()) | - |
1438 | )); | - |
1439 | } never executed: end of block else { | 0 |
1440 | Stat s; | - |
1441 | attrib_clear(&s.attrib); | - |
1442 | s.name = s.long_name = resolvedname; | - |
1443 | send_names(id, 1, &s); | - |
1444 | } never executed: end of block | 0 |
1445 | free(path); | - |
1446 | } never executed: end of block | 0 |
1447 | | - |
1448 | static void | - |
1449 | process_rename(u_int32_t id) | - |
1450 | { | - |
1451 | char *oldpath, *newpath; | - |
1452 | int r, status; | - |
1453 | struct stat sb; | - |
1454 | | - |
1455 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &oldpath, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1456 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1457 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
1458 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &newpath, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1459 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1460 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1461 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1462 | | - |
1463 | debug3("request %u: rename", id); | - |
1464 | logit("rename old \"%s\" new \"%s\"", oldpath, newpath); | - |
1465 | status = 4; | - |
1466 | if (lstat(oldpath, &sb) == -1TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1467 | status = errno_to_portable( never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1468 | (*__errno_location ()) never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1469 | ); never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1470 | else if ( | - |
1471 | ((((TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1472 | sb.st_modeTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1473 | )) & 0170000) == (0100000))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1474 | ) { | - |
1475 | | - |
1476 | if (link(oldpath, newpath) == -1TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1477 | if ( | - |
1478 | (*TRUE | never evaluated | FALSE | never evaluated |
__errno_location ()) TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1479 | == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1480 | 95TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1481 | || | - |
1482 | (*TRUE | never evaluated | FALSE | never evaluated |
__errno_location ()) TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1483 | == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1484 | 38TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1485 | | - |
1486 | | - |
1487 | || | - |
1488 | (*TRUE | never evaluated | FALSE | never evaluated |
__errno_location ()) TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1489 | == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1490 | 18TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1491 | | - |
1492 | | - |
1493 | | - |
1494 | || | - |
1495 | (*TRUE | never evaluated | FALSE | never evaluated |
__errno_location ()) TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1496 | == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1497 | 1TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1498 | | - |
1499 | | - |
1500 | ) { | - |
1501 | struct stat st; | - |
1502 | | - |
1503 | | - |
1504 | | - |
1505 | | - |
1506 | | - |
1507 | if (stat(newpath, &st) == -1TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1508 | if (rename(oldpath, newpath) == -1TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1509 | status = never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1510 | errno_to_portable( never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1511 | (*__errno_location ()) never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1512 | ); never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1513 | else | - |
1514 | status = 0; never executed: status = 0; | 0 |
1515 | } | - |
1516 | } never executed: end of block else { | 0 |
1517 | status = errno_to_portable( | - |
1518 | (*__errno_location ()) | - |
1519 | ); | - |
1520 | } never executed: end of block | 0 |
1521 | } else if (unlink(oldpath) == -1TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1522 | status = errno_to_portable( | - |
1523 | (*__errno_location ()) | - |
1524 | ); | - |
1525 | | - |
1526 | unlink(newpath); | - |
1527 | } never executed: end of block else | 0 |
1528 | status = 0; never executed: status = 0; | 0 |
1529 | } else if (stat(newpath, &sb) == -1TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1530 | if (rename(oldpath, newpath) == -1TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1531 | status = errno_to_portable( never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1532 | (*__errno_location ()) never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1533 | ); never executed: status = errno_to_portable( (*__errno_location ()) ); | 0 |
1534 | else | - |
1535 | status = 0; never executed: status = 0; | 0 |
1536 | } | - |
1537 | send_status(id, status); | - |
1538 | free(oldpath); | - |
1539 | free(newpath); | - |
1540 | } never executed: end of block | 0 |
1541 | | - |
1542 | static void | - |
1543 | process_readlink(u_int32_t id) | - |
1544 | { | - |
1545 | int r, len; | - |
1546 | char buf[ | - |
1547 | 4096 | - |
1548 | ]; | - |
1549 | char *path; | - |
1550 | | - |
1551 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &path, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1552 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1553 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1554 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1555 | | - |
1556 | debug3("request %u: readlink", id); | - |
1557 | verbose("readlink \"%s\"", path); | - |
1558 | if ((TRUE | never evaluated | FALSE | never evaluated |
len = readlink(path, buf, sizeof(buf) - 1)) == -1TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1559 | send_status(id, errno_to_portable( never executed: send_status(id, errno_to_portable( (*__errno_location ()) )); | 0 |
1560 | (*__errno_location ()) never executed: send_status(id, errno_to_portable( (*__errno_location ()) )); | 0 |
1561 | )); never executed: send_status(id, errno_to_portable( (*__errno_location ()) )); | 0 |
1562 | else { | - |
1563 | Stat s; | - |
1564 | | - |
1565 | buf[len] = '\0'; | - |
1566 | attrib_clear(&s.attrib); | - |
1567 | s.name = s.long_name = buf; | - |
1568 | send_names(id, 1, &s); | - |
1569 | } never executed: end of block | 0 |
1570 | free(path); | - |
1571 | } never executed: end of block | 0 |
1572 | | - |
1573 | static void | - |
1574 | process_symlink(u_int32_t id) | - |
1575 | { | - |
1576 | char *oldpath, *newpath; | - |
1577 | int r, status; | - |
1578 | | - |
1579 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &oldpath, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1580 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1581 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
1582 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &newpath, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1583 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1584 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1585 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1586 | | - |
1587 | debug3("request %u: symlink", id); | - |
1588 | logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); | - |
1589 | | - |
1590 | r = symlink(oldpath, newpath); | - |
1591 | status = (TRUE | never evaluated | FALSE | never evaluated |
r == -1)TRUE | never evaluated | FALSE | never evaluated |
? errno_to_portable( | 0 |
1592 | (*__errno_location ()) | - |
1593 | ) : 0; | - |
1594 | send_status(id, status); | - |
1595 | free(oldpath); | - |
1596 | free(newpath); | - |
1597 | } never executed: end of block | 0 |
1598 | | - |
1599 | static void | - |
1600 | process_extended_posix_rename(u_int32_t id) | - |
1601 | { | - |
1602 | char *oldpath, *newpath; | - |
1603 | int r, status; | - |
1604 | | - |
1605 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &oldpath, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1606 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1607 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
1608 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &newpath, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1609 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1610 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1611 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1612 | | - |
1613 | debug3("request %u: posix-rename", id); | - |
1614 | logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); | - |
1615 | r = rename(oldpath, newpath); | - |
1616 | status = (TRUE | never evaluated | FALSE | never evaluated |
r == -1)TRUE | never evaluated | FALSE | never evaluated |
? errno_to_portable( | 0 |
1617 | (*__errno_location ()) | - |
1618 | ) : 0; | - |
1619 | send_status(id, status); | - |
1620 | free(oldpath); | - |
1621 | free(newpath); | - |
1622 | } never executed: end of block | 0 |
1623 | | - |
1624 | static void | - |
1625 | process_extended_statvfs(u_int32_t id) | - |
1626 | { | - |
1627 | char *path; | - |
1628 | struct statvfs st; | - |
1629 | int r; | - |
1630 | | - |
1631 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &path, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1632 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1633 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1634 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1635 | debug3("request %u: statvfs", id); | - |
1636 | logit("statvfs \"%s\"", path); | - |
1637 | | - |
1638 | if (statvfs(path, &st) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1639 | send_status(id, errno_to_portable( never executed: send_status(id, errno_to_portable( (*__errno_location ()) )); | 0 |
1640 | (*__errno_location ()) never executed: send_status(id, errno_to_portable( (*__errno_location ()) )); | 0 |
1641 | )); never executed: send_status(id, errno_to_portable( (*__errno_location ()) )); | 0 |
1642 | else | - |
1643 | send_statvfs(id, &st); never executed: send_statvfs(id, &st); | 0 |
1644 | free(path); | - |
1645 | } never executed: end of block | 0 |
1646 | | - |
1647 | static void | - |
1648 | process_extended_fstatvfs(u_int32_t id) | - |
1649 | { | - |
1650 | int r, handle, fd; | - |
1651 | struct statvfs st; | - |
1652 | | - |
1653 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = get_handle(iqueue, &handle)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1654 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1655 | debug("request %u: fstatvfs \"%s\" (handle %u)", | - |
1656 | id, handle_to_name(handle), handle); | - |
1657 | if ((TRUE | never evaluated | FALSE | never evaluated |
fd = handle_to_fd(handle)) < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1658 | send_status(id, 4); | - |
1659 | return; never executed: return; | 0 |
1660 | } | - |
1661 | if (fstatvfs(fd, &st) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1662 | send_status(id, errno_to_portable( never executed: send_status(id, errno_to_portable( (*__errno_location ()) )); | 0 |
1663 | (*__errno_location ()) never executed: send_status(id, errno_to_portable( (*__errno_location ()) )); | 0 |
1664 | )); never executed: send_status(id, errno_to_portable( (*__errno_location ()) )); | 0 |
1665 | else | - |
1666 | send_statvfs(id, &st); never executed: send_statvfs(id, &st); | 0 |
1667 | } | - |
1668 | | - |
1669 | static void | - |
1670 | process_extended_hardlink(u_int32_t id) | - |
1671 | { | - |
1672 | char *oldpath, *newpath; | - |
1673 | int r, status; | - |
1674 | | - |
1675 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &oldpath, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1676 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1677 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
1678 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &newpath, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1679 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1680 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1681 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1682 | | - |
1683 | debug3("request %u: hardlink", id); | - |
1684 | logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath); | - |
1685 | r = link(oldpath, newpath); | - |
1686 | status = (TRUE | never evaluated | FALSE | never evaluated |
r == -1)TRUE | never evaluated | FALSE | never evaluated |
? errno_to_portable( | 0 |
1687 | (*__errno_location ()) | - |
1688 | ) : 0; | - |
1689 | send_status(id, status); | - |
1690 | free(oldpath); | - |
1691 | free(newpath); | - |
1692 | } never executed: end of block | 0 |
1693 | | - |
1694 | static void | - |
1695 | process_extended_fsync(u_int32_t id) | - |
1696 | { | - |
1697 | int handle, fd, r, status = 8; | - |
1698 | | - |
1699 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = get_handle(iqueue, &handle)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1700 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1701 | debug3("request %u: fsync (handle %u)", id, handle); | - |
1702 | verbose("fsync \"%s\"", handle_to_name(handle)); | - |
1703 | if ((TRUE | never evaluated | FALSE | never evaluated |
fd = handle_to_fd(handle)) < 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1704 | status = 2; never executed: status = 2; | 0 |
1705 | else if (handle_is_ok(handle, HANDLE_FILE)TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1706 | r = fsync(fd); | - |
1707 | status = (TRUE | never evaluated | FALSE | never evaluated |
r == -1)TRUE | never evaluated | FALSE | never evaluated |
? errno_to_portable( | 0 |
1708 | (*__errno_location ()) | - |
1709 | ) : 0; | - |
1710 | } never executed: end of block | 0 |
1711 | send_status(id, status); | - |
1712 | } never executed: end of block | 0 |
1713 | | - |
1714 | static void | - |
1715 | process_extended(u_int32_t id) | - |
1716 | { | - |
1717 | char *request; | - |
1718 | int i, r; | - |
1719 | | - |
1720 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_cstring(iqueue, &request, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1721 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1722 | )) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1723 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1724 | for (i = 0; extended_handlers[i].handler != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1725 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1726 | ; i++) { | - |
1727 | if ( | - |
1728 | __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1729 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1730 | ) && __builtin_constant_p (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1731 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1732 | ) && (__s1_len = __builtin_strlen (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1733 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1734 | ), __s2_len = __builtin_strlen (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1735 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1736 | ), (!((size_t)(const void *)((TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1737 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1738 | ) + 1) - (size_t)(const void *)(TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1739 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1740 | ) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1741 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1742 | ) + 1) - (size_t)(const void *)(TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1743 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1744 | ) == 1) || __s2_len >= 4)) ? __builtin_strcmp (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1745 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1746 | , TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1747 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1748 | ) : (__builtin_constant_p (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1749 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1750 | ) && ((size_t)(const void *)((TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1751 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1752 | ) + 1) - (size_t)(const void *)(TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1753 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1754 | ) == 1) && (__s1_len = __builtin_strlen (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1755 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1756 | ), __s1_len < 4) ? (__builtin_constant_p (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1757 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1758 | ) && ((size_t)(const void *)((TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1759 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1760 | ) + 1) - (size_t)(const void *)(TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1761 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1762 | ) == 1) ? __builtin_strcmp (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1763 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1764 | , TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1765 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1766 | ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1767 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1768 | ); int __result = (((const unsigned char *) (const char *) (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1769 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1770 | ))[0] - __s2[0]); if (__s1_len > 0TRUE | never evaluated | FALSE | never evaluated |
&& __result == 0TRUE | never evaluated | FALSE | never evaluated |
) { __result = (((const unsigned char *) (const char *) (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1771 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1772 | ))[1] - __s2[1]); if (__s1_len > 1TRUE | never evaluated | FALSE | never evaluated |
&& __result == 0TRUE | never evaluated | FALSE | never evaluated |
) { __result = (((const unsigned char *) (const char *) (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1773 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1774 | ))[2] - __s2[2]); if (__s1_len > 2TRUE | never evaluated | FALSE | never evaluated |
&& __result == 0TRUE | never evaluated | FALSE | never evaluated |
) __result = (((const unsigned char *) (const char *) (never executed: __result = (((const unsigned char *) (const char *) ( request ))[3] - __s2[3]); | 0 |
1775 | requestTRUE | never evaluated | FALSE | never evaluated |
never executed: __result = (((const unsigned char *) (const char *) ( request ))[3] - __s2[3]); | 0 |
1776 | ))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1777 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1778 | ) && ((size_t)(const void *)((TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1779 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1780 | ) + 1) - (size_t)(const void *)(TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1781 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1782 | ) == 1) && (__s2_len = __builtin_strlen (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1783 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1784 | ), __s2_len < 4) ? (__builtin_constant_p (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1785 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1786 | ) && ((size_t)(const void *)((TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1787 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1788 | ) + 1) - (size_t)(const void *)(TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1789 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1790 | ) == 1) ? __builtin_strcmp (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1791 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1792 | , TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1793 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1794 | ) : -(__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1795 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1796 | ); int __result = (((const unsigned char *) (const char *) (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1797 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1798 | ))[0] - __s2[0]); if (__s2_len > 0TRUE | never evaluated | FALSE | never evaluated |
&& __result == 0TRUE | never evaluated | FALSE | never evaluated |
) { __result = (((const unsigned char *) (const char *) (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1799 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1800 | ))[1] - __s2[1]); if (__s2_len > 1TRUE | never evaluated | FALSE | never evaluated |
&& __result == 0TRUE | never evaluated | FALSE | never evaluated |
) { __result = (((const unsigned char *) (const char *) (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1801 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1802 | ))[2] - __s2[2]); if (__s2_len > 2TRUE | never evaluated | FALSE | never evaluated |
&& __result == 0TRUE | never evaluated | FALSE | never evaluated |
) __result = (((const unsigned char *) (const char *) (never executed: __result = (((const unsigned char *) (const char *) ( extended_handlers[i].ext_name ))[3] - __s2[3]); | 0 |
1803 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
never executed: __result = (((const unsigned char *) (const char *) ( extended_handlers[i].ext_name ))[3] - __s2[3]); | 0 |
1804 | ))[3] - __s2[3]); } } __result; }))) : __builtin_strcmp (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1805 | requestTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1806 | , TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1807 | extended_handlers[i].ext_nameTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1808 | )))); }) TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1809 | == 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1810 | if (!request_permitted(&extended_handlers[i])TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1811 | send_status(id, 3); never executed: send_status(id, 3); | 0 |
1812 | else | - |
1813 | extended_handlers[i].handler(id); never executed: extended_handlers[i].handler(id); | 0 |
1814 | break; never executed: break; | 0 |
1815 | } | - |
1816 | } never executed: end of block | 0 |
1817 | if (extended_handlers[i].handler == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1818 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1819 | ) { | - |
1820 | error("Unknown extended request \"%.100s\"", request); | - |
1821 | send_status(id, 8); | - |
1822 | } never executed: end of block | 0 |
1823 | free(request); | - |
1824 | } never executed: end of block | 0 |
1825 | | - |
1826 | | - |
1827 | | - |
1828 | static void | - |
1829 | process(void) | - |
1830 | { | - |
1831 | u_int msg_len; | - |
1832 | u_int buf_len; | - |
1833 | u_int consumed; | - |
1834 | u_char type; | - |
1835 | const u_char *cp; | - |
1836 | int i, r; | - |
1837 | u_int32_t id; | - |
1838 | | - |
1839 | buf_len = sshbuf_len(iqueue); | - |
1840 | if (buf_len < 5TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1841 | return; never executed: return; | 0 |
1842 | cp = sshbuf_ptr(iqueue); | - |
1843 | msg_len = get_u32(cp); | - |
1844 | if (msg_len > (256 * 1024)TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1845 | error("bad message from %s local user %s", | - |
1846 | client_addr, pw->pw_name); | - |
1847 | sftp_server_cleanup_exit(11); | - |
1848 | } never executed: end of block | 0 |
1849 | if (buf_len < msg_len + 4TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1850 | return; never executed: return; | 0 |
1851 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_consume(iqueue, 4)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1852 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1853 | buf_len -= 4; | - |
1854 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_u8(iqueue, &type)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1855 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1856 | | - |
1857 | switch (type) { | - |
1858 | case never executed: case 1: 1:never executed: case 1: | 0 |
1859 | process_init(); | - |
1860 | init_done = 1; | - |
1861 | break; never executed: break; | 0 |
1862 | case never executed: case 200: 200:never executed: case 200: | 0 |
1863 | if (!init_doneTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1864 | fatal("Received extended request before init"); never executed: fatal("Received extended request before init"); | 0 |
1865 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_u32(iqueue, &id)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1866 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1867 | process_extended(id); | - |
1868 | break; never executed: break; | 0 |
1869 | default never executed: default: :never executed: default: | 0 |
1870 | if (!init_doneTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1871 | fatal("Received %u request before init", type); never executed: fatal("Received %u request before init", type); | 0 |
1872 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_get_u32(iqueue, &id)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1873 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1874 | for (i = 0; handlers[i].handler != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1875 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1876 | ; i++) { | - |
1877 | if (type == handlers[i].typeTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1878 | if (!request_permitted(&handlers[i])TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1879 | send_status(id, | - |
1880 | 3); | - |
1881 | } never executed: end of block else { | 0 |
1882 | handlers[i].handler(id); | - |
1883 | } never executed: end of block | 0 |
1884 | break; never executed: break; | 0 |
1885 | } | - |
1886 | } never executed: end of block | 0 |
1887 | if (handlers[i].handler == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1888 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1889 | ) | - |
1890 | error("Unknown message %u", type); never executed: error("Unknown message %u", type); | 0 |
1891 | } never executed: end of block | 0 |
1892 | | - |
1893 | if (buf_len < sshbuf_len(iqueue)TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1894 | error("iqueue grew unexpectedly"); | - |
1895 | sftp_server_cleanup_exit(255); | - |
1896 | } never executed: end of block | 0 |
1897 | consumed = buf_len - sshbuf_len(iqueue); | - |
1898 | if (msg_len < consumedTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1899 | error("msg_len %u < consumed %u", msg_len, consumed); | - |
1900 | sftp_server_cleanup_exit(255); | - |
1901 | } never executed: end of block | 0 |
1902 | if (msg_len > consumedTRUE | never evaluated | FALSE | never evaluated |
&& | 0 |
1903 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_consume(iqueue, msg_len - consumed)) != 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1904 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1905 | } never executed: end of block | 0 |
1906 | | - |
1907 | | - |
1908 | void | - |
1909 | sftp_server_cleanup_exit(int i) | - |
1910 | { | - |
1911 | if (pw != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1912 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1913 | && client_addr != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1914 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1915 | ) { | - |
1916 | handle_log_exit(); | - |
1917 | logit("session closed for local user %s from [%s]", | - |
1918 | pw->pw_name, client_addr); | - |
1919 | } never executed: end of block | 0 |
1920 | _exit(i); | - |
1921 | } never executed: end of block | 0 |
1922 | | - |
1923 | static void | - |
1924 | sftp_server_usage(void) | - |
1925 | { | - |
1926 | extern char *__progname; | - |
1927 | | - |
1928 | fprintf( | - |
1929 | stderr | - |
1930 | , | - |
1931 | "usage: %s [-ehR] [-d start_directory] [-f log_facility] " | - |
1932 | "[-l log_level]\n\t[-P blacklisted_requests] " | - |
1933 | "[-p whitelisted_requests] [-u umask]\n" | - |
1934 | " %s -Q protocol_feature\n", | - |
1935 | __progname, __progname); | - |
1936 | exit(1); never executed: exit(1); | 0 |
1937 | } | - |
1938 | | - |
1939 | int | - |
1940 | sftp_server_main(int argc, char **argv, struct passwd *user_pw) | - |
1941 | { | - |
1942 | fd_set *rset, *wset; | - |
1943 | int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; | - |
1944 | ssize_t len, olen, set_size; | - |
1945 | SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; | - |
1946 | char *cp, *homedir = | - |
1947 | ((void *)0) | - |
1948 | , uidstr[32], buf[4*4096]; | - |
1949 | long mask; | - |
1950 | | - |
1951 | extern char *BSDoptarg; | - |
1952 | extern char *__progname; | - |
1953 | | - |
1954 | ssh_malloc_init(); | - |
1955 | __progname = ssh_get_progname(argv[0]); | - |
1956 | log_init(__progname, log_level, log_facility, log_stderr); | - |
1957 | | - |
1958 | pw = pwcopy(user_pw); | - |
1959 | | - |
1960 | while (!skipargsTRUE | never evaluated | FALSE | never evaluated |
&& (TRUE | never evaluated | FALSE | never evaluated |
ch = BSDgetopt(argc, argv, "d:f:l:P:p:Q:u:cehR")TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1961 | ) != -1TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1962 | switch (ch) { | - |
1963 | case never executed: case 'Q': 'Q':never executed: case 'Q': | 0 |
1964 | if (strcasecmp(BSDoptarg, "requests") != 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
1965 | fprintf( | - |
1966 | stderr | - |
1967 | , "Invalid query type\n"); | - |
1968 | exit(1); never executed: exit(1); | 0 |
1969 | } | - |
1970 | for (i = 0; handlers[i].handler != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1971 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1972 | ; i++) | - |
1973 | printf("%s\n", handlers[i].name); never executed: printf("%s\n", handlers[i].name); | 0 |
1974 | for (i = 0; extended_handlers[i].handler != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1975 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1976 | ; i++) | - |
1977 | printf("%s\n", extended_handlers[i].name); never executed: printf("%s\n", extended_handlers[i].name); | 0 |
1978 | exit(0); never executed: exit(0); | 0 |
1979 | break; never executed: break; | 0 |
1980 | case never executed: case 'R': 'R':never executed: case 'R': | 0 |
1981 | readonly = 1; | - |
1982 | break; never executed: break; | 0 |
1983 | case never executed: case 'c': 'c':never executed: case 'c': | 0 |
1984 | | - |
1985 | | - |
1986 | | - |
1987 | | - |
1988 | skipargs = 1; | - |
1989 | break; never executed: break; | 0 |
1990 | case never executed: case 'e': 'e':never executed: case 'e': | 0 |
1991 | log_stderr = 1; | - |
1992 | break; never executed: break; | 0 |
1993 | case never executed: case 'l': 'l':never executed: case 'l': | 0 |
1994 | log_level = log_level_number(BSDoptarg); | - |
1995 | if (log_level == SYSLOG_LEVEL_NOT_SETTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
1996 | error("Invalid log level \"%s\"", BSDoptarg); never executed: error("Invalid log level \"%s\"", BSDoptarg); | 0 |
1997 | break; never executed: break; | 0 |
1998 | case never executed: case 'f': 'f':never executed: case 'f': | 0 |
1999 | log_facility = log_facility_number(BSDoptarg); | - |
2000 | if (log_facility == SYSLOG_FACILITY_NOT_SETTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
2001 | error("Invalid log facility \"%s\"", BSDoptarg); never executed: error("Invalid log facility \"%s\"", BSDoptarg); | 0 |
2002 | break; never executed: break; | 0 |
2003 | case never executed: case 'd': 'd':never executed: case 'd': | 0 |
2004 | cp = tilde_expand_filename(BSDoptarg, user_pw->pw_uid); | - |
2005 | snprintf(uidstr, sizeof(uidstr), "%llu", | - |
2006 | (unsigned long long)pw->pw_uid); | - |
2007 | homedir = percent_expand(cp, "d", user_pw->pw_dir, | - |
2008 | "u", user_pw->pw_name, "U", uidstr, (char *) | - |
2009 | ((void *)0) | - |
2010 | ); | - |
2011 | free(cp); | - |
2012 | break; never executed: break; | 0 |
2013 | case never executed: case 'p': 'p':never executed: case 'p': | 0 |
2014 | if (request_whitelist != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2015 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2016 | ) | - |
2017 | fatal("Permitted requests already set"); never executed: fatal("Permitted requests already set"); | 0 |
2018 | request_whitelist = xstrdup(BSDoptarg); | - |
2019 | break; never executed: break; | 0 |
2020 | case never executed: case 'P': 'P':never executed: case 'P': | 0 |
2021 | if (request_blacklist != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2022 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2023 | ) | - |
2024 | fatal("Refused requests already set"); never executed: fatal("Refused requests already set"); | 0 |
2025 | request_blacklist = xstrdup(BSDoptarg); | - |
2026 | break; never executed: break; | 0 |
2027 | case never executed: case 'u': 'u':never executed: case 'u': | 0 |
2028 | | - |
2029 | (*__errno_location ()) | - |
2030 | = 0; | - |
2031 | mask = strtol(BSDoptarg, &cp, 8); | - |
2032 | if (mask < 0TRUE | never evaluated | FALSE | never evaluated |
|| mask > 0777TRUE | never evaluated | FALSE | never evaluated |
|| *TRUE | never evaluated | FALSE | never evaluated |
cp != '\0'TRUE | never evaluated | FALSE | never evaluated |
|| | 0 |
2033 | cp == BSDoptargTRUE | never evaluated | FALSE | never evaluated |
|| (mask == 0TRUE | never evaluated | FALSE | never evaluated |
&& | 0 |
2034 | (*TRUE | never evaluated | FALSE | never evaluated |
__errno_location ()) TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2035 | != 0TRUE | never evaluated | FALSE | never evaluated |
)) | 0 |
2036 | fatal("Invalid umask \"%s\"", BSDoptarg); never executed: fatal("Invalid umask \"%s\"", BSDoptarg); | 0 |
2037 | (void)umask((mode_t)mask); | - |
2038 | break; never executed: break; | 0 |
2039 | case never executed: case 'h': 'h':never executed: case 'h': | 0 |
2040 | default never executed: default: :never executed: default: | 0 |
2041 | sftp_server_usage(); | - |
2042 | } never executed: end of block | 0 |
2043 | } | - |
2044 | | - |
2045 | log_init(__progname, log_level, log_facility, log_stderr); | - |
2046 | | - |
2047 | | - |
2048 | | - |
2049 | | - |
2050 | | - |
2051 | | - |
2052 | | - |
2053 | platform_disable_tracing(1); | - |
2054 | | - |
2055 | | - |
2056 | platform_pledge_sftp_server(); | - |
2057 | | - |
2058 | if ((TRUE | never evaluated | FALSE | never evaluated |
cp = getenv("SSH_CONNECTION")) != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2059 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2060 | ) { | - |
2061 | client_addr = xstrdup(cp); | - |
2062 | if ((TRUE | never evaluated | FALSE | never evaluated |
cp = TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2063 | (__extension__ (__builtin_constant_p (TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2064 | ' 'TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2065 | )TRUE | never evaluated | FALSE | never evaluated |
&& !__builtin_constant_p (TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2066 | client_addrTRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2067 | )TRUE | never evaluated | FALSE | never evaluated |
&& (TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2068 | ' 'TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2069 | ) == '\0'TRUE | never evaluated | FALSE | never evaluated |
? (char *) __rawmemchr (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2070 | client_addrTRUE | never evaluated | FALSE | never evaluated |
| 0 |
2071 | , TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2072 | ' 'TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2073 | ) : __builtin_strchr (TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2074 | client_addrTRUE | never evaluated | FALSE | never evaluated |
| 0 |
2075 | , TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2076 | ' 'TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2077 | )))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2078 | ) == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2079 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2080 | ) { | - |
2081 | error("Malformed SSH_CONNECTION variable: \"%s\"", | - |
2082 | getenv("SSH_CONNECTION")); | - |
2083 | sftp_server_cleanup_exit(255); | - |
2084 | } never executed: end of block | 0 |
2085 | *cp = '\0'; | - |
2086 | } never executed: end of block else | 0 |
2087 | client_addr = xstrdup("UNKNOWN"); never executed: client_addr = xstrdup("UNKNOWN"); | 0 |
2088 | | - |
2089 | logit("session opened for local user %s from [%s]", | - |
2090 | pw->pw_name, client_addr); | - |
2091 | | - |
2092 | in = | - |
2093 | 0 | - |
2094 | ; | - |
2095 | out = | - |
2096 | 1 | - |
2097 | ; | - |
2098 | | - |
2099 | | - |
2100 | | - |
2101 | | - |
2102 | | - |
2103 | | - |
2104 | max = 0; | - |
2105 | if (in > maxTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
2106 | max = in; never executed: max = in; | 0 |
2107 | if (out > maxTRUE | never evaluated | FALSE | never evaluated |
) | 0 |
2108 | max = out; never executed: max = out; | 0 |
2109 | | - |
2110 | if ((TRUE | never evaluated | FALSE | never evaluated |
iqueue = sshbuf_new()) == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2111 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2112 | ) | - |
2113 | fatal("%s: sshbuf_new failed", __func__); never executed: fatal("%s: sshbuf_new failed", __func__); | 0 |
2114 | if ((TRUE | never evaluated | FALSE | never evaluated |
oqueue = sshbuf_new()) == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2115 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2116 | ) | - |
2117 | fatal("%s: sshbuf_new failed", __func__); never executed: fatal("%s: sshbuf_new failed", __func__); | 0 |
2118 | | - |
2119 | rset = xcalloc( | - |
2120 | ((( | - |
2121 | max + 1 | - |
2122 | ) + (((8 * (int) sizeof (__fd_mask))) - 1)) / ((8 * (int) sizeof (__fd_mask)))) | - |
2123 | , sizeof(fd_mask)); | - |
2124 | wset = xcalloc( | - |
2125 | ((( | - |
2126 | max + 1 | - |
2127 | ) + (((8 * (int) sizeof (__fd_mask))) - 1)) / ((8 * (int) sizeof (__fd_mask)))) | - |
2128 | , sizeof(fd_mask)); | - |
2129 | | - |
2130 | if (homedir != TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2131 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2132 | ) { | - |
2133 | if (chdir(homedir) != 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
2134 | error("chdir to \"%s\" failed: %s", homedir, | - |
2135 | strerror( | - |
2136 | (*__errno_location ()) | - |
2137 | )); | - |
2138 | } never executed: end of block | 0 |
2139 | } never executed: end of block | 0 |
2140 | | - |
2141 | set_size = | - |
2142 | ((( | - |
2143 | max + 1 | - |
2144 | ) + (((8 * (int) sizeof (__fd_mask))) - 1)) / ((8 * (int) sizeof (__fd_mask)))) | - |
2145 | * sizeof(fd_mask); | - |
2146 | for (;;) { | - |
2147 | memset(rset, 0, set_size); | - |
2148 | memset(wset, 0, set_size); | - |
2149 | | - |
2150 | | - |
2151 | | - |
2152 | | - |
2153 | | - |
2154 | | - |
2155 | if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0TRUE | never evaluated | FALSE | never evaluated |
&& | 0 |
2156 | (TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_check_reserve(oqueue,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2157 | (256 * 1024))) == 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
2158 | kludge_FD_SET(in, rset); never executed: kludge_FD_SET(in, rset); | 0 |
2159 | else if (r != -9TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
2160 | fatal("%s: sshbuf_check_reserve failed: %s", never executed: fatal("%s: sshbuf_check_reserve failed: %s", __func__, ssh_err(r)); | 0 |
2161 | __func__, ssh_err(r)); never executed: fatal("%s: sshbuf_check_reserve failed: %s", __func__, ssh_err(r)); | 0 |
2162 | | - |
2163 | olen = sshbuf_len(oqueue); | - |
2164 | if (olen > 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
2165 | kludge_FD_SET(out, wset); never executed: kludge_FD_SET(out, wset); | 0 |
2166 | | - |
2167 | if (select(max+1, rset, wset, TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2168 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2169 | , TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2170 | ((void *)0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2171 | ) < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
2172 | if ( | - |
2173 | (*TRUE | never evaluated | FALSE | never evaluated |
__errno_location ()) TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2174 | == TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2175 | 4TRUE | never evaluated | FALSE | never evaluated |
| 0 |
2176 | ) | - |
2177 | continue; never executed: continue; | 0 |
2178 | error("select: %s", strerror( | - |
2179 | (*__errno_location ()) | - |
2180 | )); | - |
2181 | sftp_server_cleanup_exit(2); | - |
2182 | } never executed: end of block | 0 |
2183 | | - |
2184 | | - |
2185 | if (kludge_FD_ISSET(in, rset)TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
2186 | len = read(in, buf, sizeof buf); | - |
2187 | if (len == 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
2188 | debug("read eof"); | - |
2189 | sftp_server_cleanup_exit(0); | - |
2190 | } never executed: end of block else if (len < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
2191 | error("read: %s", strerror( | - |
2192 | (*__errno_location ()) | - |
2193 | )); | - |
2194 | sftp_server_cleanup_exit(1); | - |
2195 | } never executed: end of block else if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_put(iqueue, buf, len)) != 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
2196 | fatal("%s: buffer error: %s", | - |
2197 | __func__, ssh_err(r)); | - |
2198 | } never executed: end of block | 0 |
2199 | } never executed: end of block | 0 |
2200 | | - |
2201 | if (kludge_FD_ISSET(out, wset)TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
2202 | len = write(out, sshbuf_ptr(oqueue), olen); | - |
2203 | if (len < 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
2204 | error("write: %s", strerror( | - |
2205 | (*__errno_location ()) | - |
2206 | )); | - |
2207 | sftp_server_cleanup_exit(1); | - |
2208 | } never executed: end of block else if ((TRUE | never evaluated | FALSE | never evaluated |
r = sshbuf_consume(oqueue, len)) != 0TRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
2209 | fatal("%s: buffer error: %s", | - |
2210 | __func__, ssh_err(r)); | - |
2211 | } never executed: end of block | 0 |
2212 | } never executed: end of block | 0 |
2213 | | - |
2214 | | - |
2215 | | - |
2216 | | - |
2217 | | - |
2218 | | - |
2219 | r = sshbuf_check_reserve(oqueue, (256 * 1024)); | - |
2220 | if (r == 0TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
2221 | process(); never executed: process(); | 0 |
2222 | else if (r != -9TRUE | never evaluated | FALSE | never evaluated |
) | 0 |
2223 | fatal("%s: sshbuf_check_reserve: %s", never executed: fatal("%s: sshbuf_check_reserve: %s", __func__, ssh_err(r)); | 0 |
2224 | __func__, ssh_err(r)); never executed: fatal("%s: sshbuf_check_reserve: %s", __func__, ssh_err(r)); | 0 |
2225 | } never executed: end of block | 0 |
2226 | } never executed: end of block | 0 |
| | |