[Git][NTPsec/ntpsec][master] 6 commits: Add certificates (for NTS) to NetBSD and FreeBSD

Hal Murray gitlab at mg.gitlab.com
Thu Dec 5 14:09:09 UTC 2019



Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
23046f10 by Hal Murray at 2019-12-03T03:35:13Z
Add certificates (for NTS) to NetBSD and FreeBSD

- - - - -
962b6d35 by Hal Murray at 2019-12-03T03:35:13Z
Cleanup NTS logging, server timeout, comments on timeouts

- - - - -
6cfcadfc by Hal Murray at 2019-12-03T03:35:13Z
Repeat version and command line in log file

- - - - -
56c8aaae by Hal Murray at 2019-12-03T03:35:13Z
Add message for parsing errors after log file switch.

- - - - -
9ac8162b by Hal Murray at 2019-12-05T13:53:20Z
Add tspec_to_d to timespecops.{c,h}

- - - - -
5d790798 by Hal Murray at 2019-12-05T14:01:49Z
Fix for fuzz troubles

get_systime() isn't thread safe.  It was used by NTS routines
to time things.

- - - - -


10 changed files:

- buildprep
- include/ntp_config.h
- include/ntpd.h
- include/timespecops.h
- libntp/timespecops.c
- ntpd/ntp_config.c
- ntpd/ntp_parser.y
- ntpd/ntpd.c
- ntpd/nts_client.c
- ntpd/nts_server.c


Changes:

=====================================
buildprep
=====================================
@@ -187,6 +187,8 @@ daemon () {
 	    #  There is nothing magic about 3.7.
 	    #  In Dec 2018, 3.6 and 2.7 are also good candidates.
 	    $install bison python37 py37-curses-3.7
+	    # certificates for NTS
+	    $install mozilla-rootcerts
 	    # setup "python" from command line
 	    $do ln -s /usr/pkg/bin/python3.7 /usr/pkg/bin/python
 	    $do ln -s /usr/pkg/bin/python3.7 /usr/pkg/bin/python3
@@ -204,6 +206,8 @@ daemon () {
 	    # FreeBSD
 	    $install bison python3
 	    $do ln -s /usr/local/bin/python3 /usr/local/bin/python
+	    # certificates for NTS
+	    $install ca_root_nss
 	    ;;
 	yum|dnf)
 	    $do $installer groupinstall "Development Tools" 	# Build environment


=====================================
include/ntp_config.h
=====================================
@@ -30,6 +30,9 @@
 #define CONF_SOURCE_FILE		0
 #define CONF_SOURCE_NTPQ		1
 
+/* count of parsing errors - for log file */
+extern	int	parsing_errors;
+
 /* list of servers from command line for config_peers() */
 extern	int	cmdline_server_count;
 extern	char **	cmdline_servers;


=====================================
include/ntpd.h
=====================================
@@ -37,6 +37,8 @@
 # define FALLTHRU
 #endif
 
+/* ntpd.c */
+extern	void announce_starting(void);
 
 /* ntp_config.c */
 extern	const char	*getconfig	(const char *);


=====================================
include/timespecops.h
=====================================
@@ -46,6 +46,7 @@
 
 extern struct timespec normalize_tspec(struct timespec);
 extern struct timespec d_to_tspec(double);
+extern double          tspec_to_d(struct timespec);
 extern struct timespec add_tspec(struct timespec, struct timespec);
 extern struct timespec add_tspec_ns(struct timespec, long);
 extern struct timespec sub_tspec(struct timespec, struct timespec);


=====================================
libntp/timespecops.c
=====================================
@@ -104,6 +104,17 @@ d_to_tspec(
 	return x;
 }
 
+/* convert a timespec to a double
+ * will drop low bits if integer part is big
+ */
+double
+tspec_to_d(
+	struct timespec ts
+	)
+{
+	return (ts.tv_sec + ts.tv_nsec*S_PER_NS);
+}
+
 /* x = a + b */
 struct timespec
 add_tspec(


=====================================
ntpd/ntp_config.c
=====================================
@@ -84,6 +84,9 @@
 #define REFCLOCKUNIT(srcadr)	(SRCADR(srcadr) & 0xff)
 
 
+/* count of parsing errors - for log file */
+int     parsing_errors = 0;
+
 /* list of servers from command line for config_peers() */
 int	cmdline_server_count = 0;
 char **	cmdline_servers;
@@ -2537,6 +2540,8 @@ config_logfile(
 				msyslog(LOG_ERR,
 					"CONFIG: Cannot open logfile %s: %s",
 					curr_var->value.s, strerror(errno));
+			/* Repeat critical info in logfile. Helps debugging. */
+			announce_starting();
 			break;
 
 		default:


=====================================
ntpd/ntp_parser.y
=====================================
@@ -334,6 +334,7 @@ command_list
 				ip_ctx->fname,
 				ip_ctx->errpos.nline,
 				ip_ctx->errpos.ncol);
+			parsing_errors++;
 		}
 	;
 


=====================================
ntpd/ntpd.c
=====================================
@@ -536,23 +536,7 @@ ntpdmain(
 	}
 
 	if (!dumpopts)
-	{
-		char buf[1024];	/* Secret knowledge of msyslog buf length */
-		char *cp = buf;
-
-		msyslog(LOG_NOTICE, "INIT: %s: Starting", ntpd_version());
-
-		/* Note that every arg has an initial space character */
-		snprintf(cp, sizeof(buf), "Command line:");
-		cp += strlen(cp);
-
-		for (int i = 0; i < saved_argc ; ++i) {
-			snprintf(cp, sizeof(buf) - (size_t)(cp - buf),
-				" %s", saved_argv[i]);
-			cp += strlen(cp);
-		}
-		msyslog(LOG_INFO, "INIT: %s", buf);
-	}
+	announce_starting();
 
 	uid = getuid();
 	if (uid && !dumpopts) {
@@ -898,8 +882,8 @@ ntpdmain(
 	readconfig(getconfig(explicit_config));
 	check_minsane();
         if ( 8 > sizeof(time_t) ) {
-	    msyslog(LOG_ERR, "INIT: This system has a 32-bit time_t.");
-	    msyslog(LOG_ERR, "INIT: This ntpd will fail on 2038-01-19T03:14:07Z.");
+	    msyslog(LOG_NOTICE, "INIT: This system has a 32-bit time_t.");
+	    msyslog(LOG_NOTICE, "INIT: This ntpd will fail on 2038-01-19T03:14:07Z.");
         }
 
 	loop_config(LOOP_DRIFTINIT, 0);
@@ -925,6 +909,33 @@ ntpdmain(
         /* unreachable, mainloop() never returns */
 }
 
+void announce_starting() {
+	char buf[1024];	/* Secret knowledge of msyslog buf length */
+	char *cp = buf;
+
+	msyslog(LOG_NOTICE, "INIT: %s: Starting", ntpd_version());
+
+	/* Note that every arg gets an initial space character */
+	snprintf(cp, sizeof(buf), "Command line:");
+	cp += strlen(cp);
+
+	for (int i = 0; i < saved_argc ; ++i) {
+		snprintf(cp, sizeof(buf) - (size_t)(cp - buf),
+			" %s", saved_argv[i]);
+		cp += strlen(cp);
+	}
+	msyslog(LOG_NOTICE, "INIT: %s", buf);
+
+	/* This is helpful if you specify a log file in ntp.conf
+	 * The error messages while parsing ntp.conf go to syslog.
+	 * You might forget to look there while debugging things.
+	 */
+	if (0 < parsing_errors) {
+		msyslog(LOG_ERR, "INIT: saw %d parsing errors", parsing_errors);
+		parsing_errors = 0;
+	}
+}
+
 /*
  * Process incoming packets until exit or interrupted.
  */
@@ -984,7 +995,7 @@ static void mainloop(void)
 				if (!--mdnstries) {
 					msyslog(LOG_ERR, "INIT: Unable to register mDNS, giving up.");
 				} else {
-					msyslog(LOG_INFO, "INIT: Unable to register mDNS, will try later.");
+					msyslog(LOG_NOTICE, "INIT: Unable to register mDNS, will try later.");
 				}
 			} else {
 				msyslog(LOG_INFO, "INIT: mDNS service registered.");


=====================================
ntpd/nts_client.c
=====================================
@@ -30,6 +30,7 @@
 #include "nts2.h"
 #include "ntp_dns.h"
 #include "ntp_stdlib.h"
+#include "timespecops.h"
 
 SSL_CTX* make_ssl_client_ctx(const char *filename);
 int open_TCP_socket(struct peer *peer, const char *hostname);
@@ -74,14 +75,14 @@ bool nts_probe(struct peer * peer) {
 	char errbuf[100];
 	SSL     *ssl;
 	int      server;
-	l_fp     start, finish;
+	struct timespec start, finish;
 	int      err;
 
 	if (NULL == client_ctx)
 		return false;
 
 	addrOK = false;
-	get_systime(&start);
+	clock_gettime(CLOCK_REALTIME, &start);
 
 	if (NULL == hostname) {
 		/* IP Address case */
@@ -182,10 +183,10 @@ bool nts_probe(struct peer * peer) {
 	SSL_free(ssl);
 	close(server);
 
-	get_systime(&finish);
-	finish -= start;
-	msyslog(LOG_INFO, "NTSc: NTS-KE req to %s took %.3Lf sec, %s",
-		hostname, lfptod(finish),
+	clock_gettime(CLOCK_REALTIME, &finish);
+	finish = sub_tspec(finish, start);
+	msyslog(LOG_INFO, "NTSc: NTS-KE req to %s took %.3f sec, %s",
+		hostname, tspec_to_d(finish),
 		addrOK? "OK" : "fail");
 
 	return addrOK;
@@ -231,7 +232,7 @@ SSL_CTX* make_ssl_client_ctx(const char * filename) {
 #endif
 
 	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
-	SSL_CTX_set_timeout(ctx, NTS_KE_TIMEOUT);
+	SSL_CTX_set_timeout(ctx, NTS_KE_TIMEOUT);   /* session lifetime */
 
 	ok &= nts_load_versions(ctx);
 	ok &= nts_load_ciphers(ctx);
@@ -255,7 +256,7 @@ int open_TCP_socket(struct peer *peer, const char *hostname) {
 	struct addrinfo *answer;
 	int gai_rc, err;
 	int sockfd;
-	l_fp start, finish;
+	struct timespec start, finish;
 
 	/* copy avoids dancing around const warnings */
 	strlcpy(host, hostname, sizeof(host));
@@ -281,17 +282,17 @@ int open_TCP_socket(struct peer *peer, const char *hostname) {
 	hints.ai_protocol = IPPROTO_TCP;
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_family = AF(&peer->srcadr);  /* -4, -6 switch */
-	get_systime(&start);
+	clock_gettime(CLOCK_REALTIME, &start);
 	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;
 	}
-	get_systime(&finish);
-	finish -= start;
-	msyslog(LOG_INFO, "NTSc: DNS lookup of %s took %.3Lf sec",
-		hostname, lfptod(finish));
+	clock_gettime(CLOCK_REALTIME, &finish);
+	finish = sub_tspec(finish, start);
+	msyslog(LOG_INFO, "NTSc: DNS lookup of %s took %.3f sec",
+		hostname, tspec_to_d(finish));
 
 	/* Save first answer for NTP, switch to NTP port in case of server-name:port */
 	memcpy(&sockaddr, answer->ai_addr, answer->ai_addrlen);
@@ -307,6 +308,9 @@ int open_TCP_socket(struct peer *peer, const char *hostname) {
 		msyslog(LOG_INFO, "NTSc: nts_probe: no socket: %s", errbuf);
 	} else {
 		// Use first answer
+		// FIXME: need timeout - no simple way
+		// a) timer, signal, EINTR
+		// b) fcntl(O_NONBLOCK), select/poll
 		err = connect(sockfd, answer->ai_addr, answer->ai_addrlen);
 		if (-1 == err) {
 			ntp_strerror_r(errno, errbuf, sizeof(errbuf));


=====================================
ntpd/nts_server.c
=====================================
@@ -17,12 +17,17 @@
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 #include <openssl/x509.h>
+/* Old OpenSSL 1.0.2 doesn't have sslerr.h */
+#ifndef SSL_R_WRONG_VERSION_NUMBER
+#include <openssl/sslerr.h>
+#endif
 
 #include "ntp.h"
 #include "ntpd.h"
 #include "ntp_stdlib.h"
 #include "nts.h"
 #include "nts2.h"
+#include "timespecops.h"
 
 /* Beware: bind and accept take type sockaddr, but that's not big
  *         enough for an IPv6 address.
@@ -33,7 +38,7 @@ static bool create_listener4(int port);
 static bool create_listener6(int port);
 static void* nts_ke_listener(void*);
 static bool nts_ke_request(SSL *ssl);
-static void nts_ke_accept_fail(char* addrbuf, l_fp finish);
+static void nts_ke_accept_fail(char* addrbuf, double sec);
 
 static void nts_lock_certlock(void);
 static void nts_unlock_certlock(void);
@@ -113,6 +118,7 @@ bool nts_server_init(void) {
 #endif
 
 	SSL_CTX_set_session_cache_mode(server_ctx, SSL_SESS_CACHE_OFF);
+	SSL_CTX_set_timeout(server_ctx, NTS_KE_TIMEOUT);  /* session lifetime */
 
 	ok &= nts_load_versions(server_ctx);
 	ok &= nts_load_ciphers(server_ctx);
@@ -197,7 +203,7 @@ void* nts_ke_listener(void* arg) {
 		sockaddr_u addr;
 		socklen_t len = sizeof(addr);
 		SSL *ssl;
-		l_fp start, finish;
+		struct timespec start, finish;
 		int client, err;
 
 		client = accept(sock, &addr.sa, &len);
@@ -209,7 +215,7 @@ void* nts_ke_listener(void* arg) {
 			sleep(1);		/* avoid log clutter on bug */
 			continue;
 		}
-		get_systime(&start);
+		clock_gettime(CLOCK_REALTIME, &start);
 		sockporttoa_r(&addr, addrbuf, sizeof(addrbuf));
 
 /* This is disabled in order to reduce clutter in the log file.
@@ -246,9 +252,9 @@ void* nts_ke_listener(void* arg) {
 		SSL_set_fd(ssl, client);
 
 		if (SSL_accept(ssl) <= 0) {
-			get_systime(&finish);
-			finish -= start;
-			nts_ke_accept_fail(addrbuf, finish);
+			clock_gettime(CLOCK_REALTIME, &finish);
+			finish = sub_tspec(finish, start);
+			nts_ke_accept_fail(addrbuf, tspec_to_d(finish));
 			SSL_free(ssl);
 			close(client);
 			nts_ke_serves_bad++;
@@ -268,11 +274,11 @@ void* nts_ke_listener(void* arg) {
 		SSL_free(ssl);
 		close(client);
 
-		get_systime(&finish);
-		finish -= start;
+		clock_gettime(CLOCK_REALTIME, &finish);
+		finish = sub_tspec(finish, start);
 		nts_ke_serves_good++;
-		msyslog(LOG_INFO, "NTSs: NTS-KE from %s, Using %s, took %.3Lf sec",
-			addrbuf, usingbuf, lfptod(finish));
+		msyslog(LOG_INFO, "NTSs: NTS-KE from %s, Using %s, took %.3f sec",
+			addrbuf, usingbuf, tspec_to_d(finish));
 
 	}
 	return NULL;
@@ -281,27 +287,25 @@ void* nts_ke_listener(void* arg) {
 /* Analyze failure from SSL_accept
  * print single error message for common cases.
  */
-void nts_ke_accept_fail(char* addrbuf, l_fp finish) {
+void nts_ke_accept_fail(char* addrbuf, double sec) {
 	unsigned long err = ERR_peek_error();
-	const char *reason;
-	switch(err) {
-	  case 0x1408F10B:
-		reason = "wrong version number";
-		break;
-	  case 0x1408F09C:
-		reason = "http request";
-		break;
-	  case 0x1417A0C1:
-		reason = "no shared cipher";
-		break;
-	  default:
-		msyslog(LOG_INFO, "NTSs: SSL accept from %s failed, took %.3Lf sec",
-			addrbuf, lfptod(finish));
+	int lib = ERR_GET_LIB(err);
+	int reason = ERR_GET_REASON(err);
+	const char *msg = NULL;
+	if (ERR_LIB_SSL == lib && SSL_R_WRONG_VERSION_NUMBER == reason)
+		msg = "wrong version number";
+	if (ERR_LIB_SSL == lib && SSL_R_HTTP_REQUEST == reason)
+		msg = "http request";
+	if (ERR_LIB_SSL == lib && SSL_R_NO_SHARED_CIPHER == reason)
+		msg = "no shared cipher";
+	if (NULL == msg) {
+		msyslog(LOG_INFO, "NTSs: SSL accept from %s failed, took %.3f sec",
+			addrbuf, sec);
 		nts_log_ssl_error();
 		return;
 	}
-	msyslog(LOG_INFO, "NTSs: SSL accept from %s failed: %s, took %.3Lf sec",
-		addrbuf, reason, lfptod(finish));
+	msyslog(LOG_INFO, "NTSs: SSL accept from %s failed: %s, took %.3f sec",
+		addrbuf, msg, sec);
 }
 
 bool nts_ke_request(SSL *ssl) {



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/49556c6b47436bb98f12d2d7e676325ff478c440...5d7907981b37832654a6cf3737763221481f72aa

-- 
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/49556c6b47436bb98f12d2d7e676325ff478c440...5d7907981b37832654a6cf3737763221481f72aa
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/20191205/10d56c06/attachment-0001.htm>


More information about the vc mailing list