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