[Git][NTPsec/ntpsec][master] 3 commits: NTS: tweak comments

Hal Murray gitlab at mg.gitlab.com
Mon May 13 07:10:25 UTC 2019



Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
92f31395 by Hal Murray at 2019-05-06T08:29:47Z
NTS: tweak comments

- - - - -
aa5b2746 by Hal Murray at 2019-05-06T08:29:47Z
NTS: add subroutines to lock/unlock cookie_lock

- - - - -
09896eff by Hal Murray at 2019-05-06T08:29:47Z
NTS: reload certificate file on SIGHUP

- - - - -


8 changed files:

- docs/includes/ntpd-body.adoc
- include/ntpd.h
- include/nts2.h
- ntpd/ntpd.c
- ntpd/nts.c
- ntpd/nts_cookie.c
- ntpd/nts_extens.c
- ntpd/nts_server.c


Changes:

=====================================
docs/includes/ntpd-body.adoc
=====================================
@@ -534,6 +534,8 @@ SIGQUIT, SIGINT, and SIGTERM will cause ntpd to clean up and exit.
 
 SIGHUP will reopen the log file if it has changed and
 check for a new leapseconds file if one was specified.
+If the NTS server is enabled, it will reload the
+certificate file if it has changed.
 
 On most systems, you can send SIGHUP to +ntpd+ with
 -----


=====================================
include/ntpd.h
=====================================
@@ -209,6 +209,9 @@ extern void record_ref_stats(
 
 extern	void	check_leap_file	(bool is_daily_check, time_t systime);
 
+/* NTS */
+extern	void	check_cert_file	(void);
+
 /* packetstamp.c */
 extern void	enable_packetstamps(int, sockaddr_u *);
 extern l_fp	fetch_packetstamp(struct msghdr *);


=====================================
include/nts2.h
=====================================
@@ -18,6 +18,7 @@
 
 
 bool nts_load_certificate(SSL_CTX *ctx);
+void nts_reload_certificate(SSL_CTX *ctx);
 bool nts_load_ciphers(SSL_CTX *ctx);
 bool nts_load_versions(SSL_CTX *ctx);
 


=====================================
ntpd/ntpd.c
=====================================
@@ -906,7 +906,7 @@ ntpdmain(
 	}
 #endif
 
-	nts_init2();		/* Before droproot */
+	nts_init2();		/* After droproot */
 
 	if (access(statsdir, W_OK) != 0) {
 	    msyslog(LOG_ERR, "statistics directory %s does not exist or is unwriteable, error %s", statsdir, strerror(errno));
@@ -958,11 +958,8 @@ static void mainloop(void)
 
 			reopen_logfile();
 
-			{
-			time_t tnow;
-			time(&tnow);
-			check_leap_file(false, tnow);
-			}
+			check_leap_file(false, time(NULL));
+			check_cert_file();
 		}
 
 		/*


=====================================
ntpd/nts.c
=====================================
@@ -16,6 +16,10 @@
 
 #include "config.h"
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
 #include <arpa/inet.h>
 #include <openssl/err.h>
 
@@ -174,6 +178,25 @@ bool nts_load_ciphers(SSL_CTX *ctx) {
 }
 
 
+static struct stat certfile_stat;
+
+void nts_reload_certificate(SSL_CTX *ctx) {
+    struct stat temp_stat;
+    const char *cert = NTS_CERT_FILE;
+
+    if (NULL != ntsconfig.cert)
+       cert = ntsconfig.cert;
+
+    stat(cert, &temp_stat);
+
+    if ((certfile_stat.st_mtime == temp_stat.st_mtime)
+            && (certfile_stat.st_ctime == temp_stat.st_ctime))
+        return;  /* avoid clutter in log file */
+
+    nts_load_certificate(ctx);
+
+}
+
 bool nts_load_certificate(SSL_CTX *ctx) {
     const char *cert = NTS_CERT_FILE;
     const char *key = NTS_KEY_FILE;
@@ -183,6 +206,10 @@ bool nts_load_certificate(SSL_CTX *ctx) {
     if (NULL != ntsconfig.key)
        key = ntsconfig.key;
 
+    /* for reload checking */
+    if (stat(cert, &certfile_stat))
+        return false;
+
     if (1 != SSL_CTX_use_certificate_chain_file(ctx, cert)) {
         msyslog(LOG_ERR, "NTSs: can't load certificate (chain) from %s", cert);
         nts_log_ssl_error();


=====================================
ntpd/nts_cookie.c
=====================================
@@ -93,6 +93,8 @@ uint64_t nts_cookie_decode_old = 0;
 uint64_t nts_cookie_decode_too_old = 0;
 uint64_t nts_cookie_decode_error = 0;
 
+void nts_lock_cookielock(void);
+void nts_unlock_cookielock(void);
 
 // FIXME  AEAD_LENGTH
 /* Associated data: aead (rounded up to 4) plus NONCE */
@@ -252,7 +254,6 @@ int nts_make_cookie(uint8_t *cookie,
   uint8_t *nonce;
   int used, plainlength;
   bool ok;
-  int err;
   uint8_t * finger;
   uint32_t temp;	/* keep 4 byte alignment */
   size_t left;
@@ -291,11 +292,7 @@ int nts_make_cookie(uint8_t *cookie,
   used = finger-cookie;
   left = NTS_MAX_COOKIELEN-used;
 
-  err = pthread_mutex_lock(&cookie_lock);
-  if (0 != err) {
-    msyslog(LOG_ERR, "ERR: Can't lock cookie_lock: %d", err);
-    exit(2);
-  }
+  nts_lock_cookielock();
 
   ok = AES_SIV_Encrypt(cookie_ctx,
            finger, &left,   /* left: in: max out length, out: length used */
@@ -304,11 +301,7 @@ int nts_make_cookie(uint8_t *cookie,
            plaintext, plainlength,
            cookie, AD_LENGTH);
 
-  err = pthread_mutex_unlock(&cookie_lock);
-  if (0 != err) {
-    msyslog(LOG_ERR, "ERR: Can't unlock cookie_lock: %d", err);
-    exit(2);
-  }
+  nts_unlock_cookielock();
 
   if (!ok) {
     msyslog(LOG_ERR, "NTS: nts_make_cookie - Error from AES_SIV_Encrypt");
@@ -338,7 +331,6 @@ bool nts_unpack_cookie(uint8_t *cookie, int cookielen,
   uint32_t temp;
   size_t plainlength;
   int cipherlength;
-  int err;
   bool ok;
 
   if (NULL == cookie_ctx)
@@ -368,11 +360,7 @@ bool nts_unpack_cookie(uint8_t *cookie, int cookielen,
   cipherlength = cookielen - AD_LENGTH;
   plainlength = NTS_MAX_COOKIELEN;
 
-  err = pthread_mutex_lock(&cookie_lock);
-  if (0 != err) {
-    msyslog(LOG_ERR, "ERR: Can't lock cookie_lock: %d", err);
-    exit(2);
-  }
+  nts_lock_cookielock();
 
   ok = AES_SIV_Decrypt(cookie_ctx,
            plaintext, &plainlength,
@@ -381,11 +369,7 @@ bool nts_unpack_cookie(uint8_t *cookie, int cookielen,
            finger, cipherlength,
            cookie, AD_LENGTH);
 
-  err = pthread_mutex_unlock(&cookie_lock);
-  if (0 != err) {
-    msyslog(LOG_ERR, "ERR: Can't unlock cookie_lock: %d", err);
-    exit(2);
-  }
+  nts_unlock_cookielock();
 
   if (!ok) {
     nts_cookie_decode_error++;
@@ -405,6 +389,20 @@ bool nts_unpack_cookie(uint8_t *cookie, int cookielen,
   return true;
 }
 
+void nts_lock_cookielock(void) {
+  int err = pthread_mutex_lock(&cookie_lock);
+  if (0 != err) {
+    msyslog(LOG_ERR, "ERR: Can't lock cookie_lock: %d", err);
+    exit(2);
+  }
+}
 
+void nts_unlock_cookielock(void) {
+  int err = pthread_mutex_unlock(&cookie_lock);
+  if (0 != err) {
+    msyslog(LOG_ERR, "ERR: Can't unlock cookie_lock: %d", err);
+    exit(2);
+  }
+}
 
 /* end */


=====================================
ntpd/nts_extens.c
=====================================
@@ -1,7 +1,5 @@
 /*
  * ntp_extens.c - Network Time Protocol (NTP) extension processing
- * Copyright 2019 by the NTPsec project contributors
- * SPDX-License-Identifier: BSD-4-Clause-UC
  *
  * NB: This module is working with the wire format packet.
  *     It must do byte swapping.
@@ -84,8 +82,9 @@ int extens_client_send(struct peer *peer, struct pkt *xpkt) {
   peer->nts_state.readIdx = peer->nts_state.readIdx % NTS_MAX_COOKIES;
   peer->nts_state.count--;
 
-  // Need more cookies?
+  /* Need more cookies? */
   for (int i=peer->nts_state.count+1; i<NTS_MAX_COOKIES; i++) {
+    /* WARN: This may get too big for the MTU. */
     ex_append_header(&buf, NTS_Cookie_Placeholder, peer->nts_state.cookielen);
     memset(buf.next, 0, peer->nts_state.cookielen);
     buf.next += peer->nts_state.cookielen;
@@ -286,6 +285,9 @@ int extens_server_send(struct ntspacket_t *ntspacket, struct pkt *xpkt) {
   ex_append_record_bytes(&buf, NTS_Cookie,
       cookie, cookielen);
   for (int i=1; i<ntspacket->needed; i++) {
+    /* WARN: This may get too big for the MTU. See length calculation above.
+     * Responses are the same length as requests to avoid DDoS amplification.
+     * So if it got to us, there is a good chance it will get back.  */
     nts_make_cookie(cookie, ntspacket->aead,
         ntspacket->c2s, ntspacket->s2c, ntspacket->keylen);
     ex_append_record_bytes(&buf, NTS_Cookie,


=====================================
ntpd/nts_server.c
=====================================
@@ -1,7 +1,5 @@
 /*
  * nts_server.c - Network Time Security (NTS) server side support
- * Copyright 2019 by the NTPsec project contributors
- * SPDX-License-Identifier: BSD-4-Clause-UC
  *
  * Section references are to
  * https://tools.ietf.org/html/draft-ietf-ntp-using-nts-for-ntp-15
@@ -31,11 +29,18 @@ static int create_listener(int port, int family);
 static void* nts_ke_listener(void*);
 static bool nts_ke_request(SSL *ssl);
 
+static void nts_lock_certlock(void);
+static void nts_unlock_certlock(void);
+
 
 static SSL_CTX *server_ctx = NULL;
 static int listner4_sock = -1;
 static int listner6_sock = -1;
 
+/* We need a lock to protect reloading our certificate.
+ * This seems like overkill, but it doesn't happen often. */
+pthread_mutex_t certificate_lock = PTHREAD_MUTEX_INITIALIZER;
+
 /* Statistics for ntpq */
 uint64_t nts_ke_serves_good = 0;
 uint64_t nts_ke_serves_bad = 0;
@@ -111,6 +116,29 @@ bool nts_server_init2(void) {
     return true;
 }
 
+void check_cert_file(void) {
+
+    nts_lock_certlock();
+    nts_reload_certificate(server_ctx);
+    nts_unlock_certlock();
+}
+
+void nts_lock_certlock(void) {
+    int err = pthread_mutex_lock(&certificate_lock);
+    if (0 != err) {
+      msyslog(LOG_ERR, "ERR: Can't lock certificate_lock: %d", err);
+      exit(2);
+    }
+}
+
+void nts_unlock_certlock(void) {
+    int err = pthread_mutex_unlock(&certificate_lock);
+    if (0 != err) {
+      msyslog(LOG_ERR, "ERR: Can't unlock certificate_lock: %d", err);
+      exit(2);
+    }
+}
+
 void* nts_ke_listener(void* arg) {
     struct timeval timeout = {.tv_sec = NTS_KE_TIMEOUT, .tv_usec = 0};
     int sock = *(int*)arg;
@@ -145,8 +173,10 @@ void* nts_ke_listener(void* arg) {
             continue;
         }
 
-        /* For high volume servers, this should go in a new thread. */
+        /* WARN: For high volume servers, this should go in a new thread. */
+        nts_lock_certlock();
         ssl = SSL_new(server_ctx);
+        nts_unlock_certlock();
         SSL_set_fd(ssl, client);
 
         if (SSL_accept(ssl) <= 0) {



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/5b9324c0c00d68d53d82f1d00b54ed2f0c63601b...09896eff3e53e5f7ab09823225bf55da5f0ab0a0

-- 
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/5b9324c0c00d68d53d82f1d00b54ed2f0c63601b...09896eff3e53e5f7ab09823225bf55da5f0ab0a0
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/20190513/3e5de7a3/attachment-0001.html>


More information about the vc mailing list