From 3511ddee9055454419c53447e803ad298ed9884c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Kou=C5=99il?= Date: Fri, 11 Aug 2006 13:43:41 +0000 Subject: [PATCH] Added renewal_core library exporting calls to perform actual renewal --- org.glite.security.proxyrenewal/Makefile | 21 +- .../interface/renewal_core.h | 62 +++++ org.glite.security.proxyrenewal/src/renewal_core.c | 283 +++++++++++++++++++++ .../src/renewal_core_compat.c | 93 +++++++ 4 files changed, 454 insertions(+), 5 deletions(-) create mode 100644 org.glite.security.proxyrenewal/interface/renewal_core.h create mode 100644 org.glite.security.proxyrenewal/src/renewal_core.c create mode 100644 org.glite.security.proxyrenewal/src/renewal_core_compat.c diff --git a/org.glite.security.proxyrenewal/Makefile b/org.glite.security.proxyrenewal/Makefile index 3730746..d011319 100644 --- a/org.glite.security.proxyrenewal/Makefile +++ b/org.glite.security.proxyrenewal/Makefile @@ -73,20 +73,28 @@ INSTALL:=libtool --mode=install install DAEMONOBJ:=renewd.o renew.o common.o commands.o api.o voms.o LIBOBJ:=api.o common.o +LIB_CORE_OBJS := renewal_core.o voms.o renewal_core_compat.o CLIENTOBJ:=client.o THRLIBOBJ:=${LIBOBJ:.o=.thr.o} LIBLOBJ:=${LIBOBJ:.o=.lo} THRLIBLOBJ:=${LIBOBJ:.o=.thr.lo} +LIB_CORE_NOTHR_OBJS := ${LIB_CORE_OBJS} +LIB_CORE_NOTHR_LOBJS := ${LIB_CORE_OBJS:.o=.lo} +LIB_CORE_THR_OBJS := ${LIB_CORE_OBJS:.o=.thr.o} +LIB_CORE_THR_LOBJS := ${LIB_CORE_OBJS:.o=.thr.lo} + LIB:=libglite_security_proxyrenewal_${nothrflavour}.la THRLIB:=libglite_security_proxyrenewal_${thrflavour}.la +LIB_CORE_NOTHR := libglite_security_proxyrenewal_core_${nothrflavour}.la +LIB_CORE_THR := libglite_security_proxyrenewal_core_${thrflavour}.la DAEMON:=glite-proxy-renewd CLIENT:=glite-proxy-renew default: all -compile all: ${LIB} ${THRLIB} ${DAEMON} ${CLIENT} +compile all: ${LIB} ${THRLIB} ${LIB_CORE_NOTHR} ${DAEMON} ${CLIENT} ${LIB}: ${LIBOBJ} ${LINK} -o $@ ${LIBLOBJ} -rpath ${glite_location}/lib ${JOBIDLIB} @@ -95,13 +103,16 @@ ${LIB}: ${LIBOBJ} ${THRLIB}: ${THRLIBOBJ} ${LINK} -o $@ ${THRLIBLOBJ} -rpath ${glite_location}/lib +${LIB_CORE_NOTHR}: ${LIB_CORE_NOTHR_OBJS} + ${LINK} -o $@ ${LIB_CORE_NOTHR_OBJS} -rpath ${glite_location}/lib ${MYPROXY_LIB} -L${glite_location}/lib -lvomsc_${nothrflavour} + ${DAEMON}: ${DAEMONOBJ} ${LINK} -o $@ ${DAEMONOBJ} ${JOBIDLIB} ${MYPROXY_LIB} -lvomsc -lglobus_gss_assist_${nothrflavour} ${GLOBUS_LIBS} ${CLIENT}: ${CLIENTOBJ} ${LIB} ${LINK} -o $@ ${CLIENTOBJ} ${LIB} ${GLOBUS_LIBS} -${THRLIBOBJ}: %.thr.o: %.c +${THRLIBOBJ} ${LIB_CORE_THR_OBJS}: %.thr.o: %.c ${COMPILE} ${GLOBUSTHRINC} -o $@ -c $< %.o: %.c @@ -129,13 +140,13 @@ distbin: install: -mkdir -p ${PREFIX}/bin ${PREFIX}/lib ${PREFIX}/include/glite/security/proxyrenewal ${PREFIX}/share/doc/${package}-${version} ${PREFIX}/etc/init.d - ${INSTALL} -m 644 ${LIB} ${THRLIB} ${PREFIX}/lib + ${INSTALL} -m 644 ${LIB} ${THRLIB} ${LIB_CORE_NOTHR} ${PREFIX}/lib ${INSTALL} -m 755 ${DAEMON} ${CLIENT} ${PREFIX}/bin ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - cd ${top_srcdir}/interface && ${INSTALL} -m 644 renewal.h ${PREFIX}/include/glite/security/proxyrenewal + cd ${top_srcdir}/interface && ${INSTALL} -m 644 renewal.h renewal_core.h ${PREFIX}/include/glite/security/proxyrenewal ${INSTALL} -m 755 ${top_srcdir}/config/startup ${PREFIX}/etc/init.d/glite-proxy-renewald clean: - $(RM) $(LIB) $(DAEMON) $(CLIENT) *.o core + $(RM) $(LIB) ${LIB_CORE_NOTHR} $(DAEMON) $(CLIENT) *.o core diff --git a/org.glite.security.proxyrenewal/interface/renewal_core.h b/org.glite.security.proxyrenewal/interface/renewal_core.h new file mode 100644 index 0000000..8348963 --- /dev/null +++ b/org.glite.security.proxyrenewal/interface/renewal_core.h @@ -0,0 +1,62 @@ +#ifndef RENEWAL_CORE_H +#define RENEWAL_CORE_H + +#ident "$Id$" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + GLITE_RENEWAL_LOG_NONE, + GLITE_RENEWAL_LOG_STDOUT, + GLITE_RENEWAL_LOG_SYSLOG, +} glite_renewal_log_dst; + +typedef struct glite_renewal_core_context_data { + int log_level; + glite_renewal_log_dst log_dst; + char *err_message; + char *voms_conf; +} glite_renewal_core_context_data; + +typedef struct glite_renewal_core_context_data *glite_renewal_core_context; + +/** + * This cal initializes the context and sets default values + */ +int +glite_renewal_core_init_ctx(glite_renewal_core_context *context); + +/** + * This call frees the context and all memory used by the context + */ +int +glite_renewal_core_destroy_ctx(glite_renewal_core_context context); + +/** + * This call tries to renew the proxy certificate using the MyProxy + * repository. If VOMS attributes are present in the proxy they are renewed + * as well. + * \param context IN: context with authentication information + * \param myproxy_server IN: hostname of the myproxy repository + * \param myproxy_port IN: TCP port of the myproxy repository, if 0 the + * default value will be used + * \param current_proxy IN: filename with the proxy to renew + * \param new_proxy OUT: filename with the renewed proxy, the caller is + * responsible for removing the file when it's not needed. + */ +int +glite_renewal_core_renew(glite_renewal_core_context context, + const char *myproxy_server, + unsigned int myproxy_port, + const char *current_proxy, + char **new_proxy); + +#ifdef __cplusplus +} +#endif + +#endif /* RENEWAL_CORE_H */ diff --git a/org.glite.security.proxyrenewal/src/renewal_core.c b/org.glite.security.proxyrenewal/src/renewal_core.c new file mode 100644 index 0000000..3bd2d1d --- /dev/null +++ b/org.glite.security.proxyrenewal/src/renewal_core.c @@ -0,0 +1,283 @@ +#include +#include + +#include "renewal_core.h" +#include "renewal_locl.h" +#include "renewd_locl.h" + +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, + STACK_OF(X509) **chain, globus_gsi_cred_handle_t *cur_proxy) +{ + globus_result_t result; + globus_gsi_cred_handle_t proxy = NULL; + int ret; + + result = globus_gsi_cred_handle_init(&proxy, NULL); + if (result) { + fprintf(stderr, "globus_gsi_cred_handle_init() failed\n"); + goto end; + } + + result = globus_gsi_cred_read_proxy(proxy, (char *) cur_file); + if (result) { + fprintf(stderr, "globus_gsi_cred_read_proxy() failed\n"); + goto end; + } + + if (cert) { + result = globus_gsi_cred_get_cert(proxy, cert); + if (result) { + fprintf(stderr, "globus_gsi_cred_get_cert() failed\n"); + goto end; + } + } + + if (priv_key) { + result = globus_gsi_cred_get_key(proxy, priv_key); + if (result) { + fprintf(stderr, "globus_gsi_cred_get_key() failed\n"); + goto end; + } + } + + if (chain) { + result = globus_gsi_cred_get_cert_chain(proxy, chain); + if (result) { + fprintf(stderr, "globus_gsi_cred_get_cert_chain() failed\n"); + goto end; + } + } + + if (cur_proxy) { + *cur_proxy = proxy; + proxy = NULL; + } + + ret = 0; + +end: + if (proxy) + globus_gsi_cred_handle_destroy(proxy); + if (result) + ret = EDG_WLPR_ERROR_GENERIC; + + return ret; +} + +int +glite_renewal_get_proxy_base_name(glite_renewal_core_context ctx, const char *file, char **name) +{ + X509 *cert = NULL; + EVP_PKEY *key = NULL; + STACK_OF(X509) *chain = NULL; + X509_NAME *subject = NULL; + int ret; + globus_result_t result; + + ret = glite_renewal_load_proxy(ctx, file, &cert, &key, &chain, NULL); + if (ret) + return ret; + + subject = X509_NAME_dup(X509_get_subject_name(cert)); + + sk_X509_insert(chain, cert, 0); + cert = NULL; + + 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); + ret = EDG_WLPR_ERROR_SSL; /* XXX ??? */ + goto end; + } + + *name = X509_NAME_oneline(subject, NULL, 0); + ret = 0; + +end: + if (cert) + X509_free(cert); + if (key) + EVP_PKEY_free(key); + if (chain) + sk_X509_pop_free(chain, X509_free); + if (subject) + X509_NAME_free(subject); + + return ret; +} + +int +glite_renewal_core_renew(glite_renewal_core_context ctx, + const char * myproxy_server, + unsigned int myproxy_port, + const char *current_proxy, + char **new_proxy) +{ + 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; + myproxy_response_t *server_response; + char *renewed_proxy; + int voms_exts; + + socket_attrs = malloc(sizeof(*socket_attrs)); + memset(socket_attrs, 0, sizeof(*socket_attrs)); + + client_request = malloc(sizeof(*client_request)); + memset(client_request, 0, sizeof(*client_request)); + + server_response = malloc(sizeof(*server_response)); + memset(server_response, 0, sizeof(*server_response)); + + myproxy_set_delegation_defaults(socket_attrs, client_request); + + glite_renewal_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)); + return errno; + } + + ret = glite_renewal_get_proxy_base_name(ctx, current_proxy, &client_request->username); + if (ret) + goto end; + + voms_exts = glite_renewal_check_voms_attrs(ctx, current_proxy); + + 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"); + ret = EINVAL; + goto end; + } + socket_attrs->pshost = strdup(server); + + socket_attrs->psport = (myproxy_port) ? myproxy_port : MYPROXY_SERVER_PORT; + + verror_clear(); + ret = myproxy_get_delegation(socket_attrs, client_request, (char *) current_proxy, + 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()); + verror_clear(); + goto end; + } + + renewed_proxy = tmp_proxy; + + if (voms_exts) { + char tmp_voms_proxy[FILENAME_MAX]; + int tmp_voms_fd; + + snprintf(tmp_voms_proxy, sizeof(tmp_voms_proxy), "%s.voms.XXXXXX", + 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)); + ret = errno; + goto end; + } + + ret = glite_renewal_renew_voms_creds(ctx, current_proxy, renewed_proxy, tmp_voms_proxy); + close(tmp_voms_fd); + if (ret) { + unlink(tmp_voms_proxy); + goto end; + } + + renewed_proxy = tmp_voms_proxy; + unlink(tmp_proxy); + } + + if (new_proxy) + *new_proxy = strdup(renewed_proxy); + + ret = 0; + +end: + if (socket_attrs->socket_fd) + close(socket_attrs->socket_fd); + close(tmp_fd); + if (ret) + unlink(tmp_proxy); + myproxy_free(socket_attrs, client_request, server_response); + + return ret; +} + +int +glite_renewal_core_init_ctx(glite_renewal_core_context *context) +{ + glite_renewal_core_context p = NULL; + + *context = NULL; + + p = calloc(1, sizeof(*p)); + if (p == NULL) + return ENOMEM; + + p->log_level = LOG_ERR; + p->log_dst = GLITE_RENEWAL_LOG_SYSLOG; + + *context = p; + return 0; +} + +int +glite_renewal_core_destroy_ctx(glite_renewal_core_context context) +{ + if (context == NULL) + return 0; + if (context->err_message); + free(context->err_message); + free(context); + return 0; +} + +void +glite_renewal_log(glite_renewal_core_context context, int dbg_level, const char *format, ...) +{ + va_list ap; + + 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; + + switch (context->log_dst) { + case GLITE_RENEWAL_LOG_STDOUT: + printf("%s\n", context->err_message); + break; + case GLITE_RENEWAL_LOG_SYSLOG: + syslog(dbg_level, "%s", context->err_message); + break; + case GLITE_RENEWAL_LOG_NONE: + default: + break; + } + + return; +} diff --git a/org.glite.security.proxyrenewal/src/renewal_core_compat.c b/org.glite.security.proxyrenewal/src/renewal_core_compat.c new file mode 100644 index 0000000..80c50f2 --- /dev/null +++ b/org.glite.security.proxyrenewal/src/renewal_core_compat.c @@ -0,0 +1,93 @@ +/* + * This is a "glue" file containing various pieces that are needed to build + * separated renewal_core library. + */ + +#include + +#include "renewal_core.h" +#include "renewal_locl.h" +#include "renewd_locl.h" + +char *vomsconf = NULL; +static glite_renewal_core_context saved_ctx = NULL; + +/* Wrapper calling renew_voms_creds() from voms.o */ +int +glite_renewal_renew_voms_creds(glite_renewal_core_context ctx, const char *cur_file, const char *renewed_file, const char *new_file) +{ + int ret; + + vomsconf = ctx->voms_conf; + saved_ctx = ctx; + ret = renew_voms_creds(cur_file, renewed_file, new_file); + saved_ctx = NULL; + + return ret; +} + +/* This is called from voms.o, normaly it sits in renew.o, which we don't want + * to add to the renewal_core lib. */ +int +load_proxy(const char *cur_file, X509 **cert, EVP_PKEY **priv_key, + STACK_OF(X509) **chain, globus_gsi_cred_handle_t *cur_proxy) +{ + assert(saved_ctx != NULL); + + return glite_renewal_load_proxy(saved_ctx, cur_file, cert, priv_key, chain, cur_proxy); +} + +/* This is called from voms.o */ +void +edg_wlpr_Log(int dbg_level, const char *format, ...) +{ + char *str; + va_list ap; + + assert(saved_ctx != NULL); + + va_start(ap, format); + vasprintf(&str, format, ap); + va_end(ap); + + glite_renewal_log(saved_ctx, dbg_level, "%s", str); + free(str); +} + +/* A new call not implemented in 3.0 version of voms.o */ +int +glite_renewal_check_voms_attrs(glite_renewal_core_context ctx, const char *proxy) +{ + int ret, voms_err, present; + X509 *cert = NULL; + STACK_OF(X509) *chain = NULL; + struct vomsdata *vd = NULL; + + ret = glite_renewal_load_proxy(ctx, proxy, &cert, NULL, &chain, NULL); + if (ret) + return 0; + + vd = VOMS_Init(NULL, NULL); + if (vd == NULL) { + present = 0; + goto end; + } + + ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, vd, &voms_err); + if (ret == 0) { + present = 0; + goto end; + } + + present = 1; + +end: + if (cert) + X509_free(cert); + if (chain) + sk_X509_pop_free(chain, X509_free); + if (vd) + VOMS_Destroy(vd); + + return present; +} -- 1.8.2.3