1 /* $OpenBSD: misc.c,v 1.177 2022/08/11 01:56:51 djm Exp $ */ 2 /* 3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2005-2020 Damien Miller. All rights reserved. 5 * Copyright (c) 2004 Henning Brauer <henning@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 21 #include "includes.h" 22 23 #include <sys/types.h> 24 #include <sys/ioctl.h> 25 #include <sys/socket.h> 26 #include <sys/stat.h> 27 #include <sys/time.h> 28 #include <sys/wait.h> 29 #include <sys/un.h> 30 31 #include <limits.h> 32 #ifdef HAVE_LIBGEN_H 33 # include <libgen.h> 34 #endif 35 #ifdef HAVE_POLL_H 36 #include <poll.h> 37 #endif 38 #include <signal.h> 39 #include <stdarg.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <time.h> 44 #include <unistd.h> 45 46 #include <netinet/in.h> 47 #include <netinet/in_systm.h> 48 #include <netinet/ip.h> 49 #include <netinet/tcp.h> 50 #include <arpa/inet.h> 51 52 #include <ctype.h> 53 #include <errno.h> 54 #include <fcntl.h> 55 #include <netdb.h> 56 #ifdef HAVE_PATHS_H 57 # include <paths.h> 58 #include <pwd.h> 59 #include <grp.h> 60 #endif 61 #ifdef SSH_TUN_OPENBSD 62 #include <net/if.h> 63 #endif 64 65 #include "xmalloc.h" 66 #include "misc.h" 67 #include "log.h" 68 #include "ssh.h" 69 #include "sshbuf.h" 70 #include "ssherr.h" 71 #include "platform.h" 72 73 /* remove newline at end of string */ 74 char * 75 chop(char *s) 76 { 77 char *t = s; 78 while (*t) { 79 if (*t == '\n' || *t == '\r') { 80 *t = '\0'; 81 return s; 82 } 83 t++; 84 } 85 return s; 86 87 } 88 89 /* remove whitespace from end of string */ 90 void 91 rtrim(char *s) 92 { 93 size_t i; 94 95 if ((i = strlen(s)) == 0) 96 return; 97 for (i--; i > 0; i--) { 98 if (isspace((int)s[i])) 99 s[i] = '\0'; 100 } 101 } 102 103 /* set/unset filedescriptor to non-blocking */ 104 int 105 set_nonblock(int fd) 106 { 107 int val; 108 109 val = fcntl(fd, F_GETFL); 110 if (val == -1) { 111 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); 112 return (-1); 113 } 114 if (val & O_NONBLOCK) { 115 debug3("fd %d is O_NONBLOCK", fd); 116 return (0); 117 } 118 debug2("fd %d setting O_NONBLOCK", fd); 119 val |= O_NONBLOCK; 120 if (fcntl(fd, F_SETFL, val) == -1) { 121 debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, 122 strerror(errno)); 123 return (-1); 124 } 125 return (0); 126 } 127 128 int 129 unset_nonblock(int fd) 130 { 131 int val; 132 133 val = fcntl(fd, F_GETFL); 134 if (val == -1) { 135 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); 136 return (-1); 137 } 138 if (!(val & O_NONBLOCK)) { 139 debug3("fd %d is not O_NONBLOCK", fd); 140 return (0); 141 } 142 debug("fd %d clearing O_NONBLOCK", fd); 143 val &= ~O_NONBLOCK; 144 if (fcntl(fd, F_SETFL, val) == -1) { 145 debug("fcntl(%d, F_SETFL, ~O_NONBLOCK): %s", 146 fd, strerror(errno)); 147 return (-1); 148 } 149 return (0); 150 } 151 152 const char * 153 ssh_gai_strerror(int gaierr) 154 { 155 if (gaierr == EAI_SYSTEM && errno != 0) 156 return strerror(errno); 157 return gai_strerror(gaierr); 158 } 159 160 /* disable nagle on socket */ 161 void 162 set_nodelay(int fd) 163 { 164 int opt; 165 socklen_t optlen; 166 167 optlen = sizeof opt; 168 if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) { 169 debug("getsockopt TCP_NODELAY: %.100s", strerror(errno)); 170 return; 171 } 172 if (opt == 1) { 173 debug2("fd %d is TCP_NODELAY", fd); 174 return; 175 } 176 opt = 1; 177 debug2("fd %d setting TCP_NODELAY", fd); 178 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1) 179 error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); 180 } 181 182 /* Allow local port reuse in TIME_WAIT */ 183 int 184 set_reuseaddr(int fd) 185 { 186 int on = 1; 187 188 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { 189 error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno)); 190 return -1; 191 } 192 return 0; 193 } 194 195 /* Get/set routing domain */ 196 char * 197 get_rdomain(int fd) 198 { 199 #if defined(HAVE_SYS_GET_RDOMAIN) 200 return sys_get_rdomain(fd); 201 #elif defined(__OpenBSD__) 202 int rtable; 203 char *ret; 204 socklen_t len = sizeof(rtable); 205 206 if (getsockopt(fd, SOL_SOCKET, SO_RTABLE, &rtable, &len) == -1) { 207 error("Failed to get routing domain for fd %d: %s", 208 fd, strerror(errno)); 209 return NULL; 210 } 211 xasprintf(&ret, "%d", rtable); 212 return ret; 213 #else /* defined(__OpenBSD__) */ 214 return NULL; 215 #endif 216 } 217 218 int 219 set_rdomain(int fd, const char *name) 220 { 221 #if defined(HAVE_SYS_SET_RDOMAIN) 222 return sys_set_rdomain(fd, name); 223 #elif defined(__OpenBSD__) 224 int rtable; 225 const char *errstr; 226 227 if (name == NULL) 228 return 0; /* default table */ 229 230 rtable = (int)strtonum(name, 0, 255, &errstr); 231 if (errstr != NULL) { 232 /* Shouldn't happen */ 233 error("Invalid routing domain \"%s\": %s", name, errstr); 234 return -1; 235 } 236 if (setsockopt(fd, SOL_SOCKET, SO_RTABLE, 237 &rtable, sizeof(rtable)) == -1) { 238 error("Failed to set routing domain %d on fd %d: %s", 239 rtable, fd, strerror(errno)); 240 return -1; 241 } 242 return 0; 243 #else /* defined(__OpenBSD__) */ 244 error("Setting routing domain is not supported on this platform"); 245 return -1; 246 #endif 247 } 248 249 int 250 get_sock_af(int fd) 251 { 252 struct sockaddr_storage to; 253 socklen_t tolen = sizeof(to); 254 255 memset(&to, 0, sizeof(to)); 256 if (getsockname(fd, (struct sockaddr *)&to, &tolen) == -1) 257 return -1; 258 #ifdef IPV4_IN_IPV6 259 if (to.ss_family == AF_INET6 && 260 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr)) 261 return AF_INET; 262 #endif 263 return to.ss_family; 264 } 265 266 void 267 set_sock_tos(int fd, int tos) 268 { 269 #ifndef IP_TOS_IS_BROKEN 270 int af; 271 272 switch ((af = get_sock_af(fd))) { 273 case -1: 274 /* assume not a socket */ 275 break; 276 case AF_INET: 277 # ifdef IP_TOS 278 debug3_f("set socket %d IP_TOS 0x%02x", fd, tos); 279 if (setsockopt(fd, IPPROTO_IP, IP_TOS, 280 &tos, sizeof(tos)) == -1) { 281 error("setsockopt socket %d IP_TOS %d: %s:", 282 fd, tos, strerror(errno)); 283 } 284 # endif /* IP_TOS */ 285 break; 286 case AF_INET6: 287 # ifdef IPV6_TCLASS 288 debug3_f("set socket %d IPV6_TCLASS 0x%02x", fd, tos); 289 if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, 290 &tos, sizeof(tos)) == -1) { 291 error("setsockopt socket %d IPV6_TCLASS %d: %.100s:", 292 fd, tos, strerror(errno)); 293 } 294 # endif /* IPV6_TCLASS */ 295 break; 296 default: 297 debug2_f("unsupported socket family %d", af); 298 break; 299 } 300 #endif /* IP_TOS_IS_BROKEN */ 301 } 302 303 /* 304 * Wait up to *timeoutp milliseconds for events on fd. Updates 305 * *timeoutp with time remaining. 306 * Returns 0 if fd ready or -1 on timeout or error (see errno). 307 */ 308 static int 309 waitfd(int fd, int *timeoutp, short events) 310 { 311 struct pollfd pfd; 312 struct timeval t_start; 313 int oerrno, r; 314 315 pfd.fd = fd; 316 pfd.events = events; 317 for (; *timeoutp >= 0;) { 318 monotime_tv(&t_start); 319 r = poll(&pfd, 1, *timeoutp); 320 oerrno = errno; 321 ms_subtract_diff(&t_start, timeoutp); 322 errno = oerrno; 323 if (r > 0) 324 return 0; 325 else if (r == -1 && errno != EAGAIN && errno != EINTR) 326 return -1; 327 else if (r == 0) 328 break; 329 } 330 /* timeout */ 331 errno = ETIMEDOUT; 332 return -1; 333 } 334 335 /* 336 * Wait up to *timeoutp milliseconds for fd to be readable. Updates 337 * *timeoutp with time remaining. 338 * Returns 0 if fd ready or -1 on timeout or error (see errno). 339 */ 340 int 341 waitrfd(int fd, int *timeoutp) { 342 return waitfd(fd, timeoutp, POLLIN); 343 } 344 345 /* 346 * Attempt a non-blocking connect(2) to the specified address, waiting up to 347 * *timeoutp milliseconds for the connection to complete. If the timeout is 348 * <=0, then wait indefinitely. 349 * 350 * Returns 0 on success or -1 on failure. 351 */ 352 int 353 timeout_connect(int sockfd, const struct sockaddr *serv_addr, 354 socklen_t addrlen, int *timeoutp) 355 { 356 int optval = 0; 357 socklen_t optlen = sizeof(optval); 358 359 /* No timeout: just do a blocking connect() */ 360 if (timeoutp == NULL || *timeoutp <= 0) 361 return connect(sockfd, serv_addr, addrlen); 362 363 set_nonblock(sockfd); 364 for (;;) { 365 if (connect(sockfd, serv_addr, addrlen) == 0) { 366 /* Succeeded already? */ 367 unset_nonblock(sockfd); 368 return 0; 369 } else if (errno == EINTR) 370 continue; 371 else if (errno != EINPROGRESS) 372 return -1; 373 break; 374 } 375 376 if (waitfd(sockfd, timeoutp, POLLIN | POLLOUT) == -1) 377 return -1; 378 379 /* Completed or failed */ 380 if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) { 381 debug("getsockopt: %s", strerror(errno)); 382 return -1; 383 } 384 if (optval != 0) { 385 errno = optval; 386 return -1; 387 } 388 unset_nonblock(sockfd); 389 return 0; 390 } 391 392 /* Characters considered whitespace in strsep calls. */ 393 #define WHITESPACE " \t\r\n" 394 #define QUOTE "\"" 395 396 /* return next token in configuration line */ 397 static char * 398 strdelim_internal(char **s, int split_equals) 399 { 400 char *old; 401 int wspace = 0; 402 403 if (*s == NULL) 404 return NULL; 405 406 old = *s; 407 408 *s = strpbrk(*s, 409 split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); 410 if (*s == NULL) 411 return (old); 412 413 if (*s[0] == '\"') { 414 memmove(*s, *s + 1, strlen(*s)); /* move nul too */ 415 /* Find matching quote */ 416 if ((*s = strpbrk(*s, QUOTE)) == NULL) { 417 return (NULL); /* no matching quote */ 418 } else { 419 *s[0] = '\0'; 420 *s += strspn(*s + 1, WHITESPACE) + 1; 421 return (old); 422 } 423 } 424 425 /* Allow only one '=' to be skipped */ 426 if (split_equals && *s[0] == '=') 427 wspace = 1; 428 *s[0] = '\0'; 429 430 /* Skip any extra whitespace after first token */ 431 *s += strspn(*s + 1, WHITESPACE) + 1; 432 if (split_equals && *s[0] == '=' && !wspace) 433 *s += strspn(*s + 1, WHITESPACE) + 1; 434 435 return (old); 436 } 437 438 /* 439 * Return next token in configuration line; splts on whitespace or a 440 * single '=' character. 441 */ 442 char * 443 strdelim(char **s) 444 { 445 return strdelim_internal(s, 1); 446 } 447 448 /* 449 * Return next token in configuration line; splts on whitespace only. 450 */ 451 char * 452 strdelimw(char **s) 453 { 454 return strdelim_internal(s, 0); 455 } 456 457 struct passwd * 458 pwcopy(struct passwd *pw) 459 { 460 struct passwd *copy = xcalloc(1, sizeof(*copy)); 461 462 copy->pw_name = xstrdup(pw->pw_name); 463 copy->pw_passwd = xstrdup(pw->pw_passwd == NULL ? "*" : pw->pw_passwd); 464 #ifdef HAVE_STRUCT_PASSWD_PW_GECOS 465 copy->pw_gecos = xstrdup(pw->pw_gecos); 466 #endif 467 copy->pw_uid = pw->pw_uid; 468 copy->pw_gid = pw->pw_gid; 469 #ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE 470 copy->pw_expire = pw->pw_expire; 471 #endif 472 #ifdef HAVE_STRUCT_PASSWD_PW_CHANGE 473 copy->pw_change = pw->pw_change; 474 #endif 475 #ifdef HAVE_STRUCT_PASSWD_PW_CLASS 476 copy->pw_class = xstrdup(pw->pw_class); 477 #endif 478 copy->pw_dir = xstrdup(pw->pw_dir); 479 copy->pw_shell = xstrdup(pw->pw_shell); 480 return copy; 481 } 482 483 /* 484 * Convert ASCII string to TCP/IP port number. 485 * Port must be >=0 and <=65535. 486 * Return -1 if invalid. 487 */ 488 int 489 a2port(const char *s) 490 { 491 struct servent *se; 492 long long port; 493 const char *errstr; 494 495 port = strtonum(s, 0, 65535, &errstr); 496 if (errstr == NULL) 497 return (int)port; 498 if ((se = getservbyname(s, "tcp")) != NULL) 499 return ntohs(se->s_port); 500 return -1; 501 } 502 503 int 504 a2tun(const char *s, int *remote) 505 { 506 const char *errstr = NULL; 507 char *sp, *ep; 508 int tun; 509 510 if (remote != NULL) { 511 *remote = SSH_TUNID_ANY; 512 sp = xstrdup(s); 513 if ((ep = strchr(sp, ':')) == NULL) { 514 free(sp); 515 return (a2tun(s, NULL)); 516 } 517 ep[0] = '\0'; ep++; 518 *remote = a2tun(ep, NULL); 519 tun = a2tun(sp, NULL); 520 free(sp); 521 return (*remote == SSH_TUNID_ERR ? *remote : tun); 522 } 523 524 if (strcasecmp(s, "any") == 0) 525 return (SSH_TUNID_ANY); 526 527 tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr); 528 if (errstr != NULL) 529 return (SSH_TUNID_ERR); 530 531 return (tun); 532 } 533 534 #define SECONDS 1 535 #define MINUTES (SECONDS * 60) 536 #define HOURS (MINUTES * 60) 537 #define DAYS (HOURS * 24) 538 #define WEEKS (DAYS * 7) 539 540 /* 541 * Convert a time string into seconds; format is 542 * a sequence of: 543 * time[qualifier] 544 * 545 * Valid time qualifiers are: 546 * <none> seconds 547 * s|S seconds 548 * m|M minutes 549 * h|H hours 550 * d|D days 551 * w|W weeks 552 * 553 * Examples: 554 * 90m 90 minutes 555 * 1h30m 90 minutes 556 * 2d 2 days 557 * 1w 1 week 558 * 559 * Return -1 if time string is invalid. 560 */ 561 int 562 convtime(const char *s) 563 { 564 long total, secs, multiplier; 565 const char *p; 566 char *endp; 567 568 errno = 0; 569 total = 0; 570 p = s; 571 572 if (p == NULL || *p == '\0') 573 return -1; 574 575 while (*p) { 576 secs = strtol(p, &endp, 10); 577 if (p == endp || 578 (errno == ERANGE && (secs == INT_MIN || secs == INT_MAX)) || 579 secs < 0) 580 return -1; 581 582 multiplier = 1; 583 switch (*endp++) { 584 case '\0': 585 endp--; 586 break; 587 case 's': 588 case 'S': 589 break; 590 case 'm': 591 case 'M': 592 multiplier = MINUTES; 593 break; 594 case 'h': 595 case 'H': 596 multiplier = HOURS; 597 break; 598 case 'd': 599 case 'D': 600 multiplier = DAYS; 601 break; 602 case 'w': 603 case 'W': 604 multiplier = WEEKS; 605 break; 606 default: 607 return -1; 608 } 609 if (secs > INT_MAX / multiplier) 610 return -1; 611 secs *= multiplier; 612 if (total > INT_MAX - secs) 613 return -1; 614 total += secs; 615 if (total < 0) 616 return -1; 617 p = endp; 618 } 619 620 return total; 621 } 622 623 #define TF_BUFS 8 624 #define TF_LEN 9 625 626 const char * 627 fmt_timeframe(time_t t) 628 { 629 char *buf; 630 static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */ 631 static int idx = 0; 632 unsigned int sec, min, hrs, day; 633 unsigned long long week; 634 635 buf = tfbuf[idx++]; 636 if (idx == TF_BUFS) 637 idx = 0; 638 639 week = t; 640 641 sec = week % 60; 642 week /= 60; 643 min = week % 60; 644 week /= 60; 645 hrs = week % 24; 646 week /= 24; 647 day = week % 7; 648 week /= 7; 649 650 if (week > 0) 651 snprintf(buf, TF_LEN, "%02lluw%01ud%02uh", week, day, hrs); 652 else if (day > 0) 653 snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min); 654 else 655 snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec); 656 657 return (buf); 658 } 659 660 /* 661 * Returns a standardized host+port identifier string. 662 * Caller must free returned string. 663 */ 664 char * 665 put_host_port(const char *host, u_short port) 666 { 667 char *hoststr; 668 669 if (port == 0 || port == SSH_DEFAULT_PORT) 670 return(xstrdup(host)); 671 if (asprintf(&hoststr, "[%s]:%d", host, (int)port) == -1) 672 fatal("put_host_port: asprintf: %s", strerror(errno)); 673 debug3("put_host_port: %s", hoststr); 674 return hoststr; 675 } 676 677 /* 678 * Search for next delimiter between hostnames/addresses and ports. 679 * Argument may be modified (for termination). 680 * Returns *cp if parsing succeeds. 681 * *cp is set to the start of the next field, if one was found. 682 * The delimiter char, if present, is stored in delim. 683 * If this is the last field, *cp is set to NULL. 684 */ 685 char * 686 hpdelim2(char **cp, char *delim) 687 { 688 char *s, *old; 689 690 if (cp == NULL || *cp == NULL) 691 return NULL; 692 693 old = s = *cp; 694 if (*s == '[') { 695 if ((s = strchr(s, ']')) == NULL) 696 return NULL; 697 else 698 s++; 699 } else if ((s = strpbrk(s, ":/")) == NULL) 700 s = *cp + strlen(*cp); /* skip to end (see first case below) */ 701 702 switch (*s) { 703 case '\0': 704 *cp = NULL; /* no more fields*/ 705 break; 706 707 case ':': 708 case '/': 709 if (delim != NULL) 710 *delim = *s; 711 *s = '\0'; /* terminate */ 712 *cp = s + 1; 713 break; 714 715 default: 716 return NULL; 717 } 718 719 return old; 720 } 721 722 /* The common case: only accept colon as delimiter. */ 723 char * 724 hpdelim(char **cp) 725 { 726 char *r, delim = '\0'; 727 728 r = hpdelim2(cp, &delim); 729 if (delim == '/') 730 return NULL; 731 return r; 732 } 733 734 char * 735 cleanhostname(char *host) 736 { 737 if (*host == '[' && host[strlen(host) - 1] == ']') { 738 host[strlen(host) - 1] = '\0'; 739 return (host + 1); 740 } else 741 return host; 742 } 743 744 char * 745 colon(char *cp) 746 { 747 int flag = 0; 748 749 if (*cp == ':') /* Leading colon is part of file name. */ 750 return NULL; 751 if (*cp == '[') 752 flag = 1; 753 754 for (; *cp; ++cp) { 755 if (*cp == '@' && *(cp+1) == '[') 756 flag = 1; 757 if (*cp == ']' && *(cp+1) == ':' && flag) 758 return (cp+1); 759 if (*cp == ':' && !flag) 760 return (cp); 761 if (*cp == '/') 762 return NULL; 763 } 764 return NULL; 765 } 766 767 /* 768 * Parse a [user@]host:[path] string. 769 * Caller must free returned user, host and path. 770 * Any of the pointer return arguments may be NULL (useful for syntax checking). 771 * If user was not specified then *userp will be set to NULL. 772 * If host was not specified then *hostp will be set to NULL. 773 * If path was not specified then *pathp will be set to ".". 774 * Returns 0 on success, -1 on failure. 775 */ 776 int 777 parse_user_host_path(const char *s, char **userp, char **hostp, char **pathp) 778 { 779 char *user = NULL, *host = NULL, *path = NULL; 780 char *sdup, *tmp; 781 int ret = -1; 782 783 if (userp != NULL) 784 *userp = NULL; 785 if (hostp != NULL) 786 *hostp = NULL; 787 if (pathp != NULL) 788 *pathp = NULL; 789 790 sdup = xstrdup(s); 791 792 /* Check for remote syntax: [user@]host:[path] */ 793 if ((tmp = colon(sdup)) == NULL) 794 goto out; 795 796 /* Extract optional path */ 797 *tmp++ = '\0'; 798 if (*tmp == '\0') 799 tmp = "."; 800 path = xstrdup(tmp); 801 802 /* Extract optional user and mandatory host */ 803 tmp = strrchr(sdup, '@'); 804 if (tmp != NULL) { 805 *tmp++ = '\0'; 806 host = xstrdup(cleanhostname(tmp)); 807 if (*sdup != '\0') 808 user = xstrdup(sdup); 809 } else { 810 host = xstrdup(cleanhostname(sdup)); 811 user = NULL; 812 } 813 814 /* Success */ 815 if (userp != NULL) { 816 *userp = user; 817 user = NULL; 818 } 819 if (hostp != NULL) { 820 *hostp = host; 821 host = NULL; 822 } 823 if (pathp != NULL) { 824 *pathp = path; 825 path = NULL; 826 } 827 ret = 0; 828 out: 829 free(sdup); 830 free(user); 831 free(host); 832 free(path); 833 return ret; 834 } 835 836 /* 837 * Parse a [user@]host[:port] string. 838 * Caller must free returned user and host. 839 * Any of the pointer return arguments may be NULL (useful for syntax checking). 840 * If user was not specified then *userp will be set to NULL. 841 * If port was not specified then *portp will be -1. 842 * Returns 0 on success, -1 on failure. 843 */ 844 int 845 parse_user_host_port(const char *s, char **userp, char **hostp, int *portp) 846 { 847 char *sdup, *cp, *tmp; 848 char *user = NULL, *host = NULL; 849 int port = -1, ret = -1; 850 851 if (userp != NULL) 852 *userp = NULL; 853 if (hostp != NULL) 854 *hostp = NULL; 855 if (portp != NULL) 856 *portp = -1; 857 858 if ((sdup = tmp = strdup(s)) == NULL) 859 return -1; 860 /* Extract optional username */ 861 if ((cp = strrchr(tmp, '@')) != NULL) { 862 *cp = '\0'; 863 if (*tmp == '\0') 864 goto out; 865 if ((user = strdup(tmp)) == NULL) 866 goto out; 867 tmp = cp + 1; 868 } 869 /* Extract mandatory hostname */ 870 if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0') 871 goto out; 872 host = xstrdup(cleanhostname(cp)); 873 /* Convert and verify optional port */ 874 if (tmp != NULL && *tmp != '\0') { 875 if ((port = a2port(tmp)) <= 0) 876 goto out; 877 } 878 /* Success */ 879 if (userp != NULL) { 880 *userp = user; 881 user = NULL; 882 } 883 if (hostp != NULL) { 884 *hostp = host; 885 host = NULL; 886 } 887 if (portp != NULL) 888 *portp = port; 889 ret = 0; 890 out: 891 free(sdup); 892 free(user); 893 free(host); 894 return ret; 895 } 896 897 /* 898 * Converts a two-byte hex string to decimal. 899 * Returns the decimal value or -1 for invalid input. 900 */ 901 static int 902 hexchar(const char *s) 903 { 904 unsigned char result[2]; 905 int i; 906 907 for (i = 0; i < 2; i++) { 908 if (s[i] >= '0' && s[i] <= '9') 909 result[i] = (unsigned char)(s[i] - '0'); 910 else if (s[i] >= 'a' && s[i] <= 'f') 911 result[i] = (unsigned char)(s[i] - 'a') + 10; 912 else if (s[i] >= 'A' && s[i] <= 'F') 913 result[i] = (unsigned char)(s[i] - 'A') + 10; 914 else 915 return -1; 916 } 917 return (result[0] << 4) | result[1]; 918 } 919 920 /* 921 * Decode an url-encoded string. 922 * Returns a newly allocated string on success or NULL on failure. 923 */ 924 static char * 925 urldecode(const char *src) 926 { 927 char *ret, *dst; 928 int ch; 929 930 ret = xmalloc(strlen(src) + 1); 931 for (dst = ret; *src != '\0'; src++) { 932 switch (*src) { 933 case '+': 934 *dst++ = ' '; 935 break; 936 case '%': 937 if (!isxdigit((unsigned char)src[1]) || 938 !isxdigit((unsigned char)src[2]) || 939 (ch = hexchar(src + 1)) == -1) { 940 free(ret); 941 return NULL; 942 } 943 *dst++ = ch; 944 src += 2; 945 break; 946 default: 947 *dst++ = *src; 948 break; 949 } 950 } 951 *dst = '\0'; 952 953 return ret; 954 } 955 956 /* 957 * Parse an (scp|ssh|sftp)://[user@]host[:port][/path] URI. 958 * See https://tools.ietf.org/html/draft-ietf-secsh-scp-sftp-ssh-uri-04 959 * Either user or path may be url-encoded (but not host or port). 960 * Caller must free returned user, host and path. 961 * Any of the pointer return arguments may be NULL (useful for syntax checking) 962 * but the scheme must always be specified. 963 * If user was not specified then *userp will be set to NULL. 964 * If port was not specified then *portp will be -1. 965 * If path was not specified then *pathp will be set to NULL. 966 * Returns 0 on success, 1 if non-uri/wrong scheme, -1 on error/invalid uri. 967 */ 968 int 969 parse_uri(const char *scheme, const char *uri, char **userp, char **hostp, 970 int *portp, char **pathp) 971 { 972 char *uridup, *cp, *tmp, ch; 973 char *user = NULL, *host = NULL, *path = NULL; 974 int port = -1, ret = -1; 975 size_t len; 976 977 len = strlen(scheme); 978 if (strncmp(uri, scheme, len) != 0 || strncmp(uri + len, "://", 3) != 0) 979 return 1; 980 uri += len + 3; 981 982 if (userp != NULL) 983 *userp = NULL; 984 if (hostp != NULL) 985 *hostp = NULL; 986 if (portp != NULL) 987 *portp = -1; 988 if (pathp != NULL) 989 *pathp = NULL; 990 991 uridup = tmp = xstrdup(uri); 992 993 /* Extract optional ssh-info (username + connection params) */ 994 if ((cp = strchr(tmp, '@')) != NULL) { 995 char *delim; 996 997 *cp = '\0'; 998 /* Extract username and connection params */ 999 if ((delim = strchr(tmp, ';')) != NULL) { 1000 /* Just ignore connection params for now */ 1001 *delim = '\0'; 1002 } 1003 if (*tmp == '\0') { 1004 /* Empty username */ 1005 goto out; 1006 } 1007 if ((user = urldecode(tmp)) == NULL) 1008 goto out; 1009 tmp = cp + 1; 1010 } 1011 1012 /* Extract mandatory hostname */ 1013 if ((cp = hpdelim2(&tmp, &ch)) == NULL || *cp == '\0') 1014 goto out; 1015 host = xstrdup(cleanhostname(cp)); 1016 if (!valid_domain(host, 0, NULL)) 1017 goto out; 1018 1019 if (tmp != NULL && *tmp != '\0') { 1020 if (ch == ':') { 1021 /* Convert and verify port. */ 1022 if ((cp = strchr(tmp, '/')) != NULL) 1023 *cp = '\0'; 1024 if ((port = a2port(tmp)) <= 0) 1025 goto out; 1026 tmp = cp ? cp + 1 : NULL; 1027 } 1028 if (tmp != NULL && *tmp != '\0') { 1029 /* Extract optional path */ 1030 if ((path = urldecode(tmp)) == NULL) 1031 goto out; 1032 } 1033 } 1034 1035 /* Success */ 1036 if (userp != NULL) { 1037 *userp = user; 1038 user = NULL; 1039 } 1040 if (hostp != NULL) { 1041 *hostp = host; 1042 host = NULL; 1043 } 1044 if (portp != NULL) 1045 *portp = port; 1046 if (pathp != NULL) { 1047 *pathp = path; 1048 path = NULL; 1049 } 1050 ret = 0; 1051 out: 1052 free(uridup); 1053 free(user); 1054 free(host); 1055 free(path); 1056 return ret; 1057 } 1058 1059 /* function to assist building execv() arguments */ 1060 void 1061 addargs(arglist *args, char *fmt, ...) 1062 { 1063 va_list ap; 1064 char *cp; 1065 u_int nalloc; 1066 int r; 1067 1068 va_start(ap, fmt); 1069 r = vasprintf(&cp, fmt, ap); 1070 va_end(ap); 1071 if (r == -1) 1072 fatal_f("argument too long"); 1073 1074 nalloc = args->nalloc; 1075 if (args->list == NULL) { 1076 nalloc = 32; 1077 args->num = 0; 1078 } else if (args->num > (256 * 1024)) 1079 fatal_f("too many arguments"); 1080 else if (args->num >= args->nalloc) 1081 fatal_f("arglist corrupt"); 1082 else if (args->num+2 >= nalloc) 1083 nalloc *= 2; 1084 1085 args->list = xrecallocarray(args->list, args->nalloc, 1086 nalloc, sizeof(char *)); 1087 args->nalloc = nalloc; 1088 args->list[args->num++] = cp; 1089 args->list[args->num] = NULL; 1090 } 1091 1092 void 1093 replacearg(arglist *args, u_int which, char *fmt, ...) 1094 { 1095 va_list ap; 1096 char *cp; 1097 int r; 1098 1099 va_start(ap, fmt); 1100 r = vasprintf(&cp, fmt, ap); 1101 va_end(ap); 1102 if (r == -1) 1103 fatal_f("argument too long"); 1104 if (args->list == NULL || args->num >= args->nalloc) 1105 fatal_f("arglist corrupt"); 1106 1107 if (which >= args->num) 1108 fatal_f("tried to replace invalid arg %d >= %d", 1109 which, args->num); 1110 free(args->list[which]); 1111 args->list[which] = cp; 1112 } 1113 1114 void 1115 freeargs(arglist *args) 1116 { 1117 u_int i; 1118 1119 if (args == NULL) 1120 return; 1121 if (args->list != NULL && args->num < args->nalloc) { 1122 for (i = 0; i < args->num; i++) 1123 free(args->list[i]); 1124 free(args->list); 1125 } 1126 args->nalloc = args->num = 0; 1127 args->list = NULL; 1128 } 1129 1130 /* 1131 * Expands tildes in the file name. Returns data allocated by xmalloc. 1132 * Warning: this calls getpw*. 1133 */ 1134 int 1135 tilde_expand(const char *filename, uid_t uid, char **retp) 1136 { 1137 char *ocopy = NULL, *copy, *s = NULL; 1138 const char *path = NULL, *user = NULL; 1139 struct passwd *pw; 1140 size_t len; 1141 int ret = -1, r, slash; 1142 1143 *retp = NULL; 1144 if (*filename != '~') { 1145 *retp = xstrdup(filename); 1146 return 0; 1147 } 1148 ocopy = copy = xstrdup(filename + 1); 1149 1150 if (*copy == '\0') /* ~ */ 1151 path = NULL; 1152 else if (*copy == '/') { 1153 copy += strspn(copy, "/"); 1154 if (*copy == '\0') 1155 path = NULL; /* ~/ */ 1156 else 1157 path = copy; /* ~/path */ 1158 } else { 1159 user = copy; 1160 if ((path = strchr(copy, '/')) != NULL) { 1161 copy[path - copy] = '\0'; 1162 path++; 1163 path += strspn(path, "/"); 1164 if (*path == '\0') /* ~user/ */ 1165 path = NULL; 1166 /* else ~user/path */ 1167 } 1168 /* else ~user */ 1169 } 1170 if (user != NULL) { 1171 if ((pw = getpwnam(user)) == NULL) { 1172 error_f("No such user %s", user); 1173 goto out; 1174 } 1175 } else if ((pw = getpwuid(uid)) == NULL) { 1176 error_f("No such uid %ld", (long)uid); 1177 goto out; 1178 } 1179 1180 /* Make sure directory has a trailing '/' */ 1181 slash = (len = strlen(pw->pw_dir)) == 0 || pw->pw_dir[len - 1] != '/'; 1182 1183 if ((r = xasprintf(&s, "%s%s%s", pw->pw_dir, 1184 slash ? "/" : "", path != NULL ? path : "")) <= 0) { 1185 error_f("xasprintf failed"); 1186 goto out; 1187 } 1188 if (r >= PATH_MAX) { 1189 error_f("Path too long"); 1190 goto out; 1191 } 1192 /* success */ 1193 ret = 0; 1194 *retp = s; 1195 s = NULL; 1196 out: 1197 free(s); 1198 free(ocopy); 1199 return ret; 1200 } 1201 1202 char * 1203 tilde_expand_filename(const char *filename, uid_t uid) 1204 { 1205 char *ret; 1206 1207 if (tilde_expand(filename, uid, &ret) != 0) 1208 cleanup_exit(255); 1209 return ret; 1210 } 1211 1212 /* 1213 * Expand a string with a set of %[char] escapes and/or ${ENVIRONMENT} 1214 * substitutions. A number of escapes may be specified as 1215 * (char *escape_chars, char *replacement) pairs. The list must be terminated 1216 * by a NULL escape_char. Returns replaced string in memory allocated by 1217 * xmalloc which the caller must free. 1218 */ 1219 static char * 1220 vdollar_percent_expand(int *parseerror, int dollar, int percent, 1221 const char *string, va_list ap) 1222 { 1223 #define EXPAND_MAX_KEYS 16 1224 u_int num_keys = 0, i; 1225 struct { 1226 const char *key; 1227 const char *repl; 1228 } keys[EXPAND_MAX_KEYS]; 1229 struct sshbuf *buf; 1230 int r, missingvar = 0; 1231 char *ret = NULL, *var, *varend, *val; 1232 size_t len; 1233 1234 if ((buf = sshbuf_new()) == NULL) 1235 fatal_f("sshbuf_new failed"); 1236 if (parseerror == NULL) 1237 fatal_f("null parseerror arg"); 1238 *parseerror = 1; 1239 1240 /* Gather keys if we're doing percent expansion. */ 1241 if (percent) { 1242 for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) { 1243 keys[num_keys].key = va_arg(ap, char *); 1244 if (keys[num_keys].key == NULL) 1245 break; 1246 keys[num_keys].repl = va_arg(ap, char *); 1247 if (keys[num_keys].repl == NULL) { 1248 fatal_f("NULL replacement for token %s", 1249 keys[num_keys].key); 1250 } 1251 } 1252 if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL) 1253 fatal_f("too many keys"); 1254 if (num_keys == 0) 1255 fatal_f("percent expansion without token list"); 1256 } 1257 1258 /* Expand string */ 1259 for (i = 0; *string != '\0'; string++) { 1260 /* Optionally process ${ENVIRONMENT} expansions. */ 1261 if (dollar && string[0] == '$' && string[1] == '{') { 1262 string += 2; /* skip over '${' */ 1263 if ((varend = strchr(string, '}')) == NULL) { 1264 error_f("environment variable '%s' missing " 1265 "closing '}'", string); 1266 goto out; 1267 } 1268 len = varend - string; 1269 if (len == 0) { 1270 error_f("zero-length environment variable"); 1271 goto out; 1272 } 1273 var = xmalloc(len + 1); 1274 (void)strlcpy(var, string, len + 1); 1275 if ((val = getenv(var)) == NULL) { 1276 error_f("env var ${%s} has no value", var); 1277 missingvar = 1; 1278 } else { 1279 debug3_f("expand ${%s} -> '%s'", var, val); 1280 if ((r = sshbuf_put(buf, val, strlen(val))) !=0) 1281 fatal_fr(r, "sshbuf_put ${}"); 1282 } 1283 free(var); 1284 string += len; 1285 continue; 1286 } 1287 1288 /* 1289 * Process percent expansions if we have a list of TOKENs. 1290 * If we're not doing percent expansion everything just gets 1291 * appended here. 1292 */ 1293 if (*string != '%' || !percent) { 1294 append: 1295 if ((r = sshbuf_put_u8(buf, *string)) != 0) 1296 fatal_fr(r, "sshbuf_put_u8 %%"); 1297 continue; 1298 } 1299 string++; 1300 /* %% case */ 1301 if (*string == '%') 1302 goto append; 1303 if (*string == '\0') { 1304 error_f("invalid format"); 1305 goto out; 1306 } 1307 for (i = 0; i < num_keys; i++) { 1308 if (strchr(keys[i].key, *string) != NULL) { 1309 if ((r = sshbuf_put(buf, keys[i].repl, 1310 strlen(keys[i].repl))) != 0) 1311 fatal_fr(r, "sshbuf_put %%-repl"); 1312 break; 1313 } 1314 } 1315 if (i >= num_keys) { 1316 error_f("unknown key %%%c", *string); 1317 goto out; 1318 } 1319 } 1320 if (!missingvar && (ret = sshbuf_dup_string(buf)) == NULL) 1321 fatal_f("sshbuf_dup_string failed"); 1322 *parseerror = 0; 1323 out: 1324 sshbuf_free(buf); 1325 return *parseerror ? NULL : ret; 1326 #undef EXPAND_MAX_KEYS 1327 } 1328 1329 /* 1330 * Expand only environment variables. 1331 * Note that although this function is variadic like the other similar 1332 * functions, any such arguments will be unused. 1333 */ 1334 1335 char * 1336 dollar_expand(int *parseerr, const char *string, ...) 1337 { 1338 char *ret; 1339 int err; 1340 va_list ap; 1341 1342 va_start(ap, string); 1343 ret = vdollar_percent_expand(&err, 1, 0, string, ap); 1344 va_end(ap); 1345 if (parseerr != NULL) 1346 *parseerr = err; 1347 return ret; 1348 } 1349 1350 /* 1351 * Returns expanded string or NULL if a specified environment variable is 1352 * not defined, or calls fatal if the string is invalid. 1353 */ 1354 char * 1355 percent_expand(const char *string, ...) 1356 { 1357 char *ret; 1358 int err; 1359 va_list ap; 1360 1361 va_start(ap, string); 1362 ret = vdollar_percent_expand(&err, 0, 1, string, ap); 1363 va_end(ap); 1364 if (err) 1365 fatal_f("failed"); 1366 return ret; 1367 } 1368 1369 /* 1370 * Returns expanded string or NULL if a specified environment variable is 1371 * not defined, or calls fatal if the string is invalid. 1372 */ 1373 char * 1374 percent_dollar_expand(const char *string, ...) 1375 { 1376 char *ret; 1377 int err; 1378 va_list ap; 1379 1380 va_start(ap, string); 1381 ret = vdollar_percent_expand(&err, 1, 1, string, ap); 1382 va_end(ap); 1383 if (err) 1384 fatal_f("failed"); 1385 return ret; 1386 } 1387 1388 int 1389 tun_open(int tun, int mode, char **ifname) 1390 { 1391 #if defined(CUSTOM_SYS_TUN_OPEN) 1392 return (sys_tun_open(tun, mode, ifname)); 1393 #elif defined(SSH_TUN_OPENBSD) 1394 struct ifreq ifr; 1395 char name[100]; 1396 int fd = -1, sock; 1397 const char *tunbase = "tun"; 1398 1399 if (ifname != NULL) 1400 *ifname = NULL; 1401 1402 if (mode == SSH_TUNMODE_ETHERNET) 1403 tunbase = "tap"; 1404 1405 /* Open the tunnel device */ 1406 if (tun <= SSH_TUNID_MAX) { 1407 snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); 1408 fd = open(name, O_RDWR); 1409 } else if (tun == SSH_TUNID_ANY) { 1410 for (tun = 100; tun >= 0; tun--) { 1411 snprintf(name, sizeof(name), "/dev/%s%d", 1412 tunbase, tun); 1413 if ((fd = open(name, O_RDWR)) >= 0) 1414 break; 1415 } 1416 } else { 1417 debug_f("invalid tunnel %u", tun); 1418 return -1; 1419 } 1420 1421 if (fd == -1) { 1422 debug_f("%s open: %s", name, strerror(errno)); 1423 return -1; 1424 } 1425 1426 debug_f("%s mode %d fd %d", name, mode, fd); 1427 1428 /* Bring interface up if it is not already */ 1429 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); 1430 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) 1431 goto failed; 1432 1433 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { 1434 debug_f("get interface %s flags: %s", ifr.ifr_name, 1435 strerror(errno)); 1436 goto failed; 1437 } 1438 1439 if (!(ifr.ifr_flags & IFF_UP)) { 1440 ifr.ifr_flags |= IFF_UP; 1441 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { 1442 debug_f("activate interface %s: %s", ifr.ifr_name, 1443 strerror(errno)); 1444 goto failed; 1445 } 1446 } 1447 1448 if (ifname != NULL) 1449 *ifname = xstrdup(ifr.ifr_name); 1450 1451 close(sock); 1452 return fd; 1453 1454 failed: 1455 if (fd >= 0) 1456 close(fd); 1457 if (sock >= 0) 1458 close(sock); 1459 return -1; 1460 #else 1461 error("Tunnel interfaces are not supported on this platform"); 1462 return (-1); 1463 #endif 1464 } 1465 1466 void 1467 sanitise_stdfd(void) 1468 { 1469 int nullfd, dupfd; 1470 1471 if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) { 1472 fprintf(stderr, "Couldn't open /dev/null: %s\n", 1473 strerror(errno)); 1474 exit(1); 1475 } 1476 while (++dupfd <= STDERR_FILENO) { 1477 /* Only populate closed fds. */ 1478 if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) { 1479 if (dup2(nullfd, dupfd) == -1) { 1480 fprintf(stderr, "dup2: %s\n", strerror(errno)); 1481 exit(1); 1482 } 1483 } 1484 } 1485 if (nullfd > STDERR_FILENO) 1486 close(nullfd); 1487 } 1488 1489 char * 1490 tohex(const void *vp, size_t l) 1491 { 1492 const u_char *p = (const u_char *)vp; 1493 char b[3], *r; 1494 size_t i, hl; 1495 1496 if (l > 65536) 1497 return xstrdup("tohex: length > 65536"); 1498 1499 hl = l * 2 + 1; 1500 r = xcalloc(1, hl); 1501 for (i = 0; i < l; i++) { 1502 snprintf(b, sizeof(b), "%02x", p[i]); 1503 strlcat(r, b, hl); 1504 } 1505 return (r); 1506 } 1507 1508 /* 1509 * Extend string *sp by the specified format. If *sp is not NULL (or empty), 1510 * then the separator 'sep' will be prepended before the formatted arguments. 1511 * Extended strings are heap allocated. 1512 */ 1513 void 1514 xextendf(char **sp, const char *sep, const char *fmt, ...) 1515 { 1516 va_list ap; 1517 char *tmp1, *tmp2; 1518 1519 va_start(ap, fmt); 1520 xvasprintf(&tmp1, fmt, ap); 1521 va_end(ap); 1522 1523 if (*sp == NULL || **sp == '\0') { 1524 free(*sp); 1525 *sp = tmp1; 1526 return; 1527 } 1528 xasprintf(&tmp2, "%s%s%s", *sp, sep == NULL ? "" : sep, tmp1); 1529 free(tmp1); 1530 free(*sp); 1531 *sp = tmp2; 1532 } 1533 1534 1535 u_int64_t 1536 get_u64(const void *vp) 1537 { 1538 const u_char *p = (const u_char *)vp; 1539 u_int64_t v; 1540 1541 v = (u_int64_t)p[0] << 56; 1542 v |= (u_int64_t)p[1] << 48; 1543 v |= (u_int64_t)p[2] << 40; 1544 v |= (u_int64_t)p[3] << 32; 1545 v |= (u_int64_t)p[4] << 24; 1546 v |= (u_int64_t)p[5] << 16; 1547 v |= (u_int64_t)p[6] << 8; 1548 v |= (u_int64_t)p[7]; 1549 1550 return (v); 1551 } 1552 1553 u_int32_t 1554 get_u32(const void *vp) 1555 { 1556 const u_char *p = (const u_char *)vp; 1557 u_int32_t v; 1558 1559 v = (u_int32_t)p[0] << 24; 1560 v |= (u_int32_t)p[1] << 16; 1561 v |= (u_int32_t)p[2] << 8; 1562 v |= (u_int32_t)p[3]; 1563 1564 return (v); 1565 } 1566 1567 u_int32_t 1568 get_u32_le(const void *vp) 1569 { 1570 const u_char *p = (const u_char *)vp; 1571 u_int32_t v; 1572 1573 v = (u_int32_t)p[0]; 1574 v |= (u_int32_t)p[1] << 8; 1575 v |= (u_int32_t)p[2] << 16; 1576 v |= (u_int32_t)p[3] << 24; 1577 1578 return (v); 1579 } 1580 1581 u_int16_t 1582 get_u16(const void *vp) 1583 { 1584 const u_char *p = (const u_char *)vp; 1585 u_int16_t v; 1586 1587 v = (u_int16_t)p[0] << 8; 1588 v |= (u_int16_t)p[1]; 1589 1590 return (v); 1591 } 1592 1593 void 1594 put_u64(void *vp, u_int64_t v) 1595 { 1596 u_char *p = (u_char *)vp; 1597 1598 p[0] = (u_char)(v >> 56) & 0xff; 1599 p[1] = (u_char)(v >> 48) & 0xff; 1600 p[2] = (u_char)(v >> 40) & 0xff; 1601 p[3] = (u_char)(v >> 32) & 0xff; 1602 p[4] = (u_char)(v >> 24) & 0xff; 1603 p[5] = (u_char)(v >> 16) & 0xff; 1604 p[6] = (u_char)(v >> 8) & 0xff; 1605 p[7] = (u_char)v & 0xff; 1606 } 1607 1608 void 1609 put_u32(void *vp, u_int32_t v) 1610 { 1611 u_char *p = (u_char *)vp; 1612 1613 p[0] = (u_char)(v >> 24) & 0xff; 1614 p[1] = (u_char)(v >> 16) & 0xff; 1615 p[2] = (u_char)(v >> 8) & 0xff; 1616 p[3] = (u_char)v & 0xff; 1617 } 1618 1619 void 1620 put_u32_le(void *vp, u_int32_t v) 1621 { 1622 u_char *p = (u_char *)vp; 1623 1624 p[0] = (u_char)v & 0xff; 1625 p[1] = (u_char)(v >> 8) & 0xff; 1626 p[2] = (u_char)(v >> 16) & 0xff; 1627 p[3] = (u_char)(v >> 24) & 0xff; 1628 } 1629 1630 void 1631 put_u16(void *vp, u_int16_t v) 1632 { 1633 u_char *p = (u_char *)vp; 1634 1635 p[0] = (u_char)(v >> 8) & 0xff; 1636 p[1] = (u_char)v & 0xff; 1637 } 1638 1639 void 1640 ms_subtract_diff(struct timeval *start, int *ms) 1641 { 1642 struct timeval diff, finish; 1643 1644 monotime_tv(&finish); 1645 timersub(&finish, start, &diff); 1646 *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); 1647 } 1648 1649 void 1650 ms_to_timespec(struct timespec *ts, int ms) 1651 { 1652 if (ms < 0) 1653 ms = 0; 1654 ts->tv_sec = ms / 1000; 1655 ts->tv_nsec = (ms % 1000) * 1000 * 1000; 1656 } 1657 1658 void 1659 monotime_ts(struct timespec *ts) 1660 { 1661 struct timeval tv; 1662 #if defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_BOOTTIME) || \ 1663 defined(CLOCK_MONOTONIC) || defined(CLOCK_REALTIME)) 1664 static int gettime_failed = 0; 1665 1666 if (!gettime_failed) { 1667 # ifdef CLOCK_BOOTTIME 1668 if (clock_gettime(CLOCK_BOOTTIME, ts) == 0) 1669 return; 1670 # endif /* CLOCK_BOOTTIME */ 1671 # ifdef CLOCK_MONOTONIC 1672 if (clock_gettime(CLOCK_MONOTONIC, ts) == 0) 1673 return; 1674 # endif /* CLOCK_MONOTONIC */ 1675 # ifdef CLOCK_REALTIME 1676 /* Not monotonic, but we're almost out of options here. */ 1677 if (clock_gettime(CLOCK_REALTIME, ts) == 0) 1678 return; 1679 # endif /* CLOCK_REALTIME */ 1680 debug3("clock_gettime: %s", strerror(errno)); 1681 gettime_failed = 1; 1682 } 1683 #endif /* HAVE_CLOCK_GETTIME && (BOOTTIME || MONOTONIC || REALTIME) */ 1684 gettimeofday(&tv, NULL); 1685 ts->tv_sec = tv.tv_sec; 1686 ts->tv_nsec = (long)tv.tv_usec * 1000; 1687 } 1688 1689 void 1690 monotime_tv(struct timeval *tv) 1691 { 1692 struct timespec ts; 1693 1694 monotime_ts(&ts); 1695 tv->tv_sec = ts.tv_sec; 1696 tv->tv_usec = ts.tv_nsec / 1000; 1697 } 1698 1699 time_t 1700 monotime(void) 1701 { 1702 struct timespec ts; 1703 1704 monotime_ts(&ts); 1705 return ts.tv_sec; 1706 } 1707 1708 double 1709 monotime_double(void) 1710 { 1711 struct timespec ts; 1712 1713 monotime_ts(&ts); 1714 return ts.tv_sec + ((double)ts.tv_nsec / 1000000000); 1715 } 1716 1717 void 1718 bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) 1719 { 1720 bw->buflen = buflen; 1721 bw->rate = kbps; 1722 bw->thresh = buflen; 1723 bw->lamt = 0; 1724 timerclear(&bw->bwstart); 1725 timerclear(&bw->bwend); 1726 } 1727 1728 /* Callback from read/write loop to insert bandwidth-limiting delays */ 1729 void 1730 bandwidth_limit(struct bwlimit *bw, size_t read_len) 1731 { 1732 u_int64_t waitlen; 1733 struct timespec ts, rm; 1734 1735 bw->lamt += read_len; 1736 if (!timerisset(&bw->bwstart)) { 1737 monotime_tv(&bw->bwstart); 1738 return; 1739 } 1740 if (bw->lamt < bw->thresh) 1741 return; 1742 1743 monotime_tv(&bw->bwend); 1744 timersub(&bw->bwend, &bw->bwstart, &bw->bwend); 1745 if (!timerisset(&bw->bwend)) 1746 return; 1747 1748 bw->lamt *= 8; 1749 waitlen = (double)1000000L * bw->lamt / bw->rate; 1750 1751 bw->bwstart.tv_sec = waitlen / 1000000L; 1752 bw->bwstart.tv_usec = waitlen % 1000000L; 1753 1754 if (timercmp(&bw->bwstart, &bw->bwend, >)) { 1755 timersub(&bw->bwstart, &bw->bwend, &bw->bwend); 1756 1757 /* Adjust the wait time */ 1758 if (bw->bwend.tv_sec) { 1759 bw->thresh /= 2; 1760 if (bw->thresh < bw->buflen / 4) 1761 bw->thresh = bw->buflen / 4; 1762 } else if (bw->bwend.tv_usec < 10000) { 1763 bw->thresh *= 2; 1764 if (bw->thresh > bw->buflen * 8) 1765 bw->thresh = bw->buflen * 8; 1766 } 1767 1768 TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts); 1769 while (nanosleep(&ts, &rm) == -1) { 1770 if (errno != EINTR) 1771 break; 1772 ts = rm; 1773 } 1774 } 1775 1776 bw->lamt = 0; 1777 monotime_tv(&bw->bwstart); 1778 } 1779 1780 /* Make a template filename for mk[sd]temp() */ 1781 void 1782 mktemp_proto(char *s, size_t len) 1783 { 1784 const char *tmpdir; 1785 int r; 1786 1787 if ((tmpdir = getenv("TMPDIR")) != NULL) { 1788 r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir); 1789 if (r > 0 && (size_t)r < len) 1790 return; 1791 } 1792 r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX"); 1793 if (r < 0 || (size_t)r >= len) 1794 fatal_f("template string too short"); 1795 } 1796 1797 static const struct { 1798 const char *name; 1799 int value; 1800 } ipqos[] = { 1801 { "none", INT_MAX }, /* can't use 0 here; that's CS0 */ 1802 { "af11", IPTOS_DSCP_AF11 }, 1803 { "af12", IPTOS_DSCP_AF12 }, 1804 { "af13", IPTOS_DSCP_AF13 }, 1805 { "af21", IPTOS_DSCP_AF21 }, 1806 { "af22", IPTOS_DSCP_AF22 }, 1807 { "af23", IPTOS_DSCP_AF23 }, 1808 { "af31", IPTOS_DSCP_AF31 }, 1809 { "af32", IPTOS_DSCP_AF32 }, 1810 { "af33", IPTOS_DSCP_AF33 }, 1811 { "af41", IPTOS_DSCP_AF41 }, 1812 { "af42", IPTOS_DSCP_AF42 }, 1813 { "af43", IPTOS_DSCP_AF43 }, 1814 { "cs0", IPTOS_DSCP_CS0 }, 1815 { "cs1", IPTOS_DSCP_CS1 }, 1816 { "cs2", IPTOS_DSCP_CS2 }, 1817 { "cs3", IPTOS_DSCP_CS3 }, 1818 { "cs4", IPTOS_DSCP_CS4 }, 1819 { "cs5", IPTOS_DSCP_CS5 }, 1820 { "cs6", IPTOS_DSCP_CS6 }, 1821 { "cs7", IPTOS_DSCP_CS7 }, 1822 { "ef", IPTOS_DSCP_EF }, 1823 { "le", IPTOS_DSCP_LE }, 1824 { "lowdelay", IPTOS_LOWDELAY }, 1825 { "throughput", IPTOS_THROUGHPUT }, 1826 { "reliability", IPTOS_RELIABILITY }, 1827 { NULL, -1 } 1828 }; 1829 1830 int 1831 parse_ipqos(const char *cp) 1832 { 1833 u_int i; 1834 char *ep; 1835 long val; 1836 1837 if (cp == NULL) 1838 return -1; 1839 for (i = 0; ipqos[i].name != NULL; i++) { 1840 if (strcasecmp(cp, ipqos[i].name) == 0) 1841 return ipqos[i].value; 1842 } 1843 /* Try parsing as an integer */ 1844 val = strtol(cp, &ep, 0); 1845 if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255) 1846 return -1; 1847 return val; 1848 } 1849 1850 const char * 1851 iptos2str(int iptos) 1852 { 1853 int i; 1854 static char iptos_str[sizeof "0xff"]; 1855 1856 for (i = 0; ipqos[i].name != NULL; i++) { 1857 if (ipqos[i].value == iptos) 1858 return ipqos[i].name; 1859 } 1860 snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos); 1861 return iptos_str; 1862 } 1863 1864 void 1865 lowercase(char *s) 1866 { 1867 for (; *s; s++) 1868 *s = tolower((u_char)*s); 1869 } 1870 1871 int 1872 unix_listener(const char *path, int backlog, int unlink_first) 1873 { 1874 struct sockaddr_un sunaddr; 1875 int saved_errno, sock; 1876 1877 memset(&sunaddr, 0, sizeof(sunaddr)); 1878 sunaddr.sun_family = AF_UNIX; 1879 if (strlcpy(sunaddr.sun_path, path, 1880 sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) { 1881 error_f("path \"%s\" too long for Unix domain socket", path); 1882 errno = ENAMETOOLONG; 1883 return -1; 1884 } 1885 1886 sock = socket(PF_UNIX, SOCK_STREAM, 0); 1887 if (sock == -1) { 1888 saved_errno = errno; 1889 error_f("socket: %.100s", strerror(errno)); 1890 errno = saved_errno; 1891 return -1; 1892 } 1893 if (unlink_first == 1) { 1894 if (unlink(path) != 0 && errno != ENOENT) 1895 error("unlink(%s): %.100s", path, strerror(errno)); 1896 } 1897 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) { 1898 saved_errno = errno; 1899 error_f("cannot bind to path %s: %s", path, strerror(errno)); 1900 close(sock); 1901 errno = saved_errno; 1902 return -1; 1903 } 1904 if (listen(sock, backlog) == -1) { 1905 saved_errno = errno; 1906 error_f("cannot listen on path %s: %s", path, strerror(errno)); 1907 close(sock); 1908 unlink(path); 1909 errno = saved_errno; 1910 return -1; 1911 } 1912 return sock; 1913 } 1914 1915 void 1916 sock_set_v6only(int s) 1917 { 1918 #if defined(IPV6_V6ONLY) && !defined(__OpenBSD__) 1919 int on = 1; 1920 1921 debug3("%s: set socket %d IPV6_V6ONLY", __func__, s); 1922 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) 1923 error("setsockopt IPV6_V6ONLY: %s", strerror(errno)); 1924 #endif 1925 } 1926 1927 /* 1928 * Compares two strings that maybe be NULL. Returns non-zero if strings 1929 * are both NULL or are identical, returns zero otherwise. 1930 */ 1931 static int 1932 strcmp_maybe_null(const char *a, const char *b) 1933 { 1934 if ((a == NULL && b != NULL) || (a != NULL && b == NULL)) 1935 return 0; 1936 if (a != NULL && strcmp(a, b) != 0) 1937 return 0; 1938 return 1; 1939 } 1940 1941 /* 1942 * Compare two forwards, returning non-zero if they are identical or 1943 * zero otherwise. 1944 */ 1945 int 1946 forward_equals(const struct Forward *a, const struct Forward *b) 1947 { 1948 if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0) 1949 return 0; 1950 if (a->listen_port != b->listen_port) 1951 return 0; 1952 if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0) 1953 return 0; 1954 if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0) 1955 return 0; 1956 if (a->connect_port != b->connect_port) 1957 return 0; 1958 if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0) 1959 return 0; 1960 /* allocated_port and handle are not checked */ 1961 return 1; 1962 } 1963 1964 /* returns 1 if process is already daemonized, 0 otherwise */ 1965 int 1966 daemonized(void) 1967 { 1968 int fd; 1969 1970 if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) { 1971 close(fd); 1972 return 0; /* have controlling terminal */ 1973 } 1974 if (getppid() != 1) 1975 return 0; /* parent is not init */ 1976 if (getsid(0) != getpid()) 1977 return 0; /* not session leader */ 1978 debug3("already daemonized"); 1979 return 1; 1980 } 1981 1982 /* 1983 * Splits 's' into an argument vector. Handles quoted string and basic 1984 * escape characters (\\, \", \'). Caller must free the argument vector 1985 * and its members. 1986 */ 1987 int 1988 argv_split(const char *s, int *argcp, char ***argvp, int terminate_on_comment) 1989 { 1990 int r = SSH_ERR_INTERNAL_ERROR; 1991 int argc = 0, quote, i, j; 1992 char *arg, **argv = xcalloc(1, sizeof(*argv)); 1993 1994 *argvp = NULL; 1995 *argcp = 0; 1996 1997 for (i = 0; s[i] != '\0'; i++) { 1998 /* Skip leading whitespace */ 1999 if (s[i] == ' ' || s[i] == '\t') 2000 continue; 2001 if (terminate_on_comment && s[i] == '#') 2002 break; 2003 /* Start of a token */ 2004 quote = 0; 2005 2006 argv = xreallocarray(argv, (argc + 2), sizeof(*argv)); 2007 arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1); 2008 argv[argc] = NULL; 2009 2010 /* Copy the token in, removing escapes */ 2011 for (j = 0; s[i] != '\0'; i++) { 2012 if (s[i] == '\\') { 2013 if (s[i + 1] == '\'' || 2014 s[i + 1] == '\"' || 2015 s[i + 1] == '\\' || 2016 (quote == 0 && s[i + 1] == ' ')) { 2017 i++; /* Skip '\' */ 2018 arg[j++] = s[i]; 2019 } else { 2020 /* Unrecognised escape */ 2021 arg[j++] = s[i]; 2022 } 2023 } else if (quote == 0 && (s[i] == ' ' || s[i] == '\t')) 2024 break; /* done */ 2025 else if (quote == 0 && (s[i] == '\"' || s[i] == '\'')) 2026 quote = s[i]; /* quote start */ 2027 else if (quote != 0 && s[i] == quote) 2028 quote = 0; /* quote end */ 2029 else 2030 arg[j++] = s[i]; 2031 } 2032 if (s[i] == '\0') { 2033 if (quote != 0) { 2034 /* Ran out of string looking for close quote */ 2035 r = SSH_ERR_INVALID_FORMAT; 2036 goto out; 2037 } 2038 break; 2039 } 2040 } 2041 /* Success */ 2042 *argcp = argc; 2043 *argvp = argv; 2044 argc = 0; 2045 argv = NULL; 2046 r = 0; 2047 out: 2048 if (argc != 0 && argv != NULL) { 2049 for (i = 0; i < argc; i++) 2050 free(argv[i]); 2051 free(argv); 2052 } 2053 return r; 2054 } 2055 2056 /* 2057 * Reassemble an argument vector into a string, quoting and escaping as 2058 * necessary. Caller must free returned string. 2059 */ 2060 char * 2061 argv_assemble(int argc, char **argv) 2062 { 2063 int i, j, ws, r; 2064 char c, *ret; 2065 struct sshbuf *buf, *arg; 2066 2067 if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL) 2068 fatal_f("sshbuf_new failed"); 2069 2070 for (i = 0; i < argc; i++) { 2071 ws = 0; 2072 sshbuf_reset(arg); 2073 for (j = 0; argv[i][j] != '\0'; j++) { 2074 r = 0; 2075 c = argv[i][j]; 2076 switch (c) { 2077 case ' ': 2078 case '\t': 2079 ws = 1; 2080 r = sshbuf_put_u8(arg, c); 2081 break; 2082 case '\\': 2083 case '\'': 2084 case '"': 2085 if ((r = sshbuf_put_u8(arg, '\\')) != 0) 2086 break; 2087 /* FALLTHROUGH */ 2088 default: 2089 r = sshbuf_put_u8(arg, c); 2090 break; 2091 } 2092 if (r != 0) 2093 fatal_fr(r, "sshbuf_put_u8"); 2094 } 2095 if ((i != 0 && (r = sshbuf_put_u8(buf, ' ')) != 0) || 2096 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) || 2097 (r = sshbuf_putb(buf, arg)) != 0 || 2098 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0)) 2099 fatal_fr(r, "assemble"); 2100 } 2101 if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL) 2102 fatal_f("malloc failed"); 2103 memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf)); 2104 ret[sshbuf_len(buf)] = '\0'; 2105 sshbuf_free(buf); 2106 sshbuf_free(arg); 2107 return ret; 2108 } 2109 2110 char * 2111 argv_next(int *argcp, char ***argvp) 2112 { 2113 char *ret = (*argvp)[0]; 2114 2115 if (*argcp > 0 && ret != NULL) { 2116 (*argcp)--; 2117 (*argvp)++; 2118 } 2119 return ret; 2120 } 2121 2122 void 2123 argv_consume(int *argcp) 2124 { 2125 *argcp = 0; 2126 } 2127 2128 void 2129 argv_free(char **av, int ac) 2130 { 2131 int i; 2132 2133 if (av == NULL) 2134 return; 2135 for (i = 0; i < ac; i++) 2136 free(av[i]); 2137 free(av); 2138 } 2139 2140 /* Returns 0 if pid exited cleanly, non-zero otherwise */ 2141 int 2142 exited_cleanly(pid_t pid, const char *tag, const char *cmd, int quiet) 2143 { 2144 int status; 2145 2146 while (waitpid(pid, &status, 0) == -1) { 2147 if (errno != EINTR) { 2148 error("%s waitpid: %s", tag, strerror(errno)); 2149 return -1; 2150 } 2151 } 2152 if (WIFSIGNALED(status)) { 2153 error("%s %s exited on signal %d", tag, cmd, WTERMSIG(status)); 2154 return -1; 2155 } else if (WEXITSTATUS(status) != 0) { 2156 do_log2(quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO, 2157 "%s %s failed, status %d", tag, cmd, WEXITSTATUS(status)); 2158 return -1; 2159 } 2160 return 0; 2161 } 2162 2163 /* 2164 * Check a given path for security. This is defined as all components 2165 * of the path to the file must be owned by either the owner of 2166 * of the file or root and no directories must be group or world writable. 2167 * 2168 * XXX Should any specific check be done for sym links ? 2169 * 2170 * Takes a file name, its stat information (preferably from fstat() to 2171 * avoid races), the uid of the expected owner, their home directory and an 2172 * error buffer plus max size as arguments. 2173 * 2174 * Returns 0 on success and -1 on failure 2175 */ 2176 int 2177 safe_path(const char *name, struct stat *stp, const char *pw_dir, 2178 uid_t uid, char *err, size_t errlen) 2179 { 2180 char buf[PATH_MAX], homedir[PATH_MAX]; 2181 char *cp; 2182 int comparehome = 0; 2183 struct stat st; 2184 2185 if (realpath(name, buf) == NULL) { 2186 snprintf(err, errlen, "realpath %s failed: %s", name, 2187 strerror(errno)); 2188 return -1; 2189 } 2190 if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) 2191 comparehome = 1; 2192 2193 if (!S_ISREG(stp->st_mode)) { 2194 snprintf(err, errlen, "%s is not a regular file", buf); 2195 return -1; 2196 } 2197 if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) || 2198 (stp->st_mode & 022) != 0) { 2199 snprintf(err, errlen, "bad ownership or modes for file %s", 2200 buf); 2201 return -1; 2202 } 2203 2204 /* for each component of the canonical path, walking upwards */ 2205 for (;;) { 2206 if ((cp = dirname(buf)) == NULL) { 2207 snprintf(err, errlen, "dirname() failed"); 2208 return -1; 2209 } 2210 strlcpy(buf, cp, sizeof(buf)); 2211 2212 if (stat(buf, &st) == -1 || 2213 (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) || 2214 (st.st_mode & 022) != 0) { 2215 snprintf(err, errlen, 2216 "bad ownership or modes for directory %s", buf); 2217 return -1; 2218 } 2219 2220 /* If are past the homedir then we can stop */ 2221 if (comparehome && strcmp(homedir, buf) == 0) 2222 break; 2223 2224 /* 2225 * dirname should always complete with a "/" path, 2226 * but we can be paranoid and check for "." too 2227 */ 2228 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) 2229 break; 2230 } 2231 return 0; 2232 } 2233 2234 /* 2235 * Version of safe_path() that accepts an open file descriptor to 2236 * avoid races. 2237 * 2238 * Returns 0 on success and -1 on failure 2239 */ 2240 int 2241 safe_path_fd(int fd, const char *file, struct passwd *pw, 2242 char *err, size_t errlen) 2243 { 2244 struct stat st; 2245 2246 /* check the open file to avoid races */ 2247 if (fstat(fd, &st) == -1) { 2248 snprintf(err, errlen, "cannot stat file %s: %s", 2249 file, strerror(errno)); 2250 return -1; 2251 } 2252 return safe_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); 2253 } 2254 2255 /* 2256 * Sets the value of the given variable in the environment. If the variable 2257 * already exists, its value is overridden. 2258 */ 2259 void 2260 child_set_env(char ***envp, u_int *envsizep, const char *name, 2261 const char *value) 2262 { 2263 char **env; 2264 u_int envsize; 2265 u_int i, namelen; 2266 2267 if (strchr(name, '=') != NULL) { 2268 error("Invalid environment variable \"%.100s\"", name); 2269 return; 2270 } 2271 2272 /* 2273 * If we're passed an uninitialized list, allocate a single null 2274 * entry before continuing. 2275 */ 2276 if (*envp == NULL && *envsizep == 0) { 2277 *envp = xmalloc(sizeof(char *)); 2278 *envp[0] = NULL; 2279 *envsizep = 1; 2280 } 2281 2282 /* 2283 * Find the slot where the value should be stored. If the variable 2284 * already exists, we reuse the slot; otherwise we append a new slot 2285 * at the end of the array, expanding if necessary. 2286 */ 2287 env = *envp; 2288 namelen = strlen(name); 2289 for (i = 0; env[i]; i++) 2290 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') 2291 break; 2292 if (env[i]) { 2293 /* Reuse the slot. */ 2294 free(env[i]); 2295 } else { 2296 /* New variable. Expand if necessary. */ 2297 envsize = *envsizep; 2298 if (i >= envsize - 1) { 2299 if (envsize >= 1000) 2300 fatal("child_set_env: too many env vars"); 2301 envsize += 50; 2302 env = (*envp) = xreallocarray(env, envsize, sizeof(char *)); 2303 *envsizep = envsize; 2304 } 2305 /* Need to set the NULL pointer at end of array beyond the new slot. */ 2306 env[i + 1] = NULL; 2307 } 2308 2309 /* Allocate space and format the variable in the appropriate slot. */ 2310 /* XXX xasprintf */ 2311 env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); 2312 snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); 2313 } 2314 2315 /* 2316 * Check and optionally lowercase a domain name, also removes trailing '.' 2317 * Returns 1 on success and 0 on failure, storing an error message in errstr. 2318 */ 2319 int 2320 valid_domain(char *name, int makelower, const char **errstr) 2321 { 2322 size_t i, l = strlen(name); 2323 u_char c, last = '\0'; 2324 static char errbuf[256]; 2325 2326 if (l == 0) { 2327 strlcpy(errbuf, "empty domain name", sizeof(errbuf)); 2328 goto bad; 2329 } 2330 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) { 2331 snprintf(errbuf, sizeof(errbuf), "domain name \"%.100s\" " 2332 "starts with invalid character", name); 2333 goto bad; 2334 } 2335 for (i = 0; i < l; i++) { 2336 c = tolower((u_char)name[i]); 2337 if (makelower) 2338 name[i] = (char)c; 2339 if (last == '.' && c == '.') { 2340 snprintf(errbuf, sizeof(errbuf), "domain name " 2341 "\"%.100s\" contains consecutive separators", name); 2342 goto bad; 2343 } 2344 if (c != '.' && c != '-' && !isalnum(c) && 2345 c != '_') /* technically invalid, but common */ { 2346 snprintf(errbuf, sizeof(errbuf), "domain name " 2347 "\"%.100s\" contains invalid characters", name); 2348 goto bad; 2349 } 2350 last = c; 2351 } 2352 if (name[l - 1] == '.') 2353 name[l - 1] = '\0'; 2354 if (errstr != NULL) 2355 *errstr = NULL; 2356 return 1; 2357 bad: 2358 if (errstr != NULL) 2359 *errstr = errbuf; 2360 return 0; 2361 } 2362 2363 /* 2364 * Verify that a environment variable name (not including initial '$') is 2365 * valid; consisting of one or more alphanumeric or underscore characters only. 2366 * Returns 1 on valid, 0 otherwise. 2367 */ 2368 int 2369 valid_env_name(const char *name) 2370 { 2371 const char *cp; 2372 2373 if (name[0] == '\0') 2374 return 0; 2375 for (cp = name; *cp != '\0'; cp++) { 2376 if (!isalnum((u_char)*cp) && *cp != '_') 2377 return 0; 2378 } 2379 return 1; 2380 } 2381 2382 const char * 2383 atoi_err(const char *nptr, int *val) 2384 { 2385 const char *errstr = NULL; 2386 long long num; 2387 2388 if (nptr == NULL || *nptr == '\0') 2389 return "missing"; 2390 num = strtonum(nptr, 0, INT_MAX, &errstr); 2391 if (errstr == NULL) 2392 *val = (int)num; 2393 return errstr; 2394 } 2395 2396 int 2397 parse_absolute_time(const char *s, uint64_t *tp) 2398 { 2399 struct tm tm; 2400 time_t tt; 2401 char buf[32], *fmt; 2402 const char *cp; 2403 size_t l; 2404 int is_utc = 0; 2405 2406 *tp = 0; 2407 2408 l = strlen(s); 2409 if (l > 1 && strcasecmp(s + l - 1, "Z") == 0) { 2410 is_utc = 1; 2411 l--; 2412 } else if (l > 3 && strcasecmp(s + l - 3, "UTC") == 0) { 2413 is_utc = 1; 2414 l -= 3; 2415 } 2416 /* 2417 * POSIX strptime says "The application shall ensure that there 2418 * is white-space or other non-alphanumeric characters between 2419 * any two conversion specifications" so arrange things this way. 2420 */ 2421 switch (l) { 2422 case 8: /* YYYYMMDD */ 2423 fmt = "%Y-%m-%d"; 2424 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6); 2425 break; 2426 case 12: /* YYYYMMDDHHMM */ 2427 fmt = "%Y-%m-%dT%H:%M"; 2428 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s", 2429 s, s + 4, s + 6, s + 8, s + 10); 2430 break; 2431 case 14: /* YYYYMMDDHHMMSS */ 2432 fmt = "%Y-%m-%dT%H:%M:%S"; 2433 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s", 2434 s, s + 4, s + 6, s + 8, s + 10, s + 12); 2435 break; 2436 default: 2437 return SSH_ERR_INVALID_FORMAT; 2438 } 2439 2440 memset(&tm, 0, sizeof(tm)); 2441 if ((cp = strptime(buf, fmt, &tm)) == NULL || *cp != '\0') 2442 return SSH_ERR_INVALID_FORMAT; 2443 if (is_utc) { 2444 if ((tt = timegm(&tm)) < 0) 2445 return SSH_ERR_INVALID_FORMAT; 2446 } else { 2447 if ((tt = mktime(&tm)) < 0) 2448 return SSH_ERR_INVALID_FORMAT; 2449 } 2450 /* success */ 2451 *tp = (uint64_t)tt; 2452 return 0; 2453 } 2454 2455 /* On OpenBSD time_t is int64_t which is long long. */ 2456 /* #define SSH_TIME_T_MAX LLONG_MAX */ 2457 2458 void 2459 format_absolute_time(uint64_t t, char *buf, size_t len) 2460 { 2461 time_t tt = t > SSH_TIME_T_MAX ? SSH_TIME_T_MAX : t; 2462 struct tm tm; 2463 2464 localtime_r(&tt, &tm); 2465 strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm); 2466 } 2467 2468 /* check if path is absolute */ 2469 int 2470 path_absolute(const char *path) 2471 { 2472 return (*path == '/') ? 1 : 0; 2473 } 2474 2475 void 2476 skip_space(char **cpp) 2477 { 2478 char *cp; 2479 2480 for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) 2481 ; 2482 *cpp = cp; 2483 } 2484 2485 /* authorized_key-style options parsing helpers */ 2486 2487 /* 2488 * Match flag 'opt' in *optsp, and if allow_negate is set then also match 2489 * 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0 2490 * if negated option matches. 2491 * If the option or negated option matches, then *optsp is updated to 2492 * point to the first character after the option. 2493 */ 2494 int 2495 opt_flag(const char *opt, int allow_negate, const char **optsp) 2496 { 2497 size_t opt_len = strlen(opt); 2498 const char *opts = *optsp; 2499 int negate = 0; 2500 2501 if (allow_negate && strncasecmp(opts, "no-", 3) == 0) { 2502 opts += 3; 2503 negate = 1; 2504 } 2505 if (strncasecmp(opts, opt, opt_len) == 0) { 2506 *optsp = opts + opt_len; 2507 return negate ? 0 : 1; 2508 } 2509 return -1; 2510 } 2511 2512 char * 2513 opt_dequote(const char **sp, const char **errstrp) 2514 { 2515 const char *s = *sp; 2516 char *ret; 2517 size_t i; 2518 2519 *errstrp = NULL; 2520 if (*s != '"') { 2521 *errstrp = "missing start quote"; 2522 return NULL; 2523 } 2524 s++; 2525 if ((ret = malloc(strlen((s)) + 1)) == NULL) { 2526 *errstrp = "memory allocation failed"; 2527 return NULL; 2528 } 2529 for (i = 0; *s != '\0' && *s != '"';) { 2530 if (s[0] == '\\' && s[1] == '"') 2531 s++; 2532 ret[i++] = *s++; 2533 } 2534 if (*s == '\0') { 2535 *errstrp = "missing end quote"; 2536 free(ret); 2537 return NULL; 2538 } 2539 ret[i] = '\0'; 2540 s++; 2541 *sp = s; 2542 return ret; 2543 } 2544 2545 int 2546 opt_match(const char **opts, const char *term) 2547 { 2548 if (strncasecmp((*opts), term, strlen(term)) == 0 && 2549 (*opts)[strlen(term)] == '=') { 2550 *opts += strlen(term) + 1; 2551 return 1; 2552 } 2553 return 0; 2554 } 2555 2556 void 2557 opt_array_append2(const char *file, const int line, const char *directive, 2558 char ***array, int **iarray, u_int *lp, const char *s, int i) 2559 { 2560 2561 if (*lp >= INT_MAX) 2562 fatal("%s line %d: Too many %s entries", file, line, directive); 2563 2564 if (iarray != NULL) { 2565 *iarray = xrecallocarray(*iarray, *lp, *lp + 1, 2566 sizeof(**iarray)); 2567 (*iarray)[*lp] = i; 2568 } 2569 2570 *array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array)); 2571 (*array)[*lp] = xstrdup(s); 2572 (*lp)++; 2573 } 2574 2575 void 2576 opt_array_append(const char *file, const int line, const char *directive, 2577 char ***array, u_int *lp, const char *s) 2578 { 2579 opt_array_append2(file, line, directive, array, NULL, lp, s, 0); 2580 } 2581 2582 sshsig_t 2583 ssh_signal(int signum, sshsig_t handler) 2584 { 2585 struct sigaction sa, osa; 2586 2587 /* mask all other signals while in handler */ 2588 memset(&sa, 0, sizeof(sa)); 2589 sa.sa_handler = handler; 2590 sigfillset(&sa.sa_mask); 2591 #if defined(SA_RESTART) && !defined(NO_SA_RESTART) 2592 if (signum != SIGALRM) 2593 sa.sa_flags = SA_RESTART; 2594 #endif 2595 if (sigaction(signum, &sa, &osa) == -1) { 2596 debug3("sigaction(%s): %s", strsignal(signum), strerror(errno)); 2597 return SIG_ERR; 2598 } 2599 return osa.sa_handler; 2600 } 2601 2602 int 2603 stdfd_devnull(int do_stdin, int do_stdout, int do_stderr) 2604 { 2605 int devnull, ret = 0; 2606 2607 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { 2608 error_f("open %s: %s", _PATH_DEVNULL, 2609 strerror(errno)); 2610 return -1; 2611 } 2612 if ((do_stdin && dup2(devnull, STDIN_FILENO) == -1) || 2613 (do_stdout && dup2(devnull, STDOUT_FILENO) == -1) || 2614 (do_stderr && dup2(devnull, STDERR_FILENO) == -1)) { 2615 error_f("dup2: %s", strerror(errno)); 2616 ret = -1; 2617 } 2618 if (devnull > STDERR_FILENO) 2619 close(devnull); 2620 return ret; 2621 } 2622 2623 /* 2624 * Runs command in a subprocess with a minimal environment. 2625 * Returns pid on success, 0 on failure. 2626 * The child stdout and stderr maybe captured, left attached or sent to 2627 * /dev/null depending on the contents of flags. 2628 * "tag" is prepended to log messages. 2629 * NB. "command" is only used for logging; the actual command executed is 2630 * av[0]. 2631 */ 2632 pid_t 2633 subprocess(const char *tag, const char *command, 2634 int ac, char **av, FILE **child, u_int flags, 2635 struct passwd *pw, privdrop_fn *drop_privs, privrestore_fn *restore_privs) 2636 { 2637 FILE *f = NULL; 2638 struct stat st; 2639 int fd, devnull, p[2], i; 2640 pid_t pid; 2641 char *cp, errmsg[512]; 2642 u_int nenv = 0; 2643 char **env = NULL; 2644 2645 /* If dropping privs, then must specify user and restore function */ 2646 if (drop_privs != NULL && (pw == NULL || restore_privs == NULL)) { 2647 error("%s: inconsistent arguments", tag); /* XXX fatal? */ 2648 return 0; 2649 } 2650 if (pw == NULL && (pw = getpwuid(getuid())) == NULL) { 2651 error("%s: no user for current uid", tag); 2652 return 0; 2653 } 2654 if (child != NULL) 2655 *child = NULL; 2656 2657 debug3_f("%s command \"%s\" running as %s (flags 0x%x)", 2658 tag, command, pw->pw_name, flags); 2659 2660 /* Check consistency */ 2661 if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 && 2662 (flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) { 2663 error_f("inconsistent flags"); 2664 return 0; 2665 } 2666 if (((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0) != (child == NULL)) { 2667 error_f("inconsistent flags/output"); 2668 return 0; 2669 } 2670 2671 /* 2672 * If executing an explicit binary, then verify the it exists 2673 * and appears safe-ish to execute 2674 */ 2675 if (!path_absolute(av[0])) { 2676 error("%s path is not absolute", tag); 2677 return 0; 2678 } 2679 if (drop_privs != NULL) 2680 drop_privs(pw); 2681 if (stat(av[0], &st) == -1) { 2682 error("Could not stat %s \"%s\": %s", tag, 2683 av[0], strerror(errno)); 2684 goto restore_return; 2685 } 2686 if ((flags & SSH_SUBPROCESS_UNSAFE_PATH) == 0 && 2687 safe_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) { 2688 error("Unsafe %s \"%s\": %s", tag, av[0], errmsg); 2689 goto restore_return; 2690 } 2691 /* Prepare to keep the child's stdout if requested */ 2692 if (pipe(p) == -1) { 2693 error("%s: pipe: %s", tag, strerror(errno)); 2694 restore_return: 2695 if (restore_privs != NULL) 2696 restore_privs(); 2697 return 0; 2698 } 2699 if (restore_privs != NULL) 2700 restore_privs(); 2701 2702 switch ((pid = fork())) { 2703 case -1: /* error */ 2704 error("%s: fork: %s", tag, strerror(errno)); 2705 close(p[0]); 2706 close(p[1]); 2707 return 0; 2708 case 0: /* child */ 2709 /* Prepare a minimal environment for the child. */ 2710 if ((flags & SSH_SUBPROCESS_PRESERVE_ENV) == 0) { 2711 nenv = 5; 2712 env = xcalloc(sizeof(*env), nenv); 2713 child_set_env(&env, &nenv, "PATH", _PATH_STDPATH); 2714 child_set_env(&env, &nenv, "USER", pw->pw_name); 2715 child_set_env(&env, &nenv, "LOGNAME", pw->pw_name); 2716 child_set_env(&env, &nenv, "HOME", pw->pw_dir); 2717 if ((cp = getenv("LANG")) != NULL) 2718 child_set_env(&env, &nenv, "LANG", cp); 2719 } 2720 2721 for (i = 1; i < NSIG; i++) 2722 ssh_signal(i, SIG_DFL); 2723 2724 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { 2725 error("%s: open %s: %s", tag, _PATH_DEVNULL, 2726 strerror(errno)); 2727 _exit(1); 2728 } 2729 if (dup2(devnull, STDIN_FILENO) == -1) { 2730 error("%s: dup2: %s", tag, strerror(errno)); 2731 _exit(1); 2732 } 2733 2734 /* Set up stdout as requested; leave stderr in place for now. */ 2735 fd = -1; 2736 if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) 2737 fd = p[1]; 2738 else if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0) 2739 fd = devnull; 2740 if (fd != -1 && dup2(fd, STDOUT_FILENO) == -1) { 2741 error("%s: dup2: %s", tag, strerror(errno)); 2742 _exit(1); 2743 } 2744 closefrom(STDERR_FILENO + 1); 2745 2746 if (geteuid() == 0 && 2747 initgroups(pw->pw_name, pw->pw_gid) == -1) { 2748 error("%s: initgroups(%s, %u): %s", tag, 2749 pw->pw_name, (u_int)pw->pw_gid, strerror(errno)); 2750 _exit(1); 2751 } 2752 if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) { 2753 error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid, 2754 strerror(errno)); 2755 _exit(1); 2756 } 2757 if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) { 2758 error("%s: setresuid %u: %s", tag, (u_int)pw->pw_uid, 2759 strerror(errno)); 2760 _exit(1); 2761 } 2762 /* stdin is pointed to /dev/null at this point */ 2763 if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 && 2764 dup2(STDIN_FILENO, STDERR_FILENO) == -1) { 2765 error("%s: dup2: %s", tag, strerror(errno)); 2766 _exit(1); 2767 } 2768 if (env != NULL) 2769 execve(av[0], av, env); 2770 else 2771 execv(av[0], av); 2772 error("%s %s \"%s\": %s", tag, env == NULL ? "execv" : "execve", 2773 command, strerror(errno)); 2774 _exit(127); 2775 default: /* parent */ 2776 break; 2777 } 2778 2779 close(p[1]); 2780 if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0) 2781 close(p[0]); 2782 else if ((f = fdopen(p[0], "r")) == NULL) { 2783 error("%s: fdopen: %s", tag, strerror(errno)); 2784 close(p[0]); 2785 /* Don't leave zombie child */ 2786 kill(pid, SIGTERM); 2787 while (waitpid(pid, NULL, 0) == -1 && errno == EINTR) 2788 ; 2789 return 0; 2790 } 2791 /* Success */ 2792 debug3_f("%s pid %ld", tag, (long)pid); 2793 if (child != NULL) 2794 *child = f; 2795 return pid; 2796 } 2797 2798 const char * 2799 lookup_env_in_list(const char *env, char * const *envs, size_t nenvs) 2800 { 2801 size_t i, envlen; 2802 2803 envlen = strlen(env); 2804 for (i = 0; i < nenvs; i++) { 2805 if (strncmp(envs[i], env, envlen) == 0 && 2806 envs[i][envlen] == '=') { 2807 return envs[i] + envlen + 1; 2808 } 2809 } 2810 return NULL; 2811 } 2812 2813 const char * 2814 lookup_setenv_in_list(const char *env, char * const *envs, size_t nenvs) 2815 { 2816 char *name, *cp; 2817 const char *ret; 2818 2819 name = xstrdup(env); 2820 if ((cp = strchr(name, '=')) == NULL) { 2821 free(name); 2822 return NULL; /* not env=val */ 2823 } 2824 *cp = '\0'; 2825 ret = lookup_env_in_list(name, envs, nenvs); 2826 free(name); 2827 return ret; 2828 } 2829