]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Fix filtering functions to work with nested attributes
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 23 Oct 2020 20:13:06 +0000 (15:13 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 23 Oct 2020 20:13:15 +0000 (15:13 -0500)
src/bin/radclient.c
src/bin/radsniff.c
src/bin/unit_test_module.c
src/lib/util/pair.c
src/lib/util/pair.h

index 209b04a68c6095280954ac6ed60f09b15d553905..5561ac2abaa284b1a5c4622df73a5185f67cdaf0 100644 (file)
@@ -1076,7 +1076,7 @@ static int recv_one_packet(fr_time_t wait_time)
                VALUE_PAIR const *failed[2];
 
                fr_pair_list_sort(&request->reply_pairs, fr_pair_cmp_by_da);
-               if (fr_pair_validate(failed, request->filter, request->reply_pairs)) {
+               if (fr_pair_validate(failed, &request->filter, &request->reply_pairs)) {
                        RDEBUG("%s: Response passed filter", request->name);
                        stats.passed++;
                } else {
index 8a843289b72579621a85440cb10a4b5672398c6e..7a2a0704769f473d5e6d007c83b8b97c245652a0 100644 (file)
@@ -1426,7 +1426,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt
                         */
                        if (conf->filter_response_vps) {
                                fr_pair_list_sort(&packet->vps, fr_pair_cmp_by_da);
-                               if (!fr_pair_validate_relaxed(NULL, conf->filter_response_vps, packet->vps)) {
+                               if (!fr_pair_validate_relaxed(NULL, &conf->filter_response_vps, &packet->vps)) {
                                        goto drop_response;
                                }
                        }
@@ -1622,7 +1622,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt
                 *      Now verify the packet passes the attribute filter
                 */
                if (conf->filter_request_vps) {
-                       if (!fr_pair_validate_relaxed(NULL, conf->filter_request_vps, packet->vps)) {
+                       if (!fr_pair_validate_relaxed(NULL, &conf->filter_request_vps, &packet->vps)) {
                                goto drop_request;
                        }
                }
index dd0bcfb1be339abbf444949679ff56d03d5caeef..5b35edf9f62e257977bd942598529a84b9c206a6 100644 (file)
@@ -989,7 +989,7 @@ int main(int argc, char *argv[])
                vp->vp_uint32 = request->reply->code;
 
 
-               if (!fr_pair_validate(failed, filter_vps, request->reply_pairs)) {
+               if (!fr_pair_validate(failed, &filter_vps, &request->reply_pairs)) {
                        fr_pair_validate_debug(request, failed);
                        fr_perror("Output file %s does not match attributes in filter %s",
                                  output_file ? output_file : input_file, filter_file);
index 7aa33b2652b3ab286c22cf8466c3d43a5f9890c4..43cf981affa22047ee86e4e4485dd72df7548dff 100644 (file)
@@ -1137,7 +1137,7 @@ void fr_pair_validate_debug(TALLOC_CTX *ctx, VALUE_PAIR const *failed[2])
  * @param filter attributes to check list against.
  * @param list attributes, probably a request or reply
  */
-bool fr_pair_validate(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, VALUE_PAIR *list)
+bool fr_pair_validate(VALUE_PAIR const *failed[2], VALUE_PAIR **filter, VALUE_PAIR **list)
 {
        fr_cursor_t filter_cursor;
        fr_cursor_t list_cursor;
@@ -1154,11 +1154,11 @@ bool fr_pair_validate(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, VALUE_PAI
         *
         *      @todo this should be removed one we have sets and lists
         */
-       fr_pair_list_sort(&filter, fr_pair_cmp_by_da);
-       fr_pair_list_sort(&list, fr_pair_cmp_by_da);
+       fr_pair_list_sort(filter, fr_pair_cmp_by_da);
+       fr_pair_list_sort(list, fr_pair_cmp_by_da);
 
-       check = fr_cursor_init(&filter_cursor, &filter);
-       match = fr_cursor_init(&list_cursor, &list);
+       check = fr_cursor_init(&filter_cursor, filter);
+       match = fr_cursor_init(&list_cursor, list);
        while (match || check) {
                /*
                 *      Lists are of different lengths
@@ -1179,7 +1179,18 @@ bool fr_pair_validate(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, VALUE_PAI
                 *      Note that the RFCs say that for attributes of
                 *      the same type, order is important.
                 */
-               if (fr_pair_cmp(check, match) != 1) goto mismatch;
+               switch (check->da->type) {
+               case FR_TYPE_STRUCTURAL:
+                       if (!fr_pair_validate(failed, &check->vp_group, &match->vp_group)) goto mismatch;
+                       break;
+
+               default:
+                       /*
+                        *      This attribute passed the filter
+                        */
+                       if (!fr_pair_cmp(check, match)) goto mismatch;
+                       break;
+               }
 
                check = fr_cursor_next(&filter_cursor);
                match = fr_cursor_next(&list_cursor);
@@ -1204,7 +1215,7 @@ mismatch:
  * @param filter attributes to check list against.
  * @param list attributes, probably a request or reply
  */
-bool fr_pair_validate_relaxed(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, VALUE_PAIR *list)
+bool fr_pair_validate_relaxed(VALUE_PAIR const *failed[2], VALUE_PAIR **filter, VALUE_PAIR **list)
 {
        vp_cursor_t     filter_cursor;
        vp_cursor_t     list_cursor;
@@ -1221,11 +1232,11 @@ bool fr_pair_validate_relaxed(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, V
         *
         *      @todo this should be removed one we have sets and lists
         */
-       fr_pair_list_sort(&filter, fr_pair_cmp_by_da);
-       fr_pair_list_sort(&list, fr_pair_cmp_by_da);
+       fr_pair_list_sort(filter, fr_pair_cmp_by_da);
+       fr_pair_list_sort(list, fr_pair_cmp_by_da);
 
-       fr_pair_cursor_init(&list_cursor, &list);
-       for (check = fr_pair_cursor_init(&filter_cursor, &filter);
+       fr_pair_cursor_init(&list_cursor, list);
+       for (check = fr_pair_cursor_init(&filter_cursor, filter);
             check;
             check = fr_pair_cursor_next(&filter_cursor)) {
                /*
@@ -1252,10 +1263,18 @@ bool fr_pair_validate_relaxed(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, V
                for (match = fr_pair_cursor_head(&list_cursor);
                     ATTRIBUTE_EQ(match, check);
                     match = fr_pair_cursor_next(&list_cursor)) {
-                       /*
-                        *      This attribute passed the filter
-                        */
-                       if (!fr_pair_cmp(check, match)) goto mismatch;
+                       switch (check->da->type) {
+                       case FR_TYPE_STRUCTURAL:
+                               if (!fr_pair_validate_relaxed(failed, &check->vp_group, &match->vp_group)) goto mismatch;
+                               break;
+
+                       default:
+                               /*
+                                *      This attribute passed the filter
+                                */
+                               if (!fr_pair_cmp(check, match)) goto mismatch;
+                               break;
+                       }
                }
        }
 
index 29e0cf707f21480848d5bee1ea6ef4ee69ed35fe..d9ced2502ad2f28d29d9d1e64f0385c3f85d546a 100644 (file)
@@ -302,8 +302,8 @@ void                fr_pair_list_sort(VALUE_PAIR **vps, fr_cmp_t cmp);
 
 /* Filtering */
 void           fr_pair_validate_debug(TALLOC_CTX *ctx, VALUE_PAIR const *failed[2]);
-bool           fr_pair_validate(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, VALUE_PAIR *list);
-bool           fr_pair_validate_relaxed(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, VALUE_PAIR *list);
+bool           fr_pair_validate(VALUE_PAIR const *failed[2], VALUE_PAIR **filter, VALUE_PAIR **list);
+bool           fr_pair_validate_relaxed(VALUE_PAIR const *failed[2], VALUE_PAIR **filter, VALUE_PAIR **list);
 
 /* Lists */
 int            fr_pair_list_copy(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR *from);