1 /* $NetBSD: misc.c,v 1.13 2016/08/02 13:45:12 christos Exp $ */ 2 /* $OpenBSD: misc.c,v 1.105 2016/07/15 00:24:30 djm Exp $ */ 3 /* 4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 5 * Copyright (c) 2005,2006 Damien Miller. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "includes.h" 29 __RCSID("$NetBSD: misc.c,v 1.13 2016/08/02 13:45:12 christos Exp $"); 30 #include <sys/types.h> 31 #include <sys/ioctl.h> 32 #include <sys/socket.h> 33 #include <sys/time.h> 34 #include <sys/un.h> 35 36 #include <net/if.h> 37 #include <net/if_tun.h> 38 #include <netinet/in.h> 39 #include <netinet/ip.h> 40 #include <netinet/tcp.h> 41 42 #include <ctype.h> 43 #include <errno.h> 44 #include <fcntl.h> 45 #include <netdb.h> 46 #include <paths.h> 47 #include <pwd.h> 48 #include <limits.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 60 /* remove newline at end of string */ 61 char * 62 chop(char *s) 63 { 64 char *t = s; 65 while (*t) { 66 if (*t == '\n' || *t == '\r') { 67 *t = '\0'; 68 return s; 69 } 70 t++; 71 } 72 return s; 73 74 } 75 76 /* set/unset filedescriptor to non-blocking */ 77 int 78 set_nonblock(int fd) 79 { 80 int val; 81 82 val = fcntl(fd, F_GETFL); 83 if (val < 0) { 84 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); 85 return (-1); 86 } 87 if (val & O_NONBLOCK) { 88 debug3("fd %d is O_NONBLOCK", fd); 89 return (0); 90 } 91 debug2("fd %d setting O_NONBLOCK", fd); 92 val |= O_NONBLOCK; 93 if (fcntl(fd, F_SETFL, val) == -1) { 94 debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, 95 strerror(errno)); 96 return (-1); 97 } 98 return (0); 99 } 100 101 int 102 unset_nonblock(int fd) 103 { 104 int val; 105 106 val = fcntl(fd, F_GETFL); 107 if (val < 0) { 108 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); 109 return (-1); 110 } 111 if (!(val & O_NONBLOCK)) { 112 debug3("fd %d is not O_NONBLOCK", fd); 113 return (0); 114 } 115 debug("fd %d clearing O_NONBLOCK", fd); 116 val &= ~O_NONBLOCK; 117 if (fcntl(fd, F_SETFL, val) == -1) { 118 debug("fcntl(%d, F_SETFL, ~O_NONBLOCK): %s", 119 fd, strerror(errno)); 120 return (-1); 121 } 122 return (0); 123 } 124 125 const char * 126 ssh_gai_strerror(int gaierr) 127 { 128 if (gaierr == EAI_SYSTEM && errno != 0) 129 return strerror(errno); 130 return gai_strerror(gaierr); 131 } 132 133 /* disable nagle on socket */ 134 void 135 set_nodelay(int fd) 136 { 137 int opt; 138 socklen_t optlen; 139 140 optlen = sizeof opt; 141 if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) { 142 debug("getsockopt TCP_NODELAY: %.100s", strerror(errno)); 143 return; 144 } 145 if (opt == 1) { 146 debug2("fd %d is TCP_NODELAY", fd); 147 return; 148 } 149 opt = 1; 150 debug2("fd %d setting TCP_NODELAY", fd); 151 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1) 152 error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); 153 } 154 155 /* Characters considered whitespace in strsep calls. */ 156 #define WHITESPACE " \t\r\n" 157 #define QUOTE "\"" 158 159 /* return next token in configuration line */ 160 char * 161 strdelim(char **s) 162 { 163 char *old; 164 int wspace = 0; 165 166 if (*s == NULL) 167 return NULL; 168 169 old = *s; 170 171 *s = strpbrk(*s, WHITESPACE QUOTE "="); 172 if (*s == NULL) 173 return (old); 174 175 if (*s[0] == '\"') { 176 memmove(*s, *s + 1, strlen(*s)); /* move nul too */ 177 /* Find matching quote */ 178 if ((*s = strpbrk(*s, QUOTE)) == NULL) { 179 return (NULL); /* no matching quote */ 180 } else { 181 *s[0] = '\0'; 182 *s += strspn(*s + 1, WHITESPACE) + 1; 183 return (old); 184 } 185 } 186 187 /* Allow only one '=' to be skipped */ 188 if (*s[0] == '=') 189 wspace = 1; 190 *s[0] = '\0'; 191 192 /* Skip any extra whitespace after first token */ 193 *s += strspn(*s + 1, WHITESPACE) + 1; 194 if (*s[0] == '=' && !wspace) 195 *s += strspn(*s + 1, WHITESPACE) + 1; 196 197 return (old); 198 } 199 200 struct passwd * 201 pwcopy(struct passwd *pw) 202 { 203 struct passwd *copy = xcalloc(1, sizeof(*copy)); 204 205 copy->pw_name = xstrdup(pw->pw_name); 206 copy->pw_passwd = xstrdup(pw->pw_passwd); 207 copy->pw_gecos = xstrdup(pw->pw_gecos); 208 copy->pw_uid = pw->pw_uid; 209 copy->pw_gid = pw->pw_gid; 210 copy->pw_expire = pw->pw_expire; 211 copy->pw_change = pw->pw_change; 212 copy->pw_class = xstrdup(pw->pw_class); 213 copy->pw_dir = xstrdup(pw->pw_dir); 214 copy->pw_shell = xstrdup(pw->pw_shell); 215 return copy; 216 } 217 218 /* 219 * Convert ASCII string to TCP/IP port number. 220 * Port must be >=0 and <=65535. 221 * Return -1 if invalid. 222 */ 223 int 224 a2port(const char *s) 225 { 226 long long port; 227 const char *errstr; 228 229 port = strtonum(s, 0, 65535, &errstr); 230 if (errstr != NULL) 231 return -1; 232 return (int)port; 233 } 234 235 int 236 a2tun(const char *s, int *remote) 237 { 238 const char *errstr = NULL; 239 char *sp, *ep; 240 int tun; 241 242 if (remote != NULL) { 243 *remote = SSH_TUNID_ANY; 244 sp = xstrdup(s); 245 if ((ep = strchr(sp, ':')) == NULL) { 246 free(sp); 247 return (a2tun(s, NULL)); 248 } 249 ep[0] = '\0'; ep++; 250 *remote = a2tun(ep, NULL); 251 tun = a2tun(sp, NULL); 252 free(sp); 253 return (*remote == SSH_TUNID_ERR ? *remote : tun); 254 } 255 256 if (strcasecmp(s, "any") == 0) 257 return (SSH_TUNID_ANY); 258 259 tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr); 260 if (errstr != NULL) 261 return (SSH_TUNID_ERR); 262 263 return (tun); 264 } 265 266 #define SECONDS 1 267 #define MINUTES (SECONDS * 60) 268 #define HOURS (MINUTES * 60) 269 #define DAYS (HOURS * 24) 270 #define WEEKS (DAYS * 7) 271 272 /* 273 * Convert a time string into seconds; format is 274 * a sequence of: 275 * time[qualifier] 276 * 277 * Valid time qualifiers are: 278 * <none> seconds 279 * s|S seconds 280 * m|M minutes 281 * h|H hours 282 * d|D days 283 * w|W weeks 284 * 285 * Examples: 286 * 90m 90 minutes 287 * 1h30m 90 minutes 288 * 2d 2 days 289 * 1w 1 week 290 * 291 * Return -1 if time string is invalid. 292 */ 293 long 294 convtime(const char *s) 295 { 296 long total, secs; 297 const char *p; 298 char *endp; 299 300 errno = 0; 301 total = 0; 302 p = s; 303 304 if (p == NULL || *p == '\0') 305 return -1; 306 307 while (*p) { 308 secs = strtol(p, &endp, 10); 309 if (p == endp || 310 (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) || 311 secs < 0) 312 return -1; 313 314 switch (*endp++) { 315 case '\0': 316 endp--; 317 break; 318 case 's': 319 case 'S': 320 break; 321 case 'm': 322 case 'M': 323 secs *= MINUTES; 324 break; 325 case 'h': 326 case 'H': 327 secs *= HOURS; 328 break; 329 case 'd': 330 case 'D': 331 secs *= DAYS; 332 break; 333 case 'w': 334 case 'W': 335 secs *= WEEKS; 336 break; 337 default: 338 return -1; 339 } 340 total += secs; 341 if (total < 0) 342 return -1; 343 p = endp; 344 } 345 346 return total; 347 } 348 349 /* 350 * Returns a standardized host+port identifier string. 351 * Caller must free returned string. 352 */ 353 char * 354 put_host_port(const char *host, u_short port) 355 { 356 char *hoststr; 357 358 if (port == 0 || port == SSH_DEFAULT_PORT) 359 return(xstrdup(host)); 360 if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0) 361 fatal("put_host_port: asprintf: %s", strerror(errno)); 362 debug3("put_host_port: %s", hoststr); 363 return hoststr; 364 } 365 366 /* 367 * Search for next delimiter between hostnames/addresses and ports. 368 * Argument may be modified (for termination). 369 * Returns *cp if parsing succeeds. 370 * *cp is set to the start of the next delimiter, if one was found. 371 * If this is the last field, *cp is set to NULL. 372 */ 373 char * 374 hpdelim(char **cp) 375 { 376 char *s, *old; 377 378 if (cp == NULL || *cp == NULL) 379 return NULL; 380 381 old = s = *cp; 382 if (*s == '[') { 383 if ((s = strchr(s, ']')) == NULL) 384 return NULL; 385 else 386 s++; 387 } else if ((s = strpbrk(s, ":/")) == NULL) 388 s = *cp + strlen(*cp); /* skip to end (see first case below) */ 389 390 switch (*s) { 391 case '\0': 392 *cp = NULL; /* no more fields*/ 393 break; 394 395 case ':': 396 case '/': 397 *s = '\0'; /* terminate */ 398 *cp = s + 1; 399 break; 400 401 default: 402 return NULL; 403 } 404 405 return old; 406 } 407 408 char * 409 cleanhostname(char *host) 410 { 411 if (*host == '[' && host[strlen(host) - 1] == ']') { 412 host[strlen(host) - 1] = '\0'; 413 return (host + 1); 414 } else 415 return host; 416 } 417 418 char * 419 colon(char *cp) 420 { 421 int flag = 0; 422 423 if (*cp == ':') /* Leading colon is part of file name. */ 424 return NULL; 425 if (*cp == '[') 426 flag = 1; 427 428 for (; *cp; ++cp) { 429 if (*cp == '@' && *(cp+1) == '[') 430 flag = 1; 431 if (*cp == ']' && *(cp+1) == ':' && flag) 432 return (cp+1); 433 if (*cp == ':' && !flag) 434 return (cp); 435 if (*cp == '/') 436 return NULL; 437 } 438 return NULL; 439 } 440 441 /* 442 * Parse a [user@]host[:port] string. 443 * Caller must free returned user and host. 444 * Any of the pointer return arguments may be NULL (useful for syntax checking). 445 * If user was not specified then *userp will be set to NULL. 446 * If port was not specified then *portp will be -1. 447 * Returns 0 on success, -1 on failure. 448 */ 449 int 450 parse_user_host_port(const char *s, char **userp, char **hostp, int *portp) 451 { 452 char *sdup, *cp, *tmp; 453 char *user = NULL, *host = NULL; 454 int port = -1, ret = -1; 455 456 if (userp != NULL) 457 *userp = NULL; 458 if (hostp != NULL) 459 *hostp = NULL; 460 if (portp != NULL) 461 *portp = -1; 462 463 if ((sdup = tmp = strdup(s)) == NULL) 464 return -1; 465 /* Extract optional username */ 466 if ((cp = strchr(tmp, '@')) != NULL) { 467 *cp = '\0'; 468 if (*tmp == '\0') 469 goto out; 470 if ((user = strdup(tmp)) == NULL) 471 goto out; 472 tmp = cp + 1; 473 } 474 /* Extract mandatory hostname */ 475 if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0') 476 goto out; 477 host = xstrdup(cleanhostname(cp)); 478 /* Convert and verify optional port */ 479 if (tmp != NULL && *tmp != '\0') { 480 if ((port = a2port(tmp)) <= 0) 481 goto out; 482 } 483 /* Success */ 484 if (userp != NULL) { 485 *userp = user; 486 user = NULL; 487 } 488 if (hostp != NULL) { 489 *hostp = host; 490 host = NULL; 491 } 492 if (portp != NULL) 493 *portp = port; 494 ret = 0; 495 out: 496 free(sdup); 497 free(user); 498 free(host); 499 return ret; 500 } 501 502 /* function to assist building execv() arguments */ 503 void 504 addargs(arglist *args, const char *fmt, ...) 505 { 506 va_list ap; 507 char *cp; 508 u_int nalloc; 509 int r; 510 511 va_start(ap, fmt); 512 r = vasprintf(&cp, fmt, ap); 513 va_end(ap); 514 if (r == -1) 515 fatal("addargs: argument too long"); 516 517 nalloc = args->nalloc; 518 if (args->list == NULL) { 519 nalloc = 32; 520 args->num = 0; 521 } else if (args->num+2 >= nalloc) 522 nalloc *= 2; 523 524 args->list = xreallocarray(args->list, nalloc, sizeof(char *)); 525 args->nalloc = nalloc; 526 args->list[args->num++] = cp; 527 args->list[args->num] = NULL; 528 } 529 530 void 531 replacearg(arglist *args, u_int which, const char *fmt, ...) 532 { 533 va_list ap; 534 char *cp; 535 int r; 536 537 va_start(ap, fmt); 538 r = vasprintf(&cp, fmt, ap); 539 va_end(ap); 540 if (r == -1) 541 fatal("replacearg: argument too long"); 542 543 if (which >= args->num) 544 fatal("replacearg: tried to replace invalid arg %d >= %d", 545 which, args->num); 546 free(args->list[which]); 547 args->list[which] = cp; 548 } 549 550 void 551 freeargs(arglist *args) 552 { 553 u_int i; 554 555 if (args->list != NULL) { 556 for (i = 0; i < args->num; i++) 557 free(args->list[i]); 558 free(args->list); 559 args->nalloc = args->num = 0; 560 args->list = NULL; 561 } 562 } 563 564 /* 565 * Expands tildes in the file name. Returns data allocated by xmalloc. 566 * Warning: this calls getpw*. 567 */ 568 char * 569 tilde_expand_filename(const char *filename, uid_t uid) 570 { 571 const char *path, *sep; 572 char user[128], *ret, *homedir; 573 struct passwd *pw; 574 u_int len, slash; 575 576 if (*filename != '~') 577 return (xstrdup(filename)); 578 filename++; 579 580 path = strchr(filename, '/'); 581 if (path != NULL && path > filename) { /* ~user/path */ 582 slash = path - filename; 583 if (slash > sizeof(user) - 1) 584 fatal("tilde_expand_filename: ~username too long"); 585 memcpy(user, filename, slash); 586 user[slash] = '\0'; 587 if ((pw = getpwnam(user)) == NULL) 588 fatal("tilde_expand_filename: No such user %s", user); 589 homedir = pw->pw_dir; 590 } else { 591 if ((pw = getpwuid(uid)) == NULL) /* ~/path */ 592 fatal("tilde_expand_filename: No such uid %ld", 593 (long)uid); 594 homedir = pw->pw_dir; 595 } 596 597 /* Make sure directory has a trailing '/' */ 598 len = strlen(homedir); 599 if (len == 0 || homedir[len - 1] != '/') 600 sep = "/"; 601 else 602 sep = ""; 603 604 /* Skip leading '/' from specified path */ 605 if (path != NULL) 606 filename = path + 1; 607 608 if (xasprintf(&ret, "%s%s%s", homedir, sep, filename) >= PATH_MAX) 609 fatal("tilde_expand_filename: Path too long"); 610 611 return (ret); 612 } 613 614 /* 615 * Expand a string with a set of %[char] escapes. A number of escapes may be 616 * specified as (char *escape_chars, char *replacement) pairs. The list must 617 * be terminated by a NULL escape_char. Returns replaced string in memory 618 * allocated by xmalloc. 619 */ 620 char * 621 percent_expand(const char *string, ...) 622 { 623 #define EXPAND_MAX_KEYS 16 624 u_int num_keys, i, j; 625 struct { 626 const char *key; 627 const char *repl; 628 } keys[EXPAND_MAX_KEYS]; 629 char buf[4096]; 630 va_list ap; 631 632 /* Gather keys */ 633 va_start(ap, string); 634 for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) { 635 keys[num_keys].key = va_arg(ap, char *); 636 if (keys[num_keys].key == NULL) 637 break; 638 keys[num_keys].repl = va_arg(ap, char *); 639 if (keys[num_keys].repl == NULL) 640 fatal("%s: NULL replacement", __func__); 641 } 642 if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL) 643 fatal("%s: too many keys", __func__); 644 va_end(ap); 645 646 /* Expand string */ 647 *buf = '\0'; 648 for (i = 0; *string != '\0'; string++) { 649 if (*string != '%') { 650 append: 651 buf[i++] = *string; 652 if (i >= sizeof(buf)) 653 fatal("%s: string too long", __func__); 654 buf[i] = '\0'; 655 continue; 656 } 657 string++; 658 /* %% case */ 659 if (*string == '%') 660 goto append; 661 if (*string == '\0') 662 fatal("%s: invalid format", __func__); 663 for (j = 0; j < num_keys; j++) { 664 if (strchr(keys[j].key, *string) != NULL) { 665 i = strlcat(buf, keys[j].repl, sizeof(buf)); 666 if (i >= sizeof(buf)) 667 fatal("%s: string too long", __func__); 668 break; 669 } 670 } 671 if (j >= num_keys) 672 fatal("%s: unknown key %%%c", __func__, *string); 673 } 674 return (xstrdup(buf)); 675 #undef EXPAND_MAX_KEYS 676 } 677 678 /* 679 * Read an entire line from a public key file into a static buffer, discarding 680 * lines that exceed the buffer size. Returns 0 on success, -1 on failure. 681 */ 682 int 683 read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz, 684 u_long *lineno) 685 { 686 while (fgets(buf, bufsz, f) != NULL) { 687 if (buf[0] == '\0') 688 continue; 689 (*lineno)++; 690 if (buf[strlen(buf) - 1] == '\n' || feof(f)) { 691 return 0; 692 } else { 693 debug("%s: %s line %lu exceeds size limit", __func__, 694 filename, *lineno); 695 /* discard remainder of line */ 696 while (fgetc(f) != '\n' && !feof(f)) 697 ; /* nothing */ 698 } 699 } 700 return -1; 701 } 702 703 int 704 tun_open(int tun, int mode) 705 { 706 struct ifreq ifr; 707 char name[100]; 708 int fd = -1, sock; 709 const char *tunbase = "tun"; 710 711 if (mode == SSH_TUNMODE_ETHERNET) 712 tunbase = "tap"; 713 714 /* Open the tunnel device */ 715 if (tun <= SSH_TUNID_MAX) { 716 snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); 717 fd = open(name, O_RDWR); 718 } else if (tun == SSH_TUNID_ANY) { 719 for (tun = 100; tun >= 0; tun--) { 720 snprintf(name, sizeof(name), "/dev/%s%d", 721 tunbase, tun); 722 if ((fd = open(name, O_RDWR)) >= 0) 723 break; 724 } 725 } else { 726 debug("%s: invalid tunnel %u", __func__, tun); 727 return -1; 728 } 729 730 if (fd < 0) { 731 debug("%s: %s open: %s", __func__, name, strerror(errno)); 732 return -1; 733 } 734 735 736 #ifdef TUNSIFHEAD 737 /* Turn on tunnel headers */ 738 int flag = 1; 739 if (mode != SSH_TUNMODE_ETHERNET && 740 ioctl(fd, TUNSIFHEAD, &flag) == -1) { 741 debug("%s: ioctl(%d, TUNSIFHEAD, 1): %s", __func__, fd, 742 strerror(errno)); 743 close(fd); 744 return -1; 745 } 746 #endif 747 748 debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd); 749 /* Bring interface up if it is not already */ 750 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); 751 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) 752 goto failed; 753 754 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { 755 debug("%s: get interface %s flags: %s", __func__, 756 ifr.ifr_name, strerror(errno)); 757 goto failed; 758 } 759 760 if (!(ifr.ifr_flags & IFF_UP)) { 761 ifr.ifr_flags |= IFF_UP; 762 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { 763 debug("%s: activate interface %s: %s", __func__, 764 ifr.ifr_name, strerror(errno)); 765 goto failed; 766 } 767 } 768 769 close(sock); 770 return fd; 771 772 failed: 773 if (fd >= 0) 774 close(fd); 775 if (sock >= 0) 776 close(sock); 777 debug("%s: failed to set %s mode %d: %s", __func__, ifr.ifr_name, 778 mode, strerror(errno)); 779 return -1; 780 } 781 782 void 783 sanitise_stdfd(void) 784 { 785 int nullfd, dupfd; 786 787 if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) { 788 fprintf(stderr, "Couldn't open /dev/null: %s\n", 789 strerror(errno)); 790 exit(1); 791 } 792 while (++dupfd <= STDERR_FILENO) { 793 /* Only populate closed fds. */ 794 if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) { 795 if (dup2(nullfd, dupfd) == -1) { 796 fprintf(stderr, "dup2: %s\n", strerror(errno)); 797 exit(1); 798 } 799 } 800 } 801 if (nullfd > STDERR_FILENO) 802 close(nullfd); 803 } 804 805 char * 806 tohex(const void *vp, size_t l) 807 { 808 const u_char *p = (const u_char *)vp; 809 char b[3], *r; 810 size_t i, hl; 811 812 if (l > 65536) 813 return xstrdup("tohex: length > 65536"); 814 815 hl = l * 2 + 1; 816 r = xcalloc(1, hl); 817 for (i = 0; i < l; i++) { 818 snprintf(b, sizeof(b), "%02x", p[i]); 819 strlcat(r, b, hl); 820 } 821 return (r); 822 } 823 824 u_int64_t 825 get_u64(const void *vp) 826 { 827 const u_char *p = (const u_char *)vp; 828 u_int64_t v; 829 830 v = (u_int64_t)p[0] << 56; 831 v |= (u_int64_t)p[1] << 48; 832 v |= (u_int64_t)p[2] << 40; 833 v |= (u_int64_t)p[3] << 32; 834 v |= (u_int64_t)p[4] << 24; 835 v |= (u_int64_t)p[5] << 16; 836 v |= (u_int64_t)p[6] << 8; 837 v |= (u_int64_t)p[7]; 838 839 return (v); 840 } 841 842 u_int32_t 843 get_u32(const void *vp) 844 { 845 const u_char *p = (const u_char *)vp; 846 u_int32_t v; 847 848 v = (u_int32_t)p[0] << 24; 849 v |= (u_int32_t)p[1] << 16; 850 v |= (u_int32_t)p[2] << 8; 851 v |= (u_int32_t)p[3]; 852 853 return (v); 854 } 855 856 u_int32_t 857 get_u32_le(const void *vp) 858 { 859 const u_char *p = (const u_char *)vp; 860 u_int32_t v; 861 862 v = (u_int32_t)p[0]; 863 v |= (u_int32_t)p[1] << 8; 864 v |= (u_int32_t)p[2] << 16; 865 v |= (u_int32_t)p[3] << 24; 866 867 return (v); 868 } 869 870 u_int16_t 871 get_u16(const void *vp) 872 { 873 const u_char *p = (const u_char *)vp; 874 u_int16_t v; 875 876 v = (u_int16_t)p[0] << 8; 877 v |= (u_int16_t)p[1]; 878 879 return (v); 880 } 881 882 void 883 put_u64(void *vp, u_int64_t v) 884 { 885 u_char *p = (u_char *)vp; 886 887 p[0] = (u_char)(v >> 56) & 0xff; 888 p[1] = (u_char)(v >> 48) & 0xff; 889 p[2] = (u_char)(v >> 40) & 0xff; 890 p[3] = (u_char)(v >> 32) & 0xff; 891 p[4] = (u_char)(v >> 24) & 0xff; 892 p[5] = (u_char)(v >> 16) & 0xff; 893 p[6] = (u_char)(v >> 8) & 0xff; 894 p[7] = (u_char)v & 0xff; 895 } 896 897 void 898 put_u32(void *vp, u_int32_t v) 899 { 900 u_char *p = (u_char *)vp; 901 902 p[0] = (u_char)(v >> 24) & 0xff; 903 p[1] = (u_char)(v >> 16) & 0xff; 904 p[2] = (u_char)(v >> 8) & 0xff; 905 p[3] = (u_char)v & 0xff; 906 } 907 908 void 909 put_u32_le(void *vp, u_int32_t v) 910 { 911 u_char *p = (u_char *)vp; 912 913 p[0] = (u_char)v & 0xff; 914 p[1] = (u_char)(v >> 8) & 0xff; 915 p[2] = (u_char)(v >> 16) & 0xff; 916 p[3] = (u_char)(v >> 24) & 0xff; 917 } 918 919 void 920 put_u16(void *vp, u_int16_t v) 921 { 922 u_char *p = (u_char *)vp; 923 924 p[0] = (u_char)(v >> 8) & 0xff; 925 p[1] = (u_char)v & 0xff; 926 } 927 928 void 929 ms_subtract_diff(struct timeval *start, int *ms) 930 { 931 struct timeval diff, finish; 932 933 gettimeofday(&finish, NULL); 934 timersub(&finish, start, &diff); 935 *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); 936 } 937 938 void 939 ms_to_timeval(struct timeval *tv, int ms) 940 { 941 if (ms < 0) 942 ms = 0; 943 tv->tv_sec = ms / 1000; 944 tv->tv_usec = (ms % 1000) * 1000; 945 } 946 947 time_t 948 monotime(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); 956 } 957 958 double 959 monotime_double(void) 960 { 961 struct timespec ts; 962 963 if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) 964 fatal("clock_gettime: %s", strerror(errno)); 965 966 return (ts.tv_sec + (double)ts.tv_nsec / 1000000000); 967 } 968 969 void 970 bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) 971 { 972 bw->buflen = buflen; 973 bw->rate = kbps; 974 bw->thresh = bw->rate; 975 bw->lamt = 0; 976 timerclear(&bw->bwstart); 977 timerclear(&bw->bwend); 978 } 979 980 /* Callback from read/write loop to insert bandwidth-limiting delays */ 981 void 982 bandwidth_limit(struct bwlimit *bw, size_t read_len) 983 { 984 u_int64_t waitlen; 985 struct timespec ts, rm; 986 987 if (!timerisset(&bw->bwstart)) { 988 gettimeofday(&bw->bwstart, NULL); 989 return; 990 } 991 992 bw->lamt += read_len; 993 if (bw->lamt < bw->thresh) 994 return; 995 996 gettimeofday(&bw->bwend, NULL); 997 timersub(&bw->bwend, &bw->bwstart, &bw->bwend); 998 if (!timerisset(&bw->bwend)) 999 return; 1000 1001 bw->lamt *= 8; 1002 waitlen = (double)1000000L * bw->lamt / bw->rate; 1003 1004 bw->bwstart.tv_sec = waitlen / 1000000L; 1005 bw->bwstart.tv_usec = waitlen % 1000000L; 1006 1007 if (timercmp(&bw->bwstart, &bw->bwend, >)) { 1008 timersub(&bw->bwstart, &bw->bwend, &bw->bwend); 1009 1010 /* Adjust the wait time */ 1011 if (bw->bwend.tv_sec) { 1012 bw->thresh /= 2; 1013 if (bw->thresh < bw->buflen / 4) 1014 bw->thresh = bw->buflen / 4; 1015 } else if (bw->bwend.tv_usec < 10000) { 1016 bw->thresh *= 2; 1017 if (bw->thresh > bw->buflen * 8) 1018 bw->thresh = bw->buflen * 8; 1019 } 1020 1021 TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts); 1022 while (nanosleep(&ts, &rm) == -1) { 1023 if (errno != EINTR) 1024 break; 1025 ts = rm; 1026 } 1027 } 1028 1029 bw->lamt = 0; 1030 gettimeofday(&bw->bwstart, NULL); 1031 } 1032 1033 /* Make a template filename for mk[sd]temp() */ 1034 void 1035 mktemp_proto(char *s, size_t len) 1036 { 1037 const char *tmpdir; 1038 int r; 1039 1040 if ((tmpdir = getenv("TMPDIR")) != NULL) { 1041 r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir); 1042 if (r > 0 && (size_t)r < len) 1043 return; 1044 } 1045 r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX"); 1046 if (r < 0 || (size_t)r >= len) 1047 fatal("%s: template string too short", __func__); 1048 } 1049 1050 static const struct { 1051 const char *name; 1052 int value; 1053 } ipqos[] = { 1054 { "af11", IPTOS_DSCP_AF11 }, 1055 { "af12", IPTOS_DSCP_AF12 }, 1056 { "af13", IPTOS_DSCP_AF13 }, 1057 { "af21", IPTOS_DSCP_AF21 }, 1058 { "af22", IPTOS_DSCP_AF22 }, 1059 { "af23", IPTOS_DSCP_AF23 }, 1060 { "af31", IPTOS_DSCP_AF31 }, 1061 { "af32", IPTOS_DSCP_AF32 }, 1062 { "af33", IPTOS_DSCP_AF33 }, 1063 { "af41", IPTOS_DSCP_AF41 }, 1064 { "af42", IPTOS_DSCP_AF42 }, 1065 { "af43", IPTOS_DSCP_AF43 }, 1066 { "cs0", IPTOS_DSCP_CS0 }, 1067 { "cs1", IPTOS_DSCP_CS1 }, 1068 { "cs2", IPTOS_DSCP_CS2 }, 1069 { "cs3", IPTOS_DSCP_CS3 }, 1070 { "cs4", IPTOS_DSCP_CS4 }, 1071 { "cs5", IPTOS_DSCP_CS5 }, 1072 { "cs6", IPTOS_DSCP_CS6 }, 1073 { "cs7", IPTOS_DSCP_CS7 }, 1074 { "ef", IPTOS_DSCP_EF }, 1075 { "lowdelay", IPTOS_LOWDELAY }, 1076 { "throughput", IPTOS_THROUGHPUT }, 1077 { "reliability", IPTOS_RELIABILITY }, 1078 { NULL, -1 } 1079 }; 1080 1081 int 1082 parse_ipqos(const char *cp) 1083 { 1084 u_int i; 1085 char *ep; 1086 long val; 1087 1088 if (cp == NULL) 1089 return -1; 1090 for (i = 0; ipqos[i].name != NULL; i++) { 1091 if (strcasecmp(cp, ipqos[i].name) == 0) 1092 return ipqos[i].value; 1093 } 1094 /* Try parsing as an integer */ 1095 val = strtol(cp, &ep, 0); 1096 if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255) 1097 return -1; 1098 return val; 1099 } 1100 1101 const char * 1102 iptos2str(int iptos) 1103 { 1104 int i; 1105 static char iptos_str[sizeof "0xff"]; 1106 1107 for (i = 0; ipqos[i].name != NULL; i++) { 1108 if (ipqos[i].value == iptos) 1109 return ipqos[i].name; 1110 } 1111 snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos); 1112 return iptos_str; 1113 } 1114 1115 void 1116 lowercase(char *s) 1117 { 1118 for (; *s; s++) 1119 *s = tolower((u_char)*s); 1120 } 1121 1122 int 1123 unix_listener(const char *path, int backlog, int unlink_first) 1124 { 1125 struct sockaddr_un sunaddr; 1126 int saved_errno, sock; 1127 1128 memset(&sunaddr, 0, sizeof(sunaddr)); 1129 sunaddr.sun_family = AF_UNIX; 1130 if (strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) { 1131 error("%s: \"%s\" too long for Unix domain socket", __func__, 1132 path); 1133 errno = ENAMETOOLONG; 1134 return -1; 1135 } 1136 1137 sock = socket(PF_UNIX, SOCK_STREAM, 0); 1138 if (sock < 0) { 1139 saved_errno = errno; 1140 error("socket: %.100s", strerror(errno)); 1141 errno = saved_errno; 1142 return -1; 1143 } 1144 if (unlink_first == 1) { 1145 if (unlink(path) != 0 && errno != ENOENT) 1146 error("unlink(%s): %.100s", path, strerror(errno)); 1147 } 1148 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { 1149 saved_errno = errno; 1150 error("bind: %.100s", strerror(errno)); 1151 close(sock); 1152 error("%s: cannot bind to path: %s", __func__, path); 1153 errno = saved_errno; 1154 return -1; 1155 } 1156 if (listen(sock, backlog) < 0) { 1157 saved_errno = errno; 1158 error("listen: %.100s", strerror(errno)); 1159 close(sock); 1160 unlink(path); 1161 error("%s: cannot listen on path: %s", __func__, path); 1162 errno = saved_errno; 1163 return -1; 1164 } 1165 return sock; 1166 } 1167 1168 /* 1169 * Compares two strings that maybe be NULL. Returns non-zero if strings 1170 * are both NULL or are identical, returns zero otherwise. 1171 */ 1172 static int 1173 strcmp_maybe_null(const char *a, const char *b) 1174 { 1175 if ((a == NULL && b != NULL) || (a != NULL && b == NULL)) 1176 return 0; 1177 if (a != NULL && strcmp(a, b) != 0) 1178 return 0; 1179 return 1; 1180 } 1181 1182 /* 1183 * Compare two forwards, returning non-zero if they are identical or 1184 * zero otherwise. 1185 */ 1186 int 1187 forward_equals(const struct Forward *a, const struct Forward *b) 1188 { 1189 if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0) 1190 return 0; 1191 if (a->listen_port != b->listen_port) 1192 return 0; 1193 if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0) 1194 return 0; 1195 if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0) 1196 return 0; 1197 if (a->connect_port != b->connect_port) 1198 return 0; 1199 if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0) 1200 return 0; 1201 /* allocated_port and handle are not checked */ 1202 return 1; 1203 } 1204 1205