LCOV - code coverage report
Current view: top level - zxid - zxidpep.c (source / functions) Hit Total Coverage
Test: ZXID Code Coverage Lines: 96 235 40.9 %
Date: 2010-12-19 Functions: 6 12 50.0 %
Branches: 68 266 25.6 %

           Branch data     Line data    Source code
       1                 :            : /* zxidpep.c  -  Handwritten functions for XACML Policy Enforcement Point
       2                 :            :  * Copyright (c) 2010 Sampo Kellomaki (sampo@iki.fi), All Rights Reserved.
       3                 :            :  * Copyright (c) 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: zxidpep.c,v 1.10 2010-01-08 02:10:09 sampo Exp $
      10                 :            :  *
      11                 :            :  * 24.8.2009, created --Sampo
      12                 :            :  * 10.10.2009, added zxid_az() family --Sampo
      13                 :            :  * 12.2.2010,  added locking to lazy loading --Sampo
      14                 :            :  * 31.5.2010,  generalized to several PEPs model --Sampo
      15                 :            :  * 7.9.2010,   merged patches from Stijn Lievens --Sampo
      16                 :            :  */
      17                 :            : 
      18                 :            : #include "errmac.h"
      19                 :            : #include "zxid.h"
      20                 :            : #include "zxidpriv.h"
      21                 :            : #include "zxidconf.h"
      22                 :            : #include "saml2.h"
      23                 :            : #include "c/zx-const.h"
      24                 :            : #include "c/zx-ns.h"
      25                 :            : #include "c/zx-data.h"
      26                 :            : #include "c/zx-e-data.h"
      27                 :            : 
      28                 :            : #if 0
      29                 :            : #define XS_STRING "xs:string"
      30                 :            : #else
      31                 :            : #define XS_STRING "http://www.w3.org/2001/XMLSchema#string"
      32                 :            : #endif
      33                 :            : 
      34                 :            : /* ============== Policy Enforcement Point, Authorization Decision Query ============== */
      35                 :            : 
      36                 :            : /*() Extract attributes from session pool according to pepmap, usually the PEPMAP
      37                 :            :  * configuration variable.
      38                 :            :  *
      39                 :            :  * cf:: the configuration will need to have ~PEPMAP~ and ~PDP_URL~ options
      40                 :            :  *     set according to your situation.
      41                 :            :  * cgi:: if non-null, will receive error and status codes
      42                 :            :  * ses:: all attributes are obtained from the session. You may wish
      43                 :            :  *     to add additional attributes that are not known by SSO.
      44                 :            :  * pepmap:: The map used to extract the attributes from the pool to the XACML request
      45                 :            :  * subj:: Value-result parameter. Linked list of subject attributes.
      46                 :            :  * rsrc:: Value-result parameter. Linked list of resource attributes.
      47                 :            :  * act::  Value-result parameter. Linked list of action attributes (usually just one attribute).
      48                 :            :  * env::  Value-result parameter. Linked list of environment attributes.
      49                 :            :  */
      50                 :            : 
      51                 :            : /* Called by:  zxid_pep_az_base_soap_pepmap, zxid_pep_az_soap_pepmap */
      52                 :            : static void zxid_pepmap_extract(zxid_conf* cf, zxid_cgi* cgi, zxid_ses* ses, struct zxid_map* pepmap, struct zx_xac_Attribute_s** subj, struct zx_xac_Attribute_s** rsrc, struct zx_xac_Attribute_s** act, struct zx_xac_Attribute_s** env)
      53                 :         89 : {
      54                 :            :   struct zxid_map* map;
      55                 :            :   struct zxid_attr* at;
      56                 :            :   struct zxid_attr* av;
      57                 :            :   struct zx_xac_Attribute_s* xac_at;
      58                 :            :   char* name;
      59                 :            : 
      60   [ +  -  +  + ]:       4363 :   for (at = ses?ses->at:0; at; at = at->n) {
      61                 :       4274 :     map = zxid_find_map(pepmap, at->name);
      62         [ -  + ]:       4274 :     if (!map) {
      63   [ #  #  #  # ]:          0 :       D("ATTR(%s)=VAL(%s): Ignored due to no matching PEPMAP", at->name, at->val);
      64                 :          0 :       continue;
      65                 :            :     }
      66                 :            : 
      67         [ +  + ]:       4274 :     if (map->rule == ZXID_MAP_RULE_DEL) {
      68   [ +  +  -  + ]:        198 :       D("attribute(%s) filtered out by del rule in PEPMAP", at->name);
      69                 :        198 :       continue;
      70                 :            :     }
      71                 :            : 
      72                 :       4076 :     at->map_val = zxid_map_val(cf, ses, 0, map, at->name, at->val);
      73   [ +  -  +  +  :       4291 :     if (map->dst && *map->dst && map->src && map->src[0] != '*') {
             +  -  +  - ]
      74   [ +  +  -  + ]:        215 :       D("renaming(%s) to(%s) orig_val(%s) map_val(%.*s)", at->name, map->dst, at->val, at->map_val->len, at->map_val->s);
      75                 :        215 :       name = map->dst;
      76                 :            :     } else {
      77                 :       3861 :       name = at->name;
      78                 :            :     }
      79                 :       4076 :     xac_at = zxid_mk_xacml_simple_at(cf, 0,
      80                 :            :                                      zx_dup_str(cf->ctx, name),
      81                 :            :                                      zx_dup_str(cf->ctx, XS_STRING),
      82                 :            :                                      at->issuer, at->map_val);
      83   [ +  -  +  - ]:       8152 :     if (map->ns && *map->ns) {
      84         [ +  + ]:       4076 :       if (!strcmp(map->ns, "subj")) {
      85                 :         99 :         ZX_NEXT(xac_at) = (void*)*subj;
      86                 :         99 :         *subj = xac_at;
      87         [ +  + ]:       3977 :       } else if (!strcmp(map->ns, "rsrc")) {
      88                 :         99 :         ZX_NEXT(xac_at) = (void*)*rsrc;
      89                 :         99 :         *rsrc = xac_at;
      90         [ +  + ]:       3878 :       } else if (!strcmp(map->ns, "act")) {
      91                 :            : #if 0
      92                 :            :         *act = xac_at;  /* there can be only one */
      93                 :            : #else
      94                 :         17 :         ZX_NEXT(xac_at) = (void*)*act;
      95                 :         17 :         *act = xac_at;  /* We can have multiple attributes in the action section */
      96                 :            : #endif
      97         [ +  - ]:       3861 :       } else if (!strcmp(map->ns, "env")) {
      98                 :       3861 :         ZX_NEXT(xac_at) = (void*)*env;
      99                 :       3861 :         *env = xac_at;
     100                 :            :       } else {
     101                 :          0 :         ERR("PEPMAP unknown ns(%s). Valid values are subj, rsrc, act, and env.", map->ns);
     102                 :            :       }
     103                 :            :     } else {
     104                 :          0 :       ERR("PEPMAP entry lacks ns %p", map->ns);
     105                 :            :     }
     106                 :            :     
     107         [ -  + ]:       4076 :     for (av = at->nv; av; av = av->n) {
     108                 :          0 :       av->map_val = zxid_map_val(cf, ses, 0, map, at->name, av->val);
     109                 :          0 :       xac_at = zxid_mk_xacml_simple_at(cf, 0,
     110                 :            :                                        zx_dup_str(cf->ctx, name),
     111                 :            :                                        zx_dup_str(cf->ctx, XS_STRING),
     112                 :            :                                        at->issuer, at->map_val);
     113   [ #  #  #  # ]:          0 :       if (map->ns && *map->ns) {
     114         [ #  # ]:          0 :         if (!strcmp(map->ns, "subj")) {
     115                 :          0 :           ZX_NEXT(xac_at) = (void*)*subj;
     116                 :          0 :           *subj = xac_at;
     117         [ #  # ]:          0 :         } else if (!strcmp(map->ns, "rsrc")) {
     118                 :          0 :           ZX_NEXT(xac_at) = (void*)*rsrc;
     119                 :          0 :           *rsrc = xac_at;
     120         [ #  # ]:          0 :         } else if (!strcmp(map->ns, "act")) {
     121                 :          0 :           ERR("PEPMAP: Only one XACML action attribute allowed %d", 0);
     122         [ #  # ]:          0 :         } else if (!strcmp(map->ns, "env")) {
     123                 :          0 :           ZX_NEXT(xac_at) = (void*)*env;
     124                 :          0 :           *env = xac_at;
     125                 :            :         } else {
     126                 :          0 :           ERR("PEPMAP unknown ns(%s). Valid values are subj, rsrc, act, and env.", map->ns);
     127                 :            :         }
     128                 :            :       } else {
     129                 :          0 :         ERR("PEPMAP entry lacks ns %p", map->ns);
     130                 :            :       }
     131                 :            :     }
     132                 :            :   }
     133                 :            :   
     134         [ +  + ]:         89 :   if (!*act) {
     135                 :         72 :     *act = zxid_mk_xacml_simple_at(cf, 0,
     136                 :            :              zx_dup_str(cf->ctx, "urn:oasis:names:tc:xacml:1.0:action:action-id"),
     137                 :            :              zx_dup_str(cf->ctx, XS_STRING),
     138                 :            :              0,
     139                 :            :              zx_dup_str(cf->ctx, "urn:oasis:names:tc:xacml:1.0:action:implied-action"));
     140                 :            :   }
     141                 :         89 : }
     142                 :            : 
     143                 :            : /*() Call Policy Decision Point (PDP) to obtain an authorization decision
     144                 :            :  * about a contemplated action on a resource. The attributes from the session
     145                 :            :  * pool, as filtered by PEPMAP are fed to the PDP as inputs
     146                 :            :  * for the decision. The call is using XACML SAML profile over SOAP.
     147                 :            :  *
     148                 :            :  * cf:: the configuration will need to have ~PEPMAP~ and ~PDP_URL~ options
     149                 :            :  *     set according to your situation.
     150                 :            :  * cgi:: if non-null, will receive error and status codes
     151                 :            :  * ses:: all attributes are obtained from the session. You may wish
     152                 :            :  *     to add additional attributes that are not known by SSO.
     153                 :            :  * pdp_url:: URL of the PDP to contact
     154                 :            :  * subj:: Linked list of subject attributes.
     155                 :            :  * rsrc:: Linked list of resource attributes.
     156                 :            :  * act::  Linked list of action attributes (usually just one attribute).
     157                 :            :  * env::  Linked list of environment attributes.
     158                 :            :  * returns:: SAML Response as data structure or null upon error.
     159                 :            :  */
     160                 :            : 
     161                 :            : /* Called by:  zxid_pep_az_base_soap_pepmap, zxid_pep_az_soap_pepmap */
     162                 :            : static struct zx_sp_Response_s* zxid_az_soap(zxid_conf* cf, zxid_cgi* cgi, zxid_ses* ses, const char* pdp_url, struct zx_xac_Attribute_s* subj, struct zx_xac_Attribute_s* rsrc, struct zx_xac_Attribute_s* act, struct zx_xac_Attribute_s* env)
     163                 :         89 : {
     164                 :            :   X509* sign_cert;
     165                 :            :   EVP_PKEY* sign_pkey;
     166                 :            :   struct zxsig_ref refs;
     167                 :            :   struct zx_root_s* r;
     168                 :            :   struct zx_e_Header_s* hdr;
     169                 :            :   struct zx_e_Body_s* body;
     170                 :            :   struct zx_wsse_Security_s* sec;
     171                 :            :   struct zx_str* ss;
     172                 :            :   struct zx_sp_Response_s* resp;
     173                 :            : 
     174                 :         89 :   hdr = zx_NEW_e_Header(cf->ctx,0);
     175                 :            : #if 0
     176                 :            :   hdr->Action = zx_NEW_a_Action(cf->ctx, &hdr->gg);
     177                 :            :   //zx_add_content(cf->ctx, &hdr->Action->gg, zx_dup_str(cf->ctx, "urn:oasis:names:tc:xacml:2.0:profile:saml2.0:v2:schema:protocol:cd-01"));
     178                 :            :   zx_add_content(cf->ctx, &hdr->Action->gg, zx_dup_str(cf->ctx, "urn:oasis:xacml:2.0:saml:protocol:schema:os"));
     179                 :            : 
     180                 :            :   //zx_add_content(cf->ctx, &hdr->Action->gg, zx_dup_str(cf->ctx, "SAML2XACMLAuthzRequest"));
     181                 :            :   //zx_add_content(cf->ctx, &hdr->Action->gg, zx_dup_str(cf->ctx, "http://ws.apache.org/axis2/TestPolicyPortType/authRequestRequest"));
     182                 :            :   hdr->Action->mustUnderstand = zx_ref_str(cf->ctx, XML_TRUE);
     183                 :            :   hdr->Action->actor = zx_ref_str(cf->ctx, SOAP_ACTOR_NEXT);
     184                 :            : #endif
     185                 :            : 
     186                 :            :   /* Add our own token so PDP can do whatever PEP can (they are considered to be
     187                 :            :    * part of the same entity). This is TAS3 specific hack. */
     188                 :            : 
     189                 :         89 :   sec = hdr->Security = zx_NEW_wsse_Security(cf->ctx, &hdr->gg);
     190                 :         89 :   sec->actor = zx_ref_attr(cf->ctx, &sec->gg, zx_e_actor_ATTR, SOAP_ACTOR_NEXT);
     191                 :         89 :   sec->mustUnderstand = zx_ref_attr(cf->ctx, &sec->gg, zx_e_mustUnderstand_ATTR, XML_TRUE);
     192                 :         89 :   sec->Timestamp = zx_NEW_wsu_Timestamp(cf->ctx, &sec->gg);
     193                 :         89 :   sec->Timestamp->Created = zx_NEW_wsu_Created(cf->ctx, &sec->Timestamp->gg);
     194                 :         89 :   sec->Assertion = ses->tgta7n;
     195                 :         89 :   zx_reverse_elem_lists(&sec->gg);
     196   [ +  +  -  + ]:         89 :   D("tgta7n=%p", ses->tgta7n);
     197                 :            : 
     198                 :            :   /* Prepare request according to the version */
     199                 :            : 
     200                 :         89 :   body = zx_NEW_e_Body(cf->ctx,0);
     201         [ -  + ]:         89 :   if (!strcmp(cf->xasp_vers, "xac-soap")) {
     202                 :          0 :     ZX_ADD_KID(body, xac_Request, zxid_mk_xac_az(cf, &body->gg, subj, rsrc, act, env));
     203                 :            : #if 0
     204                 :            :     /* *** xac:Response does not have signature field */
     205                 :            :     if (cf->sso_soap_sign) {
     206                 :            :       ZERO(&refs, sizeof(refs));
     207                 :            :       refs.id = body->xac_Request->ID;
     208                 :            :       refs.canon = zx_EASY_ENC_SO_xac_Request(cf->ctx, body->xac_Request);
     209                 :            :       if (zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "use sign cert az xac-soap")) {
     210                 :            :         body->xac_Request->Signature = zxsig_sign(cf->ctx, 1, &refs, sign_cert, sign_pkey);
     211                 :            :         zx_add_kid(&body->xac_Request->gg, &body->xac_Request->Signature->gg);
     212                 :            :       }
     213                 :            :       zx_str_free(cf->ctx, refs.canon);
     214                 :            :     }
     215                 :            : #endif
     216         [ -  + ]:         89 :   } else if (!strcmp(cf->xasp_vers, "2.0-cd1")) {
     217                 :          0 :     ZX_ADD_KID(body, xaspcd1_XACMLAuthzDecisionQuery, zxid_mk_az_cd1(cf, subj, rsrc, act, env));
     218         [ #  # ]:          0 :     if (cf->sso_soap_sign) {
     219                 :          0 :       ZERO(&refs, sizeof(refs));
     220                 :          0 :       refs.id = &body->xaspcd1_XACMLAuthzDecisionQuery->ID->g;
     221                 :          0 :       refs.canon = zx_easy_enc_elem_sig(cf, &body->xaspcd1_XACMLAuthzDecisionQuery->gg);
     222         [ #  # ]:          0 :       if (zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "use sign cert az cd1")) {
     223                 :          0 :         body->xaspcd1_XACMLAuthzDecisionQuery->Signature
     224                 :            :           = zxsig_sign(cf->ctx, 1, &refs, sign_cert, sign_pkey);
     225                 :          0 :         zx_add_kid_after_sa_Issuer(&body->xaspcd1_XACMLAuthzDecisionQuery->gg, &body->xaspcd1_XACMLAuthzDecisionQuery->Signature->gg);
     226                 :            :       }
     227                 :          0 :       zx_str_free(cf->ctx, refs.canon);
     228                 :            :     }
     229                 :            :   } else {
     230                 :         89 :     ZX_ADD_KID(body, XACMLAuthzDecisionQuery, zxid_mk_az(cf, subj, rsrc, act, env));
     231         [ +  - ]:         89 :     if (cf->sso_soap_sign) {
     232                 :         89 :       ZERO(&refs, sizeof(refs));
     233                 :         89 :       refs.id = &body->XACMLAuthzDecisionQuery->ID->g;
     234                 :         89 :       refs.canon = zx_easy_enc_elem_sig(cf, &body->XACMLAuthzDecisionQuery->gg);
     235         [ +  - ]:         89 :       if (zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "use sign cert az")) {
     236                 :         89 :         body->XACMLAuthzDecisionQuery->Signature
     237                 :            :           = zxsig_sign(cf->ctx, 1, &refs, sign_cert, sign_pkey);
     238                 :         89 :         zx_add_kid_after_sa_Issuer(&body->XACMLAuthzDecisionQuery->gg, &body->XACMLAuthzDecisionQuery->Signature->gg);
     239                 :            :       }
     240                 :         89 :       zx_str_free(cf->ctx, refs.canon);
     241                 :            :     }
     242                 :            :   }
     243                 :            : 
     244                 :            :   /* Perform the network I/O for the call (connect to PDP) */
     245                 :            : 
     246                 :            : #if 0
     247                 :            :   //ss = zx_ref_str(cf->ctx, "https://idpdemo.tas3.eu:8443/zxididp?o=S");
     248                 :            :   // http://192.168.136.42:1104/axis2/services/TestPolicy.PERMISAuthzServerHttpSoap12Endpoint/
     249                 :            :   // http://192.168.1.27:1104/axis2/services/TestPolicy?wsdl
     250                 :            :   // http://192.168.1.66:1104/axis2/services/TestPolicy.PERMISAuthzServerHttpEndpoint/
     251                 :            :   ss = zx_ref_str(cf->ctx, "http://192.168.1.27:1104/axis2/services/TestPolicy.PERMISAuthzServerHttpEndpoint/");
     252                 :            :   //ss = zx_ref_str(cf->ctx, "");
     253                 :            :   //ss = zx_ref_str(cf->ctx, "http://192.168.1.66:1104/axis2/services/TestPolicy.PERMISAuthzServerHttpEndpoint/");
     254                 :            :   //ss = zx_ref_str(cf->ctx, "http://192.168.1.27:1104/axis2/services/TestPolicy.PERMISAuthzServerHttpSoap12Endpoint/");
     255                 :            : #else
     256                 :         89 :   ss = zx_ref_str(cf->ctx, pdp_url);
     257                 :            : #endif
     258                 :         89 :   r = zxid_soap_call_hdr_body(cf, ss, hdr, body);
     259                 :            :   //r = zxid_idp_soap(cf, cgi, ses, idp_meta, ZXID_MNI_SVC, body);
     260   [ +  -  +  -  :         89 :   if (!r || !r->Envelope || !r->Envelope->Body || !r->Envelope->Body->Response) {
             +  -  -  + ]
     261   [ #  #  #  #  :          0 :     ERR("Missing Response or other essential element %p %p %p %p", r, r?r->Envelope:0, r && r->Envelope?r->Envelope->Body:0, r && r->Envelope && r->Envelope->Body ? r->Envelope->Body->Response:0);
          #  #  #  #  #  
                #  #  # ]
     262                 :          0 :     return 0;
     263                 :            :   }
     264                 :            : 
     265                 :         89 :   resp = r->Envelope->Body->Response;
     266                 :            : 
     267                 :            :   /* Parse response from the PDP. */
     268                 :            : 
     269         [ -  + ]:         89 :   if (!zxid_saml_ok(cf, cgi, resp->Status, "AzResp")) {
     270                 :          0 :     ERR("Response->Status no OK (%p)", resp->Status);
     271                 :          0 :     return 0;
     272                 :            :   }
     273         [ -  + ]:         89 :   if (!resp->Assertion) {
     274                 :          0 :     ERR("No Assertion in the Response (%p)", resp);
     275                 :          0 :     return 0;
     276                 :            :   }
     277                 :            :   
     278                 :         89 :   return resp;
     279                 :            : }
     280                 :            : 
     281                 :            : /*(i) Call Policy Decision Point (PDP) to obtain an authorization decision
     282                 :            :  * about a contemplated action on a resource. The attributes from the session
     283                 :            :  * pool, as filtered by PEPMAP are fed to the PDP as inputs
     284                 :            :  * for the decision. The call is using XACML SAML profile over SOAP.
     285                 :            :  *
     286                 :            :  * cf:: the configuration will need to have ~PEPMAP~ and ~PDP_URL~ options
     287                 :            :  *     set according to your situation.
     288                 :            :  * cgi:: if non-null, will receive error and status codes
     289                 :            :  * ses:: all attributes are obtained from the session. You may wish
     290                 :            :  *     to add additional attributes that are not known by SSO.
     291                 :            :  * pdp_url:: URL of the PDP to contact
     292                 :            :  * pepmap:: The map used to extract the attributes from the pool to the XACML request
     293                 :            :  * returns:: 0 on error or deny (for any reason, e.g. indeterminate); in case of
     294                 :            :  *     permit returns <xac:Response> as string, allowing the obligations to be extracted.
     295                 :            :  *
     296                 :            :  * For simpler API, see zxid_az() family of functions.
     297                 :            :  */
     298                 :            : 
     299                 :            : /* Called by:  zxid_call_epr, zxid_pep_az_soap, zxid_simple_ab_pep, zxid_simple_ses_active_cf, zxid_wsc_prepare_call, zxid_wsc_valid_re_env, zxid_wsp_decorate, zxid_wsp_validate_env */
     300                 :            : char* zxid_pep_az_soap_pepmap(zxid_conf* cf, zxid_cgi* cgi, zxid_ses* ses, const char* pdp_url, struct zxid_map* pepmap)
     301                 :         89 : {
     302                 :         89 :   struct zx_xac_Attribute_s* subj = 0;
     303                 :         89 :   struct zx_xac_Attribute_s* rsrc = 0;
     304                 :         89 :   struct zx_xac_Attribute_s* act = 0;
     305                 :         89 :   struct zx_xac_Attribute_s* env = 0;
     306                 :            :   struct zx_str* ss;
     307                 :            :   struct zx_sp_Response_s* resp;
     308                 :            :   struct zx_sa_Statement_s* stmt;
     309                 :            :   struct zx_xasa_XACMLAuthzDecisionStatement_s* az_stmt;
     310                 :            :   struct zx_xasacd1_XACMLAuthzDecisionStatement_s* az_stmt_cd1;
     311                 :            :   struct zx_elem_s* decision;
     312                 :            :   char* p;
     313                 :            : 
     314         [ +  - ]:         89 :   if (cf->log_level>0)
     315   [ +  -  +  -  :         89 :     zxlog(cf, 0, 0, 0, 0, 0, 0, ses?ZX_GET_CONTENT(ses->nameid):0, "N", "W", "AZSOAP", ses?ses->sid:0, " ");
          +  +  +  -  +  
                      - ]
     316                 :            :   
     317   [ +  -  -  + ]:         89 :   if (!pdp_url || !*pdp_url) {
     318                 :          0 :     ERR("No PDP_URL or PDP_CALL_URL set. Deny. %p", pdp_url);
     319                 :          0 :     return 0;
     320                 :            :   }
     321                 :            : 
     322                 :         89 :   zxid_pepmap_extract(cf, cgi, ses, pepmap, &subj, &rsrc, &act, &env);
     323                 :         89 :   resp = zxid_az_soap(cf, cgi, ses, pdp_url, subj, rsrc, act, env);
     324   [ +  -  -  + ]:         89 :   if (!resp || !resp->Assertion) {
     325                 :          0 :     ERR("DENY due to malformed authorization response from PDP. Either no response or response lacking assertion. %p", resp);
     326                 :          0 :     return 0;
     327                 :            :   }
     328                 :            :   
     329                 :         89 :   az_stmt = resp->Assertion->XACMLAuthzDecisionStatement;
     330   [ +  -  +  -  :         89 :   if (az_stmt && az_stmt->Response && az_stmt->Response->Result) {
                   +  - ]
     331                 :         89 :     decision = az_stmt->Response->Result->Decision;
     332   [ +  -  +  -  :         89 :     if (ZX_CONTENT_EQ_CONST(decision, "Permit")) {
          +  -  +  -  +  
                      - ]
     333                 :         89 :       ss = zx_easy_enc_elem_opt(cf, &az_stmt->Response->gg);
     334   [ +  -  -  + ]:         89 :       if (!ss || !ss->len)
     335                 :          0 :         return 0;
     336                 :         89 :       p = ss->s;
     337                 :            :       DD("Permit azstmt(%s)", p);
     338                 :         89 :       INFO("PERMIT found in azstmt len=%d", ss->len);
     339                 :         89 :       ZX_FREE(cf->ctx, ss);
     340                 :         89 :       return p;
     341                 :            :     }
     342                 :            :   }
     343                 :          0 :   az_stmt_cd1 = resp->Assertion->xasacd1_XACMLAuthzDecisionStatement;
     344   [ #  #  #  #  :          0 :   if (az_stmt_cd1 && az_stmt_cd1->Response && az_stmt_cd1->Response->Result) {
                   #  # ]
     345                 :          0 :     decision = az_stmt_cd1->Response->Result->Decision;
     346   [ #  #  #  #  :          0 :     if (ZX_CONTENT_EQ_CONST(decision, "Permit")) {
          #  #  #  #  #  
                      # ]
     347                 :          0 :       ss = zx_easy_enc_elem_opt(cf, &az_stmt_cd1->Response->gg);
     348   [ #  #  #  # ]:          0 :       if (!ss || !ss->len)
     349                 :          0 :         return 0;
     350                 :          0 :       p = ss->s;
     351                 :          0 :       ZX_FREE(cf->ctx, ss);
     352                 :            :       DD("Permit cd1(%s)", p);
     353                 :          0 :       INFO("PERMIT found in azstmt_cd1 len=%d", ss->len);
     354                 :          0 :       ZX_FREE(cf->ctx, ss);
     355                 :          0 :       return p;
     356                 :            :     }
     357                 :            :   }
     358                 :          0 :   stmt = resp->Assertion->Statement;
     359   [ #  #  #  #  :          0 :   if (stmt && stmt->Response && stmt->Response->Result) {  /* Response here is xac:Response */
                   #  # ]
     360                 :          0 :     decision = stmt->Response->Result->Decision;
     361   [ #  #  #  #  :          0 :     if (ZX_CONTENT_EQ_CONST(decision, "Permit")) {
          #  #  #  #  #  
                      # ]
     362                 :          0 :       ss = zx_easy_enc_elem_opt(cf, &stmt->Response->gg);
     363   [ #  #  #  # ]:          0 :       if (!ss || !ss->len)
     364                 :          0 :         return 0;
     365                 :          0 :       p = ss->s;
     366   [ #  #  #  # ]:          0 :       D("Permit stmt(%s)", p);
     367                 :          0 :       INFO("PERMIT found in stmt len=%d", ss->len);
     368                 :          0 :       ZX_FREE(cf->ctx, ss);
     369                 :          0 :       return p;
     370                 :            :     }
     371                 :            :   }
     372                 :            :   /*if (resp->Assertion->AuthzDecisionStatement) {  }*/
     373   [ #  #  #  # ]:          0 :   D("Deny or error or no xac:Response in reply %d",0);
     374                 :          0 :   INFO("DENY or error or no xac:Response from PDP %p %p %p", az_stmt, az_stmt_cd1, stmt);
     375                 :          0 :   return 0;
     376                 :            : }
     377                 :            : 
     378                 :            : /*(i) Call Policy Decision Point (PDP) to obtain an authorization decision
     379                 :            :  * about a contemplated action on a resource. The attributes from the session
     380                 :            :  * pool, as filtered by PEPMAP are fed to the PDP as inputs
     381                 :            :  * for the decision. The call is using XACML SAML profile over SOAP.
     382                 :            :  *
     383                 :            :  * This is similar to zxid_pep_az_soap_pepmap() with the difference that the <xac:Response>
     384                 :            :  * element is returned even in the deny and indeterminate cases (null
     385                 :            :  * is still returned if there was an error). Effectively this +base+
     386                 :            :  * form does not make judgement about whether <xac:Response> means
     387                 :            :  * permit, deny, or something else.
     388                 :            :  *
     389                 :            :  * You should use this function if the Deny message contains interesting
     390                 :            :  * obligations (normally it does not).
     391                 :            :  *
     392                 :            :  * cf:: the configuration will need to have ~PEPMAP~ and ~PDP_URL~ options
     393                 :            :  *     set according to your situation.
     394                 :            :  * cgi:: if non-null, will receive error and status codes
     395                 :            :  * ses:: all attributes are obtained from the session. You may wish
     396                 :            :  *     to add additional attributes that are not known by SSO.
     397                 :            :  * pdp_url:: URL of the PDP to contact
     398                 :            :  * pepmap:: The map used to extract the attributes from the pool to the XACML request
     399                 :            :  * returns:: 0 on error; in case of deny (or indeterminate, etc.) as well as
     400                 :            :  *     permit returns <xac:Response> as string, allowing the obligations to be extracted.
     401                 :            :  *
     402                 :            :  * For simpler API, see zxid_az_base() family of functions.
     403                 :            :  */
     404                 :            : 
     405                 :            : /* Called by:  zxid_pep_az_base_soap */
     406                 :            : char* zxid_pep_az_base_soap_pepmap(zxid_conf* cf, zxid_cgi* cgi, zxid_ses* ses, const char* pdp_url, struct zxid_map* pepmap)
     407                 :          0 : {
     408                 :          0 :   struct zx_xac_Attribute_s* subj = 0;
     409                 :          0 :   struct zx_xac_Attribute_s* rsrc = 0;
     410                 :          0 :   struct zx_xac_Attribute_s* act = 0;
     411                 :          0 :   struct zx_xac_Attribute_s* env = 0;
     412                 :            :   char* res;
     413                 :            :   struct zx_str* ss;
     414                 :            :   struct zx_sp_Response_s* resp;
     415                 :            :   struct zx_sa_Statement_s* stmt;
     416                 :            :   struct zx_xasa_XACMLAuthzDecisionStatement_s* az_stmt;
     417                 :            :   struct zx_xasacd1_XACMLAuthzDecisionStatement_s* az_stmt_cd1;
     418                 :            : 
     419         [ #  # ]:          0 :   if (cf->log_level>0)
     420   [ #  #  #  #  :          0 :     zxlog(cf, 0, 0, 0, 0, 0, 0, ses?ZX_GET_CONTENT(ses->nameid):0, "N", "W", "AZSOAP", ses?ses->sid:0, " ");
          #  #  #  #  #  
                      # ]
     421                 :            :   
     422   [ #  #  #  # ]:          0 :   if (!pdp_url || !*pdp_url) {
     423                 :          0 :     ERR("No PDP_URL or PDP_CALL_URL set. Deny. %p", pdp_url);
     424                 :          0 :     return 0;
     425                 :            :   }
     426                 :            : 
     427                 :          0 :   zxid_pepmap_extract(cf, cgi, ses, pepmap, &subj, &rsrc, &act, &env);
     428                 :          0 :   resp = zxid_az_soap(cf, cgi, ses, pdp_url, subj, rsrc, act, env);
     429         [ #  # ]:          0 :   if (!resp)
     430                 :          0 :     return 0;
     431                 :            : 
     432                 :          0 :   az_stmt = resp->Assertion->XACMLAuthzDecisionStatement;
     433   [ #  #  #  # ]:          0 :   if (az_stmt && az_stmt->Response) {
     434                 :          0 :     ss = zx_easy_enc_elem_opt(cf, &az_stmt->Response->gg);
     435   [ #  #  #  # ]:          0 :     if (!ss || !ss->len)
     436                 :          0 :       return 0;
     437                 :          0 :     res = ss->s;
     438                 :          0 :     ZX_FREE(cf->ctx, ss);
     439   [ #  #  #  # ]:          0 :     D("azstmt(%s)", res);
     440                 :          0 :     return res;
     441                 :            :   }
     442                 :          0 :   az_stmt_cd1 = resp->Assertion->xasacd1_XACMLAuthzDecisionStatement;
     443   [ #  #  #  # ]:          0 :   if (az_stmt_cd1 && az_stmt_cd1->Response) {
     444                 :          0 :     ss = zx_easy_enc_elem_opt(cf, &az_stmt_cd1->Response->gg);
     445   [ #  #  #  # ]:          0 :     if (!ss || !ss->len)
     446                 :          0 :       return 0;
     447                 :          0 :     res = ss->s;
     448                 :          0 :     ZX_FREE(cf->ctx, ss);
     449   [ #  #  #  # ]:          0 :     D("cd1(%s)", res);
     450                 :          0 :     return res;
     451                 :            :   }
     452                 :          0 :   stmt = resp->Assertion->Statement;
     453   [ #  #  #  # ]:          0 :   if (stmt && stmt->Response) {  /* Response here is xac:Response */
     454                 :          0 :     ss = zx_easy_enc_elem_opt(cf, &stmt->Response->gg);
     455   [ #  #  #  # ]:          0 :     if (!ss || !ss->len)
     456                 :          0 :       return 0;
     457                 :          0 :     res = ss->s;
     458                 :          0 :     ZX_FREE(cf->ctx, ss);
     459   [ #  #  #  # ]:          0 :     D("stmt(%s)", res);
     460                 :          0 :     return res;
     461                 :            :   }
     462                 :            : 
     463   [ #  #  #  # ]:          0 :   D("Missing az related Response element %d",0);
     464                 :          0 :   return 0;
     465                 :            : }
     466                 :            : 
     467                 :            : /*() Call Policy Decision Point (PDP) to obtain an authorization decision.
     468                 :            :  * Uses default PEPMAP to call zxid_pep_az_soap_pepmap(). */
     469                 :            : 
     470                 :            : /* Called by:  zxid_az_cf_ses */
     471                 :         12 : char* zxid_pep_az_soap(zxid_conf* cf, zxid_cgi* cgi, zxid_ses* ses, const char* pdp_url) {
     472                 :         12 :   return zxid_pep_az_soap_pepmap(cf, cgi, ses, pdp_url, cf->pepmap);
     473                 :            : }
     474                 :            : 
     475                 :            : /* Called by:  zxid_az_base_cf_ses */
     476                 :          0 : char* zxid_pep_az_base_soap(zxid_conf* cf, zxid_cgi* cgi, zxid_ses* ses, const char* pdp_url) {
     477                 :          0 :   return zxid_pep_az_base_soap_pepmap(cf, cgi, ses, pdp_url, cf->pepmap);
     478                 :            : }
     479                 :            : 
     480                 :            : /*int zxid_az_cf_cgi_ses(zxid_conf* cf,  zxid_cgi* cgi, zxid_ses* ses);*/
     481                 :            : 
     482                 :            : /*(i) Call Policy Decision Point (PDP) to obtain an authorization decision
     483                 :            :  * about a contemplated action on a resource. The attributes from the session
     484                 :            :  * pool, as filtered by ~PEPMAP~ are fed to the PDP as inputs
     485                 :            :  * for the decision. Session object is passed in as an argument.
     486                 :            :  *
     487                 :            :  * cf:: the configuration will need to have ~PEPMAP~ and ~PDP_URL~ options
     488                 :            :  *     set according to your situation.
     489                 :            :  * qs:: if non-null, will resceive error and status codes
     490                 :            :  * ses:: all attributes are obtained from the session. You may wish
     491                 :            :  *     to add additional attributes that are not known by SSO.
     492                 :            :  *     The session object, e.g. from zxid_get_ses()
     493                 :            :  * returns:: 0 on deny (for any reason, e.g. indeterminate),  or string
     494                 :            :  *     containing the obligations on permit.
     495                 :            :  *
     496                 :            :  * For simpler API, see zxid_az() family of functions.
     497                 :            :  */
     498                 :            : 
     499                 :            : /* Called by:  zxcall_main, zxid_az_cf */
     500                 :            : char* zxid_az_cf_ses(zxid_conf* cf, const char* qs, zxid_ses* ses)
     501                 :         12 : {
     502                 :            :   zxid_cgi cgi;
     503                 :            :   char* ret;
     504   [ -  +  #  # ]:         12 :   char* url = (cf->pdp_call_url&&*cf->pdp_call_url) ? cf->pdp_call_url : cf->pdp_url;
     505                 :         12 :   D_INDENT("az: ");
     506                 :         12 :   ZERO(&cgi, sizeof(cgi));
     507                 :            :   /*zxid_parse_cgi(&cgi, "");  DD("qs(%s) ses=%p", STRNULLCHKD(qs), ses);*/
     508   [ +  -  +  - ]:         12 :   if (qs && ses)
     509                 :         12 :     zxid_add_qs_to_ses(cf, ses, zx_dup_cstr(cf->ctx, qs), 1);
     510                 :         12 :   ret = zxid_pep_az_soap(cf, &cgi, ses, url);
     511                 :         12 :   D_DEDENT("az: ");
     512                 :         12 :   return ret;
     513                 :            : }
     514                 :            : 
     515                 :            : /* Called by:  zxid_az_base_cf */
     516                 :            : char* zxid_az_base_cf_ses(zxid_conf* cf, const char* qs, zxid_ses* ses)
     517                 :          0 : {
     518                 :            :   zxid_cgi cgi;
     519                 :            :   char* ret;
     520   [ #  #  #  # ]:          0 :   char* url = (cf->pdp_call_url&&*cf->pdp_call_url) ? cf->pdp_call_url : cf->pdp_url;
     521                 :          0 :   D_INDENT("azb: ");
     522                 :          0 :   ZERO(&cgi, sizeof(cgi));
     523                 :            :   /*zxid_parse_cgi(&cgi, "");  DD("qs(%s) ses=%p", STRNULLCHKD(qs), ses);*/
     524   [ #  #  #  # ]:          0 :   if (qs && ses)
     525                 :          0 :     zxid_add_qs_to_ses(cf, ses, zx_dup_cstr(cf->ctx, qs), 1);
     526                 :          0 :   ret = zxid_pep_az_base_soap(cf, &cgi, ses, url);
     527                 :          0 :   D_DEDENT("azb: ");
     528                 :          0 :   return ret;
     529                 :            : }
     530                 :            : 
     531                 :            : /*(i) Call Policy Decision Point (PDP) to obtain an authorization decision
     532                 :            :  * about a contemplated action on a resource. The attributes from the session
     533                 :            :  * pool, as filtered by ~PEPMAP~ are fed to the PDP as inputs
     534                 :            :  * for the decision. Session is identified by a session id.
     535                 :            :  *
     536                 :            :  * cf:: the configuration will need to have ~PEPMAP~ and ~PDP_URL~ options
     537                 :            :  *     set according to your situation.
     538                 :            :  * qs:: if non-null, will resceive error and status codes
     539                 :            :  * sid:: all attributes are obtained from the session. You may wish
     540                 :            :  *     to add additional attributes that are not known by SSO. The
     541                 :            :  *     session id, such as returned from SSO.
     542                 :            :  * returns:: 0 on deny (for any reason, e.g. indeterminate),  or string
     543                 :            :  *     containing the obligations on permit.
     544                 :            :  *
     545                 :            :  * For simpler API, see zxid_az() family of functions.
     546                 :            :  */
     547                 :            : 
     548                 :            : /* Called by:  zxid_az */
     549                 :            : char* zxid_az_cf(zxid_conf* cf, const char* qs, const char* sid)
     550                 :          9 : {
     551                 :            :   zxid_ses ses;
     552                 :          9 :   ZERO(&ses, sizeof(ses));
     553   [ +  -  +  - ]:          9 :   if (sid && sid[0])
     554                 :          9 :     zxid_get_ses(cf, &ses, sid);
     555                 :          9 :   return zxid_az_cf_ses(cf, qs, &ses);
     556                 :            : }
     557                 :            : 
     558                 :            : /* Called by:  zxid_az_base */
     559                 :            : char* zxid_az_base_cf(zxid_conf* cf, const char* qs, const char* sid)
     560                 :          0 : {
     561                 :            :   zxid_ses ses;
     562                 :          0 :   ZERO(&ses, sizeof(ses));
     563   [ #  #  #  # ]:          0 :   if (sid && sid[0])
     564                 :          0 :     zxid_get_ses(cf, &ses, sid);
     565                 :          0 :   return zxid_az_base_cf_ses(cf, qs, &ses);
     566                 :            : }
     567                 :            : 
     568                 :            : /*() See zxid_az_cf() for description. Only difference is that the configuration
     569                 :            :  * is accepted as a string instead of an object. */
     570                 :            : 
     571                 :            : /* Called by: */
     572                 :            : char* zxid_az(const char* conf, const char* qs, const char* sid)
     573                 :          0 : {
     574                 :            :   struct zx_ctx ctx;
     575                 :            :   zxid_conf cf;
     576                 :          0 :   zx_reset_ctx(&ctx);
     577                 :          0 :   ZERO(&cf, sizeof(cf));
     578                 :          0 :   cf.ctx = &ctx;
     579                 :          0 :   zxid_conf_to_cf_len(&cf, -1, conf);
     580                 :          0 :   return zxid_az_cf(&cf, qs, sid);
     581                 :            : }
     582                 :            : 
     583                 :            : /* Called by: */
     584                 :            : char* zxid_az_base(const char* conf, const char* qs, const char* sid)
     585                 :          0 : {
     586                 :            :   struct zx_ctx ctx;
     587                 :            :   zxid_conf cf;
     588                 :          0 :   zx_reset_ctx(&ctx);
     589                 :          0 :   ZERO(&cf, sizeof(cf));
     590                 :          0 :   cf.ctx = &ctx;
     591                 :          0 :   zxid_conf_to_cf_len(&cf, -1, conf);
     592                 :          0 :   return zxid_az_base_cf(&cf, qs, sid);
     593                 :            : }
     594                 :            : 
     595                 :            : /* EOF  --  zxidpep.c */

Generated by: LCOV version 1.9