OpenNTPD daemon with OpenSSL implementation & flexible configurability
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1701 lines
49 KiB

  1. From: Pekka Helenius <fincer89@hotmail.com>
  2. Date: Tue, 04 Aug 2020 01:52:16 +0300
  3. Subject: Implement OpenSSL support, update manual, update ChangeLog
  4. --- a/configure.ac 2020-07-31 23:00:40.000000000 +0300
  5. +++ b/configure.ac 2020-08-02 01:23:30.696950640 +0300
  6. @@ -59,35 +59,100 @@ AM_CONDITIONAL([HAVE_ADJFREQ], [test "x$
  7. AM_CONDITIONAL([HAVE_CLOCK_GETRES], [test "x$ac_cv_func_clock_getres" = xyes])
  8. AM_CONDITIONAL([HAVE_CLOCK_GETTIME], [test "x$ac_cv_func_clock_gettime" = xyes])
  9. -# check for libtls
  10. -AC_SEARCH_LIBS([tls_config_set_ca_mem],[tls],
  11. - [LIBS="$LIBS -ltls -lssl -lcrypto"],,[-lssl -lcrypto])
  12. -AC_CHECK_FUNCS([tls_config_set_ca_mem])
  13. -
  14. -# check if libtls uses 3-argument tls_write
  15. -AC_CACHE_CHECK([if tls_write takes 3 arguments], ac_cv_have_tls_write_3_arg, [
  16. - AC_LINK_IFELSE([AC_LANG_PROGRAM([[
  17. -#include <tls.h>
  18. -size_t outlen;
  19. - ]], [[ tls_write(NULL, NULL, 0); ]])],
  20. - [ ac_cv_have_tls_write_3_arg="yes" ],
  21. - [ ac_cv_have_tls_write_3_arg="no"
  22. +# NOTE: hard-set AC_CHECK_HEADER or friends can't really be checked since
  23. +# libressl/openssl include header files must be determined by OS basis
  24. +# during compilation. Use the following approach instead.
  25. +
  26. +AM_CONDITIONAL(HAVE_SSL, false)
  27. +AM_CONDITIONAL([HAVE_LIBRESSL], false)
  28. +AM_CONDITIONAL([HAVE_OPENSSL], false)
  29. +
  30. +# check for libressl
  31. +AC_ARG_WITH([libressl],
  32. + AS_HELP_STRING([--without-libressl],
  33. + [Disable LibreSSL support for constraints]))
  34. +
  35. +AS_IF([test "x$with_libressl" != "xno" ],
  36. + [ have_libressl="yes" ],
  37. + [ have_libressl="no" ]
  38. +)
  39. +
  40. +if test "x$have_libressl" == "xyes"; then
  41. +
  42. + AC_SEARCH_LIBS([tls_config_set_ca_mem],[tls],
  43. + [LIBS="$LIBS -ltls -lssl -lcrypto"],,[-lssl -lcrypto])
  44. +
  45. + AC_CHECK_FUNCS([tls_config_set_ca_mem])
  46. +
  47. + # check if libressl uses 3-argument tls_write
  48. + AC_CACHE_CHECK(
  49. + [if LibreSSL tls_write takes 3 arguments],
  50. + ac_cv_have_libressl_write_3_arg,
  51. + [AC_LINK_IFELSE([AC_LANG_PROGRAM(
  52. + [[ #include <libressl/tls.h> ]],
  53. + [[ size_t outlen; ]],
  54. + [[ tls_write(NULL, NULL, 0); ]]
  55. + )],
  56. + [ ac_cv_have_libressl_write_3_arg="yes" ],
  57. + [ ac_cv_have_libressl_write_3_arg="no" ]
  58. + )
  59. + ])
  60. +fi
  61. +
  62. +# check for openssl
  63. +AC_ARG_WITH([openssl],
  64. + AS_HELP_STRING([--without-openssl],
  65. + [Disable OpenSSL support for constraints]))
  66. +
  67. +AS_IF([test "x$with_openssl" != "xno" ],
  68. + [ have_openssl="yes" ],
  69. + [ have_openssl="no" ]
  70. +)
  71. +
  72. +if test "x$have_openssl" == "xyes"; then
  73. +
  74. + AC_SEARCH_LIBS([X509_STORE_load_locations],[ssl],
  75. + [LIBS="$LIBS -lssl -lcrypto"],,[-lssl -lcrypto])
  76. +
  77. + AC_CHECK_FUNCS([X509_STORE_load_locations])
  78. +
  79. + # check if openssl uses 3-argument SSL_write
  80. + AC_CACHE_CHECK(
  81. + [if OpenSSL SSL_write takes 3 arguments],
  82. + ac_cv_have_openssl_write_3_arg,
  83. + [AC_LINK_IFELSE([AC_LANG_PROGRAM(
  84. + [[ #include <openssl/ssl.h> ]],
  85. + [[ SSL *a; SSL_CTX *ff; ]],
  86. + [[ ff = SSL_CTX_new(TLS_method()); ]],
  87. + [[ a = SSL_new(ff); ]],
  88. + [[ SSL_write(a, NULL, 0); ]]
  89. + )],
  90. + [ ac_cv_have_openssl_write_3_arg="yes" ],
  91. + [ ac_cv_have_openssl_write_3_arg="no" ]
  92. + )
  93. ])
  94. -])
  95. +fi
  96. -AC_ARG_ENABLE([https-constraint],
  97. - AS_HELP_STRING([--disable-https-constraint],
  98. - [Disable HTTPS Constraint Functionality]))
  99. -
  100. -AM_CONDITIONAL([HAVE_LIBTLS],
  101. - [test "x$ac_cv_func_tls_config_set_ca_mem" = xyes \
  102. - -a "x$ac_cv_have_tls_write_3_arg" = xyes \
  103. - -a "x$enable_https_constraint" != xno])
  104. -
  105. -if test "x$ac_cv_func_tls_config_set_ca_mem" = xyes \
  106. - -a "x$ac_cv_have_tls_write_3_arg" = xyes \
  107. - -a "x$enable_https_constraint" != xno; then
  108. - AC_DEFINE([HAVE_LIBTLS], [yes])
  109. +if test "x$with_libressl" != xno \
  110. + -a "x$ac_cv_func_tls_config_set_ca_mem" = xyes \
  111. + -a "x$ac_cv_have_libressl_write_3_arg" = xyes; then
  112. + AM_CONDITIONAL([HAVE_LIBRESSL], true)
  113. + AM_CONDITIONAL([HAVE_SSL], true)
  114. + AC_DEFINE([HAVE_LIBRESSL], [yes])
  115. + AC_DEFINE([HAVE_SSL], [yes])
  116. +else
  117. + AC_MSG_WARN([LibreSSL support disabled])
  118. +fi
  119. +
  120. +if test "x$with_openssl" != xno \
  121. + -a "x$ac_cv_func_X509_STORE_load_locations" = xyes \
  122. + -a "x$ac_cv_have_openssl_write_3_arg" = xyes; then
  123. + AM_CONDITIONAL([HAVE_OPENSSL], true)
  124. + AM_CONDITIONAL([HAVE_SSL], true)
  125. + AC_DEFINE([HAVE_OPENSSL], [yes])
  126. + AC_DEFINE([HAVE_SSL], [yes])
  127. +else
  128. + AC_MSG_WARN([OpenSSL support disabled])
  129. fi
  130. # Share test results with automake
  131. @@ -144,14 +209,6 @@ AC_ARG_WITH([privsep-path],
  132. )
  133. AC_SUBST(PRIVSEP_PATH)
  134. -AC_ARG_WITH([cacert],
  135. - AS_HELP_STRING([--with-cacert=path],
  136. - [CA certificate location for HTTPS constraint validation]),
  137. - CONSTRAINT_CA="$withval",
  138. - CONSTRAINT_CA="/etc/ssl/cert.pem"
  139. -)
  140. -AC_DEFINE_UNQUOTED(CONSTRAINT_CA, "$CONSTRAINT_CA", [CA certificate path])
  141. -
  142. AC_CONFIG_FILES([
  143. Makefile
  144. include/Makefile
  145. --- a/include/tls.h 2020-07-31 23:00:40.000000000 +0300
  146. +++ b/include/tls.h 2020-08-01 19:24:29.153594762 +0300
  147. @@ -1,8 +1,22 @@
  148. /*
  149. * Public domain
  150. * tls.h compatibility shim
  151. + *
  152. + * __linux__
  153. + * __sun
  154. + * __FreeBSD__
  155. + * __NetBSD__
  156. + * __OpenBSD__
  157. + * __APPLE__
  158. */
  159. -#ifdef HAVE_LIBTLS
  160. +#if defined(HAVE_LIBRESSL) && __linux__
  161. +#include_next <libressl/tls.h>
  162. +#elif HAVE_LIBRESSL
  163. #include_next <tls.h>
  164. #endif
  165. +
  166. +#ifdef HAVE_OPENSSL
  167. +#include <openssl/ssl.h>
  168. +#include <openssl/err.h>
  169. +#endif
  170. --- a/src/constraint.c 2020-08-02 01:57:57.020286149 +0300
  171. +++ b/src/constraint.c 2020-08-02 01:58:28.366952848 +0300
  172. @@ -39,7 +39,6 @@
  173. #include <unistd.h>
  174. #include <time.h>
  175. #include <ctype.h>
  176. -#include <tls.h>
  177. #include <pwd.h>
  178. #include <math.h>
  179. @@ -65,33 +64,11 @@ void priv_constraint_close(int, int);
  180. void priv_constraint_readquery(struct constraint *, struct ntp_addr_msg *,
  181. uint8_t **);
  182. -struct httpsdate *
  183. - httpsdate_init(const char *, const int *, const char *,
  184. - const char *, const u_int8_t *, size_t);
  185. -void httpsdate_free(void *);
  186. -int httpsdate_request(struct httpsdate *, struct timeval *);
  187. -void *httpsdate_query(const char *, const int *, const char *,
  188. - const char *, const u_int8_t *, size_t,
  189. - struct timeval *, struct timeval *);
  190. -
  191. -char *tls_readline(struct tls *, size_t *, size_t *, struct timeval *);
  192. -
  193. u_int constraint_cnt;
  194. extern u_int peer_cnt;
  195. extern struct imsgbuf *ibuf; /* priv */
  196. extern struct imsgbuf *ibuf_main; /* chld */
  197. -struct httpsdate {
  198. - char *tls_addr;
  199. - char *tls_port;
  200. - char *tls_hostname;
  201. - char *tls_path;
  202. - char *tls_request;
  203. - struct tls_config *tls_config;
  204. - struct tls *tls_ctx;
  205. - struct tm tls_tm;
  206. -};
  207. -
  208. int
  209. constraint_init(struct constraint *cstr)
  210. {
  211. @@ -155,7 +132,7 @@ constraint_query(struct constraint *cstr
  212. {
  213. time_t now;
  214. struct ntp_addr_msg am;
  215. - struct iovec iov[3];
  216. + struct iovec iov[4];
  217. int iov_cnt = 0;
  218. now = getmonotime();
  219. @@ -252,7 +229,7 @@ priv_constraint_msg(u_int32_t id, u_int8
  220. return;
  221. }
  222. memcpy(&am, data, sizeof(am));
  223. - if (len != (sizeof(am) + am.namelen + am.pathlen + am.portlen)) {
  224. + if (len != (sizeof(am) + am.namelen + am.pathlen + am.portlen)) {
  225. log_warnx("constraint id %d: invalid query received", id);
  226. return;
  227. }
  228. @@ -343,13 +320,13 @@ priv_constraint_readquery(struct constra
  229. memcpy(h, &am->a, sizeof(*h));
  230. memcpy(&port, &am->port, sizeof(port));
  231. h->next = NULL;
  232. -
  233. +
  234. cstr->id = imsg.hdr.peerid;
  235. cstr->addr = h;
  236. cstr->addr_head.a = h;
  237. cstr->port = port;
  238. cstr->addr_head.port = port;
  239. -
  240. +
  241. dptr = imsg.data;
  242. memcpy(*data, dptr + sizeof(*am), mlen - sizeof(*am));
  243. imsg_free(&imsg);
  244. @@ -364,20 +341,46 @@ priv_constraint_child(const char *pw_dir
  245. static char addr[NI_MAXHOST];
  246. struct timeval rectv, xmttv;
  247. struct sigaction sa;
  248. - void *ctx;
  249. + void *ctx = NULL;
  250. struct iovec iov[2];
  251. int i, rv;
  252. +#ifdef HAVE_OPENSSL
  253. + X509_STORE *o_store = NULL;
  254. +#endif
  255. if (setpriority(PRIO_PROCESS, 0, 0) == -1)
  256. log_warn("constraint: can't set priority for subprocess");
  257. -#ifdef HAVE_LIBTLS
  258. - /* Init TLS and load CA certs before chroot() */
  259. - if (tls_init() == -1)
  260. - fatalx("constraint: can't initialize LibreSSL engine");
  261. - if ((conf->ca = tls_load_file(tls_default_ca_cert_file(),
  262. - &conf->ca_len, NULL)) == NULL)
  263. - log_warnx("constraint: failed to load CA certificate bundle file");
  264. +/* Init TLS and load CA certs before chroot() */
  265. +#ifdef HAVE_LIBRESSL
  266. + if (strcmp("libressl", conf->constraint_engine) == 0) {
  267. + if (tls_init() == -1)
  268. + fatalx("constraint: can't initialize LibreSSL engine");
  269. + if (conf->constraint_ca_validation == 1) {
  270. + if ((conf->ca = tls_load_file(conf->constraint_ca,
  271. + &conf->ca_len, NULL)) == NULL)
  272. + log_warnx("constraint: failed to load CA certificate bundle file");
  273. + }
  274. + }
  275. +#endif
  276. +
  277. +#ifdef HAVE_OPENSSL
  278. + if (strcmp("openssl", conf->constraint_engine) == 0) {
  279. + if (OPENSSL_init_ssl(0, NULL) == 0)
  280. + fatalx("constraint: can't initialize OpenSSL engine");
  281. + //SSL_library_init();
  282. + OpenSSL_add_all_algorithms();
  283. + OpenSSL_add_all_digests();
  284. + SSL_load_error_strings();
  285. + o_store = X509_STORE_new();
  286. +
  287. + if (conf->constraint_ca_validation == 1) {
  288. + if ((conf->o_ca = X509_STORE_load_locations(o_store, conf->constraint_ca, NULL)) != 1) {
  289. + log_warnx("constraint: failed to load CA certificate bundle file");
  290. + openssl_lasterr();
  291. + }
  292. + }
  293. + }
  294. #endif
  295. if (chroot(pw_dir) == -1)
  296. @@ -420,7 +423,13 @@ priv_constraint_child(const char *pw_dir
  297. log_debug("constraint %s: setting HTTPS request", addr);
  298. setproctitle("constraint %s: new HTTPS request", addr);
  299. - (void)closefrom(CONSTRAINT_PASSFD + 1);
  300. +
  301. + /*
  302. + * OpenSSL requires new file descriptors which must not be deleted.
  303. + * This restriction does not apply to LibreSSL implementation.
  304. + */
  305. + if (strcmp("libressl", conf->constraint_engine) == 0)
  306. + (void)closefrom(CONSTRAINT_PASSFD + 1);
  307. /*
  308. * Set the close-on-exec flag to prevent leaking the communication
  309. @@ -449,14 +458,32 @@ priv_constraint_child(const char *pw_dir
  310. fatalx("constraint %s: invalid port", addr);
  311. }
  312. - /* Run! */
  313. - if ((ctx = httpsdate_query(addr,
  314. - &cstr.addr_head.port, cstr.addr_head.name, cstr.addr_head.path,
  315. - conf->ca, conf->ca_len, &rectv, &xmttv)) == NULL) {
  316. - log_debug("constraint %s: failed to get proper time results", addr);
  317. - /* Abort with failure but without warning */
  318. - exit(1);
  319. +#ifdef HAVE_LIBRESSL
  320. + if (strcmp("libressl", conf->constraint_engine) == 0) {
  321. + /* Run! */
  322. + log_debug("constraint %s: initializing HTTPS request", addr);
  323. + if ((ctx = httpsdate_query(addr,
  324. + &cstr.addr_head.port, cstr.addr_head.name, cstr.addr_head.path,
  325. + conf->ca, conf->ca_len, &rectv, &xmttv)) == NULL) {
  326. + log_debug("constraint %s: failed to get proper time results", addr);
  327. + /* Abort with failure but without warning */
  328. + exit(1);
  329. + }
  330. }
  331. +#endif
  332. +
  333. +#ifdef HAVE_OPENSSL
  334. + if (strcmp("openssl", conf->constraint_engine) == 0) {
  335. + /* Run! */
  336. + log_debug("constraint %s: initializing HTTPS request", addr);
  337. + if ((ctx = o_httpsdate_query(&cstr,
  338. + &conf->o_ca, &rectv, &xmttv)) == NULL) {
  339. + log_debug("constraint %s: failed to get proper time results", addr);
  340. + /* Abort with failure but without warning */
  341. + exit(1);
  342. + }
  343. + }
  344. +#endif
  345. iov[0].iov_base = &rectv;
  346. iov[0].iov_len = sizeof(rectv);
  347. @@ -468,8 +495,18 @@ priv_constraint_child(const char *pw_dir
  348. rv = imsg_flush(&cstr.ibuf);
  349. } while (rv == -1 && errno == EAGAIN);
  350. - /* Tear down the TLS connection after sending the result */
  351. - httpsdate_free(ctx);
  352. +/* Tear down the TLS connection after sending the result */
  353. +#ifdef HAVE_LIBRESSL
  354. + if (strcmp("libressl", conf->constraint_engine) == 0) {
  355. + httpsdate_free(ctx);
  356. + }
  357. +#endif
  358. +
  359. +#ifdef HAVE_OPENSSL
  360. + if (strcmp("openssl", conf->constraint_engine) == 0) {
  361. + o_httpsdate_free(ctx);
  362. + }
  363. +#endif
  364. exit(0);
  365. }
  366. @@ -932,270 +969,6 @@ constraint_check(double val)
  367. return (0);
  368. }
  369. -struct httpsdate *
  370. -httpsdate_init(const char *addr, const int *port, const char *hostname,
  371. - const char *path, const u_int8_t *ca, size_t ca_len)
  372. -{
  373. - struct httpsdate *httpsdate = NULL;
  374. - char port_s[sizeof(port)];
  375. -
  376. - if ((httpsdate = calloc(1, sizeof(*httpsdate))) == NULL)
  377. - goto fail;
  378. -
  379. - if (hostname == NULL)
  380. - hostname = addr;
  381. -
  382. - sprintf(port_s, "%d", *port);
  383. -
  384. - if ((httpsdate->tls_addr = strdup(addr)) == NULL ||
  385. - (httpsdate->tls_port = strdup(port_s)) == NULL ||
  386. - (httpsdate->tls_hostname = strdup(hostname)) == NULL ||
  387. - (httpsdate->tls_path = strdup(path)) == NULL)
  388. - goto fail;
  389. -
  390. - if (asprintf(&httpsdate->tls_request,
  391. - "HEAD %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",
  392. - httpsdate->tls_path, httpsdate->tls_hostname) == -1)
  393. - goto fail;
  394. -
  395. - if ((httpsdate->tls_config = tls_config_new()) == NULL)
  396. - goto fail;
  397. - if (tls_config_set_ca_mem(httpsdate->tls_config, ca, ca_len) == -1)
  398. - goto fail;
  399. -
  400. - /*
  401. - * Due to the fact that we're trying to determine a constraint for time
  402. - * we do our own certificate validity checking, since the automatic
  403. - * version is based on our wallclock, which may well be inaccurate...
  404. - */
  405. - tls_config_insecure_noverifytime(httpsdate->tls_config);
  406. -
  407. - return (httpsdate);
  408. -
  409. - fail:
  410. - httpsdate_free(httpsdate);
  411. - return (NULL);
  412. -}
  413. -
  414. -void
  415. -httpsdate_free(void *arg)
  416. -{
  417. - struct httpsdate *httpsdate = arg;
  418. - if (httpsdate == NULL)
  419. - return;
  420. - if (httpsdate->tls_ctx)
  421. - tls_close(httpsdate->tls_ctx);
  422. - tls_free(httpsdate->tls_ctx);
  423. - tls_config_free(httpsdate->tls_config);
  424. - free(httpsdate->tls_addr);
  425. - free(httpsdate->tls_port);
  426. - free(httpsdate->tls_hostname);
  427. - free(httpsdate->tls_path);
  428. - free(httpsdate->tls_request);
  429. - free(httpsdate);
  430. -}
  431. -
  432. -int
  433. -httpsdate_request(struct httpsdate *httpsdate, struct timeval *when)
  434. -{
  435. - char timebuf1[32], timebuf2[32];
  436. - size_t outlen = 0, maxlength = conf->constraint_maxheaderlength, len;
  437. - char *line, *p, *buf;
  438. - time_t httptime, notbefore, notafter;
  439. - struct tm *tm;
  440. - ssize_t ret;
  441. -
  442. - if ((httpsdate->tls_ctx = tls_client()) == NULL)
  443. - goto fail;
  444. -
  445. - if (tls_configure(httpsdate->tls_ctx, httpsdate->tls_config) == -1)
  446. - goto fail;
  447. -
  448. - /*
  449. - * libtls expects an address string, which can also be a DNS name,
  450. - * but we pass a pre-resolved IP address string in tls_addr so it
  451. - * does not trigger any DNS operation and is safe to be called
  452. - * without the dns pledge.
  453. - */
  454. - log_debug("constraint %s: establishing connection", httpsdate->tls_addr);
  455. - if (tls_connect_servername(httpsdate->tls_ctx, httpsdate->tls_addr,
  456. - httpsdate->tls_port, httpsdate->tls_hostname) == -1) {
  457. - log_debug("constraint %s: TLS connection failed (%s): %s",
  458. - httpsdate->tls_addr,
  459. - httpsdate->tls_hostname,
  460. - tls_error(httpsdate->tls_ctx)
  461. - );
  462. - goto fail;
  463. - }
  464. -
  465. - buf = httpsdate->tls_request;
  466. - len = strlen(httpsdate->tls_request);
  467. - while (len > 0) {
  468. - ret = tls_write(httpsdate->tls_ctx, buf, len);
  469. - if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
  470. - continue;
  471. - if (ret == -1) {
  472. - log_warnx("constraint %s: TLS write operation failed (%s): %s",
  473. - httpsdate->tls_addr,
  474. - httpsdate->tls_hostname,
  475. - tls_error(httpsdate->tls_ctx)
  476. - );
  477. - goto fail;
  478. - }
  479. - buf += ret;
  480. - len -= ret;
  481. - }
  482. -
  483. - while ((line = tls_readline(httpsdate->tls_ctx, &outlen,
  484. - &maxlength, when)) != NULL) {
  485. - line[strcspn(line, "\r\n")] = '\0';
  486. -
  487. - if ((p = strchr(line, ' ')) == NULL || *p == '\0')
  488. - goto next;
  489. - *p++ = '\0';
  490. - if (strcasecmp("Date:", line) != 0)
  491. - goto next;
  492. -
  493. - /*
  494. - * Expect the date/time format as IMF-fixdate which is
  495. - * mandated by HTTP/1.1 in the new RFC 7231 and was
  496. - * preferred by RFC 2616. Other formats would be RFC 850
  497. - * or ANSI C's asctime() - the latter doesn't include
  498. - * the timezone which is required here.
  499. - */
  500. - if (strptime(p, IMF_FIXDATE,
  501. - &httpsdate->tls_tm) == NULL) {
  502. - log_warnx("constraint %s: unsupported date format",
  503. - httpsdate->tls_addr
  504. - );
  505. - free(line);
  506. - return (-1);
  507. - }
  508. -
  509. - free(line);
  510. - break;
  511. - next:
  512. - free(line);
  513. - }
  514. -
  515. - /*
  516. - * Now manually check the validity of the certificate presented in the
  517. - * TLS handshake, based on the time specified by the server's HTTP Date:
  518. - * header.
  519. - */
  520. - notbefore = tls_peer_cert_notbefore(httpsdate->tls_ctx);
  521. - notafter = tls_peer_cert_notafter(httpsdate->tls_ctx);
  522. - if ((httptime = timegm(&httpsdate->tls_tm)) == -1)
  523. - goto fail;
  524. - if (httptime <= notbefore) {
  525. - if ((tm = gmtime(&notbefore)) == NULL)
  526. - goto fail;
  527. - if (strftime(timebuf1, sizeof(timebuf1), X509_DATE, tm) == 0)
  528. - goto fail;
  529. - if (strftime(timebuf2, sizeof(timebuf2), X509_DATE,
  530. - &httpsdate->tls_tm) == 0)
  531. - goto fail;
  532. - log_warnx("constraint %s: TLS certificate not yet valid (%s): "
  533. - "not before %s, now is %s", httpsdate->tls_addr,
  534. - httpsdate->tls_hostname, timebuf1, timebuf2);
  535. - goto fail;
  536. - }
  537. - if (httptime >= notafter) {
  538. - if ((tm = gmtime(&notafter)) == NULL)
  539. - goto fail;
  540. - if (strftime(timebuf1, sizeof(timebuf1), X509_DATE, tm) == 0)
  541. - goto fail;
  542. - if (strftime(timebuf2, sizeof(timebuf2), X509_DATE,
  543. - &httpsdate->tls_tm) == 0)
  544. - goto fail;
  545. - log_warnx("constraint %s: TLS certificate has been expired (%s): "
  546. - "not after %s, now is %s", httpsdate->tls_addr,
  547. - httpsdate->tls_hostname, timebuf1, timebuf2);
  548. - goto fail;
  549. - }
  550. -
  551. - return (0);
  552. -
  553. - fail:
  554. - httpsdate_free(httpsdate);
  555. - return (-1);
  556. -}
  557. -
  558. -void *
  559. -httpsdate_query(const char *addr, const int *port, const char *hostname,
  560. - const char *path, const u_int8_t *ca, size_t ca_len,
  561. - struct timeval *rectv, struct timeval *xmttv)
  562. -{
  563. - struct httpsdate *httpsdate;
  564. - struct timeval when;
  565. - time_t t;
  566. -
  567. - if ((httpsdate = httpsdate_init(addr, port, hostname, path,
  568. - ca, ca_len)) == NULL)
  569. - return (NULL);
  570. -
  571. - if (httpsdate_request(httpsdate, &when) == -1)
  572. - return (NULL);
  573. -
  574. - /* Return parsed date as local time */
  575. - t = timegm(&httpsdate->tls_tm);
  576. -
  577. - /* Report parsed Date: as "received time" */
  578. - rectv->tv_sec = t;
  579. - rectv->tv_usec = 0;
  580. -
  581. - /* And add delay as "transmit time" */
  582. - xmttv->tv_sec = when.tv_sec;
  583. - xmttv->tv_usec = when.tv_usec;
  584. -
  585. - return (httpsdate);
  586. -}
  587. -
  588. -/* Based on SSL_readline in ftp/fetch.c */
  589. -char *
  590. -tls_readline(struct tls *tls, size_t *lenp, size_t *maxlength,
  591. - struct timeval *when)
  592. -{
  593. - size_t i, len;
  594. - char *buf, *q, c;
  595. - ssize_t ret;
  596. -
  597. - len = 128;
  598. - if ((buf = malloc(len)) == NULL)
  599. - fatal("constraint: can't allocate memory for TLS transfer buffer");
  600. - for (i = 0; ; i++) {
  601. - if (i >= len - 1) {
  602. - if ((q = reallocarray(buf, len, 2)) == NULL)
  603. - fatal("constraint: can't expand TLS transfer buffer");
  604. - buf = q;
  605. - len *= 2;
  606. - }
  607. - again:
  608. - ret = tls_read(tls, &c, 1);
  609. - if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
  610. - goto again;
  611. - if (ret == -1) {
  612. - /* SSL read error, ignore */
  613. - free(buf);
  614. - return (NULL);
  615. - }
  616. -
  617. - if (maxlength != NULL && (*maxlength)-- == 0) {
  618. - log_warnx("constraint: maximum HTTP header length exceeded");
  619. - free(buf);
  620. - return (NULL);
  621. - }
  622. -
  623. - buf[i] = c;
  624. - if (c == '\n')
  625. - break;
  626. - }
  627. - *lenp = i;
  628. - if (gettimeofday(when, NULL) == -1)
  629. - fatal("constraint: can't get a valid time stamp");
  630. - return (buf);
  631. -}
  632. -
  633. char *
  634. get_string(u_int8_t *ptr, size_t len)
  635. {
  636. --- /dev/null 2020-07-26 15:23:52.401078754 +0300
  637. +++ b/src/constraint-openssl.c 2020-08-03 19:23:54.377109002 +0300
  638. @@ -0,0 +1,329 @@
  639. +/*
  640. + * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
  641. + * Copyright (c) 2020 Pekka Helenius <fincer89@hotmail.com>
  642. + *
  643. + * Permission to use, copy, modify, and distribute this software for any
  644. + * purpose with or without fee is hereby granted, provided that the above
  645. + * copyright notice and this permission notice appear in all copies.
  646. + *
  647. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  648. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  649. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  650. + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  651. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  652. + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  653. + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  654. + */
  655. +
  656. +#include <errno.h>
  657. +#include <stdio.h>
  658. +#include <stdlib.h>
  659. +#include <string.h>
  660. +#include <strings.h>
  661. +#include <time.h>
  662. +#include <sys/socket.h>
  663. +#include <unistd.h>
  664. +
  665. +#include "ntpd.h"
  666. +
  667. +struct o_httpsdate *
  668. +o_httpsdate_init(struct constraint *cstr, const int *ca)
  669. +{
  670. + struct o_httpsdate *httpsdate = NULL;
  671. +
  672. + if ((httpsdate = calloc(1, sizeof(*httpsdate))) == NULL)
  673. + goto fail;
  674. +
  675. + if ((httpsdate->cstr = cstr) == NULL)
  676. + goto fail;
  677. +
  678. + if (asprintf(&httpsdate->tls_request,
  679. + "HEAD %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",
  680. + httpsdate->cstr->addr_head.path,
  681. + httpsdate->cstr->addr_head.name) == -1)
  682. + goto fail;
  683. +
  684. + if ((httpsdate->tls_method = TLS_method()) == NULL)
  685. + goto fail;
  686. +
  687. + if ((httpsdate->tls_ctx = SSL_CTX_new(httpsdate->tls_method)) == NULL)
  688. + goto fail;
  689. +
  690. + if ((SSL_CTX_set_cipher_list(httpsdate->tls_ctx,
  691. + SSL_DEFAULT_CIPHER_LIST)) <= 0)
  692. + goto fail;
  693. +
  694. + if (*ca == 1 || conf->constraint_ca_validation == 0) {
  695. + SSL_CTX_set_verify(httpsdate->tls_ctx, SSL_VERIFY_NONE, NULL);
  696. + } else {
  697. + /*
  698. + * OpenSSL built-in procedure terminates connection in
  699. + * a case of verification failure if SSL_VERIFY_PEER
  700. + * is used on the client side with NULL value for
  701. + * verify_callback function.
  702. + * See man SSL_CTX_set_verify for details.
  703. + */
  704. + SSL_CTX_set_verify(httpsdate->tls_ctx, SSL_VERIFY_PEER, NULL);
  705. + }
  706. +
  707. + return (httpsdate);
  708. +
  709. + fail:
  710. + o_httpsdate_free(httpsdate);
  711. + return (NULL);
  712. +}
  713. +
  714. +void
  715. +o_httpsdate_free(void *arg)
  716. +{
  717. + struct o_httpsdate *httpsdate = arg;
  718. + if (httpsdate == NULL)
  719. + return;
  720. + if (httpsdate->tls_conn) {
  721. + SSL_shutdown(httpsdate->tls_conn);
  722. + SSL_free(httpsdate->tls_conn);
  723. + }
  724. + SSL_CTX_free(httpsdate->tls_ctx);
  725. + free(httpsdate->tls_request);
  726. + free(httpsdate);
  727. +}
  728. +
  729. +int
  730. +o_httpsdate_request(struct o_httpsdate *httpsdate, struct timeval *when)
  731. +{
  732. + size_t outlen = 0, maxlength = conf->constraint_max_headerlength, len;
  733. + struct sockaddr_in sa_in;
  734. + struct sockaddr_in6 *sa_in6;
  735. + struct ntp_addr *h;
  736. + char *line, *p, *buf;
  737. + int ret, sslfd = 0;
  738. + char ia_str[70]; // 33: 32-bit IPv4 + EOL :: 65: 64-bit IPv6 + EOL
  739. +
  740. + if ((httpsdate->tls_conn = SSL_new(httpsdate->tls_ctx)) == NULL)
  741. + goto fail;
  742. +
  743. + h = httpsdate->cstr->addr;
  744. +
  745. + switch (h->ss.ss_family) {
  746. +
  747. + case AF_INET:
  748. + memset(&sa_in, 0, sizeof(sa_in));
  749. + memcpy(&sa_in, (struct sockaddr_in *)&h->ss, sizeof(sa_in));
  750. +
  751. + inet_ntop(AF_INET, &sa_in.sin_addr, ia_str, sizeof(ia_str));
  752. +
  753. + if ((sslfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1)
  754. + log_warnx("constraint %s: can't create OpenSSL socket (4)", ia_str);
  755. +
  756. + SSL_set_fd(httpsdate->tls_conn, sslfd);
  757. +
  758. + log_debug("constraint %s: initializing HTTPS request", ia_str);
  759. + ret = connect(sslfd, (struct sockaddr *)&sa_in, sizeof(sa_in));
  760. + if (ret < 0) {
  761. + log_warnx("constraint %s: TLS connection failed, socket error: %d",
  762. + ia_str,
  763. + errno
  764. + );
  765. + goto fail;
  766. + }
  767. +
  768. + break;
  769. +
  770. + case AF_INET6:
  771. + memset(&sa_in6, 0, sizeof(sa_in6));
  772. + memcpy(&sa_in6, (struct sockaddr6_in *)&h->ss, sizeof(sa_in6));
  773. +
  774. + inet_ntop(AF_INET6, &sa_in6->sin6_addr, ia_str, sizeof(ia_str));
  775. +
  776. + if ((sslfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
  777. + log_warnx("constraint %s: can't create OpenSSL socket (6)",
  778. + ia_str
  779. + );
  780. +
  781. + SSL_set_fd(httpsdate->tls_conn, sslfd);
  782. +
  783. + log_debug("constraint %s: initializing HTTPS request", ia_str);
  784. + ret = connect(sslfd, (struct sockaddr *)&sa_in6, sizeof(sa_in6));
  785. + if (ret < 0) {
  786. + log_warnx("constraint %s: TLS connection failed, socket error: %d",
  787. + ia_str,
  788. + errno
  789. + );
  790. + goto fail;
  791. + }
  792. +
  793. + break;
  794. +
  795. + default:
  796. + fatalx("constraint %s: invalid network address family in HTTPS request",
  797. + ia_str
  798. + );
  799. + goto fail;
  800. + }
  801. +
  802. + log_debug("constraint %s: establishing connection", ia_str);
  803. + ret = SSL_connect(httpsdate->tls_conn);
  804. + if (ret < 1) {
  805. + log_warnx("constraint %s: TLS connection failed in accept (%s)",
  806. + ia_str,
  807. + httpsdate->cstr->addr_head.name
  808. + );
  809. + openssl_lasterr();
  810. + goto fail;
  811. + }
  812. + if (ret == 5) {
  813. + log_warnx("constraint %s: socket error no: %d", ia_str, ret);
  814. + goto fail;
  815. + }
  816. +
  817. + buf = httpsdate->tls_request;
  818. + len = strlen(httpsdate->tls_request);
  819. +
  820. + while (len > 0) {
  821. + ret = SSL_write(httpsdate->tls_conn, buf, len);
  822. + if (ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ)
  823. + continue;
  824. + if (ret < 1) {
  825. + log_warnx("constraint %s: TLS write operation failed: (%s)",
  826. + ia_str,
  827. + httpsdate->cstr->addr_head.name
  828. + );
  829. + openssl_lasterr();
  830. + goto fail;
  831. + }
  832. + if (ret == 6) {
  833. + log_warnx("constraint %s: HTTPS server aborted the request", ia_str);
  834. + openssl_lasterr();
  835. + SSL_shutdown(httpsdate->tls_conn);
  836. + }
  837. + buf += ret;
  838. + len -= ret;
  839. + }
  840. +
  841. + while ((line = o_tls_readline(httpsdate->tls_conn, &outlen,
  842. + &maxlength, when)) != NULL) {
  843. +
  844. + line[strcspn(line, "\r\n")] = '\0';
  845. +
  846. + if ((p = strchr(line, ' ')) == NULL || *p == '\0')
  847. + goto next;
  848. + *p++ = '\0';
  849. + if (strcasecmp("Date:", line) != 0)
  850. + goto next;
  851. +
  852. + /*
  853. + * Expect the date/time format as IMF-fixdate which is
  854. + * mandated by HTTP/1.1 in the new RFC 7231 and was
  855. + * preferred by RFC 2616. Other formats would be RFC 850
  856. + * or ANSI C's asctime() - the latter doesn't include
  857. + * the timezone which is required here.
  858. + */
  859. + if (strptime(p, IMF_FIXDATE,
  860. + &httpsdate->tls_tm) == NULL) {
  861. + log_warnx("constraint %s: unsupported date format",
  862. + ia_str
  863. + );
  864. + free(line);
  865. + return (-1);
  866. + }
  867. +
  868. + free(line);
  869. + break;
  870. + next:
  871. + free(line);
  872. + }
  873. +
  874. + return (0);
  875. +
  876. + fail:
  877. + close(sslfd);
  878. + o_httpsdate_free(httpsdate);
  879. + return (-1);
  880. +}
  881. +
  882. +void *
  883. +o_httpsdate_query(struct constraint *cstr, const int *ca,
  884. + struct timeval *rectv, struct timeval *xmttv)
  885. +{
  886. + struct o_httpsdate *httpsdate;
  887. + struct timeval when;
  888. + time_t t;
  889. +
  890. + if ((httpsdate = o_httpsdate_init(cstr, ca)) == NULL)
  891. + return (NULL);
  892. +
  893. + if (o_httpsdate_request(httpsdate, &when) == -1)
  894. + return (NULL);
  895. +
  896. + /* Return parsed date as local time */
  897. + t = timegm(&httpsdate->tls_tm);
  898. +
  899. + /* Report parsed Date: as "received time" */
  900. + rectv->tv_sec = t;
  901. + rectv->tv_usec = 0;
  902. +
  903. + /* And add delay as "transmit time" */
  904. + xmttv->tv_sec = when.tv_sec;
  905. + xmttv->tv_usec = when.tv_usec;
  906. +
  907. + return (httpsdate);
  908. +}
  909. +
  910. +/* Based on SSL_readline in ftp/fetch.c */
  911. +char *
  912. +o_tls_readline(SSL *tls, size_t *lenp, size_t *maxlength,
  913. + struct timeval *when)
  914. +{
  915. +
  916. + size_t i, len;
  917. + char *buf, *q, c;
  918. + ssize_t ret;
  919. +
  920. + len = 128;
  921. + if ((buf = malloc(len)) == NULL)
  922. + fatal("constraint: can't allocate memory for TLS transfer buffer");
  923. +
  924. + for (i = 0; ; i++) {
  925. + if (i >= len - 1) {
  926. + if ((q = reallocarray(buf, len, 2)) == NULL)
  927. + fatal("constraint: can't expand TLS transfer buffer");
  928. + buf = q;
  929. + len *= 2;
  930. + }
  931. + again:
  932. + ret = SSL_read(tls, &c, 1);
  933. + if (ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ)
  934. + goto again;
  935. + if (ret < 1 || ret == 6) {
  936. + /* SSL read error, ignore */
  937. + free(buf);
  938. + return (NULL);
  939. + }
  940. +
  941. + if (maxlength != NULL && (*maxlength)-- == 0) {
  942. + log_warnx("constraint: maximum HTTP header length exceeded");
  943. + free(buf);
  944. + return (NULL);
  945. + }
  946. +
  947. + buf[i] = c;
  948. + if (c == '\n')
  949. + break;
  950. + }
  951. + *lenp = i;
  952. + if (gettimeofday(when, NULL) == -1)
  953. + fatal("constraint: can't get a valid time stamp");
  954. + return (buf);
  955. +}
  956. +
  957. +void
  958. +openssl_lasterr(void)
  959. +{
  960. + unsigned long err = ERR_peek_last_error();
  961. + char buf[2048];
  962. + char *msg;
  963. +
  964. + msg = ERR_error_string(err, buf);
  965. + ERR_clear_error();
  966. + log_warnx("%s", msg);
  967. +}
  968. --- /dev/null 2020-07-26 15:23:52.401078754 +0300
  969. +++ b/src/constraint-libressl.c 2020-08-01 19:50:24.130263065 +0300
  970. @@ -0,0 +1,296 @@
  971. +/* $OpenBSD: constraint.c,v 1.35 2016/12/05 10:41:33 rzalamena Exp $ */
  972. +
  973. +/*
  974. + * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
  975. + *
  976. + * Permission to use, copy, modify, and distribute this software for any
  977. + * purpose with or without fee is hereby granted, provided that the above
  978. + * copyright notice and this permission notice appear in all copies.
  979. + *
  980. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  981. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  982. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  983. + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  984. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  985. + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  986. + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  987. + */
  988. +
  989. +#include <stdio.h>
  990. +#include <stdlib.h>
  991. +#include <string.h>
  992. +#include <strings.h>
  993. +#include <time.h>
  994. +
  995. +#include "ntpd.h"
  996. +
  997. +struct httpsdate *
  998. +httpsdate_init(const char *addr, const int *port, const char *hostname,
  999. + const char *path, const u_int8_t *ca, size_t ca_len)
  1000. +{
  1001. + struct httpsdate *httpsdate = NULL;
  1002. + char port_s[sizeof(port)];
  1003. +
  1004. + if ((httpsdate = calloc(1, sizeof(*httpsdate))) == NULL)
  1005. + goto fail;
  1006. +
  1007. + if (hostname == NULL)
  1008. + hostname = addr;
  1009. +
  1010. + sprintf(port_s, "%d", *port);
  1011. +
  1012. + if ((httpsdate->tls_addr = strdup(addr)) == NULL ||
  1013. + (httpsdate->tls_port = strdup(port_s)) == NULL ||
  1014. + (httpsdate->tls_hostname = strdup(hostname)) == NULL ||
  1015. + (httpsdate->tls_path = strdup(path)) == NULL)
  1016. + goto fail;
  1017. +
  1018. + if (asprintf(&httpsdate->tls_request,
  1019. + "HEAD %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",
  1020. + httpsdate->tls_path, httpsdate->tls_hostname) == -1)
  1021. + goto fail;
  1022. +
  1023. + if ((httpsdate->tls_config = tls_config_new()) == NULL)
  1024. + goto fail;
  1025. +
  1026. + if (ca == NULL || ca_len == 0 || conf->constraint_ca_validation == 0) {
  1027. + log_debug("constraint %s: certificate can't be verified", addr);
  1028. + tls_config_insecure_noverifycert(httpsdate->tls_config);
  1029. + } else {
  1030. + log_debug("constraint %s: verifying certificate", addr);
  1031. + if (tls_config_set_ca_mem(httpsdate->tls_config, ca, ca_len) == -1)
  1032. + goto fail;
  1033. + }
  1034. +
  1035. + /*
  1036. + * Due to the fact that we're trying to determine a constraint for time
  1037. + * we do our own certificate validity checking, since the automatic
  1038. + * version is based on our wallclock, which may well be inaccurate...
  1039. + */
  1040. + tls_config_insecure_noverifytime(httpsdate->tls_config);
  1041. +
  1042. + return (httpsdate);
  1043. +
  1044. + fail:
  1045. + httpsdate_free(httpsdate);
  1046. + return (NULL);
  1047. +}
  1048. +
  1049. +void
  1050. +httpsdate_free(void *arg)
  1051. +{
  1052. + struct httpsdate *httpsdate = arg;
  1053. + if (httpsdate == NULL)
  1054. + return;
  1055. + if (httpsdate->tls_ctx)
  1056. + tls_close(httpsdate->tls_ctx);
  1057. + tls_free(httpsdate->tls_ctx);
  1058. + tls_config_free(httpsdate->tls_config);
  1059. + free(httpsdate->tls_addr);
  1060. + free(httpsdate->tls_port);
  1061. + free(httpsdate->tls_hostname);
  1062. + free(httpsdate->tls_path);
  1063. + free(httpsdate->tls_request);
  1064. + free(httpsdate);
  1065. +}
  1066. +
  1067. +int
  1068. +httpsdate_request(struct httpsdate *httpsdate, struct timeval *when)
  1069. +{
  1070. + char timebuf1[32], timebuf2[32];
  1071. + size_t outlen = 0, maxlength = conf->constraint_max_headerlength, len;
  1072. + char *line, *p, *buf;
  1073. + time_t httptime, notbefore, notafter;
  1074. + struct tm *tm;
  1075. + ssize_t ret;
  1076. +
  1077. + if ((httpsdate->tls_ctx = tls_client()) == NULL)
  1078. + goto fail;
  1079. +
  1080. + if (tls_configure(httpsdate->tls_ctx, httpsdate->tls_config) == -1)
  1081. + goto fail;
  1082. +
  1083. + /*
  1084. + * LibreSSL expects an address string, which can also be a DNS name,
  1085. + * but we pass a pre-resolved IP address string in tls_addr so it
  1086. + * does not trigger any DNS operation and is safe to be called
  1087. + * without the dns pledge.
  1088. + */
  1089. + log_debug("constraint %s: establishing connection", httpsdate->tls_addr);
  1090. + if (tls_connect_servername(httpsdate->tls_ctx, httpsdate->tls_addr,
  1091. + httpsdate->tls_port, httpsdate->tls_hostname) == -1) {
  1092. + log_debug("constraint %s: TLS connection failed (%s): %s",
  1093. + httpsdate->tls_addr,
  1094. + httpsdate->tls_hostname,
  1095. + tls_error(httpsdate->tls_ctx)
  1096. + );
  1097. + goto fail;
  1098. + }
  1099. +
  1100. + buf = httpsdate->tls_request;
  1101. + len = strlen(httpsdate->tls_request);
  1102. + while (len > 0) {
  1103. + ret = tls_write(httpsdate->tls_ctx, buf, len);
  1104. + if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
  1105. + continue;
  1106. + if (ret == -1) {
  1107. + log_warnx("constraint %s: TLS write operation failed (%s): %s",
  1108. + httpsdate->tls_addr,
  1109. + httpsdate->tls_hostname,
  1110. + tls_error(httpsdate->tls_ctx)
  1111. + );
  1112. + goto fail;
  1113. + }
  1114. + buf += ret;
  1115. + len -= ret;
  1116. + }
  1117. +
  1118. + while ((line = tls_readline(httpsdate->tls_ctx, &outlen,
  1119. + &maxlength, when)) != NULL) {
  1120. + line[strcspn(line, "\r\n")] = '\0';
  1121. +
  1122. + if ((p = strchr(line, ' ')) == NULL || *p == '\0')
  1123. + goto next;
  1124. + *p++ = '\0';
  1125. + if (strcasecmp("Date:", line) != 0)
  1126. + goto next;
  1127. +
  1128. + /*
  1129. + * Expect the date/time format as IMF-fixdate which is
  1130. + * mandated by HTTP/1.1 in the new RFC 7231 and was
  1131. + * preferred by RFC 2616. Other formats would be RFC 850
  1132. + * or ANSI C's asctime() - the latter doesn't include
  1133. + * the timezone which is required here.
  1134. + */
  1135. + if (strptime(p, IMF_FIXDATE,
  1136. + &httpsdate->tls_tm) == NULL) {
  1137. + log_warnx("constraint %s: unsupported date format",
  1138. + httpsdate->tls_addr
  1139. + );
  1140. + free(line);
  1141. + return (-1);
  1142. + }
  1143. +
  1144. + free(line);
  1145. + break;
  1146. + next:
  1147. + free(line);
  1148. + }
  1149. +
  1150. + /*
  1151. + * Now manually check the validity of the certificate presented in the
  1152. + * TLS handshake, based on the time specified by the server's HTTP Date:
  1153. + * header.
  1154. + */
  1155. + notbefore = tls_peer_cert_notbefore(httpsdate->tls_ctx);
  1156. + notafter = tls_peer_cert_notafter(httpsdate->tls_ctx);
  1157. + if ((httptime = timegm(&httpsdate->tls_tm)) == -1)
  1158. + goto fail;
  1159. + if (httptime <= notbefore) {
  1160. + if ((tm = gmtime(&notbefore)) == NULL)
  1161. + goto fail;
  1162. + if (strftime(timebuf1, sizeof(timebuf1), X509_DATE, tm) == 0)
  1163. + goto fail;
  1164. + if (strftime(timebuf2, sizeof(timebuf2), X509_DATE,
  1165. + &httpsdate->tls_tm) == 0)
  1166. + goto fail;
  1167. + log_warnx("constraint %s: TLS certificate not yet valid (%s): "
  1168. + "not before %s, now is %s", httpsdate->tls_addr,
  1169. + httpsdate->tls_hostname, timebuf1, timebuf2);
  1170. + goto fail;
  1171. + }
  1172. + if (httptime >= notafter) {
  1173. + if ((tm = gmtime(&notafter)) == NULL)
  1174. + goto fail;
  1175. + if (strftime(timebuf1, sizeof(timebuf1), X509_DATE, tm) == 0)
  1176. + goto fail;
  1177. + if (strftime(timebuf2, sizeof(timebuf2), X509_DATE,
  1178. + &httpsdate->tls_tm) == 0)
  1179. + goto fail;
  1180. + log_warnx("constraint %s: TLS certificate has been expired (%s): "
  1181. + "not after %s, now is %s", httpsdate->tls_addr,
  1182. + httpsdate->tls_hostname, timebuf1, timebuf2);
  1183. + goto fail;
  1184. + }
  1185. +
  1186. + return (0);
  1187. +
  1188. + fail:
  1189. + httpsdate_free(httpsdate);
  1190. + return (-1);
  1191. +}
  1192. +
  1193. +void *
  1194. +httpsdate_query(const char *addr, const int *port, const char *hostname,
  1195. + const char *path, const u_int8_t *ca, size_t ca_len,
  1196. + struct timeval *rectv, struct timeval *xmttv)
  1197. +{
  1198. + struct httpsdate *httpsdate;
  1199. + struct timeval when;
  1200. + time_t t;
  1201. +
  1202. + if ((httpsdate = httpsdate_init(addr, port, hostname, path,
  1203. + ca, ca_len)) == NULL)
  1204. + return (NULL);
  1205. +
  1206. + if (httpsdate_request(httpsdate, &when) == -1)
  1207. + return (NULL);
  1208. +
  1209. + /* Return parsed date as local time */
  1210. + t = timegm(&httpsdate->tls_tm);
  1211. +
  1212. + /* Report parsed Date: as "received time" */
  1213. + rectv->tv_sec = t;
  1214. + rectv->tv_usec = 0;
  1215. +
  1216. + /* And add delay as "transmit time" */
  1217. + xmttv->tv_sec = when.tv_sec;
  1218. + xmttv->tv_usec = when.tv_usec;
  1219. +
  1220. + return (httpsdate);
  1221. +}
  1222. +
  1223. +/* Based on SSL_readline in ftp/fetch.c */
  1224. +char *
  1225. +tls_readline(struct tls *tls, size_t *lenp, size_t *maxlength,
  1226. + struct timeval *when)
  1227. +{
  1228. + size_t i, len;
  1229. + char *buf, *q, c;
  1230. + ssize_t ret;
  1231. +
  1232. + len = 128;
  1233. + if ((buf = malloc(len)) == NULL)
  1234. + fatal("constraint: can't allocate memory for TLS transfer buffer");
  1235. + for (i = 0; ; i++) {
  1236. + if (i >= len - 1) {
  1237. + if ((q = reallocarray(buf, len, 2)) == NULL)
  1238. + fatal("constraint: can't expand TLS transfer buffer");
  1239. + buf = q;
  1240. + len *= 2;
  1241. + }
  1242. + again:
  1243. + ret = tls_read(tls, &c, 1);
  1244. + if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
  1245. + goto again;
  1246. + if (ret == -1) {
  1247. + /* SSL read error, ignore */
  1248. + free(buf);
  1249. + return (NULL);
  1250. + }
  1251. +
  1252. + if (maxlength != NULL && (*maxlength)-- == 0) {
  1253. + log_warnx("constraint: maximum HTTP header length exceeded");
  1254. + free(buf);
  1255. + return (NULL);
  1256. + }
  1257. +
  1258. + buf[i] = c;
  1259. + if (c == '\n')
  1260. + break;
  1261. + }
  1262. + *lenp = i;
  1263. + if (gettimeofday(when, NULL) == -1)
  1264. + fatal("constraint: can't get a valid time stamp");
  1265. + return (buf);
  1266. +}
  1267. --- a/src/config.c 2020-08-01 11:35:05.758097319 +0300
  1268. +++ b/src/config.c 2020-08-01 19:37:13.476928898 +0300
  1269. @@ -190,9 +190,6 @@ new_constraint(void)
  1270. p->id = ++constraint_maxid;
  1271. p->fd = -1;
  1272. -#ifndef HAVE_LIBTLS
  1273. - log_warnx("constraint configured without LibreSSL support");
  1274. -#endif
  1275. return (p);
  1276. }
  1277. --- a/src/ntpd.h 2020-08-03 23:10:00.839597442 +0300
  1278. +++ b/src/ntpd.h 2020-08-03 23:25:02.978705101 +0300
  1279. @@ -31,6 +31,8 @@
  1280. #include <poll.h>
  1281. #include <imsg.h>
  1282. +#include <tls.h>
  1283. +
  1284. #include "ntp.h"
  1285. #include "log.h"
  1286. @@ -98,15 +100,29 @@
  1287. #define CONSTRAINT_SCAN_TIMEOUT (10)
  1288. #define CONSTRAINT_MARGIN (2.0*60)
  1289. -#define CONSTRAINT_MAXHEADERLENGTH 8192
  1290. +#if defined HAVE_LIBRESSL && !defined(HAVE_OPENSSL)
  1291. +#define CONSTRAINT_ENGINE "libressl"
  1292. +#elif defined HAVE_OPENSSL && !defined(HAVE_LIBRESSL)
  1293. +#define CONSTRAINT_ENGINE "openssl"
  1294. +#else
  1295. +#define CONSTRAINT_ENGINE "libressl"
  1296. +#endif
  1297. +
  1298. +#define CONSTRAINT_MAX_HEADERLENGTH 8192
  1299. #define CONSTRAINT_PASSFD (STDERR_FILENO + 1)
  1300. +#define CONSTRAINT_CA SYSCONFDIR "/ssl/cert.pem"
  1301. +#define CONSTRAINT_CA_VALIDATION 0x01;
  1302. +
  1303. #define PARENT_SOCK_FILENO CONSTRAINT_PASSFD
  1304. #define NTP_PROC_NAME "ntp_main"
  1305. #define NTPDNS_PROC_NAME "ntp_dns"
  1306. #define CONSTRAINT_PROC_NAME "constraint"
  1307. +#define IMF_FIXDATE "%a, %d %h %Y %T GMT"
  1308. +#define X509_DATE "%Y-%m-%d %T UTC"
  1309. +
  1310. enum client_state {
  1311. STATE_NONE,
  1312. STATE_DNS_INPROGRESS,
  1313. @@ -268,6 +284,7 @@ struct ntpd_conf {
  1314. u_int constraint_errors;
  1315. u_int8_t *ca;
  1316. size_t ca_len;
  1317. + int o_ca;
  1318. int tmpfail;
  1319. char *pid_file;
  1320. @@ -322,7 +339,10 @@ struct ntpd_conf {
  1321. int constraint_scan_timeout;
  1322. double constraint_margin;
  1323. - int constraint_maxheaderlength;
  1324. + char *constraint_engine;
  1325. + int constraint_max_headerlength;
  1326. + char *constraint_ca;
  1327. + u_int8_t constraint_ca_validation;
  1328. };
  1329. struct ctl_show_status {
  1330. @@ -466,6 +486,55 @@ void priv_constraint_check_child(pid_t,
  1331. char *get_string(u_int8_t *, size_t);
  1332. int intlen(int);
  1333. +#ifdef HAVE_LIBRESSL
  1334. +/* constraint.c */
  1335. +/* constraint-libressl.c */
  1336. +struct httpsdate {
  1337. + char *tls_addr;
  1338. + char *tls_port;
  1339. + char *tls_hostname;
  1340. + char *tls_path;
  1341. + char *tls_request;
  1342. + struct tls_config *tls_config;
  1343. + struct tls *tls_ctx;
  1344. + struct tm tls_tm;
  1345. +};
  1346. +
  1347. +struct httpsdate *
  1348. + httpsdate_init(const char *, const int *, const char *,
  1349. + const char *, const u_int8_t *, size_t);
  1350. +void httpsdate_free(void *);
  1351. +int httpsdate_request(struct httpsdate *, struct timeval *);
  1352. +void *httpsdate_query(const char *, const int *, const char *,
  1353. + const char *, const u_int8_t *, size_t,
  1354. + struct timeval *, struct timeval *);
  1355. +
  1356. +char *tls_readline(struct tls *, size_t *, size_t *, struct timeval *);
  1357. +#endif
  1358. +
  1359. +#ifdef HAVE_OPENSSL
  1360. +/* constraint.c */
  1361. +/* constraint-openssl.c */
  1362. +struct o_httpsdate {
  1363. + struct constraint *cstr;
  1364. + char *tls_path;
  1365. + char *tls_request;
  1366. + const SSL_METHOD *tls_method;
  1367. + SSL_CTX *tls_ctx;
  1368. + SSL *tls_conn;
  1369. + struct tm tls_tm;
  1370. +};
  1371. +
  1372. +struct o_httpsdate * o_httpsdate_init(struct constraint *, const int *);
  1373. +void o_httpsdate_free(void *);
  1374. +int o_httpsdate_request(struct o_httpsdate *, struct timeval *);
  1375. +void *o_httpsdate_query(struct constraint *,
  1376. + const int *, struct timeval *, struct timeval *);
  1377. +
  1378. +char *o_tls_readline(SSL *, size_t *, size_t *, struct timeval *);
  1379. +void openssl_lasterr(void);
  1380. +#endif
  1381. +
  1382. /* util.c */
  1383. double gettime_corrected(void);
  1384. double gettime_from_timeval(struct timeval *);
  1385. --- a/src/ntpd.c 2020-08-03 23:48:03.062564686 +0300
  1386. +++ b/src/ntpd.c 2020-08-03 23:48:23.609231373 +0300
  1387. @@ -261,6 +261,20 @@ main(int argc, char *argv[])
  1388. if (lconf.automatic)
  1389. lconf.settime = 1;
  1390. +#if __linux__
  1391. + // FIXME
  1392. + /*
  1393. + * Forcefully turn off validation check on Linux due to permission issues.
  1394. + * Use seccomp to fix this?
  1395. + * See https://lwn.net/Articles/767137/
  1396. + */
  1397. + if (conf->constraint_ca_validation == 1) {
  1398. + log_info("warning: turning off constraint certificate validation due to"
  1399. + " insufficient read permissions");
  1400. + conf->constraint_ca_validation = 0;
  1401. + }
  1402. +#endif
  1403. +
  1404. if (pname != NULL) {
  1405. /* Remove our proc arguments, so child doesn't need to. */
  1406. if (sanitize_argv(&argc0, &argv0) == -1)
  1407. @@ -334,8 +348,10 @@ main(int argc, char *argv[])
  1408. * Constraint processes are forked with certificates in memory,
  1409. * then privdrop into chroot before speaking to the outside world.
  1410. */
  1411. - if (unveil(tls_default_ca_cert_file(), "r") == -1)
  1412. - err(1, "main process: can't unveil certificate file for reading");
  1413. + if (conf->constraint_ca_validation == 1) {
  1414. + if (unveil(conf->constraint_ca, "r") == -1)
  1415. + err(1, "main process: can't unveil certificate file for reading");
  1416. + }
  1417. if (unveil("/usr/sbin/ntpd", "x") == -1)
  1418. err(1, "main process: can't unveil ntpd executable for execute operations");
  1419. if (pledge("stdio rpath inet settime proc exec id", NULL) == -1)
  1420. @@ -746,7 +762,6 @@ ctl_main(int argc, char *argv[], const s
  1421. memset(&sa, 0, sizeof(sa));
  1422. sa.sun_family = AF_UNIX;
  1423. -
  1424. if (strlcpy(sa.sun_path, sockname, sizeof(sa.sun_path)) >=
  1425. sizeof(sa.sun_path))
  1426. errx(1, "ntpctl: control socket name is too long");
  1427. --- a/src/ntp.c 2020-08-03 23:08:32.397143675 +0300
  1428. +++ b/src/ntp.c 2020-08-03 23:23:48.364816044 +0300
  1429. @@ -166,8 +166,22 @@ ntp_main(struct ntpd_conf *nconf, struct
  1430. constraint_cnt = 0;
  1431. conf->constraint_median = 0;
  1432. conf->constraint_last = getmonotime();
  1433. - TAILQ_FOREACH(cstr, &conf->constraints, entry)
  1434. - constraint_cnt += constraint_init(cstr);
  1435. +
  1436. + if (strcmp("libressl", conf->constraint_engine) == 0)
  1437. +#ifndef HAVE_LIBRESSL
  1438. + warnx("main process: OpenNTPD configured without LibreSSL support");
  1439. +#else
  1440. + TAILQ_FOREACH(cstr, &conf->constraints, entry)
  1441. + constraint_cnt += constraint_init(cstr);
  1442. +#endif
  1443. +
  1444. + if (strcmp("openssl", conf->constraint_engine) == 0)
  1445. +#ifndef HAVE_OPENSSL
  1446. + warnx("main process: OpenNTPD configured without OpenSSL support");
  1447. +#else
  1448. + TAILQ_FOREACH(cstr, &conf->constraints, entry)
  1449. + constraint_cnt += constraint_init(cstr);
  1450. +#endif
  1451. TAILQ_FOREACH(p, &conf->ntp_peers, entry)
  1452. client_peer_init(p);
  1453. --- a/src/parse.y 2020-08-03 23:11:12.796264187 +0300
  1454. +++ b/src/parse.y 2020-08-03 23:22:43.401482642 +0300
  1455. @@ -144,7 +144,10 @@ typedef struct {
  1456. %token _CONSTRAINT_SCAN_TIMEOUT
  1457. %token _CONSTRAINT_MARGIN
  1458. -%token _CONSTRAINT_MAXHEADERLENGTH
  1459. +%token _CONSTRAINT_ENGINE
  1460. +%token _CONSTRAINT_MAX_HEADERLENGTH
  1461. +%token _CONSTRAINT_CA
  1462. +%token _CONSTRAINT_CA_VALIDATION
  1463. %token <v.string> STRING
  1464. %token <v.number> NUMBER
  1465. @@ -580,8 +583,35 @@ main : LISTEN ON address listen_opts {
  1466. | _CONSTRAINT_MARGIN pos_num {
  1467. conf->constraint_margin = (double)$2.pos_num;
  1468. }
  1469. - | _CONSTRAINT_MAXHEADERLENGTH pos_num {
  1470. - conf->constraint_maxheaderlength = $2.pos_num;
  1471. + | _CONSTRAINT_MAX_HEADERLENGTH pos_num {
  1472. + conf->constraint_max_headerlength = $2.pos_num;
  1473. + }
  1474. + | _CONSTRAINT_ENGINE STRING {
  1475. + if (strcmp("libressl", $2) == 0 ||
  1476. + strcmp("openssl", $2) == 0) {
  1477. + conf->constraint_engine = $2;
  1478. + } else {
  1479. + yyerror("Invalid TLS engine specified."
  1480. + " Expected 'libressl' or 'openssl'");
  1481. + YYERROR;
  1482. + }
  1483. + }
  1484. + | _CONSTRAINT_CA STRING {
  1485. + conf->constraint_ca = $2;
  1486. + }
  1487. + | _CONSTRAINT_CA_VALIDATION STRING {
  1488. + u_int8_t val;
  1489. +
  1490. + if (strcmp("true", $2) == 0) {
  1491. + val = 0x01;
  1492. + } else if (strcmp("false", $2) == 0) {
  1493. + val = 0x00;
  1494. + } else {
  1495. + yyerror("option constraint_ca_validation expects either 'true' or 'false'");
  1496. + YYERROR;
  1497. + }
  1498. +
  1499. + conf->constraint_ca_validation = val;
  1500. }
  1501. ;
  1502. @@ -842,9 +872,12 @@ lookup(char *s)
  1503. { "auto_replies", _AUTO_REPLIES, "single" },
  1504. { "auto_threshold", _AUTO_THRESHOLD, "single" },
  1505. { "constraint", CONSTRAINT, "multiple" },
  1506. + { "constraint_ca", _CONSTRAINT_CA, "single" },
  1507. + { "constraint_ca_validation", _CONSTRAINT_CA_VALIDATION, "single" },
  1508. + { "constraint_engine", _CONSTRAINT_ENGINE, "single" },
  1509. { "constraint_error_margin", _CONSTRAINT_ERROR_MARGIN, "single" },
  1510. { "constraint_margin", _CONSTRAINT_MARGIN, "single" },
  1511. - { "constraint_maxheaderlength", _CONSTRAINT_MAXHEADERLENGTH, "single" },
  1512. + { "constraint_max_headerlength", _CONSTRAINT_MAX_HEADERLENGTH, "single" },
  1513. { "constraint_retry_interval", _CONSTRAINT_RETRY_INTERVAL, "single" },
  1514. { "constraint_scan_interval", _CONSTRAINT_SCAN_INTERVAL, "single" },
  1515. { "constraint_scan_timeout", _CONSTRAINT_SCAN_TIMEOUT, "single" },
  1516. @@ -1296,7 +1329,10 @@ init_conf(struct ntpd_conf *conf)
  1517. conf->constraint_scan_timeout = CONSTRAINT_SCAN_TIMEOUT; // 10;
  1518. conf->constraint_margin = CONSTRAINT_MARGIN; // 2.0*60;
  1519. - conf->constraint_maxheaderlength = CONSTRAINT_MAXHEADERLENGTH; // 8192;
  1520. + conf->constraint_engine = CONSTRAINT_ENGINE; // "libressl";
  1521. + conf->constraint_max_headerlength = CONSTRAINT_MAX_HEADERLENGTH; // 8192;
  1522. + conf->constraint_ca = CONSTRAINT_CA; // /etc/ssl/cert.pem;
  1523. + conf->constraint_ca_validation = CONSTRAINT_CA_VALIDATION; // false;
  1524. }
  1525. void
  1526. @@ -1366,7 +1402,16 @@ print_conf(struct ntpd_conf *lconf)
  1527. fprintf(stdout, "Constraint retry interval: %d seconds\n", conf->constraint_retry_interval);
  1528. fprintf(stdout, "Constraint scan interval: %d seconds\n", conf->constraint_scan_interval);
  1529. fprintf(stdout, "Constraint scan timeout: %d seconds\n", conf->constraint_scan_timeout);
  1530. - fprintf(stdout, "Constraint maximum HTTP header length: %d bytes\n", conf->constraint_maxheaderlength);
  1531. + fprintf(stdout, "Constraint TLS engine: %s\n", conf->constraint_engine);
  1532. + fprintf(stdout, "Constraint maximum HTTP header length: %d bytes\n", conf->constraint_max_headerlength);
  1533. + fprintf(stdout, "Constraint certificate file: %s\n", conf->constraint_ca);
  1534. +
  1535. + if ((conf->constraint_ca_validation) == 0x01)
  1536. + *boolean = "true";
  1537. + else if ((conf->constraint_ca_validation) == 0x00)
  1538. + *boolean = "false";
  1539. +
  1540. + fprintf(stdout, "Constraint certificate validation: %s\n", *boolean);
  1541. fprintf(stdout, "\n");
  1542. TAILQ_FOREACH(sens, &conf->ntp_conf_sensors, entry) {
  1543. --- a/src/ntpd.conf.5 2020-08-03 23:07:12.770476926 +0300
  1544. +++ b/src/ntpd.conf.5 2020-08-03 23:21:11.124672226 +0300
  1545. @@ -14,7 +14,7 @@
  1546. .\" AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1547. .\" OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1548. .\"
  1549. -.Dd $Mdocdate: August 02 2020 $
  1550. +.Dd $Mdocdate: August 01 2020 $
  1551. .Dt NTPD.CONF 5
  1552. .Os
  1553. .Sh NAME
  1554. @@ -235,8 +235,8 @@ invalid.
  1555. .Pp
  1556. Support for constraints is only available if
  1557. .Xr ntpd 8
  1558. -has been linked with libtls from LibreSSL. Configuring a constraint
  1559. -without libtls causes
  1560. +has been linked either with libtls from LibreSSL or with OpenSSL.
  1561. +Configuring a constraint without proper TLS library support causes
  1562. .Xr ntpd 8
  1563. to log a warning message on startup.
  1564. .Bl -tag -width Ds
  1565. @@ -292,7 +292,6 @@ adaption to system policy and flexibilit
  1566. keywords may be specified only once within the configuration file. The
  1567. following values can be changed from the highlighted defaults:
  1568. .Bl -tag -width Ds
  1569. -
  1570. .It Ic auto_replies Ar number
  1571. During OpenNTPD initialization, all NTP peers get automatic time offset value,
  1572. if pre-conditions for automatic interval adjustment are being met. The
  1573. @@ -365,6 +364,39 @@ to
  1574. 4
  1575. .El
  1576. .Ed
  1577. +.It Xo Ic constraint_ca Ar path-to-file
  1578. +.Xc
  1579. +PEM-formatted certificate bundle file for constraint HTTPS connections.
  1580. +.Bd -literal -offset indent
  1581. +.Bl -tag -width "Default:" -compact
  1582. +.It Default:
  1583. +/etc/ssl/cert.pem
  1584. +.El
  1585. +.Ed
  1586. +.It Ic constraint_ca_validation Ar true | false
  1587. +Whether to validate constraint HTTPS server certificate.
  1588. +.Bd -literal -offset indent
  1589. +.Bl -tag -width "Default:" -compact
  1590. +.It Default:
  1591. +true
  1592. +.El
  1593. +.Ed
  1594. +.It Ic constraint_engine Ar libressl | openssl
  1595. +Use either LibreSSL (
  1596. +.Ic libressl
  1597. +) or OpenSSL (
  1598. +.Ic openssl
  1599. +) for constraint HTTPS server
  1600. +connections. To support chosen TLS engine,
  1601. +.Xr ntpd 8
  1602. +must be compiled and run with proper libraries installed
  1603. +on the system. Only LibreSSL and OpenSSL are supported.
  1604. +.Bd -literal -offset indent
  1605. +.Bl -tag -width "Default:" -compact
  1606. +.It Default:
  1607. +libressl (defaults to openssl if only openssl found during compile time)
  1608. +.El
  1609. +.Ed
  1610. .It Ic constraint_error_margin Ar number
  1611. Accepted number of errors during constraint process. If error count exceeds
  1612. this value multiplied by calculated peer count, constraint connection will
  1613. @@ -385,7 +417,7 @@ margin value will be ignored.
  1614. 120
  1615. .El
  1616. .Ed
  1617. -.It Ic constraint_maxheaderlength Ar length
  1618. +.It Ic constraint_max_headerlength Ar length
  1619. Maximum allowed HTTP header length of constraint HTTPS server reply to
  1620. be fetched in bytes. If the value is exceeded during processing,
  1621. nothing is returned and constraint check fails.
  1622. --- a/src/Makefile.am 2020-07-31 23:00:40.000000000 +0300
  1623. +++ b/src/Makefile.am 2020-08-01 19:24:02.713594734 +0300
  1624. @@ -34,11 +34,17 @@ ntpd_LDADD += $(top_builddir)/compat/lib
  1625. ntpd_SOURCES = client.c
  1626. ntpd_SOURCES += config.c
  1627. -if HAVE_LIBTLS
  1628. +if HAVE_SSL
  1629. ntpd_SOURCES += constraint.c
  1630. else
  1631. ntpd_SOURCES += constraint-disabled.c
  1632. endif
  1633. +if HAVE_LIBRESSL
  1634. +ntpd_SOURCES += constraint-libressl.c
  1635. +endif
  1636. +if HAVE_OPENSSL
  1637. +ntpd_SOURCES += constraint-openssl.c
  1638. +endif
  1639. ntpd_SOURCES += control.c
  1640. ntpd_SOURCES += log.c
  1641. ntpd_SOURCES += log.h
  1642. --- a/ChangeLog 2020-07-31 23:00:40.000000000 +0300
  1643. +++ b/ChangeLog 2020-08-02 14:01:47.093664999 +0300
  1644. @@ -30,7 +30,13 @@
  1645. * Prevent the case of multiple ntpds running at once by checking presence
  1646. of the local control socket.
  1647. - * TLS certificates are now searched in TLS_CA_CERT_FILE.
  1648. + * Many previously hardcoded values are now configurable via conf file.
  1649. +
  1650. + * Implemented OpenSSL support. Either LibreSSL or OpenSSL can be used.
  1651. +
  1652. + * Improved log entries interpretation.
  1653. +
  1654. + * Updated manual.
  1655. The libtls library, as shipped with LibreSSL 3.1.0 or later, is
  1656. required to use the HTTPS constraint feature, though it is not