]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow parsing 192/8 and 192.0/16, etc.
authorAlan T. DeKok <aland@freeradius.org>
Tue, 1 Apr 2025 00:39:19 +0000 (20:39 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 1 Apr 2025 00:39:19 +0000 (20:39 -0400)
src/lib/server/tmpl_tokenize.c
src/tests/keywords/filename
src/tests/keywords/ipaddr

index 4e9f96124e9782a573753120af3f0466dc3f2be6..efed9109ba2e4f0733e0f709309b7d306cfa013a 100644 (file)
@@ -2646,35 +2646,33 @@ static fr_slen_t tmpl_afrom_ipv4_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_
 {
        tmpl_t          *vpt;
        fr_sbuff_t      our_in = FR_SBUFF(in);
-       uint8_t         octet;
        fr_type_t       type;
+       int             count;
+       uint32_t        ipaddr;
+       uint8_t         addr[4] = {}, prefix = 32;
 
-       /*
-        *      Check for char sequence
-        *
-        *      xxx.xxx.xxx.xxx
-        */
-       if (!(fr_sbuff_out(NULL, &octet, &our_in) && fr_sbuff_next_if_char(&our_in, '.') &&
-             fr_sbuff_out(NULL, &octet, &our_in) && fr_sbuff_next_if_char(&our_in, '.') &&
-             fr_sbuff_out(NULL, &octet, &our_in) && fr_sbuff_next_if_char(&our_in, '.') &&
-             fr_sbuff_out(NULL, &octet, &our_in))) {
-       error:
-               FR_SBUFF_ERROR_RETURN(&our_in);
+       for (count = 0; count < 4; count++) {
+               if (!fr_sbuff_out(NULL, &addr[count], &our_in)) FR_SBUFF_ERROR_RETURN(&our_in);
+
+               if (count == 3) break;
+
+               if (fr_sbuff_next_if_char(&our_in, '.')) continue;
+
+               if (!fr_sbuff_is_char(&our_in, '/')) FR_SBUFF_ERROR_RETURN(&our_in);
        }
 
        /*
-        *      If it has a trailing '/' then it's probably
-        *      an IP prefix.
+        *      If it has a trailing '/' then it's an IP prefix.
         */
        if (fr_sbuff_next_if_char(&our_in, '/')) {
-               if (fr_sbuff_out(NULL, &octet, &our_in) < 0) {
+               if (fr_sbuff_out(NULL, &prefix, &our_in) < 0) {
                        fr_strerror_const("IPv4 CIDR mask malformed");
-                       goto error;
+                       FR_SBUFF_ERROR_RETURN(&our_in);
                }
 
-               if (octet > 32) {
+               if (prefix > 32) {
                        fr_strerror_const("IPv4 CIDR mask too high");
-                       goto error;
+                       FR_SBUFF_ERROR_RETURN(&our_in);
                }
 
                type = FR_TYPE_IPV4_PREFIX;
@@ -2684,16 +2682,23 @@ static fr_slen_t tmpl_afrom_ipv4_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_
 
        if (!tmpl_substr_terminal_check(&our_in, p_rules)) {
                fr_strerror_const("Unexpected text after IPv4 string or prefix");
-               goto error;
+               FR_SBUFF_ERROR_RETURN(&our_in);
        }
 
        MEM(vpt = tmpl_alloc(ctx, TMPL_TYPE_DATA, T_BARE_WORD, fr_sbuff_start(&our_in), fr_sbuff_used(&our_in)));
-       if (fr_value_box_from_substr(vpt, &vpt->data.literal, type, NULL,
-                                    &FR_SBUFF_REPARSE(&our_in),
-                                    NULL) < 0) {
-               talloc_free(vpt);
-               goto error;
+       fr_value_box_init(&vpt->data.literal, type, NULL, false);
+       vpt->data.literal.vb_ip.af = AF_INET;
+       vpt->data.literal.vb_ip.prefix = prefix;
+
+       /*
+        *      Zero out lower bits
+        */
+       ipaddr = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
+       if (prefix < 32) {
+               ipaddr &= ~((uint32_t) 0) << (32 - prefix);
        }
+       vpt->data.literal.vb_ip.addr.v4.s_addr = htonl(ipaddr);
+
        *out = vpt;
 
        FR_SBUFF_SET_RETURN(in, &our_in);
index e2f86bbb16ae685793ff35e40046d2167c167505..3b1b6b94f6b17b87732f1e270a59203f1a8f6682 100644 (file)
@@ -3,7 +3,7 @@
 #
 ipv4prefix prefix
 
-prefix = "192.0.2/24"
+prefix = 192.0.2/24
 
 if (%file.escape(%taint("../foobar")) != "_x2e_x2e_x2ffoobar") {
        test_fail
index 0a32f00a6a7ad33aa451ad1405a5a6d9bdfb9921..a2e44f840ac1285fb925b6a7a3791d3935267cd3 100644 (file)
@@ -2,6 +2,7 @@
 #  PRE: if
 #
 ipaddr result_ipaddr
+ipv4prefix prefix
 
 if (!(NAS-IP-Address == 127.0.0.1)) {
        test_fail
@@ -31,4 +32,17 @@ if (!(result_ipaddr == 127.0.0.4)) {
        test_fail
 }
 
+prefix = 192.0.2/24
+if "%{prefix}" != "192.0.2.0/24" {
+       test_fail
+}
+
+#
+#  And with extra bits, which are cleared out.
+#
+prefix = 192.0.2.2/24
+if "%{prefix}" != "192.0.2.0/24" {
+       test_fail
+}
+
 success