Added glite_renewal_core_renew() implementing the renewal process
authorDaniel Kouřil <kouril@ics.muni.cz>
Tue, 14 Mar 2006 12:33:42 +0000 (12:33 +0000)
committerDaniel Kouřil <kouril@ics.muni.cz>
Tue, 14 Mar 2006 12:33:42 +0000 (12:33 +0000)
org.glite.security.proxyrenewal/Makefile
org.glite.security.proxyrenewal/interface/renewal_core.h [new file with mode: 0644]
org.glite.security.proxyrenewal/src/renewal_core.c [new file with mode: 0644]

index 3730746..6c731c8 100644 (file)
@@ -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 (file)
index 0000000..1e8dc68
--- /dev/null
@@ -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 (file)
index 0000000..32e6ea8
--- /dev/null
@@ -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;
+}