1 /* $NetBSD: misc.c,v 1.20 2019/04/20 17:16:40 christos Exp $ */ 2 /* $OpenBSD: misc.c,v 1.137 2019/01/23 21:50:56 dtucker 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.20 2019/04/20 17:16:40 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 < 0) { 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 < 0) { 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) < 0) 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, j; 1038 struct { 1039 const char *key; 1040 const char *repl; 1041 } keys[EXPAND_MAX_KEYS]; 1042 char buf[4096]; 1043 va_list ap; 1044 1045 /* Gather keys */ 1046 va_start(ap, string); 1047 for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) { 1048 keys[num_keys].key = va_arg(ap, char *); 1049 if (keys[num_keys].key == NULL) 1050 break; 1051 keys[num_keys].repl = va_arg(ap, char *); 1052 if (keys[num_keys].repl == NULL) 1053 fatal("%s: NULL replacement", __func__); 1054 } 1055 if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL) 1056 fatal("%s: too many keys", __func__); 1057 va_end(ap); 1058 1059 /* Expand string */ 1060 *buf = '\0'; 1061 for (i = 0; *string != '\0'; string++) { 1062 if (*string != '%') { 1063 append: 1064 buf[i++] = *string; 1065 if (i >= sizeof(buf)) 1066 fatal("%s: string too long", __func__); 1067 buf[i] = '\0'; 1068 continue; 1069 } 1070 string++; 1071 /* %% case */ 1072 if (*string == '%') 1073 goto append; 1074 if (*string == '\0') 1075 fatal("%s: invalid format", __func__); 1076 for (j = 0; j < num_keys; j++) { 1077 if (strchr(keys[j].key, *string) != NULL) { 1078 i = strlcat(buf, keys[j].repl, sizeof(buf)); 1079 if (i >= sizeof(buf)) 1080 fatal("%s: string too long", __func__); 1081 break; 1082 } 1083 } 1084 if (j >= num_keys) 1085 fatal("%s: unknown key %%%c", __func__, *string); 1086 } 1087 return (xstrdup(buf)); 1088 #undef EXPAND_MAX_KEYS 1089 } 1090 1091 int 1092 tun_open(int tun, int mode, char **ifname) 1093 { 1094 struct ifreq ifr; 1095 char name[100]; 1096 int fd = -1, sock; 1097 const char *tunbase = "tun"; 1098 1099 if (ifname != NULL) 1100 *ifname = NULL; 1101 1102 if (mode == SSH_TUNMODE_ETHERNET) 1103 tunbase = "tap"; 1104 1105 /* Open the tunnel device */ 1106 if (tun <= SSH_TUNID_MAX) { 1107 snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); 1108 fd = open(name, O_RDWR); 1109 } else if (tun == SSH_TUNID_ANY) { 1110 for (tun = 100; tun >= 0; tun--) { 1111 snprintf(name, sizeof(name), "/dev/%s%d", 1112 tunbase, tun); 1113 if ((fd = open(name, O_RDWR)) >= 0) 1114 break; 1115 } 1116 } else { 1117 debug("%s: invalid tunnel %u", __func__, tun); 1118 return -1; 1119 } 1120 1121 if (fd < 0) { 1122 debug("%s: %s open: %s", __func__, name, strerror(errno)); 1123 return -1; 1124 } 1125 1126 1127 #ifdef TUNSIFHEAD 1128 /* Turn on tunnel headers */ 1129 int flag = 1; 1130 if (mode != SSH_TUNMODE_ETHERNET && 1131 ioctl(fd, TUNSIFHEAD, &flag) == -1) { 1132 debug("%s: ioctl(%d, TUNSIFHEAD, 1): %s", __func__, fd, 1133 strerror(errno)); 1134 close(fd); 1135 return -1; 1136 } 1137 #endif 1138 1139 debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd); 1140 /* Bring interface up if it is not already */ 1141 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); 1142 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) 1143 goto failed; 1144 1145 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { 1146 debug("%s: get interface %s flags: %s", __func__, 1147 ifr.ifr_name, strerror(errno)); 1148 goto failed; 1149 } 1150 1151 if (!(ifr.ifr_flags & IFF_UP)) { 1152 ifr.ifr_flags |= IFF_UP; 1153 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { 1154 debug("%s: activate interface %s: %s", __func__, 1155 ifr.ifr_name, strerror(errno)); 1156 goto failed; 1157 } 1158 } 1159 1160 if (ifname != NULL) 1161 *ifname = xstrdup(ifr.ifr_name); 1162 1163 close(sock); 1164 return fd; 1165 1166 failed: 1167 if (fd >= 0) 1168 close(fd); 1169 if (sock >= 0) 1170 close(sock); 1171 debug("%s: failed to set %s mode %d: %s", __func__, ifr.ifr_name, 1172 mode, strerror(errno)); 1173 return -1; 1174 } 1175 1176 void 1177 sanitise_stdfd(void) 1178 { 1179 int nullfd, dupfd; 1180 1181 if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) { 1182 fprintf(stderr, "Couldn't open /dev/null: %s\n", 1183 strerror(errno)); 1184 exit(1); 1185 } 1186 while (++dupfd <= STDERR_FILENO) { 1187 /* Only populate closed fds. */ 1188 if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) { 1189 if (dup2(nullfd, dupfd) == -1) { 1190 fprintf(stderr, "dup2: %s\n", strerror(errno)); 1191 exit(1); 1192 } 1193 } 1194 } 1195 if (nullfd > STDERR_FILENO) 1196 close(nullfd); 1197 } 1198 1199 char * 1200 tohex(const void *vp, size_t l) 1201 { 1202 const u_char *p = (const u_char *)vp; 1203 char b[3], *r; 1204 size_t i, hl; 1205 1206 if (l > 65536) 1207 return xstrdup("tohex: length > 65536"); 1208 1209 hl = l * 2 + 1; 1210 r = xcalloc(1, hl); 1211 for (i = 0; i < l; i++) { 1212 snprintf(b, sizeof(b), "%02x", p[i]); 1213 strlcat(r, b, hl); 1214 } 1215 return (r); 1216 } 1217 1218 u_int64_t 1219 get_u64(const void *vp) 1220 { 1221 const u_char *p = (const u_char *)vp; 1222 u_int64_t v; 1223 1224 v = (u_int64_t)p[0] << 56; 1225 v |= (u_int64_t)p[1] << 48; 1226 v |= (u_int64_t)p[2] << 40; 1227 v |= (u_int64_t)p[3] << 32; 1228 v |= (u_int64_t)p[4] << 24; 1229 v |= (u_int64_t)p[5] << 16; 1230 v |= (u_int64_t)p[6] << 8; 1231 v |= (u_int64_t)p[7]; 1232 1233 return (v); 1234 } 1235 1236 u_int32_t 1237 get_u32(const void *vp) 1238 { 1239 const u_char *p = (const u_char *)vp; 1240 u_int32_t v; 1241 1242 v = (u_int32_t)p[0] << 24; 1243 v |= (u_int32_t)p[1] << 16; 1244 v |= (u_int32_t)p[2] << 8; 1245 v |= (u_int32_t)p[3]; 1246 1247 return (v); 1248 } 1249 1250 u_int32_t 1251 get_u32_le(const void *vp) 1252 { 1253 const u_char *p = (const u_char *)vp; 1254 u_int32_t v; 1255 1256 v = (u_int32_t)p[0]; 1257 v |= (u_int32_t)p[1] << 8; 1258 v |= (u_int32_t)p[2] << 16; 1259 v |= (u_int32_t)p[3] << 24; 1260 1261 return (v); 1262 } 1263 1264 u_int16_t 1265 get_u16(const void *vp) 1266 { 1267 const u_char *p = (const u_char *)vp; 1268 u_int16_t v; 1269 1270 v = (u_int16_t)p[0] << 8; 1271 v |= (u_int16_t)p[1]; 1272 1273 return (v); 1274 } 1275 1276 void 1277 put_u64(void *vp, u_int64_t v) 1278 { 1279 u_char *p = (u_char *)vp; 1280 1281 p[0] = (u_char)(v >> 56) & 0xff; 1282 p[1] = (u_char)(v >> 48) & 0xff; 1283 p[2] = (u_char)(v >> 40) & 0xff; 1284 p[3] = (u_char)(v >> 32) & 0xff; 1285 p[4] = (u_char)(v >> 24) & 0xff; 1286 p[5] = (u_char)(v >> 16) & 0xff; 1287 p[6] = (u_char)(v >> 8) & 0xff; 1288 p[7] = (u_char)v & 0xff; 1289 } 1290 1291 void 1292 put_u32(void *vp, u_int32_t v) 1293 { 1294 u_char *p = (u_char *)vp; 1295 1296 p[0] = (u_char)(v >> 24) & 0xff; 1297 p[1] = (u_char)(v >> 16) & 0xff; 1298 p[2] = (u_char)(v >> 8) & 0xff; 1299 p[3] = (u_char)v & 0xff; 1300 } 1301 1302 void 1303 put_u32_le(void *vp, u_int32_t v) 1304 { 1305 u_char *p = (u_char *)vp; 1306 1307 p[0] = (u_char)v & 0xff; 1308 p[1] = (u_char)(v >> 8) & 0xff; 1309 p[2] = (u_char)(v >> 16) & 0xff; 1310 p[3] = (u_char)(v >> 24) & 0xff; 1311 } 1312 1313 void 1314 put_u16(void *vp, u_int16_t v) 1315 { 1316 u_char *p = (u_char *)vp; 1317 1318 p[0] = (u_char)(v >> 8) & 0xff; 1319 p[1] = (u_char)v & 0xff; 1320 } 1321 1322 void 1323 ms_subtract_diff(struct timeval *start, int *ms) 1324 { 1325 struct timeval diff, finish; 1326 1327 monotime_tv(&finish); 1328 timersub(&finish, start, &diff); 1329 *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); 1330 } 1331 1332 void 1333 ms_to_timeval(struct timeval *tv, int ms) 1334 { 1335 if (ms < 0) 1336 ms = 0; 1337 tv->tv_sec = ms / 1000; 1338 tv->tv_usec = (ms % 1000) * 1000; 1339 } 1340 1341 void 1342 monotime_ts(struct timespec *ts) 1343 { 1344 if (clock_gettime(CLOCK_MONOTONIC, ts) != 0) 1345 fatal("clock_gettime: %s", strerror(errno)); 1346 } 1347 1348 void 1349 monotime_tv(struct timeval *tv) 1350 { 1351 struct timespec ts; 1352 1353 monotime_ts(&ts); 1354 tv->tv_sec = ts.tv_sec; 1355 tv->tv_usec = ts.tv_nsec / 1000; 1356 } 1357 1358 time_t 1359 monotime(void) 1360 { 1361 struct timespec ts; 1362 1363 monotime_ts(&ts); 1364 return (ts.tv_sec); 1365 } 1366 1367 double 1368 monotime_double(void) 1369 { 1370 struct timespec ts; 1371 1372 monotime_ts(&ts); 1373 return (double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0; 1374 } 1375 1376 void 1377 bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) 1378 { 1379 bw->buflen = buflen; 1380 bw->rate = kbps; 1381 bw->thresh = buflen; 1382 bw->lamt = 0; 1383 timerclear(&bw->bwstart); 1384 timerclear(&bw->bwend); 1385 } 1386 1387 /* Callback from read/write loop to insert bandwidth-limiting delays */ 1388 void 1389 bandwidth_limit(struct bwlimit *bw, size_t read_len) 1390 { 1391 u_int64_t waitlen; 1392 struct timespec ts, rm; 1393 1394 bw->lamt += read_len; 1395 if (!timerisset(&bw->bwstart)) { 1396 monotime_tv(&bw->bwstart); 1397 return; 1398 } 1399 if (bw->lamt < bw->thresh) 1400 return; 1401 1402 monotime_tv(&bw->bwend); 1403 timersub(&bw->bwend, &bw->bwstart, &bw->bwend); 1404 if (!timerisset(&bw->bwend)) 1405 return; 1406 1407 bw->lamt *= 8; 1408 waitlen = (double)1000000L * bw->lamt / bw->rate; 1409 1410 bw->bwstart.tv_sec = waitlen / 1000000L; 1411 bw->bwstart.tv_usec = waitlen % 1000000L; 1412 1413 if (timercmp(&bw->bwstart, &bw->bwend, >)) { 1414 timersub(&bw->bwstart, &bw->bwend, &bw->bwend); 1415 1416 /* Adjust the wait time */ 1417 if (bw->bwend.tv_sec) { 1418 bw->thresh /= 2; 1419 if (bw->thresh < bw->buflen / 4) 1420 bw->thresh = bw->buflen / 4; 1421 } else if (bw->bwend.tv_usec < 10000) { 1422 bw->thresh *= 2; 1423 if (bw->thresh > bw->buflen * 8) 1424 bw->thresh = bw->buflen * 8; 1425 } 1426 1427 TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts); 1428 while (nanosleep(&ts, &rm) == -1) { 1429 if (errno != EINTR) 1430 break; 1431 ts = rm; 1432 } 1433 } 1434 1435 bw->lamt = 0; 1436 monotime_tv(&bw->bwstart); 1437 } 1438 1439 /* Make a template filename for mk[sd]temp() */ 1440 void 1441 mktemp_proto(char *s, size_t len) 1442 { 1443 const char *tmpdir; 1444 int r; 1445 1446 if ((tmpdir = getenv("TMPDIR")) != NULL) { 1447 r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir); 1448 if (r > 0 && (size_t)r < len) 1449 return; 1450 } 1451 r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX"); 1452 if (r < 0 || (size_t)r >= len) 1453 fatal("%s: template string too short", __func__); 1454 } 1455 1456 static const struct { 1457 const char *name; 1458 int value; 1459 } ipqos[] = { 1460 { "none", INT_MAX }, /* can't use 0 here; that's CS0 */ 1461 { "af11", IPTOS_DSCP_AF11 }, 1462 { "af12", IPTOS_DSCP_AF12 }, 1463 { "af13", IPTOS_DSCP_AF13 }, 1464 { "af21", IPTOS_DSCP_AF21 }, 1465 { "af22", IPTOS_DSCP_AF22 }, 1466 { "af23", IPTOS_DSCP_AF23 }, 1467 { "af31", IPTOS_DSCP_AF31 }, 1468 { "af32", IPTOS_DSCP_AF32 }, 1469 { "af33", IPTOS_DSCP_AF33 }, 1470 { "af41", IPTOS_DSCP_AF41 }, 1471 { "af42", IPTOS_DSCP_AF42 }, 1472 { "af43", IPTOS_DSCP_AF43 }, 1473 { "cs0", IPTOS_DSCP_CS0 }, 1474 { "cs1", IPTOS_DSCP_CS1 }, 1475 { "cs2", IPTOS_DSCP_CS2 }, 1476 { "cs3", IPTOS_DSCP_CS3 }, 1477 { "cs4", IPTOS_DSCP_CS4 }, 1478 { "cs5", IPTOS_DSCP_CS5 }, 1479 { "cs6", IPTOS_DSCP_CS6 }, 1480 { "cs7", IPTOS_DSCP_CS7 }, 1481 { "ef", IPTOS_DSCP_EF }, 1482 { "lowdelay", IPTOS_LOWDELAY }, 1483 { "throughput", IPTOS_THROUGHPUT }, 1484 { "reliability", IPTOS_RELIABILITY }, 1485 { NULL, -1 } 1486 }; 1487 1488 int 1489 parse_ipqos(const char *cp) 1490 { 1491 u_int i; 1492 char *ep; 1493 long val; 1494 1495 if (cp == NULL) 1496 return -1; 1497 for (i = 0; ipqos[i].name != NULL; i++) { 1498 if (strcasecmp(cp, ipqos[i].name) == 0) 1499 return ipqos[i].value; 1500 } 1501 /* Try parsing as an integer */ 1502 val = strtol(cp, &ep, 0); 1503 if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255) 1504 return -1; 1505 return val; 1506 } 1507 1508 const char * 1509 iptos2str(int iptos) 1510 { 1511 int i; 1512 static char iptos_str[sizeof "0xff"]; 1513 1514 for (i = 0; ipqos[i].name != NULL; i++) { 1515 if (ipqos[i].value == iptos) 1516 return ipqos[i].name; 1517 } 1518 snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos); 1519 return iptos_str; 1520 } 1521 1522 void 1523 lowercase(char *s) 1524 { 1525 for (; *s; s++) 1526 *s = tolower((u_char)*s); 1527 } 1528 1529 int 1530 unix_listener(const char *path, int backlog, int unlink_first) 1531 { 1532 struct sockaddr_un sunaddr; 1533 int saved_errno, sock; 1534 1535 memset(&sunaddr, 0, sizeof(sunaddr)); 1536 sunaddr.sun_family = AF_UNIX; 1537 if (strlcpy(sunaddr.sun_path, path, 1538 sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) { 1539 error("%s: path \"%s\" too long for Unix domain socket", 1540 __func__, path); 1541 errno = ENAMETOOLONG; 1542 return -1; 1543 } 1544 1545 sock = socket(PF_UNIX, SOCK_STREAM, 0); 1546 if (sock < 0) { 1547 saved_errno = errno; 1548 error("%s: socket: %.100s", __func__, strerror(errno)); 1549 errno = saved_errno; 1550 return -1; 1551 } 1552 if (unlink_first == 1) { 1553 if (unlink(path) != 0 && errno != ENOENT) 1554 error("unlink(%s): %.100s", path, strerror(errno)); 1555 } 1556 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { 1557 saved_errno = errno; 1558 error("%s: cannot bind to path %s: %s", 1559 __func__, path, strerror(errno)); 1560 close(sock); 1561 errno = saved_errno; 1562 return -1; 1563 } 1564 if (listen(sock, backlog) < 0) { 1565 saved_errno = errno; 1566 error("%s: cannot listen on path %s: %s", 1567 __func__, path, strerror(errno)); 1568 close(sock); 1569 unlink(path); 1570 errno = saved_errno; 1571 return -1; 1572 } 1573 return sock; 1574 } 1575 1576 /* 1577 * Compares two strings that maybe be NULL. Returns non-zero if strings 1578 * are both NULL or are identical, returns zero otherwise. 1579 */ 1580 static int 1581 strcmp_maybe_null(const char *a, const char *b) 1582 { 1583 if ((a == NULL && b != NULL) || (a != NULL && b == NULL)) 1584 return 0; 1585 if (a != NULL && strcmp(a, b) != 0) 1586 return 0; 1587 return 1; 1588 } 1589 1590 /* 1591 * Compare two forwards, returning non-zero if they are identical or 1592 * zero otherwise. 1593 */ 1594 int 1595 forward_equals(const struct Forward *a, const struct Forward *b) 1596 { 1597 if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0) 1598 return 0; 1599 if (a->listen_port != b->listen_port) 1600 return 0; 1601 if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0) 1602 return 0; 1603 if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0) 1604 return 0; 1605 if (a->connect_port != b->connect_port) 1606 return 0; 1607 if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0) 1608 return 0; 1609 /* allocated_port and handle are not checked */ 1610 return 1; 1611 } 1612 1613 /* returns 1 if process is already daemonized, 0 otherwise */ 1614 int 1615 daemonized(void) 1616 { 1617 int fd; 1618 1619 if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) { 1620 close(fd); 1621 return 0; /* have controlling terminal */ 1622 } 1623 if (getppid() != 1) 1624 return 0; /* parent is not init */ 1625 if (getsid(0) != getpid()) 1626 return 0; /* not session leader */ 1627 debug3("already daemonized"); 1628 return 1; 1629 } 1630 1631 1632 /* 1633 * Splits 's' into an argument vector. Handles quoted string and basic 1634 * escape characters (\\, \", \'). Caller must free the argument vector 1635 * and its members. 1636 */ 1637 int 1638 argv_split(const char *s, int *argcp, char ***argvp) 1639 { 1640 int r = SSH_ERR_INTERNAL_ERROR; 1641 int argc = 0, quote, i, j; 1642 char *arg, **argv = xcalloc(1, sizeof(*argv)); 1643 1644 *argvp = NULL; 1645 *argcp = 0; 1646 1647 for (i = 0; s[i] != '\0'; i++) { 1648 /* Skip leading whitespace */ 1649 if (s[i] == ' ' || s[i] == '\t') 1650 continue; 1651 1652 /* Start of a token */ 1653 quote = 0; 1654 if (s[i] == '\\' && 1655 (s[i + 1] == '\'' || s[i + 1] == '\"' || s[i + 1] == '\\')) 1656 i++; 1657 else if (s[i] == '\'' || s[i] == '"') 1658 quote = s[i++]; 1659 1660 argv = xreallocarray(argv, (argc + 2), sizeof(*argv)); 1661 arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1); 1662 argv[argc] = NULL; 1663 1664 /* Copy the token in, removing escapes */ 1665 for (j = 0; s[i] != '\0'; i++) { 1666 if (s[i] == '\\') { 1667 if (s[i + 1] == '\'' || 1668 s[i + 1] == '\"' || 1669 s[i + 1] == '\\') { 1670 i++; /* Skip '\' */ 1671 arg[j++] = s[i]; 1672 } else { 1673 /* Unrecognised escape */ 1674 arg[j++] = s[i]; 1675 } 1676 } else if (quote == 0 && (s[i] == ' ' || s[i] == '\t')) 1677 break; /* done */ 1678 else if (quote != 0 && s[i] == quote) 1679 break; /* done */ 1680 else 1681 arg[j++] = s[i]; 1682 } 1683 if (s[i] == '\0') { 1684 if (quote != 0) { 1685 /* Ran out of string looking for close quote */ 1686 r = SSH_ERR_INVALID_FORMAT; 1687 goto out; 1688 } 1689 break; 1690 } 1691 } 1692 /* Success */ 1693 *argcp = argc; 1694 *argvp = argv; 1695 argc = 0; 1696 argv = NULL; 1697 r = 0; 1698 out: 1699 if (argc != 0 && argv != NULL) { 1700 for (i = 0; i < argc; i++) 1701 free(argv[i]); 1702 free(argv); 1703 } 1704 return r; 1705 } 1706 1707 /* 1708 * Reassemble an argument vector into a string, quoting and escaping as 1709 * necessary. Caller must free returned string. 1710 */ 1711 char * 1712 argv_assemble(int argc, char **argv) 1713 { 1714 int i, j, ws, r; 1715 char c, *ret; 1716 struct sshbuf *buf, *arg; 1717 1718 if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL) 1719 fatal("%s: sshbuf_new failed", __func__); 1720 1721 for (i = 0; i < argc; i++) { 1722 ws = 0; 1723 sshbuf_reset(arg); 1724 for (j = 0; argv[i][j] != '\0'; j++) { 1725 r = 0; 1726 c = argv[i][j]; 1727 switch (c) { 1728 case ' ': 1729 case '\t': 1730 ws = 1; 1731 r = sshbuf_put_u8(arg, c); 1732 break; 1733 case '\\': 1734 case '\'': 1735 case '"': 1736 if ((r = sshbuf_put_u8(arg, '\\')) != 0) 1737 break; 1738 /* FALLTHROUGH */ 1739 default: 1740 r = sshbuf_put_u8(arg, c); 1741 break; 1742 } 1743 if (r != 0) 1744 fatal("%s: sshbuf_put_u8: %s", 1745 __func__, ssh_err(r)); 1746 } 1747 if ((i != 0 && (r = sshbuf_put_u8(buf, ' ')) != 0) || 1748 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) || 1749 (r = sshbuf_putb(buf, arg)) != 0 || 1750 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0)) 1751 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1752 } 1753 if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL) 1754 fatal("%s: malloc failed", __func__); 1755 memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf)); 1756 ret[sshbuf_len(buf)] = '\0'; 1757 sshbuf_free(buf); 1758 sshbuf_free(arg); 1759 return ret; 1760 } 1761 1762 /* Returns 0 if pid exited cleanly, non-zero otherwise */ 1763 int 1764 exited_cleanly(pid_t pid, const char *tag, const char *cmd, int quiet) 1765 { 1766 int status; 1767 1768 while (waitpid(pid, &status, 0) == -1) { 1769 if (errno != EINTR) { 1770 error("%s: waitpid: %s", tag, strerror(errno)); 1771 return -1; 1772 } 1773 } 1774 if (WIFSIGNALED(status)) { 1775 error("%s %s exited on signal %d", tag, cmd, WTERMSIG(status)); 1776 return -1; 1777 } else if (WEXITSTATUS(status) != 0) { 1778 do_log2(quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO, 1779 "%s %s failed, status %d", tag, cmd, WEXITSTATUS(status)); 1780 return -1; 1781 } 1782 return 0; 1783 } 1784 1785 /* 1786 * Check a given path for security. This is defined as all components 1787 * of the path to the file must be owned by either the owner of 1788 * of the file or root and no directories must be group or world writable. 1789 * 1790 * XXX Should any specific check be done for sym links ? 1791 * 1792 * Takes a file name, its stat information (preferably from fstat() to 1793 * avoid races), the uid of the expected owner, their home directory and an 1794 * error buffer plus max size as arguments. 1795 * 1796 * Returns 0 on success and -1 on failure 1797 */ 1798 int 1799 safe_path(const char *name, struct stat *stp, const char *pw_dir, 1800 uid_t uid, char *err, size_t errlen) 1801 { 1802 char buf[PATH_MAX], homedir[PATH_MAX]; 1803 char *cp; 1804 int comparehome = 0; 1805 struct stat st; 1806 1807 if (realpath(name, buf) == NULL) { 1808 snprintf(err, errlen, "realpath %s failed: %s", name, 1809 strerror(errno)); 1810 return -1; 1811 } 1812 if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) 1813 comparehome = 1; 1814 1815 if (!S_ISREG(stp->st_mode)) { 1816 snprintf(err, errlen, "%s is not a regular file", buf); 1817 return -1; 1818 } 1819 if ((stp->st_uid != 0 && stp->st_uid != uid) || 1820 (stp->st_mode & 022) != 0) { 1821 snprintf(err, errlen, "bad ownership or modes for file %s", 1822 buf); 1823 return -1; 1824 } 1825 1826 /* for each component of the canonical path, walking upwards */ 1827 for (;;) { 1828 if ((cp = dirname(buf)) == NULL) { 1829 snprintf(err, errlen, "dirname() failed"); 1830 return -1; 1831 } 1832 strlcpy(buf, cp, sizeof(buf)); 1833 1834 if (stat(buf, &st) < 0 || 1835 (st.st_uid != 0 && st.st_uid != uid) || 1836 (st.st_mode & 022) != 0) { 1837 snprintf(err, errlen, 1838 "bad ownership or modes for directory %s", buf); 1839 return -1; 1840 } 1841 1842 /* If are past the homedir then we can stop */ 1843 if (comparehome && strcmp(homedir, buf) == 0) 1844 break; 1845 1846 /* 1847 * dirname should always complete with a "/" path, 1848 * but we can be paranoid and check for "." too 1849 */ 1850 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) 1851 break; 1852 } 1853 return 0; 1854 } 1855 1856 /* 1857 * Version of safe_path() that accepts an open file descriptor to 1858 * avoid races. 1859 * 1860 * Returns 0 on success and -1 on failure 1861 */ 1862 int 1863 safe_path_fd(int fd, const char *file, struct passwd *pw, 1864 char *err, size_t errlen) 1865 { 1866 struct stat st; 1867 1868 /* check the open file to avoid races */ 1869 if (fstat(fd, &st) < 0) { 1870 snprintf(err, errlen, "cannot stat file %s: %s", 1871 file, strerror(errno)); 1872 return -1; 1873 } 1874 return safe_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); 1875 } 1876 1877 /* 1878 * Sets the value of the given variable in the environment. If the variable 1879 * already exists, its value is overridden. 1880 */ 1881 void 1882 child_set_env(char ***envp, u_int *envsizep, const char *name, 1883 const char *value) 1884 { 1885 char **env; 1886 u_int envsize; 1887 u_int i, namelen; 1888 1889 if (strchr(name, '=') != NULL) { 1890 error("Invalid environment variable \"%.100s\"", name); 1891 return; 1892 } 1893 1894 /* 1895 * Find the slot where the value should be stored. If the variable 1896 * already exists, we reuse the slot; otherwise we append a new slot 1897 * at the end of the array, expanding if necessary. 1898 */ 1899 env = *envp; 1900 namelen = strlen(name); 1901 for (i = 0; env[i]; i++) 1902 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') 1903 break; 1904 if (env[i]) { 1905 /* Reuse the slot. */ 1906 free(env[i]); 1907 } else { 1908 /* New variable. Expand if necessary. */ 1909 envsize = *envsizep; 1910 if (i >= envsize - 1) { 1911 if (envsize >= 1000) 1912 fatal("child_set_env: too many env vars"); 1913 envsize += 50; 1914 env = (*envp) = xreallocarray(env, envsize, sizeof(char *)); 1915 *envsizep = envsize; 1916 } 1917 /* Need to set the NULL pointer at end of array beyond the new slot. */ 1918 env[i + 1] = NULL; 1919 } 1920 1921 /* Allocate space and format the variable in the appropriate slot. */ 1922 /* XXX xasprintf */ 1923 env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); 1924 snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); 1925 } 1926 1927 /* 1928 * Check and optionally lowercase a domain name, also removes trailing '.' 1929 * Returns 1 on success and 0 on failure, storing an error message in errstr. 1930 */ 1931 int 1932 valid_domain(char *name, int makelower, const char **errstr) 1933 { 1934 size_t i, l = strlen(name); 1935 u_char c, last = '\0'; 1936 static char errbuf[256]; 1937 1938 if (l == 0) { 1939 strlcpy(errbuf, "empty domain name", sizeof(errbuf)); 1940 goto bad; 1941 } 1942 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) { 1943 snprintf(errbuf, sizeof(errbuf), "domain name \"%.100s\" " 1944 "starts with invalid character", name); 1945 goto bad; 1946 } 1947 for (i = 0; i < l; i++) { 1948 c = tolower((u_char)name[i]); 1949 if (makelower) 1950 name[i] = (char)c; 1951 if (last == '.' && c == '.') { 1952 snprintf(errbuf, sizeof(errbuf), "domain name " 1953 "\"%.100s\" contains consecutive separators", name); 1954 goto bad; 1955 } 1956 if (c != '.' && c != '-' && !isalnum(c) && 1957 c != '_') /* technically invalid, but common */ { 1958 snprintf(errbuf, sizeof(errbuf), "domain name " 1959 "\"%.100s\" contains invalid characters", name); 1960 goto bad; 1961 } 1962 last = c; 1963 } 1964 if (name[l - 1] == '.') 1965 name[l - 1] = '\0'; 1966 if (errstr != NULL) 1967 *errstr = NULL; 1968 return 1; 1969 bad: 1970 if (errstr != NULL) 1971 *errstr = errbuf; 1972 return 0; 1973 } 1974 1975 /* 1976 * Verify that a environment variable name (not including initial '$') is 1977 * valid; consisting of one or more alphanumeric or underscore characters only. 1978 * Returns 1 on valid, 0 otherwise. 1979 */ 1980 int 1981 valid_env_name(const char *name) 1982 { 1983 const char *cp; 1984 1985 if (name[0] == '\0') 1986 return 0; 1987 for (cp = name; *cp != '\0'; cp++) { 1988 if (!isalnum((u_char)*cp) && *cp != '_') 1989 return 0; 1990 } 1991 return 1; 1992 } 1993 1994 const char * 1995 atoi_err(const char *nptr, int *val) 1996 { 1997 const char *errstr = NULL; 1998 long long num; 1999 2000 if (nptr == NULL || *nptr == '\0') 2001 return "missing"; 2002 num = strtonum(nptr, 0, INT_MAX, &errstr); 2003 if (errstr == NULL) 2004 *val = (int)num; 2005 return errstr; 2006 } 2007 2008 int 2009 parse_absolute_time(const char *s, uint64_t *tp) 2010 { 2011 struct tm tm; 2012 time_t tt; 2013 char buf[32]; 2014 const char *fmt; 2015 2016 *tp = 0; 2017 2018 /* 2019 * POSIX strptime says "The application shall ensure that there 2020 * is white-space or other non-alphanumeric characters between 2021 * any two conversion specifications" so arrange things this way. 2022 */ 2023 switch (strlen(s)) { 2024 case 8: /* YYYYMMDD */ 2025 fmt = "%Y-%m-%d"; 2026 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6); 2027 break; 2028 case 12: /* YYYYMMDDHHMM */ 2029 fmt = "%Y-%m-%dT%H:%M"; 2030 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s", 2031 s, s + 4, s + 6, s + 8, s + 10); 2032 break; 2033 case 14: /* YYYYMMDDHHMMSS */ 2034 fmt = "%Y-%m-%dT%H:%M:%S"; 2035 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s", 2036 s, s + 4, s + 6, s + 8, s + 10, s + 12); 2037 break; 2038 default: 2039 return SSH_ERR_INVALID_FORMAT; 2040 } 2041 2042 memset(&tm, 0, sizeof(tm)); 2043 if (strptime(buf, fmt, &tm) == NULL) 2044 return SSH_ERR_INVALID_FORMAT; 2045 if ((tt = mktime(&tm)) < 0) 2046 return SSH_ERR_INVALID_FORMAT; 2047 /* success */ 2048 *tp = (uint64_t)tt; 2049 return 0; 2050 } 2051 2052 void 2053 format_absolute_time(uint64_t t, char *buf, size_t len) 2054 { 2055 time_t tt = t > INT_MAX ? INT_MAX : t; /* XXX revisit in 2038 :P */ 2056 struct tm tm; 2057 2058 localtime_r(&tt, &tm); 2059 strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm); 2060 } 2061 2062 /* check if path is absolute */ 2063 int 2064 path_absolute(const char *path) 2065 { 2066 return (*path == '/') ? 1 : 0; 2067 } 2068