From: Harlan Stenn Date: Thu, 15 Sep 2005 05:59:15 +0000 (-0400) Subject: "ident" changes from Dave Mills X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fc62155f290b52f146a99ab7863396ab3a4dd608;p=thirdparty%2Fntp.git "ident" changes from Dave Mills bk: 43290db3fFKDvw4ZdwjKq5iF1yqjtw --- diff --git a/include/ntp_config.h b/include/ntp_config.h index 4fc8c22a21..2d77109329 100644 --- a/include/ntp_config.h +++ b/include/ntp_config.h @@ -165,10 +165,11 @@ #define CONF_CRYPTO_CERT 4 #define CONF_CRYPTO_RAND 5 #define CONF_CRYPTO_KEYS 6 -#define CONF_CRYPTO_IFFPAR 7 -#define CONF_CRYPTO_GQPAR 8 -#define CONF_CRYPTO_MVPAR 9 -#define CONF_CRYPTO_PW 10 +#define CONF_CRYPTO_IDENT 7 +#define CONF_CRYPTO_IFFPAR 8 +#define CONF_CRYPTO_GQPAR 9 +#define CONF_CRYPTO_MVPAR 10 +#define CONF_CRYPTO_PW 11 #endif /* OPENSSL */ /* diff --git a/include/ntp_control.h b/include/ntp_control.h index c90848ba52..8877dc061c 100644 --- a/include/ntp_control.h +++ b/include/ntp_control.h @@ -173,7 +173,8 @@ struct ntp_control { #define CS_REVTIME 25 #define CS_LEAPTAB 26 #define CS_TAI 27 -#define CS_DIGEST 28 +#define CS_DIGEST 28 +#define CS_IDENT 29 #define CS_MAXCODE CS_DIGEST #else #define CS_MAXCODE CS_VARLIST diff --git a/include/ntp_crypto.h b/include/ntp_crypto.h index ba3bec946a..ce545b5b90 100644 --- a/include/ntp_crypto.h +++ b/include/ntp_crypto.h @@ -31,9 +31,10 @@ /* * Flags used for certificate management */ -#define CERT_SIGN 0x01 /* certificate is signed */ -#define CERT_TRUST 0x02 /* certificate is trusted */ -#define CERT_PRIV 0x04 /* certificate is private */ +#define CERT_TRUST 0x01 /* certificate is trusted */ +#define CERT_SIGN 0x02 /* certificate is signed */ +#define CERT_VALID 0x04 /* certificate is valid */ +#define CERT_PRIV 0x08 /* certificate is private */ #define CERT_ERROR 0x80 /* certificate has errors */ /* @@ -91,6 +92,7 @@ #define CRYPTO_CONF_GQPAR 9 /* GQ parameters file name */ #define CRYPTO_CONF_MVPAR 10 /* GQ parameters file name */ #define CRYPTO_CONF_PW 11 /* private key password */ +#define CRYPTO_CONF_IDENT 12 /* specify identity scheme */ /* * Miscellaneous crypto stuff @@ -99,6 +101,7 @@ #define NTP_AUTOMAX 13 /* log2 default max session key life */ #define KEY_REVOKE 16 /* log2 default key revoke timeout */ #define NTP_MAXEXTEN 1024 /* maximum extension field size */ +#define TAI_1972 10 /* initial TAI offset (s) */ /* * The autokey structure holds the values used to authenticate key IDs. @@ -163,5 +166,4 @@ extern u_int crypto_flags; /* status word */ extern struct value hostval; /* host name/value */ extern struct cert_info *cinfo; /* host certificate information */ extern struct value tai_leap; /* leapseconds table */ -extern u_int sys_tai; /* current UTC offset from TAI */ #endif /* OPENSSL */ diff --git a/include/ntpd.h b/include/ntpd.h index 30a61460cb..f0decb38d0 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -108,6 +108,7 @@ extern void adj_host_clock P((void)); extern void loop_config P((int, double)); extern void huffpuff P((void)); extern u_long sys_clocktime; +extern u_long sys_tai; /* ntp_monitor.c */ extern void init_mon P((void)); @@ -147,6 +148,13 @@ extern u_int crypto_ident P((struct peer *)); extern struct exten *crypto_args P((struct peer *, u_int, char *)); extern int crypto_public P((struct peer *, u_char *, u_int)); extern void value_free P((struct value *)); +extern char *iffpar_file; +extern EVP_PKEY *iffpar_pkey; +extern char *gqpar_file; +extern EVP_PKEY *gqpar_pkey; +extern char *mvpar_file; +extern EVP_PKEY *mvpar_pkey; +extern struct value tai_leap; #endif /* OPENSSL */ /* ntp_proto.c */ diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index d4c3ba3ab8..73336e225a 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -259,6 +259,7 @@ static struct keyword crypto_keywords[] = { { "cert", CONF_CRYPTO_CERT }, { "gqpar", CONF_CRYPTO_GQPAR }, { "host", CONF_CRYPTO_RSA }, + { "ident", CONF_CRYPTO_IDENT }, { "iffpar", CONF_CRYPTO_IFFPAR }, { "leap", CONF_CRYPTO_LEAP }, { "mvpar", CONF_CRYPTO_MVPAR }, @@ -1206,6 +1207,11 @@ getconfig( tokens[i]); break; + case CONF_CRYPTO_IDENT: + crypto_config(CRYPTO_CONF_IDENT, + tokens[i]); + break; + case CONF_CRYPTO_IFFPAR: crypto_config(CRYPTO_CONF_IFFPAR, tokens[i]); diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index 33d43b00fd..1df6eccb52 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -119,11 +119,12 @@ static struct ctl_var sys_var[] = { { CS_PUBLIC, RO, "hostkey" }, /* 23 */ { CS_CERTIF, RO, "cert" }, /* 24 */ { CS_REVTIME, RO, "refresh" }, /* 25 */ - { CS_LEAPTAB, RO, "leapseconds" }, /* 26 */ + { CS_LEAPTAB, RO, "leapsec" }, /* 26 */ { CS_TAI, RO, "tai" }, /* 27 */ { CS_DIGEST, RO, "signature" }, /* 28 */ + { CS_IDENT, RO, "ident" }, /* 29 */ #endif /* OPENSSL */ - { 0, EOV, "" } /* 29 */ + { 0, EOV, "" } /* 21/30 */ }; static struct ctl_var *ext_sys_var = (struct ctl_var *)0; @@ -158,7 +159,9 @@ static u_char def_sys_var[] = { CS_FLAGS, CS_PUBLIC, CS_REVTIME, + CS_IDENT, CS_LEAPTAB, + CS_TAI, CS_CERTIF, #endif /* OPENSSL */ 0 @@ -1390,12 +1393,26 @@ ctl_putsys( ntohl(hostval.tstamp)); break; + case CS_IDENT: + if (iffpar_pkey != NULL) + ctl_putstr(sys_var[CS_IDENT].text, + iffpar_file, strlen(iffpar_file)); + if (gqpar_pkey != NULL) + ctl_putstr(sys_var[CS_IDENT].text, + gqpar_file, strlen(gqpar_file)); + if (mvpar_pkey != NULL) + ctl_putstr(sys_var[CS_IDENT].text, + mvpar_file, strlen(mvpar_file)); + break; + case CS_LEAPTAB: if (tai_leap.fstamp != 0) ctl_putuint(sys_var[CS_LEAPTAB].text, ntohl(tai_leap.fstamp)); - if (sys_tai != 0) - ctl_putuint(sys_var[CS_TAI].text, sys_tai); + break; + + case CS_TAI: + ctl_putuint(sys_var[CS_TAI].text, sys_tai); break; #endif /* OPENSSL */ } diff --git a/ntpd/ntp_crypto.c b/ntpd/ntp_crypto.c index affbeb2c4a..d8d4f5a984 100644 --- a/ntpd/ntp_crypto.c +++ b/ntpd/ntp_crypto.c @@ -99,7 +99,6 @@ * Global cryptodata in host byte order */ u_int32 crypto_flags = 0x0; /* status word */ -u_int sys_tai; /* current UTC offset from TAI */ /* * Global cryptodata in network byte order @@ -108,6 +107,12 @@ struct cert_info *cinfo = NULL; /* certificate info/value */ struct value hostval; /* host value */ struct value pubkey; /* public key */ struct value tai_leap; /* leapseconds table */ +EVP_PKEY *iffpar_pkey = NULL; /* IFF parameters */ +EVP_PKEY *gqpar_pkey = NULL; /* GQ parameters */ +EVP_PKEY *mvpar_pkey = NULL; /* MV parameters */ +char *iffpar_file = NULL; /* IFF parameters file */ +char *gqpar_file = NULL; /* GQ parameters file */ +char *mvpar_file = NULL; /* MV parameters file */ /* * Private cryptodata in host byte order @@ -115,17 +120,11 @@ struct value tai_leap; /* leapseconds table */ static char *passwd = NULL; /* private key password */ static EVP_PKEY *host_pkey = NULL; /* host key */ static EVP_PKEY *sign_pkey = NULL; /* sign key */ -static EVP_PKEY *iffpar_pkey = NULL; /* IFF parameters */ -static EVP_PKEY *gqpar_pkey = NULL; /* GQ parameters */ -static EVP_PKEY *mvpar_pkey = NULL; /* MV parameters */ static const EVP_MD *sign_digest = NULL; /* sign digest */ static u_int sign_siglen; /* sign key length */ static char *rand_file = NULL; /* random seed file */ static char *host_file = NULL; /* host key file */ static char *sign_file = NULL; /* sign key file */ -static char *iffpar_file = NULL; /* IFF parameters file */ -static char *gqpar_file = NULL; /* GQ parameters file */ -static char *mvpar_file = NULL; /* MV parameters file */ static char *cert_file = NULL; /* certificate file */ static char *leap_file = NULL; /* leapseconds file */ static tstamp_t if_fstamp = 0; /* IFF file stamp */ @@ -1042,22 +1041,10 @@ crypto_recv( tai_leap.ptr = emalloc(vallen); memcpy(tai_leap.ptr, ep->pkt, vallen); crypto_update(); - sys_tai = vallen / 4 + TAI_1972 - 1; } crypto_flags |= CRYPTO_FLAG_TAI; peer->crypto |= CRYPTO_FLAG_LEAP; peer->flash &= ~TEST8; -#ifdef KERNEL_PLL -#if NTP_API > 3 - /* - * If the kernel cooperates, initialize the - * current TAI offset. - */ - ntv.modes = MOD_TAI; - ntv.constant = sys_tai; - (void)ntp_adjtime(&ntv); -#endif /* NTP_API */ -#endif /* KERNEL_PLL */ sprintf(statstr, "leap %u ts %u fs %u", vallen, ntohl(ep->tstamp), ntohl(ep->fstamp)); @@ -1158,7 +1145,7 @@ crypto_xmit( struct peer *peer; /* peer structure pointer */ u_int opcode; /* extension field opcode */ struct exten *fp; /* extension pointers */ - struct cert_info *cp; /* certificate info/value pointer */ + struct cert_info *cp, *xp; /* certificate info/value pointer */ char certname[MAXHOSTNAME + 1]; /* subject name buffer */ char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ u_int vallen; @@ -1228,17 +1215,28 @@ crypto_xmit( memcpy(certname, ep->pkt, vallen); certname[vallen] = '\0'; } + + /* + * Find the self-signed, trusted certificate. If not + * found, use the first one found. + */ + xp = NULL; for (cp = cinfo; cp != NULL; cp = cp->link) { if (cp->flags & CERT_PRIV) continue; if (strcmp(certname, cp->subject) == 0) { - len += crypto_send(fp, &cp->cert); - break; + if (xp == NULL) + xp = cp; + else if (strcmp(certname, cp->issuer) == + 0 && cp->flags & CERT_TRUST) + xp = cp; } } - if (cp == NULL) + if (xp == NULL) opcode |= CRYPTO_ERROR; + else + len += crypto_send(fp, &xp->cert); break; /* @@ -3349,10 +3347,10 @@ cert_install( * this might result in a loop that could * persist until timeout. */ - if (!(xp->flags & CERT_TRUST)) + if (!(xp->flags & (CERT_TRUST | CERT_VALID))) continue; - yp->flags |= CERT_TRUST; + yp->flags |= CERT_VALID; /* * If subject Y matches the server subject name, @@ -3621,20 +3619,16 @@ crypto_tai( { FILE *str; /* file handle */ char buf[NTP_MAXSTRLEN]; /* file line buffer */ - u_int leapsec[MAX_LEAP]; /* NTP time at leaps */ - u_int offset; /* offset at leap (s) */ + u_int32 leapsec[MAX_LEAP]; /* NTP time at leaps */ + int offset; /* offset at leap (s) */ char filename[MAXFILENAME]; /* name of leapseconds file */ char linkname[MAXFILENAME]; /* file link (for filestamp) */ char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ tstamp_t fstamp; /* filestamp */ u_int len; - char *ptr; - int rval, i; -#ifdef KERNEL_PLL -#if NTP_API > 3 - struct timex ntv; /* kernel interface structure */ -#endif /* NTP_API */ -#endif /* KERNEL_PLL */ + u_int32 *ptr; + char *dp; + int rval, i, j; /* * Open the file and discard comment lines. If the first @@ -3656,12 +3650,12 @@ crypto_tai( rval = readlink(filename, linkname, MAXFILENAME - 1); if (rval > 0) { linkname[rval] = '\0'; - ptr = strrchr(linkname, '.'); + dp = strrchr(linkname, '.'); } else { - ptr = strrchr(filename, '.'); + dp = strrchr(filename, '.'); } - if (ptr != NULL) - sscanf(++ptr, "%u", &fstamp); + if (dp != NULL) + sscanf(++dp, "%u", &fstamp); else fstamp = 0; tai_leap.fstamp = htonl(fstamp); @@ -3678,8 +3672,8 @@ crypto_tai( */ i = 0; while (i < MAX_LEAP) { - ptr = fgets(buf, NTP_MAXSTRLEN - 1, str); - if (ptr == NULL) + dp = fgets(buf, NTP_MAXSTRLEN - 1, str); + if (dp == NULL) break; if (strlen(buf) < 1) @@ -3688,16 +3682,16 @@ crypto_tai( if (*buf == '#') continue; - if (sscanf(buf, "%u %u", &leapsec[i], &offset) != 2) + if (sscanf(buf, "%u %d", &leapsec[i], &offset) != 2) continue; - if (i != (int)(offset - TAI_1972)) { + if (i != offset - TAI_1972) break; - } + i++; } fclose(str); - if (ptr != NULL) { + if (dp != NULL) { msyslog(LOG_INFO, "crypto_tai: leapseconds file %s error %d", cp, rval); @@ -3706,29 +3700,17 @@ crypto_tai( /* * The extension field table entries consists of the NTP seconds - * of leap insertion in reverse order, so that the most recent - * insertion is the first entry in the table. + * of leap insertion in network byte order. */ - len = i * 4; + len = i * sizeof(u_int32); tai_leap.vallen = htonl(len); ptr = emalloc(len); tai_leap.ptr = (u_char *)ptr; - for (; i >= 0; i--) { - *ptr++ = (char) htonl(leapsec[i]); - } + for (j = 0; j < i; j++) + *ptr++ = htonl(leapsec[j]); crypto_flags |= CRYPTO_FLAG_TAI; - sys_tai = len / 4 + TAI_1972 - 1; -#ifdef KERNEL_PLL -#if NTP_API > 3 - ntv.modes = MOD_TAI; - ntv.constant = sys_tai; - if (ntp_adjtime(&ntv) == TIME_ERROR) - msyslog(LOG_INFO, - "crypto_tai: kernel TAI update failed"); -#endif /* NTP_API */ -#endif /* KERNEL_PLL */ - sprintf(statstr, "%s link %d fs %u offset %u", cp, rval, fstamp, - ntohl(tai_leap.vallen) / 4 + TAI_1972 - 1); + sprintf(statstr, "%s fs %u leap %u len %u", cp, fstamp, + leapsec[--j], len); record_crypto_stats(NULL, statstr); #ifdef DEBUG if (debug) @@ -3945,7 +3927,7 @@ crypto_setup(void) * It the certificate is trusted, the subject must be the same * as the issuer, in other words it must be self signed. */ - if (cinfo->flags & CERT_PRIV && strcmp(cinfo->subject, + if (cinfo->flags & CERT_TRUST && strcmp(cinfo->subject, cinfo->issuer) != 0) { if (cert_valid(cinfo, sign_pkey) != XEVNT_OK) { msyslog(LOG_ERR, @@ -4044,6 +4026,18 @@ crypto_config( strcpy(mvpar_file, cp); break; + /* + * Set identity scheme. + */ + case CRYPTO_CONF_IDENT: + if (!strcasecmp(cp, "iff")) + crypto_flags |= CRYPTO_FLAG_IFF; + else if (!strcasecmp(cp, "gq")) + crypto_flags |= CRYPTO_FLAG_GQ; + else if (!strcasecmp(cp, "mv")) + crypto_flags |= CRYPTO_FLAG_MV; + break; + /* * Set certificate file name. */ diff --git a/ntpd/ntp_loopfilter.c b/ntpd/ntp_loopfilter.c index e3bfc0ad4c..9f6a3137d8 100644 --- a/ntpd/ntp_loopfilter.c +++ b/ntpd/ntp_loopfilter.c @@ -122,7 +122,7 @@ double drift_comp; /* frequency (s/s) */ double clock_stability; /* frequency stability (s/s) */ u_long sys_clocktime; /* last system clock update */ u_long pps_control; /* last pps update */ - +u_long sys_tai; /* TAI offset from UTC (s) */ static void rstclock P((int, u_long, double)); /* transition function */ #ifdef KERNEL_PLL @@ -200,16 +200,22 @@ init_loopfilter(void) */ int local_clock( - struct peer *peer, /* synch source peer structure */ - double fp_offset /* clock offset (s) */ + struct peer *peer, /* synch source peer structure */ + double fp_offset /* clock offset (s) */ ) { int rval; /* return code */ - u_long mu; /* interval since last update (s) */ - double flladj; /* FLL frequency adjustment (ppm) */ - double plladj; /* PLL frequency adjustment (ppm) */ - double clock_frequency; /* clock frequency adjustment (ppm) */ - double dtemp, etemp; /* double temps */ + u_long mu; /* interval since last update (s) */ + double flladj; /* FLL frequency adjustment (ppm) */ + double plladj; /* PLL frequency adjustment (ppm) */ + double clock_frequency; /* clock frequency adjustment (ppm) */ + double dtemp, etemp; /* double temps */ +#ifdef OPENSSL + u_int32 *tpt; + int i; + u_int len; + long togo; +#endif /* OPENSSL */ /* * If the loop is opened, monitor and record the offsets @@ -391,6 +397,7 @@ local_clock( fp_offset); reinit_timer(); tc_counter = 0; + sys_tai = 0; rval = 2; if (state == S_NSET) { rstclock(S_FREQ, peer->epoch, 0); @@ -472,6 +479,32 @@ local_clock( rstclock(S_SYNC, peer->epoch, fp_offset); } +#ifdef OPENSSL + /* + * Scan the loopsecond table to determine the TAI offset. If + * there is a scheduled leap in future, set the leap warning. + */ + tpt = (u_int32 *)tai_leap.ptr; + len = ntohl(tai_leap.vallen) / sizeof(u_int32); + if (tpt != NULL) { + for (i = 0; i < len; i++) { + togo = ntohl(tpt[i]) - peer->rec.l_ui; + if (togo > 0) { + sys_leap |= LEAP_ADDSECOND; + break; + } +#ifdef STA_NANO + if (pll_control && kern_enable) { + memset(&ntv, 0, sizeof(ntv)); + ntv.modes = MOD_BITS | MOD_TAI; + ntv.constant = i + TAI_1972 - 1; + ntp_adjtime(&ntv); + } +#endif /* STA_NANO */ + } + sys_tai = i + TAI_1972 - 1; + } +#endif /* OPENSSL */ #ifdef KERNEL_PLL /* * This code segment works when clock adjustments are made using diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index fb721a5af3..fc0b658e59 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -61,7 +61,6 @@ int sys_calldelay; /* modem callup delay (s) */ int sys_authenticate; /* requre authentication for config */ l_fp sys_authdelay; /* authentication delay */ static u_long sys_authdly[2]; /* authentication delay shift reg */ -static u_char leap_consensus; /* consensus of survivor leap bits */ static double sys_mindisp = MINDISPERSE; /* min disp increment (s) */ static double sys_maxdist = MAXDISTANCE; /* selection threshold (s) */ double sys_jitter; /* system jitter (s) */ @@ -853,11 +852,9 @@ receive( } /* - * Do not respond if unsynchronized or stratum is below - * the floor or at or above the ceiling. + * Do not respond if stratum is below the floor. */ - if (hisleap == LEAP_NOTINSYNC || hisstratum < - sys_floor || hisstratum >= sys_ceiling) + if (hisstratum < sys_floor) return; /* bad stratum */ if ((peer = newpeer(&rbufp->recv_srcadr, @@ -1308,7 +1305,6 @@ clock_update(void) dtemp = sys_mindisp; #endif /* REFCLOCK */ sys_rootdispersion = sys_peer->rootdispersion + dtemp; - sys_leap = leap_consensus; if (oleap == LEAP_NOTINSYNC) { report_event(EVNT_SYNCCHG, NULL); #ifdef OPENSSL @@ -2092,11 +2088,11 @@ clock_select(void) * stratum and that unsynchronized peers cannot survive this * far. */ - leap_consensus = 0; + sys_leap = LEAP_NOWARNING; for (i = 0; i < nlist; i++) { peer = peer_list[i]; sys_survivors++; - leap_consensus |= peer->leap; + sys_leap |= peer->leap; peer->status = CTL_PST_SEL_SYNCCAND; if (peer->flags & FLAG_PREFER) sys_prefer = peer; diff --git a/ntpd/refclock_wwvb.c b/ntpd/refclock_wwvb.c index c2452c92da..7bddd3a375 100644 --- a/ntpd/refclock_wwvb.c +++ b/ntpd/refclock_wwvb.c @@ -43,7 +43,7 @@ * * Format 0 (22 ASCII printing characters): * - * i ddd hh:mm:ss TZ=zz + * i ddd hh:mm:ss TZ=zz * * on-time = first * hh:mm:ss = hours, minutes, seconds