Branch data Line data Source code
1 : : /* zxidspx.c - Handwritten functions for SP dispatch
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: zxidspx.c,v 1.14 2010-01-08 02:10:09 sampo Exp $
10 : : *
11 : : * 12.8.2006, created --Sampo
12 : : * 12.10.2007, tweaked for signing SLO and MNI --Sampo
13 : : * 14.4.2008, added SimpleSign --Sampo
14 : : * 7.10.2008, added documentation --Sampo
15 : : * 22.8.2009, added XACML dummy PDP support --Sampo
16 : : * 15.11.2009, added discovery service Query --Sampo
17 : : * 12.2.2010, added locking to lazy loading --Sampo
18 : : *
19 : : * See also zxid/sg/wsf-soap11.sg and zxid/c/zx-e-data.h, which is generated.
20 : : */
21 : :
22 : : #include "platform.h" /* needed on Win32 for pthread_mutex_lock() et al. */
23 : :
24 : : #include "errmac.h"
25 : : #include "zxid.h"
26 : : #include "zxidpriv.h"
27 : : #include "zxidconf.h"
28 : : #include "saml2.h"
29 : : #include "c/zx-const.h"
30 : : #include "c/zx-ns.h"
31 : : #include "c/zx-data.h"
32 : :
33 : : /*() Extract an assertion, decrypting EncryptedAssertion if needed. */
34 : :
35 : : /* Called by: sig_validate x2, zxid_imreq, zxid_sp_dig_sso_a7n, zxid_wsp_validate_env x2 */
36 : : zxid_a7n* zxid_dec_a7n(zxid_conf* cf, zxid_a7n* a7n, struct zx_sa_EncryptedAssertion_s* enca7n)
37 : 60 : {
38 : : struct zx_str* ss;
39 : : struct zx_root_s* r;
40 : :
41 [ + + + - ]: 60 : if (!a7n && enca7n) {
42 : 41 : ss = zxenc_privkey_dec(cf, enca7n->EncryptedData, enca7n->EncryptedKey);
43 [ + - + - : 41 : if (!ss || !ss->s || !ss->len) {
- + ]
44 : 0 : return 0;
45 : : }
46 : 41 : r = zx_dec_zx_root(cf->ctx, ss->len, ss->s, "dec a7n");
47 [ - + ]: 41 : if (!r) {
48 : 0 : ERR("Failed to parse EncryptedAssertion buf(%.*s)", ss->len, ss->s);
49 : 0 : zxlog(cf, 0, 0, 0, 0, 0, 0, 0, "N", "C", "BADXML", 0, "bad EncryptedAssertion");
50 : 0 : return 0;
51 : : }
52 : 41 : a7n = r->Assertion;
53 : : }
54 : 60 : return a7n;
55 : : }
56 : :
57 : : /*() Extract an assertion from Request, decrypting EncryptedAssertion if needed, and perform SSO */
58 : :
59 : : /* Called by: zxid_idp_soap_dispatch, zxid_sp_dispatch, zxid_sp_soap_dispatch x3 */
60 : : static int zxid_sp_dig_sso_a7n(zxid_conf* cf, zxid_cgi* cgi, zxid_ses* ses, struct zx_sp_Response_s* resp)
61 : 4 : {
62 : : zxid_a7n* a7n;
63 : 4 : struct zx_ns_s* pop_seen = 0;
64 : :
65 [ - + ]: 4 : if (!zxid_chk_sig(cf, cgi, ses, &resp->gg, resp->Signature, resp->Issuer, 0, "Response"))
66 : 0 : return 0;
67 : :
68 : 4 : a7n = zxid_dec_a7n(cf, resp->Assertion, resp->EncryptedAssertion);
69 [ + - ]: 4 : if (a7n) {
70 : 4 : zx_see_elem_ns(cf->ctx, &pop_seen, &resp->gg);
71 : 4 : return zxid_sp_sso_finalize(cf, cgi, ses, a7n, pop_seen);
72 : : }
73 [ # # # # : 0 : if (cf->anon_ok && cgi->rs && !strcmp(cf->anon_ok, cgi->rs)) /* Prefix match */
# # ]
74 : 0 : return zxid_sp_anon_finalize(cf, cgi, ses);
75 : 0 : ERR("No Assertion found and not anon_ok in SAML Response %d", 0);
76 [ # # # # : 0 : zxlog(cf, 0, 0, 0, 0, 0, 0, ZX_GET_CONTENT(ses->nameid), "N", "C", "ERR", 0, "sid(%s) No assertion", ses->sid);
# # ]
77 : 0 : return 0;
78 : : }
79 : :
80 : : /*() Dispatch redirct or post binding requests (and sometimes responses).
81 : : *
82 : : * return:: a string (such as Location: header) and let the caller output it.
83 : : * Sometimes a dummy string is just output to indicate status, e.g.
84 : : * "O" for SSO OK, "K" for normal OK no further action needed,
85 : : * "M" show management screen, "I" forward to IdP dispatch, or
86 : : * "* ERR" for error situations. These special strings
87 : : * are allocated from static storage and MUST NOT be freed. Other
88 : : * strings such as "Location: ..." should be freed by caller. */
89 : :
90 : : /* Called by: main x3, zxid_mgmt, zxid_simple_no_ses_cf, zxid_simple_ses_active_cf */
91 : : struct zx_str* zxid_sp_dispatch(zxid_conf* cf, zxid_cgi* cgi, zxid_ses* ses)
92 : 10 : {
93 : : struct zx_sp_LogoutRequest_s* req;
94 : : zxid_entity* idp_meta;
95 : : struct zx_str* loc;
96 : : struct zx_str* ss;
97 : : struct zx_str* ss2;
98 : : struct zx_root_s* r;
99 : : int ret;
100 : :
101 : 10 : ses->sigres = ZXSIG_NO_SIG;
102 : 10 : r = zxid_decode_redir_or_post(cf, cgi, ses, 1);
103 [ + + ]: 10 : if (!r)
104 : 2 : return zx_dup_str(cf->ctx, "* ERR");
105 : :
106 [ + + ]: 8 : if (r->Response) {
107 [ - + ]: 4 : if (!zxid_saml_ok(cf, cgi, r->Response->Status, "SAMLresp"))
108 : 0 : return zx_dup_str(cf->ctx, "* ERR");
109 : 4 : ret = zxid_sp_dig_sso_a7n(cf, cgi, ses, r->Response);
110 [ + - - + ]: 4 : D("ret=%d", ret);
111 [ - + - - ]: 4 : switch (ret) {
112 : 0 : case ZXID_OK: return zx_dup_str(cf->ctx, "K");
113 : 4 : case ZXID_SSO_OK: return zx_dup_str(cf->ctx, "O");
114 [ # # # # ]: 0 : case ZXID_FAIL: D("*** FAIL, should send back to IdP select %d", 0); return zx_dup_str(cf->ctx, "* ERR");
115 : : }
116 : 0 : return zx_dup_str(cf->ctx, "M"); /* Management screen, please. */
117 : : }
118 : :
119 [ + + ]: 4 : if (req = r->LogoutRequest) {
120 [ + - ]: 2 : if (cf->idp_ena) { /* *** Kludgy check */
121 [ + - - + ]: 2 : D("IdP SLO %d", 0);
122 [ - + ]: 2 : if (!zxid_idp_slo_do(cf, cgi, ses, req))
123 : 0 : return zx_dup_str(cf->ctx, "* ERR");
124 : : } else {
125 [ # # ]: 0 : if (!zxid_sp_slo_do(cf, cgi, ses, req))
126 : 0 : return zx_dup_str(cf->ctx, "* ERR");
127 : : }
128 : 2 : return zxid_slo_resp_redir(cf, cgi, req);
129 : : }
130 : :
131 [ + - ]: 2 : if (r->LogoutResponse) {
132 [ - + ]: 2 : if (!zxid_saml_ok(cf, cgi, r->LogoutResponse->Status, "SLO resp"))
133 : 0 : return zx_dup_str(cf->ctx, "* ERR");
134 : 2 : cgi->msg = "Logout Response OK. Logged out.";
135 : 2 : zxid_del_ses(cf, ses);
136 : 2 : return zx_dup_str(cf->ctx, "K"); /* Prevent mgmt screen from displaying, show login screen. */
137 : : }
138 : :
139 [ # # ]: 0 : if (r->ManageNameIDRequest) {
140 [ # # # # : 0 : idp_meta = zxid_get_ent_ss(cf, ZX_GET_CONTENT(r->ManageNameIDRequest->Issuer));
# # ]
141 : 0 : loc = zxid_idp_loc_raw(cf, cgi, idp_meta, ZXID_MNI_SVC, SAML2_REDIR, 0);
142 [ # # ]: 0 : if (!loc)
143 : 0 : return zx_dup_str(cf->ctx, "* ERR"); /* *** consider sending error page */
144 : 0 : ss = zxid_mni_do_ss(cf, cgi, ses, r->ManageNameIDRequest, loc);
145 : 0 : ss2 = zxid_saml2_resp_redir(cf, loc, ss, cgi->rs);
146 : 0 : zx_str_free(cf->ctx, loc);
147 : 0 : zx_str_free(cf->ctx, ss);
148 : 0 : return ss2;
149 : : }
150 : :
151 [ # # ]: 0 : if (r->ManageNameIDResponse) {
152 [ # # ]: 0 : if (!zxid_saml_ok(cf, cgi, r->ManageNameIDResponse->Status, "MNI resp")) {
153 : 0 : ERR("MNI Response indicates failure. %d", 0);
154 : 0 : return zx_dup_str(cf->ctx, "* ERR");
155 : : }
156 : 0 : cgi->msg = "Manage NameID Response OK.";
157 : 0 : return zx_dup_str(cf->ctx, "M"); /* Defederation doesn't have to mean SLO, show mgmt screen. */
158 : : }
159 : :
160 [ # # ]: 0 : if (r->AuthnRequest) {
161 [ # # # # ]: 0 : D("AuthnRequest %d", 0);
162 : 0 : return zx_dup_str(cf->ctx, "I");
163 : : }
164 : :
165 [ # # ]: 0 : if (cf->log_level > 0)
166 [ # # # # : 0 : zxlog(cf, 0, 0, 0, 0, 0, 0, ZX_GET_CONTENT(ses->nameid), "N", "C", "SPDISP", 0, "sid(%s) unknown req or resp", STRNULLCHK(ses->sid));
# # # # ]
167 : 0 : ERR("Unknown request or response %p", r);
168 : 0 : return zx_dup_str(cf->ctx, "* ERR");
169 : : }
170 : :
171 : : /*() Create Authorization Decision */
172 : :
173 : : /* Called by: zxid_xacml_az_do x2 */
174 : : static void zxid_ins_xacml_az_stmt(zxid_conf* cf, zxid_a7n* a7n, char* deci)
175 : 99 : {
176 : : /* Two ways of doing assertion with XACMLAuthzDecisionStatement:
177 : : * 1. Explicitly include such statement in assertion
178 : : * 2. Use sa:Statement, but brandit with xsi:type
179 : : * The former is more logical, but the latter is what Jericho does
180 : : * and in effect the XACML interop events have done (de-facto standard?). */
181 : :
182 : : #if 1
183 : 99 : a7n->XACMLAuthzDecisionStatement = zx_NEW_xasa_XACMLAuthzDecisionStatement(cf->ctx,0);
184 : 99 : ZX_ADD_KID(a7n->XACMLAuthzDecisionStatement, Response, zxid_mk_xacml_resp(cf, deci));
185 : : /* *** Add xaspcd1 and xasacd1 variants */
186 : 99 : zx_add_kid_before(&a7n->gg, zx_xasa_XACMLPolicyStatement_ELEM, &a7n->XACMLAuthzDecisionStatement->gg);
187 : : #else
188 : : a7n->Statement = zx_NEW_sa_Statement(cf->ctx,0);
189 : : a7n->Statement->type = zx_ref_str(cf->ctx, "xasa:XACMLAuthzDecisionStatementType");
190 : : a7n->Statement->Response = zxid_mk_xacml_resp(cf, deci);
191 : : zx_add_kid_before(&a7n->gg, zx_sa_AuthnStatement_ELEM, a7n->Statement);
192 : : #endif
193 : 99 : }
194 : :
195 : : /* Called by: zxid_xacml_az_cd1_do x2 */
196 : : static void zxid_ins_xacml_az_cd1_stmt(zxid_conf* cf, zxid_a7n* a7n, char* deci)
197 : 0 : {
198 : : /* Two ways of doing assertion with XACMLAuthzDecisionStatement:
199 : : * 1. Explicitly include such statement in assertion
200 : : * 2. Use sa:Statement, but brandit with xsi:type
201 : : * The former is more logical, but the latter is what Jericho does
202 : : * and in effect the XACML interop events have done (de-facto standard?). */
203 : :
204 : : #if 1
205 : 0 : a7n->xasacd1_XACMLAuthzDecisionStatement = zx_NEW_xasacd1_XACMLAuthzDecisionStatement(cf->ctx,0);
206 : 0 : ZX_ADD_KID(a7n->xasacd1_XACMLAuthzDecisionStatement, Response, zxid_mk_xacml_resp(cf, deci));
207 : : /* *** Add xaspcd1 and xasacd1 variants */
208 : 0 : zx_add_kid_before(&a7n->gg, zx_xasacd1_XACMLPolicyStatement_ELEM, &a7n->xasacd1_XACMLAuthzDecisionStatement->gg);
209 : : #else
210 : : a7n->Statement = zx_NEW_sa_Statement(cf->ctx,0);
211 : : a7n->Statement->type = zx_ref_str(cf->ctx, "xasacd1:XACMLAuthzDecisionStatementType");
212 : : a7n->Statement->Response = zxid_mk_xacml_resp(cf, deci);
213 : : zx_add_kid_before(&a7n->gg, zx_sa_AuthnStatement_ELEM, a7n->Statement);
214 : : #endif
215 : 0 : }
216 : :
217 : : /*() Process <XACMLAuthzDecisionQuery>. The response will have
218 : : * SAML assertion containing Authorization Decision Statement. */
219 : :
220 : : /* Called by: zxid_sp_soap_dispatch */
221 : : static struct zx_sp_Response_s* zxid_xacml_az_do(zxid_conf* cf, zxid_cgi* cgi, zxid_ses* ses, struct zx_xasp_XACMLAuthzDecisionQuery_s* azq)
222 : 99 : {
223 : : zxid_a7n* a7n;
224 : : struct zx_str* affil;
225 : : struct zx_str* subj;
226 : : struct zx_str* ss;
227 : : struct zx_xac_Attribute_s* xac_at;
228 : :
229 [ - + ]: 99 : if (!zxid_chk_sig(cf, cgi, ses, &azq->gg, azq->Signature, azq->Issuer, 0, "XACMLAuthzDecisionQuery"))
230 : 0 : return 0;
231 : :
232 : 99 : affil = subj = 0;
233 : : #if 0
234 : : affil = ar->NameIDPolicy && ar->NameIDPolicy->SPNameQualifier
235 : : ? ar->NameIDPolicy->SPNameQualifier
236 : : : ZX_GET_CONTENT(ar->Issuer);
237 : : subj = zxid_mk_subj(cf, ses, affil, sp_meta);
238 : : #endif
239 : : //a7n = zxid_mk_a7n(cf, affil, subj, 0, 0);
240 : 99 : a7n = zxid_mk_a7n(cf, affil, 0, 0, 0);
241 : :
242 [ + - + - ]: 99 : if (azq->Request && azq->Request->Subject) {
243 : 99 : for (xac_at = azq->Request->Subject->Attribute;
244 [ + + + - ]: 309 : xac_at && xac_at->gg.g.tok == zx_xac_Attribute_ELEM;
245 : 111 : xac_at = (struct zx_xac_Attribute_s*)ZX_NEXT(xac_at)) {
246 [ - + # # ]: 111 : if (xac_at->AttributeId->g.len == sizeof("role")-1
247 : : && !memcmp(xac_at->AttributeId->g.s, "role", sizeof("role")-1)) {
248 [ # # # # : 0 : ss = ZX_GET_CONTENT(xac_at->AttributeValue);
# # ]
249 [ # # # # ]: 0 : if (ss?ss->len:0 == sizeof("deny")-1 && !memcmp(ss->s, "deny", sizeof("deny")-1)) {
250 [ # # # # ]: 0 : D("PDP: DENY due to role=deny %d",0);
251 : 0 : zxid_ins_xacml_az_stmt(cf, a7n, "Deny");
252 : 0 : return zxid_mk_saml_resp(cf, a7n, 0);
253 : : }
254 : : }
255 : : }
256 : : }
257 [ + - - + ]: 99 : D("PDP: PERMIT by default %d",0);
258 : 99 : zxid_ins_xacml_az_stmt(cf, a7n, "Permit");
259 : 99 : return zxid_mk_saml_resp(cf, a7n, 0);
260 : : }
261 : :
262 : : /* Called by: zxid_sp_soap_dispatch */
263 : : static struct zx_sp_Response_s* zxid_xacml_az_cd1_do(zxid_conf* cf, zxid_cgi* cgi, zxid_ses* ses, struct zx_xaspcd1_XACMLAuthzDecisionQuery_s* azq)
264 : 0 : {
265 : : zxid_a7n* a7n;
266 : : struct zx_str* affil;
267 : : struct zx_str* subj;
268 : : struct zx_str* ss;
269 : : struct zx_xac_Attribute_s* xac_at;
270 : :
271 [ # # ]: 0 : if (!zxid_chk_sig(cf, cgi, ses, &azq->gg, azq->Signature, azq->Issuer, 0, "XACMLAuthzDecisionQuery"))
272 : 0 : return 0;
273 : :
274 : 0 : affil = subj = 0;
275 : : #if 0
276 : : affil = ar->NameIDPolicy && ar->NameIDPolicy->SPNameQualifier
277 : : ? ar->NameIDPolicy->SPNameQualifier
278 : : : ZX_GET_CONTENT(ar->Issuer);
279 : : subj = zxid_mk_subj(cf, ses, affil, sp_meta);
280 : : #endif
281 : : //a7n = zxid_mk_a7n(cf, affil, subj, 0, 0);
282 : 0 : a7n = zxid_mk_a7n(cf, affil, 0, 0, 0);
283 : :
284 [ # # # # ]: 0 : if (azq->Request && azq->Request->Subject) {
285 : 0 : for (xac_at = azq->Request->Subject->Attribute;
286 [ # # # # ]: 0 : xac_at && xac_at->gg.g.tok == zx_xac_Attribute_ELEM;
287 : 0 : xac_at = (struct zx_xac_Attribute_s*)ZX_NEXT(xac_at)) {
288 [ # # # # ]: 0 : if (xac_at->AttributeId->g.len == sizeof("role")-1
289 : : && !memcmp(xac_at->AttributeId->g.s, "role", sizeof("role")-1)) {
290 [ # # # # : 0 : ss = ZX_GET_CONTENT(xac_at->AttributeValue);
# # ]
291 [ # # # # ]: 0 : if (ss?ss->len:0 == sizeof("deny")-1 && !memcmp(ss->s, "deny", sizeof("deny")-1)) {
292 [ # # # # ]: 0 : D("PDP: Deny due to role=deny %d",0);
293 : 0 : zxid_ins_xacml_az_cd1_stmt(cf, a7n, "Deny");
294 : 0 : return zxid_mk_saml_resp(cf, a7n, 0);
295 : : }
296 : : }
297 : : }
298 : : }
299 [ # # # # ]: 0 : D("PDP: Permit by default %d",0);
300 : 0 : zxid_ins_xacml_az_cd1_stmt(cf, a7n, "Permit");
301 : 0 : return zxid_mk_saml_resp(cf, a7n, 0);
302 : : }
303 : :
304 : : /*() SOAP dispatch can also handle requests and responses received via artifact
305 : : * resolution. However only some combinations make sense.
306 : : * See zxid/sg/wsf-soap11.sg for the master SOAP dispatch from parsing perspective.
307 : : *
308 : : * Return 0 for failure, otherwise some success code such as ZXID_SSO_OK */
309 : :
310 : : /* Called by: zxid_idp_soap_parse, zxid_sp_deref_art, zxid_sp_soap_parse */
311 : : int zxid_sp_soap_dispatch(zxid_conf* cf, zxid_cgi* cgi, zxid_ses* ses, struct zx_root_s* r)
312 : 137 : {
313 : : X509* sign_cert;
314 : : EVP_PKEY* sign_pkey;
315 : : struct zxsig_ref refs;
316 : : struct zx_e_Header_s* hdr; /* Request headers */
317 : : struct zx_e_Body_s* bdy; /* Request Body */
318 : : struct zx_e_Body_s* body; /* Response Body */
319 : 137 : ses->sigres = ZXSIG_NO_SIG;
320 : :
321 [ + - ]: 137 : if (!r) goto bad;
322 [ + - ]: 137 : if (!r->Envelope) goto bad;
323 : 137 : hdr = r->Envelope->Header;
324 : 137 : bdy = r->Envelope->Body;
325 : :
326 [ + - ]: 137 : if (cf->log_level > 1)
327 [ - + - + : 137 : zxlog(cf, 0, 0, 0, 0, 0, 0, ZX_GET_CONTENT(ses->nameid), "N", "W", "SPDISP", 0, "sid(%s) soap", STRNULLCHK(ses->sid));
# # # # ]
328 : :
329 [ - + ]: 137 : if (bdy->ArtifactResponse) {
330 [ # # ]: 0 : if (!zxid_saml_ok(cf, cgi, bdy->ArtifactResponse->Status, "ArtResp"))
331 : 0 : return 0;
332 : 0 : return zxid_sp_dig_sso_a7n(cf, cgi, ses, bdy->ArtifactResponse->Response);
333 : : }
334 : :
335 [ - + ]: 137 : if (bdy->Response) { /* PAOS/ECP response */
336 [ # # ]: 0 : if (!zxid_saml_ok(cf, cgi, bdy->Response->Status, "PAOS Resp"))
337 : 0 : return 0;
338 : 0 : return zxid_sp_dig_sso_a7n(cf, cgi, ses, bdy->Response);
339 : : }
340 : :
341 : 137 : body = zx_NEW_e_Body(cf->ctx,0);
342 : :
343 [ - + ]: 137 : if (bdy->LogoutRequest) {
344 [ # # # # : 0 : ses->issuer = ZX_GET_CONTENT(bdy->LogoutRequest->Issuer);
# # ]
345 [ # # ]: 0 : if (!zxid_sp_slo_do(cf, cgi, ses, bdy->LogoutRequest))
346 : 0 : return 0;
347 : 0 : ZX_ADD_KID(body, LogoutResponse, zxid_mk_logout_resp(cf, zxid_OK(cf, 0), &bdy->LogoutRequest->ID->g));
348 [ # # ]: 0 : if (cf->sso_soap_resp_sign) {
349 : 0 : ZERO(&refs, sizeof(refs));
350 : 0 : refs.id = &body->LogoutResponse->ID->g;
351 : 0 : refs.canon = zx_easy_enc_elem_sig(cf, &body->LogoutResponse->gg);
352 [ # # ]: 0 : if (zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "use sign cert slor")) {
353 : 0 : body->LogoutResponse->Signature = zxsig_sign(cf->ctx, 1, &refs, sign_cert, sign_pkey);
354 : 0 : zx_add_kid_after_sa_Issuer(&body->LogoutResponse->gg,&body->LogoutResponse->Signature->gg);
355 : : }
356 : 0 : zx_str_free(cf->ctx, refs.canon);
357 : : }
358 : 0 : return zxid_soap_cgi_resp_body(cf, ses, body);
359 : : }
360 : :
361 [ - + ]: 137 : if (bdy->ManageNameIDRequest) {
362 [ # # # # : 0 : ses->issuer = ZX_GET_CONTENT(bdy->ManageNameIDRequest->Issuer);
# # ]
363 : 0 : ZX_ADD_KID(body, ManageNameIDResponse, zxid_mni_do(cf, cgi, ses, bdy->ManageNameIDRequest));
364 [ # # ]: 0 : if (cf->sso_soap_resp_sign) {
365 : 0 : ZERO(&refs, sizeof(refs));
366 : 0 : refs.id = &body->ManageNameIDResponse->ID->g;
367 : 0 : refs.canon = zx_easy_enc_elem_sig(cf, &body->ManageNameIDResponse->gg);
368 [ # # ]: 0 : if (zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "use sign cert mnir")) {
369 : 0 : body->ManageNameIDResponse->Signature = zxsig_sign(cf->ctx, 1, &refs,sign_cert,sign_pkey);
370 : 0 : zx_add_kid_after_sa_Issuer(&body->ManageNameIDResponse->gg, &body->ManageNameIDResponse->Signature->gg);
371 : : }
372 : 0 : zx_str_free(cf->ctx, refs.canon);
373 : : }
374 : 0 : return zxid_soap_cgi_resp_body(cf, ses, body);
375 : : }
376 : :
377 : : DD("as_ena=%d %p", cf->as_ena, bdy->SASLRequest);
378 [ + - ]: 137 : if (cf->as_ena) {
379 [ + + ]: 137 : if (bdy->SASLRequest) {
380 [ - + # # : 18 : if (hdr && hdr->Sender && hdr->Sender->providerID)
# # ]
381 : 0 : ses->issuer = &hdr->Sender->providerID->g;
382 : : else
383 : 18 : ses->issuer = 0;
384 : : //ses->issuer = ZX_GET_CONTENT(bdy->SASLRequest->Issuer);
385 : 18 : ZX_ADD_KID(body, SASLResponse, zxid_idp_as_do(cf, bdy->SASLRequest));
386 : : #if 0
387 : : if (cf->sso_soap_resp_sign) {
388 : : ZERO(&refs, sizeof(refs));
389 : : refs.id = res->ID;
390 : : refs.canon = zx_EASY_ENC_SO_as_SASLResponse(cf->ctx, res);
391 : : if (zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "use sign cert asr")) {
392 : : res->Signature = zxsig_sign(cf->ctx, 1, &refs, sign_cert, sign_pkey);
393 : : zx_add_kid(&res->gg, &res->gg);
394 : : }
395 : : zx_str_free(cf->ctx, refs.canon);
396 : : }
397 : : #endif
398 : 18 : return zxid_soap_cgi_resp_body(cf, ses, body);
399 : : }
400 : : }
401 : :
402 [ + - ]: 119 : if (cf->pdp_ena) {
403 [ + + ]: 119 : if (bdy->XACMLAuthzDecisionQuery) {
404 [ + - + - : 99 : ses->issuer = ZX_GET_CONTENT(bdy->XACMLAuthzDecisionQuery->Issuer);
+ - ]
405 [ + - - + ]: 99 : D("XACMLAuthzDecisionQuery %d",0);
406 : 99 : ZX_ADD_KID(body, Response, zxid_xacml_az_do(cf, cgi, ses, bdy->XACMLAuthzDecisionQuery));
407 [ + - ]: 99 : if (cf->sso_soap_resp_sign) {
408 : 99 : ZERO(&refs, sizeof(refs));
409 : 99 : refs.id = &body->Response->ID->g;
410 : 99 : refs.canon = zx_easy_enc_elem_sig(cf, &body->Response->gg);
411 [ + - ]: 99 : if (zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "use sign cert azr")) {
412 : 99 : body->Response->Signature = zxsig_sign(cf->ctx, 1, &refs, sign_cert, sign_pkey);
413 : 99 : zx_add_kid_after_sa_Issuer(&body->Response->gg, &body->Response->Signature->gg);
414 : : }
415 : 99 : zx_str_free(cf->ctx, refs.canon);
416 : : }
417 : 99 : return zxid_soap_cgi_resp_body(cf, ses, body);
418 : : }
419 [ - + ]: 20 : if (bdy->xaspcd1_XACMLAuthzDecisionQuery) {
420 [ # # # # : 0 : ses->issuer = ZX_GET_CONTENT(bdy->XACMLAuthzDecisionQuery->Issuer);
# # ]
421 [ # # # # ]: 0 : D("xaspcd1:XACMLAuthzDecisionQuery %d",0);
422 : 0 : ZX_ADD_KID(body, Response, zxid_xacml_az_cd1_do(cf, cgi, ses, bdy->xaspcd1_XACMLAuthzDecisionQuery));
423 [ # # ]: 0 : if (cf->sso_soap_resp_sign) {
424 : 0 : ZERO(&refs, sizeof(refs));
425 : 0 : refs.id = &body->Response->ID->g;
426 : 0 : refs.canon = zx_easy_enc_elem_sig(cf, &body->Response->gg);
427 [ # # ]: 0 : if (zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "use sign cert azr")) {
428 : 0 : body->Response->Signature = zxsig_sign(cf->ctx, 1, &refs, sign_cert, sign_pkey);
429 : 0 : zx_add_kid_after_sa_Issuer(&body->Response->gg, &body->Response->Signature->gg);
430 : : }
431 : 0 : zx_str_free(cf->ctx, refs.canon);
432 : : }
433 : 0 : return zxid_soap_cgi_resp_body(cf, ses, body);
434 : : }
435 : : }
436 : :
437 [ + - ]: 20 : if (cf->idp_ena) {
438 [ - + ]: 20 : if (bdy->ArtifactResolve) {
439 [ # # # # ]: 0 : D("*** ArtifactResolve not implemented yet %d",0);
440 : : //if (!zxid_saml_ok(cf, cgi, bdy->ArtifactResponse->Status, "ArtResp"))
441 : : // return 0;
442 : : //return zxid_sp_dig_sso_a7n(cf, cgi, ses, bdy->ArtifactResponse->Response);
443 : : }
444 : :
445 [ - + # # ]: 20 : if (bdy->NameIDMappingRequest && cf->imps_ena) {
446 [ # # # # : 0 : ses->issuer = ZX_GET_CONTENT(bdy->NameIDMappingRequest->Issuer);
# # ]
447 : 0 : ZX_ADD_KID(body, NameIDMappingResponse, zxid_nidmap_do(cf, bdy->NameIDMappingRequest));
448 [ # # ]: 0 : if (cf->sso_soap_resp_sign) {
449 : 0 : ZERO(&refs, sizeof(refs));
450 : 0 : refs.id = &body->NameIDMappingResponse->ID->g;
451 : 0 : refs.canon = zx_easy_enc_elem_sig(cf, &body->NameIDMappingResponse->gg);
452 [ # # ]: 0 : if (zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "use sign cert mnir")) {
453 : 0 : body->NameIDMappingResponse->Signature = zxsig_sign(cf->ctx, 1, &refs, sign_cert, sign_pkey);
454 : 0 : zx_add_kid_after_sa_Issuer(&body->NameIDMappingResponse->gg, &body->NameIDMappingResponse->Signature->gg);
455 : : }
456 : 0 : zx_str_free(cf->ctx, refs.canon);
457 : : }
458 : 0 : return zxid_soap_cgi_resp_body(cf, ses, body);
459 : : }
460 : :
461 [ + + ]: 20 : if (!zxid_wsp_validate_env(cf, ses, 0, r->Envelope))
462 : 2 : return 0;
463 : :
464 [ + + ]: 18 : if (bdy->Query) { /* Discovery 2.0 Query */
465 : 17 : ZX_ADD_KID(body, QueryResponse, zxid_di_query(cf, ses, bdy->Query));
466 : 18 : idwsf_resp:
467 : : #if 0
468 : : // *** should really sign the Body, putting sig in wsse:Security header
469 : : if (cf->sso_soap_resp_sign) {
470 : : ZERO(&refs, sizeof(refs));
471 : : refs.id = di_resp->ID;
472 : : refs.canon = zx_EASY_ENC_SO_e_Body(cf->ctx, body);
473 : : if (zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "use sign cert dir")) {
474 : : res->Signature = zxsig_sign(cf->ctx, 1, &refs, sign_cert, sign_pkey);
475 : : zx_add_kid_after_sa_Issuer(&res->gg, &res->Signature->gg);
476 : : }
477 : : zx_str_free(cf->ctx, refs.canon);
478 : : }
479 : : #endif
480 : :
481 : 18 : return zxid_soap_cgi_resp_body(cf, ses, body);
482 : : }
483 : :
484 [ + - ]: 1 : if (cf->imps_ena) {
485 [ - + ]: 1 : if (bdy->AddEntityRequest) {
486 : 0 : ZX_ADD_KID(body, AddEntityResponse, zxid_ps_addent_invite(cf, ses, bdy->AddEntityRequest));
487 : 0 : goto idwsf_resp;
488 : : }
489 [ - + ]: 1 : if (bdy->ResolveIdentifierRequest) {
490 : 0 : ZX_ADD_KID(body, ResolveIdentifierResponse, zxid_ps_resolv_id(cf, ses, bdy->ResolveIdentifierRequest));
491 : 0 : goto idwsf_resp;
492 : : }
493 [ - + ]: 1 : if (bdy->IdentityMappingRequest) {
494 : 0 : ZX_ADD_KID(body, IdentityMappingResponse, zxid_imreq(cf,ses, bdy->IdentityMappingRequest));
495 : 0 : goto idwsf_resp;
496 : : }
497 : : }
498 [ + - + - ]: 1 : if (bdy->AuthnRequest && cf->as_ena) {
499 : 1 : ZX_ADD_KID(body, Response, zxid_ssos_anreq(cf, ses, bdy->AuthnRequest));
500 : 1 : goto idwsf_resp;
501 : : }
502 : : }
503 : :
504 : 0 : bad:
505 : 0 : ERR("Unknown SOAP request %p", r);
506 [ # # ]: 0 : if (cf->log_level > 0)
507 [ # # # # : 0 : zxlog(cf, 0, 0, 0, 0, 0, 0, ZX_GET_CONTENT(ses->nameid), "N", "C", "SPDISP", 0, "sid(%s) unknown soap req", STRNULLCHK(ses->sid));
# # # # ]
508 : 0 : return 0;
509 : : }
510 : :
511 : : /*() Return 0 for failure, otherwise some success code such as ZXID_SSO_OK */
512 : :
513 : : /* Called by: chkuid, main x6, zxid_simple_cf_ses */
514 : : int zxid_sp_soap_parse(zxid_conf* cf, zxid_cgi* cgi, zxid_ses* ses, int len, char* buf)
515 : 137 : {
516 : : struct zx_root_s* r;
517 : 137 : r = zx_dec_zx_root(cf->ctx, len, buf, "sp soap parse");
518 [ + - + - : 137 : if (!r || !r->Envelope || !r->Envelope->Body) {
- + ]
519 : 0 : ERR("Failed to parse SOAP request buf(%.*s)", len, buf);
520 [ # # # # : 0 : zxlog(cf, 0, 0, 0, 0, 0, 0, ZX_GET_CONTENT(ses->nameid), "N", "C", "BADXML", 0, "sid(%s) bad soap req", STRNULLCHK(ses->sid));
# # # # ]
521 : 0 : return 0;
522 : : }
523 : 137 : return zxid_sp_soap_dispatch(cf, cgi, ses, r);
524 : : }
525 : :
526 : : /* EOF -- zxidspx.c */
|