misc.c revision 323136
1/* $OpenBSD: misc.c,v 1.109 2017/03/14 00:55:37 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/sysctl.h>
33#include <sys/time.h>
34#include <sys/un.h>
35
36#include <limits.h>
37#include <stdarg.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <time.h>
42#include <unistd.h>
43
44#include <netinet/in.h>
45#include <netinet/in_systm.h>
46#include <netinet/ip.h>
47#include <netinet/tcp.h>
48
49#include <ctype.h>
50#include <errno.h>
51#include <fcntl.h>
52#include <netdb.h>
53#ifdef HAVE_PATHS_H
54# include <paths.h>
55#include <pwd.h>
56#endif
57#ifdef SSH_TUN_OPENBSD
58#include <net/if.h>
59#endif
60
61#include "xmalloc.h"
62#include "misc.h"
63#include "log.h"
64#include "ssh.h"
65
66/* remove newline at end of string */
67char *
68chop(char *s)
69{
70	char *t = s;
71	while (*t) {
72		if (*t == '\n' || *t == '\r') {
73			*t = '\0';
74			return s;
75		}
76		t++;
77	}
78	return s;
79
80}
81
82/* set/unset filedescriptor to non-blocking */
83int
84set_nonblock(int fd)
85{
86	int val;
87
88	val = fcntl(fd, F_GETFL);
89	if (val < 0) {
90		error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
91		return (-1);
92	}
93	if (val & O_NONBLOCK) {
94		debug3("fd %d is O_NONBLOCK", fd);
95		return (0);
96	}
97	debug2("fd %d setting O_NONBLOCK", fd);
98	val |= O_NONBLOCK;
99	if (fcntl(fd, F_SETFL, val) == -1) {
100		debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd,
101		    strerror(errno));
102		return (-1);
103	}
104	return (0);
105}
106
107int
108unset_nonblock(int fd)
109{
110	int val;
111
112	val = fcntl(fd, F_GETFL);
113	if (val < 0) {
114		error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
115		return (-1);
116	}
117	if (!(val & O_NONBLOCK)) {
118		debug3("fd %d is not O_NONBLOCK", fd);
119		return (0);
120	}
121	debug("fd %d clearing O_NONBLOCK", fd);
122	val &= ~O_NONBLOCK;
123	if (fcntl(fd, F_SETFL, val) == -1) {
124		debug("fcntl(%d, F_SETFL, ~O_NONBLOCK): %s",
125		    fd, strerror(errno));
126		return (-1);
127	}
128	return (0);
129}
130
131const char *
132ssh_gai_strerror(int gaierr)
133{
134	if (gaierr == EAI_SYSTEM && errno != 0)
135		return strerror(errno);
136	return gai_strerror(gaierr);
137}
138
139/* disable nagle on socket */
140void
141set_nodelay(int fd)
142{
143	int opt;
144	socklen_t optlen;
145
146	optlen = sizeof opt;
147	if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) {
148		debug("getsockopt TCP_NODELAY: %.100s", strerror(errno));
149		return;
150	}
151	if (opt == 1) {
152		debug2("fd %d is TCP_NODELAY", fd);
153		return;
154	}
155	opt = 1;
156	debug2("fd %d setting TCP_NODELAY", fd);
157	if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1)
158		error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
159}
160
161/* Characters considered whitespace in strsep calls. */
162#define WHITESPACE " \t\r\n"
163#define QUOTE	"\""
164
165/* return next token in configuration line */
166char *
167strdelim(char **s)
168{
169	char *old;
170	int wspace = 0;
171
172	if (*s == NULL)
173		return NULL;
174
175	old = *s;
176
177	*s = strpbrk(*s, WHITESPACE QUOTE "=");
178	if (*s == NULL)
179		return (old);
180
181	if (*s[0] == '\"') {
182		memmove(*s, *s + 1, strlen(*s)); /* move nul too */
183		/* Find matching quote */
184		if ((*s = strpbrk(*s, QUOTE)) == NULL) {
185			return (NULL);		/* no matching quote */
186		} else {
187			*s[0] = '\0';
188			*s += strspn(*s + 1, WHITESPACE) + 1;
189			return (old);
190		}
191	}
192
193	/* Allow only one '=' to be skipped */
194	if (*s[0] == '=')
195		wspace = 1;
196	*s[0] = '\0';
197
198	/* Skip any extra whitespace after first token */
199	*s += strspn(*s + 1, WHITESPACE) + 1;
200	if (*s[0] == '=' && !wspace)
201		*s += strspn(*s + 1, WHITESPACE) + 1;
202
203	return (old);
204}
205
206struct passwd *
207pwcopy(struct passwd *pw)
208{
209	struct passwd *copy = xcalloc(1, sizeof(*copy));
210
211	copy->pw_name = xstrdup(pw->pw_name);
212	copy->pw_passwd = xstrdup(pw->pw_passwd);
213#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
214	copy->pw_gecos = xstrdup(pw->pw_gecos);
215#endif
216	copy->pw_uid = pw->pw_uid;
217	copy->pw_gid = pw->pw_gid;
218#ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE
219	copy->pw_expire = pw->pw_expire;
220#endif
221#ifdef HAVE_STRUCT_PASSWD_PW_CHANGE
222	copy->pw_change = pw->pw_change;
223#endif
224#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
225	copy->pw_class = xstrdup(pw->pw_class);
226#endif
227	copy->pw_dir = xstrdup(pw->pw_dir);
228	copy->pw_shell = xstrdup(pw->pw_shell);
229	return copy;
230}
231
232/*
233 * Convert ASCII string to TCP/IP port number.
234 * Port must be >=0 and <=65535.
235 * Return -1 if invalid.
236 */
237int
238a2port(const char *s)
239{
240	long long port;
241	const char *errstr;
242
243	port = strtonum(s, 0, 65535, &errstr);
244	if (errstr != NULL)
245		return -1;
246	return (int)port;
247}
248
249int
250a2tun(const char *s, int *remote)
251{
252	const char *errstr = NULL;
253	char *sp, *ep;
254	int tun;
255
256	if (remote != NULL) {
257		*remote = SSH_TUNID_ANY;
258		sp = xstrdup(s);
259		if ((ep = strchr(sp, ':')) == NULL) {
260			free(sp);
261			return (a2tun(s, NULL));
262		}
263		ep[0] = '\0'; ep++;
264		*remote = a2tun(ep, NULL);
265		tun = a2tun(sp, NULL);
266		free(sp);
267		return (*remote == SSH_TUNID_ERR ? *remote : tun);
268	}
269
270	if (strcasecmp(s, "any") == 0)
271		return (SSH_TUNID_ANY);
272
273	tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr);
274	if (errstr != NULL)
275		return (SSH_TUNID_ERR);
276
277	return (tun);
278}
279
280#define SECONDS		1
281#define MINUTES		(SECONDS * 60)
282#define HOURS		(MINUTES * 60)
283#define DAYS		(HOURS * 24)
284#define WEEKS		(DAYS * 7)
285
286/*
287 * Convert a time string into seconds; format is
288 * a sequence of:
289 *      time[qualifier]
290 *
291 * Valid time qualifiers are:
292 *      <none>  seconds
293 *      s|S     seconds
294 *      m|M     minutes
295 *      h|H     hours
296 *      d|D     days
297 *      w|W     weeks
298 *
299 * Examples:
300 *      90m     90 minutes
301 *      1h30m   90 minutes
302 *      2d      2 days
303 *      1w      1 week
304 *
305 * Return -1 if time string is invalid.
306 */
307long
308convtime(const char *s)
309{
310	long total, secs, multiplier = 1;
311	const char *p;
312	char *endp;
313
314	errno = 0;
315	total = 0;
316	p = s;
317
318	if (p == NULL || *p == '\0')
319		return -1;
320
321	while (*p) {
322		secs = strtol(p, &endp, 10);
323		if (p == endp ||
324		    (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||
325		    secs < 0)
326			return -1;
327
328		switch (*endp++) {
329		case '\0':
330			endp--;
331			break;
332		case 's':
333		case 'S':
334			break;
335		case 'm':
336		case 'M':
337			multiplier = MINUTES;
338			break;
339		case 'h':
340		case 'H':
341			multiplier = HOURS;
342			break;
343		case 'd':
344		case 'D':
345			multiplier = DAYS;
346			break;
347		case 'w':
348		case 'W':
349			multiplier = WEEKS;
350			break;
351		default:
352			return -1;
353		}
354		if (secs >= LONG_MAX / multiplier)
355			return -1;
356		secs *= multiplier;
357		if  (total >= LONG_MAX - secs)
358			return -1;
359		total += secs;
360		if (total < 0)
361			return -1;
362		p = endp;
363	}
364
365	return total;
366}
367
368/*
369 * Returns a standardized host+port identifier string.
370 * Caller must free returned string.
371 */
372char *
373put_host_port(const char *host, u_short port)
374{
375	char *hoststr;
376
377	if (port == 0 || port == SSH_DEFAULT_PORT)
378		return(xstrdup(host));
379	if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0)
380		fatal("put_host_port: asprintf: %s", strerror(errno));
381	debug3("put_host_port: %s", hoststr);
382	return hoststr;
383}
384
385/*
386 * Search for next delimiter between hostnames/addresses and ports.
387 * Argument may be modified (for termination).
388 * Returns *cp if parsing succeeds.
389 * *cp is set to the start of the next delimiter, if one was found.
390 * If this is the last field, *cp is set to NULL.
391 */
392char *
393hpdelim(char **cp)
394{
395	char *s, *old;
396
397	if (cp == NULL || *cp == NULL)
398		return NULL;
399
400	old = s = *cp;
401	if (*s == '[') {
402		if ((s = strchr(s, ']')) == NULL)
403			return NULL;
404		else
405			s++;
406	} else if ((s = strpbrk(s, ":/")) == NULL)
407		s = *cp + strlen(*cp); /* skip to end (see first case below) */
408
409	switch (*s) {
410	case '\0':
411		*cp = NULL;	/* no more fields*/
412		break;
413
414	case ':':
415	case '/':
416		*s = '\0';	/* terminate */
417		*cp = s + 1;
418		break;
419
420	default:
421		return NULL;
422	}
423
424	return old;
425}
426
427char *
428cleanhostname(char *host)
429{
430	if (*host == '[' && host[strlen(host) - 1] == ']') {
431		host[strlen(host) - 1] = '\0';
432		return (host + 1);
433	} else
434		return host;
435}
436
437char *
438colon(char *cp)
439{
440	int flag = 0;
441
442	if (*cp == ':')		/* Leading colon is part of file name. */
443		return NULL;
444	if (*cp == '[')
445		flag = 1;
446
447	for (; *cp; ++cp) {
448		if (*cp == '@' && *(cp+1) == '[')
449			flag = 1;
450		if (*cp == ']' && *(cp+1) == ':' && flag)
451			return (cp+1);
452		if (*cp == ':' && !flag)
453			return (cp);
454		if (*cp == '/')
455			return NULL;
456	}
457	return NULL;
458}
459
460/*
461 * Parse a [user@]host[:port] string.
462 * Caller must free returned user and host.
463 * Any of the pointer return arguments may be NULL (useful for syntax checking).
464 * If user was not specified then *userp will be set to NULL.
465 * If port was not specified then *portp will be -1.
466 * Returns 0 on success, -1 on failure.
467 */
468int
469parse_user_host_port(const char *s, char **userp, char **hostp, int *portp)
470{
471	char *sdup, *cp, *tmp;
472	char *user = NULL, *host = NULL;
473	int port = -1, ret = -1;
474
475	if (userp != NULL)
476		*userp = NULL;
477	if (hostp != NULL)
478		*hostp = NULL;
479	if (portp != NULL)
480		*portp = -1;
481
482	if ((sdup = tmp = strdup(s)) == NULL)
483		return -1;
484	/* Extract optional username */
485	if ((cp = strchr(tmp, '@')) != NULL) {
486		*cp = '\0';
487		if (*tmp == '\0')
488			goto out;
489		if ((user = strdup(tmp)) == NULL)
490			goto out;
491		tmp = cp + 1;
492	}
493	/* Extract mandatory hostname */
494	if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0')
495		goto out;
496	host = xstrdup(cleanhostname(cp));
497	/* Convert and verify optional port */
498	if (tmp != NULL && *tmp != '\0') {
499		if ((port = a2port(tmp)) <= 0)
500			goto out;
501	}
502	/* Success */
503	if (userp != NULL) {
504		*userp = user;
505		user = NULL;
506	}
507	if (hostp != NULL) {
508		*hostp = host;
509		host = NULL;
510	}
511	if (portp != NULL)
512		*portp = port;
513	ret = 0;
514 out:
515	free(sdup);
516	free(user);
517	free(host);
518	return ret;
519}
520
521/* function to assist building execv() arguments */
522void
523addargs(arglist *args, char *fmt, ...)
524{
525	va_list ap;
526	char *cp;
527	u_int nalloc;
528	int r;
529
530	va_start(ap, fmt);
531	r = vasprintf(&cp, fmt, ap);
532	va_end(ap);
533	if (r == -1)
534		fatal("addargs: argument too long");
535
536	nalloc = args->nalloc;
537	if (args->list == NULL) {
538		nalloc = 32;
539		args->num = 0;
540	} else if (args->num+2 >= nalloc)
541		nalloc *= 2;
542
543	args->list = xreallocarray(args->list, nalloc, sizeof(char *));
544	args->nalloc = nalloc;
545	args->list[args->num++] = cp;
546	args->list[args->num] = NULL;
547}
548
549void
550replacearg(arglist *args, u_int which, char *fmt, ...)
551{
552	va_list ap;
553	char *cp;
554	int r;
555
556	va_start(ap, fmt);
557	r = vasprintf(&cp, fmt, ap);
558	va_end(ap);
559	if (r == -1)
560		fatal("replacearg: argument too long");
561
562	if (which >= args->num)
563		fatal("replacearg: tried to replace invalid arg %d >= %d",
564		    which, args->num);
565	free(args->list[which]);
566	args->list[which] = cp;
567}
568
569void
570freeargs(arglist *args)
571{
572	u_int i;
573
574	if (args->list != NULL) {
575		for (i = 0; i < args->num; i++)
576			free(args->list[i]);
577		free(args->list);
578		args->nalloc = args->num = 0;
579		args->list = NULL;
580	}
581}
582
583/*
584 * Expands tildes in the file name.  Returns data allocated by xmalloc.
585 * Warning: this calls getpw*.
586 */
587char *
588tilde_expand_filename(const char *filename, uid_t uid)
589{
590	const char *path, *sep;
591	char user[128], *ret;
592	struct passwd *pw;
593	u_int len, slash;
594
595	if (*filename != '~')
596		return (xstrdup(filename));
597	filename++;
598
599	path = strchr(filename, '/');
600	if (path != NULL && path > filename) {		/* ~user/path */
601		slash = path - filename;
602		if (slash > sizeof(user) - 1)
603			fatal("tilde_expand_filename: ~username too long");
604		memcpy(user, filename, slash);
605		user[slash] = '\0';
606		if ((pw = getpwnam(user)) == NULL)
607			fatal("tilde_expand_filename: No such user %s", user);
608	} else if ((pw = getpwuid(uid)) == NULL)	/* ~/path */
609		fatal("tilde_expand_filename: No such uid %ld", (long)uid);
610
611	/* Make sure directory has a trailing '/' */
612	len = strlen(pw->pw_dir);
613	if (len == 0 || pw->pw_dir[len - 1] != '/')
614		sep = "/";
615	else
616		sep = "";
617
618	/* Skip leading '/' from specified path */
619	if (path != NULL)
620		filename = path + 1;
621
622	if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX)
623		fatal("tilde_expand_filename: Path too long");
624
625	return (ret);
626}
627
628/*
629 * Expand a string with a set of %[char] escapes. A number of escapes may be
630 * specified as (char *escape_chars, char *replacement) pairs. The list must
631 * be terminated by a NULL escape_char. Returns replaced string in memory
632 * allocated by xmalloc.
633 */
634char *
635percent_expand(const char *string, ...)
636{
637#define EXPAND_MAX_KEYS	16
638	u_int num_keys, i, j;
639	struct {
640		const char *key;
641		const char *repl;
642	} keys[EXPAND_MAX_KEYS];
643	char buf[4096];
644	va_list ap;
645
646	/* Gather keys */
647	va_start(ap, string);
648	for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {
649		keys[num_keys].key = va_arg(ap, char *);
650		if (keys[num_keys].key == NULL)
651			break;
652		keys[num_keys].repl = va_arg(ap, char *);
653		if (keys[num_keys].repl == NULL)
654			fatal("%s: NULL replacement", __func__);
655	}
656	if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL)
657		fatal("%s: too many keys", __func__);
658	va_end(ap);
659
660	/* Expand string */
661	*buf = '\0';
662	for (i = 0; *string != '\0'; string++) {
663		if (*string != '%') {
664 append:
665			buf[i++] = *string;
666			if (i >= sizeof(buf))
667				fatal("%s: string too long", __func__);
668			buf[i] = '\0';
669			continue;
670		}
671		string++;
672		/* %% case */
673		if (*string == '%')
674			goto append;
675		if (*string == '\0')
676			fatal("%s: invalid format", __func__);
677		for (j = 0; j < num_keys; j++) {
678			if (strchr(keys[j].key, *string) != NULL) {
679				i = strlcat(buf, keys[j].repl, sizeof(buf));
680				if (i >= sizeof(buf))
681					fatal("%s: string too long", __func__);
682				break;
683			}
684		}
685		if (j >= num_keys)
686			fatal("%s: unknown key %%%c", __func__, *string);
687	}
688	return (xstrdup(buf));
689#undef EXPAND_MAX_KEYS
690}
691
692/*
693 * Read an entire line from a public key file into a static buffer, discarding
694 * lines that exceed the buffer size.  Returns 0 on success, -1 on failure.
695 */
696int
697read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
698   u_long *lineno)
699{
700	while (fgets(buf, bufsz, f) != NULL) {
701		if (buf[0] == '\0')
702			continue;
703		(*lineno)++;
704		if (buf[strlen(buf) - 1] == '\n' || feof(f)) {
705			return 0;
706		} else {
707			debug("%s: %s line %lu exceeds size limit", __func__,
708			    filename, *lineno);
709			/* discard remainder of line */
710			while (fgetc(f) != '\n' && !feof(f))
711				;	/* nothing */
712		}
713	}
714	return -1;
715}
716
717int
718tun_open(int tun, int mode)
719{
720#if defined(CUSTOM_SYS_TUN_OPEN)
721	return (sys_tun_open(tun, mode));
722#elif defined(SSH_TUN_OPENBSD)
723	struct ifreq ifr;
724	char name[100];
725	int fd = -1, sock;
726	const char *tunbase = "tun";
727
728	if (mode == SSH_TUNMODE_ETHERNET)
729		tunbase = "tap";
730
731	/* Open the tunnel device */
732	if (tun <= SSH_TUNID_MAX) {
733		snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun);
734		fd = open(name, O_RDWR);
735	} else if (tun == SSH_TUNID_ANY) {
736		for (tun = 100; tun >= 0; tun--) {
737			snprintf(name, sizeof(name), "/dev/%s%d",
738			    tunbase, tun);
739			if ((fd = open(name, O_RDWR)) >= 0)
740				break;
741		}
742	} else {
743		debug("%s: invalid tunnel %u", __func__, tun);
744		return -1;
745	}
746
747	if (fd < 0) {
748		debug("%s: %s open: %s", __func__, name, strerror(errno));
749		return -1;
750	}
751
752	debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
753
754	/* Bring interface up if it is not already */
755	snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun);
756	if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
757		goto failed;
758
759	if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
760		debug("%s: get interface %s flags: %s", __func__,
761		    ifr.ifr_name, strerror(errno));
762		goto failed;
763	}
764
765	if (!(ifr.ifr_flags & IFF_UP)) {
766		ifr.ifr_flags |= IFF_UP;
767		if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {
768			debug("%s: activate interface %s: %s", __func__,
769			    ifr.ifr_name, strerror(errno));
770			goto failed;
771		}
772	}
773
774	close(sock);
775	return fd;
776
777 failed:
778	if (fd >= 0)
779		close(fd);
780	if (sock >= 0)
781		close(sock);
782	return -1;
783#else
784	error("Tunnel interfaces are not supported on this platform");
785	return (-1);
786#endif
787}
788
789void
790sanitise_stdfd(void)
791{
792	int nullfd, dupfd;
793
794	if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
795		fprintf(stderr, "Couldn't open /dev/null: %s\n",
796		    strerror(errno));
797		exit(1);
798	}
799	while (++dupfd <= STDERR_FILENO) {
800		/* Only populate closed fds. */
801		if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) {
802			if (dup2(nullfd, dupfd) == -1) {
803				fprintf(stderr, "dup2: %s\n", strerror(errno));
804				exit(1);
805			}
806		}
807	}
808	if (nullfd > STDERR_FILENO)
809		close(nullfd);
810}
811
812char *
813tohex(const void *vp, size_t l)
814{
815	const u_char *p = (const u_char *)vp;
816	char b[3], *r;
817	size_t i, hl;
818
819	if (l > 65536)
820		return xstrdup("tohex: length > 65536");
821
822	hl = l * 2 + 1;
823	r = xcalloc(1, hl);
824	for (i = 0; i < l; i++) {
825		snprintf(b, sizeof(b), "%02x", p[i]);
826		strlcat(r, b, hl);
827	}
828	return (r);
829}
830
831u_int64_t
832get_u64(const void *vp)
833{
834	const u_char *p = (const u_char *)vp;
835	u_int64_t v;
836
837	v  = (u_int64_t)p[0] << 56;
838	v |= (u_int64_t)p[1] << 48;
839	v |= (u_int64_t)p[2] << 40;
840	v |= (u_int64_t)p[3] << 32;
841	v |= (u_int64_t)p[4] << 24;
842	v |= (u_int64_t)p[5] << 16;
843	v |= (u_int64_t)p[6] << 8;
844	v |= (u_int64_t)p[7];
845
846	return (v);
847}
848
849u_int32_t
850get_u32(const void *vp)
851{
852	const u_char *p = (const u_char *)vp;
853	u_int32_t v;
854
855	v  = (u_int32_t)p[0] << 24;
856	v |= (u_int32_t)p[1] << 16;
857	v |= (u_int32_t)p[2] << 8;
858	v |= (u_int32_t)p[3];
859
860	return (v);
861}
862
863u_int32_t
864get_u32_le(const void *vp)
865{
866	const u_char *p = (const u_char *)vp;
867	u_int32_t v;
868
869	v  = (u_int32_t)p[0];
870	v |= (u_int32_t)p[1] << 8;
871	v |= (u_int32_t)p[2] << 16;
872	v |= (u_int32_t)p[3] << 24;
873
874	return (v);
875}
876
877u_int16_t
878get_u16(const void *vp)
879{
880	const u_char *p = (const u_char *)vp;
881	u_int16_t v;
882
883	v  = (u_int16_t)p[0] << 8;
884	v |= (u_int16_t)p[1];
885
886	return (v);
887}
888
889void
890put_u64(void *vp, u_int64_t v)
891{
892	u_char *p = (u_char *)vp;
893
894	p[0] = (u_char)(v >> 56) & 0xff;
895	p[1] = (u_char)(v >> 48) & 0xff;
896	p[2] = (u_char)(v >> 40) & 0xff;
897	p[3] = (u_char)(v >> 32) & 0xff;
898	p[4] = (u_char)(v >> 24) & 0xff;
899	p[5] = (u_char)(v >> 16) & 0xff;
900	p[6] = (u_char)(v >> 8) & 0xff;
901	p[7] = (u_char)v & 0xff;
902}
903
904void
905put_u32(void *vp, u_int32_t v)
906{
907	u_char *p = (u_char *)vp;
908
909	p[0] = (u_char)(v >> 24) & 0xff;
910	p[1] = (u_char)(v >> 16) & 0xff;
911	p[2] = (u_char)(v >> 8) & 0xff;
912	p[3] = (u_char)v & 0xff;
913}
914
915void
916put_u32_le(void *vp, u_int32_t v)
917{
918	u_char *p = (u_char *)vp;
919
920	p[0] = (u_char)v & 0xff;
921	p[1] = (u_char)(v >> 8) & 0xff;
922	p[2] = (u_char)(v >> 16) & 0xff;
923	p[3] = (u_char)(v >> 24) & 0xff;
924}
925
926void
927put_u16(void *vp, u_int16_t v)
928{
929	u_char *p = (u_char *)vp;
930
931	p[0] = (u_char)(v >> 8) & 0xff;
932	p[1] = (u_char)v & 0xff;
933}
934
935void
936ms_subtract_diff(struct timeval *start, int *ms)
937{
938	struct timeval diff, finish;
939
940	gettimeofday(&finish, NULL);
941	timersub(&finish, start, &diff);
942	*ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);
943}
944
945void
946ms_to_timeval(struct timeval *tv, int ms)
947{
948	if (ms < 0)
949		ms = 0;
950	tv->tv_sec = ms / 1000;
951	tv->tv_usec = (ms % 1000) * 1000;
952}
953
954time_t
955monotime(void)
956{
957#if defined(HAVE_CLOCK_GETTIME) && \
958    (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME))
959	struct timespec ts;
960	static int gettime_failed = 0;
961
962	if (!gettime_failed) {
963#if defined(CLOCK_BOOTTIME)
964		if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0)
965			return (ts.tv_sec);
966#endif
967#if defined(CLOCK_MONOTONIC)
968		if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
969			return (ts.tv_sec);
970#endif
971		debug3("clock_gettime: %s", strerror(errno));
972		gettime_failed = 1;
973	}
974#endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */
975
976	return time(NULL);
977}
978
979double
980monotime_double(void)
981{
982#if defined(HAVE_CLOCK_GETTIME) && \
983    (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME))
984	struct timespec ts;
985	static int gettime_failed = 0;
986
987	if (!gettime_failed) {
988#if defined(CLOCK_BOOTTIME)
989		if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0)
990			return (ts.tv_sec + (double)ts.tv_nsec / 1000000000);
991#endif
992#if defined(CLOCK_MONOTONIC)
993		if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
994			return (ts.tv_sec + (double)ts.tv_nsec / 1000000000);
995#endif
996		debug3("clock_gettime: %s", strerror(errno));
997		gettime_failed = 1;
998	}
999#endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */
1000
1001	return (double)time(NULL);
1002}
1003
1004void
1005bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen)
1006{
1007	bw->buflen = buflen;
1008	bw->rate = kbps;
1009	bw->thresh = bw->rate;
1010	bw->lamt = 0;
1011	timerclear(&bw->bwstart);
1012	timerclear(&bw->bwend);
1013}
1014
1015/* Callback from read/write loop to insert bandwidth-limiting delays */
1016void
1017bandwidth_limit(struct bwlimit *bw, size_t read_len)
1018{
1019	u_int64_t waitlen;
1020	struct timespec ts, rm;
1021
1022	if (!timerisset(&bw->bwstart)) {
1023		gettimeofday(&bw->bwstart, NULL);
1024		return;
1025	}
1026
1027	bw->lamt += read_len;
1028	if (bw->lamt < bw->thresh)
1029		return;
1030
1031	gettimeofday(&bw->bwend, NULL);
1032	timersub(&bw->bwend, &bw->bwstart, &bw->bwend);
1033	if (!timerisset(&bw->bwend))
1034		return;
1035
1036	bw->lamt *= 8;
1037	waitlen = (double)1000000L * bw->lamt / bw->rate;
1038
1039	bw->bwstart.tv_sec = waitlen / 1000000L;
1040	bw->bwstart.tv_usec = waitlen % 1000000L;
1041
1042	if (timercmp(&bw->bwstart, &bw->bwend, >)) {
1043		timersub(&bw->bwstart, &bw->bwend, &bw->bwend);
1044
1045		/* Adjust the wait time */
1046		if (bw->bwend.tv_sec) {
1047			bw->thresh /= 2;
1048			if (bw->thresh < bw->buflen / 4)
1049				bw->thresh = bw->buflen / 4;
1050		} else if (bw->bwend.tv_usec < 10000) {
1051			bw->thresh *= 2;
1052			if (bw->thresh > bw->buflen * 8)
1053				bw->thresh = bw->buflen * 8;
1054		}
1055
1056		TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts);
1057		while (nanosleep(&ts, &rm) == -1) {
1058			if (errno != EINTR)
1059				break;
1060			ts = rm;
1061		}
1062	}
1063
1064	bw->lamt = 0;
1065	gettimeofday(&bw->bwstart, NULL);
1066}
1067
1068/* Make a template filename for mk[sd]temp() */
1069void
1070mktemp_proto(char *s, size_t len)
1071{
1072	const char *tmpdir;
1073	int r;
1074
1075	if ((tmpdir = getenv("TMPDIR")) != NULL) {
1076		r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir);
1077		if (r > 0 && (size_t)r < len)
1078			return;
1079	}
1080	r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX");
1081	if (r < 0 || (size_t)r >= len)
1082		fatal("%s: template string too short", __func__);
1083}
1084
1085static const struct {
1086	const char *name;
1087	int value;
1088} ipqos[] = {
1089	{ "af11", IPTOS_DSCP_AF11 },
1090	{ "af12", IPTOS_DSCP_AF12 },
1091	{ "af13", IPTOS_DSCP_AF13 },
1092	{ "af21", IPTOS_DSCP_AF21 },
1093	{ "af22", IPTOS_DSCP_AF22 },
1094	{ "af23", IPTOS_DSCP_AF23 },
1095	{ "af31", IPTOS_DSCP_AF31 },
1096	{ "af32", IPTOS_DSCP_AF32 },
1097	{ "af33", IPTOS_DSCP_AF33 },
1098	{ "af41", IPTOS_DSCP_AF41 },
1099	{ "af42", IPTOS_DSCP_AF42 },
1100	{ "af43", IPTOS_DSCP_AF43 },
1101	{ "cs0", IPTOS_DSCP_CS0 },
1102	{ "cs1", IPTOS_DSCP_CS1 },
1103	{ "cs2", IPTOS_DSCP_CS2 },
1104	{ "cs3", IPTOS_DSCP_CS3 },
1105	{ "cs4", IPTOS_DSCP_CS4 },
1106	{ "cs5", IPTOS_DSCP_CS5 },
1107	{ "cs6", IPTOS_DSCP_CS6 },
1108	{ "cs7", IPTOS_DSCP_CS7 },
1109	{ "ef", IPTOS_DSCP_EF },
1110	{ "lowdelay", IPTOS_LOWDELAY },
1111	{ "throughput", IPTOS_THROUGHPUT },
1112	{ "reliability", IPTOS_RELIABILITY },
1113	{ NULL, -1 }
1114};
1115
1116int
1117parse_ipqos(const char *cp)
1118{
1119	u_int i;
1120	char *ep;
1121	long val;
1122
1123	if (cp == NULL)
1124		return -1;
1125	for (i = 0; ipqos[i].name != NULL; i++) {
1126		if (strcasecmp(cp, ipqos[i].name) == 0)
1127			return ipqos[i].value;
1128	}
1129	/* Try parsing as an integer */
1130	val = strtol(cp, &ep, 0);
1131	if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255)
1132		return -1;
1133	return val;
1134}
1135
1136const char *
1137iptos2str(int iptos)
1138{
1139	int i;
1140	static char iptos_str[sizeof "0xff"];
1141
1142	for (i = 0; ipqos[i].name != NULL; i++) {
1143		if (ipqos[i].value == iptos)
1144			return ipqos[i].name;
1145	}
1146	snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos);
1147	return iptos_str;
1148}
1149
1150void
1151lowercase(char *s)
1152{
1153	for (; *s; s++)
1154		*s = tolower((u_char)*s);
1155}
1156
1157int
1158unix_listener(const char *path, int backlog, int unlink_first)
1159{
1160	struct sockaddr_un sunaddr;
1161	int saved_errno, sock;
1162
1163	memset(&sunaddr, 0, sizeof(sunaddr));
1164	sunaddr.sun_family = AF_UNIX;
1165	if (strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) {
1166		error("%s: \"%s\" too long for Unix domain socket", __func__,
1167		    path);
1168		errno = ENAMETOOLONG;
1169		return -1;
1170	}
1171
1172	sock = socket(PF_UNIX, SOCK_STREAM, 0);
1173	if (sock < 0) {
1174		saved_errno = errno;
1175		error("socket: %.100s", strerror(errno));
1176		errno = saved_errno;
1177		return -1;
1178	}
1179	if (unlink_first == 1) {
1180		if (unlink(path) != 0 && errno != ENOENT)
1181			error("unlink(%s): %.100s", path, strerror(errno));
1182	}
1183	if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {
1184		saved_errno = errno;
1185		error("bind: %.100s", strerror(errno));
1186		close(sock);
1187		error("%s: cannot bind to path: %s", __func__, path);
1188		errno = saved_errno;
1189		return -1;
1190	}
1191	if (listen(sock, backlog) < 0) {
1192		saved_errno = errno;
1193		error("listen: %.100s", strerror(errno));
1194		close(sock);
1195		unlink(path);
1196		error("%s: cannot listen on path: %s", __func__, path);
1197		errno = saved_errno;
1198		return -1;
1199	}
1200	return sock;
1201}
1202
1203void
1204sock_set_v6only(int s)
1205{
1206#if defined(IPV6_V6ONLY) && !defined(__OpenBSD__)
1207	int on = 1;
1208
1209	debug3("%s: set socket %d IPV6_V6ONLY", __func__, s);
1210	if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1)
1211		error("setsockopt IPV6_V6ONLY: %s", strerror(errno));
1212#endif
1213}
1214
1215/*
1216 * Compares two strings that maybe be NULL. Returns non-zero if strings
1217 * are both NULL or are identical, returns zero otherwise.
1218 */
1219static int
1220strcmp_maybe_null(const char *a, const char *b)
1221{
1222	if ((a == NULL && b != NULL) || (a != NULL && b == NULL))
1223		return 0;
1224	if (a != NULL && strcmp(a, b) != 0)
1225		return 0;
1226	return 1;
1227}
1228
1229/*
1230 * Compare two forwards, returning non-zero if they are identical or
1231 * zero otherwise.
1232 */
1233int
1234forward_equals(const struct Forward *a, const struct Forward *b)
1235{
1236	if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0)
1237		return 0;
1238	if (a->listen_port != b->listen_port)
1239		return 0;
1240	if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0)
1241		return 0;
1242	if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0)
1243		return 0;
1244	if (a->connect_port != b->connect_port)
1245		return 0;
1246	if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0)
1247		return 0;
1248	/* allocated_port and handle are not checked */
1249	return 1;
1250}
1251
1252static int
1253ipport_reserved(void)
1254{
1255#if __FreeBSD__
1256	int old, ret;
1257	size_t len = sizeof(old);
1258
1259	ret = sysctlbyname("net.inet.ip.portrange.reservedhigh",
1260	    &old, &len, NULL, 0);
1261	if (ret == 0)
1262		return (old + 1);
1263#endif
1264	return (IPPORT_RESERVED);
1265}
1266
1267/* returns 1 if bind to specified port by specified user is permitted */
1268int
1269bind_permitted(int port, uid_t uid)
1270{
1271
1272	if (port < ipport_reserved() && uid != 0)
1273		return 0;
1274	return 1;
1275}
1276
1277/* returns 1 if process is already daemonized, 0 otherwise */
1278int
1279daemonized(void)
1280{
1281	int fd;
1282
1283	if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) {
1284		close(fd);
1285		return 0;	/* have controlling terminal */
1286	}
1287	if (getppid() != 1)
1288		return 0;	/* parent is not init */
1289	if (getsid(0) != getpid())
1290		return 0;	/* not session leader */
1291	debug3("already daemonized");
1292	return 1;
1293}
1294