1/* 2 * ntp_config.c - read and apply configuration information 3 */ 4#ifdef HAVE_CONFIG_H 5# include <config.h> 6#endif 7 8#ifdef HAVE_NETINFO 9# include <netinfo/ni.h> 10#endif 11 12#include "ntpd.h" 13#include "ntp_io.h" 14#include "ntp_unixtime.h" 15#include "ntp_refclock.h" 16#include "ntp_filegen.h" 17#include "ntp_stdlib.h" 18#include "ntp_config.h" 19#include "ntp_cmdargs.h" 20
|
21#ifdef PUBKEY
22# include "ntp_crypto.h"
23#endif /* PUBKEY */
24
|
21#include <stdio.h> 22#include <ctype.h> 23#ifdef HAVE_SYS_PARAM_H 24#include <sys/param.h> 25#endif 26#include <signal.h> 27#ifndef SIGCHLD 28# define SIGCHLD SIGCLD 29#endif 30#if !defined(VMS) 31# ifdef HAVE_SYS_WAIT_H 32# include <sys/wait.h> 33# endif 34#endif /* VMS */ 35 36#ifdef SYS_WINNT 37# include <io.h> 38extern HANDLE ResolverThreadHandle; 39#endif /* SYS_WINNT */ 40
|
41#include <netdb.h> 42 |
43extern int priority_done; 44 45/* 46 * These routines are used to read the configuration file at 47 * startup time. An entry in the file must fit on a single line. 48 * Entries are processed as multiple tokens separated by white space 49 * Lines are considered terminated when a '#' is encountered. Blank 50 * lines are ignored. 51 */
|
54
|
52/*
|
56 * We understand the following configuration entries and defaults.
57 *
58 * peer [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
59 * server [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
60 * broadcast [ addr ] [ version 3 ] [ key 0 ] [ ttl 1 ]
61 * broadcastclient
62 * multicastclient [ 224.0.1.1 ]
63 * manycastclient [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
64 * manycastserver [ 224.0.1.1 ]
65 * broadcastdelay 0.0102
66 * restrict [ addr ] [ mask 255.255.255.0 ] ignore|noserve|notrust|noquery
67 * driftfile file_name
68 * keys file_name
69 * publickey file_name
70 * privatekey file_name
71 * statsdir /var/NTP/
72 * filegen peerstats [ file peerstats ] [ type day ] [ link ]
73 * clientlimit [ n ]
74 * clientperiod [ 3600 ]
75 * trustedkey [ key ]
76 * requestkey [ key]
77 * controlkey [ key ]
78 * trap [ addr ]
79 * fudge [ addr ] [ stratum ] [ refid ] ...
80 * pidfile [ ]
81 * setvar [ ]
82 * logfile logfile
83 * logconfig [+|-|=][{sync|sys|peer|clock}{{,all}{info|statistics|events|status}}]...
84 * enable auth|bclient|pll|kernel|monitor|stats|calibrate
85 * disable auth|bclient|pll|kernel|monitor|stats|calibrate
86 * phone ...
87 * pps device [assert|clear] [hardpps]
88 * priority high|normal
89 */
90
91/*
|
53 * Translation table - keywords to function index 54 */ 55struct keyword { 56 const char *text; 57 int keytype; 58}; 59 60/* 61 * Command keywords 62 */ 63static struct keyword keywords[] = {
|
103 { "authenticate", CONFIG_AUTHENTICATE },
|
64 { "automax", CONFIG_AUTOMAX }, 65 { "broadcast", CONFIG_BROADCAST }, 66 { "broadcastclient", CONFIG_BROADCASTCLIENT }, 67 { "broadcastdelay", CONFIG_BDELAY },
|
108 { "clientlimit", CONFIG_CLIENTLIMIT },
109 { "clientperiod", CONFIG_CLIENTPERIOD },
110#ifdef PUBKEY
|
68 { "calldelay", CONFIG_CDELAY}, 69#ifdef OPENSSL |
70 { "crypto", CONFIG_CRYPTO },
|
112#endif /* PUBKEY */
|
71#endif /* OPENSSL */ |
72 { "controlkey", CONFIG_CONTROLKEY }, 73 { "disable", CONFIG_DISABLE }, 74 { "driftfile", CONFIG_DRIFTFILE }, 75 { "enable", CONFIG_ENABLE }, 76 { "filegen", CONFIG_FILEGEN }, 77 { "fudge", CONFIG_FUDGE }, 78 { "includefile", CONFIG_INCLUDEFILE }, 79 { "keys", CONFIG_KEYS },
|
121#ifdef PUBKEY
|
80 { "keysdir", CONFIG_KEYSDIR },
|
123#endif /* PUBKEY */
|
81 { "logconfig", CONFIG_LOGCONFIG }, 82 { "logfile", CONFIG_LOGFILE }, 83 { "manycastclient", CONFIG_MANYCASTCLIENT }, 84 { "manycastserver", CONFIG_MANYCASTSERVER }, 85 { "multicastclient", CONFIG_MULTICASTCLIENT }, 86 { "peer", CONFIG_PEER }, 87 { "phone", CONFIG_PHONE }, 88 { "pidfile", CONFIG_PIDFILE },
|
132 { "pps", CONFIG_PPS },
|
89 { "discard", CONFIG_DISCARD }, |
90 { "requestkey", CONFIG_REQUESTKEY }, 91 { "restrict", CONFIG_RESTRICT }, 92 { "revoke", CONFIG_REVOKE }, 93 { "server", CONFIG_SERVER }, 94 { "setvar", CONFIG_SETVAR }, 95 { "statistics", CONFIG_STATISTICS }, 96 { "statsdir", CONFIG_STATSDIR },
|
97 { "tick", CONFIG_ADJ }, |
98 { "tinker", CONFIG_TINKER },
|
99 { "tos", CONFIG_TOS }, |
100 { "trap", CONFIG_TRAP }, 101 { "trustedkey", CONFIG_TRUSTEDKEY },
|
102 { "ttl", CONFIG_TTL }, |
103 { "", CONFIG_UNKNOWN } 104}; 105 106/* 107 * "peer", "server", "broadcast" modifier keywords 108 */ 109static struct keyword mod_keywords[] = { 110 { "autokey", CONF_MOD_SKEY }, 111 { "burst", CONF_MOD_BURST }, 112 { "iburst", CONF_MOD_IBURST }, 113 { "key", CONF_MOD_KEY }, 114 { "maxpoll", CONF_MOD_MAXPOLL }, 115 { "minpoll", CONF_MOD_MINPOLL }, 116 { "mode", CONF_MOD_MODE }, /* refclocks */ 117 { "noselect", CONF_MOD_NOSELECT }, 118 { "prefer", CONF_MOD_PREFER },
|
159#ifdef PUBKEY
160 { "publickey", CONF_MOD_PUBLICKEY },
161#endif /* PUBKEY */
|
119 { "ttl", CONF_MOD_TTL }, /* NTP peers */ 120 { "version", CONF_MOD_VERSION }, 121 { "", CONFIG_UNKNOWN } 122}; 123 124/* 125 * "restrict" modifier keywords 126 */ 127static struct keyword res_keywords[] = { 128 { "ignore", CONF_RES_IGNORE }, 129 { "limited", CONF_RES_LIMITED }, 130 { "kod", CONF_RES_DEMOBILIZE }, 131 { "lowpriotrap", CONF_RES_LPTRAP }, 132 { "mask", CONF_RES_MASK }, 133 { "nomodify", CONF_RES_NOMODIFY }, 134 { "nopeer", CONF_RES_NOPEER }, 135 { "noquery", CONF_RES_NOQUERY }, 136 { "noserve", CONF_RES_NOSERVE }, 137 { "notrap", CONF_RES_NOTRAP }, 138 { "notrust", CONF_RES_NOTRUST }, 139 { "ntpport", CONF_RES_NTPPORT }, 140 { "version", CONF_RES_VERSION }, 141 { "", CONFIG_UNKNOWN } 142}; 143 144/* 145 * "trap" modifier keywords 146 */ 147static struct keyword trap_keywords[] = { 148 { "port", CONF_TRAP_PORT }, 149 { "interface", CONF_TRAP_INTERFACE }, 150 { "", CONFIG_UNKNOWN } 151}; 152 153/* 154 * "fudge" modifier keywords 155 */ 156static struct keyword fudge_keywords[] = { 157 { "flag1", CONF_FDG_FLAG1 }, 158 { "flag2", CONF_FDG_FLAG2 }, 159 { "flag3", CONF_FDG_FLAG3 }, 160 { "flag4", CONF_FDG_FLAG4 }, 161 { "refid", CONF_FDG_REFID }, 162 { "stratum", CONF_FDG_STRATUM }, 163 { "time1", CONF_FDG_TIME1 }, 164 { "time2", CONF_FDG_TIME2 }, 165 { "", CONFIG_UNKNOWN } 166}; 167
|
211
|
168/* 169 * "filegen" modifier keywords 170 */ 171static struct keyword filegen_keywords[] = { 172 { "disable", CONF_FGEN_FLAG_DISABLE }, 173 { "enable", CONF_FGEN_FLAG_ENABLE }, 174 { "file", CONF_FGEN_FILE }, 175 { "link", CONF_FGEN_FLAG_LINK }, 176 { "nolink", CONF_FGEN_FLAG_NOLINK }, 177 { "type", CONF_FGEN_TYPE }, 178 { "", CONFIG_UNKNOWN } 179}; 180 181/* 182 * "type" modifier keywords 183 */ 184static struct keyword fgen_types[] = { 185 { "age", FILEGEN_AGE }, 186 { "day", FILEGEN_DAY }, 187 { "month", FILEGEN_MONTH }, 188 { "none", FILEGEN_NONE }, 189 { "pid", FILEGEN_PID }, 190 { "week", FILEGEN_WEEK }, 191 { "year", FILEGEN_YEAR }, 192 { "", CONFIG_UNKNOWN} 193}; 194 195/* 196 * "enable", "disable" modifier keywords 197 */ 198static struct keyword flags_keywords[] = { 199 { "auth", PROTO_AUTHENTICATE }, 200 { "bclient", PROTO_BROADCLIENT }, 201 { "calibrate", PROTO_CAL }, 202 { "kernel", PROTO_KERNEL }, 203 { "monitor", PROTO_MONITOR }, 204 { "ntp", PROTO_NTP }, 205 { "pps", PROTO_PPS }, 206 { "stats", PROTO_FILEGEN }, 207 { "", CONFIG_UNKNOWN } 208}; 209 210/*
|
255 * "pps" modifier keywords
|
211 * "discard" modifier keywords |
212 */
|
257static struct keyword pps_keywords[] = {
258 { "assert", CONF_PPS_ASSERT },
259 { "clear", CONF_PPS_CLEAR },
260 { "hardpps", CONF_PPS_HARDPPS },
|
213static struct keyword discard_keywords[] = { 214 { "average", CONF_DISCARD_AVERAGE }, 215 { "minimum", CONF_DISCARD_MINIMUM }, 216 { "monitor", CONF_DISCARD_MONITOR }, |
217 { "", CONFIG_UNKNOWN } 218}; 219 220/* 221 * "tinker" modifier keywords 222 */ 223static struct keyword tinker_keywords[] = { 224 { "step", CONF_CLOCK_MAX }, 225 { "panic", CONF_CLOCK_PANIC }, 226 { "dispersion", CONF_CLOCK_PHI }, 227 { "stepout", CONF_CLOCK_MINSTEP },
|
272 { "minpoll", CONF_CLOCK_MINPOLL },
|
228 { "allan", CONF_CLOCK_ALLAN }, 229 { "huffpuff", CONF_CLOCK_HUFFPUFF },
|
230 { "freq", CONF_CLOCK_FREQ }, |
231 { "", CONFIG_UNKNOWN } 232}; 233
|
278#ifdef PUBKEY
|
234/*
|
235 * "tos" modifier keywords 236 */ 237static struct keyword tos_keywords[] = { 238 { "minclock", CONF_TOS_MINCLOCK }, 239 { "minsane", CONF_TOS_MINSANE }, 240 { "floor", CONF_TOS_FLOOR }, 241 { "ceiling", CONF_TOS_CEILING }, 242 { "cohort", CONF_TOS_COHORT }, 243 { "", CONFIG_UNKNOWN } 244}; 245 246#ifdef OPENSSL 247/* |
248 * "crypto" modifier keywords 249 */ 250static struct keyword crypto_keywords[] = {
|
283 { "dh", CONF_CRYPTO_DH },
284 { "flags", CONF_CRYPTO_FLAGS },
|
251 { "cert", CONF_CRYPTO_CERT }, 252 { "gqpar", CONF_CRYPTO_GQPAR }, 253 { "host", CONF_CRYPTO_RSA }, 254 { "iffpar", CONF_CRYPTO_IFFPAR }, |
255 { "leap", CONF_CRYPTO_LEAP },
|
286 { "privatekey", CONF_CRYPTO_PRIVATEKEY },
287 { "publickey", CONF_CRYPTO_PUBLICKEY },
|
256 { "mvpar", CONF_CRYPTO_MVPAR }, 257 { "pw", CONF_CRYPTO_PW }, 258 { "randfile", CONF_CRYPTO_RAND }, 259 { "sign", CONF_CRYPTO_SIGN }, |
260 { "", CONFIG_UNKNOWN } 261};
|
290#endif /* PUBKEY */
|
262#endif /* OPENSSL */ |
263 264/*
|
265 * Address type selection, IPv4 or IPv4. 266 * Used on various lines. 267 */ 268static struct keyword addr_type[] = { 269 { "-4", CONF_ADDR_IPV4 }, 270 { "-6", CONF_ADDR_IPV6 }, 271 { "", CONFIG_UNKNOWN } 272}; 273 274/* |
275 * "logconfig" building blocks 276 */ 277struct masks { 278 const char *name; 279 unsigned long mask; 280}; 281 282static struct masks logcfg_class[] = { 283 { "clock", NLOG_OCLOCK }, 284 { "peer", NLOG_OPEER }, 285 { "sync", NLOG_OSYNC }, 286 { "sys", NLOG_OSYS }, 287 { (char *)0, 0 } 288}; 289 290static struct masks logcfg_item[] = { 291 { "info", NLOG_INFO }, 292 { "allinfo", NLOG_SYSINFO|NLOG_PEERINFO|NLOG_CLOCKINFO|NLOG_SYNCINFO }, 293 { "events", NLOG_EVENT }, 294 { "allevents", NLOG_SYSEVENT|NLOG_PEEREVENT|NLOG_CLOCKEVENT|NLOG_SYNCEVENT }, 295 { "status", NLOG_STATUS }, 296 { "allstatus", NLOG_SYSSTATUS|NLOG_PEERSTATUS|NLOG_CLOCKSTATUS|NLOG_SYNCSTATUS }, 297 { "statistics", NLOG_STATIST }, 298 { "allstatistics", NLOG_SYSSTATIST|NLOG_PEERSTATIST|NLOG_CLOCKSTATIST|NLOG_SYNCSTATIST }, 299 { "allclock", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OCLOCK }, 300 { "allpeer", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OPEER }, 301 { "allsys", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OSYS }, 302 { "allsync", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OSYNC }, 303 { "all", NLOG_SYSMASK|NLOG_PEERMASK|NLOG_CLOCKMASK|NLOG_SYNCMASK }, 304 { (char *)0, 0 } 305}; 306 307/* 308 * Limits on things 309 */ 310#define MAXTOKENS 20 /* 20 tokens on line */ 311#define MAXLINE 1024 /* maximum length of line */ 312#define MAXPHONE 5 /* maximum number of phone strings */ 313#define MAXPPS 20 /* maximum length of PPS device string */ 314#define MAXINCLUDELEVEL 5 /* maximum include file levels */ 315 316/* 317 * Miscellaneous macros 318 */ 319#define STRSAME(s1, s2) (*(s1) == *(s2) && strcmp((s1), (s2)) == 0) 320#define ISEOL(c) ((c) == '#' || (c) == '\n' || (c) == '\0') 321#define ISSPACE(c) ((c) == ' ' || (c) == '\t') 322#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) 323 324#define KEY_TYPE_MD5 4 325 326/* 327 * File descriptor used by the resolver save routines, and temporary file 328 * name. 329 */
|
330int call_resolver = 1; /* ntp-genkeys sets this to 0, for example */ |
331static FILE *res_fp; 332#ifndef SYS_WINNT 333static char res_file[20]; /* enough for /tmp/ntpXXXXXX\0 */ 334#define RES_TEMPFILE "/tmp/ntpXXXXXX" 335#else 336static char res_file[MAX_PATH]; 337#endif /* SYS_WINNT */ 338 339/* 340 * Definitions of things either imported from or exported to outside 341 */ 342char const *progname; 343char sys_phone[MAXPHONE][MAXDIAL]; /* ACTS phone numbers */
|
344char *keysdir = NTP_KEYSDIR; /* crypto keys directory */ |
345char pps_device[MAXPPS + 1]; /* PPS device name */
|
362int pps_assert;
363int pps_hardpps;
|
346#if defined(HAVE_SCHED_SETSCHEDULER) 347int config_priority_override = 0; 348int config_priority; 349#endif 350 351const char *config_file; 352#ifdef HAVE_NETINFO 353 struct netinfo_config_state *config_netinfo = NULL; 354 int check_netinfo = 1; 355#endif /* HAVE_NETINFO */ 356#ifdef SYS_WINNT 357 char *alt_config_file; 358 LPTSTR temp; 359 char config_file_storage[MAX_PATH]; 360 char alt_config_file_storage[MAX_PATH]; 361#endif /* SYS_WINNT */ 362 363#ifdef HAVE_NETINFO 364/* 365 * NetInfo configuration state 366 */ 367struct netinfo_config_state { 368 void *domain; /* domain with config */ 369 ni_id config_dir; /* ID config dir */ 370 int prop_index; /* current property */ 371 int val_index; /* current value */ 372 char **val_list; /* value list */ 373}; 374#endif 375 376/* 377 * Function prototypes 378 */ 379static unsigned long get_pfxmatch P((char **, struct masks *)); 380static unsigned long get_match P((char *, struct masks *)); 381static unsigned long get_logmask P((char *)); 382#ifdef HAVE_NETINFO 383static struct netinfo_config_state *get_netinfo_config P((void)); 384static void free_netinfo_config P((struct netinfo_config_state *)); 385static int gettokens_netinfo P((struct netinfo_config_state *, char **, int *)); 386#endif 387static int gettokens P((FILE *, char *, char **, int *));
|
406static int matchkey P((char *, struct keyword *));
407static int getnetnum P((const char *, struct sockaddr_in *, int));
|
388static int matchkey P((char *, struct keyword *, int)); 389static int getnetnum P((const char *, struct sockaddr_storage *, int)); |
390static void save_resolve P((char *, int, int, int, int, u_int, int, 391 keyid_t, u_char *)); 392static void do_resolve_internal P((void)); 393static void abort_resolve P((void));
|
412#if !defined(VMS)
|
394#if !defined(VMS) && !defined(SYS_WINNT) |
395static RETSIGTYPE catchchild P((int)); 396#endif /* VMS */ 397 398/* 399 * get_pfxmatch - find value for prefixmatch 400 * and update char * accordingly 401 */ 402static unsigned long 403get_pfxmatch( 404 char ** s, 405 struct masks *m 406 ) 407{ 408 while (m->name) { 409 if (strncmp(*s, m->name, strlen(m->name)) == 0) { 410 *s += strlen(m->name); 411 return m->mask; 412 } else { 413 m++; 414 } 415 } 416 return 0; 417} 418 419/* 420 * get_match - find logmask value 421 */ 422static unsigned long 423get_match( 424 char *s, 425 struct masks *m 426 ) 427{ 428 while (m->name) { 429 if (strcmp(s, m->name) == 0) { 430 return m->mask; 431 } else { 432 m++; 433 } 434 } 435 return 0; 436} 437 438/* 439 * get_logmask - build bitmask for ntp_syslogmask 440 */ 441static unsigned long 442get_logmask( 443 char *s 444 ) 445{ 446 char *t; 447 unsigned long offset; 448 unsigned long mask; 449 450 t = s; 451 offset = get_pfxmatch(&t, logcfg_class); 452 mask = get_match(t, logcfg_item); 453 454 if (mask) 455 return mask << offset; 456 else 457 msyslog(LOG_ERR, "logconfig: illegal argument %s - ignored", s); 458 459 return 0; 460} 461 462 463/* 464 * getconfig - get command line options and read the configuration file 465 */ 466void 467getconfig( 468 int argc, 469 char *argv[] 470 ) 471{ 472 register int i; 473 int c; 474 int errflg;
|
475 int istart; |
476 int peerversion; 477 int minpoll; 478 int maxpoll; 479 int ttl; 480 long stratum; 481 unsigned long ul; 482 keyid_t peerkey; 483 u_char *peerkeystr; 484 u_long fudgeflag; 485 u_int peerflags; 486 int hmode;
|
504 struct sockaddr_in peeraddr;
505 struct sockaddr_in maskaddr;
|
487 struct sockaddr_storage peeraddr; 488 struct sockaddr_storage maskaddr; |
489 FILE *fp[MAXINCLUDELEVEL+1]; 490 FILE *includefile; 491 int includelevel = 0; 492 char line[MAXLINE]; 493 char *(tokens[MAXTOKENS]);
|
511 int ntokens;
|
494 int ntokens = 0; |
495 int tok = CONFIG_UNKNOWN; 496 struct interface *localaddr; 497 struct refclockstat clock_stat; 498 FILEGEN *filegen; 499 500 /* 501 * Initialize, initialize 502 */ 503 errflg = 0; 504 /* HMS: don't initialize debug to 0 here! */ 505#ifndef SYS_WINNT 506 config_file = CONFIG_FILE; 507#else 508 temp = CONFIG_FILE; 509 if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)config_file_storage, (DWORD)sizeof(config_file_storage))) { 510 msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m\n"); 511 exit(1); 512 } 513 config_file = config_file_storage; 514 515 temp = ALT_CONFIG_FILE; 516 if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)alt_config_file_storage, (DWORD)sizeof(alt_config_file_storage))) { 517 msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m\n"); 518 exit(1); 519 } 520 alt_config_file = alt_config_file_storage; 521 522#endif /* SYS_WINNT */ 523 progname = argv[0]; 524 res_fp = NULL; 525 memset((char *)sys_phone, 0, sizeof(sys_phone)); 526 ntp_syslogmask = NLOG_SYNCMASK; /* set more via logconfig */ 527 528 /* 529 * install a non default variable with this daemon version 530 */ 531 (void) sprintf(line, "daemon_version=\"%s\"", Version); 532 set_sys_var(line, strlen(line)+1, RO); 533 534 /* 535 * Say how we're setting the time of day 536 */ 537 (void) sprintf(line, "settimeofday=\"%s\"", set_tod_using); 538 set_sys_var(line, strlen(line)+1, RO); 539 540 /* 541 * Initialize the loop. 542 */ 543 loop_config(LOOP_DRIFTINIT, 0.); 544 545 getCmdOpts(argc, argv); 546 547 if ( 548 (fp[0] = fopen(FindConfig(config_file), "r")) == NULL 549#ifdef HAVE_NETINFO 550 /* If there is no config_file, try NetInfo. */ 551 && check_netinfo && !(config_netinfo = get_netinfo_config()) 552#endif /* HAVE_NETINFO */ 553 ) { 554 fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(config_file)); 555 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(config_file)); 556#ifdef SYS_WINNT 557 /* Under WinNT try alternate_config_file name, first NTP.CONF, then NTP.INI */ 558 559 if ((fp[0] = fopen(FindConfig(alt_config_file), "r")) == NULL) { 560 561 /* 562 * Broadcast clients can sometimes run without 563 * a configuration file. 564 */ 565 566 fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(alt_config_file)); 567 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(alt_config_file)); 568 return; 569 } 570#else /* not SYS_WINNT */ 571 return; 572#endif /* not SYS_WINNT */ 573 } 574 575 for (;;) { 576 if (fp[includelevel]) 577 tok = gettokens(fp[includelevel], line, tokens, &ntokens); 578#ifdef HAVE_NETINFO 579 else 580 tok = gettokens_netinfo(config_netinfo, tokens, &ntokens); 581#endif /* HAVE_NETINFO */ 582 583 if (tok == CONFIG_UNKNOWN) { 584 if (includelevel > 0) { 585 fclose(fp[includelevel--]); 586 continue; 587 } else { 588 break; 589 } 590 } 591 592 switch(tok) { 593 case CONFIG_PEER: 594 case CONFIG_SERVER: 595 case CONFIG_MANYCASTCLIENT: 596 case CONFIG_BROADCAST: 597 if (tok == CONFIG_PEER) 598 hmode = MODE_ACTIVE; 599 else if (tok == CONFIG_SERVER) 600 hmode = MODE_CLIENT; 601 else if (tok == CONFIG_MANYCASTCLIENT) 602 hmode = MODE_CLIENT; 603 else 604 hmode = MODE_BROADCAST; 605 606 if (ntokens < 2) { 607 msyslog(LOG_ERR, 608 "No address for %s, line ignored", 609 tokens[0]); 610 break; 611 } 612
|
630 if (!getnetnum(tokens[1], &peeraddr, 0)) {
|
613 istart = 1; 614 memset((char *)&peeraddr, 0, sizeof(peeraddr)); 615 switch (matchkey(tokens[istart], addr_type, 0)) { 616 case CONF_ADDR_IPV4: 617 peeraddr.ss_family = AF_INET; 618 istart++; 619 break; 620 case CONF_ADDR_IPV6: 621 peeraddr.ss_family = AF_INET6; 622 istart++; 623 break; 624 } 625 626 if (!getnetnum(tokens[istart], &peeraddr, 0)) { |
627 errflg = -1; 628 } else { 629 errflg = 0; 630 631 if ( 632#ifdef REFCLOCK 633 !ISREFCLOCKADR(&peeraddr) && 634#endif 635 ISBADADR(&peeraddr)) { 636 msyslog(LOG_ERR, 637 "attempt to configure invalid address %s",
|
642 ntoa(&peeraddr));
|
638 stoa(&peeraddr)); |
639 break; 640 } 641 /* 642 * Shouldn't be able to specify multicast 643 * address for server/peer! 644 * and unicast address for manycastclient! 645 */
|
650 if (((tok == CONFIG_SERVER) ||
651 (tok == CONFIG_PEER)) &&
|
646 if (peeraddr.ss_family == AF_INET) { 647 if (((tok == CONFIG_SERVER) || 648 (tok == CONFIG_PEER)) && |
649#ifdef REFCLOCK
|
653 !ISREFCLOCKADR(&peeraddr) &&
|
650 !ISREFCLOCKADR(&peeraddr) && |
651#endif
|
655 IN_CLASSD(ntohl(peeraddr.sin_addr.s_addr))) {
656 msyslog(LOG_ERR,
657 "attempt to configure invalid address %s",
658 ntoa(&peeraddr));
659 break;
|
652 IN_CLASSD(ntohl(((struct sockaddr_in*)&peeraddr)->sin_addr.s_addr))) { 653 msyslog(LOG_ERR, 654 "attempt to configure invalid address %s", 655 stoa(&peeraddr)); 656 break; 657 } 658 if ((tok == CONFIG_MANYCASTCLIENT) && 659 !IN_CLASSD(ntohl(((struct sockaddr_in*)&peeraddr)->sin_addr.s_addr))) { 660 msyslog(LOG_ERR, 661 "attempt to configure invalid address %s", 662 stoa(&peeraddr)); 663 break; 664 } |
665 }
|
661 if ((tok == CONFIG_MANYCASTCLIENT) &&
662 !IN_CLASSD(ntohl(peeraddr.sin_addr.s_addr))) {
663 msyslog(LOG_ERR,
664 "attempt to configure invalid address %s",
665 ntoa(&peeraddr));
666 break;
|
666 else if(peeraddr.ss_family == AF_INET6) { 667 if (((tok == CONFIG_SERVER) || 668 (tok == CONFIG_PEER)) && 669#ifdef REFCLOCK 670 !ISREFCLOCKADR(&peeraddr) && 671#endif 672 IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)&peeraddr)->sin6_addr)) { 673 msyslog(LOG_ERR, 674 "attempt to configure in valid address %s", 675 stoa(&peeraddr)); 676 break; 677 } 678 if ((tok == CONFIG_MANYCASTCLIENT) && 679 !IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)&peeraddr)->sin6_addr)) { 680 msyslog(LOG_ERR, 681 "attempt to configure in valid address %s", 682 stoa(&peeraddr)); 683 break; 684 } |
685 } 686 } 687 688 peerversion = NTP_VERSION; 689 minpoll = NTP_MINDPOLL; 690 maxpoll = NTP_MAXDPOLL; 691 peerkey = 0;
|
674 peerkeystr = "*";
|
692 peerkeystr = (u_char *)"*"; |
693 peerflags = 0; 694 ttl = 0;
|
677 for (i = 2; i < ntokens; i++)
678 switch (matchkey(tokens[i], mod_keywords)) {
|
695 istart++; 696 for (i = istart; i < ntokens; i++) 697 switch (matchkey(tokens[i], mod_keywords, 1)) { |
698 case CONF_MOD_VERSION: 699 if (i >= ntokens-1) { 700 msyslog(LOG_ERR, 701 "peer/server version requires an argument"); 702 errflg = 1; 703 break; 704 } 705 peerversion = atoi(tokens[++i]); 706 if ((u_char)peerversion > NTP_VERSION 707 || (u_char)peerversion < NTP_OLDVERSION) { 708 msyslog(LOG_ERR, 709 "inappropriate version number %s, line ignored", 710 tokens[i]); 711 errflg = 1; 712 } 713 break; 714 715 case CONF_MOD_KEY: 716 if (i >= ntokens-1) { 717 msyslog(LOG_ERR, 718 "key: argument required"); 719 errflg = 1; 720 break; 721 } 722 peerkey = (int)atol(tokens[++i]); 723 peerflags |= FLAG_AUTHENABLE; 724 break; 725 726 case CONF_MOD_MINPOLL: 727 if (i >= ntokens-1) { 728 msyslog(LOG_ERR, 729 "minpoll: argument required"); 730 errflg = 1; 731 break; 732 } 733 minpoll = atoi(tokens[++i]); 734 if (minpoll < NTP_MINPOLL) { 735 msyslog(LOG_INFO, 736 "minpoll: provided value (%d) is below minimum (%d)", 737 minpoll, NTP_MINPOLL); 738 minpoll = NTP_MINPOLL; 739 } 740 break; 741 742 case CONF_MOD_MAXPOLL: 743 if (i >= ntokens-1) { 744 msyslog(LOG_ERR, 745 "maxpoll: argument required" 746 ); 747 errflg = 1; 748 break; 749 } 750 maxpoll = atoi(tokens[++i]); 751 if (maxpoll > NTP_MAXPOLL) { 752 msyslog(LOG_INFO, 753 "maxpoll: provided value (%d) is above maximum (%d)", 754 maxpoll, NTP_MAXPOLL); 755 maxpoll = NTP_MAXPOLL; 756 } 757 break; 758 759 case CONF_MOD_PREFER: 760 peerflags |= FLAG_PREFER; 761 break; 762 763 case CONF_MOD_NOSELECT: 764 peerflags |= FLAG_NOSELECT; 765 break; 766 767 case CONF_MOD_BURST: 768 peerflags |= FLAG_BURST; 769 break; 770 771 case CONF_MOD_IBURST: 772 peerflags |= FLAG_IBURST; 773 break;
|
755#ifdef AUTOKEY
|
774#ifdef OPENSSL |
775 case CONF_MOD_SKEY: 776 peerflags |= FLAG_SKEY | 777 FLAG_AUTHENABLE; 778 break;
|
779#endif /* OPENSSL */ |
780
|
761#ifdef PUBKEY
762 case CONF_MOD_PUBLICKEY:
763 if (i >= ntokens - 1) {
764 msyslog(LOG_ERR,
765 "Public key file name required");
766 errflg = 1;
767 break;
768 }
769 peerflags |= FLAG_SKEY |
770 FLAG_AUTHENABLE;
771 peerkeystr = tokens[++i];
772 break;
773#endif /* PUBKEY */
774#endif /* AUTOKEY */
775
|
781 case CONF_MOD_TTL: 782 if (i >= ntokens-1) {
|
778 msyslog(LOG_ERR,
779 "ttl: argument required");
780 errflg = 1;
781 break;
|
783 msyslog(LOG_ERR, 784 "ttl: argument required"); 785 errflg = 1; 786 break; |
787 } 788 ttl = atoi(tokens[++i]);
|
789 if (ttl >= MAX_TTL) { 790 msyslog(LOG_ERR, 791 "ttl: invalid argument"); 792 errflg = 1; 793 } |
794 break; 795 796 case CONF_MOD_MODE: 797 if (i >= ntokens-1) {
|
788 msyslog(LOG_ERR,
789 "mode: argument required");
790 errflg = 1;
791 break;
|
798 msyslog(LOG_ERR, 799 "mode: argument required"); 800 errflg = 1; 801 break; |
802 } 803 ttl = atoi(tokens[++i]); 804 break; 805 806 case CONFIG_UNKNOWN: 807 errflg = 1; 808 break; 809 } 810 if (minpoll > maxpoll) {
|
801 msyslog(LOG_ERR, "config error: minpoll > maxpoll");
|
811 msyslog(LOG_ERR, 812 "config error: minpoll > maxpoll"); |
813 errflg = 1; 814 } 815 if (errflg == 0) {
|
805 if (peer_config(&peeraddr, any_interface, hmode,
806 peerversion, minpoll, maxpoll, peerflags,
807 ttl, peerkey, peerkeystr) == 0) {
|
816 if (peer_config(&peeraddr, 817 ANY_INTERFACE_CHOOSE(&peeraddr), hmode, 818 peerversion, minpoll, maxpoll, peerflags, 819 ttl, peerkey, peerkeystr) == 0) { |
820 msyslog(LOG_ERR, 821 "configuration of %s failed",
|
810 ntoa(&peeraddr));
|
822 stoa(&peeraddr)); |
823 }
|
824 if (tok == CONFIG_MANYCASTCLIENT) 825 proto_config(PROTO_MULTICAST_ADD, 826 0, 0., &peeraddr); |
827 828 } else if (errflg == -1) { 829 save_resolve(tokens[1], hmode, peerversion, 830 minpoll, maxpoll, peerflags, ttl, 831 peerkey, peerkeystr); 832 } 833 break; 834 835 case CONFIG_DRIFTFILE: 836 if (ntokens >= 2) 837 stats_config(STATS_FREQ_FILE, tokens[1]); 838 else 839 stats_config(STATS_FREQ_FILE, (char *)0); 840 break; 841 842 case CONFIG_PIDFILE: 843 if (ntokens >= 2) 844 stats_config(STATS_PID_FILE, tokens[1]); 845 else 846 stats_config(STATS_PID_FILE, (char *)0); 847 break; 848 849 case CONFIG_INCLUDEFILE: 850 if (ntokens < 2) { 851 msyslog(LOG_ERR, "includefile needs one argument"); 852 break; 853 } 854 if (includelevel >= MAXINCLUDELEVEL) { 855 fprintf(stderr, "getconfig: Maximum include file level exceeded.\n"); 856 msyslog(LOG_INFO, "getconfig: Maximum include file level exceeded."); 857 break; 858 } 859 includefile = fopen(FindConfig(tokens[1]), "r"); 860 if (includefile == NULL) { 861 fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(tokens[1])); 862 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(tokens[1])); 863 break; 864 } 865 fp[++includelevel] = includefile; 866 break; 867 868 case CONFIG_LOGFILE: 869 if (ntokens >= 2) { 870 FILE *new_file; 871 872 new_file = fopen(tokens[1], "a"); 873 if (new_file != NULL) { 874 NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */ 875 msyslog(LOG_NOTICE, "logging to file %s", tokens[1]); 876 if (syslog_file != NULL && 877 fileno(syslog_file) != fileno(new_file)) 878 (void)fclose(syslog_file); 879 880 syslog_file = new_file; 881 syslogit = 0; 882 } 883 else 884 msyslog(LOG_ERR, 885 "Cannot open log file %s", 886 tokens[1]); 887 } 888 else 889 msyslog(LOG_ERR, "logfile needs one argument"); 890 break; 891 892 case CONFIG_LOGCONFIG: 893 for (i = 1; i < ntokens; i++) 894 { 895 int add = 1; 896 int equals = 0; 897 char * s = &tokens[i][0]; 898 899 switch (*s) { 900 case '+': 901 case '-': 902 case '=': 903 add = *s == '+'; 904 equals = *s == '='; 905 s++; 906 break; 907 908 default: 909 break; 910 } 911 if (equals) { 912 ntp_syslogmask = get_logmask(s); 913 } else { 914 if (add) { 915 ntp_syslogmask |= get_logmask(s); 916 } else { 917 ntp_syslogmask &= ~get_logmask(s); 918 } 919 } 920#ifdef DEBUG 921 if (debug) 922 printf("ntp_syslogmask = 0x%08lx (%s)\n", ntp_syslogmask, tokens[i]); 923#endif 924 } 925 break; 926 927 case CONFIG_BROADCASTCLIENT:
|
913 proto_config(PROTO_BROADCLIENT, 1, 0.);
|
928 proto_config(PROTO_BROADCLIENT, 1, 0., NULL); |
929 break;
|
915
|
930 |
931 case CONFIG_MULTICASTCLIENT: 932 case CONFIG_MANYCASTSERVER: 933 if (ntokens > 1) {
|
919 for (i = 1; i < ntokens; i++) {
|
934 istart = 1; 935 memset((char *)&peeraddr, 0, sizeof(peeraddr)); 936 switch (matchkey(tokens[istart], 937 addr_type, 0)) { 938 case CONF_ADDR_IPV4: 939 peeraddr.ss_family = AF_INET; 940 istart++; 941 break; 942 case CONF_ADDR_IPV6: 943 peeraddr.ss_family = AF_INET6; 944 istart++; 945 break; 946 } 947 /* 948 * Abuse maskaddr to store the prefered ip 949 * version. 950 */ 951 memset((char *)&maskaddr, 0, sizeof(maskaddr)); 952 maskaddr.ss_family = peeraddr.ss_family; 953 954 for (i = istart; i < ntokens; i++) { 955 memset((char *)&peeraddr, 0, 956 sizeof(peeraddr)); 957 peeraddr.ss_family = maskaddr.ss_family; |
958 if (getnetnum(tokens[i], &peeraddr, 1)) 959 proto_config(PROTO_MULTICAST_ADD,
|
922 peeraddr.sin_addr.s_addr, 0.);
|
960 0, 0., &peeraddr); |
961 } 962 } else 963 proto_config(PROTO_MULTICAST_ADD,
|
926 htonl(INADDR_NTP), 0.);
|
964 0, 0., NULL); |
965 if (tok == CONFIG_MULTICASTCLIENT) 966 sys_bclient = 1; 967 else if (tok == CONFIG_MANYCASTSERVER) 968 sys_manycastserver = 1; 969 break; 970
|
933 case CONFIG_AUTHENTICATE:
934 errflg = 0;
|
971 case CONFIG_KEYS: |
972 if (ntokens >= 2) {
|
936 if (STREQ(tokens[1], "yes"))
937 proto_config(PROTO_AUTHENTICATE, 1, 0.);
938 else if (STREQ(tokens[1], "no"))
939 proto_config(PROTO_AUTHENTICATE, 0, 0.);
940 else
941 errflg++;
942 } else {
943 errflg++;
|
973 getauthkeys(tokens[1]); |
974 }
|
945
946 if (errflg)
947 msyslog(LOG_ERR,
948 "should be `authenticate yes|no'");
|
975 break; 976
|
951 case CONFIG_KEYS:
952 if (ntokens >= 2) {
953 getauthkeys(tokens[1]);
|
977 case CONFIG_KEYSDIR: 978 if (ntokens < 2) { 979 msyslog(LOG_ERR, 980 "Keys directory name required"); 981 break; |
982 }
|
983 keysdir = emalloc(strlen(tokens[1]) + 1); 984 strcpy(keysdir, tokens[1]); |
985 break; 986 987 case CONFIG_TINKER: 988 for (i = 1; i < ntokens; i++) { 989 int temp; 990 double ftemp; 991
|
962 temp = matchkey(tokens[i++],
963 tinker_keywords);
|
992 temp = matchkey(tokens[i++], tinker_keywords, 1); |
993 if (i > ntokens - 1) { 994 msyslog(LOG_ERR, 995 "tinker: missing argument"); 996 errflg++; 997 break; 998 } 999 sscanf(tokens[i], "%lf", &ftemp); 1000 switch(temp) {
|
1001 |
1002 case CONF_CLOCK_MAX: 1003 loop_config(LOOP_MAX, ftemp); 1004 break; 1005 1006 case CONF_CLOCK_PANIC: 1007 loop_config(LOOP_PANIC, ftemp); 1008 break; 1009 1010 case CONF_CLOCK_PHI: 1011 loop_config(LOOP_PHI, ftemp); 1012 break; 1013 1014 case CONF_CLOCK_MINSTEP: 1015 loop_config(LOOP_MINSTEP, ftemp); 1016 break; 1017
|
988 case CONF_CLOCK_MINPOLL:
989 loop_config(LOOP_MINPOLL, ftemp);
990 break;
991
|
1018 case CONF_CLOCK_ALLAN: 1019 loop_config(LOOP_ALLAN, ftemp); 1020 break; 1021 1022 case CONF_CLOCK_HUFFPUFF: 1023 loop_config(LOOP_HUFFPUFF, ftemp); 1024 break;
|
1025 1026 case CONF_CLOCK_FREQ: 1027 loop_config(LOOP_FREQ, ftemp); 1028 break; |
1029 } 1030 } 1031 break; 1032
|
1003#ifdef AUTOKEY
|
1033 case CONFIG_TOS: 1034 for (i = 1; i < ntokens; i++) { 1035 int temp; 1036 double ftemp; 1037 1038 temp = matchkey(tokens[i++], tos_keywords, 1); 1039 if (i > ntokens - 1) { 1040 msyslog(LOG_ERR, 1041 "tinker: missing argument"); 1042 errflg++; 1043 break; 1044 } 1045 sscanf(tokens[i], "%lf", &ftemp); 1046 switch(temp) { 1047 1048 case CONF_TOS_MINCLOCK: 1049 proto_config(PROTO_MINCLOCK, 0, ftemp, NULL); 1050 break; 1051 1052 case CONF_TOS_MINSANE: 1053 proto_config(PROTO_MINSANE, 0, ftemp, NULL); 1054 break; 1055 1056 case CONF_TOS_FLOOR: 1057 proto_config(PROTO_FLOOR, 0, ftemp, NULL); 1058 break; 1059 1060 case CONF_TOS_CEILING: 1061 proto_config(PROTO_CEILING, 0, ftemp, NULL); 1062 break; 1063 1064 case CONF_TOS_COHORT: 1065 proto_config(PROTO_COHORT, 0, ftemp, NULL); 1066 break; 1067 } 1068 } 1069 break; 1070 1071 case CONFIG_TTL: 1072 for (i = 1; i < ntokens && i < MAX_TTL; i++) { 1073 sys_ttl[i - 1] = (u_char) atoi(tokens[i]); 1074 sys_ttlmax = i - 1; 1075 } 1076 break; 1077 1078 case CONFIG_DISCARD: 1079 for (i = 1; i < ntokens; i++) { 1080 int temp; 1081 1082 temp = matchkey(tokens[i++], 1083 discard_keywords, 1); 1084 if (i > ntokens - 1) { 1085 msyslog(LOG_ERR, 1086 "discard: missing argument"); 1087 errflg++; 1088 break; 1089 } 1090 switch(temp) { 1091 case CONF_DISCARD_AVERAGE: 1092 res_avg_interval = atoi(tokens[i++]); 1093 break; 1094 1095 case CONF_DISCARD_MINIMUM: 1096 res_min_interval = atoi(tokens[i++]); 1097 break; 1098 1099 case CONF_DISCARD_MONITOR: 1100 mon_age = atoi(tokens[i++]); 1101 break; 1102 1103 default: 1104 msyslog(LOG_ERR, 1105 "discard: unknown keyword"); 1106 break; 1107 } 1108 } 1109 break; 1110 1111#ifdef OPENSSL |
1112 case CONFIG_REVOKE: 1113 if (ntokens >= 2)
|
1006 sys_revoke = 1 << max(atoi(tokens[1]), 10);
|
1114 sys_revoke = (u_char) max(atoi(tokens[1]), KEY_REVOKE); |
1115 break; 1116 1117 case CONFIG_AUTOMAX: 1118 if (ntokens >= 2) 1119 sys_automax = 1 << max(atoi(tokens[1]), 10); 1120 break; 1121
|
1014#ifdef PUBKEY
1015 case CONFIG_KEYSDIR:
1016 if (ntokens < 2) {
1017 msyslog(LOG_ERR,
1018 "Keys directory name required");
1019 break;
1020 }
1021 crypto_config(CRYPTO_CONF_KEYS, tokens[1]);
1022 break;
1023
|
1122 case CONFIG_CRYPTO: 1123 if (ntokens == 1) {
|
1026 crypto_config(CRYPTO_CONF_FLAGS , "0");
|
1124 crypto_config(CRYPTO_CONF_NONE, NULL); |
1125 break; 1126 } 1127 for (i = 1; i < ntokens; i++) { 1128 int temp; 1129
|
1032 temp = matchkey(tokens[i++], crypto_keywords);
|
1130 temp = matchkey(tokens[i++], 1131 crypto_keywords, 1); |
1132 if (i > ntokens - 1) { 1133 msyslog(LOG_ERR, 1134 "crypto: missing argument"); 1135 errflg++; 1136 break; 1137 } 1138 switch(temp) {
|
1040 case CONF_CRYPTO_FLAGS:
1041 crypto_config(CRYPTO_CONF_FLAGS, tokens[i]);
|
1139 1140 case CONF_CRYPTO_CERT: 1141 crypto_config(CRYPTO_CONF_CERT, 1142 tokens[i]); |
1143 break; 1144
|
1044 case CONF_CRYPTO_LEAP:
1045 crypto_config(CRYPTO_CONF_LEAP, tokens[i]);
|
1145 case CONF_CRYPTO_RSA: 1146 crypto_config(CRYPTO_CONF_PRIV, 1147 tokens[i]); |
1148 break; 1149
|
1048 case CONF_CRYPTO_DH:
1049 crypto_config(CRYPTO_CONF_DH, tokens[i]);
|
1150 case CONF_CRYPTO_IFFPAR: 1151 crypto_config(CRYPTO_CONF_IFFPAR, 1152 tokens[i]); |
1153 break; 1154
|
1052 case CONF_CRYPTO_PRIVATEKEY:
1053 crypto_config(CRYPTO_CONF_PRIV, tokens[i]);
|
1155 case CONF_CRYPTO_GQPAR: 1156 crypto_config(CRYPTO_CONF_GQPAR, 1157 tokens[i]); |
1158 break; 1159
|
1056 case CONF_CRYPTO_PUBLICKEY:
1057 crypto_config(CRYPTO_CONF_PUBL, tokens[i]);
|
1160 case CONF_CRYPTO_MVPAR: 1161 crypto_config(CRYPTO_CONF_MVPAR, 1162 tokens[i]); |
1163 break; 1164
|
1060 case CONF_CRYPTO_CERT:
1061 crypto_config(CRYPTO_CONF_CERT, tokens[i]);
|
1165 case CONF_CRYPTO_LEAP: 1166 crypto_config(CRYPTO_CONF_LEAP, 1167 tokens[i]); |
1168 break; 1169
|
1170 case CONF_CRYPTO_PW: 1171 crypto_config(CRYPTO_CONF_PW, 1172 tokens[i]); 1173 break; 1174 1175 case CONF_CRYPTO_RAND: 1176 crypto_config(CRYPTO_CONF_RAND, 1177 tokens[i]); 1178 break; 1179 1180 case CONF_CRYPTO_SIGN: 1181 crypto_config(CRYPTO_CONF_SIGN, 1182 tokens[i]); 1183 break; 1184 |
1185 default:
|
1065 msyslog(LOG_ERR, "crypto: unknown keyword");
|
1186 msyslog(LOG_ERR, 1187 "crypto: unknown keyword"); |
1188 break; 1189 } 1190 } 1191 break;
|
1070#endif /* PUBKEY */
1071#endif /* AUTOKEY */
|
1192#endif /* OPENSSL */ |
1193 1194 case CONFIG_RESTRICT: 1195 if (ntokens < 2) { 1196 msyslog(LOG_ERR, "restrict requires an address"); 1197 break; 1198 }
|
1078 if (STREQ(tokens[1], "default"))
1079 peeraddr.sin_addr.s_addr = htonl(INADDR_ANY);
1080 else if (!getnetnum(tokens[1], &peeraddr, 1))
1081 break;
|
1199 istart = 1; 1200 memset((char *)&peeraddr, 0, sizeof(peeraddr)); 1201 switch (matchkey(tokens[istart], addr_type, 0)) { 1202 case CONF_ADDR_IPV4: 1203 peeraddr.ss_family = AF_INET; 1204 istart++; 1205 break; 1206 case CONF_ADDR_IPV6: 1207 peeraddr.ss_family = AF_INET6; 1208 istart++; 1209 break; 1210 } |
1211 1212 /*
|
1213 * Assume default means an IPv4 address, except 1214 * if forced by a -4 or -6. 1215 */ 1216 if (STREQ(tokens[istart], "default")) { 1217 if (peeraddr.ss_family == 0) 1218 peeraddr.ss_family = AF_INET; 1219 } else if (!getnetnum(tokens[istart], &peeraddr, 1)) 1220 break; 1221 1222 /* |
1223 * Use peerversion as flags, peerkey as mflags. Ick. 1224 */ 1225 peerversion = 0; 1226 peerkey = 0; 1227 errflg = 0;
|
1089 maskaddr.sin_addr.s_addr = ~(u_int32)0;
1090 for (i = 2; i < ntokens; i++) {
1091 switch (matchkey(tokens[i], res_keywords)) {
|
1228 SET_HOSTMASK(&maskaddr, peeraddr.ss_family); 1229 istart++; 1230 for (i = istart; i < ntokens; i++) { 1231 switch (matchkey(tokens[i], res_keywords, 1)) { |
1232 case CONF_RES_MASK: 1233 if (i >= ntokens-1) { 1234 msyslog(LOG_ERR, 1235 "mask keyword needs argument"); 1236 errflg++; 1237 break; 1238 } 1239 i++; 1240 if (!getnetnum(tokens[i], &maskaddr, 1)) 1241 errflg++; 1242 break; 1243 1244 case CONF_RES_IGNORE: 1245 peerversion |= RES_IGNORE; 1246 break; 1247 1248 case CONF_RES_NOSERVE: 1249 peerversion |= RES_DONTSERVE; 1250 break; 1251 1252 case CONF_RES_NOTRUST: 1253 peerversion |= RES_DONTTRUST; 1254 break; 1255 1256 case CONF_RES_NOQUERY: 1257 peerversion |= RES_NOQUERY; 1258 break; 1259 1260 case CONF_RES_NOMODIFY: 1261 peerversion |= RES_NOMODIFY; 1262 break; 1263 1264 case CONF_RES_NOPEER: 1265 peerversion |= RES_NOPEER; 1266 break; 1267 1268 case CONF_RES_NOTRAP: 1269 peerversion |= RES_NOTRAP; 1270 break; 1271 1272 case CONF_RES_LPTRAP: 1273 peerversion |= RES_LPTRAP; 1274 break; 1275 1276 case CONF_RES_NTPPORT: 1277 peerkey |= RESM_NTPONLY; 1278 break; 1279 1280 case CONF_RES_VERSION: 1281 peerversion |= RES_VERSION; 1282 break; 1283 1284 case CONF_RES_DEMOBILIZE: 1285 peerversion |= RES_DEMOBILIZE; 1286 break; 1287 1288 case CONF_RES_LIMITED: 1289 peerversion |= RES_LIMITED; 1290 break; 1291 1292 case CONFIG_UNKNOWN: 1293 errflg++; 1294 break; 1295 } 1296 }
|
1157 if (SRCADR(&peeraddr) == htonl(INADDR_ANY))
1158 maskaddr.sin_addr.s_addr = 0;
|
1297 if (SOCKNUL(&peeraddr)) 1298 ANYSOCK(&maskaddr); |
1299 if (!errflg) 1300 hack_restrict(RESTRICT_FLAGS, &peeraddr, &maskaddr, 1301 (int)peerkey, peerversion); 1302 break; 1303 1304 case CONFIG_BDELAY: 1305 if (ntokens >= 2) { 1306 double tmp; 1307 1308 if (sscanf(tokens[1], "%lf", &tmp) != 1) { 1309 msyslog(LOG_ERR, 1310 "broadcastdelay value %s undecodable", 1311 tokens[1]); 1312 } else {
|
1173 proto_config(PROTO_BROADDELAY, 0, tmp);
|
1313 proto_config(PROTO_BROADDELAY, 0, tmp, NULL); |
1314 } 1315 } 1316 break; 1317
|
1318 case CONFIG_CDELAY: 1319 if (ntokens >= 2) { 1320 u_long ui; 1321 1322 if (sscanf(tokens[1], "%ld", &ui) != 1) 1323 msyslog(LOG_ERR, 1324 "illegal value - line ignored"); 1325 else 1326 proto_config(PROTO_CALLDELAY, ui, 0, NULL); 1327 } 1328 break; 1329 |
1330 case CONFIG_TRUSTEDKEY: 1331 for (i = 1; i < ntokens; i++) { 1332 keyid_t tkey; 1333 1334 tkey = atol(tokens[i]); 1335 if (tkey == 0) { 1336 msyslog(LOG_ERR, 1337 "trusted key %s unlikely", 1338 tokens[i]); 1339 } else { 1340 authtrust(tkey, 1); 1341 } 1342 } 1343 break; 1344 1345 case CONFIG_REQUESTKEY: 1346 if (ntokens >= 2) { 1347 if (!atouint(tokens[1], &ul)) { 1348 msyslog(LOG_ERR, 1349 "%s is undecodable as request key", 1350 tokens[1]); 1351 } else if (ul == 0) { 1352 msyslog(LOG_ERR, 1353 "%s makes a poor request keyid", 1354 tokens[1]); 1355 } else { 1356#ifdef DEBUG 1357 if (debug > 3) 1358 printf( 1359 "set info_auth_key to %08lx\n", ul); 1360#endif 1361 info_auth_keyid = (keyid_t)ul; 1362 } 1363 } 1364 break; 1365 1366 case CONFIG_CONTROLKEY: 1367 if (ntokens >= 2) { 1368 keyid_t ckey; 1369 1370 ckey = atol(tokens[1]); 1371 if (ckey == 0) { 1372 msyslog(LOG_ERR, 1373 "%s makes a poor control keyid", 1374 tokens[1]); 1375 } else { 1376 ctl_auth_keyid = ckey; 1377 } 1378 } 1379 break; 1380 1381 case CONFIG_TRAP: 1382 if (ntokens < 2) { 1383 msyslog(LOG_ERR, 1384 "no address for trap command, line ignored"); 1385 break; 1386 }
|
1235 if (!getnetnum(tokens[1], &peeraddr, 1))
|
1387 istart = 1; 1388 memset((char *)&peeraddr, 0, sizeof(peeraddr)); 1389 switch (matchkey(tokens[istart], addr_type, 0)) { 1390 case CONF_ADDR_IPV4: 1391 peeraddr.ss_family = AF_INET; 1392 istart++; 1393 break; 1394 case CONF_ADDR_IPV6: 1395 peeraddr.ss_family = AF_INET6; 1396 istart++; 1397 break; 1398 } 1399 1400 if (!getnetnum(tokens[istart], &peeraddr, 1)) |
1401 break; 1402 1403 /* 1404 * Use peerversion for port number. Barf. 1405 */ 1406 errflg = 0; 1407 peerversion = 0; 1408 localaddr = 0;
|
1244 for (i = 2; i < ntokens-1; i++)
1245 switch (matchkey(tokens[i], trap_keywords)) {
|
1409 istart++; 1410 for (i = istart; i < ntokens-1; i++) 1411 switch (matchkey(tokens[i], trap_keywords, 1)) { |
1412 case CONF_TRAP_PORT: 1413 if (i >= ntokens-1) { 1414 msyslog(LOG_ERR, 1415 "trap port requires an argument"); 1416 errflg = 1; 1417 break; 1418 } 1419 peerversion = atoi(tokens[++i]); 1420 if (peerversion <= 0 1421 || peerversion > 32767) { 1422 msyslog(LOG_ERR, 1423 "invalid port number %s, trap ignored", 1424 tokens[i]); 1425 errflg = 1; 1426 } 1427 break; 1428 1429 case CONF_TRAP_INTERFACE: 1430 if (i >= ntokens-1) { 1431 msyslog(LOG_ERR, 1432 "trap interface requires an argument"); 1433 errflg = 1; 1434 break; 1435 } 1436
|
1437 memset((char *)&maskaddr, 0, 1438 sizeof(maskaddr)); 1439 maskaddr.ss_family = peeraddr.ss_family; |
1440 if (!getnetnum(tokens[++i], 1441 &maskaddr, 1)) { 1442 errflg = 1; 1443 break; 1444 } 1445 1446 localaddr = findinterface(&maskaddr); 1447 if (localaddr == NULL) { 1448 msyslog(LOG_ERR, 1449 "can't find interface with address %s",
|
1281 ntoa(&maskaddr));
|
1450 stoa(&maskaddr)); |
1451 errflg = 1; 1452 } 1453 break; 1454 1455 case CONFIG_UNKNOWN: 1456 errflg++; 1457 break; 1458 } 1459 1460 if (!errflg) { 1461 if (peerversion != 0)
|
1293 peeraddr.sin_port = htons( (u_short) peerversion);
|
1462 ((struct sockaddr_in6*)&peeraddr)->sin6_port = htons( (u_short) peerversion); |
1463 else
|
1295 peeraddr.sin_port = htons(TRAPPORT);
|
1464 ((struct sockaddr_in6*)&peeraddr)->sin6_port = htons(TRAPPORT); |
1465 if (localaddr == NULL)
|
1297 localaddr = any_interface;
|
1466 localaddr = ANY_INTERFACE_CHOOSE(&peeraddr); |
1467 if (!ctlsettrap(&peeraddr, localaddr, 0, 1468 NTP_VERSION)) 1469 msyslog(LOG_ERR, 1470 "can't set trap for %s, no resources",
|
1302 ntoa(&peeraddr));
|
1471 stoa(&peeraddr)); |
1472 } 1473 break; 1474 1475 case CONFIG_FUDGE: 1476 if (ntokens < 2) { 1477 msyslog(LOG_ERR, 1478 "no address for fudge command, line ignored"); 1479 break; 1480 }
|
1481 memset((char *)&peeraddr, 0, sizeof(peeraddr)); |
1482 if (!getnetnum(tokens[1], &peeraddr, 1)) 1483 break; 1484 1485 if (!ISREFCLOCKADR(&peeraddr)) { 1486 msyslog(LOG_ERR, 1487 "%s is inappropriate address for the fudge command, line ignored",
|
1318 ntoa(&peeraddr));
|
1488 stoa(&peeraddr)); |
1489 break; 1490 } 1491 1492 memset((void *)&clock_stat, 0, sizeof clock_stat); 1493 fudgeflag = 0; 1494 errflg = 0; 1495 for (i = 2; i < ntokens-1; i++) { 1496 switch (c = matchkey(tokens[i],
|
1327 fudge_keywords)) {
|
1497 fudge_keywords, 1)) { |
1498 case CONF_FDG_TIME1: 1499 if (sscanf(tokens[++i], "%lf", 1500 &clock_stat.fudgetime1) != 1) { 1501 msyslog(LOG_ERR, 1502 "fudge %s time1 value in error",
|
1333 ntoa(&peeraddr));
|
1503 stoa(&peeraddr)); |
1504 errflg = i; 1505 break; 1506 } 1507 clock_stat.haveflags |= CLK_HAVETIME1; 1508 break; 1509 1510 case CONF_FDG_TIME2: 1511 if (sscanf(tokens[++i], "%lf", 1512 &clock_stat.fudgetime2) != 1) { 1513 msyslog(LOG_ERR, 1514 "fudge %s time2 value in error",
|
1345 ntoa(&peeraddr));
|
1515 stoa(&peeraddr)); |
1516 errflg = i; 1517 break; 1518 } 1519 clock_stat.haveflags |= CLK_HAVETIME2; 1520 break; 1521 1522 1523 case CONF_FDG_STRATUM: 1524 if (!atoint(tokens[++i], &stratum)) 1525 { 1526 msyslog(LOG_ERR, 1527 "fudge %s stratum value in error",
|
1358 ntoa(&peeraddr));
|
1528 stoa(&peeraddr)); |
1529 errflg = i; 1530 break; 1531 } 1532 clock_stat.fudgeval1 = stratum; 1533 clock_stat.haveflags |= CLK_HAVEVAL1; 1534 break; 1535 1536 case CONF_FDG_REFID: 1537 /* HMS: Endianness and 0 bytes? */ 1538 /* XXX */ 1539 strncpy((char *)&clock_stat.fudgeval2, 1540 tokens[++i], 4); 1541 clock_stat.haveflags |= CLK_HAVEVAL2; 1542 break; 1543 1544 case CONF_FDG_FLAG1: 1545 case CONF_FDG_FLAG2: 1546 case CONF_FDG_FLAG3: 1547 case CONF_FDG_FLAG4: 1548 if (!atouint(tokens[++i], &fudgeflag) 1549 || fudgeflag > 1) { 1550 msyslog(LOG_ERR, 1551 "fudge %s flag value in error",
|
1382 ntoa(&peeraddr));
|
1552 stoa(&peeraddr)); |
1553 errflg = i; 1554 break; 1555 } 1556 switch(c) { 1557 case CONF_FDG_FLAG1: 1558 c = CLK_FLAG1; 1559 clock_stat.haveflags|=CLK_HAVEFLAG1; 1560 break; 1561 case CONF_FDG_FLAG2: 1562 c = CLK_FLAG2; 1563 clock_stat.haveflags|=CLK_HAVEFLAG2; 1564 break; 1565 case CONF_FDG_FLAG3: 1566 c = CLK_FLAG3; 1567 clock_stat.haveflags|=CLK_HAVEFLAG3; 1568 break; 1569 case CONF_FDG_FLAG4: 1570 c = CLK_FLAG4; 1571 clock_stat.haveflags|=CLK_HAVEFLAG4; 1572 break; 1573 } 1574 if (fudgeflag == 0) 1575 clock_stat.flags &= ~c; 1576 else 1577 clock_stat.flags |= c; 1578 break; 1579 1580 case CONFIG_UNKNOWN: 1581 errflg = -1; 1582 break; 1583 } 1584 } 1585 1586#ifdef REFCLOCK 1587 /* 1588 * If reference clock support isn't defined the 1589 * fudge line will still be accepted and syntax 1590 * checked, but will essentially do nothing. 1591 */ 1592 if (!errflg) { 1593 refclock_control(&peeraddr, &clock_stat, 1594 (struct refclockstat *)0); 1595 } 1596#endif 1597 break; 1598 1599 case CONFIG_STATSDIR: 1600 if (ntokens >= 2) 1601 stats_config(STATS_STATSDIR,tokens[1]); 1602 break; 1603 1604 case CONFIG_STATISTICS: 1605 for (i = 1; i < ntokens; i++) { 1606 filegen = filegen_get(tokens[i]); 1607 1608 if (filegen == NULL) { 1609 msyslog(LOG_ERR, 1610 "no statistics named %s available", 1611 tokens[i]); 1612 continue; 1613 } 1614#ifdef DEBUG 1615 if (debug > 3) 1616 printf("enabling filegen for %s statistics \"%s%s\"\n", 1617 tokens[i], filegen->prefix, filegen->basename); 1618#endif 1619 filegen->flag |= FGEN_FLAG_ENABLED; 1620 } 1621 break; 1622 1623 case CONFIG_FILEGEN: 1624 if (ntokens < 2) { 1625 msyslog(LOG_ERR, 1626 "no id for filegen command, line ignored"); 1627 break; 1628 } 1629 1630 filegen = filegen_get(tokens[1]); 1631 if (filegen == NULL) { 1632 msyslog(LOG_ERR, 1633 "unknown filegen \"%s\" ignored", 1634 tokens[1]); 1635 break; 1636 } 1637 /* 1638 * peerversion is (ab)used for filegen file (index) 1639 * peerkey is (ab)used for filegen type 1640 * peerflags is (ab)used for filegen flags 1641 */ 1642 peerversion = 0; 1643 peerkey = filegen->type; 1644 peerflags = filegen->flag; 1645 errflg = 0; 1646 1647 for (i = 2; i < ntokens; i++) {
|
1478 switch (matchkey(tokens[i], filegen_keywords)) {
|
1648 switch (matchkey(tokens[i], 1649 filegen_keywords, 1)) { |
1650 case CONF_FGEN_FILE: 1651 if (i >= ntokens - 1) { 1652 msyslog(LOG_ERR, 1653 "filegen %s file requires argument", 1654 tokens[1]); 1655 errflg = i; 1656 break; 1657 } 1658 peerversion = ++i; 1659 break; 1660 case CONF_FGEN_TYPE: 1661 if (i >= ntokens -1) { 1662 msyslog(LOG_ERR, 1663 "filegen %s type requires argument", 1664 tokens[1]); 1665 errflg = i; 1666 break; 1667 }
|
1497 peerkey = matchkey(tokens[++i], fgen_types);
|
1668 peerkey = matchkey(tokens[++i], 1669 fgen_types, 1); |
1670 if (peerkey == CONFIG_UNKNOWN) { 1671 msyslog(LOG_ERR, 1672 "filegen %s unknown type \"%s\"", 1673 tokens[1], tokens[i]); 1674 errflg = i; 1675 break; 1676 } 1677 break; 1678 1679 case CONF_FGEN_FLAG_LINK: 1680 peerflags |= FGEN_FLAG_LINK; 1681 break; 1682 1683 case CONF_FGEN_FLAG_NOLINK: 1684 peerflags &= ~FGEN_FLAG_LINK; 1685 break; 1686 1687 case CONF_FGEN_FLAG_ENABLE: 1688 peerflags |= FGEN_FLAG_ENABLED; 1689 break; 1690 1691 case CONF_FGEN_FLAG_DISABLE: 1692 peerflags &= ~FGEN_FLAG_ENABLED; 1693 break; 1694 } 1695 } 1696 if (!errflg) 1697 filegen_config(filegen, tokens[peerversion], 1698 (u_char)peerkey, (u_char)peerflags); 1699 break; 1700 1701 case CONFIG_SETVAR: 1702 if (ntokens < 2) { 1703 msyslog(LOG_ERR, 1704 "no value for setvar command - line ignored"); 1705 } else { 1706 set_sys_var(tokens[1], strlen(tokens[1])+1,
|
1535 RW |
|
1707 (u_short) (RW | |
1708 ((((ntokens > 2) 1709 && !strcmp(tokens[2], 1710 "default"))) 1711 ? DEF
|
1540 : 0));
|
1712 : 0))); |
1713 } 1714 break; 1715
|
1544 case CONFIG_CLIENTLIMIT:
1545 if (ntokens < 2) {
1546 msyslog(LOG_ERR,
1547 "no value for clientlimit command - line ignored");
1548 } else {
1549 u_long ui;
1550
1551 if (!atouint(tokens[1], &ui) || !ui) {
1552 msyslog(LOG_ERR,
1553 "illegal value for clientlimit command - line ignored");
1554 } else {
1555 char bp[80];
1556
1557#ifdef DEBUG
1558 if (debug)
1559 sprintf(bp, "client_limit=%lu", ui);
1560#endif
1561 set_sys_var(bp, strlen(bp)+1, RO);
1562 client_limit = ui;
1563 }
1564 }
1565 break;
1566
1567 case CONFIG_CLIENTPERIOD:
1568 if (ntokens < 2) {
1569 msyslog(LOG_ERR,
1570 "no value for clientperiod command - line ignored");
1571 } else {
1572 u_long ui;
1573
1574 if (!atouint(tokens[1], &ui) || ui < 64) {
1575 msyslog(LOG_ERR,
1576 "illegal value for clientperiod command - line ignored");
1577 } else {
1578 char bp[80];
1579
1580 sprintf(bp, "client_limit_period=%ld", ui);
1581 set_sys_var(bp, strlen(bp)+1, RO);
1582 client_limit_period = ui;
1583 }
1584 }
1585 break;
1586
|
1716 case CONFIG_ENABLE: 1717 for (i = 1; i < ntokens; i++) { 1718 int flag; 1719
|
1591 flag = matchkey(tokens[i], flags_keywords);
|
1720 flag = matchkey(tokens[i], flags_keywords, 1); |
1721 if (flag == CONFIG_UNKNOWN) { 1722 msyslog(LOG_ERR, 1723 "enable unknown flag %s", 1724 tokens[i]); 1725 errflg = 1; 1726 break; 1727 }
|
1599 proto_config(flag, 1, 0.);
|
1728 proto_config(flag, 1, 0., NULL); |
1729 } 1730 break; 1731 1732 case CONFIG_DISABLE: 1733 for (i = 1; i < ntokens; i++) { 1734 int flag; 1735
|
1607 flag = matchkey(tokens[i], flags_keywords);
|
1736 flag = matchkey(tokens[i], flags_keywords, 1); |
1737 if (flag == CONFIG_UNKNOWN) { 1738 msyslog(LOG_ERR, 1739 "disable unknown flag %s", 1740 tokens[i]); 1741 errflg = 1; 1742 break; 1743 }
|
1615 proto_config(flag, 0, 0.);
|
1744 proto_config(flag, 0, 0., NULL); |
1745 } 1746 break; 1747 1748 case CONFIG_PHONE: 1749 for (i = 1; i < ntokens && i < MAXPHONE; i++) { 1750 (void)strncpy(sys_phone[i - 1], 1751 tokens[i], MAXDIAL); 1752 } 1753 sys_phone[i - 1][0] = '\0'; 1754 break; 1755
|
1627 case CONFIG_PPS:
1628 if (ntokens < 2) {
1629 msyslog(LOG_ERR,
1630 "pps missing device name");
1631 break;
1632 }
1633 (void)strncpy(pps_device, tokens[1], MAXPPS);
1634 for (i = 2; i < ntokens; i++) {
1635 int flag;
|
1756 case CONFIG_ADJ: { 1757 double ftemp; |
1758
|
1637 flag = matchkey(tokens[i], pps_keywords);
1638 switch(flag) {
1639 case CONF_PPS_ASSERT:
1640 pps_assert = 0;
1641 break;
1642 case CONF_PPS_CLEAR:
1643 pps_assert = 1;
1644 break;
1645 case CONF_PPS_HARDPPS:
1646 pps_hardpps = 1;
1647 break;
1648 default:
1649 msyslog(LOG_ERR,
1650 "pps unknown flag %s",
1651 tokens[i]);
1652 errflg = 1;
1653 break;
1654 }
1655 if(errflg)
1656 break;
|
1759 sscanf(tokens[1], "%lf", &ftemp); 1760 proto_config(PROTO_ADJ, 0, ftemp, NULL); |
1761 } 1762 break;
|
1763 |
1764 } 1765 } 1766 if (fp[0]) 1767 (void)fclose(fp[0]); 1768 1769#ifdef HAVE_NETINFO 1770 if (config_netinfo) 1771 free_netinfo_config(config_netinfo); 1772#endif /* HAVE_NETINFO */ 1773 1774#if !defined(VMS) && !defined(SYS_VXWORKS) 1775 /* find a keyid */ 1776 if (info_auth_keyid == 0) 1777 req_keyid = 65535; 1778 else 1779 req_keyid = info_auth_keyid; 1780 1781 /* if doesn't exist, make up one at random */ 1782 if (!authhavekey(req_keyid)) { 1783 char rankey[9]; 1784 int j; 1785 1786 for (i = 0; i < 8; i++) 1787 for (j = 1; j < 100; ++j) {
|
1683 rankey[i] = RANDOM & 0xff;
|
1788 rankey[i] = (char) (RANDOM & 0xff); |
1789 if (rankey[i] != 0) break; 1790 } 1791 rankey[8] = 0; 1792 authusekey(req_keyid, KEY_TYPE_MD5, (u_char *)rankey); 1793 authtrust(req_keyid, 1); 1794 if (!authhavekey(req_keyid)) { 1795 msyslog(LOG_ERR, "getconfig: Couldn't generate a valid random key!"); 1796 /* HMS: Should this be fatal? */ 1797 } 1798 } 1799 1800 /* save keyid so we will accept config requests with it */ 1801 info_auth_keyid = req_keyid; 1802#endif /* !defined(VMS) && !defined(SYS_VXWORKS) */ 1803 1804 if (res_fp != NULL) {
|
1700 /*
1701 * Need name resolution
1702 */
1703 do_resolve_internal();
|
1805 if (call_resolver) { 1806 /* 1807 * Need name resolution 1808 */ 1809 do_resolve_internal(); 1810 } |
1811 } 1812} 1813 1814 1815#ifdef HAVE_NETINFO 1816 1817/* 1818 * get_netinfo_config - find the nearest NetInfo domain with an ntp 1819 * configuration and initialize the configuration state. 1820 */ 1821static struct netinfo_config_state * 1822get_netinfo_config() 1823{ 1824 ni_status status; 1825 void *domain; 1826 ni_id config_dir; 1827 struct netinfo_config_state *config; 1828 1829 if (ni_open(NULL, ".", &domain) != NI_OK) return NULL; 1830 1831 while ((status = ni_pathsearch(domain, &config_dir, NETINFO_CONFIG_DIR)) == NI_NODIR) { 1832 void *next_domain; 1833 if (ni_open(domain, "..", &next_domain) != NI_OK) { 1834 ni_free(next_domain); 1835 break; 1836 } 1837 ni_free(domain); 1838 domain = next_domain; 1839 } 1840 if (status != NI_OK) { 1841 ni_free(domain); 1842 return NULL; 1843 } 1844 1845 config = (struct netinfo_config_state *)malloc(sizeof(struct netinfo_config_state)); 1846 config->domain = domain; 1847 config->config_dir = config_dir; 1848 config->prop_index = 0; 1849 config->val_index = 0; 1850 config->val_list = NULL; 1851 1852 return config; 1853} 1854 1855 1856 1857/* 1858 * free_netinfo_config - release NetInfo configuration state 1859 */ 1860static void 1861free_netinfo_config(struct netinfo_config_state *config) 1862{ 1863 ni_free(config->domain); 1864 free(config); 1865} 1866 1867 1868 1869/* 1870 * gettokens_netinfo - return tokens from NetInfo 1871 */ 1872static int 1873gettokens_netinfo ( 1874 struct netinfo_config_state *config, 1875 char **tokenlist, 1876 int *ntokens 1877 ) 1878{ 1879 int prop_index = config->prop_index; 1880 int val_index = config->val_index; 1881 char **val_list = config->val_list; 1882 1883 /* 1884 * Iterate through each keyword and look for a property that matches it. 1885 */ 1886 again: 1887 if (!val_list) { 1888 for (; prop_index < (sizeof(keywords)/sizeof(keywords[0])); prop_index++) 1889 { 1890 ni_namelist namelist; 1891 struct keyword current_prop = keywords[prop_index]; 1892 1893 /* 1894 * For each value associated in the property, we're going to return 1895 * a separate line. We squirrel away the values in the config state 1896 * so the next time through, we don't need to do this lookup. 1897 */ 1898 NI_INIT(&namelist); 1899 if (ni_lookupprop(config->domain, &config->config_dir, current_prop.text, &namelist) == NI_OK) { 1900 ni_index index; 1901 1902 /* Found the property, but it has no values */ 1903 if (namelist.ni_namelist_len == 0) continue; 1904 1905 if (! (val_list = config->val_list = (char**)malloc(sizeof(char*) * (namelist.ni_namelist_len + 1)))) 1906 { msyslog(LOG_ERR, "out of memory while configuring"); break; } 1907 1908 for (index = 0; index < namelist.ni_namelist_len; index++) { 1909 char *value = namelist.ni_namelist_val[index]; 1910
|
1804 if (! (val_list[index] = (char*)malloc(strlen(value+1))))
|
1911 if (! (val_list[index] = (char*)malloc(strlen(value)+1))) |
1912 { msyslog(LOG_ERR, "out of memory while configuring"); break; } 1913 1914 strcpy(val_list[index], value); 1915 } 1916 val_list[index] = NULL; 1917 1918 break; 1919 } 1920 ni_namelist_free(&namelist); 1921 } 1922 config->prop_index = prop_index; 1923 } 1924 1925 /* No list; we're done here. */ 1926 if (!val_list) return CONFIG_UNKNOWN; 1927 1928 /* 1929 * We have a list of values for the current property. 1930 * Iterate through them and return each in order. 1931 */ 1932 if (val_list[val_index]) 1933 { 1934 int ntok = 1; 1935 int quoted = 0; 1936 char *tokens = val_list[val_index]; 1937 1938 msyslog(LOG_INFO, "%s %s", keywords[prop_index].text, val_list[val_index]); 1939 1940 (const char*)tokenlist[0] = keywords[prop_index].text; 1941 for (ntok = 1; ntok < MAXTOKENS; ntok++) { 1942 tokenlist[ntok] = tokens; 1943 while (!ISEOL(*tokens) && (!ISSPACE(*tokens) || quoted)) 1944 quoted ^= (*tokens++ == '"'); 1945 1946 if (ISEOL(*tokens)) { 1947 *tokens = '\0'; 1948 break; 1949 } else { /* must be space */ 1950 *tokens++ = '\0'; 1951 while (ISSPACE(*tokens)) tokens++; 1952 if (ISEOL(*tokens)) break; 1953 } 1954 } 1955 *ntokens = ntok + 1; 1956 1957 config->val_index++; 1958 1959 return keywords[prop_index].keytype; 1960 } 1961 1962 /* We're done with the current property. */ 1963 prop_index = ++config->prop_index; 1964 1965 /* Free val_list and reset counters. */ 1966 for (val_index = 0; val_list[val_index]; val_index++) 1967 free(val_list[val_index]); 1968 free(val_list); val_list = config->val_list = NULL; val_index = config->val_index = 0; 1969 1970 goto again; 1971} 1972 1973#endif /* HAVE_NETINFO */ 1974 1975 1976/* 1977 * gettokens - read a line and return tokens 1978 */ 1979static int 1980gettokens ( 1981 FILE *fp, 1982 char *line, 1983 char **tokenlist, 1984 int *ntokens 1985 ) 1986{ 1987 register char *cp; 1988 register int ntok; 1989 register int quoted = 0; 1990 1991 /* 1992 * Find start of first token 1993 */ 1994 again: 1995 while ((cp = fgets(line, MAXLINE, fp)) != NULL) { 1996 cp = line; 1997 while (ISSPACE(*cp)) 1998 cp++; 1999 if (!ISEOL(*cp)) 2000 break; 2001 } 2002 if (cp == NULL) { 2003 *ntokens = 0; 2004 return CONFIG_UNKNOWN; /* hack. Is recognized as EOF */ 2005 } 2006 2007 /* 2008 * Now separate out the tokens 2009 */ 2010 for (ntok = 0; ntok < MAXTOKENS; ntok++) { 2011 tokenlist[ntok] = cp; 2012 while (!ISEOL(*cp) && (!ISSPACE(*cp) || quoted)) 2013 quoted ^= (*cp++ == '"'); 2014 2015 if (ISEOL(*cp)) { 2016 *cp = '\0'; 2017 break; 2018 } else { /* must be space */ 2019 *cp++ = '\0'; 2020 while (ISSPACE(*cp)) 2021 cp++; 2022 if (ISEOL(*cp)) 2023 break; 2024 } 2025 } 2026 2027 /* 2028 * Return the match 2029 */ 2030 *ntokens = ntok + 1;
|
1924 ntok = matchkey(tokenlist[0], keywords);
|
2031 ntok = matchkey(tokenlist[0], keywords, 1); |
2032 if (ntok == CONFIG_UNKNOWN) 2033 goto again; 2034 return ntok; 2035} 2036 2037 2038 2039/* 2040 * matchkey - match a keyword to a list 2041 */ 2042static int 2043matchkey( 2044 register char *word,
|
1938 register struct keyword *keys
|
2045 register struct keyword *keys, 2046 int complain |
2047 ) 2048{ 2049 for (;;) { 2050 if (keys->keytype == CONFIG_UNKNOWN) {
|
1943 msyslog(LOG_ERR,
1944 "configure: keyword \"%s\" unknown, line ignored",
1945 word);
|
2051 if (complain) 2052 msyslog(LOG_ERR, 2053 "configure: keyword \"%s\" unknown, line ignored", 2054 word); |
2055 return CONFIG_UNKNOWN; 2056 } 2057 if (STRSAME(word, keys->text)) 2058 return keys->keytype; 2059 keys++; 2060 } 2061} 2062 2063 2064/* 2065 * getnetnum - return a net number (this is crude, but careful) 2066 */ 2067static int 2068getnetnum( 2069 const char *num,
|
1961 struct sockaddr_in *addr,
|
2070 struct sockaddr_storage *addr, |
2071 int complain 2072 ) 2073{
|
1965 register const char *cp;
1966 register char *bp;
1967 register int i;
1968 register int temp;
1969 char buf[80]; /* will core dump on really stupid stuff */
1970 u_int32 netnum;
|
2074 struct addrinfo hints; 2075 struct addrinfo *ptr; |
2076
|
1972 /* XXX ELIMINATE replace with decodenetnum */
1973 cp = num;
1974 netnum = 0;
1975 for (i = 0; i < 4; i++) {
1976 bp = buf;
1977 while (isdigit((int)*cp))
1978 *bp++ = *cp++;
1979 if (bp == buf)
1980 break;
|
2077 /* Get host address. Looking for UDP datagram connection */ 2078 memset(&hints, 0, sizeof (hints)); 2079 if (addr->ss_family == AF_INET || addr->ss_family == AF_INET6) 2080 hints.ai_family = addr->ss_family; 2081 else 2082 hints.ai_family = AF_UNSPEC; |
2083
|
1982 if (i < 3) {
1983 if (*cp++ != '.')
1984 break;
1985 } else if (*cp != '\0')
1986 break;
1987
1988 *bp = '\0';
1989 temp = atoi(buf);
1990 if (temp > 255)
1991 break;
1992 netnum <<= 8;
1993 netnum += temp;
|
2084 hints.ai_socktype = SOCK_DGRAM; |
2085#ifdef DEBUG 2086 if (debug > 3)
|
1996 printf("getnetnum %s step %d buf %s temp %d netnum %lu\n",
1997 num, i, buf, temp, (u_long)netnum);
|
2087 printf("getaddrinfo %s\n", num); |
2088#endif
|
1999 }
2000
2001 if (i < 4) {
|
2089 if (getaddrinfo(num, "ntp", &hints, &ptr)!=0) { |
2090 if (complain) 2091 msyslog(LOG_ERR,
|
2004 "getnetnum: \"%s\" invalid host number, line ignored",
|
2092 "getaddrinfo: \"%s\" invalid host address, line ignored", |
2093 num); 2094#ifdef DEBUG 2095 if (debug > 3) 2096 printf(
|
2009 "getnetnum: \"%s\" invalid host number, line ignored\n",
2010 num);
|
2097 "getaddrinfo: \"%s\" invalid host address%s.\n", 2098 num, (complain) 2099 ? ", line ignored" 2100 : ""); |
2101#endif 2102 return 0; 2103 } 2104
|
2015 /*
2016 * make up socket address. Clear it out for neatness.
2017 */
2018 memset((void *)addr, 0, sizeof(struct sockaddr_in));
2019 addr->sin_family = AF_INET;
2020 addr->sin_port = htons(NTP_PORT);
2021 addr->sin_addr.s_addr = htonl(netnum);
|
2105 memcpy(addr, ptr->ai_addr, ptr->ai_addrlen); |
2106#ifdef DEBUG 2107 if (debug > 1)
|
2024 printf("getnetnum given %s, got %s (%lx)\n",
2025 num, ntoa(addr), (u_long)netnum);
|
2108 printf("getnetnum given %s, got %s \n", 2109 num, stoa(addr)); |
2110#endif
|
2111 freeaddrinfo(ptr); |
2112 return 1; 2113} 2114 2115
|
2031#if !defined(VMS)
|
2116#if !defined(VMS) && !defined(SYS_WINNT) |
2117/* 2118 * catchchild - receive the resolver's exit status 2119 */ 2120static RETSIGTYPE 2121catchchild( 2122 int sig 2123 ) 2124{ 2125 /* 2126 * We only start up one child, and if we're here 2127 * it should have already exited. Hence the following 2128 * shouldn't hang. If it does, please tell me. 2129 */ 2130#if !defined (SYS_WINNT) && !defined(SYS_VXWORKS) 2131 (void) wait(0); 2132#endif /* SYS_WINNT && VXWORKS*/ 2133} 2134#endif /* VMS */ 2135 2136 2137/* 2138 * save_resolve - save configuration info into a file for later name resolution 2139 */ 2140static void 2141save_resolve( 2142 char *name, 2143 int mode, 2144 int version, 2145 int minpoll, 2146 int maxpoll, 2147 u_int flags, 2148 int ttl, 2149 keyid_t keyid, 2150 u_char *keystr 2151 ) 2152{ 2153#ifndef SYS_VXWORKS 2154 if (res_fp == NULL) { 2155#ifndef SYS_WINNT 2156 (void) strcpy(res_file, RES_TEMPFILE); 2157#else 2158 /* no /tmp directory under NT */ 2159 {
|
2075 DWORD len;
2076 if(!(len = GetTempPath((DWORD)MAX_PATH, (LPTSTR)res_file))) {
|
2160 if(!(GetTempPath((DWORD)MAX_PATH, (LPTSTR)res_file))) { |
2161 msyslog(LOG_ERR, "cannot get pathname for temporary directory: %m"); 2162 return; 2163 } 2164 (void) strcat(res_file, "ntpdXXXXXX"); 2165 } 2166#endif /* SYS_WINNT */ 2167#ifdef HAVE_MKSTEMP 2168 { 2169 int fd; 2170 2171 res_fp = NULL; 2172 if ((fd = mkstemp(res_file)) != -1) 2173 res_fp = fdopen(fd, "r+"); 2174 } 2175#else 2176 (void) mktemp(res_file); 2177 res_fp = fopen(res_file, "w"); 2178#endif 2179 if (res_fp == NULL) { 2180 msyslog(LOG_ERR, "open failed for %s: %m", res_file); 2181 return; 2182 } 2183 } 2184#ifdef DEBUG 2185 if (debug) { 2186 printf("resolving %s\n", name); 2187 } 2188#endif 2189 2190 (void)fprintf(res_fp, "%s %d %d %d %d %d %d %u %s\n", name, 2191 mode, version, minpoll, maxpoll, flags, ttl, keyid, keystr); 2192#ifdef DEBUG 2193 if (debug > 1) 2194 printf("config: %s %d %d %d %d %x %d %u %s\n", name, mode, 2195 version, minpoll, maxpoll, flags, ttl, keyid, keystr); 2196#endif 2197 2198#else /* SYS_VXWORKS */ 2199 /* save resolve info to a struct */ 2200#endif /* SYS_VXWORKS */ 2201} 2202 2203 2204/* 2205 * abort_resolve - terminate the resolver stuff and delete the file 2206 */ 2207static void 2208abort_resolve(void) 2209{ 2210 /* 2211 * In an ideal world we would might reread the file and 2212 * log the hosts which aren't getting configured. Since 2213 * this is too much work, however, just close and delete 2214 * the temp file. 2215 */ 2216 if (res_fp != NULL) 2217 (void) fclose(res_fp); 2218 res_fp = NULL; 2219 2220#ifndef SYS_VXWORKS /* we don't open the file to begin with */ 2221#if !defined(VMS) 2222 (void) unlink(res_file); 2223#else 2224 (void) delete(res_file); 2225#endif /* VMS */ 2226#endif /* SYS_VXWORKS */ 2227} 2228 2229 2230/* 2231 * do_resolve_internal - start up the resolver function (not program) 2232 */ 2233/* 2234 * On VMS, this routine will simply refuse to resolve anything. 2235 * 2236 * Possible implementation: keep `res_file' in memory, do async 2237 * name resolution via QIO, update from within completion AST. 2238 * I'm unlikely to find the time for doing this, though. -wjm 2239 */ 2240static void 2241do_resolve_internal(void) 2242{ 2243 int i; 2244 2245 if (res_fp == NULL) { 2246 /* belch */ 2247 msyslog(LOG_ERR, 2248 "do_resolve_internal: Fatal: res_fp == NULL"); 2249 exit(1); 2250 } 2251 2252 /* we are done with this now */ 2253 (void) fclose(res_fp); 2254 res_fp = NULL; 2255 2256#if !defined(VMS) && !defined (SYS_VXWORKS) 2257 req_file = res_file; /* set up pointer to res file */ 2258#ifndef SYS_WINNT 2259 (void) signal_no_reset(SIGCHLD, catchchild); 2260 2261#ifndef SYS_VXWORKS 2262 i = fork(); 2263 if (i == 0) { 2264 /* 2265 * this used to close everything 2266 * I don't think this is necessary 2267 */ 2268 /* 2269 * To the unknown commenter above: 2270 * Well, I think it's better to clean up 2271 * after oneself. I have had problems with 2272 * refclock-io when intres was running - things 2273 * where fine again when ntpintres was gone. 2274 * So some systems react erratic at least. 2275 * 2276 * Frank Kardel 2277 * 2278 * 94-11-16: 2279 * Further debugging has proven that the above is 2280 * absolutely harmful. The internal resolver 2281 * is still in the SIGIO process group and the lingering 2282 * async io information causes it to process requests from 2283 * all file decriptor causing a race between the NTP daemon 2284 * and the resolver. which then eats data when it wins 8-(. 2285 * It is absolutly necessary to kill any IO associations 2286 * shared with the NTP daemon. 2287 * 2288 * We also block SIGIO (currently no ports means to 2289 * disable the signal handle for IO). 2290 * 2291 * Thanks to wgstuken@informatik.uni-erlangen.de to notice 2292 * that it is the ntp-resolver child running into trouble. 2293 * 2294 * THUS: 2295 */ 2296 2297 closelog();
|
2214 kill_asyncio();
|
2298 kill_asyncio(0); |
2299 2300 (void) signal_no_reset(SIGCHLD, SIG_DFL); 2301 2302#ifdef DEBUG 2303 if (0) 2304 debug = 2; 2305#endif 2306 2307# ifndef LOG_DAEMON 2308 openlog("ntpd_initres", LOG_PID); 2309# else /* LOG_DAEMON */ 2310 2311# ifndef LOG_NTP 2312# define LOG_NTP LOG_DAEMON 2313# endif 2314 openlog("ntpd_initres", LOG_PID | LOG_NDELAY, LOG_NTP); 2315#ifndef SYS_CYGWIN32 2316# ifdef DEBUG 2317 if (debug) 2318 setlogmask(LOG_UPTO(LOG_DEBUG)); 2319 else 2320# endif /* DEBUG */ 2321 setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */ 2322# endif /* LOG_DAEMON */ 2323#endif 2324 2325 ntp_intres(); 2326 2327 /* 2328 * If we got here, the intres code screwed up. 2329 * Print something so we don't die without complaint 2330 */ 2331 msyslog(LOG_ERR, "call to ntp_intres lost"); 2332 abort_resolve(); 2333 exit(1); 2334 } 2335#else 2336 /* vxWorks spawns a thread... -casey */ 2337 i = sp (ntp_intres); 2338 /*i = taskSpawn("ntp_intres",100,VX_FP_TASK,20000,ntp_intres);*/ 2339#endif 2340 if (i == -1) { 2341 msyslog(LOG_ERR, "fork() failed, can't start ntp_intres: %m"); 2342 (void) signal_no_reset(SIGCHLD, SIG_DFL); 2343 abort_resolve(); 2344 } 2345#else /* SYS_WINNT */ 2346 { 2347 /* NT's equivalent of fork() is _spawn(), but the start point 2348 * of the new process is an executable filename rather than 2349 * a function name as desired here. 2350 */ 2351 DWORD dwThreadId; 2352 fflush(stdout);
|
2269 if (!(ResolverThreadHandle = CreateThread(
2270 NULL, /* no security attributes */
2271 0, /* use default stack size */
|
2353 ResolverThreadHandle = CreateThread( 2354 NULL, /* no security attributes */ 2355 0, /* use default stack size */ |
2356 (LPTHREAD_START_ROUTINE) ntp_intres, /* thread function */
|
2273 NULL, /* argument to thread function */
2274 0, /* use default creation flags */
2275 &dwThreadId))) { /* returns the thread identifier */
|
2357 NULL, /* argument to thread function */ 2358 0, /* use default creation flags */ 2359 &dwThreadId); /* returns the thread identifier */ 2360 if (ResolverThreadHandle == NULL) { |
2361 msyslog(LOG_ERR, "CreateThread() failed, can't start ntp_intres"); 2362 abort_resolve(); 2363 } 2364 } 2365#endif /* SYS_WINNT */ 2366#else /* VMS VX_WORKS */ 2367 msyslog(LOG_ERR, 2368 "Name resolution not implemented for VMS - use numeric addresses"); 2369 abort_resolve(); 2370#endif /* VMS VX_WORKS */ 2371}
|