From: Daniel KouĊ™il Date: Tue, 14 Mar 2006 12:33:42 +0000 (+0000) Subject: Added glite_renewal_core_renew() implementing the renewal process X-Git-Tag: merge_for_3_1_after~24 X-Git-Url: http://scientific.zcu.cz/git/?a=commitdiff_plain;h=4bafcbedf5ddd1cd97c1d3de1c7126634b787625;p=jra1mw.git Added glite_renewal_core_renew() implementing the renewal process --- diff --git a/org.glite.security.proxyrenewal/Makefile b/org.glite.security.proxyrenewal/Makefile index 3730746..6c731c8 100644 --- a/org.glite.security.proxyrenewal/Makefile +++ b/org.glite.security.proxyrenewal/Makefile @@ -30,7 +30,7 @@ distdir=. globalprefix=glite lbprefix=lb package=glite-security-proxyrenewal -version=1.0.0 +version=0.0.0 PREFIX=/opt/glite glite_location=$PREFIX @@ -41,7 +41,7 @@ myproxy_prefix=$globus_prefix -include Makefile.inc -VPATH:=${top_srcdir}/src +VPATH:=${top_srcdir}/src:${top_srcdir}/examples GLOBUSINC:= -I${globus_prefix}/include/${nothrflavour} \ -I${globus_prefix}/include/${nothrflavour}/openssl @@ -63,57 +63,83 @@ GLOBUS_LIBS:=-L${globus_prefix}/lib \ -lglobus_common_${nothrflavour} \ -lssl_${nothrflavour} -MYPROXY_LIB:=-L${myproxy_prefix}/lib -lmyproxy_${nothrflavour} +MYPROXY_LIB_NOTHR :=-L${myproxy_prefix}/lib -lmyproxy_${nothrflavour} +MYPROXY_LIB_THR:=-L${myproxy_prefix}/lib -lmyproxy_${thrflavour} JOBIDLIB:=-L${glite_location}/lib -lglite_wmsutils_cjobid +offset=1 +version_info:=-version-info ${shell \ + perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } + COMPILE:=libtool --mode=compile ${CC} ${CFLAGS} LINK:=libtool --mode=link ${CC} ${LDFLAGS} 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 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 + +VOMS_LIB_NOTHR := -L${glite_location}/lib -lvomsc_${nothrflavour} +VOMS_LIB_THR := -L${glite_location}/lib -lvomsc_${thrflavour} DAEMON:=glite-proxy-renewd CLIENT:=glite-proxy-renew +EXAMPLES := renew_core 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} - + ${LINK} ${version_info} -o $@ ${LIBLOBJ} -rpath ${glite_location}/lib ${JOBIDLIB} ${THRLIB}: ${THRLIBOBJ} - ${LINK} -o $@ ${THRLIBLOBJ} -rpath ${glite_location}/lib + ${LINK} ${version_info} -o $@ ${THRLIBLOBJ} -rpath ${glite_location}/lib + +${LIB_CORE_NOTHR}: ${LIB_CORE_NOTHR_OBJS} + ${LINK} ${version_info} -o $@ ${LIB_CORE_NOTHR_LOBJS} -rpath ${glite_location}/lib ${MYPROXY_LIB_NOTHR} ${VOMS_LIB_NOTHR} + +${LIB_CORE_THR}: ${LIB_CORE_THR_OBJS} + ${LINK} ${version_info} -o $@ ${LIB_CORE_THR_LOBJS} -rpath ${glite_location}/lib ${MYPROXY_LIB_THR} ${VOMS_LIB_THR} ${DAEMON}: ${DAEMONOBJ} - ${LINK} -o $@ ${DAEMONOBJ} ${JOBIDLIB} ${MYPROXY_LIB} -lvomsc -lglobus_gss_assist_${nothrflavour} ${GLOBUS_LIBS} + ${LINK} -o $@ ${DAEMONOBJ} ${JOBIDLIB} ${MYPROXY_LIB_NOTHR} -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 ${COMPILE} ${GLOBUSINC} -c $< +${EXAMPLES}: %: %.o + ${LINK} -o $@ $< ${LIB_CORE_NOTHR} + stage: compile $(MAKE) install PREFIX=${stagedir} - check: echo No unit tests +examples: ${EXAMPLES} + dist: distsrc distbin distsrc: @@ -129,13 +155,15 @@ 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) ${THRLIB} ${LIB_CORE_NOTHR} ${LIB_CORE_THR} $(DAEMON) $(CLIENT) *.o core + +.PHONY: default all compile examples check stage dist distsrc distbin install clean 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..1e8dc68 --- /dev/null +++ b/org.glite.security.proxyrenewal/interface/renewal_core.h @@ -0,0 +1,43 @@ +#ifndef RENEWAL_CORE_H +#define RENEWAL_CORE_H + +#ident "$Id$" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct glite_renewal_core_context_data { + int dbg_level; + char *cert; + char *key; + char *cadir; + int voms_enabled; +} glite_renewal_core_context_data; + +typedef struct glite_renewal_core_context_data *glite_renewal_core_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..32e6ea8 --- /dev/null +++ b/org.glite.security.proxyrenewal/src/renewal_core.c @@ -0,0 +1,216 @@ +#include "renewal_core.h" +#include "renewal_locl.h" +#include "renewd_locl.h" + +static const char rcsid[] = "$Id$"; + +int +load_proxy(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, 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 +get_proxy_base_name(char *file, char **name) +{ + X509 *cert = NULL; + EVP_PKEY *key = NULL; + STACK_OF(X509) *chain = NULL; + X509_NAME *subject = NULL; + int ret; + + ret = load_proxy(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; + + ret = globus_gsi_cert_utils_get_base_name(subject, chain); + if (ret) { + edg_wlpr_Log(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 context, + 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; + char *server = NULL; + myproxy_socket_attrs_t *socket_attrs; + myproxy_request_t *client_request; + myproxy_response_t *server_response; + char *renewed_proxy; + /* XXX */ + int voms_exts = 1; + + 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); + + edg_wlpr_Log(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) { + edg_wlpr_Log(LOG_ERR, "Cannot create temporary file (%s)", + strerror(errno)); + return errno; + } + + ret = get_proxy_base_name(current_proxy, &client_request->username); + if (ret) + goto end; + + client_request->proxy_lifetime = 60 * 60 * DGPR_RETRIEVE_DEFAULT_HOURS; + + server = (myproxy_server) ? myproxy_server : socket_attrs->pshost; + if (server == NULL) { + edg_wlpr_Log(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, current_proxy, + server_response, tmp_proxy); + if (ret == 1) { + ret = EDG_WLPR_ERROR_MYPROXY; + edg_wlpr_Log(LOG_ERR, "Error contacting MyProxy server for proxy %s: %s", + current_proxy, verror_get_string()); + verror_clear(); + goto end; + } + + renewed_proxy = tmp_proxy; + + if (context->voms_enabled && 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) { + edg_wlpr_Log(LOG_ERR, "Cannot create temporary file (%s)", + strerror(errno)); + ret = errno; + goto end; + } + + ret = renew_voms_creds(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; +}