[Git][NTPsec/ntpsec][master] 9 commits: Remove unused SIGIO/SIGPOLL quirks

Hal Murray gitlab at mg.gitlab.com
Wed Feb 27 00:43:05 UTC 2019


Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
6b85d691 by Hal Murray at 2019-02-27T00:41:03Z
Remove unused SIGIO/SIGPOLL quirks

- - - - -
e50fc64b by Hal Murray at 2019-02-27T00:41:03Z
Add checks for not-initialized to nts_cookie

- - - - -
f9990a6e by Hal Murray at 2019-02-27T00:41:03Z
Add listen to seccomp list

- - - - -
3cc0f872 by Hal Murray at 2019-02-27T00:41:03Z
Add comments for non-NTS extensions

- - - - -
6f848c0a by Hal Murray at 2019-02-27T00:41:03Z
Move FLAG_NTS* to peer->flags

Drop unused FLAG_BC_VOL
Add FLAG_DNSNTS and comments

- - - - -
15424909 by Hal Murray at 2019-02-27T00:41:03Z
Remove unused CRPT_EVENT from ntp.h

- - - - -
e54c68c9 by Hal Murray at 2019-02-27T00:41:03Z
Change FLAG_DNSNTS to FLAG_LOOKUP, use it

- - - - -
48080e0a by Hal Murray at 2019-02-27T00:41:03Z
Work on NTS client

Use FLAG_LOOKUP
Process hostname of foo:port
Cleanup processing after NTS-KE thread

- - - - -
1d101ead by Hal Murray at 2019-02-27T00:41:03Z
Update devel/TODO-NTS

- - - - -


13 changed files:

- devel/TODO-NTS
- include/ntp.h
- include/ntpd.h
- include/nts.h
- libntp/syssignal.c
- ntpd/ntp_config.c
- ntpd/ntp_dns.c
- ntpd/ntp_extens.c
- ntpd/ntp_peer.c
- ntpd/ntp_proto.c
- ntpd/ntp_sandbox.c
- ntpd/nts_client.c
- ntpd/nts_cookie.c


Changes:

=====================================
devel/TODO-NTS
=====================================
@@ -1,15 +1,7 @@
-flag for require NTS
-
 multithread msyslog
 
 security level
 
-test/fix seccomp
-
-show NTS flag via ntpq
-  extra credit if we can find a place on the peers display
-show NTS statistics
-
 documentation:
   HOWTO on NTS
   HOWTO on certificates


=====================================
include/ntp.h
=====================================
@@ -383,19 +383,29 @@ struct peer {
 /*
  * Values for peer.flags (unsigned int)
  */
-#define	FLAG_CONFIG	0x0001u	/* association was configured */
-#define	FLAG_PREEMPT	0x0002u	/* preemptable association */
-#define	FLAG_AUTHENTIC	0x0004u	/* last message was authentic */
-#define	FLAG_REFCLOCK	0x0008u	/* this is actually a reference clock */
-#define	FLAG_BC_VOL	0x0010u	/* broadcast client volleying */
-#define	FLAG_PREFER	0x0020u	/* prefer peer */
-#define	FLAG_BURST	0x0040u	/* burst mode */
-#define	FLAG_PPS	0x0080u	/* steered by PPS */
-#define	FLAG_IBURST	0x0100u	/* initial burst mode */
-#define	FLAG_NOSELECT	0x0200u	/* never select */
-#define	FLAG_TRUE	0x0400u	/* force truechimer */
-#define	FLAG_DNS	0x0800u	/* needs DNS lookup */
-#define FLAG_TSTAMP_PPS	0x1000u	/* PPS source provides absolute timestamp */
+#define	FLAG_CONFIG	 0x0001u   /* association was configured */
+#define	FLAG_PREEMPT	 0x0002u   /* preemptable association */
+#define	FLAG_AUTHENTIC	 0x0004u   /* last message was authentic */
+#define	FLAG_REFCLOCK	 0x0008u   /* this is actually a reference clock */
+/* #define	FLAG_BC_VOL	 0x0010u   ** broadcast client volleying */
+#define	FLAG_PREFER	 0x0020u   /* prefer peer */
+#define	FLAG_BURST	 0x0040u   /* burst mode */
+#define	FLAG_PPS	 0x0080u   /* steered by PPS */
+#define	FLAG_IBURST	 0x0100u   /* initial burst mode */
+#define	FLAG_NOSELECT	 0x0200u   /* never select */
+#define	FLAG_TRUE	 0x0400u   /* force truechimer */
+#define	FLAG_DNS	 0x0800u   /* Server name, not number: needs DNS */
+#define FLAG_NTS         0x1000u   /* use NTS (network time security) */
+#define FLAG_NTS_ASK     0x2000u   /* NTS, ask for specified server */
+#define FLAG_NTS_REQ     0x4000u   /* NTS, require specified server */
+#define FLAG_NTS_NOVAL   0x8000u   /* do not validate the server certificate */
+#define FLAG_TSTAMP_PPS	0x10000u   /* PPS source provides absolute timestamp */
+#define	FLAG_LOOKUP	0x20000u   /* needs DNS or NTS lookup */
+
+/* FLAG_DNS and FLAG_NTS stay on.
+ * FLAG_LOOKUP gets turned off when lookup succeeds.
+ */
+
 
 /* This is the new, sane way of representing packets. All fields are
    in host byte order, and the fixed-point time fields are just integers,
@@ -465,7 +475,6 @@ struct pkt {
  * Event codes. Used for reporting errors/events to the control module
  */
 #define	PEER_EVENT	0x080	/* this is a peer event */
-#define CRPT_EVENT	0x100	/* this is a crypto event */
 
 /*
  * System event codes


=====================================
include/ntpd.h
=====================================
@@ -446,6 +446,7 @@ bool extens_client_recv(struct peer *peer, uint8_t *pkt, int lng);
 void nts_init(void);   /* Before sandbox() */
 void nts_init2(void);  /* After sandbox() */
 bool nts_probe(struct peer *peer);
+bool nts_check(struct peer *peer);
 int nts_client_ke_request(struct ntscfg_t *);
 int nts_server_ke_verify(struct ntscfg_t *);
 int nts_client_ke_verify(struct ntscfg_t *, struct ntsclient_t *);


=====================================
include/nts.h
=====================================
@@ -14,21 +14,16 @@
 #define NTS_UID_LENGTH		32	/* RFC 5.3 */
 #define NTS_UID_MAX_LENGTH	64
 
-#define FLAG_NTS	0x01u	/* use NTS (network time security) */
-#define FLAG_NTS_ASK	0x02u	/* NTS, ask for specified server */
-#define FLAG_NTS_REQ	0x04u	/* NTS, ask for specified server */
-#define FLAG_NTS_NOVAL	0x08u	/* do not validate the server certificate */
-
-/* Configuration data for an NTS association */
+/* Client side configuration data for an NTS association */
+/* part of peer struct */
 struct ntscfg_t {
     char *server;	/* if NULL, use the peer itself (normal case) */
     char *ca;		/* if NULL, use the site default (normal case) */
     char *cert;		/* if NULL, use the site default (normal case) */
-    uint32_t flags;
     uint32_t expire;
 };
 
-// We are using AEAD_AES_SIV_CMAC_256, from RFC 5297
+/* We are using AEAD_AES_SIV_CMAC_256, from RFC 5297 */
 #define IANA_AEAD_AES_SIV_CMAC_256 15
 #define IANA_AEAD_AES_SIV_CMAC_384 16
 #define IANA_AEAD_AES_SIV_CMAC_512 17


=====================================
libntp/syssignal.c
=====================================
@@ -27,19 +27,7 @@ signal_no_reset(
 	sigemptyset(&vec.sa_mask);
 	vec.sa_handler = func;
 
-	/* Added for PPS clocks on Solaris 7 which get EINTR errors */
-# ifdef SIGPOLL
-	if (SIGPOLL == sig)
-		vec.sa_flags = Z_SA_RESTART;
-# endif
-# ifdef SIGIO
-	if (SIGIO == sig)
-		vec.sa_flags = Z_SA_RESTART;
-# endif
-
-	do
-		n = sigaction(sig, &vec, NULL);
-	while (-1 == n && EINTR == errno);
+	n = sigaction(sig, &vec, NULL);
 	if (-1 == n) {
 		perror("ERROR: signal_no_reset() sigaction");
 		exit(1);


=====================================
ntpd/ntp_config.c
=====================================
@@ -632,11 +632,11 @@ create_peer_node(
 				break;
 
 			case T_Noval:
-				my_node->ctl.nts_cfg.flags |= FLAG_NTS_NOVAL;
+				my_node->ctl.flags |= FLAG_NTS_NOVAL;
 				break;
 
 			case T_Nts:
-				my_node->ctl.nts_cfg.flags |= FLAG_NTS;
+				my_node->ctl.flags |= (FLAG_NTS | FLAG_LOOKUP);
 				break;
 
 			case T_Prefer:
@@ -729,12 +729,12 @@ create_peer_node(
 			break;
 
 		case T_Ask:
-			my_node->ctl.nts_cfg.flags |= FLAG_NTS_ASK;
+			my_node->ctl.flags |= FLAG_NTS_ASK;
 			my_node->ctl.nts_cfg.server = estrdup(option->value.s);
 			break;
 
 		case T_Require:
-			my_node->ctl.nts_cfg.flags |= FLAG_NTS_REQ;
+			my_node->ctl.flags |= FLAG_NTS_REQ;
 			my_node->ctl.nts_cfg.server = estrdup(option->value.s);
 			break;
 
@@ -2687,7 +2687,7 @@ peer_config(
 		cast_flags = MDF_UCAST;
 		hmode = MODE_CLIENT;
 		if (NULL != hostname)
-			ctl->flags |= FLAG_DNS;
+			ctl->flags |= (FLAG_DNS | FLAG_LOOKUP);
 		break;
 
 	default:


=====================================
ntpd/ntp_dns.c
=====================================
@@ -24,18 +24,18 @@
 
 /* Notes:
 
-  Only one DNS lookup active at a time
+  This module also handles the start of NTS-KE.
+
+  Only one DNS/NTS lookup active at a time
 
   peer->srcadr holds IPv4/IPv6/UNSPEC flag
   peer->hmode holds DNS retry time (log 2)
-  FLAG_DNS used in server case to indicate need DNS
-
-  Server can't lookup again after finding an answer
-    answer uses same peer slot, turns off FLAG_DNS
-    srcadr+hmode changed by normal code
-    server can't lookup again if answer stops responding
-  Pool case makes new peer slots, pool slot unchanged
-    so OK for another lookup
+
+  Older versions of this code turned off FLAG_DNS
+  so there wasn't any way to do another DNS lookup.
+  Now, we turn off FLAG_DNSNTS to indicate success.
+
+  Pool case makes new peer slots.
 */
 
 static struct peer* active = NULL;  /* busy flag */
@@ -94,6 +94,13 @@ void dns_check(void)
 		msyslog(LOG_ERR, "DNS: dns_check: join failed %s", strerror(rc));
 		return;  /* leaves active set */
 	}
+
+	if (active->cfg.flags & FLAG_NTS) {
+		nts_check(active);
+		active = NULL;
+		return;
+	}
+
 	if (0 != gai_rc) {
 		msyslog(LOG_INFO, "DNS: dns_check: DNS error: %d, %s",
 			gai_rc, gai_strerror(gai_rc));
@@ -102,6 +109,8 @@ void dns_check(void)
 
 	for (ai = answer; NULL != ai; ai = ai->ai_next) {
 		sockaddr_u sockaddr;
+		if (sizeof(sockaddr_u) < ai->ai_addrlen)
+			continue;  /* Weird */
 		memcpy(&sockaddr, ai->ai_addr, ai->ai_addrlen);
 		/* Both dns_take_pool and dns_take_server log something. */
 		// msyslog(LOG_INFO, "DNS: Take %s=>%s",
@@ -154,18 +163,16 @@ static void* dns_lookup(void* arg)
 	res_init();
 #endif
 
-	if (pp->cfg.nts_cfg.flags & FLAG_NTS) {
-		pp->cfg.nts_cfg.flags &= !FLAG_NTS;
+	if (pp->cfg.flags & FLAG_NTS) {
 		nts_probe(pp);
+	} else {
+		ZERO(hints);
+		hints.ai_protocol = IPPROTO_UDP;
+		hints.ai_socktype = SOCK_DGRAM;
+		hints.ai_family = AF(&pp->srcadr);
+		gai_rc = getaddrinfo(pp->hostname, "ntp", &hints, &answer);
 	}
 
-
-	ZERO(hints);
-	hints.ai_protocol = IPPROTO_UDP;
-	hints.ai_socktype = SOCK_DGRAM;
-	hints.ai_family = AF(&pp->srcadr);
-	gai_rc = getaddrinfo(pp->hostname, "ntp", &hints, &answer);
-
 	kill(getpid(), SIGDNS);
 	pthread_exit(NULL);
 


=====================================
ntpd/ntp_extens.c
=====================================
@@ -217,6 +217,8 @@ bool extens_server_recv(struct ntspacket_t *ntspacket, uint8_t *pkt, int lng) {
         sawAEEF = true;
         break;
       default:
+        /* Non NTS extensions on requests at server.
+         * Call out when we get some that we want. */
         if (critical)
           return false;
         buf.next += length;
@@ -391,6 +393,8 @@ bool extens_client_recv(struct peer *peer, uint8_t *pkt, int lng) {
 	sawAEEF = true;
         break;
       default:
+        /* Non NTS extensions on reply from server.
+         * Call out when we get some that we want. */
         if (critical)
           return false;
         buf.next += length;


=====================================
ntpd/ntp_peer.c
=====================================
@@ -362,7 +362,7 @@ free_peer(
 	int		hash;
 
 
-	if ((MDF_UCAST & p->cast_flags) && !(FLAG_DNS & p->cfg.flags)) {
+	if ((MDF_UCAST & p->cast_flags) && !(FLAG_LOOKUP & p->cfg.flags)) {
 		hash = NTP_HASH_ADDR(&p->srcadr);
 		peer_hash_count[hash]--;
 
@@ -447,14 +447,6 @@ set_peerdstadr(
 	if (p == NULL || p->dstadr == dstadr)
 		return;
 
-	/*
-	 * Don't accept updates to a separate multicast receive-only
-	 * endpt while a BCLNT peer is running its unicast protocol.
-	 */
-	if (dstadr != NULL && (FLAG_BC_VOL & p->cfg.flags) &&
-	    (INT_MCASTIF & dstadr->flags) && MODE_CLIENT == p->hmode) {
-		return;
-	}
 	if (p->dstadr != NULL) {
 		p->dstadr->peercnt--;
 		UNLINK_SLIST(unlinked, p->dstadr->peers, p, ilink,
@@ -528,7 +520,7 @@ refresh_all_peerinterfaces(void)
 			continue;
 		if (MDF_POOL & p->cast_flags)
 			continue;	/* Pool slots don't get interfaces. */
-		if (FLAG_DNS & p->cfg.flags)
+		if (FLAG_LOOKUP & p->cfg.flags)
 			continue;	/* Still doing DNS lookup. */
 		peer_refresh_interface(p);
 
@@ -671,6 +663,10 @@ newpeer(
 	peer->hpoll = peer->cfg.minpoll;
 	if (cast_flags & MDF_POOL)
 		peer_clear(peer, "POOL", initializing1);
+	else if (FLAG_NTS & peer->cfg.flags)
+		peer_clear(peer, "NTS", initializing1);
+	else if (FLAG_DNS & peer->cfg.flags)
+		peer_clear(peer, "DNS", initializing1);
 	else
 		peer_clear(peer, "INIT", initializing1);
 	if (clock_ctl.mode_ntpdate)
@@ -686,7 +682,7 @@ newpeer(
 	/*
 	 * Put the new peer in the hash tables.
 	 */
-	if ((MDF_UCAST & cast_flags) && !(FLAG_DNS & ctl->flags))
+	if ((MDF_UCAST & cast_flags) && !(FLAG_LOOKUP & ctl->flags))
 		peer_update_hash(peer);
 	hash = peer->associd & NTP_HASH_MASK;
 	LINK_SLIST(assoc_hash[hash], peer, aid_link);


=====================================
ntpd/ntp_proto.c
=====================================
@@ -776,7 +776,7 @@ transmit(
 	}
 
 	/* Does server need DNS or NTS lookup? */
-	if (peer->cfg.flags & FLAG_DNS) {
+	if (peer->cfg.flags & FLAG_LOOKUP) {
 		peer->outdate = current_time;
 		if (!dns_probe(peer)) return;
 		poll_update(peer, hpoll);
@@ -2054,7 +2054,7 @@ peer_xmit(
 		peer->org_rand = peer->org_ts;
 	}
 
-	/* Maybe we should bump org_ts to compensate for crypto */
+	/* FIXME bump org_ts to compensate for crypto */
 	xpkt.xmt = htonl_fp(peer->org_rand);	/* out in xmt, back in org */
 
 	/* 3 way branch to add authentication:
@@ -2062,8 +2062,13 @@ peer_xmit(
          *  2) Shared KEY
          *  3) none
 	 */
-	if (0 < peer->nts_state.count) {
-		sendlen += extens_client_send(peer, &xpkt);
+	if (FLAG_NTS & peer->cfg.flags) {
+		if (0 < peer->nts_state.count)
+		  sendlen += extens_client_send(peer, &xpkt);
+		else {
+		  // FIXME - out of cookies
+		  return;
+		}
         } else if (0 != peer->cfg.peerkey) {
 		auth_info *auth = authlookup(peer->cfg.peerkey, true);
 		if (NULL == auth) {
@@ -2261,7 +2266,7 @@ dns_take_server(
 	int		restrict_mask;
 	struct peer *	pp;
 
-	if(!(server->cfg.flags & FLAG_DNS))
+	if(!(server->cfg.flags & FLAG_LOOKUP))
 		/* Already got an address for this slot. */
 		return;
 
@@ -2273,7 +2278,7 @@ dns_take_server(
 	}
 
 	msyslog(LOG_INFO, "DNS: Server taking: %s", socktoa(rmtadr));
-	server->cfg.flags &= (unsigned)~FLAG_DNS;
+	server->cfg.flags &= (unsigned)~FLAG_LOOKUP;
 
 	server->srcadr = *rmtadr;
 	peer_update_hash(server);
@@ -2361,7 +2366,7 @@ void dns_take_status(struct peer* peer, DNS_Status status) {
 	switch (status) {
 		case DNS_good:
 			txt = "good";
-			if (FLAG_DNS & peer->cfg.flags)
+			if (FLAG_LOOKUP & peer->cfg.flags)
 				/* server: got answer, but didn't like any */
 				/* (all) already in use ?? */
 				hpoll += 1;
@@ -2384,7 +2389,7 @@ void dns_take_status(struct peer* peer, DNS_Status status) {
 	if (hpoll > 12)
 		hpoll = 12;  /* 4096, a bit over an hour */
 	if ((DNS_good == status) &&
-		(MDF_UCAST & peer->cast_flags) && !(FLAG_DNS & peer->cfg.flags))
+		(MDF_UCAST & peer->cast_flags) && !(FLAG_LOOKUP & peer->cfg.flags))
 		hpoll = 0;  /* server: no more */
 	msyslog(LOG_INFO, "DNS: dns_take_status: %s=>%s, %d",
 		peer->hostname, txt, hpoll);
@@ -2402,7 +2407,7 @@ void dns_take_status(struct peer* peer, DNS_Status status) {
 void dns_new_interface(void) {
     struct peer *p;
     for (p = peer_list; p != NULL; p = p->p_link) {
-	if ((p->cfg.flags & FLAG_DNS) || (p->cast_flags & MDF_POOL)) {
+	if ((p->cfg.flags & FLAG_LOOKUP) || (p->cast_flags & MDF_POOL)) {
 	    p->hpoll = p->cfg.minpoll;
 	    transmit(p);   /* does all the work */
 	}


=====================================
ntpd/ntp_sandbox.c
=====================================
@@ -331,6 +331,7 @@ int scmp_sc[] = {
 	SCMP_SYS(gettimeofday),	/* mkstemp */
 	SCMP_SYS(ioctl),
 	SCMP_SYS(link),
+	SCMP_SYS(listen),
 	SCMP_SYS(lseek),
 	SCMP_SYS(munmap),
 	SCMP_SYS(open),


=====================================
ntpd/nts_client.c
=====================================
@@ -24,15 +24,17 @@
 #include "ntp_types.h"
 #include "ntpd.h"
 #include "nts.h"
-
-#define PORT "123"
+#include "ntp_dns.h"
 
 int open_TCP_socket(const char *hostname);
 bool nts_set_cert_search(SSL_CTX *ctx);
-bool nts_client_build_request(struct peer* peer, SSL *ssl);
+bool check_certificate(struct peer* peer, SSL *ssl);
+bool nts_client_send_request(struct peer* peer, SSL *ssl);
 bool nts_client_process_response(struct peer* peer, SSL *ssl);
 
-SSL_CTX *client_ctx = NULL;
+static SSL_CTX *client_ctx = NULL;
+static sockaddr_u sockaddr;
+static bool addrOK;
 
 // Fedora 29:  0x1010101fL  1.1.1a
 // Fedora 28:  0x1010009fL  1.1.0i
@@ -92,12 +94,12 @@ bool nts_client_init(void) {
 bool nts_probe(struct peer * peer) {
   SSL     *ssl;
   int      server = 0;
-  X509    *cert = NULL;
 
   if (NULL == client_ctx)
     return false;
 
   nts_ke_probes++;
+  addrOK = false;
 
   server = open_TCP_socket(peer->hostname);
   if (-1 == server)
@@ -110,24 +112,6 @@ bool nts_probe(struct peer * peer) {
   ssl = SSL_new(client_ctx);
   SSL_set_fd(ssl, server);
 
-// https://wiki.openssl.org/index.php/Hostname_validation
-#if (OPENSSL_VERSION_NUMBER > 0x1010000fL)
-  // SSL_set_hostflags(ssl, X509_CHECK_FLAG_NO_WILDCARDS);
-  SSL_set1_host(ssl, peer->hostname);
-#elif (OPENSSL_VERSION_NUMBER > 0x1000200fL)
-{
-  X509_VERIFY_PARAM *param = SSL_get0_param(ssl);
-  // X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_WILDCARDS);
-  if (1 != X509_VERIFY_PARAM_set1_host(param,
-          peer->hostname, strlen(peer->hostname))) {
-      msyslog(LOG_ERR, "NTSc: troubles setting hostflags");
-  }
-  SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL);
-}
-#else
-  msyslog(LOG_ERR, "NTSc: can't check hostname/certificate");
-#endif
-
   // SSL_set_timeout(SSL_get_session(ssl), 2);  // FIXME
   if (1 != SSL_connect(ssl)) {
     msyslog(LOG_INFO, "NTSc: SSL_connect failed");
@@ -146,72 +130,86 @@ bool nts_probe(struct peer * peer) {
     SSL_get_cipher_name(ssl),
     SSL_get_cipher_bits(ssl, NULL));
 
-  cert = SSL_get_peer_certificate(ssl);
-  if (NULL == cert) {
-    msyslog(LOG_INFO, "NTSc: No certificate");
-  } else {
-    X509_NAME *certname;
-    char name[200];
-    int certok;
-    certname = X509_get_subject_name(cert);
-    X509_NAME_oneline(certname, name, sizeof(name));
-    msyslog(LOG_INFO, "NTSc: certificate subject name: %s", name);
-    certname = X509_get_issuer_name(cert);
-    X509_NAME_oneline(certname, name, sizeof(name));
-    msyslog(LOG_INFO, "NTSc: certificate issuer name: %s", name);
-    certok = SSL_get_verify_result(ssl);
-    if (X509_V_OK == certok) {
-      msyslog(LOG_INFO, "NTSc: certificate is valid.");
-    } else {
-      msyslog(LOG_ERR, "NTSc: certificate invalid: %d=>%s",
-          certok, X509_verify_cert_error_string(certok));
-    }
-  }
+  if (!check_certificate(peer, ssl))
+    goto bail;
 
-  if (!nts_client_build_request(peer, ssl))
+  if (!nts_client_send_request(peer, ssl))
     goto bail;
   if (!nts_client_process_response(peer, ssl))
     goto bail;
 
-  // FIXME
-  /* We are using AEAD_AES_SIV_CMAC_256, from RFC 5297
-   * There are no alternatives and no clean API yet.
-   */
-  peer->nts_state.keylen = nts_get_key_length(AEAD_AES_SIV_CMAC_256);
+  /* We are using AEAD_AES_SIV_CMAC_xxx, from RFC 5297
+   * key length depends upon which key is selected */
+  peer->nts_state.keylen = nts_get_key_length(peer->nts_state.aead);
+  if (0 == peer->nts_state.keylen)
+    goto bail;		/* unknown AEAD algorithm */
   nts_make_keys(ssl,
     peer->nts_state.c2s,
     peer->nts_state.s2c,
     peer->nts_state.keylen);
 
+  addrOK = true;
+
 bail:
   SSL_shutdown(ssl);
   SSL_free(ssl);
   close(server);
 
-  return false;
+  return addrOK;
+}
+
+bool nts_check(struct peer *peer) {
+//  msyslog(LOG_INFO, "NTSc: nts_check %s, %d", sockporttoa(&sockaddr), addrOK);
+  if (addrOK) {
+    dns_take_server(peer, &sockaddr);
+    dns_take_status(peer, DNS_good);
+  } else
+    dns_take_status(peer, DNS_error);
+  return addrOK;
 }
 
 int open_TCP_socket(const char *hostname) {
+  char host[256], port[32];
+  char *tmp;
   struct addrinfo hints;
   struct addrinfo *answer;
-  sockaddr_u sockaddr;
   int gai_rc, err;
   int sockfd;
 
+  /* copy avoids dancing around const warnings */
+  strlcpy(host, hostname, sizeof(host));
+
   ZERO(hints);
   hints.ai_protocol = IPPROTO_TCP;
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_family = AF_UNSPEC;
-  gai_rc = getaddrinfo(hostname, PORT, &hints, &answer);  // FIXME
+  tmp = strchr(host, ']');
+  if (NULL == tmp) {
+    tmp = strchr(host, ':');
+  } else {
+    /* IPv6 case, start search after ] */
+    tmp = strchr(tmp, ':');
+  }
+  if (NULL == tmp) {
+    /* simple case, no : */
+    strlcpy(port, "ntp", sizeof(port));
+  } else {
+    /* Complicated case, found a : */
+    *tmp++ = 0;
+    strlcpy(port, tmp, sizeof(port));
+  }
+  gai_rc = getaddrinfo(host, port, &hints, &answer);
   if (0 != gai_rc) {
     msyslog(LOG_INFO, "NTSc: nts_probe: DNS error trying to contact %s: %d, %s",
       hostname, gai_rc, gai_strerror(gai_rc));
     return -1;
   }
 
+  /* Save first answer for NTP */
   memcpy(&sockaddr, answer->ai_addr, answer->ai_addrlen);
-  msyslog(LOG_INFO, "NTSc: nts_probe connecting to %s=%s:%s",
-    hostname, socktoa(&sockaddr), PORT);
+  msyslog(LOG_INFO, "NTSc: nts_probe connecting to %s:%s => %s",
+    host, port, sockporttoa(&sockaddr));
+  SET_PORT(&sockaddr, NTP_PORT);	/* setup default NTP address */
   sockfd = socket(AF_INET, SOCK_STREAM, 0);
   if (-1 == sockfd) {
     msyslog(LOG_INFO, "NTSc: nts_probe: no socket: %m");
@@ -229,12 +227,67 @@ int open_TCP_socket(const char *hostname) {
   return sockfd;
 }
 
+bool check_certificate(struct peer* peer, SSL *ssl) {
+  X509 *cert = SSL_get_peer_certificate(ssl);
+  char host[256], *tmp;
+
+  /* chop off trailing :port */
+  strlcpy(host, peer->hostname, sizeof(host));
+  tmp = strchr(host, ']');
+  if (NULL == tmp)
+    tmp = host;			/* not IPv6 [...] format */
+  tmp = strchr(tmp, ':');
+  if (NULL != tmp)
+    *tmp = 0;
+
+// https://wiki.openssl.org/index.php/Hostname_validation
+#if (OPENSSL_VERSION_NUMBER > 0x1010000fL)
+  SSL_set1_host(ssl, host);
+#elif (OPENSSL_VERSION_NUMBER > 0x1000200fL)
+{
+  X509_VERIFY_PARAM *param = SSL_get0_param(ssl);
+  if (1 != X509_VERIFY_PARAM_set1_host(param, host, strlen(host))) {
+      msyslog(LOG_ERR, "NTSc: troubles setting hostflags");
+  }
+  SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL);
+}
+#else
+  msyslog(LOG_ERR, "NTSc: can't check hostname/certificate");
+#endif
+
+  if (NULL == cert) {
+    msyslog(LOG_INFO, "NTSc: No certificate");
+    return false;
+  } else {
+    X509_NAME *certname;
+    char name[200];
+    int certok;
+    certname = X509_get_subject_name(cert);
+    X509_NAME_oneline(certname, name, sizeof(name));
+    msyslog(LOG_INFO, "NTSc: certificate subject name: %s", name);
+    certname = X509_get_issuer_name(cert);
+    X509_NAME_oneline(certname, name, sizeof(name));
+    msyslog(LOG_INFO, "NTSc: certificate issuer name: %s", name);
+    certok = SSL_get_verify_result(ssl);
+    if (X509_V_OK == certok) {
+      msyslog(LOG_INFO, "NTSc: certificate is valid.");
+    } else {
+      msyslog(LOG_ERR, "NTSc: certificate invalid: %d=>%s",
+          certok, X509_verify_cert_error_string(certok));
+      if (!(FLAG_NTS_NOVAL & peer->cfg.flags))
+        return false;
+    }
+  }
+  return true;
+}
+
 // FIXME - context shouldn't be magic
 bool nts_make_keys(SSL *ssl, uint8_t *c2s, uint8_t *s2c, int keylen) {
   // char *label = "EXPORTER-network-time-security/1";
   // Subject: [Ntp] [NTS4NTP] info for NTS developers
   // From: Martin Langer <mart.langer at ostfalia.de>
   // Date: Tue, 15 Jan 2019 11:40:13 +0100
+  // https://mailarchive.ietf.org/arch/msg/ntp/nkc-9n6XOPt5Glgi_ueLvuD9EfY
   // bug in OpenSSL 1.1.1a
   const char *label = "EXPORTER-nts/1";
   unsigned char context[5] = {0x00, 0x00, 0x00, 0x0f, 0x00};
@@ -256,7 +309,7 @@ bool nts_make_keys(SSL *ssl, uint8_t *c2s, uint8_t *s2c, int keylen) {
   return true;
 }
 
-bool nts_client_build_request(struct peer* peer, SSL *ssl) {
+bool nts_client_send_request(struct peer* peer, SSL *ssl) {
   uint8_t buff[1000];
   int     used, transferred;
   struct BufCtl_t buf;


=====================================
ntpd/nts_cookie.c
=====================================
@@ -112,10 +112,13 @@ int nts_make_cookie(uint8_t *cookie,
   bool ok;
   int err;
 
+  if (NULL == cookie_ctx)
+    return 0;		/* We aren't initialized yet. */
+
   // ASSERT(keylen<NTS_MAX_KEYLEN);
   
   uint8_t * finger;
-  uint32_t temp;      /* keep 4 byte alignment */
+  uint32_t temp;	/* keep 4 byte alignment */
   size_t left;
 
   err = pthread_mutex_lock(&cookie_lock);
@@ -194,6 +197,9 @@ bool nts_unpack_cookie(uint8_t *cookie, int cookielen,
   int cipherlength;
   bool ok;
 
+  if (NULL == cookie_ctx)
+    return false;	/* We aren't initialized yet. */
+
 // FIXME - these are our cookies.  We should know the exact length
   if (cookielen > NTS_MAX_COOKIELEN)
     return false;



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/fe758cb47831ad36180c826642f1f85da9d62268...1d101eada1c4e30975fe4ad8c519f2665a3f3b70

-- 
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/fe758cb47831ad36180c826642f1f85da9d62268...1d101eada1c4e30975fe4ad8c519f2665a3f3b70
You're receiving this email because of your account on gitlab.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20190227/349f5492/attachment-0001.html>


More information about the vc mailing list