]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: net_is_in_network() - Fix checking scope ID in IPv6
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 20 Jan 2023 15:43:55 +0000 (17:43 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Fri, 27 Jan 2023 13:01:47 +0000 (13:01 +0000)
Using "ip%iface1" shouldn't match "ip%iface2". However, do allow it to
match "ip" when %iface is missing.

src/lib/net.c
src/lib/test-net.c

index b101b45ce08d6a29f480b83000bc032ec16efec0..326cebe099f4fc6baf5fa3f557ffd3b1797b22e3 100644 (file)
@@ -1228,6 +1228,12 @@ bool net_is_in_network(const struct ip_addr *ip,
        } else {
                ip1 = (const void *)&ip->u.ip6;
                ip2 = (const void *)&net_ip->u.ip6;
+               if (ip->scope_id != net_ip->scope_id &&
+                   net_ip->scope_id != 0) {
+                       /* %iface1 != %iface2 never matches, but allow
+                          missing interface on the net_ip */
+                       return FALSE;
+               }
        }
 
        /* check first the full 32bit ints */
index f703a983e92cd41e3cd6f94382aa2c665feb7096..19887d830bb9d37c6febf5b3d4b2000bb3229775 100644 (file)
@@ -32,6 +32,7 @@ static void test_net_is_in_network(void)
                { "::ffff:1.2.3.4", "1.2.3.4", 32, TRUE },
                { "::ffff:1.2.3.4", "1.2.3.3", 32, FALSE },
                { "::ffff:1.2.3.4", "::ffff:1.2.3.4", 0, FALSE },
+               { "fe80::1%lo", "fe80::%lo", 8, TRUE },
                { "fe80::1%lo", "fe80::", 8, TRUE },
        };
        struct ip_addr ip, net_ip;
@@ -55,6 +56,13 @@ static void test_net_is_in_network(void)
        net_ip.family = 0;
        test_assert(!net_is_in_network(&ip, &net_ip, 0));
        test_assert(!net_is_in_network(&net_ip, &ip, 0));
+
+       /* make sure a changed scope_id won't match */
+       test_assert(net_addr2ip("fe80::1%lo", &ip) == 0);
+       test_assert(net_addr2ip("fe80::1%lo", &net_ip) == 0);
+       test_assert(net_is_in_network(&ip, &net_ip, 1));
+       net_ip.scope_id++;
+       test_assert(!net_is_in_network(&ip, &net_ip, 1));
        test_end();
 }