]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: open server socket only when access is allowed
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 6 Jan 2015 14:12:26 +0000 (15:12 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 6 Jan 2015 15:35:12 +0000 (16:35 +0100)
When changing access configuration, check if any address is allowed and
open/close the server socket as needed.

addrfilt.c
addrfilt.h
chrony.texi.in
ntp_core.c

index 0930289d2143d5d5bc28b21f49d9ea6b1653fb6e..98d66a8bb3d1ff0453dd9185f5708c81b83db88d 100644 (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)
index 65784e55e52ec1998c82d7d0c80e062befca8bdf..b8c131f514eb17cf2c72c5c6560e4d552875bc61 100644 (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 */
index 277b924df454609a932e168ccc64f304673de982..c82758eba6c30893696e564635f7b919343d3943 100644 (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.
 
index e936a094e45808b03f5e3e6b82046225c072f777..8615bc82f292b0ddec1f61c3b464162fc817b3c8 100644 (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) {
+  if (status != ADF_SUCCESS)
     return 0;
-  } else if (status == ADF_SUCCESS) {
-    return 1;
+
+  /* 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 {
-    return 0;
+    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;
 }
 
 /* ================================================== */