@ -0,0 +1 @@ | |||||
*.patch linguist-language=c |
@ -0,0 +1,54 @@ | |||||
From: Pekka Helenius <fincer89@hotmail.com> | |||||
Date: Sun, 02 Aug 2020 14:12:40 +0300 | |||||
Subject: Set 'Sensors' to lowercase in ntpctl settings | |||||
--- a/src/ntpd.c 2020-08-01 13:33:10.798104786 +0300 | |||||
+++ b/src/ntpd.c 2020-08-01 13:33:27.848104803 +0300 | |||||
@@ -76,7 +76,7 @@ extern u_int constraint_cnt; | |||||
const char *showopt; | |||||
static const char *ctl_showopt_list[] = { | |||||
- "peers", "Sensors", "status", "all", NULL | |||||
+ "peers", "sensors", "status", "all", NULL | |||||
}; | |||||
void | |||||
@@ -115,7 +115,7 @@ usage(void) | |||||
if (strcmp(__progname, "ntpctl") == 0) | |||||
fprintf(stderr, | |||||
- "usage: ntpctl -s all | peers | Sensors | status\n"); | |||||
+ "usage: ntpctl -s all | peers | sensors | status\n"); | |||||
else | |||||
fprintf(stderr, "usage: %s [-dnv] [-f file] [-p file]\n", | |||||
__progname); | |||||
--- a/src/ntpctl.8 2020-07-31 23:00:50.329054281 +0300 | |||||
+++ b/src/ntpctl.8 2020-08-01 00:35:22.158056263 +0300 | |||||
@@ -22,7 +22,7 @@ | |||||
.Nd control the Network Time Protocol daemon | |||||
.Sh SYNOPSIS | |||||
.Nm ntpctl | |||||
-.Fl s Cm all | peers | Sensors | status | |||||
+.Fl s Cm all | peers | sensors | status | |||||
.Sh DESCRIPTION | |||||
The | |||||
.Nm | |||||
@@ -32,7 +32,7 @@ daemon. | |||||
.Pp | |||||
The options are as follows: | |||||
.Bl -tag -width "-s modifierX" | |||||
-.It Fl s Cm all | peers | Sensors | status | |||||
+.It Fl s Cm all | peers | sensors | status | |||||
Used to display information about the running daemon. | |||||
Keywords may be abbreviated. | |||||
.Pp | |||||
@@ -46,7 +46,7 @@ in seconds, and offset, network delay an | |||||
When the system clock is synced to a peer, an asterisk | |||||
is displayed to the left of the weight column for that peer. | |||||
.Pp | |||||
-.Cm Sensors | |||||
+.Cm sensors | |||||
shows the following information about each sensor: weight, sensor "good" | |||||
status, stratum, and offset and the configured correction in | |||||
milliseconds. |
@ -0,0 +1,678 @@ | |||||
From: Pekka Helenius <fincer89@hotmail.com> | |||||
Date: Sun, 02 Aug 2020 14:12:40 +0300 | |||||
Subject: Unhardcode NTP server, client and constraint UDP & TCP port numbers | |||||
--- a/src/client.c 2020-08-02 02:03:13.840286484 +0300 | |||||
+++ b/src/client.c 2020-08-02 02:04:23.993619892 +0300 | |||||
@@ -76,13 +76,13 @@ client_addr_init(struct ntp_peer *p) | |||||
case AF_INET: | |||||
sa_in = (struct sockaddr_in *)&h->ss; | |||||
if (ntohs(sa_in->sin_port) == 0) | |||||
- sa_in->sin_port = htons(123); | |||||
+ sa_in->sin_port = htons(p->addr_head.port); | |||||
p->state = STATE_DNS_DONE; | |||||
break; | |||||
case AF_INET6: | |||||
sa_in6 = (struct sockaddr_in6 *)&h->ss; | |||||
if (ntohs(sa_in6->sin6_port) == 0) | |||||
- sa_in6->sin6_port = htons(123); | |||||
+ sa_in6->sin6_port = htons(p->addr_head.port); | |||||
p->state = STATE_DNS_DONE; | |||||
break; | |||||
default: | |||||
@@ -122,9 +122,10 @@ client_nextaddr(struct ntp_peer *p) | |||||
p->shift = 0; | |||||
p->trustlevel = TRUSTLEVEL_PATHETIC; | |||||
- if (p->addr == NULL) | |||||
+ if (p->addr == NULL) { | |||||
p->addr = p->addr_head.a; | |||||
- else if ((p->addr = p->addr->next) == NULL) | |||||
+ p->port = p->addr_head.port; | |||||
+ } else if ((p->addr = p->addr->next) == NULL) | |||||
return (1); | |||||
return (0); | |||||
--- a/src/ntp.c 2020-07-31 23:34:32.000000000 +0300 | |||||
+++ b/src/ntp.c 2020-08-01 00:56:09.608057581 +0300 | |||||
@@ -603,6 +603,8 @@ ntp_dispatch_imsg_dns(void) | |||||
peer->addr_head.name; | |||||
npeer->addr_head.pool = | |||||
peer->addr_head.pool; | |||||
+ npeer->addr_head.port = | |||||
+ peer->addr_head.port; | |||||
client_peer_init(npeer); | |||||
npeer->state = STATE_DNS_DONE; | |||||
peer_add(npeer); | |||||
@@ -611,6 +613,7 @@ ntp_dispatch_imsg_dns(void) | |||||
h->next = peer->addr; | |||||
peer->addr = h; | |||||
peer->addr_head.a = peer->addr; | |||||
+ peer->addr_head.port = peer->port; | |||||
peer->state = STATE_DNS_DONE; | |||||
} | |||||
} | |||||
--- a/src/config.c 2020-07-31 23:11:30.000000000 +0300 | |||||
+++ b/src/config.c 2020-08-01 01:02:14.468057965 +0300 | |||||
@@ -196,3 +196,10 @@ new_constraint(void) | |||||
return (p); | |||||
} | |||||
+int | |||||
+intdup(int in) | |||||
+{ | |||||
+ int *out; | |||||
+ out = ∈ | |||||
+ return *out; | |||||
+} | |||||
--- a/src/ntpd.h 2020-07-31 23:00:51.000000000 +0300 | |||||
+++ b/src/ntpd.h 2020-08-01 01:27:06.418059534 +0300 | |||||
@@ -95,7 +95,7 @@ | |||||
#define CONSTRAINT_SCAN_INTERVAL (15*60) | |||||
#define CONSTRAINT_SCAN_TIMEOUT (10) | |||||
#define CONSTRAINT_MARGIN (2.0*60) | |||||
-#define CONSTRAINT_PORT "443" /* HTTPS port */ | |||||
+ | |||||
#define CONSTRAINT_MAXHEADERLENGTH 8192 | |||||
#define CONSTRAINT_PASSFD (STDERR_FILENO + 1) | |||||
@@ -121,6 +121,7 @@ struct listen_addr { | |||||
struct sockaddr_storage sa; | |||||
int fd; | |||||
int rtable; | |||||
+ int port; | |||||
}; | |||||
struct ntp_addr { | |||||
@@ -132,14 +133,17 @@ struct ntp_addr { | |||||
struct ntp_addr_wrap { | |||||
char *name; | |||||
char *path; | |||||
+ int port; | |||||
struct ntp_addr *a; | |||||
u_int8_t pool; | |||||
}; | |||||
struct ntp_addr_msg { | |||||
struct ntp_addr a; | |||||
+ int port; | |||||
size_t namelen; | |||||
size_t pathlen; | |||||
+ size_t portlen; | |||||
}; | |||||
struct ntp_status { | |||||
@@ -184,6 +188,7 @@ struct ntp_peer { | |||||
u_int8_t trusted; | |||||
int lasterror; | |||||
int senderrors; | |||||
+ int port; | |||||
}; | |||||
struct ntp_sensor { | |||||
@@ -206,6 +211,7 @@ struct constraint { | |||||
TAILQ_ENTRY(constraint) entry; | |||||
struct ntp_addr_wrap addr_head; | |||||
struct ntp_addr *addr; | |||||
+ int port; | |||||
int senderrors; | |||||
enum client_state state; | |||||
u_int32_t id; | |||||
@@ -365,6 +371,7 @@ void host_dns_free(struct ntp_addr *) | |||||
struct ntp_peer *new_peer(void); | |||||
struct ntp_conf_sensor *new_sensor(char *); | |||||
struct constraint *new_constraint(void); | |||||
+int intdup(int); | |||||
/* ntp_msg.c */ | |||||
int ntp_getmsg(struct sockaddr *, char *, ssize_t, struct ntp_msg *); | |||||
@@ -401,6 +408,7 @@ void priv_constraint_kill(u_int32_t); | |||||
int priv_constraint_dispatch(struct pollfd *); | |||||
void priv_constraint_check_child(pid_t, int); | |||||
char *get_string(u_int8_t *, size_t); | |||||
+int intlen(int); | |||||
/* util.c */ | |||||
double gettime_corrected(void); | |||||
--- a/src/constraint.c 2020-08-02 01:56:09.060286035 +0300 | |||||
+++ b/src/constraint.c 2020-08-02 01:56:47.110286075 +0300 | |||||
@@ -66,11 +66,11 @@ void priv_constraint_readquery(struct c | |||||
uint8_t **); | |||||
struct httpsdate * | |||||
- httpsdate_init(const char *, const char *, const char *, | |||||
+ httpsdate_init(const char *, const int *, const char *, | |||||
const char *, const u_int8_t *, size_t); | |||||
void httpsdate_free(void *); | |||||
int httpsdate_request(struct httpsdate *, struct timeval *); | |||||
-void *httpsdate_query(const char *, const char *, const char *, | |||||
+void *httpsdate_query(const char *, const int *, const char *, | |||||
const char *, const u_int8_t *, size_t, | |||||
struct timeval *, struct timeval *); | |||||
@@ -125,13 +125,13 @@ constraint_addr_init(struct constraint * | |||||
case AF_INET: | |||||
sa_in = (struct sockaddr_in *)&h->ss; | |||||
if (ntohs(sa_in->sin_port) == 0) | |||||
- sa_in->sin_port = htons(443); | |||||
+ sa_in->sin_port = htons(cstr->addr_head.port); | |||||
cstr->state = STATE_DNS_DONE; | |||||
break; | |||||
case AF_INET6: | |||||
sa_in6 = (struct sockaddr_in6 *)&h->ss; | |||||
if (ntohs(sa_in6->sin6_port) == 0) | |||||
- sa_in6->sin6_port = htons(443); | |||||
+ sa_in6->sin6_port = htons(cstr->addr_head.port); | |||||
cstr->state = STATE_DNS_DONE; | |||||
break; | |||||
default: | |||||
@@ -206,6 +206,7 @@ constraint_query(struct constraint *cstr | |||||
memset(&am, 0, sizeof(am)); | |||||
memcpy(&am.a, cstr->addr, sizeof(am.a)); | |||||
+ memcpy(&am.port, &cstr->addr_head.port, sizeof(am.port)); | |||||
iov[iov_cnt].iov_base = &am; | |||||
iov[iov_cnt++].iov_len = sizeof(am); | |||||
@@ -219,6 +220,11 @@ constraint_query(struct constraint *cstr | |||||
iov[iov_cnt].iov_base = cstr->addr_head.path; | |||||
iov[iov_cnt++].iov_len = am.pathlen; | |||||
} | |||||
+ if (cstr->addr_head.port) { | |||||
+ am.portlen = intlen(cstr->addr_head.port) + 1; | |||||
+ iov[iov_cnt].iov_base = &cstr->addr_head.port; | |||||
+ iov[iov_cnt++].iov_len = am.portlen; | |||||
+ } | |||||
imsg_composev(ibuf_main, IMSG_CONSTRAINT_QUERY, | |||||
cstr->id, 0, -1, iov, iov_cnt); | |||||
@@ -246,7 +252,7 @@ priv_constraint_msg(u_int32_t id, u_int8 | |||||
return; | |||||
} | |||||
memcpy(&am, data, sizeof(am)); | |||||
- if (len != (sizeof(am) + am.namelen + am.pathlen)) { | |||||
+ if (len != (sizeof(am) + am.namelen + am.pathlen + am.portlen)) { | |||||
log_warnx("constraint id %d: invalid query received", id); | |||||
return; | |||||
} | |||||
@@ -301,6 +307,7 @@ priv_constraint_readquery(struct constra | |||||
int n; | |||||
struct imsg imsg; | |||||
size_t mlen; | |||||
+ int port; | |||||
/* Read the message our parent left us. */ | |||||
if (((n = imsg_read(&cstr->ibuf)) == -1 && errno != EAGAIN) || n == 0) | |||||
@@ -324,7 +331,7 @@ priv_constraint_readquery(struct constra | |||||
); | |||||
memcpy(am, imsg.data, sizeof(*am)); | |||||
- if (mlen != (sizeof(*am) + am->namelen + am->pathlen)) | |||||
+ if (mlen != (sizeof(*am) + am->namelen + am->pathlen + am->portlen)) | |||||
fatalx("constraint: invalid message length received from parent process (%s)", | |||||
__func__ | |||||
); | |||||
@@ -334,12 +341,15 @@ priv_constraint_readquery(struct constra | |||||
fatal("constraint: can't allocate memory (%s)", __func__); | |||||
memcpy(h, &am->a, sizeof(*h)); | |||||
+ memcpy(&port, &am->port, sizeof(port)); | |||||
h->next = NULL; | |||||
- | |||||
+ | |||||
cstr->id = imsg.hdr.peerid; | |||||
cstr->addr = h; | |||||
cstr->addr_head.a = h; | |||||
- | |||||
+ cstr->port = port; | |||||
+ cstr->addr_head.port = port; | |||||
+ | |||||
dptr = imsg.data; | |||||
memcpy(*data, dptr + sizeof(*am), mlen - sizeof(*am)); | |||||
imsg_free(&imsg); | |||||
@@ -434,10 +444,14 @@ priv_constraint_child(const char *pw_dir | |||||
get_string(data, am.pathlen)) == NULL) | |||||
fatalx("constraint %s: invalid path", addr); | |||||
} | |||||
+ if (am.portlen) { | |||||
+ if (cstr.addr_head.port == 0) | |||||
+ fatalx("constraint %s: invalid port", addr); | |||||
+ } | |||||
/* Run! */ | |||||
if ((ctx = httpsdate_query(addr, | |||||
- CONSTRAINT_PORT, cstr.addr_head.name, cstr.addr_head.path, | |||||
+ &cstr.addr_head.port, cstr.addr_head.name, cstr.addr_head.path, | |||||
conf->ca, conf->ca_len, &rectv, &xmttv)) == NULL) { | |||||
log_debug("constraint %s: failed to get proper time results", addr); | |||||
/* Abort with failure but without warning */ | |||||
@@ -800,8 +814,14 @@ constraint_msg_dns(u_int32_t id, u_int8_ | |||||
ncstr->addr_head.a = h; | |||||
ncstr->addr_head.name = strdup(cstr->addr_head.name); | |||||
ncstr->addr_head.path = strdup(cstr->addr_head.path); | |||||
+ ncstr->addr_head.port = intdup(cstr->addr_head.port); | |||||
+ | |||||
+ // Unless we do this, we have value 0 in ncstr->port | |||||
+ ncstr->port = intdup(cstr->port); | |||||
+ | |||||
if (ncstr->addr_head.name == NULL || | |||||
- ncstr->addr_head.path == NULL) | |||||
+ ncstr->addr_head.path == NULL || | |||||
+ ncstr->addr_head.port == 0 || ncstr->port == 0) | |||||
fatal("constraint id %d: DNS dispatching failed: invalid data", id); | |||||
ncstr->addr_head.pool = cstr->addr_head.pool; | |||||
ncstr->state = STATE_DNS_DONE; | |||||
@@ -811,6 +831,7 @@ constraint_msg_dns(u_int32_t id, u_int8_ | |||||
h->next = ncstr->addr; | |||||
ncstr->addr = h; | |||||
ncstr->addr_head.a = h; | |||||
+ // TODO missing port? | |||||
} | |||||
} while (len); | |||||
@@ -912,10 +933,11 @@ constraint_check(double val) | |||||
} | |||||
struct httpsdate * | |||||
-httpsdate_init(const char *addr, const char *port, const char *hostname, | |||||
+httpsdate_init(const char *addr, const int *port, const char *hostname, | |||||
const char *path, const u_int8_t *ca, size_t ca_len) | |||||
{ | |||||
struct httpsdate *httpsdate = NULL; | |||||
+ char port_s[sizeof(port)]; | |||||
if ((httpsdate = calloc(1, sizeof(*httpsdate))) == NULL) | |||||
goto fail; | |||||
@@ -923,8 +945,10 @@ httpsdate_init(const char *addr, const c | |||||
if (hostname == NULL) | |||||
hostname = addr; | |||||
+ sprintf(port_s, "%d", *port); | |||||
+ | |||||
if ((httpsdate->tls_addr = strdup(addr)) == NULL || | |||||
- (httpsdate->tls_port = strdup(port)) == NULL || | |||||
+ (httpsdate->tls_port = strdup(port_s)) == NULL || | |||||
(httpsdate->tls_hostname = strdup(hostname)) == NULL || | |||||
(httpsdate->tls_path = strdup(path)) == NULL) | |||||
goto fail; | |||||
@@ -1098,7 +1122,7 @@ httpsdate_request(struct httpsdate *http | |||||
} | |||||
void * | |||||
-httpsdate_query(const char *addr, const char *port, const char *hostname, | |||||
+httpsdate_query(const char *addr, const int *port, const char *hostname, | |||||
const char *path, const u_int8_t *ca, size_t ca_len, | |||||
struct timeval *rectv, struct timeval *xmttv) | |||||
{ | |||||
@@ -1183,3 +1207,17 @@ get_string(u_int8_t *ptr, size_t len) | |||||
return strndup(ptr, i); | |||||
} | |||||
+ | |||||
+int | |||||
+intlen(int val) | |||||
+{ | |||||
+ int n = 1; | |||||
+ if (val < 0) | |||||
+ return 0; | |||||
+ while(val > 9) { | |||||
+ n++; | |||||
+ val /= 10; | |||||
+ } | |||||
+ | |||||
+ return val; | |||||
+} | |||||
--- a/src/parse.y 2020-07-31 23:57:08.000000000 +0300 | |||||
+++ b/src/parse.y 2020-08-01 01:51:28.041394057 +0300 | |||||
@@ -60,6 +60,7 @@ int findeol(void); | |||||
struct sockaddr_in query_addr4; | |||||
struct sockaddr_in6 query_addr6; | |||||
int poolseqnum; | |||||
+struct servent *se; | |||||
struct opts { | |||||
int weight; | |||||
@@ -68,6 +69,7 @@ struct opts { | |||||
int rtable; | |||||
int trusted; | |||||
char *refstr; | |||||
+ int port; | |||||
} opts; | |||||
void opts_default(void); | |||||
@@ -86,18 +88,21 @@ typedef struct { | |||||
%token LISTEN ON CONSTRAINT CONSTRAINTS FROM QUERY TRUSTED | |||||
%token SERVER SERVERS SENSOR CORRECTION RTABLE REFID STRATUM WEIGHT | |||||
%token ERROR | |||||
+%token PORT | |||||
%token <v.string> STRING | |||||
%token <v.number> NUMBER | |||||
%type <v.addr> address url urllist | |||||
%type <v.opts> listen_opts listen_opts_l listen_opt | |||||
%type <v.opts> server_opts server_opts_l server_opt | |||||
%type <v.opts> sensor_opts sensor_opts_l sensor_opt | |||||
+%type <v.opts> constraint_opts constraint_opts_l constraint_opt | |||||
%type <v.opts> correction | |||||
%type <v.opts> rtable | |||||
%type <v.opts> refid | |||||
%type <v.opts> stratum | |||||
%type <v.opts> weight | |||||
%type <v.opts> trusted | |||||
+%type <v.opts> port | |||||
%% | |||||
grammar : /* empty */ | |||||
@@ -125,6 +130,10 @@ main : LISTEN ON address listen_opts { | |||||
fatal("can't allocate memory for listening address"); | |||||
la->fd = -1; | |||||
la->rtable = $4.rtable; | |||||
+ | |||||
+ if ($4.port != 0) | |||||
+ la->port = $4.port; | |||||
+ | |||||
memcpy(&la->sa, &h->ss, | |||||
sizeof(struct sockaddr_storage)); | |||||
TAILQ_INSERT_TAIL(&conf->listen_addrs, la, | |||||
@@ -186,10 +195,22 @@ main : LISTEN ON address listen_opts { | |||||
p->trusted = $3.trusted; | |||||
conf->trusted_peers = conf->trusted_peers || | |||||
$3.trusted; | |||||
+ | |||||
+ if ($3.port == 0) { | |||||
+ if ((se = getservbyname("ntp", "udp")) == NULL) { | |||||
+ fatal("new server: can't find default system information for NTP protocol (getservbyname)"); | |||||
+ } else { | |||||
+ $3.port = ntohs(se->s_port); | |||||
+ } | |||||
+ } | |||||
+ p->port = $3.port; | |||||
+ $2->port = p->port; | |||||
+ | |||||
p->query_addr4 = query_addr4; | |||||
p->query_addr6 = query_addr6; | |||||
p->addr = h; | |||||
p->addr_head.a = h; | |||||
+ p->addr_head.port = intdup($2->port); | |||||
p->addr_head.pool = ++poolseqnum; | |||||
p->addr_head.name = strdup($2->name); | |||||
if (p->addr_head.name == NULL) | |||||
@@ -228,9 +249,21 @@ main : LISTEN ON address listen_opts { | |||||
p->trusted = $3.trusted; | |||||
conf->trusted_peers = conf->trusted_peers || | |||||
$3.trusted; | |||||
+ | |||||
+ if ($3.port == 0) { | |||||
+ if ((se = getservbyname("ntp", "udp")) == NULL) { | |||||
+ fatal("new server: can't find default system information for NTP protocol (getservbyname)"); | |||||
+ } else { | |||||
+ $3.port = ntohs(se->s_port); | |||||
+ } | |||||
+ } | |||||
+ p->port = $3.port; | |||||
+ $2->port = p->port; | |||||
+ | |||||
p->query_addr4 = query_addr4; | |||||
p->query_addr6 = query_addr6; | |||||
p->addr_head.a = p->addr; | |||||
+ p->addr_head.port = intdup($2->port); | |||||
p->addr_head.pool = 0; | |||||
p->addr_head.name = strdup($2->name); | |||||
if (p->addr_head.name == NULL) | |||||
@@ -241,7 +274,7 @@ main : LISTEN ON address listen_opts { | |||||
free($2->name); | |||||
free($2); | |||||
} | |||||
- | CONSTRAINTS FROM url { | |||||
+ | CONSTRAINTS FROM url constraint_opts { | |||||
struct constraint *p; | |||||
struct ntp_addr *h, *next; | |||||
@@ -266,6 +299,17 @@ main : LISTEN ON address listen_opts { | |||||
p = new_constraint(); | |||||
p->addr = h; | |||||
p->addr_head.a = h; | |||||
+ | |||||
+ if ($4.port == 0) { | |||||
+ if ((se = getservbyname("https", "tcp")) == NULL) { | |||||
+ fatal("new constraint: can't find default system information for HTTPS protocol (getservbyname)"); | |||||
+ } else { | |||||
+ $4.port = ntohs(se->s_port); | |||||
+ } | |||||
+ } | |||||
+ p->port = $4.port; | |||||
+ p->addr_head.port = intdup($4.port); | |||||
+ | |||||
p->addr_head.pool = ++poolseqnum; | |||||
p->addr_head.name = strdup($3->name); | |||||
p->addr_head.path = strdup($3->path); | |||||
@@ -281,7 +325,7 @@ main : LISTEN ON address listen_opts { | |||||
free($3->name); | |||||
free($3); | |||||
} | |||||
- | CONSTRAINT FROM urllist { | |||||
+ | CONSTRAINT FROM urllist constraint_opts { | |||||
struct constraint *p; | |||||
struct ntp_addr *h, *next; | |||||
@@ -304,6 +348,17 @@ main : LISTEN ON address listen_opts { | |||||
} | |||||
p->addr_head.a = p->addr; | |||||
+ | |||||
+ if ($4.port == 0) { | |||||
+ if ((se = getservbyname("https", "tcp")) == NULL) { | |||||
+ fatal("new constraint: can't find default system information for HTTPS protocol (getservbyname)"); | |||||
+ } else { | |||||
+ $4.port = ntohs(se->s_port); | |||||
+ } | |||||
+ } | |||||
+ p->port = $4.port; | |||||
+ p->addr_head.port = intdup($4.port); | |||||
+ | |||||
p->addr_head.pool = 0; | |||||
p->addr_head.name = strdup($3->name); | |||||
p->addr_head.path = strdup($3->path); | |||||
@@ -410,6 +465,7 @@ listen_opts_l : listen_opts_l listen_opt | |||||
| listen_opt | |||||
; | |||||
listen_opt : rtable | |||||
+ | port | |||||
; | |||||
server_opts : { opts_default(); } | |||||
@@ -422,6 +478,18 @@ server_opts_l : server_opts_l server_opt | |||||
; | |||||
server_opt : weight | |||||
| trusted | |||||
+ | port | |||||
+ ; | |||||
+ | |||||
+constraint_opts : { opts_default(); } | |||||
+ constraint_opts_l | |||||
+ { $$ = opts; } | |||||
+ | { opts_default(); $$ = opts; } | |||||
+ ; | |||||
+constraint_opts_l : constraint_opts_l constraint_opt | |||||
+ | constraint_opt | |||||
+ ; | |||||
+constraint_opt : port | |||||
; | |||||
sensor_opts : { opts_default(); } | |||||
@@ -478,6 +546,17 @@ weight : WEIGHT NUMBER { | |||||
} | |||||
opts.weight = $2; | |||||
} | |||||
+ ; | |||||
+ | |||||
+port : PORT NUMBER { | |||||
+ if ($2 < 1 || $2 > 65535) { | |||||
+ yyerror("port must be between 1 and 65535"); | |||||
+ YYERROR; | |||||
+ } | |||||
+ opts.port = $2; | |||||
+ } | |||||
+ ; | |||||
+ | |||||
rtable : RTABLE NUMBER { | |||||
#ifdef RT_TABLEID_MAX | |||||
if ($2 < 0 || $2 > RT_TABLEID_MAX) { | |||||
@@ -502,6 +581,7 @@ opts_default(void) | |||||
memset(&opts, 0, sizeof opts); | |||||
opts.weight = 1; | |||||
opts.stratum = 1; | |||||
+ opts.port = 0; | |||||
} | |||||
struct keywords { | |||||
@@ -542,6 +622,7 @@ lookup(char *s) | |||||
{ "from", FROM}, | |||||
{ "listen", LISTEN}, | |||||
{ "on", ON}, | |||||
+ { "port", PORT}, | |||||
{ "query", QUERY}, | |||||
{ "refid", REFID}, | |||||
{ "rtable", RTABLE}, | |||||
--- a/src/server.c 2020-08-01 00:04:05.000000000 +0300 | |||||
+++ b/src/server.c 2020-08-01 01:14:42.328058753 +0300 | |||||
@@ -107,14 +107,18 @@ setup_listeners(struct servent *se, stru | |||||
for (la = TAILQ_FIRST(&lconf->listen_addrs); la; ) { | |||||
switch (la->sa.ss_family) { | |||||
case AF_INET: | |||||
- if (((struct sockaddr_in *)&la->sa)->sin_port == 0) | |||||
- ((struct sockaddr_in *)&la->sa)->sin_port = | |||||
- se->s_port; | |||||
+ if ((la->port == 0) && \ | |||||
+ (((struct sockaddr_in *)&la->sa)->sin_port == 0)) | |||||
+ ((struct sockaddr_in *)&la->sa)->sin_port = se->s_port; | |||||
+ else | |||||
+ ((struct sockaddr_in *)&la->sa)->sin_port = ntohs(la->port); | |||||
break; | |||||
case AF_INET6: | |||||
- if (((struct sockaddr_in6 *)&la->sa)->sin6_port == 0) | |||||
- ((struct sockaddr_in6 *)&la->sa)->sin6_port = | |||||
- se->s_port; | |||||
+ if ((la->port == 0) && \ | |||||
+ (((struct sockaddr_in6 *)&la->sa)->sin6_port == 0)) | |||||
+ ((struct sockaddr_in6 *)&la->sa)->sin6_port = se->s_port; | |||||
+ else | |||||
+ ((struct sockaddr_in6 *)&la->sa)->sin6_port = ntohs(la->port); | |||||
break; | |||||
case AF_UNSPEC: | |||||
nla = TAILQ_NEXT(la, entry); | |||||
--- a/src/ntpd.conf.5 2020-07-31 23:00:51.000000000 +0300 | |||||
+++ b/src/ntpd.conf.5 2020-08-01 01:22:25.424725907 +0300 | |||||
@@ -14,7 +14,7 @@ | |||||
.\" AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | |||||
.\" OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
.\" | |||||
-.Dd $Mdocdate: May 16 2020 $ | |||||
+.Dd $Mdocdate: August 01 2020 $ | |||||
.Dt NTPD.CONF 5 | |||||
.Os | |||||
.Sh NAME | |||||
@@ -37,6 +37,7 @@ The basic configuration options are as f | |||||
.Bl -tag -width Ds | |||||
.It Xo Ic listen on Ar address | |||||
.Op Ic rtable Ar table-id | |||||
+.Op Ic port Ar port-number | |||||
.Xc | |||||
.Xr ntpd 8 | |||||
has the ability to sync the local clock to remote NTP servers and, if | |||||
@@ -62,6 +63,12 @@ keyword will specify which routing table | |||||
By default | |||||
.Xr ntpd 8 | |||||
will listen using the current routing table. | |||||
+The optional | |||||
+.Ic port | |||||
+keyword will specify which local UDP port the NTP server process should use for inbound connections. | |||||
+By default | |||||
+.Xr ntpd 8 | |||||
+will listen to UDP port 123 for new client connections. | |||||
For example: | |||||
.Bd -literal -offset indent | |||||
listen on * | |||||
@@ -72,6 +79,7 @@ or | |||||
listen on 127.0.0.1 | |||||
listen on ::1 | |||||
listen on 127.0.0.1 rtable 4 | |||||
+listen on 127.0.0.1 port 1230 | |||||
.Ed | |||||
.It Ic query from Ar sourceaddr | |||||
Specify a local IP address the | |||||
@@ -165,6 +173,7 @@ than a server with a weight of 1. | |||||
.It Xo Ic server Ar address | |||||
.Op Ic trusted | |||||
.Op Ic weight Ar weight-value | |||||
+.Op Ic port Ar port-number | |||||
.Xc | |||||
Specify the IP address or the hostname of an NTP | |||||
server to synchronize to. | |||||
@@ -182,6 +191,7 @@ For example: | |||||
.Bd -literal -offset indent | |||||
server 10.0.0.2 weight 5 | |||||
server ntp.example.org weight 1 | |||||
+server ntp.foo.org port 123 | |||||
.Ed | |||||
.Pp | |||||
To provide redundancy, it is good practice to configure multiple servers. | |||||
@@ -190,6 +200,7 @@ network latency. | |||||
.It Xo Ic servers Ar address | |||||
.Op Ic trusted | |||||
.Op Ic weight Ar weight-value | |||||
+.Op Ic port Ar port-number | |||||
.Xc | |||||
As with | |||||
.Cm server , | |||||
@@ -204,6 +215,7 @@ For example: | |||||
.Bd -literal -offset indent | |||||
servers pool.ntp.org | |||||
servers pool.ntp.org weight 5 | |||||
+servers pool.ntp.org weight 6 port 123 | |||||
.Ed | |||||
.El | |||||
.Sh CONSTRAINTS | |||||
@@ -227,8 +239,13 @@ without libtls causes | |||||
to log a warning message on startup. | |||||
.Bl -tag -width Ds | |||||
.It Ic constraint from Ar url [ip...] | |||||
+.Op Ic port Ar port-number | |||||
Specify the URL, IP address or the hostname of an HTTPS server to | |||||
-provide a constraint. | |||||
+provide a constraint. The optional | |||||
+.Ic port | |||||
+number is an HTTPS server port to connect to. By default | |||||
+.Xr ntpd 8 | |||||
+will connect to remote TCP port 443. | |||||
If the url is followed by one or more addresses the url and addresses will be | |||||
tried until a working one is found. | |||||
The url path and expected certificate name is always taken from the | |||||
@@ -242,8 +259,10 @@ will calculate a median constraint from | |||||
server ntp.example.org | |||||
constraint from www.example.com | |||||
constraint from "https://9.9.9.9" "2620:fe::9" | |||||
+constraint from www.google.com port 443 | |||||
.Ed | |||||
.It Ic constraints from Ar url | |||||
+.Op Ic port Ar port-number | |||||
As with | |||||
.Ic constraint from , | |||||
specify the URL, IP address or the hostname of an HTTPS server to | |||||
@@ -251,10 +270,16 @@ provide a constraint. | |||||
Should the hostname resolve to multiple IP addresses, | |||||
.Xr ntpd 8 | |||||
will calculate a median constraint from all of them. | |||||
+The optional | |||||
+.Ic port | |||||
+number is an HTTPS server port to connect to. By default | |||||
+.Xr ntpd 8 | |||||
+will connect to remote TCP port 443. | |||||
For example: | |||||
.Bd -literal -offset indent | |||||
servers pool.ntp.org | |||||
constraints from "https://www.google.com/" | |||||
+constraints from "https://duckduckgo.com/" port 443 | |||||
.Ed | |||||
.El | |||||
.Sh FILES |
@ -0,0 +1,24 @@ | |||||
From: Pekka Helenius <fincer89@hotmail.com> | |||||
Date: Sun, 02 Aug 2020 14:12:40 +0300 | |||||
Subject: Fix C compiler warning about uninitialized variable peercount | |||||
--- a/src/ntp.c 2020-08-01 00:56:09.608057581 +0300 | |||||
+++ b/src/ntp.c 2020-08-01 15:22:42.981445052 +0300 | |||||
@@ -511,7 +511,7 @@ ntp_dispatch_imsg_dns(void) | |||||
u_int16_t dlen; | |||||
u_char *p; | |||||
struct ntp_addr *h; | |||||
- size_t addrcount, peercount; | |||||
+ size_t addrcount, peercount = 0; | |||||
int n; | |||||
if (((n = imsg_read(ibuf_dns)) == -1 && errno != EAGAIN) || n == 0) | |||||
@@ -540,7 +540,6 @@ ntp_dispatch_imsg_dns(void) | |||||
if (peer->addr_head.pool) { | |||||
n = 0; | |||||
- peercount = 0; | |||||
TAILQ_FOREACH_SAFE(npeer, &conf->ntp_peers, | |||||
entry, tmp) { |
@ -0,0 +1,22 @@ | |||||
From: Pekka Helenius <fincer89@hotmail.com> | |||||
Date: Sun, 02 Aug 2020 14:12:40 +0300 | |||||
Subject: Fix debug mode not showing output in command line | |||||
--- a/src/ntpd.c 2020-08-01 13:33:42.000000000 +0300 | |||||
+++ b/src/ntpd.c 2020-08-01 16:07:32.660248971 +0300 | |||||
@@ -195,12 +195,14 @@ main(int argc, char *argv[]) | |||||
switch (ch) { | |||||
case 'd': | |||||
lconf.debug = 1; | |||||
+ lconf.verbose = 2; | |||||
break; | |||||
case 'f': | |||||
conffile = optarg; | |||||
break; | |||||
case 'n': | |||||
lconf.debug = 1; | |||||
+ lconf.verbose = 2; | |||||
lconf.noaction = 1; | |||||
break; | |||||
case 'P': |
@ -0,0 +1,706 @@ | |||||
From: Pekka Helenius <fincer89@hotmail.com> | |||||
Date: Sun, 02 Aug 2020 14:12:40 +0300 | |||||
Subject: Implement OpenSSL support, update manual, update ChangeLog | |||||
--- a/configure.ac 2020-07-31 23:00:40.000000000 +0300 | |||||
+++ b/configure.ac 2020-08-02 01:23:30.696950640 +0300 | |||||
@@ -59,35 +59,100 @@ AM_CONDITIONAL([HAVE_ADJFREQ], [test "x$ | |||||
AM_CONDITIONAL([HAVE_CLOCK_GETRES], [test "x$ac_cv_func_clock_getres" = xyes]) | |||||
AM_CONDITIONAL([HAVE_CLOCK_GETTIME], [test "x$ac_cv_func_clock_gettime" = xyes]) | |||||
-# check for libtls | |||||
-AC_SEARCH_LIBS([tls_config_set_ca_mem],[tls], | |||||
- [LIBS="$LIBS -ltls -lssl -lcrypto"],,[-lssl -lcrypto]) | |||||
-AC_CHECK_FUNCS([tls_config_set_ca_mem]) | |||||
- | |||||
-# check if libtls uses 3-argument tls_write | |||||
-AC_CACHE_CHECK([if tls_write takes 3 arguments], ac_cv_have_tls_write_3_arg, [ | |||||
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[ | |||||
-#include <tls.h> | |||||
-size_t outlen; | |||||
- ]], [[ tls_write(NULL, NULL, 0); ]])], | |||||
- [ ac_cv_have_tls_write_3_arg="yes" ], | |||||
- [ ac_cv_have_tls_write_3_arg="no" | |||||
+# NOTE: hard-set AC_CHECK_HEADER or friends can't really be checked since | |||||
+# libressl/openssl include header files must be determined by OS basis | |||||
+# during compilation. Use the following approach instead. | |||||
+ | |||||
+AM_CONDITIONAL(HAVE_SSL, false) | |||||
+AM_CONDITIONAL([HAVE_LIBRESSL], false) | |||||
+AM_CONDITIONAL([HAVE_OPENSSL], false) | |||||
+ | |||||
+# check for libressl | |||||
+AC_ARG_WITH([libressl], | |||||
+ AS_HELP_STRING([--without-libressl], | |||||
+ [Disable LibreSSL support for constraints])) | |||||
+ | |||||
+AS_IF([test "x$with_libressl" != "xno" ], | |||||
+ [ have_libressl="yes" ], | |||||
+ [ have_libressl="no" ] | |||||
+) | |||||
+ | |||||
+if test "x$have_libressl" == "xyes"; then | |||||
+ | |||||
+ AC_SEARCH_LIBS([tls_config_set_ca_mem],[tls], | |||||
+ [LIBS="$LIBS -ltls -lssl -lcrypto"],,[-lssl -lcrypto]) | |||||
+ | |||||
+ AC_CHECK_FUNCS([tls_config_set_ca_mem]) | |||||
+ | |||||
+ # check if libressl uses 3-argument tls_write | |||||
+ AC_CACHE_CHECK( | |||||
+ [if LibreSSL tls_write takes 3 arguments], | |||||
+ ac_cv_have_libressl_write_3_arg, | |||||
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM( | |||||
+ [[ #include <libressl/tls.h> ]], | |||||
+ [[ size_t outlen; ]], | |||||
+ [[ tls_write(NULL, NULL, 0); ]] | |||||
+ )], | |||||
+ [ ac_cv_have_libressl_write_3_arg="yes" ], | |||||
+ [ ac_cv_have_libressl_write_3_arg="no" ] | |||||
+ ) | |||||
+ ]) | |||||
+fi | |||||
+ | |||||
+# check for openssl | |||||
+AC_ARG_WITH([openssl], | |||||
+ AS_HELP_STRING([--without-openssl], | |||||
+ [Disable OpenSSL support for constraints])) | |||||
+ | |||||
+AS_IF([test "x$with_openssl" != "xno" ], | |||||
+ [ have_openssl="yes" ], | |||||
+ [ have_openssl="no" ] | |||||
+) | |||||
+ | |||||
+if test "x$have_openssl" == "xyes"; then | |||||
+ | |||||
+ AC_SEARCH_LIBS([X509_STORE_load_locations],[ssl], | |||||
+ [LIBS="$LIBS -lssl -lcrypto"],,[-lssl -lcrypto]) | |||||
+ | |||||
+ AC_CHECK_FUNCS([X509_STORE_load_locations]) | |||||
+ | |||||
+ # check if openssl uses 3-argument SSL_write | |||||
+ AC_CACHE_CHECK( | |||||
+ [if OpenSSL SSL_write takes 3 arguments], | |||||
+ ac_cv_have_openssl_write_3_arg, | |||||
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM( | |||||
+ [[ #include <openssl/ssl.h> ]], | |||||
+ [[ SSL *a; SSL_CTX *ff; ]], | |||||
+ [[ ff = SSL_CTX_new(TLS_method()); ]], | |||||
+ [[ a = SSL_new(ff); ]], | |||||
+ [[ SSL_write(a, NULL, 0); ]] | |||||
+ )], | |||||
+ [ ac_cv_have_openssl_write_3_arg="yes" ], | |||||
+ [ ac_cv_have_openssl_write_3_arg="no" ] | |||||
+ ) | |||||
]) | |||||
-]) | |||||
+fi | |||||
-AC_ARG_ENABLE([https-constraint], | |||||
- AS_HELP_STRING([--disable-https-constraint], | |||||
- [Disable HTTPS Constraint Functionality])) | |||||
- | |||||
-AM_CONDITIONAL([HAVE_LIBTLS], | |||||
- [test "x$ac_cv_func_tls_config_set_ca_mem" = xyes \ | |||||
- -a "x$ac_cv_have_tls_write_3_arg" = xyes \ | |||||
- -a "x$enable_https_constraint" != xno]) | |||||
- | |||||
-if test "x$ac_cv_func_tls_config_set_ca_mem" = xyes \ | |||||
- -a "x$ac_cv_have_tls_write_3_arg" = xyes \ | |||||
- -a "x$enable_https_constraint" != xno; then | |||||
- AC_DEFINE([HAVE_LIBTLS], [yes]) | |||||
+if test "x$with_libressl" != xno \ | |||||
+ -a "x$ac_cv_func_tls_config_set_ca_mem" = xyes \ | |||||
+ -a "x$ac_cv_have_libressl_write_3_arg" = xyes; then | |||||
+ AM_CONDITIONAL([HAVE_LIBRESSL], true) | |||||
+ AM_CONDITIONAL([HAVE_SSL], true) | |||||
+ AC_DEFINE([HAVE_LIBRESSL], [yes]) | |||||
+ AC_DEFINE([HAVE_SSL], [yes]) | |||||
+else | |||||
+ AC_MSG_WARN([LibreSSL support disabled]) | |||||
+fi | |||||
+ | |||||
+if test "x$with_openssl" != xno \ | |||||
+ -a "x$ac_cv_func_X509_STORE_load_locations" = xyes \ | |||||
+ -a "x$ac_cv_have_openssl_write_3_arg" = xyes; then | |||||
+ AM_CONDITIONAL([HAVE_OPENSSL], true) | |||||
+ AM_CONDITIONAL([HAVE_SSL], true) | |||||
+ AC_DEFINE([HAVE_OPENSSL], [yes]) | |||||
+ AC_DEFINE([HAVE_SSL], [yes]) | |||||
+else | |||||
+ AC_MSG_WARN([OpenSSL support disabled]) | |||||
fi | |||||
# Share test results with automake | |||||
@@ -144,14 +209,6 @@ AC_ARG_WITH([privsep-path], | |||||
) | |||||
AC_SUBST(PRIVSEP_PATH) | |||||
-AC_ARG_WITH([cacert], | |||||
- AS_HELP_STRING([--with-cacert=path], | |||||
- [CA certificate location for HTTPS constraint validation]), | |||||
- CONSTRAINT_CA="$withval", | |||||
- CONSTRAINT_CA="/etc/ssl/cert.pem" | |||||
-) | |||||
-AC_DEFINE_UNQUOTED(CONSTRAINT_CA, "$CONSTRAINT_CA", [CA certificate path]) | |||||
- | |||||
AC_CONFIG_FILES([ | |||||
Makefile | |||||
include/Makefile | |||||
--- a/include/tls.h 2020-07-31 23:00:40.000000000 +0300 | |||||
+++ b/include/tls.h 2020-08-01 19:24:29.153594762 +0300 | |||||
@@ -1,8 +1,22 @@ | |||||
/* | |||||
* Public domain | |||||
* tls.h compatibility shim | |||||
+ * | |||||
+ * __linux__ | |||||
+ * __sun | |||||
+ * __FreeBSD__ | |||||
+ * __NetBSD__ | |||||
+ * __OpenBSD__ | |||||
+ * __APPLE__ | |||||
*/ | |||||
-#ifdef HAVE_LIBTLS | |||||
+#if defined(HAVE_LIBRESSL) && __linux__ | |||||
+#include_next <libressl/tls.h> | |||||
+#elif HAVE_LIBRESSL | |||||
#include_next <tls.h> | |||||
#endif | |||||
+ | |||||
+#ifdef HAVE_OPENSSL | |||||
+#include <openssl/ssl.h> | |||||
+#include <openssl/err.h> | |||||
+#endif | |||||
--- a/src/constraint.c 2020-08-02 01:57:57.020286149 +0300 | |||||
+++ b/src/constraint.c 2020-08-02 01:58:28.366952848 +0300 | |||||
@@ -39,7 +39,6 @@ | |||||
#include <unistd.h> | |||||
#include <time.h> | |||||
#include <ctype.h> | |||||
-#include <tls.h> | |||||
#include <pwd.h> | |||||
#include <math.h> | |||||
@@ -65,33 +64,11 @@ void priv_constraint_close(int, int); | |||||
void priv_constraint_readquery(struct constraint *, struct ntp_addr_msg *, | |||||
uint8_t **); | |||||
-struct httpsdate * | |||||
- httpsdate_init(const char *, const int *, const char *, | |||||
- const char *, const u_int8_t *, size_t); | |||||
-void httpsdate_free(void *); | |||||
-int httpsdate_request(struct httpsdate *, struct timeval *); | |||||
-void *httpsdate_query(const char *, const int *, const char *, | |||||
- const char *, const u_int8_t *, size_t, | |||||
- struct timeval *, struct timeval *); | |||||
- | |||||
-char *tls_readline(struct tls *, size_t *, size_t *, struct timeval *); | |||||
- | |||||
u_int constraint_cnt; | |||||
extern u_int peer_cnt; | |||||
extern struct imsgbuf *ibuf; /* priv */ | |||||
extern struct imsgbuf *ibuf_main; /* chld */ | |||||
-struct httpsdate { | |||||
- char *tls_addr; | |||||
- char *tls_port; | |||||
- char *tls_hostname; | |||||
- char *tls_path; | |||||
- char *tls_request; | |||||
- struct tls_config *tls_config; | |||||
- struct tls *tls_ctx; | |||||
- struct tm tls_tm; | |||||
-}; | |||||
- | |||||
int | |||||
constraint_init(struct constraint *cstr) | |||||
{ | |||||
@@ -155,7 +132,7 @@ constraint_query(struct constraint *cstr | |||||
{ | |||||
time_t now; | |||||
struct ntp_addr_msg am; | |||||
- struct iovec iov[3]; | |||||
+ struct iovec iov[4]; | |||||
int iov_cnt = 0; | |||||
now = getmonotime(); | |||||
@@ -252,7 +229,7 @@ priv_constraint_msg(u_int32_t id, u_int8 | |||||
return; | |||||
} | |||||
memcpy(&am, data, sizeof(am)); | |||||
- if (len != (sizeof(am) + am.namelen + am.pathlen + am.portlen)) { | |||||
+ if (len != (sizeof(am) + am.namelen + am.pathlen + am.portlen)) { | |||||
log_warnx("constraint id %d: invalid query received", id); | |||||
return; | |||||
} | |||||
@@ -343,13 +320,13 @@ priv_constraint_readquery(struct constra | |||||
memcpy(h, &am->a, sizeof(*h)); | |||||
memcpy(&port, &am->port, sizeof(port)); | |||||
h->next = NULL; | |||||
- | |||||
+ | |||||
cstr->id = imsg.hdr.peerid; | |||||
cstr->addr = h; | |||||
cstr->addr_head.a = h; | |||||
cstr->port = port; | |||||
cstr->addr_head.port = port; | |||||
- | |||||
+ | |||||
dptr = imsg.data; | |||||
memcpy(*data, dptr + sizeof(*am), mlen - sizeof(*am)); | |||||
imsg_free(&imsg); | |||||
@@ -364,20 +341,46 @@ priv_constraint_child(const char *pw_dir | |||||
static char addr[NI_MAXHOST]; | |||||
struct timeval rectv, xmttv; | |||||
struct sigaction sa; | |||||
- void *ctx; | |||||
+ void *ctx = NULL; | |||||
struct iovec iov[2]; | |||||
int i, rv; | |||||
+#ifdef HAVE_OPENSSL | |||||
+ X509_STORE *o_store = NULL; | |||||
+#endif | |||||
if (setpriority(PRIO_PROCESS, 0, 0) == -1) | |||||
log_warn("constraint: can't set priority for subprocess"); | |||||
-#ifdef HAVE_LIBTLS | |||||
- /* Init TLS and load CA certs before chroot() */ | |||||
- if (tls_init() == -1) | |||||
- fatalx("constraint: can't initialize LibreSSL engine"); | |||||
- if ((conf->ca = tls_load_file(tls_default_ca_cert_file(), | |||||
- &conf->ca_len, NULL)) == NULL) | |||||
- log_warnx("constraint: failed to load CA certificate bundle file"); | |||||
+/* Init TLS and load CA certs before chroot() */ | |||||
+#ifdef HAVE_LIBRESSL | |||||
+ if (strcmp("libressl", conf->constraint_engine) == 0) { | |||||
+ if (tls_init() == -1) | |||||
+ fatalx("constraint: can't initialize LibreSSL engine"); | |||||
+ if (conf->constraint_ca_validation == 1) { | |||||
+ if ((conf->ca = tls_load_file(conf->constraint_ca, | |||||
+ &conf->ca_len, NULL)) == NULL) | |||||
+ log_warnx("constraint: failed to load CA certificate bundle file"); | |||||
+ } | |||||
+ } | |||||
+#endif | |||||
+ | |||||
+#ifdef HAVE_OPENSSL | |||||
+ if (strcmp("openssl", conf->constraint_engine) == 0) { | |||||
+ if (OPENSSL_init_ssl(0, NULL) == 0) | |||||
+ fatalx("constraint: can't initialize OpenSSL engine"); | |||||
+ //SSL_library_init(); | |||||
+ OpenSSL_add_all_algorithms(); | |||||
+ OpenSSL_add_all_digests(); | |||||
+ SSL_load_error_strings(); | |||||
+ o_store = X509_STORE_new(); | |||||
+ | |||||
+ if (conf->constraint_ca_validation == 1) { | |||||
+ if ((conf->o_ca = X509_STORE_load_locations(o_store, conf->constraint_ca, NULL)) != 1) { | |||||
+ log_warnx("constraint: failed to load CA certificate bundle file"); | |||||
+ openssl_lasterr(); | |||||
+ } | |||||
+ } | |||||
+ } | |||||
#endif | |||||
if (chroot(pw_dir) == -1) | |||||
@@ -420,7 +423,13 @@ priv_constraint_child(const char *pw_dir | |||||
log_debug("constraint %s: setting HTTPS request", addr); | |||||
setproctitle("constraint %s: new HTTPS request", addr); | |||||
- (void)closefrom(CONSTRAINT_PASSFD + 1); | |||||
+ | |||||
+ /* | |||||
+ * OpenSSL requires new file descriptors which must not be deleted. | |||||
+ * This restriction does not apply to LibreSSL implementation. | |||||
+ */ | |||||
+ if (strcmp("libressl", conf->constraint_engine) == 0) | |||||
+ (void)closefrom(CONSTRAINT_PASSFD + 1); | |||||
/* | |||||
* Set the close-on-exec flag to prevent leaking the communication | |||||
@@ -449,14 +458,32 @@ priv_constraint_child(const char *pw_dir | |||||
fatalx("constraint %s: invalid port", addr); | |||||
} | |||||
- /* Run! */ | |||||
- if ((ctx = httpsdate_query(addr, | |||||
- &cstr.addr_head.port, cstr.addr_head.name, cstr.addr_head.path, | |||||
- conf->ca, conf->ca_len, &rectv, &xmttv)) == NULL) { | |||||
- log_debug("constraint %s: failed to get proper time results", addr); | |||||
- /* Abort with failure but without warning */ | |||||
- exit(1); | |||||
+#ifdef HAVE_LIBRESSL | |||||
+ if (strcmp("libressl", conf->constraint_engine) == 0) { | |||||
+ /* Run! */ | |||||
+ log_debug("constraint %s: initializing HTTPS request", addr); | |||||
+ if ((ctx = httpsdate_query(addr, | |||||
+ &cstr.addr_head.port, cstr.addr_head.name, cstr.addr_head.path, | |||||
+ conf->ca, conf->ca_len, &rectv, &xmttv)) == NULL) { | |||||
+ log_debug("constraint %s: failed to get proper time results", addr); | |||||
+ /* Abort with failure but without warning */ | |||||
+ exit(1); | |||||
+ } | |||||
} | |||||
+#endif | |||||
+ | |||||
+#ifdef HAVE_OPENSSL | |||||
+ if (strcmp("openssl", conf->constraint_engine) == 0) { | |||||
+ /* Run! */ | |||||
+ log_debug("constraint %s: initializing HTTPS request", addr); | |||||
+ if ((ctx = o_httpsdate_query(&cstr, | |||||
+ &conf->o_ca, &rectv, &xmttv)) == NULL) { | |||||
+ log_debug("constraint %s: failed to get proper time results", addr); | |||||
+ /* Abort with failure but without warning */ | |||||
+ exit(1); | |||||
+ } | |||||
+ } | |||||
+#endif | |||||
iov[0].iov_base = &rectv; | |||||
iov[0].iov_len = sizeof(rectv); | |||||
@@ -468,8 +495,18 @@ priv_constraint_child(const char *pw_dir | |||||
rv = imsg_flush(&cstr.ibuf); | |||||
} while (rv == -1 && errno == EAGAIN); | |||||
- /* Tear down the TLS connection after sending the result */ | |||||
- httpsdate_free(ctx); | |||||
+/* Tear down the TLS connection after sending the result */ | |||||
+#ifdef HAVE_LIBRESSL | |||||
+ if (strcmp("libressl", conf->constraint_engine) == 0) { | |||||
+ httpsdate_free(ctx); | |||||
+ } | |||||
+#endif | |||||
+ | |||||
+#ifdef HAVE_OPENSSL | |||||
+ if (strcmp("openssl", conf->constraint_engine) == 0) { | |||||
+ o_httpsdate_free(ctx); | |||||
+ } | |||||
+#endif | |||||
exit(0); | |||||
} | |||||
@@ -932,270 +969,6 @@ constraint_check(double val) | |||||
return (0); | |||||
} | |||||
-struct httpsdate * | |||||
-httpsdate_init(const char *addr, const int *port, const char *hostname, | |||||
- const char *path, const u_int8_t *ca, size_t ca_len) | |||||
-{ | |||||
- struct httpsdate *httpsdate = NULL; | |||||
- char port_s[sizeof(port)]; | |||||
- | |||||
- if ((httpsdate = calloc(1, sizeof(*httpsdate))) == NULL) | |||||
- goto fail; | |||||
- | |||||
- if (hostname == NULL) | |||||
- hostname = addr; | |||||
- | |||||
- sprintf(port_s, "%d", *port); | |||||
- | |||||
- if ((httpsdate->tls_addr = strdup(addr)) == NULL || | |||||
- (httpsdate->tls_port = strdup(port_s)) == NULL || | |||||
- (httpsdate->tls_hostname = strdup(hostname)) == NULL || | |||||
- (httpsdate->tls_path = strdup(path)) == NULL) | |||||
- goto fail; | |||||
- | |||||
- if (asprintf(&httpsdate->tls_request, | |||||
- "HEAD %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", | |||||
- httpsdate->tls_path, httpsdate->tls_hostname) == -1) | |||||
- goto fail; | |||||
- | |||||
- if ((httpsdate->tls_config = tls_config_new()) == NULL) | |||||
- goto fail; | |||||
- if (tls_config_set_ca_mem(httpsdate->tls_config, ca, ca_len) == -1) | |||||
- goto fail; | |||||
- | |||||
- /* | |||||
- * Due to the fact that we're trying to determine a constraint for time | |||||
- * we do our own certificate validity checking, since the automatic | |||||
- * version is based on our wallclock, which may well be inaccurate... | |||||
- */ | |||||
- tls_config_insecure_noverifytime(httpsdate->tls_config); | |||||
- | |||||
- return (httpsdate); | |||||
- | |||||
- fail: | |||||
- httpsdate_free(httpsdate); | |||||
- return (NULL); | |||||
-} | |||||
- | |||||
-void | |||||
-httpsdate_free(void *arg) | |||||
-{ | |||||
- struct httpsdate *httpsdate = arg; | |||||
- if (httpsdate == NULL) | |||||
- return; | |||||
- if (httpsdate->tls_ctx) | |||||
- tls_close(httpsdate->tls_ctx); | |||||
- tls_free(httpsdate->tls_ctx); | |||||
- tls_config_free(httpsdate->tls_config); | |||||
- free(httpsdate->tls_addr); | |||||
- free(httpsdate->tls_port); | |||||
- free(httpsdate->tls_hostname); | |||||
- free(httpsdate->tls_path); | |||||
- free(httpsdate->tls_request); | |||||
- free(httpsdate); | |||||
-} | |||||
- | |||||
-int | |||||
-httpsdate_request(struct httpsdate *httpsdate, struct timeval *when) | |||||
-{ | |||||
- char timebuf1[32], timebuf2[32]; | |||||
- size_t outlen = 0, maxlength = conf->constraint_maxheaderlength, len; | |||||
- char *line, *p, *buf; | |||||
- time_t httptime, notbefore, notafter; | |||||
- struct tm *tm; | |||||
- ssize_t ret; | |||||
- | |||||
- if ((httpsdate->tls_ctx = tls_client()) == NULL) | |||||
- goto fail; | |||||
- | |||||
- if (tls_configure(httpsdate->tls_ctx, httpsdate->tls_config) == -1) | |||||
- goto fail; | |||||
- | |||||
- /* | |||||
- * libtls expects an address string, which can also be a DNS name, | |||||
- * but we pass a pre-resolved IP address string in tls_addr so it | |||||
- * does not trigger any DNS operation and is safe to be called | |||||
- * without the dns pledge. | |||||
- */ | |||||
- log_debug("constraint %s: establishing connection", httpsdate->tls_addr); | |||||
- if (tls_connect_servername(httpsdate->tls_ctx, httpsdate->tls_addr, | |||||
- httpsdate->tls_port, httpsdate->tls_hostname) == -1) { | |||||
- log_debug("constraint %s: TLS connection failed (%s): %s", | |||||
- httpsdate->tls_addr, | |||||
- httpsdate->tls_hostname, | |||||
- tls_error(httpsdate->tls_ctx) | |||||
- ); | |||||
- goto fail; | |||||
- } | |||||
- | |||||
- buf = httpsdate->tls_request; | |||||
- len = strlen(httpsdate->tls_request); | |||||
- while (len > 0) { | |||||
- ret = tls_write(httpsdate->tls_ctx, buf, len); | |||||
- if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) | |||||
- continue; | |||||
- if (ret == -1) { | |||||
- log_warnx("constraint %s: TLS write operation failed (%s): %s", | |||||
- httpsdate->tls_addr, | |||||
- httpsdate->tls_hostname, | |||||
- tls_error(httpsdate->tls_ctx) | |||||
- ); | |||||
- goto fail; | |||||
- } | |||||
- buf += ret; | |||||
- len -= ret; | |||||
- } | |||||
- | |||||
- while ((line = tls_readline(httpsdate->tls_ctx, &outlen, | |||||
- &maxlength, when)) != NULL) { | |||||
- line[strcspn(line, "\r\n")] = '\0'; | |||||
- | |||||
- if ((p = strchr(line, ' ')) == NULL || *p == '\0') | |||||
- goto next; | |||||
- *p++ = '\0'; | |||||
- if (strcasecmp("Date:", line) != 0) | |||||
- goto next; | |||||
- | |||||
- /* | |||||
- * Expect the date/time format as IMF-fixdate which is | |||||
- * mandated by HTTP/1.1 in the new RFC 7231 and was | |||||
- * preferred by RFC 2616. Other formats would be RFC 850 | |||||
- * or ANSI C's asctime() - the latter doesn't include | |||||
- * the timezone which is required here. | |||||
- */ | |||||
- if (strptime(p, IMF_FIXDATE, | |||||
- &httpsdate->tls_tm) == NULL) { | |||||
- log_warnx("constraint %s: unsupported date format", | |||||
- httpsdate->tls_addr | |||||
- ); | |||||
- free(line); | |||||
- return (-1); | |||||
- } | |||||
- | |||||
- free(line); | |||||
- break; | |||||
- next: | |||||
- free(line); | |||||
- } | |||||
- | |||||
- /* | |||||
- * Now manually check the validity of the certificate presented in the | |||||
- * TLS handshake, based on the time specified by the server's HTTP Date: | |||||
- * header. | |||||
- */ | |||||
- notbefore = tls_peer_cert_notbefore(httpsdate->tls_ctx); | |||||
- notafter = tls_peer_cert_notafter(httpsdate->tls_ctx); | |||||
- if ((httptime = timegm(&httpsdate->tls_tm)) == -1) | |||||
- goto fail; | |||||
- if (httptime <= notbefore) { | |||||
- if ((tm = gmtime(¬before)) == NULL) | |||||
- goto fail; | |||||
- if (strftime(timebuf1, sizeof(timebuf1), X509_DATE, tm) == 0) | |||||
- goto fail; | |||||
- if (strftime(timebuf2, sizeof(timebuf2), X509_DATE, | |||||
- &httpsdate->tls_tm) == 0) | |||||
- goto fail; | |||||
- log_warnx("constraint %s: TLS certificate not yet valid (%s): " | |||||
- "not before %s, now is %s", httpsdate->tls_addr, | |||||
- httpsdate->tls_hostname, timebuf1, timebuf2); | |||||
- goto fail; | |||||
- } | |||||
- if (httptime >= notafter) { | |||||
- if ((tm = gmtime(¬after)) == NULL) | |||||
- goto fail; | |||||
- if (strftime(timebuf1, sizeof(timebuf1), X509_DATE, tm) == 0) | |||||
- goto fail; | |||||
- if (strftime(timebuf2, sizeof(timebuf2), X509_DATE, | |||||
- &httpsdate->tls_tm) == 0) | |||||
- goto fail; | |||||
- log_warnx("constraint %s: TLS certificate has been expired (%s): " | |||||
- "not after %s, now is %s", httpsdate->tls_addr, | |||||
- httpsdate->tls_hostname, timebuf1, timebuf2); | |||||
- goto fail; | |||||
- } | |||||
- | |||||
- return (0); | |||||
- | |||||
- fail: | |||||
- httpsdate_free(httpsdate); | |||||
- return (-1); | |||||
-} | |||||
- | |||||
-void * | |||||
-httpsdate_query(const char *addr, const int *port, const char *hostname, | |||||
- const char *path, const u_int8_t *ca, size_t ca_len, | |||||
- struct timeval *rectv, struct timeval *xmttv) | |||||
-{ | |||||
- struct httpsdate *httpsdate; | |||||
- struct timeval when; | |||||
- time_t t; | |||||
- | |||||
- if ((httpsdate = httpsdate_init(addr, port, hostname, path, | |||||
- ca, ca_len)) == NULL) | |||||
- return (NULL); | |||||
- | |||||
- if (httpsdate_request(httpsdate, &when) == -1) | |||||
- return (NULL); | |||||
- | |||||
- /* Return parsed date as local time */ | |||||
- t = timegm(&httpsdate->tls_tm); | |||||
- | |||||
- /* Report parsed Date: as "received time" */ | |||||
- rectv->tv_sec = t; | |||||
- rectv->tv_usec = 0; | |||||
- | |||||
- /* And add delay as "transmit time" */ | |||||
- xmttv->tv_sec = when.tv_sec; | |||||
- xmttv->tv_usec = when.tv_usec; | |||||
- | |||||
- return (httpsdate); | |||||
-} | |||||
- | |||||
-/* Based on SSL_readline in ftp/fetch.c */ | |||||
-char * | |||||
-tls_readline(struct tls *tls, size_t *lenp, size_t *maxlength, | |||||
- struct timeval *when) | |||||
-{ | |||||
- size_t i, len; | |||||
- char *buf, *q, c; | |||||
- ssize_t ret; | |||||
- | |||||
- len = 128; | |||||
- if ((buf = malloc(len)) == NULL) | |||||
- fatal("constraint: can't allocate memory for TLS transfer buffer"); | |||||
- for (i = 0; ; i++) { | |||||
- if (i >= len - 1) { | |||||
- if ((q = reallocarray(buf, len, 2)) == NULL) | |||||
- fatal("constraint: can't expand TLS transfer buffer"); | |||||
- buf = q; | |||||
- len *= 2; | |||||
- } | |||||
- again: | |||||
- ret = tls_read(tls, &c, 1); | |||||
- if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) | |||||
- goto again; | |||||
- if (ret == -1) { | |||||
- /* SSL read error, ignore */ | |||||
- free(buf); | |||||
- return (NULL); | |||||
- } | |||||
- | |||||
- if (maxlength != NULL && (*maxlength)-- == 0) { | |||||
- log_warnx("constraint: maximum HTTP header length exceeded"); | |||||
- free(buf); | |||||
- return (NULL); | |||||
- } | |||||
- | |||||
- buf[i] = c; | |||||
- if (c == '\n') | |||||
- break; | |||||
- } | |||||
- *lenp = i; | |||||
- if (gettimeofday(when, NULL) == -1) | |||||
- fatal("constraint: can't get a valid time stamp"); | |||||
- return (buf); | |||||
-} | |||||
- | |||||
char * | |||||
get_string(u_int8_t *ptr, size_t len) | |||||
{ | |||||
--- /dev/null 2020-07-26 15:23:52.401078754 +0300 | |||||
+++ b/src/constraint-openssl.c 2020-08-01 19:56:30.010263450 +0300 | |||||
@@ -0,0 +1,329 @@ | |||||
+/* | |||||
+ * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org> | |||||
+ * Copyright (c) 2020 Pekka Helenius <fincer89@hotmail.com> | |||||
+ * | |||||
+ * Permission to use, copy, modify, and distribute this software for any | |||||
+ * purpose with or without fee is hereby granted, provided that the above | |||||
+ * copyright notice and this permission notice appear in all copies. | |||||
+ * | |||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
+ */ | |||||
+ | |||||
+#include <errno.h> | |||||
+#include <stdio.h> | |||||
+#include <stdlib.h> | |||||
+#include <string.h> | |||||
+#include <strings.h> | |||||
+#include <time.h> | |||||
+#include <sys/socket.h> | |||||
+#include <unistd.h> | |||||
+ | |||||
+#include "ntpd.h" | |||||
+ | |||||
+struct o_httpsdate * | |||||
+o_httpsdate_init(struct constraint *cstr, const int *ca) | |||||
+{ | |||||
+ struct o_httpsdate *httpsdate = NULL; | |||||
+ | |||||
+ if ((httpsdate = calloc(1, sizeof(*httpsdate))) == NULL) | |||||
+ goto fail; | |||||
+ | |||||
+ if ((httpsdate->cstr = cstr) == NULL) | |||||
+ goto fail; | |||||
+ | |||||
+ if (asprintf(&httpsdate->tls_request, | |||||
+ "HEAD %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", | |||||
+ httpsdate->cstr->addr_head.path, | |||||
+ httpsdate->cstr->addr_head.name) == -1) | |||||
+ goto fail; | |||||
+ | |||||
+ if ((httpsdate->tls_method = TLS_method()) == NULL) | |||||
+ goto fai |
@ -0,0 +1,344 @@ | |||||
From: Pekka Helenius <fincer89@hotmail.com> | |||||
Date: Sun, 02 Aug 2020 14:12:40 +0300 | |||||
Subject: Update default configuration file | |||||
--- a/ntpd.conf 2020-07-31 23:00:50.000000000 +0300 | |||||
+++ b/ntpd.conf 2020-08-02 02:30:41.706954890 +0300 | |||||
@@ -1,11 +1,330 @@ | |||||
-# $OpenBSD: ntpd.conf,v 1.16 2019/11/06 19:04:12 deraadt Exp $ | |||||
-# | |||||
# See ntpd.conf(5) and /etc/examples/ntpd.conf | |||||
+# BASIC KEYWORDS | |||||
+ | |||||
+# listen on 127.0.0.1 port 123 | |||||
+ | |||||
servers pool.ntp.org | |||||
-server time.cloudflare.com | |||||
-sensor * | |||||
+server time.cloudflare.com | |||||
+sensor * | |||||
-constraint from "9.9.9.9" # quad9 v4 without DNS | |||||
-constraint from "2620:fe::fe" # quad9 v6 without DNS | |||||
+constraint from "9.9.9.9" # quad9 v4 without DNS | |||||
+constraint from "2620:fe::fe" # quad9 v6 without DNS | |||||
constraints from "www.google.com" # intentionally not 8.8.8.8 | |||||
+ | |||||
+constraints from "https://www.duckduckgo.com" port 443 | |||||
+ | |||||
+# ADVANCED KEYWORDS | |||||
+ | |||||
+# During OpenNTPD initialization, all NTP peers get | |||||
+# automatic time offset value, if pre-conditions for | |||||
+# automatic interval adjustment are being met. | |||||
+# The conditions are as follows: OpenNTPD configuration | |||||
+# has constraints, trusted NTP peers or trusted sensors | |||||
+# and current internally defined process security level | |||||
+# is 0. In this case, initial time offset value is set | |||||
+# to 1 which, in return, triggers automatic offset calculation. | |||||
+# | |||||
+# In the automatic offset calculation, a trusted NTP | |||||
+# peer offset values are being counted for each peer. | |||||
+# For each peer an independent pool size is determined | |||||
+# by auto_replies value, ignoring the last value. | |||||
+# For instance, with auto_replies value 4, first | |||||
+# 3 NTP peer offset values are considered for a single | |||||
+# NTP peer, and a median offset value of these collected | |||||
+# 3 offset values is calculated and used for time adjustment. | |||||
+# | |||||
+# auto_replies 4 | |||||
+ | |||||
+# In OpenNTPD initial automatic time offset calculation, | |||||
+# three conditions are being considered for NTP peers: | |||||
+# is a NTP peer trusted and current overall constraint-based | |||||
+# median offset not 0, and whether an initial NTP peer | |||||
+# time offset exceeds value of auto_threshold . If these | |||||
+# conditions are met, then auto_threshold value may be | |||||
+# considered. If NTP peer current time offset value is | |||||
+# less than auto_threshold , then the system time offset | |||||
+# value is considered to be already OK, and OpenNTPD stops | |||||
+# calculating automatic offset value from further NTP peer | |||||
+# queries. In this case, median offset value is not calculated. | |||||
+# | |||||
+# auto_threshold 60 | |||||
+ | |||||
+# In automatic NTP peer offset calculation mode (during OpenNTPD | |||||
+# initialization), if NTP peer IP address is still unresolved | |||||
+# (unknown), the next query is attempted in interval_auto_dnsfail | |||||
+# seconds. Applies to unresolved constraint IP addresses, as well. | |||||
+# | |||||
+# interval_auto_dnsfail 1 | |||||
+ | |||||
+# Maximum number of attempts to resolve a constraint IP address(es) | |||||
+# with a DNS query before falling back from constraint_retry_interval | |||||
+# to interval_auto_dnsfail in constraint initialization. | |||||
+# | |||||
+# tries_auto_dnsfail 4 | |||||
+ | |||||
+# PEM-formatted certificate bundle file | |||||
+# for constraint HTTPS connections. | |||||
+# | |||||
+# constraint_ca /etc/ssl/cert.pem | |||||
+ | |||||
+# Whether to validate constraint HTTPS | |||||
+# server certificate. | |||||
+# | |||||
+# constraint_ca_validation true | |||||
+ | |||||
+# Use either LibreSSL (libressl) or OpenSSL (openssl) | |||||
+# for constraint HTTPS server connections. To | |||||
+# support chosen TLS engine, ntpd(8) must be | |||||
+# compiled and run with proper libraries installed | |||||
+# on the system. Only LibreSSL and OpenSSL are | |||||
+# supported. | |||||
+# | |||||
+# constraint_engine libressl | |||||
+ | |||||
+# Accepted number of errors during constraint | |||||
+# process. If error count exceeds this value | |||||
+# multiplied by calculated peer count, | |||||
+# constraint connection will be reseted and | |||||
+# a new constraint is retrieved. | |||||
+# | |||||
+# constraint_error_margin 4 | |||||
+ | |||||
+# Acceptable time difference between retrieved | |||||
+# HTTP header time value and calculated time | |||||
+# value in seconds. HTTP header time values | |||||
+# exceeding this margin value will be ignored. | |||||
+# | |||||
+# constraint_margin 120 | |||||
+ | |||||
+# Maximum allowed HTTP header length of constraint | |||||
+# HTTPS server reply to be fetched in bytes. If | |||||
+# the value is exceeded during processing, nothing | |||||
+# is returned and constraint check fails. | |||||
+# | |||||
+# constraint_max_headerlength 8192 | |||||
+ | |||||
+# Constraint HTTPS servers scan interval in seconds. | |||||
+# | |||||
+# constraint_scan_interval 900 | |||||
+ | |||||
+# Maximum connection establishment time to a | |||||
+# constraint HTTPS server in seconds. | |||||
+# | |||||
+# constraint_scan_timeout 10 | |||||
+ | |||||
+# ntpd(8) socket file path. | |||||
+# | |||||
+# ctlsocket /var/run/ntpd.sock | |||||
+ | |||||
+# ntpd(8) drift file path. | |||||
+# | |||||
+# driftfile /var/db/ntpd.drift | |||||
+ | |||||
+# Whether to reset frequency filters after | |||||
+# frequency adjustment. | |||||
+# | |||||
+# filter_adjfreq true | |||||
+ | |||||
+# Number of frequency samples for estimating | |||||
+# permanent drift value. | |||||
+# | |||||
+# frequency_samples 8 | |||||
+ | |||||
+# Initial trust level for a new, timed out or | |||||
+# erroneous remote NTP server. Every received | |||||
+# and non-discarded reply increases trust for | |||||
+# the server. The trust level is used for | |||||
+# setting used interval_query_* value for the | |||||
+# server and keeping track of valid remote NTP | |||||
+# servers. | |||||
+# | |||||
+# A server having this trust level uses remote | |||||
+# NTP query interval value interval_query_aggressive . | |||||
+# | |||||
+# trustlevel_pathetic 2 | |||||
+ | |||||
+# If a replying remote NTP server has trust level | |||||
+# one number less than this value, the server gets | |||||
+# trusted. In this case, the server can achieve | |||||
+# maximum trust level trustlevel_max . This trust | |||||
+# level is preceded by trust level trustlevel_pathetic | |||||
+# and followed by trust level trustlevel_aggressive . | |||||
+# | |||||
+# A NTP server having trust level value trustlevel_badpeer , | |||||
+# or value greater than trustlevel_pathetic but less than | |||||
+# trustlevel_aggressive uses remote NTP query interval | |||||
+# value interval_query_aggressive . | |||||
+# | |||||
+# In a case of NTP server reply time out, if the server | |||||
+# has at least trust level value trustlevel_badpeer | |||||
+# and the trust level value divided by 2 is less than | |||||
+# the trustlevel_badpeer value, the server will be | |||||
+# invalidated and falls back to initial trust level | |||||
+# trustlevel_pathetic . | |||||
+# | |||||
+# trustlevel_badpeer 6 | |||||
+ | |||||
+# Aggressive trust level is preceded by trust level | |||||
+# trustlevel_badpeer and followed by trust level | |||||
+# trustlevel_max . If a remote NTP server current trust | |||||
+# level is at least value of trustlevel_pathetic but | |||||
+# less than this value, used remote NTP query interval | |||||
+# is determined by value interval_query_aggressive . | |||||
+# A server with exact trust level trustlevel_aggressive | |||||
+# uses query interval interval_query_normal | |||||
+# (see trustlevel_max below). | |||||
+# | |||||
+# trustlevel_aggressive 8 | |||||
+ | |||||
+# Maximum trust level follows trust level trustlevel_aggressive . | |||||
+# This is the maximum trust level which a remote NTP | |||||
+# server can achieve. A server having at least trust | |||||
+# level trustlevel_aggressive uses remote NTP query | |||||
+# interval value interval_query_normal . | |||||
+# | |||||
+# trustlevel_max 10 | |||||
+ | |||||
+# Remote NTP server query interval in seconds for servers with | |||||
+# a trust level value greater than trustlevel_pathetic but less | |||||
+# than trustlevel_aggressive in a case where a NTP peer does not | |||||
+# still have large enough pool of already queried offset time values | |||||
+# for its offset time median calculation (checked against value | |||||
+# auto replies ) or is not trusted , interval value | |||||
+# interval_query_ultra_violence may be triggered. | |||||
+# Applies only to NTP offset calculation automatic mode. | |||||
+# | |||||
+# In most cases, interval_query_aggressive is used instead. | |||||
+# Dynamic offset scale value factors qscale_off_min and qscale_off_max | |||||
+# are ignored. | |||||
+# | |||||
+# interval_query_ultra_violence 1 | |||||
+ | |||||
+# Remote NTP server query interval in seconds for | |||||
+# servers with a trust level value less than trustlevel_pathetic . | |||||
+# Practically never used. | |||||
+# | |||||
+# This value is not the final query interval value but | |||||
+# used in a combination with a dynamic offset scale value, | |||||
+# determined by qscale_off_min and qscale_off_max . | |||||
+# | |||||
+# trustlevel_query_pathetic 60 | |||||
+ | |||||
+# Remote NTP server query interval in seconds for servers | |||||
+# with a trust level value greater than trustlevel_pathetic | |||||
+# but less than trustlevel_aggressive . Since all servers | |||||
+# start with a value trustlevel_pathetic , it means that | |||||
+# this is the initial value used for all new, timed out | |||||
+# or erroneous NTP servers. | |||||
+# | |||||
+# This value is not the final query interval value but | |||||
+# used in a combination with a dynamic offset scale value, | |||||
+# determined by qscale_off_min and qscale_off_max . | |||||
+# | |||||
+# trustlevel_query_aggressive 5 | |||||
+ | |||||
+# Remote NTP server query interval in seconds for servers | |||||
+# with a trust level value between trustlevel_aggressive | |||||
+# and trustlevel_max . | |||||
+# | |||||
+# This value is not the final query interval value but | |||||
+# used in a combination with a dynamic offset scale value, | |||||
+# determined by qscale_off_min and qscale_off_max . | |||||
+# | |||||
+# trustlevel_query_normal 30 | |||||
+ | |||||
+# Retry time in seconds after failed connection attempt | |||||
+# to a remote NTP server. | |||||
+# | |||||
+# interval_query_timeout 300 | |||||
+ | |||||
+# Negligible frequency rate to not log in PPM. | |||||
+# | |||||
+# log_negligible_adjfreq 0.05 | |||||
+ | |||||
+# Negligible drift time to not log in milliseconds. | |||||
+# | |||||
+# log_negligible_adjtime 32 | |||||
+ | |||||
+# Maximum number of characters in a ntpctl(8) | |||||
+# report line (peers, status, sensors and all). | |||||
+# | |||||
+# max_display_width 80 | |||||
+ | |||||
+# Maximum allowed frequency correction per iteration. | |||||
+# | |||||
+# max_frequency_adjust 0.0128 | |||||
+ | |||||
+# Maximum number of errors tolerated before reconnecting | |||||
+# to a remote NTP server. | |||||
+# | |||||
+# max_send_errors 3 | |||||
+ | |||||
+# Maximum number of remote NTP server IP addresses | |||||
+# fetched per DNS query. | |||||
+# | |||||
+# max_servers_dns 8 | |||||
+ | |||||
+# ntpd(8) process user name. Group name and working | |||||
+# directory are internally fetched by getpwnam(3) . | |||||
+# | |||||
+# ntpd_user ntp | |||||
+ | |||||
+# Minimum scale value used for dynamically adjusting | |||||
+# NTP server query interval time. If median NTP server | |||||
+# & sensor offset value is lower than this value, then | |||||
+# this value is used for scale calculation as minimum value. | |||||
+# Otherwise, the offset value is used as minimum value. | |||||
+# The offset value is a combined median value, based on | |||||
+# all NTP server & sensor offset values. | |||||
+# | |||||
+# The determined frequency scale is | |||||
+# qscale_off_max / { qscale_off_min OR median offset } . | |||||
+# | |||||
+# In the end, the calculated scale value is multiplied | |||||
+# one of interval_query_* values (pathetic, aggressive, normal) | |||||
+# on a client side, and ultimately used for dynamic | |||||
+# adjustment of client-side NTP server query interval time | |||||
+# for ntpd(8) process. | |||||
+# | |||||
+# qscale_off_min 0.001 | |||||
+ | |||||
+# Maximum scale value used for dynamically adjusting | |||||
+# NTP server query interval time. This value is used | |||||
+# either with a median NTP server & sensor offset value, | |||||
+# described in qscale_off_min section, or directly with | |||||
+# the value of qscale_off_min . The more detailed description | |||||
+# about further use of this value is above and | |||||
+# in interval_query_* sections. | |||||
+# | |||||
+# qscale_off_max 0.050 | |||||
+ | |||||
+# Maximum time reserved for a single NTP server query | |||||
+# in seconds. | |||||
+# | |||||
+# querytime_max 15 | |||||
+ | |||||
+# Sensor data maximum valid age in seconds. | |||||
+# | |||||
+# sensor_data_maxage 900 | |||||
+ | |||||
+# Sensor default reference ID string. | |||||
+# | |||||
+# sensor_default_refid "HARD" | |||||
+ | |||||
+# Maximum allowed sensor time offset in seconds. | |||||
+# | |||||
+# sensor_offsets 6 | |||||
+ | |||||
+# Sensor query interval in seconds. | |||||
+# | |||||
+# sensor_query_interval 15 | |||||
+ | |||||
+# Scan interval for new sensors in seconds. | |||||
+# | |||||
+# sensor_scan_interval 60 | |||||
+ | |||||
+# Maximum time to wait for a constraint to reply | |||||
+# during OpenNTPD initial automatic mode. | |||||
+# | |||||
+# settime_timeout 100 |