Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/crypto/external/bsd/openssh/dist/misc.c,v rcsdiff: /ftp/cvs/cvsroot/src/crypto/external/bsd/openssh/dist/misc.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.6.8.1 retrieving revision 1.7 diff -u -p -r1.6.8.1 -r1.7 --- src/crypto/external/bsd/openssh/dist/misc.c 2017/08/15 04:39:21 1.6.8.1 +++ src/crypto/external/bsd/openssh/dist/misc.c 2012/05/02 02:41:08 1.7 @@ -1,5 +1,5 @@ -/* $NetBSD: misc.c,v 1.6.8.1 2017/08/15 04:39:21 snj Exp $ */ -/* $OpenBSD: misc.c,v 1.109 2017/03/14 00:55:37 dtucker Exp $ */ +/* $NetBSD: misc.c,v 1.7 2012/05/02 02:41:08 christos Exp $ */ +/* $OpenBSD: misc.c,v 1.86 2011/09/05 05:59:08 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -26,26 +26,24 @@ */ #include "includes.h" -__RCSID("$NetBSD: misc.c,v 1.6.8.1 2017/08/15 04:39:21 snj Exp $"); +__RCSID("$NetBSD: misc.c,v 1.7 2012/05/02 02:41:08 christos Exp $"); #include #include #include -#include -#include +#include #include #include #include +#include #include #include -#include #include #include #include #include #include -#include #include #include #include @@ -79,9 +77,9 @@ set_nonblock(int fd) { int val; - val = fcntl(fd, F_GETFL); + val = fcntl(fd, F_GETFL, 0); if (val < 0) { - error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); + error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); return (-1); } if (val & O_NONBLOCK) { @@ -103,9 +101,9 @@ unset_nonblock(int fd) { int val; - val = fcntl(fd, F_GETFL); + val = fcntl(fd, F_GETFL, 0); if (val < 0) { - error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); + error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); return (-1); } if (!(val & O_NONBLOCK)) { @@ -125,7 +123,7 @@ unset_nonblock(int fd) const char * ssh_gai_strerror(int gaierr) { - if (gaierr == EAI_SYSTEM && errno != 0) + if (gaierr == EAI_SYSTEM) return strerror(errno); return gai_strerror(gaierr); } @@ -243,13 +241,13 @@ a2tun(const char *s, int *remote) *remote = SSH_TUNID_ANY; sp = xstrdup(s); if ((ep = strchr(sp, ':')) == NULL) { - free(sp); + xfree(sp); return (a2tun(s, NULL)); } ep[0] = '\0'; ep++; *remote = a2tun(ep, NULL); tun = a2tun(sp, NULL); - free(sp); + xfree(sp); return (*remote == SSH_TUNID_ERR ? *remote : tun); } @@ -293,7 +291,7 @@ a2tun(const char *s, int *remote) long convtime(const char *s) { - long total, secs, multiplier = 1; + long total, secs; const char *p; char *endp; @@ -320,28 +318,23 @@ convtime(const char *s) break; case 'm': case 'M': - multiplier = MINUTES; + secs *= MINUTES; break; case 'h': case 'H': - multiplier = HOURS; + secs *= HOURS; break; case 'd': case 'D': - multiplier = DAYS; + secs *= DAYS; break; case 'w': case 'W': - multiplier = WEEKS; + secs *= WEEKS; break; default: return -1; } - if (secs >= LONG_MAX / multiplier) - return -1; - secs *= multiplier; - if (total >= LONG_MAX - secs) - return -1; total += secs; if (total < 0) return -1; @@ -443,67 +436,6 @@ colon(char *cp) return NULL; } -/* - * Parse a [user@]host[:port] string. - * Caller must free returned user and host. - * Any of the pointer return arguments may be NULL (useful for syntax checking). - * If user was not specified then *userp will be set to NULL. - * If port was not specified then *portp will be -1. - * Returns 0 on success, -1 on failure. - */ -int -parse_user_host_port(const char *s, char **userp, char **hostp, int *portp) -{ - char *sdup, *cp, *tmp; - char *user = NULL, *host = NULL; - int port = -1, ret = -1; - - if (userp != NULL) - *userp = NULL; - if (hostp != NULL) - *hostp = NULL; - if (portp != NULL) - *portp = -1; - - if ((sdup = tmp = strdup(s)) == NULL) - return -1; - /* Extract optional username */ - if ((cp = strchr(tmp, '@')) != NULL) { - *cp = '\0'; - if (*tmp == '\0') - goto out; - if ((user = strdup(tmp)) == NULL) - goto out; - tmp = cp + 1; - } - /* Extract mandatory hostname */ - if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0') - goto out; - host = xstrdup(cleanhostname(cp)); - /* Convert and verify optional port */ - if (tmp != NULL && *tmp != '\0') { - if ((port = a2port(tmp)) <= 0) - goto out; - } - /* Success */ - if (userp != NULL) { - *userp = user; - user = NULL; - } - if (hostp != NULL) { - *hostp = host; - host = NULL; - } - if (portp != NULL) - *portp = port; - ret = 0; - out: - free(sdup); - free(user); - free(host); - return ret; -} - /* function to assist building execv() arguments */ void addargs(arglist *args, const char *fmt, ...) @@ -526,7 +458,7 @@ addargs(arglist *args, const char *fmt, } else if (args->num+2 >= nalloc) nalloc *= 2; - args->list = xreallocarray(args->list, nalloc, sizeof(char *)); + args->list = xrealloc(args->list, nalloc, sizeof(char *)); args->nalloc = nalloc; args->list[args->num++] = cp; args->list[args->num] = NULL; @@ -548,7 +480,7 @@ replacearg(arglist *args, u_int which, c if (which >= args->num) fatal("replacearg: tried to replace invalid arg %d >= %d", which, args->num); - free(args->list[which]); + xfree(args->list[which]); args->list[which] = cp; } @@ -559,8 +491,8 @@ freeargs(arglist *args) if (args->list != NULL) { for (i = 0; i < args->num; i++) - free(args->list[i]); - free(args->list); + xfree(args->list[i]); + xfree(args->list); args->nalloc = args->num = 0; args->list = NULL; } @@ -573,8 +505,8 @@ freeargs(arglist *args) char * tilde_expand_filename(const char *filename, uid_t uid) { - const char *path, *sep; - char user[128], *ret, *homedir; + const char *path, *homedir; + char user[128], ret[MAXPATHLEN]; struct passwd *pw; u_int len, slash; @@ -599,21 +531,22 @@ tilde_expand_filename(const char *filena homedir = pw->pw_dir; } + if (strlcpy(ret, homedir, sizeof(ret)) >= sizeof(ret)) + fatal("tilde_expand_filename: Path too long"); + /* Make sure directory has a trailing '/' */ len = strlen(homedir); - if (len == 0 || homedir[len - 1] != '/') - sep = "/"; - else - sep = ""; + if ((len == 0 || homedir[len - 1] != '/') && + strlcat(ret, "/", sizeof(ret)) >= sizeof(ret)) + fatal("tilde_expand_filename: Path too long"); /* Skip leading '/' from specified path */ if (path != NULL) filename = path + 1; - - if (xasprintf(&ret, "%s%s%s", homedir, sep, filename) >= PATH_MAX) + if (strlcat(ret, filename, sizeof(ret)) >= sizeof(ret)) fatal("tilde_expand_filename: Path too long"); - return (ret); + return (xstrdup(ret)); } /* @@ -663,8 +596,6 @@ percent_expand(const char *string, ...) /* %% case */ if (*string == '%') goto append; - if (*string == '\0') - fatal("%s: invalid format", __func__); for (j = 0; j < num_keys; j++) { if (strchr(keys[j].key, *string) != NULL) { i = strlcat(buf, keys[j].repl, sizeof(buf)); @@ -709,38 +640,35 @@ int tun_open(int tun, int mode) { struct ifreq ifr; - char name[100]; - int fd = -1, sock; - const char *tunbase = "tun"; - - if (mode == SSH_TUNMODE_ETHERNET) - tunbase = "tap"; + int fd = -1, sock, flag; + const char *tunbase = mode == SSH_TUNMODE_ETHERNET ? "tap" : "tun"; /* Open the tunnel device */ if (tun <= SSH_TUNID_MAX) { - snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); - fd = open(name, O_RDWR); + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), + "/dev/%s%d", tunbase, tun); + fd = open(ifr.ifr_name, O_RDWR); } else if (tun == SSH_TUNID_ANY) { for (tun = 100; tun >= 0; tun--) { - snprintf(name, sizeof(name), "/dev/%s%d", - tunbase, tun); - if ((fd = open(name, O_RDWR)) >= 0) + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), + "/dev/%s%d", tunbase, tun); + if ((fd = open(ifr.ifr_name, O_RDWR)) >= 0) break; } } else { debug("%s: invalid tunnel %u", __func__, tun); - return -1; + return (-1); } if (fd < 0) { - debug("%s: %s open: %s", __func__, name, strerror(errno)); - return -1; + debug("%s: %s open failed: %s", __func__, ifr.ifr_name, + strerror(errno)); + return (-1); } -#ifdef TUNSIFHEAD /* Turn on tunnel headers */ - int flag = 1; + flag = 1; if (mode != SSH_TUNMODE_ETHERNET && ioctl(fd, TUNSIFHEAD, &flag) == -1) { debug("%s: ioctl(%d, TUNSIFHEAD, 1): %s", __func__, fd, @@ -748,31 +676,34 @@ tun_open(int tun, int mode) close(fd); return -1; } -#endif debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd); - /* Bring interface up if it is not already */ + /* Set the tunnel device operation mode */ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) goto failed; - if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { - debug("%s: get interface %s flags: %s", __func__, - ifr.ifr_name, strerror(errno)); + if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) goto failed; - } - if (!(ifr.ifr_flags & IFF_UP)) { - ifr.ifr_flags |= IFF_UP; - if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { - debug("%s: activate interface %s: %s", __func__, - ifr.ifr_name, strerror(errno)); - goto failed; - } - } +#if 0 + /* Set interface mode */ + ifr.ifr_flags &= ~IFF_UP; + if (mode == SSH_TUNMODE_ETHERNET) + ifr.ifr_flags |= IFF_LINK0; + else + ifr.ifr_flags &= ~IFF_LINK0; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) + goto failed; +#endif + + /* Bring interface up */ + ifr.ifr_flags |= IFF_UP; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) + goto failed; close(sock); - return fd; + return (fd); failed: if (fd >= 0) @@ -781,7 +712,7 @@ tun_open(int tun, int mode) close(sock); debug("%s: failed to set %s mode %d: %s", __func__, ifr.ifr_name, mode, strerror(errno)); - return -1; + return (-1); } void @@ -794,16 +725,16 @@ sanitise_stdfd(void) strerror(errno)); exit(1); } - while (++dupfd <= STDERR_FILENO) { - /* Only populate closed fds. */ - if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) { - if (dup2(nullfd, dupfd) == -1) { - fprintf(stderr, "dup2: %s\n", strerror(errno)); - exit(1); - } + while (++dupfd <= 2) { + /* Only clobber closed fds */ + if (fcntl(dupfd, F_GETFL, 0) >= 0) + continue; + if (dup2(nullfd, dupfd) == -1) { + fprintf(stderr, "dup2: %s\n", strerror(errno)); + exit(1); } } - if (nullfd > STDERR_FILENO) + if (nullfd > 2) close(nullfd); } @@ -858,20 +789,6 @@ get_u32(const void *vp) return (v); } -u_int32_t -get_u32_le(const void *vp) -{ - const u_char *p = (const u_char *)vp; - u_int32_t v; - - v = (u_int32_t)p[0]; - v |= (u_int32_t)p[1] << 8; - v |= (u_int32_t)p[2] << 16; - v |= (u_int32_t)p[3] << 24; - - return (v); -} - u_int16_t get_u16(const void *vp) { @@ -910,16 +827,6 @@ put_u32(void *vp, u_int32_t v) p[3] = (u_char)v & 0xff; } -void -put_u32_le(void *vp, u_int32_t v) -{ - u_char *p = (u_char *)vp; - - p[0] = (u_char)v & 0xff; - p[1] = (u_char)(v >> 8) & 0xff; - p[2] = (u_char)(v >> 16) & 0xff; - p[3] = (u_char)(v >> 24) & 0xff; -} void put_u16(void *vp, u_int16_t v) @@ -949,28 +856,6 @@ ms_to_timeval(struct timeval *tv, int ms tv->tv_usec = (ms % 1000) * 1000; } -time_t -monotime(void) -{ - struct timespec ts; - - if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) - fatal("clock_gettime: %s", strerror(errno)); - - return (ts.tv_sec); -} - -double -monotime_double(void) -{ - struct timespec ts; - - if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) - fatal("clock_gettime: %s", strerror(errno)); - - return (ts.tv_sec + (double)ts.tv_nsec / 1000000000); -} - void bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) { @@ -1117,119 +1002,13 @@ iptos2str(int iptos) return iptos_str; } -void -lowercase(char *s) -{ - for (; *s; s++) - *s = tolower((u_char)*s); -} - -int -unix_listener(const char *path, int backlog, int unlink_first) -{ - struct sockaddr_un sunaddr; - int saved_errno, sock; - - memset(&sunaddr, 0, sizeof(sunaddr)); - sunaddr.sun_family = AF_UNIX; - if (strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) { - error("%s: \"%s\" too long for Unix domain socket", __func__, - path); - errno = ENAMETOOLONG; - return -1; - } - - sock = socket(PF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - saved_errno = errno; - error("socket: %.100s", strerror(errno)); - errno = saved_errno; - return -1; - } - if (unlink_first == 1) { - if (unlink(path) != 0 && errno != ENOENT) - error("unlink(%s): %.100s", path, strerror(errno)); - } - if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { - saved_errno = errno; - error("bind: %.100s", strerror(errno)); - close(sock); - error("%s: cannot bind to path: %s", __func__, path); - errno = saved_errno; - return -1; - } - if (listen(sock, backlog) < 0) { - saved_errno = errno; - error("listen: %.100s", strerror(errno)); - close(sock); - unlink(path); - error("%s: cannot listen on path: %s", __func__, path); - errno = saved_errno; - return -1; - } - return sock; -} - -/* - * Compares two strings that maybe be NULL. Returns non-zero if strings - * are both NULL or are identical, returns zero otherwise. - */ -static int -strcmp_maybe_null(const char *a, const char *b) -{ - if ((a == NULL && b != NULL) || (a != NULL && b == NULL)) - return 0; - if (a != NULL && strcmp(a, b) != 0) - return 0; - return 1; -} - -/* - * Compare two forwards, returning non-zero if they are identical or - * zero otherwise. - */ -int -forward_equals(const struct Forward *a, const struct Forward *b) -{ - if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0) - return 0; - if (a->listen_port != b->listen_port) - return 0; - if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0) - return 0; - if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0) - return 0; - if (a->connect_port != b->connect_port) - return 0; - if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0) - return 0; - /* allocated_port and handle are not checked */ - return 1; -} - -/* returns 1 if bind to specified port by specified user is permitted */ int -bind_permitted(int port, uid_t uid) +timingsafe_bcmp(const void *b1, const void *b2, size_t n) { - if (port < IPPORT_RESERVED && uid != 0) - return 0; - return 1; -} - -/* returns 1 if process is already daemonized, 0 otherwise */ -int -daemonized(void) -{ - int fd; + const unsigned char *p1 = b1, *p2 = b2; + int ret = 0; - if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) { - close(fd); - return 0; /* have controlling terminal */ - } - if (getppid() != 1) - return 0; /* parent is not init */ - if (getsid(0) != getpid()) - return 0; /* not session leader */ - debug3("already daemonized"); - return 1; + for (; n > 0; n--) + ret |= *p1++ ^ *p2++; + return (ret != 0); }