commit d5b81b8ed2aada3392713dd449929865cc37bf62 Author: Brent Cook Date: Sat Dec 27 23:39:37 2014 -0600 new OpenNTPD portable tree First attempt at building a new OpenNTPD portable project, based on the latest OpenBSD source. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aead0d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,76 @@ + +*.y +*.5 +*.8 +*.o +*.la +*.lo + +.deps +.dirstamp +.libs + +ntpd +openbsd + +aclocal.m4 +autom4te.cache/ +compile +config.guess +config.log +config.status +config.sub +configure +depcomp +install-sh +libtool +ltmain.sh +m4/ +missing +ylwrap +Makefile +Makefile.in + +compat/arc4random.c +compat/arc4random_freebsd.h +compat/arc4random_linux.h +compat/arc4random_osx.h +compat/arc4random_solaris.h +compat/arc4random_uniform.c +compat/arc4random_win.h +compat/chacha_private.h +compat/explicit_bzero.c +compat/getentropy_freebsd.c +compat/getentropy_linux.c +compat/getentropy_osx.c +compat/getentropy_solaris.c +compat/getentropy_win.c +compat/imsg-buffer.c +compat/imsg.c +compat/md5.c +compat/reallocarray.c +compat/strlcat.c +compat/strlcpy.c +compat/strndup.c +compat/strnlen.c +compat/strtonum.c + +client.c +config.c +control.c +include/imsg.h +include/md5.h +include/stdlib.h +include/string.h +include/sys/ +log.c +ntp.c +ntp.h +ntp_dns.c +ntp_msg.c +ntpd.c +ntpd.h +parse.c +sensors.c +server.c +util.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..4e2fdf6 --- /dev/null +++ b/COPYING @@ -0,0 +1,31 @@ +This is a summary of the licences for the files that make up Portable +OpenNTPD. + +Apart from the exceptions listed below, all of the files are under an +ISC-style licence with the following copyright holders, first for the +files from OpenBSD's ntpd: + +Henning Brauer +Alexander Guy + +and the portability layer: + +Darren Tucker +Damien Miller +Internet Software Consortium +Todd C. Miller +Anthony O.Zabelin + +/* + * 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 MIND, 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. + */ diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..db8995a --- /dev/null +++ b/INSTALL @@ -0,0 +1,90 @@ +1. Prerequisites +---------------- + +You will need an entropy (randomness) source. If your OS has arc4random or +getentropy then that is ideal. Otherwise, you can use the builtin arc4random +implementation or the one built into LibreSSL. + +2. Building / Installation +-------------------------- + +To install OpenNTPD with default options: + +./configure +make +make install + +This will install the OpenNTPD binary in /usr/local/sbin, configuration +files in /usr/local/etc. To specify a different installation prefix, +use the --prefix option to configure: + +./configure --prefix=/opt +make +make install + +Will install OpenNTPD in /opt/{etc,sbin}. You can also override +specific paths, for example: + +./configure --prefix=/opt --sysconfdir=/etc/ntp +make +make install + +This will install the binaries in /opt/sbin, but will place the +configuration files in /etc/ntp. + +OpenNTPD always uses Privilege Separation (ie the majority of the +processing is done as a chroot'ed, unprivileged user). + +This requires that a user, group and directory to be created for it. +The user should not be permitted to log in, and its home directory +should be owned by root and be mode 755. + +If you do "make install", the Makefile will create the directory with +the correct permissions and will prompt you for the rest if required. +If, however, you need to perform all of these tasks yourself (eg if you +are moving the built binaries to another system) then you will need to +do something like the following (although the exact commands required +for creating the user and group are system dependant): + +# groupadd _ntp +# useradd -g _ntp -s /sbin/nologin -d /var/empty/ntp -c 'OpenNTP daemon' _ntp +# mkdir -p /var/empty/ntp +# chown 0 /var/empty/ntp +# chgrp 0 /var/empty/ntp +# chmod 0755 /var/empty/ntp + +There are a few options to the configure script in addition to the ones +provided by autoconf itself: + +--with-privsep-user=[user] + Specify unprivileged user used for privilege separation. The default + is "_ntp". + +--with-privsep-path=path + Normally ntpd will always use the home directory of the privsep user + to chroot to, however use of this option will cause ntpd to always + use the specified directory. + +If you need to pass special options to the compiler or linker, you +can specify these as environment variables before running ./configure. +For example: + +CFLAGS="-O -m486" LDFLAGS="-s" LIBS="-lrubbish" LD="/usr/foo/ld" ./configure + + +3. Configuration +---------------- + +The runtime configuration files are installed by in ${prefix}/etc or +whatever you specified as your --sysconfdir (/usr/local/etc by default). + +If no configuration file exists, the default one is used. The default +configuration file uses a selection of publicly accessible "pool" servers +(see http://twiki.ntp.org/bin/view/Servers/NTPPoolServers). + + +4. Problems? +------------ + +If you experience problems compiling, installing or running OpenNTPD, +please report the problem to the address in the README file. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..9ba8cf2 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,129 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include +SUBDIRS = include + +ACLOCAL_AMFLAGS = -Im4 +EXTRA_DIST = VERSION +CLEANFILES = parse.c + +sbin_PROGRAMS = ntpd +noinst_LTLIBRARIES = libcompat.la libcompatnoopt.la +dist_man_MANS = ntpctl.8 ntpd.8 ntpd.conf.5 + +ntpd_CFLAGS = $(CFLAGS) $(USER_CFLAGS) +ntpd_LDADD = $(PLATFORM_LDADD) $(PROG_LDADD) libcompat.la libcompatnoopt.la + +ntpd_SOURCES = client.c +ntpd_SOURCES += config.c +ntpd_SOURCES += control.c +ntpd_SOURCES += log.c +ntpd_SOURCES += ntp.c +ntpd_SOURCES += ntp.h +ntpd_SOURCES += ntp_dns.c +ntpd_SOURCES += ntp_msg.c +ntpd_SOURCES += ntpd.c +ntpd_SOURCES += ntpd.h +ntpd_SOURCES += parse.y +if !HAVE_ADJFREQ +ntpd_SOURCES += bsd-adjfreq.c +endif +if HAVE_SENSORS +ntpd_SOURCES += sensors.c +else +ntpd_SOURCES += fake-sensors.c +endif +ntpd_SOURCES += server.c +ntpd_SOURCES += util.c + +install-exec-hook: + ln -f $(DESTDIR)$(sbindir)/ntpd $(DESTDIR)$(sbindir)/ntpctl +uninstall-local: + -rm -f $(DESTDIR)$(sbindir)/ntpctl + +# compatibility functions that need to be built without optimizations +libcompatnoopt_la_CFLAGS = -O0 +libcompatnoopt_la_SOURCES = + +if !HAVE_EXPLICIT_BZERO +libcompatnoopt_la_SOURCES += compat/explicit_bzero.c +endif + +# other compatibility functions +libcompat_la_CFLAGS = $(CFLAGS) $(USER_CFLAGS) +libcompat_la_SOURCES = +libcompat_la_LIBADD = $(PLATFORM_LDADD) + + +if !HAVE_SETPROCTITLE +libcompat_la_SOURCES += compat/setproctitle.c +endif + +if !HAVE_STRLCAT +libcompat_la_SOURCES += compat/strlcat.c +endif + +if !HAVE_STRLCPY +libcompat_la_SOURCES += compat/strlcpy.c +endif + +if !HAVE_STRNDUP +libcompat_la_SOURCES += compat/strndup.c +# the only user of strnlen is strndup, so only build it if needed +if !HAVE_STRNLEN +libcompat_la_SOURCES += compat/strnlen.c +endif +endif + +if !HAVE_STRTONUM +libcompat_la_SOURCES += compat/strtonum.c +endif + +if !HAVE_ASPRINTF +libcompat_la_SOURCES += compat/bsd-asprintf.c +endif + +if !HAVE_REALLOCARRAY +libcompat_la_SOURCES += compat/reallocarray.c +endif + +if !HAVE_MD5 +libcompat_la_SOURCES += compat/md5.c +endif + +if !HAVE_IMSG +libcompat_la_SOURCES += compat/imsg.c +libcompat_la_SOURCES += compat/imsg-buffer.c +endif + +if !HAVE_ARC4RANDOM +libcompat_la_SOURCES += compat/arc4random.c + +if !HAVE_GETENTROPY +if HOST_FREEBSD +libcompat_la_SOURCES += compat/getentropy_freebsd.c +endif +if HOST_LINUX +libcompat_la_SOURCES += compat/getentropy_linux.c +ntpd_LDADD += -lcrypto +endif +if HOST_DARWIN +libcompat_la_SOURCES += compat/getentropy_osx.c +ntpd_LDADD += -lcrypto +endif +if HOST_SOLARIS +libcompat_la_SOURCES += compat/getentropy_solaris.c +ntpd_LDADD += -lcrypto +endif +endif +endif + +if !HAVE_ARC4RANDOM_UNIFORM +libcompat_la_SOURCES += compat/arc4random_uniform.c +endif + +noinst_HEADERS = compat/arc4random.h +noinst_HEADERS += compat/arc4random_freebsd.h +noinst_HEADERS += compat/arc4random_linux.h +noinst_HEADERS += compat/arc4random_osx.h +noinst_HEADERS += compat/arc4random_solaris.h +noinst_HEADERS += compat/arc4random_win.h +noinst_HEADERS += compat/chacha_private.h diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..5ff41b4 --- /dev/null +++ b/README @@ -0,0 +1,24 @@ +This is a new port of OpenBSD's native ntpd to other Unix flavours adding +autoconf support and the necessary compatibility layer. It is based on +portability code from the OpenSSH and LibreSSL portable projects. + +OpenNTPD has a web site at http://www.openntpd.org/ + +The current portable tree can be found at https://github.com/openntpd-portable + +Platform Requirements +--------------------- +adjtime() and settimeofday() syscalls or equivalent. +either poll() or select(). +a working arc4random implementation, OpenSSL or LibreSSL + (this project shares the same arc4random compatibility code from LibreSSL) + +At the time of writing the Portable version is known to build and work on: +OpenBSD (5.6) +Linux (Ubuntu 12.04, 14.04) +FreeBSD (9.x, 10.x) +Solaris (10.x, 11.x) +Mac OS X (10.9) + +It may work on others, newer and older, but it's still a work in progress. +Reports (success or otherwise) and/or diffs welcome. diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..218e2e2 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +5.7p1 diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..0b0fc04 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -e + +./update.sh +mkdir -p m4 +autoreconf -i -f diff --git a/bsd-adjfreq.c b/bsd-adjfreq.c new file mode 100644 index 0000000..dd1eae0 --- /dev/null +++ b/bsd-adjfreq.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2007 Sebastian Benoit + * + * 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. + */ + +/* RCSID("$Id$"); */ + +#include +#include + +#ifdef HAVE_SYS_TIMEX_H +# include +#endif + +#ifdef adjfreq +# undef adjfreq +#endif + +#include "ntp.h" +#include "ntpd.h" + +/* + * adjfreq (old)freq = nanosec. per seconds shifted left 32 bits + * timex.freq is ppm / left shifted by SHIFT_USEC (16 bits), defined in timex.h + */ + +int +adjfreq(const int64_t *freq, int64_t *oldfreq) +{ + struct timex txc; + int64_t newfreq; + + if (freq != NULL) { +#if defined(__linux__) + txc.modes = ADJ_FREQUENCY; +#else + txc.modes = MOD_FREQUENCY; +#endif + txc.freq = *freq / 1e3 / (1LL << 16); + + if ((ntp_adjtime(&txc)) == -1) + log_warn("ntp_adjtime (2) failed"); + + log_debug("ntp_adjtime adjusted frequency by %fppm", + ((txc.freq * 1e3) * (1LL<<16) / 1e3 / (1LL << 32))); + } + if (oldfreq != NULL) { + txc.modes = 0; + if ((ntp_adjtime(&txc)) == -1) { + log_warn("ntp_adjtime (1) failed"); + return -1; + } + newfreq = (txc.freq * 1e3) * (1LL<<16); + log_debug("ntp_adjtime returns frequency of %fppm", + newfreq / 1e3 / (1LL << 32)); + *oldfreq = newfreq; + } + + return 0; +} diff --git a/client.patch b/client.patch new file mode 100644 index 0000000..882ab97 --- /dev/null +++ b/client.patch @@ -0,0 +1,28 @@ +--- client.orig 2014-12-28 11:10:23.875157132 -0600 ++++ client.c 2014-12-28 11:12:46.095160215 -0600 +@@ -142,10 +142,12 @@ + 0)) == -1) + fatal("client_query socket"); + ++#ifdef SO_RTABLE + if (p->rtable != -1 && + setsockopt(p->query->fd, SOL_SOCKET, SO_RTABLE, + &p->rtable, sizeof(p->rtable)) == -1) + fatal("client_query setsockopt SO_RTABLE"); ++#endif + if (connect(p->query->fd, sa, SA_LEN(sa)) == -1) { + if (errno == ECONNREFUSED || errno == ENETUNREACH || + errno == EHOSTUNREACH || errno == EADDRNOTAVAIL) { +@@ -248,10 +250,12 @@ + return (0); + } + ++#ifdef SO_RTABLE + if (p->rtable != -1 && + setsockopt(p->query->fd, SOL_SOCKET, SO_RTABLE, &p->rtable, + sizeof(p->rtable)) == -1) + fatal("client_dispatch setsockopt SO_RTABLE"); ++#endif + + for (cmsg = CMSG_FIRSTHDR(&somsg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&somsg, cmsg)) { diff --git a/compat/arc4random.h b/compat/arc4random.h new file mode 100644 index 0000000..53b5a46 --- /dev/null +++ b/compat/arc4random.h @@ -0,0 +1,26 @@ +#ifndef LIBCRYPTOCOMPAT_ARC4RANDOM_H +#define LIBCRYPTOCOMPAT_ARC4RANDOM_H + +#include + +#if defined(__FreeBSD__) +#include "arc4random_freebsd.h" + +#elif defined(__linux__) +#include "arc4random_linux.h" + +#elif defined(__APPLE__) +#include "arc4random_osx.h" + +#elif defined(__sun) +#include "arc4random_solaris.h" + +#elif defined(_WIN32) +#include "arc4random_win.h" + +#else +#error "No arc4random hooks defined for this platform." + +#endif + +#endif diff --git a/compat/bsd-asprintf.c b/compat/bsd-asprintf.c new file mode 100644 index 0000000..3728bc5 --- /dev/null +++ b/compat/bsd-asprintf.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2004 Darren Tucker. + * + * Based originally on asprintf.c from OpenBSD: + * Copyright (c) 1997 Todd C. Miller + * + * 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 HAVE_ASPRINTF + +#include +#include /* for INT_MAX */ +#include +#include /* for vsnprintf */ +#include + +#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 +vasprintf(char **str, const char *fmt, va_list ap) +{ + int ret; + va_list ap2; + char *string, *newstr; + size_t len; + + if ((string = malloc(INIT_SZ)) == NULL) + goto fail; + + VA_COPY(ap2, ap); + ret = vsnprintf(string, INIT_SZ, fmt, ap2); + va_end(ap2); + if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */ + *str = string; + } else if (ret == INT_MAX || ret < 0) { /* Bad length */ + free(string); + goto fail; + } else { /* bigger than initial, realloc allowing for nul */ + len = (size_t)ret + 1; + if ((newstr = realloc(string, len)) == NULL) { + free(string); + goto fail; + } + VA_COPY(ap2, ap); + ret = vsnprintf(newstr, len, fmt, ap2); + va_end(ap2); + if (ret < 0 || (size_t)ret >= len) { /* failed with realloc'ed string */ + free(newstr); + goto fail; + } + *str = newstr; + } + return (ret); + +fail: + *str = NULL; + errno = ENOMEM; + return (-1); +} + +int asprintf(char **str, const char *fmt, ...) +{ + va_list ap; + int ret; + + *str = NULL; + va_start(ap, fmt); + ret = vasprintf(str, fmt, ap); + va_end(ap); + + return ret; +} +#endif diff --git a/compat/imsg.patch b/compat/imsg.patch new file mode 100644 index 0000000..d842d57 --- /dev/null +++ b/compat/imsg.patch @@ -0,0 +1,20 @@ +--- imsg.orig 2014-12-28 13:24:02.771330936 -0600 ++++ imsg.c 2014-12-28 13:24:35.347331642 -0600 +@@ -70,6 +70,7 @@ + return (-1); + + again: ++#ifdef HAVE_GETDTABLECOUNT + if (getdtablecount() + imsg_fd_overhead + + (CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int) + >= getdtablesize()) { +@@ -77,7 +78,8 @@ + free(ifd); + return (-1); + } +- ++#endif ++ + if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) { + if (errno == EMSGSIZE) + goto fail; diff --git a/compat/setproctitle.c b/compat/setproctitle.c new file mode 100644 index 0000000..7742e98 --- /dev/null +++ b/compat/setproctitle.c @@ -0,0 +1,165 @@ +/* Based on conf.c from UCB sendmail 8.8.8 */ + +/* + * Copyright 2003 Damien Miller + * Copyright (c) 1983, 1995-1997 Eric P. Allman + * Copyright (c) 1988, 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. + */ + +#ifndef HAVE_SETPROCTITLE + +#include +#include +#include +#ifdef HAVE_SYS_PSTAT_H +#include +#endif +#include + +#define SPT_NONE 0 /* don't use it at all */ +#define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */ +#define SPT_REUSEARGV 2 /* cover argv with title information */ + +#ifndef SPT_TYPE +# define SPT_TYPE SPT_NONE +#endif + +#ifndef SPT_PADCHAR +# define SPT_PADCHAR '\0' +#endif + +#if SPT_TYPE == SPT_REUSEARGV +static char *argv_start = NULL; +static size_t argv_env_len = 0; +#endif + +#endif /* HAVE_SETPROCTITLE */ + +void +compat_init_setproctitle(int argc, char *argv[]) +{ +#if !defined(HAVE_SETPROCTITLE) && \ + defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV + extern char **environ; + char *lastargv = NULL; + char **envp = environ; + int i; + + /* + * 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 + * programs. Beware. + */ + + if (argc == 0 || argv[0] == NULL) + return; + + /* Fail if we can't allocate room for the new environment */ + for (i = 0; envp[i] != NULL; i++) + ; + if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) { + environ = envp; /* put it back */ + return; + } + + /* + * Find the last argv string or environment variable within + * our process memory area. + */ + for (i = 0; i < argc; i++) { + if (lastargv == NULL || lastargv + 1 == argv[i]) + lastargv = argv[i] + strlen(argv[i]); + } + for (i = 0; envp[i] != NULL; i++) { + if (lastargv + 1 == envp[i]) + lastargv = envp[i] + strlen(envp[i]); + } + + argv[1] = NULL; + argv_start = argv[0]; + argv_env_len = lastargv - argv[0] - 1; + + /* + * Copy environment + * XXX - will truncate env on strdup fail + */ + for (i = 0; envp[i] != NULL; i++) + environ[i] = strdup(envp[i]); + environ[i] = NULL; +#endif /* SPT_REUSEARGV */ +} + +#ifndef HAVE_SETPROCTITLE +void +setproctitle(const char *fmt, ...) +{ +#if SPT_TYPE != SPT_NONE + va_list ap; + char buf[1024], ptitle[1024]; + size_t len; + int r; + extern char *__progname; +#if SPT_TYPE == SPT_PSTAT + union pstun pst; +#endif + +#if SPT_TYPE == SPT_REUSEARGV + if (argv_env_len <= 0) + return; +#endif + + strlcpy(buf, __progname, sizeof(buf)); + + r = -1; + va_start(ap, fmt); + if (fmt != NULL) { + len = strlcat(buf, ": ", sizeof(buf)); + if (len < sizeof(buf)) + r = vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); + } + va_end(ap); + if (r == -1 || (size_t)r >= sizeof(buf) - len) + return; + strnvis(ptitle, buf, sizeof(ptitle), + VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL); + +#if SPT_TYPE == SPT_PSTAT + pst.pst_command = ptitle; + pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0); +#elif SPT_TYPE == SPT_REUSEARGV +/* 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++) + argv_start[len] = SPT_PADCHAR; +#endif + +#endif /* SPT_NONE */ +} + +#endif /* HAVE_SETPROCTITLE */ diff --git a/config.patch b/config.patch new file mode 100644 index 0000000..c67e4f0 --- /dev/null +++ b/config.patch @@ -0,0 +1,39 @@ +--- config.orig 2014-12-28 12:15:23.139241646 -0600 ++++ config.c 2014-12-28 12:15:58.843242420 -0600 +@@ -75,7 +75,9 @@ + if ((h = calloc(1, sizeof(struct ntp_addr))) == NULL) + fatal(NULL); + sa_in = (struct sockaddr_in *)&h->ss; ++#ifdef SIN_LEN + sa_in->sin_len = sizeof(struct sockaddr_in); ++#endif + sa_in->sin_family = AF_INET; + sa_in->sin_addr.s_addr = ina.s_addr; + +@@ -97,7 +99,9 @@ + if ((h = calloc(1, sizeof(struct ntp_addr))) == NULL) + fatal(NULL); + sa_in6 = (struct sockaddr_in6 *)&h->ss; ++#ifdef SIN6_LEN + sa_in6->sin6_len = sizeof(struct sockaddr_in6); ++#endif + sa_in6->sin6_family = AF_INET6; + memcpy(&sa_in6->sin6_addr, + &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, +@@ -141,12 +145,16 @@ + h->ss.ss_family = res->ai_family; + if (res->ai_family == AF_INET) { + sa_in = (struct sockaddr_in *)&h->ss; ++#ifdef SIN_LEN + sa_in->sin_len = sizeof(struct sockaddr_in); ++#endif + sa_in->sin_addr.s_addr = ((struct sockaddr_in *) + res->ai_addr)->sin_addr.s_addr; + } else { + sa_in6 = (struct sockaddr_in6 *)&h->ss; ++#ifdef SIN6_LEN + sa_in6->sin6_len = sizeof(struct sockaddr_in6); ++#endif + memcpy(&sa_in6->sin6_addr, &((struct sockaddr_in6 *) + res->ai_addr)->sin6_addr, sizeof(struct in6_addr)); + } diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..b4206ba --- /dev/null +++ b/configure.ac @@ -0,0 +1,147 @@ +AC_INIT([OpenNTPD], m4_esyscmd([tr -d '\n' < VERSION])) + +AC_CANONICAL_HOST +AM_INIT_AUTOMAKE([subdir-objects]) +AC_CONFIG_MACRO_DIR([m4]) + +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +AC_SUBST([USER_CFLAGS], "$CFLAGS") +CFLAGS="$CFLAGS -Wall -std=gnu99 -g" + +case $host_os in + *darwin*) + HOST_OS=darwin + ;; + *freebsd*) + HOST_OS=freebsd + AC_SUBST([PROG_LDADD], ['-lthr']) + ;; + *linux*) + HOST_OS=linux + CFLAGS="$CFLAGS -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_SOURCE -D_GNU_SOURCE" + ;; + *openbsd*) + AC_DEFINE([HAVE_ATTRIBUTE__BOUNDED__], [1], [OpenBSD gcc has __bounded__]) + AC_DEFINE([HAVE_ATTRIBUTE__DEAD], [1], [OpenBSD gcc has __dead]) + HAVE_SENSORS=true + ;; + *solaris*) + HOST_OS=solaris + CFLAGS="$CFLAGS -D__EXTENSIONS__ -D_XOPEN_SOURCE=600 -DBSD_COMP" + AC_SUBST([PLATFORM_LDADD], ['-lnsl -lsocket']) + ;; + *) ;; +esac + +AM_CONDITIONAL([HOST_DARWIN], [test x$HOST_OS = xdarwin]) +AM_CONDITIONAL([HOST_FREEBSD], [test x$HOST_OS = xfreebsd]) +AM_CONDITIONAL([HOST_LINUX], [test x$HOST_OS = xlinux]) +AM_CONDITIONAL([HOST_SOLARIS], [test x$HOST_OS = xsolaris]) +AM_CONDITIONAL([HAVE_SENSORS], [test x$HAVE_SENSORS = xtrue ]) + +AC_CHECK_FUNC([clock_gettime],, + [AC_SEARCH_LIBS([clock_gettime],[rt posix4])]) + +AC_CHECK_FUNC([dl_iterate_phdr],, + [AC_SEARCH_LIBS([dl_iterate_phdr],[dl])]) + +AC_PROG_CC +AC_PROG_CC_STDC +AM_PROG_CC_C_O +AC_PROG_LIBTOOL +AC_PROG_YACC + +save_cflags="$CFLAGS" +CFLAGS=-Wno-pointer-sign +AC_MSG_CHECKING([whether CC supports -Wno-pointer-sign]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], + [AC_MSG_RESULT([yes])] + [AM_CFLAGS=-Wno-pointer-sign], + [AC_MSG_RESULT([no])] +) +CFLAGS="$save_cflags $AM_CFLAGS" + +AC_MSG_CHECKING([if compiling with clang]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#ifndef __clang__ + not clang +#endif + ]])], + [AC_MSG_RESULT([yes])] + [CLANG_FLAGS=-Qunused-arguments], + [AC_MSG_RESULT([no])] +) +CFLAGS="$CFLAGS $CLANG_CFLAGS" +LDFLAGS="$LDFLAGS $CLANG_FLAGS" + +AC_CHECK_FUNCS([adjfreq arc4random_uniform asprintf explicit_bzero]) +AC_CHECK_FUNCS([getentropy memmem poll reallocarray]) +AC_CHECK_FUNCS([setproctitle setgroups]) +AC_CHECK_FUNCS([strlcat strlcpy strndup strnlen strtonum]) +AC_CHECK_FUNCS([MD5Init]) + +# check if arc4random is in the system or in libcrypto +AC_CHECK_FUNC([arc4random],, + [AC_SEARCH_LIBS([arc4random],[crypto])]) + +AC_CHECK_FUNC([ibuf_open],, + [AC_SEARCH_LIBS([ibuf_open],[util])]) + +# Share test results with automake +AM_CONDITIONAL([HAVE_ADJFREQ], [test "x$ac_cv_func_adjfreq" = xyes]) +AM_CONDITIONAL([HAVE_ARC4RANDOM], [test "x$ac_cv_func_arc4random" = xyes]) +AM_CONDITIONAL([HAVE_ARC4RANDOM_UNIFORM], [test "x$ac_cv_func_arc4random_uniform" = xyes]) +AM_CONDITIONAL([HAVE_ASPRINTF], [test "x$ac_cv_func_asprintf" = xyes]) +AM_CONDITIONAL([HAVE_EXPLICIT_BZERO], [test "x$ac_cv_func_explicit_bzero" = xyes]) +AM_CONDITIONAL([HAVE_GETENTROPY], [test "x$ac_cv_func_getentropy" = xyes]) +AM_CONDITIONAL([HAVE_MEMMEM], [test "x$ac_cv_func_memmem" = xyes]) +AM_CONDITIONAL([HAVE_POLL], [test "x$ac_cv_func_poll" = xyes]) +AM_CONDITIONAL([HAVE_REALLOCARRAY], [test "x$ac_cv_func_reallocarray" = xyes]) +AM_CONDITIONAL([HAVE_SETGROUPS], [test "x$ac_cv_func_setgroups" = xyes]) +AM_CONDITIONAL([HAVE_SETPROCTITLE], [test "x$ac_cv_func_setproctitle" = xyes]) +AM_CONDITIONAL([HAVE_STRLCAT], [test "x$ac_cv_func_strlcat" = xyes]) +AM_CONDITIONAL([HAVE_STRLCPY], [test "x$ac_cv_func_strlcpy" = xyes]) +AM_CONDITIONAL([HAVE_STRNDUP], [test "x$ac_cv_func_strndup" = xyes]) +AM_CONDITIONAL([HAVE_STRNLEN], [test "x$ac_cv_func_strnlen" = xyes]) +AM_CONDITIONAL([HAVE_STRTONUM], [test "x$ac_cv_func_strtonum" = xyes]) +AM_CONDITIONAL([HAVE_MD5], [test "x$ac_cv_func_MD5Init" = xyes]) +AM_CONDITIONAL([HAVE_IMSG], [test "x$ac_cv_func_ibuf_open" = xyes]) + +# overrides for arc4random_buf implementations with known issues +AM_CONDITIONAL([HAVE_ARC4RANDOM], + [test "x$HOST_OS" != xdarwin -a "x$HOST_OS" != xfreebsd -a "x$ac_cv_func_arc4random" = xyes]) + +AC_CACHE_CHECK([whether va_copy exists], ac_cv_have_va_copy, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +va_list x,y; + ]], [[ va_copy(x,y); ]])], + [ ac_cv_have_va_copy="yes" ], + [ ac_cv_have_va_copy="no" + ]) +]) +if test "x$ac_cv_have_va_copy" = "xyes" ; then + AC_DEFINE([HAVE_VA_COPY], [1], [Define if va_copy exists]) +fi + +AC_CACHE_CHECK([whether __va_copy exists], ac_cv_have___va_copy, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +va_list x,y; + ]], [[ __va_copy(x,y); ]])], + [ ac_cv_have___va_copy="yes" ], [ ac_cv_have___va_copy="no" + ]) +]) +if test "x$ac_cv_have___va_copy" = "xyes" ; then + AC_DEFINE([HAVE___VA_COPY], [1], [Define if __va_copy exists]) +fi + +AC_CHECK_HEADERS([sys/timex.h]) + +AC_CONFIG_FILES([ + Makefile + include/Makefile +]) + +AC_OUTPUT diff --git a/dist.sh b/dist.sh new file mode 100755 index 0000000..27bd40a --- /dev/null +++ b/dist.sh @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +rm -f man/*.1 man/*.3 +./autogen.sh +./configure --enable-libtls +make distcheck diff --git a/fake-sensors.c b/fake-sensors.c new file mode 100644 index 0000000..4f71783 --- /dev/null +++ b/fake-sensors.c @@ -0,0 +1,46 @@ +/* $OpenBSD: sensors.c,v 1.46 2012/09/20 12:43:16 patrick Exp $ */ + +/* + * Copyright (c) 2006 Henning Brauer + * + * 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 MIND, 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 "ntpd.h" + +void +sensor_init(void) +{ +} + +int +sensor_scan(void) +{ + return 0; +} + +void +sensor_query(struct ntp_sensor *s) +{ +} + +int +sensor_hotplugfd(void) +{ + return (-1); +} + +void +sensor_hotplugevent(int fd) +{ +} diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..19e1570 --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,12 @@ +noinst_HEADERS = +noinst_HEADERS += signal.h +noinst_HEADERS += unistd.h +noinst_HEADERS += sys/types.h +noinst_HEADERS += sys/socket.h +noinst_HEADERS += sys/time.h +noinst_HEADERS += imsg.h +noinst_HEADERS += string.h +noinst_HEADERS += md5.h +noinst_HEADERS += stdlib.h +noinst_HEADERS += Makefile.in +noinst_HEADERS += poll.h diff --git a/include/poll.h b/include/poll.h new file mode 100644 index 0000000..87365f8 --- /dev/null +++ b/include/poll.h @@ -0,0 +1,15 @@ +/* + * Public domain + * poll.h compatibility shim + */ + +#include_next + +#ifndef LIBCOMPAT_POLL_H +#define LIBCOMPAT_POLL_H + +#ifndef INFTIM +#define INFTIM (-1) +#endif + +#endif diff --git a/include/signal.h b/include/signal.h new file mode 100644 index 0000000..91eb3ea --- /dev/null +++ b/include/signal.h @@ -0,0 +1,10 @@ +/* + * Public domain + * signal.h compatibility shim + */ + +#include_next + +#ifndef SIGINFO +#define SIGINFO SIGUSR1 +#endif diff --git a/include/unistd.h b/include/unistd.h new file mode 100644 index 0000000..6b8199a --- /dev/null +++ b/include/unistd.h @@ -0,0 +1,21 @@ +/* + * Public domain + * unistd.h compatibility shim + */ + +#include_next + +#ifndef LIBCOMPAT_UNISTD_H +#define LIBCOMPAT_UNISTD_H + +#ifndef HAVE_GETENTROPY +int getentropy(void *buf, size_t buflen); +#endif + +#include + +#ifndef HAVE_SETGROUPS +int setgroups(int ngroups, const gid_t *gidset); +#endif + +#endif diff --git a/ntp.patch b/ntp.patch new file mode 100644 index 0000000..e17b5c7 --- /dev/null +++ b/ntp.patch @@ -0,0 +1,20 @@ +--- ntp.orig 2014-12-28 11:48:24.731206568 -0600 ++++ ntp.c 2014-12-28 11:49:42.107208245 -0600 +@@ -79,7 +79,7 @@ + u_int pfd_elms = 0, idx2peer_elms = 0; + u_int listener_cnt, new_cnt, sent_cnt, trial_cnt; + u_int ctl_cnt; +- pid_t pid, dns_pid; ++ pid_t pid; + struct pollfd *pfd = NULL; + struct servent *se; + struct listen_addr *la; +@@ -118,7 +118,7 @@ + close(pipe_prnt[0]); + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_dns) == -1) + fatal("socketpair"); +- dns_pid = ntp_dns(pipe_dns, nconf, pw); ++ ntp_dns(pipe_dns, nconf, pw); + close(pipe_dns[1]); + + if (stat(pw->pw_dir, &stb) == -1) diff --git a/ntpd.conf b/ntpd.conf new file mode 100644 index 0000000..ed13ade --- /dev/null +++ b/ntpd.conf @@ -0,0 +1,11 @@ +# sample ntpd configuration file, see ntpd.conf(5) + +# Addresses to listen on (ntpd does not listen by default) +#listen on * + +# sync to a single server +#server ntp.example.org + +# use a random selection of NTP Pool Time Servers +# see http://support.ntp.org/bin/view/Servers/NTPPoolServers +servers pool.ntp.org diff --git a/ntpd.patch b/ntpd.patch new file mode 100644 index 0000000..d83d5c3 --- /dev/null +++ b/ntpd.patch @@ -0,0 +1,10 @@ +--- ntpd.orig 2014-12-28 11:51:56.363211155 -0600 ++++ ntpd.c 2014-12-28 11:52:00.971211255 -0600 +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + #include + diff --git a/parse.patch b/parse.patch new file mode 100644 index 0000000..0755fac --- /dev/null +++ b/parse.patch @@ -0,0 +1,15 @@ +--- parse.orig 2014-12-28 11:59:42.075221249 -0600 ++++ parse.y 2014-12-28 11:54:22.799214329 -0600 +@@ -313,10 +313,12 @@ + opts.weight = $2; + } + rtable : RTABLE NUMBER { ++#ifdef RT_TABLEID_MAX + if ($2 < 0 || $2 > RT_TABLEID_MAX) { + yyerror("rtable must be between 1 and RT_TABLEID_MAX"); + YYERROR; + } ++#endif + opts.rtable = $2; + } + ; diff --git a/server.patch b/server.patch new file mode 100644 index 0000000..4426d6c --- /dev/null +++ b/server.patch @@ -0,0 +1,53 @@ +--- server.orig 2014-12-28 12:16:48.203243490 -0600 ++++ server.c 2014-12-28 12:18:07.907245217 -0600 +@@ -39,7 +39,10 @@ + u_int8_t *a6; + size_t sa6len = sizeof(struct in6_addr); + u_int new_cnt = 0; +- int tos = IPTOS_LOWDELAY, rdomain, fd; ++ int tos = IPTOS_LOWDELAY; ++#ifdef SO_RTABLE ++ int rdomain, fd; ++#endif + + TAILQ_FOREACH(lap, &lconf->listen_addrs, entry) { + switch (lap->sa.ss_family) { +@@ -59,6 +62,7 @@ + strlcpy(ifr.ifr_name, ifap->ifa_name, + sizeof(ifr.ifr_name)); + ++#ifdef SO_RTABLE + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (ioctl(fd, SIOCGIFRDOMAIN, + (caddr_t)&ifr) == -1) +@@ -69,6 +73,7 @@ + + if (lap->rtable != -1 && rdomain != lap->rtable) + continue; ++#endif + + if (sa->sa_family == AF_INET && + ((struct sockaddr_in *)sa)->sin_addr.s_addr == +@@ -87,7 +92,9 @@ + fatal("setup_listeners calloc"); + + memcpy(&la->sa, sa, SA_LEN(sa)); ++#ifdef SO_RTABLE + la->rtable = rdomain; ++#endif + + TAILQ_INSERT_TAIL(&lconf->listen_addrs, la, entry); + } +@@ -132,10 +139,12 @@ + IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) == -1) + log_warn("setsockopt IPTOS_LOWDELAY"); + ++#ifdef SO_RTABLE + if (la->rtable != -1 && + setsockopt(la->fd, SOL_SOCKET, SO_RTABLE, &la->rtable, + sizeof(la->rtable)) == -1) + fatal("setup_listeners setsockopt SO_RTABLE"); ++#endif + + if (bind(la->fd, (struct sockaddr *)&la->sa, + SA_LEN((struct sockaddr *)&la->sa)) == -1) { diff --git a/update.sh b/update.sh new file mode 100755 index 0000000..8ce9706 --- /dev/null +++ b/update.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +set -e + +openntpd_version=`cat VERSION` + +# pull in latest upstream code +echo "pulling upstream openbsd source" +if [ ! -d openbsd ]; then + if [ -z "$OPENNTPD_GIT" ]; then + git clone https://github.com/openntpd-portable/openbsd.git + else + git clone $OPENNTPD_GIT/openbsd + fi +fi +#(cd openbsd +# git checkout master +# git pull --rebase) + +# setup source paths +dir=`pwd` +libc_inc=$dir/openbsd/src/include +libc_src=$dir/openbsd/src/lib/libc +libcrypto_src=$dir/openbsd/src/lib/libcrypto +libutil_src=$dir/openbsd/src/lib/libutil +ntpd_src=$dir/openbsd/src/usr.sbin/ntpd + +CP='cp -p' + +cp $libc_inc/md5.h include/ +cp $libutil_src/imsg.h include/ +cp $libutil_src/imsg.c compat/ +cp $libutil_src/imsg-buffer.c compat/ +(cd compat; patch -p0 < imsg.patch) + +for i in explicit_bzero.c strlcpy.c strlcat.c strndup.c strnlen.c; do + $CP $libc_src/string/$i compat +done +$CP $libc_src/stdlib/reallocarray.c compat +$CP $libc_src/stdlib/strtonum.c compat +$CP $libc_src/crypt/arc4random.c compat +$CP $libc_src/crypt/arc4random_uniform.c compat +$CP $libc_src/crypt/chacha_private.h compat +$CP $libc_src/hash/md5.c compat +$CP $libcrypto_src/crypto/getentropy_*.c compat +$CP $libcrypto_src/crypto/arc4random_*.h compat + +for i in client.c config.c control.c log.c ntp.c ntp.h ntp_dns.c ntp_msg.c \ + ntpd.c ntpd.h parse.y sensors.c server.c util.c \ + ntpctl.8 ntpd.8 ntpd.conf.5 ; do + cp $ntpd_src/$i . +done +patch -p0 < client.patch +patch -p0 < config.patch +patch -p0 < ntp.patch +patch -p0 < ntpd.patch +patch -p0 < parse.patch +patch -p0 < server.patch +patch -p0 < util.patch diff --git a/util.patch b/util.patch new file mode 100644 index 0000000..ef600b2 --- /dev/null +++ b/util.patch @@ -0,0 +1,13 @@ +--- util.orig 2014-12-28 12:18:54.727246232 -0600 ++++ util.c 2014-12-28 12:19:04.211246438 -0600 +@@ -17,8 +17,10 @@ + */ + + #include ++ + #include + #include ++#include + + #include "ntpd.h" +