Sprout from master 2004-06-18 13:20:25 UTC Aleš Křenek <ljocha@ics.muni.cz> 'initial import'
Cherrypick from master 2004-07-09 10:16:25 UTC Aleš Křenek <ljocha@ics.muni.cz> 'initial import':
org.glite.security.proxyrenewal/Makefile
org.glite.security.proxyrenewal/build.xml
org.glite.security.proxyrenewal/interface/renewal.h
org.glite.security.proxyrenewal/project/configure.properties.xml
org.glite.security.proxyrenewal/project/properties.xml
org.glite.security.proxyrenewal/project/taskdefs.xml
org.glite.security.proxyrenewal/src/api.c
org.glite.security.proxyrenewal/src/client.c
org.glite.security.proxyrenewal/src/commands.c
org.glite.security.proxyrenewal/src/common.c
org.glite.security.proxyrenewal/src/renew.c
org.glite.security.proxyrenewal/src/renewal_locl.h
org.glite.security.proxyrenewal/src/renewd.c
org.glite.security.proxyrenewal/src/renewd_locl.h
Cherrypick from master 2004-06-18 11:45:49 UTC Aleš Křenek <ljocha@ics.muni.cz> 'initial import':
org.glite.lb.client/.Makefile.swp
org.glite.lb.client/Makefile
Delete:
org.glite.wms-utils.jobid/.cvsignore
org.glite.wms-utils.jobid/LICENSE
org.glite.wms-utils.jobid/Makefile.am
org.glite.wms-utils.jobid/bootstrap
org.glite.wms-utils.jobid/build.xml
org.glite.wms-utils.jobid/configure.ac
org.glite.wms-utils.jobid/project/build.properties
org.glite.wms-utils.jobid/project/configure-options.xml
org.glite.wms-utils.jobid/project/properties.xml
org.glite.wms-utils.jobid/project/version.properties
org.glite.wms-utils.jobid/src/Makefile.am
org.glite.wms-utils.jobid/src/jobid/JobId.cpp
org.glite.wms-utils.jobid/src/jobid/JobId.h
org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp
org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.h
org.glite.wms-utils.jobid/src/jobid/Makefile.am
org.glite.wms-utils.jobid/src/jobid/cjobid.c
org.glite.wms-utils.jobid/src/jobid/cjobid.h
org.glite.wms-utils.jobid/src/jobid/manipulation.cpp
org.glite.wms-utils.jobid/src/jobid/manipulation.h
org.glite.wms-utils.jobid/src/jobid/strmd5.c
org.glite.wms-utils.jobid/src/jobid/strmd5.h
org.glite.wms-utils.jobid/test/Makefile.am
org.glite.wms-utils.jobid/test/testjobid.c
default: all
-compile: ${LIB} ${TOOLS} logevent
+compile: ${LIB} ${PLUSLIB} ${TOOLS} logevent
check:
echo No unit tests so far.
--- /dev/null
+# defaults
+top_srcdir=.
+builddir=build
+top_builddir=${top_srcdir}/${builddir}
+stagedir=.
+distdir=.
+globalprefix=glite
+lbprefix=lb
+package=glite-security-proxyrenewal
+version=0.0.0
+PREFIX=/opt/glite
+
+glite_location=/opt/glite
+globus_prefix=/opt/globus
+nothrflavour=gcc32
+thrflavour=gcc32pthr
+myproxy_prefix=/software/myproxy-0.4
+
+-include Makefile.inc
+
+VPATH:=${top_srcdir}/src
+
+GLOBUSINC:= -I${globus_prefix}/include/${nothrflavour} \
+ -I${globus_prefix}/include/${nothrflavour}/openssl
+
+GLOBUSTHRINC:= -I${globus_prefix}/include/${thrflavour} \
+ -I${globus_prefix}/include/${thrflavour}/openssl
+
+
+DEBUG:=-g -O0
+
+# XXX: until VOMS is ready in SCM
+CFLAGS:= -DNOVOMS \
+ ${DEBUG} \
+ -DVOMS_INSTALL_PATH=\"${voms_prefix}\"\
+ -I${myproxy_prefix}/include \
+ -I${top_srcdir}/src -I${top_srcdir}/interface \
+ -I${stagedir}/include
+
+GLOBUS_LIBS:=-L${globus_prefix}/lib \
+ -lglobus_common_${nothrflavour} \
+ -lssl_${nothrflavour}
+
+SSL_UTILS_LIB:=-L${stagedir}/lib -lglobus_ssl_utils
+MYPROXY_LIB:=-L${myproxy_prefix}/lib -lmyproxy
+
+JOBIDLIB:=-L${stagedir}/lib -lglite_wms_cjobid
+
+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
+LIBOBJ:=api.o common.o
+CLIENTOBJ:=client.o
+
+THRLIBOBJ:=${LIBOBJ:.o=.thr.o}
+LIBLOBJ:=${LIBOBJ:.o=.lo}
+THRLIBLOBJ:=${LIBOBJ:.o=.thr.lo}
+
+LIB:=libglite_security_proxyrenewal_${nothrflavour}.la
+THRLIB:=libglite_security_proxyrenewal_${thrflavour}.la
+
+DAEMON:=glite-proxy-renewd
+CLIENT:=glite-proxy-renew
+
+default: all
+compile all: ${LIB} ${THRLIB} ${DAEMON} ${CLIENT}
+
+${LIB}: ${LIBOBJ}
+ ${LINK} -o $@ ${LIBLOBJ} -rpath ${glite_location}/lib ${JOBIDLIB} ${SSL_UTILS_LIB}
+
+
+${THRLIB}: ${THRLIBOBJ}
+ ${LINK} -o $@ ${THRLIBLOBJ} -rpath ${glite_location}/lib ${SSL_UTILS_LIB}
+
+${DAEMON}: ${DAEMONOBJ}
+ ${LINK} -o $@ ${DAEMONOBJ} ${JOBIDLIB} ${SSL_UTILS_LIB} ${MYPROXY_LIB} -lglobus_gss_assist_${nothrflavour} ${GLOBUS_LIBS}
+
+${CLIENT}: ${CLIENTOBJ} ${LIB}
+ ${LINK} -o $@ ${CLIENTOBJ} ${LIB} ${GLOBUS_LIBS}
+
+${THRLIBOBJ}: %.thr.o: %.c
+ ${COMPILE} ${GLOBUSTHRINC} -o $@ -c $<
+
+%.o: %.c
+ ${COMPILE} ${GLOBUSINC} -c $<
+
+install:
+ -mkdir -p ${PREFIX}/bin ${PREFIX}/lib ${PREFIX}/include/glite/security
+ ${INSTALL} -m 644 ${LIB} ${THRLIB} ${PREFIX}/lib
+ ${INSTALL} -m 755 ${DAEMON} ${CLIENT} ${PREFIX}/bin
+ cd ${top_srcdir}/interface && ${INSTALL} -m 644 renewal.h ${PREFIX}/include/glite/security
+
+
+stage: compile
+ $(MAKE) install PREFIX=${stagedir}
+
+
+check:
+ echo No unit tests
University of Bergen (UiB), Norway
Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom
- Build file for the GLite WMS jobid module
+ Build file for the GLite LB Client module
- Authors: Alberto Di Meglio <alberto.di.meglio@cern.ch>
- Joachim Flammer <Joachim.Flammer@cern.ch>
+ Authors: Ales Krenek <ljocha@ics.muni.cz>
Version info: $Id$
Release: $Name$
Revision history:
$Log$
- Revision 1.1.1.1 2004/05/26 18:45:05 eronchie
- Import of wms jobid
+ Revision 1.2 2004/07/07 09:24:57 akrenek
+ thr/nonthr flavours used correctly
+
+ Revision 1.3 2004/07/06 17:45:30 flammer
+ Update of classpath definitions, targets & configure file.
+
+ Revision 1.2 2004/06/23 00:29:33 dimeglio
+ Added standard comments and handling of support files
-
-->
-<project name="jobid" default="dist">
-
- <!-- =========================================
- Builds the GLite WMS jobid Module
- ========================================= -->
+<project name="proxyrenewal" default="compile">
<!-- =========================================
Import properties (order is important)
- ========================================= -->
+ ========================================= -->
<!-- import baseline & user properties -->
<import file="../org.glite/project/baseline.properties.xml" />
<!-- =========================================
Load dependency property files (order is important)
- ========================================= -->
+ ========================================= -->
<property file="${user.dependencies.file}"/>
<property file="${component.dependencies.file}" />
<property file="${subsystem.dependencies.file}" />
<property file="${global.dependencies.file}"/>
-
+ <!-- =========================================
+ Load configure options (order is important)
+ ========================================= -->
+ <import file="${global.configure.options.file}"/>
+ <import file="${component.configure.options.file}"/>
+
<!-- =========================================
Import task definitions (order is important)
- ========================================= -->
+ ========================================= -->
<import file="${subsystem.taskdefs.file}" />
<import file="${global.taskdefs.file}" />
-
+
<!-- =========================================
- Load configure options
- ========================================= -->
- <property file="${global.configure.options.file}"/>
-
- <!-- =========================================
- Load common targets
- ========================================= -->
- <import file="${global.targets-external-dependencies.file}"/>
- <import file="${global.targets-make.file}" />
- <import file="${component.configure.options.file}"/>
-
+ Load common targets
+ ========================================= -->
+ <import file="${global.targets-simple_make.file}" />
+
<!-- =========================================
Load version file
- ========================================= -->
+ ========================================= -->
<property file="${module.version.file}"/>
<!-- ==============================================
Local private targets
- ============================================== -->
+ ============================================== -->
<target name="localinit"
description="Module specific initialization tasks">
+ <antcall target="lbmakefiles" />
</target>
<target name="localcompile"
--- /dev/null
+/**
+ * \file proxyrenewal/renewal.h
+ * \author Daniel Kouril
+ * \author Miroslav Ruda
+ * \brief API for proxy renewal.
+ * \version 2.0
+ *
+ * General rules:
+ * - functions return 0 on success, nonzero on error, errror details can
+ * be found via edg_wlpr_GetErrorText()
+ */
+
+#ifndef RENEWAL_H
+#define RENEWAL_H
+
+#ident "$Header$"
+
+#include "glite/wms/jobid/cjobid.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EDG_WLPR_FLAG_UNIQUE 1
+#define EDG_WLPR_FLAG_UPDATE 2
+
+typedef enum _edg_wlpr_ErrorCode {
+/**
+ * Base for proxy renewal specific code.
+ * Start sufficently high not to collide with standard errno. */
+ /* XXX see common/exception_codes.h */
+ EDG_WLPR_ERROR_BASE = 1900,
+ EDG_WLPR_ERROR_UNEXPECTED_EOF,
+ EDG_WLPR_ERROR_GENERIC,
+ EDG_WLPR_ERROR_PROTO_PARSE_ERROR,
+ EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND,
+ EDG_WLPR_ERROR_UNKNOWN_COMMAND,
+ EDG_WLPR_ERROR_SSL,
+ EDG_WLPR_ERROR_MYPROXY,
+ EDG_WLPR_PROXY_NOT_REGISTERED,
+ EDG_WLPR_PROXY_EXPIRED,
+ EDG_WLPR_ERROR_VOMS,
+} edg_wlpr_ErrorCode;
+
+/**
+ * Return a human readable string containg description of the errorcode
+ * \retval char* pointer to a error description
+ */
+const char *
+edg_wlpr_GetErrorText(int err_code);
+
+/**
+ * This function contacts the renewal daemon and registers the specified proxy
+ * for periodic renewal.
+ * \param filename IN: specification of the proxy to register.
+ * \param jdl IN: JDL of the job owing the proxy. The JDL is looked for a
+ * myproxy server contact.
+ * \param flags IN: one of EDG_WLPR_FLAG_UNIQUE or EDG_WLPR_FLAG_UPDATE, or
+ * their bitwise OR.
+ * \param repository_filename OUT: filename of registered proxy in repository.
+ * \retval 0 success
+ * \retval nonzero on error. Human readable form of the error can be get via
+ * edg_wlpr_GetErrorText().
+ */
+int
+edg_wlpr_RegisterProxy(
+ const char * filename,
+ const char *jdl,
+ int flags,
+ char ** repository_filename
+);
+
+/**
+ * The same function as edg_wlpr_RegisterProxy() but information about the
+ * myproxy server and jobid are passed as parameters instead of in JDL.
+ */
+int
+edg_wlpr_RegisterProxyExt(
+ const char * filename,
+ const char * server,
+ unsigned int port,
+ edg_wlc_JobId jobid,
+ int flags,
+ char ** repository_filename
+);
+
+/**
+ * Unregister proxy from the renewal daemon.
+ * \param jobid IN: specification of job whose proxy shall be unregistered
+ * \param filename IN: (optional) specification of the proxy to unregister.
+ * \retval 0 success
+ * \retval nonzero on error. Human readable form of the error can be get via
+ * edg_wlpr_GetErrorText().
+ */
+int
+edg_wlpr_UnregisterProxy(
+ edg_wlc_JobId jobid,
+ const char * repository_filename
+);
+
+/**
+ * Get a list of registered proxies maintained by the renewal daemon.
+ * \param count OUT: number of proxies
+ * \param list OUT: a list of filenames separated by '\n'
+ * specifying the registered proxies.
+ * \warning The caller is responsible for freeing the data.
+ * \retval 0 success
+ * \retval nonzero on error. Human readable form of the error can be get via
+ * edg_wlpr_GetErrorText().
+ */
+int
+edg_wlpr_GetList(int *count, char **list);
+
+/**
+ * Get a status message about a proxy.
+ * The function contacts the renewal daemon and retrieve information it
+ * maintains about the proxy.
+ * \param filename IN: specification of the proxy to query
+ * \param info OUT: status message.
+ * \warning The caller is responsible for freeing the data.
+ * \retval 0 success
+ * \retval nonzero on error. Human readable form of the error can be get via
+ * edg_wlpr_GetErrorText().
+ */
+int
+edg_wlpr_GetStatus(const char *repository_filename, char **info);
+
+/**
+ * For given jobid return registered proxy filename from repository
+ * \param jobid IN: specification of jobid
+ * \param repository_filename OUT: proxy regitered for given jobid
+ * \warning The caller is responsible for freeing the data.
+ * \retval 0 success
+ * \retval nonzero on error. Human readable form of the error can be get via
+ * edg_wlpr_GetErrorText().
+ */
+int
+edg_wlpr_GetProxy(edg_wlc_JobId jobid, char **repository_filename);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RENEWAL_H */
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ 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
+
+ Configuration options for the GLite LB Client module
+
+ Authors: Ales Krenek <ljocha@ics.muni.cz>
+-->
+
+ <!-- ======================================================
+ Define extra properties here ...
+ ====================================================== -->
+
+ <project name="LB Client configuration options">
+ <target name="lbmakefiles">
+ <exec executable="ln" failonerror="true">
+ <arg line="-fs ${component.dir}/Makefile ${module.build.dir}/Makefile"/>
+ </exec>
+ <echo file="${module.build.dir}/Makefile.inc">
+top_srcdir=..
+builddir=build
+stagedir=${stage.abs.dir}
+distdir=${dist.dir}
+globalprefix=${global.prefix}
+package=${module.package.name}
+PREFIX=${install.dir}
+version=${module.version}
+glite_location=${with.glite.location}
+globus_prefix=${with.globus.prefix}
+thrflavour=${with.globus.thr.flavor}
+nothrflavour=${with.globus.nothr.flavor}
+ </echo>
+ </target>
+ </project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project name="Proxy renewal">
+
+ <property file="build.properties" />
+ <property name="subsystem.name" value="${security.subsystem.name}"/>
+ <property name="subsystem.prefix" value="${security.subsystem.prefix}"/>
+ <property name="component.prefix" value="proxyrenewal" />
+
+ <import file="${component.general.properties.file}" />
+
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project name="tasks and types definitions">
+</project>
--- /dev/null
+#include "renewal.h"
+#include "renewal_locl.h"
+
+#ident "$Header$"
+
+#define SEPARATORS "\n"
+
+/* prototypes of static routines */
+static int
+encode_request(edg_wlpr_Request *request, char **msg);
+
+static int
+decode_response(const char *msg, const size_t msg_len, edg_wlpr_Response *response);
+
+static int
+do_connect(char *socket_name, int *sock);
+
+static int
+send_request(int sock, edg_wlpr_Request *request, edg_wlpr_Response *response);
+
+
+static int
+encode_request(edg_wlpr_Request *request, char **msg)
+{
+ char *buf;
+ size_t buf_len;
+ int ret;
+
+ buf_len = EDG_WLPR_BUF_SIZE;
+ buf = malloc(buf_len);
+ if (buf == NULL)
+ return ENOMEM;
+ buf[0] = '\0';
+
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_VERSION,
+ EDG_WLPR_VERSION, SEPARATORS);
+ if (ret)
+ goto err;
+
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_COMMAND,
+ edg_wlpr_EncodeInt(request->command),
+ SEPARATORS);
+ if (ret)
+ goto err;
+
+ if (request->myproxy_server) {
+ char host[1024];
+
+#if 0
+ snprintf(host, sizeof(host), "%s:%d", request->myproxy_server,
+ (request->myproxy_port) ? request->myproxy_port : EDG_WLPR_MYPROXY_PORT); /* XXX let server decide ? */
+#else
+ snprintf(host, sizeof(host), "%s", request->myproxy_server);
+#endif
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_MYPROXY_SERVER,
+ host, SEPARATORS);
+ if (ret)
+ goto err;
+ }
+
+ if (request->proxy_filename) {
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_PROXY,
+ request->proxy_filename, SEPARATORS);
+ if (ret)
+ goto err;
+ }
+
+ if (request->jobid) {
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_JOBID,
+ request->jobid, SEPARATORS);
+ if (ret)
+ goto err;
+ }
+
+ if (request->entries) {
+ char **p = request->entries;
+ while (*p) {
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_ENTRY,
+ *p, SEPARATORS);
+ if (ret)
+ goto err;
+ p++;
+ }
+ }
+
+ buf[strlen(buf)] = '\0';
+ *msg = buf;
+ return 0;
+
+err:
+ free(buf);
+ *msg = NULL;
+ return ret;
+}
+
+static int
+decode_response(const char *msg, const size_t msg_len, edg_wlpr_Response *response)
+{
+ int ret;
+ char *value = NULL;
+ /* char *p; */
+ int i;
+ int current_size = 0;
+
+ /* XXX add an ending zero '\0' */
+
+ assert(msg != NULL);
+ assert(response != NULL);
+
+ memset(response, 0, sizeof(*response));
+
+ ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_VERSION, SEPARATORS,
+ 0, &response->version);
+ if (ret)
+ goto err;
+
+ ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_RESPONSE, SEPARATORS,
+ 0, &value);
+ if (ret)
+ goto err;
+
+ ret = edg_wlpr_DecodeInt(value, (int *)(&response->response_code));
+ free(value);
+ if (ret)
+ goto err;
+
+ ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_MYPROXY_SERVER,
+ SEPARATORS, 0, &response->myproxy_server);
+ if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND)
+ goto err;
+
+#if 0
+ response->myproxy_port = EDG_WLPR_MYPROXY_PORT; /* ??? */
+ if (response->myproxy_server && (p = strchr(response->myproxy_server, ':'))) {
+ int port;
+ *p = '\0';
+ port = atol(p+1); /* XXX */
+ response->myproxy_port = port;
+ }
+#endif
+
+ ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_START_TIME, SEPARATORS,
+ 0, &value);
+ if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND)
+ goto err;
+ if (ret == 0) {
+ ret = edg_wlpr_DecodeInt(value, (int *)(&response->start_time));
+ free(value);
+ if (ret)
+ goto err;
+ }
+
+ ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_END_TIME, SEPARATORS,
+ 0, &value);
+ if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND)
+ goto err;
+ if (ret == 0) {
+ ret = edg_wlpr_DecodeInt(value, (int *)(&response->end_time));
+ free(value);
+ if (ret)
+ goto err;
+ }
+
+ ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_RENEWAL_TIME,
+ SEPARATORS, 0, &value);
+ if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND)
+ goto err;
+ if (ret == 0) {
+ ret = edg_wlpr_DecodeInt(value, (int *)(&response->next_renewal_time));
+ free(value);
+ if (ret)
+ goto err;
+ }
+
+ /* XXX Counter */
+
+ i = 0;
+ while ((ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_PROXY,
+ SEPARATORS, i, &value)) == 0) {
+ if (i >= current_size) {
+ char **tmp;
+
+ tmp = realloc(response->filenames,
+ (current_size + 16 + 1) * sizeof(*tmp));
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto err;
+ }
+ response->filenames = tmp;
+ current_size += 16;
+ }
+ response->filenames[i] = value;
+ i++;
+ }
+ if (ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND)
+ goto err;
+ if (response->filenames)
+ response->filenames[i] = NULL;
+
+ return 0;
+
+err:
+ edg_wlpr_CleanResponse(response);
+
+ return ret;
+}
+
+static int
+do_connect(char *socket_name, int *sock)
+{
+ struct sockaddr_un my_addr;
+ int s;
+ int ret;
+
+ assert(sock != NULL);
+ memset(&my_addr, 0, sizeof(my_addr));
+
+ s = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (s == -1) {
+ return errno;
+ }
+
+ my_addr.sun_family = AF_UNIX;
+ strncpy(my_addr.sun_path, socket_name, sizeof(my_addr.sun_path));
+
+ ret = connect(s, (struct sockaddr *) &my_addr, sizeof(my_addr));
+ if (ret == -1) {
+ close(s);
+ return errno;
+ }
+
+ *sock = s;
+ return 0;
+}
+
+static int
+send_request(int sock, edg_wlpr_Request *request, edg_wlpr_Response *response)
+{
+ int ret;
+ char *buf = NULL;
+ size_t buf_len;
+
+ /* timeouts ?? */
+
+ ret = encode_request(request, &buf);
+ if (ret)
+ return ret;
+
+ ret = edg_wlpr_Write(sock, buf, strlen(buf) + 1);
+ free(buf);
+ if (ret)
+ return ret;
+
+ ret = edg_wlpr_Read(sock, &buf, &buf_len);
+ if (ret)
+ return ret;
+
+ ret = decode_response(buf, buf_len, response);
+ free(buf);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int
+edg_wlpr_RequestSend(edg_wlpr_Request *request, edg_wlpr_Response *response)
+{
+ char sockname[1024];
+ int ret;
+ int sock;
+
+ snprintf(sockname, sizeof(sockname), "%s%d",
+ DGPR_REG_SOCKET_NAME_ROOT, getuid());
+ ret = do_connect(sockname, &sock);
+ if (ret)
+ return ret;
+
+ ret = send_request(sock, request, response);
+
+ close(sock);
+ return ret;
+}
+
+int
+edg_wlpr_RegisterProxyExt(const char *filename, const char * server,
+ unsigned int port,
+ edg_wlc_JobId jobid, int flags,
+ char **repository_filename)
+{
+ edg_wlpr_Request request;
+ edg_wlpr_Response response;
+ int ret;
+
+ memset(&request, 0, sizeof(request));
+ memset(&response, 0, sizeof(response));
+
+ request.command = EDG_WLPR_COMMAND_REG;
+ request.myproxy_server = server;
+ request.proxy_filename = filename;
+ request.jobid = edg_wlc_JobIdUnparse(jobid);
+ if (request.jobid == NULL)
+ return EINVAL; /* XXX */
+
+ ret = edg_wlpr_RequestSend(&request, &response);
+ free(request.jobid);
+ if (ret == 0 && response.response_code == 0 && repository_filename &&
+ response.filenames && response.filenames[0] )
+ *repository_filename = strdup(response.filenames[0]);
+
+ if (ret == 0)
+ ret = response.response_code;
+
+ edg_wlpr_CleanResponse(&response);
+
+ return ret;
+}
+
+int
+edg_wlpr_RegisterProxy(const char *filename, const char *jdl,
+ int flags, char **repository_filename)
+{
+ char server[1024];
+ size_t server_len;
+ unsigned int port = 0;
+ char *p, *q;
+
+ memset(server, 0, sizeof(server));
+
+ /* parse JDL and find information about myproxy server */
+ p = strstr(jdl, JDL_MYPROXY);
+ if (p == NULL)
+ return 0; /* XXX */
+ q = strchr(p, '\n'); /* XXX */
+ if (q)
+ server_len = q - p;
+ else
+ server_len = jdl + strlen(jdl) - p;
+ if (server_len >= sizeof(server))
+ return EINVAL; /* XXX */
+ strncmp(server, p, sizeof(server));
+
+ return (edg_wlpr_RegisterProxyExt(filename, server, port, NULL, flags,
+ repository_filename));
+}
+
+int
+edg_wlpr_UnregisterProxy(edg_wlc_JobId jobid, const char *repository_filename)
+{
+ edg_wlpr_Request request;
+ edg_wlpr_Response response;
+ int ret;
+
+ memset(&request, 0, sizeof(request));
+ memset(&response, 0, sizeof(response));
+
+ request.command = EDG_WLPR_COMMAND_UNREG;
+ request.proxy_filename = repository_filename;
+ request.jobid = edg_wlc_JobIdUnparse(jobid);
+ if (request.jobid == NULL)
+ return EINVAL;
+
+ ret = edg_wlpr_RequestSend(&request, &response);
+ free(request.jobid);
+
+ if (ret == 0)
+ ret = response.response_code;
+ edg_wlpr_CleanResponse(&response);
+
+ return ret;
+}
+
+int
+edg_wlpr_GetList(int *count, char **list)
+{
+ return ENOSYS; /* XXX */
+}
+
+int
+edg_wlpr_GetStatus(const char *filename, char **info)
+{
+ return ENOSYS; /* XXX */
+}
+
+static const char* const errTexts[] = {
+ "Unexpected EOF from peer",
+ "Generic error",
+ "Protocol parse error",
+ "Compulsory element not found in message",
+ "Unknown protocol command",
+ "SSL error",
+ "Error from Myproxy server",
+ "Proxy not registered",
+ "Proxy expired",
+ "VOMS error",
+};
+
+const char *
+edg_wlpr_GetErrorText(int code)
+{
+ return code ?
+ (code <= EDG_WLPR_ERROR_BASE ?
+ strerror(code) :
+ errTexts[code - EDG_WLPR_ERROR_BASE - 1]
+ ) :
+ NULL;
+}
+
+int
+edg_wlpr_GetProxy(edg_wlc_JobId jobid, char **repository_filename)
+{
+ edg_wlpr_Request request;
+ edg_wlpr_Response response;
+ int ret;
+
+ memset(&request, 0, sizeof(request));
+ memset(&response, 0, sizeof(response));
+
+ request.command = EDG_WLPR_COMMAND_GET;
+ request.jobid = edg_wlc_JobIdUnparse(jobid);
+ if (request.jobid == NULL)
+ return EINVAL;
+
+ ret = edg_wlpr_RequestSend(&request, &response);
+ free(request.jobid);
+
+ if (ret == 0 && response.response_code == 0 && repository_filename &&
+ response.filenames && response.filenames[0] )
+ *repository_filename = strdup(response.filenames[0]);
+
+ if (ret == 0)
+ ret = response.response_code;
+ edg_wlpr_CleanResponse(&response);
+
+ return ret;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+#include "renewal.h"
+
+static const char rcsid[] = "$Header$";
+
+static struct option const long_options[] = {
+ { "help", no_argument, 0, 'h' },
+ { "version", no_argument, 0, 'v' },
+ { "server", required_argument, 0, 's' },
+ { "port", required_argument, 0, 'p' },
+ { "file", required_argument, 0, 'f' },
+ { "jobid", required_argument, 0, 'j' },
+ { NULL, 0, NULL, 0}
+};
+
+static char short_options[] = "hvs:p:f:j:";
+
+static void
+usage(exit_code)
+{
+ fprintf(stdout, "Usage: edg-wl-renew [option] operation\n"
+ "\t-s myproxy_server [-p port] -f filename -j jobid start |\n"
+ "\t-j jobid [-f filename] stop |\n"
+ "\t-j jobid get\n"
+ "-h, --help display this help and exit\n"
+ "-v, --version output version information and exit\n"
+ "-s, --server <fqdn> address of myproxy server\n"
+ "-p, --port <num> port of myproxy server\n"
+ "-f, --file <file> filename with proxy\n"
+ "-j, --jobid <str> datagrid jobid\n");
+ exit(exit_code);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *server = NULL;
+ int port = 0;
+ char *proxyfile = NULL;
+ char *jobid_str = NULL;
+ edg_wlc_JobId jobid = NULL;
+ char *repository_filename = NULL;
+ int ret;
+ int arg;
+ extern int optind;
+
+ while ((arg = getopt_long(argc, argv,
+ short_options, long_options, (int *) 0)) != EOF)
+ switch(arg) {
+ case 'h':
+ usage(0); break;
+ case 'v':
+ fprintf(stdout, "%s:\t%s\n", argv[0], rcsid); exit(0);
+ case 's':
+ server = strdup(optarg); break;
+ case 'p':
+ port = atoi(optarg); break;
+ case 'f':
+ proxyfile = strdup(optarg); break;
+ case 'j':
+ jobid_str = strdup(optarg); break;
+ default:
+ usage(1); break;
+ }
+
+ if (optind >= argc)
+ usage(1);
+
+ if (jobid_str && edg_wlc_JobIdParse(jobid_str, &jobid)) {
+ fprintf(stderr, "Cannot parse jobid\n");
+ exit(1);
+ }
+
+ if (strcmp(argv[optind], "start") == 0) {
+ if (proxyfile == NULL || server == NULL || jobid == NULL)
+ usage(1);
+ ret = edg_wlpr_RegisterProxyExt(proxyfile, server, port, jobid, 0,
+ &repository_filename);
+ if (ret) {
+ fprintf(stderr, "Registering proxy failed: %s\n",
+ edg_wlpr_GetErrorText(ret));
+ exit(1);
+ }
+ printf("%s\n", repository_filename);
+ free(repository_filename);
+ exit(0);
+ }
+ else if (strcmp(argv[optind], "stop") == 0) {
+ if (jobid == NULL)
+ usage(1);
+ ret = edg_wlpr_UnregisterProxy(jobid, proxyfile);
+ if (ret) {
+ fprintf(stderr, "Unregistering proxy failed: %s\n",
+ edg_wlpr_GetErrorText(ret));
+ exit(1);
+ }
+ }
+ else if (strcmp(argv[optind], "get") == 0) {
+ if (jobid == NULL)
+ usage(1);
+ ret = edg_wlpr_GetProxy(jobid, &proxyfile);
+ if (ret) {
+ fprintf(stderr, "GET request failed: %s\n",
+ edg_wlpr_GetErrorText(ret));
+ exit(1);
+ }
+ printf("%s\n", proxyfile);
+ free(proxyfile);
+ }
+ else
+ usage(1);
+
+ return 0;
+}
--- /dev/null
+#include "renewal_locl.h"
+#include "renewd_locl.h"
+
+#ifndef NOVOMS
+#include <voms_apic.h>
+#endif
+
+#ident "$Header$"
+
+#define SEPARATORS ",\n"
+#define RENEWAL_START_FRACTION 0.75 /* XXX */
+#define RENEWAL_CLOCK_SKEW (5 * 60)
+#define RENEWAL_MIN_LIFETIME (15 * 60)
+
+extern char *repository;
+extern time_t condor_limit;
+extern char *cadir;
+extern char *vomsdir;
+extern int voms_enabled;
+
+static char *
+strmd5(const char *s, unsigned char *digest);
+
+static int
+get_record_ext(FILE *fd, proxy_record *record, int *last_used_suffix);
+
+static int
+get_record(FILE *fd, proxy_record *record);
+
+static int
+store_record(char *basename, proxy_record *record);
+
+static int
+copy_file_content(FILE *in, FILE *out);
+
+static int
+copy_file(char *src, char *dst);
+
+static int
+get_base_filename(char *proxy_file, char **basefilename);
+
+int
+decode_record(char *line, proxy_record *record);
+
+int
+encode_record(proxy_record *record, char **line);
+
+static int
+open_metafile(char *proxy_file, FILE **fd);
+
+void
+free_record(proxy_record *record);
+
+static int
+realloc_prd_list(prd_list *list);
+
+/* make public: */
+static int
+edg_wlpr_GetTokenInt(const char *msg, const size_t msg_len,
+ const char *key, const char *separators,
+ int req_index, int *value);
+
+static void
+record_to_response(int status_code, proxy_record *record,
+ edg_wlpr_Response *response);
+
+static int
+filename_to_response(char *filename, edg_wlpr_Response *response);
+
+
+
+
+static char *
+strmd5(const char *s, unsigned char *digest)
+{
+ MD5_CTX md5;
+ unsigned char d[16];
+ int i;
+ static char mbuf[33];
+
+ MD5_Init(&md5);
+ MD5_Update(&md5,s,strlen(s));
+ MD5_Final(d,&md5);
+
+ if (digest)
+ memcpy(digest,d,sizeof(d));
+ for (i=0; i<16; i++) {
+ int dd = d[i] & 0x0f;
+ mbuf[2*i+1] = dd<10 ? dd+'0' : dd-10+'a';
+ dd = d[i] >> 4;
+ mbuf[2*i] = dd<10 ? dd+'0' : dd-10+'a';
+ }
+ mbuf[32] = 0;
+ return mbuf;
+}
+
+static int
+get_base_filename(char *proxy_file, char **basefilename)
+{
+ FILE *cert_file = NULL;
+ X509 *cert = NULL;
+ X509_NAME *s = NULL;
+ char *subject = NULL;
+ char file[FILENAME_MAX];
+ int ret;
+
+ assert(basefilename != NULL);
+
+ cert_file = fopen(proxy_file, "r");
+ if (cert_file == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot open file %s (%s)",
+ proxy_file, strerror(errno));
+ return errno;
+ }
+
+ cert = PEM_read_X509(cert_file, NULL, NULL, NULL);
+ if (cert == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot read certificate from %s", proxy_file);
+ ret = EDG_WLPR_ERROR_SSL; /* XXX */
+ goto end;
+ }
+
+ s = X509_NAME_dup(X509_get_subject_name(cert));
+ proxy_get_base_name(s);
+ subject = X509_NAME_oneline(s, NULL, 0);
+ X509_NAME_free(s);
+ X509_free(cert);
+ if (subject == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot read subject name from %s", proxy_file);
+ ret = EDG_WLPR_ERROR_SSL; /* XXX */
+ goto end;
+ }
+
+ snprintf(file, sizeof(file), "%s/%s", repository, strmd5(subject, NULL));
+ *basefilename = strdup(file); /* XXX test ENOMEM */
+ ret = 0;
+
+end:
+ if (subject)
+ free(subject);
+ fclose(cert_file);
+ return ret;
+}
+
+static int
+copy_file_content(FILE *in, FILE *out)
+{
+ char buf[1024];
+ size_t num;
+ int ret;
+
+ while (1) {
+ num = fread(buf, sizeof(*buf), sizeof(buf), in);
+ if ((ret = ferror(in))) {
+ edg_wlpr_Log(LOG_ERR, "Reading failed: %s", strerror(errno));
+ return ret;
+ }
+ num = fwrite(buf, sizeof(*buf), num, out);
+ if ((ret = ferror(in))) {
+ edg_wlpr_Log(LOG_ERR, "Writing failed: %s", strerror(errno));
+ return ret;
+ }
+ if (feof(in))
+ return 0;
+ }
+}
+
+/* return the time interval, after which the renewal should be started */
+static time_t
+get_delta(time_t current_time, time_t start_time, time_t end_time)
+{
+ time_t length, lifetime;
+ time_t delta;
+ int condor_tested = 0;
+
+ lifetime = end_time - start_time;
+ delta = 0;
+ while (1) {
+ if (end_time - current_time <= RENEWAL_MIN_LIFETIME)
+ /* if the proxy is too short, renew it as soon as possible */
+ return RENEWAL_CLOCK_SKEW;
+
+ /* renewal starts at 3/4 of lifetime */
+ length = end_time - (start_time + delta);
+ delta += length * RENEWAL_START_FRACTION;
+
+ if (!condor_tested && delta > lifetime - condor_limit) {
+ /* Condor requires the proxies to be renewed a specified time interval
+ before the proxies have expired (see the
+ GRIDMANAGER_MINIMUM_PROXY_TIME variable). We must ensure that
+ renewal takes place before Condor does this check */
+ if (current_time > end_time - condor_limit) {
+ edg_wlpr_Log(LOG_ERR, "Proxy lifetime exceeded value of the Condor limit!");
+ }
+ else
+ delta = lifetime - condor_limit - RENEWAL_CLOCK_SKEW;
+ condor_tested = 1;
+ }
+
+ if (abs(current_time - (start_time + delta)) < RENEWAL_CLOCK_SKEW)
+ continue;
+
+ return (start_time + delta) - current_time;
+ };
+
+ /* not reachable */
+ return 0;
+}
+
+int
+get_times(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);
+
+ fd = fopen(proxy_file, "r");
+ if (fd == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Opening proxy file %s failed: %s",
+ proxy_file, strerror(errno));
+ return errno;
+ }
+
+ cert = PEM_read_X509(fd, NULL, NULL, NULL);
+ if (cert == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot read X.509 certificate from %s",
+ proxy_file);
+ ret = -1; /* XXX SSL_ERROR */
+ goto end;
+ }
+
+ asn1_time = ASN1_UTCTIME_new();
+ X509_gmtime_adj(asn1_time,0);
+ end_time = ASN1_UTCTIME_mktime(X509_get_notAfter(cert));
+ start_time = ASN1_UTCTIME_mktime(X509_get_notBefore(cert));
+ 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) {
+ edg_wlpr_Log(LOG_ERR, "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;
+ }
+ edg_wlpr_Log(LOG_ERR, "Cannot read additional certificates from %s",
+ proxy_file);
+ ret = -1; /* XXX SSL_ERROR */
+ goto end;
+ }
+ tmp_end = ASN1_UTCTIME_mktime(X509_get_notAfter(cert));
+ if (tmp_end + RENEWAL_CLOCK_SKEW < current_time) {
+ edg_wlpr_Log(LOG_ERR, "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(current_time, start_time,
+ end_time);
+ record->end_time = end_time;
+ ret = 0;
+
+end:
+ fclose(fd);
+ if (cert)
+ X509_free(cert);
+
+ return ret;
+}
+
+static int
+copy_file(char *src, char *dst)
+{
+ FILE *from = NULL;
+ FILE *tmp_to = NULL;
+ int tmp_fd;
+ char tmpfile[FILENAME_MAX];
+ int ret;
+
+ if (strcmp(src, dst) == 0)
+ return 0;
+
+ from = fopen(src, "r");
+ if (from == NULL) {
+ edg_wlpr_Log(LOG_ERR, "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) {
+ edg_wlpr_Log(LOG_ERR, "Cannot create temporary file (%s)",
+ strerror(errno));
+ ret = errno;
+ goto end;
+ }
+
+
+ tmp_to = fdopen(tmp_fd, "w");
+ if (tmp_to == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot associate stream with temporary file (%s)",
+ strerror(errno));
+ unlink(tmpfile);
+ ret = errno;
+ goto end;
+ }
+
+ ret = copy_file_content(from, tmp_to);
+ fclose(tmp_to);
+ if (ret) {
+ goto end;
+ }
+
+ ret = rename(tmpfile, dst);
+ if (ret) {
+ edg_wlpr_Log(LOG_ERR, "Cannot replace repository file %s with temporary file (%s)",
+ strerror(errno));
+ unlink(tmpfile);
+ ret = errno;
+ goto end;
+ }
+ tmp_to = NULL;
+
+end:
+ fclose(from);
+ close(tmp_fd);
+ unlink(tmpfile);
+
+ return ret;
+}
+
+void
+free_record(proxy_record *record)
+{
+ int i;
+
+ if (record == NULL)
+ return;
+ if (record->myproxy_server)
+ free(record->myproxy_server);
+ if (record->jobids.val) {
+ for (i = 0; i < record->jobids.len; i++)
+ free(record->jobids.val[i]);
+ free(record->jobids.val);
+ }
+ memset(record, 0, sizeof(*record));
+}
+
+static int
+realloc_prd_list(prd_list *list)
+{
+ char **tmp;
+
+ tmp = realloc(list->val, (list->len + 1) * sizeof(*list->val));
+ if (tmp == NULL)
+ return ENOMEM;
+ list->val = tmp;
+ list->len++;
+ return 0;
+}
+
+static int
+get_jobids(const char *msg, const size_t msg_len, proxy_record *record)
+{
+ int index = 0;
+ int ret;
+ char *value;
+ char **tmp;
+
+ memset(&record->jobids, 0, sizeof(record->jobids));
+ while ((ret = edg_wlpr_GetToken(msg, msg_len, "jobid=", SEPARATORS,
+ index, &value)) == 0) {
+ tmp = realloc(record->jobids.val, (record->jobids.len + 1) * sizeof(*tmp));
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ break;
+ }
+ record->jobids.val = tmp;
+ record->jobids.val[index] = value;
+ record->jobids.len++;
+ index++;
+ }
+ if (ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND) {
+ if (record->jobids.len)
+ free(record->jobids.val);
+ record->jobids.len = 0;
+ record->jobids.val = NULL;
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+edg_wlpr_GetTokenInt(const char *msg, const size_t msg_len,
+ const char *key, const char *separators,
+ int req_index, int *value)
+{
+ int ret;
+ char *str_value = NULL;
+
+ ret = edg_wlpr_GetToken(msg, msg_len, key, separators, req_index, &str_value);
+ if (ret)
+ return ret;
+
+ ret = edg_wlpr_DecodeInt(str_value, value);
+ free(str_value);
+ return ret;
+}
+
+int
+decode_record(char *line, proxy_record *record)
+{
+ /* line must be ended with '\0' */
+ int ret;
+ size_t len;
+
+ assert(line != NULL);
+ assert(record != NULL);
+
+ memset(record, 0, sizeof(*record));
+
+ len = strlen(line) + 1;
+
+ ret = edg_wlpr_GetTokenInt(line, len, "suffix=", SEPARATORS, 0,
+ &record->suffix);
+ if (ret)
+ return ret;
+
+#if 0
+ ret = edg_wlpr_GetTokenInt(line, len, "counter=", SEPARATORS, 0,
+ &record->counter);
+ if (ret)
+ goto end;
+#endif
+
+ ret = edg_wlpr_GetTokenInt(line, len, "unique=", SEPARATORS, 0,
+ &record->unique);
+ if (ret)
+ goto end;
+
+ ret = edg_wlpr_GetTokenInt(line, len, "voms_exts=", SEPARATORS, 0,
+ &record->voms_exts);
+
+ ret = edg_wlpr_GetToken(line, len, "server=", SEPARATORS, 0,
+ &record->myproxy_server);
+ if (ret)
+ goto end;
+
+ ret = edg_wlpr_GetTokenInt(line, len, "next_renewal=", SEPARATORS, 0,
+ (int *)&record->next_renewal);
+ if (ret)
+ goto end;
+
+ ret = edg_wlpr_GetTokenInt(line, len, "end_time=", SEPARATORS, 0,
+ (int *)&record->end_time);
+ if (ret)
+ goto end;
+
+ ret = get_jobids(line, len, record);
+ if (ret)
+ goto end;
+
+end:
+ if (ret)
+ free_record(record);
+
+ return ret;
+}
+
+int
+encode_record(proxy_record *record, char **line)
+{
+ char tmp_line[1024];
+ size_t jobids_len = 0;
+ int i;
+
+ snprintf(tmp_line, sizeof(tmp_line), "suffix=%d, unique=%d, voms_exts=%d, server=%s, next_renewal=%ld, end_time=%ld",
+ record->suffix, record->unique, record->voms_exts,
+ (record->myproxy_server) ? record->myproxy_server : "",
+ record->next_renewal, record->end_time);
+ for (i = 0; i < record->jobids.len; i++)
+ /* alloc space for string ", jobid=<jobid>" */
+ jobids_len += 2 + strlen("jobid=") + strlen(record->jobids.val[i]);
+
+ *line = calloc(1, strlen(tmp_line) + jobids_len + 1);
+ if (*line == NULL)
+ return ENOMEM;
+
+ strcat(*line, tmp_line);
+ memset(tmp_line, 0, sizeof(tmp_line));
+
+ for (i = 0; i < record->jobids.len; i++) {
+ snprintf(tmp_line, sizeof(tmp_line), ", jobid=%s", record->jobids.val[i]);
+ strcat(*line, tmp_line);
+ }
+
+ return 0;
+}
+
+/* Get proxy record from the index file. If no suffix is defined return a free
+ record with the smallest index */
+static int
+get_record_ext(FILE *fd, proxy_record *record, int *last_used_suffix)
+{
+ char line[1024];
+ int last_suffix = -1;
+ int ret;
+ char *p;
+ proxy_record tmp_record;
+ time_t current_time;
+
+ assert(record != NULL);
+ memset(&tmp_record, 0, sizeof(tmp_record));
+
+ current_time = time(NULL);
+ while (fgets(line, sizeof(line), fd) != NULL) {
+ free_record(&tmp_record);
+ p = strchr(line, '\n');
+ if (p)
+ *p = '\0';
+ ret = decode_record(line, &tmp_record);
+ if (ret)
+ return ret; /* XXX continue */
+ if (record->suffix >= 0) {
+ if (record->suffix == tmp_record.suffix) {
+ record->suffix = tmp_record.suffix;
+ record->jobids.len = tmp_record.jobids.len;
+ record->jobids.val = tmp_record.jobids.val;
+ record->unique = tmp_record.unique;
+ record->voms_exts = tmp_record.voms_exts;
+ if (record->myproxy_server)
+ free(record->myproxy_server);
+ record->myproxy_server = tmp_record.myproxy_server;
+ record->end_time = tmp_record.end_time;
+ record->next_renewal = tmp_record.next_renewal;
+ return 0;
+ } else
+ continue;
+ }
+ if (tmp_record.suffix > last_suffix)
+ last_suffix = tmp_record.suffix;
+
+ /* if no particular suffix was specified get the first free record
+ available */
+ if (tmp_record.jobids.len >= MAX_PROXIES || tmp_record.unique ||
+ tmp_record.voms_exts)
+ continue;
+
+ if (tmp_record.jobids.len == 0) {
+ /* no jobs registered for this record, so use it initialized with the
+ * parameters (currently myproxy location) provided by user */
+ char *server = record->myproxy_server;
+
+ memset(record, sizeof(*record), 0);
+ record->suffix = tmp_record.suffix;
+ if (record->myproxy_server)
+ free(record->myproxy_server);
+ record->myproxy_server = server;
+ free_record(&tmp_record);
+ return 0;
+ }
+
+ if (tmp_record.jobids.len > 0 && record->myproxy_server &&
+ strcmp(record->myproxy_server, tmp_record.myproxy_server) != 0)
+ continue;
+
+ if (tmp_record.jobids.len > 0 &&
+ tmp_record.end_time - current_time < condor_limit) {
+ /* skip expired proxy (and that ones that are going to expire soon),
+ leaving it untouched (it will be removed after next run of the
+ renewal process */
+ continue;
+ }
+
+ record->suffix = tmp_record.suffix;
+ record->jobids.len = tmp_record.jobids.len;
+ record->jobids.val = tmp_record.jobids.val;
+ record->unique = tmp_record.unique;
+ record->voms_exts = tmp_record.voms_exts;
+ if (record->myproxy_server)
+ free(record->myproxy_server);
+ record->myproxy_server = tmp_record.myproxy_server;
+ record->end_time = tmp_record.end_time;
+ record->next_renewal = tmp_record.next_renewal;
+ return 0;
+ }
+
+ if (last_used_suffix)
+ *last_used_suffix = last_suffix;
+
+ if (record->suffix >= 0) {
+ edg_wlpr_Log(LOG_DEBUG, "Requested suffix %d not found in meta file",
+ record->suffix);
+ }
+
+ free_record(&tmp_record);
+
+ return EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND;
+}
+
+static int
+get_record(FILE *fd, proxy_record *record)
+{
+ return get_record_ext(fd, record, NULL);
+}
+
+static int
+store_record(char *basename, proxy_record *record)
+{
+ int stored = 0;
+ FILE *fd = NULL;
+ int temp;
+ char line[1024];
+ char *new_line = NULL;
+ int ret, i;
+ char *p;
+ proxy_record tmp_record;
+ char tmp_file[FILENAME_MAX];
+ char meta_file[FILENAME_MAX];
+
+ assert (record != NULL);
+
+ memset(&tmp_record, 0, sizeof(tmp_record));
+
+ snprintf(meta_file, sizeof(meta_file), "%s.data", basename);
+ snprintf(tmp_file, sizeof(tmp_file), "%s.XXXXXX", meta_file);
+
+ temp = mkstemp(tmp_file);
+ if (temp < 0)
+ return errno;
+
+ fd = fopen(meta_file, "r");
+ if (fd == NULL) {
+ ret = errno;
+ goto end;
+ }
+ while (fgets(line, sizeof(line), fd) != NULL) {
+ free_record(&tmp_record);
+ p = strchr(line, '\n');
+ if (p)
+ *p = '\0';
+ ret = decode_record(line, &tmp_record);
+ if (ret)
+ goto end;
+ if (record->suffix == tmp_record.suffix &&
+ record->unique == tmp_record.unique) {
+ tmp_record.next_renewal = record->next_renewal;
+ tmp_record.end_time = record->end_time;
+ tmp_record.voms_exts = record->voms_exts;
+ if (tmp_record.myproxy_server != NULL)
+ free(tmp_record.myproxy_server);
+ tmp_record.myproxy_server = strdup(record->myproxy_server);
+ if (tmp_record.jobids.val) {
+ for (i = 0; i < tmp_record.jobids.len; i++)
+ free(tmp_record.jobids.val[i]);
+ free(tmp_record.jobids.val);
+ }
+ tmp_record.jobids.len = 0;
+ tmp_record.jobids.val = NULL;
+ for (i = 0; i < record->jobids.len; i++) {
+ realloc_prd_list(&tmp_record.jobids);
+ tmp_record.jobids.val[tmp_record.jobids.len - 1] =
+ strdup(record->jobids.val[i]);
+ }
+ stored = 1;
+ }
+ ret = encode_record(&tmp_record, &new_line);
+ if (ret)
+ goto end;
+ dprintf(temp, "%s\n", new_line);
+ free(new_line);
+ new_line = NULL;
+ }
+ if (! stored) {
+ ret = encode_record(record, &new_line);
+ if (ret)
+ goto end;
+ ret = dprintf(temp, "%s\n", new_line);
+ free(new_line);
+ new_line = NULL;
+ }
+ fclose(fd); fd = NULL;
+ close(temp);
+
+ ret = rename(tmp_file, meta_file);
+ if (ret)
+ ret = errno;
+
+end:
+ free_record(&tmp_record);
+ if (fd)
+ fclose(fd);
+ close(temp);
+ return ret;
+}
+
+static int
+open_metafile(char *basename, FILE **fd)
+{
+ FILE *meta_fd;
+ char meta_filename[FILENAME_MAX];
+
+ snprintf(meta_filename, sizeof(meta_filename), "%s.data", basename);
+ meta_fd = fopen(meta_filename, "a+");
+ if (meta_fd == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Opening meta file %s failed (%s)",
+ meta_filename, strerror(errno));
+ return errno;
+ }
+ rewind(meta_fd);
+ *fd = meta_fd;
+ edg_wlpr_Log(LOG_DEBUG, "Using meta file %s", meta_filename);
+ return 0;
+}
+
+static int
+filename_to_response(char *filename, edg_wlpr_Response *response)
+{
+ response->filenames = malloc(2 * sizeof(*response->filenames));
+ if (response->filenames == NULL) {
+ edg_wlpr_Log(LOG_DEBUG, "Not enough memory");
+ return errno;
+ }
+ response->filenames[0] = strdup(filename);
+ if (response->filenames[0] == NULL) {
+ edg_wlpr_Log(LOG_DEBUG, "Not enough memory");
+ free(response->filenames);
+ return errno;
+ }
+ response->filenames[1] = NULL;
+ return 0;
+}
+
+static void
+record_to_response(int status_code, proxy_record *record,
+ edg_wlpr_Response *response)
+{
+ /* XXX Neni struktrura proxy_record zbytecna? Mohla by se pouzivat primo
+ edg_wlpr_Response? */
+ response->response_code = status_code; /* XXX chyba parsovatelna pres API */
+ if (status_code)
+ return;
+
+ if (response->myproxy_server) {
+ response->myproxy_server = strdup(record->myproxy_server);
+ if (response->myproxy_server == NULL) {
+ response->response_code = ENOMEM; /* XXX */
+ return;
+ }
+ }
+ response->end_time = record->end_time;
+ response->next_renewal_time = record->next_renewal;
+ /* XXX use jobid response->counter = record->counter; */
+}
+
+int
+check_proxyname(char *datafile, char *jobid, char **filename)
+{
+ proxy_record record;
+ FILE *meta_fd = NULL;
+ char line[1024];
+ char proxy[FILENAME_MAX];
+ char *p;
+ int ret, i;
+
+ memset(&record, 0, sizeof(record));
+
+ meta_fd = fopen(datafile, "r");
+ if (meta_fd == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot open meta file %s (%s)",
+ datafile, strerror(errno));
+ return errno;
+ }
+
+ while (fgets(line, sizeof(line), meta_fd) != NULL) {
+ free_record(&record);
+ p = strchr(line, '\n');
+ if (p)
+ *p = '\0';
+ ret = decode_record(line, &record);
+ if (ret)
+ continue; /* XXX exit? */
+ for (i = 0; i < record.jobids.len; i++) {
+ if (strcmp(jobid, record.jobids.val[i]) == 0) {
+ snprintf(proxy, sizeof(proxy), "%s/%s", repository, datafile);
+ p = strrchr(proxy, '.');
+ sprintf(p, ".%d", record.suffix);
+ *filename = strdup(proxy);
+ free_record(&record);
+ fclose(meta_fd);
+ return 0;
+ }
+ }
+ }
+ free_record(&record);
+ fclose(meta_fd);
+ return EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND;
+}
+
+int
+find_proxyname(char *jobid, char **filename)
+{
+ DIR *dir = NULL;
+ struct dirent *file;
+ int ret;
+
+ chdir(repository);
+
+ dir = opendir(repository);
+ if (dir == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot open repository directory %s (%s)",
+ repository, strerror(errno));
+ return errno;
+ }
+
+ while ((file = readdir(dir))) {
+ /* read files of format `md5sum`.data, where md5sum() is of fixed length
+ 32 chars */
+ if (file->d_name == NULL || strlen(file->d_name) != 37 ||
+ strcmp(file->d_name + 32, ".data") != 0)
+ continue;
+ ret = check_proxyname(file->d_name, jobid, filename);
+ if (ret == 0) {
+ closedir(dir);
+ return 0;
+ }
+ }
+ closedir(dir);
+ edg_wlpr_Log(LOG_ERR, "Requested proxy is not registered");
+ return EDG_WLPR_PROXY_NOT_REGISTERED;
+}
+
+#ifdef NOVOMS
+int
+find_voms_cert(char *file, int *present)
+{
+ *present = 0;
+ return 0;
+}
+
+#else
+int
+find_voms_cert(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) {
+ edg_wlpr_Log(LOG_ERR, "check_voms_cert(): Cannot initialize VOMS context (VOMS_Init() failed, probably voms dir was not specified)");
+ return EDG_WLPR_ERROR_VOMS;
+ }
+
+ ret = load_proxy(file, &cert, &privkey, &chain);
+ 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(edg_wlpr_Request *request, edg_wlpr_Response *response)
+{
+ proxy_record record;
+ int ret;
+ FILE *meta_fd = NULL;
+ int last_suffix;
+ char *basename = NULL;
+ char filename[FILENAME_MAX];
+
+ assert(request != NULL);
+ assert(response != NULL);
+
+ memset(&record, 0, sizeof(record));
+ memset(response, 0, sizeof(*response));
+ edg_wlpr_Log(LOG_DEBUG, "Registration request for %s", request->proxy_filename);
+
+ if (request->proxy_filename == NULL || request->jobid == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Registration request doesn't contain registration information");
+ return; /* EINVAL; */
+ }
+ umask(0177);
+
+ ret = get_base_filename(request->proxy_filename, &basename);
+ if (ret)
+ goto end;
+
+ ret = open_metafile(basename, &meta_fd);
+ if (ret)
+ goto end;
+
+ if (voms_enabled)
+ ret = find_voms_cert(request->proxy_filename, &record.voms_exts);
+ /* ignore VOMS related error */
+
+ /* Find first free record */
+ record.suffix = -1;
+ record.myproxy_server = strdup(request->myproxy_server);
+ ret = get_record_ext(meta_fd, &record, &last_suffix);
+ fclose(meta_fd); meta_fd = NULL;
+ if (ret && ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND)
+ goto end;
+
+ if (ret == EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND || record.jobids.len == 0 || request->unique || record.voms_exts) {
+ /* create a new proxy file in the repository */
+ int suffix;
+
+ suffix = (record.jobids.len == 0 && record.suffix >= 0) ?
+ record.suffix : last_suffix + 1;
+ snprintf(filename, sizeof(filename), "%s.%d", basename, suffix);
+ ret = copy_file(request->proxy_filename, filename);
+ if (ret)
+ goto end;
+ ret = get_times(filename, &record);
+ if (ret)
+ goto end;
+ record.suffix = suffix;
+ ret = realloc_prd_list(&record.jobids);
+ if (ret)
+ goto end;
+ record.jobids.val[record.jobids.len - 1] = strdup(request->jobid);
+ record.unique = request->unique;
+ edg_wlpr_Log(LOG_DEBUG, "Created a new proxy file in repository (%s)",
+ filename);
+ } else {
+ ret = realloc_prd_list(&record.jobids);
+ if (ret)
+ goto end;
+ record.jobids.val[record.jobids.len - 1] = strdup(request->jobid);
+ snprintf(filename, sizeof(filename), "%s.%d", basename, record.suffix);
+ edg_wlpr_Log(LOG_DEBUG, "Inremented counter on %s", filename);
+ }
+
+ ret = store_record(basename, &record);
+
+end:
+ if (meta_fd) {
+ fclose(meta_fd);
+ }
+
+ if (basename)
+ free(basename);
+
+ if (ret == 0)
+ ret = filename_to_response(filename, response);
+ record_to_response(ret, &record, response);
+ free_record(&record);
+}
+
+void
+unregister_proxy(edg_wlpr_Request *request, edg_wlpr_Response *response)
+{
+ proxy_record record;
+ int ret, i, index;
+ FILE *meta_fd = NULL;
+ char *basename = NULL;
+ char *p;
+ struct stat stat_buf;
+
+ memset(&record, 0, sizeof(record));
+ edg_wlpr_Log(LOG_DEBUG, "Unregistration request for %s", request->jobid);
+
+ if (request->jobid == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Unregistration request doesn't contain needed information");
+ ret = EINVAL;
+ goto end;
+ }
+
+ if (request->proxy_filename == NULL) {
+ ret = find_proxyname(request->jobid, &request->proxy_filename);
+ if (ret)
+ goto end;
+ }
+
+ ret = get_base_filename(request->proxy_filename, &basename);
+ if (ret) {
+ goto end;
+ }
+
+ if (strncmp(request->proxy_filename, basename, strlen(basename) != 0)) {
+ edg_wlpr_Log(LOG_DEBUG, "Requested proxy %s is not from repository",
+ request->proxy_filename);
+ ret = EDG_WLPR_PROXY_NOT_REGISTERED;
+ goto end;
+ }
+
+ p = strrchr(request->proxy_filename, '.');
+ if (p == NULL) {
+ edg_wlpr_Log(LOG_DEBUG, "Requested proxy %s is not from repository",
+ request->proxy_filename);
+ ret = EDG_WLPR_PROXY_NOT_REGISTERED;
+ goto end;
+ }
+
+ ret = edg_wlpr_DecodeInt(p+1, &record.suffix);
+ if (ret) {
+ edg_wlpr_Log(LOG_DEBUG, "Requested proxy %s is not from repository",
+ request->proxy_filename);
+ ret = EDG_WLPR_PROXY_NOT_REGISTERED;
+ goto end;
+ }
+
+ ret = open_metafile(basename, &meta_fd);
+ if (ret) {
+ /* fill in error response */
+ return;
+ }
+
+ ret = get_record(meta_fd, &record);
+ if (ret)
+ goto end;
+
+ ret = EDG_WLPR_PROXY_NOT_REGISTERED;
+ for (i = 0; i < record.jobids.len; i++)
+ if (strcmp(request->jobid, record.jobids.val[i]) == 0) {
+ ret = 0;
+ break;
+ }
+ if (ret) {
+ edg_wlpr_Log(LOG_DEBUG, "Requested proxy %s is not registered",
+ request->proxy_filename);
+ goto end;
+ }
+
+ /* remove jobid from the list */
+ index = i;
+ free(record.jobids.val[i]);
+ record.jobids.len--;
+ for (i = index; i < record.jobids.len; i++)
+ record.jobids.val[i] = record.jobids.val[i+1];
+
+ if (record.jobids.len == 0) {
+ record.unique = 0;
+ record.voms_exts = 0;
+ record.end_time = 0;
+ record.next_renewal = 0;
+ }
+
+ ret = stat(request->proxy_filename, &stat_buf);
+ if (ret) {
+ edg_wlpr_Log(LOG_DEBUG, "Cannot stat file %s: (%s)",
+ request->proxy_filename, strerror(errno));
+ ret = errno;
+ goto end;
+ }
+
+ ret = store_record(basename, &record);
+ if (ret)
+ goto end;
+
+ if (record.jobids.len == 0)
+ unlink(request->proxy_filename);
+
+end:
+ if (meta_fd) {
+ fclose(meta_fd);
+ }
+ if (basename)
+ free(basename);
+
+ if (ret == 0)
+ ret = filename_to_response(request->proxy_filename, response);
+ record_to_response(ret, &record, response);
+ free_record(&record);
+}
+
+void
+get_proxy(edg_wlpr_Request *request, edg_wlpr_Response *response)
+{
+ char *filename = NULL;
+ int ret;
+
+ memset(response, 0, sizeof(*response));
+
+ edg_wlpr_Log(LOG_DEBUG, "GET request for %s", request->jobid);
+
+ if (request->jobid == NULL) {
+ edg_wlpr_Log(LOG_ERR, "GET request doesn't contain jobid specification");
+ ret = EINVAL;
+ goto end;
+ }
+
+ ret = find_proxyname(request->jobid, &filename);
+
+end:
+ if (ret == 0)
+ ret = filename_to_response(filename, response);
+ if (filename)
+ free(filename);
+ response->response_code = ret;
+}
+
+void
+update_db(edg_wlpr_Request *request, edg_wlpr_Response *response)
+{
+ FILE *fd = NULL;
+ int tmp_fd = -1;
+ int suffix = -1;
+ char tmp_file[FILENAME_MAX];
+ char cur_proxy[FILENAME_MAX];
+ char datafile[FILENAME_MAX];
+ char line[1024];
+ char *new_line = NULL;
+ char *basename, *proxy = NULL;
+ char **entry;
+ proxy_record record;
+ int ret;
+ char *p;
+ time_t current_time;
+
+ memset(&record, 0, sizeof(record));
+
+ edg_wlpr_Log(LOG_DEBUG, "UPDATE_DB request for %s", request->proxy_filename);
+
+ chdir(repository);
+ basename = request->proxy_filename;
+
+ snprintf(datafile, sizeof(datafile), "%s.data", basename);
+ fd = fopen(datafile, "r");
+ if (fd == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot open meta file %s (%s)",
+ datafile, strerror(errno));
+ ret = errno;
+ return;
+ }
+
+ snprintf(tmp_file, sizeof(tmp_file), "%s.XXXXXX", datafile);
+ tmp_fd = mkstemp(tmp_file);
+ if (tmp_fd < 0) {
+ edg_wlpr_Log(LOG_ERR, "Cannot create temporary file (%s)",
+ strerror(errno));
+ ret = errno;
+ goto end;
+ }
+
+ entry = request->entries;
+ if (entry) {
+ p = strchr(*entry, ':');
+ *p = '\0';
+ suffix = atoi(*entry);
+ proxy = p+1;
+ }
+
+ current_time = time(NULL);
+
+ while (fgets(line, sizeof(line), fd) != NULL) {
+ free_record(&record);
+ p = strchr(line, '\n');
+ if (p)
+ *p = '\0';
+ ret = decode_record(line, &record);
+ if (ret)
+ goto end;
+
+ if (record.suffix > suffix && entry && *entry) {
+ do {
+ entry++;
+ if (entry == NULL || *entry == NULL) {
+ suffix = -1;
+ break;
+ }
+
+ p = strchr(*entry, ':');
+ suffix = atoi(*entry);
+ proxy = p+1;
+ } while (record.suffix > suffix);
+ }
+
+ if (record.suffix == suffix) {
+ snprintf(cur_proxy, sizeof(cur_proxy), "%s.%d", basename, suffix);
+ if (proxy == NULL || *proxy == '\0') {
+ /* if proxy isn't specified use file registered currently and
+ * reschedule renewal */
+ if (record.end_time < current_time) {
+ char *server;
+ /* remove file with expired proxy and clean the record in db */
+ unlink(cur_proxy);
+ server = strdup(record.myproxy_server);
+ free_record(&record);
+ record.suffix = suffix;
+ record.myproxy_server = server;
+ edg_wlpr_Log(LOG_WARNING, "Removed expired proxy (suffix %d)",
+ suffix);
+ } else
+ get_times(cur_proxy, &record);
+ } else {
+ ret = get_times(proxy, &record);
+ (ret == 0) ? rename(proxy, cur_proxy) : unlink(proxy);
+ }
+ }
+
+ ret = encode_record(&record, &new_line);
+ if (ret)
+ goto end;
+
+ dprintf(tmp_fd, "%s\n", new_line);
+ free(new_line);
+ new_line = NULL;
+ }
+ free_record(&record);
+
+ close(tmp_fd);
+ fclose(fd);
+
+ rename(tmp_file, datafile);
+
+ return;
+
+end:
+ if (fd)
+ fclose(fd);
+ unlink(tmp_file);
+ if (tmp_fd > 0)
+ close(tmp_fd);
+ free_record(&record);
+
+ return;
+}
--- /dev/null
+#include "renewal_locl.h"
+
+#ident "$Header$"
+
+/* nread() and nwrite() never return partial data */
+static size_t
+nread(int sock, char *buf, size_t buf_len)
+{
+ size_t count;
+ size_t remain = buf_len;
+ char *cbuf = buf;
+
+ while (remain > 0) {
+ count = read(sock, cbuf, remain);
+ if (count < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ return count;
+ } else
+ if (count == 0) {
+ return count;
+ }
+ cbuf += count;
+ remain -= count;
+ }
+ return buf_len;
+}
+
+static size_t
+nwrite(int sock, const char *buf, size_t buf_len)
+{
+ const char *cbuf = buf;
+ size_t count;
+ size_t remain = buf_len;
+
+ while (remain > 0) {
+ count = write(sock, cbuf, remain);
+ if (count < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ return count;
+ }
+ cbuf += count;
+ remain -= count;
+ }
+ return buf_len;
+}
+
+int
+edg_wlpr_Read(int sock, char **buf, size_t *buf_len)
+{
+ int ret;
+ unsigned char length[4];
+
+ ret = nread(sock, length, 4);
+ if (ret == -1) {
+ *buf_len = 0;
+ return errno;
+ }
+ if (ret < 4) {
+ *buf_len = 0;
+ return EDG_WLPR_ERROR_UNEXPECTED_EOF; /* XXX vraci i kdyz peer spadne a zavre trubku */
+ }
+ *buf_len = (length[0] << 24) |
+ (length[1] << 16) |
+ (length[2] << 8 ) |
+ (length[3] << 0);
+
+ *buf = malloc(*buf_len);
+ if (*buf == NULL)
+ return ENOMEM;
+
+ ret = nread(sock, *buf, *buf_len);
+ if (ret != *buf_len) {
+ free(*buf);
+ *buf_len = 0;
+ return errno;
+ }
+
+ return 0;
+}
+
+int
+edg_wlpr_Write(int sock, char *buf, size_t buf_len)
+{
+ unsigned char length[4];
+
+ length[0] = (buf_len >> 24) & 0xFF;
+ length[1] = (buf_len >> 16) & 0xFF;
+ length[2] = (buf_len >> 8) & 0xFF;
+ length[3] = (buf_len >> 0) & 0xFF;
+
+ if (nwrite(sock, length, 4) != 4 ||
+ nwrite(sock, buf, buf_len) != buf_len)
+ return errno;
+
+ return 0;
+}
+
+int
+edg_wlpr_GetToken(const char *msg, const size_t msg_len,
+ const char *key, const char *separators,
+ int req_index, char **value)
+{
+ char *p;
+ size_t len;
+ int index;
+
+ assert(separators != NULL);
+
+ /* Add ending zero ? */
+
+ index = 0;
+ p = (char *)msg;
+ while (p && (p = strstr(p, key))) {
+ if (index == req_index)
+ break;
+ index++;
+ p += strlen(key);
+ }
+ if (p == NULL)
+ return EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND;
+
+ p = strchr(p, '=');
+ if (p == NULL)
+ return EDG_WLPR_ERROR_PROTO_PARSE_ERROR;
+
+ len = strcspn(p+1, separators);
+ if (len == 0)
+ return EDG_WLPR_ERROR_PROTO_PARSE_ERROR;
+
+ *value = malloc(len + 1);
+ if (*value == NULL)
+ return ENOMEM;
+
+ memcpy(*value, p+1, len);
+ (*value)[len] = '\0';
+
+ return 0;
+}
+
+int
+edg_wlpr_StoreToken(char **buf, size_t *buf_len, char *command,
+ char *value, const char *separator)
+{
+ char line[2048];
+ char *tmp;
+
+ assert(buf != NULL);
+ assert(separator != NULL);
+
+ if (strlen(command) + 1 + strlen(value) + 2 > sizeof(line))
+ return ERANGE; /* XXX */
+
+ snprintf(line, sizeof(line), "%s%s%s", command, value, separator);
+
+ while (strlen(*buf) + strlen(line) + 1 > *buf_len) {
+ tmp = realloc(*buf, *buf_len + EDG_WLPR_BUF_SIZE);
+ if (tmp == NULL)
+ return ENOMEM;
+ *buf = tmp;
+ *buf_len += EDG_WLPR_BUF_SIZE;
+ }
+ strcat(*buf, line);
+
+ return 0;
+}
+
+void
+edg_wlpr_CleanRequest(edg_wlpr_Request *request)
+{
+ assert(request != NULL);
+ if (request->version)
+ free(request->version);
+ if (request->proxy_filename)
+ free(request->proxy_filename);
+ if (request->myproxy_server)
+ free(request->myproxy_server);
+ if (request->jobid)
+ free(request->jobid);
+ if (request->entries) {
+ char **p = request->entries;
+ char **next;
+ while (*p) {
+ next = p+1;
+ free(*p);
+ p = next;
+ }
+ free(request->entries);
+ }
+
+ memset(request, 0, sizeof(request));
+}
+
+void
+edg_wlpr_CleanResponse(edg_wlpr_Response *response)
+{
+ assert(response != NULL);
+ if (response->version)
+ free(response->version);
+ if (response->myproxy_server)
+ free(response->myproxy_server);
+ if (response->filenames) {
+ char **p = response->filenames;
+ char **next;
+
+ while (*p) {
+ next = p+1;
+ free(*p);
+ p = next;
+ }
+ free(response->filenames);
+ }
+ memset(response, 0, sizeof(*response));
+}
+
+const char *
+edg_wlpr_GetErrorString(int code)
+{
+ return (code == 0) ? "OK" : "Error";
+}
+
+char *
+edg_wlpr_EncodeInt(int num) /* long? time */
+{
+ static char ret[64];
+
+ snprintf(ret, sizeof(ret), "%d", num);
+ return ret;
+}
+
+int
+edg_wlpr_DecodeInt(char *str, int *num)
+{
+ *num = atol(str); /* XXX */
+ return 0;
+}
--- /dev/null
+#include "renewal_locl.h"
+#include "renewd_locl.h"
+
+#ifndef NOVOMS
+#include <voms_apic.h>
+#endif
+
+#ident "$Header$"
+
+extern char *repository;
+extern char *cadir;
+extern char *vomsdir;
+extern int voms_enabled;
+extern char *vomsconf;
+extern struct vomses_records vomses;
+
+static int received_signal = -1;
+
+static void
+check_renewal(char *datafile, int force_renew);
+
+static int
+renew_proxy(proxy_record *record, char *basename, char **new_proxy);
+
+static void
+register_signal(int signal);
+
+
+#define DGPR_RETRIEVE_DEFAULT_HOURS 10
+#define RENEWAL_CLOCK_SKEW 5 * 60
+
+static const char *
+get_ssl_err()
+{
+ return "SSL failed";
+}
+
+int
+load_proxy(const char *filename, X509 **cert, EVP_PKEY **privkey,
+ STACK_OF(X509) **chain)
+{
+ X509 *my_cert = NULL;
+ EVP_PKEY *my_key = NULL;
+ STACK_OF(X509) *my_chain = NULL;
+ FILE *fd = NULL;
+ int ret;
+
+ fd = fopen(filename, "r");
+ if (fd == NULL) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot read VOMS certificate (fopen() failed on %s: %s)",
+ filename, strerror(errno));
+ return errno;
+ }
+
+ my_cert = PEM_read_X509(fd, NULL, NULL, NULL);
+ if (my_cert == NULL) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot read VOMS certificate (PEM_read_X509() failed: %s)",
+ get_ssl_err());
+ ret = EDG_WLPR_ERROR_SSL;
+ goto end;
+ }
+
+ my_key = PEM_read_PrivateKey(fd, NULL, NULL, NULL);
+ if (my_key == NULL) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot read VOMS certificate (PEM_read_PrivateKey() failed: %s)",
+ get_ssl_err());
+ ret = EDG_WLPR_ERROR_SSL;
+ goto end;
+ }
+
+ my_chain = sk_X509_new_null();
+ if (my_chain == NULL) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot read VOMS certificate (sk_X509_new_null() failed: %s)",
+ get_ssl_err());
+ ret = EDG_WLPR_ERROR_SSL;
+ goto end;
+ }
+
+ while (1) {
+ X509 *c;
+
+ c = PEM_read_X509(fd, NULL, NULL, NULL);
+ if (c == NULL) {
+ if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) {
+ /* End of file reached. no error */
+ ERR_clear_error();
+ break;
+ }
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot read VOMS certificate (PEM_read_X509() failed: %s)",
+ get_ssl_err());
+ ret = EDG_WLPR_ERROR_SSL;
+ goto end;
+ }
+ sk_X509_push(my_chain, c);
+ }
+
+ *cert = my_cert;
+ *privkey = my_key;
+ *chain = my_chain;
+ my_cert = NULL; my_key = NULL; my_chain = NULL;
+ ret = 0;
+
+end:
+ fclose(fd);
+
+ if (my_cert)
+ X509_free(my_cert);
+ if (my_key)
+ EVP_PKEY_free(my_key);
+ if (my_chain)
+ sk_X509_pop_free(my_chain, X509_free);
+
+ return ret;
+}
+
+static int
+save_proxy(const char *filename, X509 *new_cert, EVP_PKEY *new_privkey,
+ STACK_OF(X509) *chain)
+{
+ FILE *fd = NULL;
+ int ret, i;
+ int retval = EDG_WLPR_ERROR_SSL;
+
+ fd = fopen(filename, "w");
+ if (fd == NULL) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot store proxy (fopen() failed on %s: %s)",
+ filename, strerror(errno));
+ return errno;
+ }
+
+ ret = PEM_write_X509(fd, new_cert);
+ if (ret == 0) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot store proxy (PEM_write_X509() failed: %s)",
+ get_ssl_err());
+ goto end;
+ }
+
+ ret = PEM_write_PrivateKey(fd, new_privkey, NULL, NULL, 0, NULL, NULL);
+ if (ret == 0) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot store proxy (PEM_write_PrivateKey() failed: %s)",
+ get_ssl_err());
+ goto end;
+ }
+
+ for (i = 0; i < sk_X509_num(chain); i++) {
+ X509 *cert = sk_X509_value(chain, i);
+ ret = PEM_write_X509(fd, cert);
+ if (ret == 0) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot store proxy (PEM_write_X509() failed: %s)",
+ get_ssl_err());
+ goto end;
+ }
+ }
+
+ retval = 0;
+
+end:
+ fclose(fd);
+
+ return retval;
+}
+
+static int
+gen_keypair(EVP_PKEY **keypair, int requested_bits)
+{
+ RSA *rsa = NULL;
+ EVP_PKEY *key;
+
+ *keypair = NULL;
+ rsa = RSA_generate_key(requested_bits,
+ RSA_F4 /* public exponent */,
+ NULL, NULL);
+ if (rsa == NULL) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (RSA_generate_key() failed: %s)",
+ get_ssl_err());
+ return EDG_WLPR_ERROR_SSL;
+ }
+
+ key = EVP_PKEY_new();
+ if (key == NULL) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (EVP_PKEY_new() failed: %s)",
+ get_ssl_err());
+ RSA_free(rsa);
+ return EDG_WLPR_ERROR_SSL;
+ }
+
+ if (EVP_PKEY_assign_RSA(key, rsa) == 0) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (EVP_PKEY_assign_RSA() failed: %s)",
+ get_ssl_err());
+ RSA_free(rsa);
+ EVP_PKEY_free(key);
+ return EDG_WLPR_ERROR_SSL;
+ }
+
+ *keypair = key;
+
+ return 0;
+}
+
+static int
+gen_subject_name(X509 *old_cert, X509 *new_cert)
+{
+ X509_NAME *name = NULL;
+ X509_NAME_ENTRY *name_entry = NULL;
+ int ret = EDG_WLPR_ERROR_SSL;
+
+ name = X509_NAME_dup(X509_get_subject_name(old_cert));
+ if (name == NULL) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (X509_NAME_dup() failed: %s",
+ get_ssl_err());
+ goto end;
+ }
+
+ name_entry = X509_NAME_ENTRY_create_by_NID(NULL /* make new entry */,
+ NID_commonName,
+ V_ASN1_APP_CHOOSE,
+ "proxy", -1);
+ if (name_entry == NULL) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (X509_NAME_ENTRY_create_by_NID() failed: %s)",
+ get_ssl_err());
+ goto end;
+ }
+
+ if (X509_NAME_add_entry(name, name_entry, X509_NAME_entry_count(name), 0) == 0) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (X509_NAME_add_entry() failed: %s)",
+ get_ssl_err());
+ goto end;
+ }
+
+
+ if (X509_set_subject_name(new_cert, name) == 0) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (X509_set_subject_name() failed: %s)",
+ get_ssl_err());
+ goto end;
+ }
+
+ ret = 0;
+
+end:
+ if (name)
+ X509_NAME_free(name);
+ if (name_entry != NULL)
+ X509_NAME_ENTRY_free(name_entry);
+
+ return ret;
+}
+
+static int
+create_proxy(X509 *old_cert, EVP_PKEY *old_privkey, X509_EXTENSION *extension,
+ X509 **new_cert, EVP_PKEY **new_privkey)
+{
+ /* Inspired by code from Myproxy */
+ EVP_PKEY *key_pair = NULL;
+ X509 *cert = NULL;
+ int ret;
+ int retval = EDG_WLPR_ERROR_SSL;
+
+ ret = gen_keypair(&key_pair, 512);
+ if (ret)
+ return ret;
+
+ cert = X509_new();
+ if (cert == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot generate new proxy (X509_new() failed: Not enough memory)");
+ goto end;
+ }
+
+ ret = gen_subject_name(old_cert, cert);
+ if (ret) {
+ retval = ret;
+ goto end;
+ }
+
+ if (X509_set_issuer_name(cert, X509_get_subject_name(old_cert)) == 0) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (X509_set_issuer_name() failed: %s)",
+ get_ssl_err());
+ goto end;
+ }
+
+ if (X509_set_serialNumber(cert, X509_get_serialNumber(old_cert)) == 0) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (X509_set_serialNumber() failed: %s)",
+ get_ssl_err());
+ goto end;
+ }
+
+ X509_gmtime_adj(X509_get_notBefore(cert), -(60 * 5));
+ X509_set_notAfter(cert, X509_get_notAfter(old_cert));
+
+ if (X509_set_pubkey(cert, key_pair) == 0) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (X509_set_pubkey() failed: %s)",
+ get_ssl_err());
+ goto end;
+ }
+
+ /* set v3 */
+ if (X509_set_version(cert, 2L) == 0) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (X509_set_version() failed: %s)",
+ get_ssl_err());
+ goto end;
+ }
+
+ if (cert->cert_info->extensions != NULL)
+ sk_X509_EXTENSION_pop_free(cert->cert_info->extensions,
+ X509_EXTENSION_free);
+ cert->cert_info->extensions = sk_X509_EXTENSION_new_null();
+ sk_X509_EXTENSION_push(cert->cert_info->extensions, extension);
+
+ if (X509_sign(cert, old_privkey, EVP_md5()) == 0) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (X509_sign() failed: %s)",
+ get_ssl_err());
+ goto end;
+ }
+
+ *new_privkey = key_pair;
+ *new_cert = cert;
+ key_pair = NULL;
+ cert = NULL;
+
+ retval = 0;
+
+end:
+ if (key_pair)
+ EVP_PKEY_free(key_pair);
+ if (cert)
+ X509_free(cert);
+
+ return retval;
+}
+
+static int
+create_voms_extension(char *buf, size_t buf_len, X509_EXTENSION **extensions)
+{
+ ASN1_OBJECT *voms_obj = NULL;
+ ASN1_OCTET_STRING *voms_oct = NULL;
+
+ *extensions = NULL;
+
+ voms_oct = ASN1_OCTET_STRING_new();
+ if (voms_oct == NULL) {
+ edg_wlpr_Log(LOG_ERR,
+ "Cannot generate new proxy (ASN1_OCTET_STRING_new() failed: %s)",
+ get_ssl_err());
+ return EDG_WLPR_ERROR_SSL;
+ }
+
+ voms_oct->data = buf;
+ voms_oct->length = buf_len;
+
+ voms_obj = OBJ_nid2obj(OBJ_txt2nid("VOMS"));
+ if (voms_obj == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot generate new proxy (OBJ_nid2obj() failed");
+ goto end;
+ }
+
+ *extensions = X509_EXTENSION_create_by_OBJ(NULL, voms_obj, 0, voms_oct);
+ if (*extensions == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot generate new proxy (X509_EXTENSION_create_by_OBJ() failed");
+ goto end;
+ }
+
+ return 0;
+
+end:
+ if (voms_oct)
+ ASN1_OCTET_STRING_free(voms_oct);
+ if (voms_obj)
+ ASN1_OBJECT_free(voms_obj);
+ return EDG_WLPR_ERROR_SSL;
+}
+
+#ifndef NOVOMS
+static int
+export_std_data(struct data *voms_data, char **buf)
+{
+ asprintf(buf, "GROUP: %s\n"
+ "ROLE:%s\n" /* the space is missing intentionaly */
+ "CAP: %s\n",
+ (voms_data->group) ? voms_data->group : "NULL",
+ (voms_data->role) ? voms_data->role : "NULL",
+ (voms_data->cap) ? voms_data->cap : "NULL");
+ return 0;
+}
+
+static int
+export_user_data(struct voms *voms_cert, char **buf, size_t *len)
+{
+ struct data **voms_data;
+ char *str = NULL;
+ char *ptr;
+
+ *buf = NULL;
+
+ switch (voms_cert->type) {
+ case TYPE_NODATA:
+ *buf = strdup("NO DATA");
+ break;
+ case TYPE_CUSTOM:
+ *buf = strdup(voms_cert->custom);
+ break;
+ case TYPE_STD:
+ for (voms_data = voms_cert->std; voms_data && *voms_data; voms_data++) {
+ export_std_data(*voms_data, &str);
+ if (*buf == NULL)
+ ptr = calloc(strlen(str) + 1, 1);
+ else
+ ptr = realloc(*buf, strlen(*buf) + strlen(str) + 1);
+ if (ptr == NULL) {
+ return ENOMEM;
+ }
+ *buf = ptr;
+ strcat(*buf, str);
+ free(str);
+ }
+
+ break;
+ default:
+ return -1;
+ }
+
+ *len = strlen(*buf);
+ return 0;
+}
+
+#endif
+
+static int
+encode_voms_buf(const char *label, char *data, size_t data_len,
+ char **buf, size_t *buf_len)
+{
+ char *tmp;
+
+ tmp = realloc(*buf, *buf_len + strlen(label) + data_len + 1);
+ if (tmp == NULL)
+ return ENOMEM;
+
+ memcpy(tmp + *buf_len, label, strlen(label));
+
+ memcpy(tmp + *buf_len + strlen(label), data, data_len);
+ tmp[*buf_len + strlen(label) + data_len] = '\n';
+ *buf = tmp;
+ *buf_len = *buf_len + strlen(label) + data_len + 1;
+
+ return 0;
+}
+
+static int
+encode_voms_int(const char *label, int value, char **buf, size_t *buf_len)
+{
+ char tmp[16];
+
+ snprintf(tmp, sizeof(tmp), "%d", value);
+ return encode_voms_buf(label, tmp, strlen(tmp), buf, buf_len);
+}
+
+static int
+encode_voms_str(const char *label, char *value, char **buf, size_t *buf_len)
+{
+ return encode_voms_buf(label, value, strlen(value), buf, buf_len);
+}
+
+#if 0
+static int
+VOMS_Export(struct vomsdata *voms_info, char **buf, size_t *len)
+{
+ struct voms *vc;
+ char *enc_voms = NULL;
+ size_t enc_voms_len = 0;
+ char *data_buf;
+ size_t data_len;
+ int ret;
+
+ if (voms_info == NULL || voms_info->data == NULL || *voms_info->data == NULL)
+ return EINVAL;
+ vc = *voms_info->data;
+
+ ret = export_user_data(vc, &data_buf, &data_len);
+ if (ret)
+ return ret;
+
+ encode_voms_int("SIGLEN:", vc->siglen, &enc_voms, &enc_voms_len);
+ encode_voms_buf("SIGNATURE:",vc->signature, vc->siglen,
+ &enc_voms, &enc_voms_len);
+ enc_voms_len--; /* Signature is not followed by '\n' */
+ encode_voms_str("USER:", vc->user, &enc_voms, &enc_voms_len);
+ encode_voms_str("UCA:", vc->userca, &enc_voms, &enc_voms_len);
+ encode_voms_str("SERVER:", vc->server, &enc_voms, &enc_voms_len);
+ encode_voms_str("SCA:", vc->serverca, &enc_voms, &enc_voms_len);
+ encode_voms_str("VO:", vc->voname, &enc_voms, &enc_voms_len);
+ encode_voms_str("URI:", vc->uri, &enc_voms, &enc_voms_len);
+ encode_voms_str("TIME1:", vc->date1, &enc_voms, &enc_voms_len);
+ encode_voms_str("TIME2:", vc->date2, &enc_voms, &enc_voms_len);
+ encode_voms_int("DATALEN:", data_len, &enc_voms, &enc_voms_len);
+ encode_voms_buf("", data_buf, data_len, &enc_voms, &enc_voms_len);
+ enc_voms_len--; /* the data already contains endind '\n' */
+
+ free(data_buf);
+ if (enc_voms == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot renew VOMS certificate (Not enough memory)");
+ return ENOMEM;
+ }
+ *buf = enc_voms;
+ *len = enc_voms_len;
+ return 0;
+}
+
+static int
+voms_cert_renew(char *hostname, int port, char *voms_subject,
+ char *proxy,
+ struct voms **cur_voms_cert, struct vomsdata *voms_info)
+{
+ int ret = 0;
+ char *command = "A";
+ int err = 0;
+ char *old_env_proxy = getenv("X509_USER_PROXY");
+
+ setenv("X509_USER_PROXY", proxy, 1);
+
+ /* hack (suggested by Vincenzo Ciaschini) to work around problem with
+ * unitialized VOMS struct */
+ ret = VOMS_Ordering("zzz:zzz", voms_info, &err);
+ if (ret == 0) {
+ edg_wlpr_Log(LOG_ERR, "Cannot renew VOMS certificate (VOMS_Ordering() failed");
+ ret = EDG_WLPR_ERROR_VOMS;
+ goto end;
+ }
+
+ /* XXX only attributes which are in current certificate should be requested*/
+ ret = VOMS_Contact(hostname, port, (*cur_voms_cert)->server, command,
+ voms_info, &err);
+ if (ret == 0) {
+#if 0
+ if (err == 1) { /* XXX cannot connect voms server */
+ ret = 0;
+ goto end;
+ }
+#endif
+ edg_wlpr_Log(LOG_ERR, "Cannot renew VOMS certificate (VOMS_Contact() failed: %d)", err);
+ ret = EDG_WLPR_ERROR_VOMS;
+ } else
+ ret = 0;
+
+end:
+ (old_env_proxy) ? setenv("X509_USER_PROXY", old_env_proxy, 1) :
+ unsetenv("X509_USER_PROXY");
+
+ return ret;
+}
+
+static int
+renew_voms_cert(struct voms **cur_voms_cert, char *proxy, char **buf, size_t *buf_len)
+{
+ struct vomsdata *voms_info = NULL;
+ char *hostname = NULL;
+ char *p;
+ int port, ret;
+
+ hostname = strdup((*cur_voms_cert)->uri);
+ p = strchr(hostname, ':');
+ if (p)
+ *p = '\0';
+ port = (p) ? atoi(p+1) : 15000;
+
+ voms_info = VOMS_Init(vomsdir, cadir);
+ if (voms_info == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot renew VOMS certificate (VOMS_Init() failed)");
+ ret = EDG_WLPR_ERROR_VOMS;
+ goto end;
+ }
+
+ ret = voms_cert_renew(hostname, port, (*cur_voms_cert)->server, proxy, cur_voms_cert,
+ voms_info);
+ if (ret)
+ goto end;
+
+ ret = VOMS_Export(voms_info, buf, buf_len);
+ if (ret) {
+ edg_wlpr_Log(LOG_ERR, "Cannot renew VOMS certificate (VOMS_Export() failed)");
+ ret = EDG_WLPR_ERROR_VOMS;
+ goto end;
+ }
+
+ ret = 0;
+
+end:
+ if (hostname)
+ free(hostname);
+#if 0
+ if (voms_info)
+ VOMS_Destroy(voms_info);
+#endif
+
+ return ret;
+}
+#endif
+
+#ifndef NOVOMS
+static vomses_record *
+find_vomses_record(char *hostname, int port)
+{
+ int i;
+
+ for (i = 0; i < vomses.len; i++) {
+ if (strcmp(vomses.val[i]->hostname, hostname) == 0 &&
+ vomses.val[i]->port == port)
+ return vomses.val[i];
+ }
+
+ return NULL;
+}
+
+static int
+set_vo_params(struct voms **voms_cert, char **arg)
+{
+ vomses_record *r;
+ char *tmp;
+ int port;
+ char *hostname;
+ char *p;
+
+ hostname = strdup((*voms_cert)->uri);
+ p = strchr(hostname, ':');
+ if (p)
+ *p = '\0';
+ port = (p) ? atoi(p+1) : 15000;
+
+ r = find_vomses_record(hostname, port);
+ if (r == NULL)
+ return EINVAL;
+
+ if (*arg == NULL) {
+ asprintf(arg, " -voms %s", r->nick);
+ } else {
+ tmp = realloc(*arg,
+ strlen(*arg) + strlen(" -voms ") + strlen(r->nick) + 1);
+ if (tmp == NULL)
+ return ENOMEM;
+ *arg = tmp;
+ *arg = strcat(*arg, " -voms ");
+ *arg = strcat(*arg, r->nick);
+ }
+ return 0;
+}
+#endif
+
+static int
+exec_voms_proxy_init(char *arg, char *old_proxy, char *new_proxy)
+{
+ char command[256];
+ int ret;
+ char *old_env_proxy = getenv("X509_USER_PROXY");
+
+ setenv("X509_USER_PROXY", old_proxy, 1);
+
+ snprintf(command, sizeof(command),
+ "edg-voms-proxy-init -out %s -key %s -cert %s -confile %s -q %s",
+ new_proxy, old_proxy, old_proxy, vomsconf, arg);
+ ret = system(command);
+
+ (old_env_proxy) ? setenv("X509_USER_PROXY", old_env_proxy, 1) :
+ unsetenv("X509_USER_PROXY");
+
+ return ret;
+}
+
+#if 0
+static int
+renew_voms_certs(const char *old_proxy, const char *new_proxy)
+{
+ struct vomsdata *voms_info = NULL;
+ struct voms **voms_cert = NULL;
+ STACK_OF(X509) *chain = NULL;
+ EVP_PKEY *privkey = NULL;
+ X509 *cert = NULL;
+ int ret, err;
+ char *buf = NULL;
+ size_t buf_len = 0;
+ X509_EXTENSION *extension = NULL;
+ X509 *new_cert = NULL;
+ EVP_PKEY *new_privkey = NULL;
+
+ voms_info = VOMS_Init(vomsdir, cadir);
+ if (voms_info == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot initialize VOMS context (VOMS_Init() failed)");
+ return EDG_WLPR_ERROR_VOMS;
+ }
+
+ ret = load_proxy(old_proxy, &cert, &privkey, &chain);
+ if (ret)
+ goto end;
+
+ ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, voms_info, &err);
+ if (ret == 0) {
+ if (err == VERR_NOEXT) {
+ /* no VOMS cred, no problem; continue */
+ ret = 0;
+ } else {
+ edg_wlpr_Log(LOG_ERR, "Cannot get VOMS certificate(s) from proxy");
+ ret = EDG_WLPR_ERROR_VOMS;
+ }
+ goto end;
+ }
+
+ for (voms_cert = voms_info->data; voms_cert && *voms_cert; voms_cert++) {
+ char *tmp, *ptr;
+ size_t tmp_len;
+
+ ret = renew_voms_cert(voms_cert, old_proxy, &tmp, &tmp_len);
+ if (ret)
+ continue;
+ ptr = realloc(buf, buf_len + tmp_len);
+ if (ptr == NULL) {
+ ret = ENOMEM;
+ goto end;
+ }
+ buf = ptr;
+ memcpy(buf + buf_len, tmp, tmp_len);
+ buf_len += tmp_len;
+ }
+
+ if (buf == NULL) {
+ /* no extension renewed, return */
+ ret = 0;
+ goto end;
+ }
+
+ ret = create_voms_extension(buf, buf_len, &extension);
+ if (ret)
+ goto end;
+
+ X509_free(cert);
+ EVP_PKEY_free(privkey);
+ sk_X509_pop_free(chain, X509_free);
+
+ ret = load_proxy(new_proxy, &cert, &privkey, &chain);
+ if (ret)
+ goto end;
+
+ ret = create_proxy(cert, privkey, extension, &new_cert, &new_privkey);
+ if (ret)
+ goto end;
+
+ sk_X509_insert(chain, cert, 0);
+
+ ret = save_proxy(new_proxy, new_cert, new_privkey, chain);
+ if (ret)
+ goto end;
+
+ ret = 0;
+
+end:
+ VOMS_Destroy(voms_info);
+
+ return ret;
+}
+#else /* 0 */
+
+#ifdef NOVOMS
+static int
+renew_voms_certs(const char *old_proxy, char *myproxy_proxy, const char *new_proxy)
+{
+ return 0;
+}
+
+#else
+static int
+renew_voms_certs(const char *old_proxy, char *myproxy_proxy, const char *new_proxy)
+{
+ struct vomsdata *voms_info = NULL;
+ struct voms **voms_cert = NULL;
+ STACK_OF(X509) *chain = NULL;
+ EVP_PKEY *privkey = NULL;
+ X509 *cert = NULL;
+ int ret, err;
+ char *arg = NULL;
+
+ voms_info = VOMS_Init(vomsdir, cadir);
+ if (voms_info == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot initialize VOMS context (VOMS_Init() failed)");
+ return EDG_WLPR_ERROR_VOMS;
+ }
+
+ ret = load_proxy(old_proxy, &cert, &privkey, &chain);
+ if (ret)
+ goto end;
+
+ ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, voms_info, &err);
+ if (ret == 0) {
+ if (err == VERR_NOEXT) {
+ /* no VOMS cred, no problem; continue */
+ ret = 0;
+ } else {
+ edg_wlpr_Log(LOG_ERR, "Cannot get VOMS certificate(s) from proxy");
+ ret = EDG_WLPR_ERROR_VOMS;
+ }
+ goto end;
+ }
+
+ for (voms_cert = voms_info->data; voms_cert && *voms_cert; voms_cert++) {
+ ret = set_vo_params(voms_cert, &arg);
+ if (ret)
+ goto end;
+ }
+ ret = exec_voms_proxy_init(arg, myproxy_proxy, new_proxy);
+
+end:
+ VOMS_Destroy(voms_info);
+ return ret;
+}
+#endif /* NOVOMS */
+
+#endif /* 0 */
+
+static void
+register_signal(int signal)
+{
+ received_signal = signal;
+}
+
+static int
+renew_proxy(proxy_record *record, char *basename, char **new_proxy)
+{
+ char tmp_proxy[FILENAME_MAX];
+ int tmp_fd;
+ char repository_file[FILENAME_MAX];
+ FILE *fd = NULL;
+ int ret = -1;
+ char *p;
+ X509 *cert = NULL;
+ X509_NAME *subject = NULL;
+ char *server = NULL;
+ myproxy_socket_attrs_t *socket_attrs;
+ myproxy_request_t *client_request;
+ myproxy_response_t *server_response;
+ char *renewed_proxy;
+
+ 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));
+
+ edg_wlpr_Log(LOG_DEBUG, "Trying to renew proxy in %s.%d",
+ basename, record->suffix);
+
+ snprintf(tmp_proxy, sizeof(tmp_proxy), "%s.%d.renew.XXXXXX",
+ basename, record->suffix);
+ tmp_fd = mkstemp(tmp_proxy);
+ if (tmp_fd == -1) {
+ edg_wlpr_Log(LOG_ERR, "Cannot create temporary file (%s)",
+ strerror(errno));
+ return errno;
+ }
+
+ myproxy_set_delegation_defaults(socket_attrs, client_request);
+
+ snprintf(repository_file, sizeof(repository_file),"%s.%d",
+ basename, record->suffix);
+ fd = fopen(repository_file, "r");
+ if (fd == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot open proxy %s for renewal (%s)",
+ repository_file, strerror(errno));
+ ret = errno;
+ goto end; /* XXX */
+ }
+
+ cert = PEM_read_X509(fd, NULL, NULL, NULL);
+ fclose(fd);
+ if (cert == NULL) {
+ edg_wlpr_Log(LOG_ERR, "SSL routines failed to read proxy %s for renewal",
+ repository_file);
+ ret = EDG_WLPR_ERROR_SSL;
+ goto end;
+ }
+
+ subject = X509_NAME_dup(X509_get_subject_name(cert));
+ proxy_get_base_name(subject);
+ client_request->username = X509_NAME_oneline(subject, NULL, 0);
+ X509_NAME_free(subject);
+ X509_free(cert);
+ if (client_request->username == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot read subject name from %s", repository_file);
+ ret = EINVAL;
+ goto end;
+ }
+
+ /* XXX support VERY_SHORT_LIFETIME ? */
+ client_request->proxy_lifetime = 60 * 60 * DGPR_RETRIEVE_DEFAULT_HOURS;
+
+ server = (record->myproxy_server) ? record->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);
+
+ p = strchr(socket_attrs->pshost, ':');
+ if (p) {
+ *p++ = '\0';
+ ret = edg_wlpr_DecodeInt(p, &socket_attrs->psport);
+ if (ret)
+ goto end;
+ } else
+ socket_attrs->psport = MYPROXY_SERVER_PORT;
+
+ ret = myproxy_get_delegation(socket_attrs, client_request, repository_file,
+ server_response, tmp_proxy);
+ if (ret == 1) {
+ ret = EDG_WLPR_ERROR_MYPROXY;
+ edg_wlpr_Log(LOG_ERR, "Cannot get renewed proxy from Myproxy server");
+ goto end;
+ }
+
+ renewed_proxy = tmp_proxy;
+
+ if (voms_enabled) {
+ char tmp_voms_proxy[FILENAME_MAX];
+ int tmp_voms_fd;
+
+ snprintf(tmp_voms_proxy, sizeof(tmp_voms_proxy), "%s.%d.renew.XXXXXX",
+ basename, record->suffix);
+ 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_certs(repository_file, tmp_proxy, tmp_voms_proxy);
+ if (ret)
+ goto end;
+
+ renewed_proxy = tmp_voms_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;
+}
+
+static void
+check_renewal(char *datafile, int force_renew)
+{
+ char line[1024];
+ proxy_record record;
+ char *p;
+ int ret, i;
+ time_t current_time;
+ FILE *meta_fd = NULL;
+ char basename[FILENAME_MAX];
+ edg_wlpr_Request request;
+ edg_wlpr_Response response;
+ char *new_proxy = NULL;
+ char *entry = NULL;
+ char **tmp;
+ int num = 0;
+
+ assert(datafile != NULL);
+
+ memset(&record, 0, sizeof(record));
+ memset(basename, 0, sizeof(basename));
+ memset(&request, 0, sizeof(request));
+ memset(&response, 0, sizeof(response));
+
+ strncpy(basename, datafile, sizeof(basename) - 1);
+ p = basename + strlen(basename) - strlen(".data");
+ if (strcmp(p, ".data") != 0) {
+ edg_wlpr_Log(LOG_ERR, "Meta filename doesn't end with '.data'");
+ return;
+ }
+ *p = '\0';
+
+ request.command = EDG_WLPR_COMMAND_UPDATE_DB;
+ request.proxy_filename = strdup(basename);
+
+ meta_fd = fopen(datafile, "r");
+ if (meta_fd == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot open meta file %s (%s)",
+ datafile, strerror(errno));
+ return;
+ }
+
+ current_time = time(NULL);
+ edg_wlpr_Log(LOG_DEBUG, "Reading metafile %s", datafile);
+
+ while (fgets(line, sizeof(line), meta_fd) != NULL) {
+ free_record(&record);
+ p = strchr(line, '\n');
+ if (p)
+ *p = '\0';
+ ret = decode_record(line, &record);
+ if (ret)
+ continue; /* XXX exit? */
+ if (record.jobids.len == 0) /* no jobid registered for this proxy */
+ continue;
+ if (record.end_time - current_time < RENEWAL_CLOCK_SKEW ||
+ abs(record.next_renewal - current_time) < RENEWAL_CLOCK_SKEW ||
+ record.next_renewal < current_time ||
+ record.end_time < current_time ||
+ force_renew) {
+ ret = EDG_WLPR_PROXY_EXPIRED;
+ if (record.end_time >= current_time)
+ /* only try renewal if the proxy hasn't already expired */
+ ret = renew_proxy(&record, basename, &new_proxy);
+
+ /* if the proxy wasn't renewed have the daemon planned another renewal */
+ asprintf(&entry, "%d:%s", record.suffix, (ret == 0) ? new_proxy : "");
+ if (new_proxy) {
+ free(new_proxy); new_proxy = NULL;
+ }
+
+ tmp = realloc(request.entries, (num + 2) * sizeof(*tmp));
+ if (tmp == NULL) {
+ free_record(&record);
+ return;
+ }
+ request.entries = tmp;
+ request.entries[num] = entry;
+ request.entries[num+1] = NULL;
+ num++;
+ }
+ }
+ free_record(&record);
+
+ if (num > 0) {
+ ret = edg_wlpr_RequestSend(&request, &response);
+ if (ret != 0)
+ edg_wlpr_Log(LOG_ERR,
+ "Failed to send update request to master (%d)", ret);
+ else if (response.response_code != 0)
+ edg_wlpr_Log(LOG_ERR,
+ "Master failed to update database (%d)", response.response_code);
+
+ /* delete all tmp proxy files which may survive */
+ for (i = 0; i < num; i++) {
+ p = strchr(request.entries[i], ':');
+ if (p+1)
+ unlink(p+1);
+ }
+ }
+ fclose(meta_fd);
+
+ edg_wlpr_CleanResponse(&response);
+ edg_wlpr_CleanRequest(&request);
+
+ return;
+}
+
+int renewal(int force_renew)
+{
+ DIR *dir = NULL;
+ struct dirent *file;
+ FILE *fd;
+
+ edg_wlpr_Log(LOG_DEBUG, "Starting renewal process");
+
+ if (chdir(repository)) {
+ edg_wlpr_Log(LOG_ERR, "Cannot access repository directory %s (%s)",
+ repository, strerror(errno));
+ return errno;
+ }
+
+ dir = opendir(repository);
+ if (dir == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot open repository directory %s (%s)",
+ repository, strerror(errno));
+ return errno;
+ }
+
+ while ((file = readdir(dir))) {
+ /* read files of format `md5sum`.data, where md5sum() is of fixed length
+ 32 chars */
+ if (file->d_name == NULL || strlen(file->d_name) != 37 ||
+ strcmp(file->d_name + 32, ".data") != 0)
+ continue;
+ fd = fopen(file->d_name, "r");
+ if (fd == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot open meta file %s (%s)",
+ file->d_name, strerror(errno));
+ continue;
+ }
+ check_renewal(file->d_name, force_renew);
+ fclose(fd);
+ }
+ closedir(dir);
+ edg_wlpr_Log(LOG_DEBUG, "Finishing renewal process");
+ return 0;
+}
+
+void
+watchdog_start(void)
+{
+ struct sigaction sa;
+ int force_renewal;
+
+ memset(&sa,0,sizeof(sa));
+ sa.sa_handler = register_signal;
+ sigaction(SIGUSR1, &sa, NULL);
+
+ /* load_vomses(); */
+
+ while (1) {
+ received_signal = -1;
+ sleep(60 * 5);
+ force_renewal = (received_signal == SIGUSR1) ? 1 : 0;
+ /* XXX uninstall signal handler ? */
+ renewal(force_renewal);
+ }
+}
--- /dev/null
+#ifndef RENEWAL_LOCL_H
+#define RENEWAL_LOCL_H
+
+#ident "$Header$"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <syslog.h>
+#include <linux/limits.h>
+#include <signal.h>
+#include <assert.h>
+#include <getopt.h>
+#include <dirent.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <openssl/md5.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+#include "renewal.h"
+
+#define JDL_MYPROXY "Myproxy_server="
+
+typedef enum {
+ EDG_WLPR_COMMAND_NONE = 0,
+ EDG_WLPR_COMMAND_REG = 1,
+ EDG_WLPR_COMMAND_UNREG,
+ EDG_WLPR_COMMAND_GET,
+ EDG_WLPR_COMMAND_LIST,
+ EDG_WLPR_COMMAND_STATUS,
+ EDG_WLPR_COMMAND_UPDATE_DB,
+} edg_wlpr_Command;
+
+/* prefix neni nutny */
+#define EDG_WLPR_PROTO_VERSION "Version="
+#define EDG_WLPR_PROTO_COMMAND "Command="
+#define EDG_WLPR_PROTO_MYPROXY_SERVER "Myproxy_server="
+#define EDG_WLPR_PROTO_PROXY "Proxy_name="
+#define EDG_WLPR_PROTO_UNIQUE_PROXY "Unique=" /* XXX */
+#define EDG_WLPR_PROTO_JOBID "Jobid="
+#define EDG_WLPR_PROTO_ENTRY "Entry="
+
+#define EDG_WLPR_PROTO_RESPONSE "Response=" /* XXX result ?? */
+#define EDG_WLPR_PROTO_START_TIME "Start_time="
+#define EDG_WLPR_PROTO_END_TIME "End_time="
+#define EDG_WLPR_PROTO_RENEWAL_TIME "Renewal_time=" /* XXX Next renewal ?? */
+
+#define EDG_WLPR_MYPROXY_PORT 7512
+
+#define EDG_WLPR_REPOSITORY_ROOT "/var/spool/edg-wl-renewd"
+
+#define EDG_WLPR_BUF_SIZE 4096
+
+#define EDG_WLPR_VERSION "EDG Proxy Renewal 1.0"
+
+#define MAX_PROXIES 4 /* max. number of jobids sharing one proxy */
+
+typedef struct {
+ char *version;
+ edg_wlpr_Command command;
+ char *myproxy_server;
+ char *proxy_filename;
+ int unique;
+ char *jobid;
+ char **entries; /* for updates from the renewal part (renew.c) */
+} edg_wlpr_Request;
+
+typedef struct {
+ char *version;
+ int response_code;
+ time_t start_time;
+ time_t end_time;
+ time_t next_renewal_time;
+ int counter;
+ char *myproxy_server;
+ char **filenames;
+} edg_wlpr_Response;
+
+#define DGPR_REG_SOCKET_NAME_ROOT "/tmp/dgpr_renew_"
+
+#if 0
+/* Errors: */
+/* XXX enum */
+#define EDG_WLPR_ERROR_EOF 1
+#define EDG_WLPR_ERROR_PARSE_NOT_FOUND 2
+#define EDG_WLPR_ERROR_PARSE_ERROR 3
+#define EDG_WLPR_ERROR_UNKNOWN_COMMAND 4
+#define EDG_WLPR_ERROR_NOTFOUND 5
+#endif
+
+int
+edg_wlpr_GetToken(const char *msg, const size_t msg_len,
+ const char *key, const char *separators,
+ int req_index, char **value);
+
+int
+edg_wlpr_StoreToken(char **buf, size_t *buf_len, char *command,
+ char *value, const char *separator);
+
+int
+edg_wlpr_Read(int sock, char **buf, size_t *buf_len);
+
+int
+edg_wlpr_Write(int sock, char *buf, size_t buf_len);
+
+void
+edg_wlpr_CleanRequest(edg_wlpr_Request *request);
+
+void
+edg_wlpr_CleanResponse(edg_wlpr_Response *response);
+
+const char *
+edg_wlpr_GetErrorString(int err);
+
+char *
+edg_wlpr_EncodeInt(int num); /* long? time */
+
+int
+edg_wlpr_DecodeInt(char *str, int *num);
+
+int
+edg_wlpr_RequestSend(edg_wlpr_Request *request, edg_wlpr_Response *response);
+
+#endif /* RENEWAL_LOCL_H */
--- /dev/null
+#include "renewal_locl.h"
+#include "renewd_locl.h"
+
+static const char rcsid[] = "$Header$";
+
+#define SEPARATORS "\n"
+/* GRIDMANAGER_CHECKPROXY_INTERVAL + GRIDMANAGER_MINIMUM_PROXY_TIME */
+#define CONDOR_MINIMUM_PROXY_TIME (1800)
+
+int debug = 0;
+char *repository = NULL;
+time_t condor_limit = CONDOR_MINIMUM_PROXY_TIME;
+char *cadir = NULL;
+char *vomsdir = NULL;
+int voms_enabled = 0;
+
+char *vomsconf = "/opt/edg/etc/vomses";
+#ifndef NOVOMS
+struct vomses_records vomses;
+#endif
+
+static struct option opts[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { "debug", no_argument, NULL, 'd' },
+ { "repository", required_argument, NULL, 'r' },
+ { "condor-limit", required_argument, NULL, 'c' },
+ { "CAdir", required_argument, NULL, 'C' },
+ { "VOMSdir", required_argument, NULL, 'V' },
+ { "enable-voms", no_argument, NULL, 'A' },
+ { "voms-config", required_argument, NULL, 'G' },
+ { NULL, 0, NULL, 0 }
+};
+
+typedef struct {
+ edg_wlpr_Command code;
+ void (*handler) (edg_wlpr_Request *request, edg_wlpr_Response *response);
+} command_table;
+
+static command_table commands[] = {
+ { EDG_WLPR_COMMAND_REG, register_proxy, },
+ { EDG_WLPR_COMMAND_UNREG, unregister_proxy, },
+ { EDG_WLPR_COMMAND_GET, get_proxy, },
+#if 0
+ { EDG_WLPR_COMMAND_LIST, list_proxies, },
+ { EDG_WLPR_COMMAND_STATUS, status_proxy, },
+#endif
+ { EDG_WLPR_COMMAND_UPDATE_DB, update_db, },
+ { 0, NULL },
+};
+
+/* static prototypes */
+static void
+usage(char *progname);
+
+static int
+do_listen(char *socket_name, int *sock);
+
+static int
+encode_response(edg_wlpr_Response *response, char **msg);
+
+static command_table *
+find_command(edg_wlpr_Command code);
+
+static int
+proto(int sock);
+
+static int
+doit(int sock);
+
+static int
+decode_request(const char *msg, const size_t msg_len, edg_wlpr_Request *request);
+
+static command_table *
+find_command(edg_wlpr_Command code)
+{
+ command_table *c;
+
+ for (c = commands; c->code; c++) {
+ if (c->code == code)
+ return c;
+ }
+ return NULL;
+}
+
+static int
+proto(int sock)
+{
+ char *buf = NULL;
+ size_t buf_len;
+ int ret;
+ edg_wlpr_Response response;
+ edg_wlpr_Request request;
+ command_table *command;
+
+ memset(&request, 0, sizeof(request));
+ memset(&response, 0, sizeof(response));
+
+ ret = edg_wlpr_Read(sock, &buf, &buf_len);
+ if (ret) {
+ edg_wlpr_Log(LOG_ERR, "Error reading from client: %s",
+ edg_wlpr_GetErrorString(ret));
+ return ret;
+ }
+
+ ret = decode_request(buf, buf_len, &request);
+ free(buf);
+ if (ret)
+ goto end;
+
+ /* XXX check request (protocol version, ...) */
+
+ command = find_command(request.command);
+ if (command == NULL) {
+ ret = EDG_WLPR_ERROR_UNKNOWN_COMMAND;
+ edg_wlpr_Log(LOG_ERR, "Received unknown command (%d)", request.command);
+ goto end;
+ }
+
+ edg_wlpr_Log(LOG_INFO, "Received command code %d for proxy %s",
+ request.command,
+ request.proxy_filename ? request.proxy_filename : "(unspecified)");
+
+ command->handler(&request, &response);
+
+ ret = encode_response(&response, &buf);
+ if (ret)
+ goto end;
+
+ ret = edg_wlpr_Write(sock, buf, strlen(buf) + 1);
+ free(buf);
+ if (ret) {
+ edg_wlpr_Log(LOG_ERR, "Error sending response to client: %s",
+ edg_wlpr_GetErrorString(ret));
+ goto end;
+ }
+
+end:
+ edg_wlpr_CleanRequest(&request);
+ edg_wlpr_CleanResponse(&response);
+
+ return ret;
+}
+
+static int
+doit(int sock)
+{
+ int newsock;
+ struct sockaddr_un client_addr;
+ int client_addr_len = sizeof(client_addr);
+#if 0
+ next_renewal = LONG_MAX;
+ size_of_proxies = PROXIES_ALLOC_SIZE;
+ proxies = malloc((size_of_proxies) * sizeof(struct guarded_proxy *));
+ if (proxies == NULL) {
+ return ENOMEM;
+ }
+ proxies[0] = NULL;
+#endif
+
+#if 0
+ sigemptyset(&sset);
+ sigaddset(&sset,SIGTERM);
+ sigaddset(&sset,SIGINT);
+ sigaddset(&sset, SIGKILL);
+ sigaddset(&sset, SIGUSR1);
+ sigaddset(&sset, SIGALRM);
+ sigprocmask(SIG_BLOCK,&sset,NULL);
+#endif
+
+ while (1) {
+#if 0
+ sigprocmask(SIG_UNBLOCK,&sset,NULL);
+ newsock = accept(sock, (struct sockaddr *) &client_addr, &client_addr_len);
+ sigprocmask(SIG_BLOCK,&sset,NULL);
+
+ if (newsock == -1) {
+ if (errno == EINTR) /* ERESTARTSYS */
+ proxy_renewal(received_signal);
+ else
+ log();
+ continue;
+ }
+#else
+ newsock = accept(sock, (struct sockaddr *) &client_addr, &client_addr_len);
+ if (newsock == -1) {
+ edg_wlpr_Log(LOG_ERR, "accept() failed");
+ continue;
+ }
+ edg_wlpr_Log(LOG_DEBUG, "Got connection");
+
+#endif
+
+ proto(newsock);
+
+ edg_wlpr_Log(LOG_DEBUG, "Connection closed");
+ close(newsock);
+ }
+}
+
+static int
+decode_request(const char *msg, const size_t msg_len, edg_wlpr_Request *request)
+{
+ char *value = NULL;
+#if 0
+ char *p;
+ int port;
+#endif
+ int ret;
+ int index;
+
+ /* XXX add an ending zero '\0' */
+
+ assert(msg != NULL);
+ assert(request != NULL);
+
+ memset(request, 0, sizeof(*request));
+
+ ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_VERSION, SEPARATORS,
+ 0, &request->version);
+ if (ret) {
+ edg_wlpr_Log(LOG_ERR, "Protocol error reading protocol specification: %s",
+ edg_wlpr_GetErrorString(ret));
+ return ret;
+ }
+
+ ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_COMMAND, SEPARATORS,
+ 0, &value);
+ if (ret) {
+ edg_wlpr_Log(LOG_ERR, "Protocol error reading command specification: %s",
+ edg_wlpr_GetErrorString(ret));
+ goto err;
+ }
+
+ ret = edg_wlpr_DecodeInt(value, (int *)(&request->command));
+ if (ret) {
+ edg_wlpr_Log(LOG_ERR, "Received non-numeric command specification (%s)",
+ value);
+ free(value);
+ goto err;
+ }
+ free(value);
+
+ if (find_command(request->command) == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Received unknown command (%d)", request->command);
+ ret = EDG_WLPR_ERROR_UNKNOWN_COMMAND;
+ goto err;
+ }
+
+ 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) {
+ edg_wlpr_Log(LOG_ERR, "Protocol error reading myproxy server specification: %s",
+ edg_wlpr_GetErrorString(ret));
+ goto err;
+ }
+
+#if 0
+ request->myproxy_port = EDG_WLPR_MYPROXY_PORT; /* ??? */
+ if (request->myproxy_server && (p = strchr(request->myproxy_server, ':'))) {
+ *p = '\0';
+ port = atol(p+1); /* XXX see myproxy for err check */
+ request->myproxy_port = port;
+ }
+#endif
+
+ 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) {
+ edg_wlpr_Log(LOG_ERR, "Protocol error reading proxy specification: %s",
+ edg_wlpr_GetErrorString(ret));
+ goto err;
+ }
+
+#if 0
+ ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_UNIQUE_PROXY,
+ SEPARATORS, 0, &value);
+ if (ret && ret != EDG_WLPR_ERROR_PARSE_NOT_FOUND)
+ goto err;
+ if (ret == 0 && strcasecmp(value, "yes") == 0)
+ request->unique = 1;
+ free(value);
+#endif
+
+ 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) {
+ edg_wlpr_Log(LOG_ERR, "Protocol error reading JobId : %s",
+ edg_wlpr_GetErrorString(ret));
+ goto err;
+ }
+
+ index = 0;
+ while ((ret = edg_wlpr_GetToken(msg, msg_len, EDG_WLPR_PROTO_ENTRY,
+ SEPARATORS, index, &value)) == 0) {
+ char **tmp;
+
+ tmp = realloc(request->entries, (index + 2) * sizeof(*tmp));
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto err;
+ }
+ request->entries = tmp;
+ request->entries[index] = value;
+ index++;
+ }
+ if (ret != EDG_WLPR_ERROR_PROTO_PARSE_NOT_FOUND)
+ goto err;
+ if (request->entries)
+ request->entries[index] = NULL;
+
+ return 0;
+
+err:
+ edg_wlpr_CleanRequest(request);
+ return ret;
+}
+
+static int
+encode_response(edg_wlpr_Response *response, char **msg)
+{
+ char *buf;
+ size_t buf_len;
+ int ret;
+
+ buf_len = EDG_WLPR_BUF_SIZE;
+ buf = malloc(buf_len);
+ if (buf == NULL)
+ return ENOMEM;
+ buf[0] = '\0';
+
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_VERSION,
+ EDG_WLPR_VERSION, SEPARATORS);
+ if (ret)
+ goto err;
+
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_RESPONSE,
+ edg_wlpr_EncodeInt(response->response_code),
+ SEPARATORS);
+ if (ret)
+ goto err;
+
+ if (response->myproxy_server) {
+ char host[1024];
+
+#if 0
+ snprintf(host, sizeof(host), "%s:%d", response->myproxy_server,
+ (response->myproxy_port) ? response->myproxy_port : EDG_WLPR_MYPROXY_PORT);
+#endif
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_MYPROXY_SERVER,
+ host, SEPARATORS);
+ if (ret)
+ goto err;
+ }
+
+ if (response->start_time) {
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_START_TIME,
+ edg_wlpr_EncodeInt(response->start_time),
+ SEPARATORS);
+ if (ret)
+ goto err;
+ }
+
+ if (response->end_time) {
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_END_TIME,
+ edg_wlpr_EncodeInt(response->end_time),
+ SEPARATORS);
+ if (ret)
+ goto err;
+ }
+
+ if (response->next_renewal_time) {
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_RENEWAL_TIME,
+ edg_wlpr_EncodeInt(response->next_renewal_time),
+ SEPARATORS);
+ if (ret)
+ goto err;
+ }
+
+ if (response->filenames) {
+ char **p = response->filenames;
+ while (*p) {
+ ret = edg_wlpr_StoreToken(&buf, &buf_len, EDG_WLPR_PROTO_PROXY, *p,
+ SEPARATORS);
+ if (ret)
+ goto err;
+ p++;
+ }
+ }
+
+ buf[strlen(buf)] = '\0';
+ *msg = buf;
+ return 0;
+
+err:
+ free(buf);
+ *msg = NULL;
+ return ret;
+}
+
+
+static void
+usage(char *progname)
+{
+ fprintf(stderr,"usage: %s [option]\n"
+ "\t-h, --help display this help and exit\n"
+ "\t-v, --version output version information and exit\n"
+ "\t-d, --debug don't fork, print out debugging information\n"
+ "\t-r, --repository repository directory\n"
+ "\t-c, --condor-limit how long before expiration the proxy must be renewed\n"
+ "\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",
+ progname);
+}
+
+static int
+do_listen(char *socket_name, int *sock)
+{
+ struct sockaddr_un my_addr;
+ int s;
+ int ret;
+
+ assert(sock != NULL);
+
+ memset(&my_addr, 0, sizeof(my_addr));
+ 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) {
+ edg_wlpr_Log(LOG_ERR, "socket(): %s", strerror(errno));
+ return errno;
+ }
+
+ ret = bind(s, (struct sockaddr *)&my_addr, sizeof(my_addr));
+ if (ret == -1) {
+ edg_wlpr_Log(LOG_ERR, "bind(): %s", strerror(errno));
+ close(s);
+ return errno;
+ }
+
+ ret = listen(s, 5); /* XXX enough ? */
+ if (ret == -1) {
+ edg_wlpr_Log(LOG_ERR, "listen(): %s", strerror(errno));
+ close(s);
+ return errno;
+ }
+
+ *sock = s;
+ return 0;
+}
+
+void
+edg_wlpr_Log(int dbg_level, const char *format, ...)
+{
+ va_list ap;
+ char log_mess[1024];
+
+ /* cannot handle the %m format argument specific for syslog() */
+ va_start(ap, format);
+ vsnprintf(log_mess, sizeof(log_mess), format, ap);
+ va_end(ap);
+
+ if (debug)
+ printf("[%d] %s\n", getpid(), log_mess);
+ else
+ if (dbg_level < LOG_DEBUG) /* XXX make configurable */
+ syslog(dbg_level, "%s", log_mess);
+}
+
+int
+start_watchdog(pid_t *pid)
+{
+ pid_t p;
+
+ switch ((p = fork())) {
+ case -1:
+ edg_wlpr_Log(LOG_ERR, "fork() failed: %s",
+ strerror(errno));
+ return errno;
+ case 0:
+ watchdog_start();
+ exit(0);
+ break;
+ default:
+ *pid = p;
+ return 0;
+ }
+ /* not reachable */
+ exit(0);
+}
+
+#ifdef NOVOMS
+static int
+load_vomses()
+{
+ return ENOSYS;
+}
+
+#else
+static int
+load_vomses()
+{
+ FILE *fd = NULL;
+ char line[1024];
+ char *nick, *hostname;
+ int port;
+ vomses_record *rec;
+ vomses_record **tmp;
+ char *p;
+
+ fd = fopen(vomsconf, "r");
+ if (fd == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Cannot open vomses configuration file (%s)",
+ strerror(errno));
+ return errno;
+ }
+ while (fgets(line, sizeof(line), fd) != NULL) {
+ p = line;
+ if (*p != '"') {
+ edg_wlpr_Log(LOG_ERR, "Parsing error when reading vomses configuration file");
+ return EINVAL;
+ }
+ nick = strdup(strtok(p+1, "\""));
+
+ p = strtok(NULL, "\"");
+ hostname = strdup(strtok(NULL, "\""));
+
+ p = strtok(NULL, "\"");
+ port = atoi(strdup(strtok(NULL, "\"")));
+
+ if (nick == NULL || hostname == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Parsing error when reading vomses configuration file");
+ return EINVAL;
+ }
+
+ rec = calloc(1, sizeof(*rec));
+ if (rec == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Not enough memory");
+ return ENOMEM;
+ }
+ rec->nick = nick;
+ rec->hostname = hostname;
+ rec->port = port;
+
+ tmp = realloc(vomses.val, vomses.len + 1);
+ if (tmp == NULL) {
+ edg_wlpr_Log(LOG_ERR, "Not enough memory");
+ return ENOMEM;
+ }
+ vomses.val = tmp;
+ vomses.len++;
+
+ vomses.val[vomses.len-1] = rec;
+ }
+ fclose(fd);
+ return 0;
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+ int sock;
+ char *progname;
+ int opt;
+ int fd;
+ char sockname[PATH_MAX];
+ int ret;
+ pid_t pid;
+
+ progname = strrchr(argv[0],'/');
+ if (progname) progname++;
+ else progname = argv[0];
+
+ repository = EDG_WLPR_REPOSITORY_ROOT;
+ debug = 0;
+
+ while ((opt = getopt_long(argc, argv, "hvdr:c:C:V:AG:", opts, NULL)) != EOF)
+ switch (opt) {
+ case 'h': usage(progname); exit(0);
+ case 'v': fprintf(stdout, "%s:\t%s\n", progname, rcsid); exit(0);
+ case 'd': debug = 1; break;
+ case 'r': repository = optarg; break;
+ case 'c': condor_limit = atoi(optarg); break;
+ case 'C': cadir = optarg; break;
+ case 'V': vomsdir = optarg; break;
+ case 'A': voms_enabled = 1; break;
+ case 'G': vomsconf = optarg; break;
+ case '?': usage(progname); return 1;
+ }
+
+ if (optind < argc) {
+ usage(progname);
+ exit(1);
+ }
+
+ if (chdir(repository)) {
+ edg_wlpr_Log(LOG_ERR, "Cannot access repository directory %s (%s)",
+ repository, strerror(errno));
+ exit(1);
+ }
+
+ if (!debug)
+ for (fd = 3; fd < OPEN_MAX; fd++) close(fd);
+
+ if (!debug) {
+ /* chdir ? */
+ if (daemon(1,0) == -1) {
+ perror("deamon()");
+ exit(1);
+ }
+ openlog(progname, LOG_PID, LOG_DAEMON);
+ }
+
+ if (voms_enabled) {
+ char *path;
+ char *new_path;
+ ret = load_vomses();
+ if (ret)
+ return 1;
+ setenv("GLOBUS_VERSION", "22", 0);
+ if (VOMS_INSTALL_PATH != NULL && *VOMS_INSTALL_PATH != '\0') {
+ path = getenv("PATH");
+ asprintf(&new_path, "%s:%s/bin", path, VOMS_INSTALL_PATH);
+ setenv("PATH", new_path, 1);
+ }
+ }
+
+ ret = start_watchdog(&pid);
+ if (ret)
+ return 1;
+
+ umask(0177);
+ snprintf(sockname, sizeof(sockname), "%s%d",
+ DGPR_REG_SOCKET_NAME_ROOT, getuid());
+ /* XXX check that the socket is not already active */
+ ret = do_listen(sockname, &sock);
+ if (ret)
+ return 1;
+ edg_wlpr_Log(LOG_DEBUG, "Listening at %s", sockname);
+
+#if 0
+ /* XXX ??? */
+ install_handlers();
+#endif
+
+
+#if 0
+ /* XXX this overrides setings done by install_handlers()? */
+ signal(SIGTERM, cleanup);
+ signal(SIGINT, cleanup);
+ signal(SIGKILL, cleanup);
+ signal(SIGPIPE, SIG_IGN);
+
+ atexit(cleanup);
+#endif
+
+ ret = doit(sock);
+
+ close(sock);
+ return ret;
+}
--- /dev/null
+#ifndef RENEWALD_LOCL_H
+#define RENEWALD_LOCL_H
+
+#ident "$Header$"
+
+#include <myproxy.h>
+#include <myproxy_delegation.h>
+
+#include "glite/wms/thirdparty/globus_ssl_utils/sslutils.h"
+#include "renewal.h"
+
+#ifdef HAVE_DMALLOC_H
+#include <dmalloc.h>
+#endif
+
+/* XXX */
+#if 0
+#define EDG_WLPR_ERROR_PARSE_NOT_FOUND EDG_WLPR_ERROR_PROTO_PARSE_ERROR
+#define EDG_WLPR_ERROR_NOTFOUND EDG_WLPR_PROXY_NOT_REGISTERED
+#endif
+
+typedef struct {
+ unsigned int len;
+ char **val;
+} prd_list;
+
+typedef struct {
+ int suffix;
+ prd_list jobids;
+ int unique;
+ int voms_exts;
+ char *myproxy_server;
+ time_t end_time;
+ time_t next_renewal;
+} proxy_record;
+
+typedef struct vomses_record {
+ char *nick;
+ char *hostname;
+ int port;
+} vomses_record;
+
+typedef struct vomses_records {
+ unsigned int len;
+ struct vomses_record **val;
+} vomses_records;
+
+/* commands */
+void
+register_proxy(edg_wlpr_Request *request, edg_wlpr_Response *response);
+
+void
+unregister_proxy(edg_wlpr_Request *request, edg_wlpr_Response *response);
+
+void
+get_proxy(edg_wlpr_Request *request, edg_wlpr_Response *response);
+
+void
+update_db(edg_wlpr_Request *request, edg_wlpr_Response *response);
+
+int
+get_times(char *proxy_file, proxy_record *record);
+
+void
+watchdog_start(void);
+
+void
+edg_wlpr_Log(int dbg_level, const char *format, ...);
+
+int
+decode_record(char *line, proxy_record *record);
+
+int
+encode_record(proxy_record *record, char **line);
+
+void
+free_record(proxy_record *record);
+
+int
+load_proxy(const char *filename, X509 **cert, EVP_PKEY **privkey,
+ STACK_OF(X509) **chain);
+
+#endif /* RENEWALD_LOCL_H */
+++ /dev/null
-.project
-.cdtproject
\ No newline at end of file
+++ /dev/null
-LICENSE file for EGEE Middleware
-================================
-
-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
-<email address>.
-
-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/
-
-
+++ /dev/null
-## *********************************************************************
-## *
-## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid.
-## * For license conditions see LICENSE file or
-## * http://www.edg.org/license.html
-## *
-## *********************************************************************
-
-## Process this file with automake to produce Makefile.in
-
-## Subdirectories list
-SUBDIRS = src test
-
-## Default flags to run aclocal
-ACLOCAL_AMFLAGS = -I project
-
-stage:
- @set fnord $(MAKEFLAGS); amf=$$2; \
- dot_seen=no; \
- target="install"; \
- prefix_arg="@prefix@"; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
- echo "Making $$target $$prefix_arg in $$subdir"; \
- if test "$$subdir" = "."; then \
- dot_seen=yes; \
- local_target="$$target-am"; \
- else \
- local_target="$$target"; \
- fi; \
- (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target $$prefix_arg) \
- || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
- done; \
- if test "$$dot_seen" = "no"; then \
- $(MAKE) $(AM_MAKEFLAGS) "$$target-am" $$prefix_arg || exit 1; \
- fi; test -z "$$fail"
-
-distsrc: dist
- mv $(distdir).tar.gz $(DISTTAR)/$(distdir)_src.tar.gz
-
-distbin:
- @set fnord $(MAKEFLAGS); amf=$$2; \
- dot_seen=no; \
- target="install"; \
- tmpdistbin="$(WORKDIR)/dist_bin"; \
- prefix_arg="prefix=$$tmpdistbin"; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
- echo "Making $$target $$prefix_arg in $$subdir"; \
- if test "$$subdir" = "."; then \
- dot_seen=yes; \
- local_target="$$target-am"; \
- else \
- local_target="$$target"; \
- fi; \
- (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target $$prefix_arg) \
- || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
- done; \
- if test "$$dot_seen" = "no"; then \
- $(MAKE) $(AM_MAKEFLAGS) "$$target-am" $$prefix_arg || exit 1; \
- fi; test -z "$$fail"; \
- pushd $$tmpdistbin; \
- $(AMTAR) -zcf $(DISTTAR)/$(distdir)_bin.tar.gz .; \
- popd; \
- rm -rf $$tmpdistbin
-
+++ /dev/null
-#! /bin/sh
-
-mkdir -p src/autogen
-set -x
-aclocal -I project
-libtoolize --force
-autoheader
-automake --foreign --add-missing --copy
-autoconf
+++ /dev/null
-#
-# 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
-#
-# Common configure.ac file for the GLite WMS Common module
-#
-# Authors: Alberto Di Meglio <alberto.di.meglio@cern.ch>
-# Version info: $Id$
-# Release: $Name$
-#
-# Revision history:
-# $Log$
-# Revision 1.5 2004/06/16 11:02:05 eronchie
-# Added configure options
-# WARNING: Work in progress
-#
-# Revision 1.4 2004/06/14 18:14:35 eronchie
-# Added Configure options
-# WARNING work in progress
-#
-# Revision 1.3 2004/06/01 13:52:35 eronchie
-# Updated namespace for jobid.
-# Changed glite::wms::common::jobid namespace in glite::wms::jobid
-#
-# Revision 1.2 2004/05/31 14:03:30 eronchie
-# Merged with code in the infnforge repository
-#
-# Revision 1.1.1.1 2004/05/26 18:45:05 eronchie
-# Import of wms jobid
-#
-#
-#
-
-# Process this file with autoconf to produce a configure script.
-
-AC_PREREQ(2.57)
-AC_INIT([GLite WMS jobid], [0.0.0])
-AC_CONFIG_AUX_DIR([./project])
-AM_INIT_AUTOMAKE([1.6.3 subdir-objects])
-AC_CONFIG_SRCDIR([src/jobid/cjobid.h])
-
-# Notices.
-AC_COPYRIGHT([Copyright (c) 2004 The EU EGEE Project
-See LICENCE file for details
-])
-AC_REVISION([$Revision$])
-
-#Environment.
-WORKDIR=`pwd`
-AC_SUBST(WORKDIR)
-
-# Checks for programs.
-AC_PROG_CC
-AC_PROG_CPP
-AC_PROG_CXX
-AC_PROG_CXXCPP
-AM_PROG_CC_C_O
-AC_PROG_LIBTOOL
-
-# Checks for libraries.
-
-# Checks for header files.
-AC_CHECK_HEADERS([fcntl.h mntent.h sys/vfs.h syslog.h unistd.h])
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_HEADER_STDBOOL
-AC_C_CONST
-AC_C_INLINE
-AC_TYPE_OFF_T
-AC_TYPE_SIZE_T
-AC_CHECK_MEMBERS([struct stat.st_rdev])
-AC_TYPE_UID_T
-AC_CHECK_TYPES([ptrdiff_t])
-
-# Checks for library functions.
-AC_HEADER_STDC
-AC_FUNC_ERROR_AT_LINE
-AC_FUNC_GETMNTENT
-AC_FUNC_MEMCMP
-AC_FUNC_STAT
-AC_FUNC_STRFTIME
-AC_FUNC_VPRINTF
-AC_CHECK_FUNCS([bzero endpwent ftruncate getmntent memset mkdir pow strerror strtol])
-
-have_globus=no
-
-AC_GLOBUS([], have_globus=yes, have_globus=no)
-AC_MSG_RESULT(["GLOBUS found $have_globus"])
-
-have_glite_wms_common=no
-
-AC_GLITE
-
-AC_GLITE_WMS_COMMON([], have_glite_wms_common=yes, have_glite_wms_common=no)
-AC_MSG_RESULT(["GLITE_WMS_COMMON found $have_glite_wms_common"])
-
-# Configuration items
-AC_PREFIX_DEFAULT([/opt/glite])
-AM_CONFIG_HEADER([src/autogen/config.h])
-AC_CONFIG_FILES([Makefile])
-AC_CONFIG_FILES([src/Makefile])
-AC_CONFIG_FILES([src/jobid/Makefile])
-AC_CONFIG_FILES([test/Makefile])
-
-AC_OUTPUT
+++ /dev/null
- <!-- ======================================================
- Define extra properties here ...
- ====================================================== -->
-
- <project name="configure options">
- <property name="configure.args"
- value="--prefix=${workspace.abs.dir}/stage --with-globus-prefix=${with.globus.prefix} --with-globus-thr-flavor=${with.globus.thr.flavor} --with-globus-nothr-flavor=${with.globus.nothr.flavor} --with-glite-location=${with.glite.location} --with-dist-location=${with.dist.location}"/>
-
- </project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- Common build properties file for the Glite WMS Common component
-
- Authors: Alberto Di Meglio <alberto.di.meglio@cern.ch>
- Joachim Flammer <Joachim.Flammer@cern.ch>
- Version info: $Id$
- Release: $Name$
-
- Revision history:
- $Log$
-
--->
-
-<project name="WMS jobid component common properties">
-
- <!-- Include build properties to allow overwriting
- of properties for subsystem -->
- <property file="build.properties" />
-
- <!-- ======================================================
- Define corresponding subsystem properties
- ====================================================== -->
-
- <!-- Subsystem name -->
- <property name="subsystem.name" value="${wms.subsystem.name}"/>
-
- <!-- Subsystem prefix -->
- <property name="subsystem.prefix" value="${wms.subsystem.prefix}"/>
-
- <!-- ======================================================
- Define component properties
- ====================================================== -->
-
- <!-- Component name prefix -->
- <property name="component.prefix" value="jobid" />
-
- <!-- ======================================================
- Define general component properties
- ====================================================== -->
-
- <import file="${component.general.properties.file}" />
-
- <!-- ======================================================
- Define extra properties here ...
- ====================================================== -->
-
-
-</project>
+++ /dev/null
-module.version=0.0.0
-module.build=0
-module.age=0
\ No newline at end of file
+++ /dev/null
-## *********************************************************************
-## *
-## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid.
-## * For license conditions see LICENSE file or
-## * http://www.edg.org/license.html
-## *
-## *********************************************************************
-
-## Subdirectories list
-SUBDIRS = jobid
-
-MAINTAINERCLEANFILES = Makefile.in
+++ /dev/null
-/* **************************************************************************
- * filename : JobId.cpp
- * author : Alessandro Maraschini <alessandro.maraschini@datamat.it>
- * copyright : (C) 2002 by DATAMAT
- ***************************************************************************/
-
-#include "JobId.h"
-
-#include <iostream>
-
-#include "JobIdExceptions.h"
-
-namespace glite {
-namespace wms {
-namespace jobid {
-
-using namespace std ;
-
-/******************************************************************
- Constructor / Destructor
- *******************************************************************/
-JobId::JobId() : m_JobId( 0 ), m_pStr( 0 ), m_pBkserver( 0 ), m_pUnique( 0 )
-{
-}
-
-JobId::JobId(const std::string& job_id_string )
- : m_JobId( 0 ), m_pStr( 0 ), m_pBkserver( 0 ), m_pUnique( 0 )
-{
- fromString( job_id_string ) ;
-}
-
-JobId::JobId(const JobId &old)
-{
- edg_wlc_JobIdDup(old.m_JobId,&m_JobId);
- m_pStr = old.m_pStr ? strdup(old.m_pStr) : 0;
- m_pBkserver = old.m_pBkserver ? strdup(old.m_pBkserver) : 0;
- m_pUnique = old.m_pUnique ? strdup(old.m_pUnique) : 0;
-}
-
-JobId & JobId::operator=(JobId const &old)
-{
- clear();
- edg_wlc_JobIdDup(old.m_JobId,&m_JobId);
- m_pStr = old.m_pStr ? strdup(old.m_pStr) : 0;
- m_pBkserver = old.m_pBkserver ? strdup(old.m_pBkserver) : 0;
- m_pUnique = old.m_pUnique ? strdup(old.m_pUnique) : 0;
-
- return *this;
-}
-
-
-JobId::JobId(const edg_wlc_JobId &old)
- : m_pStr(0), m_pBkserver(0), m_pUnique(0)
-{
- edg_wlc_JobIdDup(old,&m_JobId);
-}
-
-
-JobId & JobId::operator=(const edg_wlc_JobId &old)
-{
- clear();
- edg_wlc_JobIdDup(old,&m_JobId);
- m_pStr = 0;
- m_pBkserver = 0;
- m_pUnique = 0;
- return(*this);
-}
-
-JobId::~JobId()
-{
- clear();
-}
-
-/******************************************************************
- method : clear
- unsets the JobId instance.
- *******************************************************************/
-void JobId::clear()
-{
- if ( m_JobId )
- {
- edg_wlc_JobIdFree( m_JobId );
- m_JobId = 0;
- if (m_pStr)
- free(m_pStr);
- if (m_pBkserver)
- free(m_pBkserver);
- if (m_pUnique)
- free(m_pUnique);
- m_pStr = m_pBkserver = m_pUnique = NULL;
- }
-}
-
-
-/******************************************************************
- method : setJobId
- sets the JobId instance according to the LB and RB
- server addresses and the unique string passed as input parameters.
- *******************************************************************/
-void JobId::setJobId(const string& bkserver, int port, const string& unique)
-{
- int code = edg_wlc_JobIdRecreate(bkserver.c_str(), port, unique.size() ? unique.c_str() : NULL, &m_JobId) ;
- if ( code != 0 )
- throw WrongIdException(__FILE__ , __LINE__ , "setJobId(const string& bkserver, int port, const string& unique)" , code ) ;
-}
-
-
-/******************************************************************
- Protected method : fromString
- sets the JobId instance from the dg_jobId in string format given as input.
- *******************************************************************/
-void JobId::fromString (const string& dg_JobId)
-{
- clear();
- int code = edg_wlc_JobIdParse(dg_JobId.c_str(), &m_JobId) ;
- if ( code != 0 )
- throw WrongIdException(__FILE__ , __LINE__ , "fromString (const string& dg_JobId)" , code ) ;
-}
-
-/******************************************************************
- method : ToString
- converts the JobId instance into its string format.
- and put it in the dg_jobId output variable
- *******************************************************************/
-std::string JobId::toString() const
-{
- if ( m_JobId && !m_pStr )
- m_pStr = edg_wlc_JobIdUnparse(m_JobId) ;
- if ( !m_pStr )
- throw EmptyIdException (__FILE__ , __LINE__ ,"toString()" ,ENOENT , "JobId") ;
- return m_pStr;
-}
-
-/******************************************************************
- method : getServer
- return a string containing the LB server address,
- *******************************************************************/
-std::string JobId::getServer() const
-{
- if ( m_JobId && !m_pBkserver )
- m_pBkserver = edg_wlc_JobIdGetServer( m_JobId ) ;
-
- if ( !m_pBkserver )
- throw EmptyIdException (__FILE__ , __LINE__ , "getServer()", ENOENT , "LB server Address") ;
-
- return m_pBkserver;
-}
-
-/******************************************************************
- method : getUnique
- return a string containing unique jobid string
- *******************************************************************/
-std::string JobId::getUnique() const
-{
- if ( m_JobId && !m_pUnique )
- m_pUnique = edg_wlc_JobIdGetUnique( m_JobId ) ;
-
- if ( !m_pUnique )
- throw EmptyIdException (__FILE__ , __LINE__ , "getUnique()" , ENOENT , "Unique") ;
-
- return m_pUnique;
-}
-/******************************************************************
- method : getId
- return the c JobId struct representing this instance
- *******************************************************************/
-edg_wlc_JobId JobId::getId() const
-{
- edg_wlc_JobId out ;
- if ( edg_wlc_JobIdDup(m_JobId, &out) )
- throw EmptyIdException (__FILE__ , __LINE__ , "getId()" , ENOENT , "JobId") ;
- return out ;
-}
-
-std::ostream&
-operator<<(std::ostream& os, JobId const& id)
-{
- return os << id.toString();
-}
-
-} // namespace jobid
-} // namespace wms
-} // namespace glite
+++ /dev/null
-#ifndef GLITE_WMS_JOBID_JOBID_H
-#define GLITE_WMS_JOBID_JOBID_H
-
-/*
- * JobId.h
- * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved.
- *
- */
-
-#include <string>
-#include <iosfwd>
-
-#include "cjobid.h"
-
-typedef struct _edg_wlc_jobid_s* edg_wlc_jobid_t;
-
-namespace glite {
-namespace wms {
-namespace jobid {
-
-/**
- * Managing Identification, checking, retreiving info from a job
- * File name: JobId.h
- * The JobId class provides a representation of the Datagrid job identifier
- * (dg_jobId) and the methods for manipulating it.
- * We remind that the format of the dg_jobId is as follows:
- * <LB address>:<LB port>/<Unique String>
- *
- * @ingroup common
- * @version 0.1
- * @date 15 April 2002
- * @author Alessandro Maraschini <alessandro.maraschini@datamat.it> */
-
-class JobId {
-public:
- /**@name Constructors/Destructor */
- //@{
- /** Instantiates an empty JobId object */
- JobId() ;
- /**
- * Instantiates a JobId object from the passed dg_jobId in string format.
- * @param job_id_string a string representig a classAd expression
- * @throws WrongIdException When a string is passed in a wrong format
- */
- JobId(const std::string& job_id_string ) ;
- JobId(const JobId&);
- JobId(const edg_wlc_JobId&);
- /**
- * Destructor
- * Destroy the Job Id instance
- */
- ~JobId() ;
- //@}
-
- /**@name Miscellaneous */
- //@{
- /** Unsets the JobId instance. Clear all it's memebers */
- void clear() ;
- /**
- * Check wheater the jobId has been already created (true) or not (false)
- *@return true (jobId created) or false (jobId not yet created)
- */
- bool isSet() { return ( m_JobId != 0 ) ; }
- /**
- * Set the JobId instance according to the LB and RB server addresses and the unique string passed as input parameters.
- * @param lb_server Loggin and Bookkeeping server address
- * @param port Loggin and Bookkeeping port ( dafault value is 9000 )
- * @param unique A Unique identification ( automatically generatad by md5 protocol )
- * @throws WrongIdException When one parameter has been passed in a wrong format */
- void setJobId(const std::string& lb_server, int port = 0, const std::string& unique = "");
- //@}
- /**@name Get Methods */
- //@{
- /** @return the LB address into its string format
- * @throws EmptyIdException If the jobId has not been initialised yet */
- std::string getServer() const;
- /** @return the Unique string into its string format
- * @throws EmptyIdException If the jobId has not been initialised yet */
- std::string getUnique() const;
- //@}
- /** This method sets the JobId instance from the JobId in string format given
- * as input.
- * @param dg_JobId the string representing the job
- * @throws WrongIdException When a string is passed in a wrong format */
- void fromString ( const std::string& dg_JobId );
- /** Converts the jobId into a string
- @return the string representation of a JobId*/
- std::string toString() const;
- operator const edg_wlc_JobId() const { return m_JobId; }
- JobId & operator=(JobId const &);
- JobId & operator=(const edg_wlc_JobId &);
- edg_wlc_JobId getId() const ;
-private:
- // This Variable stores the Job unique identification String
- edg_wlc_JobId m_JobId;
- mutable char* m_pStr;
- mutable char* m_pBkserver;
- mutable char* m_pUnique;
-
- friend bool operator<(JobId const& lhs, JobId const& rhs);
- friend bool operator==(JobId const& lhs, JobId const& rhs);
-};
-
-inline bool operator<(JobId const& lhs, JobId const& rhs)
-{
- return strcmp ( lhs.m_pStr , rhs.m_pStr ) <0 ;
-}
-
-inline bool operator==(JobId const& lhs, JobId const& rhs)
-{
-return strcmp ( lhs.m_pStr , rhs.m_pStr ) ==0 ;
-}
-
-std::ostream& operator<<(std::ostream& os, JobId const& id);
-
-} // namespace jobid
-} // namespace wms
-} // namespace glite
-
-#endif // GLITE_WMS_JOBID_JOBID_H
+++ /dev/null
-/* **************************************************************************
-* filename : JobIdExecptions.cpp
-* author : Alessandro Maraschini <alessandro.maraschini@datamat.it>
-* copyright : (C) 2002 by DATAMAT
-***************************************************************************/
-
-#include "JobIdExceptions.h"
-
-namespace glite {
-namespace wms {
-namespace jobid {
-
-using namespace std;
-using namespace glite::wms::common::utilities;
-
-/*****************************
-* JobIdException
-*****************************/
-JobIdException::JobIdException (const string& file,
- int line,
- const string& method,
- int code,
- const string& exception_name)
- : Exception(file, line, method, code, exception_name)
-{
-}
-
-/*****************************
-* WrongIdException
-*****************************/
-WrongIdException::WrongIdException(const string& file,
- int line,
- const string& method,
- int code )
- : JobIdException(file, line, method, code,
- "WrongIdException")
-{
- error_message = "Wrong Field caught while parsing Job Id" ;
-}
-
-/*****************************
-* EmptyIdException
-*****************************/
-EmptyIdException::EmptyIdException(const string& file,
- int line,
- const string& method,
- int code ,
- const string& field )
- : JobIdException(file, line, method, code,
- "EmptyIdException")
-{
- error_message = "Unable to retrieve " + field + ": the instance has not been initialized yet";
-}
-
-} // namespace jobid
-} // namespace wms
-} // namespace glite
-
+++ /dev/null
-#ifndef GLITE_WMS_JOBID_EXCEPTIONS_H
-#define GLITE_WMS_JOBID_EXCEPTIONS_H
-
-/*
- * JobIdExceptions.h
- * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved.
- */
-
-#include "glite/wms/common/utilities/Exceptions.h"
-
-namespace glite {
-namespace wms {
-namespace jobid {
-
-/**
- * JobIdException - Exception thrown by JobId Class
- * @ingroup Common
- * @version 0.1
- * @date 15 April 2002
- * @author Alessandro Maraschini <alessandro.maraschini@datamat.it>
-*/
-
-class JobIdException : public glite::wms::common::utilities::Exception {
-public:
- /**
- * Update all mandatory Exception Information
- */
- JobIdException (const std::string& file,
- int line,
- const std::string& method,
- int code,
- const std::string& exception_name) ;
-};//End CLass JobIdException
-
-/**
-* WrongIdFieldException
-* This Exception is thrown when a Job Id syntax error is found
-* A valid Job Identification string should be made as follows:
-* <LB address>:<LB port>/ <Unique string> */
-class WrongIdException : public JobIdException {
-public:
- /**
- * Constructor
- * @param file - The source file which has generated the Exception
- * @param line - The line number in the source file where the Exception has been thrown
- * @param method - The Name of the method which has thrown the Exception
- * @param code - The Code of the Error raised
- * @param field - The wrong expression catched */
- WrongIdException(const std::string& file,
- int line,
- const std::string& method,
- int code );
-}; //End CLass WrongIdException
-/**
-* EmptyIdException
-* This Exception is thrown when the user tries to get information from a JobId
-* which has not been initialized yet, i.e tries to use the get<field name> Methods
-*/
-class EmptyIdException : public JobIdException {
-public:
- /**
- * Constructor
- * @param file - The source file which has generated the Exception
- * @param line - The line number in the source file where the Exception has been thrown
- * @param method - The Name of the method which has thrown the Exception
- * @param code - The Code of the Error raised
- * @param field - The Empty filed requested for */
- EmptyIdException::EmptyIdException(const std::string& file,
- int line,
- const std::string& method,
- int code ,
- const std::string& field );
-}; //End CLass EmptyIdException
-
-} // namespace jobid
-} // namespace wms
-} // namespace glite
-
-#endif // GLITE_WMS_JOBID_EXCEPTIONS_H
-
+++ /dev/null
-## *********************************************************************
-## *
-## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid.
-## * For license conditions see LICENSE file or
-## * http://www.edg.org/license.html
-## *
-## *********************************************************************
-
-lib_LTLIBRARIES = libglite_wms_jobid.la libglite_wms_cjobid.la
-
-libglite_wms_jobid_la_SOURCES = \
- JobId.cpp \
- JobIdExceptions.cpp \
- manipulation.cpp
-
-libglite_wms_cjobid_la_SOURCES = \
- cjobid.c \
- strmd5.c
-
-jobidincludedir = $(includedir)/glite/wms/jobid
-jobidinclude_HEADERS = \
- JobId.h \
- JobIdExceptions.h \
- cjobid.h \
- manipulation.h \
- strmd5.h
-
-AM_CPPFLAGS = -I$(top_srcdir)/src \
- $(GLITE_CFLAGS) \
- -D_GNU_SOURCE
-
-MAINTAINERCLEANFILES = Makefile.in
+++ /dev/null
-#ident "$Header$"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include <netdb.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-#include "cjobid.h"
-#include "strmd5.h"
-
-struct _edg_wlc_JobId {
- char *id; /* unique job identification */
- /* additional information */
- char *BShost;/* bookkeeping server hostname */
- unsigned int BSport; /* bookkeeping server port */
- char *info; /* additional information (after ? in URI) */
-};
-
-int edg_wlc_JobIdCreate(const char *bkserver, int port, edg_wlc_JobId *jobId)
-{
- return edg_wlc_JobIdRecreate(bkserver, port, NULL, jobId);
-}
-
-
-int edg_wlc_JobIdRecreate(const char* bkserver, int port, const char *unique, edg_wlc_JobId *jobId)
-{
- edg_wlc_JobId out;
- char hostname[200]; /* used to hold string for encrypt */
- struct timeval tv;
- int skip;
- char* portbeg;
-
- struct hostent* he;
-
- if (!bkserver)
- return EINVAL;
-
- if (unique == NULL) {
- gethostname(hostname, 100);
- he = gethostbyname(hostname);
- assert(he->h_length > 0);
- gettimeofday(&tv, NULL);
- srandom(tv.tv_usec);
-
- skip = strlen(hostname);
- skip += sprintf(hostname + skip, "-IP:0x%x-pid:%d-rnd:%d-time:%d:%d",
- *((int*)he->h_addr_list[0]), getpid(), (int)random(),
- (int)tv.tv_sec, (int)tv.tv_usec);
- }
-
- *jobId = NULL;
- out = (edg_wlc_JobId) malloc (sizeof(*out));
- if (!out)
- return ENOMEM;
-
- memset(out, 0, sizeof(*out));
-
- /* check if it begins with prefix */
- /* unsupported */
- if (strncmp(bkserver, GLITE_WMSC_JOBID_PROTO_PREFIX, sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX)-1) == 0)
- return EINVAL;
-
- out->BShost = strdup(bkserver);
- portbeg = strchr(out->BShost, ':');
- if (portbeg) {
- *portbeg = 0;
- /* try to get port number */
- if (port == 0)
- port = atoi(portbeg + 1);
- }
-
- if (port == 0)
- port = GLITE_WMSC_JOBID_DEFAULT_PORT;
-
- out->BSport = port;
-
- out->id = (unique) ? strdup(unique) : str2md5base64(hostname);
- //printf("Encrypt: %s\nBASE64 %s\n", hostname, out->id);
-
- if (!out->id || !out->BShost) {
- edg_wlc_JobIdFree(out);
- return ENOMEM;
- }
-
- *jobId = out;
- return 0;
-}
-
-
-int edg_wlc_JobIdDup(const edg_wlc_JobId in, edg_wlc_JobId *out)
-{
- edg_wlc_JobId jid;
- *out = NULL;
- if (in == NULL)
- return 0;
-
- jid = malloc(sizeof(*jid));
- if (!jid)
- return ENOMEM;
-
- memset(jid, 0,sizeof(*jid));
- jid->BShost = strdup(in->BShost);
- jid->id = strdup(in->id);
- if (in->info)
- jid->info = strdup(in->info);
-
- if (jid->BShost == NULL || jid->id == NULL) {
- edg_wlc_JobIdFree(jid);
- return ENOMEM;
- }
-
- jid->BSport = in->BSport;
- *out = jid;
- return 0;
-}
-
-
-// XXX
-// use recreate
-// parse name, port, unique
-int edg_wlc_JobIdParse(const char *idString, edg_wlc_JobId *jobId)
-{
- char *pom, *pom1, *pom2;
- edg_wlc_JobId out;
-
- *jobId = NULL;
-
- out = (edg_wlc_JobId) malloc (sizeof(*out));
- if (out == NULL )
- return ENOMEM;
-
- memset(out,0,sizeof(*out));
-
- if (strncmp(idString, GLITE_WMSC_JOBID_PROTO_PREFIX, sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX) - 1)) {
- out->BShost = (char *) NULL;
- out->BSport = 0;
-
- free(out);
- return EINVAL;
- }
-
- pom = strdup(idString + sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX) - 1);
- pom1 = strchr(pom, '/');
- pom2 = strchr(pom, ':');
-
- if (!pom1) { free(pom); free(out); return EINVAL; }
-
- if ( pom2 && (pom1 > pom2)) {
- pom[pom2-pom] = '\0';
- out->BShost = strdup(pom);
- pom[pom1-pom] = '\0';
- out->BSport = (unsigned int) strtoul(pom2 + 1,NULL,10);
- } else {
- pom[pom1-pom] = '\0';
- out->BShost = strdup(pom);
- out->BSport = GLITE_WMSC_JOBID_DEFAULT_PORT;
- }
-
- /* XXX: localhost not supported in jobid
- if (!strncmp(out->BShost,"localhost",9) {
- free(pom);
- free(out->BShost);
- free(out);
- return EINVAL;
- }
- */
-
- /* additional info from URI */
- pom2 = strchr(pom1+1,'?');
- if (pom2) {
- *pom2 = 0;
- out->info = strdup(pom2+1);
- }
-
- /* extract the unique part */
- out->id = strdup(pom1+1);
-
- for (pom1 = out->BShost; *pom1; pom1++)
- if (isspace(*pom1)) break;
-
- for (pom2 = out->id; *pom2; pom2++)
- if (isspace(*pom2)) break;
-
- if (*pom1 || *pom2) {
- free(pom);
- edg_wlc_JobIdFree(out);
- return EINVAL;
- }
-
- free(pom);
- *jobId = out;
- return 0;
-}
-
-
-void edg_wlc_JobIdFree(edg_wlc_JobId job)
-{
- if (job) {
- free(job->id);
- free(job->BShost);
- free(job->info);
- free(job);
- }
-}
-
-
-char* edg_wlc_JobIdUnparse(const edg_wlc_JobId jobid)
-{
- char *out, port[40];
-
- if (!jobid)
- return NULL;
-
- if (jobid->BSport)
- sprintf(port,":%d",jobid->BSport);
- else
- *port = 0;
-
- asprintf(&out, GLITE_WMSC_JOBID_PROTO_PREFIX"%s%s/%s%s%s",
- jobid->BShost,port,
- jobid->id,
- (jobid->info ? "?" : ""),
- (jobid->info ? jobid->info : ""));
-
- return out;
-}
-
-
-char* edg_wlc_JobIdGetServer(const edg_wlc_JobId jobid)
-{
- char *bs = NULL;
-
- if (jobid)
- asprintf(&bs, "%s:%u", jobid->BShost,
- jobid->BSport ? jobid->BSport : GLITE_WMSC_JOBID_DEFAULT_PORT);
-
- return bs;
-}
-
-
-void edg_wlc_JobIdGetServerParts(const edg_wlc_JobId jobid, char **srvName, unsigned int *srvPort)
-{
- if (jobid) {
- *srvName = strdup(jobid->BShost);
- *srvPort = jobid->BSport ? jobid->BSport : GLITE_WMSC_JOBID_DEFAULT_PORT;
- }
-}
-
-
-char* edg_wlc_JobIdGetUnique(const edg_wlc_JobId jobid)
-{
- return jobid ? strdup(jobid->id) : NULL;
-}
+++ /dev/null
-#ifndef _GLITE_JOBID_H
-#define _GLITE_JOBID_H
-
-/*!
- * \file cjobid.h
- * \brief L&B consumer API
- */
-
-#ident "$Header$"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct _edg_wlc_JobId *edg_wlc_JobId;
-
-#define GLITE_WMSC_JOBID_DEFAULT_PORT 9000 /**< Default port where bookkeeping server listens */
-#define GLITE_WMSC_JOBID_PROTO_PREFIX "https://" /**< JobId protocol prefix */
-
-
-/* All the pointer functions return malloc'ed objects (or NULL on error) */
-
-/**
- * Create a Job ID.
- * See the lb_draft document for details on its construction and components
- * \param bkserver book keeping server hostname
- * \param port port for the bk service
- * \param jobid new created job id
- * \ret al 0 success
- * \retval EINVAL invalid bkserver
- * \retval ENOMEM if memory allocation fails
- */
-int edg_wlc_JobIdCreate(const char * bkserver, int port, edg_wlc_JobId * jobid);
-
-/**
- * Recreate a Job ID
- * \param bkserver bookkeeping server hostname
- * \param port port for the bk service
- * \param unique string which represent created jobid (if NULL then new
- * one is created)
- * \param jobid new created job id
- * \retval 0 success
- * \retval EINVAL invalid bkserver
- * \retval ENOMEM if memory allocation fails
- */
-int edg_wlc_JobIdRecreate(const char *bkserver, int port, const char * unique, edg_wlc_JobId * jobid);
-
-/**
- * Create copy of Job ID
- * \param in jobid for duplication
- * \param jobid duplicated jobid
- * \retval 0 for success
- * \retval EINVAL invalid jobid
- * \retval ENOMEM if memory allocation fails
- */
-int edg_wlc_JobIdDup(const edg_wlc_JobId in, edg_wlc_JobId * jobid);
-
-/*
- * Free jobid structure
- * \param jobid for dealocation
- */
-void edg_wlc_JobIdFree(edg_wlc_JobId jobid);
-
-/**
- * Parse Job ID string and creates jobid structure
- * \param jobidstr string representation of jobid
- * \param jobid parsed job id
- * \retval 0 for success
- * \retval EINVAL jobidstr can't be parsed
- * \retval ENOMEM if memory allocation fails
- */
-int edg_wlc_JobIdParse(const char* jobidstr, edg_wlc_JobId * jobid);
-
-/**
- * Unparse Job ID (produce the string form of JobId).
- * \param jobid to be converted to string
- * \return allocated string which represents jobid
- */
-char* edg_wlc_JobIdUnparse(const edg_wlc_JobId jobid);
-
-/**
- * Extract bookkeeping server address (address:port)
- * \param jobid from which the bkserver address should be extracted
- * \retval pointer to allocated string with bkserver address
- * \retval NULL if jobid is 0 or memory allocation fails
- */
-char* edg_wlc_JobIdGetServer(const edg_wlc_JobId jobid);
-
-/**
- * Extract bookkeeping server address and port
- * \param jobid from which the bkserver address should be extracted
- * \param srvName pointer where to return server name
- * \param srvPort pointer where to return server port
- * */
-void edg_wlc_JobIdGetServerParts(const edg_wlc_JobId jobid, char **srvName, unsigned int *srvPort);
-
-/**
- * Extract unique string
- * \param jobid
- * \retval pointer to allocated unique string representing jobid
- * \retval NULL if jobid is 0 or memory allocation fails
- */
-char* edg_wlc_JobIdGetUnique(const edg_wlc_JobId jobid);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _GLITE_JOBID_H */
+++ /dev/null
-#include <cctype>
-
-#include <string>
-#include <algorithm>
-
-#include "JobId.h"
-
-using namespace std;
-
-namespace glite {
-namespace wms {
-namespace jobid {
-
-namespace {
-
-class HexInt {
-public:
- HexInt( unsigned int i = 0 );
- HexInt( const string &str );
- HexInt( string::const_iterator begin, string::const_iterator end );
- ~HexInt( void );
-
- inline operator unsigned int( void ) const { return this->hi_int; }
- inline operator const string &( void ) const { return this->hi_str; }
-
- static unsigned int least( void ) { return hi_s_least; }
- static void least( unsigned int least ) { hi_s_least = least; }
-
-private:
- void parseString( void );
-
- unsigned int hi_int;
- string hi_str;
-
- static unsigned int hi_s_least;
- static const char *hi_s_map;
-};
-
-class BadChar {
-public:
- BadChar( void );
- ~BadChar( void );
-
- inline bool operator()( char c )
- { return( !(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9')) ||
- (c == '.') || (c == '-') || (c == ' ')) ); }
-};
-
-unsigned int HexInt::hi_s_least = 2;
-const char *HexInt::hi_s_map = "0123456789abcdef";
-
-HexInt::HexInt( unsigned int ui ) : hi_int( ui ), hi_str( hi_s_least, '0' )
-{
- int n;
- string::reverse_iterator pos = this->hi_str.rbegin();
-
- while( ui != 0 ) {
- n = ui % 16;
- if( pos != this->hi_str.rend() ) {
- *pos = hi_s_map[n];
- pos += 1;
- }
- else this->hi_str.insert( this->hi_str.begin(), hi_s_map[n] );
-
- ui /= 16;
- }
-
- if( this->hi_str.length() < hi_s_least )
- this->hi_str.insert( this->hi_str.begin(), (hi_s_least - this->hi_str.length()), '0' );
-}
-
-HexInt::HexInt( const string &str ) : hi_int( 0 ), hi_str( str )
-{
- this->parseString();
-}
-
-HexInt::HexInt( string::const_iterator begin, string::const_iterator end ) : hi_int( 0 ), hi_str( begin, end )
-{
- this->parseString();
-}
-
-void HexInt::parseString( void )
-{
- int hexbase;
- char *pos, *end = (char *) hi_s_map + 16;
- string::reverse_iterator it;
-
- for( it = this->hi_str.rbegin(), hexbase = 1; it != this->hi_str.rend(); ++it, hexbase *= 16 ) {
- pos = find( (char *) hi_s_map, end, (char) tolower(*it) );
-
- if( pos != end ) this->hi_int += hexbase * (pos - hi_s_map);
- else {
- this->hi_int = 0;
- break;
- }
- }
-
- return;
-}
-
-HexInt::~HexInt( void ) {}
-
-BadChar::BadChar( void ) {}
-
-BadChar::~BadChar( void ) {}
-
-/*
- Helper function for the get_reduced_part(...)
-*/
-string get_reduced_part_internal( const string &unique, int level )
-{
- string::size_type length = unique.length();
- string piece( unique.substr(0, 2) ), answer;
-
- if( (level == 0) || (length <= 2) ) answer.assign( piece );
- else if( length != 0 ) {
- answer.assign( piece );
- answer.append( 1, '/' );
- answer.append( get_reduced_part_internal(unique.substr(2, length - 2), level - 1) );
- }
-
- return answer;
-}
-
-}; // Unnamed namespace
-
-string get_reduced_part( const JobId &id, int level )
-{
- return get_reduced_part_internal( id.getUnique(), level );
-}
-
-string to_filename( const JobId &id )
-{
- string sid( id.toString() ), coded;
- string::iterator last, next;
-
- last = sid.begin();
- do {
- next = find_if( last, sid.end(), BadChar() );
-
- if( next != sid.end() ) {
- if( last != next ) coded.append( last, next );
- coded.append( 1, '_' );
- coded.append( HexInt(*next) );
-
- last = next + 1;
- }
- else coded.append( last, sid.end() );
- } while( next != sid.end() );
-
- return coded;
-}
-
-JobId from_filename( const string &filename )
-{
- char c;
- string decoded;
- string::const_iterator last, next;
-
- last = filename.begin();
- do {
- next = find( last, filename.end(), '_' );
-
- if( next != filename.end() ) {
- c = HexInt( next + 1, next + 3 );
-
- if( last != next ) decoded.append( last, next );
- decoded.append( 1, c );
-
- last = next + 3;
- }
- else decoded.append( last, filename.end() );
- } while( next != filename.end() );
-
- return JobId( decoded );
-}
-
-} // namespace jobid
-} // namespace wms
-} // namespace glite
+++ /dev/null
-#ifndef GLITE_WMS_JOBID_MANIPULATION_H
-#define GLITE_WMS_JOBID_MANIPULATION_H
-
-#include <string>
-
-namespace glite {
-namespace wms {
-namespace jobid {
-
-class JobId;
-
-std::string get_reduced_part( const JobId &id, int level = 0 );
-std::string to_filename( const JobId &id );
-JobId from_filename( const std::string &filename );
-
-} // namespace jobid
-} // namespace wms
-} // namespace glite
-
-#endif /* GLITE_WMS_JOBID_MANIPULATION_H */
-
-// Local Variables:
-// mode: c++
-// End:
+++ /dev/null
-#ident "$Header$"
-
-#include <openssl/md5.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "jobid/strmd5.h"
-
-#warning Thread unsafe!
-static char mbuf[33];
-
-static int base64_encode(const void *enc, int enc_size, char *out, int out_max_size)
-{
- static const char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
-
- unsigned char* enc_buf = (unsigned char*)enc;
- int out_size = 0;
- unsigned int bits = 0;
- unsigned int shift = 0;
-
- while ( out_size < out_max_size ) {
- if ( enc_size>0 ) {
- // Shift in byte
- bits <<= 8;
- bits |= *enc_buf;
- shift += 8;
- // Next byte
- enc_buf++;
- enc_size--;
- } else if ( shift>0 ) {
- // Pad last bits to 6 bits - will end next loop
- bits <<= 6 - shift;
- shift = 6;
- } else {
- // Terminate with Mime style '='
- *out = '=';
- out_size++;
-
- return out_size;
- }
-
- // Encode 6 bit segments
- while ( shift>=6 ) {
- shift -= 6;
- *out = b64[ (bits >> shift) & 0x3F ];
- out++;
- out_size++;
- }
- }
-
- // Output overflow
- return -1;
-}
-
-char *strmd5(const char *s, unsigned char *digest)
-{
- MD5_CTX md5;
- unsigned char d[16];
- int i;
-
- MD5_Init(&md5);
- MD5_Update(&md5,s,strlen(s));
- MD5_Final(d,&md5);
-
- if (digest) memcpy(digest,d,sizeof(d));
-
- for (i=0; i<16; i++) {
- int dd = d[i] & 0x0f;
- mbuf[2*i+1] = dd<10 ? dd+'0' : dd-10+'a';
- dd = d[i] >> 4;
- mbuf[2*i] = dd<10 ? dd+'0' : dd-10+'a';
- }
- mbuf[32] = 0;
- return (char *) mbuf;
-}
-
-char *str2md5(const char *s)
-{
- MD5_CTX md5;
- unsigned char d[16];
- char* ret = malloc(33);
- int i;
-
- if (!ret)
- return NULL;
-
- MD5_Init(&md5);
- MD5_Update(&md5, s, strlen(s));
- MD5_Final(d, &md5);
-
- for (i=0; i<16; i++) {
- int dd = d[i] & 0x0f;
- ret[2*i+1] = dd<10 ? dd+'0' : dd-10+'a';
- dd = d[i] >> 4;
- ret[2*i] = dd<10 ? dd+'0' : dd-10+'a';
- }
- ret[32] = 0;
- return ret;
-}
-
-char *str2md5base64(const char *s)
-{
- MD5_CTX md5;
- unsigned char d[16];
- char buf[50];
- int l;
-
- MD5_Init(&md5);
- MD5_Update(&md5, s, strlen(s));
- MD5_Final(d, &md5);
-
- l = base64_encode(d, 16, buf, sizeof(buf) - 1);
- if (l < 1)
- return NULL;
- buf[l - 1] = 0;
- return strdup(buf);
-}
+++ /dev/null
-#ifndef _GLITE_STRMD5_H
-#define _GLITE_STRMD5_H
-
-#ident "$Header$"
-
-/* Compute MD5 sum of the first argument.
- * The sum is returned in the 16-byte array pointed to by 2nd argument
- * (if not NULL)
- *
- * Return value: ASCII string of the sum, i.e. 32 characters [0-9a-f]
- * (pointer to static area, changed by subsequent calls)
- */
-
-char *strmd5(const char *src, unsigned char *dst);
-
-/**
- * Returns: allocated 32bytes long ASCII string with md5 sum
- * of the first argument
- */
-char *str2md5(const char *src);
-
-/**
- * Returns: allocated 22bytes long ASCII string with md5 sum in base64
- * format of the source argument
- */
-char *str2md5base64(const char *src);
-
-#endif /* _GLITE_STRMD5_H */
+++ /dev/null
-## *********************************************************************
-## *
-## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid.
-## * For license conditions see LICENSE file or
-## * http://www.edg.org/license.html
-## *
-## *********************************************************************
-
-STDCPP = -lstdc++
-
-JOBID = $(top_builddir)/src/jobid/libglite_wms_cjobid.la
-
-check_PROGRAMS = testjobid
-
-testjobid_SOURCES = testjobid.c
-testjobid_LDADD = \
- $(JOBID) \
- $(GLITE_WMS_COMMON_UT_EXCEPTIONS_LIBS) \
- $(GLOBUS_SSL_THR_LIBS) \
- $(STDCPP)
-
-AM_CPPFLAGS = -I$(top_srcdir)/src \
- $(GLITE_CFLAGS) \
- $(GLITE_THR_CFLAGS)
-
-MAINTAINERCLEANFILES = Makefile.in *~
-
+++ /dev/null
-/* test code for jobid routines */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "jobid/cjobid.h"
-
-int main(int argc, char* argv[])
-{
- char* ju;
- char* bkserver = "ujsa.uhjs";
-
- edg_wlc_JobId ji = 0;
- edg_wlc_JobId ji2 = 0;
-
- int r = edg_wlc_JobIdCreate(bkserver, 0, &ji);
- printf("Create: %d\n", r);
-
- ju = edg_wlc_JobIdUnparse(ji);
- printf("Unparse: %s\n", ju);
-
- edg_wlc_JobIdParse(ju, &ji2);
- free(ju);
-
- ju = edg_wlc_JobIdUnparse(ji);
- printf("Unparse2: %s\n", ju);
- free(ju);
-
- edg_wlc_JobIdFree(ji);
- edg_wlc_JobIdFree(ji2);
-
- return 0;
-}