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

lcmaps_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 
00076 /*****************************************************************************
00077                             Include header files
00078 ******************************************************************************/
00079 #include "lcmaps_config.h"
00080 #include <stdio.h>
00081 #include <stdlib.h>
00082 #include <string.h>
00083 #include <pwd.h>
00084 #include <openssl/x509.h>
00085 #include "gssapi.h"
00086 
00087 #include "lcmaps_modules.h"
00088 #include "lcmaps_arguments.h"
00089 #include "lcmaps_cred_data.h"
00090 #include "lcmaps_voms_utils.h"
00091 #include "lcmaps_vo_data.h"
00092 
00093 #include "voms_apic.h"
00094 #include "globus_gss_assist.h"
00095 
00096 #undef TESTBIO
00097 #ifdef TESTBIO
00098 #    include <openssl/pem.h>
00099 #    include <openssl/bio.h>
00100 #endif
00101 
00102 
00103 /******************************************************************************
00104                                 Definitions
00105 ******************************************************************************/
00106 
00107 #define VOMS_BUFFER_SIZE 1024
00108 
00109 
00110 /******************************************************************************
00111                           Module specific prototypes
00112 ******************************************************************************/
00113 static void print_vomsdata(struct vomsdata *);
00114 
00115 #ifdef TESTBIO
00116 static STACK_OF(X509) *load_chain(char *certfile);
00117 static char *retmsg[] = { "VERR_NONE", "VERR_NOSOCKET", "VERR_NOIDENT", "VERR_COMM", 
00118                           "VERR_PARAM", "VERR_NOEXT", "VERR_NOINIT",
00119                           "VERR_TIME", "VERR_IDCHECK", "VERR_EXTRAINFO",
00120                           "VERR_FORMAT", "VERR_NODATA", "VERR_PARSE",
00121                           "VERR_DIR", "VERR_SIGN", "VERR_SERVER", 
00122                           "VERR_MEM", "VERR_VERIFY", "VERR_IDENT",
00123                           "VERR_TYPE", "VERR_ORDER" };
00124 #endif
00125 
00126 /******************************************************************************
00127                        Define module specific variables
00128 ******************************************************************************/
00129 
00130 
00131 static char * certdir = NULL;
00132 static char * vomsdir = NULL;
00133 static char   voms_buffer[VOMS_BUFFER_SIZE];
00134 
00135 #ifdef TESTBIO
00136 static STACK_OF(X509) *load_chain(char *certfile)
00137 {
00138     STACK_OF(X509_INFO) *sk=NULL;
00139     STACK_OF(X509) *stack=NULL, *ret=NULL;
00140     BIO *in=NULL;
00141     X509_INFO *xi;
00142     int first = 1;
00143 
00144     if(!(stack = sk_X509_new_null()))
00145     {
00146         printf("%s: memory allocation failure\n", logstr);
00147         goto end;
00148     }
00149 
00150     if(!(in=BIO_new_file(certfile, "r")))
00151     {
00152         printf("%s: error opening the file, %s\n", logstr,certfile);
00153         goto end;
00154     }
00155 
00156     /* This loads from a file, a stack of x509/crl/pkey sets */
00157     if(!(sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL)))
00158     {
00159         printf("%s: error reading the file, %s\n", logstr,certfile);
00160         goto end;
00161     }
00162 
00163     /* scan over it and pull out the certs */
00164     while (sk_X509_INFO_num(sk))
00165     {
00166         /* skip first cert */
00167         if (first)
00168         {
00169             first = 0;
00170             continue;
00171         }
00172         xi=sk_X509_INFO_shift(sk);
00173         if (xi->x509 != NULL)
00174         {
00175             sk_X509_push(stack,xi->x509);
00176             xi->x509=NULL;
00177         }
00178         X509_INFO_free(xi);
00179     }
00180     if(!sk_X509_num(stack))
00181     {
00182         printf("%s: no certificates in file, %s\n", logstr,certfile);
00183         sk_X509_free(stack);
00184         goto end;
00185     }
00186     ret=stack;
00187 end:
00188     BIO_free(in);
00189     sk_X509_INFO_free(sk);
00190     return(ret);
00191 }
00192 #endif
00193 
00194 /******************************************************************************
00195 Function:   plugin_initialize
00196 Description:
00197     Initialize plugin
00198 Parameters:
00199     argc, argv
00200     argv[0]: the name of the plugin
00201 Returns:
00202     LCMAPS_MOD_SUCCESS : succes
00203     LCMAPS_MOD_FAIL    : failure
00204     LCMAPS_MOD_NOFILE  : db file not found (will halt LCMAPS initialization)
00205 ******************************************************************************/
00206 int plugin_initialize(
00207         int argc,
00208         char ** argv
00209 )
00210 {
00211     char * logstr = "\tlcmaps_plugin_voms-plugin_initialize()";
00212     int i;
00213  
00214     lcmaps_log_debug(1,"%s: passed arguments:\n", logstr);
00215     for (i=0; i < argc; i++)
00216     {
00217        lcmaps_log_debug(2,"%s: arg %d is %s\n", logstr, i, argv[i]);
00218     }
00219  
00220     /*
00221      * CERTDIR = The directory which contains the CA certificates
00222      * VOMSDIR = The directory which contains the certificates of the VOMS servers 
00223      */
00224  
00225     /*
00226      * Parse arguments, argv[0] = name of plugin, so start with i = 1
00227      */
00228     for (i = 1; i < argc; i++)
00229     {
00230         if ( ((strcmp(argv[i], "-vomsdir") == 0) ||
00231               (strcmp(argv[i], "-VOMSDIR") == 0))
00232              && (i + 1 < argc))
00233         {
00234             if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00235             {
00236                  vomsdir = strdup(argv[i + 1]);
00237             }
00238             i++;
00239         }
00240         else if ( ((strcmp(argv[i], "-certdir") == 0) ||
00241                    (strcmp(argv[i], "-CERTDIR") == 0))
00242                    && (i + 1 < argc))
00243         {
00244             if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00245             {
00246                  certdir = strdup(argv[i + 1]);
00247             }
00248             i++;
00249         }
00250         else
00251         {
00252             lcmaps_log(0,"%s: Error in initialization parameter: %s (failure)\n", logstr,
00253                        argv[i]);
00254             return LCMAPS_MOD_FAIL;
00255         }
00256     }
00257     return LCMAPS_MOD_SUCCESS;
00258 } 
00259 
00260 
00261 /******************************************************************************
00262 Function:   plugin_introspect
00263 Description:
00264     return list of required arguments
00265 Parameters:
00266 
00267 Returns:
00268     LCMAPS_MOD_SUCCESS : succes
00269     LCMAPS_MOD_FAIL    : failure
00270 ******************************************************************************/
00271 int plugin_introspect(
00272         int * argc,
00273         lcmaps_argument_t ** argv
00274 )
00275 {
00276     char * logstr = "\tlcmaps_plugin_voms-plugin_introspect()";
00277     static lcmaps_argument_t argList[] = {
00278         { "user_dn"   , "char *"        ,  1, NULL},
00279         { "user_cred" , "gss_cred_id_t" ,  0, NULL},
00280         { NULL        , NULL            , -1, NULL}
00281     };
00282 
00283     lcmaps_log_debug(1,"%s: introspecting\n", logstr);
00284 
00285     *argv = argList;
00286     lcmaps_log_debug(4,"%s: before lcmaps_cntArgs()\n", logstr);
00287     *argc = lcmaps_cntArgs(argList);
00288     lcmaps_log_debug(1,"%s: address first argument: 0x%x\n", logstr,argList);
00289 
00290     return LCMAPS_MOD_SUCCESS;
00291 }
00292 
00293 
00294 /******************************************************************************
00295 Function:   plugin_run
00296 Description:
00297     Gather credentials for LCMAPS
00298 Parameters:
00299     argc: number of arguments
00300     argv: list of arguments
00301 Returns:
00302     LCMAPS_MOD_SUCCESS: authorization succeeded
00303     LCMAPS_MOD_FAIL   : authorization failed
00304 ******************************************************************************/
00305 int plugin_run(
00306         int argc,
00307         lcmaps_argument_t * argv
00308 )
00309 {
00310     char * logstr = "\tlcmaps_plugin_voms-plugin_run()";
00311     char *              dn          = NULL; 
00312     struct vomsdata *   vd          = NULL;
00313     int                 errNo       = 0;
00314     gss_cred_id_t *     pcred       = NULL;
00315     gss_cred_id_t       cred        = GSS_C_NO_CREDENTIAL;
00316     X509 *              px509_cred  = NULL;
00317     STACK_OF(X509) *    px509_chain = NULL;
00318 
00319 #ifdef TESTBIO
00320     int err;
00321     int res;
00322     BIO *in = NULL;
00323     X509 *x = NULL;
00324     STACK_OF(X509) *chain;
00325 #endif
00326 
00327 
00328     /*
00329      * The beginning
00330      */
00331     lcmaps_log_debug(1,"%s:\n", logstr);
00332 
00333     /*
00334      * Try to get the ordered values:
00335      */
00336     if ( ( dn = *(char **) lcmaps_getArgValue("user_dn", "char *", argc, argv) ) )
00337         lcmaps_log_debug(1,"%s: found dn: %s\n", logstr,dn);
00338     else
00339         lcmaps_log_debug(1,"%s: could not get value of dn !\n", logstr);
00340 
00341     /* Fetch user gss credential */
00342     if ( ( pcred = (gss_cred_id_t *) lcmaps_getArgValue("user_cred", "gss_cred_id_t", argc, argv) ) )
00343     {
00344         lcmaps_log_debug(2,"%s: address user_cred: %p\n", logstr,pcred);
00345         cred = *pcred;
00346         if (cred == GSS_C_NO_CREDENTIAL)
00347         {
00348             lcmaps_log(0,"%s: user gss credential is empty ! (exit voms)\n", logstr);
00349             goto fail_voms;
00350         }
00351     }
00352     else
00353     {
00354         lcmaps_log(0,"%s: could not get address of user_cred (exit voms)!\n", logstr);
00355         goto fail_voms;
00356     }
00357 
00358 #undef EXPORT_CREDENTIAL
00359 #if EXPORT_CREDENTIAL
00360     if (cred)
00361     {
00362         gss_buffer_desc                 deleg_proxy_filename;
00363         OM_uint32         major_status = 0;
00364         OM_uint32         minor_status = 0;
00365         
00366         major_status = gss_export_cred(&minor_status,
00367                                        cred,
00368                                        NULL,
00369                                        1,
00370                                        &deleg_proxy_filename);
00371 
00372         if (major_status == GSS_S_COMPLETE)
00373         {
00374             char *                      cp;
00375 
00376             lcmaps_log_debug(1,"%s: deleg_proxy_filename.value: %s\n", logstr,
00377                                deleg_proxy_filename.value);
00378             cp = strchr((char *)deleg_proxy_filename.value, '=');
00379             *cp = '\0';
00380             cp++;
00381             setenv((char *)deleg_proxy_filename.value, cp, 1);
00382             free(deleg_proxy_filename.value);
00383         }
00384         else
00385         {
00386             char *                      error_str = NULL;
00387             globus_object_t *           error_obj;
00388 
00389             error_obj = globus_error_get((globus_result_t) minor_status);
00390             
00391             error_str = globus_error_print_chain(error_obj);
00392             lcmaps_log(0,"%s: Error, gss_export_cred(): %s\n", logstr,error_str);
00393             goto fail_voms;
00394         }
00395     }
00396 #endif /* EXPORT_CREDENTIAL */
00397 
00398     /*
00399      * Retrieve a newly created X509 struct and X509 chain from gss credential (should be freed)
00400      */
00401     if ( ( px509_cred = lcmaps_cred_to_x509(cred) ) )
00402     {
00403         lcmaps_log_debug(1,"%s: found X509 struct inside gss credential\n", logstr);
00404         lcmaps_log_debug(5,"%s: just for kicks: X509->name %s\n", logstr,px509_cred->name);
00405     }
00406     else
00407     {
00408         lcmaps_log(0,"%s: could not get X509 cred (exit voms)!\n", logstr);
00409         goto fail_voms;
00410     }
00411     if ( ( px509_chain = lcmaps_cred_to_x509_chain(cred) ) )
00412     {
00413         lcmaps_log_debug(1,"%s: found X509 chain inside gss credential\n", logstr);
00414     }
00415     else
00416     {
00417         lcmaps_log(0,"%s: could not get X509 chain (exit voms)!\n", logstr);
00418         goto fail_voms;
00419     }
00420 
00421     lcmaps_log_debug(1,"%s: vomsdir = %s\n", logstr, vomsdir);
00422     lcmaps_log_debug(1,"%s: certdir = %s\n", logstr, certdir);
00423     if ((vd = VOMS_Init(vomsdir, certdir)) == NULL)
00424     {
00425         lcmaps_log(0,"%s: failed to initialize voms data structure\n", logstr);
00426         goto fail_voms;
00427     }
00428     lcmaps_log_debug(1,"%s: voms data structure initialized\n", logstr);
00429 
00430 #ifdef TESTBIO
00431     in = BIO_new(BIO_s_file());
00432     chain = load_chain("/home/gridtest/cvs/fabric_mgt/gridification/lcmaps/modules/voms/x509up_u500");
00433     if (in)
00434     {
00435         if (BIO_read_filename(in, "/home/gridtest/cvs/fabric_mgt/gridification/lcmaps/modules/voms/x509up_u500") > 0)
00436         {
00437             x = PEM_read_bio_X509(in, NULL, 0, NULL);
00438 
00439             res = VOMS_Retrieve(x, chain, RECURSE_CHAIN, vd, &err);
00440 
00441             if (res)
00442                 print_vomsdata(vd);
00443             else
00444                 printf("%s: ERROR!\n", logstr);
00445         }
00446     }
00447 
00448     if (!res)
00449     {
00450         printf("%s: err: %s\n", logstr, retmsg[err]);
00451     }
00452 #else
00453     if (VOMS_Retrieve(px509_cred, px509_chain, RECURSE_CHAIN, 
00454                          vd, &errNo))
00455 #endif
00456     { 
00457         lcmaps_vo_data_t * lcmaps_vo_data = NULL;
00458         struct voms **     volist = vd->data;
00459         struct voms *      vo;
00460         char *             bufptr = NULL;
00461         int k = 0;
00462         int j = 0;
00463 
00464         lcmaps_log_debug(1,"%s: We got something, errNo = %d\n", logstr, errNo);
00465         print_vomsdata(vd);
00466         if (errNo == VERR_ORDER)
00467         {
00468             lcmaps_log(0,"%s: The ordering of the VOMS groups, as required by the client, was not delivered by VOMS (but no failure)!\n", logstr);
00469         }
00470   
00471         while(volist[k]) {
00472             vo = volist[k++];
00473             lcmaps_log_debug(1,"%s: setting voms data for VO == %s\n", logstr,
00474                              vo->voname);
00475 
00476             switch (vo->type) {
00477                 case TYPE_NODATA:
00478                     lcmaps_log_debug(1,"%s: NO DATA\n", logstr);
00479                     break;
00480                 case TYPE_CUSTOM:
00481                     lcmaps_log_debug(1,"%s: %*s\n", logstr, vo->datalen - 10, vo->custom);
00482                     break;
00483                 case TYPE_STD:
00484                     j = 0;
00485                     while (vo->std[j]) {
00486                         lcmaps_vo_data=lcmaps_createVoData(vo->voname,vo->std[j]->group,
00487                                                            NULL, vo->std[j]->role, vo->std[j]->cap
00488                         );
00489                         if (! lcmaps_vo_data)
00490                         {
00491                             lcmaps_log(0,"%s: could not create VoData structure (failure)\n", logstr);
00492                             goto fail_voms;
00493                         }
00494 //                        lcmaps_printVoData(2,lcmaps_vo_data);
00495                         if ( lcmaps_stringVoData(lcmaps_vo_data, voms_buffer, VOMS_BUFFER_SIZE) )
00496                         {
00497                             lcmaps_log(0,"%s: error in casting VoData structure into string (failure)\n", logstr);
00498                             goto fail_voms;
00499                         }
00500 //                        lcmaps_log_debug(1,"%s: buffer: %s\n", logstr, voms_buffer);
00501                         /* Add credential */
00502                         /* copy address of voms_buffer[0] in bufptr, because you cannot take the address of the array voms_buffer */
00503                         bufptr = voms_buffer;
00504                         addCredentialData(LCMAPS_VO_CRED_STRING, (void *) &bufptr);
00505                         addCredentialData(LCMAPS_VO_CRED, (void *) lcmaps_vo_data);
00506                         if ( lcmaps_deleteVoData(&lcmaps_vo_data) )
00507                         {
00508                             lcmaps_log(0,"%s: error while deleting VoData structure (failure)\n", logstr);
00509                             goto fail_voms;
00510                         }
00511                         j++;
00512                     }
00513                     break;
00514             }
00515         }
00516         lcmaps_log_debug(1,"%s: doing VOMS_Destroy\n", logstr);
00517         VOMS_Destroy(vd);
00518         lcmaps_log_debug(1,"%s: done\n", logstr);
00519     }
00520 #ifdef TESTBIO
00521 #else
00522     else if (errNo == VERR_NOEXT)
00523     {
00524         lcmaps_log(0,"%s: VOMS extensions missing from certificate !\n", logstr);
00525         goto fail_voms;
00526     }
00527     else if (errNo == VERR_IDCHECK)
00528     {
00529         lcmaps_log(0,"%s: VOMS User data in extension different from the real ones!\n", logstr);
00530         goto fail_voms;
00531     }
00532     else if (errNo == VERR_TIME)
00533     {
00534         lcmaps_log(0,"%s: VOMS extensions expired for at least one of the VOs !\n", logstr);
00535         goto fail_voms;
00536     }
00537     else if (errNo == VERR_ORDER)
00538     {
00539         lcmaps_log(0,"%s: The ordering of the VOMS groups, as required by the client, was not delivered by VOMS (failure)!\n", logstr);
00540         goto fail_voms;
00541     }
00542     else
00543     {
00544         lcmaps_log(0,"%s: VOMS_Retrieve() error --> %d\n", logstr, errNo);
00545         goto fail_voms;
00546     }
00547 #endif
00548 
00549     /* succes */
00550  success_voms:
00551     if (px509_cred) X509_free(px509_cred);
00552     if (px509_chain) sk_X509_free(px509_chain);
00553     lcmaps_log_time(0,"%s: voms plugin succeeded\n", logstr);
00554     return LCMAPS_MOD_SUCCESS;
00555 
00556  fail_voms:
00557     if (px509_cred) X509_free(px509_cred);
00558     if (px509_chain) sk_X509_free(px509_chain);
00559     lcmaps_log_time(0,"%s: voms plugin failed\n", logstr);
00560     return LCMAPS_MOD_FAIL;
00561 }
00562 
00563 /******************************************************************************
00564 Function:   plugin_terminate
00565 Description:
00566     Terminate plugin
00567 Parameters:
00568 
00569 Returns:
00570     LCMAPS_MOD_SUCCESS : succes
00571     LCMAPS_MOD_FAIL    : failure
00572 ******************************************************************************/
00573 int plugin_terminate()
00574 {
00575     char * logstr = "\tlcmaps_plugin_voms-plugin_terminate()";
00576     lcmaps_log_debug(1,"%s: terminating\n", logstr);
00577     if (vomsdir) free(vomsdir);
00578     if (certdir) free(certdir);
00579 
00580     return LCMAPS_MOD_SUCCESS;
00581 }
00582 
00583 static void print_vomsdata(struct vomsdata *d)
00584 {
00585     char * logstr = "\tlcmaps_plugin_voms-print_vomsdata()";
00586     struct voms **vo = d->data;
00587     struct voms *v;
00588     int k = 0;
00589     int j =0;
00590   
00591     while(vo[k])
00592     {
00593         v = vo[k++];
00594         lcmaps_log_debug(1,"%s: %d *******************************************\n", logstr,k);
00595         lcmaps_log_debug(1,"%s: SIGLEN: %d\nUSER: %s\n", logstr, v->siglen, v->user);
00596         lcmaps_log_debug(1,"%s: UCA: %s\nSERVER: %s\n", logstr, v->userca, v->server);
00597         lcmaps_log_debug(1,"%s: SCA: %s\nVO: %s\n", logstr, v->serverca, v->voname);
00598         lcmaps_log_debug(1,"%s: URI: %s\nDATE1: %s\n", logstr, v->uri, v->date1);
00599         lcmaps_log_debug(1,"%s: DATE2: %s\n", logstr, v->date2);
00600 
00601         switch (v->type)
00602         {
00603         case TYPE_NODATA:
00604             lcmaps_log_debug(1,"%s: NO DATA\n", logstr);
00605             break;
00606         case TYPE_CUSTOM:
00607             lcmaps_log_debug(1,"%s: %*s\n", logstr, v->datalen - 10, v->custom);
00608             break;
00609         case TYPE_STD:
00610             j = 0;
00611             while (v->std[j])
00612             {
00613                 lcmaps_log_debug(1,"%s: GROUP: %s\tROLE: %s\tCAP: %s\n", logstr,v->std[j]->group,
00614                      v->std[j]->role,v->std[j]->cap);
00615                 j++;
00616             }
00617             break;
00618         }
00619     }
00620 
00621     if (d->workvo)
00622         lcmaps_log_debug(1,"%s: WORKVO: %s\n", logstr, d->workvo);
00623 
00624     if (d->extra_data)
00625         lcmaps_log_debug(1,"%s: EXTRA: %s\n", logstr, d->extra_data);
00626 }
00627 
00628 /******************************************************************************
00629 CVS Information:
00630     $Source: /cvs/fabric_mgt/gridification/lcmaps/modules/voms/lcmaps_voms.c,v $
00631     $Date: 2003/08/12 13:04:17 $
00632     $Revision: 1.16 $
00633     $Author: martijn $
00634 ******************************************************************************/

Generated at Tue Sep 23 15:48:09 2003 for edg-lcmaps by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001