xref: /openbsd/sbin/isakmpd/util.c (revision 898184e3)
1 /* $OpenBSD: util.c,v 1.65 2009/06/25 15:40:55 claudio 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 "sysdep.h"
52 #include "transport.h"
53 #include "util.h"
54 
55 /*
56  * Set if -N is given, allowing name lookups to be done, possibly stalling
57  * the daemon for quite a while.
58  */
59 int	allow_name_lookups = 0;
60 
61 #if defined(INSECURE_RAND)
62 /*
63  * This is set to true in case of regression-test mode, when it will
64  * cause predictable random numbers be generated.
65  */
66 int	regrand = 0;
67 #endif
68 
69 /*
70  * XXX These might be turned into inlines or macros, maybe even
71  * machine-dependent ones, for performance reasons.
72  */
73 u_int16_t
74 decode_16(u_int8_t *cp)
75 {
76 	return cp[0] << 8 | cp[1];
77 }
78 
79 u_int32_t
80 decode_32(u_int8_t *cp)
81 {
82 	return cp[0] << 24 | cp[1] << 16 | cp[2] << 8 | cp[3];
83 }
84 
85 void
86 encode_16(u_int8_t *cp, u_int16_t x)
87 {
88 	*cp++ = x >> 8;
89 	*cp = x & 0xff;
90 }
91 
92 void
93 encode_32(u_int8_t *cp, u_int32_t x)
94 {
95 	*cp++ = x >> 24;
96 	*cp++ = (x >> 16) & 0xff;
97 	*cp++ = (x >> 8) & 0xff;
98 	*cp = x & 0xff;
99 }
100 
101 /* Check a buffer for all zeroes.  */
102 int
103 zero_test(const u_int8_t *p, size_t sz)
104 {
105 	while (sz-- > 0)
106 		if (*p++ != 0)
107 			return 0;
108 	return 1;
109 }
110 
111 /*
112  * Generate 32 bits of random data.  If compiled with INSECURE_RAND
113  * and -r option is specified, then return deterministic data.
114  */
115 u_int32_t
116 rand_32(void)
117 {
118 #if !defined(INSECURE_RAND)
119 	return arc4random();
120 #else
121 	if (regrand)
122 		return random();
123 	else
124 		return arc4random();
125 #endif
126 }
127 
128 /*
129  * Generate a random data, len bytes long.
130  */
131 u_int8_t *
132 getrandom(u_int8_t *buf, size_t len)
133 {
134 	u_int32_t	tmp = 0;
135 	size_t		i;
136 
137 	for (i = 0; i < len; i++) {
138 		if (i % sizeof tmp == 0)
139 			tmp = rand_32();
140 
141 		buf[i] = tmp & 0xff;
142 		tmp >>= 8;
143 	}
144 
145 	return buf;
146 }
147 
148 static __inline int
149 hex2nibble(char c)
150 {
151 	if (c >= '0' && c <= '9')
152 		return c - '0';
153 	if (c >= 'a' && c <= 'f')
154 		return c - 'a' + 10;
155 	if (c >= 'A' && c <= 'F')
156 		return c - 'A' + 10;
157 	return -1;
158 }
159 
160 /*
161  * Convert hexadecimal string in S to raw binary buffer at BUF sized SZ
162  * bytes.  Return 0 if everything is OK, -1 otherwise.
163  */
164 int
165 hex2raw(char *s, u_int8_t *buf, size_t sz)
166 {
167 	u_int8_t *bp;
168 	char	*p;
169 	int	tmp;
170 
171 	if (strlen(s) > sz * 2)
172 		return -1;
173 	for (p = s + strlen(s) - 1, bp = &buf[sz - 1]; bp >= buf; bp--) {
174 		*bp = 0;
175 		if (p >= s) {
176 			tmp = hex2nibble(*p--);
177 			if (tmp == -1)
178 				return -1;
179 			*bp = tmp;
180 		}
181 		if (p >= s) {
182 			tmp = hex2nibble(*p--);
183 			if (tmp == -1)
184 				return -1;
185 			*bp |= tmp << 4;
186 		}
187 	}
188 	return 0;
189 }
190 
191 /*
192  * Convert raw binary buffer to a newly allocated hexadecimal string.  Returns
193  * NULL if an error occurred.  It is the caller's responsibility to free the
194  * returned string.
195  */
196 char *
197 raw2hex(u_int8_t *buf, size_t sz)
198 {
199 	char *s;
200 	size_t i;
201 
202 	if ((s = (char *)malloc(sz * 2 + 1)) == NULL) {
203 		log_error("raw2hex: malloc (%lu) failed", (unsigned long)sz * 2 + 1);
204 		return NULL;
205 	}
206 
207 	for (i = 0; i < sz; i++)
208 		snprintf(s + (2 * i), 2 * (sz - i) + 1, "%02x", buf[i]);
209 
210 	s[sz * 2] = '\0';
211 	return s;
212 }
213 
214 in_port_t
215 text2port(char *port_str)
216 {
217 	char           *port_str_end;
218 	long            port_long;
219 	struct servent *service;
220 
221 	port_long = strtol(port_str, &port_str_end, 0);
222 	if (port_str == port_str_end) {
223 		service = getservbyname(port_str, "udp");
224 		if (!service) {
225 			log_print("text2port: service \"%s\" unknown",
226 			    port_str);
227 			return 0;
228 		}
229 		return ntohs(service->s_port);
230 	} else if (port_long < 1 || port_long > (long)USHRT_MAX) {
231 		log_print("text2port: port %ld out of range", port_long);
232 		return 0;
233 	}
234 	return port_long;
235 }
236 
237 int
238 text2sockaddr(char *address, char *port, struct sockaddr **sa, sa_family_t af,
239     int netmask)
240 {
241 	struct addrinfo *ai, hints;
242 	struct sockaddr_storage tmp_sas;
243 	struct ifaddrs *ifap, *ifa = NULL, *llifa = NULL;
244 	char *np = address;
245 	char ifname[IFNAMSIZ];
246 	u_char buf[BUFSIZ];
247 	struct rt_msghdr *rtm;
248 	struct sockaddr *sa2;
249 	struct sockaddr_in *sin;
250 	struct sockaddr_in6 *sin6;
251 	int fd = 0, seq, len, b;
252 	pid_t pid;
253 
254 	bzero(&hints, sizeof hints);
255 	if (!allow_name_lookups)
256 		hints.ai_flags = AI_NUMERICHOST;
257 	hints.ai_family = PF_UNSPEC;
258 	hints.ai_socktype = SOCK_DGRAM;
259 	hints.ai_protocol = IPPROTO_UDP;
260 
261 	if (getaddrinfo(address, port, &hints, &ai)) {
262 		/*
263 		 * If the 'default' keyword is used, do a route lookup for
264 		 * the default route, and use the interface associated with
265 		 * it to select a source address.
266 		 */
267 		if (!strcmp(address, "default")) {
268 			fd = socket(PF_ROUTE, SOCK_RAW, af);
269 
270 			bzero(buf, sizeof(buf));
271 
272 			rtm = (struct rt_msghdr *)buf;
273 			rtm->rtm_version = RTM_VERSION;
274 			rtm->rtm_type = RTM_GET;
275 			rtm->rtm_flags = RTF_UP;
276 			rtm->rtm_addrs = RTA_DST;
277 			rtm->rtm_seq = seq = arc4random();
278 
279 			/* default destination */
280 			sa2 = (struct sockaddr *)((char *)rtm + rtm->rtm_hdrlen);
281 			switch (af) {
282 			case AF_INET: {
283 				sin = (struct sockaddr_in *)sa2;
284 				sin->sin_len = sizeof(*sin);
285 				sin->sin_family = af;
286 				break;
287 			}
288 			case AF_INET6: {
289 				sin6 = (struct sockaddr_in6 *)sa2;
290 				sin6->sin6_len = sizeof(*sin6);
291 				sin6->sin6_family = af;
292 				break;
293 			}
294 			default:
295 				close(fd);
296 				return -1;
297 			}
298 			rtm->rtm_addrs |= RTA_NETMASK|RTA_IFP|RTA_IFA;
299 			rtm->rtm_msglen = sizeof(*rtm) + sizeof(*sa2);
300 
301 			if ((b = write(fd, buf, rtm->rtm_msglen)) < 0) {
302 				close(fd);
303 				return -1;
304 			}
305 
306 			pid = getpid();
307 
308 			while ((len = read(fd, buf, sizeof(buf))) > 0) {
309 				if (len < sizeof(*rtm)) {
310 					close(fd);
311 					return -1;
312 				}
313 				if (rtm->rtm_version != RTM_VERSION)
314 					continue;
315 
316 				if (rtm->rtm_type == RTM_GET &&
317 				    rtm->rtm_pid == pid &&
318 				    rtm->rtm_seq == seq) {
319 					if (rtm->rtm_errno) {
320 						close(fd);
321 						return -1;
322 					}
323 					break;
324 				}
325 			}
326 			close(fd);
327 
328 			if ((rtm->rtm_addrs & (RTA_DST|RTA_GATEWAY)) ==
329 			    (RTA_DST|RTA_GATEWAY)) {
330 				np = if_indextoname(rtm->rtm_index, ifname);
331 				if (np == NULL)
332 					return -1;
333 			}
334 		}
335 
336 		if (getifaddrs(&ifap) != 0)
337 			return -1;
338 
339 		switch (af) {
340 		default:
341 		case AF_INET:
342 			for (ifa = ifap; ifa; ifa = ifa->ifa_next)
343 				if (!strcmp(ifa->ifa_name, np) &&
344 				    ifa->ifa_addr != NULL &&
345 				    ifa->ifa_addr->sa_family == AF_INET)
346 					break;
347 			break;
348 		case AF_INET6:
349 			for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
350 				if (!strcmp(ifa->ifa_name, np) &&
351 				    ifa->ifa_addr != NULL &&
352 				    ifa->ifa_addr->sa_family == AF_INET6) {
353 					if (IN6_IS_ADDR_LINKLOCAL(
354 					    &((struct sockaddr_in6 *)
355 					    ifa->ifa_addr)->sin6_addr) &&
356 					    llifa == NULL)
357 						llifa = ifa;
358 					else
359 						break;
360 				}
361 			}
362 			if (ifa == NULL) {
363 				ifa = llifa;
364 			}
365 			break;
366 		}
367 
368 		if (ifa) {
369 			if (netmask)
370 				memcpy(&tmp_sas, ifa->ifa_netmask,
371 				    SA_LEN(ifa->ifa_netmask));
372 			else
373 				memcpy(&tmp_sas, ifa->ifa_addr,
374 				    SA_LEN(ifa->ifa_addr));
375 			freeifaddrs(ifap);
376 		} else {
377 			freeifaddrs(ifap);
378 			return -1;
379 		}
380 	} else {
381 		memcpy(&tmp_sas, ai->ai_addr, SA_LEN(ai->ai_addr));
382 		freeaddrinfo(ai);
383 	}
384 
385 	*sa = malloc(SA_LEN((struct sockaddr *)&tmp_sas));
386 	if (!*sa)
387 		return -1;
388 
389 	memcpy(*sa, &tmp_sas, SA_LEN((struct sockaddr *)&tmp_sas));
390 	return 0;
391 }
392 
393 /*
394  * Convert a sockaddr to text. With zflag non-zero fill out with zeroes,
395  * i.e 10.0.0.10 --> "010.000.000.010"
396  */
397 int
398 sockaddr2text(struct sockaddr *sa, char **address, int zflag)
399 {
400 	char	buf[NI_MAXHOST], *token, *bstart, *ep;
401 	int	addrlen, i, j;
402 	long	val;
403 
404 	if (getnameinfo(sa, SA_LEN(sa), buf, sizeof buf, 0, 0,
405 			allow_name_lookups ? 0 : NI_NUMERICHOST))
406 		return -1;
407 
408 	if (zflag == 0) {
409 		*address = strdup(buf);
410 		if (!*address)
411 			return -1;
412 	} else
413 		switch (sa->sa_family) {
414 		case AF_INET:
415 			addrlen = sizeof "000.000.000.000";
416 			*address = malloc(addrlen);
417 			if (!*address)
418 				return -1;
419 			buf[addrlen] = '\0';
420 			bstart = buf;
421 			**address = '\0';
422 			while ((token = strsep(&bstart, ".")) != NULL) {
423 				if (strlen(*address) > 12) {
424 					free(*address);
425 					return -1;
426 				}
427 				val = strtol(token, &ep, 10);
428 				if (ep == token || val < (long)0 ||
429 				    val > (long)UCHAR_MAX) {
430 					free(*address);
431 					return -1;
432 				}
433 				snprintf(*address + strlen(*address),
434 				    addrlen - strlen(*address), "%03ld", val);
435 				if (bstart)
436 					strlcat(*address, ".", addrlen);
437 			}
438 			break;
439 
440 		case AF_INET6:
441 			/*
442 			 * XXX In the algorithm below there are some magic
443 			 * numbers we probably could give explaining names.
444 			 */
445 			addrlen =
446 			    sizeof "0000:0000:0000:0000:0000:0000:0000:0000";
447 			*address = malloc(addrlen);
448 			if (!*address)
449 				return -1;
450 
451 			for (i = 0, j = 0; i < 8; i++) {
452 				snprintf((*address) + j, addrlen - j,
453 				    "%02x%02x",
454 				    ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[2*i],
455 				    ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[2*i + 1]);
456 				j += 4;
457 				(*address)[j] =
458 				    (j < (addrlen - 1)) ? ':' : '\0';
459 				j++;
460 			}
461 			break;
462 
463 		default:
464 			*address = strdup("<error>");
465 			if (!*address)
466 				return -1;
467 		}
468 
469 	return 0;
470 }
471 
472 /*
473  * sockaddr_addrlen and sockaddr_addrdata return the relevant sockaddr info
474  * depending on address family.  Useful to keep other code shorter(/clearer?).
475  */
476 int
477 sockaddr_addrlen(struct sockaddr *sa)
478 {
479 	switch (sa->sa_family) {
480 	case AF_INET6:
481 		return sizeof((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
482 	case AF_INET:
483 		return sizeof((struct sockaddr_in *)sa)->sin_addr.s_addr;
484 	default:
485 		log_print("sockaddr_addrlen: unsupported protocol family %d",
486 		    sa->sa_family);
487 		return 0;
488 	}
489 }
490 
491 u_int8_t *
492 sockaddr_addrdata(struct sockaddr *sa)
493 {
494 	switch (sa->sa_family) {
495 	case AF_INET6:
496 		return (u_int8_t *)&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
497 	case AF_INET:
498 		return (u_int8_t *)&((struct sockaddr_in *)sa)->sin_addr.s_addr;
499 	default:
500 		log_print("sockaddr_addrdata: unsupported protocol family %d",
501 		    sa->sa_family);
502 		return 0;
503 	}
504 }
505 
506 in_port_t
507 sockaddr_port(struct sockaddr *sa)
508 {
509 	switch (sa->sa_family) {
510 	case AF_INET6:
511 		return ((struct sockaddr_in6 *)sa)->sin6_port;
512 	case AF_INET:
513 		return ((struct sockaddr_in *)sa)->sin_port;
514 	default:
515 		log_print("sockaddr_port: unsupported protocol family %d",
516 		    sa->sa_family);
517 		return 0;
518 	}
519 }
520 
521 /* Utility function used to set the port of a sockaddr.  */
522 void
523 sockaddr_set_port(struct sockaddr *sa, in_port_t port)
524 {
525 	switch (sa->sa_family) {
526 	case AF_INET:
527 		((struct sockaddr_in *)sa)->sin_port = htons (port);
528 		break;
529 
530 	case AF_INET6:
531 		((struct sockaddr_in6 *)sa)->sin6_port = htons (port);
532 		break;
533 	}
534 }
535 
536 /*
537  * Convert network address to text. The network address does not need
538  * to be properly aligned.
539  */
540 void
541 util_ntoa(char **buf, int af, u_int8_t *addr)
542 {
543 	struct sockaddr_storage from;
544 	struct sockaddr *sfrom = (struct sockaddr *) & from;
545 	socklen_t	fromlen = sizeof from;
546 
547 	bzero(&from, fromlen);
548 	sfrom->sa_family = af;
549 
550 	switch (af) {
551 	case AF_INET:
552 		sfrom->sa_len = sizeof(struct sockaddr_in);
553 		break;
554 	case AF_INET6:
555 		sfrom->sa_len = sizeof(struct sockaddr_in6);
556 		break;
557 	}
558 
559 	memcpy(sockaddr_addrdata(sfrom), addr, sockaddr_addrlen(sfrom));
560 
561 	if (sockaddr2text(sfrom, buf, 0)) {
562 		log_print("util_ntoa: could not make printable address out "
563 		    "of sockaddr %p", sfrom);
564 		*buf = 0;
565 	}
566 }
567 
568 /*
569  * Perform sanity check on files containing secret information.
570  * Returns -1 on failure, 0 otherwise.
571  * Also, if FILE_SIZE is a not a null pointer, store file size here.
572  */
573 
574 int
575 check_file_secrecy_fd(int fd, char *name, size_t *file_size)
576 {
577 	struct stat st;
578 
579 	if (fstat(fd, &st) == -1) {
580 		log_error("check_file_secrecy: stat (\"%s\") failed", name);
581 		return -1;
582 	}
583 	if (st.st_uid != 0 && st.st_uid != getuid()) {
584 		log_print("check_file_secrecy_fd: "
585 		    "not loading %s - file owner is not process user", name);
586 		errno = EPERM;
587 		return -1;
588 	}
589 	if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
590 		log_print("check_file_secrecy_fd: not loading %s - too open "
591 		    "permissions", name);
592 		errno = EPERM;
593 		return -1;
594 	}
595 	if (file_size)
596 		*file_size = (size_t)st.st_size;
597 
598 	return 0;
599 }
600 
601 /* Calculate timeout.  Returns -1 on error. */
602 long
603 get_timeout(struct timeval *timeout)
604 {
605 	struct timeval	now, result;
606 
607 	if (gettimeofday(&now, NULL) < 0)
608 		return -1;
609 
610 	timersub(timeout, &now, &result);
611 
612 	return result.tv_sec;
613 }
614 
615 
616 /* Special for compiling with Boehms GC. See Makefile and sysdep.h  */
617 #if defined (USE_BOEHM_GC)
618 char *
619 gc_strdup(const char *x)
620 {
621 	char *strcpy(char *,const char *);
622 	char *y = malloc(strlen(x) + 1);
623 	return strcpy(y,x);
624 }
625 #endif
626 
627 int
628 expand_string(char *label, size_t len, const char *srch, const char *repl)
629 {
630 	char *tmp;
631 	char *p, *q;
632 
633 	if ((tmp = calloc(1, len)) == NULL) {
634 		log_error("expand_string: calloc");
635 		return (-1);
636 	}
637 	p = q = label;
638 	while ((q = strstr(p, srch)) != NULL) {
639 		*q = '\0';
640 		if ((strlcat(tmp, p, len) >= len) ||
641 		    (strlcat(tmp, repl, len) >= len)) {
642 			log_print("expand_string: string too long");
643 			return (-1);
644 		}
645 		q += strlen(srch);
646 		p = q;
647 	}
648 	if (strlcat(tmp, p, len) >= len) {
649 		log_print("expand_string: string too long");
650 		return (-1);
651 	}
652 	strlcpy(label, tmp, len);	/* always fits */
653 	free(tmp);
654 
655 	return (0);
656 }
657