networkd: set PRL default options depending on Anonymize.
authorjuga0 <juga@riseup.net>
Thu, 3 Aug 2017 01:32:46 +0000 (03:32 +0200)
committerjuga0 <juga@riseup.net>
Wed, 6 Sep 2017 17:03:25 +0000 (19:03 +0200)
Add also Client variable to know when Anonymize is true.

src/libsystemd-network/sd-dhcp-client.c
src/libsystemd-network/test-dhcp-client.c
src/network/networkd-dhcp4.c
src/network/networkd-link.c
src/systemd/sd-dhcp-client.h

index e20d339..9cc5636 100644 (file)
@@ -62,6 +62,7 @@ struct sd_dhcp_client {
         uint8_t *req_opts;
         size_t req_opts_allocated;
         size_t req_opts_size;
+        bool anonymize;
         be32_t last_addr;
         uint8_t mac_addr[MAX_MAC_ADDR_LEN];
         size_t mac_addr_len;
@@ -116,6 +117,32 @@ static const uint8_t default_req_opts[] = {
         SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
 };
 
+/* RFC7844 section 3:
+   MAY contain the Parameter Request List option.
+   RFC7844 section 3.6:
+   The client intending to protect its privacy SHOULD only request a
+   minimal number of options in the PRL and SHOULD also randomly shuffle
+   the ordering of option codes in the PRL.  If this random ordering
+   cannot be implemented, the client MAY order the option codes in the
+   PRL by option code number (lowest to highest).
+*/
+/* NOTE: using PRL options that Windows 10 RFC7844 implementation uses */
+static const uint8_t default_req_opts_anonymize[] = {
+       SD_DHCP_OPTION_SUBNET_MASK,                     /* 1 */
+       SD_DHCP_OPTION_ROUTER,                          /* 3 */
+       SD_DHCP_OPTION_DOMAIN_NAME_SERVER,              /* 6 */
+       SD_DHCP_OPTION_DOMAIN_NAME,                     /* 15 */
+       SD_DHCP_OPTION_ROUTER_DISCOVER,                 /* 31 */
+       SD_DHCP_OPTION_STATIC_ROUTE,                    /* 33 */
+       SD_DHCP_OPTION_VENDOR_SPECIFIC,                 /* 43 */
+       SD_DHCP_OPTION_NETBIOS_NAMESERVER,              /* 44 */
+       SD_DHCP_OPTION_NETBIOS_NODETYPE,                /* 46 */
+       SD_DHCP_OPTION_NETBIOS_SCOPE,                   /* 47 */
+       SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE,          /* 121 */
+       SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE,  /* 249 */
+       SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY,     /* 252 */
+};
+
 static int client_receive_message_raw(
                 sd_event_source *s,
                 int fd,
@@ -1875,7 +1902,7 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
         return mfree(client);
 }
 
-int sd_dhcp_client_new(sd_dhcp_client **ret) {
+int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
         _cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = NULL;
 
         assert_return(ret, -EINVAL);
@@ -1892,8 +1919,15 @@ int sd_dhcp_client_new(sd_dhcp_client **ret) {
         client->mtu = DHCP_DEFAULT_MIN_SIZE;
         client->port = DHCP_PORT_CLIENT;
 
-        client->req_opts_size = ELEMENTSOF(default_req_opts);
-        client->req_opts = memdup(default_req_opts, client->req_opts_size);
+        client->anonymize = !!anonymize;
+        /* NOTE: this could be moved to a function. */
+        if (anonymize) {
+                client->req_opts_size = ELEMENTSOF(default_req_opts_anonymize);
+                client->req_opts = memdup(default_req_opts_anonymize, client->req_opts_size);
+        } else {
+                client->req_opts_size = ELEMENTSOF(default_req_opts);
+                client->req_opts = memdup(default_req_opts, client->req_opts_size);
+        }
         if (!client->req_opts)
                 return -ENOMEM;
 
index f5f1284..4eaebbb 100644 (file)
@@ -56,7 +56,8 @@ static void test_request_basic(sd_event *e) {
         if (verbose)
                 printf("* %s\n", __FUNCTION__);
 
-        r = sd_dhcp_client_new(&client);
+        /* Initialize client without Anonymize settings. */
+        r = sd_dhcp_client_new(&client, false);
 
         assert_se(r >= 0);
         assert_se(client);
@@ -78,6 +79,8 @@ static void test_request_basic(sd_event *e) {
                                         SD_DHCP_OPTION_SUBNET_MASK) == -EEXIST);
         assert_se(sd_dhcp_client_set_request_option(client,
                                         SD_DHCP_OPTION_ROUTER) == -EEXIST);
+        /* This PRL option is not set when using Anonymize, but in this test
+         * Anonymize settings are not being used. */
         assert_se(sd_dhcp_client_set_request_option(client,
                                         SD_DHCP_OPTION_HOST_NAME) == -EEXIST);
         assert_se(sd_dhcp_client_set_request_option(client,
@@ -97,10 +100,15 @@ static void test_request_basic(sd_event *e) {
                                         SD_DHCP_OPTION_PARAMETER_REQUEST_LIST)
                         == -EINVAL);
 
-        assert_se(sd_dhcp_client_set_request_option(client, 33) == 0);
-        assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
-        assert_se(sd_dhcp_client_set_request_option(client, 44) == 0);
-        assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
+        /* RFC7844: option 33 (SD_DHCP_OPTION_STATIC_ROUTE) is set in the
+         * default PRL when using Anonymize, so it is changed to other option
+         * that is not set by default, to check that it succed setting it.
+         * Ooptions not set by default (using or not anonymize) are option 17
+         * (SD_DHCP_OPTION_ROOT_PATH) and 42 (SD_DHCP_OPTION_NTP_SERVER) */
+        assert_se(sd_dhcp_client_set_request_option(client, 17) == 0);
+        assert_se(sd_dhcp_client_set_request_option(client, 17) == -EEXIST);
+        assert_se(sd_dhcp_client_set_request_option(client, 42) == 0);
+        assert_se(sd_dhcp_client_set_request_option(client, 17) == -EEXIST);
 
         sd_dhcp_client_unref(client);
 }
@@ -236,7 +244,7 @@ static void test_discover_message(sd_event *e) {
         if (verbose)
                 printf("* %s\n", __FUNCTION__);
 
-        r = sd_dhcp_client_new(&client);
+        r = sd_dhcp_client_new(&client, false);
         assert_se(r >= 0);
         assert_se(client);
 
@@ -451,7 +459,7 @@ static void test_addr_acq(sd_event *e) {
         if (verbose)
                 printf("* %s\n", __FUNCTION__);
 
-        r = sd_dhcp_client_new(&client);
+        r = sd_dhcp_client_new(&client, false);
         assert_se(r >= 0);
         assert_se(client);
 
index 546c90b..07661e3 100644 (file)
@@ -583,7 +583,7 @@ int dhcp4_configure(Link *link) {
         assert(link->network->dhcp & ADDRESS_FAMILY_IPV4);
 
         if (!link->dhcp_client) {
-                r = sd_dhcp_client_new(&link->dhcp_client);
+                r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize);
                 if (r < 0)
                         return r;
         }
index 2ad10d2..2fb1dd6 100644 (file)
@@ -2916,7 +2916,7 @@ network_file_fail:
                         goto dhcp4_address_fail;
                 }
 
-                r = sd_dhcp_client_new(&link->dhcp_client);
+                r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize);
                 if (r < 0)
                         return log_link_error_errno(link, r, "Failed to create DHCPv4 client: %m");
 
index fa7e80d..5e46d8d 100644 (file)
@@ -158,7 +158,9 @@ int sd_dhcp_client_start(sd_dhcp_client *client);
 sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client);
 sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
 
-int sd_dhcp_client_new(sd_dhcp_client **ret);
+/* NOTE: anonymize parameter is used to initialize PRL memory with different
+ * options when using RFC7844 Anonymity Profiles */
+int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize);
 
 int sd_dhcp_client_attach_event(
                 sd_dhcp_client *client,