mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-04 15:15:07 -05:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5658f4d9c | ||
|
|
ad58baa13b | ||
|
|
c6fdeeb6bb | ||
|
|
7712455d9a | ||
|
|
a9a5f98406 | ||
|
|
9ac8f64d89 |
14
NEWS
14
NEWS
@@ -1,3 +1,17 @@
|
||||
New in version 1.29
|
||||
===================
|
||||
|
||||
Security fixes
|
||||
--------------
|
||||
* Fix crash when processing crafted commands (CVE-2012-4502)
|
||||
(possible with IP addresses allowed by cmdallow and localhost)
|
||||
* Don't send uninitialized data in SUBNETS_ACCESSED and CLIENT_ACCESSES
|
||||
replies (CVE-2012-4503) (not used by chronyc)
|
||||
|
||||
Other changes
|
||||
-------------
|
||||
* Drop support for SUBNETS_ACCESSED and CLIENT_ACCESSES commands
|
||||
|
||||
New in version 1.28
|
||||
===================
|
||||
|
||||
|
||||
29
candm.h
29
candm.h
@@ -298,22 +298,10 @@ typedef struct {
|
||||
uint32_t bits_specd;
|
||||
} REQ_SubnetsAccessed_Subnet;
|
||||
|
||||
#define MAX_SUBNETS_ACCESSED 8
|
||||
|
||||
typedef struct {
|
||||
uint32_t n_subnets;
|
||||
REQ_SubnetsAccessed_Subnet subnets[MAX_SUBNETS_ACCESSED];
|
||||
} REQ_SubnetsAccessed;
|
||||
|
||||
/* This is based on the response size rather than the
|
||||
request size */
|
||||
#define MAX_CLIENT_ACCESSES 8
|
||||
|
||||
typedef struct {
|
||||
uint32_t n_clients;
|
||||
IPAddr client_ips[MAX_CLIENT_ACCESSES];
|
||||
} REQ_ClientAccesses;
|
||||
|
||||
typedef struct {
|
||||
uint32_t first_index;
|
||||
uint32_t n_indices;
|
||||
@@ -370,7 +358,8 @@ typedef struct {
|
||||
modify polltarget, modify maxdelaydevratio, reselect, reselectdistance
|
||||
|
||||
Version 5 : auth data moved to the end of the packet to allow hashes with
|
||||
different sizes, extended sources, tracking and activity reports
|
||||
different sizes, extended sources, tracking and activity reports, dropped
|
||||
subnets accessed and client accesses
|
||||
*/
|
||||
|
||||
#define PROTO_VERSION_NUMBER 5
|
||||
@@ -426,8 +415,6 @@ typedef struct {
|
||||
REQ_RTCReport rtcreport;
|
||||
REQ_TrimRTC trimrtc;
|
||||
REQ_CycleLogs cyclelogs;
|
||||
REQ_SubnetsAccessed subnets_accessed;
|
||||
REQ_ClientAccesses client_accesses;
|
||||
REQ_ClientAccessesByIndex client_accesses_by_index;
|
||||
REQ_ManualList manual_list;
|
||||
REQ_ManualDelete manual_delete;
|
||||
@@ -582,11 +569,6 @@ typedef struct {
|
||||
uint32_t bitmap[8];
|
||||
} RPY_SubnetsAccessed_Subnet;
|
||||
|
||||
typedef struct {
|
||||
uint32_t n_subnets;
|
||||
RPY_SubnetsAccessed_Subnet subnets[MAX_SUBNETS_ACCESSED];
|
||||
} RPY_SubnetsAccessed;
|
||||
|
||||
typedef struct {
|
||||
IPAddr ip;
|
||||
uint32_t client_hits;
|
||||
@@ -598,11 +580,6 @@ typedef struct {
|
||||
uint32_t last_cmd_hit_ago;
|
||||
} RPY_ClientAccesses_Client;
|
||||
|
||||
typedef struct {
|
||||
uint32_t n_clients;
|
||||
RPY_ClientAccesses_Client clients[MAX_CLIENT_ACCESSES];
|
||||
} RPY_ClientAccesses;
|
||||
|
||||
typedef struct {
|
||||
uint32_t n_indices; /* how many indices there are in the server's table */
|
||||
uint32_t next_index; /* the index 1 beyond those processed on this call */
|
||||
@@ -656,8 +633,6 @@ typedef struct {
|
||||
RPY_Tracking tracking;
|
||||
RPY_Sourcestats sourcestats;
|
||||
RPY_Rtc rtc;
|
||||
RPY_SubnetsAccessed subnets_accessed;
|
||||
RPY_ClientAccesses client_accesses;
|
||||
RPY_ClientAccessesByIndex client_accesses_by_index;
|
||||
RPY_ManualList manual_list;
|
||||
RPY_Activity activity;
|
||||
|
||||
@@ -125,9 +125,7 @@ different quirks in its behaviour.
|
||||
|
||||
The software is known to work in the following environments:
|
||||
@itemize @bullet
|
||||
@item Linux on i386, x86_64 and PowerPC architectures. The software is known
|
||||
to work on Linux 2.0.x and newer. Prior to 2.0.31, the real time clock can't
|
||||
be used.
|
||||
@item Linux 2.2 and newer
|
||||
|
||||
@item NetBSD
|
||||
@item BSD/386
|
||||
@@ -826,18 +824,10 @@ compiled into the kernel). An estimate is made of the RTC error at a
|
||||
particular RTC second, and the rate at which the RTC gains or loses time
|
||||
relative to true time.
|
||||
|
||||
The RTC is fully supported in 2.2, 2.4 and 2.6 kernels.
|
||||
|
||||
On 2.6 kernels, if your motherboard has a HPET, you need to enable the
|
||||
On 2.6 and later kernels, if your motherboard has a HPET, you need to enable the
|
||||
@samp{HPET_EMULATE_RTC} option in your kernel configuration. Otherwise, chrony
|
||||
will not be able to interact with the RTC device and will give up using it.
|
||||
|
||||
For kernels in the 2.0 series prior to 2.0.32, the kernel was set up to
|
||||
trim the RTC every 11 minutes. This would be disasterous for
|
||||
@code{chronyd} -- there is no reliable way of synchronising with this
|
||||
trimming. For this reason, @code{chronyd} only supports the RTC in 2.0
|
||||
kernels from v2.0.32 onwards.
|
||||
|
||||
When the computer is powered down, the measurement histories for all the
|
||||
NTP servers are saved to files (if the @code{dumponexit} directive is
|
||||
specified in the configuration file), and the RTC tracking information
|
||||
@@ -2637,8 +2627,7 @@ conditions apply:
|
||||
|
||||
@enumerate 1
|
||||
@item
|
||||
You are running Linux version 2.2.x or 2.4.x (for any value of x), or v2.0.x
|
||||
with x>=32.
|
||||
You are running Linux version 2.2.x or later.
|
||||
|
||||
@item
|
||||
You have compiled the kernel with extended real-time clock support
|
||||
|
||||
204
client.c
204
client.c
@@ -1371,7 +1371,8 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
|
||||
read_length = recvfrom_status;
|
||||
expected_length = PKL_ReplyLength(reply);
|
||||
|
||||
bad_length = (read_length < expected_length);
|
||||
bad_length = (read_length < expected_length ||
|
||||
expected_length < offsetof(CMD_Reply, data));
|
||||
bad_sender = (where_from.u.sa_family != his_addr.u.sa_family ||
|
||||
(where_from.u.sa_family == AF_INET &&
|
||||
(where_from.in4.sin_addr.s_addr != his_addr.in4.sin_addr.s_addr ||
|
||||
@@ -1990,207 +1991,6 @@ process_cmd_rtcreport(char *line)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#if 0
|
||||
|
||||
/* This is a previous attempt at implementing the clients command. It
|
||||
could be re-instated sometime as a way of looking at all clients in a
|
||||
particular subnet. The problem with it is that is requires at least 5
|
||||
round trips to the server even if the server only has one client to
|
||||
report. */
|
||||
|
||||
typedef struct XSubnetToDo {
|
||||
struct XSubnetToDo *next;
|
||||
unsigned long ip;
|
||||
unsigned long bits;
|
||||
} SubnetToDo;
|
||||
|
||||
static void
|
||||
process_cmd_clients(char *line)
|
||||
{
|
||||
CMD_Request request;
|
||||
CMD_Reply reply;
|
||||
SubnetToDo *head, *todo, *tail, *p, *next_node, *new_node;
|
||||
int i, j, nets_looked_up, clients_looked_up;
|
||||
int word;
|
||||
unsigned long mask;
|
||||
unsigned long ip, bits;
|
||||
unsigned long client_hits;
|
||||
unsigned long peer_hits;
|
||||
unsigned long cmd_hits_auth;
|
||||
unsigned long cmd_hits_normal;
|
||||
unsigned long cmd_hits_bad;
|
||||
unsigned long last_ntp_hit_ago;
|
||||
unsigned long last_cmd_hit_ago;
|
||||
char hostname_buf[50];
|
||||
|
||||
int n_replies;
|
||||
|
||||
head = todo = MallocNew(SubnetToDo);
|
||||
todo->next = NULL;
|
||||
/* Set up initial query = root subnet */
|
||||
todo->ip = 0;
|
||||
todo->bits = 0;
|
||||
tail = todo;
|
||||
|
||||
do {
|
||||
|
||||
request.command = htons(REQ_SUBNETS_ACCESSED);
|
||||
/* Build list of subnets to examine */
|
||||
i=0;
|
||||
p=todo;
|
||||
while((i < MAX_SUBNETS_ACCESSED) &&
|
||||
p &&
|
||||
(p->bits < 32)) {
|
||||
|
||||
request.data.subnets_accessed.subnets[i].ip = htonl(p->ip);
|
||||
request.data.subnets_accessed.subnets[i].bits_specd = htonl(p->bits);
|
||||
p = p->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
nets_looked_up = i;
|
||||
|
||||
if (nets_looked_up == 0) {
|
||||
/* No subnets need examining */
|
||||
break;
|
||||
}
|
||||
|
||||
request.data.subnets_accessed.n_subnets = htonl(nets_looked_up);
|
||||
|
||||
if (request_reply(&request, &reply, RPY_SUBNETS_ACCESSED, 0)) {
|
||||
n_replies = ntohl(reply.data.subnets_accessed.n_subnets);
|
||||
for (j=0; j<n_replies; j++) {
|
||||
ip = ntohl(reply.data.subnets_accessed.subnets[j].ip);
|
||||
bits = ntohl(reply.data.subnets_accessed.subnets[j].bits_specd);
|
||||
for (i=0; i<256; i++) {
|
||||
word = i/32;
|
||||
mask = 1UL << (i%32);
|
||||
if (ntohl(reply.data.subnets_accessed.subnets[j].bitmap[word]) & mask) {
|
||||
/* Add this subnet to the todo list */
|
||||
new_node = MallocNew(SubnetToDo);
|
||||
new_node->next = NULL;
|
||||
new_node->bits = bits + 8;
|
||||
new_node->ip = ip | (i << (24 - bits));
|
||||
tail->next = new_node;
|
||||
tail = new_node;
|
||||
#if 0
|
||||
printf("%08lx %2d %3d %08lx\n", ip, bits, i, new_node->ip);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip the todo pointer forwards by the number of nets looked
|
||||
up. Can't do this earlier, because we might have to point
|
||||
at the next layer of subnets that have only just been
|
||||
concatenated to the linked list. */
|
||||
for (i=0; i<nets_looked_up; i++) {
|
||||
todo = todo->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} while (1); /* keep going until all subnets have been expanded,
|
||||
down to single nodes */
|
||||
|
||||
/* Now the todo list consists of client records */
|
||||
request.command = htons(REQ_CLIENT_ACCESSES);
|
||||
|
||||
#if 0
|
||||
printf("%d %d\n", sizeof (RPY_ClientAccesses_Client), offsetof(CMD_Reply, data.client_accesses.clients));
|
||||
#endif
|
||||
|
||||
printf("Hostname Client Peer CmdAuth CmdNorm CmdBad LstN LstC\n"
|
||||
"========================= ====== ====== ====== ====== ====== ==== ====\n");
|
||||
|
||||
do {
|
||||
|
||||
i = 0;
|
||||
p = todo;
|
||||
while ((i < MAX_CLIENT_ACCESSES) &&
|
||||
p) {
|
||||
|
||||
request.data.client_accesses.client_ips[i] = htonl(p->ip);
|
||||
p = p->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
clients_looked_up = i;
|
||||
|
||||
if (clients_looked_up == 0) {
|
||||
/* No more clients to do */
|
||||
break;
|
||||
}
|
||||
|
||||
request.data.client_accesses.n_clients = htonl(clients_looked_up);
|
||||
|
||||
if (request_reply(&request, &reply, RPY_CLIENT_ACCESSES, 0)) {
|
||||
n_replies = ntohl(reply.data.client_accesses.n_clients);
|
||||
for (j=0; j<n_replies; j++) {
|
||||
ip = ntohl(reply.data.client_accesses.clients[j].ip);
|
||||
if (ip != 0UL) {
|
||||
/* ip == 0 implies that the node could not be found in
|
||||
the daemon's tables; we shouldn't ever generate this
|
||||
case, but ignore it if we do. (In future there might
|
||||
be a protocol to reset the client logging; if another
|
||||
administrator runs that while we're doing the clients
|
||||
command, there will be a race condition that could
|
||||
cause this). */
|
||||
|
||||
client_hits = ntohl(reply.data.client_accesses.clients[j].client_hits);
|
||||
peer_hits = ntohl(reply.data.client_accesses.clients[j].peer_hits);
|
||||
cmd_hits_auth = ntohl(reply.data.client_accesses.clients[j].cmd_hits_auth);
|
||||
cmd_hits_normal = ntohl(reply.data.client_accesses.clients[j].cmd_hits_normal);
|
||||
cmd_hits_bad = ntohl(reply.data.client_accesses.clients[j].cmd_hits_bad);
|
||||
last_ntp_hit_ago = ntohl(reply.data.client_accesses.clients[j].last_ntp_hit_ago);
|
||||
last_cmd_hit_ago = ntohl(reply.data.client_accesses.clients[j].last_cmd_hit_ago);
|
||||
|
||||
if (no_dns) {
|
||||
snprintf(hostname_buf, sizeof(hostname_buf),
|
||||
"%s", UTI_IPToDottedQuad(ip));
|
||||
} else {
|
||||
DNS_IPAddress2Name(ip, hostname_buf, sizeof(hostname_buf));
|
||||
hostname_buf[25] = 0;
|
||||
}
|
||||
printf("%-25s %6d %6d %6d %6d %6d ",
|
||||
hostname_buf,
|
||||
client_hits, peer_hits,
|
||||
cmd_hits_auth, cmd_hits_normal, cmd_hits_bad);
|
||||
print_seconds(last_ntp_hit_ago);
|
||||
printf(" ");
|
||||
print_seconds(last_cmd_hit_ago);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip the todo pointer forwards by the number of nets looked
|
||||
up. Can't do this earlier, because we might have to point
|
||||
at the next layer of subnets that have only just been
|
||||
concatenated to the linked list. */
|
||||
for (i=0; i<clients_looked_up; i++) {
|
||||
todo = todo->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} while (1);
|
||||
|
||||
cleanup:
|
||||
for (p = head; p; ) {
|
||||
next_node = p->next;
|
||||
Free(p);
|
||||
p = next_node;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* New implementation of clients command */
|
||||
|
||||
static int
|
||||
process_cmd_clients(char *line)
|
||||
{
|
||||
|
||||
156
cmdmon.c
156
cmdmon.c
@@ -1479,107 +1479,6 @@ handle_cyclelogs(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#define FLIPL(X) ((X) = htonl(X))
|
||||
|
||||
static void
|
||||
handle_subnets_accessed(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
int i, j;
|
||||
unsigned long ns, bits_specd;
|
||||
IPAddr ip;
|
||||
CLG_Status result;
|
||||
|
||||
ns = ntohl(rx_message->data.subnets_accessed.n_subnets);
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
tx_message->reply = htons(RPY_SUBNETS_ACCESSED);
|
||||
tx_message->data.subnets_accessed.n_subnets = htonl(ns);
|
||||
|
||||
for (i=0; i<ns; i++) {
|
||||
UTI_IPNetworkToHost(&rx_message->data.subnets_accessed.subnets[i].ip, &ip);
|
||||
bits_specd = ntohl(rx_message->data.subnets_accessed.subnets[i].bits_specd);
|
||||
|
||||
UTI_IPHostToNetwork(&ip, &tx_message->data.subnets_accessed.subnets[i].ip);
|
||||
tx_message->data.subnets_accessed.subnets[i].bits_specd = htonl(bits_specd);
|
||||
|
||||
result = CLG_GetSubnetBitmap(&ip, bits_specd, tx_message->data.subnets_accessed.subnets[i].bitmap);
|
||||
switch (result) {
|
||||
case CLG_SUCCESS:
|
||||
case CLG_EMPTYSUBNET:
|
||||
/* Flip endianness of each 4 byte word. Don't care if subnet
|
||||
is empty - just return an all-zero bitmap. */
|
||||
for (j=0; j<8; j++) {
|
||||
FLIPL(tx_message->data.subnets_accessed.subnets[i].bitmap[j]);
|
||||
}
|
||||
break;
|
||||
case CLG_BADSUBNET:
|
||||
tx_message->status = htons(STT_BADSUBNET);
|
||||
return;
|
||||
case CLG_INACTIVE:
|
||||
tx_message->status = htons(STT_INACTIVE);
|
||||
return;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
handle_client_accesses(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
CLG_Status result;
|
||||
RPT_ClientAccess_Report report;
|
||||
unsigned long nc;
|
||||
IPAddr ip;
|
||||
int i;
|
||||
struct timeval now;
|
||||
|
||||
LCL_ReadCookedTime(&now, NULL);
|
||||
|
||||
nc = ntohl(rx_message->data.client_accesses.n_clients);
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
tx_message->reply = htons(RPY_CLIENT_ACCESSES);
|
||||
tx_message->data.client_accesses.n_clients = htonl(nc);
|
||||
|
||||
printf("%d %d\n", (int)sizeof(RPY_ClientAccesses_Client), (int)offsetof(CMD_Reply, data.client_accesses.clients));
|
||||
|
||||
for (i=0; i<nc; i++) {
|
||||
UTI_IPNetworkToHost(&rx_message->data.client_accesses.client_ips[i], &ip);
|
||||
UTI_IPHostToNetwork(&ip, &tx_message->data.client_accesses.clients[i].ip);
|
||||
|
||||
result = CLG_GetClientAccessReportByIP(&ip, &report, now.tv_sec);
|
||||
switch (result) {
|
||||
case CLG_SUCCESS:
|
||||
tx_message->data.client_accesses.clients[i].client_hits = htonl(report.client_hits);
|
||||
tx_message->data.client_accesses.clients[i].peer_hits = htonl(report.peer_hits);
|
||||
tx_message->data.client_accesses.clients[i].cmd_hits_auth = htonl(report.cmd_hits_auth);
|
||||
tx_message->data.client_accesses.clients[i].cmd_hits_normal = htonl(report.cmd_hits_normal);
|
||||
tx_message->data.client_accesses.clients[i].cmd_hits_bad = htonl(report.cmd_hits_bad);
|
||||
tx_message->data.client_accesses.clients[i].last_ntp_hit_ago = htonl(report.last_ntp_hit_ago);
|
||||
tx_message->data.client_accesses.clients[i].last_cmd_hit_ago = htonl(report.last_cmd_hit_ago);
|
||||
printf("%s %lu %lu %lu %lu %lu %lu %lu\n", UTI_IPToString(&ip), report.client_hits, report.peer_hits, report.cmd_hits_auth, report.cmd_hits_normal, report.cmd_hits_bad, report.last_ntp_hit_ago, report.last_cmd_hit_ago);
|
||||
break;
|
||||
case CLG_EMPTYSUBNET:
|
||||
/* Signal back to the client that this single client address
|
||||
was unknown */
|
||||
ip.family = IPADDR_UNSPEC;
|
||||
UTI_IPHostToNetwork(&ip, &tx_message->data.client_accesses.clients[i].ip);
|
||||
break;
|
||||
case CLG_INACTIVE:
|
||||
tx_message->status = htons(STT_INACTIVE);
|
||||
return;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
handle_client_accesses_by_index(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
@@ -1781,29 +1680,10 @@ read_from_cmd_socket(void *anything)
|
||||
}
|
||||
|
||||
read_length = status;
|
||||
expected_length = PKL_CommandLength(&rx_message);
|
||||
rx_command = ntohs(rx_message.command);
|
||||
|
||||
LCL_ReadRawTime(&now);
|
||||
LCL_CookTime(&now, &cooked_now, NULL);
|
||||
|
||||
tx_message.version = PROTO_VERSION_NUMBER;
|
||||
tx_message.pkt_type = PKT_TYPE_CMD_REPLY;
|
||||
tx_message.res1 = 0;
|
||||
tx_message.res2 = 0;
|
||||
tx_message.command = rx_message.command;
|
||||
tx_message.sequence = rx_message.sequence;
|
||||
tx_message.reply = htons(RPY_NULL);
|
||||
tx_message.number = htons(1);
|
||||
tx_message.total = htons(1);
|
||||
tx_message.pad1 = 0;
|
||||
tx_message.utoken = htonl(utoken);
|
||||
/* Set this to a default (invalid) value. This protects against the
|
||||
token field being set to an arbitrary value if we reject the
|
||||
message, e.g. due to the host failing the access check. */
|
||||
tx_message.token = htonl(0xffffffffUL);
|
||||
memset(&tx_message.auth, 0, sizeof(tx_message.auth));
|
||||
|
||||
switch (where_from.u.sa_family) {
|
||||
case AF_INET:
|
||||
remote_ip.family = IPADDR_INET4;
|
||||
@@ -1830,7 +1710,14 @@ read_from_cmd_socket(void *anything)
|
||||
|
||||
allowed = ADF_IsAllowed(access_auth_table, &remote_ip) || localhost;
|
||||
|
||||
if (read_length < offsetof(CMD_Request, data) ||
|
||||
/* Message size sanity check */
|
||||
if (read_length >= offsetof(CMD_Request, data)) {
|
||||
expected_length = PKL_CommandLength(&rx_message);
|
||||
} else {
|
||||
expected_length = 0;
|
||||
}
|
||||
|
||||
if (expected_length < offsetof(CMD_Request, data) ||
|
||||
rx_message.pkt_type != PKT_TYPE_CMD_REQUEST ||
|
||||
rx_message.res1 != 0 ||
|
||||
rx_message.res2 != 0) {
|
||||
@@ -1842,6 +1729,25 @@ read_from_cmd_socket(void *anything)
|
||||
return;
|
||||
}
|
||||
|
||||
rx_command = ntohs(rx_message.command);
|
||||
|
||||
tx_message.version = PROTO_VERSION_NUMBER;
|
||||
tx_message.pkt_type = PKT_TYPE_CMD_REPLY;
|
||||
tx_message.res1 = 0;
|
||||
tx_message.res2 = 0;
|
||||
tx_message.command = rx_message.command;
|
||||
tx_message.sequence = rx_message.sequence;
|
||||
tx_message.reply = htons(RPY_NULL);
|
||||
tx_message.number = htons(1);
|
||||
tx_message.total = htons(1);
|
||||
tx_message.pad1 = 0;
|
||||
tx_message.utoken = htonl(utoken);
|
||||
/* Set this to a default (invalid) value. This protects against the
|
||||
token field being set to an arbitrary value if we reject the
|
||||
message, e.g. due to the host failing the access check. */
|
||||
tx_message.token = htonl(0xffffffffUL);
|
||||
memset(&tx_message.auth, 0, sizeof(tx_message.auth));
|
||||
|
||||
if (rx_message.version != PROTO_VERSION_NUMBER) {
|
||||
tx_message.status = htons(STT_NOHOSTACCESS);
|
||||
if (!LOG_RateLimited()) {
|
||||
@@ -2233,14 +2139,6 @@ read_from_cmd_socket(void *anything)
|
||||
handle_cyclelogs(&rx_message, &tx_message);
|
||||
break;
|
||||
|
||||
case REQ_SUBNETS_ACCESSED:
|
||||
handle_subnets_accessed(&rx_message, &tx_message);
|
||||
break;
|
||||
|
||||
case REQ_CLIENT_ACCESSES:
|
||||
handle_client_accesses(&rx_message, &tx_message);
|
||||
break;
|
||||
|
||||
case REQ_CLIENT_ACCESSES_BY_INDEX:
|
||||
handle_client_accesses_by_index(&rx_message, &tx_message);
|
||||
break;
|
||||
|
||||
@@ -15,8 +15,8 @@ driftfile /var/lib/chrony/drift
|
||||
rtcsync
|
||||
|
||||
# In first three updates step the system clock instead of slew
|
||||
# if the adjustment is larger than 100 seconds.
|
||||
makestep 100 3
|
||||
# if the adjustment is larger than 10 seconds.
|
||||
makestep 10 3
|
||||
|
||||
# Allow NTP client access from local network.
|
||||
#allow 192.168/16
|
||||
|
||||
4
faq.txt
4
faq.txt
@@ -68,7 +68,7 @@ support hardware reference clocks to your computer, then xntpd will work fine.
|
||||
Apart from not supporting hardware clocks, chrony will work fine too.
|
||||
|
||||
If your computer connects to the 'net for 5 minutes once a day (or something
|
||||
like that), or you turn your (Linux v2.0) computer off when you're not using
|
||||
like that), or you turn your Linux computer off when you're not using
|
||||
it, or you want to use NTP on an isolated network with no hardware clocks in
|
||||
sight, chrony will work much better for you.
|
||||
|
||||
@@ -271,7 +271,7 @@ The program needs to see the definitions of structures used to interact with
|
||||
the real time clock (via /dev/rtc) and with the adjtimex() system call. Sadly
|
||||
this has led to a number of compilation problems with newer kernels which have
|
||||
been increasingly hard to fix in a way that makes the code compilable on all
|
||||
Linux kernel versions (from 2.0 up anyway, I doubt 1.x still works.) Hopefully
|
||||
Linux kernel versions. Hopefully
|
||||
the situation will not deteriorate further with future kernel versions.
|
||||
|
||||
Q: I get "Could not open /dev/rtc, Device or resource busy" in my syslog file.
|
||||
|
||||
38
pktlength.c
38
pktlength.c
@@ -124,19 +124,9 @@ PKL_CommandLength(CMD_Request *r)
|
||||
case REQ_CYCLELOGS :
|
||||
return offsetof(CMD_Request, data.cyclelogs.EOR);
|
||||
case REQ_SUBNETS_ACCESSED :
|
||||
{
|
||||
unsigned long ns;
|
||||
ns = ntohl(r->data.subnets_accessed.n_subnets);
|
||||
return (offsetof(CMD_Request, data.subnets_accessed.subnets) +
|
||||
ns * sizeof(REQ_SubnetsAccessed_Subnet));
|
||||
}
|
||||
case REQ_CLIENT_ACCESSES:
|
||||
{
|
||||
unsigned long nc;
|
||||
nc = ntohl(r->data.client_accesses.n_clients);
|
||||
return (offsetof(CMD_Request, data.client_accesses.client_ips) +
|
||||
nc * sizeof(unsigned long));
|
||||
}
|
||||
/* No longer supported */
|
||||
return 0;
|
||||
case REQ_CLIENT_ACCESSES_BY_INDEX:
|
||||
return offsetof(CMD_Request, data.client_accesses_by_index.EOR);
|
||||
case REQ_MANUAL_LIST:
|
||||
@@ -194,29 +184,15 @@ PKL_ReplyLength(CMD_Reply *r)
|
||||
case RPY_RTC:
|
||||
return offsetof(CMD_Reply, data.rtc.EOR);
|
||||
case RPY_SUBNETS_ACCESSED :
|
||||
{
|
||||
unsigned long ns = ntohl(r->data.subnets_accessed.n_subnets);
|
||||
if (r->status == htons(STT_SUCCESS)) {
|
||||
return (offsetof(CMD_Reply, data.subnets_accessed.subnets) +
|
||||
ns * sizeof(RPY_SubnetsAccessed_Subnet));
|
||||
} else {
|
||||
return offsetof(CMD_Reply, data);
|
||||
}
|
||||
}
|
||||
case RPY_CLIENT_ACCESSES:
|
||||
{
|
||||
unsigned long nc = ntohl(r->data.client_accesses.n_clients);
|
||||
if (r->status == htons(STT_SUCCESS)) {
|
||||
return (offsetof(CMD_Reply, data.client_accesses.clients) +
|
||||
nc * sizeof(RPY_ClientAccesses_Client));
|
||||
} else {
|
||||
return offsetof(CMD_Reply, data);
|
||||
}
|
||||
}
|
||||
/* No longer supported */
|
||||
return 0;
|
||||
case RPY_CLIENT_ACCESSES_BY_INDEX:
|
||||
{
|
||||
unsigned long nc = ntohl(r->data.client_accesses_by_index.n_clients);
|
||||
if (r->status == htons(STT_SUCCESS)) {
|
||||
if (nc > MAX_CLIENT_ACCESSES)
|
||||
return 0;
|
||||
return (offsetof(CMD_Reply, data.client_accesses_by_index.clients) +
|
||||
nc * sizeof(RPY_ClientAccesses_Client));
|
||||
} else {
|
||||
@@ -226,6 +202,8 @@ PKL_ReplyLength(CMD_Reply *r)
|
||||
case RPY_MANUAL_LIST:
|
||||
{
|
||||
unsigned long ns = ntohl(r->data.manual_list.n_samples);
|
||||
if (ns > MAX_MANUAL_LIST_SAMPLES)
|
||||
return 0;
|
||||
if (r->status == htons(STT_SUCCESS)) {
|
||||
return (offsetof(CMD_Reply, data.manual_list.samples) +
|
||||
ns * sizeof(RPY_ManualListSample));
|
||||
|
||||
Reference in New Issue
Block a user