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 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
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
00501
00502
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
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
00565
00566
00567
00568
00569
00570
00571
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
00630
00631
00632
00633
00634