1 /* $OpenBSD: misc.c,v 1.135 2018/12/07 04:36:09 dtucker 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 #include <arpa/inet.h> 40 41 #include <ctype.h> 42 #include <errno.h> 43 #include <fcntl.h> 44 #include <netdb.h> 45 #include <paths.h> 46 #include <pwd.h> 47 #include <libgen.h> 48 #include <limits.h> 49 #include <signal.h> 50 #include <stdarg.h> 51 #include <stdio.h> 52 #include <stdlib.h> 53 #include <string.h> 54 #include <unistd.h> 55 56 #include "xmalloc.h" 57 #include "misc.h" 58 #include "log.h" 59 #include "ssh.h" 60 #include "sshbuf.h" 61 #include "ssherr.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 /* Allow local port reuse in TIME_WAIT */ 159 int 160 set_reuseaddr(int fd) 161 { 162 int on = 1; 163 164 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { 165 error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno)); 166 return -1; 167 } 168 return 0; 169 } 170 171 /* Get/set routing domain */ 172 char * 173 get_rdomain(int fd) 174 { 175 int rtable; 176 char *ret; 177 socklen_t len = sizeof(rtable); 178 179 if (getsockopt(fd, SOL_SOCKET, SO_RTABLE, &rtable, &len) == -1) { 180 error("Failed to get routing domain for fd %d: %s", 181 fd, strerror(errno)); 182 return NULL; 183 } 184 xasprintf(&ret, "%d", rtable); 185 return ret; 186 } 187 188 int 189 set_rdomain(int fd, const char *name) 190 { 191 int rtable; 192 const char *errstr; 193 194 if (name == NULL) 195 return 0; /* default table */ 196 197 rtable = (int)strtonum(name, 0, 255, &errstr); 198 if (errstr != NULL) { 199 /* Shouldn't happen */ 200 error("Invalid routing domain \"%s\": %s", name, errstr); 201 return -1; 202 } 203 if (setsockopt(fd, SOL_SOCKET, SO_RTABLE, 204 &rtable, sizeof(rtable)) == -1) { 205 error("Failed to set routing domain %d on fd %d: %s", 206 rtable, fd, strerror(errno)); 207 return -1; 208 } 209 return 0; 210 } 211 212 /* Characters considered whitespace in strsep calls. */ 213 #define WHITESPACE " \t\r\n" 214 #define QUOTE "\"" 215 216 /* return next token in configuration line */ 217 static char * 218 strdelim_internal(char **s, int split_equals) 219 { 220 char *old; 221 int wspace = 0; 222 223 if (*s == NULL) 224 return NULL; 225 226 old = *s; 227 228 *s = strpbrk(*s, 229 split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); 230 if (*s == NULL) 231 return (old); 232 233 if (*s[0] == '\"') { 234 memmove(*s, *s + 1, strlen(*s)); /* move nul too */ 235 /* Find matching quote */ 236 if ((*s = strpbrk(*s, QUOTE)) == NULL) { 237 return (NULL); /* no matching quote */ 238 } else { 239 *s[0] = '\0'; 240 *s += strspn(*s + 1, WHITESPACE) + 1; 241 return (old); 242 } 243 } 244 245 /* Allow only one '=' to be skipped */ 246 if (split_equals && *s[0] == '=') 247 wspace = 1; 248 *s[0] = '\0'; 249 250 /* Skip any extra whitespace after first token */ 251 *s += strspn(*s + 1, WHITESPACE) + 1; 252 if (split_equals && *s[0] == '=' && !wspace) 253 *s += strspn(*s + 1, WHITESPACE) + 1; 254 255 return (old); 256 } 257 258 /* 259 * Return next token in configuration line; splts on whitespace or a 260 * single '=' character. 261 */ 262 char * 263 strdelim(char **s) 264 { 265 return strdelim_internal(s, 1); 266 } 267 268 /* 269 * Return next token in configuration line; splts on whitespace only. 270 */ 271 char * 272 strdelimw(char **s) 273 { 274 return strdelim_internal(s, 0); 275 } 276 277 struct passwd * 278 pwcopy(struct passwd *pw) 279 { 280 struct passwd *copy = xcalloc(1, sizeof(*copy)); 281 282 copy->pw_name = xstrdup(pw->pw_name); 283 copy->pw_passwd = xstrdup(pw->pw_passwd); 284 copy->pw_gecos = xstrdup(pw->pw_gecos); 285 copy->pw_uid = pw->pw_uid; 286 copy->pw_gid = pw->pw_gid; 287 copy->pw_expire = pw->pw_expire; 288 copy->pw_change = pw->pw_change; 289 copy->pw_class = xstrdup(pw->pw_class); 290 copy->pw_dir = xstrdup(pw->pw_dir); 291 copy->pw_shell = xstrdup(pw->pw_shell); 292 return copy; 293 } 294 295 /* 296 * Convert ASCII string to TCP/IP port number. 297 * Port must be >=0 and <=65535. 298 * Return -1 if invalid. 299 */ 300 int 301 a2port(const char *s) 302 { 303 struct servent *se; 304 long long port; 305 const char *errstr; 306 307 port = strtonum(s, 0, 65535, &errstr); 308 if (errstr == NULL) 309 return (int)port; 310 if ((se = getservbyname(s, "tcp")) != NULL) 311 return ntohs(se->s_port); 312 return -1; 313 } 314 315 int 316 a2tun(const char *s, int *remote) 317 { 318 const char *errstr = NULL; 319 char *sp, *ep; 320 int tun; 321 322 if (remote != NULL) { 323 *remote = SSH_TUNID_ANY; 324 sp = xstrdup(s); 325 if ((ep = strchr(sp, ':')) == NULL) { 326 free(sp); 327 return (a2tun(s, NULL)); 328 } 329 ep[0] = '\0'; ep++; 330 *remote = a2tun(ep, NULL); 331 tun = a2tun(sp, NULL); 332 free(sp); 333 return (*remote == SSH_TUNID_ERR ? *remote : tun); 334 } 335 336 if (strcasecmp(s, "any") == 0) 337 return (SSH_TUNID_ANY); 338 339 tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr); 340 if (errstr != NULL) 341 return (SSH_TUNID_ERR); 342 343 return (tun); 344 } 345 346 #define SECONDS 1 347 #define MINUTES (SECONDS * 60) 348 #define HOURS (MINUTES * 60) 349 #define DAYS (HOURS * 24) 350 #define WEEKS (DAYS * 7) 351 352 /* 353 * Convert a time string into seconds; format is 354 * a sequence of: 355 * time[qualifier] 356 * 357 * Valid time qualifiers are: 358 * <none> seconds 359 * s|S seconds 360 * m|M minutes 361 * h|H hours 362 * d|D days 363 * w|W weeks 364 * 365 * Examples: 366 * 90m 90 minutes 367 * 1h30m 90 minutes 368 * 2d 2 days 369 * 1w 1 week 370 * 371 * Return -1 if time string is invalid. 372 */ 373 long 374 convtime(const char *s) 375 { 376 long total, secs, multiplier = 1; 377 const char *p; 378 char *endp; 379 380 errno = 0; 381 total = 0; 382 p = s; 383 384 if (p == NULL || *p == '\0') 385 return -1; 386 387 while (*p) { 388 secs = strtol(p, &endp, 10); 389 if (p == endp || 390 (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) || 391 secs < 0) 392 return -1; 393 394 switch (*endp++) { 395 case '\0': 396 endp--; 397 break; 398 case 's': 399 case 'S': 400 break; 401 case 'm': 402 case 'M': 403 multiplier = MINUTES; 404 break; 405 case 'h': 406 case 'H': 407 multiplier = HOURS; 408 break; 409 case 'd': 410 case 'D': 411 multiplier = DAYS; 412 break; 413 case 'w': 414 case 'W': 415 multiplier = WEEKS; 416 break; 417 default: 418 return -1; 419 } 420 if (secs >= LONG_MAX / multiplier) 421 return -1; 422 secs *= multiplier; 423 if (total >= LONG_MAX - secs) 424 return -1; 425 total += secs; 426 if (total < 0) 427 return -1; 428 p = endp; 429 } 430 431 return total; 432 } 433 434 /* 435 * Returns a standardized host+port identifier string. 436 * Caller must free returned string. 437 */ 438 char * 439 put_host_port(const char *host, u_short port) 440 { 441 char *hoststr; 442 443 if (port == 0 || port == SSH_DEFAULT_PORT) 444 return(xstrdup(host)); 445 if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0) 446 fatal("put_host_port: asprintf: %s", strerror(errno)); 447 debug3("put_host_port: %s", hoststr); 448 return hoststr; 449 } 450 451 /* 452 * Search for next delimiter between hostnames/addresses and ports. 453 * Argument may be modified (for termination). 454 * Returns *cp if parsing succeeds. 455 * *cp is set to the start of the next field, if one was found. 456 * The delimiter char, if present, is stored in delim. 457 * If this is the last field, *cp is set to NULL. 458 */ 459 static char * 460 hpdelim2(char **cp, char *delim) 461 { 462 char *s, *old; 463 464 if (cp == NULL || *cp == NULL) 465 return NULL; 466 467 old = s = *cp; 468 if (*s == '[') { 469 if ((s = strchr(s, ']')) == NULL) 470 return NULL; 471 else 472 s++; 473 } else if ((s = strpbrk(s, ":/")) == NULL) 474 s = *cp + strlen(*cp); /* skip to end (see first case below) */ 475 476 switch (*s) { 477 case '\0': 478 *cp = NULL; /* no more fields*/ 479 break; 480 481 case ':': 482 case '/': 483 if (delim != NULL) 484 *delim = *s; 485 *s = '\0'; /* terminate */ 486 *cp = s + 1; 487 break; 488 489 default: 490 return NULL; 491 } 492 493 return old; 494 } 495 496 char * 497 hpdelim(char **cp) 498 { 499 return hpdelim2(cp, NULL); 500 } 501 502 char * 503 cleanhostname(char *host) 504 { 505 if (*host == '[' && host[strlen(host) - 1] == ']') { 506 host[strlen(host) - 1] = '\0'; 507 return (host + 1); 508 } else 509 return host; 510 } 511 512 char * 513 colon(char *cp) 514 { 515 int flag = 0; 516 517 if (*cp == ':') /* Leading colon is part of file name. */ 518 return NULL; 519 if (*cp == '[') 520 flag = 1; 521 522 for (; *cp; ++cp) { 523 if (*cp == '@' && *(cp+1) == '[') 524 flag = 1; 525 if (*cp == ']' && *(cp+1) == ':' && flag) 526 return (cp+1); 527 if (*cp == ':' && !flag) 528 return (cp); 529 if (*cp == '/') 530 return NULL; 531 } 532 return NULL; 533 } 534 535 /* 536 * Parse a [user@]host:[path] string. 537 * Caller must free returned user, host and path. 538 * Any of the pointer return arguments may be NULL (useful for syntax checking). 539 * If user was not specified then *userp will be set to NULL. 540 * If host was not specified then *hostp will be set to NULL. 541 * If path was not specified then *pathp will be set to ".". 542 * Returns 0 on success, -1 on failure. 543 */ 544 int 545 parse_user_host_path(const char *s, char **userp, char **hostp, char **pathp) 546 { 547 char *user = NULL, *host = NULL, *path = NULL; 548 char *sdup, *tmp; 549 int ret = -1; 550 551 if (userp != NULL) 552 *userp = NULL; 553 if (hostp != NULL) 554 *hostp = NULL; 555 if (pathp != NULL) 556 *pathp = NULL; 557 558 sdup = xstrdup(s); 559 560 /* Check for remote syntax: [user@]host:[path] */ 561 if ((tmp = colon(sdup)) == NULL) 562 goto out; 563 564 /* Extract optional path */ 565 *tmp++ = '\0'; 566 if (*tmp == '\0') 567 tmp = "."; 568 path = xstrdup(tmp); 569 570 /* Extract optional user and mandatory host */ 571 tmp = strrchr(sdup, '@'); 572 if (tmp != NULL) { 573 *tmp++ = '\0'; 574 host = xstrdup(cleanhostname(tmp)); 575 if (*sdup != '\0') 576 user = xstrdup(sdup); 577 } else { 578 host = xstrdup(cleanhostname(sdup)); 579 user = NULL; 580 } 581 582 /* Success */ 583 if (userp != NULL) { 584 *userp = user; 585 user = NULL; 586 } 587 if (hostp != NULL) { 588 *hostp = host; 589 host = NULL; 590 } 591 if (pathp != NULL) { 592 *pathp = path; 593 path = NULL; 594 } 595 ret = 0; 596 out: 597 free(sdup); 598 free(user); 599 free(host); 600 free(path); 601 return ret; 602 } 603 604 /* 605 * Parse a [user@]host[:port] string. 606 * Caller must free returned user and host. 607 * Any of the pointer return arguments may be NULL (useful for syntax checking). 608 * If user was not specified then *userp will be set to NULL. 609 * If port was not specified then *portp will be -1. 610 * Returns 0 on success, -1 on failure. 611 */ 612 int 613 parse_user_host_port(const char *s, char **userp, char **hostp, int *portp) 614 { 615 char *sdup, *cp, *tmp; 616 char *user = NULL, *host = NULL; 617 int port = -1, ret = -1; 618 619 if (userp != NULL) 620 *userp = NULL; 621 if (hostp != NULL) 622 *hostp = NULL; 623 if (portp != NULL) 624 *portp = -1; 625 626 if ((sdup = tmp = strdup(s)) == NULL) 627 return -1; 628 /* Extract optional username */ 629 if ((cp = strrchr(tmp, '@')) != NULL) { 630 *cp = '\0'; 631 if (*tmp == '\0') 632 goto out; 633 if ((user = strdup(tmp)) == NULL) 634 goto out; 635 tmp = cp + 1; 636 } 637 /* Extract mandatory hostname */ 638 if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0') 639 goto out; 640 host = xstrdup(cleanhostname(cp)); 641 /* Convert and verify optional port */ 642 if (tmp != NULL && *tmp != '\0') { 643 if ((port = a2port(tmp)) <= 0) 644 goto out; 645 } 646 /* Success */ 647 if (userp != NULL) { 648 *userp = user; 649 user = NULL; 650 } 651 if (hostp != NULL) { 652 *hostp = host; 653 host = NULL; 654 } 655 if (portp != NULL) 656 *portp = port; 657 ret = 0; 658 out: 659 free(sdup); 660 free(user); 661 free(host); 662 return ret; 663 } 664 665 /* 666 * Converts a two-byte hex string to decimal. 667 * Returns the decimal value or -1 for invalid input. 668 */ 669 static int 670 hexchar(const char *s) 671 { 672 unsigned char result[2]; 673 int i; 674 675 for (i = 0; i < 2; i++) { 676 if (s[i] >= '0' && s[i] <= '9') 677 result[i] = (unsigned char)(s[i] - '0'); 678 else if (s[i] >= 'a' && s[i] <= 'f') 679 result[i] = (unsigned char)(s[i] - 'a') + 10; 680 else if (s[i] >= 'A' && s[i] <= 'F') 681 result[i] = (unsigned char)(s[i] - 'A') + 10; 682 else 683 return -1; 684 } 685 return (result[0] << 4) | result[1]; 686 } 687 688 /* 689 * Decode an url-encoded string. 690 * Returns a newly allocated string on success or NULL on failure. 691 */ 692 static char * 693 urldecode(const char *src) 694 { 695 char *ret, *dst; 696 int ch; 697 698 ret = xmalloc(strlen(src) + 1); 699 for (dst = ret; *src != '\0'; src++) { 700 switch (*src) { 701 case '+': 702 *dst++ = ' '; 703 break; 704 case '%': 705 if (!isxdigit((unsigned char)src[1]) || 706 !isxdigit((unsigned char)src[2]) || 707 (ch = hexchar(src + 1)) == -1) { 708 free(ret); 709 return NULL; 710 } 711 *dst++ = ch; 712 src += 2; 713 break; 714 default: 715 *dst++ = *src; 716 break; 717 } 718 } 719 *dst = '\0'; 720 721 return ret; 722 } 723 724 /* 725 * Parse an (scp|ssh|sftp)://[user@]host[:port][/path] URI. 726 * See https://tools.ietf.org/html/draft-ietf-secsh-scp-sftp-ssh-uri-04 727 * Either user or path may be url-encoded (but not host or port). 728 * Caller must free returned user, host and path. 729 * Any of the pointer return arguments may be NULL (useful for syntax checking) 730 * but the scheme must always be specified. 731 * If user was not specified then *userp will be set to NULL. 732 * If port was not specified then *portp will be -1. 733 * If path was not specified then *pathp will be set to NULL. 734 * Returns 0 on success, 1 if non-uri/wrong scheme, -1 on error/invalid uri. 735 */ 736 int 737 parse_uri(const char *scheme, const char *uri, char **userp, char **hostp, 738 int *portp, char **pathp) 739 { 740 char *uridup, *cp, *tmp, ch; 741 char *user = NULL, *host = NULL, *path = NULL; 742 int port = -1, ret = -1; 743 size_t len; 744 745 len = strlen(scheme); 746 if (strncmp(uri, scheme, len) != 0 || strncmp(uri + len, "://", 3) != 0) 747 return 1; 748 uri += len + 3; 749 750 if (userp != NULL) 751 *userp = NULL; 752 if (hostp != NULL) 753 *hostp = NULL; 754 if (portp != NULL) 755 *portp = -1; 756 if (pathp != NULL) 757 *pathp = NULL; 758 759 uridup = tmp = xstrdup(uri); 760 761 /* Extract optional ssh-info (username + connection params) */ 762 if ((cp = strchr(tmp, '@')) != NULL) { 763 char *delim; 764 765 *cp = '\0'; 766 /* Extract username and connection params */ 767 if ((delim = strchr(tmp, ';')) != NULL) { 768 /* Just ignore connection params for now */ 769 *delim = '\0'; 770 } 771 if (*tmp == '\0') { 772 /* Empty username */ 773 goto out; 774 } 775 if ((user = urldecode(tmp)) == NULL) 776 goto out; 777 tmp = cp + 1; 778 } 779 780 /* Extract mandatory hostname */ 781 if ((cp = hpdelim2(&tmp, &ch)) == NULL || *cp == '\0') 782 goto out; 783 host = xstrdup(cleanhostname(cp)); 784 if (!valid_domain(host, 0, NULL)) 785 goto out; 786 787 if (tmp != NULL && *tmp != '\0') { 788 if (ch == ':') { 789 /* Convert and verify port. */ 790 if ((cp = strchr(tmp, '/')) != NULL) 791 *cp = '\0'; 792 if ((port = a2port(tmp)) <= 0) 793 goto out; 794 tmp = cp ? cp + 1 : NULL; 795 } 796 if (tmp != NULL && *tmp != '\0') { 797 /* Extract optional path */ 798 if ((path = urldecode(tmp)) == NULL) 799 goto out; 800 } 801 } 802 803 /* Success */ 804 if (userp != NULL) { 805 *userp = user; 806 user = NULL; 807 } 808 if (hostp != NULL) { 809 *hostp = host; 810 host = NULL; 811 } 812 if (portp != NULL) 813 *portp = port; 814 if (pathp != NULL) { 815 *pathp = path; 816 path = NULL; 817 } 818 ret = 0; 819 out: 820 free(uridup); 821 free(user); 822 free(host); 823 free(path); 824 return ret; 825 } 826 827 /* function to assist building execv() arguments */ 828 void 829 addargs(arglist *args, char *fmt, ...) 830 { 831 va_list ap; 832 char *cp; 833 u_int nalloc; 834 int r; 835 836 va_start(ap, fmt); 837 r = vasprintf(&cp, fmt, ap); 838 va_end(ap); 839 if (r == -1) 840 fatal("addargs: argument too long"); 841 842 nalloc = args->nalloc; 843 if (args->list == NULL) { 844 nalloc = 32; 845 args->num = 0; 846 } else if (args->num+2 >= nalloc) 847 nalloc *= 2; 848 849 args->list = xrecallocarray(args->list, args->nalloc, nalloc, sizeof(char *)); 850 args->nalloc = nalloc; 851 args->list[args->num++] = cp; 852 args->list[args->num] = NULL; 853 } 854 855 void 856 replacearg(arglist *args, u_int which, char *fmt, ...) 857 { 858 va_list ap; 859 char *cp; 860 int r; 861 862 va_start(ap, fmt); 863 r = vasprintf(&cp, fmt, ap); 864 va_end(ap); 865 if (r == -1) 866 fatal("replacearg: argument too long"); 867 868 if (which >= args->num) 869 fatal("replacearg: tried to replace invalid arg %d >= %d", 870 which, args->num); 871 free(args->list[which]); 872 args->list[which] = cp; 873 } 874 875 void 876 freeargs(arglist *args) 877 { 878 u_int i; 879 880 if (args->list != NULL) { 881 for (i = 0; i < args->num; i++) 882 free(args->list[i]); 883 free(args->list); 884 args->nalloc = args->num = 0; 885 args->list = NULL; 886 } 887 } 888 889 /* 890 * Expands tildes in the file name. Returns data allocated by xmalloc. 891 * Warning: this calls getpw*. 892 */ 893 char * 894 tilde_expand_filename(const char *filename, uid_t uid) 895 { 896 const char *path, *sep; 897 char user[128], *ret; 898 struct passwd *pw; 899 u_int len, slash; 900 901 if (*filename != '~') 902 return (xstrdup(filename)); 903 filename++; 904 905 path = strchr(filename, '/'); 906 if (path != NULL && path > filename) { /* ~user/path */ 907 slash = path - filename; 908 if (slash > sizeof(user) - 1) 909 fatal("tilde_expand_filename: ~username too long"); 910 memcpy(user, filename, slash); 911 user[slash] = '\0'; 912 if ((pw = getpwnam(user)) == NULL) 913 fatal("tilde_expand_filename: No such user %s", user); 914 } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */ 915 fatal("tilde_expand_filename: No such uid %ld", (long)uid); 916 917 /* Make sure directory has a trailing '/' */ 918 len = strlen(pw->pw_dir); 919 if (len == 0 || pw->pw_dir[len - 1] != '/') 920 sep = "/"; 921 else 922 sep = ""; 923 924 /* Skip leading '/' from specified path */ 925 if (path != NULL) 926 filename = path + 1; 927 928 if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX) 929 fatal("tilde_expand_filename: Path too long"); 930 931 return (ret); 932 } 933 934 /* 935 * Expand a string with a set of %[char] escapes. A number of escapes may be 936 * specified as (char *escape_chars, char *replacement) pairs. The list must 937 * be terminated by a NULL escape_char. Returns replaced string in memory 938 * allocated by xmalloc. 939 */ 940 char * 941 percent_expand(const char *string, ...) 942 { 943 #define EXPAND_MAX_KEYS 16 944 u_int num_keys, i, j; 945 struct { 946 const char *key; 947 const char *repl; 948 } keys[EXPAND_MAX_KEYS]; 949 char buf[4096]; 950 va_list ap; 951 952 /* Gather keys */ 953 va_start(ap, string); 954 for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) { 955 keys[num_keys].key = va_arg(ap, char *); 956 if (keys[num_keys].key == NULL) 957 break; 958 keys[num_keys].repl = va_arg(ap, char *); 959 if (keys[num_keys].repl == NULL) 960 fatal("%s: NULL replacement", __func__); 961 } 962 if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL) 963 fatal("%s: too many keys", __func__); 964 va_end(ap); 965 966 /* Expand string */ 967 *buf = '\0'; 968 for (i = 0; *string != '\0'; string++) { 969 if (*string != '%') { 970 append: 971 buf[i++] = *string; 972 if (i >= sizeof(buf)) 973 fatal("%s: string too long", __func__); 974 buf[i] = '\0'; 975 continue; 976 } 977 string++; 978 /* %% case */ 979 if (*string == '%') 980 goto append; 981 if (*string == '\0') 982 fatal("%s: invalid format", __func__); 983 for (j = 0; j < num_keys; j++) { 984 if (strchr(keys[j].key, *string) != NULL) { 985 i = strlcat(buf, keys[j].repl, sizeof(buf)); 986 if (i >= sizeof(buf)) 987 fatal("%s: string too long", __func__); 988 break; 989 } 990 } 991 if (j >= num_keys) 992 fatal("%s: unknown key %%%c", __func__, *string); 993 } 994 return (xstrdup(buf)); 995 #undef EXPAND_MAX_KEYS 996 } 997 998 int 999 tun_open(int tun, int mode, char **ifname) 1000 { 1001 struct ifreq ifr; 1002 char name[100]; 1003 int fd = -1, sock; 1004 const char *tunbase = "tun"; 1005 1006 if (ifname != NULL) 1007 *ifname = NULL; 1008 1009 if (mode == SSH_TUNMODE_ETHERNET) 1010 tunbase = "tap"; 1011 1012 /* Open the tunnel device */ 1013 if (tun <= SSH_TUNID_MAX) { 1014 snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); 1015 fd = open(name, O_RDWR); 1016 } else if (tun == SSH_TUNID_ANY) { 1017 for (tun = 100; tun >= 0; tun--) { 1018 snprintf(name, sizeof(name), "/dev/%s%d", 1019 tunbase, tun); 1020 if ((fd = open(name, O_RDWR)) >= 0) 1021 break; 1022 } 1023 } else { 1024 debug("%s: invalid tunnel %u", __func__, tun); 1025 return -1; 1026 } 1027 1028 if (fd < 0) { 1029 debug("%s: %s open: %s", __func__, name, strerror(errno)); 1030 return -1; 1031 } 1032 1033 debug("%s: %s mode %d fd %d", __func__, name, mode, fd); 1034 1035 /* Bring interface up if it is not already */ 1036 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); 1037 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) 1038 goto failed; 1039 1040 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { 1041 debug("%s: get interface %s flags: %s", __func__, 1042 ifr.ifr_name, strerror(errno)); 1043 goto failed; 1044 } 1045 1046 if (!(ifr.ifr_flags & IFF_UP)) { 1047 ifr.ifr_flags |= IFF_UP; 1048 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { 1049 debug("%s: activate interface %s: %s", __func__, 1050 ifr.ifr_name, strerror(errno)); 1051 goto failed; 1052 } 1053 } 1054 1055 if (ifname != NULL) 1056 *ifname = xstrdup(ifr.ifr_name); 1057 1058 close(sock); 1059 return fd; 1060 1061 failed: 1062 if (fd >= 0) 1063 close(fd); 1064 if (sock >= 0) 1065 close(sock); 1066 return -1; 1067 } 1068 1069 void 1070 sanitise_stdfd(void) 1071 { 1072 int nullfd, dupfd; 1073 1074 if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) { 1075 fprintf(stderr, "Couldn't open /dev/null: %s\n", 1076 strerror(errno)); 1077 exit(1); 1078 } 1079 while (++dupfd <= STDERR_FILENO) { 1080 /* Only populate closed fds. */ 1081 if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) { 1082 if (dup2(nullfd, dupfd) == -1) { 1083 fprintf(stderr, "dup2: %s\n", strerror(errno)); 1084 exit(1); 1085 } 1086 } 1087 } 1088 if (nullfd > STDERR_FILENO) 1089 close(nullfd); 1090 } 1091 1092 char * 1093 tohex(const void *vp, size_t l) 1094 { 1095 const u_char *p = (const u_char *)vp; 1096 char b[3], *r; 1097 size_t i, hl; 1098 1099 if (l > 65536) 1100 return xstrdup("tohex: length > 65536"); 1101 1102 hl = l * 2 + 1; 1103 r = xcalloc(1, hl); 1104 for (i = 0; i < l; i++) { 1105 snprintf(b, sizeof(b), "%02x", p[i]); 1106 strlcat(r, b, hl); 1107 } 1108 return (r); 1109 } 1110 1111 u_int64_t 1112 get_u64(const void *vp) 1113 { 1114 const u_char *p = (const u_char *)vp; 1115 u_int64_t v; 1116 1117 v = (u_int64_t)p[0] << 56; 1118 v |= (u_int64_t)p[1] << 48; 1119 v |= (u_int64_t)p[2] << 40; 1120 v |= (u_int64_t)p[3] << 32; 1121 v |= (u_int64_t)p[4] << 24; 1122 v |= (u_int64_t)p[5] << 16; 1123 v |= (u_int64_t)p[6] << 8; 1124 v |= (u_int64_t)p[7]; 1125 1126 return (v); 1127 } 1128 1129 u_int32_t 1130 get_u32(const void *vp) 1131 { 1132 const u_char *p = (const u_char *)vp; 1133 u_int32_t v; 1134 1135 v = (u_int32_t)p[0] << 24; 1136 v |= (u_int32_t)p[1] << 16; 1137 v |= (u_int32_t)p[2] << 8; 1138 v |= (u_int32_t)p[3]; 1139 1140 return (v); 1141 } 1142 1143 u_int32_t 1144 get_u32_le(const void *vp) 1145 { 1146 const u_char *p = (const u_char *)vp; 1147 u_int32_t v; 1148 1149 v = (u_int32_t)p[0]; 1150 v |= (u_int32_t)p[1] << 8; 1151 v |= (u_int32_t)p[2] << 16; 1152 v |= (u_int32_t)p[3] << 24; 1153 1154 return (v); 1155 } 1156 1157 u_int16_t 1158 get_u16(const void *vp) 1159 { 1160 const u_char *p = (const u_char *)vp; 1161 u_int16_t v; 1162 1163 v = (u_int16_t)p[0] << 8; 1164 v |= (u_int16_t)p[1]; 1165 1166 return (v); 1167 } 1168 1169 void 1170 put_u64(void *vp, u_int64_t v) 1171 { 1172 u_char *p = (u_char *)vp; 1173 1174 p[0] = (u_char)(v >> 56) & 0xff; 1175 p[1] = (u_char)(v >> 48) & 0xff; 1176 p[2] = (u_char)(v >> 40) & 0xff; 1177 p[3] = (u_char)(v >> 32) & 0xff; 1178 p[4] = (u_char)(v >> 24) & 0xff; 1179 p[5] = (u_char)(v >> 16) & 0xff; 1180 p[6] = (u_char)(v >> 8) & 0xff; 1181 p[7] = (u_char)v & 0xff; 1182 } 1183 1184 void 1185 put_u32(void *vp, u_int32_t v) 1186 { 1187 u_char *p = (u_char *)vp; 1188 1189 p[0] = (u_char)(v >> 24) & 0xff; 1190 p[1] = (u_char)(v >> 16) & 0xff; 1191 p[2] = (u_char)(v >> 8) & 0xff; 1192 p[3] = (u_char)v & 0xff; 1193 } 1194 1195 void 1196 put_u32_le(void *vp, u_int32_t v) 1197 { 1198 u_char *p = (u_char *)vp; 1199 1200 p[0] = (u_char)v & 0xff; 1201 p[1] = (u_char)(v >> 8) & 0xff; 1202 p[2] = (u_char)(v >> 16) & 0xff; 1203 p[3] = (u_char)(v >> 24) & 0xff; 1204 } 1205 1206 void 1207 put_u16(void *vp, u_int16_t v) 1208 { 1209 u_char *p = (u_char *)vp; 1210 1211 p[0] = (u_char)(v >> 8) & 0xff; 1212 p[1] = (u_char)v & 0xff; 1213 } 1214 1215 void 1216 ms_subtract_diff(struct timeval *start, int *ms) 1217 { 1218 struct timeval diff, finish; 1219 1220 monotime_tv(&finish); 1221 timersub(&finish, start, &diff); 1222 *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); 1223 } 1224 1225 void 1226 ms_to_timeval(struct timeval *tv, int ms) 1227 { 1228 if (ms < 0) 1229 ms = 0; 1230 tv->tv_sec = ms / 1000; 1231 tv->tv_usec = (ms % 1000) * 1000; 1232 } 1233 1234 void 1235 monotime_ts(struct timespec *ts) 1236 { 1237 if (clock_gettime(CLOCK_MONOTONIC, ts) != 0) 1238 fatal("clock_gettime: %s", strerror(errno)); 1239 } 1240 1241 void 1242 monotime_tv(struct timeval *tv) 1243 { 1244 struct timespec ts; 1245 1246 monotime_ts(&ts); 1247 tv->tv_sec = ts.tv_sec; 1248 tv->tv_usec = ts.tv_nsec / 1000; 1249 } 1250 1251 time_t 1252 monotime(void) 1253 { 1254 struct timespec ts; 1255 1256 monotime_ts(&ts); 1257 return (ts.tv_sec); 1258 } 1259 1260 double 1261 monotime_double(void) 1262 { 1263 struct timespec ts; 1264 1265 monotime_ts(&ts); 1266 return (double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0; 1267 } 1268 1269 void 1270 bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) 1271 { 1272 bw->buflen = buflen; 1273 bw->rate = kbps; 1274 bw->thresh = buflen; 1275 bw->lamt = 0; 1276 timerclear(&bw->bwstart); 1277 timerclear(&bw->bwend); 1278 } 1279 1280 /* Callback from read/write loop to insert bandwidth-limiting delays */ 1281 void 1282 bandwidth_limit(struct bwlimit *bw, size_t read_len) 1283 { 1284 u_int64_t waitlen; 1285 struct timespec ts, rm; 1286 1287 bw->lamt += read_len; 1288 if (!timerisset(&bw->bwstart)) { 1289 monotime_tv(&bw->bwstart); 1290 return; 1291 } 1292 if (bw->lamt < bw->thresh) 1293 return; 1294 1295 monotime_tv(&bw->bwend); 1296 timersub(&bw->bwend, &bw->bwstart, &bw->bwend); 1297 if (!timerisset(&bw->bwend)) 1298 return; 1299 1300 bw->lamt *= 8; 1301 waitlen = (double)1000000L * bw->lamt / bw->rate; 1302 1303 bw->bwstart.tv_sec = waitlen / 1000000L; 1304 bw->bwstart.tv_usec = waitlen % 1000000L; 1305 1306 if (timercmp(&bw->bwstart, &bw->bwend, >)) { 1307 timersub(&bw->bwstart, &bw->bwend, &bw->bwend); 1308 1309 /* Adjust the wait time */ 1310 if (bw->bwend.tv_sec) { 1311 bw->thresh /= 2; 1312 if (bw->thresh < bw->buflen / 4) 1313 bw->thresh = bw->buflen / 4; 1314 } else if (bw->bwend.tv_usec < 10000) { 1315 bw->thresh *= 2; 1316 if (bw->thresh > bw->buflen * 8) 1317 bw->thresh = bw->buflen * 8; 1318 } 1319 1320 TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts); 1321 while (nanosleep(&ts, &rm) == -1) { 1322 if (errno != EINTR) 1323 break; 1324 ts = rm; 1325 } 1326 } 1327 1328 bw->lamt = 0; 1329 monotime_tv(&bw->bwstart); 1330 } 1331 1332 /* Make a template filename for mk[sd]temp() */ 1333 void 1334 mktemp_proto(char *s, size_t len) 1335 { 1336 const char *tmpdir; 1337 int r; 1338 1339 if ((tmpdir = getenv("TMPDIR")) != NULL) { 1340 r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir); 1341 if (r > 0 && (size_t)r < len) 1342 return; 1343 } 1344 r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX"); 1345 if (r < 0 || (size_t)r >= len) 1346 fatal("%s: template string too short", __func__); 1347 } 1348 1349 static const struct { 1350 const char *name; 1351 int value; 1352 } ipqos[] = { 1353 { "none", INT_MAX }, /* can't use 0 here; that's CS0 */ 1354 { "af11", IPTOS_DSCP_AF11 }, 1355 { "af12", IPTOS_DSCP_AF12 }, 1356 { "af13", IPTOS_DSCP_AF13 }, 1357 { "af21", IPTOS_DSCP_AF21 }, 1358 { "af22", IPTOS_DSCP_AF22 }, 1359 { "af23", IPTOS_DSCP_AF23 }, 1360 { "af31", IPTOS_DSCP_AF31 }, 1361 { "af32", IPTOS_DSCP_AF32 }, 1362 { "af33", IPTOS_DSCP_AF33 }, 1363 { "af41", IPTOS_DSCP_AF41 }, 1364 { "af42", IPTOS_DSCP_AF42 }, 1365 { "af43", IPTOS_DSCP_AF43 }, 1366 { "cs0", IPTOS_DSCP_CS0 }, 1367 { "cs1", IPTOS_DSCP_CS1 }, 1368 { "cs2", IPTOS_DSCP_CS2 }, 1369 { "cs3", IPTOS_DSCP_CS3 }, 1370 { "cs4", IPTOS_DSCP_CS4 }, 1371 { "cs5", IPTOS_DSCP_CS5 }, 1372 { "cs6", IPTOS_DSCP_CS6 }, 1373 { "cs7", IPTOS_DSCP_CS7 }, 1374 { "ef", IPTOS_DSCP_EF }, 1375 { "lowdelay", IPTOS_LOWDELAY }, 1376 { "throughput", IPTOS_THROUGHPUT }, 1377 { "reliability", IPTOS_RELIABILITY }, 1378 { NULL, -1 } 1379 }; 1380 1381 int 1382 parse_ipqos(const char *cp) 1383 { 1384 u_int i; 1385 char *ep; 1386 long val; 1387 1388 if (cp == NULL) 1389 return -1; 1390 for (i = 0; ipqos[i].name != NULL; i++) { 1391 if (strcasecmp(cp, ipqos[i].name) == 0) 1392 return ipqos[i].value; 1393 } 1394 /* Try parsing as an integer */ 1395 val = strtol(cp, &ep, 0); 1396 if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255) 1397 return -1; 1398 return val; 1399 } 1400 1401 const char * 1402 iptos2str(int iptos) 1403 { 1404 int i; 1405 static char iptos_str[sizeof "0xff"]; 1406 1407 for (i = 0; ipqos[i].name != NULL; i++) { 1408 if (ipqos[i].value == iptos) 1409 return ipqos[i].name; 1410 } 1411 snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos); 1412 return iptos_str; 1413 } 1414 1415 void 1416 lowercase(char *s) 1417 { 1418 for (; *s; s++) 1419 *s = tolower((u_char)*s); 1420 } 1421 1422 int 1423 unix_listener(const char *path, int backlog, int unlink_first) 1424 { 1425 struct sockaddr_un sunaddr; 1426 int saved_errno, sock; 1427 1428 memset(&sunaddr, 0, sizeof(sunaddr)); 1429 sunaddr.sun_family = AF_UNIX; 1430 if (strlcpy(sunaddr.sun_path, path, 1431 sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) { 1432 error("%s: path \"%s\" too long for Unix domain socket", 1433 __func__, path); 1434 errno = ENAMETOOLONG; 1435 return -1; 1436 } 1437 1438 sock = socket(PF_UNIX, SOCK_STREAM, 0); 1439 if (sock < 0) { 1440 saved_errno = errno; 1441 error("%s: socket: %.100s", __func__, strerror(errno)); 1442 errno = saved_errno; 1443 return -1; 1444 } 1445 if (unlink_first == 1) { 1446 if (unlink(path) != 0 && errno != ENOENT) 1447 error("unlink(%s): %.100s", path, strerror(errno)); 1448 } 1449 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { 1450 saved_errno = errno; 1451 error("%s: cannot bind to path %s: %s", 1452 __func__, path, strerror(errno)); 1453 close(sock); 1454 errno = saved_errno; 1455 return -1; 1456 } 1457 if (listen(sock, backlog) < 0) { 1458 saved_errno = errno; 1459 error("%s: cannot listen on path %s: %s", 1460 __func__, path, strerror(errno)); 1461 close(sock); 1462 unlink(path); 1463 errno = saved_errno; 1464 return -1; 1465 } 1466 return sock; 1467 } 1468 1469 /* 1470 * Compares two strings that maybe be NULL. Returns non-zero if strings 1471 * are both NULL or are identical, returns zero otherwise. 1472 */ 1473 static int 1474 strcmp_maybe_null(const char *a, const char *b) 1475 { 1476 if ((a == NULL && b != NULL) || (a != NULL && b == NULL)) 1477 return 0; 1478 if (a != NULL && strcmp(a, b) != 0) 1479 return 0; 1480 return 1; 1481 } 1482 1483 /* 1484 * Compare two forwards, returning non-zero if they are identical or 1485 * zero otherwise. 1486 */ 1487 int 1488 forward_equals(const struct Forward *a, const struct Forward *b) 1489 { 1490 if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0) 1491 return 0; 1492 if (a->listen_port != b->listen_port) 1493 return 0; 1494 if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0) 1495 return 0; 1496 if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0) 1497 return 0; 1498 if (a->connect_port != b->connect_port) 1499 return 0; 1500 if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0) 1501 return 0; 1502 /* allocated_port and handle are not checked */ 1503 return 1; 1504 } 1505 1506 /* returns 1 if process is already daemonized, 0 otherwise */ 1507 int 1508 daemonized(void) 1509 { 1510 int fd; 1511 1512 if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) { 1513 close(fd); 1514 return 0; /* have controlling terminal */ 1515 } 1516 if (getppid() != 1) 1517 return 0; /* parent is not init */ 1518 if (getsid(0) != getpid()) 1519 return 0; /* not session leader */ 1520 debug3("already daemonized"); 1521 return 1; 1522 } 1523 1524 1525 /* 1526 * Splits 's' into an argument vector. Handles quoted string and basic 1527 * escape characters (\\, \", \'). Caller must free the argument vector 1528 * and its members. 1529 */ 1530 int 1531 argv_split(const char *s, int *argcp, char ***argvp) 1532 { 1533 int r = SSH_ERR_INTERNAL_ERROR; 1534 int argc = 0, quote, i, j; 1535 char *arg, **argv = xcalloc(1, sizeof(*argv)); 1536 1537 *argvp = NULL; 1538 *argcp = 0; 1539 1540 for (i = 0; s[i] != '\0'; i++) { 1541 /* Skip leading whitespace */ 1542 if (s[i] == ' ' || s[i] == '\t') 1543 continue; 1544 1545 /* Start of a token */ 1546 quote = 0; 1547 if (s[i] == '\\' && 1548 (s[i + 1] == '\'' || s[i + 1] == '\"' || s[i + 1] == '\\')) 1549 i++; 1550 else if (s[i] == '\'' || s[i] == '"') 1551 quote = s[i++]; 1552 1553 argv = xreallocarray(argv, (argc + 2), sizeof(*argv)); 1554 arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1); 1555 argv[argc] = NULL; 1556 1557 /* Copy the token in, removing escapes */ 1558 for (j = 0; s[i] != '\0'; i++) { 1559 if (s[i] == '\\') { 1560 if (s[i + 1] == '\'' || 1561 s[i + 1] == '\"' || 1562 s[i + 1] == '\\') { 1563 i++; /* Skip '\' */ 1564 arg[j++] = s[i]; 1565 } else { 1566 /* Unrecognised escape */ 1567 arg[j++] = s[i]; 1568 } 1569 } else if (quote == 0 && (s[i] == ' ' || s[i] == '\t')) 1570 break; /* done */ 1571 else if (quote != 0 && s[i] == quote) 1572 break; /* done */ 1573 else 1574 arg[j++] = s[i]; 1575 } 1576 if (s[i] == '\0') { 1577 if (quote != 0) { 1578 /* Ran out of string looking for close quote */ 1579 r = SSH_ERR_INVALID_FORMAT; 1580 goto out; 1581 } 1582 break; 1583 } 1584 } 1585 /* Success */ 1586 *argcp = argc; 1587 *argvp = argv; 1588 argc = 0; 1589 argv = NULL; 1590 r = 0; 1591 out: 1592 if (argc != 0 && argv != NULL) { 1593 for (i = 0; i < argc; i++) 1594 free(argv[i]); 1595 free(argv); 1596 } 1597 return r; 1598 } 1599 1600 /* 1601 * Reassemble an argument vector into a string, quoting and escaping as 1602 * necessary. Caller must free returned string. 1603 */ 1604 char * 1605 argv_assemble(int argc, char **argv) 1606 { 1607 int i, j, ws, r; 1608 char c, *ret; 1609 struct sshbuf *buf, *arg; 1610 1611 if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL) 1612 fatal("%s: sshbuf_new failed", __func__); 1613 1614 for (i = 0; i < argc; i++) { 1615 ws = 0; 1616 sshbuf_reset(arg); 1617 for (j = 0; argv[i][j] != '\0'; j++) { 1618 r = 0; 1619 c = argv[i][j]; 1620 switch (c) { 1621 case ' ': 1622 case '\t': 1623 ws = 1; 1624 r = sshbuf_put_u8(arg, c); 1625 break; 1626 case '\\': 1627 case '\'': 1628 case '"': 1629 if ((r = sshbuf_put_u8(arg, '\\')) != 0) 1630 break; 1631 /* FALLTHROUGH */ 1632 default: 1633 r = sshbuf_put_u8(arg, c); 1634 break; 1635 } 1636 if (r != 0) 1637 fatal("%s: sshbuf_put_u8: %s", 1638 __func__, ssh_err(r)); 1639 } 1640 if ((i != 0 && (r = sshbuf_put_u8(buf, ' ')) != 0) || 1641 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) || 1642 (r = sshbuf_putb(buf, arg)) != 0 || 1643 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0)) 1644 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1645 } 1646 if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL) 1647 fatal("%s: malloc failed", __func__); 1648 memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf)); 1649 ret[sshbuf_len(buf)] = '\0'; 1650 sshbuf_free(buf); 1651 sshbuf_free(arg); 1652 return ret; 1653 } 1654 1655 /* Returns 0 if pid exited cleanly, non-zero otherwise */ 1656 int 1657 exited_cleanly(pid_t pid, const char *tag, const char *cmd, int quiet) 1658 { 1659 int status; 1660 1661 while (waitpid(pid, &status, 0) == -1) { 1662 if (errno != EINTR) { 1663 error("%s: waitpid: %s", tag, strerror(errno)); 1664 return -1; 1665 } 1666 } 1667 if (WIFSIGNALED(status)) { 1668 error("%s %s exited on signal %d", tag, cmd, WTERMSIG(status)); 1669 return -1; 1670 } else if (WEXITSTATUS(status) != 0) { 1671 do_log2(quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO, 1672 "%s %s failed, status %d", tag, cmd, WEXITSTATUS(status)); 1673 return -1; 1674 } 1675 return 0; 1676 } 1677 1678 /* 1679 * Check a given path for security. This is defined as all components 1680 * of the path to the file must be owned by either the owner of 1681 * of the file or root and no directories must be group or world writable. 1682 * 1683 * XXX Should any specific check be done for sym links ? 1684 * 1685 * Takes a file name, its stat information (preferably from fstat() to 1686 * avoid races), the uid of the expected owner, their home directory and an 1687 * error buffer plus max size as arguments. 1688 * 1689 * Returns 0 on success and -1 on failure 1690 */ 1691 int 1692 safe_path(const char *name, struct stat *stp, const char *pw_dir, 1693 uid_t uid, char *err, size_t errlen) 1694 { 1695 char buf[PATH_MAX], homedir[PATH_MAX]; 1696 char *cp; 1697 int comparehome = 0; 1698 struct stat st; 1699 1700 if (realpath(name, buf) == NULL) { 1701 snprintf(err, errlen, "realpath %s failed: %s", name, 1702 strerror(errno)); 1703 return -1; 1704 } 1705 if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) 1706 comparehome = 1; 1707 1708 if (!S_ISREG(stp->st_mode)) { 1709 snprintf(err, errlen, "%s is not a regular file", buf); 1710 return -1; 1711 } 1712 if ((stp->st_uid != 0 && stp->st_uid != uid) || 1713 (stp->st_mode & 022) != 0) { 1714 snprintf(err, errlen, "bad ownership or modes for file %s", 1715 buf); 1716 return -1; 1717 } 1718 1719 /* for each component of the canonical path, walking upwards */ 1720 for (;;) { 1721 if ((cp = dirname(buf)) == NULL) { 1722 snprintf(err, errlen, "dirname() failed"); 1723 return -1; 1724 } 1725 strlcpy(buf, cp, sizeof(buf)); 1726 1727 if (stat(buf, &st) < 0 || 1728 (st.st_uid != 0 && st.st_uid != uid) || 1729 (st.st_mode & 022) != 0) { 1730 snprintf(err, errlen, 1731 "bad ownership or modes for directory %s", buf); 1732 return -1; 1733 } 1734 1735 /* If are past the homedir then we can stop */ 1736 if (comparehome && strcmp(homedir, buf) == 0) 1737 break; 1738 1739 /* 1740 * dirname should always complete with a "/" path, 1741 * but we can be paranoid and check for "." too 1742 */ 1743 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) 1744 break; 1745 } 1746 return 0; 1747 } 1748 1749 /* 1750 * Version of safe_path() that accepts an open file descriptor to 1751 * avoid races. 1752 * 1753 * Returns 0 on success and -1 on failure 1754 */ 1755 int 1756 safe_path_fd(int fd, const char *file, struct passwd *pw, 1757 char *err, size_t errlen) 1758 { 1759 struct stat st; 1760 1761 /* check the open file to avoid races */ 1762 if (fstat(fd, &st) < 0) { 1763 snprintf(err, errlen, "cannot stat file %s: %s", 1764 file, strerror(errno)); 1765 return -1; 1766 } 1767 return safe_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); 1768 } 1769 1770 /* 1771 * Sets the value of the given variable in the environment. If the variable 1772 * already exists, its value is overridden. 1773 */ 1774 void 1775 child_set_env(char ***envp, u_int *envsizep, const char *name, 1776 const char *value) 1777 { 1778 char **env; 1779 u_int envsize; 1780 u_int i, namelen; 1781 1782 if (strchr(name, '=') != NULL) { 1783 error("Invalid environment variable \"%.100s\"", name); 1784 return; 1785 } 1786 1787 /* 1788 * Find the slot where the value should be stored. If the variable 1789 * already exists, we reuse the slot; otherwise we append a new slot 1790 * at the end of the array, expanding if necessary. 1791 */ 1792 env = *envp; 1793 namelen = strlen(name); 1794 for (i = 0; env[i]; i++) 1795 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') 1796 break; 1797 if (env[i]) { 1798 /* Reuse the slot. */ 1799 free(env[i]); 1800 } else { 1801 /* New variable. Expand if necessary. */ 1802 envsize = *envsizep; 1803 if (i >= envsize - 1) { 1804 if (envsize >= 1000) 1805 fatal("child_set_env: too many env vars"); 1806 envsize += 50; 1807 env = (*envp) = xreallocarray(env, envsize, sizeof(char *)); 1808 *envsizep = envsize; 1809 } 1810 /* Need to set the NULL pointer at end of array beyond the new slot. */ 1811 env[i + 1] = NULL; 1812 } 1813 1814 /* Allocate space and format the variable in the appropriate slot. */ 1815 /* XXX xasprintf */ 1816 env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); 1817 snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); 1818 } 1819 1820 /* 1821 * Check and optionally lowercase a domain name, also removes trailing '.' 1822 * Returns 1 on success and 0 on failure, storing an error message in errstr. 1823 */ 1824 int 1825 valid_domain(char *name, int makelower, const char **errstr) 1826 { 1827 size_t i, l = strlen(name); 1828 u_char c, last = '\0'; 1829 static char errbuf[256]; 1830 1831 if (l == 0) { 1832 strlcpy(errbuf, "empty domain name", sizeof(errbuf)); 1833 goto bad; 1834 } 1835 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) { 1836 snprintf(errbuf, sizeof(errbuf), "domain name \"%.100s\" " 1837 "starts with invalid character", name); 1838 goto bad; 1839 } 1840 for (i = 0; i < l; i++) { 1841 c = tolower((u_char)name[i]); 1842 if (makelower) 1843 name[i] = (char)c; 1844 if (last == '.' && c == '.') { 1845 snprintf(errbuf, sizeof(errbuf), "domain name " 1846 "\"%.100s\" contains consecutive separators", name); 1847 goto bad; 1848 } 1849 if (c != '.' && c != '-' && !isalnum(c) && 1850 c != '_') /* technically invalid, but common */ { 1851 snprintf(errbuf, sizeof(errbuf), "domain name " 1852 "\"%.100s\" contains invalid characters", name); 1853 goto bad; 1854 } 1855 last = c; 1856 } 1857 if (name[l - 1] == '.') 1858 name[l - 1] = '\0'; 1859 if (errstr != NULL) 1860 *errstr = NULL; 1861 return 1; 1862 bad: 1863 if (errstr != NULL) 1864 *errstr = errbuf; 1865 return 0; 1866 } 1867 1868 /* 1869 * Verify that a environment variable name (not including initial '$') is 1870 * valid; consisting of one or more alphanumeric or underscore characters only. 1871 * Returns 1 on valid, 0 otherwise. 1872 */ 1873 int 1874 valid_env_name(const char *name) 1875 { 1876 const char *cp; 1877 1878 if (name[0] == '\0') 1879 return 0; 1880 for (cp = name; *cp != '\0'; cp++) { 1881 if (!isalnum((u_char)*cp) && *cp != '_') 1882 return 0; 1883 } 1884 return 1; 1885 } 1886 1887 const char * 1888 atoi_err(const char *nptr, int *val) 1889 { 1890 const char *errstr = NULL; 1891 long long num; 1892 1893 if (nptr == NULL || *nptr == '\0') 1894 return "missing"; 1895 num = strtonum(nptr, 0, INT_MAX, &errstr); 1896 if (errstr == NULL) 1897 *val = (int)num; 1898 return errstr; 1899 } 1900 1901 int 1902 parse_absolute_time(const char *s, uint64_t *tp) 1903 { 1904 struct tm tm; 1905 time_t tt; 1906 char buf[32], *fmt; 1907 1908 *tp = 0; 1909 1910 /* 1911 * POSIX strptime says "The application shall ensure that there 1912 * is white-space or other non-alphanumeric characters between 1913 * any two conversion specifications" so arrange things this way. 1914 */ 1915 switch (strlen(s)) { 1916 case 8: /* YYYYMMDD */ 1917 fmt = "%Y-%m-%d"; 1918 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6); 1919 break; 1920 case 12: /* YYYYMMDDHHMM */ 1921 fmt = "%Y-%m-%dT%H:%M"; 1922 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s", 1923 s, s + 4, s + 6, s + 8, s + 10); 1924 break; 1925 case 14: /* YYYYMMDDHHMMSS */ 1926 fmt = "%Y-%m-%dT%H:%M:%S"; 1927 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s", 1928 s, s + 4, s + 6, s + 8, s + 10, s + 12); 1929 break; 1930 default: 1931 return SSH_ERR_INVALID_FORMAT; 1932 } 1933 1934 memset(&tm, 0, sizeof(tm)); 1935 if (strptime(buf, fmt, &tm) == NULL) 1936 return SSH_ERR_INVALID_FORMAT; 1937 if ((tt = mktime(&tm)) < 0) 1938 return SSH_ERR_INVALID_FORMAT; 1939 /* success */ 1940 *tp = (uint64_t)tt; 1941 return 0; 1942 } 1943 1944 void 1945 format_absolute_time(uint64_t t, char *buf, size_t len) 1946 { 1947 time_t tt = t > INT_MAX ? INT_MAX : t; /* XXX revisit in 2038 :P */ 1948 struct tm tm; 1949 1950 localtime_r(&tt, &tm); 1951 strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm); 1952 } 1953 1954 /* check if path is absolute */ 1955 int 1956 path_absolute(const char *path) 1957 { 1958 return (*path == '/') ? 1 : 0; 1959 } 1960