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 */
58 int 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 */
64 u_int16_t
decode_16(u_int8_t * cp)65 decode_16(u_int8_t *cp)
66 {
67 return cp[0] << 8 | cp[1];
68 }
69
70 u_int32_t
decode_32(u_int8_t * cp)71 decode_32(u_int8_t *cp)
72 {
73 return cp[0] << 24 | cp[1] << 16 | cp[2] << 8 | cp[3];
74 }
75
76 void
encode_16(u_int8_t * cp,u_int16_t x)77 encode_16(u_int8_t *cp, u_int16_t x)
78 {
79 *cp++ = x >> 8;
80 *cp = x & 0xff;
81 }
82
83 void
encode_32(u_int8_t * cp,u_int32_t x)84 encode_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. */
93 int
zero_test(const u_int8_t * p,size_t sz)94 zero_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
102 static __inline int
hex2nibble(char c)103 hex2nibble(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 */
118 int
hex2raw(char * s,u_int8_t * buf,size_t sz)119 hex2raw(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 */
150 char *
raw2hex(u_int8_t * buf,size_t sz)151 raw2hex(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
168 in_port_t
text2port(char * port_str)169 text2port(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
191 int
text2sockaddr(char * address,char * port,struct sockaddr ** sa,sa_family_t af,int netmask)192 text2sockaddr(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 */
351 int
sockaddr2text(struct sockaddr * sa,char ** address,int zflag)352 sockaddr2text(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 */
430 int
sockaddr_addrlen(struct sockaddr * sa)431 sockaddr_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
445 u_int8_t *
sockaddr_addrdata(struct sockaddr * sa)446 sockaddr_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
460 in_port_t
sockaddr_port(struct sockaddr * sa)461 sockaddr_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. */
476 void
sockaddr_set_port(struct sockaddr * sa,in_port_t port)477 sockaddr_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 */
494 void
util_ntoa(char ** buf,int af,u_int8_t * addr)495 util_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
528 int
check_file_secrecy_fd(int fd,char * name,size_t * file_size)529 check_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. */
556 long
get_timeout(struct timespec * timeout)557 get_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
567 int
expand_string(char * label,size_t len,const char * srch,const char * repl)568 expand_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