Line | Source | Count |
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | | - |
8 | | - |
9 | | - |
10 | | - |
11 | | - |
12 | | - |
13 | | - |
14 | | - |
15 | | - |
16 | | - |
17 | | - |
18 | | - |
19 | | - |
20 | | - |
21 | | - |
22 | | - |
23 | | - |
24 | | - |
25 | | - |
26 | | - |
27 | #include "includes.h" | - |
28 | | - |
29 | #include <sys/types.h> | - |
30 | #include <sys/ioctl.h> | - |
31 | #include <sys/socket.h> | - |
32 | #include <sys/stat.h> | - |
33 | #include <sys/time.h> | - |
34 | #include <sys/wait.h> | - |
35 | #include <sys/un.h> | - |
36 | | - |
37 | #include <limits.h> | - |
38 | #ifdef HAVE_LIBGEN_H | - |
39 | # include <libgen.h> | - |
40 | #endif | - |
41 | #include <signal.h> | - |
42 | #include <stdarg.h> | - |
43 | #include <stdio.h> | - |
44 | #include <stdlib.h> | - |
45 | #include <string.h> | - |
46 | #include <time.h> | - |
47 | #include <unistd.h> | - |
48 | | - |
49 | #include <netinet/in.h> | - |
50 | #include <netinet/in_systm.h> | - |
51 | #include <netinet/ip.h> | - |
52 | #include <netinet/tcp.h> | - |
53 | | - |
54 | #include <ctype.h> | - |
55 | #include <errno.h> | - |
56 | #include <fcntl.h> | - |
57 | #include <netdb.h> | - |
58 | #ifdef HAVE_PATHS_H | - |
59 | # include <paths.h> | - |
60 | #include <pwd.h> | - |
61 | #endif | - |
62 | #ifdef SSH_TUN_OPENBSD | - |
63 | #include <net/if.h> | - |
64 | #endif | - |
65 | | - |
66 | #include "xmalloc.h" | - |
67 | #include "misc.h" | - |
68 | #include "log.h" | - |
69 | #include "ssh.h" | - |
70 | #include "sshbuf.h" | - |
71 | #include "ssherr.h" | - |
72 | #include "platform.h" | - |
73 | | - |
74 | | - |
75 | char * | - |
76 | chop(char *s) | - |
77 | { | - |
78 | char *t = s; | - |
79 | while (*t) {TRUE | evaluated 2560 times by 1 test | FALSE | never evaluated |
| 0-2560 |
80 | if (*t == '\n' || *t == '\r') {TRUE | evaluated 64 times by 1 test | FALSE | evaluated 2496 times by 1 test |
TRUE | evaluated 64 times by 1 test | FALSE | evaluated 2432 times by 1 test |
| 64-2496 |
81 | *t = '\0'; | - |
82 | return s;executed 128 times by 1 test: return s; | 128 |
83 | } | - |
84 | t++; | - |
85 | }executed 2432 times by 1 test: end of block | 2432 |
86 | return s; never executed: return s; | 0 |
87 | | - |
88 | } | - |
89 | | - |
90 | | - |
91 | int | - |
92 | set_nonblock(int fd) | - |
93 | { | - |
94 | int val; | - |
95 | | - |
96 | val = fcntl(fd, F_GETFL); | - |
97 | if (val < 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
98 | error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); | - |
99 | return (-1); never executed: return (-1); | 0 |
100 | } | - |
101 | if (val & O_NONBLOCK) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
102 | debug3("fd %d is O_NONBLOCK", fd); | - |
103 | return (0); never executed: return (0); | 0 |
104 | } | - |
105 | debug2("fd %d setting O_NONBLOCK", fd); | - |
106 | val |= O_NONBLOCK; | - |
107 | if (fcntl(fd, F_SETFL, val) == -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
108 | debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, | - |
109 | strerror(errno)); | - |
110 | return (-1); never executed: return (-1); | 0 |
111 | } | - |
112 | return (0); never executed: return (0); | 0 |
113 | } | - |
114 | | - |
115 | int | - |
116 | unset_nonblock(int fd) | - |
117 | { | - |
118 | int val; | - |
119 | | - |
120 | val = fcntl(fd, F_GETFL); | - |
121 | if (val < 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
122 | error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); | - |
123 | return (-1); never executed: return (-1); | 0 |
124 | } | - |
125 | if (!(val & O_NONBLOCK)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
126 | debug3("fd %d is not O_NONBLOCK", fd); | - |
127 | return (0); never executed: return (0); | 0 |
128 | } | - |
129 | debug("fd %d clearing O_NONBLOCK", fd); | - |
130 | val &= ~O_NONBLOCK; | - |
131 | if (fcntl(fd, F_SETFL, val) == -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
132 | debug("fcntl(%d, F_SETFL, ~O_NONBLOCK): %s", | - |
133 | fd, strerror(errno)); | - |
134 | return (-1); never executed: return (-1); | 0 |
135 | } | - |
136 | return (0); never executed: return (0); | 0 |
137 | } | - |
138 | | - |
139 | const char * | - |
140 | ssh_gai_strerror(int gaierr) | - |
141 | { | - |
142 | if (gaierr == EAI_SYSTEM && errno != 0)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
143 | return strerror(errno); never executed: return strerror( (*__errno_location ()) ); | 0 |
144 | return gai_strerror(gaierr); never executed: return gai_strerror(gaierr); | 0 |
145 | } | - |
146 | | - |
147 | | - |
148 | void | - |
149 | set_nodelay(int fd) | - |
150 | { | - |
151 | int opt; | - |
152 | socklen_t optlen; | - |
153 | | - |
154 | optlen = sizeof opt; | - |
155 | if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
156 | debug("getsockopt TCP_NODELAY: %.100s", strerror(errno)); | - |
157 | return; never executed: return; | 0 |
158 | } | - |
159 | if (opt == 1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
160 | debug2("fd %d is TCP_NODELAY", fd); | - |
161 | return; never executed: return; | 0 |
162 | } | - |
163 | opt = 1; | - |
164 | debug2("fd %d setting TCP_NODELAY", fd); | - |
165 | if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
166 | error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); never executed: error("setsockopt TCP_NODELAY: %.100s", strerror( (*__errno_location ()) )); | 0 |
167 | } never executed: end of block | 0 |
168 | | - |
169 | | - |
170 | int | - |
171 | set_reuseaddr(int fd) | - |
172 | { | - |
173 | int on = 1; | - |
174 | | - |
175 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
176 | error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno)); | - |
177 | return -1; never executed: return -1; | 0 |
178 | } | - |
179 | return 0; never executed: return 0; | 0 |
180 | } | - |
181 | | - |
182 | | - |
183 | char * | - |
184 | get_rdomain(int fd) | - |
185 | { | - |
186 | #if defined(HAVE_SYS_GET_RDOMAIN) | - |
187 | return sys_get_rdomain(fd); | - |
188 | #elif defined(__OpenBSD__) | - |
189 | int rtable; | - |
190 | char *ret; | - |
191 | socklen_t len = sizeof(rtable); | - |
192 | | - |
193 | if (getsockopt(fd, SOL_SOCKET, SO_RTABLE, &rtable, &len) == -1) { | - |
194 | error("Failed to get routing domain for fd %d: %s", | - |
195 | fd, strerror(errno)); | - |
196 | return NULL; | - |
197 | } | - |
198 | xasprintf(&ret, "%d", rtable); | - |
199 | return ret; | - |
200 | #else /* defined(__OpenBSD__) */ | - |
201 | return NULL; never executed: return ((void *)0) ; | 0 |
202 | #endif | - |
203 | } | - |
204 | | - |
205 | int | - |
206 | set_rdomain(int fd, const char *name) | - |
207 | { | - |
208 | #if defined(HAVE_SYS_SET_RDOMAIN) | - |
209 | return sys_set_rdomain(fd, name); | - |
210 | #elif defined(__OpenBSD__) | - |
211 | int rtable; | - |
212 | const char *errstr; | - |
213 | | - |
214 | if (name == NULL) | - |
215 | return 0; | - |
216 | | - |
217 | rtable = (int)strtonum(name, 0, 255, &errstr); | - |
218 | if (errstr != NULL) { | - |
219 | | - |
220 | error("Invalid routing domain \"%s\": %s", name, errstr); | - |
221 | return -1; | - |
222 | } | - |
223 | if (setsockopt(fd, SOL_SOCKET, SO_RTABLE, | - |
224 | &rtable, sizeof(rtable)) == -1) { | - |
225 | error("Failed to set routing domain %d on fd %d: %s", | - |
226 | rtable, fd, strerror(errno)); | - |
227 | return -1; | - |
228 | } | - |
229 | return 0; | - |
230 | #else /* defined(__OpenBSD__) */ | - |
231 | error("Setting routing domain is not supported on this platform"); | - |
232 | return -1; never executed: return -1; | 0 |
233 | #endif | - |
234 | } | - |
235 | | - |
236 | | - |
237 | #define WHITESPACE " \t\r\n" | - |
238 | #define QUOTE "\"" | - |
239 | | - |
240 | | - |
241 | static char * | - |
242 | strdelim_internal(char **s, int split_equals) | - |
243 | { | - |
244 | char *old; | - |
245 | int wspace = 0; | - |
246 | | - |
247 | if (*s == NULL)TRUE | evaluated 33 times by 1 test | FALSE | evaluated 52 times by 1 test |
| 33-52 |
248 | return NULL;executed 33 times by 1 test: return ((void *)0) ; | 33 |
249 | | - |
250 | old = *s; | - |
251 | | - |
252 | *s = strpbrk(*s, | - |
253 | split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); | - |
254 | if (*s == NULL)TRUE | evaluated 25 times by 1 test | FALSE | evaluated 27 times by 1 test |
| 25-27 |
255 | return (old);executed 25 times by 1 test: return (old); | 25 |
256 | | - |
257 | if (*s[0] == '\"') {TRUE | never evaluated | FALSE | evaluated 27 times by 1 test |
| 0-27 |
258 | memmove(*s, *s + 1, strlen(*s)); | - |
259 | | - |
260 | if ((*s = strpbrk(*s, QUOTE)) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
261 | return (NULL); never executed: return ( ((void *)0) ); | 0 |
262 | } else { | - |
263 | *s[0] = '\0'; | - |
264 | *s += strspn(*s + 1, WHITESPACE) + 1; | - |
265 | return (old); never executed: return (old); | 0 |
266 | } | - |
267 | } | - |
268 | | - |
269 | | - |
270 | if (split_equals && *s[0] == '=')TRUE | evaluated 27 times by 1 test | FALSE | never evaluated |
TRUE | never evaluated | FALSE | evaluated 27 times by 1 test |
| 0-27 |
271 | wspace = 1; never executed: wspace = 1; | 0 |
272 | *s[0] = '\0'; | - |
273 | | - |
274 | | - |
275 | *s += strspn(*s + 1, WHITESPACE) + 1; | - |
276 | if (split_equals && *s[0] == '=' && !wspace)TRUE | evaluated 27 times by 1 test | FALSE | never evaluated |
TRUE | never evaluated | FALSE | evaluated 27 times by 1 test |
TRUE | never evaluated | FALSE | never evaluated |
| 0-27 |
277 | *s += strspn(*s + 1, WHITESPACE) + 1; never executed: *s += __builtin_strspn ( *s + 1 , " \t\r\n" ) + 1; | 0 |
278 | | - |
279 | return (old);executed 27 times by 1 test: return (old); | 27 |
280 | } | - |
281 | | - |
282 | | - |
283 | | - |
284 | | - |
285 | | - |
286 | char * | - |
287 | strdelim(char **s) | - |
288 | { | - |
289 | return strdelim_internal(s, 1);executed 85 times by 1 test: return strdelim_internal(s, 1); | 85 |
290 | } | - |
291 | | - |
292 | | - |
293 | | - |
294 | | - |
295 | char * | - |
296 | strdelimw(char **s) | - |
297 | { | - |
298 | return strdelim_internal(s, 0); never executed: return strdelim_internal(s, 0); | 0 |
299 | } | - |
300 | | - |
301 | struct passwd * | - |
302 | pwcopy(struct passwd *pw) | - |
303 | { | - |
304 | struct passwd *copy = xcalloc(1, sizeof(*copy)); | - |
305 | | - |
306 | copy->pw_name = xstrdup(pw->pw_name); | - |
307 | copy->pw_passwd = xstrdup(pw->pw_passwd); | - |
308 | #ifdef HAVE_STRUCT_PASSWD_PW_GECOS | - |
309 | copy->pw_gecos = xstrdup(pw->pw_gecos); | - |
310 | #endif | - |
311 | copy->pw_uid = pw->pw_uid; | - |
312 | copy->pw_gid = pw->pw_gid; | - |
313 | #ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE | - |
314 | copy->pw_expire = pw->pw_expire; | - |
315 | #endif | - |
316 | #ifdef HAVE_STRUCT_PASSWD_PW_CHANGE | - |
317 | copy->pw_change = pw->pw_change; | - |
318 | #endif | - |
319 | #ifdef HAVE_STRUCT_PASSWD_PW_CLASS | - |
320 | copy->pw_class = xstrdup(pw->pw_class); | - |
321 | #endif | - |
322 | copy->pw_dir = xstrdup(pw->pw_dir); | - |
323 | copy->pw_shell = xstrdup(pw->pw_shell); | - |
324 | return copy;executed 2 times by 1 test: return copy; | 2 |
325 | } | - |
326 | | - |
327 | | - |
328 | | - |
329 | | - |
330 | | - |
331 | | - |
332 | int | - |
333 | a2port(const char *s) | - |
334 | { | - |
335 | long long port; | - |
336 | const char *errstr; | - |
337 | | - |
338 | port = strtonum(s, 0, 65535, &errstr); | - |
339 | if (errstr != NULL)TRUE | never evaluated | FALSE | evaluated 2 times by 1 test |
| 0-2 |
340 | return -1; never executed: return -1; | 0 |
341 | return (int)port;executed 2 times by 1 test: return (int)port; | 2 |
342 | } | - |
343 | | - |
344 | int | - |
345 | a2tun(const char *s, int *remote) | - |
346 | { | - |
347 | const char *errstr = NULL; | - |
348 | char *sp, *ep; | - |
349 | int tun; | - |
350 | | - |
351 | if (remote != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
352 | *remote = SSH_TUNID_ANY; | - |
353 | sp = xstrdup(s); | - |
354 | if ((ep = strchr(sp, ':')) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
355 | free(sp); | - |
356 | return (a2tun(s, NULL)); never executed: return (a2tun(s, ((void *)0) )); | 0 |
357 | } | - |
358 | ep[0] = '\0'; ep++; | - |
359 | *remote = a2tun(ep, NULL); | - |
360 | tun = a2tun(sp, NULL); | - |
361 | free(sp); | - |
362 | return (*remote == SSH_TUNID_ERR ? *remote : tun); never executed: return (*remote == (0x7fffffff - 1) ? *remote : tun); TRUE | never evaluated | FALSE | never evaluated |
| 0 |
363 | } | - |
364 | | - |
365 | if (strcasecmp(s, "any") == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
366 | return (SSH_TUNID_ANY); never executed: return (0x7fffffff); | 0 |
367 | | - |
368 | tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr); | - |
369 | if (errstr != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
370 | return (SSH_TUNID_ERR); never executed: return ((0x7fffffff - 1)); | 0 |
371 | | - |
372 | return (tun); never executed: return (tun); | 0 |
373 | } | - |
374 | | - |
375 | #define SECONDS 1 | - |
376 | #define MINUTES (SECONDS * 60) | - |
377 | #define HOURS (MINUTES * 60) | - |
378 | #define DAYS (HOURS * 24) | - |
379 | #define WEEKS (DAYS * 7) | - |
380 | | - |
381 | | - |
382 | | - |
383 | | - |
384 | | - |
385 | | - |
386 | | - |
387 | | - |
388 | | - |
389 | | - |
390 | | - |
391 | | - |
392 | | - |
393 | | - |
394 | | - |
395 | | - |
396 | | - |
397 | | - |
398 | | - |
399 | | - |
400 | | - |
401 | | - |
402 | long | - |
403 | convtime(const char *s) | - |
404 | { | - |
405 | long total, secs, multiplier = 1; | - |
406 | const char *p; | - |
407 | char *endp; | - |
408 | | - |
409 | errno = 0; | - |
410 | total = 0; | - |
411 | p = s; | - |
412 | | - |
413 | if (p == NULL || *p == '\0')TRUE | never evaluated | FALSE | evaluated 12 times by 1 test |
TRUE | never evaluated | FALSE | evaluated 12 times by 1 test |
| 0-12 |
414 | return -1; never executed: return -1; | 0 |
415 | | - |
416 | while (*p) {TRUE | evaluated 13 times by 1 test | FALSE | evaluated 7 times by 1 test |
| 7-13 |
417 | secs = strtol(p, &endp, 10); | - |
418 | if (p == endp ||TRUE | never evaluated | FALSE | evaluated 13 times by 1 test |
| 0-13 |
419 | (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||TRUE | evaluated 2 times by 1 test | FALSE | evaluated 11 times by 1 test |
TRUE | never evaluated | FALSE | evaluated 2 times by 1 test |
TRUE | evaluated 2 times by 1 test | FALSE | never evaluated |
| 0-11 |
420 | secs < 0)TRUE | evaluated 2 times by 1 test | FALSE | evaluated 9 times by 1 test |
| 2-9 |
421 | return -1;executed 4 times by 1 test: return -1; | 4 |
422 | | - |
423 | switch (*endp++) { | - |
424 | case '\0':executed 2 times by 1 test: case '\0': | 2 |
425 | endp--; | - |
426 | break;executed 2 times by 1 test: break; | 2 |
427 | case 's': never executed: case 's': | 0 |
428 | case 'S':executed 1 time by 1 test: case 'S': | 1 |
429 | break;executed 1 time by 1 test: break; | 1 |
430 | case 'm':executed 2 times by 1 test: case 'm': | 2 |
431 | case 'M':executed 1 time by 1 test: case 'M': | 1 |
432 | multiplier = MINUTES; | - |
433 | break;executed 3 times by 1 test: break; | 3 |
434 | case 'h':executed 1 time by 1 test: case 'h': | 1 |
435 | case 'H': never executed: case 'H': | 0 |
436 | multiplier = HOURS; | - |
437 | break;executed 1 time by 1 test: break; | 1 |
438 | case 'd':executed 1 time by 1 test: case 'd': | 1 |
439 | case 'D': never executed: case 'D': | 0 |
440 | multiplier = DAYS; | - |
441 | break;executed 1 time by 1 test: break; | 1 |
442 | case 'w':executed 1 time by 1 test: case 'w': | 1 |
443 | case 'W': never executed: case 'W': | 0 |
444 | multiplier = WEEKS; | - |
445 | break;executed 1 time by 1 test: break; | 1 |
446 | default: never executed: default: | 0 |
447 | return -1; never executed: return -1; | 0 |
448 | } | - |
449 | if (secs >= LONG_MAX / multiplier)TRUE | evaluated 1 time by 1 test | FALSE | evaluated 8 times by 1 test |
| 1-8 |
450 | return -1;executed 1 time by 1 test: return -1; | 1 |
451 | secs *= multiplier; | - |
452 | if (total >= LONG_MAX - secs)TRUE | never evaluated | FALSE | evaluated 8 times by 1 test |
| 0-8 |
453 | return -1; never executed: return -1; | 0 |
454 | total += secs; | - |
455 | if (total < 0)TRUE | never evaluated | FALSE | evaluated 8 times by 1 test |
| 0-8 |
456 | return -1; never executed: return -1; | 0 |
457 | p = endp; | - |
458 | }executed 8 times by 1 test: end of block | 8 |
459 | | - |
460 | return total;executed 7 times by 1 test: return total; | 7 |
461 | } | - |
462 | | - |
463 | | - |
464 | | - |
465 | | - |
466 | | - |
467 | char * | - |
468 | put_host_port(const char *host, u_short port) | - |
469 | { | - |
470 | char *hoststr; | - |
471 | | - |
472 | if (port == 0 || port == SSH_DEFAULT_PORT)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
473 | return(xstrdup(host)); never executed: return(xstrdup(host)); | 0 |
474 | if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
475 | fatal("put_host_port: asprintf: %s", strerror(errno)); never executed: fatal("put_host_port: asprintf: %s", strerror( (*__errno_location ()) )); | 0 |
476 | debug3("put_host_port: %s", hoststr); | - |
477 | return hoststr; never executed: return hoststr; | 0 |
478 | } | - |
479 | | - |
480 | | - |
481 | | - |
482 | | - |
483 | | - |
484 | | - |
485 | | - |
486 | | - |
487 | | - |
488 | static char * | - |
489 | hpdelim2(char **cp, char *delim) | - |
490 | { | - |
491 | char *s, *old; | - |
492 | | - |
493 | if (cp == NULL || *cp == NULL)TRUE | never evaluated | FALSE | evaluated 2 times by 1 test |
TRUE | never evaluated | FALSE | evaluated 2 times by 1 test |
| 0-2 |
494 | return NULL; never executed: return ((void *)0) ; | 0 |
495 | | - |
496 | old = s = *cp; | - |
497 | if (*s == '[') {TRUE | never evaluated | FALSE | evaluated 2 times by 1 test |
| 0-2 |
498 | if ((s = strchr(s, ']')) == NULL)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
499 | return NULL; never executed: return ((void *)0) ; | 0 |
500 | else | - |
501 | s++; never executed: s++; | 0 |
502 | } else if ((s = strpbrk(s, ":/")) == NULL)TRUE | evaluated 2 times by 1 test | FALSE | never evaluated |
| 0-2 |
503 | s = *cp + strlen(*cp); executed 2 times by 1 test: s = *cp + strlen(*cp); | 2 |
504 | | - |
505 | switch (*s) { | - |
506 | case '\0':executed 2 times by 1 test: case '\0': | 2 |
507 | *cp = NULL; | - |
508 | break;executed 2 times by 1 test: break; | 2 |
509 | | - |
510 | case ':': never executed: case ':': | 0 |
511 | case '/': never executed: case '/': | 0 |
512 | if (delim != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
513 | *delim = *s; never executed: *delim = *s; | 0 |
514 | *s = '\0'; | - |
515 | *cp = s + 1; | - |
516 | break; never executed: break; | 0 |
517 | | - |
518 | default: never executed: default: | 0 |
519 | return NULL; never executed: return ((void *)0) ; | 0 |
520 | } | - |
521 | | - |
522 | return old;executed 2 times by 1 test: return old; | 2 |
523 | } | - |
524 | | - |
525 | char * | - |
526 | hpdelim(char **cp) | - |
527 | { | - |
528 | return hpdelim2(cp, NULL);executed 2 times by 1 test: return hpdelim2(cp, ((void *)0) ); | 2 |
529 | } | - |
530 | | - |
531 | char * | - |
532 | cleanhostname(char *host) | - |
533 | { | - |
534 | if (*host == '[' && host[strlen(host) - 1] == ']') {TRUE | never evaluated | FALSE | evaluated 2 times by 1 test |
TRUE | never evaluated | FALSE | never evaluated |
| 0-2 |
535 | host[strlen(host) - 1] = '\0'; | - |
536 | return (host + 1); never executed: return (host + 1); | 0 |
537 | } else | - |
538 | return host;executed 2 times by 1 test: return host; | 2 |
539 | } | - |
540 | | - |
541 | char * | - |
542 | colon(char *cp) | - |
543 | { | - |
544 | int flag = 0; | - |
545 | | - |
546 | if (*cp == ':') TRUE | never evaluated | FALSE | never evaluated |
| 0 |
547 | return NULL; never executed: return ((void *)0) ; | 0 |
548 | if (*cp == '[')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
549 | flag = 1; never executed: flag = 1; | 0 |
550 | | - |
551 | for (; *cp; ++cp) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
552 | if (*cp == '@' && *(cp+1) == '[')TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
553 | flag = 1; never executed: flag = 1; | 0 |
554 | if (*cp == ']' && *(cp+1) == ':' && flag)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
555 | return (cp+1); never executed: return (cp+1); | 0 |
556 | if (*cp == ':' && !flag)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
557 | return (cp); never executed: return (cp); | 0 |
558 | if (*cp == '/')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
559 | return NULL; never executed: return ((void *)0) ; | 0 |
560 | } never executed: end of block | 0 |
561 | return NULL; never executed: return ((void *)0) ; | 0 |
562 | } | - |
563 | | - |
564 | | - |
565 | | - |
566 | | - |
567 | | - |
568 | | - |
569 | | - |
570 | | - |
571 | | - |
572 | | - |
573 | int | - |
574 | parse_user_host_path(const char *s, char **userp, char **hostp, char **pathp) | - |
575 | { | - |
576 | char *user = NULL, *host = NULL, *path = NULL; | - |
577 | char *sdup, *tmp; | - |
578 | int ret = -1; | - |
579 | | - |
580 | if (userp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
581 | *userp = NULL; never executed: *userp = ((void *)0) ; | 0 |
582 | if (hostp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
583 | *hostp = NULL; never executed: *hostp = ((void *)0) ; | 0 |
584 | if (pathp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
585 | *pathp = NULL; never executed: *pathp = ((void *)0) ; | 0 |
586 | | - |
587 | sdup = xstrdup(s); | - |
588 | | - |
589 | | - |
590 | if ((tmp = colon(sdup)) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
591 | goto out; never executed: goto out; | 0 |
592 | | - |
593 | | - |
594 | *tmp++ = '\0'; | - |
595 | if (*tmp == '\0')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
596 | tmp = "."; never executed: tmp = "."; | 0 |
597 | path = xstrdup(tmp); | - |
598 | | - |
599 | | - |
600 | tmp = strrchr(sdup, '@'); | - |
601 | if (tmp != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
602 | *tmp++ = '\0'; | - |
603 | host = xstrdup(cleanhostname(tmp)); | - |
604 | if (*sdup != '\0')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
605 | user = xstrdup(sdup); never executed: user = xstrdup(sdup); | 0 |
606 | } else { never executed: end of block | 0 |
607 | host = xstrdup(cleanhostname(sdup)); | - |
608 | user = NULL; | - |
609 | } never executed: end of block | 0 |
610 | | - |
611 | | - |
612 | if (userp != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
613 | *userp = user; | - |
614 | user = NULL; | - |
615 | } never executed: end of block | 0 |
616 | if (hostp != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
617 | *hostp = host; | - |
618 | host = NULL; | - |
619 | } never executed: end of block | 0 |
620 | if (pathp != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
621 | *pathp = path; | - |
622 | path = NULL; | - |
623 | } never executed: end of block | 0 |
624 | ret = 0; | - |
625 | out: code before this statement never executed: out: | 0 |
626 | free(sdup); | - |
627 | free(user); | - |
628 | free(host); | - |
629 | free(path); | - |
630 | return ret; never executed: return ret; | 0 |
631 | } | - |
632 | | - |
633 | | - |
634 | | - |
635 | | - |
636 | | - |
637 | | - |
638 | | - |
639 | | - |
640 | | - |
641 | int | - |
642 | parse_user_host_port(const char *s, char **userp, char **hostp, int *portp) | - |
643 | { | - |
644 | char *sdup, *cp, *tmp; | - |
645 | char *user = NULL, *host = NULL; | - |
646 | int port = -1, ret = -1; | - |
647 | | - |
648 | if (userp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
649 | *userp = NULL; never executed: *userp = ((void *)0) ; | 0 |
650 | if (hostp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
651 | *hostp = NULL; never executed: *hostp = ((void *)0) ; | 0 |
652 | if (portp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
653 | *portp = -1; never executed: *portp = -1; | 0 |
654 | | - |
655 | if ((sdup = tmp = strdup(s)) == NULL) never executed: __retval = (char *) memcpy (__retval, s , __len); TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
656 | return -1; never executed: return -1; | 0 |
657 | | - |
658 | if ((cp = strrchr(tmp, '@')) != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
659 | *cp = '\0'; | - |
660 | if (*tmp == '\0')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
661 | goto out; never executed: goto out; | 0 |
662 | if ((user = strdup(tmp)) == NULL) never executed: __retval = (char *) memcpy (__retval, tmp , __len); TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
663 | goto out; never executed: goto out; | 0 |
664 | tmp = cp + 1; | - |
665 | } never executed: end of block | 0 |
666 | | - |
667 | if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0')TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
668 | goto out; never executed: goto out; | 0 |
669 | host = xstrdup(cleanhostname(cp)); | - |
670 | | - |
671 | if (tmp != NULL && *tmp != '\0') {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
672 | if ((port = a2port(tmp)) <= 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
673 | goto out; never executed: goto out; | 0 |
674 | } never executed: end of block | 0 |
675 | | - |
676 | if (userp != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
677 | *userp = user; | - |
678 | user = NULL; | - |
679 | } never executed: end of block | 0 |
680 | if (hostp != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
681 | *hostp = host; | - |
682 | host = NULL; | - |
683 | } never executed: end of block | 0 |
684 | if (portp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
685 | *portp = port; never executed: *portp = port; | 0 |
686 | ret = 0; | - |
687 | out: code before this statement never executed: out: | 0 |
688 | free(sdup); | - |
689 | free(user); | - |
690 | free(host); | - |
691 | return ret; never executed: return ret; | 0 |
692 | } | - |
693 | | - |
694 | | - |
695 | | - |
696 | | - |
697 | | - |
698 | static int | - |
699 | hexchar(const char *s) | - |
700 | { | - |
701 | unsigned char result[2]; | - |
702 | int i; | - |
703 | | - |
704 | for (i = 0; i < 2; i++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
705 | if (s[i] >= '0' && s[i] <= '9')TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
706 | result[i] = (unsigned char)(s[i] - '0'); never executed: result[i] = (unsigned char)(s[i] - '0'); | 0 |
707 | else if (s[i] >= 'a' && s[i] <= 'f')TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
708 | result[i] = (unsigned char)(s[i] - 'a') + 10; never executed: result[i] = (unsigned char)(s[i] - 'a') + 10; | 0 |
709 | else if (s[i] >= 'A' && s[i] <= 'F')TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
710 | result[i] = (unsigned char)(s[i] - 'A') + 10; never executed: result[i] = (unsigned char)(s[i] - 'A') + 10; | 0 |
711 | else | - |
712 | return -1; never executed: return -1; | 0 |
713 | } | - |
714 | return (result[0] << 4) | result[1]; never executed: return (result[0] << 4) | result[1]; | 0 |
715 | } | - |
716 | | - |
717 | | - |
718 | | - |
719 | | - |
720 | | - |
721 | static char * | - |
722 | urldecode(const char *src) | - |
723 | { | - |
724 | char *ret, *dst; | - |
725 | int ch; | - |
726 | | - |
727 | ret = xmalloc(strlen(src) + 1); | - |
728 | for (dst = ret; *src != '\0'; src++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
729 | switch (*src) { | - |
730 | case '+': never executed: case '+': | 0 |
731 | *dst++ = ' '; | - |
732 | break; never executed: break; | 0 |
733 | case '%': never executed: case '%': | 0 |
734 | if (!isxdigit((unsigned char)src[1]) ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
735 | !isxdigit((unsigned char)src[2]) ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
736 | (ch = hexchar(src + 1)) == -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
737 | free(ret); | - |
738 | return NULL; never executed: return ((void *)0) ; | 0 |
739 | } | - |
740 | *dst++ = ch; | - |
741 | src += 2; | - |
742 | break; never executed: break; | 0 |
743 | default: never executed: default: | 0 |
744 | *dst++ = *src; | - |
745 | break; never executed: break; | 0 |
746 | } | - |
747 | } | - |
748 | *dst = '\0'; | - |
749 | | - |
750 | return ret; never executed: return ret; | 0 |
751 | } | - |
752 | | - |
753 | | - |
754 | | - |
755 | | - |
756 | | - |
757 | | - |
758 | | - |
759 | | - |
760 | | - |
761 | | - |
762 | | - |
763 | | - |
764 | | - |
765 | int | - |
766 | parse_uri(const char *scheme, const char *uri, char **userp, char **hostp, | - |
767 | int *portp, char **pathp) | - |
768 | { | - |
769 | char *uridup, *cp, *tmp, ch; | - |
770 | char *user = NULL, *host = NULL, *path = NULL; | - |
771 | int port = -1, ret = -1; | - |
772 | size_t len; | - |
773 | | - |
774 | len = strlen(scheme); | - |
775 | if (strncmp(uri, scheme, len) != 0 || strncmp(uri + len, "://", 3) != 0) never executed: __result = (((const unsigned char *) (const char *) ( uri ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( scheme ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( uri + len ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( "://" ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
776 | return 1; never executed: return 1; | 0 |
777 | uri += len + 3; | - |
778 | | - |
779 | if (userp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
780 | *userp = NULL; never executed: *userp = ((void *)0) ; | 0 |
781 | if (hostp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
782 | *hostp = NULL; never executed: *hostp = ((void *)0) ; | 0 |
783 | if (portp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
784 | *portp = -1; never executed: *portp = -1; | 0 |
785 | if (pathp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
786 | *pathp = NULL; never executed: *pathp = ((void *)0) ; | 0 |
787 | | - |
788 | uridup = tmp = xstrdup(uri); | - |
789 | | - |
790 | | - |
791 | if ((cp = strchr(tmp, '@')) != NULL) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
792 | char *delim; | - |
793 | | - |
794 | *cp = '\0'; | - |
795 | | - |
796 | if ((delim = strchr(tmp, ';')) != NULL) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
797 | | - |
798 | *delim = '\0'; | - |
799 | } never executed: end of block | 0 |
800 | if (*tmp == '\0') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
801 | | - |
802 | goto out; never executed: goto out; | 0 |
803 | } | - |
804 | if ((user = urldecode(tmp)) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
805 | goto out; never executed: goto out; | 0 |
806 | tmp = cp + 1; | - |
807 | } never executed: end of block | 0 |
808 | | - |
809 | | - |
810 | if ((cp = hpdelim2(&tmp, &ch)) == NULL || *cp == '\0')TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
811 | goto out; never executed: goto out; | 0 |
812 | host = xstrdup(cleanhostname(cp)); | - |
813 | if (!valid_domain(host, 0, NULL))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
814 | goto out; never executed: goto out; | 0 |
815 | | - |
816 | if (tmp != NULL && *tmp != '\0') {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
817 | if (ch == ':') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
818 | | - |
819 | if ((cp = strchr(tmp, '/')) != NULL)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
820 | *cp = '\0'; never executed: *cp = '\0'; | 0 |
821 | if ((port = a2port(tmp)) <= 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
822 | goto out; never executed: goto out; | 0 |
823 | tmp = cp ? cp + 1 : NULL;TRUE | never evaluated | FALSE | never evaluated |
| 0 |
824 | } never executed: end of block | 0 |
825 | if (tmp != NULL && *tmp != '\0') {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
826 | | - |
827 | if ((path = urldecode(tmp)) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
828 | goto out; never executed: goto out; | 0 |
829 | } never executed: end of block | 0 |
830 | } never executed: end of block | 0 |
831 | | - |
832 | | - |
833 | if (userp != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
834 | *userp = user; | - |
835 | user = NULL; | - |
836 | } never executed: end of block | 0 |
837 | if (hostp != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
838 | *hostp = host; | - |
839 | host = NULL; | - |
840 | } never executed: end of block | 0 |
841 | if (portp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
842 | *portp = port; never executed: *portp = port; | 0 |
843 | if (pathp != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
844 | *pathp = path; | - |
845 | path = NULL; | - |
846 | } never executed: end of block | 0 |
847 | ret = 0; | - |
848 | out: code before this statement never executed: out: | 0 |
849 | free(uridup); | - |
850 | free(user); | - |
851 | free(host); | - |
852 | free(path); | - |
853 | return ret; never executed: return ret; | 0 |
854 | } | - |
855 | | - |
856 | | - |
857 | void | - |
858 | addargs(arglist *args, char *fmt, ...) | - |
859 | { | - |
860 | va_list ap; | - |
861 | char *cp; | - |
862 | u_int nalloc; | - |
863 | int r; | - |
864 | | - |
865 | va_start(ap, fmt); | - |
866 | r = vasprintf(&cp, fmt, ap); | - |
867 | va_end(ap); | - |
868 | if (r == -1)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
869 | fatal("addargs: argument too long"); never executed: fatal("addargs: argument too long"); | 0 |
870 | | - |
871 | nalloc = args->nalloc; | - |
872 | if (args->list == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
873 | nalloc = 32; | - |
874 | args->num = 0; | - |
875 | } else if (args->num+2 >= nalloc) never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
876 | nalloc *= 2; never executed: nalloc *= 2; | 0 |
877 | | - |
878 | args->list = xrecallocarray(args->list, args->nalloc, nalloc, sizeof(char *)); | - |
879 | args->nalloc = nalloc; | - |
880 | args->list[args->num++] = cp; | - |
881 | args->list[args->num] = NULL; | - |
882 | } never executed: end of block | 0 |
883 | | - |
884 | void | - |
885 | replacearg(arglist *args, u_int which, char *fmt, ...) | - |
886 | { | - |
887 | va_list ap; | - |
888 | char *cp; | - |
889 | int r; | - |
890 | | - |
891 | va_start(ap, fmt); | - |
892 | r = vasprintf(&cp, fmt, ap); | - |
893 | va_end(ap); | - |
894 | if (r == -1)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
895 | fatal("replacearg: argument too long"); never executed: fatal("replacearg: argument too long"); | 0 |
896 | | - |
897 | if (which >= args->num)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
898 | fatal("replacearg: tried to replace invalid arg %d >= %d", never executed: fatal("replacearg: tried to replace invalid arg %d >= %d", which, args->num); | 0 |
899 | which, args->num); never executed: fatal("replacearg: tried to replace invalid arg %d >= %d", which, args->num); | 0 |
900 | free(args->list[which]); | - |
901 | args->list[which] = cp; | - |
902 | } never executed: end of block | 0 |
903 | | - |
904 | void | - |
905 | freeargs(arglist *args) | - |
906 | { | - |
907 | u_int i; | - |
908 | | - |
909 | if (args->list != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
910 | for (i = 0; i < args->num; i++)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
911 | free(args->list[i]); never executed: free(args->list[i]); | 0 |
912 | free(args->list); | - |
913 | args->nalloc = args->num = 0; | - |
914 | args->list = NULL; | - |
915 | } never executed: end of block | 0 |
916 | } never executed: end of block | 0 |
917 | | - |
918 | | - |
919 | | - |
920 | | - |
921 | | - |
922 | char * | - |
923 | tilde_expand_filename(const char *filename, uid_t uid) | - |
924 | { | - |
925 | const char *path, *sep; | - |
926 | char user[128], *ret; | - |
927 | struct passwd *pw; | - |
928 | u_int len, slash; | - |
929 | | - |
930 | if (*filename != '~')TRUE | evaluated 8 times by 1 test | FALSE | never evaluated |
| 0-8 |
931 | return (xstrdup(filename));executed 8 times by 1 test: return (xstrdup(filename)); | 8 |
932 | filename++; | - |
933 | | - |
934 | path = strchr(filename, '/');TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
935 | if (path != NULL && path > filename) { TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
936 | slash = path - filename; | - |
937 | if (slash > sizeof(user) - 1)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
938 | fatal("tilde_expand_filename: ~username too long"); never executed: fatal("tilde_expand_filename: ~username too long"); | 0 |
939 | memcpy(user, filename, slash); | - |
940 | user[slash] = '\0'; | - |
941 | if ((pw = getpwnam(user)) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
942 | fatal("tilde_expand_filename: No such user %s", user); never executed: fatal("tilde_expand_filename: No such user %s", user); | 0 |
943 | } else if ((pw = getpwuid(uid)) == NULL) never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
944 | fatal("tilde_expand_filename: No such uid %ld", (long)uid); never executed: fatal("tilde_expand_filename: No such uid %ld", (long)uid); | 0 |
945 | | - |
946 | | - |
947 | len = strlen(pw->pw_dir); | - |
948 | if (len == 0 || pw->pw_dir[len - 1] != '/')TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
949 | sep = "/"; never executed: sep = "/"; | 0 |
950 | else | - |
951 | sep = ""; never executed: sep = ""; | 0 |
952 | | - |
953 | | - |
954 | if (path != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
955 | filename = path + 1; never executed: filename = path + 1; | 0 |
956 | | - |
957 | if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
958 | fatal("tilde_expand_filename: Path too long"); never executed: fatal("tilde_expand_filename: Path too long"); | 0 |
959 | | - |
960 | return (ret); never executed: return (ret); | 0 |
961 | } | - |
962 | | - |
963 | | - |
964 | | - |
965 | | - |
966 | | - |
967 | | - |
968 | | - |
969 | char * | - |
970 | percent_expand(const char *string, ...) | - |
971 | { | - |
972 | #define EXPAND_MAX_KEYS 16 | - |
973 | u_int num_keys, i, j; | - |
974 | struct { | - |
975 | const char *key; | - |
976 | const char *repl; | - |
977 | } keys[EXPAND_MAX_KEYS]; | - |
978 | char buf[4096]; | - |
979 | va_list ap; | - |
980 | | - |
981 | | - |
982 | va_start(ap, string); | - |
983 | for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
984 | keys[num_keys].key = va_arg(ap, char *); | - |
985 | if (keys[num_keys].key == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
986 | break; never executed: break; | 0 |
987 | keys[num_keys].repl = va_arg(ap, char *); | - |
988 | if (keys[num_keys].repl == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
989 | fatal("%s: NULL replacement", __func__); never executed: fatal("%s: NULL replacement", __func__); | 0 |
990 | } never executed: end of block | 0 |
991 | if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
992 | fatal("%s: too many keys", __func__); never executed: fatal("%s: too many keys", __func__); | 0 |
993 | va_end(ap); | - |
994 | | - |
995 | | - |
996 | *buf = '\0'; | - |
997 | for (i = 0; *string != '\0'; string++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
998 | if (*string != '%') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
999 | append: | - |
1000 | buf[i++] = *string; | - |
1001 | if (i >= sizeof(buf))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1002 | fatal("%s: string too long", __func__); never executed: fatal("%s: string too long", __func__); | 0 |
1003 | buf[i] = '\0'; | - |
1004 | continue; never executed: continue; | 0 |
1005 | } | - |
1006 | string++; | - |
1007 | | - |
1008 | if (*string == '%')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1009 | goto append; never executed: goto append; | 0 |
1010 | if (*string == '\0')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1011 | fatal("%s: invalid format", __func__); never executed: fatal("%s: invalid format", __func__); | 0 |
1012 | for (j = 0; j < num_keys; j++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1013 | if (strchr(keys[j].key, *string) != NULL) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1014 | i = strlcat(buf, keys[j].repl, sizeof(buf)); | - |
1015 | if (i >= sizeof(buf))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1016 | fatal("%s: string too long", __func__); never executed: fatal("%s: string too long", __func__); | 0 |
1017 | break; never executed: break; | 0 |
1018 | } | - |
1019 | } never executed: end of block | 0 |
1020 | if (j >= num_keys)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1021 | fatal("%s: unknown key %%%c", __func__, *string); never executed: fatal("%s: unknown key %%%c", __func__, *string); | 0 |
1022 | } never executed: end of block | 0 |
1023 | return (xstrdup(buf)); never executed: return (xstrdup(buf)); | 0 |
1024 | #undef EXPAND_MAX_KEYS | - |
1025 | } | - |
1026 | | - |
1027 | int | - |
1028 | tun_open(int tun, int mode, char **ifname) | - |
1029 | { | - |
1030 | #if defined(CUSTOM_SYS_TUN_OPEN) | - |
1031 | return (sys_tun_open(tun, mode, ifname)); never executed: return (sys_tun_open(tun, mode, ifname)); | 0 |
1032 | #elif defined(SSH_TUN_OPENBSD) | - |
1033 | struct ifreq ifr; | - |
1034 | char name[100]; | - |
1035 | int fd = -1, sock; | - |
1036 | const char *tunbase = "tun"; | - |
1037 | | - |
1038 | if (ifname != NULL) | - |
1039 | *ifname = NULL; | - |
1040 | | - |
1041 | if (mode == SSH_TUNMODE_ETHERNET) | - |
1042 | tunbase = "tap"; | - |
1043 | | - |
1044 | | - |
1045 | if (tun <= SSH_TUNID_MAX) { | - |
1046 | snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); | - |
1047 | fd = open(name, O_RDWR); | - |
1048 | } else if (tun == SSH_TUNID_ANY) { | - |
1049 | for (tun = 100; tun >= 0; tun--) { | - |
1050 | snprintf(name, sizeof(name), "/dev/%s%d", | - |
1051 | tunbase, tun); | - |
1052 | if ((fd = open(name, O_RDWR)) >= 0) | - |
1053 | break; | - |
1054 | } | - |
1055 | } else { | - |
1056 | debug("%s: invalid tunnel %u", __func__, tun); | - |
1057 | return -1; | - |
1058 | } | - |
1059 | | - |
1060 | if (fd < 0) { | - |
1061 | debug("%s: %s open: %s", __func__, name, strerror(errno)); | - |
1062 | return -1; | - |
1063 | } | - |
1064 | | - |
1065 | debug("%s: %s mode %d fd %d", __func__, name, mode, fd); | - |
1066 | | - |
1067 | | - |
1068 | snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); | - |
1069 | if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) | - |
1070 | goto failed; | - |
1071 | | - |
1072 | if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { | - |
1073 | debug("%s: get interface %s flags: %s", __func__, | - |
1074 | ifr.ifr_name, strerror(errno)); | - |
1075 | goto failed; | - |
1076 | } | - |
1077 | | - |
1078 | if (!(ifr.ifr_flags & IFF_UP)) { | - |
1079 | ifr.ifr_flags |= IFF_UP; | - |
1080 | if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { | - |
1081 | debug("%s: activate interface %s: %s", __func__, | - |
1082 | ifr.ifr_name, strerror(errno)); | - |
1083 | goto failed; | - |
1084 | } | - |
1085 | } | - |
1086 | | - |
1087 | if (ifname != NULL) | - |
1088 | *ifname = xstrdup(ifr.ifr_name); | - |
1089 | | - |
1090 | close(sock); | - |
1091 | return fd; | - |
1092 | | - |
1093 | failed: | - |
1094 | if (fd >= 0) | - |
1095 | close(fd); | - |
1096 | if (sock >= 0) | - |
1097 | close(sock); | - |
1098 | return -1; | - |
1099 | #else | - |
1100 | error("Tunnel interfaces are not supported on this platform"); | - |
1101 | return (-1); | - |
1102 | #endif | - |
1103 | } | - |
1104 | | - |
1105 | void | - |
1106 | sanitise_stdfd(void) | - |
1107 | { | - |
1108 | int nullfd, dupfd; | - |
1109 | | - |
1110 | if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {TRUE | never evaluated | FALSE | evaluated 30 times by 2 tests |
| 0-30 |
1111 | fprintf(stderr, "Couldn't open /dev/null: %s\n", | - |
1112 | strerror(errno)); | - |
1113 | exit(1); never executed: exit(1); | 0 |
1114 | } | - |
1115 | while (++dupfd <= STDERR_FILENO) {TRUE | never evaluated | FALSE | evaluated 30 times by 2 tests |
| 0-30 |
1116 | | - |
1117 | if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1118 | if (dup2(nullfd, dupfd) == -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1119 | fprintf(stderr, "dup2: %s\n", strerror(errno)); | - |
1120 | exit(1); never executed: exit(1); | 0 |
1121 | } | - |
1122 | } never executed: end of block | 0 |
1123 | } never executed: end of block | 0 |
1124 | if (nullfd > STDERR_FILENO)TRUE | evaluated 30 times by 2 tests | FALSE | never evaluated |
| 0-30 |
1125 | close(nullfd);executed 30 times by 2 tests: close(nullfd); | 30 |
1126 | }executed 30 times by 2 tests: end of block | 30 |
1127 | | - |
1128 | char * | - |
1129 | tohex(const void *vp, size_t l) | - |
1130 | { | - |
1131 | const u_char *p = (const u_char *)vp; | - |
1132 | char b[3], *r; | - |
1133 | size_t i, hl; | - |
1134 | | - |
1135 | if (l > 65536)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1136 | return xstrdup("tohex: length > 65536"); never executed: return xstrdup("tohex: length > 65536"); | 0 |
1137 | | - |
1138 | hl = l * 2 + 1; | - |
1139 | r = xcalloc(1, hl); | - |
1140 | for (i = 0; i < l; i++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1141 | snprintf(b, sizeof(b), "%02x", p[i]); | - |
1142 | strlcat(r, b, hl); | - |
1143 | } never executed: end of block | 0 |
1144 | return (r); never executed: return (r); | 0 |
1145 | } | - |
1146 | | - |
1147 | u_int64_t | - |
1148 | get_u64(const void *vp) | - |
1149 | { | - |
1150 | const u_char *p = (const u_char *)vp; | - |
1151 | u_int64_t v; | - |
1152 | | - |
1153 | v = (u_int64_t)p[0] << 56; | - |
1154 | v |= (u_int64_t)p[1] << 48; | - |
1155 | v |= (u_int64_t)p[2] << 40; | - |
1156 | v |= (u_int64_t)p[3] << 32; | - |
1157 | v |= (u_int64_t)p[4] << 24; | - |
1158 | v |= (u_int64_t)p[5] << 16; | - |
1159 | v |= (u_int64_t)p[6] << 8; | - |
1160 | v |= (u_int64_t)p[7]; | - |
1161 | | - |
1162 | return (v); never executed: return (v); | 0 |
1163 | } | - |
1164 | | - |
1165 | u_int32_t | - |
1166 | get_u32(const void *vp) | - |
1167 | { | - |
1168 | const u_char *p = (const u_char *)vp; | - |
1169 | u_int32_t v; | - |
1170 | | - |
1171 | v = (u_int32_t)p[0] << 24; | - |
1172 | v |= (u_int32_t)p[1] << 16; | - |
1173 | v |= (u_int32_t)p[2] << 8; | - |
1174 | v |= (u_int32_t)p[3]; | - |
1175 | | - |
1176 | return (v); never executed: return (v); | 0 |
1177 | } | - |
1178 | | - |
1179 | u_int32_t | - |
1180 | get_u32_le(const void *vp) | - |
1181 | { | - |
1182 | const u_char *p = (const u_char *)vp; | - |
1183 | u_int32_t v; | - |
1184 | | - |
1185 | v = (u_int32_t)p[0]; | - |
1186 | v |= (u_int32_t)p[1] << 8; | - |
1187 | v |= (u_int32_t)p[2] << 16; | - |
1188 | v |= (u_int32_t)p[3] << 24; | - |
1189 | | - |
1190 | return (v); never executed: return (v); | 0 |
1191 | } | - |
1192 | | - |
1193 | u_int16_t | - |
1194 | get_u16(const void *vp) | - |
1195 | { | - |
1196 | const u_char *p = (const u_char *)vp; | - |
1197 | u_int16_t v; | - |
1198 | | - |
1199 | v = (u_int16_t)p[0] << 8; | - |
1200 | v |= (u_int16_t)p[1]; | - |
1201 | | - |
1202 | return (v); never executed: return (v); | 0 |
1203 | } | - |
1204 | | - |
1205 | void | - |
1206 | put_u64(void *vp, u_int64_t v) | - |
1207 | { | - |
1208 | u_char *p = (u_char *)vp; | - |
1209 | | - |
1210 | p[0] = (u_char)(v >> 56) & 0xff; | - |
1211 | p[1] = (u_char)(v >> 48) & 0xff; | - |
1212 | p[2] = (u_char)(v >> 40) & 0xff; | - |
1213 | p[3] = (u_char)(v >> 32) & 0xff; | - |
1214 | p[4] = (u_char)(v >> 24) & 0xff; | - |
1215 | p[5] = (u_char)(v >> 16) & 0xff; | - |
1216 | p[6] = (u_char)(v >> 8) & 0xff; | - |
1217 | p[7] = (u_char)v & 0xff; | - |
1218 | } never executed: end of block | 0 |
1219 | | - |
1220 | void | - |
1221 | put_u32(void *vp, u_int32_t v) | - |
1222 | { | - |
1223 | u_char *p = (u_char *)vp; | - |
1224 | | - |
1225 | p[0] = (u_char)(v >> 24) & 0xff; | - |
1226 | p[1] = (u_char)(v >> 16) & 0xff; | - |
1227 | p[2] = (u_char)(v >> 8) & 0xff; | - |
1228 | p[3] = (u_char)v & 0xff; | - |
1229 | } never executed: end of block | 0 |
1230 | | - |
1231 | void | - |
1232 | put_u32_le(void *vp, u_int32_t v) | - |
1233 | { | - |
1234 | u_char *p = (u_char *)vp; | - |
1235 | | - |
1236 | p[0] = (u_char)v & 0xff; | - |
1237 | p[1] = (u_char)(v >> 8) & 0xff; | - |
1238 | p[2] = (u_char)(v >> 16) & 0xff; | - |
1239 | p[3] = (u_char)(v >> 24) & 0xff; | - |
1240 | } never executed: end of block | 0 |
1241 | | - |
1242 | void | - |
1243 | put_u16(void *vp, u_int16_t v) | - |
1244 | { | - |
1245 | u_char *p = (u_char *)vp; | - |
1246 | | - |
1247 | p[0] = (u_char)(v >> 8) & 0xff; | - |
1248 | p[1] = (u_char)v & 0xff; | - |
1249 | } never executed: end of block | 0 |
1250 | | - |
1251 | void | - |
1252 | ms_subtract_diff(struct timeval *start, int *ms) | - |
1253 | { | - |
1254 | struct timeval diff, finish; | - |
1255 | | - |
1256 | monotime_tv(&finish); | - |
1257 | timersub(&finish, start, &diff); never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1258 | *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); | - |
1259 | } never executed: end of block | 0 |
1260 | | - |
1261 | void | - |
1262 | ms_to_timeval(struct timeval *tv, int ms) | - |
1263 | { | - |
1264 | if (ms < 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1265 | ms = 0; never executed: ms = 0; | 0 |
1266 | tv->tv_sec = ms / 1000; | - |
1267 | tv->tv_usec = (ms % 1000) * 1000; | - |
1268 | } never executed: end of block | 0 |
1269 | | - |
1270 | void | - |
1271 | monotime_ts(struct timespec *ts) | - |
1272 | { | - |
1273 | struct timeval tv; | - |
1274 | #if defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_BOOTTIME) || \ | - |
1275 | defined(CLOCK_MONOTONIC) || defined(CLOCK_REALTIME)) | - |
1276 | static int gettime_failed = 0; | - |
1277 | | - |
1278 | if (!gettime_failed) {TRUE | evaluated 352 times by 1 test | FALSE | never evaluated |
| 0-352 |
1279 | # ifdef CLOCK_BOOTTIME | - |
1280 | if (clock_gettime(CLOCK_BOOTTIME, ts) == 0)TRUE | evaluated 352 times by 1 test | FALSE | never evaluated |
| 0-352 |
1281 | return;executed 352 times by 1 test: return; | 352 |
1282 | # endif /* CLOCK_BOOTTIME */ | - |
1283 | # ifdef CLOCK_MONOTONIC | - |
1284 | if (clock_gettime(CLOCK_MONOTONIC, ts) == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1285 | return; never executed: return; | 0 |
1286 | # endif /* CLOCK_MONOTONIC */ | - |
1287 | # ifdef CLOCK_REALTIME | - |
1288 | | - |
1289 | if (clock_gettime(CLOCK_REALTIME, ts) == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1290 | return; never executed: return; | 0 |
1291 | # endif /* CLOCK_REALTIME */ | - |
1292 | debug3("clock_gettime: %s", strerror(errno)); | - |
1293 | gettime_failed = 1; | - |
1294 | } never executed: end of block | 0 |
1295 | #endif /* HAVE_CLOCK_GETTIME && (BOOTTIME || MONOTONIC || REALTIME) */ | - |
1296 | gettimeofday(&tv, NULL); | - |
1297 | ts->tv_sec = tv.tv_sec; | - |
1298 | ts->tv_nsec = (long)tv.tv_usec * 1000; | - |
1299 | } never executed: end of block | 0 |
1300 | | - |
1301 | void | - |
1302 | monotime_tv(struct timeval *tv) | - |
1303 | { | - |
1304 | struct timespec ts; | - |
1305 | | - |
1306 | monotime_ts(&ts); | - |
1307 | tv->tv_sec = ts.tv_sec; | - |
1308 | tv->tv_usec = ts.tv_nsec / 1000; | - |
1309 | } never executed: end of block | 0 |
1310 | | - |
1311 | time_t | - |
1312 | monotime(void) | - |
1313 | { | - |
1314 | struct timespec ts; | - |
1315 | | - |
1316 | monotime_ts(&ts); | - |
1317 | return ts.tv_sec;executed 352 times by 1 test: return ts.tv_sec; | 352 |
1318 | } | - |
1319 | | - |
1320 | double | - |
1321 | monotime_double(void) | - |
1322 | { | - |
1323 | struct timespec ts; | - |
1324 | | - |
1325 | monotime_ts(&ts); | - |
1326 | return ts.tv_sec + ((double)ts.tv_nsec / 1000000000); never executed: return ts.tv_sec + ((double)ts.tv_nsec / 1000000000); | 0 |
1327 | } | - |
1328 | | - |
1329 | void | - |
1330 | bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) | - |
1331 | { | - |
1332 | bw->buflen = buflen; | - |
1333 | bw->rate = kbps; | - |
1334 | bw->thresh = bw->rate; | - |
1335 | bw->lamt = 0; | - |
1336 | timerclear(&bw->bwstart); | - |
1337 | timerclear(&bw->bwend); | - |
1338 | } never executed: end of block never executed: end of block | 0 |
1339 | | - |
1340 | | - |
1341 | void | - |
1342 | bandwidth_limit(struct bwlimit *bw, size_t read_len) | - |
1343 | { | - |
1344 | u_int64_t waitlen; | - |
1345 | struct timespec ts, rm; | - |
1346 | | - |
1347 | if (!timerisset(&bw->bwstart)) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1348 | monotime_tv(&bw->bwstart); | - |
1349 | return; never executed: return; | 0 |
1350 | } | - |
1351 | | - |
1352 | bw->lamt += read_len; | - |
1353 | if (bw->lamt < bw->thresh)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1354 | return; never executed: return; | 0 |
1355 | | - |
1356 | monotime_tv(&bw->bwend); | - |
1357 | timersub(&bw->bwend, &bw->bwstart, &bw->bwend); never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1358 | if (!timerisset(&bw->bwend))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1359 | return; never executed: return; | 0 |
1360 | | - |
1361 | bw->lamt *= 8; | - |
1362 | waitlen = (double)1000000L * bw->lamt / bw->rate; | - |
1363 | | - |
1364 | bw->bwstart.tv_sec = waitlen / 1000000L; | - |
1365 | bw->bwstart.tv_usec = waitlen % 1000000L; | - |
1366 | | - |
1367 | if (timercmp(&bw->bwstart, &bw->bwend, >)) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1368 | timersub(&bw->bwstart, &bw->bwend, &bw->bwend); never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1369 | | - |
1370 | | - |
1371 | if (bw->bwend.tv_sec) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1372 | bw->thresh /= 2; | - |
1373 | if (bw->thresh < bw->buflen / 4)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1374 | bw->thresh = bw->buflen / 4; never executed: bw->thresh = bw->buflen / 4; | 0 |
1375 | } else if (bw->bwend.tv_usec < 10000) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1376 | bw->thresh *= 2; | - |
1377 | if (bw->thresh > bw->buflen * 8)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1378 | bw->thresh = bw->buflen * 8; never executed: bw->thresh = bw->buflen * 8; | 0 |
1379 | } never executed: end of block | 0 |
1380 | | - |
1381 | TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts); | - |
1382 | while (nanosleep(&ts, &rm) == -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1383 | if (errno != EINTR)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1384 | break; never executed: break; | 0 |
1385 | ts = rm; | - |
1386 | } never executed: end of block | 0 |
1387 | } never executed: end of block | 0 |
1388 | | - |
1389 | bw->lamt = 0; | - |
1390 | monotime_tv(&bw->bwstart); | - |
1391 | } never executed: end of block | 0 |
1392 | | - |
1393 | | - |
1394 | void | - |
1395 | mktemp_proto(char *s, size_t len) | - |
1396 | { | - |
1397 | const char *tmpdir; | - |
1398 | int r; | - |
1399 | | - |
1400 | if ((tmpdir = getenv("TMPDIR")) != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1401 | r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir); | - |
1402 | if (r > 0 && (size_t)r < len)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1403 | return; never executed: return; | 0 |
1404 | } never executed: end of block | 0 |
1405 | r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX"); | - |
1406 | if (r < 0 || (size_t)r >= len)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1407 | fatal("%s: template string too short", __func__); never executed: fatal("%s: template string too short", __func__); | 0 |
1408 | } never executed: end of block | 0 |
1409 | | - |
1410 | static const struct { | - |
1411 | const char *name; | - |
1412 | int value; | - |
1413 | } ipqos[] = { | - |
1414 | { "none", INT_MAX }, | - |
1415 | { "af11", IPTOS_DSCP_AF11 }, | - |
1416 | { "af12", IPTOS_DSCP_AF12 }, | - |
1417 | { "af13", IPTOS_DSCP_AF13 }, | - |
1418 | { "af21", IPTOS_DSCP_AF21 }, | - |
1419 | { "af22", IPTOS_DSCP_AF22 }, | - |
1420 | { "af23", IPTOS_DSCP_AF23 }, | - |
1421 | { "af31", IPTOS_DSCP_AF31 }, | - |
1422 | { "af32", IPTOS_DSCP_AF32 }, | - |
1423 | { "af33", IPTOS_DSCP_AF33 }, | - |
1424 | { "af41", IPTOS_DSCP_AF41 }, | - |
1425 | { "af42", IPTOS_DSCP_AF42 }, | - |
1426 | { "af43", IPTOS_DSCP_AF43 }, | - |
1427 | { "cs0", IPTOS_DSCP_CS0 }, | - |
1428 | { "cs1", IPTOS_DSCP_CS1 }, | - |
1429 | { "cs2", IPTOS_DSCP_CS2 }, | - |
1430 | { "cs3", IPTOS_DSCP_CS3 }, | - |
1431 | { "cs4", IPTOS_DSCP_CS4 }, | - |
1432 | { "cs5", IPTOS_DSCP_CS5 }, | - |
1433 | { "cs6", IPTOS_DSCP_CS6 }, | - |
1434 | { "cs7", IPTOS_DSCP_CS7 }, | - |
1435 | { "ef", IPTOS_DSCP_EF }, | - |
1436 | { "lowdelay", IPTOS_LOWDELAY }, | - |
1437 | { "throughput", IPTOS_THROUGHPUT }, | - |
1438 | { "reliability", IPTOS_RELIABILITY }, | - |
1439 | { NULL, -1 } | - |
1440 | }; | - |
1441 | | - |
1442 | int | - |
1443 | parse_ipqos(const char *cp) | - |
1444 | { | - |
1445 | u_int i; | - |
1446 | char *ep; | - |
1447 | long val; | - |
1448 | | - |
1449 | if (cp == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1450 | return -1; never executed: return -1; | 0 |
1451 | for (i = 0; ipqos[i].name != NULL; i++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1452 | if (strcasecmp(cp, ipqos[i].name) == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1453 | return ipqos[i].value; never executed: return ipqos[i].value; | 0 |
1454 | } never executed: end of block | 0 |
1455 | | - |
1456 | val = strtol(cp, &ep, 0); | - |
1457 | if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1458 | return -1; never executed: return -1; | 0 |
1459 | return val; never executed: return val; | 0 |
1460 | } | - |
1461 | | - |
1462 | const char * | - |
1463 | iptos2str(int iptos) | - |
1464 | { | - |
1465 | int i; | - |
1466 | static char iptos_str[sizeof "0xff"]; | - |
1467 | | - |
1468 | for (i = 0; ipqos[i].name != NULL; i++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1469 | if (ipqos[i].value == iptos)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1470 | return ipqos[i].name; never executed: return ipqos[i].name; | 0 |
1471 | } never executed: end of block | 0 |
1472 | snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos); | - |
1473 | return iptos_str; never executed: return iptos_str; | 0 |
1474 | } | - |
1475 | | - |
1476 | void | - |
1477 | lowercase(char *s) | - |
1478 | { | - |
1479 | for (; *s; s++)TRUE | evaluated 8400 times by 1 test | FALSE | evaluated 520 times by 1 test |
| 520-8400 |
1480 | *s = tolower((u_char)*s);executed 8400 times by 1 test: *s = (__extension__ ({ int __res; if (sizeof ( (u_char)*s ) > 1) { if (__builtin_constant_p ( (u_char)*s )) { int __c = ( (u_char)*s ); __res = __c < -128 || __c > 255 ? __c : (*__ctype_tolower_loc ())[__c]; } else __res = tolower ( (u_char)*s ); } else __res = (*__ctype_tolower_loc ())[(int) ( (u_char)*s )]; __res; })) ; never executed: end of block never executed: __res = tolower ( (u_char)*s ); executed 8400 times by 1 test: __res = (*__ctype_tolower_loc ())[(int) ( (u_char)*s )]; TRUE | never evaluated | FALSE | evaluated 8400 times by 1 test |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0-8400 |
1481 | }executed 520 times by 1 test: end of block | 520 |
1482 | | - |
1483 | int | - |
1484 | unix_listener(const char *path, int backlog, int unlink_first) | - |
1485 | { | - |
1486 | struct sockaddr_un sunaddr; | - |
1487 | int saved_errno, sock; | - |
1488 | | - |
1489 | memset(&sunaddr, 0, sizeof(sunaddr)); | - |
1490 | sunaddr.sun_family = AF_UNIX; | - |
1491 | if (strlcpy(sunaddr.sun_path, path,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1492 | sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1493 | error("%s: path \"%s\" too long for Unix domain socket", | - |
1494 | __func__, path); | - |
1495 | errno = ENAMETOOLONG; | - |
1496 | return -1; never executed: return -1; | 0 |
1497 | } | - |
1498 | | - |
1499 | sock = socket(PF_UNIX, SOCK_STREAM, 0); | - |
1500 | if (sock < 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1501 | saved_errno = errno; | - |
1502 | error("%s: socket: %.100s", __func__, strerror(errno)); | - |
1503 | errno = saved_errno; | - |
1504 | return -1; never executed: return -1; | 0 |
1505 | } | - |
1506 | if (unlink_first == 1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1507 | if (unlink(path) != 0 && errno != ENOENT)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1508 | error("unlink(%s): %.100s", path, strerror(errno)); never executed: error("unlink(%s): %.100s", path, strerror( (*__errno_location ()) )); | 0 |
1509 | } never executed: end of block | 0 |
1510 | if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1511 | saved_errno = errno; | - |
1512 | error("%s: cannot bind to path %s: %s", | - |
1513 | __func__, path, strerror(errno)); | - |
1514 | close(sock); | - |
1515 | errno = saved_errno; | - |
1516 | return -1; never executed: return -1; | 0 |
1517 | } | - |
1518 | if (listen(sock, backlog) < 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1519 | saved_errno = errno; | - |
1520 | error("%s: cannot listen on path %s: %s", | - |
1521 | __func__, path, strerror(errno)); | - |
1522 | close(sock); | - |
1523 | unlink(path); | - |
1524 | errno = saved_errno; | - |
1525 | return -1; never executed: return -1; | 0 |
1526 | } | - |
1527 | return sock; never executed: return sock; | 0 |
1528 | } | - |
1529 | | - |
1530 | void | - |
1531 | sock_set_v6only(int s) | - |
1532 | { | - |
1533 | #if defined(IPV6_V6ONLY) && !defined(__OpenBSD__) | - |
1534 | int on = 1; | - |
1535 | | - |
1536 | debug3("%s: set socket %d IPV6_V6ONLY", __func__, s); | - |
1537 | if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1538 | error("setsockopt IPV6_V6ONLY: %s", strerror(errno)); never executed: error("setsockopt IPV6_V6ONLY: %s", strerror( (*__errno_location ()) )); | 0 |
1539 | #endif | - |
1540 | } never executed: end of block | 0 |
1541 | | - |
1542 | | - |
1543 | | - |
1544 | | - |
1545 | | - |
1546 | static int | - |
1547 | strcmp_maybe_null(const char *a, const char *b) | - |
1548 | { | - |
1549 | if ((a == NULL && b != NULL) || (a != NULL && b == NULL))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1550 | return 0; never executed: return 0; | 0 |
1551 | if (a != NULL && strcmp(a, b) != 0) never executed: __result = (((const unsigned char *) (const char *) ( a ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( b ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1552 | return 0; never executed: return 0; | 0 |
1553 | return 1; never executed: return 1; | 0 |
1554 | } | - |
1555 | | - |
1556 | | - |
1557 | | - |
1558 | | - |
1559 | | - |
1560 | int | - |
1561 | forward_equals(const struct Forward *a, const struct Forward *b) | - |
1562 | { | - |
1563 | if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1564 | return 0; never executed: return 0; | 0 |
1565 | if (a->listen_port != b->listen_port)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1566 | return 0; never executed: return 0; | 0 |
1567 | if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1568 | return 0; never executed: return 0; | 0 |
1569 | if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1570 | return 0; never executed: return 0; | 0 |
1571 | if (a->connect_port != b->connect_port)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1572 | return 0; never executed: return 0; | 0 |
1573 | if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1574 | return 0; never executed: return 0; | 0 |
1575 | | - |
1576 | return 1; never executed: return 1; | 0 |
1577 | } | - |
1578 | | - |
1579 | | - |
1580 | int | - |
1581 | daemonized(void) | - |
1582 | { | - |
1583 | int fd; | - |
1584 | | - |
1585 | if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1586 | close(fd); | - |
1587 | return 0; never executed: return 0; | 0 |
1588 | } | - |
1589 | if (getppid() != 1)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1590 | return 0; never executed: return 0; | 0 |
1591 | if (getsid(0) != getpid())TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1592 | return 0; never executed: return 0; | 0 |
1593 | debug3("already daemonized"); | - |
1594 | return 1; never executed: return 1; | 0 |
1595 | } | - |
1596 | | - |
1597 | | - |
1598 | | - |
1599 | | - |
1600 | | - |
1601 | | - |
1602 | | - |
1603 | int | - |
1604 | argv_split(const char *s, int *argcp, char ***argvp) | - |
1605 | { | - |
1606 | int r = SSH_ERR_INTERNAL_ERROR; | - |
1607 | int argc = 0, quote, i, j; | - |
1608 | char *arg, **argv = xcalloc(1, sizeof(*argv)); | - |
1609 | | - |
1610 | *argvp = NULL; | - |
1611 | *argcp = 0; | - |
1612 | | - |
1613 | for (i = 0; s[i] != '\0'; i++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1614 | | - |
1615 | if (s[i] == ' ' || s[i] == '\t')TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1616 | continue; never executed: continue; | 0 |
1617 | | - |
1618 | | - |
1619 | quote = 0; | - |
1620 | if (s[i] == '\\' &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1621 | (s[i + 1] == '\'' || s[i + 1] == '\"' || s[i + 1] == '\\'))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1622 | i++; never executed: i++; | 0 |
1623 | else if (s[i] == '\'' || s[i] == '"')TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1624 | quote = s[i++]; never executed: quote = s[i++]; | 0 |
1625 | | - |
1626 | argv = xreallocarray(argv, (argc + 2), sizeof(*argv)); | - |
1627 | arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1); | - |
1628 | argv[argc] = NULL; | - |
1629 | | - |
1630 | | - |
1631 | for (j = 0; s[i] != '\0'; i++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1632 | if (s[i] == '\\') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1633 | if (s[i + 1] == '\'' ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1634 | s[i + 1] == '\"' ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1635 | s[i + 1] == '\\') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1636 | i++; | - |
1637 | arg[j++] = s[i]; | - |
1638 | } else { never executed: end of block | 0 |
1639 | | - |
1640 | arg[j++] = s[i]; | - |
1641 | } never executed: end of block | 0 |
1642 | } else if (quote == 0 && (s[i] == ' ' || s[i] == '\t'))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1643 | break; never executed: break; | 0 |
1644 | else if (quote != 0 && s[i] == quote)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1645 | break; never executed: break; | 0 |
1646 | else | - |
1647 | arg[j++] = s[i]; never executed: arg[j++] = s[i]; | 0 |
1648 | } | - |
1649 | if (s[i] == '\0') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1650 | if (quote != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1651 | | - |
1652 | r = SSH_ERR_INVALID_FORMAT; | - |
1653 | goto out; never executed: goto out; | 0 |
1654 | } | - |
1655 | break; never executed: break; | 0 |
1656 | } | - |
1657 | } never executed: end of block | 0 |
1658 | | - |
1659 | *argcp = argc; | - |
1660 | *argvp = argv; | - |
1661 | argc = 0; | - |
1662 | argv = NULL; | - |
1663 | r = 0; | - |
1664 | out: code before this statement never executed: out: | 0 |
1665 | if (argc != 0 && argv != NULL) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1666 | for (i = 0; i < argc; i++)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1667 | free(argv[i]); never executed: free(argv[i]); | 0 |
1668 | free(argv); | - |
1669 | } never executed: end of block | 0 |
1670 | return r; never executed: return r; | 0 |
1671 | } | - |
1672 | | - |
1673 | | - |
1674 | | - |
1675 | | - |
1676 | | - |
1677 | char * | - |
1678 | argv_assemble(int argc, char **argv) | - |
1679 | { | - |
1680 | int i, j, ws, r; | - |
1681 | char c, *ret; | - |
1682 | struct sshbuf *buf, *arg; | - |
1683 | | - |
1684 | if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1685 | fatal("%s: sshbuf_new failed", __func__); never executed: fatal("%s: sshbuf_new failed", __func__); | 0 |
1686 | | - |
1687 | for (i = 0; i < argc; i++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1688 | ws = 0; | - |
1689 | sshbuf_reset(arg); | - |
1690 | for (j = 0; argv[i][j] != '\0'; j++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1691 | r = 0; | - |
1692 | c = argv[i][j]; | - |
1693 | switch (c) { | - |
1694 | case ' ': never executed: case ' ': | 0 |
1695 | case '\t': never executed: case '\t': | 0 |
1696 | ws = 1; | - |
1697 | r = sshbuf_put_u8(arg, c); | - |
1698 | break; never executed: break; | 0 |
1699 | case '\\': never executed: case '\\': | 0 |
1700 | case '\'': never executed: case '\'': | 0 |
1701 | case '"': never executed: case '"': | 0 |
1702 | if ((r = sshbuf_put_u8(arg, '\\')) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1703 | break; never executed: break; | 0 |
1704 | | - |
1705 | default: code before this statement never executed: default: never executed: default: | 0 |
1706 | r = sshbuf_put_u8(arg, c); | - |
1707 | break; never executed: break; | 0 |
1708 | } | - |
1709 | if (r != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1710 | fatal("%s: sshbuf_put_u8: %s", never executed: fatal("%s: sshbuf_put_u8: %s", __func__, ssh_err(r)); | 0 |
1711 | __func__, ssh_err(r)); never executed: fatal("%s: sshbuf_put_u8: %s", __func__, ssh_err(r)); | 0 |
1712 | } never executed: end of block | 0 |
1713 | if ((i != 0 && (r = sshbuf_put_u8(buf, ' ')) != 0) ||TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1714 | (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) ||TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1715 | (r = sshbuf_putb(buf, arg)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1716 | (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1717 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 0 |
1718 | } never executed: end of block | 0 |
1719 | if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1720 | fatal("%s: malloc failed", __func__); never executed: fatal("%s: malloc failed", __func__); | 0 |
1721 | memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf)); | - |
1722 | ret[sshbuf_len(buf)] = '\0'; | - |
1723 | sshbuf_free(buf); | - |
1724 | sshbuf_free(arg); | - |
1725 | return ret; never executed: return ret; | 0 |
1726 | } | - |
1727 | | - |
1728 | | - |
1729 | int | - |
1730 | exited_cleanly(pid_t pid, const char *tag, const char *cmd, int quiet) | - |
1731 | { | - |
1732 | int status; | - |
1733 | | - |
1734 | while (waitpid(pid, &status, 0) == -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1735 | if (errno != EINTR) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1736 | error("%s: waitpid: %s", tag, strerror(errno)); | - |
1737 | return -1; never executed: return -1; | 0 |
1738 | } | - |
1739 | } never executed: end of block | 0 |
1740 | if (WIFSIGNALED(status)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1741 | error("%s %s exited on signal %d", tag, cmd, WTERMSIG(status)); | - |
1742 | return -1; never executed: return -1; | 0 |
1743 | } else if (WEXITSTATUS(status) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1744 | do_log2(quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO, | - |
1745 | "%s %s failed, status %d", tag, cmd, WEXITSTATUS(status)); | - |
1746 | return -1; never executed: return -1; | 0 |
1747 | } | - |
1748 | return 0; never executed: return 0; | 0 |
1749 | } | - |
1750 | | - |
1751 | | - |
1752 | | - |
1753 | | - |
1754 | | - |
1755 | | - |
1756 | | - |
1757 | | - |
1758 | | - |
1759 | | - |
1760 | | - |
1761 | | - |
1762 | | - |
1763 | | - |
1764 | int | - |
1765 | safe_path(const char *name, struct stat *stp, const char *pw_dir, | - |
1766 | uid_t uid, char *err, size_t errlen) | - |
1767 | { | - |
1768 | char buf[PATH_MAX], homedir[PATH_MAX]; | - |
1769 | char *cp; | - |
1770 | int comparehome = 0; | - |
1771 | struct stat st; | - |
1772 | | - |
1773 | if (realpath(name, buf) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1774 | snprintf(err, errlen, "realpath %s failed: %s", name, | - |
1775 | strerror(errno)); | - |
1776 | return -1; never executed: return -1; | 0 |
1777 | } | - |
1778 | if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1779 | comparehome = 1; never executed: comparehome = 1; | 0 |
1780 | | - |
1781 | if (!S_ISREG(stp->st_mode)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1782 | snprintf(err, errlen, "%s is not a regular file", buf); | - |
1783 | return -1; never executed: return -1; | 0 |
1784 | } | - |
1785 | if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) ||TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1786 | (stp->st_mode & 022) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1787 | snprintf(err, errlen, "bad ownership or modes for file %s", | - |
1788 | buf); | - |
1789 | return -1; never executed: return -1; | 0 |
1790 | } | - |
1791 | | - |
1792 | | - |
1793 | for (;;) { | - |
1794 | if ((cp = dirname(buf)) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1795 | snprintf(err, errlen, "dirname() failed"); | - |
1796 | return -1; never executed: return -1; | 0 |
1797 | } | - |
1798 | strlcpy(buf, cp, sizeof(buf)); | - |
1799 | | - |
1800 | if (stat(buf, &st) < 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1801 | (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1802 | (st.st_mode & 022) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1803 | snprintf(err, errlen, | - |
1804 | "bad ownership or modes for directory %s", buf); | - |
1805 | return -1; never executed: return -1; | 0 |
1806 | } | - |
1807 | | - |
1808 | | - |
1809 | if (comparehome && strcmp(homedir, buf) == 0) never executed: __result = (((const unsigned char *) (const char *) ( homedir ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( buf ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1810 | break; never executed: break; | 0 |
1811 | | - |
1812 | | - |
1813 | | - |
1814 | | - |
1815 | | - |
1816 | if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) never executed: __result = (((const unsigned char *) (const char *) ( "/" ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( buf ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( "." ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( buf ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1817 | break; never executed: break; | 0 |
1818 | } never executed: end of block | 0 |
1819 | return 0; never executed: return 0; | 0 |
1820 | } | - |
1821 | | - |
1822 | | - |
1823 | | - |
1824 | | - |
1825 | | - |
1826 | | - |
1827 | | - |
1828 | int | - |
1829 | safe_path_fd(int fd, const char *file, struct passwd *pw, | - |
1830 | char *err, size_t errlen) | - |
1831 | { | - |
1832 | struct stat st; | - |
1833 | | - |
1834 | | - |
1835 | if (fstat(fd, &st) < 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1836 | snprintf(err, errlen, "cannot stat file %s: %s", | - |
1837 | file, strerror(errno)); | - |
1838 | return -1; never executed: return -1; | 0 |
1839 | } | - |
1840 | return safe_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); never executed: return safe_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); | 0 |
1841 | } | - |
1842 | | - |
1843 | | - |
1844 | | - |
1845 | | - |
1846 | | - |
1847 | void | - |
1848 | child_set_env(char ***envp, u_int *envsizep, const char *name, | - |
1849 | const char *value) | - |
1850 | { | - |
1851 | char **env; | - |
1852 | u_int envsize; | - |
1853 | u_int i, namelen; | - |
1854 | | - |
1855 | if (strchr(name, '=') != NULL) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1856 | error("Invalid environment variable \"%.100s\"", name); | - |
1857 | return; never executed: return; | 0 |
1858 | } | - |
1859 | | - |
1860 | | - |
1861 | | - |
1862 | | - |
1863 | | - |
1864 | if (*envp == NULL && *envsizep == 0) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1865 | *envp = xmalloc(sizeof(char *)); | - |
1866 | *envp[0] = NULL; | - |
1867 | *envsizep = 1; | - |
1868 | } never executed: end of block | 0 |
1869 | | - |
|