LCOV - code coverage report
Current view: top level - zxid - zxidpool.c (source / functions) Hit Total Coverage
Test: ZXID Code Coverage Lines: 262 446 58.7 %
Date: 2010-12-19 Functions: 11 14 78.6 %
Branches: 251 638 39.3 %

           Branch data     Line data    Source code
       1                 :            : /* zxidpool.c  -  Attribute handling
       2                 :            :  * Copyright (c) 2010 Sampo Kellomaki (sampo@iki.fi), All Rights Reserved.
       3                 :            :  * Copyright (c) 2007-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: zxidpool.c,v 1.7 2009-11-24 23:53:40 sampo Exp $
      10                 :            :  *
      11                 :            :  * 4.9.2009, forked from zxidsimp.c --Sampo
      12                 :            :  * 1.2.2010, added ses_to methods --Sampo
      13                 :            :  * 21.5.2010, added local attribute authority and local EPRs feature --Sampo
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "platform.h"
      17                 :            : 
      18                 :            : #include <memory.h>
      19                 :            : #include <string.h>
      20                 :            : #include <errno.h>
      21                 :            : 
      22                 :            : #include "errmac.h"
      23                 :            : #include "zx.h"
      24                 :            : #include "zxid.h"
      25                 :            : #include "zxidpriv.h"
      26                 :            : #include "zxidutil.h"
      27                 :            : #include "zxidconf.h"
      28                 :            : #include "c/zx-sa-data.h"
      29                 :            : 
      30                 :            : /*(i) Convert attributes from (session) pool to LDIF entry, applying OUTMAP.
      31                 :            :  * This is used by zxid_simple() SSO successful code to generate return
      32                 :            :  * value, but can also be used later to regenerate the LDIF
      33                 :            :  * given the pool. See zxid_ses_to_pool() for how to create the pool.
      34                 :            :  *
      35                 :            :  * N.B. More complete documentation is available in <<link: zxid-simple.pd>> (*** fixme) */
      36                 :            : 
      37                 :            : /* Called by: */
      38                 :            : static struct zx_str* zxid_pool_to_ldif(zxid_conf* cf, struct zxid_attr* pool)
      39                 :         11 : {
      40                 :            :   char* p;
      41                 :            :   char* name;
      42                 :         11 :   char* idpnid = 0;
      43                 :         11 :   char* affid = 0;
      44                 :         11 :   int len = 0, name_len;
      45                 :            :   struct zxid_map* map;
      46                 :            :   struct zxid_attr* at;
      47                 :            :   struct zxid_attr* av;
      48                 :            :   struct zx_str* ss;
      49                 :            :   
      50                 :            :   /* Length computation pass */
      51                 :            : 
      52         [ +  + ]:        508 :   for (at = pool; at; at = at->n) {
      53                 :        497 :     map = zxid_find_map(cf->outmap, at->name);
      54         [ +  + ]:        497 :     if (map) {
      55         [ +  + ]:        153 :       if (map->rule == ZXID_MAP_RULE_DEL) {
      56   [ +  -  -  + ]:          3 :         D("attribute(%s) filtered out by del rule in OUTMAP", at->name);
      57                 :          3 :         continue;
      58                 :            :       }
      59                 :        150 :       at->map_val = zxid_map_val(cf, 0, 0, map, at->name, at->val);
      60   [ +  -  +  +  :        153 :       if (map->dst && *map->dst && map->src && map->src[0] != '*') {
             +  -  +  - ]
      61                 :          3 :         name_len = strlen(map->dst);
      62                 :            :       } else {
      63                 :        147 :         name_len = strlen(at->name);
      64                 :            :       }
      65                 :        150 :       len += name_len + sizeof(": \n")-1 + at->map_val->len;
      66                 :            :       DD("len1=%d", len);
      67                 :            : 
      68         [ -  + ]:        150 :       for (av = at->nv; av; av = av->n) {
      69                 :          0 :         av->map_val = zxid_map_val(cf, 0, 0, map, at->name, av->val);
      70                 :          0 :         len += name_len + sizeof(": \n")-1 + av->map_val->len;
      71                 :            :         DD("len2=%d", len);
      72                 :            :       }
      73                 :            :     } else {
      74                 :        344 :       name_len = strlen(at->name);
      75         [ +  + ]:        344 :       len += name_len + sizeof(": \n")-1 + (at->val?strlen(at->val):0);
      76                 :            :       DD("len3=%d name_len=%d name(%s)", len, name_len, at->name);
      77         [ -  + ]:        344 :       for (av = at->nv; av; av = av->n) {
      78         [ #  # ]:          0 :         len += name_len + sizeof(": \n")-1 + (av->val?strlen(av->val):0);
      79                 :            :         DD("len4=%d", len);
      80                 :            :       }
      81                 :            :     }
      82                 :            : 
      83         [ +  + ]:        494 :     if (!strcmp(at->name, "idpnid")) idpnid = at->val;
      84         [ +  + ]:        483 :     else if (!strcmp(at->name, "affid")) affid = at->val;
      85                 :            :   }
      86   [ +  -  +  - ]:         11 :   len += sizeof("dn: idpnid=,affid=\n")-1 + (idpnid?strlen(idpnid):0) + (affid?strlen(affid):0);
      87                 :            :   DD("lenFin=%d", p-ss->s);
      88                 :            :   
      89                 :            :   /* Attribute rendering pass */
      90                 :            : 
      91                 :         11 :   ss = zx_new_len_str(cf->ctx, len);
      92                 :         11 :   p = ss->s;
      93                 :            : 
      94                 :         11 :   memcpy(p, "dn: idpnid=", sizeof("dn: idpnid=")-1);
      95                 :         11 :   p += sizeof("dn: idpnid=")-1;
      96         [ +  - ]:         11 :   if (idpnid) {
      97                 :         11 :     strcpy(p, idpnid);
      98                 :         11 :     p += strlen(idpnid);
      99                 :            :   }
     100                 :         11 :   memcpy(p, ",affid=", sizeof(",affid=")-1);
     101                 :         11 :   p += sizeof(",affid=")-1;
     102         [ +  - ]:         11 :   if (affid) {
     103                 :         11 :     strcpy(p, affid);
     104                 :         11 :     p += strlen(affid);
     105                 :            :   }
     106                 :         11 :   *p++ = '\n';
     107                 :            : 
     108                 :            :   DD("len 0=%d", p-ss->s);
     109                 :            : 
     110         [ +  + ]:        508 :   for (at = pool; at; at = at->n) {
     111                 :        497 :     map = zxid_find_map(cf->outmap, at->name);
     112         [ +  + ]:        497 :     if (map) {
     113         [ +  + ]:        153 :       if (map->rule == ZXID_MAP_RULE_DEL)
     114                 :          3 :         continue;
     115   [ +  -  +  +  :        153 :       if (map->dst && *map->dst && map->src && map->src[0] != '*') {
             +  -  +  - ]
     116                 :          3 :         name = map->dst;
     117                 :            :       } else {
     118                 :        147 :         name = at->name;
     119                 :            :       }
     120                 :            :       
     121                 :        150 :       name_len = strlen(name);
     122                 :        150 :       strcpy(p, name);
     123                 :        150 :       p += name_len;
     124                 :        150 :       *p++ = ':';
     125                 :        150 :       *p++ = ' ';
     126                 :        150 :       memcpy(p, at->map_val->s, at->map_val->len);
     127                 :        150 :       p += at->map_val->len;
     128                 :        150 :       *p++ = '\n';
     129                 :            : 
     130                 :            :       DD("len 1=%d", p-ss->s);
     131                 :            :       
     132         [ -  + ]:        150 :       for (av = at->nv; av; av = av->n) {
     133                 :          0 :         strcpy(p, name);
     134                 :          0 :         p += name_len;
     135                 :          0 :         *p++ = ':';
     136                 :          0 :         *p++ = ' ';
     137                 :          0 :         memcpy(p, av->map_val->s, av->map_val->len);
     138                 :          0 :         p += av->map_val->len;
     139                 :          0 :         *p++ = '\n';
     140                 :            : 
     141                 :            :         DD("len 2=%d", p-ss->s);
     142                 :            :       }
     143                 :            : 
     144                 :            : 
     145                 :            :     } else {
     146                 :        344 :       name_len = strlen(at->name);
     147                 :        344 :       strcpy(p, at->name);
     148                 :        344 :       p += name_len;
     149                 :        344 :       *p++ = ':';
     150                 :        344 :       *p++ = ' ';
     151         [ +  + ]:        344 :       if (at->val) {
     152                 :        314 :         strcpy(p, at->val);
     153                 :        314 :         p += strlen(at->val);
     154                 :            :       }
     155                 :        344 :       *p++ = '\n';
     156                 :            : 
     157                 :            :       DD("len 3=%d name_len=%d name(%s)", p-ss->s, name_len, at->name);
     158                 :            :       
     159         [ -  + ]:        344 :       for (av = at->nv; av; av = av->n) {
     160                 :          0 :         strcpy(p, at->name);
     161                 :          0 :         p += name_len;
     162                 :          0 :         *p++ = ':';
     163                 :          0 :         *p++ = ' ';
     164         [ #  # ]:          0 :         if (at->val) {
     165                 :          0 :           strcpy(p, av->val);
     166                 :          0 :           p += strlen(av->val);
     167                 :            :         }
     168                 :          0 :         *p++ = '\n';
     169                 :            : 
     170   [ #  #  #  # ]:          0 :         D("len 4=%d", p-ss->s);
     171                 :            :       }
     172                 :            : 
     173                 :            :     }
     174                 :            :   }
     175                 :            :   DD("len Fin=%d", p-ss->s);
     176                 :            : 
     177   [ -  +  #  # ]:         11 :   ASSERTOP(p, ==, ss->s+len);
     178                 :         11 :   return ss;
     179                 :            : }
     180                 :            : 
     181                 :            : /*() Convert attributes from (session) pool to JSON, applying OUTMAP.
     182                 :            :  * *** Need to check escaping JSON values, e.g. " or \n */
     183                 :            : 
     184                 :            : /* Called by:  zxid_ses_to_json */
     185                 :            : static struct zx_str* zxid_pool_to_json(zxid_conf* cf, struct zxid_attr* pool)
     186                 :          0 : {
     187                 :            :   char* p;
     188                 :            :   char* name;
     189                 :          0 :   int len = sizeof("{")-1, name_len;
     190                 :            :   struct zxid_map* map;
     191                 :            :   struct zxid_attr* at;
     192                 :            :   struct zxid_attr* av;
     193                 :            :   struct zx_str* ss;
     194                 :            :   
     195                 :            :   /* Length computation pass */
     196                 :            : 
     197         [ #  # ]:          0 :   for (at = pool; at; at = at->n) {
     198                 :          0 :     map = zxid_find_map(cf->outmap, at->name);
     199         [ #  # ]:          0 :     if (map) {
     200         [ #  # ]:          0 :       if (map->rule == ZXID_MAP_RULE_DEL) {
     201   [ #  #  #  # ]:          0 :         D("attribute(%s) filtered out by del rule in OUTMAP", at->name);
     202                 :          0 :         continue;
     203                 :            :       }
     204                 :          0 :       at->map_val = zxid_map_val(cf, 0, 0, map, at->name, at->val);
     205   [ #  #  #  #  :          0 :       if (map->dst && *map->dst && map->src && map->src[0] != '*') {
             #  #  #  # ]
     206                 :          0 :         name_len = strlen(map->dst);
     207                 :            :       } else {
     208                 :          0 :         name_len = strlen(at->name);
     209                 :            :       }
     210                 :            : 
     211         [ #  # ]:          0 :       if (at->nv) {  /* Multivalue requires array */
     212                 :          0 :         len += name_len + sizeof("\"\":[\"\"],")-1 + at->map_val->len;
     213         [ #  # ]:          0 :         for (av = at->nv; av; av = av->n) {
     214                 :          0 :           av->map_val = zxid_map_val(cf, 0, 0, map, at->name, av->val);
     215                 :          0 :           len += name_len + sizeof(",\"\"")-1 + av->map_val->len;
     216                 :            :         }
     217                 :            :       } else {
     218                 :          0 :         len += name_len + sizeof("\"\":\"\",")-1 + at->map_val->len;
     219                 :            :       }
     220                 :            :     } else {
     221                 :          0 :       name_len = strlen(at->name);
     222         [ #  # ]:          0 :       if (at->nv) {  /* Multivalue requires array */
     223         [ #  # ]:          0 :         len += name_len + sizeof("\"\":[\"\"],")-1 + (at->val?strlen(at->val):0);
     224         [ #  # ]:          0 :         for (av = at->nv; av; av = av->n)
     225         [ #  # ]:          0 :           len += name_len + sizeof(",\"\"")-1 + (av->val?strlen(av->val):0);
     226                 :            :       } else {
     227         [ #  # ]:          0 :         len += name_len + sizeof("\"\":\"\",")-1 + (at->val?strlen(at->val):0);
     228                 :            :       }
     229                 :            :     }
     230                 :            :   }
     231                 :            :   
     232                 :            :   /* Attribute rendering pass */
     233                 :            : 
     234                 :          0 :   ss = zx_new_len_str(cf->ctx, len);
     235                 :          0 :   p = ss->s;
     236                 :          0 :   *p++ = '{';
     237                 :            : 
     238         [ #  # ]:          0 :   for (at = pool; at; at = at->n) {
     239                 :          0 :     map = zxid_find_map(cf->outmap, at->name);
     240         [ #  # ]:          0 :     if (map) {
     241         [ #  # ]:          0 :       if (map->rule == ZXID_MAP_RULE_DEL)
     242                 :          0 :         continue;
     243   [ #  #  #  #  :          0 :       if (map->dst && *map->dst && map->src && map->src[0] != '*') {
             #  #  #  # ]
     244                 :          0 :         name = map->dst;
     245                 :            :       } else {
     246                 :          0 :         name = at->name;
     247                 :            :       }
     248                 :            : 
     249                 :          0 :       *p++ = '"';
     250                 :          0 :       strcpy(p, name);
     251                 :          0 :       p += strlen(name);
     252                 :          0 :       *p++ = '"';
     253                 :          0 :       *p++ = ':';
     254         [ #  # ]:          0 :       if (at->nv) {
     255                 :          0 :         *p++ = '[';
     256                 :          0 :         *p++ = '"';
     257                 :          0 :         memcpy(p, at->map_val->s, at->map_val->len);
     258                 :          0 :         p += at->map_val->len;
     259                 :          0 :         *p++ = '"';
     260         [ #  # ]:          0 :         for (av = at->nv; av; av = av->n) {
     261                 :          0 :           *p++ = ',';
     262                 :          0 :           *p++ = '"';
     263                 :          0 :           memcpy(p, av->map_val->s, av->map_val->len);
     264                 :          0 :           p += av->map_val->len;
     265                 :          0 :           *p++ = '"';
     266                 :            :         }
     267                 :          0 :         *p++ = ']';
     268                 :            :       } else {
     269                 :          0 :         *p++ = '"';
     270                 :          0 :         memcpy(p, at->map_val->s, at->map_val->len);
     271                 :          0 :         p += at->map_val->len;
     272                 :          0 :         *p++ = '"';
     273                 :            :       }
     274                 :            : 
     275                 :            :     } else {
     276                 :          0 :       *p++ = '"';
     277                 :          0 :       strcpy(p, at->name);
     278                 :          0 :       p += strlen(at->name);
     279                 :          0 :       *p++ = '"';
     280                 :          0 :       *p++ = ':';
     281         [ #  # ]:          0 :       if (at->nv) {
     282                 :          0 :         *p++ = '[';
     283                 :          0 :         *p++ = '"';
     284         [ #  # ]:          0 :         if (at->val) {
     285                 :          0 :           strcpy(p, at->val);
     286                 :          0 :           p += strlen(at->val);
     287                 :            :         }
     288                 :          0 :         *p++ = '"';
     289         [ #  # ]:          0 :         for (av = at->nv; av; av = av->n) {
     290                 :          0 :           *p++ = ',';
     291                 :          0 :           *p++ = '"';
     292         [ #  # ]:          0 :           if (at->val) {
     293                 :          0 :             strcpy(p, av->val);
     294                 :          0 :             p += strlen(av->val);
     295                 :            :           }
     296                 :          0 :           *p++ = '"';
     297                 :            :         }
     298                 :          0 :         *p++ = ']';
     299                 :            :       } else {
     300                 :          0 :         *p++ = '"';
     301         [ #  # ]:          0 :         if (at->val) {
     302                 :          0 :           strcpy(p, at->val);
     303                 :          0 :           p += strlen(at->val);
     304                 :            :         }
     305                 :          0 :         *p++ = '"';
     306                 :            :       }
     307                 :            :     }
     308                 :          0 :     *p++ = ',';
     309                 :            :   }
     310                 :          0 :   *p = '}';   /* Overwrites last comma */
     311   [ #  #  #  # ]:          0 :   ASSERTOP(p, ==, ss->s+len);
     312                 :          0 :   return ss;
     313                 :            : }
     314                 :            : 
     315                 :            : /*() Convert attributes from (session) pool to query string, applying OUTMAP.
     316                 :            :  * *** Need to check multivalue handling. Now all values are simply blurted
     317                 :            :  *     out as separate name=value pairs.
     318                 :            :  * *** Need to figure out how to distinguish query string return from
     319                 :            :  *     other returns, like redirect. Perhaps arrange dn field always first? */
     320                 :            : 
     321                 :            : /* Called by:  zxid_ses_to_qs */
     322                 :            : static struct zx_str* zxid_pool_to_qs(zxid_conf* cf, struct zxid_attr* pool)
     323                 :          3 : {
     324                 :            :   char* p;
     325                 :            :   char* name;
     326                 :          3 :   int len = sizeof("dn=QS1&")-1, name_len;
     327                 :            :   struct zxid_map* map;
     328                 :            :   struct zxid_attr* at;
     329                 :            :   struct zxid_attr* av;
     330                 :            :   struct zx_str* ss;
     331                 :            :   
     332                 :            :   /* Length computation pass */
     333                 :            : 
     334         [ +  + ]:        156 :   for (at = pool; at; at = at->n) {
     335                 :        153 :     map = zxid_find_map(cf->outmap, at->name);
     336         [ -  + ]:        153 :     if (map) {
     337         [ #  # ]:          0 :       if (map->rule == ZXID_MAP_RULE_DEL) {
     338   [ #  #  #  # ]:          0 :         D("attribute(%s) filtered out by del rule in OUTMAP", at->name);
     339                 :          0 :         continue;
     340                 :            :       }
     341                 :          0 :       at->map_val = zxid_map_val(cf, 0, 0, map, at->name, at->val);
     342   [ #  #  #  #  :          0 :       if (map->dst && *map->dst && map->src && map->src[0] != '*') {
             #  #  #  # ]
     343                 :          0 :         name_len = strlen(map->dst);
     344                 :            :       } else {
     345                 :          0 :         name_len = strlen(at->name);
     346                 :            :       }
     347                 :          0 :       len += name_len + sizeof("=&")-1 + zx_url_encode_len(at->map_val->len,at->map_val->s)-1;
     348         [ #  # ]:          0 :       for (av = at->nv; av; av = av->n) {
     349                 :          0 :         av->map_val = zxid_map_val(cf, 0, 0, map, at->name, av->val);
     350                 :          0 :         len += name_len + sizeof("=&")-1 + zx_url_encode_len(av->map_val->len,av->map_val->s)-1;
     351                 :            :       }
     352   [ #  #  #  # ]:          0 :       D("len=%d name_len=%d %s", len, name_len, at->name);
     353                 :            :     } else {
     354                 :        153 :       name_len = strlen(at->name);
     355         [ +  + ]:        153 :       len += name_len + sizeof("=&")-1 + (at->val?zx_url_encode_len(strlen(at->val),at->val)-1:0);
     356   [ +  -  +  +  :        153 :       D("len=%d name_len=%d %s (nomap) url_enc_len=%d", len, name_len, at->name, (at->val?zx_url_encode_len(strlen(at->val),at->val)-1:0));
                   -  + ]
     357         [ -  + ]:        153 :       for (av = at->nv; av; av = av->n)
     358         [ #  # ]:          0 :         len += name_len + sizeof("=&")-1 + (av->val?zx_url_encode_len(strlen(av->val),av->val)-1:0);
     359                 :            :     }
     360                 :            :   }
     361                 :            :   
     362                 :            :   /* Attribute rendering pass */
     363                 :            : 
     364                 :            :   DD("HERE %d", 0);
     365                 :            : 
     366                 :          3 :   ss = zx_new_len_str(cf->ctx, len);
     367                 :          3 :   p = ss->s;
     368                 :          3 :   memcpy(p, "dn=QS1&", sizeof("dn=QS1&")-1);
     369                 :          3 :   p += sizeof("dn=QS1&")-1;
     370                 :            :   
     371         [ +  + ]:        156 :   for (at = pool; at; at = at->n) {
     372                 :        153 :     map = zxid_find_map(cf->outmap, at->name);
     373         [ -  + ]:        153 :     if (map) {
     374         [ #  # ]:          0 :       if (map->rule == ZXID_MAP_RULE_DEL)
     375                 :          0 :         continue;
     376   [ #  #  #  #  :          0 :       if (map->dst && *map->dst && map->src && map->src[0] != '*') {
             #  #  #  # ]
     377                 :          0 :         name = map->dst;
     378                 :            :       } else {
     379                 :          0 :         name = at->name;
     380                 :            :       }
     381                 :            :       
     382                 :          0 :       name_len = strlen(name);
     383                 :          0 :       strcpy(p, name);
     384                 :          0 :       p += name_len;
     385                 :          0 :       *p++ = '=';
     386                 :          0 :       p = zx_url_encode_raw(at->map_val->len, at->map_val->s, p);
     387                 :          0 :       *p++ = '&';
     388                 :            :       
     389         [ #  # ]:          0 :       for (av = at->nv; av; av = av->n) {
     390                 :          0 :         strcpy(p, name);
     391                 :          0 :         p += name_len;
     392                 :          0 :         *p++ = '=';
     393                 :          0 :         p = zx_url_encode_raw(av->map_val->len, av->map_val->s, p);
     394                 :          0 :         *p++ = '&';
     395                 :            :       }
     396                 :            :     } else {
     397                 :        153 :       name_len = strlen(at->name);
     398                 :        153 :       strcpy(p, at->name);
     399                 :        153 :       p += name_len;
     400                 :        153 :       *p++ = '=';
     401         [ +  + ]:        153 :       if (at->val)
     402                 :        135 :         p = zx_url_encode_raw(strlen(at->val), at->val, p);
     403                 :        153 :       *p++ = '&';
     404                 :            :       
     405         [ -  + ]:        153 :       for (av = at->nv; av; av = av->n) {
     406                 :          0 :         strcpy(p, at->name);
     407                 :          0 :         p += name_len;
     408                 :          0 :         *p++ = '=';
     409         [ #  # ]:          0 :         if (at->val)
     410                 :          0 :           p = zx_url_encode_raw(strlen(av->val), av->val, p);
     411                 :          0 :         *p++ = '&';
     412                 :            :       }
     413                 :            :     }
     414                 :            :   }
     415   [ +  -  -  + ]:          3 :   D("p=%p == %p ss=%p len=%d", p, ss->s+len, ss->s, len);
     416   [ +  -  -  + ]:          3 :   D("p(%.*s)", len, ss->s);
     417   [ -  +  #  # ]:          3 :   ASSERTOP(p, ==, ss->s+len);
     418                 :          3 :   *p = 0;  /* Zap last & */
     419                 :          3 :   return ss;
     420                 :            : }
     421                 :            : 
     422                 :            : /*() Convert attributes from session to LDIF, applying OUTMAP. */
     423                 :            : 
     424                 :            : /* Called by: */
     425                 :         11 : struct zx_str* zxid_ses_to_ldif(zxid_conf* cf, zxid_ses* ses) {
     426         [ +  - ]:         11 :   return zxid_pool_to_ldif(cf, ses?ses->at:0);
     427                 :            : }
     428                 :            : 
     429                 :            : /*() Convert attributes from session to JSON, applying OUTMAP. */
     430                 :            : 
     431                 :            : /* Called by:  zxid_simple_ab_pep */
     432                 :          0 : struct zx_str* zxid_ses_to_json(zxid_conf* cf, zxid_ses* ses) {
     433         [ #  # ]:          0 :   return zxid_pool_to_json(cf, ses?ses->at:0);
     434                 :            : }
     435                 :            : 
     436                 :            : /*() Convert attributes from session to query string, applying OUTMAP. */
     437                 :            : 
     438                 :            : /* Called by:  zxid_simple_ab_pep */
     439                 :          3 : struct zx_str* zxid_ses_to_qs(zxid_conf* cf, zxid_ses* ses) {
     440         [ +  - ]:          3 :   return zxid_pool_to_qs(cf, ses?ses->at:0);
     441                 :            : }
     442                 :            : 
     443                 :            : /*() Add values, applying NEED, WANT, and INMAP */
     444                 :            : 
     445                 :            : /* Called by:  zxid_add_a7n_at_to_pool x2 */
     446                 :            : static int zxid_add_at_values(zxid_conf* cf, zxid_ses* ses, struct zx_sa_Attribute_s* at, char* name, struct zx_str* issuer)
     447                 :       1386 : {
     448                 :            :   struct zx_str* ss;
     449                 :            :   struct zxid_map* map;
     450                 :            :   struct zx_sa_AttributeValue_s* av;
     451                 :            :   
     452                 :            :   /* Attribute must be needed or wanted */
     453                 :            : 
     454   [ +  -  -  + ]:       1386 :   if (!zxid_is_needed(cf->need, name) && !zxid_is_needed(cf->want, name)) {
     455   [ #  #  #  # ]:          0 :     D("attribute(%s) neither needed nor wanted", name);
     456                 :          0 :     return 0;
     457                 :            :   }
     458                 :            :   
     459                 :       1386 :   map = zxid_find_map(cf->inmap, name);
     460   [ -  +  #  # ]:       1386 :   if (map && map->rule == ZXID_MAP_RULE_DEL) {
     461   [ #  #  #  # ]:          0 :     D("attribute(%s) filtered out by del rule in INMAP", name);
     462                 :          0 :     return 0;
     463                 :            :   }
     464                 :            :   
     465   [ -  +  #  #  :       1386 :   if (map && map->dst && *map->dst && map->src && map->src[0] != '*') {
          #  #  #  #  #  
                      # ]
     466                 :          0 :     ses->at = zxid_new_at(cf, ses->at, strlen(map->dst), map->dst, 0, 0, "mapped");
     467                 :            :   } else {
     468                 :       1386 :     ses->at = zxid_new_at(cf, ses->at, strlen(name), name, 0, 0, "as is");
     469                 :            :   }
     470                 :       1386 :   ses->at->orig = at;
     471                 :       1386 :   ses->at->issuer = issuer;
     472                 :            :   
     473                 :       1386 :   for (av = at->AttributeValue;
     474   [ +  +  +  - ]:       4158 :        av && av->gg.g.tok == zx_sa_AttributeValue_ELEM;
     475                 :       1386 :        av = (struct zx_sa_AttributeValue_s*)ZX_NEXT(av)) {
     476   [ +  -  +  -  :       1386 :     D("Adding value: %p", ZX_GET_CONTENT(av));
          +  +  +  +  -  
                      + ]
     477   [ +  +  +  - ]:       1386 :     if (av->EndpointReference || av->ResourceOffering)
     478                 :            :       continue;  /* Skip bootstraps. They are handled elsewhere, see zxid_snarf_eprs_from_ses(). */
     479   [ +  -  +  +  :       1302 :     if (ZX_GET_CONTENT(av)) {
                   +  + ]
     480   [ +  -  +  -  :       1062 :       ss = zxid_map_val_ss(cf, ses, 0, map, ses->at->name, ZX_GET_CONTENT(av));
                   +  - ]
     481         [ -  + ]:       1062 :       if (ses->at->val) {
     482   [ #  #  #  # ]:          0 :         D("map val(%.*s)", ss->len, ss->s);
     483                 :          0 :         ses->at->nv = zxid_new_at(cf, ses->at->nv, 0, 0, ss->len, ss->s, "multival");
     484                 :            :       } else {
     485   [ +  -  -  + ]:       1062 :         D("copy val(%.*s)", ss->len, ss->s);
     486                 :       1062 :         COPYVAL(ses->at->val, ss->s, ss->s+ss->len);
     487                 :            :       }
     488                 :            :     }
     489                 :            :   }
     490                 :            :   // *** check that value is not null, add empty string
     491                 :       1386 :   return 1;
     492                 :            : }
     493                 :            : 
     494                 :            : /*() Add Attribute Statements of an Assertion to pool, applying NEED, WANT, and INMAP */
     495                 :            : 
     496                 :            : /* Called by:  zxid_ses_to_pool */
     497                 :            : static void zxid_add_a7n_at_to_pool(zxid_conf* cf, zxid_ses* ses, zxid_a7n* a7n)
     498                 :         87 : {
     499                 :            :   struct zx_sa_Attribute_s* at;
     500                 :            :   struct zx_sa_AttributeStatement_s* as;
     501         [ +  + ]:         87 :   if (!a7n)
     502                 :         26 :     return;
     503                 :            :   
     504                 :         61 :   for (as = a7n->AttributeStatement;
     505   [ +  +  +  - ]:        183 :        as && as->gg.g.tok == zx_sa_AttributeStatement_ELEM;
     506                 :         61 :        as = (struct zx_sa_AttributeStatement_s*)ZX_NEXT(as)) {
     507                 :         61 :     for (at = as->Attribute;
     508   [ +  +  +  - ]:       1508 :          at && at->gg.g.tok == zx_sa_Attribute_ELEM;
     509                 :       1386 :          at = (struct zx_sa_Attribute_s*)ZX_NEXT(at)) {      
     510         [ +  - ]:       1386 :       if (at->Name)
     511   [ +  -  +  -  :       1386 :         zxid_add_at_values(cf, ses, at, zx_str_to_c(cf->ctx, &at->Name->g), ZX_GET_CONTENT(a7n->Issuer));
                   +  - ]
     512         [ -  + ]:       1386 :       if (at->FriendlyName)
     513   [ #  #  #  #  :          0 :         zxid_add_at_values(cf, ses, at, zx_str_to_c(cf->ctx, &at->FriendlyName->g), ZX_GET_CONTENT(a7n->Issuer));
                   #  # ]
     514                 :            :     }
     515                 :            :   }
     516                 :            : }
     517                 :            : 
     518                 :            : /*() Add simple attribute to pool, applying NEED, WANT, and INMAP */
     519                 :            : 
     520                 :            : /* Called by:  zxid_add_ldif_at2ses, zxid_add_qs_to_ses, zxid_ses_to_pool x25 */
     521                 :            : void zxid_add_attr_to_ses(zxid_conf* cf, zxid_ses* ses, char* at_name, struct zx_str* val)
     522                 :       2257 : {
     523                 :            :   struct zxid_map* map;
     524         [ +  + ]:       2257 :   if (!val)
     525                 :        222 :     val = zx_dup_str(cf->ctx, "-");
     526                 :            : 
     527   [ +  +  +  - ]:       4514 :   if (zxid_is_needed(cf->need, at_name) || zxid_is_needed(cf->want, at_name)) {
     528                 :       2257 :     map = zxid_find_map(cf->inmap, at_name);
     529   [ -  +  #  # ]:       2257 :     if (map && map->rule == ZXID_MAP_RULE_DEL) {
     530   [ #  #  #  # ]:          0 :       D("attribute(%s) filtered out by del rule in INMAP", at_name);
     531                 :            :     } else {
     532   [ -  +  #  #  :       2257 :       if (map && map->dst && *map->dst && map->src && map->src[0] != '*') {
          #  #  #  #  #  
                      # ]
     533                 :          0 :         ses->at = zxid_new_at(cf, ses->at, strlen(map->dst), map->dst, val->len, val->s, "mapd2");
     534                 :            :       } else {
     535                 :       2257 :         ses->at = zxid_new_at(cf, ses->at, strlen(at_name), at_name, val->len, val->s, "as is2");
     536                 :            :       }
     537                 :            :     }
     538                 :            :   } else {
     539   [ #  #  #  # ]:          0 :     D("attribute(%s) neither needed nor wanted", at_name);
     540                 :            :   }
     541                 :       2257 : }
     542                 :            : 
     543                 :            : /*() Parse LDIF format and insert attributes to linked list. Return new head of the list.
     544                 :            :  * *** illegal input causes corrupt pointer. For example query string input causes corruption. */
     545                 :            : 
     546                 :            : /* Called by:  zxid_ses_to_pool x3 */
     547                 :            : static void zxid_add_ldif_at2ses(zxid_conf* cf, zxid_ses* ses, const char* prefix, char* p, char* lk)
     548                 :         67 : {
     549                 :            :   char* name;
     550                 :            :   char* val;
     551                 :            :   char* nbuf;
     552                 :            :   char name_buf[ZXID_MAX_USER];
     553                 :            :   int len;
     554         [ -  + ]:         67 :   if (prefix) {
     555                 :          0 :     strncpy(name_buf, prefix, sizeof(name_buf)-1);
     556         [ #  # ]:          0 :     nbuf = name_buf + MIN(strlen(prefix), sizeof(name_buf)-1);
     557                 :            :   } else
     558                 :         67 :     nbuf = name_buf;  
     559                 :            : 
     560         [ +  - ]:        268 :   for (; p; ++p) {
     561                 :        268 :     name = p;
     562                 :        268 :     p = strstr(p, ": ");
     563         [ +  + ]:        268 :     if (!p)
     564                 :         67 :       break;
     565                 :        201 :     len = MIN(p-name, sizeof(name_buf)-(nbuf-name_buf)-1);
     566                 :        201 :     memcpy(nbuf, name, len);
     567                 :        201 :     nbuf[len]=0;
     568                 :            : 
     569                 :        201 :     val = p+2;
     570                 :        201 :     p = strchr(val, '\n');  /* *** parsing LDIF is fragile if values are multiline */
     571         [ +  - ]:        201 :     len = p?(p-val):strlen(val);
     572   [ +  +  -  + ]:        201 :     D("%s: ATTR(%s)=VAL(%.*s)", lk, name_buf, len, val);
     573                 :        201 :     zxid_add_attr_to_ses(cf, ses, name_buf,  zx_dup_len_str(cf->ctx, len, val));
     574                 :            :   }
     575                 :         67 : }
     576                 :            : 
     577                 :            : /*() Copy user's local EPRs to his current session.
     578                 :            :  * This function implements a feature where user can have at
     579                 :            :  * some site some long term EPRs (with long term credential). When SSO
     580                 :            :  * is made, these EPRs are copied to user's session's EPR
     581                 :            :  * cache and thus made available. The persistent user EPRs could
     582                 :            :  * be used to implement stuff like subscriptions.
     583                 :            :  *
     584                 :            :  * The ".all" user's EPRs provide a mechanism to add to all users of
     585                 :            :  * a given SP some EPR. Naturally such EPR can not have per user
     586                 :            :  * or short time credential. This can have security implications.
     587                 :            :  *
     588                 :            :  * cf:: Config object for cf->path, and for memory allocation
     589                 :            :  * ses:: Session object. ses->sid is used to determine desitmation directory.
     590                 :            :  * path:: Path to the user directory (in /var/zxid/user/<sha1_safe_base64(idpnid)>/)
     591                 :            :  */
     592                 :            : 
     593                 :            : /* Called by:  zxid_ses_to_pool x3 */
     594                 :            : static void zxid_cp_usr_eprs2ses(zxid_conf* cf, zxid_ses* ses, struct zx_str* path)
     595                 :        209 : {
     596                 :            :   char bs_dir[ZXID_MAX_BUF];
     597                 :            :   char ses_path[ZXID_MAX_BUF];
     598                 :            :   DIR* dir;
     599                 :            :   struct dirent * de;
     600   [ +  -  +  -  :        209 :   if (!ses->sid || !*ses->sid || !path)
                   -  + ]
     601                 :          0 :     return;  /* No valid session. Nothing to do. */
     602                 :            :   
     603                 :        209 :   snprintf(bs_dir, sizeof(bs_dir), "%.*s/.bs", path->len, path->s);
     604                 :        209 :   bs_dir[sizeof(bs_dir)-1] = 0; /* must terminate manually as on win32 nul is not guaranteed */
     605                 :        209 :   dir = opendir(bs_dir);
     606         [ +  + ]:        209 :   if (!dir) {
     607   [ +  -  -  + ]:        142 :     D("Local bootstrap dir(%s) does not exist", bs_dir);
     608                 :        142 :     return;
     609                 :            :   }
     610         [ +  + ]:        335 :   while (de = readdir(dir)) {
     611   [ -  +  #  # ]:        201 :     if (ONE_OF_2(de->d_name[0], '.', 0))   /* skip . and .. and .foo */
     612                 :            :       continue;
     613                 :            :     
     614                 :          0 :     snprintf(bs_dir, sizeof(bs_dir), "%.*s/.bs/%s", path->len, path->s, de->d_name);
     615                 :          0 :     bs_dir[sizeof(bs_dir)-1] = 0; /* must terminate manually as on win32 nul is not guaranteed */
     616                 :          0 :     snprintf(ses_path, sizeof(ses_path), "%.*s" ZXID_SES_DIR "%s/%s", path->len, path->s, ses->sid, de->d_name);
     617                 :          0 :     ses_path[sizeof(ses_path)-1] = 0; /* must term manually as on win32 nul is not guaranteed */
     618                 :          0 :     copy_file(bs_dir, ses_path, "EPRS2ses", 1);
     619                 :            :   }
     620                 :         67 :   closedir(dir);
     621                 :            : }
     622                 :            : 
     623                 :            : /*(i) Process attributes from the AttributeStatements of the session
     624                 :            :  * SSO Assertion and insert them to the pool. NEED, WANT, and INMAP
     625                 :            :  * are applied. The pool is suitable for use by PEP or eventually
     626                 :            :  * rendering to LDIF (or JSON). This function also implements
     627                 :            :  * local attribute authority. */
     628                 :            : 
     629                 :            : /* Called by:  zxid_as_call_ses, zxid_fetch_ses, zxid_simple_ab_pep, zxid_wsc_valid_re_env, zxid_wsp_validate_env */
     630                 :            : void zxid_ses_to_pool(zxid_conf* cf, zxid_ses* ses)
     631                 :         87 : {
     632                 :            :   char* src;
     633                 :            :   char* dst;
     634                 :            :   char* lim;
     635                 :         87 :   struct zx_str* issuer = 0;
     636                 :            :   struct zx_str* affid;
     637                 :            :   struct zx_str* nid;
     638                 :         87 :   struct zx_str* tgtissuer = 0;
     639                 :            :   struct zx_str* tgtaffid;
     640                 :            :   struct zx_str* tgtnid;
     641                 :            :   struct zx_str* accr;
     642                 :            :   struct zx_str* path;
     643                 :            :   struct zx_sa_AuthnStatement_s* as;
     644                 :            :   struct zx_sa_Assertion_s* a7n;
     645                 :            :   struct zx_sa_Assertion_s* tgta7n;
     646                 :            :   char* buf;
     647                 :            :   char sha1_name[28];
     648                 :            : 
     649                 :         87 :   D_INDENT("ses2pool: ");
     650                 :         87 :   zxid_get_ses_sso_a7n(cf, ses);
     651                 :         87 :   a7n = ses->a7n;
     652   [ +  +  -  + ]:         87 :   D("adding a7n %p to pool", a7n);
     653                 :         87 :   zxid_add_a7n_at_to_pool(cf, ses, a7n);
     654                 :            :   
     655                 :            :   /* Format some pseudo attributes that describe the SSO */
     656                 :            : 
     657         [ +  + ]:         87 :   if (a7n) {
     658                 :         61 :     zxid_add_attr_to_ses(cf, ses, "ssoa7n", zx_easy_enc_elem_opt(cf, &a7n->gg));
     659   [ +  -  +  -  :         61 :     issuer = ZX_GET_CONTENT(a7n->Issuer);
                   +  - ]
     660                 :            :   }
     661                 :         87 :   zxid_add_attr_to_ses(cf, ses, "issuer", issuer);
     662         [ +  + ]:         87 :   zxid_add_attr_to_ses(cf, ses, "ssoa7npath",zx_dup_str(cf->ctx, STRNULLCHK(ses->sso_a7n_path)));
     663                 :            :   
     664   [ +  +  +  - ]:         87 :   affid = ses->nameid&&ses->nameid->NameQualifier?&ses->nameid->NameQualifier->g:0;
     665   [ +  +  +  -  :         87 :   nid = ZX_GET_CONTENT(ses->nameid);
                   +  - ]
     666                 :         87 :   zxid_add_attr_to_ses(cf, ses, "affid",  affid);
     667                 :         87 :   zxid_add_attr_to_ses(cf, ses, "idpnid", nid);
     668         [ +  + ]:         87 :   zxid_add_attr_to_ses(cf, ses, "nidfmt", zx_dup_str(cf->ctx, ses->nidfmt?"P":"T"));
     669         [ +  + ]:         87 :   if (nid) {  
     670                 :         61 :     zxid_user_sha1_name(cf, affid, nid, sha1_name);
     671                 :         61 :     path = zx_strf(cf->ctx, "%s" ZXID_USER_DIR "%s", cf->path, sha1_name);
     672                 :         61 :     zxid_add_attr_to_ses(cf, ses, "localpath",   path);
     673                 :         61 :     buf = read_all_alloc(cf->ctx, "splocal_user_at", 0, 0, "%.*s/.bs/.at", path->len, path->s);
     674         [ -  + ]:         61 :     if (buf) {
     675                 :          0 :       zxid_add_ldif_at2ses(cf, ses, "local_", buf, "splocal_user_at");
     676                 :          0 :       ZX_FREE(cf->ctx, buf);
     677                 :            :     }
     678                 :         61 :     zxid_cp_usr_eprs2ses(cf, ses, path);
     679                 :            :   }
     680                 :            : 
     681                 :            :   /* Format pseudo attrs that describe the target, defaulting to the SSO identity. */
     682                 :            :   
     683         [ +  + ]:         87 :   if (ses->tgta7n)
     684                 :         37 :     tgta7n = ses->tgta7n;
     685                 :            :   else
     686                 :         50 :     tgta7n = a7n;
     687         [ +  + ]:         87 :   if (tgta7n) {
     688                 :         61 :     zxid_add_attr_to_ses(cf, ses, "tgta7n", zx_easy_enc_elem_opt(cf, &a7n->gg));
     689   [ +  -  +  -  :         61 :     tgtissuer = ZX_GET_CONTENT(tgta7n->Issuer);
                   +  - ]
     690                 :            :   }
     691         [ +  + ]:         87 :   if (tgtissuer)
     692                 :         61 :     zxid_add_attr_to_ses(cf, ses, "tgtissuer", tgtissuer);
     693         [ +  + ]:         87 :   zxid_add_attr_to_ses(cf, ses, "tgta7npath",zx_dup_str(cf->ctx, STRNULLCHK(ses->tgt_a7n_path)));
     694                 :            : 
     695   [ +  +  +  - ]:         87 :   tgtaffid = ses->tgtnameid&&ses->tgtnameid->NameQualifier?&ses->tgtnameid->NameQualifier->g:0;
     696   [ +  +  +  -  :         87 :   tgtnid = ZX_GET_CONTENT(ses->tgtnameid);
                   +  - ]
     697         [ +  + ]:         87 :   if (!tgtissuer) tgtissuer = issuer;  /* Default: requestor is the target */
     698         [ +  + ]:         87 :   if (!tgtaffid)  tgtaffid = affid;
     699         [ +  + ]:         87 :   if (!tgtnid)    tgtnid = nid;
     700                 :         87 :   zxid_add_attr_to_ses(cf, ses, "tgtaffid",  tgtaffid);
     701                 :         87 :   zxid_add_attr_to_ses(cf, ses, "tgtnid",    tgtnid);
     702         [ +  + ]:         87 :   zxid_add_attr_to_ses(cf, ses, "tgtfmt",    zx_dup_str(cf->ctx, ses->tgtfmt?"P":"T"));
     703         [ +  + ]:         87 :   if (tgtnid) {
     704                 :         61 :     zxid_user_sha1_name(cf, tgtaffid, tgtnid, sha1_name);
     705                 :         61 :     path = zx_strf(cf->ctx, "%s" ZXID_USER_DIR "%s", cf->path, sha1_name);
     706                 :         61 :     zxid_add_attr_to_ses(cf, ses, "tgtpath",   path);
     707                 :         61 :     buf = read_all_alloc(cf->ctx, "sptgt_user_at", 0, 0, "%.*s/.bs/.at", path->len, path->s);
     708         [ -  + ]:         61 :     if (buf) {
     709                 :          0 :       zxid_add_ldif_at2ses(cf, ses, "tgt_", buf, "sptgt_user_at");
     710                 :          0 :       ZX_FREE(cf->ctx, buf);
     711                 :            :     }
     712                 :         61 :     zxid_cp_usr_eprs2ses(cf, ses, path);
     713                 :            :   }
     714                 :            :   
     715   [ +  +  +  -  :         87 :   accr = a7n&&(as = a7n->AuthnStatement)&&as->AuthnContext?ZX_GET_CONTENT(as->AuthnContext->AuthnContextClassRef):0;
          +  -  +  +  +  
                -  +  - ]
     716                 :            :   //accr = a7n&&a7n->AuthnStatement&&a7n->AuthnStatement->AuthnContext&&a7n->AuthnStatement->AuthnContext->AuthnContextClassRef&&a7n->AuthnStatement->AuthnContext->AuthnContextClassRef->content&&a7n->AuthnStatement->AuthnContext->AuthnContextClassRef->content?a7n->AuthnStatement->AuthnContext->AuthnContextClassRef->content:0;
     717                 :         87 :   zxid_add_attr_to_ses(cf, ses, "authnctxlevel", accr);
     718                 :            :   
     719                 :         87 :   buf = read_all_alloc(cf->ctx, "splocal.all", 0, 0, "%s" ZXID_USER_DIR ".all/.bs/.at" , cf->path);
     720         [ +  + ]:         87 :   if (buf) {
     721                 :         67 :     zxid_add_ldif_at2ses(cf, ses, 0, buf, "splocal.all");
     722                 :         67 :     ZX_FREE(cf->ctx, buf);
     723                 :            :   }
     724                 :         87 :   path = zx_strf(cf->ctx, "%s" ZXID_USER_DIR ".all", cf->path);
     725                 :         87 :   zxid_cp_usr_eprs2ses(cf, ses, path);
     726                 :            :   
     727                 :         87 :   zxid_add_attr_to_ses(cf, ses, "eid",        zxid_my_ent_id(cf));
     728                 :         87 :   zxid_add_attr_to_ses(cf, ses, "sigres",     zx_strf(cf->ctx, "%x", ses->sigres));
     729                 :         87 :   zxid_add_attr_to_ses(cf, ses, "ssores",     zx_strf(cf->ctx, "%x", ses->ssores));
     730   [ +  -  +  - ]:         87 :   if (ses->sid && *ses->sid) {
     731         [ +  - ]:         87 :     zxid_add_attr_to_ses(cf, ses, "sesid",    zx_dup_str(cf->ctx, STRNULLCHK(ses->sid)));
     732         [ +  - ]:         87 :     zxid_add_attr_to_ses(cf, ses, "sespath",  zx_strf(cf->ctx, "%s" ZXID_SES_DIR "%s", cf->path, STRNULLCHK(ses->sid)));
     733                 :            :   }
     734         [ +  + ]:         87 :   zxid_add_attr_to_ses(cf, ses, "sesix",      zx_dup_str(cf->ctx, STRNULLCHK(ses->sesix)));
     735         [ +  + ]:         87 :   zxid_add_attr_to_ses(cf, ses, "setcookie",  zx_dup_str(cf->ctx, STRNULLCHK(ses->setcookie)));
     736         [ +  + ]:         87 :   zxid_add_attr_to_ses(cf, ses, "cookie",     zx_dup_str(cf->ctx, STRNULLCHK(ses->cookie)));
     737                 :         87 :   zxid_add_attr_to_ses(cf, ses, "msgid",      ses->wsp_msgid);
     738                 :            : 
     739         [ +  + ]:         87 :   zxid_add_attr_to_ses(cf, ses, "rs",         zx_dup_str(cf->ctx, STRNULLCHK(ses->rs)));
     740                 :         87 :   src = dst = ses->at->val;
     741                 :         87 :   lim = ses->at->val + strlen(ses->at->val);
     742   [ +  +  +  -  :         87 :   URL_DECODE(dst, src, lim);
          +  -  -  +  #  
          #  #  #  #  #  
          #  #  +  -  +  
          -  +  -  -  +  
          #  #  #  #  +  
          -  +  -  +  -  
          -  +  -  +  +  
                      + ]
     743                 :         87 :   *dst = 0;
     744   [ +  +  -  + ]:         87 :   D("RelayState(%s)", ses->at->val);
     745                 :         87 :   D_DEDENT("ses2pool: ");
     746                 :         87 : }
     747                 :            : 
     748                 :            : /*(i) Add Attributes from Querty String to Session attribute pool
     749                 :            :  * The qs argument is parsed according to the CGI Query String rules
     750                 :            :  * and the attributes are added to the session. If apply_map is 1, the
     751                 :            :  * INMAP configuration is applied. While this may seem a hassle, it
     752                 :            :  * allows for specification of the values as safe_base64, etc. If values
     753                 :            :  * are to be added verbatim, just specify 0 (all other values reserved).
     754                 :            :  * The input argument qs gets modified in-situ due to URL decoding and
     755                 :            :  * nul termination. Make sure to duplicate any string constant before calling.
     756                 :            :  * Returns 1 on success, 0 on failure (return value often not checked). */
     757                 :            : 
     758                 :            : /* Called by:  zxid_az_base_cf_ses, zxid_az_cf_ses */
     759                 :            : int zxid_add_qs_to_ses(zxid_conf* cf, zxid_ses* ses, char* qs, int apply_map)
     760                 :         12 : {
     761                 :            :   char *p, *n, *v, *val, *name;
     762   [ +  -  -  + ]:         12 :   if (!qs || !ses)
     763                 :          0 :     return 0;
     764                 :            : 
     765   [ +  +  -  + ]:         12 :   D("qs(%s) len=%d", qs, strlen(qs));
     766   [ +  -  +  + ]:         35 :   while (qs && *qs) {
     767         [ -  + ]:         11 :     for (; *qs == '&'; ++qs) ;    /* Skip over & or && */
     768         [ +  - ]:         11 :     if (!*qs) break;
     769                 :            :     
     770                 :         11 :     qs = strchr(name = qs, '=');  /* Scan name (until '=') */
     771         [ +  - ]:         11 :     if (!qs) break;
     772         [ -  + ]:         11 :     if (qs == name) {             /* Key was an empty string: skip it */
     773                 :          0 :       qs = strchr(qs, '&');       /* Scan value (until '&') *** or '?' */
     774                 :          0 :       continue;
     775                 :            :     }
     776   [ +  -  -  + ]:         11 :     for (; name < qs && *name <= ' '; ++name) ; /* Skip over initial whitespace before name */
     777                 :         11 :     n = p = name;
     778   [ -  +  #  #  :         11 :     URL_DECODE(p, name, qs);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  -  +  +  
                      + ]
     779                 :         11 :     *p = 0;                                     /* Nul-term n (name) */
     780                 :            :     
     781   [ +  +  +  - ]:         11 :     for (val = ++qs; *qs && *qs != '&'; ++qs) ; /* Skip over = and scan value till '&' */
     782                 :         11 :     v = p = val;
     783   [ -  +  #  #  :         11 :     URL_DECODE(p, val, qs);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  -  +  +  
                      + ]
     784                 :            : 
     785         [ -  + ]:         11 :     if (*qs)
     786                 :          0 :       ++qs;
     787                 :         11 :     *p = 0;                                     /* Nul-term v (value) */
     788                 :            : 
     789         [ +  - ]:         11 :     if (apply_map) {
     790   [ +  -  -  + ]:         11 :       D("map %s=%s", n,v);
     791                 :         11 :       zxid_add_attr_to_ses(cf, ses, n, zx_dup_str(cf->ctx, v));  
     792                 :            :     } else {
     793   [ #  #  #  # ]:          0 :       D("asis %s=%s", n,v);
     794                 :          0 :       ses->at = zxid_new_at(cf, ses->at, v-n-1, n, p-v, v, "as is");
     795                 :            :     }
     796                 :            :   }
     797                 :         12 :   return 1;
     798                 :            : }
     799                 :            : 
     800                 :            : /*(i) Given session object (see zxid_simple_cf_ses() or zxid_fetch_ses()),
     801                 :            :  * return n'th value (ix=0 is first) of given attribute, if any, from the
     802                 :            :  * session common attribute pool. If apply_map is 0, the value is returned
     803                 :            :  * as is. If it is 1 then OUTMAP is applied (the
     804                 :            :  * attribute name is in the internal namespace). Other apply_map values
     805                 :            :  * are reserved. */
     806                 :            : 
     807                 :            : /* Called by: */
     808                 :            : struct zx_str* zxid_get_at(zxid_conf* cf, zxid_ses* ses, char* atname, int ix, int apply_map)
     809                 :          0 : {
     810                 :            :   struct zxid_attr* at;
     811                 :            :   struct zxid_attr* av;
     812   [ #  #  #  #  :          0 :   if (!cf || !ses || !atname) {
                   #  # ]
     813                 :          0 :     ERR("Missing args cf=%p ses=%p atname=%p", cf, ses, atname);
     814                 :          0 :     return 0;
     815                 :            :   }
     816         [ #  # ]:          0 :   for (at = ses->at; at; at = at->n) {
     817         [ #  # ]:          0 :     if (!strcmp(at->name, atname)) {
     818   [ #  #  #  # ]:          0 :       for (av = at; av && ix; --ix, av = av->nv) ;
     819         [ #  # ]:          0 :       if (av) {
     820         [ #  # ]:          0 :         if (apply_map) {
     821                 :          0 :           return zx_dup_str(cf->ctx, at->val); /* *** */
     822                 :            :         } else
     823                 :          0 :           return zx_dup_str(cf->ctx, at->val);
     824                 :            :       }
     825                 :            :     }
     826                 :            :   }
     827                 :          0 :   return 0;
     828                 :            : }
     829                 :            : 
     830                 :            : /* EOF  --  zxidpool.c */

Generated by: LCOV version 1.9