2 * Copyright (c) 2017, JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of JANET(UK) nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 #if JANSSON_VERSION_HEX < 0x020500
41 #include "../jansson_iterators.h"
43 #include <trp_internal.h>
44 #include <tid_internal.h>
45 #include <tr_filter.h>
46 #include <tr_config.h>
48 #define FILTER_PATH "./test-filters/"
51 * Load a JSON file containing filters and return the filters from the first rp_client.
53 * @param fname File to read
54 * @param filt_out Will point to the loaded filter on success
55 * @return Return value from tr_cfg_parse_one_config_file()
57 int load_filter(char *fname, TR_FILTER_SET **filts_out)
59 TR_CFG_MGR *cfg_mgr=tr_cfg_mgr_new(NULL);
60 TR_CFG_RC rc=TR_CFG_ERROR;
66 rc=tr_parse_config(cfg_mgr, 1, &fname);
67 if (rc!=TR_CFG_SUCCESS)
70 /* Steal the filter from the first rp_client */
72 assert(cfg_mgr->new->rp_clients);
73 assert(cfg_mgr->new->rp_clients->filters);
74 *filts_out=cfg_mgr->new->rp_clients->filters;
75 cfg_mgr->new->rp_clients->filters=NULL; /* can't use the _set_filter() because that will free the filter */
76 talloc_steal(NULL, *filts_out);
79 tr_cfg_mgr_free(cfg_mgr);
84 * Test that filters load / fail to load as expected.
86 * @return 1 if all tests pass
88 int test_load_filter(void)
90 TR_FILTER_SET *filts=NULL;
92 assert(TR_CFG_SUCCESS==load_filter(FILTER_PATH "valid-filt.json", &filts));
93 if (filts) tr_filter_set_free(filts);
95 assert(TR_CFG_NOPARSE==load_filter(FILTER_PATH "invalid-filt-repeated-key.json", &filts));
96 if (filts) tr_filter_set_free(filts);
98 assert(TR_CFG_NOPARSE==load_filter(FILTER_PATH "invalid-filt-unknown-field.json", &filts));
99 if (filts) tr_filter_set_free(filts);
105 * Read the first inforec from the TR_MSG encoded in JSON file named fname.
107 * @param fname Filename with path for TR_MSG JSON
108 * @return Pointer to the decoded inforec, or NULL on failure
110 TRP_INFOREC *load_inforec(const char *fname)
114 TRP_INFOREC *inforec=NULL;
115 json_t *decoded=json_load_file(fname, JSON_REJECT_DUPLICATES|JSON_DISABLE_EOF_CHECK, NULL);
116 char *encoded=json_dumps(decoded, 0); /* silly way to read the file without mucking around */
119 json_decref(decoded);
122 assert(msg= tr_msg_decode(NULL, encoded, strlen(encoded)));
123 assert(upd=tr_msg_get_trp_upd(msg));
124 assert(inforec=trp_upd_get_inforec(upd));
125 /* now remove the inforec from the update context */
126 talloc_steal(NULL, inforec);
127 tr_msg_free_decoded(msg);
128 tr_msg_free_encoded(encoded);
132 /* make this bigger than your message file */
133 #define MAX_FILE_SIZE 20000
134 TID_REQ *load_tid_req(const char *fname)
142 msgbuf=malloc(MAX_FILE_SIZE);
146 msglen=fread(msgbuf, 1, MAX_FILE_SIZE, f);
149 msg= tr_msg_decode(NULL, msgbuf, msglen);
154 assert(tr_msg_get_msg_type(msg)==TID_REQUEST);
156 /* take the tid req out of the msg */
157 out=tr_msg_get_req(msg);
158 tr_msg_set_req(msg, NULL);
161 tr_msg_free_decoded(msg);
166 * Read a set of filters from a config JSON in filt_fname and test against the tid_req or inforec in target_fname.
167 * If expect==1, succeed if the target is accepted by the filter, otherwise succeed if it is rejected.
168 * Takes filters from the first rp_realm defined in the filter file and the first inforec or tid req from
171 * @param filt_fname Name of JSON file containing filters
172 * @param ftype Which type of filter to test
173 * @param target_fname Name of JSON file containing inforec
174 * @param expected_match 1 if we expect a match, 0 otherwise
175 * @param expected_action Expected action if the filter matches
176 * @return 1 if expected result is obtained, 0 or does not return otherwise
178 int test_one_filter(char *filt_fname,
179 TR_FILTER_TYPE ftype,
180 const char *target_fname,
182 TR_FILTER_ACTION expected_action)
184 TR_FILTER_TARGET *target=NULL;
185 TR_FILTER_SET *filts=NULL;
186 TR_FILTER_ACTION action=TR_FILTER_ACTION_UNKNOWN;
188 /* load filter for first test */
189 assert(TR_CFG_SUCCESS==load_filter(filt_fname, &filts));
191 /* load the target req or inforec */
193 case TR_FILTER_TYPE_TID_INBOUND:
194 target=tr_filter_target_tid_req(NULL, load_tid_req(target_fname));
197 case TR_FILTER_TYPE_TRP_INBOUND:
198 case TR_FILTER_TYPE_TRP_OUTBOUND:
199 /* TODO: read realm and community */
200 target= tr_filter_target_trp_inforec(NULL, NULL, load_inforec(target_fname));
204 printf("Unknown filter type.\n");
208 assert(expected_match==tr_filter_apply(target, tr_filter_set_get(filts, ftype), NULL, &action));
209 if (expected_match==TR_FILTER_MATCH)
210 assert(action==expected_action);
212 tr_filter_set_free(filts);
214 case TR_FILTER_TYPE_TID_INBOUND:
215 tid_req_free(target->tid_req);
218 case TR_FILTER_TYPE_TRP_INBOUND:
219 case TR_FILTER_TYPE_TRP_OUTBOUND:
220 trp_inforec_free(target->trp_inforec);
221 if (target->trp_upd!=NULL)
222 trp_upd_free(target->trp_upd);
226 printf("Unknown filter type.\n");
228 tr_filter_target_free(target);
232 int test_filter(void)
234 json_t *test_list=json_load_file(FILTER_PATH "filter-tests.json", JSON_DISABLE_EOF_CHECK, NULL);
237 char *filt_file, *target_file;
238 TR_FILTER_TYPE ftype;
240 TR_FILTER_ACTION action;
242 json_array_foreach(test_list, ii, this) {
243 printf("Running filter test case: %s\n", json_string_value(json_object_get(this, "test label")));
246 filt_file=talloc_strdup(NULL, json_string_value(json_object_get(this, "filter file")));
247 ftype=tr_filter_type_from_string(json_string_value(json_object_get(this, "filter type")));
248 target_file=talloc_strdup(NULL, json_string_value(json_object_get(this, "target file")));
249 if (0==strcmp("yes", json_string_value(json_object_get(this, "expect match"))))
250 expect_match=TR_FILTER_MATCH;
252 expect_match=TR_FILTER_NO_MATCH;
254 if (0==strcmp("accept", json_string_value(json_object_get(this, "action"))))
255 action=TR_FILTER_ACTION_ACCEPT;
257 action=TR_FILTER_ACTION_REJECT;
259 assert(test_one_filter(filt_file, ftype, target_file, expect_match, action));
261 talloc_free(filt_file);
262 talloc_free(target_file);
272 assert(test_load_filter());
273 assert(test_filter());