2 * Copyright (c) 2012-2018, 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.
41 #include <tr_cfgwatch.h>
43 #include <tr_config.h>
44 #include <tr_gss_names.h>
46 #include <tr_filter.h>
47 #include <trust_router/tr_constraint.h>
50 #include <trust_router/trp.h>
52 #if JANSSON_VERSION_HEX < 0x020500
53 #include "jansson_iterators.h"
57 TR_CFG_RC tr_cfg_parse_gss_names(TALLOC_CTX *mem_ctx, json_t *jgss_names, TR_GSS_NAMES **gssn_out)
59 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
60 TR_GSS_NAMES *gn=NULL;
64 TR_CFG_RC rc = TR_CFG_ERROR;
66 if (jgss_names==NULL) {
67 tr_err("tr_cfg_parse_gss_names: Bad parameters.");
72 if (!json_is_array(jgss_names)) {
73 tr_err("tr_cfg_parse_gss_names: gss_names not an array.");
78 gn=tr_gss_names_new(tmp_ctx);
79 for (ii=0; ii<json_array_size(jgss_names); ii++) {
80 jname=json_array_get(jgss_names, ii);
81 if (!json_is_string(jname)) {
82 tr_err("tr_cfg_parse_gss_names: Encountered non-string gss name.");
87 name=tr_new_name(json_string_value(jname));
89 tr_err("tr_cfg_parse_gss_names: Out of memory allocating gss name.");
94 if (tr_gss_names_add(gn, name)!=0) {
96 tr_err("tr_cfg_parse_gss_names: Unable to add gss name to RP client.");
103 talloc_steal(mem_ctx, *gssn_out);
107 talloc_free(tmp_ctx);
111 /* default filter accepts realm and *.realm */
112 static TR_FILTER_SET *tr_cfg_default_filters(TALLOC_CTX *mem_ctx, TR_NAME *realm, TR_CFG_RC *rc)
114 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
115 TR_FILTER *filt=NULL;
116 TR_FLINE *fline = NULL;
117 TR_FSPEC *fspec = NULL;
118 TR_FILTER_SET *filt_set=NULL;
119 TR_CONSTRAINT *cons=NULL;
121 TR_NAME *n_prefix=tr_new_name("*.");
122 TR_NAME *n_rp_realm_1=tr_new_name("rp_realm");
123 TR_NAME *n_rp_realm_2=tr_new_name("rp_realm");
124 TR_NAME *n_domain=tr_new_name("domain");
125 TR_NAME *n_realm=tr_new_name("realm");
128 if ((realm==NULL) || (rc==NULL)) {
129 tr_debug("tr_cfg_default_filters: invalid arguments.");
131 *rc=TR_CFG_BAD_PARAMS;
135 if ((n_prefix==NULL) ||
136 (n_rp_realm_1==NULL) ||
137 (n_rp_realm_2==NULL) ||
140 tr_debug("tr_cfg_default_filters: unable to allocate names.");
145 filt=tr_filter_new(tmp_ctx);
147 tr_debug("tr_cfg_default_filters: could not allocate filter.");
151 tr_filter_set_type(filt, TR_FILTER_TYPE_TID_INBOUND);
153 fline = tr_fline_new(tmp_ctx);
155 tr_debug("tr_cfg_default_filters: could not allocate filter line.");
160 fline->action=TR_FILTER_ACTION_ACCEPT;
162 fspec=tr_fspec_new(tmp_ctx);
163 fspec->field=n_rp_realm_1;
164 n_rp_realm_1=NULL; /* we don't own this name any more */
166 name=tr_dup_name(realm);
168 tr_debug("tr_cfg_default_filters: could not allocate realm name.");
172 tr_fspec_add_match(fspec, name);
173 name=NULL; /* we no longer own the name */
175 if (tr_fline_add_spec(fline, fspec) == NULL) {
176 tr_debug("tr_cfg_default_filters: could not add first spec to filter line");
181 /* now do the wildcard name */
182 fspec=tr_fspec_new(tmp_ctx);
183 fspec->field=n_rp_realm_2;
184 n_rp_realm_2=NULL; /* we don't own this name any more */
186 if (NULL==(name=tr_name_cat(n_prefix, realm))) {
187 tr_debug("tr_cfg_default_filters: could not allocate wildcard realm name.");
192 tr_fspec_add_match(fspec, name);
193 name=NULL; /* we no longer own the name */
195 if (tr_fline_add_spec(fline, fspec) == NULL) {
196 tr_debug("tr_cfg_default_filters: could not add second spec to filter line");
201 /* domain constraint */
202 if (NULL==(cons=tr_constraint_new(fline))) {
203 tr_debug("tr_cfg_default_filters: could not allocate domain constraint.");
209 n_domain=NULL; /* belongs to the constraint now */
210 name=tr_dup_name(realm);
212 tr_debug("tr_cfg_default_filters: could not allocate realm name for domain constraint.");
216 cons->matches[0]=name;
217 name=tr_name_cat(n_prefix, realm);
219 tr_debug("tr_cfg_default_filters: could not allocate wildcard realm name for domain constraint.");
223 cons->matches[1]=name;
225 fline->domain_cons=cons;
228 /* realm constraint */
229 if (NULL==(cons=tr_constraint_new(fline))) {
230 tr_debug("tr_cfg_default_filters: could not allocate realm constraint.");
236 n_realm=NULL; /* belongs to the constraint now */
237 name=tr_dup_name(realm);
239 tr_debug("tr_cfg_default_filters: could not allocate realm name for realm constraint.");
243 cons->matches[0]=name;
244 name=tr_name_cat(n_prefix, realm);
246 tr_debug("tr_cfg_default_filters: could not allocate wildcard realm name for realm constraint.");
250 cons->matches[1]=name;
252 fline->realm_cons=cons;
254 /* put the fline in the filter */
255 if (NULL == tr_filter_add_line(filt, fline)) {
256 tr_debug("tr_cfg_default_filters: could not add line to filter.");
261 /* put the filter in a set */
262 filt_set=tr_filter_set_new(tmp_ctx);
263 if ((filt_set==NULL)||(0!=tr_filter_set_add(filt_set, filt))) {
264 tr_debug("tr_cfg_default_filters: could not allocate filter set.");
268 talloc_steal(mem_ctx, filt_set);
271 talloc_free(tmp_ctx);
273 if (*rc!=TR_CFG_SUCCESS)
277 tr_free_name(n_prefix);
278 if (n_rp_realm_1!=NULL)
279 tr_free_name(n_rp_realm_1);
280 if (n_rp_realm_2!=NULL)
281 tr_free_name(n_rp_realm_2);
283 tr_free_name(n_realm);
285 tr_free_name(n_domain);
292 /* parses rp client */
293 static TR_RP_CLIENT *tr_cfg_parse_one_rp_client(TALLOC_CTX *mem_ctx, json_t *jrealm, TR_CFG_RC *rc)
295 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
296 TR_RP_CLIENT *client=NULL;
297 TR_CFG_RC call_rc=TR_CFG_ERROR;
298 TR_FILTER_SET *new_filts=NULL;
301 json_t *jrealm_id=NULL;
303 *rc=TR_CFG_ERROR; /* default to error if not set */
305 if ((!jrealm) || (!rc)) {
306 tr_err("tr_cfg_parse_one_rp_client: Bad parameters.");
308 *rc=TR_CFG_BAD_PARAMS;
312 if ((NULL==(jrealm_id=json_object_get(jrealm, "realm"))) || (!json_is_string(jrealm_id))) {
313 tr_debug("tr_cfg_parse_one_rp_client: no realm ID found.");
314 *rc=TR_CFG_BAD_PARAMS;
318 tr_debug("tr_cfg_parse_one_rp_client: realm_id=\"%s\"", json_string_value(jrealm_id));
319 realm=tr_new_name(json_string_value(jrealm_id));
321 tr_err("tr_cfg_parse_one_rp_client: could not allocate realm ID.");
326 if (NULL==(client=tr_rp_client_new(tmp_ctx))) {
327 tr_err("tr_cfg_parse_one_rp_client: could not allocate rp client.");
332 call_rc = tr_cfg_parse_gss_names(client, json_object_get(jrealm, "gss_names"), &(client->gss_names));
334 if (call_rc!=TR_CFG_SUCCESS) {
335 tr_err("tr_cfg_parse_one_rp_client: could not parse gss_names.");
341 jfilt=json_object_get(jrealm, "filters");
343 new_filts=tr_cfg_parse_filters(tmp_ctx, jfilt, &call_rc);
344 if (call_rc!=TR_CFG_SUCCESS) {
345 tr_err("tr_cfg_parse_one_rp_client: could not parse filters.");
350 tr_debug("tr_cfg_parse_one_rp_client: no filters specified, using default filters.");
351 new_filts= tr_cfg_default_filters(tmp_ctx, realm, &call_rc);
352 if (call_rc!=TR_CFG_SUCCESS) {
353 tr_err("tr_cfg_parse_one_rp_client: could not set default filters.");
359 tr_rp_client_set_filters(client, new_filts);
366 if (*rc==TR_CFG_SUCCESS)
367 talloc_steal(mem_ctx, client);
373 talloc_free(tmp_ctx);
377 /* Determine whether the realm is an RP realm */
378 static int tr_cfg_is_rp_realm(json_t *jrealm)
380 /* Check that we have a gss name. */
381 if (NULL != json_object_get(jrealm, "gss_names"))
387 /* Parse any rp clients in the j_realms object. Ignores other realms. */
388 TR_RP_CLIENT *tr_cfg_parse_rp_clients(TALLOC_CTX *mem_ctx, json_t *jrealms, TR_CFG_RC *rc)
390 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
391 TR_RP_CLIENT *clients=NULL;
392 TR_RP_CLIENT *new_client=NULL;
393 json_t *this_jrealm=NULL;
397 if ((jrealms==NULL) || (!json_is_array(jrealms))) {
398 tr_err("tr_cfg_parse_rp_clients: realms not an array");
399 *rc=TR_CFG_BAD_PARAMS;
403 for (ii=0; ii<json_array_size(jrealms); ii++) {
404 this_jrealm=json_array_get(jrealms, ii);
405 if (tr_cfg_is_rp_realm(this_jrealm)) {
406 new_client=tr_cfg_parse_one_rp_client(tmp_ctx, this_jrealm, rc);
407 if ((*rc)!=TR_CFG_SUCCESS) {
408 tr_err("tr_cfg_parse_rp_clients: error decoding realm entry %d", ii+1);
412 tr_rp_client_add(clients, new_client);
417 talloc_steal(mem_ctx, clients);
420 talloc_free(tmp_ctx);