@ -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 |