Branch data Line data Source code
1 : : /* zxlib.c - Utility functions for generated (and other) code
2 : : * Copyright (c) 2010 Sampo Kellomaki (sampo@iki.fi), All Rights Reserved.
3 : : * Copyright (c) 2006-2009 Symlabs (symlabs@symlabs.com), All Rights Reserved.
4 : : * Author: Sampo Kellomaki (sampo@iki.fi)
5 : : * This is confidential unpublished proprietary source code of the author.
6 : : * NO WARRANTY, not even implied warranties. Contains trade secrets.
7 : : * Distribution prohibited unless authorized in writing.
8 : : * Licensed under Apache License 2.0, see file COPYING.
9 : : * $Id: zxlib.c,v 1.41 2009-11-24 23:53:40 sampo Exp $
10 : : *
11 : : * 28.5.2006, created --Sampo
12 : : * 8.8.2006, moved lookup functions to generated code --Sampo
13 : : * 12.8.2006, added special scanning of xmlns to avoid backtracking elem recognition --Sampo
14 : : * 26.8.2006, significant Common Subexpression Elimination (CSE) --Sampo
15 : : * 30.9.2007, more CSE --Sampo
16 : : * 7.10.2008, added documentation --Sampo
17 : : * 26.5.2010, added XML parse error reporting --Sampo
18 : : * 27.10.2010, re-engineered namespace handling --Sampo
19 : : */
20 : :
21 : : #include "platform.h" /* needed on Win32 for snprintf(), va_copy() et al. */
22 : :
23 : : //#include <pthread.h>
24 : : //#ifndef MACOSX
25 : : //#include <malloc.h>
26 : : //#endif
27 : : #include <memory.h>
28 : : #include <string.h>
29 : : #include <stdarg.h>
30 : : #include <stdio.h>
31 : : #include <stdlib.h>
32 : :
33 : : #include "errmac.h"
34 : : #include "zx.h"
35 : : #include "c/zx-ns.h"
36 : : #include "c/zx-data.h"
37 : :
38 : : /*() ZX implementation of memmem(3) for platforms that do not have this. */
39 : :
40 : : /* Called by: covimp_test, zxid_map_sec_mech x3 */
41 : : char* zx_memmem(const char* haystack, int haystack_len, const char* needle, int needle_len)
42 : 1 : {
43 : 1 : const char* lim = haystack + haystack_len - needle_len;
44 [ + - ]: 3 : for (; haystack < lim; ++haystack)
45 [ + + ]: 3 : if (!memcmp(haystack, needle, needle_len))
46 : 1 : return (char*)haystack; /* discards const qualifier, but is right if haystack was modifiable, as often is the case. */
47 : 0 : return 0;
48 : : }
49 : :
50 : : /*() ZX memory allocator that does not zero the buffer. Allocation is
51 : : * potentially done relative to ZX context <<italic: c>>, though
52 : : * actual (2008) implementation simply uses malloc(3).
53 : : *
54 : : * Rather than reference this function directly, you should
55 : : * use the ZX_ALLOC() macro as much as possible.
56 : : *
57 : : * Some implementations may take c->mx mutex lock. However, they will
58 : : * do so such that no deadlock will result even if already taken. */
59 : :
60 : : /* Called by: zx_zalloc */
61 : : void* zx_alloc(struct zx_ctx* c, int size)
62 : 2930461 : {
63 : : char* p;
64 : 2930461 : p = malloc(size);
65 : : DD("malloc %p size=%d", p, size);
66 [ - + ]: 2930461 : if (!p) {
67 : 0 : ERR("Out-of-memory(%d)", size);
68 [ # # ]: 0 : if (size < 0)
69 [ # # ]: 0 : DIE_ACTION(1);
70 : 0 : exit(1);
71 : : }
72 : 2930461 : return p;
73 : : }
74 : :
75 : : /*() ZX memory allocator that zeroes the buffer. Allocation is
76 : : * potentially done relative to ZX context <<italic: c>>, though
77 : : * actual (2008) implementation simply uses malloc(3).
78 : : *
79 : : * Rather than reference this function directly, you should
80 : : * use the ZX_ALLOC() macro as much as possible. */
81 : :
82 : : /* Called by: zxid_parse_conf_raw */
83 : : void* zx_zalloc(struct zx_ctx* c, int size)
84 : 1985825 : {
85 : 1985825 : char* p = zx_alloc(c, size);
86 : 1985825 : ZERO(p, size);
87 : 1985825 : return p;
88 : : }
89 : :
90 : :
91 : : /*() ZX memory free'er. Freeing is
92 : : * potentially done relative to ZX context <<italic: c>>, though
93 : : * actual (2008) implementation simply uses free(3).
94 : : *
95 : : * Rather than reference this function directly, you should
96 : : * use the ZX_FREE() macro as much as possible. */
97 : :
98 : : /* Called by: */
99 : : void* zx_free(struct zx_ctx* c, void* p)
100 : 1423682 : {
101 [ + + ]: 1423682 : if (p)
102 : 1423530 : free(p);
103 : 1423682 : return 0;
104 : : }
105 : :
106 : : /*() Convert zx_str to C string. The ZX context will provide the memory. */
107 : :
108 : : /* Called by: zxid_add_a7n_at_to_pool x2, zxid_get_meta_ss, zxid_get_ses_sso_a7n, zxid_get_tas3_fault_actor, zxid_get_tas3_fault_comment, zxid_get_tas3_fault_ref, zxid_get_tas3_fault_sc1, zxid_get_tas3_fault_sc2, zxid_get_tas3_status_comment, zxid_get_tas3_status_ctlpt, zxid_get_tas3_status_ref, zxid_get_tas3_status_sc1, zxid_get_tas3_status_sc2, zxid_idp_sso, zxid_map_val_ss, zxid_mk_at_cert x3, zxid_mk_ent x2, zxid_saml2_post_enc, zxid_simple_idp_show_an, zxid_sp_sso_finalize x3, zxid_wsc_call, zxid_wsc_valid_re_env x2, zxid_wsf_validate_a7n x3, zxid_wsp_validate_env x2 */
109 : : char* zx_str_to_c(struct zx_ctx* c, struct zx_str* ss)
110 : 3997 : {
111 : 3997 : char* p = ZX_ALLOC(c, ss->len+1);
112 : 3997 : memcpy(p, ss->s, ss->len);
113 : 3997 : p[ss->len] = 0;
114 : 3997 : return p;
115 : : }
116 : :
117 : : /*() zx_str_conv() helps SWIG typemaps to achieve natural conversion
118 : : * to native length + data representations of scripting languages.
119 : : * Should not need to use directly. */
120 : :
121 : : /* Called by: covimp_test */
122 : : void zx_str_conv(struct zx_str* ss, int* out_len, char** out_s) /* SWIG typemap friendly */
123 : 1 : {
124 : 1 : *out_s = 0;
125 : 1 : *out_len = 0;
126 [ - + ]: 1 : if (!ss)
127 : 0 : return;
128 : 1 : *out_s = ss->s;
129 : 1 : *out_len = ss->len;
130 : : }
131 : :
132 : : /*() Free both the zx_str node and the underlying string data */
133 : :
134 : : /* Called by: main, zx_free_elem, zxenc_privkey_dec, zxenc_pubkey_enc, zxenc_symkey_enc, zxid_addmd x3, zxid_anoint_a7n x5, zxid_anoint_sso_resp x4, zxid_az_soap x3, zxid_cache_epr, zxid_decode_redir_or_post, zxid_fed_mgmt_cf x3, zxid_idp_dispatch x2, zxid_idp_list_cf_cgi x3, zxid_idp_soap, zxid_idp_soap_dispatch x2, zxid_idp_sso x4, zxid_lecp_check, zxid_mgmt x3, zxid_mk_art_deref, zxid_mk_enc_a7n, zxid_mk_enc_id, zxid_mk_mni, zxid_psobj_dec, zxid_psobj_enc, zxid_reg_svc x3, zxid_saml2_post_enc x2, zxid_saml2_redir, zxid_saml2_redir_enc x2, zxid_saml2_redir_url, zxid_saml2_resp_redir, zxid_send_sp_meta, zxid_simple_idp_show_an, zxid_simple_no_ses_cf x3, zxid_simple_ses_active_cf, zxid_simple_show_page x3, zxid_slo_resp_redir, zxid_snarf_eprs_from_ses, zxid_soap_call_raw, zxid_soap_cgi_resp_body x2, zxid_sp_dispatch x2, zxid_sp_mni_soap, zxid_sp_slo_soap, zxid_sp_soap, zxid_sp_soap_dispatch x7, zxid_sp_sso_finalize, zxid_ssos_anreq, zxid_start_sso_location, zxid_user_sha1_name, zxid_write_ent_to_cache, zxid_wsf_validate_a7n, zxsig_sign */
135 : : void zx_str_free(struct zx_ctx* c, struct zx_str* ss)
136 : 7764 : {
137 [ + - ]: 7764 : if (ss->s)
138 : 7764 : ZX_FREE(c, ss->s);
139 : 7764 : ZX_FREE(c, ss);
140 : 7764 : }
141 : :
142 : : /*() Construct zx_str from length and raw string data, which will be referenced, not copied. */
143 : :
144 : : /* Called by: zx_EASY_ENC_elem, zx_ref_len_elem, zx_ref_str, zx_strf, zxid_http_post_raw, zxid_map_val_ss, zxid_saml2_redir_enc x2, zxlog_path */
145 : : struct zx_str* zx_ref_len_str(struct zx_ctx* c, int len, const char* s)
146 : 16577 : {
147 : 16577 : struct zx_str* ss = ZX_ZALLOC(c, struct zx_str);
148 : 16577 : ss->s = (char*)s; /* ref points to underlying data */
149 : 16577 : ss->len = len;
150 : 16577 : return ss;
151 : : }
152 : :
153 : : /*() Construct zx_str from C string, which will be referenced, not copied. */
154 : :
155 : : /* Called by: a7n_test x3, covimp_test, test_ibm_cert_problem_enc_dec, x509_test x2, zxid_az_soap x8, zxid_ins_xacml_az_cd1_stmt, zxid_ins_xacml_az_stmt, zxid_map_val_ss, zxid_mk_di_req_svc, zxid_org_desc x5, zxid_simple_ses_active_cf x2, zxid_wsf_decor */
156 : : struct zx_str* zx_ref_str(struct zx_ctx* c, const char* s)
157 : 384 : {
158 [ - + ]: 384 : if (!s)
159 : 0 : return 0;
160 : 384 : return zx_ref_len_str(c, strlen(s), s);
161 : : }
162 : :
163 : : /*() Newly allocated string (node and data) of specified length, but uninitialized */
164 : :
165 : : /* Called by: zx_dup_len_str, zx_raw_cipher, zx_rsa_priv_dec, zx_rsa_priv_enc, zx_rsa_pub_dec, zx_rsa_pub_enc, zxenc_pubkey_enc, zxenc_symkey_enc, zxid_map_val_ss x5, zxid_pool_to_json, zxid_pool_to_ldif, zxid_pool_to_qs, zxid_psobj_dec, zxid_psobj_enc, zxid_template_page_cf, zxsig_sign x2 */
166 : : struct zx_str* zx_new_len_str(struct zx_ctx* c, int len)
167 : 30082 : {
168 : 30082 : struct zx_str* ss = ZX_ZALLOC(c, struct zx_str);
169 : 30082 : ss->s = ZX_ALLOC(c, len+1);
170 : 30082 : ss->s[len] = 0;
171 : 30082 : ss->len = len;
172 : 30082 : return ss;
173 : : }
174 : :
175 : : /*() Construct zx_str by duplication of raw string data of given length. */
176 : :
177 : : /* Called by: zx_dup_len_elem, zx_dup_str, zxid_add_ldif_at2ses, zxid_parse_invite, zxid_parse_psobj */
178 : : struct zx_str* zx_dup_len_str(struct zx_ctx* c, int len, const char* s)
179 : 20843 : {
180 : 20843 : struct zx_str* ss = zx_new_len_str(c, len);
181 : 20843 : memcpy(ss->s, s, len);
182 : 20843 : return ss;
183 : : }
184 : :
185 : : /*() Construct zx_str by duplication of C string. */
186 : :
187 : : /* Called by: zxid_add_attr_to_ses, zxid_add_qs_to_ses, zxid_anoint_a7n x2, zxid_anoint_sso_resp x3, zxid_attach_sol1_usage_directive, zxid_az_soap x4, zxid_call_epr, zxid_fed_mgmt_cf, zxid_get_at x2, zxid_idp_dispatch x8, zxid_idp_list_cf_cgi x2, zxid_idp_select_zxstr_cf_cgi, zxid_idp_sso x13, zxid_map_identity_token, zxid_map_val, zxid_map_val_ss x3, zxid_mk_an_stmt, zxid_mk_sa_attribute, zxid_mk_subj, zxid_mk_usr_a7n_to_sp, zxid_new_epr, zxid_parse_invite x6, zxid_parse_mni, zxid_parse_psobj x7, zxid_pepmap_extract x7, zxid_saml2_redir, zxid_saml2_resp_redir, zxid_ses_to_pool x9, zxid_show_conf x3, zxid_show_cstr_list, zxid_show_map, zxid_show_need x2, zxid_simple_ab_pep x3, zxid_slo_resp_redir, zxid_sp_dispatch x15, zxid_sp_mni_redir x3, zxid_sp_slo_redir x3, zxid_start_sso_location, zxid_wsc_prep, zxid_wsc_prepare_call, zxid_wsc_valid_re_env, zxid_wsp_decorate, zxid_wsp_validate_env */
188 : : struct zx_str* zx_dup_str(struct zx_ctx* c, const char* s)
189 : 20359 : {
190 : 20359 : return zx_dup_len_str(c, strlen(s), s);
191 : : }
192 : :
193 : : /*() ZX verion of strdup(). */
194 : :
195 : : /* Called by: chkuid x2, zxid_az_base_cf_ses, zxid_az_cf_ses, zxid_fed_mgmt_cf, zxid_get_ses, zxid_mk_usr_a7n_to_sp, zxid_parse_invite, zxid_parse_psobj, zxid_simple_cf_ses x2, zxid_simple_no_ses_cf, zxid_simple_redir_page, zxid_simple_ses_active_cf, zxid_simple_show_page x2, zxid_url_set */
196 : : char* zx_dup_cstr(struct zx_ctx* c, const char* str)
197 : 68 : {
198 : 68 : int len = strlen(str);
199 : 68 : char* s = ZX_ALLOC(c, len+1);
200 : 68 : memcpy(s, str, len+1);
201 : 68 : return s;
202 : : }
203 : :
204 : : struct zx_str* zx_dup_zx_str(struct zx_ctx* c, struct zx_str* ss)
205 : 72 : {
206 : 72 : return zx_dup_len_str(c, ss->len, ss->s);
207 : : }
208 : :
209 : : /* ------------------ ATTR ------------------ */
210 : :
211 : : /*() Construct zx_attr_s from length and raw string data, which will be referenced, not copied. */
212 : :
213 : : /* Called by: zx_attrf, zx_ref_attr, zxenc_symkey_enc, zxid_check_fed, zxid_idp_sso, zxid_mk_an_stmt, zxid_mk_logout_resp, zxid_mk_mni_resp, zxid_mk_xacml_simple_at x3, zxid_mni_do_ss, zxid_ps_addent_invite, zxid_slo_resp_redir, zxid_sp_mni_redir, zxid_sp_slo_redir, zxid_sso_issue_a7n x2 */
214 : : struct zx_attr_s* zx_ref_len_attr(struct zx_ctx* c, struct zx_elem_s* father, int tok, int len, const char* s)
215 : 36855 : {
216 : 36855 : struct zx_attr_s* ss = ZX_ZALLOC(c, struct zx_attr_s);
217 : 36855 : ss->g.s = (char*)s; /* ref points to underlying data */
218 : 36855 : ss->g.len = len;
219 : 36855 : ss->g.tok = tok;
220 [ + + ]: 36855 : if (father) {
221 : 35561 : ss->g.n = &father->attr->g;
222 : 35561 : father->attr = ss;
223 : : }
224 : 36855 : return ss;
225 : : }
226 : :
227 : : /*() Construct zx_attr_s from C string, which will be referenced, not copied. */
228 : :
229 : : /* Called by: test_ibm_cert_problem_enc_dec x2, x509_test x3, zxenc_pubkey_enc, zxenc_symkey_enc x3, zxid_ac_desc x2, zxid_ar_desc, zxid_attach_sol1_usage_directive x5, zxid_az_soap x2, zxid_check_fed, zxid_contact_desc, zxid_idp_sso, zxid_idp_sso_desc x2, zxid_issuer, zxid_key_desc, zxid_map_identity_token x2, zxid_mk_Status x2, zxid_mk_art_deref, zxid_mk_authn_req x10, zxid_mk_az, zxid_mk_az_cd1, zxid_mk_dap_query, zxid_mk_dap_query_item x8, zxid_mk_dap_resquery x6, zxid_mk_dap_select x2, zxid_mk_dap_subscription x7, zxid_mk_dap_test_item x2, zxid_mk_dap_testop x2, zxid_mk_di_req_svc, zxid_mk_ecp_Request_hdr x2, zxid_mk_idp_list x2, zxid_mk_logout, zxid_mk_logout_resp, zxid_mk_mni, zxid_mk_mni_resp, zxid_mk_paos_Request_hdr x3, zxid_mk_sa_attribute_ss, zxid_mk_tas3_status, zxid_mk_transient_nid, zxid_mk_xacml_resp, zxid_mni_desc, zxid_nidmap_identity_token x2, zxid_nimap_desc, zxid_org_desc x3, zxid_ps_addent_invite x2, zxid_slo_desc, zxid_sp_sso_desc x3, zxid_sso_desc, zxid_sso_issue_a7n, zxid_wsc_prep x8, zxid_wsc_prep_secmech, zxid_wsf_decor x24, zxsig_sign x5 */
230 : : struct zx_attr_s* zx_ref_attr(struct zx_ctx* c, struct zx_elem_s* father, int tok, const char* s)
231 : 17139 : {
232 [ + + ]: 17139 : if (!s)
233 : 5 : return 0;
234 : 17134 : return zx_ref_len_attr(c, father, tok, strlen(s), s);
235 : : }
236 : :
237 : : /*() Newly allocated attribute (node and data) of specified length, but uninitialized */
238 : :
239 : : /* Called by: zx_dup_len_attr */
240 : : struct zx_attr_s* zx_new_len_attr(struct zx_ctx* c, struct zx_elem_s* father, int tok, int len)
241 : 8774 : {
242 : 8774 : struct zx_attr_s* ss = ZX_ZALLOC(c, struct zx_attr_s);
243 : 8774 : ss->g.s = ZX_ALLOC(c, len+1);
244 : 8774 : ss->g.s[len] = 0;
245 : 8774 : ss->g.len = len;
246 : 8774 : ss->g.tok = tok;
247 [ + - ]: 8774 : if (father) {
248 : 8774 : ss->g.n = &father->attr->g;
249 : 8774 : father->attr = ss;
250 : : }
251 : 8774 : return ss;
252 : : }
253 : :
254 : : /*() Construct zx_str by duplication of raw string data of given length. */
255 : :
256 : : /* Called by: zx_dup_attr, zxid_imreq */
257 : : struct zx_attr_s* zx_dup_len_attr(struct zx_ctx* c, struct zx_elem_s* father, int tok, int len, const char* s)
258 : 8774 : {
259 : 8774 : struct zx_attr_s* ss = zx_new_len_attr(c, father, tok, len);
260 : 8774 : memcpy(ss->g.s, s, len);
261 : 8774 : return ss;
262 : : }
263 : :
264 : : /*() Construct zx_str by duplication of C string. */
265 : :
266 : : /* Called by: zxenc_pubkey_enc, zxid_as_call_ses, zxid_attach_sol1_usage_directive, zxid_idp_sso, zxid_map_identity_token x3, zxid_mk_a7n, zxid_mk_authn_req, zxid_mk_lu_Status x3, zxid_mk_sa_attribute_ss, zxid_mk_saml_resp, zxid_mk_tas3_status x4, zxid_nidmap_identity_token, zxid_parse_mni x3 */
267 : : struct zx_attr_s* zx_dup_attr(struct zx_ctx* c, struct zx_elem_s* father, int tok, const char* s)
268 : 8774 : {
269 : 8774 : return zx_dup_len_attr(c, father, tok, strlen(s), s);
270 : : }
271 : :
272 : : /*() vasprintf(3) implementation that will grab its memory from ZX memory allocator. */
273 : :
274 : : /* Called by: zx_alloc_sprintf, zx_attrf, zx_strf, zxid_callf, zxid_callf_epr, zxid_wsc_prepare_callf, zxid_wsp_decoratef */
275 : : char* zx_alloc_vasprintf(struct zx_ctx* c, int* retlen, const char* f, va_list ap) /* data is new memory */
276 : 14927 : {
277 : : va_list ap2;
278 : : int len;
279 : : char* s;
280 : : char buf[2];
281 : 14927 : va_copy(ap2, ap);
282 : 14927 : len = vsnprintf(buf, 1, f, ap2);
283 : 14927 : va_end(ap2);
284 [ - + ]: 14927 : if (len < 0) {
285 : 0 : perror("vsnprintf");
286 [ # # # # ]: 0 : D("Broken vsnprintf? Impossible to compute length of string. Be sure to `export LANG=C' if you get errors about multibyte characters. Length returned: %d", len);
287 [ # # ]: 0 : if (retlen)
288 : 0 : *retlen = 0;
289 : 0 : s = ZX_ALLOC(c, 1);
290 : 0 : s[0] = 0;
291 : 0 : return s;
292 : : }
293 : 14927 : s = ZX_ALLOC(c, len+1);
294 : 14927 : vsnprintf(s, len+1, f, ap);
295 : 14927 : s[len] = 0; /* must terminate manually as on win32 nul termination is not guaranteed */
296 [ + + ]: 14927 : if (retlen)
297 : 14844 : *retlen = len;
298 : 14927 : return s;
299 : : }
300 : :
301 : : /*() sprintf(3) implementation that will grab its memory from ZX memory allocator. */
302 : :
303 : : /* Called by: main x2, zxid_add_env_if_needed, zxid_pw_authn x2, zxid_simple_no_ses_cf x2 */
304 : : char* zx_alloc_sprintf(struct zx_ctx* c, int* retlen, const char* f, ...) /* data is new memory */
305 : 82 : {
306 : : char* ret;
307 : : va_list ap;
308 : 82 : va_start(ap, f);
309 : 82 : ret = zx_alloc_vasprintf(c, retlen, f, ap);
310 : 82 : va_end(ap);
311 : 82 : return ret;
312 : : }
313 : :
314 : : /*(i) Construct zx_str given sprintf(3) format and grabbing memory from ZX memory allocator. */
315 : :
316 : : /* Called by: chkuid, zx_prefix_seen_whine, zxenc_pubkey_enc, zxid_date_time x2, zxid_decode_redir_or_post x5, zxid_fed_mgmt_cf x4, zxid_idp_list_cf_cgi x6, zxid_idp_select_zxstr_cf_cgi x3, zxid_idp_sso x3, zxid_lecp_check, zxid_mk_di_req_svc, zxid_mk_id, zxid_my_cdc_url, zxid_my_ent_id x3, zxid_ps_accept_invite, zxid_ps_addent_invite, zxid_ps_finalize_invite, zxid_saml2_post_enc x3, zxid_saml2_redir, zxid_saml2_redir_url, zxid_saml2_resp_redir, zxid_saml_ok, zxid_ses_to_pool x6, zxid_show_conf x5, zxid_show_cstr_list, zxid_show_map, zxid_show_need x2, zxid_simple_idp_an_ok_do_rest, zxid_simple_idp_new_user, zxid_simple_idp_recover_password, zxid_simple_idp_show_an x2, zxid_simple_no_ses_cf, zxid_simple_redir_page, zxid_simple_show_err, zxid_simple_show_page, zxid_sp_carml, zxid_start_sso_location, zxid_user_sha1_name, zxid_wsc_prep, zxid_wsf_decor */
317 : : struct zx_str* zx_strf(struct zx_ctx* c, const char* f, ...) /* data is new memory */
318 : 6094 : {
319 : : va_list ap;
320 : : int len;
321 : : char* s;
322 : 6094 : va_start(ap, f);
323 : 6094 : s = zx_alloc_vasprintf(c, &len, f, ap);
324 : 6094 : va_end(ap);
325 : 6094 : return zx_ref_len_str(c, len, s);
326 : : }
327 : :
328 : : /* Called by: zxenc_pubkey_enc x2, zxenc_symkey_enc, zxid_ac_desc, zxid_ar_desc x2, zxid_date_time_attr x2, zxid_idp_sso_desc, zxid_mk_dap_query_item x2, zxid_mk_dap_select x4, zxid_mk_dap_testop x4, zxid_mk_id_attr, zxid_mk_paos_Request_hdr, zxid_mni_desc x2, zxid_my_ent_id_attr x3, zxid_nimap_desc x2, zxid_slo_desc x2, zxid_sp_sso_desc, zxid_sso_desc x2, zxsig_sign */
329 : : struct zx_attr_s* zx_attrf(struct zx_ctx* c, struct zx_elem_s* father, int tok, const char* f, ...) /* data is new memory */
330 : 8750 : {
331 : : va_list ap;
332 : : int len;
333 : : char* s;
334 : 8750 : va_start(ap, f);
335 : 8750 : s = zx_alloc_vasprintf(c, &len, f, ap);
336 : 8750 : va_end(ap);
337 : 8750 : return zx_ref_len_attr(c, father, tok, len, s);
338 : : }
339 : :
340 : : /*() Check if string ends in suffix */
341 : :
342 : : /* Called by: */
343 : : int zx_str_ends_in(struct zx_str* ss, int len, const char* suffix)
344 : 827 : {
345 : 827 : return !memcmp(ss->s + ss->len - len, suffix, len);
346 : : }
347 : :
348 : : /*() Add non-XML content to the kids list. These essentially appear as DATA items. */
349 : :
350 : : /* Called by: test_ibm_cert_problem_enc_dec, x509_test, zx_new_str_elem, zxid_attach_sol1_usage_directive, zxid_az_soap x4, zxid_check_fed, zxid_issuer, zxid_mk_addr, zxid_mk_sa_attribute_ss, zxid_mk_subj, zxid_mk_transient_nid, zxid_new_epr, zxid_org_desc x5, zxid_parse_mni, zxid_ps_addent_invite x2, zxid_wsc_prep, zxid_wsc_prep_secmech x3, zxid_wsf_decor x4, zxsig_sign */
351 : : void zx_add_content(struct zx_ctx* c, struct zx_elem_s* x, struct zx_str* cont)
352 : 17522 : {
353 [ + - - + ]: 17522 : if (!cont || !x) {
354 : 0 : ERR("Call to zx_add_content(c,%p,%p) with null values", x, cont);
355 : 0 : return;
356 : : }
357 : 17522 : cont->tok = ZX_TOK_DATA;
358 : 17522 : cont->n = &x->kids->g;
359 : 17522 : x->kids = (struct zx_elem_s*)cont;
360 : : }
361 : :
362 : : /*() Add kid to head of kids list. Usually you should add in schema order
363 : : * and in the end call zx_reverse_elem_lists() to make the list right order. */
364 : :
365 : : /* Called by: zx_add_kid_after_sa_Issuer, zxid_add_fed_tok2epr, zxid_az_soap, zxid_di_query, zxid_idp_as_do, zxid_imreq, zxid_mk_a7n x3, zxid_mk_logout_resp, zxid_mk_mni_resp, zxid_mk_saml_resp, zxid_soap_call_hdr_body x2, zxid_soap_cgi_resp_body, zxid_sp_soap_dispatch, zxid_wsf_sign */
366 : : struct zx_elem_s* zx_add_kid(struct zx_elem_s* father, struct zx_elem_s* kid)
367 : 4795 : {
368 [ + - ]: 4795 : if (father) {
369 : 4795 : kid->g.n = &father->kids->g;
370 : 4795 : father->kids = kid;
371 : : }
372 : 4795 : return kid;
373 : : }
374 : :
375 : : /*() Add kid before another elem. This assumes father is already in
376 : : * forward order, i.e. zx_reverse_elem_lists() was already called. */
377 : :
378 : : /* Called by: zxid_add_fed_tok2epr, zxid_choose_sectok x2, zxid_ins_xacml_az_cd1_stmt x2, zxid_ins_xacml_az_stmt x2, zxid_sso_issue_a7n, zxid_wsc_prep_secmech */
379 : : struct zx_elem_s* zx_add_kid_before(struct zx_elem_s* father, int before, struct zx_elem_s* kid)
380 : 312 : {
381 [ - + ]: 312 : if (!father->kids) {
382 : 0 : father->kids = kid;
383 : 0 : return kid;
384 : : }
385 [ + + ]: 312 : if (father->kids->g.tok == before) {
386 : 38 : kid->g.n = &father->kids->g;
387 : 38 : father->kids = kid;
388 : 38 : return kid;
389 : : }
390 : 274 : for (father = father->kids;
391 [ + + + + ]: 1037 : father->g.n && father->g.n->tok != before;
392 : 489 : father = (struct zx_elem_s*)father->g.n) ;
393 : :
394 : 274 : kid->g.n = father->g.n;
395 : 274 : father->g.n = &kid->g;
396 : 274 : return kid;
397 : : }
398 : :
399 : : /*() Add Signature right after sa:Issuer. This assumes father is
400 : : * already in forward order (i.e. zx_reverse_elem_lists() was already
401 : : * called. */
402 : :
403 : : /* Called by: zxid_anoint_a7n, zxid_anoint_sso_resp, zxid_az_soap x2, zxid_idp_soap_dispatch x2, zxid_idp_sso, zxid_mk_art_deref, zxid_sp_mni_soap, zxid_sp_slo_soap, zxid_sp_soap_dispatch x6, zxid_ssos_anreq */
404 : : struct zx_elem_s* zx_add_kid_after_sa_Issuer(struct zx_elem_s* father, struct zx_elem_s* kid)
405 : 1005 : {
406 [ + + ]: 1005 : if (father->kids->g.tok == zx_sa_Issuer_ELEM) {
407 : 1004 : father = father->kids;
408 : 1004 : kid->g.n = father->g.n;
409 : 1004 : father->g.n = &kid->g;
410 : 1004 : return kid;
411 : : }
412 : 1 : ERR("No <sa:Issuer> found. Adding signature at list head. %d", father->kids->g.tok);
413 : 1 : return zx_add_kid(father, kid);
414 : : }
415 : :
416 : : /*() Replace kid element. */
417 : :
418 : : /* Called by: zxid_wsp_decorate */
419 : : struct zx_elem_s* zx_replace_kid(struct zx_elem_s* father, struct zx_elem_s* kid)
420 : 0 : {
421 [ # # ]: 0 : if (!father->kids) {
422 : 0 : father->kids = kid;
423 : 0 : return kid;
424 : : }
425 [ # # ]: 0 : if (father->kids->g.tok == kid->g.tok) {
426 : 0 : kid->g.n = father->kids->g.n;
427 : 0 : father->kids = kid;
428 : 0 : return kid;
429 : : }
430 : 0 : for (father = father->kids;
431 [ # # # # ]: 0 : father->g.n && father->g.n->tok != kid->g.tok;
432 : 0 : father = (struct zx_elem_s*)father->g.n) ;
433 : :
434 : 0 : kid->g.n = father->g.n->n;
435 : 0 : father->g.n = &kid->g;
436 : 0 : return kid;
437 : : }
438 : :
439 : : /*() Construct new simple element from zx_str by referencing, not copying, it. */
440 : :
441 : : /* Called by: main, zx_dup_len_elem, zx_ref_len_elem, zxenc_pubkey_enc, zxenc_symkey_enc, zxid_mk_a7n, zxid_mk_logout, zxid_mk_mni x4, zxid_mk_xacml_simple_at, zxid_ps_addent_invite x2, zxsig_sign */
442 : : struct zx_elem_s* zx_new_str_elem(struct zx_ctx* c, struct zx_elem_s* father, int tok, struct zx_str* ss)
443 : 10386 : {
444 : : struct zx_elem_s* el;
445 : 10386 : el = ZX_ZALLOC(c, struct zx_elem_s);
446 : 10386 : el->g.tok = tok;
447 [ + + ]: 10386 : if (father) {
448 : 10385 : el->g.n = &father->kids->g;
449 : 10385 : father->kids = el;
450 : : }
451 : 10386 : zx_add_content(c, el, ss);
452 : 10386 : return el;
453 : : }
454 : :
455 : : /*() Helper function for the zx_NEW_*() macros */
456 : :
457 : : /* Called by: */
458 : : struct zx_elem_s* zx_new_elem(struct zx_ctx* c, struct zx_elem_s* father, int tok)
459 : 73640 : {
460 : : const struct zx_el_desc* ed;
461 : : struct zx_elem_s* el;
462 : 73640 : ed = zx_el_desc_lookup(tok);
463 [ + - ]: 73640 : if (ed) {
464 : 73640 : el = ZX_ALLOC(c, ed->siz);
465 : 73640 : ZERO(el, ed->siz);
466 : : } else {
467 [ # # ]: 0 : INFO("Unknown element tok=%06x in tok=%06x", tok, father?father->g.tok:0);
468 : 0 : el = ZX_ZALLOC(c, struct zx_elem_s);
469 : 0 : tok = ZX_TOK_NOT_FOUND;
470 : : }
471 : 73640 : el->g.tok = tok;
472 [ + + ]: 73640 : if (father) {
473 : 40360 : el->g.n = &father->kids->g;
474 : 40360 : father->kids = el;
475 : : }
476 : 73640 : return el;
477 : : }
478 : :
479 : : /*() Construct new simple element by referencing, not copying, raw string data of given length. */
480 : :
481 : : /* Called by: zx_ref_elem, zxid_as_call_ses, zxid_key_info */
482 : : struct zx_elem_s* zx_ref_len_elem(struct zx_ctx* c, struct zx_elem_s* father, int tok, int len, const char* s)
483 : 1136 : {
484 : 1136 : return zx_new_str_elem(c, father, tok, zx_ref_len_str(c, len, s));
485 : : }
486 : :
487 : : /*() Construct new simple element by referencing, not copying, C string. */
488 : :
489 : : /* Called by: main, zxid_contact_desc x6, zxid_idp_sso_desc x2, zxid_mk_Status, zxid_mk_art_deref, zxid_mk_authn_req, zxid_mk_dap_query_item x4, zxid_mk_dap_resquery x4, zxid_mk_dap_select x2, zxid_mk_dap_subscription x2, zxid_mk_dap_testop x2, zxid_mk_di_req_svc x6, zxid_mk_xacml_resp, zxid_sp_sso_desc x2 */
490 : : struct zx_elem_s* zx_ref_elem(struct zx_ctx* c, struct zx_elem_s* father, int tok, const char* s)
491 : 144 : {
492 : 144 : return zx_ref_len_elem(c, father, tok, strlen(s), s);
493 : : }
494 : :
495 : : /* Called by: zx_dup_elem */
496 : : struct zx_elem_s* zx_dup_len_elem(struct zx_ctx* c, struct zx_elem_s* father, int tok, int len, const char* s)
497 : 211 : {
498 : 211 : return zx_new_str_elem(c, father, tok, zx_dup_len_str(c, len, s));
499 : : }
500 : :
501 : : /* Called by: zxid_add_fed_tok2epr, zxid_mk_an_stmt, zxid_mk_fault x3, zxid_new_epr x3, zxid_set_epr_secmech x2 */
502 : : struct zx_elem_s* zx_dup_elem(struct zx_ctx* c, struct zx_elem_s* father, int tok, const char* s)
503 : 211 : {
504 : 211 : return zx_dup_len_elem(c, father, tok, strlen(s), s);
505 : : }
506 : :
507 : : /* ----------- F r e e ----------- */
508 : :
509 : : /* Called by: zx_free_elem */
510 : : void zx_free_attr(struct zx_ctx* c, struct zx_attr_s* aa, int free_strs)
511 : 619136 : {
512 : : struct zx_attr_s* aan;
513 [ + + ]: 1027911 : for (; aa; aa = aan) { /* attributes */
514 : 408775 : aan = (struct zx_attr_s*)aa->g.n;
515 [ - + # # ]: 408775 : if (free_strs && aa->name)
516 : 0 : ZX_FREE(c, aa->name);
517 [ - + # # ]: 408775 : if (free_strs && aa->g.s)
518 : 0 : ZX_FREE(c, aa->g.s);
519 : 408775 : ZX_FREE(c, aa);
520 : : }
521 : 619136 : }
522 : :
523 : : /*() Free element and its attributes, child elements, and content.
524 : : * Depth first traversal of data structure to free it and its subelements. Simple
525 : : * strings are handled as a special case according to the free_strs flag. This
526 : : * is useful if the strings point to underlying data from the wire that was
527 : : * allocated differently. */
528 : :
529 : : /* Called by: main, zx_free_elem, zxid_mk_mni, zxid_parse_meta, zxid_set_fault, zxid_set_tas3_status */
530 : : void zx_free_elem(struct zx_ctx* c, struct zx_elem_s* x, int free_strs)
531 : 619136 : {
532 : : struct zx_elem_s* ae;
533 : : struct zx_elem_s* aen;
534 : :
535 [ + + - + ]: 619136 : if (x->g.tok == ZX_TOK_NOT_FOUND && free_strs) {
536 : 0 : ae = x;
537 [ # # ]: 0 : if (ae->g.s)
538 : 0 : ZX_FREE(c, ae->g.s);
539 : : }
540 : 619136 : zx_free_attr(c, x->attr, free_strs);
541 : :
542 [ + + ]: 1369566 : for (ae = x->kids; ae; ae = aen) { /* elements */
543 : 750430 : aen = (struct zx_elem_s*)ae->g.n;
544 [ + + ]: 750430 : switch (ae->g.tok) {
545 : : case ZX_TOK_DATA:
546 [ - + ]: 149423 : if (free_strs)
547 : 0 : zx_str_free(c, &ae->g);
548 : : else
549 : 149423 : ZX_FREE(c, ae);
550 : 149423 : break;
551 : : default:
552 : 601007 : zx_free_elem(c, ae, free_strs);
553 : : //zx_FREE_elem(c, ae, free_strs);
554 : : }
555 : : }
556 : 619136 : ZX_FREE(c, x);
557 : 619136 : }
558 : :
559 : : #ifdef ZX_ENA_AUX
560 : :
561 : : /* *** clone code has not been updated since great namespace reform */
562 : :
563 : : /* Called by: zxenc_pubkey_enc, zxid_as_call_ses, zxid_attach_sol1_usage_directive, zxid_idp_sso, zxid_map_identity_token x3, zxid_mk_a7n, zxid_mk_authn_req, zxid_mk_lu_Status x3, zxid_mk_sa_attribute_ss, zxid_mk_saml_resp, zxid_mk_tas3_status x4, zxid_nidmap_identity_token, zxid_parse_mni x3 */
564 : : void zx_dup_attr(struct zx_ctx* c, struct zx_str* attr)
565 : : {
566 : : char* p;
567 : : for (; attr; attr = (struct zx_str*)attr->g.n)
568 : : if (attr->s) {
569 : : p = ZX_ALLOC(c, attr->len);
570 : : memcpy(p, attr->s, attr->len);
571 : : attr->s = p;
572 : : }
573 : : }
574 : :
575 : : /* Called by: */
576 : : struct zx_str* zx_clone_attr(struct zx_ctx* c, struct zx_str* attr)
577 : : {
578 : : struct zx_str* ret;
579 : : struct zx_str* attrnn;
580 : : struct zx_str* attrn;
581 : : char* p;
582 : : for (attrnn = 0; attr; attr = (struct zx_str*)attr->g.n) {
583 : : ZX_DUPALLOC(c, struct zx_str, attrn, attr);
584 : : if (!attrnn)
585 : : ret = attrn;
586 : : else
587 : : attrnn->g.n = &attrn->g;
588 : : attrnn = attrn;
589 : : if (attrn->s) {
590 : : p = ZX_ALLOC(c, attrn->len);
591 : : memcpy(p, attrn->s, attrn->len);
592 : : attrn->s = p;
593 : : }
594 : : }
595 : : return ret;
596 : : }
597 : :
598 : : /* Called by: TXDEEP_CLONE_ELNAME */
599 : : struct zx_elem_s* zx_clone_elem_common(struct zx_ctx* c, struct zx_elem_s* x, int size, int dup_strs)
600 : : {
601 : : struct zx_attr_s* aa;
602 : : struct zx_elem_s* ae;
603 : : struct zx_attr_s* aan;
604 : : struct zx_elem_s* aen;
605 : : struct zx_attr_s* aann;
606 : : struct zx_elem_s* aenn;
607 : : char* p;
608 : :
609 : : if (x->g.tok == ZX_TOK_NOT_FOUND) {
610 : : ae = (struct zx_elem_s*)x;
611 : : ZX_DUPALLOC(c, struct zx_elem_s, aen, ae);
612 : : if (dup_strs) {
613 : : aen->name = ZX_ALLOC(c, ae->name_len);
614 : : memcpy(aen->name, ae->name, ae->name_len);
615 : : }
616 : : x = &aen->gg;
617 : : } else {
618 : : struct zx_elem_s* xx = (struct zx_elem_s*)ZX_ALLOC(c, size);
619 : : memcpy(xx, x, size);
620 : : x = xx;
621 : : }
622 : :
623 : : /* *** deal with xmlns specifications in exc c14n way */
624 : :
625 : : for (aann = 0, aa = x->attr; aa; aa = (struct zx_attr_s*)aa->ss.g.n) { /* unknown attributes */
626 : : ZX_DUPALLOC(c, struct zx_attr_s, aan, aa);
627 : : if (!aann)
628 : : x->any_attr = aan;
629 : : else
630 : : aann->ss.g.n = &aan->ss.g;
631 : : aann = aan;
632 : :
633 : : if (dup_strs && aan->name) {
634 : : p = ZX_ALLOC(c, aan->name_len);
635 : : memcpy(p, aan->name, aan->name_len);
636 : : aan->name = p;
637 : : }
638 : : if (dup_strs && aan->ss.s) {
639 : : p = ZX_ALLOC(c, aan->ss.len);
640 : : memcpy(p, aan->ss.s, aan->ss.len);
641 : : aan->ss.s = p;
642 : : }
643 : : }
644 : :
645 : : for (aenn = 0, ae = x->kids; ae; ae = (struct zx_elem_s*)ae->gg.g.n) { /* unknown elements */
646 : : switch (ae->g.tok) {
647 : : case ZX_TOK_DATA:
648 : : ZX_DUPALLOC(c, struct zx_str, aen, ae);
649 : : if (aen->g.s) {
650 : : p = ZX_ALLOC(c, aen->g.len);
651 : : memcpy(p, aen->g.s, aen->g.len);
652 : : aen->s = p;
653 : : }
654 : : break;
655 : : default:
656 : : aen = (struct zx_elem_s*)zx_DEEP_CLONE_elem(c, &ae->gg, dup_strs);
657 : : }
658 : : if (!aenn)
659 : : x->kids = aen;
660 : : else
661 : : aenn->gg.g.n = &aen->gg.g;
662 : : aenn = aen;
663 : : }
664 : : return x;
665 : : }
666 : :
667 : : /* Called by: TXDUP_STRS_ELNAME */
668 : : void zx_dup_strs_common(struct zx_ctx* c, struct zx_elem_s* x)
669 : : {
670 : : struct zx_attr_s* aa;
671 : : struct zx_elem_s* ae;
672 : : char* p;
673 : :
674 : : if (x->g.tok == ZX_TOK_NOT_FOUND) {
675 : : ae = (struct zx_elem_s*)x;
676 : : p = ZX_ALLOC(c, ae->name_len);
677 : : memcpy(p, ae->name, ae->name_len);
678 : : ae->name = p;
679 : : }
680 : :
681 : : /* *** deal with xmlns specifications in exc c14n way */
682 : :
683 : : for (aa = x->attr; aa; aa = (struct zx_attr_s*)aa->ss.g.n) { /* unknown attributes */
684 : : if (aa->name) {
685 : : p = ZX_ALLOC(c, aa->name_len);
686 : : memcpy(p, aa->name, aa->name_len);
687 : : aa->name = p;
688 : : }
689 : : if (aa->ss.s) {
690 : : p = ZX_ALLOC(c, aa->ss.len);
691 : : memcpy(p, aa->ss.s, aa->ss.len);
692 : : aa->ss.s = p;
693 : : }
694 : : }
695 : :
696 : : for (ae = x->kids; ae; ae = (struct zx_elem_s*)ae->gg.g.n) /* unknown elements */
697 : : switch (ae->g.tok) {
698 : : case ZX_TOK_DATA:
699 : : if (ae->g.s) {
700 : : p = ZX_ALLOC(c, ae->g.len);
701 : : memcpy(p, ae->g.s, ae->g.len);
702 : : ss->s = p;
703 : : }
704 : : break;
705 : : default:
706 : : zx_DUP_STRS_elem(c, &ae->gg);
707 : : }
708 : : }
709 : :
710 : : int zx_walk_so_unknown_attributes(struct zx_ctx* c, struct zx_elem_s* x, void* ctx, int (*callback)(struct zx_node_s* node, void* ctx))
711 : : {
712 : : struct zx_attr_s* aa;
713 : : int ret;
714 : :
715 : : for (aa = x->attr; aa; aa = (struct zx_attr_s*)aa->ss.g.n) { /* unknown attributes */
716 : : ret = callback(&aa->ss.g, ctx);
717 : : if (ret)
718 : : return ret;
719 : : }
720 : : return 0;
721 : : }
722 : :
723 : : int zx_walk_so_unknown_elems_and_content(struct zx_ctx* c, struct zx_elem_s* x, void* ctx, int (*callback)(struct zx_node_s* node, void* ctx))
724 : : {
725 : : struct zx_elem_s* ae;
726 : : int ret;
727 : :
728 : : for (ae = x->kids; ae; ae = (struct zx_elem_s*)ae->gg.g.n) { /* unknown elements */
729 : : switch (ae->g.tok) {
730 : : case ZX_TOK_DATA:
731 : : ret = callback(ae, ctx);
732 : : break;
733 : : default:
734 : : ret = zx_WALK_SO_elem(c, ae, ctx, callback);
735 : : }
736 : : if (ret)
737 : : return ret;
738 : : }
739 : : return 0;
740 : : }
741 : :
742 : : /* Called by: */
743 : : struct zx_elem_s* zx_deep_clone_elems(struct zx_ctx* c, struct zx_elem_s* x, int dup_strs)
744 : : {
745 : : struct zx_elem_s* se;
746 : : struct zx_elem_s* sen;
747 : : struct zx_elem_s* senn;
748 : :
749 : : for (senn = 0, se = x; se; se = (struct zx_elem_s*)se->g.n) {
750 : : sen = zx_DEEP_CLONE_elem(c, se, dup_strs);
751 : : if (!senn)
752 : : x = sen;
753 : : else
754 : : senn->g.n = &sen->g;
755 : : senn = sen;
756 : : }
757 : : return x;
758 : : }
759 : :
760 : :
761 : : int zx_walk_so_elems(struct zx_ctx* c, struct zx_elem_s* se, void* ctx, int (*callback)(struct zx_node_s* node, void* ctx))
762 : : {
763 : : int ret;
764 : :
765 : : for (; se; se = (struct zx_elem_s*)se->g.n) {
766 : : ret = zx_WALK_SO_elem(c, se, ctx, callback);
767 : : if (ret)
768 : : return ret;
769 : : }
770 : : return 0;
771 : : }
772 : :
773 : : /* Called by: */
774 : : void zx_dup_strs_elems(struct zx_ctx* c, struct zx_elem_s* se)
775 : : {
776 : : for (; se; se = (struct zx_elem_s*)se->g.n)
777 : : zx_DUP_STRS_elem(c, se);
778 : : }
779 : :
780 : : #endif /* end ZX_ENA_AUX */
781 : :
782 : : /* EOF -- zxlib.c */
|