[Git][NTPsec/ntpsec][proto-refactor] Handle manycast and pool mode
Daniel Fox Franke
gitlab at mg.gitlab.com
Fri Jul 8 15:29:15 UTC 2016
Daniel Fox Franke pushed to branch proto-refactor at NTPsec / ntpsec
Commits:
2d4764fa by Daniel Fox Franke at 2016-07-07T15:30:24-04:00
Handle manycast and pool mode
- - - - -
1 changed file:
- ntpd/ntp_proto.c
Changes:
=====================================
ntpd/ntp_proto.c
=====================================
--- a/ntpd/ntp_proto.c
+++ b/ntpd/ntp_proto.c
@@ -379,23 +379,44 @@ parse_packet(
}
/* Returns true if we should not accept any unauthenticated packets from
- this peer. There are two ways the user can configure this requirement:
+ this peer. There are four ways the user can configure this requirement:
1. A 'restrict notrust' command applies to the peer's IP, or,
- 2. The peer is one of our servers, and we've configured it with a
- 'key' option to the 'server' command.
-
+ 2. We've configured the peer with a 'key' option,
+ 3. The packet wants to create a new associations, and a 'restrict
+ nopeer' command applies to the peer's IP.
+ 4. This is a symmetric mode packet, and sys_authenticate is set
+ (as it is by default).
+
The 'peer' argument may be NULL to indicate that we have no current
association.
+
+ These rules implement a couple changes in behavior from NTP Classic:
+
+ 1. Unless sys_authenticate is disabled, we always require
+ authentication for symmetric mode. NTP Classic only requires
+ authentication for symmetric active mode packets from new peers.
+ However, without authentication, symmetric mode is vulnerable
+ to simple attacks even from off path, so we require it.
+
+ 2. We don't enforce 'restrict nopeer' against pool-mode responses.
*/
static bool
i_require_authentication(
struct peer const* peer,
+ struct parsed_pkt const* pkt,
u_short restrict_mask
)
{
return (peer != NULL && peer->keyid != 0) ||
- (restrict_mask & RES_DONTTRUST);
+ (restrict_mask & RES_DONTTRUST) ||
+ ((restrict_mask & RES_NOPEER) &&
+ ((peer != NULL && (peer->cast_flags & MDF_ACAST)) ||
+ (peer == NULL && PKT_MODE(pkt->li_vn_mode) == MODE_ACTIVE) ||
+ (PKT_MODE(pkt->li_vn_mode) == MODE_BROADCAST))) ||
+ (sys_authenticate &&
+ (PKT_MODE(pkt->li_vn_mode) == MODE_ACTIVE ||
+ PKT_MODE(pkt->li_vn_mode) == MODE_PASSIVE));
}
static bool
@@ -500,6 +521,8 @@ handle_procpkt(
/* Shouldn't happen, but include this for safety. */
if(peer == NULL) { return; }
+ peer->flash &= ~PKT_BOGON_MASK;
+
/* Duplicate detection */
if(pkt->xmt == lfp_to_uint64(&peer->xmt)) {
peer->flash |= BOGON1;
@@ -663,6 +686,43 @@ handle_procpkt(
clock_filter(peer, theta + peer->bias, delta, epsilon);
}
+static void
+handle_manycast(
+ struct recvbuf *rbufp,
+ u_short restrict_mask,
+ struct parsed_pkt const* pkt,
+ struct peer *mpeer,
+ bool request_already_authenticated
+ )
+{
+ (void)request_already_authenticated;
+ (void)restrict_mask;
+
+ if(mpeer == NULL) {
+ sys_restricted++;
+ return;
+ };
+
+ if(mpeer->cast_flags & MDF_POOL) {
+ mpeer->nextdate = current_time + 1;
+ }
+
+ /* Don't bother associating with unsynchronized servers */
+ if (PKT_LEAP(pkt->li_vn_mode) == LEAP_NOTINSYNC ||
+ PKT_TO_STRATUM(pkt->stratum) < sys_floor ||
+ PKT_TO_STRATUM(pkt->stratum) >= sys_ceiling ||
+ scalbn((double)pkt->rootdelay/2.0 + (double)pkt->rootdisp, -16) >=
+ MAXDISPERSE) {
+ return;
+ }
+
+ newpeer(&rbufp->recv_srcadr, NULL, rbufp->dstadr,
+ MODE_CLIENT, PKT_VERSION(pkt->li_vn_mode),
+ mpeer->minpoll, mpeer->maxpoll,
+ FLAG_PREEMPT | (FLAG_IBURST & mpeer->flags),
+ MDF_UCAST | MDF_UCLNT, 0, mpeer->keyid, false);
+}
+
void
receive(
struct recvbuf *rbufp
@@ -705,9 +765,11 @@ receive(
goto done;
}
peer = findpeer(rbufp, PKT_MODE(pkt->li_vn_mode), &match);
- if(peer != NULL) { peer->flash &= ~PKT_BOGON_MASK; }
+ if(peer == NULL && match == AM_MANYCAST) {
+ peer = findmanycastpeer(rbufp);
+ }
- if(i_require_authentication(peer, restrict_mask)) {
+ if(i_require_authentication(peer, pkt, restrict_mask)) {
if(
/* Check whether an authenticator is even present. */
!pkt->keyid_present || is_crypto_nak(pkt) ||
@@ -742,6 +804,9 @@ receive(
case AM_PROCPKT:
handle_procpkt(rbufp, restrict_mask, pkt, peer, authenticated);
break;
+ case AM_MANYCAST:
+ handle_manycast(rbufp, restrict_mask, pkt, peer, authenticated);
+ break;
default:
/* Everything else is for symmetric passive, broadcast,
or multicast modes, which are a security nightmare.
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/2d4764fa2c977a764b2fd0f56216032eb799111a
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20160708/45815bb0/attachment.html>
More information about the vc
mailing list