00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00083
00084
00085
00086 #include "lcmaps_config.h"
00087 #include <stdio.h>
00088 #include <stdlib.h>
00089 #include <string.h>
00090 #include <pwd.h>
00091 #include <openssl/x509.h>
00092 #include "gssapi.h"
00093
00094 #include "lcmaps_modules.h"
00095 #include "lcmaps_arguments.h"
00096 #include "lcmaps_cred_data.h"
00097 #include "lcmaps_voms_utils.h"
00098 #include "lcmaps_vo_data.h"
00099
00100 #include "voms_apic.h"
00101 #include "globus_gss_assist.h"
00102
00103 #undef TESTBIO
00104 #ifdef TESTBIO
00105 # include <openssl/pem.h>
00106 # include <openssl/bio.h>
00107 #endif
00108
00109
00110
00111
00112
00113
00114 #define VOMS_BUFFER_SIZE 1024
00115
00116
00117
00118
00119
00120 static void print_vomsdata(struct vomsdata *);
00121
00122 #ifdef TESTBIO
00123 static STACK_OF(X509) *load_chain(char *certfile);
00124 static char *retmsg[] = { "VERR_NONE", "VERR_NOSOCKET", "VERR_NOIDENT", "VERR_COMM",
00125 "VERR_PARAM", "VERR_NOEXT", "VERR_NOINIT",
00126 "VERR_TIME", "VERR_IDCHECK", "VERR_EXTRAINFO",
00127 "VERR_FORMAT", "VERR_NODATA", "VERR_PARSE",
00128 "VERR_DIR", "VERR_SIGN", "VERR_SERVER",
00129 "VERR_MEM", "VERR_VERIFY", "VERR_IDENT",
00130 "VERR_TYPE", "VERR_ORDER" };
00131 #endif
00132
00133
00134
00135
00136
00137
00138 static char * certdir = NULL;
00139 static char * vomsdir = NULL;
00140 static char voms_buffer[VOMS_BUFFER_SIZE];
00141
00142 #ifdef TESTBIO
00143 static STACK_OF(X509) *load_chain(char *certfile)
00144 {
00145 STACK_OF(X509_INFO) *sk=NULL;
00146 STACK_OF(X509) *stack=NULL, *ret=NULL;
00147 BIO *in=NULL;
00148 X509_INFO *xi;
00149 int first = 1;
00150
00151 if(!(stack = sk_X509_new_null()))
00152 {
00153 printf("%s: memory allocation failure\n", logstr);
00154 goto end;
00155 }
00156
00157 if(!(in=BIO_new_file(certfile, "r")))
00158 {
00159 printf("%s: error opening the file, %s\n", logstr,certfile);
00160 goto end;
00161 }
00162
00163
00164 if(!(sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL)))
00165 {
00166 printf("%s: error reading the file, %s\n", logstr,certfile);
00167 goto end;
00168 }
00169
00170
00171 while (sk_X509_INFO_num(sk))
00172 {
00173
00174 if (first)
00175 {
00176 first = 0;
00177 continue;
00178 }
00179 xi=sk_X509_INFO_shift(sk);
00180 if (xi->x509 != NULL)
00181 {
00182 sk_X509_push(stack,xi->x509);
00183 xi->x509=NULL;
00184 }
00185 X509_INFO_free(xi);
00186 }
00187 if(!sk_X509_num(stack))
00188 {
00189 printf("%s: no certificates in file, %s\n", logstr,certfile);
00190 sk_X509_free(stack);
00191 goto end;
00192 }
00193 ret=stack;
00194 end:
00195 BIO_free(in);
00196 sk_X509_INFO_free(sk);
00197 return(ret);
00198 }
00199 #endif
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 int plugin_initialize(
00214 int argc,
00215 char ** argv
00216 )
00217 {
00218 char * logstr = "\tlcmaps_plugin_voms-plugin_initialize()";
00219 int i;
00220
00221 lcmaps_log_debug(1,"%s: passed arguments:\n", logstr);
00222 for (i=0; i < argc; i++)
00223 {
00224 lcmaps_log_debug(2,"%s: arg %d is %s\n", logstr, i, argv[i]);
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 for (i = 1; i < argc; i++)
00236 {
00237 if ( ((strcmp(argv[i], "-vomsdir") == 0) ||
00238 (strcmp(argv[i], "-VOMSDIR") == 0))
00239 && (i + 1 < argc))
00240 {
00241 if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00242 {
00243 vomsdir = strdup(argv[i + 1]);
00244 }
00245 i++;
00246 }
00247 else if ( ((strcmp(argv[i], "-certdir") == 0) ||
00248 (strcmp(argv[i], "-CERTDIR") == 0))
00249 && (i + 1 < argc))
00250 {
00251 if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00252 {
00253 certdir = strdup(argv[i + 1]);
00254 }
00255 i++;
00256 }
00257 else
00258 {
00259 lcmaps_log(0,"%s: Error in initialization parameter: %s (failure)\n", logstr,
00260 argv[i]);
00261 return LCMAPS_MOD_FAIL;
00262 }
00263 }
00264 return LCMAPS_MOD_SUCCESS;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 int plugin_introspect(
00279 int * argc,
00280 lcmaps_argument_t ** argv
00281 )
00282 {
00283 char * logstr = "\tlcmaps_plugin_voms-plugin_introspect()";
00284 static lcmaps_argument_t argList[] = {
00285 { "user_dn" , "char *" , 1, NULL},
00286 { "user_cred" , "gss_cred_id_t" , 0, NULL},
00287 { NULL , NULL , -1, NULL}
00288 };
00289
00290 lcmaps_log_debug(1,"%s: introspecting\n", logstr);
00291
00292 *argv = argList;
00293 lcmaps_log_debug(4,"%s: before lcmaps_cntArgs()\n", logstr);
00294 *argc = lcmaps_cntArgs(argList);
00295 lcmaps_log_debug(1,"%s: address first argument: 0x%x\n", logstr,argList);
00296
00297 return LCMAPS_MOD_SUCCESS;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 int plugin_run(
00313 int argc,
00314 lcmaps_argument_t * argv
00315 )
00316 {
00317 char * logstr = "\tlcmaps_plugin_voms-plugin_run()";
00318 char * dn = NULL;
00319 struct vomsdata * vd = NULL;
00320 int errNo = 0;
00321 gss_cred_id_t * pcred = NULL;
00322 gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
00323 X509 * px509_cred = NULL;
00324 STACK_OF(X509) * px509_chain = NULL;
00325
00326 #ifdef TESTBIO
00327 int err;
00328 int res;
00329 BIO *in = NULL;
00330 X509 *x = NULL;
00331 STACK_OF(X509) *chain;
00332 #endif
00333
00334
00335
00336
00337
00338 lcmaps_log_debug(1,"%s:\n", logstr);
00339
00340
00341
00342
00343 if ( ( dn = *(char **) lcmaps_getArgValue("user_dn", "char *", argc, argv) ) )
00344 lcmaps_log_debug(1,"%s: found dn: %s\n", logstr,dn);
00345 else
00346 lcmaps_log_debug(1,"%s: could not get value of dn !\n", logstr);
00347
00348
00349 if ( ( pcred = (gss_cred_id_t *) lcmaps_getArgValue("user_cred", "gss_cred_id_t", argc, argv) ) )
00350 {
00351 lcmaps_log_debug(2,"%s: address user_cred: %p\n", logstr,pcred);
00352 cred = *pcred;
00353 if (cred == GSS_C_NO_CREDENTIAL)
00354 {
00355 lcmaps_log(0,"%s: user gss credential is empty ! (exit voms)\n", logstr);
00356 goto fail_voms;
00357 }
00358 }
00359 else
00360 {
00361 lcmaps_log(0,"%s: could not get address of user_cred (exit voms)!\n", logstr);
00362 goto fail_voms;
00363 }
00364
00365 #undef EXPORT_CREDENTIAL
00366 #if EXPORT_CREDENTIAL
00367 if (cred)
00368 {
00369 gss_buffer_desc deleg_proxy_filename;
00370 OM_uint32 major_status = 0;
00371 OM_uint32 minor_status = 0;
00372
00373 major_status = gss_export_cred(&minor_status,
00374 cred,
00375 NULL,
00376 1,
00377 &deleg_proxy_filename);
00378
00379 if (major_status == GSS_S_COMPLETE)
00380 {
00381 char * cp;
00382
00383 lcmaps_log_debug(1,"%s: deleg_proxy_filename.value: %s\n", logstr,
00384 deleg_proxy_filename.value);
00385 cp = strchr((char *)deleg_proxy_filename.value, '=');
00386 *cp = '\0';
00387 cp++;
00388 setenv((char *)deleg_proxy_filename.value, cp, 1);
00389 free(deleg_proxy_filename.value);
00390 }
00391 else
00392 {
00393 char * error_str = NULL;
00394 globus_object_t * error_obj;
00395
00396 error_obj = globus_error_get((globus_result_t) minor_status);
00397
00398 error_str = globus_error_print_chain(error_obj);
00399 lcmaps_log(0,"%s: Error, gss_export_cred(): %s\n", logstr,error_str);
00400 goto fail_voms;
00401 }
00402 }
00403 #endif
00404
00405
00406
00407
00408 if ( ( px509_cred = lcmaps_cred_to_x509(cred) ) )
00409 {
00410 lcmaps_log_debug(1,"%s: found X509 struct inside gss credential\n", logstr);
00411 lcmaps_log_debug(5,"%s: just for kicks: X509->name %s\n", logstr,px509_cred->name);
00412 }
00413 else
00414 {
00415 lcmaps_log(0,"%s: could not get X509 cred (exit voms)!\n", logstr);
00416 goto fail_voms;
00417 }
00418 if ( ( px509_chain = lcmaps_cred_to_x509_chain(cred) ) )
00419 {
00420 lcmaps_log_debug(1,"%s: found X509 chain inside gss credential\n", logstr);
00421 }
00422 else
00423 {
00424 lcmaps_log(0,"%s: could not get X509 chain (exit voms)!\n", logstr);
00425 goto fail_voms;
00426 }
00427
00428 lcmaps_log_debug(1,"%s: vomsdir = %s\n", logstr, vomsdir);
00429 lcmaps_log_debug(1,"%s: certdir = %s\n", logstr, certdir);
00430 if ((vd = VOMS_Init(vomsdir, certdir)) == NULL)
00431 {
00432 lcmaps_log(0,"%s: failed to initialize voms data structure\n", logstr);
00433 lcmaps_log(0,"%s: This may be because either the specified voms directory (%s)\n",logstr,vomsdir);
00434 lcmaps_log(0,"%s: or the specified CA certificates directory (%s) does not exist\n", logstr, certdir);
00435 goto fail_voms;
00436 }
00437 lcmaps_log_debug(1,"%s: voms data structure initialized\n", logstr);
00438
00439 #ifdef TESTBIO
00440 in = BIO_new(BIO_s_file());
00441 chain = load_chain("/home/gridtest/cvs/fabric_mgt/gridification/lcmaps/modules/voms/x509up_u500");
00442 if (in)
00443 {
00444 if (BIO_read_filename(in, "/home/gridtest/cvs/fabric_mgt/gridification/lcmaps/modules/voms/x509up_u500") > 0)
00445 {
00446 x = PEM_read_bio_X509(in, NULL, 0, NULL);
00447
00448 res = VOMS_Retrieve(x, chain, RECURSE_CHAIN, vd, &err);
00449
00450 if (res)
00451 print_vomsdata(vd);
00452 else
00453 printf("%s: ERROR!\n", logstr);
00454 }
00455 }
00456
00457 if (!res)
00458 {
00459 printf("%s: err: %s\n", logstr, retmsg[err]);
00460 }
00461 #else
00462 if (VOMS_Retrieve(px509_cred, px509_chain, RECURSE_CHAIN,
00463 vd, &errNo))
00464 #endif
00465 {
00466 lcmaps_vo_data_t * lcmaps_vo_data = NULL;
00467 struct voms ** volist = vd->data;
00468 struct voms * vo;
00469 char * bufptr = NULL;
00470 int k = 0;
00471 int j = 0;
00472
00473 lcmaps_log_debug(1,"%s: We got something, errNo = %d\n", logstr, errNo);
00474 print_vomsdata(vd);
00475
00476 while(volist[k]) {
00477 vo = volist[k++];
00478 lcmaps_log_debug(1,"%s: setting voms data for VO == %s\n", logstr,
00479 vo->voname);
00480
00481 switch (vo->type) {
00482 case TYPE_NODATA:
00483 lcmaps_log_debug(1,"%s: NO DATA\n", logstr);
00484 break;
00485 case TYPE_CUSTOM:
00486 lcmaps_log_debug(1,"%s: %*s\n", logstr, vo->datalen - 10, vo->custom);
00487 break;
00488 case TYPE_STD:
00489 j = 0;
00490 while (vo->std[j]) {
00491 lcmaps_vo_data=lcmaps_createVoData(vo->voname,vo->std[j]->group,
00492 NULL, vo->std[j]->role, vo->std[j]->cap
00493 );
00494 if (! lcmaps_vo_data)
00495 {
00496 lcmaps_log(0,"%s: could not create VoData structure (failure)\n", logstr);
00497 goto fail_voms;
00498 }
00499
00500 if ( lcmaps_stringVoData(lcmaps_vo_data, voms_buffer, VOMS_BUFFER_SIZE) )
00501 {
00502 lcmaps_log(0,"%s: error in casting VoData structure into string (failure)\n", logstr);
00503 goto fail_voms;
00504 }
00505
00506
00507
00508 bufptr = voms_buffer;
00509 addCredentialData(LCMAPS_VO_CRED_STRING, (void *) &bufptr);
00510 addCredentialData(LCMAPS_VO_CRED, (void *) lcmaps_vo_data);
00511 if ( lcmaps_deleteVoData(&lcmaps_vo_data) )
00512 {
00513 lcmaps_log(0,"%s: error while deleting VoData structure (failure)\n", logstr);
00514 goto fail_voms;
00515 }
00516 j++;
00517 }
00518 break;
00519 }
00520 }
00521 lcmaps_log_debug(1,"%s: doing VOMS_Destroy\n", logstr);
00522 VOMS_Destroy(vd);
00523 lcmaps_log_debug(1,"%s: done\n", logstr);
00524 }
00525 #ifdef TESTBIO
00526 #else
00527 else if (errNo == VERR_NOEXT)
00528 {
00529 lcmaps_log(0,"%s: VOMS extensions missing from certificate (failure)!\n", logstr);
00530 goto fail_voms;
00531 }
00532 else if (errNo == VERR_IDCHECK)
00533 {
00534 lcmaps_log(0,"%s: VOMS User data in extension different from the real ones (failure)!\n", logstr);
00535 goto fail_voms;
00536 }
00537 else if (errNo == VERR_TIME)
00538 {
00539 lcmaps_log(0,"%s: VOMS extensions expired for at least one of the VOs (failure)!\n", logstr);
00540 goto fail_voms;
00541 }
00542 else if (errNo == VERR_ORDER)
00543 {
00544 lcmaps_log(0,"%s: The ordering of the VOMS groups, as required by the client, was not delivered by VOMS (failure)!\n", logstr);
00545 goto fail_voms;
00546 }
00547 else if (errNo == VERR_NOSOCKET)
00548 {
00549 lcmaps_log(0,"%s: VOMS Socket problem (failure)!\n", logstr);
00550 goto fail_voms;
00551 }
00552 else if (errNo == VERR_NOIDENT)
00553 {
00554 lcmaps_log(0,"%s: VOMS Cannot identify itself (certificate problem) (failure)!\n", logstr);
00555 goto fail_voms;
00556 }
00557 else if (errNo == VERR_COMM)
00558 {
00559 lcmaps_log(0,"%s: VOMS server problem (failure)!\n", logstr);
00560 goto fail_voms;
00561 }
00562 else if (errNo == VERR_PARAM)
00563 {
00564 lcmaps_log(0,"%s: Wrong parameters for VOMS (failure)!\n", logstr);
00565 goto fail_voms;
00566 }
00567 else if (errNo == VERR_NOINIT)
00568 {
00569 lcmaps_log(0,"%s: VOMS initialization error (failure)!\n", logstr);
00570 goto fail_voms;
00571 }
00572 else if (errNo == VERR_EXTRAINFO)
00573 {
00574 lcmaps_log(0,"%s: VO name and URI missing (in proxy ?) (failure)!\n", logstr);
00575 goto fail_voms;
00576 }
00577 else if (errNo == VERR_FORMAT)
00578 {
00579 lcmaps_log(0,"%s: Wrong VOMS data format (in proxy ?) (failure)!\n", logstr);
00580 goto fail_voms;
00581 }
00582 else if (errNo == VERR_NODATA)
00583 {
00584 lcmaps_log(0,"%s: Empty VOMS extension (failure)!\n", logstr);
00585 goto fail_voms;
00586 }
00587 else if (errNo == VERR_PARSE)
00588 {
00589 lcmaps_log(0,"%s: VOMS parse error (failure)!\n", logstr);
00590 goto fail_voms;
00591 }
00592 else if (errNo == VERR_DIR)
00593 {
00594 lcmaps_log(0,"%s: VOMS directory error (failure)!\n", logstr);
00595 goto fail_voms;
00596 }
00597 else if (errNo == VERR_SIGN)
00598 {
00599 lcmaps_log(0,"%s: VOMS Signature error (failure)!\n", logstr);
00600 goto fail_voms;
00601 }
00602 else if (errNo == VERR_SERVER)
00603 {
00604 lcmaps_log(0,"%s: Unidentifiable VOMS server (failure)!\n", logstr);
00605 goto fail_voms;
00606 }
00607 else if (errNo == VERR_MEM)
00608 {
00609 lcmaps_log(0,"%s: Memory problems in VOMS_Retrieve() (failure)!\n", logstr);
00610 goto fail_voms;
00611 }
00612 else if (errNo == VERR_VERIFY)
00613 {
00614 lcmaps_log(0,"%s: Generic verification error for VOMS (failure)!\n", logstr);
00615 goto fail_voms;
00616 }
00617 else if (errNo == VERR_TYPE)
00618 {
00619 lcmaps_log(0,"%s: Returned VOMS data of unknown type (failure)!\n", logstr);
00620 goto fail_voms;
00621 }
00622 else
00623 {
00624 lcmaps_log(0,"%s: VOMS_Retrieve() error --> %d (failure)!\n", logstr, errNo);
00625 goto fail_voms;
00626 }
00627 #endif
00628
00629
00630 success_voms:
00631 if (px509_cred) X509_free(px509_cred);
00632 if (px509_chain) sk_X509_free(px509_chain);
00633 lcmaps_log_time(0,"%s: voms plugin succeeded\n", logstr);
00634 return LCMAPS_MOD_SUCCESS;
00635
00636 fail_voms:
00637 if (px509_cred) X509_free(px509_cred);
00638 if (px509_chain) sk_X509_free(px509_chain);
00639 lcmaps_log_time(0,"%s: voms plugin failed\n", logstr);
00640 return LCMAPS_MOD_FAIL;
00641 }
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 int plugin_terminate()
00654 {
00655 char * logstr = "\tlcmaps_plugin_voms-plugin_terminate()";
00656 lcmaps_log_debug(1,"%s: terminating\n", logstr);
00657 if (vomsdir) free(vomsdir);
00658 if (certdir) free(certdir);
00659
00660 return LCMAPS_MOD_SUCCESS;
00661 }
00662
00663 static void print_vomsdata(struct vomsdata *d)
00664 {
00665 char * logstr = "\tlcmaps_plugin_voms-print_vomsdata()";
00666 struct voms **vo = d->data;
00667 struct voms *v;
00668 int k = 0;
00669 int j =0;
00670
00671 while(vo[k])
00672 {
00673 v = vo[k++];
00674 lcmaps_log_debug(1,"%s: %d *******************************************\n", logstr,k);
00675 lcmaps_log_debug(1,"%s: SIGLEN: %d\n", logstr, v->siglen);
00676 lcmaps_log_a_string_debug(1, "\tlcmaps_plugin_voms-print_vomsdata(): USER: %s\n", v->user);
00677 lcmaps_log_a_string_debug(1, "\tlcmaps_plugin_voms-print_vomsdata(): UCA: %s\n", v->userca);
00678 lcmaps_log_a_string_debug(1, "\tlcmaps_plugin_voms-print_vomsdata(): SERVER: %s\n", v->server);
00679 lcmaps_log_a_string_debug(1, "\tlcmaps_plugin_voms-print_vomsdata(): SCA: %s\n", v->serverca);
00680 lcmaps_log_a_string_debug(1, "\tlcmaps_plugin_voms-print_vomsdata(): VO: %s\n", v->voname);
00681 lcmaps_log_a_string_debug(1, "\tlcmaps_plugin_voms-print_vomsdata(): URI: %s\n", v->uri);
00682 lcmaps_log_a_string_debug(1, "\tlcmaps_plugin_voms-print_vomsdata(): DATE1: %s\n", v->date1);
00683 lcmaps_log_a_string_debug(1, "\tlcmaps_plugin_voms-print_vomsdata(): DATE2: %s\n", v->date2);
00684
00685 switch (v->type)
00686 {
00687 case TYPE_NODATA:
00688 lcmaps_log_debug(1,"%s: NO DATA\n", logstr);
00689 break;
00690 case TYPE_CUSTOM:
00691 lcmaps_log_debug(1,"%s: VOMS custom type. Wont print.\n", logstr);
00692 break;
00693 case TYPE_STD:
00694 j = 0;
00695 if (v->fqan)
00696 {
00697 while ((v->fqan)[j] != NULL)
00698 {
00699 lcmaps_log_a_string_debug(1,
00700 "\tlcmaps_plugin_voms-print_vomsdata(): fqan: %s\n",
00701 (v->fqan)[j]);
00702 j++;
00703 }
00704 }
00705 j = 0;
00706 if (v->std)
00707 {
00708 while (v->std[j])
00709 {
00710 lcmaps_log_a_string_debug(1,
00711 "\tlcmaps_plugin_voms-print_vomsdata(): GROUP: %s\n", v->std[j]->group);
00712 lcmaps_log_a_string_debug(1,
00713 "\tlcmaps_plugin_voms-print_vomsdata(): ROLE: %s\n", v->std[j]->role);
00714 lcmaps_log_a_string_debug(1,
00715 "\tlcmaps_plugin_voms-print_vomsdata(): CAP: %s\n", v->std[j]->cap);
00716 j++;
00717 }
00718 }
00719 break;
00720 }
00721 lcmaps_log_debug(1,"%s: %d *******************************************\n", logstr,k);
00722 }
00723
00724 if (d->workvo)
00725 {
00726 lcmaps_log_a_string_debug(1,
00727 "\tlcmaps_plugin_voms-print_vomsdata(): WORKVO: %s\n", d->workvo);
00728 }
00729
00730 if (d->extra_data)
00731 {
00732 lcmaps_log_a_string_debug(1,
00733 "\tlcmaps_plugin_voms-print_vomsdata(): EXTRA: %s\n", d->extra_data);
00734 }
00735 }
00736
00737
00738
00739
00740
00741
00742
00743