]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
options: introduce the uri option as opposed to a string
authorRoy Marples <roy@marples.name>
Wed, 4 Oct 2023 12:03:21 +0000 (13:03 +0100)
committerRoy Marples <roy@marples.name>
Wed, 4 Oct 2023 12:08:20 +0000 (13:08 +0100)
Currently we don't attempt to validate a uri given, aside from
not allowing any space characters within.

If the option is `array uri` then the first two bytes are the
length of the uri in network order and the rest is a uri element.
The uri's are space separated for the variable because space is not
allowed within the uri.

This allows us to implement RFC 8572, Secure Zero Touch Provisioning.

src/dhcp-common.c
src/dhcp-common.h
src/dhcpcd-definitions.conf
src/dhcpcd.conf.5.in
src/if-options.c

index 679af243286ae237745094eaf7ace3c93a4cf25a..e5dd9efa721fb534104590772571202167594536 100644 (file)
@@ -125,6 +125,8 @@ dhcp_print_option_encoding(const struct dhcp_opt *opt, int cols)
                printf(" binhex");
        else if (opt->type & OT_STRING)
                printf(" string");
+       else if (opt->type & OT_URI)
+               printf(" uri");
        if (opt->type & OT_RFC3361)
                printf(" rfc3361");
        if (opt->type & OT_RFC3442)
@@ -518,6 +520,10 @@ print_string(char *dst, size_t len, int type, const uint8_t *data, size_t dl)
                        errno = EINVAL;
                        break;
                }
+               if (type & OT_URI && isspace(c)) {
+                       errno = EINVAL;
+                       break;
+               }
                if ((type & (OT_ESCSTRING | OT_ESCFILE) &&
                    (c == '\\' || !isascii(c) || !isprint(c))) ||
                    (type & OT_ESCFILE && (c == '/' || c == ' ')))
@@ -675,7 +681,58 @@ print_option(FILE *fp, const char *prefix, const struct dhcp_opt *opt,
                return print_rfc3442(fp, data, dl);
 #endif
 
-       if (opt->type & OT_STRING) {
+       /* Produces a space separated list of URIs.
+        * This is valid as a URI cannot contain a space. */
+       if ((opt->type & (OT_ARRAY | OT_URI)) == (OT_ARRAY | OT_URI)) {
+#ifdef SMALL
+               errno = ENOTSUP;
+               return -1;
+#else
+               char buf[UINT16_MAX + 1];
+               uint16_t sz;
+               bool first = true;
+
+               while (dl) {
+                       if (dl < 2) {
+                               errno = EINVAL;
+                               goto err;
+                       }
+
+                       memcpy(&u16, data, sizeof(u16));
+                       sz = ntohs(u16);
+                       data += sizeof(u16);
+                       dl -= sizeof(u16);
+
+                       if (sz == 0)
+                               continue;
+                       if (sz > dl) {
+                               errno = EINVAL;
+                               goto err;
+                       }
+
+                       if (print_string(buf, sizeof(buf),
+                           opt->type, data, sz) == -1)
+                               goto err;
+
+                       if (first)
+                               first = false;
+                       else if (fputc(' ', fp) == EOF)
+                               goto err;
+
+                       if (fprintf(fp, "%s", buf) == -1)
+                               goto err;
+
+                       data += sz;
+                       dl -= sz;
+               }
+
+               if (fputc('\0', fp) == EOF)
+                       goto err;
+               return 0;
+#endif
+       }
+
+       if (opt->type & (OT_STRING | OT_URI)) {
                char buf[1024];
 
                if (print_string(buf, sizeof(buf), opt->type, data, dl) == -1)
index 3b21c98e2d5035d3b623989fd9ab48d277796e5e..514131404004d43e4a7eaca94988f4d2a9764b57 100644 (file)
@@ -80,6 +80,7 @@
 #define        OT_ESCFILE              (1 << 26)
 #define        OT_BITFLAG              (1 << 27)
 #define        OT_RESERVED             (1 << 28)
+#define        OT_URI                  (1 << 29)
 
 #define        DHC_REQ(r, n, o) \
        (has_option_mask((r), (o)) && !has_option_mask((n), (o)))
index 3c20eef399a4ac752edab7d363b246df95f25300..d9de797cfd81480cee79e2a20ecfafa84176be41 100644 (file)
@@ -254,6 +254,9 @@ define 141  array domain            sip_ua_cs_list
 # DHCP ANDSF, RFC6153
 define 142     array ipaddress         andsf
 
+# DHCP SZTP Redirect, RFC8572
+define 143     array uri               sztp_redirect
+
 # DHCP Coordinate LCI, RFC6225
 # We have no means of expressing 6 bit lengths
 define 144     binhex                  geoloc
@@ -339,7 +342,7 @@ define 249  rfc3442                 ms_classless_static_routes
 # An expired RFC for Web Proxy Auto Discovery Protocol does define
 # Option 252 which is commonly used by major browsers.
 # Apparently the code was assigned by agreement of the DHC working group chair.
-define 252     string                  wpad_url
+define 252     uri                     wpad_url
 
 # Option 255 End
 
@@ -544,7 +547,7 @@ define6 57  domain                  access_domain
 define6 58     array domain            sip_ua_cs_list
 
 # DHCPv6 Network Boot, RFC5970
-define6 59     string                  bootfile_url
+define6 59     uri                     bootfile_url
 # We presently cannot decode bootfile_param
 define6 60     binhex                  bootfile_param
 define6 61     array uint16            architecture_types
@@ -648,7 +651,10 @@ encap      92      option
 define6 112    string                  mudurl
 
 # DHCP Captive Portal, RFC8910
-define6 103    string                  captive_portal_uri
+define6 103    uri                     captive_portal_uri
+
+# DHCP SZTP Redirect, RFC8572
+define6 136    array uri               sztp_redirect
 
 # DHCP DDoS Open Threat Signaling (DOTS) Agent Discovery, RFC8973
 define6 141    domain                  dots_ri
index 6383756553305eac1a85e4421250ed5bce505ab8..566b3727a5dbf8327e0a8e996d4483300409f61c 100644 (file)
@@ -24,7 +24,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd August 31, 2022
+.Dd October 4, 2023
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -927,6 +927,10 @@ A fixed value (1) to indicate that the option is present, 0 bytes.
 An RFC 3397 encoded string.
 .It Ic dname
 An RFC 1035 validated string.
+.It Ic uri
+If an array then the first two bytes are the URI length inside the option data.
+Otherwise, the whole option data is the URI.
+As a space is not allowed in the URI encoding, the URIs are space separated.
 .It Ic binhex Op : Ic length
 Binary data expressed as hexadecimal.
 .It Ic embed
index bb1c1fca5793591387a7125e1798b32af3de2759..9c930f3817ef90dd299981e796c8131d59268145 100644 (file)
@@ -1833,6 +1833,8 @@ err_sla:
                        t |= OT_ADDRIPV6;
                else if (strcasecmp(arg, "string") == 0)
                        t |= OT_STRING;
+               else if (strcasecmp(arg, "uri") == 0)
+                       t |= OT_URI;
                else if (strcasecmp(arg, "byte") == 0)
                        t |= OT_UINT8;
                else if (strcasecmp(arg, "bitflags") == 0)