Coverage Report

Created: 2023-05-19 06:16

/src/ntp-dev/ntpd/ntp_control.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * ntp_control.c - respond to mode 6 control messages and send async
3
 *       traps.  Provides service to ntpq and others.
4
 */
5
6
#ifdef HAVE_CONFIG_H
7
# include <config.h>
8
#endif
9
10
#include <stdio.h>
11
#include <ctype.h>
12
#include <signal.h>
13
#include <sys/stat.h>
14
#ifdef HAVE_NETINET_IN_H
15
# include <netinet/in.h>
16
#endif
17
#include <arpa/inet.h>
18
19
#include "ntpd.h"
20
#include "ntp_io.h"
21
#include "ntp_refclock.h"
22
#include "ntp_control.h"
23
#include "ntp_unixtime.h"
24
#include "ntp_stdlib.h"
25
#include "ntp_config.h"
26
#include "ntp_crypto.h"
27
#include "ntp_assert.h"
28
#include "ntp_leapsec.h"
29
#include "ntp_md5.h"  /* provides OpenSSL digest API */
30
#include "lib_strbuf.h"
31
#include <rc_cmdlength.h>
32
#ifdef KERNEL_PLL
33
# include "ntp_syscall.h"
34
#endif
35
36
/*
37
 * Structure to hold request procedure information
38
 */
39
40
struct ctl_proc {
41
  short control_code;   /* defined request code */
42
10.1k
#define NO_REQUEST  (-1)
43
  u_short flags;      /* flags word */
44
  /* Only one flag.  Authentication required or not. */
45
#define NOAUTH  0
46
2.43k
#define AUTH  1
47
  void (*handler) (struct recvbuf *, int); /* handle request */
48
};
49
50
51
/*
52
 * Request processing routines
53
 */
54
static  void  ctl_error (u_char);
55
#ifdef REFCLOCK
56
static  u_short ctlclkstatus  (struct refclockstat *);
57
#endif
58
static  void  ctl_flushpkt  (u_char);
59
static  void  ctl_putdata (const char *, unsigned int, int);
60
static  void  ctl_putstr  (const char *, const char *, size_t);
61
static  void  ctl_putdblf (const char *, int, int, double);
62
183
#define ctl_putdbl(tag, d)  ctl_putdblf(tag, 1, 3, d)
63
70
#define ctl_putdbl6(tag, d) ctl_putdblf(tag, 1, 6, d)
64
0
#define ctl_putsfp(tag, sfp)  ctl_putdblf(tag, 0, -1, \
65
0
              FPTOD(sfp))
66
static  void  ctl_putuint (const char *, u_long);
67
static  void  ctl_puthex  (const char *, u_long);
68
static  void  ctl_putint  (const char *, long);
69
static  void  ctl_putts (const char *, l_fp *);
70
static  void  ctl_putadr  (const char *, u_int32,
71
         sockaddr_u *);
72
static  void  ctl_putrefid  (const char *, u_int32);
73
static  void  ctl_putarray  (const char *, double *, int);
74
static  void  ctl_putsys  (int);
75
static  void  ctl_putpeer (int, struct peer *);
76
static  void  ctl_putfs (const char *, tstamp_t);
77
static  void  ctl_printf  (const char *, ...) NTP_PRINTF(1, 2);
78
#ifdef REFCLOCK
79
static  void  ctl_putclock  (int, struct refclockstat *, int);
80
#endif  /* REFCLOCK */
81
static  const struct ctl_var *ctl_getitem(const struct ctl_var *,
82
            char **);
83
static  u_short count_var (const struct ctl_var *);
84
static  void  control_unspec  (struct recvbuf *, int);
85
static  void  read_status (struct recvbuf *, int);
86
static  void  read_sysvars  (void);
87
static  void  read_peervars (void);
88
static  void  read_variables  (struct recvbuf *, int);
89
static  void  write_variables (struct recvbuf *, int);
90
static  void  read_clockstatus(struct recvbuf *, int);
91
static  void  write_clockstatus(struct recvbuf *, int);
92
static  void  set_trap  (struct recvbuf *, int);
93
static  void  save_config (struct recvbuf *, int);
94
static  void  configure (struct recvbuf *, int);
95
static  void  send_mru_entry  (mon_entry *, int);
96
static  void  send_random_tag_value(int);
97
static  void  read_mru_list (struct recvbuf *, int);
98
static  void  send_ifstats_entry(endpt *, u_int);
99
static  void  read_ifstats  (struct recvbuf *);
100
static  void  sockaddrs_from_restrict_u(sockaddr_u *, sockaddr_u *,
101
            restrict_u *, int);
102
static  void  send_restrict_entry(restrict_u *, int, u_int);
103
static  void  send_restrict_list(restrict_u *, int, u_int *);
104
static  void  read_addr_restrictions(struct recvbuf *);
105
static  void  read_ordlist  (struct recvbuf *, int);
106
static  u_int32 derive_nonce  (sockaddr_u *, u_int32, u_int32);
107
static  void  generate_nonce  (struct recvbuf *, char *, size_t);
108
static  int validate_nonce  (const char *, struct recvbuf *);
109
static  void  req_nonce (struct recvbuf *, int);
110
static  void  unset_trap  (struct recvbuf *, int);
111
static  struct ctl_trap *ctlfindtrap(sockaddr_u *,
112
             struct interface *);
113
114
int/*BOOL*/ is_safe_filename(const char * name);
115
116
static const struct ctl_proc control_codes[] = {
117
  { CTL_OP_UNSPEC,    NOAUTH, control_unspec },
118
  { CTL_OP_READSTAT,    NOAUTH, read_status },
119
  { CTL_OP_READVAR,   NOAUTH, read_variables },
120
  { CTL_OP_WRITEVAR,    AUTH, write_variables },
121
  { CTL_OP_READCLOCK,   NOAUTH, read_clockstatus },
122
  { CTL_OP_WRITECLOCK,    AUTH, write_clockstatus },
123
  { CTL_OP_SETTRAP,   AUTH, set_trap },
124
  { CTL_OP_CONFIGURE,   AUTH, configure },
125
  { CTL_OP_SAVECONFIG,    AUTH, save_config },
126
  { CTL_OP_READ_MRU,    NOAUTH, read_mru_list },
127
  { CTL_OP_READ_ORDLIST_A,  AUTH, read_ordlist },
128
  { CTL_OP_REQ_NONCE,   NOAUTH, req_nonce },
129
  { CTL_OP_UNSETTRAP,   AUTH, unset_trap },
130
  { NO_REQUEST,     0,  NULL }
131
};
132
133
/*
134
 * System variables we understand
135
 */
136
72
#define CS_LEAP     1
137
70
#define CS_STRATUM    2
138
70
#define CS_PRECISION    3
139
35
#define CS_ROOTDELAY    4
140
35
#define CS_ROOTDISPERSION 5
141
35
#define CS_REFID    6
142
70
#define CS_REFTIME    7
143
96
#define CS_POLL     8
144
84
#define CS_PEERID   9
145
35
#define CS_OFFSET   10
146
35
#define CS_DRIFT    11
147
35
#define CS_JITTER   12
148
35
#define CS_ERROR    13
149
86
#define CS_CLOCK    14
150
70
#define CS_PROCESSOR    15
151
84
#define CS_SYSTEM   16
152
70
#define CS_VERSION    17
153
35
#define CS_STABIL   18
154
0
#define CS_VARLIST    19
155
36
#define CS_TAI      20
156
35
#define CS_LEAPTAB    21
157
35
#define CS_LEAPEND    22
158
76
#define CS_RATE     23
159
0
#define CS_MRU_ENABLED    24
160
0
#define CS_MRU_DEPTH    25
161
0
#define CS_MRU_DEEPEST    26
162
0
#define CS_MRU_MINDEPTH   27
163
0
#define CS_MRU_MAXAGE   28
164
0
#define CS_MRU_MAXDEPTH   29
165
0
#define CS_MRU_MEM    30
166
0
#define CS_MRU_MAXMEM   31
167
0
#define CS_SS_UPTIME    32
168
0
#define CS_SS_RESET   33
169
0
#define CS_SS_RECEIVED    34
170
0
#define CS_SS_THISVER   35
171
0
#define CS_SS_OLDVER    36
172
0
#define CS_SS_BADFORMAT   37
173
0
#define CS_SS_BADAUTH   38
174
0
#define CS_SS_DECLINED    39
175
0
#define CS_SS_RESTRICTED  40
176
0
#define CS_SS_LIMITED   41
177
0
#define CS_SS_KODSENT   42
178
0
#define CS_SS_PROCESSED   43
179
0
#define CS_SS_LAMPORT   44
180
0
#define CS_SS_TSROUNDING  45
181
8
#define CS_PEERADR    46
182
0
#define CS_PEERMODE   47
183
0
#define CS_BCASTDELAY   48
184
0
#define CS_AUTHDELAY    49
185
0
#define CS_AUTHKEYS   50
186
0
#define CS_AUTHFREEK    51
187
0
#define CS_AUTHKLOOKUPS   52
188
0
#define CS_AUTHKNOTFOUND  53
189
0
#define CS_AUTHKUNCACHED  54
190
0
#define CS_AUTHKEXPIRED   55
191
0
#define CS_AUTHENCRYPTS   56
192
0
#define CS_AUTHDECRYPTS   57
193
0
#define CS_AUTHRESET    58
194
892
#define CS_K_OFFSET   59
195
0
#define CS_K_FREQ   60
196
0
#define CS_K_MAXERR   61
197
0
#define CS_K_ESTERR   62
198
0
#define CS_K_STFLAGS    63
199
0
#define CS_K_TIMECONST    64
200
0
#define CS_K_PRECISION    65
201
0
#define CS_K_FREQTOL    66
202
0
#define CS_K_PPS_FREQ   67
203
0
#define CS_K_PPS_STABIL   68
204
0
#define CS_K_PPS_JITTER   69
205
0
#define CS_K_PPS_CALIBDUR 70
206
0
#define CS_K_PPS_CALIBS   71
207
0
#define CS_K_PPS_CALIBERRS  72
208
0
#define CS_K_PPS_JITEXC   73
209
970
#define CS_K_PPS_STBEXC   74
210
892
#define CS_KERN_FIRST   CS_K_OFFSET
211
78
#define CS_KERN_LAST    CS_K_PPS_STBEXC
212
0
#define CS_IOSTATS_RESET  75
213
0
#define CS_TOTAL_RBUF   76
214
0
#define CS_FREE_RBUF    77
215
0
#define CS_USED_RBUF    78
216
0
#define CS_RBUF_LOWATER   79
217
0
#define CS_IO_DROPPED   80
218
0
#define CS_IO_IGNORED   81
219
0
#define CS_IO_RECEIVED    82
220
0
#define CS_IO_SENT    83
221
0
#define CS_IO_SENDFAILED  84
222
0
#define CS_IO_WAKEUPS   85
223
0
#define CS_IO_GOODWAKEUPS 86
224
0
#define CS_TIMERSTATS_RESET 87
225
0
#define CS_TIMER_OVERRUNS 88
226
0
#define CS_TIMER_XMTS   89
227
8
#define CS_FUZZ     90
228
0
#define CS_WANDER_THRESH  91
229
#define CS_LEAPSMEARINTV  92
230
2.31k
#define CS_LEAPSMEAROFFS  93
231
2.31k
#define CS_MAX_NOAUTOKEY  CS_LEAPSMEAROFFS
232
#ifdef AUTOKEY
233
#define CS_FLAGS    (1 + CS_MAX_NOAUTOKEY)
234
#define CS_HOST     (2 + CS_MAX_NOAUTOKEY)
235
#define CS_PUBLIC   (3 + CS_MAX_NOAUTOKEY)
236
#define CS_CERTIF   (4 + CS_MAX_NOAUTOKEY)
237
#define CS_SIGNATURE    (5 + CS_MAX_NOAUTOKEY)
238
#define CS_REVTIME    (6 + CS_MAX_NOAUTOKEY)
239
#define CS_IDENT    (7 + CS_MAX_NOAUTOKEY)
240
#define CS_DIGEST   (8 + CS_MAX_NOAUTOKEY)
241
#define CS_MAXCODE    CS_DIGEST
242
#else /* !AUTOKEY follows */
243
2.31k
#define CS_MAXCODE    CS_MAX_NOAUTOKEY
244
#endif  /* !AUTOKEY */
245
246
/*
247
 * Peer variables we understand
248
 */
249
0
#define CP_CONFIG   1
250
0
#define CP_AUTHENABLE   2
251
0
#define CP_AUTHENTIC    3
252
0
#define CP_SRCADR   4
253
0
#define CP_SRCPORT    5
254
0
#define CP_DSTADR   6
255
0
#define CP_DSTPORT    7
256
0
#define CP_LEAP     8
257
0
#define CP_HMODE    9
258
0
#define CP_STRATUM    10
259
0
#define CP_PPOLL    11
260
0
#define CP_HPOLL    12
261
0
#define CP_PRECISION    13
262
0
#define CP_ROOTDELAY    14
263
0
#define CP_ROOTDISPERSION 15
264
0
#define CP_REFID    16
265
0
#define CP_REFTIME    17
266
0
#define CP_ORG      18
267
0
#define CP_REC      19
268
0
#define CP_XMT      20
269
0
#define CP_REACH    21
270
0
#define CP_UNREACH    22
271
0
#define CP_TIMER    23
272
0
#define CP_DELAY    24
273
0
#define CP_OFFSET   25
274
0
#define CP_JITTER   26
275
0
#define CP_DISPERSION   27
276
0
#define CP_KEYID    28
277
0
#define CP_FILTDELAY    29
278
0
#define CP_FILTOFFSET   30
279
0
#define CP_PMODE    31
280
0
#define CP_RECEIVED   32
281
0
#define CP_SENT     33
282
0
#define CP_FILTERROR    34
283
0
#define CP_FLASH    35
284
0
#define CP_TTL      36
285
0
#define CP_VARLIST    37
286
0
#define CP_IN     38
287
0
#define CP_OUT      39
288
0
#define CP_RATE     40
289
0
#define CP_BIAS     41
290
0
#define CP_SRCHOST    42
291
0
#define CP_TIMEREC    43
292
0
#define CP_TIMEREACH    44
293
0
#define CP_BADAUTH    45
294
0
#define CP_BOGUSORG   46
295
0
#define CP_OLDPKT   47
296
0
#define CP_SELDISP    48
297
0
#define CP_SELBROKEN    49
298
0
#define CP_CANDIDATE    50
299
0
#define CP_MAX_NOAUTOKEY  CP_CANDIDATE
300
#ifdef AUTOKEY
301
#define CP_FLAGS    (1 + CP_MAX_NOAUTOKEY)
302
#define CP_HOST     (2 + CP_MAX_NOAUTOKEY)
303
#define CP_VALID    (3 + CP_MAX_NOAUTOKEY)
304
#define CP_INITSEQ    (4 + CP_MAX_NOAUTOKEY)
305
#define CP_INITKEY    (5 + CP_MAX_NOAUTOKEY)
306
#define CP_INITTSP    (6 + CP_MAX_NOAUTOKEY)
307
#define CP_SIGNATURE    (7 + CP_MAX_NOAUTOKEY)
308
#define CP_IDENT    (8 + CP_MAX_NOAUTOKEY)
309
#define CP_MAXCODE    CP_IDENT
310
#else /* !AUTOKEY follows */
311
#define CP_MAXCODE    CP_MAX_NOAUTOKEY
312
#endif  /* !AUTOKEY */
313
314
/*
315
 * Clock variables we understand
316
 */
317
0
#define CC_TYPE   1
318
0
#define CC_TIMECODE 2
319
0
#define CC_POLL   3
320
0
#define CC_NOREPLY  4
321
0
#define CC_BADFORMAT  5
322
0
#define CC_BADDATA  6
323
0
#define CC_FUDGETIME1 7
324
0
#define CC_FUDGETIME2 8
325
0
#define CC_FUDGEVAL1  9
326
0
#define CC_FUDGEVAL2  10
327
0
#define CC_FLAGS  11
328
0
#define CC_DEVICE 12
329
0
#define CC_VARLIST  13
330
0
#define CC_MAXCODE  CC_VARLIST
331
332
/*
333
 * System variable values. The array can be indexed by the variable
334
 * index to find the textual name.
335
 */
336
static const struct ctl_var sys_var[] = {
337
  { 0,    PADDING, "" },    /* 0 */
338
  { CS_LEAP,  RW, "leap" },   /* 1 */
339
  { CS_STRATUM, RO, "stratum" },  /* 2 */
340
  { CS_PRECISION, RO, "precision" },  /* 3 */
341
  { CS_ROOTDELAY, RO, "rootdelay" },  /* 4 */
342
  { CS_ROOTDISPERSION, RO, "rootdisp" },  /* 5 */
343
  { CS_REFID, RO, "refid" },    /* 6 */
344
  { CS_REFTIME, RO, "reftime" },  /* 7 */
345
  { CS_POLL,  RO, "tc" },   /* 8 */
346
  { CS_PEERID,  RO, "peer" },   /* 9 */
347
  { CS_OFFSET,  RO, "offset" },   /* 10 */
348
  { CS_DRIFT, RO, "frequency" },  /* 11 */
349
  { CS_JITTER,  RO, "sys_jitter" }, /* 12 */
350
  { CS_ERROR, RO, "clk_jitter" }, /* 13 */
351
  { CS_CLOCK, RO, "clock" },    /* 14 */
352
  { CS_PROCESSOR, RO, "processor" },  /* 15 */
353
  { CS_SYSTEM,  RO, "system" },   /* 16 */
354
  { CS_VERSION, RO, "version" },  /* 17 */
355
  { CS_STABIL,  RO, "clk_wander" }, /* 18 */
356
  { CS_VARLIST, RO, "sys_var_list" }, /* 19 */
357
  { CS_TAI, RO, "tai" },    /* 20 */
358
  { CS_LEAPTAB, RO, "leapsec" },  /* 21 */
359
  { CS_LEAPEND, RO, "expire" },   /* 22 */
360
  { CS_RATE,  RO, "mintc" },    /* 23 */
361
  { CS_MRU_ENABLED, RO, "mru_enabled" },  /* 24 */
362
  { CS_MRU_DEPTH,   RO, "mru_depth" },  /* 25 */
363
  { CS_MRU_DEEPEST, RO, "mru_deepest" },  /* 26 */
364
  { CS_MRU_MINDEPTH,  RO, "mru_mindepth" }, /* 27 */
365
  { CS_MRU_MAXAGE,  RO, "mru_maxage" }, /* 28 */
366
  { CS_MRU_MAXDEPTH,  RO, "mru_maxdepth" }, /* 29 */
367
  { CS_MRU_MEM,   RO, "mru_mem" },  /* 30 */
368
  { CS_MRU_MAXMEM,  RO, "mru_maxmem" }, /* 31 */
369
  { CS_SS_UPTIME,   RO, "ss_uptime" },  /* 32 */
370
  { CS_SS_RESET,    RO, "ss_reset" }, /* 33 */
371
  { CS_SS_RECEIVED, RO, "ss_received" },  /* 34 */
372
  { CS_SS_THISVER,  RO, "ss_thisver" }, /* 35 */
373
  { CS_SS_OLDVER,   RO, "ss_oldver" },  /* 36 */
374
  { CS_SS_BADFORMAT,  RO, "ss_badformat" }, /* 37 */
375
  { CS_SS_BADAUTH,  RO, "ss_badauth" }, /* 38 */
376
  { CS_SS_DECLINED, RO, "ss_declined" },  /* 39 */
377
  { CS_SS_RESTRICTED, RO, "ss_restricted" },  /* 40 */
378
  { CS_SS_LIMITED,  RO, "ss_limited" }, /* 41 */
379
  { CS_SS_KODSENT,  RO, "ss_kodsent" }, /* 42 */
380
  { CS_SS_PROCESSED,  RO, "ss_processed" }, /* 43 */
381
  { CS_SS_LAMPORT,  RO, "ss_lamport" }, /* 44 */
382
  { CS_SS_TSROUNDING, RO, "ss_tsrounding" },  /* 45 */
383
  { CS_PEERADR,   RO, "peeradr" },  /* 46 */
384
  { CS_PEERMODE,    RO, "peermode" }, /* 47 */
385
  { CS_BCASTDELAY,  RO, "bcastdelay" }, /* 48 */
386
  { CS_AUTHDELAY,   RO, "authdelay" },  /* 49 */
387
  { CS_AUTHKEYS,    RO, "authkeys" }, /* 50 */
388
  { CS_AUTHFREEK,   RO, "authfreek" },  /* 51 */
389
  { CS_AUTHKLOOKUPS,  RO, "authklookups" }, /* 52 */
390
  { CS_AUTHKNOTFOUND, RO, "authknotfound" },  /* 53 */
391
  { CS_AUTHKUNCACHED, RO, "authkuncached" },  /* 54 */
392
  { CS_AUTHKEXPIRED,  RO, "authkexpired" }, /* 55 */
393
  { CS_AUTHENCRYPTS,  RO, "authencrypts" }, /* 56 */
394
  { CS_AUTHDECRYPTS,  RO, "authdecrypts" }, /* 57 */
395
  { CS_AUTHRESET,   RO, "authreset" },  /* 58 */
396
  { CS_K_OFFSET,    RO, "koffset" },  /* 59 */
397
  { CS_K_FREQ,    RO, "kfreq" },    /* 60 */
398
  { CS_K_MAXERR,    RO, "kmaxerr" },  /* 61 */
399
  { CS_K_ESTERR,    RO, "kesterr" },  /* 62 */
400
  { CS_K_STFLAGS,   RO, "kstflags" }, /* 63 */
401
  { CS_K_TIMECONST, RO, "ktimeconst" }, /* 64 */
402
  { CS_K_PRECISION, RO, "kprecis" },  /* 65 */
403
  { CS_K_FREQTOL,   RO, "kfreqtol" }, /* 66 */
404
  { CS_K_PPS_FREQ,  RO, "kppsfreq" }, /* 67 */
405
  { CS_K_PPS_STABIL,  RO, "kppsstab" }, /* 68 */
406
  { CS_K_PPS_JITTER,  RO, "kppsjitter" }, /* 69 */
407
  { CS_K_PPS_CALIBDUR,  RO, "kppscalibdur" }, /* 70 */
408
  { CS_K_PPS_CALIBS,  RO, "kppscalibs" }, /* 71 */
409
  { CS_K_PPS_CALIBERRS, RO, "kppscaliberrs" },  /* 72 */
410
  { CS_K_PPS_JITEXC,  RO, "kppsjitexc" }, /* 73 */
411
  { CS_K_PPS_STBEXC,  RO, "kppsstbexc" }, /* 74 */
412
  { CS_IOSTATS_RESET, RO, "iostats_reset" },  /* 75 */
413
  { CS_TOTAL_RBUF,  RO, "total_rbuf" }, /* 76 */
414
  { CS_FREE_RBUF,   RO, "free_rbuf" },  /* 77 */
415
  { CS_USED_RBUF,   RO, "used_rbuf" },  /* 78 */
416
  { CS_RBUF_LOWATER,  RO, "rbuf_lowater" }, /* 79 */
417
  { CS_IO_DROPPED,  RO, "io_dropped" }, /* 80 */
418
  { CS_IO_IGNORED,  RO, "io_ignored" }, /* 81 */
419
  { CS_IO_RECEIVED, RO, "io_received" },  /* 82 */
420
  { CS_IO_SENT,   RO, "io_sent" },  /* 83 */
421
  { CS_IO_SENDFAILED, RO, "io_sendfailed" },  /* 84 */
422
  { CS_IO_WAKEUPS,  RO, "io_wakeups" }, /* 85 */
423
  { CS_IO_GOODWAKEUPS,  RO, "io_goodwakeups" }, /* 86 */
424
  { CS_TIMERSTATS_RESET,  RO, "timerstats_reset" },/* 87 */
425
  { CS_TIMER_OVERRUNS,  RO, "timer_overruns" }, /* 88 */
426
  { CS_TIMER_XMTS,  RO, "timer_xmts" }, /* 89 */
427
  { CS_FUZZ,    RO, "fuzz" },   /* 90 */
428
  { CS_WANDER_THRESH, RO, "clk_wander_threshold" }, /* 91 */
429
430
  { CS_LEAPSMEARINTV, RO, "leapsmearinterval" },    /* 92 */
431
  { CS_LEAPSMEAROFFS, RO, "leapsmearoffset" },      /* 93 */
432
433
#ifdef AUTOKEY
434
  { CS_FLAGS, RO, "flags" },    /* 1 + CS_MAX_NOAUTOKEY */
435
  { CS_HOST,  RO, "host" },   /* 2 + CS_MAX_NOAUTOKEY */
436
  { CS_PUBLIC,  RO, "update" },   /* 3 + CS_MAX_NOAUTOKEY */
437
  { CS_CERTIF,  RO, "cert" },   /* 4 + CS_MAX_NOAUTOKEY */
438
  { CS_SIGNATURE, RO, "signature" },  /* 5 + CS_MAX_NOAUTOKEY */
439
  { CS_REVTIME, RO, "until" },    /* 6 + CS_MAX_NOAUTOKEY */
440
  { CS_IDENT, RO, "ident" },    /* 7 + CS_MAX_NOAUTOKEY */
441
  { CS_DIGEST,  RO, "digest" },   /* 8 + CS_MAX_NOAUTOKEY */
442
#endif  /* AUTOKEY */
443
  { 0,    EOV, "" }   /* 94/102 */
444
};
445
446
static struct ctl_var *ext_sys_var = NULL;
447
448
/*
449
 * System variables we print by default (in fuzzball order,
450
 * more-or-less)
451
 */
452
static const u_char def_sys_var[] = {
453
  CS_VERSION,
454
  CS_PROCESSOR,
455
  CS_SYSTEM,
456
  CS_LEAP,
457
  CS_STRATUM,
458
  CS_PRECISION,
459
  CS_ROOTDELAY,
460
  CS_ROOTDISPERSION,
461
  CS_REFID,
462
  CS_REFTIME,
463
  CS_CLOCK,
464
  CS_PEERID,
465
  CS_POLL,
466
  CS_RATE,
467
  CS_OFFSET,
468
  CS_DRIFT,
469
  CS_JITTER,
470
  CS_ERROR,
471
  CS_STABIL,
472
  CS_TAI,
473
  CS_LEAPTAB,
474
  CS_LEAPEND,
475
  CS_LEAPSMEARINTV,
476
  CS_LEAPSMEAROFFS,
477
#ifdef AUTOKEY
478
  CS_HOST,
479
  CS_IDENT,
480
  CS_FLAGS,
481
  CS_DIGEST,
482
  CS_SIGNATURE,
483
  CS_PUBLIC,
484
  CS_CERTIF,
485
#endif  /* AUTOKEY */
486
  0
487
};
488
489
490
/*
491
 * Peer variable list
492
 */
493
static const struct ctl_var peer_var[] = {
494
  { 0,    PADDING, "" },    /* 0 */
495
  { CP_CONFIG,  RO, "config" },   /* 1 */
496
  { CP_AUTHENABLE, RO,  "authenable" }, /* 2 */
497
  { CP_AUTHENTIC, RO, "authentic" },  /* 3 */
498
  { CP_SRCADR,  RO, "srcadr" },   /* 4 */
499
  { CP_SRCPORT, RO, "srcport" },  /* 5 */
500
  { CP_DSTADR,  RO, "dstadr" },   /* 6 */
501
  { CP_DSTPORT, RO, "dstport" },  /* 7 */
502
  { CP_LEAP,  RO, "leap" },   /* 8 */
503
  { CP_HMODE, RO, "hmode" },    /* 9 */
504
  { CP_STRATUM, RO, "stratum" },  /* 10 */
505
  { CP_PPOLL, RO, "ppoll" },    /* 11 */
506
  { CP_HPOLL, RO, "hpoll" },    /* 12 */
507
  { CP_PRECISION, RO, "precision" },  /* 13 */
508
  { CP_ROOTDELAY, RO, "rootdelay" },  /* 14 */
509
  { CP_ROOTDISPERSION, RO, "rootdisp" },  /* 15 */
510
  { CP_REFID, RO, "refid" },    /* 16 */
511
  { CP_REFTIME, RO, "reftime" },  /* 17 */
512
  { CP_ORG, RO, "org" },    /* 18 */
513
  { CP_REC, RO, "rec" },    /* 19 */
514
  { CP_XMT, RO, "xleave" },   /* 20 */
515
  { CP_REACH, RO, "reach" },    /* 21 */
516
  { CP_UNREACH, RO, "unreach" },  /* 22 */
517
  { CP_TIMER, RO, "timer" },    /* 23 */
518
  { CP_DELAY, RO, "delay" },    /* 24 */
519
  { CP_OFFSET,  RO, "offset" },   /* 25 */
520
  { CP_JITTER,  RO, "jitter" },   /* 26 */
521
  { CP_DISPERSION, RO, "dispersion" },  /* 27 */
522
  { CP_KEYID, RO, "keyid" },    /* 28 */
523
  { CP_FILTDELAY, RO, "filtdelay" },  /* 29 */
524
  { CP_FILTOFFSET, RO, "filtoffset" },  /* 30 */
525
  { CP_PMODE, RO, "pmode" },    /* 31 */
526
  { CP_RECEIVED,  RO, "received"},  /* 32 */
527
  { CP_SENT,  RO, "sent" },   /* 33 */
528
  { CP_FILTERROR, RO, "filtdisp" }, /* 34 */
529
  { CP_FLASH, RO, "flash" },    /* 35 */
530
  { CP_TTL, RO, "ttl" },    /* 36 */
531
  { CP_VARLIST, RO, "peer_var_list" },  /* 37 */
532
  { CP_IN,  RO, "in" },   /* 38 */
533
  { CP_OUT, RO, "out" },    /* 39 */
534
  { CP_RATE,  RO, "headway" },  /* 40 */
535
  { CP_BIAS,  RO, "bias" },   /* 41 */
536
  { CP_SRCHOST, RO, "srchost" },  /* 42 */
537
  { CP_TIMEREC, RO, "timerec" },  /* 43 */
538
  { CP_TIMEREACH, RO, "timereach" },  /* 44 */
539
  { CP_BADAUTH, RO, "badauth" },  /* 45 */
540
  { CP_BOGUSORG,  RO, "bogusorg" }, /* 46 */
541
  { CP_OLDPKT,  RO, "oldpkt" },   /* 47 */
542
  { CP_SELDISP, RO, "seldisp" },  /* 48 */
543
  { CP_SELBROKEN, RO, "selbroken" },  /* 49 */
544
  { CP_CANDIDATE, RO, "candidate" },  /* 50 */
545
#ifdef AUTOKEY
546
  { CP_FLAGS, RO, "flags" },    /* 1 + CP_MAX_NOAUTOKEY */
547
  { CP_HOST,  RO, "host" },   /* 2 + CP_MAX_NOAUTOKEY */
548
  { CP_VALID, RO, "valid" },    /* 3 + CP_MAX_NOAUTOKEY */
549
  { CP_INITSEQ, RO, "initsequence" }, /* 4 + CP_MAX_NOAUTOKEY */
550
  { CP_INITKEY, RO, "initkey" },  /* 5 + CP_MAX_NOAUTOKEY */
551
  { CP_INITTSP, RO, "timestamp" },  /* 6 + CP_MAX_NOAUTOKEY */
552
  { CP_SIGNATURE, RO, "signature" },  /* 7 + CP_MAX_NOAUTOKEY */
553
  { CP_IDENT, RO, "ident" },    /* 8 + CP_MAX_NOAUTOKEY */
554
#endif  /* AUTOKEY */
555
  { 0,    EOV, "" }   /* 50/58 */
556
};
557
558
559
/*
560
 * Peer variables we print by default
561
 */
562
static const u_char def_peer_var[] = {
563
  CP_SRCADR,
564
  CP_SRCPORT,
565
  CP_SRCHOST,
566
  CP_DSTADR,
567
  CP_DSTPORT,
568
  CP_OUT,
569
  CP_IN,
570
  CP_LEAP,
571
  CP_STRATUM,
572
  CP_PRECISION,
573
  CP_ROOTDELAY,
574
  CP_ROOTDISPERSION,
575
  CP_REFID,
576
  CP_REFTIME,
577
  CP_REC,
578
  CP_REACH,
579
  CP_UNREACH,
580
  CP_HMODE,
581
  CP_PMODE,
582
  CP_HPOLL,
583
  CP_PPOLL,
584
  CP_RATE,
585
  CP_FLASH,
586
  CP_KEYID,
587
  CP_TTL,
588
  CP_OFFSET,
589
  CP_DELAY,
590
  CP_DISPERSION,
591
  CP_JITTER,
592
  CP_XMT,
593
  CP_BIAS,
594
  CP_FILTDELAY,
595
  CP_FILTOFFSET,
596
  CP_FILTERROR,
597
#ifdef AUTOKEY
598
  CP_HOST,
599
  CP_FLAGS,
600
  CP_SIGNATURE,
601
  CP_VALID,
602
  CP_INITSEQ,
603
  CP_IDENT,
604
#endif  /* AUTOKEY */
605
  0
606
};
607
608
609
#ifdef REFCLOCK
610
/*
611
 * Clock variable list
612
 */
613
static const struct ctl_var clock_var[] = {
614
  { 0,    PADDING, "" },    /* 0 */
615
  { CC_TYPE,  RO, "type" },   /* 1 */
616
  { CC_TIMECODE,  RO, "timecode" }, /* 2 */
617
  { CC_POLL,  RO, "poll" },   /* 3 */
618
  { CC_NOREPLY, RO, "noreply" },  /* 4 */
619
  { CC_BADFORMAT, RO, "badformat" },  /* 5 */
620
  { CC_BADDATA, RO, "baddata" },  /* 6 */
621
  { CC_FUDGETIME1, RO, "fudgetime1" },  /* 7 */
622
  { CC_FUDGETIME2, RO, "fudgetime2" },  /* 8 */
623
  { CC_FUDGEVAL1, RO, "stratum" },  /* 9 */
624
  { CC_FUDGEVAL2, RO, "refid" },    /* 10 */
625
  { CC_FLAGS, RO, "flags" },    /* 11 */
626
  { CC_DEVICE,  RO, "device" },   /* 12 */
627
  { CC_VARLIST, RO, "clock_var_list" }, /* 13 */
628
  { 0,    EOV, ""  }    /* 14 */
629
};
630
631
632
/*
633
 * Clock variables printed by default
634
 */
635
static const u_char def_clock_var[] = {
636
  CC_DEVICE,
637
  CC_TYPE,  /* won't be output if device = known */
638
  CC_TIMECODE,
639
  CC_POLL,
640
  CC_NOREPLY,
641
  CC_BADFORMAT,
642
  CC_BADDATA,
643
  CC_FUDGETIME1,
644
  CC_FUDGETIME2,
645
  CC_FUDGEVAL1,
646
  CC_FUDGEVAL2,
647
  CC_FLAGS,
648
  0
649
};
650
#endif
651
652
/*
653
 * MRU string constants shared by send_mru_entry() and read_mru_list().
654
 */
655
static const char addr_fmt[] =    "addr.%d";
656
static const char last_fmt[] =    "last.%d";
657
658
/*
659
 * System and processor definitions.
660
 */
661
#ifndef HAVE_UNAME
662
# ifndef STR_SYSTEM
663
#  define   STR_SYSTEM  "UNIX"
664
# endif
665
# ifndef STR_PROCESSOR
666
#  define   STR_PROCESSOR "unknown"
667
# endif
668
669
static const char str_system[] = STR_SYSTEM;
670
static const char str_processor[] = STR_PROCESSOR;
671
#else
672
# include <sys/utsname.h>
673
static struct utsname utsnamebuf;
674
#endif /* HAVE_UNAME */
675
676
/*
677
 * Trap structures. We only allow a few of these, and send a copy of
678
 * each async message to each live one. Traps time out after an hour, it
679
 * is up to the trap receipient to keep resetting it to avoid being
680
 * timed out.
681
 */
682
/* ntp_request.c */
683
struct ctl_trap ctl_traps[CTL_MAXTRAPS];
684
int num_ctl_traps;
685
686
/*
687
 * Type bits, for ctlsettrap() call.
688
 */
689
0
#define TRAP_TYPE_CONFIG  0  /* used by configuration code */
690
0
#define TRAP_TYPE_PRIO    1  /* priority trap */
691
0
#define TRAP_TYPE_NONPRIO 2  /* nonpriority trap */
692
693
694
/*
695
 * List relating reference clock types to control message time sources.
696
 * Index by the reference clock type. This list will only be used iff
697
 * the reference clock driver doesn't set peer->sstclktype to something
698
 * different than CTL_SST_TS_UNSPEC.
699
 */
700
#ifdef REFCLOCK
701
static const u_char clocktypes[] = {
702
  CTL_SST_TS_NTP,   /* REFCLK_NONE (0) */
703
  CTL_SST_TS_LOCAL, /* REFCLK_LOCALCLOCK (1) */
704
  CTL_SST_TS_UHF,   /* deprecated REFCLK_GPS_TRAK (2) */
705
  CTL_SST_TS_HF,    /* REFCLK_WWV_PST (3) */
706
  CTL_SST_TS_LF,    /* REFCLK_WWVB_SPECTRACOM (4) */
707
  CTL_SST_TS_UHF,   /* REFCLK_TRUETIME (5) */
708
  CTL_SST_TS_UHF,   /* REFCLK_IRIG_AUDIO (6) */
709
  CTL_SST_TS_HF,    /* REFCLK_CHU (7) */
710
  CTL_SST_TS_LF,    /* REFCLOCK_PARSE (default) (8) */
711
  CTL_SST_TS_LF,    /* REFCLK_GPS_MX4200 (9) */
712
  CTL_SST_TS_UHF,   /* REFCLK_GPS_AS2201 (10) */
713
  CTL_SST_TS_UHF,   /* REFCLK_GPS_ARBITER (11) */
714
  CTL_SST_TS_UHF,   /* REFCLK_IRIG_TPRO (12) */
715
  CTL_SST_TS_ATOM,  /* REFCLK_ATOM_LEITCH (13) */
716
  CTL_SST_TS_LF,    /* deprecated REFCLK_MSF_EES (14) */
717
  CTL_SST_TS_NTP,   /* not used (15) */
718
  CTL_SST_TS_UHF,   /* REFCLK_IRIG_BANCOMM (16) */
719
  CTL_SST_TS_UHF,   /* REFCLK_GPS_DATU (17) */
720
  CTL_SST_TS_TELEPHONE, /* REFCLK_NIST_ACTS (18) */
721
  CTL_SST_TS_HF,    /* REFCLK_WWV_HEATH (19) */
722
  CTL_SST_TS_UHF,   /* REFCLK_GPS_NMEA (20) */
723
  CTL_SST_TS_UHF,   /* REFCLK_GPS_VME (21) */
724
  CTL_SST_TS_ATOM,  /* REFCLK_ATOM_PPS (22) */
725
  CTL_SST_TS_NTP,   /* not used (23) */
726
  CTL_SST_TS_NTP,   /* not used (24) */
727
  CTL_SST_TS_NTP,   /* not used (25) */
728
  CTL_SST_TS_UHF,   /* REFCLK_GPS_HP (26) */
729
  CTL_SST_TS_LF,    /* REFCLK_ARCRON_MSF (27) */
730
  CTL_SST_TS_UHF,   /* REFCLK_SHM (28) */
731
  CTL_SST_TS_UHF,   /* REFCLK_PALISADE (29) */
732
  CTL_SST_TS_UHF,   /* REFCLK_ONCORE (30) */
733
  CTL_SST_TS_UHF,   /* REFCLK_JUPITER (31) */
734
  CTL_SST_TS_LF,    /* REFCLK_CHRONOLOG (32) */
735
  CTL_SST_TS_LF,    /* REFCLK_DUMBCLOCK (33) */
736
  CTL_SST_TS_LF,    /* REFCLK_ULINK (34) */
737
  CTL_SST_TS_LF,    /* REFCLK_PCF (35) */
738
  CTL_SST_TS_HF,    /* REFCLK_WWV (36) */
739
  CTL_SST_TS_LF,    /* REFCLK_FG (37) */
740
  CTL_SST_TS_UHF,   /* REFCLK_HOPF_SERIAL (38) */
741
  CTL_SST_TS_UHF,   /* REFCLK_HOPF_PCI (39) */
742
  CTL_SST_TS_LF,    /* REFCLK_JJY (40) */
743
  CTL_SST_TS_UHF,   /* REFCLK_TT560 (41) */
744
  CTL_SST_TS_UHF,   /* REFCLK_ZYFER (42) */
745
  CTL_SST_TS_UHF,   /* REFCLK_RIPENCC (43) */
746
  CTL_SST_TS_UHF,   /* REFCLK_NEOCLOCK4X (44) */
747
  CTL_SST_TS_UHF,   /* REFCLK_TSYNCPCI (45) */
748
  CTL_SST_TS_UHF    /* REFCLK_GPSDJSON (46) */
749
};
750
#endif  /* REFCLOCK */
751
752
753
/*
754
 * Keyid used for authenticating write requests.
755
 */
756
keyid_t ctl_auth_keyid;
757
758
/*
759
 * We keep track of the last error reported by the system internally
760
 */
761
static  u_char ctl_sys_last_event;
762
static  u_char ctl_sys_num_events;
763
764
765
/*
766
 * Statistic counters to keep track of requests and responses.
767
 */
768
u_long ctltimereset;    /* time stats reset */
769
u_long numctlreq;   /* number of requests we've received */
770
u_long numctlbadpkts;   /* number of bad control packets */
771
u_long numctlresponses;   /* number of resp packets sent with data */
772
u_long numctlfrags;   /* number of fragments sent */
773
u_long numctlerrors;    /* number of error responses sent */
774
u_long numctltooshort;    /* number of too short input packets */
775
u_long numctlinputresp;   /* number of responses on input */
776
u_long numctlinputfrag;   /* number of fragments on input */
777
u_long numctlinputerr;    /* number of input pkts with err bit set */
778
u_long numctlbadoffset;   /* number of input pkts with nonzero offset */
779
u_long numctlbadversion;  /* number of input pkts with unknown version */
780
u_long numctldatatooshort;  /* data too short for count */
781
u_long numctlbadop;   /* bad op code found in packet */
782
u_long numasyncmsgs;    /* number of async messages we've sent */
783
784
/*
785
 * Response packet used by these routines. Also some state information
786
 * so that we can handle packet formatting within a common set of
787
 * subroutines.  Note we try to enter data in place whenever possible,
788
 * but the need to set the more bit correctly means we occasionally
789
 * use the extra buffer and copy.
790
 */
791
static struct ntp_control rpkt;
792
static u_char res_version;
793
static u_char res_opcode;
794
static associd_t res_associd;
795
static u_short  res_frags;  /* datagrams in this response */
796
static int  res_offset; /* offset of payload in response */
797
static u_char * datapt;
798
static u_char * dataend;
799
static int  datalinelen;
800
static int  datasent; /* flag to avoid initial ", " */
801
static int  datanotbinflag;
802
static sockaddr_u *rmt_addr;
803
static struct interface *lcl_inter;
804
805
static u_char res_authenticate;
806
static u_char res_authokay;
807
static keyid_t  res_keyid;
808
809
659
#define MAXDATALINELEN  (72)
810
811
static u_char res_async;  /* sending async trap response? */
812
813
/*
814
 * Pointers for saving state when decoding request packets
815
 */
816
static  char *reqpt;
817
static  char *reqend;
818
819
#ifndef MIN
820
#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
821
#endif
822
823
/*
824
 * init_control - initialize request data
825
 */
826
void
827
init_control(void)
828
1
{
829
1
  size_t i;
830
831
1
#ifdef HAVE_UNAME
832
1
  uname(&utsnamebuf);
833
1
#endif /* HAVE_UNAME */
834
835
1
  ctl_clr_stats();
836
837
1
  ctl_auth_keyid = 0;
838
1
  ctl_sys_last_event = EVNT_UNSPEC;
839
1
  ctl_sys_num_events = 0;
840
841
1
  num_ctl_traps = 0;
842
4
  for (i = 0; i < COUNTOF(ctl_traps); i++)
843
3
    ctl_traps[i].tr_flags = 0;
844
1
}
845
846
847
/*
848
 * ctl_error - send an error response for the current request
849
 */
850
static void
851
ctl_error(
852
  u_char errcode
853
  )
854
309
{
855
309
  size_t    maclen;
856
857
309
  numctlerrors++;
858
309
  DPRINTF(3, ("sending control error %u\n", errcode));
859
860
  /*
861
   * Fill in the fields. We assume rpkt.sequence and rpkt.associd
862
   * have already been filled in.
863
   */
864
309
  rpkt.r_m_e_op = (u_char)CTL_RESPONSE | CTL_ERROR |
865
309
      (res_opcode & CTL_OP_MASK);
866
309
  rpkt.status = htons((u_short)(errcode << 8) & 0xff00);
867
309
  rpkt.count = 0;
868
869
  /*
870
   * send packet and bump counters
871
   */
872
309
  if (res_authenticate && sys_authenticate) {
873
51
    maclen = authencrypt(res_keyid, (u_int32 *)&rpkt,
874
51
             CTL_HEADER_LEN);
875
51
    sendpkt(rmt_addr, lcl_inter, -2, (void *)&rpkt,
876
51
      CTL_HEADER_LEN + maclen);
877
51
  } else
878
258
    sendpkt(rmt_addr, lcl_inter, -3, (void *)&rpkt,
879
258
      CTL_HEADER_LEN);
880
309
}
881
882
int/*BOOL*/
883
is_safe_filename(const char * name)
884
0
{
885
  /* We need a strict validation of filenames we should write: The
886
   * daemon might run with special permissions and is remote
887
   * controllable, so we better take care what we allow as file
888
   * name!
889
   *
890
   * The first character must be digit or a letter from the ASCII
891
   * base plane or a '_' ([_A-Za-z0-9]), the following characters
892
   * must be from [-._+A-Za-z0-9].
893
   *
894
   * We do not trust the character classification much here: Since
895
   * the NTP protocol makes no provisions for UTF-8 or local code
896
   * pages, we strictly require the 7bit ASCII code page.
897
   *
898
   * The following table is a packed bit field of 128 two-bit
899
   * groups. The LSB in each group tells us if a character is
900
   * acceptable at the first position, the MSB if the character is
901
   * accepted at any other position.
902
   *
903
   * This does not ensure that the file name is syntactically
904
   * correct (multiple dots will not work with VMS...) but it will
905
   * exclude potential globbing bombs and directory traversal. It
906
   * also rules out drive selection. (For systems that have this
907
   * notion, like Windows or VMS.)
908
   */
909
0
  static const uint32_t chclass[8] = {
910
0
    0x00000000, 0x00000000,
911
0
    0x28800000, 0x000FFFFF,
912
0
    0xFFFFFFFC, 0xC03FFFFF,
913
0
    0xFFFFFFFC, 0x003FFFFF
914
0
  };
915
916
0
  u_int widx, bidx, mask;
917
0
  if ( ! (name && *name))
918
0
    return FALSE;
919
920
0
  mask = 1u;
921
0
  while (0 != (widx = (u_char)*name++)) {
922
0
    bidx = (widx & 15) << 1;
923
0
    widx = widx >> 4;
924
0
    if (widx >= sizeof(chclass)/sizeof(chclass[0]))
925
0
      return FALSE;
926
0
    if (0 == ((chclass[widx] >> bidx) & mask))
927
0
      return FALSE;
928
0
    mask = 2u;
929
0
  }
930
0
  return TRUE;
931
0
}
932
933
934
/*
935
 * save_config - Implements ntpq -c "saveconfig <filename>"
936
 *     Writes current configuration including any runtime
937
 *     changes by ntpq's :config or config-from-file
938
 *
939
 * Note: There should be no buffer overflow or truncation in the
940
 * processing of file names -- both cause security problems. This is bit
941
 * painful to code but essential here.
942
 */
943
void
944
save_config(
945
  struct recvbuf *rbufp,
946
  int restrict_mask
947
  )
948
0
{
949
  /* block directory traversal by searching for characters that
950
   * indicate directory components in a file path.
951
   *
952
   * Conceptually we should be searching for DIRSEP in filename,
953
   * however Windows actually recognizes both forward and
954
   * backslashes as equivalent directory separators at the API
955
   * level.  On POSIX systems we could allow '\\' but such
956
   * filenames are tricky to manipulate from a shell, so just
957
   * reject both types of slashes on all platforms.
958
   */
959
  /* TALOS-CAN-0062: block directory traversal for VMS, too */
960
0
  static const char * illegal_in_filename =
961
#if defined(VMS)
962
      ":[]" /* do not allow drive and path components here */
963
#elif defined(SYS_WINNT)
964
      ":\\/"  /* path and drive separators */
965
#else
966
0
      "\\/" /* separator and critical char for POSIX */
967
0
#endif
968
0
      ;
969
0
  char reply[128];
970
0
#ifdef SAVECONFIG
971
0
  static const char savedconfig_eq[] = "savedconfig=";
972
973
  /* Build a safe open mode from the available mode flags. We want
974
   * to create a new file and write it in text mode (when
975
   * applicable -- only Windows does this...)
976
   */
977
0
  static const int openmode = O_CREAT | O_TRUNC | O_WRONLY
978
0
#  if defined(O_EXCL)   /* posix, vms */
979
0
      | O_EXCL
980
#  elif defined(_O_EXCL)  /* windows is alway very special... */
981
      | _O_EXCL
982
#  endif
983
#  if defined(_O_TEXT)    /* windows, again */
984
      | _O_TEXT
985
#endif
986
0
      ;
987
988
0
  char filespec[128];
989
0
  char filename[128];
990
0
  char fullpath[512];
991
0
  char savedconfig[sizeof(savedconfig_eq) + sizeof(filename)];
992
0
  time_t now;
993
0
  int fd;
994
0
  FILE *fptr;
995
0
  int prc;
996
0
  size_t reqlen;
997
0
#endif
998
999
0
  if (RES_NOMODIFY & restrict_mask) {
1000
0
    ctl_printf("%s", "saveconfig prohibited by restrict ... nomodify");
1001
0
    ctl_flushpkt(0);
1002
0
    NLOG(NLOG_SYSINFO)
1003
0
      msyslog(LOG_NOTICE,
1004
0
        "saveconfig from %s rejected due to nomodify restriction",
1005
0
        stoa(&rbufp->recv_srcadr));
1006
0
    sys_restricted++;
1007
0
    return;
1008
0
  }
1009
1010
0
#ifdef SAVECONFIG
1011
0
  if (NULL == saveconfigdir) {
1012
0
    ctl_printf("%s", "saveconfig prohibited, no saveconfigdir configured");
1013
0
    ctl_flushpkt(0);
1014
0
    NLOG(NLOG_SYSINFO)
1015
0
      msyslog(LOG_NOTICE,
1016
0
        "saveconfig from %s rejected, no saveconfigdir",
1017
0
        stoa(&rbufp->recv_srcadr));
1018
0
    return;
1019
0
  }
1020
1021
  /* The length checking stuff gets serious. Do not assume a NUL
1022
   * byte can be found, but if so, use it to calculate the needed
1023
   * buffer size. If the available buffer is too short, bail out;
1024
   * likewise if there is no file spec. (The latter will not
1025
   * happen when using NTPQ, but there are other ways to craft a
1026
   * network packet!)
1027
   */
1028
0
  reqlen = (size_t)(reqend - reqpt);
1029
0
  if (0 != reqlen) {
1030
0
    char * nulpos = (char*)memchr(reqpt, 0, reqlen);
1031
0
    if (NULL != nulpos)
1032
0
      reqlen = (size_t)(nulpos - reqpt);
1033
0
  }
1034
0
  if (0 == reqlen)
1035
0
    return;
1036
0
  if (reqlen >= sizeof(filespec)) {
1037
0
    ctl_printf("saveconfig exceeded maximum raw name length (%u)",
1038
0
         (u_int)sizeof(filespec));
1039
0
    ctl_flushpkt(0);
1040
0
    msyslog(LOG_NOTICE,
1041
0
      "saveconfig exceeded maximum raw name length from %s",
1042
0
      stoa(&rbufp->recv_srcadr));
1043
0
    return;
1044
0
  }
1045
1046
  /* copy data directly as we exactly know the size */
1047
0
  memcpy(filespec, reqpt, reqlen);
1048
0
  filespec[reqlen] = '\0';
1049
1050
  /*
1051
   * allow timestamping of the saved config filename with
1052
   * strftime() format such as:
1053
   *   ntpq -c "saveconfig ntp-%Y%m%d-%H%M%S.conf"
1054
   * XXX: Nice feature, but not too safe.
1055
   * YYY: The check for permitted characters in file names should
1056
   *      weed out the worst. Let's hope 'strftime()' does not
1057
   *      develop pathological problems.
1058
   */
1059
0
  time(&now);
1060
0
  if (0 == strftime(filename, sizeof(filename), filespec,
1061
0
        localtime(&now)))
1062
0
  {
1063
    /*
1064
     * If we arrive here, 'strftime()' balked; most likely
1065
     * the buffer was too short. (Or it encounterd an empty
1066
     * format, or just a format that expands to an empty
1067
     * string.) We try to use the original name, though this
1068
     * is very likely to fail later if there are format
1069
     * specs in the string. Note that truncation cannot
1070
     * happen here as long as both buffers have the same
1071
     * size!
1072
     */
1073
0
    strlcpy(filename, filespec, sizeof(filename));
1074
0
  }
1075
1076
  /*
1077
   * Check the file name for sanity. This might/will rule out file
1078
   * names that would be legal but problematic, and it blocks
1079
   * directory traversal.
1080
   */
1081
0
  if (!is_safe_filename(filename)) {
1082
0
    ctl_printf("saveconfig rejects unsafe file name '%s'",
1083
0
         filename);
1084
0
    ctl_flushpkt(0);
1085
0
    msyslog(LOG_NOTICE,
1086
0
      "saveconfig rejects unsafe file name from %s",
1087
0
      stoa(&rbufp->recv_srcadr));
1088
0
    return;
1089
0
  }
1090
1091
  /*
1092
   * XXX: This next test may not be needed with is_safe_filename()
1093
   */
1094
1095
  /* block directory/drive traversal */
1096
  /* TALOS-CAN-0062: block directory traversal for VMS, too */
1097
0
  if (NULL != strpbrk(filename, illegal_in_filename)) {
1098
0
    snprintf(reply, sizeof(reply),
1099
0
       "saveconfig does not allow directory in filename");
1100
0
    ctl_putdata(reply, strlen(reply), 0);
1101
0
    ctl_flushpkt(0);
1102
0
    msyslog(LOG_NOTICE,
1103
0
      "saveconfig rejects unsafe file name from %s",
1104
0
      stoa(&rbufp->recv_srcadr));
1105
0
    return;
1106
0
  }
1107
1108
  /* concatenation of directory and path can cause another
1109
   * truncation...
1110
   */
1111
0
  prc = snprintf(fullpath, sizeof(fullpath), "%s%s",
1112
0
           saveconfigdir, filename);
1113
0
  if (prc < 0 || (size_t)prc >= sizeof(fullpath)) {
1114
0
    ctl_printf("saveconfig exceeded maximum path length (%u)",
1115
0
         (u_int)sizeof(fullpath));
1116
0
    ctl_flushpkt(0);
1117
0
    msyslog(LOG_NOTICE,
1118
0
      "saveconfig exceeded maximum path length from %s",
1119
0
      stoa(&rbufp->recv_srcadr));
1120
0
    return;
1121
0
  }
1122
1123
0
  fd = open(fullpath, openmode, S_IRUSR | S_IWUSR);
1124
0
  if (-1 == fd)
1125
0
    fptr = NULL;
1126
0
  else
1127
0
    fptr = fdopen(fd, "w");
1128
1129
0
  if (NULL == fptr || -1 == dump_all_config_trees(fptr, 1)) {
1130
0
    ctl_printf("Unable to save configuration to file '%s': %s",
1131
0
         filename, strerror(errno));
1132
0
    msyslog(LOG_ERR,
1133
0
      "saveconfig %s from %s failed", filename,
1134
0
      stoa(&rbufp->recv_srcadr));
1135
0
  } else {
1136
0
    ctl_printf("Configuration saved to '%s'", filename);
1137
0
    msyslog(LOG_NOTICE,
1138
0
      "Configuration saved to '%s' (requested by %s)",
1139
0
      fullpath, stoa(&rbufp->recv_srcadr));
1140
    /*
1141
     * save the output filename in system variable
1142
     * savedconfig, retrieved with:
1143
     *   ntpq -c "rv 0 savedconfig"
1144
     * Note: the way 'savedconfig' is defined makes overflow
1145
     * checks unnecessary here.
1146
     */
1147
0
    snprintf(savedconfig, sizeof(savedconfig), "%s%s",
1148
0
       savedconfig_eq, filename);
1149
0
    set_sys_var(savedconfig, strlen(savedconfig) + 1, RO);
1150
0
  }
1151
1152
0
  if (NULL != fptr)
1153
0
    fclose(fptr);
1154
#else /* !SAVECONFIG follows */
1155
  ctl_printf("%s",
1156
       "saveconfig unavailable, configured with --disable-saveconfig");
1157
#endif
1158
0
  ctl_flushpkt(0);
1159
0
}
1160
1161
1162
/*
1163
 * process_control - process an incoming control message
1164
 */
1165
void
1166
process_control(
1167
  struct recvbuf *rbufp,
1168
  int restrict_mask
1169
  )
1170
1.34k
{
1171
1.34k
  struct ntp_control *pkt;
1172
1.34k
  int req_count;
1173
1.34k
  int req_data;
1174
1.34k
  const struct ctl_proc *cc;
1175
1.34k
  keyid_t *pkid;
1176
1.34k
  int properlen;
1177
1.34k
  size_t maclen;
1178
1179
1.34k
  DPRINTF(3, ("in process_control()\n"));
1180
1181
  /*
1182
   * Save the addresses for error responses
1183
   */
1184
1.34k
  numctlreq++;
1185
1.34k
  rmt_addr = &rbufp->recv_srcadr;
1186
1.34k
  lcl_inter = rbufp->dstadr;
1187
1.34k
  pkt = (struct ntp_control *)&rbufp->recv_pkt;
1188
1189
  /*
1190
   * If the length is less than required for the header, or
1191
   * it is a response or a fragment, ignore this.
1192
   */
1193
1.34k
  if (rbufp->recv_length < (int)CTL_HEADER_LEN
1194
1.34k
      || (CTL_RESPONSE | CTL_MORE | CTL_ERROR) & pkt->r_m_e_op
1195
1.34k
      || pkt->offset != 0) {
1196
61
    DPRINTF(1, ("invalid format in control packet\n"));
1197
61
    if (rbufp->recv_length < (int)CTL_HEADER_LEN)
1198
32
      numctltooshort++;
1199
61
    if (CTL_RESPONSE & pkt->r_m_e_op)
1200
19
      numctlinputresp++;
1201
61
    if (CTL_MORE & pkt->r_m_e_op)
1202
21
      numctlinputfrag++;
1203
61
    if (CTL_ERROR & pkt->r_m_e_op)
1204
23
      numctlinputerr++;
1205
61
    if (pkt->offset != 0)
1206
43
      numctlbadoffset++;
1207
61
    return;
1208
61
  }
1209
1.28k
  res_version = PKT_VERSION(pkt->li_vn_mode);
1210
1.28k
  if (res_version > NTP_VERSION || res_version < NTP_OLDVERSION) {
1211
2
    DPRINTF(1, ("unknown version %d in control packet\n",
1212
2
          res_version));
1213
2
    numctlbadversion++;
1214
2
    return;
1215
2
  }
1216
1217
  /*
1218
   * Pull enough data from the packet to make intelligent
1219
   * responses
1220
   */
1221
1.28k
  rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version,
1222
1.28k
           MODE_CONTROL);
1223
1.28k
  res_opcode = pkt->r_m_e_op;
1224
1.28k
  rpkt.sequence = pkt->sequence;
1225
1.28k
  rpkt.associd = pkt->associd;
1226
1.28k
  rpkt.status = 0;
1227
1.28k
  res_frags = 1;
1228
1.28k
  res_offset = 0;
1229
1.28k
  res_associd = htons(pkt->associd);
1230
1.28k
  res_async = FALSE;
1231
1.28k
  res_authenticate = FALSE;
1232
1.28k
  res_keyid = 0;
1233
1.28k
  res_authokay = FALSE;
1234
1.28k
  req_count = (int)ntohs(pkt->count);
1235
1.28k
  datanotbinflag = FALSE;
1236
1.28k
  datalinelen = 0;
1237
1.28k
  datasent = 0;
1238
1.28k
  datapt = rpkt.u.data;
1239
1.28k
  dataend = &rpkt.u.data[CTL_MAX_DATA_LEN];
1240
1241
1.28k
  if ((rbufp->recv_length & 0x3) != 0)
1242
32
    DPRINTF(3, ("Control packet length %d unrounded\n",
1243
1.28k
          rbufp->recv_length));
1244
1245
  /*
1246
   * We're set up now. Make sure we've got at least enough
1247
   * incoming data space to match the count.
1248
   */
1249
1.28k
  req_data = rbufp->recv_length - CTL_HEADER_LEN;
1250
1.28k
  if (req_data < req_count || rbufp->recv_length & 0x3) {
1251
59
    ctl_error(CERR_BADFMT);
1252
59
    numctldatatooshort++;
1253
59
    return;
1254
59
  }
1255
1256
1.22k
  properlen = req_count + CTL_HEADER_LEN;
1257
  /* round up proper len to a 8 octet boundary */
1258
1259
1.22k
  properlen = (properlen + 7) & ~7;
1260
1.22k
  maclen = rbufp->recv_length - properlen;
1261
1.22k
  if ((rbufp->recv_length & 3) == 0 &&
1262
1.22k
      maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN &&
1263
1.22k
      sys_authenticate) {
1264
137
    res_authenticate = TRUE;
1265
137
    pkid = (void *)((char *)pkt + properlen);
1266
137
    res_keyid = ntohl(*pkid);
1267
137
    DPRINTF(3, ("recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%zu\n",
1268
137
          rbufp->recv_length, properlen, res_keyid,
1269
137
          maclen));
1270
1271
137
    if (!authistrustedip(res_keyid, &rbufp->recv_srcadr))
1272
137
      DPRINTF(3, ("invalid keyid %08x\n", res_keyid));
1273
0
    else if (authdecrypt(res_keyid, (u_int32 *)pkt,
1274
0
             rbufp->recv_length - maclen,
1275
0
             maclen)) {
1276
0
      res_authokay = TRUE;
1277
0
      DPRINTF(3, ("authenticated okay\n"));
1278
0
    } else {
1279
0
      res_keyid = 0;
1280
0
      DPRINTF(3, ("authentication failed\n"));
1281
0
    }
1282
137
  }
1283
1284
  /*
1285
   * Set up translate pointers
1286
   */
1287
1.22k
  reqpt = (char *)pkt->u.data;
1288
1.22k
  reqend = reqpt + req_count;
1289
1290
  /*
1291
   * Look for the opcode processor
1292
   */
1293
10.1k
  for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) {
1294
10.1k
    if (cc->control_code == res_opcode) {
1295
1.21k
      DPRINTF(3, ("opcode %d, found command handler\n",
1296
1.21k
            res_opcode));
1297
1.21k
      if (cc->flags == AUTH
1298
1.21k
          && (!res_authokay
1299
9
        || res_keyid != ctl_auth_keyid)) {
1300
9
        ctl_error(CERR_PERMISSION);
1301
9
        return;
1302
9
      }
1303
1.20k
      (cc->handler)(rbufp, restrict_mask);
1304
1.20k
      return;
1305
1.21k
    }
1306
10.1k
  }
1307
1308
  /*
1309
   * Can't find this one, return an error.
1310
   */
1311
8
  numctlbadop++;
1312
8
  ctl_error(CERR_BADOP);
1313
8
  return;
1314
1.22k
}
1315
1316
1317
/*
1318
 * ctlpeerstatus - return a status word for this peer
1319
 */
1320
u_short
1321
ctlpeerstatus(
1322
  register struct peer *p
1323
  )
1324
0
{
1325
0
  u_short status;
1326
1327
0
  status = p->status;
1328
0
  if (FLAG_CONFIG & p->flags)
1329
0
    status |= CTL_PST_CONFIG;
1330
0
  if (p->keyid)
1331
0
    status |= CTL_PST_AUTHENABLE;
1332
0
  if (FLAG_AUTHENTIC & p->flags)
1333
0
    status |= CTL_PST_AUTHENTIC;
1334
0
  if (p->reach)
1335
0
    status |= CTL_PST_REACH;
1336
0
  if (MDF_TXONLY_MASK & p->cast_flags)
1337
0
    status |= CTL_PST_BCAST;
1338
1339
0
  return CTL_PEER_STATUS(status, p->num_events, p->last_event);
1340
0
}
1341
1342
1343
/*
1344
 * ctlclkstatus - return a status word for this clock
1345
 */
1346
#ifdef REFCLOCK
1347
static u_short
1348
ctlclkstatus(
1349
  struct refclockstat *pcs
1350
  )
1351
0
{
1352
0
  return CTL_PEER_STATUS(0, pcs->lastevent, pcs->currentstatus);
1353
0
}
1354
#endif
1355
1356
1357
/*
1358
 * ctlsysstatus - return the system status word
1359
 */
1360
u_short
1361
ctlsysstatus(void)
1362
161
{
1363
161
  register u_char this_clock;
1364
1365
161
  this_clock = CTL_SST_TS_UNSPEC;
1366
161
#ifdef REFCLOCK
1367
161
  if (sys_peer != NULL) {
1368
0
    if (CTL_SST_TS_UNSPEC != sys_peer->sstclktype)
1369
0
      this_clock = sys_peer->sstclktype;
1370
0
    else if (sys_peer->refclktype < COUNTOF(clocktypes))
1371
0
      this_clock = clocktypes[sys_peer->refclktype];
1372
0
  }
1373
#else /* REFCLOCK */
1374
  if (sys_peer != 0)
1375
    this_clock = CTL_SST_TS_NTP;
1376
#endif /* REFCLOCK */
1377
161
  return CTL_SYS_STATUS(sys_leap, this_clock, ctl_sys_num_events,
1378
161
            ctl_sys_last_event);
1379
161
}
1380
1381
1382
/*
1383
 * ctl_flushpkt - write out the current packet and prepare
1384
 *      another if necessary.
1385
 */
1386
static void
1387
ctl_flushpkt(
1388
  u_char more
1389
  )
1390
109
{
1391
109
  size_t i;
1392
109
  size_t dlen;
1393
109
  size_t sendlen;
1394
109
  size_t maclen;
1395
109
  size_t totlen;
1396
109
  keyid_t keyid;
1397
1398
109
  dlen = datapt - rpkt.u.data;
1399
109
  if (!more && datanotbinflag && dlen + 2 < CTL_MAX_DATA_LEN) {
1400
    /*
1401
     * Big hack, output a trailing \r\n
1402
     */
1403
94
    *datapt++ = '\r';
1404
94
    *datapt++ = '\n';
1405
94
    dlen += 2;
1406
94
  }
1407
109
  sendlen = dlen + CTL_HEADER_LEN;
1408
1409
  /*
1410
   * Pad to a multiple of 32 bits
1411
   */
1412
138
  while (sendlen & 0x3) {
1413
29
    *datapt++ = '\0';
1414
29
    sendlen++;
1415
29
  }
1416
1417
  /*
1418
   * Fill in the packet with the current info
1419
   */
1420
109
  rpkt.r_m_e_op = CTL_RESPONSE | more |
1421
109
      (res_opcode & CTL_OP_MASK);
1422
109
  rpkt.count = htons((u_short)dlen);
1423
109
  rpkt.offset = htons((u_short)res_offset);
1424
109
  if (res_async) {
1425
0
    for (i = 0; i < COUNTOF(ctl_traps); i++) {
1426
0
      if (TRAP_INUSE & ctl_traps[i].tr_flags) {
1427
0
        rpkt.li_vn_mode =
1428
0
            PKT_LI_VN_MODE(
1429
0
          sys_leap,
1430
0
          ctl_traps[i].tr_version,
1431
0
          MODE_CONTROL);
1432
0
        rpkt.sequence =
1433
0
            htons(ctl_traps[i].tr_sequence);
1434
0
        sendpkt(&ctl_traps[i].tr_addr,
1435
0
          ctl_traps[i].tr_localaddr, -4,
1436
0
          (struct pkt *)&rpkt, sendlen);
1437
0
        if (!more)
1438
0
          ctl_traps[i].tr_sequence++;
1439
0
        numasyncmsgs++;
1440
0
      }
1441
0
    }
1442
109
  } else {
1443
109
    if (res_authenticate && sys_authenticate) {
1444
22
      totlen = sendlen;
1445
      /*
1446
       * If we are going to authenticate, then there
1447
       * is an additional requirement that the MAC
1448
       * begin on a 64 bit boundary.
1449
       */
1450
58
      while (totlen & 7) {
1451
36
        *datapt++ = '\0';
1452
36
        totlen++;
1453
36
      }
1454
22
      keyid = htonl(res_keyid);
1455
22
      memcpy(datapt, &keyid, sizeof(keyid));
1456
22
      maclen = authencrypt(res_keyid,
1457
22
               (u_int32 *)&rpkt, totlen);
1458
22
      sendpkt(rmt_addr, lcl_inter, -5,
1459
22
        (struct pkt *)&rpkt, totlen + maclen);
1460
87
    } else {
1461
87
      sendpkt(rmt_addr, lcl_inter, -6,
1462
87
        (struct pkt *)&rpkt, sendlen);
1463
87
    }
1464
109
    if (more)
1465
0
      numctlfrags++;
1466
109
    else
1467
109
      numctlresponses++;
1468
109
  }
1469
1470
  /*
1471
   * Set us up for another go around.
1472
   */
1473
109
  res_frags++;
1474
109
  res_offset += dlen;
1475
109
  datapt = rpkt.u.data;
1476
109
}
1477
1478
1479
/* --------------------------------------------------------------------
1480
 * block transfer API -- stream string/data fragments into xmit buffer
1481
 * without additional copying
1482
 */
1483
1484
/* buffer descriptor: address & size of fragment
1485
 * 'buf' may only be NULL when 'len' is zero!
1486
 */
1487
typedef struct {
1488
  const void  *buf;
1489
  size_t       len;
1490
} CtlMemBufT;
1491
1492
/* put ctl data in a gather-style operation */
1493
static void
1494
ctl_putdata_ex(
1495
  const CtlMemBufT * argv,
1496
  size_t             argc,
1497
  int/*BOOL*/        bin    /* set to 1 when data is binary */
1498
  )
1499
753
{
1500
753
  const char * src_ptr;
1501
753
  size_t       src_len, cur_len, add_len, argi;
1502
1503
  /* text / binary preprocessing, possibly create new linefeed */
1504
753
  if (bin) {
1505
0
    add_len = 0;
1506
753
  } else {
1507
753
    datanotbinflag = TRUE;
1508
753
    add_len = 3;
1509
1510
753
    if (datasent) {
1511
659
      *datapt++ = ',';
1512
659
      datalinelen++;
1513
1514
      /* sum up total length */
1515
2.71k
      for (argi = 0, src_len = 0; argi < argc; ++argi)
1516
2.05k
        src_len += argv[argi].len;
1517
      /* possibly start a new line, assume no size_t overflow */
1518
659
      if ((src_len + datalinelen + 1) >= MAXDATALINELEN) {
1519
179
        *datapt++ = '\r';
1520
179
        *datapt++ = '\n';
1521
179
        datalinelen = 0;
1522
480
      } else {
1523
480
        *datapt++ = ' ';
1524
480
        datalinelen++;
1525
480
      }
1526
659
    }
1527
753
  }
1528
1529
  /* now stream out all buffers */
1530
3.12k
  for (argi = 0; argi < argc; ++argi) {
1531
2.37k
    src_ptr = argv[argi].buf;
1532
2.37k
    src_len = argv[argi].len;
1533
1534
2.37k
    if ( ! (src_ptr && src_len))
1535
0
      continue;
1536
1537
2.37k
    cur_len = (size_t)(dataend - datapt);
1538
2.37k
    while ((src_len + add_len) > cur_len) {
1539
      /* Not enough room in this one, flush it out. */
1540
0
      if (src_len < cur_len)
1541
0
        cur_len = src_len;
1542
1543
0
      memcpy(datapt, src_ptr, cur_len);
1544
0
      datapt      += cur_len;
1545
0
      datalinelen += cur_len;
1546
1547
0
      src_ptr     += cur_len;
1548
0
      src_len     -= cur_len;
1549
1550
0
      ctl_flushpkt(CTL_MORE);
1551
0
      cur_len = (size_t)(dataend - datapt);
1552
0
    }
1553
1554
2.37k
    memcpy(datapt, src_ptr, src_len);
1555
2.37k
    datapt      += src_len;
1556
2.37k
    datalinelen += src_len;
1557
1558
2.37k
    datasent = TRUE;
1559
2.37k
  }
1560
753
}
1561
1562
/*
1563
 * ctl_putdata - write data into the packet, fragmenting and starting
1564
 * another if this one is full.
1565
 */
1566
static void
1567
ctl_putdata(
1568
  const char *dp,
1569
  unsigned int dlen,
1570
  int bin     /* set to 1 when data is binary */
1571
  )
1572
0
{
1573
0
  CtlMemBufT args[1];
1574
1575
0
  args[0].buf = dp;
1576
0
  args[0].len = dlen;
1577
0
  ctl_putdata_ex(args, 1, bin);
1578
0
}
1579
1580
/*
1581
 * ctl_putstr - write a tagged string into the response packet
1582
 *    in the form:
1583
 *
1584
 *    tag="data"
1585
 *
1586
 *    len is the data length excluding the NUL terminator,
1587
 *    as in ctl_putstr("var", "value", strlen("value"));
1588
 */
1589
static void
1590
ctl_putstr(
1591
  const char *  tag,
1592
  const char *  data,
1593
  size_t    len
1594
  )
1595
112
{
1596
112
  CtlMemBufT args[4];
1597
1598
112
  args[0].buf = tag;
1599
112
  args[0].len = strlen(tag);
1600
112
  if (data && len) {
1601
112
      args[1].buf = "=\"";
1602
112
      args[1].len = 2;
1603
112
      args[2].buf = data;
1604
112
      args[2].len = len;
1605
112
      args[3].buf = "\"";
1606
112
      args[3].len = 1;
1607
112
      ctl_putdata_ex(args, 4, FALSE);
1608
112
  } else {
1609
0
      args[1].buf = "=\"\"";
1610
0
      args[1].len = 3;
1611
0
      ctl_putdata_ex(args, 2, FALSE);
1612
0
  }
1613
112
}
1614
1615
1616
/*
1617
 * ctl_putunqstr - write a tagged string into the response packet
1618
 *       in the form:
1619
 *
1620
 *       tag=data
1621
 *
1622
 *  len is the data length excluding the NUL terminator.
1623
 *  data must not contain a comma or whitespace.
1624
 */
1625
static void
1626
ctl_putunqstr(
1627
  const char *  tag,
1628
  const char *  data,
1629
  size_t    len
1630
  )
1631
641
{
1632
641
  CtlMemBufT args[3];
1633
1634
641
  args[0].buf = tag;
1635
641
  args[0].len = strlen(tag);
1636
641
  args[1].buf = "=";
1637
641
  args[1].len = 1;
1638
641
  if (data && len) {
1639
641
    args[2].buf = data;
1640
641
    args[2].len = len;
1641
641
    ctl_putdata_ex(args, 3, FALSE);
1642
641
  } else {
1643
0
    ctl_putdata_ex(args, 2, FALSE);
1644
0
  }
1645
641
}
1646
1647
1648
/*
1649
 * ctl_putdblf - write a tagged, signed double into the response packet
1650
 */
1651
static void
1652
ctl_putdblf(
1653
  const char *  tag,
1654
  int   use_f,
1655
  int   precision,
1656
  double    d
1657
  )
1658
253
{
1659
253
  char buffer[40];
1660
253
  int  rc;
1661
1662
253
  rc = snprintf(buffer, sizeof(buffer),
1663
253
          (use_f ? "%.*f" : "%.*g"),
1664
253
          precision, d);
1665
253
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1666
0
  ctl_putunqstr(tag, buffer, rc);
1667
253
}
1668
1669
/*
1670
 * ctl_putuint - write a tagged unsigned integer into the response
1671
 */
1672
static void
1673
ctl_putuint(
1674
  const char *tag,
1675
  u_long uval
1676
  )
1677
199
{
1678
199
  char buffer[24]; /* needs to fit for 64 bits! */
1679
199
  int  rc;
1680
1681
199
  rc = snprintf(buffer, sizeof(buffer), "%lu", uval);
1682
199
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1683
0
  ctl_putunqstr(tag, buffer, rc);
1684
199
}
1685
1686
/*
1687
 * ctl_putcal - write a decoded calendar data into the response.
1688
 * only used with AUTOKEY currently, so compiled conditional
1689
 */
1690
#ifdef AUTOKEY
1691
static void
1692
ctl_putcal(
1693
  const char *tag,
1694
  const struct calendar *pcal
1695
  )
1696
{
1697
  char buffer[16];
1698
  int  rc;
1699
1700
  rc = snprintf(buffer, sizeof(buffer),
1701
          "%04d%02d%02d%02d%02d",
1702
          pcal->year, pcal->month, pcal->monthday,
1703
          pcal->hour, pcal->minute
1704
    );
1705
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1706
  ctl_putunqstr(tag, buffer, rc);
1707
}
1708
#endif
1709
1710
/*
1711
 * ctl_putfs - write a decoded filestamp into the response
1712
 */
1713
static void
1714
ctl_putfs(
1715
  const char *tag,
1716
  tstamp_t uval
1717
  )
1718
0
{
1719
0
  char buffer[16];
1720
0
  int  rc;
1721
1722
0
  time_t fstamp = (time_t)uval - JAN_1970;
1723
0
  struct tm *tm = gmtime(&fstamp);
1724
1725
0
  if (NULL == tm)
1726
0
    return;
1727
1728
0
  rc = snprintf(buffer, sizeof(buffer),
1729
0
          "%04d%02d%02d%02d%02d",
1730
0
          tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1731
0
          tm->tm_hour, tm->tm_min);
1732
0
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1733
0
  ctl_putunqstr(tag, buffer, rc);
1734
0
}
1735
1736
1737
/*
1738
 * ctl_puthex - write a tagged unsigned integer, in hex, into the
1739
 * response
1740
 */
1741
static void
1742
ctl_puthex(
1743
  const char *tag,
1744
  u_long uval
1745
  )
1746
0
{
1747
0
  char buffer[24];  /* must fit 64bit int! */
1748
0
  int  rc;
1749
1750
0
  rc = snprintf(buffer, sizeof(buffer), "0x%lx", uval);
1751
0
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1752
0
  ctl_putunqstr(tag, buffer, rc);
1753
0
}
1754
1755
1756
/*
1757
 * ctl_putint - write a tagged signed integer into the response
1758
 */
1759
static void
1760
ctl_putint(
1761
  const char *tag,
1762
  long ival
1763
  )
1764
35
{
1765
35
  char buffer[24];  /*must fit 64bit int */
1766
35
  int  rc;
1767
1768
35
  rc = snprintf(buffer, sizeof(buffer), "%ld", ival);
1769
35
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1770
0
  ctl_putunqstr(tag, buffer, rc);
1771
35
}
1772
1773
1774
/*
1775
 * ctl_putts - write a tagged timestamp, in hex, into the response
1776
 */
1777
static void
1778
ctl_putts(
1779
  const char *tag,
1780
  l_fp *ts
1781
  )
1782
78
{
1783
78
  char buffer[24];
1784
78
  int  rc;
1785
1786
78
  rc = snprintf(buffer, sizeof(buffer),
1787
78
          "0x%08lx.%08lx",
1788
78
          (u_long)ts->l_ui, (u_long)ts->l_uf);
1789
78
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1790
0
  ctl_putunqstr(tag, buffer, rc);
1791
78
}
1792
1793
1794
/*
1795
 * ctl_putadr - write an IP address into the response
1796
 */
1797
static void
1798
ctl_putadr(
1799
  const char *tag,
1800
  u_int32 addr32,
1801
  sockaddr_u *addr
1802
  )
1803
0
{
1804
0
  const char *cq;
1805
1806
0
  if (NULL == addr)
1807
0
    cq = numtoa(addr32);
1808
0
  else
1809
0
    cq = stoa(addr);
1810
0
  ctl_putunqstr(tag, cq, strlen(cq));
1811
0
}
1812
1813
1814
/*
1815
 * ctl_putrefid - send a u_int32 refid as printable text
1816
 */
1817
static void
1818
ctl_putrefid(
1819
  const char *  tag,
1820
  u_int32   refid
1821
  )
1822
35
{
1823
35
  size_t nc;
1824
1825
35
  union {
1826
35
    uint32_t w;
1827
35
    uint8_t  b[sizeof(uint32_t)];
1828
35
  } bytes;
1829
1830
35
  bytes.w = refid;
1831
175
  for (nc = 0; nc < sizeof(bytes.b) && bytes.b[nc]; ++nc)
1832
140
    if (  !isprint(bytes.b[nc])
1833
140
        || isspace(bytes.b[nc])
1834
140
        || bytes.b[nc] == ','  )
1835
0
      bytes.b[nc] = '.';
1836
35
  ctl_putunqstr(tag, (const char*)bytes.b, nc);
1837
35
}
1838
1839
1840
/*
1841
 * ctl_putarray - write a tagged eight element double array into the response
1842
 */
1843
static void
1844
ctl_putarray(
1845
  const char *tag,
1846
  double *arr,
1847
  int start
1848
  )
1849
0
{
1850
0
  char *cp, *ep;
1851
0
  char buffer[200];
1852
0
  int  i, rc;
1853
1854
0
  cp = buffer;
1855
0
  ep = buffer + sizeof(buffer);
1856
0
  i  = start;
1857
0
  do {
1858
0
    if (i == 0)
1859
0
      i = NTP_SHIFT;
1860
0
    i--;
1861
0
    rc = snprintf(cp, (size_t)(ep - cp), " %.2f", arr[i] * 1e3);
1862
0
    INSIST(rc >= 0 && (size_t)rc < (size_t)(ep - cp));
1863
0
    cp += rc;
1864
0
  } while (i != start);
1865
0
  ctl_putunqstr(tag, buffer, (size_t)(cp - buffer));
1866
0
}
1867
1868
/*
1869
 * ctl_printf - put a formatted string into the data buffer
1870
 */
1871
static void
1872
ctl_printf(
1873
  const char * fmt,
1874
  ...
1875
  )
1876
0
{
1877
0
  static const char * ellipsis = "[...]";
1878
0
  va_list va;
1879
0
  char    fmtbuf[128];
1880
0
  int     rc;
1881
1882
0
  va_start(va, fmt);
1883
0
  rc = vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, va);
1884
0
  va_end(va);
1885
0
  if (rc < 0 || (size_t)rc >= sizeof(fmtbuf))
1886
0
    strcpy(fmtbuf + sizeof(fmtbuf) - strlen(ellipsis) - 1,
1887
0
           ellipsis);
1888
0
  ctl_putdata(fmtbuf, strlen(fmtbuf), 0);
1889
0
}
1890
1891
1892
/*
1893
 * ctl_putsys - output a system variable
1894
 */
1895
static void
1896
ctl_putsys(
1897
  int varid
1898
  )
1899
892
{
1900
892
  l_fp tmp;
1901
892
  char str[256];
1902
892
  u_int u;
1903
892
  double kb;
1904
892
  double dtemp;
1905
892
  const char *ss;
1906
#ifdef AUTOKEY
1907
  struct cert_info *cp;
1908
#endif  /* AUTOKEY */
1909
892
#ifdef KERNEL_PLL
1910
892
  static struct timex ntx;
1911
892
  static u_long ntp_adjtime_time;
1912
1913
892
  static const double to_ms_usec =
1914
892
    1.0e-3; /* usec to msec */
1915
892
  static const double to_ms_nusec =
1916
892
# ifdef STA_NANO
1917
892
    1.0e-6; /* nsec to msec */
1918
# else
1919
    to_ms_usec;
1920
# endif
1921
1922
  /*
1923
   * CS_K_* variables depend on up-to-date output of ntp_adjtime()
1924
   */
1925
892
  if (CS_KERN_FIRST <= varid && varid <= CS_KERN_LAST &&
1926
892
      current_time != ntp_adjtime_time) {
1927
0
    ZERO(ntx);
1928
0
    if (ntp_adjtime(&ntx) < 0)
1929
0
      msyslog(LOG_ERR, "ntp_adjtime() for mode 6 query failed: %m");
1930
0
    else
1931
0
      ntp_adjtime_time = current_time;
1932
0
  }
1933
892
#endif  /* KERNEL_PLL */
1934
1935
892
  switch (varid) {
1936
1937
36
  case CS_LEAP:
1938
36
    ctl_putuint(sys_var[CS_LEAP].text, sys_leap);
1939
36
    break;
1940
1941
35
  case CS_STRATUM:
1942
35
    ctl_putuint(sys_var[CS_STRATUM].text, sys_stratum);
1943
35
    break;
1944
1945
35
  case CS_PRECISION:
1946
35
    ctl_putint(sys_var[CS_PRECISION].text, sys_precision);
1947
35
    break;
1948
1949
35
  case CS_ROOTDELAY:
1950
35
    ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay *
1951
35
         1e3);
1952
35
    break;
1953
1954
35
  case CS_ROOTDISPERSION:
1955
35
    ctl_putdbl(sys_var[CS_ROOTDISPERSION].text,
1956
35
         sys_rootdisp * 1e3);
1957
35
    break;
1958
1959
35
  case CS_REFID:
1960
35
    if (REFID_ISTEXT(sys_stratum))
1961
35
      ctl_putrefid(sys_var[varid].text, sys_refid);
1962
0
    else
1963
0
      ctl_putadr(sys_var[varid].text, sys_refid, NULL);
1964
35
    break;
1965
1966
35
  case CS_REFTIME:
1967
35
    ctl_putts(sys_var[CS_REFTIME].text, &sys_reftime);
1968
35
    break;
1969
1970
48
  case CS_POLL:
1971
48
    ctl_putuint(sys_var[CS_POLL].text, sys_poll);
1972
48
    break;
1973
1974
42
  case CS_PEERID:
1975
42
    if (sys_peer == NULL)
1976
42
      ctl_putuint(sys_var[CS_PEERID].text, 0);
1977
0
    else
1978
0
      ctl_putuint(sys_var[CS_PEERID].text,
1979
0
            sys_peer->associd);
1980
42
    break;
1981
1982
4
  case CS_PEERADR:
1983
4
    if (sys_peer != NULL && sys_peer->dstadr != NULL)
1984
0
      ss = sptoa(&sys_peer->srcadr);
1985
4
    else
1986
4
      ss = "0.0.0.0:0";
1987
4
    ctl_putunqstr(sys_var[CS_PEERADR].text, ss, strlen(ss));
1988
4
    break;
1989
1990
0
  case CS_PEERMODE:
1991
0
    u = (sys_peer != NULL)
1992
0
      ? sys_peer->hmode
1993
0
      : MODE_UNSPEC;
1994
0
    ctl_putuint(sys_var[CS_PEERMODE].text, u);
1995
0
    break;
1996
1997
35
  case CS_OFFSET:
1998
35
    ctl_putdbl6(sys_var[CS_OFFSET].text, last_offset * 1e3);
1999
35
    break;
2000
2001
35
  case CS_DRIFT:
2002
35
    ctl_putdbl(sys_var[CS_DRIFT].text, drift_comp * 1e6);
2003
35
    break;
2004
2005
35
  case CS_JITTER:
2006
35
    ctl_putdbl6(sys_var[CS_JITTER].text, sys_jitter * 1e3);
2007
35
    break;
2008
2009
35
  case CS_ERROR:
2010
35
    ctl_putdbl(sys_var[CS_ERROR].text, clock_jitter * 1e3);
2011
35
    break;
2012
2013
43
  case CS_CLOCK:
2014
43
    get_systime(&tmp);
2015
43
    ctl_putts(sys_var[CS_CLOCK].text, &tmp);
2016
43
    break;
2017
2018
35
  case CS_PROCESSOR:
2019
#ifndef HAVE_UNAME
2020
    ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor,
2021
         sizeof(str_processor) - 1);
2022
#else
2023
35
    ctl_putstr(sys_var[CS_PROCESSOR].text,
2024
35
         utsnamebuf.machine, strlen(utsnamebuf.machine));
2025
35
#endif /* HAVE_UNAME */
2026
35
    break;
2027
2028
42
  case CS_SYSTEM:
2029
#ifndef HAVE_UNAME
2030
    ctl_putstr(sys_var[CS_SYSTEM].text, str_system,
2031
         sizeof(str_system) - 1);
2032
#else
2033
42
    snprintf(str, sizeof(str), "%s/%s", utsnamebuf.sysname,
2034
42
       utsnamebuf.release);
2035
42
    ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str));
2036
42
#endif /* HAVE_UNAME */
2037
42
    break;
2038
2039
35
  case CS_VERSION:
2040
35
    ctl_putstr(sys_var[CS_VERSION].text, Version,
2041
35
         strlen(Version));
2042
35
    break;
2043
2044
35
  case CS_STABIL:
2045
35
    ctl_putdbl(sys_var[CS_STABIL].text, clock_stability *
2046
35
         1e6);
2047
35
    break;
2048
2049
0
  case CS_VARLIST:
2050
0
  {
2051
0
    char buf[CTL_MAX_DATA_LEN];
2052
    //buffPointer, firstElementPointer, buffEndPointer
2053
0
    char *buffp, *buffend;
2054
0
    int firstVarName;
2055
0
    const char *ss1;
2056
0
    int len;
2057
0
    const struct ctl_var *k;
2058
2059
0
    buffp = buf;
2060
0
    buffend = buf + sizeof(buf);
2061
0
    if (strlen(sys_var[CS_VARLIST].text) > (sizeof(buf) - 4))
2062
0
      break; /* really long var name */
2063
2064
0
    snprintf(buffp, sizeof(buf), "%s=\"",sys_var[CS_VARLIST].text);
2065
0
    buffp += strlen(buffp);
2066
0
    firstVarName = TRUE;
2067
0
    for (k = sys_var; !(k->flags & EOV); k++) {
2068
0
      if (k->flags & PADDING)
2069
0
        continue;
2070
0
      len = strlen(k->text);
2071
0
      if (len + 1 >= buffend - buffp)
2072
0
        break;
2073
0
      if (!firstVarName)
2074
0
        *buffp++ = ',';
2075
0
      else
2076
0
        firstVarName = FALSE;
2077
0
      memcpy(buffp, k->text, len);
2078
0
      buffp += len;
2079
0
    }
2080
2081
0
    for (k = ext_sys_var; k && !(k->flags & EOV); k++) {
2082
0
      if (k->flags & PADDING)
2083
0
        continue;
2084
0
      if (NULL == k->text)
2085
0
        continue;
2086
0
      ss1 = strchr(k->text, '=');
2087
0
      if (NULL == ss1)
2088
0
        len = strlen(k->text);
2089
0
      else
2090
0
        len = ss1 - k->text;
2091
0
      if (len + 1 >= buffend - buffp)
2092
0
        break;
2093
0
      if (firstVarName) {
2094
0
        *buffp++ = ',';
2095
0
        firstVarName = FALSE;
2096
0
      }
2097
0
      memcpy(buffp, k->text,(unsigned)len);
2098
0
      buffp += len;
2099
0
    }
2100
0
    if (2 >= buffend - buffp)
2101
0
      break;
2102
2103
0
    *buffp++ = '"';
2104
0
    *buffp = '\0';
2105
2106
0
    ctl_putdata(buf, (unsigned)( buffp - buf ), 0);
2107
0
    break;
2108
0
  }
2109
2110
36
  case CS_TAI:
2111
36
    if (sys_tai > 0)
2112
0
      ctl_putuint(sys_var[CS_TAI].text, sys_tai);
2113
36
    break;
2114
2115
35
  case CS_LEAPTAB:
2116
35
  {
2117
35
    leap_signature_t lsig;
2118
35
    leapsec_getsig(&lsig);
2119
35
    if (lsig.ttime > 0)
2120
0
      ctl_putfs(sys_var[CS_LEAPTAB].text, lsig.ttime);
2121
35
    break;
2122
0
  }
2123
2124
35
  case CS_LEAPEND:
2125
35
  {
2126
35
    leap_signature_t lsig;
2127
35
    leapsec_getsig(&lsig);
2128
35
    if (lsig.etime > 0)
2129
0
      ctl_putfs(sys_var[CS_LEAPEND].text, lsig.etime);
2130
35
    break;
2131
0
  }
2132
2133
#ifdef LEAP_SMEAR
2134
  case CS_LEAPSMEARINTV:
2135
    if (leap_smear_intv > 0)
2136
      ctl_putuint(sys_var[CS_LEAPSMEARINTV].text, leap_smear_intv);
2137
    break;
2138
2139
  case CS_LEAPSMEAROFFS:
2140
    if (leap_smear_intv > 0)
2141
      ctl_putdbl(sys_var[CS_LEAPSMEAROFFS].text,
2142
           leap_smear.doffset * 1e3);
2143
    break;
2144
#endif  /* LEAP_SMEAR */
2145
2146
38
  case CS_RATE:
2147
38
    ctl_putuint(sys_var[CS_RATE].text, ntp_minpoll);
2148
38
    break;
2149
2150
0
  case CS_MRU_ENABLED:
2151
0
    ctl_puthex(sys_var[varid].text, mon_enabled);
2152
0
    break;
2153
2154
0
  case CS_MRU_DEPTH:
2155
0
    ctl_putuint(sys_var[varid].text, mru_entries);
2156
0
    break;
2157
2158
0
  case CS_MRU_MEM:
2159
0
    kb = mru_entries * (sizeof(mon_entry) / 1024.);
2160
0
    u = (u_int)kb;
2161
0
    if (kb - u >= 0.5)
2162
0
      u++;
2163
0
    ctl_putuint(sys_var[varid].text, u);
2164
0
    break;
2165
2166
0
  case CS_MRU_DEEPEST:
2167
0
    ctl_putuint(sys_var[varid].text, mru_peakentries);
2168
0
    break;
2169
2170
0
  case CS_MRU_MINDEPTH:
2171
0
    ctl_putuint(sys_var[varid].text, mru_mindepth);
2172
0
    break;
2173
2174
0
  case CS_MRU_MAXAGE:
2175
0
    ctl_putint(sys_var[varid].text, mru_maxage);
2176
0
    break;
2177
2178
0
  case CS_MRU_MAXDEPTH:
2179
0
    ctl_putuint(sys_var[varid].text, mru_maxdepth);
2180
0
    break;
2181
2182
0
  case CS_MRU_MAXMEM:
2183
0
    kb = mru_maxdepth * (sizeof(mon_entry) / 1024.);
2184
0
    u = (u_int)kb;
2185
0
    if (kb - u >= 0.5)
2186
0
      u++;
2187
0
    ctl_putuint(sys_var[varid].text, u);
2188
0
    break;
2189
2190
0
  case CS_SS_UPTIME:
2191
0
    ctl_putuint(sys_var[varid].text, current_time);
2192
0
    break;
2193
2194
0
  case CS_SS_RESET:
2195
0
    ctl_putuint(sys_var[varid].text,
2196
0
          current_time - sys_stattime);
2197
0
    break;
2198
2199
0
  case CS_SS_RECEIVED:
2200
0
    ctl_putuint(sys_var[varid].text, sys_received);
2201
0
    break;
2202
2203
0
  case CS_SS_THISVER:
2204
0
    ctl_putuint(sys_var[varid].text, sys_newversion);
2205
0
    break;
2206
2207
0
  case CS_SS_OLDVER:
2208
0
    ctl_putuint(sys_var[varid].text, sys_oldversion);
2209
0
    break;
2210
2211
0
  case CS_SS_BADFORMAT:
2212
0
    ctl_putuint(sys_var[varid].text, sys_badlength);
2213
0
    break;
2214
2215
0
  case CS_SS_BADAUTH:
2216
0
    ctl_putuint(sys_var[varid].text, sys_badauth);
2217
0
    break;
2218
2219
0
  case CS_SS_DECLINED:
2220
0
    ctl_putuint(sys_var[varid].text, sys_declined);
2221
0
    break;
2222
2223
0
  case CS_SS_RESTRICTED:
2224
0
    ctl_putuint(sys_var[varid].text, sys_restricted);
2225
0
    break;
2226
2227
0
  case CS_SS_LIMITED:
2228
0
    ctl_putuint(sys_var[varid].text, sys_limitrejected);
2229
0
    break;
2230
2231
0
  case CS_SS_LAMPORT:
2232
0
    ctl_putuint(sys_var[varid].text, sys_lamport);
2233
0
    break;
2234
2235
0
  case CS_SS_TSROUNDING:
2236
0
    ctl_putuint(sys_var[varid].text, sys_tsrounding);
2237
0
    break;
2238
2239
0
  case CS_SS_KODSENT:
2240
0
    ctl_putuint(sys_var[varid].text, sys_kodsent);
2241
0
    break;
2242
2243
0
  case CS_SS_PROCESSED:
2244
0
    ctl_putuint(sys_var[varid].text, sys_processed);
2245
0
    break;
2246
2247
0
  case CS_BCASTDELAY:
2248
0
    ctl_putdbl(sys_var[varid].text, sys_bdelay * 1e3);
2249
0
    break;
2250
2251
0
  case CS_AUTHDELAY:
2252
0
    LFPTOD(&sys_authdelay, dtemp);
2253
0
    ctl_putdbl(sys_var[varid].text, dtemp * 1e3);
2254
0
    break;
2255
2256
0
  case CS_AUTHKEYS:
2257
0
    ctl_putuint(sys_var[varid].text, authnumkeys);
2258
0
    break;
2259
2260
0
  case CS_AUTHFREEK:
2261
0
    ctl_putuint(sys_var[varid].text, authnumfreekeys);
2262
0
    break;
2263
2264
0
  case CS_AUTHKLOOKUPS:
2265
0
    ctl_putuint(sys_var[varid].text, authkeylookups);
2266
0
    break;
2267
2268
0
  case CS_AUTHKNOTFOUND:
2269
0
    ctl_putuint(sys_var[varid].text, authkeynotfound);
2270
0
    break;
2271
2272
0
  case CS_AUTHKUNCACHED:
2273
0
    ctl_putuint(sys_var[varid].text, authkeyuncached);
2274
0
    break;
2275
2276
0
  case CS_AUTHKEXPIRED:
2277
0
    ctl_putuint(sys_var[varid].text, authkeyexpired);
2278
0
    break;
2279
2280
0
  case CS_AUTHENCRYPTS:
2281
0
    ctl_putuint(sys_var[varid].text, authencryptions);
2282
0
    break;
2283
2284
0
  case CS_AUTHDECRYPTS:
2285
0
    ctl_putuint(sys_var[varid].text, authdecryptions);
2286
0
    break;
2287
2288
0
  case CS_AUTHRESET:
2289
0
    ctl_putuint(sys_var[varid].text,
2290
0
          current_time - auth_timereset);
2291
0
    break;
2292
2293
    /*
2294
     * CTL_IF_KERNLOOP() puts a zero if the kernel loop is
2295
     * unavailable, otherwise calls putfunc with args.
2296
     */
2297
#ifndef KERNEL_PLL
2298
# define  CTL_IF_KERNLOOP(putfunc, args)  \
2299
    ctl_putint(sys_var[varid].text, 0)
2300
#else
2301
0
# define  CTL_IF_KERNLOOP(putfunc, args)  \
2302
0
    putfunc args
2303
0
#endif
2304
2305
    /*
2306
     * CTL_IF_KERNPPS() puts a zero if either the kernel
2307
     * loop is unavailable, or kernel hard PPS is not
2308
     * active, otherwise calls putfunc with args.
2309
     */
2310
#ifndef KERNEL_PLL
2311
# define  CTL_IF_KERNPPS(putfunc, args) \
2312
    ctl_putint(sys_var[varid].text, 0)
2313
#else
2314
0
# define  CTL_IF_KERNPPS(putfunc, args)     \
2315
0
    if (0 == ntx.shift)       \
2316
0
      ctl_putint(sys_var[varid].text, 0); \
2317
0
    else            \
2318
0
      putfunc args /* no trailing ; */
2319
0
#endif
2320
2321
0
  case CS_K_OFFSET:
2322
0
    CTL_IF_KERNLOOP(
2323
0
      ctl_putdblf,
2324
0
      (sys_var[varid].text, 0, -1, to_ms_nusec * ntx.offset)
2325
0
    );
2326
0
    break;
2327
2328
0
  case CS_K_FREQ:
2329
0
    CTL_IF_KERNLOOP(
2330
0
      ctl_putsfp,
2331
0
      (sys_var[varid].text, ntx.freq)
2332
0
    );
2333
0
    break;
2334
2335
0
  case CS_K_MAXERR:
2336
0
    CTL_IF_KERNLOOP(
2337
0
      ctl_putdblf,
2338
0
      (sys_var[varid].text, 0, 6,
2339
0
       to_ms_usec * ntx.maxerror)
2340
0
    );
2341
0
    break;
2342
2343
0
  case CS_K_ESTERR:
2344
0
    CTL_IF_KERNLOOP(
2345
0
      ctl_putdblf,
2346
0
      (sys_var[varid].text, 0, 6,
2347
0
       to_ms_usec * ntx.esterror)
2348
0
    );
2349
0
    break;
2350
2351
0
  case CS_K_STFLAGS:
2352
#ifndef KERNEL_PLL
2353
    ss = "";
2354
#else
2355
0
    ss = k_st_flags(ntx.status);
2356
0
#endif
2357
0
    ctl_putstr(sys_var[varid].text, ss, strlen(ss));
2358
0
    break;
2359
2360
0
  case CS_K_TIMECONST:
2361
0
    CTL_IF_KERNLOOP(
2362
0
      ctl_putint,
2363
0
      (sys_var[varid].text, ntx.constant)
2364
0
    );
2365
0
    break;
2366
2367
0
  case CS_K_PRECISION:
2368
0
    CTL_IF_KERNLOOP(
2369
0
      ctl_putdblf,
2370
0
      (sys_var[varid].text, 0, 6,
2371
0
          to_ms_usec * ntx.precision)
2372
0
    );
2373
0
    break;
2374
2375
0
  case CS_K_FREQTOL:
2376
0
    CTL_IF_KERNLOOP(
2377
0
      ctl_putsfp,
2378
0
      (sys_var[varid].text, ntx.tolerance)
2379
0
    );
2380
0
    break;
2381
2382
0
  case CS_K_PPS_FREQ:
2383
0
    CTL_IF_KERNPPS(
2384
0
      ctl_putsfp,
2385
0
      (sys_var[varid].text, ntx.ppsfreq)
2386
0
    );
2387
0
    break;
2388
2389
0
  case CS_K_PPS_STABIL:
2390
0
    CTL_IF_KERNPPS(
2391
0
      ctl_putsfp,
2392
0
      (sys_var[varid].text, ntx.stabil)
2393
0
    );
2394
0
    break;
2395
2396
0
  case CS_K_PPS_JITTER:
2397
0
    CTL_IF_KERNPPS(
2398
0
      ctl_putdbl,
2399
0
      (sys_var[varid].text, to_ms_nusec * ntx.jitter)
2400
0
    );
2401
0
    break;
2402
2403
0
  case CS_K_PPS_CALIBDUR:
2404
0
    CTL_IF_KERNPPS(
2405
0
      ctl_putint,
2406
0
      (sys_var[varid].text, 1 << ntx.shift)
2407
0
    );
2408
0
    break;
2409
2410
0
  case CS_K_PPS_CALIBS:
2411
0
    CTL_IF_KERNPPS(
2412
0
      ctl_putint,
2413
0
      (sys_var[varid].text, ntx.calcnt)
2414
0
    );
2415
0
    break;
2416
2417
0
  case CS_K_PPS_CALIBERRS:
2418
0
    CTL_IF_KERNPPS(
2419
0
      ctl_putint,
2420
0
      (sys_var[varid].text, ntx.errcnt)
2421
0
    );
2422
0
    break;
2423
2424
0
  case CS_K_PPS_JITEXC:
2425
0
    CTL_IF_KERNPPS(
2426
0
      ctl_putint,
2427
0
      (sys_var[varid].text, ntx.jitcnt)
2428
0
    );
2429
0
    break;
2430
2431
0
  case CS_K_PPS_STBEXC:
2432
0
    CTL_IF_KERNPPS(
2433
0
      ctl_putint,
2434
0
      (sys_var[varid].text, ntx.stbcnt)
2435
0
    );
2436
0
    break;
2437
2438
0
  case CS_IOSTATS_RESET:
2439
0
    ctl_putuint(sys_var[varid].text,
2440
0
          current_time - io_timereset);
2441
0
    break;
2442
2443
0
  case CS_TOTAL_RBUF:
2444
0
    ctl_putuint(sys_var[varid].text, total_recvbuffs());
2445
0
    break;
2446
2447
0
  case CS_FREE_RBUF:
2448
0
    ctl_putuint(sys_var[varid].text, free_recvbuffs());
2449
0
    break;
2450
2451
0
  case CS_USED_RBUF:
2452
0
    ctl_putuint(sys_var[varid].text, full_recvbuffs());
2453
0
    break;
2454
2455
0
  case CS_RBUF_LOWATER:
2456
0
    ctl_putuint(sys_var[varid].text, lowater_additions());
2457
0
    break;
2458
2459
0
  case CS_IO_DROPPED:
2460
0
    ctl_putuint(sys_var[varid].text, packets_dropped);
2461
0
    break;
2462
2463
0
  case CS_IO_IGNORED:
2464
0
    ctl_putuint(sys_var[varid].text, packets_ignored);
2465
0
    break;
2466
2467
0
  case CS_IO_RECEIVED:
2468
0
    ctl_putuint(sys_var[varid].text, packets_received);
2469
0
    break;
2470
2471
0
  case CS_IO_SENT:
2472
0
    ctl_putuint(sys_var[varid].text, packets_sent);
2473
0
    break;
2474
2475
0
  case CS_IO_SENDFAILED:
2476
0
    ctl_putuint(sys_var[varid].text, packets_notsent);
2477
0
    break;
2478
2479
0
  case CS_IO_WAKEUPS:
2480
0
    ctl_putuint(sys_var[varid].text, handler_calls);
2481
0
    break;
2482
2483
0
  case CS_IO_GOODWAKEUPS:
2484
0
    ctl_putuint(sys_var[varid].text, handler_pkts);
2485
0
    break;
2486
2487
0
  case CS_TIMERSTATS_RESET:
2488
0
    ctl_putuint(sys_var[varid].text,
2489
0
          current_time - timer_timereset);
2490
0
    break;
2491
2492
0
  case CS_TIMER_OVERRUNS:
2493
0
    ctl_putuint(sys_var[varid].text, alarm_overflow);
2494
0
    break;
2495
2496
0
  case CS_TIMER_XMTS:
2497
0
    ctl_putuint(sys_var[varid].text, timer_xmtcalls);
2498
0
    break;
2499
2500
8
  case CS_FUZZ:
2501
8
    ctl_putdbl(sys_var[varid].text, sys_fuzz * 1e3);
2502
8
    break;
2503
0
  case CS_WANDER_THRESH:
2504
0
    ctl_putdbl(sys_var[varid].text, wander_threshold * 1e6);
2505
0
    break;
2506
#ifdef AUTOKEY
2507
  case CS_FLAGS:
2508
    if (crypto_flags)
2509
      ctl_puthex(sys_var[CS_FLAGS].text,
2510
          crypto_flags);
2511
    break;
2512
2513
  case CS_DIGEST:
2514
    if (crypto_flags) {
2515
      strlcpy(str, OBJ_nid2ln(crypto_nid),
2516
          COUNTOF(str));
2517
      ctl_putstr(sys_var[CS_DIGEST].text, str,
2518
          strlen(str));
2519
    }
2520
    break;
2521
2522
  case CS_SIGNATURE:
2523
    if (crypto_flags) {
2524
      const EVP_MD *dp;
2525
2526
      dp = EVP_get_digestbynid(crypto_flags >> 16);
2527
      strlcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)),
2528
          COUNTOF(str));
2529
      ctl_putstr(sys_var[CS_SIGNATURE].text, str,
2530
          strlen(str));
2531
    }
2532
    break;
2533
2534
  case CS_HOST:
2535
    if (hostval.ptr != NULL)
2536
      ctl_putstr(sys_var[CS_HOST].text, hostval.ptr,
2537
          strlen(hostval.ptr));
2538
    break;
2539
2540
  case CS_IDENT:
2541
    if (sys_ident != NULL)
2542
      ctl_putstr(sys_var[CS_IDENT].text, sys_ident,
2543
          strlen(sys_ident));
2544
    break;
2545
2546
  case CS_CERTIF:
2547
    for (cp = cinfo; cp != NULL; cp = cp->link) {
2548
      snprintf(str, sizeof(str), "%s %s 0x%x",
2549
          cp->subject, cp->issuer, cp->flags);
2550
      ctl_putstr(sys_var[CS_CERTIF].text, str,
2551
          strlen(str));
2552
      ctl_putcal(sys_var[CS_REVTIME].text, &(cp->last));
2553
    }
2554
    break;
2555
2556
  case CS_PUBLIC:
2557
    if (hostval.tstamp != 0)
2558
      ctl_putfs(sys_var[CS_PUBLIC].text,
2559
          ntohl(hostval.tstamp));
2560
    break;
2561
#endif  /* AUTOKEY */
2562
2563
70
  default:
2564
70
    break;
2565
892
  }
2566
892
}
2567
2568
2569
/*
2570
 * ctl_putpeer - output a peer variable
2571
 */
2572
static void
2573
ctl_putpeer(
2574
  int id,
2575
  struct peer *p
2576
  )
2577
0
{
2578
0
  char buf[CTL_MAX_DATA_LEN];
2579
0
  char *s;
2580
0
  char *t;
2581
0
  char *be;
2582
0
  int i;
2583
0
  const struct ctl_var *k;
2584
#ifdef AUTOKEY
2585
  struct autokey *ap;
2586
  const EVP_MD *dp;
2587
  const char *str;
2588
#endif  /* AUTOKEY */
2589
2590
0
  switch (id) {
2591
2592
0
  case CP_CONFIG:
2593
0
    ctl_putuint(peer_var[id].text,
2594
0
          !(FLAG_PREEMPT & p->flags));
2595
0
    break;
2596
2597
0
  case CP_AUTHENABLE:
2598
0
    ctl_putuint(peer_var[id].text, !(p->keyid));
2599
0
    break;
2600
2601
0
  case CP_AUTHENTIC:
2602
0
    ctl_putuint(peer_var[id].text,
2603
0
          !!(FLAG_AUTHENTIC & p->flags));
2604
0
    break;
2605
2606
0
  case CP_SRCADR:
2607
0
    ctl_putadr(peer_var[id].text, 0, &p->srcadr);
2608
0
    break;
2609
2610
0
  case CP_SRCPORT:
2611
0
    ctl_putuint(peer_var[id].text, SRCPORT(&p->srcadr));
2612
0
    break;
2613
2614
0
  case CP_SRCHOST:
2615
0
    if (p->hostname != NULL)
2616
0
      ctl_putstr(peer_var[id].text, p->hostname,
2617
0
           strlen(p->hostname));
2618
0
    break;
2619
2620
0
  case CP_DSTADR:
2621
0
    ctl_putadr(peer_var[id].text, 0,
2622
0
         (p->dstadr != NULL)
2623
0
        ? &p->dstadr->sin
2624
0
        : NULL);
2625
0
    break;
2626
2627
0
  case CP_DSTPORT:
2628
0
    ctl_putuint(peer_var[id].text,
2629
0
          (p->dstadr != NULL)
2630
0
        ? SRCPORT(&p->dstadr->sin)
2631
0
        : 0);
2632
0
    break;
2633
2634
0
  case CP_IN:
2635
0
    if (p->r21 > 0.)
2636
0
      ctl_putdbl(peer_var[id].text, p->r21 / 1e3);
2637
0
    break;
2638
2639
0
  case CP_OUT:
2640
0
    if (p->r34 > 0.)
2641
0
      ctl_putdbl(peer_var[id].text, p->r34 / 1e3);
2642
0
    break;
2643
2644
0
  case CP_RATE:
2645
0
    ctl_putuint(peer_var[id].text, p->throttle);
2646
0
    break;
2647
2648
0
  case CP_LEAP:
2649
0
    ctl_putuint(peer_var[id].text, p->leap);
2650
0
    break;
2651
2652
0
  case CP_HMODE:
2653
0
    ctl_putuint(peer_var[id].text, p->hmode);
2654
0
    break;
2655
2656
0
  case CP_STRATUM:
2657
0
    ctl_putuint(peer_var[id].text, p->stratum);
2658
0
    break;
2659
2660
0
  case CP_PPOLL:
2661
0
    ctl_putuint(peer_var[id].text, p->ppoll);
2662
0
    break;
2663
2664
0
  case CP_HPOLL:
2665
0
    ctl_putuint(peer_var[id].text, p->hpoll);
2666
0
    break;
2667
2668
0
  case CP_PRECISION:
2669
0
    ctl_putint(peer_var[id].text, p->precision);
2670
0
    break;
2671
2672
0
  case CP_ROOTDELAY:
2673
0
    ctl_putdbl(peer_var[id].text, p->rootdelay * 1e3);
2674
0
    break;
2675
2676
0
  case CP_ROOTDISPERSION:
2677
0
    ctl_putdbl(peer_var[id].text, p->rootdisp * 1e3);
2678
0
    break;
2679
2680
0
  case CP_REFID:
2681
0
#ifdef REFCLOCK
2682
0
    if (p->flags & FLAG_REFCLOCK) {
2683
0
      ctl_putrefid(peer_var[id].text, p->refid);
2684
0
      break;
2685
0
    }
2686
0
#endif
2687
0
    if (REFID_ISTEXT(p->stratum))
2688
0
      ctl_putrefid(peer_var[id].text, p->refid);
2689
0
    else
2690
0
      ctl_putadr(peer_var[id].text, p->refid, NULL);
2691
0
    break;
2692
2693
0
  case CP_REFTIME:
2694
0
    ctl_putts(peer_var[id].text, &p->reftime);
2695
0
    break;
2696
2697
0
  case CP_ORG:
2698
0
    ctl_putts(peer_var[id].text, &p->aorg);
2699
0
    break;
2700
2701
0
  case CP_REC:
2702
0
    ctl_putts(peer_var[id].text, &p->dst);
2703
0
    break;
2704
2705
0
  case CP_XMT:
2706
0
    if (p->xleave)
2707
0
      ctl_putdbl(peer_var[id].text, p->xleave * 1e3);
2708
0
    break;
2709
2710
0
  case CP_BIAS:
2711
0
    if (p->bias != 0.)
2712
0
      ctl_putdbl(peer_var[id].text, p->bias * 1e3);
2713
0
    break;
2714
2715
0
  case CP_REACH:
2716
0
    ctl_puthex(peer_var[id].text, p->reach);
2717
0
    break;
2718
2719
0
  case CP_FLASH:
2720
0
    ctl_puthex(peer_var[id].text, p->flash);
2721
0
    break;
2722
2723
0
  case CP_TTL:
2724
0
#ifdef REFCLOCK
2725
0
    if (p->flags & FLAG_REFCLOCK) {
2726
0
      ctl_putuint(peer_var[id].text, p->ttl);
2727
0
      break;
2728
0
    }
2729
0
#endif
2730
0
    if (p->ttl > 0 && p->ttl < COUNTOF(sys_ttl))
2731
0
      ctl_putint(peer_var[id].text,
2732
0
           sys_ttl[p->ttl]);
2733
0
    break;
2734
2735
0
  case CP_UNREACH:
2736
0
    ctl_putuint(peer_var[id].text, p->unreach);
2737
0
    break;
2738
2739
0
  case CP_TIMER:
2740
0
    ctl_putuint(peer_var[id].text,
2741
0
          p->nextdate - current_time);
2742
0
    break;
2743
2744
0
  case CP_DELAY:
2745
0
    ctl_putdbl(peer_var[id].text, p->delay * 1e3);
2746
0
    break;
2747
2748
0
  case CP_OFFSET:
2749
0
    ctl_putdbl(peer_var[id].text, p->offset * 1e3);
2750
0
    break;
2751
2752
0
  case CP_JITTER:
2753
0
    ctl_putdbl(peer_var[id].text, p->jitter * 1e3);
2754
0
    break;
2755
2756
0
  case CP_DISPERSION:
2757
0
    ctl_putdbl(peer_var[id].text, p->disp * 1e3);
2758
0
    break;
2759
2760
0
  case CP_KEYID:
2761
0
    if (p->keyid > NTP_MAXKEY)
2762
0
      ctl_puthex(peer_var[id].text, p->keyid);
2763
0
    else
2764
0
      ctl_putuint(peer_var[id].text, p->keyid);
2765
0
    break;
2766
2767
0
  case CP_FILTDELAY:
2768
0
    ctl_putarray(peer_var[id].text, p->filter_delay,
2769
0
           p->filter_nextpt);
2770
0
    break;
2771
2772
0
  case CP_FILTOFFSET:
2773
0
    ctl_putarray(peer_var[id].text, p->filter_offset,
2774
0
           p->filter_nextpt);
2775
0
    break;
2776
2777
0
  case CP_FILTERROR:
2778
0
    ctl_putarray(peer_var[id].text, p->filter_disp,
2779
0
           p->filter_nextpt);
2780
0
    break;
2781
2782
0
  case CP_PMODE:
2783
0
    ctl_putuint(peer_var[id].text, p->pmode);
2784
0
    break;
2785
2786
0
  case CP_RECEIVED:
2787
0
    ctl_putuint(peer_var[id].text, p->received);
2788
0
    break;
2789
2790
0
  case CP_SENT:
2791
0
    ctl_putuint(peer_var[id].text, p->sent);
2792
0
    break;
2793
2794
0
  case CP_VARLIST:
2795
0
    s = buf;
2796
0
    be = buf + sizeof(buf);
2797
0
    if (strlen(peer_var[id].text) + 4 > sizeof(buf))
2798
0
      break; /* really long var name */
2799
2800
0
    snprintf(s, sizeof(buf), "%s=\"", peer_var[id].text);
2801
0
    s += strlen(s);
2802
0
    t = s;
2803
0
    for (k = peer_var; !(EOV & k->flags); k++) {
2804
0
      if (PADDING & k->flags)
2805
0
        continue;
2806
0
      i = strlen(k->text);
2807
0
      if (s + i + 1 >= be)
2808
0
        break;
2809
0
      if (s != t)
2810
0
        *s++ = ',';
2811
0
      memcpy(s, k->text, i);
2812
0
      s += i;
2813
0
    }
2814
0
    if (s + 2 < be) {
2815
0
      *s++ = '"';
2816
0
      *s = '\0';
2817
0
      ctl_putdata(buf, (u_int)(s - buf), 0);
2818
0
    }
2819
0
    break;
2820
2821
0
  case CP_TIMEREC:
2822
0
    ctl_putuint(peer_var[id].text,
2823
0
          current_time - p->timereceived);
2824
0
    break;
2825
2826
0
  case CP_TIMEREACH:
2827
0
    ctl_putuint(peer_var[id].text,
2828
0
          current_time - p->timereachable);
2829
0
    break;
2830
2831
0
  case CP_BADAUTH:
2832
0
    ctl_putuint(peer_var[id].text, p->badauth);
2833
0
    break;
2834
2835
0
  case CP_BOGUSORG:
2836
0
    ctl_putuint(peer_var[id].text, p->bogusorg);
2837
0
    break;
2838
2839
0
  case CP_OLDPKT:
2840
0
    ctl_putuint(peer_var[id].text, p->oldpkt);
2841
0
    break;
2842
2843
0
  case CP_SELDISP:
2844
0
    ctl_putuint(peer_var[id].text, p->seldisptoolarge);
2845
0
    break;
2846
2847
0
  case CP_SELBROKEN:
2848
0
    ctl_putuint(peer_var[id].text, p->selbroken);
2849
0
    break;
2850
2851
0
  case CP_CANDIDATE:
2852
0
    ctl_putuint(peer_var[id].text, p->status);
2853
0
    break;
2854
#ifdef AUTOKEY
2855
  case CP_FLAGS:
2856
    if (p->crypto)
2857
      ctl_puthex(peer_var[id].text, p->crypto);
2858
    break;
2859
2860
  case CP_SIGNATURE:
2861
    if (p->crypto) {
2862
      dp = EVP_get_digestbynid(p->crypto >> 16);
2863
      str = OBJ_nid2ln(EVP_MD_pkey_type(dp));
2864
      ctl_putstr(peer_var[id].text, str, strlen(str));
2865
    }
2866
    break;
2867
2868
  case CP_HOST:
2869
    if (p->subject != NULL)
2870
      ctl_putstr(peer_var[id].text, p->subject,
2871
          strlen(p->subject));
2872
    break;
2873
2874
  case CP_VALID:    /* not used */
2875
    break;
2876
2877
  case CP_INITSEQ:
2878
    if (NULL == (ap = p->recval.ptr))
2879
      break;
2880
2881
    ctl_putint(peer_var[CP_INITSEQ].text, ap->seq);
2882
    ctl_puthex(peer_var[CP_INITKEY].text, ap->key);
2883
    ctl_putfs(peer_var[CP_INITTSP].text,
2884
        ntohl(p->recval.tstamp));
2885
    break;
2886
2887
  case CP_IDENT:
2888
    if (p->ident != NULL)
2889
      ctl_putstr(peer_var[id].text, p->ident,
2890
          strlen(p->ident));
2891
    break;
2892
2893
2894
#endif  /* AUTOKEY */
2895
0
  }
2896
0
}
2897
2898
2899
#ifdef REFCLOCK
2900
/*
2901
 * ctl_putclock - output clock variables
2902
 */
2903
static void
2904
ctl_putclock(
2905
  int id,
2906
  struct refclockstat *pcs,
2907
  int mustput
2908
  )
2909
0
{
2910
0
  char buf[CTL_MAX_DATA_LEN];
2911
0
  char *s, *t, *be;
2912
0
  const char *ss;
2913
0
  int i;
2914
0
  const struct ctl_var *k;
2915
2916
0
  switch (id) {
2917
2918
0
  case CC_TYPE:
2919
0
    if (mustput || pcs->clockdesc == NULL
2920
0
        || *(pcs->clockdesc) == '\0') {
2921
0
      ctl_putuint(clock_var[id].text, pcs->type);
2922
0
    }
2923
0
    break;
2924
0
  case CC_TIMECODE:
2925
0
    ctl_putstr(clock_var[id].text,
2926
0
         pcs->p_lastcode,
2927
0
         (unsigned)pcs->lencode);
2928
0
    break;
2929
2930
0
  case CC_POLL:
2931
0
    ctl_putuint(clock_var[id].text, pcs->polls);
2932
0
    break;
2933
2934
0
  case CC_NOREPLY:
2935
0
    ctl_putuint(clock_var[id].text,
2936
0
          pcs->noresponse);
2937
0
    break;
2938
2939
0
  case CC_BADFORMAT:
2940
0
    ctl_putuint(clock_var[id].text,
2941
0
          pcs->badformat);
2942
0
    break;
2943
2944
0
  case CC_BADDATA:
2945
0
    ctl_putuint(clock_var[id].text,
2946
0
          pcs->baddata);
2947
0
    break;
2948
2949
0
  case CC_FUDGETIME1:
2950
0
    if (mustput || (pcs->haveflags & CLK_HAVETIME1))
2951
0
      ctl_putdbl(clock_var[id].text,
2952
0
           pcs->fudgetime1 * 1e3);
2953
0
    break;
2954
2955
0
  case CC_FUDGETIME2:
2956
0
    if (mustput || (pcs->haveflags & CLK_HAVETIME2))
2957
0
      ctl_putdbl(clock_var[id].text,
2958
0
           pcs->fudgetime2 * 1e3);
2959
0
    break;
2960
2961
0
  case CC_FUDGEVAL1:
2962
0
    if (mustput || (pcs->haveflags & CLK_HAVEVAL1))
2963
0
      ctl_putint(clock_var[id].text,
2964
0
           pcs->fudgeval1);
2965
0
    break;
2966
2967
0
  case CC_FUDGEVAL2:
2968
0
    if (mustput || (pcs->haveflags & CLK_HAVEVAL2)) {
2969
0
      if (pcs->fudgeval1 > 1)
2970
0
        ctl_putadr(clock_var[id].text,
2971
0
             pcs->fudgeval2, NULL);
2972
0
      else
2973
0
        ctl_putrefid(clock_var[id].text,
2974
0
               pcs->fudgeval2);
2975
0
    }
2976
0
    break;
2977
2978
0
  case CC_FLAGS:
2979
0
    ctl_putuint(clock_var[id].text, pcs->flags);
2980
0
    break;
2981
2982
0
  case CC_DEVICE:
2983
0
    if (pcs->clockdesc == NULL ||
2984
0
        *(pcs->clockdesc) == '\0') {
2985
0
      if (mustput)
2986
0
        ctl_putstr(clock_var[id].text,
2987
0
             "", 0);
2988
0
    } else {
2989
0
      ctl_putstr(clock_var[id].text,
2990
0
           pcs->clockdesc,
2991
0
           strlen(pcs->clockdesc));
2992
0
    }
2993
0
    break;
2994
2995
0
  case CC_VARLIST:
2996
0
    s = buf;
2997
0
    be = buf + sizeof(buf);
2998
0
    if (strlen(clock_var[CC_VARLIST].text) + 4 >
2999
0
        sizeof(buf))
3000
0
      break; /* really long var name */
3001
3002
0
    snprintf(s, sizeof(buf), "%s=\"",
3003
0
       clock_var[CC_VARLIST].text);
3004
0
    s += strlen(s);
3005
0
    t = s;
3006
3007
0
    for (k = clock_var; !(EOV & k->flags); k++) {
3008
0
      if (PADDING & k->flags)
3009
0
        continue;
3010
3011
0
      i = strlen(k->text);
3012
0
      if (s + i + 1 >= be)
3013
0
        break;
3014
3015
0
      if (s != t)
3016
0
        *s++ = ',';
3017
0
      memcpy(s, k->text, i);
3018
0
      s += i;
3019
0
    }
3020
3021
0
    for (k = pcs->kv_list; k && !(EOV & k->flags); k++) {
3022
0
      if (PADDING & k->flags)
3023
0
        continue;
3024
3025
0
      ss = k->text;
3026
0
      if (NULL == ss)
3027
0
        continue;
3028
3029
0
      while (*ss && *ss != '=')
3030
0
        ss++;
3031
0
      i = ss - k->text;
3032
0
      if (s + i + 1 >= be)
3033
0
        break;
3034
3035
0
      if (s != t)
3036
0
        *s++ = ',';
3037
0
      memcpy(s, k->text, (unsigned)i);
3038
0
      s += i;
3039
0
      *s = '\0';
3040
0
    }
3041
0
    if (s + 2 >= be)
3042
0
      break;
3043
3044
0
    *s++ = '"';
3045
0
    *s = '\0';
3046
0
    ctl_putdata(buf, (unsigned)(s - buf), 0);
3047
0
    break;
3048
0
  }
3049
0
}
3050
#endif
3051
3052
3053
3054
/*
3055
 * ctl_getitem - get the next data item from the incoming packet
3056
 */
3057
static const struct ctl_var *
3058
ctl_getitem(
3059
  const struct ctl_var *var_list,
3060
  char **data
3061
  )
3062
3.03k
{
3063
  /* [Bug 3008] First check the packet data sanity, then search
3064
   * the key. This improves the consistency of result values: If
3065
   * the result is NULL once, it will never be EOV again for this
3066
   * packet; If it's EOV, it will never be NULL again until the
3067
   * variable is found and processed in a given 'var_list'. (That
3068
   * is, a result is returned that is neither NULL nor EOV).
3069
   */
3070
3.03k
  static const struct ctl_var eol = { 0, EOV, NULL };
3071
3.03k
  static char buf[128];
3072
3.03k
  static u_long quiet_until;
3073
3.03k
  const struct ctl_var *v;
3074
3.03k
  char *cp;
3075
3.03k
  char *tp;
3076
3077
  /*
3078
   * Part One: Validate the packet state
3079
   */
3080
3081
  /* Delete leading commas and white space */
3082
3.75k
  while (reqpt < reqend && (*reqpt == ',' ||
3083
3.55k
          isspace((unsigned char)*reqpt)))
3084
712
    reqpt++;
3085
3.03k
  if (reqpt >= reqend)
3086
198
    return NULL;
3087
3088
  /* Scan the string in the packet until we hit comma or
3089
   * EoB. Register position of first '=' on the fly. */
3090
41.3k
  for (tp = NULL, cp = reqpt; cp != reqend; ++cp) {
3091
40.7k
    if (*cp == '=' && tp == NULL)
3092
2.27k
      tp = cp;
3093
40.7k
    if (*cp == ',')
3094
2.20k
      break;
3095
40.7k
  }
3096
3097
  /* Process payload, if any. */
3098
2.84k
  *data = NULL;
3099
2.84k
  if (NULL != tp) {
3100
    /* eventually strip white space from argument. */
3101
2.27k
    const char *plhead = tp + 1; /* skip the '=' */
3102
2.27k
    const char *pltail = cp;
3103
2.27k
    size_t      plsize;
3104
3105
2.56k
    while (plhead != pltail && isspace((u_char)plhead[0]))
3106
290
      ++plhead;
3107
2.49k
    while (plhead != pltail && isspace((u_char)pltail[-1]))
3108
226
      --pltail;
3109
3110
    /* check payload size, terminate packet on overflow */
3111
2.27k
    plsize = (size_t)(pltail - plhead);
3112
2.27k
    if (plsize >= sizeof(buf))
3113
8
      goto badpacket;
3114
3115
    /* copy data, NUL terminate, and set result data ptr */
3116
2.26k
    memcpy(buf, plhead, plsize);
3117
2.26k
    buf[plsize] = '\0';
3118
2.26k
    *data = buf;
3119
2.26k
  } else {
3120
    /* no payload, current end --> current name termination */
3121
569
    tp = cp;
3122
569
  }
3123
3124
  /* Part Two
3125
   *
3126
   * Now we're sure that the packet data itself is sane. Scan the
3127
   * list now. Make sure a NULL list is properly treated by
3128
   * returning a synthetic End-Of-Values record. We must not
3129
   * return NULL pointers after this point, or the behaviour would
3130
   * become inconsistent if called several times with different
3131
   * variable lists after an EoV was returned.  (Such a behavior
3132
   * actually caused Bug 3008.)
3133
   */
3134
3135
2.83k
  if (NULL == var_list)
3136
74
    return &eol;
3137
3138
30.1k
  for (v = var_list; !(EOV & v->flags); ++v)
3139
29.9k
    if (!(PADDING & v->flags)) {
3140
      /* Check if the var name matches the buffer. The
3141
       * name is bracketed by [reqpt..tp] and not NUL
3142
       * terminated, and it contains no '=' char. The
3143
       * lookup value IS NUL-terminated but might
3144
       * include a '='... We have to look out for
3145
       * that!
3146
       */
3147
29.3k
      const char *sp1 = reqpt;
3148
29.3k
      const char *sp2 = v->text;
3149
3150
      /* [Bug 3412] do not compare past NUL byte in name */
3151
50.3k
      while (   (sp1 != tp)
3152
50.3k
             && ('\0' != *sp2) && (*sp1 == *sp2)) {
3153
21.0k
        ++sp1;
3154
21.0k
        ++sp2;
3155
21.0k
      }
3156
29.3k
      if (sp1 == tp && (*sp2 == '\0' || *sp2 == '='))
3157
2.64k
        break;
3158
29.3k
    }
3159
3160
  /* See if we have found a valid entry or not. If found, advance
3161
   * the request pointer for the next round; if not, clear the
3162
   * data pointer so we have no dangling garbage here.
3163
   */
3164
2.75k
  if (EOV & v->flags)
3165
114
    *data = NULL;
3166
2.64k
  else
3167
2.64k
    reqpt = cp + (cp != reqend);
3168
2.75k
  return v;
3169
3170
8
  badpacket:
3171
  /*TODO? somehow indicate this packet was bad, apart from syslog? */
3172
8
  numctlbadpkts++;
3173
8
  NLOG(NLOG_SYSEVENT)
3174
8
      if (quiet_until <= current_time) {
3175
1
        quiet_until = current_time + 300;
3176
1
        msyslog(LOG_WARNING,
3177
1
          "Possible 'ntpdx' exploit from %s#%u (possibly spoofed)",
3178
1
          stoa(rmt_addr), SRCPORT(rmt_addr));
3179
1
      }
3180
8
  reqpt = reqend; /* never again for this packet! */
3181
8
  return NULL;
3182
2.83k
}
3183
3184
3185
/*
3186
 * control_unspec - response to an unspecified op-code
3187
 */
3188
/*ARGSUSED*/
3189
static void
3190
control_unspec(
3191
  struct recvbuf *rbufp,
3192
  int restrict_mask
3193
  )
3194
59
{
3195
59
  struct peer *peer;
3196
3197
  /*
3198
   * What is an appropriate response to an unspecified op-code?
3199
   * I return no errors and no data, unless a specified assocation
3200
   * doesn't exist.
3201
   */
3202
59
  if (res_associd) {
3203
50
    peer = findpeerbyassoc(res_associd);
3204
50
    if (NULL == peer) {
3205
50
      ctl_error(CERR_BADASSOC);
3206
50
      return;
3207
50
    }
3208
0
    rpkt.status = htons(ctlpeerstatus(peer));
3209
0
  } else
3210
9
    rpkt.status = htons(ctlsysstatus());
3211
9
  ctl_flushpkt(0);
3212
9
}
3213
3214
3215
/*
3216
 * read_status - return either a list of associd's, or a particular
3217
 * peer's status.
3218
 */
3219
/*ARGSUSED*/
3220
static void
3221
read_status(
3222
  struct recvbuf *rbufp,
3223
  int restrict_mask
3224
  )
3225
41
{
3226
41
  struct peer *peer;
3227
41
  const u_char *cp;
3228
41
  size_t n;
3229
  /* a_st holds association ID, status pairs alternating */
3230
41
  u_short a_st[CTL_MAX_DATA_LEN / sizeof(u_short)];
3231
3232
41
#ifdef DEBUG
3233
41
  if (debug > 2)
3234
0
    printf("read_status: ID %d\n", res_associd);
3235
41
#endif
3236
  /*
3237
   * Two choices here. If the specified association ID is
3238
   * zero we return all known assocation ID's.  Otherwise
3239
   * we return a bunch of stuff about the particular peer.
3240
   */
3241
41
  if (res_associd) {
3242
36
    peer = findpeerbyassoc(res_associd);
3243
36
    if (NULL == peer) {
3244
36
      ctl_error(CERR_BADASSOC);
3245
36
      return;
3246
36
    }
3247
0
    rpkt.status = htons(ctlpeerstatus(peer));
3248
0
    if (res_authokay)
3249
0
      peer->num_events = 0;
3250
    /*
3251
     * For now, output everything we know about the
3252
     * peer. May be more selective later.
3253
     */
3254
0
    for (cp = def_peer_var; *cp != 0; cp++)
3255
0
      ctl_putpeer((int)*cp, peer);
3256
0
    ctl_flushpkt(0);
3257
0
    return;
3258
36
  }
3259
5
  n = 0;
3260
5
  rpkt.status = htons(ctlsysstatus());
3261
5
  for (peer = peer_list; peer != NULL; peer = peer->p_link) {
3262
0
    a_st[n++] = htons(peer->associd);
3263
0
    a_st[n++] = htons(ctlpeerstatus(peer));
3264
    /* two entries each loop iteration, so n + 1 */
3265
0
    if (n + 1 >= COUNTOF(a_st)) {
3266
0
      ctl_putdata((void *)a_st, n * sizeof(a_st[0]),
3267
0
            1);
3268
0
      n = 0;
3269
0
    }
3270
0
  }
3271
5
  if (n)
3272
0
    ctl_putdata((void *)a_st, n * sizeof(a_st[0]), 1);
3273
5
  ctl_flushpkt(0);
3274
5
}
3275
3276
3277
/*
3278
 * read_peervars - half of read_variables() implementation
3279
 */
3280
static void
3281
read_peervars(void)
3282
33
{
3283
33
  const struct ctl_var *v;
3284
33
  struct peer *peer;
3285
33
  const u_char *cp;
3286
33
  size_t i;
3287
33
  char *  valuep;
3288
33
  u_char  wants[CP_MAXCODE + 1];
3289
33
  u_int gotvar;
3290
3291
  /*
3292
   * Wants info for a particular peer. See if we know
3293
   * the guy.
3294
   */
3295
33
  peer = findpeerbyassoc(res_associd);
3296
33
  if (NULL == peer) {
3297
33
    ctl_error(CERR_BADASSOC);
3298
33
    return;
3299
33
  }
3300
0
  rpkt.status = htons(ctlpeerstatus(peer));
3301
0
  if (res_authokay)
3302
0
    peer->num_events = 0;
3303
0
  ZERO(wants);
3304
0
  gotvar = 0;
3305
0
  while (NULL != (v = ctl_getitem(peer_var, &valuep))) {
3306
0
    if (v->flags & EOV) {
3307
0
      ctl_error(CERR_UNKNOWNVAR);
3308
0
      return;
3309
0
    }
3310
0
    INSIST(v->code < COUNTOF(wants));
3311
0
    wants[v->code] = 1;
3312
0
    gotvar = 1;
3313
0
  }
3314
0
  if (gotvar) {
3315
0
    for (i = 1; i < COUNTOF(wants); i++)
3316
0
      if (wants[i])
3317
0
        ctl_putpeer(i, peer);
3318
0
  } else
3319
0
    for (cp = def_peer_var; *cp != 0; cp++)
3320
0
      ctl_putpeer((int)*cp, peer);
3321
0
  ctl_flushpkt(0);
3322
0
}
3323
3324
3325
/*
3326
 * read_sysvars - half of read_variables() implementation
3327
 */
3328
static void
3329
read_sysvars(void)
3330
132
{
3331
132
  const struct ctl_var *v;
3332
132
  struct ctl_var *kv;
3333
132
  u_int n;
3334
132
  u_int gotvar;
3335
132
  const u_char *cs;
3336
132
  char *  valuep;
3337
132
  const char * pch;
3338
132
  u_char *wants;
3339
132
  size_t  wants_count;
3340
3341
  /*
3342
   * Wants system variables. Figure out which he wants
3343
   * and give them to him.
3344
   */
3345
132
  rpkt.status = htons(ctlsysstatus());
3346
132
  if (res_authokay)
3347
0
    ctl_sys_num_events = 0;
3348
132
  wants_count = CS_MAXCODE + 1 + count_var(ext_sys_var);
3349
132
  wants = emalloc_zero(wants_count);
3350
132
  gotvar = 0;
3351
739
  while (NULL != (v = ctl_getitem(sys_var, &valuep))) {
3352
681
    if (!(EOV & v->flags)) {
3353
607
      INSIST(v->code < wants_count);
3354
0
      wants[v->code] = 1;
3355
607
      gotvar = 1;
3356
607
    } else {
3357
74
      v = ctl_getitem(ext_sys_var, &valuep);
3358
74
      if (NULL == v) {
3359
0
        ctl_error(CERR_BADVALUE);
3360
0
        free(wants);
3361
0
        return;
3362
0
      }
3363
74
      if (EOV & v->flags) {
3364
74
        ctl_error(CERR_UNKNOWNVAR);
3365
74
        free(wants);
3366
74
        return;
3367
74
      }
3368
0
      n = v->code + CS_MAXCODE + 1;
3369
0
      INSIST(n < wants_count);
3370
0
      wants[n] = 1;
3371
0
      gotvar = 1;
3372
0
    }
3373
681
  }
3374
58
  if (gotvar) {
3375
2.16k
    for (n = 1; n <= CS_MAXCODE; n++)
3376
2.13k
      if (wants[n])
3377
52
        ctl_putsys(n);
3378
23
    for (n = 0; n + CS_MAXCODE + 1 < wants_count; n++)
3379
0
      if (wants[n + CS_MAXCODE + 1]) {
3380
0
        pch = ext_sys_var[n].text;
3381
0
        ctl_putdata(pch, strlen(pch), 0);
3382
0
      }
3383
35
  } else {
3384
875
    for (cs = def_sys_var; *cs != 0; cs++)
3385
840
      ctl_putsys((int)*cs);
3386
35
    for (kv = ext_sys_var; kv && !(EOV & kv->flags); kv++)
3387
0
      if (DEF & kv->flags)
3388
0
        ctl_putdata(kv->text, strlen(kv->text),
3389
0
              0);
3390
35
  }
3391
58
  free(wants);
3392
58
  ctl_flushpkt(0);
3393
58
}
3394
3395
3396
/*
3397
 * read_variables - return the variables the caller asks for
3398
 */
3399
/*ARGSUSED*/
3400
static void
3401
read_variables(
3402
  struct recvbuf *rbufp,
3403
  int restrict_mask
3404
  )
3405
165
{
3406
165
  if (res_associd)
3407
33
    read_peervars();
3408
132
  else
3409
132
    read_sysvars();
3410
165
}
3411
3412
3413
/*
3414
 * write_variables - write into variables. We only allow leap bit
3415
 * writing this way.
3416
 */
3417
/*ARGSUSED*/
3418
static void
3419
write_variables(
3420
  struct recvbuf *rbufp,
3421
  int restrict_mask
3422
  )
3423
0
{
3424
0
  const struct ctl_var *v;
3425
0
  int ext_var;
3426
0
  char *valuep;
3427
0
  long val;
3428
0
  size_t octets;
3429
0
  char *vareqv;
3430
0
  const char *t;
3431
0
  char *tt;
3432
3433
0
  val = 0;
3434
  /*
3435
   * If he's trying to write into a peer tell him no way
3436
   */
3437
0
  if (res_associd != 0) {
3438
0
    ctl_error(CERR_PERMISSION);
3439
0
    return;
3440
0
  }
3441
3442
  /*
3443
   * Set status
3444
   */
3445
0
  rpkt.status = htons(ctlsysstatus());
3446
3447
  /*
3448
   * Look through the variables. Dump out at the first sign of
3449
   * trouble.
3450
   */
3451
0
  while ((v = ctl_getitem(sys_var, &valuep)) != NULL) {
3452
0
    ext_var = 0;
3453
0
    if (v->flags & EOV) {
3454
0
      v = ctl_getitem(ext_sys_var, &valuep);
3455
0
      if (v != NULL) {
3456
0
        if (v->flags & EOV) {
3457
0
          ctl_error(CERR_UNKNOWNVAR);
3458
0
          return;
3459
0
        }
3460
0
        ext_var = 1;
3461
0
      } else {
3462
0
        break;
3463
0
      }
3464
0
    }
3465
0
    if (!(v->flags & CAN_WRITE)) {
3466
0
      ctl_error(CERR_PERMISSION);
3467
0
      return;
3468
0
    }
3469
    /* [bug 3565] writing makes sense only if we *have* a
3470
     * value in the packet!
3471
     */
3472
0
    if (valuep == NULL) {
3473
0
      ctl_error(CERR_BADFMT);
3474
0
      return;
3475
0
    }
3476
0
    if (!ext_var) {
3477
0
      if ( !(*valuep && atoint(valuep, &val))) {
3478
0
        ctl_error(CERR_BADFMT);
3479
0
        return;
3480
0
      }
3481
0
      if ((val & ~LEAP_NOTINSYNC) != 0) {
3482
0
        ctl_error(CERR_BADVALUE);
3483
0
        return;
3484
0
      }
3485
0
    }
3486
    
3487
0
    if (ext_var) {
3488
0
      octets = strlen(v->text) + strlen(valuep) + 2;
3489
0
      vareqv = emalloc(octets);
3490
0
      tt = vareqv;
3491
0
      t = v->text;
3492
0
      while (*t && *t != '=')
3493
0
        *tt++ = *t++;
3494
0
      *tt++ = '=';
3495
0
      memcpy(tt, valuep, 1 + strlen(valuep));
3496
0
      set_sys_var(vareqv, 1 + strlen(vareqv), v->flags);
3497
0
      free(vareqv);
3498
0
    } else {
3499
0
      ctl_error(CERR_UNSPEC); /* really */
3500
0
      return;
3501
0
    }
3502
0
  }
3503
3504
  /*
3505
   * If we got anything, do it. xxx nothing to do ***
3506
   */
3507
  /*
3508
    if (leapind != ~0 || leapwarn != ~0) {
3509
    if (!leap_setleap((int)leapind, (int)leapwarn)) {
3510
    ctl_error(CERR_PERMISSION);
3511
    return;
3512
    }
3513
    }
3514
  */
3515
0
  ctl_flushpkt(0);
3516
0
}
3517
3518
3519
/*
3520
 * configure() processes ntpq :config/config-from-file, allowing
3521
 *    generic runtime reconfiguration.
3522
 */
3523
static void configure(
3524
  struct recvbuf *rbufp,
3525
  int restrict_mask
3526
  )
3527
0
{
3528
0
  size_t data_count;
3529
0
  int retval;
3530
3531
  /* I haven't yet implemented changes to an existing association.
3532
   * Hence check if the association id is 0
3533
   */
3534
0
  if (res_associd != 0) {
3535
0
    ctl_error(CERR_BADVALUE);
3536
0
    return;
3537
0
  }
3538
3539
0
  if (RES_NOMODIFY & restrict_mask) {
3540
0
    snprintf(remote_config.err_msg,
3541
0
       sizeof(remote_config.err_msg),
3542
0
       "runtime configuration prohibited by restrict ... nomodify");
3543
0
    ctl_putdata(remote_config.err_msg,
3544
0
          strlen(remote_config.err_msg), 0);
3545
0
    ctl_flushpkt(0);
3546
0
    NLOG(NLOG_SYSINFO)
3547
0
      msyslog(LOG_NOTICE,
3548
0
        "runtime config from %s rejected due to nomodify restriction",
3549
0
        stoa(&rbufp->recv_srcadr));
3550
0
    sys_restricted++;
3551
0
    return;
3552
0
  }
3553
3554
  /* Initialize the remote config buffer */
3555
0
  data_count = remoteconfig_cmdlength(reqpt, reqend);
3556
3557
0
  if (data_count > sizeof(remote_config.buffer) - 2) {
3558
0
    snprintf(remote_config.err_msg,
3559
0
       sizeof(remote_config.err_msg),
3560
0
       "runtime configuration failed: request too long");
3561
0
    ctl_putdata(remote_config.err_msg,
3562
0
          strlen(remote_config.err_msg), 0);
3563
0
    ctl_flushpkt(0);
3564
0
    msyslog(LOG_NOTICE,
3565
0
      "runtime config from %s rejected: request too long",
3566
0
      stoa(&rbufp->recv_srcadr));
3567
0
    return;
3568
0
  }
3569
  /* Bug 2853 -- check if all characters were acceptable */
3570
0
  if (data_count != (size_t)(reqend - reqpt)) {
3571
0
    snprintf(remote_config.err_msg,
3572
0
       sizeof(remote_config.err_msg),
3573
0
       "runtime configuration failed: request contains an unprintable character");
3574
0
    ctl_putdata(remote_config.err_msg,
3575
0
          strlen(remote_config.err_msg), 0);
3576
0
    ctl_flushpkt(0);
3577
0
    msyslog(LOG_NOTICE,
3578
0
      "runtime config from %s rejected: request contains an unprintable character: %0x",
3579
0
      stoa(&rbufp->recv_srcadr),
3580
0
      reqpt[data_count]);
3581
0
    return;
3582
0
  }
3583
3584
0
  memcpy(remote_config.buffer, reqpt, data_count);
3585
  /* The buffer has no trailing linefeed or NUL right now. For
3586
   * logging, we do not want a newline, so we do that first after
3587
   * adding the necessary NUL byte.
3588
   */
3589
0
  remote_config.buffer[data_count] = '\0';
3590
0
  DPRINTF(1, ("Got Remote Configuration Command: %s\n",
3591
0
    remote_config.buffer));
3592
0
  msyslog(LOG_NOTICE, "%s config: %s",
3593
0
    stoa(&rbufp->recv_srcadr),
3594
0
    remote_config.buffer);
3595
3596
  /* Now we have to make sure there is a NL/NUL sequence at the
3597
   * end of the buffer before we parse it.
3598
   */
3599
0
  remote_config.buffer[data_count++] = '\n';
3600
0
  remote_config.buffer[data_count] = '\0';
3601
0
  remote_config.pos = 0;
3602
0
  remote_config.err_pos = 0;
3603
0
  remote_config.no_errors = 0;
3604
0
  config_remotely(&rbufp->recv_srcadr);
3605
3606
  /*
3607
   * Check if errors were reported. If not, output 'Config
3608
   * Succeeded'.  Else output the error count.  It would be nice
3609
   * to output any parser error messages.
3610
   */
3611
0
  if (0 == remote_config.no_errors) {
3612
0
    retval = snprintf(remote_config.err_msg,
3613
0
          sizeof(remote_config.err_msg),
3614
0
          "Config Succeeded");
3615
0
    if (retval > 0)
3616
0
      remote_config.err_pos += retval;
3617
0
  }
3618
3619
0
  ctl_putdata(remote_config.err_msg, remote_config.err_pos, 0);
3620
0
  ctl_flushpkt(0);
3621
3622
0
  DPRINTF(1, ("Reply: %s\n", remote_config.err_msg));
3623
3624
0
  if (remote_config.no_errors > 0)
3625
0
    msyslog(LOG_NOTICE, "%d error in %s config",
3626
0
      remote_config.no_errors,
3627
0
      stoa(&rbufp->recv_srcadr));
3628
0
}
3629
3630
3631
/*
3632
 * derive_nonce - generate client-address-specific nonce value
3633
 *      associated with a given timestamp.
3634
 */
3635
static u_int32 derive_nonce(
3636
  sockaddr_u *  addr,
3637
  u_int32   ts_i,
3638
  u_int32   ts_f
3639
  )
3640
124
{
3641
124
  static u_int32  salt[4];
3642
124
  static u_long last_salt_update;
3643
124
  union d_tag {
3644
124
    u_char  digest[EVP_MAX_MD_SIZE];
3645
124
    u_int32 extract;
3646
124
  }   d;
3647
124
  EVP_MD_CTX  *ctx;
3648
124
  u_int   len;
3649
3650
125
  while (!salt[0] || current_time - last_salt_update >= 3600) {
3651
1
    salt[0] = ntp_random();
3652
1
    salt[1] = ntp_random();
3653
1
    salt[2] = ntp_random();
3654
1
    salt[3] = ntp_random();
3655
1
    last_salt_update = current_time;
3656
1
  }
3657
3658
124
  ctx = EVP_MD_CTX_new();
3659
#   if defined(OPENSSL) && defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
3660
  /* [Bug 3457] set flags and don't kill them again */
3661
  EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
3662
  EVP_DigestInit_ex(ctx, EVP_get_digestbynid(NID_md5), NULL);
3663
#   else
3664
124
  EVP_DigestInit(ctx, EVP_get_digestbynid(NID_md5));
3665
124
#   endif
3666
124
  EVP_DigestUpdate(ctx, salt, sizeof(salt));
3667
124
  EVP_DigestUpdate(ctx, &ts_i, sizeof(ts_i));
3668
124
  EVP_DigestUpdate(ctx, &ts_f, sizeof(ts_f));
3669
124
  if (IS_IPV4(addr))
3670
124
    EVP_DigestUpdate(ctx, &SOCK_ADDR4(addr),
3671
123
               sizeof(SOCK_ADDR4(addr)));
3672
123
  else
3673
124
    EVP_DigestUpdate(ctx, &SOCK_ADDR6(addr),
3674
124
               sizeof(SOCK_ADDR6(addr)));
3675
124
  EVP_DigestUpdate(ctx, &NSRCPORT(addr), sizeof(NSRCPORT(addr)));
3676
124
  EVP_DigestUpdate(ctx, salt, sizeof(salt));
3677
124
  EVP_DigestFinal(ctx, d.digest, &len);
3678
124
  EVP_MD_CTX_free(ctx);
3679
3680
124
  return d.extract;
3681
124
}
3682
3683
3684
/*
3685
 * generate_nonce - generate client-address-specific nonce string.
3686
 */
3687
static void generate_nonce(
3688
  struct recvbuf *  rbufp,
3689
  char *      nonce,
3690
  size_t      nonce_octets
3691
  )
3692
37
{
3693
37
  u_int32 derived;
3694
3695
37
  derived = derive_nonce(&rbufp->recv_srcadr,
3696
37
             rbufp->recv_time.l_ui,
3697
37
             rbufp->recv_time.l_uf);
3698
37
  snprintf(nonce, nonce_octets, "%08x%08x%08x",
3699
37
     rbufp->recv_time.l_ui, rbufp->recv_time.l_uf, derived);
3700
37
}
3701
3702
3703
/*
3704
 * validate_nonce - validate client-address-specific nonce string.
3705
 *
3706
 * Returns TRUE if the local calculation of the nonce matches the
3707
 * client-provided value and the timestamp is recent enough.
3708
 */
3709
static int validate_nonce(
3710
  const char *    pnonce,
3711
  struct recvbuf *  rbufp
3712
  )
3713
101
{
3714
101
  u_int ts_i;
3715
101
  u_int ts_f;
3716
101
  l_fp  ts;
3717
101
  l_fp  now_delta;
3718
101
  u_int supposed;
3719
101
  u_int derived;
3720
3721
101
  if (3 != sscanf(pnonce, "%08x%08x%08x", &ts_i, &ts_f, &supposed))
3722
14
    return FALSE;
3723
3724
87
  ts.l_ui = (u_int32)ts_i;
3725
87
  ts.l_uf = (u_int32)ts_f;
3726
87
  derived = derive_nonce(&rbufp->recv_srcadr, ts.l_ui, ts.l_uf);
3727
87
  get_systime(&now_delta);
3728
87
  L_SUB(&now_delta, &ts);
3729
3730
87
  return (supposed == derived && now_delta.l_ui < 16);
3731
101
}
3732
3733
3734
/*
3735
 * send_random_tag_value - send a randomly-generated three character
3736
 *         tag prefix, a '.', an index, a '=' and a
3737
 *         random integer value.
3738
 *
3739
 * To try to force clients to ignore unrecognized tags in mrulist,
3740
 * reslist, and ifstats responses, the first and last rows are spiced
3741
 * with randomly-generated tag names with correct .# index.  Make it
3742
 * three characters knowing that none of the currently-used subscripted
3743
 * tags have that length, avoiding the need to test for
3744
 * tag collision.
3745
 */
3746
static void
3747
send_random_tag_value(
3748
  int indx
3749
  )
3750
0
{
3751
0
  int noise;
3752
0
  char  buf[32];
3753
3754
0
  noise = rand() ^ (rand() << 16);
3755
0
  buf[0] = 'a' + noise % 26;
3756
0
  noise >>= 5;
3757
0
  buf[1] = 'a' + noise % 26;
3758
0
  noise >>= 5;
3759
0
  buf[2] = 'a' + noise % 26;
3760
0
  noise >>= 5;
3761
0
  buf[3] = '.';
3762
0
  snprintf(&buf[4], sizeof(buf) - 4, "%d", indx);
3763
0
  ctl_putuint(buf, noise);
3764
0
}
3765
3766
3767
/*
3768
 * Send a MRU list entry in response to a "ntpq -c mrulist" operation.
3769
 *
3770
 * To keep clients honest about not depending on the order of values,
3771
 * and thereby avoid being locked into ugly workarounds to maintain
3772
 * backward compatibility later as new fields are added to the response,
3773
 * the order is random.
3774
 */
3775
static void
3776
send_mru_entry(
3777
  mon_entry * mon,
3778
  int   count
3779
  )
3780
0
{
3781
0
  const char first_fmt[] =  "first.%d";
3782
0
  const char ct_fmt[] =   "ct.%d";
3783
0
  const char mv_fmt[] =   "mv.%d";
3784
0
  const char rs_fmt[] =   "rs.%d";
3785
0
  char  tag[32];
3786
0
  u_char  sent[6]; /* 6 tag=value pairs */
3787
0
  u_int32 noise;
3788
0
  u_int which;
3789
0
  u_int remaining;
3790
0
  const char * pch;
3791
3792
0
  remaining = COUNTOF(sent);
3793
0
  ZERO(sent);
3794
0
  noise = (u_int32)(rand() ^ (rand() << 16));
3795
0
  while (remaining > 0) {
3796
0
    which = (noise & 7) % COUNTOF(sent);
3797
0
    noise >>= 3;
3798
0
    while (sent[which])
3799
0
      which = (which + 1) % COUNTOF(sent);
3800
3801
0
    switch (which) {
3802
3803
0
    case 0:
3804
0
      snprintf(tag, sizeof(tag), addr_fmt, count);
3805
0
      pch = sptoa(&mon->rmtadr);
3806
0
      ctl_putunqstr(tag, pch, strlen(pch));
3807
0
      break;
3808
3809
0
    case 1:
3810
0
      snprintf(tag, sizeof(tag), last_fmt, count);
3811
0
      ctl_putts(tag, &mon->last);
3812
0
      break;
3813
3814
0
    case 2:
3815
0
      snprintf(tag, sizeof(tag), first_fmt, count);
3816
0
      ctl_putts(tag, &mon->first);
3817
0
      break;
3818
3819
0
    case 3:
3820
0
      snprintf(tag, sizeof(tag), ct_fmt, count);
3821
0
      ctl_putint(tag, mon->count);
3822
0
      break;
3823
3824
0
    case 4:
3825
0
      snprintf(tag, sizeof(tag), mv_fmt, count);
3826
0
      ctl_putuint(tag, mon->vn_mode);
3827
0
      break;
3828
3829
0
    case 5:
3830
0
      snprintf(tag, sizeof(tag), rs_fmt, count);
3831
0
      ctl_puthex(tag, mon->flags);
3832
0
      break;
3833
0
    }
3834
0
    sent[which] = TRUE;
3835
0
    remaining--;
3836
0
  }
3837
0
}
3838
3839
3840
/*
3841
 * read_mru_list - supports ntpq's mrulist command.
3842
 *
3843
 * The challenge here is to match ntpdc's monlist functionality without
3844
 * being limited to hundreds of entries returned total, and without
3845
 * requiring state on the server.  If state were required, ntpq's
3846
 * mrulist command would require authentication.
3847
 *
3848
 * The approach was suggested by Ry Jones.  A finite and variable number
3849
 * of entries are retrieved per request, to avoid having responses with
3850
 * such large numbers of packets that socket buffers are overflowed and
3851
 * packets lost.  The entries are retrieved oldest-first, taking into
3852
 * account that the MRU list will be changing between each request.  We
3853
 * can expect to see duplicate entries for addresses updated in the MRU
3854
 * list during the fetch operation.  In the end, the client can assemble
3855
 * a close approximation of the MRU list at the point in time the last
3856
 * response was sent by ntpd.  The only difference is it may be longer,
3857
 * containing some number of oldest entries which have since been
3858
 * reclaimed.  If necessary, the protocol could be extended to zap those
3859
 * from the client snapshot at the end, but so far that doesn't seem
3860
 * useful.
3861
 *
3862
 * To accomodate the changing MRU list, the starting point for requests
3863
 * after the first request is supplied as a series of last seen
3864
 * timestamps and associated addresses, the newest ones the client has
3865
 * received.  As long as at least one of those entries hasn't been
3866
 * bumped to the head of the MRU list, ntpd can pick up at that point.
3867
 * Otherwise, the request is failed and it is up to ntpq to back up and
3868
 * provide the next newest entry's timestamps and addresses, conceivably
3869
 * backing up all the way to the starting point.
3870
 *
3871
 * input parameters:
3872
 *  nonce=    Regurgitated nonce retrieved by the client
3873
 *      previously using CTL_OP_REQ_NONCE, demonstrating
3874
 *      ability to receive traffic sent to its address.
3875
 *  frags=    Limit on datagrams (fragments) in response.  Used
3876
 *      by newer ntpq versions instead of limit= when
3877
 *      retrieving multiple entries.
3878
 *  limit=    Limit on MRU entries returned.  One of frags= or
3879
 *      limit= must be provided.
3880
 *      limit=1 is a special case:  Instead of fetching
3881
 *      beginning with the supplied starting point's
3882
 *      newer neighbor, fetch the supplied entry, and
3883
 *      in that case the #.last timestamp can be zero.
3884
 *      This enables fetching a single entry by IP
3885
 *      address.  When limit is not one and frags= is
3886
 *      provided, the fragment limit controls.
3887
 *  mincount= (decimal) Return entries with count >= mincount.
3888
 *  laddr=    Return entries associated with the server's IP
3889
 *      address given.  No port specification is needed,
3890
 *      and any supplied is ignored.
3891
 *  resall=   0x-prefixed hex restrict bits which must all be
3892
 *      lit for an MRU entry to be included.
3893
 *      Has precedence over any resany=.
3894
 *  resany=   0x-prefixed hex restrict bits, at least one of
3895
 *      which must be list for an MRU entry to be
3896
 *      included.
3897
 *  last.0=   0x-prefixed hex l_fp timestamp of newest entry
3898
 *      which client previously received.
3899
 *  addr.0=   text of newest entry's IP address and port,
3900
 *      IPv6 addresses in bracketed form: [::]:123
3901
 *  last.1=   timestamp of 2nd newest entry client has.
3902
 *  addr.1=   address of 2nd newest entry.
3903
 *  [...]
3904
 *
3905
 * ntpq provides as many last/addr pairs as will fit in a single request
3906
 * packet, except for the first request in a MRU fetch operation.
3907
 *
3908
 * The response begins with a new nonce value to be used for any
3909
 * followup request.  Following the nonce is the next newer entry than
3910
 * referred to by last.0 and addr.0, if the "0" entry has not been
3911
 * bumped to the front.  If it has, the first entry returned will be the
3912
 * next entry newer than referred to by last.1 and addr.1, and so on.
3913
 * If none of the referenced entries remain unchanged, the request fails
3914
 * and ntpq backs up to the next earlier set of entries to resync.
3915
 *
3916
 * Except for the first response, the response begins with confirmation
3917
 * of the entry that precedes the first additional entry provided:
3918
 *
3919
 *  last.older= hex l_fp timestamp matching one of the input
3920
 *      .last timestamps, which entry now precedes the
3921
 *      response 0. entry in the MRU list.
3922
 *  addr.older= text of address corresponding to older.last.
3923
 *
3924
 * And in any case, a successful response contains sets of values
3925
 * comprising entries, with the oldest numbered 0 and incrementing from
3926
 * there:
3927
 *
3928
 *  addr.#    text of IPv4 or IPv6 address and port
3929
 *  last.#    hex l_fp timestamp of last receipt
3930
 *  first.#   hex l_fp timestamp of first receipt
3931
 *  ct.#    count of packets received
3932
 *  mv.#    mode and version
3933
 *  rs.#    restriction mask (RES_* bits)
3934
 *
3935
 * Note the code currently assumes there are no valid three letter
3936
 * tags sent with each row, and needs to be adjusted if that changes.
3937
 *
3938
 * The client should accept the values in any order, and ignore .#
3939
 * values which it does not understand, to allow a smooth path to
3940
 * future changes without requiring a new opcode.  Clients can rely
3941
 * on all *.0 values preceding any *.1 values, that is all values for
3942
 * a given index number are together in the response.
3943
 *
3944
 * The end of the response list is noted with one or two tag=value
3945
 * pairs.  Unconditionally:
3946
 *
3947
 *  now=    0x-prefixed l_fp timestamp at the server marking
3948
 *      the end of the operation.
3949
 *
3950
 * If any entries were returned, now= is followed by:
3951
 *
3952
 *  last.newest=  hex l_fp identical to last.# of the prior
3953
 *      entry.
3954
 */
3955
static void read_mru_list(
3956
  struct recvbuf *rbufp,
3957
  int restrict_mask
3958
  )
3959
866
{
3960
866
  static const char nulltxt[1] =    { '\0' };
3961
866
  static const char nonce_text[] =    "nonce";
3962
866
  static const char frags_text[] =    "frags";
3963
866
  static const char limit_text[] =    "limit";
3964
866
  static const char mincount_text[] = "mincount";
3965
866
  static const char resall_text[] =   "resall";
3966
866
  static const char resany_text[] =   "resany";
3967
866
  static const char maxlstint_text[] =  "maxlstint";
3968
866
  static const char laddr_text[] =    "laddr";
3969
866
  static const char resaxx_fmt[] =    "0x%hx";
3970
3971
866
  u_int     limit;
3972
866
  u_short     frags;
3973
866
  u_short     resall;
3974
866
  u_short     resany;
3975
866
  int     mincount;
3976
866
  u_int     maxlstint;
3977
866
  sockaddr_u    laddr;
3978
866
  struct interface *  lcladr;
3979
866
  u_int     count;
3980
866
  u_int     ui;
3981
866
  u_int     uf;
3982
866
  l_fp      last[16];
3983
866
  sockaddr_u    addr[COUNTOF(last)];
3984
866
  char      buf[128];
3985
866
  struct ctl_var *  in_parms;
3986
866
  const struct ctl_var *  v;
3987
866
  const char *    val;
3988
866
  const char *    pch;
3989
866
  char *      pnonce;
3990
866
  int     nonce_valid;
3991
866
  size_t      i;
3992
866
  int     priors;
3993
866
  u_short     hash;
3994
866
  mon_entry *   mon;
3995
866
  mon_entry *   prior_mon;
3996
866
  l_fp      now;
3997
3998
866
  if (RES_NOMRULIST & restrict_mask) {
3999
0
    ctl_error(CERR_PERMISSION);
4000
0
    NLOG(NLOG_SYSINFO)
4001
0
      msyslog(LOG_NOTICE,
4002
0
        "mrulist from %s rejected due to nomrulist restriction",
4003
0
        stoa(&rbufp->recv_srcadr));
4004
0
    sys_restricted++;
4005
0
    return;
4006
0
  }
4007
  /*
4008
   * fill in_parms var list with all possible input parameters.
4009
   */
4010
866
  in_parms = NULL;
4011
866
  set_var(&in_parms, nonce_text, sizeof(nonce_text), 0);
4012
866
  set_var(&in_parms, frags_text, sizeof(frags_text), 0);
4013
866
  set_var(&in_parms, limit_text, sizeof(limit_text), 0);
4014
866
  set_var(&in_parms, mincount_text, sizeof(mincount_text), 0);
4015
866
  set_var(&in_parms, resall_text, sizeof(resall_text), 0);
4016
866
  set_var(&in_parms, resany_text, sizeof(resany_text), 0);
4017
866
  set_var(&in_parms, maxlstint_text, sizeof(maxlstint_text), 0);
4018
866
  set_var(&in_parms, laddr_text, sizeof(laddr_text), 0);
4019
14.7k
  for (i = 0; i < COUNTOF(last); i++) {
4020
13.8k
    snprintf(buf, sizeof(buf), last_fmt, (int)i);
4021
13.8k
    set_var(&in_parms, buf, strlen(buf) + 1, 0);
4022
13.8k
    snprintf(buf, sizeof(buf), addr_fmt, (int)i);
4023
13.8k
    set_var(&in_parms, buf, strlen(buf) + 1, 0);
4024
13.8k
  }
4025
4026
  /* decode input parms */
4027
866
  pnonce = NULL;
4028
866
  frags = 0;
4029
866
  limit = 0;
4030
866
  mincount = 0;
4031
866
  resall = 0;
4032
866
  resany = 0;
4033
866
  maxlstint = 0;
4034
866
  lcladr = NULL;
4035
866
  priors = 0;
4036
866
  ZERO(last);
4037
866
  ZERO(addr);
4038
4039
  /* have to go through '(void*)' to drop 'const' property from pointer.
4040
   * ctl_getitem()' needs some cleanup, too.... perlinger@ntp.org
4041
   */
4042
2.22k
  while (NULL != (v = ctl_getitem(in_parms, (void*)&val)) &&
4043
2.22k
         !(EOV & v->flags)) {
4044
2.03k
    int si;
4045
4046
2.03k
    if (NULL == val)
4047
277
      val = nulltxt;
4048
4049
2.03k
    if (!strcmp(nonce_text, v->text)) {
4050
519
      free(pnonce);
4051
519
      pnonce = (*val) ? estrdup(val) : NULL;
4052
1.51k
    } else if (!strcmp(frags_text, v->text)) {
4053
197
      if (1 != sscanf(val, "%hu", &frags))
4054
3
        goto blooper;
4055
1.32k
    } else if (!strcmp(limit_text, v->text)) {
4056
145
      if (1 != sscanf(val, "%u", &limit))
4057
2
        goto blooper;
4058
1.17k
    } else if (!strcmp(mincount_text, v->text)) {
4059
154
      if (1 != sscanf(val, "%d", &mincount))
4060
0
        goto blooper;
4061
154
      if (mincount < 0)
4062
78
        mincount = 0;
4063
1.02k
    } else if (!strcmp(resall_text, v->text)) {
4064
70
      if (1 != sscanf(val, resaxx_fmt, &resall))
4065
2
        goto blooper;
4066
952
    } else if (!strcmp(resany_text, v->text)) {
4067
48
      if (1 != sscanf(val, resaxx_fmt, &resany))
4068
2
        goto blooper;
4069
904
    } else if (!strcmp(maxlstint_text, v->text)) {
4070
77
      if (1 != sscanf(val, "%u", &maxlstint))
4071
2
        goto blooper;
4072
827
    } else if (!strcmp(laddr_text, v->text)) {
4073
313
      if (!decodenetnum(val, &laddr))
4074
313
        goto blooper;
4075
0
      lcladr = getinterface(&laddr, 0);
4076
514
    } else if (1 == sscanf(v->text, last_fmt, &si) &&
4077
514
         (size_t)si < COUNTOF(last)) {
4078
165
      if (2 != sscanf(val, "0x%08x.%08x", &ui, &uf))
4079
5
        goto blooper;
4080
160
      last[si].l_ui = ui;
4081
160
      last[si].l_uf = uf;
4082
160
      if (!SOCK_UNSPEC(&addr[si]) && si == priors)
4083
0
        priors++;
4084
349
    } else if (1 == sscanf(v->text, addr_fmt, &si) &&
4085
349
         (size_t)si < COUNTOF(addr)) {
4086
349
      if (!decodenetnum(val, &addr[si]))
4087
349
        goto blooper;
4088
0
      if (last[si].l_ui && last[si].l_uf && si == priors)
4089
0
        priors++;
4090
0
    } else {
4091
0
      DPRINTF(1, ("read_mru_list: invalid key item: '%s' (ignored)\n",
4092
0
            v->text));
4093
0
      continue;
4094
4095
678
    blooper:
4096
678
      DPRINTF(1, ("read_mru_list: invalid param for '%s': '%s' (bailing)\n",
4097
678
            v->text, val));
4098
678
      free(pnonce);
4099
678
      pnonce = NULL;
4100
678
      break;
4101
0
    }
4102
2.03k
  }
4103
866
  free_varlist(in_parms);
4104
866
  in_parms = NULL;
4105
4106
  /* return no responses until the nonce is validated */
4107
866
  if (NULL == pnonce)
4108
765
    return;
4109
4110
101
  nonce_valid = validate_nonce(pnonce, rbufp);
4111
101
  free(pnonce);
4112
101
  if (!nonce_valid)
4113
101
    return;
4114
4115
0
  if ((0 == frags && !(0 < limit && limit <= MRU_ROW_LIMIT)) ||
4116
0
      frags > MRU_FRAGS_LIMIT) {
4117
0
    ctl_error(CERR_BADVALUE);
4118
0
    return;
4119
0
  }
4120
4121
  /*
4122
   * If either frags or limit is not given, use the max.
4123
   */
4124
0
  if (0 != frags && 0 == limit)
4125
0
    limit = UINT_MAX;
4126
0
  else if (0 != limit && 0 == frags)
4127
0
    frags = MRU_FRAGS_LIMIT;
4128
4129
  /*
4130
   * Find the starting point if one was provided.
4131
   */
4132
0
  mon = NULL;
4133
0
  for (i = 0; i < (size_t)priors; i++) {
4134
0
    hash = MON_HASH(&addr[i]);
4135
0
    for (mon = mon_hash[hash];
4136
0
         mon != NULL;
4137
0
         mon = mon->hash_next)
4138
0
      if (ADDR_PORT_EQ(&mon->rmtadr, &addr[i]))
4139
0
        break;
4140
0
    if (mon != NULL) {
4141
0
      if (L_ISEQU(&mon->last, &last[i]))
4142
0
        break;
4143
0
      mon = NULL;
4144
0
    }
4145
0
  }
4146
4147
  /* If a starting point was provided... */
4148
0
  if (priors) {
4149
    /* and none could be found unmodified... */
4150
0
    if (NULL == mon) {
4151
      /* tell ntpq to try again with older entries */
4152
0
      ctl_error(CERR_UNKNOWNVAR);
4153
0
      return;
4154
0
    }
4155
    /* confirm the prior entry used as starting point */
4156
0
    ctl_putts("last.older", &mon->last);
4157
0
    pch = sptoa(&mon->rmtadr);
4158
0
    ctl_putunqstr("addr.older", pch, strlen(pch));
4159
4160
    /*
4161
     * Move on to the first entry the client doesn't have,
4162
     * except in the special case of a limit of one.  In
4163
     * that case return the starting point entry.
4164
     */
4165
0
    if (limit > 1)
4166
0
      mon = PREV_DLIST(mon_mru_list, mon, mru);
4167
0
  } else { /* start with the oldest */
4168
0
    mon = TAIL_DLIST(mon_mru_list, mru);
4169
0
  }
4170
4171
  /*
4172
   * send up to limit= entries in up to frags= datagrams
4173
   */
4174
0
  get_systime(&now);
4175
0
  generate_nonce(rbufp, buf, sizeof(buf));
4176
0
  ctl_putunqstr("nonce", buf, strlen(buf));
4177
0
  prior_mon = NULL;
4178
0
  for (count = 0;
4179
0
       mon != NULL && res_frags < frags && count < limit;
4180
0
       mon = PREV_DLIST(mon_mru_list, mon, mru)) {
4181
4182
0
    if (mon->count < mincount)
4183
0
      continue;
4184
0
    if (resall && resall != (resall & mon->flags))
4185
0
      continue;
4186
0
    if (resany && !(resany & mon->flags))
4187
0
      continue;
4188
0
    if (maxlstint > 0 && now.l_ui - mon->last.l_ui >
4189
0
        maxlstint)
4190
0
      continue;
4191
0
    if (lcladr != NULL && mon->lcladr != lcladr)
4192
0
      continue;
4193
4194
0
    send_mru_entry(mon, count);
4195
0
    if (!count)
4196
0
      send_random_tag_value(0);
4197
0
    count++;
4198
0
    prior_mon = mon;
4199
0
  }
4200
4201
  /*
4202
   * If this batch completes the MRU list, say so explicitly with
4203
   * a now= l_fp timestamp.
4204
   */
4205
0
  if (NULL == mon) {
4206
0
    if (count > 1)
4207
0
      send_random_tag_value(count - 1);
4208
0
    ctl_putts("now", &now);
4209
    /* if any entries were returned confirm the last */
4210
0
    if (prior_mon != NULL)
4211
0
      ctl_putts("last.newest", &prior_mon->last);
4212
0
  }
4213
0
  ctl_flushpkt(0);
4214
0
}
4215
4216
4217
/*
4218
 * Send a ifstats entry in response to a "ntpq -c ifstats" request.
4219
 *
4220
 * To keep clients honest about not depending on the order of values,
4221
 * and thereby avoid being locked into ugly workarounds to maintain
4222
 * backward compatibility later as new fields are added to the response,
4223
 * the order is random.
4224
 */
4225
static void
4226
send_ifstats_entry(
4227
  endpt * la,
4228
  u_int ifnum
4229
  )
4230
0
{
4231
0
  const char addr_fmtu[] =  "addr.%u";
4232
0
  const char bcast_fmt[] =  "bcast.%u";
4233
0
  const char en_fmt[] =   "en.%u";  /* enabled */
4234
0
  const char name_fmt[] =   "name.%u";
4235
0
  const char flags_fmt[] =  "flags.%u";
4236
0
  const char tl_fmt[] =   "tl.%u";  /* ttl */
4237
0
  const char mc_fmt[] =   "mc.%u";  /* mcast count */
4238
0
  const char rx_fmt[] =   "rx.%u";
4239
0
  const char tx_fmt[] =   "tx.%u";
4240
0
  const char txerr_fmt[] =  "txerr.%u";
4241
0
  const char pc_fmt[] =   "pc.%u";  /* peer count */
4242
0
  const char up_fmt[] =   "up.%u";  /* uptime */
4243
0
  char  tag[32];
4244
0
  u_char  sent[IFSTATS_FIELDS]; /* 12 tag=value pairs */
4245
0
  int noisebits;
4246
0
  u_int32 noise;
4247
0
  u_int which;
4248
0
  u_int remaining;
4249
0
  const char *pch;
4250
4251
0
  remaining = COUNTOF(sent);
4252
0
  ZERO(sent);
4253
0
  noise = 0;
4254
0
  noisebits = 0;
4255
0
  while (remaining > 0) {
4256
0
    if (noisebits < 4) {
4257
0
      noise = rand() ^ (rand() << 16);
4258
0
      noisebits = 31;
4259
0
    }
4260
0
    which = (noise & 0xf) % COUNTOF(sent);
4261
0
    noise >>= 4;
4262
0
    noisebits -= 4;
4263
4264
0
    while (sent[which])
4265
0
      which = (which + 1) % COUNTOF(sent);
4266
4267
0
    switch (which) {
4268
4269
0
    case 0:
4270
0
      snprintf(tag, sizeof(tag), addr_fmtu, ifnum);
4271
0
      pch = sptoa(&la->sin);
4272
0
      ctl_putunqstr(tag, pch, strlen(pch));
4273
0
      break;
4274
4275
0
    case 1:
4276
0
      snprintf(tag, sizeof(tag), bcast_fmt, ifnum);
4277
0
      if (INT_BCASTOPEN & la->flags)
4278
0
        pch = sptoa(&la->bcast);
4279
0
      else
4280
0
        pch = "";
4281
0
      ctl_putunqstr(tag, pch, strlen(pch));
4282
0
      break;
4283
4284
0
    case 2:
4285
0
      snprintf(tag, sizeof(tag), en_fmt, ifnum);
4286
0
      ctl_putint(tag, !la->ignore_packets);
4287
0
      break;
4288
4289
0
    case 3:
4290
0
      snprintf(tag, sizeof(tag), name_fmt, ifnum);
4291
0
      ctl_putstr(tag, la->name, strlen(la->name));
4292
0
      break;
4293
4294
0
    case 4:
4295
0
      snprintf(tag, sizeof(tag), flags_fmt, ifnum);
4296
0
      ctl_puthex(tag, (u_int)la->flags);
4297
0
      break;
4298
4299
0
    case 5:
4300
0
      snprintf(tag, sizeof(tag), tl_fmt, ifnum);
4301
0
      ctl_putint(tag, la->last_ttl);
4302
0
      break;
4303
4304
0
    case 6:
4305
0
      snprintf(tag, sizeof(tag), mc_fmt, ifnum);
4306
0
      ctl_putint(tag, la->num_mcast);
4307
0
      break;
4308
4309
0
    case 7:
4310
0
      snprintf(tag, sizeof(tag), rx_fmt, ifnum);
4311
0
      ctl_putint(tag, la->received);
4312
0
      break;
4313
4314
0
    case 8:
4315
0
      snprintf(tag, sizeof(tag), tx_fmt, ifnum);
4316
0
      ctl_putint(tag, la->sent);
4317
0
      break;
4318
4319
0
    case 9:
4320
0
      snprintf(tag, sizeof(tag), txerr_fmt, ifnum);
4321
0
      ctl_putint(tag, la->notsent);
4322
0
      break;
4323
4324
0
    case 10:
4325
0
      snprintf(tag, sizeof(tag), pc_fmt, ifnum);
4326
0
      ctl_putuint(tag, la->peercnt);
4327
0
      break;
4328
4329
0
    case 11:
4330
0
      snprintf(tag, sizeof(tag), up_fmt, ifnum);
4331
0
      ctl_putuint(tag, current_time - la->starttime);
4332
0
      break;
4333
0
    }
4334
0
    sent[which] = TRUE;
4335
0
    remaining--;
4336
0
  }
4337
0
  send_random_tag_value((int)ifnum);
4338
0
}
4339
4340
4341
/*
4342
 * read_ifstats - send statistics for each local address, exposed by
4343
 *      ntpq -c ifstats
4344
 */
4345
static void
4346
read_ifstats(
4347
  struct recvbuf *  rbufp
4348
  )
4349
0
{
4350
0
  u_int ifidx;
4351
0
  endpt * la;
4352
4353
  /*
4354
   * loop over [0..sys_ifnum] searching ep_list for each
4355
   * ifnum in turn.
4356
   */
4357
0
  for (ifidx = 0; ifidx < sys_ifnum; ifidx++) {
4358
0
    for (la = ep_list; la != NULL; la = la->elink)
4359
0
      if (ifidx == la->ifnum)
4360
0
        break;
4361
0
    if (NULL == la)
4362
0
      continue;
4363
    /* return stats for one local address */
4364
0
    send_ifstats_entry(la, ifidx);
4365
0
  }
4366
0
  ctl_flushpkt(0);
4367
0
}
4368
4369
static void
4370
sockaddrs_from_restrict_u(
4371
  sockaddr_u *  psaA,
4372
  sockaddr_u *  psaM,
4373
  restrict_u *  pres,
4374
  int   ipv6
4375
  )
4376
0
{
4377
0
  ZERO(*psaA);
4378
0
  ZERO(*psaM);
4379
0
  if (!ipv6) {
4380
0
    psaA->sa.sa_family = AF_INET;
4381
0
    psaA->sa4.sin_addr.s_addr = htonl(pres->u.v4.addr);
4382
0
    psaM->sa.sa_family = AF_INET;
4383
0
    psaM->sa4.sin_addr.s_addr = htonl(pres->u.v4.mask);
4384
0
  } else {
4385
0
    psaA->sa.sa_family = AF_INET6;
4386
0
    memcpy(&psaA->sa6.sin6_addr, &pres->u.v6.addr,
4387
0
           sizeof(psaA->sa6.sin6_addr));
4388
0
    psaM->sa.sa_family = AF_INET6;
4389
0
    memcpy(&psaM->sa6.sin6_addr, &pres->u.v6.mask,
4390
0
           sizeof(psaA->sa6.sin6_addr));
4391
0
  }
4392
0
}
4393
4394
4395
/*
4396
 * Send a restrict entry in response to a "ntpq -c reslist" request.
4397
 *
4398
 * To keep clients honest about not depending on the order of values,
4399
 * and thereby avoid being locked into ugly workarounds to maintain
4400
 * backward compatibility later as new fields are added to the response,
4401
 * the order is random.
4402
 */
4403
static void
4404
send_restrict_entry(
4405
  restrict_u *  pres,
4406
  int   ipv6,
4407
  u_int   idx
4408
  )
4409
0
{
4410
0
  const char addr_fmtu[] =  "addr.%u";
4411
0
  const char mask_fmtu[] =  "mask.%u";
4412
0
  const char hits_fmt[] =   "hits.%u";
4413
0
  const char flags_fmt[] =  "flags.%u";
4414
0
  char    tag[32];
4415
0
  u_char    sent[RESLIST_FIELDS]; /* 4 tag=value pairs */
4416
0
  int   noisebits;
4417
0
  u_int32   noise;
4418
0
  u_int   which;
4419
0
  u_int   remaining;
4420
0
  sockaddr_u  addr;
4421
0
  sockaddr_u  mask;
4422
0
  const char *  pch;
4423
0
  char *    buf;
4424
0
  const char *  match_str;
4425
0
  const char *  access_str;
4426
4427
0
  sockaddrs_from_restrict_u(&addr, &mask, pres, ipv6);
4428
0
  remaining = COUNTOF(sent);
4429
0
  ZERO(sent);
4430
0
  noise = 0;
4431
0
  noisebits = 0;
4432
0
  while (remaining > 0) {
4433
0
    if (noisebits < 2) {
4434
0
      noise = rand() ^ (rand() << 16);
4435
0
      noisebits = 31;
4436
0
    }
4437
0
    which = (noise & 0x3) % COUNTOF(sent);
4438
0
    noise >>= 2;
4439
0
    noisebits -= 2;
4440
4441
0
    while (sent[which])
4442
0
      which = (which + 1) % COUNTOF(sent);
4443
4444
    /* XXX: Numbers?  Really? */
4445
0
    switch (which) {
4446
4447
0
    case 0:
4448
0
      snprintf(tag, sizeof(tag), addr_fmtu, idx);
4449
0
      pch = stoa(&addr);
4450
0
      ctl_putunqstr(tag, pch, strlen(pch));
4451
0
      break;
4452
4453
0
    case 1:
4454
0
      snprintf(tag, sizeof(tag), mask_fmtu, idx);
4455
0
      pch = stoa(&mask);
4456
0
      ctl_putunqstr(tag, pch, strlen(pch));
4457
0
      break;
4458
4459
0
    case 2:
4460
0
      snprintf(tag, sizeof(tag), hits_fmt, idx);
4461
0
      ctl_putuint(tag, pres->count);
4462
0
      break;
4463
4464
0
    case 3:
4465
0
      snprintf(tag, sizeof(tag), flags_fmt, idx);
4466
0
      match_str = res_match_flags(pres->mflags);
4467
0
      access_str = res_access_flags(pres->rflags);
4468
0
      if ('\0' == match_str[0]) {
4469
0
        pch = access_str;
4470
0
      } else {
4471
0
        LIB_GETBUF(buf);
4472
0
        snprintf(buf, LIB_BUFLENGTH, "%s %s",
4473
0
           match_str, access_str);
4474
0
        pch = buf;
4475
0
      }
4476
0
      ctl_putunqstr(tag, pch, strlen(pch));
4477
0
      break;
4478
0
    }
4479
0
    sent[which] = TRUE;
4480
0
    remaining--;
4481
0
  }
4482
0
  send_random_tag_value((int)idx);
4483
0
}
4484
4485
4486
static void
4487
send_restrict_list(
4488
  restrict_u *  pres,
4489
  int   ipv6,
4490
  u_int *   pidx
4491
  )
4492
0
{
4493
0
  for ( ; pres != NULL; pres = pres->link) {
4494
0
    send_restrict_entry(pres, ipv6, *pidx);
4495
0
    (*pidx)++;
4496
0
  }
4497
0
}
4498
4499
4500
/*
4501
 * read_addr_restrictions - returns IPv4 and IPv6 access control lists
4502
 */
4503
static void
4504
read_addr_restrictions(
4505
  struct recvbuf *  rbufp
4506
)
4507
0
{
4508
0
  u_int idx;
4509
4510
0
  idx = 0;
4511
0
  send_restrict_list(restrictlist4, FALSE, &idx);
4512
0
  send_restrict_list(restrictlist6, TRUE, &idx);
4513
0
  ctl_flushpkt(0);
4514
0
}
4515
4516
4517
/*
4518
 * read_ordlist - CTL_OP_READ_ORDLIST_A for ntpq -c ifstats & reslist
4519
 */
4520
static void
4521
read_ordlist(
4522
  struct recvbuf *  rbufp,
4523
  int     restrict_mask
4524
  )
4525
0
{
4526
0
  const char ifstats_s[] = "ifstats";
4527
0
  const size_t ifstats_chars = COUNTOF(ifstats_s) - 1;
4528
0
  const char addr_rst_s[] = "addr_restrictions";
4529
0
  const size_t a_r_chars = COUNTOF(addr_rst_s) - 1;
4530
0
  struct ntp_control *  cpkt;
4531
0
  u_short     qdata_octets;
4532
4533
  /*
4534
   * CTL_OP_READ_ORDLIST_A was first named CTL_OP_READ_IFSTATS and
4535
   * used only for ntpq -c ifstats.  With the addition of reslist
4536
   * the same opcode was generalized to retrieve ordered lists
4537
   * which require authentication.  The request data is empty or
4538
   * contains "ifstats" (not null terminated) to retrieve local
4539
   * addresses and associated stats.  It is "addr_restrictions"
4540
   * to retrieve the IPv4 then IPv6 remote address restrictions,
4541
   * which are access control lists.  Other request data return
4542
   * CERR_UNKNOWNVAR.
4543
   */
4544
0
  cpkt = (struct ntp_control *)&rbufp->recv_pkt;
4545
0
  qdata_octets = ntohs(cpkt->count);
4546
0
  if (0 == qdata_octets || (ifstats_chars == qdata_octets &&
4547
0
      !memcmp(ifstats_s, cpkt->u.data, ifstats_chars))) {
4548
0
    read_ifstats(rbufp);
4549
0
    return;
4550
0
  }
4551
0
  if (a_r_chars == qdata_octets &&
4552
0
      !memcmp(addr_rst_s, cpkt->u.data, a_r_chars)) {
4553
0
    read_addr_restrictions(rbufp);
4554
0
    return;
4555
0
  }
4556
0
  ctl_error(CERR_UNKNOWNVAR);
4557
0
}
4558
4559
4560
/*
4561
 * req_nonce - CTL_OP_REQ_NONCE for ntpq -c mrulist prerequisite.
4562
 */
4563
static void req_nonce(
4564
  struct recvbuf *  rbufp,
4565
  int     restrict_mask
4566
  )
4567
37
{
4568
37
  char  buf[64];
4569
4570
37
  generate_nonce(rbufp, buf, sizeof(buf));
4571
37
  ctl_putunqstr("nonce", buf, strlen(buf));
4572
37
  ctl_flushpkt(0);
4573
37
}
4574
4575
4576
/*
4577
 * read_clockstatus - return clock radio status
4578
 */
4579
/*ARGSUSED*/
4580
static void
4581
read_clockstatus(
4582
  struct recvbuf *rbufp,
4583
  int restrict_mask
4584
  )
4585
40
{
4586
#ifndef REFCLOCK
4587
  /*
4588
   * If no refclock support, no data to return
4589
   */
4590
  ctl_error(CERR_BADASSOC);
4591
#else
4592
40
  const struct ctl_var *  v;
4593
40
  int     i;
4594
40
  struct peer *   peer;
4595
40
  char *      valuep;
4596
40
  u_char *    wants;
4597
40
  size_t      wants_alloc;
4598
40
  int     gotvar;
4599
40
  const u_char *    cc;
4600
40
  struct ctl_var *  kv;
4601
40
  struct refclockstat cs;
4602
4603
40
  if (res_associd != 0) {
4604
35
    peer = findpeerbyassoc(res_associd);
4605
35
  } else {
4606
    /*
4607
     * Find a clock for this jerk.  If the system peer
4608
     * is a clock use it, else search peer_list for one.
4609
     */
4610
5
    if (sys_peer != NULL && (FLAG_REFCLOCK &
4611
0
        sys_peer->flags))
4612
0
      peer = sys_peer;
4613
5
    else
4614
5
      for (peer = peer_list;
4615
5
           peer != NULL;
4616
5
           peer = peer->p_link)
4617
0
        if (FLAG_REFCLOCK & peer->flags)
4618
0
          break;
4619
5
  }
4620
40
  if (NULL == peer || !(FLAG_REFCLOCK & peer->flags)) {
4621
40
    ctl_error(CERR_BADASSOC);
4622
40
    return;
4623
40
  }
4624
  /*
4625
   * If we got here we have a peer which is a clock. Get his
4626
   * status.
4627
   */
4628
0
  cs.kv_list = NULL;
4629
0
  refclock_control(&peer->srcadr, NULL, &cs);
4630
0
  kv = cs.kv_list;
4631
  /*
4632
   * Look for variables in the packet.
4633
   */
4634
0
  rpkt.status = htons(ctlclkstatus(&cs));
4635
0
  wants_alloc = CC_MAXCODE + 1 + count_var(kv);
4636
0
  wants = emalloc_zero(wants_alloc);
4637
0
  gotvar = FALSE;
4638
0
  while (NULL != (v = ctl_getitem(clock_var, &valuep))) {
4639
0
    if (!(EOV & v->flags)) {
4640
0
      wants[v->code] = TRUE;
4641
0
      gotvar = TRUE;
4642
0
    } else {
4643
0
      v = ctl_getitem(kv, &valuep);
4644
0
      if (NULL == v) {
4645
0
        ctl_error(CERR_BADVALUE);
4646
0
        free(wants);
4647
0
        free_varlist(cs.kv_list);
4648
0
        return;
4649
0
      }
4650
0
      if (EOV & v->flags) {
4651
0
        ctl_error(CERR_UNKNOWNVAR);
4652
0
        free(wants);
4653
0
        free_varlist(cs.kv_list);
4654
0
        return;
4655
0
      }
4656
0
      wants[CC_MAXCODE + 1 + v->code] = TRUE;
4657
0
      gotvar = TRUE;
4658
0
    }
4659
0
  }
4660
4661
0
  if (gotvar) {
4662
0
    for (i = 1; i <= CC_MAXCODE; i++)
4663
0
      if (wants[i])
4664
0
        ctl_putclock(i, &cs, TRUE);
4665
0
    if (kv != NULL)
4666
0
      for (i = 0; !(EOV & kv[i].flags); i++)
4667
0
        if (wants[i + CC_MAXCODE + 1])
4668
0
          ctl_putdata(kv[i].text,
4669
0
                strlen(kv[i].text),
4670
0
                FALSE);
4671
0
  } else {
4672
0
    for (cc = def_clock_var; *cc != 0; cc++)
4673
0
      ctl_putclock((int)*cc, &cs, FALSE);
4674
0
    for ( ; kv != NULL && !(EOV & kv->flags); kv++)
4675
0
      if (DEF & kv->flags)
4676
0
        ctl_putdata(kv->text, strlen(kv->text),
4677
0
              FALSE);
4678
0
  }
4679
4680
0
  free(wants);
4681
0
  free_varlist(cs.kv_list);
4682
4683
0
  ctl_flushpkt(0);
4684
0
#endif
4685
0
}
4686
4687
4688
/*
4689
 * write_clockstatus - we don't do this
4690
 */
4691
/*ARGSUSED*/
4692
static void
4693
write_clockstatus(
4694
  struct recvbuf *rbufp,
4695
  int restrict_mask
4696
  )
4697
0
{
4698
0
  ctl_error(CERR_PERMISSION);
4699
0
}
4700
4701
/*
4702
 * Trap support from here on down. We send async trap messages when the
4703
 * upper levels report trouble. Traps can by set either by control
4704
 * messages or by configuration.
4705
 */
4706
/*
4707
 * set_trap - set a trap in response to a control message
4708
 */
4709
static void
4710
set_trap(
4711
  struct recvbuf *rbufp,
4712
  int restrict_mask
4713
  )
4714
0
{
4715
0
  int traptype;
4716
4717
  /*
4718
   * See if this guy is allowed
4719
   */
4720
0
  if (restrict_mask & RES_NOTRAP) {
4721
0
    ctl_error(CERR_PERMISSION);
4722
0
    return;
4723
0
  }
4724
4725
  /*
4726
   * Determine his allowed trap type.
4727
   */
4728
0
  traptype = TRAP_TYPE_PRIO;
4729
0
  if (restrict_mask & RES_LPTRAP)
4730
0
    traptype = TRAP_TYPE_NONPRIO;
4731
4732
  /*
4733
   * Call ctlsettrap() to do the work.  Return
4734
   * an error if it can't assign the trap.
4735
   */
4736
0
  if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype,
4737
0
      (int)res_version))
4738
0
    ctl_error(CERR_NORESOURCE);
4739
0
  ctl_flushpkt(0);
4740
0
}
4741
4742
4743
/*
4744
 * unset_trap - unset a trap in response to a control message
4745
 */
4746
static void
4747
unset_trap(
4748
  struct recvbuf *rbufp,
4749
  int restrict_mask
4750
  )
4751
0
{
4752
0
  int traptype;
4753
4754
  /*
4755
   * We don't prevent anyone from removing his own trap unless the
4756
   * trap is configured. Note we also must be aware of the
4757
   * possibility that restriction flags were changed since this
4758
   * guy last set his trap. Set the trap type based on this.
4759
   */
4760
0
  traptype = TRAP_TYPE_PRIO;
4761
0
  if (restrict_mask & RES_LPTRAP)
4762
0
    traptype = TRAP_TYPE_NONPRIO;
4763
4764
  /*
4765
   * Call ctlclrtrap() to clear this out.
4766
   */
4767
0
  if (!ctlclrtrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype))
4768
0
    ctl_error(CERR_BADASSOC);
4769
0
  ctl_flushpkt(0);
4770
0
}
4771
4772
4773
/*
4774
 * ctlsettrap - called to set a trap
4775
 */
4776
int
4777
ctlsettrap(
4778
  sockaddr_u *raddr,
4779
  struct interface *linter,
4780
  int traptype,
4781
  int version
4782
  )
4783
0
{
4784
0
  size_t n;
4785
0
  struct ctl_trap *tp;
4786
0
  struct ctl_trap *tptouse;
4787
4788
  /*
4789
   * See if we can find this trap.  If so, we only need update
4790
   * the flags and the time.
4791
   */
4792
0
  if ((tp = ctlfindtrap(raddr, linter)) != NULL) {
4793
0
    switch (traptype) {
4794
4795
0
    case TRAP_TYPE_CONFIG:
4796
0
      tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED;
4797
0
      break;
4798
4799
0
    case TRAP_TYPE_PRIO:
4800
0
      if (tp->tr_flags & TRAP_CONFIGURED)
4801
0
        return (1); /* don't change anything */
4802
0
      tp->tr_flags = TRAP_INUSE;
4803
0
      break;
4804
4805
0
    case TRAP_TYPE_NONPRIO:
4806
0
      if (tp->tr_flags & TRAP_CONFIGURED)
4807
0
        return (1); /* don't change anything */
4808
0
      tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO;
4809
0
      break;
4810
0
    }
4811
0
    tp->tr_settime = current_time;
4812
0
    tp->tr_resets++;
4813
0
    return (1);
4814
0
  }
4815
4816
  /*
4817
   * First we heard of this guy.  Try to find a trap structure
4818
   * for him to use, clearing out lesser priority guys if we
4819
   * have to. Clear out anyone who's expired while we're at it.
4820
   */
4821
0
  tptouse = NULL;
4822
0
  for (n = 0; n < COUNTOF(ctl_traps); n++) {
4823
0
    tp = &ctl_traps[n];
4824
0
    if ((TRAP_INUSE & tp->tr_flags) &&
4825
0
        !(TRAP_CONFIGURED & tp->tr_flags) &&
4826
0
        ((tp->tr_settime + CTL_TRAPTIME) > current_time)) {
4827
0
      tp->tr_flags = 0;
4828
0
      num_ctl_traps--;
4829
0
    }
4830
0
    if (!(TRAP_INUSE & tp->tr_flags)) {
4831
0
      tptouse = tp;
4832
0
    } else if (!(TRAP_CONFIGURED & tp->tr_flags)) {
4833
0
      switch (traptype) {
4834
4835
0
      case TRAP_TYPE_CONFIG:
4836
0
        if (tptouse == NULL) {
4837
0
          tptouse = tp;
4838
0
          break;
4839
0
        }
4840
0
        if ((TRAP_NONPRIO & tptouse->tr_flags) &&
4841
0
            !(TRAP_NONPRIO & tp->tr_flags))
4842
0
          break;
4843
4844
0
        if (!(TRAP_NONPRIO & tptouse->tr_flags)
4845
0
            && (TRAP_NONPRIO & tp->tr_flags)) {
4846
0
          tptouse = tp;
4847
0
          break;
4848
0
        }
4849
0
        if (tptouse->tr_origtime <
4850
0
            tp->tr_origtime)
4851
0
          tptouse = tp;
4852
0
        break;
4853
4854
0
      case TRAP_TYPE_PRIO:
4855
0
        if ( TRAP_NONPRIO & tp->tr_flags) {
4856
0
          if (tptouse == NULL ||
4857
0
              ((TRAP_INUSE &
4858
0
                tptouse->tr_flags) &&
4859
0
               tptouse->tr_origtime <
4860
0
               tp->tr_origtime))
4861
0
            tptouse = tp;
4862
0
        }
4863
0
        break;
4864
4865
0
      case TRAP_TYPE_NONPRIO:
4866
0
        break;
4867
0
      }
4868
0
    }
4869
0
  }
4870
4871
  /*
4872
   * If we don't have room for him return an error.
4873
   */
4874
0
  if (tptouse == NULL)
4875
0
    return (0);
4876
4877
  /*
4878
   * Set up this structure for him.
4879
   */
4880
0
  tptouse->tr_settime = tptouse->tr_origtime = current_time;
4881
0
  tptouse->tr_count = tptouse->tr_resets = 0;
4882
0
  tptouse->tr_sequence = 1;
4883
0
  tptouse->tr_addr = *raddr;
4884
0
  tptouse->tr_localaddr = linter;
4885
0
  tptouse->tr_version = (u_char) version;
4886
0
  tptouse->tr_flags = TRAP_INUSE;
4887
0
  if (traptype == TRAP_TYPE_CONFIG)
4888
0
    tptouse->tr_flags |= TRAP_CONFIGURED;
4889
0
  else if (traptype == TRAP_TYPE_NONPRIO)
4890
0
    tptouse->tr_flags |= TRAP_NONPRIO;
4891
0
  num_ctl_traps++;
4892
0
  return (1);
4893
0
}
4894
4895
4896
/*
4897
 * ctlclrtrap - called to clear a trap
4898
 */
4899
int
4900
ctlclrtrap(
4901
  sockaddr_u *raddr,
4902
  struct interface *linter,
4903
  int traptype
4904
  )
4905
0
{
4906
0
  register struct ctl_trap *tp;
4907
4908
0
  if ((tp = ctlfindtrap(raddr, linter)) == NULL)
4909
0
    return (0);
4910
4911
0
  if (tp->tr_flags & TRAP_CONFIGURED
4912
0
      && traptype != TRAP_TYPE_CONFIG)
4913
0
    return (0);
4914
4915
0
  tp->tr_flags = 0;
4916
0
  num_ctl_traps--;
4917
0
  return (1);
4918
0
}
4919
4920
4921
/*
4922
 * ctlfindtrap - find a trap given the remote and local addresses
4923
 */
4924
static struct ctl_trap *
4925
ctlfindtrap(
4926
  sockaddr_u *raddr,
4927
  struct interface *linter
4928
  )
4929
0
{
4930
0
  size_t  n;
4931
4932
0
  for (n = 0; n < COUNTOF(ctl_traps); n++)
4933
0
    if ((ctl_traps[n].tr_flags & TRAP_INUSE)
4934
0
        && ADDR_PORT_EQ(raddr, &ctl_traps[n].tr_addr)
4935
0
        && (linter == ctl_traps[n].tr_localaddr))
4936
0
      return &ctl_traps[n];
4937
4938
0
  return NULL;
4939
0
}
4940
4941
4942
/*
4943
 * report_event - report an event to the trappers
4944
 */
4945
void
4946
report_event(
4947
  int err,    /* error code */
4948
  struct peer *peer,  /* peer structure pointer */
4949
  const char *str   /* protostats string */
4950
  )
4951
74
{
4952
74
  char  statstr[NTP_MAXSTRLEN];
4953
74
  int i;
4954
74
  size_t  len;
4955
4956
  /*
4957
   * Report the error to the protostats file, system log and
4958
   * trappers.
4959
   */
4960
74
  if (peer == NULL) {
4961
4962
    /*
4963
     * Discard a system report if the number of reports of
4964
     * the same type exceeds the maximum.
4965
     */
4966
74
    if (ctl_sys_last_event != (u_char)err)
4967
1
      ctl_sys_num_events= 0;
4968
74
    if (ctl_sys_num_events >= CTL_SYS_MAXEVENTS)
4969
59
      return;
4970
4971
15
    ctl_sys_last_event = (u_char)err;
4972
15
    ctl_sys_num_events++;
4973
15
    snprintf(statstr, sizeof(statstr),
4974
15
        "0.0.0.0 %04x %02x %s",
4975
15
        ctlsysstatus(), err, eventstr(err));
4976
15
    if (str != NULL) {
4977
15
      len = strlen(statstr);
4978
15
      snprintf(statstr + len, sizeof(statstr) - len,
4979
15
          " %s", str);
4980
15
    }
4981
15
    NLOG(NLOG_SYSEVENT)
4982
15
      msyslog(LOG_INFO, "%s", statstr);
4983
15
  } else {
4984
4985
    /*
4986
     * Discard a peer report if the number of reports of
4987
     * the same type exceeds the maximum for that peer.
4988
     */
4989
0
    const char *  src;
4990
0
    u_char    errlast;
4991
4992
0
    errlast = (u_char)err & ~PEER_EVENT;
4993
0
    if (peer->last_event != errlast)
4994
0
      peer->num_events = 0;
4995
0
    if (peer->num_events >= CTL_PEER_MAXEVENTS)
4996
0
      return;
4997
4998
0
    peer->last_event = errlast;
4999
0
    peer->num_events++;
5000
0
    if (ISREFCLOCKADR(&peer->srcadr))
5001
0
      src = refnumtoa(&peer->srcadr);
5002
0
    else
5003
0
      src = stoa(&peer->srcadr);
5004
5005
0
    snprintf(statstr, sizeof(statstr),
5006
0
        "%s %04x %02x %s", src,
5007
0
        ctlpeerstatus(peer), err, eventstr(err));
5008
0
    if (str != NULL) {
5009
0
      len = strlen(statstr);
5010
0
      snprintf(statstr + len, sizeof(statstr) - len,
5011
0
          " %s", str);
5012
0
    }
5013
0
    NLOG(NLOG_PEEREVENT)
5014
0
      msyslog(LOG_INFO, "%s", statstr);
5015
0
  }
5016
15
  record_proto_stats(statstr);
5017
15
#if DEBUG
5018
15
  if (debug)
5019
0
    printf("event at %lu %s\n", current_time, statstr);
5020
15
#endif
5021
5022
  /*
5023
   * If no trappers, return.
5024
   */
5025
15
  if (num_ctl_traps <= 0)
5026
15
    return;
5027
5028
  /* [Bug 3119]
5029
   * Peer Events should be associated with a peer -- hence the
5030
   * name. But there are instances where this function is called
5031
   * *without* a valid peer. This happens e.g. with an unsolicited
5032
   * CryptoNAK, or when a leap second alarm is going off while
5033
   * currently without a system peer.
5034
   *
5035
   * The most sensible approach to this seems to bail out here if
5036
   * this happens. Avoiding to call this function would also
5037
   * bypass the log reporting in the first part of this function,
5038
   * and this is probably not the best of all options.
5039
   *   -*-perlinger@ntp.org-*-
5040
   */
5041
0
  if ((err & PEER_EVENT) && !peer)
5042
0
    return;
5043
5044
  /*
5045
   * Set up the outgoing packet variables
5046
   */
5047
0
  res_opcode = CTL_OP_ASYNCMSG;
5048
0
  res_offset = 0;
5049
0
  res_async = TRUE;
5050
0
  res_authenticate = FALSE;
5051
0
  datapt = rpkt.u.data;
5052
0
  dataend = &rpkt.u.data[CTL_MAX_DATA_LEN];
5053
0
  if (!(err & PEER_EVENT)) {
5054
0
    rpkt.associd = 0;
5055
0
    rpkt.status = htons(ctlsysstatus());
5056
5057
    /* Include the core system variables and the list. */
5058
0
    for (i = 1; i <= CS_VARLIST; i++)
5059
0
      ctl_putsys(i);
5060
0
  } else if (NULL != peer) { /* paranoia -- skip output */
5061
0
    rpkt.associd = htons(peer->associd);
5062
0
    rpkt.status = htons(ctlpeerstatus(peer));
5063
5064
    /* Dump it all. Later, maybe less. */
5065
0
    for (i = 1; i <= CP_MAX_NOAUTOKEY; i++)
5066
0
      ctl_putpeer(i, peer);
5067
0
#     ifdef REFCLOCK
5068
    /*
5069
     * for clock exception events: add clock variables to
5070
     * reflect info on exception
5071
     */
5072
0
    if (err == PEVNT_CLOCK) {
5073
0
      struct refclockstat cs;
5074
0
      struct ctl_var *kv;
5075
5076
0
      cs.kv_list = NULL;
5077
0
      refclock_control(&peer->srcadr, NULL, &cs);
5078
5079
0
      ctl_puthex("refclockstatus",
5080
0
           ctlclkstatus(&cs));
5081
5082
0
      for (i = 1; i <= CC_MAXCODE; i++)
5083
0
        ctl_putclock(i, &cs, FALSE);
5084
0
      for (kv = cs.kv_list;
5085
0
           kv != NULL && !(EOV & kv->flags);
5086
0
           kv++)
5087
0
        if (DEF & kv->flags)
5088
0
          ctl_putdata(kv->text,
5089
0
                strlen(kv->text),
5090
0
                FALSE);
5091
0
      free_varlist(cs.kv_list);
5092
0
    }
5093
0
#     endif /* REFCLOCK */
5094
0
  }
5095
5096
  /*
5097
   * We're done, return.
5098
   */
5099
0
  ctl_flushpkt(0);
5100
0
}
5101
5102
5103
/*
5104
 * mprintf_event - printf-style varargs variant of report_event()
5105
 */
5106
int
5107
mprintf_event(
5108
  int   evcode,   /* event code */
5109
  struct peer * p,    /* may be NULL */
5110
  const char *  fmt,    /* msnprintf format */
5111
  ...
5112
  )
5113
0
{
5114
0
  va_list ap;
5115
0
  int rc;
5116
0
  char  msg[512];
5117
5118
0
  va_start(ap, fmt);
5119
0
  rc = mvsnprintf(msg, sizeof(msg), fmt, ap);
5120
0
  va_end(ap);
5121
0
  report_event(evcode, p, msg);
5122
5123
0
  return rc;
5124
0
}
5125
5126
5127
/*
5128
 * ctl_clr_stats - clear stat counters
5129
 */
5130
void
5131
ctl_clr_stats(void)
5132
1
{
5133
1
  ctltimereset = current_time;
5134
1
  numctlreq = 0;
5135
1
  numctlbadpkts = 0;
5136
1
  numctlresponses = 0;
5137
1
  numctlfrags = 0;
5138
1
  numctlerrors = 0;
5139
1
  numctlfrags = 0;
5140
1
  numctltooshort = 0;
5141
1
  numctlinputresp = 0;
5142
1
  numctlinputfrag = 0;
5143
1
  numctlinputerr = 0;
5144
1
  numctlbadoffset = 0;
5145
1
  numctlbadversion = 0;
5146
1
  numctldatatooshort = 0;
5147
1
  numctlbadop = 0;
5148
1
  numasyncmsgs = 0;
5149
1
}
5150
5151
static u_short
5152
count_var(
5153
  const struct ctl_var *k
5154
  )
5155
34.7k
{
5156
34.7k
  u_int c;
5157
5158
34.7k
  if (NULL == k)
5159
998
    return 0;
5160
5161
33.7k
  c = 0;
5162
709k
  while (!(EOV & (k++)->flags))
5163
675k
    c++;
5164
5165
33.7k
  ENSURE(c <= USHRT_MAX);
5166
0
  return (u_short)c;
5167
34.7k
}
5168
5169
5170
char *
5171
add_var(
5172
  struct ctl_var **kv,
5173
  u_long size,
5174
  u_short def
5175
  )
5176
34.6k
{
5177
34.6k
  u_short   c;
5178
34.6k
  struct ctl_var *k;
5179
34.6k
  char *    buf;
5180
5181
34.6k
  c = count_var(*kv);
5182
34.6k
  *kv  = erealloc(*kv, (c + 2) * sizeof(**kv));
5183
34.6k
  k = *kv;
5184
34.6k
  buf = emalloc(size);
5185
34.6k
  k[c].code  = c;
5186
34.6k
  k[c].text  = buf;
5187
34.6k
  k[c].flags = def;
5188
34.6k
  k[c + 1].code  = 0;
5189
34.6k
  k[c + 1].text  = NULL;
5190
34.6k
  k[c + 1].flags = EOV;
5191
5192
34.6k
  return buf;
5193
34.6k
}
5194
5195
5196
void
5197
set_var(
5198
  struct ctl_var **kv,
5199
  const char *data,
5200
  u_long size,
5201
  u_short def
5202
  )
5203
34.6k
{
5204
34.6k
  struct ctl_var *k;
5205
34.6k
  const char *s;
5206
34.6k
  const char *t;
5207
34.6k
  char *td;
5208
5209
34.6k
  if (NULL == data || !size)
5210
0
    return;
5211
5212
34.6k
  k = *kv;
5213
34.6k
  if (k != NULL) {
5214
709k
    while (!(EOV & k->flags)) {
5215
675k
      if (NULL == k->text)  {
5216
0
        td = emalloc(size);
5217
0
        memcpy(td, data, size);
5218
0
        k->text = td;
5219
0
        k->flags = def;
5220
0
        return;
5221
675k
      } else {
5222
675k
        s = data;
5223
675k
        t = k->text;
5224
1.79M
        while (*t != '=' && *s == *t) {
5225
1.12M
          s++;
5226
1.12M
          t++;
5227
1.12M
        }
5228
675k
        if (*s == *t && ((*t == '=') || !*t)) {
5229
0
          td = erealloc((void *)(intptr_t)k->text, size);
5230
0
          memcpy(td, data, size);
5231
0
          k->text = td;
5232
0
          k->flags = def;
5233
0
          return;
5234
0
        }
5235
675k
      }
5236
675k
      k++;
5237
675k
    }
5238
33.7k
  }
5239
34.6k
  td = add_var(kv, size, def);
5240
34.6k
  memcpy(td, data, size);
5241
34.6k
}
5242
5243
5244
void
5245
set_sys_var(
5246
  const char *data,
5247
  u_long size,
5248
  u_short def
5249
  )
5250
0
{
5251
0
  set_var(&ext_sys_var, data, size, def);
5252
0
}
5253
5254
5255
/*
5256
 * get_ext_sys_var() retrieves the value of a user-defined variable or
5257
 * NULL if the variable has not been setvar'd.
5258
 */
5259
const char *
5260
get_ext_sys_var(const char *tag)
5261
0
{
5262
0
  struct ctl_var *  v;
5263
0
  size_t      c;
5264
0
  const char *    val;
5265
5266
0
  val = NULL;
5267
0
  c = strlen(tag);
5268
0
  for (v = ext_sys_var; !(EOV & v->flags); v++) {
5269
0
    if (NULL != v->text && !memcmp(tag, v->text, c)) {
5270
0
      if ('=' == v->text[c]) {
5271
0
        val = v->text + c + 1;
5272
0
        break;
5273
0
      } else if ('\0' == v->text[c]) {
5274
0
        val = "";
5275
0
        break;
5276
0
      }
5277
0
    }
5278
0
  }
5279
5280
0
  return val;
5281
0
}
5282
5283
5284
void
5285
free_varlist(
5286
  struct ctl_var *kv
5287
  )
5288
866
{
5289
866
  struct ctl_var *k;
5290
866
  if (kv) {
5291
35.5k
    for (k = kv; !(k->flags & EOV); k++)
5292
34.6k
      free((void *)(intptr_t)k->text);
5293
866
    free((void *)kv);
5294
866
  }
5295
866
}