Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

lcas_voms.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001 EU DataGrid.                                                                             
00003  * For license conditions see http://www.eu-datagrid.org/license.html                                          
00004  *
00005  * Copyright (c) 2001, 2002 by 
00006  *     Martijn Steenbakkers <martijn@nikhef.nl>,
00007  *     David Groep <davidg@nikhef.nl>,
00008  *     NIKHEF Amsterdam, the Netherlands
00009  */
00010 
00091 /*****************************************************************************
00092                             Include header files
00093 ******************************************************************************/
00094 #include "lcas_config.h"
00095 #include <stdio.h>
00096 #include <stdlib.h>
00097 #include <string.h>
00098 #include <pwd.h>
00099 #include <sys/types.h>
00100 #include <sys/stat.h>
00101 #include <unistd.h>
00102 #include <libgen.h>
00103 #include <openssl/x509.h>
00104 #include <errno.h>
00105 #include "gssapi.h"
00106 
00107 #include "lcas_modules.h"
00108 #include "lcas_voms_utils.h"
00109 #include "lcas_vo_data.h"
00110 #include "lcas_gridlist.h"
00111 
00112 #include "voms_apic.h"
00113 #include "gacl.h"
00114 #include "globus_gss_assist.h"
00115 
00116 #undef TESTBIO
00117 #ifdef TESTBIO
00118 #    include <openssl/pem.h>
00119 #    include <openssl/bio.h>
00120 #endif
00121 
00122 
00123 /******************************************************************************
00124                                 Definitions
00125 ******************************************************************************/
00126 
00127 #define VOMS_BUFFER_SIZE 1024
00128 
00129 /******************************************************************************
00130                                Type definitions
00131 ******************************************************************************/
00137 typedef enum authformat_e
00138 {
00139     NO_FORMAT,     
00140     SIMPLE_FORMAT, 
00141     GACL_FORMAT,   
00142     XACML_FORMAT,  
00143 }
00144 authformat_t;
00145 
00146 typedef enum gacl_use_voms_dn_e
00147 {
00148     ALWAYS_USE_VOMS_DN,  
00149     USE_VOMS_DN,         
00150     DONT_USE_VOMS_DN,    
00151 }
00152 gacl_use_voms_dn_t;
00153 
00154 /******************************************************************************
00155                           Module specific prototypes
00156 ******************************************************************************/
00157 static void print_vomsdata(struct vomsdata *);
00158 static void print_vomsdata(struct vomsdata *);
00159 static int  lcas_check_gacl(GACLuser *, char *);
00160 static int  lcas_gacl_add_dn(GACLuser **, char *);
00161 static int  lcas_gacl_add_vomsdata(GACLuser **, lcas_vo_data_t *, char *);
00162 
00163 #ifdef TESTBIO
00164 static STACK_OF(X509) *load_chain(char *certfile);
00165 static char *retmsg[] = { "VERR_NONE", "VERR_NOSOCKET", "VERR_NOIDENT", "VERR_COMM", 
00166                           "VERR_PARAM", "VERR_NOEXT", "VERR_NOINIT",
00167                           "VERR_TIME", "VERR_IDCHECK", "VERR_EXTRAINFO",
00168                           "VERR_FORMAT", "VERR_NODATA", "VERR_PARSE",
00169                           "VERR_DIR", "VERR_SIGN", "VERR_SERVER", 
00170                           "VERR_MEM", "VERR_VERIFY", "VERR_IDENT",
00171                           "VERR_TYPE", "VERR_ORDER" };
00172 #endif
00173 
00174 /******************************************************************************
00175                        Define module specific variables
00176 ******************************************************************************/
00177 
00178 
00179 static authformat_t authformat       = NO_FORMAT;
00180 static char *       authfile         = NULL;
00181 static char *       certdir          = NULL;
00182 static char *       vomsdir          = NULL;
00183 static char         voms_buffer[VOMS_BUFFER_SIZE];
00184 static authformat_t gacl_use_voms_dn = USE_VOMS_DN;
00185 static int          use_user_dn = 0;
00186 
00187 #ifdef TESTBIO
00188 static STACK_OF(X509) *load_chain(char *certfile)
00189 {
00190     STACK_OF(X509_INFO) *sk=NULL;
00191     STACK_OF(X509) *stack=NULL, *ret=NULL;
00192     BIO *in=NULL;
00193     X509_INFO *xi;
00194     int first = 1;
00195 
00196     if(!(stack = sk_X509_new_null()))
00197     {
00198         printf("%s: memory allocation failure\n", logstr);
00199         goto end;
00200     }
00201 
00202     if(!(in=BIO_new_file(certfile, "r")))
00203     {
00204         printf("%s: error opening the file, %s\n", logstr,certfile);
00205         goto end;
00206     }
00207 
00208     /* This loads from a file, a stack of x509/crl/pkey sets */
00209     if(!(sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL)))
00210     {
00211         printf("%s: error reading the file, %s\n", logstr,certfile);
00212         goto end;
00213     }
00214 
00215     /* scan over it and pull out the certs */
00216     while (sk_X509_INFO_num(sk))
00217     {
00218         /* skip first cert */
00219         if (first)
00220         {
00221             first = 0;
00222             continue;
00223         }
00224         xi=sk_X509_INFO_shift(sk);
00225         if (xi->x509 != NULL)
00226         {
00227             sk_X509_push(stack,xi->x509);
00228             xi->x509=NULL;
00229         }
00230         X509_INFO_free(xi);
00231     }
00232     if(!sk_X509_num(stack))
00233     {
00234         printf("%s: no certificates in file, %s\n", logstr,certfile);
00235         sk_X509_free(stack);
00236         goto end;
00237     }
00238     ret=stack;
00239 end:
00240     BIO_free(in);
00241     sk_X509_INFO_free(sk);
00242     return(ret);
00243 }
00244 #endif
00245 
00246 /******************************************************************************
00247 Function:   plugin_initialize
00248 Description:
00249     Initialize plugin
00250 Parameters:
00251     argc, argv
00252     argv[0]: the name of the plugin
00253 Returns:
00254     LCAS_MOD_SUCCESS : succes
00255     LCAS_MOD_FAIL    : failure
00256     LCAS_MOD_NOFILE  : db file not found (will halt LCAS initialization)
00257 ******************************************************************************/
00258 int plugin_initialize(
00259         int argc,
00260         char ** argv
00261 )
00262 {
00263     struct stat  buf;
00264     char *       logstr = "\tlcas_plugin_voms-plugin_initialize()";
00265     char *       authfilecopy = NULL;
00266     char *       authfilebase = NULL;
00267     int          i;
00268  
00269     lcas_log_debug(1,"%s: passed arguments:\n", logstr);
00270     for (i=0; i < argc; i++)
00271     {
00272        lcas_log_debug(2,"%s: arg %d is %s\n", logstr, i, argv[i]);
00273     }
00274  
00275     /*
00276      * CERTDIR = The directory which contains the CA certificates
00277      * VOMSDIR = The directory which contains the certificates of the VOMS servers 
00278      */
00279  
00280     /*
00281      * Parse arguments, argv[0] = name of plugin, so start with i = 1
00282      */
00283     for (i = 1; i < argc; i++)
00284     {
00285         if ( ((strcmp(argv[i], "-vomsdir") == 0) ||
00286               (strcmp(argv[i], "-VOMSDIR") == 0))
00287              && (i + 1 < argc))
00288         {
00289             if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00290             {
00291                  vomsdir = strdup(argv[i + 1]);
00292             }
00293             i++;
00294         }
00295         else if ( ((strcmp(argv[i], "-certdir") == 0) ||
00296                    (strcmp(argv[i], "-CERTDIR") == 0))
00297                    && (i + 1 < argc))
00298         {
00299             if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00300             {
00301                  certdir = strdup(argv[i + 1]);
00302             }
00303             i++;
00304         }
00305         else if ((strcmp(argv[i], "-authfile") == 0)
00306                    && (i + 1 < argc))
00307         {
00308             if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00309             {
00310                  authfile = strdup(argv[i + 1]);
00311             }
00312             i++;
00313         }
00314         else if ((strcmp(argv[i], "-authformat") == 0)
00315                    && (i + 1 < argc))
00316         {
00317             if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00318             {
00319                  if ( (strcmp(argv[i + 1], "gacl") == 0) || (strcmp(argv[i + 1], "GACL") == 0) )
00320                  {
00321                      authformat = GACL_FORMAT;
00322                  }
00323                  else if ( (strcmp(argv[i + 1], "xacml") == 0) || (strcmp(argv[i + 1], "XACML") == 0) )
00324                  {
00325                      authformat = XACML_FORMAT;
00326                  }
00327                  else if ( (strcmp(argv[i + 1], "simple") == 0) || (strcmp(argv[i + 1], "SIMPLE") == 0) )
00328                  {
00329                      authformat = SIMPLE_FORMAT;
00330                  }
00331                  else
00332                  {
00333                      lcas_log(0,"%s: use  \"simple/SIMPLE\", \"gacl/GACL\" or \"xacml/XACML\" for option %s\n",
00334                                 logstr, argv[i]);
00335                      goto fail_voms_init;
00336                  }
00337             }
00338             i++;
00339         }
00340         else if (strcmp(argv[i], "-use_user_dn") == 0)
00341         {
00342             use_user_dn = 1;
00343         }
00344         else if ((strcmp(argv[i], "-gacl_use_voms_dn") == 0)
00345                    && (i + 1 < argc))
00346         {
00347             if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00348             {
00349                  if ( (strcmp(argv[i + 1], "yes") == 0) || (strcmp(argv[i + 1], "YES") == 0) )
00350                  {
00351                      gacl_use_voms_dn = USE_VOMS_DN;
00352                  }
00353                  else if ( (strcmp(argv[i + 1], "no") == 0) || (strcmp(argv[i + 1], "NO") == 0) )
00354                  {
00355                      gacl_use_voms_dn = DONT_USE_VOMS_DN;
00356                  }
00357                  else if ( (strcmp(argv[i + 1], "always") == 0) || (strcmp(argv[i + 1], "ALWAYS") == 0) )
00358                  {
00359                      gacl_use_voms_dn = ALWAYS_USE_VOMS_DN;
00360                  }
00361                  else
00362                  {
00363                      lcas_log(0,"%s: use  \"yes/YES\", \"no/NO\" or \"always/ALWAYS\" for option %s\n",
00364                                 logstr, argv[i]);
00365                      goto fail_voms_init;
00366                  }
00367             }
00368             i++;
00369         }
00370         else
00371         {
00372             lcas_log(0,"%s: Error in initialization parameter: %s (failure)\n", logstr,
00373                        argv[i]);
00374             return LCAS_MOD_FAIL;
00375         }
00376     }
00377 
00378     /* Check if authfile is filled */
00379     if (authfile == NULL)
00380     {
00381         lcas_log(0, "%s: authorization file is not specified (failure)\n", logstr);
00382         goto fail_voms_init;
00383     }
00384     if ((stat(authfile, &buf)) != 0)
00385     {
00386         lcas_log(0, "%s: unable to get stat of authorization file: %s\n", logstr, authfile);
00387         lcas_log(0, "%s: %s\n", logstr, strerror(errno));
00388         goto fail_voms_init;
00389     }
00390     if ( !(S_ISREG(buf.st_mode)))
00391     {
00392         lcas_log(0, "%s: specified authorization file (%s) is not a regular file (failure)\n",
00393                    logstr, authfile);
00394         goto fail_voms_init;
00395     }
00396 
00397     /* If necessary, try to establish the authorization file format from suffix */
00398     if (authformat == NO_FORMAT)
00399     {
00400         authfilecopy = strdup(authfile);
00401         authfilebase = basename(authfilecopy);
00402         if (strstr(authfilebase, ".gacl") != NULL)
00403         {
00404             authformat = GACL_FORMAT;
00405         }
00406         else if (strstr(authfilebase, ".xacml") != NULL)
00407         {
00408             authformat = XACML_FORMAT;
00409         }
00410         else
00411         {
00412             authformat = SIMPLE_FORMAT;
00413         }
00414         if (authfilecopy)
00415         {
00416             free(authfilecopy);
00417             authfilecopy = NULL;
00418         }
00419     }
00420     lcas_log_debug(1, "%s: authorization file: %s, format: %d\n", logstr, authfile, authformat);
00421 
00422     /* success */
00423 // success_voms_init:
00424     return LCAS_MOD_SUCCESS;
00425 
00426     /* failure */
00427  fail_voms_init:
00428     return LCAS_MOD_FAIL;
00429 } 
00430 
00431 
00432 /******************************************************************************
00433 Function:   plugin_introspect
00434 Description:
00435     return list of required arguments
00436 Parameters:
00437 
00438 Returns:
00439     LCAS_MOD_SUCCESS : succes
00440     LCAS_MOD_FAIL    : failure
00441 ******************************************************************************/
00442 //int plugin_introspect(
00443 //        int * argc,
00444 //        lcas_argument_t ** argv
00445 //)
00446 //{
00447 //    char * logstr = "\tlcas_plugin_voms-plugin_introspect()";
00448 //    static lcas_argument_t argList[] = {
00449 //        { "user_dn"   , "char *"        ,  1, NULL},
00450 //        { "user_cred" , "gss_cred_id_t" ,  0, NULL},
00451 //        { NULL        , NULL            , -1, NULL}
00452 //    };
00453 //
00454 //    lcas_log_debug(1,"%s: introspecting\n", logstr);
00455 //
00456 //    *argv = argList;
00457 //    lcas_log_debug(4,"%s: before lcas_cntArgs()\n", logstr);
00458 //    *argc = lcas_cntArgs(argList);
00459 //    lcas_log_debug(1,"%s: address first argument: 0x%x\n", logstr,argList);
00460 //
00461 //    return LCAS_MOD_SUCCESS;
00462 //}
00463 
00464 
00466 //Function:   plugin_run
00467 //Description:
00468 //    Gather credentials for LCAS
00469 //Parameters:
00470 //    argc: number of arguments
00471 //    argv: list of arguments
00472 //Returns:
00473 //    LCAS_MOD_SUCCESS: authorization succeeded
00474 //    LCAS_MOD_FAIL   : authorization failed
00475 //******************************************************************************/
00476 //int plugin_run(
00477 //        int argc,
00478 //        lcas_argument_t * argv
00479 //)
00480 /******************************************************************************
00481 Function:   plugin_confirm_authorization
00482 Description:
00483     Ask for authorization by passing RSL and user credential
00484 Parameters:
00485     request:   RSL request
00486     user_cred: user credential
00487 Returns:
00488     LCAS_MOD_SUCCESS : succes
00489     LCAS_MOD_FAIL    : failure
00490 ******************************************************************************/
00491 int
00492 plugin_confirm_authorization(lcas_request_t request, lcas_cred_id_t lcas_cred)
00493 {
00494     char * logstr = "\tlcas_plugin_voms-plugin_confirm_authorization()";
00495     char *              dn          = NULL; 
00496     struct vomsdata *   vd          = NULL;
00497     int                 errNo       = 0;
00498 //    gss_cred_id_t *     pcred       = NULL;
00499     gss_cred_id_t       cred        = GSS_C_NO_CREDENTIAL;
00500     X509 *              px509_cred  = NULL;
00501     STACK_OF(X509) *    px509_chain = NULL;
00502     GACLuser *          gacluser = NULL;
00503     int                 rc = 0;
00504     char *              dummy = NULL;
00505 
00506 #ifdef TESTBIO
00507     int err;
00508     int res;
00509     BIO *in = NULL;
00510     X509 *x = NULL;
00511     STACK_OF(X509) *chain;
00512 #endif
00513 
00514 
00515     /*
00516      * The beginning
00517      */
00518     lcas_log_debug(1,"%s:\n", logstr);
00519 
00520     /*
00521      * Get the gss_cred_t credential and get the globus name
00522      */
00523     if ( (dn = lcas_get_dn(lcas_cred)) == NULL)
00524     {
00525         lcas_log(0, "%s: Error, user DN empty\n", logstr);
00526         goto fail_voms;
00527     }
00528     if ( (cred = lcas_get_gss_cred(lcas_cred)) == GSS_C_NO_CREDENTIAL)
00529     {
00530         lcas_log(0, "%s: Error, user gss credential is empty !\n", logstr);
00531         goto fail_voms;
00532     }
00533 
00534 //    /*
00535 //     * Try to get the ordered values:
00536 //     */
00537 //    if ( ( dn = *(char **) lcas_getArgValue("user_dn", "char *", argc, argv) ) )
00538 //        lcas_log_debug(1,"%s: found dn: %s\n", logstr,dn);
00539 //    else
00540 //        lcas_log_debug(1,"%s: could not get value of dn !\n", logstr);
00541 //
00542 //    /* Fetch user gss credential */
00543 //    if ( ( pcred = (gss_cred_id_t *) lcas_getArgValue("user_cred", "gss_cred_id_t", argc, argv) ) )
00544 //    {
00545 //        lcas_log_debug(2,"%s: address user_cred: %p\n", logstr,pcred);
00546 //        cred = *pcred;
00547 //        if (cred == GSS_C_NO_CREDENTIAL)
00548 //        {
00549 //            lcas_log(0,"%s: user gss credential is empty ! (exit voms)\n", logstr);
00550 //            goto fail_voms;
00551 //        }
00552 //    }
00553 //    else
00554 //    {
00555 //        lcas_log(0,"%s: could not get address of user_cred (exit voms)!\n", logstr);
00556 //        goto fail_voms;
00557 //    }
00558 
00559 #undef EXPORT_CREDENTIAL
00560 #if EXPORT_CREDENTIAL
00561     if (cred)
00562     {
00563         gss_buffer_desc                 deleg_proxy_filename;
00564         OM_uint32         major_status = 0;
00565         OM_uint32         minor_status = 0;
00566         
00567         major_status = gss_export_cred(&minor_status,
00568                                        cred,
00569                                        NULL,
00570                                        1,
00571                                        &deleg_proxy_filename);
00572 
00573         if (major_status == GSS_S_COMPLETE)
00574         {
00575             char *                      cp;
00576 
00577             lcas_log_debug(1,"%s: deleg_proxy_filename.value: %s\n", logstr,
00578                                deleg_proxy_filename.value);
00579             cp = strchr((char *)deleg_proxy_filename.value, '=');
00580             *cp = '\0';
00581             cp++;
00582             setenv((char *)deleg_proxy_filename.value, cp, 1);
00583             free(deleg_proxy_filename.value);
00584         }
00585         else
00586         {
00587             char *                      error_str = NULL;
00588             globus_object_t *           error_obj;
00589 
00590             error_obj = globus_error_get((globus_result_t) minor_status);
00591             
00592             error_str = globus_error_print_chain(error_obj);
00593             lcas_log(0,"%s: Error, gss_export_cred(): %s\n", logstr,error_str);
00594             goto fail_voms;
00595         }
00596     }
00597 #endif /* EXPORT_CREDENTIAL */
00598 
00599     /*
00600      * Retrieve a newly created X509 struct and X509 chain from gss credential (should be freed)
00601      */
00602     if ( ( px509_cred = lcas_cred_to_x509(cred) ) )
00603     {
00604         lcas_log_debug(1,"%s: found X509 struct inside gss credential\n", logstr);
00605         lcas_log_debug(5,"%s: just for kicks: X509->name %s\n", logstr,px509_cred->name);
00606     }
00607     else
00608     {
00609         lcas_log(0,"%s: could not get X509 cred (exit voms)!\n", logstr);
00610         goto fail_voms;
00611     }
00612     if ( ( px509_chain = lcas_cred_to_x509_chain(cred) ) )
00613     {
00614         lcas_log_debug(1,"%s: found X509 chain inside gss credential\n", logstr);
00615     }
00616     else
00617     {
00618         lcas_log(0,"%s: could not get X509 chain (exit voms)!\n", logstr);
00619         goto fail_voms;
00620     }
00621 
00622     lcas_log_debug(1,"%s: vomsdir = %s\n", logstr, vomsdir);
00623     lcas_log_debug(1,"%s: certdir = %s\n", logstr, certdir);
00624     if ((vd = VOMS_Init(vomsdir, certdir)) == NULL)
00625     {
00626         lcas_log(0,"%s: failed to initialize voms data structure\n", logstr);
00627         goto fail_voms;
00628     }
00629     lcas_log_debug(1,"%s: voms data structure initialized\n", logstr);
00630 
00631 #ifdef TESTBIO
00632     in = BIO_new(BIO_s_file());
00633     chain = load_chain("/home/gridtest/cvs/fabric_mgt/gridification/lcas/modules/voms/x509up_u500");
00634     if (in)
00635     {
00636         if (BIO_read_filename(in, "/home/gridtest/cvs/fabric_mgt/gridification/lcas/modules/voms/x509up_u500") > 0)
00637         {
00638             x = PEM_read_bio_X509(in, NULL, 0, NULL);
00639 
00640             res = VOMS_Retrieve(x, chain, RECURSE_CHAIN, vd, &err);
00641 
00642             if (res)
00643                 print_vomsdata(vd);
00644             else
00645                 printf("%s: ERROR!\n", logstr);
00646         }
00647     }
00648 
00649     if (!res)
00650     {
00651         printf("%s: err: %s\n", logstr, retmsg[err]);
00652     }
00653 #else
00654     if (VOMS_Retrieve(px509_cred, px509_chain, RECURSE_CHAIN, 
00655                          vd, &errNo))
00656 #endif
00657     {
00658         lcas_vo_data_t *   lcas_vo_data = NULL;
00659         struct voms **     volist = vd->data;
00660         struct voms *      vo;
00661         char *             bufptr = NULL;
00662         int                k = 0;
00663         int                j = 0;
00664         int                foundmatch = 0;
00665 
00666         lcas_log_debug(1,"%s: We got something, errNo = %d\n", logstr, errNo);
00667         print_vomsdata(vd);
00668         if (errNo == VERR_ORDER)
00669         {
00670             lcas_log(0,"%s: The ordering of the VOMS groups, as required by the client, was not delivered by VOMS (but no failure)!\n", logstr);
00671         }
00672 
00673         if (authformat == GACL_FORMAT)
00674         {
00675             /* initialize gacl */
00676             GACLinit();
00677             if (lcas_gacl_add_dn(&gacluser, dn) != 0)
00678             {
00679                 lcas_log(0,"%s: error adding dn %s to gacluser\n", logstr, dn);
00680                 goto fail_voms;
00681             }
00682             else
00683             {
00684                 lcas_log_debug(2,"%s: added dn %s to gacluser\n", logstr, dn);
00685             }
00686         }
00687 
00688         while(volist[k])
00689         {
00690             vo = volist[k++];
00691             lcas_log_debug(1,"%s: setting voms data for VO == %s\n", logstr,
00692                              vo->voname);
00693             lcas_log_debug(2,"%s: setting voms data for VO server == %s\n", logstr,
00694                              vo->server);
00695 
00696             switch (vo->type) {
00697                 case TYPE_NODATA:
00698                     lcas_log_debug(1,"%s: NO DATA\n", logstr);
00699                     break;
00700                 case TYPE_CUSTOM:
00701                     lcas_log_debug(1,"%s: %*s\n", logstr, vo->datalen - 10, vo->custom);
00702                     break;
00703                 case TYPE_STD:
00704                     j = 0;
00705                     while (vo->std[j]) {
00706                         lcas_vo_data=lcas_createVoData(vo->voname,vo->std[j]->group,
00707                                                            NULL, vo->std[j]->role, vo->std[j]->cap
00708                         );
00709                         if (! lcas_vo_data)
00710                         {
00711                             lcas_log(0,"%s: could not create VoData structure (failure)\n", logstr);
00712                             goto fail_voms;
00713                         }
00714 //                        lcas_printVoData(2,lcas_vo_data);
00715                         if ( lcas_stringVoData(lcas_vo_data, voms_buffer, VOMS_BUFFER_SIZE) )
00716                         {
00717                             lcas_log(0,"%s: error in casting VoData structure into string (failure)\n", logstr);
00718                             goto fail_voms;
00719                         }
00720 //                        lcas_log_debug(1,"%s: buffer: %s\n", logstr, voms_buffer);
00721                         /*
00722                          * Now that we have the VO-GROUP-ROLE combination as a string it has to be matched in the
00723                          * authorization file. Check the format.
00724                          */
00725                         if (authformat == SIMPLE_FORMAT)
00726                         {
00727                             /* check with gridlist */
00728                             rc = lcas_gridlist(voms_buffer, &dummy, authfile, MATCH_ONLY_DN|MATCH_WILD_CHARS, NULL, NULL);
00729                             if ( rc == LCAS_MOD_ENTRY )
00730                             {
00731                                 /* Entry found for VO combi */
00732                                 lcas_log_debug(1,"%s: entry found for %s\n", logstr, voms_buffer);
00733                                 foundmatch++;
00734                             }
00735                             else if ( rc == LCAS_MOD_NOFILE )
00736                             {
00737                                 /* file not found */
00738                                 lcas_log(0, "%s: Error, Cannot find authorization file: %s\n", logstr, authfile);
00739                                 if (dummy)
00740                                 {
00741                                     free(dummy);
00742                                     dummy = NULL;
00743                                 }
00744                                 goto fail_voms;;
00745                             }
00746                             else
00747                             {
00748                                 /* no entry found, not fatal */
00749                                 lcas_log_debug(1, "%s: no entry for %s in %s\n", logstr, voms_buffer, authfile);
00750                             }
00751                             if (dummy)
00752                             {
00753                                 free(dummy);
00754                                 dummy = NULL;
00755                             }
00756                         }
00757                         else if (authformat == GACL_FORMAT)
00758                         {
00759                             /* Fill the gacluser with another VOMS credential, do the ACL checking afterwards */
00760                             if ( (gacl_use_voms_dn == USE_VOMS_DN) || (gacl_use_voms_dn == ALWAYS_USE_VOMS_DN) )
00761                             {
00762                                 if (!lcas_parseVostring(vo->server))
00763                                 {
00764                                     lcas_log(0,"%s: No VOMS server DN found in user cert. (failure)\n", logstr);
00765                                     goto fail_voms;
00766                                 }
00767                                 /* First create a credential with the VOMS DN */
00768                                 if (lcas_gacl_add_vomsdata(&gacluser, lcas_vo_data, vo->server) != 0)
00769                                 {
00770                                     lcas_log(0,"%s: error adding voms data for %s to gacluser\n", logstr, voms_buffer);
00771                                     goto fail_voms;
00772                                 }
00773                                 else
00774                                 {
00775                                     lcas_log_debug(2,"%s: added voms data for %s to gacluser\n", logstr, voms_buffer);
00776                                 }
00777                                 /* Then create a credential without the VOMS DN if (gacl_use_voms_dn == USE_VOMS_DN) */
00778                                 if (gacl_use_voms_dn == USE_VOMS_DN)
00779                                 {
00780                                     if (lcas_gacl_add_vomsdata(&gacluser, lcas_vo_data, NULL) != 0)
00781                                     {
00782                                         lcas_log(0,"%s: error adding voms data for %s to gacluser\n", logstr, voms_buffer);
00783                                         goto fail_voms;
00784                                     }
00785                                     else
00786                                     {
00787                                         lcas_log_debug(2,"%s: added voms data for %s to gacluser\n", logstr, voms_buffer);
00788                                     }
00789                                 }
00790                             }
00791                             else if (gacl_use_voms_dn == DONT_USE_VOMS_DN)
00792                             {
00793                                 /* Create a credential without the VOMS DN */
00794                                 if (lcas_gacl_add_vomsdata(&gacluser, lcas_vo_data, NULL) != 0)
00795                                 {
00796                                     lcas_log(0,"%s: error adding voms data for %s to gacluser\n", logstr, voms_buffer);
00797                                     goto fail_voms;
00798                                 }
00799                                 else
00800                                 {
00801                                     lcas_log_debug(2,"%s: added voms data for %s to gacluser\n", logstr, voms_buffer);
00802                                 }
00803                             }
00804                         }
00805                         else if (authformat == XACML_FORMAT)
00806                         {
00807                             /* check with xacml */
00808                             lcas_log(0,"%s: This (%d) format is not supported yet\n", logstr, authformat);
00809                         }
00810                         else
00811                         {
00812                             lcas_log(0,"%s: This (%d) format is not supported\n", logstr, authformat);
00813                         }
00814                         /* Add credential */
00815                         /* copy address of voms_buffer[0] in bufptr, because you cannot take the address of the array voms_buffer */
00816                         bufptr = voms_buffer;
00817 //                        addCredentialData(LCAS_VO_CRED_STRING, (void *) &bufptr);
00818 //                        addCredentialData(LCAS_VO_CRED, (void *) lcas_vo_data);
00819                         if ( lcas_deleteVoData(&lcas_vo_data) )
00820                         {
00821                             lcas_log(0,"%s: error while deleting VoData structure (failure)\n", logstr);
00822                             goto fail_voms;
00823                         }
00824                         j++;
00825                     }
00826                     break;
00827             }
00828         }
00829         lcas_log_debug(1,"%s: doing VOMS_Destroy\n", logstr);
00830         VOMS_Destroy(vd);
00831         lcas_log_debug(1,"%s: done\n", logstr);
00832 
00833         /* evaluate the matching, may become more elaborate */
00834         
00835         if (authformat == GACL_FORMAT)
00836         {
00837             /* check with gacl */
00838             /* Perhaps do something with fatalness, if deny found always quit */
00839             rc = lcas_check_gacl(gacluser, authfile);
00840             if (rc == 0)
00841             {
00842                 lcas_log_debug(1, "%s: authorization granted based on VOMS info for user %s in %s\n", logstr, dn, authfile);
00843             }
00844             else
00845             {
00846                 /* no authorization --> failure */
00847                 lcas_log(0, "%s: authorization denied based on VOMS info for user %s in %s\n", logstr, dn, authfile);
00848                 goto fail_voms;
00849             }
00850         }
00851         else
00852         {
00853             if (foundmatch)
00854             {
00855                 lcas_log_debug(1,"%s: found a matching VO entry in the authorization file\n", logstr);
00856             }
00857             else
00858             {
00859                 lcas_log(0,"%s: Did not find a matching VO entry in the authorization file\n", logstr);
00860                 goto fail_voms;
00861             }
00862         }
00863         
00864     }
00865 #ifdef TESTBIO
00866 #else
00867     else if (errNo == VERR_NOEXT)
00868     {
00869         /*
00870          * If no voms info is found in user proxy: try with the user dn if
00871          * use_user_dn flag is specified
00872          */
00873         if (use_user_dn != 0)
00874         {
00875             lcas_log_debug(1,"%s: VOMS extensions missing from certificate, trying\n", logstr);
00876             lcas_log_debug(1,"%s: to find user dn (%s) in authorization file %s\n", logstr, dn, authfile);
00877 
00878             if (authformat == SIMPLE_FORMAT)
00879             {
00880                 /* check with gridlist */
00881                 rc = lcas_gridlist(dn, &dummy, authfile, MATCH_ONLY_DN, NULL, NULL);
00882                 if ( rc == LCAS_MOD_ENTRY )
00883                 {
00884                     /* Entry found for user DN */
00885                     lcas_log_debug(1,"%s: entry found for %s\n", logstr, dn);
00886                 }
00887                 else if ( rc == LCAS_MOD_NOFILE )
00888                 {
00889                     /* file not found */
00890                     lcas_log(0, "%s: Error, Cannot find authorization file: %s\n", logstr, authfile);
00891                     if (dummy)
00892                     {
00893                         free(dummy);
00894                         dummy = NULL;
00895                     }
00896                     goto fail_voms;;
00897                 }
00898                 else
00899                 {
00900                     /* no entry found --> failure */
00901                     lcas_log(0, "%s: authorization denied based on DN info for user\n", logstr);
00902                     lcas_log(0, "%s: %s in %s\n", logstr, dn, authfile);
00903                     lcas_log(0, "%s: (in addition no VOMS info was found in user proxy)\n", logstr);
00904                     if (dummy)
00905                     {
00906                         free(dummy);
00907                         dummy = NULL;
00908                     }
00909                     goto fail_voms;
00910                 }
00911             }
00912             else if (authformat == GACL_FORMAT)
00913             {
00914                 /* initialize gacl */
00915                 GACLinit();
00916                 if (lcas_gacl_add_dn(&gacluser, dn) != 0)
00917                 {
00918                     lcas_log(0,"%s: error adding dn %s to gacluser\n", logstr, dn);
00919                     goto fail_voms;
00920                 }
00921                 else
00922                 {
00923                     lcas_log_debug(2,"%s: added dn %s to gacluser\n", logstr, dn);
00924                 }
00925                 /* check with gacl */
00926                 /* Perhaps do something with fatalness, if deny found always quit */
00927                 rc = lcas_check_gacl(gacluser, authfile);
00928                 if (rc == 0)
00929                 {
00930                     lcas_log_debug(1, "%s: authorization granted based on DN info for user %s in %s\n", logstr, dn, authfile);
00931                 }
00932                 else
00933                 {
00934                     /* no authorization --> failure */
00935                     lcas_log(0, "%s: authorization denied based on DN info for user\n", logstr);
00936                     lcas_log(0, "%s: %s in %s\n", logstr, dn, authfile);
00937                     lcas_log(0, "%s: (in addition no VOMS info was found in user proxy)\n", logstr);
00938                     goto fail_voms;
00939                 }
00940             }
00941             else
00942             {
00943                 lcas_log(0,"%s: This (%d) format is not supported yet, but this should have been checked earlier in the process! \n", logstr, authformat);
00944             }
00945         }
00946         else
00947         {
00948             lcas_log(0,"%s: VOMS extensions missing from certificate !\n", logstr);
00949             goto fail_voms;
00950         }
00951     }
00952     else if (errNo == VERR_IDCHECK)
00953     {
00954         lcas_log(0,"%s: VOMS User data in extension different from the real ones!\n", logstr);
00955         goto fail_voms;
00956     }
00957     else if (errNo == VERR_TIME)
00958     {
00959         lcas_log(0,"%s: VOMS extensions expired for at least one of the VOs !\n", logstr);
00960         goto fail_voms;
00961     }
00962     else if (errNo == VERR_ORDER)
00963     {
00964         lcas_log(0,"%s: The ordering of the VOMS groups, as required by the client, was not delivered by VOMS (failure)!\n", logstr);
00965         goto fail_voms;
00966     }
00967     else
00968     {
00969         lcas_log(0,"%s: VOMS_Retrieve() error --> %d\n", logstr, errNo);
00970         goto fail_voms;
00971     }
00972 #endif
00973 
00974     /* succes */
00975 // success_voms:
00976     if (px509_cred) X509_free(px509_cred);
00977     if (px509_chain) sk_X509_free(px509_chain);
00978     if (authformat == GACL_FORMAT)
00979     {
00980         if (gacluser)
00981         {
00982             GACLfreeUser(gacluser);
00983             gacluser = NULL;
00984         }
00985     }
00986     lcas_log_time(0,"%s: voms plugin succeeded\n", logstr);
00987     return LCAS_MOD_SUCCESS;
00988 
00989  fail_voms:
00990     if (px509_cred) X509_free(px509_cred);
00991     if (px509_chain) sk_X509_free(px509_chain);
00992     if (authformat == GACL_FORMAT)
00993     {
00994         if (gacluser)
00995         {
00996             GACLfreeUser(gacluser);
00997             gacluser = NULL;
00998         }
00999     }
01000     lcas_log_time(0,"%s: voms plugin failed\n", logstr);
01001     return LCAS_MOD_FAIL;
01002 }
01003 
01004 /******************************************************************************
01005 Function:   plugin_terminate
01006 Description:
01007     Terminate plugin
01008 Parameters:
01009 
01010 Returns:
01011     LCAS_MOD_SUCCESS : succes
01012     LCAS_MOD_FAIL    : failure
01013 ******************************************************************************/
01014 int plugin_terminate()
01015 {
01016     char * logstr = "\tlcas_plugin_voms-plugin_terminate()";
01017     lcas_log_debug(1,"%s: terminating\n", logstr);
01018     if (vomsdir)
01019     {
01020         free(vomsdir);
01021         vomsdir = NULL;
01022     }
01023     if (certdir)
01024     {
01025         free(certdir);
01026         certdir = NULL;
01027     }
01028     if (authfile)
01029     {
01030         free(authfile);
01031         authfile = NULL;
01032     }
01033 
01034     return LCAS_MOD_SUCCESS;
01035 }
01036 
01037 
01038 /******************************************************************************
01039 Function:   lcas_gacl_add_dn
01040 Description:
01041     Add the user DN to the gacl user credential
01042 Parameters:
01043     pgacluser:      pointer to the gacl user
01044     user_dn:        the DN of the user
01045 
01046 Returns:
01047     0 : succes
01048     1 : failure
01049 ******************************************************************************/
01064 static int lcas_gacl_add_dn(
01065         GACLuser ** pgacluser,
01066         char *      user_dn
01067 )
01068 {
01069     char *      logstr = "\tlcas_plugin_voms-lcas_gacl_add_dn()";
01070     GACLcred *  dn_cred = NULL;
01071     GACLuser *  gacluser = NULL;
01072     
01073     if (user_dn)
01074     {
01075         if ( (dn_cred = GACLnewCred("person")) != NULL )
01076         {
01077             lcas_log_debug(3,"%s: adding dn = %s to dn_cred\n", logstr, user_dn);
01078             GACLaddToCred(dn_cred, "dn", user_dn);
01079         }
01080         else
01081         {
01082             lcas_log_debug(1,"%s: Cannot create new credential\n", logstr);
01083             return 1;
01084         }
01085     }
01086     else
01087     {
01088         lcas_log_debug(1,"%s: empty user DN !, cannot fill GACLuser\n", logstr);
01089         return 1;
01090     }
01091 
01092     /* if necessary create user and add credential to user */
01093     if (pgacluser == NULL)
01094     {
01095         /* This should not happen ! */
01096         lcas_log(0, "%s: ptr to gacluser is NULL !, wrong invocation of lcas_gacl_add_dn()\n", logstr);
01097         GACLfreeCred(dn_cred);
01098         return 1;
01099     }
01100     gacluser = *pgacluser;
01101     if (gacluser == NULL) /* create new user */
01102     {
01103         if ( (gacluser = GACLnewUser(dn_cred)) == NULL )
01104         {
01105             lcas_log(0, "%s: Could not create new user\n", logstr);
01106             GACLfreeCred(dn_cred);
01107             return 1;
01108         }
01109         *pgacluser = gacluser;
01110     }
01111     else
01112     {
01113         if (GACLuserAddCred(gacluser, dn_cred) != 1)
01114         {
01115             lcas_log(0, "%s: Could not add credential to user\n", logstr);
01116             return 1;
01117         }
01118     } 
01119 
01120     /* clean credential */
01121     if (dn_cred)
01122     {
01123         /* Cannot free credential, because it's used in the gacluser
01124            structure (only a copy of the credential pointer is made)
01125         GACLfreeCred(dn_cred);
01126         */
01127         dn_cred = NULL;
01128     }
01129     return 0;
01130 }
01131 
01132 
01133 /******************************************************************************
01134 Function:   lcas_gacl_add_vomsdata
01135 Description:
01136     Add the VOMS data to the gacl user
01137 Parameters:
01138     pgacluser:       pointer to the gacl user
01139     lcas_voms_data:  the gathered VOMS data structure
01140     voms_server_dn:  the DN of the VOMS server that signed the VOMS certificate
01141 
01142 Returns:
01143     0 : succes
01144     1 : failure
01145 ******************************************************************************/
01163 static int lcas_gacl_add_vomsdata(
01164         GACLuser **       pgacluser,
01165         lcas_vo_data_t *  lcas_voms_data,
01166         char *            voms_server_dn
01167 )
01168 {
01169     char *      logstr = "\tlcas_plugin_voms-lcas_gacl_add_vomsdata()";
01170     GACLcred *  voms_cred = NULL;
01171     GACLuser *  gacluser = NULL;
01172     
01173     if (lcas_voms_data)
01174     {
01175         if ( (voms_cred = GACLnewCred("voms-cred")) != NULL )
01176         {
01177             char * strptr = NULL;
01178 
01179             if ( (strptr = lcas_parseVostring(voms_server_dn)) )
01180             {
01181                 lcas_log_debug(3,"%s: adding voms       = %s to voms_cred\n", logstr, strptr);
01182                 GACLaddToCred(voms_cred, "voms", strptr);
01183             }
01184             if ( (strptr = lcas_parseVostring(lcas_voms_data->vo)) )
01185             {
01186                 lcas_log_debug(3,"%s: adding vo         = %s to voms_cred\n", logstr, strptr);
01187                 GACLaddToCred(voms_cred, "vo", strptr);
01188             }
01189             if ( (strptr = lcas_parseVostring(lcas_voms_data->group)) )
01190             {
01191                 lcas_log_debug(3,"%s: adding group      = %s to voms_cred\n", logstr, strptr);
01192                 GACLaddToCred(voms_cred, "group", strptr);
01193             }
01194             if ( (strptr = lcas_parseVostring(lcas_voms_data->subgroup)) )
01195             {
01196                 lcas_log_debug(3,"%s: adding subgroup   = %s to voms_cred\n", logstr, strptr);
01197                 GACLaddToCred(voms_cred, "group", strptr);
01198             }
01199             if ( (strptr = lcas_parseVostring(lcas_voms_data->role)) )
01200             {
01201                 lcas_log_debug(3,"%s: adding role       = %s to voms_cred\n", logstr, strptr);
01202                 GACLaddToCred(voms_cred, "role", strptr);
01203             }
01204             if ( (strptr = lcas_parseVostring(lcas_voms_data->capability)) )
01205             {
01206                 lcas_log_debug(3,"%s: adding capability = %s to voms_cred\n", logstr, strptr);
01207                 GACLaddToCred(voms_cred, "capability", strptr);
01208             }
01209         }
01210         else
01211         {
01212             lcas_log_debug(1,"%s: Cannot create new credential\n", logstr);
01213             return 1;
01214         }
01215     }
01216     else
01217     {
01218         lcas_log_debug(1,"%s: empty VO data !, cannot fill GACLuser\n", logstr);
01219         return 1;
01220     }
01221 
01222     /* if necessary create user and add credential to user */
01223     if (pgacluser == NULL)
01224     {
01225         /* This should not happen ! */
01226         lcas_log(0, "%s: ptr to gacluser is NULL !, wrong invocation of lcas_gacl_add_vomsdata()\n", logstr);
01227         GACLfreeCred(voms_cred);
01228         return 1;
01229     }
01230     gacluser = *pgacluser;
01231     if (gacluser == NULL) /* create new user */
01232     {
01233         if ( (gacluser = GACLnewUser(voms_cred)) == NULL )
01234         {
01235             lcas_log(0, "%s: Could not create new user\n", logstr);
01236             GACLfreeCred(voms_cred);
01237             return 1;
01238         }
01239         *pgacluser = gacluser;
01240     }
01241     else
01242     {
01243         if (GACLuserAddCred(gacluser, voms_cred) != 1)
01244         {
01245             lcas_log(0, "%s: Could not add credential to user\n", logstr);
01246             return 1;
01247         }
01248     } 
01249 
01250     /* clean credential */
01251     if (voms_cred)
01252     {
01253         /* Cannot free credential, because it's used in the gacluser
01254            structure (only a copy of the credential pointer is made)
01255         GACLfreeCred(voms_cred);
01256         */
01257         voms_cred = NULL;
01258     }
01259     return 0;
01260 }
01261 
01262 
01263 /******************************************************************************
01264 Function:   lcas_check_gacl
01265 Description:
01266     Apply the LCAS authorization GACL to the GACL user
01267 Parameters:
01268     gacluser:  the gacluser, which consists of his DN and VOMS entries
01269     gaclfile:  the file containing the LCAS GACL.
01270 
01271 Returns:
01272     0 : succes
01273     1 : failure
01274 ******************************************************************************/
01289 static int lcas_check_gacl(
01290         GACLuser *  gacluser,
01291         char *      gaclfile
01292 )
01293 {
01294     /*
01295      * Procedure:
01296      * 1. initialize gacl
01297      * 2. load the gacl file
01298      * 3. create an GACLuser (list of credentials)
01299      * 4. check the premissions for the user
01300      *    (for the moment if the result is none --> deny, otherwise allow)
01301      */
01302 
01303     char *      logstr = "\tlcas_plugin_voms-lcas_check_gacl()";
01304     GACLacl *   lcasacl = NULL;
01305     GACLperm    lcas_gacl_perm = GACL_PERM_NONE;
01306 
01307     /* load the gacl file */
01308     lcasacl = GACLloadAcl(gaclfile);
01309     lcas_log_debug(1,"%s: gacl authorization file %s loaded\n", logstr, gaclfile);
01310     if (lcasacl != NULL)
01311     {
01312 //        GACLprintAcl(lcasacl, stderr);
01313     }
01314     else
01315     {
01316         lcas_log(0,"%s: lcasacl is NULL\n", logstr);
01317         return 1;
01318     }
01319 
01320     /* check the premissions for the user */
01321     lcas_gacl_perm = GACLtestExclAcl(lcasacl, gacluser);
01322     lcas_log_debug(1,"%s: exclusive permission = %d\n", logstr, lcas_gacl_perm);
01323 
01324     lcas_gacl_perm = GACLtestUserAcl(lcasacl, gacluser);
01325     lcas_log_debug(1,"%s: permission = %d\n", logstr, lcas_gacl_perm);
01326     if (GACLhasNone(lcas_gacl_perm))
01327     {
01328         if (lcas_get_debug_level() >= 5)
01329             GACLprintAcl(lcasacl, stderr);
01330         GACLfreeAcl(lcasacl);
01331         return 1;
01332     }
01333     else
01334     {
01335         GACLfreeAcl(lcasacl);
01336         return 0;
01337     }
01338 }
01339 
01340 static void print_vomsdata(struct vomsdata *d)
01341 {
01342     char * logstr = "\tlcas_plugin_voms-print_vomsdata()";
01343     struct voms **vo = d->data;
01344     struct voms *v;
01345     int k = 0;
01346     int j =0;
01347   
01348     while(vo[k])
01349     {
01350         v = vo[k++];
01351         lcas_log_debug(1,"%s: %d *******************************************\n", logstr,k);
01352         lcas_log_debug(1,"%s: SIGLEN: %d\nUSER: %s\n", logstr, v->siglen, v->user);
01353         lcas_log_debug(1,"%s: UCA: %s\nSERVER: %s\n", logstr, v->userca, v->server);
01354         lcas_log_debug(1,"%s: SCA: %s\nVO: %s\n", logstr, v->serverca, v->voname);
01355         lcas_log_debug(1,"%s: URI: %s\nDATE1: %s\n", logstr, v->uri, v->date1);
01356         lcas_log_debug(1,"%s: DATE2: %s\n", logstr, v->date2);
01357 
01358         switch (v->type)
01359         {
01360         case TYPE_NODATA:
01361             lcas_log_debug(1,"%s: NO DATA\n", logstr);
01362             break;
01363         case TYPE_CUSTOM:
01364             lcas_log_debug(1,"%s: %*s\n", logstr, v->datalen - 10, v->custom);
01365             break;
01366         case TYPE_STD:
01367             j = 0;
01368             while (v->std[j])
01369             {
01370                 lcas_log_debug(1,"%s: GROUP: %s\tROLE: %s\tCAP: %s\n", logstr,v->std[j]->group,
01371                      v->std[j]->role,v->std[j]->cap);
01372                 j++;
01373             }
01374             break;
01375         }
01376     }
01377 
01378     if (d->workvo)
01379         lcas_log_debug(1,"%s: WORKVO: %s\n", logstr, d->workvo);
01380 
01381     if (d->extra_data)
01382         lcas_log_debug(1,"%s: EXTRA: %s\n", logstr, d->extra_data);
01383 }
01384 
01385 /******************************************************************************
01386 CVS Information:
01387     $Source: /cvs/fabric_mgt/gridification/lcas/modules/voms/lcas_voms.c,v $
01388     $Date: 2003/09/17 08:20:34 $
01389     $Revision: 1.13 $
01390     $Author: martijn $
01391 ******************************************************************************/

Generated at Tue Sep 23 15:06:52 2003 for edg-lcas by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001