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