[Git][NTPsec/ntpsec][scanner] 4 commits: ntpd/nts_cookie.c: Remove tabs, Single line /* comments to //
Hal Murray (@hal.murray)
gitlab at mg.gitlab.com
Thu Aug 6 18:36:11 UTC 2026
Hal Murray pushed to branch scanner at NTPsec / ntpsec
Commits:
d0c7791a by Gary E. Miller at 2026-08-06T10:31:20-07:00
ntpd/nts_cookie.c: Remove tabs, Single line /* comments to //
- - - - -
76bc1031 by Gary E. Miller at 2026-08-06T10:51:10-07:00
ntpd/nts_client.c: Remove tabs, Single line /* comments to //
- - - - -
beacee22 by Gary E. Miller at 2026-08-06T11:05:53-07:00
ntpd/nts.c: Remove tabs, Single line /* comments to //
- - - - -
c281f95c by Gary E. Miller at 2026-08-06T11:34:56-07:00
ntpd/ntp_scanner.c: Remove tabs, Single line /* comments to //
No functional changes.
- - - - -
4 changed files:
- ntpd/ntp_scanner.c
- ntpd/nts.c
- ntpd/nts_client.c
- ntpd/nts_cookie.c
Changes:
=====================================
ntpd/ntp_scanner.c
=====================================
@@ -3,9 +3,9 @@
*
* The source code for a simple lexical analyzer.
*
- * Written By: Sachin Kamboj
- * University of Delaware
- * Newark, DE 19711
+ * Written By: Sachin Kamboj
+ * University of Delaware
+ * Newark, DE 19711
* Copyright Sachin Kamboj
* Copyright the NTPsec project contributors
* SPDX-License-Identifier: BSD-2-Clause
@@ -29,24 +29,24 @@
#include "ntp_scanner.h"
#include "ntp_debug.h"
#include "ntp_parser.tab.h"
-#include "timespecops.h" /* for D_ISZERO_NS() */
+#include "timespecops.h" // for D_ISZERO_NS()
-/* ntp_keyword.h declares finite state machine and token text */
+// ntp_keyword.h declares finite state machine and token text
#include "ntp_keyword.h"
-/* used to implement g and G suffixes for numeric literals in fudge offset declarations */
-#define SECONDS_IN_WEEK (unsigned long long)(7 * 24 * 60 * 60) /* 32bit systems*/
-#define GPS_ERA_10BIT (1024L * SECONDS_IN_WEEK)
-#define GPS_ERA_13BIT (8192L * SECONDS_IN_WEEK)
-#define ERA_SUFFIX(c) ((c) == 'g' || (c) == 'G')
+// used to implement g and G suffixes for numeric literals in fudge offset declarations
+#define SECONDS_IN_WEEK (unsigned long long)(7 * 24 * 60 * 60) // 32bit systems
+#define GPS_ERA_10BIT (1024L * SECONDS_IN_WEEK)
+#define GPS_ERA_13BIT (8192L * SECONDS_IN_WEEK)
+#define ERA_SUFFIX(c) ((c) == 'g' || (c) == 'G')
/* SCANNER GLOBAL VARIABLES
* ------------------------
*/
-#define MAX_LEXEME (1024 + 1) /* The maximum size of a lexeme */
-static char yytext[MAX_LEXEME]; /* Buffer for storing the input text/lexeme */
-static uint32_t conf_file_sum; /* Simple sum of characters read */
+#define MAX_LEXEME (1024 + 1) // The maximum size of a lexeme
+static char yytext[MAX_LEXEME]; // Buffer for storing the input text/lexeme
+static uint32_t conf_file_sum; // Simple sum of characters read
static struct FILE_INFO * lex_stack = NULL;
@@ -54,7 +54,7 @@ static struct FILE_INFO * lex_stack = NULL;
* --------------------
*/
#define ENDSWITH(str, suff) (strcmp(str + strlen(str) - strlen(suff), suff)==0)
-#define CONF_ENABLE(s) ENDSWITH(s, ".conf")
+#define CONF_ENABLE(s) ENDSWITH(s, ".conf")
/* SCANNER GLOBAL VARIABLES
@@ -72,29 +72,29 @@ static int is_keyword(char *lexeme, follby *pfollowedby);
/*
* keyword() - Return the keyword associated with token T_ identifier.
- * See also token_name() for the string-ized T_ identifier.
- * Example: keyword(T_Server) returns "server"
- * token_name(T_Server) returns "T_Server"
+ * See also token_name() for the string-ized T_ identifier.
+ * Example: keyword(T_Server) returns "server"
+ * token_name(T_Server) returns "T_Server"
*/
const char *
keyword(
- int token
- )
+ int token
+ )
{
- size_t i;
- const char *text;
+ size_t i;
+ const char *text;
- i = (size_t)(token - LOWEST_KEYWORD_ID);
+ i = (size_t)(token - LOWEST_KEYWORD_ID);
- if (i < COUNTOF(keyword_text)) {
- text = keyword_text[i];
- } else {
- text = NULL;
- }
+ if (i < COUNTOF(keyword_text)) {
+ text = keyword_text[i];
+ } else {
+ text = NULL;
+ }
- return (text != NULL)
- ? text
- : "(keyword not found)";
+ return (text != NULL)
+ ? text
+ : "(keyword not found)";
}
@@ -135,30 +135,30 @@ keyword(
*/
static struct FILE_INFO *
lex_open(
- const char *path,
- const char *mode
- )
+ const char *path,
+ const char *mode
+ )
{
- struct FILE_INFO *stream;
- size_t nnambuf;
-
- nnambuf = strlen(path);
- stream = emalloc_zero(sizeof(*stream) + nnambuf);
- stream->curpos.nline = 1;
- stream->backch = EOF;
- /* copy name with memcpy -- trailing NUL already there! */
- memcpy(stream->fname, path, nnambuf);
-
- if (NULL != mode) {
- stream->fpi = fopen(path, mode);
- if (NULL == stream->fpi) {
- free(stream);
- msyslog(LOG_ERR, "CONFIG: failed to open \'%s\': %s",
- path, strerror(errno));
- stream = NULL;
- }
- }
- return stream;
+ struct FILE_INFO *stream;
+ size_t nnambuf;
+
+ nnambuf = strlen(path);
+ stream = emalloc_zero(sizeof(*stream) + nnambuf);
+ stream->curpos.nline = 1;
+ stream->backch = EOF;
+ // copy name with memcpy -- trailing NUL already there!
+ memcpy(stream->fname, path, nnambuf);
+
+ if (NULL != mode) {
+ stream->fpi = fopen(path, mode);
+ if (NULL == stream->fpi) {
+ free(stream);
+ msyslog(LOG_ERR, "CONFIG: failed to open \'%s\': %s",
+ path, strerror(errno));
+ stream = NULL;
+ }
+ }
+ return stream;
}
/* get next character from buffer or file. This will return any putback
@@ -167,62 +167,62 @@ lex_open(
*/
static int
lex_getch(
- struct FILE_INFO *stream
- )
+ struct FILE_INFO *stream
+ )
{
- int ch;
-
- if (NULL == stream || stream->force_eof)
- return EOF;
-
- if (EOF != stream->backch) {
- ch = stream->backch;
- stream->backch = EOF;
- if (stream->fpi)
- conf_file_sum += (unsigned int)ch;
- } else if (stream->fpi) {
- /* fetch next 7-bit ASCII char (or EOF) from file */
- /* coverity[tainted_scalar] */
- while ((ch = fgetc(stream->fpi)) != EOF && ch > SCHAR_MAX) {
- stream->curpos.ncol++;
- }
- if (EOF != ch) {
- conf_file_sum += (unsigned int)ch;
- stream->curpos.ncol++;
- }
- } else {
- /* fetch next 7-bit ASCII char from buffer */
- const char * scan;
- scan = &remote_config.buffer[remote_config.pos];
- while ((ch = (uint8_t)*scan) > SCHAR_MAX) {
- scan++;
- stream->curpos.ncol++;
- }
- if ('\0' != ch) {
- scan++;
- stream->curpos.ncol++;
- } else {
- ch = EOF;
- }
- remote_config.pos = (int)(scan - remote_config.buffer);
- }
-
- /* If the last line ends without '\n', generate one. This
- * happens most likely on Windows, where editors often have a
- * sloppy concept of a line.
- */
- if (EOF == ch && stream->curpos.ncol != 0) {
- ch = '\n';
- }
-
- /* update scan position tallies */
- if (ch == '\n') {
- stream->bakpos = stream->curpos;
- stream->curpos.nline++;
- stream->curpos.ncol = 0;
- }
-
- return ch;
+ int ch;
+
+ if (NULL == stream || stream->force_eof)
+ return EOF;
+
+ if (EOF != stream->backch) {
+ ch = stream->backch;
+ stream->backch = EOF;
+ if (stream->fpi)
+ conf_file_sum += (unsigned int)ch;
+ } else if (stream->fpi) {
+ // fetch next 7-bit ASCII char (or EOF) from file
+ // coverity[tainted_scalar]
+ while ((ch = fgetc(stream->fpi)) != EOF && ch > SCHAR_MAX) {
+ stream->curpos.ncol++;
+ }
+ if (EOF != ch) {
+ conf_file_sum += (unsigned int)ch;
+ stream->curpos.ncol++;
+ }
+ } else {
+ // fetch next 7-bit ASCII char from buffer
+ const char * scan;
+ scan = &remote_config.buffer[remote_config.pos];
+ while ((ch = (uint8_t)*scan) > SCHAR_MAX) {
+ scan++;
+ stream->curpos.ncol++;
+ }
+ if ('\0' != ch) {
+ scan++;
+ stream->curpos.ncol++;
+ } else {
+ ch = EOF;
+ }
+ remote_config.pos = (int)(scan - remote_config.buffer);
+ }
+
+ /* If the last line ends without '\n', generate one. This
+ * happens most likely on Windows, where editors often have a
+ * sloppy concept of a line.
+ */
+ if (EOF == ch && stream->curpos.ncol != 0) {
+ ch = '\n';
+ }
+
+ // update scan position tallies
+ if (ch == '\n') {
+ stream->bakpos = stream->curpos;
+ stream->curpos.nline++;
+ stream->curpos.ncol = 0;
+ }
+
+ return ch;
}
/* Note: lex_ungetch will fail to track more than one line of push
@@ -231,29 +231,29 @@ lex_getch(
*/
static int
lex_ungetch(
- int ch,
- struct FILE_INFO *stream
- )
+ int ch,
+ struct FILE_INFO *stream
+ )
{
- /* check preconditions */
- if (NULL == stream || stream->force_eof)
- return EOF;
- if (EOF != stream->backch || EOF == ch) {
- return EOF;
- }
-
- /* keep for later reference and update checksum */
- stream->backch = (uint8_t)ch;
- if (stream->fpi)
- conf_file_sum -= (unsigned int)stream->backch;
-
- /* update position */
- if (stream->backch == '\n') {
- stream->curpos = stream->bakpos;
- stream->bakpos.ncol = -1;
- }
- stream->curpos.ncol--;
- return stream->backch;
+ // check preconditions
+ if (NULL == stream || stream->force_eof)
+ return EOF;
+ if (EOF != stream->backch || EOF == ch) {
+ return EOF;
+ }
+
+ // keep for later reference and update checksum
+ stream->backch = (uint8_t)ch;
+ if (stream->fpi)
+ conf_file_sum -= (unsigned int)stream->backch;
+
+ // update position
+ if (stream->backch == '\n') {
+ stream->curpos = stream->bakpos;
+ stream->bakpos.ncol = -1;
+ }
+ stream->curpos.ncol--;
+ return stream->backch;
}
/* dispose of an input structure. If the file pointer is not NULL, close
@@ -261,15 +261,15 @@ lex_ungetch(
*/
static void
lex_close(
- struct FILE_INFO *stream
- )
+ struct FILE_INFO *stream
+ )
{
- if (NULL != stream) {
- if (NULL != stream->fpi) {
- fclose(stream->fpi);
- }
- free(stream);
- }
+ if (NULL != stream) {
+ if (NULL != stream->fpi) {
+ fclose(stream->fpi);
+ }
+ free(stream);
+ }
}
/* INPUT STACK
@@ -287,16 +287,16 @@ lex_close(
static struct FILE_INFO *
_drop_stack_do(
- struct FILE_INFO * head
- )
+ struct FILE_INFO * head
+ )
{
- struct FILE_INFO * tail;
- while (NULL != head) {
- tail = head->st_next;
- lex_close(head);
- head = tail;
- }
- return head;
+ struct FILE_INFO * tail;
+ while (NULL != head) {
+ tail = head->st_next;
+ lex_close(head);
+ head = tail;
+ }
+ return head;
}
@@ -309,16 +309,16 @@ _drop_stack_do(
*/
bool
lex_init_stack(
- const char * path,
- const char * mode
- )
+ const char * path,
+ const char * mode
+ )
{
- if (NULL != lex_stack || NULL == path)
- return false;
+ if (NULL != lex_stack || NULL == path)
+ return false;
- //fprintf(stderr, "lex_init_stack(%s)\n", path);
- lex_stack = lex_open(path, mode);
- return (NULL != lex_stack);
+ //fprintf(stderr, "lex_init_stack(%s)\n", path);
+ lex_stack = lex_open(path, mode);
+ return (NULL != lex_stack);
}
/* This removes *all* input sources from the stack, leaving the head
@@ -331,7 +331,7 @@ lex_init_stack(
void
lex_drop_stack(void)
{
- lex_stack = _drop_stack_do(lex_stack);
+ lex_stack = _drop_stack_do(lex_stack);
}
/* Flush the lexer input stack: This will nip all input objects on the
@@ -344,43 +344,43 @@ lex_drop_stack(void)
*/
bool
lex_flush_stack(void) {
- bool retv = false;
-
- if (NULL != lex_stack) {
- retv = !lex_stack->force_eof;
- lex_stack->force_eof = true;
- lex_stack->st_next = _drop_stack_do(
- lex_stack->st_next);
- }
- return retv;
+ bool retv = false;
+
+ if (NULL != lex_stack) {
+ retv = !lex_stack->force_eof;
+ lex_stack->force_eof = true;
+ lex_stack->st_next = _drop_stack_do(
+ lex_stack->st_next);
+ }
+ return retv;
}
/* Reversed string comparison - we want to LIFO directory subfiles so they
* actually get evaluated in sort order.
*/
static int rcmpstring(const void *p1, const void *p2) {
- return strcmp(*(const char * const *)p1, *(const char * const *)p2);
+ return strcmp(*(const char * const *)p1, *(const char * const *)p2);
}
bool is_directory(const char *path) {
- struct stat sb;
- return stat(path, &sb) == 0 && S_ISDIR(sb.st_mode);
+ struct stat sb;
+ return stat(path, &sb) == 0 && S_ISDIR(sb.st_mode);
}
void reparent(char *fullpath, size_t fullpathsize,
- const char *dir, const char *base)
+ const char *dir, const char *base)
{
- fullpath[0] = '\0';
- if (base[0] != DIR_SEP) {
- char *dirpart = strdup(dir);
- char *end;
- strlcpy(fullpath, dirname(dirpart), fullpathsize-2);
- end = fullpath + strlen(fullpath);
- *end++ = DIR_SEP;
- *end++ = '\0';
- free(dirpart);
- }
- strlcat(fullpath, base, fullpathsize);
+ fullpath[0] = '\0';
+ if (base[0] != DIR_SEP) {
+ char *dirpart = strdup(dir);
+ char *end;
+ strlcpy(fullpath, dirname(dirpart), fullpathsize-2);
+ end = fullpath + strlen(fullpath);
+ *end++ = DIR_SEP;
+ *end++ = '\0';
+ free(dirpart);
+ }
+ strlcat(fullpath, base, fullpathsize);
}
/* Push another file on the parsing stack. If the mode is NULL, create a
@@ -400,40 +400,40 @@ void reparent(char *fullpath, size_t fullpathsize,
* Returns true if a new info record was pushed onto the stack.
*/
bool lex_push_file(
- const char * path
- )
+ const char * path
+ )
{
- struct FILE_INFO * next = NULL;
-
- if (NULL != path) {
- char fullpath[PATH_MAX];
- if (lex_stack != NULL) {
- reparent(fullpath, sizeof(fullpath), lex_stack->fname, path);
- } else {
- strlcpy(fullpath, path, sizeof(fullpath));
- }
- //fprintf(stderr, "lex_push_file(%s)\n", fullpath);
- if (is_directory(fullpath)) {
- /* directory scanning */
- DIR *dfd;
- struct dirent *dp;
- char **baselist;
- int basecount = 0;
- if ((dfd = opendir(fullpath)) == NULL)
- return false;
- baselist = (char **)malloc(sizeof(char *));
- if (NULL == baselist) {
- msyslog(LOG_ERR,
+ struct FILE_INFO * next = NULL;
+
+ if (NULL != path) {
+ char fullpath[PATH_MAX];
+ if (lex_stack != NULL) {
+ reparent(fullpath, sizeof(fullpath), lex_stack->fname, path);
+ } else {
+ strlcpy(fullpath, path, sizeof(fullpath));
+ }
+ //fprintf(stderr, "lex_push_file(%s)\n", fullpath);
+ if (is_directory(fullpath)) {
+ // directory scanning
+ DIR *dfd;
+ struct dirent *dp;
+ char **baselist;
+ int basecount = 0;
+ if ((dfd = opendir(fullpath)) == NULL)
+ return false;
+ baselist = (char **)malloc(sizeof(char *));
+ if (NULL == baselist) {
+ msyslog(LOG_ERR,
"CONFIG: lex_push_file: NULL from malloc");
- exit(3);
- }
- while ((dp = readdir(dfd)) != NULL)
- {
- if (!CONF_ENABLE(dp->d_name)) {
- continue;
- }
- baselist[basecount++] = strdup(dp->d_name);
- baselist = realloc(baselist,
+ exit(3);
+ }
+ while ((dp = readdir(dfd)) != NULL)
+ {
+ if (!CONF_ENABLE(dp->d_name)) {
+ continue;
+ }
+ baselist[basecount++] = strdup(dp->d_name);
+ baselist = realloc(baselist,
(size_t)(basecount+1) * sizeof(char *));
if (NULL == baselist) {
msyslog(LOG_ERR,
@@ -441,43 +441,43 @@ bool lex_push_file(
"NULL from realloc");
exit(3);
}
- }
- closedir(dfd);
- qsort(baselist, (size_t)basecount, sizeof(char *),
+ }
+ closedir(dfd);
+ qsort(baselist, (size_t)basecount, sizeof(char *),
rcmpstring);
- for (int i = 0; i < basecount; i++) {
- char subpath[PATH_MAX];
- size_t pathlen = strlcpy(subpath, fullpath, PATH_MAX);
- if ((pathlen < PATH_MAX - 1) &&
- (subpath[pathlen -1] != DIR_SEP)
- ) {
- char *ep = subpath + strlen(subpath);
- *ep++ = DIR_SEP;
- *ep = '\0';
- }
- strlcat(subpath, baselist[i], PATH_MAX);
- /* This should barf safely if the complete
- * filename was too long to fit in the buffer.
- */
- msyslog(LOG_NOTICE,
- "CONFIG: opening <%s> from dir <%s>",
- subpath, fullpath);
- lex_push_file(subpath);
- }
- for (int i = 0; i < basecount; i++) {
- free(baselist[i]);
- }
- free(baselist);
- return basecount > 0;
- } else {
- next = lex_open(fullpath, "r");
- if (NULL != next) {
- next->st_next = lex_stack;
- lex_stack = next;
- }
- }
- }
- return (NULL != next);
+ for (int i = 0; i < basecount; i++) {
+ char subpath[PATH_MAX];
+ size_t pathlen = strlcpy(subpath, fullpath, PATH_MAX);
+ if ((pathlen < PATH_MAX - 1) &&
+ (subpath[pathlen -1] != DIR_SEP)
+ ) {
+ char *ep = subpath + strlen(subpath);
+ *ep++ = DIR_SEP;
+ *ep = '\0';
+ }
+ strlcat(subpath, baselist[i], PATH_MAX);
+ /* This should barf safely if the complete
+ * filename was too long to fit in the buffer.
+ */
+ msyslog(LOG_NOTICE,
+ "CONFIG: opening <%s> from dir <%s>",
+ subpath, fullpath);
+ lex_push_file(subpath);
+ }
+ for (int i = 0; i < basecount; i++) {
+ free(baselist[i]);
+ }
+ free(baselist);
+ return basecount > 0;
+ } else {
+ next = lex_open(fullpath, "r");
+ if (NULL != next) {
+ next->st_next = lex_stack;
+ lex_stack = next;
+ }
+ }
+ }
+ return (NULL != next);
}
/* Pop, close & free the top of the include stack, unless the stack
@@ -490,17 +490,17 @@ bool lex_push_file(
bool
lex_pop_file(void)
{
- struct FILE_INFO * head = lex_stack;
- struct FILE_INFO * tail = NULL;
-
- if (NULL != head) {
- tail = head->st_next;
- if (NULL != tail) {
- lex_stack = tail;
- lex_close(head);
- }
- }
- return (NULL != tail);
+ struct FILE_INFO * head = lex_stack;
+ struct FILE_INFO * tail = NULL;
+
+ if (NULL != head) {
+ tail = head->st_next;
+ if (NULL != tail) {
+ lex_stack = tail;
+ lex_close(head);
+ }
+ }
+ return (NULL != tail);
}
/* Get include nesting level. This currently loops over the stack and
@@ -516,30 +516,30 @@ lex_pop_file(void)
size_t
lex_level(void)
{
- size_t cnt = 0;
- struct FILE_INFO *ipf = lex_stack;
-
- while (NULL != ipf) {
- cnt++;
- ipf = ipf->st_next;
- }
- return cnt;
+ size_t cnt = 0;
+ struct FILE_INFO *ipf = lex_stack;
+
+ while (NULL != ipf) {
+ cnt++;
+ ipf = ipf->st_next;
+ }
+ return cnt;
}
-/* check if the current input is from a file */
+// check if the current input is from a file
bool
lex_from_file(void)
{
- return (NULL != lex_stack) && (NULL != lex_stack->fpi);
+ return (NULL != lex_stack) && (NULL != lex_stack->fpi);
}
struct FILE_INFO *
lex_current(void)
{
- /* this became so simple, it could be a macro. But then,
- * lex_stack needed to be global...
- */
- return lex_stack;
+ /* this became so simple, it could be a macro. But then,
+ * lex_stack needed to be global...
+ */
+ return lex_stack;
}
@@ -547,239 +547,239 @@ lex_current(void)
* --------------
*/
-/* Keywords */
+// Keywords
static int
is_keyword(
- char *lexeme,
- follby *pfollowedby
- )
+ char *lexeme,
+ follby *pfollowedby
+ )
{
- follby fb;
- int curr_s; /* current state index */
- int token;
-
- curr_s = SCANNER_INIT_S;
- token = 0;
-
- for (int i = 0; lexeme[i]; i++) {
- while (curr_s && (lexeme[i] != SS_CH(sst[curr_s])))
- curr_s = (int)SS_OTHER_N(sst[curr_s]);
-
- if (curr_s && (lexeme[i] == SS_CH(sst[curr_s]))) {
- if ('\0' == lexeme[i + 1]
- && FOLLBY_NON_ACCEPTING
- != SS_FB(sst[curr_s])) {
- fb = SS_FB(sst[curr_s]);
- *pfollowedby = fb;
- token = curr_s;
- break;
- }
- curr_s = SS_MATCH_N(sst[curr_s]);
- } else
- break;
- }
-
- return token;
+ follby fb;
+ int curr_s; // current state index
+ int token;
+
+ curr_s = SCANNER_INIT_S;
+ token = 0;
+
+ for (int i = 0; lexeme[i]; i++) {
+ while (curr_s && (lexeme[i] != SS_CH(sst[curr_s])))
+ curr_s = (int)SS_OTHER_N(sst[curr_s]);
+
+ if (curr_s && (lexeme[i] == SS_CH(sst[curr_s]))) {
+ if ('\0' == lexeme[i + 1]
+ && FOLLBY_NON_ACCEPTING
+ != SS_FB(sst[curr_s])) {
+ fb = SS_FB(sst[curr_s]);
+ *pfollowedby = fb;
+ token = curr_s;
+ break;
+ }
+ curr_s = SS_MATCH_N(sst[curr_s]);
+ } else
+ break;
+ }
+
+ return token;
}
-/* Integer */
+// Integer
static int
is_integer(
- char *lexeme
- )
+ char *lexeme
+ )
{
- int i;
- int is_neg;
- unsigned int u_val;
-
- i = 0;
-
- /* Allow a leading minus sign */
- if (lexeme[i] == '-') {
- i++;
- is_neg = true;
- } else {
- is_neg = false;
- }
-
- /* Check that all the remaining characters are digits */
- for (; lexeme[i] != '\0'; i++) {
- if (!isdigit((uint8_t)lexeme[i]))
- return false;
- }
-
- if (is_neg)
- return true;
-
- /* Reject numbers that fit in unsigned but not in signed int */
- if (1 == sscanf(lexeme, "%u", &u_val)) {
- return (u_val <= INT_MAX);
- } else {
- return false;
- }
+ int i;
+ int is_neg;
+ unsigned int u_val;
+
+ i = 0;
+
+ // Allow a leading minus sign
+ if (lexeme[i] == '-') {
+ i++;
+ is_neg = true;
+ } else {
+ is_neg = false;
+ }
+
+ // Check that all the remaining characters are digits
+ for (; lexeme[i] != '\0'; i++) {
+ if (!isdigit((uint8_t)lexeme[i]))
+ return false;
+ }
+
+ if (is_neg)
+ return true;
+
+ // Reject numbers that fit in unsigned but not in signed int
+ if (1 == sscanf(lexeme, "%u", &u_val)) {
+ return (u_val <= INT_MAX);
+ } else {
+ return false;
+ }
}
-/* unsigned int -- assumes is_integer() has returned false */
+// unsigned int -- assumes is_integer() has returned false
static int
is_u_int(
- char *lexeme
- )
+ char *lexeme
+ )
{
- int i;
- int is_hex;
-
- i = 0;
- if ('0' == lexeme[i] && 'x' == tolower((uint8_t)lexeme[i + 1])) {
- i += 2;
- is_hex = true;
- } else {
- is_hex = false;
- }
-
- /* Check that all the remaining characters are digits */
- for (; lexeme[i] != '\0'; i++) {
- if (is_hex && !isxdigit((uint8_t)lexeme[i]))
- return false;
- if (!is_hex && !isdigit((uint8_t)lexeme[i]))
- return false;
- }
-
- return true;
+ int i;
+ int is_hex;
+
+ i = 0;
+ if ('0' == lexeme[i] && 'x' == tolower((uint8_t)lexeme[i + 1])) {
+ i += 2;
+ is_hex = true;
+ } else {
+ is_hex = false;
+ }
+
+ // Check that all the remaining characters are digits
+ for (; lexeme[i] != '\0'; i++) {
+ if (is_hex && !isxdigit((uint8_t)lexeme[i]))
+ return false;
+ if (!is_hex && !isdigit((uint8_t)lexeme[i]))
+ return false;
+ }
+
+ return true;
}
-/* Double */
+// Double
static bool
is_double(
- char *lexeme
- )
+ char *lexeme
+ )
{
- unsigned int num_digits = 0; /* Number of digits read */
- unsigned int i;
-
- i = 0;
-
- /* Check for an optional '+' or '-' */
- if ('+' == lexeme[i] || '-' == lexeme[i]) {
- i++;
- }
-
- /* Read the integer part */
- for (; lexeme[i] && isdigit((uint8_t)lexeme[i]); i++)
- num_digits++;
-
- /* Check for the optional decimal point */
- if ('.' == lexeme[i]) {
- i++;
- /* Check for any digits after the decimal point */
- for (; lexeme[i] && isdigit((uint8_t)lexeme[i]); i++)
- num_digits++;
- }
-
- /*
- * The number of digits in both the decimal part and the
- * fraction part must not be zero at this point
- */
- if (!num_digits)
- return false;
-
- /* Check if we are done */
- if (!lexeme[i])
- return true;
-
- /* There is still more input, read the exponent */
- if ('e' == tolower((uint8_t)lexeme[i])) {
- i++;
-
- /* Read an optional Sign */
- if ('+' == lexeme[i] || '-' == lexeme[i]) {
- i++;
- }
-
- /* Now read the exponent part */
- while (lexeme[i] && isdigit((uint8_t)lexeme[i]))
- i++;
-
- }
-
- /* Allow trailing multipliers */
- while (lexeme[i] && ERA_SUFFIX(lexeme[i])) {
- i++;
- }
-
- /* Check if we are done */
- if (!lexeme[i])
- return true;
- else
- return false;
+ unsigned int num_digits = 0; // Number of digits read
+ unsigned int i;
+
+ i = 0;
+
+ // Check for an optional '+' or '-'
+ if ('+' == lexeme[i] || '-' == lexeme[i]) {
+ i++;
+ }
+
+ // Read the integer part
+ for (; lexeme[i] && isdigit((uint8_t)lexeme[i]); i++)
+ num_digits++;
+
+ // Check for the optional decimal point
+ if ('.' == lexeme[i]) {
+ i++;
+ // Check for any digits after the decimal point
+ for (; lexeme[i] && isdigit((uint8_t)lexeme[i]); i++)
+ num_digits++;
+ }
+
+ /*
+ * The number of digits in both the decimal part and the
+ * fraction part must not be zero at this point
+ */
+ if (!num_digits)
+ return false;
+
+ // Check if we are done
+ if (!lexeme[i])
+ return true;
+
+ // There is still more input, read the exponent
+ if ('e' == tolower((uint8_t)lexeme[i])) {
+ i++;
+
+ // Read an optional Sign
+ if ('+' == lexeme[i] || '-' == lexeme[i]) {
+ i++;
+ }
+
+ // Now read the exponent part
+ while (lexeme[i] && isdigit((uint8_t)lexeme[i]))
+ i++;
+
+ }
+
+ // Allow trailing multipliers
+ while (lexeme[i] && ERA_SUFFIX(lexeme[i])) {
+ i++;
+ }
+
+ // Check if we are done
+ if (!lexeme[i])
+ return true;
+ else
+ return false;
}
-/* is_special() - Test whether a character is a token */
+// is_special() - Test whether a character is a token
static inline bool
is_special(
- int ch
- )
+ int ch
+ )
{
- return strchr(special_chars, ch) != NULL;
+ return strchr(special_chars, ch) != NULL;
}
static bool
is_EOC(
- int ch
- )
+ int ch
+ )
{
- if ( ch == '\n')
- return true;
- return false;
+ if ( ch == '\n')
+ return true;
+ return false;
}
char *
quote_if_needed(char *str) {
- char *ret;
- size_t len;
- size_t octets;
-
- len = strlen(str);
- octets = len + 2 + 1;
- ret = emalloc(octets);
- if ('"' != str[0]
- && (strcspn(str, special_chars) < len
- || strchr(str, ' ') != NULL)) {
- snprintf(ret, octets, "\"%s\"", str);
- } else {
- strlcpy(ret, str, octets);
- }
-
- return ret;
+ char *ret;
+ size_t len;
+ size_t octets;
+
+ len = strlen(str);
+ octets = len + 2 + 1;
+ ret = emalloc(octets);
+ if ('"' != str[0]
+ && (strcspn(str, special_chars) < len
+ || strchr(str, ' ') != NULL)) {
+ snprintf(ret, octets, "\"%s\"", str);
+ } else {
+ strlcpy(ret, str, octets);
+ }
+
+ return ret;
}
static int
create_string_token(
- char *lexeme
- )
+ char *lexeme
+ )
{
- char *pch;
-
- /*
- * ignore end of line whitespace
- */
- pch = lexeme;
- while (*pch && isspace((uint8_t)*pch))
- pch++;
-
- if (!*pch) {
- yylval.Integer = T_EOC;
- return yylval.Integer;
- }
-
- yylval.String = estrdup(lexeme);
- return T_String;
+ char *pch;
+
+ /*
+ * ignore end of line whitespace
+ */
+ pch = lexeme;
+ while (*pch && isspace((uint8_t)*pch))
+ pch++;
+
+ if (!*pch) {
+ yylval.Integer = T_EOC;
+ return yylval.Integer;
+ }
+
+ yylval.String = estrdup(lexeme);
+ return T_String;
}
@@ -793,277 +793,277 @@ create_string_token(
int
yylex(void)
{
- static follby followedby = FOLLBY_TOKEN;
- int i;
- bool instring;
- bool yylval_was_set;
- int converted;
- int token; /* The return value */
- int ch;
-
- instring = false;
- yylval_was_set = false;
-
- do {
- /* Ignore whitespace at the beginning */
- while (EOF != (ch = lex_getch(lex_stack)) &&
- isspace(ch) &&
- !is_EOC(ch))
-
- ; /* Null Statement */
-
- if (EOF == ch) {
-
- if ( ! lex_pop_file())
- return 0;
- token = T_EOC;
- goto normal_return;
-
- } else if (is_EOC(ch)) {
-
- /* end FOLLBY_STRINGS_TO_EOC effect */
- followedby = FOLLBY_TOKEN;
- token = T_EOC;
- goto normal_return;
-
- } else if (is_special(ch) && FOLLBY_TOKEN == followedby) {
- /* special chars are their own token values */
- token = ch;
- /*
- * '=' outside simulator configuration implies
- * a single string following as in:
- * setvar Owner = "The Boss" default
- */
- if ('=' == ch ) {
- followedby = FOLLBY_STRING;
- }
- yytext[0] = (char)ch;
- yytext[1] = '\0';
- goto normal_return;
- } else
- lex_ungetch(ch, lex_stack);
-
- /* save the position of start of the token */
- lex_stack->tokpos = lex_stack->curpos;
-
- /* Read in the lexeme */
- i = 0;
- while (EOF != (ch = lex_getch(lex_stack))) {
-
- yytext[i] = (char)ch;
-
- /* Break on whitespace or a special character */
- if (isspace(ch) || is_EOC(ch)
- || '"' == ch
- || (FOLLBY_TOKEN == followedby
- && is_special(ch)))
- break;
-
- /* Read the rest of the line on reading a start
- of comment character */
- if ('#' == ch) {
- while (EOF != (ch = lex_getch(lex_stack))
- && '\n' != ch) {
- ; /* Null Statement */
- }
- break;
- }
-
- i++;
- if (i >= (int)COUNTOF(yytext)) {
- goto lex_too_long;
- }
- }
- /* Pick up all of the string inside between " marks, to
- * end of line. If we make it to EOL without a
- * terminating " assume it for them.
- *
- * XXX - HMS: I'm not sure we want to assume the closing "
- */
- if ('"' == ch) {
- instring = true;
- while (EOF != (ch = lex_getch(lex_stack)) &&
- ch != '"' && ch != '\n') {
- yytext[i++] = (char)ch;
- if (i >= (int)COUNTOF(yytext)) {
- goto lex_too_long;
- }
- }
- /*
- * yytext[i] will be pushed back as not part of
- * this lexeme, but any closing quote should
- * not be pushed back, so we read another char.
- */
- if ('"' == ch) {
- ch = lex_getch(lex_stack);
- }
- }
- /* Pushback the last character read that is not a part
- * of this lexeme. This fails silently if ch is EOF,
- * but then the EOF condition persists and is handled on
- * the next turn by the include stack mechanism.
- */
- lex_ungetch(ch, lex_stack);
-
- yytext[i] = '\0';
- } while (i == 0);
-
- /* Now return the desired token */
-
- /* First make sure that the parser is *not* expecting a string
- * as the next token (based on the previous token that was
- * returned) and that we haven't read a string.
- */
-
- if (followedby == FOLLBY_TOKEN && !instring) {
- token = is_keyword(yytext, &followedby);
- if (token) {
- goto normal_return;
- } else if (is_integer(yytext)) {
- yylval_was_set = true;
- errno = 0;
- yylval.Integer = (int)strtol(yytext, NULL, 10);
- if (yylval.Integer == 0
- && ((errno == EINVAL) || (errno == ERANGE))) {
- msyslog(LOG_ERR,
- "CONFIG: Integer cannot be represented: %s",
- yytext);
- if (lex_from_file()) {
- exit(1);
- } else {
- /* force end of parsing */
- yylval.Integer = 0;
- return 0;
- }
- }
- token = T_Integer;
- goto normal_return;
- } else if (is_u_int(yytext)) {
- yylval_was_set = true;
- if ('0' == yytext[0] &&
- 'x' == tolower((int)yytext[1]))
- converted = sscanf(&yytext[2], "%x",
- &yylval.U_int);
- else
- converted = sscanf(yytext, "%u",
- &yylval.U_int);
- if (1 != converted) {
- msyslog(LOG_ERR,
- "CONFIG: U_int cannot be represented: %s",
- yytext);
- if (lex_from_file()) {
- exit(1);
- } else {
- /* force end of parsing */
- yylval.Integer = 0;
- return 0;
- }
- }
- token = T_U_int;
- goto normal_return;
- } else if (is_double(yytext)) {
- double era_offset = 0;
- yylval_was_set = true;
- errno = 0;
- while (ERA_SUFFIX(yytext[strlen(yytext)-1])) {
- if (yytext[strlen(yytext)-1] == 'g') {
- era_offset += GPS_ERA_10BIT;
- }
- if (yytext[strlen(yytext)-1] == 'G') {
- era_offset += GPS_ERA_13BIT;
- }
- yytext[strlen(yytext)-1] = '\0';
- }
- yylval.Double = era_offset + atof(yytext);
- if ( D_ISZERO_NS(yylval.Double) && errno == ERANGE) {
- /* FIXME, POSIX says atof() never returns errors */
- msyslog(LOG_ERR,
- "CONFIG: Double too large to represent: %s",
- yytext);
- exit(1);
- } else {
- token = T_Double;
- goto normal_return;
- }
- } else {
- /* Default: Everything is a string */
- yylval_was_set = true;
- token = create_string_token(yytext);
- goto normal_return;
- }
- }
-
- /*
- * Either followedby is not FOLLBY_TOKEN or this lexeme is part
- * of a string. Hence, we need to return T_String.
- *
- * _Except_ we might have a -4 or -6 flag on a an association
- * configuration line (server, peer, pool, etc.).
- *
- * This is a terrible hack, but the grammar is ambiguous so we
- * don't have a choice. [SK]
- *
- * The ambiguity is in the keyword scanner, not ntp_parser.y.
- * We do not require server addresses be quoted in ntp.conf,
- * complicating the scanner's job. To avoid trying (and
- * failing) to match an IP address or DNS name to a keyword,
- * the association keywords use FOLLBY_STRING in the keyword
- * table, which tells the scanner to force the next token to be
- * a T_String, so it does not try to match a keyword but rather
- * expects a string when -4/-6 modifiers to server, peer, etc.
- * are encountered.
- * restrict -4 and restrict -6 parsing works correctly without
- * this hack, as restrict uses FOLLBY_TOKEN. [DH]
- */
- if ('-' == yytext[0]) {
- if ('4' == yytext[1]) {
- token = T_Ipv4_flag;
- goto normal_return;
- } else if ('6' == yytext[1]) {
- token = T_Ipv6_flag;
- goto normal_return;
- }
- }
-
- instring = false;
- if (FOLLBY_STRING == followedby) {
- followedby = FOLLBY_TOKEN;
- }
-
- yylval_was_set = true;
- token = create_string_token(yytext);
+ static follby followedby = FOLLBY_TOKEN;
+ int i;
+ bool instring;
+ bool yylval_was_set;
+ int converted;
+ int token; // The return value
+ int ch;
+
+ instring = false;
+ yylval_was_set = false;
+
+ do {
+ // Ignore whitespace at the beginning
+ while (EOF != (ch = lex_getch(lex_stack)) &&
+ isspace(ch) &&
+ !is_EOC(ch))
+
+ ; // Null Statement
+
+ if (EOF == ch) {
+
+ if ( ! lex_pop_file())
+ return 0;
+ token = T_EOC;
+ goto normal_return;
+
+ } else if (is_EOC(ch)) {
+
+ // end FOLLBY_STRINGS_TO_EOC effect
+ followedby = FOLLBY_TOKEN;
+ token = T_EOC;
+ goto normal_return;
+
+ } else if (is_special(ch) && FOLLBY_TOKEN == followedby) {
+ // special chars are their own token values
+ token = ch;
+ /*
+ * '=' outside simulator configuration implies
+ * a single string following as in:
+ * setvar Owner = "The Boss" default
+ */
+ if ('=' == ch ) {
+ followedby = FOLLBY_STRING;
+ }
+ yytext[0] = (char)ch;
+ yytext[1] = '\0';
+ goto normal_return;
+ } else
+ lex_ungetch(ch, lex_stack);
+
+ // save the position of start of the token
+ lex_stack->tokpos = lex_stack->curpos;
+
+ // Read in the lexeme
+ i = 0;
+ while (EOF != (ch = lex_getch(lex_stack))) {
+
+ yytext[i] = (char)ch;
+
+ // Break on whitespace or a special character
+ if (isspace(ch) || is_EOC(ch)
+ || '"' == ch
+ || (FOLLBY_TOKEN == followedby
+ && is_special(ch)))
+ break;
+
+ /* Read the rest of the line on reading a start
+ of comment character */
+ if ('#' == ch) {
+ while (EOF != (ch = lex_getch(lex_stack))
+ && '\n' != ch) {
+ ; // Null Statement
+ }
+ break;
+ }
+
+ i++;
+ if (i >= (int)COUNTOF(yytext)) {
+ goto lex_too_long;
+ }
+ }
+ /* Pick up all of the string inside between " marks, to
+ * end of line. If we make it to EOL without a
+ * terminating " assume it for them.
+ *
+ * XXX - HMS: I'm not sure we want to assume the closing "
+ */
+ if ('"' == ch) {
+ instring = true;
+ while (EOF != (ch = lex_getch(lex_stack)) &&
+ ch != '"' && ch != '\n') {
+ yytext[i++] = (char)ch;
+ if (i >= (int)COUNTOF(yytext)) {
+ goto lex_too_long;
+ }
+ }
+ /*
+ * yytext[i] will be pushed back as not part of
+ * this lexeme, but any closing quote should
+ * not be pushed back, so we read another char.
+ */
+ if ('"' == ch) {
+ ch = lex_getch(lex_stack);
+ }
+ }
+ /* Pushback the last character read that is not a part
+ * of this lexeme. This fails silently if ch is EOF,
+ * but then the EOF condition persists and is handled on
+ * the next turn by the include stack mechanism.
+ */
+ lex_ungetch(ch, lex_stack);
+
+ yytext[i] = '\0';
+ } while (i == 0);
+
+ // Now return the desired token
+
+ /* First make sure that the parser is *not* expecting a string
+ * as the next token (based on the previous token that was
+ * returned) and that we haven't read a string.
+ */
+
+ if (followedby == FOLLBY_TOKEN && !instring) {
+ token = is_keyword(yytext, &followedby);
+ if (token) {
+ goto normal_return;
+ } else if (is_integer(yytext)) {
+ yylval_was_set = true;
+ errno = 0;
+ yylval.Integer = (int)strtol(yytext, NULL, 10);
+ if (yylval.Integer == 0
+ && ((errno == EINVAL) || (errno == ERANGE))) {
+ msyslog(LOG_ERR,
+ "CONFIG: Integer cannot be represented: %s",
+ yytext);
+ if (lex_from_file()) {
+ exit(1);
+ } else {
+ // force end of parsing
+ yylval.Integer = 0;
+ return 0;
+ }
+ }
+ token = T_Integer;
+ goto normal_return;
+ } else if (is_u_int(yytext)) {
+ yylval_was_set = true;
+ if ('0' == yytext[0] &&
+ 'x' == tolower((int)yytext[1]))
+ converted = sscanf(&yytext[2], "%x",
+ &yylval.U_int);
+ else
+ converted = sscanf(yytext, "%u",
+ &yylval.U_int);
+ if (1 != converted) {
+ msyslog(LOG_ERR,
+ "CONFIG: U_int cannot be represented: %s",
+ yytext);
+ if (lex_from_file()) {
+ exit(1);
+ } else {
+ // force end of parsing
+ yylval.Integer = 0;
+ return 0;
+ }
+ }
+ token = T_U_int;
+ goto normal_return;
+ } else if (is_double(yytext)) {
+ double era_offset = 0;
+ yylval_was_set = true;
+ errno = 0;
+ while (ERA_SUFFIX(yytext[strlen(yytext)-1])) {
+ if (yytext[strlen(yytext)-1] == 'g') {
+ era_offset += GPS_ERA_10BIT;
+ }
+ if (yytext[strlen(yytext)-1] == 'G') {
+ era_offset += GPS_ERA_13BIT;
+ }
+ yytext[strlen(yytext)-1] = '\0';
+ }
+ yylval.Double = era_offset + atof(yytext);
+ if ( D_ISZERO_NS(yylval.Double) && errno == ERANGE) {
+ // FIXME, POSIX says atof() never returns errors
+ msyslog(LOG_ERR,
+ "CONFIG: Double too large to represent: %s",
+ yytext);
+ exit(1);
+ } else {
+ token = T_Double;
+ goto normal_return;
+ }
+ } else {
+ // Default: Everything is a string
+ yylval_was_set = true;
+ token = create_string_token(yytext);
+ goto normal_return;
+ }
+ }
+
+ /*
+ * Either followedby is not FOLLBY_TOKEN or this lexeme is part
+ * of a string. Hence, we need to return T_String.
+ *
+ * _Except_ we might have a -4 or -6 flag on a an association
+ * configuration line (server, peer, pool, etc.).
+ *
+ * This is a terrible hack, but the grammar is ambiguous so we
+ * don't have a choice. [SK]
+ *
+ * The ambiguity is in the keyword scanner, not ntp_parser.y.
+ * We do not require server addresses be quoted in ntp.conf,
+ * complicating the scanner's job. To avoid trying (and
+ * failing) to match an IP address or DNS name to a keyword,
+ * the association keywords use FOLLBY_STRING in the keyword
+ * table, which tells the scanner to force the next token to be
+ * a T_String, so it does not try to match a keyword but rather
+ * expects a string when -4/-6 modifiers to server, peer, etc.
+ * are encountered.
+ * restrict -4 and restrict -6 parsing works correctly without
+ * this hack, as restrict uses FOLLBY_TOKEN. [DH]
+ */
+ if ('-' == yytext[0]) {
+ if ('4' == yytext[1]) {
+ token = T_Ipv4_flag;
+ goto normal_return;
+ } else if ('6' == yytext[1]) {
+ token = T_Ipv6_flag;
+ goto normal_return;
+ }
+ }
+
+ instring = false;
+ if (FOLLBY_STRING == followedby) {
+ followedby = FOLLBY_TOKEN;
+ }
+
+ yylval_was_set = true;
+ token = create_string_token(yytext);
normal_return:
- if (T_EOC == token)
- DPRINT(4,("\t<end of command>\n"));
- else
- DPRINT(4, ("yylex: lexeme '%s' -> %s\n", yytext,
- token_name(token)));
+ if (T_EOC == token)
+ DPRINT(4,("\t<end of command>\n"));
+ else
+ DPRINT(4, ("yylex: lexeme '%s' -> %s\n", yytext,
+ token_name(token)));
- if (!yylval_was_set)
- yylval.Integer = token;
+ if (!yylval_was_set)
+ yylval.Integer = token;
- return token;
+ return token;
lex_too_long:
- yytext[min(sizeof(yytext) - 1, 50)] = 0;
- msyslog(LOG_ERR,
- "CONFIG: configuration item on line %d longer than limit of %lu, began with '%s'",
- lex_stack->curpos.nline, (unsigned long)min(sizeof(yytext) - 1, 50),
- yytext);
-
- /*
- * If we hit the length limit reading the startup configuration
- * file, abort.
- */
- if (lex_from_file())
- exit(sizeof(yytext) - 1);
-
- /*
- * If it's runtime configuration via ntpq :config treat it as
- * if the configuration text ended before the too-long lexeme,
- * hostname, or string.
- */
- yylval.Integer = 0;
- return 0;
+ yytext[min(sizeof(yytext) - 1, 50)] = 0;
+ msyslog(LOG_ERR,
+ "CONFIG: configuration item on line %d longer than limit of %lu, began with '%s'",
+ lex_stack->curpos.nline, (unsigned long)min(sizeof(yytext) - 1, 50),
+ yytext);
+
+ /*
+ * If we hit the length limit reading the startup configuration
+ * file, abort.
+ */
+ if (lex_from_file())
+ exit(sizeof(yytext) - 1);
+
+ /*
+ * If it's runtime configuration via ntpq :config treat it as
+ * if the configuration text ended before the too-long lexeme,
+ * hostname, or string.
+ */
+ yylval.Integer = 0;
+ return 0;
}
=====================================
ntpd/nts.c
=====================================
@@ -33,50 +33,50 @@ struct nts_counters nts_cnt, old_nts_cnt;
struct ntske_counters ntske_cnt, old_ntske_cnt;
struct ntsconfig_t ntsconfig = {
- .ntsenable = false,
- .mintls = NULL,
- .maxtls = NULL,
- .tlsciphersuites = NULL,
- .tlsecdhcurves = NULL,
- .cert = NULL,
- .key = NULL,
- .KI = NULL,
- .ca = NULL,
- .aead = NULL,
- .tlscipherserverpreference = false,
+ .ntsenable = false,
+ .mintls = NULL,
+ .maxtls = NULL,
+ .tlsciphersuites = NULL,
+ .tlsecdhcurves = NULL,
+ .cert = NULL,
+ .key = NULL,
+ .KI = NULL,
+ .ca = NULL,
+ .aead = NULL,
+ .tlscipherserverpreference = false,
};
void nts_log_version(void);
-/*****************************************************/
+// ***************************************************
-/* More SSL initialization in ssl_init() from libntp/ssl_init.c */
+// More SSL initialization in ssl_init() from libntp/ssl_init.c
void nts_init(void) {
- bool ok = true;
- nts_log_version();
- if (ntsconfig.ntsenable) {
- ok &= nts_server_init();
- }
- ok &= nts_client_init();
- ok &= nts_cookie_init();
- ok &= extens_init();
- if (!ok) {
- msyslog(LOG_ERR, "NTS: troubles during init. Bailing.");
- exit(1);
- }
+ bool ok = true;
+ nts_log_version();
+ if (ntsconfig.ntsenable) {
+ ok &= nts_server_init();
+ }
+ ok &= nts_client_init();
+ ok &= nts_cookie_init();
+ ok &= extens_init();
+ if (!ok) {
+ msyslog(LOG_ERR, "NTS: troubles during init. Bailing.");
+ exit(1);
+ }
}
void nts_init2(void) {
- bool ok = true;
- if (ntsconfig.ntsenable) {
- ok &= nts_server_init2();
- ok &= nts_cookie_init2();
- }
- if (!ok) {
- msyslog(LOG_ERR, "NTS: troubles during init2. Bailing.");
- exit(1);
- }
+ bool ok = true;
+ if (ntsconfig.ntsenable) {
+ ok &= nts_server_init2();
+ ok &= nts_cookie_init2();
+ }
+ if (!ok) {
+ msyslog(LOG_ERR, "NTS: troubles during init2. Bailing.");
+ exit(1);
+ }
}
/* There are 2 cases:
@@ -84,212 +84,212 @@ void nts_init2(void) {
* 2: mismatch, log both build and run
*/
void nts_log_version(void) {
- unsigned long buildVersion = OPENSSL_VERSION_NUMBER;
- const char * text = OpenSSL_version(OPENSSL_VERSION);
- bool match = (buildVersion == OpenSSL_version_num()) &&
- (0 == strcmp(OPENSSL_VERSION_TEXT, text));
- if (match) {
- /* Case 1 */
- msyslog(LOG_INFO, "INIT: %s, %lx",
- OPENSSL_VERSION_TEXT, buildVersion);
- } else {
- /* Case 2 */
- msyslog(LOG_INFO, "INIT: Built with %s, %lx",
- OPENSSL_VERSION_TEXT, buildVersion);
- msyslog(LOG_INFO, "INIT: Running with %s, %lx",
- OpenSSL_version(OPENSSL_VERSION),
- OpenSSL_version_num());
- if (buildVersion > OpenSSL_version_num()) {
- msyslog(LOG_ERR, "INIT: Old OpenSSL library, bailing");
- exit(1);
- }
- }
- /*
- * If the runtime OpenSSL is 1.1.1a, then bail, since we'll run into errors with the
- * TLSv1.3 maximum label length
- */
- if (OpenSSL_version_num() == 0x1010101fL) {
- msyslog(LOG_ERR, "INIT: OpenSSL 1.1.1a has a maximum label length bug, bailing");
- exit(1);
- }
-}
-
-/*****************************************************/
+ unsigned long buildVersion = OPENSSL_VERSION_NUMBER;
+ const char * text = OpenSSL_version(OPENSSL_VERSION);
+ bool match = (buildVersion == OpenSSL_version_num()) &&
+ (0 == strcmp(OPENSSL_VERSION_TEXT, text));
+ if (match) {
+ // Case 1
+ msyslog(LOG_INFO, "INIT: %s, %lx",
+ OPENSSL_VERSION_TEXT, buildVersion);
+ } else {
+ // Case 2
+ msyslog(LOG_INFO, "INIT: Built with %s, %lx",
+ OPENSSL_VERSION_TEXT, buildVersion);
+ msyslog(LOG_INFO, "INIT: Running with %s, %lx",
+ OpenSSL_version(OPENSSL_VERSION),
+ OpenSSL_version_num());
+ if (buildVersion > OpenSSL_version_num()) {
+ msyslog(LOG_ERR, "INIT: Old OpenSSL library, bailing");
+ exit(1);
+ }
+ }
+ /*
+ * If the runtime OpenSSL is 1.1.1a, then bail, since we'll run into errors with the
+ * TLSv1.3 maximum label length
+ */
+ if (OpenSSL_version_num() == 0x1010101fL) {
+ msyslog(LOG_ERR, "INIT: OpenSSL 1.1.1a has a maximum label length bug, bailing");
+ exit(1);
+ }
+}
+
+// ***************************************************
void nts_timer(void) {
- nts_cert_timer();
- nts_cookie_timer();
+ nts_cert_timer();
+ nts_cookie_timer();
}
-/*****************************************************/
+// ***************************************************
-/* 0 is default, -1 is error */
+// 0 is default, -1 is error
int nts_translate_version(const char *arg) {
- if (NULL == arg) {
- return 0;
- }
- if (0 == strcmp(arg, "TLS1.3")) {
- return TLS1_3_VERSION;
- }
- msyslog(LOG_ERR, "NTS: TLS unrecognized version string: %s.", arg);
- return -1;
+ if (NULL == arg) {
+ return 0;
+ }
+ if (0 == strcmp(arg, "TLS1.3")) {
+ return TLS1_3_VERSION;
+ }
+ msyslog(LOG_ERR, "NTS: TLS unrecognized version string: %s.", arg);
+ return -1;
}
-/* Translate text to AEAD code. NO_AEAD for none/error */
+// Translate text to AEAD code. NO_AEAD for none/error
uint16_t nts_string_to_aead(const char* text) {
- if (false) {
- } else if (0 == strcmp(text, "AES_SIV_CMAC_256")) {
- return AEAD_AES_SIV_CMAC_256;
- } else if (0 == strcmp(text, "AES_SIV_CMAC_384")) {
- return AEAD_AES_SIV_CMAC_384;
- } else if (0 == strcmp(text, "AES_SIV_CMAC_512")) {
- return AEAD_AES_SIV_CMAC_512;
- } else {
- return NO_AEAD;
- }
-}
-
-/* returns key length, 0 if unknown arg */
+ if (false) {
+ } else if (0 == strcmp(text, "AES_SIV_CMAC_256")) {
+ return AEAD_AES_SIV_CMAC_256;
+ } else if (0 == strcmp(text, "AES_SIV_CMAC_384")) {
+ return AEAD_AES_SIV_CMAC_384;
+ } else if (0 == strcmp(text, "AES_SIV_CMAC_512")) {
+ return AEAD_AES_SIV_CMAC_512;
+ } else {
+ return NO_AEAD;
+ }
+}
+
+// returns key length, 0 if unknown arg
int nts_get_key_length(uint16_t aead) {
- switch (aead) {
- case AEAD_AES_SIV_CMAC_256:
- return AEAD_AES_SIV_CMAC_256_KEYLEN;
- case AEAD_AES_SIV_CMAC_384:
- return AEAD_AES_SIV_CMAC_384_KEYLEN;
- case AEAD_AES_SIV_CMAC_512:
- return AEAD_AES_SIV_CMAC_512_KEYLEN;
- default:
- return 0;
- }
+ switch (aead) {
+ case AEAD_AES_SIV_CMAC_256:
+ return AEAD_AES_SIV_CMAC_256_KEYLEN;
+ case AEAD_AES_SIV_CMAC_384:
+ return AEAD_AES_SIV_CMAC_384_KEYLEN;
+ case AEAD_AES_SIV_CMAC_512:
+ return AEAD_AES_SIV_CMAC_512_KEYLEN;
+ default:
+ return 0;
+ }
}
-/*****************************************************/
+// ***************************************************
bool nts_load_versions(SSL_CTX *ctx) {
- int minver, maxver;
- minver = nts_translate_version(ntsconfig.mintls);
- maxver = nts_translate_version(ntsconfig.maxtls);
- if ((-1 == minver) || (-1 == maxver))
- return false;
- if(0 == minver) minver = TLS1_3_VERSION; // 3.
- SSL_CTX_set_min_proto_version(ctx, minver);
- SSL_CTX_set_max_proto_version(ctx, maxver);
- return true;
+ int minver, maxver;
+ minver = nts_translate_version(ntsconfig.mintls);
+ maxver = nts_translate_version(ntsconfig.maxtls);
+ if ((-1 == minver) || (-1 == maxver))
+ return false;
+ if(0 == minver) minver = TLS1_3_VERSION; // 3.
+ SSL_CTX_set_min_proto_version(ctx, minver);
+ SSL_CTX_set_max_proto_version(ctx, maxver);
+ return true;
}
bool nts_load_ciphers(SSL_CTX *ctx) {
- /* SSL set_ciphers(uites) ignores typos or ciphers it doesn't support.
- * There is no SSL_CTX_get_cipher_list, so we can't easily read back
- * the ciphers to see what it took.
- * We could make a dummy SSL, read the list, then free it.
- * man SSL_CTX_set_ciphersuites() has info.
- */
- if (NULL == ntsconfig.tlsciphersuites) {
- return true;
- }
- /* This used to set server-preference See #797 */
- if (1 != SSL_CTX_set_ciphersuites(ctx, ntsconfig.tlsciphersuites)) {
- msyslog(LOG_ERR, "NTS: troubles setting ciphersuites.");
- return false;
- } else {
- msyslog(LOG_INFO, "NTS: set ciphersuites %s.", ntsconfig.tlsciphersuites);
- }
- return true;
+ /* SSL set_ciphers(uites) ignores typos or ciphers it doesn't support.
+ * There is no SSL_CTX_get_cipher_list, so we can't easily read back
+ * the ciphers to see what it took.
+ * We could make a dummy SSL, read the list, then free it.
+ * man SSL_CTX_set_ciphersuites() has info.
+ */
+ if (NULL == ntsconfig.tlsciphersuites) {
+ return true;
+ }
+ // This used to set server-preference See #797
+ if (1 != SSL_CTX_set_ciphersuites(ctx, ntsconfig.tlsciphersuites)) {
+ msyslog(LOG_ERR, "NTS: troubles setting ciphersuites.");
+ return false;
+ } else {
+ msyslog(LOG_INFO, "NTS: set ciphersuites %s.", ntsconfig.tlsciphersuites);
+ }
+ return true;
}
bool nts_load_ecdhcurves(SSL_CTX *ctx) {
- /* SSL_CTX_set1_groups_list ignores typos or curves it doesn't support.
- * There is no SSL_CTX_get_groups_list, so we can't easily read back
- * the ecdhcurves to see what it took.
- * We could make a dummy SSL, read the list, then free it.
- */
- if (NULL != ntsconfig.tlsecdhcurves) {
- /* FIXME -- const bug in OpenSSL */
- char *copy = estrdup(ntsconfig.tlsecdhcurves);
- if (1 != SSL_CTX_set1_groups_list(ctx, copy)) {
- msyslog(LOG_ERR, "NTS: troubles setting ecdhcurves.");
- free(copy);
- return false;
- } else {
- msyslog(LOG_INFO, "NTS: set ecdhcurves %s.", ntsconfig.tlsecdhcurves);
- }
- free(copy);
- }
- return true;
+ /* SSL_CTX_set1_groups_list ignores typos or curves it doesn't support.
+ * There is no SSL_CTX_get_groups_list, so we can't easily read back
+ * the ecdhcurves to see what it took.
+ * We could make a dummy SSL, read the list, then free it.
+ */
+ if (NULL != ntsconfig.tlsecdhcurves) {
+ // FIXME -- const bug in OpenSSL
+ char *copy = estrdup(ntsconfig.tlsecdhcurves);
+ if (1 != SSL_CTX_set1_groups_list(ctx, copy)) {
+ msyslog(LOG_ERR, "NTS: troubles setting ecdhcurves.");
+ free(copy);
+ return false;
+ } else {
+ msyslog(LOG_INFO, "NTS: set ecdhcurves %s.", ntsconfig.tlsecdhcurves);
+ }
+ free(copy);
+ }
+ return true;
}
bool nts_set_cipher_order(SSL_CTX *ctx) {
- if (ntsconfig.tlscipherserverpreference)
- SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
- return true;
+ if (ntsconfig.tlscipherserverpreference)
+ SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
+ return true;
}
static struct stat certfile_stat;
void nts_reload_certificate(SSL_CTX *ctx) {
- struct stat temp_stat;
- const char *cert = NTS_CERT_FILE;
+ struct stat temp_stat;
+ const char *cert = NTS_CERT_FILE;
- if (NULL != ntsconfig.cert)
- cert = ntsconfig.cert;
+ if (NULL != ntsconfig.cert)
+ cert = ntsconfig.cert;
- if (0 != stat(cert, &temp_stat)) {
- return;
- }
+ if (0 != stat(cert, &temp_stat)) {
+ return;
+ }
- if ((certfile_stat.st_mtime == temp_stat.st_mtime)
+ if ((certfile_stat.st_mtime == temp_stat.st_mtime)
&& (certfile_stat.st_ctime == temp_stat.st_ctime)) {
- return; /* avoid clutter in log file */
- }
+ return; // avoid clutter in log file
+ }
- nts_load_certificate(ctx);
+ nts_load_certificate(ctx);
}
bool nts_load_certificate(SSL_CTX *ctx) {
- const char *cert = NTS_CERT_FILE;
- const char *key = NTS_KEY_FILE;
+ const char *cert = NTS_CERT_FILE;
+ const char *key = NTS_KEY_FILE;
char errbuf[100];
- if (NULL != ntsconfig.cert)
- cert = ntsconfig.cert;
- if (NULL != ntsconfig.key)
- key = ntsconfig.key;
-
- /* for reload checking */
- if (0 != stat(cert, &certfile_stat)) {
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
- msyslog(LOG_ERR, "NTSs: can't stat certificate (chain) from %s: %s", cert, errbuf);
- 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();
- return false;
- } else {
- msyslog(LOG_ERR, "NTSs: loaded certificate (chain) from %s", cert);
- }
- if (1 != SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) {
- msyslog(LOG_ERR, "NTSs: can't load private key from %s", key);
- nts_log_ssl_error();
- return false;
- } else {
- msyslog(LOG_ERR, "NTSs: loaded private key from %s", key);
- }
-
- if (1 != SSL_CTX_check_private_key(ctx)) {
- msyslog(LOG_ERR, "NTSs: Private Key doesn't work ******");
- return false;
- } else {
- msyslog(LOG_INFO, "NTSs: Private Key OK");
- }
- return true;
-}
-
-/* scan partial(?) buffer for end marker */
+ if (NULL != ntsconfig.cert)
+ cert = ntsconfig.cert;
+ if (NULL != ntsconfig.key)
+ key = ntsconfig.key;
+
+ // for reload checking
+ if (0 != stat(cert, &certfile_stat)) {
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ msyslog(LOG_ERR, "NTSs: can't stat certificate (chain) from %s: %s", cert, errbuf);
+ 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();
+ return false;
+ } else {
+ msyslog(LOG_ERR, "NTSs: loaded certificate (chain) from %s", cert);
+ }
+ if (1 != SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) {
+ msyslog(LOG_ERR, "NTSs: can't load private key from %s", key);
+ nts_log_ssl_error();
+ return false;
+ } else {
+ msyslog(LOG_ERR, "NTSs: loaded private key from %s", key);
+ }
+
+ if (1 != SSL_CTX_check_private_key(ctx)) {
+ msyslog(LOG_ERR, "NTSs: Private Key doesn't work ******");
+ return false;
+ } else {
+ msyslog(LOG_INFO, "NTSs: Private Key OK");
+ }
+ return true;
+}
+
+// scan partial(?) buffer for end marker
static bool find_end_marker(uint8_t *buff, int bytes) {
while (NTS_KE_HDR_LNG<=bytes) {
uint16_t *buff16 = (uint16_t *)buff;
@@ -381,131 +381,131 @@ int nts_ssl_write(SSL *ssl, uint8_t *buff, int buff_length, const char** errtxt)
return bytes_written;
}
-/* Each thread has it's own queue of errors */
+// Each thread has it's own queue of errors
void nts_get_ssl_error(char *errbuf, int errlng) {
int err = ERR_get_error();
ERR_error_string_n(err, errbuf, errlng);
}
void nts_log_ssl_error(void) {
- char buff[256];
- int err = ERR_get_error();
- SSL_load_error_strings(); /* Needed on NetBSD */
- while (0 != err) {
- ERR_error_string_n(err, buff, sizeof(buff));
- msyslog(LOG_INFO, "NTS: %s", buff);
- err = ERR_get_error();
- }
+ char buff[256];
+ int err = ERR_get_error();
+ SSL_load_error_strings(); // Needed on NetBSD
+ while (0 != err) {
+ ERR_error_string_n(err, buff, sizeof(buff));
+ msyslog(LOG_INFO, "NTS: %s", buff);
+ err = ERR_get_error();
+ }
}
-/*****************************************************/
+// ***************************************************
-/* NB: KE length is body length, Extension length includes header. */
+// NB: KE length is body length, Extension length includes header.
-/* Troubles with signed/unsigned compares when using sizeof() */
+// Troubles with signed/unsigned compares when using sizeof()
void ke_append_record_null(BufCtl* buf, uint16_t type) {
- append_header(buf, type, 0);
+ append_header(buf, type, 0);
}
void ke_append_record_uint16(BufCtl* buf, uint16_t type, uint16_t data) {
- if (NTS_KE_HDR_LNG+NTS_KE_U16_LNG > buf->left)
- return;
- append_header(buf, type, NTS_KE_U16_LNG);
- append_uint16(buf, data);
+ if (NTS_KE_HDR_LNG+NTS_KE_U16_LNG > buf->left)
+ return;
+ append_header(buf, type, NTS_KE_U16_LNG);
+ append_uint16(buf, data);
}
void ke_append_record_bytes(BufCtl* buf, uint16_t type, uint8_t *data, int length) {
- if (NTS_KE_HDR_LNG+length > buf->left)
- return;
- append_header(buf, type, length);
- append_bytes(buf, data, length);
+ if (NTS_KE_HDR_LNG+length > buf->left)
+ return;
+ append_header(buf, type, length);
+ append_bytes(buf, data, length);
}
void ex_append_record_null(BufCtl* buf, uint16_t type) {
- append_header(buf, type, NTS_KE_HDR_LNG);
+ append_header(buf, type, NTS_KE_HDR_LNG);
}
void ex_append_record_uint16(BufCtl* buf, uint16_t type, uint16_t data) {
- if (NTS_KE_HDR_LNG+NTS_KE_U16_LNG > buf->left)
- return;
- append_header(buf, type, NTS_KE_HDR_LNG+NTS_KE_U16_LNG);
- append_uint16(buf, data);
+ if (NTS_KE_HDR_LNG+NTS_KE_U16_LNG > buf->left)
+ return;
+ append_header(buf, type, NTS_KE_HDR_LNG+NTS_KE_U16_LNG);
+ append_uint16(buf, data);
}
void ex_append_record_bytes(BufCtl* buf, uint16_t type, uint8_t *data, int length) {
- if (NTS_KE_HDR_LNG+length > buf->left)
- return;
- append_header(buf, type, NTS_KE_HDR_LNG+length);
- append_bytes(buf, data, length);
+ if (NTS_KE_HDR_LNG+length > buf->left)
+ return;
+ append_header(buf, type, NTS_KE_HDR_LNG+length);
+ append_bytes(buf, data, length);
}
void ex_append_header(BufCtl* buf, uint16_t type, uint16_t length) {
- append_header(buf, type, NTS_KE_HDR_LNG+length);
+ append_header(buf, type, NTS_KE_HDR_LNG+length);
}
void append_header(BufCtl* buf, uint16_t type, uint16_t length) {
- uint16_t * ptr = (uint16_t *)buf->next;
- if (NTS_KE_HDR_LNG > buf->left)
- return;
- *ptr++ = htons(type);
- *ptr++ = htons(length);
- buf->next += NTS_KE_HDR_LNG;
- buf->left -= NTS_KE_HDR_LNG;
- /* leaves buf pointing to where data will go */
+ uint16_t * ptr = (uint16_t *)buf->next;
+ if (NTS_KE_HDR_LNG > buf->left)
+ return;
+ *ptr++ = htons(type);
+ *ptr++ = htons(length);
+ buf->next += NTS_KE_HDR_LNG;
+ buf->left -= NTS_KE_HDR_LNG;
+ // leaves buf pointing to where data will go
}
void append_uint16(BufCtl* buf, uint16_t data) {
- uint16_t * ptr = (uint16_t *)buf->next;
- if (NTS_KE_U16_LNG > buf->left)
- return;
- *ptr++ = htons(data);
- buf->next += NTS_KE_U16_LNG;
- buf->left -= NTS_KE_U16_LNG;
+ uint16_t * ptr = (uint16_t *)buf->next;
+ if (NTS_KE_U16_LNG > buf->left)
+ return;
+ *ptr++ = htons(data);
+ buf->next += NTS_KE_U16_LNG;
+ buf->left -= NTS_KE_U16_LNG;
}
void append_bytes(BufCtl* buf, uint8_t *data, int length) {
- if (length > buf->left)
- return;
- memcpy(buf->next, data, length);
- buf->next += length;
- buf->left -= length;
+ if (length > buf->left)
+ return;
+ memcpy(buf->next, data, length);
+ buf->next += length;
+ buf->left -= length;
}
-/* Reads type and length of the next record, and moves cursor to the data */
+// Reads type and length of the next record, and moves cursor to the data
uint16_t ke_next_record(BufCtl* buf, int *length) {
- uint16_t *ptr = (uint16_t *)buf->next;
- uint16_t type = ntohs(*ptr++);
- *length = ntohs(*ptr++);
- buf->next += NTS_KE_HDR_LNG;
- buf->left -= NTS_KE_HDR_LNG;
- return type;
+ uint16_t *ptr = (uint16_t *)buf->next;
+ uint16_t type = ntohs(*ptr++);
+ *length = ntohs(*ptr++);
+ buf->next += NTS_KE_HDR_LNG;
+ buf->left -= NTS_KE_HDR_LNG;
+ return type;
}
uint16_t ex_next_record(BufCtl* buf, int *length) {
- uint16_t *ptr = (uint16_t *)buf->next;
- uint16_t type = ntohs(*ptr++);
- *length = ntohs(*ptr++)-NTS_KE_HDR_LNG;
- buf->next += NTS_KE_HDR_LNG;
- buf->left -= NTS_KE_HDR_LNG;
- return type;
+ uint16_t *ptr = (uint16_t *)buf->next;
+ uint16_t type = ntohs(*ptr++);
+ *length = ntohs(*ptr++)-NTS_KE_HDR_LNG;
+ buf->next += NTS_KE_HDR_LNG;
+ buf->left -= NTS_KE_HDR_LNG;
+ return type;
}
-/* Reads a uint16 from the record and advances to the next data */
+// Reads a uint16 from the record and advances to the next data
uint16_t next_uint16(BufCtl* buf) {
- uint16_t *ptr = (uint16_t *)buf->next;
- uint16_t data = ntohs(*ptr++);
- buf->next += NTS_KE_U16_LNG;
- buf->left -= NTS_KE_U16_LNG;
- return data;
+ uint16_t *ptr = (uint16_t *)buf->next;
+ uint16_t data = ntohs(*ptr++);
+ buf->next += NTS_KE_U16_LNG;
+ buf->left -= NTS_KE_U16_LNG;
+ return data;
}
-/* Reads a string of bytes from the record and advances to the next data */
+// Reads a string of bytes from the record and advances to the next data
uint16_t next_bytes(BufCtl* buf, uint8_t *data, int length) {
- memcpy(data, buf->next, length);
- buf->next += length;
- buf->left -= length;
- return length;
+ memcpy(data, buf->next, length);
+ buf->next += length;
+ buf->left -= length;
+ return length;
}
-/* end */
+// end
=====================================
ntpd/nts_client.c
=====================================
@@ -52,218 +52,218 @@ bool nts_server_lookup(char *server, sockaddr_u *addr, int af);
static SSL_CTX *client_ctx = NULL;
-/* Ugly global variables passed from worker thread back to main thread. */
+// Ugly global variables passed from worker thread back to main thread.
static sockaddr_u sockaddr;
static bool addrOK;
bool nts_client_init(void) {
- client_ctx = make_ssl_client_ctx(ntsconfig.ca);
+ client_ctx = make_ssl_client_ctx(ntsconfig.ca);
-/* Ugly global variables passed from worker thread back to main thread. */
- return true;
+// Ugly global variables passed from worker thread back to main thread.
+ return true;
}
bool nts_probe(struct peer * peer) {
- struct timeval timeout = {.tv_sec = NTS_KE_TIMEOUT, .tv_usec = 0};
- const char *hostname = peer->hostname;
- char hostbuf[100];
- char errbuf[100];
- SSL *ssl;
- int server;
- struct timespec start, finish;
- int err;
-
- if (NULL == client_ctx)
- return false;
-
- addrOK = false;
- clock_gettime(CLOCK_MONOTONIC, &start);
-
- if (NULL == hostname) {
- /* IP Address case */
- int af = AF(&peer->srcadr);
- switch (af) {
- case AF_INET:
- inet_ntop(af, PSOCK_ADDR4(&peer->srcadr), hostbuf, sizeof(hostbuf));
- break;
- case AF_INET6:
- /* Add [] in case [xxx]:port */
- hostbuf[0] = '[';
- inet_ntop(af, PSOCK_ADDR6(&peer->srcadr), hostbuf+1, sizeof(hostbuf)-1);
- strlcat(hostbuf, "]", sizeof(hostbuf));
- break;
- default:
- return false;
- }
- hostname = hostbuf;
-// msyslog(LOG_INFO, "NTSc: Address Literal: %s", hostbuf);
- }
-
- server = open_TCP_socket(peer, hostname);
- if (-1 == server) {
- ntske_cnt.probes_bad++;
- return false;
- }
-
- err = setsockopt(server, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
- if (0 > err) {
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
- msyslog(LOG_ERR, "NTSc: can't set recv timeout: %s", errbuf);
- close(server);
- ntske_cnt.probes_bad++;
- return false;
- }
- err = setsockopt(server, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
- if (0 > err) {
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
- msyslog(LOG_ERR, "NTSc: can't set send timeout: %s", errbuf);
- close(server);
- ntske_cnt.probes_bad++;
- return false;
- }
-
- if (NULL == peer->cfg.nts_cfg.ca)
- ssl = SSL_new(client_ctx);
- else {
- SSL_CTX *ctx;
- ctx = make_ssl_client_ctx(peer->cfg.nts_cfg.ca);
- if (NULL == ctx) {
- close(server);
- return false;
- }
- ssl = SSL_new(ctx);
- SSL_CTX_free(ctx);
- }
- if (NULL == ssl) {
- msyslog(LOG_ERR, "NTSc: SSL_new failed");
- nts_log_ssl_error();
- close(server);
- ntske_cnt.probes_bad++;
- return false;
- }
- set_hostname(ssl, hostname);
- SSL_set_fd(ssl, server);
-
- if (1 != SSL_connect(ssl)) {
- msyslog(LOG_INFO, "NTSc: SSL_connect failed");
- nts_log_ssl_error();
- goto bail;
- }
- if (1 != SSL_do_handshake(ssl)) {
- msyslog(LOG_INFO, "NTSc: SSL_do_handshake failed");
- nts_log_ssl_error();
- goto bail;
- }
-
- /* This may be clutter, but this is how to do it. */
- msyslog(LOG_INFO, "NTSc: Using %s, %s (%d)",
- SSL_get_version(ssl),
- SSL_get_cipher_name(ssl),
- SSL_get_cipher_bits(ssl, NULL));
-
- if (!check_certificate(ssl, peer))
- goto bail;
- if (!check_alpn(ssl, peer, hostname))
- goto bail;
-
- if (!nts_client_send_request(ssl, peer))
- goto bail;
- if (!nts_client_process_response(ssl, peer))
- goto bail;
-
- /* 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) {
- msyslog(LOG_ERR, "NTSc: Unknown AEAD code: %d", peer->nts_state.aead);
- goto bail;
- }
- if (!nts_make_keys(ssl,
- peer->nts_state.aead,
- peer->nts_state.c2s,
- peer->nts_state.s2c,
- peer->nts_state.keylen))
- goto bail;
-
- addrOK = true;
- ntske_cnt.probes_good++;
+ struct timeval timeout = {.tv_sec = NTS_KE_TIMEOUT, .tv_usec = 0};
+ const char *hostname = peer->hostname;
+ char hostbuf[100];
+ char errbuf[100];
+ SSL *ssl;
+ int server;
+ struct timespec start, finish;
+ int err;
+
+ if (NULL == client_ctx)
+ return false;
+
+ addrOK = false;
+ clock_gettime(CLOCK_MONOTONIC, &start);
+
+ if (NULL == hostname) {
+ // IP Address case
+ int af = AF(&peer->srcadr);
+ switch (af) {
+ case AF_INET:
+ inet_ntop(af, PSOCK_ADDR4(&peer->srcadr), hostbuf, sizeof(hostbuf));
+ break;
+ case AF_INET6:
+ // Add [] in case [xxx]:port
+ hostbuf[0] = '[';
+ inet_ntop(af, PSOCK_ADDR6(&peer->srcadr), hostbuf+1, sizeof(hostbuf)-1);
+ strlcat(hostbuf, "]", sizeof(hostbuf));
+ break;
+ default:
+ return false;
+ }
+ hostname = hostbuf;
+// msyslog(LOG_INFO, "NTSc: Address Literal: %s", hostbuf);
+ }
+
+ server = open_TCP_socket(peer, hostname);
+ if (-1 == server) {
+ ntske_cnt.probes_bad++;
+ return false;
+ }
+
+ err = setsockopt(server, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
+ if (0 > err) {
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ msyslog(LOG_ERR, "NTSc: can't set recv timeout: %s", errbuf);
+ close(server);
+ ntske_cnt.probes_bad++;
+ return false;
+ }
+ err = setsockopt(server, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
+ if (0 > err) {
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ msyslog(LOG_ERR, "NTSc: can't set send timeout: %s", errbuf);
+ close(server);
+ ntske_cnt.probes_bad++;
+ return false;
+ }
+
+ if (NULL == peer->cfg.nts_cfg.ca)
+ ssl = SSL_new(client_ctx);
+ else {
+ SSL_CTX *ctx;
+ ctx = make_ssl_client_ctx(peer->cfg.nts_cfg.ca);
+ if (NULL == ctx) {
+ close(server);
+ return false;
+ }
+ ssl = SSL_new(ctx);
+ SSL_CTX_free(ctx);
+ }
+ if (NULL == ssl) {
+ msyslog(LOG_ERR, "NTSc: SSL_new failed");
+ nts_log_ssl_error();
+ close(server);
+ ntske_cnt.probes_bad++;
+ return false;
+ }
+ set_hostname(ssl, hostname);
+ SSL_set_fd(ssl, server);
+
+ if (1 != SSL_connect(ssl)) {
+ msyslog(LOG_INFO, "NTSc: SSL_connect failed");
+ nts_log_ssl_error();
+ goto bail;
+ }
+ if (1 != SSL_do_handshake(ssl)) {
+ msyslog(LOG_INFO, "NTSc: SSL_do_handshake failed");
+ nts_log_ssl_error();
+ goto bail;
+ }
+
+ // This may be clutter, but this is how to do it.
+ msyslog(LOG_INFO, "NTSc: Using %s, %s (%d)",
+ SSL_get_version(ssl),
+ SSL_get_cipher_name(ssl),
+ SSL_get_cipher_bits(ssl, NULL));
+
+ if (!check_certificate(ssl, peer))
+ goto bail;
+ if (!check_alpn(ssl, peer, hostname))
+ goto bail;
+
+ if (!nts_client_send_request(ssl, peer))
+ goto bail;
+ if (!nts_client_process_response(ssl, peer))
+ goto bail;
+
+ /* 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) {
+ msyslog(LOG_ERR, "NTSc: Unknown AEAD code: %d", peer->nts_state.aead);
+ goto bail;
+ }
+ if (!nts_make_keys(ssl,
+ peer->nts_state.aead,
+ peer->nts_state.c2s,
+ peer->nts_state.s2c,
+ peer->nts_state.keylen))
+ goto bail;
+
+ addrOK = true;
+ ntske_cnt.probes_good++;
bail:
- if (!addrOK) {
- ntske_cnt.probes_bad++;
- peer->nts_state.count = -1;
- }
- SSL_shutdown(ssl);
- SSL_free(ssl);
- close(server);
-
- clock_gettime(CLOCK_MONOTONIC, &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;
+ if (!addrOK) {
+ ntske_cnt.probes_bad++;
+ peer->nts_state.count = -1;
+ }
+ SSL_shutdown(ssl);
+ SSL_free(ssl);
+ close(server);
+
+ clock_gettime(CLOCK_MONOTONIC, &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;
}
bool nts_check(struct peer *peer) {
- if (0) {
- char errbuf[100];
- sockporttoa_r(&sockaddr, errbuf, sizeof(errbuf));
- msyslog(LOG_INFO, "NTSc: nts_check %s, %d", errbuf, addrOK);
- }
- if (addrOK) {
- if (peer->cast_flags & MDF_POOL) {
- dns_take_pool(peer, &sockaddr);
- dns_take_status(peer, DNS_NTS_pool);
- } else {
- dns_take_server(peer, &sockaddr);
- dns_take_status(peer, DNS_good);
- }
- } else
- dns_take_status(peer, DNS_error);
- return addrOK;
+ if (0) {
+ char errbuf[100];
+ sockporttoa_r(&sockaddr, errbuf, sizeof(errbuf));
+ msyslog(LOG_INFO, "NTSc: nts_check %s, %d", errbuf, addrOK);
+ }
+ if (addrOK) {
+ if (peer->cast_flags & MDF_POOL) {
+ dns_take_pool(peer, &sockaddr);
+ dns_take_status(peer, DNS_NTS_pool);
+ } else {
+ dns_take_server(peer, &sockaddr);
+ dns_take_status(peer, DNS_good);
+ }
+ } else
+ dns_take_status(peer, DNS_error);
+ return addrOK;
}
SSL_CTX* make_ssl_client_ctx(const char * filename) {
- bool ok = true;
- SSL_CTX *ctx;
-
- ctx = SSL_CTX_new(TLS_client_method());
- if (NULL == ctx) {
- /* Happens if no ciphers */
- msyslog(LOG_ERR, "NTSc: NULL ctx");
- nts_log_ssl_error();
- return NULL;
- }
-
- {
- // 4., ALPN, RFC 7301
- static unsigned char alpn [] = { 7, 'n', 't', 's', 'k', 'e', '/', '1' };
- SSL_CTX_set_alpn_protos(ctx, alpn, sizeof(alpn));
- }
-
- SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
- SSL_CTX_set_timeout(ctx, NTS_KE_TIMEOUT); /* session lifetime */
-
- ok &= nts_load_versions(ctx);
- ok &= nts_load_ciphers(ctx);
- ok &= nts_load_ecdhcurves(ctx);
- ok &= nts_set_cert_search(ctx, filename);
-
- if (!ok) {
- msyslog(LOG_ERR, "NTSc: Troubles setting up client SSL CTX");
- SSL_CTX_free(ctx);
- return NULL;
- };
-
- return ctx;
+ bool ok = true;
+ SSL_CTX *ctx;
+
+ ctx = SSL_CTX_new(TLS_client_method());
+ if (NULL == ctx) {
+ // Happens if no ciphers
+ msyslog(LOG_ERR, "NTSc: NULL ctx");
+ nts_log_ssl_error();
+ return NULL;
+ }
+
+ {
+ // 4., ALPN, RFC 7301
+ static unsigned char alpn [] = { 7, 'n', 't', 's', 'k', 'e', '/', '1' };
+ SSL_CTX_set_alpn_protos(ctx, alpn, sizeof(alpn));
+ }
+
+ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
+ SSL_CTX_set_timeout(ctx, NTS_KE_TIMEOUT); // session lifetime
+
+ ok &= nts_load_versions(ctx);
+ ok &= nts_load_ciphers(ctx);
+ ok &= nts_load_ecdhcurves(ctx);
+ ok &= nts_set_cert_search(ctx, filename);
+
+ if (!ok) {
+ msyslog(LOG_ERR, "NTSc: Troubles setting up client SSL CTX");
+ SSL_CTX_free(ctx);
+ return NULL;
+ };
+
+ return ctx;
}
-/* FIXME - split out DNS work. */
+// FIXME - split out DNS work.
/* Note that there are 2 DNS lookups.
* One for the NTS-KE server and another for the NTP server.
@@ -279,129 +279,129 @@ SSL_CTX* make_ssl_client_ctx(const char * filename) {
* for most servers.
*/
-/* return -1 on error */
+// return -1 on error
int open_TCP_socket(struct peer *peer, const char *hostname) {
- char host[256], port[32];
- char errbuf[100];
- char *tmp;
- struct addrinfo hints;
- struct addrinfo *answer, *worker;
- int gai_rc;
- int sockfd;
- struct timespec start, finish;
-
- /* FIXME -- const bug in OpenSSL */
- strlcpy(host, hostname, sizeof(host));
-
- /* handle xxx:port case */
- if ('[' == host[0]) {
- /* IPv6 case, drop [], start search after ] */
- SET_AF(&peer->srcadr, AF_INET6);
- strlcpy(host, hostname+1, sizeof(host));
- tmp = strchr(host, ']');
- if (NULL == tmp) {
- msyslog(LOG_ERR, "NTSc: open_TCP_socket: missing ']': %s",
- hostname);
- return -1;
- }
- *tmp++ = 0;
- /* We have chopped off the [] around the host literal.
- * There should be nothing left or :<port> */
- if ((0 != *tmp) && (':' != *tmp)) {
- msyslog(LOG_ERR, "NTSc: open_TCP_socket: missing ':': %s",
- hostname);
- return -1;
- }
- if (0 == *tmp) tmp = NULL; /* no : */
- } else {
- tmp = strchr(host, ':');
- }
- if (NULL == tmp) {
- /* simple case, no : */
- strlcpy(port, NTS_KE_PORTA, sizeof(port));
- } else {
- /* Complicated case, found a : */
- *tmp++ = 0;
- strlcpy(port, tmp, sizeof(port));
- msyslog(LOG_INFO, "NTSc: open_TCP_socket: found port %s", port);
- }
-
- ZERO(hints);
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = AF(&peer->srcadr); /* -4, -6 switch */
- clock_gettime(CLOCK_MONOTONIC, &start);
- gai_rc = getaddrinfo(host, port, &hints, &answer);
- if (0 != gai_rc) {
- msyslog(LOG_INFO, "NTSc: open_TCP_socket: DNS error trying to contact %s, %d, %s",
- hostname, gai_rc, gai_strerror(gai_rc));
- return -1;
- }
- clock_gettime(CLOCK_MONOTONIC, &finish);
- finish = sub_tspec(finish, start);
- msyslog(LOG_INFO, "NTSc: DNS lookup of %s (%d) took %.3f sec",
- hostname, hints.ai_family, tspec_to_d(finish));
-
- /* sockaddr is global for NTP address
- * also use as temp for printing here */
- if (NULL == peer->hostname) {
- /* Address literal case, use first/only answer */
- worker = answer;
- } else {
- worker = find_best_addr(answer);
- if (NULL == worker) {
- msyslog(LOG_INFO, "NTSc: All addresses in use.");
- freeaddrinfo(answer);
- return -1;
- }
- }
- memcpy(&sockaddr, worker->ai_addr, worker->ai_addrlen);
- sockporttoa_r(&sockaddr, errbuf, sizeof(errbuf));
- msyslog(LOG_INFO, "NTSc: connecting to %s+%s => %s",
- host, port, errbuf);
-
- /* setup default NTP port now
- * in case of server-name:port later on
- */
- SET_PORT(&sockaddr, NTP_PORT);
- sockfd = socket(worker->ai_family, SOCK_STREAM, 0);
- if (-1 == sockfd) {
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
- msyslog(LOG_INFO, "NTSc: open_TCP_socket: no socket: %s", errbuf);
- } else {
- if (!connect_TCP_socket(sockfd, worker)) {
- close(sockfd);
- sockfd = -1;
- }
- }
-
- freeaddrinfo(answer);
- return sockfd;
+ char host[256], port[32];
+ char errbuf[100];
+ char *tmp;
+ struct addrinfo hints;
+ struct addrinfo *answer, *worker;
+ int gai_rc;
+ int sockfd;
+ struct timespec start, finish;
+
+ // FIXME -- const bug in OpenSSL
+ strlcpy(host, hostname, sizeof(host));
+
+ // handle xxx:port case
+ if ('[' == host[0]) {
+ // IPv6 case, drop [], start search after ]
+ SET_AF(&peer->srcadr, AF_INET6);
+ strlcpy(host, hostname+1, sizeof(host));
+ tmp = strchr(host, ']');
+ if (NULL == tmp) {
+ msyslog(LOG_ERR, "NTSc: open_TCP_socket: missing ']': %s",
+ hostname);
+ return -1;
+ }
+ *tmp++ = 0;
+ /* We have chopped off the [] around the host literal.
+ * There should be nothing left or :<port> */
+ if ((0 != *tmp) && (':' != *tmp)) {
+ msyslog(LOG_ERR, "NTSc: open_TCP_socket: missing ':': %s",
+ hostname);
+ return -1;
+ }
+ if (0 == *tmp) tmp = NULL; // no :
+ } else {
+ tmp = strchr(host, ':');
+ }
+ if (NULL == tmp) {
+ // simple case, no :
+ strlcpy(port, NTS_KE_PORTA, sizeof(port));
+ } else {
+ // Complicated case, found a :
+ *tmp++ = 0;
+ strlcpy(port, tmp, sizeof(port));
+ msyslog(LOG_INFO, "NTSc: open_TCP_socket: found port %s", port);
+ }
+
+ ZERO(hints);
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = AF(&peer->srcadr); // -4, -6 switch
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ gai_rc = getaddrinfo(host, port, &hints, &answer);
+ if (0 != gai_rc) {
+ msyslog(LOG_INFO, "NTSc: open_TCP_socket: DNS error trying to contact %s, %d, %s",
+ hostname, gai_rc, gai_strerror(gai_rc));
+ return -1;
+ }
+ clock_gettime(CLOCK_MONOTONIC, &finish);
+ finish = sub_tspec(finish, start);
+ msyslog(LOG_INFO, "NTSc: DNS lookup of %s (%d) took %.3f sec",
+ hostname, hints.ai_family, tspec_to_d(finish));
+
+ /* sockaddr is global for NTP address
+ * also use as temp for printing here */
+ if (NULL == peer->hostname) {
+ // Address literal case, use first/only answer
+ worker = answer;
+ } else {
+ worker = find_best_addr(answer);
+ if (NULL == worker) {
+ msyslog(LOG_INFO, "NTSc: All addresses in use.");
+ freeaddrinfo(answer);
+ return -1;
+ }
+ }
+ memcpy(&sockaddr, worker->ai_addr, worker->ai_addrlen);
+ sockporttoa_r(&sockaddr, errbuf, sizeof(errbuf));
+ msyslog(LOG_INFO, "NTSc: connecting to %s+%s => %s",
+ host, port, errbuf);
+
+ /* setup default NTP port now
+ * in case of server-name:port later on
+ */
+ SET_PORT(&sockaddr, NTP_PORT);
+ sockfd = socket(worker->ai_family, SOCK_STREAM, 0);
+ if (-1 == sockfd) {
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ msyslog(LOG_INFO, "NTSc: open_TCP_socket: no socket: %s", errbuf);
+ } else {
+ if (!connect_TCP_socket(sockfd, worker)) {
+ close(sockfd);
+ sockfd = -1;
+ }
+ }
+
+ freeaddrinfo(answer);
+ return sockfd;
}
struct addrinfo *find_best_addr(struct addrinfo *answer) {
- for ( ; NULL != answer; answer = answer->ai_next) {
- sockaddr_u addr;
- struct peer *pp;
- if (sizeof(sockaddr_u) < answer->ai_addrlen)
- continue; /* Weird */
- memcpy(&addr, answer->ai_addr, answer->ai_addrlen);
- /* findexistingpeer checks port too */
- for (pp = peer_list; NULL != pp; pp = pp->p_link) {
- if (MDF_POOL & pp->cast_flags) continue;
- if (FLAG_LOOKUP & pp->cfg.flags) continue;
- if (SOCK_EQ(&addr, &pp->srcadr)) break;
- }
- if (NULL != pp) {
- char errbuf[200];
- socktoa_r(&addr, errbuf, sizeof(errbuf));
- msyslog(LOG_INFO, "NTSc: Skipping %s", errbuf);
- continue; /* already in use */
- }
- break;
- }
- return(answer);
+ for ( ; NULL != answer; answer = answer->ai_next) {
+ sockaddr_u addr;
+ struct peer *pp;
+ if (sizeof(sockaddr_u) < answer->ai_addrlen)
+ continue; // Weird
+ memcpy(&addr, answer->ai_addr, answer->ai_addrlen);
+ // findexistingpeer checks port too
+ for (pp = peer_list; NULL != pp; pp = pp->p_link) {
+ if (MDF_POOL & pp->cast_flags) continue;
+ if (FLAG_LOOKUP & pp->cfg.flags) continue;
+ if (SOCK_EQ(&addr, &pp->srcadr)) break;
+ }
+ if (NULL != pp) {
+ char errbuf[200];
+ socktoa_r(&addr, errbuf, sizeof(errbuf));
+ msyslog(LOG_INFO, "NTSc: Skipping %s", errbuf);
+ continue; // already in use
+ }
+ break;
+ }
+ return(answer);
}
@@ -411,108 +411,108 @@ struct addrinfo *find_best_addr(struct addrinfo *answer) {
* Use man 3 connect.
*/
bool connect_TCP_socket(int sockfd, struct addrinfo *addr) {
- char errbuf[100];
- int err;
- fd_set fdset;
- struct timeval timeout;
- int so_error;
- socklen_t so_len = sizeof(so_error);
-
- err = fcntl(sockfd, F_SETFL, O_NONBLOCK);
- if (-1 == err) {
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
- msyslog(LOG_INFO, "NTSc: can't set O_NONBLOCK %s", errbuf);
- return false;
- }
- err = connect(sockfd, addr->ai_addr, addr->ai_addrlen);
- /* The usual nonblocking case is -1 and errno == EINPROGRESS.
- * A fast local connection can also succeed immediately.
- * Getting connected should be possible if the scheduler
- * avoids us for long enough.
- * Other errors may be possible. No route?
- * I haven't seen that yet. HGM, 2020 Jan 19
- */
- if (-1 == err && EINPROGRESS != errno) {
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
- msyslog(LOG_INFO, "NTSc: connect_TCP_socket: connect failed: %s", errbuf);
- return false;
- }
-
- if (-1 == err) {
- FD_ZERO(&fdset);
- FD_SET(sockfd, &fdset);
- timeout.tv_sec = NTS_KE_TIMEOUT;
- timeout.tv_usec = 0;
-
- if (0 == select(sockfd + 1, NULL, &fdset, NULL, &timeout)) {
- msyslog(LOG_INFO, "NTSc: connect_TCP_socket: timeout");
- return false;
- }
-
- /* It's ready, either connected or error. */
- if (-1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &so_error, &so_len)) {
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
- msyslog(LOG_INFO, "NTSc: connect_TCP_socket: getsockopt failed: %s", errbuf);
- return false;
- }
-
- if (0 != so_error) {
- ntp_strerror_r(so_error, errbuf, sizeof(errbuf));
- msyslog(LOG_INFO, "NTSc: connect_TCP_socket: connect failed: %s", errbuf);
- return false;
- }
- }
-
- err = fcntl(sockfd, F_SETFL, 0); /* turn off O_NONBLOCK */
- if (-1 == err) {
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
- msyslog(LOG_INFO, "NTSc: can't unset O_NONBLOCK %s", errbuf);
- return false;
- }
-
- return true;
+ char errbuf[100];
+ int err;
+ fd_set fdset;
+ struct timeval timeout;
+ int so_error;
+ socklen_t so_len = sizeof(so_error);
+
+ err = fcntl(sockfd, F_SETFL, O_NONBLOCK);
+ if (-1 == err) {
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ msyslog(LOG_INFO, "NTSc: can't set O_NONBLOCK %s", errbuf);
+ return false;
+ }
+ err = connect(sockfd, addr->ai_addr, addr->ai_addrlen);
+ /* The usual nonblocking case is -1 and errno == EINPROGRESS.
+ * A fast local connection can also succeed immediately.
+ * Getting connected should be possible if the scheduler
+ * avoids us for long enough.
+ * Other errors may be possible. No route?
+ * I haven't seen that yet. HGM, 2020 Jan 19
+ */
+ if (-1 == err && EINPROGRESS != errno) {
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ msyslog(LOG_INFO, "NTSc: connect_TCP_socket: connect failed: %s", errbuf);
+ return false;
+ }
+
+ if (-1 == err) {
+ FD_ZERO(&fdset);
+ FD_SET(sockfd, &fdset);
+ timeout.tv_sec = NTS_KE_TIMEOUT;
+ timeout.tv_usec = 0;
+
+ if (0 == select(sockfd + 1, NULL, &fdset, NULL, &timeout)) {
+ msyslog(LOG_INFO, "NTSc: connect_TCP_socket: timeout");
+ return false;
+ }
+
+ // It's ready, either connected or error.
+ if (-1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &so_error, &so_len)) {
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ msyslog(LOG_INFO, "NTSc: connect_TCP_socket: getsockopt failed: %s", errbuf);
+ return false;
+ }
+
+ if (0 != so_error) {
+ ntp_strerror_r(so_error, errbuf, sizeof(errbuf));
+ msyslog(LOG_INFO, "NTSc: connect_TCP_socket: connect failed: %s", errbuf);
+ return false;
+ }
+ }
+
+ err = fcntl(sockfd, F_SETFL, 0); // turn off O_NONBLOCK
+ if (-1 == err) {
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ msyslog(LOG_INFO, "NTSc: can't unset O_NONBLOCK %s", errbuf);
+ return false;
+ }
+
+ return true;
}
void set_hostname(SSL *ssl, const char *hostname) {
- char host[256], *tmp;
-
- /* chop off [] and trailing :port */
- strlcpy(host, hostname, sizeof(host));
- if ('[' == host[0]) {
- /* IPv6 literal, [...] format */
- strlcpy(host, hostname+1, sizeof(host));
- tmp = strchr(host, ']');
- if (NULL != tmp) *tmp = 0;
- } else {
- /* not IPv6 [...] format */
- tmp = strchr(host, ':');
- if (NULL != tmp) {
- *tmp = 0;
- }
- }
+ char host[256], *tmp;
+
+ // chop off [] and trailing :port
+ strlcpy(host, hostname, sizeof(host));
+ if ('[' == host[0]) {
+ // IPv6 literal, [...] format
+ strlcpy(host, hostname+1, sizeof(host));
+ tmp = strchr(host, ']');
+ if (NULL != tmp) *tmp = 0;
+ } else {
+ // not IPv6 [...] format
+ tmp = strchr(host, ':');
+ if (NULL != tmp) {
+ *tmp = 0;
+ }
+ }
/* https://wiki.openssl.org/index.php/Hostname_validation
* draft-ietf-uta-rfc6125bis section 3 relaxes the restrictions around the use
* of wildcards to make it clear that they're permitted unless specifically
* prohibited in an RFC
*/
- SSL_set_hostflags(ssl, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+ SSL_set_hostflags(ssl, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
#if OPENSSL_VERSION_NUMBER >= 0x40000000L
{
- sockaddr_u addr;
- if (is_ip_address(host, AF_UNSPEC, &addr))
- SSL_set1_ipaddr(ssl, host);
- else {
- SSL_set1_dnsname(ssl, host);
- SSL_set_tlsext_host_name(ssl, host);
- }
+ sockaddr_u addr;
+ if (is_ip_address(host, AF_UNSPEC, &addr))
+ SSL_set1_ipaddr(ssl, host);
+ else {
+ SSL_set1_dnsname(ssl, host);
+ SSL_set_tlsext_host_name(ssl, host);
+ }
}
#else
- SSL_set1_host(ssl, host); /* DEPRECATED in OpenSSL 4.0 */
- SSL_set_tlsext_host_name(ssl, host);
+ SSL_set1_host(ssl, host); // DEPRECATED in OpenSSL 4.0
+ SSL_set_tlsext_host_name(ssl, host);
#endif
- msyslog(LOG_DEBUG, "NTSc: set cert host: %s", host);
+ msyslog(LOG_DEBUG, "NTSc: set cert host: %s", host);
}
@@ -521,394 +521,394 @@ void set_hostname(SSL *ssl, const char *hostname) {
// DNS:*.time.nl, DNS:time.nl
bool check_certificate(SSL *ssl, struct peer* peer) {
- X509 *cert = SSL_get_peer_certificate(ssl);
- const X509_NAME *certname;
- GENERAL_NAMES *gens;
- char name[200];
- int certok;
- int numgens = 0;
-
- if (NULL == cert) {
- msyslog(LOG_INFO, "NTSc: No certificate");
- if (!(FLAG_NTS_NOVAL & peer->cfg.flags))
- return false;
- return true;
- }
-
- 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);
- /* print SAN:DNS strings */
- gens = X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0);
- if (gens) {
- char buff[150];
- numgens = sk_GENERAL_NAME_num(gens);
- buff[0] = 0;
- for (int i = 0; i<numgens; i++) {
- const GENERAL_NAME *gen;
- const char *dnsname;
- unsigned int len;
- gen = sk_GENERAL_NAME_value(gens, i);
- if (gen->type != GEN_DNS)
- continue;
- // string is NUL terminated but may have internal NULs
- len = (unsigned int)ASN1_STRING_length(gen->d.ia5);
- dnsname = (const char *)ASN1_STRING_get0_data(gen->d.ia5);
- if (0 != buff[0])
- strlcat(buff, ", ", sizeof(buff));
- strlcat(buff, dnsname, sizeof(buff));
- if (len != strlen(dnsname))
- strlcat(buff, "??", sizeof(buff));
- }
- msyslog(LOG_INFO, "NTSc: SAN:DNS %s", buff);
- GENERAL_NAMES_free(gens);
- }
- if (0 == numgens) {
- const char *peername = SSL_get0_peername(ssl);
- msyslog(LOG_INFO, "NTSc: matching with subject:CN %s", peername);
- } else if (1 > numgens) {
- const char *peername = SSL_get0_peername(ssl);
- msyslog(LOG_INFO, "NTSc: matching with SAN:DNS: %s", peername);
- }
- X509_free(cert);
- 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) {
- msyslog(LOG_INFO, "NTSc: noval - accepting invalid cert.");
- return true;
- }
- return false;
- }
- return true;
+ X509 *cert = SSL_get_peer_certificate(ssl);
+ const X509_NAME *certname;
+ GENERAL_NAMES *gens;
+ char name[200];
+ int certok;
+ int numgens = 0;
+
+ if (NULL == cert) {
+ msyslog(LOG_INFO, "NTSc: No certificate");
+ if (!(FLAG_NTS_NOVAL & peer->cfg.flags))
+ return false;
+ return true;
+ }
+
+ 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);
+ // print SAN:DNS strings
+ gens = X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0);
+ if (gens) {
+ char buff[150];
+ numgens = sk_GENERAL_NAME_num(gens);
+ buff[0] = 0;
+ for (int i = 0; i<numgens; i++) {
+ const GENERAL_NAME *gen;
+ const char *dnsname;
+ unsigned int len;
+ gen = sk_GENERAL_NAME_value(gens, i);
+ if (gen->type != GEN_DNS)
+ continue;
+ // string is NUL terminated but may have internal NULs
+ len = (unsigned int)ASN1_STRING_length(gen->d.ia5);
+ dnsname = (const char *)ASN1_STRING_get0_data(gen->d.ia5);
+ if (0 != buff[0])
+ strlcat(buff, ", ", sizeof(buff));
+ strlcat(buff, dnsname, sizeof(buff));
+ if (len != strlen(dnsname))
+ strlcat(buff, "??", sizeof(buff));
+ }
+ msyslog(LOG_INFO, "NTSc: SAN:DNS %s", buff);
+ GENERAL_NAMES_free(gens);
+ }
+ if (0 == numgens) {
+ const char *peername = SSL_get0_peername(ssl);
+ msyslog(LOG_INFO, "NTSc: matching with subject:CN %s", peername);
+ } else if (1 > numgens) {
+ const char *peername = SSL_get0_peername(ssl);
+ msyslog(LOG_INFO, "NTSc: matching with SAN:DNS: %s", peername);
+ }
+ X509_free(cert);
+ 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) {
+ msyslog(LOG_INFO, "NTSc: noval - accepting invalid cert.");
+ return true;
+ }
+ return false;
+ }
+ return true;
}
bool check_alpn(SSL *ssl, struct peer* peer, const char *hostname) {
- UNUSED_ARG(peer);
- const unsigned char *data;
- unsigned int len;
- SSL_get0_alpn_selected(ssl, &data, &len);
- if (0 == len) {
- msyslog(LOG_DEBUG, "NTSc: No ALPN from %s (%s)",
- hostname, SSL_get_version(ssl));
- return false;
- }
- /* For now, we only support one version.
- * This will get more complicated when version 2 arrives. */
- if (len != 7 ||
- 0 != memcmp(data, "ntske/1", len)) {
- /* copy data over so we can print it. */
- /* don't read past end of data */
- unsigned int i, l;
- char buff [16];
- l = min(len, sizeof(buff)-1);
- memcpy(buff, data, l);
- buff[l] = '\0';
- for (i=0; i<l; i++) {
- if (!isgraph((int)buff[i])) {
- buff[i] = '*'; /* fix non-printing crap */
- }
- }
- msyslog(LOG_DEBUG, "NTSc: Strange ALPN %s (%u) from %s",
- buff, len, hostname);
- return false;
- }
- msyslog(LOG_DEBUG, "NTSc: Good ALPN from %s", hostname);
-
- return true;
+ UNUSED_ARG(peer);
+ const unsigned char *data;
+ unsigned int len;
+ SSL_get0_alpn_selected(ssl, &data, &len);
+ if (0 == len) {
+ msyslog(LOG_DEBUG, "NTSc: No ALPN from %s (%s)",
+ hostname, SSL_get_version(ssl));
+ return false;
+ }
+ /* For now, we only support one version.
+ * This will get more complicated when version 2 arrives. */
+ if (len != 7 ||
+ 0 != memcmp(data, "ntske/1", len)) {
+ // copy data over so we can print it.
+ // don't read past end of data
+ unsigned int i, l;
+ char buff [16];
+ l = min(len, sizeof(buff)-1);
+ memcpy(buff, data, l);
+ buff[l] = '\0';
+ for (i=0; i<l; i++) {
+ if (!isgraph((int)buff[i])) {
+ buff[i] = '*'; // fix non-printing crap
+ }
+ }
+ msyslog(LOG_DEBUG, "NTSc: Strange ALPN %s (%u) from %s",
+ buff, len, hostname);
+ return false;
+ }
+ msyslog(LOG_DEBUG, "NTSc: Good ALPN from %s", hostname);
+
+ return true;
}
bool nts_make_keys(SSL *ssl, uint16_t aead, uint8_t *c2s, uint8_t *s2c, int keylen) {
- const char *label = "EXPORTER-network-time-security";
- unsigned char context[5];
- context[0] = (nts_protocol_NTP >> 8) & 0xFF;
- context[1] = nts_protocol_NTP & 0xFF;
- context[2] = (aead >> 8) & 0xFF;
- context[3] = aead & 0xFF;
- context[4] = 0x00;
- if (1 != SSL_export_keying_material(ssl, c2s, keylen,
- label, strlen(label),
- context, 5, 1)) {
- msyslog(LOG_ERR, "NTS: Error making c2s\n");
- nts_log_ssl_error();
- return false;
- }
- context[4] = 0x01;
- if (1 != SSL_export_keying_material(ssl, s2c, keylen,
- label, strlen(label),
- context, 5, 1)) {
- msyslog(LOG_ERR, "NTS: Error making s2c\n");
- nts_log_ssl_error();
- return false;
- }
- return true;
+ const char *label = "EXPORTER-network-time-security";
+ unsigned char context[5];
+ context[0] = (nts_protocol_NTP >> 8) & 0xFF;
+ context[1] = nts_protocol_NTP & 0xFF;
+ context[2] = (aead >> 8) & 0xFF;
+ context[3] = aead & 0xFF;
+ context[4] = 0x00;
+ if (1 != SSL_export_keying_material(ssl, c2s, keylen,
+ label, strlen(label),
+ context, 5, 1)) {
+ msyslog(LOG_ERR, "NTS: Error making c2s\n");
+ nts_log_ssl_error();
+ return false;
+ }
+ context[4] = 0x01;
+ if (1 != SSL_export_keying_material(ssl, s2c, keylen,
+ label, strlen(label),
+ context, 5, 1)) {
+ msyslog(LOG_ERR, "NTS: Error making s2c\n");
+ nts_log_ssl_error();
+ return false;
+ }
+ return true;
}
bool nts_client_send_request(SSL *ssl, struct peer* peer) {
- uint8_t buff[1000];
- int used, transferred;
- bool success;
- const char *errtxt = NULL;
+ uint8_t buff[1000];
+ int used, transferred;
+ bool success;
+ const char *errtxt = NULL;
- success = nts_client_send_request_core(buff, sizeof(buff), &used, peer);
- if (!success) {
- return false;
- }
+ success = nts_client_send_request_core(buff, sizeof(buff), &used, peer);
+ if (!success) {
+ return false;
+ }
- transferred = nts_ssl_write(ssl, buff, used, &errtxt);
- if (used != transferred)
- return false;
+ transferred = nts_ssl_write(ssl, buff, used, &errtxt);
+ if (used != transferred)
+ return false;
- return true;
+ return true;
}
bool nts_client_send_request_core(uint8_t *buff, int buf_size, int *used, struct peer* peer) {
- struct BufCtl_t buf;
- uint16_t aead = NO_AEAD;
-
- buf.next = buff;
- buf.left = buf_size;
-
- /* 4.1.2 Next Protocol, 0 for NTP */
- ke_append_record_uint16(&buf,
- NTS_CRITICAL+nts_next_protocol_negotiation, nts_protocol_NTP);
-
- /* 4.1.5 AEAD Algorithm List */
- // FIXME should be : separated list
-
- if ((NO_AEAD == aead) && (NULL != peer->cfg.nts_cfg.aead))
- aead = nts_string_to_aead(peer->cfg.nts_cfg.aead);
- if ((NO_AEAD == aead) && (NULL != ntsconfig.aead))
- aead = nts_string_to_aead(ntsconfig.aead);
- if (NO_AEAD == aead)
- aead = AEAD_AES_SIV_CMAC_256;
- ke_append_record_uint16(&buf, nts_algorithm_negotiation, aead);
-
- /* 4.1.1: End, Critical */
- ke_append_record_null(&buf, NTS_CRITICAL+nts_end_of_message);
-
- *used = buf_size-buf.left;
- if (*used >= (int)(buf_size - 10)) {
- msyslog(LOG_ERR, "ERR-NTSc: buffer overflow: %d, %ld",
- *used, (long)buf_size);
- exit(2);
- }
- return true;
+ struct BufCtl_t buf;
+ uint16_t aead = NO_AEAD;
+
+ buf.next = buff;
+ buf.left = buf_size;
+
+ // 4.1.2 Next Protocol, 0 for NTP
+ ke_append_record_uint16(&buf,
+ NTS_CRITICAL+nts_next_protocol_negotiation, nts_protocol_NTP);
+
+ // 4.1.5 AEAD Algorithm List
+ // FIXME should be : separated list
+
+ if ((NO_AEAD == aead) && (NULL != peer->cfg.nts_cfg.aead))
+ aead = nts_string_to_aead(peer->cfg.nts_cfg.aead);
+ if ((NO_AEAD == aead) && (NULL != ntsconfig.aead))
+ aead = nts_string_to_aead(ntsconfig.aead);
+ if (NO_AEAD == aead)
+ aead = AEAD_AES_SIV_CMAC_256;
+ ke_append_record_uint16(&buf, nts_algorithm_negotiation, aead);
+
+ // 4.1.1: End, Critical
+ ke_append_record_null(&buf, NTS_CRITICAL+nts_end_of_message);
+
+ *used = buf_size-buf.left;
+ if (*used >= (int)(buf_size - 10)) {
+ msyslog(LOG_ERR, "ERR-NTSc: buffer overflow: %d, %ld",
+ *used, (long)buf_size);
+ exit(2);
+ }
+ return true;
}
bool nts_client_process_response(SSL *ssl, struct peer* peer) {
- uint8_t buff[2048]; /* RFC 4. says SHOULD be 65K */
- int transferred;
- const char *errtxt = NULL;
+ uint8_t buff[2048]; // RFC 4. says SHOULD be 65K
+ int transferred;
+ const char *errtxt = NULL;
- transferred = nts_ssl_read(ssl, buff, sizeof(buff), &errtxt);
- if (0 >= transferred)
- return false;
- msyslog(LOG_ERR, "NTSc: read %d bytes", transferred);
+ transferred = nts_ssl_read(ssl, buff, sizeof(buff), &errtxt);
+ if (0 >= transferred)
+ return false;
+ msyslog(LOG_ERR, "NTSc: read %d bytes", transferred);
- return nts_client_process_response_core(buff, transferred, peer);
+ return nts_client_process_response_core(buff, transferred, peer);
}
bool nts_client_process_response_core(uint8_t *buff, int transferred, struct peer* peer) {
- int idx;
- struct BufCtl_t buf;
-
- peer->nts_state.cookielen = 0;
- peer->nts_state.aead = NO_AEAD;
- peer->nts_state.keylen = 0;
- peer->nts_state.writeIdx = 0;
- peer->nts_state.readIdx = 0;
- peer->nts_state.count = 0;
-
- buf.next = buff;
- buf.left = transferred;
- while (buf.left >= NTS_KE_HDR_LNG) {
- uint16_t type, data, port;
- bool critical = false;
- int length, keylength;
- char errbuf[100];
+ int idx;
+ struct BufCtl_t buf;
+
+ peer->nts_state.cookielen = 0;
+ peer->nts_state.aead = NO_AEAD;
+ peer->nts_state.keylen = 0;
+ peer->nts_state.writeIdx = 0;
+ peer->nts_state.readIdx = 0;
+ peer->nts_state.count = 0;
+
+ buf.next = buff;
+ buf.left = transferred;
+ while (buf.left >= NTS_KE_HDR_LNG) {
+ uint16_t type, data, port;
+ bool critical = false;
+ int length, keylength;
+ char errbuf[100];
#define MAX_SERVER 100
- char server[MAX_SERVER];
-
- type = ke_next_record(&buf, &length);
- if (length > buf.left){
- msyslog(LOG_ERR, "NTSc: Chunk too big: 0x%x, %d, %d",
- type, buf.left, length);
- return false;
- }
- if (NTS_CRITICAL & type) {
- critical = true;
- type &= ~NTS_CRITICAL;
- }
- if (0) // Handy for debugging but very verbose
- msyslog(LOG_ERR, "NTSc: Record: T=%d, L=%d, C=%d", type, length, critical);
- switch (type) {
- case nts_error:
- if (sizeof(data) != length) {
- msyslog(LOG_ERR, "NTSc: wrong length on error: %d", length);
- return false;
- }
- data = next_uint16(&buf);
- msyslog(LOG_ERR, "NTSc: error: %d", data);
- return false;
- case nts_next_protocol_negotiation:
- if (sizeof(data) != length) {
- msyslog(LOG_ERR, "NTSc: NPN-Wrong length: %d", length);
- return false;
- }
- data = next_uint16(&buf);
- if (data != nts_protocol_NTP) {
- msyslog(LOG_ERR, "NTSc: NPN-Bad data: %d", data);
- return false;
- }
- break;
- case nts_algorithm_negotiation:
- if (sizeof(data) != length) {
- msyslog(LOG_ERR, "NTSc: AN-Wrong length: %d", length);
- return false;
- }
- data = next_uint16(&buf);
- keylength = nts_get_key_length(data);
- if (0 == keylength) {
- msyslog(LOG_ERR, "NTSc: AN-Unsupported AEAN type: %d", data);
- return false;
- }
- peer->nts_state.aead = data;
- break;
- case nts_new_cookie:
- if (NTS_MAX_COOKIELEN < length) {
- msyslog(LOG_ERR, "NTSc: NC cookie too big: %d", length);
- return false;
- }
- if (0 == peer->nts_state.cookielen)
- peer->nts_state.cookielen = length;
- if (length != peer->nts_state.cookielen) {
- msyslog(LOG_ERR, "NTSc: Cookie length mismatch %d, %d.",
- length, peer->nts_state.cookielen);
- return false;
- }
- idx = peer->nts_state.writeIdx;
- if (NTS_MAX_COOKIES <= peer->nts_state.count) {
- msyslog(LOG_ERR, "NTSc: Extra cookie ignored.");
- buf.next += length;
- buf.left -= length;
- break;
- }
- next_bytes(&buf, (uint8_t*)&peer->nts_state.cookies[idx], length);
- peer->nts_state.writeIdx++;
- peer->nts_state.writeIdx = peer->nts_state.writeIdx % NTS_MAX_COOKIES;
- peer->nts_state.count++;
- break;
- case nts_server_negotiation:
- if (MAX_SERVER < (length+1)) {
- msyslog(LOG_ERR, "NTSc: server string too long %d.", length);
- return false;
- }
- next_bytes(&buf, (uint8_t *)server, length);
- server[length] = '\0';
- /* save port in case port specified before server */
- port = SRCPORT(&sockaddr);
- if (!nts_server_lookup(server, &sockaddr, AF(&peer->srcadr)))
- return false;
- SET_PORT(&sockaddr, port);
- socktoa_r(&sockaddr, errbuf, sizeof(errbuf));
- msyslog(LOG_ERR, "NTSc: Using server %s=>%s", server, errbuf);
- break;
- case nts_port_negotiation:
- if (sizeof(port) != length) {
- msyslog(LOG_ERR, "NTSc: PN-Wrong length: %d, %d",
- length, critical);
- return false;
- }
- port = next_uint16(&buf);
- SET_PORT(&sockaddr, port);
- msyslog(LOG_ERR, "NTSc: Using port %d", port);
- break;
- case nts_end_of_message:
- if ((0 != length) || !critical) {
- msyslog(LOG_ERR, "NTSc: EOM-Wrong length or not Critical: %d, %d",
- length, critical);
- return false;
- }
- if (0 != buf.left) {
- msyslog(LOG_ERR, "NTSc: EOM not at end: %d", buf.left);
- return false;
- }
- break;
- default:
- msyslog(LOG_ERR, "NTSc: received strange type: T=%d, C=%d, L=%d",
- type, critical, length);
- if (critical) {
- return false;
- }
- buf.next += length;
- buf.left -= length;
- break;
- } /* case */
- } /* while */
-
-// FIXME: Need to check for EOM -- read more??
- if (buf.left > 0)
- return false;
-
- if (NO_AEAD == peer->nts_state.aead) {
- msyslog(LOG_ERR, "NTSc: No AEAD algorithm.");
- return false;
- }
- if (0 == peer->nts_state.count) {
- msyslog(LOG_ERR, "NTSc: No cookies.");
- return false;
- }
-
- msyslog(LOG_ERR, "NTSc: Got %d cookies, length %d, aead=%d.",
- peer->nts_state.count, peer->nts_state.cookielen, peer->nts_state.aead);
- return true;
+ char server[MAX_SERVER];
+
+ type = ke_next_record(&buf, &length);
+ if (length > buf.left){
+ msyslog(LOG_ERR, "NTSc: Chunk too big: 0x%x, %d, %d",
+ type, buf.left, length);
+ return false;
+ }
+ if (NTS_CRITICAL & type) {
+ critical = true;
+ type &= ~NTS_CRITICAL;
+ }
+ if (0) // Handy for debugging but very verbose
+ msyslog(LOG_ERR, "NTSc: Record: T=%d, L=%d, C=%d", type, length, critical);
+ switch (type) {
+ case nts_error:
+ if (sizeof(data) != length) {
+ msyslog(LOG_ERR, "NTSc: wrong length on error: %d", length);
+ return false;
+ }
+ data = next_uint16(&buf);
+ msyslog(LOG_ERR, "NTSc: error: %d", data);
+ return false;
+ case nts_next_protocol_negotiation:
+ if (sizeof(data) != length) {
+ msyslog(LOG_ERR, "NTSc: NPN-Wrong length: %d", length);
+ return false;
+ }
+ data = next_uint16(&buf);
+ if (data != nts_protocol_NTP) {
+ msyslog(LOG_ERR, "NTSc: NPN-Bad data: %d", data);
+ return false;
+ }
+ break;
+ case nts_algorithm_negotiation:
+ if (sizeof(data) != length) {
+ msyslog(LOG_ERR, "NTSc: AN-Wrong length: %d", length);
+ return false;
+ }
+ data = next_uint16(&buf);
+ keylength = nts_get_key_length(data);
+ if (0 == keylength) {
+ msyslog(LOG_ERR, "NTSc: AN-Unsupported AEAN type: %d", data);
+ return false;
+ }
+ peer->nts_state.aead = data;
+ break;
+ case nts_new_cookie:
+ if (NTS_MAX_COOKIELEN < length) {
+ msyslog(LOG_ERR, "NTSc: NC cookie too big: %d", length);
+ return false;
+ }
+ if (0 == peer->nts_state.cookielen)
+ peer->nts_state.cookielen = length;
+ if (length != peer->nts_state.cookielen) {
+ msyslog(LOG_ERR, "NTSc: Cookie length mismatch %d, %d.",
+ length, peer->nts_state.cookielen);
+ return false;
+ }
+ idx = peer->nts_state.writeIdx;
+ if (NTS_MAX_COOKIES <= peer->nts_state.count) {
+ msyslog(LOG_ERR, "NTSc: Extra cookie ignored.");
+ buf.next += length;
+ buf.left -= length;
+ break;
+ }
+ next_bytes(&buf, (uint8_t*)&peer->nts_state.cookies[idx], length);
+ peer->nts_state.writeIdx++;
+ peer->nts_state.writeIdx = peer->nts_state.writeIdx % NTS_MAX_COOKIES;
+ peer->nts_state.count++;
+ break;
+ case nts_server_negotiation:
+ if (MAX_SERVER < (length+1)) {
+ msyslog(LOG_ERR, "NTSc: server string too long %d.", length);
+ return false;
+ }
+ next_bytes(&buf, (uint8_t *)server, length);
+ server[length] = '\0';
+ // save port in case port specified before server
+ port = SRCPORT(&sockaddr);
+ if (!nts_server_lookup(server, &sockaddr, AF(&peer->srcadr)))
+ return false;
+ SET_PORT(&sockaddr, port);
+ socktoa_r(&sockaddr, errbuf, sizeof(errbuf));
+ msyslog(LOG_ERR, "NTSc: Using server %s=>%s", server, errbuf);
+ break;
+ case nts_port_negotiation:
+ if (sizeof(port) != length) {
+ msyslog(LOG_ERR, "NTSc: PN-Wrong length: %d, %d",
+ length, critical);
+ return false;
+ }
+ port = next_uint16(&buf);
+ SET_PORT(&sockaddr, port);
+ msyslog(LOG_ERR, "NTSc: Using port %d", port);
+ break;
+ case nts_end_of_message:
+ if ((0 != length) || !critical) {
+ msyslog(LOG_ERR, "NTSc: EOM-Wrong length or not Critical: %d, %d",
+ length, critical);
+ return false;
+ }
+ if (0 != buf.left) {
+ msyslog(LOG_ERR, "NTSc: EOM not at end: %d", buf.left);
+ return false;
+ }
+ break;
+ default:
+ msyslog(LOG_ERR, "NTSc: received strange type: T=%d, C=%d, L=%d",
+ type, critical, length);
+ if (critical) {
+ return false;
+ }
+ buf.next += length;
+ buf.left -= length;
+ break;
+ } // case
+ } // while
+
+// FIXME: Need to check for EOM -- read more??
+ if (buf.left > 0)
+ return false;
+
+ if (NO_AEAD == peer->nts_state.aead) {
+ msyslog(LOG_ERR, "NTSc: No AEAD algorithm.");
+ return false;
+ }
+ if (0 == peer->nts_state.count) {
+ msyslog(LOG_ERR, "NTSc: No cookies.");
+ return false;
+ }
+
+ msyslog(LOG_ERR, "NTSc: Got %d cookies, length %d, aead=%d.",
+ peer->nts_state.count, peer->nts_state.cookielen, peer->nts_state.aead);
+ return true;
}
bool nts_set_cert_search(SSL_CTX *ctx, const char *filename) {
- struct stat statbuf;
- char errbuf[100];
- if (NULL == filename) {
- msyslog(LOG_INFO, "NTSc: Using system default root certificates.");
- SSL_CTX_set_default_verify_paths(ctx); // Use system root certs
- return true;
- }
- if (0 == stat(filename, &statbuf)) {
- if (S_ISDIR(statbuf.st_mode)) {
- if (1 != SSL_CTX_load_verify_locations(
- ctx, NULL, filename)) {
- msyslog(LOG_INFO, "NTSc: Can't use %s as dir for root certificates.", filename);
- nts_log_ssl_error();
- return false;
- }
- msyslog(LOG_INFO, "NTSc: Using dir %s for root certificates.", filename);
- return true;
- }
- if (S_ISREG(statbuf.st_mode)) {
- if (1 != SSL_CTX_load_verify_locations(
- ctx, filename, NULL)) {
- msyslog(LOG_INFO, "NTSc: Can't use %s as file for root certificates.", filename);
- nts_log_ssl_error();
- return false;
- }
- msyslog(LOG_INFO, "NTSc: Using file %s for root certificates.", filename);
- return true;
- }
- msyslog(LOG_ERR, "NTSc: cert dir/file isn't dir or file: %s. mode 0x%x",
- filename, statbuf.st_mode);
- return false;
- }
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
- msyslog(LOG_ERR, "NTSc: can't stat cert dir/file: %s, %s",
- filename, errbuf);
- return false;
+ struct stat statbuf;
+ char errbuf[100];
+ if (NULL == filename) {
+ msyslog(LOG_INFO, "NTSc: Using system default root certificates.");
+ SSL_CTX_set_default_verify_paths(ctx); // Use system root certs
+ return true;
+ }
+ if (0 == stat(filename, &statbuf)) {
+ if (S_ISDIR(statbuf.st_mode)) {
+ if (1 != SSL_CTX_load_verify_locations(
+ ctx, NULL, filename)) {
+ msyslog(LOG_INFO, "NTSc: Can't use %s as dir for root certificates.", filename);
+ nts_log_ssl_error();
+ return false;
+ }
+ msyslog(LOG_INFO, "NTSc: Using dir %s for root certificates.", filename);
+ return true;
+ }
+ if (S_ISREG(statbuf.st_mode)) {
+ if (1 != SSL_CTX_load_verify_locations(
+ ctx, filename, NULL)) {
+ msyslog(LOG_INFO, "NTSc: Can't use %s as file for root certificates.", filename);
+ nts_log_ssl_error();
+ return false;
+ }
+ msyslog(LOG_INFO, "NTSc: Using file %s for root certificates.", filename);
+ return true;
+ }
+ msyslog(LOG_ERR, "NTSc: cert dir/file isn't dir or file: %s. mode 0x%x",
+ filename, statbuf.st_mode);
+ return false;
+ }
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ msyslog(LOG_ERR, "NTSc: can't stat cert dir/file: %s, %s",
+ filename, errbuf);
+ return false;
}
/* The -4/-6 option is used for both the NTS-KE server and the NTP server.
* That will break if the KE server returns a name that returns only an
@@ -916,31 +916,31 @@ bool nts_set_cert_search(SSL_CTX *ctx, const char *filename) {
* We could fix that by trying again with AF_UNSPEC.
*/
bool nts_server_lookup(char *server, sockaddr_u *addr, int af) {
- struct addrinfo hints;
- struct addrinfo *answer = NULL; /* init to keep oss-fuzz happy */
- int gai_rc;
+ struct addrinfo hints;
+ struct addrinfo *answer = NULL; // init to keep oss-fuzz happy
+ int gai_rc;
- ZERO(hints);
- hints.ai_protocol = IPPROTO_UDP;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_family = af;
+ ZERO(hints);
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_family = af;
- gai_rc = getaddrinfo(server, NTS_KE_PORTA, &hints, &answer);
- if (0 != gai_rc) {
- msyslog(LOG_INFO, "NTSc: DNS error trying to lookup %s: %d, %s",
- server, gai_rc, gai_strerror(gai_rc));
- return false;
- }
+ gai_rc = getaddrinfo(server, NTS_KE_PORTA, &hints, &answer);
+ if (0 != gai_rc) {
+ msyslog(LOG_INFO, "NTSc: DNS error trying to lookup %s: %d, %s",
+ server, gai_rc, gai_strerror(gai_rc));
+ return false;
+ }
- if (NULL == answer)
- return false;
+ if (NULL == answer)
+ return false;
- if (sizeof(sockaddr_u) >= answer->ai_addrlen)
- memcpy(addr, answer->ai_addr, answer->ai_addrlen);
+ if (sizeof(sockaddr_u) >= answer->ai_addrlen)
+ memcpy(addr, answer->ai_addr, answer->ai_addrlen);
- freeaddrinfo(answer);
+ freeaddrinfo(answer);
- return true;
+ return true;
}
-/* end */
+// end
=====================================
ntpd/nts_cookie.c
=====================================
@@ -81,7 +81,7 @@
* #define is in include/nts.h
*/
-/* cookies use same AEAD algorithms as wire */
+// cookies use same AEAD algorithms as wire
/* This determines which algorithm we use.
* Valid choices are 32, 48, and 64
* making this a variable rather than #define
@@ -90,7 +90,7 @@
* You can change that by editing the keys file.
*/
int K_length = AEAD_AES_SIV_CMAC_256_KEYLEN;
-time_t K_time = 0; /* time K was created, 0 for none */
+time_t K_time = 0; // time K was created, 0 for none
struct NTS_Key nts_keys[NTS_nKEYS];
int nts_nKeys = 0;
@@ -105,11 +105,11 @@ void nts_lock_cookielock(void);
void nts_unlock_cookielock(void);
// FIXME AEAD_LENGTH
-/* Associated data: aead (rounded up to 4) plus NONCE */
+// Associated data: aead (rounded up to 4) plus NONCE
#define AD_LENGTH 20
#define AEAD_LENGTH 4
-/* cookie_ctx needed for client side */
+// cookie_ctx needed for client side
bool nts_cookie_init(void) {
cookie_ctx = AES_SIV_CTX_new();
if (NULL == cookie_ctx) {
@@ -119,16 +119,16 @@ bool nts_cookie_init(void) {
return true;
}
-/* cookie key needed for server side */
+// cookie key needed for server side
bool nts_cookie_init2(void) {
- bool OK = true;
- if (!nts_read_cookie_keys()) {
- /* Can't read cookie file. Make one */
- nts_make_cookie_key();
- K_time = time(NULL);
- nts_write_cookie_keys();
- }
- return OK;
+ bool OK = true;
+ if (!nts_read_cookie_keys()) {
+ // Can't read cookie file. Make one
+ nts_make_cookie_key();
+ K_time = time(NULL);
+ nts_write_cookie_keys();
+ }
+ return OK;
}
/* Rotate key -- 24 hours after last rotation
@@ -142,83 +142,83 @@ bool nts_cookie_init2(void) {
// Just uncommenting the next line will generate a warning reminder.
// #define SecondsPerDay 3600
void nts_cookie_timer(void) {
- time_t now;
- if (0 == K_time) {
- return;
- }
- now = time(NULL);
- if (SecondsPerDay > (now-K_time)) {
- return;
- }
- nts_make_cookie_key();
- /* In case we were off for many days. */
- while (SecondsPerDay < (now-K_time)) {
- K_time += SecondsPerDay;
- }
- if (nts_write_cookie_keys() )
- msyslog(LOG_INFO, "NTS: Wrote new cookie file, %d keys.", nts_nKeys);
- else
- msyslog(LOG_INFO, "NTS: Trouble writing new cookie file.");
- return;
+ time_t now;
+ if (0 == K_time) {
+ return;
+ }
+ now = time(NULL);
+ if (SecondsPerDay > (now-K_time)) {
+ return;
+ }
+ nts_make_cookie_key();
+ // In case we were off for many days.
+ while (SecondsPerDay < (now-K_time)) {
+ K_time += SecondsPerDay;
+ }
+ if (nts_write_cookie_keys() )
+ msyslog(LOG_INFO, "NTS: Wrote new cookie file, %d keys.", nts_nKeys);
+ else
+ msyslog(LOG_INFO, "NTS: Trouble writing new cookie file.");
+ return;
}
bool nts_read_cookie_keys(void) {
- const char *cookie_filename = NTS_COOKIE_KEY_FILE;
- FILE *in;
- unsigned long templ;
- if (NULL != ntsconfig.KI)
- cookie_filename = ntsconfig.KI;
- in = fopen(cookie_filename, "r");
- if (NULL == in) {
- char errbuf[100];
- if (ENOENT == errno)
- return false; /* File doesn't exist */
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
- msyslog(LOG_ERR, "NTSs: can't read old cookie file: %s=>%s",
- cookie_filename, errbuf);
- exit(1);
- }
- if (1 != fscanf(in, "T: %lu\n", &templ)) {
- goto bail;
- }
- K_time = templ;
- if (1 != fscanf(in, "L: %d\n", &K_length)) {
- goto bail;
- }
- if ( !((32 == K_length) || (48 == K_length) || (64 == K_length))) {
- goto bail;
- }
- nts_nKeys = 0;
- for (int i=0; i<NTS_nKEYS; i++) {
- struct NTS_Key *key = &nts_keys[i];
- if (1 != fscanf(in, "I: %u\n", &key->I)) {
- if (0 < nts_nKeys) break;
- goto bail;
- }
- if (0 != fscanf(in, "K: ")) {
- goto bail;
- }
- for (int j=0; j< K_length; j++) {
- unsigned int temp;
- if (1 != fscanf(in, "%02x", &temp)) {
- goto bail;
- }
- key->K[j] = temp;
- }
- if (0 != fscanf(in, "\n")) {
- goto bail;
- }
- nts_nKeys = i+1;
- }
- fclose(in);
- msyslog(LOG_INFO, "NTS: Read cookie file, %d keys.", nts_nKeys);
- return true;
+ const char *cookie_filename = NTS_COOKIE_KEY_FILE;
+ FILE *in;
+ unsigned long templ;
+ if (NULL != ntsconfig.KI)
+ cookie_filename = ntsconfig.KI;
+ in = fopen(cookie_filename, "r");
+ if (NULL == in) {
+ char errbuf[100];
+ if (ENOENT == errno)
+ return false; // File doesn't exist
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ msyslog(LOG_ERR, "NTSs: can't read old cookie file: %s=>%s",
+ cookie_filename, errbuf);
+ exit(1);
+ }
+ if (1 != fscanf(in, "T: %lu\n", &templ)) {
+ goto bail;
+ }
+ K_time = templ;
+ if (1 != fscanf(in, "L: %d\n", &K_length)) {
+ goto bail;
+ }
+ if ( !((32 == K_length) || (48 == K_length) || (64 == K_length))) {
+ goto bail;
+ }
+ nts_nKeys = 0;
+ for (int i=0; i<NTS_nKEYS; i++) {
+ struct NTS_Key *key = &nts_keys[i];
+ if (1 != fscanf(in, "I: %u\n", &key->I)) {
+ if (0 < nts_nKeys) break;
+ goto bail;
+ }
+ if (0 != fscanf(in, "K: ")) {
+ goto bail;
+ }
+ for (int j=0; j< K_length; j++) {
+ unsigned int temp;
+ if (1 != fscanf(in, "%02x", &temp)) {
+ goto bail;
+ }
+ key->K[j] = temp;
+ }
+ if (0 != fscanf(in, "\n")) {
+ goto bail;
+ }
+ nts_nKeys = i+1;
+ }
+ fclose(in);
+ msyslog(LOG_INFO, "NTS: Read cookie file, %d keys.", nts_nKeys);
+ return true;
bail:
- msyslog(LOG_ERR, "ERR: Error parsing cookie keys file");
- fclose(in);
- return false;
+ msyslog(LOG_ERR, "ERR: Error parsing cookie keys file");
+ fclose(in);
+ return false;
}
/* RFC 8915 describes a ratchet mode to make new keys
@@ -229,241 +229,241 @@ bool nts_read_cookie_keys(void) {
* they copy the key file to other systems and have them load it.
*/
void nts_make_cookie_key(void) {
- if (nts_nKeys < NTS_nKEYS) nts_nKeys++;
- for (int i=nts_nKeys-1; i>0; i--) {
- nts_keys[i] = nts_keys[i-1];
- }
- ntp_RAND_priv_bytes(nts_keys[0].K, K_length);
- ntp_RAND_bytes((uint8_t *)&nts_keys[0].I, sizeof(nts_keys[0].I));
- return;
+ if (nts_nKeys < NTS_nKEYS) nts_nKeys++;
+ for (int i=nts_nKeys-1; i>0; i--) {
+ nts_keys[i] = nts_keys[i-1];
+ }
+ ntp_RAND_priv_bytes(nts_keys[0].K, K_length);
+ ntp_RAND_bytes((uint8_t *)&nts_keys[0].I, sizeof(nts_keys[0].I));
+ return;
}
bool nts_write_cookie_keys(void) {
- const char *cookiefile = NTS_COOKIE_KEY_FILE;
- char tempfile[PATH_MAX];
- int fd;
- FILE *out;
- char errbuf[100];
- if (NULL != ntsconfig.KI)
- cookiefile = ntsconfig.KI;
- strlcpy(tempfile, cookiefile, sizeof(tempfile));
- strlcat(tempfile, "-tmp", sizeof(tempfile));
- fd = open(tempfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
- if (-1 == fd) {
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
- msyslog(LOG_ERR, "ERR: can't open %s: %s", tempfile, errbuf);
- return false;
- }
- out = fdopen(fd, "w");
- if (NULL == out) {
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
- msyslog(LOG_ERR, "ERR: can't fdopen %s: %s", tempfile, errbuf);
- close(fd);
- return false;
- }
-
- fprintf(out, "T: %lu\n", (unsigned long)K_time);
- fprintf(out, "L: %d\n", K_length);
- for (int i=0; i<nts_nKeys; i++) {
- struct NTS_Key *key = &nts_keys[i];
- fprintf(out, "I: %u\n", key->I);
- fprintf(out, "K: ");
- for (int j=0; j< K_length; j++) fprintf(out, "%02x", key->K[j]);
- fprintf(out, "\n");
- key++;
- }
- fclose(out);
+ const char *cookiefile = NTS_COOKIE_KEY_FILE;
+ char tempfile[PATH_MAX];
+ int fd;
+ FILE *out;
+ char errbuf[100];
+ if (NULL != ntsconfig.KI)
+ cookiefile = ntsconfig.KI;
+ strlcpy(tempfile, cookiefile, sizeof(tempfile));
+ strlcat(tempfile, "-tmp", sizeof(tempfile));
+ fd = open(tempfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
+ if (-1 == fd) {
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ msyslog(LOG_ERR, "ERR: can't open %s: %s", tempfile, errbuf);
+ return false;
+ }
+ out = fdopen(fd, "w");
+ if (NULL == out) {
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ msyslog(LOG_ERR, "ERR: can't fdopen %s: %s", tempfile, errbuf);
+ close(fd);
+ return false;
+ }
+
+ fprintf(out, "T: %lu\n", (unsigned long)K_time);
+ fprintf(out, "L: %d\n", K_length);
+ for (int i=0; i<nts_nKeys; i++) {
+ struct NTS_Key *key = &nts_keys[i];
+ fprintf(out, "I: %u\n", key->I);
+ fprintf(out, "K: ");
+ for (int j=0; j< K_length; j++) fprintf(out, "%02x", key->K[j]);
+ fprintf(out, "\n");
+ key++;
+ }
+ fclose(out);
if (rename(tempfile, cookiefile)) {
- ntp_strerror_r(errno, errbuf, sizeof(errbuf));
+ ntp_strerror_r(errno, errbuf, sizeof(errbuf));
msyslog(LOG_WARNING,
"LOG: Unable to rename temp cookie file %s to %s, %s",
tempfile, cookiefile, errbuf);
- return false;
- }
- return true;
+ return false;
+ }
+ return true;
}
-/* returns actual length */
+// returns actual length
int nts_make_cookie(uint8_t *cookie,
uint16_t aead,
uint8_t *c2s, uint8_t *s2c, int keylen) {
- uint8_t plaintext[NTS_MAX_COOKIELEN];
- uint8_t *nonce;
- int used, plainlength;
- bool ok;
- uint8_t * finger;
- uint32_t temp; /* keep 4 byte alignment */
- size_t left;
-
- if (NULL == cookie_ctx)
- return 0; /* We aren't initialized yet. */
-
- nts_cnt.cookie_make++;
-
- INSIST(keylen <= NTS_MAX_KEYLEN);
-
- /* collect plaintext
- * separate buffer avoids encrypt in place
- * but costs cache space
- */
- finger = plaintext;
- temp = aead;
- memcpy(finger, &temp, AEAD_LENGTH);
- finger += AEAD_LENGTH;
- memcpy(finger, c2s, keylen);
- finger += keylen;
- memcpy(finger, s2c, keylen);
- finger += keylen;
- plainlength = finger-plaintext;
-
- /* collect associated data */
- finger = cookie;
-
- memcpy(finger, &nts_keys[0].I, sizeof(nts_keys[0].I));
- finger += sizeof(nts_keys[0].I);
-
- nonce = finger;
- ntp_RAND_bytes(finger, NONCE_LENGTH);
- finger += NONCE_LENGTH;
-
- used = finger-cookie;
- left = NTS_MAX_COOKIELEN-used;
-
- nts_lock_cookielock();
-
- ok = AES_SIV_Encrypt(cookie_ctx,
- finger, &left, /* left: in: max out length, out: length used */
- nts_keys[0].K, K_length,
- nonce, NONCE_LENGTH,
- plaintext, plainlength,
- cookie, AD_LENGTH);
-
- nts_unlock_cookielock();
-
- if (!ok) {
- msyslog(LOG_ERR, "NTS: nts_make_cookie - Error from AES_SIV_Encrypt");
- /* I don't think this should happen,
- * so crash rather than work incorrectly.
- * Hal, 2019-Feb-17
- * Similar code in ntp_extens
- */
- exit(1);
- }
-
- used += left;
- INSIST(used <= NTS_MAX_COOKIELEN);
-
- return used;
+ uint8_t plaintext[NTS_MAX_COOKIELEN];
+ uint8_t *nonce;
+ int used, plainlength;
+ bool ok;
+ uint8_t * finger;
+ uint32_t temp; // keep 4 byte alignment
+ size_t left;
+
+ if (NULL == cookie_ctx)
+ return 0; // We aren't initialized yet.
+
+ nts_cnt.cookie_make++;
+
+ INSIST(keylen <= NTS_MAX_KEYLEN);
+
+ /* collect plaintext
+ * separate buffer avoids encrypt in place
+ * but costs cache space
+ */
+ finger = plaintext;
+ temp = aead;
+ memcpy(finger, &temp, AEAD_LENGTH);
+ finger += AEAD_LENGTH;
+ memcpy(finger, c2s, keylen);
+ finger += keylen;
+ memcpy(finger, s2c, keylen);
+ finger += keylen;
+ plainlength = finger-plaintext;
+
+ // collect associated data
+ finger = cookie;
+
+ memcpy(finger, &nts_keys[0].I, sizeof(nts_keys[0].I));
+ finger += sizeof(nts_keys[0].I);
+
+ nonce = finger;
+ ntp_RAND_bytes(finger, NONCE_LENGTH);
+ finger += NONCE_LENGTH;
+
+ used = finger-cookie;
+ left = NTS_MAX_COOKIELEN-used;
+
+ nts_lock_cookielock();
+
+ ok = AES_SIV_Encrypt(cookie_ctx,
+ finger, &left, // left: in: max out length, out: length used
+ nts_keys[0].K, K_length,
+ nonce, NONCE_LENGTH,
+ plaintext, plainlength,
+ cookie, AD_LENGTH);
+
+ nts_unlock_cookielock();
+
+ if (!ok) {
+ msyslog(LOG_ERR, "NTS: nts_make_cookie - Error from AES_SIV_Encrypt");
+ /* I don't think this should happen,
+ * so crash rather than work incorrectly.
+ * Hal, 2019-Feb-17
+ * Similar code in ntp_extens
+ */
+ exit(1);
+ }
+
+ used += left;
+ INSIST(used <= NTS_MAX_COOKIELEN);
+
+ return used;
}
-/* can't decrypt in place - that would trash the unauthenticated packet */
+// can't decrypt in place - that would trash the unauthenticated packet
bool nts_unpack_cookie(uint8_t *cookie, int cookielen,
uint16_t *aead,
uint8_t *c2s, uint8_t *s2c, int *keylen) {
- uint8_t *finger;
- uint8_t plaintext[NTS_MAX_COOKIELEN];
- uint8_t *nonce;
- uint32_t temp;
- size_t plainlength;
- int cipherlength;
- bool ok;
- struct NTS_Key *key;
- int i;
-
- if (NULL == cookie_ctx)
- return false; /* We aren't initialized yet. */
-
- if (0 == nts_nKeys) {
- nts_cnt.cookie_not_server++;
- return false; /* We are not a NTS enabled server. */
- }
-
- /* We may get garbage from the net */
- if (cookielen > NTS_MAX_COOKIELEN)
- return false;
-
- finger = cookie;
- key = NULL; /* squash uninitialized warning */
- for (i=0; i<nts_nKeys; i++) {
- key = &nts_keys[i];
- if (0 == memcmp(finger, &key->I, sizeof(key->I))) {
- break;
- }
- }
- nts_cnt.cookie_decode_total++; /* total attempts, includes too old */
- if (nts_nKeys == i) {
- nts_cnt.cookie_decode_too_old++;
- return false;
+ uint8_t *finger;
+ uint8_t plaintext[NTS_MAX_COOKIELEN];
+ uint8_t *nonce;
+ uint32_t temp;
+ size_t plainlength;
+ int cipherlength;
+ bool ok;
+ struct NTS_Key *key;
+ int i;
+
+ if (NULL == cookie_ctx)
+ return false; // We aren't initialized yet.
+
+ if (0 == nts_nKeys) {
+ nts_cnt.cookie_not_server++;
+ return false; // We are not a NTS enabled server.
+ }
+
+ // We may get garbage from the net
+ if (cookielen > NTS_MAX_COOKIELEN)
+ return false;
+
+ finger = cookie;
+ key = NULL; // squash uninitialized warning
+ for (i=0; i<nts_nKeys; i++) {
+ key = &nts_keys[i];
+ if (0 == memcmp(finger, &key->I, sizeof(key->I))) {
+ break;
+ }
+ }
+ nts_cnt.cookie_decode_total++; // total attempts, includes too old
+ if (nts_nKeys == i) {
+ nts_cnt.cookie_decode_too_old++;
+ return false;
+ }
+ if (0 == i) {
+ nts_cnt.cookie_decode_current++;
+ } else if (1 == i) {
+ nts_cnt.cookie_decode_old++;
+ } else if (2 == i) {
+ nts_cnt.cookie_decode_old2++;
+ } else {
+ nts_cnt.cookie_decode_older++;
}
- if (0 == i) {
- nts_cnt.cookie_decode_current++;
- } else if (1 == i) {
- nts_cnt.cookie_decode_old++;
- } else if (2 == i) {
- nts_cnt.cookie_decode_old2++;
- } else {
- nts_cnt.cookie_decode_older++;
- }
#if 0
- if (1<i) {
- /* Hack for debugging */
- /* Beware: DoS possibility on a public server */
- msyslog(LOG_INFO, "NTS: Old cookie: %d days.", i);
- }
+ if (1<i) {
+ // Hack for debugging
+ // Beware: DoS possibility on a public server
+ msyslog(LOG_INFO, "NTS: Old cookie: %d days.", i);
+ }
#endif
- finger += sizeof(key->I);
- nonce = finger;
- finger += NONCE_LENGTH;
-
- // require(AD_LENGTH==finger-cookie);
+ finger += sizeof(key->I);
+ nonce = finger;
+ finger += NONCE_LENGTH;
- cipherlength = cookielen - AD_LENGTH;
- plainlength = NTS_MAX_COOKIELEN;
+ // require(AD_LENGTH==finger-cookie);
- nts_lock_cookielock();
+ cipherlength = cookielen - AD_LENGTH;
+ plainlength = NTS_MAX_COOKIELEN;
- ok = AES_SIV_Decrypt(cookie_ctx,
- plaintext, &plainlength,
- key->K, K_length,
- nonce, NONCE_LENGTH,
- finger, cipherlength,
- cookie, AD_LENGTH);
+ nts_lock_cookielock();
- nts_unlock_cookielock();
+ ok = AES_SIV_Decrypt(cookie_ctx,
+ plaintext, &plainlength,
+ key->K, K_length,
+ nonce, NONCE_LENGTH,
+ finger, cipherlength,
+ cookie, AD_LENGTH);
- if (!ok) {
- nts_cnt.cookie_decode_error++;
- return false;
- }
+ nts_unlock_cookielock();
- *keylen = (plainlength-AEAD_LENGTH)/2;
- finger = plaintext;
- memcpy(&temp, finger, AEAD_LENGTH);
- *aead = temp;
- finger += AEAD_LENGTH;
- memcpy(c2s, finger, *keylen);
- finger += *keylen;
- memcpy(s2c, finger, *keylen);
- finger += *keylen;
+ if (!ok) {
+ nts_cnt.cookie_decode_error++;
+ return false;
+ }
- return true;
+ *keylen = (plainlength-AEAD_LENGTH)/2;
+ finger = plaintext;
+ memcpy(&temp, finger, AEAD_LENGTH);
+ *aead = temp;
+ finger += AEAD_LENGTH;
+ memcpy(c2s, finger, *keylen);
+ finger += *keylen;
+ memcpy(s2c, finger, *keylen);
+ finger += *keylen;
+
+ 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);
- }
+ 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);
- }
+ int err = pthread_mutex_unlock(&cookie_lock);
+ if (0 != err) {
+ msyslog(LOG_ERR, "ERR: Can't unlock cookie_lock: %d", err);
+ exit(2);
+ }
}
-/* end */
+// end
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/98e2af0169cc5225ecdd71903c39f30aa4fe5f4a...c281f95cd3834786abeca138940d0af2d7ccc3fb
--
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/98e2af0169cc5225ecdd71903c39f30aa4fe5f4a...c281f95cd3834786abeca138940d0af2d7ccc3fb
You're receiving this email because of your account on gitlab.com. Manage all notifications: https://gitlab.com/-/profile/notifications | Help: https://gitlab.com/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20260806/69d140f5/attachment-0001.htm>
More information about the vc
mailing list