diff options
Diffstat (limited to 'openbsd-compat')
87 files changed, 4058 insertions, 3194 deletions
diff --git a/openbsd-compat/.cvsignore b/openbsd-compat/.cvsignore deleted file mode 100644 index f3c7a7c5..00000000 --- a/openbsd-compat/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -Makefile diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index 3c5e3b7f..3eb188f0 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -1,5 +1,3 @@ -# $Id: Makefile.in,v 1.56 2014/09/30 23:43:08 djm Exp $ - sysconfdir=@sysconfdir@ piddir=@piddir@ srcdir=@srcdir@ @@ -9,21 +7,99 @@ VPATH=@srcdir@ CC=@CC@ LD=@LD@ CFLAGS=@CFLAGS@ +CFLAGS_NOPIE=@CFLAGS_NOPIE@ CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ +PICFLAG=@PICFLAG@ LIBS=@LIBS@ AR=@AR@ RANLIB=@RANLIB@ INSTALL=@INSTALL@ LDFLAGS=-L. @LDFLAGS@ +LDFLAGS_NOPIE=-L. -Lopenbsd-compat/ @LDFLAGS_NOPIE@ -OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o +OPENBSD=base64.o \ + basename.o \ + bcrypt_pbkdf.o \ + bcrypt_pbkdf.o \ + bindresvport.o \ + blowfish.o \ + daemon.o \ + dirname.o \ + explicit_bzero.o \ + fmt_scaled.o \ + freezero.o \ + fnmatch.o \ + getcwd.o \ + getgrouplist.o \ + getopt_long.o \ + getrrsetbyname.o \ + glob.o \ + inet_aton.o \ + inet_ntoa.o \ + inet_ntop.o \ + md5.o \ + memmem.o \ + mktemp.o \ + pwcache.o \ + readpassphrase.o \ + reallocarray.o \ + recallocarray.o \ + rresvport.o \ + setenv.o \ + setproctitle.o \ + sha1.o \ + sha2.o \ + sigact.o \ + strcasestr.o \ + strlcat.o \ + strlcpy.o \ + strmode.o \ + strndup.o \ + strnlen.o \ + strptime.o \ + strsep.o \ + strtoll.o \ + strtonum.o \ + strtoull.o \ + strtoul.o \ + timingsafe_bcmp.o \ + vis.o -COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o +COMPAT= arc4random.o \ + bsd-asprintf.o \ + bsd-closefrom.o \ + bsd-cygwin_util.o \ + bsd-err.o \ + bsd-flock.o \ + bsd-getline.o \ + bsd-getpagesize.o \ + bsd-getpeereid.o \ + bsd-malloc.o \ + bsd-misc.o \ + bsd-nextstep.o \ + bsd-openpty.o \ + bsd-poll.o \ + bsd-setres_id.o \ + bsd-signal.o \ + bsd-snprintf.o \ + bsd-statvfs.o \ + bsd-waitpid.o \ + fake-rfc2553.o \ + getrrsetbyname-ldns.o \ + kludge-fd_set.o \ + openssl-compat.o \ + libressl-api-compat.o \ + xcrypt.o -PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o +PORTS= port-aix.o \ + port-irix.o \ + port-linux.o \ + port-solaris.o \ + port-net.o \ + port-uw.o .c.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< + $(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $< all: libopenbsd-compat.a @@ -36,7 +112,7 @@ libopenbsd-compat.a: $(COMPAT) $(OPENBSD) $(PORTS) $(RANLIB) $@ clean: - rm -f *.o *.a core + rm -f *.o *.a core distclean: clean rm -f Makefile *~ diff --git a/openbsd-compat/arc4random.c b/openbsd-compat/arc4random.c index 046f57e6..578f69f4 100644 --- a/openbsd-compat/arc4random.c +++ b/openbsd-compat/arc4random.c @@ -33,6 +33,10 @@ #include <string.h> #include <unistd.h> +#ifdef HAVE_SYS_RANDOM_H +# include <sys/random.h> +#endif + #ifndef HAVE_ARC4RANDOM #ifdef WITH_OPENSSL @@ -78,8 +82,9 @@ _rs_init(u_char *buf, size_t n) } #ifndef WITH_OPENSSL -#define SSH_RANDOM_DEV "/dev/urandom" -/* XXX use getrandom() if supported on Linux */ +# ifndef SSH_RANDOM_DEV +# define SSH_RANDOM_DEV "/dev/urandom" +# endif /* SSH_RANDOM_DEV */ static void getrnd(u_char *s, size_t len) { @@ -87,6 +92,11 @@ getrnd(u_char *s, size_t len) ssize_t r; size_t o = 0; +#ifdef HAVE_GETRANDOM + if ((r = getrandom(s, len, 0)) > 0 && (size_t)r == len) + return; +#endif /* HAVE_GETRANDOM */ + if ((fd = open(SSH_RANDOM_DEV, O_RDONLY)) == -1) fatal("Couldn't open %s: %s", SSH_RANDOM_DEV, strerror(errno)); while (o < len) { @@ -101,7 +111,7 @@ getrnd(u_char *s, size_t len) } close(fd); } -#endif +#endif /* WITH_OPENSSL */ static void _rs_stir(void) @@ -110,8 +120,8 @@ _rs_stir(void) #ifdef WITH_OPENSSL if (RAND_bytes(rnd, sizeof(rnd)) <= 0) - fatal("Couldn't obtain random bytes (error %ld)", - ERR_get_error()); + fatal("Couldn't obtain random bytes (error 0x%lx)", + (unsigned long)ERR_get_error()); #else getrnd(rnd, sizeof(rnd)); #endif diff --git a/openbsd-compat/base64.h b/openbsd-compat/base64.h index 732c6b3f..bd772931 100644 --- a/openbsd-compat/base64.h +++ b/openbsd-compat/base64.h @@ -1,5 +1,3 @@ -/* $Id: base64.h,v 1.6 2003/08/29 16:59:52 mouring Exp $ */ - /* * Copyright (c) 1996 by Internet Software Consortium. * @@ -49,7 +47,7 @@ #ifndef HAVE___B64_NTOP # ifndef HAVE_B64_NTOP -int b64_ntop(u_char const *src, size_t srclength, char *target, +int b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize); # endif /* !HAVE_B64_NTOP */ # define __b64_ntop(a,b,c,d) b64_ntop(a,b,c,d) diff --git a/openbsd-compat/bcrypt_pbkdf.c b/openbsd-compat/bcrypt_pbkdf.c index 16912575..78523456 100644 --- a/openbsd-compat/bcrypt_pbkdf.c +++ b/openbsd-compat/bcrypt_pbkdf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bcrypt_pbkdf.c,v 1.9 2014/07/13 21:21:25 tedu Exp $ */ +/* $OpenBSD: bcrypt_pbkdf.c,v 1.13 2015/01/12 03:20:04 tedu Exp $ */ /* * Copyright (c) 2013 Ted Unangst <tedu@openbsd.org> * @@ -37,6 +37,8 @@ #endif #define SHA512_DIGEST_LENGTH crypto_hash_sha512_BYTES +#define MINIMUM(a,b) (((a) < (b)) ? (a) : (b)) + /* * pkcs #5 pbkdf2 implementation using the "bcrypt" hash * @@ -44,7 +46,7 @@ * function with the following modifications: * 1. The input password and salt are preprocessed with SHA512. * 2. The output length is expanded to 256 bits. - * 3. Subsequently the magic string to be encrypted is lengthened and modifed + * 3. Subsequently the magic string to be encrypted is lengthened and modified * to "OxychromaticBlowfishSwatDynamite" * 4. The hash function is defined to perform 64 rounds of initial state * expansion. (More rounds are performed by iterating the hash.) @@ -61,8 +63,8 @@ * wise caller could do; we just do it for you. */ -#define BCRYPT_BLOCKS 8 -#define BCRYPT_HASHSIZE (BCRYPT_BLOCKS * 4) +#define BCRYPT_WORDS 8 +#define BCRYPT_HASHSIZE (BCRYPT_WORDS * 4) static void bcrypt_hash(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out) @@ -70,7 +72,7 @@ bcrypt_hash(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out) blf_ctx state; u_int8_t ciphertext[BCRYPT_HASHSIZE] = "OxychromaticBlowfishSwatDynamite"; - uint32_t cdata[BCRYPT_BLOCKS]; + uint32_t cdata[BCRYPT_WORDS]; int i; uint16_t j; size_t shalen = SHA512_DIGEST_LENGTH; @@ -85,14 +87,14 @@ bcrypt_hash(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out) /* encryption */ j = 0; - for (i = 0; i < BCRYPT_BLOCKS; i++) + for (i = 0; i < BCRYPT_WORDS; i++) cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext), &j); for (i = 0; i < 64; i++) blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t)); /* copy out */ - for (i = 0; i < BCRYPT_BLOCKS; i++) { + for (i = 0; i < BCRYPT_WORDS; i++) { out[4 * i + 3] = (cdata[i] >> 24) & 0xff; out[4 * i + 2] = (cdata[i] >> 16) & 0xff; out[4 * i + 1] = (cdata[i] >> 8) & 0xff; @@ -156,9 +158,9 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const u_int8_t *salt, size_t salt } /* - * pbkdf2 deviation: ouput the key material non-linearly. + * pbkdf2 deviation: output the key material non-linearly. */ - amt = MIN(amt, keylen); + amt = MINIMUM(amt, keylen); for (i = 0; i < amt; i++) { size_t dest = i * stride + (count - 1); if (dest >= origkeylen) diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c index c89f2140..eeb269d5 100644 --- a/openbsd-compat/bindresvport.c +++ b/openbsd-compat/bindresvport.c @@ -64,6 +64,7 @@ bindresvport_sa(int sd, struct sockaddr *sa) if (sa == NULL) { memset(&myaddr, 0, sizeof(myaddr)); sa = (struct sockaddr *)&myaddr; + salen = sizeof(myaddr); if (getsockname(sd, sa, &salen) == -1) return -1; /* errno is correctly set */ diff --git a/openbsd-compat/blowfish.c b/openbsd-compat/blowfish.c index 6c419549..e10f7e7d 100644 --- a/openbsd-compat/blowfish.c +++ b/openbsd-compat/blowfish.c @@ -50,7 +50,9 @@ #endif #include <sys/types.h> +#ifdef HAVE_BLF_H #include <blf.h> +#endif #undef inline #ifdef __GNUC__ diff --git a/openbsd-compat/bsd-asprintf.c b/openbsd-compat/bsd-asprintf.c index 3368195d..10927727 100644 --- a/openbsd-compat/bsd-asprintf.c +++ b/openbsd-compat/bsd-asprintf.c @@ -19,24 +19,21 @@ #include "includes.h" +/* + * Don't let systems with broken printf(3) avoid our replacements + * via asprintf(3)/vasprintf(3) calling libc internally. + */ +#if defined(BROKEN_SNPRINTF) +# undef HAVE_VASPRINTF +# undef HAVE_ASPRINTF +#endif + #ifndef HAVE_VASPRINTF #include <errno.h> #include <stdarg.h> #include <stdlib.h> -#ifndef VA_COPY -# ifdef HAVE_VA_COPY -# define VA_COPY(dest, src) va_copy(dest, src) -# else -# ifdef HAVE___VA_COPY -# define VA_COPY(dest, src) __va_copy(dest, src) -# else -# define VA_COPY(dest, src) (dest) = (src) -# endif -# endif -#endif - #define INIT_SZ 128 int @@ -90,7 +87,7 @@ int asprintf(char **str, const char *fmt, ...) { va_list ap; int ret; - + *str = NULL; va_start(ap, fmt); ret = vasprintf(str, fmt, ap); diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c index 9380b33a..8fadca2d 100644 --- a/openbsd-compat/bsd-closefrom.c +++ b/openbsd-compat/bsd-closefrom.c @@ -46,6 +46,9 @@ # include <ndir.h> # endif #endif +#if defined(HAVE_LIBPROC_H) +# include <libproc.h> +#endif #ifndef OPEN_MAX # define OPEN_MAX 256 @@ -55,21 +58,73 @@ __unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $"; #endif /* lint */ +#ifndef HAVE_FCNTL_CLOSEM /* * Close all file descriptors greater than or equal to lowfd. */ +static void +closefrom_fallback(int lowfd) +{ + long fd, maxfd; + + /* + * Fall back on sysconf() or getdtablesize(). We avoid checking + * resource limits since it is possible to open a file descriptor + * and then drop the rlimit such that it is below the open fd. + */ +#ifdef HAVE_SYSCONF + maxfd = sysconf(_SC_OPEN_MAX); +#else + maxfd = getdtablesize(); +#endif /* HAVE_SYSCONF */ + if (maxfd < 0) + maxfd = OPEN_MAX; + + for (fd = lowfd; fd < maxfd; fd++) + (void) close((int) fd); +} +#endif /* HAVE_FCNTL_CLOSEM */ + #ifdef HAVE_FCNTL_CLOSEM void closefrom(int lowfd) { (void) fcntl(lowfd, F_CLOSEM, 0); } -#else +#elif defined(HAVE_LIBPROC_H) && defined(HAVE_PROC_PIDINFO) void closefrom(int lowfd) { - long fd, maxfd; -#if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) + int i, r, sz; + pid_t pid = getpid(); + struct proc_fdinfo *fdinfo_buf = NULL; + + sz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); + if (sz == 0) + return; /* no fds, really? */ + else if (sz == -1) + goto fallback; + if ((fdinfo_buf = malloc(sz)) == NULL) + goto fallback; + r = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fdinfo_buf, sz); + if (r < 0 || r > sz) + goto fallback; + for (i = 0; i < r / (int)PROC_PIDLISTFD_SIZE; i++) { + if (fdinfo_buf[i].proc_fd >= lowfd) + close(fdinfo_buf[i].proc_fd); + } + free(fdinfo_buf); + return; + fallback: + free(fdinfo_buf); + closefrom_fallback(lowfd); + return; +} +#elif defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) +void +closefrom(int lowfd) +{ + long fd; char fdpath[PATH_MAX], *endp; struct dirent *dent; DIR *dirp; @@ -77,7 +132,7 @@ closefrom(int lowfd) /* Check for a /proc/$$/fd directory. */ len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); - if (len > 0 && (size_t)len <= sizeof(fdpath) && (dirp = opendir(fdpath))) { + if (len > 0 && (size_t)len < sizeof(fdpath) && (dirp = opendir(fdpath))) { while ((dent = readdir(dirp)) != NULL) { fd = strtol(dent->d_name, &endp, 10); if (dent->d_name != endp && *endp == '\0' && @@ -85,25 +140,16 @@ closefrom(int lowfd) (void) close((int) fd); } (void) closedir(dirp); - } else -#endif - { - /* - * Fall back on sysconf() or getdtablesize(). We avoid checking - * resource limits since it is possible to open a file descriptor - * and then drop the rlimit such that it is below the open fd. - */ -#ifdef HAVE_SYSCONF - maxfd = sysconf(_SC_OPEN_MAX); -#else - maxfd = getdtablesize(); -#endif /* HAVE_SYSCONF */ - if (maxfd < 0) - maxfd = OPEN_MAX; - - for (fd = lowfd; fd < maxfd; fd++) - (void) close((int) fd); + return; } + /* /proc/$$/fd strategy failed, fall back to brute force closure */ + closefrom_fallback(lowfd); +} +#else +void +closefrom(int lowfd) +{ + closefrom_fallback(lowfd); } #endif /* !HAVE_FCNTL_CLOSEM */ #endif /* HAVE_CLOSEFROM */ diff --git a/openbsd-compat/bsd-cray.c b/openbsd-compat/bsd-cray.c deleted file mode 100644 index f1bbd7de..00000000 --- a/openbsd-compat/bsd-cray.c +++ /dev/null @@ -1,817 +0,0 @@ -/* - * $Id: bsd-cray.c,v 1.17 2007/08/15 09:17:43 dtucker Exp $ - * - * bsd-cray.c - * - * Copyright (c) 2002, Cray Inc. (Wendy Palm <wendyp@cray.com>) - * Significant portions provided by - * Wayne Schroeder, SDSC <schroeder@sdsc.edu> - * William Jones, UTexas <jones@tacc.utexas.edu> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Created: Apr 22 16.34:00 2002 wp - * - * This file contains functions required for proper execution - * on UNICOS systems. - * - */ -#ifdef _UNICOS - -#include <udb.h> -#include <tmpdir.h> -#include <unistd.h> -#include <sys/category.h> -#include <utmp.h> -#include <sys/jtab.h> -#include <signal.h> -#include <sys/priv.h> -#include <sys/secparm.h> -#include <sys/tfm.h> -#include <sys/usrv.h> -#include <sys/sysv.h> -#include <sys/sectab.h> -#include <sys/secstat.h> -#include <sys/stat.h> -#include <sys/session.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <pwd.h> -#include <fcntl.h> -#include <errno.h> -#include <ia.h> -#include <urm.h> -#include "ssh.h" - -#include "includes.h" -#include "sys/types.h" - -#ifndef HAVE_STRUCT_SOCKADDR_STORAGE -# define _SS_MAXSIZE 128 /* Implementation specific max size */ -# define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) - -# define ss_family ss_sa.sa_family -#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ - -#ifndef IN6_IS_ADDR_LOOPBACK -# define IN6_IS_ADDR_LOOPBACK(a) \ - (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ - ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) -#endif /* !IN6_IS_ADDR_LOOPBACK */ - -#ifndef AF_INET6 -/* Define it to something that should never appear */ -#define AF_INET6 AF_MAX -#endif - -#include "log.h" -#include "servconf.h" -#include "bsd-cray.h" - -#define MAXACID 80 - -extern ServerOptions options; - -char cray_tmpdir[TPATHSIZ + 1]; /* job TMPDIR path */ - -struct sysv sysv; /* system security structure */ -struct usrv usrv; /* user security structure */ - -/* - * Functions. - */ -void cray_retain_utmp(struct utmp *, int); -void cray_delete_tmpdir(char *, int, uid_t); -void cray_init_job(struct passwd *); -void cray_set_tmpdir(struct utmp *); -void cray_login_failure(char *, int); -int cray_setup(uid_t, char *, const char *); -int cray_access_denied(char *); - -void -cray_login_failure(char *username, int errcode) -{ - struct udb *ueptr; /* UDB pointer for username */ - ia_failure_t fsent; /* ia_failure structure */ - ia_failure_ret_t fret; /* ia_failure return stuff */ - struct jtab jtab; /* job table structure */ - int jid = 0; /* job id */ - - if ((jid = getjtab(&jtab)) < 0) - debug("cray_login_failure(): getjtab error"); - - getsysudb(); - if ((ueptr = getudbnam(username)) == UDB_NULL) - debug("cray_login_failure(): getudbname() returned NULL"); - endudb(); - - memset(&fsent, '\0', sizeof(fsent)); - fsent.revision = 0; - fsent.uname = username; - fsent.host = (char *)get_canonical_hostname(options.use_dns); - fsent.ttyn = "sshd"; - fsent.caller = IA_SSHD; - fsent.flags = IA_INTERACTIVE; - fsent.ueptr = ueptr; - fsent.jid = jid; - fsent.errcode = errcode; - fsent.pwdp = NULL; - fsent.exitcode = 0; /* dont exit in ia_failure() */ - - fret.revision = 0; - fret.normal = 0; - - /* - * Call ia_failure because of an login failure. - */ - ia_failure(&fsent, &fret); -} - -/* - * Cray access denied - */ -int -cray_access_denied(char *username) -{ - struct udb *ueptr; /* UDB pointer for username */ - int errcode; /* IA errorcode */ - - errcode = 0; - getsysudb(); - if ((ueptr = getudbnam(username)) == UDB_NULL) - debug("cray_login_failure(): getudbname() returned NULL"); - endudb(); - - if (ueptr != NULL && ueptr->ue_disabled) - errcode = IA_DISABLED; - if (errcode) - cray_login_failure(username, errcode); - - return (errcode); -} - -/* - * record_failed_login: generic "login failed" interface function - */ -void -record_failed_login(const char *user, const char *hostname, const char *ttyname) -{ - cray_login_failure((char *)user, IA_UDBERR); -} - -int -cray_setup (uid_t uid, char *username, const char *command) -{ - extern struct udb *getudb(); - extern char *setlimits(); - - int err; /* error return */ - time_t system_time; /* current system clock */ - time_t expiration_time; /* password expiration time */ - int maxattempts; /* maximum no. of failed login attempts */ - int SecureSys; /* unicos security flag */ - int minslevel = 0; /* system minimum security level */ - int i, j; - int valid_acct = -1; /* flag for reading valid acct */ - char acct_name[MAXACID] = { "" }; /* used to read acct name */ - struct jtab jtab; /* Job table struct */ - struct udb ue; /* udb entry for logging-in user */ - struct udb *up; /* pointer to UDB entry */ - struct secstat secinfo; /* file security attributes */ - struct servprov init_info; /* used for sesscntl() call */ - int jid; /* job ID */ - int pid; /* process ID */ - char *sr; /* status return from setlimits() */ - char *ttyn = NULL; /* ttyname or command name*/ - char hostname[MAXHOSTNAMELEN]; - /* passwd stuff for ia_user */ - passwd_t pwdacm, pwddialup, pwdudb, pwdwal, pwddce; - ia_user_ret_t uret; /* stuff returned from ia_user */ - ia_user_t usent; /* ia_user main structure */ - int ia_rcode; /* ia_user return code */ - ia_failure_t fsent; /* ia_failure structure */ - ia_failure_ret_t fret; /* ia_failure return stuff */ - ia_success_t ssent; /* ia_success structure */ - ia_success_ret_t sret; /* ia_success return stuff */ - int ia_mlsrcode; /* ia_mlsuser return code */ - int secstatrc; /* [f]secstat return code */ - - if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) { - getsysv(&sysv, sizeof(struct sysv)); - minslevel = sysv.sy_minlvl; - if (getusrv(&usrv) < 0) - fatal("getusrv() failed, errno = %d", errno); - } - hostname[0] = '\0'; - strlcpy(hostname, - (char *)get_canonical_hostname(options.use_dns), - MAXHOSTNAMELEN); - /* - * Fetch user's UDB entry. - */ - getsysudb(); - if ((up = getudbnam(username)) == UDB_NULL) - fatal("cannot fetch user's UDB entry"); - - /* - * Prevent any possible fudging so perform a data - * safety check and compare the supplied uid against - * the udb's uid. - */ - if (up->ue_uid != uid) - fatal("IA uid missmatch"); - endudb(); - - if ((jid = getjtab(&jtab)) < 0) { - debug("getjtab"); - return(-1); - } - pid = getpid(); - ttyn = ttyname(0); - if (SecureSys) { - if (ttyn != NULL) - secstatrc = secstat(ttyn, &secinfo); - else - secstatrc = fsecstat(1, &secinfo); - - if (secstatrc == 0) - debug("[f]secstat() successful"); - else - fatal("[f]secstat() error, rc = %d", secstatrc); - } - if ((ttyn == NULL) && ((char *)command != NULL)) - ttyn = (char *)command; - /* - * Initialize all structures to call ia_user - */ - usent.revision = 0; - usent.uname = username; - usent.host = hostname; - usent.ttyn = ttyn; - usent.caller = IA_SSHD; - usent.pswdlist = &pwdacm; - usent.ueptr = &ue; - usent.flags = IA_INTERACTIVE | IA_FFLAG; - pwdacm.atype = IA_SECURID; - pwdacm.pwdp = NULL; - pwdacm.next = &pwdudb; - - pwdudb.atype = IA_UDB; - pwdudb.pwdp = NULL; - pwdudb.next = &pwddce; - - pwddce.atype = IA_DCE; - pwddce.pwdp = NULL; - pwddce.next = &pwddialup; - - pwddialup.atype = IA_DIALUP; - pwddialup.pwdp = NULL; - /* pwddialup.next = &pwdwal; */ - pwddialup.next = NULL; - - pwdwal.atype = IA_WAL; - pwdwal.pwdp = NULL; - pwdwal.next = NULL; - - uret.revision = 0; - uret.pswd = NULL; - uret.normal = 0; - - ia_rcode = ia_user(&usent, &uret); - switch (ia_rcode) { - /* - * These are acceptable return codes from ia_user() - */ - case IA_UDBWEEK: /* Password Expires in 1 week */ - expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage; - printf ("WARNING - your current password will expire %s\n", - ctime((const time_t *)&expiration_time)); - break; - case IA_UDBEXPIRED: - if (ttyname(0) != NULL) { - /* Force a password change */ - printf("Your password has expired; Choose a new one.\n"); - execl("/bin/passwd", "passwd", username, 0); - exit(9); - } - break; - case IA_NORMAL: /* Normal Return Code */ - break; - case IA_BACKDOOR: - /* XXX: can we memset it to zero here so save some of this */ - strlcpy(ue.ue_name, "root", sizeof(ue.ue_name)); - strlcpy(ue.ue_dir, "/", sizeof(ue.ue_dir)); - strlcpy(ue.ue_shell, "/bin/sh", sizeof(ue.ue_shell)); - - ue.ue_passwd[0] = '\0'; - ue.ue_age[0] = '\0'; - ue.ue_comment[0] = '\0'; - ue.ue_loghost[0] = '\0'; - ue.ue_logline[0] = '\0'; - - ue.ue_uid = -1; - ue.ue_nice[UDBRC_INTER] = 0; - - for (i = 0; i < MAXVIDS; i++) - ue.ue_gids[i] = 0; - - ue.ue_logfails = 0; - ue.ue_minlvl = ue.ue_maxlvl = ue.ue_deflvl = minslevel; - ue.ue_defcomps = 0; - ue.ue_comparts = 0; - ue.ue_permits = 0; - ue.ue_trap = 0; - ue.ue_disabled = 0; - ue.ue_logtime = 0; - break; - case IA_CONSOLE: /* Superuser not from Console */ - case IA_TRUSTED: /* Trusted user */ - if (options.permit_root_login > PERMIT_NO) - break; /* Accept root login */ - default: - /* - * These are failed return codes from ia_user() - */ - switch (ia_rcode) - { - case IA_BADAUTH: - printf("Bad authorization, access denied.\n"); - break; - case IA_DISABLED: - printf("Your login has been disabled. Contact the system "); - printf("administrator for assistance.\n"); - break; - case IA_GETSYSV: - printf("getsysv() failed - errno = %d\n", errno); - break; - case IA_MAXLOGS: - printf("Maximum number of failed login attempts exceeded.\n"); - printf("Access denied.\n"); - break; - case IA_UDBPWDNULL: - if (SecureSys) - printf("NULL Password not allowed on MLS systems.\n"); - break; - default: - break; - } - - /* - * Authentication failed. - */ - printf("sshd: Login incorrect, (0%o)\n", - ia_rcode-IA_ERRORCODE); - - /* - * Initialize structure for ia_failure - * which will exit. - */ - fsent.revision = 0; - fsent.uname = username; - fsent.host = hostname; - fsent.ttyn = ttyn; - fsent.caller = IA_SSHD; - fsent.flags = IA_INTERACTIVE; - fsent.ueptr = &ue; - fsent.jid = jid; - fsent.errcode = ia_rcode; - fsent.pwdp = uret.pswd; - fsent.exitcode = 1; - - fret.revision = 0; - fret.normal = 0; - - /* - * Call ia_failure because of an IA failure. - * There is no return because ia_failure exits. - */ - ia_failure(&fsent, &fret); - - exit(1); - } - - ia_mlsrcode = IA_NORMAL; - if (SecureSys) { - debug("calling ia_mlsuser()"); - ia_mlsrcode = ia_mlsuser(&ue, &secinfo, &usrv, NULL, 0); - } - if (ia_mlsrcode != IA_NORMAL) { - printf("sshd: Login incorrect, (0%o)\n", - ia_mlsrcode-IA_ERRORCODE); - /* - * Initialize structure for ia_failure - * which will exit. - */ - fsent.revision = 0; - fsent.uname = username; - fsent.host = hostname; - fsent.ttyn = ttyn; - fsent.caller = IA_SSHD; - fsent.flags = IA_INTERACTIVE; - fsent.ueptr = &ue; - fsent.jid = jid; - fsent.errcode = ia_mlsrcode; - fsent.pwdp = uret.pswd; - fsent.exitcode = 1; - fret.revision = 0; - fret.normal = 0; - - /* - * Call ia_failure because of an IA failure. - * There is no return because ia_failure exits. - */ - ia_failure(&fsent,&fret); - exit(1); - } - - /* Provide login status information */ - if (options.print_lastlog && ue.ue_logtime != 0) { - printf("Last successful login was : %.*s ", 19, - (char *)ctime(&ue.ue_logtime)); - - if (*ue.ue_loghost != '\0') { - printf("from %.*s\n", sizeof(ue.ue_loghost), - ue.ue_loghost); - } else { - printf("on %.*s\n", sizeof(ue.ue_logline), - ue.ue_logline); - } - - if (SecureSys && (ue.ue_logfails != 0)) { - printf(" followed by %d failed attempts\n", - ue.ue_logfails); - } - } - - /* - * Call ia_success to process successful I/A. - */ - ssent.revision = 0; - ssent.uname = username; - ssent.host = hostname; - ssent.ttyn = ttyn; - ssent.caller = IA_SSHD; - ssent.flags = IA_INTERACTIVE; - ssent.ueptr = &ue; - ssent.jid = jid; - ssent.errcode = ia_rcode; - ssent.us = NULL; - ssent.time = 1; /* Set ue_logtime */ - - sret.revision = 0; - sret.normal = 0; - - ia_success(&ssent, &sret); - - /* - * Query for account, iff > 1 valid acid & askacid permbit - */ - if (((ue.ue_permbits & PERMBITS_ACCTID) || - (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) && - ue.ue_permbits & PERMBITS_ASKACID) { - if (ttyname(0) != NULL) { - debug("cray_setup: ttyname true case, %.100s", ttyname); - while (valid_acct == -1) { - printf("Account (? for available accounts)" - " [%s]: ", acid2nam(ue.ue_acids[0])); - fgets(acct_name, MAXACID, stdin); - switch (acct_name[0]) { - case EOF: - exit(0); - break; - case '\0': - valid_acct = ue.ue_acids[0]; - strlcpy(acct_name, acid2nam(valid_acct), MAXACID); - break; - case '?': - /* Print the list 3 wide */ - for (i = 0, j = 0; i < MAXVIDS; i++) { - if (ue.ue_acids[i] == -1) { - printf("\n"); - break; - } - if (++j == 4) { - j = 1; - printf("\n"); - } - printf(" %s", - acid2nam(ue.ue_acids[i])); - } - if (ue.ue_permbits & PERMBITS_ACCTID) { - printf("\"acctid\" permbit also allows" - " you to select any valid " - "account name.\n"); - } - printf("\n"); - break; - default: - valid_acct = nam2acid(acct_name); - if (valid_acct == -1) - printf( - "Account id not found for" - " account name \"%s\"\n\n", - acct_name); - break; - } - /* - * If an account was given, search the user's - * acids array to verify they can use this account. - */ - if ((valid_acct != -1) && - !(ue.ue_permbits & PERMBITS_ACCTID)) { - for (i = 0; i < MAXVIDS; i++) { - if (ue.ue_acids[i] == -1) - break; - if (valid_acct == ue.ue_acids[i]) - break; - } - if (i == MAXVIDS || - ue.ue_acids[i] == -1) { - fprintf(stderr, "Cannot set" - " account name to " - "\"%s\", permission " - "denied\n\n", acct_name); - valid_acct = -1; - } - } - } - } else { - /* - * The client isn't connected to a terminal and can't - * respond to an acid prompt. Use default acid. - */ - debug("cray_setup: ttyname false case, %.100s", - ttyname); - valid_acct = ue.ue_acids[0]; - } - } else { - /* - * The user doesn't have the askacid permbit set or - * only has one valid account to use. - */ - valid_acct = ue.ue_acids[0]; - } - if (acctid(0, valid_acct) < 0) { - printf ("Bad account id: %d\n", valid_acct); - exit(1); - } - - /* - * Now set shares, quotas, limits, including CPU time for the - * (interactive) job and process, and set up permissions - * (for chown etc), etc. - */ - if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) { - printf("Unable to give %d shares to <%s>(%d/%d)\n", - ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct); - exit(1); - } - - sr = setlimits(username, C_PROC, pid, UDBRC_INTER); - if (sr != NULL) { - debug("%.200s", sr); - exit(1); - } - sr = setlimits(username, C_JOB, jid, UDBRC_INTER); - if (sr != NULL) { - debug("%.200s", sr); - exit(1); - } - /* - * Place the service provider information into - * the session table (Unicos) or job table (Unicos/mk). - * There exist double defines for the job/session table in - * unicos/mk (jtab.h) so no need for a compile time switch. - */ - memset(&init_info, '\0', sizeof(init_info)); - init_info.s_sessinit.si_id = URM_SPT_LOGIN; - init_info.s_sessinit.si_pid = getpid(); - init_info.s_sessinit.si_sid = jid; - sesscntl(0, S_SETSERVPO, (int)&init_info); - - /* - * Set user and controlling tty security attributes. - */ - if (SecureSys) { - if (setusrv(&usrv) == -1) { - debug("setusrv() failed, errno = %d",errno); - exit(1); - } - } - - return (0); -} - -/* - * The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk - * can have pal privileges that sshd can inherit which - * could allow a user to su to root with out a password. - * This subroutine clears all privileges. - */ -void -drop_cray_privs() -{ -#if defined(_SC_CRAY_PRIV_SU) - priv_proc_t *privstate; - int result; - extern int priv_set_proc(); - extern priv_proc_t *priv_init_proc(); - - /* - * If ether of theses two flags are not set - * then don't allow this version of ssh to run. - */ - if (!sysconf(_SC_CRAY_PRIV_SU)) - fatal("Not PRIV_SU system."); - if (!sysconf(_SC_CRAY_POSIX_PRIV)) - fatal("Not POSIX_PRIV."); - - debug("Setting MLS labels.");; - - if (sysconf(_SC_CRAY_SECURE_MAC)) { - usrv.sv_minlvl = SYSLOW; - usrv.sv_actlvl = SYSHIGH; - usrv.sv_maxlvl = SYSHIGH; - } else { - usrv.sv_minlvl = sysv.sy_minlvl; - usrv.sv_actlvl = sysv.sy_minlvl; - usrv.sv_maxlvl = sysv.sy_maxlvl; - } - usrv.sv_actcmp = 0; - usrv.sv_valcmp = sysv.sy_valcmp; - - usrv.sv_intcat = TFM_SYSTEM; - usrv.sv_valcat |= (TFM_SYSTEM | TFM_SYSFILE); - - if (setusrv(&usrv) < 0) { - fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, - strerror(errno)); - } - - if ((privstate = priv_init_proc()) != NULL) { - result = priv_set_proc(privstate); - if (result != 0 ) { - fatal("%s(%d): priv_set_proc(): %s", - __FILE__, __LINE__, strerror(errno)); - } - priv_free_proc(privstate); - } - debug ("Privileges should be cleared..."); -#else - /* XXX: do this differently */ -# error Cray systems must be run with _SC_CRAY_PRIV_SU on! -#endif -} - - -/* - * Retain utmp/wtmp information - used by cray accounting. - */ -void -cray_retain_utmp(struct utmp *ut, int pid) -{ - int fd; - struct utmp utmp; - - if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) { - /* XXX use atomicio */ - while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) { - if (pid == utmp.ut_pid) { - ut->ut_jid = utmp.ut_jid; - strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath)); - strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host)); - strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name)); - break; - } - } - close(fd); - } else - fatal("Unable to open utmp file"); -} - -/* - * tmpdir support. - */ - -/* - * find and delete jobs tmpdir. - */ -void -cray_delete_tmpdir(char *login, int jid, uid_t uid) -{ - static char jtmp[TPATHSIZ]; - struct stat statbuf; - int child, c, wstat; - - for (c = 'a'; c <= 'z'; c++) { - snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); - if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid) - break; - } - - if (c > 'z') - return; - - if ((child = fork()) == 0) { - execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL); - fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed"); - } - - while (waitpid(child, &wstat, 0) == -1 && errno == EINTR) - ; -} - -/* - * Remove tmpdir on job termination. - */ -void -cray_job_termination_handler(int sig) -{ - int jid; - char *login = NULL; - struct jtab jtab; - - if ((jid = waitjob(&jtab)) == -1 || - (login = uid2nam(jtab.j_uid)) == NULL) - return; - - cray_delete_tmpdir(login, jid, jtab.j_uid); -} - -/* - * Set job id and create tmpdir directory. - */ -void -cray_init_job(struct passwd *pw) -{ - int jid; - int c; - - jid = setjob(pw->pw_uid, WJSIGNAL); - if (jid < 0) - fatal("System call setjob failure"); - - for (c = 'a'; c <= 'z'; c++) { - snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); - if (mkdir(cray_tmpdir, JTMPMODE) != 0) - continue; - if (chown(cray_tmpdir, pw->pw_uid, pw->pw_gid) != 0) { - rmdir(cray_tmpdir); - continue; - } - break; - } - - if (c > 'z') - cray_tmpdir[0] = '\0'; -} - -void -cray_set_tmpdir(struct utmp *ut) -{ - int jid; - struct jtab jbuf; - - if ((jid = getjtab(&jbuf)) < 0) - return; - - /* - * Set jid and tmpdir in utmp record. - */ - ut->ut_jid = jid; - strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); -} -#endif /* UNICOS */ - -#ifdef _UNICOSMP -#include <pwd.h> -/* - * Set job id and create tmpdir directory. - */ -void -cray_init_job(struct passwd *pw) -{ - initrm_silent(pw->pw_uid); - return; -} -#endif /* _UNICOSMP */ diff --git a/openbsd-compat/bsd-cray.h b/openbsd-compat/bsd-cray.h deleted file mode 100644 index 774eceb5..00000000 --- a/openbsd-compat/bsd-cray.h +++ /dev/null @@ -1,61 +0,0 @@ -/* $Id: bsd-cray.h,v 1.12 2005/02/02 06:10:11 dtucker Exp $ */ - -/* - * Copyright (c) 2002, Cray Inc. (Wendy Palm <wendyp@cray.com>) - * Significant portions provided by - * Wayne Schroeder, SDSC <schroeder@sdsc.edu> - * William Jones, UTexas <jones@tacc.utexas.edu> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Created: Apr 22 16.34:00 2002 wp - * - * This file contains functions required for proper execution - * on UNICOS systems. - * - */ - -#ifndef _BSD_CRAY_H -#define _BSD_CRAY_H - -#ifdef _UNICOS - -void cray_init_job(struct passwd *); -void cray_job_termination_handler(int); -void cray_login_failure(char *, int ); -int cray_access_denied(char *); -extern char cray_tmpdir[]; - -#define CUSTOM_FAILED_LOGIN 1 - -#ifndef IA_SSHD -# define IA_SSHD IA_LOGIN -#endif -#ifndef MAXHOSTNAMELEN -# define MAXHOSTNAMELEN 64 -#endif -#ifndef _CRAYT3E -# define TIOCGPGRP (tIOC|20) -#endif - -#endif /* UNICOS */ - -#endif /* _BSD_CRAY_H */ diff --git a/openbsd-compat/bsd-cygwin_util.c b/openbsd-compat/bsd-cygwin_util.c index a2d82126..54628e26 100644 --- a/openbsd-compat/bsd-cygwin_util.c +++ b/openbsd-compat/bsd-cygwin_util.c @@ -36,15 +36,19 @@ #include <fcntl.h> #include <string.h> #include <unistd.h> +#include <stdarg.h> +#include <stdlib.h> +#include <wchar.h> +#include <wctype.h> #include "xmalloc.h" -int +int binary_open(const char *filename, int flags, ...) { va_list ap; mode_t mode; - + va_start(ap, flags); mode = va_arg(ap, mode_t); va_end(ap); @@ -68,7 +72,7 @@ cygwin_ssh_privsep_user() if (cygwin_internal (CW_CYGNAME_FROM_WINNAME, "sshd", cyg_privsep_user, sizeof cyg_privsep_user) != 0) #endif - strcpy (cyg_privsep_user, "sshd"); + strlcpy(cyg_privsep_user, "sshd", sizeof(cyg_privsep_user)); } return cyg_privsep_user; } @@ -116,4 +120,150 @@ free_windows_environment(char **p) free(p); } +/* + * Returns true if the given string matches the pattern (which may contain ? + * and * as wildcards), and zero if it does not match. + * + * The Cygwin version of this function must be case-insensitive and take + * Unicode characters into account. + */ + +static int +__match_pattern (const wchar_t *s, const wchar_t *pattern) +{ + for (;;) { + /* If at end of pattern, accept if also at end of string. */ + if (!*pattern) + return !*s; + + if (*pattern == '*') { + /* Skip the asterisk. */ + pattern++; + + /* If at end of pattern, accept immediately. */ + if (!*pattern) + return 1; + + /* If next character in pattern is known, optimize. */ + if (*pattern != '?' && *pattern != '*') { + /* + * Look instances of the next character in + * pattern, and try to match starting from + * those. + */ + for (; *s; s++) + if (*s == *pattern && + __match_pattern(s + 1, pattern + 1)) + return 1; + /* Failed. */ + return 0; + } + /* + * Move ahead one character at a time and try to + * match at each position. + */ + for (; *s; s++) + if (__match_pattern(s, pattern)) + return 1; + /* Failed. */ + return 0; + } + /* + * There must be at least one more character in the string. + * If we are at the end, fail. + */ + if (!*s) + return 0; + + /* Check if the next character of the string is acceptable. */ + if (*pattern != '?' && towlower(*pattern) != towlower(*s)) + return 0; + + /* Move to the next character, both in string and in pattern. */ + s++; + pattern++; + } + /* NOTREACHED */ +} + +static int +_match_pattern(const char *s, const char *pattern) +{ + wchar_t *ws; + wchar_t *wpattern; + size_t len; + int ret; + + if ((len = mbstowcs(NULL, s, 0)) < 0) + return 0; + ws = (wchar_t *) xcalloc(len + 1, sizeof (wchar_t)); + mbstowcs(ws, s, len + 1); + if ((len = mbstowcs(NULL, pattern, 0)) < 0) + return 0; + wpattern = (wchar_t *) xcalloc(len + 1, sizeof (wchar_t)); + mbstowcs(wpattern, pattern, len + 1); + ret = __match_pattern (ws, wpattern); + free(ws); + free(wpattern); + return ret; +} + +/* + * Tries to match the string against the + * comma-separated sequence of subpatterns (each possibly preceded by ! to + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. + */ +int +cygwin_ug_match_pattern_list(const char *string, const char *pattern) +{ + char sub[1024]; + int negated; + int got_positive; + u_int i, subi, len = strlen(pattern); + + got_positive = 0; + for (i = 0; i < len;) { + /* Check if the subpattern is negated. */ + if (pattern[i] == '!') { + negated = 1; + i++; + } else + negated = 0; + + /* + * Extract the subpattern up to a comma or end. Convert the + * subpattern to lowercase. + */ + for (subi = 0; + i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; + subi++, i++) + sub[subi] = pattern[i]; + /* If subpattern too long, return failure (no match). */ + if (subi >= sizeof(sub) - 1) + return 0; + + /* If the subpattern was terminated by a comma, then skip it. */ + if (i < len && pattern[i] == ',') + i++; + + /* Null-terminate the subpattern. */ + sub[subi] = '\0'; + + /* Try to match the subpattern against the string. */ + if (_match_pattern(string, sub)) { + if (negated) + return -1; /* Negative */ + else + got_positive = 1; /* Positive */ + } + } + + /* + * Return success if got a positive match. If there was a negative + * match, we have already returned -1 and never get here. + */ + return got_positive; +} + #endif /* HAVE_CYGWIN */ diff --git a/openbsd-compat/bsd-cygwin_util.h b/openbsd-compat/bsd-cygwin_util.h index 79cb2a19..55c5a5b8 100644 --- a/openbsd-compat/bsd-cygwin_util.h +++ b/openbsd-compat/bsd-cygwin_util.h @@ -1,5 +1,3 @@ -/* $Id: bsd-cygwin_util.h,v 1.18 2014/05/27 04:34:43 djm Exp $ */ - /* * Copyright (c) 2000, 2001, 2011, 2013 Corinna Vinschen <vinschen@redhat.com> * @@ -43,7 +41,7 @@ typedef void *HANDLE; #define UNLEN 256 /* Cygwin functions for which declarations are only available when including - windows headers, so we have to define them here explicitely. */ + windows headers, so we have to define them here explicitly. */ extern HANDLE cygwin_logon_user (const struct passwd *, const char *); extern void cygwin_set_impersonation_token (const HANDLE); @@ -57,6 +55,7 @@ int binary_open(const char *, int , ...); int check_ntsec(const char *); char **fetch_windows_environment(void); void free_windows_environment(char **); +int cygwin_ug_match_pattern_list(const char *, const char *); #ifndef NO_BINARY_OPEN #define open binary_open diff --git a/openbsd-compat/bsd-err.c b/openbsd-compat/bsd-err.c new file mode 100644 index 00000000..e4ed22b8 --- /dev/null +++ b/openbsd-compat/bsd-err.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015 Tim Rice <tim@multitalents.net> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifndef HAVE_ERR +void +err(int r, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + fprintf(stderr, "%s: ", strerror(errno)); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); + exit(r); +} +#endif + +#ifndef HAVE_ERRX +void +errx(int r, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); + exit(r); +} +#endif + +#ifndef HAVE_WARN +void +warn(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + fprintf(stderr, "%s: ", strerror(errno)); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); +} +#endif diff --git a/openbsd-compat/bsd-flock.c b/openbsd-compat/bsd-flock.c new file mode 100644 index 00000000..9b15d1ea --- /dev/null +++ b/openbsd-compat/bsd-flock.c @@ -0,0 +1,81 @@ +/* $NetBSD: flock.c,v 1.6 2008/04/28 20:24:12 martin Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Todd Vierling. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Emulate flock() with fcntl(), where available. + * Otherwise, don't do locking; just pretend success. + */ + +#include "includes.h" + +#ifndef HAVE_FLOCK +#include <errno.h> +#include <fcntl.h> + +int +flock(int fd, int op) +{ + int rc = 0; + +#if defined(F_SETLK) && defined(F_SETLKW) + struct flock fl = {0}; + + switch (op & (LOCK_EX|LOCK_SH|LOCK_UN)) { + case LOCK_EX: + fl.l_type = F_WRLCK; + break; + + case LOCK_SH: + fl.l_type = F_RDLCK; + break; + + case LOCK_UN: + fl.l_type = F_UNLCK; + break; + + default: + errno = EINVAL; + return -1; + } + + fl.l_whence = SEEK_SET; + rc = fcntl(fd, op & LOCK_NB ? F_SETLK : F_SETLKW, &fl); + + if (rc && (errno == EAGAIN)) + errno = EWOULDBLOCK; +#else + rc = -1; + errno = ENOSYS; +#endif + + return rc; +} +#endif diff --git a/openbsd-compat/bsd-getline.c b/openbsd-compat/bsd-getline.c new file mode 100644 index 00000000..d676f4ce --- /dev/null +++ b/openbsd-compat/bsd-getline.c @@ -0,0 +1,113 @@ +/* $NetBSD: getline.c,v 1.1.1.6 2015/01/02 20:34:27 christos Exp $ */ + +/* NetBSD: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* NETBSD ORIGINAL: external/bsd/file/dist/src/getline.c */ + +#include "includes.h" + +#if 0 +#include "file.h" +#endif + +#if !HAVE_GETLINE +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> + +static ssize_t +getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) +{ + char *ptr, *eptr; + + + if (*buf == NULL || *bufsiz == 0) { + if ((*buf = malloc(BUFSIZ)) == NULL) + return -1; + *bufsiz = BUFSIZ; + } + + for (ptr = *buf, eptr = *buf + *bufsiz;;) { + int c = fgetc(fp); + if (c == -1) { + if (feof(fp)) { + ssize_t diff = (ssize_t)(ptr - *buf); + if (diff != 0) { + *ptr = '\0'; + return diff; + } + } + return -1; + } + *ptr++ = c; + if (c == delimiter) { + *ptr = '\0'; + return ptr - *buf; + } + if (ptr + 2 >= eptr) { + char *nbuf; + size_t nbufsiz = *bufsiz * 2; + ssize_t d = ptr - *buf; + if ((nbuf = realloc(*buf, nbufsiz)) == NULL) + return -1; + *buf = nbuf; + *bufsiz = nbufsiz; + eptr = nbuf + nbufsiz; + ptr = nbuf + d; + } + } +} + +ssize_t +getline(char **buf, size_t *bufsiz, FILE *fp) +{ + return getdelim(buf, bufsiz, '\n', fp); +} + +#endif + +#ifdef TEST +int +main(int argc, char *argv[]) +{ + char *p = NULL; + ssize_t len; + size_t n = 0; + + while ((len = getline(&p, &n, stdin)) != -1) + (void)printf("%" SIZE_T_FORMAT "d %s", len, p); + free(p); + return 0; +} +#endif diff --git a/openbsd-compat/bsd-getpagesize.c b/openbsd-compat/bsd-getpagesize.c new file mode 100644 index 00000000..416a8d4c --- /dev/null +++ b/openbsd-compat/bsd-getpagesize.c @@ -0,0 +1,25 @@ +/* Placed in the public domain */ + +#include "includes.h" + +#ifndef HAVE_GETPAGESIZE + +#include <unistd.h> +#include <limits.h> + +int +getpagesize(void) +{ +#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) + long r = sysconf(_SC_PAGESIZE); + if (r > 0 && r < INT_MAX) + return (int)r; +#endif + /* + * This is at the lower end of common values and appropriate for + * our current use of getpagesize() in recallocarray(). + */ + return 4096; +} + +#endif /* HAVE_GETPAGESIZE */ diff --git a/openbsd-compat/bsd-malloc.c b/openbsd-compat/bsd-malloc.c new file mode 100644 index 00000000..482facdc --- /dev/null +++ b/openbsd-compat/bsd-malloc.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017 Darren Tucker (dtucker at zip com au). + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "config.h" +#undef malloc +#undef calloc +#undef realloc + +#include <sys/types.h> +#include <stdlib.h> + +#if defined(HAVE_MALLOC) && HAVE_MALLOC == 0 +void * +rpl_malloc(size_t size) +{ + if (size == 0) + size = 1; + return malloc(size); +} +#endif + +#if defined(HAVE_CALLOC) && HAVE_CALLOC == 0 +void * +rpl_calloc(size_t nmemb, size_t size) +{ + if (nmemb == 0) + nmemb = 1; + if (size == 0) + size = 1; + return calloc(nmemb, size); +} +#endif + +#if defined (HAVE_REALLOC) && HAVE_REALLOC == 0 +void * +rpl_realloc(void *ptr, size_t size) +{ + if (size == 0) + size = 1; + if (ptr == 0) + return malloc(size); + return realloc(ptr, size); +} +#endif diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index f7be415e..059b6d3b 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -25,9 +25,11 @@ # include <sys/time.h> #endif +#include <fcntl.h> #include <string.h> #include <signal.h> #include <stdlib.h> +#include <stdio.h> #include <time.h> #include <unistd.h> @@ -70,8 +72,8 @@ int setlogin(const char *name) #endif /* !HAVE_SETLOGIN */ #ifndef HAVE_INNETGR -int innetgr(const char *netgroup, const char *host, - const char *user, const char *domain) +int innetgr(const char *netgroup, const char *host, + const char *user, const char *domain) { return (0); } @@ -96,7 +98,7 @@ const char *strerror(int e) { extern int sys_nerr; extern char *sys_errlist[]; - + if ((e >= 0) && (e < sys_nerr)) return (sys_errlist[e]); @@ -111,10 +113,112 @@ int utimes(char *filename, struct timeval *tvp) ub.actime = tvp[0].tv_sec; ub.modtime = tvp[1].tv_sec; - + return (utime(filename, &ub)); } -#endif +#endif + +#ifndef HAVE_UTIMENSAT +/* + * A limited implementation of utimensat() that only implements the + * functionality used by OpenSSH, currently only AT_FDCWD and + * AT_SYMLINK_NOFOLLOW. + */ +int +utimensat(int fd, const char *path, const struct timespec times[2], + int flag) +{ + struct timeval tv[2]; +# ifdef HAVE_FUTIMES + int ret, oflags = O_WRONLY; +# endif + + tv[0].tv_sec = times[0].tv_sec; + tv[0].tv_usec = times[0].tv_nsec / 1000; + tv[1].tv_sec = times[1].tv_sec; + tv[1].tv_usec = times[1].tv_nsec / 1000; + + if (fd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } +# ifndef HAVE_FUTIMES + return utimes(path, tv); +# else +# ifdef O_NOFOLLOW + if (flag & AT_SYMLINK_NOFOLLOW) + oflags |= O_NOFOLLOW; +# endif /* O_NOFOLLOW */ + if ((fd = open(path, oflags)) == -1) + return -1; + ret = futimes(fd, tv); + close(fd); + return ret; +# endif +} +#endif + +#ifndef HAVE_FCHOWNAT +/* + * A limited implementation of fchownat() that only implements the + * functionality used by OpenSSH, currently only AT_FDCWD and + * AT_SYMLINK_NOFOLLOW. + */ +int +fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag) +{ + int ret, oflags = O_WRONLY; + + if (fd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } +# ifndef HAVE_FCHOWN + return chown(path, owner, group); +# else +# ifdef O_NOFOLLOW + if (flag & AT_SYMLINK_NOFOLLOW) + oflags |= O_NOFOLLOW; +# endif /* O_NOFOLLOW */ + if ((fd = open(path, oflags)) == -1) + return -1; + ret = fchown(fd, owner, group); + close(fd); + return ret; +# endif +} +#endif + +#ifndef HAVE_FCHMODAT +/* + * A limited implementation of fchmodat() that only implements the + * functionality used by OpenSSH, currently only AT_FDCWD and + * AT_SYMLINK_NOFOLLOW. + */ +int +fchmodat(int fd, const char *path, mode_t mode, int flag) +{ + int ret, oflags = O_WRONLY; + + if (fd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } +# ifndef HAVE_FCHMOD + return chmod(path, mode); +# else +# ifdef O_NOFOLLOW + if (flag & AT_SYMLINK_NOFOLLOW) + oflags |= O_NOFOLLOW; +# endif /* O_NOFOLLOW */ + if ((fd = open(path, oflags)) == -1) + return -1; + ret = fchmod(fd, mode); + close(fd); + return ret; +# endif +} +#endif #ifndef HAVE_TRUNCATE int truncate(const char *path, off_t length) @@ -149,9 +253,9 @@ int nanosleep(const struct timespec *req, struct timespec *rem) saverrno = errno; (void) gettimeofday (&tstop, NULL); errno = saverrno; - tremain.tv_sec = time2wait.tv_sec - + tremain.tv_sec = time2wait.tv_sec - (tstop.tv_sec - tstart.tv_sec); - tremain.tv_usec = time2wait.tv_usec - + tremain.tv_usec = time2wait.tv_usec - (tstop.tv_usec - tstart.tv_usec); tremain.tv_sec += tremain.tv_usec / 1000000L; tremain.tv_usec %= 1000000L; @@ -211,33 +315,6 @@ tcsendbreak(int fd, int duration) } #endif /* HAVE_TCSENDBREAK */ -mysig_t -mysignal(int sig, mysig_t act) -{ -#ifdef HAVE_SIGACTION - struct sigaction sa, osa; - - if (sigaction(sig, NULL, &osa) == -1) - return (mysig_t) -1; - if (osa.sa_handler != act) { - memset(&sa, 0, sizeof(sa)); - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; -#ifdef SA_INTERRUPT - if (sig == SIGALRM) - sa.sa_flags |= SA_INTERRUPT; -#endif - sa.sa_handler = act; - if (sigaction(sig, &sa, NULL) == -1) - return (mysig_t) -1; - } - return (osa.sa_handler); -#else - #undef signal - return (signal(sig, act)); -#endif -} - #ifndef HAVE_STRDUP char * strdup(const char *str) @@ -265,7 +342,7 @@ isblank(int c) pid_t getpgid(pid_t pid) { -#if defined(HAVE_GETPGRP) && !defined(GETPGRP_VOID) +#if defined(HAVE_GETPGRP) && !defined(GETPGRP_VOID) && GETPGRP_VOID == 0 return getpgrp(pid); #elif defined(HAVE_GETPGRP) if (pid == 0) @@ -276,3 +353,88 @@ getpgid(pid_t pid) return -1; } #endif + +#ifndef HAVE_PLEDGE +int +pledge(const char *promises, const char *paths[]) +{ + return 0; +} +#endif + +#ifndef HAVE_MBTOWC +/* a mbtowc that only supports ASCII */ +int +mbtowc(wchar_t *pwc, const char *s, size_t n) +{ + if (s == NULL || *s == '\0') + return 0; /* ASCII is not state-dependent */ + if (*s < 0 || *s > 0x7f || n < 1) { + errno = EOPNOTSUPP; + return -1; + } + if (pwc != NULL) + *pwc = *s; + return 1; +} +#endif + +#ifndef HAVE_LLABS +long long +llabs(long long j) +{ + return (j < 0 ? -j : j); +} +#endif + +#ifndef HAVE_BZERO +void +bzero(void *b, size_t n) +{ + (void)memset(b, 0, n); +} +#endif + +#ifndef HAVE_RAISE +int +raise(int sig) +{ + kill(getpid(), sig); +} +#endif + +#ifndef HAVE_GETSID +pid_t +getsid(pid_t pid) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifdef FFLUSH_NULL_BUG +#undef fflush +int _ssh_compat_fflush(FILE *f) +{ + int r1, r2; + + if (f == NULL) { + r1 = fflush(stdout); + r2 = fflush(stderr); + if (r1 == -1 || r2 == -1) + return -1; + return 0; + } + return fflush(f); +} +#endif + +#ifndef HAVE_LOCALTIME_R +struct tm * +localtime_r(const time_t *timep, struct tm *result) +{ + struct tm *tm = localtime(timep); + *result = *tm; + return result; +} +#endif diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h index 65c18ec2..3a7dd6f4 100644 --- a/openbsd-compat/bsd-misc.h +++ b/openbsd-compat/bsd-misc.h @@ -1,5 +1,3 @@ -/* $Id: bsd-misc.h,v 1.25 2013/08/04 11:48:41 dtucker Exp $ */ - /* * Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org> * @@ -49,7 +47,7 @@ int setegid(uid_t); #if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) const char *strerror(int); -#endif +#endif #if !defined(HAVE_SETLINEBUF) #define setlinebuf(a) (setvbuf((a), NULL, _IOLBF, 0)) @@ -66,20 +64,43 @@ struct timeval { int utimes(char *, struct timeval *); #endif /* HAVE_UTIMES */ +#ifndef AT_FDCWD +# define AT_FDCWD (-2) +#endif + +#ifndef HAVE_FCHMODAT +int fchmodat(int, const char *, mode_t, int); +#endif + +#ifndef HAVE_FCHOWNAT +int fchownat(int, const char *, uid_t, gid_t, int); +#endif + #ifndef HAVE_TRUNCATE int truncate (const char *, off_t); #endif /* HAVE_TRUNCATE */ -#if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) #ifndef HAVE_STRUCT_TIMESPEC struct timespec { time_t tv_sec; long tv_nsec; }; -#endif +#endif /* !HAVE_STRUCT_TIMESPEC */ + +#if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) +# include <time.h> int nanosleep(const struct timespec *, struct timespec *); #endif +#ifndef HAVE_UTIMENSAT +# include <time.h> +/* start with the high bits and work down to minimise risk of overlap */ +# ifndef AT_SYMLINK_NOFOLLOW +# define AT_SYMLINK_NOFOLLOW 0x80000000 +# endif +int utimensat(int, const char *, const struct timespec[2], int); +#endif /* !HAVE_UTIMENSAT */ + #ifndef HAVE_USLEEP int usleep(unsigned int useconds); #endif @@ -96,12 +117,6 @@ int tcsendbreak(int, int); int unsetenv(const char *); #endif -/* wrapper for signal interface */ -typedef void (*mysig_t)(int); -mysig_t mysignal(int sig, mysig_t act); - -#define signal(a,b) mysignal(a,b) - #ifndef HAVE_ISBLANK int isblank(int); #endif @@ -111,7 +126,7 @@ pid_t getpgid(pid_t); #endif #ifndef HAVE_ENDGRENT -# define endgrent() {} +# define endgrent() do { } while(0) #endif #ifndef HAVE_KRB5_GET_ERROR_MESSAGE @@ -119,7 +134,58 @@ pid_t getpgid(pid_t); #endif #ifndef HAVE_KRB5_FREE_ERROR_MESSAGE -# define krb5_free_error_message(a,b) while(0) +# define krb5_free_error_message(a,b) do { } while(0) +#endif + +#ifndef HAVE_PLEDGE +int pledge(const char *promises, const char *paths[]); +#endif + +/* bsd-err.h */ +#ifndef HAVE_ERR +void err(int, const char *, ...) __attribute__((format(printf, 2, 3))); +#endif +#ifndef HAVE_ERRX +void errx(int, const char *, ...) __attribute__((format(printf, 2, 3))); +#endif +#ifndef HAVE_WARN +void warn(const char *, ...) __attribute__((format(printf, 1, 2))); +#endif + +#ifndef HAVE_LLABS +long long llabs(long long); +#endif + +#if defined(HAVE_DECL_BZERO) && HAVE_DECL_BZERO == 0 +void bzero(void *, size_t); +#endif + +#ifndef HAVE_RAISE +int raise(int); +#endif + +#ifndef HAVE_GETSID +pid_t getsid(pid_t); +#endif + +#ifndef HAVE_FLOCK +# define LOCK_SH 0x01 +# define LOCK_EX 0x02 +# define LOCK_NB 0x04 +# define LOCK_UN 0x08 +int flock(int, int); +#endif + +#ifdef FFLUSH_NULL_BUG +# define fflush(x) (_ssh_compat_fflush(x)) +#endif + +#ifndef HAVE_LOCALTIME_R +struct tm *localtime_r(const time_t *, struct tm *); +#endif + +#ifndef HAVE_REALPATH +#define realpath(x, y) (sftp_realpath((x), (y))) #endif #endif /* _BSD_MISC_H */ diff --git a/openbsd-compat/bsd-nextstep.c b/openbsd-compat/bsd-nextstep.c index 8195af88..d52443f6 100644 --- a/openbsd-compat/bsd-nextstep.c +++ b/openbsd-compat/bsd-nextstep.c @@ -29,7 +29,7 @@ #include <sys/wait.h> #include "bsd-nextstep.h" -pid_t +pid_t posix_wait(int *status) { union wait statusp; diff --git a/openbsd-compat/bsd-nextstep.h b/openbsd-compat/bsd-nextstep.h index ca5b4b54..4a45b15a 100644 --- a/openbsd-compat/bsd-nextstep.h +++ b/openbsd-compat/bsd-nextstep.h @@ -1,5 +1,3 @@ -/* $Id: bsd-nextstep.h,v 1.9 2003/08/29 16:59:52 mouring Exp $ */ - /* * Copyright (c) 2000,2001 Ben Lindstrom. All rights reserved. * @@ -38,7 +36,7 @@ /* NeXT's readdir() is BSD (struct direct) not POSIX (struct dirent) */ #define dirent direct -/* Swap out NeXT's BSD wait() for a more POSIX complient one */ +/* Swap out NeXT's BSD wait() for a more POSIX compliant one */ pid_t posix_wait(int *); #define wait(a) posix_wait(a) diff --git a/openbsd-compat/bsd-openpty.c b/openbsd-compat/bsd-openpty.c index 1e0c3333..0b3fc3b2 100644 --- a/openbsd-compat/bsd-openpty.c +++ b/openbsd-compat/bsd-openpty.c @@ -65,6 +65,8 @@ #include <string.h> #include <unistd.h> +#include "misc.h" + #ifndef O_NOCTTY #define O_NOCTTY 0 #endif @@ -97,16 +99,16 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp, */ int ptm; char *pts; - mysig_t old_signal; + sshsig_t old_signal; if ((ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) return (-1); /* XXX: need to close ptm on error? */ - old_signal = signal(SIGCHLD, SIG_DFL); + old_signal = ssh_signal(SIGCHLD, SIG_DFL); if (grantpt(ptm) < 0) return (-1); - signal(SIGCHLD, old_signal); + ssh_signal(SIGCHLD, old_signal); if (unlockpt(ptm) < 0) return (-1); @@ -122,8 +124,17 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp, } #if !defined(ANDROID) +# if defined(I_FIND) && defined(__SVR4) + /* + * If the streams modules have already been pushed then there + * is no more work to do here. + */ + if (ioctl(*aslave, I_FIND, "ptem") != 0) + return 0; +# endif + /* - * Try to push the appropriate streams modules, as described + * Try to push the appropriate streams modules, as described * in Solaris pts(7). */ ioctl(*aslave, I_PUSH, "ptem"); @@ -149,31 +160,6 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp, } return (0); -#elif defined(_UNICOS) - char ptbuf[64], ttbuf[64]; - int i; - int highpty; - - highpty = 128; -#ifdef _SC_CRAY_NPTY - if ((highpty = sysconf(_SC_CRAY_NPTY)) == -1) - highpty = 128; -#endif /* _SC_CRAY_NPTY */ - - for (i = 0; i < highpty; i++) { - snprintf(ptbuf, sizeof(ptbuf), "/dev/pty/%03d", i); - snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%03d", i); - if ((*amaster = open(ptbuf, O_RDWR|O_NOCTTY)) == -1) - continue; - /* Open the slave side. */ - if ((*aslave = open(ttbuf, O_RDWR|O_NOCTTY)) == -1) { - close(*amaster); - return (-1); - } - return (0); - } - return (-1); - #else /* BSD-style pty code. */ char ptbuf[64], ttbuf[64]; @@ -186,7 +172,7 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct termios tio; for (i = 0; i < num_ptys; i++) { - snprintf(ptbuf, sizeof(ptbuf), "/dev/pty%c%c", + snprintf(ptbuf, sizeof(ptbuf), "/dev/pty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); snprintf(ttbuf, sizeof(ttbuf), "/dev/tty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); diff --git a/openbsd-compat/bsd-poll.c b/openbsd-compat/bsd-poll.c index 73a85248..c8e6222c 100644 --- a/openbsd-compat/bsd-poll.c +++ b/openbsd-compat/bsd-poll.c @@ -1,5 +1,3 @@ -/* $Id: bsd-poll.c,v 1.6 2014/02/05 23:44:13 dtucker Exp $ */ - /* * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). * diff --git a/openbsd-compat/bsd-poll.h b/openbsd-compat/bsd-poll.h index dcbb9ca4..17945f5b 100644 --- a/openbsd-compat/bsd-poll.h +++ b/openbsd-compat/bsd-poll.h @@ -42,11 +42,11 @@ typedef unsigned int nfds_t; #define POLLIN 0x0001 #define POLLOUT 0x0004 #define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 #if 0 /* the following are currently not implemented */ #define POLLPRI 0x0002 -#define POLLHUP 0x0010 -#define POLLNVAL 0x0020 #define POLLRDNORM 0x0040 #define POLLNORM POLLRDNORM #define POLLWRNORM POLLOUT diff --git a/openbsd-compat/bsd-setres_id.c b/openbsd-compat/bsd-setres_id.c index 018bde8c..04752d5a 100644 --- a/openbsd-compat/bsd-setres_id.c +++ b/openbsd-compat/bsd-setres_id.c @@ -1,5 +1,3 @@ -/* $Id: bsd-setres_id.c,v 1.2 2013/12/07 21:23:09 djm Exp $ */ - /* * Copyright (c) 2012 Darren Tucker (dtucker at zip com au). * @@ -39,20 +37,20 @@ setresgid(gid_t rgid, gid_t egid, gid_t sgid) #if defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID) if (setregid(rgid, egid) < 0) { saved_errno = errno; - error("setregid %u: %.100s", rgid, strerror(errno)); + error("setregid %lu: %.100s", (u_long)rgid, strerror(errno)); errno = saved_errno; ret = -1; } #else if (setegid(egid) < 0) { saved_errno = errno; - error("setegid %u: %.100s", (u_int)egid, strerror(errno)); + error("setegid %lu: %.100s", (u_long)egid, strerror(errno)); errno = saved_errno; ret = -1; } if (setgid(rgid) < 0) { saved_errno = errno; - error("setgid %u: %.100s", rgid, strerror(errno)); + error("setgid %lu: %.100s", (u_long)rgid, strerror(errno)); errno = saved_errno; ret = -1; } @@ -74,7 +72,7 @@ setresuid(uid_t ruid, uid_t euid, uid_t suid) #if defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID) if (setreuid(ruid, euid) < 0) { saved_errno = errno; - error("setreuid %u: %.100s", ruid, strerror(errno)); + error("setreuid %lu: %.100s", (u_long)ruid, strerror(errno)); errno = saved_errno; ret = -1; } @@ -83,14 +81,14 @@ setresuid(uid_t ruid, uid_t euid, uid_t suid) # ifndef SETEUID_BREAKS_SETUID if (seteuid(euid) < 0) { saved_errno = errno; - error("seteuid %u: %.100s", euid, strerror(errno)); + error("seteuid %lu: %.100s", (u_long)euid, strerror(errno)); errno = saved_errno; ret = -1; } # endif if (setuid(ruid) < 0) { saved_errno = errno; - error("setuid %u: %.100s", ruid, strerror(errno)); + error("setuid %lu: %.100s", (u_long)ruid, strerror(errno)); errno = saved_errno; ret = -1; } diff --git a/openbsd-compat/bsd-setres_id.h b/openbsd-compat/bsd-setres_id.h index 6c269e0b..0350a596 100644 --- a/openbsd-compat/bsd-setres_id.h +++ b/openbsd-compat/bsd-setres_id.h @@ -1,5 +1,3 @@ -/* $Id: bsd-setres_id.h,v 1.1 2012/11/05 06:04:37 dtucker Exp $ */ - /* * Copyright (c) 2012 Darren Tucker (dtucker at zip com au). * diff --git a/openbsd-compat/bsd-signal.c b/openbsd-compat/bsd-signal.c new file mode 100644 index 00000000..38d5e972 --- /dev/null +++ b/openbsd-compat/bsd-signal.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <signal.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include "openbsd-compat/bsd-signal.h" + +#if !defined(HAVE_STRSIGNAL) +char *strsignal(int sig) +{ + static char buf[16]; + + (void)snprintf(buf, sizeof(buf), "%d", sig); + return buf; +} +#endif + diff --git a/openbsd-compat/bsd-signal.h b/openbsd-compat/bsd-signal.h new file mode 100644 index 00000000..8d8c4441 --- /dev/null +++ b/openbsd-compat/bsd-signal.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BSD_SIGNAL_H +#define _BSD_SIGNAL_H + +#include "includes.h" + +#include <signal.h> + +#ifndef _NSIG +# ifdef NSIG +# define _NSIG NSIG +# else +# define _NSIG 128 +# endif +#endif + +#if !defined(HAVE_STRSIGNAL) +char *strsignal(int); +#endif + +#endif /* _BSD_SIGNAL_H */ diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index 23a63598..f041121f 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c @@ -30,7 +30,7 @@ * probably requires libm on most operating systems. Don't yet * support the exponent (e,E) and sigfig (g,G). Also, fmtint() * was pretty badly broken, it just wasn't being exercised in ways - * which showed it, so that's been fixed. Also, formated the code + * which showed it, so that's been fixed. Also, formatted the code * to mutt conventions, and removed dead code left over from the * original. Also, there is now a builtin-test, just compile with: * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm @@ -73,7 +73,7 @@ * Fix incorrect zpadlen handling in fmtfp. * Thanks to Ollie Oldham <ollie.oldham@metro-optix.com> for spotting it. * few mods to make it easier to compile the tests. - * addedd the "Ollie" test to the floating point ones. + * added the "Ollie" test to the floating point ones. * * Martin Pool (mbp@samba.org) April 2003 * Remove NO_CONFIG_H so that the test case can be built within a source @@ -99,18 +99,6 @@ # undef HAVE_VSNPRINTF #endif -#ifndef VA_COPY -# ifdef HAVE_VA_COPY -# define VA_COPY(dest, src) va_copy(dest, src) -# else -# ifdef HAVE___VA_COPY -# define VA_COPY(dest, src) __va_copy(dest, src) -# else -# define VA_COPY(dest, src) (dest) = (src) -# endif -# endif -#endif - #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) #include <ctype.h> diff --git a/openbsd-compat/bsd-statvfs.c b/openbsd-compat/bsd-statvfs.c index 2d93bfc8..b05ee2b3 100644 --- a/openbsd-compat/bsd-statvfs.c +++ b/openbsd-compat/bsd-statvfs.c @@ -1,5 +1,3 @@ -/* $Id: bsd-statvfs.c,v 1.2 2014/01/17 07:10:59 dtucker Exp $ */ - /* * Copyright (c) 2008,2014 Darren Tucker <dtucker@zip.com.au> * @@ -26,13 +24,21 @@ #endif #if defined(ANDROID) -#include <sys/vfs.h> -#include <string.h> +#include <sys/param.h> #define MNAMELEN PATH_MAX #endif #include <errno.h> +#ifndef MNAMELEN +# define MNAMELEN 32 +#endif + +#ifdef HAVE_STRUCT_STATFS_F_FILES +# define HAVE_STRUCT_STATFS +#endif + +#ifdef HAVE_STRUCT_STATFS static void copy_statfs_to_statvfs(struct statvfs *to, struct statfs *from) { @@ -45,18 +51,19 @@ copy_statfs_to_statvfs(struct statvfs *to, struct statfs *from) to->f_ffree = from->f_ffree; to->f_favail = from->f_ffree; /* no exact equivalent */ to->f_fsid = 0; /* XXX fix me */ -#if GCE_PLATFORM_SDK_VERSION >= 19 +#ifdef HAVE_STRUCT_STATFS_F_FLAGS to->f_flag = from->f_flags; #else - to->f_flag = from->f_spare[0]; + to->f_flag = 0; #endif to->f_namemax = MNAMELEN; } +#endif # ifndef HAVE_STATVFS int statvfs(const char *path, struct statvfs *buf) { -# ifdef HAVE_STATFS +# if defined(HAVE_STATFS) && defined(HAVE_STRUCT_STATFS) struct statfs fs; memset(&fs, 0, sizeof(fs)); @@ -74,7 +81,7 @@ int statvfs(const char *path, struct statvfs *buf) # ifndef HAVE_FSTATVFS int fstatvfs(int fd, struct statvfs *buf) { -# ifdef HAVE_FSTATFS +# if defined(HAVE_FSTATFS) && defined(HAVE_STRUCT_STATFS) struct statfs fs; memset(&fs, 0, sizeof(fs)); diff --git a/openbsd-compat/bsd-statvfs.h b/openbsd-compat/bsd-statvfs.h index dfd60997..e2a4c15f 100644 --- a/openbsd-compat/bsd-statvfs.h +++ b/openbsd-compat/bsd-statvfs.h @@ -1,5 +1,3 @@ -/* $Id: bsd-statvfs.h,v 1.3 2014/01/17 07:48:22 dtucker Exp $ */ - /* * Copyright (c) 2008,2014 Darren Tucker <dtucker@zip.com.au> * @@ -28,6 +26,9 @@ #ifdef HAVE_SYS_STATFS_H #include <sys/statfs.h> #endif +#ifdef HAVE_SYS_VFS_H +#include <sys/vfs.h> +#endif #ifndef HAVE_FSBLKCNT_T typedef unsigned long fsblkcnt_t; diff --git a/openbsd-compat/bsd-waitpid.c b/openbsd-compat/bsd-waitpid.c index 40e6ffaa..113fb1ea 100644 --- a/openbsd-compat/bsd-waitpid.c +++ b/openbsd-compat/bsd-waitpid.c @@ -24,7 +24,7 @@ #include "includes.h" -#ifndef HAVE_WAITPID +#ifndef HAVE_WAITPID #include <errno.h> #include <sys/wait.h> #include "bsd-waitpid.h" @@ -43,11 +43,11 @@ waitpid(int pid, int *stat_loc, int options) /* wait4() wants pid=0 for indiscriminate wait. */ pid = 0; } - wait_pid = wait4(pid, &statusp, options, NULL); + wait_pid = wait4(pid, &statusp, options, NULL); if (stat_loc) - *stat_loc = (int) statusp.w_status; + *stat_loc = (int) statusp.w_status; - return (wait_pid); + return (wait_pid); } #endif /* !HAVE_WAITPID */ diff --git a/openbsd-compat/bsd-waitpid.h b/openbsd-compat/bsd-waitpid.h index 2d853db6..b551268a 100644 --- a/openbsd-compat/bsd-waitpid.h +++ b/openbsd-compat/bsd-waitpid.h @@ -1,5 +1,3 @@ -/* $Id: bsd-waitpid.h,v 1.5 2003/08/29 16:59:52 mouring Exp $ */ - /* * Copyright (c) 2000 Ben Lindstrom. All rights reserved. * @@ -29,7 +27,7 @@ #define _BSD_WAITPID_H #ifndef HAVE_WAITPID -/* Clean out any potental issues */ +/* Clean out any potential issues */ #undef WIFEXITED #undef WIFSTOPPED #undef WIFSIGNALED diff --git a/openbsd-compat/explicit_bzero.c b/openbsd-compat/explicit_bzero.c index 13f87fe3..7a2fa354 100644 --- a/openbsd-compat/explicit_bzero.c +++ b/openbsd-compat/explicit_bzero.c @@ -6,6 +6,7 @@ */ #include "includes.h" + #include <string.h> /* @@ -19,6 +20,8 @@ void explicit_bzero(void *p, size_t n) { + if (n == 0) + return; (void)memset_s(p, n, 0, n); } @@ -28,12 +31,29 @@ explicit_bzero(void *p, size_t n) * Indirect bzero through a volatile pointer to hopefully avoid * dead-store optimisation eliminating the call. */ -static void* (* volatile ssh_memset)(void *, int, size_t) = memset; +#if defined(ANDROID) +static void (* volatile ssh_bzero)(void *, size_t) = __bionic_bzero; +#else +static void (* volatile ssh_bzero)(void *, size_t) = bzero; +#endif void explicit_bzero(void *p, size_t n) { - ssh_memset(p, 0, n); + if (n == 0) + return; + /* + * clang -fsanitize=memory needs to intercept memset-like functions + * to correctly detect memory initialisation. Make sure one is called + * directly since our indirection trick above successfully confuses it. + */ +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) + memset(p, 0, n); +# endif +#endif + + ssh_bzero(p, n); } #endif /* HAVE_MEMSET_S */ diff --git a/openbsd-compat/fake-rfc2553.c b/openbsd-compat/fake-rfc2553.c index 096d9e09..d5a62975 100644 --- a/openbsd-compat/fake-rfc2553.c +++ b/openbsd-compat/fake-rfc2553.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2000-2003 Damien Miller. All rights reserved. * Copyright (C) 1999 WIDE Project. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +13,7 @@ * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -44,8 +44,8 @@ #include <arpa/inet.h> #ifndef HAVE_GETNAMEINFO -int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, - size_t hostlen, char *serv, size_t servlen, int flags) +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags) { struct sockaddr_in *sin = (struct sockaddr_in *)sa; struct hostent *hp; @@ -67,11 +67,11 @@ int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, else return (0); } else { - hp = gethostbyaddr((char *)&sin->sin_addr, + hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr), AF_INET); if (hp == NULL) return (EAI_NODATA); - + if (strlcpy(host, hp->h_name, hostlen) >= hostlen) return (EAI_MEMORY); else @@ -102,7 +102,7 @@ gai_strerror(int err) default: return ("unknown/invalid error."); } -} +} #endif /* !HAVE_GAI_STRERROR */ #ifndef HAVE_FREEADDRINFO @@ -128,9 +128,9 @@ addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints) ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in)); if (ai == NULL) return (NULL); - + memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in)); - + ai->ai_addr = (struct sockaddr *)(ai + 1); /* XXX -- ssh doesn't use sa_len */ ai->ai_addrlen = sizeof(struct sockaddr_in); @@ -138,7 +138,7 @@ addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints) ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; - + /* XXX: the following is not generally correct, but does what we want */ if (hints->ai_socktype) ai->ai_socktype = hints->ai_socktype; @@ -152,7 +152,7 @@ addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints) } int -getaddrinfo(const char *hostname, const char *servname, +getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { struct hostent *hp; @@ -183,29 +183,29 @@ getaddrinfo(const char *hostname, const char *servname, if (hostname && inet_aton(hostname, &in) != 0) addr = in.s_addr; *res = malloc_ai(port, addr, hints); - if (*res == NULL) + if (*res == NULL) return (EAI_MEMORY); return (0); } - + if (!hostname) { *res = malloc_ai(port, htonl(0x7f000001), hints); - if (*res == NULL) + if (*res == NULL) return (EAI_MEMORY); return (0); } - + if (inet_aton(hostname, &in)) { *res = malloc_ai(port, in.s_addr, hints); - if (*res == NULL) + if (*res == NULL) return (EAI_MEMORY); return (0); } - + /* Don't try DNS if AI_NUMERICHOST is set */ if (hints && hints->ai_flags & AI_NUMERICHOST) return (EAI_NONAME); - + hp = gethostbyname(hostname); if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { struct addrinfo *cur, *prev; @@ -229,7 +229,7 @@ getaddrinfo(const char *hostname, const char *servname, } return (0); } - + return (EAI_NODATA); } #endif /* !HAVE_GETADDRINFO */ diff --git a/openbsd-compat/fake-rfc2553.h b/openbsd-compat/fake-rfc2553.h index 6426f7bf..f913617f 100644 --- a/openbsd-compat/fake-rfc2553.h +++ b/openbsd-compat/fake-rfc2553.h @@ -1,9 +1,7 @@ -/* $Id: fake-rfc2553.h,v 1.16 2008/07/14 11:37:37 djm Exp $ */ - /* * Copyright (C) 2000-2003 Damien Miller. All rights reserved. * Copyright (C) 1999 WIDE Project. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +13,7 @@ * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -47,7 +45,7 @@ #endif /* - * First, socket and INET6 related definitions + * First, socket and INET6 related definitions */ #ifndef HAVE_STRUCT_SOCKADDR_STORAGE # define _SS_MAXSIZE 128 /* Implementation specific max size */ @@ -154,7 +152,7 @@ struct addrinfo { # undef getaddrinfo #endif #define getaddrinfo(a,b,c,d) (ssh_getaddrinfo(a,b,c,d)) -int getaddrinfo(const char *, const char *, +int getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **); #endif /* !HAVE_GETADDRINFO */ @@ -170,7 +168,7 @@ void freeaddrinfo(struct addrinfo *); #ifndef HAVE_GETNAMEINFO #define getnameinfo(a,b,c,d,e,f,g) (ssh_getnameinfo(a,b,c,d,e,f,g)) -int getnameinfo(const struct sockaddr *, size_t, char *, size_t, +int getnameinfo(const struct sockaddr *, size_t, char *, size_t, char *, size_t, int); #endif /* !HAVE_GETNAMEINFO */ diff --git a/openbsd-compat/fmt_scaled.c b/openbsd-compat/fmt_scaled.c index edd682a4..2f76ef93 100644 --- a/openbsd-compat/fmt_scaled.c +++ b/openbsd-compat/fmt_scaled.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fmt_scaled.c,v 1.9 2007/03/20 03:42:52 tedu Exp $ */ +/* $OpenBSD: fmt_scaled.c,v 1.17 2018/05/14 04:39:04 djm Exp $ */ /* * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved. @@ -69,7 +69,7 @@ static long long scale_factors[] = { #define MAX_DIGITS (SCALE_LENGTH * 3) /* XXX strlen(sprintf("%lld", -1)? */ -/** Convert the given input string "scaled" into numeric in "result". +/* Convert the given input string "scaled" into numeric in "result". * Return 0 on success, -1 and errno set on error. */ int @@ -81,7 +81,7 @@ scan_scaled(char *scaled, long long *result) long long scale_fact = 1, whole = 0, fpart = 0; /* Skip leading whitespace */ - while (isascii(*p) && isspace(*p)) + while (isascii((unsigned char)*p) && isspace((unsigned char)*p)) ++p; /* Then at most one leading + or - */ @@ -108,7 +108,8 @@ scan_scaled(char *scaled, long long *result) * (but note that E for Exa might look like e to some!). * Advance 'p' to end, to get scale factor. */ - for (; isascii(*p) && (isdigit(*p) || *p=='.'); ++p) { + for (; isascii((unsigned char)*p) && + (isdigit((unsigned char)*p) || *p=='.'); ++p) { if (*p == '.') { if (fract_digits > 0) { /* oops, more than one '.' */ errno = EINVAL; @@ -124,14 +125,30 @@ scan_scaled(char *scaled, long long *result) /* ignore extra fractional digits */ continue; fract_digits++; /* for later scaling */ + if (fpart > LLONG_MAX / 10) { + errno = ERANGE; + return -1; + } fpart *= 10; + if (i > LLONG_MAX - fpart) { + errno = ERANGE; + return -1; + } fpart += i; } else { /* normal digit */ if (++ndigits >= MAX_DIGITS) { errno = ERANGE; return -1; } + if (whole > LLONG_MAX / 10) { + errno = ERANGE; + return -1; + } whole *= 10; + if (i > LLONG_MAX - whole) { + errno = ERANGE; + return -1; + } whole += i; } } @@ -150,21 +167,28 @@ scan_scaled(char *scaled, long long *result) /* Validate scale factor, and scale whole and fraction by it. */ for (i = 0; i < SCALE_LENGTH; i++) { - /** Are we there yet? */ + /* Are we there yet? */ if (*p == scale_chars[i] || - *p == tolower(scale_chars[i])) { + *p == tolower((unsigned char)scale_chars[i])) { /* If it ends with alphanumerics after the scale char, bad. */ - if (isalnum(*(p+1))) { + if (isalnum((unsigned char)*(p+1))) { errno = EINVAL; return -1; } scale_fact = scale_factors[i]; + /* check for overflow and underflow after scaling */ + if (whole > LLONG_MAX / scale_fact || + whole < LLONG_MIN / scale_fact) { + errno = ERANGE; + return -1; + } + /* scale whole part */ whole *= scale_fact; - /* truncate fpart so it does't overflow. + /* truncate fpart so it doesn't overflow. * then scale fractional part. */ while (fpart >= LLONG_MAX / scale_fact) { @@ -181,7 +205,9 @@ scan_scaled(char *scaled, long long *result) return 0; } } - errno = ERANGE; + + /* Invalid unit or character */ + errno = EINVAL; return -1; } @@ -196,7 +222,7 @@ fmt_scaled(long long number, char *result) unsigned int i; unit_type unit = NONE; - abval = (number < 0LL) ? -number : number; /* no long long_abs yet */ + abval = llabs(number); /* Not every negative long long has a positive representation. * Also check for numbers that are just too darned big to format @@ -220,12 +246,15 @@ fmt_scaled(long long number, char *result) fract = (10 * fract + 512) / 1024; /* if the result would be >= 10, round main number */ - if (fract == 10) { + if (fract >= 10) { if (number >= 0) number++; else number--; fract = 0; + } else if (fract < 0) { + /* shouldn't happen */ + fract = 0; } if (number == 0) diff --git a/openbsd-compat/fnmatch.c b/openbsd-compat/fnmatch.c new file mode 100644 index 00000000..b5641a09 --- /dev/null +++ b/openbsd-compat/fnmatch.c @@ -0,0 +1,495 @@ +/* $OpenBSD: fnmatch.c,v 1.22 2020/03/13 03:25:45 djm Exp $ */ + +/* Copyright (c) 2011, VMware, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the VMware, Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2008, 2016 Todd C. Miller <millert@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* Authored by William A. Rowe Jr. <wrowe; apache.org, vmware.com>, April 2011 + * + * Derived from The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008 + * as described in; + * http://pubs.opengroup.org/onlinepubs/9699919799/functions/fnmatch.html + * + * Filename pattern matches defined in section 2.13, "Pattern Matching Notation" + * from chapter 2. "Shell Command Language" + * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13 + * where; 1. A bracket expression starting with an unquoted <circumflex> '^' + * character CONTINUES to specify a non-matching list; 2. an explicit <period> '.' + * in a bracket expression matching list, e.g. "[.abc]" does NOT match a leading + * <period> in a filename; 3. a <left-square-bracket> '[' which does not introduce + * a valid bracket expression is treated as an ordinary character; 4. a differing + * number of consecutive slashes within pattern and string will NOT match; + * 5. a trailing '\' in FNM_ESCAPE mode is treated as an ordinary '\' character. + * + * Bracket expansion defined in section 9.3.5, "RE Bracket Expression", + * from chapter 9, "Regular Expressions" + * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05 + * with no support for collating symbols, equivalence class expressions or + * character class expressions. A partial range expression with a leading + * hyphen following a valid range expression will match only the ordinary + * <hyphen> and the ending character (e.g. "[a-m-z]" will match characters + * 'a' through 'm', a <hyphen> '-', or a 'z'). + * + * Supports BSD extensions FNM_LEADING_DIR to match pattern to the end of one + * path segment of string, and FNM_CASEFOLD to ignore alpha case. + * + * NOTE: Only POSIX/C single byte locales are correctly supported at this time. + * Notably, non-POSIX locales with FNM_CASEFOLD produce undefined results, + * particularly in ranges of mixed case (e.g. "[A-z]") or spanning alpha and + * nonalpha characters within a range. + * + * XXX comments below indicate porting required for multi-byte character sets + * and non-POSIX locale collation orders; requires mbr* APIs to track shift + * state of pattern and string (rewinding pattern and string repeatedly). + * + * Certain parts of the code assume 0x00-0x3F are unique with any MBCS (e.g. + * UTF-8, SHIFT-JIS, etc). Any implementation allowing '\' as an alternate + * path delimiter must be aware that 0x5C is NOT unique within SHIFT-JIS. + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/fnmatch.c */ + +#include "includes.h" +#ifndef HAVE_FNMATCH + +#include <fnmatch.h> +#include <string.h> +#include <ctype.h> + +#include "charclass.h" + +#define RANGE_MATCH 1 +#define RANGE_NOMATCH 0 +#define RANGE_ERROR (-1) + +static int +classmatch(const char *pattern, char test, int foldcase, const char **ep) +{ + const char * const mismatch = pattern; + const char *colon; + struct cclass *cc; + int rval = RANGE_NOMATCH; + size_t len; + + if (pattern[0] != '[' || pattern[1] != ':') { + *ep = mismatch; + return RANGE_ERROR; + } + pattern += 2; + + if ((colon = strchr(pattern, ':')) == NULL || colon[1] != ']') { + *ep = mismatch; + return RANGE_ERROR; + } + *ep = colon + 2; + len = (size_t)(colon - pattern); + + if (foldcase && strncmp(pattern, "upper:]", 7) == 0) + pattern = "lower:]"; + for (cc = cclasses; cc->name != NULL; cc++) { + if (!strncmp(pattern, cc->name, len) && cc->name[len] == '\0') { + if (cc->isctype((unsigned char)test)) + rval = RANGE_MATCH; + break; + } + } + if (cc->name == NULL) { + /* invalid character class, treat as normal text */ + *ep = mismatch; + rval = RANGE_ERROR; + } + return rval; +} + +/* Most MBCS/collation/case issues handled here. Wildcard '*' is not handled. + * EOS '\0' and the FNM_PATHNAME '/' delimiters are not advanced over, + * however the "\/" sequence is advanced to '/'. + * + * Both pattern and string are **char to support pointer increment of arbitrary + * multibyte characters for the given locale, in a later iteration of this code + */ +static int fnmatch_ch(const char **pattern, const char **string, int flags) +{ + const char * const mismatch = *pattern; + const int nocase = !!(flags & FNM_CASEFOLD); + const int escape = !(flags & FNM_NOESCAPE); + const int slash = !!(flags & FNM_PATHNAME); + int result = FNM_NOMATCH; + const char *startch; + int negate; + + if (**pattern == '[') { + ++*pattern; + + /* Handle negation, either leading ! or ^ operators */ + negate = (**pattern == '!') || (**pattern == '^'); + if (negate) + ++*pattern; + + /* ']' is an ordinary char at the start of the range pattern */ + if (**pattern == ']') + goto leadingclosebrace; + + while (**pattern) { + if (**pattern == ']') { + ++*pattern; + /* XXX: Fix for MBCS character width */ + ++*string; + return (result ^ negate); + } + + if (escape && (**pattern == '\\')) { + ++*pattern; + + /* Patterns must terminate with ']', not EOS */ + if (!**pattern) + break; + } + + /* Patterns must terminate with ']' not '/' */ + if (slash && (**pattern == '/')) + break; + + /* Match character classes. */ + switch (classmatch(*pattern, **string, nocase, pattern)) { + case RANGE_MATCH: + result = 0; + continue; + case RANGE_NOMATCH: + /* Valid character class but no match. */ + continue; + default: + /* Not a valid character class. */ + break; + } + if (!**pattern) + break; + +leadingclosebrace: + /* Look at only well-formed range patterns; + * "x-]" is not allowed unless escaped ("x-\]") + * XXX: Fix for locale/MBCS character width + */ + if (((*pattern)[1] == '-') && ((*pattern)[2] != ']')) { + startch = *pattern; + *pattern += (escape && ((*pattern)[2] == '\\')) ? 3 : 2; + + /* + * NOT a properly balanced [expr] pattern, EOS + * terminated or ranges containing a slash in + * FNM_PATHNAME mode pattern fall out to to the + * rewind and test '[' literal code path. + */ + if (!**pattern || (slash && (**pattern == '/'))) + break; + + /* XXX: handle locale/MBCS comparison, advance by MBCS char width */ + if ((**string >= *startch) && (**string <= **pattern)) + result = 0; + else if (nocase && + (isupper((unsigned char)**string) || + isupper((unsigned char)*startch) || + isupper((unsigned char)**pattern)) && + (tolower((unsigned char)**string) >= + tolower((unsigned char)*startch)) && + (tolower((unsigned char)**string) <= + tolower((unsigned char)**pattern))) + result = 0; + + ++*pattern; + continue; + } + + /* XXX: handle locale/MBCS comparison, advance by MBCS char width */ + if ((**string == **pattern)) + result = 0; + else if (nocase && (isupper((unsigned char)**string) || + isupper((unsigned char)**pattern)) && + (tolower((unsigned char)**string) == + tolower((unsigned char)**pattern))) + result = 0; + + ++*pattern; + } + /* + * NOT a properly balanced [expr] pattern; + * Rewind and reset result to test '[' literal + */ + *pattern = mismatch; + result = FNM_NOMATCH; + } else if (**pattern == '?') { + /* Optimize '?' match before unescaping **pattern */ + if (!**string || (slash && (**string == '/'))) + return FNM_NOMATCH; + result = 0; + goto fnmatch_ch_success; + } else if (escape && (**pattern == '\\') && (*pattern)[1]) { + ++*pattern; + } + + /* XXX: handle locale/MBCS comparison, advance by the MBCS char width */ + if (**string == **pattern) + result = 0; + else if (nocase && (isupper((unsigned char)**string) || + isupper((unsigned char)**pattern)) && + (tolower((unsigned char)**string) == + tolower((unsigned char)**pattern))) + result = 0; + + /* Refuse to advance over trailing slash or NULs */ + if (**string == '\0' || **pattern == '\0' || + (slash && ((**string == '/') || (**pattern == '/')))) + return result; + +fnmatch_ch_success: + ++*pattern; + ++*string; + return result; +} + + +int fnmatch(const char *pattern, const char *string, int flags) +{ + static const char dummystring[2] = {' ', 0}; + const int escape = !(flags & FNM_NOESCAPE); + const int slash = !!(flags & FNM_PATHNAME); + const int leading_dir = !!(flags & FNM_LEADING_DIR); + const char *dummyptr, *matchptr, *strendseg; + int wild; + /* For '*' wild processing only; suppress 'used before initialization' + * warnings with dummy initialization values; + */ + const char *strstartseg = NULL; + const char *mismatch = NULL; + int matchlen = 0; + + if (*pattern == '*') + goto firstsegment; + + while (*pattern && *string) { + /* + * Pre-decode "\/" which has no special significance, and + * match balanced slashes, starting a new segment pattern. + */ + if (slash && escape && (*pattern == '\\') && (pattern[1] == '/')) + ++pattern; + if (slash && (*pattern == '/') && (*string == '/')) { + ++pattern; + ++string; + } + +firstsegment: + /* + * At the beginning of each segment, validate leading period + * behavior. + */ + if ((flags & FNM_PERIOD) && (*string == '.')) { + if (*pattern == '.') + ++pattern; + else if (escape && (*pattern == '\\') && (pattern[1] == '.')) + pattern += 2; + else + return FNM_NOMATCH; + ++string; + } + + /* + * Determine the end of string segment. Presumes '/' + * character is unique, not composite in any MBCS encoding + */ + if (slash) { + strendseg = strchr(string, '/'); + if (!strendseg) + strendseg = strchr(string, '\0'); + } else { + strendseg = strchr(string, '\0'); + } + + /* + * Allow pattern '*' to be consumed even with no remaining + * string to match. + */ + while (*pattern) { + if ((string > strendseg) || + ((string == strendseg) && (*pattern != '*'))) + break; + + if (slash && ((*pattern == '/') || + (escape && (*pattern == '\\') && (pattern[1] == '/')))) + break; + + /* + * Reduce groups of '*' and '?' to n '?' matches + * followed by one '*' test for simplicity. + */ + for (wild = 0; (*pattern == '*') || (*pattern == '?'); ++pattern) { + if (*pattern == '*') { + wild = 1; + } else if (string < strendseg) { /* && (*pattern == '?') */ + /* XXX: Advance 1 char for MBCS locale */ + ++string; + } + else { /* (string >= strendseg) && (*pattern == '?') */ + return FNM_NOMATCH; + } + } + + if (wild) { + strstartseg = string; + mismatch = pattern; + + /* + * Count fixed (non '*') char matches remaining + * in pattern * excluding '/' (or "\/") and '*'. + */ + for (matchptr = pattern, matchlen = 0; 1; ++matchlen) { + if ((*matchptr == '\0') || + (slash && ((*matchptr == '/') || + (escape && (*matchptr == '\\') && + (matchptr[1] == '/'))))) { + /* Compare precisely this many + * trailing string chars, the + * resulting match needs no + * wildcard loop. + */ + /* XXX: Adjust for MBCS */ + if (string + matchlen > strendseg) + return FNM_NOMATCH; + + string = strendseg - matchlen; + wild = 0; + break; + } + + if (*matchptr == '*') { + /* + * Ensure at least this many + * trailing string chars remain + * for the first comparison. + */ + /* XXX: Adjust for MBCS */ + if (string + matchlen > strendseg) + return FNM_NOMATCH; + + /* + * Begin first wild comparison + * at the current position. + */ + break; + } + + /* + * Skip forward in pattern by a single + * character match Use a dummy + * fnmatch_ch() test to count one + * "[range]" escape. + */ + /* XXX: Adjust for MBCS */ + if (escape && (*matchptr == '\\') && + matchptr[1]) { + matchptr += 2; + } else if (*matchptr == '[') { + dummyptr = dummystring; + fnmatch_ch(&matchptr, &dummyptr, + flags); + } else { + ++matchptr; + } + } + } + + /* Incrementally match string against the pattern. */ + while (*pattern && (string < strendseg)) { + /* Success; begin a new wild pattern search. */ + if (*pattern == '*') + break; + + if (slash && ((*string == '/') || + (*pattern == '/') || (escape && + (*pattern == '\\') && (pattern[1] == '/')))) + break; + + /* + * Compare ch's (the pattern is advanced over + * "\/" to the '/', but slashes will mismatch, + * and are not consumed). + */ + if (!fnmatch_ch(&pattern, &string, flags)) + continue; + + /* + * Failed to match, loop against next char + * offset of string segment until not enough + * string chars remain to match the fixed + * pattern. + */ + if (wild) { + /* XXX: Advance 1 char for MBCS locale */ + string = ++strstartseg; + if (string + matchlen > strendseg) + return FNM_NOMATCH; + + pattern = mismatch; + continue; + } else + return FNM_NOMATCH; + } + } + + if (*string && !((slash || leading_dir) && (*string == '/'))) + return FNM_NOMATCH; + + if (*pattern && !(slash && ((*pattern == '/') || + (escape && (*pattern == '\\') && (pattern[1] == '/'))))) + return FNM_NOMATCH; + + if (leading_dir && !*pattern && *string == '/') + return 0; + } + + /* Where both pattern and string are at EOS, declare success. */ + if (!*string && !*pattern) + return 0; + + /* Pattern didn't match to the end of string. */ + return FNM_NOMATCH; +} +#endif /* HAVE_FNMATCH */ diff --git a/openbsd-compat/fnmatch.h b/openbsd-compat/fnmatch.h new file mode 100644 index 00000000..d3bc4a86 --- /dev/null +++ b/openbsd-compat/fnmatch.h @@ -0,0 +1,66 @@ +/* $OpenBSD: fnmatch.h,v 1.8 2005/12/13 00:35:22 millert Exp $ */ +/* $NetBSD: fnmatch.h,v 1.5 1994/10/26 00:55:53 cgd Exp $ */ + +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93 + */ + +/* OPENBSD ORIGINAL: include/fnmatch.h */ + +#ifndef HAVE_FNMATCH_H +/* Ensure we define FNM_CASEFOLD */ +#define __BSD_VISIBLE 1 + +#ifndef _FNMATCH_H_ +#define _FNMATCH_H_ + +#ifdef HAVE_SYS_CDEFS_H +#include <sys/cdefs.h> +#endif + +#define FNM_NOMATCH 1 /* Match failed. */ +#define FNM_NOSYS 2 /* Function not supported (unused). */ + +#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ +#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ +#define FNM_PERIOD 0x04 /* Period must be matched by period. */ +#if __BSD_VISIBLE +#define FNM_LEADING_DIR 0x08 /* Ignore /<tail> after Imatch. */ +#define FNM_CASEFOLD 0x10 /* Case insensitive search. */ +#define FNM_IGNORECASE FNM_CASEFOLD +#define FNM_FILE_NAME FNM_PATHNAME +#endif + +/* __BEGIN_DECLS */ +int fnmatch(const char *, const char *, int); +/* __END_DECLS */ + +#endif /* !_FNMATCH_H_ */ +#endif /* ! HAVE_FNMATCH_H */ diff --git a/openbsd-compat/freezero.c b/openbsd-compat/freezero.c new file mode 100644 index 00000000..bad018ff --- /dev/null +++ b/openbsd-compat/freezero.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <stdlib.h> +#include <string.h> + +#ifndef HAVE_FREEZERO + +void +freezero(void *ptr, size_t sz) +{ + if (ptr == NULL) + return; + explicit_bzero(ptr, sz); + free(ptr); +} + +#endif /* HAVE_FREEZERO */ + diff --git a/openbsd-compat/getcwd.c b/openbsd-compat/getcwd.c index 3edbb9cb..e4f7f5a3 100644 --- a/openbsd-compat/getcwd.c +++ b/openbsd-compat/getcwd.c @@ -1,4 +1,4 @@ -/* from OpenBSD: getcwd.c,v 1.14 2005/08/08 08:05:34 espie Exp */ +/* $OpenBSD: getcwd.c,v 1.14 2005/08/08 08:05:34 espie Exp */ /* * Copyright (c) 1989, 1991, 1993 * The Regents of the University of California. All rights reserved. diff --git a/openbsd-compat/getgrouplist.c b/openbsd-compat/getgrouplist.c index 3afcb928..3906cd62 100644 --- a/openbsd-compat/getgrouplist.c +++ b/openbsd-compat/getgrouplist.c @@ -1,4 +1,4 @@ -/* from OpenBSD: getgrouplist.c,v 1.12 2005/08/08 08:05:34 espie Exp */ +/* $OpenBSD: getgrouplist.c,v 1.12 2005/08/08 08:05:34 espie Exp */ /* * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. diff --git a/openbsd-compat/getrrsetbyname.c b/openbsd-compat/getrrsetbyname.c index d2bea212..dc6fe053 100644 --- a/openbsd-compat/getrrsetbyname.c +++ b/openbsd-compat/getrrsetbyname.c @@ -56,8 +56,6 @@ #include <arpa/inet.h> #include "getrrsetbyname.h" -#include "nameser.h" -#include "nameser_compat.h" #if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO extern int h_errno; diff --git a/openbsd-compat/getrrsetbyname.c.orig b/openbsd-compat/getrrsetbyname.c.orig deleted file mode 100644 index dc6fe053..00000000 --- a/openbsd-compat/getrrsetbyname.c.orig +++ /dev/null @@ -1,610 +0,0 @@ -/* $OpenBSD: getrrsetbyname.c,v 1.11 2007/10/11 18:36:41 jakob Exp $ */ - -/* - * Copyright (c) 2001 Jakob Schlyter. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */ - -#include "includes.h" - -#if !defined (HAVE_GETRRSETBYNAME) && !defined (HAVE_LDNS) - -#include <stdlib.h> -#include <string.h> - -#include <netinet/in.h> -#include <arpa/inet.h> - -#include "getrrsetbyname.h" - -#if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO -extern int h_errno; -#endif - -/* We don't need multithread support here */ -#ifdef _THREAD_PRIVATE -# undef _THREAD_PRIVATE -#endif -#define _THREAD_PRIVATE(a,b,c) (c) - -#ifndef HAVE__RES_EXTERN -struct __res_state _res; -#endif - -/* Necessary functions and macros */ - -/* - * Inline versions of get/put short/long. Pointer is advanced. - * - * These macros demonstrate the property of C whereby it can be - * portable or it can be elegant but rarely both. - */ - -#ifndef INT32SZ -# define INT32SZ 4 -#endif -#ifndef INT16SZ -# define INT16SZ 2 -#endif - -#ifndef GETSHORT -#define GETSHORT(s, cp) { \ - register u_char *t_cp = (u_char *)(cp); \ - (s) = ((u_int16_t)t_cp[0] << 8) \ - | ((u_int16_t)t_cp[1]) \ - ; \ - (cp) += INT16SZ; \ -} -#endif - -#ifndef GETLONG -#define GETLONG(l, cp) { \ - register u_char *t_cp = (u_char *)(cp); \ - (l) = ((u_int32_t)t_cp[0] << 24) \ - | ((u_int32_t)t_cp[1] << 16) \ - | ((u_int32_t)t_cp[2] << 8) \ - | ((u_int32_t)t_cp[3]) \ - ; \ - (cp) += INT32SZ; \ -} -#endif - -/* - * Routines to insert/extract short/long's. - */ - -#ifndef HAVE__GETSHORT -static u_int16_t -_getshort(msgp) - register const u_char *msgp; -{ - register u_int16_t u; - - GETSHORT(u, msgp); - return (u); -} -#elif defined(HAVE_DECL__GETSHORT) && (HAVE_DECL__GETSHORT == 0) -u_int16_t _getshort(register const u_char *); -#endif - -#ifndef HAVE__GETLONG -static u_int32_t -_getlong(msgp) - register const u_char *msgp; -{ - register u_int32_t u; - - GETLONG(u, msgp); - return (u); -} -#elif defined(HAVE_DECL__GETLONG) && (HAVE_DECL__GETLONG == 0) -u_int32_t _getlong(register const u_char *); -#endif - -/* ************** */ - -#define ANSWER_BUFFER_SIZE 0xffff - -struct dns_query { - char *name; - u_int16_t type; - u_int16_t class; - struct dns_query *next; -}; - -struct dns_rr { - char *name; - u_int16_t type; - u_int16_t class; - u_int16_t ttl; - u_int16_t size; - void *rdata; - struct dns_rr *next; -}; - -struct dns_response { - HEADER header; - struct dns_query *query; - struct dns_rr *answer; - struct dns_rr *authority; - struct dns_rr *additional; -}; - -static struct dns_response *parse_dns_response(const u_char *, int); -static struct dns_query *parse_dns_qsection(const u_char *, int, - const u_char **, int); -static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **, - int); - -static void free_dns_query(struct dns_query *); -static void free_dns_rr(struct dns_rr *); -static void free_dns_response(struct dns_response *); - -static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); - -int -getrrsetbyname(const char *hostname, unsigned int rdclass, - unsigned int rdtype, unsigned int flags, - struct rrsetinfo **res) -{ - struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); - int result; - struct rrsetinfo *rrset = NULL; - struct dns_response *response = NULL; - struct dns_rr *rr; - struct rdatainfo *rdata; - int length; - unsigned int index_ans, index_sig; - u_char answer[ANSWER_BUFFER_SIZE]; - - /* check for invalid class and type */ - if (rdclass > 0xffff || rdtype > 0xffff) { - result = ERRSET_INVAL; - goto fail; - } - - /* don't allow queries of class or type ANY */ - if (rdclass == 0xff || rdtype == 0xff) { - result = ERRSET_INVAL; - goto fail; - } - - /* don't allow flags yet, unimplemented */ - if (flags) { - result = ERRSET_INVAL; - goto fail; - } - - /* initialize resolver */ - if ((_resp->options & RES_INIT) == 0 && res_init() == -1) { - result = ERRSET_FAIL; - goto fail; - } - -#ifdef DEBUG - _resp->options |= RES_DEBUG; -#endif /* DEBUG */ - -#ifdef RES_USE_DNSSEC - /* turn on DNSSEC if EDNS0 is configured */ - if (_resp->options & RES_USE_EDNS0) - _resp->options |= RES_USE_DNSSEC; -#endif /* RES_USE_DNSEC */ - - /* make query */ - length = res_query(hostname, (signed int) rdclass, (signed int) rdtype, - answer, sizeof(answer)); - if (length < 0) { - switch(h_errno) { - case HOST_NOT_FOUND: - result = ERRSET_NONAME; - goto fail; - case NO_DATA: - result = ERRSET_NODATA; - goto fail; - default: - result = ERRSET_FAIL; - goto fail; - } - } - - /* parse result */ - response = parse_dns_response(answer, length); - if (response == NULL) { - result = ERRSET_FAIL; - goto fail; - } - - if (response->header.qdcount != 1) { - result = ERRSET_FAIL; - goto fail; - } - - /* initialize rrset */ - rrset = calloc(1, sizeof(struct rrsetinfo)); - if (rrset == NULL) { - result = ERRSET_NOMEMORY; - goto fail; - } - rrset->rri_rdclass = response->query->class; - rrset->rri_rdtype = response->query->type; - rrset->rri_ttl = response->answer->ttl; - rrset->rri_nrdatas = response->header.ancount; - -#ifdef HAVE_HEADER_AD - /* check for authenticated data */ - if (response->header.ad == 1) - rrset->rri_flags |= RRSET_VALIDATED; -#endif - - /* copy name from answer section */ - rrset->rri_name = strdup(response->answer->name); - if (rrset->rri_name == NULL) { - result = ERRSET_NOMEMORY; - goto fail; - } - - /* count answers */ - rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass, - rrset->rri_rdtype); - rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass, - T_RRSIG); - - /* allocate memory for answers */ - rrset->rri_rdatas = calloc(rrset->rri_nrdatas, - sizeof(struct rdatainfo)); - if (rrset->rri_rdatas == NULL) { - result = ERRSET_NOMEMORY; - goto fail; - } - - /* allocate memory for signatures */ - if (rrset->rri_nsigs > 0) { - rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); - if (rrset->rri_sigs == NULL) { - result = ERRSET_NOMEMORY; - goto fail; - } - } - - /* copy answers & signatures */ - for (rr = response->answer, index_ans = 0, index_sig = 0; - rr; rr = rr->next) { - - rdata = NULL; - - if (rr->class == rrset->rri_rdclass && - rr->type == rrset->rri_rdtype) - rdata = &rrset->rri_rdatas[index_ans++]; - - if (rr->class == rrset->rri_rdclass && - rr->type == T_RRSIG) - rdata = &rrset->rri_sigs[index_sig++]; - - if (rdata) { - rdata->rdi_length = rr->size; - rdata->rdi_data = malloc(rr->size); - - if (rdata->rdi_data == NULL) { - result = ERRSET_NOMEMORY; - goto fail; - } - memcpy(rdata->rdi_data, rr->rdata, rr->size); - } - } - free_dns_response(response); - - *res = rrset; - return (ERRSET_SUCCESS); - -fail: - if (rrset != NULL) - freerrset(rrset); - if (response != NULL) - free_dns_response(response); - return (result); -} - -void -freerrset(struct rrsetinfo *rrset) -{ - u_int16_t i; - - if (rrset == NULL) - return; - - if (rrset->rri_rdatas) { - for (i = 0; i < rrset->rri_nrdatas; i++) { - if (rrset->rri_rdatas[i].rdi_data == NULL) - break; - free(rrset->rri_rdatas[i].rdi_data); - } - free(rrset->rri_rdatas); - } - - if (rrset->rri_sigs) { - for (i = 0; i < rrset->rri_nsigs; i++) { - if (rrset->rri_sigs[i].rdi_data == NULL) - break; - free(rrset->rri_sigs[i].rdi_data); - } - free(rrset->rri_sigs); - } - - if (rrset->rri_name) - free(rrset->rri_name); - free(rrset); -} - -/* - * DNS response parsing routines - */ -static struct dns_response * -parse_dns_response(const u_char *answer, int size) -{ - struct dns_response *resp; - const u_char *cp; - - /* allocate memory for the response */ - resp = calloc(1, sizeof(*resp)); - if (resp == NULL) - return (NULL); - - /* initialize current pointer */ - cp = answer; - - /* copy header */ - memcpy(&resp->header, cp, HFIXEDSZ); - cp += HFIXEDSZ; - - /* fix header byte order */ - resp->header.qdcount = ntohs(resp->header.qdcount); - resp->header.ancount = ntohs(resp->header.ancount); - resp->header.nscount = ntohs(resp->header.nscount); - resp->header.arcount = ntohs(resp->header.arcount); - - /* there must be at least one query */ - if (resp->header.qdcount < 1) { - free_dns_response(resp); - return (NULL); - } - - /* parse query section */ - resp->query = parse_dns_qsection(answer, size, &cp, - resp->header.qdcount); - if (resp->header.qdcount && resp->query == NULL) { - free_dns_response(resp); - return (NULL); - } - - /* parse answer section */ - resp->answer = parse_dns_rrsection(answer, size, &cp, - resp->header.ancount); - if (resp->header.ancount && resp->answer == NULL) { - free_dns_response(resp); - return (NULL); - } - - /* parse authority section */ - resp->authority = parse_dns_rrsection(answer, size, &cp, - resp->header.nscount); - if (resp->header.nscount && resp->authority == NULL) { - free_dns_response(resp); - return (NULL); - } - - /* parse additional section */ - resp->additional = parse_dns_rrsection(answer, size, &cp, - resp->header.arcount); - if (resp->header.arcount && resp->additional == NULL) { - free_dns_response(resp); - return (NULL); - } - - return (resp); -} - -static struct dns_query * -parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count) -{ - struct dns_query *head, *curr, *prev; - int i, length; - char name[MAXDNAME]; - - for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) { - - /* allocate and initialize struct */ - curr = calloc(1, sizeof(struct dns_query)); - if (curr == NULL) { - free_dns_query(head); - return (NULL); - } - if (head == NULL) - head = curr; - if (prev != NULL) - prev->next = curr; - - /* name */ - length = dn_expand(answer, answer + size, *cp, name, - sizeof(name)); - if (length < 0) { - free_dns_query(head); - return (NULL); - } - curr->name = strdup(name); - if (curr->name == NULL) { - free_dns_query(head); - return (NULL); - } - *cp += length; - - /* type */ - curr->type = _getshort(*cp); - *cp += INT16SZ; - - /* class */ - curr->class = _getshort(*cp); - *cp += INT16SZ; - } - - return (head); -} - -static struct dns_rr * -parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, - int count) -{ - struct dns_rr *head, *curr, *prev; - int i, length; - char name[MAXDNAME]; - - for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) { - - /* allocate and initialize struct */ - curr = calloc(1, sizeof(struct dns_rr)); - if (curr == NULL) { - free_dns_rr(head); - return (NULL); - } - if (head == NULL) - head = curr; - if (prev != NULL) - prev->next = curr; - - /* name */ - length = dn_expand(answer, answer + size, *cp, name, - sizeof(name)); - if (length < 0) { - free_dns_rr(head); - return (NULL); - } - curr->name = strdup(name); - if (curr->name == NULL) { - free_dns_rr(head); - return (NULL); - } - *cp += length; - - /* type */ - curr->type = _getshort(*cp); - *cp += INT16SZ; - - /* class */ - curr->class = _getshort(*cp); - *cp += INT16SZ; - - /* ttl */ - curr->ttl = _getlong(*cp); - *cp += INT32SZ; - - /* rdata size */ - curr->size = _getshort(*cp); - *cp += INT16SZ; - - /* rdata itself */ - curr->rdata = malloc(curr->size); - if (curr->rdata == NULL) { - free_dns_rr(head); - return (NULL); - } - memcpy(curr->rdata, *cp, curr->size); - *cp += curr->size; - } - - return (head); -} - -static void -free_dns_query(struct dns_query *p) -{ - if (p == NULL) - return; - - if (p->name) - free(p->name); - free_dns_query(p->next); - free(p); -} - -static void -free_dns_rr(struct dns_rr *p) -{ - if (p == NULL) - return; - - if (p->name) - free(p->name); - if (p->rdata) - free(p->rdata); - free_dns_rr(p->next); - free(p); -} - -static void -free_dns_response(struct dns_response *p) -{ - if (p == NULL) - return; - - free_dns_query(p->query); - free_dns_rr(p->answer); - free_dns_rr(p->authority); - free_dns_rr(p->additional); - free(p); -} - -static int -count_dns_rr(struct dns_rr *p, u_int16_t class, u_int16_t type) -{ - int n = 0; - - while(p) { - if (p->class == class && p->type == type) - n++; - p = p->next; - } - - return (n); -} - -#endif /* !defined (HAVE_GETRRSETBYNAME) && !defined (HAVE_LDNS) */ diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c index 742b4b95..e8915178 100644 --- a/openbsd-compat/glob.c +++ b/openbsd-compat/glob.c @@ -1,4 +1,4 @@ -/* $OpenBSD: glob.c,v 1.38 2011/09/22 06:27:29 djm Exp $ */ +/* $OpenBSD: glob.c,v 1.49 2020/04/21 08:25:22 dtucker Exp $ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -59,6 +59,7 @@ */ #include "includes.h" +#include "glob.h" #include <sys/types.h> #include <sys/stat.h> @@ -69,6 +70,9 @@ #include <limits.h> #include <pwd.h> #include <stdlib.h> +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif #include <string.h> #include <unistd.h> @@ -79,6 +83,10 @@ #include "charclass.h" +#ifdef TILDE +# undef TILDE +#endif + #define DOLLAR '$' #define DOT '.' #define EOS '\0' @@ -130,12 +138,9 @@ typedef char Char; #define ismeta(c) (((c)&M_QUOTE) != 0) #define GLOB_LIMIT_MALLOC 65536 -#define GLOB_LIMIT_STAT 128 +#define GLOB_LIMIT_STAT 2048 #define GLOB_LIMIT_READDIR 16384 -/* Limit of recursion during matching attempts. */ -#define GLOB_LIMIT_RECUR 64 - struct glob_lim { size_t glim_malloc; size_t glim_stat; @@ -149,7 +154,7 @@ struct glob_path_stat { static int compare(const void *, const void *); static int compare_gps(const void *, const void *); -static int g_Ctoc(const Char *, char *, u_int); +static int g_Ctoc(const Char *, char *, size_t); static int g_lstat(Char *, struct stat *, glob_t *); static DIR *g_opendir(Char *, glob_t *); static Char *g_strchr(const Char *, int); @@ -168,7 +173,7 @@ static const Char * static int globexp1(const Char *, glob_t *, struct glob_lim *); static int globexp2(const Char *, const Char *, glob_t *, struct glob_lim *); -static int match(Char *, Char *, Char *, int); +static int match(Char *, Char *, Char *); #ifdef DEBUG static void qprintf(const char *, Char *); #endif @@ -179,12 +184,9 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int), { const u_char *patnext; int c; - Char *bufnext, *bufend, patbuf[MAXPATHLEN]; + Char *bufnext, *bufend, patbuf[PATH_MAX]; struct glob_lim limit = { 0, 0, 0 }; - if (strnlen(pattern, PATH_MAX) == PATH_MAX) - return(GLOB_NOMATCH); - patnext = (u_char *) pattern; if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; @@ -197,13 +199,15 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int), pglob->gl_errfunc = errfunc; pglob->gl_matchc = 0; - if (pglob->gl_offs < 0 || pglob->gl_pathc < 0 || - pglob->gl_offs >= INT_MAX || pglob->gl_pathc >= INT_MAX || - pglob->gl_pathc >= INT_MAX - pglob->gl_offs - 1) + if (strnlen(pattern, PATH_MAX) == PATH_MAX) + return(GLOB_NOMATCH); + + if (pglob->gl_offs >= SSIZE_MAX || pglob->gl_pathc >= SSIZE_MAX || + pglob->gl_pathc >= SSIZE_MAX - pglob->gl_offs - 1) return GLOB_NOSPACE; bufnext = patbuf; - bufend = bufnext + MAXPATHLEN - 1; + bufend = bufnext + PATH_MAX - 1; if (flags & GLOB_NOESCAPE) while (bufnext < bufend && (c = *patnext++) != EOS) *bufnext++ = c; @@ -260,7 +264,7 @@ globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int i, rv; Char *lm, *ls; const Char *pe, *pm, *pl; - Char patbuf[MAXPATHLEN]; + Char patbuf[PATH_MAX]; /* copy part up to the brace */ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) @@ -471,10 +475,11 @@ static int glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) { const Char *qpatnext; - int c, err, oldpathc; - Char *bufnext, patbuf[MAXPATHLEN]; + int c, err; + size_t oldpathc; + Char *bufnext, patbuf[PATH_MAX]; - qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); + qpatnext = globtilde(pattern, patbuf, PATH_MAX, pglob); oldpathc = pglob->gl_pathc; bufnext = patbuf; @@ -544,7 +549,7 @@ glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) qprintf("glob0:", patbuf); #endif - if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp)) != 0) + if ((err = glob1(patbuf, patbuf+PATH_MAX-1, pglob, limitp)) != 0) return(err); /* @@ -565,9 +570,9 @@ glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) if ((pglob->gl_flags & GLOB_KEEPSTAT)) { /* Keep the paths and stat info synced during sort */ struct glob_path_stat *path_stat; - int i; - int n = pglob->gl_pathc - oldpathc; - int o = pglob->gl_offs + oldpathc; + size_t i; + size_t n = pglob->gl_pathc - oldpathc; + size_t o = pglob->gl_offs + oldpathc; if ((path_stat = calloc(n, sizeof(*path_stat))) == NULL) return GLOB_NOSPACE; @@ -608,13 +613,13 @@ compare_gps(const void *_p, const void *_q) static int glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) { - Char pathbuf[MAXPATHLEN]; + Char pathbuf[PATH_MAX]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return(0); - return(glob2(pathbuf, pathbuf+MAXPATHLEN-1, - pathbuf, pathbuf+MAXPATHLEN-1, + return(glob2(pathbuf, pathbuf+PATH_MAX-1, + pathbuf, pathbuf+PATH_MAX-1, pattern, pattern_last, pglob, limitp)); } @@ -638,8 +643,6 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, for (anymeta = 0;;) { if (*pattern == EOS) { /* End of pattern? */ *pathend = EOS; - if (g_lstat(pathbuf, &sb, pglob)) - return(0); if ((pglob->gl_flags & GLOB_LIMIT) && limitp->glim_stat++ >= GLOB_LIMIT_STAT) { @@ -648,6 +651,8 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, *pathend = EOS; return(GLOB_NOSPACE); } + if (g_lstat(pathbuf, &sb, pglob)) + return(0); if (((pglob->gl_flags & GLOB_MARK) && pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || @@ -699,7 +704,7 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, struct dirent *dp; DIR *dirp; int err; - char buf[MAXPATHLEN]; + char buf[PATH_MAX]; /* * The readdirfunc declaration can't be prototyped, because it is @@ -759,7 +764,7 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, break; } - if (!match(pathend, pattern, restpattern, GLOB_LIMIT_RECUR)) { + if (!match(pathend, pattern, restpattern)) { *pathend = EOS; continue; } @@ -796,56 +801,51 @@ globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp, struct stat *sb) { char **pathv; - ssize_t i; - size_t newn, len; + size_t i, newn, len; char *copy = NULL; const Char *p; struct stat **statv; newn = 2 + pglob->gl_pathc + pglob->gl_offs; - if (pglob->gl_offs >= INT_MAX || - pglob->gl_pathc >= INT_MAX || - newn >= INT_MAX || + if (pglob->gl_offs >= SSIZE_MAX || + pglob->gl_pathc >= SSIZE_MAX || + newn >= SSIZE_MAX || SIZE_MAX / sizeof(*pathv) <= newn || SIZE_MAX / sizeof(*statv) <= newn) { nospace: - for (i = pglob->gl_offs; i < (ssize_t)(newn - 2); i++) { + for (i = pglob->gl_offs; i < newn - 2; i++) { if (pglob->gl_pathv && pglob->gl_pathv[i]) free(pglob->gl_pathv[i]); if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0 && pglob->gl_pathv && pglob->gl_pathv[i]) free(pglob->gl_statv[i]); } - if (pglob->gl_pathv) { - free(pglob->gl_pathv); - pglob->gl_pathv = NULL; - } - if (pglob->gl_statv) { - free(pglob->gl_statv); - pglob->gl_statv = NULL; - } + free(pglob->gl_pathv); + pglob->gl_pathv = NULL; + free(pglob->gl_statv); + pglob->gl_statv = NULL; return(GLOB_NOSPACE); } - pathv = realloc(pglob->gl_pathv, newn * sizeof(*pathv)); + pathv = reallocarray(pglob->gl_pathv, newn, sizeof(*pathv)); if (pathv == NULL) goto nospace; if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { /* first time around -- clear initial gl_offs items */ pathv += pglob->gl_offs; - for (i = pglob->gl_offs; --i >= 0; ) + for (i = pglob->gl_offs; i > 0; i--) *--pathv = NULL; } pglob->gl_pathv = pathv; if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0) { - statv = realloc(pglob->gl_statv, newn * sizeof(*statv)); + statv = reallocarray(pglob->gl_statv, newn, sizeof(*statv)); if (statv == NULL) goto nospace; if (pglob->gl_statv == NULL && pglob->gl_offs > 0) { /* first time around -- clear initial gl_offs items */ statv += pglob->gl_offs; - for (i = pglob->gl_offs; --i >= 0; ) + for (i = pglob->gl_offs; i > 0; i--) *--statv = NULL; } pglob->gl_statv = statv; @@ -893,17 +893,24 @@ globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp, /* * pattern matching function for filenames. Each occurrence of the * - * pattern causes a recursion level. + * pattern causes an iteration. + * + * Note, this function differs from the original as per the discussion + * here: https://research.swtch.com/glob + * + * Basically we removed the recursion and made it use the algorithm + * from Russ Cox to not go quadratic on cases like a file called + * ("a" x 100) . "x" matched against a pattern like "a*a*a*a*a*a*a*y". */ static int -match(Char *name, Char *pat, Char *patend, int recur) +match(Char *name, Char *pat, Char *patend) { int ok, negate_range; Char c, k; + Char *nextp = NULL; + Char *nextn = NULL; - if (recur-- == 0) - return(GLOB_NOSPACE); - +loop: while (pat < patend) { c = *pat++; switch (c & M_MASK) { @@ -912,19 +919,19 @@ match(Char *name, Char *pat, Char *patend, int recur) pat++; /* eat consecutive '*' */ if (pat == patend) return(1); - do { - if (match(name, pat, patend, recur)) - return(1); - } while (*name++ != EOS); - return(0); + if (*name == EOS) + return(0); + nextn = name + 1; + nextp = pat - 1; + break; case M_ONE: if (*name++ == EOS) - return(0); + goto fail; break; case M_SET: ok = 0; if ((k = *name++) == EOS) - return(0); + goto fail; if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) ++pat; while (((c = *pat++) & M_MASK) != M_END) { @@ -943,36 +950,43 @@ match(Char *name, Char *pat, Char *patend, int recur) ok = 1; } if (ok == negate_range) - return(0); + goto fail; break; default: if (*name++ != c) - return(0); + goto fail; break; } } - return(*name == EOS); + if (*name == EOS) + return(1); + +fail: + if (nextn) { + pat = nextp; + name = nextn; + goto loop; + } + return(0); } /* Free allocated data belonging to a glob_t structure. */ void globfree(glob_t *pglob) { - int i; + size_t i; char **pp; if (pglob->gl_pathv != NULL) { pp = pglob->gl_pathv + pglob->gl_offs; for (i = pglob->gl_pathc; i--; ++pp) - if (*pp) - free(*pp); + free(*pp); free(pglob->gl_pathv); pglob->gl_pathv = NULL; } if (pglob->gl_statv != NULL) { for (i = 0; i < pglob->gl_pathc; i++) { - if (pglob->gl_statv[i] != NULL) - free(pglob->gl_statv[i]); + free(pglob->gl_statv[i]); } free(pglob->gl_statv); pglob->gl_statv = NULL; @@ -982,7 +996,7 @@ globfree(glob_t *pglob) static DIR * g_opendir(Char *str, glob_t *pglob) { - char buf[MAXPATHLEN]; + char buf[PATH_MAX]; if (!*str) strlcpy(buf, ".", sizeof buf); @@ -1000,7 +1014,7 @@ g_opendir(Char *str, glob_t *pglob) static int g_lstat(Char *fn, struct stat *sb, glob_t *pglob) { - char buf[MAXPATHLEN]; + char buf[PATH_MAX]; if (g_Ctoc(fn, buf, sizeof(buf))) return(-1); @@ -1012,7 +1026,7 @@ g_lstat(Char *fn, struct stat *sb, glob_t *pglob) static int g_stat(Char *fn, struct stat *sb, glob_t *pglob) { - char buf[MAXPATHLEN]; + char buf[PATH_MAX]; if (g_Ctoc(fn, buf, sizeof(buf))) return(-1); @@ -1032,7 +1046,7 @@ g_strchr(const Char *str, int ch) } static int -g_Ctoc(const Char *str, char *buf, u_int len) +g_Ctoc(const Char *str, char *buf, size_t len) { while (len--) { diff --git a/openbsd-compat/glob.h b/openbsd-compat/glob.h index f8a7fa5f..1692d36c 100644 --- a/openbsd-compat/glob.h +++ b/openbsd-compat/glob.h @@ -1,4 +1,4 @@ -/* $OpenBSD: glob.h,v 1.11 2010/09/24 13:32:55 djm Exp $ */ +/* $OpenBSD: glob.h,v 1.14 2019/02/04 16:45:40 millert Exp $ */ /* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */ /* @@ -42,16 +42,21 @@ !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \ defined(BROKEN_GLOB) -#ifndef _GLOB_H_ -#define _GLOB_H_ +#ifndef _COMPAT_GLOB_H_ +#define _COMPAT_GLOB_H_ #include <sys/stat.h> +#include <sys/types.h> + +# define glob_t _ssh_compat_glob_t +# define glob(a, b, c, d) _ssh__compat_glob(a, b, c, d) +# define globfree(a) _ssh__compat_globfree(a) struct stat; typedef struct { - int gl_pathc; /* Count of total paths so far. */ - int gl_matchc; /* Count of paths matching pattern. */ - int gl_offs; /* Reserved at beginning of gl_pathv. */ + size_t gl_pathc; /* Count of total paths so far. */ + size_t gl_matchc; /* Count of paths matching pattern. */ + size_t gl_offs; /* Reserved at beginning of gl_pathv. */ int gl_flags; /* Copy of flags parameter to glob. */ char **gl_pathv; /* List of paths matching pattern. */ struct stat **gl_statv; /* Stat entries corresponding to gl_pathv */ diff --git a/openbsd-compat/inet_aton.c b/openbsd-compat/inet_aton.c index 130597e1..093a1720 100644 --- a/openbsd-compat/inet_aton.c +++ b/openbsd-compat/inet_aton.c @@ -3,7 +3,7 @@ /* * Copyright (c) 1983, 1990, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +15,7 @@ * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -29,14 +29,14 @@ * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -77,7 +77,7 @@ inet_addr(const char *cp) } #endif -/* +/* * Check whether "cp" is a valid ascii representation * of an Internet address and convert to a binary address. * Returns 1 if the address is valid, 0 if not. diff --git a/openbsd-compat/libressl-api-compat.c b/openbsd-compat/libressl-api-compat.c new file mode 100644 index 00000000..fdadd4e5 --- /dev/null +++ b/openbsd-compat/libressl-api-compat.c @@ -0,0 +1,642 @@ +/* $OpenBSD: dsa_lib.c,v 1.29 2018/04/14 07:09:21 tb Exp $ */ +/* $OpenBSD: rsa_lib.c,v 1.37 2018/04/14 07:09:21 tb Exp $ */ +/* $OpenBSD: evp_lib.c,v 1.17 2018/09/12 06:35:38 djm Exp $ */ +/* $OpenBSD: dh_lib.c,v 1.32 2018/05/02 15:48:38 tb Exp $ */ +/* $OpenBSD: p_lib.c,v 1.24 2018/05/30 15:40:50 tb Exp $ */ +/* $OpenBSD: digest.c,v 1.30 2018/04/14 07:09:21 tb Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* $OpenBSD: dsa_asn1.c,v 1.22 2018/06/14 17:03:19 jsing Exp $ */ +/* $OpenBSD: ecs_asn1.c,v 1.9 2018/03/17 15:24:44 tb Exp $ */ +/* $OpenBSD: digest.c,v 1.30 2018/04/14 07:09:21 tb Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* $OpenBSD: rsa_meth.c,v 1.2 2018/09/12 06:35:38 djm Exp $ */ +/* + * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifdef WITH_OPENSSL + +#include <sys/types.h> + +#include <stdlib.h> +#include <string.h> + +#include <openssl/err.h> +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/rsa.h> +#include <openssl/evp.h> +#ifdef OPENSSL_HAS_ECC +#include <openssl/ecdsa.h> +#endif +#include <openssl/dh.h> + +#ifndef HAVE_DSA_GET0_PQG +void +DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = d->p; + if (q != NULL) + *q = d->q; + if (g != NULL) + *g = d->g; +} +#endif /* HAVE_DSA_GET0_PQG */ + +#ifndef HAVE_DSA_SET0_PQG +int +DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + if ((d->p == NULL && p == NULL) || (d->q == NULL && q == NULL) || + (d->g == NULL && g == NULL)) + return 0; + + if (p != NULL) { + BN_free(d->p); + d->p = p; + } + if (q != NULL) { + BN_free(d->q); + d->q = q; + } + if (g != NULL) { + BN_free(d->g); + d->g = g; + } + + return 1; +} +#endif /* HAVE_DSA_SET0_PQG */ + +#ifndef HAVE_DSA_GET0_KEY +void +DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = d->pub_key; + if (priv_key != NULL) + *priv_key = d->priv_key; +} +#endif /* HAVE_DSA_GET0_KEY */ + +#ifndef HAVE_DSA_SET0_KEY +int +DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) +{ + if (d->pub_key == NULL && pub_key == NULL) + return 0; + + if (pub_key != NULL) { + BN_free(d->pub_key); + d->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(d->priv_key); + d->priv_key = priv_key; + } + + return 1; +} +#endif /* HAVE_DSA_SET0_KEY */ + +#ifndef HAVE_RSA_GET0_KEY +void +RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +{ + if (n != NULL) + *n = r->n; + if (e != NULL) + *e = r->e; + if (d != NULL) + *d = r->d; +} +#endif /* HAVE_RSA_GET0_KEY */ + +#ifndef HAVE_RSA_SET0_KEY +int +RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) +{ + if ((r->n == NULL && n == NULL) || (r->e == NULL && e == NULL)) + return 0; + + if (n != NULL) { + BN_free(r->n); + r->n = n; + } + if (e != NULL) { + BN_free(r->e); + r->e = e; + } + if (d != NULL) { + BN_free(r->d); + r->d = d; + } + + return 1; +} +#endif /* HAVE_RSA_SET0_KEY */ + +#ifndef HAVE_RSA_GET0_CRT_PARAMS +void +RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, + const BIGNUM **iqmp) +{ + if (dmp1 != NULL) + *dmp1 = r->dmp1; + if (dmq1 != NULL) + *dmq1 = r->dmq1; + if (iqmp != NULL) + *iqmp = r->iqmp; +} +#endif /* HAVE_RSA_GET0_CRT_PARAMS */ + +#ifndef HAVE_RSA_SET0_CRT_PARAMS +int +RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) +{ + if ((r->dmp1 == NULL && dmp1 == NULL) || + (r->dmq1 == NULL && dmq1 == NULL) || + (r->iqmp == NULL && iqmp == NULL)) + return 0; + + if (dmp1 != NULL) { + BN_free(r->dmp1); + r->dmp1 = dmp1; + } + if (dmq1 != NULL) { + BN_free(r->dmq1); + r->dmq1 = dmq1; + } + if (iqmp != NULL) { + BN_free(r->iqmp); + r->iqmp = iqmp; + } + + return 1; +} +#endif /* HAVE_RSA_SET0_CRT_PARAMS */ + +#ifndef HAVE_RSA_GET0_FACTORS +void +RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) +{ + if (p != NULL) + *p = r->p; + if (q != NULL) + *q = r->q; +} +#endif /* HAVE_RSA_GET0_FACTORS */ + +#ifndef HAVE_RSA_SET0_FACTORS +int +RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) +{ + if ((r->p == NULL && p == NULL) || (r->q == NULL && q == NULL)) + return 0; + + if (p != NULL) { + BN_free(r->p); + r->p = p; + } + if (q != NULL) { + BN_free(r->q); + r->q = q; + } + + return 1; +} +#endif /* HAVE_RSA_SET0_FACTORS */ + +#ifndef HAVE_EVP_CIPHER_CTX_GET_IV +int +EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, unsigned char *iv, size_t len) +{ + if (ctx == NULL) + return 0; + if (EVP_CIPHER_CTX_iv_length(ctx) < 0) + return 0; + if (len != (size_t)EVP_CIPHER_CTX_iv_length(ctx)) + return 0; + if (len > EVP_MAX_IV_LENGTH) + return 0; /* sanity check; shouldn't happen */ + /* + * Skip the memcpy entirely when the requested IV length is zero, + * since the iv pointer may be NULL or invalid. + */ + if (len != 0) { + if (iv == NULL) + return 0; +# ifdef HAVE_EVP_CIPHER_CTX_IV + memcpy(iv, EVP_CIPHER_CTX_iv(ctx), len); +# else + memcpy(iv, ctx->iv, len); +# endif /* HAVE_EVP_CIPHER_CTX_IV */ + } + return 1; +} +#endif /* HAVE_EVP_CIPHER_CTX_GET_IV */ + +#ifndef HAVE_EVP_CIPHER_CTX_SET_IV +int +EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, const unsigned char *iv, size_t len) +{ + if (ctx == NULL) + return 0; + if (EVP_CIPHER_CTX_iv_length(ctx) < 0) + return 0; + if (len != (size_t)EVP_CIPHER_CTX_iv_length(ctx)) + return 0; + if (len > EVP_MAX_IV_LENGTH) + return 0; /* sanity check; shouldn't happen */ + /* + * Skip the memcpy entirely when the requested IV length is zero, + * since the iv pointer may be NULL or invalid. + */ + if (len != 0) { + if (iv == NULL) + return 0; +# ifdef HAVE_EVP_CIPHER_CTX_IV_NOCONST + memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, len); +# else + memcpy(ctx->iv, iv, len); +# endif /* HAVE_EVP_CIPHER_CTX_IV_NOCONST */ + } + return 1; +} +#endif /* HAVE_EVP_CIPHER_CTX_SET_IV */ + +#ifndef HAVE_DSA_SIG_GET0 +void +DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) + *pr = sig->r; + if (ps != NULL) + *ps = sig->s; +} +#endif /* HAVE_DSA_SIG_GET0 */ + +#ifndef HAVE_DSA_SIG_SET0 +int +DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return 0; + + BN_clear_free(sig->r); + sig->r = r; + BN_clear_free(sig->s); + sig->s = s; + + return 1; +} +#endif /* HAVE_DSA_SIG_SET0 */ + +#ifdef OPENSSL_HAS_ECC +#ifndef HAVE_ECDSA_SIG_GET0 +void +ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) + *pr = sig->r; + if (ps != NULL) + *ps = sig->s; +} +#endif /* HAVE_ECDSA_SIG_GET0 */ + +#ifndef HAVE_ECDSA_SIG_SET0 +int +ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return 0; + + BN_clear_free(sig->r); + BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} +#endif /* HAVE_ECDSA_SIG_SET0 */ +#endif /* OPENSSL_HAS_ECC */ + +#ifndef HAVE_DH_GET0_PQG +void +DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = dh->p; + if (q != NULL) + *q = dh->q; + if (g != NULL) + *g = dh->g; +} +#endif /* HAVE_DH_GET0_PQG */ + +#ifndef HAVE_DH_SET0_PQG +int +DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL)) + return 0; + + if (p != NULL) { + BN_free(dh->p); + dh->p = p; + } + if (q != NULL) { + BN_free(dh->q); + dh->q = q; + } + if (g != NULL) { + BN_free(dh->g); + dh->g = g; + } + + return 1; +} +#endif /* HAVE_DH_SET0_PQG */ + +#ifndef HAVE_DH_GET0_KEY +void +DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = dh->pub_key; + if (priv_key != NULL) + *priv_key = dh->priv_key; +} +#endif /* HAVE_DH_GET0_KEY */ + +#ifndef HAVE_DH_SET0_KEY +int +DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) +{ + if (pub_key != NULL) { + BN_free(dh->pub_key); + dh->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(dh->priv_key); + dh->priv_key = priv_key; + } + + return 1; +} +#endif /* HAVE_DH_SET0_KEY */ + +#ifndef HAVE_DH_SET_LENGTH +int +DH_set_length(DH *dh, long length) +{ + if (length < 0 || length > INT_MAX) + return 0; + +#if !defined(OPENSSL_IS_BORINGSSL) + dh->length = length; +#endif + return 1; +} +#endif /* HAVE_DH_SET_LENGTH */ + +#ifndef HAVE_RSA_METH_FREE +void +RSA_meth_free(RSA_METHOD *meth) +{ + if (meth != NULL) { + free((char *)meth->name); + free(meth); + } +} +#endif /* HAVE_RSA_METH_FREE */ + +#ifndef HAVE_RSA_METH_DUP +RSA_METHOD * +RSA_meth_dup(const RSA_METHOD *meth) +{ + RSA_METHOD *copy; + + if ((copy = calloc(1, sizeof(*copy))) == NULL) + return NULL; + memcpy(copy, meth, sizeof(*copy)); + if ((copy->name = strdup(meth->name)) == NULL) { + free(copy); + return NULL; + } + + return copy; +} +#endif /* HAVE_RSA_METH_DUP */ + +#ifndef HAVE_RSA_METH_SET1_NAME +int +RSA_meth_set1_name(RSA_METHOD *meth, const char *name) +{ + char *copy; + + if ((copy = strdup(name)) == NULL) + return 0; + free((char *)meth->name); + meth->name = copy; + return 1; +} +#endif /* HAVE_RSA_METH_SET1_NAME */ + +#ifndef HAVE_RSA_METH_GET_FINISH +int +(*RSA_meth_get_finish(const RSA_METHOD *meth))(RSA *rsa) +{ + return meth->finish; +} +#endif /* HAVE_RSA_METH_GET_FINISH */ + +#ifndef HAVE_RSA_METH_SET_PRIV_ENC +int +RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc)(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding)) +{ + meth->rsa_priv_enc = priv_enc; + return 1; +} +#endif /* HAVE_RSA_METH_SET_PRIV_ENC */ + +#ifndef HAVE_RSA_METH_SET_PRIV_DEC +int +RSA_meth_set_priv_dec(RSA_METHOD *meth, int (*priv_dec)(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding)) +{ + meth->rsa_priv_dec = priv_dec; + return 1; +} +#endif /* HAVE_RSA_METH_SET_PRIV_DEC */ + +#ifndef HAVE_RSA_METH_SET_FINISH +int +RSA_meth_set_finish(RSA_METHOD *meth, int (*finish)(RSA *rsa)) +{ + meth->finish = finish; + return 1; +} +#endif /* HAVE_RSA_METH_SET_FINISH */ + +#ifndef HAVE_EVP_PKEY_GET0_RSA +RSA * +EVP_PKEY_get0_RSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_RSA) { + /* EVPerror(EVP_R_EXPECTING_AN_RSA_KEY); */ + return NULL; + } + return pkey->pkey.rsa; +} +#endif /* HAVE_EVP_PKEY_GET0_RSA */ + +#ifndef HAVE_EVP_MD_CTX_NEW +EVP_MD_CTX * +EVP_MD_CTX_new(void) +{ + return calloc(1, sizeof(EVP_MD_CTX)); +} +#endif /* HAVE_EVP_MD_CTX_NEW */ + +#ifndef HAVE_EVP_MD_CTX_FREE +void +EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + if (ctx == NULL) + return; + + EVP_MD_CTX_cleanup(ctx); + + free(ctx); +} +#endif /* HAVE_EVP_MD_CTX_FREE */ + +#endif /* WITH_OPENSSL */ diff --git a/openbsd-compat/memmem.c b/openbsd-compat/memmem.c new file mode 100644 index 00000000..3e5e6b5e --- /dev/null +++ b/openbsd-compat/memmem.c @@ -0,0 +1,69 @@ +/* $OpenBSD: memmem.c,v 1.4 2015/08/31 02:53:57 guenther Exp $ */ +/*- + * Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" + +#ifndef HAVE_MEMMEM + +#include <string.h> + +/* + * Find the first occurrence of the byte string s in byte string l. + */ + +void * +memmem(const void *l, size_t l_len, const void *s, size_t s_len) +{ + const char *cur, *last; + const char *cl = l; + const char *cs = s; + + /* a zero length needle should just return the haystack */ + if (s_len == 0) + return (void *)cl; + + /* "s" must be smaller or equal to "l" */ + if (l_len < s_len) + return NULL; + + /* special case where s_len == 1 */ + if (s_len == 1) + return memchr(l, *cs, l_len); + + /* the last position where its possible to find "s" in "l" */ + last = cl + l_len - s_len; + + for (cur = cl; cur <= last; cur++) + if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) + return (void *)cur; + + return NULL; +} +DEF_WEAK(memmem); +#endif /* HAVE_MEMMEM */ diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index 1cffefe0..e5fd6f5b 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -1,5 +1,3 @@ -/* $Id: openbsd-compat.h,v 1.62 2014/09/30 23:43:08 djm Exp $ */ - /* * Copyright (c) 1999-2003 Damien Miller. All rights reserved. * Copyright (c) 2003 Ben Lindstrom. All rights reserved. @@ -36,18 +34,19 @@ #include <sys/socket.h> +#include <stddef.h> /* for wchar_t */ + /* OpenBSD function replacements */ #include "base64.h" #include "sigact.h" -#include "glob.h" #include "readpassphrase.h" #include "vis.h" #include "getrrsetbyname.h" #include "sha1.h" #include "sha2.h" -#include "rmd160.h" #include "md5.h" #include "blf.h" +#include "fnmatch.h" #ifndef HAVE_BASENAME char *basename(const char *path); @@ -61,31 +60,54 @@ int bindresvport_sa(int sd, struct sockaddr *sa); void closefrom(int); #endif +#ifndef HAVE_GETLINE +#include <stdio.h> +ssize_t getline(char **, size_t *, FILE *); +#endif + +#ifndef HAVE_GETPAGESIZE +int getpagesize(void); +#endif + #ifndef HAVE_GETCWD char *getcwd(char *pt, size_t size); -#endif +#endif + +#if defined(HAVE_DECL_MEMMEM) && HAVE_DECL_MEMMEM == 0 +void *memmem(const void *, size_t, const void *, size_t); +#endif #ifndef HAVE_REALLOCARRAY void *reallocarray(void *, size_t, size_t); #endif -#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) -char *realpath(const char *path, char *resolved); -#endif +#ifndef HAVE_RECALLOCARRAY +void *recallocarray(void *, size_t, size_t, size_t); +#endif #ifndef HAVE_RRESVPORT_AF int rresvport_af(int *alport, sa_family_t af); #endif #ifndef HAVE_STRLCPY -/* #include <sys/types.h> XXX Still needed? */ size_t strlcpy(char *dst, const char *src, size_t siz); #endif #ifndef HAVE_STRLCAT -/* #include <sys/types.h> XXX Still needed? */ size_t strlcat(char *dst, const char *src, size_t siz); -#endif +#endif + +#ifndef HAVE_STRCASESTR +char *strcasestr(const char *, const char *); +#endif + +#ifndef HAVE_STRNLEN +size_t strnlen(const char *, size_t); +#endif + +#ifndef HAVE_STRNDUP +char *strndup(const char *s, size_t n); +#endif #ifndef HAVE_SETENV int setenv(register const char *name, register const char *value, int rewrite); @@ -104,11 +126,11 @@ char *strptime(const char *buf, const char *fmt, struct tm *tm); int mkstemps(char *path, int slen); int mkstemp(char *path); char *mkdtemp(char *path); -#endif +#endif #ifndef HAVE_DAEMON int daemon(int nochdir, int noclose); -#endif +#endif #ifndef HAVE_DIRNAME char *dirname(const char *path); @@ -133,7 +155,7 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); #ifndef HAVE_INET_ATON int inet_aton(const char *cp, struct in_addr *addr); -#endif +#endif #ifndef HAVE_STRSEP char *strsep(char **stringp, const char *delim); @@ -145,7 +167,6 @@ void compat_init_setproctitle(int argc, char *argv[]); #endif #ifndef HAVE_GETGROUPLIST -/* #include <grp.h> XXXX Still needed ? */ int getgrouplist(const char *, gid_t, gid_t *, int *); #endif @@ -154,20 +175,29 @@ int BSDgetopt(int argc, char * const *argv, const char *opts); #include "openbsd-compat/getopt.h" #endif -#if defined(HAVE_DECL_WRITEV) && HAVE_DECL_WRITEV == 0 +#if ((defined(HAVE_DECL_READV) && HAVE_DECL_READV == 0) || \ + (defined(HAVE_DECL_WRITEV) && HAVE_DECL_WRITEV == 0)) # include <sys/types.h> # include <sys/uio.h> + +# if defined(HAVE_DECL_READV) && HAVE_DECL_READV == 0 +int readv(int, struct iovec *, int); +# endif + +# if defined(HAVE_DECL_WRITEV) && HAVE_DECL_WRITEV == 0 int writev(int, struct iovec *, int); +# endif #endif /* Home grown routines */ #include "bsd-misc.h" #include "bsd-setres_id.h" +#include "bsd-signal.h" #include "bsd-statvfs.h" #include "bsd-waitpid.h" #include "bsd-poll.h" -#ifndef HAVE_GETPEEREID +#if defined(HAVE_DECL_GETPEEREID) && HAVE_DECL_GETPEEREID == 0 int getpeereid(int , uid_t *, gid_t *); #endif @@ -190,18 +220,16 @@ u_int32_t arc4random_uniform(u_int32_t); #ifndef HAVE_ASPRINTF int asprintf(char **, const char *, ...); -#endif +#endif #ifndef HAVE_OPENPTY # include <sys/ioctl.h> /* for struct winsize */ int openpty(int *, int *, char *, struct termios *, struct winsize *); #endif /* HAVE_OPENPTY */ -/* #include <sys/types.h> XXX needed? For size_t */ - #ifndef HAVE_SNPRINTF int snprintf(char *, size_t, SNPRINTF_CONST char *, ...); -#endif +#endif #ifndef HAVE_STRTOLL long long strtoll(const char *, char **, int); @@ -221,13 +249,46 @@ long long strtonum(const char *, long long, long long, const char **); /* multibyte character support */ #ifndef HAVE_MBLEN -# define mblen(x, y) 1 +# define mblen(x, y) (1) +#endif + +#ifndef HAVE_WCWIDTH +# define wcwidth(x) (((x) >= 0x20 && (x) <= 0x7e) ? 1 : -1) +/* force our no-op nl_langinfo and mbtowc */ +# undef HAVE_NL_LANGINFO +# undef HAVE_MBTOWC +# undef HAVE_LANGINFO_H +#endif + +#ifndef HAVE_NL_LANGINFO +# define nl_langinfo(x) "" +#endif + +#ifndef HAVE_MBTOWC +int mbtowc(wchar_t *, const char*, size_t); #endif #if !defined(HAVE_VASPRINTF) || !defined(HAVE_VSNPRINTF) # include <stdarg.h> #endif +/* + * Some platforms unconditionally undefine va_copy() so we define VA_COPY() + * instead. This is known to be the case on at least some configurations of + * AIX with the xlc compiler. + */ +#ifndef VA_COPY +# ifdef HAVE_VA_COPY +# define VA_COPY(dest, src) va_copy(dest, src) +# else +# ifdef HAVE___VA_COPY +# define VA_COPY(dest, src) __va_copy(dest, src) +# else +# define VA_COPY(dest, src) (dest) = (src) +# endif +# endif +#endif + #ifndef HAVE_VASPRINTF int vasprintf(char **, const char *, va_list); #endif @@ -257,7 +318,14 @@ int bcrypt_pbkdf(const char *, size_t, const u_int8_t *, size_t, void explicit_bzero(void *p, size_t n); #endif -void *xmmap(size_t size); +#ifndef HAVE_FREEZERO +void freezero(void *, size_t); +#endif + +#ifndef HAVE_LOCALTIME_R +struct tm *localtime_r(const time_t *, struct tm *); +#endif + char *xcrypt(const char *password, const char *salt); char *shadow_pw(struct passwd *pw); @@ -265,14 +333,13 @@ char *shadow_pw(struct passwd *pw); #include "fake-rfc2553.h" /* Routines for a single OS platform */ -#include "bsd-cray.h" #include "bsd-cygwin_util.h" #include "port-aix.h" #include "port-irix.h" #include "port-linux.h" #include "port-solaris.h" -#include "port-tun.h" +#include "port-net.h" #include "port-uw.h" /* _FORTIFY_SOURCE breaks FD_ISSET(n)/FD_SET(n) for n > FD_SETSIZE. Avoid. */ diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index 63a660c7..a37ca61b 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -1,5 +1,3 @@ -/* $Id: openssl-compat.c,v 1.19 2014/07/02 05:28:07 djm Exp $ */ - /* * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au> * @@ -55,7 +53,7 @@ ssh_compatible_openssl(long headerver, long libver) mask = 0xfffff00fL; /* major,minor,fix,status */ return (headerver & mask) == (libver & mask); } - + /* * For versions >= 1.0.0, major,minor,status must match and library * fix version must be equal to or newer than the header. @@ -68,17 +66,31 @@ ssh_compatible_openssl(long headerver, long libver) return 0; } -#ifdef USE_OPENSSL_ENGINE void -ssh_OpenSSL_add_all_algorithms(void) +ssh_libcrypto_init(void) { +#if defined(HAVE_OPENSSL_INIT_CRYPTO) && \ + defined(OPENSSL_INIT_ADD_ALL_CIPHERS) && \ + defined(OPENSSL_INIT_ADD_ALL_DIGESTS) + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | + OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); +#elif defined(HAVE_OPENSSL_ADD_ALL_ALGORITHMS) OpenSSL_add_all_algorithms(); +#endif +#ifdef USE_OPENSSL_ENGINE /* Enable use of crypto hardware */ ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); + + /* Load the libcrypto config file to pick up engines defined there */ +# if defined(HAVE_OPENSSL_INIT_CRYPTO) && defined(OPENSSL_INIT_LOAD_CONFIG) + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | + OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL); +# else OPENSSL_config(NULL); +# endif +#endif /* USE_OPENSSL_ENGINE */ } -#endif #endif /* WITH_OPENSSL */ diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index 8917551d..388ae8aa 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -1,5 +1,3 @@ -/* $Id: openssl-compat.h,v 1.31 2014/08/29 18:18:29 djm Exp $ */ - /* * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au> * @@ -23,14 +21,32 @@ #ifdef WITH_OPENSSL #include <openssl/opensslv.h> +#include <openssl/crypto.h> #include <openssl/evp.h> #include <openssl/rsa.h> #include <openssl/dsa.h> +#ifdef OPENSSL_HAS_ECC +#include <openssl/ecdsa.h> +#endif +#include <openssl/dh.h> int ssh_compatible_openssl(long, long); +void ssh_libcrypto_init(void); -#if (OPENSSL_VERSION_NUMBER <= 0x0090805fL) -# error OpenSSL 0.9.8f or greater is required +#if (OPENSSL_VERSION_NUMBER < 0x1000100fL) +# error OpenSSL 1.0.1 or greater is required +#endif + +#ifndef OPENSSL_VERSION +# define OPENSSL_VERSION SSLEAY_VERSION +#endif + +#ifndef HAVE_OPENSSL_VERSION +# define OpenSSL_version(x) SSLeay_version(x) +#endif + +#ifndef HAVE_OPENSSL_VERSION_NUM +# define OpenSSL_version_num SSLeay #endif #if OPENSSL_VERSION_NUMBER < 0x10000001L @@ -46,6 +62,12 @@ int ssh_compatible_openssl(long, long); # define OPENSSL_DSA_MAX_MODULUS_BITS 10000 #endif +#ifdef LIBRESSL_VERSION_NUMBER +# if LIBRESSL_VERSION_NUMBER < 0x3010000fL +# define HAVE_BROKEN_CHACHA20 +# endif +#endif + #ifndef OPENSSL_HAVE_EVPCTR # define EVP_aes_128_ctr evp_aes_128_ctr # define EVP_aes_192_ctr evp_aes_128_ctr @@ -71,26 +93,141 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t); # endif #endif -/* - * We overload some of the OpenSSL crypto functions with ssh_* equivalents - * to automatically handle OpenSSL engine initialisation. - * - * In order for the compat library to call the real functions, it must - * define SSH_DONT_OVERLOAD_OPENSSL_FUNCS before including this file and - * implement the ssh_* equivalents. - */ -#ifndef SSH_DONT_OVERLOAD_OPENSSL_FUNCS - -# ifdef USE_OPENSSL_ENGINE -# ifdef OpenSSL_add_all_algorithms -# undef OpenSSL_add_all_algorithms -# endif -# define OpenSSL_add_all_algorithms() ssh_OpenSSL_add_all_algorithms() -# endif - -void ssh_OpenSSL_add_all_algorithms(void); - -#endif /* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */ +/* LibreSSL/OpenSSL 1.1x API compat */ +#ifndef HAVE_DSA_GET0_PQG +void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, + const BIGNUM **g); +#endif /* HAVE_DSA_GET0_PQG */ + +#ifndef HAVE_DSA_SET0_PQG +int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g); +#endif /* HAVE_DSA_SET0_PQG */ + +#ifndef HAVE_DSA_GET0_KEY +void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, + const BIGNUM **priv_key); +#endif /* HAVE_DSA_GET0_KEY */ + +#ifndef HAVE_DSA_SET0_KEY +int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key); +#endif /* HAVE_DSA_SET0_KEY */ + +#ifndef HAVE_EVP_CIPHER_CTX_GET_IV +int EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, + unsigned char *iv, size_t len); +#endif /* HAVE_EVP_CIPHER_CTX_GET_IV */ + +#ifndef HAVE_EVP_CIPHER_CTX_SET_IV +int EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, + const unsigned char *iv, size_t len); +#endif /* HAVE_EVP_CIPHER_CTX_SET_IV */ + +#ifndef HAVE_RSA_GET0_KEY +void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, + const BIGNUM **d); +#endif /* HAVE_RSA_GET0_KEY */ + +#ifndef HAVE_RSA_SET0_KEY +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); +#endif /* HAVE_RSA_SET0_KEY */ + +#ifndef HAVE_RSA_GET0_CRT_PARAMS +void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, + const BIGNUM **iqmp); +#endif /* HAVE_RSA_GET0_CRT_PARAMS */ + +#ifndef HAVE_RSA_SET0_CRT_PARAMS +int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); +#endif /* HAVE_RSA_SET0_CRT_PARAMS */ + +#ifndef HAVE_RSA_GET0_FACTORS +void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); +#endif /* HAVE_RSA_GET0_FACTORS */ + +#ifndef HAVE_RSA_SET0_FACTORS +int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); +#endif /* HAVE_RSA_SET0_FACTORS */ + +#ifndef DSA_SIG_GET0 +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); +#endif /* DSA_SIG_GET0 */ + +#ifndef DSA_SIG_SET0 +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); +#endif /* DSA_SIG_SET0 */ + +#ifdef OPENSSL_HAS_ECC +#ifndef HAVE_ECDSA_SIG_GET0 +void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); +#endif /* HAVE_ECDSA_SIG_GET0 */ + +#ifndef HAVE_ECDSA_SIG_SET0 +int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); +#endif /* HAVE_ECDSA_SIG_SET0 */ +#endif /* OPENSSL_HAS_ECC */ + +#ifndef HAVE_DH_GET0_PQG +void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, + const BIGNUM **g); +#endif /* HAVE_DH_GET0_PQG */ + +#ifndef HAVE_DH_SET0_PQG +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); +#endif /* HAVE_DH_SET0_PQG */ + +#ifndef HAVE_DH_GET0_KEY +void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key); +#endif /* HAVE_DH_GET0_KEY */ + +#ifndef HAVE_DH_SET0_KEY +int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); +#endif /* HAVE_DH_SET0_KEY */ + +#ifndef HAVE_DH_SET_LENGTH +int DH_set_length(DH *dh, long length); +#endif /* HAVE_DH_SET_LENGTH */ + +#ifndef HAVE_RSA_METH_FREE +void RSA_meth_free(RSA_METHOD *meth); +#endif /* HAVE_RSA_METH_FREE */ + +#ifndef HAVE_RSA_METH_DUP +RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth); +#endif /* HAVE_RSA_METH_DUP */ + +#ifndef HAVE_RSA_METH_SET1_NAME +int RSA_meth_set1_name(RSA_METHOD *meth, const char *name); +#endif /* HAVE_RSA_METH_SET1_NAME */ + +#ifndef HAVE_RSA_METH_GET_FINISH +int (*RSA_meth_get_finish(const RSA_METHOD *meth))(RSA *rsa); +#endif /* HAVE_RSA_METH_GET_FINISH */ + +#ifndef HAVE_RSA_METH_SET_PRIV_ENC +int RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc)(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding)); +#endif /* HAVE_RSA_METH_SET_PRIV_ENC */ + +#ifndef HAVE_RSA_METH_SET_PRIV_DEC +int RSA_meth_set_priv_dec(RSA_METHOD *meth, int (*priv_dec)(int flen, + const unsigned char *from, unsigned char *to, RSA *rsa, int padding)); +#endif /* HAVE_RSA_METH_SET_PRIV_DEC */ + +#ifndef HAVE_RSA_METH_SET_FINISH +int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish)(RSA *rsa)); +#endif /* HAVE_RSA_METH_SET_FINISH */ + +#ifndef HAVE_EVP_PKEY_GET0_RSA +RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); +#endif /* HAVE_EVP_PKEY_GET0_RSA */ + +#ifndef HAVE_EVP_MD_CTX_new +EVP_MD_CTX *EVP_MD_CTX_new(void); +#endif /* HAVE_EVP_MD_CTX_new */ + +#ifndef HAVE_EVP_MD_CTX_free +void EVP_MD_CTX_free(EVP_MD_CTX *ctx); +#endif /* HAVE_EVP_MD_CTX_free */ #endif /* WITH_OPENSSL */ #endif /* _OPENSSL_COMPAT_H */ diff --git a/openbsd-compat/port-aix.c b/openbsd-compat/port-aix.c index 8da367d4..e0d3eba5 100644 --- a/openbsd-compat/port-aix.c +++ b/openbsd-compat/port-aix.c @@ -26,16 +26,18 @@ */ #include "includes.h" +#ifdef _AIX + #include "xmalloc.h" -#include "buffer.h" -#include "key.h" +#include "sshbuf.h" +#include "ssherr.h" +#include "sshkey.h" #include "hostfile.h" #include "auth.h" #include "ssh.h" +#include "ssh_api.h" #include "log.h" -#ifdef _AIX - #include <errno.h> #if defined(HAVE_NETDB_H) # include <netdb.h> @@ -171,15 +173,16 @@ aix_valid_authentications(const char *user) * returns 0. */ int -sys_auth_passwd(Authctxt *ctxt, const char *password) +sys_auth_passwd(struct ssh *ssh, const char *password) { + Authctxt *ctxt = ssh->authctxt; char *authmsg = NULL, *msg = NULL, *name = ctxt->pw->pw_name; - int authsuccess = 0, expired, reenter, result; + int r, authsuccess = 0, expired, reenter, result; do { result = authenticate((char *)name, (char *)password, &reenter, &authmsg); - aix_remove_embedded_newlines(authmsg); + aix_remove_embedded_newlines(authmsg); debug3("AIX/authenticate result %d, authmsg %.100s", result, authmsg); } while (reenter); @@ -201,7 +204,10 @@ sys_auth_passwd(Authctxt *ctxt, const char *password) */ expired = passwdexpired(name, &msg); if (msg && *msg) { - buffer_append(ctxt->loginmsg, msg, strlen(msg)); + if ((r = sshbuf_put(ctxt->loginmsg, + msg, strlen(msg))) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); aix_remove_embedded_newlines(msg); } debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg); @@ -232,10 +238,10 @@ sys_auth_passwd(Authctxt *ctxt, const char *password) * Returns 1 if login is allowed, 0 if not allowed. */ int -sys_auth_allowed_user(struct passwd *pw, Buffer *loginmsg) +sys_auth_allowed_user(struct passwd *pw, struct sshbuf *loginmsg) { char *msg = NULL; - int result, permitted = 0; + int r, result, permitted = 0; struct stat st; /* @@ -258,8 +264,10 @@ sys_auth_allowed_user(struct passwd *pw, Buffer *loginmsg) */ if (result == -1 && errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0) permitted = 1; - else if (msg != NULL) - buffer_append(loginmsg, msg, strlen(msg)); + else if (msg != NULL) { + if ((r = sshbuf_put(loginmsg, msg, strlen(msg))) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + } if (msg == NULL) msg = xstrdup("(none)"); aix_remove_embedded_newlines(msg); @@ -273,7 +281,7 @@ sys_auth_allowed_user(struct passwd *pw, Buffer *loginmsg) int sys_auth_record_login(const char *user, const char *host, const char *ttynm, - Buffer *loginmsg) + struct sshbuf *loginmsg) { char *msg = NULL; int success = 0; @@ -305,7 +313,8 @@ sys_auth_get_lastlogin_msg(const char *user, uid_t uid) * record_failed_login: generic "login failed" interface function */ void -record_failed_login(const char *user, const char *hostname, const char *ttyname) +record_failed_login(struct ssh *ssh, const char *user, const char *hostname, + const char *ttyname) { if (geteuid() != 0) return; @@ -337,11 +346,11 @@ aix_setauthdb(const char *user) debug3("%s: Could not open userdb to read", __func__); return; } - + if (getuserattr((char *)user, S_REGISTRY, ®istry, SEC_CHAR) == 0) { if (setauthdb(registry, old_registry) == 0) debug3("AIX/setauthdb set registry '%s'", registry); - else + else debug3("AIX/setauthdb set registry '%s' failed: %s", registry, strerror(errno)); } else @@ -374,12 +383,13 @@ aix_restoreauthdb(void) # ifdef USE_AIX_KRB_NAME /* - * aix_krb5_get_principal_name: returns the user's kerberos client principal name if - * configured, otherwise NULL. Caller must free returned string. + * aix_krb5_get_principal_name: returns the user's kerberos client principal + * name if configured, otherwise NULL. Caller must free returned string. */ char * -aix_krb5_get_principal_name(char *pw_name) +aix_krb5_get_principal_name(const char *const_pw_name) { + char *pw_name = (char *)const_pw_name; char *authname = NULL, *authdomain = NULL, *principal = NULL; setuserdb(S_READ); @@ -389,7 +399,8 @@ aix_krb5_get_principal_name(char *pw_name) debug("AIX getuserattr S_AUTHNAME: %s", strerror(errno)); if (authdomain != NULL) - xasprintf(&principal, "%s@%s", authname ? authname : pw_name, authdomain); + xasprintf(&principal, "%s@%s", authname ? authname : pw_name, + authdomain); else if (authname != NULL) principal = xstrdup(authname); enduserdb(); diff --git a/openbsd-compat/port-aix.h b/openbsd-compat/port-aix.h index 53e4e88a..0ee36614 100644 --- a/openbsd-compat/port-aix.h +++ b/openbsd-compat/port-aix.h @@ -1,5 +1,3 @@ -/* $Id: port-aix.h,v 1.32 2009/12/20 23:49:22 dtucker Exp $ */ - /* * * Copyright (c) 2001 Gert Doering. All rights reserved. @@ -32,7 +30,8 @@ # include <sys/socket.h> #endif -#include "buffer.h" +struct ssh; +struct sshbuf; /* These should be in the system headers but are not. */ int usrinfo(int, char *, int); @@ -89,15 +88,16 @@ void aix_usrinfo(struct passwd *); #ifdef WITH_AIXAUTHENTICATE # define CUSTOM_SYS_AUTH_PASSWD 1 # define CUSTOM_SYS_AUTH_ALLOWED_USER 1 -int sys_auth_allowed_user(struct passwd *, Buffer *); +int sys_auth_allowed_user(struct passwd *, struct sshbuf *); # define CUSTOM_SYS_AUTH_RECORD_LOGIN 1 -int sys_auth_record_login(const char *, const char *, const char *, Buffer *); +int sys_auth_record_login(const char *, const char *, const char *, + struct sshbuf *); # define CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG char *sys_auth_get_lastlogin_msg(const char *, uid_t); # define CUSTOM_FAILED_LOGIN 1 # if defined(S_AUTHDOMAIN) && defined (S_AUTHNAME) # define USE_AIX_KRB_NAME -char *aix_krb5_get_principal_name(char *); +char *aix_krb5_get_principal_name(const char *); # endif #endif diff --git a/openbsd-compat/port-irix.c b/openbsd-compat/port-irix.c index ba751a53..aebffb01 100644 --- a/openbsd-compat/port-irix.c +++ b/openbsd-compat/port-irix.c @@ -43,46 +43,48 @@ # include <sat.h> #endif /* WITH_IRIX_AUDIT */ +#include "log.h" + void irix_setusercontext(struct passwd *pw) { #ifdef WITH_IRIX_PROJECT - prid_t projid; + prid_t projid; #endif #ifdef WITH_IRIX_JOBS - jid_t jid = 0; + jid_t jid = 0; #elif defined(WITH_IRIX_ARRAY) - int jid = 0; + int jid = 0; #endif #ifdef WITH_IRIX_JOBS - jid = jlimit_startjob(pw->pw_name, pw->pw_uid, "interactive"); - if (jid == -1) - fatal("Failed to create job container: %.100s", - strerror(errno)); + jid = jlimit_startjob(pw->pw_name, pw->pw_uid, "interactive"); + if (jid == -1) + fatal("Failed to create job container: %.100s", + strerror(errno)); #endif /* WITH_IRIX_JOBS */ #ifdef WITH_IRIX_ARRAY - /* initialize array session */ - if (jid == 0 && newarraysess() != 0) - fatal("Failed to set up new array session: %.100s", - strerror(errno)); + /* initialize array session */ + if (jid == 0 && newarraysess() != 0) + fatal("Failed to set up new array session: %.100s", + strerror(errno)); #endif /* WITH_IRIX_ARRAY */ #ifdef WITH_IRIX_PROJECT - /* initialize irix project info */ - if ((projid = getdfltprojuser(pw->pw_name)) == -1) { - debug("Failed to get project id, using projid 0"); - projid = 0; - } - if (setprid(projid)) - fatal("Failed to initialize project %d for %s: %.100s", - (int)projid, pw->pw_name, strerror(errno)); + /* initialize irix project info */ + if ((projid = getdfltprojuser(pw->pw_name)) == -1) { + debug("Failed to get project id, using projid 0"); + projid = 0; + } + if (setprid(projid)) + fatal("Failed to initialize project %d for %s: %.100s", + (int)projid, pw->pw_name, strerror(errno)); #endif /* WITH_IRIX_PROJECT */ #ifdef WITH_IRIX_AUDIT - if (sysconf(_SC_AUDIT)) { - debug("Setting sat id to %d", (int) pw->pw_uid); - if (satsetid(pw->pw_uid)) - debug("error setting satid: %.100s", strerror(errno)); - } + if (sysconf(_SC_AUDIT)) { + debug("Setting sat id to %d", (int) pw->pw_uid); + if (satsetid(pw->pw_uid)) + debug("error setting satid: %.100s", strerror(errno)); + } #endif /* WITH_IRIX_AUDIT */ } diff --git a/openbsd-compat/port-irix.h b/openbsd-compat/port-irix.h index 67c48630..bc8cc44a 100644 --- a/openbsd-compat/port-irix.h +++ b/openbsd-compat/port-irix.h @@ -1,5 +1,3 @@ -/* $Id: port-irix.h,v 1.4 2003/08/29 16:59:52 mouring Exp $ */ - /* * Copyright (c) 2000 Denis Parker. All rights reserved. * Copyright (c) 2000 Michael Stone. All rights reserved. diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index 4637a7a3..f46094fa 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -1,5 +1,3 @@ -/* $Id: port-linux.c,v 1.18 2013/06/01 22:07:32 dtucker Exp $ */ - /* * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com> * Copyright (c) 2006 Damien Miller <djm@openbsd.org> @@ -28,6 +26,7 @@ #include <stdarg.h> #include <string.h> #include <stdio.h> +#include <stdlib.h> #include "log.h" #include "xmalloc.h" @@ -35,7 +34,6 @@ #ifdef WITH_SELINUX #include <selinux/selinux.h> -#include <selinux/flask.h> #include <selinux/get_context_list.h> #ifndef SSH_SELINUX_UNCONFINED_TYPE @@ -141,6 +139,7 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) security_context_t new_tty_ctx = NULL; security_context_t user_ctx = NULL; security_context_t old_tty_ctx = NULL; + security_class_t chrclass; if (!ssh_selinux_enabled()) return; @@ -155,9 +154,12 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) error("%s: getfilecon: %s", __func__, strerror(errno)); goto out; } - + if ((chrclass = string_to_security_class("chr_file")) == 0) { + error("%s: couldn't get security class for chr_file", __func__); + goto out; + } if (security_compute_relabel(user_ctx, old_tty_ctx, - SECCLASS_CHR_FILE, &new_tty_ctx) != 0) { + chrclass, &new_tty_ctx) != 0) { error("%s: security_compute_relabel: %s", __func__, strerror(errno)); goto out; @@ -191,7 +193,7 @@ ssh_selinux_change_context(const char *newname) } if ((cx = index(oldctx, ':')) == NULL || (cx = index(cx + 1, ':')) == NULL) { - logit ("%s: unparseable context %s", __func__, oldctx); + logit ("%s: unparsable context %s", __func__, oldctx); return; } @@ -278,7 +280,7 @@ oom_adjust_setup(void) verbose("error writing %s: %s", oom_adj_path, strerror(errno)); else - verbose("Set %s from %d to %d", + debug("Set %s from %d to %d", oom_adj_path, oom_adj_save, value); } fclose(fp); @@ -302,7 +304,7 @@ oom_adjust_restore(void) if (fprintf(fp, "%d\n", oom_adj_save) <= 0) verbose("error writing %s: %s", oom_adj_path, strerror(errno)); else - verbose("Set %s to %d", oom_adj_path, oom_adj_save); + debug("Set %s to %d", oom_adj_path, oom_adj_save); fclose(fp); return; diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index e3d1004a..3c22a854 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h @@ -1,5 +1,3 @@ -/* $Id: port-linux.h,v 1.5 2011/01/25 01:16:18 djm Exp $ */ - /* * Copyright (c) 2006 Damien Miller <djm@openbsd.org> * diff --git a/openbsd-compat/port-tun.c b/openbsd-compat/port-net.c index 49e7b4d9..617bffce 100644 --- a/openbsd-compat/port-tun.c +++ b/openbsd-compat/port-net.c @@ -37,6 +37,90 @@ #include "ssherr.h" /* + * This file contains various portability code for network support, + * including tun/tap forwarding and routing domains. + */ + +#if defined(SYS_RDOMAIN_LINUX) || defined(SSH_TUN_LINUX) +#include <linux/if.h> +#endif + +#if defined(SYS_RDOMAIN_LINUX) +char * +sys_get_rdomain(int fd) +{ + char dev[IFNAMSIZ + 1]; + socklen_t len = sizeof(dev) - 1; + + if (getsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, dev, &len) == -1) { + error("%s: cannot determine VRF for fd=%d : %s", + __func__, fd, strerror(errno)); + return NULL; + } + dev[len] = '\0'; + return strdup(dev); +} + +int +sys_set_rdomain(int fd, const char *name) +{ + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, + name, strlen(name)) == -1) { + error("%s: setsockopt(%d, SO_BINDTODEVICE, %s): %s", + __func__, fd, name, strerror(errno)); + return -1; + } + return 0; +} + +int +sys_valid_rdomain(const char *name) +{ + int fd; + + /* + * This is a pretty crappy way to test. It would be better to + * check whether "name" represents a VRF device, but apparently + * that requires an rtnetlink transaction. + */ + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + return 0; + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, + name, strlen(name)) == -1) { + close(fd); + return 0; + } + close(fd); + return 1; +} +#elif defined(SYS_RDOMAIN_XXX) +/* XXX examples */ +char * +sys_get_rdomain(int fd) +{ + return NULL; +} + +int +sys_set_rdomain(int fd, const char *name) +{ + return -1; +} + +int +valid_rdomain(const char *name) +{ + return 0; +} + +void +sys_set_process_rdomain(const char *name) +{ + fatal("%s: not supported", __func__); +} +#endif /* defined(SYS_RDOMAIN_XXX) */ + +/* * This is the portable version of the SSH tunnel forwarding, it * uses some preprocessor definitions for various platform-specific * settings. @@ -52,23 +136,25 @@ */ #if defined(SSH_TUN_LINUX) -#include <linux/if.h> #include <linux/if_tun.h> +#define TUN_CTRL_DEV "/dev/net/tun" int -sys_tun_open(int tun, int mode) +sys_tun_open(int tun, int mode, char **ifname) { struct ifreq ifr; int fd = -1; const char *name = NULL; - if ((fd = open("/dev/net/tun", O_RDWR)) == -1) { - debug("%s: failed to open tunnel control interface: %s", - __func__, strerror(errno)); + if (ifname != NULL) + *ifname = NULL; + if ((fd = open(TUN_CTRL_DEV, O_RDWR)) == -1) { + debug("%s: failed to open tunnel control device \"%s\": %s", + __func__, TUN_CTRL_DEV, strerror(errno)); return (-1); } - bzero(&ifr, sizeof(ifr)); + bzero(&ifr, sizeof(ifr)); if (mode == SSH_TUNMODE_ETHERNET) { ifr.ifr_flags = IFF_TAP; @@ -99,6 +185,9 @@ sys_tun_open(int tun, int mode) else debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd); + if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)) == NULL) + goto failed; + return (fd); failed: @@ -116,13 +205,16 @@ sys_tun_open(int tun, int mode) #endif int -sys_tun_open(int tun, int mode) +sys_tun_open(int tun, int mode, char **ifname) { struct ifreq ifr; char name[100]; int fd = -1, sock, flag; const char *tunbase = "tun"; + if (ifname != NULL) + *ifname = NULL; + if (mode == SSH_TUNMODE_ETHERNET) { #ifdef SSH_TUN_NO_L2 debug("%s: no layer 2 tunnelling support", __func__); @@ -180,6 +272,9 @@ sys_tun_open(int tun, int mode) goto failed; } + if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)) == NULL) + goto failed; + close(sock); return (fd); @@ -199,84 +294,81 @@ sys_tun_open(int tun, int mode) */ #if defined(SSH_TUN_FILTER) +/* + * The tunnel forwarding protocol prepends the address family of forwarded + * IP packets using OpenBSD's numbers. + */ #define OPENBSD_AF_INET 2 #define OPENBSD_AF_INET6 24 int -sys_tun_infilter(struct Channel *c, char *buf, int len) +sys_tun_infilter(struct ssh *ssh, struct Channel *c, char *buf, int _len) { + int r; + size_t len; + char *ptr = buf; #if defined(SSH_TUN_PREPEND_AF) char rbuf[CHAN_RBUF]; - struct ip *iph; + struct ip iph; #endif - u_int32_t *af; - char *ptr = buf; - int r; - -#if defined(SSH_TUN_PREPEND_AF) - if (len <= 0 || len > (int)(sizeof(rbuf) - sizeof(*af))) - return (-1); - ptr = (char *)&rbuf[0]; - bcopy(buf, ptr + sizeof(u_int32_t), len); - len += sizeof(u_int32_t); - af = (u_int32_t *)ptr; - - iph = (struct ip *)(ptr + sizeof(u_int32_t)); - switch (iph->ip_v) { - case 6: - *af = AF_INET6; - break; - case 4: - default: - *af = AF_INET; - break; - } +#if defined(SSH_TUN_PREPEND_AF) || defined(SSH_TUN_COMPAT_AF) + u_int32_t af; #endif -#if defined(SSH_TUN_COMPAT_AF) - if (len < (int)sizeof(u_int32_t)) - return (-1); + /* XXX update channel input filter API to use unsigned length */ + if (_len < 0) + return -1; + len = _len; - af = (u_int32_t *)ptr; - if (*af == htonl(AF_INET6)) - *af = htonl(OPENBSD_AF_INET6); - else - *af = htonl(OPENBSD_AF_INET); +#if defined(SSH_TUN_PREPEND_AF) + if (len <= sizeof(iph) || len > sizeof(rbuf) - 4) + return -1; + /* Determine address family from packet IP header. */ + memcpy(&iph, buf, sizeof(iph)); + af = iph.ip_v == 6 ? OPENBSD_AF_INET6 : OPENBSD_AF_INET; + /* Prepend address family to packet using OpenBSD constants */ + memcpy(rbuf + 4, buf, len); + len += 4; + POKE_U32(rbuf, af); + ptr = rbuf; +#elif defined(SSH_TUN_COMPAT_AF) + /* Convert existing address family header to OpenBSD value */ + if (len <= 4) + return -1; + af = PEEK_U32(buf); + /* Put it back */ + POKE_U32(buf, af == AF_INET6 ? OPENBSD_AF_INET6 : OPENBSD_AF_INET); #endif - if ((r = sshbuf_put_string(&c->input, ptr, len)) != 0) + if ((r = sshbuf_put_string(c->input, ptr, len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); return (0); } u_char * -sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen) +sys_tun_outfilter(struct ssh *ssh, struct Channel *c, + u_char **data, size_t *dlen) { u_char *buf; - u_int32_t *af; + u_int32_t af; int r; - size_t xxx_dlen; /* XXX new API is incompatible with this signature. */ - if ((r = sshbuf_get_string(&c->output, data, &xxx_dlen)) != 0) + if ((r = sshbuf_get_string(c->output, data, dlen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); - if (dlen != NULL) - *dlen = xxx_dlen; - if (*dlen < sizeof(*af)) + if (*dlen < sizeof(af)) return (NULL); buf = *data; #if defined(SSH_TUN_PREPEND_AF) - *dlen -= sizeof(u_int32_t); - buf = *data + sizeof(u_int32_t); + /* skip address family */ + *dlen -= sizeof(af); + buf = *data + sizeof(af); #elif defined(SSH_TUN_COMPAT_AF) - af = ntohl(*(u_int32_t *)buf); - if (*af == OPENBSD_AF_INET6) - *af = htonl(AF_INET6); - else - *af = htonl(AF_INET); + /* translate address family */ + af = (PEEK_U32(buf) == OPENBSD_AF_INET6) ? AF_INET6 : AF_INET; + POKE_U32(buf, af); #endif - return (buf); } #endif /* SSH_TUN_FILTER */ diff --git a/openbsd-compat/port-tun.h b/openbsd-compat/port-net.h index c53df01f..3a0d1104 100644 --- a/openbsd-compat/port-tun.h +++ b/openbsd-compat/port-net.h @@ -18,16 +18,31 @@ #define _PORT_TUN_H struct Channel; +struct ssh; #if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD) # define CUSTOM_SYS_TUN_OPEN -int sys_tun_open(int, int); +int sys_tun_open(int, int, char **); #endif #if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF) # define SSH_TUN_FILTER -int sys_tun_infilter(struct Channel *, char *, int); -u_char *sys_tun_outfilter(struct Channel *, u_char **, u_int *); +int sys_tun_infilter(struct ssh *, struct Channel *, char *, int); +u_char *sys_tun_outfilter(struct ssh *, struct Channel *, u_char **, size_t *); +#endif + +#if defined(SYS_RDOMAIN_LINUX) +# define HAVE_SYS_GET_RDOMAIN +# define HAVE_SYS_SET_RDOMAIN +# define HAVE_SYS_VALID_RDOMAIN +char *sys_get_rdomain(int fd); +int sys_set_rdomain(int fd, const char *name); +int sys_valid_rdomain(const char *name); +#endif + +#if defined(SYS_RDOMAIN_XXX) +# define HAVE_SYS_SET_PROCESS_RDOMAIN +void sys_set_process_rdomain(const char *name); #endif #endif diff --git a/openbsd-compat/port-solaris.c b/openbsd-compat/port-solaris.c index 25382f1c..7d5a28cd 100644 --- a/openbsd-compat/port-solaris.c +++ b/openbsd-compat/port-solaris.c @@ -1,5 +1,3 @@ -/* $Id: port-solaris.c,v 1.4 2010/11/05 01:03:05 dtucker Exp $ */ - /* * Copyright (c) 2006 Chad Mynhier. * @@ -215,7 +213,7 @@ solaris_set_default_project(struct passwd *pw) /* get default project, if we fail just return gracefully */ if ((defaultproject = getdefaultproj(pw->pw_name, &tempproject, &buf, - sizeof(buf))) > 0) { + sizeof(buf))) != NULL) { /* set default project */ if (setproject(defaultproject->pj_name, pw->pw_name, TASK_NORMAL) != 0) @@ -227,3 +225,137 @@ solaris_set_default_project(struct passwd *pw) } } #endif /* USE_SOLARIS_PROJECTS */ + +#ifdef USE_SOLARIS_PRIVS +# ifdef HAVE_PRIV_H +# include <priv.h> +# endif + +priv_set_t * +solaris_basic_privset(void) +{ + priv_set_t *pset; + +#ifdef HAVE_PRIV_BASICSET + if ((pset = priv_allocset()) == NULL) { + error("priv_allocset: %s", strerror(errno)); + return NULL; + } + priv_basicset(pset); +#else + if ((pset = priv_str_to_set("basic", ",", NULL)) == NULL) { + error("priv_str_to_set: %s", strerror(errno)); + return NULL; + } +#endif + return pset; +} + +void +solaris_drop_privs_pinfo_net_fork_exec(void) +{ + priv_set_t *pset = NULL, *npset = NULL; + + /* + * Note: this variant avoids dropping DAC filesystem rights, in case + * the process calling it is running as root and should have the + * ability to read/write/chown any file on the system. + * + * We start with the basic set, then *add* the DAC rights to it while + * taking away other parts of BASIC we don't need. Then we intersect + * this with our existing PERMITTED set. In this way we keep any + * DAC rights we had before, while otherwise reducing ourselves to + * the minimum set of privileges we need to proceed. + * + * This also means we drop any other parts of "root" that we don't + * need (e.g. the ability to kill any process, create new device nodes + * etc etc). + */ + + if ((pset = priv_allocset()) == NULL) + fatal("priv_allocset: %s", strerror(errno)); + if ((npset = solaris_basic_privset()) == NULL) + fatal("solaris_basic_privset: %s", strerror(errno)); + + if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 || + priv_addset(npset, PRIV_FILE_DAC_READ) != 0 || + priv_addset(npset, PRIV_FILE_DAC_SEARCH) != 0 || + priv_addset(npset, PRIV_FILE_DAC_WRITE) != 0 || + priv_addset(npset, PRIV_FILE_OWNER) != 0) + fatal("priv_addset: %s", strerror(errno)); + + if (priv_delset(npset, PRIV_PROC_EXEC) != 0 || +#ifdef PRIV_NET_ACCESS + priv_delset(npset, PRIV_NET_ACCESS) != 0 || +#endif + priv_delset(npset, PRIV_PROC_FORK) != 0 || + priv_delset(npset, PRIV_PROC_INFO) != 0 || + priv_delset(npset, PRIV_PROC_SESSION) != 0) + fatal("priv_delset: %s", strerror(errno)); + + if (getppriv(PRIV_PERMITTED, pset) != 0) + fatal("getppriv: %s", strerror(errno)); + + priv_intersect(pset, npset); + + if (setppriv(PRIV_SET, PRIV_PERMITTED, npset) != 0 || + setppriv(PRIV_SET, PRIV_LIMIT, npset) != 0 || + setppriv(PRIV_SET, PRIV_INHERITABLE, npset) != 0) + fatal("setppriv: %s", strerror(errno)); + + priv_freeset(pset); + priv_freeset(npset); +} + +void +solaris_drop_privs_root_pinfo_net(void) +{ + priv_set_t *pset = NULL; + + /* Start with "basic" and drop everything we don't need. */ + if ((pset = solaris_basic_privset()) == NULL) + fatal("solaris_basic_privset: %s", strerror(errno)); + + if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 || +#ifdef PRIV_NET_ACCESS + priv_delset(pset, PRIV_NET_ACCESS) != 0 || +#endif + priv_delset(pset, PRIV_PROC_INFO) != 0 || + priv_delset(pset, PRIV_PROC_SESSION) != 0) + fatal("priv_delset: %s", strerror(errno)); + + if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 || + setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 || + setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0) + fatal("setppriv: %s", strerror(errno)); + + priv_freeset(pset); +} + +void +solaris_drop_privs_root_pinfo_net_exec(void) +{ + priv_set_t *pset = NULL; + + + /* Start with "basic" and drop everything we don't need. */ + if ((pset = solaris_basic_privset()) == NULL) + fatal("solaris_basic_privset: %s", strerror(errno)); + + if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 || +#ifdef PRIV_NET_ACCESS + priv_delset(pset, PRIV_NET_ACCESS) != 0 || +#endif + priv_delset(pset, PRIV_PROC_EXEC) != 0 || + priv_delset(pset, PRIV_PROC_INFO) != 0) + fatal("priv_delset: %s", strerror(errno)); + + if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 || + setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 || + setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0) + fatal("setppriv: %s", strerror(errno)); + + priv_freeset(pset); +} + +#endif diff --git a/openbsd-compat/port-solaris.h b/openbsd-compat/port-solaris.h index cd442e78..dde1a5b8 100644 --- a/openbsd-compat/port-solaris.h +++ b/openbsd-compat/port-solaris.h @@ -1,5 +1,3 @@ -/* $Id: port-solaris.h,v 1.2 2010/11/05 01:03:05 dtucker Exp $ */ - /* * Copyright (c) 2006 Chad Mynhier. * @@ -26,5 +24,12 @@ void solaris_contract_pre_fork(void); void solaris_contract_post_fork_child(void); void solaris_contract_post_fork_parent(pid_t pid); void solaris_set_default_project(struct passwd *); +# ifdef USE_SOLARIS_PRIVS +#include <priv.h> +priv_set_t *solaris_basic_privset(void); +void solaris_drop_privs_pinfo_net_fork_exec(void); +void solaris_drop_privs_root_pinfo_net(void); +void solaris_drop_privs_root_pinfo_net_exec(void); +# endif /* USE_SOLARIS_PRIVS */ #endif diff --git a/openbsd-compat/port-uw.c b/openbsd-compat/port-uw.c index db24dbb9..13221313 100644 --- a/openbsd-compat/port-uw.c +++ b/openbsd-compat/port-uw.c @@ -38,8 +38,6 @@ #include "xmalloc.h" #include "packet.h" -#include "buffer.h" -#include "key.h" #include "auth-options.h" #include "log.h" #include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ @@ -47,12 +45,14 @@ #include "hostfile.h" #include "auth.h" #include "ssh.h" +#include "ssh_api.h" int nischeck(char *); int -sys_auth_passwd(Authctxt *authctxt, const char *password) +sys_auth_passwd(struct ssh *ssh, const char *password) { + Authctxt *authctxt = ssh->authctxt; struct passwd *pw = authctxt->pw; char *salt; int result; @@ -60,6 +60,9 @@ sys_auth_passwd(Authctxt *authctxt, const char *password) /* Just use the supplied fake password if authctxt is invalid */ char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd; + if (pw_password == NULL) + return 0; + /* Check for users with no password. */ if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0) return (1); @@ -97,7 +100,7 @@ nischeck(char *namep) if ((fd = fopen (password_file, "r")) == NULL) { /* - * If the passwd file has dissapeared we are in a bad state. + * If the passwd file has disappeared we are in a bad state. * However, returning 0 will send us back through the * authentication scheme that has checked the ia database for * passwords earlier. diff --git a/openbsd-compat/pwcache.c b/openbsd-compat/pwcache.c index 5a8b7880..826c2378 100644 --- a/openbsd-compat/pwcache.c +++ b/openbsd-compat/pwcache.c @@ -67,7 +67,7 @@ user_from_uid(uid_t uid, int nouser) if ((pw = getpwuid(uid)) == NULL) { if (nouser) return (NULL); - (void)snprintf(nbuf, sizeof(nbuf), "%u", uid); + (void)snprintf(nbuf, sizeof(nbuf), "%lu", (u_long)uid); } cp->uid = uid; if (cp->name != NULL) @@ -102,7 +102,7 @@ group_from_gid(gid_t gid, int nogroup) if ((gr = getgrgid(gid)) == NULL) { if (nogroup) return (NULL); - (void)snprintf(nbuf, sizeof(nbuf), "%u", gid); + (void)snprintf(nbuf, sizeof(nbuf), "%lu", (u_long)gid); } cp->gid = gid; if (cp->name != NULL) diff --git a/openbsd-compat/readpassphrase.c b/openbsd-compat/readpassphrase.c index d63cdf2f..ff8ff3de 100644 --- a/openbsd-compat/readpassphrase.c +++ b/openbsd-compat/readpassphrase.c @@ -1,7 +1,8 @@ -/* $OpenBSD: readpassphrase.c,v 1.22 2010/01/13 10:20:54 dtucker Exp $ */ +/* $OpenBSD: readpassphrase.c,v 1.26 2016/10/18 12:47:18 millert Exp $ */ /* - * Copyright (c) 2000-2002, 2007 Todd C. Miller <Todd.Miller@courtesan.com> + * Copyright (c) 2000-2002, 2007, 2010 + * Todd C. Miller <Todd.Miller@courtesan.com> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -35,10 +36,9 @@ #include <string.h> #include <unistd.h> -#ifdef TCSASOFT -# define _T_FLUSH (TCSAFLUSH|TCSASOFT) -#else -# define _T_FLUSH (TCSAFLUSH) +#ifndef TCSASOFT +/* If we don't have TCSASOFT define it so that ORing it it below is a no-op. */ +# define TCSASOFT 0 #endif /* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */ @@ -46,14 +46,6 @@ # define _POSIX_VDISABLE VDISABLE #endif -#ifndef _NSIG -# ifdef NSIG -# define _NSIG NSIG -# else -# define _NSIG 128 -# endif -#endif - static volatile sig_atomic_t signo[_NSIG]; static void handler(int); @@ -95,6 +87,27 @@ restart: } /* + * Turn off echo if possible. + * If we are using a tty but are not the foreground pgrp this will + * generate SIGTTOU, so do it *before* installing the signal handlers. + */ + if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { + memcpy(&term, &oterm, sizeof(term)); + if (!(flags & RPP_ECHO_ON)) + term.c_lflag &= ~(ECHO | ECHONL); +#ifdef VSTATUS + if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) + term.c_cc[VSTATUS] = _POSIX_VDISABLE; +#endif + (void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); + } else { + memset(&term, 0, sizeof(term)); + term.c_lflag |= ECHO; + memset(&oterm, 0, sizeof(oterm)); + oterm.c_lflag |= ECHO; + } + + /* * Catch signals that would otherwise cause the user to end * up with echo turned off in the shell. Don't worry about * things like SIGXCPU and SIGVTALRM for now. @@ -112,53 +125,37 @@ restart: (void)sigaction(SIGTTIN, &sa, &savettin); (void)sigaction(SIGTTOU, &sa, &savettou); - /* Turn off echo if possible. */ - if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { - memcpy(&term, &oterm, sizeof(term)); - if (!(flags & RPP_ECHO_ON)) - term.c_lflag &= ~(ECHO | ECHONL); -#ifdef VSTATUS - if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) - term.c_cc[VSTATUS] = _POSIX_VDISABLE; -#endif - (void)tcsetattr(input, _T_FLUSH, &term); - } else { - memset(&term, 0, sizeof(term)); - term.c_lflag |= ECHO; - memset(&oterm, 0, sizeof(oterm)); - oterm.c_lflag |= ECHO; - } - - /* No I/O if we are already backgrounded. */ - if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) { - if (!(flags & RPP_STDIN)) - (void)write(output, prompt, strlen(prompt)); - end = buf + bufsiz - 1; - p = buf; - while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { - if (p < end) { - if ((flags & RPP_SEVENBIT)) - ch &= 0x7f; - if (isalpha(ch)) { - if ((flags & RPP_FORCELOWER)) - ch = (char)tolower(ch); - if ((flags & RPP_FORCEUPPER)) - ch = (char)toupper(ch); - } - *p++ = ch; + if (!(flags & RPP_STDIN)) + (void)write(output, prompt, strlen(prompt)); + end = buf + bufsiz - 1; + p = buf; + while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { + if (p < end) { + if ((flags & RPP_SEVENBIT)) + ch &= 0x7f; + if (isalpha((unsigned char)ch)) { + if ((flags & RPP_FORCELOWER)) + ch = (char)tolower((unsigned char)ch); + if ((flags & RPP_FORCEUPPER)) + ch = (char)toupper((unsigned char)ch); } + *p++ = ch; } - *p = '\0'; - save_errno = errno; - if (!(term.c_lflag & ECHO)) - (void)write(output, "\n", 1); } + *p = '\0'; + save_errno = errno; + if (!(term.c_lflag & ECHO)) + (void)write(output, "\n", 1); /* Restore old terminal settings and signals. */ if (memcmp(&term, &oterm, sizeof(term)) != 0) { - while (tcsetattr(input, _T_FLUSH, &oterm) == -1 && - errno == EINTR) + const int sigttou = signo[SIGTTOU]; + + /* Ignore SIGTTOU generated when we are not the fg pgrp. */ + while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 && + errno == EINTR && !signo[SIGTTOU]) continue; + signo[SIGTTOU] = sigttou; } (void)sigaction(SIGALRM, &savealrm, NULL); (void)sigaction(SIGHUP, &savehup, NULL); @@ -194,6 +191,7 @@ restart: errno = save_errno; return(nr == -1 ? NULL : buf); } +DEF_WEAK(readpassphrase); #if 0 char * diff --git a/openbsd-compat/readpassphrase.c.orig b/openbsd-compat/readpassphrase.c.orig deleted file mode 100644 index d63cdf2f..00000000 --- a/openbsd-compat/readpassphrase.c.orig +++ /dev/null @@ -1,213 +0,0 @@ -/* $OpenBSD: readpassphrase.c,v 1.22 2010/01/13 10:20:54 dtucker Exp $ */ - -/* - * Copyright (c) 2000-2002, 2007 Todd C. Miller <Todd.Miller@courtesan.com> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F39502-99-1-0512. - */ - -/* OPENBSD ORIGINAL: lib/libc/gen/readpassphrase.c */ - -#include "includes.h" - -#ifndef HAVE_READPASSPHRASE - -#include <termios.h> -#include <signal.h> -#include <ctype.h> -#include <fcntl.h> -#include <readpassphrase.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> - -#ifdef TCSASOFT -# define _T_FLUSH (TCSAFLUSH|TCSASOFT) -#else -# define _T_FLUSH (TCSAFLUSH) -#endif - -/* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */ -#if !defined(_POSIX_VDISABLE) && defined(VDISABLE) -# define _POSIX_VDISABLE VDISABLE -#endif - -#ifndef _NSIG -# ifdef NSIG -# define _NSIG NSIG -# else -# define _NSIG 128 -# endif -#endif - -static volatile sig_atomic_t signo[_NSIG]; - -static void handler(int); - -char * -readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) -{ - ssize_t nr; - int input, output, save_errno, i, need_restart; - char ch, *p, *end; - struct termios term, oterm; - struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; - struct sigaction savetstp, savettin, savettou, savepipe; - - /* I suppose we could alloc on demand in this case (XXX). */ - if (bufsiz == 0) { - errno = EINVAL; - return(NULL); - } - -restart: - for (i = 0; i < _NSIG; i++) - signo[i] = 0; - nr = -1; - save_errno = 0; - need_restart = 0; - /* - * Read and write to /dev/tty if available. If not, read from - * stdin and write to stderr unless a tty is required. - */ - if ((flags & RPP_STDIN) || - (input = output = open(_PATH_TTY, O_RDWR)) == -1) { - if (flags & RPP_REQUIRE_TTY) { - errno = ENOTTY; - return(NULL); - } - input = STDIN_FILENO; - output = STDERR_FILENO; - } - - /* - * Catch signals that would otherwise cause the user to end - * up with echo turned off in the shell. Don't worry about - * things like SIGXCPU and SIGVTALRM for now. - */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; /* don't restart system calls */ - sa.sa_handler = handler; - (void)sigaction(SIGALRM, &sa, &savealrm); - (void)sigaction(SIGHUP, &sa, &savehup); - (void)sigaction(SIGINT, &sa, &saveint); - (void)sigaction(SIGPIPE, &sa, &savepipe); - (void)sigaction(SIGQUIT, &sa, &savequit); - (void)sigaction(SIGTERM, &sa, &saveterm); - (void)sigaction(SIGTSTP, &sa, &savetstp); - (void)sigaction(SIGTTIN, &sa, &savettin); - (void)sigaction(SIGTTOU, &sa, &savettou); - - /* Turn off echo if possible. */ - if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { - memcpy(&term, &oterm, sizeof(term)); - if (!(flags & RPP_ECHO_ON)) - term.c_lflag &= ~(ECHO | ECHONL); -#ifdef VSTATUS - if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) - term.c_cc[VSTATUS] = _POSIX_VDISABLE; -#endif - (void)tcsetattr(input, _T_FLUSH, &term); - } else { - memset(&term, 0, sizeof(term)); - term.c_lflag |= ECHO; - memset(&oterm, 0, sizeof(oterm)); - oterm.c_lflag |= ECHO; - } - - /* No I/O if we are already backgrounded. */ - if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) { - if (!(flags & RPP_STDIN)) - (void)write(output, prompt, strlen(prompt)); - end = buf + bufsiz - 1; - p = buf; - while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { - if (p < end) { - if ((flags & RPP_SEVENBIT)) - ch &= 0x7f; - if (isalpha(ch)) { - if ((flags & RPP_FORCELOWER)) - ch = (char)tolower(ch); - if ((flags & RPP_FORCEUPPER)) - ch = (char)toupper(ch); - } - *p++ = ch; - } - } - *p = '\0'; - save_errno = errno; - if (!(term.c_lflag & ECHO)) - (void)write(output, "\n", 1); - } - - /* Restore old terminal settings and signals. */ - if (memcmp(&term, &oterm, sizeof(term)) != 0) { - while (tcsetattr(input, _T_FLUSH, &oterm) == -1 && - errno == EINTR) - continue; - } - (void)sigaction(SIGALRM, &savealrm, NULL); - (void)sigaction(SIGHUP, &savehup, NULL); - (void)sigaction(SIGINT, &saveint, NULL); - (void)sigaction(SIGQUIT, &savequit, NULL); - (void)sigaction(SIGPIPE, &savepipe, NULL); - (void)sigaction(SIGTERM, &saveterm, NULL); - (void)sigaction(SIGTSTP, &savetstp, NULL); - (void)sigaction(SIGTTIN, &savettin, NULL); - (void)sigaction(SIGTTOU, &savettou, NULL); - if (input != STDIN_FILENO) - (void)close(input); - - /* - * If we were interrupted by a signal, resend it to ourselves - * now that we have restored the signal handlers. - */ - for (i = 0; i < _NSIG; i++) { - if (signo[i]) { - kill(getpid(), i); - switch (i) { - case SIGTSTP: - case SIGTTIN: - case SIGTTOU: - need_restart = 1; - } - } - } - if (need_restart) - goto restart; - - if (save_errno) - errno = save_errno; - return(nr == -1 ? NULL : buf); -} - -#if 0 -char * -getpass(const char *prompt) -{ - static char buf[_PASSWORD_LEN + 1]; - - return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF)); -} -#endif - -static void handler(int s) -{ - - signo[s] = 1; -} -#endif /* HAVE_READPASSPHRASE */ diff --git a/openbsd-compat/realpath.c b/openbsd-compat/realpath.c deleted file mode 100644 index b6120d03..00000000 --- a/openbsd-compat/realpath.c +++ /dev/null @@ -1,197 +0,0 @@ -/* $OpenBSD: realpath.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ -/* - * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The names of the authors may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* OPENBSD ORIGINAL: lib/libc/stdlib/realpath.c */ - -#include "includes.h" - -#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) - -#include <sys/param.h> -#include <sys/stat.h> - -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -/* - * char *realpath(const char *path, char resolved[PATH_MAX]); - * - * Find the real name of path, by removing all ".", ".." and symlink - * components. Returns (resolved) on success, or (NULL) on failure, - * in which case the path which caused trouble is left in (resolved). - */ -char * -realpath(const char *path, char resolved[PATH_MAX]) -{ - struct stat sb; - char *p, *q, *s; - size_t left_len, resolved_len; - unsigned symlinks; - int serrno, slen; - char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; - - serrno = errno; - symlinks = 0; - if (path[0] == '/') { - resolved[0] = '/'; - resolved[1] = '\0'; - if (path[1] == '\0') - return (resolved); - resolved_len = 1; - left_len = strlcpy(left, path + 1, sizeof(left)); - } else { - if (getcwd(resolved, PATH_MAX) == NULL) { - strlcpy(resolved, ".", PATH_MAX); - return (NULL); - } - resolved_len = strlen(resolved); - left_len = strlcpy(left, path, sizeof(left)); - } - if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { - errno = ENAMETOOLONG; - return (NULL); - } - - /* - * Iterate over path components in `left'. - */ - while (left_len != 0) { - /* - * Extract the next path component and adjust `left' - * and its length. - */ - p = strchr(left, '/'); - s = p ? p : left + left_len; - if (s - left >= sizeof(next_token)) { - errno = ENAMETOOLONG; - return (NULL); - } - memcpy(next_token, left, s - left); - next_token[s - left] = '\0'; - left_len -= s - left; - if (p != NULL) - memmove(left, s + 1, left_len + 1); - if (resolved[resolved_len - 1] != '/') { - if (resolved_len + 1 >= PATH_MAX) { - errno = ENAMETOOLONG; - return (NULL); - } - resolved[resolved_len++] = '/'; - resolved[resolved_len] = '\0'; - } - if (next_token[0] == '\0') - continue; - else if (strcmp(next_token, ".") == 0) - continue; - else if (strcmp(next_token, "..") == 0) { - /* - * Strip the last path component except when we have - * single "/" - */ - if (resolved_len > 1) { - resolved[resolved_len - 1] = '\0'; - q = strrchr(resolved, '/') + 1; - *q = '\0'; - resolved_len = q - resolved; - } - continue; - } - - /* - * Append the next path component and lstat() it. If - * lstat() fails we still can return successfully if - * there are no more path components left. - */ - resolved_len = strlcat(resolved, next_token, PATH_MAX); - if (resolved_len >= PATH_MAX) { - errno = ENAMETOOLONG; - return (NULL); - } - if (lstat(resolved, &sb) != 0) { - if (errno == ENOENT && p == NULL) { - errno = serrno; - return (resolved); - } - return (NULL); - } - if (S_ISLNK(sb.st_mode)) { - if (symlinks++ > MAXSYMLINKS) { - errno = ELOOP; - return (NULL); - } - slen = readlink(resolved, symlink, sizeof(symlink) - 1); - if (slen < 0) - return (NULL); - symlink[slen] = '\0'; - if (symlink[0] == '/') { - resolved[1] = 0; - resolved_len = 1; - } else if (resolved_len > 1) { - /* Strip the last path component. */ - resolved[resolved_len - 1] = '\0'; - q = strrchr(resolved, '/') + 1; - *q = '\0'; - resolved_len = q - resolved; - } - - /* - * If there are any path components left, then - * append them to symlink. The result is placed - * in `left'. - */ - if (p != NULL) { - if (symlink[slen - 1] != '/') { - if (slen + 1 >= sizeof(symlink)) { - errno = ENAMETOOLONG; - return (NULL); - } - symlink[slen] = '/'; - symlink[slen + 1] = 0; - } - left_len = strlcat(symlink, left, sizeof(left)); - if (left_len >= sizeof(left)) { - errno = ENAMETOOLONG; - return (NULL); - } - } - left_len = strlcpy(left, symlink, sizeof(left)); - } - } - - /* - * Remove trailing slash except when the resolved pathname - * is a single "/". - */ - if (resolved_len > 1 && resolved[resolved_len - 1] == '/') - resolved[resolved_len - 1] = '\0'; - return (resolved); -} -#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ diff --git a/openbsd-compat/recallocarray.c b/openbsd-compat/recallocarray.c new file mode 100644 index 00000000..3e1156ce --- /dev/null +++ b/openbsd-compat/recallocarray.c @@ -0,0 +1,90 @@ +/* $OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $ */ +/* + * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/stdlib/recallocarray.c */ + +#include "includes.h" +#ifndef HAVE_RECALLOCARRAY + +#include <errno.h> +#include <stdlib.h> +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +#include <string.h> +#include <unistd.h> + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void * +recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) +{ + size_t oldsize, newsize; + void *newptr; + + if (ptr == NULL) + return calloc(newnmemb, size); + + if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + newnmemb > 0 && SIZE_MAX / newnmemb < size) { + errno = ENOMEM; + return NULL; + } + newsize = newnmemb * size; + + if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + oldnmemb > 0 && SIZE_MAX / oldnmemb < size) { + errno = EINVAL; + return NULL; + } + oldsize = oldnmemb * size; + + /* + * Don't bother too much if we're shrinking just a bit, + * we do not shrink for series of small steps, oh well. + */ + if (newsize <= oldsize) { + size_t d = oldsize - newsize; + + if (d < oldsize / 2 && d < (size_t)getpagesize()) { + memset((char *)ptr + newsize, 0, d); + return ptr; + } + } + + newptr = malloc(newsize); + if (newptr == NULL) + return NULL; + + if (newsize > oldsize) { + memcpy(newptr, ptr, oldsize); + memset((char *)newptr + oldsize, 0, newsize - oldsize); + } else + memcpy(newptr, ptr, newsize); + + explicit_bzero(ptr, oldsize); + free(ptr); + + return newptr; +} +/* DEF_WEAK(recallocarray); */ + +#endif /* HAVE_RECALLOCARRAY */ diff --git a/openbsd-compat/regress/.cvsignore b/openbsd-compat/regress/.cvsignore deleted file mode 100644 index 33074f4a..00000000 --- a/openbsd-compat/regress/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -Makefile -snprintftest -strduptest -strtonumtest -closefromtest -opensslvertest diff --git a/openbsd-compat/regress/Makefile.in b/openbsd-compat/regress/Makefile.in index dabdb091..c5aae61e 100644 --- a/openbsd-compat/regress/Makefile.in +++ b/openbsd-compat/regress/Makefile.in @@ -1,5 +1,3 @@ -# $Id: Makefile.in,v 1.5 2014/06/17 13:06:08 dtucker Exp $ - sysconfdir=@sysconfdir@ piddir=@piddir@ srcdir=@srcdir@ @@ -16,7 +14,7 @@ LIBS=@LIBS@ LDFLAGS=@LDFLAGS@ $(LIBCOMPAT) TESTPROGS=closefromtest$(EXEEXT) snprintftest$(EXEEXT) strduptest$(EXEEXT) \ - strtonumtest$(EXEEXT) opensslvertest$(EXEEXT) + strtonumtest$(EXEEXT) opensslvertest$(EXEEXT) utimensattest$(EXEEXT) all: t-exec ${OTHERTESTS} diff --git a/openbsd-compat/regress/snprintftest.c b/openbsd-compat/regress/snprintftest.c index 4ca63e18..6dc2e222 100644 --- a/openbsd-compat/regress/snprintftest.c +++ b/openbsd-compat/regress/snprintftest.c @@ -47,7 +47,7 @@ int main(void) { char b[5]; - char *src; + char *src = NULL; snprintf(b,5,"123456789"); if (b[4] != '\0') @@ -69,5 +69,6 @@ main(void) if (x_snprintf(b, 1, "%s %d", "hello", 12345) != 11) fail("vsnprintf does not return required length"); + free(src); return failed; } diff --git a/openbsd-compat/regress/utimensattest.c b/openbsd-compat/regress/utimensattest.c new file mode 100644 index 00000000..24312e5d --- /dev/null +++ b/openbsd-compat/regress/utimensattest.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2019 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/stat.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define TMPFILE "utimensat.tmp" +#define TMPFILE2 "utimensat.tmp2" + +#ifndef AT_SYMLINK_NOFOLLOW +# define AT_SYMLINK_NOFOLLOW 0x80000000 +#endif + +int utimensat(int, const char *, const struct timespec[2], int); + +static void +cleanup(void) +{ + (void)unlink(TMPFILE); + (void)unlink(TMPFILE2); +} + +static void +fail(char *msg, long expect, long got) +{ + int saved_errno = errno; + + if (expect == got && got == 0) + fprintf(stderr, "utimensat: %s: %s\n", msg, + strerror(saved_errno)); + else + fprintf(stderr, "utimensat: %s: expected %ld got %ld\n", + msg, expect, got); + cleanup(); + exit(1); +} + +int +main(void) +{ + int fd; + struct stat sb; + struct timespec ts[2]; + + cleanup(); + if ((fd = open(TMPFILE, O_CREAT, 0600)) == -1) + fail("open", 0, 0); + close(fd); + + ts[0].tv_sec = 12345678; + ts[0].tv_nsec = 23456789; + ts[1].tv_sec = 34567890; + ts[1].tv_nsec = 45678901; + if (utimensat(AT_FDCWD, TMPFILE, ts, AT_SYMLINK_NOFOLLOW) == -1) + fail("utimensat", 0, 0); + + if (stat(TMPFILE, &sb) == -1) + fail("stat", 0, 0 ); + if (sb.st_atime != 12345678) + fail("st_atime", 0, 0 ); + if (sb.st_mtime != 34567890) + fail("st_mtime", 0, 0 ); +#if 0 + /* + * Results expected to be rounded to the nearest microsecond. + * Depends on timestamp precision in kernel and filesystem so + * disabled by default. + */ + if (sb.st_atim.tv_nsec != 23456000) + fail("atim.tv_nsec", 23456000, sb.st_atim.tv_nsec); + if (sb.st_mtim.tv_nsec != 45678000) + fail("mtim.tv_nsec", 45678000, sb.st_mtim.tv_nsec); +#endif + + /* + * POSIX specifies that when given a symlink, AT_SYMLINK_NOFOLLOW + * should update the symlink and not the destination. The compat + * code doesn't have a way to do this, so where possible it fails + * with instead of following a symlink when explicitly asked not to. + * Here we just test that it does not update the destination. + */ + if (rename(TMPFILE, TMPFILE2) == -1) + fail("rename", 0, 0); + if (symlink(TMPFILE2, TMPFILE) == -1) + fail("symlink", 0, 0); + ts[0].tv_sec = 11223344; + ts[1].tv_sec = 55667788; + (void)utimensat(AT_FDCWD, TMPFILE, ts, AT_SYMLINK_NOFOLLOW); + if (stat(TMPFILE2, &sb) == -1) + fail("stat", 0, 0 ); + if (sb.st_atime == 11223344) + fail("utimensat symlink st_atime", 0, 0 ); + if (sb.st_mtime == 55667788) + fail("utimensat symlink st_mtime", 0, 0 ); + + cleanup(); + exit(0); +} diff --git a/openbsd-compat/rmd160.c b/openbsd-compat/rmd160.c deleted file mode 100644 index 2a14dd7b..00000000 --- a/openbsd-compat/rmd160.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160", - * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997, - * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf - */ - -#include "includes.h" - -#ifndef WITH_OPENSSL - -#include <sys/types.h> -#include <endian.h> -#include <string.h> -#include <rmd160.h> - -#define PUT_64BIT_LE(cp, value) do { \ - (cp)[7] = (value) >> 56; \ - (cp)[6] = (value) >> 48; \ - (cp)[5] = (value) >> 40; \ - (cp)[4] = (value) >> 32; \ - (cp)[3] = (value) >> 24; \ - (cp)[2] = (value) >> 16; \ - (cp)[1] = (value) >> 8; \ - (cp)[0] = (value); } while (0) - -#define PUT_32BIT_LE(cp, value) do { \ - (cp)[3] = (value) >> 24; \ - (cp)[2] = (value) >> 16; \ - (cp)[1] = (value) >> 8; \ - (cp)[0] = (value); } while (0) - -#define H0 0x67452301U -#define H1 0xEFCDAB89U -#define H2 0x98BADCFEU -#define H3 0x10325476U -#define H4 0xC3D2E1F0U - -#define K0 0x00000000U -#define K1 0x5A827999U -#define K2 0x6ED9EBA1U -#define K3 0x8F1BBCDCU -#define K4 0xA953FD4EU - -#define KK0 0x50A28BE6U -#define KK1 0x5C4DD124U -#define KK2 0x6D703EF3U -#define KK3 0x7A6D76E9U -#define KK4 0x00000000U - -/* rotate x left n bits. */ -#define ROL(n, x) (((x) << (n)) | ((x) >> (32-(n)))) - -#define F0(x, y, z) ((x) ^ (y) ^ (z)) -#define F1(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define F2(x, y, z) (((x) | (~y)) ^ (z)) -#define F3(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define F4(x, y, z) ((x) ^ ((y) | (~z))) - -#define R(a, b, c, d, e, Fj, Kj, sj, rj) \ - do { \ - a = ROL(sj, a + Fj(b,c,d) + X(rj) + Kj) + e; \ - c = ROL(10, c); \ - } while(0) - -#define X(i) x[i] - -static u_int8_t PADDING[RMD160_BLOCK_LENGTH] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -void -RMD160Init(RMD160_CTX *ctx) -{ - ctx->count = 0; - ctx->state[0] = H0; - ctx->state[1] = H1; - ctx->state[2] = H2; - ctx->state[3] = H3; - ctx->state[4] = H4; -} - -void -RMD160Update(RMD160_CTX *ctx, const u_int8_t *input, size_t len) -{ - size_t have, off, need; - - have = (ctx->count / 8) % RMD160_BLOCK_LENGTH; - need = RMD160_BLOCK_LENGTH - have; - ctx->count += 8 * len; - off = 0; - - if (len >= need) { - if (have) { - memcpy(ctx->buffer + have, input, need); - RMD160Transform(ctx->state, ctx->buffer); - off = need; - have = 0; - } - /* now the buffer is empty */ - while (off + RMD160_BLOCK_LENGTH <= len) { - RMD160Transform(ctx->state, input+off); - off += RMD160_BLOCK_LENGTH; - } - } - if (off < len) - memcpy(ctx->buffer + have, input+off, len-off); -} - -void -RMD160Pad(RMD160_CTX *ctx) -{ - u_int8_t size[8]; - size_t padlen; - - PUT_64BIT_LE(size, ctx->count); - - /* - * pad to RMD160_BLOCK_LENGTH byte blocks, at least one byte from - * PADDING plus 8 bytes for the size - */ - padlen = RMD160_BLOCK_LENGTH - ((ctx->count / 8) % RMD160_BLOCK_LENGTH); - if (padlen < 1 + 8) - padlen += RMD160_BLOCK_LENGTH; - RMD160Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ - RMD160Update(ctx, size, 8); -} - -void -RMD160Final(u_int8_t digest[RMD160_DIGEST_LENGTH], RMD160_CTX *ctx) -{ - int i; - - RMD160Pad(ctx); - for (i = 0; i < 5; i++) - PUT_32BIT_LE(digest + i*4, ctx->state[i]); - memset(ctx, 0, sizeof (*ctx)); -} - -void -RMD160Transform(u_int32_t state[5], const u_int8_t block[RMD160_BLOCK_LENGTH]) -{ - u_int32_t a, b, c, d, e, aa, bb, cc, dd, ee, t, x[16]; - -#if BYTE_ORDER == LITTLE_ENDIAN - memcpy(x, block, RMD160_BLOCK_LENGTH); -#else - int i; - - for (i = 0; i < 16; i++) - x[i] = (u_int32_t)( - (u_int32_t)(block[i*4 + 0]) | - (u_int32_t)(block[i*4 + 1]) << 8 | - (u_int32_t)(block[i*4 + 2]) << 16 | - (u_int32_t)(block[i*4 + 3]) << 24); -#endif - - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - - /* Round 1 */ - R(a, b, c, d, e, F0, K0, 11, 0); - R(e, a, b, c, d, F0, K0, 14, 1); - R(d, e, a, b, c, F0, K0, 15, 2); - R(c, d, e, a, b, F0, K0, 12, 3); - R(b, c, d, e, a, F0, K0, 5, 4); - R(a, b, c, d, e, F0, K0, 8, 5); - R(e, a, b, c, d, F0, K0, 7, 6); - R(d, e, a, b, c, F0, K0, 9, 7); - R(c, d, e, a, b, F0, K0, 11, 8); - R(b, c, d, e, a, F0, K0, 13, 9); - R(a, b, c, d, e, F0, K0, 14, 10); - R(e, a, b, c, d, F0, K0, 15, 11); - R(d, e, a, b, c, F0, K0, 6, 12); - R(c, d, e, a, b, F0, K0, 7, 13); - R(b, c, d, e, a, F0, K0, 9, 14); - R(a, b, c, d, e, F0, K0, 8, 15); /* #15 */ - /* Round 2 */ - R(e, a, b, c, d, F1, K1, 7, 7); - R(d, e, a, b, c, F1, K1, 6, 4); - R(c, d, e, a, b, F1, K1, 8, 13); - R(b, c, d, e, a, F1, K1, 13, 1); - R(a, b, c, d, e, F1, K1, 11, 10); - R(e, a, b, c, d, F1, K1, 9, 6); - R(d, e, a, b, c, F1, K1, 7, 15); - R(c, d, e, a, b, F1, K1, 15, 3); - R(b, c, d, e, a, F1, K1, 7, 12); - R(a, b, c, d, e, F1, K1, 12, 0); - R(e, a, b, c, d, F1, K1, 15, 9); - R(d, e, a, b, c, F1, K1, 9, 5); - R(c, d, e, a, b, F1, K1, 11, 2); - R(b, c, d, e, a, F1, K1, 7, 14); - R(a, b, c, d, e, F1, K1, 13, 11); - R(e, a, b, c, d, F1, K1, 12, 8); /* #31 */ - /* Round 3 */ - R(d, e, a, b, c, F2, K2, 11, 3); - R(c, d, e, a, b, F2, K2, 13, 10); - R(b, c, d, e, a, F2, K2, 6, 14); - R(a, b, c, d, e, F2, K2, 7, 4); - R(e, a, b, c, d, F2, K2, 14, 9); - R(d, e, a, b, c, F2, K2, 9, 15); - R(c, d, e, a, b, F2, K2, 13, 8); - R(b, c, d, e, a, F2, K2, 15, 1); - R(a, b, c, d, e, F2, K2, 14, 2); - R(e, a, b, c, d, F2, K2, 8, 7); - R(d, e, a, b, c, F2, K2, 13, 0); - R(c, d, e, a, b, F2, K2, 6, 6); - R(b, c, d, e, a, F2, K2, 5, 13); - R(a, b, c, d, e, F2, K2, 12, 11); - R(e, a, b, c, d, F2, K2, 7, 5); - R(d, e, a, b, c, F2, K2, 5, 12); /* #47 */ - /* Round 4 */ - R(c, d, e, a, b, F3, K3, 11, 1); - R(b, c, d, e, a, F3, K3, 12, 9); - R(a, b, c, d, e, F3, K3, 14, 11); - R(e, a, b, c, d, F3, K3, 15, 10); - R(d, e, a, b, c, F3, K3, 14, 0); - R(c, d, e, a, b, F3, K3, 15, 8); - R(b, c, d, e, a, F3, K3, 9, 12); - R(a, b, c, d, e, F3, K3, 8, 4); - R(e, a, b, c, d, F3, K3, 9, 13); - R(d, e, a, b, c, F3, K3, 14, 3); - R(c, d, e, a, b, F3, K3, 5, 7); - R(b, c, d, e, a, F3, K3, 6, 15); - R(a, b, c, d, e, F3, K3, 8, 14); - R(e, a, b, c, d, F3, K3, 6, 5); - R(d, e, a, b, c, F3, K3, 5, 6); - R(c, d, e, a, b, F3, K3, 12, 2); /* #63 */ - /* Round 5 */ - R(b, c, d, e, a, F4, K4, 9, 4); - R(a, b, c, d, e, F4, K4, 15, 0); - R(e, a, b, c, d, F4, K4, 5, 5); - R(d, e, a, b, c, F4, K4, 11, 9); - R(c, d, e, a, b, F4, K4, 6, 7); - R(b, c, d, e, a, F4, K4, 8, 12); - R(a, b, c, d, e, F4, K4, 13, 2); - R(e, a, b, c, d, F4, K4, 12, 10); - R(d, e, a, b, c, F4, K4, 5, 14); - R(c, d, e, a, b, F4, K4, 12, 1); - R(b, c, d, e, a, F4, K4, 13, 3); - R(a, b, c, d, e, F4, K4, 14, 8); - R(e, a, b, c, d, F4, K4, 11, 11); - R(d, e, a, b, c, F4, K4, 8, 6); - R(c, d, e, a, b, F4, K4, 5, 15); - R(b, c, d, e, a, F4, K4, 6, 13); /* #79 */ - - aa = a ; bb = b; cc = c; dd = d; ee = e; - - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - - /* Parallel round 1 */ - R(a, b, c, d, e, F4, KK0, 8, 5); - R(e, a, b, c, d, F4, KK0, 9, 14); - R(d, e, a, b, c, F4, KK0, 9, 7); - R(c, d, e, a, b, F4, KK0, 11, 0); - R(b, c, d, e, a, F4, KK0, 13, 9); - R(a, b, c, d, e, F4, KK0, 15, 2); - R(e, a, b, c, d, F4, KK0, 15, 11); - R(d, e, a, b, c, F4, KK0, 5, 4); - R(c, d, e, a, b, F4, KK0, 7, 13); - R(b, c, d, e, a, F4, KK0, 7, 6); - R(a, b, c, d, e, F4, KK0, 8, 15); - R(e, a, b, c, d, F4, KK0, 11, 8); - R(d, e, a, b, c, F4, KK0, 14, 1); - R(c, d, e, a, b, F4, KK0, 14, 10); - R(b, c, d, e, a, F4, KK0, 12, 3); - R(a, b, c, d, e, F4, KK0, 6, 12); /* #15 */ - /* Parallel round 2 */ - R(e, a, b, c, d, F3, KK1, 9, 6); - R(d, e, a, b, c, F3, KK1, 13, 11); - R(c, d, e, a, b, F3, KK1, 15, 3); - R(b, c, d, e, a, F3, KK1, 7, 7); - R(a, b, c, d, e, F3, KK1, 12, 0); - R(e, a, b, c, d, F3, KK1, 8, 13); - R(d, e, a, b, c, F3, KK1, 9, 5); - R(c, d, e, a, b, F3, KK1, 11, 10); - R(b, c, d, e, a, F3, KK1, 7, 14); - R(a, b, c, d, e, F3, KK1, 7, 15); - R(e, a, b, c, d, F3, KK1, 12, 8); - R(d, e, a, b, c, F3, KK1, 7, 12); - R(c, d, e, a, b, F3, KK1, 6, 4); - R(b, c, d, e, a, F3, KK1, 15, 9); - R(a, b, c, d, e, F3, KK1, 13, 1); - R(e, a, b, c, d, F3, KK1, 11, 2); /* #31 */ - /* Parallel round 3 */ - R(d, e, a, b, c, F2, KK2, 9, 15); - R(c, d, e, a, b, F2, KK2, 7, 5); - R(b, c, d, e, a, F2, KK2, 15, 1); - R(a, b, c, d, e, F2, KK2, 11, 3); - R(e, a, b, c, d, F2, KK2, 8, 7); - R(d, e, a, b, c, F2, KK2, 6, 14); - R(c, d, e, a, b, F2, KK2, 6, 6); - R(b, c, d, e, a, F2, KK2, 14, 9); - R(a, b, c, d, e, F2, KK2, 12, 11); - R(e, a, b, c, d, F2, KK2, 13, 8); - R(d, e, a, b, c, F2, KK2, 5, 12); - R(c, d, e, a, b, F2, KK2, 14, 2); - R(b, c, d, e, a, F2, KK2, 13, 10); - R(a, b, c, d, e, F2, KK2, 13, 0); - R(e, a, b, c, d, F2, KK2, 7, 4); - R(d, e, a, b, c, F2, KK2, 5, 13); /* #47 */ - /* Parallel round 4 */ - R(c, d, e, a, b, F1, KK3, 15, 8); - R(b, c, d, e, a, F1, KK3, 5, 6); - R(a, b, c, d, e, F1, KK3, 8, 4); - R(e, a, b, c, d, F1, KK3, 11, 1); - R(d, e, a, b, c, F1, KK3, 14, 3); - R(c, d, e, a, b, F1, KK3, 14, 11); - R(b, c, d, e, a, F1, KK3, 6, 15); - R(a, b, c, d, e, F1, KK3, 14, 0); - R(e, a, b, c, d, F1, KK3, 6, 5); - R(d, e, a, b, c, F1, KK3, 9, 12); - R(c, d, e, a, b, F1, KK3, 12, 2); - R(b, c, d, e, a, F1, KK3, 9, 13); - R(a, b, c, d, e, F1, KK3, 12, 9); - R(e, a, b, c, d, F1, KK3, 5, 7); - R(d, e, a, b, c, F1, KK3, 15, 10); - R(c, d, e, a, b, F1, KK3, 8, 14); /* #63 */ - /* Parallel round 5 */ - R(b, c, d, e, a, F0, KK4, 8, 12); - R(a, b, c, d, e, F0, KK4, 5, 15); - R(e, a, b, c, d, F0, KK4, 12, 10); - R(d, e, a, b, c, F0, KK4, 9, 4); - R(c, d, e, a, b, F0, KK4, 12, 1); - R(b, c, d, e, a, F0, KK4, 5, 5); - R(a, b, c, d, e, F0, KK4, 14, 8); - R(e, a, b, c, d, F0, KK4, 6, 7); - R(d, e, a, b, c, F0, KK4, 8, 6); - R(c, d, e, a, b, F0, KK4, 13, 2); - R(b, c, d, e, a, F0, KK4, 6, 13); - R(a, b, c, d, e, F0, KK4, 5, 14); - R(e, a, b, c, d, F0, KK4, 15, 0); - R(d, e, a, b, c, F0, KK4, 13, 3); - R(c, d, e, a, b, F0, KK4, 11, 9); - R(b, c, d, e, a, F0, KK4, 11, 11); /* #79 */ - - t = state[1] + cc + d; - state[1] = state[2] + dd + e; - state[2] = state[3] + ee + a; - state[3] = state[4] + aa + b; - state[4] = state[0] + bb + c; - state[0] = t; -} - -#endif /* !WITH_OPENSSL */ diff --git a/openbsd-compat/rmd160.h b/openbsd-compat/rmd160.h deleted file mode 100644 index 99c1dcdc..00000000 --- a/openbsd-compat/rmd160.h +++ /dev/null @@ -1,61 +0,0 @@ -/* $OpenBSD: rmd160.h,v 1.17 2012/12/05 23:19:57 deraadt Exp $ */ -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef _RMD160_H -#define _RMD160_H - -#ifndef WITH_OPENSSL - -#define RMD160_BLOCK_LENGTH 64 -#define RMD160_DIGEST_LENGTH 20 -#define RMD160_DIGEST_STRING_LENGTH (RMD160_DIGEST_LENGTH * 2 + 1) - -/* RMD160 context. */ -typedef struct RMD160Context { - u_int32_t state[5]; /* state */ - u_int64_t count; /* number of bits, mod 2^64 */ - u_int8_t buffer[RMD160_BLOCK_LENGTH]; /* input buffer */ -} RMD160_CTX; - -void RMD160Init(RMD160_CTX *); -void RMD160Transform(u_int32_t [5], const u_int8_t [RMD160_BLOCK_LENGTH]) - __attribute__((__bounded__(__minbytes__,1,5))) - __attribute__((__bounded__(__minbytes__,2,RMD160_BLOCK_LENGTH))); -void RMD160Update(RMD160_CTX *, const u_int8_t *, size_t) - __attribute__((__bounded__(__string__,2,3))); -void RMD160Pad(RMD160_CTX *); -void RMD160Final(u_int8_t [RMD160_DIGEST_LENGTH], RMD160_CTX *) - __attribute__((__bounded__(__minbytes__,1,RMD160_DIGEST_LENGTH))); -char *RMD160End(RMD160_CTX *, char *) - __attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH))); -char *RMD160File(const char *, char *) - __attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH))); -char *RMD160FileChunk(const char *, char *, off_t, off_t) - __attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH))); -char *RMD160Data(const u_int8_t *, size_t, char *) - __attribute__((__bounded__(__string__,1,2))) - __attribute__((__bounded__(__minbytes__,3,RMD160_DIGEST_STRING_LENGTH))); - -#endif /* !WITH_OPENSSL */ -#endif /* _RMD160_H */ diff --git a/openbsd-compat/setproctitle.c b/openbsd-compat/setproctitle.c index 9f7ca14c..e4064323 100644 --- a/openbsd-compat/setproctitle.c +++ b/openbsd-compat/setproctitle.c @@ -36,6 +36,7 @@ #ifndef HAVE_SETPROCTITLE #include <stdarg.h> +#include <stdio.h> #include <stdlib.h> #include <unistd.h> #ifdef HAVE_SYS_PSTAT_H @@ -76,7 +77,7 @@ compat_init_setproctitle(int argc, char *argv[]) /* * NB: This assumes that argv has already been copied out of the - * way. This is true for sshd, but may not be true for other + * way. This is true for sshd, but may not be true for other * programs. Beware. */ @@ -92,7 +93,7 @@ compat_init_setproctitle(int argc, char *argv[]) } /* - * Find the last argv string or environment variable within + * Find the last argv string or environment variable within * our process memory area. */ for (i = 0; i < argc; i++) { @@ -108,8 +109,8 @@ compat_init_setproctitle(int argc, char *argv[]) argv_start = argv[0]; argv_env_len = lastargv - argv[0] - 1; - /* - * Copy environment + /* + * Copy environment * XXX - will truncate env on strdup fail */ for (i = 0; envp[i] != NULL; i++) @@ -125,7 +126,7 @@ setproctitle(const char *fmt, ...) #if SPT_TYPE != SPT_NONE va_list ap; char buf[1024], ptitle[1024]; - size_t len; + size_t len = 0; int r; extern char *__progname; #if SPT_TYPE == SPT_PSTAT @@ -156,7 +157,7 @@ setproctitle(const char *fmt, ...) pst.pst_command = ptitle; pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0); #elif SPT_TYPE == SPT_REUSEARGV -/* debug("setproctitle: copy \"%s\" into len %d", +/* debug("setproctitle: copy \"%s\" into len %d", buf, argv_env_len); */ len = strlcpy(argv_start, ptitle, argv_env_len); for(; len < argv_env_len; len++) diff --git a/openbsd-compat/sha1.c b/openbsd-compat/sha1.c index 4b5381f8..73f89748 100644 --- a/openbsd-compat/sha1.c +++ b/openbsd-compat/sha1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sha1.c,v 1.23 2014/01/08 06:14:57 tedu Exp $ */ +/* $OpenBSD: sha1.c,v 1.27 2019/06/07 22:56:36 dtucker Exp $ */ /* * SHA-1 in C @@ -18,7 +18,7 @@ #ifndef WITH_OPENSSL -#include <sys/param.h> +#include <sys/types.h> #include <string.h> #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) @@ -101,6 +101,7 @@ SHA1Transform(u_int32_t state[5], const u_int8_t buffer[SHA1_BLOCK_LENGTH]) /* Wipe variables */ a = b = c = d = e = 0; } +DEF_WEAK(SHA1Transform); /* @@ -118,6 +119,7 @@ SHA1Init(SHA1_CTX *context) context->state[3] = 0x10325476; context->state[4] = 0xC3D2E1F0; } +DEF_WEAK(SHA1Init); /* @@ -129,7 +131,7 @@ SHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len) size_t i, j; j = (size_t)((context->count >> 3) & 63); - context->count += (len << 3); + context->count += ((u_int64_t)len << 3); if ((j + len) > 63) { (void)memcpy(&context->buffer[j], data, (i = 64-j)); SHA1Transform(context->state, context->buffer); @@ -141,6 +143,7 @@ SHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len) } (void)memcpy(&context->buffer[j], &data[i], len - i); } +DEF_WEAK(SHA1Update); /* @@ -161,6 +164,7 @@ SHA1Pad(SHA1_CTX *context) SHA1Update(context, (u_int8_t *)"\0", 1); SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ } +DEF_WEAK(SHA1Pad); void SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) @@ -172,6 +176,7 @@ SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) digest[i] = (u_int8_t) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } - memset(context, 0, sizeof(*context)); + explicit_bzero(context, sizeof(*context)); } +DEF_WEAK(SHA1Final); #endif /* !WITH_OPENSSL */ diff --git a/openbsd-compat/sha2.c b/openbsd-compat/sha2.c index 737935d4..e36cc24e 100644 --- a/openbsd-compat/sha2.c +++ b/openbsd-compat/sha2.c @@ -1,4 +1,4 @@ -/* from OpenBSD: sha2.c,v 1.11 2005/08/08 08:05:35 espie Exp */ +/* $OpenBSD: sha2.c,v 1.28 2019/07/23 12:35:22 dtucker Exp $ */ /* * FILE: sha2.c @@ -38,18 +38,14 @@ #include "includes.h" -#ifdef WITH_OPENSSL -# include <openssl/opensslv.h> -# if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) -# define _NEED_SHA2 1 -# endif -#else -# define _NEED_SHA2 1 -#endif +#if !defined(HAVE_SHA256UPDATE) || !defined(HAVE_SHA384UPDATE) || \ + !defined(HAVE_SHA512UPDATE) -#if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) +/* no-op out, similar to DEF_WEAK but only needed here */ +#define MAKE_CLONE(x, y) void __ssh_compat_make_clone_##x_##y(void) #include <string.h> +#include <sha2.h> /* * UNROLLED TRANSFORM LOOP NOTE: @@ -64,15 +60,20 @@ * #define SHA2_UNROLL_TRANSFORM * */ +#ifndef SHA2_SMALL +#if defined(__amd64__) || defined(__i386__) +#define SHA2_UNROLL_TRANSFORM +#endif +#endif -/*** SHA-256/384/512 Machine Architecture Definitions *****************/ +/*** SHA-224/256/384/512 Machine Architecture Definitions *****************/ /* * BYTE_ORDER NOTE: * * Please make sure that your system defines BYTE_ORDER. If your * architecture is little-endian, make sure it also defines * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are - * equivilent. + * equivalent. * * If your system does not define the above, then you can do so by * hand like this: @@ -98,8 +99,9 @@ #endif -/*** SHA-256/384/512 Various Length Definitions ***********************/ +/*** SHA-224/256/384/512 Various Length Definitions ***********************/ /* NOTE: Most of these are in sha2.h */ +#define SHA224_SHORT_BLOCK_LENGTH (SHA224_BLOCK_LENGTH - 8) #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) #define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) @@ -152,22 +154,22 @@ * Bit shifting and rotation (used by the six SHA-XYZ logical functions: * * NOTE: The naming of R and S appears backwards here (R is a SHIFT and - * S is a ROTATION) because the SHA-256/384/512 description document + * S is a ROTATION) because the SHA-224/256/384/512 description document * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this * same "backwards" definition. */ -/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ +/* Shift-right (used in SHA-224, SHA-256, SHA-384, and SHA-512): */ #define R(b,x) ((x) >> (b)) -/* 32-bit Rotate-right (used in SHA-256): */ +/* 32-bit Rotate-right (used in SHA-224 and SHA-256): */ #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) -/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ +/* Two of six logical functions used in SHA-224, SHA-256, SHA-384, and SHA-512: */ #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) -/* Four of six logical functions used in SHA-256: */ +/* Four of six logical functions used in SHA-224 and SHA-256: */ #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) @@ -181,8 +183,8 @@ /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ -/* Hash constant words K for SHA-256: */ -const static u_int32_t K256[64] = { +/* Hash constant words K for SHA-224 and SHA-256: */ +static const u_int32_t K256[64] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, @@ -202,7 +204,7 @@ const static u_int32_t K256[64] = { }; /* Initial hash value H for SHA-256: */ -const static u_int32_t sha256_initial_hash_value[8] = { +static const u_int32_t sha256_initial_hash_value[8] = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, @@ -214,7 +216,7 @@ const static u_int32_t sha256_initial_hash_value[8] = { }; /* Hash constant words K for SHA-384 and SHA-512: */ -const static u_int64_t K512[80] = { +static const u_int64_t K512[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, @@ -257,8 +259,35 @@ const static u_int64_t K512[80] = { 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; +/* Initial hash value H for SHA-512 */ +static const u_int64_t sha512_initial_hash_value[8] = { + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL +}; + +#if !defined(SHA2_SMALL) +#if 0 +/* Initial hash value H for SHA-224: */ +static const u_int32_t sha224_initial_hash_value[8] = { + 0xc1059ed8UL, + 0x367cd507UL, + 0x3070dd17UL, + 0xf70e5939UL, + 0xffc00b31UL, + 0x68581511UL, + 0x64f98fa7UL, + 0xbefa4fa4UL +}; +#endif /* 0 */ + /* Initial hash value H for SHA-384 */ -const static u_int64_t sha384_initial_hash_value[8] = { +static const u_int64_t sha384_initial_hash_value[8] = { 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL, @@ -269,30 +298,67 @@ const static u_int64_t sha384_initial_hash_value[8] = { 0x47b5481dbefa4fa4ULL }; -/* Initial hash value H for SHA-512 */ -const static u_int64_t sha512_initial_hash_value[8] = { - 0x6a09e667f3bcc908ULL, - 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, - 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, - 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, - 0x5be0cd19137e2179ULL +#if 0 +/* Initial hash value H for SHA-512-256 */ +static const u_int64_t sha512_256_initial_hash_value[8] = { + 0x22312194fc2bf72cULL, + 0x9f555fa3c84c64c2ULL, + 0x2393b86b6f53b151ULL, + 0x963877195940eabdULL, + 0x96283ee2a88effe3ULL, + 0xbe5e1e2553863992ULL, + 0x2b0199fc2c85b8aaULL, + 0x0eb72ddc81c52ca2ULL }; +/*** SHA-224: *********************************************************/ +void +SHA224Init(SHA2_CTX *context) +{ + memcpy(context->state.st32, sha224_initial_hash_value, + sizeof(sha224_initial_hash_value)); + memset(context->buffer, 0, sizeof(context->buffer)); + context->bitcount[0] = 0; +} +DEF_WEAK(SHA224Init); + +MAKE_CLONE(SHA224Transform, SHA256Transform); +MAKE_CLONE(SHA224Update, SHA256Update); +MAKE_CLONE(SHA224Pad, SHA256Pad); +DEF_WEAK(SHA224Transform); +DEF_WEAK(SHA224Update); +DEF_WEAK(SHA224Pad); + +void +SHA224Final(u_int8_t digest[SHA224_DIGEST_LENGTH], SHA2_CTX *context) +{ + SHA224Pad(context); + +#if BYTE_ORDER == LITTLE_ENDIAN + int i; + + /* Convert TO host byte order */ + for (i = 0; i < 7; i++) + BE_32_TO_8(digest + i * 4, context->state.st32[i]); +#else + memcpy(digest, context->state.st32, SHA224_DIGEST_LENGTH); +#endif + explicit_bzero(context, sizeof(*context)); +} +DEF_WEAK(SHA224Final); +#endif /* !defined(SHA2_SMALL) */ +#endif /* 0 */ /*** SHA-256: *********************************************************/ void -SHA256_Init(SHA256_CTX *context) +SHA256Init(SHA2_CTX *context) { - if (context == NULL) - return; - memcpy(context->state, sha256_initial_hash_value, + memcpy(context->state.st32, sha256_initial_hash_value, sizeof(sha256_initial_hash_value)); memset(context->buffer, 0, sizeof(context->buffer)); - context->bitcount = 0; + context->bitcount[0] = 0; } +DEF_WEAK(SHA256Init); #ifdef SHA2_UNROLL_TRANSFORM @@ -320,7 +386,7 @@ SHA256_Init(SHA256_CTX *context) } while(0) void -SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) +SHA256Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) { u_int32_t a, b, c, d, e, f, g, h, s0, s1; u_int32_t T1, W256[16]; @@ -378,7 +444,7 @@ SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) #else /* SHA2_UNROLL_TRANSFORM */ void -SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) +SHA256Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) { u_int32_t a, b, c, d, e, f, g, h, s0, s1; u_int32_t T1, T2, W256[16]; @@ -451,17 +517,18 @@ SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) } #endif /* SHA2_UNROLL_TRANSFORM */ +DEF_WEAK(SHA256Transform); void -SHA256_Update(SHA256_CTX *context, const u_int8_t *data, size_t len) +SHA256Update(SHA2_CTX *context, const u_int8_t *data, size_t len) { - size_t freespace, usedspace; + u_int64_t freespace, usedspace; /* Calling with no data is valid (we do nothing) */ if (len == 0) return; - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA256_BLOCK_LENGTH - usedspace; @@ -469,14 +536,14 @@ SHA256_Update(SHA256_CTX *context, const u_int8_t *data, size_t len) if (len >= freespace) { /* Fill the buffer completely and process it */ memcpy(&context->buffer[usedspace], data, freespace); - context->bitcount += freespace << 3; + context->bitcount[0] += freespace << 3; len -= freespace; data += freespace; - SHA256_Transform(context->state, context->buffer); + SHA256Transform(context->state.st32, context->buffer); } else { /* The buffer is not yet full */ memcpy(&context->buffer[usedspace], data, len); - context->bitcount += len << 3; + context->bitcount[0] += (u_int64_t)len << 3; /* Clean up: */ usedspace = freespace = 0; return; @@ -484,26 +551,27 @@ SHA256_Update(SHA256_CTX *context, const u_int8_t *data, size_t len) } while (len >= SHA256_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ - SHA256_Transform(context->state, data); - context->bitcount += SHA256_BLOCK_LENGTH << 3; + SHA256Transform(context->state.st32, data); + context->bitcount[0] += SHA256_BLOCK_LENGTH << 3; len -= SHA256_BLOCK_LENGTH; data += SHA256_BLOCK_LENGTH; } if (len > 0) { /* There's left-overs, so save 'em */ memcpy(context->buffer, data, len); - context->bitcount += len << 3; + context->bitcount[0] += len << 3; } /* Clean up: */ usedspace = freespace = 0; } +DEF_WEAK(SHA256Update); void -SHA256_Pad(SHA256_CTX *context) +SHA256Pad(SHA2_CTX *context) { unsigned int usedspace; - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH; if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; @@ -518,7 +586,7 @@ SHA256_Pad(SHA256_CTX *context) SHA256_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ - SHA256_Transform(context->state, context->buffer); + SHA256Transform(context->state.st32, context->buffer); /* Prepare for last transform: */ memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); @@ -532,47 +600,45 @@ SHA256_Pad(SHA256_CTX *context) } /* Store the length of input data (in bits) in big endian format: */ BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], - context->bitcount); + context->bitcount[0]); /* Final transform: */ - SHA256_Transform(context->state, context->buffer); + SHA256Transform(context->state.st32, context->buffer); /* Clean up: */ usedspace = 0; } +DEF_WEAK(SHA256Pad); void -SHA256_Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA256_CTX *context) +SHA256Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA2_CTX *context) { - SHA256_Pad(context); + SHA256Pad(context); - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != NULL) { #if BYTE_ORDER == LITTLE_ENDIAN - int i; + int i; - /* Convert TO host byte order */ - for (i = 0; i < 8; i++) - BE_32_TO_8(digest + i * 4, context->state[i]); + /* Convert TO host byte order */ + for (i = 0; i < 8; i++) + BE_32_TO_8(digest + i * 4, context->state.st32[i]); #else - memcpy(digest, context->state, SHA256_DIGEST_LENGTH); + memcpy(digest, context->state.st32, SHA256_DIGEST_LENGTH); #endif - memset(context, 0, sizeof(*context)); - } + explicit_bzero(context, sizeof(*context)); } +DEF_WEAK(SHA256Final); /*** SHA-512: *********************************************************/ void -SHA512_Init(SHA512_CTX *context) +SHA512Init(SHA2_CTX *context) { - if (context == NULL) - return; - memcpy(context->state, sha512_initial_hash_value, + memcpy(context->state.st64, sha512_initial_hash_value, sizeof(sha512_initial_hash_value)); memset(context->buffer, 0, sizeof(context->buffer)); context->bitcount[0] = context->bitcount[1] = 0; } +DEF_WEAK(SHA512Init); #ifdef SHA2_UNROLL_TRANSFORM @@ -601,7 +667,7 @@ SHA512_Init(SHA512_CTX *context) } while(0) void -SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) +SHA512Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) { u_int64_t a, b, c, d, e, f, g, h, s0, s1; u_int64_t T1, W512[16]; @@ -659,7 +725,7 @@ SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) #else /* SHA2_UNROLL_TRANSFORM */ void -SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) +SHA512Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) { u_int64_t a, b, c, d, e, f, g, h, s0, s1; u_int64_t T1, T2, W512[16]; @@ -732,9 +798,10 @@ SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) } #endif /* SHA2_UNROLL_TRANSFORM */ +DEF_WEAK(SHA512Transform); void -SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len) +SHA512Update(SHA2_CTX *context, const u_int8_t *data, size_t len) { size_t freespace, usedspace; @@ -753,7 +820,7 @@ SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len) ADDINC128(context->bitcount, freespace << 3); len -= freespace; data += freespace; - SHA512_Transform(context->state, context->buffer); + SHA512Transform(context->state.st64, context->buffer); } else { /* The buffer is not yet full */ memcpy(&context->buffer[usedspace], data, len); @@ -765,7 +832,7 @@ SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len) } while (len >= SHA512_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ - SHA512_Transform(context->state, data); + SHA512Transform(context->state.st64, data); ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); len -= SHA512_BLOCK_LENGTH; data += SHA512_BLOCK_LENGTH; @@ -778,9 +845,10 @@ SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len) /* Clean up: */ usedspace = freespace = 0; } +DEF_WEAK(SHA512Update); void -SHA512_Pad(SHA512_CTX *context) +SHA512Pad(SHA2_CTX *context) { unsigned int usedspace; @@ -797,7 +865,7 @@ SHA512_Pad(SHA512_CTX *context) memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ - SHA512_Transform(context->state, context->buffer); + SHA512Transform(context->state.st64, context->buffer); /* And set-up for the last transform: */ memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2); @@ -816,89 +884,127 @@ SHA512_Pad(SHA512_CTX *context) context->bitcount[0]); /* Final transform: */ - SHA512_Transform(context->state, context->buffer); + SHA512Transform(context->state.st64, context->buffer); /* Clean up: */ usedspace = 0; } +DEF_WEAK(SHA512Pad); void -SHA512_Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA512_CTX *context) +SHA512Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA2_CTX *context) { - SHA512_Pad(context); + SHA512Pad(context); - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != NULL) { #if BYTE_ORDER == LITTLE_ENDIAN - int i; + int i; - /* Convert TO host byte order */ - for (i = 0; i < 8; i++) - BE_64_TO_8(digest + i * 8, context->state[i]); + /* Convert TO host byte order */ + for (i = 0; i < 8; i++) + BE_64_TO_8(digest + i * 8, context->state.st64[i]); #else - memcpy(digest, context->state, SHA512_DIGEST_LENGTH); + memcpy(digest, context->state.st64, SHA512_DIGEST_LENGTH); #endif - memset(context, 0, sizeof(*context)); - } + explicit_bzero(context, sizeof(*context)); } +DEF_WEAK(SHA512Final); +#if !defined(SHA2_SMALL) /*** SHA-384: *********************************************************/ void -SHA384_Init(SHA384_CTX *context) +SHA384Init(SHA2_CTX *context) { - if (context == NULL) - return; - memcpy(context->state, sha384_initial_hash_value, + memcpy(context->state.st64, sha384_initial_hash_value, sizeof(sha384_initial_hash_value)); memset(context->buffer, 0, sizeof(context->buffer)); context->bitcount[0] = context->bitcount[1] = 0; } +DEF_WEAK(SHA384Init); -#if 0 -__weak_alias(SHA384_Transform, SHA512_Transform); -__weak_alias(SHA384_Update, SHA512_Update); -__weak_alias(SHA384_Pad, SHA512_Pad); -#endif +MAKE_CLONE(SHA384Transform, SHA512Transform); +MAKE_CLONE(SHA384Update, SHA512Update); +MAKE_CLONE(SHA384Pad, SHA512Pad); +DEF_WEAK(SHA384Transform); +DEF_WEAK(SHA384Update); +DEF_WEAK(SHA384Pad); +/* Equivalent of MAKE_CLONE (which is a no-op) for SHA384 funcs */ void -SHA384_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) +SHA384Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) { - return SHA512_Transform(state, data); + SHA512Transform(state, data); } void -SHA384_Update(SHA512_CTX *context, const u_int8_t *data, size_t len) +SHA384Update(SHA2_CTX *context, const u_int8_t *data, size_t len) { - SHA512_Update(context, data, len); + SHA512Update(context, data, len); } void -SHA384_Pad(SHA512_CTX *context) +SHA384Pad(SHA2_CTX *context) { - SHA512_Pad(context); + SHA512Pad(context); } void -SHA384_Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA384_CTX *context) +SHA384Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA2_CTX *context) { - SHA384_Pad(context); + SHA384Pad(context); - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != NULL) { #if BYTE_ORDER == LITTLE_ENDIAN - int i; + int i; - /* Convert TO host byte order */ - for (i = 0; i < 6; i++) - BE_64_TO_8(digest + i * 8, context->state[i]); + /* Convert TO host byte order */ + for (i = 0; i < 6; i++) + BE_64_TO_8(digest + i * 8, context->state.st64[i]); #else - memcpy(digest, context->state, SHA384_DIGEST_LENGTH); + memcpy(digest, context->state.st64, SHA384_DIGEST_LENGTH); #endif - } + /* Zero out state data */ + explicit_bzero(context, sizeof(*context)); +} +DEF_WEAK(SHA384Final); + +#if 0 +/*** SHA-512/256: *********************************************************/ +void +SHA512_256Init(SHA2_CTX *context) +{ + memcpy(context->state.st64, sha512_256_initial_hash_value, + sizeof(sha512_256_initial_hash_value)); + memset(context->buffer, 0, sizeof(context->buffer)); + context->bitcount[0] = context->bitcount[1] = 0; +} +DEF_WEAK(SHA512_256Init); +MAKE_CLONE(SHA512_256Transform, SHA512Transform); +MAKE_CLONE(SHA512_256Update, SHA512Update); +MAKE_CLONE(SHA512_256Pad, SHA512Pad); +DEF_WEAK(SHA512_256Transform); +DEF_WEAK(SHA512_256Update); +DEF_WEAK(SHA512_256Pad); + +void +SHA512_256Final(u_int8_t digest[SHA512_256_DIGEST_LENGTH], SHA2_CTX *context) +{ + SHA512_256Pad(context); + +#if BYTE_ORDER == LITTLE_ENDIAN + int i; + + /* Convert TO host byte order */ + for (i = 0; i < 4; i++) + BE_64_TO_8(digest + i * 8, context->state.st64[i]); +#else + memcpy(digest, context->state.st64, SHA512_256_DIGEST_LENGTH); +#endif /* Zero out state data */ - memset(context, 0, sizeof(*context)); + explicit_bzero(context, sizeof(*context)); } +DEF_WEAK(SHA512_256Final); +#endif /* !defined(SHA2_SMALL) */ +#endif /* 0 */ -#endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */ +#endif /* HAVE_SHA{256,384,512}UPDATE */ diff --git a/openbsd-compat/sha2.h b/openbsd-compat/sha2.h index c8bfc3cd..d051e96e 100644 --- a/openbsd-compat/sha2.h +++ b/openbsd-compat/sha2.h @@ -1,4 +1,4 @@ -/* OpenBSD: sha2.h,v 1.6 2004/06/22 01:57:30 jfb Exp */ +/* $OpenBSD: sha2.h,v 1.10 2016/09/03 17:00:29 tedu Exp $ */ /* * FILE: sha2.h @@ -41,18 +41,13 @@ #include "includes.h" -#ifdef WITH_OPENSSL -# include <openssl/opensslv.h> -# if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) -# define _NEED_SHA2 1 -# endif -#else -# define _NEED_SHA2 1 -#endif - -#if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) +#if !defined(HAVE_SHA256UPDATE) || !defined(HAVE_SHA384UPDATE) || \ + !defined(HAVE_SHA512UPDATE) /*** SHA-256/384/512 Various Length Definitions ***********************/ +#define SHA224_BLOCK_LENGTH 64 +#define SHA224_DIGEST_LENGTH 28 +#define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1) #define SHA256_BLOCK_LENGTH 64 #define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) @@ -62,73 +57,118 @@ #define SHA512_BLOCK_LENGTH 128 #define SHA512_DIGEST_LENGTH 64 #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) +#define SHA512_256_BLOCK_LENGTH 128 +#define SHA512_256_DIGEST_LENGTH 32 +#define SHA512_256_DIGEST_STRING_LENGTH (SHA512_256_DIGEST_LENGTH * 2 + 1) -/*** SHA-256/384/512 Context Structures *******************************/ -typedef struct _SHA256_CTX { - u_int32_t state[8]; - u_int64_t bitcount; - u_int8_t buffer[SHA256_BLOCK_LENGTH]; -} SHA256_CTX; -typedef struct _SHA512_CTX { - u_int64_t state[8]; +/*** SHA-224/256/384/512 Context Structure *******************************/ +typedef struct _SHA2_CTX { + union { + u_int32_t st32[8]; + u_int64_t st64[8]; + } state; u_int64_t bitcount[2]; u_int8_t buffer[SHA512_BLOCK_LENGTH]; -} SHA512_CTX; +} SHA2_CTX; -typedef SHA512_CTX SHA384_CTX; +#if 0 +__BEGIN_DECLS +void SHA224Init(SHA2_CTX *); +void SHA224Transform(u_int32_t state[8], const u_int8_t [SHA224_BLOCK_LENGTH]); +void SHA224Update(SHA2_CTX *, const u_int8_t *, size_t) + __attribute__((__bounded__(__string__,2,3))); +void SHA224Pad(SHA2_CTX *); +void SHA224Final(u_int8_t [SHA224_DIGEST_LENGTH], SHA2_CTX *) + __attribute__((__bounded__(__minbytes__,1,SHA224_DIGEST_LENGTH))); +char *SHA224End(SHA2_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA224_DIGEST_STRING_LENGTH))); +char *SHA224File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA224_DIGEST_STRING_LENGTH))); +char *SHA224FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,SHA224_DIGEST_STRING_LENGTH))); +char *SHA224Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,SHA224_DIGEST_STRING_LENGTH))); +#endif /* 0 */ -void SHA256_Init(SHA256_CTX *); -void SHA256_Transform(u_int32_t state[8], const u_int8_t [SHA256_BLOCK_LENGTH]); -void SHA256_Update(SHA256_CTX *, const u_int8_t *, size_t) +#ifndef HAVE_SHA256UPDATE +void SHA256Init(SHA2_CTX *); +void SHA256Transform(u_int32_t state[8], const u_int8_t [SHA256_BLOCK_LENGTH]); +void SHA256Update(SHA2_CTX *, const u_int8_t *, size_t) __attribute__((__bounded__(__string__,2,3))); -void SHA256_Pad(SHA256_CTX *); -void SHA256_Final(u_int8_t [SHA256_DIGEST_LENGTH], SHA256_CTX *) +void SHA256Pad(SHA2_CTX *); +void SHA256Final(u_int8_t [SHA256_DIGEST_LENGTH], SHA2_CTX *) __attribute__((__bounded__(__minbytes__,1,SHA256_DIGEST_LENGTH))); -char *SHA256_End(SHA256_CTX *, char *) +char *SHA256End(SHA2_CTX *, char *) __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); -char *SHA256_File(const char *, char *) +char *SHA256File(const char *, char *) __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); -char *SHA256_FileChunk(const char *, char *, off_t, off_t) +char *SHA256FileChunk(const char *, char *, off_t, off_t) __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); -char *SHA256_Data(const u_int8_t *, size_t, char *) +char *SHA256Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA256_DIGEST_STRING_LENGTH))); +#endif /* HAVE_SHA256UPDATE */ -void SHA384_Init(SHA384_CTX *); -void SHA384_Transform(u_int64_t state[8], const u_int8_t [SHA384_BLOCK_LENGTH]); -void SHA384_Update(SHA384_CTX *, const u_int8_t *, size_t) +#ifndef HAVE_SHA384UPDATE +void SHA384Init(SHA2_CTX *); +void SHA384Transform(u_int64_t state[8], const u_int8_t [SHA384_BLOCK_LENGTH]); +void SHA384Update(SHA2_CTX *, const u_int8_t *, size_t) __attribute__((__bounded__(__string__,2,3))); -void SHA384_Pad(SHA384_CTX *); -void SHA384_Final(u_int8_t [SHA384_DIGEST_LENGTH], SHA384_CTX *) +void SHA384Pad(SHA2_CTX *); +void SHA384Final(u_int8_t [SHA384_DIGEST_LENGTH], SHA2_CTX *) __attribute__((__bounded__(__minbytes__,1,SHA384_DIGEST_LENGTH))); -char *SHA384_End(SHA384_CTX *, char *) +char *SHA384End(SHA2_CTX *, char *) __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); -char *SHA384_File(const char *, char *) +char *SHA384File(const char *, char *) __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); -char *SHA384_FileChunk(const char *, char *, off_t, off_t) +char *SHA384FileChunk(const char *, char *, off_t, off_t) __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); -char *SHA384_Data(const u_int8_t *, size_t, char *) +char *SHA384Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA384_DIGEST_STRING_LENGTH))); +#endif /* HAVE_SHA384UPDATE */ -void SHA512_Init(SHA512_CTX *); -void SHA512_Transform(u_int64_t state[8], const u_int8_t [SHA512_BLOCK_LENGTH]); -void SHA512_Update(SHA512_CTX *, const u_int8_t *, size_t) +#ifndef HAVE_SHA512UPDATE +void SHA512Init(SHA2_CTX *); +void SHA512Transform(u_int64_t state[8], const u_int8_t [SHA512_BLOCK_LENGTH]); +void SHA512Update(SHA2_CTX *, const u_int8_t *, size_t) __attribute__((__bounded__(__string__,2,3))); -void SHA512_Pad(SHA512_CTX *); -void SHA512_Final(u_int8_t [SHA512_DIGEST_LENGTH], SHA512_CTX *) +void SHA512Pad(SHA2_CTX *); +void SHA512Final(u_int8_t [SHA512_DIGEST_LENGTH], SHA2_CTX *) __attribute__((__bounded__(__minbytes__,1,SHA512_DIGEST_LENGTH))); -char *SHA512_End(SHA512_CTX *, char *) +char *SHA512End(SHA2_CTX *, char *) __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); -char *SHA512_File(const char *, char *) +char *SHA512File(const char *, char *) __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); -char *SHA512_FileChunk(const char *, char *, off_t, off_t) +char *SHA512FileChunk(const char *, char *, off_t, off_t) __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); -char *SHA512_Data(const u_int8_t *, size_t, char *) +char *SHA512Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA512_DIGEST_STRING_LENGTH))); +#endif /* HAVE_SHA512UPDATE */ + +#if 0 +void SHA512_256Init(SHA2_CTX *); +void SHA512_256Transform(u_int64_t state[8], const u_int8_t [SHA512_256_BLOCK_LENGTH]); +void SHA512_256Update(SHA2_CTX *, const u_int8_t *, size_t) + __attribute__((__bounded__(__string__,2,3))); +void SHA512_256Pad(SHA2_CTX *); +void SHA512_256Final(u_int8_t [SHA512_256_DIGEST_LENGTH], SHA2_CTX *) + __attribute__((__bounded__(__minbytes__,1,SHA512_256_DIGEST_LENGTH))); +char *SHA512_256End(SHA2_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA512_256_DIGEST_STRING_LENGTH))); +char *SHA512_256File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA512_256_DIGEST_STRING_LENGTH))); +char *SHA512_256FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,SHA512_256_DIGEST_STRING_LENGTH))); +char *SHA512_256Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,SHA512_256_DIGEST_STRING_LENGTH))); +__END_DECLS +#endif /* 0 */ -#endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */ +#endif /* HAVE_SHA{256,384,512}UPDATE */ #endif /* _SSHSHA2_H */ diff --git a/openbsd-compat/strcasestr.c b/openbsd-compat/strcasestr.c new file mode 100644 index 00000000..4c4d1475 --- /dev/null +++ b/openbsd-compat/strcasestr.c @@ -0,0 +1,69 @@ +/* $OpenBSD: strcasestr.c,v 1.4 2015/08/31 02:53:57 guenther Exp $ */ +/* $NetBSD: strcasestr.c,v 1.2 2005/02/09 21:35:47 kleink Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strcasestr.c */ + +#include "includes.h" + +#ifndef HAVE_STRCASESTR + +#include <ctype.h> +#include <string.h> + +/* + * Find the first occurrence of find in s, ignore case. + */ +char * +strcasestr(const char *s, const char *find) +{ + char c, sc; + size_t len; + + if ((c = *find++) != 0) { + c = (char)tolower((unsigned char)c); + len = strlen(find); + do { + do { + if ((sc = *s++) == 0) + return (NULL); + } while ((char)tolower((unsigned char)sc) != c); + } while (strncasecmp(s, find, len) != 0); + s--; + } + return ((char *)s); +} +DEF_WEAK(strcasestr); + +#endif diff --git a/openbsd-compat/strndup.c b/openbsd-compat/strndup.c new file mode 100644 index 00000000..30ac6f04 --- /dev/null +++ b/openbsd-compat/strndup.c @@ -0,0 +1,43 @@ +/* $OpenBSD: strndup.c,v 1.2 2015/08/31 02:53:57 guenther Exp $ */ + +/* + * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" +#if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP) +#include <sys/types.h> + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +char * +strndup(const char *str, size_t maxlen) +{ + char *copy; + size_t len; + + len = strnlen(str, maxlen); + copy = malloc(len + 1); + if (copy != NULL) { + (void)memcpy(copy, str, len); + copy[len] = '\0'; + } + + return copy; +} +DEF_WEAK(strndup); +#endif /* HAVE_STRNDUP */ diff --git a/openbsd-compat/strnlen.c b/openbsd-compat/strnlen.c index 93d51559..7ad3573a 100644 --- a/openbsd-compat/strnlen.c +++ b/openbsd-compat/strnlen.c @@ -18,8 +18,8 @@ /* OPENBSD ORIGINAL: lib/libc/string/strnlen.c */ -#include "config.h" -#ifndef HAVE_STRNLEN +#include "includes.h" +#if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN) #include <sys/types.h> #include <string.h> diff --git a/openbsd-compat/sys-queue.h b/openbsd-compat/sys-queue.h index 28aaaa37..5108f394 100644 --- a/openbsd-compat/sys-queue.h +++ b/openbsd-compat/sys-queue.h @@ -45,6 +45,7 @@ #undef SLIST_HEAD_INITIALIZER #undef SLIST_ENTRY #undef SLIST_FOREACH_PREVPTR +#undef SLIST_FOREACH_SAFE #undef SLIST_FIRST #undef SLIST_END #undef SLIST_EMPTY @@ -54,6 +55,7 @@ #undef SLIST_INSERT_AFTER #undef SLIST_INSERT_HEAD #undef SLIST_REMOVE_HEAD +#undef SLIST_REMOVE_AFTER #undef SLIST_REMOVE #undef SLIST_REMOVE_NEXT #undef LIST_HEAD @@ -64,6 +66,7 @@ #undef LIST_EMPTY #undef LIST_NEXT #undef LIST_FOREACH +#undef LIST_FOREACH_SAFE #undef LIST_INIT #undef LIST_INSERT_AFTER #undef LIST_INSERT_BEFORE @@ -78,6 +81,7 @@ #undef SIMPLEQ_EMPTY #undef SIMPLEQ_NEXT #undef SIMPLEQ_FOREACH +#undef SIMPLEQ_FOREACH_SAFE #undef SIMPLEQ_INIT #undef SIMPLEQ_INSERT_HEAD #undef SIMPLEQ_INSERT_TAIL @@ -94,6 +98,8 @@ #undef TAILQ_EMPTY #undef TAILQ_FOREACH #undef TAILQ_FOREACH_REVERSE +#undef TAILQ_FOREACH_SAFE +#undef TAILQ_FOREACH_REVERSE_SAFE #undef TAILQ_INIT #undef TAILQ_INSERT_HEAD #undef TAILQ_INSERT_TAIL diff --git a/openbsd-compat/vis.c b/openbsd-compat/vis.c index f6f5665c..0e04ed02 100644 --- a/openbsd-compat/vis.c +++ b/openbsd-compat/vis.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vis.c,v 1.19 2005/09/01 17:15:49 millert Exp $ */ +/* $OpenBSD: vis.c,v 1.25 2015/09/13 11:32:51 guenther Exp $ */ /*- * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -33,13 +33,18 @@ #include "includes.h" #if !defined(HAVE_STRNVIS) || defined(BROKEN_STRNVIS) +#include <sys/types.h> +#include <errno.h> #include <ctype.h> +#include <limits.h> #include <string.h> +#include <stdlib.h> #include "vis.h" #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') -#define isvisible(c) \ +#define isvisible(c,flag) \ + (((c) == '\\' || (flag & VIS_ALL) == 0) && \ (((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) && \ (((c) != '*' && (c) != '?' && (c) != '[' && (c) != '#') || \ (flag & VIS_GLOB) == 0) && isgraph((u_char)(c))) || \ @@ -48,7 +53,7 @@ ((flag & VIS_NL) == 0 && (c) == '\n') || \ ((flag & VIS_SAFE) && ((c) == '\b' || \ (c) == '\007' || (c) == '\r' || \ - isgraph((u_char)(c))))) + isgraph((u_char)(c)))))) /* * vis - visually encode characters @@ -56,10 +61,11 @@ char * vis(char *dst, int c, int flag, int nextc) { - if (isvisible(c)) { - *dst++ = c; - if (c == '\\' && (flag & VIS_NOSLASH) == 0) + if (isvisible(c, flag)) { + if ((c == '"' && (flag & VIS_DQ) != 0) || + (c == '\\' && (flag & VIS_NOSLASH) == 0)) *dst++ = '\\'; + *dst++ = c; *dst = '\0'; return (dst); } @@ -136,6 +142,7 @@ done: *dst = '\0'; return (dst); } +DEF_WEAK(vis); /* * strvis, strnvis, strvisx - visually encode characters from src into dst @@ -161,6 +168,7 @@ strvis(char *dst, const char *src, int flag) *dst = '\0'; return (dst - start); } +DEF_WEAK(strvis); int strnvis(char *dst, const char *src, size_t siz, int flag) @@ -171,19 +179,18 @@ strnvis(char *dst, const char *src, size_t siz, int flag) i = 0; for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) { - if (isvisible(c)) { - i = 1; - *dst++ = c; - if (c == '\\' && (flag & VIS_NOSLASH) == 0) { + if (isvisible(c, flag)) { + if ((c == '"' && (flag & VIS_DQ) != 0) || + (c == '\\' && (flag & VIS_NOSLASH) == 0)) { /* need space for the extra '\\' */ - if (dst < end) - *dst++ = '\\'; - else { - dst--; + if (dst + 1 >= end) { i = 2; break; } + *dst++ = '\\'; } + i = 1; + *dst++ = c; src++; } else { i = vis(tbuf, c, flag, *++src) - tbuf; @@ -207,6 +214,25 @@ strnvis(char *dst, const char *src, size_t siz, int flag) } int +stravis(char **outp, const char *src, int flag) +{ + char *buf; + int len, serrno; + + buf = reallocarray(NULL, 4, strlen(src) + 1); + if (buf == NULL) + return -1; + len = strvis(buf, src, flag); + serrno = errno; + *outp = realloc(buf, len + 1); + if (*outp == NULL) { + *outp = buf; + errno = serrno; + } + return (len); +} + +int strvisx(char *dst, const char *src, size_t len, int flag) { char c; diff --git a/openbsd-compat/vis.h b/openbsd-compat/vis.h index d1286c99..2cdfd364 100644 --- a/openbsd-compat/vis.h +++ b/openbsd-compat/vis.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vis.h,v 1.11 2005/08/09 19:38:31 millert Exp $ */ +/* $OpenBSD: vis.h,v 1.15 2015/07/20 01:52:27 millert Exp $ */ /* $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $ */ /*- @@ -58,6 +58,8 @@ #define VIS_NL 0x10 /* also encode newline */ #define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) #define VIS_SAFE 0x20 /* only encode "unsafe" characters */ +#define VIS_DQ 0x200 /* backslash-escape double quotes */ +#define VIS_ALL 0x400 /* encode all characters */ /* * other @@ -81,6 +83,7 @@ char *vis(char *, int, int, int); int strvis(char *, const char *, int); +int stravis(char **, const char *, int); int strnvis(char *, const char *, size_t, int) __attribute__ ((__bounded__(__string__,1,3))); int strvisx(char *, const char *, size_t, int) diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c index 8577cbd8..360b187a 100644 --- a/openbsd-compat/xcrypt.c +++ b/openbsd-compat/xcrypt.c @@ -25,6 +25,7 @@ #include "includes.h" #include <sys/types.h> +#include <string.h> #include <unistd.h> #include <pwd.h> @@ -41,7 +42,7 @@ # include <sys/security.h> # include <sys/audit.h> # include <prot.h> -# endif +# endif # if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) # include <shadow.h> @@ -62,26 +63,66 @@ # define crypt DES_crypt # endif +/* + * Pick an appropriate password encryption type and salt for the running + * system by searching through accounts until we find one that has a valid + * salt. Usually this will be root unless the root account is locked out. + * If we don't find one we return a traditional DES-based salt. + */ +static const char * +pick_salt(void) +{ + struct passwd *pw; + char *passwd, *p; + size_t typelen; + static char salt[32]; + + if (salt[0] != '\0') + return salt; + strlcpy(salt, "xx", sizeof(salt)); + setpwent(); + while ((pw = getpwent()) != NULL) { + if ((passwd = shadow_pw(pw)) == NULL) + continue; + if (passwd[0] == '$' && (p = strrchr(passwd+1, '$')) != NULL) { + typelen = p - passwd + 1; + strlcpy(salt, passwd, MIN(typelen, sizeof(salt))); + explicit_bzero(passwd, strlen(passwd)); + goto out; + } + } + out: + endpwent(); + return salt; +} + char * xcrypt(const char *password, const char *salt) { char *crypted; + /* + * If we don't have a salt we are encrypting a fake password for + * for timing purposes. Pick an appropriate salt. + */ + if (salt == NULL) + salt = pick_salt(); + # ifdef HAVE_MD5_PASSWORDS - if (is_md5_salt(salt)) - crypted = md5_crypt(password, salt); - else - crypted = crypt(password, salt); + if (is_md5_salt(salt)) + crypted = md5_crypt(password, salt); + else + crypted = crypt(password, salt); # elif defined(__hpux) && !defined(HAVE_SECUREWARE) if (iscomsec()) - crypted = bigcrypt(password, salt); - else - crypted = crypt(password, salt); + crypted = bigcrypt(password, salt); + else + crypted = crypt(password, salt); # elif defined(HAVE_SECUREWARE) - crypted = bigcrypt(password, salt); + crypted = bigcrypt(password, salt); # else - crypted = crypt(password, salt); -# endif + crypted = crypt(password, salt); +# endif return crypted; } diff --git a/openbsd-compat/xmmap.c b/openbsd-compat/xmmap.c deleted file mode 100644 index 04c6babc..00000000 --- a/openbsd-compat/xmmap.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2002 Tim Rice. All rights reserved. - * MAP_FAILED code by Solar Designer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* $Id: xmmap.c,v 1.15 2009/02/16 04:21:40 djm Exp $ */ - -#include "includes.h" - -#include <sys/types.h> -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif -#include <sys/stat.h> - -#ifdef HAVE_FCNTL_H -# include <fcntl.h> -#endif -#include <errno.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "log.h" - -void * -xmmap(size_t size) -{ -#ifdef HAVE_MMAP - void *address; - -# ifdef MAP_ANON - address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED, - -1, (off_t)0); -# else - address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, - open("/dev/zero", O_RDWR), (off_t)0); -# endif - -#define MM_SWAP_TEMPLATE "/var/run/sshd.mm.XXXXXXXX" - if (address == (void *)MAP_FAILED) { - char tmpname[sizeof(MM_SWAP_TEMPLATE)] = MM_SWAP_TEMPLATE; - int tmpfd; - mode_t old_umask; - - old_umask = umask(0177); - tmpfd = mkstemp(tmpname); - umask(old_umask); - if (tmpfd == -1) - fatal("mkstemp(\"%s\"): %s", - MM_SWAP_TEMPLATE, strerror(errno)); - unlink(tmpname); - if (ftruncate(tmpfd, size) != 0) - fatal("%s: ftruncate: %s", __func__, strerror(errno)); - address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, - tmpfd, (off_t)0); - close(tmpfd); - } - - return (address); -#else - fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported", - __func__); -#endif /* HAVE_MMAP */ - -} - |