From: Harlan Stenn Date: Tue, 14 Mar 2000 03:41:14 +0000 (-0000) Subject: Many files: X-Git-Tag: NTP_4_0_99_J~81 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d18c7b580e3d17f6be52af16dbc856bfcc42a471;p=thirdparty%2Fntp.git Many files: Crypto code update bk: 38cdb4daeEsO7vdrLKTVcn21iHA_Jg --- diff --git a/COPYRIGHT b/COPYRIGHT index 44ee155bae..5a2de4821d 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -163,5 +163,5 @@ References 47. mailto:tsuruoka@nc.fukuoka-u.ac.jp 48. mailto:vixie@vix.com 49. mailto:Ulrich.Windl@rz.uni-regensburg.de - 50. file://localhost/backroom/ntp4/html/index.htm + 50. file://localhost/backroom/ntp4+/html/index.htm 51. mailto:mills@udel.edu diff --git a/Makefile.in b/Makefile.in index d754804b6b..596be05eb3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/adjtimed/Makefile.in b/adjtimed/Makefile.in index be13d2aa18..3e42ddcc83 100644 --- a/adjtimed/Makefile.in +++ b/adjtimed/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/clockstuff/Makefile.in b/clockstuff/Makefile.in index 29713aeeb8..07ac40bdc6 100644 --- a/clockstuff/Makefile.in +++ b/clockstuff/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/config.h.in b/config.h.in index 34a469fdf5..a25caa4cf2 100644 --- a/config.h.in +++ b/config.h.in @@ -456,6 +456,9 @@ /* toupper()? */ #undef DECL_TOUPPER_0 +/* Autokey? */ +#undef AUTOKEY + /* Define if you have the header file. */ #undef HAVE_ARPA_NAMESER_H @@ -489,6 +492,9 @@ /* Define if you have the `getuid' function. */ #undef HAVE_GETUID +/* Define if you have the header file. */ +#undef HAVE_IEEEFP_H + /* Define if you have the `kvm_open' function. */ #undef HAVE_KVM_OPEN @@ -846,6 +852,9 @@ /* Define if compiler has function prototypes */ #undef PROTOTYPES +/* Public key? */ +#undef PUBKEY + /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE diff --git a/configure b/configure index 9f0d309cb1..de7bf8f479 100755 --- a/configure +++ b/configure @@ -144,6 +144,8 @@ ac_arg_enable_help="$ac_arg_enable_help --enable-WHARTON s WHARTON 400A Series clock" ac_arg_enable_help="$ac_arg_enable_help --enable-VARITEXT s VARITEXT clock" +ac_arg_with_help="$ac_arg_with_help + --with-rsaref + Use rsaref if possible" ac_arg_enable_help="$ac_arg_enable_help --enable-kmem s read /dev/kmem for tick and/or tickadj" ac_arg_enable_help="$ac_arg_enable_help @@ -727,7 +729,7 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. echo $ac_n "checking host system type... $ac_c" 1>&6 -echo "configure:731: checking host system type" 1>&5 +echo "configure:733: checking host system type" 1>&5 if test "x$ac_cv_host" = "x" || (test "x$host" != "xNONE" && test "x$host" != "x$ac_cv_host_alias"); then # Make sure we can run config.sub. @@ -763,7 +765,7 @@ host_vendor=$ac_cv_host_vendor host_os=$ac_cv_host_os echo $ac_n "checking target system type... $ac_c" 1>&6 -echo "configure:767: checking target system type" 1>&5 +echo "configure:769: checking target system type" 1>&5 if test "x$ac_cv_target" = "x" || (test "x$target" != "xNONE" && test "x$target" != "x$ac_cv_target_alias"); then # Make sure we can run config.sub. @@ -798,7 +800,7 @@ target_vendor=$ac_cv_target_vendor target_os=$ac_cv_target_os echo $ac_n "checking build system type... $ac_c" 1>&6 -echo "configure:802: checking build system type" 1>&5 +echo "configure:804: checking build system type" 1>&5 if test "x$ac_cv_build" = "x" || (test "x$build" != "xNONE" && test "x$build" != "x$ac_cv_build_alias"); then # Make sure we can run config.sub. @@ -892,7 +894,7 @@ test "$program_transform_name" = "" && program_transform_name="s,x,x," # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install... $ac_c" 1>&6 -echo "configure:896: checking for a BSD compatible install" 1>&5 +echo "configure:898: checking for a BSD compatible install" 1>&5 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -949,7 +951,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether build environment is sane... $ac_c" 1>&6 -echo "configure:953: checking whether build environment is sane" 1>&5 +echo "configure:955: checking whether build environment is sane" 1>&5 # Just in case sleep 1 echo timestamp > conftestfile @@ -1001,7 +1003,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word... $ac_c" 1>&6 -echo "configure:1005: checking for $ac_word" 1>&5 +echo "configure:1007: checking for $ac_word" 1>&5 if test "${ac_cv_prog_AWK+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1031,7 +1033,7 @@ test -n "$AWK" && break done echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}... $ac_c" 1>&6 -echo "configure:1035: checking whether ${MAKE-make} sets \${MAKE}" 1>&5 +echo "configure:1037: checking whether ${MAKE-make} sets \${MAKE}" 1>&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1137,7 +1139,7 @@ esac # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word... $ac_c" 1>&6 -echo "configure:1141: checking for $ac_word" 1>&5 +echo "configure:1143: checking for $ac_word" 1>&5 if test "${ac_cv_prog_CC+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1167,7 +1169,7 @@ fi # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word... $ac_c" 1>&6 -echo "configure:1171: checking for $ac_word" 1>&5 +echo "configure:1173: checking for $ac_word" 1>&5 if test "${ac_cv_prog_CC+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1218,7 +1220,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word... $ac_c" 1>&6 -echo "configure:1222: checking for $ac_word" 1>&5 +echo "configure:1224: checking for $ac_word" 1>&5 if test "${ac_cv_prog_CC+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1253,7 +1255,7 @@ done test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } echo $ac_n "checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works... $ac_c" 1>&6 -echo "configure:1257: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works" 1>&5 +echo "configure:1259: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works" 1>&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -1264,12 +1266,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1275: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -1295,12 +1297,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 77; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler... $ac_c" 1>&6 -echo "configure:1299: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler" 1>&5 +echo "configure:1301: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler" 1>&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6 -echo "configure:1304: checking whether we are using GNU C" 1>&5 +echo "configure:1306: checking whether we are using GNU C" 1>&5 if test "${ac_cv_prog_gcc+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1309,7 +1311,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1313: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1315: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1327,7 +1329,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g... $ac_c" 1>&6 -echo "configure:1331: checking whether ${CC-cc} accepts -g" 1>&5 +echo "configure:1333: checking whether ${CC-cc} accepts -g" 1>&5 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1358,7 +1360,7 @@ else fi echo $ac_n "checking how to run the C preprocessor... $ac_c" 1>&6 -echo "configure:1362: checking how to run the C preprocessor" 1>&5 +echo "configure:1364: checking how to run the C preprocessor" 1>&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1373,13 +1375,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat >conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1383: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1385: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1390,13 +1392,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat >conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1400: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1402: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1407,13 +1409,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat >conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1417: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1419: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1440,7 +1442,7 @@ echo "$ac_t""$CPP" 1>&6 depcc="$CC" depcpp="$CPP" echo $ac_n "checking dependency style of $depcc... $ac_c" 1>&6 -echo "configure:1444: checking dependency style of $depcc" 1>&5 +echo "configure:1446: checking dependency style of $depcc" 1>&5 if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1484,7 +1486,7 @@ echo "$ac_t""$am_cv_CC_dependencies_compiler_type" 1>&6 CCDEPMODE="depmode=$am_cv_CC_dependencies_compiler_type" echo $ac_n "checking how to run the C preprocessor... $ac_c" 1>&6 -echo "configure:1488: checking how to run the C preprocessor" 1>&5 +echo "configure:1490: checking how to run the C preprocessor" 1>&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1499,13 +1501,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat >conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1509: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1511: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1516,13 +1518,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat >conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1526: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1528: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1533,13 +1535,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat >conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1543: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1545: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1604,7 +1606,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word... $ac_c" 1>&6 -echo "configure:1608: checking for $ac_word" 1>&5 +echo "configure:1610: checking for $ac_word" 1>&5 if test "${ac_cv_prog_AWK+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1634,7 +1636,7 @@ test -n "$AWK" && break done echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}... $ac_c" 1>&6 -echo "configure:1638: checking whether ${MAKE-make} sets \${MAKE}" 1>&5 +echo "configure:1640: checking whether ${MAKE-make} sets \${MAKE}" 1>&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1675,7 +1677,7 @@ case "$GCC" in CFLAGS="$CFLAGS -Wstrict-prototypes" echo $ac_n "checking whether ${CC-cc} -pipe works... $ac_c" 1>&6 -echo "configure:1679: checking whether ${CC-cc} -pipe works" 1>&5 +echo "configure:1681: checking whether ${CC-cc} -pipe works" 1>&5 if test "${ac_cv_prog_cc_pipe+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1743,7 +1745,7 @@ case "$ac_busted_vpath_in_make$srcdir" in esac echo $ac_n "checking whether ln -s works... $ac_c" 1>&6 -echo "configure:1747: checking whether ln -s works" 1>&5 +echo "configure:1749: checking whether ln -s works" 1>&5 if test "${ac_cv_prog_LN_S+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1765,13 +1767,13 @@ fi if test $ac_cv_prog_gcc = yes; then echo $ac_n "checking whether ${CC-cc} needs -traditional... $ac_c" 1>&6 -echo "configure:1769: checking whether ${CC-cc} needs -traditional" 1>&5 +echo "configure:1771: checking whether ${CC-cc} needs -traditional" 1>&5 if test "${ac_cv_prog_gcc_traditional+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_pattern="Autoconf.*'x'" cat >conftest.$ac_ext < Autoconf TIOCGETP @@ -1788,7 +1790,7 @@ rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat >conftest.$ac_ext < Autoconf TCGETA @@ -1809,9 +1811,9 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 fi echo $ac_n "checking for AIX... $ac_c" 1>&6 -echo "configure:1813: checking for AIX" 1>&5 +echo "configure:1815: checking for AIX" 1>&5 cat >conftest.$ac_ext <&6 -echo "configure:1837: checking for minix/config.h" 1>&5 +echo "configure:1839: checking for minix/config.h" 1>&5 if test "${ac_cv_header_minix_config_h+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1848: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1850: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1881,7 +1883,7 @@ EOF fi echo $ac_n "checking for POSIXized ISC... $ac_c" 1>&6 -echo "configure:1885: checking for POSIXized ISC" 1>&5 +echo "configure:1887: checking for POSIXized ISC" 1>&5 if test -d /etc/conf/kconfig.d && grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 then @@ -1904,7 +1906,7 @@ fi # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word... $ac_c" 1>&6 -echo "configure:1908: checking for $ac_word" 1>&5 +echo "configure:1910: checking for $ac_word" 1>&5 if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1934,7 +1936,7 @@ fi # Extract the first word of "sh", so it can be a program name with args. set dummy sh; ac_word=$2 echo $ac_n "checking for $ac_word... $ac_c" 1>&6 -echo "configure:1938: checking for $ac_word" 1>&5 +echo "configure:1940: checking for $ac_word" 1>&5 if test "${ac_cv_path_PATH_SH+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1966,7 +1968,7 @@ fi # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 echo $ac_n "checking for $ac_word... $ac_c" 1>&6 -echo "configure:1970: checking for $ac_word" 1>&5 +echo "configure:1972: checking for $ac_word" 1>&5 if test "${ac_cv_path_PATH_PERL+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2013,7 +2015,7 @@ esac # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install... $ac_c" 1>&6 -echo "configure:2017: checking for a BSD compatible install" 1>&5 +echo "configure:2019: checking for a BSD compatible install" 1>&5 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2072,14 +2074,14 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' case "$target" in *-pc-cygwin*) echo $ac_n "checking for main in -ladvapi32... $ac_c" 1>&6 -echo "configure:2076: checking for main in -ladvapi32" 1>&5 +echo "configure:2078: checking for main in -ladvapi32" 1>&5 if test "${ac_cv_lib_advapi32_main+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ladvapi32 $LIBS" cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_advapi32_main=yes else @@ -2116,14 +2118,14 @@ fi ;; esac echo $ac_n "checking for nlist in -lelf... $ac_c" 1>&6 -echo "configure:2120: checking for nlist in -lelf" 1>&5 +echo "configure:2122: checking for nlist in -lelf" 1>&5 if test "${ac_cv_lib_elf_nlist+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lelf $LIBS" cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_elf_nlist=yes else @@ -2162,14 +2164,14 @@ EOF fi echo $ac_n "checking for main in -lkvm... $ac_c" 1>&6 -echo "configure:2166: checking for main in -lkvm" 1>&5 +echo "configure:2168: checking for main in -lkvm" 1>&5 if test "${ac_cv_lib_kvm_main+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lkvm $LIBS" cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2186: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_kvm_main=yes else @@ -2203,14 +2205,14 @@ EOF fi echo $ac_n "checking for nlist in -lld... $ac_c" 1>&6 -echo "configure:2207: checking for nlist in -lld" 1>&5 +echo "configure:2209: checking for nlist in -lld" 1>&5 if test "${ac_cv_lib_ld_nlist+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lld $LIBS" cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2231: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_ld_nlist=yes else @@ -2249,14 +2251,14 @@ EOF fi echo $ac_n "checking for nlist in -lmld... $ac_c" 1>&6 -echo "configure:2253: checking for nlist in -lmld" 1>&5 +echo "configure:2255: checking for nlist in -lmld" 1>&5 if test "${ac_cv_lib_mld_nlist+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lmld $LIBS" cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2277: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_mld_nlist=yes else @@ -2295,12 +2297,12 @@ EOF fi echo $ac_n "checking for gethostent... $ac_c" 1>&6 -echo "configure:2299: checking for gethostent" 1>&5 +echo "configure:2301: checking for gethostent" 1>&5 if test "${ac_cv_func_gethostent+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2334: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_gethostent=yes else @@ -2345,14 +2347,14 @@ if test $ac_cv_func_gethostent = yes; then : else echo $ac_n "checking for gethostent in -lnsl... $ac_c" 1>&6 -echo "configure:2349: checking for gethostent in -lnsl" 1>&5 +echo "configure:2351: checking for gethostent in -lnsl" 1>&5 if test "${ac_cv_lib_nsl_gethostent+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl -lsocket $LIBS" cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_nsl_gethostent=yes else @@ -2393,12 +2395,12 @@ fi fi echo $ac_n "checking for openlog... $ac_c" 1>&6 -echo "configure:2397: checking for openlog" 1>&5 +echo "configure:2399: checking for openlog" 1>&5 if test "${ac_cv_func_openlog+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2432: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_openlog=yes else @@ -2443,14 +2445,14 @@ if test $ac_cv_func_openlog = yes; then : else echo $ac_n "checking for openlog in -lgen... $ac_c" 1>&6 -echo "configure:2447: checking for openlog in -lgen" 1>&5 +echo "configure:2449: checking for openlog in -lgen" 1>&5 if test "${ac_cv_lib_gen_openlog+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lgen $LIBS" cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_gen_openlog=yes else @@ -2491,14 +2493,14 @@ fi fi echo $ac_n "checking for sched_setscheduler in -lrt... $ac_c" 1>&6 -echo "configure:2495: checking for sched_setscheduler in -lrt" 1>&5 +echo "configure:2497: checking for sched_setscheduler in -lrt" 1>&5 if test "${ac_cv_lib_rt_sched_setscheduler+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lrt $LIBS" cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2519: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_rt_sched_setscheduler=yes else @@ -2536,14 +2538,14 @@ EOF else echo $ac_n "checking for sched_setscheduler in -lposix4... $ac_c" 1>&6 -echo "configure:2540: checking for sched_setscheduler in -lposix4" 1>&5 +echo "configure:2542: checking for sched_setscheduler in -lposix4" 1>&5 if test "${ac_cv_lib_posix4_sched_setscheduler+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lposix4 $LIBS" cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_posix4_sched_setscheduler=yes else @@ -2584,12 +2586,12 @@ fi fi echo $ac_n "checking for setsockopt... $ac_c" 1>&6 -echo "configure:2588: checking for setsockopt" 1>&5 +echo "configure:2590: checking for setsockopt" 1>&5 if test "${ac_cv_func_setsockopt+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2623: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_setsockopt=yes else @@ -2634,14 +2636,14 @@ if test $ac_cv_func_setsockopt = yes; then : else echo $ac_n "checking for setsockopt in -lsocket... $ac_c" 1>&6 -echo "configure:2638: checking for setsockopt in -lsocket" 1>&5 +echo "configure:2640: checking for setsockopt in -lsocket" 1>&5 if test "${ac_cv_lib_socket_setsockopt+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_socket_setsockopt=yes else @@ -2682,12 +2684,12 @@ fi fi echo $ac_n "checking for ANSI C header files... $ac_c" 1>&6 -echo "configure:2686: checking for ANSI C header files" 1>&5 +echo "configure:2688: checking for ANSI C header files" 1>&5 if test "${ac_cv_header_stdc+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #include @@ -2696,7 +2698,7 @@ else EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2700: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2702: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2713,7 +2715,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext < @@ -2732,7 +2734,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext < @@ -2754,7 +2756,7 @@ if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext < #if ((' ' & 0x0FF) == 0x020) @@ -2779,7 +2781,7 @@ main () exit (0); } EOF -if { (eval echo configure:2783: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -2802,22 +2804,22 @@ EOF fi -for ac_header in bstring.h errno.h fcntl.h memory.h netdb.h poll.h resolv.h +for ac_header in bstring.h errno.h fcntl.h ieeefp.h memory.h netdb.h poll.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:2810: checking for $ac_header" 1>&5 +echo "configure:2812: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2821: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2823: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2840,22 +2842,22 @@ EOF fi done -for ac_header in sched.h sgtty.h stdlib.h string.h termio.h termios.h +for ac_header in resolv.h sched.h sgtty.h stdlib.h string.h termio.h termios.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:2848: checking for $ac_header" 1>&5 +echo "configure:2850: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2859: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2861: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2882,18 +2884,18 @@ for ac_header in timepps.h timex.h unistd.h utmp.h utmpx.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:2886: checking for $ac_header" 1>&5 +echo "configure:2888: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2897: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2899: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2920,18 +2922,18 @@ for ac_header in arpa/nameser.h net/if.h netinet/in_systm.h netinet/in.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:2924: checking for $ac_header" 1>&5 +echo "configure:2926: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2935: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2937: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2958,18 +2960,18 @@ for ac_header in netinfo/ni.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:2962: checking for $ac_header" 1>&5 +echo "configure:2964: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2973: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2975: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2999,18 +3001,18 @@ for ac_header in sun/audioio.h sys/audioio.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3003: checking for $ac_header" 1>&5 +echo "configure:3005: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3014: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3016: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3037,18 +3039,18 @@ for ac_header in sys/clkdefs.h sys/file.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3041: checking for $ac_header" 1>&5 +echo "configure:3043: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3052: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3054: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3077,18 +3079,18 @@ case "$target" in do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3081: checking for $ac_header" 1>&5 +echo "configure:3083: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3092: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3094: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3117,18 +3119,18 @@ for ac_header in sys/lock.h sys/mman.h sys/modem.h sys/param.h sys/ppsclock.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3121: checking for $ac_header" 1>&5 +echo "configure:3123: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3132: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3134: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3155,18 +3157,18 @@ for ac_header in sys/ppstime.h sys/proc.h sys/resource.h sys/sched.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3159: checking for $ac_header" 1>&5 +echo "configure:3161: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3170: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3172: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3195,18 +3197,18 @@ case "$target" in do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3199: checking for $ac_header" 1>&5 +echo "configure:3201: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3210: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3212: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3235,18 +3237,18 @@ for ac_header in sys/select.h sys/sockio.h sys/stat.h sys/stream.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3239: checking for $ac_header" 1>&5 +echo "configure:3241: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3250: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3252: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3273,18 +3275,18 @@ for ac_header in sys/stropts.h sys/sysctl.h sys/syssgi.h sys/termios.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3277: checking for $ac_header" 1>&5 +echo "configure:3279: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3288: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3290: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3311,18 +3313,18 @@ for ac_header in sys/time.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3315: checking for $ac_header" 1>&5 +echo "configure:3317: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3326: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3328: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3346,7 +3348,7 @@ fi done cat >conftest.$ac_ext < #ifdef PPS_API_VERS_1 @@ -3361,18 +3363,18 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3365: checking for $ac_header" 1>&5 +echo "configure:3367: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3376: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3378: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3402,18 +3404,18 @@ for ac_header in sys/timers.h sys/timex.h sys/tpro.h sys/types.h sys/wait.h do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3406: checking for $ac_header" 1>&5 +echo "configure:3408: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3417: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3419: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3437,12 +3439,12 @@ fi done echo $ac_n "checking whether time.h and sys/time.h may both be included... $ac_c" 1>&6 -echo "configure:3441: checking whether time.h and sys/time.h may both be included" 1>&5 +echo "configure:3443: checking whether time.h and sys/time.h may both be included" 1>&5 if test "${ac_cv_header_time+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #include @@ -3456,7 +3458,7 @@ struct tm *tp; return 0; } EOF -if { (eval echo configure:3460: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3462: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else @@ -3481,18 +3483,18 @@ case "$target" in do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3485: checking for $ac_header" 1>&5 +echo "configure:3487: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3496: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3498: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3521,18 +3523,18 @@ done do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3525: checking for $ac_header" 1>&5 +echo "configure:3527: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3536: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3538: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3559,18 +3561,18 @@ done esac echo $ac_n "checking for nlist.h... $ac_c" 1>&6 -echo "configure:3563: checking for nlist.h" 1>&5 +echo "configure:3565: checking for nlist.h" 1>&5 if test "${ac_cv_header_nlist_h+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3574: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3576: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3591,12 +3593,12 @@ if test $ac_cv_header_nlist_h = yes; then EOF echo $ac_n "checking for n_un in struct nlist... $ac_c" 1>&6 -echo "configure:3595: checking for n_un in struct nlist" 1>&5 +echo "configure:3597: checking for n_un in struct nlist" 1>&5 if test "${ac_cv_struct_nlist_n_un+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < int @@ -3607,7 +3609,7 @@ struct nlist n; n.n_un.n_name = 0; return 0; } EOF -if { (eval echo configure:3611: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3613: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_nlist_n_un=yes else @@ -3629,12 +3631,12 @@ fi fi echo $ac_n "checking for basic volatile support... $ac_c" 1>&6 -echo "configure:3633: checking for basic volatile support" 1>&5 +echo "configure:3635: checking for basic volatile support" 1>&5 if test "${ac_cv_c_volatile+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3652: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_volatile=yes else @@ -3677,7 +3679,7 @@ case "$target" in echo $ac_n "checking for ${CC-cc} option to accept ANSI C... $ac_c" 1>&6 -echo "configure:3681: checking for ${CC-cc} option to accept ANSI C" 1>&5 +echo "configure:3683: checking for ${CC-cc} option to accept ANSI C" 1>&5 if test "${am_cv_prog_cc_stdc+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3694,7 +3696,7 @@ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIO do CC="$ac_save_CC $ac_arg" cat >conftest.$ac_ext < #include @@ -3735,7 +3737,7 @@ return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; return 0; } EOF -if { (eval echo configure:3739: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3741: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* am_cv_prog_cc_stdc="$ac_arg"; break else @@ -3759,7 +3761,7 @@ case "x$am_cv_prog_cc_stdc" in esac echo $ac_n "checking for function prototypes... $ac_c" 1>&6 -echo "configure:3763: checking for function prototypes" 1>&5 +echo "configure:3765: checking for function prototypes" 1>&5 if test "$am_cv_prog_cc_stdc" != no; then echo "$ac_t""yes" 1>&6 cat >>confdefs.h <<\EOF @@ -3772,12 +3774,12 @@ else U=_ ANSI2KNR=./ansi2knr # Ensure some checks needed by ansi2knr itself. echo $ac_n "checking for ANSI C header files... $ac_c" 1>&6 -echo "configure:3776: checking for ANSI C header files" 1>&5 +echo "configure:3778: checking for ANSI C header files" 1>&5 if test "${ac_cv_header_stdc+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #include @@ -3786,7 +3788,7 @@ else EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3790: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3792: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3803,7 +3805,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext < @@ -3822,7 +3824,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext < @@ -3844,7 +3846,7 @@ if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext < #if ((' ' & 0x0FF) == 0x020) @@ -3869,7 +3871,7 @@ main () exit (0); } EOF -if { (eval echo configure:3873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3875: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -3896,18 +3898,18 @@ fi do ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh` echo $ac_n "checking for $ac_header... $ac_c" 1>&6 -echo "configure:3900: checking for $ac_header" 1>&5 +echo "configure:3902: checking for $ac_header" 1>&5 if eval "test \"\${$ac_ac_Header+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3911: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3935,12 +3937,12 @@ fi ;; esac echo $ac_n "checking if C compiler permits function prototypes... $ac_c" 1>&6 -echo "configure:3939: checking if C compiler permits function prototypes" 1>&5 +echo "configure:3941: checking if C compiler permits function prototypes" 1>&5 if test "${ac_cv_have_prototypes+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3960: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_prototypes=yes else @@ -3975,7 +3977,7 @@ EOF fi echo $ac_n "checking for ${CC-cc} option to accept ANSI C... $ac_c" 1>&6 -echo "configure:3979: checking for ${CC-cc} option to accept ANSI C" 1>&5 +echo "configure:3981: checking for ${CC-cc} option to accept ANSI C" 1>&5 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3992,7 +3994,7 @@ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIO do CC="$ac_save_CC $ac_arg" cat >conftest.$ac_ext < #include @@ -4030,7 +4032,7 @@ return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; return 0; } EOF -if { (eval echo configure:4034: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4036: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_prog_cc_stdc="$ac_arg"; break else @@ -4052,12 +4054,12 @@ case "x$ac_cv_prog_cc_stdc" in esac echo $ac_n "checking for an ANSI C conforming const... $ac_c" 1>&6 -echo "configure:4056: checking for an ANSI C conforming const" 1>&5 +echo "configure:4058: checking for an ANSI C conforming const" 1>&5 if test "${ac_cv_c_const+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4120: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -4136,14 +4138,14 @@ fi case "$host" in $target) echo $ac_n "checking whether byte ordering is bigendian... $ac_c" 1>&6 -echo "configure:4140: checking whether byte ordering is bigendian" 1>&5 +echo "configure:4142: checking whether byte ordering is bigendian" 1>&5 if test "${ac_cv_c_bigendian+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_bigendian=unknown # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext < #include @@ -4159,11 +4161,11 @@ main () return 0; } EOF -if { (eval echo configure:4163: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4165: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext < #include @@ -4179,7 +4181,7 @@ main () return 0; } EOF -if { (eval echo configure:4183: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4185: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_bigendian=yes else @@ -4199,7 +4201,7 @@ if test "$cross_compiling" = yes; then { echo "configure: error: cannot run test program while cross compiling" 1>&2; exit 1; } else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_bigendian=no else @@ -4254,12 +4256,12 @@ EOF ;; esac echo $ac_n "checking return type of signal handlers... $ac_c" 1>&6 -echo "configure:4258: checking return type of signal handlers" 1>&5 +echo "configure:4260: checking return type of signal handlers" 1>&5 if test "${ac_cv_type_signal+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #include @@ -4280,7 +4282,7 @@ int i; return 0; } EOF -if { (eval echo configure:4284: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4286: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else @@ -4297,12 +4299,12 @@ cat >>confdefs.h <&6 -echo "configure:4301: checking for off_t" 1>&5 +echo "configure:4303: checking for off_t" 1>&5 if test "${ac_cv_type_off_t+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4322: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_off_t=yes else @@ -4338,12 +4340,12 @@ EOF fi echo $ac_n "checking for size_t... $ac_c" 1>&6 -echo "configure:4342: checking for size_t" 1>&5 +echo "configure:4344: checking for size_t" 1>&5 if test "${ac_cv_type_size_t+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4363: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_size_t=yes else @@ -4379,12 +4381,12 @@ EOF fi echo $ac_n "checking for time_t... $ac_c" 1>&6 -echo "configure:4383: checking for time_t" 1>&5 +echo "configure:4385: checking for time_t" 1>&5 if test "${ac_cv_type_time_t+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4404: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_time_t=yes else @@ -4420,12 +4422,12 @@ EOF fi echo $ac_n "checking whether struct tm is in sys/time.h or time.h... $ac_c" 1>&6 -echo "configure:4424: checking whether struct tm is in sys/time.h or time.h" 1>&5 +echo "configure:4426: checking whether struct tm is in sys/time.h or time.h" 1>&5 if test "${ac_cv_struct_tm+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #include @@ -4438,7 +4440,7 @@ struct tm *tp; tp->tm_sec; return 0; } EOF -if { (eval echo configure:4442: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4444: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_tm=time.h else @@ -4458,7 +4460,7 @@ EOF fi echo $ac_n "checking for a fallback value for HZ... $ac_c" 1>&6 -echo "configure:4462: checking for a fallback value for HZ" 1>&5 +echo "configure:4464: checking for a fallback value for HZ" 1>&5 if test "${ac_cv_var_default_hz+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4478,7 +4480,7 @@ cat >>confdefs.h <&6 -echo "configure:4482: checking if we need to override the system's value for HZ" 1>&5 +echo "configure:4484: checking if we need to override the system's value for HZ" 1>&5 if test "${ac_cv_var_override_hz+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4509,13 +4511,13 @@ EOF esac echo $ac_n "checking struct sigaction for sa_sigaction... $ac_c" 1>&6 -echo "configure:4513: checking struct sigaction for sa_sigaction" 1>&5 +echo "configure:4515: checking struct sigaction for sa_sigaction" 1>&5 if test "${ac_cv_struct_sigaction_has_sa_sigaction+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < int @@ -4526,7 +4528,7 @@ struct sigaction act; act.sa_sigaction = 0; return 0; } EOF -if { (eval echo configure:4530: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4532: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_sigaction_has_sa_sigaction=yes else @@ -4549,12 +4551,12 @@ EOF fi echo $ac_n "checking for struct ppsclockev... $ac_c" 1>&6 -echo "configure:4553: checking for struct ppsclockev" 1>&5 +echo "configure:4555: checking for struct ppsclockev" 1>&5 if test "${ac_cv_struct_ppsclockev+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -4577,7 +4579,7 @@ return pce->serial; return 0; } EOF -if { (eval echo configure:4581: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4583: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_ppsclockev=yes else @@ -4598,12 +4600,12 @@ EOF fi echo $ac_n "checking struct sockaddr for sa_len... $ac_c" 1>&6 -echo "configure:4602: checking struct sockaddr for sa_len" 1>&5 +echo "configure:4604: checking struct sockaddr for sa_len" 1>&5 if test "${ac_cv_struct_sockaddr_has_sa_len+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -4618,7 +4620,7 @@ return ps->sa_len; return 0; } EOF -if { (eval echo configure:4622: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4624: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_sockaddr_has_sa_len=yes else @@ -4639,12 +4641,12 @@ EOF fi echo $ac_n "checking struct clockinfo for hz... $ac_c" 1>&6 -echo "configure:4643: checking struct clockinfo for hz" 1>&5 +echo "configure:4645: checking struct clockinfo for hz" 1>&5 if test "${ac_cv_struct_clockinfo_has_hz+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -4658,7 +4660,7 @@ return pc->hz; return 0; } EOF -if { (eval echo configure:4662: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4664: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_clockinfo_has_hz=yes else @@ -4679,12 +4681,12 @@ EOF fi echo $ac_n "checking struct clockinfo for tickadj... $ac_c" 1>&6 -echo "configure:4683: checking struct clockinfo for tickadj" 1>&5 +echo "configure:4685: checking struct clockinfo for tickadj" 1>&5 if test "${ac_cv_struct_clockinfo_has_tickadj+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -4698,7 +4700,7 @@ return pc->tickadj; return 0; } EOF -if { (eval echo configure:4702: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4704: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_clockinfo_has_tickadj=yes else @@ -4719,12 +4721,12 @@ EOF fi echo $ac_n "checking for struct ntptimeval... $ac_c" 1>&6 -echo "configure:4723: checking for struct ntptimeval" 1>&5 +echo "configure:4725: checking for struct ntptimeval" 1>&5 if test "${ac_cv_struct_ntptimeval+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -4737,7 +4739,7 @@ struct ntptimeval n; return 0; } EOF -if { (eval echo configure:4741: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4743: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_ntptimeval=yes else @@ -4757,12 +4759,12 @@ EOF fi echo $ac_n "checking struct ntptimeval for time.tv_nsec... $ac_c" 1>&6 -echo "configure:4761: checking struct ntptimeval for time.tv_nsec" 1>&5 +echo "configure:4763: checking struct ntptimeval for time.tv_nsec" 1>&5 if test "${ac_cv_struct_ntptimeval_tv_nsec+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <time.tv_nsec; return 0; } EOF -if { (eval echo configure:4793: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4795: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_ntptimeval_tv_nsec=yes else @@ -4810,12 +4812,12 @@ EOF fi echo $ac_n "checking for struct timespec in struct ntptimeval... $ac_c" 1>&6 -echo "configure:4814: checking for struct timespec in struct ntptimeval" 1>&5 +echo "configure:4816: checking for struct timespec in struct ntptimeval" 1>&5 if test "${ac_cv_struct_ntptimeval_timespec+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #include @@ -4827,7 +4829,7 @@ struct ntptimeval n; n.time.tv_nsec = 0; return 0; } EOF -if { (eval echo configure:4831: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4833: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_ntptimeval_timespec=yes else @@ -4847,14 +4849,14 @@ EOF fi echo $ac_n "checking for inline... $ac_c" 1>&6 -echo "configure:4851: checking for inline" 1>&5 +echo "configure:4853: checking for inline" 1>&5 if test "${ac_cv_c_inline+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4874: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -4893,14 +4895,14 @@ EOF esac echo $ac_n "checking whether char is unsigned... $ac_c" 1>&6 -echo "configure:4897: checking whether char is unsigned" 1>&5 +echo "configure:4899: checking whether char is unsigned" 1>&5 if test "${ac_cv_c_char_unsigned+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$GCC" = yes; then # GCC predefines this symbol on systems where it applies. cat >conftest.$ac_ext <&2; exit 1; } else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_char_unsigned=yes else @@ -4960,7 +4962,7 @@ fi case "$host" in $target) echo $ac_n "checking size of signed char... $ac_c" 1>&6 -echo "configure:4964: checking size of signed char" 1>&5 +echo "configure:4966: checking size of signed char" 1>&5 if test "${ac_cv_sizeof_signed_char+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4968,7 +4970,7 @@ else { echo "configure: error: cannot run test program while cross compiling" 1>&2; exit 1; } else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4987: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_signed_char=`cat conftestval` else @@ -5004,7 +5006,7 @@ EOF *) case "$target" in *-*-vxworks*) echo $ac_n "checking size of signed char... $ac_c" 1>&6 -echo "configure:5008: checking size of signed char" 1>&5 +echo "configure:5010: checking size of signed char" 1>&5 if test "${ac_cv_sizeof_signed_char+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5012,7 +5014,7 @@ else ac_cv_sizeof_signed_char=1 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_signed_char=`cat conftestval` else @@ -5054,7 +5056,7 @@ esac case "$host" in $target) echo $ac_n "checking size of int... $ac_c" 1>&6 -echo "configure:5058: checking size of int" 1>&5 +echo "configure:5060: checking size of int" 1>&5 if test "${ac_cv_sizeof_int+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5062,7 +5064,7 @@ else { echo "configure: error: cannot run test program while cross compiling" 1>&2; exit 1; } else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5081: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_int=`cat conftestval` else @@ -5098,7 +5100,7 @@ EOF *) case "$target" in *-*-vxworks*) echo $ac_n "checking size of int... $ac_c" 1>&6 -echo "configure:5102: checking size of int" 1>&5 +echo "configure:5104: checking size of int" 1>&5 if test "${ac_cv_sizeof_int+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5106,7 +5108,7 @@ else ac_cv_sizeof_int=4 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5125: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_int=`cat conftestval` else @@ -5148,7 +5150,7 @@ esac case "$host" in $target) echo $ac_n "checking size of long... $ac_c" 1>&6 -echo "configure:5152: checking size of long" 1>&5 +echo "configure:5154: checking size of long" 1>&5 if test "${ac_cv_sizeof_long+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5156,7 +5158,7 @@ else { echo "configure: error: cannot run test program while cross compiling" 1>&2; exit 1; } else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5175: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -5192,7 +5194,7 @@ EOF *) case "$target" in *-*-vxworks*) echo $ac_n "checking size of long... $ac_c" 1>&6 -echo "configure:5196: checking size of long" 1>&5 +echo "configure:5198: checking size of long" 1>&5 if test "${ac_cv_sizeof_long+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5200,7 +5202,7 @@ else ac_cv_sizeof_long=4 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5219: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -5240,12 +5242,12 @@ EOF esac echo $ac_n "checking for s_char... $ac_c" 1>&6 -echo "configure:5244: checking for s_char" 1>&5 +echo "configure:5246: checking for s_char" 1>&5 if test "${ac_cv_type_s_char+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5265: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_s_char=yes else @@ -5309,12 +5311,12 @@ EOF ;; esac echo $ac_n "checking for uid_t in sys/types.h... $ac_c" 1>&6 -echo "configure:5313: checking for uid_t in sys/types.h" 1>&5 +echo "configure:5315: checking for uid_t in sys/types.h" 1>&5 if test "${ac_cv_type_uid_t+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -5348,12 +5350,12 @@ case "$target" in do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:5352: checking for $ac_func" 1>&5 +echo "configure:5354: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -5416,12 +5418,12 @@ case "$target" in do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:5420: checking for $ac_func" 1>&5 +echo "configure:5422: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5455: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -5476,12 +5478,12 @@ for ac_func in daemon getbootfile getdtablesize getrusage do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:5480: checking for $ac_func" 1>&5 +echo "configure:5482: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5515: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -5534,12 +5536,12 @@ for ac_func in gettimeofday do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:5538: checking for $ac_func" 1>&5 +echo "configure:5540: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -5595,12 +5597,12 @@ case "$target" in do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:5599: checking for $ac_func" 1>&5 +echo "configure:5601: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5634: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -5655,12 +5657,12 @@ for ac_func in K_open kvm_open memcpy memmove memset do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:5659: checking for $ac_func" 1>&5 +echo "configure:5661: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -5717,12 +5719,12 @@ case "$target" in do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:5721: checking for $ac_func" 1>&5 +echo "configure:5723: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5756: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -5777,12 +5779,12 @@ for ac_func in mktime do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:5781: checking for $ac_func" 1>&5 +echo "configure:5783: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5816: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -5850,12 +5852,12 @@ case "$target" in do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:5854: checking for $ac_func" 1>&5 +echo "configure:5856: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5889: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -5908,12 +5910,12 @@ done do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:5912: checking for $ac_func" 1>&5 +echo "configure:5914: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5947: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -5967,12 +5969,12 @@ done do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:5971: checking for $ac_func" 1>&5 +echo "configure:5973: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6006: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6027,12 +6029,12 @@ for ac_func in mrand48 srand48 nice nlist do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:6031: checking for $ac_func" 1>&5 +echo "configure:6033: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6066: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6089,12 +6091,12 @@ case "$target" in do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:6093: checking for $ac_func" 1>&5 +echo "configure:6095: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6149,12 +6151,12 @@ for ac_func in plock pututline pututxline rtprio do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:6153: checking for $ac_func" 1>&5 +echo "configure:6155: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6188: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6209,12 +6211,12 @@ case "$ac_cv_func_mrand48" in do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:6213: checking for $ac_func" 1>&5 +echo "configure:6215: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6248: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6278,12 +6280,12 @@ case "$target" in do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:6282: checking for $ac_func" 1>&5 +echo "configure:6284: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6317: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6338,12 +6340,12 @@ for ac_func in setlinebuf do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:6342: checking for $ac_func" 1>&5 +echo "configure:6344: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6377: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6396,12 +6398,12 @@ for ac_func in setpgid setpriority setsid settimeofday setvbuf sigaction do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:6400: checking for $ac_func" 1>&5 +echo "configure:6402: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6435: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6454,12 +6456,12 @@ for ac_func in sigvec sigset sigsuspend stime strchr sysconf sysctl do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:6458: checking for $ac_func" 1>&5 +echo "configure:6460: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6493: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6512,12 +6514,12 @@ for ac_func in strerror do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:6516: checking for $ac_func" 1>&5 +echo "configure:6518: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6582,12 +6584,12 @@ case "$target" in do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:6586: checking for $ac_func" 1>&5 +echo "configure:6588: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6621: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6646,12 +6648,12 @@ case "$target" in do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:6650: checking for $ac_func" 1>&5 +echo "configure:6652: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6685: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6706,12 +6708,12 @@ for ac_func in uname updwtmp updwtmpx vsprintf do ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh` echo $ac_n "checking for $ac_func... $ac_c" 1>&6 -echo "configure:6710: checking for $ac_func" 1>&5 +echo "configure:6712: checking for $ac_func" 1>&5 if eval "test \"\${$ac_ac_var+set}\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "$ac_ac_var=yes" else @@ -6761,12 +6763,12 @@ fi done echo $ac_n "checking number of arguments to gettimeofday()... $ac_c" 1>&6 -echo "configure:6765: checking number of arguments to gettimeofday()" 1>&5 +echo "configure:6767: checking number of arguments to gettimeofday()" 1>&5 if test "${ac_cv_func_Xettimeofday_nargs+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < int @@ -6780,7 +6782,7 @@ settimeofday((struct timeval*)0,(struct timezone*)0); return 0; } EOF -if { (eval echo configure:6784: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6786: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_func_Xettimeofday_nargs=2 else @@ -6801,12 +6803,12 @@ EOF fi echo $ac_n "checking number of arguments taken by setpgrp()... $ac_c" 1>&6 -echo "configure:6805: checking number of arguments taken by setpgrp()" 1>&5 +echo "configure:6807: checking number of arguments taken by setpgrp()" 1>&5 if test "${ac_cv_func_setpgrp_nargs+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_func_setpgrp_nargs=2 else @@ -6848,12 +6850,12 @@ save_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -I$srcdir/include" echo $ac_n "checking argument pointer type of qsort()'s compare function and base... $ac_c" 1>&6 -echo "configure:6852: checking argument pointer type of qsort()'s compare function and base" 1>&5 +echo "configure:6854: checking argument pointer type of qsort()'s compare function and base" 1>&5 if test "${ac_cv_func_qsort_argtype+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6886: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_func_qsort_argtype=void else @@ -6905,12 +6907,12 @@ esac CFLAGS=$save_CFLAGS echo $ac_n "checking if we need to declare 'errno'... $ac_c" 1>&6 -echo "configure:6909: checking if we need to declare 'errno'" 1>&5 +echo "configure:6911: checking if we need to declare 'errno'" 1>&5 if test "${ac_cv_decl_errno+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -6923,7 +6925,7 @@ errno = 0; return 0; } EOF -if { (eval echo configure:6927: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6929: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_decl_errno=no else @@ -6943,12 +6945,12 @@ EOF esac echo $ac_n "checking if we may declare 'h_errno'... $ac_c" 1>&6 -echo "configure:6947: checking if we may declare 'h_errno'" 1>&5 +echo "configure:6949: checking if we may declare 'h_errno'" 1>&5 if test "${ac_cv_decl_h_errno+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #ifdef HAVE_NETINET_IN_H @@ -6971,7 +6973,7 @@ extern int h_errno; return 0; } EOF -if { (eval echo configure:6975: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6977: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_decl_h_errno=yes else @@ -6991,12 +6993,12 @@ EOF esac echo $ac_n "checking if declaring 'char *sys_errlist[]' is ok... $ac_c" 1>&6 -echo "configure:6995: checking [if declaring 'char *sys_errlist[]' is ok]" 1>&5 +echo "configure:6997: checking [if declaring 'char *sys_errlist[]' is ok]" 1>&5 if test "${ac_cv_decl_sys_errlist+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #ifdef HAVE_ERRNO_H @@ -7011,7 +7013,7 @@ extern char *sys_errlist[]; return 0; } EOF -if { (eval echo configure:7015: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7017: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_decl_sys_errlist=yes else @@ -7031,12 +7033,12 @@ EOF esac echo $ac_n "checking if declaring 'syscall()' is ok... $ac_c" 1>&6 -echo "configure:7035: checking if declaring 'syscall()' is ok" 1>&5 +echo "configure:7037: checking if declaring 'syscall()' is ok" 1>&5 if test "${ac_cv_decl_syscall+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7065: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_decl_syscall=yes else @@ -7345,7 +7347,7 @@ EOF esac echo $ac_n "checking if we should use a streams device for ifconfig... $ac_c" 1>&6 -echo "configure:7349: checking if we should use a streams device for ifconfig" 1>&5 +echo "configure:7351: checking if we should use a streams device for ifconfig" 1>&5 if test "${ac_cv_var_use_streams_device_for_ifconfig+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7354,7 +7356,7 @@ fi echo "$ac_t""$ac_cv_var_use_streams_device_for_ifconfig" 1>&6 echo $ac_n "checking if we need extra room for SO_RCVBUF... $ac_c" 1>&6 -echo "configure:7358: checking if we need extra room for SO_RCVBUF" 1>&5 +echo "configure:7360: checking if we need extra room for SO_RCVBUF" 1>&5 if test "${ac_cv_var_rcvbuf_slop+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7375,7 +7377,7 @@ EOF esac echo $ac_n "checking if we will open the broadcast socket... $ac_c" 1>&6 -echo "configure:7379: checking if we will open the broadcast socket" 1>&5 +echo "configure:7381: checking if we will open the broadcast socket" 1>&5 if test "${ac_cv_var_open_bcast_socket+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7399,7 +7401,7 @@ EOF esac echo $ac_n "checking if we want the HPUX version of FindConfig()... $ac_c" 1>&6 -echo "configure:7403: checking if we want the HPUX version of FindConfig()" 1>&5 +echo "configure:7405: checking if we want the HPUX version of FindConfig()" 1>&5 if test "${ac_cv_var_hpux_findconfig+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7420,7 +7422,7 @@ EOF esac echo $ac_n "checking if process groups are set with -pid... $ac_c" 1>&6 -echo "configure:7424: checking if process groups are set with -pid" 1>&5 +echo "configure:7426: checking if process groups are set with -pid" 1>&5 if test "${ac_cv_arg_setpgrp_negpid+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7455,7 +7457,7 @@ EOF esac echo $ac_n "checking if we need a ctty for F_SETOWN... $ac_c" 1>&6 -echo "configure:7459: checking if we need a ctty for F_SETOWN" 1>&5 +echo "configure:7461: checking if we need a ctty for F_SETOWN" 1>&5 if test "${ac_cv_func_ctty_for_f_setown+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7490,7 +7492,7 @@ esac ntp_warning='GRONK' echo $ac_n "checking if we'll use clock_settime or settimeofday or stime... $ac_c" 1>&6 -echo "configure:7494: checking if we'll use clock_settime or settimeofday or stime" 1>&5 +echo "configure:7496: checking if we'll use clock_settime or settimeofday or stime" 1>&5 case "$ac_cv_func_clock_settime$ac_cv_func_settimeofday$ac_cv_func_stime" in yes*) ntp_warning='' @@ -7519,7 +7521,7 @@ case "$ntp_warning" in esac echo $ac_n "checking if we have a losing syscall()... $ac_c" 1>&6 -echo "configure:7523: checking if we have a losing syscall()" 1>&5 +echo "configure:7525: checking if we have a losing syscall()" 1>&5 if test "${ac_cv_var_syscall_bug+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7541,7 +7543,7 @@ EOF esac echo $ac_n "checking for Streams/TLI... $ac_c" 1>&6 -echo "configure:7545: checking for Streams/TLI" 1>&5 +echo "configure:7547: checking for Streams/TLI" 1>&5 if test "${ac_cv_var_streams_tli+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7569,12 +7571,12 @@ EOF esac echo $ac_n "checking for SIGIO... $ac_c" 1>&6 -echo "configure:7573: checking for SIGIO" 1>&5 +echo "configure:7575: checking for SIGIO" 1>&5 if test "${ac_cv_hdr_def_sigio+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #ifdef SIGIO @@ -7596,7 +7598,7 @@ fi echo "$ac_t""$ac_cv_hdr_def_sigio" 1>&6 echo $ac_n "checking if we want to use signalled IO... $ac_c" 1>&6 -echo "configure:7600: checking if we want to use signalled IO" 1>&5 +echo "configure:7602: checking if we want to use signalled IO" 1>&5 if test "${ac_cv_var_signalled_io+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7646,12 +7648,12 @@ EOF esac echo $ac_n "checking for SIGPOLL... $ac_c" 1>&6 -echo "configure:7650: checking for SIGPOLL" 1>&5 +echo "configure:7652: checking for SIGPOLL" 1>&5 if test "${ac_cv_hdr_def_sigpoll+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #ifdef SIGPOLL @@ -7673,12 +7675,12 @@ fi echo "$ac_t""$ac_cv_hdr_def_sigpoll" 1>&6 echo $ac_n "checking for SIGSYS... $ac_c" 1>&6 -echo "configure:7677: checking for SIGSYS" 1>&5 +echo "configure:7679: checking for SIGSYS" 1>&5 if test "${ac_cv_hdr_def_sigsys+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #ifdef SIGSYS @@ -7700,7 +7702,7 @@ fi echo "$ac_t""$ac_cv_hdr_def_sigsys" 1>&6 echo $ac_n "checking if we can use SIGPOLL for UDP I/O... $ac_c" 1>&6 -echo "configure:7704: checking if we can use SIGPOLL for UDP I/O" 1>&5 +echo "configure:7706: checking if we can use SIGPOLL for UDP I/O" 1>&5 if test "${ac_cv_var_use_udp_sigpoll+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7754,7 +7756,7 @@ EOF esac echo $ac_n "checking if we can use SIGPOLL for TTY I/O... $ac_c" 1>&6 -echo "configure:7758: checking if we can use SIGPOLL for TTY I/O" 1>&5 +echo "configure:7760: checking if we can use SIGPOLL for TTY I/O" 1>&5 if test "${ac_cv_var_use_tty_sigpoll+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7810,12 +7812,12 @@ esac case "$ac_cv_header_sys_sio_h" in yes) echo $ac_n "checking sys/sio.h for TIOCDCDTIMESTAMP... $ac_c" 1>&6 -echo "configure:7814: checking sys/sio.h for TIOCDCDTIMESTAMP" 1>&5 +echo "configure:7816: checking sys/sio.h for TIOCDCDTIMESTAMP" 1>&5 if test "${ac_cv_hdr_def_tiocdcdtimestamp+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #ifdef TIOCDCDTIMESTAMP @@ -7845,7 +7847,7 @@ case "$ac_cv_hdr_def_tiocdcdtimestamp" in esac echo $ac_n "checking if nlist() values might require extra indirection... $ac_c" 1>&6 -echo "configure:7849: checking if nlist() values might require extra indirection" 1>&5 +echo "configure:7851: checking if nlist() values might require extra indirection" 1>&5 if test "${ac_cv_var_nlist_extra_indirection+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7866,7 +7868,7 @@ EOF esac echo $ac_n "checking for a minimum recommended value of tickadj... $ac_c" 1>&6 -echo "configure:7870: checking for a minimum recommended value of tickadj" 1>&5 +echo "configure:7872: checking for a minimum recommended value of tickadj" 1>&5 if test "${ac_cv_var_min_rec_tickadj+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7888,7 +7890,7 @@ EOF esac echo $ac_n "checking if the TTY code permits PARENB and IGNPAR... $ac_c" 1>&6 -echo "configure:7892: checking if the TTY code permits PARENB and IGNPAR" 1>&5 +echo "configure:7894: checking if the TTY code permits PARENB and IGNPAR" 1>&5 if test "${ac_cv_var_no_parenb_ignpar+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7912,7 +7914,7 @@ EOF esac echo $ac_n "checking if we're including debugging code... $ac_c" 1>&6 -echo "configure:7916: checking if we're including debugging code" 1>&5 +echo "configure:7918: checking if we're including debugging code" 1>&5 # Check whether --enable-debugging or --disable-debugging was given. if test "${enable_debugging+set}" = set; then enableval="$enable_debugging" @@ -7930,7 +7932,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking for a the number of minutes in a DST adjustment... $ac_c" 1>&6 -echo "configure:7934: checking for a the number of minutes in a DST adjustment" 1>&5 +echo "configure:7936: checking for a the number of minutes in a DST adjustment" 1>&5 # Check whether --enable-dst_minutes or --disable-dst_minutes was given. if test "${enable_dst_minutes+set}" = set; then enableval="$enable_dst_minutes" @@ -7946,7 +7948,7 @@ EOF echo "$ac_t""$ans" 1>&6 echo $ac_n "checking if we have the tty_clk line discipline/streams module... $ac_c" 1>&6 -echo "configure:7950: checking if we have the tty_clk line discipline/streams module" 1>&5 +echo "configure:7952: checking if we have the tty_clk line discipline/streams module" 1>&5 if test "${ac_cv_var_tty_clk+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7963,7 +7965,7 @@ EOF esac echo $ac_n "checking for the ppsclock streams module... $ac_c" 1>&6 -echo "configure:7967: checking for the ppsclock streams module" 1>&5 +echo "configure:7969: checking for the ppsclock streams module" 1>&5 if test "${ac_cv_var_ppsclock+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7978,7 +7980,7 @@ EOF esac echo $ac_n "checking for kernel multicast support... $ac_c" 1>&6 -echo "configure:7982: checking for kernel multicast support" 1>&5 +echo "configure:7984: checking for kernel multicast support" 1>&5 if test "${ac_cv_var_mcast+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7986,7 +7988,7 @@ else case "$target" in i386-sequent-sysv4) ;; *) cat >conftest.$ac_ext < #ifdef IP_ADD_MEMBERSHIP @@ -8012,7 +8014,7 @@ EOF esac echo $ac_n "checking availability of ntp_{adj,get}time()... $ac_c" 1>&6 -echo "configure:8016: checking [availability of ntp_{adj,get}time()]" 1>&5 +echo "configure:8018: checking [availability of ntp_{adj,get}time()]" 1>&5 if test "${ac_cv_var_ntp_syscalls+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8026,7 +8028,7 @@ else ac_cv_var_ntp_syscalls=libc ;; *) cat >conftest.$ac_ext < #if defined(SYS_ntp_gettime) && defined(SYS_ntp_adjtime) @@ -8065,12 +8067,12 @@ EOF esac echo $ac_n "checking if sys/timex.h has STA_FLL... $ac_c" 1>&6 -echo "configure:8069: checking if sys/timex.h has STA_FLL" 1>&5 +echo "configure:8071: checking if sys/timex.h has STA_FLL" 1>&5 if test "${ac_cv_var_sta_fll+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < #ifdef STA_FLL @@ -8092,7 +8094,7 @@ fi echo "$ac_t""$ac_cv_var_sta_fll" 1>&6 echo $ac_n "checking if we have kernel PLL support... $ac_c" 1>&6 -echo "configure:8096: checking if we have kernel PLL support" 1>&5 +echo "configure:8098: checking if we have kernel PLL support" 1>&5 if test "${ac_cv_var_kernel_pll+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8115,7 +8117,7 @@ EOF esac echo $ac_n "checking if SIOCGIFCONF returns buffer size in the buffer... $ac_c" 1>&6 -echo "configure:8119: checking if SIOCGIFCONF returns buffer size in the buffer" 1>&5 +echo "configure:8121: checking if SIOCGIFCONF returns buffer size in the buffer" 1>&5 if test "${ac_cv_var_size_returned_in_buffer+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8142,7 +8144,7 @@ EOF esac echo $ac_n "checking if we want to use MD5 authentication... $ac_c" 1>&6 -echo "configure:8146: checking if we want to use MD5 authentication" 1>&5 +echo "configure:8148: checking if we want to use MD5 authentication" 1>&5 if test "${ac_cv_var_use_md5+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8158,18 +8160,24 @@ ac_cv_var_use_md5=$ans fi echo "$ac_t""$ac_cv_var_use_md5" 1>&6 case "$ac_cv_var_use_md5" in - yes) cat >>confdefs.h <<\EOF + yes) + cat >>confdefs.h <<\EOF +#define AUTOKEY +EOF + + cat >>confdefs.h <<\EOF #define MD5 1 EOF - ;; + + ;; esac # Check for ioctls TIOCGPPSEV echo $ac_n "checking ioctl TIOCGPPSEV... $ac_c" 1>&6 -echo "configure:8170: checking ioctl TIOCGPPSEV" 1>&5 +echo "configure:8178: checking ioctl TIOCGPPSEV" 1>&5 if test "$ac_cv_header_termios_h" = "yes"; then cat >conftest.$ac_ext < #ifdef TIOCGPPSEV @@ -8201,10 +8209,10 @@ echo "$ac_t""$ntp_ok" 1>&6 # Check for ioctls TIOCSPPS echo $ac_n "checking ioctl TIOCSPPS... $ac_c" 1>&6 -echo "configure:8205: checking ioctl TIOCSPPS" 1>&5 +echo "configure:8213: checking ioctl TIOCSPPS" 1>&5 if test "$ac_cv_header_termios_h" = "yes"; then cat >conftest.$ac_ext < #ifdef TIOCSPPS @@ -8236,10 +8244,10 @@ echo "$ac_t""$ntp_ok" 1>&6 # Check for ioctls CIOGETEV echo $ac_n "checking ioctl CIOGETEV... $ac_c" 1>&6 -echo "configure:8240: checking ioctl CIOGETEV" 1>&5 +echo "configure:8248: checking ioctl CIOGETEV" 1>&5 if test "$ac_cv_header_sys_ppsclock_h" = "yes"; then cat >conftest.$ac_ext < #ifdef CIOGETEV @@ -8289,18 +8297,18 @@ esac # Check for ioctls TIOCGSERIAL, TIOCSSERIAL, ASYNC_PPS_CD_POS, ASYNC_PPS_CD_NEG echo $ac_n "checking for linux/serial.h... $ac_c" 1>&6 -echo "configure:8293: checking for linux/serial.h" 1>&5 +echo "configure:8301: checking for linux/serial.h" 1>&5 if test "${ac_cv_header_linux_serial_h+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8304: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8312: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -8317,11 +8325,11 @@ fi echo "$ac_t""$ac_cv_header_linux_serial_h" 1>&6 echo $ac_n "checking ioctl TIOCGSERIAL... $ac_c" 1>&6 -echo "configure:8321: checking ioctl TIOCGSERIAL" 1>&5 +echo "configure:8329: checking ioctl TIOCGSERIAL" 1>&5 case "$ac_cv_header_sys_ppsclock_h$ac_cv_header_linux_serial_h" in yesyes) cat >conftest.$ac_ext < typedef int u_int; @@ -8364,7 +8372,7 @@ echo "$ac_t""$ntp_ok" 1>&6 # Check for SHMEM_STATUS support echo $ac_n "checking SHMEM_STATUS support... $ac_c" 1>&6 -echo "configure:8368: checking SHMEM_STATUS support" 1>&5 +echo "configure:8376: checking SHMEM_STATUS support" 1>&5 case "$ac_cv_header_sys_mman_h" in yes) ntp_ok=yes ;; *) ntp_ok=no ;; @@ -8381,7 +8389,7 @@ ntp_refclock=no # HPUX only, and by explicit request echo $ac_n "checking Datum/Bancomm bc635/VME interface... $ac_c" 1>&6 -echo "configure:8385: checking Datum/Bancomm bc635/VME interface" 1>&5 +echo "configure:8393: checking Datum/Bancomm bc635/VME interface" 1>&5 # Check whether --enable-BANCOMM or --disable-BANCOMM was given. if test "${enable_BANCOMM+set}" = set; then enableval="$enable_BANCOMM" @@ -8405,7 +8413,7 @@ esac #HPUX only, and only by explicit request echo $ac_n "checking TrueTime GPS receiver/VME interface... $ac_c" 1>&6 -echo "configure:8409: checking TrueTime GPS receiver/VME interface" 1>&5 +echo "configure:8417: checking TrueTime GPS receiver/VME interface" 1>&5 # Check whether --enable-GPSVME or --disable-GPSVME was given. if test "${enable_GPSVME+set}" = set; then enableval="$enable_GPSVME" @@ -8428,7 +8436,7 @@ case "$ntp_ok$target" in esac echo $ac_n "checking for PCL720 clock support... $ac_c" 1>&6 -echo "configure:8432: checking for PCL720 clock support" 1>&5 +echo "configure:8440: checking for PCL720 clock support" 1>&5 case "$ac_cv_header_machine_inline_h$ac_cv_header_sys_pcl720_h$ac_cv_header_sys_i8253_h" in yesyesyes) cat >>confdefs.h <<\EOF @@ -8444,7 +8452,7 @@ esac echo "$ac_t""$ans" 1>&6 echo $ac_n "checking for SHM clock attached thru shared memory... $ac_c" 1>&6 -echo "configure:8448: checking for SHM clock attached thru shared memory" 1>&5 +echo "configure:8456: checking for SHM clock attached thru shared memory" 1>&5 # Check whether --enable-SHM or --disable-SHM was given. if test "${enable_SHM+set}" = set; then enableval="$enable_SHM" @@ -8463,7 +8471,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking for default inclusion of all suitable non-PARSE clocks... $ac_c" 1>&6 -echo "configure:8467: checking for default inclusion of all suitable non-PARSE clocks" 1>&5 +echo "configure:8475: checking for default inclusion of all suitable non-PARSE clocks" 1>&5 # Check whether --enable-all-clocks or --disable-all-clocks was given. if test "${enable_all_clocks+set}" = set; then enableval="$enable_all_clocks" @@ -8475,7 +8483,7 @@ fi echo "$ac_t""$ntp_eac" 1>&6 echo $ac_n "checking if we have support for PARSE clocks... $ac_c" 1>&6 -echo "configure:8479: checking if we have support for PARSE clocks" 1>&5 +echo "configure:8487: checking if we have support for PARSE clocks" 1>&5 case "$ac_cv_header_termio_h$ac_cv_header_termios_h" in *yes*) ntp_canparse=yes @@ -8486,7 +8494,7 @@ esac echo "$ac_t""$ntp_canparse" 1>&6 echo $ac_n "checking if we have support for audio clocks... $ac_c" 1>&6 -echo "configure:8490: checking if we have support for audio clocks" 1>&5 +echo "configure:8498: checking if we have support for audio clocks" 1>&5 case "$ac_cv_header_sun_audioio_h$ac_cv_header_sys_audioio_h" in *yes*) ntp_canaudio=yes ;; *) ntp_canaudio=no ;; @@ -8494,12 +8502,12 @@ esac echo "$ac_t""$ntp_canaudio" 1>&6 echo $ac_n "checking for struct audio_info.monitor_gain... $ac_c" 1>&6 -echo "configure:8498: checking for struct audio_info.monitor_gain" 1>&5 +echo "configure:8506: checking for struct audio_info.monitor_gain" 1>&5 if test "${ac_cv_member_struct_audio_info_monitor_gain+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -8517,7 +8525,7 @@ foo.monitor_gain; return 0; } EOF -if { (eval echo configure:8521: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8529: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_member_struct_audio_info_monitor_gain=yes else @@ -8537,12 +8545,12 @@ EOF fi echo $ac_n "checking for struct audio_info.output_muted... $ac_c" 1>&6 -echo "configure:8541: checking for struct audio_info.output_muted" 1>&5 +echo "configure:8549: checking for struct audio_info.output_muted" 1>&5 if test "${ac_cv_member_struct_audio_info_output_muted+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -8560,7 +8568,7 @@ foo.output_muted; return 0; } EOF -if { (eval echo configure:8564: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8572: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_member_struct_audio_info_output_muted=yes else @@ -8580,12 +8588,12 @@ EOF fi echo $ac_n "checking for struct audio_info.blocksize... $ac_c" 1>&6 -echo "configure:8584: checking for struct audio_info.blocksize" 1>&5 +echo "configure:8592: checking for struct audio_info.blocksize" 1>&5 if test "${ac_cv_member_struct_audio_info_blocksize+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -8603,7 +8611,7 @@ foo.blocksize; return 0; } EOF -if { (eval echo configure:8607: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8615: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_member_struct_audio_info_blocksize=yes else @@ -8623,12 +8631,12 @@ EOF fi echo $ac_n "checking for struct audio_info.hiwat... $ac_c" 1>&6 -echo "configure:8627: checking for struct audio_info.hiwat" 1>&5 +echo "configure:8635: checking for struct audio_info.hiwat" 1>&5 if test "${ac_cv_member_struct_audio_info_hiwat+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -8646,7 +8654,7 @@ foo.hiwat; return 0; } EOF -if { (eval echo configure:8650: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8658: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_member_struct_audio_info_hiwat=yes else @@ -8666,12 +8674,12 @@ EOF fi echo $ac_n "checking for struct audio_info.lowat... $ac_c" 1>&6 -echo "configure:8670: checking for struct audio_info.lowat" 1>&5 +echo "configure:8678: checking for struct audio_info.lowat" 1>&5 if test "${ac_cv_member_struct_audio_info_lowat+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -8689,7 +8697,7 @@ foo.lowat; return 0; } EOF -if { (eval echo configure:8693: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8701: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_member_struct_audio_info_lowat=yes else @@ -8709,12 +8717,12 @@ EOF fi echo $ac_n "checking for struct audio_info.mode... $ac_c" 1>&6 -echo "configure:8713: checking for struct audio_info.mode" 1>&5 +echo "configure:8721: checking for struct audio_info.mode" 1>&5 if test "${ac_cv_member_struct_audio_info_mode+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else cat >conftest.$ac_ext < @@ -8732,7 +8740,7 @@ foo.mode; return 0; } EOF -if { (eval echo configure:8736: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8744: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_member_struct_audio_info_mode=yes else @@ -8753,14 +8761,14 @@ fi # Requires modem control echo $ac_n "checking ACTS modem service... $ac_c" 1>&6 -echo "configure:8757: checking ACTS modem service" 1>&5 +echo "configure:8765: checking ACTS modem service" 1>&5 # Check whether --enable-ACTS or --disable-ACTS was given. if test "${enable_ACTS+set}" = set; then enableval="$enable_ACTS" ntp_ok=$enableval else cat >conftest.$ac_ext < #ifdef HAVE_SYS_IOCTL_H @@ -8793,7 +8801,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking Arbiter 1088A/B GPS receiver... $ac_c" 1>&6 -echo "configure:8797: checking Arbiter 1088A/B GPS receiver" 1>&5 +echo "configure:8805: checking Arbiter 1088A/B GPS receiver" 1>&5 # Check whether --enable-ARBITER or --disable-ARBITER was given. if test "${enable_ARBITER+set}" = set; then enableval="$enable_ARBITER" @@ -8812,7 +8820,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking Arcron MSF receiver... $ac_c" 1>&6 -echo "configure:8816: checking Arcron MSF receiver" 1>&5 +echo "configure:8824: checking Arcron MSF receiver" 1>&5 # Check whether --enable-ARCRON_MSF or --disable-ARCRON_MSF was given. if test "${enable_ARCRON_MSF+set}" = set; then enableval="$enable_ARCRON_MSF" @@ -8831,7 +8839,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking Austron 2200A/2201A GPS receiver... $ac_c" 1>&6 -echo "configure:8835: checking Austron 2200A/2201A GPS receiver" 1>&5 +echo "configure:8843: checking Austron 2200A/2201A GPS receiver" 1>&5 # Check whether --enable-AS2201 or --disable-AS2201 was given. if test "${enable_AS2201+set}" = set; then enableval="$enable_AS2201" @@ -8850,7 +8858,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking PPS interface... $ac_c" 1>&6 -echo "configure:8854: checking PPS interface" 1>&5 +echo "configure:8862: checking PPS interface" 1>&5 # Check whether --enable-ATOM or --disable-ATOM was given. if test "${enable_ATOM+set}" = set; then enableval="$enable_ATOM" @@ -8869,7 +8877,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking CHU modem/decoder... $ac_c" 1>&6 -echo "configure:8873: checking CHU modem/decoder" 1>&5 +echo "configure:8881: checking CHU modem/decoder" 1>&5 # Check whether --enable-CHU or --disable-CHU was given. if test "${enable_CHU+set}" = set; then enableval="$enable_CHU" @@ -8889,7 +8897,7 @@ echo "$ac_t""$ntp_ok" 1>&6 ac_refclock_chu=$ntp_ok echo $ac_n "checking CHU audio/decoder... $ac_c" 1>&6 -echo "configure:8893: checking CHU audio/decoder" 1>&5 +echo "configure:8901: checking CHU audio/decoder" 1>&5 # Check whether --enable-AUDIO-CHU or --disable-AUDIO-CHU was given. if test "${enable_AUDIO_CHU+set}" = set; then enableval="$enable_AUDIO_CHU" @@ -8915,7 +8923,7 @@ esac # Not under HP-UX echo $ac_n "checking Datum Programmable Time System... $ac_c" 1>&6 -echo "configure:8919: checking Datum Programmable Time System" 1>&5 +echo "configure:8927: checking Datum Programmable Time System" 1>&5 # Check whether --enable-DATUM or --disable-DATUM was given. if test "${enable_DATUM+set}" = set; then enableval="$enable_DATUM" @@ -8940,7 +8948,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking Forum Graphic GPS... $ac_c" 1>&6 -echo "configure:8944: checking Forum Graphic GPS" 1>&5 +echo "configure:8952: checking Forum Graphic GPS" 1>&5 # Check whether --enable-FG or --disable-FG was given. if test "${enable_FG+set}" = set; then enableval="$enable_FG" @@ -8960,14 +8968,14 @@ echo "$ac_t""$ntp_ok" 1>&6 # Requires modem control echo $ac_n "checking Heath GC-1000 WWV/WWVH receiver... $ac_c" 1>&6 -echo "configure:8964: checking Heath GC-1000 WWV/WWVH receiver" 1>&5 +echo "configure:8972: checking Heath GC-1000 WWV/WWVH receiver" 1>&5 # Check whether --enable-HEATH or --disable-HEATH was given. if test "${enable_HEATH+set}" = set; then enableval="$enable_HEATH" ntp_ok=$enableval else cat >conftest.$ac_ext < #ifdef HAVE_SYS_IOCTL_H @@ -9000,7 +9008,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking HP 58503A GPS receiver... $ac_c" 1>&6 -echo "configure:9004: checking HP 58503A GPS receiver" 1>&5 +echo "configure:9012: checking HP 58503A GPS receiver" 1>&5 # Check whether --enable-HPGPS or --disable-HPGPS was given. if test "${enable_HPGPS+set}" = set; then enableval="$enable_HPGPS" @@ -9019,7 +9027,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking Sun IRIG audio decoder... $ac_c" 1>&6 -echo "configure:9023: checking Sun IRIG audio decoder" 1>&5 +echo "configure:9031: checking Sun IRIG audio decoder" 1>&5 # Check whether --enable-IRIG or --disable-IRIG was given. if test "${enable_IRIG+set}" = set; then enableval="$enable_IRIG" @@ -9044,7 +9052,7 @@ case "$ntp_ok$ntp_canaudio" in esac echo $ac_n "checking Leitch CSD 5300 Master Clock System Driver... $ac_c" 1>&6 -echo "configure:9048: checking Leitch CSD 5300 Master Clock System Driver" 1>&5 +echo "configure:9056: checking Leitch CSD 5300 Master Clock System Driver" 1>&5 # Check whether --enable-LEITCH or --disable-LEITCH was given. if test "${enable_LEITCH+set}" = set; then enableval="$enable_LEITCH" @@ -9063,7 +9071,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking local clock reference... $ac_c" 1>&6 -echo "configure:9067: checking local clock reference" 1>&5 +echo "configure:9075: checking local clock reference" 1>&5 # Check whether --enable-LOCAL-CLOCK or --disable-LOCAL-CLOCK was given. if test "${enable_LOCAL_CLOCK+set}" = set; then enableval="$enable_LOCAL_CLOCK" @@ -9082,7 +9090,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking EES M201 MSF receiver... $ac_c" 1>&6 -echo "configure:9086: checking EES M201 MSF receiver" 1>&5 +echo "configure:9094: checking EES M201 MSF receiver" 1>&5 # Check whether --enable-MSFEES or --disable-MSFEES was given. if test "${enable_MSFEES+set}" = set; then enableval="$enable_MSFEES" @@ -9102,7 +9110,7 @@ echo "$ac_t""$ntp_ok" 1>&6 # Not Ultrix echo $ac_n "checking Magnavox MX4200 GPS receiver... $ac_c" 1>&6 -echo "configure:9106: checking Magnavox MX4200 GPS receiver" 1>&5 +echo "configure:9114: checking Magnavox MX4200 GPS receiver" 1>&5 # Check whether --enable-MX4200 or --disable-MX4200 was given. if test "${enable_MX4200+set}" = set; then enableval="$enable_MX4200" @@ -9129,7 +9137,7 @@ case "$ntp_ok$target" in esac echo $ac_n "checking NMEA GPS receiver... $ac_c" 1>&6 -echo "configure:9133: checking NMEA GPS receiver" 1>&5 +echo "configure:9141: checking NMEA GPS receiver" 1>&5 # Check whether --enable-NMEA or --disable-NMEA was given. if test "${enable_NMEA+set}" = set; then enableval="$enable_NMEA" @@ -9148,7 +9156,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking for ONCORE Motorola VP/UT Oncore GPS... $ac_c" 1>&6 -echo "configure:9152: checking for ONCORE Motorola VP/UT Oncore GPS" 1>&5 +echo "configure:9160: checking for ONCORE Motorola VP/UT Oncore GPS" 1>&5 # Check whether --enable-ONCORE or --disable-ONCORE was given. if test "${enable_ONCORE+set}" = set; then enableval="$enable_ONCORE" @@ -9170,7 +9178,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking for Palisade clock... $ac_c" 1>&6 -echo "configure:9174: checking for Palisade clock" 1>&5 +echo "configure:9182: checking for Palisade clock" 1>&5 # Check whether --enable-PALISADE or --disable-PALISADE was given. if test "${enable_PALISADE+set}" = set; then enableval="$enable_PALISADE" @@ -9195,7 +9203,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking PST/Traconex 1020 WWV/WWVH receiver... $ac_c" 1>&6 -echo "configure:9199: checking PST/Traconex 1020 WWV/WWVH receiver" 1>&5 +echo "configure:9207: checking PST/Traconex 1020 WWV/WWVH receiver" 1>&5 # Check whether --enable-PST or --disable-PST was given. if test "${enable_PST+set}" = set; then enableval="$enable_PST" @@ -9215,7 +9223,7 @@ echo "$ac_t""$ntp_ok" 1>&6 # Not Ultrix echo $ac_n "checking Rockwell Jupiter GPS receiver... $ac_c" 1>&6 -echo "configure:9219: checking Rockwell Jupiter GPS receiver" 1>&5 +echo "configure:9227: checking Rockwell Jupiter GPS receiver" 1>&5 # Check whether --enable-JUPITER or --disable-JUPITER was given. if test "${enable_JUPITER+set}" = set; then enableval="$enable_JUPITER" @@ -9243,14 +9251,14 @@ esac # Requires modem control echo $ac_n "checking PTB modem service... $ac_c" 1>&6 -echo "configure:9247: checking PTB modem service" 1>&5 +echo "configure:9255: checking PTB modem service" 1>&5 # Check whether --enable-PTBACTS or --disable-PTBACTS was given. if test "${enable_PTBACTS+set}" = set; then enableval="$enable_PTBACTS" ntp_ok=$enableval else cat >conftest.$ac_ext < #ifdef HAVE_SYS_IOCTL_H @@ -9283,7 +9291,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking KSI/Odetics TPRO/S GPS receiver/IRIG interface... $ac_c" 1>&6 -echo "configure:9287: checking KSI/Odetics TPRO/S GPS receiver/IRIG interface" 1>&5 +echo "configure:9295: checking KSI/Odetics TPRO/S GPS receiver/IRIG interface" 1>&5 # Check whether --enable-TPRO or --disable-TPRO was given. if test "${enable_TPRO+set}" = set; then enableval="$enable_TPRO" @@ -9311,7 +9319,7 @@ case "$ntp_ok$ac_cv_header_sys_tpro" in esac echo $ac_n "checking TRAK 8810 GPS receiver... $ac_c" 1>&6 -echo "configure:9315: checking TRAK 8810 GPS receiver" 1>&5 +echo "configure:9323: checking TRAK 8810 GPS receiver" 1>&5 # Check whether --enable-TRAK or --disable-TRAK was given. if test "${enable_TRAK+set}" = set; then enableval="$enable_TRAK" @@ -9330,7 +9338,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking Chrono-log K-series WWVB receiver... $ac_c" 1>&6 -echo "configure:9334: checking Chrono-log K-series WWVB receiver" 1>&5 +echo "configure:9342: checking Chrono-log K-series WWVB receiver" 1>&5 # Check whether --enable-CHRONOLOG or --disable-CHRONOLOG was given. if test "${enable_CHRONOLOG+set}" = set; then enableval="$enable_CHRONOLOG" @@ -9349,7 +9357,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking Dumb generic hh:mm:ss local clock... $ac_c" 1>&6 -echo "configure:9353: checking Dumb generic hh:mm:ss local clock" 1>&5 +echo "configure:9361: checking Dumb generic hh:mm:ss local clock" 1>&5 # Check whether --enable-DUMBCLOCK or --disable-DUMBCLOCK was given. if test "${enable_DUMBCLOCK+set}" = set; then enableval="$enable_DUMBCLOCK" @@ -9368,7 +9376,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking Conrad parallel port radio clock... $ac_c" 1>&6 -echo "configure:9372: checking Conrad parallel port radio clock" 1>&5 +echo "configure:9380: checking Conrad parallel port radio clock" 1>&5 # Check whether --enable-PCF or --disable-PCF was given. if test "${enable_PCF+set}" = set; then enableval="$enable_PCF" @@ -9387,7 +9395,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking Spectracom 8170/Netclock/2 WWVB receiver... $ac_c" 1>&6 -echo "configure:9391: checking Spectracom 8170/Netclock/2 WWVB receiver" 1>&5 +echo "configure:9399: checking Spectracom 8170/Netclock/2 WWVB receiver" 1>&5 # Check whether --enable-SPECTRACOM or --disable-SPECTRACOM was given. if test "${enable_SPECTRACOM+set}" = set; then enableval="$enable_SPECTRACOM" @@ -9407,7 +9415,7 @@ echo "$ac_t""$ntp_ok" 1>&6 # Not on a vax-dec-bsd echo $ac_n "checking Kinemetrics/TrueTime receivers... $ac_c" 1>&6 -echo "configure:9411: checking Kinemetrics/TrueTime receivers" 1>&5 +echo "configure:9419: checking Kinemetrics/TrueTime receivers" 1>&5 # Check whether --enable-TRUETIME or --disable-TRUETIME was given. if test "${enable_TRUETIME+set}" = set; then enableval="$enable_TRUETIME" @@ -9436,7 +9444,7 @@ case "$ntp_ok$target" in esac echo $ac_n "checking Ultralink M320 WWVB receiver... $ac_c" 1>&6 -echo "configure:9440: checking Ultralink M320 WWVB receiver" 1>&5 +echo "configure:9448: checking Ultralink M320 WWVB receiver" 1>&5 # Check whether --enable-ULINK or --disable-ULINK was given. if test "${enable_ULINK+set}" = set; then enableval="$enable_ULINK" @@ -9455,7 +9463,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking WWV receiver... $ac_c" 1>&6 -echo "configure:9459: checking WWV receiver" 1>&5 +echo "configure:9467: checking WWV receiver" 1>&5 # Check whether --enable-WWV or --disable-WWV was given. if test "${enable_WWV+set}" = set; then enableval="$enable_WWV" @@ -9481,14 +9489,14 @@ esac # Requires modem control echo $ac_n "checking USNO modem service... $ac_c" 1>&6 -echo "configure:9485: checking USNO modem service" 1>&5 +echo "configure:9493: checking USNO modem service" 1>&5 # Check whether --enable-USNO or --disable-USNO was given. if test "${enable_USNO+set}" = set; then enableval="$enable_USNO" ntp_ok=$enableval else cat >conftest.$ac_ext < #ifdef HAVE_SYS_IOCTL_H @@ -9521,7 +9529,7 @@ fi echo "$ac_t""$ntp_ok" 1>&6 echo $ac_n "checking for default inclusion of all suitable PARSE clocks... $ac_c" 1>&6 -echo "configure:9525: checking for default inclusion of all suitable PARSE clocks" 1>&5 +echo "configure:9533: checking for default inclusion of all suitable PARSE clocks" 1>&5 # Check whether --enable-parse-clocks or --disable-parse-clocks was given. if test "${enable_parse_clocks+set}" = set; then enableval="$enable_parse_clocks" @@ -9551,7 +9559,7 @@ ntp_parseutil=no ntp_rawdcf=no echo $ac_n "checking Diem Computime Radio Clock... $ac_c" 1>&6 -echo "configure:9555: checking Diem Computime Radio Clock" 1>&5 +echo "configure:9563: checking Diem Computime Radio Clock" 1>&5 # Check whether --enable-COMPUTIME or --disable-COMPUTIME was given. if test "${enable_COMPUTIME+set}" = set; then enableval="$enable_COMPUTIME" @@ -9576,7 +9584,7 @@ case "$ntp_ok$ntp_canparse" in esac echo $ac_n "checking ELV/DCF7000 clock... $ac_c" 1>&6 -echo "configure:9580: checking ELV/DCF7000 clock" 1>&5 +echo "configure:9588: checking ELV/DCF7000 clock" 1>&5 # Check whether --enable-DCF7000 or --disable-DCF7000 was given. if test "${enable_DCF7000+set}" = set; then enableval="$enable_DCF7000" @@ -9601,7 +9609,7 @@ case "$ntp_ok$ntp_canparse" in esac echo $ac_n "checking HOPF 6021 clock... $ac_c" 1>&6 -echo "configure:9605: checking HOPF 6021 clock" 1>&5 +echo "configure:9613: checking HOPF 6021 clock" 1>&5 # Check whether --enable-HOPF6021 or --disable-HOPF6021 was given. if test "${enable_HOPF6021+set}" = set; then enableval="$enable_HOPF6021" @@ -9626,7 +9634,7 @@ case "$ntp_ok$ntp_canparse" in esac echo $ac_n "checking Meinberg clocks... $ac_c" 1>&6 -echo "configure:9630: checking Meinberg clocks" 1>&5 +echo "configure:9638: checking Meinberg clocks" 1>&5 # Check whether --enable-MEINBERG or --disable-MEINBERG was given. if test "${enable_MEINBERG+set}" = set; then enableval="$enable_MEINBERG" @@ -9651,7 +9659,7 @@ case "$ntp_ok$ntp_canparse" in esac echo $ac_n "checking DCF77 raw time code... $ac_c" 1>&6 -echo "configure:9655: checking DCF77 raw time code" 1>&5 +echo "configure:9663: checking DCF77 raw time code" 1>&5 # Check whether --enable-RAWDCF or --disable-RAWDCF was given. if test "${enable_RAWDCF+set}" = set; then enableval="$enable_RAWDCF" @@ -9680,7 +9688,7 @@ esac case "$ntp_rawdcf" in yes) echo $ac_n "checking if we must enable parity for RAWDCF... $ac_c" 1>&6 -echo "configure:9684: checking if we must enable parity for RAWDCF" 1>&5 +echo "configure:9692: checking if we must enable parity for RAWDCF" 1>&5 if test "${ac_cv_var_rawdcf_parity+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9707,7 +9715,7 @@ EOF esac echo $ac_n "checking RCC 8000 clock... $ac_c" 1>&6 -echo "configure:9711: checking RCC 8000 clock" 1>&5 +echo "configure:9719: checking RCC 8000 clock" 1>&5 # Check whether --enable-RCC8000 or --disable-RCC8000 was given. if test "${enable_RCC8000+set}" = set; then enableval="$enable_RCC8000" @@ -9732,7 +9740,7 @@ case "$ntp_ok$ntp_canparse" in esac echo $ac_n "checking Schmid DCF77 clock... $ac_c" 1>&6 -echo "configure:9736: checking Schmid DCF77 clock" 1>&5 +echo "configure:9744: checking Schmid DCF77 clock" 1>&5 # Check whether --enable-SCHMID or --disable-SCHMID was given. if test "${enable_SCHMID+set}" = set; then enableval="$enable_SCHMID" @@ -9757,7 +9765,7 @@ case "$ntp_ok$ntp_canparse" in esac echo $ac_n "checking Trimble GPS receiver/TAIP protocol... $ac_c" 1>&6 -echo "configure:9761: checking Trimble GPS receiver/TAIP protocol" 1>&5 +echo "configure:9769: checking Trimble GPS receiver/TAIP protocol" 1>&5 # Check whether --enable-TRIMTAIP or --disable-TRIMTAIP was given. if test "${enable_TRIMTAIP+set}" = set; then enableval="$enable_TRIMTAIP" @@ -9782,7 +9790,7 @@ case "$ntp_ok$ntp_canparse" in esac echo $ac_n "checking Trimble GPS receiver/TSIP protocol... $ac_c" 1>&6 -echo "configure:9786: checking Trimble GPS receiver/TSIP protocol" 1>&5 +echo "configure:9794: checking Trimble GPS receiver/TSIP protocol" 1>&5 # Check whether --enable-TRIMTSIP or --disable-TRIMTSIP was given. if test "${enable_TRIMTSIP+set}" = set; then enableval="$enable_TRIMTSIP" @@ -9807,7 +9815,7 @@ case "$ntp_ok$ntp_canparse" in esac echo $ac_n "checking WHARTON 400A Series clock... $ac_c" 1>&6 -echo "configure:9811: checking WHARTON 400A Series clock" 1>&5 +echo "configure:9819: checking WHARTON 400A Series clock" 1>&5 # Check whether --enable-WHARTON or --disable-WHARTON was given. if test "${enable_WHARTON+set}" = set; then enableval="$enable_WHARTON" @@ -9832,7 +9840,7 @@ case "$ntp_ok$ntp_canparse" in esac echo $ac_n "checking VARITEXT clock... $ac_c" 1>&6 -echo "configure:9836: checking VARITEXT clock" 1>&5 +echo "configure:9844: checking VARITEXT clock" 1>&5 # Check whether --enable-VARITEXT or --disable-VARITEXT was given. if test "${enable_VARITEXT+set}" = set; then enableval="$enable_VARITEXT" @@ -9857,7 +9865,7 @@ case "$ntp_ok$ntp_canparse" in esac echo $ac_n "checking if we need to make and use the parse libraries... $ac_c" 1>&6 -echo "configure:9861: checking if we need to make and use the parse libraries" 1>&5 +echo "configure:9869: checking if we need to make and use the parse libraries" 1>&5 ans=no case "$ntp_libparse" in yes) @@ -9882,22 +9890,42 @@ esac echo "$ac_t""$ans" 1>&6 echo $ac_n "checking if we need to make and use the RSAREF library... $ac_c" 1>&6 -echo "configure:9886: checking if we need to make and use the RSAREF library" 1>&5 -ans=no -if test -f $srcdir/rsaref2/source/rsa.c -then - ans=yes - LIBRSAREF=../librsaref/librsaref.a - MAKE_LIBRSAREF=librsaref.a - cat >>confdefs.h <<\EOF +echo "configure:9894: checking if we need to make and use the RSAREF library" 1>&5 +# Check whether --with-rsaref or --without-rsaref was given. +if test "${with_rsaref+set}" = set; then + withval="$with_rsaref" + ans=yes +case "$withval" in + no) ans=no ;; +esac +else + ans=yes +fi + +case "$ans" in + yes) + ans=no + if test -f $srcdir/rsaref2/source/rsa.c + then + ans=yes + LIBRSAREF=../librsaref/librsaref.a + MAKE_LIBRSAREF=librsaref.a + MAKE_NTP_GENKEYS=ntp_genkeys + cat >>confdefs.h <<\EOF #define DES 1 EOF -fi + cat >>confdefs.h <<\EOF +#define PUBKEY +EOF + + fi + ;; +esac echo "$ac_t""$ans" 1>&6 echo $ac_n "checking if we can make dcf parse utilities... $ac_c" 1>&6 -echo "configure:9901: checking if we can make dcf parse utilities" 1>&5 +echo "configure:9929: checking if we can make dcf parse utilities" 1>&5 ans=no if test "$ntp_parseutil" = "yes"; then case "$target" in @@ -9911,7 +9939,7 @@ fi echo "$ac_t""$ans" 1>&6 echo $ac_n "checking if we can build kernel streams modules for parse... $ac_c" 1>&6 -echo "configure:9915: checking if we can build kernel streams modules for parse" 1>&5 +echo "configure:9943: checking if we can build kernel streams modules for parse" 1>&5 ans=no case "$ntp_parseutil$ac_cv_header_sys_stropts_h" in yesyes) @@ -9938,7 +9966,7 @@ esac echo "$ac_t""$ans" 1>&6 echo $ac_n "checking if we need basic refclock support... $ac_c" 1>&6 -echo "configure:9942: checking if we need basic refclock support" 1>&5 +echo "configure:9970: checking if we need basic refclock support" 1>&5 if test "$ntp_refclock" = "yes"; then cat >>confdefs.h <<\EOF #define REFCLOCK 1 @@ -9950,7 +9978,7 @@ echo "$ac_t""$ntp_refclock" 1>&6 echo $ac_n "checking if we want HP-UX adjtimed support... $ac_c" 1>&6 -echo "configure:9954: checking if we want HP-UX adjtimed support" 1>&5 +echo "configure:9982: checking if we want HP-UX adjtimed support" 1>&5 case "$target" in *-*-hpux[56789]*) ans=yes @@ -9968,7 +9996,7 @@ fi echo "$ac_t""$ans" 1>&6 echo $ac_n "checking if we can read kmem... $ac_c" 1>&6 -echo "configure:9972: checking if we can read kmem" 1>&5 +echo "configure:10000: checking if we can read kmem" 1>&5 if test "${ac_cv_var_can_kmem+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10020,7 +10048,7 @@ EOF esac echo $ac_n "checking if adjtime is accurate... $ac_c" 1>&6 -echo "configure:10024: checking if adjtime is accurate" 1>&5 +echo "configure:10052: checking if adjtime is accurate" 1>&5 if test "${ac_cv_var_adjtime_is_accurate+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10071,7 +10099,7 @@ EOF esac echo $ac_n "checking the name of 'tick' in the kernel... $ac_c" 1>&6 -echo "configure:10075: checking the name of 'tick' in the kernel" 1>&5 +echo "configure:10103: checking the name of 'tick' in the kernel" 1>&5 if test "${ac_cv_var_nlist_tick+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10114,7 +10142,7 @@ EOF esac # echo $ac_n "checking for the units of 'tick'... $ac_c" 1>&6 -echo "configure:10118: checking for the units of 'tick'" 1>&5 +echo "configure:10146: checking for the units of 'tick'" 1>&5 if test "${ac_cv_var_tick_nano+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10137,7 +10165,7 @@ EOF esac # echo $ac_n "checking the name of 'tickadj' in the kernel... $ac_c" 1>&6 -echo "configure:10141: checking the name of 'tickadj' in the kernel" 1>&5 +echo "configure:10169: checking the name of 'tickadj' in the kernel" 1>&5 if test "${ac_cv_var_nlist_tickadj+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10189,7 +10217,7 @@ EOF esac # echo $ac_n "checking for the units of 'tickadj'... $ac_c" 1>&6 -echo "configure:10193: checking for the units of 'tickadj'" 1>&5 +echo "configure:10221: checking for the units of 'tickadj'" 1>&5 if test "${ac_cv_var_tickadj_nano+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10212,7 +10240,7 @@ EOF esac # echo $ac_n "checking half-heartedly for 'dosynctodr' in the kernel... $ac_c" 1>&6 -echo "configure:10216: checking half-heartedly for 'dosynctodr' in the kernel" 1>&5 +echo "configure:10244: checking half-heartedly for 'dosynctodr' in the kernel" 1>&5 if test "${ac_cv_var_nlist_dosynctodr+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10264,7 +10292,7 @@ EOF esac # echo $ac_n "checking half-heartedly for 'noprintf' in the kernel... $ac_c" 1>&6 -echo "configure:10268: checking half-heartedly for 'noprintf' in the kernel" 1>&5 +echo "configure:10296: checking half-heartedly for 'noprintf' in the kernel" 1>&5 if test "${ac_cv_var_nlist_noprintf+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10310,7 +10338,7 @@ EOF esac echo $ac_n "checking for a default value for 'tick'... $ac_c" 1>&6 -echo "configure:10314: checking for a default value for 'tick'" 1>&5 +echo "configure:10342: checking for a default value for 'tick'" 1>&5 if test "${ac_cv_var_tick+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10353,7 +10381,7 @@ EOF esac echo $ac_n "checking for a default value for 'tickadj'... $ac_c" 1>&6 -echo "configure:10357: checking for a default value for 'tickadj'" 1>&5 +echo "configure:10385: checking for a default value for 'tickadj'" 1>&5 if test "${ac_cv_var_tickadj+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10484,7 +10512,7 @@ case "$target" in esac echo $ac_n "checking if we want and can make the tickadj utility... $ac_c" 1>&6 -echo "configure:10488: checking if we want and can make the tickadj utility" 1>&5 +echo "configure:10516: checking if we want and can make the tickadj utility" 1>&5 if test "${ac_cv_make_tickadj+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10498,7 +10526,7 @@ case "$ac_cv_make_tickadj" in esac echo $ac_n "checking if we want and can make the ntptime utility... $ac_c" 1>&6 -echo "configure:10502: checking if we want and can make the ntptime utility" 1>&5 +echo "configure:10530: checking if we want and can make the ntptime utility" 1>&5 if test "${ac_cv_make_ntptime+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10523,7 +10551,7 @@ case "$ac_cv_make_ntptime" in esac echo $ac_n "checking if we want UDP wildcard delivery... $ac_c" 1>&6 -echo "configure:10527: checking if we want UDP wildcard delivery" 1>&5 +echo "configure:10555: checking if we want UDP wildcard delivery" 1>&5 if test "${ac_cv_var_udp_wildcard_delivery+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10601,7 +10629,7 @@ case "$host" in esac echo $ac_n "checking if we should always slew the time... $ac_c" 1>&6 -echo "configure:10605: checking if we should always slew the time" 1>&5 +echo "configure:10633: checking if we should always slew the time" 1>&5 if test "${ac_cv_var_slew_always+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10640,7 +10668,7 @@ EOF esac echo $ac_n "checking if we should step and slew the time... $ac_c" 1>&6 -echo "configure:10644: checking if we should step and slew the time" 1>&5 +echo "configure:10672: checking if we should step and slew the time" 1>&5 if test "${ac_cv_var_step_slew+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10682,7 +10710,7 @@ EOF esac echo $ac_n "checking if ntpdate should step the time... $ac_c" 1>&6 -echo "configure:10686: checking if ntpdate should step the time" 1>&5 +echo "configure:10714: checking if ntpdate should step the time" 1>&5 if test "${ac_cv_var_ntpdate_step+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10712,7 +10740,7 @@ EOF esac echo $ac_n "checking if we should sync TODR clock every hour... $ac_c" 1>&6 -echo "configure:10716: checking if we should sync TODR clock every hour" 1>&5 +echo "configure:10744: checking if we should sync TODR clock every hour" 1>&5 if test "${ac_cv_var_sync_todr+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10744,7 +10772,7 @@ EOF esac echo $ac_n "checking if we should avoid kernel FLL bug... $ac_c" 1>&6 -echo "configure:10748: checking if we should avoid kernel FLL bug" 1>&5 +echo "configure:10776: checking if we should avoid kernel FLL bug" 1>&5 if test "${ac_cv_var_kernel_fll_bug+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11121,6 +11149,7 @@ s%@MAKE_CHECK_Y2K@%$MAKE_CHECK_Y2K%;t t s%@RSAREF@%$RSAREF%;t t s%@LIBRSAREF@%$LIBRSAREF%;t t s%@MAKE_LIBRSAREF@%$MAKE_LIBRSAREF%;t t +s%@MAKE_NTP_GENKEYS@%$MAKE_NTP_GENKEYS%;t t s%@TESTDCF@%$TESTDCF%;t t s%@DCFD@%$DCFD%;t t s%@MAKE_PARSEKMODULE@%$MAKE_PARSEKMODULE%;t t diff --git a/configure.in b/configure.in index 0965305336..e9aa84bd98 100644 --- a/configure.in +++ b/configure.in @@ -187,8 +187,8 @@ AC_CHECK_LIB(rt, sched_setscheduler, , AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt)) AC_HEADER_STDC -AC_CHECK_HEADERS(bstring.h errno.h fcntl.h memory.h netdb.h poll.h resolv.h) -AC_CHECK_HEADERS(sched.h sgtty.h stdlib.h string.h termio.h termios.h) +AC_CHECK_HEADERS(bstring.h errno.h fcntl.h ieeefp.h memory.h netdb.h poll.h) +AC_CHECK_HEADERS(resolv.h sched.h sgtty.h stdlib.h string.h termio.h termios.h) AC_CHECK_HEADERS(timepps.h timex.h unistd.h utmp.h utmpx.h) AC_CHECK_HEADERS(arpa/nameser.h net/if.h netinet/in_systm.h netinet/in.h) AC_CHECK_HEADERS(netinfo/ni.h, [AC_DEFINE(HAVE_NETINFO)]) @@ -1352,7 +1352,10 @@ AC_CACHE_CHECK(if we want to use MD5 authentication, ac_cv_var_use_md5, [ans=$enableval], [ans=yes]) ac_cv_var_use_md5=$ans]) case "$ac_cv_var_use_md5" in - yes) AC_DEFINE(MD5) ;; + yes) + AC_DEFINE(AUTOKEY, , [Autokey?]) + AC_DEFINE(MD5) + ;; esac # Check for ioctls TIOCGPPSEV @@ -2229,15 +2232,27 @@ AC_MSG_RESULT($ans) AC_SUBST(RSAREF) AC_SUBST(LIBRSAREF) AC_SUBST(MAKE_LIBRSAREF) +AC_SUBST(MAKE_NTP_GENKEYS) AC_MSG_CHECKING(if we need to make and use the RSAREF library) -ans=no -if test -f $srcdir/rsaref2/source/rsa.c -then - ans=yes - LIBRSAREF=../librsaref/librsaref.a - MAKE_LIBRSAREF=librsaref.a - AC_DEFINE(DES) -fi +AC_ARG_WITH(rsaref, [ --with-rsaref + Use rsaref if possible], +[ans=yes +case "$withval" in + no) ans=no ;; +esac], [ans=yes]) +case "$ans" in + yes) + ans=no + if test -f $srcdir/rsaref2/source/rsa.c + then + ans=yes + LIBRSAREF=../librsaref/librsaref.a + MAKE_LIBRSAREF=librsaref.a + MAKE_NTP_GENKEYS=ntp_genkeys + AC_DEFINE(DES) + AC_DEFINE(PUBKEY, , [Public key?]) + fi + ;; +esac AC_MSG_RESULT($ans) AC_SUBST(TESTDCF) diff --git a/include/Makefile.am b/include/Makefile.am index d7f28f6155..46c22d34bf 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -5,6 +5,7 @@ ETAGS_ARGS = $(srcdir)/Makefile.am noinst_HEADERS = \ adjtime.h \ + audio.h \ ascii.h \ audio.h \ binio.h \ @@ -21,6 +22,7 @@ noinst_HEADERS = \ ntp.h \ ntp_calendar.h \ ntp_control.h \ + ntp_crypto.h \ ntp_datum.h \ ntp_filegen.h \ ntp_fp.h \ diff --git a/include/Makefile.in b/include/Makefile.in index b48a2b714d..96ac009e8b 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ @@ -108,6 +109,7 @@ ETAGS_ARGS = $(srcdir)/Makefile.am noinst_HEADERS = \ adjtime.h \ + audio.h \ ascii.h \ audio.h \ binio.h \ @@ -124,6 +126,7 @@ noinst_HEADERS = \ ntp.h \ ntp_calendar.h \ ntp_control.h \ + ntp_crypto.h \ ntp_datum.h \ ntp_filegen.h \ ntp_fp.h \ diff --git a/include/ntp.h b/include/ntp.h index e07870cf8f..81d73f98ea 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -8,58 +8,64 @@ #include "ntp_types.h" #include - /* common definitions for Y2K repairs [ Y2KFixes */ - - /* (this might better be put in ntp_calendar.h) */ -#define YEAR_BREAK 500 /* assume years < this are tm_year values: */ - /* Break < AnyFourDigitYear - && Break > Anytm_yearYear */ -#define YEAR_PIVOT 98 /* 97/98: assume years < this are year 2000+ */ - /* FYI: official UNIX pivot year is 68/69 */ - - /* Number of Days since (mythical) 1.BC Gregorian to 1 January of given year*/ -#define julian0(year) \ - ( \ - ( (year) * 365 ) + ( (year) > 0 \ - ? ( ((year)+3) / 4 - ((year-1) / 100) + ((year-1) / 400) ) \ - : 0 ) \ - ) - - /* Number of days since start of NTP time to 1 January of given year */ -#define ntp0(year) ( julian0(year) - julian0(1900) ) - - /* Number of days since start of UNIX time to 1 January of given year */ -#define unix0(year) ( julian0(year) - julian0(1970) ) - - /* LEAP YEAR test for full 4-digit years (e.g, 1999, 2010) */ -#define isleap_4(y) /* a TRUE and PROPER leap year test */ \ - ((y)%4 == 0 && !((y)%100 == 0 && !(y%400 == 0))) - /* NOTE: year 2000 TRULY IS A LEAP YEAR!!! */ - - /* LEAP YEAR test for tm_year (struct tm) years (e.g, 99, 110) */ -#define isleap_tm(y) /* a TRUE and PROPER leap year test */ \ - ((y)%4 == 0 && !((y)%100 == 0 && !(((y)+1900)%400 == 0))) - - /* to convert simple two-digit years to tm_year style years: - if ( year < YEAR_PIVOT ) year += 100; - - * to convert either two-digit OR tm_year years to four-digit years: - if ( year < YEAR_PIVOT ) year += 100; - if ( year < YEAR_BREAK ) year += 1900; - - CALL TO STANDARD: - * As the Internet is an INTERNATIONAL network, it makes SENSE to use - the international standard ISO 8601 to format dates and times. - Basically this is yyyy-mm-dd for years and hh:mm:ss for times - (joining the two togeather in computer readable media calls for - yyyy-mm-ddThh:mm:ss, though yyyy-mm-dd hh:mm:ss is often used - for human readable forms even though it is not not strictly - valid ISO 8601). Standard time-zone offsets ([+-]hh:mm) are allowed. - ghealton ] Y2KFixes */ +/* + * Calendar arithmetic - contributed by G. Healton + */ +#define YEAR_BREAK 500 /* years < this are tm_year values: + * Break < AnyFourDigitYear && Break > + * Anytm_yearYear */ + +#define YEAR_PIVOT 98 /* 97/98: years < this are year 2000+ + * FYI: official UNIX pivot year is + * 68/69 */ + +/* + * Number of Days since 1 BC Gregorian to 1 January of given year + */ +#define julian0(year) (((year) * 365 ) + ((year) > 0 ? (((year) + 3) \ + / 4 - ((year - 1) / 100) + ((year - 1) / \ + 400)) : 0)) + +/* + * Number of days since start of NTP time to 1 January of given year + */ +#define ntp0(year) (julian0(year) - julian0(1900)) + +/* + * Number of days since start of UNIX time to 1 January of given year + */ +#define unix0(year) (julian0(year) - julian0(1970)) + +/* + * LEAP YEAR test for full 4-digit years (e.g, 1999, 2010) + */ +#define isleap_4(y) ((y) % 4 == 0 && !((y) % 100 == 0 && !(y % \ + 400 == 0))) + +/* + * LEAP YEAR test for tm_year (struct tm) years (e.g, 99, 110) + */ +#define isleap_tm(y) ((y) % 4 == 0 && !((y) % 100 == 0 && !(((y) \ + + 1900) % 400 == 0))) + +/* + * to convert simple two-digit years to tm_year style years: + * + * if (year < YEAR_PIVOT) + * year += 100; + * + * to convert either two-digit OR tm_year years to four-digit years: + * + * if (year < YEAR_PIVOT) + * year += 100; + * + * if (year < YEAR_BREAK) + * year += 1900; + */ /* * How to get signed characters. On machines where signed char works, - * use it. On machines where signed char doesn't work, char had better + * use it. On machines where signed char doesn't work, char had better * be signed. */ #ifdef NEED_S_CHAR_TYPEDEF @@ -90,6 +96,7 @@ typedef char s_char; #define NTP_MAXSTRATUM ((u_char)15) /* max stratum, infinity a la Bellman-Ford */ #define NTP_MAXAGE 86400 /* one day in seconds */ #define NTP_UNREACH 16 /* poll interval backoff count */ +#define NTP_TAILMAX 4 /* tailgate poll counter max */ #define NTP_MINDPOLL 6 /* log2 default min poll interval (64 s) */ #define NTP_MAXDPOLL 10 /* log2 default max poll interval (~17 m) */ #define NTP_MINPOLL 4 /* log2 min poll interval (16 s) */ @@ -100,7 +107,8 @@ typedef char s_char; #define NTP_WINDOW 8 /* reachability register size */ #define NTP_SHIFT 8 /* 8 suitable for crystal time base */ #define NTP_MAXKEY 65535 /* maximum authentication key number */ -#define NTP_MAXSESSION 100 /* maximum entries on session key list */ +#define NTP_MINSESSION 10 /* minimum session key list entries */ +#define NTP_MAXSESSION 100 /* maximum session key list entries */ #define NTP_AUTOMAX 12 /* log2 default max session key lifetime */ #define KEY_REVOKE 16 /* log2 default key revoke timeout */ #define NTP_FWEIGHT .5 /* clock filter weight */ @@ -111,13 +119,14 @@ typedef char s_char; /* * Operations for jitter (variance) calculations (these use doubles). - * Note that we carefully separate the jitter component from the dispersion - * component (frequency error plus precision). The frequency error - * component is computed as CLOCK_PHI times the difference between the epoch - * of the time measurement and the reference time. The precision componen - * is computed as the square root of the mean of the squares of a zero- - * mean, uniform distribution of unit maximum amplitude. Whether this - * makes statistical sense may be arguable. + * + * Note that we carefully separate the jitter component from the + * dispersion component (frequency error plus precision). The frequency + * error component is computed as CLOCK_PHI times the difference between + * the epoch of the time measurement and the reference time. The + * precision componen is computed as the square root of the mean of the + * squares of a zero-mean, uniform distribution of unit maximum + * amplitude. Whether this makes statistical sense may be arguable. */ #define SQUARE(x) ((x) * (x)) #define SQRT(x) (sqrt(x)) @@ -139,7 +148,7 @@ typedef char s_char; */ #define CLOCK_PHI 15e-6 /* max frequency wander */ -#define EVENT_TIMEOUT 0 /* one second, that is */ +#define EVENT_TIMEOUT 0 /* one second, that is */ /* * The interface structure is used to hold the addresses and socket @@ -149,8 +158,8 @@ struct interface { int fd; /* socket this is opened on */ int bfd; /* socket for receiving broadcasts */ struct sockaddr_in sin; /* interface address */ - struct sockaddr_in bcast; /* broadcast address */ - struct sockaddr_in mask; /* interface mask */ + struct sockaddr_in bcast; /* broadcast address */ + struct sockaddr_in mask; /* interface mask */ char name[8]; /* name of interface */ int flags; /* interface flags */ int last_ttl; /* last TTL specified */ @@ -168,7 +177,7 @@ struct interface { #define INT_MULTICAST 8 /* multicasting enabled */ /* - * Define flasher bits (tests 1 through 8 in packet procedure) + * Define flasher bits (tests 1 through 11 in packet procedure) * These reveal the state at the last grumble from the peer and are * most handy for diagnosing problems, even if not strictly a state * variable in the spec. These are recorded in the peer structure. @@ -181,97 +190,145 @@ struct interface { #define TEST6 0x0020 /* peer clock unsynchronized */ #define TEST7 0x0040 /* peer stratum out of bounds */ #define TEST8 0x0080 /* root delay/dispersion bounds check */ -#define TEST9 0x0100 /* peer not authenticated */ -#define TEST10 0x0200 /* access denied */ +#define TEST9 0x0100 /* access denied */ +#define TEST10 0x0200 /* autokey not authentic */ +#define TEST11 0x0400 /* autokey not confirmed */ /* - * The peer structure. Holds state information relating to the guys - * we are peering with. Most of this stuff is from section 3.2 of the + * The peer structure. Holds state information relating to the guys + * we are peering with. Most of this stuff is from section 3.2 of the * spec. */ struct peer { - struct peer *next; - struct peer *ass_next; /* link pointer in associd hash */ - struct sockaddr_in srcadr; /* address of remote host */ - struct interface *dstadr; /* pointer to address on local host */ - struct refclockproc *procptr; /* pointer to reference clock stuff */ - u_char leap; /* leap indicator */ - u_char hmode; /* association mode with this peer */ - u_char pmode; /* peer's association mode */ - u_char stratum; /* stratum of remote peer */ - s_char precision; /* peer's clock precision */ - u_char ppoll; /* peer poll interval */ - u_char hpoll; /* local host poll interval */ - u_char minpoll; /* min local host poll interval */ - u_char maxpoll; /* max local host poll interval */ - u_char burst; /* packets remaining in burst */ - u_char version; /* version number */ - u_int flags; /* peer flags */ - u_char cast_flags; /* flags MDF_?CAST */ - u_int flash; /* protocol error tally bits */ - u_char refclktype; /* reference clock type */ - u_char refclkunit; /* reference clock unit number */ - u_char sstclktype; /* clock type for system status word */ - u_int32 refid; /* peer reference ID */ - l_fp reftime; /* update epoch */ - u_long keyid; /* current key ID */ - u_long pkeyid; /* previous key ID (autokey) */ - u_long *keylist; /* session key identifier list */ - int keynumber; /* session key identifier number */ - u_short associd; /* association ID, a unique integer */ - u_char ttl; /* time to live (multicast) */ - -/* **Start of clear-to-zero area.*** */ -/* Everything that is cleared to zero goes below here */ - u_char valid; /* valid counter */ -#define clear_to_zero valid - double estbdelay; /* broadcast offset */ - u_char status; /* peer status */ - u_char pollsw; /* what it says */ - u_char reach; /* reachability, NTP_WINDOW bits */ - u_char unreach; /* unreachable count */ - u_short filter_nextpt; /* index into filter shift register */ - double filter_delay[NTP_SHIFT]; /* delay part of shift register */ - double filter_offset[NTP_SHIFT]; /* offset part of shift register */ - double filter_disp[NTP_SHIFT]; /* dispersion part of shift register */ - u_long filter_epoch[NTP_SHIFT]; /* epoch part of shift register */ - u_char filter_order[NTP_SHIFT]; /* we keep the filter sorted here */ - l_fp org; /* originate time stamp */ - l_fp rec; /* receive time stamp */ - l_fp xmt; /* transmit time stamp */ - double offset; /* peer clock offset */ - double delay; /* peer roundtrip delay */ - double variance; /* peer variance (jitter) */ - double disp; /* peer dispersion */ - double rootdelay; /* roundtrip delay to primary clock */ - double rootdispersion; /* dispersion to primary clock */ - u_long epoch; /* reference epoch */ - -/* ***End of clear-to-zero area.*** */ -/* Everything that is cleared to zero goes above here */ - u_long update; /* receive epoch */ + struct peer *next; /* pointer to next association */ + struct peer *ass_next; /* link pointer in associd hash */ + struct sockaddr_in srcadr; /* address of remote host */ + struct interface *dstadr; /* pointer to address on local host */ + u_short associd; /* association ID, a unique integer */ + u_char version; /* version number */ + u_char hmode; /* local association mode */ + u_char hpoll; /* local poll interval */ + u_char minpoll; /* min poll interval */ + u_char maxpoll; /* max poll interval */ + u_char burst; /* packets remaining in burst */ + u_int flags; /* peer association flags */ + u_char cast_flags; /* additional flags */ + u_int flash; /* protocol error test tally bits */ + u_char last_event; /* last peer error code */ + u_char num_events; /* number of error events */ + u_char ttl; /* m'cast time to live/refclock mode */ + + /* + * Variables used by reference clock support + */ + struct refclockproc *procptr; /* refclock structure pointer */ + u_char refclktype; /* reference clock type */ + u_char refclkunit; /* reference clock unit number */ + u_char sstclktype; /* clock type for system status word */ + + /* + * Variables set by received packet + */ + u_char leap; /* local leap indicator */ + u_char pmode; /* remote association mode */ + u_char stratum; /* remote stratum */ + s_char precision; /* remote clock precision */ + u_char ppoll; /* remote poll interval */ + u_int32 refid; /* remote reference ID */ + l_fp reftime; /* update epoch */ + + /* + * Variables used by authenticated client + */ + keyid_t keyid; /* current key ID */ + u_char *keystr; /* public key file name */ +#ifdef PUBKEY + u_char *pubkey; /* public key */ +#endif /* PUBKEY */ +#ifdef AUTOKEY + keyid_t pkeyid; /* previous key ID */ +#define clear_to_zero pkeyid + keyid_t hcookie; /* host cookie */ + keyid_t pcookie; /* peer cookie */ + int recseq; /* session key number */ + keyid_t finlkey; /* initial key ID */ + int finlseq; /* initial key number */ + u_int32 cmmd; /* peer command */ + u_short assoc; /* association ID of peer */ + u_char *dh_public; /* Diffie-Hellman public value */ + u_char *dh_key; /* Diffie-Hellman agreed key */ + + /* + * Variables used by authenticated server + */ + keyid_t *keylist; /* session key ID list */ + int keynumber; /* current key number */ + keyid_t lastkey; /* initial key ID */ + int lastseq; /* initial key number */ +#ifdef PUBKEY + u_char *sign; /* signature of keylist values */ + u_int signlen; /* length of signature */ +#endif /* PUBKEY */ +#endif /* AUTOKEY */ + + /* + * Ephemeral state variables + */ + u_int valid; /* valid update counter */ + u_int tailcnt; /* tailgate poll counter */ +#ifndef AUTOKEY +#define clear_to_zero valid +#endif /* AUTOKEY */ + u_char status; /* peer status */ + u_char pollsw; /* what it says */ + u_char reach; /* reachability register */ + u_char unreach; /* unreachable count */ + u_long epoch; /* reference epoch */ + u_short filter_nextpt; /* index into filter shift register */ + double filter_delay[NTP_SHIFT]; /* delay shift register */ + double filter_offset[NTP_SHIFT]; /* offset shift register */ + double filter_disp[NTP_SHIFT]; /* dispersion shift register */ + u_long filter_epoch[NTP_SHIFT]; /* epoch shift register */ + u_char filter_order[NTP_SHIFT]; /* filter sort index */ + l_fp org; /* originate time stamp */ + l_fp rec; /* receive time stamp */ + l_fp xmt; /* transmit time stamp */ + double offset; /* peer clock offset */ + double delay; /* peer roundtrip delay */ + double variance; /* peer variance (jitter) */ + double disp; /* peer dispersion */ + double estbdelay; /* clock offset to broadcast server */ + + /* + * Variables set by received packet + */ + double rootdelay; /* roundtrip delay to primary clock */ + double rootdispersion; /* dispersion to primary clock */ + + /* + * End of clear-to-zero area + */ + u_long update; /* receive epoch */ #define end_clear_to_zero update - u_long outdate; /* send time last packet */ - u_long nextdate; /* send time next packet */ - u_long nextaction; /* peer local activity timeout (refclocks mainly) */ - void (*action) P((struct peer *));/* action timeout function */ + u_long outdate; /* send time last packet */ + u_long nextdate; /* send time next packet */ + u_long nextaction; /* peer local activity timeout (refclocks mainly) */ + void (*action) P((struct peer *)); /* action timeout function */ /* - * statistic counters + * Statistic counters */ - u_long timereset; /* time stat counters were reset */ - u_long sent; /* number of updates sent */ - u_long received; /* number of frames received */ - u_long timereceived; /* last time a frame received */ - u_long timereachable; /* last reachable/unreachable event */ - u_long processed; /* processed by the protocol */ - u_long badauth; /* bad credentials detected */ - u_long bogusorg; /* rejected due to bogus origin */ - u_long oldpkt; /* rejected as duplicate packet */ - u_long seldisptoolarge; /* too much dispersion for selection */ - u_long selbroken; /* broken NTP detected in selection */ - u_long seltooold; /* too long since sync in selection */ - u_char last_event; /* set to code for last peer error */ - u_char num_events; /* num. of events which have occurred */ + u_long timereset; /* time stat counters were reset */ + u_long timereceived; /* last packet received time */ + u_long timereachable; /* last reachable/unreachable time */ + + u_long sent; /* packets sent */ + u_long received; /* packets received */ + u_long processed; /* packets processed by the protocol */ + u_long badauth; /* packets cryptosum failed */ + u_long bogusorg; /* packets bogus origin */ + u_long oldpkt; /* packets duplicate packet */ + u_long seldisptoolarge; /* packets dispersion to large*/ + u_long selbroken; /* not used */ }; /* @@ -310,17 +367,18 @@ struct peer { /* * Values for peer.flags */ -#define FLAG_CONFIG 0x1 /* association was configured */ -#define FLAG_AUTHENABLE 0x2 /* this guy needs authentication */ -#define FLAG_MCAST1 0x4 /* multicast client/server mode */ -#define FLAG_MCAST2 0x8 /* multicast client mode */ -#define FLAG_AUTHENTIC 0x10 /* last message was authentic */ -#define FLAG_REFCLOCK 0x20 /* this is actually a reference clock */ -#define FLAG_SYSPEER 0x40 /* this is one of the selected peers */ -#define FLAG_PREFER 0x80 /* this is the preferred peer */ -#define FLAG_BURST 0x100 /* burst mode */ -#define FLAG_SKEY 0x200 /* autokey authentication */ -#define FLAG_NOSELECT 0x400 /* this is a "noselect" peer */ +#define FLAG_CONFIG 0x0001 /* association was configured */ +#define FLAG_AUTHENABLE 0x0002 /* authentication required */ +#define FLAG_MCAST1 0x0004 /* multicast client/server mode */ +#define FLAG_MCAST2 0x0008 /* multicast client mode */ +#define FLAG_AUTHENTIC 0x0010 /* last message was authentic */ +#define FLAG_REFCLOCK 0x0020 /* this is actually a reference clock */ +#define FLAG_SYSPEER 0x0040 /* this is one of the selected peers */ +#define FLAG_PREFER 0x0080 /* this is the preferred peer */ +#define FLAG_BURST 0x0100 /* burst mode */ +#define FLAG_SKEY 0x0200 /* autokey authentication */ +#define FLAG_NOSELECT 0x0400 /* this is a "noselect" peer */ +#define FLAG_AUTOKEY 0x0800 /* autokey confirmed */ /* * Definitions for the clear() routine. We use memset() to clear @@ -420,9 +478,9 @@ struct peer { * and must be converted (except the mac, which isn't, really). */ struct pkt { - u_char li_vn_mode; /* contains leap indicator, version and mode */ - u_char stratum; /* peer's stratum */ - u_char ppoll; /* the peer polling interval */ + u_char li_vn_mode; /* leap indicator, version and mode */ + u_char stratum; /* peer stratum */ + u_char ppoll; /* peer poll interval */ s_char precision; /* peer clock precision */ u_fp rootdelay; /* distance to primary clock */ u_fp rootdispersion; /* clock dispersion */ @@ -432,32 +490,27 @@ struct pkt { l_fp rec; /* receive time stamp */ l_fp xmt; /* transmit time stamp */ -#define MIN_MAC_LEN (sizeof(u_int32) + 8) /* DES */ -#define MAX_MAC_LEN (sizeof(u_int32) + 16) /* MD5 */ +#define LEN_PKT_NOMAC 12 * sizeof(u_int32) /* min header length */ +#define LEN_PKT_MAC LEN_PKT_NOMAC + sizeof(u_int32) +#define MIN_MAC_LEN 3 * sizeof(u_int32) /* DES */ +#define MAX_MAC_LEN 5 * sizeof(u_int32) /* MD5 */ +#define MAX_EXT_LEN 264 /* RSA public key */ /* * The length of the packet less MAC must be a multiple of 64 - * bits. For normal private-key cryptography, the cryptosum - * covers only the raw NTP header. For autokey cryptography, - * the heade is incresed by 64 bits to contain the field length - * and private value. + * bits. The maximum length of an extension data field is 272 + * octets. The next longest is 80 octets. There can only be + * two extension fields in a message, so the maximum lenth + * is 352 octets or 88 words, so we cheat and call it 100. */ - u_int32 keyid1; /* key identifier 1 */ - u_int32 keyid2; /* key identifier 2 */ - u_int32 keyid3; /* key identifier 3 */ +#ifdef AUTOKEY + u_int32 exten[100]; /* extension field */ +#else + u_int32 exten[1]; /* misused */ +#endif /* AUTOKEY */ u_char mac[MAX_MAC_LEN]; /* mac */ }; -/* - * Packets can come in two flavours, one with a mac and one without. - */ -#define LEN_PKT_NOMAC (sizeof(struct pkt) - MAX_MAC_LEN - 3 * sizeof(u_int32)) - -/* - * Minimum size of packet with a MAC: has to include at least a key number. - */ -#define LEN_PKT_MAC (LEN_PKT_NOMAC + sizeof(u_int32)) - /* * Stuff for extracting things from li_vn_mode */ @@ -482,37 +535,42 @@ struct pkt { #define STRATUM_TO_PKT(s) ((u_char)(((s) == (STRATUM_UNSPEC)) ?\ (STRATUM_PKT_UNSPEC) : (s))) - /* - * Event codes. Used for reporting errors/events to the control module + * Event codes. Used for reporting errors/events to the control module */ -#define PEER_EVENT 0x80 /* this is a peer event */ +#define PEER_EVENT 0x80 /* this is a peer event */ -#define EVNT_UNSPEC 0 -#define EVNT_SYSRESTART 1 -#define EVNT_SYSFAULT 2 -#define EVNT_SYNCCHG 3 -#define EVNT_PEERSTCHG 4 -#define EVNT_CLOCKRESET 5 -#define EVNT_BADDATETIM 6 -#define EVNT_CLOCKEXCPT 7 +/* + * System event codes + */ +#define EVNT_UNSPEC 0 /* unspecified */ +#define EVNT_SYSRESTART 1 /* system restart */ +#define EVNT_SYSFAULT 2 /* wsystem or hardware fault */ +#define EVNT_SYNCCHG 3 /* new leap or synch change */ +#define EVNT_PEERSTCHG 4 /* new source or stratum */ +#define EVNT_CLOCKRESET 5 /* clock reset */ +#define EVNT_BADDATETIM 6 /* invalid time or date */ +#define EVNT_CLOCKEXCPT 7 /* reference clock exception */ -#define EVNT_PEERIPERR (1|PEER_EVENT) -#define EVNT_PEERAUTH (2|PEER_EVENT) -#define EVNT_UNREACH (3|PEER_EVENT) -#define EVNT_REACH (4|PEER_EVENT) -#define EVNT_PEERCLOCK (5|PEER_EVENT) +/* + * Peer event codes + */ +#define EVNT_PEERIPERR (1 | PEER_EVENT) /* IP error */ +#define EVNT_PEERAUTH (2 | PEER_EVENT) /* authentication failure */ +#define EVNT_UNREACH (3 | PEER_EVENT) /* change to unreachable */ +#define EVNT_REACH (4 | PEER_EVENT) /* change to reachable */ +#define EVNT_PEERCLOCK (5 | PEER_EVENT) /* clock exception */ /* * Clock event codes */ -#define CEVNT_NOMINAL 0 -#define CEVNT_TIMEOUT 1 -#define CEVNT_BADREPLY 2 -#define CEVNT_FAULT 3 -#define CEVNT_PROP 4 -#define CEVNT_BADDATE 5 -#define CEVNT_BADTIME 6 +#define CEVNT_NOMINAL 0 /* unspecified */ +#define CEVNT_TIMEOUT 1 /* poll timeout */ +#define CEVNT_BADREPLY 2 /* bad reply format */ +#define CEVNT_FAULT 3 /* hardware or software fault */ +#define CEVNT_PROP 4 /* propagation failure */ +#define CEVNT_BADDATE 5 /* bad date format or value */ +#define CEVNT_BADTIME 6 /* bad time format or value */ #define CEVNT_MAX CEVNT_BADTIME /* @@ -522,8 +580,8 @@ struct pkt { /* - * To speed lookups, peers are hashed by the low order bits of the remote - * IP address. These definitions relate to that. + * To speed lookups, peers are hashed by the low order bits of the + * remote IP address. These definitions relate to that. */ #define HASH_SIZE 32 #define HASH_MASK (HASH_SIZE-1) diff --git a/include/ntp_control.h b/include/ntp_control.h index dbcc2c659f..7181d7a024 100644 --- a/include/ntp_control.h +++ b/include/ntp_control.h @@ -163,8 +163,14 @@ struct ntp_control { #define CS_SYSTEM 16 #define CS_STABIL 17 #define CS_VARLIST 18 - +#ifdef PUBKEY +#define CS_PRIVATE 19 +#define CS_PUBLIC 20 +#define CS_DHPARAMS 21 +#define CS_MAXCODE CS_DHPARAMS +#else #define CS_MAXCODE CS_VARLIST +#endif /* PUBKEY */ /* * Peer variables we understand @@ -206,8 +212,17 @@ struct ntp_control { #define CP_FLASH 35 #define CP_DISP 36 #define CP_VARLIST 37 - +#ifdef PUBKEY +#define CP_PUBLIC 38 +#define CP_SESKEY 39 +#define CP_SASKEY 40 +#define CP_AUTOSEQ 41 +#define CP_INITKEY 42 +#define CP_INITSEQ 43 +#define CP_MAXCODE CP_INITSEQ +#else #define CP_MAXCODE CP_VARLIST +#endif /* PUBKEY */ /* * Clock variables we understand diff --git a/include/ntp_crypto.h b/include/ntp_crypto.h new file mode 100644 index 0000000000..f85097d4d9 --- /dev/null +++ b/include/ntp_crypto.h @@ -0,0 +1,68 @@ +/* + * ntp_crypto.h - definitions for cryptographic operations + */ +#ifdef AUTOKEY +#include "global.h" +#include "md5.h" +#ifdef PUBKEY +#include "rsaref.h" +#include "rsa.h" +#endif /* PUBKEY */ + +/* + * Extension field definitions + */ +#define CRYPTO_NULL 0 /* no operation */ +#define CRYPTO_PUBL 1 /* public key */ +#define CRYPTO_ASSOC 2 /* association ID */ +#define CRYPTO_AUTO 3 /* autokey values */ +#define CRYPTO_PRIV 4 /* cookie value (client/server) */ +#define CRYPTO_DH 5 /* Diffie-Hellman value (symmetric) */ +#define CRYPTO_RESP 0x80 /* response */ +#define CRYPTO_ERROR 0x40 /* error */ + +/* + * Cryptoflags + */ +#define CRYPTO_FLAG_NONE 0x00 /* nothing happening */ +#define CRYPTO_FLAG_PUBL 0x01 /* read peer public key from file */ + +#ifdef PUBKEY +/* + * Configuration codes + */ +#define CRYPTO_CONF_NONE 0 /* nothing doing */ +#define CRYPTO_CONF_FLAGS 1 /* initialize flags */ +#define CRYPTO_CONF_PRIV 2 /* load private key from file */ +#define CRYPTO_CONF_PUBL 3 /* load public key from file */ +#define CRYPTO_CONF_DH 4 /* load Diffie_Hellman pars from file */ +#define CRYPTO_CONF_KEYS 5 /* set keys directory path */ +#endif /* PUBKEY */ + +/* + * Function prototypes + */ +extern void crypto_recv P((struct peer *, struct recvbuf *)); +extern int crypto_xmit P((u_int32 *, int, u_int, keyid_t, + int)); +extern keyid_t session_key P((struct sockaddr_in *, struct + sockaddr_in *, keyid_t, keyid_t, + u_long)); +extern void make_keylist P((struct peer *)); +extern void key_expire P((struct peer *)); +#ifdef PUBKEY +extern void crypto_init P((void)); +extern void crypto_config P((int, char *)); +extern void crypto_setup P((void)); +extern void crypto_public P((struct peer *, u_char *)); +extern void crypto_agree P((void)); + +/* + * Cryptographic values + */ +extern int crypto_enable; +extern char * private_key_file; +extern char * public_key_file; +extern char * dh_public_file; +#endif /* PUBKEY */ +#endif /* AUTOKEY */ diff --git a/include/ntp_request.h b/include/ntp_request.h index 87dba88154..5246163d88 100644 --- a/include/ntp_request.h +++ b/include/ntp_request.h @@ -111,6 +111,8 @@ /* * A request packet. These are almost a fixed length. */ +#define MAXFILENAME 128 /* max key file name length */ + struct req_pkt { u_char rm_vn_mode; /* response, more, version, mode */ u_char auth_seq; /* key, sequence number */ @@ -118,9 +120,9 @@ struct req_pkt { u_char request; /* request number */ u_short err_nitems; /* error code/number of data items */ u_short mbz_itemsize; /* item size */ - char data[32]; /* data area */ + char data[144]; /* data area */ l_fp tstamp; /* time stamp, for authentication */ - u_int32 keyid; /* encryption key */ + keyid_t keyid; /* encryption key */ char mac[MAX_MAC_LEN-sizeof(u_int32)]; /* (optional) 8 byte auth code */ }; @@ -257,7 +259,8 @@ struct resp_pkt { #define REQ_GET_KERNEL 38 /* get kernel pll/pps information */ #define REQ_GET_CLKBUGINFO 39 /* get clock debugging info */ #define REQ_SET_PRECISION 41 /* (not used) */ -#define REQ_MON_GETLIST_1 42 /* return data collected by monitor v1 */ +#define REQ_MON_GETLIST_1 42 /* return collected v1 monitor data */ +#define REQ_HOSTNAME_ASSOCID 43 /* Here is a hostname + assoc_id */ /* * Flags in the peer information returns @@ -286,6 +289,7 @@ struct resp_pkt { /* * Peer list structure. Used to return raw lists of peers. It goes * without saying that everything returned is in network byte order. + * Well, it *would* have gone without saying, but somebody said it. */ struct info_peer_list { u_int32 address; /* address of peer */ @@ -337,7 +341,7 @@ struct info_peer { u_char ttl; /* peer.ttl */ u_short flash2; /* new peer.flash */ u_short associd; /* association ID */ - u_int32 keyid; /* peer.keyid */ + keyid_t keyid; /* peer.keyid */ u_int32 pkeyid; /* unused */ u_int32 refid; /* peer.refid */ u_int32 timer; /* peer.timer */ @@ -524,7 +528,8 @@ struct conf_peer { u_char flags; /* flags for this request */ u_char ttl; /* time to live (multicast) or refclock mode */ u_short unused; /* unused */ - u_int32 keyid; /* key to use for this association */ + keyid_t keyid; /* key to use for this association */ + char keystr[MAXFILENAME]; /* public key file name*/ }; #define CONF_FLAG_AUTHENABLE 0x1 @@ -788,3 +793,13 @@ struct info_kernel { int32 errcnt; int32 stbcnt; }; + +/* + * Info returned with IP -> hostname lookup + */ +#define NTP_MAXHOSTNAME (144 - sizeof(u_int32) - sizeof(u_short)) +struct info_dns_assoc { + u_int32 peeraddr; /* peer address (HMS: being careful...) */ + u_short associd; /* association ID */ + char hostname[NTP_MAXHOSTNAME]; /* hostname */ +}; diff --git a/include/ntp_stdlib.h b/include/ntp_stdlib.h index 6a2a852212..30423204cf 100644 --- a/include/ntp_stdlib.h +++ b/include/ntp_stdlib.h @@ -32,25 +32,15 @@ extern void msyslog P((int, const char *, ...)) extern void msyslog P(()); #endif -#if 0 /* HMS: These seem to be unused now */ -extern void auth_des P((u_long *, u_char *)); extern void auth_delkeys P((void)); -extern int auth_parity P((u_long *)); -extern void auth_setkey P((u_long, u_long *)); -extern void auth_subkeys P((u_long *, u_char *, u_char *)); -#endif - -extern void auth1crypt P((u_long, u_int32 *, int)); -extern int auth2crypt P((u_long, u_int32 *, int)); -extern void auth_delkeys P((void)); -extern int auth_havekey P((u_long)); -extern int authdecrypt P((u_long, u_int32 *, int, int)); -extern int authencrypt P((u_long, u_int32 *, int)); -extern int authhavekey P((u_long)); -extern int authistrusted P((u_long)); +extern int auth_havekey P((keyid_t)); +extern int authdecrypt P((keyid_t, u_int32 *, int, int)); +extern int authencrypt P((keyid_t, u_int32 *, int)); +extern int authhavekey P((keyid_t)); +extern int authistrusted P((keyid_t)); extern int authreadkeys P((const char *)); -extern void authtrust P((u_long, int)); -extern int authusekey P((u_long, int, const u_char *)); +extern void authtrust P((keyid_t, u_long)); +extern int authusekey P((keyid_t, int, const u_char *)); extern u_long calleapwhen P((u_long)); extern u_long calyearstart P((u_long)); @@ -66,14 +56,14 @@ extern int ntp_getopt P((int, char **, const char *)); extern void init_auth P((void)); extern void init_lib P((void)); extern void init_random P((void)); -extern struct savekey *auth_findkey P((u_long)); +extern struct savekey *auth_findkey P((keyid_t)); extern int auth_moremem P((void)); extern int ymd2yd P((int, int, int)); #ifdef DES extern int DESauthdecrypt P((u_char *, u_int32 *, int, int)); extern int DESauthencrypt P((u_char *, u_int32 *, int)); -extern void DESauth_setkey P((u_long, const u_int32 *)); +extern void DESauth_setkey P((keyid_t, const u_int32 *)); extern void DESauth_subkeys P((const u_int32 *, u_char *, u_char *)); extern void DESauth_des P((u_int32 *, u_char *)); extern int DESauth_parity P((u_int32 *)); @@ -82,8 +72,7 @@ extern int DESauth_parity P((u_int32 *)); #ifdef MD5 extern int MD5authdecrypt P((u_char *, u_int32 *, int, int)); extern int MD5authencrypt P((u_char *, u_int32 *, int)); -extern void MD5auth_setkey P((u_long, const u_char *, const int)); -extern u_long session_key P((u_int32, u_int32, u_long, u_long)); +extern void MD5auth_setkey P((keyid_t, const u_char *, const int)); #endif /* MD5 */ extern int atoint P((const char *, long *)); @@ -143,7 +132,7 @@ extern int authnumfreekeys; /* * The key cache. We cache the last key we looked at here. */ -extern u_long cache_keyid; /* key identifier */ +extern keyid_t cache_keyid; /* key identifier */ extern u_char * cache_key; /* key pointer */ extern u_int cache_keylen; /* key length */ diff --git a/include/ntp_types.h b/include/ntp_types.h index 820c72aeed..25a5a8d73f 100644 --- a/include/ntp_types.h +++ b/include/ntp_types.h @@ -65,5 +65,7 @@ typedef unsigned int u_int; # include "Bletch: what's 32 bits on this machine?" #endif /* not sizeof(int) == 4 */ +typedef u_int32 keyid_t; + #endif /* _NTP_TYPES_ */ diff --git a/include/ntpd.h b/include/ntpd.h index 1a83d6eb0a..fcb480b560 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -11,6 +11,7 @@ #include "recvbuff.h" #define MAXINTERFACES 512 +#define MAXFILENAME 128 /* maximum length of a file name */ #ifdef SYS_WINNT #define exit service_exit @@ -71,6 +72,8 @@ extern void set_var P((struct ctl_var **, const char *, unsigned long, int)) extern void set_sys_var P((char *, unsigned long, int)); /* ntp_intres.c */ +extern void ntp_res_send P((void *, char *, u_int32, u_short)); +extern void ntp_res_recv P((void)); extern void ntp_intres P((void)); /* ntp_io.c */ @@ -125,7 +128,7 @@ extern struct peer *findpeerbyassoc P((int)); extern struct peer *newpeer P((struct sockaddr_in *, struct interface *, int, int, int, int, int, u_long)); extern void peer_all_reset P((void)); extern void peer_clr_stats P((void)); -extern struct peer *peer_config P((struct sockaddr_in *, struct interface *, int, int, int, int, int, int, u_long)); +extern struct peer *peer_config P((struct sockaddr_in *, struct interface *, int, int, int, int, int, int, keyid_t, u_char *)); extern void peer_reset P((struct peer *)); extern int peer_unconfig P((struct sockaddr_in *, struct interface *, int)); extern void unpeer P((struct peer *)); @@ -137,7 +140,7 @@ extern void peer_config_manycast P((struct peer *, struct peer *)); extern void transmit P((struct peer *)); extern void receive P((struct recvbuf *)); extern void peer_clear P((struct peer *)); -extern int process_packet P((struct peer *, struct pkt *, l_fp *)); +extern void process_packet P((struct peer *, struct pkt *, l_fp *)); extern void clock_select P((void)); /* @@ -203,7 +206,7 @@ extern int config_priority; struct ctl_trap; extern struct ctl_trap ctl_trap[]; extern int num_ctl_traps; -extern u_long ctl_auth_keyid; /* keyid used for authenticating write requests */ +extern keyid_t ctl_auth_keyid; /* keyid used for authenticating write requests */ /* * Statistic counters to keep track of requests and responses. @@ -225,7 +228,7 @@ extern u_long numctlbadop; /* bad op code found in packet */ extern u_long numasyncmsgs; /* number of async messages we've sent */ /* ntp_intres.c */ -extern u_long req_keyid; /* request keyid */ +extern keyid_t req_keyid; /* request keyid */ extern char * req_file; /* name of the file with configuration info */ /* @@ -326,7 +329,7 @@ extern int sys_bclient; /* we set our time to broadcasts */ extern double sys_bdelay; /* broadcast client default delay */ extern int sys_authenticate; /* requre authentication for config */ extern l_fp sys_authdelay; /* authentication delay */ -extern u_long sys_private; /* private value for session seed */ +extern keyid_t sys_private; /* private value for session seed */ extern int sys_manycastserver; /* 1 => respond to manycast client pkts */ /* @@ -350,7 +353,7 @@ extern int fdpps; /* pps file descriptor */ #endif /* ntp_request.c */ -extern u_long info_auth_keyid; /* keyid used to authenticate requests */ +extern keyid_t info_auth_keyid; /* keyid used to authenticate requests */ /* ntp_restrict.c */ extern struct restrictlist *restrictlist; /* the restriction list */ diff --git a/kernel/Makefile.in b/kernel/Makefile.in index b79370efa9..e657e98e5f 100644 --- a/kernel/Makefile.in +++ b/kernel/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/kernel/sys/Makefile.in b/kernel/sys/Makefile.in index 25d8ad189d..430bf57bc7 100644 --- a/kernel/sys/Makefile.in +++ b/kernel/sys/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/libntp/Makefile.in b/libntp/Makefile.in index 005e5890c8..c69becec61 100644 --- a/libntp/Makefile.in +++ b/libntp/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/libntp/a_md5encrypt.c b/libntp/a_md5encrypt.c index 76f9c4fadd..8271ae55b5 100644 --- a/libntp/a_md5encrypt.c +++ b/libntp/a_md5encrypt.c @@ -18,14 +18,12 @@ #include #include "ntp_types.h" -#include "ntp_fp.h" #include "ntp_string.h" #include "global.h" #include "md5.h" #include "ntp_stdlib.h" #define BLOCK_OCTETS 16 /* message digest size */ -#define NTP_MAXKEY 65535 /* max identifier from ntp.h */ /* @@ -85,48 +83,4 @@ MD5authdecrypt( return (!memcmp((char *)digest, (char *)pkt + length + 4, BLOCK_OCTETS)); } - - -/* - * session_key - generate session key from supplied plaintext. - * - * Returns hashed session key for validation. - */ -u_long -session_key( - u_int32 srcadr, /* source address */ - u_int32 dstadr, /* destination address */ - u_long keyno, /* key identifier */ - u_long lifetime /* key lifetime */ - ) -{ - MD5_CTX ctx; - u_int32 header[3]; - u_long keyid; - u_char digest[BLOCK_OCTETS]; - - /* - * Generate the session key and retrieve the hash for later. If - * the lifetime is greater than zero, call the key trusted. - */ - header[0] = htonl(srcadr); - header[1] = htonl(dstadr); - header[2] = htonl(keyno); - MD5Init(&ctx); - MD5Update(&ctx, (u_char *)header, sizeof(header)); - MD5Final(digest, &ctx); - memcpy(&keyid, digest, 4); - if (lifetime != 0) { - MD5auth_setkey(keyno, digest, BLOCK_OCTETS); - authtrust(keyno, (int)lifetime); - } -#ifdef DEBUG - if (debug > 1) - printf( - "session_key: from %s to %s keyid %08lx hash %08lx life %ld\n", - numtoa(htonl(srcadr)), numtoa(htonl(dstadr)), keyno, - keyid, lifetime); -#endif - return (keyid); -} #endif /* MD5 */ diff --git a/libntp/authencrypt.c b/libntp/authencrypt.c index 22f910c366..075afe09b7 100644 --- a/libntp/authencrypt.c +++ b/libntp/authencrypt.c @@ -67,7 +67,7 @@ int DESauthdecrypt( u_char *key, /* key pointer */ u_int32 *pkt, /* packet pointer */ - int length, /* packet length */ + int length, /* packet length */ int size /* size of MAC field */ ) { diff --git a/libntp/authkeys.c b/libntp/authkeys.c index 578688bdf2..670e8d0b65 100644 --- a/libntp/authkeys.c +++ b/libntp/authkeys.c @@ -30,7 +30,7 @@ struct savekey { u_char MD5_key[32]; /* MD5 key */ #endif } k; - u_long keyid; /* key identifier */ + keyid_t keyid; /* key identifier */ u_short flags; /* flags that wave */ u_long lifetime; /* remaining lifetime */ #ifdef MD5 @@ -73,7 +73,7 @@ int authnumfreekeys; /* * The key cache. We cache the last key we looked at here. */ -u_long cache_keyid; /* key identifier */ +keyid_t cache_keyid; /* key identifier */ u_char *cache_key; /* key pointer */ u_int cache_keylen; /* key length */ u_short cache_flags; /* flags that wave */ @@ -97,7 +97,7 @@ init_auth(void) */ struct savekey * auth_findkey( - u_long keyno + keyid_t keyno ) { struct savekey *sk; @@ -118,7 +118,7 @@ auth_findkey( */ int auth_havekey( - u_long keyno + keyid_t keyno ) { struct savekey *sk; @@ -142,7 +142,7 @@ auth_havekey( */ int authhavekey( - u_long keyno + keyid_t keyno ) { struct savekey *sk; @@ -211,15 +211,15 @@ auth_moremem(void) */ void authtrust( - u_long keyno, - int trust + keyid_t keyno, + u_long trust ) { struct savekey *sk; #ifdef DEBUG - if (debug > 1) - printf("authtrust: keyid %08lx life %d\n", (u_long)keyno, trust); + if (debug > 2) + printf("authtrust: keyid %08x life %lu\n", keyno, trust); #endif sk = key_hash[KEYHASH(keyno)]; while (sk != 0) { @@ -288,7 +288,7 @@ authtrust( */ int authistrusted( - u_long keyno + keyid_t keyno ) { struct savekey *sk; @@ -321,7 +321,7 @@ authistrusted( */ void DESauth_setkey( - u_long keyno, + keyid_t keyno, const u_int32 *key ) { @@ -371,7 +371,7 @@ DESauth_setkey( #ifdef MD5 void MD5auth_setkey( - u_long keyno, + keyid_t keyno, const u_char *key, const int len ) @@ -503,7 +503,7 @@ auth_agekeys(void) */ int authencrypt( - u_long keyno, + keyid_t keyno, u_int32 *pkt, int length ) @@ -515,7 +515,7 @@ authencrypt( * consists of a single word with value zero. */ authencryptions++; - pkt[length / 4] = (u_long)htonl(keyno); + pkt[length / 4] = htonl(keyno); if (keyno == 0) { return (4); } @@ -541,7 +541,7 @@ authencrypt( */ int authdecrypt( - u_long keyno, + keyid_t keyno, u_int32 *pkt, int length, int size @@ -555,7 +555,7 @@ authdecrypt( */ authdecryptions++; if (keyno == 0) - return (1); + return (0); if (!authhavekey(keyno) || size < 4) return (0); diff --git a/libntp/authusekey.c b/libntp/authusekey.c index a399a48a13..b944d7dc43 100644 --- a/libntp/authusekey.c +++ b/libntp/authusekey.c @@ -30,7 +30,7 @@ int authusekey( - u_long keyno, + keyid_t keyno, int keytype, const u_char *str ) diff --git a/libntp/systime.c b/libntp/systime.c index 2ef6ef9da7..3664870104 100644 --- a/libntp/systime.c +++ b/libntp/systime.c @@ -159,7 +159,8 @@ adj_systime( /* casey - we need a posix type thang here */ if (adjtime(&adjtv, &oadjtv) < 0) { - msyslog(LOG_ERR, "Can't adjust time: %m"); + msyslog(LOG_ERR, "Can't adjust time (%d sec, %d usec): %m", + adjtv.tv_sec, adjtv.tv_usec); return 0; } else { diff --git a/libparse/Makefile.in b/libparse/Makefile.in index 8331a908d9..e4cab217a6 100644 --- a/libparse/Makefile.in +++ b/libparse/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/librsaref/Makefile.in b/librsaref/Makefile.in index fe2a22bc69..b8d8a3e2e0 100644 --- a/librsaref/Makefile.in +++ b/librsaref/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/ntpd/Makefile.am b/ntpd/Makefile.am index 8c53a23cd5..2b30f69d14 100644 --- a/ntpd/Makefile.am +++ b/ntpd/Makefile.am @@ -15,9 +15,11 @@ EXTRA_PROGRAMS = check_y2k check-local: @MAKE_CHECK_Y2K@ [ -z "@MAKE_CHECK_Y2K@" ] || ./@MAKE_CHECK_Y2K@ -ntpd_SOURCES = jupiter.h map_vme.c ntp_config.c ntp_control.c ntp_filegen.c \ +ntpd_SOURCES = jupiter.h map_vme.c ntp_config.c ntp_control.c ntp_crypto.c \ + ntp_filegen.c \ ntp_intres.c ntp_io.c ntp_loopfilter.c ntp_monitor.c ntp_peer.c \ - ntp_proto.c ntp_refclock.c ntp_request.c ntp_restrict.c ntp_timer.c \ + ntp_proto.c ntp_refclock.c ntp_request.c ntp_resolver.c \ + ntp_restrict.c ntp_timer.c \ ntp_util.c ntpd.c refclock_acts.c refclock_arbiter.c refclock_arc.c \ refclock_as2201.c refclock_atom.c refclock_bancomm.c \ refclock_chronolog.c refclock_chu.c refclock_conf.c refclock_datum.c \ diff --git a/ntpd/Makefile.in b/ntpd/Makefile.in index f26b375a8e..87319fa818 100644 --- a/ntpd/Makefile.in +++ b/ntpd/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ @@ -115,9 +116,11 @@ ETAGS_ARGS = Makefile.am check_PROGRAMS = @MAKE_CHECK_Y2K@ EXTRA_PROGRAMS = check_y2k -ntpd_SOURCES = jupiter.h map_vme.c ntp_config.c ntp_control.c ntp_filegen.c \ +ntpd_SOURCES = jupiter.h map_vme.c ntp_config.c ntp_control.c ntp_crypto.c \ + ntp_filegen.c \ ntp_intres.c ntp_io.c ntp_loopfilter.c ntp_monitor.c ntp_peer.c \ - ntp_proto.c ntp_refclock.c ntp_request.c ntp_restrict.c ntp_timer.c \ + ntp_proto.c ntp_refclock.c ntp_request.c ntp_resolver.c \ + ntp_restrict.c ntp_timer.c \ ntp_util.c ntpd.c refclock_acts.c refclock_arbiter.c refclock_arc.c \ refclock_as2201.c refclock_atom.c refclock_bancomm.c \ refclock_chronolog.c refclock_chu.c refclock_conf.c refclock_datum.c \ @@ -146,21 +149,21 @@ check_y2k_LDADD = $(LDADD) check_y2k_DEPENDENCIES = version.o ../libntp/libntp.a check_y2k_LDFLAGS = am_ntpd_OBJECTS = map_vme$U.o ntp_config$U.o ntp_control$U.o \ -ntp_filegen$U.o ntp_intres$U.o ntp_io$U.o ntp_loopfilter$U.o \ -ntp_monitor$U.o ntp_peer$U.o ntp_proto$U.o ntp_refclock$U.o \ -ntp_request$U.o ntp_restrict$U.o ntp_timer$U.o ntp_util$U.o ntpd$U.o \ -refclock_acts$U.o refclock_arbiter$U.o refclock_arc$U.o \ -refclock_as2201$U.o refclock_atom$U.o refclock_bancomm$U.o \ -refclock_chronolog$U.o refclock_chu$U.o refclock_conf$U.o \ -refclock_datum$U.o refclock_dumbclock$U.o refclock_fg$U.o \ -refclock_gpsvme$U.o refclock_heath$U.o refclock_hpgps$U.o \ -refclock_irig$U.o refclock_jupiter$U.o refclock_leitch$U.o \ -refclock_local$U.o refclock_msfees$U.o refclock_mx4200$U.o \ -refclock_nmea$U.o refclock_oncore$U.o refclock_palisade$U.o \ -refclock_parse$U.o refclock_pcf$U.o refclock_pst$U.o \ -refclock_ptbacts$U.o refclock_shm$U.o refclock_tpro$U.o \ -refclock_trak$U.o refclock_true$U.o refclock_ulink$U.o \ -refclock_usno$U.o refclock_wwv$U.o refclock_wwvb$U.o +ntp_crypto$U.o ntp_filegen$U.o ntp_intres$U.o ntp_io$U.o \ +ntp_loopfilter$U.o ntp_monitor$U.o ntp_peer$U.o ntp_proto$U.o \ +ntp_refclock$U.o ntp_request$U.o ntp_resolver$U.o ntp_restrict$U.o \ +ntp_timer$U.o ntp_util$U.o ntpd$U.o refclock_acts$U.o \ +refclock_arbiter$U.o refclock_arc$U.o refclock_as2201$U.o \ +refclock_atom$U.o refclock_bancomm$U.o refclock_chronolog$U.o \ +refclock_chu$U.o refclock_conf$U.o refclock_datum$U.o \ +refclock_dumbclock$U.o refclock_fg$U.o refclock_gpsvme$U.o \ +refclock_heath$U.o refclock_hpgps$U.o refclock_irig$U.o \ +refclock_jupiter$U.o refclock_leitch$U.o refclock_local$U.o \ +refclock_msfees$U.o refclock_mx4200$U.o refclock_nmea$U.o \ +refclock_oncore$U.o refclock_palisade$U.o refclock_parse$U.o \ +refclock_pcf$U.o refclock_pst$U.o refclock_ptbacts$U.o refclock_shm$U.o \ +refclock_tpro$U.o refclock_trak$U.o refclock_true$U.o \ +refclock_ulink$U.o refclock_usno$U.o refclock_wwv$U.o refclock_wwvb$U.o ntpd_OBJECTS = $(am_ntpd_OBJECTS) ntpd_DEPENDENCIES = version.o ../libntp/libntp.a ntpd_LDFLAGS = @@ -177,11 +180,12 @@ GZIP_ENV = --best depcomp = $(SHELL) $(top_srcdir)/depcomp DEP_FILES = @AMDEP@ $(DEPDIR)/check_y2k$U.Po $(DEPDIR)/map_vme$U.Po \ $(DEPDIR)/ntp_config$U.Po $(DEPDIR)/ntp_control$U.Po \ -$(DEPDIR)/ntp_filegen$U.Po $(DEPDIR)/ntp_intres$U.Po \ -$(DEPDIR)/ntp_io$U.Po $(DEPDIR)/ntp_loopfilter$U.Po \ -$(DEPDIR)/ntp_monitor$U.Po $(DEPDIR)/ntp_peer$U.Po \ -$(DEPDIR)/ntp_proto$U.Po $(DEPDIR)/ntp_refclock$U.Po \ -$(DEPDIR)/ntp_request$U.Po $(DEPDIR)/ntp_restrict$U.Po \ +$(DEPDIR)/ntp_crypto$U.Po $(DEPDIR)/ntp_filegen$U.Po \ +$(DEPDIR)/ntp_intres$U.Po $(DEPDIR)/ntp_io$U.Po \ +$(DEPDIR)/ntp_loopfilter$U.Po $(DEPDIR)/ntp_monitor$U.Po \ +$(DEPDIR)/ntp_peer$U.Po $(DEPDIR)/ntp_proto$U.Po \ +$(DEPDIR)/ntp_refclock$U.Po $(DEPDIR)/ntp_request$U.Po \ +$(DEPDIR)/ntp_resolver$U.Po $(DEPDIR)/ntp_restrict$U.Po \ $(DEPDIR)/ntp_timer$U.Po $(DEPDIR)/ntp_util$U.Po $(DEPDIR)/ntpd$U.Po \ $(DEPDIR)/refclock_acts$U.Po $(DEPDIR)/refclock_arbiter$U.Po \ $(DEPDIR)/refclock_arc$U.Po $(DEPDIR)/refclock_as2201$U.Po \ @@ -292,6 +296,8 @@ ntp_config_.c: ntp_config.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_config.c; then echo $(srcdir)/ntp_config.c; else echo ntp_config.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_config_.c ntp_control_.c: ntp_control.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_control.c; then echo $(srcdir)/ntp_control.c; else echo ntp_control.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_control_.c +ntp_crypto_.c: ntp_crypto.c $(ANSI2KNR) + $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_crypto.c; then echo $(srcdir)/ntp_crypto.c; else echo ntp_crypto.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_crypto_.c ntp_filegen_.c: ntp_filegen.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_filegen.c; then echo $(srcdir)/ntp_filegen.c; else echo ntp_filegen.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_filegen_.c ntp_intres_.c: ntp_intres.c $(ANSI2KNR) @@ -310,6 +316,8 @@ ntp_refclock_.c: ntp_refclock.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_refclock.c; then echo $(srcdir)/ntp_refclock.c; else echo ntp_refclock.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_refclock_.c ntp_request_.c: ntp_request.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_request.c; then echo $(srcdir)/ntp_request.c; else echo ntp_request.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_request_.c +ntp_resolver_.c: ntp_resolver.c $(ANSI2KNR) + $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_resolver.c; then echo $(srcdir)/ntp_resolver.c; else echo ntp_resolver.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_resolver_.c ntp_restrict_.c: ntp_restrict.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_restrict.c; then echo $(srcdir)/ntp_restrict.c; else echo ntp_restrict.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_restrict_.c ntp_timer_.c: ntp_timer.c $(ANSI2KNR) @@ -390,13 +398,13 @@ refclock_wwv_.c: refclock_wwv.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/refclock_wwv.c; then echo $(srcdir)/refclock_wwv.c; else echo refclock_wwv.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > refclock_wwv_.c refclock_wwvb_.c: refclock_wwvb.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/refclock_wwvb.c; then echo $(srcdir)/refclock_wwvb.c; else echo refclock_wwvb.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > refclock_wwvb_.c -check_y2k_.o map_vme_.o ntp_config_.o ntp_control_.o ntp_filegen_.o \ -ntp_intres_.o ntp_io_.o ntp_loopfilter_.o ntp_monitor_.o ntp_peer_.o \ -ntp_proto_.o ntp_refclock_.o ntp_request_.o ntp_restrict_.o \ -ntp_timer_.o ntp_util_.o ntpd_.o refclock_acts_.o refclock_arbiter_.o \ -refclock_arc_.o refclock_as2201_.o refclock_atom_.o refclock_bancomm_.o \ -refclock_chronolog_.o refclock_chu_.o refclock_conf_.o \ -refclock_datum_.o refclock_dumbclock_.o refclock_fg_.o \ +check_y2k_.o map_vme_.o ntp_config_.o ntp_control_.o ntp_crypto_.o \ +ntp_filegen_.o ntp_intres_.o ntp_io_.o ntp_loopfilter_.o ntp_monitor_.o \ +ntp_peer_.o ntp_proto_.o ntp_refclock_.o ntp_request_.o ntp_resolver_.o \ +ntp_restrict_.o ntp_timer_.o ntp_util_.o ntpd_.o refclock_acts_.o \ +refclock_arbiter_.o refclock_arc_.o refclock_as2201_.o refclock_atom_.o \ +refclock_bancomm_.o refclock_chronolog_.o refclock_chu_.o \ +refclock_conf_.o refclock_datum_.o refclock_dumbclock_.o refclock_fg_.o \ refclock_gpsvme_.o refclock_heath_.o refclock_hpgps_.o refclock_irig_.o \ refclock_jupiter_.o refclock_leitch_.o refclock_local_.o \ refclock_msfees_.o refclock_mx4200_.o refclock_nmea_.o \ @@ -456,6 +464,7 @@ distdir: $(DISTFILES) @AMDEP@include $(DEPDIR)/map_vme$U.Po @AMDEP@include $(DEPDIR)/ntp_config$U.Po @AMDEP@include $(DEPDIR)/ntp_control$U.Po +@AMDEP@include $(DEPDIR)/ntp_crypto$U.Po @AMDEP@include $(DEPDIR)/ntp_filegen$U.Po @AMDEP@include $(DEPDIR)/ntp_intres$U.Po @AMDEP@include $(DEPDIR)/ntp_io$U.Po @@ -465,6 +474,7 @@ distdir: $(DISTFILES) @AMDEP@include $(DEPDIR)/ntp_proto$U.Po @AMDEP@include $(DEPDIR)/ntp_refclock$U.Po @AMDEP@include $(DEPDIR)/ntp_request$U.Po +@AMDEP@include $(DEPDIR)/ntp_resolver$U.Po @AMDEP@include $(DEPDIR)/ntp_restrict$U.Po @AMDEP@include $(DEPDIR)/ntp_timer$U.Po @AMDEP@include $(DEPDIR)/ntp_util$U.Po diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index 60c9283d41..d71e051ef8 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -1,7 +1,6 @@ /* * ntp_config.c - read and apply configuration information */ - #ifdef HAVE_CONFIG_H # include #endif @@ -32,6 +31,10 @@ #include "ntp_filegen.h" #include "ntp_stdlib.h" +#ifdef PUBKEY +#include "ntp_crypto.h" +#endif /* PUBKEY */ + #ifdef SYS_WINNT #include extern HANDLE ResolverThreadHandle; @@ -71,6 +74,8 @@ extern HANDLE ResolverThreadHandle; * restrict [ addr ] [ mask 255.255.255.0 ] ignore|noserve|notrust|noquery * driftfile file_name * keys file_name + * publickey file_name + * privatekey file_name * statsdir /var/NTP/ * filegen peerstats [ file peerstats ] [ type day ] [ link ] * clientlimit [ n ] @@ -95,6 +100,9 @@ extern HANDLE ResolverThreadHandle; */ #define CONFIG_UNKNOWN 0 +/* + * Command keywords + */ #define CONFIG_PEER 1 #define CONFIG_SERVER 2 #define CONFIG_AUTOMAX 3 @@ -112,7 +120,9 @@ extern HANDLE ResolverThreadHandle; #define CONFIG_CONTROLKEY 15 #define CONFIG_TRAP 16 #define CONFIG_FUDGE 17 -#define CONFIG_18 18 /* unused */ +#ifdef PUBKEY +#define CONFIG_KEYSDIR 18 +#endif /* PUBKEY */ #define CONFIG_STATSDIR 19 #define CONFIG_FILEGEN 20 #define CONFIG_STATISTICS 21 @@ -128,7 +138,13 @@ extern HANDLE ResolverThreadHandle; #define CONFIG_LOGCONFIG 31 #define CONFIG_MANYCASTCLIENT 32 #define CONFIG_MANYCASTSERVER 33 +#ifdef PUBKEY +#define CONFIG_CRYPTO 34 +#endif /* PUBKEY */ +/* + * "peer", "server", "broadcast" modifier keywords + */ #define CONF_MOD_VERSION 1 #define CONF_MOD_KEY 2 #define CONF_MOD_MINPOLL 3 @@ -139,7 +155,13 @@ extern HANDLE ResolverThreadHandle; #define CONF_MOD_TTL 8 #define CONF_MOD_MODE 9 #define CONF_MOD_NOSELECT 10 +#ifdef PUBKEY +#define CONF_MOD_PUBLICKEY 11 +#endif /* PUBKEY */ +/* + * "restrict" modifier keywords + */ #define CONF_RES_MASK 1 #define CONF_RES_IGNORE 2 #define CONF_RES_NOSERVE 3 @@ -152,9 +174,15 @@ extern HANDLE ResolverThreadHandle; #define CONF_RES_NTPPORT 10 #define CONF_RES_LIMITED 11 +/* + * "trap" modifier keywords + */ #define CONF_TRAP_PORT 1 #define CONF_TRAP_INTERFACE 2 +/* + * "fudge" modifier keywords + */ #define CONF_FDG_TIME1 1 #define CONF_FDG_TIME2 2 #define CONF_FDG_STRATUM 3 @@ -164,6 +192,9 @@ extern HANDLE ResolverThreadHandle; #define CONF_FDG_FLAG3 7 #define CONF_FDG_FLAG4 8 +/* + * "filegen" modifier keywords + */ #define CONF_FGEN_FILE 1 #define CONF_FGEN_TYPE 2 #define CONF_FGEN_FLAG_LINK 3 @@ -171,10 +202,23 @@ extern HANDLE ResolverThreadHandle; #define CONF_FGEN_FLAG_ENABLE 5 #define CONF_FGEN_FLAG_DISABLE 6 +/* + * "pps" modifier keywords + */ #define CONF_PPS_ASSERT 1 #define CONF_PPS_CLEAR 2 #define CONF_PPS_HARDPPS 3 +#ifdef PUBKEY +/* + * "crypto" modifier keywords + */ +#define CONF_CRYPTO_DH 1 +#define CONF_CRYPTO_PRIVATEKEY 2 +#define CONF_CRYPTO_PUBLICKEY 3 +#define CONF_CRYPTO_FLAGS 4 +#endif /* PUBKEY */ + /* * Translation table - keywords to function index */ @@ -187,38 +231,44 @@ struct keyword { * Command keywords */ static struct keyword keywords[] = { - { "peer", CONFIG_PEER }, - { "server", CONFIG_SERVER }, - { "driftfile", CONFIG_DRIFTFILE }, - { "broadcast", CONFIG_BROADCAST }, - { "broadcastclient", CONFIG_BROADCASTCLIENT }, - { "multicastclient", CONFIG_MULTICASTCLIENT }, - { "manycastclient", CONFIG_MANYCASTCLIENT }, - { "manycastserver", CONFIG_MANYCASTSERVER }, { "authenticate", CONFIG_AUTHENTICATE }, - { "keys", CONFIG_KEYS }, - { "revoke", CONFIG_REVOKE }, - { "pps", CONFIG_PPS }, { "automax", CONFIG_AUTOMAX }, - { "restrict", CONFIG_RESTRICT }, + { "broadcast", CONFIG_BROADCAST }, + { "broadcastclient", CONFIG_BROADCASTCLIENT }, { "broadcastdelay", CONFIG_BDELAY }, - { "trustedkey", CONFIG_TRUSTEDKEY }, - { "requestkey", CONFIG_REQUESTKEY }, - { "controlkey", CONFIG_CONTROLKEY }, - { "trap", CONFIG_TRAP }, - { "fudge", CONFIG_FUDGE }, - { "statsdir", CONFIG_STATSDIR }, - { "filegen", CONFIG_FILEGEN }, - { "statistics", CONFIG_STATISTICS }, - { "pidfile", CONFIG_PIDFILE }, - { "setvar", CONFIG_SETVAR }, { "clientlimit", CONFIG_CLIENTLIMIT }, { "clientperiod", CONFIG_CLIENTPERIOD }, - { "enable", CONFIG_ENABLE }, +#ifdef PUBKEY + { "crypto", CONFIG_CRYPTO }, +#endif /* PUBKEY */ + { "controlkey", CONFIG_CONTROLKEY }, { "disable", CONFIG_DISABLE }, - { "phone", CONFIG_PHONE }, - { "logfile", CONFIG_LOGFILE }, + { "driftfile", CONFIG_DRIFTFILE }, + { "enable", CONFIG_ENABLE }, + { "filegen", CONFIG_FILEGEN }, + { "fudge", CONFIG_FUDGE }, + { "keys", CONFIG_KEYS }, +#ifdef PUBKEY + { "keysdir", CONFIG_KEYSDIR }, +#endif /* PUBKEY */ { "logconfig", CONFIG_LOGCONFIG }, + { "logfile", CONFIG_LOGFILE }, + { "manycastclient", CONFIG_MANYCASTCLIENT }, + { "manycastserver", CONFIG_MANYCASTSERVER }, + { "multicastclient", CONFIG_MULTICASTCLIENT }, + { "peer", CONFIG_PEER }, + { "phone", CONFIG_PHONE }, + { "pidfile", CONFIG_PIDFILE }, + { "pps", CONFIG_PPS }, + { "requestkey", CONFIG_REQUESTKEY }, + { "restrict", CONFIG_RESTRICT }, + { "revoke", CONFIG_REVOKE }, + { "server", CONFIG_SERVER }, + { "setvar", CONFIG_SETVAR }, + { "statistics", CONFIG_STATISTICS }, + { "statsdir", CONFIG_STATSDIR }, + { "trap", CONFIG_TRAP }, + { "trustedkey", CONFIG_TRUSTEDKEY }, { "", CONFIG_UNKNOWN } }; @@ -226,16 +276,19 @@ static struct keyword keywords[] = { * "peer", "server", "broadcast" modifier keywords */ static struct keyword mod_keywords[] = { - { "version", CONF_MOD_VERSION }, + { "autokey", CONF_MOD_SKEY }, + { "burst", CONF_MOD_BURST }, { "key", CONF_MOD_KEY }, - { "minpoll", CONF_MOD_MINPOLL }, { "maxpoll", CONF_MOD_MAXPOLL }, - { "prefer", CONF_MOD_PREFER }, + { "minpoll", CONF_MOD_MINPOLL }, + { "mode", CONF_MOD_MODE }, /* refclocks */ { "noselect", CONF_MOD_NOSELECT }, - { "burst", CONF_MOD_BURST }, - { "autokey", CONF_MOD_SKEY }, - { "mode", CONF_MOD_MODE }, /* reference clocks */ + { "prefer", CONF_MOD_PREFER }, +#ifdef PUBKEY + { "publickey", CONF_MOD_PUBLICKEY }, +#endif /* PUBKEY */ { "ttl", CONF_MOD_TTL }, /* NTP peers */ + { "version", CONF_MOD_VERSION }, { "", CONFIG_UNKNOWN } }; @@ -243,17 +296,17 @@ static struct keyword mod_keywords[] = { * "restrict" modifier keywords */ static struct keyword res_keywords[] = { - { "mask", CONF_RES_MASK }, { "ignore", CONF_RES_IGNORE }, - { "noserve", CONF_RES_NOSERVE }, - { "notrust", CONF_RES_NOTRUST }, - { "noquery", CONF_RES_NOQUERY }, + { "limited", CONF_RES_LIMITED }, + { "lowpriotrap", CONF_RES_LPTRAP }, + { "mask", CONF_RES_MASK }, { "nomodify", CONF_RES_NOMODIFY }, { "nopeer", CONF_RES_NOPEER }, + { "noquery", CONF_RES_NOQUERY }, + { "noserve", CONF_RES_NOSERVE }, { "notrap", CONF_RES_NOTRAP }, - { "lowpriotrap", CONF_RES_LPTRAP }, + { "notrust", CONF_RES_NOTRUST }, { "ntpport", CONF_RES_NTPPORT }, - { "limited", CONF_RES_LIMITED }, { "", CONFIG_UNKNOWN } }; @@ -266,19 +319,18 @@ static struct keyword trap_keywords[] = { { "", CONFIG_UNKNOWN } }; - /* * "fudge" modifier keywords */ static struct keyword fudge_keywords[] = { - { "time1", CONF_FDG_TIME1 }, - { "time2", CONF_FDG_TIME2 }, - { "stratum", CONF_FDG_STRATUM }, - { "refid", CONF_FDG_REFID }, { "flag1", CONF_FDG_FLAG1 }, { "flag2", CONF_FDG_FLAG2 }, { "flag3", CONF_FDG_FLAG3 }, { "flag4", CONF_FDG_FLAG4 }, + { "refid", CONF_FDG_REFID }, + { "stratum", CONF_FDG_STRATUM }, + { "time1", CONF_FDG_TIME1 }, + { "time2", CONF_FDG_TIME2 }, { "", CONFIG_UNKNOWN } }; @@ -287,12 +339,12 @@ static struct keyword fudge_keywords[] = { * "filegen" modifier keywords */ static struct keyword filegen_keywords[] = { + { "disable", CONF_FGEN_FLAG_DISABLE }, + { "enable", CONF_FGEN_FLAG_ENABLE }, { "file", CONF_FGEN_FILE }, - { "type", CONF_FGEN_TYPE }, { "link", CONF_FGEN_FLAG_LINK }, { "nolink", CONF_FGEN_FLAG_NOLINK }, - { "enable", CONF_FGEN_FLAG_ENABLE }, - { "disable", CONF_FGEN_FLAG_DISABLE }, + { "type", CONF_FGEN_TYPE }, { "", CONFIG_UNKNOWN } }; @@ -300,13 +352,13 @@ static struct keyword filegen_keywords[] = { * "type" modifier keywords */ static struct keyword fgen_types[] = { + { "age", FILEGEN_AGE }, + { "day", FILEGEN_DAY }, + { "month", FILEGEN_MONTH }, { "none", FILEGEN_NONE }, { "pid", FILEGEN_PID }, - { "day", FILEGEN_DAY }, { "week", FILEGEN_WEEK }, - { "month", FILEGEN_MONTH }, { "year", FILEGEN_YEAR }, - { "age", FILEGEN_AGE }, { "", CONFIG_UNKNOWN} }; @@ -316,15 +368,15 @@ static struct keyword fgen_types[] = { static struct keyword flags_keywords[] = { { "auth", PROTO_AUTHENTICATE }, { "bclient", PROTO_BROADCLIENT }, - { "ntp", PROTO_NTP }, { "kernel", PROTO_KERNEL }, { "monitor", PROTO_MONITOR }, + { "ntp", PROTO_NTP }, { "stats", PROTO_FILEGEN }, { "", CONFIG_UNKNOWN } }; /* - * pps modifier keywords + * "pps" modifier keywords */ static struct keyword pps_keywords[] = { { "assert", CONF_PPS_ASSERT }, @@ -333,6 +385,19 @@ static struct keyword pps_keywords[] = { { "", CONFIG_UNKNOWN } }; +#ifdef PUBKEY +/* + * "crypto" modifier keywords + */ +static struct keyword crypto_keywords[] = { + { "dh", CONF_CRYPTO_DH }, + { "flags", CONF_CRYPTO_FLAGS }, + { "privatekey", CONF_CRYPTO_PRIVATEKEY }, + { "publickey", CONF_CRYPTO_PUBLICKEY }, + { "", CONFIG_UNKNOWN } +}; +#endif /* PUBKEY */ + /* * "logconfig" building blocks */ @@ -342,10 +407,10 @@ struct masks { }; static struct masks logcfg_class[] = { - { "sys", NLOG_OSYS }, - { "peer", NLOG_OPEER }, { "clock", NLOG_OCLOCK }, + { "peer", NLOG_OPEER }, { "sync", NLOG_OSYNC }, + { "sys", NLOG_OSYS }, { (char *)0, 0 } }; @@ -373,8 +438,6 @@ static struct masks logcfg_item[] = { #define MAXLINE 1024 /* maximum length of line */ #define MAXPHONE 5 /* maximum number of phone strings */ #define MAXPPS 20 /* maximum length of PPS device string */ -#define MAXFILENAME 128 /* maximum length of a file name (alloca()?) */ - /* * Miscellaneous macros @@ -439,7 +502,8 @@ static int gettokens_netinfo P((struct netinfo_config_state *, char **, int *)); static int gettokens P((FILE *, char *, char **, int *)); static int matchkey P((char *, struct keyword *)); static int getnetnum P((const char *, struct sockaddr_in *, int)); -static void save_resolve P((char *, int, int, int, int, int, int, u_long)); +static void save_resolve P((char *, int, int, int, int, int, int, + keyid_t, u_char *)); static void do_resolve_internal P((void)); static void abort_resolve P((void)); #if !defined(VMS) @@ -640,8 +704,9 @@ getconfig( int minpoll; int maxpoll; int ttl; - u_long peerkey; - u_long lpeerkey; + keyid_t peerkey; + char *peerkeystr; + keyid_t lpeerkey; int peerflags; int hmode; struct sockaddr_in peeraddr; @@ -954,6 +1019,7 @@ getconfig( minpoll = NTP_MINDPOLL; maxpoll = NTP_MAXDPOLL; peerkey = 0; + peerkeystr = "*"; peerflags = 0; ttl = 0; for (i = 2; i < ntokens; i++) @@ -1022,11 +1088,27 @@ getconfig( case CONF_MOD_BURST: peerflags |= FLAG_BURST; break; - +#ifdef AUTOKEY case CONF_MOD_SKEY: - peerflags |= FLAG_SKEY | FLAG_AUTHENABLE; + peerflags |= FLAG_SKEY | + FLAG_AUTHENABLE; break; +#ifdef PUBKEY + case CONF_MOD_PUBLICKEY: + if (i >= ntokens - 1) { + msyslog(LOG_ERR, + "Public key file name required"); + errflg = 1; + break; + } + peerflags |= FLAG_SKEY | + FLAG_AUTHENABLE; + peerkeystr = tokens[++i]; + break; +#endif /* PUBKEY */ +#endif /* AUTOKEY */ + case CONF_MOD_TTL: if (i >= ntokens-1) { msyslog(LOG_ERR, @@ -1056,19 +1138,20 @@ getconfig( errflg = 1; } if (errflg == 0) { - if (peer_config(&peeraddr, - (struct interface *)0, hmode, - peerversion, minpoll, maxpoll, - peerflags, ttl, peerkey) - == 0) { + if (peer_config(&peeraddr, + (struct interface *)0, hmode, + peerversion, minpoll, maxpoll, peerflags, + ttl, peerkey, peerkeystr) == 0) { msyslog(LOG_ERR, "configuration of %s failed", ntoa(&peeraddr)); - } + } + } else if (errflg == -1) { - save_resolve(tokens[1], hmode, peerversion, - minpoll, maxpoll, peerflags, ttl, - peerkey); + save_resolve(tokens[1], hmode, + peerversion, minpoll, maxpoll, + peerflags, ttl, peerkey, + peerkeystr); } break; @@ -1089,6 +1172,7 @@ getconfig( case CONFIG_LOGFILE: if (ntokens >= 2) { FILE *new_file; + new_file = fopen(tokens[1], "a"); if (new_file != NULL) { NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */ @@ -1199,18 +1283,57 @@ getconfig( } break; +#ifdef AUTOKEY case CONFIG_REVOKE: - if (ntokens >= 2) { - sys_revoke = 1 << max(atoi(tokens[1]), 10); - } + if (ntokens >= 2) + sys_revoke = 1 << max(atoi(tokens[1]), 10); break; case CONFIG_AUTOMAX: - if (ntokens >= 2) { - sys_automax = 1 << max(atoi(tokens[1]), 10); + if (ntokens >= 2) + sys_automax = 1 << max(atoi(tokens[1]), 10); + break; + +#ifdef PUBKEY + case CONFIG_KEYSDIR: + if (ntokens < 2) { + msyslog(LOG_ERR, + "Keys directory name required"); + break; } + crypto_config(CRYPTO_CONF_KEYS, tokens[1]); break; + case CONFIG_CRYPTO: + crypto_enable = 1; + for (i = 2; i < ntokens; i++) { + switch (matchkey(tokens[i], + crypto_keywords)) { + + case CONF_CRYPTO_FLAGS: + crypto_config(CRYPTO_CONF_FLAGS, + tokens[i++]); + + case CONF_CRYPTO_DH: + crypto_config(CRYPTO_CONF_DH, + tokens[i++]); + break; + + case CONF_CRYPTO_PRIVATEKEY: + crypto_config(CRYPTO_CONF_PRIV, + tokens[i++]); + break; + + case CONF_CRYPTO_PUBLICKEY: + crypto_config(CRYPTO_CONF_PUBL, + tokens[i++]); + break; + } + } + break; +#endif /* PUBKEY */ +#endif /* AUTOKEY */ + case CONFIG_RESTRICT: if (ntokens < 2) { msyslog(LOG_ERR, "restrict requires an address"); @@ -1310,7 +1433,7 @@ getconfig( case CONFIG_TRUSTEDKEY: for (i = 1; i < ntokens; i++) { - u_long tkey; + keyid_t tkey; tkey = atol(tokens[i]); if (tkey == 0) { @@ -1325,7 +1448,7 @@ getconfig( case CONFIG_REQUESTKEY: if (ntokens >= 2) { - u_long rkey; + keyid_t rkey; if (!atouint(tokens[1], &rkey)) { msyslog(LOG_ERR, @@ -1339,7 +1462,7 @@ getconfig( #ifdef DEBUG if (debug > 3) printf( - "set info_auth_key to %lu\n", rkey); + "set info_auth_key to %08x\n", rkey); #endif info_auth_keyid = rkey; } @@ -1348,7 +1471,7 @@ getconfig( case CONFIG_CONTROLKEY: if (ntokens >= 2) { - u_long ckey; + keyid_t ckey; ckey = atol(tokens[1]); if (ckey == 0) { @@ -1558,15 +1681,14 @@ getconfig( */ if (!errflg) { refclock_control(&peeraddr, &clock_stat, - (struct refclockstat *)0); + (struct refclockstat *)0); } #endif break; case CONFIG_STATSDIR: - if (ntokens >= 2) { + if (ntokens >= 2) stats_config(STATS_STATSDIR,tokens[1]); - } break; case CONFIG_STATISTICS: @@ -1808,6 +1930,7 @@ getconfig( */ do_resolve_internal(); } + ntp_res_send(0, 0, inet_addr("127.0.0.1"), 0); /* HMS: Testing... */ } @@ -2167,7 +2290,8 @@ save_resolve( int maxpoll, int flags, int ttl, - u_long keyid + keyid_t keyid, + u_char *keystr ) { #ifndef SYS_VXWORKS @@ -2208,8 +2332,14 @@ save_resolve( } #endif - (void) fprintf(res_fp, "%s %d %d %d %d %d %d %lu\n", name, mode, - version, minpoll, maxpoll, flags, ttl, keyid); + (void)fprintf(res_fp, "%s %d %d %d %d %d %d %08x %s\n", name, + mode, version, minpoll, maxpoll, flags, ttl, keyid, keystr); +#ifdef DEBUG + if (debug > 1) + printf("config: %s %d %d %d %d %d %d %08x %s\n", name, mode, + version, minpoll, maxpoll, flags, ttl, keyid, keystr); +#endif + #else /* SYS_VXWORKS */ /* save resolve info to a struct */ #endif /* SYS_VXWORKS */ @@ -2326,10 +2456,10 @@ do_resolve_internal(void) * async io information causes it to process requests from * all file decriptor causing a race between the NTP daemon * and the resolver. which then eats data when it wins 8-(. - * It is absolutly necessary to kill ane io associations - * shared with the NTP daemon. I currently don't want + * It is absolutly necessary to kill any IO associations + * shared with the NTP daemon. * - * we also block SIGIO (currently no portes means to + * We also block SIGIO (currently no ports means to * disable the signal handle for IO). * * Thanks to wgstuken@informatik.uni-erlangen.de to notice diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index e2fb03995f..908f005d34 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -17,6 +17,10 @@ #include "ntp_control.h" #include "ntp_stdlib.h" +#ifdef PUBKEY +#include "ntp_crypto.h" +#endif /* PUBKEY */ + /* * Structure to hold request procedure information */ @@ -26,9 +30,9 @@ #define NO_REQUEST (-1) struct ctl_proc { - short control_code; /* defined request code */ - u_short flags; /* flags word */ - void (*handler) P((struct recvbuf *, int)); /* routine to handle request */ + short control_code; /* defined request code */ + u_short flags; /* flags word */ + void (*handler) P((struct recvbuf *, int)); /* handle request */ }; /* @@ -44,9 +48,10 @@ static void ctl_error P((int)); static u_short ctlclkstatus P((struct refclockstat *)); static void ctl_flushpkt P((int)); static void ctl_putdata P((const char *, unsigned int, int)); -static void ctl_putstr P((const char *, const char *, unsigned int)); +static void ctl_putstr P((const char *, const char *, + unsigned int)); static void ctl_putdbl P((const char *, double)); -static void ctl_putuint P((const char *, u_long)); +static void ctl_putuint P((const char *, u_long)); static void ctl_puthex P((const char *, u_long)); static void ctl_putint P((const char *, long)); static void ctl_putts P((const char *, l_fp *)); @@ -54,21 +59,22 @@ static void ctl_putadr P((const char *, u_int32)); static void ctl_putid P((const char *, char *)); static void ctl_putarray P((const char *, double *, int)); static void ctl_putsys P((int)); -static void ctl_putpeer P((int, struct peer *)); +static void ctl_putpeer P((int, struct peer *)); #ifdef REFCLOCK static void ctl_putclock P((int, struct refclockstat *, int)); #endif /* REFCLOCK */ static struct ctl_var *ctl_getitem P((struct ctl_var *, char **)); -static u_long count_var P((struct ctl_var *)); +static u_long count_var P((struct ctl_var *)); static void control_unspec P((struct recvbuf *, int)); -static void read_status P((struct recvbuf *, int)); +static void read_status P((struct recvbuf *, int)); static void read_variables P((struct recvbuf *, int)); static void write_variables P((struct recvbuf *, int)); -static void read_clock_status P((struct recvbuf *, int)); -static void write_clock_status P((struct recvbuf *, int)); +static void read_clock_status P((struct recvbuf *, int)); +static void write_clock_status P((struct recvbuf *, int)); static void set_trap P((struct recvbuf *, int)); static void unset_trap P((struct recvbuf *, int)); -static struct ctl_trap *ctlfindtrap P((struct sockaddr_in *, struct interface *)); +static struct ctl_trap *ctlfindtrap P((struct sockaddr_in *, + struct interface *)); static struct ctl_proc control_codes[] = { { CTL_OP_UNSPEC, NOAUTH, control_unspec }, @@ -83,10 +89,10 @@ static struct ctl_proc control_codes[] = { }; /* - * System variable values. The array can be indexed by - * the variable index to find the textual name. + * System variable values. The array can be indexed by the variable + * index to find the textual name. */ -static struct ctl_var sys_var[] = { +static struct ctl_var sys_var[] = { { 0, PADDING, "" }, /* 0 */ { CS_LEAP, RW, "leap" }, /* 1 */ { CS_STRATUM, RO, "stratum" }, /* 2 */ @@ -106,13 +112,19 @@ static struct ctl_var sys_var[] = { { CS_SYSTEM, RO, "system" }, /* 16 */ { CS_STABIL, RO, "stability" }, /* 17 */ { CS_VARLIST, RO, "sys_var_list" }, /* 18 */ +#ifdef PUBKEY + { CS_PRIVATE, RO, "privatekey" }, /* 19 */ + { CS_PUBLIC, RO, "publickey" }, /* 20 */ + { CS_DHPARAMS, RO, "dhparams" }, /* 21 */ +#endif /* PUBKEY */ { 0, EOV, "" } }; -static struct ctl_var *ext_sys_var = (struct ctl_var *)0; +static struct ctl_var *ext_sys_var = (struct ctl_var *)0; /* - * System variables we print by default (in fuzzball order, more-or-less) + * System variables we print by default (in fuzzball order, + * more-or-less) */ static u_char def_sys_var[] = { CS_PROCESSOR, @@ -132,6 +144,11 @@ static u_char def_sys_var[] = { CS_DRIFT, CS_COMPLIANCE, CS_STABIL, +#ifdef PUBKEY + CS_PRIVATE, + CS_PUBLIC, + CS_DHPARAMS, +#endif /* PUBKEY */ 0 }; @@ -139,7 +156,7 @@ static u_char def_sys_var[] = { /* * Peer variable list */ -static struct ctl_var peer_var[] = { +static struct ctl_var peer_var[] = { { 0, PADDING, "" }, /* 0 */ { CP_CONFIG, RO, "config" }, /* 1 */ { CP_AUTHENABLE, RO, "authenable" }, /* 2 */ @@ -178,6 +195,14 @@ static struct ctl_var peer_var[] = { { CP_FLASH, RO, "flash" }, /* 35 */ { CP_DISP, PADDING,"" }, /* 36 */ { CP_VARLIST, RO, "peer_var_list" }, /* 37 */ +#ifdef PUBKEY + { CP_PUBLIC, RO, "publickey" }, /* 38 */ + { CP_SESKEY, RO, "pcookie" }, /* 39 */ + { CP_SASKEY, RO, "hcookie" }, /* 40 */ + { CP_AUTOSEQ, RO, "sequence" }, /* 41 */ + { CP_INITKEY, RO, "initkey" }, /* 42 */ + { CP_INITSEQ, RO, "initsequence" }, /* 43 */ +#endif /* PUBKEY */ { 0, EOV, "" } }; @@ -185,7 +210,7 @@ static struct ctl_var peer_var[] = { /* * Peer variables we print by default */ -static u_char def_peer_var[] = { +static u_char def_peer_var[] = { CP_SRCADR, CP_SRCPORT, CP_DSTADR, @@ -215,6 +240,9 @@ static u_char def_peer_var[] = { CP_FILTDELAY, CP_FILTOFFSET, CP_FILTERROR, +#ifdef PUBKEY + CP_PUBLIC, +#endif /* PUBKEY */ 0 }; @@ -223,7 +251,7 @@ static u_char def_peer_var[] = { /* * Clock variable list */ -static struct ctl_var clock_var[] = { +static struct ctl_var clock_var[] = { { 0, PADDING, "" }, /* 0 */ { CC_TYPE, RO, "type" }, /* 1 */ { CC_TIMECODE, RO, "timecode" }, /* 2 */ @@ -245,9 +273,9 @@ static struct ctl_var clock_var[] = { /* * Clock variables printed by default */ -static u_char def_clock_var[] = { +static u_char def_clock_var[] = { CC_DEVICE, - CC_TYPE, /* won't be output if device= known */ + CC_TYPE, /* won't be output if device = known */ CC_TIMECODE, CC_POLL, CC_NOREPLY, @@ -264,14 +292,14 @@ static u_char def_clock_var[] = { /* - * System and processor definitions. These will change for the gizmo board. + * System and processor definitions. */ #ifndef HAVE_UNAME # ifndef STR_SYSTEM -# define STR_SYSTEM "UNIX" +# define STR_SYSTEM "UNIX" # endif # ifndef STR_PROCESSOR -# define STR_PROCESSOR "unknown" +# define STR_PROCESSOR "unknown" # endif static char str_system[] = STR_SYSTEM; @@ -282,10 +310,10 @@ static struct utsname utsnamebuf; #endif /* HAVE_UNAME */ /* - * Trap structures. We only allow a few of these, and send - * a copy of each async message to each live one. Traps time - * out after an hour, it is up to the trap receipient to - * keep resetting it to avoid being timed out. + * Trap structures. We only allow a few of these, and send a copy of + * each async message to each live one. Traps time out after an hour, it + * is up to the trap receipient to keep resetting it to avoid being + * timed out. */ /* ntp_request.c */ struct ctl_trap ctl_trap[CTL_MAXTRAPS]; @@ -301,9 +329,9 @@ int num_ctl_traps; /* * List relating reference clock types to control message time sources. - * Index by the reference clock type. - * This list will only be used iff the reference clock driver doesn't - * set peer->sstclktype to something different than CTL_SST_TS_UNSPEC. + * Index by the reference clock type. This list will only be used iff + * the reference clock driver doesn't set peer->sstclktype to something + * different than CTL_SST_TS_UNSPEC. */ static u_char clocktypes[] = { CTL_SST_TS_NTP, /* REFCLK_NONE (0) */ @@ -342,7 +370,7 @@ static u_char clocktypes[] = { CTL_SST_TS_LF, /* REFCLK_DUMBCLOCK (32) */ CTL_SST_TS_LF, /* REFCLK_ULINK (33) */ CTL_SST_TS_LF, /* REFCLK_PCF (35) */ - CTL_SST_TS_LF, /* REFCLK_WWW (36) */ + CTL_SST_TS_LF, /* REFCLK_WWV (36) */ CTL_SST_TS_LF, /* REFCLK_FG (37) */ }; @@ -350,7 +378,7 @@ static u_char clocktypes[] = { /* * Keyid used for authenticating write requests. */ -u_long ctl_auth_keyid; +keyid_t ctl_auth_keyid; /* * We keep track of the last error reported by the system internally @@ -366,7 +394,7 @@ u_long ctltimereset; /* time stats reset */ u_long numctlreq; /* number of requests we've received */ u_long numctlbadpkts; /* number of bad control packets */ u_long numctlresponses; /* number of resp packets sent with data */ -u_long numctlfrags; /* number of fragments sent */ +u_long numctlfrags; /* number of fragments sent */ u_long numctlerrors; /* number of error responses sent */ u_long numctltooshort; /* number of too short input packets */ u_long numctlinputresp; /* number of responses on input */ @@ -375,11 +403,11 @@ u_long numctlinputerr; /* number of input pkts with err bit set */ u_long numctlbadoffset; /* number of input pkts with nonzero offset */ u_long numctlbadversion; /* number of input pkts with unknown version */ u_long numctldatatooshort; /* data too short for count */ -u_long numctlbadop; /* bad op code found in packet */ +u_long numctlbadop; /* bad op code found in packet */ u_long numasyncmsgs; /* number of async messages we've sent */ /* - * Response packet used by these routines. Also some state information + * Response packet used by these routines. Also some state information * so that we can handle packet formatting within a common set of * subroutines. Note we try to enter data in place whenever possible, * but the need to set the more bit correctly means we occasionally @@ -399,7 +427,7 @@ static struct interface *lcl_inter; static u_char res_authenticate; static u_char res_authokay; -static u_long res_keyid; +static keyid_t res_keyid; #define MAXDATALINELEN (72) @@ -448,10 +476,11 @@ ctl_error( printf("sending control error %d\n", errcode); #endif /* - * fill in the fields. We assume rpkt.sequence and rpkt.associd + * Fill in the fields. We assume rpkt.sequence and rpkt.associd * have already been filled in. */ - rpkt.r_m_e_op = (u_char) (CTL_RESPONSE|CTL_ERROR|(res_opcode & CTL_OP_MASK)); + rpkt.r_m_e_op = (u_char) (CTL_RESPONSE|CTL_ERROR|(res_opcode & + CTL_OP_MASK)); rpkt.status = htons((u_short) ((errcode<<8) & 0xff00)); rpkt.count = 0; @@ -461,15 +490,15 @@ ctl_error( if (res_authenticate && sys_authenticate) { int maclen; - *(u_int32 *)((u_char *)&rpkt + CTL_HEADER_LEN) - = htonl(res_keyid); + *(u_int32 *)((u_char *)&rpkt + CTL_HEADER_LEN) = + htonl(res_keyid); maclen = authencrypt(res_keyid, (u_int32 *)&rpkt, - CTL_HEADER_LEN); + CTL_HEADER_LEN); sendpkt(rmt_addr, lcl_inter, -2, (struct pkt *)&rpkt, - CTL_HEADER_LEN + maclen); + CTL_HEADER_LEN + maclen); } else { sendpkt(rmt_addr, lcl_inter, -3, (struct pkt *)&rpkt, - CTL_HEADER_LEN); + CTL_HEADER_LEN); } numctlerrors++; } @@ -492,7 +521,7 @@ process_control( int maclen; #ifdef DEBUG - if (debug > 1) + if (debug > 2) printf("in process_control()\n"); #endif @@ -509,8 +538,8 @@ process_control( * it is a response or a fragment, ignore this. */ if (rbufp->recv_length < CTL_HEADER_LEN - || pkt->r_m_e_op & (CTL_RESPONSE|CTL_MORE|CTL_ERROR) - || pkt->offset != 0) { + || pkt->r_m_e_op & (CTL_RESPONSE|CTL_MORE|CTL_ERROR) + || pkt->offset != 0) { #ifdef DEBUG if (debug) printf("invalid format in control packet\n"); @@ -539,9 +568,11 @@ process_control( } /* - * Pull enough data from the packet to make intelligent responses + * Pull enough data from the packet to make intelligent + * responses */ - rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version, MODE_CONTROL); + rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version, + MODE_CONTROL); res_opcode = pkt->r_m_e_op; rpkt.sequence = pkt->sequence; rpkt.associd = pkt->associd; @@ -559,8 +590,8 @@ process_control( dataend = &(rpkt.data[CTL_MAX_DATA_LEN]); /* - * We're set up now. Make sure we've got at least - * enough incoming data space to match the count. + * We're set up now. Make sure we've got at least enough + * incoming data space to match the count. */ req_data = rbufp->recv_length - CTL_HEADER_LEN; if (req_data < req_count || rbufp->recv_length & 0x3) { @@ -571,40 +602,43 @@ process_control( properlen = req_count + CTL_HEADER_LEN; #ifdef DEBUG - if (debug >= 2 && (rbufp->recv_length & 0x3) != 0) - printf("Packet length %d unrounded\n", rbufp->recv_length); + if (debug > 2 && (rbufp->recv_length & 0x3) != 0) + printf("Packet length %d unrounded\n", + rbufp->recv_length); #endif /* round up proper len to a 8 octet boundary */ properlen = (properlen + 7) & ~7; maclen = rbufp->recv_length - properlen; if ((rbufp->recv_length & (sizeof(u_long) - 1)) == 0 && - maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN && - sys_authenticate) { + maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN && + sys_authenticate) { res_authenticate = 1; - res_keyid = ntohl(*(u_int32 *)((u_char *)pkt + properlen)); + res_keyid = ntohl(*(u_int32 *)((u_char *)pkt + + properlen)); #ifdef DEBUG - if (debug >= 3) + if (debug > 2) printf( - "recv_len %d, properlen %d, wants auth with keyid %ld, MAC length=%d\n", - rbufp->recv_length, properlen, res_keyid, maclen); + "recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%d\n", + rbufp->recv_length, properlen, res_keyid, maclen); #endif if (!authistrusted(res_keyid)) { #ifdef DEBUG - if (debug >= 2) - printf("invalid keyid %lu\n", res_keyid); + if (debug > 2) + printf("invalid keyid %08x\n", + res_keyid); #endif } else if (authdecrypt(res_keyid, (u_int32 *)pkt, - rbufp->recv_length - maclen, maclen)) { + rbufp->recv_length - maclen, maclen)) { #ifdef DEBUG - if (debug >= 3) + if (debug > 2) printf("authenticated okay\n"); #endif res_authokay = 1; } else { #ifdef DEBUG - if (debug >= 3) + if (debug > 2) printf("authentication failed\n"); #endif res_keyid = 0; @@ -623,12 +657,12 @@ process_control( for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) { if (cc->control_code == res_opcode) { #ifdef DEBUG - if (debug >= 2) + if (debug > 2) printf("opcode %d, found command handler\n", - res_opcode); + res_opcode); #endif - if (cc->flags == AUTH && (!res_authokay - || res_keyid != ctl_auth_keyid)) { + if (cc->flags == AUTH && (!res_authokay || + res_keyid != ctl_auth_keyid)) { ctl_error(CERR_PERMISSION); return; } @@ -666,7 +700,7 @@ ctlpeerstatus( if (peer->reach != 0) status |= CTL_PST_REACH; return (u_short)CTL_PEER_STATUS(status, peer->num_events, - peer->last_event); + peer->last_event); } @@ -678,12 +712,11 @@ ctlclkstatus( struct refclockstat *this_clock ) { - return ((u_short)(this_clock->currentstatus) << 8) - | (u_short)(this_clock->lastevent); + return ((u_short)(this_clock->currentstatus) << 8) | + (u_short)(this_clock->lastevent); } - /* * ctlsysstatus - return the system status word */ @@ -700,17 +733,17 @@ ctlsysstatus(void) this_clock |= CTL_SST_TS_PPS; } else { if (sys_peer->refclktype < sizeof(clocktypes)) - this_clock = clocktypes[sys_peer->refclktype]; + this_clock = + clocktypes[sys_peer->refclktype]; if (pps_control) this_clock |= CTL_SST_TS_PPS; } } return (u_short)CTL_SYS_STATUS(sys_leap, this_clock, - ctl_sys_num_events, ctl_sys_last_event); + ctl_sys_num_events, ctl_sys_last_event); } - /* * ctl_flushpkt - write out the current packet and prepare * another if necessary. @@ -744,7 +777,8 @@ ctl_flushpkt( /* * Fill in the packet with the current info */ - rpkt.r_m_e_op = (u_char)(CTL_RESPONSE|more|(res_opcode & CTL_OP_MASK)); + rpkt.r_m_e_op = (u_char)(CTL_RESPONSE|more|(res_opcode & + CTL_OP_MASK)); rpkt.count = htons((u_short) dlen); rpkt.offset = htons( (u_short) res_offset); if (res_async) { @@ -752,12 +786,14 @@ ctl_flushpkt( for (i = 0; i < CTL_MAXTRAPS; i++) { if (ctl_trap[i].tr_flags & TRAP_INUSE) { - rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, - ctl_trap[i].tr_version, MODE_CONTROL); - rpkt.sequence = htons(ctl_trap[i].tr_sequence); + rpkt.li_vn_mode = + PKT_LI_VN_MODE(sys_leap, + ctl_trap[i].tr_version, + MODE_CONTROL); + rpkt.sequence = + htons(ctl_trap[i].tr_sequence); sendpkt(&ctl_trap[i].tr_addr, - ctl_trap[i].tr_localaddr, - -4, + ctl_trap[i].tr_localaddr, -4, (struct pkt *)&rpkt, sendlen); if (!more) ctl_trap[i].tr_sequence++; @@ -768,25 +804,25 @@ ctl_flushpkt( if (res_authenticate && sys_authenticate) { int maclen; int totlen = sendlen; - u_long keyid = htonl(res_keyid); + keyid_t keyid = htonl(res_keyid); /* - * If we are going to authenticate, then there is - * an additional requirement that the MAC begin on - * a 64 bit boundary. + * If we are going to authenticate, then there + * is an additional requirement that the MAC + * begin on a 64 bit boundary. */ while (totlen & 7) { *datapt++ = '\0'; totlen++; } memcpy(datapt, &keyid, sizeof keyid); - maclen = authencrypt(res_keyid, (u_int32 *)&rpkt, - totlen); - sendpkt(rmt_addr, lcl_inter, -5, (struct pkt *)&rpkt, - totlen + maclen); + maclen = authencrypt(res_keyid, + (u_int32 *)&rpkt, totlen); + sendpkt(rmt_addr, lcl_inter, -5, + (struct pkt *)&rpkt, totlen + maclen); } else { - sendpkt(rmt_addr, lcl_inter, -6, (struct pkt *)&rpkt, - sendlen); + sendpkt(rmt_addr, lcl_inter, -6, + (struct pkt *)&rpkt, sendlen); } if (more) numctlfrags++; @@ -803,8 +839,8 @@ ctl_flushpkt( /* - * ctl_putdata - write data into the packet, fragmenting and - * starting another if this one is full. + * ctl_putdata - write data into the packet, fragmenting and starting + * another if this one is full. */ static void ctl_putdata( @@ -822,7 +858,8 @@ ctl_putdata( if (datapt != rpkt.data) { *datapt++ = ','; datalinelen++; - if ((dlen + datalinelen + 1) >= MAXDATALINELEN) { + if ((dlen + datalinelen + 1) >= MAXDATALINELEN) + { *datapt++ = '\r'; *datapt++ = '\n'; datalinelen = 0; @@ -842,7 +879,6 @@ ctl_putdata( */ ctl_flushpkt(CTL_MORE); } - memmove((char *)datapt, dp, (unsigned)dlen); datapt += dlen; datalinelen += dlen; @@ -867,7 +903,6 @@ ctl_putstr( cq = tag; while (*cq != '\0') *cp++ = *cq++; - if (len > 0) { *cp++ = '='; *cp++ = '"'; @@ -877,7 +912,6 @@ ctl_putstr( cp += len; *cp++ = '"'; } - ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); } @@ -928,7 +962,6 @@ ctl_putuint( (void) sprintf(cp, "%lu", uval); while (*cp != '\0') cp++; - ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); } @@ -955,7 +988,6 @@ ctl_puthex( (void) sprintf(cp, "0x%lx", uval); while (*cp != '\0') cp++; - ctl_putdata(buffer,(unsigned)( cp - buffer ), 0); } @@ -982,7 +1014,6 @@ ctl_putint( (void) sprintf(cp, "%ld", ival); while (*cp != '\0') cp++; - ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); } @@ -1010,7 +1041,6 @@ ctl_putts( ts->l_uf & 0xffffffffL); while (*cp != '\0') cp++; - ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); } @@ -1037,7 +1067,6 @@ ctl_putadr( cq = numtoa(addr); while (*cq != '\0') *cp++ = *cq++; - ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); } @@ -1064,7 +1093,6 @@ ctl_putid( cq = id; while (*cq != '\0' && (cq - id) < 4) *cp++ = *cq++; - ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); } @@ -1113,143 +1141,178 @@ ctl_putsys( #ifdef HAVE_UNAME char str[50]; #endif - switch (varid) { - case CS_LEAP: + + case CS_LEAP: ctl_putuint(sys_var[CS_LEAP].text, sys_leap); break; - case CS_STRATUM: + + case CS_STRATUM: ctl_putuint(sys_var[CS_STRATUM].text, sys_stratum); break; - case CS_PRECISION: + + case CS_PRECISION: ctl_putint(sys_var[CS_PRECISION].text, sys_precision); break; - case CS_ROOTDELAY: - ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay * 1e3); + + case CS_ROOTDELAY: + ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay * + 1e3); break; - case CS_ROOTDISPERSION: + + case CS_ROOTDISPERSION: ctl_putdbl(sys_var[CS_ROOTDISPERSION].text, sys_rootdispersion * 1e3); break; - case CS_REFID: + + case CS_REFID: if (sys_stratum > 1) ctl_putadr(sys_var[CS_REFID].text, sys_refid); else - ctl_putid(sys_var[CS_REFID].text, (char *)&sys_refid); + ctl_putid(sys_var[CS_REFID].text, + (char *)&sys_refid); break; - case CS_REFTIME: + + case CS_REFTIME: ctl_putts(sys_var[CS_REFTIME].text, &sys_reftime); break; - case CS_POLL: + + case CS_POLL: ctl_putuint(sys_var[CS_POLL].text, sys_poll); break; - case CS_PEERID: + + case CS_PEERID: if (sys_peer == NULL) ctl_putuint(sys_var[CS_PEERID].text, 0); else ctl_putuint(sys_var[CS_PEERID].text, sys_peer->associd); break; - case CS_STATE: + + case CS_STATE: ctl_putuint(sys_var[CS_STATE].text, (unsigned)state); break; - case CS_OFFSET: + + case CS_OFFSET: ctl_putdbl(sys_var[CS_OFFSET].text, last_offset * 1e3); break; - case CS_DRIFT: + + case CS_DRIFT: ctl_putdbl(sys_var[CS_DRIFT].text, drift_comp * 1e6); break; - case CS_COMPLIANCE: - ctl_putdbl(sys_var[CS_COMPLIANCE].text, sys_error * 1e3); + + case CS_COMPLIANCE: + ctl_putdbl(sys_var[CS_COMPLIANCE].text, sys_error * + 1e3); break; - case CS_CLOCK: + + case CS_CLOCK: get_systime(&tmp); ctl_putts(sys_var[CS_CLOCK].text, &tmp); break; - case CS_PROCESSOR: + + case CS_PROCESSOR: #ifndef HAVE_UNAME ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor, - sizeof(str_processor) - 1); + sizeof(str_processor) - 1); #else - ctl_putstr(sys_var[CS_PROCESSOR].text, utsnamebuf.machine, - strlen(utsnamebuf.machine)); + ctl_putstr(sys_var[CS_PROCESSOR].text, + utsnamebuf.machine, strlen(utsnamebuf.machine)); #endif /* HAVE_UNAME */ break; - case CS_SYSTEM: + + case CS_SYSTEM: #ifndef HAVE_UNAME ctl_putstr(sys_var[CS_SYSTEM].text, str_system, - sizeof(str_system) - 1); + sizeof(str_system) - 1); #else (void)strcpy(str, utsnamebuf.sysname); (void)strcat(str, utsnamebuf.release); ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str)); #endif /* HAVE_UNAME */ break; - case CS_STABIL: - ctl_putdbl(sys_var[CS_STABIL].text, clock_stability * 1e6); - break; - case CS_VARLIST: - { - char buf[CTL_MAX_DATA_LEN]; - register char *s, *t, *be; - register const char *ss; - register int i; - register struct ctl_var *k; - - s = buf; - be = buf + sizeof(buf) - strlen(sys_var[CS_VARLIST].text) - 4; - if (s > be) - break; /* really long var name 8-( - Killer */ - - strcpy(s, sys_var[CS_VARLIST].text); - strcat(s, "=\""); - s += strlen(s); - t = s; - - for (k = sys_var; !(k->flags &EOV); k++) - { - if (k->flags & PADDING) + + case CS_STABIL: + ctl_putdbl(sys_var[CS_STABIL].text, clock_stability * + 1e6); + break; + + case CS_VARLIST: + { + char buf[CTL_MAX_DATA_LEN]; + register char *s, *t, *be; + register const char *ss; + register int i; + register struct ctl_var *k; + + s = buf; + be = buf + sizeof(buf) - + strlen(sys_var[CS_VARLIST].text) - 4; + if (s > be) + break; /* really long var name */ + + strcpy(s, sys_var[CS_VARLIST].text); + strcat(s, "=\""); + s += strlen(s); + t = s; + for (k = sys_var; !(k->flags &EOV); k++) { + if (k->flags & PADDING) continue; + i = strlen(k->text); + if (s+i+1 >= be) + break; - i = strlen(k->text); - if (s+i+1 >= be) - break; - if (s != t) - *s++ = ','; - strcpy(s, k->text); - s += i; - } + if (s != t) + *s++ = ','; + strcpy(s, k->text); + s += i; + } - for (k = ext_sys_var; k && !(k->flags &EOV); k++) - { - if (k->flags & PADDING) + for (k = ext_sys_var; k && !(k->flags &EOV); + k++) { + if (k->flags & PADDING) continue; - ss = k->text; - if (!ss) + ss = k->text; + if (!ss) continue; - while (*ss && *ss != '=') + while (*ss && *ss != '=') ss++; - - i = ss - k->text; - if (s+i+1 >= be) + i = ss - k->text; + if (s + i + 1 >= be) break; - if (s != t) - *s++ = ','; - strncpy(s, k->text, (unsigned)i); - s += i; - } - if (s+2 >= be) + if (s != t) + *s++ = ','; + strncpy(s, k->text, + (unsigned)i); + s += i; + } + if (s+2 >= be) break; - *s++ = '"'; - *s = '\0'; + *s++ = '"'; + *s = '\0'; - ctl_putdata(buf, (unsigned)( s - buf ), 0); - } - break; + ctl_putdata(buf, (unsigned)( s - buf ), + 0); + } + break; + +#ifdef PUBKEY + case CS_PRIVATE: + if (private_key_file != NULL) + ctl_putstr(sys_var[CS_PRIVATE].text, + private_key_file, strlen(private_key_file)); + break; + + case CS_PUBLIC: + if (public_key_file != NULL) + ctl_putstr(sys_var[CS_PUBLIC].text, + public_key_file, strlen(public_key_file)); + break; +#endif /* PUBKEY */ } } @@ -1263,187 +1326,243 @@ ctl_putpeer( struct peer *peer ) { +#ifdef PUBKEY + u_int len; +#endif /* PUBKEY */ + switch (varid) { - case CP_CONFIG: + + case CP_CONFIG: ctl_putuint(peer_var[CP_CONFIG].text, - (unsigned)((peer->flags & FLAG_CONFIG) != 0)); + (unsigned)((peer->flags & FLAG_CONFIG) != 0)); break; - case CP_AUTHENABLE: + + case CP_AUTHENABLE: ctl_putuint(peer_var[CP_AUTHENABLE].text, - (unsigned)((peer->flags & FLAG_AUTHENABLE) != 0)); + (unsigned)((peer->flags & FLAG_AUTHENABLE) != 0)); break; - case CP_AUTHENTIC: + + case CP_AUTHENTIC: ctl_putuint(peer_var[CP_AUTHENTIC].text, - (unsigned)((peer->flags & FLAG_AUTHENTIC) != 0)); + (unsigned)((peer->flags & FLAG_AUTHENTIC) != 0)); break; - case CP_SRCADR: + + case CP_SRCADR: ctl_putadr(peer_var[CP_SRCADR].text, - peer->srcadr.sin_addr.s_addr); + peer->srcadr.sin_addr.s_addr); break; - case CP_SRCPORT: + + case CP_SRCPORT: ctl_putuint(peer_var[CP_SRCPORT].text, - ntohs(peer->srcadr.sin_port)); - break; - case CP_DSTADR: - ctl_putadr(peer_var[CP_DSTADR].text, - peer->processed ? - peer->cast_flags & MDF_BCAST ? - peer->dstadr->bcast.sin_addr.s_addr: - peer->cast_flags ? - peer->dstadr->sin.sin_addr.s_addr ? - peer->dstadr->sin.sin_addr.s_addr: - peer->dstadr->bcast.sin_addr.s_addr: - 8 : 12); - break; - case CP_DSTPORT: + ntohs(peer->srcadr.sin_port)); + break; + + case CP_DSTADR: + ctl_putadr(peer_var[CP_DSTADR].text, peer->processed ? + peer->cast_flags & MDF_BCAST ? + peer->dstadr->bcast.sin_addr.s_addr: + peer->cast_flags ? + peer->dstadr->sin.sin_addr.s_addr ? + peer->dstadr->sin.sin_addr.s_addr: + peer->dstadr->bcast.sin_addr.s_addr: 8 : 12); + break; + + case CP_DSTPORT: ctl_putuint(peer_var[CP_DSTPORT].text, - (u_long)(peer->dstadr - ? ntohs(peer->dstadr->sin.sin_port) - : 0 - ) - ); + (u_long)(peer->dstadr ? + ntohs(peer->dstadr->sin.sin_port) : 0)); break; - case CP_LEAP: + + case CP_LEAP: ctl_putuint(peer_var[CP_LEAP].text, peer->leap); break; - case CP_HMODE: + + case CP_HMODE: ctl_putuint(peer_var[CP_HMODE].text, peer->hmode); break; - case CP_STRATUM: + + case CP_STRATUM: ctl_putuint(peer_var[CP_STRATUM].text, peer->stratum); break; - case CP_PPOLL: + + case CP_PPOLL: ctl_putuint(peer_var[CP_PPOLL].text, peer->ppoll); break; - case CP_HPOLL: + + case CP_HPOLL: ctl_putuint(peer_var[CP_HPOLL].text, peer->hpoll); break; - case CP_PRECISION: - ctl_putint(peer_var[CP_PRECISION].text, peer->precision); + + case CP_PRECISION: + ctl_putint(peer_var[CP_PRECISION].text, + peer->precision); break; - case CP_ROOTDELAY: - ctl_putdbl(peer_var[CP_ROOTDELAY].text, peer->rootdelay * 1e3); + + case CP_ROOTDELAY: + ctl_putdbl(peer_var[CP_ROOTDELAY].text, + peer->rootdelay * 1e3); break; - case CP_ROOTDISPERSION: + + case CP_ROOTDISPERSION: ctl_putdbl(peer_var[CP_ROOTDISPERSION].text, - peer->rootdispersion * 1e3); + peer->rootdispersion * 1e3); break; - case CP_REFID: - if (peer->stratum > 1) - { + + case CP_REFID: + if (peer->stratum > 1) { if (peer->flags & FLAG_REFCLOCK) ctl_putadr(peer_var[CP_REFID].text, - peer->srcadr.sin_addr.s_addr); + peer->srcadr.sin_addr.s_addr); else ctl_putadr(peer_var[CP_REFID].text, - peer->refid); - } - else + peer->refid); + } else { ctl_putid(peer_var[CP_REFID].text, - (char *)&peer->refid); + (char *)&peer->refid); + } break; - case CP_REFTIME: + + case CP_REFTIME: ctl_putts(peer_var[CP_REFTIME].text, &peer->reftime); break; - case CP_ORG: + + case CP_ORG: ctl_putts(peer_var[CP_ORG].text, &peer->org); break; - case CP_REC: + + case CP_REC: ctl_putts(peer_var[CP_REC].text, &peer->rec); break; - case CP_XMT: + + case CP_XMT: ctl_putts(peer_var[CP_XMT].text, &peer->xmt); break; - case CP_REACH: + + case CP_REACH: ctl_puthex(peer_var[CP_REACH].text, peer->reach); break; - case CP_FLASH: + + case CP_FLASH: ctl_puthex(peer_var[CP_FLASH].text, peer->flash); break; - case CP_VALID: + + case CP_VALID: ctl_putuint(peer_var[CP_VALID].text, peer->valid); break; - case CP_TIMER: + case CP_TIMER: ctl_putuint(peer_var[CP_TIMER].text, peer->nextdate - current_time); break; - case CP_DELAY: + + case CP_DELAY: ctl_putdbl(peer_var[CP_DELAY].text, peer->delay * 1e3); break; - case CP_OFFSET: - ctl_putdbl(peer_var[CP_OFFSET].text, peer->offset * 1e3); + + case CP_OFFSET: + ctl_putdbl(peer_var[CP_OFFSET].text, peer->offset * + 1e3); break; - case CP_JITTER: + + case CP_JITTER: ctl_putdbl(peer_var[CP_JITTER].text, SQRT(peer->variance) * 1e3); break; - case CP_DISPERSION: - ctl_putdbl(peer_var[CP_DISPERSION].text, peer->disp * 1e3); + + case CP_DISPERSION: + ctl_putdbl(peer_var[CP_DISPERSION].text, peer->disp * + 1e3); break; - case CP_KEYID: + + case CP_KEYID: ctl_putuint(peer_var[CP_KEYID].text, peer->keyid); break; - case CP_FILTDELAY: + + case CP_FILTDELAY: ctl_putarray(peer_var[CP_FILTDELAY].text, peer->filter_delay, (int)peer->filter_nextpt); break; - case CP_FILTOFFSET: + + case CP_FILTOFFSET: ctl_putarray(peer_var[CP_FILTOFFSET].text, peer->filter_offset, (int)peer->filter_nextpt); break; - case CP_FILTERROR: + + case CP_FILTERROR: ctl_putarray(peer_var[CP_FILTERROR].text, peer->filter_disp, (int)peer->filter_nextpt); break; - case CP_PMODE: + + case CP_PMODE: ctl_putuint(peer_var[CP_PMODE].text, peer->pmode); break; - case CP_RECEIVED: + + case CP_RECEIVED: ctl_putuint(peer_var[CP_RECEIVED].text, peer->received); break; - case CP_SENT: + + case CP_SENT: ctl_putuint(peer_var[CP_SENT].text, peer->sent); break; - case CP_VARLIST: - { - char buf[CTL_MAX_DATA_LEN]; - register char *s, *t, *be; - register int i; - register struct ctl_var *k; - - s = buf; - be = buf + sizeof(buf) - strlen(peer_var[CP_VARLIST].text) - 4; - if (s > be) - break; /* really long var name 8-( - Killer */ - - strcpy(s, peer_var[CP_VARLIST].text); - strcat(s, "=\""); - s += strlen(s); - t = s; - - for (k = peer_var; !(k->flags &EOV); k++) - { - if (k->flags & PADDING) + + case CP_VARLIST: + { + char buf[CTL_MAX_DATA_LEN]; + register char *s, *t, *be; + register int i; + register struct ctl_var *k; + + s = buf; + be = buf + sizeof(buf) - + strlen(peer_var[CP_VARLIST].text) - 4; + if (s > be) + break; /* really long var name */ + + strcpy(s, peer_var[CP_VARLIST].text); + strcat(s, "=\""); + s += strlen(s); + t = s; + for (k = peer_var; !(k->flags &EOV); k++) { + if (k->flags & PADDING) continue; - i = strlen(k->text); - if (s+i+1 >= be) - break; - if (s != t) - *s++ = ','; - strcpy(s, k->text); - s += i; - } + i = strlen(k->text); + if (s + i + 1 >= be) + break; - if (s+2 >= be) + if (s != t) + *s++ = ','; + strcpy(s, k->text); + s += i; + } + if (s+2 >= be) break; - *s++ = '"'; - *s = '\0'; + *s++ = '"'; + *s = '\0'; + ctl_putdata(buf, (unsigned)(s - buf), 0); + } + break; +#ifdef PUBKEY + case CP_PUBLIC: + if (peer->keystr == 0) + break; + len = strlen(peer->keystr); + ctl_putstr(peer_var[CP_PUBLIC].text, peer->keystr, len); - ctl_putdata(buf, (unsigned)(s - buf), 0); - } + case CP_SESKEY: + if (peer->pcookie != 0) + ctl_puthex(peer_var[CP_SESKEY].text, peer->pcookie); + if (peer->hcookie != 0) + ctl_puthex(peer_var[CP_SASKEY].text, peer->hcookie); + break; + + case CP_AUTOSEQ: + if (peer->keynumber == 0) break; + ctl_putint(peer_var[CP_AUTOSEQ].text, peer->recseq); + ctl_puthex(peer_var[CP_INITKEY].text, peer->finlkey); + ctl_putint(peer_var[CP_INITSEQ].text, peer->finlseq); +#endif /* PUBKEY */ } } @@ -1460,132 +1579,148 @@ ctl_putclock( ) { switch(varid) { - case CC_TYPE: + + case CC_TYPE: if (mustput || clock_stat->clockdesc == NULL || *(clock_stat->clockdesc) == '\0') { ctl_putuint(clock_var[CC_TYPE].text, clock_stat->type); } break; - case CC_TIMECODE: - ctl_putstr(clock_var[CC_TIMECODE].text, clock_stat->p_lastcode, - (unsigned)clock_stat->lencode); + case CC_TIMECODE: + ctl_putstr(clock_var[CC_TIMECODE].text, + clock_stat->p_lastcode, + (unsigned)clock_stat->lencode); break; - case CC_POLL: + + case CC_POLL: ctl_putuint(clock_var[CC_POLL].text, clock_stat->polls); break; - case CC_NOREPLY: - ctl_putuint(clock_var[CC_NOREPLY].text, clock_stat->noresponse); + + case CC_NOREPLY: + ctl_putuint(clock_var[CC_NOREPLY].text, + clock_stat->noresponse); break; - case CC_BADFORMAT: - ctl_putuint(clock_var[CC_BADFORMAT].text, clock_stat->badformat); + + case CC_BADFORMAT: + ctl_putuint(clock_var[CC_BADFORMAT].text, + clock_stat->badformat); break; - case CC_BADDATA: - ctl_putuint(clock_var[CC_BADDATA].text, clock_stat->baddata); + + case CC_BADDATA: + ctl_putuint(clock_var[CC_BADDATA].text, + clock_stat->baddata); break; - case CC_FUDGETIME1: - if (mustput || (clock_stat->haveflags & CLK_HAVETIME1)) { + + case CC_FUDGETIME1: + if (mustput || (clock_stat->haveflags & CLK_HAVETIME1)) ctl_putdbl(clock_var[CC_FUDGETIME1].text, - clock_stat->fudgetime1 * 1e3); - } + clock_stat->fudgetime1 * 1e3); break; - case CC_FUDGETIME2: - if (mustput || (clock_stat->haveflags & CLK_HAVETIME2)) { - ctl_putdbl(clock_var[CC_FUDGETIME2].text, - clock_stat->fudgetime2 * 1e3); - } + + case CC_FUDGETIME2: + if (mustput || (clock_stat->haveflags & CLK_HAVETIME2)) ctl_putdbl(clock_var[CC_FUDGETIME2].text, + clock_stat->fudgetime2 * 1e3); break; - case CC_FUDGEVAL1: + + case CC_FUDGEVAL1: if (mustput || (clock_stat->haveflags & CLK_HAVEVAL1)) ctl_putint(clock_var[CC_FUDGEVAL1].text, - clock_stat->fudgeval1); + clock_stat->fudgeval1); break; - case CC_FUDGEVAL2: + + case CC_FUDGEVAL2: if (mustput || (clock_stat->haveflags & CLK_HAVEVAL2)) { if (clock_stat->fudgeval1 > 1) - ctl_putadr(clock_var[CC_FUDGEVAL2].text, - (u_int32)clock_stat->fudgeval2); + ctl_putadr(clock_var[CC_FUDGEVAL2].text, + (u_int32)clock_stat->fudgeval2); else - ctl_putid(clock_var[CC_FUDGEVAL2].text, - (char *)&clock_stat->fudgeval2); + ctl_putid(clock_var[CC_FUDGEVAL2].text, + (char *)&clock_stat->fudgeval2); } break; - case CC_FLAGS: - if (mustput || (clock_stat->haveflags & - (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4))) - ctl_putuint(clock_var[CC_FLAGS].text, clock_stat->flags); + + case CC_FLAGS: + if (mustput || (clock_stat->haveflags & (CLK_HAVEFLAG1 | + CLK_HAVEFLAG2 | CLK_HAVEFLAG3 | CLK_HAVEFLAG4))) + ctl_putuint(clock_var[CC_FLAGS].text, + clock_stat->flags); break; - case CC_DEVICE: - if (clock_stat->clockdesc == NULL || *(clock_stat->clockdesc) == '\0') { + + case CC_DEVICE: + if (clock_stat->clockdesc == NULL || + *(clock_stat->clockdesc) == '\0') { if (mustput) - ctl_putstr(clock_var[CC_DEVICE].text, "", 0); + ctl_putstr(clock_var[CC_DEVICE].text, + "", 0); } else { - ctl_putstr(clock_var[CC_DEVICE].text, clock_stat->clockdesc, - strlen(clock_stat->clockdesc)); + ctl_putstr(clock_var[CC_DEVICE].text, + clock_stat->clockdesc, + strlen(clock_stat->clockdesc)); } break; - case CC_VARLIST: - { - char buf[CTL_MAX_DATA_LEN]; - register char *s, *t, *be; - register const char *ss; - register int i; - register struct ctl_var *k; - - s = buf; - be = buf + sizeof(buf); - if (s + strlen(clock_var[CC_VARLIST].text) + 4 > be) - break; /* really long var name 8-( - Killer */ - - strcpy(s, clock_var[CC_VARLIST].text); - strcat(s, "=\""); - s += strlen(s); - t = s; - - for (k = clock_var; !(k->flags &EOV); k++) - { - if (k->flags & PADDING) + + case CC_VARLIST: + { + char buf[CTL_MAX_DATA_LEN]; + register char *s, *t, *be; + register const char *ss; + register int i; + register struct ctl_var *k; + + s = buf; + be = buf + sizeof(buf); + if (s + strlen(clock_var[CC_VARLIST].text) + 4 > + be) + break; /* really long var name */ + + strcpy(s, clock_var[CC_VARLIST].text); + strcat(s, "=\""); + s += strlen(s); + t = s; + + for (k = clock_var; !(k->flags &EOV); k++) { + if (k->flags & PADDING) continue; - i = strlen(k->text); - if (s+i+1 >= be) + i = strlen(k->text); + if (s + i + 1 >= be) break; - if (s != t) - *s++ = ','; - strcpy(s, k->text); - s += i; - } - for (k = clock_stat->kv_list; k && !(k->flags &EOV); k++) - { - if (k->flags & PADDING) + if (s != t) + *s++ = ','; + strcpy(s, k->text); + s += i; + } + + for (k = clock_stat->kv_list; k && !(k->flags & + EOV); k++) { + if (k->flags & PADDING) continue; - ss = k->text; - if (!ss) + ss = k->text; + if (!ss) continue; - while (*ss && *ss != '=') + while (*ss && *ss != '=') ss++; - - i = ss - k->text; - if (s+i+1 >= be) + i = ss - k->text; + if (s+i+1 >= be) break; - if (s != t) - *s++ = ','; - strncpy(s, k->text, (unsigned)i); - s += i; - *s = '\0'; - } - if (s+2 >= be) - break; - - *s++ = '"'; + if (s != t) + *s++ = ','; + strncpy(s, k->text, (unsigned)i); + s += i; *s = '\0'; - - ctl_putdata(buf, (unsigned)( s - buf ), 0); } - break; + if (s+2 >= be) + break; + + *s++ = '"'; + *s = '\0'; + ctl_putdata(buf, (unsigned)( s - buf ), 0); + } + break; } } #endif @@ -1610,15 +1745,14 @@ ctl_getitem( /* * Delete leading commas and white space */ - while (reqpt < reqend && (*reqpt == ',' || isspace((int)*reqpt))) { + while (reqpt < reqend && (*reqpt == ',' || + isspace((int)*reqpt))) reqpt++; - } - if (reqpt >= reqend) - return 0; + return (0); if (var_list == (struct ctl_var *)0) - return &eol; + return (&eol); /* * Look for a first character match on the tag. If we find @@ -1629,7 +1763,8 @@ ctl_getitem( while (!(v->flags & EOV)) { if (!(v->flags & PADDING) && *cp == *(v->text)) { tp = v->text; - while (*tp != '\0' && *tp != '=' && cp < reqend && *cp == *tp) { + while (*tp != '\0' && *tp != '=' && cp < + reqend && *cp == *tp) { cp++; tp++; } @@ -1647,9 +1782,11 @@ ctl_getitem( if (*cp == '=') { cp++; tp = buf; - while (cp < reqend && isspace((int)*cp)) + while (cp < reqend && + isspace((int)*cp)) cp++; - while (cp < reqend && *cp != ',') + while (cp < reqend && *cp != + ',') *tp++ = *cp++; if (cp < reqend) cp++; @@ -1658,7 +1795,7 @@ ctl_getitem( *(--tp) = '\0'; reqpt = cp; *data = buf; - return v; + return (v); } } cp = reqpt; @@ -1701,7 +1838,7 @@ control_unspec( /* * read_status - return either a list of associd's, or a particular - * peer's status. + * peer's status. */ /*ARGSUSED*/ static void @@ -1712,14 +1849,14 @@ read_status( { register int i; register struct peer *peer; - u_short ass_stat[CTL_MAX_DATA_LEN/sizeof(u_short)]; + u_short ass_stat[CTL_MAX_DATA_LEN / sizeof(u_short)]; #ifdef DEBUG - if (debug >= 2) + if (debug > 2) printf("read_status: ID %d\n", res_associd); #endif /* - * Two choices here. If the specified association ID is + * Two choices here. If the specified association ID is * zero we return all known assocation ID's. Otherwise * we return a bunch of stuff about the particular peer. */ @@ -1730,19 +1867,22 @@ read_status( rpkt.status = htons(ctlsysstatus()); for (i = 0; i < HASH_SIZE; i++) { for (peer = assoc_hash[i]; peer != 0; - peer = peer->ass_next) { + peer = peer->ass_next) { ass_stat[n++] = htons(peer->associd); - ass_stat[n++] = htons(ctlpeerstatus(peer)); - if (n == CTL_MAX_DATA_LEN/sizeof(u_short)) { + ass_stat[n++] = + htons(ctlpeerstatus(peer)); + if (n == + CTL_MAX_DATA_LEN/sizeof(u_short)) { ctl_putdata((char *)ass_stat, - n * sizeof(u_short), 1); + n * sizeof(u_short), 1); n = 0; } } } if (n != 0) - ctl_putdata((char *)ass_stat, n * sizeof(u_short), 1); + ctl_putdata((char *)ass_stat, n * + sizeof(u_short), 1); ctl_flushpkt(0); } else { peer = findpeerbyassoc((int)res_associd); @@ -1755,8 +1895,8 @@ read_status( if (res_authokay) peer->num_events = 0; /* - * For now, output everything we know about the peer. - * May be more selective later. + * For now, output everything we know about the + * peer. May be more selective later. */ for (cp = def_peer_var; *cp != 0; cp++) ctl_putpeer((int)*cp, peer); @@ -1780,11 +1920,11 @@ read_variables( register int i; char *valuep; u_char *wants; - unsigned int gotvar = (CS_MAXCODE>CP_MAXCODE) ? (CS_MAXCODE+1) : (CP_MAXCODE+1); - + unsigned int gotvar = (CS_MAXCODE > CP_MAXCODE) ? (CS_MAXCODE + + 1) : (CP_MAXCODE + 1); if (res_associd == 0) { /* - * Wants system variables. Figure out which he wants + * Wants system variables. Figure out which he wants * and give them to him. */ rpkt.status = htons(ctlsysstatus()); @@ -1796,13 +1936,15 @@ read_variables( gotvar = 0; while ((v = ctl_getitem(sys_var, &valuep)) != 0) { if (v->flags & EOV) { - if ((v = ctl_getitem(ext_sys_var, &valuep)) != 0) { + if ((v = ctl_getitem(ext_sys_var, + &valuep)) != 0) { if (v->flags & EOV) { ctl_error(CERR_UNKNOWNVAR); free((char *)wants); return; } - wants[CS_MAXCODE+1+v->code] = 1; + wants[CS_MAXCODE + 1 + + v->code] = 1; gotvar = 1; continue; } else { @@ -1815,27 +1957,31 @@ read_variables( if (gotvar) { for (i = 1; i <= CS_MAXCODE; i++) if (wants[i]) - ctl_putsys(i); - for (i = 0; ext_sys_var && !(ext_sys_var[i].flags & EOV); i++) - if (wants[i+CS_MAXCODE+1]) - ctl_putdata(ext_sys_var[i].text, - strlen(ext_sys_var[i].text), 0); + ctl_putsys(i); + for (i = 0; ext_sys_var && + !(ext_sys_var[i].flags & EOV); i++) + if (wants[i + CS_MAXCODE + 1]) + ctl_putdata(ext_sys_var[i].text, + strlen(ext_sys_var[i].text), + 0); } else { register u_char *cs; register struct ctl_var *kv; for (cs = def_sys_var; *cs != 0; cs++) ctl_putsys((int)*cs); - for (kv = ext_sys_var; kv && !(kv->flags & EOV); kv++) + for (kv = ext_sys_var; kv && !(kv->flags & EOV); + kv++) if (kv->flags & DEF) - ctl_putdata(kv->text, strlen(kv->text), 0); + ctl_putdata(kv->text, + strlen(kv->text), 0); } free((char *)wants); } else { register struct peer *peer; /* - * Wants info for a particular peer. See if we know + * Wants info for a particular peer. See if we know * the guy. */ peer = findpeerbyassoc((int)res_associd); @@ -1843,7 +1989,6 @@ read_variables( ctl_error(CERR_BADASSOC); return; } - rpkt.status = htons(ctlpeerstatus(peer)); if (res_authokay) peer->num_events = 0; @@ -1862,7 +2007,7 @@ read_variables( if (gotvar) { for (i = 1; i <= CP_MAXCODE; i++) if (wants[i]) - ctl_putpeer(i, peer); + ctl_putpeer(i, peer); } else { register u_char *cp; @@ -1876,8 +2021,8 @@ read_variables( /* - * write_variables - write into variables. We only allow leap bit writing - * this way. + * write_variables - write into variables. We only allow leap bit + * writing this way. */ /*ARGSUSED*/ static void @@ -1890,7 +2035,6 @@ write_variables( register int ext_var; char *valuep; long val; - /*int leapind, leapwarn;*/ /* * If he's trying to write into a peer tell him no way @@ -1906,20 +2050,14 @@ write_variables( rpkt.status = htons(ctlsysstatus()); /* - * Set flags to not-in-sync so we can tell when we get something. - */ - /* - leapind = ~0; - leapwarn = ~0; - */ - - /* - * Look through the variables. Dump out at the first sign of trouble. + * Look through the variables. Dump out at the first sign of + * trouble. */ while ((v = ctl_getitem(sys_var, &valuep)) != 0) { ext_var = 0; if (v->flags & EOV) { - if ((v = ctl_getitem(ext_sys_var, &valuep)) != 0) { + if ((v = ctl_getitem(ext_sys_var, &valuep)) != + 0) { if (v->flags & EOV) { ctl_error(CERR_UNKNOWNVAR); return; @@ -1933,7 +2071,8 @@ write_variables( ctl_error(CERR_PERMISSION); return; } - if (!ext_var && (*valuep == '\0' || !atoint(valuep, &val))) { + if (!ext_var && (*valuep == '\0' || !atoint(valuep, + &val))) { ctl_error(CERR_BADFMT); return; } @@ -1943,7 +2082,8 @@ write_variables( } if (ext_var) { - char *s = (char *)emalloc(strlen(v->text)+strlen(valuep)+2); + char *s = (char *)emalloc(strlen(v->text) + + strlen(valuep) + 2); const char *t; char *tt = s; @@ -1953,24 +2093,24 @@ write_variables( *tt++ = '='; strcat(tt, valuep); - set_sys_var(s, strlen(s)+1, v->flags); free(s); } else { /* - * This one seems sane. Save it. + * This one seems sane. Save it. */ switch(v->code) { - case CS_LEAP: - default: - ctl_error(CERR_UNSPEC); /* our fault, really */ + + case CS_LEAP: + default: + ctl_error(CERR_UNSPEC); /* really */ return; } } } /* - * If we got anything, do it. + * If we got anything, do it. xxx nothing to do *** */ /* if (leapind != ~0 || leapwarn != ~0) { @@ -2009,18 +2149,20 @@ read_clock_status( struct refclockstat clock_stat; if (res_associd == 0) { + /* * Find a clock for this jerk. If the system peer * is a clock use it, else search the hash tables * for one. */ - if (sys_peer != 0 && (sys_peer->flags & FLAG_REFCLOCK)) { + if (sys_peer != 0 && (sys_peer->flags & FLAG_REFCLOCK)) + { peer = sys_peer; } else { peer = 0; for (i = 0; peer == 0 && i < HASH_SIZE; i++) { for (peer = assoc_hash[i]; peer != 0; - peer = peer->ass_next) { + peer = peer->ass_next) { if (peer->flags & FLAG_REFCLOCK) break; } @@ -2039,30 +2181,32 @@ read_clock_status( } /* - * If we got here we have a peer which is a clock. Get his status. + * If we got here we have a peer which is a clock. Get his + * status. */ clock_stat.kv_list = (struct ctl_var *)0; - - refclock_control(&peer->srcadr, (struct refclockstat *)0, &clock_stat); + refclock_control(&peer->srcadr, (struct refclockstat *)0, + &clock_stat); /* * Look for variables in the packet. */ rpkt.status = htons(ctlclkstatus(&clock_stat)); - gotvar = CC_MAXCODE+1+count_var(clock_stat.kv_list); + gotvar = CC_MAXCODE + 1 + count_var(clock_stat.kv_list); wants = (u_char *)emalloc(gotvar); memset((char*)wants, 0, gotvar); gotvar = 0; while ((v = ctl_getitem(clock_var, &valuep)) != 0) { if (v->flags & EOV) { - if ((v = ctl_getitem(clock_stat.kv_list, &valuep)) != 0) { + if ((v = ctl_getitem(clock_stat.kv_list, + &valuep)) != 0) { if (v->flags & EOV) { ctl_error(CERR_UNKNOWNVAR); free((char*)wants); free_varlist(clock_stat.kv_list); return; } - wants[CC_MAXCODE+1+v->code] = 1; + wants[CC_MAXCODE + 1 + v->code] = 1; gotvar = 1; continue; } else { @@ -2077,19 +2221,23 @@ read_clock_status( for (i = 1; i <= CC_MAXCODE; i++) if (wants[i]) ctl_putclock(i, &clock_stat, 1); - for (i = 0; clock_stat.kv_list && !(clock_stat.kv_list[i].flags & EOV); i++) - if (wants[i+CC_MAXCODE+1]) - ctl_putdata(clock_stat.kv_list[i].text, - strlen(clock_stat.kv_list[i].text), 0); + for (i = 0; clock_stat.kv_list && + !(clock_stat.kv_list[i].flags & EOV); i++) + if (wants[i + CC_MAXCODE + 1]) + ctl_putdata(clock_stat.kv_list[i].text, + strlen(clock_stat.kv_list[i].text), + 0); } else { register u_char *cc; register struct ctl_var *kv; for (cc = def_clock_var; *cc != 0; cc++) ctl_putclock((int)*cc, &clock_stat, 0); - for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV); kv++) + for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV); + kv++) if (kv->flags & DEF) - ctl_putdata(kv->text, strlen(kv->text), 0); + ctl_putdata(kv->text, strlen(kv->text), + 0); } free((char*)wants); @@ -2114,11 +2262,10 @@ write_clock_status( } /* - * Trap support from here on down. We send async trap messages when the - * upper levels report trouble. Traps can by set either by control + * Trap support from here on down. We send async trap messages when the + * upper levels report trouble. Traps can by set either by control * messages or by configuration. */ - /* * set_trap - set a trap in response to a control message */ @@ -2150,7 +2297,7 @@ set_trap( * an error if it can't assign the trap. */ if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype, - (int)res_version)) + (int)res_version)) ctl_error(CERR_NORESOURCE); ctl_flushpkt(0); } @@ -2168,11 +2315,10 @@ unset_trap( int traptype; /* - * We don't prevent anyone from removing his own - * trap unless the trap is configured. Note we also - * must be aware of the possibility that restriction - * flags were changed since this guy last set his trap. - * Set the trap type based on this. + * We don't prevent anyone from removing his own trap unless the + * trap is configured. Note we also must be aware of the + * possibility that restriction flags were changed since this + * guy last set his trap. Set the trap type based on this. */ traptype = TRAP_TYPE_PRIO; if (restrict_mask & RES_LPTRAP) @@ -2207,69 +2353,77 @@ ctlsettrap( */ if ((tp = ctlfindtrap(raddr, linter)) != NULL) { switch (traptype) { - case TRAP_TYPE_CONFIG: + + case TRAP_TYPE_CONFIG: tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED; break; - case TRAP_TYPE_PRIO: + + case TRAP_TYPE_PRIO: if (tp->tr_flags & TRAP_CONFIGURED) - return 1; /* don't change anything */ + return (1); /* don't change anything */ tp->tr_flags = TRAP_INUSE; break; - case TRAP_TYPE_NONPRIO: + + case TRAP_TYPE_NONPRIO: if (tp->tr_flags & TRAP_CONFIGURED) - return 1; /* don't change anything */ + return (1); /* don't change anything */ tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO; break; } tp->tr_settime = current_time; tp->tr_resets++; - return 1; + return (1); } /* * First we heard of this guy. Try to find a trap structure * for him to use, clearing out lesser priority guys if we - * have to. Clear out anyone who's expired while we're at it. + * have to. Clear out anyone who's expired while we're at it. */ tptouse = NULL; for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) { if ((tp->tr_flags & TRAP_INUSE) && - !(tp->tr_flags & TRAP_CONFIGURED) && - ((tp->tr_settime + CTL_TRAPTIME) > current_time)) { + !(tp->tr_flags & TRAP_CONFIGURED) && + ((tp->tr_settime + CTL_TRAPTIME) > current_time)) { tp->tr_flags = 0; num_ctl_traps--; } - if (!(tp->tr_flags & TRAP_INUSE)) { tptouse = tp; } else if (!(tp->tr_flags & TRAP_CONFIGURED)) { switch (traptype) { - case TRAP_TYPE_CONFIG: + + case TRAP_TYPE_CONFIG: if (tptouse == NULL) { tptouse = tp; break; } - if (tptouse->tr_flags & TRAP_NONPRIO - && !(tp->tr_flags & TRAP_NONPRIO)) + if (tptouse->tr_flags & TRAP_NONPRIO && + !(tp->tr_flags & TRAP_NONPRIO)) break; + if (!(tptouse->tr_flags & TRAP_NONPRIO) - && tp->tr_flags & TRAP_NONPRIO) { + && tp->tr_flags & TRAP_NONPRIO) { tptouse = tp; break; } - if (tptouse->tr_origtime < tp->tr_origtime) + if (tptouse->tr_origtime < + tp->tr_origtime) tptouse = tp; break; - case TRAP_TYPE_PRIO: + + case TRAP_TYPE_PRIO: if (tp->tr_flags & TRAP_NONPRIO) { if (tptouse == NULL || - (tptouse->tr_flags & TRAP_INUSE - && tptouse->tr_origtime - < tp->tr_origtime)) + (tptouse->tr_flags & + TRAP_INUSE && + tptouse->tr_origtime < + tp->tr_origtime)) tptouse = tp; } break; - case TRAP_TYPE_NONPRIO: + + case TRAP_TYPE_NONPRIO: break; } } @@ -2279,7 +2433,7 @@ ctlsettrap( * If we don't have room for him return an error. */ if (tptouse == NULL) - return 0; + return (0); /* * Set up this structure for him. @@ -2290,19 +2444,18 @@ ctlsettrap( tptouse->tr_addr = *raddr; tptouse->tr_localaddr = linter; tptouse->tr_version = version; - tptouse->tr_flags = TRAP_INUSE; if (traptype == TRAP_TYPE_CONFIG) tptouse->tr_flags |= TRAP_CONFIGURED; else if (traptype == TRAP_TYPE_NONPRIO) tptouse->tr_flags |= TRAP_NONPRIO; num_ctl_traps++; - return 1; + return (1); } /* - * ctlclrtrap - called to clr a trap + * ctlclrtrap - called to clear a trap */ int ctlclrtrap( @@ -2314,15 +2467,15 @@ ctlclrtrap( register struct ctl_trap *tp; if ((tp = ctlfindtrap(raddr, linter)) == NULL) - return 0; + return (0); if (tp->tr_flags & TRAP_CONFIGURED && traptype != TRAP_TYPE_CONFIG) - return 0; + return (0); tp->tr_flags = 0; num_ctl_traps--; - return 1; + return (1); } @@ -2338,11 +2491,11 @@ ctlfindtrap( register struct ctl_trap *tp; for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) { - if (tp->tr_flags & TRAP_INUSE - && NSRCADR(raddr) == NSRCADR(&tp->tr_addr) - && NSRCPORT(raddr) == NSRCPORT(&tp->tr_addr) - && linter == tp->tr_localaddr) - return tp; + if (tp->tr_flags & TRAP_INUSE && NSRCADR(raddr) == + NSRCADR(&tp->tr_addr) && NSRCPORT(raddr) == + NSRCPORT(&tp->tr_addr) && linter == + tp->tr_localaddr) + return (tp); } return (struct ctl_trap *)NULL; } @@ -2368,14 +2521,15 @@ report_event( ctl_sys_num_events++; if (ctl_sys_last_event != (u_char)err) { NLOG(NLOG_SYSEVENT) - msyslog(LOG_INFO, "system event '%s' (0x%02x) status '%s' (0x%02x)", - eventstr(err), err, - sysstatstr(ctlsysstatus()), ctlsysstatus()); + msyslog(LOG_INFO, "system event '%s' (0x%02x) status '%s' (0x%02x)", + eventstr(err), err, + sysstatstr(ctlsysstatus()), ctlsysstatus()); #ifdef DEBUG if (debug) printf("report_event: system event '%s' (0x%02x) status '%s' (0x%02x)\n", - eventstr(err), err, - sysstatstr(ctlsysstatus()), ctlsysstatus()); + eventstr(err), err, + sysstatstr(ctlsysstatus()), + ctlsysstatus()); #endif ctl_sys_last_event = (u_char)err; } @@ -2393,19 +2547,25 @@ report_event( if (peer->num_events < CTL_PEER_MAXEVENTS) peer->num_events++; NLOG(NLOG_PEEREVENT) - msyslog(LOG_INFO, "peer %s event '%s' (0x%02x) status '%s' (0x%02x)", - src, eventstr(err), err, - peerstatstr(ctlpeerstatus(peer)), ctlpeerstatus(peer)); + msyslog(LOG_INFO, "peer %s event '%s' (0x%02x) status '%s' (0x%02x)", + src, eventstr(err), err, + peerstatstr(ctlpeerstatus(peer)), + ctlpeerstatus(peer)); #ifdef DEBUG if (debug) printf( "peer %s event '%s' (0x%02x) status '%s' (0x%02x)\n", - src, eventstr(err), err, - peerstatstr(ctlpeerstatus(peer)), ctlpeerstatus(peer)); + src, eventstr(err), err, + peerstatstr(ctlpeerstatus(peer)), + ctlpeerstatus(peer)); #endif } else { - msyslog(LOG_ERR, "report_event: err '%s' (0x%02x), no peer", eventstr(err), err); + msyslog(LOG_ERR, + "report_event: err '%s' (0x%02x), no peer", + eventstr(err), err); #ifdef DEBUG - printf("report_event: peer event '%s' (0x%02x), no peer\n", eventstr(err), err); + printf( + "report_event: peer event '%s' (0x%02x), no peer\n", + eventstr(err), err); #endif return; } @@ -2425,38 +2585,42 @@ report_event( res_authenticate = 0; datapt = rpkt.data; dataend = &(rpkt.data[CTL_MAX_DATA_LEN]); - if (!(err & PEER_EVENT)) { rpkt.associd = 0; rpkt.status = htons(ctlsysstatus()); /* * For now, put everything we know about system - * variables. Maybe more selective later + * variables. Don't send crypto strings. */ - for (i = 1; i <= CS_MAXCODE; i++) + for (i = 1; i <= CS_MAXCODE; i++) { +#ifdef PUBKEY + if (i > CS_VARLIST) + continue; +#endif /* PUBKEY */ ctl_putsys(i); + } #ifdef REFCLOCK /* - * for clock exception events: - * add clock variables to reflect info on exception + * for clock exception events: add clock variables to + * reflect info on exception */ if (err == EVNT_CLOCKEXCPT) { struct refclockstat clock_stat; struct ctl_var *kv; clock_stat.kv_list = (struct ctl_var *)0; - refclock_control(&peer->srcadr, - (struct refclockstat *)0, &clock_stat); - ctl_puthex("refclockstatus", ctlclkstatus(&clock_stat)); - + (struct refclockstat *)0, &clock_stat); + ctl_puthex("refclockstatus", + ctlclkstatus(&clock_stat)); for (i = 1; i <= CC_MAXCODE; i++) ctl_putclock(i, &clock_stat, 0); - for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV); kv++) + for (kv = clock_stat.kv_list; kv && + !(kv->flags & EOV); kv++) if (kv->flags & DEF) - ctl_putdata(kv->text, strlen(kv->text), 0); - + ctl_putdata(kv->text, + strlen(kv->text), 0); free_varlist(clock_stat.kv_list); } #endif /*REFCLOCK*/ @@ -2465,34 +2629,37 @@ report_event( rpkt.status = htons(ctlpeerstatus(peer)); /* - * Dump it all. Later, maybe less. + * Dump it all. Later, maybe less. */ for (i = 1; i <= CP_MAXCODE; i++) +#ifdef PUBKEY + if (i > CP_VARLIST) + continue; +#endif /* PUBKEY */ ctl_putpeer(i, peer); #ifdef REFCLOCK /* - * for clock exception events: - * add clock variables to reflect info on exception + * for clock exception events: add clock variables to + * reflect info on exception */ if (err == EVNT_PEERCLOCK) { struct refclockstat clock_stat; struct ctl_var *kv; clock_stat.kv_list = (struct ctl_var *)0; - refclock_control(&peer->srcadr, - (struct refclockstat *)0, - &clock_stat); + (struct refclockstat *)0, &clock_stat); ctl_puthex("refclockstatus", - ctlclkstatus(&clock_stat)); + ctlclkstatus(&clock_stat)); for (i = 1; i <= CC_MAXCODE; i++) ctl_putclock(i, &clock_stat, 0); - for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV); kv++) + for (kv = clock_stat.kv_list; kv && + !(kv->flags & EOV); kv++) if (kv->flags & DEF) - ctl_putdata(kv->text, strlen(kv->text), 0); - + ctl_putdata(kv->text, + strlen(kv->text), 0); free_varlist(clock_stat.kv_list); } #endif /*REFCLOCK*/ @@ -2537,14 +2704,12 @@ count_var( register u_long c; if (!k) - return 0; + return (0); c = 0; - while (!(k++->flags & EOV)) - c++; - - return c; + c++; + return (c); } char * @@ -2561,12 +2726,11 @@ add_var( k = *kv; *kv = (struct ctl_var *)emalloc((c+2)*sizeof(struct ctl_var)); - if (k) - { - memmove((char *)*kv, (char *)k, sizeof(struct ctl_var)*c); + if (k) { + memmove((char *)*kv, (char *)k, + sizeof(struct ctl_var)*c); free((char *)k); } - (*kv)[c].code = (u_short) c; (*kv)[c].text = (char *)emalloc(size); (*kv)[c].flags = def; @@ -2592,21 +2756,16 @@ set_var( if (!data || !size) return; - if ((k = *kv)) - { - while (!(k->flags & EOV)) - { + if ((k = *kv)) { + while (!(k->flags & EOV)) { s = data; t = k->text; - if (t) - { - while (*t != '=' && *s - *t == 0) - { + if (t) { + while (*t != '=' && *s - *t == 0) { s++; t++; } - if (*s == *t && ((*t == '=') || !*t)) - { + if (*s == *t && ((*t == '=') || !*t)) { free((void *)k->text); td = (char *)emalloc(size); memmove(td, data, size); @@ -2614,9 +2773,7 @@ set_var( k->flags = def; return; } - } - else - { + } else { td = (char *)emalloc(size); memmove(td, data, size); k->text = td; @@ -2646,10 +2803,9 @@ free_varlist( ) { struct ctl_var *k; - if (kv) - { + if (kv) { for (k = kv; !(k->flags & EOV); k++) - free((void *)k->text); + free((void *)k->text); free((void *)kv); } } diff --git a/ntpd/ntp_crypto.c b/ntpd/ntp_crypto.c new file mode 100644 index 0000000000..cc72171aee --- /dev/null +++ b/ntpd/ntp_crypto.c @@ -0,0 +1,1053 @@ +/* + * ntp_crypto.c - NTP version 4 public key routines + */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef AUTOKEY +#include +#include +#include +#include + +#include "ntpd.h" +#include "ntp_stdlib.h" +#include "ntp_string.h" +#include "ntp_crypto.h" + +/* + * Extension field message formats + * + * +-------+-------+ +-------+-------+ +-------+-------+ + * 0 | 3 | len | | 4 | len | | 1/5 | len | + * +-------+-------+ +-------+-------+ +-------+-------+ + * 1 | assoc ID | | assoc ID | | assoc ID | + * +---------------+ +---------------+ +---------------+ + * 2 | current seq | | peer cookie | | value len | + * +---------------+ +---------------+ +---------------+ + * 3 | final seq | | signature len | | | + * +---------------+ +---------------+ = value = + * 4 | final key | | | | | + * +---------------+ = signature = +---------------+ + * 5 | signature len | | | CRYPTO_PUBL rsp + * +---------------+ +---------------+ CRYPTO_DH cmd + * 6 | | CRYPTO_PRIV rsp CRYPTO_DH rsp + * = signature = + * | | Other commands and responses have only the + * +---------------+ first three words plus one word of padding. + * CRYPTO_AUTO rsp + * + * CRYPTO_PUBL 1 request/respond for public key + * CRYPTO_ASSOC 2 request/respond association ID + * CRYPTO_AUTO 3 request/respond autokey values + * CRYPTO_PRIV 4 request/respond cookie + * CRYPTO_DH 5 send public value/receive signature + * + * Note: commands carry the association ID of the receiver; responses + * carry the association ID of the sender. + */ + +#ifdef PUBKEY +/* + * Cryptodefines + */ +#define MAX_KEYLEN 1024 /* maximum key length */ + +/* + * Cryptodata + */ +static R_DH_PARAMS dh_params; /* Diffie-Hellman parameters */ +static u_int dh_keyLen; /* Diffie-Hellman key length */ +static u_char *dh_public; /* Diffie-Hellman public value */ +static u_char *dh_private; /* Diffie-Hellman private value */ +static R_RSA_PRIVATE_KEY private_key; /* RSA private key */ +static R_RSA_PUBLIC_KEY public_key; /* RSA public key */ + +int crypto_enable; /* master switch */ +int crypto_flags; /* flags that wave cryptically */ +char *private_key_file = "ntpkey"; /* private key file */ +char *public_key_file = NULL; /* public key file */ +char *dh_params_file = "ntpkey_dh"; /* D-H parameters file */ +char *keysdir = "/usr/local/etc/"; /* crypto keys directory */ + +/* + * Cryptotypes + */ +static int crypto_read P((u_char *, u_char *, u_int)); +static void crypto_line P((FILE *, u_char **, u_int *)); +#endif /* PUBKEY */ + +/* + * session_key - generate session key + * + * This routine generates a session key from the source address, + * destination address, key ID and private value. The value of the + * session key is the MD5 hash of these values, while the next key ID is + * the first four octets of the hash. + */ +keyid_t /* returns next key ID */ +session_key( + struct sockaddr_in *srcadr, /* source address */ + struct sockaddr_in *dstadr, /* destination address */ + keyid_t keyno, /* key ID */ + keyid_t private, /* private value */ + u_long lifetime /* key lifetime */ + ) +{ + MD5_CTX ctx; /* MD5 context */ + keyid_t keyid; /* key identifer */ + u_int32 header[4]; /* data in network byte order */ + u_char digest[16]; /* message digest */ + + /* + * Generate the session key and key ID. If the lifetime is + * greater than zero, install the key and call it trusted. + */ + header[0] = srcadr->sin_addr.s_addr; + header[1] = dstadr->sin_addr.s_addr; + header[2] = htonl(keyno); + header[3] = htonl(private); + MD5Init(&ctx); + MD5Update(&ctx, (u_char *)header, sizeof(header)); + MD5Final(digest, &ctx); + memcpy(&keyid, digest, 4); + keyid = ntohl(keyid); + if (lifetime != 0) { + MD5auth_setkey(keyno, digest, 16); + authtrust(keyno, lifetime); + } +#ifdef DEBUG + if (debug > 1) + printf( + "session_key: %s > %s %08x %08x hash %08x life %lu\n", + numtoa(header[0]), numtoa(header[1]), keyno, + private, keyid, lifetime); +#endif + return (keyid); +} + + +/* + * make_keylist - generate key list + * + * This routine constructs a pseudo-random sequence by repeatedly + * hashing the session key starting from a given source address, + * destination address, private value and the next key ID of the + * preceeding session key. The last entry on the list is saved along + * with its sequence number and public signature. + */ +void +make_keylist( + struct peer *peer /* peer structure pointer */ + ) +{ + keyid_t keyid; /* next key ID */ + keyid_t cookie; /* private value */ + u_long ltemp; + int i, n; +#ifdef PUBKEY + R_SIGNATURE_CTX ctx; /* signature context */ + int rval; /* return value */ + u_int32 xpkt[2]; /* data in network byte order */ +#endif /* PUBKEY */ + + /* + * Allocate the key list if necessary. + */ + if (peer->keylist == 0) + peer->keylist = (keyid_t *)emalloc(sizeof(keyid_t) * + NTP_MAXSESSION); + + /* + * Generate an initial key ID which is unique and greater than + * NTP_MAXKEY. + */ + while (1) { + keyid = (u_long)RANDOM & 0xffffffff; + if (keyid <= NTP_MAXKEY) + continue; + if (authhavekey(keyid)) + continue; + break; + } + + /* + * Generate up to NTP_MAXSESSION session keys. Stop if the + * next one would not be unique or not a session key ID or if + * it would expire before the next poll. The private value + * included in the hash is zero if broadcast mode, the peer + * cookie if client mode or the host cookie if symmetric modes. + */ + ltemp = sys_automax; + peer->hcookie = session_key(&peer->dstadr->sin, &peer->srcadr, + 0, sys_private, 0); + n = NTP_MINSESSION; + if (peer->hmode == MODE_BROADCAST) { + cookie = 0; + n = NTP_MAXSESSION; + } else if (peer->hmode == MODE_SERVER) { + cookie = peer->hcookie; + } else { + cookie = peer->pcookie; + } + for (i = 0; i < n; i++) { + peer->keylist[i] = keyid; + peer->keynumber = i; + keyid = session_key(&peer->dstadr->sin, (peer->hmode == + MODE_BROADCAST) ? &peer->dstadr->bcast : + &peer->srcadr, keyid, cookie, ltemp); + ltemp -= 1 << peer->hpoll; + if (auth_havekey(keyid) || keyid <= NTP_MAXKEY || + ltemp <= (1 << (peer->hpoll + 1))) + break; + } + + /* + * Save the last session key ID and sequence number, then sign + * these values for later retrieval by the clients. Be careful + * not to use invalid key media. + */ + peer->lastseq = peer->keynumber; + peer->lastkey = keyid; +#if DEBUG + if (debug) + printf("make_keys: %d %08x\n", peer->lastseq, + peer->lastkey); +#endif +#ifdef PUBKEY + if (private_key.bits < MIN_RSA_MODULUS_BITS || + private_key.bits > MAX_RSA_MODULUS_BITS) { + rval = -1; + } else { + if (peer->sign == NULL) + peer->sign = emalloc(MAX_SIGNATURE_LEN); + xpkt[0] = htonl(peer->lastseq); + xpkt[1] = htonl(peer->lastkey); + R_SignInit(&ctx, DA_MD5); + R_SignUpdate(&ctx, (u_char *)xpkt, 8); + rval = R_SignFinal(&ctx, peer->sign, &peer->signlen, + &private_key); + } + if (rval != 0) + msyslog(LOG_ERR, "make_keylist: signature fails %x", + rval); +#endif /* PUBKEY */ +} + + +/* + * crypto_recv - parse extension fields + * + * This routine is called when the packet has been matched to an + * association and passed sanity, format and authentication checks. + */ +void +crypto_recv( + struct peer *peer, /* peer structure pointer */ + struct recvbuf *rbufp /* packet buffer pointer */ + ) +{ + u_int32 *pkt; /* packet pointer */ + int has_mac; /* length of MAC field */ + int authlen; /* offset of MAC field */ + int len; /* extension field length */ + u_int code; /* extension field opcode */ + int i; + u_int temp; +#ifdef PUBKEY + R_SIGNATURE_CTX ctx; /* signature context */ + u_int modulus; /* modulus length */ + int rval; /* return value */ +#endif /* PUBKEY */ + + /* + * Initialize. Note that the packet has already been checked for + * valid format and extension field lengths. + */ + pkt = (u_int32 *)&rbufp->recv_pkt; + authlen = LEN_PKT_NOMAC; + while ((has_mac = rbufp->recv_length - authlen) > MAX_MAC_LEN) { + i = authlen / 4; + len = ntohl(pkt[i]) & 0xffff; + code = (ntohl(pkt[i]) >> 16) & 0xffff; + if (code & CRYPTO_RESP) + peer->assoc = ntohl(pkt[i + 1]); +#ifdef DEBUG + if (debug) + printf( + "crypto_recv: ext field offset %d length %d code %x assoc ID %d\n", + authlen, len, code, (u_int32)ntohl(pkt[i + + 1])); +#endif + switch (code) { + + /* + * Exchange association IDs. This is used in multicast + * server mode and is a NOP here. + */ + case CRYPTO_ASSOC | CRYPTO_RESP: + break; + + /* + * Install autokey values. We believe the values only if + * the public key is valid and the signature has valid + * length and is verified. This is used in multicast + * client and symmetric modes. + */ + case CRYPTO_AUTO | CRYPTO_RESP: + peer->recseq = ntohl(pkt[i + 2]); +#ifdef PUBKEY + temp = ntohl(pkt[i + 5]); + if (temp == 0 || peer->pubkey == NULL) { + rval = -1; + } else { + R_VerifyInit(&ctx, DA_MD5); + R_VerifyUpdate(&ctx, (char *)&pkt[i + + 3], 8); + rval = R_VerifyFinal(&ctx, + (char *)&pkt[i + 6], temp, + (R_RSA_PUBLIC_KEY *)peer->pubkey); + } +#ifdef DEBUG + if (debug) + printf( + "crypto_recv: verify %x autokey %d %08x\n", + rval, (u_int32)ntohl(pkt[i + 3]), + (u_int32)ntohl(pkt[i + 4])); +#endif + if (rval != 0) { + peer->flags &= ~FLAG_AUTOKEY; + break; + } + peer->flags |= FLAG_AUTOKEY; +#endif /* PUBKEY */ + peer->flash &= ~TEST10; + peer->finlseq = ntohl(pkt[i + 3]); + peer->finlkey = peer->pkeyid = ntohl(pkt[i + + 4]); + break; + + /* + * Install session cookie. We believe the value only if + * the public key is valid and the signature has valid + * length and is verified. This is used in client mode. + */ + case CRYPTO_PRIV | CRYPTO_RESP: +#ifdef PUBKEY + temp = ntohl(pkt[i + 3]); + if (temp == 0 || peer->pubkey == NULL) { + rval = -1; + temp = 0; + } else { + R_VerifyInit(&ctx, DA_MD5); + R_VerifyUpdate(&ctx, (char *)&pkt[i + + 2], 4); + rval = R_VerifyFinal(&ctx, + (char *)&pkt[i + 4], temp, + (R_RSA_PUBLIC_KEY *)peer->pubkey); + temp = ntohl(pkt[i + 2]); + } +#ifdef DEBUG + if (debug) + printf( + "crypto_recv: verify %x cookie %08x\n", + rval, temp); +#endif + if (rval != 0) { + peer->flags &= ~FLAG_AUTOKEY; + break; + } + peer->flags |= FLAG_AUTOKEY; +#else + temp = ntohl(pkt[i + 2]); +#endif /* PUBKEY */ + peer->flash &= ~TEST10; + if (temp != peer->pcookie) { + key_expire(peer); + peer->pcookie = temp; + } + break; + +#ifdef PUBKEY + /* + * Compute Diffie-Hellman key agreement. We allocate + * space and save the public value to compute the + * signature later, Then we allocate space for the + * agreed key, run the agreement algorithm and stash the + * key vale. We use only the first u_int32 for the host + * cookie. Wasteful. This is used in symmetric modes. + */ + case CRYPTO_DH: + temp = ntohl(pkt[i + 2]); + if (temp == 0 || temp != dh_params.primeLen) { + rval = -1; + temp = 0; + } else { + if (peer->dh_public == NULL) + peer->dh_public = + (u_char *)emalloc(temp); + memcpy(peer->dh_public, + (char *)&pkt[i + 3], temp); + if (peer->dh_key == NULL) + peer->dh_key = + (u_char *)emalloc(temp); + rval = R_ComputeDHAgreedKey( + peer->dh_key, peer->dh_public, + dh_private, dh_keyLen, &dh_params); + temp = ntohl(*((u_int *)peer->dh_key)); + } +#ifdef DEBUG + if (debug) + printf( + "crypto_recv: d-h agree %x %08x\n", + rval, temp); +#endif + if (rval != 0) { + peer->flags &= ~FLAG_AUTOKEY; + break; + } + peer->flash &= ~TEST10; + if (temp != peer->pcookie) + peer->pcookie = 0; + peer->cmmd = ntohl(pkt[i]); + break; + + /* + * Verify signature of Diffie-Hellman public values. The + * verification fails if the signature length does not + * match the modulus length or any of the public values + * or the agreed key is not valid. This is used in + * symmetric modes. + */ + case CRYPTO_DH | CRYPTO_RESP: + temp = ntohl(pkt[i + 2]); + if (temp == 0 || temp != dh_params.primeLen || + peer->pubkey == NULL || peer->dh_public == + NULL || dh_public == NULL || peer->dh_key == + NULL) { + rval = -1; + temp = 0; + } else { + R_VerifyInit(&ctx, DA_MD5); + R_VerifyUpdate(&ctx, + (u_char *)peer->dh_public, + dh_params.primeLen); + R_VerifyUpdate(&ctx, dh_public, + dh_params.primeLen); + rval = R_VerifyFinal(&ctx, + (u_char *)&pkt[i + 3], temp, + (R_RSA_PUBLIC_KEY *)peer->pubkey); + temp = ntohl(*((u_int *)peer->dh_key)); + } +#ifdef DEBUG + if (debug) + printf( + "crypto_recv: d-h verify %x %08x\n", + rval, temp); +#endif + if (rval != 0) { + peer->flags &= ~FLAG_AUTOKEY; + break; + } + peer->flash &= ~TEST10; + peer->flags |= FLAG_AUTOKEY; + if (temp != peer->pcookie) { + key_expire(peer); + peer->pcookie = temp; + } + break; + + /* + * Install peer public key. This is rather raucus, since + * the extension field is in network order and the first + * word is a u_int32; however, the corresponding word of + * the key is a u_int, which can be 32 or 64 bits + * depending on architecture. We don't do anything + * unless the length and modulus are valid. Picky, + * picky. + */ + case CRYPTO_PUBL | CRYPTO_RESP: + temp = sizeof(R_RSA_PUBLIC_KEY) - sizeof(u_int); + if (ntohl(pkt[i + 2]) != temp + 4) + break; + modulus = ntohl(pkt[i + 3]); + if ( modulus < MIN_RSA_MODULUS_BITS || + modulus > MAX_RSA_MODULUS_BITS) + break; + if (peer->pubkey == NULL) + peer->pubkey = + emalloc(sizeof(R_RSA_PUBLIC_KEY)); + ((R_RSA_PUBLIC_KEY *)peer->pubkey)->bits = + modulus; + memcpy( + ((R_RSA_PUBLIC_KEY *)peer->pubkey)->modulus, + (u_char *)&(pkt[i + 4]), temp); + break; +#endif /* PUBKEY */ + + /* + * For other commands, save the command code for later; + * for unknown responses or errors, just ignore for now. + */ + default: + if (code & (CRYPTO_RESP | CRYPTO_ERROR)) + break; + peer->cmmd = ntohl(pkt[i]); + break; + + } + authlen += len; + } + return; +} + + +/* + * crypto_xmit - construct extension fields + * + * This routine is called both when an association is configured and + * when one is not. The only case where this matters now is to retrieve + * the autokey information, in which case the caller has to provide the + * association ID to match the association. + */ +int /* return length of extension field */ +crypto_xmit( + u_int32 *xpkt, /* packet pointer */ + int start, /* offset to extension field */ + u_int code, /* extension field code */ + keyid_t cookie, /* session cookie */ + int associd /* association ID */ + ) +{ + struct peer *peer; /* peer structure pointer */ + int len; /* extension field length */ + u_int opcode; /* extension field opcode */ + int i; +#ifdef PUBKEY + R_SIGNATURE_CTX ctx; /* signature context */ + int rval; /* return value */ + u_int temp; +#endif /* PUBKEY */ + + /* + * Generate the requested extension field command code, length + * and association ID. + */ + i = start / 4; + opcode = code; + xpkt[i + 1] = htonl(associd); + len = 8; + switch (opcode) { + + /* + * Exchange association IDs. This is used in multicast server + * mode and is a NOP here. + */ + case CRYPTO_ASSOC | CRYPTO_RESP: + break; + + /* + * Find peer and send autokey data and signature. We send the + * data only if the peer exists and the make_keylist routine has + * previously constructed the list and successfully signed the + * data. This is used in multicast server and symmetric modes. + */ + case CRYPTO_AUTO | CRYPTO_RESP: + peer = findpeerbyassoc(associd); + if (peer == NULL) { + opcode |= CRYPTO_ERROR; + break; + } + xpkt[i + 2] = htonl(peer->keynumber); + xpkt[i + 3] = htonl(peer->lastseq); + xpkt[i + 4] = htonl(peer->lastkey); + xpkt[i + 5] = 0; + len += 16; +#ifdef PUBKEY + if (peer->signlen == 0) + break; + xpkt[i + 5] = htonl(peer->signlen); + memcpy((u_char *)&xpkt[i + 6], peer->sign, + peer->signlen); + len += peer->signlen; +#endif /* PUBKEY */ + break; + + /* + * Send peer cookie and signature. We send the signature only if + * the private key exists and is valid. This is used in server + * mode. + */ + case CRYPTO_PRIV | CRYPTO_RESP: + xpkt[i + 2] = htonl(cookie); + xpkt[i + 3] = 0; + len += 8; +#ifdef PUBKEY + if (private_key.bits < MIN_RSA_MODULUS_BITS || + private_key.bits > MAX_RSA_MODULUS_BITS) { + rval = -1; + } else { + R_SignInit(&ctx, DA_MD5); + R_SignUpdate(&ctx, (u_char *)&xpkt[i + 2], 4); + rval = R_SignFinal(&ctx, (u_char *)&xpkt[i + 4], + &temp, &private_key); + } + if (rval != 0) { + msyslog(LOG_ERR, + "crypto_xmit: signature fails %x", rval); + break; + } + xpkt[i + 3] = htonl(temp); + len += temp; +#endif /* PUBKEY */ + break; + +#ifdef PUBKEY + /* + * Send Diffie-Hellman public value. We send only if the + * parameters have been initialized and the public/private + * values have been set up. This is used in symmetric modes. + */ + case CRYPTO_DH: + xpkt[i + 2] = 0; + len += 4; + if (dh_params.primeLen == 0 || dh_public == NULL) + break; + xpkt[i + 2] = htonl(dh_params.primeLen); + memcpy((u_char *)&xpkt[i + 3], dh_public, + dh_params.primeLen); + len += dh_params.primeLen; + break; + + /* + * Find peer and send signature of Diffie-Hellman public values. + * This takes a leap of faith, or maybe just a stumble of + * depravity. This is used in symmetric modes. + */ + case CRYPTO_DH | CRYPTO_RESP: + peer = findpeerbyassoc(associd); + if (peer == NULL) { + opcode |= CRYPTO_ERROR; + break; + } + xpkt[i + 2] = 0; + len += 4; + if (private_key.bits < MIN_RSA_MODULUS_BITS || + private_key.bits > MAX_RSA_MODULUS_BITS || + dh_public == NULL || peer->dh_public == NULL) { + rval = -1; + } else { + R_SignInit(&ctx, DA_MD5); + R_SignUpdate(&ctx, dh_public, + dh_params.primeLen); + R_SignUpdate(&ctx, (u_char *)peer->dh_public, + dh_params.primeLen); + rval = R_SignFinal(&ctx, (u_char *)&xpkt[i + 3], + &temp, &private_key); + } + if (rval != 0) { + msyslog(LOG_ERR, + "crypto_xmit: signature fails %x", rval); + break; + } + xpkt[i + 2] = htonl(temp); + len += temp; + break; + + /* + * Send public key. We send the public key only if it exists and + * is valid. This is used in all modes. + */ + case CRYPTO_PUBL | CRYPTO_RESP: + xpkt[i + 2] = 0; + len += 4; + if (public_key.bits < MIN_RSA_MODULUS_BITS || + public_key.bits > MAX_RSA_MODULUS_BITS) + break; + temp = sizeof(R_RSA_PUBLIC_KEY) - sizeof(u_int); + xpkt[i + 2] = htonl(temp + 4); + xpkt[i + 3] = htonl(public_key.bits); + memcpy((u_char *)&xpkt[i + 4], + (u_char *)&public_key.modulus, temp); + len += temp + 4; + break; +#endif /* PUBKEY */ + + /* + * Default - Fall through for commands; for unknown responses, + * flag as error. + */ + default: + if (opcode & CRYPTO_RESP) + opcode |= CRYPTO_ERROR; + break; + } + + /* + * Round up the field length to a multiple of 8 bytes and save + * the command code and length. + */ + len = ((len + 7) / 8) * 8; + if (len >= 4) { + xpkt[i] = htonl((u_int32)((opcode << 16) | len)); +#ifdef DEBUG + if (debug) + printf( + "crypto_xmit: ext field offset %d length %d code %x assoc ID %d\n", + start, len, code, associd); +#endif + } + return (len); +} + + +#ifdef PUBKEY +/* + * crypto_read - read RSA key, decode and check for errors + */ +int +crypto_read( + u_char *cp, /* file name */ + u_char *key, /* key pointer */ + u_int keylen /* key length */ + ) +{ + FILE *str; + u_char buf[MAX_KEYLEN]; + u_char encoded_key[MAX_KEYLEN]; + char filename[MAXFILENAME]; + u_int modulus; + u_int buflen; + char *rptr; + int rval; + + /* + * Open the key file and discard comment lines. + */ + if (strlen(cp) == 0 || strlen(cp) >= MAXFILENAME - 1) { + msyslog(LOG_ERR, "invalid key file name length %d", + strlen(filename)); + return (0); + } else if (*cp == '/') { + strcpy(filename, cp); + } else { + sprintf(filename, "%s%s", keysdir, cp); + } + str = fopen(filename, "r"); + if (str == NULL) { + msyslog(LOG_ERR, "key file %s not found", filename); + return (0); + } + while ((rptr = fgets(buf, MAX_KEYLEN - 1, str)) != NULL) { + buflen = strlen(buf); + if (buflen < 1) + continue; + if (*buf == '#' || *buf == '\r' || *buf == '\0') + continue; + break; + } + + /* + * We are rather paranoid here, since an intruder can cause a + * coredump by infiltrating a naughty key. The line must contain + * a single integer followed by a PEM encoded, null-terminated + * string. + */ + if (rptr == NULL) { + msyslog(LOG_ERR, "invalid key file %s", filename); + return (0); + } + if (sscanf(buf, "%d %s", &modulus, encoded_key) != 2) { + msyslog(LOG_ERR, "invalid key format %s", filename); + return (0); + } + + /* + * Initialize the key with the decoded PEM string, but leave + * room for the modulus length in the key structure. + */ + rval = R_DecodePEMBlock(&key[sizeof(u_int)], &buflen, + encoded_key, strlen(encoded_key)); + if (rval != 0) { + msyslog(LOG_ERR, "invalid key %s %x", filename, rval); + return (0); + } + + /* + * Make sure the structure has the required length. + */ + buflen += sizeof(u_int); + if (buflen != keylen) { + msyslog(LOG_ERR, "invalid key length %s %d", filename, + buflen); + return (0); + } + + /* + * Make sure the modulus length is within limits. + */ + if (modulus < MIN_RSA_MODULUS_BITS || modulus > + MAX_RSA_MODULUS_BITS) { + msyslog(LOG_ERR, "invalid key modulus %s %d", filename, + modulus); + return (0); + } + ((u_int *)key)[0] = modulus; +#ifdef DEBUG + if (debug) + printf( + "crypto_read: RSA key file %s length %d modulus %d\n", + cp, keylen, modulus); +#endif + return (1); +} + + +/* + * crypto_public - read and install the public key from the public key + * file. The name of the file is in the form "ntpkey_host", where host + * is the DNS canonical name of the host. If the file is not found or + * has errors, we just keep going and expect the host to fetch the + * public key from the peer via the extension field. + */ +void +crypto_public( + struct peer *peer, /* peer structure pointer */ + u_char *cp /* file name */ + ) +{ + R_RSA_PUBLIC_KEY keybuf; + u_int keylen = sizeof(R_RSA_PUBLIC_KEY); + char filename[MAXFILENAME]; + + sprintf(filename, "ntpkey_%s", cp); + if (!crypto_read(filename, (u_char *)&keybuf, keylen)) + return; + if (peer->keystr != NULL) + free(peer->keystr); + peer->keystr = emalloc(strlen(filename) + 1); + strcpy(peer->keystr, filename); + if (peer->pubkey == NULL) + peer->pubkey = emalloc(keylen); + memcpy(peer->pubkey, (char *)&keybuf, keylen); +} + + +/* + * crypto_line - read, decode and install Diffie-Hellman prime and + * generator. Be very parannoyed here if every little thing is not + * exactly right. + */ +void +crypto_line( + FILE *str, /* file handle */ + u_char **key, /* decoded string pointer */ + u_int *len /* length */ + ) +{ + u_char buf[MAX_KEYLEN]; + u_char encoded_key[MAX_KEYLEN]; + u_int temp, temp1, temp2; + char *rptr; + + /* + * Read key and length. Bail out if the length word doesn't + * match the decoded string length. + */ + *key = NULL; + *len = 0; + while ((rptr = fgets(buf, MAX_KEYLEN - 1, str)) != NULL) { + if (strlen(buf) < 1) + continue; + if (*buf == '#' || *buf == '\r' || *buf == '\0') + continue; + break; + } + if (sscanf(buf, "%d %s", &temp, encoded_key) != 2) + return; + temp2 = DECODED_CONTENT_LEN(strlen(encoded_key)); + if (R_DecodePEMBlock(buf, &temp1, encoded_key, + strlen(encoded_key))) + return; + if (temp != temp1 || temp > temp2) + return; + *key = (u_char *)emalloc(temp2); + memcpy(*key, buf, temp2); + *len = temp; + return; +} + + +/* + * crypto_setup - read RSA private key, RSA public key and Diffie- + * Hellman parameter files and initialize cryptographic data. + */ +void +crypto_setup(void) +{ + FILE *str; + struct utsname utsnamebuf; + u_char filename[MAXFILENAME]; + + /* + * Load RSA private key from file. + */ + if (private_key_file == NULL) + private_key_file = "ntpkey"; + crypto_read(private_key_file, (u_char *)&private_key, + sizeof(R_RSA_PRIVATE_KEY)); + + /* + * Load RSA public key from file, default "ntpkey_host", where + * host is the DNS name of this machine. + */ + if (public_key_file == NULL) { + uname(&utsnamebuf); + sprintf(filename, "ntpkey_%s", utsnamebuf.nodename); + public_key_file = emalloc(strlen(filename) + 1); + strcpy(public_key_file, filename); + } + crypto_read(public_key_file, (u_char *)&public_key, + sizeof(R_RSA_PUBLIC_KEY)); + + /* + * Load Diffie-Hellman key agreement parameters from file. + */ + if (dh_params_file == NULL) + dh_params_file = "ntpkey_dh"; + if (*dh_params_file == '/') + strcpy(filename, dh_params_file); + else + sprintf(filename, "%s%s", keysdir, dh_params_file); + + str = fopen(filename, "r"); + if (str == NULL) { + msyslog(LOG_ERR, "key file %s not found", + filename); + return; + } + + /* + * Read prime and generator. Note that the private value length + * is set arbitrarily at half the prime length. + */ + crypto_line(str, &dh_params.prime, &dh_params.primeLen); + crypto_line(str, &dh_params.generator, &dh_params.generatorLen); + if (dh_params.primeLen == 0|| dh_params.generatorLen == 0) { + msyslog(LOG_ERR, + "invalid Diffie-Hellman file format or value"); + return; + } + dh_keyLen = dh_params.primeLen / 2; +} + + +/* + * crypto_agree - compute public and private Diffie-Hellman values from + * given prime and generator. + */ +void +crypto_agree(void) +{ + R_RANDOM_STRUCT randomstr; + u_int len, temp; + int rval, i; + + /* + * Note that the length of the private value is set arbitrarily + * to half the prime length. + */ + if (dh_params.primeLen == 0) + return; + R_RandomInit(&randomstr); + R_GetRandomBytesNeeded(&len, &randomstr); + for (i = 0; i < len; i++) { + temp = random(); + R_RandomUpdate(&randomstr, (u_char *)&temp, 1); + } + if (dh_private == NULL) + dh_private = (u_char *)emalloc(dh_keyLen); + if (dh_public == NULL) + dh_public = (u_char *)emalloc(dh_params.primeLen); + rval = R_SetupDHAgreement(dh_public, dh_private, dh_keyLen, + &dh_params, &randomstr); + if (rval != 0) + msyslog(LOG_ERR, "invalid Diffie-Hellman parameters"); +#ifdef DEBUG + if (debug) + printf( + "cypto_init: Diffie-Hellman prime %d generator %d key %d\n", + dh_params.primeLen, dh_params.generatorLen, + dh_keyLen); +#endif +} + + +/* + * crypto_config - configure crypto data. + */ +void +crypto_config( + int item, /* configuration item */ + char *cp /* file name */ + ) +{ + switch (item) { + + /* + * Initialize flags + */ + case CRYPTO_CONF_FLAGS: + crypto_flags = atoi(cp); + break; + /* + * Override the default Diffie-Hellman parameter file name. + */ + case CRYPTO_CONF_DH: + dh_params_file = emalloc(strlen(cp) + 1); + strcpy(dh_params_file, cp); + break; + + /* + * Override the default RSA private key file name. + */ + case CRYPTO_CONF_PRIV: + private_key_file = emalloc(strlen(cp) + 1); + strcpy(private_key_file, cp); + break; + + /* + * Override the default RSA public key file name. + */ + case CRYPTO_CONF_PUBL: + public_key_file = emalloc(strlen(cp) + 1); + strcpy(public_key_file, cp); + break; + + /* + * Override the default crypto keys directory. + */ + case CRYPTO_CONF_KEYS: + keysdir = emalloc(strlen(cp) + 1); + strcpy(keysdir, cp); + break; + } +} + + +/* + * crypto_init () - initialize things. + */ +void +crypto_init(void) +{ + /* + * Zeroize sensitive crypto data. + */ + memset((char *)&private_key, 0, sizeof(private_key)); + memset((char *)&public_key, 0, sizeof(public_key)); + memset((char *)&dh_params, 0, sizeof(dh_params)); +} +#endif /* PUBKEY */ +#endif /* AUTOKEY */ diff --git a/ntpd/ntp_intres.c b/ntpd/ntp_intres.c index e9a387e075..ed9fe08728 100644 --- a/ntpd/ntp_intres.c +++ b/ntpd/ntp_intres.c @@ -27,6 +27,14 @@ #include #include +/**/ +#include +#include +/**/ +#ifdef HAVE_SYS_PARAM_H +# include /* MAXHOSTNAMELEN (often) */ +#endif + #include "ntpd.h" #include "ntp_io.h" #include "ntp_request.h" @@ -52,6 +60,7 @@ struct conf_entry { #define ce_flags ce_config.flags #define ce_ttl ce_config.ttl #define ce_keyid ce_config.keyid +#define ce_keystr ce_config.keystr /* * confentries is a pointer to the list of configuration entries @@ -73,7 +82,6 @@ static struct conf_entry *confentries = NULL; #define MAXRESOLVE 32 #define CONFIG_TIME 2 #define ALARM_TIME 30 - #define SLEEPTIME 2 static volatile int config_timer = 0; @@ -107,7 +115,8 @@ static int resolve_value; /* next value of resolve timer */ #define TOK_FLAGS 5 #define TOK_TTL 6 #define TOK_KEYID 7 -#define NUMTOK 8 +#define TOK_KEYSTR 8 +#define NUMTOK 9 #define MAXLINESIZE 512 @@ -120,7 +129,7 @@ static int sockfd = -1; /* stuff to be filled in by caller */ -u_long req_keyid; /* request keyid */ +keyid_t req_keyid; /* request keyid */ char *req_file; /* name of the file with configuration info */ /* end stuff to be filled in */ @@ -129,7 +138,8 @@ char *req_file; /* name of the file with configuration info */ static RETSIGTYPE bong P((int)); static void checkparent P((void)); static void removeentry P((struct conf_entry *)); -static void addentry P((char *, int, int, int, int, int, int, u_long)); +static void addentry P((char *, int, int, int, int, int, + int, keyid_t, char *)); static int findhostaddr P((struct conf_entry *)); static void openntp P((void)); static int request P((struct conf_peer *)); @@ -137,10 +147,48 @@ static char * nexttoken P((char **)); static void readconf P((FILE *, char *)); static void doconfigure P((int)); +struct ntp_res_t_pkt { /* Tagged packet: */ + void *tag; /* For the caller */ + u_int32 paddr; /* IP to look up, or 0 */ + char name[MAXHOSTNAMELEN]; /* Name to look up (if 1st byte is not 0) */ +}; + +struct ntp_res_c_pkt { /* Control packet: */ + char name[MAXHOSTNAMELEN]; + u_int32 paddr; + int mode; + int version; + int minpoll; + int maxpoll; + int flags; + int ttl; + keyid_t keyid; + u_char keystr[MAXFILENAME]; +}; + + +/* + * ntp_res_recv: Process an answer from the resolver + */ + +void +ntp_res_recv(void) +{ + /* + We have data ready on our descriptor. + It may be an EOF, meaning the resolver process went away. + Otherwise, it will be an "answer". + */ +} + + /* - * assumes: req_key, req_keyid, conffile valid - * syslog still open + * ntp_intres needs; + * + * req_key(???), req_keyid, req_file valid + * syslog still open */ + void ntp_intres(void) { @@ -149,7 +197,7 @@ ntp_intres(void) sigset_t set; sigemptyset(&set); -#endif /* NTP_POSIX_SOURCE */ +#endif /* HAVE_SIGSUSPEND */ #ifdef DEBUG if (debug > 1) { @@ -160,7 +208,7 @@ ntp_intres(void) /* check out auth stuff */ if (sys_authenticate) { if (!authistrusted(req_keyid)) { - msyslog(LOG_ERR, "invalid request keyid %lu", + msyslog(LOG_ERR, "invalid request keyid %08x", req_keyid ); exit(1); } @@ -180,7 +228,7 @@ ntp_intres(void) (void) fclose(in); if (!debug ) - (void) unlink(req_file); + (void) unlink(req_file); /* * Sleep a little to make sure the server is completely up @@ -192,12 +240,13 @@ ntp_intres(void) * Make a first cut at resolving the bunch */ doconfigure(1); - if (confentries == NULL) + if (confentries == NULL) { #if defined SYS_WINNT - ExitThread(0); /* Don't want to kill whole NT process */ + ExitThread(0); /* Don't want to kill whole NT process */ #else - exit(0); /* done that quick */ + exit(0); /* done that quick */ #endif + } /* * Here we've got some problem children. Set up the timer @@ -239,11 +288,11 @@ ntp_intres(void) * There is a race in here. Is okay, though, since * all it does is delay things by 30 seconds. */ -#ifdef HAVE_SIGSUSPEND +# ifdef HAVE_SIGSUSPEND sigsuspend(&set); -#else +# else sigpause(0); -#endif /* HAVE_SIGSUSPEND */ +# endif /* HAVE_SIGSUSPEND */ #else if (config_timer > 0) config_timer--; @@ -338,15 +387,23 @@ addentry( int maxpoll, int flags, int ttl, - u_long keyid + keyid_t keyid, + char *keystr ) { register char *cp; register struct conf_entry *ce; unsigned int len; +#ifdef DEBUG + if (debug > 1) + msyslog(LOG_INFO, + "intres: <%s> %d %d %d %d %d %d %u %s\n", + name, mode, version, + minpoll, maxpoll, flags, ttl, keyid, keystr); +#endif len = strlen(name) + 1; - cp = (char*)emalloc(len); + cp = (char *)emalloc(len); memmove(cp, name, len); ce = (struct conf_entry *)emalloc(sizeof(struct conf_entry)); @@ -359,6 +416,7 @@ addentry( ce->ce_flags = (u_char)flags; ce->ce_ttl = (u_char)ttl; ce->ce_keyid = keyid; + strncpy(ce->ce_keystr, keystr, MAXFILENAME); ce->ce_next = NULL; if (confentries == NULL) { @@ -375,12 +433,12 @@ addentry( /* - * findhostaddr - resolve a host name into an address + * findhostaddr - resolve a host name into an address (Or vice-versa) * - * The routine sticks the address into the entry's ce_peeraddr if it - * gets one. It returns 1 for "success" and 0 for an uncorrectable - * failure. Note that "success" includes try again errors. You can - * tell that you got a try again since ce_peeraddr will still be zero. + * Given one of {ce_peeraddr,ce_name}, find the other one. + * It returns 1 for "success" and 0 for an uncorrectable failure. + * Note that "success" includes try again errors. You can tell that you + * got a "try again" since {ce_peeraddr,ce_name} will still be zero. */ static int findhostaddr( @@ -391,28 +449,75 @@ findhostaddr( checkparent(); /* make sure our guy is still running */ - hp = gethostbyname(entry->ce_name); + if (entry->ce_name && entry->ce_peeraddr) { + /* HMS: Squawk? */ + msyslog(LOG_ERR, "findhostaddr: both ce_name and ce_peeraddr are defined..."); + return 1; + } + + if (!entry->ce_name && !entry->ce_peeraddr) { + msyslog(LOG_ERR, "findhostaddr: both ce_name and ce_peeraddr are undefined!"); + return 0; + } + + if (entry->ce_name) { +#ifdef DEBUG + if (debug > 2) + msyslog(LOG_DEBUG, "findhostaddr: Resolving <%s>", + entry->ce_name); +#endif DEBUG + hp = gethostbyname(entry->ce_name); + } else { +#ifdef DEBUG + if (debug > 2) + msyslog(LOG_DEBUG, "findhostaddr: Resolving %x>", + entry->ce_peeraddr); +#endif + hp = gethostbyaddr((const char *)entry->ce_peeraddr, + sizeof entry->ce_peeraddr, + AF_INET); + } if (hp == NULL) { -#ifndef NODNS /* * If the resolver is in use, see if the failure is * temporary. If so, return success. */ if (h_errno == TRY_AGAIN) return (1); -#endif return (0); } - /* - * Use the first address. We don't have any way to - * tell preferences and older gethostbyname() implementations - * only return one. - */ - memmove((char *)&(entry->ce_peeraddr), - (char *)hp->h_addr, - sizeof(struct in_addr)); + if (entry->ce_name) { +#ifdef DEBUG + if (debug > 2) + msyslog(LOG_DEBUG, "findhostaddr: name resolved."); +#endif + /* + * Use the first address. We don't have any way to tell + * preferences and older gethostbyname() implementations + * only return one. + */ + memmove((char *)&(entry->ce_peeraddr), + (char *)hp->h_addr, + sizeof(struct in_addr)); + if (entry->ce_keystr[0] == '*') + strncpy((char *)&(entry->ce_keystr), hp->h_name, + MAXFILENAME); + } else { + char *cp; + size_t s; + +#ifdef DEBUG + if (debug > 2) + msyslog(LOG_DEBUG, "findhostaddr: address resolved."); +#endif + s = strlen(hp->h_name) + 1; + cp = emalloc(s); + strcpy(cp, hp->h_name); + entry->ce_name = cp; + } + return (1); } @@ -460,7 +565,7 @@ openntp(void) #endif /* O_NONBLOCK */ #else /* SYS_WINNT */ { - int on=1; + int on = 1; if (ioctlsocket(sockfd,FIONBIO,(u_long *) &on) == SOCKET_ERROR) { msyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m"); exit(1); /* Windows NT - set socket in non-blocking mode */ @@ -470,7 +575,7 @@ openntp(void) if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) { - msyslog(LOG_ERR, "connect() failed: %m"); + msyslog(LOG_ERR, "openntp: connect() failed: %m"); exit(1); } } @@ -552,7 +657,7 @@ request( } #else /* In the NT world, documentation seems to indicate that there - * exist _write and _read routines that can be used to so blocking + * exist _write and _read routines that can be used to do blocking * I/O on sockets. Problem is these routines require a socket * handle obtained through the _open_osf_handle C run-time API * of which there is no explanation in the documentation. We need @@ -830,7 +935,7 @@ readconf( } } - for (i = 1; i < NUMTOK; i++) { + for (i = 1; i < NUMTOK - 1; i++) { if (!atouint(token[i], &intval[i])) { msyslog(LOG_ERR, "format error for integer token `%s', file `%s', quitting", @@ -893,7 +998,7 @@ readconf( addentry(token[TOK_HOSTNAME], (int)intval[TOK_HMODE], (int)intval[TOK_VERSION], (int)intval[TOK_MINPOLL], (int)intval[TOK_MAXPOLL], flags, (int)intval[TOK_TTL], - intval[TOK_KEYID]); + intval[TOK_KEYID], token[TOK_KEYSTR]); } } @@ -909,16 +1014,12 @@ doconfigure( register struct conf_entry *ce; register struct conf_entry *ceremove; -#ifdef DEBUG - if (debug > 1) - msyslog(LOG_INFO, "doconfigure(%d)", dores); -#endif - ce = confentries; while (ce != NULL) { #ifdef DEBUG if (debug > 1) - msyslog(LOG_INFO, "doconfigure: <%s> has peeraddr %#x", + msyslog(LOG_INFO, + "doconfigure: <%s> has peeraddr %#x", ce->ce_name, ce->ce_peeraddr); #endif if (dores && ce->ce_peeraddr == 0) { @@ -931,28 +1032,10 @@ doconfigure( removeentry(ceremove); continue; } -#ifdef DEBUG - if (debug > 1) { - msyslog(LOG_INFO, - "doconfigure:findhostaddr() worked"); - } -#endif } if (ce->ce_peeraddr != 0) { -#ifdef DEBUG - if (debug > 1) { - msyslog(LOG_INFO, - "doconfigure: calling request()"); - } -#endif if (request(&ce->ce_config)) { -#ifdef DEBUG - if (debug > 1) { - msyslog(LOG_INFO, - "doconfigure: request() OK, removing this entry"); - } -#endif ceremove = ce; ce = ceremove->ce_next; removeentry(ceremove); @@ -961,7 +1044,7 @@ doconfigure( #ifdef DEBUG if (debug > 1) { msyslog(LOG_INFO, - "doconfigure: request() FAILED, maybe next time."); + "doconfigure: request() FAILED, maybe next time."); } #endif } diff --git a/ntpd/ntp_loopfilter.c b/ntpd/ntp_loopfilter.c index 15b625de6f..88f61bf17e 100644 --- a/ntpd/ntp_loopfilter.c +++ b/ntpd/ntp_loopfilter.c @@ -583,14 +583,14 @@ local_clock( sys_rootdispersion = peer->rootdispersion + dtemp; (void)record_loop_stats(); #ifdef DEBUG - if (debug) + if (debug > 1) printf( "local_clock: mu %.0f allan %.0f fadj %.3f fll %.3f pll %.3f\n", mu, allan_xpt, clock_frequency * 1e6, flladj * 1e6, plladj * 1e6); #endif /* DEBUG */ #ifdef DEBUG - if (debug) + if (debug > 1) printf( "local_clock: jitter %.6f freq %.3f stab %.3f poll %d count %d\n", sys_error, drift_comp * 1e6, clock_stability * 1e6, diff --git a/ntpd/ntp_peer.c b/ntpd/ntp_peer.c index 90646abcfa..470a107f33 100644 --- a/ntpd/ntp_peer.c +++ b/ntpd/ntp_peer.c @@ -10,6 +10,9 @@ #include "ntpd.h" #include "ntp_stdlib.h" +#ifdef PUBKEY +#include "ntp_crypto.h" +#endif /* PUBKEY */ /* * Table of valid association combinations @@ -127,7 +130,6 @@ static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* static u_long init_peer_starttime; */ static void getmorepeermem P((void)); -static void key_expire P((struct peer *)); /* * init_peer - initialize peer data structures and counters @@ -285,21 +287,17 @@ findpeer( } } -#ifdef DEBUG - if (debug > 1) - printf("pkt_mode %d action %d\n", pkt_mode, *action); -#endif - /* if no matching association is found */ + /* + * If no matching association is found + */ if (peer == 0) { *action = MATCH_ASSOC(NO_PEER, pkt_mode); -#ifdef DEBUG - if (debug > 1) - printf("pkt_mode %d action %d\n", pkt_mode, *action); -#endif return (struct peer *)0; } - /* reset the default interface to something more meaningful */ + /* + * Reset the default interface to something more meaningful + */ if ((peer->dstadr == any_interface)) peer->dstadr = dstadr; return peer; @@ -368,31 +366,10 @@ findmanycastpeer( return manycast_peer; } +#ifdef AUTOKEY /* - * key_expire - garbage collect keys - */ -static void -key_expire( - struct peer *peer - ) -{ - int i; - - if (peer->keylist != 0) { - for (i = 0; i <= peer->keynumber; i++) - authtrust(peer->keylist[i], 0); - free(peer->keylist); - peer->keylist = 0; - } - if (peer->keyid > NTP_MAXKEY) { - authtrust(peer->keyid, 0); - peer->keyid = 0; - } -} - -/* - * key_rekey - expire all keys and roll a new private value. Note the - * 32-bit mask is necessary for 64-bit u_longs. + * key_expire - expire all keys and roll a new private value. Note the + * 32-bit mask is necessary for 64-bit u_ints. */ void key_expire_all( @@ -404,16 +381,21 @@ key_expire_all( for (n = 0; n < HASH_SIZE; n++) { for (peer = peer_hash[n]; peer != 0; peer = next_peer) { next_peer = peer->next; - key_expire(peer); + peer_clear(peer); } } - sys_private = (u_long)RANDOM & 0xffffffff; + sys_private = (u_int32)RANDOM & 0xffffffff; +#ifdef PUBKEY + crypto_agree(); +#endif /* PUBKEY */ #ifdef DEBUG if (debug) - printf("key_expire_all: at %lu private %08lx\n", - current_time, sys_private); + printf("key_expire_all: at %lu private %08x next %lu\n", + current_time, sys_private, current_time + sys_revoke); #endif } +#endif /* AUTOKEY */ + /* * unpeer - remove peer structure from hash table and free structure */ @@ -424,16 +406,22 @@ unpeer( { int hash; + peer_associations--; #ifdef DEBUG - if (debug > 1) - printf("demobilize %u\n", peer_to_remove->associd); + if (debug) + printf("demobilize %u %d\n", peer_to_remove->associd, + peer_associations); #endif - key_expire(peer_to_remove); + peer_clear(peer_to_remove); + if (peer_to_remove->keystr != 0) + free(peer_to_remove->keystr); +#ifdef PUBKEY + if (peer_to_remove->pubkey != 0) + free(peer_to_remove->pubkey); +#endif /* PUBKEY */ hash = HASH_ADDR(&peer_to_remove->srcadr); peer_hash_count[hash]--; peer_demobilizations++; - peer_associations--; - #ifdef REFCLOCK /* * If this peer is actually a clock, shut it down first @@ -502,7 +490,8 @@ peer_config( int maxpoll, int flags, int ttl, - u_long key + keyid_t key, + u_char *keystr ) { register struct peer *peer; @@ -515,7 +504,7 @@ peer_config( if (dstadr != 0) { while (peer != 0) { if (peer->dstadr == dstadr) - break; + break; peer = findexistingpeer(srcadr, peer, hmode); } } @@ -533,30 +522,36 @@ peer_config( peer->flags = flags | FLAG_CONFIG | (peer->flags & FLAG_REFCLOCK); peer->cast_flags = (hmode == MODE_BROADCAST) ? - IN_CLASSD(ntohl(srcadr->sin_addr.s_addr)) ? MDF_MCAST : MDF_BCAST : MDF_UCAST; + IN_CLASSD(ntohl(srcadr->sin_addr.s_addr)) ? + MDF_MCAST : MDF_BCAST : MDF_UCAST; peer->ttl = (u_char)ttl; peer->keyid = key; - peer->keynumber = 0; - return peer; - } + } else { - /* - * If we're here this guy is unknown to us. Make a new peer - * structure for him. - */ - peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll, - ttl, key); - if (peer != 0) { + /* + * If we're here this guy is unknown to us. Make a new peer + * structure for him. + */ + peer = newpeer(srcadr, dstadr, hmode, version, minpoll, + maxpoll, ttl, key); + if (peer == 0) + return (peer); peer->flags |= flags | FLAG_CONFIG; + } #ifdef DEBUG - if (debug) - printf("peer_config: %s mode %d vers %d min %d max %d flags 0x%04x ttl %d key %lu\n", - ntoa(&peer->srcadr), peer->hmode, peer->version, - peer->minpoll, peer->maxpoll, peer->flags, - peer->ttl, peer->keyid); + if (debug) + printf( + "peer_config: %s mode %d vers %d min %d max %d flags 0x%04x ttl %d key %08x\n", + ntoa(&peer->srcadr), peer->hmode, peer->version, + peer->minpoll, peer->maxpoll, peer->flags, peer->ttl, + peer->keyid); #endif - } - return peer; +#ifdef PUBKEY + if (!(peer->flags & FLAG_SKEY)) + return (peer); + crypto_public(peer, keystr); +#endif /* PUBKEY */ + return (peer); } @@ -583,7 +578,7 @@ newpeer( * knowlege of our system state. */ if (peer_free_count == 0) - getmorepeermem(); + getmorepeermem(); peer = peer_free; peer_free = peer->next; @@ -593,12 +588,11 @@ newpeer( /* * Initialize the structure. This stuff is sort of part of * the receive procedure and part of the clear procedure rolled - * into one. - * + * into one. + * * Zero the whole thing for now. We might be pickier later. */ memset((char *)peer, 0, sizeof(struct peer)); - peer->srcadr = *srcadr; if (dstadr != 0) peer->dstadr = dstadr; @@ -630,15 +624,13 @@ newpeer( peer_clear(peer); peer->update = peer->outdate = current_time; peer->nextdate = peer->outdate + RANDPOLL(NTP_MINPOLL); - if (peer->flags & FLAG_BURST) - peer->burst = NTP_SHIFT; /* * Assign him an association ID and increment the system variable */ peer->associd = current_association_ID; if (++current_association_ID == 0) - ++current_association_ID; + ++current_association_ID; /* * Note time on statistics timers. @@ -680,9 +672,9 @@ newpeer( assoc_hash[i] = peer; assoc_hash_count[i]++; #ifdef DEBUG - if (debug > 1) - printf("mobilize %u next %lu\n", peer->associd, - peer->nextdate - peer->outdate); + if (debug) + printf("mobilize %u %d next %lu\n", peer->associd, + peer_associations, peer->nextdate - peer->outdate); #endif return peer; } @@ -775,7 +767,6 @@ peer_reset( peer->oldpkt = 0; peer->seldisptoolarge = 0; peer->selbroken = 0; - peer->seltooold = 0; peer->timereset = current_time; } diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index a24c0e3e56..7c1142a660 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -14,6 +14,7 @@ #include "ntp_unixtime.h" #include "ntp_control.h" #include "ntp_string.h" +#include "ntp_crypto.h" #if defined(VMS) && defined(VMS_LOCALUNIT) /*wjm*/ #include "ntp_refclock.h" @@ -24,7 +25,7 @@ #endif /* - * System variables are declared here. See Section 3.2 of the + * System variables are declared here. See Section 3.2 of the * specification. */ u_char sys_leap; /* system leap indicator */ @@ -36,7 +37,9 @@ u_int32 sys_refid; /* reference source for local clock */ static double sys_offset; /* current local clock offset */ l_fp sys_reftime; /* time we were last updated */ struct peer *sys_peer; /* our current peer */ +#ifdef AUTOKEY u_long sys_automax; /* maximum session key lifetime */ +#endif /* AUTOKEY */ /* * Nonspecified system state variables. @@ -49,7 +52,7 @@ static u_long sys_authdly[2]; /* authentication delay shift reg */ static u_char leap_consensus; /* consensus of survivor leap bits */ static double sys_maxd; /* select error (squares) */ static double sys_epsil; /* system error (squares) */ -u_long sys_private; /* private value for session seed */ +keyid_t sys_private; /* private value for session seed */ int sys_manycastserver; /* 1 => respond to manycast client pkts */ /* @@ -68,12 +71,10 @@ u_long sys_limitrejected; /* pkts rejected due to client count per net */ static double root_distance P((struct peer *)); static double clock_combine P((struct peer **, int)); static void peer_xmit P((struct peer *)); -static void fast_xmit P((struct recvbuf *, int, u_long)); +static void fast_xmit P((struct recvbuf *, int, keyid_t)); static void clock_update P((void)); int default_get_precision P((void)); -#ifdef MD5 -static void make_keylist P((struct peer *)); -#endif /* MD5 */ + /* * transmit - Transmit Procedure. See Section 3.4.2 of the @@ -101,22 +102,30 @@ transmit( peer->valid++; if (oreach & 0x80) peer->valid--; - if (!(peer->flags & FLAG_CONFIG) && peer->valid > - NTP_SHIFT / 2 && (peer->reach & 0x80) && - peer->status < CTL_PST_SEL_SYNCCAND) - peer->reach = 0; peer->reach <<= 1; if (peer->reach == 0) { /* - * If this is an uncofigured association and - * has become unreachable, demobilize it. + * If this association has become unreachable, + * clear it and raise a trap. */ if (oreach != 0) { report_event(EVNT_UNREACH, peer); peer->timereachable = current_time; peer_clear(peer); - if (!(peer->flags & FLAG_CONFIG)) { + } + + /* + * If this association is unreachable and not + * configured, we give it a little while before + * pulling the plug. This is to allow semi- + * persistent things like cryptographic + * authentication to complete the dance. There + * is a denial-of-service hazard here. + */ + if (!(peer->flags & FLAG_CONFIG)) { + peer->tailcnt++; + if (peer->tailcnt > NTP_TAILMAX) { unpeer(peer); return; } @@ -133,14 +142,19 @@ transmit( */ peer->ppoll = peer->maxpoll; if (peer->unreach < NTP_UNREACH) { - if (peer->hmode == MODE_CLIENT) + if (peer->hmode == MODE_CLIENT || + peer->hmode == MODE_ACTIVE) peer->unreach++; hpoll = peer->minpoll; } else { hpoll++; } - if (peer->flags & FLAG_BURST) - peer->burst = 2; + if (peer->flags & FLAG_BURST) { + if (peer->flags & FLAG_MCAST2) + peer->burst = NTP_SHIFT; + else + peer->burst = 2; + } } else { @@ -162,7 +176,7 @@ transmit( clock_filter(peer, 0., 0., MAXDISPERSE); clock_select(); } - if (peer->valid <= 2) + if (peer->valid <= 2 && hpoll > peer->minpoll) hpoll--; else if (peer->valid >= NTP_SHIFT - 2) hpoll++; @@ -172,9 +186,20 @@ transmit( } else { peer->burst--; if (peer->burst == 0) { + + /* + * If a broadcast client at this point, the + * burst has concluded, so we turn off the + * burst, switch to client mode and purge the + * keylist, since no further transmissions will + * be made. + */ if (peer->flags & FLAG_MCAST2) { peer->flags &= ~FLAG_BURST; peer->hmode = MODE_BCLIENT; +#ifdef AUTOKEY + key_expire(peer); +#endif /* AUTOKEY */ } clock_select(); poll_update(peer, hpoll); @@ -216,203 +241,232 @@ receive( int hismode; int oflags; int restrict_mask; - int has_mac; /* has MAC field */ - int authlen; /* length of MAC field */ + int has_mac; /* length of MAC field */ + int authlen; /* offset of MAC field */ int is_authentic; /* cryptosum ok */ - int is_mystic; /* session key exists */ int is_error; /* parse error */ -/* u_long pkeyid; */ - u_long skeyid, tkeyid; + keyid_t pkeyid, skeyid, tkeyid; /* cryptographic keys */ struct peer *peer2; int retcode = AM_NOMATCH; /* - * Monitor the packet and get restrictions + * Monitor the packet and get restrictions. Note that the packet + * length for control and private mode packets must be checked + * by the service routines. Note that no statistics counters are + * recorded for restrict violations, since these counters are in + * the restriction routine. */ ntp_monitor(rbufp); restrict_mask = restrictions(&rbufp->recv_srcadr); #ifdef DEBUG - if (debug > 1) - printf("receive: from %s restrict %02x\n", - ntoa(&rbufp->recv_srcadr), restrict_mask); + if (debug > 2) + printf("receive: at %ld %s restrict %02x\n", + current_time, ntoa(&rbufp->recv_srcadr), + restrict_mask); #endif if (restrict_mask & RES_IGNORE) - return; - - /* - * Discard packets with invalid version number. - */ + return; /* no amything */ pkt = &rbufp->recv_pkt; if (PKT_VERSION(pkt->li_vn_mode) >= NTP_VERSION) sys_newversionpkt++; else if (PKT_VERSION(pkt->li_vn_mode) >= NTP_OLDVERSION) sys_oldversionpkt++; else { - sys_unknownversion++; + sys_unknownversion++; /* unknown version */ return; } - - /* - * Restrict control/private mode packets. Note that packet - * length has to be checked in the control/private mode protocol - * module. - */ if (PKT_MODE(pkt->li_vn_mode) == MODE_PRIVATE) { if (restrict_mask & RES_NOQUERY) - return; + return; /* no query private */ process_private(rbufp, ((restrict_mask & RES_NOMODIFY) == 0)); return; } if (PKT_MODE(pkt->li_vn_mode) == MODE_CONTROL) { if (restrict_mask & RES_NOQUERY) - return; + return; /* no query control */ process_control(rbufp, restrict_mask); return; } - - /* - * Restrict revenue packets. - */ if (restrict_mask & RES_DONTSERVE) - return; - - /* - * See if we only accept limited number of clients from the net - * this guy is from. Note: the flag is determined dynamically - * within restrictions() - */ + return; /* no time service */ if (restrict_mask & RES_LIMITED) { sys_limitrejected++; - return; + return; /* too many clients */ } + if (rbufp->recv_length < LEN_PKT_NOMAC) { + sys_badlength++; + return; /* no runt packets */ + } /* - * If we are not a broadcast client, ignore broadcast packets. + * Figure out his mode and validate the packet. This has some + * legacy raunch that probably should be removed. If from NTPv1 + * mode zero, The NTPv4 mode is determined from the source port. + * If the port number is zero, it is from a symmetric active + * association; otherwise, it is from a client association. From + * NTPv2 on, all we do is toss out mode zero packets, since + * control and private mode packets have already been handled. + * In either case, toss out broadcast packets if we are not a + * broadcast client. */ + hismode = (int)PKT_MODE(pkt->li_vn_mode); + if (PKT_VERSION(pkt->li_vn_mode) == NTP_OLDVERSION && hismode == + 0) { + if (SRCPORT(&rbufp->recv_srcadr) == NTP_PORT) + hismode = MODE_ACTIVE; + else + hismode = MODE_CLIENT; + } else { + if (hismode == MODE_UNSPEC) { + sys_badlength++; + return; /* invalid mode */ + } + } if ((PKT_MODE(pkt->li_vn_mode) == MODE_BROADCAST && !sys_bclient)) return; /* - * This is really awful ugly. We figure out whether an extension - * field is present and then measure the MAC size. If the number - * of words following the packet header is less than or equal to - * 5, no extension field is present and these words constitute - * the MAC. If the number of words is greater than 5, an - * extension field is present and the first word contains the - * length of the extension field and the MAC follows that. + * Parse the extension field if present. We figure out whether + * an extension field is present by measuring the MAC size. If + * the number of words following the packet header is 0 or 1, no + * MAC is present and the packet is not authenticated. If 1, the + * packet is a reply to a previous request that failed to + * authenticate. If 3, the packet is authenticated with DES; if + * 5, the packet is authenticated with MD5. If greater than 5, + * an extension field is present. If 2 or 4, the packet is a + * runt and thus discarded. */ - has_mac = 0; -/* pkeyid = 0; */ - skeyid = tkeyid = 0; + pkeyid = skeyid = tkeyid = 0; authlen = LEN_PKT_NOMAC; - has_mac = rbufp->recv_length - authlen; - if (has_mac <= 5 * sizeof(u_int32)) { - skeyid = (u_long)ntohl(pkt->keyid1) & 0xffffffff; - } else { - authlen += (u_long)ntohl(pkt->keyid1) & 0xffffffff; - has_mac = rbufp->recv_length - authlen; - if (authlen <= 0) { + while ((has_mac = rbufp->recv_length - authlen) > 0) { + int temp; + if (has_mac % 4 != 0 || has_mac < 0) { sys_badlength++; return; } - - /* - * Note that keyid3 is actually the key ident of the - * MAC itself. - */ -/* pkeyid = (u_long)ntohl(pkt->keyid2) & 0xffffffff; */ - skeyid = tkeyid = (u_long)ntohl(pkt->keyid3) & - 0xffffffff; - } - - /* - * Figure out his mode and validate it. - */ - hismode = (int)PKT_MODE(pkt->li_vn_mode); - if (PKT_VERSION(pkt->li_vn_mode) == NTP_OLDVERSION && hismode == - 0) { - /* - * Easy. If it is from the NTP port it is - * a sym act, else client. - */ - if (SRCPORT(&rbufp->recv_srcadr) == NTP_PORT) - hismode = MODE_ACTIVE; - else - hismode = MODE_CLIENT; - } else { - if (hismode != MODE_ACTIVE && hismode != MODE_PASSIVE && - hismode != MODE_SERVER && hismode != MODE_CLIENT && - hismode != MODE_BROADCAST) + if (has_mac == 1 * 4 || has_mac == 3 * 4 || has_mac == + MAX_MAC_LEN) { + skeyid = + (u_long)ntohl(((u_int32 *)pkt)[authlen / + 4]) & 0xffffffff; + break; + } else if (has_mac > MAX_MAC_LEN) { + temp = ntohl(((u_int32 *)pkt)[authlen / 4]) & + 0xffff; + if (temp < 4) { + sys_badlength++; + return; + } + authlen += temp; + } else { + sys_badlength++; return; + } } /* - * If he included a mac field, decrypt it to see if it is - * authentic. + * We have tossed out as many buggy packets as possible early in + * the game to reduce the exposure to a clogging attack. Now we + * have to burn some cycles to find the association and + * authenticate the packet if required. Note that we burn only + * MD5 or DES cycles, again to reduce exposure. There may be no + * matching association and that's okay. */ - is_authentic = is_mystic = 0; + peer = findpeer(&rbufp->recv_srcadr, rbufp->dstadr, rbufp->fd, + hismode, &retcode); + is_authentic = 0; if (has_mac == 0) { #ifdef DEBUG if (debug) - printf("receive: at %ld from %s mode %d\n", - current_time, ntoa(&rbufp->recv_srcadr), - hismode); + printf("receive: at %ld %s mode %d code %d\n", + current_time, ntoa(&rbufp->recv_srcadr), + hismode, retcode); #endif } else { - is_mystic = authistrusted(skeyid); -#ifdef MD5 - if (skeyid > NTP_MAXKEY && !is_mystic) { +#ifdef AUTOKEY + /* + * For autokey modes, generate the session key + * and install in the key cache. Use the socket + * multicast or unicast address as appropriate. + * Remember, we don't know these addresses until + * the first packet has been received. Bummer. + */ + if (skeyid > NTP_MAXKEY) { + + /* + * More on the autokey dance (AKD). A cookie is + * constructed from public and private values. + * For broadcast packets and packets with + * extension fields, the cookie is public + * (zero); for packets that match no + * association, the cookie is hashed from the + * addresses and private value. For server and + * symmetric packets, the cookie has been + * previously obtained from the server via an + * extension field. for symmetric modes, a + * common cookie is constructed as the exclusive + * OR of the two cookies. + */ + if (authlen > LEN_PKT_NOMAC || hismode == + MODE_BROADCAST) + pkeyid = 0; + else if (peer == 0) + pkeyid = session_key( + &rbufp->recv_srcadr, + &rbufp->dstadr->sin, 0, sys_private, + 0); + else if (hismode == MODE_CLIENT) + pkeyid = peer->hcookie; + else + pkeyid = peer->pcookie; /* - * For multicast mode, generate the session key - * and install in the key cache. For client - * mode, generate the session key for the - * unicast address. For server mode, the session - * key should already be in the key cache, since - * it was generated when the last request was - * sent. + * The session key includes both the public + * values and cookie. We have to be careful to + * use the right socket addresses for broadcast + * and unicast packets. Note the hash is saved + * for use later in the AKD mambo. */ - if (hismode == MODE_BROADCAST) { + if (hismode == MODE_BROADCAST) tkeyid = session_key( - ntohl((&rbufp->recv_srcadr)->sin_addr.s_addr), - ntohl(rbufp->dstadr->bcast.sin_addr.s_addr), - skeyid, (u_long)(4 * (1 << pkt->ppoll))); - } else if (hismode != MODE_SERVER) { + &rbufp->recv_srcadr, + &rbufp->dstadr->bcast, skeyid, + pkeyid, 2); + else tkeyid = session_key( - ntohl((&rbufp->recv_srcadr)->sin_addr.s_addr), - ntohl(rbufp->dstadr->sin.sin_addr.s_addr), - skeyid, (u_long)(4 * (1 << pkt->ppoll))); - } - + &rbufp->recv_srcadr, + &rbufp->dstadr->sin, skeyid, pkeyid, + 2); } -#endif /* MD5 */ +#endif /* AUTOKEY */ /* * Compute the cryptosum. Note a clogging attack may - * succceed in bloating the key cache. + * succeed in bloating the key cache. If an autokey, + * purge it immediately, since we won't be needing it + * again. */ if (authdecrypt(skeyid, (u_int32 *)pkt, authlen, has_mac)) is_authentic = 1; else sys_badauth++; +#ifdef AUTOKEY + if (skeyid > NTP_MAXKEY) + authtrust(skeyid, 0); +#endif /* AUTOKEY */ #ifdef DEBUG if (debug) printf( - "receive: at %ld %s mode %d keyid %08lx mac %d auth %d\n", - current_time, ntoa(&rbufp->recv_srcadr), - hismode, skeyid, has_mac, is_authentic); + "receive: at %ld %s mode %d code %d keyid %08x len %d mac %d auth %d\n", + current_time, ntoa(&rbufp->recv_srcadr), + hismode, retcode, skeyid, authlen, has_mac, + is_authentic); #endif } - /* - * Find the peer. This will return a null if this guy isn't in - * the database. - */ - peer = findpeer(&rbufp->recv_srcadr, rbufp->dstadr, rbufp->fd, - hismode, &retcode); /* * The new association matching rules are driven by a table * specified in ntp.h. We have replaced the *default* behaviour @@ -442,14 +496,7 @@ receive( else fast_xmit(rbufp, MODE_SERVER, 0); } - - /* - * We can't get here if an association is mobilized, so - * just toss the key, if appropriate. - */ - if (!is_mystic && skeyid > NTP_MAXKEY) - authtrust(skeyid, 0); - return; + return; case AM_MANYCAST: @@ -505,8 +552,8 @@ receive( * properly authenticated. */ if ((sys_authenticate && !is_authentic)) { - is_error = 1; - break; + fast_xmit(rbufp, MODE_PASSIVE, 0); + return; } peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, MODE_PASSIVE, PKT_VERSION(pkt->li_vn_mode), @@ -557,141 +604,151 @@ receive( * throw the structure away without fear of breaking * anything. */ - if (!is_mystic && skeyid > NTP_MAXKEY) - authtrust(skeyid, 0); if (peer != 0) if (!(peer->flags & FLAG_CONFIG)) unpeer(peer); #ifdef DEBUG if (debug) - printf("match error code %d assoc %d\n", - retcode, peer_associations); + printf("receive: bad protocol %d\n", retcode); #endif return; } /* - * If the peer isn't configured, set his keyid and authenable - * status based on the packet. + * If the peer isn't configured, set his authenable and autokey + * status based on the packet. Once the status is set, it can't + * be unset. It seems like a silly idea to do this here, rather + * in the configuration routine, but in some goofy cases the + * first packet sent cannot be authenticated and we need a way + * for the dude to change his mind. */ oflags = peer->flags; peer->timereceived = current_time; + peer->received++; if (!(peer->flags & FLAG_CONFIG) && has_mac) { peer->flags |= FLAG_AUTHENABLE; - if (skeyid > NTP_MAXKEY) { - if (peer->flags & FLAG_MCAST2) - peer->keyid = skeyid; - else - peer->flags |= FLAG_SKEY; - } +#ifdef AUTOKEY + if (skeyid > NTP_MAXKEY) + peer->flags |= FLAG_SKEY; +#endif /* AUTOKEY */ } /* - * Determine if this guy is basically trustable. If not, flush - * the bugger. If this is the first packet that is - * authenticated, flush the clock filter. This is to foil - * clogging attacks that might starve the poor dear. + * A valid packet must be from an authentic and allowed source. + * All packets must pass the authentication allowed tests. + * Autokey authenticated packets must pass additional tests and + * public-key authenticated packets must have the credentials + * verified. If all tests are passed, the packet is forwarded + * for processing. If not, the packet is discarded and the + * association demobilized if appropriate. */ peer->flash = 0; - if (is_authentic) + if (is_authentic) { peer->flags |= FLAG_AUTHENTIC; - else + peer->tailcnt = 0; + } else { peer->flags &= ~FLAG_AUTHENTIC; - if (peer->hmode == MODE_BROADCAST && (restrict_mask & - RES_DONTTRUST)) - peer->flash |= TEST10; /* access denied */ + } + if (peer->hmode == MODE_BROADCAST && + (restrict_mask & RES_DONTTRUST)) /* test 9 */ + peer->flash |= TEST9; /* access denied */ if (peer->flags & FLAG_AUTHENABLE) { - if (!(peer->flags & FLAG_AUTHENTIC)) + if (!(peer->flags & FLAG_AUTHENTIC)) { /* test 5 */ peer->flash |= TEST5; /* auth failed */ - else if (skeyid == 0) - peer->flash |= TEST9; /* peer not auth */ - else if (!(oflags & FLAG_AUTHENABLE)) { - peer_clear(peer); +#ifdef AUTOKEY + peer->pcookie = 0; +#endif /* AUTOKEY */ + } else if (!(oflags & FLAG_AUTHENABLE)) { report_event(EVNT_PEERAUTH, peer); } } - if ((peer->flash & ~(u_int)TEST9) != 0) { - - /* - * The packet is bogus, so we throw it away before - * becoming a denial-of-service hazard. We don't throw - * the current association away if it is configured or - * if it has prior reachable friends. - */ - if (!is_mystic && skeyid > NTP_MAXKEY) - authtrust(skeyid, 0); - if (!(peer->flags & FLAG_CONFIG) && peer->reach == 0) - unpeer(peer); + if (peer->flash) { #ifdef DEBUG if (debug) - printf( - "invalid packet 0x%02x code %d assoc %d\n", - peer->flash, retcode, peer_associations); + printf("receive: bad packet %03x\n", + peer->flash); #endif return; } -#ifdef MD5 +#ifdef AUTOKEY /* - * The autokey dance. The cha-cha requires that the hash of the - * current session key matches the previous key identifier. - * Heaps of trouble if the steps falter. + * More autokey dance. The rules of the cha-cha are as follows: + * + * 1. If there is no key or the key is not auto, do nothing. + * + * 2. If this is a server reply, check only to see that the + * transmitted key ID matches the received key ID. + * + * 3. If there are no extension fields or if this is a + * broadcast, the cookie is zero. Dance the conga line and + * check to see that one or more hashes of the current key ID + * matches the previous key ID or ultimate original key ID + * obtained from the broadcaster or symmetric peer. If no + * match, arm for an autokey values update. + * + * 4. The only remaining case is where an extension field is + * present and did not contain a verified signature and this + * is a symmetric mode reply. This reply cannot be verified, + * so just let the packet header check kick it out and hope + * the next packet can be verified. */ - if (skeyid > NTP_MAXKEY) { - int i; + if (peer->flags & FLAG_SKEY) { + int i = 0; - /* - * In the case of a new autokey, verify the hash matches - * one of the previous four hashes. If not, raise the - * authentication flasher and hope the next one works. - */ + peer->flash |= TEST10; + crypto_recv(peer, rbufp); if (hismode == MODE_SERVER) { - peer->pkeyid = peer->keyid; - } else if (peer->flags & FLAG_MCAST2) { - if (peer->pkeyid > NTP_MAXKEY) - authtrust(peer->pkeyid, 0); - for (i = 0; i < 4 && tkeyid != peer->pkeyid; - i++) { - tkeyid = session_key( - ntohl((&rbufp->recv_srcadr)->sin_addr.s_addr), - ntohl(rbufp->dstadr->bcast.sin_addr.s_addr), - tkeyid, 0); + if (skeyid == peer->keyid) + peer->flash &= ~TEST10; + } else if (authlen == LEN_PKT_NOMAC || hismode == + MODE_BROADCAST) { + for (i = 0;; i++) { + if (tkeyid == peer->pkeyid || + tkeyid == peer->finlkey) { + peer->flash &= ~TEST10; + peer->pkeyid = skeyid; + break; + } + if (i > peer->finlseq) { + peer->finlseq = 0; + break; + } + if (hismode == MODE_BROADCAST) + tkeyid = session_key( + &rbufp->recv_srcadr, + &rbufp->dstadr->bcast, + tkeyid, pkeyid, 0); + else + tkeyid = session_key( + &rbufp->recv_srcadr, + &rbufp->dstadr->sin, + tkeyid, pkeyid, 0); } - } else { - if (peer->pkeyid > NTP_MAXKEY) - authtrust(peer->pkeyid, 0); - for (i = 0; i < 4 && tkeyid != peer->pkeyid; - i++) { - tkeyid = session_key( - ntohl((&rbufp->recv_srcadr)->sin_addr.s_addr), - ntohl(rbufp->dstadr->sin.sin_addr.s_addr), - tkeyid, 0); +#ifdef PUBKEY + /* + * If the autokey boogie fails, the server may + * be bogus or worse. Raise an alarm and rekey + * this thing. + */ + if (authlen == LEN_PKT_NOMAC) { + if (peer->flash & TEST10) + peer->flags &= ~FLAG_AUTOKEY; + if (!(peer->flags & FLAG_AUTOKEY)) + peer->flash |= TEST11; } +#endif /* PUBKEY */ } -#ifdef XXX /* temp until certificate code is mplemented */ - if (tkeyid != peer->pkeyid) - peer->flash |= TEST9; /* peer not authentic */ -#endif - peer->pkeyid = skeyid; } -#endif /* MD5 */ +#endif /* AUTOKEY */ /* - * Gawdz, it's come to this. Process the dang packet. If - * something breaks and the association doesn't deserve to live, - * toss it. Be careful in active mode and return a packet - * anyway. + * We have survived the gaunt. Forward to the packet routine. If + * a symmetric passive association has been mobilized and the + * association doesn't deserve to live, it will die in the + * transmit routine if not reachable after timeout. */ - process_packet(peer, pkt, &(rbufp->recv_time)); - if (!(peer->flags & FLAG_CONFIG) && peer->reach == 0) { - if (peer->hmode == MODE_PASSIVE) { - if (is_authentic) - fast_xmit(rbufp, MODE_PASSIVE, skeyid); - else - fast_xmit(rbufp, MODE_PASSIVE, 0); - } - unpeer(peer); - } + process_packet(peer, pkt, &rbufp->recv_time); } @@ -701,7 +758,7 @@ receive( * reasonable expectation that we will be having a long term * relationship with this host. */ -int +void process_packet( register struct peer *peer, register struct pkt *pkt, @@ -716,7 +773,10 @@ process_packet( int pmode; /* - * Swap header fields and keep the books. + * Swap header fields and keep the books. The books amount to + * the receive timestamp and poll interval in the header. We + * need these even if there are other problems in order to crank + * up the state machine. */ sys_processed++; peer->processed++; @@ -741,20 +801,17 @@ process_packet( if (L_ISEQU(&peer->org, &p_xmt)) /* test 1 */ peer->flash |= TEST1; /* duplicate packet */ if (PKT_MODE(pkt->li_vn_mode) != MODE_BROADCAST) { - if (!L_ISEQU(&peer->xmt, &p_org)) { /* test 2 */ - peer->bogusorg++; + if (!L_ISEQU(&peer->xmt, &p_org)) /* test 2 */ peer->flash |= TEST2; /* bogus packet */ - } - if (L_ISZERO(&p_rec) || L_ISZERO(&p_org)) - peer->flash |= TEST3; /* unsynchronized */ - } else { - if (L_ISZERO(&p_org)) + if (L_ISZERO(&p_rec) || L_ISZERO(&p_org)) /* test 3 */ peer->flash |= TEST3; /* unsynchronized */ } + if (L_ISZERO(&p_xmt)) /* test 3 */ + peer->flash |= TEST3; /* unsynchronized */ peer->org = p_xmt; /* - * Test for valid header (tests 5 through 10) + * Test for valid packet header (tests 6 through 8) */ ci = p_xmt; L_SUB(&ci, &p_reftime); @@ -765,35 +822,33 @@ process_packet( peer->flash |= TEST6; /* peer clock unsynchronized */ if (!(peer->flags & FLAG_CONFIG) && sys_peer != 0) { /* test 7 */ if (PKT_TO_STRATUM(pkt->stratum) > sys_stratum) { - peer->flash |= TEST7; /* peer stratum too high */ + peer->flash |= TEST7; /* peer stratum too high */ sys_badstratum++; } } - if (fabs(p_del) >= MAXDISPERSE /* test 8 */ + if (fabs(p_del) >= MAXDISPERSE /* test 8 */ || p_disp >= MAXDISPERSE) - peer->flash |= TEST8; /* delay/dispersion too high */ + peer->flash |= TEST8; /* delay/dispersion too high */ /* - * If the packet header is invalid (tests 5 through 10), exit. - * XXX we let TEST9 sneak by until the certificate code is - * implemented, but only to mobilize the association. + * If the packet header is invalid, abandon ship. Otherwise + * capture the header data. */ - if (peer->flash & (TEST5 | TEST6 | TEST7 | TEST8 | TEST10)) { + if (peer->flash & ~(u_int)(TEST1 | TEST2 | TEST3 | TEST4)) { #ifdef DEBUG if (debug) - printf( - "invalid packet header 0x%02x mode %d\n", - peer->flash, pmode); + printf("packet: bad header %03x\n", + peer->flash); #endif - return (0); + return; } /* - * Valid header; update our state. + * The header is valid. Capture the remaining header values and + * mark as reachable. */ record_raw_stats(&peer->srcadr, &peer->dstadr->sin, &p_org, &p_rec, &p_xmt, &peer->rec); - peer->leap = PKT_LEAP(pkt->li_vn_mode); peer->pmode = pmode; /* unspec */ peer->stratum = PKT_TO_STRATUM(pkt->stratum); @@ -849,12 +904,17 @@ process_packet( */ if (pmode == MODE_BROADCAST) { if (peer->flags & FLAG_MCAST1) { - if (peer->hmode == MODE_BCLIENT) - peer->flags &= ~FLAG_MCAST1; LFPTOD(&ci, p_offset); peer->estbdelay = peer->offset - p_offset; - return (1); - + if (peer->hmode != MODE_BCLIENT) { +#ifdef DEBUG + if (debug) + printf("packet: bclient %03x\n", + peer->flash); +#endif + return; + } + peer->flags &= ~FLAG_MCAST1; } DTOLFP(peer->estbdelay, &t10); L_ADD(&ci, &t10); @@ -870,27 +930,22 @@ process_packet( peer->flash |= TEST4; /* delay/dispersion too big */ /* - * If the packet data are invalid (tests 1 through 4), exit. + * If the packet data are invalid (tests 1 through 4), abandon + * ship. Otherwise, forward to the clock filter. */ if (peer->flash) { #ifdef DEBUG if (debug) - printf("invalid packet data 0x%02x mode %d\n", - peer->flash, pmode); + printf("packet: bad data %03x\n", + peer->flash); #endif - return(1); + return; } - - - /* - * This one is valid. Mark it so, give it to clock_filter(). - */ clock_filter(peer, p_offset, p_del, fabs(p_disp)); clock_select(); record_peer_stats(&peer->srcadr, ctlpeerstatus(peer), peer->offset, peer->delay, peer->disp, SQRT(peer->variance)); - return(1); } @@ -983,7 +1038,7 @@ poll_update( int hpoll ) { - long update; + long update, oldpoll; /* * The wiggle-the-poll-interval dance. Broadcasters dance only @@ -992,6 +1047,7 @@ poll_update( * clock. Broadcast clients are usually lead by their broadcast * partner, but faster in the initial mating dance. */ + oldpoll = peer->hpoll; if (peer->hmode == MODE_BROADCAST) { peer->hpoll = peer->minpoll; } else if (peer->flags & FLAG_SYSPEER) { @@ -1018,11 +1074,22 @@ poll_update( peer->minpoll); peer->nextdate = peer->outdate + RANDPOLL(update); } + + /* + * Bit of crass arrogance at this point. If the poll interval + * has changed and we have a keylist, the lifetimes in the + * keylist are probably bogus. In this case purge the keylist + * and regenerate it later. + */ +#ifdef AUTOKEY + if (peer->hpoll != oldpoll) + key_expire(peer); +#endif /* AUTOKEY */ #ifdef DEBUG if (debug > 1) - printf("poll_update: at %lu %s poll %d burst %d last %lu next %lu\n", - current_time, ntoa(&peer->srcadr), hpoll, - peer->burst, peer->outdate, peer->nextdate); + printf("poll_update: at %lu %s flags %04x poll %d burst %d last %lu next %lu\n", + current_time, ntoa(&peer->srcadr), peer->flags, + hpoll, peer->burst, peer->outdate, peer->nextdate); #endif } @@ -1037,6 +1104,40 @@ peer_clear( { register int i; + /* + * If cryptographic credentials have been acquired, toss them to + * Valhalla. Note that autokeys are ephemeral, in that they are + * tossed immediately upon use. Therefore, the keylist can be + * purged anytime without needing to preserve random keys. Note + * that, if the peer is purged, the cryptographic variables are + * purged, too. This makes it much harder to sneak in some + * unauthenticated data in the clock filter. + */ +#ifdef DEBUG + if (debug) + printf("peer_clear: at %ld\n", current_time); +#endif +#ifdef AUTOKEY + key_expire(peer); +#ifdef PUBKEY + if (peer->sign != NULL) + free(peer->sign); + if (peer->dh_public != NULL) + free(peer->dh_public); + if (peer->dh_key != NULL) + free(peer->dh_key); +#endif /* PUBKEY */ +#endif /* AUTOKEY */ + + /* + * If he dies as a multicast client, he comes back to life as + * a multicast client in client mode in order to recover the + * initial autokey values. + */ + if (peer->flags & FLAG_MCAST2) { + peer->flags |= FLAG_MCAST1 | FLAG_BURST; + peer->hmode = MODE_CLIENT; + } memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO); peer->estbdelay = sys_bdelay; peer->hpoll = peer->minpoll; @@ -1073,21 +1174,22 @@ clock_filter( double sample_disp ) { - register int i, j, k, n = 0; + register int i, j, k, n; register u_char *ord; double distance[NTP_SHIFT]; - double x, y, z, off; + double off, dly, var, dsp, dtemp, etemp; /* - * Update error bounds and calculate distances. Also initialize - * sort index vector. + * Update error bounds and calculate distances. The distance for + * each sample is equal to the sample dispersion plus one-half + * the sample delay. Also initialize the sort index vector. */ - x = CLOCK_PHI * (current_time - peer->update); + dtemp = CLOCK_PHI * (current_time - peer->update); peer->update = current_time; ord = peer->filter_order; j = peer->filter_nextpt; for (i = 0; i < NTP_SHIFT; i++) { - peer->filter_disp[j] += x; + peer->filter_disp[j] += dtemp; if (peer->filter_disp[j] > MAXDISPERSE) peer->filter_disp[j] = MAXDISPERSE; distance[i] = fabs(peer->filter_delay[j]) / 2 + @@ -1098,15 +1200,19 @@ clock_filter( } /* - * Insert the new sample at the beginning of the register. + * Shift the new sample into the register and discard the oldest + * one. The new offset and delay come directly from the caller. + * The dispersion from the caller is increased by the sum of the + * precision in the the packet header and the precision of this + * machine. */ peer->filter_offset[peer->filter_nextpt] = sample_offset; peer->filter_delay[peer->filter_nextpt] = sample_delay; - x = LOGTOD(peer->precision) + LOGTOD(sys_precision) + + dsp = LOGTOD(peer->precision) + LOGTOD(sys_precision) + sample_disp; - peer->filter_disp[peer->filter_nextpt] = min(x, MAXDISPERSE); + peer->filter_disp[peer->filter_nextpt] = min(dsp, MAXDISPERSE); peer->filter_epoch[peer->filter_nextpt] = current_time; - distance[0] = min(x + fabs(sample_delay) / 2, MAXDISTANCE); + distance[0] = min(dsp + fabs(sample_delay) / 2, MAXDISTANCE); peer->filter_nextpt++; if (peer->filter_nextpt >= NTP_SHIFT) peer->filter_nextpt = 0; @@ -1116,44 +1222,49 @@ clock_filter( * sample will be in ord[0]. Sort the samples only if they * are younger than the Allen intercept. */ - y = min(allan_xpt, NTP_SHIFT * ULOGTOD(sys_poll)); - for (n = 0; n < NTP_SHIFT && current_time - - peer->filter_epoch[ord[n]] <= y; n++) { + dtemp = min(allan_xpt, NTP_SHIFT * ULOGTOD(sys_poll)); + for (n = 0; n < NTP_SHIFT; n++) { + if (n > 0 && current_time - peer->filter_epoch[ord[n]] > + dtemp) + break; for (j = 0; j < n; j++) { if (distance[j] > distance[n]) { - x = distance[j]; + etemp = distance[j]; k = ord[j]; distance[j] = distance[n]; ord[j] = ord[n]; - distance[n] = x; + distance[n] = etemp; ord[n] = k; } } } /* - * Compute the error bound and standard error. + * Compute the offset, delay, variance (squares) and error + * bound. The offset, delay and variance are weighted by the + * reciprocal of distance and normalized. The error bound is + * weighted exponentially. */ - x = y = z = off = 0.; + off = dly = var = dsp = dtemp = 0; for (i = NTP_SHIFT - 1; i >= 0; i--) { - x = NTP_FWEIGHT * (x + peer->filter_disp[ord[i]]); - if (i < n) { - z += 1. / distance[i]; + dsp = NTP_FWEIGHT * (dsp + peer->filter_disp[ord[i]]); + if (i < n && distance[i] < MAXDISTANCE) { + dtemp += 1. / distance[i]; off += peer->filter_offset[ord[i]] / distance[i]; - y += DIFF(peer->filter_offset[ord[i]], - peer->filter_offset[ord[0]]); + dly += peer->filter_delay[ord[i]] / + distance[i]; + var += DIFF(peer->filter_offset[ord[i]], + peer->filter_offset[ord[0]]) / + SQUARE(distance[i]); } } - peer->delay = peer->filter_delay[ord[0]]; - peer->variance = min(y / n, MAXDISPERSE); - peer->disp = min(x, MAXDISPERSE); + peer->delay = dly / dtemp; + peer->variance = min(var / SQUARE(dtemp), MAXDISPERSE); + peer->disp = min(dsp, MAXDISPERSE); peer->epoch = current_time; - x = peer->offset; - if (peer->flags & FLAG_BURST) - peer->offset = off / z; - else - peer->offset = peer->filter_offset[ord[0]]; + etemp = peer->offset; + peer->offset = off / dtemp; /* * A new sample is useful only if it is younger than the last @@ -1174,15 +1285,21 @@ clock_filter( * poll interval, consider the update a popcorn spike and ignore * it. */ - if (fabs(x - peer->offset) > CLOCK_SGATE && + if (fabs(etemp - peer->offset) > CLOCK_SGATE && peer->filter_epoch[ord[0]] - peer->epoch < (1 << (sys_poll + 1))) { #ifdef DEBUG if (debug) - printf("clock_filter: popcorn spike %.6f\n", x); + printf("clock_filter: popcorn spike %.6f\n", + off); #endif return; } + + /* + * The mitigated sample statistics are saved for later + * processing, but can be processed only once. + */ peer->epoch = peer->filter_epoch[ord[0]]; peer->pollsw = TRUE; #ifdef DEBUG @@ -1219,10 +1336,10 @@ clock_select(void) static int list_alloc = 0; static struct endpoint *endpoint = NULL; - static int *index = NULL; + static int *indx = NULL; static struct peer **peer_list = NULL; static u_int endpoint_size = 0; - static u_int index_size = 0; + static u_int indx_size = 0; static u_int peer_list_size = 0; /* @@ -1238,17 +1355,17 @@ clock_select(void) if (nlist > list_alloc) { if (list_alloc > 0) { free(endpoint); - free(index); + free(indx); free(peer_list); } while (list_alloc < nlist) { list_alloc += 5; endpoint_size += 5 * 3 * sizeof *endpoint; - index_size += 5 * 3 * sizeof *index; + indx_size += 5 * 3 * sizeof *indx; peer_list_size += 5 * sizeof *peer_list; } endpoint = (struct endpoint *)emalloc(endpoint_size); - index = (int *)emalloc(index_size); + indx = (int *)emalloc(indx_size); peer_list = (struct peer **)emalloc(peer_list_size); } @@ -1313,40 +1430,41 @@ clock_select(void) f = root_distance(peer); e = e + f; for (i = nl3 - 1; i >= 0; i--) { - if (e >= endpoint[index[i]].val) + if (e >= endpoint[indx[i]].val) break; - index[i + 3] = index[i]; + indx[i + 3] = indx[i]; } - index[i + 3] = nl3; + indx[i + 3] = nl3; endpoint[nl3].type = 1; endpoint[nl3++].val = e; e = e - f; /* Center point */ for ( ; i >= 0; i--) { - if (e >= endpoint[index[i]].val) + if (e >= endpoint[indx[i]].val) break; - index[i + 2] = index[i]; + indx[i + 2] = indx[i]; } - index[i + 2] = nl3; + indx[i + 2] = nl3; endpoint[nl3].type = 0; endpoint[nl3++].val = e; e = e - f; /* Lower end */ for ( ; i >= 0; i--) { - if (e >= endpoint[index[i]].val) + if (e >= endpoint[indx[i]].val) break; - index[i + 1] = index[i]; + indx[i + 1] = indx[i]; } - index[i + 1] = nl3; + indx[i + 1] = nl3; endpoint[nl3].type = -1; endpoint[nl3++].val = e; } } #ifdef DEBUG - if (debug > 1) + if (debug > 2) for (i = 0; i < nl3; i++) - printf("select: endpoint %2d %.6f\n", - endpoint[index[i]].type, endpoint[index[i]].val); + printf("select: endpoint %2d %.6f\n", + endpoint[indx[i]].type, + endpoint[indx[i]].val); #endif i = 0; j = nl3 - 1; @@ -1355,23 +1473,23 @@ clock_select(void) while (allow > 0) { allow--; for (n = 0; i <= j; i++) { - n += endpoint[index[i]].type; + n += endpoint[indx[i]].type; if (n < 0) break; - if (endpoint[index[i]].type == 0) + if (endpoint[indx[i]].type == 0) found++; } for (n = 0; i <= j; j--) { - n += endpoint[index[j]].type; + n += endpoint[indx[j]].type; if (n > 0) break; - if (endpoint[index[j]].type == 0) + if (endpoint[indx[j]].type == 0) found++; } if (found > allow) break; - low = endpoint[index[i++]].val; - high = endpoint[index[j--]].val; + low = endpoint[indx[i++]].val; + high = endpoint[indx[j--]].val; } /* @@ -1402,7 +1520,7 @@ clock_select(void) } } #ifdef DEBUG - if (debug > 1) + if (debug > 2) printf("select: low %.6f high %.6f\n", low, high); #endif @@ -1439,7 +1557,7 @@ clock_select(void) nlist = j; #ifdef DEBUG - if (debug > 1) + if (debug > 2) for (i = 0; i < nlist; i++) printf("select: %s distance %.6f\n", ntoa(&peer_list[i]->srcadr), synch[i]); @@ -1479,7 +1597,7 @@ clock_select(void) } #ifdef DEBUG - if (debug > 1) + if (debug > 2) printf( "select: survivors %d select %.6f peer %.6f\n", nlist, SQRT(sys_maxd), SQRT(d)); @@ -1494,7 +1612,7 @@ clock_select(void) nlist--; } #ifdef DEBUG - if (debug > 1) { + if (debug > 2) { for (i = 0; i < nlist; i++) printf( "select: %s offset %.6f, distance %.6f poll %d\n", @@ -1563,7 +1681,7 @@ clock_select(void) sys_offset = sys_peer->offset; sys_epsil = sys_peer->variance; #ifdef DEBUG - if (debug > 1) + if (debug > 2) printf("select: prefer offset %.6f\n", sys_offset); #endif @@ -1577,7 +1695,7 @@ clock_select(void) msyslog(LOG_INFO, "pps sync enabled"); pps_control = current_time; #ifdef DEBUG - if (debug > 1) + if (debug > 2) printf("select: pps offset %.6f\n", sys_offset); #endif } else { @@ -1587,7 +1705,7 @@ clock_select(void) sys_offset = clock_combine(peer_list, nlist); sys_epsil = sys_peer->variance + sys_maxd; #ifdef DEBUG - if (debug > 1) + if (debug > 2) printf("select: combine offset %.6f\n", sys_offset); #endif @@ -1639,279 +1757,449 @@ peer_xmit( struct peer *peer /* peer structure pointer */ ) { - struct pkt xpkt; + struct pkt xpkt; /* transmit packet */ int find_rtt = (peer->cast_flags & MDF_MCAST) && - peer->hmode != MODE_BROADCAST; - int sendlen; + peer->hmode != MODE_BROADCAST; + int sendlen, pktlen; + keyid_t xkeyid; /* transmit key ID */ + l_fp xmt_tx; /* - * Initialize protocol fields. + * Initialize transmit packet header fields. */ - xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, - peer->version, peer->hmode); + xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, peer->version, + peer->hmode); xpkt.stratum = STRATUM_TO_PKT(sys_stratum); xpkt.ppoll = peer->hpoll; xpkt.precision = sys_precision; xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); xpkt.rootdispersion = HTONS_FP(DTOUFP(sys_rootdispersion + - LOGTOD(sys_precision))); + LOGTOD(sys_precision))); xpkt.refid = sys_refid; HTONL_FP(&sys_reftime, &xpkt.reftime); HTONL_FP(&peer->org, &xpkt.org); HTONL_FP(&peer->rec, &xpkt.rec); /* - * Authenticate the packet if enabled and either configured or - * the previous packet was authenticated. If for some reason the - * key associated with the key identifier is not in the key - * cache, then honk key zero. + * If the received packet contains a MAC, the transmitted packet + * is authenticated and contains a MAC. If not, the transmitted + * packet is not authenticated. + * + * In the current I/O semantics we can't find the local + * interface address to generate a session key until after + * receiving a packet. So, the first packet goes out + * unauthenticated. That's why the really icky test next is + * here. */ sendlen = LEN_PKT_NOMAC; - if (peer->flags & FLAG_AUTHENABLE) { - u_long xkeyid; - l_fp xmt_tx; - - /* - * Transmit encrypted packet compensated for the - * encryption delay. - */ -#ifdef MD5 - if (peer->flags & FLAG_SKEY) { - - /* - * In autokey mode, allocate and initialize a - * key list if not already done. Then, use the - * list in inverse order, discarding keys once - * used. Keep the latest key around until the - * next one, so clients can use client/server - * packets to compute propagation delay. Note we - * have to wait until the receive side of the - * socket is bound and the server address - * confirmed. - */ - if (ntohl(peer->dstadr->sin.sin_addr.s_addr) == - 0 && - ntohl(peer->dstadr->bcast.sin_addr.s_addr) == 0) - peer->keyid = 0; - else { - if (peer->keylist == 0) { - make_keylist(peer); - } else { - authtrust(peer->keylist[peer->keynumber], 0); - if (peer->keynumber == 0) - make_keylist(peer); - else { - peer->keynumber--; - xkeyid = peer->keylist[peer->keynumber]; - if (!authistrusted(xkeyid)) - make_keylist(peer); - } - } - peer->keyid = peer->keylist[peer->keynumber]; - xpkt.keyid1 = htonl(2 * sizeof(u_int32)); - xpkt.keyid2 = htonl(sys_private); - sendlen += 2 * sizeof(u_int32); - } - } -#endif /* MD5 */ - xkeyid = peer->keyid; + if (!(peer->flags & FLAG_AUTHENABLE) || + (peer->dstadr->sin.sin_addr.s_addr == 0 && + peer->dstadr->bcast.sin_addr.s_addr == 0)) { get_systime(&peer->xmt); - L_ADD(&peer->xmt, &sys_authdelay); HTONL_FP(&peer->xmt, &xpkt.xmt); - sendlen += authencrypt(xkeyid, (u_int32 *)&xpkt, - sendlen); - get_systime(&xmt_tx); sendpkt(&peer->srcadr, find_rtt ? any_interface : peer->dstadr, ((peer->cast_flags & MDF_MCAST) && !find_rtt) ? ((peer->cast_flags & MDF_ACAST) ? -7 : - peer->ttl) : -7, &xpkt, sendlen); - - /* - * Calculate the encryption delay. Keep the minimum over - * the latest two samples. - */ - L_SUB(&xmt_tx, &peer->xmt); - L_ADD(&xmt_tx, &sys_authdelay); - sys_authdly[1] = sys_authdly[0]; - sys_authdly[0] = xmt_tx.l_uf; - if (sys_authdly[0] < sys_authdly[1]) - sys_authdelay.l_uf = sys_authdly[0]; - else - sys_authdelay.l_uf = sys_authdly[1]; + peer->ttl) : -8, &xpkt, sendlen); peer->sent++; #ifdef DEBUG if (debug) - printf( - "transmit: at %ld to %s mode %d keyid %08lx index %d\n", + printf("transmit: at %ld %s mode %d\n", current_time, ntoa(&peer->srcadr), - peer->hmode, xkeyid, peer->keynumber); + peer->hmode); #endif - } else { + return; + } + + /* + * The received packet contains a MAC, so the transmitted packet + * must be authenticated. If autokey is enabled, fuss with the + * various modes; otherwise, private key cryptography is used. + */ +#ifdef AUTOKEY + if ((peer->flags & FLAG_SKEY)) { + u_int cmmd; + /* - * Transmit non-authenticated packet. + * The Public Key Dance (PKD): Cryptographic credentials + * are contained in extension fields, each including a + * 4-octet length/code word followed by a 4-octet + * association ID and optional additional data. Optional + * data includes a 4-octet data length field followd by + * the data itself. Request messages are sent from a + * configured association; response messages can be sent + * from a configured association or can take the fast + * path without ever matching an association. Response + * messages have the same code as the request, but have + * a response bit and possibly an error bit set. In this + * implementation, a message may contain no more than + * one command and no more than one response. + * + * Cryptographic session keys include both a public and + * a private componet. Request and response messages + * using extension fields are always sent with the + * private component set to zero. Packets without + * extension fields indlude the private component when + * the session key is generated. */ - get_systime(&(peer->xmt)); - HTONL_FP(&peer->xmt, &xpkt.xmt); - sendpkt(&(peer->srcadr), find_rtt ? any_interface : - peer->dstadr, ((peer->cast_flags & MDF_MCAST) && - !find_rtt) ? ((peer->cast_flags & MDF_ACAST) ? -7 : - peer->ttl) : -8, &xpkt, sendlen); - peer->sent++; + while (1) { + + /* + * Allocate and initialize a keylist if not + * already done. Then, use the list in inverse + * order, discarding keys once used. Keep the + * latest key around until the next one, so + * clients can use client/server packets to + * compute propagation delay. + * + * Note that once a key is used from the list, + * it is retained in the key cache until the + * next key is used. This is to allow a client + * to retrieve the encrypted session key + * identifier to verify authenticity. + * + * If for some reason a key is no longer in the + * key cache, a birthday has happened and the + * pseudo-random sequence is probably broken. In + * that case, purge the keylist and regenerate + * it. + */ + if (peer->keynumber == 0) + make_keylist(peer); + else + peer->keynumber--; + xkeyid = peer->keylist[peer->keynumber]; + if (authistrusted(xkeyid)) + break; + else + key_expire(peer); + } + peer->keyid = xkeyid; + switch (peer->hmode) { + + /* + * In broadcast mode and a new keylist; otherwise, send + * the association ID so the client can request the + * values at other times. + */ + case MODE_BROADCAST: + if (peer->keynumber == peer->lastseq) + cmmd = CRYPTO_AUTO | CRYPTO_RESP; + else + cmmd = CRYPTO_ASSOC | CRYPTO_RESP; + sendlen += crypto_xmit((u_int32 *)&xpkt, + sendlen, cmmd, peer->hcookie, + peer->associd); + break; + + /* + * In symmetric modes the public key, Diffie-Hellman + * values and autokey values are required. In principle, + * these values can be provided in any order; however, + * the protocol is most efficient if the values are + * provided in the order listed. This happens with the + * following rules: + * + * 1. Don't send anything except a public-key request or + * a public-key response until the public key has + * been stored. + * + * 2. If a public-key response is pending, always send + * it first before any other command or response. + * + * 3. Once the public key has been stored, don't send + * anything except Diffie-Hellman commands or + * responses until the agreed key has been stored. + * + * 4. If a Diffie-Hellman response is pending, always + * send it last after any other command or response. + * + * 5. When the agreed key has been stored and the key + * list is regenerated, send the autokey values + * gratis. + */ + case MODE_ACTIVE: + case MODE_PASSIVE: + if (peer->cmmd != 0 && peer->cmmd >> 16 != + CRYPTO_DH) { + sendlen += crypto_xmit((u_int32 *)&xpkt, + sendlen, (peer->cmmd >> 16) | + CRYPTO_RESP, peer->hcookie, + peer->associd); + peer->cmmd = 0; + } +#ifdef PUBKEY + if (peer->pubkey == 0) { + sendlen += crypto_xmit((u_int32 *)&xpkt, + sendlen, CRYPTO_PUBL, peer->hcookie, + peer->assoc); + } else if (peer->pcookie == 0) { + sendlen += crypto_xmit((u_int32 *)&xpkt, + sendlen, CRYPTO_DH, peer->hcookie, + peer->assoc); + } else +#endif /* PUBKEY */ + if (peer->finlseq == 0) { + sendlen += crypto_xmit((u_int32 *)&xpkt, + sendlen, CRYPTO_AUTO, peer->hcookie, + peer->assoc); + } else if (peer->keynumber == peer->lastseq) { + sendlen += crypto_xmit((u_int32 *)&xpkt, + sendlen, CRYPTO_AUTO | CRYPTO_RESP, + peer->hcookie, peer->associd); + } + if (peer->cmmd != 0) { + sendlen += crypto_xmit((u_int32 *)&xpkt, + sendlen, (peer->cmmd >> 16) | + CRYPTO_RESP, peer->hcookie, + peer->associd); + peer->cmmd = 0; + } + break; + + /* + * In client mode, the public key, host cookie and + * autokey values are required. In broadcast client + * mode, these values must be acquired during the + * client/server exchange to avoid having to wait until + * the next key list regeneration. Otherwise, the poor + * dude may die a lingering death until becoming + * unreachable and attempting rebirth. + */ + case MODE_CLIENT: + if (peer->cmmd != 0) { + sendlen += crypto_xmit((u_int32 *)&xpkt, + sendlen, (peer->cmmd >> 16) | + CRYPTO_RESP, peer->hcookie, + peer->associd); + peer->cmmd = 0; + } +#ifdef PUBKEY + if (peer->pubkey == 0) { + sendlen += crypto_xmit((u_int32 *)&xpkt, + sendlen, CRYPTO_PUBL, peer->hcookie, + peer->assoc); + } else +#endif /* PUBKEY */ + if (peer->pcookie == 0) { + sendlen += crypto_xmit((u_int32 *)&xpkt, + sendlen, CRYPTO_PRIV, peer->hcookie, + peer->assoc); + } else if (peer->finlseq == 0 && peer->flags & + FLAG_MCAST2) { + sendlen += crypto_xmit((u_int32 *)&xpkt, + sendlen, CRYPTO_AUTO, peer->hcookie, + peer->assoc); + } + break; + } + + /* + * If extension fields are present, we must use a + * private value of zero. Most intricate. + */ + if (sendlen > LEN_PKT_NOMAC) + session_key(&peer->dstadr->sin, + (peer->hmode == MODE_BROADCAST) ? + &peer->dstadr->bcast : &peer->srcadr, + xkeyid, 0, 2); + } +#endif /* AUTOKEY */ + xkeyid = peer->keyid; + get_systime(&peer->xmt); + L_ADD(&peer->xmt, &sys_authdelay); + HTONL_FP(&peer->xmt, &xpkt.xmt); + pktlen = sendlen + authencrypt(xkeyid, (u_int32 *)&xpkt, + sendlen); +#ifdef AUTOKEY + if (xkeyid > NTP_MAXKEY) + authtrust(xkeyid, 0); +#endif /* AUTOKEY */ + get_systime(&xmt_tx); + sendpkt(&peer->srcadr, find_rtt ? any_interface : peer->dstadr, + ((peer->cast_flags & MDF_MCAST) && !find_rtt) ? + ((peer->cast_flags & MDF_ACAST) ? -7 : peer->ttl) : -7, + &xpkt, pktlen); + + /* + * Calculate the encryption delay. Keep the minimum over + * the latest two samples. + */ + L_SUB(&xmt_tx, &peer->xmt); + L_ADD(&xmt_tx, &sys_authdelay); + sys_authdly[1] = sys_authdly[0]; + sys_authdly[0] = xmt_tx.l_uf; + if (sys_authdly[0] < sys_authdly[1]) + sys_authdelay.l_uf = sys_authdly[0]; + else + sys_authdelay.l_uf = sys_authdly[1]; + peer->sent++; +#ifdef AUTOKEY #ifdef DEBUG - if (debug) - printf("transmit: at %ld to %s mode %d\n", - current_time, ntoa(&peer->srcadr), - peer->hmode); + if (debug) + printf( + "transmit: at %ld %s mode %d keyid %08x len %d mac %d index %d\n", + current_time, ntoa(&peer->srcadr), peer->hmode, + xkeyid, sendlen, pktlen - sendlen, peer->keynumber); #endif - } +#else +#ifdef DEBUG + if (debug) + printf( + "transmit: at %ld %s mode %d keyid %08x len %d mac %d\n", + current_time, ntoa(&peer->srcadr), peer->hmode, + xkeyid, sendlen, pktlen - sendlen); +#endif +#endif /* AUTOKEY */ } + /* - * fast_xmit - Send packet for nonpersistent association. + * fast_xmit - Send packet for nonpersistent association. Note that + * neither the source or destination can be a broadcast address. */ static void fast_xmit( struct recvbuf *rbufp, /* receive packet pointer */ int xmode, /* transmit mode */ - u_long xkeyid /* transmit key ID */ + keyid_t xkeyid /* transmit key ID */ ) { - struct pkt xpkt; - struct pkt *rpkt; - int sendlen; - l_fp xmt_ts; + struct pkt xpkt; /* transmit packet structure */ + struct pkt *rpkt; /* receive packet structure */ + l_fp xmt_ts; /* transmit timestamp */ + l_fp xmt_tx; /* transmit timestamp after authent */ + int sendlen, pktlen; /* - * Initialize transmit packet header fields in the receive + * Initialize transmit packet header fields from the receive * buffer provided. We leave some fields intact as received. */ rpkt = &rbufp->recv_pkt; xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, - PKT_VERSION(rpkt->li_vn_mode), xmode); + PKT_VERSION(rpkt->li_vn_mode), xmode); xpkt.stratum = STRATUM_TO_PKT(sys_stratum); xpkt.ppoll = rpkt->ppoll; xpkt.precision = sys_precision; xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); xpkt.rootdispersion = HTONS_FP(DTOUFP(sys_rootdispersion + - LOGTOD(sys_precision))); + LOGTOD(sys_precision))); xpkt.refid = sys_refid; HTONL_FP(&sys_reftime, &xpkt.reftime); xpkt.org = rpkt->xmt; HTONL_FP(&rbufp->recv_time, &xpkt.rec); - sendlen = LEN_PKT_NOMAC; - if (rbufp->recv_length > sendlen) { - l_fp xmt_tx; - /* - * Transmit encrypted packet compensated for the - * encryption delay. - */ - if (xkeyid > NTP_MAXKEY) { - xpkt.keyid1 = htonl(2 * sizeof(u_int32)); - xpkt.keyid2 = htonl(sys_private); - sendlen += 2 * sizeof(u_int32); - } + /* + * If the received packet contains a MAC, the transmitted packet + * is authenticated and contains a MAC. If not, the transmitted + * packet is not authenticated. + */ + sendlen = LEN_PKT_NOMAC; + if (rbufp->recv_length == sendlen) { get_systime(&xmt_ts); - L_ADD(&xmt_ts, &sys_authdelay); HTONL_FP(&xmt_ts, &xpkt.xmt); - sendlen += authencrypt(xkeyid, (u_int32 *)&xpkt, - sendlen); - get_systime(&xmt_tx); - sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, -9, &xpkt, + sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, -10, &xpkt, sendlen); - - /* - * Calculate the encryption delay. Keep the minimum over - * the latest two samples. - */ - L_SUB(&xmt_tx, &xmt_ts); - L_ADD(&xmt_tx, &sys_authdelay); - sys_authdly[1] = sys_authdly[0]; - sys_authdly[0] = xmt_tx.l_uf; - if (sys_authdly[0] < sys_authdly[1]) - sys_authdelay.l_uf = sys_authdly[0]; - else - sys_authdelay.l_uf = sys_authdly[1]; #ifdef DEBUG if (debug) - printf( - "transmit: at %ld to %s mode %d keyid %08lx\n", - current_time, ntoa(&rbufp->recv_srcadr), - xmode, xkeyid); + printf("transmit: at %ld %s mode %d\n", + current_time, ntoa(&rbufp->recv_srcadr), + xmode); #endif - } else { + return; + } - /* - * Transmit non-authenticated packet. - */ - get_systime(&xmt_ts); - HTONL_FP(&xmt_ts, &xpkt.xmt); - sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, -10, &xpkt, - sendlen); + /* + * The received packet contains a MAC, so the transmitted packet + * must be authenticated. For private-key cryptography, use the + * the public and private values to generate the cookie, which + * is unique for every source-destination-key ID combination. If + * an extension field is present, do what needs, but with + * private value of zero so the poor jerk can decode it. If no + * extension field is present, use the cookie to generate the + * session key. + */ +#ifdef AUTOKEY + if (xkeyid > NTP_MAXKEY) { + keyid_t cookie; + u_int code; + + if (xmode == MODE_SERVER) + cookie = session_key(&rbufp->recv_srcadr, + &rbufp->dstadr->sin, 0, sys_private, 0); + else + cookie = session_key(&rbufp->dstadr->sin, + &rbufp->recv_srcadr, 0, sys_private, 0); + if (rbufp->recv_length >= sendlen + MAX_MAC_LEN + 2 * + sizeof(u_int32)) { + session_key(&rbufp->dstadr->sin, + &rbufp->recv_srcadr, xkeyid, 0, 2); + code = (htonl(rpkt->exten[0]) >> 16) | + CRYPTO_RESP; + sendlen += crypto_xmit((u_int32 *)&xpkt, + sendlen, code, cookie, + (int)htonl(rpkt->exten[1])); + } else { + session_key(&rbufp->dstadr->sin, + &rbufp->recv_srcadr, xkeyid, cookie, 2); + } + } +#endif /* AUTOKEY */ + get_systime(&xmt_ts); + L_ADD(&xmt_ts, &sys_authdelay); + HTONL_FP(&xmt_ts, &xpkt.xmt); + pktlen = sendlen + authencrypt(xkeyid, (u_int32 *)&xpkt, + sendlen); +#ifdef AUTOKEY + if (xkeyid > NTP_MAXKEY) + authtrust(xkeyid, 0); +#endif /* AUTOKEY */ + get_systime(&xmt_tx); + sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, -9, &xpkt, pktlen); + + /* + * Calculate the encryption delay. Keep the minimum over the + * latest two samples. + */ + L_SUB(&xmt_tx, &xmt_ts); + L_ADD(&xmt_tx, &sys_authdelay); + sys_authdly[1] = sys_authdly[0]; + sys_authdly[0] = xmt_tx.l_uf; + if (sys_authdly[0] < sys_authdly[1]) + sys_authdelay.l_uf = sys_authdly[0]; + else + sys_authdelay.l_uf = sys_authdly[1]; #ifdef DEBUG - if (debug) - printf("transmit: at %ld to %s mode %d\n", - current_time, ntoa(&rbufp->recv_srcadr), - xmode); + if (debug) + printf( + "transmit: at %ld %s mode %d keyid %08x len %d mac %d\n", + current_time, ntoa(&rbufp->recv_srcadr), + xmode, xkeyid, sendlen, pktlen - sendlen); #endif - } } -#ifdef MD5 + +#ifdef AUTOKEY /* - * Compute key list + * key_expire - purge the key list */ -static void -make_keylist( - struct peer *peer +void +key_expire( + struct peer *peer /* peer structure pointer */ ) { int i; - u_long keyid; - u_long ltemp; - /* - * Allocate the key list if necessary. - */ - if (peer->keylist == 0) - peer->keylist = (u_long *)emalloc(sizeof(u_long) * - NTP_MAXSESSION); - - /* - * Generate an initial key ID which is unique and greater than - * NTP_MAXKEY. - */ - while (1) { - keyid = (u_long)RANDOM & 0xffffffff; - if (keyid <= NTP_MAXKEY) - continue; - if (authhavekey(keyid)) - continue; - break; - } - - /* - * Generate up to NTP_MAXSESSION session keys. Stop if the - * next one would not be unique or not a session key ID or if - * it would expire before the next poll. - */ - ltemp = sys_automax; - for (i = 0; i < NTP_MAXSESSION; i++) { - peer->keylist[i] = keyid; - peer->keynumber = i; - keyid = session_key( - ntohl(peer->dstadr->sin.sin_addr.s_addr), - (peer->hmode == MODE_BROADCAST || (peer->flags & - FLAG_MCAST2)) ? - ntohl(peer->dstadr->bcast.sin_addr.s_addr): - ntohl(peer->srcadr.sin_addr.s_addr), keyid, ltemp); - ltemp -= 1 << peer->hpoll; - if (auth_havekey(keyid) || keyid <= NTP_MAXKEY || - ltemp <= (1 << (peer->hpoll + 1))) - break; + if (peer->keylist != NULL) { + for (i = 0; i <= peer->keynumber; i++) + authtrust(peer->keylist[i], 0); + free(peer->keylist); + peer->keylist = NULL; } + peer->keynumber = peer->lastseq = 0; + peer->lastkey = 0; } -#endif /* MD5 */ +#endif /* AUTOKEY */ /* * Find the precision of this particular machine @@ -2055,7 +2343,9 @@ init_proto(void) sys_processed = 0; sys_badauth = 0; sys_manycastserver = 0; +#ifdef AUTOKEY sys_automax = 1 << NTP_AUTOMAX; +#endif /* AUTOKEY */ /* * Default these to enable diff --git a/ntpd/ntp_request.c b/ntpd/ntp_request.c index eb4b37bc1e..cdadf72b07 100644 --- a/ntpd/ntp_request.c +++ b/ntpd/ntp_request.c @@ -60,6 +60,7 @@ static void mem_stats P((struct sockaddr_in *, struct interface *, struct req_pk static void io_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *)); static void timer_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *)); static void loop_info P((struct sockaddr_in *, struct interface *, struct req_pkt *)); +static void dns_a P((struct sockaddr_in *, struct interface *, struct req_pkt *)); static void do_conf P((struct sockaddr_in *, struct interface *, struct req_pkt *)); static void do_unconf P((struct sockaddr_in *, struct interface *, struct req_pkt *)); static void set_sys_flag P((struct sockaddr_in *, struct interface *, struct req_pkt *)); @@ -77,7 +78,7 @@ static void reset_peer P((struct sockaddr_in *, struct interface *, struct req_p static void do_key_reread P((struct sockaddr_in *, struct interface *, struct req_pkt *)); static void trust_key P((struct sockaddr_in *, struct interface *, struct req_pkt *)); static void untrust_key P((struct sockaddr_in *, struct interface *, struct req_pkt *)); -static void do_trustkey P((struct sockaddr_in *, struct interface *, struct req_pkt *, int)); +static void do_trustkey P((struct sockaddr_in *, struct interface *, struct req_pkt *, u_long)); static void get_auth_info P((struct sockaddr_in *, struct interface *, struct req_pkt *)); static void reset_auth_stats P((void)); static void req_get_traps P((struct sockaddr_in *, struct interface *, struct req_pkt *)); @@ -112,6 +113,7 @@ static struct req_proc ntp_codes[] = { { REQ_MEM_STATS, NOAUTH, 0, mem_stats }, { REQ_LOOP_INFO, NOAUTH, 0, loop_info }, { REQ_TIMER_STATS, NOAUTH, 0, timer_stats }, + { REQ_HOSTNAME_ASSOCID, AUTH, sizeof(struct info_dns_assoc), dns_a }, { REQ_CONFIG, AUTH, sizeof(struct conf_peer), do_conf }, { REQ_UNCONFIG, AUTH, sizeof(struct conf_unpeer), do_unconf }, { REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), set_sys_flag }, @@ -150,7 +152,7 @@ static struct req_proc ntp_codes[] = { * Authentication keyid used to authenticate requests. Zero means we * don't allow writing anything. */ -u_long info_auth_keyid; +keyid_t info_auth_keyid; /* * Statistic counters to keep track of requests and responses. @@ -533,7 +535,8 @@ process_private( if (proc->sizeofitem != 0) if (proc->sizeofitem*INFO_NITEMS(inpkt->err_nitems) > sizeof(inpkt->data)) { - msyslog(LOG_ERR, "sizeofitem*NITEMS > data: %d > %d", + msyslog(LOG_ERR, "sizeofitem(%d)*NITEMS(%d) > data: %d > %d", + proc->sizeofitem, INFO_NITEMS(inpkt->err_nitems), proc->sizeofitem*INFO_NITEMS(inpkt->err_nitems), sizeof(inpkt->data)); req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); @@ -619,14 +622,16 @@ peer_list_sum( if (debug > 3) printf("sum: got one\n"); #endif - ips->dstadr = (pp->processed) ? - pp->cast_flags == MDF_BCAST ? - pp->dstadr->bcast.sin_addr.s_addr: - pp->cast_flags ? - pp->dstadr->sin.sin_addr.s_addr ? - pp->dstadr->sin.sin_addr.s_addr: - pp->dstadr->bcast.sin_addr.s_addr: - 1 : 5; + ips->dstadr = + (pp->processed) + ? pp->cast_flags == MDF_BCAST + ? pp->dstadr->bcast.sin_addr.s_addr + : pp->cast_flags + ? pp->dstadr->sin.sin_addr.s_addr + ? pp->dstadr->sin.sin_addr.s_addr + : pp->dstadr->bcast.sin_addr.s_addr + : 1 + : 5; ips->srcadr = pp->srcadr.sin_addr.s_addr; ips->srcport = pp->srcadr.sin_port; ips->stratum = pp->stratum; @@ -695,14 +700,16 @@ peer_info ( ipl++; if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0) continue; - ip->dstadr = (pp->processed) ? - pp->cast_flags == MDF_BCAST ? - pp->dstadr->bcast.sin_addr.s_addr: - pp->cast_flags ? - pp->dstadr->sin.sin_addr.s_addr ? - pp->dstadr->sin.sin_addr.s_addr: - pp->dstadr->bcast.sin_addr.s_addr: - 2 : 6; + ip->dstadr = + (pp->processed) + ? pp->cast_flags == MDF_BCAST + ? pp->dstadr->bcast.sin_addr.s_addr + : pp->cast_flags + ? pp->dstadr->sin.sin_addr.s_addr + ? pp->dstadr->sin.sin_addr.s_addr + : pp->dstadr->bcast.sin_addr.s_addr + : 2 + : 6; ip->srcadr = NSRCADR(&pp->srcadr); ip->srcport = NSRCPORT(&pp->srcadr); ip->flags = 0; @@ -797,14 +804,16 @@ peer_stats ( ipl++; if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0) continue; - ip->dstadr = (pp->processed) ? - pp->cast_flags == MDF_BCAST ? - pp->dstadr->bcast.sin_addr.s_addr: - pp->cast_flags ? - pp->dstadr->sin.sin_addr.s_addr ? - pp->dstadr->sin.sin_addr.s_addr: - pp->dstadr->bcast.sin_addr.s_addr: - 3 : 7; + ip->dstadr = + (pp->processed) + ? pp->cast_flags == MDF_BCAST + ? pp->dstadr->bcast.sin_addr.s_addr + : pp->cast_flags + ? pp->dstadr->sin.sin_addr.s_addr + ? pp->dstadr->sin.sin_addr.s_addr + : pp->dstadr->bcast.sin_addr.s_addr + : 3 + : 7; ip->srcadr = NSRCADR(&pp->srcadr); ip->srcport = NSRCPORT(&pp->srcadr); ip->flags = 0; @@ -1198,8 +1207,8 @@ do_conf( peeraddr.sin_addr.s_addr = cp->peeraddr; /* XXX W2DO? minpoll/maxpoll arguments ??? */ if (peer_config(&peeraddr, (struct interface *)0, - cp->hmode, cp->version, cp->minpoll, cp->maxpoll, - fl, cp->ttl, cp->keyid) == 0) { + cp->hmode, cp->version, cp->minpoll, cp->maxpoll, + fl, cp->ttl, cp->keyid, cp->keystr) == 0) { req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); return; } @@ -1210,6 +1219,86 @@ do_conf( } +/* + * dns_a - Snarf DNS info for an association ID + */ +static void +dns_a( + struct sockaddr_in *srcadr, + struct interface *inter, + struct req_pkt *inpkt + ) +{ + register struct info_dns_assoc *dp; + register int items; + struct sockaddr_in peeraddr; + int fl; + + msyslog(LOG_DEBUG, "dns_a: We're here..."); + /* + * Do a check of everything to see that it looks + * okay. If not, complain about it. Note we are + * very picky here. + */ + items = INFO_NITEMS(inpkt->err_nitems); + dp = (struct info_dns_assoc *)inpkt->data; + + /* + * Looks okay, try it out + */ + items = INFO_NITEMS(inpkt->err_nitems); + dp = (struct info_dns_assoc *)inpkt->data; + memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in)); + peeraddr.sin_family = AF_INET; + peeraddr.sin_port = htons(NTP_PORT); + + /* + * Make sure the address is valid + */ + if ( +#ifdef REFCLOCK + !ISREFCLOCKADR(&peeraddr) && +#endif + ISBADADR(&peeraddr)) { +#ifdef REFCLOCK + msyslog(LOG_ERR, "dns_a: !ISREFCLOCK && ISBADADR"); +#else + msyslog(LOG_ERR, "dns_a: ISBADADR"); +#endif + req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); + return; + } + + while (items-- > 0) { + u_short associd; + size_t hnl; + char *cp; + + associd = dp->associd; /* Validate this value? */ + peeraddr.sin_addr.s_addr = dp->peeraddr; + for (hnl = 0; *dp->hostname && hnl < sizeof dp->hostname; ++hnl) ; + if (hnl >= sizeof dp->hostname) { + /* Squawk bad data */ + } + cp = emalloc(hnl + 1); + strncpy(cp, dp->hostname, hnl); + + msyslog(LOG_DEBUG, "dns_a: <%s> for %s, AssocID %d", + cp, inet_ntoa(peeraddr.sin_addr), associd); + + /* Do Something in the "if" line to use the info we got */ + if (0) { + /* If it didn't work */ + req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); + return; + } + dp++; + } + + req_ack(srcadr, inter, inpkt, INFO_OKAY); +} + + /* * do_unconf - remove a peer from the configuration list */ @@ -1760,7 +1849,7 @@ do_trustkey( struct sockaddr_in *srcadr, struct interface *inter, struct req_pkt *inpkt, - int trust + u_long trust ) { register u_long *kp; @@ -2005,7 +2094,7 @@ set_request_keyid( struct req_pkt *inpkt ) { - u_long keyid; + keyid_t keyid; /* * Restrict ourselves to one item only. @@ -2033,8 +2122,8 @@ set_control_keyid( struct req_pkt *inpkt ) { - u_long keyid; - extern u_long ctl_auth_keyid; + keyid_t keyid; + extern keyid_t ctl_auth_keyid; /* * Restrict ourselves to one item only. diff --git a/ntpd/ntp_resolver.c b/ntpd/ntp_resolver.c new file mode 100644 index 0000000000..601cc6bca6 --- /dev/null +++ b/ntpd/ntp_resolver.c @@ -0,0 +1,893 @@ +/* + * ripped off from ../ntpres/ntpres.c by Greg Troxel 4/2/92 + * routine callable from ntpd, rather than separate program + * also, key info passed in via a global, so no key file needed. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +/**/ +#include +#include +/**/ +#ifdef HAVE_SYS_PARAM_H +# include /* MAXHOSTNAMELEN (often) */ +#endif + +#include "ntpd.h" +#include "ntp_io.h" +#include "ntp_request.h" +#include "ntp_stdlib.h" +#include "ntp_syslog.h" + +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +/* + * Each item we are to resolve and configure gets one of these + * structures defined for it. + */ +struct dns_entry { + struct dns_entry *de_next; + struct info_dns_assoc de_info; /* DNS info for peer */ +}; +#define de_associd de_info.associd +#define de_peeraddr de_info.peeraddr +#define de_hostname de_info.hostname + +/* + * dns_entries is a pointer to the list of configuration entries + * we have left to do. + */ +static struct dns_entry *dns_entries = NULL; + +/* + * We take an interrupt every thirty seconds, at which time we decrement + * config_timer and resolve_timer. The former is set to 2, so we retry + * unsucessful reconfigurations every minute. The latter is set to + * an exponentially increasing value which starts at 2 and increases to + * 32. When this expires we retry failed name resolutions. + * + * We sleep SLEEPTIME seconds before doing anything, to give the server + * time to arrange itself. + */ +#define MINRESOLVE 2 +#define MAXRESOLVE 32 +#define CONFIG_TIME 2 +#define ALARM_TIME 30 + +#define SLEEPTIME 2 + +static volatile int config_timer = 0; +static volatile int resolve_timer = 0; + +static int resolve_value; /* next value of resolve timer */ + +/* + * Big hack attack + */ +#define LOCALHOST 0x7f000001 /* 127.0.0.1, in hex, of course */ +#define SKEWTIME 0x08000000 /* 0.03125 seconds as a l_fp fraction */ + +/* + * Select time out. Set to 2 seconds. The server is on the local machine, + * after all. + */ +#define TIMEOUT_SEC 2 +#define TIMEOUT_USEC 0 + + +/* + * File descriptor for ntp request code. + */ +static int sockfd = -1; + +/* + * Pipe descriptors + */ +int p_fd[2] = { -1, -1 }; + +/* stuff to be filled in by caller */ + +extern keyid_t req_keyid; /* request keyid */ + +/* end stuff to be filled in */ + +void ntp_res P((void)); +static RETSIGTYPE bong P((int)); +static void checkparent P((void)); +static void removeentry P((struct dns_entry *)); +static void addentry P((char *, u_int32, u_short)); +static int findhostaddr P((struct dns_entry *)); +static void openntp P((void)); +static int host_assoc P((struct info_dns_assoc *)); +static void doconfigure P((int)); + +struct ntp_res_t_pkt { /* Tagged packet: */ + void *tag; /* For the caller */ + u_int32 paddr; /* IP to look up, or 0 */ + char name[NTP_MAXHOSTNAME]; /* Name to look up (if 1st byte is not 0) */ +}; + +struct ntp_res_c_pkt { /* Control packet: */ + char name[NTP_MAXHOSTNAME]; + u_int32 paddr; + int mode; + int version; + int minpoll; + int maxpoll; + int flags; + int ttl; + keyid_t keyid; + u_char keystr[MAXFILENAME]; +}; +/* + * ntp_res_send + * + */ + +void +ntp_res_send( + void *tag, /* Return this with the answer */ + char *name, /* Name to resolve (or NIL) */ + u_int32 paddr, /* Address to resolve (or 0) */ + u_short associd /* Association ID (if available) */ + ) +{ + pid_t pid; + + /* + * fork. + * - parent returns + * - child stuffs data and calls ntp_res(NTP_RES_V2) + */ + + msyslog(LOG_INFO, "ntp_res_send: req_keyid %d\n", req_keyid); + for (pid = -1; pid == -1;) { +#ifdef RES_TEST + pid = 0; +#else + pid = fork(); +#endif + if (pid == -1) { + msyslog(LOG_ERR, "ntp_res_send: fork() failed: %m"); + sleep(2); + } + } + switch (pid) { + case -1: /* Error */ + msyslog(LOG_DEBUG, "ntp_res_send: error..."); + /* Can't happen */ + break; + + case 0: /* Child */ + closelog(); + kill_asyncio(); + (void) signal_no_reset(SIGCHLD, SIG_DFL); +#ifndef LOG_DAEMON + openlog("ntp_res", LOG_PID); +# else /* LOG_DAEMON */ +# ifndef LOG_NTP +# define LOG_NTP LOG_DAEMON +# endif + openlog("ntp_res_send", LOG_PID | LOG_NDELAY, LOG_NTP); +#endif + + msyslog(LOG_DEBUG, "ntp_res_send: in child..."); + addentry(name, paddr, associd); + msyslog(LOG_DEBUG, "ntp_res_send: back from addentry()"); + ntp_res(); + msyslog(LOG_DEBUG, "ntp_res_send: in child...DONE"); + break; + + default: /* Parent */ + msyslog(LOG_DEBUG, "ntp_res_send: in parent..."); + /* Nothing to do. (In Real Life, this never happens.) */ + return; + } +} + +/* + * ntp_res needs; + * + * req_key(???), req_keyid valid + * syslog still open + */ + +void +ntp_res(void) +{ +#ifdef HAVE_SIGSUSPEND + sigset_t set; + + sigemptyset(&set); +#endif /* HAVE_SIGSUSPEND */ + +#ifdef DEBUG + if (debug) { + msyslog(LOG_INFO, "NTP_RESOLVER running"); + } +#endif + + /* + * Make a first cut at resolving the bunch + */ + doconfigure(1); + if (dns_entries == NULL) { + if (debug) { + msyslog(LOG_INFO, "NTP_RESOLVER done!"); + } +#if defined SYS_WINNT + ExitThread(0); /* Don't want to kill whole NT process */ +#else + exit(0); /* done that quick */ +#endif + } + + /* + * Here we've got some problem children. Set up the timer + * and wait for it. + */ + resolve_value = resolve_timer = MINRESOLVE; + config_timer = CONFIG_TIME; +#ifndef SYS_WINNT + (void) signal_no_reset(SIGALRM, bong); + alarm(ALARM_TIME); +#endif /* SYS_WINNT */ + + for (;;) { + if (dns_entries == NULL) + exit(0); + + checkparent(); + + if (resolve_timer == 0) { + if (resolve_value < MAXRESOLVE) + resolve_value <<= 1; + resolve_timer = resolve_value; +#ifdef DEBUG + msyslog(LOG_INFO, "resolve_timer: 0->%d", resolve_timer); +#endif + config_timer = CONFIG_TIME; + doconfigure(1); + continue; + } else if (config_timer == 0) { + config_timer = CONFIG_TIME; +#ifdef DEBUG + msyslog(LOG_INFO, "config_timer: 0->%d", config_timer); +#endif + doconfigure(0); + continue; + } +#ifndef SYS_WINNT + /* + * There is a race in here. Is okay, though, since + * all it does is delay things by 30 seconds. + */ +# ifdef HAVE_SIGSUSPEND + sigsuspend(&set); +# else + sigpause(0); +# endif /* HAVE_SIGSUSPEND */ +#else + if (config_timer > 0) + config_timer--; + if (resolve_timer > 0) + resolve_timer--; + sleep(ALARM_TIME); +#endif /* SYS_WINNT */ + } +} + + +#ifndef SYS_WINNT +/* + * bong - service and reschedule an alarm() interrupt + */ +static RETSIGTYPE +bong( + int sig + ) +{ + if (config_timer > 0) + config_timer--; + if (resolve_timer > 0) + resolve_timer--; + alarm(ALARM_TIME); +} +#endif /* SYS_WINNT */ + +/* + * checkparent - see if our parent process is still running + * + * No need to worry in the Windows NT environment whether the + * main thread is still running, because if it goes + * down it takes the whole process down with it (in + * which case we won't be running this thread either) + * Turn function into NOP; + */ + +static void +checkparent(void) +{ +#if !defined (SYS_WINNT) && !defined (SYS_VXWORKS) + + /* + * If our parent (the server) has died we will have been + * inherited by init. If so, exit. + */ + if (getppid() == 1) { + msyslog(LOG_INFO, "parent died before we finished, exiting"); + exit(0); + } +#endif /* SYS_WINNT && SYS_VXWORKS*/ +} + + +/* + * removeentry - we are done with an entry, remove it from the list + */ +static void +removeentry( + struct dns_entry *entry + ) +{ + register struct dns_entry *de; + + de = dns_entries; + if (de == entry) { + dns_entries = de->de_next; + return; + } + + while (de != NULL) { + if (de->de_next == entry) { + de->de_next = entry->de_next; + return; + } + de = de->de_next; + } +} + + +/* + * addentry - add an entry to the configuration list + */ +static void +addentry( + char *name, + u_int32 paddr, + u_short associd + ) +{ + register struct dns_entry *de; + +#ifdef DEBUG + if (debug > 1) { + struct in_addr si; + + si.s_addr = paddr; + msyslog(LOG_INFO, + "ntp_res_send: <%s> %s associd %d\n", + (name) ? name : "", inet_ntoa(si), associd); + } +#endif + + de = (struct dns_entry *)emalloc(sizeof(struct dns_entry)); + if (name) { + strncpy(de->de_hostname, name, sizeof de->de_hostname); + } else { + de->de_hostname[0] = 0; + } + de->de_peeraddr = paddr; + de->de_associd = associd; + de->de_next = NULL; + + if (dns_entries == NULL) { + dns_entries = de; + } else { + register struct dns_entry *dep; + + for (dep = dns_entries; dep->de_next != NULL; + dep = dep->de_next) + /* nothing */; + dep->de_next = de; + } +} + + +/* + * findhostaddr - resolve a host name into an address (Or vice-versa) + * + * Given one of {de_peeraddr,de_hostname}, find the other one. + * It returns 1 for "success" and 0 for an uncorrectable failure. + * Note that "success" includes try again errors. You can tell that you + * got a "try again" since {de_peeraddr,de_hostname} will still be zero. + */ +static int +findhostaddr( + struct dns_entry *entry + ) +{ + struct hostent *hp; + + checkparent(); /* make sure our guy is still running */ + + if (entry->de_hostname[0] && entry->de_peeraddr) { + struct in_addr si; + + si.s_addr = entry->de_peeraddr; + /* HMS: Squawk? */ + msyslog(LOG_ERR, "findhostaddr: both de_hostname and de_peeraddr are defined: <%s>/%s", &entry->de_hostname[0], inet_ntoa(si)); + return 1; + } + + if (!entry->de_hostname[0] && !entry->de_peeraddr) { + msyslog(LOG_ERR, "findhostaddr: both de_hostname and de_peeraddr are undefined!"); + return 0; + } + + if (entry->de_hostname[0]) { +#ifdef DEBUG + if (debug > 2) + msyslog(LOG_DEBUG, "findhostaddr: Resolving <%s>", + &entry->de_hostname[0]); +#endif DEBUG + hp = gethostbyname(&entry->de_hostname[0]); + } else { +#ifdef DEBUG + if (debug > 2) { + struct in_addr si; + + si.s_addr = entry->de_peeraddr; + msyslog(LOG_DEBUG, "findhostaddr: Resolving %s", + inet_ntoa(si)); + } +#endif + hp = gethostbyaddr((const char *)&entry->de_peeraddr, + sizeof entry->de_peeraddr, + AF_INET); + } + + if (hp == NULL) { + /* + * If the resolver is in use, see if the failure is + * temporary. If so, return success. + */ + if (h_errno == TRY_AGAIN) + return (1); + return (0); + } + + if (entry->de_hostname[0]) { +#ifdef DEBUG + if (debug > 2) + msyslog(LOG_DEBUG, "findhostaddr: name resolved."); +#endif + /* + * Use the first address. We don't have any way to tell + * preferences and older gethostbyname() implementations + * only return one. + */ + memmove((char *)&(entry->de_peeraddr), + (char *)hp->h_addr, + sizeof(struct in_addr)); + } else { +#ifdef DEBUG + if (debug > 2) + msyslog(LOG_DEBUG, "findhostaddr: address resolved."); +#endif + strncpy(&entry->de_hostname[0], hp->h_name, sizeof entry->de_hostname); + } + + return (1); +} + + +/* + * openntp - open a socket to the ntp server + */ +static void +openntp(void) +{ + struct sockaddr_in saddr; + + if (sockfd >= 0) + return; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd == -1) { + msyslog(LOG_ERR, "socket() failed: %m"); + exit(1); + } + + memset((char *)&saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_port = htons(NTP_PORT); /* trash */ + saddr.sin_addr.s_addr = htonl(LOCALHOST); /* garbage */ + + /* + * Make the socket non-blocking. We'll wait with select() + */ +#ifndef SYS_WINNT +# if defined(O_NONBLOCK) + if (fcntl(sockfd, F_SETFL, O_NONBLOCK) == -1) { + msyslog(LOG_ERR, "fcntl(O_NONBLOCK) failed: %m"); + exit(1); + } +# else +# if defined(FNDELAY) + if (fcntl(sockfd, F_SETFL, FNDELAY) == -1) { + msyslog(LOG_ERR, "fcntl(FNDELAY) failed: %m"); + exit(1); + } +# else +# include "Bletch: NEED NON BLOCKING IO" +# endif /* FNDDELAY */ +# endif /* O_NONBLOCK */ +#else /* SYS_WINNT */ + { + int on = 1; + + if (ioctlsocket(sockfd,FIONBIO,(u_long *) &on) == SOCKET_ERROR) { + msyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m"); + exit(1); /* Windows NT - set socket in non-blocking mode */ + } + } +#endif /* SYS_WINNT */ + + + if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) { + msyslog(LOG_ERR, "openntp: connect() failed: %m"); + exit(1); + } +} + + +/* + * host_assoc: Send the resolved hostname for the associd + */ +static int +host_assoc( + struct info_dns_assoc *conf + ) +{ + fd_set fdset; + struct timeval tvout; + struct req_pkt reqpkt; + l_fp ts; + int n; +#ifdef SYS_WINNT + HANDLE hReadWriteEvent = NULL; + BOOL ret; + DWORD NumberOfBytesWritten, NumberOfBytesRead, dwWait; + OVERLAPPED overlap; +#endif /* SYS_WINNT */ + + checkparent(); /* make sure our guy is still running */ + + if (sockfd < 0) + openntp(); + +#ifdef SYS_WINNT + hReadWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL); +#endif /* SYS_WINNT */ + + /* + * Try to clear out any previously received traffic so it + * doesn't fool us. Note the socket is nonblocking. + */ + tvout.tv_sec = 0; + tvout.tv_usec = 0; + FD_ZERO(&fdset); + FD_SET(sockfd, &fdset); + while (select(sockfd + 1, &fdset, (fd_set *)0, (fd_set *)0, &tvout) > + 0) { + recv(sockfd, (char *)&reqpkt, REQ_LEN_MAC, 0); + FD_ZERO(&fdset); + FD_SET(sockfd, &fdset); + } + + /* + * Make up a request packet with the configuration info + */ + memset((char *)&reqpkt, 0, sizeof(reqpkt)); + + reqpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0); + reqpkt.auth_seq = AUTH_SEQ(1, 0); /* authenticated, no seq */ + reqpkt.implementation = IMPL_XNTPD; /* local implementation */ + reqpkt.request = REQ_HOSTNAME_ASSOCID; /* Hostname for associd */ + reqpkt.err_nitems = ERR_NITEMS(0, 1); /* one item */ + reqpkt.mbz_itemsize = MBZ_ITEMSIZE(sizeof(struct info_dns_assoc)); + memmove(reqpkt.data, (char *)conf, sizeof(struct info_dns_assoc)); + reqpkt.keyid = htonl(req_keyid); + + get_systime(&ts); + L_ADDUF(&ts, SKEWTIME); + HTONL_FP(&ts, &reqpkt.tstamp); + n = 0; + if (sys_authenticate) + n = authencrypt(req_keyid, (u_int32 *)&reqpkt, REQ_LEN_NOMAC); + + /* + * Done. Send it. + */ +#ifndef SYS_WINNT + n = send(sockfd, (char *)&reqpkt, (unsigned)(REQ_LEN_NOMAC + n), 0); + if (n < 0) { + msyslog(LOG_ERR, "send to NTP server failed: %m"); + return 0; /* maybe should exit */ + } +#else + /* In the NT world, documentation seems to indicate that there + * exist _write and _read routines that can be used to do blocking + * I/O on sockets. Problem is these routines require a socket + * handle obtained through the _open_osf_handle C run-time API + * of which there is no explanation in the documentation. We need + * nonblocking write's and read's anyway for our purpose here. + * We're therefore forced to deviate a little bit from the Unix + * model here and use the ReadFile and WriteFile Win32 I/O API's + * on the socket + */ + overlap.Offset = overlap.OffsetHigh = (DWORD)0; + overlap.hEvent = hReadWriteEvent; + ret = WriteFile((HANDLE)sockfd, (char *)&reqpkt, REQ_LEN_NOMAC + n, + (LPDWORD)&NumberOfBytesWritten, (LPOVERLAPPED)&overlap); + if ((ret == FALSE) && (GetLastError() != ERROR_IO_PENDING)) { + msyslog(LOG_ERR, "send to NTP server failed: %m"); + return 0; + } + dwWait = WaitForSingleObject(hReadWriteEvent, (DWORD) TIMEOUT_SEC * 1000); + if ((dwWait == WAIT_FAILED) || (dwWait == WAIT_TIMEOUT)) { + if (dwWait == WAIT_FAILED) + msyslog(LOG_ERR, "WaitForSingleObject failed: %m"); + return 0; + } +#endif /* SYS_WINNT */ + + + /* + * Wait for a response. A weakness of the mode 7 protocol used + * is that there is no way to associate a response with a + * particular request, i.e. the response to this configuration + * request is indistinguishable from that to any other. I should + * fix this some day. In any event, the time out is fairly + * pessimistic to make sure that if an answer is coming back + * at all, we get it. + */ + for (;;) { + FD_ZERO(&fdset); + FD_SET(sockfd, &fdset); + tvout.tv_sec = TIMEOUT_SEC; + tvout.tv_usec = TIMEOUT_USEC; + + n = select(sockfd + 1, &fdset, (fd_set *)0, + (fd_set *)0, &tvout); + + if (n < 0) + { + msyslog(LOG_ERR, "select() fails: %m"); + return 0; + } + else if (n == 0) + { + if(debug) + msyslog(LOG_DEBUG, "select() returned 0."); + return 0; + } + +#ifndef SYS_WINNT + n = recv(sockfd, (char *)&reqpkt, REQ_LEN_MAC, 0); + if (n <= 0) { + if (n < 0) { + msyslog(LOG_ERR, "recv() fails: %m"); + return 0; + } + continue; + } +#else /* Overlapped I/O used on non-blocking sockets on Windows NT */ + ret = ReadFile((HANDLE)sockfd, (char *)&reqpkt, (DWORD)REQ_LEN_MAC, + (LPDWORD)&NumberOfBytesRead, (LPOVERLAPPED)&overlap); + if ((ret == FALSE) && (GetLastError() != ERROR_IO_PENDING)) { + msyslog(LOG_ERR, "ReadFile() fails: %m"); + return 0; + } + dwWait = WaitForSingleObject(hReadWriteEvent, (DWORD) TIMEOUT_SEC * 1000); + if ((dwWait == WAIT_FAILED) || (dwWait == WAIT_TIMEOUT)) { + if (dwWait == WAIT_FAILED) { + msyslog(LOG_ERR, "WaitForSingleObject fails: %m"); + return 0; + } + continue; + } + n = NumberOfBytesRead; +#endif /* SYS_WINNT */ + + /* + * Got one. Check through to make sure it is what + * we expect. + */ + if (n < RESP_HEADER_SIZE) { + msyslog(LOG_ERR, "received runt response (%d octets)", + n); + continue; + } + + if (!ISRESPONSE(reqpkt.rm_vn_mode)) { +#ifdef DEBUG + if (debug > 1) + msyslog(LOG_INFO, "received non-response packet"); +#endif + continue; + } + + if (ISMORE(reqpkt.rm_vn_mode)) { +#ifdef DEBUG + if (debug > 1) + msyslog(LOG_INFO, "received fragmented packet"); +#endif + continue; + } + + if ( ( (INFO_VERSION(reqpkt.rm_vn_mode) < 2) + || (INFO_VERSION(reqpkt.rm_vn_mode) > NTP_VERSION)) + || INFO_MODE(reqpkt.rm_vn_mode) != MODE_PRIVATE) { +#ifdef DEBUG + if (debug > 1) + msyslog(LOG_INFO, + "version (%d/%d) or mode (%d/%d) incorrect", + INFO_VERSION(reqpkt.rm_vn_mode), + NTP_VERSION, + INFO_MODE(reqpkt.rm_vn_mode), + MODE_PRIVATE); +#endif + continue; + } + + if (INFO_SEQ(reqpkt.auth_seq) != 0) { +#ifdef DEBUG + if (debug > 1) + msyslog(LOG_INFO, + "nonzero sequence number (%d)", + INFO_SEQ(reqpkt.auth_seq)); +#endif + continue; + } + + if (reqpkt.implementation != IMPL_XNTPD || + reqpkt.request != REQ_HOSTNAME_ASSOCID) { +#ifdef DEBUG + if (debug > 1) + msyslog(LOG_INFO, + "implementation (%d/%d) or request (%d/%d) incorrect", + reqpkt.implementation, IMPL_XNTPD, + reqpkt.request, REQ_HOSTNAME_ASSOCID); +#endif + continue; + } + + if (INFO_NITEMS(reqpkt.err_nitems) != 0 || + INFO_MBZ(reqpkt.mbz_itemsize) != 0 || + INFO_ITEMSIZE(reqpkt.mbz_itemsize) != 0) { +#ifdef DEBUG + if (debug > 1) + msyslog(LOG_INFO, + "nitems (%d) mbz (%d) or itemsize (%d) nonzero", + INFO_NITEMS(reqpkt.err_nitems), + INFO_MBZ(reqpkt.mbz_itemsize), + INFO_ITEMSIZE(reqpkt.mbz_itemsize)); +#endif + continue; + } + + n = INFO_ERR(reqpkt.err_nitems); + switch (n) { + case INFO_OKAY: + /* success */ + return 1; + + case INFO_ERR_IMPL: + msyslog(LOG_ERR, + "server reports implementation mismatch!!"); + return 0; + + case INFO_ERR_REQ: + msyslog(LOG_ERR, + "server claims configuration request is unknown"); + return 0; + + case INFO_ERR_FMT: + msyslog(LOG_ERR, + "server indicates a format error occurred(!!)"); + return 0; + + case INFO_ERR_NODATA: + msyslog(LOG_ERR, + "server indicates no data available (shouldn't happen)"); + return 0; + + case INFO_ERR_AUTH: + msyslog(LOG_ERR, + "server returns a permission denied error"); + return 0; + + default: + msyslog(LOG_ERR, + "server returns unknown error code %d", n); + return 0; + } + } +} + + +/* + * doconfigure - attempt to resolve names and configure the server + */ +static void +doconfigure( + int dores + ) +{ + register struct dns_entry *de; + register struct dns_entry *deremove; + + de = dns_entries; + while (de != NULL) { +#ifdef DEBUG + if (debug > 1) { + struct in_addr si; + + si.s_addr = de->de_peeraddr; + msyslog(LOG_INFO, + "doconfigure: name: <%s> peeraddr: %s", + de->de_hostname, inet_ntoa(si)); + } +#endif + if (dores && (de->de_hostname[0] == 0 || de->de_peeraddr == 0)) { + if (!findhostaddr(de)) { + struct in_addr si; + + si.s_addr = de->de_peeraddr; + msyslog(LOG_ERR, + "couldn't resolve <%s>/%s, giving up on it", + de->de_hostname, inet_ntoa(si)); + deremove = de; + de = deremove->de_next; + removeentry(deremove); + continue; + } + } + + if (de->de_hostname[0] && de->de_peeraddr != 0) { + /* Send the answer */ + if (host_assoc(&de->de_info)) { + struct in_addr si; + + si.s_addr = de->de_peeraddr; + msyslog(LOG_INFO, + "resolved <%s>/%s, done with it", + de->de_hostname, inet_ntoa(si)); + + deremove = de; + de = deremove->de_next; + removeentry(deremove); + continue; + } +#ifdef DEBUG + if (debug > 1) { + msyslog(LOG_INFO, + "doconfigure: host_assoc() FAILED, maybe next time."); + } +#endif + } + de = de->de_next; + } +} diff --git a/ntpd/ntp_timer.c b/ntpd/ntp_timer.c index 0e2dc88cbe..8d0e128127 100644 --- a/ntpd/ntp_timer.c +++ b/ntpd/ntp_timer.c @@ -41,8 +41,10 @@ volatile int alarm_flag; static u_long adjust_timer; /* second timer */ static u_long keys_timer; /* minute timer */ static u_long hourly_timer; /* hour timer */ +#ifdef AUTOKEY static u_long revoke_timer; /* keys revoke timer */ -u_long sys_revoke = KEY_REVOKE; /* keys revoke timeout */ +u_long sys_revoke = 1 << KEY_REVOKE; /* keys revoke timeout */ +#endif /* AUTOKEY */ /* * Statistics counter for the interested. @@ -250,12 +252,14 @@ timer(void) } /* - * Garbage collect revoked keys + * Garbage collect old keys and generate new private value */ +#ifdef AUTOKEY if (revoke_timer <= current_time) { - revoke_timer += RANDPOLL(sys_revoke); + revoke_timer += sys_revoke; key_expire_all(); } +#endif /* AUTOKEY */ /* * Finally, call the hourly routine. diff --git a/ntpd/ntp_util.c b/ntpd/ntp_util.c index c53255a0a6..20861b0a73 100644 --- a/ntpd/ntp_util.c +++ b/ntpd/ntp_util.c @@ -2,16 +2,20 @@ * ntp_util.c - stuff I didn't have any other place for */ #ifdef HAVE_CONFIG_H -#include +# include #endif #include #include #include -# ifdef HAVE_SYS_IOCTL_H -# include -# endif -# include +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#include + +#ifdef HAVE_IEEEFP_H +# include +#endif #include "ntpd.h" #include "ntp_io.h" @@ -341,12 +345,18 @@ stats_config( break; } if (fscanf(fp, "%lf", &old_drift) != 1) { - msyslog(LOG_ERR, "invalid frequency from %s", + msyslog(LOG_ERR, "Un-parsable frequency in %s", stats_drift_file); (void) fclose(fp); break; } (void) fclose(fp); + if ( !finite(old_drift) + || (fabs(old_drift) > (sys_maxfreq * 1e6))) { + msyslog(LOG_ERR, "invalid frequency (%lf) in %s", + old_drift, stats_drift_file); + exit(1); + } msyslog(LOG_INFO, "frequency initialized %.3f from %s", old_drift, stats_drift_file); loop_config(LOOP_DRIFTCOMP, old_drift / 1e6); diff --git a/ntpd/ntpd.c b/ntpd/ntpd.c index b9b27acc0c..30e7f5fcf6 100644 --- a/ntpd/ntpd.c +++ b/ntpd/ntpd.c @@ -92,6 +92,10 @@ # include #endif +#ifdef PUBKEY +#include "ntp_crypto.h" +#endif /* PUBKEY */ + /* * Signals we catch for debugging. If not debugging we ignore them. */ @@ -378,10 +382,13 @@ ntpdmain( } addSourceToRegistry("NTP", szMsgPath); #endif + getstartup(argc, argv); /* startup configuration, may set debug */ + /* + * Initialize random generator and public key pair + */ get_systime(&now); SRANDOM((int)(now.l_i * now.l_uf)); - getstartup(argc, argv); /* startup configuration, may set debug */ #if !defined(VMS) # ifndef NODETACH @@ -714,12 +721,14 @@ service_main( #ifdef REFCLOCK init_refclock(); #endif +#ifdef PUBKEY + crypto_init(); /* Call *before* going to high-priority */ +#endif /* PUBKEY */ set_process_priority(); - init_proto(); + init_proto(); /* Call at high priority */ init_io(); init_loopfilter(); - - mon_start(MON_ON); /* monitor on by default now */ + mon_start(MON_ON); /* monitor on by default now */ /* turn off in config if unwanted */ /* @@ -728,7 +737,10 @@ service_main( * for the gizmo board. */ getconfig(argc, argv); - +#ifdef PUBKEY + if (crypto_enable) + crypto_setup(); +#endif /* PUBKEY */ initializing = 0; #if defined(SYS_WINNT) && !defined(NODETACH) diff --git a/ntpdate/Makefile.in b/ntpdate/Makefile.in index 9af4ace544..3ffa5c59b3 100644 --- a/ntpdate/Makefile.in +++ b/ntpdate/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/ntpdate/ntpdate.c b/ntpdate/ntpdate.c index 86ac988d55..2ac99257c9 100644 --- a/ntpdate/ntpdate.c +++ b/ntpdate/ntpdate.c @@ -702,7 +702,7 @@ transmit( if (sys_authenticate) { int len; - xpkt.keyid1 = htonl(sys_authkey); + xpkt.exten[0] = htonl(sys_authkey); get_systime(&server->xmt); L_ADDUF(&server->xmt, sys_authdelay); HTONL_FP(&server->xmt, &xpkt.xmt); @@ -810,11 +810,11 @@ receive( if (debug > 3) printf("receive: rpkt keyid=%ld sys_authkey=%ld decrypt=%ld\n", - (long int)ntohl(rpkt->keyid1), (long int)sys_authkey, + (long int)ntohl(rpkt->exten[0]), (long int)sys_authkey, (long int)authdecrypt(sys_authkey, (u_int32 *)rpkt, LEN_PKT_NOMAC, (int)(rbufp->recv_length - LEN_PKT_NOMAC))); - if (has_mac && ntohl(rpkt->keyid1) == sys_authkey && + if (has_mac && ntohl(rpkt->exten[0]) == sys_authkey && authdecrypt(sys_authkey, (u_int32 *)rpkt, LEN_PKT_NOMAC, (int)(rbufp->recv_length - LEN_PKT_NOMAC))) is_authentic = 1; diff --git a/ntpdate/ntptimeset.c b/ntpdate/ntptimeset.c index bf618cad98..fb9e7e07ac 100644 --- a/ntpdate/ntptimeset.c +++ b/ntpdate/ntptimeset.c @@ -892,7 +892,7 @@ transmit( if (sys_authenticate) { int len; - xpkt.keyid1 = htonl(sys_authkey); + xpkt.exten[0] = htonl(sys_authkey); get_systime(&server->xmt); L_ADDUF(&server->xmt, sys_authdelay); HTONL_FP(&server->xmt, &xpkt.xmt); @@ -1051,11 +1051,11 @@ receive( if (debug > 3) printf("receive: rpkt keyid=%ld sys_authkey=%ld decrypt=%ld\n", - (long int)ntohl(rpkt->keyid1), (long int)sys_authkey, + (long int)ntohl(rpkt->exten[0]), (long int)sys_authkey, (long int)authdecrypt(sys_authkey, (u_int32 *)rpkt, LEN_PKT_NOMAC, (int)(rbufp->recv_length - LEN_PKT_NOMAC))); - if (has_mac && ntohl(rpkt->keyid1) == sys_authkey && + if (has_mac && ntohl(rpkt->exten[0]) == sys_authkey && authdecrypt(sys_authkey, (u_int32 *)rpkt, LEN_PKT_NOMAC, (int)(rbufp->recv_length - LEN_PKT_NOMAC))) is_authentic = 1; diff --git a/ntpdc/Makefile.in b/ntpdc/Makefile.in index cec54cad6c..1b6cda61a7 100644 --- a/ntpdc/Makefile.in +++ b/ntpdc/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/ntpq/Makefile.in b/ntpq/Makefile.in index 6d656dd925..b288deaf6b 100644 --- a/ntpq/Makefile.in +++ b/ntpq/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/ntptrace/Makefile.in b/ntptrace/Makefile.in index 5a1f05284b..27795d129d 100644 --- a/ntptrace/Makefile.in +++ b/ntptrace/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/parseutil/Makefile.in b/parseutil/Makefile.in index 58450bc0cb..3d1dc06437 100644 --- a/parseutil/Makefile.in +++ b/parseutil/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/scripts/Makefile.in b/scripts/Makefile.in index 2143524471..a296708248 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ diff --git a/util/Makefile.am b/util/Makefile.am index 504c6b0f08..985283e59e 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -1,8 +1,10 @@ #AUTOMAKE_OPTIONS = ../ansi2knr no-dependencies AUTOMAKE_OPTIONS = ansi2knr -bin_PROGRAMS = @MAKE_TICKADJ@ @MAKE_NTPTIME@ -EXTRA_PROGRAMS = byteorder hist jitter kern longsize ntptime \ -precision tickadj testrs6000 timetrim sht +bin_PROGRAMS = @MAKE_TICKADJ@ @MAKE_NTPTIME@ @MAKE_NTP_GENKEYS@ +EXTRA_PROGRAMS = byteorder hist jitter kern longsize ntp_genkeys ntptime \ +precision sht testrs6000 tickadj timetrim + +ntp_genkeys_LDADD = ../librsaref/librsaref.a INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/librsaref # LDADD might need RESLIB and ADJLIB diff --git a/util/Makefile.in b/util/Makefile.in index 6a7d5e209f..8b950fbc67 100644 --- a/util/Makefile.in +++ b/util/Makefile.in @@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@ MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ PACKAGE = @PACKAGE@ @@ -103,11 +104,13 @@ install_sh = @install_sh@ AUTOMAKE_OPTIONS = ansi2knr -bin_PROGRAMS = @MAKE_TICKADJ@ @MAKE_NTPTIME@ -EXTRA_PROGRAMS = byteorder hist jitter kern longsize ntptime \ -precision tickadj testrs6000 timetrim sht +bin_PROGRAMS = @MAKE_TICKADJ@ @MAKE_NTPTIME@ @MAKE_NTP_GENKEYS@ +EXTRA_PROGRAMS = byteorder hist jitter kern longsize ntp_genkeys ntptime \ +precision sht testrs6000 tickadj timetrim +ntp_genkeys_LDADD = ../librsaref/librsaref.a + INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/librsaref # LDADD might need RESLIB and ADJLIB LDADD = ../libntp/libntp.a @@ -150,6 +153,10 @@ longsize_OBJECTS = longsize$U.o longsize_LDADD = $(LDADD) longsize_DEPENDENCIES = ../libntp/libntp.a longsize_LDFLAGS = +ntp_genkeys_SOURCES = ntp_genkeys.c +ntp_genkeys_OBJECTS = ntp_genkeys$U.o +ntp_genkeys_DEPENDENCIES = ../librsaref/librsaref.a +ntp_genkeys_LDFLAGS = ntptime_SOURCES = ntptime.c ntptime_OBJECTS = ntptime$U.o ntptime_LDADD = $(LDADD) @@ -183,8 +190,9 @@ timetrim_LDFLAGS = COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -DIST_SOURCES = byteorder.c hist.c jitter.c kern.c longsize.c ntptime.c \ -precision.c sht.c testrs6000.c tickadj.c timetrim.c +DIST_SOURCES = byteorder.c hist.c jitter.c kern.c longsize.c \ +ntp_genkeys.c ntptime.c precision.c sht.c testrs6000.c tickadj.c \ +timetrim.c DIST_COMMON = README Makefile.am Makefile.in ansi2knr.1 ansi2knr.c @@ -194,11 +202,11 @@ GZIP_ENV = --best depcomp = $(SHELL) $(top_srcdir)/depcomp DEP_FILES = @AMDEP@ $(DEPDIR)/byteorder$U.Po $(DEPDIR)/hist$U.Po \ $(DEPDIR)/jitter$U.Po $(DEPDIR)/kern$U.Po $(DEPDIR)/longsize$U.Po \ -$(DEPDIR)/ntptime$U.Po $(DEPDIR)/precision$U.Po $(DEPDIR)/sht$U.Po \ -$(DEPDIR)/testrs6000$U.Po $(DEPDIR)/tickadj$U.Po \ -$(DEPDIR)/timetrim$U.Po -SOURCES = byteorder.c hist.c jitter.c kern.c longsize.c ntptime.c precision.c sht.c testrs6000.c tickadj.c timetrim.c -OBJECTS = byteorder$U.o hist$U.o jitter$U.o kern$U.o longsize$U.o ntptime$U.o precision$U.o sht$U.o testrs6000$U.o tickadj$U.o timetrim$U.o +$(DEPDIR)/ntp_genkeys$U.Po $(DEPDIR)/ntptime$U.Po \ +$(DEPDIR)/precision$U.Po $(DEPDIR)/sht$U.Po $(DEPDIR)/testrs6000$U.Po \ +$(DEPDIR)/tickadj$U.Po $(DEPDIR)/timetrim$U.Po +SOURCES = byteorder.c hist.c jitter.c kern.c longsize.c ntp_genkeys.c ntptime.c precision.c sht.c testrs6000.c tickadj.c timetrim.c +OBJECTS = byteorder$U.o hist$U.o jitter$U.o kern$U.o longsize$U.o ntp_genkeys$U.o ntptime$U.o precision$U.o sht$U.o testrs6000$U.o tickadj$U.o timetrim$U.o all: all-redirect .SUFFIXES: @@ -291,6 +299,10 @@ longsize: $(longsize_OBJECTS) $(longsize_DEPENDENCIES) @rm -f longsize $(LINK) $(longsize_LDFLAGS) $(longsize_OBJECTS) $(longsize_LDADD) $(LIBS) +ntp_genkeys: $(ntp_genkeys_OBJECTS) $(ntp_genkeys_DEPENDENCIES) + @rm -f ntp_genkeys + $(LINK) $(ntp_genkeys_LDFLAGS) $(ntp_genkeys_OBJECTS) $(ntp_genkeys_LDADD) $(LIBS) + ntptime: $(ntptime_OBJECTS) $(ntptime_DEPENDENCIES) @rm -f ntptime $(LINK) $(ntptime_LDFLAGS) $(ntptime_OBJECTS) $(ntptime_LDADD) $(LIBS) @@ -324,6 +336,8 @@ kern_.c: kern.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/kern.c; then echo $(srcdir)/kern.c; else echo kern.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > kern_.c longsize_.c: longsize.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/longsize.c; then echo $(srcdir)/longsize.c; else echo longsize.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > longsize_.c +ntp_genkeys_.c: ntp_genkeys.c $(ANSI2KNR) + $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_genkeys.c; then echo $(srcdir)/ntp_genkeys.c; else echo ntp_genkeys.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_genkeys_.c ntptime_.c: ntptime.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntptime.c; then echo $(srcdir)/ntptime.c; else echo ntptime.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntptime_.c precision_.c: precision.c $(ANSI2KNR) @@ -336,8 +350,9 @@ tickadj_.c: tickadj.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tickadj.c; then echo $(srcdir)/tickadj.c; else echo tickadj.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tickadj_.c timetrim_.c: timetrim.c $(ANSI2KNR) $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/timetrim.c; then echo $(srcdir)/timetrim.c; else echo timetrim.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > timetrim_.c -byteorder_.o hist_.o jitter_.o kern_.o longsize_.o ntptime_.o \ -precision_.o sht_.o testrs6000_.o tickadj_.o timetrim_.o : $(ANSI2KNR) +byteorder_.o hist_.o jitter_.o kern_.o longsize_.o ntp_genkeys_.o \ +ntptime_.o precision_.o sht_.o testrs6000_.o tickadj_.o timetrim_.o : \ +$(ANSI2KNR) tags: TAGS @@ -391,6 +406,7 @@ distdir: $(DISTFILES) @AMDEP@include $(DEPDIR)/jitter$U.Po @AMDEP@include $(DEPDIR)/kern$U.Po @AMDEP@include $(DEPDIR)/longsize$U.Po +@AMDEP@include $(DEPDIR)/ntp_genkeys$U.Po @AMDEP@include $(DEPDIR)/ntptime$U.Po @AMDEP@include $(DEPDIR)/precision$U.Po @AMDEP@include $(DEPDIR)/sht$U.Po diff --git a/util/ntp_genkeys.c b/util/ntp_genkeys.c new file mode 100644 index 0000000000..1b025cb119 --- /dev/null +++ b/util/ntp_genkeys.c @@ -0,0 +1,239 @@ +/* + * Program to generate MD5 and RSA keys for NTP clients and servers + */ +#include +#include +#include +#include +#include +#include "ntpd.h" +#include "ntp_stdlib.h" +#include "ntp_string.h" +#include "ntp_crypto.h" + +/* + * Cryptodefines + */ +#define MAXKEYLEN 1024 /* maximum encoded key length */ +#define MODULUSLEN 512 /* length of RSA modulus */ +#define PRIMELEN 512 /* length of D_H prime, generator */ +#define GENLEN 256 /* length of D-H key and subprime */ + +/* + * This program generates four files: ntp.keys containing the DES/MD5 + * private keys, ntpkey containing the RSA private key, ntpkey_host + * containing the RSA public key, where host is the DNS name of the + * generating machine, and ntpkey_dh containing the parameters for the + * Diffie-Hellman key-agreement algorithm. The files contain + * cryptographic values generated by the algorithms of the rsaref20 + * package and are in printable ASCII format. Since the algorythms are + * seeded by the system clock, each run of this program will produce a + * different outcome. There are no options or frills of any sort, + * although a number of options would seem to be appropriate. Waving + * this program in the breeze will no doubt bring a cast of thousands to + * wiggle the options this way and that for various useful purposes. + * + * The ntp.keys file contains 16 MD5 keys. Each key consists of 16 + * characters randomized over the ASCII 95-character printing subset. + * The file is read by the daemon at the location specified by the keys + * configuration file command and made visible only to root. An + * additional key consisting of a easily remembered password should be + * added by hand for use with the ntpdc program. The file must be + * distributed by secure means to other servers and clients sharing the + * same security compartment. + * + * The key identifiers for MD5 and DES keys must be less than 65536, + * although this program uses only the identifiers from 1 to 16. The key + * identifier for each association is specified as the key argument in + * the server or peer configuration file command. + * + * The ntpkey file contains the RSA private key. It is read by the + * daemon at the location specified by the private argument of the + * crypto configuration file command and made visible only to root. This + * file is useful only to the machine that generated it and never shared + * with any other daemon or application program. + * + * The ntpkey_host file contains the RSA public key, where host is the + * DNS name of the host that generated it. The file is read by the + * daemon at the location specified by the public argument to the server + * or peer configuration file command. This file can be widely + * distributed and stored without using secure means, since the data are + * public values. + * + * The ntp_dh file contains two Diffie-Hellman parameters, the prime + * modulus and the generator. The file is read by the daemon at the + * location specified by the dhparams argument of the crypto + * configuration file command. This file can be widely distributed and + * stored without using secure means, since the data are public values. + * + * The file formats all begin with two lines, the first containing the + * generating system DNS name and the second the datestamp. Lines + * beginning with # are considered comments and ignored by the daemon. + * In the ntp.keys file, the next 16 lines contain the MD5 keys in + * order. In the ntpkey and ntpkey_host files, the next line contains + * the modulus length in bits followed by the key as a PEM encoded + * string. In the ntpkey_dh file, the next line contains the prime + * length in bytes followed by the prime as a PEM encoded string, and + * the next and final line contains the generator length in bytes + * followed by the generator as a PEM encoded string. + * + * Note: See the file ./source/rsaref.h in the rsaref20 package for + * explanation of return values, if necessary. + */ +int +main( + int argc, + char *argv[] + ) +{ + R_RSA_PRIVATE_KEY rsaref_private; /* RSA private key */ + R_RSA_PUBLIC_KEY rsaref_public; /* RSA public key */ + R_RSA_PROTO_KEY protokey; /* RSA prototype key */ + R_DH_PARAMS dh_params; /* Diffie-Hellman parameters */ + R_RANDOM_STRUCT randomstr; /* random structure */ + u_char encoded_key[MAXKEYLEN]; /* encoded PEM string buffer */ + u_int modulus; /* modulus length */ + struct timeval tv; /* initialization vector */ + struct utsname utsnamebuf; /* uname argument structure */ + u_char sysname[128]; /* DNS host name */ + u_char md5key[17]; /* generated MD5 key */ + FILE *str; /* file handle */ + int rval; /* return value */ + u_int temp, len; + int i, j; + + /* + * Generate the file "ntp.keys" containing 16 random MD5 keys in + * the format expected at daemon run time. + */ + uname(&utsnamebuf); + printf("Generating MD5 keys...\n"); + str = fopen("ntp.keys", "w"); + if (str == NULL) { + perror("MD5/DES key file"); + return (-1); + } + gettimeofday(&tv, 0); + srandom((u_int)tv.tv_sec); + fprintf(str, "# MD5/DES key file generated by %s\n# %s", + utsnamebuf.nodename, ctime(&tv.tv_sec)); + for (i = 1; i <= 16; i++) { + for (j = 0; j < 16; j++) { + while (1) { + temp = random() & 0xff; + if (temp > 0x20 && temp < 0x7f) + break; + } + md5key[j] = (u_char)temp; + } + md5key[16] = 0; + fprintf(str, "%2d M %16s # MD5 key\n", i, + md5key); + } + fclose(str); + + /* + * Roll a RSA public/private key pair. + */ + printf("Generating RSA public/private key pair %d bits...\n", + MODULUSLEN); + protokey.bits = MODULUSLEN; + protokey.useFermat4 = 1; + R_RandomInit(&randomstr); + R_GetRandomBytesNeeded(&len, &randomstr); + for (i = 0; i < len; i++) { + temp = random(); + R_RandomUpdate(&randomstr, (u_char *)&temp, 1); + } + rval = R_GeneratePEMKeys(&rsaref_public, &rsaref_private, + &protokey, &randomstr); + if (rval) { + printf("R_GeneratePEMKeys error %x\n", rval); + return (-1); + } + + /* + * Generate the file "ntpkey" containing the RSA private key in + * printable ASCII format. + */ + str = fopen("ntpkey", "w"); + if (str == NULL) { + perror("RSA private key file"); + return (-1); + } + len = sizeof(rsaref_private) - sizeof(rsaref_private.bits); + modulus = (u_int32)rsaref_private.bits; + fprintf(str, "# RSA private key file generated by %s\n# %s", + utsnamebuf.nodename, ctime(&tv.tv_sec)); + R_EncodePEMBlock(encoded_key, &temp, + (u_char *)&rsaref_private.modulus, len); + encoded_key[temp] = '\0'; + fprintf(str, "%d %s\n", modulus, encoded_key); + fclose(str); + + /* + * Generate the file "ntpkey_host" containing the RSA public key + * in printable ASCII format. + */ + sprintf(sysname, "ntpkey_%s", utsnamebuf.nodename); + str = fopen(sysname, "w"); + if (str == NULL) { + perror("RSA public key file"); + return (-1); + } + len = sizeof(rsaref_public) - sizeof(rsaref_public.bits); + modulus = (u_int32)rsaref_public.bits; + fprintf(str, "# RSA public key file generated by %s\n# %s", + utsnamebuf.nodename, ctime(&tv.tv_sec)); + R_EncodePEMBlock(encoded_key, &temp, + (u_char *)&rsaref_public.modulus, len); + encoded_key[temp] = '\0'; + fprintf(str, "%d %s\n", modulus, encoded_key); + fclose(str); + + /* + * Roll the prime and generator for the Diffie-Hellman key + * agreement algorithm. + */ + printf("Generating Diffie-Hellman parameters %d bits...\n", + PRIMELEN); + str = fopen("ntpkey_dh", "w"); + if (str == NULL) { + perror("Diffie-Hellman parameters file"); + return (-1); + } + R_RandomInit(&randomstr); + R_GetRandomBytesNeeded(&len, &randomstr); + for (i = 0; i < len; i++) { + temp = random(); + R_RandomUpdate(&randomstr, (u_char *)&temp, 1); + } + + /* + * Generate the file "ntpkey_dh" containing the Diffie-Hellman + * prime and generator in printable ASCII format. + */ + len = DH_PRIME_LEN(PRIMELEN); + dh_params.prime = (u_char *)malloc(len); + dh_params.generator = (u_char *)malloc(len); + rval = R_GenerateDHParams(&dh_params, PRIMELEN, GENLEN, + &randomstr); + if (rval) { + printf("R_GenerateDHParams error %x\n", rval); + return (-1); + } + fprintf(str, + "# Diffie-Hellman parameter file generated by %s\n# %s", + utsnamebuf.nodename, ctime(&tv.tv_sec)); + R_EncodePEMBlock(encoded_key, &temp, + (u_char *)dh_params.prime, dh_params.primeLen); + encoded_key[temp] = '\0'; + fprintf(str, "%d %s\n", dh_params.primeLen, encoded_key); + R_EncodePEMBlock(encoded_key, &temp, + (u_char *)dh_params.generator, dh_params.generatorLen); + encoded_key[temp] = '\0'; + fprintf(str, "%d %s\n", dh_params.generatorLen, encoded_key); + fclose(str); + + return (0); +}