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