From: Harlan Stenn Date: Thu, 31 Mar 2005 04:41:14 +0000 (-0500) Subject: Changes from Dave Mills X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e666d377e8c8589c8a8ca71de60438d25baeaf4d;p=thirdparty%2Fntp.git Changes from Dave Mills bk: 424b7f6apQJmwz1FN5Y_9KJdIw9PnA --- diff --git a/include/ntp.h b/include/ntp.h index 171e0148af..3f2c82691b 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -220,10 +220,18 @@ struct interface { * Peer errors */ #define TEST10 0x0200 /* peer stratum exceeded */ -#define TEST11 0x0400 /* peeer distance exceeded */ +#define TEST11 0x0400 /* peer distance exceeded */ #define TEST12 0x0800 /* peer synchronization loop */ #define TEST13 0x1000 /* peer unfit for synchronization */ +/* + * Authentication codes + */ +#define AUTH_NONE 0 /* no authentication */ +#define AUTH_OK 1 /* authentication OK */ +#define AUTH_ERROR 2 /* authentication error */ +#define AUTH_CRYPTO 3 /* crypto-NAK */ + /* * 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 @@ -875,13 +883,15 @@ struct endpoint { /* * Association matching AM[] return codes */ -#define AM_ERR -1 -#define AM_NOMATCH 0 -#define AM_PROCPKT 1 -#define AM_FXMIT 2 -#define AM_MANYCAST 3 -#define AM_NEWPASS 4 -#define AM_NEWBCL 5 +#define AM_ERR -1 /* error */ +#define AM_NOMATCH 0 /* no match */ +#define AM_SERV 1 /* server packet */ +#define AM_PROCPKT 2 /* symmetric packet */ +#define AM_BCST 3 /* broadcast packet */ +#define AM_FXMIT 4 /* client packet */ +#define AM_MANYCAST 5 /* manycast packet */ +#define AM_NEWPASS 6 /* new passive */ +#define AM_NEWBCL 7 /* new broadcast */ /* NetInfo configuration locations */ #ifdef HAVE_NETINFO diff --git a/ntpd/ntp_peer.c b/ntpd/ntp_peer.c index 60ce37a42f..3a37a7c198 100644 --- a/ntpd/ntp_peer.c +++ b/ntpd/ntp_peer.c @@ -48,13 +48,13 @@ int AM[AM_MODES][AM_MODES] = { /*P*/ { AM_ERR, AM_PROCPKT, AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, -/*C*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT, AM_NOMATCH}, +/*C*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_SERV, AM_NOMATCH}, /*S*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, /*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, -/*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT}, +/*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_BCST}, }; #define MATCH_ASSOC(x,y) AM[(x)][(y)] @@ -300,13 +300,13 @@ clear_all(void) for (n = 0; n < NTP_HASH_SIZE; n++) { for (peer = peer_hash[n]; peer != 0; peer = next_peer) { next_peer = peer->next; - if (peer->flags & FLAG_CONFIG) { - if (!(peer->cast_flags & (MDF_ACAST | - MDF_MCAST | MDF_BCAST))) - peer_clear(peer, "STEP"); - } else { - unpeer(peer); + if (!(peer->cast_flags & (MDF_ACAST | MDF_MCAST | + MDF_BCAST))) { + peer->hpoll = peer->minpoll; + peer_clear(peer, "STEP"); } + if (peer->flags & FLAG_CONFIG) + unpeer(peer); } } #ifdef DEBUG @@ -617,6 +617,7 @@ newpeer( peer->ttl = (u_char)ttl; peer->keyid = key; peer->precision = sys_precision; + peer->hpoll = peer->minpoll; if (cast_flags & MDF_ACAST) peer_clear(peer, "ACST"); else if (cast_flags & MDF_MCAST) diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index 8af7ba4d45..021c9e49dc 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -212,7 +212,7 @@ transmit( peer->unreach = 0; if (!(peer->reach & 0x07)) clock_filter(peer, 0., 0., MAXDISPERSE); - hpoll = sys_poll; + hpoll = sys_poll; if (peer->flags & FLAG_BURST && !peer_unfit(peer)) peer->burst = NTP_BURST; @@ -246,31 +246,15 @@ transmit( exit (0); } } - clock_select(); - poll_update(peer, hpoll); - return; } } /* * Do not transmit if in broadcast client mode. */ - if (peer->hmode == MODE_BCLIENT) { - poll_update(peer, hpoll); - return; - } - - /* - * If in jail, do not transmit unless a get out of jail free - * card shows up. Such cards are in short supply. - */ - if (peer->flash & TEST4) { - if (!(peer->flags & FLAG_CONFIG)) - unpeer(peer); - } else { + if (peer->hmode != MODE_BCLIENT) peer_xmit(peer); - poll_update(peer, hpoll); - } + poll_update(peer, hpoll); } @@ -288,11 +272,11 @@ receive( int restrict_mask; /* restrict bits */ int has_mac; /* length of MAC field */ int authlen; /* offset of MAC field */ - int is_authentic; /* cryptosum ok */ + int is_authentic = 0; /* cryptosum ok */ keyid_t skeyid = 0; /* key ID */ struct sockaddr_storage *dstadr_sin; /* active runway */ struct peer *peer2; /* aux peer structure pointer */ - l_fp p_org; /* originate timestamp */ + l_fp p_org; /* origin timestamp */ l_fp p_rec; /* receive timestamp */ l_fp p_xmt; /* transmit timestamp */ #ifdef OPENSSL @@ -405,13 +389,13 @@ receive( /* * 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 goes poof! with a brilliant flash. + * the number of words following the packet header is 0, no MAC + * is present and the packet is not authenticated. If 1, the + * packet is a crypto-NAK; if 3, the packet is authenticated + * with DES; if 5, the packet is authenticated with MD5. If 2 or + * 4, the packet is a runt and discarded forthwith. If greater + * than 5, an extension field is present, so we subtract the + * length of the field and go around again. */ authlen = LEN_PKT_NOMAC; has_mac = rbufp->recv_length - authlen; @@ -477,15 +461,40 @@ receive( */ peer = findpeer(&rbufp->recv_srcadr, rbufp->dstadr, rbufp->fd, hismode, &retcode); - is_authentic = 0; dstadr_sin = &rbufp->dstadr->sin; + NTOHL_FP(&pkt->org, &p_org); + NTOHL_FP(&pkt->rec, &p_rec); + NTOHL_FP(&pkt->xmt, &p_xmt); + + /* + * Check authentication. There are five outcomes: + * + * NONE authentication is not required unless the key + * identifier is nonzero + * OK authentication succeeds + * ERROR the packet has a MAC and authentication fails + * CRYPTO crypto-NAK + * + * Later on if an association is present and the key identifier + * is nonzero, the authentication code must not be NONE. + */ if (has_mac == 0) { + is_authentic = AUTH_NONE; /* not required */ #ifdef DEBUG if (debug) - printf("receive: at %ld %s<-%s mode %d code %d\n", + printf("receive: at %ld %s<-%s mode %d code %d auth %d\n", current_time, stoa(&rbufp->dstadr->sin), stoa(&rbufp->recv_srcadr), hismode, - retcode); + retcode, is_authentic); +#endif + } else if (has_mac == 4) { + is_authentic = AUTH_CRYPTO; /* crypto-NAK */ +#ifdef DEBUG + if (debug) + printf("receive: at %ld %s<-%s mode %d code %d auth %d\n", + current_time, stoa(&rbufp->dstadr->sin), + stoa(&rbufp->recv_srcadr), hismode, + retcode, is_authentic); #endif } else { #ifdef OPENSSL @@ -575,10 +584,13 @@ receive( * succeed in bloating the key cache. If an autokey, * purge it immediately, since we won't be needing it * again. If the packet is authentic, it can mobilize an - * association. + * association. Note that there is no key zero. */ - is_authentic = authdecrypt(skeyid, (u_int32 *)pkt, - authlen, has_mac); + if (!authdecrypt(skeyid, (u_int32 *)pkt, authlen, + has_mac)) + is_authentic = AUTH_ERROR; + else + is_authentic = AUTH_OK; #ifdef OPENSSL if (skeyid > NTP_MAXKEY) authtrust(skeyid, 0); @@ -596,10 +608,10 @@ receive( /* * The association matching rules are implemented by a set of - * routines and a table in ntp_peer.c. A packet matching an - * association is processed by that association. If not and - * certain conditions prevail, then an ephemeral association is - * mobilized: a broadcast packet mobilizes a broadcast client + * routines and an association table. A packet matching an + * association is processed by the peer process for that + * association. If there are no errors, an ephemeral association + * is mobilized: a broadcast packet mobilizes a broadcast client * aassociation; a manycast server packet mobilizes a manycast * client association; a symmetric active packet mobilizes a * symmetric passive association. And, the adventure @@ -608,11 +620,10 @@ receive( switch (retcode) { /* - * This is a client mode packet not matching a known - * association. If from a manycast client we run a few sanity - * checks before deciding to send a unicast server response. - * Otherwise, it must be a client request, so send a server - * response and go home. + * This is a client mode packet not matching any association, so + * it must be from a manycast client. If there are no errors and + * we (as manycast server) toss a server mode packet back to the + * rascal. */ case AM_FXMIT: if (rbufp->dstadr->flags & INT_MCASTOPEN) { @@ -642,10 +653,9 @@ receive( /* * Note that we don't require authentication here, since * we can't set the system clock; but, we do send a - * crypto-NAK (kiss the frog) if the packet had a MAC - * and authentication failed. + * crypto-NAK (kiss the frog) if authentication failed. */ - if (has_mac && !is_authentic) + if (is_authentic == AUTH_ERROR) fast_xmit(rbufp, MODE_SERVER, 0, restrict_mask); else fast_xmit(rbufp, MODE_SERVER, skeyid, @@ -654,11 +664,11 @@ receive( /* * This is a server mode packet returned in response to a client - * mode packet sent to a multicast group address. The originate + * mode packet sent to a multicast group address. The origin * timestamp is a good nonce to reliably associate the reply * with what was sent. If there is no match, that's curious and * could be an intruder attempting to clog, so we just ignore - & it. + * it. * * If the packet is authentic and the manycast association is * found, we mobilize a client association and copy pertinent @@ -670,12 +680,10 @@ receive( * the guy is already here, don't fire up a duplicate. */ case AM_MANYCAST: - if (has_mac && !is_authentic) + if (!(is_authentic == AUTH_NONE || is_authentic == + AUTH_OK)) return; /* bad auth */ - if (sys_authenticate && !has_mac) - return; /* not auth */ - if ((peer2 = findmanycastpeer(rbufp)) == NULL) return; /* no assoc match */ @@ -690,30 +698,26 @@ receive( * We don't need these, but it warms the billboards. */ peer->ttl = peer2->ttl; - break; + /* fall through */ /* - * This is the first packet received from a symmetric active - * peer. If the packet is authentic, mobilize a passive - * association. If not, kiss the frog. + * This is a server mode packet sent in response to a client + * mode packet. If the origin timestamp is zero, somebody is + * spoofing us. Otherise, if the origin timestamp does not match + * the transmit timestamp, the packet is bogus. In either case, + * drop the packet and wait for the next opportunity. */ - case AM_NEWPASS: - if (has_mac && !is_authentic) { - fast_xmit(rbufp, MODE_PASSIVE, 0, - restrict_mask); - return; /* bad auth */ + case AM_SERV: + peer->flash = 0; + if (L_ISZERO(&p_org)) { + peer->flash |= TEST3; + return; /* unsynch */ + + } else if (!L_ISEQU(&p_org, &peer->xmt)) { + peer->flash |= TEST2; + return; /* bogus */ } - if (sys_authenticate && !has_mac) - return; /* not auth */ - - peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, - MODE_PASSIVE, PKT_VERSION(pkt->li_vn_mode), - NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_UCAST, 0, - skeyid); - if (peer == NULL) - return; /* system error */ - - break; + break; /* continue */ /* * This is the first packet received from a broadcast server. If @@ -722,54 +726,97 @@ receive( * kiss any frogs here. */ case AM_NEWBCL: - if (has_mac && !is_authentic) + if (!(is_authentic == AUTH_NONE || is_authentic == + AUTH_OK)) return; /* bad auth */ - if (sys_authenticate && !has_mac) - return; /* not auth */ - /* * If the sys_bclient switch is 1, execute the inital * volley; if 2, go directly to broadcast client mode. + * In the latter, autokey will not work, as it requires + * a cryptographic data exchange. */ - if (sys_bclient == 1) + if (sys_bclient == 1) { peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, MODE_CLIENT, PKT_VERSION(pkt->li_vn_mode), NTP_MINDPOLL, NTP_MAXDPOLL, FLAG_MCAST | FLAG_IBURST, MDF_BCLNT, 0, skeyid); - else - peer = newpeer(&rbufp->recv_srcadr, - rbufp->dstadr, MODE_BCLIENT, - PKT_VERSION(pkt->li_vn_mode), NTP_MINDPOLL, - NTP_MAXDPOLL, 0, MDF_BCLNT, 0, skeyid); #ifdef OPENSSL + if (peer == NULL) + return; /* system error */ + if (!(peer->flags & FLAG_SKEY)) + return; + + rval = crypto_recv(peer, rbufp); + if (rval != XEVNT_OK) { /* crypto error */ + peer_clear(peer, "CRYP"); + unpeer(peer); + } + } +#endif /* OPENSSL */ + return; + + /* + * Autokey cryptography requires a two-way exchange + * between the client and server. If a two-way exchange + * is not possible, neither is Autokey. + */ +#ifdef OPENSSL + if (!(peer->flags & FLAG_SKEY)) + return; +#endif /* OPENSSL */ + peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, + MODE_BCLIENT, PKT_VERSION(pkt->li_vn_mode), + NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_BCLNT, 0, + skeyid); if (peer == NULL) return; /* system error */ - if (peer->flags & FLAG_SKEY) - crypto_recv(peer, rbufp); -#endif - return; + /* fall through */ /* - * A symmetric packet matches a symmetric association, a server - * packet matches a client association or a broadcast packet - * matches a broadcast client association. If authenticated keep - * on going. If not and the association is ephemeral, kill it; - * otherwise clear, flash and keep on going. Later we will check - * for loopback and reset if confirmed. - * - * Note that once started in authentcated mode, the key ID is - * nonzero. Subsequently, if a packet arrives with no MAC, it is - * dropped. This is designed to avoid a bait-and-switch attack. + * Broadcast packet. Nothing much to check here. + */ + case AM_BCST: + peer->flash = 0; + break; + + /* + * This is the first packet received from a symmetric active + * peer. If the packet is authentic and the first he sent, + * mobilize a passive association. If not, kiss the frog. + */ + case AM_NEWPASS: + if (!((is_authentic == AUTH_NONE || is_authentic == + AUTH_OK) && L_ISZERO(&p_org))) { + fast_xmit(rbufp, MODE_PASSIVE, 0, + restrict_mask); + return; /* bad auth */ + } + peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, + MODE_PASSIVE, PKT_VERSION(pkt->li_vn_mode), + NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_UCAST, 0, + skeyid); + if (peer == NULL) + return; /* system error */ + + /* fall through */ + + /* + * This is a symmetric (active or passive) mode packet. If the + * origin timestamp is zero, the sender has not yet heard from + * us. Otherwise, if the origin timestamp does not match the + * transmit timestamp, the packet is bogus. In either case, + * scarf the origin and receive timestamps to send back to him. */ case AM_PROCPKT: peer->flash = 0; - if (has_mac && !is_authentic) - peer->flash |= TEST5; /* bad auth */ - if (peer->keyid && !has_mac) - return; /* not auth */ + if (L_ISZERO(&p_org)) + peer->flash |= TEST3; /* unsynch */ + + else if (!L_ISEQU(&p_org, &peer->xmt)) + peer->flash |= TEST2; /* bogus */ break; /* @@ -792,26 +839,38 @@ receive( return; } + /* + * If the association is authenticated, each packet carries a + * MAC with nonzero key ID. Subsequently, if a packet arrives + * with no MAC, it is dropped. This is designed to avoid a bait- + * and-switch attack. + */ + if (is_authentic == AUTH_ERROR || (peer->keyid != 0 && + is_authentic == AUTH_NONE)) { + peer->flash |= TEST5; /* bad auth */ + return; + } + /* - * We do some serious timestamp checking. Note the only way we - * can get here is either with an newlly-mobilized association - * or via PROCPK, so the flashers are properly illuminated. + * The packet matches association p. Verify the timestamps are + * valid and the packet is not a replay or bogus. Note the only + * way we can get here is either with an newlly-mobilized + * association or via PROCPK, so the flashers are properly + * illuminated. */ peer->received++; peer->timereceived = current_time; - NTOHL_FP(&pkt->org, &p_org); - NTOHL_FP(&pkt->rec, &p_rec); - NTOHL_FP(&pkt->xmt, &p_xmt); /* - * If the transmit timestamp is zero, the packet is from a - * defective implementation. Just ignore it. + * If the transmit timestamp is zero, the server is broken. */ if (L_ISZERO(&p_xmt)) { return; /* - * If the packet is an old duplicate, drop it. + * If the transmit timestamp duplicates a previous one, the + * packet is a replay. This prevents the bad guys from replaying + * the most recent packet, authenticated or not. */ } else if (L_ISEQU(&peer->org, &p_xmt)) { peer->flash |= TEST1; /* dupe */ @@ -819,69 +878,16 @@ receive( return; /* - * For broadcast client mode, loopback checking is not useful. - */ - } else if (hismode == MODE_BROADCAST) { - /* fall through */ - - /* - * If both the originate and receive timestamps are zero, the - * peer has never heard from us. Light the synch bit and pass it - * on for extension field processing. + * The timestamps are valid and the receive packet matches the + * last one sent. If the packet is a crypto-NAK, the server + * might have just changed keys. We demobilize the association + * and wait for better times. */ - } else if (L_ISZERO(&p_org) && L_ISZERO(&p_rec)) { - peer->flash |= TEST3; /* unsynch */ - /* fall through */ - - /* - * If only one of either the originate or receive timestamps is - * nonzero, the packet is from a defective implementation. Just - * dump it. - */ - } else if (L_ISZERO(&p_org) || L_ISZERO(&p_rec)) { + } else if (is_authentic == AUTH_CRYPTO) { + peer_clear(peer, "AUTH"); + if (!(peer->flags & FLAG_CONFIG)) + unpeer(peer); return; - - /* - * All three timestamps are valid. If the association transmit - * timestamp matches the packet originate timestamp, loopback is - * confirmed. - */ - } else if (L_ISEQU(&peer->xmt, &p_org)) { - - /* - * An authentication error probably means the server or - * peer restarted or rolled a new private value, but - * could be an intruder trying to stir up trouble. - * However, if this is a crypto-NAK, we know it is - * authentic. If the server is reachable, restart the - * protocol; if not, ignore it and wait for timeout - */ - if (peer->flash & TEST5) { - if (has_mac == 4 && pkt->exten[0] == 0 && - peer->reach) { -#ifdef DEBUG - if (debug) - printf( - "receive: flash auth %04x\n", - peer->flash); -#endif - if (!(peer->flags & FLAG_CONFIG)) - unpeer(peer); - else - peer_clear(peer, "AUTH"); - return; - } - } - /* fall through */ - - /* - * The packet does not match one previously sent. This probably - * means a packet was lost or peer messages crossed in flight. - * Process the extension field anyway. - */ - } else { - peer->flash |= TEST2; /* bogus */ - /* fall through */ } /* @@ -921,7 +927,7 @@ receive( rval = crypto_recv(peer, rbufp); if (rval != XEVNT_OK) { peer_clear(peer, "CRYP"); - peer->flash |= TEST4; /* crypto error */ + peer->flash |= TEST9; /* crypto error */ if (!(peer->flags & FLAG_CONFIG)) { unpeer(peer); return; @@ -950,7 +956,7 @@ receive( } } if (!(peer->crypto & CRYPTO_FLAG_PROV)) /* test 9 */ - peer->flash |= TEST9; /* not proventic */ + peer->flash |= TEST8; /* not proventic */ /* * If the transmit queue is nonempty, clamp the host @@ -995,10 +1001,9 @@ receive( printf( "receive: flash auto %04x\n", peer->flash); #endif + peer_clear(peer, "AUTO"); if (!(peer->flags & FLAG_CONFIG)) unpeer(peer); - else - peer_clear(peer, "AUTO"); } #endif /* OPENSSL */ } @@ -1051,7 +1056,7 @@ process_packet( } } else if (memcmp(&pkt->refid, "CRYP", 4) == 0) { peer_clear(peer, "CRYP"); - peer->flash |= TEST4; /* crypto error */ + peer->flash |= TEST9; /* crypto error */ if (!(peer->flags & FLAG_CONFIG)) { unpeer(peer); return; @@ -1135,7 +1140,7 @@ process_packet( * computed delay during the client/server volley. Note that * org has been set to the time of last reception. Note the * computation of dispersion includes the system precision plus - * that due to the frequency error since the originate time. + * that due to the frequency error since the origin time. * * It is very important to respect the hazards of overflow. The * only permitted operation on raw timestamps is subtraction, @@ -1248,16 +1253,15 @@ clock_update(void) case -1: report_event(EVNT_SYSFAULT, NULL); exit (-1); - /*NOTREACHED*/ + /* not reached */ /* * Clock was stepped. Flush all time values of all peers. */ case 2: clear_all(); - sys_peer = NULL; sys_stratum = STRATUM_UNSPEC; - memcpy(&sys_refid, "STEP", 4); + memcpy(&sys_refid, "STEP", 4); sys_poll = NTP_MINPOLL; report_event(EVNT_CLOCKRESET, NULL); #ifdef OPENSSL @@ -1439,7 +1443,7 @@ peer_clear( char *ident /* tally lights */ ) { - u_char i; + int i; /* * If cryptographic credentials have been acquired, toss them to @@ -1474,19 +1478,21 @@ peer_clear( value_free(&peer->encrypt); value_free(&peer->sndval); #endif /* OPENSSL */ + if (peer == sys_peer) + sys_peer = NULL; /* * Wipe the association clean and initialize the nonzero values. */ memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO); - if (peer == sys_peer) - sys_peer = NULL; peer->estbdelay = sys_bdelay; - peer->hpoll = peer->minpoll; peer->ppoll = peer->maxpoll; peer->disp = MAXDISPERSE; - peer->jitter = SQRT(MAXDISPERSE); peer->epoch = current_time; + for (i = 0; i < NTP_SHIFT; i++) { + peer->filter_order[i] = i; + peer->filter_disp[i] = MAXDISPERSE; + } #ifdef REFCLOCK if (!(peer->flags & FLAG_REFCLOCK)) { peer->leap = LEAP_NOTINSYNC; @@ -1498,11 +1504,6 @@ peer_clear( peer->stratum = STRATUM_UNSPEC; memcpy(&peer->refid, ident, 4); #endif /* REFCLOCK */ - for (i = 0; i < NTP_SHIFT; i++) { - peer->filter_order[i] = i; - peer->filter_disp[i] = MAXDISPERSE; - peer->filter_epoch[i] = current_time; - } /* * During initialization use the association count to spread out @@ -1514,12 +1515,12 @@ peer_clear( if (initializing) peer->nextdate = current_time + peer_associations; else - peer->nextdate = current_time + (RANDOM % (1 << - NTP_MINPOLL)); + peer->nextdate = current_time + (RANDOM & ((1 << + NTP_MINPOLL) - 1)); #ifdef DEBUG if (debug) - printf("peer_clear: at %ld assoc ID %d refid %s\n", - current_time, peer->associd, ident); + printf("peer_clear: at %ld next %ld assoc ID %d refid %s\n", + current_time, peer->nextdate, peer->associd, ident); #endif } @@ -2297,8 +2298,12 @@ peer_xmit( l_fp xmt_tx; /* - * Initialize the transmit packet header fields. + * If the crypto is broken, don't make it worse. Otherwise, + * initialize the header fields. */ + if (peer->flash & TEST9) + return; + xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, peer->version, peer->hmode); xpkt.stratum = STRATUM_TO_PKT(sys_stratum); @@ -2565,14 +2570,16 @@ peer_xmit( if (exten->opcode != 0) { sendlen += crypto_xmit(&xpkt, &peer->srcadr, sendlen, exten, 0); + free(exten); } else { peer_clear(peer, "CRYP"); - peer->flash |= TEST4; /* crypto error */ + peer->flash |= TEST9; /* crypto error */ msyslog(LOG_INFO, "transmit: crypto error for %s", stoa(&peer->srcadr)); + free(exten); + return; } - free(exten); } /* @@ -2584,14 +2591,6 @@ peer_xmit( xkeyid, 0, 2); } #endif /* OPENSSL */ - - /* - * If something broke go directly to jail without sending the - * packet. - */ - if (peer->flash & TEST4) - return; - xkeyid = peer->keyid; get_systime(&peer->xmt); L_ADD(&peer->xmt, &sys_authdelay); @@ -2599,7 +2598,7 @@ peer_xmit( authlen = authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen); if (authlen == 0) { peer_clear(peer, "NKEY"); - peer->flash |= TEST4; /* no key found */ + peer->flash |= TEST9; /* no key found */ msyslog(LOG_INFO, "transmit: key %u not found for %s", xkeyid, stoa(&peer->srcadr)); return; @@ -3075,6 +3074,7 @@ proto_config( case PROTO_MULTICAST_ADD: if (svalue) io_multicast_add(*svalue); + sys_bclient = 1; break; /*