1/* $OpenBSD: util.c,v 1.72 2019/06/28 13:32:44 deraadt Exp $	 */
2/* $EOM: util.c,v 1.23 2000/11/23 12:22:08 niklas Exp $	 */
3
4/*
5 * Copyright (c) 1998, 1999, 2001 Niklas Hallqvist.  All rights reserved.
6 * Copyright (c) 2000, 2001, 2004 H�kan Olsson.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * This code was written under funding by Ericsson Radio Systems.
31 */
32
33#include <sys/types.h>
34#include <sys/socket.h>
35#include <sys/stat.h>
36#include <netinet/in.h>
37#include <arpa/inet.h>
38#include <limits.h>
39#include <netdb.h>
40#include <stdlib.h>
41#include <string.h>
42#include <unistd.h>
43#include <errno.h>
44#include <ifaddrs.h>
45#include <net/route.h>
46#include <net/if.h>
47
48#include "log.h"
49#include "message.h"
50#include "monitor.h"
51#include "transport.h"
52#include "util.h"
53
54/*
55 * Set if -N is given, allowing name lookups to be done, possibly stalling
56 * the daemon for quite a while.
57 */
58int	allow_name_lookups = 0;
59
60/*
61 * XXX These might be turned into inlines or macros, maybe even
62 * machine-dependent ones, for performance reasons.
63 */
64u_int16_t
65decode_16(u_int8_t *cp)
66{
67	return cp[0] << 8 | cp[1];
68}
69
70u_int32_t
71decode_32(u_int8_t *cp)
72{
73	return cp[0] << 24 | cp[1] << 16 | cp[2] << 8 | cp[3];
74}
75
76void
77encode_16(u_int8_t *cp, u_int16_t x)
78{
79	*cp++ = x >> 8;
80	*cp = x & 0xff;
81}
82
83void
84encode_32(u_int8_t *cp, u_int32_t x)
85{
86	*cp++ = x >> 24;
87	*cp++ = (x >> 16) & 0xff;
88	*cp++ = (x >> 8) & 0xff;
89	*cp = x & 0xff;
90}
91
92/* Check a buffer for all zeroes.  */
93int
94zero_test(const u_int8_t *p, size_t sz)
95{
96	while (sz-- > 0)
97		if (*p++ != 0)
98			return 0;
99	return 1;
100}
101
102static __inline int
103hex2nibble(char c)
104{
105	if (c >= '0' && c <= '9')
106		return c - '0';
107	if (c >= 'a' && c <= 'f')
108		return c - 'a' + 10;
109	if (c >= 'A' && c <= 'F')
110		return c - 'A' + 10;
111	return -1;
112}
113
114/*
115 * Convert hexadecimal string in S to raw binary buffer at BUF sized SZ
116 * bytes.  Return 0 if everything is OK, -1 otherwise.
117 */
118int
119hex2raw(char *s, u_int8_t *buf, size_t sz)
120{
121	u_int8_t *bp;
122	char	*p;
123	int	tmp;
124
125	if (strlen(s) > sz * 2)
126		return -1;
127	for (p = s + strlen(s) - 1, bp = &buf[sz - 1]; bp >= buf; bp--) {
128		*bp = 0;
129		if (p >= s) {
130			tmp = hex2nibble(*p--);
131			if (tmp == -1)
132				return -1;
133			*bp = tmp;
134		}
135		if (p >= s) {
136			tmp = hex2nibble(*p--);
137			if (tmp == -1)
138				return -1;
139			*bp |= tmp << 4;
140		}
141	}
142	return 0;
143}
144
145/*
146 * Convert raw binary buffer to a newly allocated hexadecimal string.  Returns
147 * NULL if an error occurred.  It is the caller's responsibility to free the
148 * returned string.
149 */
150char *
151raw2hex(u_int8_t *buf, size_t sz)
152{
153	char *s;
154	size_t i;
155
156	if ((s = malloc(sz * 2 + 1)) == NULL) {
157		log_error("raw2hex: malloc (%lu) failed", (unsigned long)sz * 2 + 1);
158		return NULL;
159	}
160
161	for (i = 0; i < sz; i++)
162		snprintf(s + (2 * i), 2 * (sz - i) + 1, "%02x", buf[i]);
163
164	s[sz * 2] = '\0';
165	return s;
166}
167
168in_port_t
169text2port(char *port_str)
170{
171	char           *port_str_end;
172	long            port_long;
173	struct servent *service;
174
175	port_long = strtol(port_str, &port_str_end, 0);
176	if (port_str == port_str_end) {
177		service = getservbyname(port_str, "udp");
178		if (!service) {
179			log_print("text2port: service \"%s\" unknown",
180			    port_str);
181			return 0;
182		}
183		return ntohs(service->s_port);
184	} else if (port_long < 1 || port_long > (long)USHRT_MAX) {
185		log_print("text2port: port %ld out of range", port_long);
186		return 0;
187	}
188	return port_long;
189}
190
191int
192text2sockaddr(char *address, char *port, struct sockaddr **sa, sa_family_t af,
193    int netmask)
194{
195	struct addrinfo *ai, hints;
196	struct sockaddr_storage tmp_sas;
197	struct ifaddrs *ifap, *ifa = NULL, *llifa = NULL;
198	char *np = address;
199	char ifname[IFNAMSIZ];
200	u_char buf[BUFSIZ];
201	struct rt_msghdr *rtm;
202	struct sockaddr *sa2;
203	struct sockaddr_in *sin;
204	struct sockaddr_in6 *sin6;
205	int fd = 0, seq, len, b;
206	pid_t pid;
207
208	bzero(&hints, sizeof hints);
209	if (!allow_name_lookups)
210		hints.ai_flags = AI_NUMERICHOST;
211	hints.ai_family = PF_UNSPEC;
212	hints.ai_socktype = SOCK_DGRAM;
213	hints.ai_protocol = IPPROTO_UDP;
214
215	if (getaddrinfo(address, port, &hints, &ai)) {
216		/*
217		 * If the 'default' keyword is used, do a route lookup for
218		 * the default route, and use the interface associated with
219		 * it to select a source address.
220		 */
221		if (!strcmp(address, "default")) {
222			fd = socket(AF_ROUTE, SOCK_RAW, af);
223
224			bzero(buf, sizeof(buf));
225
226			rtm = (struct rt_msghdr *)buf;
227			rtm->rtm_version = RTM_VERSION;
228			rtm->rtm_type = RTM_GET;
229			rtm->rtm_flags = RTF_UP;
230			rtm->rtm_addrs = RTA_DST;
231			rtm->rtm_seq = seq = arc4random();
232
233			/* default destination */
234			sa2 = (struct sockaddr *)((char *)rtm + rtm->rtm_hdrlen);
235			switch (af) {
236			case AF_INET: {
237				sin = (struct sockaddr_in *)sa2;
238				sin->sin_len = sizeof(*sin);
239				sin->sin_family = af;
240				break;
241			}
242			case AF_INET6: {
243				sin6 = (struct sockaddr_in6 *)sa2;
244				sin6->sin6_len = sizeof(*sin6);
245				sin6->sin6_family = af;
246				break;
247			}
248			default:
249				close(fd);
250				return -1;
251			}
252			rtm->rtm_addrs |= RTA_NETMASK|RTA_IFP|RTA_IFA;
253			rtm->rtm_msglen = sizeof(*rtm) + sizeof(*sa2);
254
255			if ((b = write(fd, buf, rtm->rtm_msglen)) == -1) {
256				close(fd);
257				return -1;
258			}
259
260			pid = getpid();
261
262			while ((len = read(fd, buf, sizeof(buf))) > 0) {
263				if (len < sizeof(*rtm)) {
264					close(fd);
265					return -1;
266				}
267				if (rtm->rtm_version != RTM_VERSION)
268					continue;
269
270				if (rtm->rtm_type == RTM_GET &&
271				    rtm->rtm_pid == pid &&
272				    rtm->rtm_seq == seq) {
273					if (rtm->rtm_errno) {
274						close(fd);
275						return -1;
276					}
277					break;
278				}
279			}
280			close(fd);
281
282			if ((rtm->rtm_addrs & (RTA_DST|RTA_GATEWAY)) ==
283			    (RTA_DST|RTA_GATEWAY)) {
284				np = if_indextoname(rtm->rtm_index, ifname);
285				if (np == NULL)
286					return -1;
287			}
288		}
289
290		if (getifaddrs(&ifap) != 0)
291			return -1;
292
293		switch (af) {
294		default:
295		case AF_INET:
296			for (ifa = ifap; ifa; ifa = ifa->ifa_next)
297				if (!strcmp(ifa->ifa_name, np) &&
298				    ifa->ifa_addr != NULL &&
299				    ifa->ifa_addr->sa_family == AF_INET)
300					break;
301			break;
302		case AF_INET6:
303			for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
304				if (!strcmp(ifa->ifa_name, np) &&
305				    ifa->ifa_addr != NULL &&
306				    ifa->ifa_addr->sa_family == AF_INET6) {
307					if (IN6_IS_ADDR_LINKLOCAL(
308					    &((struct sockaddr_in6 *)
309					    ifa->ifa_addr)->sin6_addr) &&
310					    llifa == NULL)
311						llifa = ifa;
312					else
313						break;
314				}
315			}
316			if (ifa == NULL) {
317				ifa = llifa;
318			}
319			break;
320		}
321
322		if (ifa) {
323			if (netmask)
324				memcpy(&tmp_sas, ifa->ifa_netmask,
325				    SA_LEN(ifa->ifa_netmask));
326			else
327				memcpy(&tmp_sas, ifa->ifa_addr,
328				    SA_LEN(ifa->ifa_addr));
329			freeifaddrs(ifap);
330		} else {
331			freeifaddrs(ifap);
332			return -1;
333		}
334	} else {
335		memcpy(&tmp_sas, ai->ai_addr, SA_LEN(ai->ai_addr));
336		freeaddrinfo(ai);
337	}
338
339	*sa = malloc(SA_LEN((struct sockaddr *)&tmp_sas));
340	if (!*sa)
341		return -1;
342
343	memcpy(*sa, &tmp_sas, SA_LEN((struct sockaddr *)&tmp_sas));
344	return 0;
345}
346
347/*
348 * Convert a sockaddr to text. With zflag non-zero fill out with zeroes,
349 * i.e 10.0.0.10 --> "010.000.000.010"
350 */
351int
352sockaddr2text(struct sockaddr *sa, char **address, int zflag)
353{
354	char	buf[NI_MAXHOST], *token, *bstart, *ep;
355	int	addrlen, i, j;
356	long	val;
357
358	if (getnameinfo(sa, SA_LEN(sa), buf, sizeof buf, 0, 0,
359			allow_name_lookups ? 0 : NI_NUMERICHOST))
360		return -1;
361
362	if (zflag == 0) {
363		*address = strdup(buf);
364		if (!*address)
365			return -1;
366	} else
367		switch (sa->sa_family) {
368		case AF_INET:
369			addrlen = sizeof "000.000.000.000";
370			*address = malloc(addrlen);
371			if (!*address)
372				return -1;
373			buf[addrlen] = '\0';
374			bstart = buf;
375			**address = '\0';
376			while ((token = strsep(&bstart, ".")) != NULL) {
377				if (strlen(*address) > 12) {
378					free(*address);
379					return -1;
380				}
381				val = strtol(token, &ep, 10);
382				if (ep == token || val < (long)0 ||
383				    val > (long)UCHAR_MAX) {
384					free(*address);
385					return -1;
386				}
387				snprintf(*address + strlen(*address),
388				    addrlen - strlen(*address), "%03ld", val);
389				if (bstart)
390					strlcat(*address, ".", addrlen);
391			}
392			break;
393
394		case AF_INET6:
395			/*
396			 * XXX In the algorithm below there are some magic
397			 * numbers we probably could give explaining names.
398			 */
399			addrlen =
400			    sizeof "0000:0000:0000:0000:0000:0000:0000:0000";
401			*address = malloc(addrlen);
402			if (!*address)
403				return -1;
404
405			for (i = 0, j = 0; i < 8; i++) {
406				snprintf((*address) + j, addrlen - j,
407				    "%02x%02x",
408				    ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[2*i],
409				    ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[2*i + 1]);
410				j += 4;
411				(*address)[j] =
412				    (j < (addrlen - 1)) ? ':' : '\0';
413				j++;
414			}
415			break;
416
417		default:
418			*address = strdup("<error>");
419			if (!*address)
420				return -1;
421		}
422
423	return 0;
424}
425
426/*
427 * sockaddr_addrlen and sockaddr_addrdata return the relevant sockaddr info
428 * depending on address family.  Useful to keep other code shorter(/clearer?).
429 */
430int
431sockaddr_addrlen(struct sockaddr *sa)
432{
433	switch (sa->sa_family) {
434	case AF_INET6:
435		return sizeof((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
436	case AF_INET:
437		return sizeof((struct sockaddr_in *)sa)->sin_addr.s_addr;
438	default:
439		log_print("sockaddr_addrlen: unsupported protocol family %d",
440		    sa->sa_family);
441		return 0;
442	}
443}
444
445u_int8_t *
446sockaddr_addrdata(struct sockaddr *sa)
447{
448	switch (sa->sa_family) {
449	case AF_INET6:
450		return (u_int8_t *)&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
451	case AF_INET:
452		return (u_int8_t *)&((struct sockaddr_in *)sa)->sin_addr.s_addr;
453	default:
454		log_print("sockaddr_addrdata: unsupported protocol family %d",
455		    sa->sa_family);
456		return 0;
457	}
458}
459
460in_port_t
461sockaddr_port(struct sockaddr *sa)
462{
463	switch (sa->sa_family) {
464	case AF_INET6:
465		return ((struct sockaddr_in6 *)sa)->sin6_port;
466	case AF_INET:
467		return ((struct sockaddr_in *)sa)->sin_port;
468	default:
469		log_print("sockaddr_port: unsupported protocol family %d",
470		    sa->sa_family);
471		return 0;
472	}
473}
474
475/* Utility function used to set the port of a sockaddr.  */
476void
477sockaddr_set_port(struct sockaddr *sa, in_port_t port)
478{
479	switch (sa->sa_family) {
480	case AF_INET:
481		((struct sockaddr_in *)sa)->sin_port = htons (port);
482		break;
483
484	case AF_INET6:
485		((struct sockaddr_in6 *)sa)->sin6_port = htons (port);
486		break;
487	}
488}
489
490/*
491 * Convert network address to text. The network address does not need
492 * to be properly aligned.
493 */
494void
495util_ntoa(char **buf, int af, u_int8_t *addr)
496{
497	struct sockaddr_storage from;
498	struct sockaddr *sfrom = (struct sockaddr *) & from;
499	socklen_t	fromlen = sizeof from;
500
501	bzero(&from, fromlen);
502	sfrom->sa_family = af;
503
504	switch (af) {
505	case AF_INET:
506		sfrom->sa_len = sizeof(struct sockaddr_in);
507		break;
508	case AF_INET6:
509		sfrom->sa_len = sizeof(struct sockaddr_in6);
510		break;
511	}
512
513	memcpy(sockaddr_addrdata(sfrom), addr, sockaddr_addrlen(sfrom));
514
515	if (sockaddr2text(sfrom, buf, 0)) {
516		log_print("util_ntoa: could not make printable address out "
517		    "of sockaddr %p", sfrom);
518		*buf = 0;
519	}
520}
521
522/*
523 * Perform sanity check on files containing secret information.
524 * Returns -1 on failure, 0 otherwise.
525 * Also, if FILE_SIZE is a not a null pointer, store file size here.
526 */
527
528int
529check_file_secrecy_fd(int fd, char *name, size_t *file_size)
530{
531	struct stat st;
532
533	if (fstat(fd, &st) == -1) {
534		log_error("check_file_secrecy: stat (\"%s\") failed", name);
535		return -1;
536	}
537	if (st.st_uid != 0 && st.st_uid != getuid()) {
538		log_print("check_file_secrecy_fd: "
539		    "not loading %s - file owner is not process user", name);
540		errno = EPERM;
541		return -1;
542	}
543	if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
544		log_print("check_file_secrecy_fd: not loading %s - too open "
545		    "permissions", name);
546		errno = EPERM;
547		return -1;
548	}
549	if (file_size)
550		*file_size = (size_t)st.st_size;
551
552	return 0;
553}
554
555/* Calculate timeout.  Returns -1 on error. */
556long
557get_timeout(struct timespec *timeout)
558{
559	struct timespec	now, result;
560
561	if (clock_gettime(CLOCK_MONOTONIC, &now) == -1)
562		return -1;
563	timespecsub(timeout, &now, &result);
564	return result.tv_sec;
565}
566
567int
568expand_string(char *label, size_t len, const char *srch, const char *repl)
569{
570	char *tmp;
571	char *p, *q;
572
573	if ((tmp = calloc(1, len)) == NULL) {
574		log_error("expand_string: calloc");
575		return (-1);
576	}
577	p = q = label;
578	while ((q = strstr(p, srch)) != NULL) {
579		*q = '\0';
580		if ((strlcat(tmp, p, len) >= len) ||
581		    (strlcat(tmp, repl, len) >= len)) {
582			log_print("expand_string: string too long");
583			return (-1);
584		}
585		q += strlen(srch);
586		p = q;
587	}
588	if (strlcat(tmp, p, len) >= len) {
589		log_print("expand_string: string too long");
590		return (-1);
591	}
592	strlcpy(label, tmp, len);	/* always fits */
593	free(tmp);
594
595	return (0);
596}
597