From: Arran Cudbard-Bell Date: Fri, 23 Oct 2020 20:13:06 +0000 (-0500) Subject: Fix filtering functions to work with nested attributes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6e0a00a97419f243cf02bbc5cbf36d4ee5abd686;p=thirdparty%2Ffreeradius-server.git Fix filtering functions to work with nested attributes --- diff --git a/src/bin/radclient.c b/src/bin/radclient.c index 209b04a68c6..5561ac2abaa 100644 --- a/src/bin/radclient.c +++ b/src/bin/radclient.c @@ -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 { diff --git a/src/bin/radsniff.c b/src/bin/radsniff.c index 8a843289b72..7a2a0704769 100644 --- a/src/bin/radsniff.c +++ b/src/bin/radsniff.c @@ -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; } } diff --git a/src/bin/unit_test_module.c b/src/bin/unit_test_module.c index dd0bcfb1be3..5b35edf9f62 100644 --- a/src/bin/unit_test_module.c +++ b/src/bin/unit_test_module.c @@ -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); diff --git a/src/lib/util/pair.c b/src/lib/util/pair.c index 7aa33b2652b..43cf981affa 100644 --- a/src/lib/util/pair.c +++ b/src/lib/util/pair.c @@ -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; + } } } diff --git a/src/lib/util/pair.h b/src/lib/util/pair.h index 29e0cf707f2..d9ced2502ad 100644 --- a/src/lib/util/pair.h +++ b/src/lib/util/pair.h @@ -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);