diff options
author | Cy Schubert <cy@FreeBSD.org> | 2015-07-01 03:12:13 +0000 |
---|---|---|
committer | Cy Schubert <cy@FreeBSD.org> | 2015-07-01 03:12:13 +0000 |
commit | 873997f35a991eee09ed91148a0cf332360380da (patch) | |
tree | 5b1ffa3ad0e56e0e9f2991011729791ee86d7632 /ntpd/ntp_proto.c | |
parent | 4ba32eb5a8bf3455c09d1513ed2af8d2c861a6ba (diff) | |
download | src-873997f35a991eee09ed91148a0cf332360380da.tar.gz src-873997f35a991eee09ed91148a0cf332360380da.zip |
Vendor import ntp-4.2.8p3.vendor/ntp/4.2.8p3
Approved by: delphij (implicit, using SO hat)
Security: VuXML: 0d0f3050-1f69-11e5-9ba9-d050996490d0
Security: http://bugs.ntp.org/show_bug.cgi?id=2853
Security: https://www.kb.cert.org/vuls/id/668167
Security: http://support.ntp.org/bin/view/Main/SecurityNotice#June_2015_NTP_Security_Vulnerabi
Notes
Notes:
svn path=/vendor/ntp/dist/; revision=284990
svn path=/vendor/ntp/4.2.8p3/; revision=284992; tag=vendor/ntp/4.2.8p3
Diffstat (limited to 'ntpd/ntp_proto.c')
-rw-r--r-- | ntpd/ntp_proto.c | 104 |
1 files changed, 97 insertions, 7 deletions
diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index 577b5fb0af5a..40624066746f 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -14,6 +14,7 @@ #include "ntp_control.h" #include "ntp_string.h" #include "ntp_leapsec.h" +#include "refidsmear.h" #include <stdio.h> #ifdef HAVE_LIBSCF_H @@ -61,7 +62,8 @@ typedef struct peer_select_tag { * System variables are declared here. Unless specified otherwise, all * times are in seconds. */ -u_char sys_leap; /* system leap indicator */ +u_char sys_leap; /* system leap indicator, use set_sys_leap() to change this */ +u_char xmt_leap; /* leap indicator sent in client requests, set up by set_sys_leap() */ u_char sys_stratum; /* system stratum */ s_char sys_precision; /* local clock precision (log2 s) */ double sys_rootdelay; /* roundtrip delay to primary source */ @@ -70,6 +72,11 @@ u_int32 sys_refid; /* reference id (network byte order) */ l_fp sys_reftime; /* last update time */ struct peer *sys_peer; /* current peer */ +#ifdef LEAP_SMEAR +struct leap_smear_info leap_smear; +#endif +int leap_sec_in_progress; + /* * Rate controls. Leaky buckets are used to throttle the packet * transmission rates in order to protect busy servers such as at NIST @@ -151,6 +158,33 @@ void pool_name_resolved (int, int, void *, const char *, const struct addrinfo *); #endif /* WORKER */ +void +set_sys_leap(u_char new_sys_leap) { + sys_leap = new_sys_leap; + xmt_leap = sys_leap; + + /* + * Under certain conditions we send faked leap bits to clients, so + * eventually change xmt_leap below, but never change LEAP_NOTINSYNC. + */ + if (xmt_leap != LEAP_NOTINSYNC) { + if (leap_sec_in_progress) { + /* always send "not sync" */ + xmt_leap = LEAP_NOTINSYNC; + } +#ifdef LEAP_SMEAR + else { + /* + * If leap smear is enabled in general we must never send a leap second warning + * to clients, so make sure we only send "in sync". + */ + if (leap_smear.enabled) + xmt_leap = LEAP_NOWARNING; + } +#endif /* LEAP_SMEAR */ + } +} + /* * transmit - transmit procedure called by poll timeout @@ -1909,7 +1943,7 @@ clock_update( */ case 2: clear_all(); - sys_leap = LEAP_NOTINSYNC; + set_sys_leap(LEAP_NOTINSYNC); sys_stratum = STRATUM_UNSPEC; memcpy(&sys_refid, "STEP", 4); sys_rootdelay = 0; @@ -1930,7 +1964,7 @@ clock_update( * process. */ if (sys_leap == LEAP_NOTINSYNC) { - sys_leap = LEAP_NOWARNING; + set_sys_leap(LEAP_NOWARNING); #ifdef AUTOKEY if (crypto_flags) crypto_update(); @@ -2424,7 +2458,7 @@ clock_select(void) osys_peer = sys_peer; sys_survivors = 0; #ifdef LOCKCLOCK - sys_leap = LEAP_NOTINSYNC; + set_sys_leap(LEAP_NOTINSYNC); sys_stratum = STRATUM_UNSPEC; memcpy(&sys_refid, "DOWN", 4); #endif /* LOCKCLOCK */ @@ -3407,6 +3441,16 @@ peer_xmit( } +#ifdef LEAP_SMEAR + +static void +leap_smear_add_offs(l_fp *t, l_fp *t_recv) { + L_ADD(t, &leap_smear.offset); +} + +#endif /* LEAP_SMEAR */ + + /* * fast_xmit - Send packet for nonpersistent association. Note that * neither the source or destination can be a broadcast address. @@ -3468,18 +3512,60 @@ fast_xmit( * This is a normal packet. Use the system variables. */ } else { - xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, +#ifdef LEAP_SMEAR + /* + * Make copies of the variables which can be affected by smearing. + */ + l_fp this_ref_time; + l_fp this_recv_time; +#endif + + /* + * If we are inside the leap smear interval we add the current smear offset to + * the packet receive time, to the packet transmit time, and eventually to the + * reftime to make sure the reftime isn't later than the transmit/receive times. + */ + xpkt.li_vn_mode = PKT_LI_VN_MODE(xmt_leap, PKT_VERSION(rpkt->li_vn_mode), xmode); + xpkt.stratum = STRATUM_TO_PKT(sys_stratum); xpkt.ppoll = max(rpkt->ppoll, ntp_minpoll); xpkt.precision = sys_precision; xpkt.refid = sys_refid; xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); xpkt.rootdisp = HTONS_FP(DTOUFP(sys_rootdisp)); + +#ifdef LEAP_SMEAR + this_ref_time = sys_reftime; + if (leap_smear.in_progress) { + leap_smear_add_offs(&this_ref_time, NULL); + xpkt.refid = convertLFPToRefID(leap_smear.offset); + DPRINTF(2, ("fast_xmit: leap_smear.in_progress: refid %8x, smear %s\n", + ntohl(xpkt.refid), + lfptoa(&leap_smear.offset, 8) + )); + } + HTONL_FP(&this_ref_time, &xpkt.reftime); +#else HTONL_FP(&sys_reftime, &xpkt.reftime); +#endif + xpkt.org = rpkt->xmt; + +#ifdef LEAP_SMEAR + this_recv_time = rbufp->recv_time; + if (leap_smear.in_progress) + leap_smear_add_offs(&this_recv_time, NULL); + HTONL_FP(&this_recv_time, &xpkt.rec); +#else HTONL_FP(&rbufp->recv_time, &xpkt.rec); +#endif + get_systime(&xmt_tx); +#ifdef LEAP_SMEAR + if (leap_smear.in_progress) + leap_smear_add_offs(&xmt_tx, &this_recv_time); +#endif HTONL_FP(&xmt_tx, &xpkt.xmt); } @@ -3988,7 +4074,7 @@ init_proto(void) * Fill in the sys_* stuff. Default is don't listen to * broadcasting, require authentication. */ - sys_leap = LEAP_NOTINSYNC; + set_sys_leap(LEAP_NOTINSYNC); sys_stratum = STRATUM_UNSPEC; memcpy(&sys_refid, "INIT", 4); sys_peer = NULL; @@ -4062,8 +4148,12 @@ proto_config( case PROTO_MONITOR: /* monitoring (monitor) */ if (value) mon_start(MON_ON); - else + else { mon_stop(MON_ON); + if (mon_enabled) + msyslog(LOG_WARNING, + "restrict: 'monitor' cannot be disabled while 'limited' is enabled"); + } break; case PROTO_NTP: /* NTP discipline (ntp) */ |