Browse Source

Deploy patch files

master
Pekka Helenius 4 years ago
parent
commit
0d92de2025
9 changed files with 5983 additions and 0 deletions
  1. +1
    -0
      patches/.gitattributes
  2. +2248
    -0
      patches/1-patch_better-logs.patch
  3. +54
    -0
      patches/2-patch_ntpctl-sensors-tolowercase.patch
  4. +678
    -0
      patches/3-patch_unhardcode-ports.patch
  5. +24
    -0
      patches/4-patch_peercount-init.patch
  6. +22
    -0
      patches/5-patch_debugmode-fix.patch
  7. +1906
    -0
      patches/6-patch_unhardcode-conf.patch
  8. +706
    -0
      patches/7-patch_implement-openssl.patch
  9. +344
    -0
      patches/8-patch_update-conf.patch

+ 1
- 0
patches/.gitattributes View File

@ -0,0 +1 @@
*.patch linguist-language=c

+ 2248
- 0
patches/1-patch_better-logs.patch
File diff suppressed because it is too large
View File


+ 54
- 0
patches/2-patch_ntpctl-sensors-tolowercase.patch View File

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

+ 678
- 0
patches/3-patch_unhardcode-ports.patch View File

@ -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 = &in;
+ 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

+ 24
- 0
patches/4-patch_peercount-init.patch View File

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

+ 22
- 0
patches/5-patch_debugmode-fix.patch View File

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

+ 1906
- 0
patches/6-patch_unhardcode-conf.patch
File diff suppressed because it is too large
View File


+ 706
- 0
patches/7-patch_implement-openssl.patch View File

@ -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(&notbefore)) == 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(&notafter)) == 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

+ 344
- 0
patches/8-patch_update-conf.patch View File

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

Loading…
Cancel
Save