1 /* $OpenBSD: misc.c,v 1.113 2017/08/18 05:48:04 djm Exp $ */ 2 /* 3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/ioctl.h> 29 #include <sys/socket.h> 30 #include <sys/stat.h> 31 #include <sys/time.h> 32 #include <sys/wait.h> 33 #include <sys/un.h> 34 35 #include <net/if.h> 36 #include <netinet/in.h> 37 #include <netinet/ip.h> 38 #include <netinet/tcp.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 <signal.h> 49 #include <stdarg.h> 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <string.h> 53 #include <unistd.h> 54 55 #include "xmalloc.h" 56 #include "misc.h" 57 #include "log.h" 58 #include "ssh.h" 59 #include "sshbuf.h" 60 #include "ssherr.h" 61 #include "uidswap.h" 62 63 /* remove newline at end of string */ 64 char * 65 chop(char *s) 66 { 67 char *t = s; 68 while (*t) { 69 if (*t == '\n' || *t == '\r') { 70 *t = '\0'; 71 return s; 72 } 73 t++; 74 } 75 return s; 76 77 } 78 79 /* set/unset filedescriptor to non-blocking */ 80 int 81 set_nonblock(int fd) 82 { 83 int val; 84 85 val = fcntl(fd, F_GETFL); 86 if (val < 0) { 87 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); 88 return (-1); 89 } 90 if (val & O_NONBLOCK) { 91 debug3("fd %d is O_NONBLOCK", fd); 92 return (0); 93 } 94 debug2("fd %d setting O_NONBLOCK", fd); 95 val |= O_NONBLOCK; 96 if (fcntl(fd, F_SETFL, val) == -1) { 97 debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, 98 strerror(errno)); 99 return (-1); 100 } 101 return (0); 102 } 103 104 int 105 unset_nonblock(int fd) 106 { 107 int val; 108 109 val = fcntl(fd, F_GETFL); 110 if (val < 0) { 111 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); 112 return (-1); 113 } 114 if (!(val & O_NONBLOCK)) { 115 debug3("fd %d is not O_NONBLOCK", fd); 116 return (0); 117 } 118 debug("fd %d clearing O_NONBLOCK", fd); 119 val &= ~O_NONBLOCK; 120 if (fcntl(fd, F_SETFL, val) == -1) { 121 debug("fcntl(%d, F_SETFL, ~O_NONBLOCK): %s", 122 fd, strerror(errno)); 123 return (-1); 124 } 125 return (0); 126 } 127 128 const char * 129 ssh_gai_strerror(int gaierr) 130 { 131 if (gaierr == EAI_SYSTEM && errno != 0) 132 return strerror(errno); 133 return gai_strerror(gaierr); 134 } 135 136 /* disable nagle on socket */ 137 void 138 set_nodelay(int fd) 139 { 140 int opt; 141 socklen_t optlen; 142 143 optlen = sizeof opt; 144 if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) { 145 debug("getsockopt TCP_NODELAY: %.100s", strerror(errno)); 146 return; 147 } 148 if (opt == 1) { 149 debug2("fd %d is TCP_NODELAY", fd); 150 return; 151 } 152 opt = 1; 153 debug2("fd %d setting TCP_NODELAY", fd); 154 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1) 155 error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); 156 } 157 158 /* Characters considered whitespace in strsep calls. */ 159 #define WHITESPACE " \t\r\n" 160 #define QUOTE "\"" 161 162 /* return next token in configuration line */ 163 char * 164 strdelim(char **s) 165 { 166 char *old; 167 int wspace = 0; 168 169 if (*s == NULL) 170 return NULL; 171 172 old = *s; 173 174 *s = strpbrk(*s, WHITESPACE QUOTE "="); 175 if (*s == NULL) 176 return (old); 177 178 if (*s[0] == '\"') { 179 memmove(*s, *s + 1, strlen(*s)); /* move nul too */ 180 /* Find matching quote */ 181 if ((*s = strpbrk(*s, QUOTE)) == NULL) { 182 return (NULL); /* no matching quote */ 183 } else { 184 *s[0] = '\0'; 185 *s += strspn(*s + 1, WHITESPACE) + 1; 186 return (old); 187 } 188 } 189 190 /* Allow only one '=' to be skipped */ 191 if (*s[0] == '=') 192 wspace = 1; 193 *s[0] = '\0'; 194 195 /* Skip any extra whitespace after first token */ 196 *s += strspn(*s + 1, WHITESPACE) + 1; 197 if (*s[0] == '=' && !wspace) 198 *s += strspn(*s + 1, WHITESPACE) + 1; 199 200 return (old); 201 } 202 203 struct passwd * 204 pwcopy(struct passwd *pw) 205 { 206 struct passwd *copy = xcalloc(1, sizeof(*copy)); 207 208 copy->pw_name = xstrdup(pw->pw_name); 209 copy->pw_passwd = xstrdup(pw->pw_passwd); 210 copy->pw_gecos = xstrdup(pw->pw_gecos); 211 copy->pw_uid = pw->pw_uid; 212 copy->pw_gid = pw->pw_gid; 213 copy->pw_expire = pw->pw_expire; 214 copy->pw_change = pw->pw_change; 215 copy->pw_class = xstrdup(pw->pw_class); 216 copy->pw_dir = xstrdup(pw->pw_dir); 217 copy->pw_shell = xstrdup(pw->pw_shell); 218 return copy; 219 } 220 221 /* 222 * Convert ASCII string to TCP/IP port number. 223 * Port must be >=0 and <=65535. 224 * Return -1 if invalid. 225 */ 226 int 227 a2port(const char *s) 228 { 229 long long port; 230 const char *errstr; 231 232 port = strtonum(s, 0, 65535, &errstr); 233 if (errstr != NULL) 234 return -1; 235 return (int)port; 236 } 237 238 int 239 a2tun(const char *s, int *remote) 240 { 241 const char *errstr = NULL; 242 char *sp, *ep; 243 int tun; 244 245 if (remote != NULL) { 246 *remote = SSH_TUNID_ANY; 247 sp = xstrdup(s); 248 if ((ep = strchr(sp, ':')) == NULL) { 249 free(sp); 250 return (a2tun(s, NULL)); 251 } 252 ep[0] = '\0'; ep++; 253 *remote = a2tun(ep, NULL); 254 tun = a2tun(sp, NULL); 255 free(sp); 256 return (*remote == SSH_TUNID_ERR ? *remote : tun); 257 } 258 259 if (strcasecmp(s, "any") == 0) 260 return (SSH_TUNID_ANY); 261 262 tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr); 263 if (errstr != NULL) 264 return (SSH_TUNID_ERR); 265 266 return (tun); 267 } 268 269 #define SECONDS 1 270 #define MINUTES (SECONDS * 60) 271 #define HOURS (MINUTES * 60) 272 #define DAYS (HOURS * 24) 273 #define WEEKS (DAYS * 7) 274 275 /* 276 * Convert a time string into seconds; format is 277 * a sequence of: 278 * time[qualifier] 279 * 280 * Valid time qualifiers are: 281 * <none> seconds 282 * s|S seconds 283 * m|M minutes 284 * h|H hours 285 * d|D days 286 * w|W weeks 287 * 288 * Examples: 289 * 90m 90 minutes 290 * 1h30m 90 minutes 291 * 2d 2 days 292 * 1w 1 week 293 * 294 * Return -1 if time string is invalid. 295 */ 296 long 297 convtime(const char *s) 298 { 299 long total, secs, multiplier = 1; 300 const char *p; 301 char *endp; 302 303 errno = 0; 304 total = 0; 305 p = s; 306 307 if (p == NULL || *p == '\0') 308 return -1; 309 310 while (*p) { 311 secs = strtol(p, &endp, 10); 312 if (p == endp || 313 (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) || 314 secs < 0) 315 return -1; 316 317 switch (*endp++) { 318 case '\0': 319 endp--; 320 break; 321 case 's': 322 case 'S': 323 break; 324 case 'm': 325 case 'M': 326 multiplier = MINUTES; 327 break; 328 case 'h': 329 case 'H': 330 multiplier = HOURS; 331 break; 332 case 'd': 333 case 'D': 334 multiplier = DAYS; 335 break; 336 case 'w': 337 case 'W': 338 multiplier = WEEKS; 339 break; 340 default: 341 return -1; 342 } 343 if (secs >= LONG_MAX / multiplier) 344 return -1; 345 secs *= multiplier; 346 if (total >= LONG_MAX - secs) 347 return -1; 348 total += secs; 349 if (total < 0) 350 return -1; 351 p = endp; 352 } 353 354 return total; 355 } 356 357 /* 358 * Returns a standardized host+port identifier string. 359 * Caller must free returned string. 360 */ 361 char * 362 put_host_port(const char *host, u_short port) 363 { 364 char *hoststr; 365 366 if (port == 0 || port == SSH_DEFAULT_PORT) 367 return(xstrdup(host)); 368 if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0) 369 fatal("put_host_port: asprintf: %s", strerror(errno)); 370 debug3("put_host_port: %s", hoststr); 371 return hoststr; 372 } 373 374 /* 375 * Search for next delimiter between hostnames/addresses and ports. 376 * Argument may be modified (for termination). 377 * Returns *cp if parsing succeeds. 378 * *cp is set to the start of the next delimiter, if one was found. 379 * If this is the last field, *cp is set to NULL. 380 */ 381 char * 382 hpdelim(char **cp) 383 { 384 char *s, *old; 385 386 if (cp == NULL || *cp == NULL) 387 return NULL; 388 389 old = s = *cp; 390 if (*s == '[') { 391 if ((s = strchr(s, ']')) == NULL) 392 return NULL; 393 else 394 s++; 395 } else if ((s = strpbrk(s, ":/")) == NULL) 396 s = *cp + strlen(*cp); /* skip to end (see first case below) */ 397 398 switch (*s) { 399 case '\0': 400 *cp = NULL; /* no more fields*/ 401 break; 402 403 case ':': 404 case '/': 405 *s = '\0'; /* terminate */ 406 *cp = s + 1; 407 break; 408 409 default: 410 return NULL; 411 } 412 413 return old; 414 } 415 416 char * 417 cleanhostname(char *host) 418 { 419 if (*host == '[' && host[strlen(host) - 1] == ']') { 420 host[strlen(host) - 1] = '\0'; 421 return (host + 1); 422 } else 423 return host; 424 } 425 426 char * 427 colon(char *cp) 428 { 429 int flag = 0; 430 431 if (*cp == ':') /* Leading colon is part of file name. */ 432 return NULL; 433 if (*cp == '[') 434 flag = 1; 435 436 for (; *cp; ++cp) { 437 if (*cp == '@' && *(cp+1) == '[') 438 flag = 1; 439 if (*cp == ']' && *(cp+1) == ':' && flag) 440 return (cp+1); 441 if (*cp == ':' && !flag) 442 return (cp); 443 if (*cp == '/') 444 return NULL; 445 } 446 return NULL; 447 } 448 449 /* 450 * Parse a [user@]host[:port] string. 451 * Caller must free returned user and host. 452 * Any of the pointer return arguments may be NULL (useful for syntax checking). 453 * If user was not specified then *userp will be set to NULL. 454 * If port was not specified then *portp will be -1. 455 * Returns 0 on success, -1 on failure. 456 */ 457 int 458 parse_user_host_port(const char *s, char **userp, char **hostp, int *portp) 459 { 460 char *sdup, *cp, *tmp; 461 char *user = NULL, *host = NULL; 462 int port = -1, ret = -1; 463 464 if (userp != NULL) 465 *userp = NULL; 466 if (hostp != NULL) 467 *hostp = NULL; 468 if (portp != NULL) 469 *portp = -1; 470 471 if ((sdup = tmp = strdup(s)) == NULL) 472 return -1; 473 /* Extract optional username */ 474 if ((cp = strchr(tmp, '@')) != NULL) { 475 *cp = '\0'; 476 if (*tmp == '\0') 477 goto out; 478 if ((user = strdup(tmp)) == NULL) 479 goto out; 480 tmp = cp + 1; 481 } 482 /* Extract mandatory hostname */ 483 if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0') 484 goto out; 485 host = xstrdup(cleanhostname(cp)); 486 /* Convert and verify optional port */ 487 if (tmp != NULL && *tmp != '\0') { 488 if ((port = a2port(tmp)) <= 0) 489 goto out; 490 } 491 /* Success */ 492 if (userp != NULL) { 493 *userp = user; 494 user = NULL; 495 } 496 if (hostp != NULL) { 497 *hostp = host; 498 host = NULL; 499 } 500 if (portp != NULL) 501 *portp = port; 502 ret = 0; 503 out: 504 free(sdup); 505 free(user); 506 free(host); 507 return ret; 508 } 509 510 /* function to assist building execv() arguments */ 511 void 512 addargs(arglist *args, char *fmt, ...) 513 { 514 va_list ap; 515 char *cp; 516 u_int nalloc; 517 int r; 518 519 va_start(ap, fmt); 520 r = vasprintf(&cp, fmt, ap); 521 va_end(ap); 522 if (r == -1) 523 fatal("addargs: argument too long"); 524 525 nalloc = args->nalloc; 526 if (args->list == NULL) { 527 nalloc = 32; 528 args->num = 0; 529 } else if (args->num+2 >= nalloc) 530 nalloc *= 2; 531 532 args->list = xrecallocarray(args->list, args->nalloc, nalloc, sizeof(char *)); 533 args->nalloc = nalloc; 534 args->list[args->num++] = cp; 535 args->list[args->num] = NULL; 536 } 537 538 void 539 replacearg(arglist *args, u_int which, char *fmt, ...) 540 { 541 va_list ap; 542 char *cp; 543 int r; 544 545 va_start(ap, fmt); 546 r = vasprintf(&cp, fmt, ap); 547 va_end(ap); 548 if (r == -1) 549 fatal("replacearg: argument too long"); 550 551 if (which >= args->num) 552 fatal("replacearg: tried to replace invalid arg %d >= %d", 553 which, args->num); 554 free(args->list[which]); 555 args->list[which] = cp; 556 } 557 558 void 559 freeargs(arglist *args) 560 { 561 u_int i; 562 563 if (args->list != NULL) { 564 for (i = 0; i < args->num; i++) 565 free(args->list[i]); 566 free(args->list); 567 args->nalloc = args->num = 0; 568 args->list = NULL; 569 } 570 } 571 572 /* 573 * Expands tildes in the file name. Returns data allocated by xmalloc. 574 * Warning: this calls getpw*. 575 */ 576 char * 577 tilde_expand_filename(const char *filename, uid_t uid) 578 { 579 const char *path, *sep; 580 char user[128], *ret; 581 struct passwd *pw; 582 u_int len, slash; 583 584 if (*filename != '~') 585 return (xstrdup(filename)); 586 filename++; 587 588 path = strchr(filename, '/'); 589 if (path != NULL && path > filename) { /* ~user/path */ 590 slash = path - filename; 591 if (slash > sizeof(user) - 1) 592 fatal("tilde_expand_filename: ~username too long"); 593 memcpy(user, filename, slash); 594 user[slash] = '\0'; 595 if ((pw = getpwnam(user)) == NULL) 596 fatal("tilde_expand_filename: No such user %s", user); 597 } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */ 598 fatal("tilde_expand_filename: No such uid %ld", (long)uid); 599 600 /* Make sure directory has a trailing '/' */ 601 len = strlen(pw->pw_dir); 602 if (len == 0 || pw->pw_dir[len - 1] != '/') 603 sep = "/"; 604 else 605 sep = ""; 606 607 /* Skip leading '/' from specified path */ 608 if (path != NULL) 609 filename = path + 1; 610 611 if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX) 612 fatal("tilde_expand_filename: Path too long"); 613 614 return (ret); 615 } 616 617 /* 618 * Expand a string with a set of %[char] escapes. A number of escapes may be 619 * specified as (char *escape_chars, char *replacement) pairs. The list must 620 * be terminated by a NULL escape_char. Returns replaced string in memory 621 * allocated by xmalloc. 622 */ 623 char * 624 percent_expand(const char *string, ...) 625 { 626 #define EXPAND_MAX_KEYS 16 627 u_int num_keys, i, j; 628 struct { 629 const char *key; 630 const char *repl; 631 } keys[EXPAND_MAX_KEYS]; 632 char buf[4096]; 633 va_list ap; 634 635 /* Gather keys */ 636 va_start(ap, string); 637 for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) { 638 keys[num_keys].key = va_arg(ap, char *); 639 if (keys[num_keys].key == NULL) 640 break; 641 keys[num_keys].repl = va_arg(ap, char *); 642 if (keys[num_keys].repl == NULL) 643 fatal("%s: NULL replacement", __func__); 644 } 645 if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL) 646 fatal("%s: too many keys", __func__); 647 va_end(ap); 648 649 /* Expand string */ 650 *buf = '\0'; 651 for (i = 0; *string != '\0'; string++) { 652 if (*string != '%') { 653 append: 654 buf[i++] = *string; 655 if (i >= sizeof(buf)) 656 fatal("%s: string too long", __func__); 657 buf[i] = '\0'; 658 continue; 659 } 660 string++; 661 /* %% case */ 662 if (*string == '%') 663 goto append; 664 if (*string == '\0') 665 fatal("%s: invalid format", __func__); 666 for (j = 0; j < num_keys; j++) { 667 if (strchr(keys[j].key, *string) != NULL) { 668 i = strlcat(buf, keys[j].repl, sizeof(buf)); 669 if (i >= sizeof(buf)) 670 fatal("%s: string too long", __func__); 671 break; 672 } 673 } 674 if (j >= num_keys) 675 fatal("%s: unknown key %%%c", __func__, *string); 676 } 677 return (xstrdup(buf)); 678 #undef EXPAND_MAX_KEYS 679 } 680 681 /* 682 * Read an entire line from a public key file into a static buffer, discarding 683 * lines that exceed the buffer size. Returns 0 on success, -1 on failure. 684 */ 685 int 686 read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz, 687 u_long *lineno) 688 { 689 while (fgets(buf, bufsz, f) != NULL) { 690 if (buf[0] == '\0') 691 continue; 692 (*lineno)++; 693 if (buf[strlen(buf) - 1] == '\n' || feof(f)) { 694 return 0; 695 } else { 696 debug("%s: %s line %lu exceeds size limit", __func__, 697 filename, *lineno); 698 /* discard remainder of line */ 699 while (fgetc(f) != '\n' && !feof(f)) 700 ; /* nothing */ 701 } 702 } 703 return -1; 704 } 705 706 int 707 tun_open(int tun, int mode) 708 { 709 struct ifreq ifr; 710 char name[100]; 711 int fd = -1, sock; 712 const char *tunbase = "tun"; 713 714 if (mode == SSH_TUNMODE_ETHERNET) 715 tunbase = "tap"; 716 717 /* Open the tunnel device */ 718 if (tun <= SSH_TUNID_MAX) { 719 snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); 720 fd = open(name, O_RDWR); 721 } else if (tun == SSH_TUNID_ANY) { 722 for (tun = 100; tun >= 0; tun--) { 723 snprintf(name, sizeof(name), "/dev/%s%d", 724 tunbase, tun); 725 if ((fd = open(name, O_RDWR)) >= 0) 726 break; 727 } 728 } else { 729 debug("%s: invalid tunnel %u", __func__, tun); 730 return -1; 731 } 732 733 if (fd < 0) { 734 debug("%s: %s open: %s", __func__, name, strerror(errno)); 735 return -1; 736 } 737 738 debug("%s: %s mode %d fd %d", __func__, name, mode, fd); 739 740 /* Bring interface up if it is not already */ 741 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); 742 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) 743 goto failed; 744 745 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { 746 debug("%s: get interface %s flags: %s", __func__, 747 ifr.ifr_name, strerror(errno)); 748 goto failed; 749 } 750 751 if (!(ifr.ifr_flags & IFF_UP)) { 752 ifr.ifr_flags |= IFF_UP; 753 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { 754 debug("%s: activate interface %s: %s", __func__, 755 ifr.ifr_name, strerror(errno)); 756 goto failed; 757 } 758 } 759 760 close(sock); 761 return fd; 762 763 failed: 764 if (fd >= 0) 765 close(fd); 766 if (sock >= 0) 767 close(sock); 768 return -1; 769 } 770 771 void 772 sanitise_stdfd(void) 773 { 774 int nullfd, dupfd; 775 776 if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) { 777 fprintf(stderr, "Couldn't open /dev/null: %s\n", 778 strerror(errno)); 779 exit(1); 780 } 781 while (++dupfd <= STDERR_FILENO) { 782 /* Only populate closed fds. */ 783 if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) { 784 if (dup2(nullfd, dupfd) == -1) { 785 fprintf(stderr, "dup2: %s\n", strerror(errno)); 786 exit(1); 787 } 788 } 789 } 790 if (nullfd > STDERR_FILENO) 791 close(nullfd); 792 } 793 794 char * 795 tohex(const void *vp, size_t l) 796 { 797 const u_char *p = (const u_char *)vp; 798 char b[3], *r; 799 size_t i, hl; 800 801 if (l > 65536) 802 return xstrdup("tohex: length > 65536"); 803 804 hl = l * 2 + 1; 805 r = xcalloc(1, hl); 806 for (i = 0; i < l; i++) { 807 snprintf(b, sizeof(b), "%02x", p[i]); 808 strlcat(r, b, hl); 809 } 810 return (r); 811 } 812 813 u_int64_t 814 get_u64(const void *vp) 815 { 816 const u_char *p = (const u_char *)vp; 817 u_int64_t v; 818 819 v = (u_int64_t)p[0] << 56; 820 v |= (u_int64_t)p[1] << 48; 821 v |= (u_int64_t)p[2] << 40; 822 v |= (u_int64_t)p[3] << 32; 823 v |= (u_int64_t)p[4] << 24; 824 v |= (u_int64_t)p[5] << 16; 825 v |= (u_int64_t)p[6] << 8; 826 v |= (u_int64_t)p[7]; 827 828 return (v); 829 } 830 831 u_int32_t 832 get_u32(const void *vp) 833 { 834 const u_char *p = (const u_char *)vp; 835 u_int32_t v; 836 837 v = (u_int32_t)p[0] << 24; 838 v |= (u_int32_t)p[1] << 16; 839 v |= (u_int32_t)p[2] << 8; 840 v |= (u_int32_t)p[3]; 841 842 return (v); 843 } 844 845 u_int32_t 846 get_u32_le(const void *vp) 847 { 848 const u_char *p = (const u_char *)vp; 849 u_int32_t v; 850 851 v = (u_int32_t)p[0]; 852 v |= (u_int32_t)p[1] << 8; 853 v |= (u_int32_t)p[2] << 16; 854 v |= (u_int32_t)p[3] << 24; 855 856 return (v); 857 } 858 859 u_int16_t 860 get_u16(const void *vp) 861 { 862 const u_char *p = (const u_char *)vp; 863 u_int16_t v; 864 865 v = (u_int16_t)p[0] << 8; 866 v |= (u_int16_t)p[1]; 867 868 return (v); 869 } 870 871 void 872 put_u64(void *vp, u_int64_t v) 873 { 874 u_char *p = (u_char *)vp; 875 876 p[0] = (u_char)(v >> 56) & 0xff; 877 p[1] = (u_char)(v >> 48) & 0xff; 878 p[2] = (u_char)(v >> 40) & 0xff; 879 p[3] = (u_char)(v >> 32) & 0xff; 880 p[4] = (u_char)(v >> 24) & 0xff; 881 p[5] = (u_char)(v >> 16) & 0xff; 882 p[6] = (u_char)(v >> 8) & 0xff; 883 p[7] = (u_char)v & 0xff; 884 } 885 886 void 887 put_u32(void *vp, u_int32_t v) 888 { 889 u_char *p = (u_char *)vp; 890 891 p[0] = (u_char)(v >> 24) & 0xff; 892 p[1] = (u_char)(v >> 16) & 0xff; 893 p[2] = (u_char)(v >> 8) & 0xff; 894 p[3] = (u_char)v & 0xff; 895 } 896 897 void 898 put_u32_le(void *vp, u_int32_t v) 899 { 900 u_char *p = (u_char *)vp; 901 902 p[0] = (u_char)v & 0xff; 903 p[1] = (u_char)(v >> 8) & 0xff; 904 p[2] = (u_char)(v >> 16) & 0xff; 905 p[3] = (u_char)(v >> 24) & 0xff; 906 } 907 908 void 909 put_u16(void *vp, u_int16_t v) 910 { 911 u_char *p = (u_char *)vp; 912 913 p[0] = (u_char)(v >> 8) & 0xff; 914 p[1] = (u_char)v & 0xff; 915 } 916 917 void 918 ms_subtract_diff(struct timeval *start, int *ms) 919 { 920 struct timeval diff, finish; 921 922 gettimeofday(&finish, NULL); 923 timersub(&finish, start, &diff); 924 *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); 925 } 926 927 void 928 ms_to_timeval(struct timeval *tv, int ms) 929 { 930 if (ms < 0) 931 ms = 0; 932 tv->tv_sec = ms / 1000; 933 tv->tv_usec = (ms % 1000) * 1000; 934 } 935 936 time_t 937 monotime(void) 938 { 939 struct timespec ts; 940 941 if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) 942 fatal("clock_gettime: %s", strerror(errno)); 943 944 return (ts.tv_sec); 945 } 946 947 double 948 monotime_double(void) 949 { 950 struct timespec ts; 951 952 if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) 953 fatal("clock_gettime: %s", strerror(errno)); 954 955 return (ts.tv_sec + (double)ts.tv_nsec / 1000000000); 956 } 957 958 void 959 bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) 960 { 961 bw->buflen = buflen; 962 bw->rate = kbps; 963 bw->thresh = bw->rate; 964 bw->lamt = 0; 965 timerclear(&bw->bwstart); 966 timerclear(&bw->bwend); 967 } 968 969 /* Callback from read/write loop to insert bandwidth-limiting delays */ 970 void 971 bandwidth_limit(struct bwlimit *bw, size_t read_len) 972 { 973 u_int64_t waitlen; 974 struct timespec ts, rm; 975 976 if (!timerisset(&bw->bwstart)) { 977 gettimeofday(&bw->bwstart, NULL); 978 return; 979 } 980 981 bw->lamt += read_len; 982 if (bw->lamt < bw->thresh) 983 return; 984 985 gettimeofday(&bw->bwend, NULL); 986 timersub(&bw->bwend, &bw->bwstart, &bw->bwend); 987 if (!timerisset(&bw->bwend)) 988 return; 989 990 bw->lamt *= 8; 991 waitlen = (double)1000000L * bw->lamt / bw->rate; 992 993 bw->bwstart.tv_sec = waitlen / 1000000L; 994 bw->bwstart.tv_usec = waitlen % 1000000L; 995 996 if (timercmp(&bw->bwstart, &bw->bwend, >)) { 997 timersub(&bw->bwstart, &bw->bwend, &bw->bwend); 998 999 /* Adjust the wait time */ 1000 if (bw->bwend.tv_sec) { 1001 bw->thresh /= 2; 1002 if (bw->thresh < bw->buflen / 4) 1003 bw->thresh = bw->buflen / 4; 1004 } else if (bw->bwend.tv_usec < 10000) { 1005 bw->thresh *= 2; 1006 if (bw->thresh > bw->buflen * 8) 1007 bw->thresh = bw->buflen * 8; 1008 } 1009 1010 TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts); 1011 while (nanosleep(&ts, &rm) == -1) { 1012 if (errno != EINTR) 1013 break; 1014 ts = rm; 1015 } 1016 } 1017 1018 bw->lamt = 0; 1019 gettimeofday(&bw->bwstart, NULL); 1020 } 1021 1022 /* Make a template filename for mk[sd]temp() */ 1023 void 1024 mktemp_proto(char *s, size_t len) 1025 { 1026 const char *tmpdir; 1027 int r; 1028 1029 if ((tmpdir = getenv("TMPDIR")) != NULL) { 1030 r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir); 1031 if (r > 0 && (size_t)r < len) 1032 return; 1033 } 1034 r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX"); 1035 if (r < 0 || (size_t)r >= len) 1036 fatal("%s: template string too short", __func__); 1037 } 1038 1039 static const struct { 1040 const char *name; 1041 int value; 1042 } ipqos[] = { 1043 { "none", INT_MAX }, /* can't use 0 here; that's CS0 */ 1044 { "af11", IPTOS_DSCP_AF11 }, 1045 { "af12", IPTOS_DSCP_AF12 }, 1046 { "af13", IPTOS_DSCP_AF13 }, 1047 { "af21", IPTOS_DSCP_AF21 }, 1048 { "af22", IPTOS_DSCP_AF22 }, 1049 { "af23", IPTOS_DSCP_AF23 }, 1050 { "af31", IPTOS_DSCP_AF31 }, 1051 { "af32", IPTOS_DSCP_AF32 }, 1052 { "af33", IPTOS_DSCP_AF33 }, 1053 { "af41", IPTOS_DSCP_AF41 }, 1054 { "af42", IPTOS_DSCP_AF42 }, 1055 { "af43", IPTOS_DSCP_AF43 }, 1056 { "cs0", IPTOS_DSCP_CS0 }, 1057 { "cs1", IPTOS_DSCP_CS1 }, 1058 { "cs2", IPTOS_DSCP_CS2 }, 1059 { "cs3", IPTOS_DSCP_CS3 }, 1060 { "cs4", IPTOS_DSCP_CS4 }, 1061 { "cs5", IPTOS_DSCP_CS5 }, 1062 { "cs6", IPTOS_DSCP_CS6 }, 1063 { "cs7", IPTOS_DSCP_CS7 }, 1064 { "ef", IPTOS_DSCP_EF }, 1065 { "lowdelay", IPTOS_LOWDELAY }, 1066 { "throughput", IPTOS_THROUGHPUT }, 1067 { "reliability", IPTOS_RELIABILITY }, 1068 { NULL, -1 } 1069 }; 1070 1071 int 1072 parse_ipqos(const char *cp) 1073 { 1074 u_int i; 1075 char *ep; 1076 long val; 1077 1078 if (cp == NULL) 1079 return -1; 1080 for (i = 0; ipqos[i].name != NULL; i++) { 1081 if (strcasecmp(cp, ipqos[i].name) == 0) 1082 return ipqos[i].value; 1083 } 1084 /* Try parsing as an integer */ 1085 val = strtol(cp, &ep, 0); 1086 if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255) 1087 return -1; 1088 return val; 1089 } 1090 1091 const char * 1092 iptos2str(int iptos) 1093 { 1094 int i; 1095 static char iptos_str[sizeof "0xff"]; 1096 1097 for (i = 0; ipqos[i].name != NULL; i++) { 1098 if (ipqos[i].value == iptos) 1099 return ipqos[i].name; 1100 } 1101 snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos); 1102 return iptos_str; 1103 } 1104 1105 void 1106 lowercase(char *s) 1107 { 1108 for (; *s; s++) 1109 *s = tolower((u_char)*s); 1110 } 1111 1112 int 1113 unix_listener(const char *path, int backlog, int unlink_first) 1114 { 1115 struct sockaddr_un sunaddr; 1116 int saved_errno, sock; 1117 1118 memset(&sunaddr, 0, sizeof(sunaddr)); 1119 sunaddr.sun_family = AF_UNIX; 1120 if (strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) { 1121 error("%s: \"%s\" too long for Unix domain socket", __func__, 1122 path); 1123 errno = ENAMETOOLONG; 1124 return -1; 1125 } 1126 1127 sock = socket(PF_UNIX, SOCK_STREAM, 0); 1128 if (sock < 0) { 1129 saved_errno = errno; 1130 error("socket: %.100s", strerror(errno)); 1131 errno = saved_errno; 1132 return -1; 1133 } 1134 if (unlink_first == 1) { 1135 if (unlink(path) != 0 && errno != ENOENT) 1136 error("unlink(%s): %.100s", path, strerror(errno)); 1137 } 1138 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { 1139 saved_errno = errno; 1140 error("bind: %.100s", strerror(errno)); 1141 close(sock); 1142 error("%s: cannot bind to path: %s", __func__, path); 1143 errno = saved_errno; 1144 return -1; 1145 } 1146 if (listen(sock, backlog) < 0) { 1147 saved_errno = errno; 1148 error("listen: %.100s", strerror(errno)); 1149 close(sock); 1150 unlink(path); 1151 error("%s: cannot listen on path: %s", __func__, path); 1152 errno = saved_errno; 1153 return -1; 1154 } 1155 return sock; 1156 } 1157 1158 /* 1159 * Compares two strings that maybe be NULL. Returns non-zero if strings 1160 * are both NULL or are identical, returns zero otherwise. 1161 */ 1162 static int 1163 strcmp_maybe_null(const char *a, const char *b) 1164 { 1165 if ((a == NULL && b != NULL) || (a != NULL && b == NULL)) 1166 return 0; 1167 if (a != NULL && strcmp(a, b) != 0) 1168 return 0; 1169 return 1; 1170 } 1171 1172 /* 1173 * Compare two forwards, returning non-zero if they are identical or 1174 * zero otherwise. 1175 */ 1176 int 1177 forward_equals(const struct Forward *a, const struct Forward *b) 1178 { 1179 if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0) 1180 return 0; 1181 if (a->listen_port != b->listen_port) 1182 return 0; 1183 if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0) 1184 return 0; 1185 if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0) 1186 return 0; 1187 if (a->connect_port != b->connect_port) 1188 return 0; 1189 if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0) 1190 return 0; 1191 /* allocated_port and handle are not checked */ 1192 return 1; 1193 } 1194 1195 /* returns 1 if bind to specified port by specified user is permitted */ 1196 int 1197 bind_permitted(int port, uid_t uid) 1198 { 1199 if (port < IPPORT_RESERVED && uid != 0) 1200 return 0; 1201 return 1; 1202 } 1203 1204 /* returns 1 if process is already daemonized, 0 otherwise */ 1205 int 1206 daemonized(void) 1207 { 1208 int fd; 1209 1210 if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) { 1211 close(fd); 1212 return 0; /* have controlling terminal */ 1213 } 1214 if (getppid() != 1) 1215 return 0; /* parent is not init */ 1216 if (getsid(0) != getpid()) 1217 return 0; /* not session leader */ 1218 debug3("already daemonized"); 1219 return 1; 1220 } 1221 1222 1223 /* 1224 * Splits 's' into an argument vector. Handles quoted string and basic 1225 * escape characters (\\, \", \'). Caller must free the argument vector 1226 * and its members. 1227 */ 1228 int 1229 argv_split(const char *s, int *argcp, char ***argvp) 1230 { 1231 int r = SSH_ERR_INTERNAL_ERROR; 1232 int argc = 0, quote, i, j; 1233 char *arg, **argv = xcalloc(1, sizeof(*argv)); 1234 1235 *argvp = NULL; 1236 *argcp = 0; 1237 1238 for (i = 0; s[i] != '\0'; i++) { 1239 /* Skip leading whitespace */ 1240 if (s[i] == ' ' || s[i] == '\t') 1241 continue; 1242 1243 /* Start of a token */ 1244 quote = 0; 1245 if (s[i] == '\\' && 1246 (s[i + 1] == '\'' || s[i + 1] == '\"' || s[i + 1] == '\\')) 1247 i++; 1248 else if (s[i] == '\'' || s[i] == '"') 1249 quote = s[i++]; 1250 1251 argv = xreallocarray(argv, (argc + 2), sizeof(*argv)); 1252 arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1); 1253 argv[argc] = NULL; 1254 1255 /* Copy the token in, removing escapes */ 1256 for (j = 0; s[i] != '\0'; i++) { 1257 if (s[i] == '\\') { 1258 if (s[i + 1] == '\'' || 1259 s[i + 1] == '\"' || 1260 s[i + 1] == '\\') { 1261 i++; /* Skip '\' */ 1262 arg[j++] = s[i]; 1263 } else { 1264 /* Unrecognised escape */ 1265 arg[j++] = s[i]; 1266 } 1267 } else if (quote == 0 && (s[i] == ' ' || s[i] == '\t')) 1268 break; /* done */ 1269 else if (quote != 0 && s[i] == quote) 1270 break; /* done */ 1271 else 1272 arg[j++] = s[i]; 1273 } 1274 if (s[i] == '\0') { 1275 if (quote != 0) { 1276 /* Ran out of string looking for close quote */ 1277 r = SSH_ERR_INVALID_FORMAT; 1278 goto out; 1279 } 1280 break; 1281 } 1282 } 1283 /* Success */ 1284 *argcp = argc; 1285 *argvp = argv; 1286 argc = 0; 1287 argv = NULL; 1288 r = 0; 1289 out: 1290 if (argc != 0 && argv != NULL) { 1291 for (i = 0; i < argc; i++) 1292 free(argv[i]); 1293 free(argv); 1294 } 1295 return r; 1296 } 1297 1298 /* 1299 * Reassemble an argument vector into a string, quoting and escaping as 1300 * necessary. Caller must free returned string. 1301 */ 1302 char * 1303 argv_assemble(int argc, char **argv) 1304 { 1305 int i, j, ws, r; 1306 char c, *ret; 1307 struct sshbuf *buf, *arg; 1308 1309 if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL) 1310 fatal("%s: sshbuf_new failed", __func__); 1311 1312 for (i = 0; i < argc; i++) { 1313 ws = 0; 1314 sshbuf_reset(arg); 1315 for (j = 0; argv[i][j] != '\0'; j++) { 1316 r = 0; 1317 c = argv[i][j]; 1318 switch (c) { 1319 case ' ': 1320 case '\t': 1321 ws = 1; 1322 r = sshbuf_put_u8(arg, c); 1323 break; 1324 case '\\': 1325 case '\'': 1326 case '"': 1327 if ((r = sshbuf_put_u8(arg, '\\')) != 0) 1328 break; 1329 /* FALLTHROUGH */ 1330 default: 1331 r = sshbuf_put_u8(arg, c); 1332 break; 1333 } 1334 if (r != 0) 1335 fatal("%s: sshbuf_put_u8: %s", 1336 __func__, ssh_err(r)); 1337 } 1338 if ((i != 0 && (r = sshbuf_put_u8(buf, ' ')) != 0) || 1339 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) || 1340 (r = sshbuf_putb(buf, arg)) != 0 || 1341 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0)) 1342 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1343 } 1344 if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL) 1345 fatal("%s: malloc failed", __func__); 1346 memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf)); 1347 ret[sshbuf_len(buf)] = '\0'; 1348 sshbuf_free(buf); 1349 sshbuf_free(arg); 1350 return ret; 1351 } 1352 1353 /* 1354 * Runs command in a subprocess wuth a minimal environment. 1355 * Returns pid on success, 0 on failure. 1356 * The child stdout and stderr maybe captured, left attached or sent to 1357 * /dev/null depending on the contents of flags. 1358 * "tag" is prepended to log messages. 1359 * NB. "command" is only used for logging; the actual command executed is 1360 * av[0]. 1361 */ 1362 pid_t 1363 subprocess(const char *tag, struct passwd *pw, const char *command, 1364 int ac, char **av, FILE **child, u_int flags) 1365 { 1366 FILE *f = NULL; 1367 struct stat st; 1368 int fd, devnull, p[2], i; 1369 pid_t pid; 1370 char *cp, errmsg[512]; 1371 u_int envsize; 1372 char **child_env; 1373 1374 if (child != NULL) 1375 *child = NULL; 1376 1377 debug3("%s: %s command \"%s\" running as %s (flags 0x%x)", __func__, 1378 tag, command, pw->pw_name, flags); 1379 1380 /* Check consistency */ 1381 if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 && 1382 (flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) { 1383 error("%s: inconsistent flags", __func__); 1384 return 0; 1385 } 1386 if (((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0) != (child == NULL)) { 1387 error("%s: inconsistent flags/output", __func__); 1388 return 0; 1389 } 1390 1391 /* 1392 * If executing an explicit binary, then verify the it exists 1393 * and appears safe-ish to execute 1394 */ 1395 if (*av[0] != '/') { 1396 error("%s path is not absolute", tag); 1397 return 0; 1398 } 1399 temporarily_use_uid(pw); 1400 if (stat(av[0], &st) < 0) { 1401 error("Could not stat %s \"%s\": %s", tag, 1402 av[0], strerror(errno)); 1403 restore_uid(); 1404 return 0; 1405 } 1406 if (safe_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) { 1407 error("Unsafe %s \"%s\": %s", tag, av[0], errmsg); 1408 restore_uid(); 1409 return 0; 1410 } 1411 /* Prepare to keep the child's stdout if requested */ 1412 if (pipe(p) != 0) { 1413 error("%s: pipe: %s", tag, strerror(errno)); 1414 restore_uid(); 1415 return 0; 1416 } 1417 restore_uid(); 1418 1419 switch ((pid = fork())) { 1420 case -1: /* error */ 1421 error("%s: fork: %s", tag, strerror(errno)); 1422 close(p[0]); 1423 close(p[1]); 1424 return 0; 1425 case 0: /* child */ 1426 /* Prepare a minimal environment for the child. */ 1427 envsize = 5; 1428 child_env = xcalloc(sizeof(*child_env), envsize); 1429 child_set_env(&child_env, &envsize, "PATH", _PATH_STDPATH); 1430 child_set_env(&child_env, &envsize, "USER", pw->pw_name); 1431 child_set_env(&child_env, &envsize, "LOGNAME", pw->pw_name); 1432 child_set_env(&child_env, &envsize, "HOME", pw->pw_dir); 1433 if ((cp = getenv("LANG")) != NULL) 1434 child_set_env(&child_env, &envsize, "LANG", cp); 1435 1436 for (i = 0; i < NSIG; i++) 1437 signal(i, SIG_DFL); 1438 1439 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { 1440 error("%s: open %s: %s", tag, _PATH_DEVNULL, 1441 strerror(errno)); 1442 _exit(1); 1443 } 1444 if (dup2(devnull, STDIN_FILENO) == -1) { 1445 error("%s: dup2: %s", tag, strerror(errno)); 1446 _exit(1); 1447 } 1448 1449 /* Set up stdout as requested; leave stderr in place for now. */ 1450 fd = -1; 1451 if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) 1452 fd = p[1]; 1453 else if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0) 1454 fd = devnull; 1455 if (fd != -1 && dup2(fd, STDOUT_FILENO) == -1) { 1456 error("%s: dup2: %s", tag, strerror(errno)); 1457 _exit(1); 1458 } 1459 closefrom(STDERR_FILENO + 1); 1460 1461 /* Don't use permanently_set_uid() here to avoid fatal() */ 1462 if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) { 1463 error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid, 1464 strerror(errno)); 1465 _exit(1); 1466 } 1467 if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) { 1468 error("%s: setresuid %u: %s", tag, (u_int)pw->pw_uid, 1469 strerror(errno)); 1470 _exit(1); 1471 } 1472 /* stdin is pointed to /dev/null at this point */ 1473 if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 && 1474 dup2(STDIN_FILENO, STDERR_FILENO) == -1) { 1475 error("%s: dup2: %s", tag, strerror(errno)); 1476 _exit(1); 1477 } 1478 1479 execve(av[0], av, child_env); 1480 error("%s exec \"%s\": %s", tag, command, strerror(errno)); 1481 _exit(127); 1482 default: /* parent */ 1483 break; 1484 } 1485 1486 close(p[1]); 1487 if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0) 1488 close(p[0]); 1489 else if ((f = fdopen(p[0], "r")) == NULL) { 1490 error("%s: fdopen: %s", tag, strerror(errno)); 1491 close(p[0]); 1492 /* Don't leave zombie child */ 1493 kill(pid, SIGTERM); 1494 while (waitpid(pid, NULL, 0) == -1 && errno == EINTR) 1495 ; 1496 return 0; 1497 } 1498 /* Success */ 1499 debug3("%s: %s pid %ld", __func__, tag, (long)pid); 1500 if (child != NULL) 1501 *child = f; 1502 return pid; 1503 } 1504 1505 /* Returns 0 if pid exited cleanly, non-zero otherwise */ 1506 int 1507 exited_cleanly(pid_t pid, const char *tag, const char *cmd, int quiet) 1508 { 1509 int status; 1510 1511 while (waitpid(pid, &status, 0) == -1) { 1512 if (errno != EINTR) { 1513 error("%s: waitpid: %s", tag, strerror(errno)); 1514 return -1; 1515 } 1516 } 1517 if (WIFSIGNALED(status)) { 1518 error("%s %s exited on signal %d", tag, cmd, WTERMSIG(status)); 1519 return -1; 1520 } else if (WEXITSTATUS(status) != 0) { 1521 do_log2(quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO, 1522 "%s %s failed, status %d", tag, cmd, WEXITSTATUS(status)); 1523 return -1; 1524 } 1525 return 0; 1526 } 1527 1528 /* 1529 * Check a given path for security. This is defined as all components 1530 * of the path to the file must be owned by either the owner of 1531 * of the file or root and no directories must be group or world writable. 1532 * 1533 * XXX Should any specific check be done for sym links ? 1534 * 1535 * Takes a file name, its stat information (preferably from fstat() to 1536 * avoid races), the uid of the expected owner, their home directory and an 1537 * error buffer plus max size as arguments. 1538 * 1539 * Returns 0 on success and -1 on failure 1540 */ 1541 int 1542 safe_path(const char *name, struct stat *stp, const char *pw_dir, 1543 uid_t uid, char *err, size_t errlen) 1544 { 1545 char buf[PATH_MAX], homedir[PATH_MAX]; 1546 char *cp; 1547 int comparehome = 0; 1548 struct stat st; 1549 1550 if (realpath(name, buf) == NULL) { 1551 snprintf(err, errlen, "realpath %s failed: %s", name, 1552 strerror(errno)); 1553 return -1; 1554 } 1555 if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) 1556 comparehome = 1; 1557 1558 if (!S_ISREG(stp->st_mode)) { 1559 snprintf(err, errlen, "%s is not a regular file", buf); 1560 return -1; 1561 } 1562 if ((stp->st_uid != 0 && stp->st_uid != uid) || 1563 (stp->st_mode & 022) != 0) { 1564 snprintf(err, errlen, "bad ownership or modes for file %s", 1565 buf); 1566 return -1; 1567 } 1568 1569 /* for each component of the canonical path, walking upwards */ 1570 for (;;) { 1571 if ((cp = dirname(buf)) == NULL) { 1572 snprintf(err, errlen, "dirname() failed"); 1573 return -1; 1574 } 1575 strlcpy(buf, cp, sizeof(buf)); 1576 1577 if (stat(buf, &st) < 0 || 1578 (st.st_uid != 0 && st.st_uid != uid) || 1579 (st.st_mode & 022) != 0) { 1580 snprintf(err, errlen, 1581 "bad ownership or modes for directory %s", buf); 1582 return -1; 1583 } 1584 1585 /* If are past the homedir then we can stop */ 1586 if (comparehome && strcmp(homedir, buf) == 0) 1587 break; 1588 1589 /* 1590 * dirname should always complete with a "/" path, 1591 * but we can be paranoid and check for "." too 1592 */ 1593 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) 1594 break; 1595 } 1596 return 0; 1597 } 1598 1599 /* 1600 * Version of safe_path() that accepts an open file descriptor to 1601 * avoid races. 1602 * 1603 * Returns 0 on success and -1 on failure 1604 */ 1605 int 1606 safe_path_fd(int fd, const char *file, struct passwd *pw, 1607 char *err, size_t errlen) 1608 { 1609 struct stat st; 1610 1611 /* check the open file to avoid races */ 1612 if (fstat(fd, &st) < 0) { 1613 snprintf(err, errlen, "cannot stat file %s: %s", 1614 file, strerror(errno)); 1615 return -1; 1616 } 1617 return safe_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); 1618 } 1619 1620 /* 1621 * Sets the value of the given variable in the environment. If the variable 1622 * already exists, its value is overridden. 1623 */ 1624 void 1625 child_set_env(char ***envp, u_int *envsizep, const char *name, 1626 const char *value) 1627 { 1628 char **env; 1629 u_int envsize; 1630 u_int i, namelen; 1631 1632 if (strchr(name, '=') != NULL) { 1633 error("Invalid environment variable \"%.100s\"", name); 1634 return; 1635 } 1636 1637 /* 1638 * Find the slot where the value should be stored. If the variable 1639 * already exists, we reuse the slot; otherwise we append a new slot 1640 * at the end of the array, expanding if necessary. 1641 */ 1642 env = *envp; 1643 namelen = strlen(name); 1644 for (i = 0; env[i]; i++) 1645 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') 1646 break; 1647 if (env[i]) { 1648 /* Reuse the slot. */ 1649 free(env[i]); 1650 } else { 1651 /* New variable. Expand if necessary. */ 1652 envsize = *envsizep; 1653 if (i >= envsize - 1) { 1654 if (envsize >= 1000) 1655 fatal("child_set_env: too many env vars"); 1656 envsize += 50; 1657 env = (*envp) = xreallocarray(env, envsize, sizeof(char *)); 1658 *envsizep = envsize; 1659 } 1660 /* Need to set the NULL pointer at end of array beyond the new slot. */ 1661 env[i + 1] = NULL; 1662 } 1663 1664 /* Allocate space and format the variable in the appropriate slot. */ 1665 env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); 1666 snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); 1667 } 1668 1669