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