* compare the value timestamps here, as they
* can be updated by different servers.
*/
- if ((rval = crypto_verify(ep, NULL, peer)) !=
- XEVNT_OK)
+ rval = crypto_verify(ep, NULL, peer);
+ if ((rval != XEVNT_OK ) ||
+ (vallen != 3*sizeof(uint32_t)) )
break;
/* Check if we can update the basic TAI offset
* and ignores the time stamps in the autokey
* message.
*/
- if (vallen == 0) {
- /* NOP */
- } else if (vallen != 3*sizeof(uint32_t)) {
-#ifdef DEBUG
- if (debug)
- printf("crypto_recv: CRYPTO_LEAP: bad value size %u\n", vallen);
-#endif
- } else if (sys_leap == LEAP_NOTINSYNC) {
-#ifdef DEBUG
- if (debug)
- printf("crypto_recv: CRYPTO_LEAP: not in sync, TAI ignored\n");
-#endif
- } else if ( ! leapsec_autokey_tai(ntohl(ep->pkt[0]),
- rbufp->recv_time.l_ui, NULL))
- {
-#ifdef DEBUG
- if (debug)
- printf("crypto_recv: CRYPTO_LEAP: TAI not updated\n");
-#endif
- }
-
+ if (sys_leap != LEAP_NOTINSYNC)
+ leapsec_autokey_tai(ntohl(ep->pkt[0]),
+ rbufp->recv_time.l_ui, NULL);
tai_leap.tstamp = ep->tstamp;
tai_leap.fstamp = ep->fstamp;
crypto_update();
*/
tai_leap.tstamp = hostval.tstamp;
tai_leap.fstamp = hostval.fstamp;
- if ( ! leapsec_frame(&leap_data))
- leap_data.tai_offs = 0;
-
- if (leap_data.tai_offs != 0) { /* might be better with > 10... */
- len = 3 * sizeof(u_int32);
- if (tai_leap.ptr == NULL || ntohl(tai_leap.vallen) != len) {
- free(tai_leap.ptr);
- tai_leap.ptr = emalloc(len);
- tai_leap.vallen = htonl(len);
- }
- ptr = (u_int32 *)tai_leap.ptr;
+
+ /* Get the leap second era. We might need a full lookup early
+ * after start, when the cache is not yet loaded.
+ */
+ leapsec_frame(&leap_data);
+ if ( ! memcmp(&leap_data.ebase, &leap_data.ttime, sizeof(vint64))) {
+ time_t now = time(NULL);
+ uint32_t nowntp = (uint32_t)now + JAN_1970;
+ leapsec_query(&leap_data, nowntp, &now);
+ }
+
+ /* Create the data block. The protocol does not work without. */
+ len = 3 * sizeof(u_int32);
+ if (tai_leap.ptr == NULL || ntohl(tai_leap.vallen) != len) {
+ free(tai_leap.ptr);
+ tai_leap.ptr = emalloc(len);
+ tai_leap.vallen = htonl(len);
+ }
+ ptr = (u_int32 *)tai_leap.ptr;
+ if (leap_data.tai_offs > 10) {
+ /* create a TAI / leap era block. The end time is a
+ * fake -- maybe we can do better.
+ */
ptr[0] = htonl(leap_data.tai_offs);
ptr[1] = htonl(leap_data.ebase.d_s.lo);
if (leap_data.ttime.d_s.hi >= 0)
- ptr[2] = htonl(leap_data.ttime.D_s.lo - 7*86400);
+ ptr[2] = htonl(leap_data.ttime.D_s.lo + 7*86400);
else
ptr[2] = htonl(leap_data.ebase.D_s.lo + 25*86400);
} else {
- free(tai_leap.ptr);
- tai_leap.ptr = NULL;
- tai_leap.vallen = 0;
+ /* no leap era available */
+ memset(ptr, 0, len);
}
if (tai_leap.sig == NULL)
tai_leap.sig = emalloc(sign_siglen);
EVP_SignUpdate(&ctx, (u_char *)&tai_leap, 12);
EVP_SignUpdate(&ctx, tai_leap.ptr, len);
if (EVP_SignFinal(&ctx, tai_leap.sig, &len, sign_pkey))
- tai_leap.siglen = htonl(sign_siglen);
+ tai_leap.siglen = htonl(len);
crypto_flags |= CRYPTO_FLAG_TAI;
+
snprintf(statstr, sizeof(statstr), "signature update ts %u",
ntohl(hostval.tstamp));
record_crypto_stats(NULL, statstr);
static void reset_times(leap_table_t*);
static int leapsec_add(leap_table_t*, const vint64*, int);
static int leapsec_raw(leap_table_t*, const vint64 *, int, int);
-static char * lstostr(const vint64 * ts);
+static const char * lstostr(const vint64 * ts);
/* =====================================================================
* Get & Set the current leap table
struct calendar build;
leapsec_clear(pt);
- if (use_build_limit && ntpcal_get_build_date(&build))
+ if (use_build_limit && ntpcal_get_build_date(&build)) {
+ /* don't prune everything -- permit the last 10yrs
+ * before build.
+ */
+ build.year -= 10;
limit = ntpcal_date_to_ntp64(&build);
- else
+ } else {
memset(&limit, 0, sizeof(limit));
-
+ }
+
while (get_line(func, farg, linebuf, sizeof(linebuf))) {
cp = linebuf;
if (*cp == '#') {
memset(qr, 0, sizeof(leap_result_t));
pt = leapsec_get_table(FALSE);
- if (ucmpv64(&pt->head.ttime, &pt->head.stime) <= 0)
- return FALSE;
qr->tai_offs = pt->head.this_tai;
qr->tai_diff = pt->head.next_tai - pt->head.this_tai;
qr->ttime = pt->head.ttime;
qr->dynamic = pt->head.dynls;
- return TRUE;
+ return ucmpv64(&pt->head.ttime, &pt->head.stime) >= 0;
}
/* ------------------------------------------------------------------ */
(void)tai_offset;
pt = leapsec_get_table(FALSE);
- /* Bail out if the basic offset is not zero */
- if (pt->head.base_tai != 0)
+ /* Bail out if the basic offset is not zero and the putative
+ * offset is bigger than 10s. That was in 1972 -- we don't want
+ * to go back that far!
+ */
+ if (pt->head.base_tai != 0 || tai_offset < 10)
return FALSE;
/* If there's already data in the table, check if an update is
/*
* lstostr - prettyprint NTP seconds
*/
-static char * lstostr(
+static const char *
+lstostr(
const vint64 * ts)
{
char * buf;
struct calendar tm;
+ LIB_GETBUF(buf);
+
if ( ! (ts->d_s.hi >= 0 && ntpcal_ntp64_to_date(&tm, ts) >= 0))
- return "9999-12-31T23:59:59Z";
-
- LIB_GETBUF(buf);
- snprintf(buf, LIB_BUFLENGTH, "%04d-%02d-%02dT%02d:%02d:%02dZ",
- tm.year, tm.month, tm.monthday,
- tm.hour, tm.minute, tm.second);
+ snprintf(buf, LIB_BUFLENGTH, "%s", "9999-12-31T23:59:59Z");
+ else
+ snprintf(buf, LIB_BUFLENGTH, "%04d-%02d-%02dT%02d:%02d:%02dZ",
+ tm.year, tm.month, tm.monthday,
+ tm.hour, tm.minute, tm.second);
+
return buf;
}