Compare commits

...

35 Commits
1.21 ... 1.23.1

Author SHA1 Message Date
Miroslav Lichvar
d99c4736c2 Update NEWS 2010-02-03 15:13:13 +01:00
Miroslav Lichvar
2f63cf4485 Add option to limit clientlog memory 2010-01-15 12:51:31 +01:00
Miroslav Lichvar
0b710499f9 Limit rate of syslog messages
Error messages caused by incoming packets need to be rate limited
to avoid filling up disk space.
2010-01-15 12:51:26 +01:00
Miroslav Lichvar
7864c7a70c Don't reply to invalid chronyc packets 2010-01-14 14:43:37 +01:00
Richard P. Curnow
5331e1a146 Update NEWS for 1.23 2007-12-02 14:53:09 +00:00
Richard P. Curnow
eeac7b7ca0 Define io_linux.h constants for x86_64
Based on thread from chrony-users, October 2007.
2007-12-02 14:39:50 +00:00
Richard P. Curnow
efcf3f7c6b git archive's --prefix arg needs a trailing / 2007-06-27 23:57:03 +01:00
Richard P. Curnow
eb4c9d908c Use git-archive instead of the obsolete git-tar-tree in make_release 2007-06-27 23:54:43 +01:00
Richard P. Curnow
b6e40dbde7 Merge branch 'bu' 2007-06-26 23:51:18 +01:00
Richard P. Curnow
4ba843f8f4 Fix formatting from last patch 2007-06-26 23:50:53 +01:00
Bill Unruh
75a7af9edc Fix handling of stratum zero.
Further to the discussion with John Hasler, here are new diffs which
handles the incoming stratum 0 claim of a remote server by redefining the
incoming stratum as one bigger than the Max if it is zero, as per the NTP
version 4 documentation.

If the incoming stratum is zero it sets it to NTP_MAX_STRATUM+1 . If our
current stratum is larger than the NTP_MAX_STRATUM, the outgoing stratum is
also set to zero as per the suggestions in the NTP docs.
Introduces the new NTP_INVALID_STRATUM of 0 for doing these tests or
setting the outgoing stratum.

It is unclear whether chrony wants to follow NTP in setting the outgoing
stratum to zero if it is unknown or invalid, rather than a number larger
than the max stratum. Setting it to zero seems silly, since zero is already
used to define the stratum of a hardware clock (GPS, atomic, etc). This
seems ripe for confusion. But the fact that the ntp docs state to do this,
and that ntp servers (eg ntp.ubc.ca) are already doing this (using 0 to
mean invalid) means that chrony has to handle it on the incoming packets
from the servers.
2007-06-26 23:46:33 +01:00
Bill Unruh
8022874a47 Handle fluctuations in peer distance better. 2007-06-26 23:45:04 +01:00
Richard P. Curnow
ca1195a0e6 Fix whitespace issue with last patch 2007-06-26 23:43:28 +01:00
Bill Unruh
ce4e0a3c2f Fix problems with rtc_linux.
2) Changes to rtc_linux.c which a) do a double read of /dev/rtc when the
PPM interupt is turned on after the wait time expires. The current read
does not block to the second, as it should, thus two reads are needed.

Also, changes so that at startup the system properly ignores the last
system time from the initial burst mode for setting the system time since
it can be way off. At present this last system time is included in the
regression, which throws it off until finally that sample is dropped.
2007-06-26 23:42:11 +01:00
Stefan Lucke
215d988286 Fix sign v zero extension error in handling IP address
I switch to the git version of chrony. Accidently this version did not
talk to by lokal server at 192.168.192.4. Instead it continuosly tried
255.255.192.4 :-( .

Tracked that down to "char", "unsigned char" issue in nameserv.c:
2007-06-26 23:02:33 +01:00
Richard P. Curnow
084efe606f Merge branch 'vm' 2007-06-26 22:13:40 +01:00
Richard P. Curnow
38efaf10a8 configure: fix indentation from previous patch 2007-06-26 22:11:19 +01:00
Vladimir Michl
93f6664378 Allow RTC support to be excluded at compile time.
Add a new option to configure script, allowing
to disable (and exclude) RTC module. It saves same memory.
2007-06-26 22:08:49 +01:00
Vladimir Michl
8a94298b7e Add support for Linux/arm 2007-06-26 22:06:39 +01:00
Richard P. Curnow
242c520912 Fix format of "could not send to" message 2006-04-15 23:57:42 +01:00
Richard P. Curnow
1a4fa3330a Rename round() function to avoid clash with builtin 2006-04-15 00:34:04 +01:00
Richard P. Curnow
fd35174928 Merge quashing of compile warnings 2006-04-15 00:32:08 +01:00
kevin lyda
2a30c56f03 Quash a load of compile warnings
Kevin Lyda writes:
I enclose the following patch which removes all but three of the warnings.  i
don't have any non-linux systems handy to test a fix to the round() function.
but having it return a double should be fine.

It doesn't actually fix anything, it just shuts up -Wall, so it's certainly an
optional type of patch.
2006-04-15 00:31:29 +01:00
Richard P. Curnow
0b8979a41e Fix version.txt to remove compile warning 2006-04-15 00:27:07 +01:00
Eric Lammerts
4771cbe8b0 Fix bogus "system time" report for 64 bit systems
Eric Lammerts writes:
This is known as Debian bug #195620, which is almost three years old!

The problem is that a uint32_t which comes out of ntohl() (but
actually represents a signed value) is directly promoted to long.
Therefore no sign extension takes place.

Patch below solves the problem. There are other places where this
needs to be fixed, but I'll leave that to a less lazy person.
2006-04-15 00:18:28 +01:00
Richard P. Curnow
1e7e7d3231 Remove volatile keyword from function declarations
This silences a lot of gcc-4 compile warnings
2006-04-15 00:10:21 +01:00
Bernhard Weiss
3e7781fdaf Fix linux_io.h for MIPS
Bernard Weiss writes:
I managed to compile the chrony 1.21 package for the MIPS architecture.
For the package to compile I had to add the following lines to io_linux.h:

[patch]

These values are taken from the ioctl.h file of linux 2.4.30 for the MIPS arch
(__ASM_MIPS_IOCTL_H).
2006-04-15 00:07:43 +01:00
NAKAMURA Takumi
acd99f25ef FreeBSD support
NAKAMURA Takumi writes:

I tried to compile chrony-1.21 on FreeBSD 4.8-RELEASE & 5.4-RELEASE.
I modify two files, configure, sysinc.h.

configure:
    add label "FreeBSD-i386" to "BSD/386" line
sysincl.h:
    1. FreeBSD obsoletes alloca.h
    2. FreeBSD use stdlib.h instead of malloc.h, to use malloc(), free()

Attached file includes the above modifications.
2006-04-15 00:03:30 +01:00
Paul Elliott
91a91d1642 Flush chronyc output buffers.
The following is a patch to chronyc that causes it
to flush the buffers to stderr and stdout after
executing each command. This is needed if
you are controling chronyc from a program (i.e. chronyc's
input and output descriptors are pipes which are being
written/read by another program) and
you do not want to block waiting for chronyc response
which is trapped in a buffer!
2006-01-29 23:31:56 +00:00
Richard P. Curnow
29223ea476 Add a .gitignore file 2006-01-29 23:29:01 +00:00
Richard P. Curnow
bcae93d321 manpage improvements.
Try to address this Debian bug:
  Bug#345034: chrony: man pages refer to wrong sections
2006-01-29 23:23:52 +00:00
Richard P. Curnow
383a36371f 1st attempt at a git-compatible make_release script 2006-01-22 23:54:19 +00:00
Richard P. Curnow
fa83311903 Tidy up io_linux.h so unknown architecture result in compile-time error again 2006-01-22 23:38:43 +00:00
Richard P. Curnow
f5c3a01aee More architectures in io_linux.h (John Hasler) 2006-01-22 23:36:16 +00:00
Richard P. Curnow
d2a7dc2347 Fix gcc-4 compilation of addrfilt.c
John Hasler sent in a patch to do this (which still wouldn't make it compile
for me).  This reminded me that I had tackled this myself when my distro moved
to gcc-4 a while back.  It turned out I had never even checked in the file from
the working copy I was using (!).  Anyway, here it is now.
2006-01-19 21:56:19 +00:00
30 changed files with 347 additions and 134 deletions

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
*.swp
*.o
Makefile
chronyc
chronyd
version.h

31
NEWS
View File

@@ -1,3 +1,34 @@
New in version 1.23.1
=====================
Security fixes
--------------
* Don't reply to invalid cmdmon packets (CVE-2010-0292)
* Limit client log memory size (CVE-2010-0293)
* Limit rate of syslog messages (CVE-2010-0294)
New in version 1.23
===================
* Support for MIPS, x86_64, sparc, alpha, arm, FreeBSD
* Fix serious sign-extension error in handling IP addresses
* RTC support can be excluded at compile time
* Make sources gcc-4 compatible
* Fix various compiler warnings
* Handle fluctuations in peer distance better.
* Fixed handling of stratum zero.
* Fix various problems for 64-bit systems
* Flush chronyc output streams after each command, to allow it to be driven
through pipes
* Manpage improvements
Version 1.22
============
This release number was claimed by a release that Mandriva made to patch
important bugs in 1.21. The official numbering has jumped to 1.23 as a
consequence.
New in version 1.21
===================

View File

@@ -358,7 +358,7 @@ read_from_socket(void *anything)
int status;
ReceiveBuffer msg;
struct sockaddr_in his_addr;
int his_addr_len;
socklen_t his_addr_len;
int flags;
int message_length;
unsigned long remote_ip;

View File

@@ -6,7 +6,7 @@
chronyd/chronyc - Programs for keeping computer clocks accurate.
**********************************************************************
* Copyright (C) Richard P. Curnow 1997-2002
* Copyright (C) Richard P. Curnow 1997,1998,1999,2000,2001,2002,2005
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -43,15 +43,11 @@
/* Define the table size */
#define TABLE_SIZE (1UL<<NBITS)
struct _TableNode;
typedef struct _TableNode ExtendedTable[TABLE_SIZE];
typedef enum {DENY, ALLOW, AS_PARENT} State;
typedef struct _TableNode {
State state;
ExtendedTable *extended;
struct _TableNode *extended;
} TableNode;
struct ADF_AuthTableInst {
@@ -101,7 +97,7 @@ close_node(TableNode *node)
if (node->extended != NULL) {
for (i=0; i<TABLE_SIZE; i++) {
child_node = &((*(node->extended))[i]);
child_node = &(node->extended[i]);
close_node(child_node);
}
Free(node->extended);
@@ -124,10 +120,10 @@ open_node(TableNode *node)
if (node->extended == NULL) {
node->extended = MallocNew(ExtendedTable);
node->extended = MallocArray(struct _TableNode, TABLE_SIZE);
for (i=0; i<TABLE_SIZE; i++) {
child_node = &((*(node->extended))[i]);
child_node = &(node->extended[i]);
child_node->state = AS_PARENT;
child_node->extended = NULL;
}
@@ -168,7 +164,7 @@ set_subnet(TableNode *start_node,
if (!(node->extended)) {
open_node(node);
}
node = &((*(node->extended))[subnet]);
node = &(node->extended[subnet]);
bits_to_go -= NBITS;
}
@@ -187,7 +183,7 @@ set_subnet(TableNode *start_node,
if (!(node->extended)) {
open_node(node);
}
node = &((*(node->extended))[subnet]);
node = &(node->extended[subnet]);
bits_to_go -= NBITS;
}
@@ -199,7 +195,7 @@ set_subnet(TableNode *start_node,
}
for (i=subnet, j=0; j<N; i++, j++) {
this_node = &((*(node->extended))[i]);
this_node = &(node->extended[i]);
if (delete_children) {
close_node(this_node);
}
@@ -283,7 +279,7 @@ check_ip_in_node(TableNode *start_node, unsigned long ip)
if (node->extended) {
subnet = get_subnet(residual);
residual = get_residual(residual);
node = &((*(node->extended))[subnet]);
node = &(node->extended[subnet]);
} else {
/* Make decision on this node */
finished = 1;

View File

@@ -1,45 +0,0 @@
#!/usr/bin/env perl
# $Header: /cvs/src/chrony/build_kit,v 1.13 2003/01/12 23:50:54 richard Exp $
# Perl script for building a release
# Have to run it in the current directory
if (($0 ne "build_kit") && ($0 ne "./build_kit")) {
die "Have to be in the checked-out directory to run build_kit";
}
$here=`pwd`;
chomp $here;
$version=$here;
$version =~ s,^.*/chrony-([^/]+)$,$1, || die "Didn't recognize directory name";
print "Building kit for version $version\n";
chmod 0755, "configure";
# Overwrite normal version.h file with version-specific one
open (OUT, ">version.txt");
print OUT $version."\n";
close OUT;
# Construct chrony.spec file
open (IN, "<chrony.spec.sample");
open (OUT, ">chrony.spec");
while (<IN>) {
s/\@\@VERSION\@\@/$version/;
print OUT;
}
close (IN);
close (OUT);
# Requires the makeinfo from texinfo v4
system("makeinfo --no-headers --number-sections -o chrony.txt chrony.texi");
system ("rm -rf ./{arch}");
system ("rm -rf ./.arch-ids");
unlink "chrony.spec.sample";
unlink("build_kit");
chdir ("..");
system ("tar cvf - chrony-$version | gzip -9 > chrony-$version.tar.gz");
system ("gpg -b -a -o chrony-$version-tar-gz-asc.txt chrony-$version.tar.gz");

View File

@@ -63,3 +63,6 @@ Richard Curnow <rc@rc0.org.uk>
This man-page was written by Jan Schaumann <jschauma@netmeister.org> as part
of "The Missing Man Pages Project". Please see
\fIhttp://www.netmeister.org/misc/m2p2/index.html\fR for details.
The complete chrony documentation is supplied in texinfo format.

View File

@@ -47,3 +47,6 @@ Richard Curnow <rc@rc0.org.uk>
This man-page was written by Jan Schaumann <jschauma@netmeister.org> as part of "The Missing
Man Pages Project". Please see \fIhttp://www.netmeister.org/misc/m2p2/index.html\fR
for details.
The complete chrony documentation is supplied in texinfo format.

View File

@@ -1177,6 +1177,7 @@ directives can occur in any order in the file.
* manual directive:: Allow manual entry using chronyc's settime cmd.
* maxupdateskew directive:: Stop bad estimates upsetting machine clock
* noclientlog directive:: Prevent chronyd from gathering data about clients
* clientloglimit directive:: Set client log memory limit
* peer directive:: Specify an NTP peer
* pidfile directive:: Specify the file where chronyd's pid is written
* port directive:: Set port to use for NTP packets
@@ -2066,6 +2067,21 @@ This directive, which takes no arguments, specifies that client accesses
are not to be logged. Normally they are logged, allowing statistics to
be reported using the @code{clients} command in @code{chronyc}.
@c }}}
@c {{{ clientloglimit
@node clientloglimit directive
@subsection clientloglimit
This directive specifies the maximum size of the memory allocated to
log client accesses. When the limit is reached, only information for
clients that have already been logged will be updated. If 0 is
specified, the memory size will be unlimited. The default is 524288
bytes.
An example of the use of this directive is
@example
clientloglimit 1048576
@end example
@c }}}
@c {{{ peer
@node peer directive
@subsection peer

View File

@@ -40,10 +40,10 @@ interactively.
1.17
.SH BUGS
To report bugs, please contact the author and/or visit \fIhttp://go.to/chrony\fR
To report bugs, please contact the author and/or visit \fIhttp://chrony.sunsite.dk/\fR
.SH "SEE ALSO"
.BR chronyd(1),
.BR chronyd(8),
.BR chrony(1)
.I http://chrony.sunsite.dk/
@@ -54,3 +54,6 @@ Richard Curnow <rc@rc0.org.uk>
This man-page was written by Jan Schaumann <jschauma@netmeister.org> as part of "The Missing
Man Pages Project". Please see \fIhttp://www.netmeister.org/misc/m2p2/index.html\fR
for details.
The complete chrony documentation is supplied in texinfo format.

View File

@@ -109,3 +109,6 @@ Richard Curnow <rc@rc0.org.uk>
This man-page was written by Jan Schaumann <jschauma@netmeister.org> as part
of "The Missing Man Pages Project". Please see
\fIhttp://www.netmeister.org/misc/m2p2/index.html\fR for details.
The complete chrony documentation is supplied in texinfo format.

View File

@@ -146,7 +146,7 @@ read_line(void)
static unsigned long
get_address(const char *hostname)
{
unsigned char *address0;
char *address0;
struct hostent *host;
unsigned long result;
@@ -746,7 +746,7 @@ static int
accheck_getaddr(char *line, unsigned long *addr)
{
unsigned long a, b, c, d, ip;
unsigned char *p, *q;
char *p, *q;
p = line;
while (*p && isspace(*p)) p++;
if (!*p) {
@@ -1124,7 +1124,7 @@ static int
submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
{
unsigned long tx_sequence;
int where_from_len;
socklen_t where_from_len;
struct sockaddr_in where_from;
int bad_length, bad_sender, bad_sequence, bad_header;
int select_status;
@@ -1652,7 +1652,7 @@ process_cmd_tracking(char *line)
ref_time.tv_usec = ntohl(reply.data.tracking.ref_time_us);
ref_time_tm = *gmtime((time_t *)&ref_time.tv_sec);
printf("Ref time (UTC) : %s", asctime(&ref_time_tm));
correction_tv.tv_sec = ntohl(reply.data.tracking.current_correction_s);
correction_tv.tv_sec = (int32_t)ntohl(reply.data.tracking.current_correction_s);
correction_tv.tv_usec = ntohl(reply.data.tracking.current_correction_us);
correction = (double) correction_tv.tv_sec + 1.0e-6 * correction_tv.tv_usec;
printf("System time : %.6f seconds %s of NTP time\n", fabs(correction),
@@ -2319,7 +2319,11 @@ process_line(char *line)
/* Check for line being blank */
p = line;
while (*p && isspace((unsigned char)*p)) p++;
if (!*p) return quit;
if (!*p) {
fflush(stderr);
fflush(stdout);
return quit;
};
if (!strncmp(p, "offline", 7)) {
do_normal_submit = process_cmd_offline(&tx_message, p+7);
@@ -2480,7 +2484,8 @@ process_line(char *line)
}
}
}
fflush(stderr);
fflush(stdout);
return quit;
}

View File

@@ -40,6 +40,7 @@
#include "memory.h"
#include "reports.h"
#include "util.h"
#include "logging.h"
/* Number of bits of address per layer of the table. This value has
been chosen on the basis that a server will predominantly be serving
@@ -86,6 +87,13 @@ static int max_nodes = 0;
/* Flag indicating whether facility is turned on or not */
static int active = 0;
/* Flag indicating whether memory allocation limit has been reached
and no new nodes or subnets should be allocated */
static int alloc_limit_reached;
static unsigned long alloc_limit;
static unsigned long alloced;
/* ================================================== */
static void
@@ -128,6 +136,9 @@ CLG_Initialise(void)
max_nodes = 0;
n_nodes = 0;
alloced = 0;
alloc_limit = CNF_GetClientLogLimit();
alloc_limit_reached = 0;
}
/* ================================================== */
@@ -140,11 +151,25 @@ CLG_Finalise(void)
/* ================================================== */
static void check_alloc_limit() {
if (alloc_limit_reached)
return;
if (alloced >= alloc_limit) {
LOG(LOGS_WARN, LOGF_ClientLog, "Client log memory limit reached");
alloc_limit_reached = 1;
}
}
/* ================================================== */
static void
create_subnet(Subnet *parent_subnet, int the_entry)
{
parent_subnet->entry[the_entry] = (void *) MallocNew(Subnet);
clear_subnet((Subnet *) parent_subnet->entry[the_entry]);
alloced += sizeof (Subnet);
check_alloc_limit();
}
/* ================================================== */
@@ -157,6 +182,8 @@ create_node(Subnet *parent_subnet, int the_entry)
parent_subnet->entry[the_entry] = (void *) new_node;
clear_node(new_node);
alloced += sizeof (Node);
if (n_nodes == max_nodes) {
if (nodes) {
max_nodes += NODE_TABLE_INCREMENT;
@@ -168,8 +195,10 @@ create_node(Subnet *parent_subnet, int the_entry)
max_nodes = NODE_TABLE_INCREMENT;
nodes = MallocArray(Node *, max_nodes);
}
alloced += sizeof (Node *) * (max_nodes - n_nodes);
}
nodes[n_nodes++] = (Node *) new_node;
check_alloc_limit();
}
/* ================================================== */
@@ -195,11 +224,15 @@ find_subnet(Subnet *subnet, CLG_IP_Addr addr, int bits_left)
if (new_bits_left > 0) {
if (!subnet->entry[this_subnet]) {
if (alloc_limit_reached)
return NULL;
create_subnet(subnet, this_subnet);
}
return find_subnet((Subnet *) subnet->entry[this_subnet], new_subnet, new_bits_left);
} else {
if (!subnet->entry[this_subnet]) {
if (alloc_limit_reached)
return NULL;
create_node(subnet, this_subnet);
}
return subnet->entry[this_subnet];
@@ -248,6 +281,8 @@ CLG_LogNTPClientAccess (CLG_IP_Addr client, time_t now)
Node *node;
if (active) {
node = (Node *) find_subnet(&top_subnet, client, 32);
if (node == NULL)
return;
node->ip_addr = client;
++node->client_hits;
node->last_ntp_hit = now;
@@ -262,6 +297,8 @@ CLG_LogNTPPeerAccess(CLG_IP_Addr client, time_t now)
Node *node;
if (active) {
node = (Node *) find_subnet(&top_subnet, client, 32);
if (node == NULL)
return;
node->ip_addr = client;
++node->peer_hits;
node->last_ntp_hit = now;
@@ -276,6 +313,8 @@ CLG_LogCommandAccess(CLG_IP_Addr client, CLG_Command_Type type, time_t now)
Node *node;
if (active) {
node = (Node *) find_subnet(&top_subnet, client, 32);
if (node == NULL)
return;
node->ip_addr = client;
node->last_cmd_hit = now;
switch (type) {

View File

@@ -654,7 +654,7 @@ transmit_reply(CMD_Reply *msg, struct sockaddr_in *where_to)
status = sendto(sock_fd, (void *) msg, tx_message_length, 0,
(struct sockaddr *) where_to, sizeof(struct sockaddr_in));
if (status < 0) {
if (status < 0 && !LOG_RateLimited()) {
remote_ip = ntohl(where_to->sin_addr.s_addr);
remote_port = ntohs(where_to->sin_port);
LOG(LOGS_WARN, LOGF_CmdMon, "Could not send response to %s:%hu", UTI_IPToDottedQuad(remote_ip), remote_port);
@@ -1584,7 +1584,7 @@ read_from_cmd_socket(void *anything)
CMD_Reply tx_message, *prev_tx_message;
int rx_message_length, tx_message_length;
struct sockaddr_in where_from;
int from_length;
socklen_t from_length;
unsigned long remote_ip;
unsigned short remote_port;
int md5_ok;
@@ -1593,6 +1593,7 @@ read_from_cmd_socket(void *anything)
int valid_ts;
int authenticated;
int localhost;
int allowed;
unsigned short rx_command;
unsigned long rx_message_token;
unsigned long tx_message_token;
@@ -1642,20 +1643,43 @@ read_from_cmd_socket(void *anything)
localhost = (remote_ip == 0x7f000001UL);
if ((!ADF_IsAllowed(access_auth_table, remote_ip)) &&
(!localhost)) {
allowed = ADF_IsAllowed(access_auth_table, remote_ip) || localhost;
if ((read_length < offsetof(CMD_Request, data)) ||
(rx_message.version != PROTO_VERSION_NUMBER) ||
(rx_message.pkt_type != PKT_TYPE_CMD_REQUEST) ||
(rx_message.res1 != 0) ||
(rx_message.res2 != 0)) {
/* We don't know how to process anything like this */
if (allowed)
CLG_LogCommandAccess(remote_ip, CLG_CMD_BAD_PKT, cooked_now.tv_sec);
return;
}
if (read_length != expected_length) {
if (!LOG_RateLimited()) {
LOG(LOGS_WARN, LOGF_CmdMon, "Read incorrectly sized packet from %s:%hu", UTI_IPToDottedQuad(remote_ip), remote_port);
}
if (allowed)
CLG_LogCommandAccess(remote_ip, CLG_CMD_BAD_PKT, cooked_now.tv_sec);
/* For now, just ignore the packet. We may want to send a reply
back eventually */
return;
}
if (!allowed) {
/* The client is not allowed access, so don't waste any more time
on him. Note that localhost is always allowed access
regardless of the defined access rules - otherwise, we could
shut ourselves out completely! */
/* We ought to find another way to log this, there is an attack
here against the host because an adversary can just keep
hitting us with bad packets until our log file(s) fill up. */
LOG(LOGS_WARN, LOGF_CmdMon, "Command packet received from unauthorised host %s port %d",
UTI_IPToDottedQuad(remote_ip),
remote_port);
if (!LOG_RateLimited()) {
LOG(LOGS_WARN, LOGF_CmdMon, "Command packet received from unauthorised host %s port %d",
UTI_IPToDottedQuad(remote_ip),
remote_port);
}
tx_message.status = htons(STT_NOHOSTACCESS);
transmit_reply(&tx_message, &where_from);
@@ -1664,25 +1688,6 @@ read_from_cmd_socket(void *anything)
}
if (read_length != expected_length) {
LOG(LOGS_WARN, LOGF_CmdMon, "Read incorrectly sized packet from %s:%hu", UTI_IPToDottedQuad(remote_ip), remote_port);
CLG_LogCommandAccess(remote_ip, CLG_CMD_BAD_PKT, cooked_now.tv_sec);
/* For now, just ignore the packet. We may want to send a reply
back eventually */
return;
}
if ((rx_message.version != PROTO_VERSION_NUMBER) ||
(rx_message.pkt_type != PKT_TYPE_CMD_REQUEST) ||
(rx_message.res1 != 0) ||
(rx_message.res2 != 0)) {
/* We don't know how to process anything like this */
CLG_LogCommandAccess(remote_ip, CLG_CMD_BAD_PKT, cooked_now.tv_sec);
return;
}
rx_command = ntohs(rx_message.command);
/* OK, we have a valid message. Now dispatch on message type and process it. */
@@ -1759,7 +1764,7 @@ read_from_cmd_socket(void *anything)
tx_message_length = PKL_ReplyLength(prev_tx_message);
status = sendto(sock_fd, (void *) prev_tx_message, tx_message_length, 0,
(struct sockaddr *) &where_from, sizeof(where_from));
if (status < 0) {
if (status < 0 && !LOG_RateLimited()) {
LOG(LOGS_WARN, LOGF_CmdMon, "Could not send response to %s:%hu", UTI_IPToDottedQuad(remote_ip), remote_port);
}
return;
@@ -1809,7 +1814,7 @@ read_from_cmd_socket(void *anything)
tx_message.status = htons(STT_INVALID);
tx_message.reply = htons(RPY_NULL);
} else {
int allowed = 0;
allowed = 0;
/* Check level of authority required to issue the command */
switch(permissions[rx_command]) {
@@ -1879,7 +1884,7 @@ read_from_cmd_socket(void *anything)
case REQ_LOGON:
/* If the log-on fails, record the reason why */
if (!issue_token) {
if (!issue_token && !LOG_RateLimited()) {
LOG(LOGS_WARN, LOGF_CmdMon,
"Bad command logon from %s port %d (md5_ok=%d valid_ts=%d)\n",
UTI_IPToDottedQuad(remote_ip),

28
conf.c
View File

@@ -83,6 +83,7 @@ static void parse_cmddeny(const char *);
static void parse_cmdport(const char *);
static void parse_rtconutc(const char *);
static void parse_noclientlog(const char *);
static void parse_clientloglimit(const char *);
static void parse_logchange(const char *);
static void parse_mailonchange(const char *);
static void parse_bindaddress(const char *);
@@ -146,6 +147,9 @@ static double mail_change_threshold = 0.0;
memory */
static int no_client_log = 0;
/* Limit memory allocated for the clients log */
static unsigned long client_log_limit = 524288;
/* IP address (host order) for binding the NTP socket to. 0 means INADDR_ANY
will be used */
static unsigned long bind_address = 0UL;
@@ -200,6 +204,7 @@ static const Command commands[] = {
{"cmdport", 7, parse_cmdport},
{"rtconutc", 8, parse_rtconutc},
{"noclientlog", 11, parse_noclientlog},
{"clientloglimit", 14, parse_clientloglimit},
{"logchange", 9, parse_logchange},
{"mailonchange", 12, parse_mailonchange},
{"bindaddress", 11, parse_bindaddress},
@@ -634,6 +639,21 @@ parse_noclientlog(const char *line)
/* ================================================== */
static void
parse_clientloglimit(const char *line)
{
if (sscanf(line, "%lu", &client_log_limit) != 1) {
LOG(LOGS_WARN, LOGF_Configure, "Could not read clientlog memory limit at line %d", line_number);
}
if (client_log_limit == 0) {
/* unlimited */
client_log_limit = (unsigned long)-1;
}
}
/* ================================================== */
static void
parse_logchange(const char *line)
{
@@ -1195,6 +1215,14 @@ CNF_GetNoClientLog(void)
/* ================================================== */
unsigned long
CNF_GetClientLogLimit(void)
{
return client_log_limit;
}
/* ================================================== */
void
CNF_GetBindAddress(unsigned long *addr)
{

1
conf.h
View File

@@ -59,6 +59,7 @@ extern int CNF_GetRTCOnUTC(void);
extern void CNF_GetLogChange(int *enabled, double *threshold);
extern void CNF_GetMailOnChange(int *enabled, double *threshold, char **user);
extern int CNF_GetNoClientLog(void);
extern unsigned long CNF_GetClientLogLimit(void);
extern void CNF_GetBindAddress(unsigned long *addr);
extern void CNF_GetBindCommandAddress(unsigned long *addr);
extern char *CNF_GetPidFile(void);

13
configure vendored
View File

@@ -133,6 +133,7 @@ For better control, use the options below.
--readline-inc-dir=DIR Specify where readline include directory is
--readline-lib-dir=DIR Specify where readline lib directory is
--with-ncurses-library=DIR Specify where ncurses lib directory is
--disable-rtc Don't include RTC even on Linux
Fine tuning of the installation directories:
--infodir=DIR info documentation [PREFIX/info]
@@ -172,6 +173,7 @@ SYSDEFS=""
# Support for readline (on by default)
feat_readline=1
feat_rtc=1
readline_lib=""
readline_inc=""
ncurses_lib=""
@@ -206,6 +208,9 @@ do
--mandir=* )
SETMANDIR=`echo $option | sed -e 's/^.*=//;'`
;;
--disable-rtc)
feat_rtc=0
;;
--help | -h )
usage
exit 0
@@ -238,7 +243,11 @@ case $SYSTEM in
esac
;;
Linux* )
EXTRA_OBJECTS="sys_linux.o wrap_adjtimex.o rtc_linux.o"
EXTRA_OBJECTS="sys_linux.o wrap_adjtimex.o"
if [ $feat_rtc -eq 1 ] ; then
EXTRA_OBJECTS+=" rtc_linux.o"
EXTRA_DEFS+=" -DFEAT_RTC=1"
fi
SYSDEFS="-DLINUX"
echo "Configuring for " $SYSTEM
if [ "${MACHINE}" = "alpha" ]; then
@@ -248,7 +257,7 @@ case $SYSTEM in
fi
;;
BSD/386-i[3456]86 )
BSD/386-i[3456]86|FreeBSD-i386 )
# Antti Jrvinen <costello@iki.fi> reported that this system can
# be supported with the SunOS 4.x driver files.
EXTRA_OBJECTS="sys_sunos.o strerror.o"

View File

@@ -6,7 +6,7 @@
/* Hmm. These constants vary a bit between systems. */
/* (__sh__ includes both sh and sh64) */
#if defined(__i386__) || defined(__sh__)
#if defined(__i386__) || defined(__sh__) || defined(__arm__)||defined(__x86_64__)
#define CHRONY_IOC_NRBITS 8
#define CHRONY_IOC_TYPEBITS 8
#define CHRONY_IOC_SIZEBITS 14
@@ -15,7 +15,8 @@
#define CHRONY_IOC_NONE 0U
#define CHRONY_IOC_WRITE 1U
#define CHRONY_IOC_READ 2U
#elif defined(__alpha__) || defined(__sparc__)
#elif defined(__alpha__) || defined(__sparc__) || defined(__ppc__) || defined(__ppc64__) || defined(__sparc64__)
#define CHRONY_IOC_NRBITS 8
#define CHRONY_IOC_TYPEBITS 8
#define CHRONY_IOC_SIZEBITS 13
@@ -24,6 +25,16 @@
#define CHRONY_IOC_NONE 1U
#define CHRONY_IOC_READ 2U
#define CHRONY_IOC_WRITE 4U
#elif defined(__mips__) || defined(__mips32__)
#define CHRONY_IOC_NRBITS 8
#define CHRONY_IOC_TYPEBITS 8
#define CHRONY_IOC_SIZEBITS 13
#define CHRONY_IOC_DIRBITS 3
#define CHRONY_IOC_NONE 1U
#define CHRONY_IOC_READ 2U
#define CHRONY_IOC_WRITE 4U
#else
#error "I don't know the values of the _IOC_* constants for your architecture"
#endif

View File

@@ -40,6 +40,8 @@ static int initialised = 0;
static int is_detached = 0;
static time_t last_limited = 0;
#ifdef WINNT
static FILE *logfile;
#endif
@@ -116,7 +118,7 @@ LOG_Line_Function(LOG_Severity severity, LOG_Facility facility, const char *form
/* ================================================== */
volatile void
void
LOG_Fatal_Function(LOG_Facility facility, const char *format, ...)
{
char buf[2048];
@@ -214,3 +216,19 @@ LOG_GoDaemon(void)
}
/* ================================================== */
int
LOG_RateLimited(void)
{
time_t now;
now = time(NULL);
if (last_limited + 10 > now && last_limited <= now)
return 1;
last_limited = now;
return 0;
}
/* ================================================== */

View File

@@ -53,6 +53,7 @@ typedef enum {
LOGF_Local,
LOGF_Util,
LOGF_Main,
LOGF_ClientLog,
LOGF_Configure,
LOGF_CmdMon,
LOGF_Acquire,
@@ -77,13 +78,16 @@ extern void LOG_Finalise(void);
extern void LOG_Line_Function(LOG_Severity severity, LOG_Facility facility, const char *format, ...);
/* Logging function for fatal errors */
extern volatile void LOG_Fatal_Function(LOG_Facility facility, const char *format, ...);
extern void LOG_Fatal_Function(LOG_Facility facility, const char *format, ...);
/* Position in code reporting function */
extern void LOG_Position(const char *filename, int line_number, const char *function_name);
extern void LOG_GoDaemon(void);
/* Return zero once per 10 seconds */
extern int LOG_RateLimited(void);
/* Line logging macro. If the compiler is GNU C, we take advantage of
being able to get the function name also. */
#if defined(__GNUC__)

2
main.c
View File

@@ -74,7 +74,7 @@ delete_pidfile(void)
/* ================================================== */
volatile void
void
MAI_CleanupAndExit(void)
{
if (!initialised) exit(0);

2
main.h
View File

@@ -32,7 +32,7 @@
#define GOT_MAIN_H
/* Function to clean up at end of run */
extern volatile void MAI_CleanupAndExit(void);
extern void MAI_CleanupAndExit(void);
#endif /* GOT_MAIN_H */

52
make_release Executable file
View File

@@ -0,0 +1,52 @@
#!/usr/bin/env perl
$tool = "chrony";
$version = shift || die "Usage : $0 <version>\n";
$subdir = "${tool}-${version}";
unless (-d ".git") {
die "No .git subdirectory?"
}
unless (-d "RELEASES") {
mkdir "RELEASES", 0755;
}
system ("git-tag -s $version");
die "git-tag failed" if ($? != 0);
if (-d "RELEASES/$subdir") {
system ("rm -rf RELEASES/$subdir");
}
system ("git-archive --format=tar --prefix=RELEASES/${subdir}/ $version | tar xf -");
die "git-tar-tree failed" if ($? != 0);
chdir "RELEASES";
$here = qx/pwd/;
chomp $here;
chdir $subdir;
open (OUT, ">version.txt");
print OUT $version."\n";
close OUT;
open (IN, "<${tool}.spec.sample");
open (OUT, ">${tool}.spec");
while (<IN>) {
s/\@\@VERSION\@\@/$version/;
print OUT;
}
close (IN);
close (OUT);
system("makeinfo --no-headers --number-sections -o chrony.txt chrony.texi");
unlink "make_release";
unlink "${tool}.spec.sample";
unlink ".gitignore";
chdir $here;
system ("tar cvf - $subdir | gzip -9 > ${subdir}.tar.gz");
system ("gpg -b -a -o ${subdir}-tar-gz-asc.txt ${subdir}.tar.gz");

View File

@@ -196,6 +196,9 @@ struct NCR_Instance_Record {
/* Maximum allowed stratum */
#define NTP_MAX_STRATUM 15
/* INVALID or Unkown stratum from external server as per the NTP 4 docs */
#define NTP_INVALID_STRATUM 0
/* ================================================== */
static ADF_AuthTable access_auth_table;
@@ -378,7 +381,7 @@ generate_packet_auth(NTP_Packet *pkt, unsigned long keyid)
if (keyok) {
pkt->auth_keyid = htonl(keyid);
MD5Init(&ctx);
MD5Update(&ctx, keytext, keylen);
MD5Update(&ctx, (unsigned char *) keytext, keylen);
MD5Update(&ctx, (unsigned char *) pkt, offsetof(NTP_Packet, auth_keyid));
MD5Final(&ctx);
memcpy(&(pkt->auth_data), &ctx.digest, 16);
@@ -447,7 +450,7 @@ check_packet_auth(NTP_Packet *pkt, unsigned long keyid)
if (keyok) {
pkt->auth_keyid = htonl(keyid);
MD5Init(&ctx);
MD5Update(&ctx, keytext, keylen);
MD5Update(&ctx, (unsigned char *) keytext, keylen);
MD5Update(&ctx, (unsigned char *) pkt, offsetof(NTP_Packet, auth_keyid));
MD5Final(&ctx);
if (!memcmp((void *) &ctx.digest, (void *) &(pkt->auth_data), 16)) {
@@ -539,7 +542,13 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
/* Generate transmit packet */
message.lvm = ((leap << 6) &0xc0) | ((version << 3) & 0x38) | (my_mode & 0x07);
message.stratum = our_stratum;
if (our_stratum <= NTP_MAX_STRATUM) {
message.stratum = our_stratum;
} else {
/* (WGU) to handle NTP "Invalid" stratum as per the NTP V4 documents. */
message.stratum = NTP_INVALID_STRATUM;
}
message.poll = my_poll;
message.precision = LCL_GetSysPrecisionAsLog();
@@ -983,6 +992,12 @@ receive_packet(NTP_Packet *message, struct timeval *now, NCR_Instance inst, int
test6 = 1; /* Succeeded */
}
/* (WGU) Set stratum to greater than any valid if incoming is 0 */
/* as per the NPT v4 documentation*/
if (message->stratum <= NTP_INVALID_STRATUM) {
message->stratum = NTP_MAX_STRATUM + 1;
}
/* Test 7 checks that the stratum in the packet is appropriate */
if ((message->stratum > REF_GetOurStratum()) ||
(message->stratum > NTP_MAX_STRATUM)) {
@@ -1343,7 +1358,7 @@ process_known
&inst->local_ntp_tx,
&inst->remote_addr);
} else {
} else if (!LOG_RateLimited()) {
LOG(LOGS_WARN, LOGF_NtpCore, "NTP packet received from unauthorised host %s port %d",
UTI_IPToDottedQuad(inst->remote_addr.ip_addr),
inst->remote_addr.port);
@@ -1511,7 +1526,7 @@ NCR_ProcessNoauthUnknown(NTP_Packet *message, struct timeval *now, NTP_Remote_Ad
remote_addr);
}
} else {
} else if (!LOG_RateLimited()) {
LOG(LOGS_WARN, LOGF_NtpCore, "NTP packet received from unauthorised host %s port %d",
UTI_IPToDottedQuad(remote_addr->ip_addr),
remote_addr->port);

View File

@@ -184,7 +184,7 @@ read_from_socket(void *anything)
ReceiveBuffer message;
int message_length;
struct sockaddr_in where_from;
int from_length;
socklen_t from_length;
unsigned int flags = 0;
struct timeval now;
NTP_Remote_Address remote_addr;
@@ -243,8 +243,9 @@ NIO_SendNormalPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr)
remote.sin_addr.s_addr = htonl(remote_addr->ip_addr);
if (sendto(sock_fd, (void *) packet, NTP_NORMAL_PACKET_SIZE, 0,
(struct sockaddr *) &remote, sizeof(remote)) < 0) {
LOG(LOGS_WARN, LOGF_NtpIO, "Could not send to :%s%d : %s",
(struct sockaddr *) &remote, sizeof(remote)) < 0 &&
!LOG_RateLimited()) {
LOG(LOGS_WARN, LOGF_NtpIO, "Could not send to %s:%d : %s",
UTI_IPToDottedQuad(remote_addr->ip_addr), remote_addr->port, strerror(errno));
}
@@ -266,8 +267,9 @@ NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr)
remote.sin_addr.s_addr = htonl(remote_addr->ip_addr);
if (sendto(sock_fd, (void *) packet, sizeof(NTP_Packet), 0,
(struct sockaddr *) &remote, sizeof(remote)) < 0) {
LOG(LOGS_WARN, LOGF_NtpIO, "Could not send to :%s%d : %s",
(struct sockaddr *) &remote, sizeof(remote)) < 0 &&
!LOG_RateLimited()) {
LOG(LOGS_WARN, LOGF_NtpIO, "Could not send to %s:%d : %s",
UTI_IPToDottedQuad(remote_addr->ip_addr), remote_addr->port, strerror(errno));
}

4
rtc.c
View File

@@ -33,7 +33,7 @@
#include "logging.h"
#include "conf.h"
#if defined LINUX
#if defined LINUX && defined FEAT_RTC
#include "rtc_linux.h"
#endif /* defined LINUX */
@@ -53,7 +53,7 @@ static struct {
void (*cycle_logfile)(void);
} driver =
{
#if defined LINUX
#if defined LINUX && defined FEAT_RTC
RTC_Linux_Initialise,
RTC_Linux_Finalise,
RTC_Linux_TimePreInit,

View File

@@ -174,7 +174,7 @@ static double file_ref_offset, file_rate_ppm;
/* ================================================== */
/* Flag to remember whether to assume the RTC is running on UTC */
static int rtc_on_utc = 0;
static int rtc_on_utc = 1;
/* ================================================== */
@@ -226,15 +226,18 @@ accumulate_sample(time_t rtc, struct timeval *sys)
discard_samples(NEW_FIRST_WHEN_FULL);
}
rtc_sec[n_samples] = rtc;
/* Always use most recent sample as reference */
/* use sample only if n_sample is not negative*/
if(n_samples >=0)
{
rtc_ref = rtc;
rtc_sec[n_samples] = rtc;
rtc_trim[n_samples] = 0.0;
system_times[n_samples] = *sys;
++n_samples;
++n_samples_since_regression;
}
++n_samples;
return;
}
@@ -742,7 +745,11 @@ handle_initial_trim(void)
run_regression(1, &coefs_valid, &coef_ref_time, &coef_seconds_fast, &coef_gain_rate);
n_samples_since_regression = 0;
n_samples = 0;
/* Set sample number to -1 so the next sample is not used, as it will not yet be corrected for System Trim*/
n_samples = -1;
read_coefs_from_file();
@@ -866,6 +873,8 @@ read_from_device(void *any)
int error = 0;
status = read(fd, &data, sizeof(data));
if (operating_mode == OM_NORMAL)
status = read(fd, &data, sizeof(data));
if (status < 0) {
/* This looks like a bad error : the file descriptor was indicating it was
* ready to read but we couldn't read anything. Give up. */

View File

@@ -373,9 +373,9 @@ find_best_sample_index(SST_Stats inst, double *times_back)
/* This defines the assumed ratio between the standard deviation of
the samples and the peer distance as measured from the round trip
time. E.g. a value of 4 means that we think the standard deviation
is a quarter of the peer distance */
is four times the fluctuation of the peer distance */
#define SD_TO_DIST_RATIO 8.0
#define SD_TO_DIST_RATIO 1.0
/* ================================================== */
/* This function runs the linear regression operation on the data. It

View File

@@ -98,7 +98,7 @@ static void handle_end_of_slew(void *anything);
/* ================================================== */
inline static int
round(double x) {
our_round(double x) {
int y;
y = (int)(x + 0.5);
while ((double)y < x - 0.5) y++;
@@ -433,7 +433,7 @@ set_frequency(double freq_ppm) {
neg = 0;
}
required_delta_tick = round(freq_ppm / dhz);
required_delta_tick = our_round(freq_ppm / dhz);
required_freq = freq_ppm - dhz * (double) required_delta_tick;
if (neg) {

View File

@@ -35,7 +35,7 @@
#if defined (SOLARIS) || defined(SUNOS) || defined(LINUX) || defined(__NetBSD__)
#if !defined(__NetBSD__)
#if !defined(__NetBSD__) && !defined(__FreeBSD__)
#include <alloca.h>
#endif
#include <assert.h>
@@ -43,7 +43,9 @@
#include <errno.h>
#include <fcntl.h>
#include <float.h>
#if !defined(__FreeBSD__)
#include <malloc.h>
#endif
#include <math.h>
#include <netdb.h>
#include <netinet/in.h>

View File

@@ -1,4 +1 @@
#ifndef VERSION_H
#define VERSION_H
#define PROGRAM_VERSION_STRING "$Name: V1_12 $"
#endif /* VERSION_H */
DEVELOPMENT