ntp: open server socket only when access is allowed

When changing access configuration, check if any address is allowed and
open/close the server socket as needed.
This commit is contained in:
Miroslav Lichvar 2015-01-06 15:12:26 +01:00
parent 5214d42c07
commit 52e12e42e5
4 changed files with 78 additions and 12 deletions

View file

@ -363,6 +363,44 @@ ADF_IsAllowed(ADF_AuthTable table,
/* ================================================== */
static int
is_any_allowed(TableNode *node, State parent)
{
State state;
int i;
state = node->state != AS_PARENT ? node->state : parent;
assert(state != AS_PARENT);
if (node->extended) {
for (i = 0; i < TABLE_SIZE; i++) {
if (is_any_allowed(&node->extended[i], state))
return 1;
}
} else if (state == ALLOW) {
return 1;
}
return 0;
}
/* ================================================== */
int
ADF_IsAnyAllowed(ADF_AuthTable table, int family)
{
switch (family) {
case IPADDR_INET4:
return is_any_allowed(&table->base4, AS_PARENT);
case IPADDR_INET6:
return is_any_allowed(&table->base6, AS_PARENT);
default:
return 0;
}
}
/* ================================================== */
#if defined TEST
static void print_node(TableNode *node, uint32_t *addr, int ip_len, int shift, int subnet_bits)

View file

@ -72,4 +72,9 @@ extern void ADF_DestroyTable(ADF_AuthTable table);
extern int ADF_IsAllowed(ADF_AuthTable table,
IPAddr *ip);
/* Check if at least one address from a given family is allowed by
the rules in the table */
extern int ADF_IsAnyAllowed(ADF_AuthTable table,
int family);
#endif /* GOT_ADDRFILT_H */

View file

@ -2523,10 +2523,12 @@ pool pool.ntp.org iburst maxsources 3
@node port directive
@subsection port
This option allows you to configure the port on which @code{chronyd}
will listen for NTP requests.
will listen for NTP requests. The port will be open only when an address is
allowed by the @code{allow} directive or command, an NTP peer is configured, or
the broadcast server mode is enabled.
The compiled in default is udp/123, the standard NTP port. If set to 0,
@code{chronyd} will not open the server socket and will operate strictly in a
@code{chronyd} will never open the server port and will operate strictly in a
client-only mode. The source port used in NTP client requests can be set by
the @code{acquisitionport} directive.

View file

@ -309,8 +309,6 @@ do_time_checks(void)
void
NCR_Initialise(void)
{
NTP_Remote_Address addr;
do_size_checks();
do_time_checks();
@ -321,10 +319,9 @@ NCR_Initialise(void)
access_auth_table = ADF_CreateTable();
broadcasts = ARR_CreateInstance(sizeof (BroadcastDestination));
addr.ip_addr.family = IPADDR_INET4;
server_sock_fd4 = NIO_OpenServerSocket(&addr);
addr.ip_addr.family = IPADDR_INET6;
server_sock_fd6 = NIO_OpenServerSocket(&addr);
/* Server socket will be opened when access is allowed */
server_sock_fd4 = INVALID_SOCK_FD;
server_sock_fd6 = INVALID_SOCK_FD;
}
/* ================================================== */
@ -1855,13 +1852,37 @@ NCR_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all)
}
}
if (status == ADF_BADSUBNET) {
return 0;
} else if (status == ADF_SUCCESS) {
return 1;
} else {
if (status != ADF_SUCCESS)
return 0;
/* Keep server sockets open only when an address allowed */
if (allow) {
NTP_Remote_Address remote_addr;
if (server_sock_fd4 == INVALID_SOCK_FD &&
ADF_IsAnyAllowed(access_auth_table, IPADDR_INET4)) {
remote_addr.ip_addr.family = IPADDR_INET4;
server_sock_fd4 = NIO_OpenServerSocket(&remote_addr);
}
if (server_sock_fd6 == INVALID_SOCK_FD &&
ADF_IsAnyAllowed(access_auth_table, IPADDR_INET6)) {
remote_addr.ip_addr.family = IPADDR_INET6;
server_sock_fd6 = NIO_OpenServerSocket(&remote_addr);
}
} else {
if (server_sock_fd4 != INVALID_SOCK_FD &&
!ADF_IsAnyAllowed(access_auth_table, IPADDR_INET4)) {
NIO_CloseServerSocket(server_sock_fd4);
server_sock_fd4 = INVALID_SOCK_FD;
}
if (server_sock_fd6 != INVALID_SOCK_FD &&
!ADF_IsAnyAllowed(access_auth_table, IPADDR_INET6)) {
NIO_CloseServerSocket(server_sock_fd6);
server_sock_fd6 = INVALID_SOCK_FD;
}
}
return 1;
}
/* ================================================== */