From 6f70540d0a77c18a76106edccb5deeb3f6abc33b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Kou=C5=99il?= Date: Fri, 4 Mar 2011 11:31:03 +0000 Subject: [PATCH] Merged code from proper branch of security.proxyrenewal --- org.glite.px.proxyrenewal/LICENSE | 78 +---- org.glite.px.proxyrenewal/Makefile | 35 +-- org.glite.px.proxyrenewal/config/startup | 16 + org.glite.px.proxyrenewal/examples/renew_core.c | 18 ++ org.glite.px.proxyrenewal/interface/renewal.h | 24 +- org.glite.px.proxyrenewal/interface/renewal_core.h | 31 ++ org.glite.px.proxyrenewal/src/api.c | 18 ++ org.glite.px.proxyrenewal/src/client.c | 18 ++ org.glite.px.proxyrenewal/src/commands.c | 335 +++++++++++---------- org.glite.px.proxyrenewal/src/common.c | 18 ++ org.glite.px.proxyrenewal/src/renew.c | 48 ++- org.glite.px.proxyrenewal/src/renewal_core.c | 135 +++++++-- org.glite.px.proxyrenewal/src/renewal_locl.h | 19 +- org.glite.px.proxyrenewal/src/renewd.c | 89 +++--- org.glite.px.proxyrenewal/src/renewd_locl.h | 34 ++- org.glite.px.proxyrenewal/src/voms.c | 288 ++++++++++++------ 16 files changed, 766 insertions(+), 438 deletions(-) diff --git a/org.glite.px.proxyrenewal/LICENSE b/org.glite.px.proxyrenewal/LICENSE index 01b973b..4a9c73d 100644 --- a/org.glite.px.proxyrenewal/LICENSE +++ b/org.glite.px.proxyrenewal/LICENSE @@ -1,69 +1,15 @@ -LICENSE file for EGEE Middleware -================================ +Copyright (c) Members of the EGEE Collaboration. 2004-2010. +See http://www.eu-egee.org/partners/ for details on the copyright +holders. -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/org.glite.px.proxyrenewal/Makefile b/org.glite.px.proxyrenewal/Makefile index fae97b3..62902f6 100644 --- a/org.glite.px.proxyrenewal/Makefile +++ b/org.glite.px.proxyrenewal/Makefile @@ -1,25 +1,18 @@ +# Copyright (c) Members of the EGEE Collaboration. 2004-2010. +# See http://www.eu-egee.org/partners/ for details on the copyright +# holders. # -# Copyright (c) 2004 on behalf of the EU EGEE Project: -# The European Organization for Nuclear Research (CERN), -# Istituto Nazionale di Fisica Nucleare (INFN), Italy -# Datamat Spa, Italy -# Centre National de la Recherche Scientifique (CNRS), France -# CS Systeme d'Information (CSSI), France -# Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -# Universiteit van Amsterdam (UvA), Netherlands -# University of Helsinki (UH.HIP), Finland -# University of Bergen (UiB), Norway -# Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at # -# Top Makefile file for the GLite Security Proxyrenewal module -# -# Authors: Ales Krenek -# Version info: $Id$ -# Release: $Name$ -# -# Revision history: -# $Log +# http://www.apache.org/licenses/LICENSE-2.0 # +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. # defaults top_srcdir=.. @@ -38,6 +31,7 @@ sysconfdir=/opt/glite/etc glite_location=${PREFIX}${prefix} globus_prefix=/opt/globus +voms_prefix=${glite_location} -include Makefile.inc @@ -46,8 +40,7 @@ VPATH:=${top_srcdir}/src:${top_srcdir}/examples GLOBUS_NOTHR_INC:= -I${globus_prefix}/include/${nothrflavour} GLOBUS_THR_INC:= -I${globus_prefix}/include/${thrflavour} GLOBUS_NOTHR_LIBS:=-L${globus_prefix}/lib \ - -lglobus_common_${nothrflavour} \ - -lssl + -lglobus_common_${nothrflavour} myproxy_prefix=${myproxy-devel_prefix} myproxy_prefix?=${globus_prefix} diff --git a/org.glite.px.proxyrenewal/config/startup b/org.glite.px.proxyrenewal/config/startup index 1667085..f141908 100755 --- a/org.glite.px.proxyrenewal/config/startup +++ b/org.glite.px.proxyrenewal/config/startup @@ -1,4 +1,20 @@ #!/bin/sh +# +# Copyright (c) Members of the EGEE Collaboration. 2004-2010. +# See http://www.eu-egee.org/partners/ for details on the copyright +# holders. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. GLITE_PX_LOCATION=${GLITE_PX_LOCATION:-/opt/glite} GLITE_PX_LOCATION_VAR=${GLITE_PX_LOCATION_VAR:-/opt/glite/var} diff --git a/org.glite.px.proxyrenewal/examples/renew_core.c b/org.glite.px.proxyrenewal/examples/renew_core.c index 69518ea..e0ba537 100644 --- a/org.glite.px.proxyrenewal/examples/renew_core.c +++ b/org.glite.px.proxyrenewal/examples/renew_core.c @@ -1,3 +1,21 @@ +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include #include #include diff --git a/org.glite.px.proxyrenewal/interface/renewal.h b/org.glite.px.proxyrenewal/interface/renewal.h index e07a89f..e494134 100644 --- a/org.glite.px.proxyrenewal/interface/renewal.h +++ b/org.glite.px.proxyrenewal/interface/renewal.h @@ -1,13 +1,19 @@ -/** - * \file proxyrenewal/renewal.h - * \author Daniel Kouril - * \author Miroslav Ruda - * \brief API for proxy renewal. - * \version 2.0 +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 * - * General rules: - * - functions return 0 on success, nonzero on error, errror details can - * be found via edg_wlpr_GetErrorText() + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ #ifndef RENEWAL_H diff --git a/org.glite.px.proxyrenewal/interface/renewal_core.h b/org.glite.px.proxyrenewal/interface/renewal_core.h index 8348963..20f174a 100644 --- a/org.glite.px.proxyrenewal/interface/renewal_core.h +++ b/org.glite.px.proxyrenewal/interface/renewal_core.h @@ -1,3 +1,21 @@ +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef RENEWAL_CORE_H #define RENEWAL_CORE_H @@ -20,6 +38,7 @@ typedef struct glite_renewal_core_context_data { glite_renewal_log_dst log_dst; char *err_message; char *voms_conf; + int order_attributes; } glite_renewal_core_context_data; typedef struct glite_renewal_core_context_data *glite_renewal_core_context; @@ -55,6 +74,18 @@ glite_renewal_core_renew(glite_renewal_core_context context, const char *current_proxy, char **new_proxy); +void +glite_renewal_core_set_err(glite_renewal_core_context ctx, const char *format, ...); + +void +glite_renewal_core_update_err(glite_renewal_core_context ctx, const char *format, ...); + +char * +glite_renewal_core_get_err(glite_renewal_core_context ctx); + +void +glite_renewal_core_reset_err(glite_renewal_core_context ctx); + #ifdef __cplusplus } #endif diff --git a/org.glite.px.proxyrenewal/src/api.c b/org.glite.px.proxyrenewal/src/api.c index a72d692..ac092c8 100644 --- a/org.glite.px.proxyrenewal/src/api.c +++ b/org.glite.px.proxyrenewal/src/api.c @@ -1,3 +1,21 @@ +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "renewal.h" #include "renewal_locl.h" diff --git a/org.glite.px.proxyrenewal/src/client.c b/org.glite.px.proxyrenewal/src/client.c index 87efd78..4ef0984 100644 --- a/org.glite.px.proxyrenewal/src/client.c +++ b/org.glite.px.proxyrenewal/src/client.c @@ -1,3 +1,21 @@ +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include #include #include diff --git a/org.glite.px.proxyrenewal/src/commands.c b/org.glite.px.proxyrenewal/src/commands.c index 9ffe90b..e38ae0c 100644 --- a/org.glite.px.proxyrenewal/src/commands.c +++ b/org.glite.px.proxyrenewal/src/commands.c @@ -1,3 +1,21 @@ +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "renewal_locl.h" #include "renewd_locl.h" @@ -11,8 +29,6 @@ extern char *repository; extern time_t condor_limit; -extern char *cadir; -extern char *vomsdir; extern int voms_enabled; static char * @@ -64,9 +80,6 @@ record_to_response(glite_renewal_core_context ctx, int status_code, proxy_record static int filename_to_response(glite_renewal_core_context ctx, char *filename, edg_wlpr_Response *response); - - - static char * strmd5(glite_renewal_core_context ctx, const char *s, unsigned char *digest) { @@ -100,7 +113,7 @@ get_base_filename(glite_renewal_core_context ctx, char *proxy_file, char **basef assert(basefilename != NULL); - ret = glite_renewal_get_proxy_base_name(ctx, proxy_file, &subject); + ret = get_proxy_base_name(ctx, proxy_file, &subject); if (ret) goto end; @@ -124,12 +137,12 @@ copy_file_content(glite_renewal_core_context ctx, FILE *in, FILE *out) while (1) { num = fread(buf, sizeof(*buf), sizeof(buf), in); if ((ret = ferror(in))) { - glite_renewal_log(ctx, LOG_ERR, "Reading failed: %s", strerror(errno)); + glite_renewal_core_set_err(ctx, "Reading failed: %s", strerror(errno)); return ret; } num = fwrite(buf, sizeof(*buf), num, out); if ((ret = ferror(in))) { - glite_renewal_log(ctx, LOG_ERR, "Writing failed: %s", strerror(errno)); + glite_renewal_core_set_err(ctx, "Writing failed: %s", strerror(errno)); return ret; } if (feof(in)) @@ -139,7 +152,7 @@ copy_file_content(glite_renewal_core_context ctx, FILE *in, FILE *out) /* return the time interval, after which the renewal should be started */ static time_t -get_delta(glite_renewal_core_context ctx, time_t current_time, time_t start_time, time_t end_time) +get_delta(glite_renewal_core_context ctx, time_t current_time, time_t end_time) { time_t remaining_life; time_t life_to_lose; @@ -154,15 +167,9 @@ get_delta(glite_renewal_core_context ctx, time_t current_time, time_t start_time limit += RENEWAL_CLOCK_SKEW; - if (current_time + limit >= end_time) { - /* if the proxy is too short, renew it as soon as possible */ - - if (current_time + condor_limit > end_time ) { - glite_renewal_log(ctx, LOG_ERR, "Remaining proxy lifetime fell below the value of the Condor limit!"); - } - + /* if the proxy is too short, renew it as soon as possible */ + if (current_time + limit >= end_time) return 0; - } remaining_life = end_time - current_time; @@ -198,79 +205,115 @@ get_delta(glite_renewal_core_context ctx, time_t current_time, time_t start_time int get_times(glite_renewal_core_context ctx, char *proxy_file, proxy_record *record) { - FILE *fd; X509 *cert = NULL; - ASN1_UTCTIME *asn1_time = NULL; - int ret; - time_t current_time, start_time, end_time; - - assert(record != NULL); - assert(proxy_file != NULL); + STACK_OF(X509) *chain = NULL; + int ret, i; + time_t now, end_time, end_time_x509; + struct vomsdata *voms_data = NULL; + struct voms **voms_cert = NULL; + ASN1_UTCTIME *t; + time_t delta; + char *s, *c; - fd = fopen(proxy_file, "r"); - if (fd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Opening proxy file %s failed: %s", - proxy_file, strerror(errno)); - return errno; - } + ret = load_proxy(ctx, proxy_file, &cert, NULL, &chain, NULL); + if (ret) + return ret; - cert = PEM_read_X509(fd, NULL, NULL, NULL); - if (cert == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot read X.509 certificate from %s", - proxy_file); - ret = -1; /* XXX SSL_ERROR */ + ret = get_voms_cert(ctx, cert, chain, &voms_data); + if (ret) goto end; + + end_time = 0; + if (voms_data != NULL) { + for (voms_cert = voms_data->data; voms_cert && *voms_cert; voms_cert++) { + t = ASN1_UTCTIME_new(); + if (t == NULL) { + glite_renewal_core_set_err(ctx, "ASN1_UTCTIME_new() failed"); + ret = 1; + goto end; + } + + /* date2 contains a GENERALIZEDTIME format (YYYYMMDDHHSS[.fff]Z) + * value, which must be converted to the UTC (YYMMDDHHSSZ) format */ + s = strdup((*voms_cert)->date2 + 2); + if (s == NULL) { + glite_renewal_core_set_err(ctx, "Not enough memory"); + ret = ENOMEM; + goto end; + } + c = strchr(s, '.'); + if (c) { + *c++ = 'Z'; + *c = '\0'; + } + ret = ASN1_UTCTIME_set_string(t, s); + if (ret == 0) { + glite_renewal_core_set_err(ctx, "ASN1_UTCTIME_set_string() failed\n"); + ret = 1; + free(s); + goto end; + } + + if (end_time == 0 || ASN1_UTCTIME_cmp_time_t(t, end_time) < 0) + globus_gsi_cert_utils_make_time(t, &end_time); + + ASN1_UTCTIME_free(t); + free(s); + } + s = ctime(&end_time); + if ((c = strchr(s, '\n'))) + *c = '\0'; + edg_wlpr_Log(ctx, LOG_DEBUG, + "The shortest VOMS cert expires on %s", s); } - asn1_time = ASN1_UTCTIME_new(); - X509_gmtime_adj(asn1_time,0); - globus_gsi_cert_utils_make_time(X509_get_notAfter(cert), &end_time); - globus_gsi_cert_utils_make_time(X509_get_notBefore(cert), &start_time); - current_time = time(NULL); - ASN1_UTCTIME_free(asn1_time); - /* if (end_time - RENEWAL_CLOCK_SKEW < current_time) { Too short proxy } */ - if (end_time + RENEWAL_CLOCK_SKEW < current_time) { - glite_renewal_log(ctx, LOG_ERR, "Expired proxy in %s", proxy_file); + globus_gsi_cert_utils_make_time(X509_get_notAfter(cert), &end_time_x509); + if (end_time_x509 < end_time || end_time == 0) + end_time = end_time_x509; + + s = ctime(&end_time_x509); + if ((c = strchr(s, '\n'))) + *c = '\0'; + edg_wlpr_Log(ctx, LOG_DEBUG, "X.509 proxy credential expires on %s", s); + + now = time(NULL); + if (end_time_x509 + RENEWAL_CLOCK_SKEW < now) { + glite_renewal_core_set_err(ctx, "Expired proxy in %s", proxy_file); ret = EDG_WLPR_PROXY_EXPIRED; goto end; } /* Myproxy seems not to do check on expiration and return expired proxies if credentials in repository are expired */ - X509_free(cert); - cert = NULL; - while (1) { - time_t tmp_end; - /* see http://www.openssl.org/docs/crypto/pem.html section BUGS */ - cert = PEM_read_X509(fd, NULL, NULL, NULL); - if (cert == NULL) { - if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) { - /* End of file reached. no error */ - ERR_clear_error(); - break; - } - glite_renewal_log(ctx, LOG_ERR, "Cannot read additional certificates from %s", - proxy_file); - ret = -1; /* XXX SSL_ERROR */ - goto end; - } - globus_gsi_cert_utils_make_time(X509_get_notAfter(cert), &tmp_end); - if (tmp_end + RENEWAL_CLOCK_SKEW < current_time) { - glite_renewal_log(ctx, LOG_ERR, "Expired proxy in %s", proxy_file); - ret = EDG_WLPR_PROXY_EXPIRED; - goto end; + for (i = 0; i < sk_X509_num(chain); i++) { + t = X509_get_notAfter(sk_X509_value(chain, i)); + if (ASN1_UTCTIME_cmp_time_t(t, now - RENEWAL_CLOCK_SKEW) < 0) { + glite_renewal_core_set_err(ctx, "Expired proxy in %s", proxy_file); + ret = EDG_WLPR_PROXY_EXPIRED; + goto end; } - X509_free(cert); - cert = NULL; } - record->next_renewal = current_time + get_delta(ctx, current_time, start_time, - end_time); - record->end_time = end_time; + if (now + condor_limit > end_time_x509) { + edg_wlpr_Log(ctx, LOG_WARNING, "Remaining proxy lifetime fell below the value of the Condor limit!"); + delta = 0; + } else + delta = get_delta(ctx, now, end_time); + + record->next_renewal = now + delta; + record->end_time = end_time_x509; ret = 0; + s = ctime(&record->next_renewal); + if ((c = strchr(s, '\n'))) + *c = '\0'; + edg_wlpr_Log(ctx, LOG_DEBUG, "Next renewal will be attempted on %s", s); + end: - fclose(fd); + if (voms_data) + VOMS_Destroy(voms_data); + if (chain) + sk_X509_pop_free(chain, X509_free); if (cert) X509_free(cert); @@ -291,16 +334,16 @@ copy_file(glite_renewal_core_context ctx, char *src, char *dst) from = fopen(src, "r"); if (from == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open file %s for reading (%s)", - src, strerror(errno)); + glite_renewal_core_set_err(ctx, "Cannot open file %s for reading (%s)", + src, strerror(errno)); return errno; } snprintf(tmpfile, sizeof(tmpfile), "%s.XXXXXX", dst); tmp_fd = mkstemp(tmpfile); if (tmp_fd == -1) { - glite_renewal_log(ctx, LOG_ERR, "Cannot create temporary file (%s)", - strerror(errno)); + glite_renewal_core_set_err(ctx, "Cannot create temporary file (%s)", + strerror(errno)); ret = errno; goto end; } @@ -308,8 +351,8 @@ copy_file(glite_renewal_core_context ctx, char *src, char *dst) tmp_to = fdopen(tmp_fd, "w"); if (tmp_to == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot associate stream with temporary file (%s)", - strerror(errno)); + glite_renewal_core_set_err(ctx, "Cannot associate stream with temporary file (%s)", + strerror(errno)); unlink(tmpfile); ret = errno; goto end; @@ -323,7 +366,7 @@ copy_file(glite_renewal_core_context ctx, char *src, char *dst) ret = rename(tmpfile, dst); if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Cannot replace repository file %s with temporary file (%s)", + glite_renewal_core_set_err(ctx, "Cannot replace repository file %s with temporary file (%s)", strerror(errno)); unlink(tmpfile); ret = errno; @@ -533,7 +576,7 @@ get_record_ext(glite_renewal_core_context ctx, FILE *fd, proxy_record *record, i *p = '\0'; ret = decode_record(ctx, line, &tmp_record); if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Skipping invalid entry at line %d", line_num); + edg_wlpr_Log(ctx, LOG_WARNING, "Skipping invalid entry at line %d", line_num); continue; } if (record->suffix >= 0) { @@ -607,7 +650,7 @@ get_record_ext(glite_renewal_core_context ctx, FILE *fd, proxy_record *record, i *last_used_suffix = last_suffix; if (record->suffix >= 0) { - glite_renewal_log(ctx, LOG_DEBUG, "Requested suffix %d not found in meta file", + edg_wlpr_Log(ctx, LOG_DEBUG, "Requested suffix %d not found in meta file", record->suffix); } @@ -661,7 +704,7 @@ store_record(glite_renewal_core_context ctx, char *basename, proxy_record *recor *p = '\0'; ret = decode_record(ctx, line, &tmp_record); if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Removing invalid entry at line %d in %s", line_num, basename); + edg_wlpr_Log(ctx, LOG_WARNING, "Removing invalid entry at line %d in %s", line_num, basename); continue; } if (record->suffix == tmp_record.suffix && @@ -725,13 +768,12 @@ open_metafile(glite_renewal_core_context ctx, char *basename, FILE **fd) snprintf(meta_filename, sizeof(meta_filename), "%s.data", basename); meta_fd = fopen(meta_filename, "a+"); if (meta_fd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Opening meta file %s failed (%s)", + glite_renewal_core_set_err(ctx, "Opening meta file %s failed (%s)", meta_filename, strerror(errno)); return errno; } rewind(meta_fd); *fd = meta_fd; - glite_renewal_log(ctx, LOG_DEBUG, "Using meta file %s", meta_filename); return 0; } @@ -740,12 +782,12 @@ filename_to_response(glite_renewal_core_context ctx, char *filename, edg_wlpr_Re { response->filenames = malloc(2 * sizeof(*response->filenames)); if (response->filenames == NULL) { - glite_renewal_log(ctx, LOG_DEBUG, "Not enough memory"); + edg_wlpr_Log(ctx, LOG_DEBUG, "Not enough memory"); return errno; } response->filenames[0] = strdup(filename); if (response->filenames[0] == NULL) { - glite_renewal_log(ctx, LOG_DEBUG, "Not enough memory"); + edg_wlpr_Log(ctx, LOG_DEBUG, "Not enough memory"); free(response->filenames); return errno; } @@ -789,7 +831,7 @@ check_proxyname(glite_renewal_core_context ctx, char *datafile, char *jobid, cha meta_fd = fopen(datafile, "r"); if (meta_fd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open meta file %s (%s)", + glite_renewal_core_set_err(ctx, "Cannot open meta file %s (%s)", datafile, strerror(errno)); return errno; } @@ -830,7 +872,7 @@ find_proxyname(glite_renewal_core_context ctx, char *jobid, char **filename) dir = opendir(repository); if (dir == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open repository directory %s (%s)", + glite_renewal_core_set_err(ctx, "Cannot open repository directory %s (%s)", repository, strerror(errno)); return errno; } @@ -848,55 +890,10 @@ find_proxyname(glite_renewal_core_context ctx, char *jobid, char **filename) } } closedir(dir); - glite_renewal_log(ctx, LOG_ERR, "Requested proxy is not registered"); + glite_renewal_core_set_err(ctx, "Requested proxy is not registered"); return EDG_WLPR_PROXY_NOT_REGISTERED; } -#ifdef NOVOMS -int -find_voms_cert(glite_renewal_core_context ctx, char *file, int *present) -{ - *present = 0; - return 0; -} - -#else -int -find_voms_cert(glite_renewal_core_context ctx, char *file, int *present) -{ - struct vomsdata *voms_info = NULL; - STACK_OF(X509) *chain = NULL; - EVP_PKEY *privkey = NULL; - X509 *cert = NULL; - int ret, err; - - *present = 0; - - voms_info = VOMS_Init(vomsdir, cadir); - if (voms_info == NULL) { - glite_renewal_log(ctx, LOG_ERR, "check_voms_cert(): Cannot initialize VOMS context (VOMS_Init() failed, probably voms dir was not specified)"); - return EDG_WLPR_ERROR_VOMS; - } - - ret = glite_renewal_load_proxy(ctx, file, &cert, &privkey, &chain, NULL); - if (ret) { - VOMS_Destroy(voms_info); - return ret; - } - - ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, voms_info, &err); - if (ret == 1) { - *present = 1; - } - - VOMS_Destroy(voms_info); - X509_free(cert); - EVP_PKEY_free(privkey); - sk_X509_pop_free(chain, X509_free); - return 0; -} -#endif - void register_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Response *response) { @@ -912,13 +909,15 @@ register_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wl memset(&record, 0, sizeof(record)); memset(response, 0, sizeof(*response)); - glite_renewal_log(ctx, LOG_DEBUG, "Registration request for %s", request->proxy_filename); if (request->proxy_filename == NULL || request->jobid == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Registration request doesn't contain registration information"); + edg_wlpr_Log(ctx, LOG_ERR, "Registration request doesn't contain registration information"); return; /* EINVAL; */ } - umask(0177); + + edg_wlpr_Log(ctx, LOG_DEBUG, + "Registering proxy from %s belonging to job %s", + request->proxy_filename, request->jobid); ret = get_base_filename(ctx, request->proxy_filename, &basename); if (ret) @@ -929,7 +928,7 @@ register_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wl goto end; if (voms_enabled) - ret = find_voms_cert(ctx, request->proxy_filename, &record.voms_exts); + ret = is_voms_cert(ctx, request->proxy_filename, &record.voms_exts); /* ignore VOMS related error */ /* Find first free record */ @@ -959,7 +958,7 @@ register_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wl goto end; record.jobids.val[record.jobids.len - 1] = strdup(request->jobid); record.unique = request->unique; - glite_renewal_log(ctx, LOG_DEBUG, "Created a new proxy file in repository (%s)", + edg_wlpr_Log(ctx, LOG_DEBUG, "Created a new proxy file in repository (%s)", filename); } else { ret = realloc_prd_list(ctx, &record.jobids); @@ -967,7 +966,7 @@ register_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wl goto end; record.jobids.val[record.jobids.len - 1] = strdup(request->jobid); snprintf(filename, sizeof(filename), "%s.%d", basename, record.suffix); - glite_renewal_log(ctx, LOG_DEBUG, "Inremented counter on %s", filename); + edg_wlpr_Log(ctx, LOG_DEBUG, "Inremented counter on %s", filename); } ret = store_record(ctx, basename, &record); @@ -980,8 +979,16 @@ end: if (basename) free(basename); - if (ret == 0) + if (ret == 0) { ret = filename_to_response(ctx, filename, response); + edg_wlpr_Log(ctx, LOG_INFO, + "Proxy %s of job %s has been registered as %s", + request->proxy_filename, request->jobid, filename); + } else + edg_wlpr_Log(ctx, LOG_ERR, "Failed to register proxy %s: %s", + request->proxy_filename, + glite_renewal_core_get_err(ctx)); + record_to_response(ctx, ret, &record, response); free_record(ctx, &record); } @@ -997,14 +1004,16 @@ unregister_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_ struct stat stat_buf; memset(&record, 0, sizeof(record)); - glite_renewal_log(ctx, LOG_DEBUG, "Unregistration request for %s", request->jobid); if (request->jobid == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Unregistration request doesn't contain needed information"); + glite_renewal_core_set_err(ctx, "Request doesn't specify jobid"); ret = EINVAL; goto end; } + edg_wlpr_Log(ctx, LOG_DEBUG, "Unregistrating proxy of job %s", + request->jobid); + if (request->proxy_filename == NULL) { ret = find_proxyname(ctx, request->jobid, &request->proxy_filename); if (ret) @@ -1017,7 +1026,7 @@ unregister_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_ } if (strncmp(request->proxy_filename, basename, strlen(basename) != 0)) { - glite_renewal_log(ctx, LOG_DEBUG, "Requested proxy %s is not from repository", + edg_wlpr_Log(ctx, LOG_DEBUG, "Requested proxy %s is not from repository", request->proxy_filename); ret = EDG_WLPR_PROXY_NOT_REGISTERED; goto end; @@ -1025,7 +1034,7 @@ unregister_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_ p = strrchr(request->proxy_filename, '.'); if (p == NULL) { - glite_renewal_log(ctx, LOG_DEBUG, "Requested proxy %s is not from repository", + edg_wlpr_Log(ctx, LOG_DEBUG, "Requested proxy %s is not from repository", request->proxy_filename); ret = EDG_WLPR_PROXY_NOT_REGISTERED; goto end; @@ -1033,7 +1042,7 @@ unregister_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_ ret = edg_wlpr_DecodeInt(p+1, &record.suffix); if (ret) { - glite_renewal_log(ctx, LOG_DEBUG, "Requested proxy %s is not from repository", + edg_wlpr_Log(ctx, LOG_DEBUG, "Requested proxy %s is not from repository", request->proxy_filename); ret = EDG_WLPR_PROXY_NOT_REGISTERED; goto end; @@ -1056,7 +1065,7 @@ unregister_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_ break; } if (ret) { - glite_renewal_log(ctx, LOG_DEBUG, "Requested proxy %s is not registered", + edg_wlpr_Log(ctx, LOG_DEBUG, "Requested proxy %s is not registered", request->proxy_filename); goto end; } @@ -1077,7 +1086,7 @@ unregister_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_ ret = stat(request->proxy_filename, &stat_buf); if (ret) { - glite_renewal_log(ctx, LOG_DEBUG, "Cannot stat file %s: (%s)", + edg_wlpr_Log(ctx, LOG_DEBUG, "Cannot stat file %s: (%s)", request->proxy_filename, strerror(errno)); ret = errno; goto end; @@ -1097,8 +1106,19 @@ end: if (basename) free(basename); - if (ret == 0) + if (ret == 0) { ret = filename_to_response(ctx, request->proxy_filename, response); + edg_wlpr_Log(ctx, LOG_INFO, + "Proxy %s of job %s has been unregistered", + request->proxy_filename, request->jobid); + } + else + edg_wlpr_Log(ctx, LOG_ERR, + "Failed to unregister proxy %s of job %s: %s", + (request->proxy_filename) ? request->proxy_filename : "'(null)'", + (request->jobid) ? request->jobid : "'(null)'", + glite_renewal_core_get_err(ctx)); + record_to_response(ctx, ret, &record, response); free_record(ctx, &record); } @@ -1111,10 +1131,10 @@ get_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Re memset(response, 0, sizeof(*response)); - glite_renewal_log(ctx, LOG_DEBUG, "GET request for %s", request->jobid); + edg_wlpr_Log(ctx, LOG_DEBUG, "GET request for %s", request->jobid); if (request->jobid == NULL) { - glite_renewal_log(ctx, LOG_ERR, "GET request doesn't contain jobid specification"); + glite_renewal_core_set_err(ctx, "Request doesn't contain jobid specification"); ret = EINVAL; goto end; } @@ -1124,6 +1144,10 @@ get_proxy(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Re end: if (ret == 0) ret = filename_to_response(ctx, filename, response); + else + edg_wlpr_Log(ctx, LOG_ERR, "Failed to register proxy %s: %s", + request->proxy_filename, + glite_renewal_core_get_err(ctx)); if (filename) free(filename); response->response_code = ret; @@ -1149,7 +1173,7 @@ update_db(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Re memset(&record, 0, sizeof(record)); - glite_renewal_log(ctx, LOG_DEBUG, "UPDATE_DB request for %s", request->proxy_filename); + edg_wlpr_Log(ctx, LOG_DEBUG, "UPDATE_DB request for %s", request->proxy_filename); chdir(repository); basename = request->proxy_filename; @@ -1157,7 +1181,7 @@ update_db(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Re snprintf(datafile, sizeof(datafile), "%s.data", basename); fd = fopen(datafile, "r"); if (fd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open meta file %s (%s)", + edg_wlpr_Log(ctx, LOG_ERR, "Cannot open meta file %s (%s)", datafile, strerror(errno)); ret = errno; return; @@ -1166,7 +1190,7 @@ update_db(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Re snprintf(tmp_file, sizeof(tmp_file), "%s.XXXXXX", datafile); tmp_fd = mkstemp(tmp_file); if (tmp_fd < 0) { - glite_renewal_log(ctx, LOG_ERR, "Cannot create temporary file (%s)", + edg_wlpr_Log(ctx, LOG_ERR, "Cannot create temporary file (%s)", strerror(errno)); ret = errno; goto end; @@ -1218,7 +1242,7 @@ update_db(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Re free_record(ctx, &record); record.suffix = suffix; record.myproxy_server = server; - glite_renewal_log(ctx, LOG_WARNING, "Removed expired proxy %s", cur_proxy); + edg_wlpr_Log(ctx, LOG_WARNING, "Removed expired proxy %s", cur_proxy); } else get_times(ctx, cur_proxy, &record); } else { @@ -1226,6 +1250,7 @@ update_db(glite_renewal_core_context ctx, edg_wlpr_Request *request, edg_wlpr_Re (ret == 0) ? rename(proxy, cur_proxy) : unlink(proxy); } } + glite_renewal_core_reset_err(ctx); ret = encode_record(ctx, &record, &new_line); if (ret) diff --git a/org.glite.px.proxyrenewal/src/common.c b/org.glite.px.proxyrenewal/src/common.c index 206bc2f..70daeb0 100644 --- a/org.glite.px.proxyrenewal/src/common.c +++ b/org.glite.px.proxyrenewal/src/common.c @@ -1,3 +1,21 @@ +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "renewal_locl.h" #ident "$Header$" diff --git a/org.glite.px.proxyrenewal/src/renew.c b/org.glite.px.proxyrenewal/src/renew.c index 1c34ff7..8b45a70 100644 --- a/org.glite.px.proxyrenewal/src/renew.c +++ b/org.glite.px.proxyrenewal/src/renew.c @@ -1,3 +1,21 @@ +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "renewal_locl.h" #include "renewd_locl.h" @@ -58,9 +76,14 @@ renew_proxy(glite_renewal_core_context ctx, proxy_record *record, char *basename } ret = glite_renewal_core_renew(ctx, server, port, repository_file, new_proxy); - if (ret) + if (ret) { + edg_wlpr_Log(ctx, LOG_ERR, "Failed to renew proxy %s: %s", + repository_file, + glite_renewal_core_get_err(ctx)); goto end; + } + edg_wlpr_Log(ctx, LOG_DEBUG, "Proxy %s succesfully renewed", repository_file); ret = 0; end: @@ -99,7 +122,7 @@ check_renewal(glite_renewal_core_context ctx, char *datafile, int force_renew, i strncpy(basename, datafile, sizeof(basename) - 1); p = basename + strlen(basename) - strlen(".data"); if (strcmp(p, ".data") != 0) { - glite_renewal_log(ctx, LOG_ERR, "Meta filename doesn't end with '.data'"); + edg_wlpr_Log(ctx, LOG_ERR, "Meta filename doesn't end with '.data'"); return; } *p = '\0'; @@ -109,15 +132,15 @@ check_renewal(glite_renewal_core_context ctx, char *datafile, int force_renew, i meta_fd = fopen(datafile, "r"); if (meta_fd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open meta file %s (%s)", + edg_wlpr_Log(ctx, LOG_ERR, "Cannot open meta file %s (%s)", datafile, strerror(errno)); return; } current_time = time(NULL); - glite_renewal_log(ctx, LOG_DEBUG, "Reading metafile %s", datafile); while (fgets(line, sizeof(line), meta_fd) != NULL) { + glite_renewal_core_reset_err(ctx); free_record(ctx, &record); p = strchr(line, '\n'); if (p) @@ -158,10 +181,10 @@ check_renewal(glite_renewal_core_context ctx, char *datafile, int force_renew, i if (num > 0) { ret = edg_wlpr_RequestSend(&request, &response); if (ret != 0) - glite_renewal_log(ctx, LOG_ERR, + edg_wlpr_Log(ctx, LOG_ERR, "Failed to send update request to master (%d)", ret); else if (response.response_code != 0) - glite_renewal_log(ctx, LOG_ERR, + edg_wlpr_Log(ctx, LOG_ERR, "Master failed to update database (%d)", response.response_code); /* delete all tmp proxy files which may survive */ @@ -188,19 +211,17 @@ int renewal(glite_renewal_core_context ctx, int force_renew, int *num_renewed) FILE *fd; int num = 0; - glite_renewal_log(ctx, LOG_DEBUG, "Starting renewal process"); - *num_renewed = 0; if (chdir(repository)) { - glite_renewal_log(ctx, LOG_ERR, "Cannot access repository directory %s (%s)", + edg_wlpr_Log(ctx, LOG_ERR, "Cannot access repository directory %s (%s)", repository, strerror(errno)); return errno; } dir = opendir(repository); if (dir == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open repository directory %s (%s)", + edg_wlpr_Log(ctx, LOG_ERR, "Cannot open repository directory %s (%s)", repository, strerror(errno)); return errno; } @@ -213,7 +234,7 @@ int renewal(glite_renewal_core_context ctx, int force_renew, int *num_renewed) continue; fd = fopen(file->d_name, "r"); if (fd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Cannot open meta file %s (%s)", + edg_wlpr_Log(ctx, LOG_ERR, "Cannot open meta file %s (%s)", file->d_name, strerror(errno)); continue; } @@ -222,7 +243,8 @@ int renewal(glite_renewal_core_context ctx, int force_renew, int *num_renewed) fclose(fd); } closedir(dir); - glite_renewal_log(ctx, LOG_DEBUG, "Finishing renewal process"); + edg_wlpr_Log(ctx, LOG_DEBUG, + "Renewal attempt finished, %u proxies renewed", *num_renewed); return 0; } @@ -251,6 +273,6 @@ watchdog_start(glite_renewal_core_context ctx) renewal(ctx, force_renewal, &num); count += num; } - glite_renewal_log(ctx, LOG_DEBUG, "Terminating after %d renewal attempts", count); + edg_wlpr_Log(ctx, LOG_DEBUG, "Terminating after %d renewal attempts", count); exit(0); } diff --git a/org.glite.px.proxyrenewal/src/renewal_core.c b/org.glite.px.proxyrenewal/src/renewal_core.c index 3bd2d1d..7852b14 100644 --- a/org.glite.px.proxyrenewal/src/renewal_core.c +++ b/org.glite.px.proxyrenewal/src/renewal_core.c @@ -1,3 +1,21 @@ +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include #include @@ -8,7 +26,7 @@ static const char rcsid[] = "$Id$"; int -glite_renewal_load_proxy(glite_renewal_core_context ctx, const char *cur_file, X509 **cert, EVP_PKEY **priv_key, +load_proxy(glite_renewal_core_context ctx, const char *cur_file, X509 **cert, EVP_PKEY **priv_key, STACK_OF(X509) **chain, globus_gsi_cred_handle_t *cur_proxy) { globus_result_t result; @@ -17,20 +35,20 @@ glite_renewal_load_proxy(glite_renewal_core_context ctx, const char *cur_file, X result = globus_gsi_cred_handle_init(&proxy, NULL); if (result) { - fprintf(stderr, "globus_gsi_cred_handle_init() failed\n"); + glite_renewal_core_set_err(ctx, "globus_gsi_cred_handle_init() failed"); goto end; } result = globus_gsi_cred_read_proxy(proxy, (char *) cur_file); if (result) { - fprintf(stderr, "globus_gsi_cred_read_proxy() failed\n"); + glite_renewal_core_set_err(ctx, "globus_gsi_cred_read_proxy() failed"); goto end; } if (cert) { result = globus_gsi_cred_get_cert(proxy, cert); if (result) { - fprintf(stderr, "globus_gsi_cred_get_cert() failed\n"); + glite_renewal_core_set_err(ctx, "globus_gsi_cred_get_cert() failed"); goto end; } } @@ -38,7 +56,7 @@ glite_renewal_load_proxy(glite_renewal_core_context ctx, const char *cur_file, X if (priv_key) { result = globus_gsi_cred_get_key(proxy, priv_key); if (result) { - fprintf(stderr, "globus_gsi_cred_get_key() failed\n"); + glite_renewal_core_set_err(ctx, "globus_gsi_cred_get_key() failed"); goto end; } } @@ -46,7 +64,7 @@ glite_renewal_load_proxy(glite_renewal_core_context ctx, const char *cur_file, X if (chain) { result = globus_gsi_cred_get_cert_chain(proxy, chain); if (result) { - fprintf(stderr, "globus_gsi_cred_get_cert_chain() failed\n"); + glite_renewal_core_set_err(ctx, "globus_gsi_cred_get_cert_chain() failed"); goto end; } } @@ -68,7 +86,7 @@ end: } int -glite_renewal_get_proxy_base_name(glite_renewal_core_context ctx, const char *file, char **name) +get_proxy_base_name(glite_renewal_core_context ctx, const char *file, char **name) { X509 *cert = NULL; EVP_PKEY *key = NULL; @@ -77,7 +95,7 @@ glite_renewal_get_proxy_base_name(glite_renewal_core_context ctx, const char *fi int ret; globus_result_t result; - ret = glite_renewal_load_proxy(ctx, file, &cert, &key, &chain, NULL); + ret = load_proxy(ctx, file, &cert, &key, &chain, NULL); if (ret) return ret; @@ -88,7 +106,7 @@ glite_renewal_get_proxy_base_name(glite_renewal_core_context ctx, const char *fi result = globus_gsi_cert_utils_get_base_name(subject, chain); if (result) { - glite_renewal_log(ctx, LOG_ERR, "Cannot get subject name from proxy %s", file); + glite_renewal_core_set_err(ctx, "Cannot get subject name from proxy %s", file); ret = EDG_WLPR_ERROR_SSL; /* XXX ??? */ goto end; } @@ -119,7 +137,6 @@ glite_renewal_core_renew(glite_renewal_core_context ctx, char tmp_proxy[FILENAME_MAX]; int tmp_fd; int ret = -1; - char *p; const char *server = NULL; myproxy_socket_attrs_t *socket_attrs; myproxy_request_t *client_request; @@ -138,27 +155,27 @@ glite_renewal_core_renew(glite_renewal_core_context ctx, myproxy_set_delegation_defaults(socket_attrs, client_request); - glite_renewal_log(ctx, LOG_DEBUG, "Trying to renew proxy in %s", current_proxy); + edg_wlpr_Log(ctx, LOG_DEBUG, "Trying to renew proxy in %s", current_proxy); snprintf(tmp_proxy, sizeof(tmp_proxy), "%s.myproxy.XXXXXX", current_proxy); tmp_fd = mkstemp(tmp_proxy); if (tmp_fd == -1) { - glite_renewal_log(ctx, LOG_ERR, "Cannot create temporary file (%s)", - strerror(errno)); + glite_renewal_core_set_err(ctx, "Cannot create temporary file (%s)", + strerror(errno)); return errno; } - ret = glite_renewal_get_proxy_base_name(ctx, current_proxy, &client_request->username); + ret = get_proxy_base_name(ctx, current_proxy, &client_request->username); if (ret) goto end; - voms_exts = glite_renewal_check_voms_attrs(ctx, current_proxy); + is_voms_cert(ctx, current_proxy, &voms_exts); client_request->proxy_lifetime = 60 * 60 * DGPR_RETRIEVE_DEFAULT_HOURS; server = (myproxy_server) ? myproxy_server : socket_attrs->pshost; if (server == NULL) { - glite_renewal_log(ctx, LOG_ERR, "No myproxy server specified"); + glite_renewal_core_set_err(ctx, "No myproxy server specified"); ret = EINVAL; goto end; } @@ -171,8 +188,8 @@ glite_renewal_core_renew(glite_renewal_core_context ctx, server_response, tmp_proxy); if (ret == 1) { ret = EDG_WLPR_ERROR_MYPROXY; - glite_renewal_log(ctx, LOG_ERR, "Error contacting MyProxy server for proxy %s: %s", - current_proxy, verror_get_string()); + glite_renewal_core_set_err(ctx, "Error contacting MyProxy server for proxy %s: %s", + current_proxy, verror_get_string()); verror_clear(); goto end; } @@ -187,15 +204,17 @@ glite_renewal_core_renew(glite_renewal_core_context ctx, current_proxy); tmp_voms_fd = mkstemp(tmp_voms_proxy); if (tmp_voms_fd == -1) { - glite_renewal_log(ctx, LOG_ERR, "Cannot create temporary file (%s)", - strerror(errno)); + glite_renewal_core_set_err(ctx, "Cannot create temporary file (%s)", + strerror(errno)); ret = errno; goto end; } - ret = glite_renewal_renew_voms_creds(ctx, current_proxy, renewed_proxy, tmp_voms_proxy); + ret = renew_voms_creds(ctx, current_proxy, renewed_proxy, tmp_voms_proxy); close(tmp_voms_fd); if (ret) { + glite_renewal_core_update_err(ctx, + "Failed to renew VOMS attributes"); unlink(tmp_voms_proxy); goto end; } @@ -250,34 +269,84 @@ glite_renewal_core_destroy_ctx(glite_renewal_core_context context) } void -glite_renewal_log(glite_renewal_core_context context, int dbg_level, const char *format, ...) +glite_renewal_core_set_err(glite_renewal_core_context ctx, const char *format, ...) +{ + va_list ap; + + glite_renewal_core_reset_err(ctx); + va_start(ap, format); + vasprintf(&ctx->err_message, format, ap); + va_end(ap); +} + +void +glite_renewal_core_update_err(glite_renewal_core_context ctx, const char *format, ...) +{ + va_list ap; + char *msg, *err; + + va_start(ap, format); + vasprintf(&msg, format, ap); + va_end(ap); + + if (ctx->err_message == NULL) { + ctx->err_message = msg; + return; + } + + asprintf(&err, "%s; %s", ctx->err_message, msg); + free(ctx->err_message); + free(msg); + ctx->err_message = err; +} + +char * +glite_renewal_core_get_err(glite_renewal_core_context ctx) +{ + return (ctx->err_message) ? ctx->err_message : "No error"; +} + +void +glite_renewal_core_reset_err(glite_renewal_core_context ctx) +{ + if (ctx->err_message) + free(ctx->err_message); + ctx->err_message = NULL; +} + +void +edg_wlpr_Log(glite_renewal_core_context context, int dbg_level, const char *format, ...) { va_list ap; + char *msg = NULL, *date, *p; + time_t now = time(NULL); - if (context->err_message) { - free(context->err_message); - context->err_message = NULL; - } - - /* cannot handle the %m format argument specific for syslog() */ - va_start(ap, format); - vasprintf(&context->err_message, format, ap); - va_end(ap); if (dbg_level > context->log_level) return; + /* cannot handle the %m format argument specific for syslog() */ + va_start(ap, format); + /* XXX can hardly log ENOMEM errors */ + vasprintf(&msg, format, ap); + va_end(ap); + switch (context->log_dst) { case GLITE_RENEWAL_LOG_STDOUT: - printf("%s\n", context->err_message); + date = ctime(&now); + if ((p = strchr(date, '\n'))) + *p = '\0'; + printf("%s [renewd %u]: %s\n", date, getpid(), msg); break; case GLITE_RENEWAL_LOG_SYSLOG: - syslog(dbg_level, "%s", context->err_message); + syslog(dbg_level, "%s", msg); break; case GLITE_RENEWAL_LOG_NONE: default: break; } + free(msg); + return; } diff --git a/org.glite.px.proxyrenewal/src/renewal_locl.h b/org.glite.px.proxyrenewal/src/renewal_locl.h index 256eb26..42bf2ae 100644 --- a/org.glite.px.proxyrenewal/src/renewal_locl.h +++ b/org.glite.px.proxyrenewal/src/renewal_locl.h @@ -1,3 +1,21 @@ +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef RENEWAL_LOCL_H #define RENEWAL_LOCL_H @@ -11,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/org.glite.px.proxyrenewal/src/renewd.c b/org.glite.px.proxyrenewal/src/renewd.c index 69a2ea0..d52ee1d 100644 --- a/org.glite.px.proxyrenewal/src/renewd.c +++ b/org.glite.px.proxyrenewal/src/renewd.c @@ -1,3 +1,21 @@ +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "renewal_locl.h" #include "renewd_locl.h" @@ -15,7 +33,6 @@ char *vomsdir = NULL; int voms_enabled = 0; char *cert = NULL; char *key = NULL; -char *vomsconf = NULL; static volatile int die = 0, child_died = 0; double default_timeout = 0; @@ -32,6 +49,7 @@ static struct option opts[] = { { "voms-config", required_argument, NULL, 'G' }, { "cert", required_argument, NULL, 't' }, { "key", required_argument, NULL, 'k' }, + { "order-attributes", no_argument, NULL, 'O' }, { NULL, 0, NULL, 0 } }; @@ -125,7 +143,7 @@ proto(glite_renewal_core_context ctx, int sock) ret = edg_wlpr_Read(sock, &timeout, &buf, &buf_len); if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Error reading from client: %s", + edg_wlpr_Log(ctx, LOG_ERR, "Error reading from client: %s", edg_wlpr_GetErrorString(ret)); return ret; } @@ -140,15 +158,10 @@ proto(glite_renewal_core_context ctx, int sock) command = find_command(ctx, request.command); if (command == NULL) { ret = EDG_WLPR_ERROR_UNKNOWN_COMMAND; - glite_renewal_log(ctx, LOG_ERR, "Received unknown command (%d)", request.command); + edg_wlpr_Log(ctx, LOG_ERR, "Received unknown command (%d)", request.command); goto end; } - glite_renewal_log(ctx, LOG_INFO, "Received command code %d for proxy %s and jobid %s", - request.command, - request.proxy_filename ? request.proxy_filename : "(unspecified)", - request.jobid ? request.jobid : "(unspecified)"); - command->handler(ctx, &request, &response); ret = encode_response(ctx, &response, &buf); @@ -158,7 +171,7 @@ proto(glite_renewal_core_context ctx, int sock) ret = edg_wlpr_Write(sock, &timeout, buf, strlen(buf) + 1); free(buf); if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Error sending response to client: %s", + edg_wlpr_Log(ctx, LOG_ERR, "Error sending response to client: %s", edg_wlpr_GetErrorString(ret)); goto end; } @@ -179,6 +192,7 @@ doit(glite_renewal_core_context ctx, int sock) int flags; while (!die) { + glite_renewal_core_reset_err(ctx); if (child_died) { int pid, newpid, ret; @@ -188,7 +202,7 @@ doit(glite_renewal_core_context ctx, int sock) ret = start_watchdog(ctx, &newpid); if (ret) return ret; - glite_renewal_log(ctx, LOG_DEBUG, "Renewal slave process re-started"); + edg_wlpr_Log(ctx, LOG_DEBUG, "Renewal slave process re-started"); child_died = 0; continue; } @@ -196,14 +210,13 @@ doit(glite_renewal_core_context ctx, int sock) newsock = accept(sock, (struct sockaddr *) &client_addr, &client_addr_len); if (newsock == -1) { if (errno != EINTR) - glite_renewal_log(ctx, LOG_ERR, "accept() failed"); + edg_wlpr_Log(ctx, LOG_ERR, "accept() failed: %s", strerror(errno)); continue; } - glite_renewal_log(ctx, LOG_DEBUG, "Got connection"); flags = fcntl(newsock, F_GETFL, 0); if (fcntl(newsock, F_SETFL, flags | O_NONBLOCK) < 0) { - glite_renewal_log(ctx, LOG_ERR, "Can't set O_NONBLOCK mode (%s), closing.\n", + edg_wlpr_Log(ctx, LOG_ERR, "Can't set O_NONBLOCK mode (%s), closing.\n", strerror(errno)); close(newsock); continue; @@ -211,10 +224,9 @@ doit(glite_renewal_core_context ctx, int sock) proto(ctx, newsock); - glite_renewal_log(ctx, LOG_DEBUG, "Connection closed"); close(newsock); } - glite_renewal_log(ctx, LOG_DEBUG, "Terminating on signal %d\n",die); + edg_wlpr_Log(ctx, LOG_DEBUG, "Terminating on signal %d\n",die); return 0; } @@ -239,7 +251,7 @@ decode_request(glite_renewal_core_context ctx, const char *msg, const size_t msg ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_VERSION, SEPARATORS, 0, &request->version); if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Protocol error reading protocol specification: %s", + edg_wlpr_Log(ctx, LOG_ERR, "Protocol error reading protocol specification: %s", edg_wlpr_GetErrorString(ret)); return ret; } @@ -247,14 +259,14 @@ decode_request(glite_renewal_core_context ctx, const char *msg, const size_t msg ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_COMMAND, SEPARATORS, 0, &value); if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Protocol error reading command specification: %s", + edg_wlpr_Log(ctx, LOG_ERR, "Protocol error reading command specification: %s", edg_wlpr_GetErrorString(ret)); goto err; } ret = edg_wlpr_DecodeInt(value, (int *)(&request->command)); if (ret) { - glite_renewal_log(ctx, LOG_ERR, "Received non-numeric command specification (%s)", + edg_wlpr_Log(ctx, LOG_ERR, "Received non-numeric command specification (%s)", value); free(value); goto err; @@ -262,7 +274,7 @@ decode_request(glite_renewal_core_context ctx, const char *msg, const size_t msg free(value); if (find_command(ctx, request->command) == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Received unknown command (%d)", request->command); + edg_wlpr_Log(ctx, LOG_ERR, "Received unknown command (%d)", request->command); ret = EDG_WLPR_ERROR_UNKNOWN_COMMAND; goto err; } @@ -270,7 +282,7 @@ decode_request(glite_renewal_core_context ctx, const char *msg, const size_t msg ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_MYPROXY_SERVER, SEPARATORS, 0, &request->myproxy_server); if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) { - glite_renewal_log(ctx, LOG_ERR, "Protocol error reading myproxy server specification: %s", + edg_wlpr_Log(ctx, LOG_ERR, "Protocol error reading myproxy server specification: %s", edg_wlpr_GetErrorString(ret)); goto err; } @@ -287,7 +299,7 @@ decode_request(glite_renewal_core_context ctx, const char *msg, const size_t msg ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_PROXY, SEPARATORS, 0, &request->proxy_filename); if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) { - glite_renewal_log(ctx, LOG_ERR, "Protocol error reading proxy specification: %s", + edg_wlpr_Log(ctx, LOG_ERR, "Protocol error reading proxy specification: %s", edg_wlpr_GetErrorString(ret)); goto err; } @@ -305,7 +317,7 @@ decode_request(glite_renewal_core_context ctx, const char *msg, const size_t msg ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_JOBID, SEPARATORS, 0, &request->jobid); if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) { - glite_renewal_log(ctx, LOG_ERR, "Protocol error reading JobId : %s", + edg_wlpr_Log(ctx, LOG_ERR, "Protocol error reading JobId : %s", edg_wlpr_GetErrorString(ret)); goto err; } @@ -431,7 +443,8 @@ usage(glite_renewal_core_context ctx, char *progname) "\t-C, --CAdir trusted certificates directory\n" "\t-V, --VOMSdir trusted VOMS servers certificates directory\n" "\t-A, --enable-voms renew also VOMS certificates in proxies\n" - "\t-G, --voms-config location of the vomses configuration file\n", + "\t-G, --voms-config location of the vomses configuration file\n" + "\t-O, --order-attributes retain VOMS attributes ordering\n", progname); } @@ -448,24 +461,23 @@ do_listen(glite_renewal_core_context ctx, char *socket_name, int *sock) my_addr.sun_family = AF_UNIX; strncpy(my_addr.sun_path, socket_name, sizeof(my_addr.sun_path)); unlink(socket_name); - umask(0177); s = socket(AF_UNIX, SOCK_STREAM, 0); if (s == -1) { - glite_renewal_log(ctx, LOG_ERR, "socket(): %s", strerror(errno)); + edg_wlpr_Log(ctx, LOG_ERR, "socket(): %s", strerror(errno)); return errno; } ret = bind(s, (struct sockaddr *)&my_addr, sizeof(my_addr)); if (ret == -1) { - glite_renewal_log(ctx, LOG_ERR, "bind(): %s", strerror(errno)); + edg_wlpr_Log(ctx, LOG_ERR, "bind(): %s", strerror(errno)); close(s); return errno; } ret = listen(s, 50); if (ret == -1) { - glite_renewal_log(ctx, LOG_ERR, "listen(): %s", strerror(errno)); + edg_wlpr_Log(ctx, LOG_ERR, "listen(): %s", strerror(errno)); close(s); return errno; } @@ -481,7 +493,7 @@ start_watchdog(glite_renewal_core_context ctx, pid_t *pid) switch ((p = fork())) { case -1: - glite_renewal_log(ctx, LOG_ERR, "fork() failed: %s", + edg_wlpr_Log(ctx, LOG_ERR, "fork() failed: %s", strerror(errno)); return errno; case 0: @@ -513,10 +525,16 @@ int main(int argc, char *argv[]) if (progname) progname++; else progname = argv[0]; + ret = glite_renewal_core_init_ctx(&ctx); + if (ret) { + fprintf(stderr, "Cannot initialize context\n"); + exit(1); + } + repository = EDG_WLPR_REPOSITORY_ROOT; debug = 0; - while ((opt = getopt_long(argc, argv, "hvdr:c:C:V:AG:t:k:", opts, NULL)) != EOF) + while ((opt = getopt_long(argc, argv, "hvdr:c:C:V:AG:t:k:O", opts, NULL)) != EOF) switch (opt) { case 'h': usage(ctx, progname); exit(0); case 'v': fprintf(stdout, "%s:\t%s\n", progname, rcsid); exit(0); @@ -526,9 +544,10 @@ int main(int argc, char *argv[]) case 'C': cadir = optarg; break; case 'V': vomsdir = optarg; break; case 'A': voms_enabled = 1; break; - case 'G': vomsconf = optarg; break; + case 'G': ctx->voms_conf = optarg; break; case 't': cert = optarg; break; case 'k': key = optarg; break; + case 'O': ctx->order_attributes = 1; break; case '?': usage(ctx, progname); return 1; } @@ -537,19 +556,13 @@ int main(int argc, char *argv[]) exit(1); } - ret = glite_renewal_core_init_ctx(&ctx); - if (ret) { - fprintf(stderr, "Cannot initialize context\n"); - exit(1); - } if (debug) { ctx->log_level = LOG_DEBUG; ctx->log_dst = GLITE_RENEWAL_LOG_STDOUT; } - ctx->voms_conf = vomsconf; if (chdir(repository)) { - glite_renewal_log(ctx, LOG_ERR, "Cannot access repository directory %s (%s)", + edg_wlpr_Log(ctx, LOG_ERR, "Cannot access repository directory %s (%s)", repository, strerror(errno)); exit(1); } @@ -597,7 +610,7 @@ int main(int argc, char *argv[]) ret = do_listen(ctx, sockname, &sock); if (ret) return 1; - glite_renewal_log(ctx, LOG_DEBUG, "Listening at %s", sockname); + edg_wlpr_Log(ctx, LOG_DEBUG, "Listening at %s", sockname); ret = doit(ctx, sock); diff --git a/org.glite.px.proxyrenewal/src/renewd_locl.h b/org.glite.px.proxyrenewal/src/renewd_locl.h index 489e909..dd45faa 100644 --- a/org.glite.px.proxyrenewal/src/renewd_locl.h +++ b/org.glite.px.proxyrenewal/src/renewd_locl.h @@ -1,3 +1,21 @@ +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef RENEWALD_LOCL_H #define RENEWALD_LOCL_H @@ -7,6 +25,8 @@ #include #include +#include + #include "renewal.h" #include "renewal_core.h" @@ -55,7 +75,7 @@ void watchdog_start(glite_renewal_core_context ctx); void -glite_renewal_log(glite_renewal_core_context ctx, int dbg_level, const char *format, ...); +edg_wlpr_Log(glite_renewal_core_context ctx, int dbg_level, const char *format, ...); int decode_record(glite_renewal_core_context ctx, char *line, proxy_record *record); @@ -67,16 +87,20 @@ void free_record(glite_renewal_core_context ctx, proxy_record *record); int -glite_renewal_load_proxy(glite_renewal_core_context ctx, const char *filename, X509 **cert, EVP_PKEY **privkey, +load_proxy(glite_renewal_core_context ctx, const char *filename, X509 **cert, EVP_PKEY **privkey, STACK_OF(X509) **chain, globus_gsi_cred_handle_t *proxy); int -glite_renewal_get_proxy_base_name(glite_renewal_core_context ctx, const char *file, char **subject); +get_proxy_base_name(glite_renewal_core_context ctx, const char *file, char **subject); + +int +renew_voms_creds(glite_renewal_core_context ctx, const char *cur_file, const char *renewed_file, const char *new_file); int -glite_renewal_renew_voms_creds(glite_renewal_core_context ctx, const char *cur_file, const char *renewed_file, const char *new_file); +is_voms_cert(glite_renewal_core_context ctx, const char *proxy, int *present); int -glite_renewal_check_voms_attrs(glite_renewal_core_context ctx, const char *proxy); +get_voms_cert(glite_renewal_core_context ctx, + X509 *cert, STACK_OF(X509) *chain, struct vomsdata **vd); #endif /* RENEWALD_LOCL_H */ diff --git a/org.glite.px.proxyrenewal/src/voms.c b/org.glite.px.proxyrenewal/src/voms.c index c7af4fb..65f7da4 100644 --- a/org.glite.px.proxyrenewal/src/voms.c +++ b/org.glite.px.proxyrenewal/src/voms.c @@ -1,3 +1,23 @@ +/* + * Copyright (c) Members of the EGEE Collaboration. 2004-2010. + * See http://www.eu-egee.org/partners/ for details on the copyright + * holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static const char rcsid[] = "$Id$"; + #include "renewal_locl.h" #include "renewd_locl.h" @@ -25,39 +45,39 @@ generate_proxy(glite_renewal_core_context ctx, globus_gsi_cred_handle_t cur_prox result = globus_gsi_proxy_handle_init(&proxy_handle, NULL); if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_proxy_handle_init() failed\n"); + glite_renewal_core_set_err(ctx, "globus_gsi_proxy_handle_init() failed"); goto end; } result = globus_gsi_cred_get_key(cur_proxy, &cur_proxy_priv_key); if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_cred_get_key() failed\n"); + glite_renewal_core_set_err(ctx, "globus_gsi_cred_get_key() failed"); goto end; } /* Create and sign a new proxy */ result = globus_gsi_cred_get_cert_type(cur_proxy, &proxy_type); if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_cred_get_cert_type() failed\n"); + glite_renewal_core_set_err(ctx, "globus_gsi_cred_get_cert_type() failed"); goto end; } result = globus_gsi_proxy_handle_set_type(proxy_handle, proxy_type); if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_proxy_handle_set_type() failed\n"); + glite_renewal_core_set_err(ctx, "globus_gsi_proxy_handle_set_type() failed"); goto end; } result = globus_gsi_proxy_create_signed(proxy_handle, cur_proxy, &proxy); if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_proxy_handle_init() failed\n"); + glite_renewal_core_set_err(ctx, "globus_gsi_proxy_handle_init() failed"); goto end; } /* Get the new proxy */ result = globus_gsi_cred_get_cert(proxy, &new_cert); if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_cred_get_cert() failed\n"); + glite_renewal_core_set_err(ctx, "globus_gsi_cred_get_cert() failed"); goto end; } @@ -77,7 +97,7 @@ generate_proxy(glite_renewal_core_context ctx, globus_gsi_cred_handle_t cur_prox /* And put the cert back, older one is unallocated by the function */ result = globus_gsi_cred_set_cert(proxy, voms_cert); if (result) { - glite_renewal_log(ctx, LOG_ERR, "globus_gsi_cred_set_cert() failed\n"); + glite_renewal_core_set_err(ctx, "globus_gsi_cred_set_cert() failed"); goto end; } @@ -98,7 +118,7 @@ my_VOMS_Export(glite_renewal_core_context ctx, void *buf, int buf_len, X509_EXTE p = pp = buf; ac = d2i_AC(NULL, &p, buf_len+1); if (ac == NULL) { - glite_renewal_log(ctx, LOG_ERR, "d2i_AC() failed\n"); + glite_renewal_core_set_err(ctx, "d2i_AC() failed"); return 1; } @@ -112,34 +132,46 @@ my_VOMS_Export(glite_renewal_core_context ctx, void *buf, int buf_len, X509_EXTE static int create_voms_command(glite_renewal_core_context ctx, struct vomsdata *vd, struct voms **voms_cert, char **command) { - int voms_error, ret; + int ret, voms_err, i; struct data **attribs; - -#if 0 - VOMS_ResetOrder(vd, &voms_error); - for (i = 2; i < argc; i++) { - ret = VOMS_Ordering(argv[i], vd, &voms_error); - if (ret == 0) { - glite_renewal_log(ctx, LOG_ERR, "VOMS_Ordering() failed\n"); - return 1; - } - } -#endif + char *str = NULL; + char *role, *cmd = NULL, *tmp = NULL; if (voms_cert == NULL || *voms_cert == NULL || (*voms_cert)->std == NULL) { - glite_renewal_log(ctx, LOG_ERR, "Invalid VOMS certificate\n"); + glite_renewal_core_set_err(ctx, "Invalid VOMS certificate"); return 1; } + VOMS_ResetOrder(vd, &voms_err); attribs = (*voms_cert)->std; + i = 0; + while (attribs && attribs[i]) { + role = NULL; + if ((attribs[i])->role && strcmp ((attribs[i])->role, "NULL") != 0 && + strcmp((attribs[i])->role, "") != 0) + role = (attribs[i])->role; + + asprintf(&str, "%s%s%s", + (attribs[i])->group, + (role) ? ":" : "", + (role) ? role : ""); + + if (ctx->order_attributes) + VOMS_Ordering(str, vd, &voms_err); + + asprintf(&tmp, "%s%s%s%s", + (cmd) ? cmd : "", + (cmd) ? "," : "", + (role) ? "B" : "G", + str); + cmd = tmp; + + free(str); + str = NULL; + i++; + } - if (strcmp (attribs[0]->role, "NULL") == 0 ) - ret = asprintf(command, "G%s", attribs[0]->group); - else - ret = asprintf(command, "B%s:%s", attribs[0]->group, attribs[0]->role); - -end: - + *command = cmd; return 0; } @@ -147,38 +179,87 @@ static int renew_voms_cert(glite_renewal_core_context ctx, struct vomsdata *vd, struct voms **voms_cert, char **buf, size_t *buf_len) { - int voms_error = 0, i, ret, voms_version; + int voms_error = 0, ret, voms_version, port = -1; struct contactdata **voms_contacts = NULL; + struct contactdata **c; char *command = NULL; + char *err_msg, *voms_server = NULL, *p; - voms_contacts = VOMS_FindByVO(vd, (*voms_cert)->voname, ctx->voms_conf, NULL, &voms_error); + ret = create_voms_command(ctx, vd, voms_cert, &command); + if (ret) + return ret; - if (voms_contacts == NULL) { - glite_renewal_log(ctx, LOG_ERR, "VOMS_FindByVO() failed\n"); - return 1; + /* XXX the lifetime should be taken from the older proxy */ + VOMS_SetLifetime(60*60*12, vd, &voms_error); + + if ((*voms_cert)->uri != NULL) { + voms_server = strdup((*voms_cert)->uri); + if (voms_server == NULL) { + glite_renewal_core_set_err(ctx, "Not enough memory"); + ret = 1; + goto end; + } + + p = strchr(voms_server, ':'); + if (p) { + *p++ = '\0'; + port = atoi(p); + } } - ret = create_voms_command(ctx, vd, voms_cert, &command); + /* first try to contact the VOMS server that issued the original AC */ + if (voms_server && port != -1 && (*voms_cert)->server != NULL) { + ret = VOMS_ContactRaw(voms_server, port, (*voms_cert)->server, + command, (void**) buf, buf_len, &voms_version, + vd, &voms_error); + if (ret != 0) { + /* success, let's finish */ + ret = 0; + goto end; + } + err_msg = VOMS_ErrorMessage(vd, voms_error, NULL, 0); + glite_renewal_core_set_err(ctx, + "Failed to contact VOMS server %s of VO %s: %s", + voms_server, (*voms_cert)->voname, err_msg); + free(err_msg); + } - /* XXX the lifetime should be taken from the older proxy */ - ret = VOMS_SetLifetime(60*60*12, vd, &voms_error); - - /* XXX iterate over all servers on the list on errors */ - ret = VOMS_ContactRaw(voms_contacts[0]->host, voms_contacts[0]->port, - voms_contacts[0]->contact, command, - (void**) buf, buf_len, &voms_version, - vd, &voms_error); - if (ret == 0) { - glite_renewal_log(ctx, LOG_ERR, "VOMS_Contact() failed\n"); - return 1; + /* if the original URI doesn't work, try VOMS servers given in local + configuration */ + voms_contacts = VOMS_FindByVO(vd, (*voms_cert)->voname, ctx->voms_conf, NULL, &voms_error); + if (voms_contacts == NULL) { + err_msg = VOMS_ErrorMessage(vd, voms_error, NULL, 0); + glite_renewal_core_set_err(ctx, "Can't find configuration for VO %s: %s", + (*voms_cert)->voname, err_msg); + free(err_msg); + ret = 1; + goto end; } + ret = 0; + for (c = voms_contacts; c && *c; c++) { + ret = VOMS_ContactRaw((*c)->host, (*c)->port, (*c)->contact, + command, (void**) buf, buf_len, &voms_version, + vd, &voms_error); + if (ret != 0) { + /* success, let's finish */ + break; + } + err_msg = VOMS_ErrorMessage(vd, voms_error, NULL, 0); + glite_renewal_core_set_err(ctx, + "Failed to contact VOMS server %s of VO %s: %s", + (*c)->host, (*voms_cert)->voname, err_msg); + free(err_msg); + } + ret = (ret == 0) ? -1 : 0; + +end: VOMS_DeleteContacts(voms_contacts); if (command) free(command); - return 0; + return ret; } static int @@ -188,7 +269,7 @@ renew_voms_certs(glite_renewal_core_context ctx, const char *cur_file, const cha globus_gsi_cred_handle_t new_proxy = NULL; struct vomsdata *vd = NULL; struct voms **voms_cert = NULL; - int voms_err, ret; + int ret; X509 *cert = NULL; STACK_OF(X509) *chain = NULL; char *buf = NULL; @@ -202,34 +283,14 @@ renew_voms_certs(glite_renewal_core_context ctx, const char *cur_file, const cha setenv("X509_USER_CERT", renewed_file, 1); setenv("X509_USER_KEY", renewed_file, 1); - ret = glite_renewal_load_proxy(ctx, cur_file, &cert, NULL, &chain, &cur_proxy); + ret = load_proxy(ctx, cur_file, &cert, NULL, &chain, &cur_proxy); if (ret) goto end; - vd = VOMS_Init(NULL, NULL); - if (vd == NULL) { - glite_renewal_log(ctx, LOG_ERR, "VOMS_Init() failed\n"); - return 1; - } - - ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, vd, &voms_err); - if (ret == 0) { - if (voms_err == VERR_NOEXT) { - /* no VOMS cred, no problem; continue */ - /* XXX this part shouldn't be reachable, this call is only called - * if the proxy does contain VOMS attributes */ - glite_renewal_log(ctx, LOG_ERR, "No VOMS attributes found in proxy %s\n", cur_file); - ret = 0; - goto end; - } else { - glite_renewal_log(ctx, LOG_ERR, "Cannot get VOMS certificate(s) from proxy"); - ret = 1; - goto end; - } - } + ret = get_voms_cert(ctx, cert, chain, &vd); + if (ret) + goto end; - /* XXX make sure this loop can really work for multiple voms certificates - * embedded in the proxy */ for (voms_cert = vd->data; voms_cert && *voms_cert; voms_cert++) { char *tmp, *ptr; size_t tmp_len; @@ -257,7 +318,7 @@ renew_voms_certs(glite_renewal_core_context ctx, const char *cur_file, const cha if (ret) goto end; - ret = glite_renewal_load_proxy(ctx, renewed_file, NULL, NULL, NULL, &new_proxy); + ret = load_proxy(ctx, renewed_file, NULL, NULL, NULL, &new_proxy); if (ret) goto end; @@ -288,46 +349,79 @@ end: } int -glite_renewal_renew_voms_creds(glite_renewal_core_context ctx, const char *cur_file, const char *renewed_file, const char *new_file) +renew_voms_creds(glite_renewal_core_context ctx, const char *cur_file, const char *renewed_file, const char *new_file) { return renew_voms_certs(ctx, cur_file, renewed_file, new_file); } int -glite_renewal_check_voms_attrs(glite_renewal_core_context ctx, const char *proxy) +is_voms_cert(glite_renewal_core_context ctx, + const char *file, + int *present) { - int ret, voms_err, present; - X509 *cert = NULL; + struct vomsdata *voms_info = NULL; STACK_OF(X509) *chain = NULL; - struct vomsdata *vd = NULL; + X509 *cert = NULL; + int ret; + + *present = 0; - ret = glite_renewal_load_proxy(ctx, proxy, &cert, NULL, &chain, NULL); + ret = load_proxy(ctx, file, &cert, NULL, &chain, NULL); if (ret) - return 0; + return ret; - vd = VOMS_Init(NULL, NULL); - if (vd == NULL) { - present = 0; + ret = get_voms_cert(ctx, cert, chain, &voms_info); + if (ret) goto end; - } - ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, vd, &voms_err); - if (ret == 0) { - present = 0; - goto end; + *present = (voms_info != NULL); + +end: + if (voms_info) + VOMS_Destroy(voms_info); + sk_X509_pop_free(chain, X509_free); + X509_free(cert); + + return ret; +} + +int +get_voms_cert(glite_renewal_core_context ctx, + X509 *cert, STACK_OF(X509) *chain, struct vomsdata **vd) +{ + struct vomsdata *voms_info = NULL; + int voms_err, ret, voms_ret; + + /* XXX pass the vomsdir and cadir parameters */ + voms_info = VOMS_Init(NULL, NULL); + if (voms_info == NULL) { + glite_renewal_core_set_err(ctx, "VOMS_Init() failed, probably voms dir was not specified"); + return EDG_WLPR_ERROR_VOMS; } - present = 1; + VOMS_SetVerificationType(VERIFY_NONE, voms_info, &voms_err); -end: - if (cert) - X509_free(cert); - if (chain) - sk_X509_pop_free(chain, X509_free); - if (vd) - VOMS_Destroy(vd); + ret = 0; + voms_ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, voms_info, &voms_err); + if (voms_ret == 0) { + if (voms_err == VERR_NOEXT) { + voms_info = NULL; + ret = 0; + } else { + char *err_msg = VOMS_ErrorMessage(voms_info, voms_err, NULL, 0); + glite_renewal_core_set_err(ctx, "Failed to retrieve VOMS attributes: %s", + err_msg); + free(err_msg); + ret = -1; /* XXX */ + } + } + + if (ret == 0 && vd != NULL) + *vd = voms_info; + else + VOMS_Destroy(voms_info); - return present; + return ret; } #if 0 @@ -345,7 +439,7 @@ main(int argc, char *argv[]) if (globus_module_activate(GLOBUS_GSI_PROXY_MODULE) != GLOBUS_SUCCESS || globus_module_activate(GLOBUS_GSI_CERT_UTILS_MODULE) != GLOBUS_SUCCESS) { - glite_renewal_log(ctx, LOG_ERR, "[%d]: Unable to initialize Globus modules\n", getpid()); + glite_renewal_core_set_err(ctx, "Unable to initialize Globus modules"); return 1; } -- 1.8.2.3