From: Harlan Stenn Date: Tue, 25 Jul 2000 00:45:02 +0000 (-0000) Subject: Many files: X-Git-Tag: NTP_4_0_99_M~257 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03eebb2f6b9809fac6dd3bad8f01f29d2729065c;p=thirdparty%2Fntp.git Many files: * ntpd/ntp_request.c: * ntpd/ntp_proto.c: * ntpd/ntp_peer.c: * ntpd/ntp_io.c: * ntpd/ntp_intres.c: * ntpd/ntp_crypto.c (make_keylist): * ntpd/ntp_control.c: * ntpd/ntp_config.c (CONF_MOD_IBURST, save_resolve): * include/ntpd.h (findpeerbyassoc, newpeer, peer_config, *_interface): * include/ntp_request.h (CONF_FLAG_IBURST): * include/ntp_crypto.h (crypto_xmit, make_keylist): * include/ntp.h (FLAG_IBURST): * html/release.htm: * html/confopt.htm: * html/assoc.htm: Add iburst option, fix broadcast/multicast and some types. From: Dave Mills bk: 397ce30eCJ_VvQV1LJN2F5eu05rDHw --- diff --git a/ChangeLog b/ChangeLog index 2fa9f3a0cb..86d7867849 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2000-07-24 Harlan Stenn + + * ntpd/ntp_request.c: + * ntpd/ntp_proto.c: + * ntpd/ntp_peer.c: + * ntpd/ntp_io.c: + * ntpd/ntp_intres.c: + * ntpd/ntp_crypto.c (make_keylist): + * ntpd/ntp_control.c: + * ntpd/ntp_config.c (CONF_MOD_IBURST, save_resolve): + * include/ntpd.h (findpeerbyassoc, newpeer, peer_config, *_interface): + * include/ntp_request.h (CONF_FLAG_IBURST): + * include/ntp_crypto.h (crypto_xmit, make_keylist): + * include/ntp.h (FLAG_IBURST): + * html/release.htm: + * html/confopt.htm: + * html/assoc.htm: + Add iburst option, fix broadcast/multicast and some types. + From: Dave Mills + 2000-07-20 Harlan Stenn * scripts/Makefile.am (bin_SCRIPTS): Install ntp-wait diff --git a/configure b/configure index 57028a91a7..92ac3a8db7 100755 --- a/configure +++ b/configure @@ -1091,7 +1091,7 @@ fi PACKAGE=ntp -VERSION=4.0.99k +VERSION=4.0.99k1 if test "`CDPATH=: && cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then diff --git a/configure.in b/configure.in index 592b105a67..e752cc586f 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ AC_CANONICAL_SYSTEM AC_DEFINE_UNQUOTED(STR_SYSTEM, "$target") AM_CONFIG_HEADER(config.h) AC_ARG_PROGRAM -AM_INIT_AUTOMAKE(ntp, 4.0.99k) +AM_INIT_AUTOMAKE(ntp, 4.0.99k1) AC_PREREQ(2.14) ac_cv_var_oncore_ok=no diff --git a/html/assoc.htm b/html/assoc.htm index 69cb7bc5b1..1303a4aa7b 100644 --- a/html/assoc.htm +++ b/html/assoc.htm @@ -1,170 +1,116 @@ - - - - - Release Notes - - - - -

-Association Management

- -
-

-Association Modes

-This release of the NTP Version 4 (NTPv4) daemon for Unix incorporates -new features and refinements to the NTP Version 3 (NTPv3) algorithms. However, -it continues the tradition of retaining backwards compatibility with older -versions. The NTPv4 version has been under development for quite a while -and isn't finished yet. In fact, quite a number of NTPv4 features have -already been implemented in the current NTPv3, including a number of new + +Association Management +

+Association Management +


+ +

Association Modes

+ +The NTP Version 4 incorporates new features and refinements to the NTP +Version 3 (NTPv3) algorithms. However, it continues the tradition of +retaining backwards compatibility with older versions. However, a number +of new features have been implemented, including a number of new operating modes for automatic server discovery and improved accuracy in -occasionally-connected networks. Following is an extended abstract describing -the new features.. - -

An ephemeral association of some mode is mobilized when a message arrives -from another client or server. For instance, a symmetric-passive association -is mobilized upon arrival of a message from a symmetric- active peer. A -client association is mobilized upon arrival of a broadcast message from -a multicast server or a server message from a manycast server. Ephemeral -associations are demobilized when either (a) the server becomes unreachable -or (b) an error occurs on initial contact before the association is mobilized. - -

The one exception to (a) and (b) above is when -autokey is in use and the initial -authentication check fails due to unknown -key identifier or autokey mismatch. This exception is necessary because -the Unix kernel does not bind the local address until the first packet -is received. The result in broadcast mode is a rather painful initial exchange, -where authentication fails until after the first round of messages. The -result in multicast mode is in general fatal, especially if multiple interfaces -are in use. As promiscuous modes such as multicast and manycast require -authentication for reliable and safe operation, autokey is in general useless -with these modes until and if the input/output machinery is overhauled. +occasionally-connected networks. Following is an extended abstract +describing the new features. Additional information is available on the +Configuration Options page.. + +

An ephemeral association of some mode is mobilized when a message +arrives from a server or peer. For instance, a symmetric-passive +association is mobilized upon arrival of a message from a symmetric- +active peer. A client association is mobilized upon arrival of a +broadcast message from a multicast server or a server message from a +manycast server. Ordinarily, successful mobilization requires the server +or peer provide acceptable cryptographic credentials, either using +traditional symmetric-key cryptography or public-key cryptography new to +NTPv4. Ephemeral associations are demobilized when either (a) the server +becomes unreachable or (b) the server refreshes key media without +notifying the client.

Following is a summary of the protocol operations for each mode. -

Peer Modes (Active and Passive) +

Symmetric Modes (Active and Passive) +

    In these modes, two client/server peers agree to back each other up, -should the synchronization source for either peer fail. One or both peers -is configured in symmetric-active mode using the peer command. Alternatively, -one - the active peer - is configured in this mode and the other, the passive -peer, operates in symmetric-passive mode and requires no prior configuration. -Both association scenarios operate in NTPv4 as in NTPv3; however, several -bugs in the handling of keys and recovery of resources when an active peer -fails, have been corrected in NTPv4. The original NTPv3 authentication -scheme is applicable in this mode, as well as the new NTPv3 autokey scheme.
+should the synchronization source for either peer fail. One or both +peers is configured in symmetric-active mode using the peer +command. Alternatively, one - the active peer - is configured in this +mode and the other, the passive peer, operates in symmetric-passive mode +and requires no prior configuration. Both association scenarios operate +in NTPv4 as in NTPv3; however, several bugs in the handling of keys and +recovery of resources when an active peer fails have been corrected in +NTPv4. The original NTPv3 authentication scheme is applicable in this +mode, as well as the new NTPv3 autokey scheme. + Client/Server Modes -
    In these modes, a client sends a request to the server and expects -a reply at some future time. The client is configured in client mode using -the server (sic) command; the server requires no prior configuration. The -original NTPv3 authentication scheme is applicable in this mode, as well -as the new NTPv3 autokey scheme.
+ +
    In these modes, a client sends a request to the server and expects a +reply at some future time. The client is configured in client mode using +the server (sic) command; the server requires no prior +configuration. The original NTPv3 authentication scheme is applicable in +this mode, as well as the new NTPv3 autokey scheme. In addition, the +burst modes described below can be used in appropriate cases.
+ Broadcast/Multicast Modes +
    In these modes, the server generates messages at intervals specified -by the minpoll subcommand. When using IP multicast addresses, the scope -of the multicast tree is specified by the ttl subcommand in hops. When -using a local interface broadcast address, the scope is limited to the -attached subnet. The client responds to the first message received by waiting -an interval randomized over the minpoll interval, in order to avoid implosions. -Then, it polls the server in burst mode, in order to accumulate data to -reliably set the host clock. This normally results in eight client/server -cycles over a 32-s interval. When the next multicast message is received, -the client computes the offset between the system clock just set and the -apparent time of the multicast message in order to correct the apparent -time in future multicast messages.
+by the minpoll keyword to the configuration command. When using +IP multicast addresses, the scope of the multicast tree is specified by +the ttl keyword in hops. When using a local interface broadcast +address, the scope is limited to the attached subnet. The client +responds to the first message received by waiting an interval randomized +over the minpoll interval, in order to avoid implosions. Then, +it polls the server in burst mode in order to accumulate data to +reliably set the host clock. This normally results in eight +client/server cycles over a 30-s interval. When the next multicast +message is received, the client computes the offset between the system +clock just set and the apparent time of the multicast message in order +to correct the apparent time in future multicast messages. + Manycast Mode +
    In this mode, a configured client broadcasts a request message as in -client mode to a designated multicast group address. All servers configured -as manycast clients and in ttl range respond with a server reply message. -Each reply mobilizes a persistent client/server association as in client -mode. Then, the NTP intersection and clustering algorithms act to discard -all but the "best" of these associations, which then continue as in client/server -mode.
- -

-Burst Mode

-Burst mode can be configured when the network attachment requires an initial -calling or training procedure. Each poll initiates a burst of eight request -messages at intervals randomized over the range 3-5 s. The reply messages -update the clock filter, which then selects the best (most accurate) among -them. When the last reply in the burst is sent, the next reply updates -the client variables and system clock in the usual manner, as if only a -single request/reply cycle had occurred. This mode does produce additional -network overhead and can cause trouble if used indiscriminately. It should -only be used where the poll interval is expected to settle to values above -1024 s. -

-Revised Error Checking

-It is very important to avoid spurious mobilizations from possibly broken -or rogue servers; in particular, to avoid denial-of-service attacks. In -order to resist such attacks, arriving messages that might mobilize ephemeral -associations are carefully screened using a series of eleven sanity checks. -
    -
  1. -Duplicate packet. This message is a duplicate of one previously received.
  2. - -
      -
  3. -Bogus packet. This message did not result from a message previously sent, -or messages have been received out of order.
  4. - -
      -
  5. -Unsynchronized. The server has not yet stored the previous timestamps.
  6. - -
      -
  7. -Invalid delay or dispersion. Either the delay or dispersion or both computed -from the message timestamps are above the normal range.
  8. - -
      -
  9. -Authentication failed. The sent MAC does not match the received MAC, either -due to the wrong key material or damaged message.
  10. - -
      -
  11. -Server unsynchronized. The server indicates unsynchronized in the leap -bits included in the packet.
  12. - -
      -
  13. -Server stratum check. The server is operating at a stratum above the normal -range.
  14. - -
      -
  15. -Delay/dispersion check. The related server packet data values are above -the normal range.
  16. - -
      -
  17. -Autokey failed. The hash of the current session key does not match the -most recent key identifiers used. (The hash is repeated four times, in -order to recover from lost packets whenever possible.)
  18. - -
      -
  19. -Access denied. The sender has been blocked by the access control list.
  20. - -
      -
  21. -Key not found. The key identifier does not match any identifier in the -key list or the key has expired or been revoked.
  22. -
-Failure to pass tests 5-11 is sufficient evidence to discard the packet -without forming an association. However, failure to pass tests 1-4 is not -necessarily grounds to reject the packet, since subsequent packets may -be acceptable. In this case, the association is mobilized, but only the -packet timestamps are stored. For the moment, and until the cryptographic -signature algorithm is available, test 9 is temporarily disabled. -
-
-
-David L. Mills (mills@udel.edu)
- -
  - - +client mode to a designated multicast group address. All servers +configured as manycast servers and in ttl range respond with a +server reply message. Each reply mobilizes a persistent client/server +association as in client mode. Then, the NTP intersection and clustering +algorithms act to discard all but the "best" of these associations, +which then continue as in client/server mode. + +

The above scenario happens at each manycast message; however, once +the persisten association has been mobilized, subsequent server replies +are discarded, since they fail one or more of the authentication checks. +It is important in manycast mode to avoid frequeny request messages, +since each one requires all manycast servers in range to respond. The +result could well be an implosion, either minor or major, depending on +the number of servers in range. + +

Burst Modes

+ +

There are two burst modes that can be activated for client/server +mode. One of these iburst is intended for cases where it is +important to set the clock quickly when an association is first +mobilized. It results in good accuracy with intermittent connections +typical of PPP and ISDN services. When enabled, at each poll interval +the client sends eight messages over the next 30-s and processes them in +a batch. However, the interval between the first and subsequent messages +is about 20 s in order for a dialup modem to complete the call. Outlyers +due to initial dial-up delays, etc., are avoided and the client sets the +clock within 30 s after the first message. + +

The other burst mode burst can be configured when the +network attachment requires an initial calling or training procedure. +Each poll initiates a burst of eight request messages at intervals +randomized over the range 3-5 s. The reply messages update the clock +filter, which then selects the best (most accurate) among them. When the +last reply in the burst is sent, the next reply updates the client +variables and system clock in the usual manner, as if only a single +request/reply cycle had occurred. This mode does produce additional +network overhead and can cause trouble if used indiscriminately. It +should only be used where the poll interval is expected to settle to +values above 1024 s. + + +


David L. Mills <mills@udel.edu> +
diff --git a/html/confopt.htm b/html/confopt.htm index e3a8a62980..0c09a51153 100644 --- a/html/confopt.htm +++ b/html/confopt.htm @@ -22,29 +22,25 @@ remote server or peer (IP class A, B and C), (b) the broadcast address of a local interface, (m) a multicast address (IP class D), or (r) a reference clock address (127.127.x.x). Note that some options are not supported by all these commands while autokey and burst modes are -supported by these commands, -their effect in some weird mode combinations can be meaningless -or even destructive. +supported by these commands, their effect in some weird mode +combinations can be meaningless or even destructive.
-
peer address [key key | autokey | publickey -keyfile] [burst] [version version] [prefer] [minpoll -minpoll] [maxpoll maxpoll]
+
peer address [key key | autokey] [version +version] [prefer] [minpoll minpoll] [maxpoll +maxpoll]
-

server address [key key | autokey | publickey -keyfile] [burst] [version version] [prefer] [minpoll -minpoll] [maxpoll maxpoll] [publickey -keyfile]
+

server address [key key | autokey] [burst] +[iburst] [version version] [prefer] [minpoll minpoll] +[maxpoll maxpoll]
-

broadcast address [key key | autokey] [burst] -[version version] [minpoll minpoll] [maxpoll -maxpoll] [ttl ttl]
+

broadcast address [key key | autokey] [version +version] [minpoll minpoll] [ttl ttl]
-

manycastclient address [key key | autokey | -publickey keyfile] [burst] [version version] [minpoll -minpoll [maxpoll maxpoll] [ttl ttl] [publickey -file]
+

manycastclient address [key key | autokey] +[version version] [minpoll minpoll [ttl +ttl]

These four commands specify the time server name or address to be used and the mode in which to operate. The address can be @@ -129,9 +125,13 @@ are discarded as if never heard.
include authentication fields encrypted using the autokey scheme described in the Authentication Options page. +
burst
-
At each poll interval, send a burst of eight packets spaced, instead -of the usual one.
+
At each poll interval, send a burst of eight packets spaced at 1-s +intervals instead of the usual one.
+
iburst
+
At the first poll interval, send a burst of eight packets spaced at +1-s intervals instead of the usual one.
key key
All packets sent to and received from the server or peer are to @@ -152,14 +152,6 @@ host will be chosen for synchronization among a set of correctly operating hosts. See the Mitigation Rules and the prefer Keyword page for further information.
-
publickey file
-
This command requires the NTP daemon build process be configured -with the RSA library. The command specifies the name of the public key -file for the server or peer. The default name for this file is -ntpkey_host, where host is the DNS canonical name -of the server or peer. See the Authentication -Options page for further information.
-
ttl ttl
This option is used only with broadcast mode. It specifies the time-to-live ttl to use on multicast packets. Selection diff --git a/html/release.htm b/html/release.htm index 7f31b38b17..9b4d9c0e00 100644 --- a/html/release.htm +++ b/html/release.htm @@ -51,23 +51,15 @@ in such cases was clamped to the minimum, usually 64 s. For those servers with hundreds of clients, the new design can dramatically reduce the network load. -

  • A burst-mode feature is available which -results in good accuracy with intermittent connections typical of PPP -and ISDN services. When enabled, at each poll interval the server sends -eight messages over the next 30-s interval and processes them in a -batch. However, the interval between the first and subsequent messages -is about 20 s in order for a dialup modem to complete the call. Outlyers -due to initial dial-up delays, etc., are avoided and the server -synchronizes with its peer generally within 30 s.
  • - -

  • In addition to the NTPv3 authentication scheme, which uses -private-key cryptography, a new NTPv4 autokey -authentication scheme is available. Autokey uses public-key -technology and avoids the need to distribute keys by separate means. The -design is such that full accuracy is available without degradation due -to processing demands of the public-key routines. It can be used in any -of the NTP association modes, but is most useful in broadcast/multicast -modes.
  • +

  • There are two burst-mode features available +where special conditions apply. One of these is enabled by the +iburst keyword in the server configuration command. It +is intended for cases where it is important to set the clock quickly +when an association is first mobilized. The other is enabled by the +burst keyword in the server configuration command. It +is intended for cases where the network attachment requires an initial +calling or training procedure. See the Association +Management page for further information.

  • NTPv4 includes two new association modes which in most applications can avoid per-host configuration altogether. Both of these @@ -137,7 +129,6 @@ note the NTP authentication routines use the interface defined in the

  • The enable and disable commands have a few changes in their arguments see the ntpd Configuration Options page for details.
  • -

  • The scheme for enabling the ppsclock line discipline/streams module has changed. Formerly, it was enabled by setting fudge flag3 for the serial port connected to the PPS @@ -187,7 +178,8 @@ kernel command either in the configuration file or via ntpdc.
  • A new pulse-per-second (PPS) generic interface described in Mogul, J., D. Mills, J. +href=http://www.eecis.udel.edu/~mills/reports.htm>Mogul, J., D. Mills, +J. Brittenson, J. Stone and U. Windl. Pulse-per-second API for Unix-like operating systems, version 1. Request for Comments RFC-2783, Internet Engineering Task Force, March 2000, 31 pp is supported. Older diff --git a/include/ntp.h b/include/ntp.h index cf1050f9e6..d96cb65660 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -406,9 +406,10 @@ struct peer { #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 */ +#define FLAG_IBURST 0x0200 /* initial burst mode */ +#define FLAG_SKEY 0x0400 /* autokey authentication */ +#define FLAG_NOSELECT 0x0800 /* this is a "noselect" peer */ +#define FLAG_AUTOKEY 0x1000 /* autokey confirmed */ /* * Definitions for the clear() routine. We use memset() to clear diff --git a/include/ntp_crypto.h b/include/ntp_crypto.h index b9731623df..27b2ae2b67 100644 --- a/include/ntp_crypto.h +++ b/include/ntp_crypto.h @@ -50,11 +50,11 @@ */ extern void crypto_recv P((struct peer *, struct recvbuf *)); extern int crypto_xmit P((u_int32 *, int, u_int, keyid_t, - associd_t)); + u_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 make_keylist P((struct peer *, struct interface *)); extern void key_expire P((struct peer *)); extern void crypto_agree P((void)); #ifdef PUBKEY diff --git a/include/ntp_request.h b/include/ntp_request.h index 4457c6ae9e..8af524814b 100644 --- a/include/ntp_request.h +++ b/include/ntp_request.h @@ -532,11 +532,12 @@ struct conf_peer { char keystr[MAXFILENAME]; /* public key file name*/ }; -#define CONF_FLAG_AUTHENABLE 0x1 -#define CONF_FLAG_PREFER 0x2 -#define CONF_FLAG_BURST 0x4 -#define CONF_FLAG_NOSELECT 0x8 -#define CONF_FLAG_SKEY 0x10 +#define CONF_FLAG_AUTHENABLE 0x01 +#define CONF_FLAG_PREFER 0x02 +#define CONF_FLAG_BURST 0x04 +#define CONF_FLAG_IBURST 0x08 +#define CONF_FLAG_NOSELECT 0x10 +#define CONF_FLAG_SKEY 0x20 /* * Structure for passing peer deletion information. Currently diff --git a/include/ntpd.h b/include/ntpd.h index 852ed63e2d..b077c984b5 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -124,18 +124,17 @@ extern void ntp_monitor P((struct recvbuf *)); extern void init_peer P((void)); extern struct peer *findexistingpeer P((struct sockaddr_in *, struct peer *, int)); extern struct peer *findpeer P((struct sockaddr_in *, struct interface *, int, int, int *)); -extern struct peer *findpeerbyassoc P((associd_t)); -extern struct peer *newpeer P((struct sockaddr_in *, struct interface *, int, int, int, int, int, u_long)); +extern struct peer *findpeerbyassoc P((u_int)); +extern struct peer *newpeer P((struct sockaddr_in *, struct interface *, int, int, int, int, u_int, int, keyid_t)); 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, keyid_t, u_char *)); +extern struct peer *peer_config P((struct sockaddr_in *, struct interface *, int, int, int, int, u_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 *)); extern void clear_all P((void)); extern void expire_all P((void)); extern struct peer *findmanycastpeer P((l_fp *)); -extern void peer_config_manycast P((struct peer *, struct peer *)); /* ntp_proto.c */ extern void transmit P((struct peer *)); @@ -252,8 +251,9 @@ extern u_long io_timereset; /* time counters were reset */ /* * Interface stuff */ -extern struct interface *any_interface; /* pointer to default interface */ -extern struct interface *loopback_interface; /* point to loopback interface */ +extern struct interface *any_interface; /* default interface */ +extern struct interface *loopback_interface; /* loopback interface */ +extern struct interface *mcast_interface; /* multicast interface */ /* * File descriptor masks etc. for call to select diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index 0225127c65..0a28bbad92 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -154,12 +154,13 @@ extern int priority_done; #define CONF_MOD_MAXPOLL 4 #define CONF_MOD_PREFER 5 #define CONF_MOD_BURST 6 -#define CONF_MOD_SKEY 7 -#define CONF_MOD_TTL 8 -#define CONF_MOD_MODE 9 -#define CONF_MOD_NOSELECT 10 +#define CONF_MOD_IBURST 7 +#define CONF_MOD_SKEY 8 +#define CONF_MOD_TTL 9 +#define CONF_MOD_MODE 10 +#define CONF_MOD_NOSELECT 11 #ifdef PUBKEY -#define CONF_MOD_PUBLICKEY 11 +#define CONF_MOD_PUBLICKEY 12 #endif /* PUBKEY */ /* @@ -282,6 +283,7 @@ static struct keyword keywords[] = { static struct keyword mod_keywords[] = { { "autokey", CONF_MOD_SKEY }, { "burst", CONF_MOD_BURST }, + { "iburst", CONF_MOD_IBURST }, { "key", CONF_MOD_KEY }, { "maxpoll", CONF_MOD_MAXPOLL }, { "minpoll", CONF_MOD_MINPOLL }, @@ -509,7 +511,7 @@ 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, +static void save_resolve P((char *, int, int, int, int, u_int, int, keyid_t, u_char *)); static void do_resolve_internal P((void)); static void abort_resolve P((void)); @@ -715,7 +717,7 @@ getconfig( keyid_t peerkey; u_char *peerkeystr; u_long fudgeflag; - int peerflags; + u_int peerflags; int hmode; struct sockaddr_in peeraddr; struct sockaddr_in maskaddr; @@ -1100,6 +1102,10 @@ getconfig( case CONF_MOD_BURST: peerflags |= FLAG_BURST; break; + + case CONF_MOD_IBURST: + peerflags |= FLAG_IBURST; + break; #ifdef AUTOKEY case CONF_MOD_SKEY: peerflags |= FLAG_SKEY | @@ -1160,10 +1166,9 @@ getconfig( } } else if (errflg == -1) { - save_resolve(tokens[1], hmode, - peerversion, minpoll, maxpoll, - peerflags, ttl, peerkey, - peerkeystr); + save_resolve(tokens[1], hmode, peerversion, + minpoll, maxpoll, peerflags, ttl, + peerkey, peerkeystr); } break; @@ -1255,20 +1260,10 @@ getconfig( } else proto_config(PROTO_MULTICAST_ADD, htonl(INADDR_NTP), 0.); - if (tok == CONFIG_MULTICASTCLIENT) { + if (tok == CONFIG_MULTICASTCLIENT) sys_bclient = 1; -#ifdef DEBUG - if (debug) - printf("sys_bclient\n"); -#endif /* DEBUG */ - } - else if (tok == CONFIG_MANYCASTSERVER) { + else if (tok == CONFIG_MANYCASTSERVER) sys_manycastserver = 1; -#ifdef DEBUG - if (debug) - printf("sys_manycastserver\n"); -#endif /* DEBUG */ - } break; case CONFIG_AUTHENTICATE: @@ -1801,10 +1796,9 @@ getconfig( break; } } - if (!errflg) { + if (!errflg) filegen_config(filegen, tokens[peerversion], - (u_char)peerkey, (u_char)peerflags); - } + (u_char)peerkey, (u_char)peerflags); break; case CONFIG_SETVAR: @@ -2340,7 +2334,7 @@ save_resolve( int version, int minpoll, int maxpoll, - int flags, + u_int flags, int ttl, keyid_t keyid, u_char *keystr @@ -2388,7 +2382,7 @@ save_resolve( 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, + printf("config: %s %d %d %d %d %x %d %08x %s\n", name, mode, version, minpoll, maxpoll, flags, ttl, keyid, keystr); #endif diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index 2c5c67764d..18c1f26e4b 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -425,7 +425,7 @@ u_long numasyncmsgs; /* number of async messages we've sent */ static struct ntp_control rpkt; static u_char res_version; static u_char res_opcode; -static u_short res_associd; +static associd_t res_associd; static int res_offset; static u_char * datapt; static u_char * dataend; @@ -1860,7 +1860,7 @@ control_unspec( * doesn't exist. */ if (res_associd != 0) { - if ((peer = findpeerbyassoc((int)res_associd)) == 0) { + if ((peer = findpeerbyassoc(res_associd)) == 0) { ctl_error(CERR_BADASSOC); return; } @@ -1921,7 +1921,7 @@ read_status( sizeof(u_short), 1); ctl_flushpkt(0); } else { - peer = findpeerbyassoc((int)res_associd); + peer = findpeerbyassoc(res_associd); if (peer == 0) { ctl_error(CERR_BADASSOC); } else { @@ -2020,7 +2020,7 @@ read_variables( * Wants info for a particular peer. See if we know * the guy. */ - peer = findpeerbyassoc((int)res_associd); + peer = findpeerbyassoc(res_associd); if (peer == 0) { ctl_error(CERR_BADASSOC); return; @@ -2209,7 +2209,7 @@ read_clock_status( } } } else { - peer = findpeerbyassoc((int)res_associd); + peer = findpeerbyassoc(res_associd); if (peer == 0 || !(peer->flags & FLAG_REFCLOCK)) { ctl_error(CERR_BADASSOC); return; diff --git a/ntpd/ntp_crypto.c b/ntpd/ntp_crypto.c index 3efb93aaeb..8186a54c87 100644 --- a/ntpd/ntp_crypto.c +++ b/ntpd/ntp_crypto.c @@ -178,7 +178,8 @@ session_key( */ void make_keylist( - struct peer *peer /* peer structure pointer */ + struct peer *peer, /* peer structure pointer */ + struct interface *dstadr /* interface */ ) { struct autokey *ap; /* autokey pointer */ @@ -224,8 +225,8 @@ make_keylist( * 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); + peer->hcookie = session_key(&dstadr->sin, &peer->srcadr, 0, + sys_private, 0); if (peer->hmode == MODE_BROADCAST) cookie = 0; else @@ -233,9 +234,8 @@ make_keylist( for (i = 0; i < NTP_MAXSESSION; 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); + keyid = session_key(&dstadr->sin, &peer->srcadr, keyid, + cookie, ltemp); ltemp -= 1 << peer->kpoll; if (auth_havekey(keyid) || keyid <= NTP_MAXKEY || ltemp <= (1 << (peer->kpoll + 1))) @@ -817,7 +817,7 @@ crypto_xmit( int start, /* offset to extension field */ u_int code, /* extension field code */ keyid_t cookie, /* session cookie */ - associd_t associd /* association ID */ + u_int associd /* association ID */ ) { struct peer *peer; /* peer structure pointer */ diff --git a/ntpd/ntp_intres.c b/ntpd/ntp_intres.c index ad333fa5e7..fd1774f4ed 100644 --- a/ntpd/ntp_intres.c +++ b/ntpd/ntp_intres.c @@ -138,7 +138,7 @@ 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, +static void addentry P((char *, int, int, int, int, u_int, int, keyid_t, char *)); static int findhostaddr P((struct conf_entry *)); static void openntp P((void)); @@ -160,7 +160,7 @@ struct ntp_res_c_pkt { /* Control packet: */ int version; int minpoll; int maxpoll; - int flags; + u_int flags; int ttl; keyid_t keyid; u_char keystr[MAXFILENAME]; @@ -387,7 +387,7 @@ addentry( int version, int minpoll, int maxpoll, - int flags, + u_int flags, int ttl, keyid_t keyid, char *keystr @@ -400,9 +400,9 @@ addentry( #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); + "intres: <%s> %d %d %d %d %x %d %x %s\n", name, + mode, version, minpoll, maxpoll, flags, ttl, keyid, + keystr); #endif len = strlen(name) + 1; cp = (char *)emalloc(len); @@ -923,7 +923,7 @@ readconf( register int i; char *token[NUMTOK]; u_long intval[NUMTOK]; - int flags; + u_int flags; char buf[MAXLINESIZE]; char *bp; @@ -977,7 +977,7 @@ readconf( } if ((intval[TOK_FLAGS] & ~(FLAG_AUTHENABLE | FLAG_PREFER | - FLAG_NOSELECT | FLAG_BURST | FLAG_SKEY)) + FLAG_NOSELECT | FLAG_BURST | FLAG_IBURST | FLAG_SKEY)) != 0) { msyslog(LOG_ERR, "invalid flags (%ld) in file %s", intval[TOK_FLAGS], name); @@ -993,6 +993,8 @@ readconf( flags |= CONF_FLAG_NOSELECT; if (intval[TOK_FLAGS] & FLAG_BURST) flags |= CONF_FLAG_BURST; + if (intval[TOK_FLAGS] & FLAG_IBURST) + flags |= CONF_FLAG_IBURST; if (intval[TOK_FLAGS] & FLAG_SKEY) flags |= CONF_FLAG_SKEY; diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c index 6ab7d267d8..5934277be6 100644 --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@ -116,8 +116,9 @@ u_long io_timereset; /* time counters were reset */ /* * Interface stuff */ -struct interface *any_interface; /* pointer to default interface */ -struct interface *loopback_interface; /* point to loopback interface */ +struct interface *any_interface; /* default interface */ +struct interface *loopback_interface; /* loopback interface */ +struct interface *mcast_interface; /* multicast interface */ static struct interface inter_list[MAXINTERFACES]; static int ninterfaces; @@ -241,6 +242,7 @@ create_sockets( inter_list[0].sent = 0; inter_list[0].notsent = 0; inter_list[0].flags = INT_BROADCAST; + any_interface = &inter_list[0]; #if _BSDI_VERSION >= 199510 #if _BSDI_VERSION >= 199701 @@ -274,46 +276,32 @@ create_sockets( if ((ifap->ifa_flags & IFF_UP) == 0) continue; - if (ifap->ifa_flags & IFF_LOOPBACK) - { + if (ifap->ifa_flags & IFF_LOOPBACK) { sin = (struct sockaddr_in *)ifap->ifa_addr; if (ntohl(sin->sin_addr.s_addr) != 0x7f000001) - { continue; - } } - inter_list[i].flags = 0; if (ifap->ifa_flags & IFF_BROADCAST) - inter_list[i].flags |= INT_BROADCAST; - - (void)strcpy(inter_list[i].name, ifap->ifa_name); - + inter_list[i].flags |= INT_BROADCAST; + strcpy(inter_list[i].name, ifap->ifa_name); sin = (struct sockaddr_in *)ifap->ifa_addr; inter_list[i].sin = *sin; inter_list[i].sin.sin_port = port; - - if (ifap->ifa_flags & IFF_LOOPBACK) - { + if (ifap->ifa_flags & IFF_LOOPBACK) { inter_list[i].flags = INT_LOOPBACK; if (loopback_interface == NULL || ntohl(sin->sin_addr.s_addr) != 0x7f000001) loopback_interface = &inter_list[i]; } - - if (inter_list[i].flags & INT_BROADCAST) - { + if (inter_list[i].flags & INT_BROADCAST) { sin = (struct sockaddr_in *)ifap->ifa_broadaddr; inter_list[i].bcast = *sin; inter_list[i].bcast.sin_port = port; } - - if (ifap->ifa_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) - { + if (ifap->ifa_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) { inter_list[i].mask.sin_addr.s_addr = 0xffffffff; - } - else - { + } else { sin = (struct sockaddr_in *)ifap->ifa_netmask; inter_list[i].mask = *sin; } @@ -613,10 +601,16 @@ create_sockets( ninterfaces = i; maxactivefd = 0; FD_ZERO(&activefds); + + /* + * There is a crock here. We set mcast_interface to the first + * non-loopback interface. + */ for (i = 0; i < ninterfaces; i++) { - inter_list[i].fd = - open_socket(&inter_list[i].sin, - inter_list[i].flags & INT_BROADCAST, 0); + inter_list[i].fd = open_socket(&inter_list[i].sin, + inter_list[i].flags & INT_BROADCAST, 0); + if (!(inter_list[i].flags & INT_LOOPBACK)) + mcast_interface = &inter_list[i]; } /* @@ -653,13 +647,13 @@ create_sockets( */ resmask.sin_addr.s_addr = ~ (u_int32)0; for (i = 1; i < ninterfaces; i++) - hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask, - RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE); - - any_interface = &inter_list[0]; + hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask, + RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE); #ifdef DEBUG - if (debug > 2) { + if (debug > 1) { printf("create_sockets: ninterfaces=%d\n", ninterfaces); + printf("multicast %s\n", + inet_ntoa(mcast_interface->sin.sin_addr)); for (i = 0; i < ninterfaces; i++) { printf("interface %d: fd=%d, bfd=%d, name=%.8s, flags=0x%x\n", i, @@ -1131,7 +1125,7 @@ findbcastinter( return &inter_list[i]; } #endif /* SIOCGIFCONF */ - return any_interface; + return mcast_interface; } @@ -1172,13 +1166,6 @@ sendpkt( #else #define badaddrs ((struct cache *)0) /* Only used in empty loops! */ #endif - - /* - * check if the source address is a multicast address - replace - * interface with any-interface if so. - */ - if (IN_MULTICAST(ntohl(inter->sin.sin_addr.s_addr))) - inter = any_interface; #ifdef DEBUG if (debug > 1) printf("%ssendpkt(fd=%d dst=%s, src=%s, ttl=%d, len=%d)\n", diff --git a/ntpd/ntp_peer.c b/ntpd/ntp_peer.c index 9969940a0f..33b4b62825 100644 --- a/ntpd/ntp_peer.c +++ b/ntpd/ntp_peer.c @@ -308,7 +308,7 @@ findpeer( */ struct peer * findpeerbyassoc( - associd_t assoc + u_int assoc ) { register struct peer *peer; @@ -511,7 +511,7 @@ peer_config( int version, int minpoll, int maxpoll, - int flags, + u_int flags, int ttl, keyid_t key, u_char *keystr @@ -556,19 +556,10 @@ peer_config( * structure for him. */ peer = newpeer(srcadr, dstadr, hmode, version, minpoll, - maxpoll, ttl, key); + maxpoll, flags | FLAG_CONFIG, 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 %08x\n", - ntoa(&peer->srcadr), peer->hmode, peer->version, - peer->minpoll, peer->maxpoll, peer->flags, peer->ttl, - peer->keyid); -#endif #ifdef PUBKEY if (!(peer->flags & FLAG_SKEY) || peer->hmode == MODE_BROADCAST) return (peer); @@ -591,8 +582,9 @@ newpeer( int version, int minpoll, int maxpoll, + u_int flags, int ttl, - u_long key + keyid_t key ) { register struct peer *peer; @@ -638,6 +630,7 @@ newpeer( peer->version = (u_char)version; peer->minpoll = (u_char)minpoll; peer->maxpoll = (u_char)maxpoll; + peer->flags = flags; peer->hpoll = peer->minpoll; peer->ppoll = peer->minpoll; peer->ttl = ttl; @@ -648,7 +641,7 @@ newpeer( peer->stratum = STRATUM_UNSPEC; peer_clear(peer); peer->update = peer->outdate = current_time; - peer->nextdate = peer->outdate + (RANDOM & ((1 << NTP_MINDPOLL) - 1)); + peer->nextdate = peer->outdate + (RANDOM & ((1 << NTP_MINPOLL) - 1)); /* * Assign him an association ID and increment the system variable @@ -698,8 +691,11 @@ newpeer( assoc_hash_count[i]++; #ifdef DEBUG if (debug) - printf("mobilize %u %d next %lu\n", peer->associd, - peer_associations, peer->nextdate - peer->outdate); + printf( + "newpeer: %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; } @@ -747,20 +743,6 @@ peer_unconfig( return num_found; } -/* - * peer_copy_manycast - copy manycast peer variables to new association - * (right now it simply copies the transmit timestamp) - */ -void -peer_config_manycast( - struct peer *peer1, - struct peer *peer2 - ) -{ - peer2->cast_flags = MDF_ACAST; - peer2->xmt = peer1->xmt; -} - /* * peer_clr_stats - clear peer module stat counters */ diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index c5a198d6d1..ef0296bdc8 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -134,13 +134,10 @@ transmit( } } hpoll = peer->minpoll; - if (peer->flags & FLAG_BURST) { - if (peer->flags & FLAG_MCAST2) - peer->burst = NTP_SHIFT; - else - peer->burst = 2; - } - + if (peer->flags & FLAG_IBURST) + peer->burst = NTP_SHIFT; + else if (peer->flags & FLAG_BURST) + peer->burst = 2; } else { /* @@ -178,8 +175,8 @@ transmit( * keylist, since no further transmissions will * be made. */ + peer->flags &= ~FLAG_IBURST; if (peer->flags & FLAG_MCAST2) { - peer->flags &= ~FLAG_BURST; peer->hmode = MODE_BCLIENT; #ifdef AUTOKEY key_expire(peer); @@ -232,6 +229,7 @@ receive( keyid_t skeyid; /* cryptographic keys */ #ifdef AUTOKEY keyid_t pkeyid, tkeyid; /* cryptographic keys */ + struct sockaddr_in *dstadr_sin; /* active runway */ #endif /* AUTOKEY */ struct peer *peer2; int retcode = AM_NOMATCH; @@ -311,7 +309,7 @@ receive( } } if ((PKT_MODE(pkt->li_vn_mode) == MODE_BROADCAST && - !sys_bclient)) + !sys_bclient) || rbufp->dstadr == any_interface) return; /* @@ -363,10 +361,17 @@ receive( * 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. + * + * More on the autokey mambo. Normally the local interface + * address is the unicast one. However, if the sender is a + * broadcaster, the broadcast address is used. Notwithstanding + * that, if the sender is a multicaster, the broadcast address + * is null, so use the unicast address anyway. Don't ask. */ peer = findpeer(&rbufp->recv_srcadr, rbufp->dstadr, rbufp->fd, hismode, &retcode); is_authentic = 0; + dstadr_sin = &rbufp->dstadr->sin; if (has_mac == 0) { #ifdef DEBUG if (debug) @@ -409,51 +414,38 @@ receive( * * # if unsync, 0 * % can't happen - * - * You won't believe this. If in passive mode - * and peer->assoc is nonzero, the active peer - * has previously synchronized and will be using - * nonzero cookie. If peer->assoc is zero, that - * never happened and his cookie is zero. What - * tangled cookies we weave. */ if (hismode == MODE_BROADCAST) { pkeyid = 0; + if (rbufp->dstadr->bcast.sin_addr.s_addr + != 0) + dstadr_sin = + &rbufp->dstadr->bcast; } else if (peer == 0) { pkeyid = session_key( - &rbufp->recv_srcadr, - &rbufp->dstadr->sin, 0, sys_private, - 0); + &rbufp->recv_srcadr, dstadr_sin, 0, + sys_private, 0); } else { pkeyid = peer->pcookie.key; } /* * 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. In case of an extension + * values and cookie. In case of an extension * field, the cookie used for authentication * purposes is zero. Note the hash is saved for * use later in the autokey mambo. */ - if (hismode == MODE_BROADCAST) { - tkeyid = session_key( - &rbufp->recv_srcadr, - &rbufp->dstadr->bcast, skeyid, - pkeyid, 2); - } else if (authlen > LEN_PKT_NOMAC) { + if (authlen > LEN_PKT_NOMAC && pkeyid != 0) { session_key(&rbufp->recv_srcadr, - &rbufp->dstadr->sin, skeyid, 0, 2); + dstadr_sin, skeyid, 0, 2); tkeyid = session_key( - &rbufp->recv_srcadr, - &rbufp->dstadr->sin, skeyid, pkeyid, - 0); + &rbufp->recv_srcadr, dstadr_sin, + skeyid, pkeyid, 0); } else { tkeyid = session_key( - &rbufp->recv_srcadr, - &rbufp->dstadr->sin, skeyid, pkeyid, - 2); + &rbufp->recv_srcadr, dstadr_sin, + skeyid, pkeyid, 2); } } @@ -508,6 +500,9 @@ receive( * zero to tell the caller about this. */ if (!sys_bclient || sys_manycastserver) { + if (IN_CLASSD( + ntohl(dstadr_sin->sin_addr.s_addr))) + rbufp->dstadr = mcast_interface; if (is_authentic) fast_xmit(rbufp, MODE_SERVER, skeyid); else @@ -526,7 +521,7 @@ receive( * be properly authenticated and it's darn funny of the * manycaster isn't around now. */ - if ((sys_authenticate && !is_authentic)) { + if (sys_authenticate && !is_authentic) { is_error = 1; break; } @@ -544,12 +539,14 @@ receive( */ peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, MODE_CLIENT, PKT_VERSION(pkt->li_vn_mode), - NTP_MINDPOLL, NTP_MAXDPOLL, 0, skeyid); + NTP_MINDPOLL, NTP_MAXDPOLL, FLAG_IBURST | + (peer2->flags & (FLAG_AUTHENABLE | FLAG_SKEY)), 0, + skeyid); if (peer == 0) { is_error = 1; break; } - peer_config_manycast(peer2, peer); + peer->cast_flags |= peer2->flags & MDF_ACAST; #if defined(PUBKEY) && 0 if (crypto_flags) ntp_res_name(peer->srcadr.sin_addr.s_addr, @@ -579,7 +576,7 @@ receive( } peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, MODE_PASSIVE, PKT_VERSION(pkt->li_vn_mode), - NTP_MINDPOLL, NTP_MAXDPOLL, 0, skeyid); + NTP_MINDPOLL, NTP_MAXDPOLL, 0, 0, skeyid); #if defined(PUBKEY) && 0 if (crypto_flags) ntp_res_name(peer->srcadr.sin_addr.s_addr, @@ -600,10 +597,10 @@ receive( } peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, MODE_MCLIENT, PKT_VERSION(pkt->li_vn_mode), - NTP_MINDPOLL, NTP_MAXDPOLL, 0, skeyid); + NTP_MINDPOLL, NTP_MAXDPOLL, 0, 0, skeyid); if (peer == 0) break; - peer->flags |= FLAG_MCAST1 | FLAG_MCAST2 | FLAG_BURST; + peer->flags |= FLAG_MCAST1 | FLAG_MCAST2 | FLAG_IBURST; peer->hmode = MODE_CLIENT; #if defined(PUBKEY) && 0 if (crypto_flags) @@ -725,6 +722,7 @@ receive( peer->pkeyid = skeyid; } else { int i; + for (i = 0; ; i++) { if (tkeyid == peer->pkeyid || tkeyid == peer->recauto.key) { @@ -734,34 +732,19 @@ receive( } if (i > peer->recauto.seq) 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); + tkeyid = session_key( + &rbufp->recv_srcadr, dstadr_sin, + tkeyid, pkeyid, 0); } } #ifdef PUBKEY /* * If the autokey boogie fails, the server may be bogus - * or worse. Raise an alarm and retrieve the autokey - * values again. If the server has in fact come up with - * new autokey values, this saves a timeout and general - * reset. On the other hand, an intruder could replay at - * speed packets from old associations with different - * cookies, which would cause needless server requests - * and burdensome responses. Since victim client sends a - * message only at poll intervals and victim server - * burns no PKI cycles, the attack doesn't do much harm. + * or worse. If the server has new autokey values, but + * the client has not seen them, the result will be + * timeout and general reset. The alternative is a + * vulnerability to self-interference in manycast mode. */ - if (peer->flash & TEST10) - peer->flags &= ~FLAG_AUTOKEY; if (!(peer->flags & FLAG_AUTOKEY)) peer->flash |= TEST11; @@ -1119,7 +1102,7 @@ poll_update( if (peer->burst > 0) { if (peer->nextdate != current_time) return; - if (peer->flags & FLAG_REFCLOCK) + if (peer->flags & (FLAG_REFCLOCK | FLAG_IBURST)) peer->nextdate++; else if (peer->reach & 0x1) peer->nextdate += RANDPOLL(BURST_INTERVAL2); @@ -1131,13 +1114,13 @@ poll_update( peer->nextdate = peer->outdate + RANDPOLL(peer->kpoll); } +#ifdef AUTOKEY /* * 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->kpoll != oldpoll) key_expire(peer); #endif /* AUTOKEY */ @@ -1184,7 +1167,7 @@ peer_clear( */ peer->flags &= ~FLAG_AUTOKEY; if (peer->flags & FLAG_MCAST2) { - peer->flags |= FLAG_MCAST1 | FLAG_BURST; + peer->flags |= FLAG_MCAST1 | FLAG_IBURST; peer->hmode = MODE_CLIENT; } memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO); @@ -1811,12 +1794,23 @@ peer_xmit( ) { struct pkt xpkt; /* transmit packet */ - int find_rtt = (peer->cast_flags & MDF_MCAST) && - peer->hmode != MODE_BROADCAST; + int find_rtt; + struct interface *dstadr; int sendlen, pktlen; keyid_t xkeyid; /* transmit key ID */ l_fp xmt_tx; + /* + * Nonsense time. If multicast or if the interface is not bound, + * use the multicast interface. Mommy swat me for this is ugly. + */ + find_rtt = (peer->cast_flags & MDF_MCAST) && peer->hmode != + MODE_BROADCAST; + if (find_rtt || peer->dstadr == any_interface) + dstadr = mcast_interface; + else + dstadr = peer->dstadr; + /* * Initialize transmit packet header fields. */ @@ -1838,22 +1832,18 @@ peer_xmit( * 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. + * In the current I/O semantics the default interface is set + * until after receiving a packet and setting the right + * interface. 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) || - (peer->dstadr->sin.sin_addr.s_addr == 0 && - peer->dstadr->bcast.sin_addr.s_addr == 0)) { + if (!(peer->flags & FLAG_AUTHENABLE)) { 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); + sendpkt(&peer->srcadr, dstadr, ((peer->cast_flags & + MDF_MCAST) && !find_rtt) ? ((peer->cast_flags & + MDF_ACAST) ? -7 : peer->ttl) : -8, &xpkt, sendlen); peer->sent++; #ifdef DEBUG if (debug) @@ -1918,7 +1908,7 @@ peer_xmit( * it. */ if (peer->keynumber == 0) - make_keylist(peer); + make_keylist(peer, dstadr); else peer->keynumber--; xkeyid = peer->keylist[peer->keynumber]; @@ -2012,7 +2002,8 @@ peer_xmit( (peer->cmmd >> 16) != CRYPTO_AUTO) sendlen += crypto_xmit((u_int32 *)&xpkt, sendlen, CRYPTO_AUTO | CRYPTO_RESP, - peer->hcookie, peer->associd); + peer->hcookie, + peer->associd); #ifdef PUBKEY else if (crypto_flags & CRYPTO_FLAG_TAI && sys_tai == 0) @@ -2071,10 +2062,8 @@ peer_xmit( * 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); + session_key(&dstadr->sin, &peer->srcadr, xkeyid, + 0, 2); } #endif /* AUTOKEY */ xkeyid = peer->keyid; @@ -2092,10 +2081,9 @@ peer_xmit( msyslog(LOG_ERR, "buffer overflow %u", pktlen); exit(-1); } - 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); + sendpkt(&peer->srcadr, 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 @@ -2217,7 +2205,7 @@ fast_xmit( CRYPTO_RESP; sendlen += crypto_xmit((u_int32 *)&xpkt, sendlen, code, cookie, - (u_int)htonl(rpkt->exten[1])); + htonl(rpkt->exten[1])); } else { session_key(&rbufp->dstadr->sin, &rbufp->recv_srcadr, xkeyid, cookie, 2); diff --git a/ntpd/ntp_request.c b/ntpd/ntp_request.c index 452d7e1cae..bc9133d36c 100644 --- a/ntpd/ntp_request.c +++ b/ntpd/ntp_request.c @@ -1134,7 +1134,7 @@ do_conf( struct req_pkt *inpkt ) { - int fl; + u_int fl; register struct conf_peer *cp; register int items; struct sockaddr_in peeraddr; @@ -1156,8 +1156,9 @@ do_conf( && cp->hmode != MODE_CLIENT && cp->hmode != MODE_BROADCAST) fl = 1; - if (cp->flags & ~(CONF_FLAG_AUTHENABLE | CONF_FLAG_PREFER - | CONF_FLAG_NOSELECT | CONF_FLAG_BURST | CONF_FLAG_SKEY)) + if (cp->flags & ~(CONF_FLAG_AUTHENABLE | CONF_FLAG_PREFER | + CONF_FLAG_NOSELECT | CONF_FLAG_BURST | CONF_FLAG_IBURST | + CONF_FLAG_SKEY)) fl = 1; cp++; } @@ -1197,13 +1198,15 @@ do_conf( while (items-- > 0) { fl = 0; if (cp->flags & CONF_FLAG_AUTHENABLE) - fl |= FLAG_AUTHENABLE; + fl |= FLAG_AUTHENABLE; if (cp->flags & CONF_FLAG_PREFER) - fl |= FLAG_PREFER; + fl |= FLAG_PREFER; if (cp->flags & CONF_FLAG_NOSELECT) - fl |= FLAG_NOSELECT; + fl |= FLAG_NOSELECT; if (cp->flags & CONF_FLAG_BURST) - fl |= FLAG_BURST; + fl |= FLAG_BURST; + if (cp->flags & CONF_FLAG_IBURST) + fl |= FLAG_IBURST; if (cp->flags & CONF_FLAG_SKEY) fl |= FLAG_SKEY; peeraddr.sin_addr.s_addr = cp->peeraddr; @@ -1270,13 +1273,13 @@ dns_a( } while (items-- > 0) { - u_short associd; + associd_t associd; size_t hnl; struct peer *peer; int bogon = 0; associd = dp->associd; - peer = findpeerbyassoc((int)associd); + peer = findpeerbyassoc(associd); if (peer == 0 || peer->flags & FLAG_REFCLOCK) { msyslog(LOG_ERR, "dns_a: %s", (peer == 0) @@ -1420,7 +1423,7 @@ setclr_flags( u_long set ) { - register u_long flags; + register u_int flags; if (INFO_NITEMS(inpkt->err_nitems) > 1) { msyslog(LOG_ERR, "setclr_flags: err_nitems > 1"); @@ -1433,7 +1436,7 @@ setclr_flags( if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_AUTHENTICATE | SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN)) { - msyslog(LOG_ERR, "setclr_flags: extra flags: %#lx", + msyslog(LOG_ERR, "setclr_flags: extra flags: %#x", flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_AUTHENTICATE | SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN));