summaryrefslogtreecommitdiff
path: root/ntpd/ntp_proto.c
diff options
context:
space:
mode:
Diffstat (limited to 'ntpd/ntp_proto.c')
-rw-r--r--ntpd/ntp_proto.c125
1 files changed, 68 insertions, 57 deletions
diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c
index 2f7543f..577b5fb 100644
--- a/ntpd/ntp_proto.c
+++ b/ntpd/ntp_proto.c
@@ -245,7 +245,7 @@ transmit(
/*
* Update the reachability status. If not heard for
* three consecutive polls, stuff infinity in the clock
- * filter.
+ * filter.
*/
oreach = peer->reach;
peer->outdate = current_time;
@@ -290,7 +290,7 @@ transmit(
* If preemptible and we have more peers than maxclock,
* and this peer has the minimum score of preemptibles,
* demobilize.
- */
+ */
if (peer->unreach >= NTP_UNREACH) {
hpoll++;
/* ephemeral: no FLAG_CONFIG nor FLAG_PREEMPT */
@@ -335,7 +335,7 @@ transmit(
peer->retry--;
/*
- * Do not transmit if in broadcast client mode.
+ * Do not transmit if in broadcast client mode.
*/
if (peer->hmode != MODE_BCLIENT)
peer_xmit(peer);
@@ -442,7 +442,7 @@ receive(
return; /* no flakeway */
}
}
-
+
/*
* Version check must be after the query packets, since they
* intentionally use an early version.
@@ -486,18 +486,18 @@ receive(
*/
authlen = LEN_PKT_NOMAC;
has_mac = rbufp->recv_length - authlen;
- while (has_mac != 0) {
+ while (has_mac > 0) {
u_int32 len;
#ifdef AUTOKEY
u_int32 hostlen;
struct exten *ep;
#endif /*AUTOKEY */
- if (has_mac % 4 != 0 || has_mac < MIN_MAC_LEN) {
+ if (has_mac % 4 != 0 || has_mac < (int)MIN_MAC_LEN) {
sys_badlength++;
return; /* bad length */
}
- if (has_mac <= MAX_MAC_LEN) {
+ if (has_mac <= (int)MAX_MAC_LEN) {
skeyid = ntohl(((u_int32 *)pkt)[authlen / 4]);
break;
@@ -541,6 +541,14 @@ receive(
}
/*
+ * If has_mac is < 0 we had a malformed packet.
+ */
+ if (has_mac < 0) {
+ sys_badlength++;
+ return; /* bad length */
+ }
+
+ /*
* If authentication required, a MAC must be present.
*/
if (restrict_mask & RES_DONTTRUST && has_mac == 0) {
@@ -651,7 +659,7 @@ receive(
* If the signature is 20 bytes long, the last 16 of
* which are zero, then this is a Microsoft client
* wanting AD-style authentication of the server's
- * reply.
+ * reply.
*
* This is described in Microsoft's WSPP docs, in MS-SNTP:
* http://msdn.microsoft.com/en-us/library/cc212930.aspx
@@ -672,7 +680,7 @@ receive(
* broadcast or unicast address as appropriate.
*/
if (crypto_flags && skeyid > NTP_MAXKEY) {
-
+
/*
* More on the autokey dance (AKD). A cookie is
* constructed from public and private values.
@@ -698,7 +706,7 @@ receive(
* # if unsync, 0
* % can't happen
*/
- if (has_mac < MAX_MD5_LEN) {
+ if (has_mac < (int)MAX_MD5_LEN) {
sys_badauth++;
return;
}
@@ -736,7 +744,7 @@ receive(
* purposes is zero. Note the hash is saved for
* use later in the autokey mambo.
*/
- if (authlen > LEN_PKT_NOMAC && pkeyid != 0) {
+ if (authlen > (int)LEN_PKT_NOMAC && pkeyid != 0) {
session_key(&rbufp->recv_srcadr,
dstadr_sin, skeyid, 0, 2);
tkeyid = session_key(
@@ -866,7 +874,7 @@ receive(
* curious and could be an intruder attempting to clog, so we
* just ignore it.
*
- * If the packet is authentic and the manycastclient or pool
+ * If the packet is authentic and the manycastclient or pool
* association is found, we mobilize a client association and
* copy pertinent variables from the manycastclient or pool
* association to the new client association. If not, just
@@ -1089,6 +1097,7 @@ receive(
fast_xmit(rbufp, MODE_ACTIVE, 0,
restrict_mask);
sys_restricted++;
+ return;
}
}
@@ -1247,16 +1256,6 @@ receive(
}
/*
- * Update the state variables.
- */
- if (peer->flip == 0) {
- if (hismode != MODE_BROADCAST)
- peer->rec = p_xmt;
- peer->dst = rbufp->recv_time;
- }
- peer->xmt = p_xmt;
-
- /*
* If this is a crypto_NAK, the server cannot authenticate a
* client packet. The server might have just changed keys. Clear
* the association and restart the protocol.
@@ -1275,19 +1274,21 @@ receive(
#endif /* AUTOKEY */
return;
- /*
- * If the digest fails, the client cannot authenticate a server
+ /*
+ * If the digest fails or it's missing for authenticated
+ * associations, the client cannot authenticate a server
* reply to a client packet previously sent. The loopback check
* is designed to avoid a bait-and-switch attack, which was
* possible in past versions. If symmetric modes, return a
* crypto-NAK. The peer should restart the protocol.
*/
- } else if (!AUTH(has_mac || (restrict_mask & RES_DONTTRUST),
- is_authentic)) {
+ } else if (!AUTH(peer->keyid || has_mac ||
+ (restrict_mask & RES_DONTTRUST), is_authentic)) {
report_event(PEVNT_AUTH, peer, "digest");
peer->flash |= TEST5; /* bad auth */
peer->badauth++;
- if (hismode == MODE_ACTIVE || hismode == MODE_PASSIVE)
+ if (has_mac &&
+ (hismode == MODE_ACTIVE || hismode == MODE_PASSIVE))
fast_xmit(rbufp, MODE_ACTIVE, 0, restrict_mask);
if (peer->flags & FLAG_PREEMPT) {
unpeer(peer);
@@ -1301,6 +1302,16 @@ receive(
}
/*
+ * Update the state variables.
+ */
+ if (peer->flip == 0) {
+ if (hismode != MODE_BROADCAST)
+ peer->rec = p_xmt;
+ peer->dst = rbufp->recv_time;
+ }
+ peer->xmt = p_xmt;
+
+ /*
* Set the peer ppoll to the maximum of the packet ppoll and the
* peer minpoll. If a kiss-o'-death, set the peer minpoll to
* this maximum and advance the headway to give the sender some
@@ -1568,7 +1579,7 @@ process_packet(
/*
* If the peer was previously unreachable, raise a trap. In any
* case, mark it reachable.
- */
+ */
if (!peer->reach) {
report_event(PEVNT_REACH, peer, NULL);
peer->timereachable = current_time;
@@ -1635,8 +1646,8 @@ process_packet(
* Interleaved broadcast mode. Use interleaved timestamps.
* t1 = peer->borg, t2 = p_org, t3 = p_org, t4 = aorg
*/
- if (peer->flags & FLAG_XB) {
- ci = p_org; /* delay */
+ if (peer->flags & FLAG_XB) {
+ ci = p_org; /* delay */
L_SUB(&ci, &peer->aorg);
LFPTOD(&ci, t34);
ci = p_org; /* t2 - t1 */
@@ -1765,7 +1776,7 @@ process_packet(
p_del, peer->r21 / 1e3, peer->r34 / 1e3,
td);
#endif
- }
+ }
#endif /* ASSYM */
/*
@@ -2092,7 +2103,7 @@ poll_update(
void
peer_clear(
struct peer *peer, /* peer structure */
- char *ident /* tally lights */
+ const char *ident /* tally lights */
)
{
u_char u;
@@ -2231,7 +2242,7 @@ clock_filter(
for (i = NTP_SHIFT - 1; i >= 0; i--) {
if (i != 0)
peer->filter_disp[j] += dtemp;
- if (peer->filter_disp[j] >= MAXDISPERSE) {
+ if (peer->filter_disp[j] >= MAXDISPERSE) {
peer->filter_disp[j] = MAXDISPERSE;
dst[i] = MAXDISPERSE;
} else if (peer->update - peer->filter_epoch[j] >
@@ -2246,7 +2257,7 @@ clock_filter(
}
/*
- * If the clock has stabilized, sort the samples by distance.
+ * If the clock has stabilized, sort the samples by distance.
*/
if (freq_cnt == 0) {
for (i = 1; i < NTP_SHIFT; i++) {
@@ -2280,7 +2291,7 @@ clock_filter(
continue;
m++;
}
-
+
/*
* Compute the dispersion and jitter. The dispersion is weighted
* exponentially by NTP_FWEIGHT (0.5) so it is normalized close
@@ -2382,7 +2393,7 @@ clock_select(void)
struct peer *peer;
int i, j, k, n;
int nlist, nl2;
- int allow, osurv;
+ int allow;
int speer;
double d, e, f, g;
double high, low;
@@ -2411,7 +2422,6 @@ clock_select(void)
* enough to handle all associations.
*/
osys_peer = sys_peer;
- osurv = sys_survivors;
sys_survivors = 0;
#ifdef LOCKCLOCK
sys_leap = LEAP_NOTINSYNC;
@@ -2485,9 +2495,9 @@ clock_select(void)
/*
* If this peer could have the orphan parent
* as a synchronization ancestor, exclude it
- * from selection to avoid forming a
+ * from selection to avoid forming a
* synchronization loop within the orphan mesh,
- * triggering stratum climb to infinity
+ * triggering stratum climb to infinity
* instability. Peers at stratum higher than
* the orphan stratum could have the orphan
* parent in ancestry so are excluded.
@@ -2595,7 +2605,7 @@ clock_select(void)
for (allow = 0; 2 * allow < nlist; allow++) {
/*
- * Bound the interval (low, high) as the smallest
+ * Bound the interval (low, high) as the smallest
* interval containing points from the most sources.
*/
n = 0;
@@ -2631,7 +2641,7 @@ clock_select(void)
* We assert the correct time is contained in the interval, but
* the best offset estimate for the interval might not be
* contained in the interval. For this purpose, a truechimer is
- * defined as the midpoint of an interval that overlaps the
+ * defined as the midpoint of an interval that overlaps the
* intersection interval.
*/
j = 0;
@@ -2651,9 +2661,10 @@ clock_select(void)
* include any of them in the cluster population.
*/
if (peer->flags & FLAG_PPS) {
- if (typepps == NULL)
+ if (typepps == NULL)
typepps = peer;
- continue;
+ if (!(peer->flags & FLAG_TSTAMP_PPS))
+ continue;
}
#endif /* REFCLOCK */
@@ -2664,7 +2675,7 @@ clock_select(void)
nlist = j;
/*
- * If no survivors remain at this point, check if the modem
+ * If no survivors remain at this point, check if the modem
* driver, local driver or orphan parent in that order. If so,
* nominate the first one found as the only survivor.
* Otherwise, give up and leave the island to the rats.
@@ -2701,7 +2712,7 @@ clock_select(void)
* by root distance. Continue voting as long as there are more
* than sys_minclock survivors and the select jitter of the peer
* with the worst metric is greater than the minimum peer
- * jitter. Stop if we are about to discard a TRUE or PREFER
+ * jitter. Stop if we are about to discard a TRUE or PREFER
* peer, who of course have the immunity idol.
*/
while (1) {
@@ -2807,7 +2818,7 @@ clock_select(void)
typesystem = peers[speer].peer;
if (osys_peer == NULL || osys_peer == typesystem) {
- sys_clockhop = 0;
+ sys_clockhop = 0;
} else if ((x = fabs(typesystem->offset -
osys_peer->offset)) < sys_mindisp) {
if (sys_clockhop == 0)
@@ -2981,7 +2992,7 @@ peer_xmit(
)
{
struct pkt xpkt; /* transmit packet */
- int sendlen, authlen;
+ size_t sendlen, authlen;
keyid_t xkeyid = 0; /* transmit key ID */
l_fp xmt_tx, xmt_ty;
@@ -3065,7 +3076,7 @@ peer_xmit(
LFPTOD(&xmt_ty, peer->xleave);
#ifdef DEBUG
if (debug)
- printf("transmit: at %ld %s->%s mode %d len %d\n",
+ printf("transmit: at %ld %s->%s mode %d len %zu\n",
current_time, peer->dstadr ?
stoa(&peer->dstadr->sin) : "-",
stoa(&peer->srcadr), peer->hmode, sendlen);
@@ -3105,7 +3116,7 @@ peer_xmit(
* the session key is generated.
*/
while (1) {
-
+
/*
* Allocate and initialize a keylist if not
* already done. Then, use the list in inverse
@@ -3157,7 +3168,7 @@ peer_xmit(
break;
/*
- * In symmetric modes the parameter, certificate,
+ * In symmetric modes the parameter, certificate,
* identity, cookie and autokey exchanges are
* required. The leapsecond exchange is optional. But, a
* peer will not believe the other peer until the other
@@ -3312,11 +3323,11 @@ peer_xmit(
* Calculate the next session key. Since extension
* fields are present, the cookie value is zero.
*/
- if (sendlen > LEN_PKT_NOMAC) {
+ if (sendlen > (int)LEN_PKT_NOMAC) {
session_key(&peer->dstadr->sin, &peer->srcadr,
xkeyid, 0, 2);
}
- }
+ }
#endif /* AUTOKEY */
/*
@@ -3354,7 +3365,7 @@ peer_xmit(
authtrust(xkeyid, 0);
#endif /* AUTOKEY */
if (sendlen > sizeof(xpkt)) {
- msyslog(LOG_ERR, "proto: buffer overflow %u", sendlen);
+ msyslog(LOG_ERR, "proto: buffer overflow %zu", sendlen);
exit (-1);
}
peer->t21_bytes = sendlen;
@@ -3379,7 +3390,7 @@ peer_xmit(
#ifdef AUTOKEY
#ifdef DEBUG
if (debug)
- printf("transmit: at %ld %s->%s mode %d keyid %08x len %d index %d\n",
+ printf("transmit: at %ld %s->%s mode %d keyid %08x len %zu index %d\n",
current_time, latoa(peer->dstadr),
ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen,
peer->keynumber);
@@ -3590,7 +3601,7 @@ pool_xmit(
&hints,
0, /* no retry */
&pool_name_resolved,
- (void *)(u_int)pool->associd);
+ (void *)(intptr_t)pool->associd);
if (!rc)
DPRINTF(1, ("pool DNS lookup %s started\n",
pool->hostname));
@@ -3611,7 +3622,7 @@ pool_xmit(
return; /* out of addresses, re-query DNS next poll */
restrict_mask = restrictions(rmtadr);
if (RES_FLAGS & restrict_mask)
- restrict_source(rmtadr, 0,
+ restrict_source(rmtadr, 0,
current_time + POOL_SOLICIT_WINDOW + 1);
lcladr = findinterface(rmtadr);
memset(&xpkt, 0, sizeof(xpkt));
@@ -3696,7 +3707,7 @@ pool_name_resolved(
return;
}
- assoc = (associd_t)(u_int)context;
+ assoc = (associd_t)(intptr_t)context;
pool = findpeerbyassoc(assoc);
if (NULL == pool) {
msyslog(LOG_ERR,