ntp: restrict authentication of server/peer to specified key
When a server/peer was specified with a key number to enable
authentication with a symmetric key, packets received from the
server/peer were accepted if they were authenticated with any of
the keys contained in the key file and not just the specified key.
This allowed an attacker who knew one key of a client/peer to modify
packets from its servers/peers that were authenticated with other
keys in a man-in-the-middle (MITM) attack. For example, in a network
where each NTP association had a separate key and all hosts had only
keys they needed, a client of a server could not attack other clients
of the server, but it could attack the server and also attack its own
clients (i.e. modify packets from other servers).
To not allow the server/peer to be authenticated with other keys
extend the authentication test to check if the key ID in the received
packet is equal to the configured key number. As a consequence, it's
no longer possible to authenticate two peers to each other with two
different keys, both peers have to be configured to use the same key.
This issue was discovered by Matt Street of Cisco ASIG.
Miroslav Lichvar [Mon, 30 Mar 2015 13:13:27 +0000 (15:13 +0200)]
cmdmon: fix initialization of allocated reply slots
When allocating memory to save unacknowledged replies to authenticated
command requests, the last "next" pointer was not initialized to NULL.
When all allocated reply slots were used, the next reply could be
written to an invalid memory instead of allocating a new slot for it.
An attacker that has the command key and is allowed to access cmdmon
(only localhost is allowed by default) could exploit this to crash
chronyd or possibly execute arbitrary code with the privileges of the
chronyd process.
Miroslav Lichvar [Mon, 30 Mar 2015 12:41:37 +0000 (14:41 +0200)]
addrfilt: fix access configuration with subnet size indivisible by 4
When NTP or cmdmon access was configured (from chrony.conf or via
authenticated cmdmon) with a subnet size that is indivisible by 4 and
an address that has nonzero bits in the 4-bit subnet remainder (e.g.
192.168.15.0/22 or f000::/3), the new setting was written to an
incorrect location, possibly outside the allocated array.
An attacker that has the command key and is allowed to access cmdmon
(only localhost is allowed by default) could exploit this to crash
chronyd or possibly execute arbitrary code with the privileges of the
chronyd process.
ntp: protect authenticated symmetric associations against DoS attacks
An attacker knowing that NTP hosts A and B are peering with each other
(symmetric association) can send a packet with random timestamps to host
A with source address of B which will set the NTP state variables on A
to the values sent by the attacker. Host A will then send on its next
poll to B a packet with originate timestamp that doesn't match the
transmit timestamp of B and the packet will be dropped. If the attacker
does this periodically for both hosts, they won't be able to synchronize
to each other. It is a denial-of-service attack.
According to [1], NTP authentication is supposed to protect symmetric
associations against this attack, but in the NTPv3 (RFC 1305) and NTPv4
(RFC 5905) specifications the state variables are updated before the
authentication check is performed, which means the association is
vulnerable to the attack even when authentication is enabled.
To fix this problem, save the originate and local timestamps only when
the authentication check (test5) passed.
When current time is within 5 seconds of a leap second, don't accumulate
new samples or update the leap second status to increase the chances of
getting through safely.
Miroslav Lichvar [Wed, 20 Aug 2014 14:41:18 +0000 (16:41 +0200)]
ntp: don't stop online burst when sending fails
Don't stop online burst for unreachable sources until sending succeeds.
This is mainly useful with iburst when chronyd is started before the
network is configured.
Miroslav Lichvar [Wed, 20 Aug 2014 09:34:16 +0000 (11:34 +0200)]
sched: improve time jump detection
To detect forward time jumps, use a timestamp made before calling
select() instead of the first timeout in the queue. Also, if the timeout
value is modified by select() (e.g. on Linux) use it to get a more
accurate estimate of the elapsed time.
Miroslav Lichvar [Mon, 18 Aug 2014 16:21:24 +0000 (18:21 +0200)]
rtc: set clock to mtime of driftfile when RTC preinit fails
When the RTC preinit function fails, set the system clock to the time of
the last modification of the driftfile if it's in the future. This makes
the -s option somewhat useful on systems where RTC is not supported or
missing.
This is similar to the functionality implemented in the fake-hwclock
script.
Miroslav Lichvar [Fri, 15 Aug 2014 13:45:48 +0000 (15:45 +0200)]
ntp: use NTP instead of echo for presend
Switch to NTP for presend as the echo service (RFC 862) is rarely
enabled. When presend is active, send an NTP client packet to the
server/peer and ignore the reply.
This also fixes presend with separate client sockets. The destination
port can't be changed on connected sockets, so the echo packet was sent
to the NTP port instead of the echo port.
NTP timestamps use only 32 bits to count seconds and the current NTP era
ends in 2036. Add support for converting NTP timestamps from other NTP
eras on systems with 64-bit time_t.
The earliest assumed NTP time is set by the configure script (by default
to 50 years before the date of the build) and earlier NTP timestamps
underflow to the following NTP era.
Miroslav Lichvar [Wed, 13 Aug 2014 16:11:34 +0000 (18:11 +0200)]
ntp: create new socket for each client request
Create a new connected client socket before each request and close it
when a valid reply is received.
This is useful when the network configuration is changed and the client
socket should be reconnected, but the old bound address remains valid
and sendmsg() doesn't return with an error.
With separate client sockets, allow the initial connect() to fail (e.g.
when the network is not reachable yet) and try to connect later when
sending the packet.
Also, reconnect the socket when the local address has changed.
Miroslav Lichvar [Mon, 30 Jun 2014 10:42:26 +0000 (12:42 +0200)]
sched: exit with fatal message when there is nothing to do
With cmdport 0 and port 0, it's now possible that there is no descriptor
watched or timer running, i.e. chronyd doing nothing and only waiting to
be terminated. Replace the assertion with LOG_FATAL to exit properly.