1 /*
2   chronyd/chronyc - Programs for keeping computer clocks accurate.
3 
4  **********************************************************************
5  * Copyright (C) Richard P. Curnow  1997-2003
6  * Copyright (C) Miroslav Lichvar  2009-2016, 2018-2021
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of version 2 of the GNU General Public License as
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20  *
21  **********************************************************************
22 
23   =======================================================================
24 
25   Command and monitoring module in the main program
26   */
27 
28 #include "config.h"
29 
30 #include "sysincl.h"
31 
32 #include "cmdmon.h"
33 #include "candm.h"
34 #include "sched.h"
35 #include "util.h"
36 #include "logging.h"
37 #include "keys.h"
38 #include "ntp_sources.h"
39 #include "ntp_core.h"
40 #include "smooth.h"
41 #include "socket.h"
42 #include "sources.h"
43 #include "sourcestats.h"
44 #include "reference.h"
45 #include "manual.h"
46 #include "memory.h"
47 #include "nts_ke_server.h"
48 #include "local.h"
49 #include "addrfilt.h"
50 #include "conf.h"
51 #include "rtc.h"
52 #include "pktlength.h"
53 #include "clientlog.h"
54 #include "refclock.h"
55 
56 /* ================================================== */
57 
58 #define INVALID_SOCK_FD (-5)
59 
60 /* File descriptors for command and monitoring sockets */
61 static int sock_fdu;
62 static int sock_fd4;
63 static int sock_fd6;
64 
65 /* Flag indicating the IPv4 socket is bound to an address */
66 static int bound_sock_fd4;
67 
68 /* Flag indicating whether this module has been initialised or not */
69 static int initialised = 0;
70 
71 /* ================================================== */
72 /* Array of permission levels for command types */
73 
74 static const char permissions[] = {
75   PERMIT_OPEN, /* NULL */
76   PERMIT_AUTH, /* ONLINE */
77   PERMIT_AUTH, /* OFFLINE */
78   PERMIT_AUTH, /* BURST */
79   PERMIT_AUTH, /* MODIFY_MINPOLL */
80   PERMIT_AUTH, /* MODIFY_MAXPOLL */
81   PERMIT_AUTH, /* DUMP */
82   PERMIT_AUTH, /* MODIFY_MAXDELAY */
83   PERMIT_AUTH, /* MODIFY_MAXDELAYRATIO */
84   PERMIT_AUTH, /* MODIFY_MAXUPDATESKEW */
85   PERMIT_OPEN, /* LOGON */
86   PERMIT_AUTH, /* SETTIME */
87   PERMIT_AUTH, /* LOCAL */
88   PERMIT_AUTH, /* MANUAL */
89   PERMIT_OPEN, /* N_SOURCES */
90   PERMIT_OPEN, /* SOURCE_DATA */
91   PERMIT_AUTH, /* REKEY */
92   PERMIT_AUTH, /* ALLOW */
93   PERMIT_AUTH, /* ALLOWALL */
94   PERMIT_AUTH, /* DENY */
95   PERMIT_AUTH, /* DENYALL */
96   PERMIT_AUTH, /* CMDALLOW */
97   PERMIT_AUTH, /* CMDALLOWALL */
98   PERMIT_AUTH, /* CMDDENY */
99   PERMIT_AUTH, /* CMDDENYALL */
100   PERMIT_AUTH, /* ACCHECK */
101   PERMIT_AUTH, /* CMDACCHECK */
102   PERMIT_AUTH, /* ADD_SERVER */
103   PERMIT_AUTH, /* ADD_PEER */
104   PERMIT_AUTH, /* DEL_SOURCE */
105   PERMIT_AUTH, /* WRITERTC */
106   PERMIT_AUTH, /* DFREQ */
107   PERMIT_AUTH, /* DOFFSET */
108   PERMIT_OPEN, /* TRACKING */
109   PERMIT_OPEN, /* SOURCESTATS */
110   PERMIT_OPEN, /* RTCREPORT */
111   PERMIT_AUTH, /* TRIMRTC */
112   PERMIT_AUTH, /* CYCLELOGS */
113   PERMIT_AUTH, /* SUBNETS_ACCESSED */
114   PERMIT_AUTH, /* CLIENT_ACCESSES (by subnet) */
115   PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX */
116   PERMIT_OPEN, /* MANUAL_LIST */
117   PERMIT_AUTH, /* MANUAL_DELETE */
118   PERMIT_AUTH, /* MAKESTEP */
119   PERMIT_OPEN, /* ACTIVITY */
120   PERMIT_AUTH, /* MODIFY_MINSTRATUM */
121   PERMIT_AUTH, /* MODIFY_POLLTARGET */
122   PERMIT_AUTH, /* MODIFY_MAXDELAYDEVRATIO */
123   PERMIT_AUTH, /* RESELECT */
124   PERMIT_AUTH, /* RESELECTDISTANCE */
125   PERMIT_AUTH, /* MODIFY_MAKESTEP */
126   PERMIT_OPEN, /* SMOOTHING */
127   PERMIT_AUTH, /* SMOOTHTIME */
128   PERMIT_AUTH, /* REFRESH */
129   PERMIT_AUTH, /* SERVER_STATS */
130   PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX2 */
131   PERMIT_AUTH, /* LOCAL2 */
132   PERMIT_AUTH, /* NTP_DATA */
133   PERMIT_AUTH, /* ADD_SERVER2 */
134   PERMIT_AUTH, /* ADD_PEER2 */
135   PERMIT_AUTH, /* ADD_SERVER3 */
136   PERMIT_AUTH, /* ADD_PEER3 */
137   PERMIT_AUTH, /* SHUTDOWN */
138   PERMIT_AUTH, /* ONOFFLINE */
139   PERMIT_AUTH, /* ADD_SOURCE */
140   PERMIT_OPEN, /* NTP_SOURCE_NAME */
141   PERMIT_AUTH, /* RESET_SOURCES */
142   PERMIT_AUTH, /* AUTH_DATA */
143   PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX3 */
144   PERMIT_AUTH, /* SELECT_DATA */
145   PERMIT_AUTH, /* RELOAD_SOURCES */
146   PERMIT_AUTH, /* DOFFSET2 */
147 };
148 
149 /* ================================================== */
150 
151 /* This authorisation table is used for checking whether particular
152    machines are allowed to make command and monitoring requests. */
153 static ADF_AuthTable access_auth_table;
154 
155 /* ================================================== */
156 /* Forward prototypes */
157 static void read_from_cmd_socket(int sock_fd, int event, void *anything);
158 
159 /* ================================================== */
160 
161 static int
open_socket(int family)162 open_socket(int family)
163 {
164   const char *local_path, *iface;
165   IPSockAddr local_addr;
166   int sock_fd, port;
167 
168   switch (family) {
169     case IPADDR_INET4:
170     case IPADDR_INET6:
171       port = CNF_GetCommandPort();
172       if (port == 0 || !SCK_IsIpFamilyEnabled(family))
173         return INVALID_SOCK_FD;
174 
175       CNF_GetBindCommandAddress(family, &local_addr.ip_addr);
176       local_addr.port = port;
177       iface = CNF_GetBindCommandInterface();
178 
179       sock_fd = SCK_OpenUdpSocket(NULL, &local_addr, iface, SCK_FLAG_RX_DEST_ADDR);
180       if (sock_fd < 0) {
181         LOG(LOGS_ERR, "Could not open command socket on %s",
182             UTI_IPSockAddrToString(&local_addr));
183         return INVALID_SOCK_FD;
184       }
185 
186       if (family == IPADDR_INET4)
187         bound_sock_fd4 = local_addr.ip_addr.addr.in4 != INADDR_ANY;
188 
189       break;
190     case IPADDR_UNSPEC:
191       local_path = CNF_GetBindCommandPath();
192 
193       sock_fd = SCK_OpenUnixDatagramSocket(NULL, local_path, 0);
194       if (sock_fd < 0) {
195         LOG(LOGS_ERR, "Could not open command socket on %s", local_path);
196         return INVALID_SOCK_FD;
197       }
198 
199       break;
200     default:
201       assert(0);
202   }
203 
204   /* Register handler for read events on the socket */
205   SCH_AddFileHandler(sock_fd, SCH_FILE_INPUT, read_from_cmd_socket, NULL);
206 
207   return sock_fd;
208 }
209 
210 /* ================================================== */
211 
212 static void
do_size_checks(void)213 do_size_checks(void)
214 {
215   int i, request_length, padding_length, reply_length;
216   CMD_Request request;
217   CMD_Reply reply;
218 
219   assert(offsetof(CMD_Request, data) == 20);
220   assert(offsetof(CMD_Reply, data) == 28);
221 
222   for (i = 0; i < N_REQUEST_TYPES; i++) {
223     request.version = PROTO_VERSION_NUMBER;
224     request.command = htons(i);
225     request_length = PKL_CommandLength(&request);
226     padding_length = PKL_CommandPaddingLength(&request);
227     if (padding_length > MAX_PADDING_LENGTH || padding_length > request_length ||
228         request_length > sizeof (CMD_Request) ||
229         (request_length && request_length < offsetof(CMD_Request, data)))
230       assert(0);
231   }
232 
233   for (i = 1; i < N_REPLY_TYPES; i++) {
234     reply.reply = htons(i);
235     reply.status = STT_SUCCESS;
236     reply_length = PKL_ReplyLength(&reply);
237     if ((reply_length && reply_length < offsetof(CMD_Reply, data)) ||
238         reply_length > sizeof (CMD_Reply))
239       assert(0);
240   }
241 }
242 
243 /* ================================================== */
244 
245 void
CAM_Initialise(void)246 CAM_Initialise(void)
247 {
248   assert(!initialised);
249   assert(sizeof (permissions) / sizeof (permissions[0]) == N_REQUEST_TYPES);
250   do_size_checks();
251 
252   initialised = 1;
253 
254   bound_sock_fd4 = 0;
255 
256   sock_fdu = INVALID_SOCK_FD;
257   sock_fd4 = open_socket(IPADDR_INET4);
258   sock_fd6 = open_socket(IPADDR_INET6);
259 
260   access_auth_table = ADF_CreateTable();
261 }
262 
263 /* ================================================== */
264 
265 void
CAM_Finalise(void)266 CAM_Finalise(void)
267 {
268   if (sock_fdu != INVALID_SOCK_FD) {
269     SCH_RemoveFileHandler(sock_fdu);
270     SCK_RemoveSocket(sock_fdu);
271     SCK_CloseSocket(sock_fdu);
272     sock_fdu = INVALID_SOCK_FD;
273   }
274 
275   if (sock_fd4 != INVALID_SOCK_FD) {
276     SCH_RemoveFileHandler(sock_fd4);
277     SCK_CloseSocket(sock_fd4);
278     sock_fd4 = INVALID_SOCK_FD;
279   }
280 
281   if (sock_fd6 != INVALID_SOCK_FD) {
282     SCH_RemoveFileHandler(sock_fd6);
283     SCK_CloseSocket(sock_fd6);
284     sock_fd6 = INVALID_SOCK_FD;
285   }
286 
287   ADF_DestroyTable(access_auth_table);
288 
289   initialised = 0;
290 }
291 
292 /* ================================================== */
293 
294 void
CAM_OpenUnixSocket(void)295 CAM_OpenUnixSocket(void)
296 {
297   /* This is separated from CAM_Initialise() as it needs to be called when
298      the process has already dropped the root privileges */
299   if (CNF_GetBindCommandPath())
300     sock_fdu = open_socket(IPADDR_UNSPEC);
301 }
302 
303 /* ================================================== */
304 
305 static void
transmit_reply(int sock_fd,int request_length,SCK_Message * message)306 transmit_reply(int sock_fd, int request_length, SCK_Message *message)
307 {
308   message->length = PKL_ReplyLength((CMD_Reply *)message->data);
309 
310   if (request_length < message->length) {
311     DEBUG_LOG("Response longer than request req_len=%d res_len=%d",
312               request_length, message->length);
313     return;
314   }
315 
316   /* Don't require responses to non-link-local addresses to use the same
317      interface */
318   if (message->addr_type == SCK_ADDR_IP &&
319       !SCK_IsLinkLocalIPAddress(&message->remote_addr.ip.ip_addr))
320     message->if_index = INVALID_IF_INDEX;
321 
322 #if !defined(HAVE_IN_PKTINFO) && defined(IP_SENDSRCADDR)
323   /* On FreeBSD a local IPv4 address cannot be specified on bound socket */
324   if (message->addr_type == SCK_ADDR_IP && message->local_addr.ip.family == IPADDR_INET4 &&
325       (sock_fd != sock_fd4 || bound_sock_fd4))
326     message->local_addr.ip.family = IPADDR_UNSPEC;
327 #endif
328 
329   if (!SCK_SendMessage(sock_fd, message, 0))
330     return;
331 }
332 
333 /* ================================================== */
334 
335 static void
handle_dump(CMD_Request * rx_message,CMD_Reply * tx_message)336 handle_dump(CMD_Request *rx_message, CMD_Reply *tx_message)
337 {
338   SRC_DumpSources();
339   NSR_DumpAuthData();
340   NKS_DumpKeys();
341 }
342 
343 /* ================================================== */
344 
345 static void
handle_online(CMD_Request * rx_message,CMD_Reply * tx_message)346 handle_online(CMD_Request *rx_message, CMD_Reply *tx_message)
347 {
348   IPAddr address, mask;
349 
350   UTI_IPNetworkToHost(&rx_message->data.online.mask, &mask);
351   UTI_IPNetworkToHost(&rx_message->data.online.address, &address);
352   if (!NSR_SetConnectivity(&mask, &address, SRC_ONLINE))
353     tx_message->status = htons(STT_NOSUCHSOURCE);
354 }
355 
356 /* ================================================== */
357 
358 static void
handle_offline(CMD_Request * rx_message,CMD_Reply * tx_message)359 handle_offline(CMD_Request *rx_message, CMD_Reply *tx_message)
360 {
361   IPAddr address, mask;
362 
363   UTI_IPNetworkToHost(&rx_message->data.offline.mask, &mask);
364   UTI_IPNetworkToHost(&rx_message->data.offline.address, &address);
365   if (!NSR_SetConnectivity(&mask, &address, SRC_OFFLINE))
366     tx_message->status = htons(STT_NOSUCHSOURCE);
367 }
368 
369 /* ================================================== */
370 
371 static void
handle_onoffline(CMD_Request * rx_message,CMD_Reply * tx_message)372 handle_onoffline(CMD_Request *rx_message, CMD_Reply *tx_message)
373 {
374   IPAddr address, mask;
375 
376   address.family = mask.family = IPADDR_UNSPEC;
377   if (!NSR_SetConnectivity(&mask, &address, SRC_MAYBE_ONLINE))
378     ;
379 }
380 
381 /* ================================================== */
382 
383 static void
handle_burst(CMD_Request * rx_message,CMD_Reply * tx_message)384 handle_burst(CMD_Request *rx_message, CMD_Reply *tx_message)
385 {
386   IPAddr address, mask;
387 
388   UTI_IPNetworkToHost(&rx_message->data.burst.mask, &mask);
389   UTI_IPNetworkToHost(&rx_message->data.burst.address, &address);
390   if (!NSR_InitiateSampleBurst(ntohl(rx_message->data.burst.n_good_samples),
391                                ntohl(rx_message->data.burst.n_total_samples),
392                                &mask, &address))
393     tx_message->status = htons(STT_NOSUCHSOURCE);
394 }
395 
396 /* ================================================== */
397 
398 static void
handle_modify_minpoll(CMD_Request * rx_message,CMD_Reply * tx_message)399 handle_modify_minpoll(CMD_Request *rx_message, CMD_Reply *tx_message)
400 {
401   IPAddr address;
402 
403   UTI_IPNetworkToHost(&rx_message->data.modify_minpoll.address, &address);
404   if (!NSR_ModifyMinpoll(&address,
405                          ntohl(rx_message->data.modify_minpoll.new_minpoll)))
406     tx_message->status = htons(STT_NOSUCHSOURCE);
407 }
408 
409 /* ================================================== */
410 
411 static void
handle_modify_maxpoll(CMD_Request * rx_message,CMD_Reply * tx_message)412 handle_modify_maxpoll(CMD_Request *rx_message, CMD_Reply *tx_message)
413 {
414   IPAddr address;
415 
416   UTI_IPNetworkToHost(&rx_message->data.modify_minpoll.address, &address);
417   if (!NSR_ModifyMaxpoll(&address,
418                          ntohl(rx_message->data.modify_minpoll.new_minpoll)))
419     tx_message->status = htons(STT_NOSUCHSOURCE);
420 }
421 
422 /* ================================================== */
423 
424 static void
handle_modify_maxdelay(CMD_Request * rx_message,CMD_Reply * tx_message)425 handle_modify_maxdelay(CMD_Request *rx_message, CMD_Reply *tx_message)
426 {
427   IPAddr address;
428 
429   UTI_IPNetworkToHost(&rx_message->data.modify_maxdelay.address, &address);
430   if (!NSR_ModifyMaxdelay(&address,
431         UTI_FloatNetworkToHost(rx_message->data.modify_maxdelay.new_max_delay)))
432     tx_message->status = htons(STT_NOSUCHSOURCE);
433 }
434 
435 /* ================================================== */
436 
437 static void
handle_modify_maxdelayratio(CMD_Request * rx_message,CMD_Reply * tx_message)438 handle_modify_maxdelayratio(CMD_Request *rx_message, CMD_Reply *tx_message)
439 {
440   IPAddr address;
441 
442   UTI_IPNetworkToHost(&rx_message->data.modify_maxdelayratio.address, &address);
443   if (!NSR_ModifyMaxdelayratio(&address,
444         UTI_FloatNetworkToHost(rx_message->data.modify_maxdelayratio.new_max_delay_ratio)))
445     tx_message->status = htons(STT_NOSUCHSOURCE);
446 }
447 
448 /* ================================================== */
449 
450 static void
handle_modify_maxdelaydevratio(CMD_Request * rx_message,CMD_Reply * tx_message)451 handle_modify_maxdelaydevratio(CMD_Request *rx_message, CMD_Reply *tx_message)
452 {
453   IPAddr address;
454 
455   UTI_IPNetworkToHost(&rx_message->data.modify_maxdelaydevratio.address, &address);
456   if (!NSR_ModifyMaxdelaydevratio(&address,
457         UTI_FloatNetworkToHost(rx_message->data.modify_maxdelaydevratio.new_max_delay_dev_ratio)))
458     tx_message->status = htons(STT_NOSUCHSOURCE);
459 }
460 
461 /* ================================================== */
462 
463 static void
handle_modify_minstratum(CMD_Request * rx_message,CMD_Reply * tx_message)464 handle_modify_minstratum(CMD_Request *rx_message, CMD_Reply *tx_message)
465 {
466   IPAddr address;
467 
468   UTI_IPNetworkToHost(&rx_message->data.modify_minpoll.address, &address);
469   if (!NSR_ModifyMinstratum(&address,
470                             ntohl(rx_message->data.modify_minstratum.new_min_stratum)))
471     tx_message->status = htons(STT_NOSUCHSOURCE);
472 }
473 
474 /* ================================================== */
475 
476 static void
handle_modify_polltarget(CMD_Request * rx_message,CMD_Reply * tx_message)477 handle_modify_polltarget(CMD_Request *rx_message, CMD_Reply *tx_message)
478 {
479   IPAddr address;
480 
481   UTI_IPNetworkToHost(&rx_message->data.modify_polltarget.address, &address);
482   if (!NSR_ModifyPolltarget(&address,
483                             ntohl(rx_message->data.modify_polltarget.new_poll_target)))
484     tx_message->status = htons(STT_NOSUCHSOURCE);
485 }
486 
487 /* ================================================== */
488 
489 static void
handle_modify_maxupdateskew(CMD_Request * rx_message,CMD_Reply * tx_message)490 handle_modify_maxupdateskew(CMD_Request *rx_message, CMD_Reply *tx_message)
491 {
492   REF_ModifyMaxupdateskew(UTI_FloatNetworkToHost(rx_message->data.modify_maxupdateskew.new_max_update_skew));
493 }
494 
495 /* ================================================== */
496 
497 static void
handle_modify_makestep(CMD_Request * rx_message,CMD_Reply * tx_message)498 handle_modify_makestep(CMD_Request *rx_message, CMD_Reply *tx_message)
499 {
500   REF_ModifyMakestep(ntohl(rx_message->data.modify_makestep.limit),
501                      UTI_FloatNetworkToHost(rx_message->data.modify_makestep.threshold));
502 }
503 
504 /* ================================================== */
505 
506 static void
handle_settime(CMD_Request * rx_message,CMD_Reply * tx_message)507 handle_settime(CMD_Request *rx_message, CMD_Reply *tx_message)
508 {
509   struct timespec ts;
510   double offset, dfreq_ppm, new_afreq_ppm;
511   UTI_TimespecNetworkToHost(&rx_message->data.settime.ts, &ts);
512   if (!MNL_IsEnabled()) {
513     tx_message->status = htons(STT_NOTENABLED);
514   } else if (MNL_AcceptTimestamp(&ts, &offset, &dfreq_ppm, &new_afreq_ppm)) {
515     tx_message->reply = htons(RPY_MANUAL_TIMESTAMP2);
516     tx_message->data.manual_timestamp.offset = UTI_FloatHostToNetwork(offset);
517     tx_message->data.manual_timestamp.dfreq_ppm = UTI_FloatHostToNetwork(dfreq_ppm);
518     tx_message->data.manual_timestamp.new_afreq_ppm = UTI_FloatHostToNetwork(new_afreq_ppm);
519   } else {
520     tx_message->status = htons(STT_FAILED);
521   }
522 }
523 
524 /* ================================================== */
525 
526 static void
handle_local(CMD_Request * rx_message,CMD_Reply * tx_message)527 handle_local(CMD_Request *rx_message, CMD_Reply *tx_message)
528 {
529   if (ntohl(rx_message->data.local.on_off)) {
530     REF_EnableLocal(ntohl(rx_message->data.local.stratum),
531                     UTI_FloatNetworkToHost(rx_message->data.local.distance),
532                     ntohl(rx_message->data.local.orphan));
533   } else {
534     REF_DisableLocal();
535   }
536 }
537 
538 /* ================================================== */
539 
540 static void
handle_manual(CMD_Request * rx_message,CMD_Reply * tx_message)541 handle_manual(CMD_Request *rx_message, CMD_Reply *tx_message)
542 {
543   int option;
544   option = ntohl(rx_message->data.manual.option);
545   switch (option) {
546     case 0:
547       MNL_Disable();
548       break;
549     case 1:
550       MNL_Enable();
551       break;
552     case 2:
553       MNL_Reset();
554       break;
555     default:
556       tx_message->status = htons(STT_INVALID);
557       break;
558   }
559 }
560 
561 /* ================================================== */
562 
563 static void
handle_n_sources(CMD_Request * rx_message,CMD_Reply * tx_message)564 handle_n_sources(CMD_Request *rx_message, CMD_Reply *tx_message)
565 {
566   int n_sources;
567   n_sources = SRC_ReadNumberOfSources();
568   tx_message->reply = htons(RPY_N_SOURCES);
569   tx_message->data.n_sources.n_sources = htonl(n_sources);
570 }
571 
572 /* ================================================== */
573 
574 static void
handle_source_data(CMD_Request * rx_message,CMD_Reply * tx_message)575 handle_source_data(CMD_Request *rx_message, CMD_Reply *tx_message)
576 {
577   RPT_SourceReport report;
578   struct timespec now_corr;
579 
580   /* Get data */
581   SCH_GetLastEventTime(&now_corr, NULL, NULL);
582   if (SRC_ReportSource(ntohl(rx_message->data.source_data.index), &report, &now_corr)) {
583     switch (SRC_GetType(ntohl(rx_message->data.source_data.index))) {
584       case SRC_NTP:
585         NSR_ReportSource(&report, &now_corr);
586         break;
587       case SRC_REFCLOCK:
588         RCL_ReportSource(&report, &now_corr);
589         break;
590     }
591 
592     tx_message->reply  = htons(RPY_SOURCE_DATA);
593 
594     UTI_IPHostToNetwork(&report.ip_addr, &tx_message->data.source_data.ip_addr);
595     tx_message->data.source_data.stratum = htons(report.stratum);
596     tx_message->data.source_data.poll    = htons(report.poll);
597     switch (report.state) {
598       case RPT_NONSELECTABLE:
599         tx_message->data.source_data.state   = htons(RPY_SD_ST_NONSELECTABLE);
600         break;
601       case RPT_FALSETICKER:
602         tx_message->data.source_data.state   = htons(RPY_SD_ST_FALSETICKER);
603         break;
604       case RPT_JITTERY:
605         tx_message->data.source_data.state   = htons(RPY_SD_ST_JITTERY);
606         break;
607       case RPT_SELECTABLE:
608         tx_message->data.source_data.state   = htons(RPY_SD_ST_SELECTABLE);
609         break;
610       case RPT_UNSELECTED:
611         tx_message->data.source_data.state   = htons(RPY_SD_ST_UNSELECTED);
612         break;
613       case RPT_SELECTED:
614         tx_message->data.source_data.state   = htons(RPY_SD_ST_SELECTED);
615         break;
616     }
617     switch (report.mode) {
618       case RPT_NTP_CLIENT:
619         tx_message->data.source_data.mode    = htons(RPY_SD_MD_CLIENT);
620         break;
621       case RPT_NTP_PEER:
622         tx_message->data.source_data.mode    = htons(RPY_SD_MD_PEER);
623         break;
624       case RPT_LOCAL_REFERENCE:
625         tx_message->data.source_data.mode    = htons(RPY_SD_MD_REF);
626         break;
627     }
628     tx_message->data.source_data.flags = htons(0);
629     tx_message->data.source_data.reachability = htons(report.reachability);
630     tx_message->data.source_data.since_sample = htonl(report.latest_meas_ago);
631     tx_message->data.source_data.orig_latest_meas = UTI_FloatHostToNetwork(report.orig_latest_meas);
632     tx_message->data.source_data.latest_meas = UTI_FloatHostToNetwork(report.latest_meas);
633     tx_message->data.source_data.latest_meas_err = UTI_FloatHostToNetwork(report.latest_meas_err);
634   } else {
635     tx_message->status = htons(STT_NOSUCHSOURCE);
636   }
637 }
638 
639 /* ================================================== */
640 
641 static void
handle_rekey(CMD_Request * rx_message,CMD_Reply * tx_message)642 handle_rekey(CMD_Request *rx_message, CMD_Reply *tx_message)
643 {
644   KEY_Reload();
645   NKS_ReloadKeys();
646 }
647 
648 /* ================================================== */
649 
650 static void
handle_allowdeny(CMD_Request * rx_message,CMD_Reply * tx_message,int allow,int all)651 handle_allowdeny(CMD_Request *rx_message, CMD_Reply *tx_message, int allow, int all)
652 {
653   IPAddr ip;
654   int subnet_bits;
655 
656   UTI_IPNetworkToHost(&rx_message->data.allow_deny.ip, &ip);
657   subnet_bits = ntohl(rx_message->data.allow_deny.subnet_bits);
658   if (!NCR_AddAccessRestriction(&ip, subnet_bits, allow, all))
659     tx_message->status = htons(STT_BADSUBNET);
660 }
661 
662 /* ================================================== */
663 
664 static void
handle_cmdallowdeny(CMD_Request * rx_message,CMD_Reply * tx_message,int allow,int all)665 handle_cmdallowdeny(CMD_Request *rx_message, CMD_Reply *tx_message, int allow, int all)
666 {
667   IPAddr ip;
668   int subnet_bits;
669 
670   UTI_IPNetworkToHost(&rx_message->data.allow_deny.ip, &ip);
671   subnet_bits = ntohl(rx_message->data.allow_deny.subnet_bits);
672   if (!CAM_AddAccessRestriction(&ip, subnet_bits, allow, all))
673     tx_message->status = htons(STT_BADSUBNET);
674 }
675 
676 /* ================================================== */
677 
678 static void
handle_accheck(CMD_Request * rx_message,CMD_Reply * tx_message)679 handle_accheck(CMD_Request *rx_message, CMD_Reply *tx_message)
680 {
681   IPAddr ip;
682   UTI_IPNetworkToHost(&rx_message->data.ac_check.ip, &ip);
683   if (NCR_CheckAccessRestriction(&ip)) {
684     tx_message->status = htons(STT_ACCESSALLOWED);
685   } else {
686     tx_message->status = htons(STT_ACCESSDENIED);
687   }
688 }
689 
690 /* ================================================== */
691 
692 static void
handle_cmdaccheck(CMD_Request * rx_message,CMD_Reply * tx_message)693 handle_cmdaccheck(CMD_Request *rx_message, CMD_Reply *tx_message)
694 {
695   IPAddr ip;
696   UTI_IPNetworkToHost(&rx_message->data.ac_check.ip, &ip);
697   if (CAM_CheckAccessRestriction(&ip)) {
698     tx_message->status = htons(STT_ACCESSALLOWED);
699   } else {
700     tx_message->status = htons(STT_ACCESSDENIED);
701   }
702 }
703 
704 /* ================================================== */
705 
706 static void
handle_add_source(CMD_Request * rx_message,CMD_Reply * tx_message)707 handle_add_source(CMD_Request *rx_message, CMD_Reply *tx_message)
708 {
709   NTP_Source_Type type;
710   SourceParameters params;
711   NSR_Status status;
712   char *name;
713   int pool, port;
714 
715   switch (ntohl(rx_message->data.ntp_source.type)) {
716     case REQ_ADDSRC_SERVER:
717       type = NTP_SERVER;
718       pool = 0;
719       break;
720     case REQ_ADDSRC_PEER:
721       type = NTP_PEER;
722       pool = 0;
723       break;
724     case REQ_ADDSRC_POOL:
725       type = NTP_SERVER;
726       pool = 1;
727       break;
728     default:
729       tx_message->status = htons(STT_INVALID);
730       return;
731   }
732 
733   name = (char *)rx_message->data.ntp_source.name;
734 
735   /* Make sure the name is terminated */
736   if (name[sizeof (rx_message->data.ntp_source.name) - 1] != '\0') {
737       tx_message->status = htons(STT_INVALIDNAME);
738       return;
739   }
740 
741   port = ntohl(rx_message->data.ntp_source.port);
742   params.minpoll = ntohl(rx_message->data.ntp_source.minpoll);
743   params.maxpoll = ntohl(rx_message->data.ntp_source.maxpoll);
744   params.presend_minpoll = ntohl(rx_message->data.ntp_source.presend_minpoll);
745   params.min_stratum = ntohl(rx_message->data.ntp_source.min_stratum);
746   params.poll_target = ntohl(rx_message->data.ntp_source.poll_target);
747   params.version = ntohl(rx_message->data.ntp_source.version);
748   params.max_sources = ntohl(rx_message->data.ntp_source.max_sources);
749   params.min_samples = ntohl(rx_message->data.ntp_source.min_samples);
750   params.max_samples = ntohl(rx_message->data.ntp_source.max_samples);
751   params.filter_length = ntohl(rx_message->data.ntp_source.filter_length);
752   params.authkey = ntohl(rx_message->data.ntp_source.authkey);
753   params.nts_port = ntohl(rx_message->data.ntp_source.nts_port);
754   params.cert_set = ntohl(rx_message->data.ntp_source.cert_set);
755   params.max_delay = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay);
756   params.max_delay_ratio =
757     UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_ratio);
758   params.max_delay_dev_ratio =
759     UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_dev_ratio);
760   params.min_delay = UTI_FloatNetworkToHost(rx_message->data.ntp_source.min_delay);
761   params.asymmetry = UTI_FloatNetworkToHost(rx_message->data.ntp_source.asymmetry);
762   params.offset = UTI_FloatNetworkToHost(rx_message->data.ntp_source.offset);
763 
764   params.connectivity = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_ONLINE ?
765                         SRC_ONLINE : SRC_OFFLINE;
766   params.auto_offline = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_AUTOOFFLINE ? 1 : 0;
767   params.iburst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_IBURST ? 1 : 0;
768   params.interleaved = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_INTERLEAVED ? 1 : 0;
769   params.burst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_BURST ? 1 : 0;
770   params.nts = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_NTS ? 1 : 0;
771   params.copy = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_COPY ? 1 : 0;
772   params.ext_fields =
773     ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_EF_EXP1 ? NTP_EF_FLAG_EXP1 : 0;
774   params.sel_options =
775     (ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_PREFER ? SRC_SELECT_PREFER : 0) |
776     (ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_NOSELECT ? SRC_SELECT_NOSELECT : 0) |
777     (ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_TRUST ? SRC_SELECT_TRUST : 0) |
778     (ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_REQUIRE ? SRC_SELECT_REQUIRE : 0);
779 
780   status = NSR_AddSourceByName(name, port, pool, type, &params, NULL);
781   switch (status) {
782     case NSR_Success:
783       break;
784     case NSR_UnresolvedName:
785       /* Try to resolve the name now */
786       NSR_ResolveSources();
787       break;
788     case NSR_AlreadyInUse:
789       tx_message->status = htons(STT_SOURCEALREADYKNOWN);
790       break;
791     case NSR_TooManySources:
792       tx_message->status = htons(STT_TOOMANYSOURCES);
793       break;
794     case NSR_InvalidName:
795       tx_message->status = htons(STT_INVALIDNAME);
796       break;
797     case NSR_InvalidAF:
798     case NSR_NoSuchSource:
799       assert(0);
800       break;
801   }
802 }
803 
804 /* ================================================== */
805 
806 static void
handle_del_source(CMD_Request * rx_message,CMD_Reply * tx_message)807 handle_del_source(CMD_Request *rx_message, CMD_Reply *tx_message)
808 {
809   NSR_Status status;
810   IPAddr ip_addr;
811 
812   UTI_IPNetworkToHost(&rx_message->data.del_source.ip_addr, &ip_addr);
813 
814   status = NSR_RemoveSource(&ip_addr);
815   switch (status) {
816     case NSR_Success:
817       break;
818     case NSR_NoSuchSource:
819       tx_message->status = htons(STT_NOSUCHSOURCE);
820       break;
821     case NSR_TooManySources:
822     case NSR_AlreadyInUse:
823     case NSR_InvalidAF:
824     case NSR_InvalidName:
825     case NSR_UnresolvedName:
826       assert(0);
827       break;
828   }
829 }
830 
831 /* ================================================== */
832 
833 static void
handle_writertc(CMD_Request * rx_message,CMD_Reply * tx_message)834 handle_writertc(CMD_Request *rx_message, CMD_Reply *tx_message)
835 {
836   switch (RTC_WriteParameters()) {
837     case RTC_ST_OK:
838       break;
839     case RTC_ST_NODRV:
840       tx_message->status = htons(STT_NORTC);
841       break;
842     case RTC_ST_BADFILE:
843       tx_message->status = htons(STT_BADRTCFILE);
844       break;
845   }
846 }
847 
848 /* ================================================== */
849 
850 static void
handle_dfreq(CMD_Request * rx_message,CMD_Reply * tx_message)851 handle_dfreq(CMD_Request *rx_message, CMD_Reply *tx_message)
852 {
853   double dfreq;
854   dfreq = UTI_FloatNetworkToHost(rx_message->data.dfreq.dfreq);
855   LCL_AccumulateDeltaFrequency(dfreq * 1.0e-6);
856   LOG(LOGS_INFO, "Accumulated delta freq of %.3fppm", dfreq);
857 }
858 
859 /* ================================================== */
860 
861 static void
handle_doffset(CMD_Request * rx_message,CMD_Reply * tx_message)862 handle_doffset(CMD_Request *rx_message, CMD_Reply *tx_message)
863 {
864   double doffset;
865 
866   doffset = UTI_FloatNetworkToHost(rx_message->data.doffset.doffset);
867   if (!LCL_AccumulateOffset(doffset, 0.0)) {
868     tx_message->status = htons(STT_FAILED);
869   } else {
870     LOG(LOGS_INFO, "Accumulated delta offset of %.6f seconds", doffset);
871   }
872 }
873 
874 /* ================================================== */
875 
876 static void
handle_tracking(CMD_Request * rx_message,CMD_Reply * tx_message)877 handle_tracking(CMD_Request *rx_message, CMD_Reply *tx_message)
878 {
879   RPT_TrackingReport rpt;
880 
881   REF_GetTrackingReport(&rpt);
882   tx_message->reply  = htons(RPY_TRACKING);
883   tx_message->data.tracking.ref_id = htonl(rpt.ref_id);
884   UTI_IPHostToNetwork(&rpt.ip_addr, &tx_message->data.tracking.ip_addr);
885   tx_message->data.tracking.stratum = htons(rpt.stratum);
886   tx_message->data.tracking.leap_status = htons(rpt.leap_status);
887   UTI_TimespecHostToNetwork(&rpt.ref_time, &tx_message->data.tracking.ref_time);
888   tx_message->data.tracking.current_correction = UTI_FloatHostToNetwork(rpt.current_correction);
889   tx_message->data.tracking.last_offset = UTI_FloatHostToNetwork(rpt.last_offset);
890   tx_message->data.tracking.rms_offset = UTI_FloatHostToNetwork(rpt.rms_offset);
891   tx_message->data.tracking.freq_ppm = UTI_FloatHostToNetwork(rpt.freq_ppm);
892   tx_message->data.tracking.resid_freq_ppm = UTI_FloatHostToNetwork(rpt.resid_freq_ppm);
893   tx_message->data.tracking.skew_ppm = UTI_FloatHostToNetwork(rpt.skew_ppm);
894   tx_message->data.tracking.root_delay = UTI_FloatHostToNetwork(rpt.root_delay);
895   tx_message->data.tracking.root_dispersion = UTI_FloatHostToNetwork(rpt.root_dispersion);
896   tx_message->data.tracking.last_update_interval = UTI_FloatHostToNetwork(rpt.last_update_interval);
897 }
898 
899 /* ================================================== */
900 
901 static void
handle_smoothing(CMD_Request * rx_message,CMD_Reply * tx_message)902 handle_smoothing(CMD_Request *rx_message, CMD_Reply *tx_message)
903 {
904   RPT_SmoothingReport report;
905   struct timespec now;
906 
907   SCH_GetLastEventTime(&now, NULL, NULL);
908 
909   if (!SMT_GetSmoothingReport(&report, &now)) {
910     tx_message->status = htons(STT_NOTENABLED);
911     return;
912   }
913 
914   tx_message->reply  = htons(RPY_SMOOTHING);
915   tx_message->data.smoothing.flags = htonl((report.active ? RPY_SMT_FLAG_ACTIVE : 0) |
916                                            (report.leap_only ? RPY_SMT_FLAG_LEAPONLY : 0));
917   tx_message->data.smoothing.offset = UTI_FloatHostToNetwork(report.offset);
918   tx_message->data.smoothing.freq_ppm = UTI_FloatHostToNetwork(report.freq_ppm);
919   tx_message->data.smoothing.wander_ppm = UTI_FloatHostToNetwork(report.wander_ppm);
920   tx_message->data.smoothing.last_update_ago = UTI_FloatHostToNetwork(report.last_update_ago);
921   tx_message->data.smoothing.remaining_time = UTI_FloatHostToNetwork(report.remaining_time);
922 }
923 
924 /* ================================================== */
925 
926 static void
handle_smoothtime(CMD_Request * rx_message,CMD_Reply * tx_message)927 handle_smoothtime(CMD_Request *rx_message, CMD_Reply *tx_message)
928 {
929   struct timespec now;
930   int option;
931 
932   if (!SMT_IsEnabled()) {
933     tx_message->status = htons(STT_NOTENABLED);
934     return;
935   }
936 
937   option = ntohl(rx_message->data.smoothtime.option);
938   SCH_GetLastEventTime(&now, NULL, NULL);
939 
940   switch (option) {
941     case REQ_SMOOTHTIME_RESET:
942       SMT_Reset(&now);
943       break;
944     case REQ_SMOOTHTIME_ACTIVATE:
945       SMT_Activate(&now);
946       break;
947     default:
948       tx_message->status = htons(STT_INVALID);
949       break;
950   }
951 }
952 
953 /* ================================================== */
954 
955 static void
handle_sourcestats(CMD_Request * rx_message,CMD_Reply * tx_message)956 handle_sourcestats(CMD_Request *rx_message, CMD_Reply *tx_message)
957 {
958   int status;
959   RPT_SourcestatsReport report;
960   struct timespec now_corr;
961 
962   SCH_GetLastEventTime(&now_corr, NULL, NULL);
963   status = SRC_ReportSourcestats(ntohl(rx_message->data.sourcestats.index),
964                                  &report, &now_corr);
965 
966   if (status) {
967     tx_message->reply = htons(RPY_SOURCESTATS);
968     tx_message->data.sourcestats.ref_id = htonl(report.ref_id);
969     UTI_IPHostToNetwork(&report.ip_addr, &tx_message->data.sourcestats.ip_addr);
970     tx_message->data.sourcestats.n_samples = htonl(report.n_samples);
971     tx_message->data.sourcestats.n_runs = htonl(report.n_runs);
972     tx_message->data.sourcestats.span_seconds = htonl(report.span_seconds);
973     tx_message->data.sourcestats.resid_freq_ppm = UTI_FloatHostToNetwork(report.resid_freq_ppm);
974     tx_message->data.sourcestats.skew_ppm = UTI_FloatHostToNetwork(report.skew_ppm);
975     tx_message->data.sourcestats.sd = UTI_FloatHostToNetwork(report.sd);
976     tx_message->data.sourcestats.est_offset = UTI_FloatHostToNetwork(report.est_offset);
977     tx_message->data.sourcestats.est_offset_err = UTI_FloatHostToNetwork(report.est_offset_err);
978   } else {
979     tx_message->status = htons(STT_NOSUCHSOURCE);
980   }
981 }
982 
983 /* ================================================== */
984 
985 static void
handle_rtcreport(CMD_Request * rx_message,CMD_Reply * tx_message)986 handle_rtcreport(CMD_Request *rx_message, CMD_Reply *tx_message)
987 {
988   int status;
989   RPT_RTC_Report report;
990   status = RTC_GetReport(&report);
991   if (status) {
992     tx_message->reply  = htons(RPY_RTC);
993     UTI_TimespecHostToNetwork(&report.ref_time, &tx_message->data.rtc.ref_time);
994     tx_message->data.rtc.n_samples = htons(report.n_samples);
995     tx_message->data.rtc.n_runs = htons(report.n_runs);
996     tx_message->data.rtc.span_seconds = htonl(report.span_seconds);
997     tx_message->data.rtc.rtc_seconds_fast = UTI_FloatHostToNetwork(report.rtc_seconds_fast);
998     tx_message->data.rtc.rtc_gain_rate_ppm = UTI_FloatHostToNetwork(report.rtc_gain_rate_ppm);
999   } else {
1000     tx_message->status = htons(STT_NORTC);
1001   }
1002 }
1003 
1004 /* ================================================== */
1005 
1006 static void
handle_trimrtc(CMD_Request * rx_message,CMD_Reply * tx_message)1007 handle_trimrtc(CMD_Request *rx_message, CMD_Reply *tx_message)
1008 {
1009   if (!RTC_Trim())
1010     tx_message->status = htons(STT_NORTC);
1011 }
1012 
1013 /* ================================================== */
1014 
1015 static void
handle_cyclelogs(CMD_Request * rx_message,CMD_Reply * tx_message)1016 handle_cyclelogs(CMD_Request *rx_message, CMD_Reply *tx_message)
1017 {
1018   LOG_CycleLogFiles();
1019 }
1020 
1021 /* ================================================== */
1022 
1023 static void
handle_client_accesses_by_index(CMD_Request * rx_message,CMD_Reply * tx_message)1024 handle_client_accesses_by_index(CMD_Request *rx_message, CMD_Reply *tx_message)
1025 {
1026   RPT_ClientAccessByIndex_Report report;
1027   RPY_ClientAccesses_Client *client;
1028   int n_indices;
1029   uint32_t i, j, req_first_index, req_n_clients, req_min_hits, req_reset;
1030   struct timespec now;
1031 
1032   SCH_GetLastEventTime(&now, NULL, NULL);
1033 
1034   req_first_index = ntohl(rx_message->data.client_accesses_by_index.first_index);
1035   req_n_clients = ntohl(rx_message->data.client_accesses_by_index.n_clients);
1036   if (req_n_clients > MAX_CLIENT_ACCESSES)
1037     req_n_clients = MAX_CLIENT_ACCESSES;
1038   req_min_hits = ntohl(rx_message->data.client_accesses_by_index.min_hits);
1039   req_reset = ntohl(rx_message->data.client_accesses_by_index.reset);
1040 
1041   n_indices = CLG_GetNumberOfIndices();
1042   if (n_indices < 0) {
1043     tx_message->status = htons(STT_INACTIVE);
1044     return;
1045   }
1046 
1047   tx_message->reply = htons(RPY_CLIENT_ACCESSES_BY_INDEX3);
1048   tx_message->data.client_accesses_by_index.n_indices = htonl(n_indices);
1049 
1050   for (i = req_first_index, j = 0; i < (uint32_t)n_indices && j < req_n_clients; i++) {
1051     if (!CLG_GetClientAccessReportByIndex(i, req_reset, req_min_hits, &report, &now))
1052       continue;
1053 
1054     client = &tx_message->data.client_accesses_by_index.clients[j++];
1055 
1056     UTI_IPHostToNetwork(&report.ip_addr, &client->ip);
1057     client->ntp_hits = htonl(report.ntp_hits);
1058     client->nke_hits = htonl(report.nke_hits);
1059     client->cmd_hits = htonl(report.cmd_hits);
1060     client->ntp_drops = htonl(report.ntp_drops);
1061     client->nke_drops = htonl(report.nke_drops);
1062     client->cmd_drops = htonl(report.cmd_drops);
1063     client->ntp_interval = report.ntp_interval;
1064     client->nke_interval = report.nke_interval;
1065     client->cmd_interval = report.cmd_interval;
1066     client->ntp_timeout_interval = report.ntp_timeout_interval;
1067     client->last_ntp_hit_ago = htonl(report.last_ntp_hit_ago);
1068     client->last_nke_hit_ago = htonl(report.last_nke_hit_ago);
1069     client->last_cmd_hit_ago = htonl(report.last_cmd_hit_ago);
1070   }
1071 
1072   tx_message->data.client_accesses_by_index.next_index = htonl(i);
1073   tx_message->data.client_accesses_by_index.n_clients = htonl(j);
1074 }
1075 
1076 /* ================================================== */
1077 
1078 static void
handle_manual_list(CMD_Request * rx_message,CMD_Reply * tx_message)1079 handle_manual_list(CMD_Request *rx_message, CMD_Reply *tx_message)
1080 {
1081   int n_samples;
1082   int i;
1083   RPY_ManualListSample *sample;
1084   RPT_ManualSamplesReport report[MAX_MANUAL_LIST_SAMPLES];
1085 
1086   tx_message->reply = htons(RPY_MANUAL_LIST2);
1087 
1088   MNL_ReportSamples(report, MAX_MANUAL_LIST_SAMPLES, &n_samples);
1089   tx_message->data.manual_list.n_samples = htonl(n_samples);
1090 
1091   for (i=0; i<n_samples; i++) {
1092     sample = &tx_message->data.manual_list.samples[i];
1093     UTI_TimespecHostToNetwork(&report[i].when, &sample->when);
1094     sample->slewed_offset = UTI_FloatHostToNetwork(report[i].slewed_offset);
1095     sample->orig_offset = UTI_FloatHostToNetwork(report[i].orig_offset);
1096     sample->residual = UTI_FloatHostToNetwork(report[i].residual);
1097   }
1098 }
1099 
1100 /* ================================================== */
1101 
1102 static void
handle_manual_delete(CMD_Request * rx_message,CMD_Reply * tx_message)1103 handle_manual_delete(CMD_Request *rx_message, CMD_Reply *tx_message)
1104 {
1105   int index;
1106 
1107   index = ntohl(rx_message->data.manual_delete.index);
1108   if (!MNL_DeleteSample(index))
1109     tx_message->status = htons(STT_BADSAMPLE);
1110 }
1111 
1112 /* ================================================== */
1113 
1114 static void
handle_make_step(CMD_Request * rx_message,CMD_Reply * tx_message)1115 handle_make_step(CMD_Request *rx_message, CMD_Reply *tx_message)
1116 {
1117   if (!LCL_MakeStep())
1118     tx_message->status = htons(STT_FAILED);
1119 }
1120 
1121 /* ================================================== */
1122 
1123 static void
handle_activity(CMD_Request * rx_message,CMD_Reply * tx_message)1124 handle_activity(CMD_Request *rx_message, CMD_Reply *tx_message)
1125 {
1126   RPT_ActivityReport report;
1127   NSR_GetActivityReport(&report);
1128   tx_message->data.activity.online = htonl(report.online);
1129   tx_message->data.activity.offline = htonl(report.offline);
1130   tx_message->data.activity.burst_online = htonl(report.burst_online);
1131   tx_message->data.activity.burst_offline = htonl(report.burst_offline);
1132   tx_message->data.activity.unresolved = htonl(report.unresolved);
1133   tx_message->reply = htons(RPY_ACTIVITY);
1134 }
1135 
1136 /* ================================================== */
1137 
1138 static void
handle_reselect_distance(CMD_Request * rx_message,CMD_Reply * tx_message)1139 handle_reselect_distance(CMD_Request *rx_message, CMD_Reply *tx_message)
1140 {
1141   double dist;
1142   dist = UTI_FloatNetworkToHost(rx_message->data.reselect_distance.distance);
1143   SRC_SetReselectDistance(dist);
1144 }
1145 
1146 /* ================================================== */
1147 
1148 static void
handle_reselect(CMD_Request * rx_message,CMD_Reply * tx_message)1149 handle_reselect(CMD_Request *rx_message, CMD_Reply *tx_message)
1150 {
1151   SRC_ReselectSource();
1152 }
1153 
1154 /* ================================================== */
1155 
1156 static void
handle_refresh(CMD_Request * rx_message,CMD_Reply * tx_message)1157 handle_refresh(CMD_Request *rx_message, CMD_Reply *tx_message)
1158 {
1159   NSR_RefreshAddresses();
1160 }
1161 
1162 /* ================================================== */
1163 
1164 static void
handle_server_stats(CMD_Request * rx_message,CMD_Reply * tx_message)1165 handle_server_stats(CMD_Request *rx_message, CMD_Reply *tx_message)
1166 {
1167   RPT_ServerStatsReport report;
1168 
1169   CLG_GetServerStatsReport(&report);
1170   tx_message->reply = htons(RPY_SERVER_STATS3);
1171   tx_message->data.server_stats.ntp_hits = htonl(report.ntp_hits);
1172   tx_message->data.server_stats.nke_hits = htonl(report.nke_hits);
1173   tx_message->data.server_stats.cmd_hits = htonl(report.cmd_hits);
1174   tx_message->data.server_stats.ntp_drops = htonl(report.ntp_drops);
1175   tx_message->data.server_stats.nke_drops = htonl(report.nke_drops);
1176   tx_message->data.server_stats.cmd_drops = htonl(report.cmd_drops);
1177   tx_message->data.server_stats.log_drops = htonl(report.log_drops);
1178   tx_message->data.server_stats.ntp_auth_hits = htonl(report.ntp_auth_hits);
1179   tx_message->data.server_stats.ntp_interleaved_hits = htonl(report.ntp_interleaved_hits);
1180   tx_message->data.server_stats.ntp_timestamps = htonl(report.ntp_timestamps);
1181   tx_message->data.server_stats.ntp_span_seconds = htonl(report.ntp_span_seconds);
1182 }
1183 
1184 /* ================================================== */
1185 
1186 static void
handle_ntp_data(CMD_Request * rx_message,CMD_Reply * tx_message)1187 handle_ntp_data(CMD_Request *rx_message, CMD_Reply *tx_message)
1188 {
1189   RPT_NTPReport report;
1190 
1191   UTI_IPNetworkToHost(&rx_message->data.ntp_data.ip_addr, &report.remote_addr);
1192 
1193   if (!NSR_GetNTPReport(&report)) {
1194     tx_message->status = htons(STT_NOSUCHSOURCE);
1195     return;
1196   }
1197 
1198   tx_message->reply = htons(RPY_NTP_DATA);
1199   UTI_IPHostToNetwork(&report.remote_addr, &tx_message->data.ntp_data.remote_addr);
1200   UTI_IPHostToNetwork(&report.local_addr, &tx_message->data.ntp_data.local_addr);
1201   tx_message->data.ntp_data.remote_port = htons(report.remote_port);
1202   tx_message->data.ntp_data.leap = report.leap;
1203   tx_message->data.ntp_data.version = report.version;
1204   tx_message->data.ntp_data.mode = report.mode;
1205   tx_message->data.ntp_data.stratum = report.stratum;
1206   tx_message->data.ntp_data.poll = report.poll;
1207   tx_message->data.ntp_data.precision = report.precision;
1208   tx_message->data.ntp_data.root_delay = UTI_FloatHostToNetwork(report.root_delay);
1209   tx_message->data.ntp_data.root_dispersion = UTI_FloatHostToNetwork(report.root_dispersion);
1210   tx_message->data.ntp_data.ref_id = htonl(report.ref_id);
1211   UTI_TimespecHostToNetwork(&report.ref_time, &tx_message->data.ntp_data.ref_time);
1212   tx_message->data.ntp_data.offset = UTI_FloatHostToNetwork(report.offset);
1213   tx_message->data.ntp_data.peer_delay = UTI_FloatHostToNetwork(report.peer_delay);
1214   tx_message->data.ntp_data.peer_dispersion = UTI_FloatHostToNetwork(report.peer_dispersion);
1215   tx_message->data.ntp_data.response_time = UTI_FloatHostToNetwork(report.response_time);
1216   tx_message->data.ntp_data.jitter_asymmetry = UTI_FloatHostToNetwork(report.jitter_asymmetry);
1217   tx_message->data.ntp_data.flags = htons((report.tests & RPY_NTP_FLAGS_TESTS) |
1218                                           (report.interleaved ? RPY_NTP_FLAG_INTERLEAVED : 0) |
1219                                           (report.authenticated ? RPY_NTP_FLAG_AUTHENTICATED : 0));
1220   tx_message->data.ntp_data.tx_tss_char = report.tx_tss_char;
1221   tx_message->data.ntp_data.rx_tss_char = report.rx_tss_char;
1222   tx_message->data.ntp_data.total_tx_count = htonl(report.total_tx_count);
1223   tx_message->data.ntp_data.total_rx_count = htonl(report.total_rx_count);
1224   tx_message->data.ntp_data.total_valid_count = htonl(report.total_valid_count);
1225   memset(tx_message->data.ntp_data.reserved, 0xff, sizeof (tx_message->data.ntp_data.reserved));
1226 }
1227 
1228 /* ================================================== */
1229 
1230 static void
handle_shutdown(CMD_Request * rx_message,CMD_Reply * tx_message)1231 handle_shutdown(CMD_Request *rx_message, CMD_Reply *tx_message)
1232 {
1233   LOG(LOGS_INFO, "Received shutdown command");
1234   SCH_QuitProgram();
1235 }
1236 
1237 /* ================================================== */
1238 
1239 static void
handle_ntp_source_name(CMD_Request * rx_message,CMD_Reply * tx_message)1240 handle_ntp_source_name(CMD_Request *rx_message, CMD_Reply *tx_message)
1241 {
1242   IPAddr addr;
1243   char *name;
1244 
1245   UTI_IPNetworkToHost(&rx_message->data.ntp_source_name.ip_addr, &addr);
1246   name = NSR_GetName(&addr);
1247 
1248   if (!name) {
1249     tx_message->status = htons(STT_NOSUCHSOURCE);
1250     return;
1251   }
1252 
1253   tx_message->reply = htons(RPY_NTP_SOURCE_NAME);
1254 
1255   /* Avoid compiler warning */
1256   if (strlen(name) >= sizeof (tx_message->data.ntp_source_name.name))
1257     memcpy(tx_message->data.ntp_source_name.name, name,
1258            sizeof (tx_message->data.ntp_source_name.name));
1259   else
1260     strncpy((char *)tx_message->data.ntp_source_name.name, name,
1261             sizeof (tx_message->data.ntp_source_name.name));
1262 }
1263 
1264 /* ================================================== */
1265 
1266 static void
handle_reload_sources(CMD_Request * rx_message,CMD_Reply * tx_message)1267 handle_reload_sources(CMD_Request *rx_message, CMD_Reply *tx_message)
1268 {
1269   CNF_ReloadSources();
1270 }
1271 
1272 /* ================================================== */
1273 
1274 static void
handle_reset_sources(CMD_Request * rx_message,CMD_Reply * tx_message)1275 handle_reset_sources(CMD_Request *rx_message, CMD_Reply *tx_message)
1276 {
1277   struct timespec cooked_now, now;
1278 
1279   SRC_ResetSources();
1280   SCH_GetLastEventTime(&cooked_now, NULL, &now);
1281   LCL_NotifyExternalTimeStep(&now, &cooked_now, 0.0, 0.0);
1282 }
1283 
1284 /* ================================================== */
1285 
1286 static void
handle_auth_data(CMD_Request * rx_message,CMD_Reply * tx_message)1287 handle_auth_data(CMD_Request *rx_message, CMD_Reply *tx_message)
1288 {
1289   RPT_AuthReport report;
1290   IPAddr ip_addr;
1291 
1292   UTI_IPNetworkToHost(&rx_message->data.auth_data.ip_addr, &ip_addr);
1293 
1294   if (!NSR_GetAuthReport(&ip_addr, &report)) {
1295     tx_message->status = htons(STT_NOSUCHSOURCE);
1296     return;
1297   }
1298 
1299   tx_message->reply = htons(RPY_AUTH_DATA);
1300 
1301   switch (report.mode) {
1302     case NTP_AUTH_NONE:
1303       tx_message->data.auth_data.mode = htons(RPY_AD_MD_NONE);
1304       break;
1305     case NTP_AUTH_SYMMETRIC:
1306       tx_message->data.auth_data.mode = htons(RPY_AD_MD_SYMMETRIC);
1307       break;
1308     case NTP_AUTH_NTS:
1309       tx_message->data.auth_data.mode = htons(RPY_AD_MD_NTS);
1310       break;
1311     default:
1312       break;
1313   }
1314 
1315   tx_message->data.auth_data.key_type = htons(report.key_type);
1316   tx_message->data.auth_data.key_id = htonl(report.key_id);
1317   tx_message->data.auth_data.key_length = htons(report.key_length);
1318   tx_message->data.auth_data.ke_attempts = htons(report.ke_attempts);
1319   tx_message->data.auth_data.last_ke_ago = htonl(report.last_ke_ago);
1320   tx_message->data.auth_data.cookies = htons(report.cookies);
1321   tx_message->data.auth_data.cookie_length = htons(report.cookie_length);
1322   tx_message->data.auth_data.nak = htons(report.nak);
1323 }
1324 
1325 /* ================================================== */
1326 
1327 static uint16_t
convert_select_options(int options)1328 convert_select_options(int options)
1329 {
1330   return (options & SRC_SELECT_PREFER ? RPY_SD_OPTION_PREFER : 0) |
1331          (options & SRC_SELECT_NOSELECT ? RPY_SD_OPTION_NOSELECT : 0) |
1332          (options & SRC_SELECT_TRUST ? RPY_SD_OPTION_TRUST : 0) |
1333          (options & SRC_SELECT_REQUIRE ? RPY_SD_OPTION_REQUIRE : 0);
1334 }
1335 
1336 /* ================================================== */
1337 
1338 static void
handle_select_data(CMD_Request * rx_message,CMD_Reply * tx_message)1339 handle_select_data(CMD_Request *rx_message, CMD_Reply *tx_message)
1340 {
1341   RPT_SelectReport report;
1342 
1343   if (!SRC_GetSelectReport(ntohl(rx_message->data.select_data.index), &report)) {
1344     tx_message->status = htons(STT_NOSUCHSOURCE);
1345     return;
1346   }
1347 
1348   tx_message->reply = htons(RPY_SELECT_DATA);
1349 
1350   tx_message->data.select_data.ref_id = htonl(report.ref_id);
1351   UTI_IPHostToNetwork(&report.ip_addr, &tx_message->data.select_data.ip_addr);
1352   tx_message->data.select_data.state_char = report.state_char;
1353   tx_message->data.select_data.authentication = report.authentication;
1354   tx_message->data.select_data.leap = report.leap;
1355   tx_message->data.select_data.conf_options = htons(convert_select_options(report.conf_options));
1356   tx_message->data.select_data.eff_options = htons(convert_select_options(report.eff_options));
1357   tx_message->data.select_data.last_sample_ago = htonl(report.last_sample_ago);
1358   tx_message->data.select_data.score = UTI_FloatHostToNetwork(report.score);
1359   tx_message->data.select_data.hi_limit = UTI_FloatHostToNetwork(report.hi_limit);
1360   tx_message->data.select_data.lo_limit = UTI_FloatHostToNetwork(report.lo_limit);
1361 }
1362 
1363 /* ================================================== */
1364 /* Read a packet and process it */
1365 
1366 static void
read_from_cmd_socket(int sock_fd,int event,void * anything)1367 read_from_cmd_socket(int sock_fd, int event, void *anything)
1368 {
1369   SCK_Message *sck_message;
1370   CMD_Request rx_message;
1371   CMD_Reply tx_message;
1372   IPAddr loopback_addr, remote_ip;
1373   int read_length, expected_length;
1374   int localhost, allowed, log_index;
1375   uint16_t rx_command;
1376   struct timespec now, cooked_now;
1377 
1378   sck_message = SCK_ReceiveMessage(sock_fd, 0);
1379   if (!sck_message)
1380     return;
1381 
1382   read_length = sck_message->length;
1383 
1384   /* Get current time cheaply */
1385   SCH_GetLastEventTime(&cooked_now, NULL, &now);
1386 
1387   /* Check if it's from localhost (127.0.0.1, ::1, or Unix domain),
1388      or an authorised address */
1389   switch (sck_message->addr_type) {
1390     case SCK_ADDR_IP:
1391       assert(sock_fd == sock_fd4 || sock_fd == sock_fd6);
1392       remote_ip = sck_message->remote_addr.ip.ip_addr;
1393       SCK_GetLoopbackIPAddress(remote_ip.family, &loopback_addr);
1394       localhost = UTI_CompareIPs(&remote_ip, &loopback_addr, NULL) == 0;
1395 
1396       if (!localhost && !ADF_IsAllowed(access_auth_table, &remote_ip)) {
1397         DEBUG_LOG("Unauthorised host %s",
1398                   UTI_IPSockAddrToString(&sck_message->remote_addr.ip));
1399         return;
1400       }
1401 
1402       assert(remote_ip.family != IPADDR_UNSPEC);
1403 
1404       break;
1405     case SCK_ADDR_UNIX:
1406       assert(sock_fd == sock_fdu);
1407       remote_ip.family = IPADDR_UNSPEC;
1408       localhost = 1;
1409       break;
1410     default:
1411       DEBUG_LOG("Unexpected address type");
1412       return;
1413   }
1414 
1415   if (read_length < offsetof(CMD_Request, data) ||
1416       read_length < offsetof(CMD_Reply, data) ||
1417       read_length > sizeof (CMD_Request)) {
1418     /* We don't know how to process anything like this or an error reply
1419        would be larger than the request */
1420     DEBUG_LOG("Unexpected length");
1421     return;
1422   }
1423 
1424   memcpy(&rx_message, sck_message->data, read_length);
1425 
1426   if (rx_message.pkt_type != PKT_TYPE_CMD_REQUEST ||
1427       rx_message.res1 != 0 ||
1428       rx_message.res2 != 0) {
1429     DEBUG_LOG("Command packet dropped");
1430     return;
1431   }
1432 
1433   log_index = CLG_LogServiceAccess(CLG_CMDMON, &remote_ip, &cooked_now);
1434 
1435   /* Don't reply to all requests from hosts other than localhost if the rate
1436      is excessive */
1437   if (!localhost && log_index >= 0 && CLG_LimitServiceRate(CLG_CMDMON, log_index)) {
1438       DEBUG_LOG("Command packet discarded to limit response rate");
1439       return;
1440   }
1441 
1442   expected_length = PKL_CommandLength(&rx_message);
1443   rx_command = ntohs(rx_message.command);
1444 
1445   memset(&tx_message, 0, sizeof (tx_message));
1446   sck_message->data = &tx_message;
1447   sck_message->length = 0;
1448 
1449   tx_message.version = PROTO_VERSION_NUMBER;
1450   tx_message.pkt_type = PKT_TYPE_CMD_REPLY;
1451   tx_message.command = rx_message.command;
1452   tx_message.reply = htons(RPY_NULL);
1453   tx_message.status = htons(STT_SUCCESS);
1454   tx_message.sequence = rx_message.sequence;
1455 
1456   if (rx_message.version != PROTO_VERSION_NUMBER) {
1457     DEBUG_LOG("Command packet has invalid version (%d != %d)",
1458               rx_message.version, PROTO_VERSION_NUMBER);
1459 
1460     if (rx_message.version >= PROTO_VERSION_MISMATCH_COMPAT_SERVER) {
1461       tx_message.status = htons(STT_BADPKTVERSION);
1462       transmit_reply(sock_fd, read_length, sck_message);
1463     }
1464     return;
1465   }
1466 
1467   if (rx_command >= N_REQUEST_TYPES ||
1468       expected_length < (int)offsetof(CMD_Request, data)) {
1469     DEBUG_LOG("Command packet has invalid command %d", rx_command);
1470 
1471     tx_message.status = htons(STT_INVALID);
1472     transmit_reply(sock_fd, read_length, sck_message);
1473     return;
1474   }
1475 
1476   if (read_length < expected_length) {
1477     DEBUG_LOG("Command packet is too short (%d < %d)", read_length,
1478               expected_length);
1479 
1480     tx_message.status = htons(STT_BADPKTLENGTH);
1481     transmit_reply(sock_fd, read_length, sck_message);
1482     return;
1483   }
1484 
1485   /* OK, we have a valid message.  Now dispatch on message type and process it. */
1486 
1487   if (rx_command >= N_REQUEST_TYPES) {
1488     /* This should be already handled */
1489     assert(0);
1490   } else {
1491     /* Check level of authority required to issue the command.  All commands
1492        from the Unix domain socket (which is accessible only by the root and
1493        chrony user/group) are allowed. */
1494     if (remote_ip.family == IPADDR_UNSPEC) {
1495       assert(sock_fd == sock_fdu);
1496       allowed = 1;
1497     } else {
1498       switch (permissions[rx_command]) {
1499         case PERMIT_AUTH:
1500           allowed = 0;
1501           break;
1502         case PERMIT_LOCAL:
1503           allowed = localhost;
1504           break;
1505         case PERMIT_OPEN:
1506           allowed = 1;
1507           break;
1508         default:
1509           assert(0);
1510           allowed = 0;
1511       }
1512     }
1513 
1514     if (allowed) {
1515       switch(rx_command) {
1516         case REQ_NULL:
1517           /* Do nothing */
1518           break;
1519 
1520         case REQ_DUMP:
1521           handle_dump(&rx_message, &tx_message);
1522           break;
1523 
1524         case REQ_ONLINE:
1525           handle_online(&rx_message, &tx_message);
1526           break;
1527 
1528         case REQ_OFFLINE:
1529           handle_offline(&rx_message, &tx_message);
1530           break;
1531 
1532         case REQ_BURST:
1533           handle_burst(&rx_message, &tx_message);
1534           break;
1535 
1536         case REQ_MODIFY_MINPOLL:
1537           handle_modify_minpoll(&rx_message, &tx_message);
1538           break;
1539 
1540         case REQ_MODIFY_MAXPOLL:
1541           handle_modify_maxpoll(&rx_message, &tx_message);
1542           break;
1543 
1544         case REQ_MODIFY_MAXDELAY:
1545           handle_modify_maxdelay(&rx_message, &tx_message);
1546           break;
1547 
1548         case REQ_MODIFY_MAXDELAYRATIO:
1549           handle_modify_maxdelayratio(&rx_message, &tx_message);
1550           break;
1551 
1552         case REQ_MODIFY_MAXDELAYDEVRATIO:
1553           handle_modify_maxdelaydevratio(&rx_message, &tx_message);
1554           break;
1555 
1556         case REQ_MODIFY_MAXUPDATESKEW:
1557           handle_modify_maxupdateskew(&rx_message, &tx_message);
1558           break;
1559 
1560         case REQ_MODIFY_MAKESTEP:
1561           handle_modify_makestep(&rx_message, &tx_message);
1562           break;
1563 
1564         case REQ_LOGON:
1565           /* Authentication is no longer supported, log-on always fails */
1566           tx_message.status = htons(STT_FAILED);
1567           break;
1568 
1569         case REQ_SETTIME:
1570           handle_settime(&rx_message, &tx_message);
1571           break;
1572 
1573         case REQ_LOCAL2:
1574           handle_local(&rx_message, &tx_message);
1575           break;
1576 
1577         case REQ_MANUAL:
1578           handle_manual(&rx_message, &tx_message);
1579           break;
1580 
1581         case REQ_N_SOURCES:
1582           handle_n_sources(&rx_message, &tx_message);
1583           break;
1584 
1585         case REQ_SOURCE_DATA:
1586           handle_source_data(&rx_message, &tx_message);
1587           break;
1588 
1589         case REQ_REKEY:
1590           handle_rekey(&rx_message, &tx_message);
1591           break;
1592 
1593         case REQ_ALLOW:
1594           handle_allowdeny(&rx_message, &tx_message, 1, 0);
1595           break;
1596 
1597         case REQ_ALLOWALL:
1598           handle_allowdeny(&rx_message, &tx_message, 1, 1);
1599           break;
1600 
1601         case REQ_DENY:
1602           handle_allowdeny(&rx_message, &tx_message, 0, 0);
1603           break;
1604 
1605         case REQ_DENYALL:
1606           handle_allowdeny(&rx_message, &tx_message, 0, 1);
1607           break;
1608 
1609         case REQ_CMDALLOW:
1610           handle_cmdallowdeny(&rx_message, &tx_message, 1, 0);
1611           break;
1612 
1613         case REQ_CMDALLOWALL:
1614           handle_cmdallowdeny(&rx_message, &tx_message, 1, 1);
1615           break;
1616 
1617         case REQ_CMDDENY:
1618           handle_cmdallowdeny(&rx_message, &tx_message, 0, 0);
1619           break;
1620 
1621         case REQ_CMDDENYALL:
1622           handle_cmdallowdeny(&rx_message, &tx_message, 0, 1);
1623           break;
1624 
1625         case REQ_ACCHECK:
1626           handle_accheck(&rx_message, &tx_message);
1627           break;
1628 
1629         case REQ_CMDACCHECK:
1630           handle_cmdaccheck(&rx_message, &tx_message);
1631           break;
1632 
1633         case REQ_ADD_SOURCE:
1634           handle_add_source(&rx_message, &tx_message);
1635           break;
1636 
1637         case REQ_DEL_SOURCE:
1638           handle_del_source(&rx_message, &tx_message);
1639           break;
1640 
1641         case REQ_WRITERTC:
1642           handle_writertc(&rx_message, &tx_message);
1643           break;
1644 
1645         case REQ_DFREQ:
1646           handle_dfreq(&rx_message, &tx_message);
1647           break;
1648 
1649         case REQ_DOFFSET2:
1650           handle_doffset(&rx_message, &tx_message);
1651           break;
1652 
1653         case REQ_TRACKING:
1654           handle_tracking(&rx_message, &tx_message);
1655           break;
1656 
1657         case REQ_SMOOTHING:
1658           handle_smoothing(&rx_message, &tx_message);
1659           break;
1660 
1661         case REQ_SMOOTHTIME:
1662           handle_smoothtime(&rx_message, &tx_message);
1663           break;
1664 
1665         case REQ_SOURCESTATS:
1666           handle_sourcestats(&rx_message, &tx_message);
1667           break;
1668 
1669         case REQ_RTCREPORT:
1670           handle_rtcreport(&rx_message, &tx_message);
1671           break;
1672 
1673         case REQ_TRIMRTC:
1674           handle_trimrtc(&rx_message, &tx_message);
1675           break;
1676 
1677         case REQ_CYCLELOGS:
1678           handle_cyclelogs(&rx_message, &tx_message);
1679           break;
1680 
1681         case REQ_CLIENT_ACCESSES_BY_INDEX3:
1682           handle_client_accesses_by_index(&rx_message, &tx_message);
1683           break;
1684 
1685         case REQ_MANUAL_LIST:
1686           handle_manual_list(&rx_message, &tx_message);
1687           break;
1688 
1689         case REQ_MANUAL_DELETE:
1690           handle_manual_delete(&rx_message, &tx_message);
1691           break;
1692 
1693         case REQ_MAKESTEP:
1694           handle_make_step(&rx_message, &tx_message);
1695           break;
1696 
1697         case REQ_ACTIVITY:
1698           handle_activity(&rx_message, &tx_message);
1699           break;
1700 
1701         case REQ_RESELECTDISTANCE:
1702           handle_reselect_distance(&rx_message, &tx_message);
1703           break;
1704 
1705         case REQ_RESELECT:
1706           handle_reselect(&rx_message, &tx_message);
1707           break;
1708 
1709         case REQ_MODIFY_MINSTRATUM:
1710           handle_modify_minstratum(&rx_message, &tx_message);
1711           break;
1712 
1713         case REQ_MODIFY_POLLTARGET:
1714           handle_modify_polltarget(&rx_message, &tx_message);
1715           break;
1716 
1717         case REQ_REFRESH:
1718           handle_refresh(&rx_message, &tx_message);
1719           break;
1720 
1721         case REQ_SERVER_STATS:
1722           handle_server_stats(&rx_message, &tx_message);
1723           break;
1724 
1725         case REQ_NTP_DATA:
1726           handle_ntp_data(&rx_message, &tx_message);
1727           break;
1728 
1729         case REQ_SHUTDOWN:
1730           handle_shutdown(&rx_message, &tx_message);
1731           break;
1732 
1733         case REQ_ONOFFLINE:
1734           handle_onoffline(&rx_message, &tx_message);
1735           break;
1736 
1737         case REQ_NTP_SOURCE_NAME:
1738           handle_ntp_source_name(&rx_message, &tx_message);
1739           break;
1740 
1741         case REQ_RESET_SOURCES:
1742           handle_reset_sources(&rx_message, &tx_message);
1743           break;
1744 
1745         case REQ_AUTH_DATA:
1746           handle_auth_data(&rx_message, &tx_message);
1747           break;
1748 
1749         case REQ_SELECT_DATA:
1750           handle_select_data(&rx_message, &tx_message);
1751           break;
1752 
1753         case REQ_RELOAD_SOURCES:
1754           handle_reload_sources(&rx_message, &tx_message);
1755           break;
1756 
1757         default:
1758           DEBUG_LOG("Unhandled command %d", rx_command);
1759           tx_message.status = htons(STT_FAILED);
1760           break;
1761       }
1762     } else {
1763       tx_message.status = htons(STT_UNAUTH);
1764     }
1765   }
1766 
1767   /* Transmit the response */
1768   transmit_reply(sock_fd, read_length, sck_message);
1769 }
1770 
1771 /* ================================================== */
1772 
1773 int
CAM_AddAccessRestriction(IPAddr * ip_addr,int subnet_bits,int allow,int all)1774 CAM_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all)
1775  {
1776   ADF_Status status;
1777 
1778   if (allow) {
1779     if (all) {
1780       status = ADF_AllowAll(access_auth_table, ip_addr, subnet_bits);
1781     } else {
1782       status = ADF_Allow(access_auth_table, ip_addr, subnet_bits);
1783     }
1784   } else {
1785     if (all) {
1786       status = ADF_DenyAll(access_auth_table, ip_addr, subnet_bits);
1787     } else {
1788       status = ADF_Deny(access_auth_table, ip_addr, subnet_bits);
1789     }
1790   }
1791 
1792   if (status == ADF_BADSUBNET) {
1793     return 0;
1794   } else if (status == ADF_SUCCESS) {
1795     return 1;
1796   } else {
1797     return 0;
1798   }
1799 }
1800 
1801 /* ================================================== */
1802 
1803 int
CAM_CheckAccessRestriction(IPAddr * ip_addr)1804 CAM_CheckAccessRestriction(IPAddr *ip_addr)
1805 {
1806   return ADF_IsAllowed(access_auth_table, ip_addr);
1807 }
1808 
1809 
1810 /* ================================================== */
1811 /* ================================================== */
1812