void AddTrustedKey(keyid_t keyno) { /* * We need to add a MD5-key in addition to setting the * trust, because authhavekey() requires type != 0. */ MD5auth_setkey(keyno, KEYTYPE, NULL, 0); authtrust(keyno, TRUE); }
/* * getCmdOpts - get command line options */ void getCmdOpts( int argc, char *argv[] ) { extern const char *config_file; int errflg; tOptions *myOptions = &OPTSTRUCT; /* * Initialize, initialize */ errflg = 0; switch (WHICH_IDX_IPV4) { case INDEX_OPT_IPV4: default_ai_family = AF_INET; break; case INDEX_OPT_IPV6: default_ai_family = AF_INET6; break; default: /* ai_fam_templ = ai_fam_default; */ break; } if (HAVE_OPT( AUTHREQ )) proto_config(PROTO_AUTHENTICATE, 1, 0., NULL); if (HAVE_OPT( AUTHNOREQ )) proto_config(PROTO_AUTHENTICATE, 0, 0., NULL); if (HAVE_OPT( BCASTSYNC )) proto_config(PROTO_BROADCLIENT, 1, 0., NULL); if (HAVE_OPT( CONFIGFILE )) { config_file = OPT_ARG( CONFIGFILE ); #ifdef HAVE_NETINFO check_netinfo = 0; #endif } if (HAVE_OPT( DRIFTFILE )) stats_config(STATS_FREQ_FILE, OPT_ARG( DRIFTFILE )); if (HAVE_OPT( PANICGATE )) allow_panic = TRUE; if (HAVE_OPT( JAILDIR )) { #ifdef HAVE_DROPROOT droproot = 1; chrootdir = OPT_ARG( JAILDIR ); #else fprintf(stderr, "command line -i option (jaildir) is not supported by this binary" # ifndef SYS_WINNT ",\n" "can not drop root privileges. See configure options\n" "--enable-clockctl and --enable-linuxcaps.\n"); # else ".\n"); # endif msyslog(LOG_ERR, "command line -i option (jaildir) is not supported by this binary."); errflg++; #endif } if (HAVE_OPT( KEYFILE )) getauthkeys(OPT_ARG( KEYFILE )); if (HAVE_OPT( PIDFILE )) stats_config(STATS_PID_FILE, OPT_ARG( PIDFILE )); if (HAVE_OPT( QUIT )) mode_ntpdate = TRUE; if (HAVE_OPT( PROPAGATIONDELAY )) do { double tmp; const char *my_ntp_optarg = OPT_ARG( PROPAGATIONDELAY ); if (sscanf(my_ntp_optarg, "%lf", &tmp) != 1) { msyslog(LOG_ERR, "command line broadcast delay value %s undecodable", my_ntp_optarg); } else { proto_config(PROTO_BROADDELAY, 0, tmp, NULL); } } while (0); if (HAVE_OPT( STATSDIR )) stats_config(STATS_STATSDIR, OPT_ARG( STATSDIR )); if (HAVE_OPT( TRUSTEDKEY )) { int ct = STACKCT_OPT( TRUSTEDKEY ); const char** pp = STACKLST_OPT( TRUSTEDKEY ); do { u_long tkey; const char* p = *pp++; tkey = (int)atol(p); if (tkey == 0 || tkey > NTP_MAXKEY) { msyslog(LOG_ERR, "command line trusted key %s is invalid", p); } else { authtrust(tkey, 1); } } while (--ct > 0); } if (HAVE_OPT( USER )) { #ifdef HAVE_DROPROOT char *ntp_optarg = OPT_ARG( USER ); droproot = 1; user = emalloc(strlen(ntp_optarg) + 1); (void)strncpy(user, ntp_optarg, strlen(ntp_optarg) + 1); group = rindex(user, ':'); if (group) *group++ = '\0'; /* get rid of the ':' */ #else fprintf(stderr, "command line -u/--user option is not supported by this binary" # ifndef SYS_WINNT ",\n" "can not drop root privileges. See configure options\n" "--enable-clockctl and --enable-linuxcaps.\n"); # else ".\n"); # endif msyslog(LOG_ERR, "command line -u/--user option is not supported by this binary."); errflg++; #endif } if (HAVE_OPT( VAR )) { int ct = STACKCT_OPT( VAR ); const char** pp = STACKLST_OPT( VAR ); do { const char* my_ntp_optarg = *pp++; set_sys_var(my_ntp_optarg, strlen(my_ntp_optarg)+1, (u_short) (RW)); } while (--ct > 0); } if (HAVE_OPT( DVAR )) { int ct = STACKCT_OPT( DVAR ); const char** pp = STACKLST_OPT( DVAR ); do { const char* my_ntp_optarg = *pp++; set_sys_var(my_ntp_optarg, strlen(my_ntp_optarg)+1, (u_short) (RW | DEF)); } while (--ct > 0); } if (HAVE_OPT( SLEW )) clock_max = 600; if (HAVE_OPT( UPDATEINTERVAL )) { long val = OPT_VALUE_UPDATEINTERVAL; if (val >= 0) interface_interval = val; else { fprintf(stderr, "command line interface update interval %ld must not be negative\n", val); msyslog(LOG_ERR, "command line interface update interval %ld must not be negative", val); errflg++; } } #ifdef SIM if (HAVE_OPT( SIMBROADCASTDELAY )) sscanf(OPT_ARG( SIMBROADCASTDELAY ), "%lf", &ntp_node.bdly); if (HAVE_OPT( PHASENOISE )) sscanf(OPT_ARG( PHASENOISE ), "%lf", &ntp_node.snse); if (HAVE_OPT( SIMSLEW )) sscanf(OPT_ARG( SIMSLEW ), "%lf", &ntp_node.slew); if (HAVE_OPT( SERVERTIME )) sscanf(OPT_ARG( SERVERTIME ), "%lf", &ntp_node.clk_time); if (HAVE_OPT( ENDSIMTIME )) sscanf(OPT_ARG( ENDSIMTIME ), "%lf", &ntp_node.sim_time); if (HAVE_OPT( FREQERR )) sscanf(OPT_ARG( FREQERR ), "%lf", &ntp_node.ferr); if (HAVE_OPT( WALKNOISE )) sscanf(OPT_ARG( WALKNOISE ), "%lf", &ntp_node.fnse); if (HAVE_OPT( NDELAY )) sscanf(OPT_ARG( NDELAY ), "%lf", &ntp_node.ndly); if (HAVE_OPT( PDELAY )) sscanf(OPT_ARG( PDELAY ), "%lf", &ntp_node.pdly); #endif /* SIM */ if (errflg || argc) { if (argc) fprintf(stderr, "argc after processing is <%d>\n", argc); optionUsage(myOptions, 2); } return; }
/* * sendrequest - format and send a request packet * * Historically, ntpdc has used a fixed-size request packet regardless * of the actual payload size. When authenticating, the timestamp, key * ID, and digest have been placed just before the end of the packet. * With the introduction in late 2009 of support for authenticated * ntpdc requests using larger 20-octet digests (vs. 16 for MD5), we * come up four bytes short. * * To maintain interop while allowing for larger digests, the behavior * is unchanged when using 16-octet digests. For larger digests, the * timestamp, key ID, and digest are placed immediately following the * request payload, with the overall packet size variable. ntpd can * distinguish 16-octet digests by the overall request size being * REQ_LEN_NOMAC + 4 + 16 with the auth bit enabled. When using a * longer digest, that request size should be avoided. * * With the form used with 20-octet and larger digests, the timestamp, * key ID, and digest are located by ntpd relative to the start of the * packet, and the size of the digest is then implied by the packet * size. */ static int sendrequest( int implcode, int reqcode, int auth, u_int qitems, size_t qsize, char *qdata ) { struct req_pkt qpkt; size_t datasize; size_t reqsize; u_long key_id; l_fp ts; l_fp * ptstamp; int maclen; char * pass; memset(&qpkt, 0, sizeof(qpkt)); qpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0); qpkt.implementation = (u_char)implcode; qpkt.request = (u_char)reqcode; datasize = qitems * qsize; if (datasize && qdata != NULL) { memcpy(qpkt.data, qdata, datasize); qpkt.err_nitems = ERR_NITEMS(0, qitems); qpkt.mbz_itemsize = MBZ_ITEMSIZE(qsize); } else { qpkt.err_nitems = ERR_NITEMS(0, 0); qpkt.mbz_itemsize = MBZ_ITEMSIZE(qsize); /* allow for optional first item */ } if (!auth || (keyid_entered && info_auth_keyid == 0)) { qpkt.auth_seq = AUTH_SEQ(0, 0); return sendpkt(&qpkt, req_pkt_size); } if (info_auth_keyid == 0) { key_id = getkeyid("Keyid: "); if (!key_id) { fprintf(stderr, "Invalid key identifier\n"); return 1; } info_auth_keyid = key_id; } if (!authistrusted(info_auth_keyid)) { pass = getpass_keytype(info_auth_keytype); if ('\0' == pass[0]) { fprintf(stderr, "Invalid password\n"); return 1; } authusekey(info_auth_keyid, info_auth_keytype, (u_char *)pass); authtrust(info_auth_keyid, 1); } qpkt.auth_seq = AUTH_SEQ(1, 0); if (info_auth_hashlen > 16) { /* * Only ntpd which expects REQ_LEN_NOMAC plus maclen * octets in an authenticated request using a 16 octet * digest (that is, a newer ntpd) will handle digests * larger than 16 octets, so for longer digests, do * not attempt to shorten the requests for downlevel * ntpd compatibility. */ if (REQ_LEN_NOMAC != req_pkt_size) return 1; reqsize = REQ_LEN_HDR + datasize + sizeof(*ptstamp); /* align to 32 bits */ reqsize = (reqsize + 3) & ~3; } else reqsize = req_pkt_size; ptstamp = (void *)((char *)&qpkt + reqsize); ptstamp--; get_systime(&ts); L_ADD(&ts, &delay_time); HTONL_FP(&ts, ptstamp); maclen = authencrypt(info_auth_keyid, (void *)&qpkt, reqsize); if (!maclen) { fprintf(stderr, "Key not found\n"); return 1; } else if (maclen != (info_auth_hashlen + sizeof(keyid_t))) { fprintf(stderr, "%d octet MAC, %lu expected with %lu octet digest\n", maclen, (u_long)(info_auth_hashlen + sizeof(keyid_t)), (u_long)info_auth_hashlen); return 1; } return sendpkt(&qpkt, reqsize + maclen); }
/* * getCmdOpts - get command line options */ void getCmdOpts( int argc, char *argv[] ) { extern const char *config_file; int errflg; tOptions *myOptions = &ntpdOptions; /* * Initialize, initialize */ errflg = 0; if (HAVE_OPT( IPV4 )) default_ai_family = AF_INET; else if (HAVE_OPT( IPV6 )) default_ai_family = AF_INET6; if (HAVE_OPT( AUTHREQ )) proto_config(PROTO_AUTHENTICATE, 1, 0., NULL); else if (HAVE_OPT( AUTHNOREQ )) proto_config(PROTO_AUTHENTICATE, 0, 0., NULL); if (HAVE_OPT( BCASTSYNC )) proto_config(PROTO_BROADCLIENT, 1, 0., NULL); if (HAVE_OPT( CONFIGFILE )) { config_file = OPT_ARG( CONFIGFILE ); #ifdef HAVE_NETINFO check_netinfo = 0; #endif } if (HAVE_OPT( DRIFTFILE )) stats_config(STATS_FREQ_FILE, OPT_ARG( DRIFTFILE )); if (HAVE_OPT( PANICGATE )) allow_panic = TRUE; #ifdef HAVE_DROPROOT if (HAVE_OPT( JAILDIR )) { droproot = 1; chrootdir = OPT_ARG( JAILDIR ); } #endif if (HAVE_OPT( KEYFILE )) getauthkeys(OPT_ARG( KEYFILE )); if (HAVE_OPT( PIDFILE )) stats_config(STATS_PID_FILE, OPT_ARG( PIDFILE )); if (HAVE_OPT( QUIT )) mode_ntpdate = TRUE; if (HAVE_OPT( PROPAGATIONDELAY )) do { double tmp; const char *my_ntp_optarg = OPT_ARG( PROPAGATIONDELAY ); if (sscanf(my_ntp_optarg, "%lf", &tmp) != 1) { msyslog(LOG_ERR, "command line broadcast delay value %s undecodable", my_ntp_optarg); } else { proto_config(PROTO_BROADDELAY, 0, tmp, NULL); } } while (0); if (HAVE_OPT( STATSDIR )) stats_config(STATS_STATSDIR, OPT_ARG( STATSDIR )); if (HAVE_OPT( TRUSTEDKEY )) { int ct = STACKCT_OPT( TRUSTEDKEY ); const char** pp = STACKLST_OPT( TRUSTEDKEY ); do { u_long tkey; const char* p = *pp++; tkey = (int)atol(p); if (tkey == 0 || tkey > NTP_MAXKEY) { msyslog(LOG_ERR, "command line trusted key %s is invalid", p); } else { authtrust(tkey, 1); } } while (--ct > 0); } #ifdef HAVE_DROPROOT if (HAVE_OPT( USER )) { droproot = 1; user = estrdup(OPT_ARG( USER )); group = rindex(user, ':'); if (group) *group++ = '\0'; /* get rid of the ':' */ } #endif if (HAVE_OPT( VAR )) { int ct = STACKCT_OPT( VAR ); const char** pp = STACKLST_OPT( VAR ); do { const char* my_ntp_optarg = *pp++; set_sys_var(my_ntp_optarg, strlen(my_ntp_optarg)+1, (u_short) (RW)); } while (--ct > 0); } if (HAVE_OPT( DVAR )) { int ct = STACKCT_OPT( DVAR ); const char** pp = STACKLST_OPT( DVAR ); do { const char* my_ntp_optarg = *pp++; set_sys_var(my_ntp_optarg, strlen(my_ntp_optarg)+1, (u_short) (RW | DEF)); } while (--ct > 0); } if (HAVE_OPT( SLEW )) { clock_max = 600; kern_enable = 0; } if (HAVE_OPT( UPDATEINTERVAL )) { long val = OPT_VALUE_UPDATEINTERVAL; if (val >= 0) interface_interval = val; else { fprintf(stderr, "command line interface update interval %ld must not be negative\n", val); msyslog(LOG_ERR, "command line interface update interval %ld must not be negative", val); errflg++; } } #ifdef SIM /* SK: * The simulator no longer takes any command line arguments. Hence, * all the code that was here has been removed. */ #endif /* SIM */ if (errflg || argc) { if (argc) fprintf(stderr, "argc after processing is <%d>\n", argc); optionUsage(myOptions, 2); } return; }
void AddUntrustedKey(keyid_t keyno) { authtrust(keyno, FALSE); }
/* * getCmdOpts - apply most command line options * * A few options are examined earlier in ntpd.c ntpdmain() and * ports/winnt/ntpd/ntservice.c main(). */ void getCmdOpts( int argc, char ** argv ) { extern const char *config_file; int errflg; /* * Initialize, initialize */ errflg = 0; if (ipv4_works && ipv6_works) { if (HAVE_OPT( IPV4 )) ipv6_works = 0; else if (HAVE_OPT( IPV6 )) ipv4_works = 0; } else if (!ipv4_works && !ipv6_works) { msyslog(LOG_ERR, "Neither IPv4 nor IPv6 networking detected, fatal."); exit(1); } else if (HAVE_OPT( IPV4 ) && !ipv4_works) msyslog(LOG_WARNING, "-4/--ipv4 ignored, IPv4 networking not found."); else if (HAVE_OPT( IPV6 ) && !ipv6_works) msyslog(LOG_WARNING, "-6/--ipv6 ignored, IPv6 networking not found."); if (HAVE_OPT( AUTHREQ )) proto_config(PROTO_AUTHENTICATE, 1, 0., NULL); else if (HAVE_OPT( AUTHNOREQ )) proto_config(PROTO_AUTHENTICATE, 0, 0., NULL); if (HAVE_OPT( BCASTSYNC )) proto_config(PROTO_BROADCLIENT, 1, 0., NULL); if (HAVE_OPT( CONFIGFILE )) { config_file = OPT_ARG( CONFIGFILE ); #ifdef HAVE_NETINFO check_netinfo = 0; #endif } if (HAVE_OPT( DRIFTFILE )) stats_config(STATS_FREQ_FILE, OPT_ARG( DRIFTFILE )); if (HAVE_OPT( PANICGATE )) allow_panic = TRUE; if (HAVE_OPT( FORCE_STEP_ONCE )) force_step_once = TRUE; #ifdef HAVE_DROPROOT if (HAVE_OPT( JAILDIR )) { droproot = 1; chrootdir = OPT_ARG( JAILDIR ); } #endif if (HAVE_OPT( KEYFILE )) getauthkeys(OPT_ARG( KEYFILE )); if (HAVE_OPT( PIDFILE )) stats_config(STATS_PID_FILE, OPT_ARG( PIDFILE )); if (HAVE_OPT( QUIT )) mode_ntpdate = TRUE; if (HAVE_OPT( PROPAGATIONDELAY )) do { double tmp; const char *my_ntp_optarg = OPT_ARG( PROPAGATIONDELAY ); if (sscanf(my_ntp_optarg, "%lf", &tmp) != 1) { msyslog(LOG_ERR, "command line broadcast delay value %s undecodable", my_ntp_optarg); } else { proto_config(PROTO_BROADDELAY, 0, tmp, NULL); } } while (0); if (HAVE_OPT( STATSDIR )) stats_config(STATS_STATSDIR, OPT_ARG( STATSDIR )); if (HAVE_OPT( TRUSTEDKEY )) { int ct = STACKCT_OPT( TRUSTEDKEY ); const char** pp = STACKLST_OPT( TRUSTEDKEY ); do { u_long tkey; const char* p = *pp++; tkey = (int)atol(p); if (tkey == 0 || tkey > NTP_MAXKEY) { msyslog(LOG_ERR, "command line trusted key %s is invalid", p); } else { authtrust(tkey, 1); } } while (--ct > 0); } #ifdef HAVE_DROPROOT if (HAVE_OPT( USER )) { droproot = 1; user = estrdup(OPT_ARG( USER )); group = strrchr(user, ':'); if (group != NULL) { size_t len; *group++ = '\0'; /* get rid of the ':' */ len = group - user; group = estrdup(group); user = erealloc(user, len); } } #endif if (HAVE_OPT( VAR )) { int ct; const char ** pp; const char * v_assign; ct = STACKCT_OPT( VAR ); pp = STACKLST_OPT( VAR ); do { v_assign = *pp++; set_sys_var(v_assign, strlen(v_assign) + 1, RW); } while (--ct > 0); } if (HAVE_OPT( DVAR )) { int ct = STACKCT_OPT( DVAR ); const char** pp = STACKLST_OPT( DVAR ); do { const char* my_ntp_optarg = *pp++; set_sys_var(my_ntp_optarg, strlen(my_ntp_optarg)+1, (u_short) (RW | DEF)); } while (--ct > 0); } if (HAVE_OPT( SLEW )) loop_config(LOOP_MAX, 600); if (HAVE_OPT( UPDATEINTERVAL )) { long val = OPT_VALUE_UPDATEINTERVAL; if (val >= 0) interface_interval = val; else { fprintf(stderr, "command line interface update interval %ld must not be negative\n", val); msyslog(LOG_ERR, "command line interface update interval %ld must not be negative", val); errflg++; } } /* save list of servers from cmd line for config_peers() use */ if (argc > 0) { cmdline_server_count = argc; cmdline_servers = argv; } /* display usage & exit with any option processing errors */ if (errflg) optionUsage(&ntpdOptions, 2); /* does not return */ }