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 65 decode_16(u_int8_t *cp) 66 { 67 return cp[0] << 8 | cp[1]; 68 } 69 70 u_int32_t 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 77 encode_16(u_int8_t *cp, u_int16_t x) 78 { 79 *cp++ = x >> 8; 80 *cp = x & 0xff; 81 } 82 83 void 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 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 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 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 * 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 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 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 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 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 * 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 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 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 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 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 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 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