LCOV - code coverage report
Current view: top level - zxid - zxidhrxmlwsp.c (source / functions) Hit Total Coverage
Test: ZXID Code Coverage Lines: 103 149 69.1 %
Date: 2010-12-19 Functions: 1 1 100.0 %
Branches: 62 104 59.6 %

           Branch data     Line data    Source code
       1                 :            : /* zxidhrxmlwsp.c  -  ID-SIS HR-XML WSP
       2                 :            :  * Copyright (c) 2007-2009 Symlabs (symlabs@symlabs.com), All Rights Reserved.
       3                 :            :  * Author: Sampo Kellomaki (sampo@iki.fi)
       4                 :            :  * This is confidential unpublished proprietary source code of the author.
       5                 :            :  * NO WARRANTY, not even implied warranties. Contains trade secrets.
       6                 :            :  * Distribution prohibited unless authorized in writing.
       7                 :            :  * Licensed under Apache License 2.0, see file COPYING.
       8                 :            :  * $Id: zxidhrxmlwsp.c,v 1.14 2009-11-29 12:23:06 sampo Exp $
       9                 :            :  *
      10                 :            :  * 19.6.2007, created --Sampo
      11                 :            :  *
      12                 :            :  * See also: http://hoohoo.ncsa.uiuc.edu/cgi/interface.html (CGI specification)
      13                 :            :  *           README-zxid, section 10 "zxid_simple() API"
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "platform.h"
      17                 :            : 
      18                 :            : #include <string.h>
      19                 :            : #include <stdio.h>
      20                 :            : #include <stdlib.h>
      21                 :            : 
      22                 :            : #include <sys/types.h>
      23                 :            : #include <sys/stat.h>
      24                 :            : #include <fcntl.h>
      25                 :            : 
      26                 :            : #include <zx/errmac.h>
      27                 :            : #include <zx/zxid.h>      /* ZXID main API, including zxid_simple(). */
      28                 :            : #include <zx/zxidutil.h>
      29                 :            : #include <zx/zxidconf.h>  /* Default and compile-time configuration options. */
      30                 :            : #include <zx/wsf.h>
      31                 :            : #include <zx/c/zxidvers.h>
      32                 :            : #include <zx/c/zx-ns.h>
      33                 :            : #include <zx/c/zx-data.h>
      34                 :            : 
      35                 :            : char* help =
      36                 :            : "zxidhrxmlwsp  -  SAML 2.0 WSP CGI - R" ZXID_REL "\n\
      37                 :            : SAML 2.0 is a standard for federated identity and Single Sign-On.\n\
      38                 :            : Copyright (c) 2007-2009 Symlabs (symlabs@symlabs.com), All Rights Reserved.\n\
      39                 :            : Author: Sampo Kellomaki (sampo@iki.fi)\n\
      40                 :            : NO WARRANTY, not even implied warranties. Licensed under Apache License v2.0\n\
      41                 :            : See http://www.apache.org/licenses/LICENSE-2.0\n\
      42                 :            : Send well-researched bug reports to the author. Home: zxid.org\n\
      43                 :            : \n\
      44                 :            : Usage: zxidhrxmlwsp [options]   (when used as CGI, no options can be supplied)\n\
      45                 :            :   -h               This help message\n\
      46                 :            :   --               End of options\n";
      47                 :            : 
      48                 :            : /* ============== M A I N ============== */
      49                 :            : 
      50                 :            : #define ZXIDHLO "zxidhrxmlwsp"
      51                 :            : #define CONF "PATH=/var/zxid/"
      52                 :            : 
      53                 :            : /* Called by: */
      54                 :            : int main(int argc, char** argv)
      55                 :          9 : {
      56                 :            :   struct zx_ctx ctx;
      57                 :            :   zxid_conf cfs;
      58                 :            :   zxid_conf* cf;
      59                 :            :   zxid_ses sess;
      60                 :          9 :   zxid_ses* ses = &sess;
      61                 :            :   struct zx_root_s* r;
      62                 :            :   //struct zx_e_Envelope_s* env;
      63                 :            :   //zxid_epr* epr;
      64                 :            :   struct zx_str* ss;
      65                 :            :   //char* sid;
      66                 :            :   char* nid;
      67                 :            :   char* p;
      68                 :            :   char* res;
      69                 :            :   char buf[256*1024];  /* *** should figure the size dynamically */
      70                 :            :   char urlbuf[256];
      71                 :          9 :   int got, fd, cl=0;
      72                 :            :   char* qs;
      73                 :            :   char* qs2;
      74                 :          9 :   ZERO(ses, sizeof(zxid_ses));
      75                 :            :   
      76                 :            : #if 1
      77                 :            :   /* Helps debugging CGI scripts if you see stderr. */
      78                 :          9 :   close(2);
      79         [ -  + ]:          9 :   if (open("/var/tmp/zxid.stderr", O_WRONLY | O_CREAT | O_APPEND, 0666) != 2)
      80                 :          0 :     exit(2);
      81                 :          9 :   fprintf(stderr, "=================== Running idhrxml wsp ===================\n");
      82                 :          9 :   zx_debug = 2;
      83                 :            : #endif
      84                 :            : #if 1
      85                 :          9 :   strncpy(zx_instance, "\t\e[45mhrxml_wsp\e[0m", sizeof(zx_instance));
      86                 :            : #else
      87                 :            :   strncpy(zx_instance, "\thrxml_wsp", sizeof(zx_instance));
      88                 :            : #endif
      89                 :            : 
      90                 :          9 :   qs = getenv("CONTENT_LENGTH");
      91         [ +  + ]:          9 :   if (qs)
      92                 :          7 :     sscanf(qs, "%d", &cl);
      93                 :            : 
      94         [ +  + ]:          9 :   if (cl) {
      95                 :          7 :     read_all_fd(0, buf, MIN(cl, sizeof(buf)-1), &got);
      96                 :          7 :     buf[got] = 0;
      97                 :          7 :     qs2 = buf;
      98                 :            :   } else {
      99                 :          2 :     qs2 = getenv("QUERY_STRING");
     100         [ +  + ]:          2 :     if (!qs2)
     101                 :          1 :       qs2 = "";
     102                 :          2 :     cl = strlen(qs2);
     103                 :            :   }
     104                 :          9 :   qs = strdup(qs2);
     105                 :          9 :   D_XML_BLOB(0, "HRXML IN", -2, qs);
     106                 :            : 
     107         [ +  + ]:          9 :   if (argc > 1) {
     108                 :          1 :     fprintf(stderr, "This is a CGI script (written in C). No arguments are accepted.\n%s", help);
     109                 :          1 :     exit(1);
     110                 :            :   }
     111                 :            : 
     112                 :            : #if 1
     113                 :          8 :   zx_reset_ctx(&ctx);
     114                 :          8 :   ZERO(&cfs, sizeof(cfs));
     115                 :          8 :   cfs.ctx = &ctx;
     116                 :          8 :   cf = &cfs;
     117                 :          8 :   zxid_conf_to_cf_len(cf, -1, CONF);
     118                 :            : #else
     119                 :            :   cf = zxid_new_conf_to_cf(CONF);
     120                 :            : #endif
     121                 :            : 
     122                 :            :   /* Dynamic construction of URL configuration parameter */
     123                 :            : 
     124                 :            : #if 0  
     125                 :            : #define PROTO_STR "https://"
     126                 :            : #else
     127                 :            : #define PROTO_STR "http://"
     128                 :            : #endif
     129                 :            : 
     130                 :          8 :   strcpy(urlbuf, PROTO_STR);
     131                 :          8 :   p = urlbuf + sizeof(PROTO_STR)-1;
     132                 :          8 :   res = getenv("HTTP_HOST");
     133         [ +  + ]:          8 :   if (res) {
     134                 :          7 :     strcpy(p, res);
     135                 :          7 :     p+=strlen(res);
     136                 :            :   }
     137                 :          8 :   res = getenv("SCRIPT_NAME");
     138         [ +  + ]:          8 :   if (res) {
     139                 :          7 :     strcpy(p, res);
     140                 :          7 :     p+=strlen(res);
     141                 :            :   }
     142         [ -  + ]:          8 :   if (p > urlbuf + sizeof(urlbuf))
     143                 :          0 :     exit(1);
     144                 :          8 :   zxid_url_set(cf, urlbuf);
     145                 :            : 
     146                 :            :   //if (!memcmp(qs+cl-4, "?o=B", 4)) {
     147         [ +  + ]:          8 :   if (!memcmp(qs, "o=B", 3)) {
     148   [ +  -  -  + ]:          1 :     D("Metadata qs(%s)", qs);
     149                 :            :     //cf = zxid_new_conf_to_cf(CONF);
     150                 :            :     
     151                 :          1 :     res = zxid_simple_cf(cf, cl, qs, 0, 0x1fff);
     152         [ #  # ]:          0 :     switch (res[0]) {
     153                 :            :     default:
     154                 :          0 :       ERR("Unknown zxid_simple() response(%s)", res);
     155                 :            :     case 'd': break; /* Logged in case */
     156                 :            :     }
     157                 :          0 :     ERR("Not a metadata qs(%s)",qs);
     158                 :          0 :     exit(1);
     159                 :            :   }
     160                 :            : 
     161                 :          7 :   nid = zxid_wsp_validate(cf, ses, 0, buf);
     162         [ -  + ]:          7 :   if (!nid) {
     163                 :            :     DD("Request validation failed buf(%.*s)", got, buf);
     164                 :          0 :     ERR("Request validation failed len=%d", got);
     165                 :          0 :     ss = zxid_wsp_decorate(cf, ses, 0, "<Response><lu:Status code=\"INV\" comment=\"Request validation failed. Replay?\"></lu:Status></Response>");
     166                 :            :     DD("ss(%.*s)", ss->len, ss->s);
     167                 :          0 :     printf("CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\n\r\n%.*s", ss->len, ss->len, ss->s);
     168                 :          0 :     exit(1);
     169                 :            :   }
     170   [ +  -  -  + ]:          7 :   D("Target nid(%s)", nid);
     171                 :            :     
     172                 :          7 :   r = zx_dec_zx_root(cf->ctx, cl, qs2, "hrxml wsp");
     173                 :            : 
     174                 :            :   DD("Decoded nid(%s)", nid);
     175                 :            :   
     176   [ +  -  -  + ]:          7 :   if (!r || !r->Envelope) {
     177                 :          0 :     ERR("No SOAP Envelope found buf(%.*s)", got, buf);
     178                 :          0 :     exit(1);
     179                 :            :   }
     180         [ -  + ]:          7 :   if (!r->Envelope->Body) {
     181                 :          0 :     ERR("No SOAP Body found buf(%.*s)", got, buf);
     182                 :          0 :     exit(1);
     183                 :            :   }
     184                 :            : 
     185         [ +  + ]:          7 :   if (r->Envelope->Body->idhrxml_Create) {
     186   [ +  -  -  + ]:          1 :     D("Create %d",0);
     187         [ -  + ]:          1 :     if (!r->Envelope->Body->idhrxml_Create->CreateItem) {
     188                 :          0 :       ERR("No CreateItem found buf(%.*s)", got, buf);
     189                 :          0 :       exit(1);
     190                 :            :     }
     191                 :            : 
     192         [ -  + ]:          1 :     if (!r->Envelope->Body->idhrxml_Create->CreateItem->NewData) {
     193                 :          0 :       ERR("No NewData found buf(%.*s)", got, buf);
     194                 :          0 :       exit(1);
     195                 :            :     }
     196                 :            :     
     197         [ -  + ]:          1 :     if (!r->Envelope->Body->idhrxml_Create->CreateItem->NewData->Candidate) {
     198                 :          0 :       ERR("No Candidate found buf(%.*s)", got, buf);
     199                 :            : #if 0
     200                 :            :       env = ZXID_RESP_ENV(cf, "idhrxml:CreateResponse", "Fail", "NewData does not contain Candidate element.");
     201                 :            :       ss = zx_EASY_ENC_SO_e_Envelope(cf->ctx, env);
     202                 :            : #else
     203                 :          0 :       ss = zxid_wsp_decorate(cf, ses, 0, "<idhrxml:CreateResponse><lu:Status code=\"Fail\" comment=\"NewData does not contain Candidate element.\"></lu:Status></idhrxml:CreateResponse>");
     204                 :            : #endif
     205                 :          0 :       printf("CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\n\r\n%.*s", ss->len, ss->len, ss->s);
     206                 :          0 :       return 0;
     207                 :            :     }
     208                 :            :     
     209                 :          1 :     ss = zx_easy_enc_elem_opt(cf, &r->Envelope->Body->idhrxml_Create->CreateItem->NewData->Candidate->gg);
     210                 :            : 
     211                 :          1 :     fd = open_fd_from_path(O_CREAT|O_WRONLY|O_TRUNC, 0666, "create", 1, "%shrxml/cv.xml", cf->path);
     212                 :          1 :     write_all_fd(fd, ss->s, ss->len);
     213                 :          1 :     close_file(fd, (const char*)__FUNCTION__);
     214                 :            : 
     215                 :            : #if 0
     216                 :            :     env = ZXID_RESP_ENV(cf, "idhrxml:CreateResponse", "OK", "Fine");
     217                 :            :     D("HERE(%p)", env);
     218                 :            :     ss = zx_EASY_ENC_SO_e_Envelope(cf->ctx, env);
     219                 :            :     D("HERE(%p)", ss);
     220                 :            : #else
     221                 :          1 :     ss = zxid_wsp_decorate(cf, ses, 0, "<idhrxml:CreateResponse><lu:Status code=\"OK\" comment=\"Fine\"></lu:Status></idhrxml:CreateResponse>");
     222                 :            : #endif
     223                 :          1 :     printf("CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\n\r\n%.*s", ss->len, ss->len, ss->s);
     224   [ +  -  -  + ]:          1 :     D("ss(%.*s)", ss->len, ss->s);
     225                 :          1 :     return 0;
     226                 :            :   }
     227                 :            :   
     228         [ +  + ]:          6 :   if (r->Envelope->Body->idhrxml_Query) {
     229   [ +  -  -  + ]:          1 :     D("Query %d",0);
     230         [ -  + ]:          1 :     if (!r->Envelope->Body->idhrxml_Query->QueryItem) {
     231                 :          0 :       ERR("No QueryItem found buf(%.*s)", got, buf);
     232                 :          0 :       exit(1);
     233                 :            :     }
     234                 :            : 
     235         [ -  + ]:          1 :     if (!r->Envelope->Body->idhrxml_Query->QueryItem->Select) {
     236                 :          0 :       ERR("No Select found buf(%.*s)", got, buf);
     237                 :          0 :       exit(1);
     238                 :            :     }
     239                 :            : 
     240                 :            :     /* *** This mock implementation does not actually interpret the Select string. */
     241                 :            :     
     242                 :            :     /* Parse the XML from the CV file into data structure and include it as Candidate. */
     243                 :            : 
     244                 :          1 :     got = read_all(sizeof(buf), buf, "query", 1, "%shrxml/cv.xml", cf->path);
     245         [ -  + ]:          1 :     if (got < 1) {
     246                 :          0 :       ERR("Reading hrxml/cv.xml resulted in error or the file was empty. ret=%d", got);
     247                 :            : #if 0
     248                 :            :       env = ZXID_RESP_ENV(cf, "idhrxml:QueryResponse", "Fail", "Empty or no data");
     249                 :            :       ss = zx_EASY_ENC_SO_e_Envelope(cf->ctx, env);
     250                 :            : #else
     251                 :          0 :       ss = zxid_wsp_decorate(cf, ses, 0, "<idhrxml:QueryResponse><lu:Status code=\"Fail\" comment=\"Empty or no data\"></lu:Status></idhrxml:QueryResponse>");
     252                 :            : #endif
     253                 :          0 :       printf("CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\n\r\n%.*s", ss->len, ss->len, ss->s);
     254                 :          0 :       return 0;
     255                 :            :     }
     256                 :            :     
     257                 :          1 :     r = zx_dec_zx_root(cf->ctx, got, buf, "hrxml wsp cand");
     258   [ +  -  -  + ]:          1 :     if (!r || !r->Candidate) {
     259                 :          0 :       ERR("No hrxml:Candidate tag found in cv.xml(%s)", buf);
     260                 :            : #if 0
     261                 :            :       env = ZXID_RESP_ENV(cf, "idhrxml:QueryResponse", "Fail", "No Candidate in data");
     262                 :            :       ss = zx_EASY_ENC_SO_e_Envelope(cf->ctx, env);
     263                 :            : #else
     264                 :          0 :       ss = zxid_wsp_decorate(cf, ses, 0, "<idhrxml:QueryResponse><lu:Status code=\"Fail\" comment=\"No Candidate in data.\"></lu:Status></idhrxml:QueryResponse>");
     265                 :            : #endif
     266                 :          0 :       printf("CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\n\r\n%.*s", ss->len, ss->len, ss->s);
     267                 :          0 :       return 0;
     268                 :            :     }
     269                 :            : 
     270                 :            : #if 0
     271                 :            :     env = ZXID_RESP_ENV(cf, "idhrxml:QueryResponse", "OK", "Fine");
     272                 :            :     env->Body->idhrxml_QueryResponse->Data = zx_NEW_idhrxml_Data(cf->ctx,0);
     273                 :            :     env->Body->idhrxml_QueryResponse->Data->Candidate = r->Candidate;
     274                 :            :     ss = zx_EASY_ENC_SO_e_Envelope(cf->ctx, env);
     275                 :            : #else
     276                 :          1 :     ss = zxid_wsp_decoratef(cf, ses, 0, "<idhrxml:QueryResponse><lu:Status code=\"OK\" comment=\"Fine\"></lu:Status><idhrxml:Data><idhrxml:Candidate>%s</idhrxml:Candidate></idhrxml:Data></idhrxml:QueryResponse>", buf);
     277                 :            : #endif
     278                 :          1 :     printf("CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\n\r\n%.*s", ss->len, ss->len, ss->s);
     279                 :          1 :     return 0;
     280                 :            :   }
     281                 :            : 
     282                 :            :   // Modify
     283                 :            : 
     284         [ +  + ]:          5 :   if (r->Envelope->Body->idhrxml_Modify) {
     285   [ +  -  -  + ]:          1 :     D("Modify %d",0);
     286         [ -  + ]:          1 :     if (!r->Envelope->Body->idhrxml_Modify->ModifyItem) {
     287                 :          0 :       ERR("No ModifyItem found buf(%.*s)", got, buf);
     288                 :          0 :       exit(1);
     289                 :            :     }
     290                 :            : 
     291         [ -  + ]:          1 :     if (!r->Envelope->Body->idhrxml_Modify->ModifyItem->Select) {
     292                 :          0 :       ERR("No Select found buf(%.*s)", got, buf);
     293                 :            :       //exit(1);
     294                 :            :     }
     295                 :            : 
     296                 :            :     /* *** This mock implementation does not actually interpret the Select string. */
     297                 :            :     
     298         [ -  + ]:          1 :     if (!r->Envelope->Body->idhrxml_Modify->ModifyItem->NewData) {
     299                 :          0 :       ERR("No NewData found buf(%.*s)", got, buf);
     300                 :          0 :       exit(1);
     301                 :            :     }
     302                 :            :     
     303         [ -  + ]:          1 :     if (!r->Envelope->Body->idhrxml_Modify->ModifyItem->NewData->Candidate) {
     304                 :          0 :       ERR("No Candidate found buf(%.*s)", got, buf);
     305                 :            : #if 0
     306                 :            :       env = ZXID_RESP_ENV(cf, "idhrxml:ModifyResponse", "Fail", "NewData does not contain Candidate element.");
     307                 :            :       ss = zx_EASY_ENC_SO_e_Envelope(cf->ctx, env);
     308                 :            : #else
     309                 :          0 :       ss = zxid_wsp_decorate(cf, ses, 0, "<idhrxml:ModifyResponse><lu:Status code=\"Fail\" comment=\"No Candidate in data.\"></lu:Status></idhrxml:ModifyResponse>");
     310                 :            : #endif
     311                 :          0 :       printf("CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\n\r\n%.*s", ss->len, ss->len, ss->s);
     312                 :          0 :       return 0;
     313                 :            :     }
     314                 :            :     
     315                 :          1 :     ss = zx_easy_enc_elem_opt(cf, &r->Envelope->Body->idhrxml_Modify->ModifyItem->NewData->Candidate->gg);
     316                 :            : 
     317                 :          1 :     fd = open_fd_from_path(O_CREAT|O_WRONLY|O_TRUNC, 0666, "modify", 1, "%shrxml/cv.xml", cf->path);
     318                 :          1 :     write_all_fd(fd, ss->s, ss->len);
     319                 :          1 :     close_file(fd, (const char*)__FUNCTION__);
     320                 :            : 
     321                 :            : #if 0
     322                 :            :     env = ZXID_RESP_ENV(cf, "idhrxml:ModifyResponse", "OK", "Fine");
     323                 :            :     ss = zx_EASY_ENC_SO_e_Envelope(cf->ctx, env);
     324                 :            : #else
     325                 :          1 :     ss = zxid_wsp_decorate(cf, ses, 0, "<idhrxml:ModifyResponse><lu:Status code=\"OK\" comment=\"Fine\"></lu:Status></idhrxml:ModifyResponse>");
     326                 :            : #endif
     327   [ +  -  -  + ]:          1 :     D("ss(%.*s)", ss->len, ss->s);
     328                 :          1 :     printf("CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\n\r\n%.*s", ss->len, ss->len, ss->s);
     329                 :          1 :     return 0;
     330                 :            :   }  
     331                 :            : 
     332                 :            :   // Delete
     333                 :            : 
     334         [ +  + ]:          4 :   if (r->Envelope->Body->idhrxml_Delete) {
     335   [ +  -  -  + ]:          1 :     D("Delete %d",0);
     336         [ -  + ]:          1 :     if (!r->Envelope->Body->idhrxml_Delete->DeleteItem) {
     337                 :          0 :       ERR("No DeleteItem found buf(%.*s)", got, buf);
     338                 :          0 :       exit(1);
     339                 :            :     }
     340                 :            : 
     341         [ -  + ]:          1 :     if (!r->Envelope->Body->idhrxml_Delete->DeleteItem->Select) {
     342                 :          0 :       ERR("No Select found buf(%.*s)", got, buf);
     343                 :            :       //exit(1);
     344                 :            :     }
     345                 :            : 
     346                 :            :     /* *** This mock implementation does not actually interpret the Select string. */
     347                 :            :     
     348                 :          1 :     got = name_from_path(buf, sizeof(buf), "%shrxml/cv.xml", cf->path);
     349                 :          1 :     unlink(buf);
     350                 :            : 
     351                 :            : #if 0
     352                 :            :     env = ZXID_RESP_ENV(cf, "idhrxml:DeleteResponse", "OK", "Fine");
     353                 :            :     ss = zx_EASY_ENC_SO_e_Envelope(cf->ctx, env);
     354                 :            : #else
     355                 :          1 :     ss = zxid_wsp_decorate(cf, ses, 0, "<idhrxml:DeleteResponse><lu:Status code=\"OK\" comment=\"Fine\"></lu:Status></idhrxml:DeleteResponse>");
     356                 :            : #endif
     357   [ +  -  -  + ]:          1 :     D("ss(%.*s)", ss->len, ss->s);
     358                 :          1 :     printf("CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\n\r\n%.*s", ss->len, ss->len, ss->s);
     359                 :          1 :     return 0;
     360                 :            :   }  
     361                 :            : 
     362                 :          3 :   ss = zxid_wsp_decorate(cf, ses, 0, "<Response><lu:Status code=\"BAD\" comment=\"Unknown XML\"></lu:Status></Response>");
     363   [ +  -  -  + ]:          3 :   D("ss(%.*s)", ss->len, ss->s);
     364                 :          3 :   printf("CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\n\r\n%.*s", ss->len, ss->len, ss->s);
     365                 :          3 :   return 0;
     366                 :            : }
     367                 :            : 
     368                 :            : /* EOF  --  zxidhrxmlwsp.c */

Generated by: LCOV version 1.9