OpenCoverage

misc.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssh/src/misc.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: misc.c,v 1.131 2018/07/27 05:13:02 dtucker Exp $ */-
2/*-
3 * Copyright (c) 2000 Markus Friedl. All rights reserved.-
4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved.-
5 *-
6 * Redistribution and use in source and binary forms, with or without-
7 * modification, are permitted provided that the following conditions-
8 * are met:-
9 * 1. Redistributions of source code must retain the above copyright-
10 * notice, this list of conditions and the following disclaimer.-
11 * 2. Redistributions in binary form must reproduce the above copyright-
12 * notice, this list of conditions and the following disclaimer in the-
13 * documentation and/or other materials provided with the distribution.-
14 *-
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR-
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES-
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.-
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,-
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT-
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,-
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY-
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT-
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF-
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.-
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/* remove newline at end of string */-
75char *-
76chop(char *s)-
77{-
78 char *t = s;-
79 while (*t) {
*tDescription
TRUEevaluated 2560 times by 1 test
Evaluated by:
  • test_kex
FALSEnever evaluated
0-2560
80 if (*t == '\n' || *t == '\r') {
*t == '\n'Description
TRUEevaluated 64 times by 1 test
Evaluated by:
  • test_kex
FALSEevaluated 2496 times by 1 test
Evaluated by:
  • test_kex
*t == '\r'Description
TRUEevaluated 64 times by 1 test
Evaluated by:
  • test_kex
FALSEevaluated 2432 times by 1 test
Evaluated by:
  • test_kex
64-2496
81 *t = '\0';-
82 return s;
executed 128 times by 1 test: return s;
Executed by:
  • test_kex
128
83 }-
84 t++;-
85 }
executed 2432 times by 1 test: end of block
Executed by:
  • test_kex
2432
86 return s;
never executed: return s;
0
87-
88}-
89-
90/* set/unset filedescriptor to non-blocking */-
91int-
92set_nonblock(int fd)-
93{-
94 int val;-
95-
96 val = fcntl(fd, F_GETFL);-
97 if (val < 0) {
val < 0Description
TRUEnever evaluated
FALSEnever 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) {
val & 04000Description
TRUEnever evaluated
FALSEnever 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) {
fcntl(fd, 4 , val) == -1Description
TRUEnever evaluated
FALSEnever 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-
115int-
116unset_nonblock(int fd)-
117{-
118 int val;-
119-
120 val = fcntl(fd, F_GETFL);-
121 if (val < 0) {
val < 0Description
TRUEnever evaluated
FALSEnever 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)) {
!(val & 04000 )Description
TRUEnever evaluated
FALSEnever 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) {
fcntl(fd, 4 , val) == -1Description
TRUEnever evaluated
FALSEnever 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-
139const char *-
140ssh_gai_strerror(int gaierr)-
141{-
142 if (gaierr == EAI_SYSTEM && errno != 0)
gaierr == -11Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) != 0Description
TRUEnever evaluated
FALSEnever 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/* disable nagle on socket */-
148void-
149set_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) {
getsockopt(fd,...&optlen) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
156 debug("getsockopt TCP_NODELAY: %.100s", strerror(errno));-
157 return;
never executed: return;
0
158 }-
159 if (opt == 1) {
opt == 1Description
TRUEnever evaluated
FALSEnever 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)
setsockopt(fd,...eof opt) == -1Description
TRUEnever evaluated
FALSEnever 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/* Allow local port reuse in TIME_WAIT */-
170int-
171set_reuseaddr(int fd)-
172{-
173 int on = 1;-
174-
175 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
setsockopt(fd,...eof(on)) == -1Description
TRUEnever evaluated
FALSEnever 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/* Get/set routing domain */-
183char *-
184get_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-
205int-
206set_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; /* default table */-
216-
217 rtable = (int)strtonum(name, 0, 255, &errstr);-
218 if (errstr != NULL) {-
219 /* Shouldn't happen */-
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/* Characters considered whitespace in strsep calls. */-
237#define WHITESPACE " \t\r\n"-
238#define QUOTE "\""-
239-
240/* return next token in configuration line */-
241static char *-
242strdelim_internal(char **s, int split_equals)-
243{-
244 char *old;-
245 int wspace = 0;-
246-
247 if (*s == NULL)
*s == ((void *)0)Description
TRUEevaluated 33 times by 1 test
Evaluated by:
  • sshd
FALSEevaluated 52 times by 1 test
Evaluated by:
  • sshd
33-52
248 return NULL;
executed 33 times by 1 test: return ((void *)0) ;
Executed by:
  • sshd
33
249-
250 old = *s;-
251-
252 *s = strpbrk(*s,-
253 split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE);-
254 if (*s == NULL)
*s == ((void *)0)Description
TRUEevaluated 25 times by 1 test
Evaluated by:
  • sshd
FALSEevaluated 27 times by 1 test
Evaluated by:
  • sshd
25-27
255 return (old);
executed 25 times by 1 test: return (old);
Executed by:
  • sshd
25
256-
257 if (*s[0] == '\"') {
*s[0] == '\"'Description
TRUEnever evaluated
FALSEevaluated 27 times by 1 test
Evaluated by:
  • sshd
0-27
258 memmove(*s, *s + 1, strlen(*s)); /* move nul too */-
259 /* Find matching quote */-
260 if ((*s = strpbrk(*s, QUOTE)) == NULL) {
(*s = __builti...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
261 return (NULL); /* no matching quote */
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 /* Allow only one '=' to be skipped */-
270 if (split_equals && *s[0] == '=')
split_equalsDescription
TRUEevaluated 27 times by 1 test
Evaluated by:
  • sshd
FALSEnever evaluated
*s[0] == '='Description
TRUEnever evaluated
FALSEevaluated 27 times by 1 test
Evaluated by:
  • sshd
0-27
271 wspace = 1;
never executed: wspace = 1;
0
272 *s[0] = '\0';-
273-
274 /* Skip any extra whitespace after first token */-
275 *s += strspn(*s + 1, WHITESPACE) + 1;-
276 if (split_equals && *s[0] == '=' && !wspace)
split_equalsDescription
TRUEevaluated 27 times by 1 test
Evaluated by:
  • sshd
FALSEnever evaluated
*s[0] == '='Description
TRUEnever evaluated
FALSEevaluated 27 times by 1 test
Evaluated by:
  • sshd
!wspaceDescription
TRUEnever evaluated
FALSEnever 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);
Executed by:
  • sshd
27
280}-
281-
282/*-
283 * Return next token in configuration line; splts on whitespace or a-
284 * single '=' character.-
285 */-
286char *-
287strdelim(char **s)-
288{-
289 return strdelim_internal(s, 1);
executed 85 times by 1 test: return strdelim_internal(s, 1);
Executed by:
  • sshd
85
290}-
291-
292/*-
293 * Return next token in configuration line; splts on whitespace only.-
294 */-
295char *-
296strdelimw(char **s)-
297{-
298 return strdelim_internal(s, 0);
never executed: return strdelim_internal(s, 0);
0
299}-
300-
301struct passwd *-
302pwcopy(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;
Executed by:
  • sshd
2
325}-
326-
327/*-
328 * Convert ASCII string to TCP/IP port number.-
329 * Port must be >=0 and <=65535.-
330 * Return -1 if invalid.-
331 */-
332int-
333a2port(const char *s)-
334{-
335 long long port;-
336 const char *errstr;-
337-
338 port = strtonum(s, 0, 65535, &errstr);-
339 if (errstr != NULL)
errstr != ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • sshd
0-2
340 return -1;
never executed: return -1;
0
341 return (int)port;
executed 2 times by 1 test: return (int)port;
Executed by:
  • sshd
2
342}-
343-
344int-
345a2tun(const char *s, int *remote)-
346{-
347 const char *errstr = NULL;-
348 char *sp, *ep;-
349 int tun;-
350-
351 if (remote != NULL) {
remote != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
352 *remote = SSH_TUNID_ANY;-
353 sp = xstrdup(s);-
354 if ((ep = strchr(sp, ':')) == NULL) {
(ep = (__exten...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( ':' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_constant_p ( sp )Description
TRUEnever evaluated
FALSEnever evaluated
( ':' ) == '\0'Description
TRUEnever evaluated
FALSEnever 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);
*remote == (0x7fffffff - 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
363 }-
364-
365 if (strcasecmp(s, "any") == 0)
strcasecmp(s, "any") == 0Description
TRUEnever evaluated
FALSEnever 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)
errstr != ((void *)0)Description
TRUEnever evaluated
FALSEnever 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 * Convert a time string into seconds; format is-
383 * a sequence of:-
384 * time[qualifier]-
385 *-
386 * Valid time qualifiers are:-
387 * <none> seconds-
388 * s|S seconds-
389 * m|M minutes-
390 * h|H hours-
391 * d|D days-
392 * w|W weeks-
393 *-
394 * Examples:-
395 * 90m 90 minutes-
396 * 1h30m 90 minutes-
397 * 2d 2 days-
398 * 1w 1 week-
399 *-
400 * Return -1 if time string is invalid.-
401 */-
402long-
403convtime(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')
p == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 12 times by 1 test
Evaluated by:
  • test_conversion
*p == '\0'Description
TRUEnever evaluated
FALSEevaluated 12 times by 1 test
Evaluated by:
  • test_conversion
0-12
414 return -1;
never executed: return -1;
0
415-
416 while (*p) {
*pDescription
TRUEevaluated 13 times by 1 test
Evaluated by:
  • test_conversion
FALSEevaluated 7 times by 1 test
Evaluated by:
  • test_conversion
7-13
417 secs = strtol(p, &endp, 10);-
418 if (p == endp ||
p == endpDescription
TRUEnever evaluated
FALSEevaluated 13 times by 1 test
Evaluated by:
  • test_conversion
0-13
419 (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||
(*__errno_location ()) == 34Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • test_conversion
FALSEevaluated 11 times by 1 test
Evaluated by:
  • test_conversion
secs == (-0x7f...fffffffL - 1L)Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • test_conversion
secs == 0x7fffffffffffffffLDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • test_conversion
FALSEnever evaluated
0-11
420 secs < 0)
secs < 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • test_conversion
FALSEevaluated 9 times by 1 test
Evaluated by:
  • test_conversion
2-9
421 return -1;
executed 4 times by 1 test: return -1;
Executed by:
  • test_conversion
4
422-
423 switch (*endp++) {-
424 case '\0':
executed 2 times by 1 test: case '\0':
Executed by:
  • test_conversion
2
425 endp--;-
426 break;
executed 2 times by 1 test: break;
Executed by:
  • test_conversion
2
427 case 's':
never executed: case 's':
0
428 case 'S':
executed 1 time by 1 test: case 'S':
Executed by:
  • test_conversion
1
429 break;
executed 1 time by 1 test: break;
Executed by:
  • test_conversion
1
430 case 'm':
executed 2 times by 1 test: case 'm':
Executed by:
  • test_conversion
2
431 case 'M':
executed 1 time by 1 test: case 'M':
Executed by:
  • test_conversion
1
432 multiplier = MINUTES;-
433 break;
executed 3 times by 1 test: break;
Executed by:
  • test_conversion
3
434 case 'h':
executed 1 time by 1 test: case 'h':
Executed by:
  • test_conversion
1
435 case 'H':
never executed: case 'H':
0
436 multiplier = HOURS;-
437 break;
executed 1 time by 1 test: break;
Executed by:
  • test_conversion
1
438 case 'd':
executed 1 time by 1 test: case 'd':
Executed by:
  • test_conversion
1
439 case 'D':
never executed: case 'D':
0
440 multiplier = DAYS;-
441 break;
executed 1 time by 1 test: break;
Executed by:
  • test_conversion
1
442 case 'w':
executed 1 time by 1 test: case 'w':
Executed by:
  • test_conversion
1
443 case 'W':
never executed: case 'W':
0
444 multiplier = WEEKS;-
445 break;
executed 1 time by 1 test: break;
Executed by:
  • test_conversion
1
446 default:
never executed: default:
0
447 return -1;
never executed: return -1;
0
448 }-
449 if (secs >= LONG_MAX / multiplier)
secs >= 0x7fff...L / multiplierDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • test_conversion
FALSEevaluated 8 times by 1 test
Evaluated by:
  • test_conversion
1-8
450 return -1;
executed 1 time by 1 test: return -1;
Executed by:
  • test_conversion
1
451 secs *= multiplier;-
452 if (total >= LONG_MAX - secs)
total >= 0x7ff...ffffffL - secsDescription
TRUEnever evaluated
FALSEevaluated 8 times by 1 test
Evaluated by:
  • test_conversion
0-8
453 return -1;
never executed: return -1;
0
454 total += secs;-
455 if (total < 0)
total < 0Description
TRUEnever evaluated
FALSEevaluated 8 times by 1 test
Evaluated by:
  • test_conversion
0-8
456 return -1;
never executed: return -1;
0
457 p = endp;-
458 }
executed 8 times by 1 test: end of block
Executed by:
  • test_conversion
8
459-
460 return total;
executed 7 times by 1 test: return total;
Executed by:
  • test_conversion
7
461}-
462-
463/*-
464 * Returns a standardized host+port identifier string.-
465 * Caller must free returned string.-
466 */-
467char *-
468put_host_port(const char *host, u_short port)-
469{-
470 char *hoststr;-
471-
472 if (port == 0 || port == SSH_DEFAULT_PORT)
port == 0Description
TRUEnever evaluated
FALSEnever evaluated
port == 22Description
TRUEnever evaluated
FALSEnever evaluated
0
473 return(xstrdup(host));
never executed: return(xstrdup(host));
0
474 if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0)
asprintf(&host...(int)port) < 0Description
TRUEnever evaluated
FALSEnever 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 * Search for next delimiter between hostnames/addresses and ports.-
482 * Argument may be modified (for termination).-
483 * Returns *cp if parsing succeeds.-
484 * *cp is set to the start of the next field, if one was found.-
485 * The delimiter char, if present, is stored in delim.-
486 * If this is the last field, *cp is set to NULL.-
487 */-
488static char *-
489hpdelim2(char **cp, char *delim)-
490{-
491 char *s, *old;-
492-
493 if (cp == NULL || *cp == NULL)
cp == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • sshd
*cp == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • sshd
0-2
494 return NULL;
never executed: return ((void *)0) ;
0
495-
496 old = s = *cp;-
497 if (*s == '[') {
*s == '['Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • sshd
0-2
498 if ((s = strchr(s, ']')) == NULL)
(s = (__extens...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( ']' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_constant_p ( s )Description
TRUEnever evaluated
FALSEnever evaluated
( ']' ) == '\0'Description
TRUEnever evaluated
FALSEnever 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)
(s = __builtin...== ((void *)0)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • sshd
FALSEnever evaluated
0-2
503 s = *cp + strlen(*cp); /* skip to end (see first case below) */
executed 2 times by 1 test: s = *cp + strlen(*cp);
Executed by:
  • sshd
2
504-
505 switch (*s) {-
506 case '\0':
executed 2 times by 1 test: case '\0':
Executed by:
  • sshd
2
507 *cp = NULL; /* no more fields*/-
508 break;
executed 2 times by 1 test: break;
Executed by:
  • sshd
2
509-
510 case ':':
never executed: case ':':
0
511 case '/':
never executed: case '/':
0
512 if (delim != NULL)
delim != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
513 *delim = *s;
never executed: *delim = *s;
0
514 *s = '\0'; /* terminate */-
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;
Executed by:
  • sshd
2
523}-
524-
525char *-
526hpdelim(char **cp)-
527{-
528 return hpdelim2(cp, NULL);
executed 2 times by 1 test: return hpdelim2(cp, ((void *)0) );
Executed by:
  • sshd
2
529}-
530-
531char *-
532cleanhostname(char *host)-
533{-
534 if (*host == '[' && host[strlen(host) - 1] == ']') {
*host == '['Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • sshd
host[strlen(host) - 1] == ']'Description
TRUEnever evaluated
FALSEnever 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;
Executed by:
  • sshd
2
539}-
540-
541char *-
542colon(char *cp)-
543{-
544 int flag = 0;-
545-
546 if (*cp == ':') /* Leading colon is part of file name. */
*cp == ':'Description
TRUEnever evaluated
FALSEnever evaluated
0
547 return NULL;
never executed: return ((void *)0) ;
0
548 if (*cp == '[')
*cp == '['Description
TRUEnever evaluated
FALSEnever evaluated
0
549 flag = 1;
never executed: flag = 1;
0
550-
551 for (; *cp; ++cp) {
*cpDescription
TRUEnever evaluated
FALSEnever evaluated
0
552 if (*cp == '@' && *(cp+1) == '[')
*cp == '@'Description
TRUEnever evaluated
FALSEnever evaluated
*(cp+1) == '['Description
TRUEnever evaluated
FALSEnever evaluated
0
553 flag = 1;
never executed: flag = 1;
0
554 if (*cp == ']' && *(cp+1) == ':' && flag)
*cp == ']'Description
TRUEnever evaluated
FALSEnever evaluated
*(cp+1) == ':'Description
TRUEnever evaluated
FALSEnever evaluated
flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
555 return (cp+1);
never executed: return (cp+1);
0
556 if (*cp == ':' && !flag)
*cp == ':'Description
TRUEnever evaluated
FALSEnever evaluated
!flagDescription
TRUEnever evaluated
FALSEnever evaluated
0
557 return (cp);
never executed: return (cp);
0
558 if (*cp == '/')
*cp == '/'Description
TRUEnever evaluated
FALSEnever 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 * Parse a [user@]host:[path] string.-
566 * Caller must free returned user, host and path.-
567 * Any of the pointer return arguments may be NULL (useful for syntax checking).-
568 * If user was not specified then *userp will be set to NULL.-
569 * If host was not specified then *hostp will be set to NULL.-
570 * If path was not specified then *pathp will be set to ".".-
571 * Returns 0 on success, -1 on failure.-
572 */-
573int-
574parse_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)
userp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
581 *userp = NULL;
never executed: *userp = ((void *)0) ;
0
582 if (hostp != NULL)
hostp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
583 *hostp = NULL;
never executed: *hostp = ((void *)0) ;
0
584 if (pathp != NULL)
pathp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
585 *pathp = NULL;
never executed: *pathp = ((void *)0) ;
0
586-
587 sdup = xstrdup(s);-
588-
589 /* Check for remote syntax: [user@]host:[path] */-
590 if ((tmp = colon(sdup)) == NULL)
(tmp = colon(s...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
591 goto out;
never executed: goto out;
0
592-
593 /* Extract optional path */-
594 *tmp++ = '\0';-
595 if (*tmp == '\0')
*tmp == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
596 tmp = ".";
never executed: tmp = ".";
0
597 path = xstrdup(tmp);-
598-
599 /* Extract optional user and mandatory host */-
600 tmp = strrchr(sdup, '@');-
601 if (tmp != NULL) {
tmp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
602 *tmp++ = '\0';-
603 host = xstrdup(cleanhostname(tmp));-
604 if (*sdup != '\0')
*sdup != '\0'Description
TRUEnever evaluated
FALSEnever 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 /* Success */-
612 if (userp != NULL) {
userp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
613 *userp = user;-
614 user = NULL;-
615 }
never executed: end of block
0
616 if (hostp != NULL) {
hostp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
617 *hostp = host;-
618 host = NULL;-
619 }
never executed: end of block
0
620 if (pathp != NULL) {
pathp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
621 *pathp = path;-
622 path = NULL;-
623 }
never executed: end of block
0
624 ret = 0;-
625out:
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 * Parse a [user@]host[:port] string.-
635 * Caller must free returned user and host.-
636 * Any of the pointer return arguments may be NULL (useful for syntax checking).-
637 * If user was not specified then *userp will be set to NULL.-
638 * If port was not specified then *portp will be -1.-
639 * Returns 0 on success, -1 on failure.-
640 */-
641int-
642parse_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)
userp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
649 *userp = NULL;
never executed: *userp = ((void *)0) ;
0
650 if (hostp != NULL)
hostp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
651 *hostp = NULL;
never executed: *hostp = ((void *)0) ;
0
652 if (portp != NULL)
portp != ((void *)0)Description
TRUEnever evaluated
FALSEnever 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);
(sdup = tmp = ...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__retval != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
((const char *... ))[0] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( s )Description
TRUEnever evaluated
FALSEnever evaluated
((size_t)(cons... *)( s ) == 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
656 return -1;
never executed: return -1;
0
657 /* Extract optional username */-
658 if ((cp = strrchr(tmp, '@')) != NULL) {
(cp = strrchr(...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
659 *cp = '\0';-
660 if (*tmp == '\0')
*tmp == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
661 goto out;
never executed: goto out;
0
662 if ((user = strdup(tmp)) == NULL)
never executed: __retval = (char *) memcpy (__retval, tmp , __len);
(user = (__ext...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__retval != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
((const char *... ))[0] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( tmp )Description
TRUEnever evaluated
FALSEnever evaluated
((size_t)(cons...)( tmp ) == 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
663 goto out;
never executed: goto out;
0
664 tmp = cp + 1;-
665 }
never executed: end of block
0
666 /* Extract mandatory hostname */-
667 if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0')
(cp = hpdelim(...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
*cp == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
668 goto out;
never executed: goto out;
0
669 host = xstrdup(cleanhostname(cp));-
670 /* Convert and verify optional port */-
671 if (tmp != NULL && *tmp != '\0') {
tmp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
*tmp != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
672 if ((port = a2port(tmp)) <= 0)
(port = a2port(tmp)) <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
673 goto out;
never executed: goto out;
0
674 }
never executed: end of block
0
675 /* Success */-
676 if (userp != NULL) {
userp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
677 *userp = user;-
678 user = NULL;-
679 }
never executed: end of block
0
680 if (hostp != NULL) {
hostp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
681 *hostp = host;-
682 host = NULL;-
683 }
never executed: end of block
0
684 if (portp != NULL)
portp != ((void *)0)Description
TRUEnever evaluated
FALSEnever 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 * Converts a two-byte hex string to decimal.-
696 * Returns the decimal value or -1 for invalid input.-
697 */-
698static int-
699hexchar(const char *s)-
700{-
701 unsigned char result[2];-
702 int i;-
703-
704 for (i = 0; i < 2; i++) {
i < 2Description
TRUEnever evaluated
FALSEnever evaluated
0
705 if (s[i] >= '0' && s[i] <= '9')
s[i] >= '0'Description
TRUEnever evaluated
FALSEnever evaluated
s[i] <= '9'Description
TRUEnever evaluated
FALSEnever 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')
s[i] >= 'a'Description
TRUEnever evaluated
FALSEnever evaluated
s[i] <= 'f'Description
TRUEnever evaluated
FALSEnever 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')
s[i] >= 'A'Description
TRUEnever evaluated
FALSEnever evaluated
s[i] <= 'F'Description
TRUEnever evaluated
FALSEnever 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 * Decode an url-encoded string.-
719 * Returns a newly allocated string on success or NULL on failure.-
720 */-
721static char *-
722urldecode(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++) {
*src != '\0'Description
TRUEnever evaluated
FALSEnever 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]) ||
! ((*__ctype_b...nt) _ISxdigit)Description
TRUEnever evaluated
FALSEnever evaluated
0
735 !isxdigit((unsigned char)src[2]) ||
! ((*__ctype_b...nt) _ISxdigit)Description
TRUEnever evaluated
FALSEnever evaluated
0
736 (ch = hexchar(src + 1)) == -1) {
(ch = hexchar(src + 1)) == -1Description
TRUEnever evaluated
FALSEnever 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 * Parse an (scp|ssh|sftp)://[user@]host[:port][/path] URI.-
755 * See https://tools.ietf.org/html/draft-ietf-secsh-scp-sftp-ssh-uri-04-
756 * Either user or path may be url-encoded (but not host or port).-
757 * Caller must free returned user, host and path.-
758 * Any of the pointer return arguments may be NULL (useful for syntax checking)-
759 * but the scheme must always be specified.-
760 * If user was not specified then *userp will be set to NULL.-
761 * If port was not specified then *portp will be -1.-
762 * If path was not specified then *pathp will be set to NULL.-
763 * Returns 0 on success, 1 if non-uri/wrong scheme, -1 on error/invalid uri.-
764 */-
765int-
766parse_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
(__extension__..., len ))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( len )Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( uri )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( uri )...ze_t) ( len ))Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_cons...t_p ( scheme )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( schem...ze_t) ( len ))Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
(__extension__..." , 3 ))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( 3 )Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_cons... ( uri + len )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( uri +...size_t) ( 3 ))Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( "://" )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( "://"...size_t) ( 3 ))Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
776 return 1;
never executed: return 1;
0
777 uri += len + 3;-
778-
779 if (userp != NULL)
userp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
780 *userp = NULL;
never executed: *userp = ((void *)0) ;
0
781 if (hostp != NULL)
hostp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
782 *hostp = NULL;
never executed: *hostp = ((void *)0) ;
0
783 if (portp != NULL)
portp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
784 *portp = -1;
never executed: *portp = -1;
0
785 if (pathp != NULL)
pathp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
786 *pathp = NULL;
never executed: *pathp = ((void *)0) ;
0
787-
788 uridup = tmp = xstrdup(uri);-
789-
790 /* Extract optional ssh-info (username + connection params) */-
791 if ((cp = strchr(tmp, '@')) != NULL) {
(cp = (__exten...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( '@' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_constant_p ( tmp )Description
TRUEnever evaluated
FALSEnever evaluated
( '@' ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
792 char *delim;-
793-
794 *cp = '\0';-
795 /* Extract username and connection params */-
796 if ((delim = strchr(tmp, ';')) != NULL) {
(delim = (__ex...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( ';' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_constant_p ( tmp )Description
TRUEnever evaluated
FALSEnever evaluated
( ';' ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
797 /* Just ignore connection params for now */-
798 *delim = '\0';-
799 }
never executed: end of block
0
800 if (*tmp == '\0') {
*tmp == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
801 /* Empty username */-
802 goto out;
never executed: goto out;
0
803 }-
804 if ((user = urldecode(tmp)) == NULL)
(user = urldec...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
805 goto out;
never executed: goto out;
0
806 tmp = cp + 1;-
807 }
never executed: end of block
0
808-
809 /* Extract mandatory hostname */-
810 if ((cp = hpdelim2(&tmp, &ch)) == NULL || *cp == '\0')
(cp = hpdelim2...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
*cp == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
811 goto out;
never executed: goto out;
0
812 host = xstrdup(cleanhostname(cp));-
813 if (!valid_domain(host, 0, NULL))
!valid_domain(... ((void *)0) )Description
TRUEnever evaluated
FALSEnever evaluated
0
814 goto out;
never executed: goto out;
0
815-
816 if (tmp != NULL && *tmp != '\0') {
tmp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
*tmp != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
817 if (ch == ':') {
ch == ':'Description
TRUEnever evaluated
FALSEnever evaluated
0
818 /* Convert and verify port. */-
819 if ((cp = strchr(tmp, '/')) != NULL)
(cp = (__exten...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( '/' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_constant_p ( tmp )Description
TRUEnever evaluated
FALSEnever evaluated
( '/' ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
820 *cp = '\0';
never executed: *cp = '\0';
0
821 if ((port = a2port(tmp)) <= 0)
(port = a2port(tmp)) <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
822 goto out;
never executed: goto out;
0
823 tmp = cp ? cp + 1 : NULL;
cpDescription
TRUEnever evaluated
FALSEnever evaluated
0
824 }
never executed: end of block
0
825 if (tmp != NULL && *tmp != '\0') {
tmp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
*tmp != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
826 /* Extract optional path */-
827 if ((path = urldecode(tmp)) == NULL)
(path = urldec...== ((void *)0)Description
TRUEnever evaluated
FALSEnever 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 /* Success */-
833 if (userp != NULL) {
userp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
834 *userp = user;-
835 user = NULL;-
836 }
never executed: end of block
0
837 if (hostp != NULL) {
hostp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
838 *hostp = host;-
839 host = NULL;-
840 }
never executed: end of block
0
841 if (portp != NULL)
portp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
842 *portp = port;
never executed: *portp = port;
0
843 if (pathp != NULL) {
pathp != ((void *)0)Description
TRUEnever evaluated
FALSEnever 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/* function to assist building execv() arguments */-
857void-
858addargs(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)
r == -1Description
TRUEnever evaluated
FALSEnever 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) {
args->list == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
873 nalloc = 32;-
874 args->num = 0;-
875 } else if (args->num+2 >= nalloc)
never executed: end of block
args->num+2 >= nallocDescription
TRUEnever evaluated
FALSEnever 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-
884void-
885replacearg(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)
r == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
895 fatal("replacearg: argument too long");
never executed: fatal("replacearg: argument too long");
0
896-
897 if (which >= args->num)
which >= args->numDescription
TRUEnever evaluated
FALSEnever 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-
904void-
905freeargs(arglist *args)-
906{-
907 u_int i;-
908-
909 if (args->list != NULL) {
args->list != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
910 for (i = 0; i < args->num; i++)
i < args->numDescription
TRUEnever evaluated
FALSEnever 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 * Expands tildes in the file name. Returns data allocated by xmalloc.-
920 * Warning: this calls getpw*.-
921 */-
922char *-
923tilde_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 != '~')
*filename != '~'Description
TRUEevaluated 8 times by 1 test
Evaluated by:
  • sshd
FALSEnever evaluated
0-8
931 return (xstrdup(filename));
executed 8 times by 1 test: return (xstrdup(filename));
Executed by:
  • sshd
8
932 filename++;-
933-
934 path = strchr(filename, '/');
__builtin_constant_p ( '/' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_con...p ( filename )Description
TRUEnever evaluated
FALSEnever evaluated
( '/' ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
935 if (path != NULL && path > filename) { /* ~user/path */
path != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
path > filenameDescription
TRUEnever evaluated
FALSEnever evaluated
0
936 slash = path - filename;-
937 if (slash > sizeof(user) - 1)
slash > sizeof(user) - 1Description
TRUEnever evaluated
FALSEnever 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)
(pw = getpwnam...== ((void *)0)Description
TRUEnever evaluated
FALSEnever 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) /* ~/path */
never executed: end of block
(pw = getpwuid...== ((void *)0)Description
TRUEnever evaluated
FALSEnever 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 /* Make sure directory has a trailing '/' */-
947 len = strlen(pw->pw_dir);-
948 if (len == 0 || pw->pw_dir[len - 1] != '/')
len == 0Description
TRUEnever evaluated
FALSEnever evaluated
pw->pw_dir[len - 1] != '/'Description
TRUEnever evaluated
FALSEnever evaluated
0
949 sep = "/";
never executed: sep = "/";
0
950 else-
951 sep = "";
never executed: sep = "";
0
952-
953 /* Skip leading '/' from specified path */-
954 if (path != NULL)
path != ((void *)0)Description
TRUEnever evaluated
FALSEnever 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)
xasprintf(&ret...ename) >= 4096Description
TRUEnever evaluated
FALSEnever 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 * Expand a string with a set of %[char] escapes. A number of escapes may be-
965 * specified as (char *escape_chars, char *replacement) pairs. The list must-
966 * be terminated by a NULL escape_char. Returns replaced string in memory-
967 * allocated by xmalloc.-
968 */-
969char *-
970percent_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 /* Gather keys */-
982 va_start(ap, string);-
983 for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {
num_keys < 16Description
TRUEnever evaluated
FALSEnever evaluated
0
984 keys[num_keys].key = va_arg(ap, char *);-
985 if (keys[num_keys].key == NULL)
keys[num_keys]...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
986 break;
never executed: break;
0
987 keys[num_keys].repl = va_arg(ap, char *);-
988 if (keys[num_keys].repl == NULL)
keys[num_keys]...== ((void *)0)Description
TRUEnever evaluated
FALSEnever 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)
num_keys == 16Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_va_a...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
992 fatal("%s: too many keys", __func__);
never executed: fatal("%s: too many keys", __func__);
0
993 va_end(ap);-
994-
995 /* Expand string */-
996 *buf = '\0';-
997 for (i = 0; *string != '\0'; string++) {
*string != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
998 if (*string != '%') {
*string != '%'Description
TRUEnever evaluated
FALSEnever evaluated
0
999 append:-
1000 buf[i++] = *string;-
1001 if (i >= sizeof(buf))
i >= sizeof(buf)Description
TRUEnever evaluated
FALSEnever 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 /* %% case */-
1008 if (*string == '%')
*string == '%'Description
TRUEnever evaluated
FALSEnever evaluated
0
1009 goto append;
never executed: goto append;
0
1010 if (*string == '\0')
*string == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1011 fatal("%s: invalid format", __func__);
never executed: fatal("%s: invalid format", __func__);
0
1012 for (j = 0; j < num_keys; j++) {
j < num_keysDescription
TRUEnever evaluated
FALSEnever evaluated
0
1013 if (strchr(keys[j].key, *string) != NULL) {
(__extension__...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_cons..._p ( *string )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_con... keys[j].key )Description
TRUEnever evaluated
FALSEnever evaluated
( *string ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1014 i = strlcat(buf, keys[j].repl, sizeof(buf));-
1015 if (i >= sizeof(buf))
i >= sizeof(buf)Description
TRUEnever evaluated
FALSEnever 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)
j >= num_keysDescription
TRUEnever evaluated
FALSEnever 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-
1027int-
1028tun_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 /* Open the tunnel device */-
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 /* Bring interface up if it is not already */-
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-
1105void-
1106sanitise_stdfd(void)-
1107{-
1108 int nullfd, dupfd;-
1109-
1110 if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
(nullfd = dupf... , 02 )) == -1Description
TRUEnever evaluated
FALSEevaluated 30 times by 2 tests
Evaluated by:
  • ssh-keygen
  • sshd
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) {
++dupfd <= 2Description
TRUEnever evaluated
FALSEevaluated 30 times by 2 tests
Evaluated by:
  • ssh-keygen
  • sshd
0-30
1116 /* Only populate closed fds. */-
1117 if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) {
fcntl(dupfd, 3 ) == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 9Description
TRUEnever evaluated
FALSEnever evaluated
0
1118 if (dup2(nullfd, dupfd) == -1) {
dup2(nullfd, dupfd) == -1Description
TRUEnever evaluated
FALSEnever 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)
nullfd > 2Description
TRUEevaluated 30 times by 2 tests
Evaluated by:
  • ssh-keygen
  • sshd
FALSEnever evaluated
0-30
1125 close(nullfd);
executed 30 times by 2 tests: close(nullfd);
Executed by:
  • ssh-keygen
  • sshd
30
1126}
executed 30 times by 2 tests: end of block
Executed by:
  • ssh-keygen
  • sshd
30
1127-
1128char *-
1129tohex(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)
l > 65536Description
TRUEnever evaluated
FALSEnever 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++) {
i < lDescription
TRUEnever evaluated
FALSEnever 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-
1147u_int64_t-
1148get_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-
1165u_int32_t-
1166get_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-
1179u_int32_t-
1180get_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-
1193u_int16_t-
1194get_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-
1205void-
1206put_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-
1220void-
1221put_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-
1231void-
1232put_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-
1242void-
1243put_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-
1251void-
1252ms_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
( &diff )->tv_usec < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1258 *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);-
1259}
never executed: end of block
0
1260-
1261void-
1262ms_to_timeval(struct timeval *tv, int ms)-
1263{-
1264 if (ms < 0)
ms < 0Description
TRUEnever evaluated
FALSEnever 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-
1270void-
1271monotime_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) {
!gettime_failedDescription
TRUEevaluated 352 times by 1 test
Evaluated by:
  • test_kex
FALSEnever evaluated
0-352
1279# ifdef CLOCK_BOOTTIME-
1280 if (clock_gettime(CLOCK_BOOTTIME, ts) == 0)
clock_gettime( 7 , ts) == 0Description
TRUEevaluated 352 times by 1 test
Evaluated by:
  • test_kex
FALSEnever evaluated
0-352
1281 return;
executed 352 times by 1 test: return;
Executed by:
  • test_kex
352
1282# endif /* CLOCK_BOOTTIME */-
1283# ifdef CLOCK_MONOTONIC-
1284 if (clock_gettime(CLOCK_MONOTONIC, ts) == 0)
clock_gettime( 1 , ts) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1285 return;
never executed: return;
0
1286# endif /* CLOCK_MONOTONIC */-
1287# ifdef CLOCK_REALTIME-
1288 /* Not monotonic, but we're almost out of options here. */-
1289 if (clock_gettime(CLOCK_REALTIME, ts) == 0)
clock_gettime( 0 , ts) == 0Description
TRUEnever evaluated
FALSEnever 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-
1301void-
1302monotime_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-
1311time_t-
1312monotime(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;
Executed by:
  • test_kex
352
1318}-
1319-
1320double-
1321monotime_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-
1329void-
1330bandwidth_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/* Callback from read/write loop to insert bandwidth-limiting delays */-
1341void-
1342bandwidth_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)) {
( &bw->bwstart )->tv_secDescription
TRUEnever evaluated
FALSEnever evaluated
( &bw->bwstart )->tv_usecDescription
TRUEnever evaluated
FALSEnever 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)
bw->lamt < bw->threshDescription
TRUEnever evaluated
FALSEnever 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
( &bw->bwend )->tv_usec < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1358 if (!timerisset(&bw->bwend))
( &bw->bwend )->tv_secDescription
TRUEnever evaluated
FALSEnever evaluated
( &bw->bwend )->tv_usecDescription
TRUEnever evaluated
FALSEnever 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, >)) {
((( &bw->bwsta...nd )->tv_sec))Description
TRUEnever evaluated
FALSEnever evaluated
(( &bw->bwstar...end )->tv_sec)Description
TRUEnever evaluated
FALSEnever evaluated
0
1368 timersub(&bw->bwstart, &bw->bwend, &bw->bwend);
never executed: end of block
( &bw->bwend )->tv_usec < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1369-
1370 /* Adjust the wait time */-
1371 if (bw->bwend.tv_sec) {
bw->bwend.tv_secDescription
TRUEnever evaluated
FALSEnever evaluated
0
1372 bw->thresh /= 2;-
1373 if (bw->thresh < bw->buflen / 4)
bw->thresh < bw->buflen / 4Description
TRUEnever evaluated
FALSEnever 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
bw->bwend.tv_usec < 10000Description
TRUEnever evaluated
FALSEnever evaluated
0
1376 bw->thresh *= 2;-
1377 if (bw->thresh > bw->buflen * 8)
bw->thresh > bw->buflen * 8Description
TRUEnever evaluated
FALSEnever 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) {
nanosleep(&ts, &rm) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1383 if (errno != EINTR)
(*__errno_location ()) != 4Description
TRUEnever evaluated
FALSEnever 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/* Make a template filename for mk[sd]temp() */-
1394void-
1395mktemp_proto(char *s, size_t len)-
1396{-
1397 const char *tmpdir;-
1398 int r;-
1399-
1400 if ((tmpdir = getenv("TMPDIR")) != NULL) {
(tmpdir = gete...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1401 r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir);-
1402 if (r > 0 && (size_t)r < len)
r > 0Description
TRUEnever evaluated
FALSEnever evaluated
(size_t)r < lenDescription
TRUEnever evaluated
FALSEnever 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)
r < 0Description
TRUEnever evaluated
FALSEnever evaluated
(size_t)r >= lenDescription
TRUEnever evaluated
FALSEnever 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-
1410static const struct {-
1411 const char *name;-
1412 int value;-
1413} ipqos[] = {-
1414 { "none", INT_MAX }, /* can't use 0 here; that's CS0 */-
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-
1442int-
1443parse_ipqos(const char *cp)-
1444{-
1445 u_int i;-
1446 char *ep;-
1447 long val;-
1448-
1449 if (cp == NULL)
cp == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1450 return -1;
never executed: return -1;
0
1451 for (i = 0; ipqos[i].name != NULL; i++) {
ipqos[i].name != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1452 if (strcasecmp(cp, ipqos[i].name) == 0)
strcasecmp(cp,...[i].name) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1453 return ipqos[i].value;
never executed: return ipqos[i].value;
0
1454 }
never executed: end of block
0
1455 /* Try parsing as an integer */-
1456 val = strtol(cp, &ep, 0);-
1457 if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255)
*cp == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
*ep != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
val < 0Description
TRUEnever evaluated
FALSEnever evaluated
val > 255Description
TRUEnever evaluated
FALSEnever evaluated
0
1458 return -1;
never executed: return -1;
0
1459 return val;
never executed: return val;
0
1460}-
1461-
1462const char *-
1463iptos2str(int iptos)-
1464{-
1465 int i;-
1466 static char iptos_str[sizeof "0xff"];-
1467-
1468 for (i = 0; ipqos[i].name != NULL; i++) {
ipqos[i].name != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1469 if (ipqos[i].value == iptos)
ipqos[i].value == iptosDescription
TRUEnever evaluated
FALSEnever 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-
1476void-
1477lowercase(char *s)-
1478{-
1479 for (; *s; s++)
*sDescription
TRUEevaluated 8400 times by 1 test
Evaluated by:
  • test_hostkeys
FALSEevaluated 520 times by 1 test
Evaluated by:
  • test_hostkeys
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; })) ;
Executed by:
  • test_hostkeys
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 )];
Executed by:
  • test_hostkeys
sizeof ( (u_char)*s ) > 1Description
TRUEnever evaluated
FALSEevaluated 8400 times by 1 test
Evaluated by:
  • test_hostkeys
__builtin_cons...( (u_char)*s )Description
TRUEnever evaluated
FALSEnever evaluated
__c < -128Description
TRUEnever evaluated
FALSEnever evaluated
__c > 255Description
TRUEnever evaluated
FALSEnever evaluated
0-8400
1481}
executed 520 times by 1 test: end of block
Executed by:
  • test_hostkeys
520
1482-
1483int-
1484unix_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,
strlcpy(sunadd...addr.sun_path)Description
TRUEnever evaluated
FALSEnever evaluated
0
1492 sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) {
strlcpy(sunadd...addr.sun_path)Description
TRUEnever evaluated
FALSEnever 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) {
sock < 0Description
TRUEnever evaluated
FALSEnever 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) {
unlink_first == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1507 if (unlink(path) != 0 && errno != ENOENT)
unlink(path) != 0Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) != 2Description
TRUEnever evaluated
FALSEnever 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) {
bind(sock, (st...(sunaddr)) < 0Description
TRUEnever evaluated
FALSEnever 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) {
listen(sock, backlog) < 0Description
TRUEnever evaluated
FALSEnever 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-
1530void-
1531sock_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)
setsockopt(s, ...eof(on)) == -1Description
TRUEnever evaluated
FALSEnever 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 * Compares two strings that maybe be NULL. Returns non-zero if strings-
1544 * are both NULL or are identical, returns zero otherwise.-
1545 */-
1546static int-
1547strcmp_maybe_null(const char *a, const char *b)-
1548{-
1549 if ((a == NULL && b != NULL) || (a != NULL && b == NULL))
a == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
b != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
a != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
b == ((void *)0)Description
TRUEnever evaluated
FALSEnever 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
a != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__extension__ ... )))); }) != 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1552 return 0;
never executed: return 0;
0
1553 return 1;
never executed: return 1;
0
1554}-
1555-
1556/*-
1557 * Compare two forwards, returning non-zero if they are identical or-
1558 * zero otherwise.-
1559 */-
1560int-
1561forward_equals(const struct Forward *a, const struct Forward *b)-
1562{-
1563 if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0)
strcmp_maybe_n...ten_host) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1564 return 0;
never executed: return 0;
0
1565 if (a->listen_port != b->listen_port)
a->listen_port...b->listen_portDescription
TRUEnever evaluated
FALSEnever evaluated
0
1566 return 0;
never executed: return 0;
0
1567 if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0)
strcmp_maybe_n...ten_path) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1568 return 0;
never executed: return 0;
0
1569 if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0)
strcmp_maybe_n...ect_host) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1570 return 0;
never executed: return 0;
0
1571 if (a->connect_port != b->connect_port)
a->connect_por...->connect_portDescription
TRUEnever evaluated
FALSEnever evaluated
0
1572 return 0;
never executed: return 0;
0
1573 if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0)
strcmp_maybe_n...ect_path) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1574 return 0;
never executed: return 0;
0
1575 /* allocated_port and handle are not checked */-
1576 return 1;
never executed: return 1;
0
1577}-
1578-
1579/* returns 1 if process is already daemonized, 0 otherwise */-
1580int-
1581daemonized(void)-
1582{-
1583 int fd;-
1584-
1585 if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) {
(fd = open( "/...| 0400 )) >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1586 close(fd);-
1587 return 0; /* have controlling terminal */
never executed: return 0;
0
1588 }-
1589 if (getppid() != 1)
getppid() != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1590 return 0; /* parent is not init */
never executed: return 0;
0
1591 if (getsid(0) != getpid())
getsid(0) != getpid()Description
TRUEnever evaluated
FALSEnever evaluated
0
1592 return 0; /* not session leader */
never executed: return 0;
0
1593 debug3("already daemonized");-
1594 return 1;
never executed: return 1;
0
1595}-
1596-
1597-
1598/*-
1599 * Splits 's' into an argument vector. Handles quoted string and basic-
1600 * escape characters (\\, \", \'). Caller must free the argument vector-
1601 * and its members.-
1602 */-
1603int-
1604argv_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++) {
s[i] != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1614 /* Skip leading whitespace */-
1615 if (s[i] == ' ' || s[i] == '\t')
s[i] == ' 'Description
TRUEnever evaluated
FALSEnever evaluated
s[i] == '\t'Description
TRUEnever evaluated
FALSEnever evaluated
0
1616 continue;
never executed: continue;
0
1617-
1618 /* Start of a token */-
1619 quote = 0;-
1620 if (s[i] == '\\' &&
s[i] == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
1621 (s[i + 1] == '\'' || s[i + 1] == '\"' || s[i + 1] == '\\'))
s[i + 1] == '\''Description
TRUEnever evaluated
FALSEnever evaluated
s[i + 1] == '\"'Description
TRUEnever evaluated
FALSEnever evaluated
s[i + 1] == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
1622 i++;
never executed: i++;
0
1623 else if (s[i] == '\'' || s[i] == '"')
s[i] == '\''Description
TRUEnever evaluated
FALSEnever evaluated
s[i] == '"'Description
TRUEnever evaluated
FALSEnever 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 /* Copy the token in, removing escapes */-
1631 for (j = 0; s[i] != '\0'; i++) {
s[i] != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1632 if (s[i] == '\\') {
s[i] == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
1633 if (s[i + 1] == '\'' ||
s[i + 1] == '\''Description
TRUEnever evaluated
FALSEnever evaluated
0
1634 s[i + 1] == '\"' ||
s[i + 1] == '\"'Description
TRUEnever evaluated
FALSEnever evaluated
0
1635 s[i + 1] == '\\') {
s[i + 1] == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
1636 i++; /* Skip '\' */-
1637 arg[j++] = s[i];-
1638 } else {
never executed: end of block
0
1639 /* Unrecognised escape */-
1640 arg[j++] = s[i];-
1641 }
never executed: end of block
0
1642 } else if (quote == 0 && (s[i] == ' ' || s[i] == '\t'))
quote == 0Description
TRUEnever evaluated
FALSEnever evaluated
s[i] == ' 'Description
TRUEnever evaluated
FALSEnever evaluated
s[i] == '\t'Description
TRUEnever evaluated
FALSEnever evaluated
0
1643 break; /* done */
never executed: break;
0
1644 else if (quote != 0 && s[i] == quote)
quote != 0Description
TRUEnever evaluated
FALSEnever evaluated
s[i] == quoteDescription
TRUEnever evaluated
FALSEnever evaluated
0
1645 break; /* done */
never executed: break;
0
1646 else-
1647 arg[j++] = s[i];
never executed: arg[j++] = s[i];
0
1648 }-
1649 if (s[i] == '\0') {
s[i] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1650 if (quote != 0) {
quote != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1651 /* Ran out of string looking for close quote */-
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 /* Success */-
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) {
argc != 0Description
TRUEnever evaluated
FALSEnever evaluated
argv != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1666 for (i = 0; i < argc; i++)
i < argcDescription
TRUEnever evaluated
FALSEnever 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 * Reassemble an argument vector into a string, quoting and escaping as-
1675 * necessary. Caller must free returned string.-
1676 */-
1677char *-
1678argv_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)
(buf = sshbuf_...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
(arg = sshbuf_...== ((void *)0)Description
TRUEnever evaluated
FALSEnever 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++) {
i < argcDescription
TRUEnever evaluated
FALSEnever evaluated
0
1688 ws = 0;-
1689 sshbuf_reset(arg);-
1690 for (j = 0; argv[i][j] != '\0'; j++) {
argv[i][j] != '\0'Description
TRUEnever evaluated
FALSEnever 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)
(r = sshbuf_pu...g, '\\')) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1703 break;
never executed: break;
0
1704 /* FALLTHROUGH */-
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)
r != 0Description
TRUEnever evaluated
FALSEnever 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) ||
i != 0Description
TRUEnever evaluated
FALSEnever evaluated
(r = sshbuf_pu...uf, ' ')) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1714 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) ||
ws != 0Description
TRUEnever evaluated
FALSEnever evaluated
(r = sshbuf_pu...uf, '"')) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1715 (r = sshbuf_putb(buf, arg)) != 0 ||
(r = sshbuf_pu...uf, arg)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1716 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0))
ws != 0Description
TRUEnever evaluated
FALSEnever evaluated
(r = sshbuf_pu...uf, '"')) != 0Description
TRUEnever evaluated
FALSEnever 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)
(ret = malloc(...== ((void *)0)Description
TRUEnever evaluated
FALSEnever 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/* Returns 0 if pid exited cleanly, non-zero otherwise */-
1729int-
1730exited_cleanly(pid_t pid, const char *tag, const char *cmd, int quiet)-
1731{-
1732 int status;-
1733-
1734 while (waitpid(pid, &status, 0) == -1) {
waitpid(pid, &status, 0) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1735 if (errno != EINTR) {
(*__errno_location ()) != 4Description
TRUEnever evaluated
FALSEnever 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)) {
(((signed char... 1) >> 1) > 0)Description
TRUEnever evaluated
FALSEnever 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) {
((( status ) &...00) >> 8) != 0Description
TRUEnever evaluated
FALSEnever 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 * Check a given path for security. This is defined as all components-
1753 * of the path to the file must be owned by either the owner of-
1754 * of the file or root and no directories must be group or world writable.-
1755 *-
1756 * XXX Should any specific check be done for sym links ?-
1757 *-
1758 * Takes a file name, its stat information (preferably from fstat() to-
1759 * avoid races), the uid of the expected owner, their home directory and an-
1760 * error buffer plus max size as arguments.-
1761 *-
1762 * Returns 0 on success and -1 on failure-
1763 */-
1764int-
1765safe_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) {
_ssh_compat_re...== ((void *)0)Description
TRUEnever evaluated
FALSEnever 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)
pw_dir != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
_ssh_compat_re...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1779 comparehome = 1;
never executed: comparehome = 1;
0
1780-
1781 if (!S_ISREG(stp->st_mode)) {
! (((( stp->st... == (0100000))Description
TRUEnever evaluated
FALSEnever 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) ||
!platform_sys_...d(stp->st_uid)Description
TRUEnever evaluated
FALSEnever evaluated
stp->st_uid != uidDescription
TRUEnever evaluated
FALSEnever evaluated
0
1786 (stp->st_mode & 022) != 0) {
(stp->st_mode & 022) != 0Description
TRUEnever evaluated
FALSEnever 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 /* for each component of the canonical path, walking upwards */-
1793 for (;;) {-
1794 if ((cp = dirname(buf)) == NULL) {
(cp = dirname(...== ((void *)0)Description
TRUEnever evaluated
FALSEnever 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 ||
stat(buf, &st) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1801 (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||
!platform_sys_...uid(st.st_uid)Description
TRUEnever evaluated
FALSEnever evaluated
st.st_uid != uidDescription
TRUEnever evaluated
FALSEnever evaluated
0
1802 (st.st_mode & 022) != 0) {
(st.st_mode & 022) != 0Description
TRUEnever evaluated
FALSEnever 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 /* If are past the homedir then we can stop */-
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
comparehomeDescription
TRUEnever evaluated
FALSEnever evaluated
__extension__ ... )))); }) == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1810 break;
never executed: break;
0
1811-
1812 /*-
1813 * dirname should always complete with a "/" path,-
1814 * but we can be paranoid and check for "." too-
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
( __extension_...)))); }) == 0)Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
( __extension_...)))); }) == 0)Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
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 * Version of safe_path() that accepts an open file descriptor to-
1824 * avoid races.-
1825 *-
1826 * Returns 0 on success and -1 on failure-
1827 */-
1828int-
1829safe_path_fd(int fd, const char *file, struct passwd *pw,-
1830 char *err, size_t errlen)-
1831{-
1832 struct stat st;-
1833-
1834 /* check the open file to avoid races */-
1835 if (fstat(fd, &st) < 0) {
fstat(fd, &st) < 0Description
TRUEnever evaluated
FALSEnever 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 * Sets the value of the given variable in the environment. If the variable-
1845 * already exists, its value is overridden.-
1846 */-
1847void-
1848child_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) {
(__extension__...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( '=' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_constant_p ( name )Description
TRUEnever evaluated
FALSEnever evaluated
( '=' ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1856 error("Invalid environment variable \"%.100s\"", name);-
1857 return;
never executed: return;
0
1858 }-
1859-
1860 /*-
1861 * If we're passed an uninitialized list, allocate a single null-
1862 * entry before continuing.-
1863 */-
1864 if (*envp == NULL && *envsizep == 0) {
*envp == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
*envsizep == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1865 *envp = xmalloc(sizeof(char *));-
1866 *envp[0] = NULL;-
1867 *envsizep = 1;-
1868 }
never executed: end of block
0
1869-
1870 /*-
1871 * Find the slot where the value should be stored. If the variable-
1872 * already exists, we reuse the slot; otherwise we append a new slot-
1873 * at the end of the array, expanding if necessary.-
1874 */-
1875 env = *envp;-
1876 namelen = strlen(name);-
1877 for (i = 0; env[i]; i++)
env[i]Description
TRUEnever evaluated
FALSEnever evaluated
0
1878 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
never executed: __result = (((const unsigned char *) (const char *) ( env[i] ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( name ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
(__extension__...melen ))) == 0Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_cons..._p ( namelen )Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_cons...t_p ( env[i] )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( env[i...) ( namelen ))Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( name )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( name ...) ( namelen ))Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
env[i][namelen] == '='Description
TRUEnever evaluated
FALSEnever evaluated
0
1879 break;
never executed: break;
0
1880 if (env[i]) {
env[i]Description
TRUEnever evaluated
FALSEnever evaluated
0
1881 /* Reuse the slot. */-
1882 free(env[i]);-
1883 } else {
never executed: end of block
0
1884 /* New variable. Expand if necessary. */-
1885 envsize = *envsizep;-
1886 if (i >= envsize - 1) {
i >= envsize - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1887 if (envsize >= 1000)
envsize >= 1000Description
TRUEnever evaluated
FALSEnever evaluated
0
1888 fatal("child_set_env: too many env vars");
never executed: fatal("child_set_env: too many env vars");
0
1889 envsize += 50;-
1890 env = (*envp) = xreallocarray(env, envsize, sizeof(char *));-
1891 *envsizep = envsize;-
1892 }
never executed: end of block
0
1893 /* Need to set the NULL pointer at end of array beyond the new slot. */-
1894 env[i + 1] = NULL;-
1895 }
never executed: end of block
0
1896-
1897 /* Allocate space and format the variable in the appropriate slot. */-
1898 /* XXX xasprintf */-
1899 env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);-
1900 snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);-
1901}
never executed: end of block
0
1902-
1903/*-
1904 * Check and optionally lowercase a domain name, also removes trailing '.'-
1905 * Returns 1 on success and 0 on failure, storing an error message in errstr.-
1906 */-
1907int-
1908valid_domain(char *name, int makelower, const char **errstr)-
1909{-
1910 size_t i, l = strlen(name);-
1911 u_char c, last = '\0';-
1912 static char errbuf[256];-
1913-
1914 if (l == 0) {
l == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1915 strlcpy(errbuf, "empty domain name", sizeof(errbuf));-
1916 goto bad;
never executed: goto bad;
0
1917 }-
1918 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) {
! ((*__ctype_b...int) _ISalpha)Description
TRUEnever evaluated
FALSEnever evaluated
! ((*__ctype_b...int) _ISdigit)Description
TRUEnever evaluated
FALSEnever evaluated
0
1919 snprintf(errbuf, sizeof(errbuf), "domain name \"%.100s\" "-
1920 "starts with invalid character", name);-
1921 goto bad;
never executed: goto bad;
0
1922 }-
1923 for (i = 0; i < l; i++) {
i < lDescription
TRUEnever evaluated
FALSEnever evaluated
0
1924 c = tolower((u_char)name[i]);
never executed: end of block
never executed: __res = tolower ( (u_char)name[i] );
never executed: __res = (*__ctype_tolower_loc ())[(int) ( (u_char)name[i] )];
sizeof ( (u_char)name[i] ) > 1Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_cons...char)name[i] )Description
TRUEnever evaluated
FALSEnever evaluated
__c < -128Description
TRUEnever evaluated
FALSEnever evaluated
__c > 255Description
TRUEnever evaluated
FALSEnever evaluated
0
1925 if (makelower)
makelowerDescription
TRUEnever evaluated
FALSEnever evaluated
0
1926 name[i] = (char)c;
never executed: name[i] = (char)c;
0
1927 if (last == '.' && c == '.') {
last == '.'Description
TRUEnever evaluated
FALSEnever evaluated
c == '.'Description
TRUEnever evaluated
FALSEnever evaluated
0
1928 snprintf(errbuf, sizeof(errbuf), "domain name "-
1929 "\"%.100s\" contains consecutive separators", name);-
1930 goto bad;
never executed: goto bad;
0
1931 }-
1932 if (c != '.' && c != '-' && !isalnum(c) &&
c != '.'Description
TRUEnever evaluated
FALSEnever evaluated
c != '-'Description
TRUEnever evaluated
FALSEnever evaluated
! ((*__ctype_b...int) _ISalnum)Description
TRUEnever evaluated
FALSEnever evaluated
0
1933 c != '_') /* technically invalid, but common */ {
c != '_'Description
TRUEnever evaluated
FALSEnever evaluated
0
1934 snprintf(errbuf, sizeof(errbuf), "domain name "-
1935 "\"%.100s\" contains invalid characters", name);-
1936 goto bad;
never executed: goto bad;
0
1937 }-
1938 last = c;-
1939 }
never executed: end of block
0
1940 if (name[l - 1] == '.')
name[l - 1] == '.'Description
TRUEnever evaluated
FALSEnever evaluated
0
1941 name[l - 1] = '\0';
never executed: name[l - 1] = '\0';
0
1942 if (errstr != NULL)
errstr != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1943 *errstr = NULL;
never executed: *errstr = ((void *)0) ;
0
1944 return 1;
never executed: return 1;
0
1945bad:-
1946 if (errstr != NULL)
errstr != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1947 *errstr = errbuf;
never executed: *errstr = errbuf;
0
1948 return 0;
never executed: return 0;
0
1949}-
1950-
1951const char *-
1952atoi_err(const char *nptr, int *val)-
1953{-
1954 const char *errstr = NULL;-
1955 long long num;-
1956-
1957 if (nptr == NULL || *nptr == '\0')
nptr == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
*nptr == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1958 return "missing";
never executed: return "missing";
0
1959 num = strtonum(nptr, 0, INT_MAX, &errstr);-
1960 if (errstr == NULL)
errstr == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1961 *val = (int)num;
never executed: *val = (int)num;
0
1962 return errstr;
never executed: return errstr;
0
1963}-
1964-
1965int-
1966parse_absolute_time(const char *s, uint64_t *tp)-
1967{-
1968 struct tm tm;-
1969 time_t tt;-
1970 char buf[32], *fmt;-
1971-
1972 *tp = 0;-
1973-
1974 /*-
1975 * POSIX strptime says "The application shall ensure that there-
1976 * is white-space or other non-alphanumeric characters between-
1977 * any two conversion specifications" so arrange things this way.-
1978 */-
1979 switch (strlen(s)) {-
1980 case 8: /* YYYYMMDD */
never executed: case 8:
0
1981 fmt = "%Y-%m-%d";-
1982 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6);-
1983 break;
never executed: break;
0
1984 case 12: /* YYYYMMDDHHMM */
never executed: case 12:
0
1985 fmt = "%Y-%m-%dT%H:%M";-
1986 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s",-
1987 s, s + 4, s + 6, s + 8, s + 10);-
1988 break;
never executed: break;
0
1989 case 14: /* YYYYMMDDHHMMSS */
never executed: case 14:
0
1990 fmt = "%Y-%m-%dT%H:%M:%S";-
1991 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s",-
1992 s, s + 4, s + 6, s + 8, s + 10, s + 12);-
1993 break;
never executed: break;
0
1994 default:
never executed: default:
0
1995 return SSH_ERR_INVALID_FORMAT;
never executed: return -4;
0
1996 }-
1997-
1998 memset(&tm, 0, sizeof(tm));-
1999 if (strptime(buf, fmt, &tm) == NULL)
strptime(buf, ...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2000 return SSH_ERR_INVALID_FORMAT;
never executed: return -4;
0
2001 if ((tt = mktime(&tm)) < 0)
(tt = mktime(&tm)) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2002 return SSH_ERR_INVALID_FORMAT;
never executed: return -4;
0
2003 /* success */-
2004 *tp = (uint64_t)tt;-
2005 return 0;
never executed: return 0;
0
2006}-
2007-
2008void-
2009format_absolute_time(uint64_t t, char *buf, size_t len)-
2010{-
2011 time_t tt = t > INT_MAX ? INT_MAX : t; /* XXX revisit in 2038 :P */
t > 0x7fffffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
2012 struct tm tm;-
2013-
2014 localtime_r(&tt, &tm);-
2015 strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm);-
2016}
never executed: end of block
0
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2