LCOV - code coverage report
Current view: top level - zxid - zxidim.c (source / functions) Hit Total Coverage
Test: ZXID Code Coverage Lines: 68 240 28.3 %
Date: 2010-12-19 Functions: 3 5 60.0 %
Branches: 21 244 8.6 %

           Branch data     Line data    Source code
       1                 :            : /* zxidim.c  -  Identity Mapping Service
       2                 :            :  * Copyright (c) 2010 Sampo Kellomaki (sampo@iki.fi), All Rights Reserved.
       3                 :            :  * Copyright (c) 2010 Risaris Ltd, 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: zxiddi.c,v 1.2 2009-11-24 23:53:40 sampo Exp $
      10                 :            :  *
      11                 :            :  * 16.9.2010, created --Sampo
      12                 :            :  *
      13                 :            :  * See also zxcall for client
      14                 :            :  * - liberty-idwsf-authn-svc-v2.0.pdf sec 7 "Identity Mapping Service"
      15                 :            :  *
      16                 :            :  *   zxcot -e http://idp.tas3.pt:8081/zxididp?o=S 'IDMap Svc' \
      17                 :            :  *    http://idp.tas3.pt:8081/zxididp?o=B urn:liberty:ims:2006-08 \
      18                 :            :  *   | zxcot -b /var/zxid/idpdimd
      19                 :            :  *
      20                 :            :  * [SOAPAuthn2] "Liberty ID-WSF Authentication, Single Sign-On, and Identity Mapping Services Specification", liberty-idwsf-authn-svc-2.0-errata-v1.0.pdf from http://projectliberty.org/resource_center/specifications/
      21                 :            :  */
      22                 :            : 
      23                 :            : #include "platform.h"  /* for dirent.h */
      24                 :            : #include "errmac.h"
      25                 :            : #include "zxid.h"
      26                 :            : #include "zxidpriv.h"
      27                 :            : #include "zxidutil.h"
      28                 :            : #include "zxidconf.h"
      29                 :            : #include "saml2.h"
      30                 :            : #include "wsf.h"
      31                 :            : #include "c/zx-const.h"
      32                 :            : #include "c/zx-ns.h"
      33                 :            : #include "c/zx-data.h"
      34                 :            : 
      35                 :            : /*() ID-WSF Single Sign-On Service (SSOS): Issue SSO assertion in response to receiving a token.
      36                 :            :  * See also zxid_idp_sso() for similar code. */
      37                 :            : 
      38                 :            : /* Called by:  a7n_test, zxid_sp_soap_dispatch */
      39                 :            : struct zx_sp_Response_s* zxid_ssos_anreq(zxid_conf* cf, zxid_ses* ses, struct zx_sp_AuthnRequest_s* ar)
      40                 :          1 : {
      41                 :            :   zxid_a7n* outa7n;
      42                 :            :   X509* sign_cert;
      43                 :            :   EVP_PKEY* sign_pkey;
      44                 :            :   struct zxsig_ref refs;
      45                 :            :   zxid_cgi cgi;
      46                 :            :   char logop[8];
      47                 :          1 :   struct zx_sp_Response_s* resp = zx_NEW_sp_Response(cf->ctx,0);
      48                 :            :   struct zx_str* payload;
      49                 :            :   struct zx_str* ss;
      50                 :            :   zxid_entity* sp_meta;
      51                 :            :   char uid[ZXID_MAX_BUF];
      52                 :          1 :   D_INDENT("ssos: ");
      53                 :            : 
      54   [ +  -  +  -  :          1 :   if (!ar || !ZX_GET_CONTENT(ar->Issuer)) {
             +  -  -  + ]
      55                 :          0 :     ERR("No Issuer found in AuthnRequest %p", ar);
      56                 :          0 :     resp->Status = zxid_mk_Status(cf, &resp->gg, "Fail", 0, 0);
      57                 :          0 :     D_DEDENT("ssos: ");
      58                 :          0 :     return resp;
      59                 :            :   }
      60                 :            : 
      61         [ -  + ]:          1 :   if (!zxid_idp_map_nid2uid(cf, sizeof(uid), uid, ses->tgtnameid, 0)) {
      62                 :          0 :     resp->Status = zxid_mk_Status(cf, &resp->gg, "Fail", 0, 0);
      63                 :          0 :     D_DEDENT("ssos: ");
      64                 :          0 :     return resp;
      65                 :            :   }
      66                 :            :   
      67                 :          1 :   ZERO(&cgi, sizeof(cgi));
      68                 :          1 :   ses->an_instant = time(0);  /* This will be later used by AuthnStatement constructor. */
      69                 :          1 :   ses->an_ctx = SAML_AUTHCTX_PREVSESS;  /* Is there better one to use for token based auth? */
      70                 :          1 :   ss = zxid_mk_id(cf, "OSES", ZXID_ID_BITS);  /* Onetime Master session. Each pairwise SSO should have its own to avoid correlation. The session can not be used for SLO. */
      71                 :          1 :   ses->sesix = ss->s;
      72                 :          1 :   ZX_FREE(cf->ctx, ss);
      73                 :          1 :   ses->sid = cgi.sid = ses->sesix;
      74                 :          1 :   cgi.uid = uid;
      75                 :          1 :   ses->uid = cgi.uid;
      76                 :            :   /*zxid_put_ses(cf, ses);*/
      77                 :            :   
      78   [ +  -  +  -  :          1 :   sp_meta = zxid_get_ent_ss(cf, ZX_GET_CONTENT(ar->Issuer));
                   +  - ]
      79         [ -  + ]:          1 :   if (!sp_meta) {
      80                 :          0 :     ERR("The metadata for Issuer of the AuthnRequest could not be found or fetched %d", 0);
      81                 :          0 :     resp->Status = zxid_mk_Status(cf, &resp->gg, "Fail", 0, 0);
      82                 :          0 :     D_DEDENT("ssos: ");
      83                 :          0 :     return resp;
      84                 :            :   }
      85   [ +  -  -  + ]:          1 :   D("sp_eid(%s)", sp_meta->eid);
      86                 :            : 
      87                 :          1 :   outa7n = zxid_sso_issue_a7n(cf, &cgi, ses, &ses->srcts, sp_meta, 0, 0, logop, ar);
      88                 :            : 
      89         [ +  - ]:          1 :   if (cf->sso_sign & ZXID_SSO_SIGN_A7N) {
      90                 :          1 :     ZERO(&refs, sizeof(refs));
      91                 :          1 :     refs.id = &outa7n->ID->g;
      92                 :          1 :     refs.canon = zx_easy_enc_elem_sig(cf, &outa7n->gg);
      93         [ +  - ]:          1 :     if (zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "use sign cert paos")) {
      94                 :          1 :       outa7n->Signature = zxsig_sign(cf->ctx, 1, &refs, sign_cert, sign_pkey);
      95                 :          1 :       zx_add_kid_after_sa_Issuer(&outa7n->gg, &outa7n->Signature->gg);
      96                 :            :     }
      97                 :            :   }
      98         [ +  - ]:          1 :   resp = zxid_mk_saml_resp(cf, outa7n, cf->post_a7n_enc?sp_meta:0);
      99                 :          1 :   payload = zxid_anoint_sso_resp(cf, cf->sso_sign & ZXID_SSO_SIGN_RESP, resp, ar);
     100         [ -  + ]:          1 :   if (!payload) {
     101                 :          0 :     resp->Status = zxid_mk_Status(cf, &resp->gg, "Fail", 0, 0);
     102                 :          0 :     D_DEDENT("ssos: ");
     103                 :          0 :     return resp;
     104                 :            :   }
     105                 :          1 :   zx_str_free(cf->ctx, payload);
     106                 :            : 
     107                 :          1 :   zxlogwsp(cf, ses, "K", logop, uid, "SSOS");
     108                 :            : 
     109                 :            :   /* *** Generate SOAP envelope with ECP header as required by ECP PAOS */
     110                 :            :   
     111                 :          1 :   D_DEDENT("ssos: ");
     112                 :          1 :   return resp;
     113                 :            : }
     114                 :            : 
     115                 :            : /*(i) Use Liberty ID-WSF 2.0 Identity Mapping Service to convert
     116                 :            :  * the identity of the session to identity token in the namespace
     117                 :            :  * of the entity at_eid.
     118                 :            :  *
     119                 :            :  * This is the main work horse for WSCs wishing to call WSPs via EPR.
     120                 :            :  *
     121                 :            :  * cf:: ZXID configuration object, also used for memory allocation
     122                 :            :  * ses:: Session object in whose EPR cache the file will be searched
     123                 :            :  * at_eid:: EntityID of the destination namespace
     124                 :            :  * how:: How to make mapping (0 = invocaction identity, 1 = target identity)
     125                 :            :  * return:: 0 on failure, token on success
     126                 :            :  *
     127                 :            :  * This will generate <im:IdentityMappingRequest> in SOAP envelope to the
     128                 :            :  * IM service of the user, as discovered dynamically. For the discovery to work,
     129                 :            :  * the service must have been provisioned to the discovery, with command
     130                 :            :  * similar to
     131                 :            :  *
     132                 :            :  *  zxcot -e http://idp.tas3.pt:8081/zxididp?o=S 'IDMap Svc' \
     133                 :            :  *     http://idp.tas3.pt:8081/zxididp?o=B urn:liberty:ims:2006-08 \
     134                 :            :  *   | zxcot -b /var/zxid/idpdimd
     135                 :            :  *
     136                 :            :  * The received identity token is stored in session. From there it is usually
     137                 :            :  * automatically used in appropriate context (see the how argument). Typically
     138                 :            :  * you would not use the return value for anything else than checking for an error.
     139                 :            :  */
     140                 :            : 
     141                 :            : /* Called by:  zxcall_main */
     142                 :            : zxid_tok* zxid_map_identity_token(zxid_conf* cf, zxid_ses* ses, const char* at_eid, int how)
     143                 :          1 : {
     144                 :            :   struct zx_e_Envelope_s* env;
     145                 :            :   struct zx_im_MappingInput_s* inp;
     146                 :            :   struct zx_im_MappingOutput_s* out;
     147                 :            :   zxid_epr* epr;
     148                 :          1 :   epr = zxid_get_epr(cf, ses, XMLNS_IMS, 0, 0, 0, 1);
     149         [ -  + ]:          1 :   if (!epr) {
     150         [ #  # ]:          0 :     ERR("No Identity Mapping Service discovered svc(%s) how=%d", STRNULLCHK(at_eid), how);
     151                 :          0 :     return 0;
     152                 :            :   }
     153                 :            :   
     154         [ +  - ]:          1 :   INFO("Identity Mapping Svc svc(%s) how=%d...", STRNULLCHK(at_eid), how);
     155                 :          1 :   env = zx_NEW_e_Envelope(cf->ctx,0);
     156                 :          1 :   env->Body = zx_NEW_e_Body(cf->ctx, &env->gg);
     157                 :          1 :   env->Header = zx_NEW_e_Header(cf->ctx, &env->gg);
     158                 :          1 :   env->Body->IdentityMappingRequest = zx_NEW_im_IdentityMappingRequest(cf->ctx, &env->Body->gg);
     159                 :          1 :   env->Body->IdentityMappingRequest->MappingInput = inp = zx_NEW_im_MappingInput(cf->ctx, &env->Body->IdentityMappingRequest->gg);
     160                 :            :   //inp->Token = zx_NEW_sec_Token(cf->ctx, &inp->gg);
     161                 :            :   //inp->Token->ref = zx_dup_str(cf->ctx, "#A7N");
     162                 :          1 :   inp->TokenPolicy = zx_NEW_sec_TokenPolicy(cf->ctx, &inp->gg);
     163                 :          1 :   inp->TokenPolicy->type = zx_dup_attr(cf->ctx, &inp->TokenPolicy->gg, zx_type_ATTR, TOKNUSG_SEC);
     164                 :            : #if 0  /* Default is true anyway */
     165                 :            :   inp->TokenPolicy->wantDSEPR = zx_dup_attr(cf->ctx, &inp->TokenPolicy->gg, zx_wantDSEPR_ATTR, "1");
     166                 :            : #endif
     167                 :          1 :   inp->TokenPolicy->NameIDPolicy = zx_NEW_sp_NameIDPolicy(cf->ctx, &inp->TokenPolicy->gg);
     168                 :          1 :   inp->TokenPolicy->NameIDPolicy->Format = zx_ref_attr(cf->ctx, &inp->TokenPolicy->NameIDPolicy->gg, zx_Format_ATTR, zxid_saml2_map_nid_fmt("prstnt"));
     169                 :          1 :   inp->TokenPolicy->NameIDPolicy->SPNameQualifier = zx_dup_attr(cf->ctx, &inp->TokenPolicy->NameIDPolicy->gg, zx_SPNameQualifier_ATTR, at_eid);
     170                 :          1 :   inp->TokenPolicy->NameIDPolicy->AllowCreate = zx_ref_attr(cf->ctx, &inp->TokenPolicy->NameIDPolicy->gg, zx_AllowCreate_ATTR, XML_TRUE); /* default false */
     171                 :            : 
     172                 :          1 :   env = zxid_wsc_call(cf, ses, epr, env, 0);
     173   [ -  +  #  # ]:          1 :   if (!env || !env->Body) {
     174                 :          1 :     ERR("Identity Mapping call failed envelope=%p", env);
     175                 :          1 :     return 0;
     176                 :            :   }
     177         [ #  # ]:          0 :   if (!env->Body->IdentityMappingResponse) {
     178         [ #  # ]:          0 :       ERR("No Identity Mapping Response at_eid(%s)", STRNULLCHK(at_eid));
     179                 :          0 :       return 0;
     180                 :            :   }
     181                 :            : 
     182                 :          0 :   for (out = env->Body->IdentityMappingResponse->MappingOutput;
     183   [ #  #  #  # ]:          0 :        out && out->gg.g.tok == zx_im_MappingOutput_ELEM;
     184                 :            :        out = (void*)ZX_NEXT(out)) {
     185      [ #  #  # ]:          0 :     switch (how) {
     186                 :            :     case 0:
     187   [ #  #  #  # ]:          0 :       D("Invocation token set %p", out->Token);
     188                 :          0 :       ses->call_invoktok = out->Token;
     189                 :          0 :       break;
     190                 :            :     case 1:
     191   [ #  #  #  # ]:          0 :       D("Target Identity token set %p", out->Token);
     192                 :          0 :       ses->call_tgttok = out->Token;
     193                 :            :       break;
     194                 :            :     }
     195                 :          0 :     return out->Token;  /* Not really iterating */
     196                 :            :   }
     197                 :          0 :   return 0; /* never reached */
     198                 :            : }
     199                 :            : 
     200                 :            : /*() ID-WSF Identity Mapping Service: Issue token in response to receiving a token */
     201                 :            : 
     202                 :            : /* Called by:  zxid_sp_soap_dispatch */
     203                 :            : struct zx_im_IdentityMappingResponse_s* zxid_imreq(zxid_conf* cf, zxid_ses* ses, struct zx_im_IdentityMappingRequest_s* req)
     204                 :          0 : {
     205                 :          0 :   struct zx_im_IdentityMappingResponse_s* resp = zx_NEW_im_IdentityMappingResponse(cf->ctx,0);
     206                 :            :   struct zx_im_MappingInput_s* mapinp;
     207                 :            :   struct zx_im_MappingOutput_s* mapout;
     208                 :            :   zxid_tok* tok;
     209                 :            :   zxid_a7n* ina7n;
     210                 :            :   zxid_a7n* outa7n;
     211                 :            :   struct zx_str* issue_to;
     212                 :            :   char allow_create;
     213                 :            :   char* nid_fmt;
     214                 :            :   zxid_nid* nameid;
     215                 :            :   char* logop;
     216                 :          0 :   int  n_mapped = 0;
     217                 :            :   zxid_entity* sp_meta;
     218                 :            :   char sp_name_buf[1024];
     219                 :            :   char uid[ZXID_MAX_BUF];
     220                 :          0 :   D_INDENT("imreq: ");
     221                 :          0 :   ses->uid = uid;
     222                 :            : 
     223   [ #  #  #  # ]:          0 :   if (!req || !req->MappingInput) {
     224                 :          0 :     ERR("No IdentityMappingRequest/MappingInput found (WSC error) %p", req);
     225                 :          0 :     resp->Status = zxid_mk_lu_Status(cf, &resp->gg, "Fail", 0, 0, 0);
     226                 :          0 :     D_DEDENT("imreq: ");
     227                 :          0 :     return resp;
     228                 :            :   }
     229                 :            :   
     230                 :          0 :   for (mapinp = req->MappingInput;
     231   [ #  #  #  # ]:          0 :        mapinp && mapinp->gg.g.tok == zx_im_MappingInput_ELEM;
     232                 :          0 :        mapinp = (struct zx_im_MappingInput_s*)mapinp->gg.g.n) {
     233                 :            :   
     234         [ #  # ]:          0 :     if (tok = mapinp->Token) {
     235   [ #  #  #  # ]:          0 :       if (tok->Assertion || tok->EncryptedAssertion) {
     236                 :          0 :         ina7n = zxid_dec_a7n(cf, tok->Assertion, tok->EncryptedAssertion);
     237   [ #  #  #  # ]:          0 :         if (!ina7n || !ina7n->Subject) {
     238                 :          0 :           ERR("Missing or malformed MappingInput/Token/Assertion %p", ina7n);
     239                 :          0 :           continue;
     240                 :            :         }
     241                 :          0 :         ses->tgtnameid = zxid_decrypt_nameid(cf, ina7n->Subject->NameID, ina7n->Subject->EncryptedID);
     242   [ #  #  #  #  :          0 :       } else if (tok->ref && !ZX_STRCMP(&tok->ref->g, &ses->a7n->ID->g)) {
             #  #  #  # ]
     243   [ #  #  #  # ]:          0 :         D("Token->ref(%.*s) matches invocation security token.", tok->ref->g.len, tok->ref->g.s);
     244                 :            :         /* N.B. This is a common optimization as it often happens that invoker (delegatee) needs to
     245                 :            :          * IDMap his own token, while delegator's token can usually be found using discovery. */
     246                 :          0 :         ina7n = ses->a7n;
     247                 :            :       } else {
     248                 :          0 :         ERR("*** Missing IdentityMappingRequest/MappingInput/Token/(Encrypted)Assertion (WSC error). Using invocation identity instead. %p", tok);
     249                 :          0 :         ina7n = ses->a7n;
     250                 :            :       }
     251                 :            :     } else {
     252                 :          0 :       ERR("*** Missing IdentityMappingRequest/MappingInput/Token (WSC error). Using invocation identity instead. %d", 0);
     253                 :          0 :       ina7n = ses->a7n;
     254                 :            :     }
     255                 :            :     
     256         [ #  # ]:          0 :     if (!mapinp->TokenPolicy) {
     257                 :          0 :       ERR("Missing TokenPolicy. %d", 0);
     258                 :          0 :       resp->Status = zxid_mk_lu_Status(cf, &resp->gg, "Fail", 0, 0, 0);
     259                 :          0 :       D_DEDENT("imreq: ");
     260                 :          0 :       return resp;
     261                 :            :     }
     262                 :            : 
     263         [ #  # ]:          0 :     if (!zxid_idp_map_nid2uid(cf, sizeof(uid), uid, ses->tgtnameid, &resp->Status)) {
     264                 :          0 :       D_DEDENT("imreq: ");
     265                 :          0 :       return resp;
     266                 :            :     }
     267                 :            :     
     268                 :            :     /* Figure out destination */
     269                 :            : 
     270         [ #  # ]:          0 :     if (mapinp->TokenPolicy->NameIDPolicy) {
     271                 :          0 :       issue_to = &mapinp->TokenPolicy->NameIDPolicy->SPNameQualifier->g;
     272   [ #  #  #  #  :          0 :       nid_fmt = ZX_STR_EQ(&mapinp->TokenPolicy->NameIDPolicy->Format->g, SAML2_TRANSIENT_NID_FMT) ? "trnsnt" : "prstnt";
                   #  # ]
     273   [ #  #  #  #  :          0 :       allow_create = XML_TRUE_TEST(&mapinp->TokenPolicy->NameIDPolicy->AllowCreate->g) ? '1':'0';
          #  #  #  #  #  
                      # ]
     274                 :            :     } else {
     275                 :          0 :       issue_to = &mapinp->TokenPolicy->issueTo->g;
     276                 :          0 :       nid_fmt = "prstnt";
     277                 :          0 :       allow_create = '1';
     278                 :            :     }
     279                 :            :     
     280         [ #  # ]:          0 :     if (!issue_to) {
     281                 :          0 :       ERR("No NameIDPolicy->SPNameQualifier or issueTo %p", mapinp->TokenPolicy);
     282                 :          0 :       resp->Status = zxid_mk_lu_Status(cf, &resp->gg, "Fail", 0, 0, 0);
     283                 :          0 :       D_DEDENT("imreq: ");
     284                 :          0 :       return resp;
     285                 :            :     }
     286                 :          0 :     zxid_nice_sha1(cf, sp_name_buf, sizeof(sp_name_buf), issue_to, issue_to, 7);
     287                 :            : 
     288                 :            :     /* Check for federation */
     289                 :            : 
     290                 :          0 :     nameid = zxid_check_fed(cf, issue_to, uid, allow_create, 0, 0, 0, sp_name_buf);
     291         [ #  # ]:          0 :     if (nameid) {
     292   [ #  #  #  # ]:          0 :       if (nid_fmt && !strcmp(nid_fmt, "trnsnt")) {
     293   [ #  #  #  #  :          0 :         D("Despite old fed, using transient due to nid_fmt(%s)", STRNULLCHKD(nid_fmt));
                   #  # ]
     294                 :          0 :         zxid_mk_transient_nid(cf, nameid, sp_name_buf, uid);
     295                 :          0 :         logop = "ITIM";
     296                 :            :       } else
     297                 :          0 :         logop = "IFIM";
     298                 :            :     } else {
     299   [ #  #  #  # ]:          0 :       D("No nameid (because of no federation), using transient %d", 0);
     300                 :          0 :       nameid = zx_NEW_sa_NameID(cf->ctx,0);
     301                 :          0 :       zxid_mk_transient_nid(cf, nameid, sp_name_buf, uid);
     302                 :          0 :       logop = "ITIM";
     303                 :            :     }
     304                 :            : 
     305                 :            :     /* Issue the assertion and sign it. */
     306                 :            : 
     307                 :          0 :     sp_meta = zxid_get_ent_ss(cf, issue_to);
     308         [ #  # ]:          0 :     if (!sp_meta) {
     309                 :          0 :       ERR("The metadata for provider could not be found or fetched. Reject. %d", 0);
     310                 :          0 :       resp->Status = zxid_mk_lu_Status(cf, &resp->gg, "Fail", 0, 0, 0);
     311                 :          0 :       D_DEDENT("imreq: ");
     312                 :          0 :       return resp;
     313                 :            :     }
     314                 :            :     
     315                 :          0 :     outa7n = zxid_mk_usr_a7n_to_sp(cf, ses, nameid, sp_meta, sp_name_buf, 1);
     316                 :            :     
     317         [ #  # ]:          0 :     if (!zxid_anoint_a7n(cf, cf->sso_sign & ZXID_SSO_SIGN_A7N, outa7n, issue_to, "IMA7N", uid)) {
     318                 :          0 :       resp->Status = zxid_mk_lu_Status(cf, &resp->gg, "Fail", 0, 0, 0);
     319                 :          0 :       D_DEDENT("imreq: ");
     320                 :          0 :       return resp;
     321                 :            :     }
     322                 :            :     
     323                 :            :     /* Formulate mapping output */
     324                 :            : 
     325                 :          0 :     resp->MappingOutput = mapout = zx_NEW_im_MappingOutput(cf->ctx, &resp->gg);
     326   [ #  #  #  #  :          0 :     if (mapinp->reqID && mapinp->reqID->g.len && mapinp->reqID->g.s)
                   #  # ]
     327                 :          0 :       mapout->reqRef = zx_dup_len_attr(cf->ctx, &mapout->gg, zx_reqRef_ATTR, mapinp->reqID->g.len, mapinp->reqID->g.s);
     328                 :          0 :     mapout->Token = zx_NEW_sec_Token(cf->ctx, &mapout->gg);
     329         [ #  # ]:          0 :     if (cf->di_a7n_enc) {
     330                 :          0 :       mapout->Token->EncryptedAssertion = zxid_mk_enc_a7n(cf, &mapout->Token->gg, outa7n, sp_meta);
     331                 :            :     } else {
     332                 :          0 :       zx_add_kid(&mapout->Token->gg, &outa7n->gg);
     333                 :          0 :       mapout->Token->Assertion = outa7n;
     334                 :            :     }
     335                 :            : 
     336                 :          0 :     ++n_mapped;
     337                 :          0 :     zxlogwsp(cf, ses, "K", logop, 0,"n=%d", n_mapped);
     338                 :            :   }
     339                 :            :   
     340   [ #  #  #  # ]:          0 :   D("TOTAL Identity Mappings issued %d", n_mapped);
     341                 :          0 :   zxlogwsp(cf, ses, "K", "IMOK", 0, "n=%d", n_mapped);
     342                 :          0 :   resp->Status = zxid_mk_lu_Status(cf, &resp->gg, "OK", 0, 0, 0);
     343                 :          0 :   D_DEDENT("imreq: ");
     344                 :          0 :   return resp;
     345                 :            : }
     346                 :            : 
     347                 :            : /*(i) Use SAML 2.0 NameID Mapping Service to convert
     348                 :            :  * the identity of the session to identity token in the namespace
     349                 :            :  * of the entity at_eid.
     350                 :            :  *
     351                 :            :  * cf:: ZXID configuration object, also used for memory allocation
     352                 :            :  * ses:: Session object in whose EPR cache the file will be searched
     353                 :            :  * at_eid:: EntityID of the destination namespace
     354                 :            :  * how:: How to make mapping (0 = invocaction identity, 1 = target identity)
     355                 :            :  * return:: 0 on failure, token on success
     356                 :            :  *
     357                 :            :  * This will generate <im:IdentityMappingRequest> in SOAP envelope to the
     358                 :            :  * IM service of the user, as discovered dynamically. For the discovery to work,
     359                 :            :  * the service must have been provisioned to the discovery, with command
     360                 :            :  * similar to
     361                 :            :  *
     362                 :            :  *  zxcot -e http://idp.tas3.pt:8081/zxididp?o=S 'IDMap Svc' \
     363                 :            :  *     http://idp.tas3.pt:8081/zxididp?o=B urn:liberty:ims:2006-08 \
     364                 :            :  *   | zxcot -b /var/zxid/idpdimd
     365                 :            :  *
     366                 :            :  * The received identity token is stored in session. From there it is usually
     367                 :            :  * automatically used in appropriate context (see the how argument). Typically
     368                 :            :  * you would not use the return value for anything else than checking for an error.
     369                 :            :  */
     370                 :            : 
     371                 :            : /* Called by:  zxcall_main */
     372                 :            : zxid_tok* zxid_nidmap_identity_token(zxid_conf* cf, zxid_ses* ses, const char* at_eid, int how)
     373                 :          1 : {
     374                 :            :   struct zx_e_Envelope_s* env;
     375                 :            :   struct zx_sec_Token_s* tok;
     376                 :            :   struct zx_sp_NameIDMappingRequest_s* req;
     377                 :            :   zxid_epr* epr;
     378                 :          1 :   epr = zxid_get_epr(cf, ses, XMLNS_IMS, 0, 0, 0, 1);
     379         [ -  + ]:          1 :   if (!epr) {
     380         [ #  # ]:          0 :     ERR("No Identity Mapping Service discovered svc(%s) how=%d", STRNULLCHK(at_eid), how);
     381                 :          0 :     return 0;
     382                 :            :   }
     383                 :            :   
     384         [ +  - ]:          1 :   INFO("NID Mapping svc(%s) how=%d...", STRNULLCHK(at_eid), how);
     385                 :          1 :   env = zx_NEW_e_Envelope(cf->ctx,0);
     386                 :          1 :   env->Body = zx_NEW_e_Body(cf->ctx, &env->gg);
     387                 :          1 :   env->Header = zx_NEW_e_Header(cf->ctx, &env->gg);
     388                 :          1 :   env->Body->NameIDMappingRequest = req = zx_NEW_sp_NameIDMappingRequest(cf->ctx, &env->Body->gg);
     389                 :            : 
     390                 :          1 :   req->NameIDPolicy = zx_NEW_sp_NameIDPolicy(cf->ctx, &req->gg);
     391                 :          1 :   req->NameIDPolicy->Format = zx_ref_attr(cf->ctx, &req->NameIDPolicy->gg, zx_Format_ATTR, zxid_saml2_map_nid_fmt("prstnt"));
     392                 :          1 :   req->NameIDPolicy->SPNameQualifier = zx_dup_attr(cf->ctx, &req->NameIDPolicy->gg, zx_SPNameQualifier_ATTR, at_eid);
     393                 :          1 :   req->NameIDPolicy->AllowCreate = zx_ref_attr(cf->ctx, &req->NameIDPolicy->gg, zx_AllowCreate_ATTR, XML_TRUE); /* default false */
     394                 :            :   
     395                 :          1 :   req->NameID = ses->nameid;  /* or tgtnameid? */
     396                 :            : 
     397                 :          1 :   env = zxid_wsc_call(cf, ses, epr, env, 0);
     398   [ -  +  #  # ]:          1 :   if (!env || !env->Body) {
     399                 :          1 :     ERR("Identity Mapping call failed envelope=%p", env);
     400                 :          1 :     return 0;
     401                 :            :   }
     402         [ #  # ]:          0 :   if (!env->Body->NameIDMappingResponse) {
     403         [ #  # ]:          0 :       ERR("No Identity Mapping Response at_eid(%s)", STRNULLCHK(at_eid));
     404                 :          0 :       return 0;
     405                 :            :   }
     406                 :            :   
     407                 :          0 :   tok = zx_NEW_sec_Token(cf->ctx, 0);
     408         [ #  # ]:          0 :   if (env->Body->NameIDMappingResponse->NameID) {
     409                 :          0 :     ERR("*** NOT IMPLEMENTED NameIDMappingResponse has NameID %p", tok);
     410                 :            : 
     411         [ #  # ]:          0 :   } else if (env->Body->NameIDMappingResponse->EncryptedID) {
     412                 :          0 :     ERR("*** NOT IMPLEMENTED NameIDMappingResponse has EncryptedID %p", tok);
     413                 :            : 
     414                 :            :   } else {
     415                 :          0 :     ERR("NameIDMappingResponse did not contain any ID %p", tok);
     416                 :          0 :     return 0;
     417                 :            :   }
     418                 :            :       
     419      [ #  #  # ]:          0 :   switch (how) {
     420                 :            :   case 0:
     421   [ #  #  #  # ]:          0 :     D("Invocation token set %p", tok);
     422                 :          0 :     ses->call_invoktok = tok;
     423                 :          0 :     break;
     424                 :            :   case 1:
     425   [ #  #  #  # ]:          0 :     D("Target Identity token set %p", tok);
     426                 :          0 :     ses->call_tgttok = tok;
     427                 :            :     break;
     428                 :            :   }
     429                 :          0 :   return tok;
     430                 :            : }
     431                 :            : 
     432                 :            : /*() SAML NameID Mapping Service: Issue token in response to receiving a token */
     433                 :            : 
     434                 :            : /* Called by:  zxid_sp_soap_dispatch */
     435                 :            : struct zx_sp_NameIDMappingResponse_s* zxid_nidmap_do(zxid_conf* cf, struct zx_sp_NameIDMappingRequest_s* req)
     436                 :          0 : {
     437                 :          0 :   struct zx_sp_NameIDMappingResponse_s* resp = zx_NEW_sp_NameIDMappingResponse(cf->ctx,0);
     438                 :            :   struct zx_str* issue_to;
     439                 :            :   struct zx_str* affil;
     440                 :            :   char allow_create;
     441                 :            :   char* nid_fmt;
     442                 :            :   zxid_nid* nameid;
     443                 :            :   char* logop;
     444                 :          0 :   int len, n_mapped = 0;
     445                 :            :   char uid[ZXID_MAX_BUF];
     446                 :            :   char sp_name_buf[1024];
     447                 :          0 :   D_INDENT("nidmap: ");
     448                 :            :     
     449                 :            :   /* *** there should be some strict access control policies here, otherwise
     450                 :            :    * privacy can be lost by consulting nameids directly via this service. */
     451                 :            :   
     452                 :          0 :   nameid = zxid_decrypt_nameid(cf, req->NameID, req->EncryptedID);
     453         [ #  # ]:          0 :   affil = nameid->SPNameQualifier ? &nameid->SPNameQualifier->g : zxid_my_ent_id(cf);
     454                 :            :   
     455                 :          0 :   zxid_nice_sha1(cf, sp_name_buf, sizeof(sp_name_buf), affil, affil, 7);
     456   [ #  #  #  #  :          0 :   len = read_all(sizeof(uid)-1, uid, "idp_map_nid2uid", 1, "%s" ZXID_NID_DIR "%s/%.*s", cf->path, sp_name_buf, ZX_GET_CONTENT_LEN(nameid), ZX_GET_CONTENT_S(nameid));
          #  #  #  #  #  
                #  #  # ]
     457         [ #  # ]:          0 :   if (!len) {
     458   [ #  #  #  #  :          0 :     ERR("Can not find reverse mapping for SP,SHA1(%s) nid(%.*s)", sp_name_buf, ZX_GET_CONTENT_LEN(nameid), ZX_GET_CONTENT_S(nameid));
          #  #  #  #  #  
                #  #  # ]
     459                 :          0 :     resp->Status = zxid_mk_Status(cf, &resp->gg, "Fail", 0, 0);
     460                 :          0 :     D_DEDENT("nidmap: ");
     461                 :          0 :     return resp;
     462                 :            :   }
     463                 :            :   
     464                 :            :   /* Figure out destination */
     465                 :            :   
     466         [ #  # ]:          0 :   if (req->NameIDPolicy) {
     467                 :          0 :     issue_to = &req->NameIDPolicy->SPNameQualifier->g;
     468   [ #  #  #  #  :          0 :     nid_fmt = ZX_STR_EQ(&req->NameIDPolicy->Format->g, SAML2_TRANSIENT_NID_FMT) ? "trnsnt" : "prstnt";
                   #  # ]
     469   [ #  #  #  #  :          0 :     allow_create = XML_TRUE_TEST(&req->NameIDPolicy->AllowCreate->g) ? '1':'0';
          #  #  #  #  #  
                      # ]
     470                 :            :   } else {
     471                 :          0 :     issue_to = 0;
     472                 :            :   }
     473                 :            :   
     474         [ #  # ]:          0 :   if (!issue_to) {
     475                 :          0 :     ERR("No NameIDPolicy->SPNameQualifier %p", req->NameIDPolicy);
     476                 :          0 :     resp->Status = zxid_mk_Status(cf, &resp->gg, "Fail", 0, 0);
     477                 :          0 :     D_DEDENT("nidmap: ");
     478                 :          0 :     return resp;
     479                 :            :   }
     480                 :          0 :   zxid_nice_sha1(cf, sp_name_buf, sizeof(sp_name_buf), issue_to, issue_to, 7);
     481                 :            :   
     482                 :            :   /* Check for federation */
     483                 :            :   
     484                 :          0 :   nameid = zxid_check_fed(cf, issue_to, uid, allow_create, 0, 0, 0, sp_name_buf);
     485         [ #  # ]:          0 :   if (nameid) {
     486   [ #  #  #  # ]:          0 :     if (nid_fmt && !strcmp(nid_fmt, "trnsnt")) {
     487   [ #  #  #  #  :          0 :       D("Despite old fed, using transient due to nid_fmt(%s)", STRNULLCHKD(nid_fmt));
                   #  # ]
     488                 :          0 :       zxid_mk_transient_nid(cf, nameid, sp_name_buf, uid);
     489                 :          0 :       logop = "ITNIDMAP";
     490                 :            :     } else
     491                 :          0 :       logop = "IFNIDMAP";
     492                 :            :   } else {
     493   [ #  #  #  # ]:          0 :     D("No nameid (because of no federation), using transient %d", 0);
     494                 :          0 :     nameid = zx_NEW_sa_NameID(cf->ctx,0);
     495                 :          0 :     zxid_mk_transient_nid(cf, nameid, sp_name_buf, uid);
     496                 :          0 :     logop = "ITNIDMAP";
     497                 :            :   }
     498                 :            :   
     499   [ #  #  #  #  :          0 :   zxlog(cf, 0, 0, 0, 0, 0, 0, ZX_GET_CONTENT(nameid), "N", "K", logop, 0, "n=%d", n_mapped);
                   #  # ]
     500                 :          0 :   resp->Status = zxid_OK(cf, &resp->gg);
     501                 :          0 :   D_DEDENT("nidmap: ");
     502                 :          0 :   return resp;
     503                 :            : }
     504                 :            : 
     505                 :            : /* EOF  --  zxidim.c */

Generated by: LCOV version 1.9