00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00076
00077
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
00105
00106
00107 #define VOMS_BUFFER_SIZE 1024
00108
00109
00110
00111
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
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
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
00164 while (sk_X509_INFO_num(sk))
00165 {
00166
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
00196
00197
00198
00199
00200
00201
00202
00203
00204
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
00222
00223
00224
00225
00226
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
00263
00264
00265
00266
00267
00268
00269
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
00296
00297
00298
00299
00300
00301
00302
00303
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
00330
00331 lcmaps_log_debug(1,"%s:\n", logstr);
00332
00333
00334
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
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
00397
00398
00399
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 lcmaps_log(0,"%s: This may be because either the specified voms directory (%s)\n",logstr,vomsdir);
00427 lcmaps_log(0,"%s: or the specified CA certificates directory (%s) does not exist\n", logstr, certdir);
00428 goto fail_voms;
00429 }
00430 lcmaps_log_debug(1,"%s: voms data structure initialized\n", logstr);
00431
00432 #ifdef TESTBIO
00433 in = BIO_new(BIO_s_file());
00434 chain = load_chain("/home/gridtest/cvs/fabric_mgt/gridification/lcmaps/modules/voms/x509up_u500");
00435 if (in)
00436 {
00437 if (BIO_read_filename(in, "/home/gridtest/cvs/fabric_mgt/gridification/lcmaps/modules/voms/x509up_u500") > 0)
00438 {
00439 x = PEM_read_bio_X509(in, NULL, 0, NULL);
00440
00441 res = VOMS_Retrieve(x, chain, RECURSE_CHAIN, vd, &err);
00442
00443 if (res)
00444 print_vomsdata(vd);
00445 else
00446 printf("%s: ERROR!\n", logstr);
00447 }
00448 }
00449
00450 if (!res)
00451 {
00452 printf("%s: err: %s\n", logstr, retmsg[err]);
00453 }
00454 #else
00455 if (VOMS_Retrieve(px509_cred, px509_chain, RECURSE_CHAIN,
00456 vd, &errNo))
00457 #endif
00458 {
00459 lcmaps_vo_data_t * lcmaps_vo_data = NULL;
00460 struct voms ** volist = vd->data;
00461 struct voms * vo;
00462 char * bufptr = NULL;
00463 int k = 0;
00464 int j = 0;
00465
00466 lcmaps_log_debug(1,"%s: We got something, errNo = %d\n", logstr, errNo);
00467 print_vomsdata(vd);
00468
00469 while(volist[k]) {
00470 vo = volist[k++];
00471 lcmaps_log_debug(1,"%s: setting voms data for VO == %s\n", logstr,
00472 vo->voname);
00473
00474 switch (vo->type) {
00475 case TYPE_NODATA:
00476 lcmaps_log_debug(1,"%s: NO DATA\n", logstr);
00477 break;
00478 case TYPE_CUSTOM:
00479 lcmaps_log_debug(1,"%s: %*s\n", logstr, vo->datalen - 10, vo->custom);
00480 break;
00481 case TYPE_STD:
00482 j = 0;
00483 while (vo->std[j]) {
00484 lcmaps_vo_data=lcmaps_createVoData(vo->voname,vo->std[j]->group,
00485 NULL, vo->std[j]->role, vo->std[j]->cap
00486 );
00487 if (! lcmaps_vo_data)
00488 {
00489 lcmaps_log(0,"%s: could not create VoData structure (failure)\n", logstr);
00490 goto fail_voms;
00491 }
00492
00493 if ( lcmaps_stringVoData(lcmaps_vo_data, voms_buffer, VOMS_BUFFER_SIZE) )
00494 {
00495 lcmaps_log(0,"%s: error in casting VoData structure into string (failure)\n", logstr);
00496 goto fail_voms;
00497 }
00498
00499
00500
00501 bufptr = voms_buffer;
00502 addCredentialData(LCMAPS_VO_CRED_STRING, (void *) &bufptr);
00503 addCredentialData(LCMAPS_VO_CRED, (void *) lcmaps_vo_data);
00504 if ( lcmaps_deleteVoData(&lcmaps_vo_data) )
00505 {
00506 lcmaps_log(0,"%s: error while deleting VoData structure (failure)\n", logstr);
00507 goto fail_voms;
00508 }
00509 j++;
00510 }
00511 break;
00512 }
00513 }
00514 lcmaps_log_debug(1,"%s: doing VOMS_Destroy\n", logstr);
00515 VOMS_Destroy(vd);
00516 lcmaps_log_debug(1,"%s: done\n", logstr);
00517 }
00518 #ifdef TESTBIO
00519 #else
00520 else if (errNo == VERR_NOEXT)
00521 {
00522 lcmaps_log(0,"%s: VOMS extensions missing from certificate (failure)!\n", logstr);
00523 goto fail_voms;
00524 }
00525 else if (errNo == VERR_IDCHECK)
00526 {
00527 lcmaps_log(0,"%s: VOMS User data in extension different from the real ones (failure)!\n", logstr);
00528 goto fail_voms;
00529 }
00530 else if (errNo == VERR_TIME)
00531 {
00532 lcmaps_log(0,"%s: VOMS extensions expired for at least one of the VOs (failure)!\n", logstr);
00533 goto fail_voms;
00534 }
00535 else if (errNo == VERR_ORDER)
00536 {
00537 lcmaps_log(0,"%s: The ordering of the VOMS groups, as required by the client, was not delivered by VOMS (failure)!\n", logstr);
00538 goto fail_voms;
00539 }
00540 else if (errNo == VERR_NOSOCKET)
00541 {
00542 lcmaps_log(0,"%s: VOMS Socket problem (failure)!\n", logstr);
00543 goto fail_voms;
00544 }
00545 else if (errNo == VERR_NOIDENT)
00546 {
00547 lcmaps_log(0,"%s: VOMS Cannot identify itself (certificate problem) (failure)!\n", logstr);
00548 goto fail_voms;
00549 }
00550 else if (errNo == VERR_COMM)
00551 {
00552 lcmaps_log(0,"%s: VOMS server problem (failure)!\n", logstr);
00553 goto fail_voms;
00554 }
00555 else if (errNo == VERR_PARAM)
00556 {
00557 lcmaps_log(0,"%s: Wrong parameters for VOMS (failure)!\n", logstr);
00558 goto fail_voms;
00559 }
00560 else if (errNo == VERR_NOINIT)
00561 {
00562 lcmaps_log(0,"%s: VOMS initialization error (failure)!\n", logstr);
00563 goto fail_voms;
00564 }
00565 else if (errNo == VERR_EXTRAINFO)
00566 {
00567 lcmaps_log(0,"%s: VO name and URI missing (in proxy ?) (failure)!\n", logstr);
00568 goto fail_voms;
00569 }
00570 else if (errNo == VERR_FORMAT)
00571 {
00572 lcmaps_log(0,"%s: Wrong VOMS data format (in proxy ?) (failure)!\n", logstr);
00573 goto fail_voms;
00574 }
00575 else if (errNo == VERR_NODATA)
00576 {
00577 lcmaps_log(0,"%s: Empty VOMS extension (failure)!\n", logstr);
00578 goto fail_voms;
00579 }
00580 else if (errNo == VERR_PARSE)
00581 {
00582 lcmaps_log(0,"%s: VOMS parse error (failure)!\n", logstr);
00583 goto fail_voms;
00584 }
00585 else if (errNo == VERR_DIR)
00586 {
00587 lcmaps_log(0,"%s: VOMS directory error (failure)!\n", logstr);
00588 goto fail_voms;
00589 }
00590 else if (errNo == VERR_SIGN)
00591 {
00592 lcmaps_log(0,"%s: VOMS Signature error (failure)!\n", logstr);
00593 goto fail_voms;
00594 }
00595 else if (errNo == VERR_SERVER)
00596 {
00597 lcmaps_log(0,"%s: Unidentifiable VOMS server (failure)!\n", logstr);
00598 goto fail_voms;
00599 }
00600 else if (errNo == VERR_MEM)
00601 {
00602 lcmaps_log(0,"%s: Memory problems in VOMS_Retrieve() (failure)!\n", logstr);
00603 goto fail_voms;
00604 }
00605 else if (errNo == VERR_VERIFY)
00606 {
00607 lcmaps_log(0,"%s: Generic verification error for VOMS (failure)!\n", logstr);
00608 goto fail_voms;
00609 }
00610 else if (errNo == VERR_TYPE)
00611 {
00612 lcmaps_log(0,"%s: Returned VOMS data of unknown type (failure)!\n", logstr);
00613 goto fail_voms;
00614 }
00615 else
00616 {
00617 lcmaps_log(0,"%s: VOMS_Retrieve() error --> %d (failure)!\n", logstr, errNo);
00618 goto fail_voms;
00619 }
00620 #endif
00621
00622
00623 success_voms:
00624 if (px509_cred) X509_free(px509_cred);
00625 if (px509_chain) sk_X509_free(px509_chain);
00626 lcmaps_log_time(0,"%s: voms plugin succeeded\n", logstr);
00627 return LCMAPS_MOD_SUCCESS;
00628
00629 fail_voms:
00630 if (px509_cred) X509_free(px509_cred);
00631 if (px509_chain) sk_X509_free(px509_chain);
00632 lcmaps_log_time(0,"%s: voms plugin failed\n", logstr);
00633 return LCMAPS_MOD_FAIL;
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 int plugin_terminate()
00647 {
00648 char * logstr = "\tlcmaps_plugin_voms-plugin_terminate()";
00649 lcmaps_log_debug(1,"%s: terminating\n", logstr);
00650 if (vomsdir) free(vomsdir);
00651 if (certdir) free(certdir);
00652
00653 return LCMAPS_MOD_SUCCESS;
00654 }
00655
00656 static void print_vomsdata(struct vomsdata *d)
00657 {
00658 char * logstr = "\tlcmaps_plugin_voms-print_vomsdata()";
00659 struct voms **vo = d->data;
00660 struct voms *v;
00661 int k = 0;
00662 int j =0;
00663
00664 while(vo[k])
00665 {
00666 v = vo[k++];
00667 lcmaps_log_debug(1,"%s: %d *******************************************\n", logstr,k);
00668 lcmaps_log_debug(1,"%s: SIGLEN: %d\nUSER: %s\n", logstr, v->siglen, v->user);
00669 lcmaps_log_debug(1,"%s: UCA: %s\nSERVER: %s\n", logstr, v->userca, v->server);
00670 lcmaps_log_debug(1,"%s: SCA: %s\nVO: %s\n", logstr, v->serverca, v->voname);
00671 lcmaps_log_debug(1,"%s: URI: %s\nDATE1: %s\n", logstr, v->uri, v->date1);
00672 lcmaps_log_debug(1,"%s: DATE2: %s\n", logstr, v->date2);
00673
00674 switch (v->type)
00675 {
00676 case TYPE_NODATA:
00677 lcmaps_log_debug(1,"%s: NO DATA\n", logstr);
00678 break;
00679 case TYPE_CUSTOM:
00680 lcmaps_log_debug(1,"%s: %*s\n", logstr, v->datalen - 10, v->custom);
00681 break;
00682 case TYPE_STD:
00683 j = 0;
00684 while (v->std[j])
00685 {
00686 lcmaps_log_debug(1,"%s: GROUP: %s\tROLE: %s\tCAP: %s\n", logstr,v->std[j]->group,
00687 v->std[j]->role,v->std[j]->cap);
00688 j++;
00689 }
00690 break;
00691 }
00692 }
00693
00694 if (d->workvo)
00695 lcmaps_log_debug(1,"%s: WORKVO: %s\n", logstr, d->workvo);
00696
00697 if (d->extra_data)
00698 lcmaps_log_debug(1,"%s: EXTRA: %s\n", logstr, d->extra_data);
00699 }
00700
00701
00702
00703
00704
00705
00706
00707