2
* Copyright (c) Members of the EGEE Collaboration. 2004-2010.
3
* See http://www.eu-egee.org/partners/ for details on the copyright
6
* Licensed under the Apache License, Version 2.0 (the "License");
7
* you may not use this file except in compliance with the License.
8
* You may obtain a copy of the License at
10
* http://www.apache.org/licenses/LICENSE-2.0
12
* Unless required by applicable law or agreed to in writing, software
13
* distributed under the License is distributed on an "AS IS" BASIS,
14
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
* See the License for the specific language governing permissions and
16
* limitations under the License.
21
* Oscar Koeroo <okoeroo@nikhef.nl>
22
* Mischa Sall\'e <msalle@nikhef.nl>
23
* David Groep <davidg@nikhef.nl>
24
* NIKHEF Amsterdam, the Netherlands
25
* <grid-mw-security@nikhef.nl>
28
* Oscar Koeroo <okoeroo@nikhef.nl>
29
* David Groep <davidg@nikhef.nl>
30
* NIKHEF Amsterdam, the Netherlands
33
* Martijn Steenbakkers <martijn@nikhef.nl>
34
* Gerben Venekamp <venekamp@nikhef.nl>
35
* Oscar Koeroo <okoeroo@nikhef.nl>
36
* David Groep <davidg@nikhef.nl>
37
* NIKHEF Amsterdam, the Netherlands
42
\page lcmaps_voms.mod voms plugin
44
\section vomssyn SYNOPSIS
45
\b lcmaps_voms.mod -vomsdir \<vomsdir\> -certdir \<certdir\>
48
\section vomsdescr DESCRIPTION
50
This plugin forms the link between the VOMS data found in the user grid credential (X509
51
certificate) and the lcmaps system.
52
It will retrieve the VOMS data by using the VOMS API.
53
The plugin stores the VOMS data in the LCMAPS process space, where it is accessible by
54
other 'VOMS-aware' plugins, and should, therefore, be evaluated before the other
55
plugins, that actually gather the local credentials based on the VOMS information
56
(e.g. \ref lcmaps_voms_poolaccount.mod "lcmaps_voms_poolaccount.mod",
57
\ref lcmaps_voms_poolgroup.mod "lcmaps_voms_poolgroup.mod" and
58
\ref lcmaps_voms_localgroup.mod "lcmaps_voms_localgroup.mod").
61
\section vomsoptions OPTIONS
62
\subsection vomsoptie1 -VOMSDIR \<vomsdir\>
63
See \ref vomsoptie2 "-vomsdir"
65
\subsection vomsoptie2 -vomsdir \<vomsdir\>
66
This is the directory which contains the certificates of the VOMS servers
68
\subsection vomsoptie3 -CERTDIR \<certdir\>
69
See \ref vomsoptie4 "-certdir"
71
\subsection vomsoptie4 -certdir \<certdir\>
72
This is the directory which contains the CA certificates
75
\section vomsReturnvalue RETURN VALUES
76
\li LCMAPS_MOD_SUCCESS : Success
77
\li LCMAPS_MOD_FAIL : Failure
80
\section vomsErrors ERRORS
81
See bugzilla for known errors (http://marianne.in2p3.fr/datagrid/bugzilla/)
83
\section vomsSeeAlso SEE ALSO
84
\ref lcmaps_voms_poolaccount.mod "lcmaps_voms_poolaccount.mod",
85
\ref lcmaps_voms_poolgroup.mod "lcmaps_voms_poolgroup.mod",
86
\ref lcmaps_voms_localgroup.mod "lcmaps_voms_localgroup.mod"
87
\ref lcmaps_localaccount.mod "lcmaps_localaccount.mod",
88
\ref lcmaps_poolaccount.mod "lcmaps_poolaccount.mod",
89
\ref lcmaps_posix_enf.mod "lcmaps_posix_enf.mod",
90
\ref lcmaps_ldap_enf.mod "lcmaps_ldap_enf.mod",
95
\brief Interface to the LCMAPS plugins
96
\author Martijn Steenbakkers for the EU DataGrid.
98
This file contains the code for the voms plugin (extracts the VOMS info from the
99
certificate). The interface consists of the following functions:
100
-# plugin_initialize()
102
-# plugin_terminate()
103
-# plugin_introspect()
106
/*****************************************************************************
108
******************************************************************************/
109
#include "lcmaps_voms_config.h"
114
#include <openssl/x509.h>
117
#include <lcmaps/lcmaps_modules.h>
118
#include <lcmaps/lcmaps_arguments.h>
119
#include <lcmaps/lcmaps_cred_data.h>
120
#include <lcmaps/lcmaps_vo_data.h>
122
#include "lcmaps_voms_gsi_utils.h"
124
#include <voms/voms_apic.h>
125
#include <globus_gss_assist.h>
129
# include <openssl/pem.h>
130
# include <openssl/bio.h>
134
/******************************************************************************
136
******************************************************************************/
138
#define PLUGIN_VERIFY 1
140
#define VOMS_BUFFER_SIZE 1024
143
/******************************************************************************
144
Module specific prototypes
145
******************************************************************************/
146
static int plugin_run_or_verify(int, lcmaps_argument_t *, int);
147
static void print_vomsdata(struct vomsdata *);
150
static STACK_OF(X509) *load_chain(char *certfile);
151
static char *retmsg[] = { "VERR_NONE", "VERR_NOSOCKET", "VERR_NOIDENT", "VERR_COMM",
152
"VERR_PARAM", "VERR_NOEXT", "VERR_NOINIT",
153
"VERR_TIME", "VERR_IDCHECK", "VERR_EXTRAINFO",
154
"VERR_FORMAT", "VERR_NODATA", "VERR_PARSE",
155
"VERR_DIR", "VERR_SIGN", "VERR_SERVER",
156
"VERR_MEM", "VERR_VERIFY", "VERR_IDENT",
157
"VERR_TYPE", "VERR_ORDER" };
160
/******************************************************************************
161
Define module specific variables
162
******************************************************************************/
165
static char * certdir = NULL;
166
static char * vomsdir = NULL;
167
static char voms_buffer[VOMS_BUFFER_SIZE];
170
static STACK_OF(X509) *load_chain(char *certfile)
172
STACK_OF(X509_INFO) *sk=NULL;
173
STACK_OF(X509) *stack=NULL, *ret=NULL;
178
if(!(stack = sk_X509_new_null()))
180
printf("%s: memory allocation failure\n", logstr);
184
if(!(in=BIO_new_file(certfile, "r")))
186
printf("%s: error opening the file, %s\n", logstr,certfile);
190
/* This loads from a file, a stack of x509/crl/pkey sets */
191
if(!(sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL)))
193
printf("%s: error reading the file, %s\n", logstr,certfile);
197
/* scan over it and pull out the certs */
198
while (sk_X509_INFO_num(sk))
200
/* skip first cert */
206
xi=sk_X509_INFO_shift(sk);
207
if (xi->x509 != NULL)
209
sk_X509_push(stack,xi->x509);
214
if(!sk_X509_num(stack))
216
printf("%s: no certificates in file, %s\n", logstr,certfile);
223
sk_X509_INFO_free(sk);
228
/******************************************************************************
229
Function: plugin_initialize
234
argv[0]: the name of the plugin
236
LCMAPS_MOD_SUCCESS : succes
237
LCMAPS_MOD_FAIL : failure
238
LCMAPS_MOD_NOFILE : db file not found (will halt LCMAPS initialization)
239
******************************************************************************/
240
int plugin_initialize(
245
char * logstr = "lcmaps_plugin_voms-plugin_initialize()";
248
lcmaps_log_debug(1,"%s: passed arguments:\n", logstr);
249
for (i=0; i < argc; i++)
251
lcmaps_log_debug(2,"%s: arg %d is %s\n", logstr, i, argv[i]);
255
* CERTDIR = The directory which contains the CA certificates
256
* VOMSDIR = The directory which contains the certificates of the VOMS servers
260
* Parse arguments, argv[0] = name of plugin, so start with i = 1
262
for (i = 1; i < argc; i++)
264
if ( ((strcmp(argv[i], "-vomsdir") == 0) ||
265
(strcmp(argv[i], "-VOMSDIR") == 0))
268
if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
270
vomsdir = strdup(argv[i + 1]);
274
else if ( ((strcmp(argv[i], "-certdir") == 0) ||
275
(strcmp(argv[i], "-CERTDIR") == 0))
278
if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
280
certdir = strdup(argv[i + 1]);
286
lcmaps_log(LOG_ERR,"%s: Error in initialization parameter: %s (failure)\n", logstr,
288
return LCMAPS_MOD_FAIL;
291
return LCMAPS_MOD_SUCCESS;
295
/******************************************************************************
296
Function: plugin_introspect
298
return list of required arguments
302
LCMAPS_MOD_SUCCESS : succes
303
LCMAPS_MOD_FAIL : failure
304
******************************************************************************/
305
int plugin_introspect(
307
lcmaps_argument_t ** argv
310
char * logstr = "\tlcmaps_plugin_voms-plugin_introspect()";
311
static lcmaps_argument_t argList[] = {
312
{ "user_dn" , "char *" , 1, NULL},
313
{ "user_cred" , "gss_cred_id_t" , 0, NULL},
314
{ NULL , NULL , -1, NULL}
317
lcmaps_log_debug(4,"%s: introspecting\n", logstr);
320
lcmaps_log_debug(5,"%s: before lcmaps_cntArgs()\n", logstr);
321
*argc = lcmaps_cntArgs(argList);
322
lcmaps_log_debug(5,"%s: address first argument: 0x%x\n", logstr,argList);
324
return LCMAPS_MOD_SUCCESS;
327
/******************************************************************************
330
Gather credentials for LCMAPS
332
argc: number of arguments
333
argv: list of arguments
335
LCMAPS_MOD_SUCCESS: authorization succeeded
336
LCMAPS_MOD_FAIL : authorization failed
337
******************************************************************************/
340
lcmaps_argument_t * argv
343
return plugin_run_or_verify(argc, argv, PLUGIN_RUN);
346
/******************************************************************************
347
Function: plugin_verify
349
Verify if user is entitled to use local credentials based on his grid
350
credentials. This means that the site should already have been set up
351
by, e.g., LCMAPS in a previous run. This method will not try to setup
352
account leases, modify (distributed) passwd/group files, etc. etc.
353
The outcome should be identical to that of plugin_run().
354
In this particular case "plugin_verify()" is identical to "plugin_run()"
357
argc: number of arguments
358
argv: list of arguments
360
LCMAPS_MOD_SUCCESS: authorization succeeded
361
LCMAPS_MOD_FAIL : authorization failed
362
******************************************************************************/
365
lcmaps_argument_t * argv
368
return plugin_run_or_verify(argc, argv, PLUGIN_VERIFY);
371
static int plugin_run_or_verify(
373
lcmaps_argument_t * argv,
377
char * logstr = "lcmaps_plugin_voms-plugin_run()";
379
struct vomsdata * vd = NULL;
381
gss_cred_id_t * pcred = NULL;
382
gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
383
X509 * px509_cred = NULL;
384
STACK_OF(X509) * px509_chain = NULL;
391
STACK_OF(X509) *chain;
398
if (lcmaps_mode == PLUGIN_RUN)
399
logstr = "lcmaps_plugin_voms-plugin_run()";
400
else if (lcmaps_mode == PLUGIN_VERIFY)
401
logstr = "lcmaps_plugin_voms-plugin_verify()";
404
lcmaps_log(LOG_ERR, "lcmaps_plugin_voms-plugin_run_or_verify(): attempt to run plugin in invalid mode: %d\n", lcmaps_mode);
407
lcmaps_log_debug(LOG_DEBUG,"%s:\n", logstr);
410
* Try to get the ordered values:
412
if ( ( dn = *(char **) lcmaps_getArgValue("user_dn", "char *", argc, argv) ) )
413
lcmaps_log_debug(1,"%s: found dn: %s\n", logstr,dn);
415
lcmaps_log_debug(1,"%s: could not get value of dn !\n", logstr);
417
/* Fetch user gss credential */
418
if ( ( pcred = (gss_cred_id_t *) lcmaps_getArgValue("user_cred", "gss_cred_id_t", argc, argv) ) )
420
lcmaps_log_debug(2,"%s: address user_cred: %p\n", logstr,pcred);
422
if (cred == GSS_C_NO_CREDENTIAL)
424
lcmaps_log(LOG_NOTICE,"%s: user gss credential is empty ! (exit voms)\n", logstr);
430
lcmaps_log(LOG_DEBUG,"%s: could not get address of user_cred (exit voms)!\n", logstr);
435
* Retrieve a newly created X509 struct and X509 chain from gss credential (should be freed)
437
if ( ( px509_cred = lcmaps_cred_to_x509(cred) ) )
439
lcmaps_log_debug(1,"%s: found X509 struct inside gss credential\n", logstr);
440
lcmaps_log_debug(5,"%s: just for kicks: X509->name %s\n", logstr,px509_cred->name);
444
lcmaps_log(LOG_ERR,"%s: could not get X509 cred (exit voms)!\n", logstr);
447
if ( ( px509_chain = lcmaps_cred_to_x509_chain(cred) ) )
449
lcmaps_log_debug(1,"%s: found X509 chain inside gss credential\n", logstr);
453
lcmaps_log(LOG_ERR,"%s: could not get X509 chain (exit voms)!\n", logstr);
457
lcmaps_log_debug(1,"%s: vomsdir = %s\n", logstr, vomsdir);
458
lcmaps_log_debug(1,"%s: certdir = %s\n", logstr, certdir);
459
if ((vd = VOMS_Init(vomsdir, certdir)) == NULL)
461
lcmaps_log(LOG_ERR,"%s: failed to initialize voms data structure. This may be because either the specified voms directory (%s) or the specified CA certificates directory (%s) does not exist\n", logstr, vomsdir, certdir);
464
lcmaps_log_debug(1,"%s: voms data structure initialized\n", logstr);
467
in = BIO_new(BIO_s_file());
468
chain = load_chain("/home/gridtest/cvs/fabric_mgt/gridification/lcmaps/modules/voms/x509up_u500");
471
if (BIO_read_filename(in, "/home/gridtest/cvs/fabric_mgt/gridification/lcmaps/modules/voms/x509up_u500") > 0)
473
x = PEM_read_bio_X509(in, NULL, 0, NULL);
475
res = VOMS_Retrieve(x, chain, RECURSE_CHAIN, vd, &err);
480
printf("%s: ERROR!\n", logstr);
486
printf("%s: err: %s\n", logstr, retmsg[err]);
489
if (VOMS_Retrieve(px509_cred, px509_chain, RECURSE_CHAIN,
493
lcmaps_vo_data_t * lcmaps_vo_data = NULL;
494
struct voms ** volist = vd->data;
496
char * bufptr = NULL;
500
lcmaps_log_debug(1,"%s: We got something, errNo = %d\n", logstr, errNo);
505
lcmaps_log_debug(1,"%s: setting voms data for VO == %s\n", logstr,
510
lcmaps_log_debug(1,"%s: NO DATA\n", logstr);
513
lcmaps_log_debug(1,"%s: %*s\n", logstr, vo->datalen - 10, vo->custom);
518
lcmaps_vo_data=lcmaps_createVoData(vo->voname,vo->std[j]->group,
519
NULL, vo->std[j]->role, vo->std[j]->cap
521
if (! lcmaps_vo_data)
523
lcmaps_log(LOG_ERR,"%s: could not create VoData structure (failure)\n", logstr);
526
// lcmaps_printVoData(2,lcmaps_vo_data);
527
if ( lcmaps_stringVoData(lcmaps_vo_data, voms_buffer, VOMS_BUFFER_SIZE) )
529
lcmaps_log(LOG_ERR,"%s: error in casting VoData structure into string (failure)\n", logstr);
532
// lcmaps_log_debug(1,"%s: buffer: %s\n", logstr, voms_buffer);
534
/* copy address of voms_buffer[0] in bufptr, because you cannot take the address of the array voms_buffer */
535
bufptr = voms_buffer;
536
addCredentialData(LCMAPS_VO_CRED_STRING, (void *) &bufptr);
537
addCredentialData(LCMAPS_VO_CRED, (void *) lcmaps_vo_data);
538
if ( lcmaps_deleteVoData(&lcmaps_vo_data) )
540
lcmaps_log(LOG_ERR,"%s: error while deleting VoData structure (failure)\n", logstr);
548
lcmaps_log_debug(1,"%s: doing VOMS_Destroy\n", logstr);
550
lcmaps_log_debug(1,"%s: done\n", logstr);
554
else if (errNo == VERR_NOEXT)
556
lcmaps_log(LOG_ERR,"%s: VOMS extensions missing from certificate (failure)!\n", logstr);
559
else if (errNo == VERR_IDCHECK)
561
lcmaps_log(LOG_ERR,"%s: VOMS User data in extension different from the real ones (failure)!\n", logstr);
564
else if (errNo == VERR_TIME)
566
lcmaps_log(LOG_ERR,"%s: VOMS extensions expired for at least one of the VOs (failure)!\n", logstr);
569
else if (errNo == VERR_ORDER)
571
lcmaps_log(LOG_ERR,"%s: The ordering of the VOMS groups, as required by the client, was not delivered by VOMS (failure)!\n", logstr);
574
else if (errNo == VERR_NOSOCKET)
576
lcmaps_log(LOG_ERR,"%s: VOMS Socket problem (failure)!\n", logstr);
579
else if (errNo == VERR_NOIDENT)
581
lcmaps_log(LOG_ERR,"%s: VOMS Cannot identify itself (certificate problem) (failure)!\n", logstr);
584
else if (errNo == VERR_COMM)
586
lcmaps_log(LOG_ERR,"%s: VOMS server problem (failure)!\n", logstr);
589
else if (errNo == VERR_PARAM)
591
lcmaps_log(LOG_ERR,"%s: Wrong parameters for VOMS (failure)!\n", logstr);
594
else if (errNo == VERR_NOINIT)
596
lcmaps_log(LOG_ERR,"%s: VOMS initialization error (failure)!\n", logstr);
599
else if (errNo == VERR_EXTRAINFO)
601
lcmaps_log(LOG_ERR,"%s: VO name and URI missing (in proxy ?) (failure)!\n", logstr);
604
else if (errNo == VERR_FORMAT)
606
lcmaps_log(LOG_ERR,"%s: Wrong VOMS data format (in proxy ?) (failure)!\n", logstr);
609
else if (errNo == VERR_NODATA)
611
lcmaps_log(LOG_ERR,"%s: Empty VOMS extension (failure)!\n", logstr);
614
else if (errNo == VERR_PARSE)
616
lcmaps_log(LOG_ERR,"%s: VOMS parse error (failure)!\n", logstr);
619
else if (errNo == VERR_DIR)
621
lcmaps_log(LOG_ERR,"%s: VOMS directory error (failure)!\n", logstr);
624
else if (errNo == VERR_SIGN)
626
lcmaps_log(LOG_ERR,"%s: VOMS Signature error (failure)!\n", logstr);
629
else if (errNo == VERR_SERVER)
631
lcmaps_log(LOG_ERR,"%s: Unidentifiable VOMS server (failure)!\n", logstr);
634
else if (errNo == VERR_MEM)
636
lcmaps_log(LOG_ERR,"%s: Memory problems in VOMS_Retrieve() (failure)!\n", logstr);
639
else if (errNo == VERR_VERIFY)
641
lcmaps_log(LOG_ERR,"%s: Generic verification error for VOMS (failure)!\n", logstr);
644
else if (errNo == VERR_TYPE)
646
lcmaps_log(LOG_ERR,"%s: Returned VOMS data of unknown type (failure)!\n", logstr);
651
lcmaps_log(LOG_ERR,"%s: VOMS_Retrieve() error --> %d (failure)!\n", logstr, errNo);
658
if (px509_cred) X509_free(px509_cred);
659
if (px509_chain) sk_X509_free(px509_chain);
660
lcmaps_log(LOG_INFO,"%s: voms plugin succeeded\n", logstr);
661
return LCMAPS_MOD_SUCCESS;
664
if (px509_cred) X509_free(px509_cred);
665
if (px509_chain) sk_X509_free(px509_chain);
666
lcmaps_log(LOG_INFO,"%s: voms plugin failed\n", logstr);
667
return LCMAPS_MOD_FAIL;
670
/******************************************************************************
671
Function: plugin_terminate
677
LCMAPS_MOD_SUCCESS : succes
678
LCMAPS_MOD_FAIL : failure
679
******************************************************************************/
680
int plugin_terminate()
682
char * logstr = "lcmaps_plugin_voms-plugin_terminate()";
683
lcmaps_log_debug(LOG_DEBUG,"%s: terminating\n", logstr);
684
if (vomsdir) free(vomsdir);
685
if (certdir) free(certdir);
687
return LCMAPS_MOD_SUCCESS;
690
static void print_vomsdata(struct vomsdata *d)
692
char * logstr = "lcmaps_plugin_voms-print_vomsdata()";
693
struct voms **vo = d->data;
701
lcmaps_log_debug(1,"%s: %d *******************************************\n", logstr,k);
702
lcmaps_log_debug(1,"%s: SIGLEN: %d\n", logstr, v->siglen);
703
lcmaps_log_a_string_debug(1, "lcmaps_plugin_voms-print_vomsdata(): USER: %s\n", v->user);
704
lcmaps_log_a_string_debug(1, "lcmaps_plugin_voms-print_vomsdata(): UCA: %s\n", v->userca);
705
lcmaps_log_a_string_debug(1, "lcmaps_plugin_voms-print_vomsdata(): SERVER: %s\n", v->server);
706
lcmaps_log_a_string_debug(1, "lcmaps_plugin_voms-print_vomsdata(): SCA: %s\n", v->serverca);
707
lcmaps_log_a_string_debug(1, "lcmaps_plugin_voms-print_vomsdata(): VO: %s\n", v->voname);
708
lcmaps_log_a_string_debug(1, "lcmaps_plugin_voms-print_vomsdata(): URI: %s\n", v->uri);
709
lcmaps_log_a_string_debug(1, "lcmaps_plugin_voms-print_vomsdata(): DATE1: %s\n", v->date1);
710
lcmaps_log_a_string_debug(1, "lcmaps_plugin_voms-print_vomsdata(): DATE2: %s\n", v->date2);
715
lcmaps_log_debug(1,"%s: NO DATA\n", logstr);
718
lcmaps_log_debug(1,"%s: VOMS custom type. Wont print.\n", logstr);
724
while ((v->fqan)[j] != NULL)
726
lcmaps_log_a_string_debug(1,
727
"lcmaps_plugin_voms-print_vomsdata(): fqan: %s\n",
737
lcmaps_log_a_string_debug(1,
738
"lcmaps_plugin_voms-print_vomsdata(): GROUP: %s\n", v->std[j]->group);
739
lcmaps_log_a_string_debug(1,
740
"lcmaps_plugin_voms-print_vomsdata(): ROLE: %s\n", v->std[j]->role);
741
lcmaps_log_a_string_debug(1,
742
"lcmaps_plugin_voms-print_vomsdata(): CAP: %s\n", v->std[j]->cap);
748
lcmaps_log_debug(1,"%s: %d *******************************************\n", logstr,k);
753
lcmaps_log_a_string_debug(1,
754
"lcmaps_plugin_voms-print_vomsdata(): WORKVO: %s\n", d->workvo);
759
lcmaps_log_a_string_debug(1,
760
"lcmaps_plugin_voms-print_vomsdata(): EXTRA: %s\n", d->extra_data);
764
/******************************************************************************
766
$Source: /srv/home/dennisvd/svn/mw-security/lcmaps-plugins-voms/src/voms/lcmaps_voms.c,v $
767
$Date: 2010-02-19 06:01:37 $
770
******************************************************************************/