From ecacee4cdb74f07caf0edea7fd4bfb30ac55146f Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Mon, 13 Jun 2005 10:01:40 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create tag 'merge_shallow_src'. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Sprout from master 2005-05-19 11:16:52 UTC Aleš Křenek 'Incremented build number [GLBUILDER]' Cherrypick from glite-lb-client_branch_1_2_1_2 2005-06-09 09:52:18 UTC Miloš Mulač 'use inter-scripts variables': org.glite.lb.client/examples/gen_sample_job org.glite.lb.client/examples/job_status.c org.glite.lb.client/examples/ready.l org.glite.lb.client/examples/resubmission.l org.glite.lb.client/examples/resubmitted.l org.glite.lb.client/examples/running.l org.glite.lb.client/examples/shallow_and_full_resub.l org.glite.lb.client/examples/shallow_resub_complex.l org.glite.lb.client/examples/shallow_resub_simple.l org.glite.lb.client/examples/shallow_resub_simple2.l Cherrypick from glite-lb-server_branch_1_2_4_2 2005-06-13 10:01:39 UTC Miloš Mulač 'add forgotten header files to shallow res. branch': org.glite.lb.server/Makefile org.glite.lb.server/interface/index.h org.glite.lb.server/interface/lb_authz.h org.glite.lb.server/interface/lbs_db.h org.glite.lb.server/interface/store.h org.glite.lb.server/src/get_events.h org.glite.lb.server/src/jobstat.c org.glite.lb.server/src/jobstat.h org.glite.lb.server/src/jobstat_supp.c org.glite.lb.server/src/lb_xml_parse.c.T Cherrypick from glite-lb_branch_1_1_0_2_SHALLOW 2005-05-19 11:58:52 UTC Aleš Křenek 'event & state definitions for shallow resubmissions': org.glite.lb/project/dependencies.properties org.glite.lb/project/events.T org.glite.lb/project/status.T Cherrypick from glite-lb-common_branch_1_4_0_2 2005-06-03 14:48:17 UTC Miloš Mulač 'support for possible destinations and ce_nodes': org.glite.lb.common/src/xml_parse.c.T Delete: org.glite.deployment.lb/.cvsignore org.glite.deployment.lb/CHANGELOG org.glite.deployment.lb/build.xml org.glite.deployment.lb/config/scripts/glite-lb-config.py org.glite.deployment.lb/config/scripts/remove_all_rpms.sh org.glite.deployment.lb/config/templates/glite-lb.cfg.xml org.glite.deployment.lb/doc/release_notes/release_notes.doc org.glite.deployment.lb/doc/release_notes/release_notes.html org.glite.deployment.lb/doc/release_notes/release_notes.pdf org.glite.deployment.lb/project/.cvsignore org.glite.deployment.lb/project/build.number org.glite.deployment.lb/project/build.properties org.glite.deployment.lb/project/glite-lb.sdf.xml.template org.glite.deployment.lb/project/glite-lb.spec org.glite.deployment.lb/project/lxscript-rpm.xsl org.glite.deployment.lb/project/lxscript-tgz.xsl org.glite.deployment.lb/project/properties.xml org.glite.deployment.lb/project/quattor-template.xsl org.glite.deployment.lb/project/version.properties org.glite.jp.common/.cvsignore org.glite.jp.common/Makefile org.glite.jp.common/build.xml org.glite.jp.common/interface/context.h org.glite.jp.common/interface/strmd5.h org.glite.jp.common/interface/types.h org.glite.jp.common/project/build.number org.glite.jp.common/project/build.properties org.glite.jp.common/project/configure.properties.xml org.glite.jp.common/project/properties.xml org.glite.jp.common/project/tar_exclude org.glite.jp.common/project/version.properties org.glite.jp.common/src/attr.c org.glite.jp.common/src/context.c org.glite.jp.common/src/strmd5.c org.glite.jp.index/.cvsignore org.glite.jp.index/Makefile org.glite.jp.index/build.xml org.glite.jp.index/project/JobProvenanceIS.wsdl org.glite.jp.index/project/build.number org.glite.jp.index/project/build.properties org.glite.jp.index/project/configure.properties.xml org.glite.jp.index/project/properties.xml org.glite.jp.index/project/tar_exclude org.glite.jp.index/project/version.properties org.glite.jp.index/src/simple_server.c org.glite.jp.index/src/soap_ops.c org.glite.jp.index/src/typemap.dat org.glite.jp.primary/.cvsignore org.glite.jp.primary/Makefile org.glite.jp.primary/build.xml org.glite.jp.primary/examples/jpps-test.c org.glite.jp.primary/interface/file_plugin.h org.glite.jp.primary/project/build.number org.glite.jp.primary/project/build.properties org.glite.jp.primary/project/configure.properties.xml org.glite.jp.primary/project/properties.xml org.glite.jp.primary/project/tar_exclude org.glite.jp.primary/project/version.properties org.glite.jp.primary/src/backend.h org.glite.jp.primary/src/bones_server.c org.glite.jp.primary/src/builtin_plugins.h org.glite.jp.primary/src/db.h org.glite.jp.primary/src/feed.c org.glite.jp.primary/src/feed.h org.glite.jp.primary/src/file_plugin.c org.glite.jp.primary/src/ftp_backend.c org.glite.jp.primary/src/is_client.c org.glite.jp.primary/src/jptype_map.h org.glite.jp.primary/src/mysql.c org.glite.jp.primary/src/simple_server.c org.glite.jp.primary/src/soap_ops.c org.glite.jp.primary/src/tags.c org.glite.jp.primary/src/tags.h org.glite.jp.primary/src/tags_plugin.c org.glite.jp.primary/src/typemap.dat org.glite.jp.ws-interface/.cvsignore org.glite.jp.ws-interface/LICENSE org.glite.jp.ws-interface/Makefile org.glite.jp.ws-interface/build.xml org.glite.jp.ws-interface/interface/JobProvenanceIS.wsdl org.glite.jp.ws-interface/project/build.number org.glite.jp.ws-interface/project/build.properties org.glite.jp.ws-interface/project/configure.properties.xml org.glite.jp.ws-interface/project/glite-jp-ws-interface.spec org.glite.jp.ws-interface/project/properties.xml org.glite.jp.ws-interface/project/tar_exclude org.glite.jp.ws-interface/project/version.properties org.glite.jp.ws-interface/src/JobProvenancePS.xml org.glite.jp.ws-interface/src/JobProvenanceTypes.xml org.glite.jp.ws-interface/src/puke-wsdl.xsl org.glite.jp/.cvsignore org.glite.jp/build.xml org.glite.jp/project/build.number org.glite.jp/project/build.properties org.glite.jp/project/dependencies.properties org.glite.jp/project/glite.jp.csf.xml org.glite.jp/project/properties.xml org.glite.jp/project/run-workspace org.glite.jp/project/taskdefs.xml org.glite.jp/project/version.properties org.glite.lb.proxy/project/MultiStruct.pm org.glite.lb.proxy/project/StructField.pm org.glite.lb.proxy/project/at3 org.glite.lb.proxy/project/events.T org.glite.lb.proxy/project/status.T org.glite.lb.proxy/project/types.T org.glite.lb.ws-interface/interface/LB.wsdl org.glite.security.gsoap-plugin/LICENSE org.glite.security.gsoap-plugin/Makefile org.glite.security.gsoap-plugin/build.xml org.glite.security.gsoap-plugin/examples/calc.h.S org.glite.security.gsoap-plugin/examples/wscalc_clt_ex.c org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c org.glite.security.gsoap-plugin/interface/glite_gsplugin.h org.glite.security.gsoap-plugin/interface/glite_gss.h org.glite.security.gsoap-plugin/project/build.number org.glite.security.gsoap-plugin/project/build.properties org.glite.security.gsoap-plugin/project/configure.properties.xml org.glite.security.gsoap-plugin/project/properties.xml org.glite.security.gsoap-plugin/project/tar_exclude org.glite.security.gsoap-plugin/project/version.properties org.glite.security.gsoap-plugin/src/glite_gsplugin.c org.glite.security.gsoap-plugin/src/glite_gss.c org.glite.security.gsoap-plugin/test/test_gss.cpp org.glite.security.proxyrenewal/.cvsignore org.glite.security.proxyrenewal/LICENSE org.glite.security.proxyrenewal/Makefile org.glite.security.proxyrenewal/build.xml org.glite.security.proxyrenewal/config/startup org.glite.security.proxyrenewal/interface/renewal.h org.glite.security.proxyrenewal/project/build.number org.glite.security.proxyrenewal/project/build.properties org.glite.security.proxyrenewal/project/configure.properties.xml org.glite.security.proxyrenewal/project/properties.xml org.glite.security.proxyrenewal/project/tar_exclude org.glite.security.proxyrenewal/project/taskdefs.xml org.glite.security.proxyrenewal/project/version.properties org.glite.security.proxyrenewal/src/acstack.h 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/newformat.h 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 org.glite.security.proxyrenewal/src/voms.c org.glite.wms-utils.exception/.cvsignore org.glite.wms-utils.exception/LICENSE org.glite.wms-utils.exception/Makefile.am org.glite.wms-utils.exception/bootstrap org.glite.wms-utils.exception/build.xml org.glite.wms-utils.exception/configure.ac org.glite.wms-utils.exception/interface/Makefile.am org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h org.glite.wms-utils.exception/project/build.number org.glite.wms-utils.exception/project/build.properties org.glite.wms-utils.exception/project/configure.properties.xml org.glite.wms-utils.exception/project/properties.xml org.glite.wms-utils.exception/project/version.properties org.glite.wms-utils.exception/src/Exception.cpp org.glite.wms-utils.exception/src/Makefile.am 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/examples/Makefile.am org.glite.wms-utils.jobid/examples/testjobid.c org.glite.wms-utils.jobid/interface/Makefile.am org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h org.glite.wms-utils.jobid/project/build.number org.glite.wms-utils.jobid/project/build.properties org.glite.wms-utils.jobid/project/configure.properties.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/JobIdExceptions.cpp 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/manipulation.cpp org.glite.wms-utils.jobid/src/jobid/strmd5.c org.glite.wms-utils.jobid/src/jobid/strmd5.h org.gridsite.core/.cvsignore org.gridsite.core/CHANGES org.gridsite.core/INSTALL org.gridsite.core/LICENSE org.gridsite.core/README org.gridsite.core/VERSION org.gridsite.core/build.xml org.gridsite.core/doc/README.htcp-bin org.gridsite.core/doc/admin.html org.gridsite.core/doc/build-apache2.sh org.gridsite.core/doc/config.html org.gridsite.core/doc/findproxyfile.1 org.gridsite.core/doc/gacl.html org.gridsite.core/doc/htcp.1 org.gridsite.core/doc/htll.1 org.gridsite.core/doc/htls.1 org.gridsite.core/doc/htmkdir.1 org.gridsite.core/doc/htrm.1 org.gridsite.core/doc/httpd-fileserver.conf org.gridsite.core/doc/httpd-webserver.conf org.gridsite.core/doc/index.html org.gridsite.core/doc/install.html org.gridsite.core/doc/library.html org.gridsite.core/doc/module.html org.gridsite.core/doc/urlencode.1 org.gridsite.core/doc/user.html org.gridsite.core/interface/gridsite-gacl.h org.gridsite.core/interface/gridsite.h org.gridsite.core/project/build.number org.gridsite.core/project/build.properties org.gridsite.core/project/configure.properties.xml org.gridsite.core/project/dependencies.properties org.gridsite.core/project/gridsite.core.csf.xml org.gridsite.core/project/properties.xml org.gridsite.core/project/taskdefs.xml org.gridsite.core/project/version.properties org.gridsite.core/src/Doxyfile org.gridsite.core/src/Makefile org.gridsite.core/src/delegation.h org.gridsite.core/src/doxygen.css org.gridsite.core/src/doxyheader.html org.gridsite.core/src/findproxyfile.c org.gridsite.core/src/gaclexample.c org.gridsite.core/src/gridsite.spec org.gridsite.core/src/grst-delegation.c org.gridsite.core/src/grst_admin.h org.gridsite.core/src/grst_admin_file.c org.gridsite.core/src/grst_admin_gacl.c org.gridsite.core/src/grst_admin_main.c org.gridsite.core/src/grst_asn1.c org.gridsite.core/src/grst_gacl.c org.gridsite.core/src/grst_http.c org.gridsite.core/src/grst_x509.c org.gridsite.core/src/htcp org.gridsite.core/src/htcp.c org.gridsite.core/src/htproxyput.c org.gridsite.core/src/mod_gridsite.c org.gridsite.core/src/mod_ssl-private.h org.gridsite.core/src/proxyput-example.c org.gridsite.core/src/roffit org.gridsite.core/src/showx509exts.c org.gridsite.core/src/urlencode.c --- org.glite.deployment.lb/.cvsignore | 1 - org.glite.deployment.lb/CHANGELOG | 20 - org.glite.deployment.lb/build.xml | 110 - .../config/scripts/glite-lb-config.py | 479 --- .../config/scripts/remove_all_rpms.sh | 49 - .../config/templates/glite-lb.cfg.xml | 144 - .../doc/release_notes/release_notes.doc | Bin 334848 -> 0 bytes .../doc/release_notes/release_notes.html | 3368 -------------------- .../doc/release_notes/release_notes.pdf | Bin 277829 -> 0 bytes org.glite.deployment.lb/project/.cvsignore | 1 - org.glite.deployment.lb/project/build.number | 2 - org.glite.deployment.lb/project/build.properties | 0 .../project/glite-lb.sdf.xml.template | 131 - org.glite.deployment.lb/project/glite-lb.spec | 46 - org.glite.deployment.lb/project/lxscript-rpm.xsl | 334 -- org.glite.deployment.lb/project/lxscript-tgz.xsl | 62 - org.glite.deployment.lb/project/properties.xml | 50 - .../project/quattor-template.xsl | 53 - org.glite.deployment.lb/project/version.properties | 4 - org.glite.jp.common/.cvsignore | 1 - org.glite.jp.common/Makefile | 85 - org.glite.jp.common/build.xml | 93 - org.glite.jp.common/interface/context.h | 17 - org.glite.jp.common/interface/strmd5.h | 28 - org.glite.jp.common/interface/types.h | 89 - org.glite.jp.common/project/build.number | 1 - org.glite.jp.common/project/build.properties | 0 .../project/configure.properties.xml | 52 - org.glite.jp.common/project/properties.xml | 52 - org.glite.jp.common/project/tar_exclude | 10 - org.glite.jp.common/project/version.properties | 2 - org.glite.jp.common/src/attr.c | 18 - org.glite.jp.common/src/context.c | 164 - org.glite.jp.common/src/strmd5.c | 115 - org.glite.jp.index/.cvsignore | 1 - org.glite.jp.index/Makefile | 129 - org.glite.jp.index/build.xml | 93 - org.glite.jp.index/project/JobProvenanceIS.wsdl | 531 --- org.glite.jp.index/project/build.number | 1 - org.glite.jp.index/project/build.properties | 0 .../project/configure.properties.xml | 53 - org.glite.jp.index/project/properties.xml | 52 - org.glite.jp.index/project/tar_exclude | 10 - org.glite.jp.index/project/version.properties | 2 - org.glite.jp.index/src/simple_server.c | 39 - org.glite.jp.index/src/soap_ops.c | 81 - org.glite.jp.index/src/typemap.dat | 2 - org.glite.jp.primary/.cvsignore | 1 - org.glite.jp.primary/Makefile | 175 - org.glite.jp.primary/build.xml | 97 - org.glite.jp.primary/examples/jpps-test.c | 227 -- org.glite.jp.primary/interface/file_plugin.h | 71 - org.glite.jp.primary/project/build.number | 1 - org.glite.jp.primary/project/build.properties | 0 .../project/configure.properties.xml | 52 - org.glite.jp.primary/project/properties.xml | 51 - org.glite.jp.primary/project/tar_exclude | 10 - org.glite.jp.primary/project/version.properties | 2 - org.glite.jp.primary/src/backend.h | 116 - org.glite.jp.primary/src/bones_server.c | 316 -- org.glite.jp.primary/src/builtin_plugins.h | 7 - org.glite.jp.primary/src/db.h | 83 - org.glite.jp.primary/src/feed.c | 327 -- org.glite.jp.primary/src/feed.h | 21 - org.glite.jp.primary/src/file_plugin.c | 115 - org.glite.jp.primary/src/ftp_backend.c | 1744 ---------- org.glite.jp.primary/src/is_client.c | 38 - org.glite.jp.primary/src/jptype_map.h | 18 - org.glite.jp.primary/src/mysql.c | 260 -- org.glite.jp.primary/src/simple_server.c | 59 - org.glite.jp.primary/src/soap_ops.c | 445 --- org.glite.jp.primary/src/tags.c | 233 -- org.glite.jp.primary/src/tags.h | 1 - org.glite.jp.primary/src/tags_plugin.c | 64 - org.glite.jp.primary/src/typemap.dat | 3 - org.glite.jp.ws-interface/.cvsignore | 2 - org.glite.jp.ws-interface/LICENSE | 69 - org.glite.jp.ws-interface/Makefile | 54 - org.glite.jp.ws-interface/build.xml | 116 - .../interface/JobProvenanceIS.wsdl | 110 - org.glite.jp.ws-interface/project/build.number | 1 - org.glite.jp.ws-interface/project/build.properties | 0 .../project/configure.properties.xml | 54 - .../project/glite-jp-ws-interface.spec | 42 - org.glite.jp.ws-interface/project/properties.xml | 73 - org.glite.jp.ws-interface/project/tar_exclude | 0 .../project/version.properties | 2 - org.glite.jp.ws-interface/src/JobProvenancePS.xml | 67 - .../src/JobProvenanceTypes.xml | 50 - org.glite.jp.ws-interface/src/puke-wsdl.xsl | 272 -- org.glite.jp/.cvsignore | 1 - org.glite.jp/build.xml | 264 -- org.glite.jp/project/build.number | 1 - org.glite.jp/project/build.properties | 0 org.glite.jp/project/dependencies.properties | 12 - org.glite.jp/project/glite.jp.csf.xml | 271 -- org.glite.jp/project/properties.xml | 47 - org.glite.jp/project/run-workspace | 10 - org.glite.jp/project/taskdefs.xml | 24 - org.glite.jp/project/version.properties | 2 - org.glite.lb.client/examples/gen_sample_job | 6 + org.glite.lb.client/examples/job_status.c | 12 + org.glite.lb.client/examples/ready.l | 2 +- org.glite.lb.client/examples/resubmission.l | 18 + org.glite.lb.client/examples/resubmitted.l | 20 + org.glite.lb.client/examples/running.l | 2 +- .../examples/shallow_and_full_resub.l | 35 + .../examples/shallow_resub_complex.l | 42 + .../examples/shallow_resub_simple.l | 28 + .../examples/shallow_resub_simple2.l | 29 + org.glite.lb.common/src/xml_parse.c.T | 18 + org.glite.lb.proxy/project/MultiStruct.pm | 191 -- org.glite.lb.proxy/project/StructField.pm | 116 - org.glite.lb.proxy/project/at3 | 93 - org.glite.lb.proxy/project/events.T | 183 -- org.glite.lb.proxy/project/status.T | 77 - org.glite.lb.proxy/project/types.T | 108 - org.glite.lb.server/Makefile | 48 +- org.glite.lb.server/interface/lbs_db.h | 7 +- org.glite.lb.server/src/jobstat.c | 240 +- org.glite.lb.server/src/jobstat.h | 21 +- org.glite.lb.server/src/jobstat_supp.c | 153 +- org.glite.lb.server/src/lb_xml_parse.c.T | 2 + org.glite.lb.ws-interface/interface/LB.wsdl | 358 --- org.glite.lb/project/dependencies.properties | 33 +- org.glite.lb/project/events.T | 8 +- org.glite.lb/project/status.T | 6 + org.glite.security.gsoap-plugin/LICENSE | 69 - org.glite.security.gsoap-plugin/Makefile | 221 -- org.glite.security.gsoap-plugin/build.xml | 104 - org.glite.security.gsoap-plugin/examples/calc.h.S | 13 - .../examples/wscalc_clt_ex.c | 47 - .../examples/wscalc_srv_ex.c | 102 - .../examples/wscalc_srv_ex2.c | 130 - .../interface/glite_gsplugin.h | 37 - .../interface/glite_gss.h | 117 - .../project/build.number | 1 - .../project/build.properties | 0 .../project/configure.properties.xml | 50 - .../project/properties.xml | 55 - .../project/tar_exclude | 10 - .../project/version.properties | 3 - .../src/glite_gsplugin.c | 412 --- org.glite.security.gsoap-plugin/src/glite_gss.c | 998 ------ org.glite.security.gsoap-plugin/test/test_gss.cpp | 149 - org.glite.security.proxyrenewal/.cvsignore | 1 - org.glite.security.proxyrenewal/LICENSE | 69 - org.glite.security.proxyrenewal/Makefile | 141 - org.glite.security.proxyrenewal/build.xml | 120 - org.glite.security.proxyrenewal/config/startup | 80 - .../interface/renewal.h | 146 - .../project/build.number | 1 - .../project/build.properties | 0 .../project/configure.properties.xml | 60 - .../project/properties.xml | 62 - .../project/tar_exclude | 10 - .../project/taskdefs.xml | 4 - .../project/version.properties | 2 - org.glite.security.proxyrenewal/src/acstack.h | 79 - org.glite.security.proxyrenewal/src/api.c | 485 --- org.glite.security.proxyrenewal/src/client.c | 117 - org.glite.security.proxyrenewal/src/commands.c | 1256 -------- org.glite.security.proxyrenewal/src/common.c | 323 -- org.glite.security.proxyrenewal/src/newformat.h | 195 -- org.glite.security.proxyrenewal/src/renew.c | 404 --- org.glite.security.proxyrenewal/src/renewal_locl.h | 143 - org.glite.security.proxyrenewal/src/renewd.c | 656 ---- org.glite.security.proxyrenewal/src/renewd_locl.h | 80 - org.glite.security.proxyrenewal/src/voms.c | 318 -- org.glite.wms-utils.exception/.cvsignore | 1 - org.glite.wms-utils.exception/LICENSE | 69 - org.glite.wms-utils.exception/Makefile.am | 67 - org.glite.wms-utils.exception/bootstrap | 9 - org.glite.wms-utils.exception/build.xml | 100 - org.glite.wms-utils.exception/configure.ac | 115 - .../interface/Makefile.am | 14 - .../interface/glite/wmsutils/exception/Exception.h | 138 - .../glite/wmsutils/exception/exception_codes.h | 41 - org.glite.wms-utils.exception/project/build.number | 1 - .../project/build.properties | 0 .../project/configure.properties.xml | 9 - .../project/properties.xml | 83 - .../project/version.properties | 2 - org.glite.wms-utils.exception/src/Exception.cpp | 118 - org.glite.wms-utils.exception/src/Makefile.am | 17 - org.glite.wms-utils.jobid/.cvsignore | 2 - org.glite.wms-utils.jobid/LICENSE | 69 - org.glite.wms-utils.jobid/Makefile.am | 69 - org.glite.wms-utils.jobid/bootstrap | 9 - org.glite.wms-utils.jobid/build.xml | 100 - org.glite.wms-utils.jobid/configure.ac | 128 - org.glite.wms-utils.jobid/examples/Makefile.am | 28 - org.glite.wms-utils.jobid/examples/testjobid.c | 33 - org.glite.wms-utils.jobid/interface/Makefile.am | 16 - .../interface/glite/wmsutils/jobid/JobId.h | 136 - .../glite/wmsutils/jobid/JobIdExceptions.h | 80 - .../interface/glite/wmsutils/jobid/cjobid.h | 109 - .../interface/glite/wmsutils/jobid/manipulation.h | 24 - org.glite.wms-utils.jobid/project/build.number | 1 - org.glite.wms-utils.jobid/project/build.properties | 0 .../project/configure.properties.xml | 9 - org.glite.wms-utils.jobid/project/properties.xml | 86 - .../project/version.properties | 2 - org.glite.wms-utils.jobid/src/Makefile.am | 12 - org.glite.wms-utils.jobid/src/jobid/JobId.cpp | 183 -- .../src/jobid/JobIdExceptions.cpp | 58 - org.glite.wms-utils.jobid/src/jobid/Makefile.am | 30 - org.glite.wms-utils.jobid/src/jobid/cjobid.c | 258 -- .../src/jobid/manipulation.cpp | 180 -- org.glite.wms-utils.jobid/src/jobid/strmd5.c | 118 - org.glite.wms-utils.jobid/src/jobid/strmd5.h | 28 - org.gridsite.core/.cvsignore | 1 - org.gridsite.core/CHANGES | 186 -- org.gridsite.core/INSTALL | 39 - org.gridsite.core/LICENSE | 47 - org.gridsite.core/README | 3 - org.gridsite.core/VERSION | 4 - org.gridsite.core/build.xml | 270 -- org.gridsite.core/doc/README.htcp-bin | 13 - org.gridsite.core/doc/admin.html | 103 - org.gridsite.core/doc/build-apache2.sh | 79 - org.gridsite.core/doc/config.html | 192 -- org.gridsite.core/doc/findproxyfile.1 | 63 - org.gridsite.core/doc/gacl.html | 84 - org.gridsite.core/doc/htcp.1 | 147 - org.gridsite.core/doc/htll.1 | 1 - org.gridsite.core/doc/htls.1 | 1 - org.gridsite.core/doc/htmkdir.1 | 1 - org.gridsite.core/doc/htrm.1 | 1 - org.gridsite.core/doc/httpd-fileserver.conf | 147 - org.gridsite.core/doc/httpd-webserver.conf | 219 -- org.gridsite.core/doc/index.html | 92 - org.gridsite.core/doc/install.html | 148 - org.gridsite.core/doc/library.html | 1 - org.gridsite.core/doc/module.html | 271 -- org.gridsite.core/doc/urlencode.1 | 46 - org.gridsite.core/doc/user.html | 302 -- org.gridsite.core/interface/gridsite-gacl.h | 188 -- org.gridsite.core/interface/gridsite.h | 288 -- org.gridsite.core/project/build.number | 2 - org.gridsite.core/project/build.properties | 0 org.gridsite.core/project/configure.properties.xml | 9 - org.gridsite.core/project/dependencies.properties | 9 - org.gridsite.core/project/gridsite.core.csf.xml | 221 -- org.gridsite.core/project/properties.xml | 53 - org.gridsite.core/project/taskdefs.xml | 31 - org.gridsite.core/project/version.properties | 2 - org.gridsite.core/src/Doxyfile | 993 ------ org.gridsite.core/src/Makefile | 339 -- org.gridsite.core/src/delegation.h | 12 - org.gridsite.core/src/doxygen.css | 49 - org.gridsite.core/src/doxyheader.html | 1 - org.gridsite.core/src/findproxyfile.c | 122 - org.gridsite.core/src/gaclexample.c | 147 - org.gridsite.core/src/gridsite.spec | 85 - org.gridsite.core/src/grst-delegation.c | 297 -- org.gridsite.core/src/grst_admin.h | 57 - org.gridsite.core/src/grst_admin_file.c | 1571 --------- org.gridsite.core/src/grst_admin_gacl.c | 968 ------ org.gridsite.core/src/grst_admin_main.c | 365 --- org.gridsite.core/src/grst_asn1.c | 506 --- org.gridsite.core/src/grst_gacl.c | 1154 ------- org.gridsite.core/src/grst_http.c | 407 --- org.gridsite.core/src/grst_x509.c | 1491 --------- org.gridsite.core/src/htcp | Bin 29747 -> 0 bytes org.gridsite.core/src/htcp.c | 1237 ------- org.gridsite.core/src/htproxyput.c | 565 ---- org.gridsite.core/src/mod_gridsite.c | 2357 -------------- org.gridsite.core/src/mod_ssl-private.h | 106 - org.gridsite.core/src/proxyput-example.c | 131 - org.gridsite.core/src/roffit | 370 --- org.gridsite.core/src/showx509exts.c | 117 - org.gridsite.core/src/urlencode.c | 73 - 273 files changed, 679 insertions(+), 40439 deletions(-) delete mode 100644 org.glite.deployment.lb/.cvsignore delete mode 100644 org.glite.deployment.lb/CHANGELOG delete mode 100644 org.glite.deployment.lb/build.xml delete mode 100644 org.glite.deployment.lb/config/scripts/glite-lb-config.py delete mode 100755 org.glite.deployment.lb/config/scripts/remove_all_rpms.sh delete mode 100644 org.glite.deployment.lb/config/templates/glite-lb.cfg.xml delete mode 100644 org.glite.deployment.lb/doc/release_notes/release_notes.doc delete mode 100644 org.glite.deployment.lb/doc/release_notes/release_notes.html delete mode 100644 org.glite.deployment.lb/doc/release_notes/release_notes.pdf delete mode 100644 org.glite.deployment.lb/project/.cvsignore delete mode 100644 org.glite.deployment.lb/project/build.number delete mode 100644 org.glite.deployment.lb/project/build.properties delete mode 100644 org.glite.deployment.lb/project/glite-lb.sdf.xml.template delete mode 100644 org.glite.deployment.lb/project/glite-lb.spec delete mode 100644 org.glite.deployment.lb/project/lxscript-rpm.xsl delete mode 100644 org.glite.deployment.lb/project/lxscript-tgz.xsl delete mode 100644 org.glite.deployment.lb/project/properties.xml delete mode 100644 org.glite.deployment.lb/project/quattor-template.xsl delete mode 100644 org.glite.deployment.lb/project/version.properties delete mode 100644 org.glite.jp.common/.cvsignore delete mode 100644 org.glite.jp.common/Makefile delete mode 100755 org.glite.jp.common/build.xml delete mode 100644 org.glite.jp.common/interface/context.h delete mode 100755 org.glite.jp.common/interface/strmd5.h delete mode 100644 org.glite.jp.common/interface/types.h delete mode 100644 org.glite.jp.common/project/build.number delete mode 100644 org.glite.jp.common/project/build.properties delete mode 100644 org.glite.jp.common/project/configure.properties.xml delete mode 100755 org.glite.jp.common/project/properties.xml delete mode 100644 org.glite.jp.common/project/tar_exclude delete mode 100644 org.glite.jp.common/project/version.properties delete mode 100644 org.glite.jp.common/src/attr.c delete mode 100644 org.glite.jp.common/src/context.c delete mode 100755 org.glite.jp.common/src/strmd5.c delete mode 100644 org.glite.jp.index/.cvsignore delete mode 100644 org.glite.jp.index/Makefile delete mode 100755 org.glite.jp.index/build.xml delete mode 100644 org.glite.jp.index/project/JobProvenanceIS.wsdl delete mode 100644 org.glite.jp.index/project/build.number delete mode 100644 org.glite.jp.index/project/build.properties delete mode 100644 org.glite.jp.index/project/configure.properties.xml delete mode 100755 org.glite.jp.index/project/properties.xml delete mode 100644 org.glite.jp.index/project/tar_exclude delete mode 100644 org.glite.jp.index/project/version.properties delete mode 100644 org.glite.jp.index/src/simple_server.c delete mode 100644 org.glite.jp.index/src/soap_ops.c delete mode 100644 org.glite.jp.index/src/typemap.dat delete mode 100644 org.glite.jp.primary/.cvsignore delete mode 100644 org.glite.jp.primary/Makefile delete mode 100755 org.glite.jp.primary/build.xml delete mode 100644 org.glite.jp.primary/examples/jpps-test.c delete mode 100644 org.glite.jp.primary/interface/file_plugin.h delete mode 100644 org.glite.jp.primary/project/build.number delete mode 100644 org.glite.jp.primary/project/build.properties delete mode 100644 org.glite.jp.primary/project/configure.properties.xml delete mode 100755 org.glite.jp.primary/project/properties.xml delete mode 100644 org.glite.jp.primary/project/tar_exclude delete mode 100644 org.glite.jp.primary/project/version.properties delete mode 100644 org.glite.jp.primary/src/backend.h delete mode 100644 org.glite.jp.primary/src/bones_server.c delete mode 100644 org.glite.jp.primary/src/builtin_plugins.h delete mode 100644 org.glite.jp.primary/src/db.h delete mode 100644 org.glite.jp.primary/src/feed.c delete mode 100644 org.glite.jp.primary/src/feed.h delete mode 100644 org.glite.jp.primary/src/file_plugin.c delete mode 100644 org.glite.jp.primary/src/ftp_backend.c delete mode 100644 org.glite.jp.primary/src/is_client.c delete mode 100644 org.glite.jp.primary/src/jptype_map.h delete mode 100644 org.glite.jp.primary/src/mysql.c delete mode 100644 org.glite.jp.primary/src/simple_server.c delete mode 100644 org.glite.jp.primary/src/soap_ops.c delete mode 100644 org.glite.jp.primary/src/tags.c delete mode 100644 org.glite.jp.primary/src/tags.h delete mode 100644 org.glite.jp.primary/src/tags_plugin.c delete mode 100644 org.glite.jp.primary/src/typemap.dat delete mode 100755 org.glite.jp.ws-interface/.cvsignore delete mode 100755 org.glite.jp.ws-interface/LICENSE delete mode 100644 org.glite.jp.ws-interface/Makefile delete mode 100644 org.glite.jp.ws-interface/build.xml delete mode 100644 org.glite.jp.ws-interface/interface/JobProvenanceIS.wsdl delete mode 100644 org.glite.jp.ws-interface/project/build.number delete mode 100755 org.glite.jp.ws-interface/project/build.properties delete mode 100644 org.glite.jp.ws-interface/project/configure.properties.xml delete mode 100644 org.glite.jp.ws-interface/project/glite-jp-ws-interface.spec delete mode 100644 org.glite.jp.ws-interface/project/properties.xml delete mode 100644 org.glite.jp.ws-interface/project/tar_exclude delete mode 100755 org.glite.jp.ws-interface/project/version.properties delete mode 100644 org.glite.jp.ws-interface/src/JobProvenancePS.xml delete mode 100644 org.glite.jp.ws-interface/src/JobProvenanceTypes.xml delete mode 100644 org.glite.jp.ws-interface/src/puke-wsdl.xsl delete mode 100644 org.glite.jp/.cvsignore delete mode 100644 org.glite.jp/build.xml delete mode 100644 org.glite.jp/project/build.number delete mode 100644 org.glite.jp/project/build.properties delete mode 100644 org.glite.jp/project/dependencies.properties delete mode 100644 org.glite.jp/project/glite.jp.csf.xml delete mode 100755 org.glite.jp/project/properties.xml delete mode 100644 org.glite.jp/project/run-workspace delete mode 100755 org.glite.jp/project/taskdefs.xml delete mode 100644 org.glite.jp/project/version.properties create mode 100644 org.glite.lb.client/examples/resubmission.l create mode 100644 org.glite.lb.client/examples/resubmitted.l create mode 100644 org.glite.lb.client/examples/shallow_and_full_resub.l create mode 100644 org.glite.lb.client/examples/shallow_resub_complex.l create mode 100644 org.glite.lb.client/examples/shallow_resub_simple.l create mode 100644 org.glite.lb.client/examples/shallow_resub_simple2.l delete mode 100644 org.glite.lb.proxy/project/MultiStruct.pm delete mode 100644 org.glite.lb.proxy/project/StructField.pm delete mode 100644 org.glite.lb.proxy/project/at3 delete mode 100644 org.glite.lb.proxy/project/events.T delete mode 100644 org.glite.lb.proxy/project/status.T delete mode 100644 org.glite.lb.proxy/project/types.T delete mode 100755 org.glite.lb.ws-interface/interface/LB.wsdl delete mode 100644 org.glite.security.gsoap-plugin/LICENSE delete mode 100644 org.glite.security.gsoap-plugin/Makefile delete mode 100755 org.glite.security.gsoap-plugin/build.xml delete mode 100644 org.glite.security.gsoap-plugin/examples/calc.h.S delete mode 100644 org.glite.security.gsoap-plugin/examples/wscalc_clt_ex.c delete mode 100644 org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c delete mode 100644 org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c delete mode 100644 org.glite.security.gsoap-plugin/interface/glite_gsplugin.h delete mode 100644 org.glite.security.gsoap-plugin/interface/glite_gss.h delete mode 100644 org.glite.security.gsoap-plugin/project/build.number delete mode 100644 org.glite.security.gsoap-plugin/project/build.properties delete mode 100644 org.glite.security.gsoap-plugin/project/configure.properties.xml delete mode 100755 org.glite.security.gsoap-plugin/project/properties.xml delete mode 100644 org.glite.security.gsoap-plugin/project/tar_exclude delete mode 100644 org.glite.security.gsoap-plugin/project/version.properties delete mode 100644 org.glite.security.gsoap-plugin/src/glite_gsplugin.c delete mode 100644 org.glite.security.gsoap-plugin/src/glite_gss.c delete mode 100644 org.glite.security.gsoap-plugin/test/test_gss.cpp delete mode 100644 org.glite.security.proxyrenewal/.cvsignore delete mode 100644 org.glite.security.proxyrenewal/LICENSE delete mode 100644 org.glite.security.proxyrenewal/Makefile delete mode 100755 org.glite.security.proxyrenewal/build.xml delete mode 100755 org.glite.security.proxyrenewal/config/startup delete mode 100644 org.glite.security.proxyrenewal/interface/renewal.h delete mode 100644 org.glite.security.proxyrenewal/project/build.number delete mode 100644 org.glite.security.proxyrenewal/project/build.properties delete mode 100644 org.glite.security.proxyrenewal/project/configure.properties.xml delete mode 100755 org.glite.security.proxyrenewal/project/properties.xml delete mode 100644 org.glite.security.proxyrenewal/project/tar_exclude delete mode 100755 org.glite.security.proxyrenewal/project/taskdefs.xml delete mode 100644 org.glite.security.proxyrenewal/project/version.properties delete mode 100755 org.glite.security.proxyrenewal/src/acstack.h delete mode 100644 org.glite.security.proxyrenewal/src/api.c delete mode 100644 org.glite.security.proxyrenewal/src/client.c delete mode 100644 org.glite.security.proxyrenewal/src/commands.c delete mode 100644 org.glite.security.proxyrenewal/src/common.c delete mode 100755 org.glite.security.proxyrenewal/src/newformat.h delete mode 100644 org.glite.security.proxyrenewal/src/renew.c delete mode 100644 org.glite.security.proxyrenewal/src/renewal_locl.h delete mode 100644 org.glite.security.proxyrenewal/src/renewd.c delete mode 100644 org.glite.security.proxyrenewal/src/renewd_locl.h delete mode 100644 org.glite.security.proxyrenewal/src/voms.c delete mode 100644 org.glite.wms-utils.exception/.cvsignore delete mode 100755 org.glite.wms-utils.exception/LICENSE delete mode 100755 org.glite.wms-utils.exception/Makefile.am delete mode 100755 org.glite.wms-utils.exception/bootstrap delete mode 100755 org.glite.wms-utils.exception/build.xml delete mode 100755 org.glite.wms-utils.exception/configure.ac delete mode 100755 org.glite.wms-utils.exception/interface/Makefile.am delete mode 100644 org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h delete mode 100755 org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h delete mode 100644 org.glite.wms-utils.exception/project/build.number delete mode 100755 org.glite.wms-utils.exception/project/build.properties delete mode 100644 org.glite.wms-utils.exception/project/configure.properties.xml delete mode 100755 org.glite.wms-utils.exception/project/properties.xml delete mode 100755 org.glite.wms-utils.exception/project/version.properties delete mode 100644 org.glite.wms-utils.exception/src/Exception.cpp delete mode 100755 org.glite.wms-utils.exception/src/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/.cvsignore delete mode 100755 org.glite.wms-utils.jobid/LICENSE delete mode 100755 org.glite.wms-utils.jobid/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/bootstrap delete mode 100755 org.glite.wms-utils.jobid/build.xml delete mode 100755 org.glite.wms-utils.jobid/configure.ac delete mode 100755 org.glite.wms-utils.jobid/examples/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/examples/testjobid.c delete mode 100755 org.glite.wms-utils.jobid/interface/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h delete mode 100755 org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h delete mode 100755 org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h delete mode 100755 org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h delete mode 100644 org.glite.wms-utils.jobid/project/build.number delete mode 100755 org.glite.wms-utils.jobid/project/build.properties delete mode 100644 org.glite.wms-utils.jobid/project/configure.properties.xml delete mode 100755 org.glite.wms-utils.jobid/project/properties.xml delete mode 100755 org.glite.wms-utils.jobid/project/version.properties delete mode 100755 org.glite.wms-utils.jobid/src/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/src/jobid/JobId.cpp delete mode 100755 org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp delete mode 100755 org.glite.wms-utils.jobid/src/jobid/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/src/jobid/cjobid.c delete mode 100755 org.glite.wms-utils.jobid/src/jobid/manipulation.cpp delete mode 100755 org.glite.wms-utils.jobid/src/jobid/strmd5.c delete mode 100755 org.glite.wms-utils.jobid/src/jobid/strmd5.h delete mode 100644 org.gridsite.core/.cvsignore delete mode 100644 org.gridsite.core/CHANGES delete mode 100644 org.gridsite.core/INSTALL delete mode 100644 org.gridsite.core/LICENSE delete mode 100644 org.gridsite.core/README delete mode 100644 org.gridsite.core/VERSION delete mode 100644 org.gridsite.core/build.xml delete mode 100644 org.gridsite.core/doc/README.htcp-bin delete mode 100644 org.gridsite.core/doc/admin.html delete mode 100644 org.gridsite.core/doc/build-apache2.sh delete mode 100644 org.gridsite.core/doc/config.html delete mode 100644 org.gridsite.core/doc/findproxyfile.1 delete mode 100644 org.gridsite.core/doc/gacl.html delete mode 100644 org.gridsite.core/doc/htcp.1 delete mode 100644 org.gridsite.core/doc/htll.1 delete mode 100644 org.gridsite.core/doc/htls.1 delete mode 100644 org.gridsite.core/doc/htmkdir.1 delete mode 100644 org.gridsite.core/doc/htrm.1 delete mode 100644 org.gridsite.core/doc/httpd-fileserver.conf delete mode 100644 org.gridsite.core/doc/httpd-webserver.conf delete mode 100644 org.gridsite.core/doc/index.html delete mode 100644 org.gridsite.core/doc/install.html delete mode 100644 org.gridsite.core/doc/library.html delete mode 100644 org.gridsite.core/doc/module.html delete mode 100644 org.gridsite.core/doc/urlencode.1 delete mode 100644 org.gridsite.core/doc/user.html delete mode 100644 org.gridsite.core/interface/gridsite-gacl.h delete mode 100644 org.gridsite.core/interface/gridsite.h delete mode 100644 org.gridsite.core/project/build.number delete mode 100644 org.gridsite.core/project/build.properties delete mode 100644 org.gridsite.core/project/configure.properties.xml delete mode 100644 org.gridsite.core/project/dependencies.properties delete mode 100644 org.gridsite.core/project/gridsite.core.csf.xml delete mode 100644 org.gridsite.core/project/properties.xml delete mode 100644 org.gridsite.core/project/taskdefs.xml delete mode 100644 org.gridsite.core/project/version.properties delete mode 100644 org.gridsite.core/src/Doxyfile delete mode 100644 org.gridsite.core/src/Makefile delete mode 100644 org.gridsite.core/src/delegation.h delete mode 100644 org.gridsite.core/src/doxygen.css delete mode 100644 org.gridsite.core/src/doxyheader.html delete mode 100644 org.gridsite.core/src/findproxyfile.c delete mode 100644 org.gridsite.core/src/gaclexample.c delete mode 100644 org.gridsite.core/src/gridsite.spec delete mode 100644 org.gridsite.core/src/grst-delegation.c delete mode 100644 org.gridsite.core/src/grst_admin.h delete mode 100644 org.gridsite.core/src/grst_admin_file.c delete mode 100644 org.gridsite.core/src/grst_admin_gacl.c delete mode 100644 org.gridsite.core/src/grst_admin_main.c delete mode 100644 org.gridsite.core/src/grst_asn1.c delete mode 100644 org.gridsite.core/src/grst_gacl.c delete mode 100644 org.gridsite.core/src/grst_http.c delete mode 100644 org.gridsite.core/src/grst_x509.c delete mode 100644 org.gridsite.core/src/htcp delete mode 100644 org.gridsite.core/src/htcp.c delete mode 100644 org.gridsite.core/src/htproxyput.c delete mode 100644 org.gridsite.core/src/mod_gridsite.c delete mode 100644 org.gridsite.core/src/mod_ssl-private.h delete mode 100644 org.gridsite.core/src/proxyput-example.c delete mode 100755 org.gridsite.core/src/roffit delete mode 100644 org.gridsite.core/src/showx509exts.c delete mode 100644 org.gridsite.core/src/urlencode.c diff --git a/org.glite.deployment.lb/.cvsignore b/org.glite.deployment.lb/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.deployment.lb/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.deployment.lb/CHANGELOG b/org.glite.deployment.lb/CHANGELOG deleted file mode 100644 index e14ac8a..0000000 --- a/org.glite.deployment.lb/CHANGELOG +++ /dev/null @@ -1,20 +0,0 @@ -DATE: 21-03-2005 17:21 -[dimeglio] Implemented status method - -DATE: 21-03-2005 00:32 -[dimeglio] Added PERL5LIB env var - -DATE: 17-03-2005 17:33 -[gdiez] Stopping and starting the database before the index creation (just after the database is created and the user granted) - -DATE: 09-03-2005 23:05 -[dimeglio] Moved creation of indices inside database creation (if database - exists indices are not recreated) - -DATE: 02-03-2005 11:05 -[dimeglio] Started CHANGELOG -[dimeglio] Fixed formatting, improved display of message using glib.printXxxMessage functions -[dimeglio] Fixed some problems when starting/stopping services -[dimeglio] GLITE_USER parameter not exposed anymore in config file, use same user parameters - as WMS to allow installation on same node -[dimeglio] Increased module version number to 1.2.0 \ No newline at end of file diff --git a/org.glite.deployment.lb/build.xml b/org.glite.deployment.lb/build.xml deleted file mode 100644 index 874c661..0000000 --- a/org.glite.deployment.lb/build.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.lb/config/scripts/glite-lb-config.py b/org.glite.deployment.lb/config/scripts/glite-lb-config.py deleted file mode 100644 index 071aa41..0000000 --- a/org.glite.deployment.lb/config/scripts/glite-lb-config.py +++ /dev/null @@ -1,479 +0,0 @@ -#!/usr/bin/env python -################################################################################ -# -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://eu-egee.org/partners/ for details on the copyright holders. -# For license conditions see the license file or http://eu-egee.org/license.html -# -################################################################################ -# glite-lb-config v. 1.3.0 -# -# Post-installation script for configuring the gLite Logging and Bookkeping Server -# Robert Harakaly < robert.harakaly@cern.ch > -# Diana Bosio -# Leanne Guy -# -# Version info: $Id$ -# -# Usage: python glite-lb-config [-c|-v|-h|--help] -# -c print configuration -# -v print version -# -h,--help print usage info -# -# Return codes: 0 - Ok -# 1 - Configuration failed -# -################################################################################ - -import os,string,pwd -import sys, posix, getopt,time - -sys.path.append(".") -from gLiteInstallerLib import gLib -from gliteRgmaServicetool import gliteRgmaServicetool -import mysql as MySQL - -# Set global variables here -global params # all config values from the XML file -global rgmaServicetool - -class glite_lb: - - def __init__(self): - self.mysql = MySQL.Mysql() - self.verbose = 0 - self.version = "1.3.0" - self.name = "glite-lb" - self.friendly_name = "gLite Logging and Bookkeeping" - - #------------------------------------------------------------------------------- - # Banner - #------------------------------------------------------------------------------- - - def banner(self): - - print "\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - print "Configuring the %s" % self.friendly_name - print "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" - - #------------------------------------------------------------------------------- - # Copyright - #------------------------------------------------------------------------------- - - def copyright(self): - - print '\nCopyright (c) Members of the EGEE Collaboration. 2004' - print 'See http://eu-egee.org/partners/ for details on the copyright holders' - print 'For license conditions see the license file or http://eu-egee.org/license.html' - - #------------------------------------------------------------------------------- - # Version - #------------------------------------------------------------------------------- - - def showVersion(self): - - print '\n%s-config v. %s\n' % (self.name,self.version) - - #------------------------------------------------------------------------------- - # Usage - #------------------------------------------------------------------------------- - - def usage(self,msg = ""): - - if msg: - print "\n%s" % (msg) - - self.copyright() - self.showVersion() - - print """Usage: \n -Edit the configuration file %s.cfg.xml in -%s/etc.config/templates\n -save it as %s/etc/config/%s.cfg.xml -and run the script as follows\n -python %s-config [OPTION...]""" % (self.name, os.environ['GLITE_LOCATION'], \ - os.environ['GLITE_LOCATION'], self.name, self.name) - - print ' -c, --checkconf print the service configuration' - print ' -v, --version print the version of the configuration script' - print ' -h, --help print this usage information' - print ' --start start the service' - print ' --stop stop the service' - print ' --status check service status' - print '\n' - - #------------------------------------------------------------------------------- - # All the configuration code goes here - #------------------------------------------------------------------------------- - - def start(self): - - self.mysql.start() - time.sleep(5) - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - pid = glib.getPID('bkserverd') - if pid != 0: - print 'The gLite LB Server service is already running. Restarting...' - os.system('%s/etc/init.d/glite-lb-bkserverd stop' % os.environ['GLITE_LOCATION']) - else: - print 'Starting the gLite LB Server service...' - - os.system('%s/etc/init.d/glite-lb-bkserverd start' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('bkserverd') - - if (pid != 0): - print "The gLite LB Server service has been started ", - glib.printOkMessage() - else: - glib.printErrorMessage("Could not start the gLite LB Server service") - glib.printErrorMessage("Please verify and re-run the script "), - glib.printFailedMessage() - return 1 - - #------------------------------------------------------------------- - # Start Servicetool - #------------------------------------------------------------------- - - pid = glib.getPID('rgma-servicetool') - if (pid != 0): - print 'The gLite R-GMA Servicetool service is already running. Restarting...' - rgmaServicetool.stop() - else: - print "Starting the gLite R-GMA Servicetool service" - - rgmaServicetool.start() - - - # Check that the daemon is running - - pid = glib.getPID('rgma-servicetool') - - if (pid != 0): - print "The gLite R-GMA Servicetool service has been started ", - glib.printOkMessage() - else: - glib.printErrorMessage("Could not start the gLite R-GMA Servicetool service") - glib.printErrorMessage("Please verify and re-run the script "), - glib.printFailedMessage() - return 1 - - return 0 - - def stop(self): - - pid = glib.getPID('bkserverd') - if (pid != 0): - os.system('%s/etc/init.d/glite-lb-bkserverd stop' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('bkserverd') - if (pid != 0): - print 'Could not stop the LB Server service ', - glib.printFailedMessage() - else: - print 'The LB Server service has been stopped ', - glib.printOkMessage() - - self.mysql.stop() - - #------------------------------------------------------------------- - # Stop the servicetool - #------------------------------------------------------------------- - - pid = glib.getPID('rgma-servicetool') - if (pid != 0): - rgmaServicetool.stop() - - pid = glib.getPID('rgma-servicetool') - if (pid != 0): - print 'Could not stop the R-GMA Servicetool service ', - glib.printFailedMessage() - else: - print 'The R-GMA Servicetool service has been stopped ', - glib.printOkMessage() - - return 0 - - def status(self): - - error_level = 0 - - retval = os.system('%s/etc/init.d/glite-lb-bkserverd status' % os.environ['GLITE_LOCATION']) - if retval != 0: - error_level = 1 - - return error_level - - def configure(self): - - #-------------------------------------------------------- - # Installs the Security Utilities - #-------------------------------------------------------- - - if os.system("python %s/glite-security-utils-config.py --subservice" % glib.getScriptPath()): - print "\nInstalling gLite Security Utilities ", - glib.printFailedMessage() - return 1 - - print "\nInstalling gLite Security Utilities ", - glib.printOkMessage() - - # Create the GLITE_USER if it doesn't exists - print "\nCreating/Verifying the GLITE_USER account %s" % os.environ['GLITE_USER'] - (uid,gid) = glib.get_user_info(os.environ['GLITE_USER']) - glib.check_dir(os.environ['GLITE_LOCATION_VAR'],0755, uid, gid) - lb_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.check_dir(lb_cert_path ,0755, uid, gid) - glib.printOkMessage() - - # Create all directories needed - print "\nVerify CA certificates directory ", - glib.check_dir(os.environ['GLITE_CERT_DIR']) - glib.printOkMessage() - - # Copy certificates - print "\nCopy host certificates to GLITE_USER home directory as service certificates", - os.system("cp %s %s %s/" % (params['host.certificate.file'], params['host.key.file'], lb_cert_path)) - os.chown("%s/hostcert.pem" % lb_cert_path, uid,gid) - os.chmod("%s/hostcert.pem" % lb_cert_path, 0644) - os.chown("%s/hostkey.pem" % lb_cert_path, uid,gid) - os.chmod("%s/hostkey.pem" % lb_cert_path, 0400) - glib.printOkMessage() - - # Create the MySQL database - print "\nCreate/Verify the %s database" % params['lb.database.name'] - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - # Check if database exists - if self.mysql.existsDB(params['lb.database.name']) != 0: - # Create database - print ('\n==> Creating MySQL %s database\n' % params['lb.database.name']) - - if os.path.exists('/bin/rm /tmp/mysql_ct'): - os.remove('/tmp/mysql_ct') - - file = open('/tmp/mysql_ct', 'w') - text = ['CREATE DATABASE %s;\n' % params['lb.database.name'], - 'GRANT ALL PRIVILEGES ON %s.* TO %s@localhost IDENTIFIED BY "";\n' \ - % (params['lb.database.name'],params['lb.database.username']), - 'USE %s;\n' % params['lb.database.name'], - '\. %s/etc/glite-lb-dbsetup.sql\n' % os.environ['GLITE_LOCATION']] - - file.writelines(text) - file.close() - os.system('/usr/bin/mysql < /tmp/mysql_ct') - os.system('/bin/rm /tmp/mysql_ct') - - #Starting and stopping the database before the index creation - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - #Creating the indexes - print 'Creating the index configuration file %s/etc/glite-lb-index.conf ' % os.environ['GLITE_LOCATION'], - path = "%s/etc/glite-lb-index.conf" % os.environ['GLITE_LOCATION'] - pathBak = "%s/etc/glite-lb-index.conf.bak" % os.environ['GLITE_LOCATION'] - - if os.path.exists(pathBak): - os.remove(pathBak) - if os.path.exists(path): - os.rename(path,pathBak) - file = open(path, 'w') - file.write("[\n") - file.write(" JobIndices = {\n") - for index in params['lb.index.list']: - file.write(" [ type = \"system\"; name = \"%s\" ],\n" % index) - file.write(" }\n") - file.write("]\n") - file.close() - glib.printOkMessage() - - print "Running glite-lb-bkindex ", - if os.system('%s/bin/glite-lb-bkindex -r %s/etc/glite-lb-index.conf' % (os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])): - glib.printFailedMessage() - return 1 - else: - glib.printOkMessage() - - else: - print "\n==> MySQL database %s already exist\n" % params['lb.database.name'] - - self.mysql.stop() - - #------------------------------------------------------------------- - # RGMA servicetool: configure servicetool - #------------------------------------------------------------------- - - print "Configuring the R-GMA Servicetool..." - - if rgmaServicetool.configure(glib): - # error in configuring services - print "Configuring the R-GMA Servicetool... ", - glib.printFailedMessage() - return 1 - - print "Configuring the R-GMA Servicetool... ", - glib.printOkMessage() - - return 0 - -#------------------------------------------------------------------------------- -# Set all environment variables -#------------------------------------------------------------------------------- - -def set_env(): - - # gLite - glib.export('GLITE_LOCATION'); - glib.export('GLITE_LOCATION_VAR'); - if not os.path.exists(os.environ['GLITE_LOCATION_VAR']): - os.mkdir(os.environ['GLITE_LOCATION_VAR'],0755) - glib.export('GLITE_LOCATION_LOG'); - if not os.path.exists(os.environ['GLITE_LOCATION_LOG']): - os.mkdir(os.environ['GLITE_LOCATION_LOG'],0755) - glib.export('GLITE_LOCATION_TMP'); - if not os.path.exists(os.environ['GLITE_LOCATION_TMP']): - os.mkdir(os.environ['GLITE_LOCATION_TMP'],0755) - - if not params.has_key('glite.user.group'): - params['glite.user.group'] = '' - (uid,gid) = glib.add_user(params['glite.user.name'],params['glite.user.group']) - glib.export('GLITE_USER',params['glite.user.name']) - lb_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.export('GLITE_HOST_CERT',"%s/hostcert.pem" % lb_cert_path) - glib.export('GLITE_HOST_KEY',"%s/hostkey.pem" % lb_cert_path) - glib.export('GLITE_CERT_DIR',params['ca.certificates.dir']) - - glib.export('GLOBUS_LOCATION',params['GLOBUS_LOCATION']) - glib.export('GPT_LOCATION',params['GPT_LOCATION']) - - glib.export('JAVA_HOME') - - # bin and lib paths - glib.addEnvPath("PATH","/usr/bin/:%s/bin:%s/bin:%s/externals/bin:%s/bin" \ - % (os.environ['JAVA_HOME'],os.environ['GLOBUS_LOCATION'],os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - glib.addEnvPath("LD_LIBRARY_PATH","/usr/lib:%s/lib:%s/externals/lib:%s/lib" % (os.environ['GLOBUS_LOCATION'], os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - - # Perl - glib.addEnvPath("PERL5LIB", "%s/lib/perl:%s/lib/perl5" % (os.environ['GPT_LOCATION'],os.environ['GLITE_LOCATION'])) - - # Set environment - glib.setUserEnv() - -#------------------------------------------------------------------------------- -# Main program begins here -#------------------------------------------------------------------------------- - -if __name__ == '__main__': - - # The script must be run as root - if not os.geteuid()==0: - print '"\nThis script must be run as root\n' - sys.exit(1) - - # Get an instance of the library class - glib = gLib() - - # Load parameters - params = {} - try: - opts, args = getopt.getopt(sys.argv[1:], '', ['siteconfig=']) - for o, a in opts: - if o == "--siteconfig": - params['site.config.url'] = a - break - except getopt.GetoptError: - pass - if glib.loadConfiguration("%s/../glite-lb.cfg.xml" % glib.getScriptPath(),params): - print "An error occurred while configuring the service" - sys.exit(1) - - verbose = 0 - if params.has_key('glite.installer.verbose'): - if params['glite.installer.verbose'] == "true": - verbose = 1 - glib.verbose = verbose - - # Set up the environment - set_env() - - # Instantiate the service classes - service = glite_lb() - service.verbose = verbose - # Instantiate the rgma servicetool class - rgmaServicetool = gliteRgmaServicetool() - rgmaServicetool.verbose = verbose - - # Command line opts if any - try: - opts, args = getopt.getopt(sys.argv[1:], 'chv', ['checkconf', 'help', 'version','stop','start','status','siteconfig=']) - except getopt.GetoptError: - service.usage(msg = "Unknown options(s)") - sys.exit(1) - - # Check cli options - for o, a in opts: - if o in ("-h", "--help"): - service.usage() - sys.exit(0) - if o in ("-v", "--version"): - service.showVersion() - sys.exit(0) - if o in ("-c", "--checkconf"): - service.copyright() - service.showVersion() - glib.print_params(params) - sys.exit(0) - if o in ("stop", "--stop"): - service.stop() - sys.exit(0) - if o in ("start", "--start"): - service.start() - sys.exit(0) - if o == "--status": - sys.exit(service.status()) - - - # Check certificates - if params.has_key('glite.installer.checkcerts'): - if params['glite.installer.checkcerts'] == "true": - if glib.check_certs(params) != 0: - print "An error occurred while configuring the %s service" \ - % service.friendly_name - sys.exit(1) - - # Print configuration parameters - if verbose: - glib.print_params(params) - - service.copyright() - service.showVersion() - service.banner() - - # Configure the service - if service.configure() == 0: - print "\n%s configuration successfully completed " % service.friendly_name, - glib.printOkMessage() - glib.registerService() - else: - print "\nAn error occurred while configuring the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - - # Start the service - if service.start() == 0: - print "\nThe %s was successfully started " % service.friendly_name, - glib.printOkMessage() - else: - print "\nAn error occurred while starting the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - diff --git a/org.glite.deployment.lb/config/scripts/remove_all_rpms.sh b/org.glite.deployment.lb/config/scripts/remove_all_rpms.sh deleted file mode 100755 index 2835ee1..0000000 --- a/org.glite.deployment.lb/config/scripts/remove_all_rpms.sh +++ /dev/null @@ -1,49 +0,0 @@ - -#!/bin/sh - -rpm -e edg-fetch-crl-1.0.0-EGEE \ -ca_ArmeSFo-0.23-1 \ -ca_ASGCCA-0.23-1 \ -ca_BEGrid-0.23-1 \ -ca_CERN-0.23-1 \ -ca_CESNET-0.23-1 \ -ca_CNRS-0.23-1 \ -ca_CNRS-DataGrid-0.23-1 \ -ca_CNRS-Projets-0.23-1 \ -ca_CyGrid-0.23-1 \ -ca_DOEGrids-0.23-1 \ -ca_DOESG-Root-0.23-1 \ -ca_ESnet-0.23-1 \ -ca_FNAL-0.23-1 \ -ca_FNAL_KCA-0.23-1 \ -ca_GermanGrid-0.23-1 \ -ca_Grid-Ireland-0.23-1 \ -ca_GridCanada-0.23-1 \ -ca_HellasGrid-0.23-1 \ -ca_INFN-0.23-1 \ -ca_IUCC-0.23-1 \ -ca_LIP-0.23-1 \ -ca_NIKHEF-0.23-1 \ -ca_NorduGrid-0.23-1 \ -ca_PK-Grid-0.23-1 \ -ca_PolishGrid-0.23-1 \ -ca_Russia-0.23-1 \ -ca_SlovakGrid-0.23-1 \ -ca_Spain-0.23-1 \ -ca_UKeScience-0.23-1 \ -glite-wms-utils-exception-0.1.0-0 \ -glite-wms-utils-jobid-0.1.0-0 \ -glite-lb-client-interface-0.2.0-0 \ -glite-lb-server-bones-0.0.0-0 \ -glite-lb-common-0.2.0-0 \ -glite-lb-logger-0.2.0-0 \ -glite-lb-server-0.3.0-0 \ -glite-security-proxyrenewal-0.1.0-1 \ -ares-1.1.1-EGEE \ -gpt-VDT1.2.0rh9-1 \ -vdt_globus_essentials-VDT1.2.0rh9-1 \ -perl-Expect.pm-1.01-9 \ -myproxy-1.14-EGEE \ -MySQL-client-4.0.20-0 \ -MySQL-server-4.0.20-0 - diff --git a/org.glite.deployment.lb/config/templates/glite-lb.cfg.xml b/org.glite.deployment.lb/config/templates/glite-lb.cfg.xml deleted file mode 100644 index 747a6b4..0000000 --- a/org.glite.deployment.lb/config/templates/glite-lb.cfg.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - owner - location - destination - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.lb/doc/release_notes/release_notes.doc b/org.glite.deployment.lb/doc/release_notes/release_notes.doc deleted file mode 100644 index dd0cc439dc9ee6f2b756b12a1960e980e7a0c9cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 334848 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 MH}8pm{&5Zb3PZoRsQ>@~ diff --git a/org.glite.deployment.lb/doc/release_notes/release_notes.html b/org.glite.deployment.lb/doc/release_notes/release_notes.html deleted file mode 100644 index 989792a..0000000 --- a/org.glite.deployment.lb/doc/release_notes/release_notes.html +++ /dev/null @@ -1,3368 +0,0 @@ - - - - - -gLite LB Server Release Notes - - - - - - -
- -

gLite Logging & Bookkeeping Server

- -

1. Release Description

- -

This release contains the gLite Logging & Bookkeeping -Server module v. 1.2.2. The following sections provide additional information about -the release content, the module dependencies, the know bugs and issues and a -list of bugs closed since the previous release. For information about -installing and using the gLite Logging & Bookkeeping Server, please refer -to the gLite Installation and User Guides.

- -

2. Changes in this Release

- -

This release introduces the following changes:

- -

 

- -
    -
  • Implemented status method
  • -
  • Added definition of PERL5LIB env var
  • -
  • Stopping and starting the database before the index - creation (just after the database is created and the user granted) to fix - access denied error
  • -
  • Moved creation of indices inside database creation (if - database exists indices must not be recreated)
  • -
  • GLITE_USER parameter is not exposed anymore in the - configuration file; instead the module uses the same user parameters as - WMS to allow installation on same node
  • -
  • LB admin tools are now installed in sbin, not in bin
  • -
  • Bug fixes (see below for the complete lists)
  • -
- -

3. Release contents

- -

The gLite Logging & Bookkeeping Server v. 1.2.2 is -composed of the following gLite components:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Component name

-
-

Version

-
-

File

-
-

org.glite.deployment.lb

-
-

1.2.2

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-lb_installer.sh -

-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/noarch/RPMS/glite-lb-config-1.2.2-1.noarch.rpm

-
-

org.glite.deployment.config

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/noarch/RPMS/glite-config-1.0.0-1.noarch.rpm

-
-

org.glite.lb.client-interface

-
-

1.0.2

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-client-interface-1.0.2-1.i386.rpm

-
-

org.glite.lb.common

-
-

1.1.4

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-common-1.1.4-1.i386.rpm

-
-

org.glite.lb.logger

-
-

1.0.1

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-logger-1.0.1-1.i386.rpm

-
-

org.glite.lb.server

-
-

1.0.1

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-server-1.0.1-1.i386.rpm

-
-

org.glite.lb.server-bones

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-server-bones-1.0.0-1.i386.rpm

-
-

org.glite.lb.ws-interface

-
-

1.0.1

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-ws-interface-1.0.1-1.i386.rpm

-
-

org.glite.security.proxyrenewal

-
-

1.0.11

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-1.0.11-1.i386.rpm

-
-

org.glite.wms-utils.exception

-
-

1.0.1

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-wms-utils-exception-1.0.1-1.i386.rpm

-
-

org.glite.wms-utils.jobid

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-1.0.0-1.i386.rpm

-
-

org.glite.security.voms

-
-

1.2.32

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-security-voms-1.2.32-1.i386.rpm

-
-

org.gridsite.core

-
-

1.1.5

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/gridsite-1.1.5-1.i386.rpm

-
- -

 

- -

4. Dependencies

- -

The gLite Logging & Bookkeeping Server v. 1.2.2 module -has the following dependencies:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Component name

-
-

Version

-
-

RPM file name

-
-

gLite Security Utilities

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-security-utils_installer.sh

-
-

gLite R-GMA Service Publisher

-
-

4.1.5

-
-

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-rgma-servicetool_installer.sh

-
-

GPT

-
-

VDT 1.2.2

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-VDT1.2.2rh9-1.i386.rpm

-
-

VDT Globus Essentials

-
-

VDT 1.2.2

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-VDT1.2.2rh9-1.i386.rpm

-
-

MySQL-server

-
-

4.0.20

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-4.0.20-0.i386.rpm

-
-

MySQL-client

-
-

4.0.20

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-4.0.20-0.i386.rpm

-
-

ares

-
-

1.1.1

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/ares-1.1.1-EGEE.i386.rpm

-
-

myproxy

-
-

1.14

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-1.14-EGEE.i386.rpm

-
-

perl-Expect.pm

-
-

1.01

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/per-Expect.pm-1.01-9.i386.rpm

-
-

Java SDK/JRE

-
-

1.4.2

-
-

http://java.sun.com/j2se/1.4.2/download.html

-
- -

 

- -

5. Known bugs and issues

- -

This release has the -following bugs and issues. Bug numbers refer to the gLite Bug Tracking system -database hosted on the CERN Savannah system at https://savannah.cern.ch/bugs/?group=jra1mdw -.

- -

 

- -
    -
  • No removal procedure is provided - with this release apart from the removal of the RPMS. Any account, group - or other resource created during the module configuration must be manually - cleaned.
  • -
- -

 

- -

Known open bugs:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Bug number

-
-

Description

-
-

 

-
-

 #6412

-
-

--start and --stop options not - documented in glite-ce-config.py, glite-lb-config.py 

-
-

 

-
-

 #7053

-
-

LB configuration fails if the - mysql root pwd is set 

-
-

 

-
-

 #7180

-
-

Logging & Bookkeping UI  

-
-

 

-
-

 #7237

-
-

Intermittent errors with job - submission 

-
-

 

-
-

 #7300

-
-

update of the lb instructions - at the end of the installer script  

-
-

 

-
-

 #7305

-
-

lb.database.username paramenter - in config file 

-
-

 

-
-

 #7307

-
-

lb config script does _not_ - fail if mysql root password is set 

-
-

 

-
-

 #7321

-
-

creation of indices fails - randomly 

-
-

 

-
-

 #7324

-
-

lb-bkserver is running with no - pid 

-
-

 

-
-

 #7389

-
-

LB server and WMS local logger - related issues 

-
-

 

-
- -

 

- -

Bugs fixed in this or previous releases, but not yet officially -tested:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Bug number

-
-

Description

-
-

 

-
-

 #5850

-
-

glite-lb-config.py has - glite.location and globus.location not set in params[] 

-
-

 

-
-

 #5908

-
-

Environment variables set via - the configuration script are not passed to daemon startup scripts 

-
-

 

-
-

 #6075

-
-

glite-lb-config.py crashes with - KeyError: GLITE_CERT_DIR 

-
-

 

-
-

 #6366

-
-

LB install script:: Fails but - no error reported 

-
-

 

-
-

 #6415

-
-

glite-lb-bkserver does not - start and blocks execution of glite-lb-config.py 

-
-

 

-
-

 #6689

-
-

glite-proxy-renewd starts the - daemon glite-proxy-renewd as GLITE_USER which is glite-lb i.e. wrong 

-
-

 

-
-

 #6722

-
-

glite-job-status -all doesn't - work 

-
-

 

-
-

 #7296

-
-

glite-lb-config.py crashes with - a TypeError exception 

-
-

 

-
- -

 

- -

6. Bugs closed since last release

- -

This release fixes the -following bugs and issues. Bug numbers refer to the gLite Bug Tracking system -database hosted on the CERN Savannah system at https://savannah.cern.ch/bugs/?group=jra1mdw

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Bug number

-
-

Description

-
-

 #5833

-
-

all jobs in SUBMITTED after a - job storm 

-
-

 #5897

-
-

I20041203 LB installation - script has a missing dependency  

-
-

 #5910

-
-

glite-lb configuration scripts - don't set GLITE_USER environment 

-
-

 #5925

-
-

Running glite-lb script removes - mysql.sock file  

-
-

 #6416

-
-

the BKserver on the LB machine - needs a symlink and the script doesn't check for it 

-
-

 #7032

-
-

The LB installer fails with an - RPM not found message 

-
-

 #7152

-
-

The LB installer tries to - install gridsite with a wrong rpm name 

-
-

 #7351

-
-

Star/restart of LB services  

-
-

 #7401

-
-

The first time the LB config - script is run it fails creating the db indices 

-
-

 #7423

-
-

'/etc/rc.d/init.d/gLite status' - not working correctly in LB 

-
- -

 

- -
-
- -

7. Previous Releases

- -

7.1. Release 1.1.0

- -

7.1.1. Release Description

- -

This release contains the gLite Logging & Bookkeeping -Server module v. 1.1.0. The following sections provide additional information about -the release content, the module dependencies, the know bugs and issues and a -list of bugs closed since the previous release. For information about -installing and using the gLite Logging & Bookkeeping Server, please refer -to the gLite Installation and User Guides.

- -

7.1.2. Changes in this Release

- -

This release introduces the following changes:

- -

 

- -
    -
  • The gLite init.d script has been added to the deployment - module. The script is installed and activated by the configuration scripts - to start all LB services at boot-time
  • -
  • Bug fixes (see below for the complete lists)
  • -
- -

7.1.3. Release contents

- -

The gLite Logging & Bookkeeping Server v. 1.1.0 is -composed of the following gLite components:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Component name

-
-

Version

-
-

File

-
-

org.glite.deployment.lb

-
-

1.1.0

-
-

http://glite.web.cern.ch/glite/packages/I20050225/installers/glite-lb_installer.sh -

-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/noarch/RPMS/glite-lb-config-1.1.0-1.noarch.rpm

-
-

org.glite.deployment.config

-
-

0.8.2

-
-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/noarch/RPMS/glite- - config-0.8.2-1.noarch.rpm

-
-

org.glite.lb.client-interface

-
-

1.0.1

-
-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/i386/RPMS/glite-lb-client-interface-1.0.1-1.i386.rpm

-
-

org.glite.lb.common

-
-

1.1.3

-
-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/i386/RPMS/glite-lb-common-1.1.3-1.i386.rpm

-
-

org.glite.lb.logger

-
-

1.0.1

-
-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/i386/RPMS/glite-lb-logger-1.0.1-1.i386.rpm

-
-

org.glite.lb.server

-
-

1.0.1

-
-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/i386/RPMS/glite-lb-server-1.0.1-1.i386.rpm

-
-

org.glite.lb.server-bones

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/i386/RPMS/glite-lb-server-bones-1.0.0-1.i386.rpm

-
-

org.glite.lb.ws-interface

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/i386/RPMS/glite-lb-ws-interface-1.0.0-1.i386.rpm

-
-

org.glite.security.proxyrenewal

-
-

1.0.1

-
-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-1.0.1-1.i386.rpm

-
-

org.glite.wms-utils.exception

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/i386/RPMS/glite-wms-utils-exception-1.0.0-1.i386.rpm

-
-

org.glite.wms-utils.jobid

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-1.0.0-1.i386.rpm

-
-

org.glite.security.voms

-
-

1.2.29

-
-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/i386/RPMS/glite-security-voms-1.2.29-22.i386.rpm

-
-

org.gridsite.core

-
-

1.1.5

-
-

http://glite.web.cern.ch/glite/packages/I20050225/bin/rhel30/i386/RPMS/gridsite-1.1.5-1.i386.rpm

-
- -

 

- -

7.1.4. Dependencies

- -

The gLite Logging & Bookkeeping Server module has the -following dependencies:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Component name

-
-

Version

-
-

RPM file name

-
-

gLite Security Utilities

-
-

0.6.1

-
-

http://glite.web.cern.ch/glite/packages/I20050225/installers/glite-security-utils_installer.sh

-
-

gLite R-GMA Service Publisher

-
-

4.1.2

-
-

http://glite.web.cern.ch/glite/packages/I20050225/installers/glite-rgma-servicetool_installer.sh

-
-

GPT

-
-

VDT 1.2.2

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-VDT1.2.0rh9-1.i386.rpm

-
-

VDT Globus Essentials

-
-

VDT 1.2.2

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-VDT1.2.0rh9-1.i386.rpm

-
-

MySQL-server

-
-

4.0.20

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-4.0.20-0.i386.rpm

-
-

MySQL-client

-
-

4.0.20

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-4.0.20-0.i386.rpm

-
-

ares

-
-

1.1.1

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/ares-1.1.1-EGEE.i386.rpm

-
-

myproxy

-
-

1.14

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-1.14-EGEE.i386.rpm

-
-

perl-Expect.pm

-
-

1.01

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/per-Expect.pm-1.01-9.i386.rpm

-
- -

 

- -

7.1.5. Known bugs and issues

- -

This release has the -following bugs and issues. Bug numbers refer to the gLite Bug Tracking system -database hosted on the CERN Savannah system at https://savannah.cern.ch/bugs/?group=jra1mdw -.

- -

 

- -
    -
  • No removal procedure is provided - with this release apart from the removal of the RPMS. Any account, group - or other resource created during the module configuration must be manually - cleaned.
  • -
  • No inet.d scripts are installed or - activated in this release. This will be fixed in the next release
  • -
- -

 

- -

Known open bugs:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Bug number

-
-

Description

-
-

 

-
-

 #6057

-
-

glite-lb configuration scripts - has missing dependency (CGI.pm) 

-
-

 

-
-

 #6415

-
-

glite-lb-bkserver does not - start and blocks execution of glite-lb-config.py 

-
-

 

-
-

 #6722

-
-

glite-job-status -all doesn't - work 

-
-

 

-
-

 #6838

-
-

There are no test reports - provided for the L&B Server in gLite v1.0.6 RC1 (Integration Build - I20050204) 

-
-

 

-
-

 #7032

-
-

The LB installer fails with an - RPM not found message 

-
-

 

-
-

 #7039

-
-

Problem if LD_LIBRARY_PATH is - unset 

-
-

 

-
-

 #7053

-
-

LB configuration fails if the - mysql root pwd is set 

-
-

 

-
-

 #7180

-
-

Logging & Bookkeping UI  

-
-

 

-
- -

 

- -

Bugs fixed in this or previous releases, but not yet tested:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Bug number

-
-

Description

-
-

 

-
-

 #5833

-
-

all jobs in SUBMITTED after a - job storm 

-
-

 

-
-

 #5850

-
-

glite-lb-config.py has - glite.location and globus.location not set in params[] 

-
-

 

-
-

 #5897

-
-

I20041203 LB installation - script has a missing dependency  

-
-

 

-
-

 #5901

-
-

mysqlaccess command fails with - Broken pipe if mysql socket file is in /tmp  

-
-

 

-
-

 #5908

-
-

Environment variables set via - the configuration script are not passed to daemon startup scripts 

-
-

 

-
-

 #5910

-
-

glite-lb configuration scripts - don't set GLITE_USER environment 

-
-

 

-
-

 #5925

-
-

Running glite-lb script removes - mysql.sock file  

-
-

 

-
-

 #6075

-
-

glite-lb-config.py crashes with - KeyError: GLITE_CERT_DIR 

-
-

 

-
-

 #6366

-
-

LB install script:: Fails but - no error reported 

-
-

 

-
-

 #6412

-
-

--start and --stop options not - documented in glite-ce-config.py, glite-lb-config.py 

-
-

 

-
-

 #6416

-
-

the BKserver on the LB machine - needs a symlink and the script doesn't check for it 

-
-

 

-
- -

 

- -

7.1.6. Bugs closed since last release

- -

This release fixes the -following bugs and issues. Bug numbers refer to the gLite Bug Tracking system -database hosted on the CERN Savannah system at https://savannah.cern.ch/bugs/?group=jra1mdw

- -

 

- - - - - - -
-

Bug number

-
-

Description

-
- -

 

- -

7.2. Release 1.0.0

- -

7.2.1. Release Description

- -

This release contains the gLite Logging & Bookkeeping -Server module v. 1.0.0. The following sections provide additional information -about the release content, the module dependencies, the know bugs and issues -and a list of bugs closed since the previous release. For information about -installing and using the gLite Logging & Bookkeeping Server, please refer -to the gLite Installation and User Guides.

- -

7.2.2. Changes in this Release

- -

This release doesn’t contain any functional changes. It -contains a number of bug fixes in the components and the deployment module to -be submitted to testing.

- -

However, the version number has been changed to match the -final release number 1.0.0.

- -

7.2.3. Release contents

- -

The gLite Logging & Bookkeeping Server v. 0.3.1 is -composed of the following gLite components:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Component name

-
-

Version

-
-

File

-
-

org.glite.deployment.lb

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050114/installers/glite-lb_installer.sh -

-

http://glite.web.cern.ch/glite/packages/I20050114/bin/rhel30/noarch/RPMS/glite-lb-config-1.0.0-1.noarch.rpm

-
-

org.glite.deployment.config

-
-

0.4.1

-
-

http://glite.web.cern.ch/glite/packages/I20050114/bin/rhel30/noarch/RPMS/glite- - config-0.4.1-1.noarch.rpm

-
-

glite-lb-client-interface

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050114/bin/rhel30/i386/RPMS/glite-lb-client-interface-1.0.0-1.i386.rpm

-
-

glite-lb-common

-
-

1.1.0

-
-

http://glite.web.cern.ch/glite/packages/I20050114/bin/rhel30/i386/RPMS/glite-lb-common-1.1.0-1.i386.rpm

-
-

glite-lb-logger

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050114/bin/rhel30/i386/RPMS/glite-lb-logger-1.0.0-1.i386.rpm

-
-

glite-lb-server

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050114/bin/rhel30/i386/RPMS/glite-lb-server-1.0.0-1.i386.rpm

-
-

glite-lb-server-bones

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050114/bin/rhel30/i386/RPMS/glite-lb-server-bones-1.0.0-1.i386.rpm

-
-

glite-lb-ws-interface

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050114/bin/rhel30/i386/RPMS/glite-lb-ws-interface-1.0.0-1.i386.rpm

-
-

glite-security-proxyrenewal

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050114/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-1.0.0-1.i386.rpm

-
-

glite-wms-utils-exception

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050114/bin/rhel30/i386/RPMS/glite-wms-utils-exception-1.0.0-1.i386.rpm

-
-

glite-wms-utils-jobid

-
-

1.0.0

-
-

http://glite.web.cern.ch/glite/packages/I20050114/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-1.0.0-1.i386.rpm

-
- -

 

- -

7.2.4. Dependencies

- -

The gLite Logging & Bookkeeping Server module has the -following dependencies:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Component name

-
-

Version

-
-

RPM file name

-
-

gLite Security Utilities

-
-

0.4.0

-
-

http://glite.web.cern.ch/glite/packages/I20050114/installers/glite-security-utils_installer.sh

-
-

GPT

-
-

VDT 1.2.0

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-VDT1.2.0rh9-1.i386.rpm

-
-

VDT Globus Essentials

-
-

VDT 1.2.0

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-VDT1.2.0rh9-1.i386.rpm

-
-

MySQL-server

-
-

4.0.20

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-4.0.20-0.i386.rpm

-
-

MySQL-client

-
-

4.0.20

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-4.0.20-0.i386.rpm

-
-

ares

-
-

1.1.1

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/ares-1.1.1-EGEE.i386.rpm

-
-

myproxy

-
-

1.14

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-1.14-EGEE.i386.rpm

-
-

perl-Expect.pm

-
-

1.01

-
-

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/per-Expect.pm-1.01-9.i386.rpm

-
- -

 

- -

7.2.5. Known bugs and issues

- -

This release has the -following bugs and issues. Bug numbers refer to the gLite Bug Tracking system -database hosted on the CERN Savannah system at https://savannah.cern.ch/bugs/?group=jra1mdw -.

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Bug number

-
-

Description

-
-

 #5202

-
-

no RPM provides the - lb-local-logger daemon -  

-
-

 #5248

-
-

When running - "glite-lb-bkserverd start", glite-lb-bkserverd doesn't start in - background 

-
-

 #5833

-
-

all jobs in SUBMITTED after a - job storm 

-
-

 #5850

-
-

glite-lb-config.py has - glite.location and globus.location not set in params[] 

-
-

 #5897

-
-

I20041203 LB installation - script has a missing dependency  

-
-

 #5900

-
-

location of mysql.sock file  

-
-

 #5901

-
-

mysqlaccess command fails with - Broken pipe if mysql socket file is in /tmp

-
-

 #5903

-
-

glite-lb-bkserverd script gives - bash: /root/.bashrc: Permission denied error  

-
-

 #5904

-
-

glite-lb-bkserverd does not - check default location for credentials 

-
-

#5910

-
-

glite-lb configuration scripts - don't set GLITE_USER environment 

-
-

 #5925

-
-

Running glite-lb script removes - mysql.sock file  

-
-

 #5926

-
-

Default user should not be used - in the init.d scripts 

-
-

 #5932

-
-

credential file created in - /var/tmp is unnecessary 

-
-

 #5934

-
-

service start and stop - notifications are inconsistent for glite-lb-bkserverd init,d script 

-
-

 #6057

-
-

glite-lb configuration scripts - has missing dependency (CGI.pm) 

-
-

#6075

-
-

glite-lb-config.py crashes with - KeyError: GLITE_CERT_DIR 

-
- -

 

- -

No removal procedure is -provided with this release apart from the removal of the RPMS. Any account, -group or other resource created during the module configuration must be -manually cleaned.

- -

 

- -

7.2.6. Bugs closed since last release

- -

This release fixes the -following bugs and issues. Bug numbers refer to the gLite Bug Tracking system -database hosted on the CERN Savannah system at https://savannah.cern.ch/bugs/?group=jra1mdw

- -

 

- - - - - - -
-

Bug number

-
-

Description

-
- -

 

- -

 

- -
- - - - diff --git a/org.glite.deployment.lb/doc/release_notes/release_notes.pdf b/org.glite.deployment.lb/doc/release_notes/release_notes.pdf deleted file mode 100644 index 4b071fabd9aae0a6c4eeada184a589162f22e6f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 277829 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�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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.lb/project/glite-lb.spec b/org.glite.deployment.lb/project/glite-lb.spec deleted file mode 100644 index a4bc55e..0000000 --- a/org.glite.deployment.lb/project/glite-lb.spec +++ /dev/null @@ -1,46 +0,0 @@ -Summary:gLite LB node installation package -Name:glite-lb-config -Version:@MODULE.VERSION@ -Release:@MODULE.BUILD@ -Copyright:Open Source EGEE License -Vendor:EU EGEE project -Group:System/Application -Prefix:/opt/glite -BuildArch:noarch -BuildRoot:%{_builddir}/%{name}-%{version} -Requires: glite-config, glite-rgma-servicetool-config, glite-lb-client-interface, glite-lb-ws-interface, glite-lb-logger, glite-lb-common, glite-lb-server, glite-lb-server-bones, glite-wms-utils-jobid, glite-wms-utils-exception, glite-security-proxyrenewal, glite-security-voms, gridsite, MySQL-server, MySQL-client, ares, vdt_globus_essentials, gpt, myproxy, perl-Expect.pm - -AutoReqProv:no -Source:glite-lb.tar.gz -%define debug_package %{nil} - -%description -gLite Logging and Bookkeeping node installation package - -%prep - - -%setup -c - -%build - - -%install - - -%clean - -%pre -%post -#echo "post install script" -%preun -%postun -%files -%attr(755,root,root) %{prefix}/etc/config/scripts/glite-lb-config.py -%attr(644,root,root) %{prefix}/etc/config/templates/glite-lb.cfg.xml -%attr(644,root,root) %{prefix}/share/doc/glite-lb/release_notes/release_notes.doc -%attr(644,root,root) %{prefix}/share/doc/glite-lb/release_notes/release_notes.pdf -%attr(644,root,root) %{prefix}/share/doc/glite-lb/release_notes/release_notes.html - -%changelog - diff --git a/org.glite.deployment.lb/project/lxscript-rpm.xsl b/org.glite.deployment.lb/project/lxscript-rpm.xsl deleted file mode 100644 index e20f297..0000000 --- a/org.glite.deployment.lb/project/lxscript-rpm.xsl +++ /dev/null @@ -1,334 +0,0 @@ - - - - - - - - - - - - - -#!/bin/sh - -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html - -# glite-lb_installer v. -# -# The glite-lb_installer installs the gLite Logging and Bookkeeping Server -# -# Usage: glite-lb_installer [-u|-v|--help] -# -u uninstall -# -v print version -# --help print script usage info -# Return codes: 0 - Ok -# 1 - if a file could not be downloaded - -############################################################################### - -#Parse the RPMLIST to strip out the RPMS that are already installed -function parseRPMList() -{ - newRPMLIST="" - localRPMLIST=`rpm -qa` - for i in $RPMLIST - do - g=`echo $i | sed -e 's/\.i386\.rpm//g'` - g=`echo $g | sed -e 's/\.noarch\.rpm//g'` - if [ -z "`echo $localRPMLIST | grep $g`" ]; then - newRPMLIST="${newRPMLIST} $i" - else - echo "$i is already installed. It will be skipped." - fi - done - - RPMLIST=$newRPMLIST -} - -#Parse the SCRIPTLIST to execute all scripts -function parseScriptList() -{ - for i in $SCRIPTLIST - do - if [ "$INSTALL" = "true" ]; then - $i - else - $i -u - fi - done -} - -#Downloads and install the module RPMS -function install() -{ - - INSTALL=true - version - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, downloading the gLite Logging and Bookkeeping Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - - mkdir -p glite-lb - cd glite-lb - - # Download global dependencies - - - true - - - - - - # Download scripts from repository - - - true - - - - - # Download dependencies RPMS from repository - - - true - - - - # Download RPMS from repository - - - true - - - - - - # Download and install subservices - parseScriptList - - - # Install all RPMS - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, installing the gLite Logging and Bookkeeping Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - parseRPMList - if [ ! -z "$RPMLIST" ]; then - rpm -Uvh $RPMLIST - rpm_return=$? - else - echo All required RPMS are already installed - rpm_return=0 - fi - if [ "$rpm_return" == "0" ]; then - echo - echo Done! - echo - echo Before using the gLite LB, please create or update the configuration - echo file /opt/glite/etc/config/glite-lb.cfg.xml - echo and run the configuration script - echo /opt/glite/etc/config/scripts/glite-lb-config.py. - echo A template is provided in - echo /opt/glite/etc/config/templates/glite-lb.cfg.xml - else - echo - echo An error occurred while installing the LB RPMS. - echo Most likely one or more of the RPMS to be installed require - echo additional dependencies or are older than already installed packages. - echo Please refer to the rpm error message above for more details. - fi - echo - echo For more information refer to the gLite Installation and User Guides - echo or to the gLite web site \(http:\/\/www.glite.org\) - echo Please report problems and comments to the gLite Team at - echo project-eu-egee-glite-bugs@cern.ch - - cd .. -} - -############################################################################### -function uninstall() -{ - version - - # Global dependencies - - - false - - - - - - # dependencies RPMS from repository - - - false - - - - # RPMS from repository - - - false - - - - - - # Uninstall all RPMS - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, uninstalling the gLite Logging and Bookkeeping Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - rpm -ev $RPMLIST - if [ "$?" == "0" ]; then - echo - echo Done! - else - echo - echo An error occurred while removing the LB RPMS. - echo Most likely one or more of the RPMS to be removed have - echo dependent packages. - echo Please refer to the rpm error message above for more details. - fi -} - -############################################################################### -function usage() -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-lb_installer v. - echo - echo The glite-lb_installer installs the gLite Logging and Bookkeeping Server - echo - echo Usage: glite-lb_installer \[-u\|-v\|--help\] - echo -u uninstall - echo -v print version - echo --help print script usage info - echo - echo Return codes: - echo 0 - Ok - echo 1 - if a file could not be downloaded - echo -} - -############################################################################### -function version -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-lb_installer v. - echo -} - - -RPMLIST= - -############################################################################### -# Main - -while getopts uvh opt -do - case $opt in - 'u') uninstall - exit 0 - ;; - 'v') version - exit 0 - ;; - 'h') usage - exit 0 - ;; - esac -done - -install - -exit 0 - - - - - _installer.sh - - -wget -N --non-verbose -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -chmod u+x -SCRIPTLIST="$SCRIPTLIST ./" - - -SCRIPTLISTUn="$SCRIPTLISTUn ./ -u " - - - - - - - - --..rpm - -- - - -wget -N --non-verbose -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - - - --..rpm - -- - - -wget -N --non-verbose /RPMS/ -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - diff --git a/org.glite.deployment.lb/project/lxscript-tgz.xsl b/org.glite.deployment.lb/project/lxscript-tgz.xsl deleted file mode 100644 index 5b55e40..0000000 --- a/org.glite.deployment.lb/project/lxscript-tgz.xsl +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - -#!/bin/sh -# -# glite-lb_tgz_installer -# usage: glite-lb_tgz_installer [-u] -# -u uninstall -# -# glite-lb_tgz_installer installs the gLite Deployment Unit from biniary tarballs -# - -PREFIX=/opt/glite - -############################################################################### -# Download global dependencies - - - -############################################################################### - - -############################################################################### -# Download dependencies RPMS from repository - - - -############################################################################### -# Download RPMS from repository - - - -############################################################################### - - - - - - --..rpm -wget - - - - -_bin.tar.gz -wget i386/tgz/ -tar -xzf $PREFIX - - - diff --git a/org.glite.deployment.lb/project/properties.xml b/org.glite.deployment.lb/project/properties.xml deleted file mode 100644 index 638f02b..0000000 --- a/org.glite.deployment.lb/project/properties.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.lb/project/quattor-template.xsl b/org.glite.deployment.lb/project/quattor-template.xsl deleted file mode 100644 index e0bd623..0000000 --- a/org.glite.deployment.lb/project/quattor-template.xsl +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - -template pro_software_glite_lb; - -# -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html -# -# glite-lb Quattor template v. -# - -# Global dependencies - - - - - - -# dependencies - - - - -# RPMS - - - - - - - - -"/software/packages"=pkg_repl("","-",""); - - - -"/software/packages"=pkg_repl("","-",""); - - - diff --git a/org.glite.deployment.lb/project/version.properties b/org.glite.deployment.lb/project/version.properties deleted file mode 100644 index 66a3e69..0000000 --- a/org.glite.deployment.lb/project/version.properties +++ /dev/null @@ -1,4 +0,0 @@ - -module.version = 1.3.0 -module.age = 1 - \ No newline at end of file diff --git a/org.glite.jp.common/.cvsignore b/org.glite.jp.common/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp.common/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp.common/Makefile b/org.glite.jp.common/Makefile deleted file mode 100644 index 3f84bcd..0000000 --- a/org.glite.jp.common/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -# defaults -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -lbprefix=lb -package=glite-jp-common -version=0.0.0 -PREFIX=/opt/glite - -glite_location=/opt/glite -globus_prefix=/opt/globus -nothrflavour=gcc32 -thrflavour=gcc32pthr -expat_prefix=/opt/expat -ares_prefix=/opt/ares -gsoap_prefix=/software/gsoap-2.6 - -CC=gcc - --include Makefile.inc - - -VPATH=${top_srcdir}/src:${top_srcdir}/test:${top_srcdir}/project:${jpproject} - -GLOBUSINC:= -I${globus_prefix}/include/${nothrflavour} - - -DEBUG:=-g -O0 -CFLAGS:=${DEBUG} -I. -I${top_srcdir}/interface -I${stagedir}/include \ - ${GLOBUSINC} - -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -rpath ${stagedir}/lib -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install -COMPILE:=libtool --mode=compile ${CC} ${CFLAGS} - -HDRS:=types.h context.h strmd5.h - -SRCS:=context.c strmd5.c attr.c -OBJS:=${SRCS:.c=.lo} - -commonlib:= libglite_jp_common.la - -default all: compile - -compile: ${commonlib} - -${commonlib}: ${OBJS} - ${LINK} -o $@ ${OBJS} - -check: - -echo nothing yet - -doc: - -stage: compile - $(MAKE) install PREFIX=${stagedir} - -install: - -mkdir -p ${PREFIX}/include/${globalprefix}/${jpprefix} - cd ${top_srcdir}/interface && install -m 644 ${HDRS} ${PREFIX}/include/${globalprefix}/${jpprefix} - -mkdir -p ${PREFIX}/lib - ${INSTALL} -m 755 ${commonlib} ${PREFIX}/lib - -dist: distsrc distbin - -# FIXME: just copied from LB -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -clean: - -%.lo: %.c - ${COMPILE} -o $@ -c $< diff --git a/org.glite.jp.common/build.xml b/org.glite.jp.common/build.xml deleted file mode 100755 index f20263f..0000000 --- a/org.glite.jp.common/build.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.common/interface/context.h b/org.glite.jp.common/interface/context.h deleted file mode 100644 index 20effb2..0000000 --- a/org.glite.jp.common/interface/context.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __GLITE_JP_CONTEXT -#define __GLITE_JP_CONTEXT - -int glite_jp_init_context(glite_jp_context_t *); -void glite_jp_free_query_rec(glite_jp_query_rec_t *); - -char *glite_jp_peer_name(glite_jp_context_t); -char *glite_jp_error_chain(glite_jp_context_t); - -int glite_jp_stack_error(glite_jp_context_t, const glite_jp_error_t *); -int glite_jp_clear_error(glite_jp_context_t); - -int glite_jp_add_deferred(glite_jp_context_t,int (*)(glite_jp_context_t,void *),void *); -int glite_jp_run_deferred(glite_jp_context_t); - - -#endif diff --git a/org.glite.jp.common/interface/strmd5.h b/org.glite.jp.common/interface/strmd5.h deleted file mode 100755 index c5d76b6..0000000 --- a/org.glite.jp.common/interface/strmd5.h +++ /dev/null @@ -1,28 +0,0 @@ -#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 */ diff --git a/org.glite.jp.common/interface/types.h b/org.glite.jp.common/interface/types.h deleted file mode 100644 index 516db1a..0000000 --- a/org.glite.jp.common/interface/types.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef __GLITE_JP_TYPES -#define __GLITE_JP_TYPES - -#include - -typedef struct _glite_jp_error_t { - int code; - const char *desc; - const char *source; - struct _glite_jp_error_t *reason; -} glite_jp_error_t; - -typedef struct _glite_jp_context { - glite_jp_error_t *error; - int (**deferred_func)(struct _glite_jp_context *,void *); - void **deferred_arg; - void *feeds; - struct soap *other_soap; - char *peer; - void **plugins; - void *db_handle; -} *glite_jp_context_t; - -typedef enum { - GLITE_JP_FILECLASS_UNDEF, - GLITE_JP_FILECLASS_INPUT, - GLITE_JP_FILECLASS_OUTPUT, - GLITE_JP_FILECLASS_LBLOG, - GLITE_JP_FILECLASS_TAGS, - GLITE_JP_FILECLASS__LAST -} glite_jp_fileclass_t; - -typedef struct { - char *name; - int sequence; - time_t timestamp; - int binary; - size_t size; - char *value; -} glite_jp_tagval_t; - -typedef enum { - GLITE_JP_ATTR_UNDEF, - GLITE_JP_ATTR_OWNER, - GLITE_JP_ATTR_TIME, - GLITE_JP_ATTR_TAG, - GLITE_JP_ATTR_GENERIC, - GLITE_JP_ATTR__LAST -} glite_jp_attrtype_t; - -typedef struct { - glite_jp_attrtype_t type; - char *name,*namespace; -} glite_jp_attr_t; - -typedef struct { - glite_jp_attr_t attr; - union { - char *s; - int i; - struct timeval time; - glite_jp_tagval_t tag; - } value; -} glite_jp_attrval_t; - - -typedef enum { - GLITE_JP_QUERYOP_UNDEF, - GLITE_JP_QUERYOP_EQUAL, - GLITE_JP_QUERYOP_UNEQUAL, - GLITE_JP_QUERYOP_LESS, - GLITE_JP_QUERYOP_GREATER, - GLITE_JP_QUERYOP_WITHIN, - GLITE_JP_QUERYOP__LAST, -} glite_jp_queryop_t; - -typedef struct { - glite_jp_attr_t attr; - glite_jp_queryop_t op; - union _glite_jp_query_rec_val { - char *s; - int i; - struct timeval time; - } value,value2; -} glite_jp_query_rec_t; - -void glite_jp_attrval_free(glite_jp_attrval_t *,int); - -#endif diff --git a/org.glite.jp.common/project/build.number b/org.glite.jp.common/project/build.number deleted file mode 100644 index c680c72..0000000 --- a/org.glite.jp.common/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build=36 diff --git a/org.glite.jp.common/project/build.properties b/org.glite.jp.common/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp.common/project/configure.properties.xml b/org.glite.jp.common/project/configure.properties.xml deleted file mode 100644 index 5f0ea37..0000000 --- a/org.glite.jp.common/project/configure.properties.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -jpprefix=${subsystem.prefix} -package=${module.package.name} -PREFIX=${install.dir} -version=${module.version} -glite_location=${with.glite.location} -globus_prefix=${with.globus.prefix} -expat_prefix=${with.expat.prefix} -gsoap_prefix=${with.gsoap.prefix} -ares_prefix=${with.ares.prefix} -thrflavour=${with.globus.thr.flavor} -nothrflavour=${with.globus.nothr.flavor} -cppunit=${with.cppunit.prefix} -jpproject=${subsystem.project.dir} -project=${component.project.dir} - - - diff --git a/org.glite.jp.common/project/properties.xml b/org.glite.jp.common/project/properties.xml deleted file mode 100755 index b9d669d..0000000 --- a/org.glite.jp.common/project/properties.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.common/project/tar_exclude b/org.glite.jp.common/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.jp.common/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.jp.common/project/version.properties b/org.glite.jp.common/project/version.properties deleted file mode 100644 index cd1e9e7..0000000 --- a/org.glite.jp.common/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.0.0 -module.age=1 diff --git a/org.glite.jp.common/src/attr.c b/org.glite.jp.common/src/attr.c deleted file mode 100644 index fcef59c..0000000 --- a/org.glite.jp.common/src/attr.c +++ /dev/null @@ -1,18 +0,0 @@ -#include - -#include "types.h" - -void glite_jp_attrval_free(glite_jp_attrval_t *a,int f) -{ - free(a->attr.name); - - switch (a->attr.type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TAG: - free(a->value.s); - break; - default: break; - } - - if (f) free(a); -} diff --git a/org.glite.jp.common/src/context.c b/org.glite.jp.common/src/context.c deleted file mode 100644 index 057aad0..0000000 --- a/org.glite.jp.common/src/context.c +++ /dev/null @@ -1,164 +0,0 @@ -#include -#include - -#include "types.h" -#include "context.h" - -int glite_jp_init_context(glite_jp_context_t *ctx) -{ - *ctx = calloc(1,sizeof **ctx); -} - -char *glite_jp_peer_name(glite_jp_context_t ctx) -{ - return strdup(ctx->peer ? ctx->peer : "unknown"); -} - -char *glite_jp_error_chain(glite_jp_context_t ctx) -{ - char *ret = NULL,indent[300] = ""; - int len = 0,add; - char buf[2000]; - - glite_jp_error_t *ep = ctx->error; - - do { - add = snprintf(buf,sizeof buf,"%s%s: %s (%s)\n", - indent, - ep->source, - strerror(ep->code), - ep->desc ? ep->desc : ""); - ret = realloc(ret,len + add + 1); - strncpy(ret + len,buf,add); ret[len += add] = 0; - strcat(indent," "); - } while (ep = ep->reason); - - return ret; -} - -int glite_jp_stack_error(glite_jp_context_t ctx, const glite_jp_error_t *err) -{ - glite_jp_error_t *reason = ctx->error; - - ctx->error = calloc(1,sizeof *ctx->error); - ctx->error->code = err->code; - ctx->error->desc = err->desc ? strdup(err->desc) : NULL; - ctx->error->source = err->source ? strdup(err->source) : NULL; - ctx->error->reason = reason; - - return err->code; -} - -int glite_jp_clear_error(glite_jp_context_t ctx) -{ - glite_jp_error_t *e = ctx->error, *r; - - while (e) { - r = e->reason; - free(e->source); - free(e->desc); - free(e); - e = r; - } - ctx->error = NULL; - return 0; -} - - -void glite_jp_free_query_rec(glite_jp_query_rec_t *q) -{ - free(q->attr.name); q->attr.name = NULL; - switch (q->attr.type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TAG: - free(q->value.s); q->value.s = NULL; - if (q->op == GLITE_JP_QUERYOP_WITHIN) { - free(q->value2.s); - q->value2.s = NULL; - } - break; - default: break; - } -} - -int glite_jp_attr_copy(glite_jp_attr_t *dst,const glite_jp_attr_t *src) -{ - dst->name = src->name ? strdup(src->name) : NULL; - dst->type = src->type; - return 0; -} - -int glite_jp_queryrec_copy(glite_jp_query_rec_t *dst, const glite_jp_query_rec_t *src) -{ - glite_jp_attr_copy(&dst->attr,&src->attr); - dst->op = src->op; - switch (src->attr.type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TAG: - dst->value.s = strdup(src->value.s); - if (dst->op == GLITE_JP_QUERYOP_WITHIN) - dst->value2.s = strdup(src->value2.s); - break; - case GLITE_JP_ATTR_TIME: - memcpy(&dst->value.time,&src->value.time,sizeof dst->value.time); - if (dst->op == GLITE_JP_QUERYOP_WITHIN) - memcpy(&dst->value2.time,&src->value2.time,sizeof dst->value2.time); - break; - } - return 0; -} - -int glite_jp_run_deferred(glite_jp_context_t ctx) -{ - int i,cnt,ret; - - if (!ctx->deferred_func) return 0; - - glite_jp_clear_error(ctx); - for (cnt=0;ctx->deferred_func[cnt];cnt++); - for (i=0; ideferred_func)(ctx,*ctx->deferred_arg)) { - glite_jp_error_t err; - char desc[100]; - - sprintf(desc,"calling func #%d, %p",i,*ctx->deferred_func); - err.code = ret; - err.desc = desc; - err.source = "glite_jp_run_deferred()"; - - glite_jp_stack_error(ctx,&err); - return ret; - } - else { - memmove(ctx->deferred_func,ctx->deferred_func+1, - (cnt-i) * sizeof *ctx->deferred_func); - memmove(ctx->deferred_arg,ctx->deferred_arg+1, - (cnt-i) * sizeof *ctx->deferred_arg); - } - } - free(ctx->deferred_func); ctx->deferred_func = NULL; - free(ctx->deferred_arg); ctx->deferred_arg = NULL; - return 0; -} - -int glite_jp_add_deferred( - glite_jp_context_t ctx, - int (*func)(glite_jp_context_t, void *), - void *arg -) -{ - int (**v)(glite_jp_context_t, void *) = ctx->deferred_func; - int i; - - for (i=0; v && *v; i++); - - ctx->deferred_func = realloc(ctx->deferred_func, (i+1) * sizeof *ctx->deferred_func); - ctx->deferred_func[i] = func; - ctx->deferred_func[i+1] = NULL; - - ctx->deferred_arg = realloc(ctx->deferred_arg,(i+1) * sizeof *ctx->deferred_arg); - ctx->deferred_arg[i] = arg; - ctx->deferred_arg[i+1] = NULL; - - return 0; -} diff --git a/org.glite.jp.common/src/strmd5.c b/org.glite.jp.common/src/strmd5.c deleted file mode 100755 index 87fd400..0000000 --- a/org.glite.jp.common/src/strmd5.c +++ /dev/null @@ -1,115 +0,0 @@ -#include -#include -#include -#include - -#include "strmd5.h" - -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); -} diff --git a/org.glite.jp.index/.cvsignore b/org.glite.jp.index/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp.index/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp.index/Makefile b/org.glite.jp.index/Makefile deleted file mode 100644 index 3b893cd..0000000 --- a/org.glite.jp.index/Makefile +++ /dev/null @@ -1,129 +0,0 @@ -# defaults -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -lbprefix=lb -package=glite-lb-server -version=0.0.0 -PREFIX=/opt/glite - -glite_location=/opt/glite -globus_prefix=/opt/globus -nothrflavour=gcc32 -thrflavour=gcc32pthr -expat_prefix=/opt/expat -ares_prefix=/opt/ares -gsoap_prefix=/software/gsoap-2.6 - -CC=gcc - --include Makefile.inc - - -VPATH=${top_srcdir}/src:${top_srcdir}/examples:${top_srcdir}/test:${top_srcdir}/project:${jpproject} - -GLOBUS_LIBS:=-L${globus_prefix}/lib \ - -lglobus_common_${nothrflavour} \ - -lglobus_gssapi_gsi_${nothrflavour} - -DEBUG:=-g -O0 -DDEBUG - -CFLAGS:=${DEBUG} -I. -I${gsoap_prefix}/include -I${stagedir}/include -LDFLAGS:=-L${stagedir}/lib - -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install - - -daemon:=glite-jp-indexd -example:=jpis-test -soap_prefix:=jpis_ - -SRCS:= simple_server.c soap_ops.c \ - ${soap_prefix}C.c \ - ${soap_prefix}Server.c - -EXA_SRCS:=jpis-test.c ${soap_prefix}C.c ${soap_prefix}Client.c - - -OBJS:=${SRCS:.c=.o} stdsoap2.o -EXA_OBJS:=${EXA_SRCS:.c=.o} stdsoap2.o - -COMMONLIB:=-lglite_jp_common - -default all: compile - -compile: ${daemon} ${example} - -${daemon}: ${OBJS} - ${LINK} -o $@ ${OBJS} ${COMMONLIB} ${GLOBUS_LIBS} - -${example}: ${EXA_OBJS} - ${LINK} -o $@ ${EXA_OBJS} - -JobProvenanceIS.xh: JobProvenanceIS.wsdl JobProvenanceTypes.wsdl typemap.dat - cp ${jpproject}/JobProvenanceTypes.wsdl . - ${gsoap_prefix}/bin/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $< - rm -f JobProvenanceTypes.wsdl - -${soap_prefix}C.c ${soap_prefix}H.h: JobProvenanceIS.xh - ${gsoap_prefix}/bin/soapcpp2 -w -c -p ${soap_prefix} JobProvenanceIS.xh - -#$(SOAP_PREFIX)H.h $(SOAP_PREFIX)C.c: LB.xh -# $(GSOAP_BIN_PATH)/soapcpp2 -w -c -p $(SOAP_PREFIX) LB.xh -# -#LB.xh: LB.wsdl typemap.dat -# $(GSOAP_BIN_PATH)/wsdl2h -c -o $@ LB.wsdl -# - - -check: - -echo nothing yet - -doc: - -stage: compile - ${INSTALL} -m 755 ${daemon} ${stagedir}/bin - -dist: distsrc distbin - -# FIXME: just copied from LB -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -install: - -mkdir -p ${PREFIX}/bin ${PREFIX}/etc ${PREFIX}/etc/init.d - for p in bkserverd bkindex; do \ - ${INSTALL} -m 755 "glite_lb_$$p" "${PREFIX}/bin/glite-lb-$$p"; \ - done - - for f in dbsetup.sql index.conf.template; do \ - ${INSTALL} -m 644 ${top_srcdir}/config/"glite-lb-$$f" ${PREFIX}/etc; \ - done - - ${INSTALL} -m 755 ${top_srcdir}/config/startup ${PREFIX}/etc/init.d/glite-lb-bkserverd - -clean: - -soap_ops.o jpis-test.o simple_server.o: ${soap_prefix}H.h - -# we have no real config.h but have to force gSoap not to use -# linux ftime with broken (aka obsolete) DST information - -stdsoap2.o: ${gsoap_prefix}/devel/stdsoap2.c - test -f config.h || touch config.h - @echo 'The following warning "time_t (de)serialization is not MT safe on this platform" is harmless' - ${CC} -o $@ -c -DHAVE_CONFIG_H ${CFLAGS} ${gsoap_prefix}/devel/stdsoap2.c - diff --git a/org.glite.jp.index/build.xml b/org.glite.jp.index/build.xml deleted file mode 100755 index 547659a..0000000 --- a/org.glite.jp.index/build.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.index/project/JobProvenanceIS.wsdl b/org.glite.jp.index/project/JobProvenanceIS.wsdl deleted file mode 100644 index 26f97a4..0000000 --- a/org.glite.jp.index/project/JobProvenanceIS.wsdl +++ /dev/null @@ -1,531 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Register job with JP primary storage. -Job registration in LB is propagated to JP immediately so that JP is aware of the job, -despite no furhter information is available in it. - -Input: JobId - -Output: N/A - -Faults: GenericJPFault - - - - - - - Initiate upload of of sandbox/dump of job life log from LB. -WM component responsible for job sandbox management and LB server call JP to declare -intention to upload intput/output sandbox and job life log. - -Input: - -uclass: type of the upload - INPUT_SANDBOX, OUTPUT_SANDBOX, JOB_LOG - -commitTimeout: upper limit on time for which JP waits for committing this upload transaction - -contentType: MIME type of the uploaded file - -Output: - -destination: URL where the client should upload the file - -commitBefore: acutual time when the upload transaction times out - -Faults: GenericJPFault - - -Initiate upload of of sandbox/dump of job life log from LB. - - - - - - Confirm upload. -Should be called after a file upload initiaded with StartUpload is finished. - -Input: - -destination: Upload destination URL (to match with the original request) - -Output: - -Faults: GenericJPFault - - - - - - - Record a value of user tag. -JP tags are either standalone or override values of their LB counterparts. -However, JP tag values are still distinguishable those inherited from LB. -JP tags may be either strings or blobs. - -Input: - -jobid: - -tag: structure containing name, timestamp, optional sequence number to order tag values -without relying on timestamps, and string or blob value. - -Output: N/A - -Faults: GenericJPFault - - - - - - - Start feeding JP index server. -Called by the index server to start batch feed, and optionally also subscribe for incremental feed. - -JP index server subscribes with JP primary storage using a query -containing conditions on primary metadata and a list of queryable attributes -of the index server (i.e. data which should be sent to the index server). - -When a matching job record is created or modified within the primary storage -the job record data are sent to the subscribed index server. - -The subscription is soft-state, it expires after certain time unless refreshed by the client explicitely. - -In the batch mode the query has the same form -with additional flag asking for all matching records (i.e.\ not only -arriving afterwards). - -Input: - -destination: where to send the job record data - -attributes: which job record attributes should be sent to the requesting index server - -conditions: list of query conditions. Each conditions has the form Attribute Operator Value, -where Attribute is any of job record attributes and Operator is one of EQUAL, UNEQUAL, LESS, GREATER, WITHIN. - -continuous: flag determining that the query is incremental (not batch) - -Output: - -feedId: unique Id of the feed request, to be used in refresh, cancelation etc. - -expires: when the feed times out. Must be refreshed before this time. - -Faults: GenericJPFault - - - - - - - Extend batch feed subscription (used by index server) - -Input: feedId returned previously by FeedIndex - -Output: the same as for FeedIndex - -Faults: GenericJPFault - - - - - - - Retrieve job record URL's when jobid is known -Used either to bypass JP index server query for this specific case, or after the index server query to -retrieve actual job record. - -Input: jobid - -Output: - -jobLog, inputSandbox, outputSandbox, tags: URL's to components of the job record. - -Faults: GenericJPFault - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Job Provenance Primary Storage service - - - - - - - - - - - - - - - - - - - - - - Store or update information on jobs within the JP index server. -Called directly by the primary storage, used for both batch and incremental feed. - -Input: - -data: list of job record updates. Each contains jobid, list of JP attribute values and user tag values. - -feedDone: flag indicating end of batch feed. (In order to avoid potential problems with buffer allocation -the huge dataset of batch feed is split into reasonable chunks and delivered with more UpdateJobs calls.) - -Output: N/A - -Faults: GenericJPFault - - - - - - - - - Retrieve pointers to job records of jobs matching a query. -Input: conditions - list of lists of query conditions. - Elements of the inner lists refer to a single job attribute, the conditions are or-ed. - Elements of the outer list may refer to different job attributes, they are and-ed. - -Output: - -jobs: list of JobId, PSContact (URL of the primary storage which manges this job) pairs - -Faults: GenericJPFault - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Job Provenance Index service - - - - - - - diff --git a/org.glite.jp.index/project/build.number b/org.glite.jp.index/project/build.number deleted file mode 100644 index 95388e3..0000000 --- a/org.glite.jp.index/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build=9 diff --git a/org.glite.jp.index/project/build.properties b/org.glite.jp.index/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp.index/project/configure.properties.xml b/org.glite.jp.index/project/configure.properties.xml deleted file mode 100644 index 72af8f4..0000000 --- a/org.glite.jp.index/project/configure.properties.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -lbprefix=${subsystem.prefix} -package=${module.package.name} -PREFIX=${install.dir} -version=${module.version} -glite_location=${with.glite.location} -globus_prefix=${with.globus.prefix} -expat_prefix=${with.expat.prefix} -gsoap_prefix=${with.gsoap.prefix} -ares_prefix=${with.ares.prefix} -thrflavour=${with.globus.thr.flavor} -nothrflavour=${with.globus.nothr.flavor} -cppunit=${with.cppunit.prefix} -jpproject=${subsystem.project.dir} -project=${component.project.dir} - - - diff --git a/org.glite.jp.index/project/properties.xml b/org.glite.jp.index/project/properties.xml deleted file mode 100755 index 5f56392..0000000 --- a/org.glite.jp.index/project/properties.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.index/project/tar_exclude b/org.glite.jp.index/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.jp.index/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.jp.index/project/version.properties b/org.glite.jp.index/project/version.properties deleted file mode 100644 index cd1e9e7..0000000 --- a/org.glite.jp.index/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.0.0 -module.age=1 diff --git a/org.glite.jp.index/src/simple_server.c b/org.glite.jp.index/src/simple_server.c deleted file mode 100644 index ccaa5a7..0000000 --- a/org.glite.jp.index/src/simple_server.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "jpis_H.h" - -int main() { - struct soap soap; - int i, m, s; // master and slave sockets - - glite_jp_context_t ctx; - - soap_init(&soap); - glite_jp_init_context(&ctx); - soap.user = (void *) ctx; - - srand48(time(NULL)); /* feed id generation */ - - m = soap_bind(&soap, NULL, 8902, 100); - if (m < 0) - soap_print_fault(&soap, stderr); - else - { - fprintf(stderr, "Socket connection successful: master socket = %d\n", m); - for (i = 1; ; i++) { - s = soap_accept(&soap); - if (s < 0) { - soap_print_fault(&soap, stderr); - break; - } - soap_serve(&soap); // process RPC request - soap_destroy(&soap); // clean up class instances - soap_end(&soap); // clean up everything and close socket - glite_jp_run_deferred(ctx); - } - } - soap_done(&soap); // close master socket - - return 0; -} diff --git a/org.glite.jp.index/src/soap_ops.c b/org.glite.jp.index/src/soap_ops.c deleted file mode 100644 index 5af7352..0000000 --- a/org.glite.jp.index/src/soap_ops.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "jpis_H.h" -#include "JobProvenanceIS.nsmap" - -static struct jptype__GenericJPFaultType *jp2s_error(struct soap *soap, - const glite_jp_error_t *err) -{ - struct jptype__GenericJPFaultType *ret = NULL; - if (err) { - ret = soap_malloc(soap,sizeof *ret); - memset(ret,0,sizeof *ret); - ret->code = err->code; - ret->source = soap_strdup(soap,err->source); - ret->text = soap_strdup(soap,strerror(err->code)); - ret->description = soap_strdup(soap,err->desc); - ret->reason = jp2s_error(soap,err->reason); - } - return ret; -} - -static void err2fault(const glite_jp_context_t ctx,struct soap *soap) -{ - char *et; - struct SOAP_ENV__Detail *detail = soap_malloc(soap,sizeof *detail); - struct _GenericJPFault *f = soap_malloc(soap,sizeof *f); - - - f->jptype__GenericJPFault = jp2s_error(soap,ctx->error); - - detail->__type = SOAP_TYPE__GenericJPFault; - detail->value = f; - detail->__any = NULL; - - soap_receiver_fault(soap,"Oh, shit!",NULL); - if (soap->version == 2) soap->fault->SOAP_ENV__Detail = detail; - else soap->fault->detail = detail; -} - -static void s2jp_tag(const struct jptype__TagValue *stag,glite_jp_tagval_t *jptag) -{ - memset(jptag,0,sizeof *jptag); - jptag->name = strdup(stag->name); - jptag->sequence = stag->sequence ? *stag->sequence : 0; - jptag->timestamp = stag->timestamp ? *stag->timestamp : 0; - if (stag->stringValue) jptag->value = strdup(stag->stringValue); - else if (stag->blobValue) { - jptag->binary = 1; - jptag->size = stag->blobValue->__size; - jptag->value = (char *) stag->blobValue->__ptr; - } -} - -#define CONTEXT_FROM_SOAP(soap,ctx) glite_jp_context_t ctx = (glite_jp_context_t) ((soap)->user) - -SOAP_FMAC5 int SOAP_FMAC6 jpsrv__UpdateJobs( - struct soap *soap, - char *feed_id, - struct jptype__UpdateJobsData *jobs, - enum xsd__boolean done -) -{ - printf("%s items %d jobid %s\n",__FUNCTION__,jobs->__sizejob, - jobs->job[0]->jobid); - return SOAP_OK; -} - -SOAP_FMAC5 int SOAP_FMAC6 jpsrv__QueryJobs( - struct soap *soap, - struct jptype__IndexQuery *query, - struct jpsrv__QueryJobsResponse *resp -) -{ - puts(__FUNCTION__); - return SOAP_OK; -} - diff --git a/org.glite.jp.index/src/typemap.dat b/org.glite.jp.index/src/typemap.dat deleted file mode 100644 index 7032cb2..0000000 --- a/org.glite.jp.index/src/typemap.dat +++ /dev/null @@ -1,2 +0,0 @@ -jpsrv = http://glite.org/wsdl/services/jp -jptype = http://glite.org/wsdl/types/jp diff --git a/org.glite.jp.primary/.cvsignore b/org.glite.jp.primary/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp.primary/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp.primary/Makefile b/org.glite.jp.primary/Makefile deleted file mode 100644 index 652637b..0000000 --- a/org.glite.jp.primary/Makefile +++ /dev/null @@ -1,175 +0,0 @@ -# defaults -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -jpprefix=jp -package=glite-jp-primary -version=0.0.0 -PREFIX=/opt/glite - -glite_location=/opt/glite -globus_prefix=/opt/globus -nothrflavour=gcc32 -thrflavour=gcc32pthr -expat_prefix=/opt/expat -ares_prefix=/opt/ares -gsoap_prefix=/software/gsoap-2.6 - -CC=gcc - --include Makefile.inc - - -VPATH=${top_srcdir}/src:${top_srcdir}/examples:${top_srcdir}/test:${top_srcdir}/project:${stagedir}/interface - -GLOBUS_LIBS:=-L${globus_prefix}/lib \ - -lglobus_common_${nothrflavour} \ - -lglobus_gssapi_gsi_${nothrflavour} - -GLOBUS_CFLAGS:=-I${globus_prefix}/include/${nothrflavour} - -DEBUG:=-g -O0 -DDEBUG - -CFLAGS:=${DEBUG} -I. -I${top_srcdir}/interface -I${top_srcdir}/src -I${gsoap_prefix}/include -I${stagedir}/include ${GLOBUS_CFLAGS} -LDFLAGS:=-L${stagedir}/lib - -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -LTCOMPILE:=libtool --mode=compile ${CC} ${CFLAGS} -SOLINK:=libtool --mode=link ${CC} -module ${LDFLAGS} -rpath ${stagedir}/lib -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install - -daemon:=glite-jp-primarystoraged -example:=jpps-test -ps_prefix:=jpps_ -is_prefix:=jpis_ - -plugins:=glite-jp-tags.la - -HDRS_I=file_plugin.h -HDRS_S=builtin_plugins.h backend.h - -SRCS:= bones_server.c soap_ops.c \ - ftp_backend.c file_plugin.c \ - feed.c tags.c\ - is_client.c \ - ${ps_prefix}ServerLib.c \ - ${is_prefix}ClientLib.c jpps_C.c -# env_C.c - -EXA_SRCS:=jpps-test.c ${ps_prefix}C.c ${ps_prefix}Client.c - - -OBJS:=${SRCS:.c=.o} -EXA_OBJS:=${EXA_SRCS:.c=.o} - -COMMONLIB:=-lglite_jp_common -BONESLIB:=-lglite_lb_server_bones -GSOAPLIB:=-lglite_security_gsoap_plugin_${nothrflavour} -lglite_security_gss_${nothrflavour} \ - -L${gsoap_prefix}/lib -lgsoap${GSOAP_DEBUG} -L${ares_prefix}/lib -lares - -default all: compile - -compile: ${daemon} ${example} ${plugins} - -${daemon}: ${OBJS} - ${LINK} -o $@ ${OBJS} ${BONESLIB} ${COMMONLIB} ${GSOAPLIB} ${GLOBUS_LIBS} - -${example}: ${EXA_OBJS} - ${LINK} -o $@ ${EXA_OBJS} ${GSOAPLIB} ${GLOBUS_LIBS} - -# XXX: piss off -JobProvenanceIS.xh: - touch $@ - -JobProvenancePS.xh: %.xh: %.wsdl JobProvenanceTypes.wsdl typemap.dat - cp ${stagedir}/interface/JobProvenanceTypes.wsdl . - ${gsoap_prefix}/bin/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $< - rm -f JobProvenanceTypes.wsdl - -${ps_prefix}Client.c ${ps_prefix}ClientLib.c \ -${ps_prefix}Server.c ${ps_prefix}ServerLib.c \ -${ps_prefix}C.c ${ps_prefix}H.h: JobProvenancePS.xh - ${gsoap_prefix}/bin/soapcpp2 -n -w -c -p ${ps_prefix} JobProvenancePS.xh - -${is_prefix}ClientLib.c ${is_prefix}Client.c \ -${is_prefix}C.c ${is_prefix}H.h: JobProvenanceIS.xh - ${gsoap_prefix}/bin/soapcpp2 -n -w -c -p ${is_prefix} JobProvenanceIS.xh - -env_C.c env_Server.c: - touch env.xh - cp ${jpproject}/JobProvenanceTypes.wsdl . - ${gsoap_prefix}/bin/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o env.xh JobProvenanceTypes.wsdl - rm -f JobProvenanceTypes.wsdl - ${gsoap_prefix}/bin/soapcpp2 -w -c -p env_ env.xh - -#$(SOAP_PREFIX)H.h $(SOAP_PREFIX)C.c: LB.xh -# $(GSOAP_BIN_PATH)/soapcpp2 -w -c -p $(SOAP_PREFIX) LB.xh -# -#LB.xh: LB.wsdl typemap.dat -# $(GSOAP_BIN_PATH)/wsdl2h -c -o $@ LB.wsdl -# - - -bones_server.o simple_server.o: ${is_prefix}H.h ${ps_prefix}H.h - -check: - -echo nothing yet - -doc: - -stage: compile - ${MAKE} PREFIX=${stagedir} DOSTAGE=yes install - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -install: - -mkdir -p ${PREFIX}/bin ${PREFIX}/etc ${PREFIX}/examples ${PREFIX}/etc/init.d - ${INSTALL} -m 755 ${daemon} ${PREFIX}/bin - ${INSTALL} -m 755 jpps-test ${PREFIX}/examples/glite-jp-primary-test - if [ x${DOSTAGE} = xyes ]; then \ - mkdir -p ${PREFIX}/include/${globalprefix}/${jpprefix} ; \ - (cd ${top_srcdir}/interface && install -m 644 ${HDRS_I} ${PREFIX}/include/${globalprefix}/${jpprefix}) ; \ - (cd ${top_srcdir}/src && install -m 644 ${HDRS_S} ${PREFIX}/include/${globalprefix}/${jpprefix}) ; \ - fi - - -clean: - -simple_server.o soap_ops.o jpps-test.o: ${ps_prefix}H.h - -# we have no real config.h but have to force gSoap not to use -# linux ftime with broken (aka obsolete) DST information - -stdsoap2.o: ${gsoap_prefix}/devel/stdsoap2.c - test -f config.h || touch config.h - @echo 'The following warning "time_t (de)serialization is not MT safe on this platform" is harmless' - ${CC} -o $@ -c -DWITH_NONAMESPACES -DHAVE_CONFIG_H ${CFLAGS} ${gsoap_prefix}/devel/stdsoap2.c - - -glite-jp-tags.la: tags_plugin.lo - ${SOLINK} -o $@ tags_plugin.lo - -%.lo: %.c - ${LTCOMPILE} -o $@ -c $< - -soap_ops.o bones_server.o: soap_version.h - -soap_version.h: - ${gsoap_prefix}/bin/soapcpp2 /dev/null - perl -ne '$$. == 2 && /.*([0-9])\.([0-9])\.([0-9]).*/ && printf "#define GSOAP_VERSION %d%02d%02d\n",$$1,$$2,$$3' soapH.h >$@ - -rm soapC.cpp soapH.h soapStub.h soapClient.cpp soapServer.cpp soapClientLib.cpp soapServerLib.cpp diff --git a/org.glite.jp.primary/build.xml b/org.glite.jp.primary/build.xml deleted file mode 100755 index 28c0d13..0000000 --- a/org.glite.jp.primary/build.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.primary/examples/jpps-test.c b/org.glite.jp.primary/examples/jpps-test.c deleted file mode 100644 index 684a33f..0000000 --- a/org.glite.jp.primary/examples/jpps-test.c +++ /dev/null @@ -1,227 +0,0 @@ -#include -#include -#include -#include - -#include "glite/security/glite_gsplugin.h" - -#include "jpps_H.h" -#include "jpps_.nsmap" - -#include "jptype_map.h" - -static void usage(const char *me) -{ - fprintf(stderr,"%s: [-s server-url] operation args \n\n" - " operations are:\n" - " RegisterJob jobid owner\n" - " StartUpload jobid class commit_before mimetype\n" - " CommitUpload destination\n" - " RecordTag jobid tagname sequence stringvalue\n" - " GetJob jobid\n" - " FeedIndex destination query_number history continuous\n" - " FeedIndexRefresh feedid\n" - ,me); - - exit (EX_USAGE); -} - -static int check_fault(struct soap *soap,int err) { - struct SOAP_ENV__Detail *detail; - struct jptype__genericFault *f; - char *reason,indent[200] = " "; - - switch(err) { - case SOAP_OK: puts("OK"); - break; - case SOAP_FAULT: - case SOAP_SVR_FAULT: - if (soap->version == 2) { - detail = soap->fault->SOAP_ENV__Detail; - reason = soap->fault->SOAP_ENV__Reason; - } - else { - detail = soap->fault->detail; - reason = soap->fault->faultstring; - } - fputs(reason,stderr); - putc('\n',stderr); - assert(detail->__type == SOAP_TYPE__genericFault); -#if GSOAP_VERSION >=20700 - f = ((struct _genericFault *) detail->fault) -#else - f = ((struct _genericFault *) detail->value) -#endif - -> jpelem__genericFault; - - while (f) { - fprintf(stderr,"%s%s: %s (%s)\n",indent, - f->source,f->text,f->description); - f = f->reason; - strcat(indent," "); - } - return -1; - - default: soap_print_fault(soap,stderr); - return -1; - } - return 0; -} - -/* FIXME: new wsdl */ -#if 0 -static struct jptype__Attribute sample_attr[] = { - { OWNER, NULL }, - { TIME, "submitted" }, - { TAG, "test" }, -}; - -static struct jptype__PrimaryQueryElement sample_query[][5] = { - { - { sample_attr+OWNER, EQUAL, "unknown", NULL }, - { NULL, 0, NULL, NULL } - }, -}; -#endif - -int main(int argc,char *argv[]) -{ - char *server = "http://localhost:8901"; - int opt; - struct soap *soap = soap_new(); - - if (argc < 2) usage(argv[0]); - - soap_init(soap); - soap_set_namespaces(soap, jpps__namespaces); - - soap_register_plugin(soap,glite_gsplugin); - - while ((opt = getopt(argc,argv,"s:")) >= 0) switch (opt) { - case 's': server = optarg; - argv += 2; - break; - case '?': usage(argv[0]); - } - - if (!strcasecmp(argv[1],"RegisterJob")) { - struct _jpelem__RegisterJob in; - struct _jpelem__RegisterJobResponse empty; - - if (argc != 4) usage(argv[0]); - in.job = argv[2]; - in.owner = argv[3]; - check_fault(soap, - soap_call___jpsrv__RegisterJob(soap,server,"",&in,&empty)); - } else if (!strcasecmp(argv[1], "StartUpload")) { - struct _jpelem__StartUpload in; - struct _jpelem__StartUploadResponse out; - - in.job = argv[2]; - in.class_ = argv[3]; - in.name = NULL; - in.commitBefore = atoi(argv[4]); - in.contentType = argv[5]; - - if (argc != 6) usage(argv[0]); - if (!check_fault(soap, - soap_call___jpsrv__StartUpload(soap, server, "",&in,&out))) - { - printf("Destination: %s\nCommit before: %s\n", out.destination, ctime(&out.commitBefore)); - } - } else if (!strcasecmp(argv[1], "CommitUpload")) { - struct _jpelem__CommitUpload in; - struct _jpelem__CommitUploadResponse empty; - - in.destination = argv[2]; - - if (argc != 3) usage(argv[0]); - if (!check_fault(soap, - soap_call___jpsrv__CommitUpload(soap, server, "",&in,&empty))) { - /* OK */ - } - } else if (!strcasecmp(argv[1], "RecordTag")) { - struct _jpelem__RecordTag in; - struct _jpelem__RecordTagResponse empty; - struct jptype__tagValue tagval; - - if (argc != 6) usage(argv[0]); - - in.jobid = argv[2]; - in.tag = &tagval; - tagval.name = argv[3]; - tagval.sequence = NULL; - tagval.timestamp = NULL; - tagval.stringValue = argv[5]; - tagval.blobValue = NULL; - - if (!check_fault(soap, - soap_call___jpsrv__RecordTag(soap, server, "",&in, &empty))) { - /* OK */ - } - } -/* FIXME: new wsdl */ -#if 0 - else if (!strcasecmp(argv[1],"FeedIndex")) { - struct jpsrv__FeedIndexResponse r; - struct jptype__Attribute *ap[2]; - struct jptype__Attributes attr = { 2, ap }; - struct jptype__PrimaryQueryElement *qp[100]; - struct jptype__PrimaryQuery qry = { 0, qp }; - - int i,j,qi = atoi(argv[3])-1; - - if (argc != 6) usage(argv[0]); - - for (i=0; i__sizefile;i++) { - printf("\tclass = %s, name = %s, url = %s\n", - r.files->file[i]->class_, - r.files->file[i]->name, - r.files->file[i]->url); - } - } - - } -#endif - else usage(argv[0]); - - return 0; -} - - -/* XXX: we don't use it */ -SOAP_NMAC struct Namespace namespaces[] = { {NULL,NULL} }; diff --git a/org.glite.jp.primary/interface/file_plugin.h b/org.glite.jp.primary/interface/file_plugin.h deleted file mode 100644 index 2bb9fc0..0000000 --- a/org.glite.jp.primary/interface/file_plugin.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef __GLITE_JP_FILEPLUGIN -#define __GLITE_JP_FILEPLUGIN - -/** Methods of the file plugin. */ - -typedef struct _glite_jpps_fplug_op_t { - -/** Open a file. -\param[in] fpctx Context of the plugin, returned by its init. -\param[in] bhandle Handle of the file via JPPS backend. -\param[in] type Index of the type in this plugin's uri's. -\param[out] handle Handle to the opened file structure, to be passed to other plugin functions. -*/ - int (*open)(void *fpctx,void *bhandle,const char *uri,void **handle); - -/** Close the file. Free data associated to a handle */ - int (*close)(void *fpctx,void *handle); - -/** Retrieve value(s) of an attribute. -\param[in] fpctx Plugin context. -\param[in] handle Handle of the opened file. -\param[in] attr Queried attribute. -\param[out] attrval GLITE_JP_ATTR_UNDEF-terminated list of value(s) of the attribute. - If there are more and there is an interpretation of their order - they must be sorted, eg. current value of tag is the last one. -\retval 0 success -\retval ENOSYS this attribute is not defined by this type of file -\retval ENOENT no value is present -*/ - int (*attr)(void *fpctx,void *handle,glite_jp_attr_t attr,glite_jp_attrval_t **attrval); - -/** File type specific operation. -\param[in] fpctx Plugin context. -\param[in] handle Handle of the opened file. -\param[in] oper Code of the operation, specific for a concrete plugin. -*/ - int (*generic)(void *fpctx,void *handle,int oper,...); - -} glite_jpps_fplug_op_t; - -/** Data describing a plugin. */ -typedef struct _glite_jpps_fplug_data_t { - void *fpctx; /**< Context passed to plugin operations. */ - char **uris; /**< NULL-terminated list of file types (URIs) - handled by the plugin. */ - char **classes; /**< The same as uris but filesystem-friendly - (can be used to construct file names).*/ - - glite_jpps_fplug_op_t ops; /**< Plugin operations. */ -} glite_jpps_fplug_data_t; - -/** Initialisation function of the plugin. - Called after dlopen(), must be named "init". -\param[in] ctx JPPS context -\param[out] data filled-in plugin data -*/ - -typedef int (*glite_jpps_fplug_init_t)( - glite_jp_context_t ctx, - glite_jpps_fplug_data_t *plugin_data -); - - - - -/* XXX: not really public interface follows */ - -int glite_jpps_fplug_load(glite_jp_context_t ctx,int argc,char **argv); -int glite_jpps_fplug_lookup(glite_jp_context_t ctx,const char *uri, glite_jpps_fplug_data_t ***plugin_data); - -#endif diff --git a/org.glite.jp.primary/project/build.number b/org.glite.jp.primary/project/build.number deleted file mode 100644 index c680c72..0000000 --- a/org.glite.jp.primary/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build=36 diff --git a/org.glite.jp.primary/project/build.properties b/org.glite.jp.primary/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp.primary/project/configure.properties.xml b/org.glite.jp.primary/project/configure.properties.xml deleted file mode 100644 index 3f88fbf..0000000 --- a/org.glite.jp.primary/project/configure.properties.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -lbprefix=${subsystem.prefix} -package=${module.package.name} -PREFIX=${install.dir} -version=${module.version} -glite_location=${with.glite.location} -globus_prefix=${with.globus.prefix} -expat_prefix=${with.expat.prefix} -ares_prefix=${with.ares.prefix} -gsoap_prefix=${with.gsoap.prefix} -thrflavour=${with.globus.thr.flavor} -nothrflavour=${with.globus.nothr.flavor} -cppunit=${with.cppunit.prefix} -jpproject=${subsystem.project.dir} -project=${component.project.dir} - - - diff --git a/org.glite.jp.primary/project/properties.xml b/org.glite.jp.primary/project/properties.xml deleted file mode 100755 index 2149dd4..0000000 --- a/org.glite.jp.primary/project/properties.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.primary/project/tar_exclude b/org.glite.jp.primary/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.jp.primary/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.jp.primary/project/version.properties b/org.glite.jp.primary/project/version.properties deleted file mode 100644 index cd1e9e7..0000000 --- a/org.glite.jp.primary/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.0.0 -module.age=1 diff --git a/org.glite.jp.primary/src/backend.h b/org.glite.jp.primary/src/backend.h deleted file mode 100644 index cf901fb..0000000 --- a/org.glite.jp.primary/src/backend.h +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef __GLITE_JP_BACKEND -#define __GLITE_JP_BACKEND - -#include -#include - -int glite_jppsbe_init( - glite_jp_context_t ctx, - int argc, - char *argv[] -); - -int glite_jppsbe_init_slave( - glite_jp_context_t ctx -); - -int glite_jppsbe_register_job( - glite_jp_context_t ctx, - const char *job, - const char *owner -); - -int glite_jppsbe_start_upload( - glite_jp_context_t ctx, - const char *job, - const char *class, /* must be filesystem-friendly */ - const char *name, /* optional name within the class */ - const char *content_type, - char **destination_out, - time_t *commit_before_inout -); - -int glite_jppsbe_commit_upload( - glite_jp_context_t ctx, - const char *destination -); - -int glite_jppsbe_get_names( - glite_jp_context_t ctx, - const char *job, - const char *class, - char ***names_out -); - -int glite_jppsbe_destination_info( - glite_jp_context_t ctx, - const char *destination, - char **job_out, - char **class_out, - char **name_out -); - -int glite_jppsbe_get_job_url( - glite_jp_context_t ctx, - const char *job, - const char *class, - const char *name, /* optional within class */ - char **url_out -); - -int glite_jppsbe_open_file( - glite_jp_context_t ctx, - const char *job, - const char *class, - const char *name, /* optional within class */ - int mode, - void **handle_out -); - -int glite_jppsbe_close_file( - glite_jp_context_t ctx, - void *handle -); - -int glite_jppsbe_pread( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes, - off_t offset, - ssize_t *nbytes_ret -); - -int glite_jppsbe_pwrite( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes, - off_t offset -); - -int glite_jppsbe_append( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes -); - -int glite_jppsbe_get_job_metadata( - glite_jp_context_t ctx, - const char *job, - glite_jp_attrval_t attrs_inout[] -); - -int glite_jppsbe_query( - glite_jp_context_t ctx, - const glite_jp_query_rec_t query[], - const glite_jp_attrval_t metadata[], - int (*callback)( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t metadata[] - ) -); - -#endif diff --git a/org.glite.jp.primary/src/bones_server.c b/org.glite.jp.primary/src/bones_server.c deleted file mode 100644 index 8c90ba4..0000000 --- a/org.glite.jp.primary/src/bones_server.c +++ /dev/null @@ -1,316 +0,0 @@ -#include -#include -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "glite/lb/srvbones.h" -#include "glite/security/glite_gss.h" - -#include -#include "glite/security/glite_gsplugin.h" - -#include "backend.h" -#include "file_plugin.h" - -#include "soap_version.h" -#include "jpps_H.h" - -#define CONN_QUEUE 20 - -extern SOAP_NMAC struct Namespace jpis__namespaces[],jpps__namespaces[]; - -static int newconn(int,struct timeval *,void *); -static int request(int,struct timeval *,void *); -static int reject(int); -static int disconn(int,struct timeval *,void *); -static int data_init(void **data); - -static struct glite_srvbones_service stab = { - "JP Primary Storage", -1, newconn, request, reject, disconn -}; - -static time_t cert_mtime; -static char *server_cert, *server_key, *cadir; -static gss_cred_id_t mycred = GSS_C_NO_CREDENTIAL; -static char *mysubj; - -static char *port = "8901"; -static int debug = 1; - -static glite_jp_context_t ctx; - -static int call_opts(glite_jp_context_t,char *,char *,int (*)(glite_jp_context_t,int,char **)); - -char *glite_jp_default_namespace; - -int main(int argc, char *argv[]) -{ - int one = 1,opt,i; - edg_wll_GssStatus gss_code; - struct sockaddr_in a; - char *b_argv[20] = { "backend" },*p_argv[20] = { "plugins" },*com; - int b_argc,p_argc; - - glite_jp_init_context(&ctx); - - b_argc = p_argc = 1; - - while ((opt = getopt(argc,argv,"B:P:")) != EOF) switch (opt) { - case 'B': - assert(b_argc < 20); - if (com = strchr(optarg,',')) *com = 0; - - /* XXX: memleak -- who cares for once */ - asprintf(&b_argv[b_argc++],"-%s",optarg); - if (com) b_argv[b_argc++] = com+1; - - break; - case 'P': - assert(p_argc < 20); - p_argv[p_argc++] = optarg; - - break; - case '?': fprintf(stderr,"usage: %s: -Bb,val ... -Pplugin.so ...\n" - "b is backend option\n",argv[0]); - exit (1); - } - - if (b_argc == 1) { - fputs("-B required\n",stderr); - exit (1); - } - - optind = 0; /* XXX: getopt used internally */ - if (glite_jppsbe_init(ctx,b_argc,b_argv)) { - fputs(glite_jp_error_chain(ctx), stderr); - exit(1); - } - - optind = 0; /* XXX: getopt used internally */ - if (b_argc > 1 && glite_jpps_fplug_load(ctx,p_argc,p_argv)) { - fputs(glite_jp_error_chain(ctx), stderr); - exit(1); - } - - srand48(time(NULL)); /* feed id generation */ - - for (i=0; jpps__namespaces[i].id && strcmp(jpps__namespaces[i].id,"jpsrv"); i++); - assert(jpps__namespaces[i].id); - glite_jp_default_namespace = jpps__namespaces[i].ns; - - stab.conn = socket(PF_INET, SOCK_STREAM, 0); - if (stab.conn < 0) { - perror("socket"); - return 1; - } - - setsockopt(stab.conn,SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); - - a.sin_family = AF_INET; - a.sin_addr.s_addr = INADDR_ANY; - a.sin_port = htons(atoi(port)); - if (bind(stab.conn,(struct sockaddr *) &a, sizeof(a)) ) { - char buf[200]; - - snprintf(buf,sizeof(buf),"bind(%d)",atoi(port)); - perror(buf); - return 1; - } - - if (listen(stab.conn,CONN_QUEUE)) { - perror("listen()"); - return 1; - } - - if (!server_cert || !server_key) - fprintf(stderr, "%s: WARNING: key or certificate file not specified, " - "can't watch them for changes\n", - argv[0]); - - if ( cadir ) setenv("X509_CERT_DIR", cadir, 1); - edg_wll_gss_watch_creds(server_cert, &cert_mtime); - - if ( !edg_wll_gss_acquire_cred_gsi(server_cert, server_key, &mycred, &mysubj, &gss_code)) - fprintf(stderr,"Server idenity: %s\n",mysubj); - else fputs("WARNING: Running unauthenticated\n",stderr); - - /* XXX: daemonise */ - - glite_srvbones_set_param(GLITE_SBPARAM_SLAVES_COUNT,1); - glite_srvbones_run(data_init,&stab,1 /* XXX: entries in stab */,debug); - - return 0; -} - -static int data_init(void **data) -{ - *data = (void *) soap_new(); - - printf("[%d] slave started\n",getpid()); - - return 0; -} - -static int newconn(int conn,struct timeval *to,void *data) -{ - struct soap *soap = (struct soap *) data; - glite_gsplugin_Context plugin_ctx; - - gss_cred_id_t newcred = GSS_C_NO_CREDENTIAL; - edg_wll_GssStatus gss_code; - gss_name_t client_name = GSS_C_NO_NAME; - gss_buffer_desc token = GSS_C_EMPTY_BUFFER; - OM_uint32 maj_stat,min_stat; - - - int ret = 0; - - soap_init2(soap,SOAP_IO_KEEPALIVE,SOAP_IO_KEEPALIVE); - soap_set_namespaces(soap,jpps__namespaces); - soap->user = (void *) ctx; /* XXX: one instance per slave */ - -/* not yet: client to JP index - ctx->other_soap = soap_new(); - soap_init(ctx->other_soap); - soap_set_namespaces(ctx->other_soap,jpis__namespaces); -*/ - - - glite_gsplugin_init_context(&plugin_ctx); - plugin_ctx->connection = calloc(1,sizeof *plugin_ctx->connection); - soap_register_plugin_arg(soap,glite_gsplugin,plugin_ctx); - - switch (edg_wll_gss_watch_creds(server_cert,&cert_mtime)) { - case 0: break; - case 1: if (!edg_wll_gss_acquire_cred_gsi(server_cert,server_key, - &newcred,NULL,&gss_code)) - { - - printf("[%d] reloading credentials\n",getpid()); /* XXX: log */ - gss_release_cred(&min_stat,&mycred); - mycred = newcred; - } - break; - case -1: - printf("[%d] edg_wll_gss_watch_creds failed\n", getpid()); /* XXX: log */ - break; - } - - /* TODO: DNS paranoia etc. */ - - if (edg_wll_gss_accept(mycred,conn,to,plugin_ctx->connection,&gss_code)) { - printf("[%d] GSS connection accept failed, closing.\n", getpid()); - ret = 1; - goto cleanup; - } - - maj_stat = gss_inquire_context(&min_stat,plugin_ctx->connection->context, - &client_name, NULL, NULL, NULL, NULL, NULL, NULL); - - if (!GSS_ERROR(maj_stat)) - maj_stat = gss_display_name(&min_stat,client_name,&token,NULL); - - if (ctx->peer) free(ctx->peer); - if (!GSS_ERROR(maj_stat)) { - printf("[%d] client DN: %s\n",getpid(),(char *) token.value); /* XXX: log */ - - ctx->peer = strdup(token.value); - memset(&token, 0, sizeof(token)); - } - else { - printf("[%d] annonymous client\n",getpid()); - ctx->peer = NULL; - } - - if (client_name != GSS_C_NO_NAME) gss_release_name(&min_stat, &client_name); - if (token.value) gss_release_buffer(&min_stat, &token); - - return 0; - -cleanup: - glite_gsplugin_free_context(plugin_ctx); - soap_end(soap); - - return ret; -} - -static int request(int conn,struct timeval *to,void *data) -{ - struct soap *soap = data; - glite_jp_context_t ctx = soap->user; - - glite_gsplugin_set_timeout(glite_gsplugin_get_context(soap),to); - -/* FIXME: does not work, ask nykolas */ - soap->max_keep_alive = 1; /* XXX: prevent gsoap to close connection */ - soap_begin(soap); - if (soap_begin_recv(soap)) { - if (soap->error < SOAP_STOP) { - soap_send_fault(soap); - return -1; - } - return ENOTCONN; - } - - if (soap_envelope_begin_in(soap) - || soap_recv_header(soap) - || soap_body_begin_in(soap) - || jpps__serve_request(soap) -#if GSOAP_VERSION >= 20700 - || (soap->fserveloop && soap->fserveloop(soap)) -#endif - ) - { - soap_send_fault(soap); - return -1; - } - - glite_jp_run_deferred(ctx); - return 0; -} - -static int reject(int conn) -{ - int flags = fcntl(conn, F_GETFL, 0); - - fcntl(conn,F_SETFL,flags | O_NONBLOCK); - edg_wll_gss_reject(conn); - - return 0; -} - -static int disconn(int conn,struct timeval *to,void *data) -{ - struct soap *soap = (struct soap *) data; - soap_end(soap); // clean up everything and close socket - - return 0; -} - -#define WSPACE "\t\n " - -static int call_opts(glite_jp_context_t ctx,char *opt,char *name,int (*f)(glite_jp_context_t,int,char **)) -{ - int ac = 1,ret,my_optind; - char **av = malloc(sizeof *av),*ap; - - *av = name; - for (ap = strtok(opt,WSPACE); ap; ap = strtok(NULL,WSPACE)) { - av = realloc(av,(ac+1) * sizeof *av); - av[ac++] = ap; - } - - my_optind = optind; - optind = 0; - ret = f(ctx,ac,av); - optind = my_optind; - free(av); - return ret; -} - - -/* XXX: we don't use it */ -SOAP_NMAC struct Namespace namespaces[] = { {NULL,NULL} }; diff --git a/org.glite.jp.primary/src/builtin_plugins.h b/org.glite.jp.primary/src/builtin_plugins.h deleted file mode 100644 index 3b2c201..0000000 --- a/org.glite.jp.primary/src/builtin_plugins.h +++ /dev/null @@ -1,7 +0,0 @@ - -#define GLITE_JP_FILETYPE_TAGS "urn:org.glite.jp.primary:tags" -#define GLITE_JP_FILETYPE_LB "urn:org.glite.jp.primary:lb" -#define GLITE_JP_FILETYPE_ISB "urn:org.glite.jp.primary:isb" -#define GLITE_JP_FILETYPE_OSB "urn:org.glite.jp.primary:osb" - -#define GLITE_JP_FPLUG_TAGS_APPEND 0 diff --git a/org.glite.jp.primary/src/db.h b/org.glite.jp.primary/src/db.h deleted file mode 100644 index 0b9f730..0000000 --- a/org.glite.jp.primary/src/db.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef _DB_H -#define _DB_H - -#ident "$Header$" - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef struct _glite_jp_db_stmt_t *glite_jp_db_stmt_t; - -int glite_jp_db_connect( - glite_jp_context_t, /* INOUT: */ - char * /* IN: connect string user/password@host:database */ -); - -void glite_jp_db_close(glite_jp_context_t); - - -/* Parse and execute SQL statement. Returns number of rows selected, created - * or affected by update, or -1 on error */ - -int glite_jp_db_execstmt( - glite_jp_context_t, /* INOUT: */ - char *, /* IN: SQL statement */ - glite_jp_db_stmt_t * /* OUT: statement handle. Usable for - select only */ -); - - -/* Fetch next row of select statement. - * All columns are returned as fresh allocated strings - * - * return values: - * >0 - number of fields of the retrieved row - * 0 - no more rows - * -1 - error - * - * Errors are stored in context passed to previous glite_jp_db_execstmt() */ - -int glite_jp_db_fetchrow( - glite_jp_db_stmt_t, /* IN: statement */ - char ** /* OUT: array of fetched values. - * As number of columns is fixed and known, - * expects allocated array of pointers here */ -); - -/* Retrieve column names of a query statement */ - -int glite_jp_db_querycolumns( - glite_jp_db_stmt_t, /* IN: statement */ - char ** /* OUT: result set column names. Expects allocated array. */ -); - -/* Free the statement structure */ - -void glite_jp_db_freestmt( - glite_jp_db_stmt_t * /* INOUT: statement */ -); - - -/* convert time_t into database-specific time string - * returns pointer to static area that is changed by subsequent calls */ - -char *glite_jp_db_timetodb(time_t); -time_t glite_jp_db_dbtotime(char *); - - -/** - * Check database version. - */ -int glite_jp_db_dbcheckversion(glite_jp_context_t); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/org.glite.jp.primary/src/feed.c b/org.glite.jp.primary/src/feed.c deleted file mode 100644 index 7f4b384..0000000 --- a/org.glite.jp.primary/src/feed.c +++ /dev/null @@ -1,327 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/strmd5.h" -#include "feed.h" -#include "file_plugin.h" -#include "builtin_plugins.h" - - -/* - * seconds before feed expires: should be - * XXX: should be configurable, default for real deployment sort of 1 hour - */ -#define FEED_TTL 120 - -static int check_qry_item( - glite_jp_context_t ctx, - const glite_jp_query_rec_t *qry, - const glite_jp_attrval_t *attr -) -{ - int cmp,cmp2; - long scmp,ucmp; - - switch (qry->attr.type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TAG: - cmp = strcmp(attr->value.s,qry->value.s); - break; - case GLITE_JP_ATTR_TIME: - scmp = (ucmp = attr->value.time.tv_usec - qry->value.time.tv_usec) > 0 ? 0 : -1; - ucmp -= 1000000 * scmp; - scmp += attr->value.time.tv_sec - qry->value.time.tv_sec; - cmp = scmp ? scmp : ucmp; - break; - } - switch (qry->op) { - case GLITE_JP_QUERYOP_EQUAL: return !cmp; - case GLITE_JP_QUERYOP_UNEQUAL: return cmp; - case GLITE_JP_QUERYOP_LESS: return cmp < 0; - case GLITE_JP_QUERYOP_GREATER: return cmp > 0; - - case GLITE_JP_QUERYOP_WITHIN: - switch (qry->attr.type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TAG: - cmp2 = strcmp(attr->value.s,qry->value2.s); - break; - case GLITE_JP_ATTR_TIME: - scmp = (ucmp = attr->value.time.tv_usec - qry->value2.time.tv_usec) > 0 ? 0 : -1; - ucmp -= 1000000 * scmp; - scmp += attr->value.time.tv_sec - qry->value2.time.tv_sec; - cmp2 = scmp ? scmp : ucmp; - break; - } - return cmp >= 0 && cmp2 <= 0; - } -} - -/* XXX: limit on query size -- I'm lazy to malloc() */ -#define QUERY_MAX 100 - -static int match_feed( - glite_jp_context_t ctx, - const struct jpfeed *feed, - const char *job, - const glite_jp_attrval_t attrs[] /* XXX: not checked for correctness */ -) -{ - int i; - int attri[GLITE_JP_ATTR__LAST]; - int qi[QUERY_MAX]; - - glite_jp_attrval_t *newattr = NULL; - - glite_jp_clear_error(ctx); - - for (i=0; iqry) { - int j,complete = 1; - - memset(qi,0,sizeof qi); - for (i=0; feed->qry[i].attr.type; i++) { - assert(iqry[i].attr.type]) >=0) { - if (check_qry_item(ctx,feed->qry+i,attrs+j)) - qi[i] = 1; /* matched */ - else return 0; /* can't be satisfied */ - } - else complete = 0; - } - - /* not all attributes in query are known from input - * we have to retrieve job metadata from the backend - */ - if (!complete) { - glite_jp_attrval_t meta[GLITE_JP_ATTR__LAST+1]; - int qai[GLITE_JP_ATTR__LAST]; - - memset(meta,0,sizeof meta); - j=0; - for (i=0; feed->qry[i].attr.type; i++) if (!qi[i]) { - meta[j].attr.type = feed->qry[i].attr.type; - meta[j].attr.name = feed->qry[i].attr.name; - qai[feed->qry[i].attr.type] = i; - j++; - } - - if (glite_jppsbe_get_job_metadata(ctx,job,meta)) { - glite_jp_error_t err; - memset(&err,0,sizeof err); - err.code = EIO; - err.source = __FUNCTION__; - err.desc = "complete query"; - return glite_jp_stack_error(ctx,&err); - } - - for (i=0; j=meta[i].attr.type; i++) - if (!check_qry_item(ctx,feed->qry+qai[j],meta+i)) - return 0; - } - } - - /* matched completely */ - return glite_jpps_single_feed(ctx,feed->destination,job,attrs); - return 0; -} - -int glite_jpps_match_attr( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t attrs[] -) -{ - struct jpfeed *f = (struct jpfeed *) ctx->feeds; - int i,j; - int attri[GLITE_JP_ATTR__LAST]; - - glite_jp_clear_error(ctx); - - for (i=0; i= GLITE_JP_ATTR__LAST || - attrs[i].attr.type <= 0) - { - glite_jp_error_t err; - memset(&err,0,sizeof err); - err.code = EINVAL; - err.source = __FUNCTION__; - err.desc = "unknown attribute"; - return glite_jp_stack_error(ctx,&err); - } - if (attri[attrs[i].attr.type] >= 0) { - glite_jp_error_t err; - memset(&err,0,sizeof err); - err.code = EINVAL; - err.source = __FUNCTION__; - err.desc = "double attribute change"; - return glite_jp_stack_error(ctx,&err); - } - - attri[attrs[i].attr.type] = i; - } - - for (;f; f = f->next) { - for (i=0; f->attrs[i].type && attri[f->attrs[i].type] == -1; i++); - /* XXX: ignore any errors */ - if (f->attrs[i].type) match_feed(ctx,f,job,attrs); - } - - return glite_jp_clear_error(ctx); -} - -int glite_jpps_match_file( - glite_jp_context_t ctx, - const char *job, - const char *class, - const char *name -) -{ - glite_jpps_fplug_data_t **pd = NULL; - int pi; - void *bh = NULL; - int ret; - - fprintf(stderr,"%s: %s %s %s\n",__FUNCTION__,job,class,name); - - switch (glite_jpps_fplug_lookup(ctx,class,&pd)) { - case ENOENT: return 0; /* XXX: shall we complain? */ - case 0: break; - default: return -1; - } - - for (pi=0; pd[pi]; pi++) { - int ci; - for (ci=0; pd[pi]->uris[ci]; ci++) if (!strcmp(pd[pi]->uris[ci],class)) { - void *ph; - - if (!bh && (ret = glite_jppsbe_open_file(ctx,job,pd[pi]->classes[ci],name,O_RDONLY,&bh))) { - free(pd); - return ret; - } - - if (pd[pi]->ops.open(pd[pi]->fpctx,bh,class,&ph)) { - /* XXX: complain more visibly */ - fputs("plugin open failed\n",stderr); - continue; - } - - /* XXX: does not belong here but I'd like to avoid opening the file twice */ - if (!strcmp(class,GLITE_JP_FILETYPE_LB)) { - glite_jp_attr_t owner = { GLITE_JP_ATTR_OWNER, NULL }; - glite_jp_attrval_t *val; - - switch (pd[pi]->ops.attr(pd[pi]->fpctx,ph,owner,&val)) { - case ENOENT: - case ENOSYS: abort(); - case 0: printf("LB plugin: owner = %s\n",val[0].value.s); - /* TODO: store it in backend */ - - glite_jp_attrval_free(val,1); - break; - - default: /* TODO: complain */; break; - } - } - - /* TODO: extract attributes for the feeds */ - - - pd[pi]->ops.close(pd[pi]->fpctx,ph); - } - } - - if (bh) glite_jppsbe_close_file(ctx,bh); - free(pd); - - return 0; -} - -int glite_jpps_match_tag( - glite_jp_context_t ctx, - const char *job, - const glite_jp_tagval_t *tag -) -{ - fprintf(stderr,"%s: \n",__FUNCTION__); - return 0; -} - -static char *generate_feedid(void) -{ - char hname[200],buf[1000]; - - gethostname(hname,sizeof hname); - snprintf(buf,sizeof buf,"%s%d%ld",hname,getpid(),lrand48()); - buf[sizeof buf-1] = 0; - return str2md5base64(buf); -} - - -int glite_jpps_run_feed( - glite_jp_context_t ctx, - const char *destination, - const glite_jp_attr_t *attrs, - const glite_jp_query_rec_t *qry, - char **feed_id) -{ - fprintf(stderr,"%s: \n",__FUNCTION__); - return 0; -} - -static int register_feed_deferred(glite_jp_context_t ctx,void *feed) -{ - struct jpfeed *f = feed; - - f->next = ctx->feeds; - ctx->feeds = f; - return 0; -} - -/* FIXME: - * - volatile implementation: should store the registrations in a file - * and recover after restart - * - should communicate the data among all server slaves - */ -int glite_jpps_register_feed( - glite_jp_context_t ctx, - const char *destination, - const glite_jp_attr_t *attrs, - const glite_jp_query_rec_t *qry, - char **feed_id, - time_t *expires) -{ - int i; - struct jpfeed *f = calloc(1,sizeof *f); - - if (!*feed_id) *feed_id = generate_feedid(); - time(expires); *expires += FEED_TTL; - - f->id = strdup(*feed_id); - f->destination = strdup(destination); - f->expires = *expires; - for (i=0; attrs[i].type; i++) { - f->attrs = realloc(f->attrs,(i+2) * sizeof *f->attrs); - glite_jp_attr_copy(f->attrs+i,attrs+i); - memset(f->attrs+i+1,0,sizeof *f->attrs); - } - for (i=0; qry[i].attr.type; i++) { - f->qry = realloc(f->qry,(i+2) * sizeof *f->qry); - glite_jp_queryrec_copy(f->qry+i,qry+i); - memset(f->qry+i+1,0,sizeof *f->qry); - } - - glite_jp_add_deferred(ctx,register_feed_deferred,f); - - return 0; -} - diff --git a/org.glite.jp.primary/src/feed.h b/org.glite.jp.primary/src/feed.h deleted file mode 100644 index c3c2461..0000000 --- a/org.glite.jp.primary/src/feed.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __GLITE_JP_FEED -#define __GLITE_JP_FEED - - -struct jpfeed { - char *id,*destination; - time_t expires; - glite_jp_attr_t *attrs; - glite_jp_query_rec_t *qry; - struct jpfeed *next; -}; - - -int glite_jpps_match_attr(glite_jp_context_t,const char *,const glite_jp_attrval_t[]); -int glite_jpps_match_file(glite_jp_context_t,const char *,const char *,const char *); -int glite_jpps_match_tag(glite_jp_context_t,const char *,const glite_jp_tagval_t *); -int glite_jpps_run_feed(glite_jp_context_t,const char *,const glite_jp_attr_t *,const glite_jp_query_rec_t *,char **); -int glite_jpps_register_feed(glite_jp_context_t,const char *,const glite_jp_attr_t *,const glite_jp_query_rec_t *,char **,time_t *); - -#endif - diff --git a/org.glite.jp.primary/src/file_plugin.c b/org.glite.jp.primary/src/file_plugin.c deleted file mode 100644 index 144a231..0000000 --- a/org.glite.jp.primary/src/file_plugin.c +++ /dev/null @@ -1,115 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include "file_plugin.h" - -static struct option opts[] = { - { "plugin", 1, NULL, 'p' }, - { NULL } -}; - -static int loadit(glite_jp_context_t ctx,const char *so) -{ -/* XXX: not stored but we never dlclose() yet */ - void *dl_handle = dlopen(so,RTLD_NOW); - - glite_jp_error_t err; - const char *e; - glite_jpps_fplug_data_t *data,*dp; - int i; - - glite_jpps_fplug_init_t init; - memset(&err,0,sizeof err); - - if (!dl_handle) { - err.source = "dlopen()"; - err.code = EINVAL; - err.desc = dlerror(); - return glite_jp_stack_error(ctx,&err); - } - - dlerror(); - init = dlsym(dl_handle,"init"); - e = dlerror(); - if (e) { - char buf[300]; - snprintf(buf,sizeof buf,"dlsym(\"%s\",\"init\")",so); - buf[299] = 0; - err.source = buf; - err.code = ENOENT; - err.desc = e; - return glite_jp_stack_error(ctx,&err); - } - - data = calloc(1,sizeof *data); - - if (init(ctx,data)) return -1; - - i = 0; - if (ctx->plugins) for (i=0; ctx->plugins[i]; i++); - ctx->plugins = realloc(ctx->plugins, (i+2) * sizeof *ctx->plugins); - ctx->plugins[i] = data; - ctx->plugins[i+1] = NULL; - - /* TODO: check consistency of uri+class pairs wrt. previous plugins */ - - return 0; -} - -int glite_jpps_fplug_load(glite_jp_context_t ctx,int argc,char **argv) -{ - int i; - - for (i=1; iplugins) { - return glite_jp_stack_error(ctx,&err); - } - - for (i = 0; ctx->plugins[i]; i++) { - int j; - glite_jpps_fplug_data_t *p = ctx->plugins[i]; - - for (j=0; p->uris && p->uris[j]; j++) - if (!strcmp(p->uris[j],uri)) { - out = realloc(out, (matches+2) * sizeof *out); - out[matches++] = p; - out[matches] = NULL; - } - } - - if (matches) { - *plugin_data = out; - return 0; - } - else return glite_jp_stack_error(ctx,&err); -} - diff --git a/org.glite.jp.primary/src/ftp_backend.c b/org.glite.jp.primary/src/ftp_backend.c deleted file mode 100644 index 8bf523b..0000000 --- a/org.glite.jp.primary/src/ftp_backend.c +++ /dev/null @@ -1,1744 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" -#include "glite/jp/strmd5.h" - -#include "tags.h" -#include "backend.h" - -#define UPLOAD_SUFFIX ".upload" -#define LOCK_SUFFIX ".lock" - -struct ftpbe_config { - char *internal_path; - char *external_path; - char *gridmap; - char *logname; -}; - -static struct ftpbe_config *config = NULL; - -struct fhandle_rec { - int fd; - int fd_append; -}; -typedef struct fhandle_rec *fhandle; - -static struct option ftpbe_opts[] = { - { "ftp-internal-path", 1, NULL, 'I' }, - { "ftp-external-path", 1, NULL, 'E' }, - { "ftp-gridmap", 1, NULL, 'G' }, - { NULL, 0, NULL, 0 } -}; - -/* obsolete */ -#if 0 -static struct { - glite_jp_fileclass_t type; - char * fname; - } class_to_fname_tab[] = { - { GLITE_JP_FILECLASS_INPUT, "input" }, - { GLITE_JP_FILECLASS_OUTPUT, "output" }, - { GLITE_JP_FILECLASS_LBLOG, "lblog" }, - { GLITE_JP_FILECLASS_TAGS, "tags" }, - { GLITE_JP_FILECLASS_UNDEF, NULL } - }; - -static char *class_to_fname(glite_jp_fileclass_t type) -{ - int i; - - for (i = 0; class_to_fname_tab[i].type != GLITE_JP_FILECLASS_UNDEF; i++) - if (type == class_to_fname_tab[i].type) - return class_to_fname_tab[i].fname; - - return NULL; -} - -static glite_jp_fileclass_t fname_to_class(char* fname) -{ - int i; - - for (i = 0; class_to_fname_tab[i].type != GLITE_JP_FILECLASS_UNDEF; i++) - if (!strcmp(fname, class_to_fname_tab[i].fname)) - return class_to_fname_tab[i].type; - - return GLITE_JP_FILECLASS_UNDEF; -} -#endif - -static int config_check( - glite_jp_context_t ctx, - struct ftpbe_config *config) -{ - return config == NULL || - config->internal_path == NULL || - config->external_path == NULL || - config->gridmap == NULL || - config->logname == NULL; - - /* XXX check reality */ -} - -static int jobid_unique_pathname(glite_jp_context_t ctx, const char *job, - char **unique, char **ju_path, int get_path) -{ - char *p; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - p = strrchr(job, '/'); - if (!p) { - err.code = EINVAL; - err.desc = "Malformed jobid"; - return glite_jp_stack_error(ctx,&err); - } - /* XXX thorough checks */ - if (!(*unique = strdup(p+1))) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - if (get_path) { - if (!(*ju_path = strdup(p+1))) { - free(*unique); - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - *(*ju_path + 10) = '\0'; - } - return 0; -} - -static int mkdirpath(const char* path, int prefixlen) -{ - char *wpath, *p; - int goout, ret; - - wpath = strdup(path); - if (!wpath) { - errno = ENOMEM; - return -1; - } - - p = wpath + prefixlen; - goout = 0; - while (!goout) { - while (*p == '/') p++; - while (*p != '/' && *p != '\0') p++; - goout = (*p == '\0'); - *p = '\0'; - ret = mkdir(wpath, S_IRUSR | S_IWUSR | S_IXUSR); - if (ret < 0 && errno != EEXIST) break; - *p = '/'; - } - free(wpath); - return goout ? 0 : ret; -} - -static long regtime_trunc(long tv_sec) -{ - return tv_sec / (86400*7); -} - -static long regtime_ceil(long tv_sec) -{ - return (tv_sec % (86400*7)) ? tv_sec/(86400*7)+1 : tv_sec/(86400*7) ; -} - -/********************************************************************************/ -int glite_jppsbe_init( - glite_jp_context_t ctx, - int argc, - char *argv[] -) -{ - glite_jp_error_t err; - int opt; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - config = (struct ftpbe_config *) calloc(1, sizeof *config); - if (!config) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - - config->logname = getlogin(); - - while ((opt = getopt_long(argc, argv, "I:E:G:", ftpbe_opts, NULL)) != EOF) { - switch (opt) { - case 'I': config->internal_path = optarg; break; - case 'E': config->external_path = optarg; break; - case 'G': config->gridmap = optarg; break; - default: break; - } - } - - if (config_check(ctx, config)) { - err.code = EINVAL; - err.desc = "Invalid FTP backend configuration"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} - -int glite_jppsbe_init_slave( - glite_jp_context_t ctx -) -{ - /* Nothing to do */ -} - -int glite_jppsbe_register_job( - glite_jp_context_t ctx, - const char *job, - const char *owner -) -{ - glite_jp_error_t err; - char *int_dir = NULL; - char *int_fname = NULL; - char *data_dir = NULL; - char *data_fname = NULL; - char *ju = NULL; - char *ju_path = NULL; - char *ownerhash = NULL; - FILE *regfile = NULL; - struct timeval reg_tv; - long reg_tv_trunc; - struct stat statbuf; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(job != NULL); - assert(owner != NULL); - - gettimeofday(®_tv, NULL); - reg_tv_trunc = regtime_trunc(reg_tv.tv_sec); - - if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) { - err.code = ctx->error->code; - err.desc = "Cannot obtain jobid unique path/name"; - return glite_jp_stack_error(ctx,&err); - } - - if (asprintf(&int_dir, "%s/regs/%s", - config->internal_path, ju_path) == -1) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - - if (mkdirpath(int_dir, strlen(config->internal_path)) < 0 && - errno != EEXIST) { - free(int_dir); - err.code = errno; - err.desc = "Cannot mkdir jobs's reg directory"; - return glite_jp_stack_error(ctx,&err); - } - free(int_dir); - - if (asprintf(&int_fname, "%s/regs/%s/%s.info", - config->internal_path, ju_path, ju) == -1) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - - if (stat(int_fname, &statbuf) < 0) { - if (errno != ENOENT) { - err.code = errno; - err.desc = "Cannot stat jobs's reg info file"; - goto error_out; - } - } else { - err.code = EEXIST; - err.desc = "Job already registered"; - goto error_out; - } - - regfile = fopen(int_fname, "w"); - if (regfile == NULL) { - err.code = errno; - err.desc = "Cannot open jobs's reg info file"; - goto error_out; - } - - ownerhash = str2md5(owner); /* static buffer */ - - if (fprintf(regfile, "%d %ld.%06ld %s %s %d %s\n", 1, - (long)reg_tv.tv_sec, (long)reg_tv.tv_usec, job, - ownerhash, strlen(owner), owner) < 1 || ferror(regfile)) { - fclose(regfile); - err.code = errno; - err.desc = "Cannot write jobs's reg info file"; - goto error_out; - } - if (fclose(regfile) != 0 ) { - err.code = errno; - err.desc = "Cannot close(write) jobs's reg info file"; - goto error_out; - } - - if (asprintf(&data_dir, "%s/data/%s/%d/%s", - config->internal_path, ownerhash, regtime_trunc(reg_tv.tv_sec), ju) == -1) { - err.code = ENOMEM; - goto error_out; - } - if (asprintf(&data_fname, "%s/_info", data_dir) == -1) { - err.code = ENOMEM; - goto error_out; - } - if (mkdirpath(data_dir, strlen(config->internal_path)) < 0 && - errno != EEXIST) { - err.code = errno; - err.desc = "Cannot mkdir jobs's data directory"; - goto error_out; - } - - if (link(int_fname, data_fname) < 0) { - err.code = errno; - err.desc = "Cannot link job's reg and data info files"; - goto error_out; - } - -error_out: - free(int_fname); - free(data_fname); - if (err.code && data_dir) rmdir(data_dir); - free(data_dir); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -static int add_to_gridmap(glite_jp_context_t ctx, const char *dn) -{ - FILE *gridmap = NULL; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - gridmap = fopen(config->gridmap, "a"); - if (!gridmap) { - err.code = errno; - err.desc = "Cannot open gridmap file"; - return glite_jp_stack_error(ctx,&err); - } - if (fprintf(gridmap, "\"%s\" %s\n", dn, config->logname) < 6 || - ferror(gridmap)) { - err.code = EIO; - err.desc = "Cannot write to gridmap file"; - fclose(gridmap); - return glite_jp_stack_error(ctx,&err); - } - fclose(gridmap); - return 0; -} - -static int remove_from_gridmap(glite_jp_context_t ctx, const char *dn) -{ - FILE *gridmap = NULL; - char *temp_name = NULL; - FILE *temp_file = NULL; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - /* XXX */ - return 0; -} - -int glite_jppsbe_start_upload( - glite_jp_context_t ctx, - const char *job, - const char *class, - const char *name, /* TODO */ - const char *content_type, - char **destination_out, - time_t *commit_before_inout -) -{ - char *int_fname = NULL; - char *lock_fname = NULL; - FILE *lockfile = NULL; - FILE *regfile = NULL; - char *data_dir = NULL; - char *data_lock = NULL; - char *ju = NULL; - char *ju_path = NULL; - char *peername = NULL; - int info_version; - long reg_time; - char ownerhash[33]; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(job!=NULL); - assert(destination_out!=NULL); - - assert(class!=NULL); - - if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) { - err.code = ctx->error->code; - err.desc = "Cannot obtain jobid unique path/name"; - return glite_jp_stack_error(ctx,&err); - } - - peername = glite_jp_peer_name(ctx); - - if (asprintf(&int_fname, "%s/regs/%s/%s.info", - config->internal_path, ju_path, ju) == -1) { - err.code = ENOMEM; - goto error_out; - } - regfile = fopen(int_fname, "r"); - if (regfile == NULL) { - err.code = errno; - if (errno == ENOENT) - err.desc = "Job not registered"; - else - err.desc = "Cannot open jobs's reg info file"; - goto error_out; - } - if (fscanf(regfile, "%d %ld.%*ld %*s %s ", &info_version, - ®_time, ownerhash) < 3 || ferror(regfile)) { - fclose(regfile); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - fclose(regfile); - - /* XXX authorization */ - - if (asprintf(&data_dir, "%s/data/%s/%d/%s", - config->internal_path, ownerhash, regtime_trunc(reg_time), ju) == -1) { - err.code = ENOMEM; - goto error_out; - } - - if (asprintf(&lock_fname, "%s/%s" LOCK_SUFFIX, - data_dir, class) == -1) { - err.code = ENOMEM; - goto error_out; - } - - if (commit_before_inout != NULL) - *commit_before_inout = (time_t) LONG_MAX; /* XXX no timeout enforced */ - - lockfile = fopen(lock_fname, "w"); - if (lockfile == NULL) { - err.code = errno; - err.desc = "Cannot open uploads's lock file"; - goto error_out; - } - - if (fprintf(lockfile, "%ld %d %s\n", (long)*commit_before_inout, - peername ? peername : 0, - peername ? peername : "") < 1 || ferror(regfile)) { - fclose(lockfile); - err.code = errno; - err.desc = "Cannot write upload's lock file"; - goto error_out; - } - if (fclose(lockfile) != 0 ) { - err.code = errno; - err.desc = "Cannot close(write) upload's lock file"; - goto error_out; - } - - if (asprintf(destination_out, "%s/data/%s/%d/%s/%s" UPLOAD_SUFFIX, - config->external_path, ownerhash, regtime_trunc(reg_time), ju, class) == -1) { - err.code = ENOMEM; - goto error_out; - } - - if (add_to_gridmap(ctx, peername)) { - err.code = EIO; - err.desc = "Cannot add peer DN to ftp server authorization file"; - goto error_out; - } - -error_out: - free(int_fname); - free(data_dir); - if (err.code && data_lock) unlink(data_lock); - free(data_lock); - free(ju); free(ju_path); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -int glite_jppsbe_commit_upload( - glite_jp_context_t ctx, - const char *destination -) -{ - size_t dest_len; - size_t suff_len; - size_t extp_len; - long commit_before; - int lockpeerlen; - char *lockpeername = NULL; - char *peername = NULL; - char *dest_rw = NULL; - char *dest_rw_suff = NULL; - char *dest_rw_lock = NULL; - FILE *lockfile = NULL; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(destination != NULL); - - suff_len = strlen(UPLOAD_SUFFIX); - dest_len = strlen(destination); - extp_len = strlen(config->external_path); - - if (dest_len < suff_len || - strcmp(UPLOAD_SUFFIX, destination + (dest_len - suff_len)) || - strncmp(destination, config->external_path, extp_len)) { - err.code = EINVAL; - err.desc = "Forged destination path"; - return glite_jp_stack_error(ctx,&err); - } - - if (asprintf(&dest_rw_suff, "%s%s", config->internal_path, - destination + extp_len) == -1) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - dest_rw = strdup(dest_rw_suff); - if (!dest_rw) { - err.code = ENOMEM; - goto error_out; - } - *(dest_rw + (strlen(dest_rw_suff) - suff_len)) = '\0'; - - if (asprintf(&dest_rw_lock, "%s" LOCK_SUFFIX, dest_rw) == -1) { - err.code = ENOMEM; - goto error_out; - } - - lockfile = fopen(dest_rw_lock, "r"); - if (lockfile == NULL) { - err.code = errno; - err.desc = "Cannot open upload's lock file"; - goto error_out; - } - if (fscanf(lockfile, "%ld %d ", &commit_before, &lockpeerlen) < 2 || ferror(lockfile)) { - fclose(lockfile); - err.code = errno; - err.desc = "Cannot read upload's lock file"; - goto error_out; - } - if (lockpeerlen) { - lockpeername = (char*) calloc(1, lockpeerlen+1); - if (!lockpeername) { - err.code = ENOMEM; - goto error_out; - } - if (fgets(lockpeername, lockpeerlen+1, lockfile) == NULL) { - fclose(lockfile); - err.code = errno; - err.desc = "Cannot read upload's lock file"; - goto error_out; - } - } - fclose(lockfile); - - peername = glite_jp_peer_name(ctx); - if (lockpeername && (!peername || strcmp(lockpeername, peername))) { - err.code = EPERM; - err.desc = "Upload started by client of different identity"; - goto error_out; - } - - if (rename(dest_rw_suff, dest_rw) < 0) { - err.code = errno; - err.desc = "Cannot move upload file to the final place"; - goto error_out; - } - - if (unlink(dest_rw_lock) < 0) { - err.code = errno; - err.desc = "Cannot unlink upload's lock file"; - goto error_out; - } - -error_out: - free(dest_rw); - free(dest_rw_suff); - free(dest_rw_lock); - free(peername); - free(lockpeername); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -int glite_jppsbe_destination_info( - glite_jp_context_t ctx, - const char *destination, - char **job, - char **class, - char **name -) -{ - size_t dest_len; - size_t suff_len; - size_t extp_len; - char *dest_rw = NULL; - char *dest_rw_suff = NULL; - char *dest_rw_info = NULL; - FILE *infofile = NULL; - char *classname = NULL; - char jobstr[256+1]; - glite_jp_error_t err; - - assert(destination != NULL); - assert(job != NULL); - assert(class != NULL); - assert(name != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - suff_len = strlen(UPLOAD_SUFFIX); - dest_len = strlen(destination); - extp_len = strlen(config->external_path); - - if (dest_len < suff_len || - strcmp(UPLOAD_SUFFIX, destination + (dest_len - suff_len)) || - strncmp(destination, config->external_path, extp_len)) { - err.code = EINVAL; - err.desc = "Forged destination path"; - return glite_jp_stack_error(ctx,&err); - } - - if (asprintf(&dest_rw_suff, "%s%s", config->internal_path, - destination + extp_len) == -1) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - dest_rw = strdup(dest_rw_suff); - if (!dest_rw) { - err.code = ENOMEM; - goto error_out; - } - *(dest_rw + (strlen(dest_rw_suff) - suff_len)) = '\0'; - - classname = strrchr(dest_rw,'/'); - if (classname == NULL) { - err.code = EINVAL; - err.desc = "Forged destination path"; - goto error_out; - } - *classname++ ='\0'; - *class = strdup(classname); - -/* XXX: do we need similar check? - if (!class == GLITE_JP_FILECLASS_UNDEF) { - err.code = EINVAL; - err.desc = "Forged destination path"; - goto error_out; - } -*/ - - /* TODO: */ - *name = NULL; - - if (asprintf(&dest_rw_info, "%s/_info", dest_rw) == -1) { - err.code = ENOMEM; - goto error_out; - } - - infofile = fopen(dest_rw_info, "r"); - if (infofile == NULL) { - err.code = errno; - err.desc = "Cannot open _info file"; - goto error_out; - } - if (fscanf(infofile, "%*d %*ld.%*ld %256s ", jobstr) < 1 || ferror(infofile)) { - fclose(infofile); - err.code = errno; - err.desc = "Cannot read _info file"; - goto error_out; - } - *job = strdup(jobstr); - fclose(infofile); - -error_out: - free(dest_rw); - free(dest_rw_suff); - free(dest_rw_info); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - - -int glite_jppsbe_get_job_url( - glite_jp_context_t ctx, - const char *job, - const char *class, - const char *name, /* TODO */ - char **url_out -) -{ - FILE *regfile = NULL; - char *int_fname = NULL; - char *ju = NULL; - char *ju_path = NULL; - int info_version; - long reg_time; - char ownerhash[33]; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(job!=NULL); - assert(url_out != NULL); - - assert(class!=NULL); - - if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) { - err.code = ctx->error->code; - err.desc = "Cannot obtain jobid unique path/name"; - return glite_jp_stack_error(ctx,&err); - } - - if (asprintf(&int_fname, "%s/regs/%s/%s.info", - config->internal_path, ju_path, ju) == -1) { - err.code = ENOMEM; - goto error_out; - } - regfile = fopen(int_fname, "r"); - if (regfile == NULL) { - err.code = errno; - if (errno == ENOENT) - err.desc = "Job not registered"; - else - err.desc = "Cannot open jobs's reg info file"; - goto error_out; - } - if (fscanf(regfile, "%d %ld.%*ld %*s %s", &info_version, - ®_time, ownerhash) < 3 || ferror(regfile)) { - fclose(regfile); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - fclose(regfile); - - if (asprintf(url_out, "%s/data/%s/%d/%s/%s", - config->external_path, ownerhash, regtime_trunc(reg_time), ju, class) == -1) { - err.code = ENOMEM; - goto error_out; - } - -error_out: - free(int_fname); - free(ju); free(ju_path); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -static int get_job_fname( - glite_jp_context_t ctx, - const char *job, - const char *class, - const char *name, /* TODO */ - char **fname_out -) -{ - FILE *regfile = NULL; - char *int_fname = NULL; - char *ju = NULL; - char *ju_path = NULL; - int info_version; - long reg_time; - char ownerhash[33]; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(job!=NULL); - assert(fname_out != NULL); - - assert(class!=NULL); - - if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) { - err.code = ctx->error->code; - err.desc = "Cannot obtain jobid unique path/name"; - return glite_jp_stack_error(ctx,&err); - } - - if (asprintf(&int_fname, "%s/regs/%s/%s.info", - config->internal_path, ju_path, ju) == -1) { - err.code = ENOMEM; - goto error_out; - } - regfile = fopen(int_fname, "r"); - if (regfile == NULL) { - err.code = errno; - if (errno == ENOENT) - err.desc = "Job not registered"; - else - err.desc = "Cannot open jobs's reg info file"; - goto error_out; - } - if (fscanf(regfile, "%d %ld.%*ld %*s %s", &info_version, - ®_time, ownerhash) < 3 || ferror(regfile)) { - fclose(regfile); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - fclose(regfile); - - if (asprintf(fname_out, "%s/data/%s/%d/%s/%s", - config->internal_path, ownerhash, regtime_trunc(reg_time), ju, class) == -1) { - err.code = ENOMEM; - goto error_out; - } - -error_out: - free(int_fname); - free(ju); free(ju_path); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -int glite_jppsbe_open_file( - glite_jp_context_t ctx, - const char *job, - const char *class, - const char *name, /* TODO */ - int mode, - void **handle_out -) -{ - fhandle handle = NULL; - char* fname = NULL; - glite_jp_error_t err; - - assert(handle_out != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (get_job_fname(ctx, job, class, name, &fname)) { - err.code = ctx->error->code; - err.desc = "Cannot construct internal filename"; - return glite_jp_stack_error(ctx,&err); - } - - handle = (fhandle) calloc(1,sizeof(*handle)); - if (handle == NULL) { - err.code = ENOMEM; - goto error_out; - } - - handle->fd = open(fname, mode, S_IRUSR | S_IWUSR); - if (handle->fd < 0) { - err.code = errno; - err.desc = "Cannot open requested file"; - free(handle); - goto error_out; - } - handle->fd_append = open(fname, mode | O_APPEND, S_IRUSR | S_IWUSR); - if (handle->fd_append < 0) { - err.code = errno; - err.desc = "Cannot open requested file for append"; - close(handle->fd); - free(handle); - goto error_out; - } - *handle_out = (void*) handle; - -error_out: - free(fname); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -int glite_jppsbe_close_file( - glite_jp_context_t ctx, - void *handle -) -{ - glite_jp_error_t err; - - assert(handle != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (close(((fhandle)handle)->fd_append) < 0) { - err.code = errno; - err.desc = "Error closing file descriptor (fd_append)"; - goto error_out; - } - if (close(((fhandle)handle)->fd) < 0) { - err.code = errno; - err.desc = "Error closing file descriptor"; - goto error_out; - } - -error_out: - free(handle); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -int glite_jppsbe_pread( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes, - off_t offset, - ssize_t *nbytes_ret -) -{ - ssize_t ret; - glite_jp_error_t err; - - assert(handle != NULL); - assert(buf != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if ((ret = pread(((fhandle)handle)->fd, buf, nbytes, offset)) < 0) { - err.code = errno; - err.desc = "Error in pread()"; - return glite_jp_stack_error(ctx,&err); - } - *nbytes_ret = ret; - - return 0; -} - -int glite_jppsbe_pwrite( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes, - off_t offset -) -{ - glite_jp_error_t err; - - assert(handle != NULL); - assert(buf != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (pwrite(((fhandle)handle)->fd, buf, nbytes, offset) < 0) { - err.code = errno; - err.desc = "Error in pwrite()"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} - -int glite_jppsbe_append( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes -) -{ - glite_jp_error_t err; - - assert(handle != NULL); - assert(buf != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (write(((fhandle)handle)->fd_append, buf, nbytes) < 0) { - err.code = errno; - err.desc = "Error in write()"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} - -static int get_job_info( - glite_jp_context_t ctx, - const char *job, - char **owner, - struct timeval *tv_reg -) -{ - char *ju = NULL; - char *ju_path = NULL; - FILE *regfile = NULL; - long reg_time_sec; - long reg_time_usec; - int ownerlen = 0; - int info_version; - char *int_fname = NULL; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) { - err.code = ctx->error->code; - err.desc = "Cannot obtain jobid unique path/name"; - return glite_jp_stack_error(ctx,&err); - } - - if (asprintf(&int_fname, "%s/regs/%s/%s.info", - config->internal_path, ju_path, ju) == -1) { - err.code = ENOMEM; - goto error_out; - } - regfile = fopen(int_fname, "r"); - if (regfile == NULL) { - err.code = errno; - if (errno == ENOENT) - err.desc = "Job not registered"; - else - err.desc = "Cannot open jobs's reg info file"; - goto error_out; - } - if (fscanf(regfile, "%d %ld.%ld %*s %*s %d ", &info_version, - ®_time_sec, ®_time_usec, &ownerlen) < 4 || ferror(regfile)) { - fclose(regfile); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - if (ownerlen) { - *owner = (char *) calloc(1, ownerlen+1); - if (!*owner) { - err.code = ENOMEM; - goto error_out; - } - if (fgets(*owner, ownerlen+1, regfile) == NULL) { - fclose(regfile); - free(*owner); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - } - fclose(regfile); - - tv_reg->tv_sec = reg_time_sec; - tv_reg->tv_usec = reg_time_usec; - -error_out: - free(int_fname); - free(ju); - free(ju_path); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -static int get_job_info_int( - glite_jp_context_t ctx, - const char *int_fname, - char **jobid, - char **owner, - struct timeval *tv_reg -) -{ - FILE *regfile = NULL; - long reg_time_sec; - long reg_time_usec; - int ownerlen = 0; - int info_version; - char jobid_buf[256]; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - regfile = fopen(int_fname, "r"); - if (regfile == NULL) { - err.code = errno; - err.desc = "Cannot open jobs's reg info file"; - goto error_out; - } - if (fscanf(regfile, "%d %ld.%ld %s %*s %d ", &info_version, - ®_time_sec, ®_time_usec, jobid_buf, &ownerlen) < 5 || ferror(regfile)) { - fclose(regfile); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - *jobid = strdup(jobid_buf); - if (ownerlen) { - *owner = (char *) calloc(1, ownerlen+1); - if (!*owner) { - err.code = ENOMEM; - goto error_out; - } - if (fgets(*owner, ownerlen+1, regfile) == NULL) { - fclose(regfile); - free(*owner); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - } - fclose(regfile); - - tv_reg->tv_sec = reg_time_sec; - tv_reg->tv_usec = reg_time_usec; - -error_out: - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -int glite_jppsbe_get_job_metadata( - glite_jp_context_t ctx, - const char *job, - glite_jp_attrval_t attrs_inout[] -) -{ - int got_info = 0; - struct timeval tv_reg; - char *owner = NULL; - int got_tags = 0; - void *tags_handle = NULL; - glite_jp_tagval_t* tags = NULL; - int i,j; - glite_jp_error_t err; - - assert(job != NULL); - assert(attrs_inout != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - for (i = 0; attrs_inout[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) { - switch (attrs_inout[i].attr.type) { - case GLITE_JP_ATTR_OWNER: - -/* must be implemented via filetype plugin - case GLITE_JP_ATTR_TIME: -*/ - if (!got_info) { - if (get_job_info(ctx, job, &owner, &tv_reg)) { - err.code = ctx->error->code; - err.desc = "Cannot retrieve job info"; - goto error_out; - } - got_info = 1; - } - break; - -/* must be implemented via filetype plugin - case GLITE_JP_ATTR_TAG: - if (!got_tags) { - if (glite_jppsbe_open_file(ctx, job, GLITE_JP_FILECLASS_TAGS, - O_RDONLY, &tags_handle)) { - err.code = ctx->error->code; - err.desc = "Cannot open tag file"; - goto error_out; - } - if (glite_jpps_tag_readall(ctx, tags_handle, &tags)) { - err.code = ctx->error->code; - err.desc = "Cannot read tags"; - glite_jppsbe_close_file(ctx, tags_handle); - goto error_out; - } - glite_jppsbe_close_file(ctx, tags_handle); - got_tags = 1; - } - break; -*/ - default: - err.code = EINVAL; - err.desc = "Invalid attribute type"; - goto error_out; - break; - } - - switch (attrs_inout[i].attr.type) { - case GLITE_JP_ATTR_OWNER: - attrs_inout[i].value.s = strdup(owner); - if (!attrs_inout[i].value.s) { - err.code = ENOMEM; - err.desc = "Cannot copy owner string"; - goto error_out; - } - break; - case GLITE_JP_ATTR_TIME: - attrs_inout[i].value.time = tv_reg; - break; - -/* must be implemented via filetype plugin - case GLITE_JP_ATTR_TAG: - for (j = 0; tags[j].name != NULL; j++) { - if (!strcmp(tags[j].name, attrs_inout[i].attr.name)) { - if (glite_jpps_tagval_copy(ctx, &tags[j], - &attrs_inout[i].value.tag)) { - err.code = ENOMEM; - err.desc = "Cannot copy tag value"; - goto error_out; - } - break; - } - } - if (!tags[j].name) attrs_inout[i].value.tag.name = NULL; - break; -*/ - default: - break; - } - } - -error_out: - free(owner); - if (tags) for (j = 0; tags[j].name != NULL; j++) { - free(tags[j].name); - free(tags[j].value); - } - free(tags); - - if (err.code) { - while (i > 0) { - i--; - switch (attrs_inout[i].attr.type) { - case GLITE_JP_ATTR_OWNER: - free(attrs_inout[i].value.s); - break; - case GLITE_JP_ATTR_TAG: - free(attrs_inout[i].value.tag.name); - free(attrs_inout[i].value.tag.value); - default: - break; - } - } - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} -static int compare_timeval(struct timeval a, struct timeval b) -{ - if (a.tv_sec < b.tv_sec) return -1; - if (a.tv_sec > b.tv_sec) return 1; - if (a.tv_usec < b.tv_usec) return -1; - if (a.tv_usec > b.tv_usec) return 1; - return 0; -} - - -/* FIXME: disabled -- clarification wrt. filetype plugin needed */ - -#if 0 - -static int query_phase2( - glite_jp_context_t ctx, - const char *ownerhash, - long regtime_tr, - int q_tags, - int md_tags, - const glite_jp_query_rec_t query[], - glite_jp_attrval_t metadata[], - int (*callback)( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t metadata[] - ) -); - -static int query_phase2( - glite_jp_context_t ctx, - const char *ownerhash, - long regtime_tr, - int q_tags, - int md_tags, - const glite_jp_query_rec_t query[], - glite_jp_attrval_t metadata[], - int (*callback)( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t metadata[] - ) -) -{ - char *time_dirname = NULL; - DIR *time_dirp = NULL; - struct dirent *jobent; - char *info_fname = NULL; - char *jobid = NULL; - char *owner = NULL; - struct timeval tv_reg; - void *tags_handle = NULL; - int matching; - int i, j; - glite_jp_tagval_t* tags = NULL; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (asprintf(&time_dirname, "%s/data/%s/%d", config->internal_path, - ownerhash, regtime_tr) == -1) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - time_dirp = opendir(time_dirname); - if (!time_dirp) { - free(time_dirname); - return 0; /* found nothing */ - } - while ((jobent = readdir(time_dirp)) != NULL) { - if (!strcmp(jobent->d_name, ".")) continue; - if (!strcmp(jobent->d_name, "..")) continue; - if (asprintf(&info_fname, "%s/%s/_info", time_dirname, - jobent->d_name) == -1) { - err.code = ENOMEM; - goto error_out; - } - if (get_job_info_int(ctx, info_fname, &jobid, &owner, &tv_reg)) { - err.code = EIO; - err.desc = "Cannot retrieve job info"; - goto error_out; - } - if (q_tags || md_tags) { - if (glite_jppsbe_open_file(ctx, jobid, GLITE_JP_FILECLASS_TAGS, - O_RDONLY, &tags_handle)) { - err.code = ctx->error->code; - err.desc = "Cannot open tag file"; - goto error_out; - } - if (glite_jpps_tag_readall(ctx, tags_handle, &tags)) { - err.code = ctx->error->code; - err.desc = "Cannot read tags"; - glite_jppsbe_close_file(ctx, tags_handle); - goto error_out; - } - glite_jppsbe_close_file(ctx, tags_handle); - tags_handle = NULL; - } - - matching = 1; - for (i = 0; matching && query[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) { - switch (query[i].attr.type) { - case GLITE_JP_ATTR_OWNER: - if (query[i].value.s == NULL || - strcmp(query[i].value.s, owner)) matching = 0; - break; - case GLITE_JP_ATTR_TIME: - switch (query[i].op) { - case GLITE_JP_QUERYOP_EQUAL: - matching = !compare_timeval(tv_reg, query[i].value.time); - break; - case GLITE_JP_QUERYOP_UNEQUAL: - matching = compare_timeval(tv_reg, query[i].value.time); - break; - case GLITE_JP_QUERYOP_LESS: - matching = compare_timeval(tv_reg, query[i].value.time) < 0; - break; - case GLITE_JP_QUERYOP_GREATER: - matching = compare_timeval(tv_reg, query[i].value.time) > 0; - break; - case GLITE_JP_QUERYOP_WITHIN: - matching = compare_timeval(tv_reg, query[i].value.time) >= 0 - && compare_timeval(tv_reg, query[i].value2.time) <= 0; - break; - } - break; - case GLITE_JP_ATTR_TAG: - if (!tags) { - matching = 0; - break; - } - for (j = 0; tags[j].name != NULL; j++) { - if (!strcmp(tags[j].name, query[i].attr.name)) { - switch (query[i].op) { - case GLITE_JP_QUERYOP_EQUAL: - matching = !strcmp(tags[j].value, query[i].value.s); - break; - case GLITE_JP_QUERYOP_UNEQUAL: - matching = strcmp(tags[j].value, query[i].value.s); - break; - case GLITE_JP_QUERYOP_LESS: - matching = strcmp(tags[j].value, query[i].value.s) < 0; - break; - case GLITE_JP_QUERYOP_GREATER: - matching = strcmp(tags[j].value, query[i].value.s) > 0; - break; - case GLITE_JP_QUERYOP_WITHIN: - matching = strcmp(tags[j].value, query[i].value.s) >= 0 \ - && strcmp(tags[j].value, query[i].value2.s) <= 0 ; - break; - default: - break; - } - } - } - break; - default: - break; - } - } - if (!matching) { - free(info_fname); info_fname = NULL; - free(jobid); jobid = NULL; - if (tags) for (j = 0; tags[j].name != NULL; j++) { - free(tags[j].name); - free(tags[j].value); - } - free(tags); tags = NULL; - continue; - } - - for (i = 0; metadata[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) { - switch (metadata[i].attr.type) { - case GLITE_JP_ATTR_OWNER: - metadata[i].value.s = owner; - break; - case GLITE_JP_ATTR_TIME: - metadata[i].value.time = tv_reg; - break; - case GLITE_JP_ATTR_TAG: - for (j = 0; tags[j].name != NULL; j++) { - if (!strcmp(tags[j].name, metadata[i].attr.name)) { - if (glite_jpps_tagval_copy(ctx, &tags[j], - &metadata[i].value.tag)) { - err.code = ENOMEM; - err.desc = "Cannot copy tag value"; - goto error_out; - } - break; - } - } - if (!tags[j].name) { - metadata[i].value.tag.name = NULL; - metadata[i].value.tag.value = NULL; - } - break; - default: - break; - } - } - (*callback)(ctx, jobid, metadata); - free(jobid); jobid = NULL; - while (i > 0) { - i--; - switch (metadata[i].attr.type) { - case GLITE_JP_ATTR_TAG: - free(metadata[i].value.tag.name); - free(metadata[i].value.tag.value); - default: - break; - } - } - } - -error_out: - if (tags) for (j = 0; tags[j].name != NULL; j++) { - free(tags[j].name); - free(tags[j].value); - } - if (tags_handle) glite_jppsbe_close_file(ctx, tags_handle); - free(info_fname); - free(owner); - free(jobid); - closedir(time_dirp); - free(time_dirname); - if (err.code) { - while (i > 0) { - i--; - switch (metadata[i].attr.type) { - case GLITE_JP_ATTR_TAG: - free(metadata[i].value.tag.name); - free(metadata[i].value.tag.value); - default: - break; - } - } - return glite_jp_stack_error(ctx,&err); - } else - return 0; -} - -int glite_jppsbe_query( - glite_jp_context_t ctx, - const glite_jp_query_rec_t query[], - const glite_jp_attrval_t metadata[], - int (*callback)( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t metadata[] - ) -) -{ - /* XXX clone metadata */ - int i; - char *q_exact_owner = NULL; - char *ownerhash = NULL; - long q_min_time = 0; - long q_max_time = LONG_MAX; - long q_min_time_tr; - long q_max_time_tr; - int q_with_tags = 0; - int md_info = 0; - int md_tags = 0; - char *owner_dirname = NULL; - DIR *owner_dirp = NULL; - struct dirent *ttimeent; - char *data_dirname = NULL; - DIR *data_dirp = NULL; - struct dirent *ownerent; - long ttime = 0; - glite_jp_attrval_t *metadata_templ = NULL; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - for (i = 0; query[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) { - if (query[i].attr.type == GLITE_JP_ATTR_OWNER && query[i].op == GLITE_JP_QUERYOP_EQUAL) { - q_exact_owner = query[i].value.s; - } - if (query[i].attr.type == GLITE_JP_ATTR_TIME) { - switch (query[i].op) { - case GLITE_JP_QUERYOP_EQUAL: - q_min_time = query[i].value.time.tv_sec; - q_max_time = query[i].value.time.tv_sec + 1; - break; - case GLITE_JP_QUERYOP_LESS: - if (q_max_time > query[i].value.time.tv_sec + 1) - q_max_time = query[i].value.time.tv_sec + 1; - break; - case GLITE_JP_QUERYOP_WITHIN: - if (q_max_time > query[i].value2.time.tv_sec + 1) - q_max_time = query[i].value2.time.tv_sec + 1; - /* fallthrough */ - case GLITE_JP_QUERYOP_GREATER: - if (q_min_time < query[i].value.time.tv_sec) - q_min_time = query[i].value.time.tv_sec; - break; - default: - err.code = EINVAL; - err.desc = "Invalid query op"; - return glite_jp_stack_error(ctx,&err); - break; - } - } - if (query[i].attr.type == GLITE_JP_ATTR_TAG) - q_with_tags = 1; - - } - - for (i = 0; metadata[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) { - switch (metadata[i].attr.type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TIME: - md_info = 1; - break; - case GLITE_JP_ATTR_TAG: - md_tags = 1; - break; - default: - err.code = EINVAL; - err.desc = "Invalid attribute type in metadata parameter"; - return glite_jp_stack_error(ctx,&err); - break; - } - } - metadata_templ = (glite_jp_attrval_t *) calloc(i + 1, sizeof(glite_jp_attrval_t)); - if (!metadata_templ) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - memcpy(metadata_templ, metadata, (i + 1) * sizeof(glite_jp_attrval_t)); - - q_min_time_tr = regtime_trunc(q_min_time); - q_max_time_tr = regtime_ceil(q_max_time); - - if (q_exact_owner) { - ownerhash = str2md5(q_exact_owner); /* static buffer */ - if (asprintf(&owner_dirname, "%s/data/%s", config->internal_path, ownerhash) == -1) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - owner_dirp = opendir(owner_dirname); - free(owner_dirname); - if (!owner_dirp) { - free(metadata_templ); - return 0; /* found nothing */ - } - while ((ttimeent = readdir(owner_dirp)) != NULL) { - if (!strcmp(ttimeent->d_name, ".")) continue; - if (!strcmp(ttimeent->d_name, "..")) continue; - ttime = atol(ttimeent->d_name); - if (ttime >= q_min_time_tr && ttime < q_max_time_tr) { - if (query_phase2(ctx, ownerhash, ttime, q_with_tags, md_tags, - query, metadata_templ, callback)) { - err.code = EIO; - err.desc = "query_phase2() error"; - goto error_out; - } - } - } - } else { /* !q_exact_owner */ - if (asprintf(&data_dirname, "%s/data", config->internal_path) == -1) { - err.code = ENOMEM; - goto error_out; - } - data_dirp = opendir(data_dirname); - if (!data_dirp) { - err.code = EIO; - err.desc = "Cannot open data directory"; - goto error_out; - } - while ((ownerent = readdir(data_dirp)) != NULL) { - if (!strcmp(ownerent->d_name, ".")) continue; - if (!strcmp(ownerent->d_name, "..")) continue; - if (asprintf(&owner_dirname, "%s/data/%s", config->internal_path, - ownerent->d_name) == -1) { - err.code = ENOMEM; - goto error_out; - } - owner_dirp = opendir(owner_dirname); - free(owner_dirname); - if (!owner_dirp) { - err.code = EIO; - err.desc = "Cannot open owner data directory"; - goto error_out; - } - while ((ttimeent = readdir(owner_dirp)) != NULL) { - if (!strcmp(ttimeent->d_name, ".")) continue; - if (!strcmp(ttimeent->d_name, "..")) continue; - ttime = atol(ttimeent->d_name); - if (ttime >= q_min_time_tr && ttime < q_max_time_tr) { - if (query_phase2(ctx, ownerent->d_name, ttime, q_with_tags, md_tags, - query, metadata_templ, callback)) { - err.code = EIO; - err.desc = "query_phase2() error"; - goto error_out; - } - } - } - closedir(owner_dirp); owner_dirp = NULL; - } - closedir(data_dirp); data_dirp = NULL; - } - return 0; - -error_out: - if (owner_dirp) closedir(owner_dirp); - if (data_dirp) closedir(data_dirp); - free(data_dirname); - free(metadata_templ); - return glite_jp_stack_error(ctx,&err); -} - -#else - -/* placeholder instead */ -int glite_jppsbe_query( - glite_jp_context_t ctx, - const glite_jp_query_rec_t query[], - const glite_jp_attrval_t metadata[], - int (*callback)( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t metadata[] - ) -) -{ - glite_jp_error_t err; - err.code = ENOSYS; - err.desc = "not implemented"; - return glite_jp_stack_error(ctx,&err); -} - -#endif - -/* XXX: -- no primary authorization yet -- no concurrency control yet -- partial success in pwrite,append -- "unique" part of jobid is assumed to be unique across bookkeeping servers -- repository versioning not fully implemented yet -*/ diff --git a/org.glite.jp.primary/src/is_client.c b/org.glite.jp.primary/src/is_client.c deleted file mode 100644 index 8a747ef..0000000 --- a/org.glite.jp.primary/src/is_client.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "glite/jp/types.h" - -#include "feed.h" -/* FIXME -#include "jpis_H.h" -#include "jpis_.nsmap" -*/ - -int glite_jpps_single_feed( - glite_jp_context_t ctx, - const char *destination, - const char *job, - const glite_jp_attrval_t attrs[] -) -{ - /* TODO: really call JP Index server (via interlogger) */ - printf("feed to %s, job %s\n",destination,job); - -/* FIXME */ -#if 0 - if (soap_call_jpsrv__UpdateJobs(ctx->other_soap,destination,"", - /* FIXME: feedId */ "", - /* FIXME: UpdateJobsData */ NULL, - 0, - NULL - )) fprintf(stderr,"UpdateJobs: %s %s\n",ctx->other_soap->fault->faultcode, - ctx->other_soap->fault->faultstring); - -#endif - return 0; -} diff --git a/org.glite.jp.primary/src/jptype_map.h b/org.glite.jp.primary/src/jptype_map.h deleted file mode 100644 index 56d611f..0000000 --- a/org.glite.jp.primary/src/jptype_map.h +++ /dev/null @@ -1,18 +0,0 @@ -#include "soap_version.h" - -#if GSOAP_VERSION >= 20700 -#define INPUT_SANDBOX jptype__UploadClass__INPUT_SANDBOX -#define OUTPUT_SANDBOX jptype__UploadClass__OUTPUT_SANDBOX -#define JOB_LOG jptype__UploadClass__JOB_LOG - -#define OWNER jptype__AttributeType__OWNER -#define TIME jptype__AttributeType__TIME -#define TAG jptype__AttributeType__TAG - -#define EQUAL jptype__queryOp__EQUAL -#define UNEQUAL jptype__queryOp__UNEQUAL -#define LESS jptype__queryOp__LESS -#define GREATER jptype__queryOp__GREATER -#define WITHIN jptype__queryOp__WITHIN -#endif - diff --git a/org.glite.jp.primary/src/mysql.c b/org.glite.jp.primary/src/mysql.c deleted file mode 100644 index 591d8e1..0000000 --- a/org.glite.jp.primary/src/mysql.c +++ /dev/null @@ -1,260 +0,0 @@ -#ident "$Header$" - -#include "mysql.h" // MySql header file -#include "mysqld_error.h" -#include "errmsg.h" - -#include -#include -#include -#include -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "db.h" - -#define DEFAULTCS "jpps/@localhost:jpps1" - -static int my_err(glite_jp_context_t ctx, char *function) -{ - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = function; - err.code = EIO; /* XXX */ - err.desc = mysql_error((MYSQL *) ctx->dbhandle); - return glite_jp_stack_error(ctx,&err); -} - -struct _glite_jp_db_stmt_t { - MYSQL_RES *result; - glite_jp_context_t ctx; -}; - -int glite_jp_db_connect(glite_jp_context_t ctx,char *cs) -{ - char *buf = NULL; - char *host,*user,*pw,*db; - char *slash,*at,*colon; - - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (!cs) cs = DEFAULTCS; - - if (!(ctx->dbhandle = (void *) mysql_init(NULL))) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - - mysql_options(ctx->dbhandle, MYSQL_READ_DEFAULT_FILE, "my"); - - host = user = pw = db = NULL; - - buf = strdup(cs); - slash = strchr(buf,'/'); - at = strrchr(buf,'@'); - colon = strrchr(buf,':'); - - if (!slash || !at || !colon) { - free(buf); - err.code = EINVAL; - err.desc = "Invalid DB connect string"); - return glite_jp_stack_error(ctx,&err); - } - - *slash = *at = *colon = 0; - host = at+1; - user = buf; - pw = slash+1; - db = colon+1; - - if (!mysql_real_connect((MYSQL *) ctx->dbhandle,host,user,pw,db,0,NULL,CLIENT_FOUND_ROWS)) { - free(buf); - return my_err(ctx, __FUNCTION__); - } - - free(buf); - return 0; -} - -void glite_jp_db_close(glite_jp_context_t ctx) -{ - mysql_close((MYSQL *) ctx->dbhandle); - ctx->dbhandle = NULL; -} - -int glite_jp_db_execstmt(glite_jp_context_t ctx,char *txt,glite_jp_db_stmt_t *stmt) -{ - int err; - int retry_nr = 0; - int do_reconnect = 0; - - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (stmt) { - *stmt = NULL; - } - - while (retry_nr == 0 || do_reconnect) { - do_reconnect = 0; - if (mysql_query((MYSQL *) ctx->dbhandle,txt)) { - /* error occured */ - switch (err = mysql_errno((MYSQL *) ctx->dbhandle)) { - case 0: - break; - case ER_DUP_ENTRY: - err.code = EEXIST; - err.desc = mysql_error((MYSQL *) ctx->dbhandle)); - glite_jp_stack_error(ctx,&err); - return -1; - break; - case CR_SERVER_LOST: - if (retry_nr <= 0) - do_reconnect = 1; - break; - default: - my_err(ctx, __FUNCTION__); - return -1; - break; - } - } - retry_nr++; - } - - if (stmt) { - *stmt = malloc(sizeof(**stmt)); - if (!*stmt) { - err.code = ENOMEM; - glite_jp_stack_error(ctx,&err); - return -1; - } - memset(*stmt,0,sizeof(**stmt)); - (**stmt).ctx = ctx; - (**stmt).result = mysql_store_result((MYSQL *) ctx->dbhandle); - if (!(**stmt).result) { - if (mysql_errno((MYSQL *) ctx->dbhandle)) { - my_err(ctx, __FUNCTION__); - return -1; - } - } - } else { - MYSQL_RES *r = mysql_store_result((MYSQL *) ctx->dbhandle); - mysql_free_result(r); - } - - return mysql_affected_rows((MYSQL *) ctx->dbhandle); -} - -int glite_jp_db_fetchrow(glite_jp_db_stmt_t stmt,char **res) -{ - MYSQL_ROW row; - glite_jp_context_t ctx = stmt->ctx; - int nr,i; - unsigned long *len; - - glite_jp_clear_error(ctx); - - if (!stmt->result) return 0; - - if (!(row = mysql_fetch_row(stmt->result))) { - if (mysql_errno((MYSQL *) ctx->dbhandle)) { - my_err(ctx, __FUNCTION__); - return -1; - } else return 0; - } - - nr = mysql_num_fields(stmt->result); - len = mysql_fetch_lengths(stmt->result); - for (i=0; iresult))) cols[i++] = f->name; - return i == 0; -} - -void glite_jp_db_freestmt(glite_jp_db_stmt_t *stmt) -{ - if (*stmt) { - if ((**stmt).result) mysql_free_result((**stmt).result); - free(*stmt); - *stmt = NULL; - } -} - - -char *glite_jp_db_timetodb(time_t t) -{ - struct tm *tm = gmtime(&t); - char tbuf[256]; - - sprintf(tbuf,"'%4d-%02d-%02d %02d:%02d:%02d'",tm->tm_year+1900,tm->tm_mon+1, - tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec); - - return strdup(tbuf); -} - -time_t glite_jp_db_dbtotime(char *t) -{ - struct tm tm; - - memset(&tm,0,sizeof(tm)); - setenv("TZ","UTC",1); tzset(); - sscanf(t,"%4d-%02d-%02d %02d:%02d:%02d", - &tm.tm_year,&tm.tm_mon,&tm.tm_mday, - &tm.tm_hour,&tm.tm_min,&tm.tm_sec); - tm.tm_year -= 1900; - tm.tm_mon--; - - return mktime(&tm); -} - -int glite_jp_db_dbcheckversion(glite_jp_context_t ctx) -{ - MYSQL *m = (MYSQL *) ctx->dbhandle; - const char *ver_s = mysql_get_server_info(m); - int major,minor,sub,version; - - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (!ver_s || 3 != sscanf(ver_s,"%d.%d.%d",&major,&minor,&sub)) { - err.code = EINVAL; - err.desc = "problem checking MySQL version"; - return glite_jp_stack_error(ctx,&err); - } - - version = 10000*major + 100*minor + sub; - - if (version < GLITE_JP_LB_MYSQL_VERSION) { - char msg[300]; - - snprintf(msg,sizeof msg,"Your MySQL version is %d. At least %d required.",version, GLITE_JP_LB_MYSQL_VERSION); - err.code = EINVAL; - err.desc = msg; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} diff --git a/org.glite.jp.primary/src/simple_server.c b/org.glite.jp.primary/src/simple_server.c deleted file mode 100644 index 3bbb743..0000000 --- a/org.glite.jp.primary/src/simple_server.c +++ /dev/null @@ -1,59 +0,0 @@ -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "jpps_H.h" - -extern SOAP_NMAC struct Namespace jpis__namespaces[],jpps__namespaces[]; - -int main(int argc, char *argv[]) { - struct soap soap; - int i, m, s; // master and slave sockets - - glite_jp_context_t ctx; - - soap_init(&soap); - soap_set_namespaces(&soap, jpps__namespaces); - - glite_jp_init_context(&ctx); - - if (glite_jppsbe_init(ctx, &argc, argv)) { - /* XXX log */ - fputs(glite_jp_error_chain(ctx), stderr); - exit(1); - } - - soap.user = (void *) ctx; - - ctx->other_soap = soap_new(); - soap_init(ctx->other_soap); - soap_set_namespaces(ctx->other_soap,jpis__namespaces); - - srand48(time(NULL)); /* feed id generation */ - - m = soap_bind(&soap, NULL, 8901, 100); - if (m < 0) - soap_print_fault(&soap, stderr); - else - { - fprintf(stderr, "Socket connection successful: master socket = %d\n", m); - for (i = 1; ; i++) { - s = soap_accept(&soap); - if (s < 0) { - soap_print_fault(&soap, stderr); - break; - } - jpps__serve(&soap); // process RPC request - soap_destroy(&soap); // clean up class instances - soap_end(&soap); // clean up everything and close socket - glite_jp_run_deferred(ctx); - } - } - soap_done(&soap); // close master socket - - return 0; -} - -/* XXX: we don't use it */ -SOAP_NMAC struct Namespace namespaces[] = { {NULL,NULL} }; diff --git a/org.glite.jp.primary/src/soap_ops.c b/org.glite.jp.primary/src/soap_ops.c deleted file mode 100644 index 6ef1796..0000000 --- a/org.glite.jp.primary/src/soap_ops.c +++ /dev/null @@ -1,445 +0,0 @@ -#include -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "feed.h" - -#include "jpps_H.h" -/* #include "JobProvenancePS.nsmap" */ -#include "jpps_.nsmap" - -#include "jptype_map.h" - -#include "file_plugin.h" -#include "builtin_plugins.h" - -static struct jptype__genericFault *jp2s_error(struct soap *soap, - const glite_jp_error_t *err) -{ - struct jptype__genericFault *ret = NULL; - if (err) { - ret = soap_malloc(soap,sizeof *ret); - memset(ret,0,sizeof *ret); - ret->code = err->code; - ret->source = soap_strdup(soap,err->source); - ret->text = soap_strdup(soap,strerror(err->code)); - ret->description = soap_strdup(soap,err->desc); - ret->reason = jp2s_error(soap,err->reason); - } - return ret; -} - -static void err2fault(const glite_jp_context_t ctx,struct soap *soap) -{ - char *et; - struct SOAP_ENV__Detail *detail = soap_malloc(soap,sizeof *detail); - struct _genericFault *f = soap_malloc(soap,sizeof *f); - - - f->jpelem__genericFault = jp2s_error(soap,ctx->error); - - detail->__type = SOAP_TYPE__genericFault; -#if GSOAP_VERSION >= 20700 - detail->fault = f; -#else - detail->value = f; -#endif - detail->__any = NULL; - - soap_receiver_fault(soap,"Oh, shit!",NULL); - if (soap->version == 2) soap->fault->SOAP_ENV__Detail = detail; - else soap->fault->detail = detail; -} - -/* deprecated -static glite_jp_fileclass_t s2jp_fileclass(enum jptype__UploadClass class) -{ - switch (class) { - case INPUT_SANDBOX: return GLITE_JP_FILECLASS_INPUT; - case OUTPUT_SANDBOX: return GLITE_JP_FILECLASS_OUTPUT; - case JOB_LOG: return GLITE_JP_FILECLASS_LBLOG; - default: return GLITE_JP_FILECLASS_UNDEF; - } -} -*/ - -static void s2jp_tag(const struct jptype__tagValue *stag,glite_jp_tagval_t *jptag) -{ - memset(jptag,0,sizeof *jptag); - jptag->name = strdup(stag->name); - jptag->sequence = stag->sequence ? *stag->sequence : 0; - jptag->timestamp = stag->timestamp ? *stag->timestamp : 0; - if (stag->stringValue) jptag->value = strdup(stag->stringValue); - else if (stag->blobValue) { - jptag->binary = 1; - jptag->size = stag->blobValue->__size; - jptag->value = (char *) stag->blobValue->__ptr; - } -} - -#define CONTEXT_FROM_SOAP(soap,ctx) glite_jp_context_t ctx = (glite_jp_context_t) ((soap)->user) - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__RegisterJob( - struct soap *soap, - struct _jpelem__RegisterJob *in, - struct _jpelem__RegisterJobResponse *empty) -// struct __jpsrv__RegisterJobResponse *empty) -{ - CONTEXT_FROM_SOAP(soap,ctx); - glite_jp_attrval_t owner_val[2]; - - printf("%s %s %s\n",__FUNCTION__,in->job,in->owner); - if (glite_jppsbe_register_job(ctx,in->job,in->owner)) { - err2fault(ctx,soap); - return SOAP_FAULT; - } - - owner_val[0].attr.type = GLITE_JP_ATTR_OWNER; - owner_val[0].value.s = in->owner; - owner_val[1].attr.type = GLITE_JP_ATTR_UNDEF; - -/* XXX: errrors should be ingored but not silently */ - glite_jpps_match_attr(ctx,in->job,owner_val); - - return SOAP_OK; -} - - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__StartUpload( - struct soap *soap, - struct _jpelem__StartUpload *in, - struct _jpelem__StartUploadResponse *out) -{ - CONTEXT_FROM_SOAP(soap,ctx); - char *destination; - time_t commit_before; - glite_jp_error_t err; - glite_jpps_fplug_data_t **pd = NULL; - int i; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - - switch (glite_jpps_fplug_lookup(ctx,in->class_,&pd)) { - case ENOENT: - err.code = ENOENT; - err.source = __FUNCTION__; - err.desc = "unknown file class"; - glite_jp_stack_error(ctx,&err); - err2fault(ctx,soap); - return SOAP_FAULT; - case 0: break; - default: - err2fault(ctx,soap); - return SOAP_FAULT; - } - - for (i=0; pd[0]->uris[i] && strcmp(pd[0]->uris[i],in->class_); i++); - assert(pd[0]->uris[i]); - - if (glite_jppsbe_start_upload(ctx,in->job,pd[0]->classes[i],in->name,in->contentType, - &destination,&commit_before)) - { - err2fault(ctx,soap); - free(pd); - return SOAP_FAULT; - } - - out->destination = soap_strdup(soap,destination); - free(destination); - out->commitBefore = commit_before; - - free(pd); - return SOAP_OK; -} - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__CommitUpload( - struct soap *soap, - struct _jpelem__CommitUpload *in, - struct _jpelem__CommitUploadResponse *out) -{ - CONTEXT_FROM_SOAP(soap,ctx); - char *job,*class,*name; - - job = class = name = NULL; - - if (glite_jppsbe_commit_upload(ctx,in->destination)) { - err2fault(ctx,soap); - return SOAP_FAULT; - } - - /* XXX: should not fail when commit_upload was OK */ - glite_jppsbe_destination_info(ctx,in->destination,&job,&class,&name); - - /* XXX: ignore errors but don't fail silenty */ - glite_jpps_match_file(ctx,job,class,name); - - free(job); free(class); free(name); - - return SOAP_OK; -} - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__RecordTag( - struct soap *soap, - struct _jpelem__RecordTag *in, - struct _jpelem__RecordTagResponse *out) -{ - CONTEXT_FROM_SOAP(soap,ctx); - void *file_be,*file_p; - glite_jpps_fplug_data_t **pd = NULL; - - glite_jp_tagval_t mytag; - - file_be = file_p = NULL; - - /* XXX: we assume just one plugin and also that TAGS plugin handles - * just one uri/class */ - - if (glite_jpps_fplug_lookup(ctx,GLITE_JP_FILETYPE_TAGS,&pd) - || glite_jppsbe_open_file(ctx,in->jobid,pd[0]->classes[0],NULL, - O_WRONLY|O_CREAT,&file_be) - ) { - free(pd); - err2fault(ctx,soap); - return SOAP_FAULT; - } - - s2jp_tag(in->tag,&mytag); - - /* XXX: assuming tag plugin handles just one type */ - if (pd[0]->ops.open(pd[0]->fpctx,file_be,GLITE_JP_FILETYPE_TAGS,&file_p) - || pd[0]->ops.generic(pd[0]->fpctx,file_p,GLITE_JP_FPLUG_TAGS_APPEND,&mytag)) - { - err2fault(ctx,soap); - if (file_p) pd[0]->ops.close(pd[0]->fpctx,file_p); - glite_jppsbe_close_file(ctx,file_be); - free(pd); - return SOAP_FAULT; - } - - if (pd[0]->ops.close(pd[0]->fpctx,file_p) - || glite_jppsbe_close_file(ctx,file_be)) - { - err2fault(ctx,soap); - free(pd); - return SOAP_FAULT; - } - - /* XXX: ignore errors but don't fail silenty */ - glite_jpps_match_tag(ctx,in->jobid,&mytag); - - free(pd); - return SOAP_OK; -} - -extern char *glite_jp_default_namespace; - -/* XXX: should be public */ -#define GLITE_JP_TAGS_NAMESPACE "http://glite.org/services/jp/tags" - -static void s2jp_attr(const char *in,glite_jp_attr_t *out) -{ - char *buf = strdup(in),*name = strchr(buf,':'),*ns = NULL; - - if (name) { - ns = buf; - *name++ = 0; - } - else { - name = buf; - ns = glite_jp_default_namespace; - } - - memset(out,0,sizeof *out); - - if (strcmp(ns,glite_jp_default_namespace)) - out->type = strcmp(ns,GLITE_JP_TAGS_NAMESPACE) ? - GLITE_JP_ATTR_GENERIC : GLITE_JP_ATTR_TAG; - else { - if (!strcmp(name,"owner")) out->type = GLITE_JP_ATTR_OWNER; - else if (!strcmp(name,"time")) out->type = GLITE_JP_ATTR_OWNER; - - } - - if (out->type) { - out->name = strdup(name); - out->namespace = strdup(ns); - } -} - -static void s2jp_queryval( - const char *in, - glite_jp_attrtype_t type, - union _glite_jp_query_rec_val *out) -{ - switch (type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TAG: - case GLITE_JP_ATTR_GENERIC: - out->s = strdup(in); - break; - case GLITE_JP_ATTR_TIME: - out->time.tv_sec = atoi(in); - break; - } -} - -static void s2jp_query(const struct jptype__primaryQuery *in, glite_jp_query_rec_t *out) -{ - s2jp_attr(in->attr,&out->attr); - - switch (in->op) { - case EQUAL: out->op = GLITE_JP_QUERYOP_EQUAL; break; - case UNEQUAL: out->op = GLITE_JP_QUERYOP_UNEQUAL; break; - case LESS: out->op = GLITE_JP_QUERYOP_LESS; break; - case GREATER: out->op = GLITE_JP_QUERYOP_GREATER; break; - case WITHIN: - out->op = GLITE_JP_QUERYOP_WITHIN; - s2jp_queryval(in->value2,out->attr.type,&out->value2); - break; - } - - s2jp_queryval(in->value,out->attr.type,&out->value); -} - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__FeedIndex( - struct soap *soap, - struct _jpelem__FeedIndex *in, - struct _jpelem__FeedIndexResponse *out) -{ - -/* deferred processing: return feed_id to the index server first, - * start feeding it afterwards -- not before the index server actually - * knows feed_id and is ready to accept the feed. - * - * Has to be done within the same server slave, - * passed through the context */ - - CONTEXT_FROM_SOAP(soap,ctx); - char *feed_id = NULL; - time_t expires = 0; - int ret = SOAP_OK; - - glite_jp_attr_t *attrs = calloc(in->__sizeattributes+1,sizeof *attrs); - glite_jp_query_rec_t *qry = calloc(in->__sizeconditions+1,sizeof *qry); - int i; - - glite_jp_clear_error(ctx); - - for (i = 0; i__sizeattributes; i++) s2jp_attr(in->attributes[i],attrs+i); - for (i = 0; i__sizeconditions; i++) s2jp_query(in->conditions[i],qry+i); - - if (in->history) { - if (glite_jpps_run_feed(ctx,in->destination,attrs,qry,&feed_id)) { - err2fault(ctx,soap); - ret = SOAP_FAULT; - goto cleanup; - } - } - - if (in->continuous) { - if (glite_jpps_register_feed(ctx,in->destination,attrs,qry,&feed_id,&expires)) { - err2fault(ctx,soap); - ret = SOAP_FAULT; - goto cleanup; - } - } - - if (!in->history && !in->continuous) { - glite_jp_error_t err; - memset(&err,0,sizeof err); - err.code = EINVAL; - err.source = __FUNCTION__; - err.desc = "at least one of and must be true"; - glite_jp_stack_error(ctx,&err); - err2fault(ctx,soap); - ret = SOAP_FAULT; - goto cleanup; - } - - out->feedExpires = expires; - out->feedId = soap_strdup(soap,feed_id); - -cleanup: - free(feed_id); - for (i=0; attrs[i].type; i++) free(attrs[i].name); - free(attrs); - for (i=0; qry[i].attr.type; i++) glite_jp_free_query_rec(qry+i); - free(qry); - - return ret; -} - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__FeedIndexRefresh( - struct soap *soap, - struct _jpelem__FeedIndexRefresh *in, - struct _jpelem__FeedIndexRefreshResponse *out) -{ - fprintf(stderr,"%s: not implemented\n",__FUNCTION__); - abort(); -} - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__GetJob( - struct soap *soap, - struct _jpelem__GetJob *in, - struct _jpelem__GetJobResponse *out) -{ - CONTEXT_FROM_SOAP(soap,ctx); - char *url; - - int i,n; - glite_jp_error_t err; - void **pd; - struct jptype__jppsFile **f = NULL; - - memset(&err,0,sizeof err); - out->__sizefiles = 0; - - for (pd = ctx->plugins; *pd; pd++) { - glite_jpps_fplug_data_t *plugin = *pd; - - for (i=0; plugin->uris[i]; i++) { - glite_jp_clear_error(ctx); - switch (glite_jppsbe_get_job_url(ctx,in->jobid,plugin->classes[i],NULL,&url)) { - case 0: n = out->__sizefiles++; - f = realloc(f,out->__sizefiles * sizeof *f); - f[n] = soap_malloc(soap, sizeof **f); - f[n]->class_ = soap_strdup(soap,plugin->uris[i]); - f[n]->name = NULL; - f[n]->url = soap_strdup(soap,url); - free(url); - break; - case ENOENT: - break; - default: - err.code = ctx->error->code; - err.source = "jpsrv__GetJob()"; - err.desc = plugin->uris[i]; - glite_jp_stack_error(ctx,&err); - err2fault(ctx,soap); - glite_jp_clear_error(ctx); - return SOAP_FAULT; - } - } - } - - if (!out->__sizefiles) { - glite_jp_clear_error(ctx); - err.code = ENOENT; - err.source = __FUNCTION__; - err.desc = "No file found for this job"; - glite_jp_stack_error(ctx,&err); - err2fault(ctx,soap); - glite_jp_clear_error(ctx); - return SOAP_FAULT; - } - - out->files = soap_malloc(soap,out->__sizefiles * sizeof *f); - memcpy(out->files,f,out->__sizefiles * sizeof *f); - - return SOAP_OK; -} - diff --git a/org.glite.jp.primary/src/tags.c b/org.glite.jp.primary/src/tags.c deleted file mode 100644 index 1f11b4d..0000000 --- a/org.glite.jp.primary/src/tags.c +++ /dev/null @@ -1,233 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include "tags.h" -#include "backend.h" - -/* magic name_len value_len binary sequence timestamp */ -#define HEADER "JP#TAG# %05u %012lu %c %05u %012lu#" -#define HEADER_SIZE 48 - -int glite_jpps_tag_append( - glite_jp_context_t ctx, - void *handle, - const glite_jp_tagval_t *tag -) -{ - char hdr[HEADER_SIZE+1]; - glite_jp_error_t err; - - unsigned long vlen = tag->binary ? tag->size : - (tag->value ? strlen(tag->value) : 0); - int nlen; - - memset(&err,0,sizeof err); - err.source = "glite_jpps_tag_append()"; - - if (!tag->name) { - err.code = EINVAL; - err.desc = "tag name"; - return glite_jp_stack_error(ctx,&err); - } - - nlen = strlen(tag->name); - - assert(sprintf(hdr,HEADER,nlen,vlen, - tag->binary ? "B" : "S", - tag->sequence, tag->timestamp) == HEADER_SIZE); - - if (glite_jppsbe_append(ctx,handle,hdr,HEADER_SIZE)) { - err.code = EIO; - err.desc = "write tag header"; - return glite_jp_stack_error(ctx,&err); - } - - if (glite_jppsbe_append(ctx,handle,tag->name,nlen)) { - err.code = EIO; - err.desc = "write tag name"; - return glite_jp_stack_error(ctx,&err); - } - - if (glite_jppsbe_append(ctx,handle,tag->value,vlen)) { - err.code = EIO; - err.desc = "write tag value"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} - -int glite_jpps_tagval_copy( - glite_jp_context_t ctx, - glite_jp_tagval_t *from, - glite_jp_tagval_t *to -) -{ - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - to->name = strdup(from->name); - if (!to->name) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - to->sequence = from->sequence; - to->timestamp = from->timestamp; - to->binary = from->binary; - to->size = from->size; - to->value = (char *) malloc(to->size); - if (!to->value) { - free(to->name); - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - memcpy(from->value, to->value, to->size); - - return 0; -} - -int glite_jpps_tag_read( - glite_jp_context_t ctx, - void *handle, - off_t offset, - glite_jp_tagval_t *tagvalue, - size_t *shift -) -{ - char hdr[HEADER_SIZE+1]; - unsigned int nlen; - unsigned long vlen; - char binary; - unsigned sequence; - unsigned timestamp; - char * name = NULL; - char * value = NULL; - ssize_t ret; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - hdr[HEADER_SIZE] = '\0'; - if (glite_jppsbe_pread(ctx, handle, hdr, HEADER_SIZE, offset, &ret)) { - err.code = EIO; - err.desc = "Cannot read tag header"; - goto error_out; - } - if (ret == 0) { - err.code = ENOENT; - err.desc = "No more tags in the file"; - goto error_out; - } - /* #define HEADER "JP#TAG# %05u %012lu %c %05u %012lu#" */ - if (sscanf(hdr, HEADER, &nlen, &vlen, &binary, &sequence, ×tamp) < 5) { - err.code = EILSEQ; - err.desc = "Incorrect tag header format"; - goto error_out; - } - name = (char*) malloc(nlen + 1); - if (!name) { - err.code = ENOMEM; - goto error_out; - } - name[nlen] = '\0'; - value = (char*) malloc(vlen + 1); - if (!value) { - err.code = ENOMEM; - goto error_out; - } - value[vlen] = '\0'; - if (glite_jppsbe_pread(ctx, handle, name, nlen, offset + HEADER_SIZE, &ret)) { - err.code = EIO; - err.desc = "Cannot read tag name"; - goto error_out; - } - if (glite_jppsbe_pread(ctx, handle, value, vlen, offset + HEADER_SIZE + nlen, &ret)) { - err.code = EIO; - err.desc = "Cannot read tag value"; - goto error_out; - } - - tagvalue->name = name; - tagvalue->sequence = sequence; - tagvalue->timestamp = timestamp; - tagvalue->binary = (binary == 'B') ? 1 : 0; - tagvalue->size = vlen; - tagvalue->value = value; - - *shift = HEADER_SIZE + nlen + vlen; - - return 0; -error_out: - free(name); - free(value); - return glite_jp_stack_error(ctx,&err); -} - -/* -int glite_jpps_tag_read(glite_jp_context_t, void *, off_t, glite_jp_tagval_t *, size_t); -int glite_jpps_tag_readall(glite_jp_context_t, void *, glite_jp_tagval_t **); -*/ - -int glite_jpps_tag_readall( - glite_jp_context_t ctx, - void *handle, - glite_jp_tagval_t **tags_out -) -{ - glite_jp_tagval_t * tags = NULL; - void * newspace; - int ntags = 0; - int ntagspace = 0; - off_t offset = 0; - int ret; - size_t shift; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - ntagspace = 1; - tags = (glite_jp_tagval_t *) calloc(ntagspace + 1, sizeof(*tags)); - if (!tags) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - while (!(ret = glite_jpps_tag_read(ctx, handle, offset, &tags[ntags], &shift))) { - offset += shift; - ntags++; - if (ntagspace <= ntags) { - ntagspace += 1; - newspace = realloc(tags, (ntagspace + 1) * sizeof(*tags)); - if (!newspace) { - err.code = ENOMEM; - goto error_out; - } - tags = (glite_jp_tagval_t *) newspace; - } - } - if (ret == ENOENT) { - *tags_out = tags; - return 0; - } else { - err.code = EIO; - err.desc = "Error reading tag value"; - } - -error_out: - for (; ntags-- ;) { - free(tags[ntags].name); - free(tags[ntags].value); - } - free(tags); - return glite_jp_stack_error(ctx,&err); -} diff --git a/org.glite.jp.primary/src/tags.h b/org.glite.jp.primary/src/tags.h deleted file mode 100644 index 0d8afa8..0000000 --- a/org.glite.jp.primary/src/tags.h +++ /dev/null @@ -1 +0,0 @@ -int glite_jpps_tag_append(glite_jp_context_t,void *,const glite_jp_tagval_t *); diff --git a/org.glite.jp.primary/src/tags_plugin.c b/org.glite.jp.primary/src/tags_plugin.c deleted file mode 100644 index c107d14..0000000 --- a/org.glite.jp.primary/src/tags_plugin.c +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include -#include - -#include - -#include "file_plugin.h" -#include "builtin_plugins.h" - -static int tagappend(void *,void *,int,...); -static int tagopen(void *,void *,void **); -static int tagclose(void *,void *); - -static int tagdummy() -{ - puts("tagdummy()"); - return -1; -} - -int init(glite_jp_context_t ctx, glite_jpps_fplug_data_t *data) -{ - data->fpctx = ctx; - - data->uris = calloc(2,sizeof *data->uris); - data->uris[0] = strdup(GLITE_JP_FILETYPE_TAGS); - - data->classes = calloc(2,sizeof *data->classes); - data->classes[0] = strdup("tags"); - - data->ops.open = tagopen; - data->ops.close = tagclose; - data->ops.attr = tagdummy; - data->ops.generic = tagappend; - - printf("tags init OK\n"); - return 0; -} - -static int tagopen(void *fpctx,void *bhandle,void **handle) -{ - /* we don't need anything special yet, so just pass the backend handle */ - *handle = bhandle; - return 0; -} - -static int tagclose(void *fpctx,void *handle) -{ - return 0; -} - -static int tagappend(void *fpctx,void *handle,int oper,...) -{ - glite_jp_tagval_t *tag; - va_list ap; - va_start(ap,oper); - tag = va_arg(ap,glite_jp_tagval_t *); - va_end(ap); - - /* TODO */ - printf("tagappend: %s,%d,%s\n",tag->name,tag->sequence,tag->value); - - return 0; -} diff --git a/org.glite.jp.primary/src/typemap.dat b/org.glite.jp.primary/src/typemap.dat deleted file mode 100644 index 72f515f..0000000 --- a/org.glite.jp.primary/src/typemap.dat +++ /dev/null @@ -1,3 +0,0 @@ -jpsrv = http://glite.org/wsdl/services/jp -jptype = http://glite.org/wsdl/types/jp -jpelem = http://glite.org/wsdl/elements/jp diff --git a/org.glite.jp.ws-interface/.cvsignore b/org.glite.jp.ws-interface/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.jp.ws-interface/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.jp.ws-interface/LICENSE b/org.glite.jp.ws-interface/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.jp.ws-interface/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -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 -. - -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/ - - diff --git a/org.glite.jp.ws-interface/Makefile b/org.glite.jp.ws-interface/Makefile deleted file mode 100644 index 595f7ea..0000000 --- a/org.glite.jp.ws-interface/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -# Default values -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -package=glite-jp-ws-interface -version=0.0.0 -PREFIX=/opt/glite - --include Makefile.inc - -VPATH=${top_srcdir}/interface:${top_srcdir}/src -STAGETO=interface - -XSLTPROC=xsltproc - -#WSDL=JobProvenancePS.wsdl JobProvenanceIS.wsdl JobProvenanceTypes.wsdl -WSDL=JobProvenancePS.wsdl JobProvenanceTypes.wsdl - -all compile: ${WSDL} - -check: - @echo No unit test required for interface-only module. - -stage: ${WSDL} - $(MAKE) install PREFIX=${stagedir} - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=${top_srcdir}/tmpbuilddir - cd ${top_srcdir}/tmpbuilddir && tar -czf ${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz * - rm -rf ${top_srcdir}/tmpbuilddir - -install: - -mkdir -p ${PREFIX}/${STAGETO} - -mkdir -p ${PREFIX}/share/doc/${package}-${version} - install -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} -# cd ${top_srcdir}/interface && install -m 644 ${WSDL} ${PREFIX}/${STAGETO} - install -m 644 ${WSDL} ${PREFIX}/${STAGETO} - -clean: - rm -f *.h - -%.wsdl: %.xml - ${XSLTPROC} ../src/puke-wsdl.xsl $< >$@ diff --git a/org.glite.jp.ws-interface/build.xml b/org.glite.jp.ws-interface/build.xml deleted file mode 100644 index 44d86eb..0000000 --- a/org.glite.jp.ws-interface/build.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.ws-interface/interface/JobProvenanceIS.wsdl b/org.glite.jp.ws-interface/interface/JobProvenanceIS.wsdl deleted file mode 100644 index 84c8844..0000000 --- a/org.glite.jp.ws-interface/interface/JobProvenanceIS.wsdl +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - Store or update information on jobs within the JP index server. -Called directly by the primary storage, used for both batch and incremental feed. - -Input: - -data: list of job record updates. Each contains jobid, list of JP attribute values and user tag values. - -feedDone: flag indicating end of batch feed. (In order to avoid potential problems with buffer allocation -the huge dataset of batch feed is split into reasonable chunks and delivered with more UpdateJobs calls.) - -Output: N/A - -Faults: GenericJPFault - - - - - - - - - Retrieve pointers to job records of jobs matching a query. -Input: conditions - list of lists of query conditions. - Elements of the inner lists refer to a single job attribute, the conditions are or-ed. - Elements of the outer list may refer to different job attributes, they are and-ed. - -Output: - -jobs: list of JobId, PSContact (URL of the primary storage which manges this job) pairs - -Faults: GenericJPFault - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Job Provenance Index service - - - - - - - diff --git a/org.glite.jp.ws-interface/project/build.number b/org.glite.jp.ws-interface/project/build.number deleted file mode 100644 index 63f5995..0000000 --- a/org.glite.jp.ws-interface/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build=33 diff --git a/org.glite.jp.ws-interface/project/build.properties b/org.glite.jp.ws-interface/project/build.properties deleted file mode 100755 index e69de29..0000000 diff --git a/org.glite.jp.ws-interface/project/configure.properties.xml b/org.glite.jp.ws-interface/project/configure.properties.xml deleted file mode 100644 index 4b08208..0000000 --- a/org.glite.jp.ws-interface/project/configure.properties.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -jpprefix=${subsystem.prefix} -package=${module.package.name} -PREFIX=${install.dir} -version=${module.version} -glite_location=${with.glite.location} - - - diff --git a/org.glite.jp.ws-interface/project/glite-jp-ws-interface.spec b/org.glite.jp.ws-interface/project/glite-jp-ws-interface.spec deleted file mode 100644 index dba6d55..0000000 --- a/org.glite.jp.ws-interface/project/glite-jp-ws-interface.spec +++ /dev/null @@ -1,42 +0,0 @@ -Summary:Change me !!! -Name:glite-jp-ws-interface -Version:0.0.0 -Release:0 -Copyright:Open Source EGEE License -Vendor:EU EGEE project -Group:System/Application -Prefix:/opt/glite -BuildArch:x86_64 -BuildRoot:%{_builddir}/%{name}-%{version} -Source:glite-jp-ws-interface-0.0.0_bin.tar.gz - -%define debug_package %{nil} - -%description -Change me !!! - -%prep - - -%setup -c - -%build - - -%install - - -%clean - -%pre -%post -%preun -%postun -%files -%defattr(-,root,root) -%{prefix}/interface/JobProvenancePS.wsdl -%{prefix}/interface/JobProvenanceTypes.wsdl -%{prefix}/share/doc/glite-jp-ws-interface-0.0.0/LICENSE - -%changelog - diff --git a/org.glite.jp.ws-interface/project/properties.xml b/org.glite.jp.ws-interface/project/properties.xml deleted file mode 100644 index 4ec8018..0000000 --- a/org.glite.jp.ws-interface/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.ws-interface/project/tar_exclude b/org.glite.jp.ws-interface/project/tar_exclude deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp.ws-interface/project/version.properties b/org.glite.jp.ws-interface/project/version.properties deleted file mode 100755 index 0ff5227..0000000 --- a/org.glite.jp.ws-interface/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.0.0 -module.age=0 diff --git a/org.glite.jp.ws-interface/src/JobProvenancePS.xml b/org.glite.jp.ws-interface/src/JobProvenancePS.xml deleted file mode 100644 index 0a5f921..0000000 --- a/org.glite.jp.ws-interface/src/JobProvenancePS.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.ws-interface/src/JobProvenanceTypes.xml b/org.glite.jp.ws-interface/src/JobProvenanceTypes.xml deleted file mode 100644 index ebbede4..0000000 --- a/org.glite.jp.ws-interface/src/JobProvenanceTypes.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.ws-interface/src/puke-wsdl.xsl b/org.glite.jp.ws-interface/src/puke-wsdl.xsl deleted file mode 100644 index 6635eb4..0000000 --- a/org.glite.jp.ws-interface/src/puke-wsdl.xsl +++ /dev/null @@ -1,272 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - : - - - - - - 0 - 1 - - - - - unbounded - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - : - - - - - unbounded - 1 - - - - - - - - - - - - - - - : - - - - - unbounded - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp/.cvsignore b/org.glite.jp/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp/build.xml b/org.glite.jp/build.xml deleted file mode 100644 index 31c63e5..0000000 --- a/org.glite.jp/build.xml +++ /dev/null @@ -1,264 +0,0 @@ - - - - - - - Ant build file to build the GLite Job Provenance Subsystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Preparing directories ... - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <project name="${subsystem.name}" type="post-subsystem" packageName="${global.prefix}-${subsystem.prefix}"/> - - - - diff --git a/org.glite.jp/project/build.number b/org.glite.jp/project/build.number deleted file mode 100644 index c680c72..0000000 --- a/org.glite.jp/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build=36 diff --git a/org.glite.jp/project/build.properties b/org.glite.jp/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp/project/dependencies.properties b/org.glite.jp/project/dependencies.properties deleted file mode 100644 index ab3b83f..0000000 --- a/org.glite.jp/project/dependencies.properties +++ /dev/null @@ -1,12 +0,0 @@ -################################################################### -# System dependencies -################################################################### - -org.glite.version = HEAD -org.glite.jp.version = HEAD - -# Component dependencies tag = do not remove this line = -org.glite.jp.ws-interface.version = HEAD -org.glite.jp.common.version = HEAD -org.glite.jp.index.version = HEAD -org.glite.jp.primary.version = HEAD diff --git a/org.glite.jp/project/glite.jp.csf.xml b/org.glite.jp/project/glite.jp.csf.xml deleted file mode 100644 index fd68f71..0000000 --- a/org.glite.jp/project/glite.jp.csf.xml +++ /dev/null @@ -1,271 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The org.glite and org.glite.jp modules have been updated, please rerun the configuration file - - - - - The org.glite and org.glite.jp modules have been updated, please rerun the configuration file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp/project/properties.xml b/org.glite.jp/project/properties.xml deleted file mode 100755 index 276cf76..0000000 --- a/org.glite.jp/project/properties.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp/project/run-workspace b/org.glite.jp/project/run-workspace deleted file mode 100644 index a5d1f54..0000000 --- a/org.glite.jp/project/run-workspace +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -cd ../.. - -cvs co org.glite -cvs co org.glite.jp - -cd org.glite.jp/project -ant -f glite.jp.csf.xml - diff --git a/org.glite.jp/project/taskdefs.xml b/org.glite.jp/project/taskdefs.xml deleted file mode 100755 index c4cc889..0000000 --- a/org.glite.jp/project/taskdefs.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/org.glite.jp/project/version.properties b/org.glite.jp/project/version.properties deleted file mode 100644 index cd1e9e7..0000000 --- a/org.glite.jp/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.0.0 -module.age=1 diff --git a/org.glite.lb.client/examples/gen_sample_job b/org.glite.lb.client/examples/gen_sample_job index cc9dfac..c24dc1c 100755 --- a/org.glite.lb.client/examples/gen_sample_job +++ b/org.glite.lb.client/examples/gen_sample_job @@ -93,6 +93,12 @@ awk -F, $NESTED \ /-e UserTag/ { if (checkNOP(4) == 0) logit(); next;} +/-e ReallyRunning/ { if (checkNOP(3) == 0) logit(); + next;} + +# shell escape (for sequence number branching) + +/^!/ { print substr($0,2,(length($0) - 1)); } # macro processing - macro name starts and ends with ':' # in a file gen_MACRONAME.txt is the macro describtion diff --git a/org.glite.lb.client/examples/job_status.c b/org.glite.lb.client/examples/job_status.c index 489d194..e894065 100644 --- a/org.glite.lb.client/examples/job_status.c +++ b/org.glite.lb.client/examples/job_status.c @@ -240,6 +240,18 @@ static void printstat(edg_wll_JobStat stat, int level) printf("%sexpectUpdate : %d\n", ind, stat.expectUpdate); printf("%sexpectFrom : %s\n", ind, stat.expectFrom); printf("%sacl : %s\n", ind, stat.acl); + printf("%spayload_running: %d\n", ind, stat.payload_running); + if (stat.possible_destinations) { + printf("%spossible_destinations : \n", ind); + for (i=0; stat.possible_destinations[i]; i++) + printf("%s\t%s \n", ind, stat.possible_destinations[i]); + } + if (stat.possible_ce_nodes) { + printf("%spossible_ce_nodes : \n", ind); + for (i=0; stat.possible_ce_nodes[i]; i++) + printf("%s\t%s \n", ind, stat.possible_ce_nodes[i]); + } + printf("\n"); free(j); diff --git a/org.glite.lb.client/examples/ready.l b/org.glite.lb.client/examples/ready.l index e4d9ac7..530a503 100644 --- a/org.glite.lb.client/examples/ready.l +++ b/org.glite.lb.client/examples/ready.l @@ -12,7 +12,7 @@ -s WorkloadManager,-e HelperCall, --helper_name="name of the called component",--helper_params="parameters of the call", --src_role=CALLING #-s Helper,-e HelperCall, --helper_name="name of the called component",--helper_params="parameters of the call", --src_role=CALLED #-s Helper,-e HelperReturn, --helper_name="name of the called component",--retval="returned data", --src_role=CALLED --s WorkloadManager,-e Match,--dest_id="Id of the destination CE/queue" +-s WorkloadManager,-e Match,--dest_id="${DESTINATION:-destination CE/queue}" -s WorkloadManager,-e HelperReturn, --helper_name="name of the called component",--retval="returned data", --src_role=CALLING -s WorkloadManager,-e EnQueued, --queue="destination queue", --job="job description in receiver language", --result=OK, --reason="detailed description of transfer" diff --git a/org.glite.lb.client/examples/resubmission.l b/org.glite.lb.client/examples/resubmission.l new file mode 100644 index 0000000..3b8765c --- /dev/null +++ b/org.glite.lb.client/examples/resubmission.l @@ -0,0 +1,18 @@ +# one resubmission cycle + +-s LogMonitor,-e EnQueued, --queue="wm_input.fl", --job="job description in receiver language", --result=OK, --reason="detailed description of transfer" + +-s WorkloadManager,-e DeQueued, --queue="wm_input.fl", --local_jobid="WM_ID" +-s WorkloadManager,-e HelperCall, --helper_name="name of the called component",--helper_params="parameters of the call", --src_role=CALLING +-s WorkloadManager,-e Match,--dest_id="${DESTINATION:-destination CE/queue}" +-s WorkloadManager,-e HelperReturn, --helper_name="name of the called component",--retval="returned data", --src_role=CALLING +-s WorkloadManager,-e EnQueued, --queue="wm_output.fl", --job="job description in receiver language", --result=OK, --reason="detailed description of transfer" + +-s JobController,-e DeQueued, --queue="wm_output.fl", --local_jobid="JC_ID" +-s JobController,-e Transfer,--destination="LRMS",--dest_host="destination hostname",--dest_instance="destination instance",--dest_jobid="job description in receiver language",--result=OK,--reason="detailed description of transfer",--dest_jobid="destination internal jobid" + +-s LogMonitor,-e Accepted, --from="JobController", --from_host="sending component hostname", --from_instance="sending component instance", --local_jobid="new jobId (Condor, Globus ...)" +-s LogMonitor,-e Transfer,--destination="LRMS",--dest_host="destination hostname",--dest_instance="destination instance",--dest_jobid="job description in receiver language",--result=OK,--reason="detailed description of transfer",--dest_jobid="destination internal jobid" + +-s LogMonitor,-e Running,--node="${CE_NODE:-worker node}" + diff --git a/org.glite.lb.client/examples/resubmitted.l b/org.glite.lb.client/examples/resubmitted.l new file mode 100644 index 0000000..0051f40 --- /dev/null +++ b/org.glite.lb.client/examples/resubmitted.l @@ -0,0 +1,20 @@ +# resubmitted job example + +! DESTINATION=CE1/queue1 +! CE_NODE=worker1 +:running: + +-s LogMonitor, -e Done, --status_code=FAILED, --reason="reason for the change", --exit_code=141 +-s LogMonitor, -e Resubmission, --result=WILLRESUB, --reason="let's try again", --tag=none + +! DESTINATION=CE2/queue2 +! CE_NODE=worker2 +:resubmission: + +-s LogMonitor, -e Done, --status_code=FAILED, --reason="reason for the change", --exit_code=141 +-s LogMonitor, -e Resubmission, --result=WILLRESUB, --reason="let's try again", --tag=none + +! DESTINATION=CE3/queue3 +! CE_NODE=worker3 +:resubmission: + diff --git a/org.glite.lb.client/examples/running.l b/org.glite.lb.client/examples/running.l index 12d411a..60dfe6a 100644 --- a/org.glite.lb.client/examples/running.l +++ b/org.glite.lb.client/examples/running.l @@ -1,4 +1,4 @@ # macro definition for RUNNING state :scheduled: --s LogMonitor,-e Running,--node"worker node where the executable is run" +-s LogMonitor,-e Running,--node="${CE_NODE:-worker node}" diff --git a/org.glite.lb.client/examples/shallow_and_full_resub.l b/org.glite.lb.client/examples/shallow_and_full_resub.l new file mode 100644 index 0000000..7911d92 --- /dev/null +++ b/org.glite.lb.client/examples/shallow_and_full_resub.l @@ -0,0 +1,35 @@ +# shallow resubmission job example + +! DESTINATION=CE1/queue1 +! CE_NODE=worker1 +:running: + +-s LogMonitor, -e Done, --status_code=FAILED, --reason="reason for the change", --exit_code=141 +-s LogMonitor, -e Resubmission, --result=SHALLOW, --reason="let's try again", --tag=none + +! DESTINATION=CE2/queue2 +! CE_NODE=worker2 +:resubmission: + +-s LogMonitor, -e Done, --status_code=FAILED, --reason="reason for the change", --exit_code=141 +-s LogMonitor, -e Resubmission, --result=SHALLOW, --reason="let's try again", --tag=none + +! DESTINATION=CE3/queue3 +! CE_NODE=worker3 +:resubmission: + +-s LogMonitor, -e ReallyRunning, --wn_seq="$EDG_WL_SEQUENCE" + +-s LogMonitor, -e Done, --status_code=FAILED, --reason="reason for the change", --exit_code=141 +-s LogMonitor, -e Resubmission, --result=WILLRESUB, --reason="let's try again", --tag=none + +! DESTINATION=CE2/queue2 +! CE_NODE=worker2 +:resubmission: + +# payload_running=false +# destination=CE2/queue2 +# ce_node=worker2 +# possible_destinations=CE2/queue2 +# possible_ce_nodes=worker2 + diff --git a/org.glite.lb.client/examples/shallow_resub_complex.l b/org.glite.lb.client/examples/shallow_resub_complex.l new file mode 100644 index 0000000..258274c --- /dev/null +++ b/org.glite.lb.client/examples/shallow_resub_complex.l @@ -0,0 +1,42 @@ +# shallow resubmission job example + +! DESTINATION=CE1/queue1 +! CE_NODE=worker1 +:running: + +-s LogMonitor, -e Done, --status_code=FAILED, --reason="reason for the change", --exit_code=141 +-s LogMonitor, -e Resubmission, --result=SHALLOW, --reason="let's try again", --tag=none + +! DESTINATION=CE2/queue2 +! CE_NODE=worker2 +:resubmission: +! BRANCH_SEQUENCE="$EDG_WL_SEQUENCE" + +-s LogMonitor, -e Done, --status_code=FAILED, --reason="reason for the change", --exit_code=141 +-s LogMonitor, -e Resubmission, --result=SHALLOW, --reason="let's try again", --tag=none + +! DESTINATION=CE3/queue3 +! CE_NODE=worker3 +:resubmission: + +-s LogMonitor, -e ReallyRunning, --wn_seq="$BRANCH_SEQUENCE" + +# payload_running=true +# destination=CE2/queue2 +# ce_node=worker2 +# possible_destinations=CE1/queue1 CE2/queue2 CE3/queue3 +# possible_ce_nodes=worker1 worker2 worker3 + +-s LogMonitor, -e Done, --status_code=FAILED, --reason="reason for the change", --exit_code=141 +-s LogMonitor, -e Resubmission, --result=WILLRESUB, --reason="let's try again", --tag=none + +! DESTINATION=CE4/queue4 +! CE_NODE=worker4 +:resubmission: + +# payload_running=false +# destination=CE4/queue4 +# ce_node=worker4 +# possible_destinations=CE4/queue4 +# possible_ce_nodes=worker4 + diff --git a/org.glite.lb.client/examples/shallow_resub_simple.l b/org.glite.lb.client/examples/shallow_resub_simple.l new file mode 100644 index 0000000..18800a3 --- /dev/null +++ b/org.glite.lb.client/examples/shallow_resub_simple.l @@ -0,0 +1,28 @@ +# shallow resubmission job example + +! DESTINATION=CE1/queue1 +! CE_NODE=worker1 +:running: + +-s LogMonitor, -e Done, --status_code=FAILED, --reason="reason for the change", --exit_code=141 +-s LogMonitor, -e Resubmission, --result=SHALLOW, --reason="let's try again", --tag=none + +! DESTINATION=CE2/queue2 +! CE_NODE=worker2 +:resubmission: + +-s LogMonitor, -e Done, --status_code=FAILED, --reason="reason for the change", --exit_code=141 +-s LogMonitor, -e Resubmission, --result=SHALLOW, --reason="let's try again", --tag=none + +! DESTINATION=CE3/queue3 +! CE_NODE=worker3 +:resubmission: + +-s LogMonitor, -e ReallyRunning, --wn_seq="$EDG_WL_SEQUENCE" + +# payload_running=true +# destination=CE3/queue3 +# ce_node=worker3 +# possible_destinations=CE1/queue1 CE2/queue2 CE3/queue3 +# possible_ce_nodes=worker1 worker2 worker3 + diff --git a/org.glite.lb.client/examples/shallow_resub_simple2.l b/org.glite.lb.client/examples/shallow_resub_simple2.l new file mode 100644 index 0000000..384f444 --- /dev/null +++ b/org.glite.lb.client/examples/shallow_resub_simple2.l @@ -0,0 +1,29 @@ +# shallow resubmission job example + +! DESTINATION=CE1/queue1 +! CE_NODE=worker1 +:running: + +-s LogMonitor, -e Done, --status_code=FAILED, --reason="reason for the change", --exit_code=141 +-s LogMonitor, -e Resubmission, --result=SHALLOW, --reason="let's try again", --tag=none + +! DESTINATION=CE2/queue2 +! CE_NODE=worker2 +:resubmission: +! BRANCH_SEQUENCE="$EDG_WL_SEQUENCE" + +-s LogMonitor, -e Done, --status_code=FAILED, --reason="reason for the change", --exit_code=141 +-s LogMonitor, -e Resubmission, --result=SHALLOW, --reason="let's try again", --tag=none + +! DESTINATION=CE3/queue3 +! CE_NODE=worker3 +:resubmission: + +-s LogMonitor, -e ReallyRunning, --wn_seq="$BRANCH_SEQUENCE" + +# payload_running=true +# destination=CE2/queue2 +# ce_node=worker2 +# possible_destinations=CE1/queue1 CE2/queue2 CE3/queue3 +# possible_ce_nodes=worker1 worker2 worker3 + diff --git a/org.glite.lb.common/src/xml_parse.c.T b/org.glite.lb.common/src/xml_parse.c.T index 4b2e2bd..449db0c 100644 --- a/org.glite.lb.common/src/xml_parse.c.T +++ b/org.glite.lb.common/src/xml_parse.c.T @@ -320,6 +320,8 @@ static void startJobStatus(void *data, const char *el, const char **attr) case 1 : if (!strcmp("user_tags", el) || !strcmp("user_values", el) || !strcmp("children_hist", el) || !strcmp("stateEnterTimes", el) + || !strcmp("possible_destinations", el) + || !strcmp("possible_ce_nodes", el) || !strcmp("children_states", el) || !strcmp("children", el)) { XMLCtx->stat_begin = XML_GetCurrentByteIndex(XMLCtx->p); } @@ -937,6 +939,22 @@ static void endJobStat(void *data, const char *el) "children_hist",(int (*)()) edg_wll_StringToStat, &XMLCtx->jobStatSingleGlobal.children_hist); XMLCtx->stat_begin = 0; } + else if (!strcmp(el,"possible_destinations")) { + long len = (XML_GetCurrentByteIndex(XMLCtx->p) + XML_GetCurrentByteCount(XMLCtx->p)) + - XMLCtx->stat_begin; + + edg_wll_ParseStrList(XMLCtx->ctx, XMLCtx->message_body + XMLCtx->stat_begin, len, + "possible_destinations", "name", &XMLCtx->jobStatSingleGlobal.possible_destinations); + XMLCtx->stat_begin = 0; + } + else if (!strcmp(el,"possible_ce_nodes")) { + long len = (XML_GetCurrentByteIndex(XMLCtx->p) + XML_GetCurrentByteCount(XMLCtx->p)) + - XMLCtx->stat_begin; + + edg_wll_ParseStrList(XMLCtx->ctx, XMLCtx->message_body + XMLCtx->stat_begin, len, + "possible_ce_nodes", "name", &XMLCtx->jobStatSingleGlobal.possible_ce_nodes); + XMLCtx->stat_begin = 0; + } else if (!strcmp(el,"children")) { long len = (XML_GetCurrentByteIndex(XMLCtx->p) + XML_GetCurrentByteCount(XMLCtx->p)) - XMLCtx->stat_begin; diff --git a/org.glite.lb.proxy/project/MultiStruct.pm b/org.glite.lb.proxy/project/MultiStruct.pm deleted file mode 100644 index 9cd847c..0000000 --- a/org.glite.lb.proxy/project/MultiStruct.pm +++ /dev/null @@ -1,191 +0,0 @@ -package MultiStruct; - -use StructField; - -sub new { - shift; - my $self = {}; - $self->{comments} = {}; # typ->comment - $self->{fields} = {}; # typ->{ name->StructField, ... } - $self->{order} = {}; - - bless $self; -} - -sub selectType { - my $self = shift; - my $type = shift; - $self->{type} = $type; - 1; -} - -sub addType { - my $self = shift; - my $type = shift; - my $comment = shift; - $self->selectType($type); - $self->{comments}->{$type} = $comment; - $self->{fields}->{$type} = {}; - 1; -} - -sub selectField { - my $self = shift; - $self->{field} = shift; - $self->getField; -} - -sub addField { - my $self = shift; - my $field = shift; - - die "unselected type" unless $self->{type}; - $self->{fields}->{$self->{type}}->{$field->{name}} = $field; - $self->selectField($field->{name}); - 1; -} - -sub getField { - my $self = shift; - my $f = $self->{fields}->{$self->{type}}->{$self->{field}}; - return $f ? $f : $self->{fields}->{_common_}->{$self->{field}}; -} - -sub load { - my $self = shift; - my $fh = shift; - local $_; - - while ($_ = <$fh>) { - - chomp; - s/#.*$//; - next if /^\s*$/; - - if (/^\@type\s+(\S+)\s*(.*$)$/) { - $self->addType($1,$2); - $self->{order}->{$1} = $.; - next; - } - - s/^\s*//; - my ($ftype,$fname,$comment) = split /\s+/,$_,3; - if ($ftype eq '_code_') { - my $f = $self->getField(); - addCode $f $fname,$comment; - } - elsif ($ftype eq '_alias_') { - my $f = $self->getField(); - addAlias $f $fname,$comment; - } - elsif ($ftype eq '_special_') { - my $f = $self->getField(); - addSpecial $f $fname; - } - elsif ($ftype eq '_null_') { - my $f = $self->getField(); - setNull $f $fname; - } - elsif ($ftype eq '_optional_') { - my $f = $self->getField(); - $f->{optional} = 1; - } - elsif ($ftype eq '_index_') { - my $f = $self->getField(); - $f->{index} = 1; - } - else { - my $f = new StructField $fname,$ftype,$comment,$.; - $self->addField($f); - } - } -} - -sub getTypes { - my $self = shift; - my @out; - local $_; - - for (keys %{$self->{fields}}) { - push @out,$_ unless $_ eq '_common_'; - } - @out; -} - -sub getTypesOrdered { - my $self = shift; - my @names = getTypes $self; - - sort { - my $oa = $self->{order}->{$a}; - my $ob = $self->{order}->{$b}; - $oa <=> $ob; - } @names; -} - -sub getTypeComment { - my $self = shift; - my $type = shift || $self->{type}; - $self->{comments}->{$type}; -} - -sub getFieldComment { - my $self = shift; - my $fname = shift; - $self->{fields}->{$self->{type}}->{$fname}->{comment}; -} - -sub getFields { - my $self = shift; - keys %{$self->{fields}->{$self->{type}}}; -} - -sub getFieldsOrdered { - my $self = shift; - my @names = $self->getFields; - sort { - my $oa = $self->selectField($a)->{order}; - my $ob = $self->selectField($b)->{order}; - $oa <=> $ob; - } @names; -} - -sub getFieldOccurence { - my $self = shift; - my $fname = shift; - my @out; - local $_; - - for (keys %{$self->{fields}}) { - push @out,$_ if $self->{fields}->{$_}->{$fname}; - } - @out; -} - -sub getAllFields { - my $self = shift; - my %out; - local $_; - - for my $t (values %{$self->{fields}}) { - $out{$_->{name}} = 1 for (values %$t); - } - keys %out; -} - -sub getAllFieldsOrdered { - my $self = shift; - my @names = getAllFields $self; - - sort { - my @occ = $self->getFieldOccurence($a); - $self->selectType($occ[0]); - my $oa = $self->selectField($a)->{order}; - @occ = $self->getFieldOccurence($b); - $self->selectType($occ[0]); - my $ob = $self->selectField($b)->{order}; - $oa <=> $ob; - } @names; -} - -1; diff --git a/org.glite.lb.proxy/project/StructField.pm b/org.glite.lb.proxy/project/StructField.pm deleted file mode 100644 index 95d33b8..0000000 --- a/org.glite.lb.proxy/project/StructField.pm +++ /dev/null @@ -1,116 +0,0 @@ -package StructField; - -$lang = 'C'; -1; - -sub new { - shift; - my $self = {}; - $self->{name} = shift; - $self->{type} = shift; - $self->{comment} = shift; - $self->{order} = shift; - $self->{null} = $main::DefaultNullValue{$self->{type}}; - bless $self; -} - -sub addCode { - my $self = shift; - my $code = shift; - my $comment = shift; - push @{$self->{codes}},{name=>$code,comment=>$comment}; - 1; -} - -sub addSpecial { - my $self = shift; - my $special = shift; - $self->{special} = $special; - 1; -} - -sub addAlias { - my $self = shift; - my $name = shift; - my $lang = shift; - $self->{aliases}->{$lang} = $name; - 1; -} - -sub hasAlias { - my $self = shift; - my $lang = shift; - return $self->{aliases}->{$lang} ? 1 : 0; -} - -sub getName { - my $self = shift; - my $lang = shift || $lang; - $self->{aliases}->{$lang} || $self->{name}; -# return $self->{aliases}->{$lang} ? $self->{aliases}->{$lang} : $self->{name}; -} - -sub getComment { - my $self = shift; - $self->{comment}; -} - -sub getDefaultNullValue { - my $self = shift; - $self->{null}; -} - -sub toString { - my $self = shift; - my $src = shift; - my $dst = shift; - - eval $main::toString{$lang}->{$self->{type}}; -} - -sub fromString { - my $self = shift; - my $src = shift; - my $dst = shift; - - eval $main::fromString{$lang}->{$self->{type}}; -} - -sub isNULL { - my $self = shift; - my $a = shift; - my $b = $self->{null}; - - eval $main::compare{$lang}->{$self->{type}}; -} - -sub isnotNULL { - my $self = shift; - my $src = shift; - - '!('.$self->isNULL($src).')'; -} - -sub compare { - my $self = shift; - my $a = shift; - my $b = shift; - eval $main::compare{$lang}->{$self->{type}}; -} - -sub toFormatString { - my $self = shift; - - eval $main::toFormatString{$lang}->{$self->{type}}; -} - -sub setNull { - my $self = shift; - $self->{null} = shift; -} - -sub getType { - my $self = shift; - - eval $main::types{$lang}->{$self->{type}}; -} diff --git a/org.glite.lb.proxy/project/at3 b/org.glite.lb.proxy/project/at3 deleted file mode 100644 index 8ff52ec..0000000 --- a/org.glite.lb.proxy/project/at3 +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/perl -w - -use File::Basename; -my $dir; -BEGIN{ - $dir = dirname $0; -} - -my $lines = $ENV{AT3_LINES}; - -use lib $dir; -use MultiStruct; -require 'types.T'; - -my $eventsn; -for (@INC) { - if (-f "$_/events.T") { - $eventsn="$_/events.T"; - last; - } -} - -my $statusn; -for (@INC) { - if (-f "$_/status.T") { - $statusn = "$_/status.T"; - last; - } -} - -my $indent = ''; - -my $event = new MultiStruct; -my $status = new MultiStruct; - -sub gen { - local $_ = shift; - - s/^\n!//; - s/\n!/\n/g; - print $_; -} - - -open EVENTS,$eventsn or die "$eventsn: $!\n"; -$event->load(\*EVENTS); -close EVENTS; - -open STATUS,$statusn or die "$statusn: $!\n"; -$status->load(\*STATUS); -close STATUS; - -my $code; -my $startcode; -while (<>) { - chomp; - if (/^\@\@\@LANG: (\S+)$/) { - $StructField::lang = $1; - next; - } - - if ($code) { - if (/^\@\@\@}$/) { - $code .= "1;\n"; - print "#line $startcode \"$ARGV\"\n/* begin */\n" if $lines; - eval $code or warn "eval: $@ at $ARGV:$.\n"; - my $nxtline = $.+1; - print "/* end */\n#line $nxtline \"$ARGV\"\n" if $lines; - undef $code; - } - else { $code .= $_."\n"; } - } - else { - if (/^\@\@\@{$/) { - $startcode = $.; - $code = "\n"; - } - elsif (/^\@\@\@AUTO$/) { - print qq{ - !! Automatically generated file - !! Do not edit, your changes will be discarded upon build - !! Change the corresponding template file $ARGV - -}; - print "#line $. \"$ARGV\"\n" if $lines; - } - else { - print "$_\n"; - } - } -} - -# print $event_common{prog}->copy('bla','hu'); diff --git a/org.glite.lb.proxy/project/events.T b/org.glite.lb.proxy/project/events.T deleted file mode 100644 index b8e5399..0000000 --- a/org.glite.lb.proxy/project/events.T +++ /dev/null @@ -1,183 +0,0 @@ -@type _common_ - timeval timestamp timestamp of event generation - _alias_ date ULM - timeval arrived timestamp of event store - _alias_ arr_date ULM - _optional_ - string host hostname of the machine where the event was generated - _alias_ host ULM - int level logging level (system, debug, ...) - _alias_ lvl ULM - _code_ EMERGENCY emergency - _code_ ALERT alert - _code_ ERROR error - _code_ WARNING warning - _code_ AUTH authentication - _code_ SECURITY security - _code_ USAGE usage - _code_ SYSTEM system - _code_ IMPORTANT important - _code_ DEBUG debug - int priority message priority (yet 0 for asynchronous and 1 for synchronous transfers) - _null_ -1 - jobid jobId DataGrid job id of the source job - string seqcode sequence code assigned to the event - string user identity (cert. subj.) of the generator - logsrc source source (WMS component) which generated this event -# string prog name of program ("EDG WMS" of name of the application) - string src_instance instance of WMS component (e.g. service communication endpoint) - _optional_ - -@type Transfer Start, success, or failure of job transfer to another component - logsrc destination destination where the job is being transfered to - string dest_host destination hostname - string dest_instance destination instance - _optional_ - string job job description in receiver language - int result result of the attempt - _code_ START the sending component has started or is about to start the transfer - _code_ OK job was sent successfully - _code_ REFUSED job was refused by the other component - _code_ FAIL transfer failed for other reason than explicit refusal (eg. network timeout) - string reason detailed description of transfer, especially reason of failure - _optional_ - string dest_jobid destination internal jobid - _optional_ - -@type Accepted Accepting job (successful couterpart to Transfer) - logsrc from where was the job received from - string from_host sending component hostname - string from_instance sending component instance - _optional_ - string local_jobid new jobId (Condor, Globus ...) assigned by the receiving component - -@type Refused Refusing job (unsuccessful couterpart to Transfer) - logsrc from where was the job received from - string from_host sending component hostname - string from_instance sending component instance - _optional_ - string reason reason of refusal - -@type EnQueued The job has been enqueued in an inter-component queue - string queue destination queue - string job job description in receiver language - int result result of the attempt - _code_ START the sending component has started or is about to start the transfer - _code_ OK job was sent successfully - _code_ REFUSED job was refused by the other component - _code_ FAIL transfer failed for other reason than explicit refusal (eg. network timeout) - string reason detailed description of transfer, especially reason of failure - -@type DeQueued The job has been dequeued from an inter-component queue - string queue queue name - string local_jobid new jobId assigned by the receiving component - -@type HelperCall Helper component is called - string helper_name name of the called component - string helper_params parameters of the call - int src_role whether the logging component is called or calling one - _code_ CALLING the logging component is caller - _code_ CALLED the logging component is callee - -@type HelperReturn Helper component is returning the control - string helper_name name of the called component - string retval returned data - int src_role whether the logging component is called or calling one - _code_ CALLING the logging component is caller - _code_ CALLED the logging component is callee - -@type Running Executable started - string node worker node where the executable is run - -@type Resubmission Result of resubmission decision - int result result code - _code_ WILLRESUB will be resubmitted - _code_ WONTRESUB will not be resubmitted - string reason reason for the decision - string tag value of the attribute on which the decision is based - -@type Done Execution terminated (normally or abnormally) - int status_code way of termination - _code_ OK terminated by itself - _code_ FAILED disappeared from LRMS - _code_ CANCELLED cancelled by user request - string reason reason for the change - int exit_code process exit code - _null_ -1 - -@type Cancel Cancel operation has been attempted on the job - int status_code classification of the cancel - _code_ REQ request acknowledged - _code_ REFUSE request declined by this component - _code_ DONE request completed by whole WMS - _code_ ABORT request refused by whole WMS - string reason detailed description - -@type Abort Job aborted by system - string reason reason of abort - -@type Clear Job cleared, output sandbox removed - int reason why the job was cleared - _code_ USER user retrieved output sandbox - _code_ TIMEOUT timed out, resource purge forced - _code_ NOOUTPUT no output was generated - -@type Purge Job is purged from bookkepping server - -@type Match Matching CE found - string dest_id Id of the destination CE/queue - -@type Pending No match found yet - string reason why matching CE cannot be found - -@type RegJob New job registration - string jdl job description - string ns NetworkServer handling the job - jobid parent jobid of parent job - _optional_ - - int jobtype job type - _code_ SIMPLE simple job - _code_ DAG dag (containing static set of subjobs) - _code_ PARTITIONABLE partitionable (may become partitioned) - _code_ PARTITIONED partitioned (dynamically created dag) - - int nsubjobs number of subjobs - _optional_ - string seed seed for subjob id generation - _optional_ - -@type Chkpt Application-specific checkpoint record - string tag checkpoint tag - string classad checkpoint value - -@type Listener Listening network port for interactive control - string svc_name port instance name - string svc_host hostname - port svc_port port number - -@type CurDescr current state of job processing (optional event) - string descr description of current job transformation (output of helper) - -@type UserTag user tag -- arbitrary name=value pair - string name tag name - string value tag value - -@type ChangeACL Management of ACL stored on bookkepping server - string user_id DN or VOMS parameter (in format VO:group) - int user_id_type type of information given in user_id (DN or VOMS) - _null_ -1 - int permission ACL permission to change (currently only READ) - _null_ -1 - int permission_type type of permission requested ('allow', 'deny') - _null_ -1 - int operation operation requested to perform with ACL (add, remove) - _null_ -1 - -@type Notification Management of notification service - notifid notifId notification id - string owner owner - string dest_host destination host - port dest_port destination port - string jobstat job status - diff --git a/org.glite.lb.proxy/project/status.T b/org.glite.lb.proxy/project/status.T deleted file mode 100644 index 10071ac..0000000 --- a/org.glite.lb.proxy/project/status.T +++ /dev/null @@ -1,77 +0,0 @@ -@type _common_ -jobid jobId Id of the job -string owner Job owner -_index_ - -int jobtype Type of job - _null_ -1 - _code_ SIMPLE simple job - _code_ DAG composite job -jobid parent_job parent job of subjob - -string seed string used for generation of subjob IDs -int children_num number of subjobs -strlist children list of subjob IDs - _special_ XMLstructured -intlist children_hist summary (histogram) of children job states - _special_ XMLstructured -stslist children_states full status information of the children - _special_ XMLstructured - -string condorId Id within Condor-G -string globusId Globus allocated Id -string localId Id within LRMS - -string jdl User submitted job description -string matched_jdl Full job description after matchmaking -string destination ID of CE where the job is being sent -_index_ -string condor_jdl ClassAd passed to Condor-G for last job execution -string rsl Job RSL sent to Globus - -string reason Reason of being in this status, if any - -string location Where the job is being processed -_index_ -string ce_node Worker node where the job is executed -string network_server Network server handling the job - -bool subjob_failed Subjob failed (the parent job will fail too) -int done_code Return code - _null_ -1 - _code_ OK Finished correctly - _code_ FAILED Execution failed - _code_ CANCELLED Cancelled by user -int exit_code Unix exit code -bool resubmitted The job was resubmitted - -bool cancelling Cancellation request in progress -string cancelReason Reason of cancel - -int cpuTime Consumed CPU time - _null_ -1 - -taglist user_tags List of pairs (user_tag, user_value) - _special_ XMLstructured - -timeval stateEnterTime When entered this status -timeval lastUpdateTime Last known event of the job - -intlist stateEnterTimes When all previous states were entered - _special_ XMLstructured - -bool expectUpdate Some logged information has not arrived yet -string expectFrom Sources of the missing information -string acl ACL of the job - -@type Submitted entered by the user to the User Interface or registered by Job Partitioner -@type Waiting Accepted by WMS, waiting for resource allocation -@type Ready Matching resources found -@type Scheduled Accepted by LRMS queue -@type Running Executable is running -@type Done Execution finished, output is available -@type Cleared Output transfered back to user and freed -@type Aborted Aborted by system (at any stage) -@type Cancelled Cancelled by user -@type Unknown Status cannot be determined -@type Purged Job has been purged from bookkeeping server (for LB->RGMA interface) diff --git a/org.glite.lb.proxy/project/types.T b/org.glite.lb.proxy/project/types.T deleted file mode 100644 index ccabc74..0000000 --- a/org.glite.lb.proxy/project/types.T +++ /dev/null @@ -1,108 +0,0 @@ -%types = ( - C=>{ - bool=>'"int"', - string=>'"char *"', - strlist=>'"char **"', - intlist=>'"int *"', - taglist=>'"edg_wll_TagValue *"', - stslist=>'"struct _edg_wll_JobStat *"', - timeval=>'"struct timeval"', - jobid=>'"edg_wlc_JobId"', - notifid=>'"edg_wll_NotifId"', - logsrc=>'"edg_wll_Source"', - port=>'"uint16_t"', -# level=>'"enum edg_wll_Level"', - int=>'"int"' - }, - 'C++'=>{ - string=>'"std::string"', - timeval=>'"struct timeval"', - jobid=>'"edg::workload::common::jobid::JobId"', - bool=>'"int"', - intlist=>'"std::vector"', - strlist=>'"std::vector"', - taglist=>'"std::vector>"', - stslist=>'"std::vector"', - logsrc=>'"int"', - port=>'"int"', - int=>'"int"' - } -); - -%toString = ( - C=>{ - int=>'qq{asprintf(&$dst,"%d",$src);}', - port=>'qq{asprintf(&$dst,"%d",(int) $src);}', - bool=>'qq{asprintf(&$dst,"%d",$src);}', - string=>'qq{$dst = $src?strdup($src):NULL;}', - timeval=>'qq{edg_wll_ULMTimevalToDate(($src).tv_sec,($src).tv_usec,$dst);}', - jobid=>'qq{$dst = edg_wlc_JobIdUnparse($src);}', - notifid=>'qq{$dst = edg_wll_NotifIdUnparse($src);}', -# level=>'qq{$dst = edg_wll_LevelToString($src);}', - logsrc=>'qq{$dst = edg_wll_SourceToString($src);}', -# strlist, intlist, stslist are used only in consumer API, they don't need toString method - } -); - -%ULMasString = ( - logsrc=>1 -); - -%fromString = ( - C=>{ - int=>'qq{$dst = atoi($src);}', - port=>'qq{$dst = (uint16_t) atoi($src);}', - bool=>'qq{$dst = atoi($src);}', - string=>'qq{$dst = strdup($src);}', - timeval=>'qq{edg_wll_ULMDateToTimeval($src,&$dst);}', - jobid=>'qq{edg_wlc_JobIdParse($src,&$dst);}', - notifid=>'qq{edg_wll_NotifIdParse($src,&$dst);}', -# level=>'qq{$dst = edg_wll_StringToLevel($src);}', - logsrc=>'qq{$dst = edg_wll_StringToSource($src);}', -# strlist, intlist, stslist are used only in consumer API, they don't need fromString method - } -); - -%DefaultNullValue = ( - int=>0, - port=>0, -# level=>'EDG_WLL_LEVEL_UNDEFINED', - bool=>0, - string=>'NULL', - jobid=>'NULL', - notifid=>'NULL', - logsrc=>'EDG_WLL_SOURCE_NONE', - timeval=>'null_timeval', - strlist=>'NULL', - intlist=>'NULL', - taglist=>'NULL', - stslist=>'NULL', -); - -%compare = ( - C=>{ - int=>'"($a == $b)"', - port=>'"($a == $b)"', -# level=>'"($a == $b)"', - bool=>'"(($a || !$b) && ($b || !$a))"', - string=>'"(($a) == NULL && ($b) == NULL) || (($a)&&($b)&& !strcmp($a,$b))"', - jobid=>'"(($a) == NULL && ($b) == NULL) || (($a)&&($b)&& !strcmp(edg_wlc_JobIdUnparse($a),edg_wlc_JobIdUnparse($b)))"', - notifid=>'"($a) == ($b)"', - logsrc=>'"($a) == ($b)"', - timeval=>'"($a).tv_sec == ($b).tv_sec && ($a).tv_usec == ($b).tv_usec"', - } -); - -%toFormatString = ( - C=>{ - int=>'"%d"', - port=>'"%d"', - bool=>'"%d"', -# level=>'"%s"', - string=>'"%|Us"', - jobid=>'"%s"', - notifid=>'"%s"', - logsrc=>'"%s"', - timeval=>'"%s"', - } -); diff --git a/org.glite.lb.server/Makefile b/org.glite.lb.server/Makefile index faed144..4280ba2 100644 --- a/org.glite.lb.server/Makefile +++ b/org.glite.lb.server/Makefile @@ -20,11 +20,11 @@ gsoap_prefix=/opt/gsoap -include Makefile.inc -GLITE_LB_SERVER_WITH_WS=yes +GLITE_LB_SERVER_WITH_WS=no ifeq ($(GLITE_LB_SERVER_WITH_WS),yes) - gsoap_version=`${gsoap_prefix}/bin/soapcpp2 -version 2>&1 | cut -d' ' -f4 | perl -F\\\\. -nae '$$F[2] =~ s/\D*$$//; print $$F[2]+100*$$F[1]+10000*$$F[0]'` - WS_CFLAGS=-DGLITE_LB_SERVER_WITH_WS -DGSOAP_VERSION=${gsoap_version} + WS_CFLAGS=-DGLITE_LB_SERVER_WITH_WS + NSMAP=LoggingAndBookkeeping.nsmap else WS_CFLAGS= endif @@ -76,7 +76,7 @@ GLOBUS_LIBS:= -L${globus_prefix}/lib \ -lglobus_gssapi_gsi_${nothrflavour} \ ifneq (${mysql_prefix},/usr) - myslqlib := -L${mysql_prefix}/lib + myslqlib := -L${mysql_prefix}/lib/mysql endif ifneq (${expat_prefix},/usr) @@ -118,32 +118,34 @@ ifeq ($(GLITE_LB_SERVER_WITH_WS),yes) ws_query.o ws_fault.o ws_typeref.o BKSERVER_LIBS= \ - ${EXT_LIBS} \ ${SRVBONES_LIB} \ -lglite_lb_common_${nothrflavour} \ -L${gsoap_prefix}/lib -lgsoap \ - -lglite_security_gsoap_plugin_${nothrflavour} + -lglite_security_gsoap_plugin_${nothrflavour} \ + ${EXT_LIBS} else + BKSERVER_OBJS:= ${BKSERVER_BASE_OBJS} + BKSERVER_LIBS= \ - ${EXT_LIBS} \ ${SRVBONES_LIB} \ -lglite_lb_common_${nothrflavour} \ - -lglite_security_gss_${nothrflavour} + -lglite_security_gss_${nothrflavour} \ + ${EXT_LIBS} endif INDEX_OBJS:= index.o index_parse.o jobstat_supp.o lbs_db.o openserver.o \ jobstat.o query.o lock.o get_events.o write2rgma.o index_lex.o \ lb_authz.o store.o bkindex.o -INDEX_LIBS:= ${EXT_LIBS} ${SRVBONES_LIB} ${COMMON_LIBS} +INDEX_LIBS:= ${SRVBONES_LIB} ${COMMON_LIBS} ${EXT_LIBS} WS_CLIENT_OBJS:= $(GSOAP_FILES_PREFIX)C.o $(GSOAP_FILES_PREFIX)Client.o ws_fault.o ws_typeref.o WS_CLIENT_LIBS:= -L${stagedir}/lib \ - ${EXT_LIBS} \ -lglite_lb_client_${nothrflavour} \ -lglite_lb_common_${nothrflavour} \ -L${gsoap_prefix}/lib -lgsoap \ - -lglite_security_gsoap_plugin_${nothrflavour} + -lglite_security_gsoap_plugin_${nothrflavour} \ + ${EXT_LIBS} HDRS=index.h lb_authz.h lbs_db.h store.h @@ -156,7 +158,7 @@ LIB_OBJS_BK:= \ notification.o il_notification.o notif_match.o stats.o STATIC_LIB_BK:=libglite_lb_bkserver.a -glite_lb_bkserverd: LoggingAndBookkeeping.nsmap ${BKSERVER_OBJS} +glite_lb_bkserverd: ${NSMAP} ${BKSERVER_OBJS} ${LINK} -o $@ ${BKSERVER_OBJS} ${BKSERVER_LIBS} glite_lb_bkindex: ${INDEX_OBJS} @@ -167,7 +169,7 @@ glite_lb_plugin.la: lb_plugin.lo default all: compile -compile: glite_lb_bkserverd glite_lb_bkindex ${STATIC_LIB_BK} glite_lb_plugin.la +compile: glite_lb_bkserverd glite_lb_bkindex ${STATIC_LIB_BK} check: compile test.xml test.query -echo check.query not complete yet @@ -185,8 +187,18 @@ lb_xml_parse.c: lb_xml_parse.c.T ${GSOAP_FILES_PREFIX}H.h ${GSOAP_FILES_PREFIX}C.c ${GSOAP_FILES_PREFIX}Server.c ${GSOAP_FILES_PREFIX}Client.c ${GSOAP_FILES_PREFIX}ServerLib.c ${GSOAP_FILES_PREFIX}ClientLib.c LoggingAndBookkeeping.nsmap: LB.xh ${gsoap_prefix}/bin/soapcpp2 -w -c -p ${GSOAP_FILES_PREFIX} LB.xh -LB.xh: ws_typemap.dat +# try several times -- LB.wsdl downloads BaseFault.xsd from www.ibm.com which may be failing +# not used right now but may be useful one day +# LB.xh: ws_typemap.dat +# ${gsoap_prefix}/bin/wsdl2h -c -t ${top_srcdir}/src/ws_typemap.dat -o $@ ${stagedir}/interface/LB.wsdl || \ +# { sleep 1 ; ${gsoap_prefix}/bin/wsdl2h -c -t ${top_srcdir}/src/ws_typemap.dat -o $@ ${stagedir}/interface/LB.wsdl; } || \ +# { sleep 4 ; ${gsoap_prefix}/bin/wsdl2h -c -t ${top_srcdir}/src/ws_typemap.dat -o $@ ${stagedir}/interface/LB.wsdl; } || \ +# { sleep 16 ; ${gsoap_prefix}/bin/wsdl2h -c -t ${top_srcdir}/src/ws_typemap.dat -o $@ ${stagedir}/interface/LB.wsdl; } + +LB.xh: ws_typemap.dat ${stagedir}/interface/LB.wsdl + cp ${stagedir}/interface/LBTypes.wsdl . ${gsoap_prefix}/bin/wsdl2h -c -t ${top_srcdir}/src/ws_typemap.dat -o $@ ${stagedir}/interface/LB.wsdl + rm -f LBTypes.wsdl test.xml: test_xml ./test_xml @@ -302,3 +314,11 @@ test_query_events.o: %.o: %.cpp %.lo: %.c ${COMPILE} -o $@ -c $< +soap_version.h: + ${gsoap_prefix}/bin/soapcpp2 /dev/null + perl -ne '$$. == 2 && /.*([0-9])\.([0-9])\.([0-9]).*/ && printf "#define GSOAP_VERSION %d%02d%02d\n",$$1,$$2,$$3' soapH.h >$@ + -rm soapC.cpp soapH.h soapStub.h soapClient.cpp soapServer.cpp soapClientLib.cpp soapServerLib.cpp + +ifeq ($(GLITE_LB_SERVER_WITH_WS),yes) +bkserverd.o ws_fault.o: soap_version.h +endif diff --git a/org.glite.lb.server/interface/lbs_db.h b/org.glite.lb.server/interface/lbs_db.h index 3d7a344..8b236f3 100644 --- a/org.glite.lb.server/interface/lbs_db.h +++ b/org.glite.lb.server/interface/lbs_db.h @@ -65,8 +65,11 @@ void edg_wll_FreeStmt( ); -/* convert time_t into database-specific time string - * returns pointer to static area that is changed by subsequent calls */ +/** + * convert time_t into database-specific time string + * + * returns pointer to dynamic area which should be freed + */ char *edg_wll_TimeToDB(time_t); time_t edg_wll_DBToTime(char *); diff --git a/org.glite.lb.server/src/jobstat.c b/org.glite.lb.server/src/jobstat.c index 00a8aa4..48071d3 100644 --- a/org.glite.lb.server/src/jobstat.c +++ b/org.glite.lb.server/src/jobstat.c @@ -39,6 +39,9 @@ #define RET_BADSEQ 4 #define RET_SUSPECT 5 #define RET_IGNORE 6 +#define RET_BADBRANCH 7 +#define RET_GOODBRANCH 8 +#define RET_TOOOLD 9 #define RET_INTERNAL 100 #define rep(a,b) { free(a); a = (b == NULL) ? NULL : strdup(b); } @@ -48,7 +51,11 @@ static void warn (const char* format, ...) UNUSED_VAR ; static char *job_owner(edg_wll_Context,char *); static char* location_string(const char*, const char*, const char*); static int add_stringlist(char ***, const char *) UNUSED_VAR; +static void free_stringlist(char ***); static int add_taglist(edg_wll_TagValue **, const char *, const char *); +static void update_branch_state(char *, char *, char *, char *, branch_state **); +static void free_branch_state(branch_state **); +static void load_branch_state(intJobStat *); int edg_wll_intJobStatus(edg_wll_Context, const edg_wlc_JobId, int, intJobStat *, int); @@ -76,7 +83,7 @@ static void destroy_intJobStat_extension(intJobStat *p) { free(p->last_seqcode); p->last_seqcode = NULL; free(p->last_cancel_seqcode); p->last_cancel_seqcode = NULL; - p->wontresub = 0; + p->resubmit_type = EDG_WLL_RESUBMISSION_UNDEFINED; } void destroy_intJobStat(intJobStat *p) @@ -411,6 +418,7 @@ static int badEvent(intJobStat *js UNUSED_VAR, edg_wll_Event *e, int ev_seq UNUS #define USABLE(res,strict) ((res) == RET_OK || ( (res) == RET_SOON && !strict)) #define USABLE_DATA(res,strict) ((res) == RET_OK || ( (res) != RET_FATAL && !strict)) +#define USABLE_BRANCH(fine_res) ((fine_res) != RET_TOOOLD && (fine_res) != RET_BADBRANCH) #define LRMS_STATE(state) ((state) == EDG_WLL_JOB_RUNNING || (state) == EDG_WLL_JOB_DONE) @@ -419,7 +427,10 @@ static int processEvent(intJobStat *js, edg_wll_Event *e, int ev_seq, int strict edg_wll_JobStatCode old_state = js->pub.state; edg_wll_JobStatCode new_state = EDG_WLL_JOB_UNKNOWN; - int res = RET_OK; + int res = RET_OK, + fine_res = RET_OK; + + if (old_state == EDG_WLL_JOB_ABORTED || old_state == EDG_WLL_JOB_CANCELLED || @@ -427,11 +438,31 @@ static int processEvent(intJobStat *js, edg_wll_Event *e, int ev_seq, int strict res = RET_LATE; } - if (js->last_seqcode != NULL && - edg_wll_compare_seq(e->any.seqcode, js->last_seqcode) < 0) { + + if (js->deep_resubmit_seqcode && + before_deep_resubmission(e->any.seqcode, js->deep_resubmit_seqcode)) { + res = RET_LATE; + fine_res = RET_TOOOLD; + } + else if (js->branch_tag_seqcode) { // ReallyRunning ev. arrived + if (same_branch(e->any.seqcode, js->branch_tag_seqcode)) { + if ((js->last_seqcode != NULL) && + edg_wll_compare_seq(e->any.seqcode, js->last_branch_seqcode) < 0) { + res = RET_LATE; + } + fine_res = RET_GOODBRANCH; + } + else { + res = RET_LATE; + fine_res = RET_BADBRANCH; + } + } + else if ((js->last_seqcode != NULL) && + edg_wll_compare_seq(e->any.seqcode, js->last_seqcode) < 0) { res = RET_LATE; } + switch (e->any.type) { case EDG_WLL_EVENT_TRANSFER: if (e->transfer.result == EDG_WLL_TRANSFER_OK) { @@ -563,6 +594,8 @@ static int processEvent(intJobStat *js, edg_wll_Event *e, int ev_seq, int strict new_state = EDG_WLL_JOB_WAITING; break; case EDG_WLL_SOURCE_WORKLOAD_MANAGER: if (LRMS_STATE(old_state)) res = RET_LATE; + update_branch_state(e->any.seqcode, NULL, + NULL, e->enQueued.job, &js->branch_states); new_state = EDG_WLL_JOB_READY; break; case EDG_WLL_SOURCE_LOG_MONITOR: new_state = EDG_WLL_JOB_WAITING; break; @@ -608,7 +641,10 @@ static int processEvent(intJobStat *js, edg_wll_Event *e, int ev_seq, int strict case EDG_WLL_SOURCE_NETWORK_SERVER: rep(js->pub.jdl, e->enQueued.job); break; case EDG_WLL_SOURCE_WORKLOAD_MANAGER: - rep(js->pub.matched_jdl, e->enQueued.job); break; + if (USABLE_BRANCH(res)) { + rep(js->pub.matched_jdl, e->enQueued.job); + } + break; case EDG_WLL_SOURCE_LOG_MONITOR: /* no interim JDL here */ break; @@ -671,7 +707,38 @@ static int processEvent(intJobStat *js, edg_wll_Event *e, int ev_seq, int strict e->running.node); } if (USABLE_DATA(res, strict)) { - rep(js->pub.ce_node, e->running.node); + if (USABLE_BRANCH(fine_res)) { + rep(js->pub.ce_node, e->running.node); + } + if (e->any.source == EDG_WLL_SOURCE_LOG_MONITOR) { + if (e->running.node) { + update_branch_state(e->any.seqcode, NULL, + e->running.node, NULL, &js->branch_states); + add_stringlist(&js->pub.possible_ce_nodes, + e->running.node); + } + } + } + break; + case EDG_WLL_EVENT_REALLYRUNNING: + if (USABLE_DATA(res, strict)) { + js->pub.state = EDG_WLL_JOB_RUNNING; + free(js->pub.location); + js->pub.location = location_string( + edg_wll_SourceToString(EDG_WLL_SOURCE_LRMS), + "worknode", + e->running.node); + js->pub.payload_running = 1; + if (e->any.source == EDG_WLL_SOURCE_LRMS) { + rep(js->branch_tag_seqcode, e->any.seqcode); + rep(js->last_branch_seqcode, e->any.seqcode); + } + if (e->any.source == EDG_WLL_SOURCE_LOG_MONITOR) { + rep(js->branch_tag_seqcode, e->reallyRunning.wn_seq); + rep(js->last_branch_seqcode, e->reallyRunning.wn_seq); + } + + load_branch_state(js); } break; case EDG_WLL_EVENT_RESUBMISSION: @@ -682,7 +749,23 @@ static int processEvent(intJobStat *js, edg_wll_Event *e, int ev_seq, int strict } if (USABLE_DATA(res, strict)) { if (e->resubmission.result == EDG_WLL_RESUBMISSION_WONTRESUB) { - js->wontresub = 1; + js->resubmit_type = EDG_WLL_RESUBMISSION_WONTRESUB; + } + else + if (e->resubmission.result == EDG_WLL_RESUBMISSION_WILLRESUB && + e->any.source == EDG_WLL_SOURCE_WORKLOAD_MANAGER) { + js->resubmit_type = EDG_WLL_RESUBMISSION_WILLRESUB; + free_stringlist(&js->pub.possible_destinations); + free_stringlist(&js->pub.possible_ce_nodes); + free_branch_state(&js->branch_states); + js->pub.payload_running = 0; + rep(js->branch_tag_seqcode, NULL); + rep(js->deep_resubmit_seqcode, e->any.seqcode); + } + else + if (e->resubmission.result == EDG_WLL_RESUBMISSION_SHALLOW) { + js->resubmit_type = EDG_WLL_RESUBMISSION_SHALLOW; + rep(js->deep_resubmit_seqcode, NULL); } } break; @@ -695,6 +778,9 @@ static int processEvent(intJobStat *js, edg_wll_Event *e, int ev_seq, int strict if (USABLE(res, strict)) { js->pub.state = EDG_WLL_JOB_DONE; rep(js->pub.reason, e->done.reason); + if (fine_res == RET_GOODBRANCH) { + js->pub.payload_running = 0; + } switch (e->done.status_code) { case EDG_WLL_DONE_CANCELLED: js->pub.state = EDG_WLL_JOB_CANCELLED; @@ -725,10 +811,15 @@ static int processEvent(intJobStat *js, edg_wll_Event *e, int ev_seq, int strict } break; case EDG_WLL_EVENT_CANCEL: - if (js->last_cancel_seqcode != NULL && - edg_wll_compare_seq(e->any.seqcode, js->last_cancel_seqcode) < 0) { - res = RET_LATE; + if (fine_res != RET_BADBRANCH) { + if (js->last_cancel_seqcode != NULL && + edg_wll_compare_seq(e->any.seqcode, js->last_cancel_seqcode) < 0) { + res = RET_LATE; + } } + else { + res = RET_LATE; + } if (USABLE(res, strict)) { switch (e->cancel.status_code) { case EDG_WLL_CANCEL_REQ: @@ -756,6 +847,7 @@ static int processEvent(intJobStat *js, edg_wll_Event *e, int ev_seq, int strict js->pub.state = EDG_WLL_JOB_ABORTED; rep(js->pub.reason, e->abort.reason); rep(js->pub.location, "none"); + js->pub.payload_running = 0; } break; @@ -791,7 +883,15 @@ static int processEvent(intJobStat *js, edg_wll_Event *e, int ev_seq, int strict e->match.src_instance); } if (USABLE_DATA(res, strict)) { - rep(js->pub.destination, e->match.dest_id); + if (USABLE_BRANCH(fine_res)) { + rep(js->pub.destination, e->match.dest_id); + } + if (e->match.dest_id) { + update_branch_state(e->any.seqcode, e->match.dest_id, + NULL, NULL, &js->branch_states); + add_stringlist(&js->pub.possible_destinations, + e->match.dest_id); + } } break; case EDG_WLL_EVENT_PENDING: @@ -873,6 +973,10 @@ static int processEvent(intJobStat *js, edg_wll_Event *e, int ev_seq, int strict rep(js->last_seqcode, e->any.seqcode); } + if (fine_res == RET_GOODBRANCH) { + rep(js->last_branch_seqcode, e->any.seqcode); + } + return res; bad_event: @@ -1009,6 +1113,19 @@ static int add_stringlist(char ***lptr, const char *new_item) } } +static void free_stringlist(char ***lptr) +{ + char **itptr; + int i; + + if (*lptr) { + for (i = 0, itptr = *lptr; itptr[i] != NULL; i++) + free(itptr[i]); + free(itptr); + *lptr = NULL; + } +} + static int add_taglist(edg_wll_TagValue **lptr, const char *new_item, const char *new_item2) { edg_wll_TagValue *itptr; @@ -1042,6 +1159,107 @@ static int add_taglist(edg_wll_TagValue **lptr, const char *new_item, const char } } +static void update_branch_state(char *b, char *d, char *c, char *j, branch_state **bs) +{ + int i = 0, branch; + + + if (!b) + return; + else + branch = component_seqcode(b, EDG_WLL_SOURCE_WORKLOAD_MANAGER); + + if (*bs != NULL) { + while ((*bs)[i].branch) { + if (branch == (*bs)[i].branch) { + if (d) rep((*bs)[i].destination, d); + if (c) rep((*bs)[i].ce_node, c); + if (j) rep((*bs)[i].jdl, j); + + return; + } + i++; + } + } + + *bs = (branch_state *) realloc(*bs, (i+2)*sizeof(branch_state)); + memset(&((*bs)[i]), 0, 2*sizeof(branch_state)); + + (*bs)[i].branch = branch; + rep((*bs)[i].destination, d); + rep((*bs)[i].ce_node, c); + rep((*bs)[i].jdl, j); +} + + +static void free_branch_state(branch_state **bs) +{ + int i = 0; + + if (*bs == NULL) return; + + while ((*bs)[i].branch) { + free((*bs)[i].destination); + free((*bs)[i].ce_node); + free((*bs)[i].jdl); + i++; + } + free(*bs); + *bs = NULL; +} + +static int compare_branch_states(const void *a, const void *b) +{ + branch_state *c = (branch_state *) a; + branch_state *d = (branch_state *) b; + + if (c->branch < d->branch) return -1; + if (c->branch == d->branch) return 0; + if (c->branch > d->branch) return 1; +} + +static void load_branch_state(intJobStat *js) +{ + int i, j, branch; + + + if ( (!js->branch_tag_seqcode) || (!js->branch_states) ) return; + + branch = component_seqcode(js->branch_tag_seqcode, EDG_WLL_SOURCE_WORKLOAD_MANAGER); + + // count elements + i = 0; + while (js->branch_states[i].branch) i++; + + // sort them + qsort(js->branch_states, (size_t) i, sizeof(branch_state), + compare_branch_states); + + // find row corresponding to ReallyRunning WM seq.code (aka branch) + i = 0; + while (js->branch_states[i].branch) { + if (js->branch_states[i].branch == branch) break; + i++; + } + + // copy this and two before branches data to final state + // (each field - dest,ce,jdl - comes from different event) + // (and these events have most likely different WM seq.codes) + // (even belonging into one logical branch) + // (the newer the more important - so i-th element is copied as last) + // (and may overwrite data from previous elements) + for (j = i - 2; j <= i; j++) { + if (j >= 0) { + if (js->branch_states[j].destination) + rep(js->pub.destination, js->branch_states[j].destination); + if (js->branch_states[j].ce_node) + rep(js->pub.ce_node, js->branch_states[j].ce_node); + if (js->branch_states[j].jdl) + rep(js->pub.matched_jdl, js->branch_states[j].jdl); + } + } +} + /* XXX more thorough malloc, calloc, and asprintf failure handling */ /* XXX indexes in {short,long}_fields */ /* XXX strict mode */ diff --git a/org.glite.lb.server/src/jobstat.h b/org.glite.lb.server/src/jobstat.h index 1b17c7b..bb6fff5e 100644 --- a/org.glite.lb.server/src/jobstat.h +++ b/org.glite.lb.server/src/jobstat.h @@ -5,14 +5,28 @@ * (includes edg_wll_JobStat API structure) */ -#define INTSTAT_VERSION "release-2.0" +#define INTSTAT_VERSION "release-3.0_shallow" + +// shallow resubmission container - holds state of each branch +// (useful when state restore is needed after ReallyRunning event) +// +typedef struct _branch_state { + int branch; + char *destination; + char *ce_node; + char *jdl; +} branch_state; typedef struct _intJobStat { edg_wll_JobStat pub; - int wontresub; + int resubmit_type; char *last_seqcode; char *last_cancel_seqcode; + char *branch_tag_seqcode; + char *last_branch_seqcode; + char *deep_resubmit_seqcode; + branch_state *branch_states; // branch zero terminated array /* int expect_mask; */ } intJobStat; @@ -28,3 +42,6 @@ char *enc_intJobStat(char *, intJobStat* ); void write2rgma_status(edg_wll_JobStat *); +int before_deep_resubmission(const char *, const char *); +int same_branch(const char *, const char *); +int component_seqcode(const char *a, edg_wll_Source index); diff --git a/org.glite.lb.server/src/jobstat_supp.c b/org.glite.lb.server/src/jobstat_supp.c index 3f4f3ad..e3bbe79 100644 --- a/org.glite.lb.server/src/jobstat_supp.c +++ b/org.glite.lb.server/src/jobstat_supp.c @@ -175,6 +175,79 @@ static char **dec_strlist(char *in, char **rest) return out; } +static char *enc_branch_states(char *old, branch_state *item) +{ + char *ret; + + if (item == NULL) { + asprintf(&ret,"%s-1 ", old); + free(old); + return ret; + } else { + asprintf(&ret,"%s1 ",old); + free(old); + if (ret == NULL) return ret; + } + do { + ret = enc_int(ret, (*item).branch); + ret = enc_string(ret, (*item).destination); + ret = enc_string(ret, (*item).ce_node); + ret = enc_string(ret, (*item).jdl); + } while ((*(item++)).branch != 0); + return ret; +} + +static branch_state *dec_branch_states(char *in, char **rest) +{ + branch_state *out; + int len = -1, b = 0; + char *tmp_in, *tmp_ret; + int scret; + + scret = sscanf(in, "%d", &len); + if (scret < 1) { + *rest = NULL; + return NULL; + } + if (len == -1) { + *rest = strchr(in, ' ') ? strchr(in, ' ') + 1 : NULL; + return NULL; + } + + len = 0; + tmp_in = in = strchr(in, ' ') + 1 ; + do { + b = dec_int(tmp_in, &tmp_in); + tmp_ret = dec_string(tmp_in, &tmp_in); free(tmp_ret); + if (!tmp_in) { *rest = tmp_in; return NULL; } + tmp_ret = dec_string(tmp_in, &tmp_in); free(tmp_ret); + if (!tmp_in) { *rest = tmp_in; return NULL; } + tmp_ret = dec_string(tmp_in, &tmp_in); free(tmp_ret); + if (!tmp_in) { *rest = tmp_in; return NULL; } + len++; + } while (b != 0); + + out = (branch_state *) calloc(len+1, sizeof(branch_state)); + + if (out) { + len = 0; + tmp_in = in; + + do { + out[len].branch = dec_int(tmp_in, &tmp_in); + out[len].destination = dec_string(tmp_in, &tmp_in); + out[len].ce_node = dec_string(tmp_in, &tmp_in); + out[len].jdl = dec_string(tmp_in, &tmp_in); + } while (out[len++].branch != 0); + *rest = tmp_in; + } + else + *rest = 0; + + return out; + +} + static char* enc_taglist(char *old, edg_wll_TagValue *item) { char *ret; @@ -199,8 +272,8 @@ static edg_wll_TagValue *dec_taglist(char *in, char **rest) { edg_wll_TagValue *out; int len = -1; - char *tmp_in, *tmp_ret, *tmp_ret2; - int scret; + char *tmp_in, *tmp_ret; + int scret, end = 0; scret = sscanf(in, "%d", &len); if (scret < 1) { @@ -215,12 +288,15 @@ static edg_wll_TagValue *dec_taglist(char *in, char **rest) len = 0; tmp_in = in = strchr(in, ' ') + 1 ; do { - tmp_ret2 = dec_string(tmp_in, &tmp_in); - if (!tmp_in) { *rest = tmp_in; return NULL; } tmp_ret = dec_string(tmp_in, &tmp_in); + if (tmp_ret) free(tmp_ret); + else end = 1; + if (!tmp_in) { *rest = tmp_in; return NULL; } + tmp_ret = dec_string(tmp_in, &tmp_in); + free(tmp_ret); if (!tmp_in) { *rest = tmp_in; return NULL; } len++; - } while (tmp_ret2 != NULL); + } while (!end); out = (edg_wll_TagValue *) malloc(len*sizeof(edg_wll_TagValue)); @@ -354,6 +430,9 @@ static char *enc_JobStat(char *old, edg_wll_JobStat* stat) if (ret) ret = enc_timeval(ret, stat->lastUpdateTime); if (ret) ret = enc_int(ret, stat->expectUpdate); if (ret) ret = enc_string(ret, stat->expectFrom); + if (ret) ret = enc_int(ret, stat->payload_running); + if (ret) ret = enc_strlist(ret, stat->possible_destinations); + if (ret) ret = enc_strlist(ret, stat->possible_ce_nodes); return ret; } @@ -399,6 +478,9 @@ static edg_wll_JobStat* dec_JobStat(char *in, char **rest) if (tmp_in != NULL) stat->lastUpdateTime = dec_timeval(tmp_in, &tmp_in); if (tmp_in != NULL) stat->expectUpdate = dec_int(tmp_in, &tmp_in); if (tmp_in != NULL) stat->expectFrom = dec_string(tmp_in, &tmp_in); + if (tmp_in != NULL) stat->payload_running = dec_int(tmp_in, &tmp_in); + if (tmp_in != NULL) stat->possible_destinations = dec_strlist(tmp_in, &tmp_in); + if (tmp_in != NULL) stat->possible_ce_nodes = dec_strlist(tmp_in, &tmp_in); *rest = tmp_in; return stat; @@ -409,9 +491,13 @@ char *enc_intJobStat(char *old, intJobStat* stat) char *ret; ret = enc_JobStat(old, &stat->pub); - if (ret) ret = enc_int(ret, stat->wontresub); + if (ret) ret = enc_int(ret, stat->resubmit_type); if (ret) ret = enc_string(ret, stat->last_seqcode); if (ret) ret = enc_string(ret, stat->last_cancel_seqcode); + if (ret) ret = enc_string(ret, stat->branch_tag_seqcode); + if (ret) ret = enc_string(ret, stat->last_branch_seqcode); + if (ret) ret = enc_string(ret, stat->deep_resubmit_seqcode); + if (ret) ret = enc_branch_states(ret, stat->branch_states); return ret; } @@ -428,13 +514,25 @@ intJobStat* dec_intJobStat(char *in, char **rest) if (stat != NULL) { stat->pub = *pubstat; free(pubstat); - stat->wontresub = dec_int(tmp_in, &tmp_in); + stat->resubmit_type = dec_int(tmp_in, &tmp_in); if (tmp_in != NULL) { stat->last_seqcode = dec_string(tmp_in, &tmp_in); } if (tmp_in != NULL) { stat->last_cancel_seqcode = dec_string(tmp_in, &tmp_in); } + if (tmp_in != NULL) { + stat->branch_tag_seqcode = dec_string(tmp_in, &tmp_in); + } + if (tmp_in != NULL) { + stat->last_branch_seqcode = dec_string(tmp_in, &tmp_in); + } + if (tmp_in != NULL) { + stat->deep_resubmit_seqcode = dec_string(tmp_in, &tmp_in); + } + if (tmp_in != NULL) { + stat->branch_states = dec_branch_states(tmp_in, &tmp_in); + } } else if (tmp_in != NULL) { edg_wll_FreeStatus(pubstat); free(pubstat); @@ -598,6 +696,47 @@ edg_wll_ErrorCode edg_wll_RefreshIColumns(edg_wll_Context ctx, void *job_index_c return edg_wll_Error(ctx, NULL, NULL); } +int component_seqcode(const char *a, edg_wll_Source index) +{ + unsigned int c[EDG_WLL_SOURCE__LAST]; + int res; + + res = sscanf(a, "UI=%d:NS=%d:WM=%d:BH=%d:JSS=%d:LM=%d:LRMS=%d:APP=%d", + &c[EDG_WLL_SOURCE_USER_INTERFACE], + &c[EDG_WLL_SOURCE_NETWORK_SERVER], + &c[EDG_WLL_SOURCE_WORKLOAD_MANAGER], + &c[EDG_WLL_SOURCE_BIG_HELPER], + &c[EDG_WLL_SOURCE_JOB_SUBMISSION], + &c[EDG_WLL_SOURCE_LOG_MONITOR], + &c[EDG_WLL_SOURCE_LRMS], + &c[EDG_WLL_SOURCE_APPLICATION]); + if (res != EDG_WLL_SOURCE__LAST-1) { + syslog(LOG_ERR, "unparsable sequence code %s\n", a); + fprintf(stderr, "unparsable sequence code %s\n", a); + return -1; + } + + return(c[index]); +} + +int before_deep_resubmission(const char *a, const char *b) +{ + if (component_seqcode(a, EDG_WLL_SOURCE_WORKLOAD_MANAGER) < + component_seqcode(b, EDG_WLL_SOURCE_WORKLOAD_MANAGER) ) + return(1); + else + return(0); + +} + +int same_branch(const char *a, const char *b) +{ + if (component_seqcode(a, EDG_WLL_SOURCE_WORKLOAD_MANAGER) == + component_seqcode(b, EDG_WLL_SOURCE_WORKLOAD_MANAGER) ) + return(1); + else + return(0); +} int edg_wll_compare_seq(const char *a, const char *b) { diff --git a/org.glite.lb.server/src/lb_xml_parse.c.T b/org.glite.lb.server/src/lb_xml_parse.c.T index 6732a04..6a13b2b 100644 --- a/org.glite.lb.server/src/lb_xml_parse.c.T +++ b/org.glite.lb.server/src/lb_xml_parse.c.T @@ -1625,6 +1625,8 @@ int edg_wll_JobStatusToXML(edg_wll_Context ctx, edg_wll_JobStat stat, char **mes gen "edg_wll_add_$ft\_to_XMLBody(&pomB, stat.$_, \"$_\", $n);\n"; } @@@} + if (stat.possible_destinations) edg_wll_add_strlist_to_XMLBody(&pomB, stat.possible_destinations, "possible_destinations", "name", "\t\t\t", NULL); + if (stat.possible_ce_nodes) edg_wll_add_strlist_to_XMLBody(&pomB, stat.possible_ce_nodes, "possible_ce_nodes", "name", "\t\t\t", NULL); if (stat.children) edg_wll_add_strlist_to_XMLBody(&pomB, stat.children, "children", "jobId", "\t\t\t", NULL); if (stat.children_hist) edg_wll_add_intlist_to_XMLBody(&pomB, stat.children_hist, "children_hist", edg_wll_StatToString, "\t\t\t", 1, stat.children_hist[0]); if (stat.children_states) edg_wll_add_stslist_to_XMLBody(ctx, &pomB, stat.children_states, "children_states", "", EDG_WLL_JOB_UNDEF); diff --git a/org.glite.lb.ws-interface/interface/LB.wsdl b/org.glite.lb.ws-interface/interface/LB.wsdl deleted file mode 100755 index dfbce26..0000000 --- a/org.glite.lb.ws-interface/interface/LB.wsdl +++ /dev/null @@ -1,358 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Query the version of LB servere - -Input: no input - -Output: Version of LB server - -Faults: GenericLBFault - - - - - - - Retrieve state of a single job. - -Given a job id queries LB for detailed state of the job. - - -Input: - -jobid: Id of the job - -flags: Which fields of the job state should be retrieved: zero or more of CLASSADS, CHILDREN, CHILDSTAT - -Output: state of the job - -Faults: GenericLBFault - - - - - - - Query for jobs satisfying set of conditions. - -Intput: - -conditions: list of lists of query conditions. - Elements of the inner lists refer to a single job attribute, the conditions are or-ed. - Elements of the outer list may refer to different job attributes, they are and-ed. - -flags: Which fields of the job state should be retrieved: see JobStatus - -Output: list of mathching jobs, including their states - -Faults: GenericLBFault - - - - - - - Query all jobs of the current user. - -Input: no input - -Output: list of all user's jobs, including their states - -Faults: GenericLBFault - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Logging and Bookkeeping service - - - - - diff --git a/org.glite.lb/project/dependencies.properties b/org.glite.lb/project/dependencies.properties index a7981bb..a2f7c3b 100644 --- a/org.glite.lb/project/dependencies.properties +++ b/org.glite.lb/project/dependencies.properties @@ -1,16 +1,27 @@ + ################################################################### # System dependencies ################################################################### -org.glite.version = HEAD -org.glite.lb.version = HEAD + + + org.glite.version = glite_B_1_0_5_190 + org.glite.lb.version = glite-lb_branch_1_1_0_2_SHALLOW + + org.glite.lb.client-interface.version = glite-lb-client-interface_branch_1_2_1_3 + + org.glite.lb.ws-interface.version = glite-lb-ws-interface_branch_1_2_0_2 + + org.glite.lb.common.version = glite-lb-common_branch_1_4_0_2 + + org.glite.lb.client.version = glite-lb-client_branch_1_2_1_2 + + org.glite.lb.server-bones.version = glite-lb-server-bones_branch_2_0_0_2 + + org.glite.lb.logger.version = glite-lb-logger_branch_1_1_1_2 + + org.glite.lb.server.version = glite-lb-server_branch_1_2_4_2 + + org.glite.lb.proxy.version = glite-lb-proxy_branch_1_1_1_2 + -# Component dependencies tag = do not remove this line = -org.glite.lb.client-interface.version = HEAD -org.glite.lb.ws-interface.version = HEAD -org.glite.lb.common.version = HEAD -org.glite.lb.client.version = HEAD -org.glite.lb.server.version = HEAD -org.glite.lb.proxy.version = HEAD -org.glite.lb.server-bones.version = HEAD -org.glite.lb.logger.version = HEAD diff --git a/org.glite.lb/project/events.T b/org.glite.lb/project/events.T index b8e5399..f048a2d 100644 --- a/org.glite.lb/project/events.T +++ b/org.glite.lb/project/events.T @@ -86,13 +86,14 @@ _code_ CALLING the logging component is caller _code_ CALLED the logging component is callee -@type Running Executable started +@type Running Job wrapper started string node worker node where the executable is run @type Resubmission Result of resubmission decision int result result code - _code_ WILLRESUB will be resubmitted + _code_ WILLRESUB will be resubmitted (deep resubmission) _code_ WONTRESUB will not be resubmitted + _code_ SHALLOW shallow resubmission (user payload has not started yet) string reason reason for the decision string tag value of the attribute on which the decision is based @@ -181,3 +182,6 @@ port dest_port destination port string jobstat job status +@type ReallyRunning User payload started + _optional_ + string wn_seq sequence code on the worker node diff --git a/org.glite.lb/project/status.T b/org.glite.lb/project/status.T index 10071ac..5c409a8 100644 --- a/org.glite.lb/project/status.T +++ b/org.glite.lb/project/status.T @@ -64,6 +64,12 @@ bool expectUpdate Some logged information has not arrived yet string expectFrom Sources of the missing information string acl ACL of the job +bool payload_running User payload started +strlist possible_destinations Possible job destinations + _special_ XMLstructured +strlist possible_ce_nodes CE nodes matching to possible_destinations + _special_ XMLstructured + @type Submitted entered by the user to the User Interface or registered by Job Partitioner @type Waiting Accepted by WMS, waiting for resource allocation @type Ready Matching resources found diff --git a/org.glite.security.gsoap-plugin/LICENSE b/org.glite.security.gsoap-plugin/LICENSE deleted file mode 100644 index 259a91f..0000000 --- a/org.glite.security.gsoap-plugin/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -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 -. - -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/ - - diff --git a/org.glite.security.gsoap-plugin/Makefile b/org.glite.security.gsoap-plugin/Makefile deleted file mode 100644 index 6fce5b1..0000000 --- a/org.glite.security.gsoap-plugin/Makefile +++ /dev/null @@ -1,221 +0,0 @@ -# defaults -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -package=gsoap-plugin -version=1.0.0 -PREFIX=/opt/glite - -glite_location=/opt/glite -globus_prefix=/opt/globus -nothrflavour=gcc32 -thrflavour=gcc32pthr -gsoap_prefix=/opt/gsoap - -CC=gcc - --include Makefile.inc --include ../Makefile.inc - -GSPLUGIN_DEBUG?=no -GSPLUGIN_VERSION_CHECKING?=yes - -version_info=-version-info `echo ${version} | cut -d. -f1,2 | tr . :` - -VPATH=${top_srcdir}/src:${top_srcdir}/test:${top_srcdir}/examples - -TEST_LIBS:=-L${cppunit}/lib -lcppunit -TEST_INC:=-I${cppunit}/include - -ifeq ($(GSPLUGIN_DEBUG),yes) - DEBUG:=-g -O0 -Wall -DGSPLUGIN_DEBUG -else - DEBUG:=-g -O0 -Wall -endif - -ifeq ($(GSPLUGIN_VERSION_CHECKING),yes) - DEBUG:=${DEBUG} -DCHECK_GSOAP_VERSION -endif - -CFLAGS:= ${DEBUG} \ - -DVERSION=\"${version}\" \ - -I${top_srcdir}/src -I${top_srcdir}/interface -I. \ - -I${stagedir}/include \ - -I${gsoap_prefix}/include \ - -I${ares_prefix}/include \ - -I${globus_prefix}/include/${nothrflavour} \ - -I${globus_prefix}/include/${nothrflavour}/openssl \ - ${COVERAGE_FLAGS} -D_GNU_SOURCE -DDATAGRID_EXTENSION - -LDFLAGS:=${COVERAGE_FLAGS} - -COMPILE:=libtool --mode=compile ${CC} ${CFLAGS} -LINK:=libtool --mode=link ${CC} -rpath ${stagedir}/lib ${LDFLAGS} -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install -LINKXX:=libtool --mode=link ${CXX} -rpath ${stagedir}/lib ${LDFLAGS} - -GLOBUS_INC:= -I${globus_prefix}/include/${nothrflavour} -GLOBUS_LIBS:= -L${globus_prefix}/lib \ - -lglobus_common_${nothrflavour} \ - -lglobus_gssapi_gsi_${nothrflavour} \ - -GSOAP_LIBS:= -L${gsoap_prefix}/lib -lgsoap - -EX_LIBS:= ${GLOBUS_LIBS} -L${ares_prefix}/lib -lares - -HDRS:=glite_gss.h glite_gsplugin.h - -GSS_OBJS:=glite_gss.o -GSS_LOBJS:=${GSS_OBJS:.o=.lo} -GSS_THROBJS:=${GSS_OBJS:.o=.thr.o} -GSS_THRLOBJS:=${GSS_OBJS:.o=.thr.lo} - -GSS_STATICLIB:=libglite_security_gss_${nothrflavour}.a -GSS_THRSTATICLIB:=libglite_security_gss_${thrflavour}.a -GSS_LTLIB:=libglite_security_gss_${nothrflavour}.la -GSS_THRLTLIB:=libglite_security_gss_${thrflavour}.la - -OBJS:=${GSS_OBJS} glite_gsplugin.o -LOBJS:=${GSS_OBJS:.o=.lo} -THROBJS:=${GSS_OBJS:.o=.thr.o} -THRLOBJS:=${GSS_OBJS:.o=.thr.lo} - -STATICLIB:=libglite_security_gsoap_plugin_${nothrflavour}.a -THRSTATICLIB:=libglite_security_gsoap_plugin_${thrflavour}.a -LTLIB:=libglite_security_gsoap_plugin_${nothrflavour}.la -THRLTLIB:=libglite_security_gsoap_plugin_${thrflavour}.la - -${GSS_STATICLIB}: ${GSS_OBJS} - ar crv $@ ${GSS_OBJS} - ranlib $@ - -${GSS_THRSTATICLIB}: ${GSS_THROBJS} - ar crv $@ ${GSS_THROBJS} - ranlib $@ - -${GSS_LTLIB}: ${GSS_OBJS} - ${LINK} ${version_info} -o $@ ${GSS_LOBJS} - -${GSS_THRLTLIB}: ${GSS_THROBJS} - ${LINK} ${version_info} -o $@ ${GSS_THRLOBJS} - -${STATICLIB}: ${OBJS} - ar crv $@ ${OBJS} - ranlib $@ - -${THRSTATICLIB}: ${THROBJS} - ar crv $@ ${THROBJS} - ranlib $@ - -${LTLIB}: ${OBJS} - ${LINK} ${version_info} -o $@ ${LOBJS} - -${THRLTLIB}: ${THROBJS} - ${LINK} ${version_info} -o $@ ${THRLOBJS} - -default: all - -all compile: ${GSS_STATICLIB} ${GSS_LTLIB} ${GSS_THRSTATICLIB} ${GSS_THRLTLIB} ${STATICLIB} ${LTLIB} ${THRSTATICLIB} ${THRLTLIB} examples - -check: compile check.gss - -check.gss: test_gss - # ./test_gss - echo test_gss not run automatically util we have got some credentials - -test_gss: test_gss.o - ${LINKXX} -o $@ test_gss.o ${GSS_LTLIB} ${TEST_LIBS} ${GLOBUS_LIBS} ${EX_LIBS} - -test_coverage: - -mkdir coverage - cd coverage && $(MAKE) -f ../Makefile top_srcdir=../../ COVERAGE_FLAGS="-fprofile-arcs -ftest-coverage" check - cd coverage && for i in ${OBJS}; do gcov -o .libs/ $$i ; done - - -examples: soap_gen wscalc_clt_ex wscalc_srv_ex wscalc_srv_ex2 - -GSOAP_FPREFIX:= GSOAP_ - -ifeq ($(GSPLUGIN_DEBUG),yes) - WSCALC_CLT_OBJS = wscalc_clt_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Client.o \ - stdsoap2.o - WSCALC_SRV_OBJS = wscalc_srv_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o \ - stdsoap2.o - WSCALC_SRV2_OBJS = wscalc_srv_ex2.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o \ - stdsoap2.o -else - WSCALC_CLT_OBJS = wscalc_clt_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Client.o - WSCALC_SRV_OBJS = wscalc_srv_ex.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o - WSCALC_SRV2_OBJS = wscalc_srv_ex2.o ${GSOAP_FPREFIX}C.o ${GSOAP_FPREFIX}Server.o -endif - - -wscalc_clt_ex: ${WSCALC_CLT_OBJS} ${STATICLIB} - ${LINK} -o $@ ${STATICLIB} ${GSOAP_LIBS} ${EX_LIBS} ${WSCALC_CLT_OBJS} - -wscalc_srv_ex: ${WSCALC_SRV_OBJS} ${STATICLIB} - ${LINK} -o $@ ${STATICLIB} ${GSOAP_LIBS} ${EX_LIBS} ${WSCALC_SRV_OBJS} - -wscalc_srv_ex2: ${WSCALC_SRV2_OBJS} ${STATICLIB} - ${LINK} -o $@ ${STATICLIB} ${GSOAP_LIBS} ${EX_LIBS} ${WSCALC_SRV2_OBJS} - -${GSOAP_FPREFIX}H.h ${GSOAP_FPREFIX}C.c ${GSOAP_FPREFIX}Server.c ${GSOAP_FPREFIX}Client.c ${GSOAP_FPREFIX}ServerLib.c ${GSOAP_FPREFIX}ClientLib.c soap_gen: calc.h.S - ${gsoap_prefix}/bin/soapcpp2 -c -p ${GSOAP_FPREFIX} ${top_srcdir}/examples/calc.h.S - -wscalc_clt_ex.o: wscalc_clt_ex.c - ${CC} -c ${CFLAGS} ${GLOBUS_INC} -o $@ $< - -stdsoap2.o: ${gsoap_prefix}/devel/stdsoap2.c - ${CC} -c ${CFLAGS} -o $@ $< - -doc: - -stage: compile - $(MAKE) install PREFIX=${stagedir} DOSTAGE=yes - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -install: - -mkdir -p ${PREFIX}/lib - -mkdir -p ${PREFIX}/share/doc/${package}-${version} - -mkdir -p ${PREFIX}/include/glite/security/${package} - ${INSTALL} -m 644 ${GSS_LTLIB} ${GSS_THRLTLIB} ${PREFIX}/lib - ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - cd ${top_srcdir}/interface && ${INSTALL} -m 644 ${HDRS} ${PREFIX}/include/glite/security/ - if [ x${DOSTAGE} = xyes ]; then \ - install -m 644 ${GSS_STATICLIB} ${GSS_THRSTATICLIB} ${STATICLIB} ${THRSTATICLIB} ${PREFIX}/lib; \ - fi - -clean: - -%.o: %.c - ${COMPILE} ${GLOBUS_INC} -o $@ -c $< - -%.thr.o: %.c - ${COMPILE} ${GLOBUS_THR_INC} -o $@ -c $< - -test_gss.o: %.o: %.cpp - ${CXX} -c ${CFLAGS} ${GLOBUSINC} ${TEST_INC} $< - -soap_version.h: - ${gsoap_prefix}/bin/soapcpp2 /dev/null - perl -ne '$$. == 2 && /.*([0-9])\.([0-9])\.(\S+)\s.*/ && printf "#define GSOAP_VERSION %d%02d%02d\n#define GSOAP_MIN_VERSION \"$$3\"\n",$$1,$$2,$$3' soapH.h >$@ - -rm soapC.cpp soapH.h soapStub.h soapClient.cpp soapServer.cpp soapClientLib.cpp soapServerLib.cpp - -glite_gsplugin.o: soap_version.h - diff --git a/org.glite.security.gsoap-plugin/build.xml b/org.glite.security.gsoap-plugin/build.xml deleted file mode 100755 index 485aa55..0000000 --- a/org.glite.security.gsoap-plugin/build.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.security.gsoap-plugin/examples/calc.h.S b/org.glite.security.gsoap-plugin/examples/calc.h.S deleted file mode 100644 index 385e872..0000000 --- a/org.glite.security.gsoap-plugin/examples/calc.h.S +++ /dev/null @@ -1,13 +0,0 @@ -//gsoap egeesec schema namespace: urn:calc -// -//gsoap egeesec service name: calc -//gsoap egeesec service port: http://localhost:9999/ -//gsoap egeesec service namespace: urn:calc:wscalc - -//gsoap egeesec service method-style: add rpc -//gsoap egeesec service method-action: add "" -int wscalc__add(double a, double b, double *result); - -//gsoap egeesec service method-style: sub rpc -//gsoap egeesec service method-action: sub "" -int wscalc__sub(double a, double b, double *result); diff --git a/org.glite.security.gsoap-plugin/examples/wscalc_clt_ex.c b/org.glite.security.gsoap-plugin/examples/wscalc_clt_ex.c deleted file mode 100644 index b96827d..0000000 --- a/org.glite.security.gsoap-plugin/examples/wscalc_clt_ex.c +++ /dev/null @@ -1,47 +0,0 @@ -#include - -#include "GSOAP_H.h" -#include "wscalc.nsmap" - -static const char *server = "http://localhost:9999/"; - -int -main(int argc, char **argv) -{ - struct soap soap; - double a, b, result; - int ret; - - - if (argc < 4) { - fprintf(stderr, "Usage: [add|sub] num num\n"); - exit(1); - } - - soap_init(&soap); - soap_register_plugin(&soap, glite_gsplugin); - - a = strtod(argv[2], NULL); - b = strtod(argv[3], NULL); - switch ( *argv[1] ) { - case 'a': - ret = soap_call_wscalc__add(&soap, server, "", a, b, &result); - break; - case 's': - ret = soap_call_wscalc__sub(&soap, server, "", a, b, &result); - break; - default: - fprintf(stderr, "Unknown command\n"); - exit(2); - } - - if ( ret ) { - fprintf(stderr, "NECO JE V ****\n\n"); - fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap)); - soap_print_fault(&soap, stderr); - } - else printf("result = %g\n", result); - - - return 0; -} diff --git a/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c b/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c deleted file mode 100644 index 96d58f4..0000000 --- a/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include - -#include "GSOAP_H.h" -#include "wscalc.nsmap" - - -static struct option long_options[] = { - { "cert", required_argument, NULL, 'c' }, - { "key", required_argument, NULL, 'k' }, - { NULL, 0, NULL, 0 } -}; - -void -usage(const char *me) -{ - fprintf(stderr, - "usage: %s [option]\n" - "\t-c, --cred\t certificate file\n" - "\t-k, --key\t private key file\n", me); -} - - -int -main(int argc, char **argv) -{ - struct soap soap; - glite_gsplugin_Context ctx = NULL; - char *name; - char *cert, *key; - int opt; - - - cert = key = NULL; - name = strrchr(argv[0],'/'); - if ( name ) name++; else name = argv[0]; - - while ((opt = getopt_long(argc, argv, "c:k:", long_options, NULL)) != EOF) { - switch (opt) { - case 'c': cert = optarg; break; - case 'k': key = optarg; break; - case '?': - default : usage(name); exit(1); - } - } - - if ( cert || key ) { - if ( glite_gsplugin_init_context(&ctx) ) { perror("init context"); exit(1); } - ctx->cert_filename = strdup(cert? : key); - ctx->key_filename = strdup(key? : cert); - } - - soap_init(&soap); - - if ( soap_register_plugin_arg(&soap, glite_gsplugin, ctx? : NULL) ) { - fprintf(stderr, "Can't register plugin\n"); - exit(1); - } - - if ( soap_bind(&soap, NULL, 9999, 100) < 0 ) { - soap_print_fault(&soap, stderr); - exit(1); - } - - while ( 1 ) { - printf("accepting connection\n"); - if ( soap_accept(&soap) < 0 ) { - fprintf(stderr, "soap_accept() failed!!!\n"); - soap_print_fault(&soap, stderr); - fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap)); - break; - } - - printf("serving connection\n"); - if ( soap_serve(&soap) ) { - soap_print_fault(&soap, stderr); - fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap)); - } - - soap_destroy(&soap); /* clean up class instances */ - soap_end(&soap); /* clean up everything and close socket */ - } - soap_done(&soap); /* close master socket */ - - if ( ctx ) glite_gsplugin_free_context(ctx); - - return 0; -} - -int wscalc__add(struct soap *soap, double a, double b, double *result) -{ - *result = a + b; - return SOAP_OK; -} - -int wscalc__sub(struct soap *soap, double a, double b, double *result) -{ - *result = a - b; - return SOAP_OK; -} diff --git a/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c b/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c deleted file mode 100644 index 8a7c001..0000000 --- a/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c +++ /dev/null @@ -1,130 +0,0 @@ -#include -#include -#include -#include - -#include "GSOAP_H.h" -#include "wscalc.nsmap" - - -static struct option long_options[] = { - { "cert", required_argument, NULL, 'c' }, - { "key", required_argument, NULL, 'k' }, - { "port", required_argument, NULL, 'p' }, - { NULL, 0, NULL, 0 } -}; - -void -usage(const char *me) -{ - fprintf(stderr, - "usage: %s [option]\n" - "\t-p, --port\t listening port\n" - "\t-c, --cred\t certificate file\n" - "\t-k, --key\t private key file\n", me); -} - - -int -main(int argc, char **argv) -{ - struct soap soap; - edg_wll_GssStatus gss_code; - glite_gsplugin_Context ctx; - struct sockaddr_in a; - int alen; - char *name, *msg; - char *subject = NULL; - int opt, - port = 9999; - int sock; - - - name = strrchr(argv[0],'/'); - if ( name ) name++; else name = argv[0]; - - if ( glite_gsplugin_init_context(&ctx) ) { perror("init context"); exit(1); } - - while ((opt = getopt_long(argc, argv, "c:k:p:", long_options, NULL)) != EOF) { - switch (opt) { - case 'p': port = atoi(optarg); break; - case 'c': ctx->cert_filename = strdup(optarg); break; - case 'k': ctx->key_filename = strdup(optarg); break; - case '?': - default : usage(name); exit(1); - } - } - - if ( edg_wll_gss_acquire_cred_gsi(ctx->cert_filename, ctx->key_filename, &ctx->cred, &subject, &gss_code) ) { - edg_wll_gss_get_error(&gss_code, "Failed to read credential", &msg); - fprintf(stderr, "%s\n", msg); - free(msg); - exit(1); - } - if (subject) { - printf("server running with certificate: %s\n", subject); - free(subject); - } - - soap_init(&soap); - - if ( soap_register_plugin_arg(&soap, glite_gsplugin, ctx) ) { - fprintf(stderr, "Can't register plugin\n"); - exit(1); - } - - alen = sizeof(a); - if ( (sock = socket(PF_INET,SOCK_STREAM,0)) < 0 ) { perror("socket()"); exit(1); } - a.sin_family = AF_INET; - a.sin_port = htons(port); - a.sin_addr.s_addr = INADDR_ANY; - if ( bind(sock, (struct sockaddr *)&a, sizeof(a)) ) { perror("bind()"); exit(1); } - if ( listen(sock, 100) ) { perror("listen()"); exit(1); } - if ( !(ctx->connection = malloc(sizeof(*ctx->connection))) ) exit(1); - - bzero((char *) &a, alen); - - while ( 1 ) { - int conn; - - printf("accepting connection\n"); - if ( (conn = accept(sock, (struct sockaddr *) &a, &alen)) < 0 ) { - close(sock); - perror("accept"); - exit(1); - } - if ( edg_wll_gss_accept(ctx->cred,conn,ctx->timeout,ctx->connection,&gss_code) ){ - edg_wll_gss_get_error(&gss_code, "Failed to read credential", &msg); - fprintf(stderr, "%s\n", msg); - free(msg); - exit(1); - } - - printf("serving connection\n"); - if ( soap_serve(&soap) ) { - soap_print_fault(&soap, stderr); - fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap)); - } - - soap_destroy(&soap); /* clean up class instances */ - soap_end(&soap); /* clean up everything and close socket */ - } - - soap_done(&soap); /* close master socket */ - - glite_gsplugin_free_context(ctx); - - return 0; -} - -int wscalc__add(struct soap *soap, double a, double b, double *result) -{ - *result = a + b; - return SOAP_OK; -} - -int wscalc__sub(struct soap *soap, double a, double b, double *result) -{ - *result = a - b; - return SOAP_OK; -} diff --git a/org.glite.security.gsoap-plugin/interface/glite_gsplugin.h b/org.glite.security.gsoap-plugin/interface/glite_gsplugin.h deleted file mode 100644 index 1272a48..0000000 --- a/org.glite.security.gsoap-plugin/interface/glite_gsplugin.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __GLITE_GSOAP_PLUGIN_H__ -#define __GLITE_GSOAP_PLUGIN_H__ - -#include - -#include "glite_gss.h" - -#define PLUGIN_ID "GLITE_GSOAP_PLUGIN" - -struct _glite_gsplugin_ctx { - struct timeval _timeout, *timeout; - - char *error_msg; - - char *key_filename; - char *cert_filename; - - edg_wll_GssConnection *connection; - gss_cred_id_t cred; - - void *user_data; -}; - -typedef struct _glite_gsplugin_ctx *glite_gsplugin_Context; - -extern int glite_gsplugin_init_context(glite_gsplugin_Context *); -extern int glite_gsplugin_free_context(glite_gsplugin_Context); -extern glite_gsplugin_Context glite_gsplugin_get_context(struct soap *); -extern void *glite_gsplugin_get_udata(struct soap *); -extern void glite_gsplugin_set_udata(struct soap *, void *); - -extern void glite_gsplugin_set_timeout(glite_gsplugin_Context, struct timeval const *); - -extern int glite_gsplugin(struct soap *, struct soap_plugin *, void *); -extern char *glite_gsplugin_errdesc(struct soap *); - -#endif diff --git a/org.glite.security.gsoap-plugin/interface/glite_gss.h b/org.glite.security.gsoap-plugin/interface/glite_gss.h deleted file mode 100644 index 3dd4903..0000000 --- a/org.glite.security.gsoap-plugin/interface/glite_gss.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__ -#define __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__ - -#ident "$Header$" - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - EDG_WLL_GSS_OK = 0, /* no GSS errors */ - EDG_WLL_GSS_ERROR_GSS = -1, /* GSS specific error, call edg_wll_get_gss_error() for details */ - EDG_WLL_GSS_ERROR_TIMEOUT = -2, /* Timeout */ - EDG_WLL_GSS_ERROR_EOF = -3, /* EOF occured */ - EDG_WLL_GSS_ERROR_ERRNO = -4, /* System error. See errno */ - EDG_WLL_GSS_ERROR_HERRNO = -5 /* Resolver error. See h_errno */ -}; - -typedef struct _edg_wll_GssConnection { - gss_ctx_id_t context; - int sock; - char *buffer; - size_t bufsize; -} edg_wll_GssConnection; - -typedef struct _edg_wll_GssStatus { - OM_uint32 major_status; - OM_uint32 minor_status; -} edg_wll_GssStatus; - -/* XXX Support anonymous connections. Are we able/required to support - * anonymous servers as well. */ - -int -edg_wll_gss_acquire_cred_gsi(char *cert_file, - char *key_file, - gss_cred_id_t *cred, - char **name, - edg_wll_GssStatus* gss_code); - -int -edg_wll_gss_connect(gss_cred_id_t cred, - char const *hostname, - int port, - struct timeval *timeout, - edg_wll_GssConnection *connection, - edg_wll_GssStatus* gss_code); - -int -edg_wll_gss_accept(gss_cred_id_t cred, - int sock, - struct timeval *timeout, - edg_wll_GssConnection *connection, - edg_wll_GssStatus* gss_code); - -int -edg_wll_gss_read(edg_wll_GssConnection *connection, - void *buf, - size_t bufsize, - struct timeval *timeout, - edg_wll_GssStatus* gss_code); - -int -edg_wll_gss_write(edg_wll_GssConnection *connection, - const void *buf, - size_t bufsize, - struct timeval *timeout, - edg_wll_GssStatus* gss_code); - -int -edg_wll_gss_read_full(edg_wll_GssConnection *connection, - void *buf, - size_t bufsize, - struct timeval *timeout, - size_t *total, - edg_wll_GssStatus* gss_code); - -int -edg_wll_gss_write_full(edg_wll_GssConnection *connection, - const void *buf, - size_t bufsize, - struct timeval *timeout, - size_t *total, - edg_wll_GssStatus* gss_code); - -int -edg_wll_gss_watch_creds(const char * proxy_file, - time_t * proxy_mtime); - -int -edg_wll_gss_get_error(edg_wll_GssStatus* gss_code, - const char *prefix, - char **errmsg); - -int -edg_wll_gss_close(edg_wll_GssConnection *connection, - struct timeval *timeout); - -int -edg_wll_gss_reject(int sock); - -int -edg_wll_gss_oid_equal(const gss_OID a, - const gss_OID b); - -/* -int -edg_wll_gss_get_name(gss_cred_id_t cred, char **name); -*/ - -#ifdef __cplusplus -} -#endif - -#endif /* __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__ */ diff --git a/org.glite.security.gsoap-plugin/project/build.number b/org.glite.security.gsoap-plugin/project/build.number deleted file mode 100644 index d794048..0000000 --- a/org.glite.security.gsoap-plugin/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build=0 diff --git a/org.glite.security.gsoap-plugin/project/build.properties b/org.glite.security.gsoap-plugin/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.security.gsoap-plugin/project/configure.properties.xml b/org.glite.security.gsoap-plugin/project/configure.properties.xml deleted file mode 100644 index 466bbe2..0000000 --- a/org.glite.security.gsoap-plugin/project/configure.properties.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -lbprefix=${subsystem.prefix} -package=${module.package.name} -PREFIX=${install.dir} -version=${module.version} -glite_location=${with.glite.location} -ares_prefix=${with.ares.prefix} -globus_prefix=${with.globus.prefix} -thrflavour=${with.globus.thr.flavor} -nothrflavour=${with.globus.nothr.flavor} -cppunit=${with.cppunit.prefix} -gsoap_prefix=${with.gsoap.prefix} - - - diff --git a/org.glite.security.gsoap-plugin/project/properties.xml b/org.glite.security.gsoap-plugin/project/properties.xml deleted file mode 100755 index f63ddbd..0000000 --- a/org.glite.security.gsoap-plugin/project/properties.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.security.gsoap-plugin/project/tar_exclude b/org.glite.security.gsoap-plugin/project/tar_exclude deleted file mode 100644 index b3133e4..0000000 --- a/org.glite.security.gsoap-plugin/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure-options.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.security.gsoap-plugin/project/version.properties b/org.glite.security.gsoap-plugin/project/version.properties deleted file mode 100644 index b69e5b7..0000000 --- a/org.glite.security.gsoap-plugin/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -# 1.2 pushed after branching 1.1, no added functionality yet -module.version=1.2.0 -module.age=0 diff --git a/org.glite.security.gsoap-plugin/src/glite_gsplugin.c b/org.glite.security.gsoap-plugin/src/glite_gsplugin.c deleted file mode 100644 index 17cacc5..0000000 --- a/org.glite.security.gsoap-plugin/src/glite_gsplugin.c +++ /dev/null @@ -1,412 +0,0 @@ -#include -#include -#include -#include - -#include "soap_version.h" -#include "glite_gsplugin.h" - -#ifdef GSPLUGIN_DEBUG -# define pdprintf(s) printf s -#else -# define pdprintf(s) -#endif - -typedef struct _int_plugin_data_t { - glite_gsplugin_Context ctx; /**< data used for connection etc. */ - int def; /**< is the context created by plugin? */ -} int_plugin_data_t; - -static const char plugin_id[] = PLUGIN_ID; - -static void glite_gsplugin_delete(struct soap *, struct soap_plugin *); -static int glite_gsplugin_copy(struct soap *, struct soap_plugin *, struct soap_plugin *); - -static size_t glite_gsplugin_recv(struct soap *, char *, size_t); -static int glite_gsplugin_send(struct soap *, const char *, size_t); -static int glite_gsplugin_connect(struct soap *, const char *, const char *, int); -static int glite_gsplugin_close(struct soap *); -static int glite_gsplugin_accept(struct soap *, int, struct sockaddr *, int *); - - -int -glite_gsplugin_init_context(glite_gsplugin_Context *ctx) -{ - glite_gsplugin_Context out = (glite_gsplugin_Context) malloc(sizeof(*out)); - if (!out) return ENOMEM; - - memset(out, 0, sizeof(*out)); - out->cred = GSS_C_NO_CREDENTIAL; - - /* XXX: some troubles with glite_gss and blocking calls! - out->timeout.tv_sec = 10000; - */ - - out->timeout = NULL; - *ctx = out; - - return 0; -} - -int -glite_gsplugin_free_context(glite_gsplugin_Context ctx) -{ - OM_uint32 ms; - - if ( ctx->cred != GSS_C_NO_CREDENTIAL ) gss_release_cred(&ms, &ctx->cred); - if ( ctx->connection ) { - if ( ctx->connection->context != GSS_C_NO_CONTEXT ) - edg_wll_gss_close(ctx->connection, NULL); - free(ctx->connection); - } - free(ctx->error_msg); - free(ctx->key_filename); - free(ctx->cert_filename); - free(ctx); - - return 0; -} - -glite_gsplugin_Context -glite_gsplugin_get_context(struct soap *soap) -{ - return ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx; -} - -void * -glite_gsplugin_get_udata(struct soap *soap) -{ - int_plugin_data_t *pdata; - - pdata = (int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id); - assert(pdata); - return pdata->ctx->user_data; -} - -void -glite_gsplugin_set_udata(struct soap *soap, void *d) -{ - int_plugin_data_t *pdata; - - pdata = (int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id); - assert(pdata); - pdata->ctx->user_data = d; -} - -void glite_gsplugin_set_timeout(glite_gsplugin_Context ctx, struct timeval const *to) -{ - if (to) { - ctx->_timeout = *to; - ctx->timeout = &ctx->_timeout; - } - else ctx->timeout = NULL; -} - - -int -glite_gsplugin(struct soap *soap, struct soap_plugin *p, void *arg) -{ - int_plugin_data_t *pdata = malloc(sizeof(int_plugin_data_t)); - - pdprintf(("GSLITE_GSPLUGIN: initializing gSOAP plugin\n")); - if ( !pdata ) return ENOMEM; - if ( arg ) { - pdprintf(("GSLITE_GSPLUGIN: Context is given\n")); - pdata->ctx = arg; - pdata->def = 0; - } - else { - edg_wll_GssStatus gss_code; - char *subject = NULL; - - pdprintf(("GSLITE_GSPLUGIN: Creating default context\n")); - if ( glite_gsplugin_init_context((glite_gsplugin_Context*)&(pdata->ctx)) ) { - free(pdata); - return ENOMEM; - } - if ( edg_wll_gss_acquire_cred_gsi(NULL, NULL, &pdata->ctx->cred, &subject, &gss_code) ) { - /* XXX: Let user know, that cred. load failed. Somehow... - */ - glite_gsplugin_free_context(pdata->ctx); - return EINVAL; - } - pdprintf(("GSLITE_GSPLUGIN: server running with certificate: %s\n", subject)); - free(subject); - } - - p->id = plugin_id; - p->data = pdata; - p->fdelete = glite_gsplugin_delete; - p->fcopy = glite_gsplugin_copy; - - soap->fconnect = glite_gsplugin_connect; - soap->fclose = glite_gsplugin_close; -#if GSOAP_VERSION >= 20700 - soap->fclosesocket = glite_gsplugin_close; -#endif - soap->faccept = glite_gsplugin_accept; - soap->fsend = glite_gsplugin_send; - soap->frecv = glite_gsplugin_recv; - - - return SOAP_OK; -} - - -char *glite_gsplugin_errdesc(struct soap *soap) -{ - glite_gsplugin_Context ctx; - - ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx; - if ( ctx ) return ctx->error_msg; - - return NULL; -} - - - -static int -glite_gsplugin_copy(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src) -{ - pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_copy()\n")); - /* Should be the copy code here? - */ - return ENOSYS; -} - -static void -glite_gsplugin_delete(struct soap *soap, struct soap_plugin *p) -{ - int_plugin_data_t *d = (int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id); - - pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_delete()\n")); - if ( d->def ) { - OM_uint32 ms; - - glite_gsplugin_close(soap); - if (d->ctx->cred != GSS_C_NO_CREDENTIAL) gss_release_cred(&ms, &d->ctx->cred); - free(d->ctx->error_msg); - } - free(d); -} - - -static int -glite_gsplugin_connect( - struct soap *soap, - const char *endpoint, - const char *host, - int port) -{ - glite_gsplugin_Context ctx; - edg_wll_GssStatus gss_stat; - int ret; - - - pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_connect()\n")); -#if defined(CHECK_GSOAP_VERSION) && GSOAP_VERSION <= 20700 - if ( GSOAP_VERSION < 20700 - || (GSOAP_VERSION == 20700 - && (strlen(GSOAP_MIN_VERSION) < 1 || GSOAP_MIN_VERSION[1] < 'e')) ) { - fprintf(stderr, "Client connect will work only with gSOAP v2.7.0e and later"); - return ENOSYS; - } -#endif - - ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx; - - if ( ctx->cred == GSS_C_NO_CREDENTIAL ) { - pdprintf(("GSLITE_GSPLUGIN: loading credentials\n")); - ret = edg_wll_gss_acquire_cred_gsi(ctx->cert_filename, ctx->key_filename, - &ctx->cred, NULL, &gss_stat); - if ( ret ) { - edg_wll_gss_get_error(&gss_stat, "failed to load GSI credentials", - &ctx->error_msg); - goto err; - } - } - - if ( !(ctx->connection = malloc(sizeof(*ctx->connection))) ) return errno; - ret = edg_wll_gss_connect(ctx->cred, - host, port, - ctx->timeout, - ctx->connection, &gss_stat); - if ( ret ) { - edg_wll_gss_get_error(&gss_stat, "edg_wll_gss_connect()", &ctx->error_msg); - goto err; - } - - -err: - pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_connect() error!\n")); - switch ( ret ) { - case EDG_WLL_GSS_ERROR_HERRNO: - case EDG_WLL_GSS_ERROR_ERRNO: return errno; - case EDG_WLL_GSS_ERROR_EOF: return ECONNREFUSED; - case EDG_WLL_GSS_ERROR_TIMEOUT: return ETIMEDOUT; - } - - return ret; -} - -/** It is called in soap_closesocket() - * - * return like errno value - */ -static int -glite_gsplugin_close(struct soap *soap) -{ - glite_gsplugin_Context ctx; - int ret = SOAP_OK; - - - pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_close()\n")); - ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx; - if ( ctx->connection ) { - if ( ctx->connection->context != GSS_C_NO_CONTEXT) { - pdprintf(("GSLITE_GSPLUGIN: closing gss connection\n")); - ret = edg_wll_gss_close(ctx->connection, ctx->timeout); - } - ctx->connection->context = GSS_C_NO_CONTEXT; - } - - return ret; -} - - -static int -glite_gsplugin_accept(struct soap *soap, int s, struct sockaddr *a, int *n) -{ - glite_gsplugin_Context ctx; - edg_wll_GssStatus gss_code; - int conn; - - - pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_accept()\n")); - ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx; - if ( (conn = accept(s, (struct sockaddr *)&a, n)) < 0 ) return conn; - if ( !ctx->connection - && !(ctx->connection = malloc(sizeof(*ctx->connection))) ) return -1; - if ( edg_wll_gss_accept(ctx->cred, conn, ctx->timeout, ctx->connection, &gss_code)) { - pdprintf(("GSLITE_GSPLUGIN: Client authentication failed, closing.\n")); - edg_wll_gss_get_error(&gss_code, "Client authentication failed", &ctx->error_msg); - return -1; - } - - return conn; -} - -static size_t -glite_gsplugin_recv(struct soap *soap, char *buf, size_t bufsz) -{ - glite_gsplugin_Context ctx; - edg_wll_GssStatus gss_code; - int len; - - - pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_recv()\n")); - ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx; - if ( ctx->error_msg ) { free(ctx->error_msg); ctx->error_msg = NULL; } - - if ( ctx->connection->context == GSS_C_NO_CONTEXT ) { - soap->errnum = ENOTCONN; - /* XXX: glite_gsplugin_send() returns SOAP_EOF on errors - */ - return 0; - } - - len = edg_wll_gss_read(ctx->connection, buf, bufsz, - ctx->timeout, - &gss_code); - - switch ( len ) { - case EDG_WLL_GSS_OK: - break; - - case EDG_WLL_GSS_ERROR_GSS: - edg_wll_gss_get_error(&gss_code, "receving WS request", - &ctx->error_msg); - soap->errnum = ENOTCONN; - return 0; - - case EDG_WLL_GSS_ERROR_ERRNO: - ctx->error_msg = strdup("edg_wll_gss_read()"); - soap->errnum = errno; - return 0; - - case EDG_WLL_GSS_ERROR_TIMEOUT: - soap->errnum = ETIMEDOUT; - return 0; - - case EDG_WLL_GSS_ERROR_EOF: - soap->errnum = ENOTCONN; - return 0; - - /* default: fallthrough */ - } - - return len; -} - -static int -glite_gsplugin_send(struct soap *soap, const char *buf, size_t bufsz) -{ - glite_gsplugin_Context ctx; - edg_wll_GssStatus gss_code; - struct sigaction sa, osa; - size_t total = 0; - int ret; - - - pdprintf(("GSLITE_GSPLUGIN: glite_gsplugin_send()\n")); - ctx = ((int_plugin_data_t *)soap_lookup_plugin(soap, plugin_id))->ctx; - /* XXX: check whether ctx is initialized - * i.e. ctx->connection != NULL - */ - if ( ctx->error_msg ) { free(ctx->error_msg); ctx->error_msg = NULL; } - if ( ctx->connection->context == GSS_C_NO_CONTEXT ) { - soap->errnum = ENOTCONN; - return SOAP_EOF; - } - - memset(&sa, 0, sizeof(sa)); - assert(sa.sa_handler == NULL); - sa.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &sa, &osa); - - ret = edg_wll_gss_write_full(ctx->connection, - (void*)buf, bufsz, ctx->timeout, &total, &gss_code); - - sigaction(SIGPIPE, &osa, NULL); - - switch ( ret ) { - case EDG_WLL_GSS_OK: - break; - - case EDG_WLL_GSS_ERROR_TIMEOUT: - ctx->error_msg = strdup("glite_gsplugin_send()"); - soap->errnum = ETIMEDOUT; - return SOAP_EOF; - - case EDG_WLL_GSS_ERROR_ERRNO: - if ( errno == EPIPE ) { - ctx->error_msg = strdup("glite_gsplugin_send()"); - soap->errnum = ENOTCONN; - } - else { - ctx->error_msg = strdup("glite_gsplugin_send()"); - soap->errnum = errno; - } - return SOAP_EOF; - - case EDG_WLL_GSS_ERROR_GSS: - case EDG_WLL_GSS_ERROR_EOF: - default: - ctx->error_msg = strdup("glite_gsplugin_send()"); - soap->errnum = ENOTCONN; - return SOAP_EOF; - } - - return SOAP_OK; -} - diff --git a/org.glite.security.gsoap-plugin/src/glite_gss.c b/org.glite.security.gsoap-plugin/src/glite_gss.c deleted file mode 100644 index 8cb3351..0000000 --- a/org.glite.security.gsoap-plugin/src/glite_gss.c +++ /dev/null @@ -1,998 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "glite_gss.h" - -#define tv_sub(a,b) {\ - (a).tv_usec -= (b).tv_usec;\ - (a).tv_sec -= (b).tv_sec;\ - if ((a).tv_usec < 0) {\ - (a).tv_sec--;\ - (a).tv_usec += 1000000;\ - }\ -} - -struct asyn_result { - struct hostent *ent; - int err; -}; - -static int decrement_timeout(struct timeval *timeout, struct timeval before, struct timeval after) -{ - (*timeout).tv_sec = (*timeout).tv_sec - (after.tv_sec - before.tv_sec); - (*timeout).tv_usec = (*timeout).tv_usec - (after.tv_usec - before.tv_usec); - while ( (*timeout).tv_usec < 0) { - (*timeout).tv_sec--; - (*timeout).tv_usec += 1000000; - } - if ( ((*timeout).tv_sec < 0) || (((*timeout).tv_sec == 0) && ((*timeout).tv_usec == 0)) ) return(1); - else return(0); -} - -/* ares callback handler for ares_gethostbyname() */ -static void callback_handler(void *arg, int status, struct hostent *h) { - struct asyn_result *arp = (struct asyn_result *) arg; - - switch (status) { - case ARES_SUCCESS: - if (h && h->h_addr_list[0]) { - arp->ent->h_addr_list = - (char **) malloc(2 * sizeof(char *)); - if (arp->ent->h_addr_list == NULL) { - arp->err = NETDB_INTERNAL; - break; - } - arp->ent->h_addr_list[0] = - malloc(sizeof(struct in_addr)); - if (arp->ent->h_addr_list[0] == NULL) { - free(arp->ent->h_addr_list); - arp->err = NETDB_INTERNAL; - break; - } - memcpy(arp->ent->h_addr_list[0], h->h_addr_list[0], - sizeof(struct in_addr)); - arp->ent->h_addr_list[1] = NULL; - arp->err = NETDB_SUCCESS; - } else { - arp->err = NO_DATA; - } - break; - case ARES_EBADNAME: - case ARES_ENOTFOUND: - arp->err = HOST_NOT_FOUND; - break; - case ARES_ENOTIMP: - arp->err = NO_RECOVERY; - break; - case ARES_ENOMEM: - case ARES_EDESTRUCTION: - default: - arp->err = NETDB_INTERNAL; - break; - } -} - -static void free_hostent(struct hostent *h){ - int i; - - if (h) { - if (h->h_name) free(h->h_name); - if (h->h_aliases) { - for (i=0; h->h_aliases[i]; i++) free(h->h_aliases[i]); - free(h->h_aliases); - } - if (h->h_addr_list) { - for (i=0; h->h_addr_list[i]; i++) free(h->h_addr_list[i]); - free(h->h_addr_list); - } - free(h); - } -} - -static int asyn_gethostbyname(char **addrOut, char const *name, struct timeval *timeout) { - struct asyn_result ar; - ares_channel channel; - int nfds; - fd_set readers, writers; - struct timeval tv, *tvp; - struct timeval start_time,check_time; - -/* start timer */ - gettimeofday(&start_time,0); - -/* ares init */ - if ( ares_init(&channel) != ARES_SUCCESS ) return(NETDB_INTERNAL); - ar.ent = (struct hostent *) calloc (sizeof(*ar.ent),1); - -/* query DNS server asynchronously */ - ares_gethostbyname(channel, name, AF_INET, callback_handler, - (void *) &ar); - -/* wait for result */ - while (1) { - FD_ZERO(&readers); - FD_ZERO(&writers); - nfds = ares_fds(channel, &readers, &writers); - if (nfds == 0) - break; - - gettimeofday(&check_time,0); - if (decrement_timeout(timeout, start_time, check_time)) { - ares_destroy(channel); - free_hostent(ar.ent); - return(TRY_AGAIN); - } - start_time = check_time; - - tvp = ares_timeout(channel, timeout, &tv); - - switch ( select(nfds, &readers, &writers, NULL, tvp) ) { - case -1: if (errno != EINTR) { - ares_destroy(channel); - free_hostent(ar.ent); - return NETDB_INTERNAL; - } else - continue; - case 0: - FD_ZERO(&readers); - FD_ZERO(&writers); - /* fallthrough */ - default: ares_process(channel, &readers, &writers); - } - } - - ares_destroy(channel); - - if (ar.err == NETDB_SUCCESS) { - *addrOut = malloc(sizeof(struct in_addr)); - memcpy(*addrOut,ar.ent->h_addr_list[0], sizeof(struct in_addr)); - free_hostent(ar.ent); - } - return(ar.err); -} - -static int -do_connect(int *s, char const *hostname, int port, struct timeval *timeout) -{ - int sock; - struct timeval before,after,to; - struct sockaddr_in a; - int sock_err; - socklen_t err_len; - char *addr; - int h_errno; - - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) return EDG_WLL_GSS_ERROR_ERRNO; - - if (timeout) { - int flags = fcntl(sock, F_GETFL, 0); - if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) - return EDG_WLL_GSS_ERROR_ERRNO; - gettimeofday(&before,NULL); - } - - if (timeout) { - switch (h_errno = asyn_gethostbyname(&addr, hostname, timeout)) { - case NETDB_SUCCESS: - memset(&a,0,sizeof a); - a.sin_family = AF_INET; - memcpy(&a.sin_addr.s_addr,addr,sizeof a.sin_addr.s_addr); - a.sin_port = htons(port); - free(addr); - break; - case TRY_AGAIN: - close(sock); - return EDG_WLL_GSS_ERROR_TIMEOUT; - case NETDB_INTERNAL: - /* fall through */ - default: - close(sock); - /* h_errno may be thread safe with Linux pthread libs, - * but such an assumption is not portable - */ - errno = h_errno; - return EDG_WLL_GSS_ERROR_HERRNO; - } - } else { - struct hostent *hp; - - hp = gethostbyname(hostname); - if (hp == NULL) { - close(sock); - errno = h_errno; - return EDG_WLL_GSS_ERROR_HERRNO; - } - - memset(&a,0,sizeof a); - a.sin_family = AF_INET; - memcpy(&a.sin_addr.s_addr, hp->h_addr_list[0], sizeof(a.sin_addr.s_addr)); - a.sin_port = htons(port); - } - - if (connect(sock,(struct sockaddr *) &a,sizeof a) < 0) { - if (timeout && errno == EINPROGRESS) { - fd_set fds; - FD_ZERO(&fds); - FD_SET(sock,&fds); - memcpy(&to,timeout,sizeof to); - gettimeofday(&before,NULL); - switch (select(sock+1,NULL,&fds,NULL,&to)) { - case -1: close(sock); - return EDG_WLL_GSS_ERROR_ERRNO; - case 0: close(sock); - return EDG_WLL_GSS_ERROR_TIMEOUT; - } - gettimeofday(&after,NULL); - tv_sub(after,before); - tv_sub(*timeout,after); - - err_len = sizeof sock_err; - if (getsockopt(sock,SOL_SOCKET,SO_ERROR,&sock_err,&err_len)) { - close(sock); - return EDG_WLL_GSS_ERROR_ERRNO; - } - if (sock_err) { - close(sock); - errno = sock_err; - return EDG_WLL_GSS_ERROR_ERRNO; - } - } - else { - close(sock); - return EDG_WLL_GSS_ERROR_ERRNO; - } - } - - *s = sock; - return 0; -} - -static int -send_token(int sock, void *token, size_t token_length, struct timeval *to) -{ - size_t num_written = 0; - ssize_t count; - fd_set fds; - struct timeval timeout,before,after; - int ret; - - if (to) { - memcpy(&timeout,to,sizeof(timeout)); - gettimeofday(&before,NULL); - } - - - ret = 0; - while(num_written < token_length) { - FD_ZERO(&fds); - FD_SET(sock,&fds); - switch (select(sock+1, NULL, &fds, NULL, to ? &timeout : NULL)) { - case 0: ret = EDG_WLL_GSS_ERROR_TIMEOUT; - goto end; - break; - case -1: ret = EDG_WLL_GSS_ERROR_ERRNO; - goto end; - break; - } - - count = write(sock, ((char *)token) + num_written, - token_length - num_written); - if(count < 0) { - if(errno == EINTR) - continue; - else { - ret = EDG_WLL_GSS_ERROR_ERRNO; - goto end; - } - } - num_written += count; - } - -end: - if (to) { - gettimeofday(&after,NULL); - tv_sub(after,before); - tv_sub(*to,after); - if (to->tv_sec < 0) { - to->tv_sec = 0; - to->tv_usec = 0; - } - } - - return ret; -} - -static int -recv_token(int sock, void **token, size_t *token_length, struct timeval *to) -{ - ssize_t count; - char buf[4098]; - char *t = NULL; - char *tmp; - size_t tl = 0; - fd_set fds; - struct timeval timeout,before,after; - int ret; - - if (to) { - memcpy(&timeout,to,sizeof(timeout)); - gettimeofday(&before,NULL); - } - - ret = 0; - do { - FD_ZERO(&fds); - FD_SET(sock,&fds); - switch (select(sock+1, &fds, NULL, NULL, to ? &timeout : NULL)) { - case 0: - ret = EDG_WLL_GSS_ERROR_TIMEOUT; - goto end; - break; - case -1: - ret = EDG_WLL_GSS_ERROR_ERRNO; - goto end; - break; - } - - count = read(sock, buf, sizeof(buf)); - if (count < 0) { - if (errno == EINTR) - continue; - else { - ret = EDG_WLL_GSS_ERROR_ERRNO; - goto end; - } - } - if (count == 0 && tl == 0 && errno == 0) - return EDG_WLL_GSS_ERROR_EOF; - tmp=realloc(t, tl + count); - if (tmp == NULL) { - errno = ENOMEM; - return EDG_WLL_GSS_ERROR_ERRNO; - } - t = tmp; - memcpy(t + tl, buf, count); - tl += count; - } while (count == sizeof(buf)); - -end: - if (to) { - gettimeofday(&after,NULL); - tv_sub(after,before); - tv_sub(*to,after); - if (to->tv_sec < 0) { - to->tv_sec = 0; - to->tv_usec = 0; - } - } - - if (ret == 0) { - *token = t; - *token_length = tl; - } else - free(t); - - return ret; -} - -static int -create_proxy(char *cert_file, char *key_file, char **proxy_file) -{ - char buf[4096]; - int in, out; - char *name = NULL; - int ret, len; - - *proxy_file = NULL; - - asprintf(&name, "%s/%d.lb.XXXXXX", P_tmpdir, getpid()); - - out = mkstemp(name); - if (out < 0) - return EDG_WLL_GSS_ERROR_ERRNO; - - in = open(cert_file, O_RDONLY); - if (in < 0) { - ret = EDG_WLL_GSS_ERROR_ERRNO; - goto end; - } - while ((ret = read(in, buf, sizeof(buf))) > 0) { - len = write(out, buf, ret); - if (len != ret) { - ret = -1; - break; - } - } - close(in); - if (ret < 0) { - ret = EDG_WLL_GSS_ERROR_ERRNO; - goto end; - } - - in = open(key_file, O_RDONLY); - if (in < 0) { - ret = EDG_WLL_GSS_ERROR_ERRNO; - goto end; - } - while ((ret = read(in, buf, sizeof(buf))) > 0) { - len = write(out, buf, ret); - if (len != ret) { - ret = -1; - break; - } - } - close(in); - if (ret < 0) { - ret = EDG_WLL_GSS_ERROR_ERRNO; - goto end; - } - - ret = 0; - *proxy_file = name; - -end: - close(out); - if (ret) { - unlink(name); - free(name); - } - - return ret; -} - -static int -destroy_proxy(char *proxy_file) -{ - /* XXX we should erase the contents safely (i.e. overwrite with 0's) */ - unlink(proxy_file); - return 0; -} - -int -edg_wll_gss_acquire_cred_gsi(char *cert_file, char *key_file, gss_cred_id_t *cred, - char **name, edg_wll_GssStatus* gss_code) -{ - OM_uint32 major_status = 0, minor_status, minor_status2; - gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL; - gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER; - gss_name_t gss_name = GSS_C_NO_NAME; - OM_uint32 lifetime; - char *proxy_file = NULL; - int ret; - - if ((cert_file == NULL && key_file != NULL) || - (cert_file != NULL && key_file == NULL)) - return EINVAL; - - if (cert_file == NULL) { - major_status = gss_acquire_cred(&minor_status, GSS_C_NO_NAME, 0, - GSS_C_NO_OID_SET, GSS_C_BOTH, - &gss_cred, NULL, NULL); - if (GSS_ERROR(major_status)) { - ret = EDG_WLL_GSS_ERROR_GSS; - goto end; - } - } else { - proxy_file = cert_file; - if (strcmp(cert_file, key_file) != 0 && - (ret = create_proxy(cert_file, key_file, &proxy_file))) { - proxy_file = NULL; - goto end; - } - - asprintf((char**)&buffer.value, "X509_USER_PROXY=%s", proxy_file); - if (buffer.value == NULL) { - errno = ENOMEM; - ret = EDG_WLL_GSS_ERROR_ERRNO; - goto end; - } - buffer.length = strlen(proxy_file); - - major_status = gss_import_cred(&minor_status, &gss_cred, GSS_C_NO_OID, 1, - &buffer, 0, NULL); - free(buffer.value); - if (GSS_ERROR(major_status)) { - ret = EDG_WLL_GSS_ERROR_GSS; - goto end; - } - } - - /* gss_import_cred() doesn't check validity of credential loaded, so let's - * verify it now */ - major_status = gss_inquire_cred(&minor_status, gss_cred, &gss_name, - &lifetime, NULL, NULL); - if (GSS_ERROR(major_status)) { - ret = EDG_WLL_GSS_ERROR_GSS; - goto end; - } - - /* Must cast to time_t since OM_uint32 is unsinged and hence we couldn't - * detect negative values. */ - if ((time_t) lifetime <= 0) { - major_status = GSS_S_CREDENTIALS_EXPIRED; - minor_status = 0; /* XXX */ - ret = EDG_WLL_GSS_ERROR_GSS; - goto end; - } - - if (name) { - major_status = gss_display_name(&minor_status, gss_name, &buffer, NULL); - if (GSS_ERROR(major_status)) { - ret = EDG_WLL_GSS_ERROR_GSS; - goto end; - } - *name = buffer.value; - memset(&buffer, 0, sizeof(buffer)); - } - - *cred = gss_cred; - gss_cred = GSS_C_NO_CREDENTIAL; - ret = 0; - -end: - if (cert_file && key_file && proxy_file && strcmp(cert_file, key_file) != 0) { - destroy_proxy(proxy_file); - free(proxy_file); - } - - if (gss_name != GSS_C_NO_NAME) - gss_release_name(&minor_status2, &gss_name); - - if (gss_cred != GSS_C_NO_CREDENTIAL) - gss_release_cred(&minor_status2, &gss_cred); - - if (GSS_ERROR(major_status)) { - if (gss_code) { - gss_code->major_status = major_status; - gss_code->minor_status = minor_status; - } - ret = EDG_WLL_GSS_ERROR_GSS; - } - - return ret; -} - -int -edg_wll_gss_connect(gss_cred_id_t cred, char const *hostname, int port, - struct timeval *timeout, edg_wll_GssConnection *connection, - edg_wll_GssStatus* gss_code) -{ - int sock, ret; - OM_uint32 maj_stat, min_stat, min_stat2, req_flags; - int context_established = 0; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - gss_name_t server = GSS_C_NO_NAME; - gss_ctx_id_t context = GSS_C_NO_CONTEXT; - char *servername = NULL; - - maj_stat = min_stat = min_stat2 = req_flags = 0; - - /* GSI specific */ - req_flags = GSS_C_GLOBUS_SSL_COMPATIBLE; - - ret = do_connect(&sock, hostname, port, timeout); - if (ret) - return ret; - - /* XXX find appropriate fqdn */ - asprintf (&servername, "host@%s", hostname); - if (servername == NULL) { - errno = ENOMEM; - ret = EDG_WLL_GSS_ERROR_ERRNO; - goto end; - } - input_token.value = servername; - input_token.length = strlen(servername) + 1; - - maj_stat = gss_import_name(&min_stat, &input_token, - GSS_C_NT_HOSTBASED_SERVICE, &server); - if (GSS_ERROR(maj_stat)) { - ret = EDG_WLL_GSS_ERROR_GSS; - goto end; - } - - free(servername); - memset(&input_token, 0, sizeof(input_token)); - - /* XXX if cred == GSS_C_NO_CREDENTIAL set the ANONYMOUS flag */ - - /* XXX prepsat na do {} while (maj_stat == CONT) a osetrit chyby*/ - while (!context_established) { - /* XXX verify ret_flags match what was requested */ - maj_stat = gss_init_sec_context(&min_stat, cred, &context, - GSS_C_NO_NAME, GSS_C_NO_OID, - req_flags | GSS_C_MUTUAL_FLAG, - 0, GSS_C_NO_CHANNEL_BINDINGS, - &input_token, NULL, &output_token, - NULL, NULL); - if (input_token.length > 0) { - free(input_token.value); - input_token.length = 0; - } - - if (output_token.length != 0) { - ret = send_token(sock, output_token.value, output_token.length, timeout); - gss_release_buffer(&min_stat2, &output_token); - if (ret) - goto end; - } - - if (GSS_ERROR(maj_stat)) { - if (context != GSS_C_NO_CONTEXT) { - /* XXX send closing token to the friend */ - gss_delete_sec_context(&min_stat2, &context, GSS_C_NO_BUFFER); - context = GSS_C_NO_CONTEXT; - } - ret = EDG_WLL_GSS_ERROR_GSS; - goto end; - } - - if(maj_stat & GSS_S_CONTINUE_NEEDED) { - ret = recv_token(sock, &input_token.value, &input_token.length, timeout); - if (ret) - goto end; - } else - context_established = 1; - } - - /* XXX check ret_flags matches to what was requested */ - - memset(connection, 0, sizeof(*connection)); - connection->sock = sock; - connection->context = context; - servername = NULL; - ret = 0; - -end: - if (ret == EDG_WLL_GSS_ERROR_GSS && gss_code) { - gss_code->major_status = maj_stat; - gss_code->minor_status = min_stat; - } - if (server != GSS_C_NO_NAME) - gss_release_name(&min_stat2, &server); - if (servername == NULL) - free(servername); - if (ret) - close(sock); - - return ret; -} - -int -edg_wll_gss_accept(gss_cred_id_t cred, int sock, struct timeval *timeout, - edg_wll_GssConnection *connection, edg_wll_GssStatus* gss_code) -{ - OM_uint32 maj_stat, min_stat, min_stat2; - OM_uint32 ret_flags = 0; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - gss_name_t client_name = GSS_C_NO_NAME; - gss_ctx_id_t context = GSS_C_NO_CONTEXT; - int ret; - - maj_stat = min_stat = min_stat2 = 0; - - /* GSI specific */ - ret_flags = GSS_C_GLOBUS_SSL_COMPATIBLE; - - do { - ret = recv_token(sock, &input_token.value, &input_token.length, timeout); - if (ret) - goto end; - - maj_stat = gss_accept_sec_context(&min_stat, &context, - cred, &input_token, - GSS_C_NO_CHANNEL_BINDINGS, - &client_name, NULL, &output_token, - &ret_flags, NULL, NULL); - if (input_token.length > 0) { - free(input_token.value); - input_token.length = 0; - } - - if (output_token.length) { - ret = send_token(sock, output_token.value, output_token.length, timeout); - gss_release_buffer(&min_stat2, &output_token); - if (ret) - goto end; - } - } while(maj_stat & GSS_S_CONTINUE_NEEDED); - - if (GSS_ERROR(maj_stat)) { - if (context != GSS_C_NO_CONTEXT) { - /* XXX send closing token to the friend */ - gss_delete_sec_context(&min_stat2, &context, GSS_C_NO_BUFFER); - context = GSS_C_NO_CONTEXT; - } - ret = EDG_WLL_GSS_ERROR_GSS; - goto end; - } - - maj_stat = gss_display_name(&min_stat, client_name, &output_token, NULL); - if (GSS_ERROR(maj_stat)) { - /* XXX close context ??? */ - ret = EDG_WLL_GSS_ERROR_GSS; - goto end; - } - - memset(connection, 0, sizeof(*connection)); - connection->sock = sock; - connection->context = context; - memset(&output_token, 0, sizeof(output_token.value)); - ret = 0; - -end: - if (ret == EDG_WLL_GSS_ERROR_GSS && gss_code) { - gss_code->major_status = maj_stat; - gss_code->minor_status = min_stat; - } - if (client_name != GSS_C_NO_NAME) - gss_release_name(&min_stat2, &client_name); - - return ret; -} - -int -edg_wll_gss_write(edg_wll_GssConnection *connection, const void *buf, size_t bufsize, - struct timeval *timeout, edg_wll_GssStatus* gss_code) -{ - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token; - gss_buffer_desc output_token; - int ret; - - input_token.value = (void*)buf; - input_token.length = bufsize; - - maj_stat = gss_wrap (&min_stat, connection->context, 1, GSS_C_QOP_DEFAULT, - &input_token, NULL, &output_token); - if (GSS_ERROR(maj_stat)) { - if (gss_code) { - gss_code->minor_status = min_stat; - gss_code->major_status = maj_stat; - } - - return EDG_WLL_GSS_ERROR_GSS; - } - - ret = send_token(connection->sock, output_token.value, output_token.length, - timeout); - gss_release_buffer(&min_stat, &output_token); - - return ret; -} - - -int -edg_wll_gss_read(edg_wll_GssConnection *connection, void *buf, size_t bufsize, - struct timeval *timeout, edg_wll_GssStatus* gss_code) -{ - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token; - gss_buffer_desc output_token; - int ret, i; - - if (connection->bufsize > 0) { - size_t len; - - len = (connection->bufsize < bufsize) ? connection->bufsize : bufsize; - memcpy(buf, connection->buffer, len); - if (connection->bufsize - len == 0) { - free(connection->buffer); - connection->buffer = NULL; - } else { - for (i = 0; i < connection->bufsize - len; i++) - connection->buffer[i] = connection->buffer[i+len]; - } - connection->bufsize -= len; - - return len; - } - - do { - ret = recv_token(connection->sock, &input_token.value, &input_token.length, - timeout); - if (ret) - /* XXX cleanup */ - return ret; - - maj_stat = gss_unwrap(&min_stat, connection->context, &input_token, - &output_token, NULL, NULL); - gss_release_buffer(&min_stat, &input_token); - if (GSS_ERROR(maj_stat)) { - /* XXX cleanup */ - return EDG_WLL_GSS_ERROR_GSS; - } - } while (maj_stat == 0 && output_token.length == 0 && output_token.value == NULL); - - if (output_token.length > bufsize) { - connection->bufsize = output_token.length - bufsize; - connection->buffer = malloc(connection->bufsize); - if (connection->buffer == NULL) { - connection->bufsize = 0; - ret = EDG_WLL_GSS_ERROR_ERRNO; - goto end; - } - memcpy(connection->buffer, output_token.value + bufsize, connection->bufsize); - output_token.length = bufsize; - } - - memcpy(buf, output_token.value, output_token.length); - ret = output_token.length; - -end: - gss_release_buffer(&min_stat, &output_token); - - return ret; -} - -int -edg_wll_gss_read_full(edg_wll_GssConnection *connection, void *buf, - size_t bufsize, struct timeval *timeout, size_t *total, - edg_wll_GssStatus* gss_code) -{ - int len,i; - *total = 0; - - if (connection->bufsize > 0) { - size_t len; - - len = (connection->bufsize < bufsize) ? connection->bufsize : bufsize; - memcpy(buf, connection->buffer, len); - if (connection->bufsize - len == 0) { - free(connection->buffer); - connection->buffer = NULL; - } else { - for (i = 0; i < connection->bufsize - len; i++) - connection->buffer[i] = connection->buffer[i+len]; - } - connection->bufsize -= len; - *total = len; - } - - while (*total < bufsize) { - len = edg_wll_gss_read(connection, buf+*total, bufsize-*total, - timeout, gss_code); - if (len < 0) return len; - *total += len; - } - - return 0; -} - -int -edg_wll_gss_write_full(edg_wll_GssConnection *connection, const void *buf, - size_t bufsize, struct timeval *timeout, size_t *total, - edg_wll_GssStatus* gss_code) -{ - return edg_wll_gss_write(connection, buf, bufsize, timeout, gss_code); -} - -/* XXX: I'm afraid the contents of stuct stat is somewhat OS dependent */ -int -edg_wll_gss_watch_creds(const char *proxy_file, time_t *proxy_mtime) -{ - struct stat pstat; - int reload = 0; - - if (!proxy_file) return 0; - if (stat(proxy_file,&pstat)) return -1; - - if (!*proxy_mtime) *proxy_mtime = pstat.st_mtime; - - if (*proxy_mtime != pstat.st_mtime) { - *proxy_mtime = pstat.st_mtime; - reload = 1; - } - - return reload; -} - -int -edg_wll_gss_close(edg_wll_GssConnection *con, struct timeval *timeout) -{ - OM_uint32 min_stat; - - /* XXX if timeout is NULL use value of 120 secs */ - - if (con->context != GSS_C_NO_CONTEXT) { - gss_delete_sec_context(&min_stat, &con->context, GSS_C_NO_BUFFER); - /* XXX send the buffer (if any) to the peer. GSSAPI specs doesn't - * recommend sending it, though */ - - /* XXX can socket be open even if context == GSS_C_NO_CONTEXT) ? */ - /* XXX ensure that edg_wll_GssConnection is created with sock set to -1 */ - if (con->sock >= 0) - close(con->sock); - } - if (con->buffer) - free(con->buffer); - memset(con, 0, sizeof(*con)); - con->context = GSS_C_NO_CONTEXT; - con->sock = -1; - return 0; -} - -int -edg_wll_gss_get_error(edg_wll_GssStatus *gss_err, const char *prefix, char **msg) -{ - OM_uint32 maj_stat, min_stat; - OM_uint32 msg_ctx = 0; - gss_buffer_desc maj_status_string = GSS_C_EMPTY_BUFFER; - gss_buffer_desc min_status_string = GSS_C_EMPTY_BUFFER; - char *str = NULL; - char *line, *tmp; - - str = strdup(prefix); - do { - maj_stat = gss_display_status(&min_stat, gss_err->major_status, - GSS_C_GSS_CODE, GSS_C_NO_OID, - &msg_ctx, &maj_status_string); - if (GSS_ERROR(maj_stat)) - break; - - maj_stat = gss_display_status(&min_stat, gss_err->minor_status, - GSS_C_MECH_CODE, GSS_C_NULL_OID, - &msg_ctx, &min_status_string); - if (GSS_ERROR(maj_stat)) { - gss_release_buffer(&min_stat, &maj_status_string); - break; - } - - asprintf(&line, ": %s (%s)", (char *)maj_status_string.value, - (char *)min_status_string.value); - gss_release_buffer(&min_stat, &maj_status_string); - gss_release_buffer(&min_stat, &min_status_string); - - tmp = realloc(str, strlen(str) + strlen(line) + 1); - if (tmp == NULL) { - /* abort() ? */ - free(line); - free(str); - str = "WARNING: Not enough memory to produce error message"; - break; - } - str = tmp; - strcat(str, line); - free(line); - } while (!GSS_ERROR(maj_stat) && msg_ctx != 0); - - *msg = str; - return 0; -} - -int -edg_wll_gss_oid_equal(const gss_OID a, const gss_OID b) -{ - if (a == b) - return 1; - else { - if (a == GSS_C_NO_OID || b == GSS_C_NO_OID || a->length != b->length) - return 0; - else - return (memcmp(a->elements, b->elements, a->length) == 0); - } -} - -int -edg_wll_gss_reject(int sock) -{ - /* XXX is it possible to cut & paste edg_wll_ssl_reject() ? */ - return 0; -} diff --git a/org.glite.security.gsoap-plugin/test/test_gss.cpp b/org.glite.security.gsoap-plugin/test/test_gss.cpp deleted file mode 100644 index 083b71a..0000000 --- a/org.glite.security.gsoap-plugin/test/test_gss.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include -#include - - -#include -#include -#include -#include - - -#include "glite_gss.h" - -class GSSTest: public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(GSSTest); - CPPUNIT_TEST(echo); - CPPUNIT_TEST(errorTest); - CPPUNIT_TEST_SUITE_END(); - -public: - void echo(); - void errorTest(); - - void setUp(); - -private: - gss_cred_id_t my_cred; - char * my_subject; - int sock, port; - struct timeval timeout; - - void replier(); - -}; - - -void GSSTest::replier() { - edg_wll_GssConnection conn; - edg_wll_GssStatus stat; - struct sockaddr_in a; - socklen_t alen = sizeof(a); - int s, len; - char buf[100]; - - - if ( (s = accept(sock, (struct sockaddr *) &a, &alen)) < 0 ) exit(1); - - if ( edg_wll_gss_accept(my_cred, s, &timeout, &conn, &stat) ) exit(1); - - while ( (len = edg_wll_gss_read(&conn, buf, sizeof(buf), &timeout, &stat)) >= 0 ) { - if ( edg_wll_gss_write(&conn, buf, len, &timeout, &stat) ) exit(1); - } - - exit(0); -} - - -void GSSTest::setUp(void) { - pid_t pid; - edg_wll_GssStatus stat; - struct sockaddr_in a; - socklen_t alen = sizeof(a); - char * cred_file = NULL; - char * key_file = NULL; - - timeout.tv_sec = 10; - timeout.tv_usec = 0; - - key_file = cred_file = getenv("X509_USER_PROXY"); - CPPUNIT_ASSERT_MESSAGE("credential file", cred_file); - - if (edg_wll_gss_acquire_cred_gsi(cred_file, key_file, &my_cred, &my_subject, &stat)) - CPPUNIT_ASSERT_MESSAGE("gss_acquire_cred", 0); - - sock = socket(PF_INET,SOCK_STREAM,0); - CPPUNIT_ASSERT_MESSAGE("socket()", sock >= 0); - - a.sin_family = AF_INET; - a.sin_port = 0; - a.sin_addr.s_addr = INADDR_ANY; - - if (bind(sock,(struct sockaddr *) &a,sizeof(a))) { - CPPUNIT_ASSERT_MESSAGE("bind()", 0); - } - - if (listen(sock,1)) { - CPPUNIT_ASSERT_MESSAGE("listen()", 0); - } - - getsockname(sock,(struct sockaddr *) &a,&alen); - port = ntohs(a.sin_port); - - if ( !(pid = fork()) ) replier(); - else close(sock); -} - - - -void GSSTest::echo() -{ - edg_wll_GssConnection conn; - edg_wll_GssStatus stat; - size_t total; - int err; - char buf[] = "f843fejwfanczn nc4*&686%$$&^(*)*#$@WSH"; - char buf2[100]; - - - err = edg_wll_gss_connect(my_cred, "localhost", port, &timeout, &conn, &stat); - CPPUNIT_ASSERT_MESSAGE("edg_wll_gss_connect()", !err); - - err = edg_wll_gss_write(&conn, buf, strlen(buf)+1, &timeout, &stat); - CPPUNIT_ASSERT_MESSAGE("edg_wll_gss_write()", !err); - - err = edg_wll_gss_read_full(&conn, buf2, strlen(buf)+1, &timeout, &total, &stat); - CPPUNIT_ASSERT_MESSAGE("edg_wll_gss_read_full()", !err); - - CPPUNIT_ASSERT(strlen(buf)+1 == total && !strcmp(buf,buf2) ); - - edg_wll_gss_close(&conn, &timeout); - -} - - -void GSSTest::errorTest() -{ - edg_wll_GssConnection conn; - edg_wll_GssStatus stat; - int err; - char * msg = NULL; - - - err = edg_wll_gss_connect(my_cred, "xxx.porno.net", port, &timeout, &conn, &stat); - if (err) edg_wll_gss_get_error(&stat, "gss_connect()", &msg); - CPPUNIT_ASSERT_MESSAGE("edg_wll_gss_get_error()", msg); -} - - -CPPUNIT_TEST_SUITE_REGISTRATION( GSSTest ); - -int main (int ac,const char *av[]) -{ - CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); - CppUnit::TextUi::TestRunner runner; - - runner.addTest(suite); - return runner.run() ? 0 : 1; -} diff --git a/org.glite.security.proxyrenewal/.cvsignore b/org.glite.security.proxyrenewal/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.security.proxyrenewal/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.security.proxyrenewal/LICENSE b/org.glite.security.proxyrenewal/LICENSE deleted file mode 100644 index 01b973b..0000000 --- a/org.glite.security.proxyrenewal/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -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 -. - -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/ - - diff --git a/org.glite.security.proxyrenewal/Makefile b/org.glite.security.proxyrenewal/Makefile deleted file mode 100644 index 3730746..0000000 --- a/org.glite.security.proxyrenewal/Makefile +++ /dev/null @@ -1,141 +0,0 @@ -# -# 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 -# -# Top Makefile file for the GLite Security Proxyrenewal module -# -# Authors: Ales Krenek -# Version info: $Id$ -# Release: $Name$ -# -# Revision history: -# $Log -# - -# defaults -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -lbprefix=lb -package=glite-security-proxyrenewal -version=1.0.0 -PREFIX=/opt/glite - -glite_location=$PREFIX -globus_prefix=/opt/globus -nothrflavour=gcc32 -thrflavour=gcc32pthr -myproxy_prefix=$globus_prefix - --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 - -MYPROXYINC:= -I${myproxy_prefix}/include/${nothrflavour} -MYPROXYTHRINC:= -I${myproxy_prefix}/include/${thrflavour} - -DEBUG:=-g -O0 - -CFLAGS:= ${DEBUG} \ - ${MYPROXYINC} \ - -I${top_srcdir}/src -I${top_srcdir}/interface \ - -I${glite_location}/include - -GLOBUS_LIBS:=-L${globus_prefix}/lib \ - -lglobus_common_${nothrflavour} \ - -lssl_${nothrflavour} - -MYPROXY_LIB:=-L${myproxy_prefix}/lib -lmyproxy_${nothrflavour} - -JOBIDLIB:=-L${glite_location}/lib -lglite_wmsutils_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 voms.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} - - -${THRLIB}: ${THRLIBOBJ} - ${LINK} -o $@ ${THRLIBLOBJ} -rpath ${glite_location}/lib - -${DAEMON}: ${DAEMONOBJ} - ${LINK} -o $@ ${DAEMONOBJ} ${JOBIDLIB} ${MYPROXY_LIB} -lvomsc -lglobus_gss_assist_${nothrflavour} ${GLOBUS_LIBS} - -${CLIENT}: ${CLIENTOBJ} ${LIB} - ${LINK} -o $@ ${CLIENTOBJ} ${LIB} ${GLOBUS_LIBS} - -${THRLIBOBJ}: %.thr.o: %.c - ${COMPILE} ${GLOBUSTHRINC} -o $@ -c $< - -%.o: %.c - ${COMPILE} ${GLOBUSINC} -c $< - -stage: compile - $(MAKE) install PREFIX=${stagedir} - - -check: - echo No unit tests - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir - cd tmpbuilddir && tar -czf ../${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz * - rm -rf tmpbuilddir - -install: - -mkdir -p ${PREFIX}/bin ${PREFIX}/lib ${PREFIX}/include/glite/security/proxyrenewal ${PREFIX}/share/doc/${package}-${version} ${PREFIX}/etc/init.d - ${INSTALL} -m 644 ${LIB} ${THRLIB} ${PREFIX}/lib - ${INSTALL} -m 755 ${DAEMON} ${CLIENT} ${PREFIX}/bin - ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - cd ${top_srcdir}/interface && ${INSTALL} -m 644 renewal.h ${PREFIX}/include/glite/security/proxyrenewal - - ${INSTALL} -m 755 ${top_srcdir}/config/startup ${PREFIX}/etc/init.d/glite-proxy-renewald - - -clean: - $(RM) $(LIB) $(DAEMON) $(CLIENT) *.o core diff --git a/org.glite.security.proxyrenewal/build.xml b/org.glite.security.proxyrenewal/build.xml deleted file mode 100755 index fcced8d..0000000 --- a/org.glite.security.proxyrenewal/build.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.security.proxyrenewal/config/startup b/org.glite.security.proxyrenewal/config/startup deleted file mode 100755 index 26ba757..0000000 --- a/org.glite.security.proxyrenewal/config/startup +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh - -GLITE_LOCATION=${GLITE_LOCATION:-/opt/glite} -GLITE_LOCATION_VAR=${GLITE_LOCATION_VAR:-/opt/glite/var} - -[ -f /etc/glite.conf ] && . /etc/glite.conf -[ -f $GLITE_LOCATION/etc/glite-wms.conf ] && . $GLITE_LOCATION/etc/glite-wms.conf -[ -f $HOME/.glite.conf ] && . $HOME/.glite.conf - -PROXY_REPOSITORY="$GLITE_LOCATION_VAR/spool/glite-renewd" - -unset creds - -start() -{ - if test -z "$GLITE_USER" ;then - echo 'Error: GLITE_USER is not set' - echo FAILED - return 1 - fi - - [ -n "$GLITE_HOST_CERT" -a -n "$GLITE_HOST_KEY" ] && - creds="-t $GLITE_HOST_CERT -k $GLITE_HOST_KEY" - - if test -z "$creds"; then - if su - $GLITE_USER -c "test -r /etc/grid-security/hostkey.pem -a -r /etc/grid-security/hostcert.pem"; then - echo "$0: WARNING: /etc/grid-security/hostkey.pem readable by $GLITE_USER" - creds="-t /etc/grid-security/hostcert.pem -k /etc/grid-security/hostkey.pem" - fi - fi - - [ -z "$creds" ] && - echo $0: WARNING: No credentials specified. Using default lookup which is dangerous. >&2 - - # workaround for VOMS_FindByVO that seems to always require user's own VOMS config file (bug #7511) - user_voms_config=$HOME/.glite/vomses - if [ ! -f "$user_voms_config" ]; then - rm -f /tmp/renewal_vomses - su - $GLITE_USER -c "touch /tmp/renewal_vomses && chmod 644 /tmp/renewal_vomses" - user_voms_config=/tmp/renewal_vomses - fi - - echo -n Starting ProxyRenewal Daemon: glite-proxy-renewd ... - - if [ ! -d "$PROXY_REPOSITORY" ]; then - mkdir -p $PROXY_REPOSITORY || exit 1 - chown $GLITE_USER $PROXY_REPOSITORY - chmod 0700 $PROXY_REPOSITORY - fi - - su - $GLITE_USER -c "VOMS_USERCONF=$user_voms_config \ - $GLITE_LOCATION/bin/glite-proxy-renewd \ - -r $PROXY_REPOSITORY $creds -A" && echo " done" -} - -stop() -{ - echo -n "Stopping ProxyRenewal Daemon: glite-proxy-renewd ..." - killall glite-proxy-renewd - echo " done" -} - -status() -{ - if netstat -an --unix | grep "^unix .* LISTEN.* /tmp/dgpr_renew_" >/dev/null 2>&1 ;then - echo glite-proxy-renewd running - else - echo glite-proxy-renewd not running - return 1 - fi -} - -case x$1 in - xstart) start;; - xstop) stop;; - xrestart) stop; start;; - xstatus) status;; - x*) echo usage: $0 start,stop,restart,status >&2 - exit 1;; -esac diff --git a/org.glite.security.proxyrenewal/interface/renewal.h b/org.glite.security.proxyrenewal/interface/renewal.h deleted file mode 100644 index 953ab0e..0000000 --- a/org.glite.security.proxyrenewal/interface/renewal.h +++ /dev/null @@ -1,146 +0,0 @@ -/** - * \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/wmsutils/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_ERROR_TIMEOUT, - EDG_WLPR_ERROR_ERRNO, -} 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 */ diff --git a/org.glite.security.proxyrenewal/project/build.number b/org.glite.security.proxyrenewal/project/build.number deleted file mode 100644 index 1936771..0000000 --- a/org.glite.security.proxyrenewal/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build=137 diff --git a/org.glite.security.proxyrenewal/project/build.properties b/org.glite.security.proxyrenewal/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.security.proxyrenewal/project/configure.properties.xml b/org.glite.security.proxyrenewal/project/configure.properties.xml deleted file mode 100644 index 3d6914b..0000000 --- a/org.glite.security.proxyrenewal/project/configure.properties.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - -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} -myproxy_prefix=${with.myproxy.prefix} - - - diff --git a/org.glite.security.proxyrenewal/project/properties.xml b/org.glite.security.proxyrenewal/project/properties.xml deleted file mode 100755 index f1e51dd..0000000 --- a/org.glite.security.proxyrenewal/project/properties.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.security.proxyrenewal/project/tar_exclude b/org.glite.security.proxyrenewal/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.security.proxyrenewal/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.security.proxyrenewal/project/taskdefs.xml b/org.glite.security.proxyrenewal/project/taskdefs.xml deleted file mode 100755 index 13e894e..0000000 --- a/org.glite.security.proxyrenewal/project/taskdefs.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/org.glite.security.proxyrenewal/project/version.properties b/org.glite.security.proxyrenewal/project/version.properties deleted file mode 100644 index 80cbe6b..0000000 --- a/org.glite.security.proxyrenewal/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.2.2 -module.age=1 diff --git a/org.glite.security.proxyrenewal/src/acstack.h b/org.glite.security.proxyrenewal/src/acstack.h deleted file mode 100755 index a833a31..0000000 --- a/org.glite.security.proxyrenewal/src/acstack.h +++ /dev/null @@ -1,79 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) 2002, 2003 INFN-CNAF on behalf of the EU DataGrid. - * For license conditions see LICENSE file or - * http://www.edg.org/license.html - * - * Parts of this code may be based upon or even include verbatim pieces, - * originally written by other people, in which case the original header - * follows. - * - *********************************************************************/ -#ifndef _ACSTACK_H -#define _ACSTACK_H - -#include -#include -#include - -#define IMPL_STACK(type) \ - DECLARE_STACK_OF(type) \ - STACK_OF(type) *sk_##type##_new (int (*cmp)(const type * const *, const type * const *)) \ - { return sk_new ( (int (*)(const char * const *, const char * const *))cmp);} \ - STACK_OF(type) *sk_##type##_new_null () { return sk_new_null(); } \ - void sk_##type##_free (STACK_OF(type) *st) { sk_free(st); } \ - int sk_##type##_num (const STACK_OF(type) *st) { return sk_num(st); } \ - type *sk_##type##_value (const STACK_OF(type) *st, int i) { return (type *)sk_value(st, i); } \ - type *sk_##type##_set (STACK_OF(type) *st, int i, type *val) { return ((type *)sk_set(st, i, (char *)val)); } \ - void sk_##type##_zero (STACK_OF(type) *st) { sk_zero(st);} \ - int sk_##type##_push (STACK_OF(type) *st, type *val) { return sk_push(st, (char *)val); } \ - int sk_##type##_unshift (STACK_OF(type) *st, type *val) { return sk_unshift(st, (char *)val); } \ - int sk_##type##_find (STACK_OF(type) *st, type *val) { return sk_find(st, (char *)val); } \ - type *sk_##type##_delete (STACK_OF(type) *st, int i) { return (type *)sk_delete(st, i); } \ - type *sk_##type##_delete_ptr (STACK_OF(type) *st, type *ptr) { return (type *)sk_delete_ptr(st, (char *)ptr); } \ - int sk_##type##_insert (STACK_OF(type) *st, type *val, int i) { return sk_insert(st, (char *)val, i); } \ - int (*sk_##type##_set_cmp_func (STACK_OF(type) *st, int (*cmp)(const type * const *, const type * const *)))(const type * const *, const type * const *) \ - { return (int ((*)(const type * const *, const type * const *)))sk_set_cmp_func (st, (int (*)(const char * const *, const char * const *))cmp); } \ - STACK_OF(type) *sk_##type##_dup (STACK_OF(type) *st) { return sk_dup(st); } \ - void sk_##type##_pop_free (STACK_OF(type) *st, void (*func)(type *)) { sk_pop_free(st, (void (*)(void *))func); } \ - type *sk_##type##_shift (STACK_OF(type) *st) { return (type *)sk_shift(st); } \ - type *sk_##type##_pop (STACK_OF(type) *st) { return (type *)sk_pop(st); } \ - void sk_##type##_sort (STACK_OF(type) *st) { sk_sort(st); } \ - STACK_OF(type) *d2i_ASN1_SET_OF_##type (STACK_OF(type) **st, unsigned char **pp, long length, type *(*d2ifunc)(), void (*freefunc)(type *), int ex_tag, int ex_class) \ - { return d2i_ASN1_SET(st, pp, length, (char *(*)())d2ifunc, (void (*)(void *))freefunc, ex_tag, ex_class); } \ - int i2d_ASN1_SET_OF_##type (STACK_OF(type) *st, unsigned char **pp, int (*i2dfunc)(), int ex_tag, int ex_class, int is_set) \ - { return i2d_ASN1_SET(st, pp, i2dfunc, ex_tag, ex_class, is_set); } \ - unsigned char *ASN1_seq_pack_##type (STACK_OF(type) *st, int (*i2d)(), unsigned char **buf, int *len) { return ASN1_seq_pack(st, i2d, buf, len); } \ - STACK_OF(type) *ASN1_seq_unpack_##type (unsigned char *buf, int len, type *(*d2i)(), void (*freefunc)(type *)) \ - { return ASN1_seq_unpack(buf, len, (char *(*)())d2i, (void (*)(void *))freefunc); } - - -#define DECL_STACK(type) \ - DECLARE_STACK_OF(type) \ - extern STACK_OF(type) *sk_##type##_new (int (*)(const type * const *, const type * const *)); \ - extern STACK_OF(type) *sk_##type##_new_null (); \ - extern void sk_##type##_free (STACK_OF(type) *); \ - extern int sk_##type##_num (const STACK_OF(type) *); \ - extern type *sk_##type##_value (const STACK_OF(type) *, int); \ - extern type *sk_##type##_set (STACK_OF(type) *, int, type *); \ - extern void sk_##type##_zero (STACK_OF(type) *); \ - extern int sk_##type##_push (STACK_OF(type) *, type *); \ - extern int sk_##type##_unshift (STACK_OF(type) *, type *); \ - extern int sk_##type##_find (STACK_OF(type) *, type *); \ - extern type *sk_##type##_delete (STACK_OF(type) *, int); \ - extern type *sk_##type##_delete_ptr (STACK_OF(type) *, type *); \ - extern int sk_##type##_insert (STACK_OF(type) *, type *, int); \ - extern int (*sk_##type##_set_cmp_func (STACK_OF(type) *, int (*)(const type * const *, const type * const *)))(const type * const *, const type * const *); \ - extern STACK_OF(type) *sk_##type##_dup (STACK_OF(type) *); \ - extern void sk_##type##_pop_free (STACK_OF(type) *, void (*)(type *)); \ - extern type *sk_##type##_shift (STACK_OF(type) *); \ - extern type *sk_##type##_pop (STACK_OF(type) *); \ - extern void sk_##type##_sort (STACK_OF(type) *); \ - extern STACK_OF(type) *d2i_ASN1_SET_OF_##type (STACK_OF(type) **, unsigned char **, long, type *(*)(), void (*)(type *), int, int); \ - extern int i2d_ASN1_SET_OF_##type (STACK_OF(type) *, unsigned char **, int (*)(), int, int, int); \ - extern unsigned char *ASN1_seq_pack_##type (STACK_OF(type) *, int (*)(), unsigned char **, int *); \ - extern STACK_OF(type) *ASN1_seq_unpack_##type (unsigned char *, int, type *(*)(), void (*)(type *)) ; - -#endif diff --git a/org.glite.security.proxyrenewal/src/api.c b/org.glite.security.proxyrenewal/src/api.c deleted file mode 100644 index 922931b..0000000 --- a/org.glite.security.proxyrenewal/src/api.c +++ /dev/null @@ -1,485 +0,0 @@ -#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, struct timeval *timeout, int *sock); - -static int -send_request(int sock, struct timeval *timeout, 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, struct timeval *timeout, int *sock) -{ - struct sockaddr_un my_addr; - int s; - int ret; - struct timeval before,after,to; - int sock_err; - socklen_t err_len; - - assert(sock != NULL); - memset(&my_addr, 0, sizeof(my_addr)); - - s = socket(AF_UNIX, SOCK_STREAM, 0); - if (s == -1) { - return errno; - } - - if (timeout) { - int flags = fcntl(s, F_GETFL, 0); - if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) - 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) { - if (errno == EINPROGRESS) { - fd_set fds; - - FD_ZERO(&fds); - FD_SET(s, &fds); - memcpy(&to, timeout, sizeof(to)); - gettimeofday(&before,NULL); - switch (select(s+1, NULL, &fds, NULL, &to)) { - case -1: close(s); - return errno; - case 0: close(s); - return EDG_WLPR_ERROR_TIMEOUT; - } - gettimeofday(&after,NULL); - if (edg_wlpr_DecrementTimeout(timeout, before, after)) { - close (s); - return EDG_WLPR_ERROR_TIMEOUT; - } - - err_len = sizeof sock_err; - if (getsockopt(s,SOL_SOCKET,SO_ERROR,&sock_err,&err_len)) { - close(s); - return errno; - } - if (sock_err) { - close(s); - errno = sock_err; - return errno; - } - } else { - close(s); - return errno; - } - } - - *sock = s; - return 0; -} - -static int -send_request(int sock, struct timeval *timeout, 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, timeout, buf, strlen(buf) + 1); - free(buf); - if (ret) - return ret; - - ret = edg_wlpr_Read(sock, timeout, &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; - struct timeval timeout; - const char *s = NULL; - double d; - - s = getenv("GLITE_PR_TIMEOUT"); - d = s ? atof(s) : GLITE_PR_TIMEOUT_DEFAULT; - timeout.tv_sec = (long) d; - timeout.tv_usec = (long) ((d-timeout.tv_sec) * 1e6); - - snprintf(sockname, sizeof(sockname), "%s%d", - DGPR_REG_SOCKET_NAME_ROOT, getuid()); - ret = do_connect(sockname, &timeout, &sock); - if (ret) - return ret; - - ret = send_request(sock, &timeout, 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", - "Operation timed out", - "System 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; -} diff --git a/org.glite.security.proxyrenewal/src/client.c b/org.glite.security.proxyrenewal/src/client.c deleted file mode 100644 index eb2d36b..0000000 --- a/org.glite.security.proxyrenewal/src/client.c +++ /dev/null @@ -1,117 +0,0 @@ -#include -#include -#include -#include -#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 address of myproxy server\n" - "-p, --port port of myproxy server\n" - "-f, --file filename with proxy\n" - "-j, --jobid 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; -} diff --git a/org.glite.security.proxyrenewal/src/commands.c b/org.glite.security.proxyrenewal/src/commands.c deleted file mode 100644 index 79b96d3..0000000 --- a/org.glite.security.proxyrenewal/src/commands.c +++ /dev/null @@ -1,1256 +0,0 @@ -#include "renewal_locl.h" -#include "renewd_locl.h" - -#include "glite/security/voms/voms_apic.h" - -#ident "$Header$" - -#define SEPARATORS ",\n" -#define RENEWAL_START_FRACTION 0.75 /* XXX */ -#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) -{ - char *subject = NULL; - char file[FILENAME_MAX]; - int ret; - - assert(basefilename != NULL); - - ret = get_proxy_base_name(proxy_file, &subject); - if (ret) - 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); - 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 remaining_life; - time_t life_to_lose; - time_t limit; - time_t delta; - - if (RENEWAL_MIN_LIFETIME > condor_limit) { - limit = RENEWAL_MIN_LIFETIME; - } else { - limit = condor_limit; - } - - limit += RENEWAL_CLOCK_SKEW; - - if (current_time + limit >= end_time) { - /* if the proxy is too short, renew it as soon as possible */ - - if (current_time + condor_limit > end_time ) { - edg_wlpr_Log(LOG_ERR, "Remaining proxy lifetime fell below the value of the Condor limit!"); - } - - return 0; - } - - remaining_life = end_time - current_time; - - /* renewal should gain the jobs an extra lifetime of - RENEWAL_START_FRACTION (default 3/4) of the new proxy's - lifetime. If the time remaining on the current proxy is already - small then the jobs may gain an extra lifetime of more than that. - - In any case, a renewal will be scheduled to happen before the - lifetime limit. - - 'life_to_lose' is the lifetime that will be lost, ie the time that - will still remain on the current proxy when it is renewed - */ - - life_to_lose = (1.0-RENEWAL_START_FRACTION)*60*60*DGPR_RETRIEVE_DEFAULT_HOURS; - - if (life_to_lose < limit) { - life_to_lose = limit; - } - - delta = life_to_lose - limit; - - while( remaining_life < (limit + delta) ) { - delta *= (1.0-RENEWAL_START_FRACTION); - } - - life_to_lose = limit + delta; - - return (remaining_life - life_to_lose); -} - -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); - globus_gsi_cert_utils_make_time(X509_get_notAfter(cert), &end_time); - globus_gsi_cert_utils_make_time(X509_get_notBefore(cert), &start_time); - current_time = time(NULL); - ASN1_UTCTIME_free(asn1_time); - /* if (end_time - RENEWAL_CLOCK_SKEW < current_time) { Too short proxy } */ - if (end_time + RENEWAL_CLOCK_SKEW < current_time) { - 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; - } - globus_gsi_cert_utils_make_time(X509_get_notAfter(cert), &tmp_end); - 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=" */ - 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; - int line_num = 0; - - assert(record != NULL); - memset(&tmp_record, 0, sizeof(tmp_record)); - - current_time = time(NULL); - while (fgets(line, sizeof(line), fd) != NULL) { - line_num++; - free_record(&tmp_record); - p = strchr(line, '\n'); - if (p) - *p = '\0'; - ret = decode_record(line, &tmp_record); - if (ret) { - edg_wlpr_Log(LOG_ERR, "Skipping invalid entry at line %d", line_num); - 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 */ - record->suffix = tmp_record.suffix; - record->next_renewal = record->end_time = 0; - free_record(&tmp_record); - return 0; - } - - /* Proxies with VOMS attributes require a separate record, which is not - * shared with another proxies. The same applies it the unique flag was - * set by the caller */ - if (record->voms_exts || record->unique) - continue; - - 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 && - current_time + condor_limit + RENEWAL_CLOCK_SKEW > tmp_record.end_time) { - - /* skip expired proxy (or 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]; - int line_num = 0; - - 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) { - line_num++; - free_record(&tmp_record); - p = strchr(line, '\n'); - if (p) - *p = '\0'; - ret = decode_record(line, &tmp_record); - if (ret) { - edg_wlpr_Log(LOG_ERR, "Removing invalid entry at line %d in %s", line_num, basename); - continue; - } - 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, NULL); - if (ret) { - VOMS_Destroy(voms_info); - return ret; - } - - ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, voms_info, &err); - if (ret == 1) { - *present = 1; - } - - VOMS_Destroy(voms_info); - X509_free(cert); - EVP_PKEY_free(privkey); - sk_X509_pop_free(chain, X509_free); - return 0; -} -#endif - -void -register_proxy(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 %s", cur_proxy); - } 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; -} diff --git a/org.glite.security.proxyrenewal/src/common.c b/org.glite.security.proxyrenewal/src/common.c deleted file mode 100644 index 7b3df64..0000000 --- a/org.glite.security.proxyrenewal/src/common.c +++ /dev/null @@ -1,323 +0,0 @@ -#include "renewal_locl.h" - -#ident "$Header$" - -/* nread() and nwrite() never return partial data */ -static int -nread(int sock, struct timeval *to, char *buf, size_t buf_len, size_t *read_len) -{ - size_t count; - size_t remain = buf_len; - char *cbuf = buf; - fd_set fds; - struct timeval timeout,before,after; - int ret; - - if (to) { - memcpy(&timeout,to,sizeof(timeout)); - gettimeofday(&before,NULL); - } - - while (remain > 0) { - FD_ZERO(&fds); - FD_SET(sock,&fds); - switch (select(sock+1, &fds, NULL, NULL, to ? &timeout : NULL)) { - case 0: - ret = EDG_WLPR_ERROR_TIMEOUT; - goto end; - case -1: - ret = EDG_WLPR_ERROR_ERRNO; - goto end; - } - - count = read(sock, cbuf, remain); - if (count < 0) { - if (errno == EINTR) - continue; - else { - ret = EDG_WLPR_ERROR_ERRNO; - goto end; - } - } else - if (count == 0) { - *read_len = 0; - return 0; - } - cbuf += count; - remain -= count; - } - *read_len = buf_len; - ret = 0; - -end: - if (to) { - gettimeofday(&after,NULL); - edg_wlpr_DecrementTimeout(to, before, after); - if (to->tv_sec < 0) { - to->tv_sec = 0; - to->tv_usec = 0; - } - } - - return ret; -} - -static size_t -nwrite(int sock, struct timeval *to, const char *buf, size_t buf_len) -{ - const char *cbuf = buf; - size_t count; - size_t remain = buf_len; - fd_set fds; - struct timeval timeout,before,after; - int ret; - - if (to) { - memcpy(&timeout,to,sizeof(timeout)); - gettimeofday(&before,NULL); - } - - while (remain > 0) { - FD_ZERO(&fds); - FD_SET(sock,&fds); - switch (select(sock+1, NULL, &fds, NULL, to ? &timeout : NULL)) { - case 0: ret = EDG_WLPR_ERROR_TIMEOUT; - goto end; - case -1: ret = EDG_WLPR_ERROR_ERRNO; - goto end; - } - - count = write(sock, cbuf, remain); - if (count < 0) { - if (errno == EINTR) - continue; - else { - ret = EDG_WLPR_ERROR_ERRNO; - goto end; - } - } - cbuf += count; - remain -= count; - } - ret = buf_len; - -end: - if (to) { - gettimeofday(&after,NULL); - edg_wlpr_DecrementTimeout(to, before, after); - if (to->tv_sec < 0) { - to->tv_sec = 0; - to->tv_usec = 0; - } - } - - return ret; -} - -int -edg_wlpr_Read(int sock, struct timeval *timeout, char **buf, size_t *buf_len) -{ - int ret; - unsigned char length[4]; - size_t len; - - ret = nread(sock, timeout, length, 4, &len); - if (ret) { - *buf_len = 0; - return ret; - } - if (len != 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, timeout, *buf, *buf_len, &len); - if (ret) - return ret; - - if (len != *buf_len) { - free(*buf); - *buf_len = 0; - return EDG_WLPR_ERROR_UNEXPECTED_EOF; /* XXX */ - } - - return 0; -} - -int -edg_wlpr_Write(int sock, struct timeval *timeout, 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, timeout, length, 4) != 4 || - nwrite(sock, timeout, 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; -} - -int -edg_wlpr_DecrementTimeout(struct timeval *timeout, struct timeval before, struct timeval after) -{ - (*timeout).tv_sec = (*timeout).tv_sec - (after.tv_sec - before.tv_sec); - (*timeout).tv_usec = (*timeout).tv_usec - (after.tv_usec - before.tv_usec); - while ( (*timeout).tv_usec < 0) { - (*timeout).tv_sec--; - (*timeout).tv_usec += 1000000; - } - - if ( ((*timeout).tv_sec < 0) || (((*timeout).tv_sec == 0) && ((*timeout).tv_usec == 0)) ) return(1); - else return(0); -} diff --git a/org.glite.security.proxyrenewal/src/newformat.h b/org.glite.security.proxyrenewal/src/newformat.h deleted file mode 100755 index 0efeb7e..0000000 --- a/org.glite.security.proxyrenewal/src/newformat.h +++ /dev/null @@ -1,195 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) 2002, 2003 INFN-CNAF on behalf of the EU DataGrid. - * For license conditions see LICENSE file or - * http://www.edg.org/license.html - * - * Parts of this code may be based upon or even include verbatim pieces, - * originally written by other people, in which case the original header - * follows. - * - *********************************************************************/ -#ifndef _NEW_FORMAT_H -#define _NEW_FORMAT_H -#include -#include -#include -#include -#include -#include -#include - -#include "acstack.h" -#if 0 -static STACK_OF(CRYPT_EX_DATA_FUNS) *AC_meth = NULL; - -static AC_METHOD meth = { - (int (*)()) i2d_AC, - (char *(*)())d2i_AC, - (char *(*)())AC_new, - (void (*)()) AC_free}; -a -ASN1_METHOD *AC_asn1_meth(void) -{ - return &meth; -} -#endif - -typedef struct ACDIGEST { - ASN1_ENUMERATED *type; - ASN1_OBJECT *oid; - X509_ALGOR *algor; - ASN1_BIT_STRING *digest; -} AC_DIGEST; - -typedef struct ACIS { - STACK_OF(GENERAL_NAME) *issuer; - ASN1_INTEGER *serial; - ASN1_BIT_STRING *uid; -} AC_IS; - -typedef struct ACFORM { - STACK_OF(GENERAL_NAME) *names; - AC_IS *is; - AC_DIGEST *digest; -} AC_FORM; - -typedef struct ACACI { - STACK_OF(GENERAL_NAME) *names; - AC_FORM *form; -} AC_ACI; - -typedef struct ACHOLDER { - AC_IS *baseid; - STACK_OF(GENERAL_NAMES) *name; - AC_DIGEST *digest; -} AC_HOLDER; - -typedef struct ACVAL { - ASN1_GENERALIZEDTIME *notBefore; - ASN1_GENERALIZEDTIME *notAfter; -} AC_VAL; - -typedef struct asn1_string_st AC_IETFATTRVAL; - -typedef struct ACIETFATTR { - STACK_OF(GENERAL_NAMES) *names; - STACK_OF(AC_IETFATTRVAL) *values; -} AC_IETFATTR; - -typedef struct ACTARGET { - GENERAL_NAME *name; - GENERAL_NAME *group; - AC_IS *cert; -} AC_TARGET; - -typedef struct ACTARGETS { - STACK_OF(AC_TARGET) *targets; -} AC_TARGETS; - -typedef struct ACATTR { - ASN1_OBJECT *type; - STACK_OF(AC_IETFATTR) *ietfattr; -} AC_ATTR; - -typedef struct ACINFO { - ASN1_INTEGER *version; - AC_HOLDER *holder; - AC_FORM *form; - X509_ALGOR *alg; - ASN1_INTEGER *serial; - AC_VAL *validity; - STACK_OF(AC_ATTR) *attrib; - ASN1_BIT_STRING *id; - STACK_OF(X509_EXTENSION) *exts; -} AC_INFO; - -typedef struct ACC { - AC_INFO *acinfo; - X509_ALGOR *sig_alg; - ASN1_BIT_STRING *signature; -} AC; - -typedef struct ACSEQ { - STACK_OF(AC) *acs; -} AC_SEQ; - -DECL_STACK(AC_TARGET) -DECL_STACK(AC_TARGETS) -DECL_STACK(AC_IETFATTR) -DECL_STACK(AC_IETFATTRVAL) -DECL_STACK(AC_ATTR) -DECL_STACK(AC); -DECL_STACK(AC_INFO); -DECL_STACK(AC_VAL); -DECL_STACK(AC_HOLDER); -DECL_STACK(AC_ACI); -DECL_STACK(AC_FORM); -DECL_STACK(AC_IS); -DECL_STACK(AC_DIGEST); - -extern int i2d_AC_ATTR(AC_ATTR *a, unsigned char **pp); -extern AC_ATTR *d2i_AC_ATTR(AC_ATTR **a, unsigned char **p, long length); -extern AC_ATTR *AC_ATTR_new(); -extern void AC_ATTR_free(AC_ATTR *a); -extern int i2d_AC_IETFATTR(AC_IETFATTR *a, unsigned char **pp); -extern AC_IETFATTR *d2i_AC_IETFATTR(AC_IETFATTR **a, unsigned char **p, long length); -extern AC_IETFATTR *AC_IETFATTR_new(); -extern void AC_IETFATTR_free (AC_IETFATTR *a); -extern int i2d_AC_IETFATTRVAL(AC_IETFATTRVAL *a, unsigned char **pp); -extern AC_IETFATTRVAL *d2i_AC_IETFATTRVAL(AC_IETFATTRVAL **a, unsigned char **pp, long length); -extern AC_IETFATTRVAL *AC_IETFATTRVAL_new(); -extern void AC_IETFATTRVAL_free(AC_IETFATTRVAL *a); -extern int i2d_AC_DIGEST(AC_DIGEST *a, unsigned char **pp); -extern AC_DIGEST *d2i_AC_DIGEST(AC_DIGEST **a, unsigned char **pp, long length);; -extern AC_DIGEST *AC_DIGEST_new(void); -extern void AC_DIGEST_free(AC_DIGEST *a); -extern int i2d_AC_IS(AC_IS *a, unsigned char **pp); -extern AC_IS *d2i_AC_IS(AC_IS **a, unsigned char **pp, long length); -extern AC_IS *AC_IS_new(void); -extern void AC_IS_free(AC_IS *a); -extern int i2d_AC_FORM(AC_FORM *a, unsigned char **pp); -extern AC_FORM *d2i_AC_FORM(AC_FORM **a, unsigned char **pp, long length); -extern AC_FORM *AC_FORM_new(void); -extern void AC_FORM_free(AC_FORM *a); -extern int i2d_AC_ACI(AC_ACI *a, unsigned char **pp); -extern AC_ACI *d2i_AC_ACI(AC_ACI **a, unsigned char **pp, long length); -extern AC_ACI *AC_ACI_new(void); -extern void AC_ACI_free(AC_ACI *a); - -extern int i2d_AC_HOLDER(AC_HOLDER *a, unsigned char **pp); -extern AC_HOLDER *d2i_AC_HOLDER(AC_HOLDER **a, unsigned char **pp, long length); -extern AC_HOLDER *AC_HOLDER_new(void); -extern void AC_HOLDER_free(AC_HOLDER *a); - -/* new AC_VAL functions by Valerio */ -extern int i2d_AC_VAL(AC_VAL *a, unsigned char **pp); -extern AC_VAL *d2i_AC_VAL(AC_VAL **a, unsigned char **pp, long length); -extern AC_VAL *AC_VAL_new(void); -extern void AC_VAL_free(AC_VAL *a); -/* end*/ - -extern int i2d_AC_INFO(AC_INFO *a, unsigned char **pp); -extern AC_INFO *d2i_AC_INFO(AC_INFO **a, unsigned char **p, long length); -extern AC_INFO *AC_INFO_new(void); -extern void AC_INFO_free(AC_INFO *a); -extern int i2d_AC(AC *a, unsigned char **pp) ; -extern AC *d2i_AC(AC **a, unsigned char **pp, long length); -extern AC *AC_new(void); -extern void AC_free(AC *a); -extern int i2d_AC_TARGETS(AC_TARGETS *a, unsigned char **pp) ; -extern AC_TARGETS *d2i_AC_TARGETS(AC_TARGETS **a, unsigned char **pp, long length); -extern AC_TARGETS *AC_TARGETS_new(void); -extern void AC_TARGETS_free(AC_TARGETS *a); -extern int i2d_AC_TARGET(AC_TARGET *a, unsigned char **pp) ; -extern AC_TARGET *d2i_AC_TARGET(AC_TARGET **a, unsigned char **pp, long length); -extern AC_TARGET *AC_TARGET_new(void); -extern void AC_TARGET_free(AC_TARGET *a); -extern int i2d_AC_SEQ(AC_SEQ *a, unsigned char **pp) ; -extern AC_SEQ *d2i_AC_SEQ(AC_SEQ **a, unsigned char **pp, long length); -extern AC_SEQ *AC_SEQ_new(void); -extern void AC_SEQ_free(AC_SEQ *a); - -#endif diff --git a/org.glite.security.proxyrenewal/src/renew.c b/org.glite.security.proxyrenewal/src/renew.c deleted file mode 100644 index ddae37b..0000000 --- a/org.glite.security.proxyrenewal/src/renew.c +++ /dev/null @@ -1,404 +0,0 @@ -#include "renewal_locl.h" -#include "renewd_locl.h" - -#include "glite/security/voms/voms_apic.h" - -#ident "$Header$" - -#define RENEWAL_COUNTS_MAX 1000 /* the slave daemon exits after that many attemtps */ - -extern char *repository; -extern char *cadir; -extern char *vomsdir; -extern int voms_enabled; -extern char *vomsconf; - -static int received_signal = -1, die = 0; - -static void -check_renewal(char *datafile, int force_renew, int *num_renewed); - -static int -renew_proxy(proxy_record *record, char *basename, char **new_proxy); - -static void -register_signal(int signal); - -int -load_proxy(const char *cur_file, X509 **cert, EVP_PKEY **priv_key, - STACK_OF(X509) **chain, globus_gsi_cred_handle_t *cur_proxy) -{ - globus_result_t result; - globus_gsi_cred_handle_t proxy = NULL; - int ret; - - result = globus_gsi_cred_handle_init(&proxy, NULL); - if (result) { - fprintf(stderr, "globus_gsi_cred_handle_init() failed\n"); - goto end; - } - - result = globus_gsi_cred_read_proxy(proxy, cur_file); - if (result) { - fprintf(stderr, "globus_gsi_cred_read_proxy() failed\n"); - goto end; - } - - if (cert) { - result = globus_gsi_cred_get_cert(proxy, cert); - if (result) { - fprintf(stderr, "globus_gsi_cred_get_cert() failed\n"); - goto end; - } - } - - if (priv_key) { - result = globus_gsi_cred_get_key(proxy, priv_key); - if (result) { - fprintf(stderr, "globus_gsi_cred_get_key() failed\n"); - goto end; - } - } - - if (chain) { - result = globus_gsi_cred_get_cert_chain(proxy, chain); - if (result) { - fprintf(stderr, "globus_gsi_cred_get_cert_chain() failed\n"); - goto end; - } - } - - if (cur_proxy) { - *cur_proxy = proxy; - proxy = NULL; - } - - ret = 0; - -end: - if (proxy) - globus_gsi_cred_handle_destroy(proxy); - if (result) - ret = EDG_WLPR_ERROR_GENERIC; - - return ret; -} - -static void -register_signal(int signal) -{ - received_signal = signal; - switch ((received_signal = signal)) { - case SIGINT: - case SIGTERM: - case SIGQUIT: - die = signal; - break; - default: - break; - } -} - -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]; - int ret = -1; - char *p; - char *server = NULL; - myproxy_socket_attrs_t *socket_attrs; - myproxy_request_t *client_request; - myproxy_response_t *server_response; - char *renewed_proxy; - - socket_attrs = malloc(sizeof(*socket_attrs)); - memset(socket_attrs, 0, sizeof(*socket_attrs)); - - client_request = malloc(sizeof(*client_request)); - memset(client_request, 0, sizeof(*client_request)); - - server_response = malloc(sizeof(*server_response)); - memset(server_response, 0, sizeof(*server_response)); - - myproxy_set_delegation_defaults(socket_attrs, client_request); - - edg_wlpr_Log(LOG_DEBUG, "Trying to renew proxy in %s.%d", - basename, record->suffix); - - snprintf(tmp_proxy, sizeof(tmp_proxy), "%s.%d.myproxy.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; - } - - snprintf(repository_file, sizeof(repository_file),"%s.%d", - basename, record->suffix); - - ret = get_proxy_base_name(repository_file, &client_request->username); - if (ret) - goto end; - - client_request->proxy_lifetime = 60 * 60 * DGPR_RETRIEVE_DEFAULT_HOURS; - client_request->authzcreds = repository_file; - - 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; - - verror_clear(); - ret = myproxy_get_delegation(socket_attrs, client_request, - server_response, tmp_proxy); - if (ret == 1) { - ret = EDG_WLPR_ERROR_MYPROXY; - edg_wlpr_Log(LOG_ERR, "Error contacting MyProxy server for proxy %s: %s", - repository_file, verror_get_string()); - verror_clear(); - goto end; - } - - renewed_proxy = tmp_proxy; - - if (voms_enabled && record->voms_exts) { - char tmp_voms_proxy[FILENAME_MAX]; - int tmp_voms_fd; - - snprintf(tmp_voms_proxy, sizeof(tmp_voms_proxy), "%s.%d.voms.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_creds(repository_file, renewed_proxy, tmp_voms_proxy); - close(tmp_voms_fd); - if (ret) { - unlink(tmp_voms_proxy); - goto end; - } - - renewed_proxy = tmp_voms_proxy; - unlink(tmp_proxy); - } - - if (new_proxy) - *new_proxy = strdup(renewed_proxy); - - ret = 0; - -end: - if (socket_attrs->socket_fd) - close(socket_attrs->socket_fd); - close(tmp_fd); - if (ret) - unlink(tmp_proxy); - myproxy_free(socket_attrs, client_request, server_response); - - return ret; -} - -static void -check_renewal(char *datafile, int force_renew, int *num_renewed) -{ - 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); - - *num_renewed = 0; - - 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 (current_time + RENEWAL_CLOCK_SKEW >= record.end_time || - record.next_renewal <= current_time || - force_renew) { - ret = EDG_WLPR_PROXY_EXPIRED; - if ( record.end_time + RENEWAL_CLOCK_SKEW >= 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); - - *num_renewed = num; - - return; -} - -int renewal(int force_renew, int *num_renewed) -{ - DIR *dir = NULL; - struct dirent *file; - FILE *fd; - int num = 0; - - edg_wlpr_Log(LOG_DEBUG, "Starting renewal process"); - - *num_renewed = 0; - - 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, &num); - *num_renewed += num; - fclose(fd); - } - closedir(dir); - edg_wlpr_Log(LOG_DEBUG, "Finishing renewal process"); - return 0; -} - -void -watchdog_start(void) -{ - struct sigaction sa; - int force_renewal; - int count = 0, num; - - memset(&sa,0,sizeof(sa)); - sa.sa_handler = register_signal; - sigaction(SIGUSR1, &sa, NULL); - sigaction(SIGINT,&sa,NULL); - sigaction(SIGQUIT,&sa,NULL); - sigaction(SIGTERM,&sa,NULL); - sigaction(SIGPIPE,&sa,NULL); - - while (count < RENEWAL_COUNTS_MAX && !die) { - received_signal = -1; - sleep(60 * 5); - force_renewal = (received_signal == SIGUSR1) ? 1 : 0; - if (die) - break; - /* XXX uninstall signal handler ? */ - renewal(force_renewal, &num); - count += num; - } - edg_wlpr_Log(LOG_DEBUG, "Terminating after %d renewal attempts", count); - exit(0); -} diff --git a/org.glite.security.proxyrenewal/src/renewal_locl.h b/org.glite.security.proxyrenewal/src/renewal_locl.h deleted file mode 100644 index 9d0774d..0000000 --- a/org.glite.security.proxyrenewal/src/renewal_locl.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef RENEWAL_LOCL_H -#define RENEWAL_LOCL_H - -#ident "$Header$" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 */ - -#define RENEWAL_CLOCK_SKEW (5 * 60) - -#define DGPR_RETRIEVE_DEFAULT_HOURS 10 - -#define GLITE_PR_TIMEOUT_DEFAULT 120 - -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, struct timeval *timeout, char **buf, size_t *buf_len); - -int -edg_wlpr_Write(int sock, struct timeval *timeout, 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); - -int -edg_wlpr_DecrementTimeout(struct timeval *timeout, struct timeval before, struct timeval after); - -#endif /* RENEWAL_LOCL_H */ diff --git a/org.glite.security.proxyrenewal/src/renewd.c b/org.glite.security.proxyrenewal/src/renewd.c deleted file mode 100644 index 4a595a8..0000000 --- a/org.glite.security.proxyrenewal/src/renewd.c +++ /dev/null @@ -1,656 +0,0 @@ -#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 *cert = NULL; -char *key = NULL; -char *vomsconf = NULL; - -static volatile int die = 0, child_died = 0; -double default_timeout = 0; - -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' }, - { "cert", required_argument, NULL, 't' }, - { "key", required_argument, NULL, 'k' }, - { 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); - -int -start_watchdog(pid_t *pid); - -static void -catchsig(int sig) -{ - switch (sig) { - case SIGINT: - case SIGTERM: - case SIGQUIT: - die = sig; - break; - case SIGCHLD: - child_died = 1; - break; - default: - break; - } -} - -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; - struct timeval timeout; - - memset(&request, 0, sizeof(request)); - memset(&response, 0, sizeof(response)); - - timeout.tv_sec = (long) default_timeout; - timeout.tv_usec = (long) ((default_timeout - timeout.tv_sec) * 1e6); - - ret = edg_wlpr_Read(sock, &timeout, &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 and jobid %s", - request.command, - request.proxy_filename ? request.proxy_filename : "(unspecified)", - request.jobid ? request.jobid : "(unspecified)"); - - command->handler(&request, &response); - - ret = encode_response(&response, &buf); - if (ret) - goto end; - - ret = edg_wlpr_Write(sock, &timeout, 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); - int flags; - - while (!die) { - - if (child_died) { - int pid, newpid, ret; - - while ((pid=waitpid(-1,NULL,WNOHANG))>0) - ; - ret = start_watchdog(&newpid); - if (ret) - return ret; - edg_wlpr_Log(LOG_DEBUG, "Renewal slave process re-started"); - child_died = 0; - continue; - } - - newsock = accept(sock, (struct sockaddr *) &client_addr, &client_addr_len); - if (newsock == -1) { - if (errno != EINTR) - edg_wlpr_Log(LOG_ERR, "accept() failed"); - continue; - } - edg_wlpr_Log(LOG_DEBUG, "Got connection"); - - flags = fcntl(newsock, F_GETFL, 0); - if (fcntl(newsock, F_SETFL, flags | O_NONBLOCK) < 0) { - edg_wlpr_Log(LOG_ERR, "Can't set O_NONBLOCK mode (%s), closing.\n", - strerror(errno)); - close(newsock); - continue; - } - - proto(newsock); - - edg_wlpr_Log(LOG_DEBUG, "Connection closed"); - close(newsock); - } - edg_wlpr_Log(LOG_DEBUG, "Terminating on signal %d\n",die); - return 0; -} - -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, 50); - 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); -} - -int main(int argc, char *argv[]) -{ - int sock; - char *progname; - int opt; - int fd; - char sockname[PATH_MAX]; - int ret; - pid_t pid; - struct sigaction sa; - const char *s = NULL; - - 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:t:k:", 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 't': cert = optarg; break; - case 'k': key = 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); - } - - globus_module_activate(GLOBUS_GSI_CERT_UTILS_MODULE); - globus_module_activate(GLOBUS_GSI_PROXY_MODULE); - - 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 (cert) - setenv("X509_USER_CERT", cert, 1); - - if (key) - setenv("X509_USER_KEY", key, 1); - - if (cadir) - setenv("X509_CERT_DIR", cadir, 1); - - s = getenv("GLITE_PR_TIMEOUT"); - default_timeout = s ? atof(s) : GLITE_PR_TIMEOUT_DEFAULT; - - memset(&sa,0,sizeof(sa)); - sa.sa_handler = catchsig; - sigaction(SIGINT,&sa,NULL); - sigaction(SIGQUIT,&sa,NULL); - sigaction(SIGTERM,&sa,NULL); - sigaction(SIGCHLD,&sa,NULL); - sigaction(SIGPIPE,&sa,NULL); - - 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); - - ret = doit(sock); - - close(sock); - return ret; -} - -int -get_proxy_base_name(char *file, char **name) -{ - X509 *cert = NULL; - EVP_PKEY *key = NULL; - STACK_OF(X509) *chain = NULL; - X509_NAME *subject = NULL; - int ret; - - ret = load_proxy(file, &cert, &key, &chain, NULL); - if (ret) - return ret; - - subject = X509_NAME_dup(X509_get_subject_name(cert)); - - sk_X509_insert(chain, cert, 0); - cert = NULL; - - ret = globus_gsi_cert_utils_get_base_name(subject, chain); - if (ret) { - edg_wlpr_Log(LOG_ERR, "Cannot get subject name from proxy %s", file); - ret = EDG_WLPR_ERROR_SSL; /* XXX ??? */ - goto end; - } - - *name = X509_NAME_oneline(subject, NULL, 0); - ret = 0; - -end: - if (cert) - X509_free(cert); - if (key) - EVP_PKEY_free(key); - if (chain) - sk_X509_pop_free(chain, X509_free); - if (subject) - X509_NAME_free(subject); - - return ret; -} diff --git a/org.glite.security.proxyrenewal/src/renewd_locl.h b/org.glite.security.proxyrenewal/src/renewd_locl.h deleted file mode 100644 index c4b8de4..0000000 --- a/org.glite.security.proxyrenewal/src/renewd_locl.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef RENEWALD_LOCL_H -#define RENEWALD_LOCL_H - -#ident "$Header$" - -#include -#include -#include -#include -#include - -#include "renewal.h" - -#ifdef HAVE_DMALLOC_H -#include -#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; - -/* 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, globus_gsi_cred_handle_t *proxy); - -int -get_proxy_base_name(char *file, char **subject); - -int -renew_voms_creds(const char *cur_file, const char *renewed_file, const char *new_file); - -#endif /* RENEWALD_LOCL_H */ diff --git a/org.glite.security.proxyrenewal/src/voms.c b/org.glite.security.proxyrenewal/src/voms.c deleted file mode 100644 index f570fd4..0000000 --- a/org.glite.security.proxyrenewal/src/voms.c +++ /dev/null @@ -1,318 +0,0 @@ -#include "renewal_locl.h" -#include "renewd_locl.h" - -#include -#include - -#include "glite/security/voms/voms_apic.h" - -#include "newformat.h" - -char * Decode(const char *, int, int *); -char **listadd(char **, char *, int); - -extern char *vomsconf; - -static int -generate_proxy(globus_gsi_cred_handle_t cur_proxy, - X509_EXTENSION *voms_extension, const char *new_file) -{ - globus_result_t result; - globus_gsi_proxy_handle_t proxy_handle = NULL; - globus_gsi_cred_handle_t proxy = NULL; - EVP_PKEY *cur_proxy_priv_key = NULL; - X509 *new_cert = NULL; - X509 *voms_cert = NULL; - globus_gsi_cert_utils_cert_type_t proxy_type; - - result = globus_gsi_proxy_handle_init(&proxy_handle, NULL); - if (result) { - edg_wlpr_Log(LOG_ERR, "globus_gsi_proxy_handle_init() failed\n"); - goto end; - } - - result = globus_gsi_cred_get_key(cur_proxy, &cur_proxy_priv_key); - if (result) { - edg_wlpr_Log(LOG_ERR, "globus_gsi_cred_get_key() failed\n"); - goto end; - } - - /* Create and sign a new proxy */ - result = globus_gsi_cred_get_cert_type(cur_proxy, &proxy_type); - if (result) { - edg_wlpr_Log(LOG_ERR, "globus_gsi_cred_get_cert_type() failed\n"); - goto end; - } - - result = globus_gsi_proxy_handle_set_type(proxy_handle, proxy_type); - if (result) { - edg_wlpr_Log(LOG_ERR, "globus_gsi_proxy_handle_set_type() failed\n"); - goto end; - } - - result = globus_gsi_proxy_create_signed(proxy_handle, cur_proxy, &proxy); - if (result) { - edg_wlpr_Log(LOG_ERR, "globus_gsi_proxy_handle_init() failed\n"); - goto end; - } - - /* Get the new proxy */ - result = globus_gsi_cred_get_cert(proxy, &new_cert); - if (result) { - edg_wlpr_Log(LOG_ERR, "globus_gsi_cred_get_cert() failed\n"); - goto end; - } - - /* The Globus API doesn't allow to store custom X.509 extensions */ - voms_cert = X509_dup(new_cert); - if (voms_cert->cert_info->extensions == NULL) - voms_cert->cert_info->extensions = sk_X509_EXTENSION_new_null(); - sk_X509_EXTENSION_push(voms_cert->cert_info->extensions, voms_extension); - - /* Openssl ensures that memory containing old signature structures is unallocated */ -#if 0 - X509_sign(voms_cert, cur_proxy_priv_key, proxy_handle->attrs->signing_algorithm); -#else - X509_sign(voms_cert, cur_proxy_priv_key, EVP_md5()); -#endif - - /* And put the cert back, older one is unallocated by the function */ - result = globus_gsi_cred_set_cert(proxy, voms_cert); - if (result) { - edg_wlpr_Log(LOG_ERR, "globus_gsi_cred_set_cert() failed\n"); - goto end; - } - - result = globus_gsi_cred_write_proxy(proxy, (char *)new_file); - -end: - - return 0; -} - -static int -my_VOMS_Export(void *buf, int buf_len, X509_EXTENSION **extension) -{ - AC *ac = NULL; - unsigned char *p, *pp; - AC **voms_attrs = NULL; - - p = pp = buf; - ac = d2i_AC(NULL, &p, buf_len+1); - if (ac == NULL) { - edg_wlpr_Log(LOG_ERR, "d2i_AC() failed\n"); - return 1; - } - - voms_attrs = (AC **)listadd((char **)voms_attrs, (char *)ac, sizeof(AC *)); - - *extension = X509V3_EXT_conf_nid(NULL, NULL, OBJ_txt2nid("acseq"), - (char*)voms_attrs); - return 0; -} - -static int -create_voms_command(struct vomsdata *vd, struct voms **voms_cert, char **command) -{ - int voms_error, ret; - struct data **attribs; - -#if 0 - VOMS_ResetOrder(vd, &voms_error); - for (i = 2; i < argc; i++) { - ret = VOMS_Ordering(argv[i], vd, &voms_error); - if (ret == 0) { - edg_wlpr_Log(LOG_ERR, "VOMS_Ordering() failed\n"); - return 1; - } - } -#endif - - if (voms_cert == NULL || *voms_cert == NULL || (*voms_cert)->std == NULL) { - edg_wlpr_Log(LOG_ERR, "Invalid VOMS certificate\n"); - return 1; - } - - attribs = (*voms_cert)->std; - - if (strcmp (attribs[0]->role, "NULL") == 0 ) - ret = asprintf(command, "G%s", attribs[0]->group); - else - ret = asprintf(command, "B%s:%s", attribs[0]->group, attribs[0]->role); - -end: - - return 0; -} - -static int -renew_voms_cert(struct vomsdata *vd, struct voms **voms_cert, - char **buf, size_t *buf_len) -{ - int voms_error = 0, i, ret, voms_version; - struct contactdata **voms_contacts = NULL; - char *command = NULL; - - voms_contacts = VOMS_FindByVO(vd, (*voms_cert)->voname, vomsconf, NULL, &voms_error); - - if (voms_contacts == NULL) { - edg_wlpr_Log(LOG_ERR, "VOMS_FindByVO() failed\n"); - return 1; - } - - ret = create_voms_command(vd, voms_cert, &command); - - /* XXX iterate over all servers on the list on errors */ - ret = VOMS_ContactRaw(voms_contacts[0]->host, voms_contacts[0]->port, - voms_contacts[0]->contact, command, - (void**) buf, buf_len, &voms_version, - vd, &voms_error); - if (ret == 0) { - edg_wlpr_Log(LOG_ERR, "VOMS_Contact() failed\n"); - return 1; - } - - VOMS_DeleteContacts(voms_contacts); - - if (command) - free(command); - - return 0; -} - -static int -renew_voms_certs(const char *cur_file, const char *renewed_file, const char *new_file) -{ - globus_gsi_cred_handle_t cur_proxy = NULL; - globus_gsi_cred_handle_t new_proxy = NULL; - struct vomsdata *vd = NULL; - struct voms **voms_cert = NULL; - int voms_err, ret; - X509 *cert = NULL; - STACK_OF(X509) *chain = NULL; - char *buf = NULL; - size_t buf_len = 0; - X509_EXTENSION *extension = NULL; - char *old_env_proxy = getenv("X509_USER_PROXY"); - char *old_env_cert = getenv("X509_USER_CERT"); - char *old_env_key = getenv("X509_USER_KEY"); - - setenv("X509_USER_PROXY", cur_file, 1); - setenv("X509_USER_CERT", renewed_file, 1); - setenv("X509_USER_KEY", renewed_file, 1); - - ret = load_proxy(cur_file, &cert, NULL, &chain, &cur_proxy); - if (ret) - goto end; - - vd = VOMS_Init(NULL, NULL); - if (vd == NULL) { - edg_wlpr_Log(LOG_ERR, "VOMS_Init() failed\n"); - return 1; - } - - ret = VOMS_Retrieve(cert, chain, RECURSE_CHAIN, vd, &voms_err); - if (ret == 0) { - if (voms_err == VERR_NOEXT) { - /* no VOMS cred, no problem; continue */ - /* XXX this part shouldn't be reachable, this call is only called - * if the proxy does contain VOMS attributes */ - edg_wlpr_Log(LOG_ERR, "No VOMS attributes found in proxy %s\n", cur_file); - ret = 0; - goto end; - } else { - edg_wlpr_Log(LOG_ERR, "Cannot get VOMS certificate(s) from proxy"); - ret = 1; - goto end; - } - } - - /* XXX make sure this loop can really work for multiple voms certificates - * embedded in the proxy */ - for (voms_cert = vd->data; voms_cert && *voms_cert; voms_cert++) { - char *tmp, *ptr; - size_t tmp_len; - - ret = renew_voms_cert(vd, voms_cert, &tmp, &tmp_len); - if (ret) - goto end; - 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 = my_VOMS_Export(buf, buf_len, &extension); - if (ret) - goto end; - - ret = load_proxy(renewed_file, NULL, NULL, NULL, &new_proxy); - if (ret) - goto end; - - ret = generate_proxy(new_proxy, extension, new_file); - -end: - (old_env_proxy) ? setenv("X509_USER_PROXY", old_env_proxy, 1) : - unsetenv("X509_USER_PROXY"); - (old_env_cert) ? setenv("X509_USER_CERT", old_env_cert, 1) : - unsetenv("X509_USER_CERT"); - (old_env_key) ? setenv("X509_USER_KEY", old_env_key, 1) : - unsetenv("X509_USER_KEY"); - - if (cert) - X509_free(cert); - if (chain) - sk_X509_pop_free(chain, X509_free); - if (vd) - VOMS_Destroy(vd); - if (cur_proxy) - globus_gsi_cred_handle_destroy(cur_proxy); - if (new_proxy) - globus_gsi_cred_handle_destroy(new_proxy); - if (buf) - free(buf); - - return ret; -} - -int -renew_voms_creds(const char *cur_file, const char *renewed_file, const char *new_file) -{ - return renew_voms_certs(cur_file, renewed_file, new_file); -} - -#if 0 -int -main(int argc, char *argv[]) -{ - int ret; - const char *current_proxy = "/tmp/x509up_u11930"; - const char *renewed_proxy = "/tmp/proxy"; - - if (argc > 1) - current_proxy = argv[1]; - if (argc > 2) - renewed_proxy = argv[2]; - - if (globus_module_activate(GLOBUS_GSI_PROXY_MODULE) != GLOBUS_SUCCESS || - globus_module_activate(GLOBUS_GSI_CERT_UTILS_MODULE) != GLOBUS_SUCCESS) { - edg_wlpr_Log(LOG_ERR, "[%d]: Unable to initialize Globus modules\n", getpid()); - return 1; - } - - ret = renew_voms_certs(current_proxy, renewed_proxy); - - return 0; -} -#endif diff --git a/org.glite.wms-utils.exception/.cvsignore b/org.glite.wms-utils.exception/.cvsignore deleted file mode 100644 index e970233..0000000 --- a/org.glite.wms-utils.exception/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project \ No newline at end of file diff --git a/org.glite.wms-utils.exception/LICENSE b/org.glite.wms-utils.exception/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.wms-utils.exception/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -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 -. - -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/ - - diff --git a/org.glite.wms-utils.exception/Makefile.am b/org.glite.wms-utils.exception/Makefile.am deleted file mode 100755 index b66c2bb..0000000 --- a/org.glite.wms-utils.exception/Makefile.am +++ /dev/null @@ -1,67 +0,0 @@ -## ********************************************************************* -## * -## * 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 -EXTRA_DIST = LICENSE - -docdir = $(datadir)/doc/@PACKAGE@-@VERSION@ -doc_DATA = LICENSE -## Subdirectories list -SUBDIRS = interface src - -## 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 - diff --git a/org.glite.wms-utils.exception/bootstrap b/org.glite.wms-utils.exception/bootstrap deleted file mode 100755 index ceeb099..0000000 --- a/org.glite.wms-utils.exception/bootstrap +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/sh - -mkdir -p src/autogen -set -x -aclocal -I project -libtoolize --force -autoheader -automake --foreign --add-missing --copy -autoconf diff --git a/org.glite.wms-utils.exception/build.xml b/org.glite.wms-utils.exception/build.xml deleted file mode 100755 index 4061536..0000000 --- a/org.glite.wms-utils.exception/build.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.wms-utils.exception/configure.ac b/org.glite.wms-utils.exception/configure.ac deleted file mode 100755 index 30f379f..0000000 --- a/org.glite.wms-utils.exception/configure.ac +++ /dev/null @@ -1,115 +0,0 @@ -# -# 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 -# Version info: $Id$ -# Release: $Name$ -# -# Revision history: -# $Log$ -# Revision 1.9 2004/11/16 15:31:13 eronchie -# Increased version -# -# Revision 1.8 2004/09/22 00:25:17 glbuild -# Fixed missing parenthesis -# -# Revision 1.7 2004/09/21 19:21:57 glbuild -# modified module.version -# -# Revision 1.6 2004/08/17 10:41:47 eronchie -# Added optimize option -# -# Revision 1.5 2004/07/23 08:02:09 eronchie -# Updated configure.ac -# -# Revision 1.4 2004/07/21 18:49:26 eronchie -# Added AC_GLITE -# -# Revision 1.3 2004/07/21 18:47:49 eronchie -# Removed obsolete things -# -# Revision 1.2 2004/07/21 18:44:22 eronchie -# Updated header file -# -# Revision 1.1.1.1 2004/07/21 18:16:57 eronchie -# Moved out exception from org.glite.wms.common/src/utilitiesY -# -# -# - -# Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.57) -AC_INIT([GLite WMS Utils Exception], [1.0.0]) -AC_CONFIG_AUX_DIR([./project]) -AM_INIT_AUTOMAKE([1.6.3 subdir-objects]) -AC_CONFIG_SRCDIR([src/Exception.cpp]) - -# 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]) - -AC_GLITE - -AC_OPTIMIZE - -# 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([interface/Makefile]) - -AC_OUTPUT - diff --git a/org.glite.wms-utils.exception/interface/Makefile.am b/org.glite.wms-utils.exception/interface/Makefile.am deleted file mode 100755 index 3c4ccb7..0000000 --- a/org.glite.wms-utils.exception/interface/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -## ********************************************************************* -## * -## * 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 -## * -## ********************************************************************* - -exceptiondir = $(includedir) -nobase_exception_HEADERS = \ - glite/wmsutils/exception/exception_codes.h \ - glite/wmsutils/exception/Exception.h - -MAINTAINERCLEANFILES = Makefile.in diff --git a/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h b/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h deleted file mode 100644 index 19ca7c7..0000000 --- a/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef GLITE_WMS_UTILS_EXCEPTION_EXCEPTION_H -#define GLITE_WMS_UTILS_EXCEPTION_EXCEPTION_H - -/* - * Exception.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - * Contributors are mentioned in the code where appropriate. - */ - -#include -#include -//#include -#include // For logging exceptions to log file -#include // list the exception codes -#include -#include -#include // base ancestor stl::exception - - -namespace glite { - namespace wmsutils { - namespace exception { - -extern pthread_mutex_t METHOD_MUTEX; // used in order to store info into a file (rather then syslog) -#define GLITE_STACK_TRY(method_name) std::string METHOD = method_name ; int LINE = __LINE__ ; try { -#define GLITE_STACK_CATCH() } catch (glite::wmsutils::exception::Exception &exc){ exc.push_back ( __FILE__ , LINE, METHOD ); throw exc ; } catch (std::exception &ex){ glite::wmsutils::exception::Exception exc( __FILE__ , LINE, METHOD, 0, "Standard exception: " + std::string(ex.what()) ); throw exc; } - -/** - * The Exception base classe contains attributes into which are placed exception information and provides - * constructor that beyond the error code take parameters specifying the source file and line number - * (e.g. through __FILE__ and __LINE__) where the error has been generated and string messages, - * allowing an easy way of storing the origin of the exception. - * Moreover it provides methods for getting all the exception information and for logging them either - * in a log file or to the syslog daemon. - * Each of the derived types may contain its private attributes describing the actual error instance in detail. - * Moreover each exception has an attribute representing the exception identifier that is set by the - * class constructor and allows the identification of the original exception. - * - * @version 0.1 - * @date 22 July 2004 - * @author Alessandro Maraschini -*/ - -class Exception : public std::exception{ - public: - /** - * Constructor Update all mandatory fields - * @param method the name of the method that raised the exception - * @param source The source that raised the exception (could be the file path, the class Name, etc etc) - * @param exc the previous exception as in the stack trace */ - Exception ( const std::string& source, const std::string& method, Exception *exc); - /** - * Constructor Update all mandatory fields - * @param code the code representing the thrown exception - * @param exception the name of the thrown exception - * @param method the name of the method that raised the exception - * @param source The source that raised the exception (could be the file path, the class Name, etc etc) */ - Exception ( const std::string& source, const std::string& method, int code, const std::string& exception); - - /** - * Constructor Update all mandatory fields - * @param source the path of the file that raised the exception - * @param line_number the number of the line in the file that raised the exception - * @param method the name of the method that raised the exception - * @param code the code representing the thrown exception - * @param exception the name of the thrown exception */ - Exception (const std::string& source, int line_number, const std::string& method, int code, const std::string& exception); - /** - * Default Destructor - */ - virtual ~Exception() throw (); - /** - * Return a string debug message containing information about Exception thrown - * Debug message contains all the attributes stored in an exception instance such as the method, the file and the line - * that threw the exception. - *@return the debug message string representation - */ - virtual std::string dbgMessage(); - /** - * Return the error code - * @return The integer representing the code of the error that generated the exception - */ - virtual int getCode(); - - /** - * return the Error Message associated to the Exception - * @return The Exception string message representation - */ - virtual const char* what() const throw (); - - /** - * Print Exception error information into a log file - * @param logfile the file where to log exception information - */ - virtual void log(const std::string& logfile = ""); - /** - * Retrieve the Exception name - * @return the name of the Exception thrown - */ - virtual std::string getExceptionName(); - - /** - * Retrieve the Stack of the exception as a list of previous generated exceptions - *@return the string representation of the stack trace: each line correspond to an exception message - */ - virtual std::string printStackTrace() ; - /** - * Return the list of methods that caused the Exception - */ - virtual std::vector getStackTrace() ; - /** - * Update stack information - */ - virtual void push_back ( const std::string& source, int line_number, const std::string& method ) ; - protected: - /** Empty constructor*/ - Exception(); - /** integer error code representing the cause of the error */ - int error_code; - /** string exception message representation*/ - std::string error_message ; - /** line number where the exception was raised */ - int line; - /** The name of the file where the exception was raised */ - std::string source_file; - /** the name of the exception */ - std::string exception_name; - /** the name of the method where the expceiton was raised */ - std::string method_name ; - /** a string representation of the stacktrace */ - std::string stack; - /** the actual internal stacktrace representation */ - std::vector< std::string> stack_strings ; - /** the name of the ancestor exception */ - std::string ancestor ; -}; //End Exception Class -}}} // Closing namespace -#endif diff --git a/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h b/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h deleted file mode 100755 index fce99aa..0000000 --- a/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef GLITE_WMSUTILS_EXCEPTION_CODES_H -#define GLITE_WMSUTILS_EXCEPTION_CODES_H -// pure C-style code (needed by some libraries) -#define GLITE_WMS_COMMON_ERROR_BASE 900 -#define GLITE_WMS_USERINTERFACE_ERROR_BASE 1000 -#define GLITE_WMS_NETWORKSERVER_ERROR_BASE 1200 -#define GLITE_WMS_SOCKET_ERROR_BASE 1300 -#define GLITE_WMS_LDAP_ERROR_BASE 1350 -#define GLITE_WMS_LOGGING_ERROR_BASE 1400 -#define GLITE_WMS_REQUESTAD_ERROR_BASE 1500 -#define GLITE_WMS_CHECKPOINT_ERROR_BASE 1600 -#define GLITE_WMS_CONFIGURATION_ERROR_BASE 1800 -#ifdef __cplusplus -namespace glite { -namespace wmsutils { -namespace exception { - /** - * The Error Code - */ - enum { - WMS_COMMON_BASE = GLITE_WMS_COMMON_ERROR_BASE, - THREAD_INIT , // pthread_attr_init method failed - THREAD_DETACH , // pthread_attr_setdetachstate method failed - THREAD_CREATE , // pthread_create method failed - THREAD_JOIN, - THREAD_SSL, - WMS_FATAL_ERROR, - WMS_UI_ERROR_BASE = GLITE_WMS_USERINTERFACE_ERROR_BASE, - WMS_NS_ERROR_BASE = GLITE_WMS_NETWORKSERVER_ERROR_BASE, - WMS_SOCKET_ERROR_BASE = GLITE_WMS_SOCKET_ERROR_BASE, - WMS_LDAP_ERROR_BASE = GLITE_WMS_LDAP_ERROR_BASE, - WMS_LB_ERROR_BASE = GLITE_WMS_LOGGING_ERROR_BASE , - WMS_REQUESTAD_ERROR_BASE = GLITE_WMS_REQUESTAD_ERROR_BASE, - WMS_CHKPT_ERROR_BASE = GLITE_WMS_CHECKPOINT_ERROR_BASE, - WMS_CONFIGURATION_ERROR_BASE = GLITE_WMS_CONFIGURATION_ERROR_BASE - }; -} // exception namespace -} // wmsutils namespace -} // glite namespace -#endif //ifdef c++ -#endif diff --git a/org.glite.wms-utils.exception/project/build.number b/org.glite.wms-utils.exception/project/build.number deleted file mode 100644 index 01c437a..0000000 --- a/org.glite.wms-utils.exception/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build=138 diff --git a/org.glite.wms-utils.exception/project/build.properties b/org.glite.wms-utils.exception/project/build.properties deleted file mode 100755 index e69de29..0000000 diff --git a/org.glite.wms-utils.exception/project/configure.properties.xml b/org.glite.wms-utils.exception/project/configure.properties.xml deleted file mode 100644 index 04d3b17..0000000 --- a/org.glite.wms-utils.exception/project/configure.properties.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/org.glite.wms-utils.exception/project/properties.xml b/org.glite.wms-utils.exception/project/properties.xml deleted file mode 100755 index 1e49af0..0000000 --- a/org.glite.wms-utils.exception/project/properties.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.wms-utils.exception/project/version.properties b/org.glite.wms-utils.exception/project/version.properties deleted file mode 100755 index cd1e9e7..0000000 --- a/org.glite.wms-utils.exception/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.0.0 -module.age=1 diff --git a/org.glite.wms-utils.exception/src/Exception.cpp b/org.glite.wms-utils.exception/src/Exception.cpp deleted file mode 100644 index 38c086d..0000000 --- a/org.glite.wms-utils.exception/src/Exception.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* ************************************************************************** -* filename : Exceptions.cpp -* author : Alessandro Maraschini -* copyright : (C) 2002 by DATAMAT -***************************************************************************/ - -#include "glite/wmsutils/exception/Exception.h" -#include "glite/wmsutils/exception/exception_codes.h" - -namespace glite { -namespace wmsutils{ -namespace exception { -using namespace std ; -pthread_mutex_t METHOD_MUTEX ; // This mutex is used in order to lock the file for writing log infornation - -/* ********************************* -* Exception Class Implementation -************************************/ -//Constructor/Destructor -Exception::Exception () { - line = 0; -}; - -Exception::~Exception() throw(){ } - -/** -* Exception chainig -*/ -void Exception::push_back (const string& source, int line_number, const string& method){ - stack_strings.push_back (dbgMessage()); - ancestor = what(); - source_file = source; - line = line_number; - method_name = method; - error_message = ""; -} - -Exception::Exception( const std::string& file, int line_number, const std::string& method, int code, const std::string& name) - : error_code(code), exception_name(name){ - source_file = file; - line = line_number; - method_name = method; -}; - -Exception::Exception (const string& source, const string& method, int code, const string& exception) - : error_code(code), exception_name(exception){ - source_file = source; - method_name = method; - // stack= ""; - line = 0; -}; - -int Exception::getCode(){ - if (error_code != 0) return error_code; - else - return WMS_COMMON_BASE; -}; - -const char* Exception::what() const throw(){ - if (!ancestor.empty()) return ancestor.c_str(); - return error_message.c_str(); -}; - -string Exception::getExceptionName(){ - return exception_name; -}; - -void Exception::log(const std::string& logfile) -{ - if (logfile == "") - syslog (LOG_PERROR, (char *)(dbgMessage()).c_str()); - else{ - pthread_mutex_lock( &METHOD_MUTEX); // LOCK - //TBD : test if file exist-->>Create HEADER ?? - ofstream fout ((char *) logfile.c_str() , ios::app ); //Open the file for writing (if it doesn't exist then it will be created) - fout << "\n" << dbgMessage() ; //write (append) the message - fout.close(); //close the file - pthread_mutex_unlock( &METHOD_MUTEX); // UNLOCK - } -}; - -string Exception::printStackTrace(){ - string stack = "" ; - for (unsigned int i = 0 ; i < stack_strings.size() ; i++ ){ - stack+=stack_strings[i] +"\n" ; - } - return stack +dbgMessage(); -}; - -vector Exception::getStackTrace(){ - // make a copy of the stack - vector stack = stack_strings ; - stack.push_back(dbgMessage()) ; - return stack; -}; - -string Exception::dbgMessage(){ - string result ; - result = ""; - // Exception name should be displayed only once - if (stack_strings.size()==0){result +=exception_name;}; - //Adding error msg - if (error_message!="") result +=": " + string(what()); - if (result != "") result+="\n"; - //Adding Source - result +="\tat " + method_name +"[" +source_file; - //Adding line number - if (line!=0){ - char buffer [1024] ; - sprintf (buffer, "%i" , line) ; - result += ":" + string ( buffer ); - } - result +="]" ; - return result; -} - -}}} // Closing namespace - diff --git a/org.glite.wms-utils.exception/src/Makefile.am b/org.glite.wms-utils.exception/src/Makefile.am deleted file mode 100755 index 0c5caac..0000000 --- a/org.glite.wms-utils.exception/src/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -## ********************************************************************* -## * -## * 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_wmsutils_exception.la - -libglite_wmsutils_exception_la_SOURCES = \ - Exception.cpp - -AM_CPPFLAGS = -I$(top_srcdir)/interface \ - -I$(top_srcdir)/src - -MAINTAINERCLEANFILES = Makefile.in *.*~ diff --git a/org.glite.wms-utils.jobid/.cvsignore b/org.glite.wms-utils.jobid/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.wms-utils.jobid/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.wms-utils.jobid/LICENSE b/org.glite.wms-utils.jobid/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.wms-utils.jobid/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -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 -. - -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/ - - diff --git a/org.glite.wms-utils.jobid/Makefile.am b/org.glite.wms-utils.jobid/Makefile.am deleted file mode 100755 index bf956e1..0000000 --- a/org.glite.wms-utils.jobid/Makefile.am +++ /dev/null @@ -1,69 +0,0 @@ -## ********************************************************************* -## * -## * 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 - -EXTRA_DIST = LICENSE - -docdir = $(datadir)/doc/@PACKAGE@-@VERSION@ -doc_DATA = LICENSE - -## Subdirectories list -SUBDIRS = interface src examples - -## 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 - diff --git a/org.glite.wms-utils.jobid/bootstrap b/org.glite.wms-utils.jobid/bootstrap deleted file mode 100755 index ceeb099..0000000 --- a/org.glite.wms-utils.jobid/bootstrap +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/sh - -mkdir -p src/autogen -set -x -aclocal -I project -libtoolize --force -autoheader -automake --foreign --add-missing --copy -autoconf diff --git a/org.glite.wms-utils.jobid/build.xml b/org.glite.wms-utils.jobid/build.xml deleted file mode 100755 index 220b2a6..0000000 --- a/org.glite.wms-utils.jobid/build.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.wms-utils.jobid/configure.ac b/org.glite.wms-utils.jobid/configure.ac deleted file mode 100755 index 0f1deb4..0000000 --- a/org.glite.wms-utils.jobid/configure.ac +++ /dev/null @@ -1,128 +0,0 @@ -# -# 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 -# Version info: $Id$ -# Release: $Name$ -# -# Revision history: -# $Log$ -# Revision 1.15 2004/11/16 15:35:22 eronchie -# Increased version -# -# Revision 1.14 2004/11/16 15:15:45 eronchie -# Increased version -# -# Revision 1.13 2004/09/22 00:25:17 glbuild -# Fixed missing parenthesis -# -# Revision 1.12 2004/09/21 19:22:09 glbuild -# modified module.version -# -# Revision 1.11 2004/08/17 13:46:28 eronchie -# Added interface -# -# Revision 1.10 2004/08/17 13:41:20 eronchie -# Moved out JobIdExceptions.h cjobid.h JobId.h -# Put in interface/glite/wmsutils/jobid -# -# Revision 1.9 2004/08/17 10:40:34 eronchie -# Added optimize option -# -# Revision 1.8 2004/07/27 09:14:19 eronchie -# Removed AC_WMSUTILS_EXCEPTION and AC_GLOBUS_SSL_UTILS checks -# Set directly exception library macro -# -# Revision 1.7 2004/07/21 17:53:36 eronchie -# Moved out org.glite.wms.jobid from org.glite.wms and put in org.glite.wms-utils -# -# -# - -# Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.57) -AC_INIT([GLite WMS Utils Jobid], [1.0.0]) -AC_CONFIG_AUX_DIR([./project]) -AM_INIT_AUTOMAKE([1.6.3 subdir-objects]) -AC_CONFIG_SRCDIR([src/jobid/strmd5.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_wmsutils_exception=no - -AC_GLITE - -GLITE_WMSUTILS_EXCEPTION_LIBS="-L$GLITE_LOCATION/lib -lglite_wmsutils_exception"AC_SUBST(GLITE_WMSUTILS_EXCEPTION_LIBS) - -AC_OPTIMIZE - -# Configuration items -AC_PREFIX_DEFAULT([/opt/glite]) -AM_CONFIG_HEADER([src/autogen/config.h]) -AC_CONFIG_FILES([Makefile]) -AC_CONFIG_FILES([examples/Makefile]) -AC_CONFIG_FILES([interface/Makefile]) -AC_CONFIG_FILES([src/Makefile]) -AC_CONFIG_FILES([src/jobid/Makefile]) - -AC_OUTPUT - diff --git a/org.glite.wms-utils.jobid/examples/Makefile.am b/org.glite.wms-utils.jobid/examples/Makefile.am deleted file mode 100755 index fa9a407..0000000 --- a/org.glite.wms-utils.jobid/examples/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -## ********************************************************************* -## * -## * 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_wmsutils_cjobid.la - -check_PROGRAMS = testjobid - -testjobid_SOURCES = testjobid.c -testjobid_LDADD = \ - $(JOBID) \ - $(GLITE_WMSUTILS_EXCEPTION_LIBS) \ - $(GLOBUS_SSL_THR_LIBS) \ - $(STDCPP) - -AM_CPPFLAGS = -I$(top_srcdir)/src \ - -I$(top_srcdir)/interface \ - $(GLITE_CFLAGS) \ - $(GLOBUS_THR_CFLAGS) - -MAINTAINERCLEANFILES = Makefile.in *~ - diff --git a/org.glite.wms-utils.jobid/examples/testjobid.c b/org.glite.wms-utils.jobid/examples/testjobid.c deleted file mode 100755 index 56f6cba..0000000 --- a/org.glite.wms-utils.jobid/examples/testjobid.c +++ /dev/null @@ -1,33 +0,0 @@ -/* test code for jobid routines */ - -#include -#include - -#include "glite/wmsutils/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; -} diff --git a/org.glite.wms-utils.jobid/interface/Makefile.am b/org.glite.wms-utils.jobid/interface/Makefile.am deleted file mode 100755 index 8737f19..0000000 --- a/org.glite.wms-utils.jobid/interface/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -## ********************************************************************* -## * -## * 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 -## * -## ********************************************************************* - -jobiddir = $(includedir) -nobase_jobid_HEADERS = \ - glite/wmsutils/jobid/cjobid.h \ - glite/wmsutils/jobid/manipulation.h \ - glite/wmsutils/jobid/JobIdExceptions.h \ - glite/wmsutils/jobid/JobId.h - -MAINTAINERCLEANFILES = Makefile.in diff --git a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h b/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h deleted file mode 100755 index b0d07ce..0000000 --- a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h +++ /dev/null @@ -1,136 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_JOBID_H -#define GLITE_WMSUTILS_JOBID_JOBID_H - -/* - * JobId.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - * - */ - -#include -#include - -#include "glite/wmsutils/jobid/cjobid.h" - -typedef struct _edg_wlc_jobid_s* edg_wlc_jobid_t; - -namespace glite { -namespace wmsutils { -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: - * :/ - * - * @ingroup common - * @version 0.1 - * @date 15 April 2002 - * @author Alessandro Maraschini */ - -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 jobid a string representig a classAd expression - * @throws WrongIdException When a string is passed in a wrong format - */ - JobId(const std::string& jobid ) ; - /** - * Instantiates a JobId object from the passed JobId instance - * @param jobid a JobId instance to copy from - * @throws WrongIdException When a string is passed in a wrong format - */ - JobId(const JobId& jobid ); - /** - * Instantiates a JobId object from the passed JobId internal reference - * @param jobid the JobId internal reference - * @throws WrongIdException When a string is passed in a wrong format - */ - JobId(const edg_wlc_JobId& 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; - /** casting operator */ - operator const edg_wlc_JobId() const { return m_JobId; } - /** Operator "=" create a deep copy of the JobId instance*/ - JobId & operator=(JobId const &); - /** Operator "=" create a deep copy of the JobId instance*/ - JobId & operator=(const edg_wlc_JobId &); - /** Retrieve the internal id reference - *@return the JobId internal reference used by some LB methods */ - 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; - /** Operator "<"*/ - friend bool operator<(JobId const& lhs, JobId const& rhs); - /** Operator "=="*/ - 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 wmsutils -} // namespace glite - -#endif // GLITE_WMSUTILS_JOBID_JOBID_H diff --git a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h b/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h deleted file mode 100755 index 42cbdf4..0000000 --- a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_EXCEPTIONS_H -#define GLITE_WMSUTILS_JOBID_EXCEPTIONS_H - -/* - * JobIdExceptions.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - */ - -#include "glite/wmsutils/exception/Exception.h" - -namespace glite { -namespace wmsutils { -namespace jobid { - -/** - * JobIdException - Exception thrown by JobId Class - * @ingroup Common - * @version 0.1 - * @date 15 April 2002 - * @author Alessandro Maraschini -*/ - -class JobIdException : public glite::wmsutils::exception::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: -* :/ */ -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 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 wmsutils -} // namespace glite - -#endif // GLITE_WMSUTILS_JOBID_EXCEPTIONS_H - diff --git a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h b/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h deleted file mode 100755 index e8f84f5..0000000 --- a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h +++ /dev/null @@ -1,109 +0,0 @@ -#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 */ diff --git a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h b/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h deleted file mode 100755 index 9f862ae..0000000 --- a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_MANIPULATION_H -#define GLITE_WMSUTILS_JOBID_MANIPULATION_H - -#include - -namespace glite { -namespace wmsutils { -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 wmsutils -} // namespace glite - -#endif /* GLITE_WMSUTILS_JOBID_MANIPULATION_H */ - -// Local Variables: -// mode: c++ -// End: diff --git a/org.glite.wms-utils.jobid/project/build.number b/org.glite.wms-utils.jobid/project/build.number deleted file mode 100644 index 1936771..0000000 --- a/org.glite.wms-utils.jobid/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build=137 diff --git a/org.glite.wms-utils.jobid/project/build.properties b/org.glite.wms-utils.jobid/project/build.properties deleted file mode 100755 index e69de29..0000000 diff --git a/org.glite.wms-utils.jobid/project/configure.properties.xml b/org.glite.wms-utils.jobid/project/configure.properties.xml deleted file mode 100644 index 04d3b17..0000000 --- a/org.glite.wms-utils.jobid/project/configure.properties.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/org.glite.wms-utils.jobid/project/properties.xml b/org.glite.wms-utils.jobid/project/properties.xml deleted file mode 100755 index 9662658..0000000 --- a/org.glite.wms-utils.jobid/project/properties.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.wms-utils.jobid/project/version.properties b/org.glite.wms-utils.jobid/project/version.properties deleted file mode 100755 index cd1e9e7..0000000 --- a/org.glite.wms-utils.jobid/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.0.0 -module.age=1 diff --git a/org.glite.wms-utils.jobid/src/Makefile.am b/org.glite.wms-utils.jobid/src/Makefile.am deleted file mode 100755 index 5225c64..0000000 --- a/org.glite.wms-utils.jobid/src/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -## ********************************************************************* -## * -## * 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 diff --git a/org.glite.wms-utils.jobid/src/jobid/JobId.cpp b/org.glite.wms-utils.jobid/src/jobid/JobId.cpp deleted file mode 100755 index 273f9f9..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/JobId.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* ************************************************************************** - * filename : JobId.cpp - * author : Alessandro Maraschini - * copyright : (C) 2002 by DATAMAT - ***************************************************************************/ - -#include "glite/wmsutils/jobid/JobId.h" - -#include - -#include "glite/wmsutils/jobid/JobIdExceptions.h" - -namespace glite { -namespace wmsutils { -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 wmsutils -} // namespace glite diff --git a/org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp b/org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp deleted file mode 100755 index 6be40b7..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* ************************************************************************** -* filename : JobIdExecptions.cpp -* author : Alessandro Maraschini -* copyright : (C) 2002 by DATAMAT -***************************************************************************/ - -#include "glite/wmsutils/jobid/JobIdExceptions.h" - -namespace glite { -namespace wmsutils { -namespace jobid { - -using namespace std; -using namespace glite::wmsutils::exception; - -/***************************** -* 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 wmsutils -} // namespace glite - diff --git a/org.glite.wms-utils.jobid/src/jobid/Makefile.am b/org.glite.wms-utils.jobid/src/jobid/Makefile.am deleted file mode 100755 index 7a23118..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -## ********************************************************************* -## * -## * 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_wmsutils_jobid.la libglite_wmsutils_cjobid.la - -libglite_wmsutils_jobid_la_SOURCES = \ - JobId.cpp \ - JobIdExceptions.cpp \ - manipulation.cpp - -libglite_wmsutils_cjobid_la_SOURCES = \ - cjobid.c \ - strmd5.c - -jobidincludedir = $(includedir)/glite/wmsutils/jobid -jobidinclude_HEADERS = \ - strmd5.h - -AM_CPPFLAGS = -I$(top_srcdir)/src \ - -I$(top_srcdir)/interface \ - $(GLITE_CFLAGS) \ - $(GLOBUS_THR_CFLAGS) \ - -D_GNU_SOURCE - -MAINTAINERCLEANFILES = Makefile.in diff --git a/org.glite.wms-utils.jobid/src/jobid/cjobid.c b/org.glite.wms-utils.jobid/src/jobid/cjobid.c deleted file mode 100755 index 2fa0010..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/cjobid.c +++ /dev/null @@ -1,258 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "glite/wmsutils/jobid/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; -} diff --git a/org.glite.wms-utils.jobid/src/jobid/manipulation.cpp b/org.glite.wms-utils.jobid/src/jobid/manipulation.cpp deleted file mode 100755 index cf3a710..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/manipulation.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include - -#include -#include - -#include "glite/wmsutils/jobid/JobId.h" - -using namespace std; - -namespace glite { -namespace wmsutils { -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 wmsutils -} // namespace glite diff --git a/org.glite.wms-utils.jobid/src/jobid/strmd5.c b/org.glite.wms-utils.jobid/src/jobid/strmd5.c deleted file mode 100755 index 0433f55..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/strmd5.c +++ /dev/null @@ -1,118 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include - -#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); -} diff --git a/org.glite.wms-utils.jobid/src/jobid/strmd5.h b/org.glite.wms-utils.jobid/src/jobid/strmd5.h deleted file mode 100755 index c5d76b6..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/strmd5.h +++ /dev/null @@ -1,28 +0,0 @@ -#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 */ diff --git a/org.gridsite.core/.cvsignore b/org.gridsite.core/.cvsignore deleted file mode 100644 index e970233..0000000 --- a/org.gridsite.core/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project \ No newline at end of file diff --git a/org.gridsite.core/CHANGES b/org.gridsite.core/CHANGES deleted file mode 100644 index bf6495c..0000000 --- a/org.gridsite.core/CHANGES +++ /dev/null @@ -1,186 +0,0 @@ -* Mon Apr 25 2005 Andrew McNab -- Avoid build problems when using pre-0.9.7 OpenSSL - (ie with Globus compatibility.) -* Mon Apr 25 2005 Andrew McNab -- ==== GridSite version 1.1.8 ==== -* Mon Feb 28 2005 Andrew McNab -- Fix to GRSTgaclUndenyPerm in gridsite.h (bug #7135) - from Marco Sottilaro -* Mon Feb 28 2005 Andrew McNab -- ==== GridSite version 1.1.7 ==== -* Thu Feb 24 2005 Andrew McNab -- Add more sanity checking (signatures, dates, issuer,) - holder) to VOMS attribute parser. -* Mon Feb 21 2005 Andrew McNab -- Add bugfix for Bug #6357 from Fabrizio Pacini - to fix delegation proxy - cache names in OpenSSL 0.9.7. -* Sun Feb 20 2005 Andrew McNab -- Add basic VOMS support (signature checking not yet - in) for X.509 Attribute Certificates. -* Tue Feb 8 2005 Andrew McNab -- ==== GridSite version 1.1.6 ==== -* Tue Feb 8 2005 Andrew McNab -- Include GRSTx509MakeProxyFileName() and - GRSTx509StringToChain() (code to used hashes in cached - proxy file names.) Bug #6357 -- Change ordering of output proxy file produced by - GRSTx509CacheProxy so proxy private key is the 2nd PEM - encoded block (rather than at the end.) Bug #6365 -- Add libgridsite_globus[.so|.a] in preparation for - separate Globus OpenSSL and system OpenSSL versions -* Tue Feb 8 2005 Andrew McNab -- ==== GridSite version 1.1.5 ==== -* Tue Dec 14 2004 Andrew McNab -- Patch from Daniel Kouril to allow - switching Globus vs system OpenSSL libraries/headers. -* Tue Dec 14 2004 Andrew McNab -- ==== GridSite version 1.1.4 ==== -* Mon Nov 15 2004 Andrew McNab -- Back out of (most of) redone VOMS support for committing - to JRA1 CVS. -* Thu Oct 19 2004 Andrew McNab -- ==== GridSite version 1.1.3 ==== -* Thu Oct 19 2004 Andrew McNab -- Fix Bug #5203 from Martijn Steenbakkers - by fixing GACLparseEntry in gridsite-gacl.h -- Change to C style comments (mostly) in gridsite.h and - gridsite-gacl.h (fixes part of Bug #4222 from - ) -- Fix Bug #4225 from in - GRSTgaclCredsFree() -- Add GRSTx509CachedProxyFind() and findproxyfile - command to allow proxies to be found in proxy cache -- Change GRSTx509StoreProxy() to GRSTx509CacheProxy() for - consistency with this and GRSTx509CachedProxyKeyFind() -* Wed Oct 18 2004 Andrew McNab -- ==== GridSite version 1.1.2 ==== -* Tue Oct 19 2004 Andrew McNab -- Copy code from delegation prototype into grst_x509.c - and include htproxyput.c and grst-delegation.c - optional targets (which depend on gSOAP.) -* Wed Oct 13 2004 Andrew McNab -- Include per-file patch to GRSTgaclFileFindAclname: - .gacl:FILENAME controls FILENAME if it exists. -* Tue Jul 27 2004 Andrew McNab -- ==== GridSite version 1.1.1 ==== -* Tue Jul 27 2004 Andrew McNab -- Include HTTP Downgrade support in htcp -* Sat Jul 24 2004 Andrew McNab -- Include HTTP Downgrade support in mod_gridsite. -* Thu Jul 22 2004 Andrew McNab -- Begin development version 1.1.x -* Thu Jul 22 2004 Andrew McNab -- ==== GridSite version 1.1.0 ==== -* Mon Jul 19 2004 Andrew McNab -- Changes in line with EGEE SCM - most importantly - the top level directory becomes org.gridsite.core -* Mon Jul 19 2004 Andrew McNab -- ==== GridSite version 1.0.3 ==== -* Mon Jun 28 2004 Andrew McNab -- In GRSTx509CheckChain() and GRSTx509CompactCreds() - we now accept the first cert in a chain as a CA - even if it is X509v3 but without the CA bits set. - (On the basis that the first chain is from the - administrator-installed CA files store.) -* Sun Jun 27 2004 Andrew McNab -- ==== GridSite version 1.0.2 ==== -* Sun Jun 27 2004 Andrew McNab -- Fix for Bug #2860 (so can now read DN Lists over - HTTPS when have no user certificate if relevant - .gacl gives permission but not ) -- Include gridsite-gacl.h mods from Daniel Kouril - to fix faulty definitions - of GACLnewEntry() and GACLnewAcl() and to make - a legacy non-static GACLparseEntry() wrapper. -* Thu Jun 17 2004 Andrew McNab -- Changes to mod_gridsite.h for Fedora Core 2 / - Apache 2.0.49+ mod_ssl changes (mod_ssl-private.h) -* Wed Jun 9 2004 Andrew McNab -- Incorporate EGEE CVS layout changes in production - branch. -* Wed Jun 9 2004 Andrew McNab -- ==== GridSite version 1.0.1 ==== -* Sun Dec 14 2003 Andrew McNab -- 1.0.0 is first full production release - (development now in 1.1.x branch) -* Sun Dec 14 2003 Andrew McNab -- ==== GridSite version 1.0.0 ==== -* Sat Dec 13 2003 Andrew McNab -- Remove need for modified mod_ssl-gridsite: now - mod_gridsite intercepts callbacks with wrappers. -- Add GRSTx509NameCmp() which compares string reps of - DNs across OpenSSL version changes (ie Email=) -* Fri Dec 12 2003 Andrew McNab -- ==== GridSite version 0.9.11 ==== -* Thu Dec 11 2003 Andrew McNab -- Simplify checking of cert/proxy chain in - mod_ssl-gridsite: rely on mod_ssl/OpenSSL more. -* Wed Dec 2 2003 Andrew McNab -- ==== GridSite version 0.9.10 ==== -* Tue Dec 1 2003 Andrew McNab -- GACL ignores leading/trailing spaces in values. -* Sat Nov 29 2003 Andrew McNab -- Better directory listing in htcp. -- htcp now built as separate binary RPM. -- gridsite-admin.cgi upload now redirects to same - directory after upload (Bug #1939); allows - optional new name for file (Request / Bug #1940); - and has better checking of ../dir/file attacks. -* Sat Nov 29 2003 Andrew McNab -- ==== GridSite version 0.9.8 ==== -* Thu Nov 27 2003 Andrew McNab -- Shiv's updated GACL editor, with redirects. -* Wed Nov 26 2003 Andrew McNab -- Include Daniel Stenberg's roffit script to make - HTML man pages for htcp and urlencode. -- Various fixes found when installing GridPP WWW. -* Wed Nov 26 2003 Andrew McNab -- ==== GridSite version 0.9.7 ==== -* Thu Nov 20 2003 Andrew McNab -- Major updates to htcp (htrm/htls/htll) -- GACL now recurses subdirectories when examining - the DN List directories path. -* Sat Nov 15 2003 Andrew McNab -- ==== GridSite version 0.9.6 ==== -* Fri Nov 14 2003 Andrew McNab -- Function call fixes in grst-admin.cgi -* Thu Nov 13 2003 Andrew McNab -- Add htcp (curl-url-get reborn) -* Thu Nov 13 2003 Andrew McNab -- ==== GridSite version 0.9.5 ==== -* Thu Nov 13 2003 Andrew McNab -- More grst-admin.cgi GACL updates from Shiv. -- .gacl security improvements to grst-admin.cgi from - Shiv Kaushal and Peter Moore. -* Tue Nov 11 2003 Andrew McNab -- One RPM instead of three, with version from VERSION -- Textarea for HTML/Text editing now 80 columns -* Mon Nov 10 2003 Andrew McNab -- Add delegation level and GridSiteGSIProxyLimit - support. -- Add GridSiteAdminList handling to mod_gridsite - and real-gridsite-admin.cgi -* Sun Nov 9 2003 Andrew McNab -- Add directory create/delete, and file/dir rename. -- Add ZIP listing/unzipping via external unzip - utility from http://www.info-zip.org/pub/infozip/ -* Mon Nov 3 2003 Andrew McNab -- Include next version of Shiv's GACL editor. -- Add rpm-usr target to Makefile, to make RPMs - out-of-the-box compatible with RH9 and its Apache2 -- Use REMOTE_DOUBLE_REV for GACL hostname creds in - mod_gridsite.c/mod_gridsite_perm_handler() -* Sun Oct 26 2003 Andrew McNab -- Include GACL editor in real-gridsite-admin.cgi - from Shiv Kaushal -* Sun Oct 26 2003 Andrew McNab -- Reorganise into a single build tree, including - Apache 2.0 .h files to remove circular dependency. -* Sun Oct 26 2003 Andrew McNab -- ==== GridSite version 0.9.4 ==== -* Sun Oct 19 2003 Andrew McNab -- Include many pieces of GridSite code from 0.3.x (CGI) - fileGridSite and mod_gridsite 0.9.0 -* Sun Oct 19 2003 Andrew McNab -- ==== GridSite version 0.9.3 ==== diff --git a/org.gridsite.core/INSTALL b/org.gridsite.core/INSTALL deleted file mode 100644 index 3da6cde..0000000 --- a/org.gridsite.core/INSTALL +++ /dev/null @@ -1,39 +0,0 @@ -BUILDING/INSTALLING GRIDSITE -============================ - -For more detailed instructions, see the install.html file, either -in the ./doc subdirectory in the sources, in the directory -gridsite-VERSION/html of the docs directory when GridSite is -installed, or http://www.gridsite.org/1.1.x/install.html - -GridSite is currently only supported on Linux, but should be -trivially portable to other Unix platforms where the GNU build -tools are available. - -When building from source, two routes are available: building -with Make or with RPM. - -BUILDING WITH MAKE -================== - -make -make install - -will build all components and install them all under the default -locations of /usr/local/[lib|bin|include|sbin] The default prefix -/usr/local is set by the prefix variable in the top level Makefile - -BUILDING WITH RPM -================= - -For RedHat Linux and derivatives, building with RPM is recommended. -The command - -make rpm - -will build the gridsite and htcp binary RPMs in the directory -../RPMTMP/RPMS/i386 relative to the working directory. A SRPM is -put into ../RPMTMP/SRPMS - -Building with RPM uses the default prefix /usr, although the -resulting RPMs are relocatable to other hierarchies. diff --git a/org.gridsite.core/LICENSE b/org.gridsite.core/LICENSE deleted file mode 100644 index ce67433..0000000 --- a/org.gridsite.core/LICENSE +++ /dev/null @@ -1,47 +0,0 @@ -Copyright (c) 2002-4, Andrew McNab and Shiv Kaushal, -University of Manchester. All rights reserved. - -Redistribution and use in source and binary forms, with or -without modification, are permitted provided that the following -conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. - - -Clearly marked portions of the published GridSite source code -are derived from Apache httpd or its modules, and are covered -by the Apache Software License: - -Copyright 2001-2004 The Apache Software Foundation - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/org.gridsite.core/README b/org.gridsite.core/README deleted file mode 100644 index 62730a6..0000000 --- a/org.gridsite.core/README +++ /dev/null @@ -1,3 +0,0 @@ -See INSTALL for build and installation instructions, and -the Documentation section of http://www.gridsite.org/ -for configuration and usage guides. diff --git a/org.gridsite.core/VERSION b/org.gridsite.core/VERSION deleted file mode 100644 index 1b84e6f..0000000 --- a/org.gridsite.core/VERSION +++ /dev/null @@ -1,4 +0,0 @@ -MAJOR_VERSION=1 -MINOR_VERSION=1.1 -PATCH_VERSION=1.1.8 -VERSION=$(PATCH_VERSION) diff --git a/org.gridsite.core/build.xml b/org.gridsite.core/build.xml deleted file mode 100644 index 0d98576..0000000 --- a/org.gridsite.core/build.xml +++ /dev/null @@ -1,270 +0,0 @@ - - - - - - - Ant build file to build the Gridsite Core Component - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${global.prefix} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - New tag is ${cvs.label} - - - - - - - - - - - - - - - - - - New tag is ${cvs.label} - - - - - - - - - - - - - - - - - - diff --git a/org.gridsite.core/doc/README.htcp-bin b/org.gridsite.core/doc/README.htcp-bin deleted file mode 100644 index ac546fc..0000000 --- a/org.gridsite.core/doc/README.htcp-bin +++ /dev/null @@ -1,13 +0,0 @@ -Binaries (and links) are in ./bin; man pages are in ./man/man1 - -Install by copying binaries/links onto your path, or by copying htcp -and making symbolic links to htcp from htls, htll, htrm and htmkdir. - -All the .1 man pages should be copied to a suitable ./man/man1 -directory on your man path. - -If you just want to install htcp in /usr/local, then unpacking this -tgz file in /usr/local should do the trick. (Delete this README when -you're finished!) - -For more about htcp see http://www.gridsite.org/ diff --git a/org.gridsite.core/doc/admin.html b/org.gridsite.core/doc/admin.html deleted file mode 100644 index 1f7f422..0000000 --- a/org.gridsite.core/doc/admin.html +++ /dev/null @@ -1,103 +0,0 @@ -GridSite Admin Guide - -

GridSite Admin Guide

- -

-This Guide is intended for people administrating areas of GridSite -websites or fileservers, or managing GridSite's DN List groups - that is, -how to use GridSite to manage other people's access to parts of the site - -for example, people's write access to areas devoted to specific subprojects. - -

- There is a separate -User Guide - which explains how to authenticate to the server with X.509 certificates, -and how to manage files via a standard web browser or with command-line -HTTPS clients. You should be familiar with the User Guide to fully -understand this Admin Guide. - -

- You may also find the -Config Guide - useful to understand how the Apache webserver is configured with GridSite -extensions. If you are also the Apache webmaster for your site, you will -definitely need to read the Config Guide to create the httpd.conf file. -However, if you only need to manage webpages and files, then this Admin -Guide and the User Guide should be sufficient. - -

Groups and DN Lists

- -

-GridSite defines groups of people using plain text DN Lists - that is, lists -of people's certificate DNs. Each DN List has a URL which uniquely -identifies the list (and may also allow other sites to obtain the list and -use it themselves.) For example, the list of all GridPP members is -https://www.gridpp.ac.uk/dn-lists/gridpp (note that it's https:// not -http:// - this means that other sites that download the list can check the -certificate of www.gridpp.ac.uk and know they're talking to the -authoritative source of the lists.) - -

-The system can also have a number of other DN Lists which are associated with -specific groups of people and perhaps with specific areas of responsibility -of the website. If the DN List directory URI is /dn-lists/ then -there is a full list of the DN Lists exported by the server at that URI -(for example, https://www.gridpp.ac.uk/dn-lists/ ) - -

-If you have permission to modify a DN List, you can start changing it by -going to /dn-lists/ (via HTTPS), using the "Manage directory" -button and finding the URL of your DN List in the listings. You may -need to go down into a subdirectory to find your list. For -example, https://www.gridpp.ac.uk/dn-lists/atlas is in the atlas -subdirectory of /dn-lists/ (You may wish to bookmark the listing of such -a directory if you frequently work with one.) - -

-DN List directories are managed by the ACLs described in the next section, -and if you have write permission, you can edit the lists already there, and -add new lists with the same prefix (this means you can readily create your -own subgroups.) - -

Access Control Lists

- -

-DN Lists appear in the Grid Access Control Lists (GACL) used by GridSite. -These are stored as .gacl files in directories: if the .gacl file is -present, it governs access to the directory; if it is absent, then the -parent directories are searched upwards until a .gacl is found. - -

-The GridSite GACL Reference explains the XML format -of these files, but they -can be edited using the ACL editor built into the GridSite system by people -who have the Admin permission within the ACL. - -

-If you have this permission in a given directory, when you view directory -listings or files in that directory you will see the option "Manage -Directory" in the page footer. This allows you to get a listing of the -directory and the .gacl file will appear at the top if it's present. If not, -then there will be a button to create a new .gacl file with the same -permissions as have been inherited by that directory from its parent. - -

-GACL allows quite complex conditions to be imposed on access, but normally -you can think of an ACL as being composed of a number of entries, each of -which contains one condition (the required credential) and a set of allowed -and denied permissions. - -

-Credentials can be individual user's certificate names or whole groups of -certificate names if a DN List is given. (You can also specifiy hostname -patterns using Unix shell wildcards (eg *.ac.uk) or EDG VOMS attribute -certificates - see the GACL Reference for details.) - -

-Permissions can be Admin (edit the ACL), Write (create, modify or delete -files), List (browse the directory) or Read (read files.) Permissions can be -allowed or denied. If denied by any entry, the permission is not available -to that user or DN List (depending on what credential type was associated -with the Deny.) - - diff --git a/org.gridsite.core/doc/build-apache2.sh b/org.gridsite.core/doc/build-apache2.sh deleted file mode 100644 index 507be31..0000000 --- a/org.gridsite.core/doc/build-apache2.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2002-3, Andrew McNab, University of Manchester -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or -# without modification, are permitted provided that the following -# conditions are met: -# -# o Redistributions of source code must retain the above -# copyright notice, this list of conditions and the following -# disclaimer. -# o 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. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. -# -#--------------------------------------------------------------- -# For more information about GridSite: http://www.gridsite.org/ -#--------------------------------------------------------------- -# -# This script takes an Apache .tar.gz as the single command line argument, -# unpacks the file, modifies the httpd.spec it contains to work without -# the "-C" option to configure (which RedHat 7.3 doesnt like) and -# outputs source and binary RPMs in SRPMS and RPMS/i386 - -if [ "$1" = "" ] ; then - echo Must give a tar.gz file name - exit -fi - -export MYTOPDIR=`pwd` - -if [ -x /usr/bin/rpmbuild ] ; then - export RPMCMD=rpmbuild -else - export RPMCMD=rpm -fi - -echo "$1" | grep '\.tar\.gz$' >/dev/null 2>&1 -if [ $? = 0 ] ; then # a gzipped source tar ball - - rm -Rf $MYTOPDIR/BUILD $MYTOPDIR/BUILDROOT $MYTOPDIR/SOURCES - mkdir -p $MYTOPDIR/SOURCES $MYTOPDIR/SPECS $MYTOPDIR/BUILD \ - $MYTOPDIR/SRPMS $MYTOPDIR/RPMS/i386 $MYTOPDIR/BUILDROOT - - shortname=`echo $1 | sed 's:^.*/::' | sed 's:\.tar\.gz$::'` - - cp -f $1 SOURCES - - tar zxvf SOURCES/$shortname.tar.gz $shortname/httpd.spec - cp -f $shortname/httpd.spec SPECS - - sed -e 's/configure -C /configure /' \ - SPECS/httpd.spec >SPECS/httpd-2.spec - - $RPMCMD --define "_topdir $MYTOPDIR" \ - -ba --buildroot $MYTOPDIR/BUILDROOT SPECS/httpd-2.spec - - exit -fi - -echo I dont recognise the file type (must be .tar.gz) - -exit diff --git a/org.gridsite.core/doc/config.html b/org.gridsite.core/doc/config.html deleted file mode 100644 index 825bf49..0000000 --- a/org.gridsite.core/doc/config.html +++ /dev/null @@ -1,192 +0,0 @@ -GridSite Config Guide - -

GridSite Config Guide

- -

-This Guide is intended for webmasters setting up -GridSite with an Apache 2.0 -webserver. We assume you have root access to the server machine to do this. -There is a separate Admin Guide for -people administrating areas of GridSite -websites or fileservers, or managing GridSite's DN List groups. That is, for -people managing files on the server rather than the server itself. - -

Installation

- -

-We assume you have installed Apache 2.0 and GridSite, using the -Building and Installation Guide where necessary. -This Config Guide assumes installation has been done under /usr. For an -alternative tree like /usr/local, the relative paths should be the same. - -

-Installation should have given you an Apache 2.0 httpd binary at -/usr/sbin/httpd and a set of standard Apache 2.0 modules in -/usr/lib/httpd/modules/ including the standard mod_ssl -and our mod_gridsite.so module. - -

-GridSite also includes some commands and man pages in /usr/bin and -/usr/share/man/man1: urlencode and -htcp. - -

Certificates

- -

-You must also install the CA root certificates of the CA's -used by the users you wish to talk to. These should be installed in -/etc/grid-security/certificates as files like 01621954.0, and RPMs and tar -files for many common European and North American CAs are available from - -https://datagrid.in2p3.fr/distribution/datagrid/security/ - -

-This location also has VOMS server certificate RPMs which install into -the /etc/grid-security/vomsdir directory. You may also manually install VOMS -server certificates into that directory with any filename. (GridSite -currently parses the certificate itself when looking for a match, rather -than checking the filename.) - -

-The server itself needs a certificate to supply to clients that use HTTPS -connections. You should apply for this from your Certification Authority -(for example, the UK e-Science -CA) and your request must use the advertised hostname of your server -(the one that appears in URLs and not, for instance, the canonical name of -the host itself.) This advertised hostname should appear in the -Distinguished Name of your request. (For example -/C=UK/O=eScience/OU=Manchester/L=HEP/CN=www.gridpp.ac.uk) For compatability -with standard browsers, the /CN= component should not include any -Globus-style service name (so not /CN=host/www.gridpp.ac.uk) If -possible, you should also include the advertised hostname as a DNS Subject -Alternative Name. Consult your CA first if you're in any doubt about how to -compose your certificate request. - -

-Once you've got your certificate, -Apache uses the certificate and private key in PEM format. If you obtained -your certificate and key in PKCS#12 or .p12 format (eg by exporting from a web -browser), you can convert the .p12 file to .pem with the following commands: -

-openssl pkcs12 -in ck.p12 -clcerts -nokeys -out hostcert.pem
-openssl pkcs12 -in ck.p12 -nodes  -nocerts -out hostkey.pem
-
- -

-Copy the PEM files to /etc/grid-security/ as hostcert.pem (which -should be world readable) and hostkey.pem (which should only be readable by -root): - -

-chown root.root hostkey.pem hostcert.pem
-chmod 400 hostkey.pem
-chmod 444 hostcert.pem
-
- -

httpd.conf

- -

-/etc/httpd/conf/httpd.conf is the key to configuring the Apache 2.0 -webserver. The directives in this file determine which files the server will -publish, how they are handled, which areas are writeable and who can access -them. Through mod_gridsite.so, the GridSite system itself is configured by -directives in this file. - -

-The easiest way to get started is to examine the example httpd.conf files we -provide. - - - -

httpd-fileserver.conf

- -

-httpd-fileserver.conf is an example -configuration file to use Apache/GridSite as a read/write HTTP(S) -fileserver, including comments on how to get the server up and running. - -

httpd-webserver.conf

- -

-httpd-webserver.conf is an example -configuration file to use Apache/GridSite as a Web Server -(that is, primarily for interactive use with a browser) -including comments on how to get the server up and running. - -

GridSite Directives

- -

-The mod_gridsite reference lists all the GridSite -httpd.conf directives. - -

-To start serving files, make a directory /var/www/htdocs owned by -nobody.nobody, including the .gacl access control file described below, -and add the following directive to the HTTPS <Directory> section: - -

-GridSiteMethods GET PUT DELETE - -

-If you wish to accept Globus GSI Proxies as well as full X.509 user -certificates, set GridSiteGSIProxyLimit to the depth of proxy you -wish to accept. (As a _rough_ guide: 0=No Proxies; 1=Proxy on user's -machine; 2=Proxy owned by running Globus job; 3=Proxy delegated by a -Globus job.) - -

GACL access control

- -

-The GACL reference explains the XML access -control files used by GridSite. These allow flexible policies to be written, -in terms of X.509 user certificates, GSI proxies, VOMS attribute -certificates, DN List groups and DNS hostnames. - -

-For example, to give all clients read and list permission: -

-

-<gacl>
-<entry>
-  <any-user/>
-  <allow><read/><list/></allow>
-</entry>
-</gacl>
-
- -

-To enable writing, add DN List, Person or VOMS entries to the file. -For example: - -

-

-<gacl>
-<entry>
-  <any-user/>
-  <allow><read/><list/></allow>
-</entry>
-<entry>
-  <person>
-  <dn>/C=UK/O=eScience/OU=Manchester/L=HEP/CN=Andrew McNab</dn>
-  </person>
-  <allow><write/></allow>
-</entry>
-</gacl>
-
- -

-The GACL file that governs a directory is stored as .gacl in that directory. -If no .gacl is present, then GridSite will search the parent directories in -ascending order until one is found. - - - - diff --git a/org.gridsite.core/doc/findproxyfile.1 b/org.gridsite.core/doc/findproxyfile.1 deleted file mode 100644 index ae2f944..0000000 --- a/org.gridsite.core/doc/findproxyfile.1 +++ /dev/null @@ -1,63 +0,0 @@ -.TH findproxyfile 1 "October 2004" findproxyfile "FINDPROXYFILE Manual" -.SH NAME -.B findproxyfile -\- returns full path to GSI Proxy file -.SH SYNOPSIS -.B findproxyfile -[--proxycache=PATH] [--delegation-id=ID] [--user-dn=DN] [--outsidecache] -.SH DESCRIPTION -.B findproxyfile -returns full path to a GSI Proxy file, either in the proxy cache maintained -by the GridSite G-HTTPS and delegation portType functions, or in other -standard places. - -If a User DN is given -.B findproxyfile -uses the value of the -.B --proxycache -argument, the GRST_PROXY_PATH or the -compile time default to detemine the location of the proxy cache directory. -The directory is searched for a proxy having the given User DN and -Delegation ID. (If no Delegation ID is specificed, then the default value is -used.) - -If -.B findproxyfile -does not find a proxy or if a User DN is not given, but -.B --outsidecache -was given, then the environment variable X509_USER_PROXY and the standard -location /tmp/x509up_uUID are searched as well. - -.SH OPTIONS - -.IP "--proxycache=PATH" -Give the path of the proxy cache directory explicitly, overriding the -default and the GRST_PROXY_PATH environment variable if present. - -.IP "--delegation-id=ID" -The optional delegation ID is search for in the proxy cache in addition to -the User DN. If absent, the default Delegation ID value is searched for. - -.IP "--user-dn=DN" -The DN of the full user certificate associated with the proxy to be searched -for in the proxy cache. (This is not the DN of any proxy earlier in the -chain: it is a the DN of a certificate issued by a recognised CA.) - -.IP "--outsidecache" -If a User DN is not given, or a proxy not found in the cache, then search -for a proxy using X509_USER_PROXY environment variable and file name of -form /tmp/x509up_uUID as well. - -.SH RETURN VALUE -If a proxy is found, its full path is output on standard out. - -.SH EXIT CODES -0 is returned on succcess. Non-zero otherwise. - -.SH BUGS -In this version, no attempt is made to verify or validate the proxies. - -.SH AUTHOR -Andrew McNab - -findproxyfile is part of GridSite: http://www.gridsite.org/ diff --git a/org.gridsite.core/doc/gacl.html b/org.gridsite.core/doc/gacl.html deleted file mode 100644 index 40efdd2..0000000 --- a/org.gridsite.core/doc/gacl.html +++ /dev/null @@ -1,84 +0,0 @@ -GridSite: Grid Access Control Language - -

GridSite: Grid Access Control Language

- -

-GACL is the authorization policy language used by -GridSite GACL allows -policies to be written in terms of common Grid credentials: X.509 -identities, GSI proxies, VOMS attribute certificates and lists of X.509 -identities. - -

-GridSite both uses GACL policies and provides a GACL manipulation API for -C/C++ in the GridSite library. - -

Credentials

- -

-In GridSite 1.0.x, four credential types are supported: - -

-<person> -<dn>/O=Grid/CN=Name</dn> -</person> - -

-<voms> -<fqan>/vo.dom.ain/group</fqan> -</voms> - -

-<dn-list> -<url>https://www.vo.dom.ain/dn-lists/group</url> -</dn-list> - -

-<dns> -<hostname>host*.dom.ain</hostname> -</dns> - -

Permissions

- -

-Five permissions are supported: Admin, Write, List, Exec and Read. Admin is -permission to modify the authorization policy itself, but applications can -map the other permissions to local methods as appropriate to their -environment. For filesystems and fileservers, Write, List and Read have -their usual meanings: creating or modifying files or directories; browsing -directories; reading files. Exec is not used by GridSite itself, and -applications are free to give it a meaning within their own contexts. - -

-In 1.0.x, only per-directory GACL files are supported, and the file is stored -in the directory in question, or in one of its parent directories. (GridSite -searches upwards until it finds one.) - -

-In GACL files, the permissions are represented by single tags: -<admin/>, <write/>, <list/>, <exec/>, <read/>. -Permission -tags are contained within Allow or Deny blocks. For example: -<allow><read/><list/></allow> or -<deny><admin/></deny>. - -

Entries

- -

-Entries associate credentials with permission statements. Entries consist of -one or more credential blocks, and either an Allow or a Deny block, or both. -If multiple credentials are present in one entry, they must all be held by a -user to receive the association permissions. (So Entries provide logical AND -of credentials.) - -

Access Control Lists

- -

-ACLs consist of a list of one or more Entry blocks. When a user's credentials -are compared to the ACL, the permissions given to the user by Allow blocks -are recorded, along with those forbidden by Deny blocks. When all entries -have been evaluated, any forbidden permissions are removed from those -granted. (So Deny always wins over Allow, even between different Entries, -but otherwise ACLs provide logical OR of credentials.) - - diff --git a/org.gridsite.core/doc/htcp.1 b/org.gridsite.core/doc/htcp.1 deleted file mode 100644 index 984aaaf..0000000 --- a/org.gridsite.core/doc/htcp.1 +++ /dev/null @@ -1,147 +0,0 @@ -.TH htcp 1 "July 2004" htcp "HTCP Manual" -.SH NAME -.B htcp, htrm, htls, htll, htmkdir -\- get, put, delete or list HTTP/HTTPS files or directories -.SH SYNOPSIS -.B htcp [options] -.I Source-URL[s] [Destination URL] -.SH DESCRIPTION -.B htcp -is a client to fetch files or directory listings from remote servers using -HTTP or HTTPS, or to put or delete files or directories onto remote servers -using HTTPS. htcp is similar to scp(1), but uses HTTP/HTTPS rather than ssh -as its transfer protocol. - -When talking to an HTTPS server, htcp can run "anonymously", with a -standard X.509 user certificate and key, or with a GSI Proxy. This makes -htcp very useful in Grid environments where many users have certificates -and where jobs and users have access to GSI proxies. - -.SH URLs -htcp supports the file:, http: and https: URL schemes as sources and -destinations. If no scheme is given, the URL scheme is assumed to be file: -and relative to the current directory if not an absolute path. - -If multiple sources are given, they will be used in turn and the destination -must be a directory (directories are indicated by a trailing /) However, -source and destination cannot both refer to remote servers. - -.SH OPTIONS -.IP "-v/--verbose" -Turn on debugging information. Used once, this option will enable htcp's -messages to stderr. Used twice, will also enable the underlying libcurl -messages. - -.IP "--delete" -Instead of copying files, delete all the URLs given on the command line. -Calling the program as htrm has the same effect. - -.IP "--list" -.br -Instead of copying files, output lists of files located in the URL-directories -given on the command line. Calling the program as htls has the same effect. - -.IP "--long-list" -Instead of copying files, output long listings of files located in the -URL-directories given on the command line. If available, the size in bytes -and modification time of each file is given. Calling the program as -htll has the same effect. - -.IP "--mkdir" -Instead of copying files, attempt to create a directory on a remote server -with HTTP PUT. The server must support the convention that PUT to a URL with -a trailing slash means create a directory. No file body is sent. Calling the -program as htmkdir has the same effect. - -.IP "--anon" -.br -Do not attempt to use X.509 user certificates or GSI proxies to authenticate -to the remote HTTPS server. This means you are "anonymous", but the server's -identity may still be verified and the connection is still encrypted. - -.IP "--cert and --key " -Path to the PEM-encoded -X.509 or GSI Proxy user certificate and key to use for HTTPS -connections, intead of "anonymous mode." If only one of --key or --cert -is given, then that will be tried for both. If neither is given, then the -following order of precedence is used: -the file name held by the variable X509_USER_PROXY; the file -/tmp/x509up_uID (with Unix UID equal to ID); the file names held by -X509_USER_CERT / X509_USER_KEY; the files ~/.globus/usercert.pem and -~/.globus/userkey.pem (where ~/ is the home directory of the user.) - -.IP "--capath " -Path to the PEM-encoded CA root certificates to use when -verifying remote servers' host certificates in HTTPS connections. Ideally -this should be a directory of hash.0 files as described in the OpenSSL -verify(1) man page, but a file may be used instead. If --capath is not -given, the value of the environment variable X509_CERT_DIR will be tried. -If this is not valid, then /etc/grid-security/certificates will be used. - -.IP "--no-verify" -Do not use CA root certificates to verify remote servers' host certificates. -This is useful for testing sites before their certificate is set up properly, -but leaves you vulnerable to "man in the middle" attacks by hostile servers -masquerading as your target. - -.IP "--downgrade-size " -Try to use HTTP-Downgrade for HTTPS URLs. Compatible servers will perform -authentication and authorization on the HTTPS connection and then redirect -to HTTP for the GET or PUT file transfer. htcp makes the HTTP request using -the GRID_AUTH_ONETIME single-use passcode obtained via HTTPS. The downgrade -option will be ignored for directory operations, HTTP URLs, or if the file -size is less than the value given. If a downgraded transfer isn't possible, -a normal HTTPS data transfer will be done. - -.SH FILES -.IP /tmp/x509up_uID -Default GSI Proxy file for Unix UID equal to ID. - -.IP /etc/grid-security/certificates -Default location for trusted Certification Authority root certificates to use -when checking server certificates. - -.IP /tmp/.ca-roots-XXXXXX -Prior to 7.9.8, the underlying curl library did not support the CA root -certificates directory. -If built with an old version of libcurl, htcp will concatenate the -certificates in the CA roots directory into a unique temporary file and use -that. - -.SH ENVIRONMENT - -.IP X509_CERT_DIR -Holds directory to search for Certification Authority root certificates when -verifying server certificates. (Tried if --capath is not given on the -command line.) - -.IP X509_USER_PROXY -Holds file name of a GSI Proxy to use as user certificate. (Tried if --cert or ---key are not given on the command line.) - -.IP "X509_USER_CERT and X509_USER_KEY" -Holds file name of X.509 user certificate and key. (Tried if X509_USER_PROXY -is not valid.) - -.SH EXIT CODES -0 is returned on complete success. Curl error codes are returned when -reported by the underlying curl library, and CURLE_HTTP_RETURNED_ERROR (22) -is returned when the HTTP(S) server returns a code outside the range 200-299. -The manpage libcurl-errors(3) lists all the curl error codes. - -.SH TO DO -Recursive copying. Server-side wildcards. Parallel streams. Error recovery. - -.SH BUGS -Not enough beta testing (hint hint...) - -.SH AUTHOR -Andrew McNab - -htcp is part of GridSite: http://www.gridsite.org/ -.SH "SEE ALSO" -.BR scp(1), -.BR curl(1), -.BR wget(1), -.BR verify(1), -.BR libcurl-errors(3) diff --git a/org.gridsite.core/doc/htll.1 b/org.gridsite.core/doc/htll.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htll.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htls.1 b/org.gridsite.core/doc/htls.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htls.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htmkdir.1 b/org.gridsite.core/doc/htmkdir.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htmkdir.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htrm.1 b/org.gridsite.core/doc/htrm.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htrm.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/httpd-fileserver.conf b/org.gridsite.core/doc/httpd-fileserver.conf deleted file mode 100644 index 9bd51e2..0000000 --- a/org.gridsite.core/doc/httpd-fileserver.conf +++ /dev/null @@ -1,147 +0,0 @@ -############################################################################## -## GridSite httpd-fileserver.conf - Andrew McNab -## -## Example configuration file for GridSite as an HTTP(S) fileserver. -## -## For GridSite documentation, see http://www.gridsite.org/ -## -## This file should be renamed /etc/httpd/conf/httpd.conf and Apache -## restarted to use Apache2/GridSite as a simple HTTP(S) fileserver. -## -## You do not need to install the GridSite mod_ssl.so module if you -## do not wish to use Globus Proxies or VOMS attributes, but you must -## have the mod_gridsite.so in /usr/lib/httpd/modules -## -## We're assuming you have (a) the host's hostcert.pem and hostkey.pem -## in /etc/grid-security/ and (b) the Certification Authorities' you -## trust have their root certs in /etc/grid-security/certificates -## -## (You can get RPMs for many European and North American Grid CAs -## from https://datagrid.in2p3.fr/distribution/datagrid/security/ ) -## -## If you want to use DN Lists in ACLs, they should be placed/downloaded -## in /etc/grid-security/dn-lists/ -## -## To start serving files, make a directory /var/www/htdocs owned by -## nobody.nobody, including the file .gacl containing: -## -## -## -## -## -## -## -## -## To enable writing, add DN List, Person or VOMS entries to the GACL -## (see the GridSite GACL document for the syntax.) For example: -## -## -## -## -## -## -## -## -## /C=UK/O=eScience/OU=Manchester/L=HEP/CN=Andrew McNab -## -## -## -## -## -## and add the following directive to the HTTPS section: -## -## GridSiteMethods GET PUT DELETE -## -## If you wish to accept Globus GSI Proxies as well as full X.509 user -## certificates, set GridSiteGSIProxyLimit to the depth of proxy you -## wish to accept. -## -## (As a _rough_ guide: 0=No Proxies; 1=Proxy on user's machine; 2=Proxy -## owned by running Globus job; 3=Proxy delegated by a Globus job.) -## -## With this done and Apache restarted, you can upload a file with: -## -## curl -v --cert ~/.globus/usercert.pem --key ~/.globus/userkey.pem \ -## --capath /etc/grid-security/certificates --upload-file /tmp/tmp.txt \ -## https://INSERT.HOSTNAME.HERE/tmp.txt -## -## (or with --cert /tmp/x509up_u`id -u` --key /tmp/x509up_u`id -u` to use -## a Globus GSI Proxy created with grid-proxy-init.) -############################################################################## - -ServerRoot "/etc/httpd" - -PidFile logs/httpd.pid - -Timeout 300 -KeepAlive On -MaxKeepAliveRequests 100 -KeepAliveTimeout 15 - -LoadModule log_config_module /usr/lib/httpd/modules/mod_log_config.so -LoadModule ssl_module /usr/lib/httpd/modules/mod_ssl.so -LoadModule gridsite_module /usr/lib/httpd/modules/mod_gridsite.so -LoadModule mime_module /usr/lib/httpd/modules/mod_mime.so -LoadModule dir_module /usr/lib/httpd/modules/mod_dir.so - -TypesConfig /etc/mime.types - -# User and group who will own files created by Apache -User nobody -Group nobody - -DocumentRoot "/var/www/htdocs" - - - AllowOverride None - - -LogLevel debug -LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined - -CustomLog logs/httpd-gridsite-access combined -ErrorLog logs/httpd-gridsite-errors - -HostnameLookups On - -###################################################################### -# Plain unauthenticated HTTP on port 80 -###################################################################### - -Listen 80 - - - - GridSiteIndexes on - GridSiteAuth on - GridSiteDNlists /etc/grid-security/dn-lists/ - - - - -###################################################################### -# Secured and possibly authenticated HTTPS on port 443 -###################################################################### -Listen 443 - - -SSLEngine on -SSLCertificateFile /etc/grid-security/hostcert.pem -SSLCertificateKeyFile /etc/grid-security/hostkey.pem -SSLCACertificatePath /etc/grid-security/certificates -#SSLCARevocationPath YOUR CRL DIRECTORY WOULD GO HERE -SSLSessionCache dbm:/var/cache/mod_ssl/scache -SSLSessionCacheTimeout 300 -SSLVerifyClient optional -SSLVerifyDepth 10 -SSLOptions +ExportCertData +StdEnvVars - - - GridSiteIndexes on - GridSiteAuth on - GridSiteDNlists /etc/grid-security/dn-lists/ - GridSiteGSIProxyLimit 0 -# GridSiteMethods GET PUT DELETE - - - diff --git a/org.gridsite.core/doc/httpd-webserver.conf b/org.gridsite.core/doc/httpd-webserver.conf deleted file mode 100644 index da332a0..0000000 --- a/org.gridsite.core/doc/httpd-webserver.conf +++ /dev/null @@ -1,219 +0,0 @@ -############################################################################## -## GridSite httpd-webserver.conf - Andrew McNab -## -## Example configuration file for GridSite as a Web Server -## (that is, primarily for interactive use with a browser.) -## -## For GridSite documentation, see http://www.gridsite.org/ -## -## This file should be renamed /etc/httpd/conf/httpd.conf and Apache -## restarted to use Apache2/GridSite as a webserver. -## -## You do not need to install the GridSite mod_ssl.so module if you -## do not wish to use Globus Proxies or VOMS attributes, but you must -## have the mod_gridsite.so in /usr/lib/httpd/modules -## -## We're assuming you have (a) the host's hostcert.pem and hostkey.pem -## in /etc/grid-security/ and (b) the Certification Authorities' you -## trust have their root certs in /etc/grid-security/certificates -## -## (You can get RPMs for many European and North American Grid CAs -## from https://datagrid.in2p3.fr/distribution/datagrid/security/ ) -## -## If you want to use DN Lists in ACLs, they should be placed/downloaded -## in /etc/grid-security/dn-lists/ or /var/www/htdocs/dn-lists/ -## (Lists in /etc/grid-security/dn-lists/ override lists elsewhere.) -## -## To start serving files, make a directory /var/www/htdocs owned by -## nobody.nobody, including the file .gacl containing: -## -## -## -## -## -## -## -## -## To enable writing, add DN List, Person or VOMS entries to the GACL -## (see the GridSite GACL document for the syntax.) For example: -## -## -## -## -## -## -## -## -## /C=UK/O=eScience/OU=Manchester/L=HEP/CN=Andrew McNab -## -## -## -## -## -## and add the following directive to the HTTPS section: -## -## GridSiteMethods GET PUT DELETE -## -## If you wish to accept Globus GSI Proxies as well as full X.509 user -## certificates, set GridSiteGSIProxyLimit to the depth of proxy you -## wish to accept. -## -## (As a _rough_ guide: 0=No Proxies; 1=Proxy on user's machine; 2=Proxy -## owned by running Globus job; 3=Proxy delegated by a Globus job.) -## -## With this done and Apache restarted, you can upload a file with: -## -## curl -v --cert ~/.globus/usercert.pem --key ~/.globus/userkey.pem \ -## --capath /etc/grid-security/certificates --upload-file /tmp/tmp.txt \ -## https://INSERT.HOSTNAME.HERE/tmp.txt -## -## (or with --cert /tmp/x509up_u`id -u` --key /tmp/x509up_u`id -u` to use -## a Globus GSI Proxy created with grid-proxy-init.) -############################################################################## - -ServerRoot "/etc/httpd" - -## You MUST put your server's fully qualified domain name here -## This, the DOMAIN part of the https://DOMAIN/... URLs you want -ServerName FULL.SERVER.NAME - -PidFile logs/httpd.pid - -Timeout 300 -KeepAlive On -MaxKeepAliveRequests 100 -KeepAliveTimeout 15 - -LoadModule log_config_module /usr/lib/httpd/modules/mod_log_config.so -LoadModule ssl_module /usr/lib/httpd/modules/mod_ssl.so -LoadModule gridsite_module /usr/lib/httpd/modules/mod_gridsite.so -LoadModule mime_module /usr/lib/httpd/modules/mod_mime.so -LoadModule dir_module /usr/lib/httpd/modules/mod_dir.so -LoadModule alias_module /usr/lib/httpd/modules/mod_alias.so -LoadModule cgi_module /usr/lib/httpd/modules/mod_cgi.so - -TypesConfig /etc/mime.types - -# User and group who will own files created by Apache -User nobody -Group nobody - -DocumentRoot "/var/www/htdocs" - - - AllowOverride None - - -LogLevel debug -LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined - -CustomLog logs/httpd-gridsite-access combined -ErrorLog logs/httpd-gridsite-errors - -HostnameLookups On - -###################################################################### -# Plain unauthenticated HTTP on port 80 -###################################################################### - -Listen 80 - - -## This is used to serve the Manage Directory links in footers, -## and to allow you to edit files and ACLs via your browser. -ScriptAlias /real-gridsite-admin.cgi /usr/sbin/real-gridsite-admin.cgi - - - ## This sets up GACL authorization for this server. - GridSiteAuth on - - ## This exports various bits of info into the CGI environment - ## variables (and is needed for gridsite-admin.cgi to work.) - GridSiteEnvs on - - ## Nice GridSite directory listings (without truncating file names!) - GridSiteIndexes on - - ## If this is on, GridSite will look for gridsitehead.txt and - ## gridsitefoot.txt in the current directory or its parents, and - ## use them to replace the and tags in .html files. - GridSiteHtmlFormat on - - ## These directives (and the ScriptAlias above) allow authorized - ## people to manage files, ACLs and DN Lists through their web - ## browsers. Via HTTP, this just means extended directory listings - ## and History pages. - GridSiteAdminURI /real-gridsite-admin.cgi - GridSiteAdminFile gridsite-admin.cgi - - - - -###################################################################### -# Secured and possibly authenticated HTTPS on port 443 -###################################################################### -Listen 443 - - -SSLEngine on -SSLCertificateFile /etc/grid-security/hostcert.pem -SSLCertificateKeyFile /etc/grid-security/hostkey.pem -SSLCACertificatePath /etc/grid-security/certificates -#SSLCARevocationPath YOUR CRL DIRECTORY WOULD GO HERE -SSLSessionCache dbm:/var/cache/mod_ssl/scache -SSLSessionCacheTimeout 300 -SSLVerifyClient optional -SSLVerifyDepth 10 -SSLOptions +ExportCertData +StdEnvVars - -## This is used to serve the Manage Directory links in footers, -## and to allow you to edit files and ACLs via your browser. -ScriptAlias /real-gridsite-admin.cgi /usr/sbin/real-gridsite-admin.cgi - - - ## This sets up GACL authorization for this server. - GridSiteAuth on - - ## This exports various bits of info into the CGI environment - ## variables (and is needed for gridsite-admin.cgi to work.) - GridSiteEnvs on - - ## Nice GridSite directory listings (without truncating file names!) - GridSiteIndexes on - - ## If this is on, GridSite will look for gridsitehead.txt and - ## gridsitefoot.txt in the current directory or its parents, and - ## use them to replace the and tags in .html files. - GridSiteHtmlFormat on - - ## This is the path of directories (and all their subdirectories) for - ## GACL to search when it encounters a dn-list credential. The DN List - ## files are plain text, one DN per line, and must have the full url - ## as the file name, but URL Encoded - eg with urlencode(1) - GridSiteDNlists /etc/grid-security/dn-lists/:/var/www/htdocs/dn-lists/ - - ## This is used to form the URL at which DN Lists "owned" by this - ## server are exported. https://FULL.SERVER.NAME/dn-lists/file - ## ALL FILES WITH URLs ON THIS SERVER WILL BE EXPORTED IRRESPECTIVE - ## OF WHERE THEY ARE FOUND ON THE DN-LISTS PATH!! - GridSiteDNlistsURI /dn-lists/ - - ## If this is greater than zero, we will accept GSI Proxies for clients - ## (full client certificates - eg inside web browsers - are always ok) - GridSiteGSIProxyLimit 0 - - ## This directive allows authorized people to write/delete files - ## from non-browser clients - eg with htcp(1) - GridSiteMethods GET PUT DELETE - - ## These directives (and the ScriptAlias above) allow authorized - ## people to manage files, ACLs and DN Lists through their web - ## browsers via HTTPS. The value of GridSiteAdminFile appears to - ## exist in every directory, but is internally redirected by - ## mod_gridsite to the value of GridSiteAdminURI (the ScriptAlias - ## then maps that onto the real-gridsite-admin.cgi executable.) - GridSiteAdminURI /real-gridsite-admin.cgi - GridSiteAdminFile gridsite-admin.cgi - - - diff --git a/org.gridsite.core/doc/index.html b/org.gridsite.core/doc/index.html deleted file mode 100644 index a93f2cb..0000000 --- a/org.gridsite.core/doc/index.html +++ /dev/null @@ -1,92 +0,0 @@ -GridSite 1.1.x Documentation - -

GridSite 1.1.x Documentation

- -

-GridSite -is a set of extensions to the Apache 2.0 webserver, which support -Grid security based on X.509 certificates. Since GridSite applies access -control within Apache itself, via mod_gridsite, Grid authorization and -the associated verified credentials are available to all technologies -supported by Apache, including static file serving, SSI, CGI, PHP, JSP and -mod_perl. - -

Guides

- -

-

-
User Guide -
End-user documentation for people managing webpages and files on - GridSite servers, either through the web interface or with command - line clients like htcp. -

- -

Admin Guide -
For people administering areas of GridSite websites or fileservers, or - managing GridSite's support for DN List groups. -

- -

Building and Installation -
Instructions for building GridSite from source, and installing from - binaries or RPMs. -

- -

Config Guide -
For webmasters setting up Apache 2.0 and GridSite, and writing the - Apache httpd.conf file. -

- -

httpd-fileserver.conf and - httpd-webserver.conf -
Example configuration files for simple HTTP(S) fileservers and - webservers, with explanatory comments. -

- -

- -

Reference

- -

-

-
Grid Access Control Lists -
Syntax and usage of the XML Grid Access Control Lists used by GridSite. -

- -

htcp and - urlencode man pages -
Command line tools for copying files to or from HTTP(S) servers, and - for URL-encoding strings. -

- - - -

mod_gridsite -
An Apache 2.0 module which enforces access control via Grid Access - Control Lists, and X.509, GSI or VOMS credentials. mod_gridsite also - gives Apache built-in support for the HTTP PUT and DELETE methods, and - formatting of HTML pages with standard headers and footers. -

- - - -

gridsite.h API reference -
A detailed description of the C API provided by libgridsite, generated - from the sources by doxygen. -

- -

- - diff --git a/org.gridsite.core/doc/install.html b/org.gridsite.core/doc/install.html deleted file mode 100644 index 91a60d2..0000000 --- a/org.gridsite.core/doc/install.html +++ /dev/null @@ -1,148 +0,0 @@ -GridSite: Building and Installation Guide - -

GridSite: Building and Installation Guide

- -

-This Guide explains how to build GridSite from source, and how to install -the server components alongside an Apache 2.0 webserver. There is a -separate Config Guide which explains how to modify -the httpd.conf file, and how to set up other files and directories used by -the system. You should look through all of this Building and Installation -Guide to decide which is the easiest route for your system. - -

Installing with RPM

- -

-If you are installing on Linux with the binary RPM release, you can skip -most of this Guide, install the binary rpm(s) and go straight -to the Config Guide. - -

-We currently distribute GridSite RPMs for RedHat Linux versions 9 and 7.3 -from our download area at - -https://www.gridsite.org/download/ - -

-RedHat 9: -This is the simpler case, since the standard release includes a suitable -version of Apache 2.0: just install the gridsite-...-1.i386.rpm to get the -various GridSite components. - -

-RedHat 7.3: -This is more complicated because you must also install a back-ported Apache -2.0 RPM. We distribute RPMs built on 7.3 aimed at RedHat 7.3 -machines with updates, from our download area. These are built from the -tar.gz and .spec files distributed by the -Apache Foundation itself, using the -build-apache2.sh script in the GridSite -/usr/share/doc/gridsite directory. The Apache RPMs install in /usr, and you -should at least install the httpd and mod_ssl RPMs. -You must also install the gridsite-...-1.i386.rpm as above. - -

-GridSite also depends on shared libraries from libcurl and libxml2, and the -RPMs distributed as part of the standard RedHat 7.3 and 9 releases are -sufficient. - -

-With the RPMs installed, you can proceed to the -Config Guide. - -

Requirements for building GridSite from source

- -

-GridSite is currently only supported on Linux, but should be -straightforwardly -portable to other Unix platforms where the GNU build tools are available. - -

-GridSite consists of a core library (libgridsite[.so|.a]), an Apache module -(mod_gridsite.so), a CGI utility (gridsite-admin.cgi) and some command line -tools (htcp, urlencode.) - -

-All of the components use the GridSite library, and this in turn depends on -libcurl and libxml2. You will need the development versions of these -packages installed before you can proceed. (They are available as part of -RedHat Linux releases 7.x onwards, for instance.) - -

Building GridSite with Make

- -

-Our download area at - -https://www.gridsite.org/download/ includes a tar-ball -distribution of the sources, which can be unpacked and used to build -GridSite from source. (Bleeding-edge developers can get the current snapshot -of the same files from our CVS area.) - -

-GridSite needs a copy of the Apache 2.0 include files to build, and the -location of this is set by the MYCFLAGS variable in the top-level Makefile. -For manual builds, the default -MYCFLAGS=-I/usr/local/include/httpd is used. -If you wish to use the GridSite module with Apache -2.0 installed elsewhere, you should change the MYCFLAGS variable to point to -the includes directory installed by the development part of that Apache 2.0 -distribution. - -

-

-make 
-make install
-
- -

-will build all components and install them all under the default -locations of /usr/local/[lib|bin|include|sbin] The default prefix for manual -builds is -/usr/local, as set by the prefix variable in the top level Makefile -(/usr is the default for RPMs.) - -

Building GridSite with RPM

- -

-For RedHat Linux and derivatives, building with RPM is recommended. -The command make rpm in the top level of the source tree -will build the GridSite and htcp binary RPMs in the -directory ../RPMTMP/RPMS/i386 relative to the working directory. An SRPM is -put into ../RPMTMP/SRPMS -This build assumes the Apache 2.0 includes are in /usr/include/httpd. - -

-If you make RPMs on a RedHat 9 system (or a 7.3 system with our httpd RPM -installed), you can install the resulting GridSite -RPM alongside the standard Apache 2.0 RPM without having to -modify shared library or Apache module paths. - -

-For other configurations, -you can modify the assumed location of the Apache 2.0 includes -by changing the MYCFLAGS variable in the rpm target near the -foot of the top level Makefile. - -

Building Apache 2.0

- -

-If it is not possible to use binary RPMs of Apache 2.0, -then it can be built from source using the build-apache2.sh script -found in the GridSite docs directory. -The script includes instructions on how to build from the tarballs -distributed by the Apache Foundation. -(it removes the -C option from "configure -C" in the .spec file -and builds the RPMs under the current directory.) - -

-If these targets do not work on your build platform, -the Makefile and the scriptlets in the included SPEC files are a good -starting point for building Apache by hand yourself. The complexities of -this are outside of the scope of this Guide, but you are welcome to ask for -assistance on the -GridSite -Discussion List, although -www.apache.org is a better starting -point for purely Apache problems. - - diff --git a/org.gridsite.core/doc/library.html b/org.gridsite.core/doc/library.html deleted file mode 100644 index 28458ae..0000000 --- a/org.gridsite.core/doc/library.html +++ /dev/null @@ -1 +0,0 @@ -library docs diff --git a/org.gridsite.core/doc/module.html b/org.gridsite.core/doc/module.html deleted file mode 100644 index 7f2096e..0000000 --- a/org.gridsite.core/doc/module.html +++ /dev/null @@ -1,271 +0,0 @@ -GridSite Apache module: mod_gridsite - -

GridSite Apache module: mod_gridsite

- -

-mod_gridsite is an Apache 2.0 module which enforces access control via Grid -Access Control Lists, and X.509, GSI or VOMS credentials. mod_gridsite also -gives Apache built-in support for the HTTP PUT and DELETE methods, and -formatting of HTML pages with standard headers and footers. - -

-Since mod_gridsite access -control within Apache itself, Grid authorization and -the associated verified credentials are available to all technologies -supported by Apache, including static file serving, SSI, CGI, PHP, mod_perl -and Java servlets via a connector to Tomcat. - -

-Operation of mod_gridsite can be configured using runtime directives -in Apache's standard httpd.conf configuration file. The module must first be -loaded with a LoadModule directive: - -

-LoadModule gridsite_module /PATH/TO/MODULES/mod_gridsite.so - -

-The module's behaviour is then controlled by GridSite... directives within -Apache <Directory ...> sections, allowing different directories to use -GridSite features in different ways. - -

GridSite directives

- -
-
GridSiteIndexes on|off -
Determines whether GridSite generates HTML directory listings. These - have some advantages over standard Apache directory listings (eg the - displayed filenames are never truncated) and will include standard - headers and footers if GridSiteHtmlFormat is on. -
- (Default: GridSiteIndexes off) -

- -

GridSiteIndexHeader file -
If the named file is found in the directory being listed, the file - is included verbatim at the top of the listing and excluded from - the file-by-file listing. The file can either be HTML or plain text (in - which case browsers will be treat it as one HTML paragraph.) -
- (Default: none) -

- -

GridSiteHtmlFormat on|off -
Determines where HTML pages receive additional formatting before being - sent to the client. This includes the "Last modified", - "View page history", "Switch to HTTP(S)", - "Print View" and "Built with GridSite" footer - elements. If header and footer files are found, they will be used too. -
- (Default: GridSiteHtmlFormat off) -

- -

GridSiteHeadFile file
- GridSiteFootFile file -
Set the filenames to be searched for as standard headers and footers - for HTML pages. For each HTML page, the directory of that page is tried - first, and then parent directories in ascending order until a header / - footer file is found. Header files are inserted in place of HTML - <body[ ...]> tags; footer files in place of </body>. (These - standard files should each include the appropriate body tag as a - replacement.) -
- (Defaults: GridSiteHeadFile gridsitehead.txt, - GridSiteFootFile gridsitefoot.txt) -

- -

GridSiteAuth on|off -
Enables GridSite access control features, using - GACL files. The files are named .gacl and are - per-directory. The current directory is tried and then parent - directories in ascending order until a .gacl file is found. -
- (Default: GridSiteAuth off) -

- -

GridSiteAdminList uri -
All members of the DN List with name "uri" receive the full set - of permissions, irrespective of per-directory .gacl files. People in - this group have full control over the whole site. -
- (Default: none) -

- -

GridSiteGSIProxyLimit limit -
When using GSI Proxy credentials, - proxies with delegation depth greater than "limit" will - be ignored by mod_gridsite authorization decisions. A limit of zero - implies only full X.509 - certificates (and no proxies) will be accepted. A limit of 1 implies - that only the initial proxy, usually created on the user's own machine, - is acceptable. Higher levels lead to proxies on remote machines, eg - used by running jobs, being accepted. -
- (Default: GridSiteGSIProxyLimit 1) -

- -

GridSiteMethods [GET] [PUT] [DELETE] -
Specifies which HTTP methods are supported by GridSite. GET (and HEAD) - are always supported. PUT and DELETE support is turned on by this - directive, subject to a positive statement that write permission is - allowed for the directory in question, by a GACL file. -
- (Default: GridSite GET) -

- -

GridSiteDNlists directory1[:directory2[:directory3]...] -
Sets up the DN List path used by GACL for - evaluating <dn-list> credentials. If this directive is not used, - then GACL will use the GRST_DN_LISTS variable from Apache's own - environment. If that is not set either, then /etc/grid-security/dn-lists - is searched. -
- (Default: none) -

- -

GridSiteDNlistsURI uri -
If GridSiteDNlistsURI is used, then the URI given appears to be - populated with all the DN lists on the current DN lists path which - match the current server. That is, for server https://example.org/ - with DN lists URI /dn-lists/, all DN lists with URLs starting - https://example.org/dn-lists/ will appear to be present in /dn-lists/, - irrespective of where in the path they are stored. -
- (Default: none) -

- -

GridSiteAdminURI uri -
GridSiteAdminURI gives the absolute URI on the server of the GridSite - Admin CGI program, which is used for file management, HTML and GACL - editing. This should be used in conjunction with the standard Apache - directive ScriptAlias to map that URI to the real-gridsite-admin.cgi - executable. For example: -
- ScriptAlias /real-gridsite-admin.cgi - /PATH/TO/real-gridsite-admin.cgi -
- This URI is always reached by an internal redirection from the value - set by GridSiteAdminFile, and is never visible to users. -
- (Default: none) -

- -

GridSiteAdminFile cgifilename -
If GridSiteAdminURI is set, then the cgifilename of GridSiteAdminFile - appears to be present in all directories when explicitly - requested (it does not appear in directory listings.) Requests for these - ghost CGI URIs are internally redirected to the value set by - GridSiteAdminURI. -
- (Default: GridSiteAdminFile gridsite-admin.cgi) -

- -

GridSiteEnvs on|off -
This makes mod_gridsite export several variables into the environment - of CGI programs and other dynamic content systems. The variable names - are listed below. For gridsite-admin.cgi mechanism to work, this switch - must be left in its default state of on. -
- (Default: GridSiteEnvs on) -

- -

GridSiteEditable [ext1 [ext2 [ext3] ...]]] -
A space-separated list of file extensions which can safely be edited - by the GridSite Text/HTML editor. The extensions are given without the - initial dot. -
- (Default: GridSiteEditable txt shtml html htm css js php jsp) -

- -

GridSiteHelpURI uri -
If set, gives the URI to use for "Website Help" links in HTML - page footers. -
- (Default: none) -

- -

GridSiteLink on|off -
Turns off the link in the HTML page footers which gives credit to - GridSite. -
- (Default: GridSiteLink on) -

- -

GridSiteUnzip path -
If "path" is set by this directive, then real-gridsite-admin.cgi - will offer to list the contents of .zip archives on the server. - Users with write access are able to unpack the contents into the same - directory as the .zip file. The value of "path" must point - to the location of the - unzip binary. -
- (Default: none) -

- -

- -

Environment variables

- -

-The following variables are present in the environment of CGI programs and -other dynamic content systems if the GridSiteEnvs on directive is -in effect. - -

-

-
GRST_PERM -
Numerical value of the permission bit-map obtained by comparing the - user with the GACL in force. (These should be tested using the - GRSTgaclPermHasXXXX functions from GACL.) -

- -

GRST_ADMIN_LIST -
URI of the DN List, listing people with full admin and write access - to the whole site. -

- -

GRST_GSIPROXY_LIMIT -
Maximum valid delegation level for GSI Proxies. -

- -

GRST_DIR_PATH -
Absolute path in the local filesystem to the directory holding the - file being requested. -

- -

GRST_HELP_URI -
URI of website help pages set by GridSiteHelpURI directive. -

- -

GRST_ADMIN_FILE -
Filename of per-directory ghost gridsite-admin.cgi program. (This is - used by real-gridsite-admin.cgi to construct links in its pages.) -

- -

GRST_EDITABLE -
Space-separated list of extensions which can safely be edited with a - Text/HTML editor. -

- -

GRST_HEAD_FILE and GRST_FOOT_FILE -
Filenames of standard header and footer files. -

- -

GRST_DN_LISTS -
DN lists search path. -

- -

GRST_DN_LISTS_URI -
Directory of virtual URIs used to publish this site's DN Lists. -

- -

GRST_UNZIP -
Full path to the unzip binary, used to list and unpack .zip files. -

- -

GRST_NO_LINK -
If set, do not include credit links to GridSite in page footers. -

- -

- - diff --git a/org.gridsite.core/doc/urlencode.1 b/org.gridsite.core/doc/urlencode.1 deleted file mode 100644 index fe84405..0000000 --- a/org.gridsite.core/doc/urlencode.1 +++ /dev/null @@ -1,46 +0,0 @@ -.TH urlencode 1 "November 2003" urlencode "URLENCODE Manual" -.SH NAME -.B urlencode -\- convert strings to or from URL-encoded form -.SH SYNOPSIS -.B urlencode -[-m|-d] -.I string [string ...] -.SH DESCRIPTION -.B urlencode -encodes strings according to RFC 1738. - -That is, characters A-Z a-z 0-9 . _ -and - are passed through unmodified, but all other characters are -represented as %HH, where HH is their two-digit upper-case hexadecimal ASCII -representation. -For example, the URL http://www.gridpp.ac.uk/ becomes -http%3A%2F%2Fwww.gridpp.ac.uk%2F - -.B urlencode -converts each character in all the strings given on the command line. If -multiple strings are given, they are concatenated with separating spaces -before conversion. - -.SH OPTIONS -.IP "-m" -Instead of full conversion, do GridSite "mild URL encoding" in which A-Z a-z -0-9 . = - _ @ and / are passed through unmodified. This results in slightly -more human-readable strings but the application must be prepared to create -or simulate the directories implied by any slashes. - -.IP "-d" -Do URL-decoding rather than encoding, according to RFC 1738. %HH and %hh -strings are converted and other characters are passed through unmodified, -with the exception that + is converted to space. - -.SH EXIT CODES -0 is always returned. - -.SH BUGS -Not enough beta testing (hint hint...) - -.SH AUTHOR -Andrew McNab - -urlencode is part of GridSite: http://www.gridsite.org/ diff --git a/org.gridsite.core/doc/user.html b/org.gridsite.core/doc/user.html deleted file mode 100644 index ae37cdd..0000000 --- a/org.gridsite.core/doc/user.html +++ /dev/null @@ -1,302 +0,0 @@ -GridSite User Guide - -

GridSite User Guide

- -

If you are setting up a GridSite-based website you may wish to use this -file as the basis of your end-user documentation. If so, copy all of the -files from the GridSite doc directory (probably -/usr/share/doc/gridsite-VERSION/) -to somewhere on your website like -/gridsite-doc/ and add GridSiteHelpURI /gridsite-doc/user.html -to the virtual server configuration in -httpd.conf - you should also look through the rest of the HTML source since -there are some comments you may find helpful. - -

-This Guide is intended for people using GridSite websites with conventional -web browsers, especially people with write access to areas of the site. - There is a separate -Administration Guide - with additional information for people managing access control and group -membership. This Guide assumes you are familiar with basic Web and HTML -concepts. Towards the end we discuss how to access servers with command -line tools like curl and htcp. - -

Reading from HTTP and HTTPS servers

- -

-GridSite servers are usually accessible both via HTTP and via HTTPS. You can -always tell which version you are using by looking at whether the URL in your -browser's location window starts with "http://" or -"https://" HTTPS means that the connection to the server is -encrypted, that you can verify you're talking to the real server and not an -imposter, and gives you the option to authenticate to the site and perhaps -gain write access. - -

- Simple browsing of the website via HTTP or HTTPS is reasonably - self-explanatory. If configured, additional links may appear in the footer - of each webpage with links to this help, - - and to switch between HTTP and HTTPS versions of the page. Pages may also - have a link to the page History, - - showing the dates of changes to that page and names of its authors. - -

- When looking at HTTPS pages, you may find your browser reports it cannot - verify the server's certificate since it does not recognise the - Certification Authority (CA) it uses. You should attempt to load the CA's - root certificate into your browser to stop these warnings. (This means your - browser will be able to identify any servers using fake certificates which - you shouldn't trust.) How you obtain the CA Root Certificate from a - trust-worthy source depends on the CA. For example, the UK e-Science CA - lets you download it from their - website. - - -

Authenticating

- -

- To go beyond reading pages you need to obtain a user certificate and load it - into your web browser. How you do this again depends on the Certification - Authority you have access to (for most Grid projects, CAs are organised - on a national basis.) To use the UK e-Science CA example again, - from their website has links to - the procedure for applying for a certificate from within a web browser. - - -

-A user certificate usually has a version of your name and affiliation as its -Distinguished Name (DN) - for example, -"/C=UK/O=eScience/OU=Manchester/L=HEP/CN=Andrew McNab" - -

-Once you've obtained a user certificate in your name from your CA, you need -to make sure it is loaded into the browser you normally use to browse the -web. How you do this is different for different browsers and to some extent -for different CAs (but if you applied -for the CA through your browser, you may already have it there.) - -

-Browsers want the certificate and private key in the PKCS#12 format, which -is normally a single file with the extension ".p12". -Many programs which are based on OpenSSL, such as Globus and curl, prefer -the PEM (".pem") format for certificates, with separate -certificate and key files ("usercert.pem" and -"userkey.pem", for example.) If you only have the files in .pem -format and have access to openssl, you -can use its command line tools to convert PEM to PKCS#12: -

-openssl pkcs12 -in usercert.pem -inkey userkey.pem -export -out certkey.p12
-
- -

-Be very careful not to accidentally overwrite .pem or .p12 files when -doing this kind of thing! In particular, if you lose your private key, you -cannot retrieve it from your CA. - -

- Once your user certificate is loaded, you should be able to see your - certificate name appear when you look at an HTTPS GridSite page which has - the page footers enabled - for example, the "Switch to HTTP" link - present. If GridSite understands your user certificate, it displays a - "You are ..." line in the footer. (However, the Apache webserver - must also be set up with your CAs root certificate for this to work. The - GridPP HTTPS home page is set up - to recognise a good range of European and North American Grid CAs.) - - -

Authorization

- -

- Once users can prove their identity to the web server, it then becomes - possible to give them appropriate rights depending on that identity. - GridSite allows site administrators to specify these rights for individuals - and groups using -GACL - access control files. (The -Administration Guide - explains how to manage these files.) GACL defines who can - read files, who can list directories, - who can write or create files and who can modify the GACL policy files. To - get increased access to an area of a site, you need to contact the - administrator for that area and give the DN of your certificate (it's not - necessary to send any certificate files.) - -

Managing Directories and Files

- -

-If you have list permission for the directory containing a page, you should -see an extra link "Manage Directory" in the page's set of footer -links, which allows you to browse the directory even if the normal -index.html is present. If page histories are available, this listing view -also has links to them. - -

-The real power of GridSite becomes available if you have write access to a -directory. In that case, the "Manage Directory" page has -additional links to Delete or Rename pages and other files, and to Edit HTML -and plain text files. An Edit link also appears in the footer links of HTML -pages. - -

-If you use the Edit function, you are presented with an HTML form containing -the current filename and the full HTML or plain text of the page for you to -edit. This allows you to maintain the content of the site "in -place" and to see the result of your changes immediately, in context. - -

-If you modify the filename in the form before saving, GridSite will make a -new file with that name, and the old file will still be present, unmodified. -(However, you cannot use this feature for creating a file in a different -directory.) -As you make changes, the history of the changes and your certificate DN are -recorded, and available in the history page for that file. - -

- For people with write access, the "Manage Directory" page also has - options to upload a file from the computer your browser is running on, and to - create files and directories. If it's enabled, you can also view the - contents of WinZIP / PKZIP / .zip files, and unpack their contents into the - current directory. (This feature is very useful if you have several files - to upload at one time.) - - -

HTML Formatting in GridSite

- -

-As well as providing access control and file management, GridSite provides -some simple formatting of HTML pages by adding standard headers and footers. -(If this isn't sufficient, GridSite will happily coexist with HTML -preprocessor languages like SSI, PHP and JSP.) - -

- If HTML formatting is enabled - for the current directory, GridSite looks for the files gridsitehead.txt and - gridsitefoot.txt in that directory, or goes up through the parent - directories until they are found. - - -

-The <body> and </body> tags from the HTML file are replaced with -the contents of the gridsitehead.txt and gridsitefoot.txt files, which -should normally be chunks of HTML including a replacement <body> -or </body> tag. If either tag is absent from the original page, then -the header or footer is just added rather than being inserted in place of -the tag. (One consequence of this absence is that HTML header tags like -<title> can end up after a <body> tag, and can get ignored by -browsers - so always include <body> ... </body> in your pages.) - -

-This simple system is suprisingly flexible, and allows a variety of top and -bottom, or sidebar navigation layouts of pages. Since the <body ...> -tag is under full control of the author of the gridsitehead.txt file, -backgrounds, colour schemes and style sheets can easily be specified. - -

-For example: - -

- - - - - - - - - -
SourceHTML
page.html<title>PAGE TITLE</title>
page.html
(replaced)
<body>
gridsitehead.txt<body text=blue>
- Heading text
- <table border=1>
<tr>
<td>Standard<br>
- sidebar</td>
<td>
page.html<p>
Page content...
page.html
(replaced)
</body>
gridsitefoot.txt</td>
</tr>
- </table>
Footer text
</body>
- -

-produces pages with a layout like: - -

- - - - -
Heading text
Standard
sidebar
Page content...
Footer text
- -

Command line use

- -

-GridSite adds support for the HTTP PUT and DELETE methods, and this makes it -easy to create or delete files from within programs and commands without -using a web browser and HTML forms. It is straightforward, although slightly -awkward, to use a standard HTTPS-aware client like -curl to upload files, but GridSite -provides htcp as a more convenient client program, which is easier to use -with GSI Proxies and X.509 user certificates, and has a syntax closer to the -familiar scp command. - -

-The following examples assume the GridSite server has GSI support and use a -GSI proxy as the client certificate. For non-GSI use, just skip the -grid-proxy-init stage, and replace the proxy -filename with $HOME/.globus/usercert.pem and $HOME/.globus/userkey.pem (or -wherever your PEM format certificate and key are stored.) - -

-First generate a GSI proxy with grid-proxy-init. This will create a proxy file -in /tmp/x509up_uXXXXX where XXXXX is your Unix UID (also given by id --u.) The GSI proxy contains a -temporary private key and certificate signed by your long-term user -certificate. - -

-You should make sure you have a copy of the CA root certificates of the CA's -used by the servers you wish to talk to. These are usually installed in -/etc/grid-security/certificates as files like 01621954.0, and RPMs and tar -files for many common European and North American CAs are available from - -https://datagrid.in2p3.fr/distribution/datagrid/security/ - -

-To upload a file with curl: -

-curl --cert /tmp/x509up_u`id -n` --key /tmp/x509up_u`id -n` \
-     --capath /etc/grid-security/certificates \
-     --upload-file /tmp/new.file.txt https://server/new.file.txt
-
- -

-The equivalent htcp command is: -

-htcp /tmp/new.file.txt https://server/new.file.txt
-
-since htcp looks for the GSI proxy and CA certificates automatically. htcp -can also be used to copy remote files to the local machine by reversing the -arguments. For more details, see the -htcp(1) man page. - -

-htcp also has options for deleting files, and doing short or long listings, -and these can also be accessed using the htrm, htls and htll commands (which -are normally symbolic links to htcp.) - -

-Directory indexes are based on parsing the index returned by the web server -and by using the HTTP HEAD method to obtain the file size and modification -times. - -

-All of the ht** commands can accept multiple source file arguments, and this -allows you to copy multiple files to or from the server. Shell wildcard -expansion on the local machine is especially useful: -

-htcp /tmp/new.*.txt https://server/
-
- - diff --git a/org.gridsite.core/interface/gridsite-gacl.h b/org.gridsite.core/interface/gridsite-gacl.h deleted file mode 100644 index f739c00..0000000 --- a/org.gridsite.core/interface/gridsite-gacl.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - Copyright (c) 2002-4, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. -*/ - -/*---------------------------------------------------------------* - * For more about GridSite: http://www.gridsite.org/ * - *---------------------------------------------------------------*/ - -#ifndef HEADER_GACL_H -#define HEADER_GACL_H -#endif - -#ifndef GACL_LIB_VERSION -#define GACL_LIB_VERSION "x.x.x" -#endif - -typedef GRSTgaclCred GACLcred; - -typedef int GACLaction; -typedef unsigned int GACLperm; - -typedef GRSTgaclEntry GACLentry; - -typedef GRSTgaclAcl GACLacl; - -typedef GRSTgaclUser GACLuser; - -extern char *gacl_perm_syms[]; -extern GACLperm gacl_perm_vals[]; - -#define GACL_PERM_NONE GRST_PERM_NONE -#define GACL_PERM_READ GRST_PERM_READ -#define GACL_PERM_LIST GRST_PERM_LIST -#define GACL_PERM_WRITE GRST_PERM_WRITE -#define GACL_PERM_ADMIN GRST_PERM_ADMIN - -#define GACLhasNone(perm) (perm == 0) -#define GACLhasRead(perm) ((perm & GRST_PERM_READ) != 0) -#define GACLhasList(perm) ((perm & GRST_PERM_LIST) != 0) -#define GACLhasWrite(perm) ((perm & GRST_PERM_WRITE) != 0) -#define GACLhasAdmin(perm) ((perm & GRST_PERM_ADMIN) != 0) - -#define GACL_ACTION_ALLOW GRST_ACTION_ALLOW -#define GACL_ACTION_DENY GRST_ACTION_DENY - -#define GACL_ACL_FILE GRST_ACL_FILE -#define GACL_DN_LISTS GRST_DN_LISTS - -#define GACLinit() GRSTgaclInit() - -#define GACLnewCred(x) GRSTgaclCredNew((x)) -/* GACLcred *GACLnewCred(char *); */ - -#define GACLaddToCred(x,y,z) GRSTgaclCredAddValue((x),(y),(z)) -/* int GACLaddToCred(GACLcred *, char *, char *); */ - -#define GACLfreeCred(x) GRSTgaclCredFree((x)) -/* int GACLfreeCred(GACLcred *); */ - -#define GACLaddCred(x,y) GRSTgaclEntryAddCred((x),(y)) -/* int GACLaddCred(GACLentry *, GACLcred *); */ - -#define GACLdelCred(x,y) GRSTgaclEntryDelCred((x),(y)) -/* int GACLdelCred(GACLentry *, GACLcred *); */ - -#define GACLprintCred(x,y) GRSTgaclCredPrint((x),(y)) -/* int GACLprintCred(GACLcred *, FILE *); */ - - -#define GACLnewEntry() GRSTgaclEntryNew() -/* GACLentry *GACLnewEntry(void); */ - -#define GACLfreeEntry(x) GRSTgaclEntryFree((x)) -/* int GACLfreeEntry(GACLentry *); */ - -#define GACLaddEntry(x,y) GRSTgaclAclAddEntry((x),(y)) -/* int GACLaddEntry(GACLacl *, GACLentry *); */ - -#define GACLprintEntry(x,y) GRSTgaclEntryPrint((x),(y)) -/* int GACLprintEntry(GACLentry *, FILE *); */ - - -#define GACLprintPerm(x,y) GRSTgaclPermPrint((x),(y)) -/* int GACLprintPerm(GACLperm, FILE *); */ - -#define GACLallowPerm(x,y) GRSTgaclEntryAllowPerm((x),(y)) -/* int GACLallowPerm(GACLentry *, GACLperm); */ - -#define GACLunallowPerm(x,y) GRSTgaclEntryUnallowPerm((x),(y)) -/* int GACLunallowPerm(GACLentry *, GACLperm); */ - -#define GACLdenyPerm(x,y) GRSTgaclEntryDenyPerm((x),(y)) -/* int GACLdenyPerm(GACLentry *, GACLperm); */ - -#define GACLundenyPerm(x,y) GRSTgaclEntryUndenyPerm((x),(y)) -/* int GACLundenyPerm(GACLentry *, GACLperm); */ - -#define GACLpermToChar(x) GRSTgaclPermToChar((x)) -/* char *GACLpermToChar(GACLperm); */ - -#define GACLcharToPerm(x) GRSTgaclPermFromChar((x)) -/* GACLperm GACLcharToPerm(char *); */ - -#define GACLnewAcl() GRSTgaclAclNew() -/* GACLacl *GACLnewAcl(void); */ - -#define GACLfreeAcl(x) GRSTgaclAclFree((x)) -/* int GACLfreeAcl(GACLacl *); */ - -#define GACLprintAcl(x,y) GRSTgaclAclPrint((x),(y)) -/* int GACLprintAcl(GACLacl *, FILE *); */ - -#define GACLsaveAcl(x,y) GRSTgaclAclSave((y),(x)) -/* int GACLsaveAcl(char *, GACLacl *); */ - -#define GACLloadAcl(x) GRSTgaclAclLoadFile((x)) -/* GACLacl *GACLloadAcl(char *); */ - -#define GACLfindAclForFile(x) GRSTgaclFileFindAclname((x)) -/* char *GACLfindAclForFile(char *); */ - -#define GACLloadAclForFile(x) GRSTgaclAclLoadforFile((x)) -/* GACLacl *GACLloadAclForFile(char *); */ - -#define GACLisAclFile(x) GRSTgaclFileIsAcl((x)) -/* int GACLisAclFile(char *); */ - - -#define GACLnewUser(x) GRSTgaclUserNew((x)) -/* GACLuser *GACLnewUser(GACLcred *); */ - -#define GACLfreeUser(x) GRSTgaclUserFree((x)) -/* int GACLfreeUser(GACLuser *); */ - -#define GACLuserAddCred(x,y) GRSTgaclUserAddCred((x),(y)) -/* int GACLuserAddCred(GACLuser *, GACLcred *); */ - -#define GACLuserHasCred(x,y) GRSTgaclUserHasCred((x),(y)) -/* int GACLuserHasCred(GACLuser *, GACLcred *); */ - -#define GACLuserFindCredType(x,y) GRSTgaclUserFindCredtype((x),(y)) -/* GACLcred *GACLuserFindCredType(GACLuser *, char *); */ - -#define GACLtestDnList(x,y) GRSTgaclDNlistHasUser((x),(y)) -/* int GACLtestDnList(char *, GACLuser *); */ - -#define GACLtestUserAcl(x,y) GRSTgaclAclTestUser((x),(y)) -/* GACLperm GACLtestUserAcl(GACLacl *, GACLuser *); */ - -#define GACLtestExclAcl(x,y) GRSTgaclAclTestexclUser((x),(y)) -/* GACLperm GACLtestExclAcl(GACLacl *, GACLuser *); */ - - -#define GACLurlEncode(x) GRSThttpUrlEncode((x)) -/* char *GACLurlEncode(char *); */ - -#define GACLmildUrlEncode(x) GRSThttpUrlMildencode((x)) -/* char *GACLmildUrlEncode(char *); */ - -GACLentry *GRSTgaclEntryParse(xmlNodePtr cur); -/* special function for legacy EDG LB service */ diff --git a/org.gridsite.core/interface/gridsite.h b/org.gridsite.core/interface/gridsite.h deleted file mode 100644 index 3626069..0000000 --- a/org.gridsite.core/interface/gridsite.h +++ /dev/null @@ -1,288 +0,0 @@ -/* - Copyright (c) 2002-3, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. -*/ - -/*---------------------------------------------------------------* - * For more about GridSite: http://www.gridsite.org/ * - *---------------------------------------------------------------*/ - -#ifndef HEADER_SSL_H -#include -#endif - -#ifndef HEADER_CRYPTO_H -#include -#endif - -#ifndef FALSE -#define FALSE (0) -#endif -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -/// Everything ok (= OpenSSL X509_V_OK) -#define GRST_RET_OK 0 - -/// Failed for unspecified reason -#define GRST_RET_FAILED 1000 - -/// Failed to find certificate in some cert store / directory -#define GRST_RET_CERT_NOT_FOUND 1001 - -/// Bad signature -#define GRST_RET_BAD_SIGNATURE 1002 - -/// No such file or directory -#define GRST_RET_NO_SUCH_FILE 1003 - -typedef struct { char *name; - char *value; - void *next; } GRSTgaclNamevalue; - -typedef struct { char *type; - int delegation; - GRSTgaclNamevalue *firstname; - void *next; } GRSTgaclCred; - -typedef int GRSTgaclAction; -typedef unsigned int GRSTgaclPerm; - -typedef struct { GRSTgaclCred *firstcred; - GRSTgaclPerm allowed; - GRSTgaclPerm denied; - void *next; } GRSTgaclEntry; - -typedef struct { GRSTgaclEntry *firstentry; } GRSTgaclAcl; - -typedef struct { GRSTgaclCred *firstcred; - char *dnlists; } GRSTgaclUser; - -#define GRST_PERM_NONE 0 -#define GRST_PERM_READ 1 -#define GRST_PERM_EXEC 2 -#define GRST_PERM_LIST 4 -#define GRST_PERM_WRITE 8 -#define GRST_PERM_ADMIN 16 -#define GRST_PERM_ALL 31 - -/* DO NOT USE PermIsNone!! */ -#define GRSTgaclPermIsNone(perm) (perm == 0) - -#define GRSTgaclPermHasNone(perm) (perm == 0) -#define GRSTgaclPermHasRead(perm) ((perm & GRST_PERM_READ ) != 0) -#define GRSTgaclPermHasExec(perm) ((perm & GRST_PERM_EXEC ) != 0) -#define GRSTgaclPermHasList(perm) ((perm & GRST_PERM_LIST ) != 0) -#define GRSTgaclPermHasWrite(perm) ((perm & GRST_PERM_WRITE) != 0) -#define GRSTgaclPermHasAdmin(perm) ((perm & GRST_PERM_ADMIN) != 0) - -#define GRST_ACTION_ALLOW 0 -#define GRST_ACTION_DENY 1 - -#define GRST_HIST_PREFIX ".grsthist" -#define GRST_ACL_FILE ".gacl" -#define GRST_DN_LISTS "/etc/grid-security/dn-lists" -#define GRST_RECURS_LIMIT 9 - -#define GRST_PROXYCERTINFO_OID "1.3.6.1.4.1.3536.1.222" -#define GRST_VOMS_OID "1.3.6.1.4.1.8005.100.100.5" -#define GRST_VOMS_DIR "/etc/grid-security/vomsdir" - -#define GRST_ASN1_MAXCOORDLEN 50 -#define GRST_ASN1_MAXTAGS 500 - -struct GRSTasn1TagList { char treecoords[GRST_ASN1_MAXCOORDLEN+1]; - int start; - int headerlength; - int length; - int tag; } ; - -int GRSTgaclInit(void); - -/* #define GACLnewCred(x) GRSTgaclCredNew((x)) */ -GRSTgaclCred *GRSTgaclCredNew(char *); - -/* #define GACLaddToCred(x,y,z) GRSTgaclCredAddValue((x),(y),(z)) */ -int GRSTgaclCredAddValue(GRSTgaclCred *, char *, char *); - -#define GRSTgaclCredSetDelegation(cred, level) ((cred)->delegation = (level)) -#define GRSTgaclCredGetDelegation(cred) ((cred)->delegation) - -/* #define GACLfreeCred(x) GRSTgaclCredFree((x)) */ -int GRSTgaclCredFree(GRSTgaclCred *); - -/* #define GACLaddCred(x,y) GRSTgaclEntryAddCred((x),(y)) */ -int GRSTgaclEntryAddCred(GRSTgaclEntry *, GRSTgaclCred *); - -/* #define GACLdelCred(x,y) GRSTgaclEntryDelCred((x),(y)) */ -int GRSTgaclEntryDelCred(GRSTgaclEntry *, GRSTgaclCred *); - -/* #define GACLprintCred(x,y) GRSTgaclCredPrint((x),(y)) */ -int GRSTgaclCredCredPrint(GRSTgaclCred *, FILE *); - - -/* #define GACLnewEntry(x) GRSTgaclEntryNew((x)) */ -GRSTgaclEntry *GRSTgaclEntryNew(void); - -/* #define GACLfreeEntry(x) GRSTgaclEntryFree((x)) */ -int GRSTgaclEntryFree(GRSTgaclEntry *); - -/* #define GACLaddEntry(x,y) GRSTgaclAclAddEntry((x),(y)) */ -int GRSTgaclAclAddEntry(GRSTgaclAcl *, GRSTgaclEntry *); - -/* #define GACLprintEntry(x,y) GRSTgaclEntryPrint((x),(y)) */ -int GRSTgaclEntryPrint(GRSTgaclEntry *, FILE *); - - -/* #define GACLprintPerm(x,y) GRSTgaclPermPrint((x),(y)) */ -int GRSTgaclPermPrint(GRSTgaclPerm, FILE *); - -/* #define GACLallowPerm(x,y) GRSTgaclEntryAllowPerm((x),(y)) */ -int GRSTgaclEntryAllowPerm(GRSTgaclEntry *, GRSTgaclPerm); - -/* #define GACLunallowPerm(x,y) GRSTgaclEntryUnallowPerm((x),(y)) */ -int GRSTgaclEntryUnallowPerm(GRSTgaclEntry *, GRSTgaclPerm); - -/* #define GACLdenyPerm(x,y) GRSTgaclEntryDenyPerm((x),(y)) */ -int GRSTgaclEntryDenyPerm(GRSTgaclEntry *, GRSTgaclPerm); - -/* #define GACLundenyPerm(x,y) GRSTgaclEntryUndenyPerm((x),(y)) */ -int GRSTgaclEntryUndenyPerm(GRSTgaclEntry *, GRSTgaclPerm); - -/* #define GACLpermToChar(x) GRSTgaclPermToChar((x)) */ -char *GRSTgaclPermToChar(GRSTgaclPerm); - -/* #define GACLcharToPerm(x) GRSTgaclPermFromChar((x)) */ -GRSTgaclPerm GRSTgaclPermFromChar(char *); - -/* #define GACLnewAcl(x) GRSTgaclAclNew((x)) */ -GRSTgaclAcl *GRSTgaclAclNew(void); - -/* #define GACLfreeAcl(x) GRSTgaclAclFree((x)) */ -int GRSTgaclAclFree(GRSTgaclAcl *); - -/* #define GACLprintAcl(x,y) GRSTgaclAclPrint((x),(y)) */ -int GRSTgaclAclPrint(GRSTgaclAcl *, FILE *); - -/* #define GACLsaveAcl(x,y) GRSTgaclAclSave((y),(x)) */ -int GRSTgaclAclSave(GRSTgaclAcl *, char *); - -/* #define GACLloadAcl(x) GRSTgaclFileLoadAcl((x)) */ -GRSTgaclAcl *GRSTgaclAclLoadFile(char *); - -/* #define GACLfindAclForFile(x) GRSTgaclFileFindAclname((x)) */ -char *GRSTgaclFileFindAclname(char *); - -/* #define GACLloadAclForFile(x) GRSTgaclFileLoadAcl((x)) */ -GRSTgaclAcl *GRSTgaclAclLoadforFile(char *); - -/* #define GACLisAclFile(x) GRSTgaclFileIsAcl((x)) */ -int GRSTgaclFileIsAcl(char *); - - -/* #define GACLnewUser(x) GRSTgaclUserNew((x)) */ -GRSTgaclUser *GRSTgaclUserNew(GRSTgaclCred *); - -/* #define GACLfreeUser(x) GRSTgaclUserFree((x)) */ -int GRSTgaclUserFree(GRSTgaclUser *); - -/* #define GACLuserAddCred(x,y) GRSTgaclUserAddCred((x),(y)) */ -int GRSTgaclUserAddCred(GRSTgaclUser *, GRSTgaclCred *); - -/* #define GACLuserHasCred(x,y) GRSTgaclUserHasCred((x),(y)) */ -int GRSTgaclUserHasCred(GRSTgaclUser *, GRSTgaclCred *); - -int GRSTgaclUserSetDNlists(GRSTgaclUser *, char *); - -/* #define GACLuserFindCredType(x,y) GRSTgaclUserFindCredtype((x),(y)) */ -GRSTgaclCred *GRSTgaclUserFindCredtype(GRSTgaclUser *, char *); - -/* #define GACLtestDnList(x,y) GRSTgaclDNlistHasUser((x),(y)) */ -int GRSTgaclDNlistHasUser(char *, GRSTgaclUser *); - -/* #define GACLtestUserAcl(x,y) GRSTgaclAclTestUser((x),(y)) */ -GRSTgaclPerm GRSTgaclAclTestUser(GRSTgaclAcl *, GRSTgaclUser *); - -/* #define GACLtestExclAcl(x,y) GRSTgaclAclTestexclUser((x),(y)) */ -GRSTgaclPerm GRSTgaclAclTestexclUser(GRSTgaclAcl *, GRSTgaclUser *); - - -char *GRSThttpUrlDecode(char *); - -/* #define GACLurlEncode(x) GRSThttpUrlEncode((x)) */ -char *GRSThttpUrlEncode(char *); - -/* #define GACLmildUrlEncode(x) GRSThttpMildUrlEncode((x)) */ -char *GRSThttpUrlMildencode(char *); - -int GRSTx509NameCmp(char *, char *); - -int GRSTx509KnownCriticalExts(X509 *); - -int GRSTx509IsCA(X509 *); -int GRSTx509CheckChain(int *, X509_STORE_CTX *); -int GRSTx509VerifyCallback(int, X509_STORE_CTX *); - -int GRSTx509GetVomsCreds(int *, int, size_t, char *, X509 *, STACK_OF(X509) *, char *); -GRSTgaclCred *GRSTx509CompactToCred(char *); -int GRSTx509CompactCreds(int *, int, size_t, char *, STACK_OF(X509) *, char *); -char *GRSTx509CachedProxyFind(char *, char *, char *); -char *GRSTx509FindProxyFileName(void); -int GRSTx509MakeProxyCert(char **, FILE *, char *, char *, char *, int); -char *GRSTx509CachedProxyKeyFind(char *, char *, char *); -int GRSTx509MakeProxyRequest(char **, char *, char *, char *); -int GRSTx509StringToChain(STACK_OF(X509) **, char *); -char *GRSTx509MakeProxyFileName(char *, STACK_OF(X509) *); -int GRSTx509CacheProxy(char *, char *, char *, char *); - -#define GRST_HEADFILE "gridsitehead.txt" -#define GRST_FOOTFILE "gridsitefoot.txt" -#define GRST_ADMIN_FILE "gridsite-admin.cgi" - -typedef struct { char *text; - void *next; } GRSThttpCharsList; - -typedef struct { size_t size; - GRSThttpCharsList *first; - GRSThttpCharsList *last; } GRSThttpBody; - -void GRSThttpBodyInit(GRSThttpBody *); -void GRSThttpPrintf(GRSThttpBody *, char *, ...); -int GRSThttpCopy(GRSThttpBody *, char *); -void GRSThttpWriteOut(GRSThttpBody *); -int GRSThttpPrintHeaderFooter(GRSThttpBody *, char *, char *); -char *GRSThttpGetCGI(char *); - -time_t GRSTasn1TimeToTimeT(char *, size_t); -int GRSTasn1SearchTaglist(struct GRSTasn1TagList taglist[], int, char *); -int GRSTasn1ParseDump(BIO *, unsigned char *, long, - struct GRSTasn1TagList taglist[], int, int *); -int GRSTasn1GetX509Name(char *, int, char *, char *, - struct GRSTasn1TagList taglist[], int); diff --git a/org.gridsite.core/project/build.number b/org.gridsite.core/project/build.number deleted file mode 100644 index e3c0104..0000000 --- a/org.gridsite.core/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Wed Feb 23 03:19:54 CET 2005 -module.build=141 diff --git a/org.gridsite.core/project/build.properties b/org.gridsite.core/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.gridsite.core/project/configure.properties.xml b/org.gridsite.core/project/configure.properties.xml deleted file mode 100644 index 0e83d6e..0000000 --- a/org.gridsite.core/project/configure.properties.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/org.gridsite.core/project/dependencies.properties b/org.gridsite.core/project/dependencies.properties deleted file mode 100644 index 2a7383b..0000000 --- a/org.gridsite.core/project/dependencies.properties +++ /dev/null @@ -1,9 +0,0 @@ -################################################################### -# System dependencies -################################################################### - -org.glite.version = HEAD -org.glite.core.version = HEAD - -# Component dependencies tag = do not remove this line = - diff --git a/org.gridsite.core/project/gridsite.core.csf.xml b/org.gridsite.core/project/gridsite.core.csf.xml deleted file mode 100644 index 7ca38dc..0000000 --- a/org.gridsite.core/project/gridsite.core.csf.xml +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The org.glite and org.gridsite.core modules have been updated, please rerun the configuration file - - - - The org.glite and org.gridsite.core modules have been updated, please rerun the configuration file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.gridsite.core/project/properties.xml b/org.gridsite.core/project/properties.xml deleted file mode 100644 index 74f88dc..0000000 --- a/org.gridsite.core/project/properties.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.gridsite.core/project/taskdefs.xml b/org.gridsite.core/project/taskdefs.xml deleted file mode 100644 index 9c35cef..0000000 --- a/org.gridsite.core/project/taskdefs.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/org.gridsite.core/project/version.properties b/org.gridsite.core/project/version.properties deleted file mode 100644 index 5711198..0000000 --- a/org.gridsite.core/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.1.8 -module.age=1 diff --git a/org.gridsite.core/src/Doxyfile b/org.gridsite.core/src/Doxyfile deleted file mode 100644 index e47d005..0000000 --- a/org.gridsite.core/src/Doxyfile +++ /dev/null @@ -1,993 +0,0 @@ -# Doxyfile 1.2.18 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# General configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, -# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en -# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, -# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian. - -OUTPUT_LANGUAGE = English - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these class will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited -# members of a class in the documentation of that class as if those members were -# ordinary class members. Constructors, destructors and assignment operators of -# the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. It is allowed to use relative paths in the argument list. - -STRIP_FROM_PATH = - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower case letters. If set to YES upper case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# users are adviced to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explict @brief command for a brief description. - -JAVADOC_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# reimplements. - -INHERIT_DOCS = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consist of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. -# For instance some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources -# only. Doxygen will then generate output that is more tailored for Java. -# For instance namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp -# *.h++ *.idl *.odl - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories -# that are symbolic links (a Unix filesystem feature) are excluded from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. - -INPUT_FILTER = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = doxygen - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet - -HTML_STYLESHEET = doxygen.css - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output dir. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non empty doxygen will try to run -# the html help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the Html help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = YES - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+, -# or Internet explorer 4.0+). Note that for large projects the tree generation -# can take a very long time. In such cases it is better to disable this feature. -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimised for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assigments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_XML = NO - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = NO - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_PREDEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse the -# parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::addtions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES tag can be used to specify one or more tagfiles. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or -# super classes. Setting the tag to NO turns the diagrams off. Note that this -# option is superceded by the HAVE_DOT option below. This is only a fallback. It is -# recommended to install and use dot, since it yield more powerful graphs. - -CLASS_DIAGRAMS = YES - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found on the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermedate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::addtions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO - -# The CGI_NAME tag should be the name of the CGI script that -# starts the search engine (doxysearch) with the correct parameters. -# A script with this name will be generated by doxygen. - -CGI_NAME = search.cgi - -# The CGI_URL tag should be the absolute URL to the directory where the -# cgi binaries are located. See the documentation of your http daemon for -# details. - -CGI_URL = - -# The DOC_URL tag should be the absolute URL to the directory where the -# documentation is located. If left blank the absolute path to the -# documentation, with file:// prepended to it, will be used. - -DOC_URL = - -# The DOC_ABSPATH tag should be the absolute path to the directory where the -# documentation is located. If left blank the directory on the local machine -# will be used. - -DOC_ABSPATH = - -# The BIN_ABSPATH tag must point to the directory where the doxysearch binary -# is installed. - -BIN_ABSPATH = /usr/local/bin/ - -# The EXT_DOC_PATHS tag can be used to specify one or more paths to -# documentation generated for other projects. This allows doxysearch to search -# the documentation for these projects as well. - -EXT_DOC_PATHS = diff --git a/org.gridsite.core/src/Makefile b/org.gridsite.core/src/Makefile deleted file mode 100644 index 0acfe92..0000000 --- a/org.gridsite.core/src/Makefile +++ /dev/null @@ -1,339 +0,0 @@ -# -# Andrew McNab and Shiv Kaushal, University of Manchester. -# Copyright (c) 2002-5. All rights reserved. -# -# Redistribution and use in source and binary forms, with or -# without modification, are permitted provided that the following -# conditions are met: -# -# o Redistributions of source code must retain the above -# copyright notice, this list of conditions and the following -# disclaimer. -# o 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. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. -# -#--------------------------------------------------------------- -# For more information about GridSite: http://www.gridsite.org/ -#--------------------------------------------------------------- - -include ../VERSION - -RPMCMD=$(shell if [ -x /usr/bin/rpmbuild ] ; then echo /usr/bin/rpmbuild; else echo rpm; fi) - -ifndef MYRPMDIR -export MYRPMDIR=$(shell pwd)/../RPMTMP -endif - -ifndef prefix -export prefix=/usr/local -endif - -ifndef MYCFLAGS -export MYCFLAGS=-I. -I../interface -I/usr/include/httpd -I/usr/include/apr-0 -I/opt/glite/include -endif - -ifndef MYLDFLAGS -export MYLDFLAGS=-L. -endif - -# -# Build -# - -build: libgridsite.so.$(VERSION) libgridsite.a htcp mod_gridsite.so \ - urlencode findproxyfile real-gridsite-admin.cgi \ - # gridsite-delegation.cgi # htproxyput - -build: libgridsite_globus.so.$(VERSION) libgridsite_globus.a - -# First, normal versions using system OpenSSL rather than Globus OpenSSL - -libgridsite.so.$(VERSION): grst_x509.o grst_gacl.o grst_http.o grst_asn1.o - gcc -shared -Wl,-soname,libgridsite.so.$(MINOR_VERSION) \ - -o libgridsite.so.$(PATCH_VERSION) grst_x509.o grst_gacl.o grst_http.o grst_asn1.o - -libgridsite.a: grst_x509.o grst_gacl.o grst_http.o grst_asn1.o - ar src libgridsite.a grst_x509.o grst_gacl.o grst_http.o grst_asn1.o - -grst_x509.o: grst_x509.c ../interface/gridsite.h - gcc $(MYCFLAGS) \ - -I/usr/kerberos/include -c grst_x509.c - -grst_gacl.o: grst_gacl.c ../interface/gridsite.h - gcc $(MYCFLAGS) \ - -I/usr/kerberos/include `xml2-config --cflags` -c grst_gacl.c - -grst_http.o: grst_http.c ../interface/gridsite.h - gcc $(MYCFLAGS) \ - -I/usr/kerberos/include -c grst_http.c - -grst_asn1.o: grst_asn1.c ../interface/gridsite.h - gcc $(MYCFLAGS) \ - -I/usr/kerberos/include -c grst_asn1.c - -# Then build versions using Globus OpenSSL if configured - -ifdef OPENSSL_GLOBUS_LIBS - -libgridsite_globus.so.$(VERSION): \ - grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o \ - grst_asn1_globus.o - gcc -shared -Wl,-soname,libgridsite_globus.so.$(MINOR_VERSION) \ - -o libgridsite_globus.so.$(PATCH_VERSION) \ - grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o grst_asn1_globus.o - -libgridsite_globus.a: grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o grst_asn1_globus.o - ar src libgridsite_globus.a \ - grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o grst_asn1_globus.o - -grst_x509_globus.o: grst_x509.c ../interface/gridsite.h - gcc $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ - -I/usr/kerberos/include -c grst_x509.c \ - -o grst_x509_globus.o - -grst_gacl_globus.o: grst_gacl.c ../interface/gridsite.h - gcc $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ - -I/usr/kerberos/include `xml2-config --cflags` -c grst_gacl.c \ - -o grst_gacl_globus.o - -grst_http_globus.o: grst_http.c ../interface/gridsite.h - gcc $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ - -I/usr/kerberos/include -c grst_http.c \ - -o grst_http_globus.o - -grst_asn1_globus.o: grst_asn1.c ../interface/gridsite.h - gcc $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ - -I/usr/kerberos/include -c grst_asn1.c \ - -o grst_asn1_globus.o - -else - -libgridsite_globus.so.$(VERSION): libgridsite.so.$(VERSION) - cp -f libgridsite.so.$(VERSION) libgridsite_globus.so.$(VERSION) - -libgridsite_globus.a: libgridsite.a - cp -f libgridsite.a libgridsite_globus.a - -endif - -urlencode: urlencode.c libgridsite.a - gcc -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) \ - -o urlencode urlencode.c -L. \ - -I/usr/kerberos/include -lgridsite - -htcp: htcp.c - gcc -DVERSION=\"$(PATCH_VERSION)\" -I. -o htcp htcp.c \ - `curl-config --cflags` `curl-config --libs` - -mod_gridsite.so: mod_gridsite.c mod_ssl-private.h libgridsite.a - gcc $(MYCFLAGS) -shared -Wl,-soname=gridsite_module \ - -I/usr/kerberos/include \ - -I/usr/include/libxml2 \ - -DVERSION=\"$(VERSION)\" -o mod_gridsite.so \ - mod_gridsite.c $(MYLDFLAGS) -lxml2 -lm -lz -lgridsite - -real-gridsite-admin.cgi: grst_admin_main.c grst_admin_gacl.c \ - grst_admin_file.c grst_admin.h - gcc $(MYCFLAGS) $(MYLDFLAGS) -o real-gridsite-admin.cgi \ - grst_admin_main.c \ - grst_admin_gacl.c \ - grst_admin_file.c \ - -I/usr/kerberos/include \ - -DVERSION=\"$(VERSION)\" -lgridsite -lssl -lcrypto -lxml2 -lz -lm - -findproxyfile: findproxyfile.c libgridsite.a - gcc -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) $(MYLDFLAGS) \ - -o findproxyfile findproxyfile.c -L. \ - -I/usr/kerberos/include -lgridsite \ - -lssl -lcrypto -lxml2 -lz -lm - -showx509exts: showx509exts.c libgridsite.a - gcc -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) $(MYLDFLAGS) \ - -o showx509exts showx509exts.c -L. \ - -I/usr/kerberos/include \ - -lgridsite \ - -lssl -lcrypto - -apidoc: - doxygen Doxyfile - -gaclexample: gaclexample.c libgridsite.a - gcc -o gaclexample gaclexample.c -I. -L. \ - -I/usr/kerberos/include -lgridsite \ - -lssl -lcrypto -lxml2 -lz -lm - -# -# Delegation machinery, including SOAP delegation portType. To build this -# you need to install gSOAP and set GSOAPDIR to the directory containing -# soapcpp2 and stdsoap2.h (unless GSOAPDIR is set already) -# - -ifndef GSOAPDIR -export GSOAPDIR=/usr/local/lib/gsoap -endif - -delegation.wsdl: delegation.h - ls -lR $(GSOAPDIR) - $(GSOAPDIR)/bin/soapcpp2 -c delegation.h - -libstdsoap2.a: $(GSOAPDIR)/stdsoap2.c - gcc -c -DWITH_OPENSSL $(GSOAPDIR)/stdsoap2.c - ar src libstdsoap2.a stdsoap2.o - -gridsite-delegation.cgi: grst-delegation.c delegation.h delegation.wsdl \ - soapC.c soapServer.c - gcc $(MYCFLAGS) $(MYLDFLAGS) -o gridsite-delegation.cgi \ - grst-delegation.c \ - -I/usr/kerberos/include -I$(GSOAPDIR)/include \ - -DVERSION=\"$(VERSION)\" -L$(GSOAPDIR)/lib \ - soapC.c soapServer.c -lgsoap \ - -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm - -htproxyput: htproxyput.c delegation.h delegation.wsdl \ - soapC.c soapServer.c - gcc $(MYCFLAGS) $(MYLDFLAGS) -o htproxyput \ - htproxyput.c \ - -I/usr/kerberos/include \ - -g -DVERSION=\"$(VERSION)\" \ - -I$(GSOAPDIR)/include -DWITH_OPENSSL -L$(GSOAPDIR)/lib \ - soapC.c soapClient.c -lgsoap \ - -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm - -proxyput-example: proxyput-example.c delegation.h delegation.wsdl \ - soapC.c soapServer.c - gcc $(MYCFLAGS) $(MYLDFLAGS) -o proxyput-example \ - proxyput-example.c \ - -I/usr/kerberos/include \ - -g -DVERSION=\"$(VERSION)\" \ - -I$(GSOAPDIR) -DWITH_OPENSSL \ - soapC.c soapClient.c libstdsoap2.a \ - -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm - -clean: - -# -# Install -# - -install: apidoc - mkdir -p $(prefix)/include \ - $(prefix)/lib \ - $(prefix)/bin \ - $(prefix)/sbin \ - $(prefix)/share/man/man1 \ - $(prefix)/lib/httpd/modules \ - $(prefix)/share/doc/gridsite-$(PATCH_VERSION) - cp -f ../interface/gridsite.h $(prefix)/include - cp -f ../interface/gridsite-gacl.h $(prefix)/include - cp -f urlencode $(prefix)/bin - cp -f findproxyfile $(prefix)/bin - cp -f real-gridsite-admin.cgi $(prefix)/sbin - cp -f libgridsite.a $(prefix)/lib - cp -f libgridsite.so.$(PATCH_VERSION) $(prefix)/lib - ln -sf libgridsite.so.$(PATCH_VERSION) \ - $(prefix)/lib/libgridsite.so - ln -sf libgridsite.so.$(PATCH_VERSION) \ - $(prefix)/lib/libgridsite.so.$(MAJOR_VERSION) - ln -sf libgridsite.so.$(PATCH_VERSION) \ - $(prefix)/lib/libgridsite.so.$(MINOR_VERSION) - cp -f libgridsite_globus.a $(prefix)/lib - cp -f libgridsite_globus.so.$(PATCH_VERSION) $(prefix)/lib - ln -sf libgridsite_globus.so.$(PATCH_VERSION) \ - $(prefix)/lib/libgridsite_globus.so - ln -sf libgridsite_globus.so.$(PATCH_VERSION) \ - $(prefix)/lib/libgridsite_globus.so.$(MAJOR_VERSION) - ln -sf libgridsite_globus.so.$(PATCH_VERSION) \ - $(prefix)/lib/libgridsite_globus.so.$(MINOR_VERSION) - cp -f doxygen/index.html \ - $(prefix)/share/doc/gridsite-$(PATCH_VERSION)/doxygen-index.html - cp -f doxygen/* $(prefix)/share/doc/gridsite-$(PATCH_VERSION) - cp -f ../CHANGES ../README ../INSTALL ../LICENSE ../VERSION \ - $(prefix)/share/doc/gridsite-$(PATCH_VERSION) - cp -f ../doc/*.html ../doc/*.conf ../doc/*.1 ../doc/*.sh \ - $(prefix)/share/doc/gridsite-$(VERSION) - cp -f ../doc/*.1 $(prefix)/share/man/man1 - gzip -f $(prefix)/share/man/man1/*.1 - cd ../doc ; for i in *.1 ; do ../src/roffit < $$i \ - > $(prefix)/share/doc/gridsite-$(VERSION)/$$i.html ; done - cp -f htcp $(prefix)/bin - ln -sf htcp $(prefix)/bin/htls - ln -sf htcp $(prefix)/bin/htll - ln -sf htcp $(prefix)/bin/htrm - ln -sf htcp $(prefix)/bin/htmkdir - cp -f mod_gridsite.so $(prefix)/lib/httpd/modules - -# -# Distributions -# - -# source files tarball -dist: - mkdir -p ../gridsite-$(PATCH_VERSION)/src \ - ../gridsite-$(PATCH_VERSION)/doc \ - ../gridsite-$(PATCH_VERSION)/interface - cp -f ../VERSION ../README ../LICENSE ../CHANGES ../INSTALL \ - ../gridsite-$(PATCH_VERSION) - cp -f Makefile grst*.c htproxyput.c proxyput-example.c htcp.c \ - urlencode.c findproxyfile.c gaclexample.c mod_gridsite.c \ - delegation.h grst_admin.h mod_ssl-private.h \ - roffit gridsite.spec \ - Doxyfile doxygen.css doxyheader.html \ - ../gridsite-$(PATCH_VERSION)/src - cp -f ../doc/*.html ../doc/*.1 ../doc/*.conf ../doc/*.sh \ - ../gridsite-$(PATCH_VERSION)/doc - cp -f ../interface/*.h \ - ../gridsite-$(PATCH_VERSION)/interface - cd .. ; tar zcvf gridsite-$(PATCH_VERSION).src.tar.gz \ - gridsite-$(PATCH_VERSION) - rm -Rf ../gridsite-$(PATCH_VERSION) - - -# binary tarball distribution for htcp users -htcp-bin: htcp - mkdir -p ../htcp-bin-$(PATCH_VERSION)/bin \ - ../htcp-bin-$(PATCH_VERSION)/man/man1 - cp -f ../doc/README.htcp-bin ../htcp-bin-$(PATCH_VERSION) - cp -f htcp ../htcp-bin-$(PATCH_VERSION)/bin - cp -f ../doc/htcp.1 ../doc/htrm.1 ../doc/htls.1 ../doc/htll.1 \ - ../doc/htmkdir.1 ../htcp-bin-$(PATCH_VERSION)/man/man1 - ln -sf htcp ../htcp-bin-$(PATCH_VERSION)/bin/htls - ln -sf htcp ../htcp-bin-$(PATCH_VERSION)/bin/htll - ln -sf htcp ../htcp-bin-$(PATCH_VERSION)/bin/htrm - ln -sf htcp ../htcp-bin-$(PATCH_VERSION)/bin/htmkdir - cd ../htcp-bin-$(VERSION) ; tar zcvf ../htcp-$(VERSION).bin.tar.gz . - rm -Rf ../htcp-bin-$(PATCH_VERSION) - -# RPM targets: build and RPMs go into subdirectories of ../RPMTMP/ -rpm: dist gridsite.spec - rm -Rf $(MYRPMDIR)/BUILDROOT $(MYRPMDIR)/BUILD - mkdir -p $(MYRPMDIR)/SOURCES $(MYRPMDIR)/SPECS $(MYRPMDIR)/BUILD \ - $(MYRPMDIR)/SRPMS $(MYRPMDIR)/RPMS/i386 $(MYRPMDIR)/BUILDROOT - cp -f ../gridsite-$(PATCH_VERSION).src.tar.gz $(MYRPMDIR)/SOURCES - cp -f gridsite.spec $(MYRPMDIR)/SPECS - export MYPREFIX=/usr ; export MYVERSION=$(PATCH_VERSION) ; \ - $(RPMCMD) --define "_topdir $(MYRPMDIR)" \ - -ba --buildroot $(MYRPMDIR)/BUILDROOT gridsite.spec - - -wtf: - pwd - printenv - ls -l - ls -lR /usr/local/ - ls -lR $(GSOAPDIR) diff --git a/org.gridsite.core/src/delegation.h b/org.gridsite.core/src/delegation.h deleted file mode 100644 index e612498..0000000 --- a/org.gridsite.core/src/delegation.h +++ /dev/null @@ -1,12 +0,0 @@ -//gsoap ns service name: delegation -//gsoap ns service style: rpc -//gsoap ns service encoding: encoded -//gsoap ns service namespace: http://www.gridsite.org/ns/delegation.wsdl -//gsoap ns service location: http://localhost/delegserver.cgi - -struct ns__putProxyResponse { } ; - -//gsoap ns schema namespace: urn:delegation -int ns__getProxyReq(char *delegationID, char **request); -int ns__putProxy(char *delegationID, char *proxy, - struct ns__putProxyResponse *unused); diff --git a/org.gridsite.core/src/doxygen.css b/org.gridsite.core/src/doxygen.css deleted file mode 100644 index 97ebc25..0000000 --- a/org.gridsite.core/src/doxygen.css +++ /dev/null @@ -1,49 +0,0 @@ -H1 { text-align: center; } -CAPTION { font-weight: bold } -A.qindex {} -A.qindexRef {} -A.el { text-decoration: none; font-weight: bold } -A.elRef { font-weight: bold } -A.code { text-decoration: none; font-weight: normal; color: #4444ee } -A.codeRef { font-weight: normal; color: #4444ee } -A:hover { text-decoration: none; background-color: #f2f2ff } -DL.el { margin-left: -1cm } -DIV.fragment { width: 100%; border: none; background-color: #eeeeee } -DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } -TD.md { background-color: #f2f2ff; font-weight: bold; } -TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; } -TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; width: 600px; } -DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold } -DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller } -XXBODY { background: white } -TD.indexkey { - background-color: #eeeeff; - font-weight: bold; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} -TD.indexvalue { - background-color: #eeeeff; - font-style: italic; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} -span.keyword { color: #008000 } -span.keywordtype { color: #604020 } -span.keywordflow { color: #e08000 } -span.comment { color: #800000 } -span.preprocessor { color: #806020 } -span.stringliteral { color: #002080 } -span.charliteral { color: #008080 } diff --git a/org.gridsite.core/src/doxyheader.html b/org.gridsite.core/src/doxyheader.html deleted file mode 100644 index af78b52..0000000 --- a/org.gridsite.core/src/doxyheader.html +++ /dev/null @@ -1 +0,0 @@ -

GridSite Version 1.1.x diff --git a/org.gridsite.core/src/findproxyfile.c b/org.gridsite.core/src/findproxyfile.c deleted file mode 100644 index 4485cc5..0000000 --- a/org.gridsite.core/src/findproxyfile.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - Copyright (c) 2002-4, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. -*/ - -#ifndef VERSION -#define VERSION "0.0.0" -#endif - -#define _GNU_SOURCE - -#include -#include -#include -#include - -#include - -#include "gridsite.h" - -void printsyntax(char *argv0) -{ - char *p; - - p = rindex(argv0, '/'); - if (p != NULL) ++p; - else p = argv0; - - fprintf(stderr, "%s [--outsidecache] [--proxycache=PATH] " - "[--delegation-id=DELEGATION-ID] [--user-dn=USER-DN]\n" - "(Version: %s)\n", p, VERSION); -} - -#define GRST_PROXY_CACHE "/var/www/proxycache" - -int main(int argc, char *argv[]) -{ - char *delegation_id = "_", *proxycache = "", *user_dn = "", - *proxyfile = NULL; - int c, outsidecache = 0, verbose = 0, option_index; - struct option long_options[] = { {"verbose", 0, 0, 'v'}, - {"outsidecache", 0, 0, 0}, - {"proxycache", 1, 0, 0}, - {"delegation-id", 1, 0, 0}, - {"user-dn", 1, 0, 0}, - {0, 0, 0, 0} }; - - if (argc == 1) - { - printsyntax(argv[0]); - return 0; - } - - while (1) - { - option_index = 0; - - c = getopt_long(argc, argv, "v", long_options, &option_index); - - if (c == -1) break; - else if (c == 0) - { - if (option_index == 1) outsidecache = 1; - else if (option_index == 2) proxycache = optarg; - else if (option_index == 3) delegation_id = optarg; - else if (option_index == 4) user_dn = optarg; - } - else if (c == 'v') ++verbose; - } - - if (*user_dn != '\0') /* try to find in proxy cache */ - { - if ((proxycache == NULL) || (*proxycache == '\0')) - proxycache = getenv("GRST_PROXY_CACHE"); - - if ((proxycache == NULL) || (*proxycache == '\0')) - proxycache = GRST_PROXY_CACHE; - - proxyfile = GRSTx509CachedProxyFind(proxycache, delegation_id, user_dn); - } - - if (((proxyfile == NULL) || (*proxyfile == '\0')) && outsidecache) - { - proxyfile = GRSTx509FindProxyFileName(); - } - - if ((proxyfile != NULL) && (*proxyfile != '\0')) - { - puts(proxyfile); - return 0; - } - - fputs("No proxy file found\n", stderr); - - return 1; -} diff --git a/org.gridsite.core/src/gaclexample.c b/org.gridsite.core/src/gaclexample.c deleted file mode 100644 index 5ad29b7..0000000 --- a/org.gridsite.core/src/gaclexample.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright (c) 2002-3, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. -*/ - -/*---------------------------------------------------------------* - * For more about GridSite: http://www.gridsite.org/ * - *---------------------------------------------------------------*/ - -/* - Example program using GACL - - Build with: - - gcc -o gaclexample gaclexample.c -L. -I. -lgridsite -lxml2 -lz -lm -*/ - -#include -#include -#include -#include - -int main() -{ - GRSTgaclCred *cred, *usercred; - GRSTgaclEntry *entry; - GRSTgaclAcl *acl1, *acl2; - GRSTgaclUser *user; - GRSTgaclPerm perm0, perm1, perm2; - FILE *fp; - - /* must initialise GACL before using it */ - - GRSTgaclInit(); - - /* build up an ACL, starting with a credential */ - - cred = GRSTgaclCredNew("person"); - - GRSTgaclCredAddValue(cred, "dn", "/O=Grid/CN=Mr Grid Person"); - - /* create an entry to put it in */ - - entry = GRSTgaclEntryNew(); - - /* add the credential to it */ - - GRSTgaclEntryAddCred(entry, cred); - - /* add another credential */ - - cred = GRSTgaclCredNew("dn-list"); - GRSTgaclCredAddValue(cred, "url", "example-dn-list"); - GRSTgaclEntryAddCred(entry, cred); - - fp = fopen("example-dn-list", "w"); - fputs("/O=Grid/CN=Mr Grid Person\n", fp); - fclose(fp); - - /* associate some permissions and denials to the credential */ - - GRSTgaclEntryAllowPerm( entry, GRST_PERM_READ); - GRSTgaclEntryAllowPerm( entry, GRST_PERM_WRITE); - GRSTgaclEntryAllowPerm( entry, GRST_PERM_ADMIN); - GRSTgaclEntryDenyPerm( entry, GRST_PERM_ADMIN); - GRSTgaclEntryDenyPerm( entry, GRST_PERM_LIST); - - perm0 = GRST_PERM_READ | GRST_PERM_WRITE; - - printf("test perm should be %d\n", perm0); - - /* create a new ACL and add the entry to it */ - - acl1 = GRSTgaclAclNew(); - - GRSTgaclAclAddEntry(acl1, entry); - - /* create a GRSTgaclUser to compare with the ACL */ - - usercred = GRSTgaclCredNew("person"); - - GRSTgaclCredAddValue(usercred, "dn", "/O=Grid/CN=Mr Grid Person"); - - user = GRSTgaclUserNew(usercred); - - GRSTgaclUserSetDNlists(user, getcwd(NULL, 0)); - printf("DN Lists dir %s\n", getcwd(NULL, 0)); - -// putenv("GRST_DN_LISTS=."); - - perm1 = GRSTgaclAclTestUser(acl1, user); - - printf("test /O=Grid/CN=Mr Grid Person in acl = %d\n", perm1); - - /* print and save the whole ACL */ - - GRSTgaclAclPrint(acl1, stdout); - - GRSTgaclAclSave(acl1, "example.gacl"); - - puts("gridacl.out saved"); - - puts(""); - - /* load the ACL back off the disk, print and test it */ - - acl2 = GRSTgaclAclLoadFile("example.gacl"); - - puts("gridacl.out loaded"); - - if (acl2 != NULL) GRSTgaclAclPrint(acl2, stdout); else puts("acl2 is NULL"); - - perm2 = GRSTgaclAclTestUser(acl2, user); - - printf("test /O=Grid/CN=Mr Grid Person in acl = %d\n", perm2); - - if (perm1 != perm0) return 1; - if (perm2 != perm0) return 2; - - return 0; -} diff --git a/org.gridsite.core/src/gridsite.spec b/org.gridsite.core/src/gridsite.spec deleted file mode 100644 index 5bf3b16..0000000 --- a/org.gridsite.core/src/gridsite.spec +++ /dev/null @@ -1,85 +0,0 @@ -Name: gridsite -Version: %(echo ${MYVERSION:-1.1.x}) -Release: 1 -Summary: GridSite -Copyright: Modified BSD -Group: System Environment/Daemons -Source: %{name}-%{version}.src.tar.gz -Prefix: %(echo ${MYPREFIX:-/usr}) -URL: http://www.gridsite.org/ -Vendor: GridPP -#Requires: libxml2,curl-ssl,mod_ssl -#Buildrequires: libxml2-devel,curl-ssl-devel,httpd-devel -Packager: Andrew McNab - -%description -GridSite adds GSI, VOMS and GACL support to Apache 2.0 (mod_gridsite), -a library for manipulating these technologies (libgridsite), and CGI -programs for interactive management of HTTP(S) servers (gridsite-admin.cgi) - -See %(echo ${MYPREFIX:-/usr})/share/doc/gridsite-%{version} and -http://www.gridsite.org/ for details. - -%package -n htcp -Group: Applications/Internet -Summary: HTTP(S) read/write client -#Requires: curl-ssl - -%description -n htcp -htcp is a client to fetch files or directory listings from remote -servers using HTTP or HTTPS, or to put or delete files or directories -onto remote servers using HTTPS. htcp is similar to scp(1), but uses -HTTP/HTTPS rather than ssh as its transfer protocol. - -%prep - -%setup - -%build -cd src -make prefix=$RPM_BUILD_ROOT/%(echo ${MYPREFIX:-/usr}) \ -GSOAPDIR=$GSOAPDIR OPENSSL_FLAGS=$OPENSSL_FLAGS \ -OPENSSL_LIBS=$OPENSSL_LIBS FLAVOR_EXT=$FLAVOR_EXT - -%install -cd src -make install prefix=$RPM_BUILD_ROOT/%(echo ${MYPREFIX:-/usr}) \ -GSOAPDIR=$GSOAPDIR OPENSSL_FLAGS=$OPENSSL_FLAGS \ -OPENSSL_LIBS=$OPENSSL_LIBS FLAVOR_EXT=$FLAVOR_EXT - -%post -/sbin/ldconfig -ln -sf %(echo ${MYPREFIX:-/usr})/share/doc/gridsite-%{version} \ - %(echo ${MYPREFIX:-/usr})/share/doc/gridsite - -%postun -rm -f %(echo ${MYPREFIX:-/usr})/share/doc/gridsite - -%files -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite.so.%{version} -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite.so -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite_globus.so.%{version} -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite_globus.so -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/bin/urlencode -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/bin/findproxyfile -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/doc/gridsite-%{version} -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/urlencode.1.gz -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/findproxyfile.1.gz -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/include/gridsite.h -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/include/gridsite-gacl.h -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite.a -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite_globus.a -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/httpd/modules/mod_gridsite.so -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/sbin/real-gridsite-admin.cgi - -%files -n htcp -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/bin/htcp -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/bin/htls -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/bin/htll -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/bin/htrm -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/bin/htmkdir -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/htcp.1.gz -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/htrm.1.gz -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/htls.1.gz -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/htll.1.gz -%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/htmkdir.1.gz diff --git a/org.gridsite.core/src/grst-delegation.c b/org.gridsite.core/src/grst-delegation.c deleted file mode 100644 index c8f8185..0000000 --- a/org.gridsite.core/src/grst-delegation.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - Copyright (c) 2002-4, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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 program is part of GridSite: http://www.gridpp.ac.uk/authz/gridsite/ * - *---------------------------------------------------------------------------*/ - -#ifndef VERSION -#define VERSION "0.0.1" -#endif - -#define _GNU_SOURCE -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -/* #include */ - -#include "gridsite.h" - -#include "soapH.h" -#include "delegation.nsmap" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define GRST_KEYSIZE 512 -#define GRST_PROXYCACHE "/../proxycache/" -#define GRST_SUPPORT_G_HTTPS - -#ifdef GRST_SUPPORT_G_HTTPS -void GRSThttpError(char *status) -{ - printf("Status: %s\n", status); - printf("Server-CGI: GridSite %s\n", VERSION); - printf("Content-Length: %d\n", 2 * strlen(status) + 58); - puts("Content-Type: text/html\n"); - - printf("%s\n", status); - printf("

%s

\n", status); - - exit(0); -} - -int GRSTmethodPutProxy(char *delegation_id, char *user_dn) -/* return 0 on success; non-zero on error */ -{ - int c, len = 0, i; - char *docroot, *contentlen, *contenttype, *proxychain, *proxydir; - FILE *fp; - - if (((contenttype = getenv("CONTENT_TYPE")) == NULL) || - (strcmp(contenttype, "application/x-x509-user-cert-chain") != 0)) - return 2; - - contentlen = getenv("CONTENT_LENGTH"); - if (contentlen == NULL) return 2; - len = atoi(contentlen); - - if ((delegation_id == NULL) || (*delegation_id == '\0')) - delegation_id = "_"; - - docroot = getenv("DOCUMENT_ROOT"); - asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - - if ((user_dn == NULL) || (user_dn[0] == '\0') || - (GRSTx509CacheProxy(proxydir, delegation_id, user_dn, proxychain) - != GRST_RET_OK)) - { - return GRST_RET_FAILED; - } - - free(proxydir); - - return GRST_RET_OK; -} -#endif - -int main(int argn, char *argv[]) -{ - char *docroot, *method, *request, *p, *client_dn, *user_dn, - *delegation_id, *reqtxt, *proxydir; - struct soap soap; - -chdir("/var/tmp"); - - method = getenv("REQUEST_METHOD"); - if (strcmp(method, "POST") == 0) - { - soap_init(&soap); - soap_serve(&soap); /* CGI application */ - return 0; - } - -#ifdef GRST_SUPPORT_G_HTTPS - docroot = getenv("DOCUMENT_ROOT"); - - request = strdup(getenv("REQUEST_URI")); - p = index(request, '?'); - if (p != NULL) *p = '\0'; - - - /* non HTTP POST methods - ie special G-HTTPS methods */ - - delegation_id = getenv("HTTP_DELEGATION_ID"); - if ((delegation_id == NULL) || (*delegation_id == '\0')) delegation_id = "_"; - - user_dn = NULL; - client_dn = getenv("SSL_CLIENT_S_DN"); - if (client_dn != NULL) - { - user_dn = strdup(client_dn); - - /* we assume here that mod_ssl has verified proxy chain already ... */ - - p = strstr(user_dn, "/CN=proxy"); - if (p != NULL) *p = '\0'; - - p = strstr(user_dn, "/CN=limited proxy"); - if (p != NULL) *p = '\0'; - } - - if (user_dn == NULL) /* all methods require client auth */ - { - GRSThttpError("403 Forbidden"); - } - else if (strcmp(method, "GET-PROXY-REQ") == 0) - { - docroot = getenv("DOCUMENT_ROOT"); - asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - - if (GRSTx509MakeProxyRequest(&reqtxt, proxydir, - delegation_id, user_dn) == 0) - { - puts("Status: 200 OK"); - puts("Content-Type: application/x-x509-cert-request"); - printf("Content-Length: %d\n\n", strlen(reqtxt)); - fputs(reqtxt, stdout); - free(proxydir); - return 0; - } - - puts("Status: 500 Internal Server Error\n"); - free(proxydir); - return 0; - } - else if (strcmp(method, "PUT-PROXY-CERT") == 0) - { - if (GRSTmethodPutProxy(delegation_id, user_dn) == 0) - { - puts("Status: 200 OK\n"); - return 0; - } - - puts("Status: 500 Internal Server Error\n"); - return 0; - } - else - { - GRSThttpError("501 Method Not Implemented"); - } -#endif -} - -int ns__getProxyReq(struct soap *soap, char *delegation_id, - char **request) -{ - char *p, *client_dn, *user_dn, *docroot, *proxydir; - - user_dn = NULL; - client_dn = getenv("SSL_CLIENT_S_DN"); - if (client_dn != NULL) - { - user_dn = strdup(client_dn); - - /* we assume here that mod_ssl has verified proxy chain already ... */ - - p = strstr(user_dn, "/CN=proxy"); - if (p != NULL) *p = '\0'; - - p = strstr(user_dn, "/CN=limited proxy"); - if (p != NULL) *p = '\0'; - } - - if ((delegation_id == NULL) || (*delegation_id == '\0')) delegation_id = "_"; - - docroot = getenv("DOCUMENT_ROOT"); - asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - - if ((user_dn != NULL) && (user_dn[0] != '\0') && - (GRSTx509MakeProxyRequest(request, proxydir, - delegation_id, user_dn) == 0)) - { - return SOAP_OK; - } - - return SOAP_ERR; -} - -int ns__putProxy(struct soap *soap, char *delegation_id, - char *proxy, - struct ns__putProxyResponse *unused) -{ - int fd, c, len = 0, i; - char *docroot, *proxydir, *p, *client_dn, *user_dn; - - user_dn = NULL; - client_dn = getenv("SSL_CLIENT_S_DN"); - if (client_dn != NULL) - { - user_dn = strdup(client_dn); - - /* we assume here that mod_ssl has verified proxy chain already ... */ - - p = strstr(user_dn, "/CN=proxy"); - if (p != NULL) *p = '\0'; - - p = strstr(user_dn, "/CN=limited proxy"); - if (p != NULL) *p = '\0'; - } - - if ((delegation_id == NULL) || (*delegation_id == '\0')) - delegation_id = "_"; - - docroot = getenv("DOCUMENT_ROOT"); - asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - - if ((user_dn == NULL) || (user_dn[0] == '\0') || - (GRSTx509CacheProxy(proxydir, delegation_id, user_dn, proxy) - != GRST_RET_OK)) - { - return SOAP_ERR; - } - - return SOAP_OK; -} - diff --git a/org.gridsite.core/src/grst_admin.h b/org.gridsite.core/src/grst_admin.h deleted file mode 100644 index cddc415..0000000 --- a/org.gridsite.core/src/grst_admin.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (c) 2002-3, Andrew McNab and Shiv Kaushal, - University of Manchester. All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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 program is part of GridSite: http://www.gridsite.org/ * - *------------------------------------------------------------------*/ - -void GRSThttpError(char *); -void adminfooter(GRSThttpBody *, char *, char *, char *, char *); -int GRSTstrCmpShort(char *, char *); -char *makevfilename(char *, size_t, char *); - -/*CGI GACL - Edit interface functions*/ -void show_acl(int admin, GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void new_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void new_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void edit_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void edit_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void add_cred_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void add_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_entry_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_cred_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); - -/*Functions producing messages*/ -//void error(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void admin_continue(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file, GRSThttpBody *bp); - diff --git a/org.gridsite.core/src/grst_admin_file.c b/org.gridsite.core/src/grst_admin_file.c deleted file mode 100644 index f89a004..0000000 --- a/org.gridsite.core/src/grst_admin_file.c +++ /dev/null @@ -1,1571 +0,0 @@ -/* - Copyright (c) 2002-3, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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 program is part of GridSite: http://www.gridsite.org/ * - *------------------------------------------------------------------*/ - -#ifndef VERSION -#define VERSION "x.x.x" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// when porting: remember that sendfile() is very OS-specific! -#include - -#include - -#include "grst_admin.h" - -char *storeuploadfile(char *boundary, int *bufferused) -{ -// rewrite this to copy whole POSTed stdin HTTP body to disk then -// mmap() and pick apart? How to deal with 100MB uploaded files, say? - - char *filebuffer = NULL; - int bufferlen = 0, c, boundarylen; - - *bufferused = 0; - boundarylen = strlen(boundary); - - while ((c = getchar()) != EOF) - { - if (*bufferused > 1024*1024*100) return NULL; - - ++(*bufferused); - - if (*bufferused > bufferlen) - { - bufferlen = bufferlen + 1000; - filebuffer = realloc(filebuffer, (size_t) bufferlen); - } - - filebuffer[*bufferused - 1] = c; - - if ( (*bufferused >= boundarylen + 4) && - (boundary[boundarylen-1] == c) && - (boundary[boundarylen-2] == filebuffer[*bufferused - 2]) && - (strncmp(boundary, &filebuffer[*bufferused - boundarylen], - boundarylen) == 0)) - { - *bufferused = *bufferused - boundarylen - 4; - - if (filebuffer == NULL) return strdup(""); - else return filebuffer; - } - } - - return NULL; -} - -void uploadfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *dir_uri, char *admin_file) -{ - char *boundary, *p, oneline[200], *filename = NULL, - tmpfilename[256], *filebuffer = NULL, *filepath, - *vfile, *dir_path_vfile; - int mimestate, bufferused = 0, itworked = 0; - FILE *fp; - GRSThttpBody bp; - -#define MIMESTUNKNOWN 1 -#define MIMESTUPLOAD 2 -#define MIMESTFILENM 3 - - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - - p = getenv("CONTENT_TYPE"); - boundary = &p[30]; - - mimestate = MIMESTUNKNOWN; - - while (fgets(oneline, sizeof(oneline), stdin) != NULL) - { - if (*oneline == 13) // MIME has CR/LF line breaks, CR=13 - { - if (mimestate == MIMESTUPLOAD) - { - filebuffer = storeuploadfile(boundary, &bufferused); - mimestate = MIMESTUNKNOWN; - } - else if (mimestate == MIMESTFILENM) - { - fgets(tmpfilename, sizeof(tmpfilename), stdin); - if (*tmpfilename != 13) - { - p = index(tmpfilename, 13); - *p = '\0'; - filename = strdup(tmpfilename); - } - mimestate = MIMESTUNKNOWN; - } - } - else if (GRSTstrCmpShort(oneline, - "Content-Disposition: form-data; name=\"uploadfile\"; filename=\"") - == 0) - { - mimestate = MIMESTUPLOAD; - if (filename == NULL) - { - filename = strdup(&oneline[61]); - - p = rindex(&oneline[61], '\\'); - if (p != NULL) { ++p ; filename = p; } - - p = rindex(&oneline[61], '/'); - if (p != NULL) { ++p ; filename = p; } - - p = index(filename, '"'); - if (p != NULL) *p = '\0'; - } - } - else if (GRSTstrCmpShort(oneline, - "Content-Disposition: form-data; name=\"file\"") == 0) - { - mimestate = MIMESTFILENM; - } - } - - if ((filebuffer != NULL) && (bufferused >= 0)) - { - if (filename == NULL) GRSThttpError("403 Forbidden"); - else if ((index(filename, '/') != NULL) || - (strcmp(filename, GRST_ACL_FILE) == 0)) - { - puts("Status: 403 Forbidden filename\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Forbidden filename %s\n", filename); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Forbidden filename %s

\n", - filename); - - GRSThttpPrintf(&bp, - "

New file names cannot include slashes " - "or use the reserved ACL name, %s\n", GRST_ACL_FILE); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); - return; - } - else - { - vfile = makevfilename(filename, bufferused, dn); - asprintf(&dir_path_vfile, "%s/%s", dir_path, vfile); - - fp = fopen(dir_path_vfile, "w"); - if (fp != NULL) - { - if ((fwrite(filebuffer, - sizeof(char), bufferused, fp) == bufferused) && - (fclose(fp) == 0)) - { - asprintf(&filepath, "%s/%s", dir_path, filename); - - unlink(filepath); /* this can fail ok */ - - itworked = (link(dir_path_vfile, filepath) == 0); - } - } - } - - free((void *) filebuffer); - } - - if (itworked) - { - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); - return; - } - - puts("Status: 500 Failed trying to upload\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp, "Failed to upload\n"); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Failed to upload

\n"); - - GRSThttpPrintf(&bp, "

GridSite considers you are authorized " - "to upload the file, but the upload failed. This is " - "probably a web server or operating system level " - "misconfiguration. Consult the site administrator."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -void deletefileaction(char *dn, GRSTgaclPerm perm, char *help_uri, - char *dir_path, char *file, char *dir_uri, - char *admin_file) -{ - int fd, numfiles; - char *dir_path_file, *dir_path_vfile, *p, *vfile, *dnlistsuri, - *fulluri, *server_name, *realfile; - struct stat statbuf; - GRSThttpBody bp; - struct dirent *subdirfile_ent; - DIR *subDIR; - - if (((strcmp(file, GRST_ACL_FILE) != 0) && !GRSTgaclPermHasWrite(perm)) || - ((strcmp(file, GRST_ACL_FILE) == 0) && !GRSTgaclPermHasAdmin(perm))) - GRSThttpError("403 Forbidden"); - - dnlistsuri = getenv("GRST_DN_LISTS_URI"); - if (dnlistsuri == NULL) dnlistsuri = getenv("REDIRECT_GRST_DN_LISTS_URI"); - - if ((dnlistsuri != NULL) && - (strncmp(dnlistsuri, dir_uri, strlen(dnlistsuri)) == 0)) - realfile = GRSThttpUrlEncode(file); - else if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - else realfile = file; - - dir_path_file = malloc(strlen(dir_path) + strlen(realfile) + 2); - - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, realfile); - - if ((stat(dir_path_file, &statbuf) == 0) && S_ISDIR(statbuf.st_mode)) - { - subDIR = opendir(dir_path_file); - if (subDIR == NULL) numfiles = 99; /* stop deletion */ - else - { - numfiles = 0; - while ((subdirfile_ent = readdir(subDIR)) != NULL) - if (subdirfile_ent->d_name[0] != '.') ++numfiles; - else if (strncmp(subdirfile_ent->d_name, - GRST_ACL_FILE, - sizeof(GRST_ACL_FILE)) == 0) ++numfiles; - closedir(subDIR); - } - - if (numfiles == 0) - { - vfile = makevfilename(file, 0, dn); - dir_path_vfile = malloc(strlen(dir_path) + strlen(vfile) + 2); - strcpy(dir_path_vfile, dir_path); - strcat(dir_path_vfile, "/"); - strcat(dir_path_vfile, vfile); - - if (rename(dir_path_file, dir_path_vfile) == 0) - { - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); - return; - } - } - } - else if (unlink(dir_path_file) == 0) - { - if (strcmp(file, GRST_ACL_FILE) != 0) - { - vfile = makevfilename(file, 0, dn); - dir_path_file = malloc(strlen(dir_path) + strlen(vfile) + 2); - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, vfile); - - fd = open(dir_path_file, O_WRONLY | O_CREAT); - if (fd != -1) close(fd); - } - - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); - - return; - } - - puts("Status: 500 Failed trying to delete\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp, "Error deleting %s%s\n", dir_uri, file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error deleting %s%s

\n", - dir_uri, file); - - GRSThttpPrintf(&bp, "

GridSite considers you are authorized " - "to delete %s, but the delete failed. This is " - "probably a web server or operating system level " - "misconfiguration. Consult the site administrator.", - file); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -void deletefileform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp, "Delete %s\n", file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Delete %s

\n", file); - - GRSThttpPrintf(&bp,"
\n",dir_uri,admin_file); - GRSThttpPrintf(&bp,"

Do you really want to delete %s?", file); - GRSThttpPrintf(&bp,"

\n", file); - GRSThttpPrintf(&bp,"\n", file); - GRSThttpPrintf(&bp,"\n"); - GRSThttpPrintf(&bp,"
\n"); - - GRSThttpPrintf(&bp,"

Or " - "return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -void renameform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp, "Rename %s\n", file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Rename %s%s

\n", dir_uri, file); - - GRSThttpPrintf(&bp,"
\n",dir_uri,admin_file); - GRSThttpPrintf(&bp,"

What do you want to rename %s to?

", file); - GRSThttpPrintf(&bp,"\n", file); - GRSThttpPrintf(&bp,"

New name: \n", file); - GRSThttpPrintf(&bp,"\n"); - GRSThttpPrintf(&bp,"\n"); - GRSThttpPrintf(&bp,"

\n"); - - GRSThttpPrintf(&bp,"

Or " - "return to " - "directory listing\n", dir_uri, admin_file, dir_uri); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -void editfileaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - char *pagetext, *dir_path_file, *vfile, *dir_path_vfile, - *dnlistsuri, *server_name, *fulluri, *realfile; - FILE *fp; - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm) || (strcmp(file, GRST_ACL_FILE) == 0)) - GRSThttpError("403 Forbidden"); - - dnlistsuri = getenv("GRST_DN_LISTS_URI"); - if (dnlistsuri == NULL) dnlistsuri = getenv("REDIRECT_GRST_DN_LISTS_URI"); - - if ((dnlistsuri != NULL) && - (strncmp(dnlistsuri, dir_uri, strlen(dnlistsuri)) == 0)) - { - realfile = GRSThttpUrlEncode(file); - - if (realfile[0] == '.') GRSThttpError("403 Forbidden"); - } - else if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - else realfile = file; - - asprintf(&dir_path_file, "%s/%s", dir_path, realfile); - - pagetext = GRSThttpGetCGI("pagetext"); - vfile = makevfilename(file, strlen(pagetext), dn); - asprintf(&dir_path_vfile, "%s/%s", dir_path, vfile); - - fp = fopen(dir_path_vfile, "w"); - if (fp == NULL) - { - puts("Status: 500 Failed trying to write\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Error writing %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error writing %s%s

\n", - dir_uri, file); - - GRSThttpPrintf(&bp, - "

GridSite considers you are authorized " - "to write the file, but the write failed. This is " - "probably a web server or operating system level " - "misconfiguration. Consult the site administrator."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); - return; - } - - fwrite(pagetext, strlen(pagetext), sizeof(char), fp); - - fclose(fp); - - unlink(dir_path_file); - - if (link(dir_path_vfile,dir_path_file) != 0) GRSThttpError("403 Forbidden"); - - if ((strlen(file) > 7) && (strcmp(&file[strlen(file) - 5], ".html") == 0)) - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s\n\n", dir_uri, file); - else printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); -} - -void create_acl(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int fd; - char *tmpgacl, *newgacl; - GRSTgaclAcl *acl; - FILE *fp; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError("403 Forbidden"); - - asprintf(&tmpgacl, "%s/.tmp.XXXXXX", dir_path); - asprintf(&newgacl, "%s/%s", dir_path, GRST_ACL_FILE); - - if (((acl = GRSTgaclAclLoadforFile(dir_path)) != NULL) && - ((fd = mkstemp(tmpgacl)) != -1) && - ((fp = fdopen(fd, "w+")) != NULL) && - GRSTgaclAclPrint(acl, fp) && - (fclose(fp) == 0) && - (rename(tmpgacl, newgacl) == 0)) - { - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); - - free(tmpgacl); - free(newgacl); - return; - } - - puts("Status: 500 Failed trying to create\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Error creating %s%s\n", dir_uri, - GRST_ACL_FILE); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error creating %s%s

\n", - dir_uri, GRST_ACL_FILE); - - GRSThttpPrintf(&bp, "

GridSite considers you are authorized " - "to create it, but the create failed. This is " - "probably a web server or operating system level " - "misconfiguration. Consult the site administrator."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); - - free(tmpgacl); - free(newgacl); -} - -void renameaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int len; - char *dir_path_file, *vfile, *dir_path_vfile, - *dnlistsuri, *newfile, *dir_path_newfile; - struct stat statbuf; - FILE *fp; - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm) || (strcmp(file, GRST_ACL_FILE) == 0)) - GRSThttpError("403 Forbidden"); - - if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - - dir_path_file = malloc(strlen(dir_path) + strlen(file) + 2); - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, file); - - if (stat(dir_path_file, &statbuf) != 0) GRSThttpError("404 Not Found"); - - newfile = GRSThttpGetCGI("newfile"); - - if ((strcmp(newfile, GRST_ACL_FILE) == 0) || - (strcmp(newfile, file) == 0)) GRSThttpError("403 Forbidden"); - - dir_path_newfile = malloc(strlen(dir_path) + strlen(newfile) + 2); - strcpy(dir_path_newfile, dir_path); - strcat(dir_path_newfile, "/"); - strcat(dir_path_newfile, newfile); - - vfile = makevfilename(newfile, statbuf.st_size, dn); - dir_path_vfile = malloc(strlen(dir_path) + strlen(vfile) + 2); - strcpy(dir_path_vfile, dir_path); - strcat(dir_path_vfile, "/"); - strcat(dir_path_vfile, vfile); - - unlink(dir_path_newfile); /* just in case */ - - if ((link(dir_path_file, dir_path_vfile ) == 0) && - (link(dir_path_file, dir_path_newfile) == 0) && - (unlink(dir_path_file) == 0)) - { - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s\n\n", dir_uri); - return; - } - - puts("Status: 500 Failed trying to rename\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Error renaming %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error renaming %s%s

\n", - dir_uri, file); - - GRSThttpPrintf(&bp, "

GridSite considers you are authorized " - "to rename it, but the rename failed. This is " - "probably a web server or operating system level " - "misconfiguration. Consult the site administrator."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -void newdirectory(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int len; - char *dir_path_file, *vfile, *dir_path_vfile, *filedup; - FILE *fp; - GRSThttpBody bp; - - if ((file[0] == '\0') || - !GRSTgaclPermHasWrite(perm) || (strcmp(file, GRST_ACL_FILE) == 0)) - GRSThttpError("403 Forbidden"); - - filedup = strdup(file); - if (filedup[strlen(filedup)-1] == '/') filedup[strlen(filedup)-1] = '\0'; - if (index(filedup, '/') != NULL) GRSThttpError("403 Forbidden"); - - dir_path_file = malloc(strlen(dir_path) + strlen(file) + 2); - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, file); - - if (mkdir(dir_path_file, 0751) == 0) - { - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); - return; - } - - puts("Status: 500 Failed trying to create\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Error create %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error creating directory %s%s

\n", - dir_uri, file); - - GRSThttpPrintf(&bp, - "

GridSite considers you are authorized " - "to create the directory, but the creation failed. This " - "is probably a web server or operating system level " - "misconfiguration. Consult the site administrator."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "parent directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -void editdnlistaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int numdn = 0, ifd, ofd, numdnlines = 0, i, found; - char *dir_path_file, *dir_path_tmpfile, *realfile, - *dnlistsuri, *server_name, *fulldiruri, *p, oneline[513], - **dnlines, name[81], *add; - FILE *ofp; - struct stat statbuf; - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - - dnlistsuri = getenv("GRST_DN_LISTS_URI"); - if (dnlistsuri == NULL) dnlistsuri = getenv("REDIRECT_GRST_DN_LISTS_URI"); - - server_name = getenv("SERVER_NAME"); - - if ((server_name == NULL) || - (dnlistsuri == NULL) || - (strncmp(dnlistsuri, dir_uri, strlen(dnlistsuri)) != 0)) - GRSThttpError("403 Forbidden"); - - asprintf(&fulldiruri, "https://%s%s", server_name, dir_uri); - - if ((strncmp(fulldiruri, file, strlen(fulldiruri)) != 0) && - ((strncmp(fulldiruri, file, strlen(fulldiruri) - 1) != 0) || - (strlen(fulldiruri) - 1 != strlen(file)))) - { - puts("Status: 403 Forbidden\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Error writing %s\n", file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error writing %s to %s

\n", - file, dir_uri); - - GRSThttpPrintf(&bp, "

You cannot create a DN List " - "with that prefix in this directory. Please see the " - "the GridSite User's Guide for an explanation."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); - return; - } - - p = GRSThttpGetCGI("numdn"); - if ((p == NULL) || (sscanf(p, "%d", &numdn) != 1)) - GRSThttpError("500 No number of DNs"); - - if (numdn > 0) - { - dnlines = malloc(sizeof(char *) * numdn); - - for (i=1; i <= numdn; ++i) - { - sprintf(name, "dn%d", i); - p = GRSThttpGetCGI(name); - - if (*p != '\0') - { - dnlines[numdnlines] = p; - ++numdnlines; - } - } - } - - add = GRSThttpGetCGI("add"); - - realfile = GRSThttpUrlEncode(file); - - dir_path_file = malloc(strlen(dir_path) + strlen(realfile) + 2); - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, realfile); - - dir_path_tmpfile = malloc(strlen(dir_path) + 13); - strcpy(dir_path_tmpfile, dir_path); - strcat(dir_path_tmpfile, "/.tmp.XXXXXX"); - - if (((ofd = mkstemp(dir_path_tmpfile)) != -1) && - ((ofp = fdopen(ofd, "w")) != NULL)) - { - if (*add != '\0') - { - fputs(add, ofp); - fputc('\n', ofp); - } - - for (i=0; i < numdnlines; ++i) - { - fputs(dnlines[i], ofp); - fputc('\n', ofp); - } - - if ((fclose(ofp) == 0) && - ((stat(dir_path_file, &statbuf) != 0) || - (unlink(dir_path_file) == 0)) && - (rename(dir_path_tmpfile, dir_path_file) == 0)) - { - printf("Status: 302 Moved Temporarily\nContent-Length: 0\n" - "Location: %s%s?cmd=managedir\n\n", dir_uri, admin_file); - return; - } - } - - puts("Status: 500 Failed trying to write\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Error writing %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Error writing %s%s

\n", - dir_uri, file); - - GRSThttpPrintf(&bp, "

GridSite considers you are authorized " - "to write the file, but the write failed. This is " - "probably a web server or operating system level " - "misconfiguration. Consult the site administrator."); - - GRSThttpPrintf(&bp,"

" - "Return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); - - /* try to clean up */ - if (stat(dir_path_tmpfile, &statbuf) == 0) unlink(dir_path_tmpfile); -} - -void printfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int fd; - char *dir_path_file; - struct stat statbuf; - - if (!GRSTgaclPermHasRead(perm)) GRSThttpError("403 Forbidden"); - - if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - - dir_path_file = malloc(strlen(dir_path) + strlen(file) + 2); - - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, file); - - fd = open(dir_path_file, O_RDONLY); - if (fd == -1) GRSThttpError("500 Internal server error"); - - if ((fstat(fd, &statbuf) != 0) || - !S_ISREG(statbuf.st_mode)) GRSThttpError("403 Forbidden"); - - printf("Status: 200 OK\nContent-Type: text/html\nContent-Length: %d\n\n", - statbuf.st_size); - - fflush(stdout); - - sendfile(1, fd, 0, statbuf.st_size); -} - -void filehistory(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int fd, n, i, j, enclen, num = 0; - char *encodedfile, *p, *dndecoded, modified[99], *vfile, *q, - *encdn; - time_t file_time; - size_t file_size; - struct stat statbuf; - struct dirent **namelist; - struct tm file_tm; - GRSThttpBody bp; - - if (!GRSTgaclPermHasRead(perm)) GRSThttpError("403 Forbidden"); - - if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - GRSThttpPrintf(&bp, "History of %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - GRSThttpPrintf(&bp, - "

History of %s%s

\n", - dir_uri, file, dir_uri, file); - - asprintf(&vfile, "%s/%s", dir_path, file); - if (stat(vfile, &statbuf) == 0) - { - localtime_r((const time_t *) &(statbuf.st_mtime), &file_tm); - strftime(modified, sizeof(modified), - "%a %e %b %Y %k:%M", &file_tm); - - GRSThttpPrintf(&bp, "

Last modified: %s\n", modified); - } - free(vfile); - - encodedfile = GRSThttpUrlEncode(file); - for (p=encodedfile; *p != '\0'; ++p) if (*p == '%') *p = '='; - enclen = strlen(encodedfile); - - n = scandir(dir_path, &namelist, 0, alphasort); - - if (n > 0) - { - for (i = n - 1; i >= 0; --i) - { - if ((strncmp(namelist[i]->d_name, GRST_HIST_PREFIX, - sizeof(GRST_HIST_PREFIX) - 1) == 0) && - ((namelist[i]->d_name)[sizeof(GRST_HIST_PREFIX) - 1] == ':') && - (strncmp(&((namelist[i]->d_name)[sizeof(GRST_HIST_PREFIX)]), - encodedfile, enclen) == 0) && - ((namelist[i]->d_name)[sizeof(GRST_HIST_PREFIX)+enclen] == ':')) - { - if (num == 0) GRSThttpPrintf(&bp, - "

\n" - "" - "\n"); - - ++num; - - p = index(namelist[i]->d_name, ':'); - p = index(&p[1], ':'); - sscanf(&p[1], "%X:", &file_time); - p = index(&p[1], ':'); /* skip over microseconds time */ - p = index(&p[1], ':'); - sscanf(&p[1], "%X:", &file_size); - p = index(&p[1], ':'); - - encdn = strdup(&p[1]); - q = index(encdn, ':'); - if (q != NULL) *q = '\0'; - - for (q=encdn; *q != '\0'; ++q) if (*q == '=') *q = '%'; - dndecoded = GRSThttpUrlDecode(encdn); - - localtime_r((const time_t *) &file_time, &file_tm); - strftime(modified, sizeof(modified), - "%a %e %b %Y %k:%M", &file_tm); - - GRSThttpPrintf(&bp, - "\n", - modified, file_size, dndecoded); - - free(dndecoded); - - asprintf(&vfile, "%s/%s", dir_path, namelist[i]->d_name); - if ((stat(vfile, &statbuf) == 0) && (statbuf.st_size > 0)) - { - GRSThttpPrintf(&bp, "\n", - dir_uri, admin_file, dir_uri, namelist[i]->d_name); - else GRSThttpPrintf(&bp, "%s%s\">View\n", - dir_uri, namelist[i]->d_name); - } - else GRSThttpPrintf(&bp, ""); - - free(vfile); - } - } - } - - if (num > 0) GRSThttpPrintf(&bp, "
DateSize afterChanged by
%s%d%sView
 
\n"); - else GRSThttpPrintf(&bp, "

No history for this file\n"); - - if (GRSTgaclPermHasList(perm)) - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - else adminfooter(&bp, dn, help_uri, dir_uri, NULL); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); -} - -void ziplist(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - char *shellcmd, *unzip, oneline[129]; - FILE *fp; - GRSThttpBody bp; - - if (!GRSTgaclPermHasRead(perm)) GRSThttpError("403 Forbidden"); - - if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - GRSThttpPrintf(&bp, "Contents of %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - GRSThttpPrintf(&bp, - "

Contents of ZIP file %s%s

\n", - dir_uri, file, dir_uri, file); - - unzip = getenv("GRST_UNZIP"); - if (unzip == NULL) unzip = getenv("REDIRECT_GRST_UNZIP"); - - if (unzip != NULL) - { - GRSThttpPrintf(&bp, "
\n");
-      asprintf(&shellcmd, "cd %s ; %s -Z %s", dir_path, unzip, file);
-      fp = popen(shellcmd, "r");
-  
-      while (fgets(oneline, sizeof(oneline), fp) != NULL)           
-                          GRSThttpPrintf(&bp, "%s", oneline);         
-      pclose(fp);
-      GRSThttpPrintf(&bp, "
\n"); - - if (GRSTgaclPermHasWrite(perm)) - GRSThttpPrintf(&bp, - "

" - " in %s" - "" - "
" - "

(All files are placed in the same directory and files " - "beginning with "." are ignored.)

\n", - dir_uri, admin_file, dir_uri, file); - } - else GRSThttpPrintf(&bp, "

unzip path not defined!\n"); - - if (GRSTgaclPermHasList(perm)) - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - else adminfooter(&bp, dn, help_uri, dir_uri, NULL); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); -} - -void unzipfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - char *shellcmd, *unzip, oneline[129]; - FILE *fp; - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - - if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - GRSThttpPrintf(&bp, "Unzipping %s%s\n", dir_uri, file); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - GRSThttpPrintf(&bp, - "

Unzipping %s%s

\n", - dir_uri, file, dir_uri, file); - - unzip = getenv("GRST_UNZIP"); - if (unzip == NULL) unzip = getenv("REDIRECT_GRST_UNZIP"); - - if (unzip != NULL) - { - GRSThttpPrintf(&bp, "
\n");
-      asprintf(&shellcmd, "cd %s ; %s -jo %s -x '.*'", dir_path, unzip, file);
-      fp = popen(shellcmd, "r");
-  
-      while (fgets(oneline, sizeof(oneline), fp) != NULL)           
-                          GRSThttpPrintf(&bp, "%s", oneline);         
-      pclose(fp);
-      GRSThttpPrintf(&bp, "
\n"); - - if (GRSTgaclPermHasList(perm)) - GRSThttpPrintf(&bp, "

" - "Back to " - "directory", dir_uri, admin_file); - } - else GRSThttpPrintf(&bp, "

unzip path not defined!\n"); - - if (GRSTgaclPermHasList(perm)) - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - else adminfooter(&bp, dn, help_uri, dir_uri, NULL); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); -} - -void editfileform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int fd, rawpagesize, i, c; - char *dir_path_file, *rawpage, *p; - FILE *fp = NULL; - struct stat statbuf; - GRSThttpBody bp; - - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - - if (index(file, '/') != NULL) GRSThttpError("403 Forbidden"); - - dir_path_file = malloc(strlen(dir_path) + strlen(file) + 2); - - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, file); - - fd = open(dir_path_file, O_RDONLY); - if (fd != -1) - { - fp = fdopen(fd, "r"); - if (fp == NULL) GRSThttpError("500 File open failed!"); - - if ((fstat(fd, &statbuf) != 0) || - !S_ISREG(statbuf.st_mode)) GRSThttpError("500 Not a regular file!"); - } - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp, "Edit file %s\n", file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Edit file %s

\n", file); - - GRSThttpPrintf(&bp,"
\n",dir_uri,admin_file); - GRSThttpPrintf(&bp,"

\n"); - GRSThttpPrintf(&bp,"

File name: \n", file); - GRSThttpPrintf(&bp,"\n"); - GRSThttpPrintf(&bp,"

\n"); - GRSThttpPrintf(&bp, "

\n"); - GRSThttpPrintf(&bp, "

\n"); - - if (fp != NULL) fclose(fp); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); -} - -void editdnlistform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) -{ - int fd, i, c, numdn = 0; - char *dir_path_file, *rawpage, *p, *dnlistsuri, *server_name, *fulluri, - *realfile, oneline[513]; - FILE *fp = NULL; - struct stat statbuf; - GRSThttpBody bp; - - dnlistsuri = getenv("GRST_DN_LISTS_URI"); - if (dnlistsuri == NULL) dnlistsuri = getenv("REDIRECT_GRST_DN_LISTS_URI"); - - if (!GRSTgaclPermHasWrite(perm) || - (dnlistsuri == NULL) || - (strncmp(dnlistsuri, dir_uri, strlen(dnlistsuri)) != 0)) - GRSThttpError("403 Forbidden"); - - realfile = GRSThttpUrlEncode(file); - - dir_path_file = malloc(strlen(dir_path) + strlen(realfile) + 2); - - strcpy(dir_path_file, dir_path); - strcat(dir_path_file, "/"); - strcat(dir_path_file, realfile); - - fd = open(dir_path_file, O_RDONLY); - if (fd != -1) /* we dont mind open failing, but it must work if it doesnt */ - { - fp = fdopen(fd, "r"); - if (fp == NULL) GRSThttpError("500 File open failed!"); - - if ((fstat(fd, &statbuf) != 0) || - !S_ISREG(statbuf.st_mode)) GRSThttpError("500 Not a regular file!"); - } - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp, "Edit DN List %s\n", file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Edit DN List

\n"); - - GRSThttpPrintf(&bp,"
\n",dir_uri,admin_file); - GRSThttpPrintf(&bp,"

\n"); - GRSThttpPrintf(&bp,"

List URL: \n", file, strlen(file)); - GRSThttpPrintf(&bp,"\n"); - - if (fp != NULL) - { - GRSThttpPrintf(&bp, "

\n" - "\n"); - - while (fgets(oneline, sizeof(oneline), fp) != NULL) - { - ++numdn; - - p = rindex(oneline, '\n'); - if (p != NULL) *p = '\0'; - - GRSThttpPrintf(&bp, "" - "\n", numdn, oneline, oneline); - } - - GRSThttpPrintf(&bp,"
Keep?Name
%s
\n"); - } - - GRSThttpPrintf(&bp,"\n", numdn); - - GRSThttpPrintf(&bp, "

Add new DN: \n"); - - GRSThttpPrintf(&bp,"

\n"); - GRSThttpPrintf(&bp, "

\n"); - - if (fp != NULL) fclose(fp); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); -} - -void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *dir_uri, char *admin_file) -{ - int n, is_dnlists_dir = 0, enclen, numfiles, encprefixlen; - char *d_namepath, modified[99], *absaclpath, *editable, *p, *unzip, - *dnlistsuri, *d_name, *server_name, *fulluri, *encfulluri, - *encprefix, *dnlistsprefix; - GRSThttpBody bp; - struct tm mtime_tm; - struct stat statbuf; - struct dirent **namelist, *subdirfile_ent; - DIR *subDIR; - - if (((!GRSTgaclPermHasWrite(perm)) && - (!GRSTgaclPermHasList(perm))) || - (stat(dir_path, &statbuf) != 0) || !S_ISDIR(statbuf.st_mode)) - GRSThttpError("403 Forbidden"); - - editable = getenv("GRST_EDITABLE"); - if (editable == NULL) editable = getenv("REDIRECT_GRST_EDITABLE"); - - unzip = getenv("GRST_UNZIP"); - if (unzip == NULL) unzip = getenv("REDIRECT_GRST_UNZIP"); - - dnlistsuri = getenv("GRST_DN_LISTS_URI"); - if (dnlistsuri == NULL) dnlistsuri = getenv("REDIRECT_GRST_DN_LISTS_URI"); - - if (dnlistsuri && (strncmp(dnlistsuri, dir_uri, strlen(dnlistsuri)) == 0)) - { - is_dnlists_dir = 1; - server_name = getenv("SERVER_NAME"); - - asprintf(&fulluri, "https://%s%s", server_name, dir_uri); - encfulluri = GRSThttpUrlEncode(fulluri); - enclen = strlen(encfulluri); - - asprintf(&dnlistsprefix, "https://%s%s", server_name, dnlistsuri); - encprefix = GRSThttpUrlEncode(dnlistsprefix); - encprefixlen = strlen(encprefix); - } - - printf("Status: 200 OK\nContent-Type: text/html\n"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintf(&bp,"Manage directory %s\n", dir_uri); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpPrintf(&bp, "

Manage directory %s

\n\n", dir_uri); - - if (dir_uri[1] != '\0') - GRSThttpPrintf(&bp, - "\n", admin_file); - - if (GRSTgaclPermHasList(perm) || GRSTgaclPermHasAdmin(perm)) - { - absaclpath = malloc(strlen(dir_path) + sizeof(GRST_ACL_FILE) + 1); - strcpy(absaclpath, dir_path); - strcat(absaclpath, "/"); - strcat(absaclpath, GRST_ACL_FILE); - - if (stat(absaclpath, &statbuf) == 0) /* ACL exists in THIS directory */ - { - localtime_r(&(statbuf.st_mtime), &mtime_tm); - strftime(modified, sizeof(modified), - "", - &mtime_tm); - - if (!is_dnlists_dir) - { - GRSThttpPrintf(&bp, - "" - "%s\n", - GRST_ACL_FILE, - GRST_ACL_FILE, - statbuf.st_size, modified); - - GRSThttpPrintf(&bp, - "", - dir_uri, admin_file, GRST_ACL_FILE); - } - else GRSThttpPrintf(&bp, - "" - "%s\n", - GRST_ACL_FILE, - statbuf.st_size, modified); - - if (GRSTgaclPermHasAdmin(perm)) - GRSThttpPrintf(&bp, - "" - "", - dir_uri, admin_file, - dir_uri, admin_file, GRST_ACL_FILE); - else if (GRSTgaclPermHasRead(perm)) - GRSThttpPrintf(&bp, - "" - "", dir_uri, admin_file); - else GRSThttpPrintf(&bp, "\n"); - - GRSThttpPrintf(&bp, "\n"); - } - else if (GRSTgaclPermHasAdmin(perm)) - GRSThttpPrintf(&bp, "\n" - "\n" - "\n", - dir_uri, admin_file); - } - - if (GRSTgaclPermHasList(perm)) - { - n = scandir(dir_path, &namelist, 0, alphasort); - while (n--) - { - if (namelist[n]->d_name[0] != '.') - { - d_namepath = malloc(strlen(dir_path) + - strlen(namelist[n]->d_name) + 2); - strcpy(d_namepath, dir_path); - strcat(d_namepath, "/"); - strcat(d_namepath, namelist[n]->d_name); - stat(d_namepath, &statbuf); - - if (S_ISDIR(statbuf.st_mode)) - { - subDIR = opendir(d_namepath); - - if (subDIR == NULL) numfiles = 99; /* stop deletion */ - else - { - numfiles = 0; - while ((subdirfile_ent = readdir(subDIR)) != NULL) - if (subdirfile_ent->d_name[0] != '.') ++numfiles; - else if (strncmp(subdirfile_ent->d_name, - GRST_ACL_FILE, - sizeof(GRST_ACL_FILE)) == 0) ++numfiles; - - closedir(subDIR); - } - } - - free(d_namepath); - - localtime_r(&(statbuf.st_mtime), &mtime_tm); - strftime(modified, sizeof(modified), - "", - &mtime_tm); - - if (S_ISDIR(statbuf.st_mode)) - { - GRSThttpPrintf(&bp, - "" - "%s\n", - dir_uri, namelist[n]->d_name, admin_file, - namelist[n]->d_name, - statbuf.st_size, modified); - - if (numfiles == 0) - GRSThttpPrintf(&bp, - "\n", - dir_uri, admin_file, namelist[n]->d_name); - else GRSThttpPrintf(&bp, "\n"); - - GRSThttpPrintf(&bp, "\n"); - } - else if (is_dnlists_dir) - { - if ((strlen(namelist[n]->d_name) <= encprefixlen) || - (strncmp(namelist[n]->d_name, encprefix, - encprefixlen) != 0)) continue; - - d_name = GRSThttpUrlDecode(namelist[n]->d_name); - - GRSThttpPrintf(&bp, "" - "%s" - "", - d_name, d_name, - statbuf.st_size, modified); - - if (GRSTgaclPermHasWrite(perm)) - GRSThttpPrintf(&bp, "" - "" - "" - "" - "\n", - dir_uri, admin_file, d_name); - else GRSThttpPrintf(&bp, "\n"); - - if (GRSTgaclPermHasWrite(perm)) - GRSThttpPrintf(&bp, "" - "" - "" - "" - "\n", - dir_uri, admin_file, d_name); - else GRSThttpPrintf(&bp, "\n"); - - GRSThttpPrintf(&bp, ""); - } - else /* regular directory, not DN Lists */ - { - d_name = namelist[n]->d_name; - - GRSThttpPrintf(&bp, - "" - "%s", - dir_uri, d_name, - d_name, - statbuf.st_size, modified); - - GRSThttpPrintf(&bp, - "", - dir_uri, admin_file, d_name); - - p = rindex(namelist[n]->d_name, '.'); - - if ((unzip != NULL) && - (p != NULL) && - (strcasecmp(&p[1], "zip") == 0) && - GRSTgaclPermHasRead(perm)) - GRSThttpPrintf(&bp, - "\n", - dir_uri, admin_file, d_name); - else if ((p != NULL) && - (strstr(editable, &p[1]) != NULL) && - GRSTgaclPermHasWrite(perm)) - GRSThttpPrintf(&bp, - "\n", - dir_uri, admin_file, d_name); - else GRSThttpPrintf(&bp, ""); - - if (GRSTgaclPermHasWrite(perm)) - GRSThttpPrintf(&bp, - "\n", dir_uri, admin_file, d_name); - else - GRSThttpPrintf(&bp, "\n"); - - if (GRSTgaclPermHasWrite(perm)) - GRSThttpPrintf(&bp, - "\n", dir_uri, admin_file, d_name); - else - GRSThttpPrintf(&bp, ""); - } - } - - free(namelist[n]); - } - - free(namelist); - } - - if (GRSTgaclPermHasWrite(perm)) - { - if (is_dnlists_dir) - { - GRSThttpPrintf(&bp, "\n" - "" - "\n" - "\n", - dir_uri, admin_file, fulluri, strlen(fulluri)+8); - - GRSThttpPrintf(&bp, "\n" - "\n" - "\n", - dir_uri, admin_file); - } - else - { - GRSThttpPrintf(&bp, "\n" - "\n" - "" - "\n" - "\n" - "\n", - dir_uri, admin_file); - - GRSThttpPrintf(&bp, - "\n" - "\n" - "" - "" - "\n" - "" - "\n" - "\n", dir_uri, admin_file); - } - } - - GRSThttpPrintf(&bp, "
[Parent " - "directory]
%R%e %b %y
%s%ld" - "History
%s%ldEditDeleteView    
%R%e %b %y
" - "%s/%ld " - "Delete  
%s%ld 
 
  
%s%ld" - "History" - "List" - "Edit " - "Delete " - "Rename
 
New list name: " - "\n" - "
New directory: " - "\n" - "

New name:\n" - "

Upload file:New name: " - "
Local name:
\n"); - - if (!is_dnlists_dir) adminfooter(&bp, dn, help_uri, dir_uri, NULL); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); -} - diff --git a/org.gridsite.core/src/grst_admin_gacl.c b/org.gridsite.core/src/grst_admin_gacl.c deleted file mode 100644 index 2a40b28..0000000 --- a/org.gridsite.core/src/grst_admin_gacl.c +++ /dev/null @@ -1,968 +0,0 @@ -/* - Copyright (c) 2003, Shiv Kaushal, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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 program is part of GridSite: http://www.gridsite.org/ * -*------------------------------------------------------------*/ - -#include -#include -#include -#include -#include -#include - -extern char *grst_perm_syms[]; -extern int grst_perm_vals[]; - -#include "grst_admin.h" - -// CGI GACL Editor interface functions -void show_acl(int admin, GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void new_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void new_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void edit_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void edit_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void add_cred_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void add_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_entry_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void del_cred_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void admin_continue(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file, GRSThttpBody *bp); - -// Functions for producing HTML output -void StartHTML(GRSThttpBody *bp, char *dir_uri, char* dir_path); -void StartForm(GRSThttpBody *bp, char* dir_uri, char* dir_path, char* admin_file, int timestamp, char* target_function); -void EndForm(GRSThttpBody *bp); -void GRSTgaclCredTableStart(GRSThttpBody *bp); -void GRSTgaclCredTableAdd(GRSTgaclUser *user, GRSTgaclEntry *entry, GRSTgaclCred *cred, GRSTgaclNamevalue *namevalue, int cred_no, int entry_no, int admin, int timestamp, GRSThttpBody *bp, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); -void GRSTgaclCredTableEnd(GRSTgaclEntry* entry, int entry_no, int admin, int timestamp, GRSThttpBody *bp, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); - -// ACL Manipulation functions -int GACLentriesInAcl(GRSTgaclAcl *acl); -int GRSTgaclCredsInEntry(GRSTgaclEntry *entry); -void check_acl_save(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file, GRSTgaclUser* user, GRSTgaclAcl *acl, GRSThttpBody *bp); -void GACLeditGetPerms(GRSTgaclEntry *entry); -GRSTgaclEntry *GACLreturnEntry(GRSTgaclAcl *acl, int entry_no); -GRSTgaclCred *GACLreturnCred(GRSTgaclEntry *entry, int cred_no); - -void StringHTMLEncode (char* string, GRSThttpBody *bp); - -void revert_acl(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); - -/*****************************************/ -/********** FUNCTIONS FOLLOW *************/ -/*****************************************/ - -void show_acl(int admin, GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Shows the contents of the ACL. Gives edit 'buttons' if (int admin) == 1 - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclNamevalue *namevalue; - int entry_no, cred_no, allow, deny,timestamp; - GRSThttpBody bp; - char* AclFilename; - struct stat file_info; - int history_mode=0; - - if (admin==2){ - history_mode=1; - admin=0; - } - - /*double-check access permision*/ - if (!GRSTgaclPermHasAdmin(perm)) admin=0; - - StartHTML(&bp, dir_uri, dir_path); - - /* Load ACL from file and get timestamp*/ - if (history_mode==1) { - AclFilename=malloc(strlen(dir_path)+strlen(file)+2); - strcpy(AclFilename, dir_path); - strcat(AclFilename, "/"); - strcat(AclFilename, file); - } - else AclFilename=GRSTgaclFileFindAclname(dir_path); - - if (AclFilename==NULL){ - GRSThttpPrintf ( &bp,"The ACL was not found !!!
\n"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; - } - - stat(GRSTgaclFileFindAclname(dir_path), &file_info); - timestamp=file_info.st_mtime; - acl = GRSTgaclAclLoadFile(AclFilename); - - if (acl==NULL){ - GRSThttpPrintf ( &bp,"The ACL was found but could not be loaded - it could be incorrectly formatted
\n"); - adminfooter(&bp, dn, help_uri, dir_uri, NULL); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(&bp); - return; - } - - if (admin) GRSThttpPrintf (&bp,"New Entry
\n", dir_uri, admin_file, dir_uri, timestamp ); - - // Start with the first entry in the list and work through - entry=acl->firstentry; - entry_no=1; - while (entry!=NULL){ - - GRSThttpPrintf (&bp,"
Entry %d:\n", entry_no); - if (admin){ - GRSThttpPrintf (&bp,"Edit Entry ", dir_uri, admin_file, entry_no, dir_uri, timestamp ); - GRSThttpPrintf (&bp,"Delete Entry ",dir_uri, admin_file, entry_no, dir_uri, timestamp ); - GRSThttpPrintf (&bp,"

\n"); - } - - GRSTgaclCredTableStart(&bp); - - // Start with the first credential in the entry and work through - cred=entry->firstcred; - cred_no=1; - while (cred!=NULL){ - namevalue=cred->firstname; - GRSTgaclCredTableAdd(user, entry, cred, namevalue, cred_no, entry_no, admin, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - // Change to next credential - cred=cred->next; - cred_no++; - } - - GRSTgaclCredTableEnd (entry, entry_no, admin, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - // Change to next entry - entry=entry->next; - entry_no++; - } - - if (!admin && GRSTgaclPermHasAdmin(perm) && !history_mode) //Print a link for admin mode, if not in admin mode but the user has admin permissions - GRSThttpPrintf (&bp,"Admin Mode", dir_uri, admin_file, dir_uri, timestamp ); - if (history_mode==1 && GRSTgaclDNlistHasUser(getenv("REDIRECT_GRST_ADMIN_LIST"), user)){ - StartForm(&bp, dir_uri, dir_path, admin_file, timestamp, "revert_acl"); -//GRSThttpPrintf (&bp,"Revert to this Version", dir_uri, admin_file, dir_uri, timestamp, file ); - GRSThttpPrintf (&bp, "\n", file); - // Revert Button - GRSThttpPrintf (&bp, "

\n\n"); - } - - adminfooter(&bp, dn, help_uri, dir_uri, NULL); - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); GRSThttpWriteOut(&bp); return; -} - - -void new_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm,char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Presents the user with a form asking for details required to create a new entry - GRSThttpBody bp; - int timestamp=atol(GRSThttpGetCGI("timestamp")); - GRSTgaclCred* cred; - GRSTgaclEntry *entry; - GRSTgaclNamevalue* namevalue; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - StartHTML(&bp, dir_uri, dir_path); - StartForm(&bp, dir_uri, dir_path, admin_file, timestamp, "new_entry"); - GRSThttpPrintf (&bp, "NEW ENTRY IN ACL FOR %s

\n", dir_uri); - - GRSTgaclCredTableStart(&bp); - GRSTgaclCredTableAdd(user, entry,cred, namevalue, 0, 0, 0, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - GRSTgaclCredTableEnd (entry, 0, 0, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - - /*Submit and reset buttons - submit button sends the data in the form back to the script & new_entry() to be called*/ - EndForm(&bp); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; -} - -void new_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Processes the information entered into the form from new_entry_form() and adds a new entry to the ACL - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - char *type, *value; - GRSThttpBody bp; - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - // Get new credential info and perform checks - type=GRSThttpGetCGI("type"); - value=GRSThttpGetCGI("cred0_value"); - - if (strcmp(type, "not_chosen")==0){ - GRSThttpError ("500 Invalid input - credential type not chosen"); - return; - } - - // Create the credential - cred=GRSTgaclCredNew(type); - if (strcmp(type, "person")==0) GRSTgaclCredAddValue(cred,"dn", value); - else if (strcmp(type, "dn-list")==0) GRSTgaclCredAddValue(cred, "url", value); - else if (strcmp(type, "voms")==0) GRSTgaclCredAddValue(cred, "fqan", value); - else if (strcmp(type, "dns")==0) GRSTgaclCredAddValue(cred, "hostname", value); - else if (strcmp(type, "any-user")==0) {} // namevalue not entered for any-user credential - else{ - GRSThttpError ("500 Invalid input - credential type not valid"); - return; - } - - // Create and empty entry, add the credential and get permissions - entry = GRSTgaclEntryNew(); - GRSTgaclEntryAddCred(entry, cred); - GACLeditGetPerms(entry); - - // Load the ACL, add the entry and save - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); - GRSTgaclAclAddEntry(acl, entry); - check_acl_save(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, user, acl, &bp); - return; -} - -void del_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Deletes the entry denoted by the GCI variable "entry_no"*/ - int entry_no; - GRSTgaclAcl *acl; - GRSTgaclEntry *previous, *entry; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - // Load the ACL - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); - - // Get the number of the entry to be deleted and check okay to delete - entry_no=atol(GRSThttpGetCGI("entry_no")); - if(GACLentriesInAcl(acl)<=1){ - StartHTML(&bp, dir_uri, dir_path); - GRSThttpPrintf (&bp, "ERROR: Cannot delete all entries from the ACL
\n"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; - } - - // Get pointer to entry and previous entry - entry = GACLreturnEntry(acl, entry_no); - if (entry_no!=1) previous = GACLreturnEntry(acl, entry_no-1); - - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read entry from ACL file"); - return; - } - - // Perform deletion from the list by changing pointers - if (entry_no==1) acl->firstentry=entry->next; - else if (entry_no==GACLentriesInAcl(acl)) previous->next=NULL; - else previous->next=entry->next; - - // Save ACL and exit - check_acl_save(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, user, acl, &bp); - - return; -} - - -void edit_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Presents the user with an editable form containing details of entry denoted by CGI variable entry_no*/ - int entry_no, cred_no, i, admin=0, timestamp=atol(GRSThttpGetCGI("timestamp")); - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclNamevalue *namevalue; - // struct _GACLnamevalue *namevalue; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - // Load ACL from file - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); - - // Get pointer to the entry and check okay - entry_no=atol(GRSThttpGetCGI("entry_no")); - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - StartHTML(&bp, dir_uri, dir_path); - GRSThttpPrintf (&bp, "EDITING ENTRY %d IN ACL FOR %s

\n", entry_no, dir_uri); - - // Start with first credential in the entry and display them in order*/ - cred=entry->firstcred; - cred_no=1; - StartForm(&bp, dir_uri, dir_path, admin_file, timestamp, "edit_entry"); - GRSThttpPrintf (&bp, "\n", entry_no); - - GRSTgaclCredTableStart(&bp); - - while (cred!=NULL){ - // Start with the first namevalue in the credential - namevalue=cred->firstname; - GRSTgaclCredTableAdd(user, entry, cred, namevalue, cred_no, entry_no, admin, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - // Change to next credential - cred=cred->next; - cred_no++; - } - GRSTgaclCredTableEnd (entry, entry_no, admin, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - EndForm(&bp); - - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; -} - - -void edit_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - //Processes the information entered into the form from edit_entry_form() and updates the entry corresponding to entry_no*/ - int entry_no, cred_no, i; - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclNamevalue *namevalue; - char variable[30]; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - // Load the ACL - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); - - // Get pointer to the entry and perform checks - entry_no=atol(GRSThttpGetCGI("entry_no")); - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - // Start with the first credential and update each one - cred=entry->firstcred; - cred_no=1; - - while (cred!=NULL){ - if (strcmp(cred->type, "any-user")!=0){ - namevalue=cred->firstname; - sprintf(variable, "cred%d_value", cred_no); - namevalue->value=GRSThttpGetCGI(variable); - } - //Change to next credential*/ - cred=cred->next; - cred_no++; - } - - // Update permissions - GACLeditGetPerms(entry); - check_acl_save(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, user, acl, &bp); - return; -} - - -void add_cred_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Presents the user with a form asking for details required to create a new credential in the entry denoted by entry_no - GRSThttpBody bp; - int timestamp=atol(GRSThttpGetCGI("timestamp")), entry_no=atol(GRSThttpGetCGI("entry_no")); - GRSTgaclAcl *acl; - GRSTgaclEntry* entry; - GRSTgaclCred* cred; - GRSTgaclNamevalue* namevalue; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); // Load the ACL - - //Get pointer to the entry and perform checks - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - - if (strcmp(GRSThttpGetCGI("cmd"), "add_cred_form")==0){ //if not a new entry check to see if cred exists - cred=entry->firstcred; - while (cred!=NULL) { - if (strcmp (cred->type, "any-user")==0) { - StartHTML(&bp, dir_uri, dir_path); - GRSThttpPrintf (&bp, "ERROR: AND-ing \"any-user\" credential with other credential does not make sense
\n"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; - } - cred=cred->next; - } - } - - StartHTML(&bp, dir_uri, dir_path); - GRSThttpPrintf (&bp, " NEW CREDENTIAL IN ENTRY %d OF ACL FOR %s

\n", entry_no, dir_uri); - StartForm(&bp, dir_uri, dir_path, admin_file, timestamp, "add_cred"); - - GRSThttpPrintf (&bp, " \n", entry_no); - - GRSTgaclCredTableStart(&bp); - GRSTgaclCredTableAdd(user, entry, cred, namevalue, 0, 0, 0, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - GRSTgaclCredTableEnd (entry, 0, 0, timestamp, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - - EndForm(&bp); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; -} - - -void add_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Processes the information entered into the form [add_cred_form()]and adds a new credential to the entry corresponding to entry_no - int entry_no; - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSThttpBody bp; - char *type, *value; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path));// Load the ACL - - // Get pointer to the entry and perform checks - entry_no=atol(GRSThttpGetCGI("entry_no")); - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl)){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - // Create new credential and add it to entry - type=GRSThttpGetCGI("type"); - value=GRSThttpGetCGI("cred0_value"); - cred=GRSTgaclCredNew(type); - if (strcmp(type, "person") ==0) GRSTgaclCredAddValue(cred,"dn", value); - else if (strcmp(type, "dn-list") ==0) GRSTgaclCredAddValue(cred, "url", value); - else if (strcmp(type, "voms") ==0) GRSTgaclCredAddValue(cred, "fqan", value); - else if (strcmp(type, "dns") ==0) GRSTgaclCredAddValue(cred, "hostname", value); - else if (strcmp(type, "any-user")==0) {}// namevalue not entered for any-user credential - else{ - GRSThttpError ("500 Credential type not valid"); - return; - } - GRSTgaclEntryAddCred(entry, cred); - - check_acl_save(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, user, acl, &bp); - return; -} - - -void del_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Deletes the credential denoted by the GCI variable "cred_no", in the entry denoted by "entry_no" - int entry_no, cred_no; - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *previous, *cred; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); - - // Get pointer to the entry and perform checks - entry_no=atol(GRSThttpGetCGI("entry_no")); - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - // Get pointer the the credential and perform checks - cred_no=atol(GRSThttpGetCGI("cred_no")); - cred=GACLreturnCred(entry, cred_no); - if(entry==NULL || entry_no<1 || cred_no>GRSTgaclCredsInEntry(entry)){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - // Get pointer to previous credential - if needed - if (cred_no!=1) previous = GACLreturnCred(entry, cred_no-1); - - // Perform deletion from the list by changing pointers - if (cred_no==1) entry->firstcred=cred->next; - else if (cred_no==GRSTgaclCredsInEntry(entry)) previous->next=NULL; - else previous->next=cred->next; - - check_acl_save(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, user, acl, &bp); - return; -} - -void admin_continue(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file, GRSThttpBody *bp){ - // Single line printed out to forward users back to show_acl in admin mode - // Should ALWAYS called from another function so no HTML header required - // Should ALWAYS be the end of a page - GRSThttpPrintf (bp, "\n
Click Here to return to the editor", dir_uri,admin_file,dir_uri, time(NULL)); - adminfooter(bp, dn, help_uri, dir_uri, NULL); - GRSThttpPrintHeaderFooter(bp, dir_path, GRST_FOOTFILE); - GRSThttpWriteOut(bp); - return; -} - - -void del_entry_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Prints out entry denoted by entry_no and asks if the user really wants to delete it - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclNamevalue *namevalue; - int entry_no, cred_no, allow, deny, i, timestamp; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path));// Load ACL from file - - if (acl==NULL){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - // Get pointer to the entry and check okay - entry_no=atol(GRSThttpGetCGI("entry_no")); - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - StartHTML(&bp, dir_uri, dir_path); - GRSThttpPrintf (&bp, "

Do you really want to delete the following entry?



\n"); - GRSThttpPrintf (&bp,"
Entry %d:
\n", entry_no); - - // Print the entry out - // Start with the first credential in the entry and work through - cred=entry->firstcred; - cred_no=1; - - GRSTgaclCredTableStart(&bp); - while (cred!=NULL){ - // Start with the first namevalue in the credential - namevalue=cred->firstname; - GRSTgaclCredTableAdd(user, entry, cred, namevalue, cred_no, entry_no, 0, 0, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - // Change to next credential - cred=cred->next; - cred_no++; - } - - GRSTgaclCredTableEnd (entry, entry_no, 0, 0, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - - StartForm(&bp, dir_uri, dir_path, admin_file, atol(GRSThttpGetCGI("timestamp")), "del_entry"); - GRSThttpPrintf (&bp, "\n", entry_no); - GRSThttpPrintf (&bp, "

\n\n"); - - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; -} - -void del_cred_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Prints out credential denoted by entry_no/cred_no and asks if the user really wants to delete it - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclNamevalue *namevalue; - int entry_no, cred_no, allow, deny, timestamp, i; - GRSThttpBody bp; - - if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); - - acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path));// Load ACL from file - - if (acl==NULL){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - // Get pointer to the entry and check okay - entry_no=atol(GRSThttpGetCGI("entry_no")); - entry = GACLreturnEntry(acl, entry_no); - if(entry==NULL || entry_no<1 || entry_no>GACLentriesInAcl(acl) ){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - // Get pointer to the credential and check okay - cred_no=atol(GRSThttpGetCGI("cred_no")); - cred=GACLreturnCred(entry, cred_no); - if(entry==NULL || entry_no<1 || cred_no>GRSTgaclCredsInEntry(entry)){ - GRSThttpError ("500 Unable to read from ACL file"); - return; - } - - if(GRSTgaclCredsInEntry(entry)<=1){ - del_entry_sure(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - return; - } - - StartHTML(&bp, dir_uri, dir_path); - GRSThttpPrintf (&bp, "

Do you really want to delete the following credential from entry %d?



", entry_no); - - // Print the credential out - GRSTgaclCredTableStart(&bp); - GRSTgaclCredTableAdd(user, entry, cred, cred->firstname, cred_no, entry_no, 0, 0, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - GRSTgaclCredTableEnd (entry, entry_no, 0, 0, &bp, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - GRSThttpPrintf (&bp,"
\n"); - - // Yes Button - StartForm(&bp, dir_uri, dir_path, admin_file, atol(GRSThttpGetCGI("timestamp")), "del_cred"); - GRSThttpPrintf (&bp, "\n", entry_no); - GRSThttpPrintf (&bp, "\n", cred_no); - GRSThttpPrintf (&bp, "

\n\n"); - - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, &bp); - return; -} - - -int GACLentriesInAcl(GRSTgaclAcl *acl){ - // Returns the number of entries in acl - GRSTgaclEntry *entry; - int number; - - entry=acl->firstentry; - number=0; - - while (entry!=NULL) - { - number++; - entry=entry->next; - } - - return number; -} - -int GRSTgaclCredsInEntry(GRSTgaclEntry *entry){ - // Returns the number of credentials in entry - int number; - GRSTgaclCred *cred; - - cred=entry->firstcred; - number=0; - - while (cred!=NULL) - { - number++; - cred=cred->next; - } - - return number; -} - - -void GACLeditGetPerms(GRSTgaclEntry *entry){ - // Updates the permissions entry using permissions from a form produced using GRSTgaclCredTableEnd - int i; - char buf[30]; - - - for (i=0; grst_perm_syms[i]!=NULL; i++) /* Print the list of allowed permissions*/ - { - sprintf (buf, "allow_%s", grst_perm_syms[i]); // Update allowed - if (strcmp (GRSThttpGetCGI(buf), "ON") == 0 ) GRSTgaclEntryAllowPerm(entry, grst_perm_vals[i]); else GRSTgaclEntryUnallowPerm(entry, grst_perm_vals[i]); - - sprintf (buf, "deny_%s", grst_perm_syms[i]); // Update denied - if (strcmp (GRSThttpGetCGI(buf), "ON") == 0 ) GRSTgaclEntryDenyPerm(entry, grst_perm_vals[i]); else GRSTgaclEntryUndenyPerm(entry, grst_perm_vals[i]); - - } - - return; -} - -GRSTgaclEntry *GACLreturnEntry(GRSTgaclAcl *acl, int entry_no){ - // Returns a pointer to entry in ACL denoted by entry_no, returns NULL if not found - int number; - GRSTgaclEntry *entry; - - if (acl==NULL) return NULL; - - entry=acl->firstentry; - number=1; - - while (entry!=NULL) - { - if (number==entry_no) return entry; - number++; - entry=entry->next; - } - - return NULL; -} - - -GRSTgaclCred *GACLreturnCred(GRSTgaclEntry *entry, int cred_no){ - // Returns a pointer to credential denoted by cred_no in entry, returns NULL if not found - int number; - GRSTgaclCred *cred; - - if (entry==NULL) return NULL; - - cred=entry->firstcred; - number=1; - - while (cred!=NULL) - { - if (number==cred_no) return cred; - number++; - cred=cred->next; - } - - return NULL; -} -void StartHTML(GRSThttpBody *bp, char *dir_uri, char* dir_path){ - //Start HTML output and insert page title - printf("Status: 200 OK\nContent-Type: text/html\n"); - GRSThttpBodyInit(bp); - GRSThttpPrintf(bp, "Access Control List for %s\n", dir_uri); - GRSThttpPrintHeaderFooter(bp, dir_path, GRST_HEADFILE); - return; -} -void StartForm(GRSThttpBody *bp, char* dir_uri, char* dir_path, char* admin_file, int timestamp, char* target_function){ - // Starts an HTML form with gridsite admin as the target and target_function as the value of cmd. - // Also inputs the dir_uri and the timestamp - GRSThttpPrintf (bp, "
\n", dir_uri, admin_file, dir_uri); - GRSThttpPrintf (bp, " \n", target_function); - GRSThttpPrintf (bp, " \n", timestamp); - return; -} - -void EndForm(GRSThttpBody *bp){ - GRSThttpPrintf (bp, "

\n"); - GRSThttpPrintf (bp, "
\n"); - return; -} - -void GRSTgaclCredTableStart(GRSThttpBody *bp){ - //Starts an HTML table of credentials by setting the column widths and inputting the headings - GRSThttpPrintf (bp,""); - GRSThttpPrintf (bp,""); - return; -} - -void GRSTgaclCredTableAdd(GRSTgaclUser *user, GRSTgaclEntry *entry, GRSTgaclCred *cred, GRSTgaclNamevalue *namevalue, int cred_no, int entry_no, int admin, int timestamp, GRSThttpBody *bp, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Adds the credential "cred" to a table started byGRSTgaclCredTableStart allowing the user to edit if appropriate - char* cmd = GRSThttpGetCGI("cmd"); - int edit_values=0, new_cred=0, allow_new_person=1; - int site_admin=GRSTgaclDNlistHasUser(getenv("REDIRECT_GRST_ADMIN_LIST"), user); - - if (strcmp(cmd, "new_entry_form")==0 || strcmp(cmd, "add_cred_form")==0) new_cred=1; - if (new_cred || strcmp(cmd, "edit_entry_form")==0) edit_values=1; - - if (new_cred) { /*Print out type and descriptor*/ - if (strcmp(cmd, "add_cred_form")==0){ /*if not a new entry check to see if cred exists.*/ - cred=entry->firstcred; - while (cred!=NULL) {if (strcmp (cred->type, "person")==0) allow_new_person=0; cred=cred->next;} - } - //create dummy credential for the user to edit - cred=GRSTgaclCredNew("new"); - GRSTgaclCredAddValue(cred, "", ""); - namevalue=cred->firstname; - //Drop down list of types - GRSThttpPrintf(bp,""); - GRSThttpPrintf(bp,""); - } - - else { //Print out type and descriptor for existing cred - - GRSThttpPrintf(bp,""); -} - -void GRSTgaclCredTableEnd(GRSTgaclEntry* entry, int entry_no, int admin, int timestamp, GRSThttpBody *bp, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - // Finishes off a table of credentials by inputting "Add Credential" link and a list of premissions in the final row - int i, blank_perms, edit_perms, show_perms; - char* cmd = GRSThttpGetCGI("cmd"); - - if (strcmp(cmd, "add_cred_form")==0 ||strcmp(cmd, "del_cred_sure")==0) show_perms=0; else show_perms=1; - if (strcmp(cmd, "edit_entry_form")==0 || strcmp(cmd, "new_entry_form")==0) edit_perms=1; else edit_perms=0; - if (strcmp(cmd, "new_entry_form")==0) blank_perms=1; else blank_perms=0; - - // If showing the last row is not required then exit - if (show_perms==0){GRSThttpPrintf (bp,"
Credential No.TypeValue
New"); - GRSThttpPrintf (bp, "
%d", cred_no); - if (admin) GRSThttpPrintf (bp,"(Delete)", dir_uri,admin_file,dir_uri, entry_no, cred_no, timestamp); - GRSThttpPrintf(bp, "%s ", cred->type); - } - - if (strcmp(cred->type, "any-user")==0) GRSThttpPrintf (bp, " "); /* Do not print out namevalue for any-user credential*/ - else{ - if (edit_values){ // Place namevalue in an editable box if appropriate - GRSThttpPrintf (bp, "value, bp); - GRSThttpPrintf (bp, "\">"); - } - else if (strcmp(cred->type, "dn-list")==0){ - GRSThttpPrintf(bp, "value, bp); - GRSThttpPrintf(bp, " \">"); - StringHTMLEncode(namevalue->value, bp); - GRSThttpPrintf(bp, ""); - } - else { GRSThttpPrintf(bp, " "); StringHTMLEncode(namevalue->value, bp);} - - } - //Print out warning symbol if cred being printed relates to current user - but NOT for users in site admin list - if (GRSTgaclUserHasCred(user, cred) && !site_admin) GRSThttpPrintf(bp, " <--"); - GRSThttpPrintf(bp, "

\n"); return;} - - GRSThttpPrintf (bp,""); - - if (admin) GRSThttpPrintf (bp,"Add Credential", dir_uri,admin_file,dir_uri, entry_no, timestamp); - - GRSThttpPrintf (bp, "\n "); - - if (blank_perms) entry->allowed=entry->denied=GRST_PERM_NONE; - - // Show Permissions - will produce a list or a list of check boxes depending on whether the permissions are to be edited or not - GRSThttpPrintf (bp, "Allowed: "); - for (i=0; grst_perm_syms[i]!=NULL; i++) /* Print the list of allowed permissions*/ - { - if ( entry->allowed & grst_perm_vals[i]){ - if (edit_perms) GRSThttpPrintf (bp, "%s   \n", grst_perm_syms[i],grst_perm_syms[i]); - else GRSThttpPrintf(bp,"%s ", grst_perm_syms[i]); if (strcmp(grst_perm_syms[i], "none")==0) break; - } - else if (strcmp(grst_perm_syms[i], "none")!=0 && edit_perms) GRSThttpPrintf (bp, "%s   \n", grst_perm_syms[i],grst_perm_syms[i]); - } - - if (edit_perms) GRSThttpPrintf (bp, "

"); - GRSThttpPrintf (bp, "Denied: "); - for (i=0; grst_perm_syms[i]!=NULL; i++) /* Print the list of denied permissions*/ - { - if ( entry->denied & grst_perm_vals[i]) - { - if (edit_perms) GRSThttpPrintf (bp, "%s   \n", grst_perm_syms[i],grst_perm_syms[i]); - else GRSThttpPrintf(bp,"%s ", grst_perm_syms[i]); - if (strcmp(grst_perm_syms[i], "none")==0) break; - } - else if (strcmp(grst_perm_syms[i], "none")!=0 && edit_perms) GRSThttpPrintf (bp, "%s   \n", grst_perm_syms[i],grst_perm_syms[i]); - } - - GRSThttpPrintf (bp, ""); - GRSThttpPrintf (bp,"
\n"); - GRSThttpPrintf (bp,"\n"); -} - -void check_acl_save(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file, GRSTgaclUser* user, GRSTgaclAcl *acl, GRSThttpBody *bp){ - // Checks if the acl for the current directory has been changed, check the current user's permissions. - // If all is okay the ACl is saved -> returns 1 else returns 0 - struct stat file_info; - GRSTgaclPerm new_perm; - char *vfile, *dir_path_vfile, *dir_path_file; - FILE *fp; - - - /*Check ACL has not been modified*/ - stat(GRSTgaclFileFindAclname(dir_path), &file_info); - if (atol(GRSThttpGetCGI("timestamp"))!=file_info.st_mtime){ - StartHTML(bp, dir_uri, dir_path); - GRSThttpPrintf (bp, "ERROR: CANNOT SAVE CHANGES

The ACL has been modified since it was last viewed\n

"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, bp); - return; - } - - // check users permissions in the new ACL - - if (!GRSTgaclDNlistHasUser(getenv("REDIRECT_GRST_ADMIN_LIST"), user)) - { - new_perm = GRSTgaclAclTestUser(acl, user); - if (new_perm != perm){ - StartHTML(bp, dir_uri, dir_path); - if (!GRSTgaclPermHasAdmin(new_perm)){//Check that user still has Admin permissions - if not then exit without saving the new ACL - GRSThttpPrintf (bp, "ERROR: CANNOT SAVE CHANGES\n\n

You cannot deny yourself admin access from within the editor\n"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, bp); - return; - } - //Functions to inform of other permission changes come next - GRSThttpPrintf (bp, "WARNING: OPERATION CHANGED YOUR PERMISSIONS!\n\n

You still have Admin permissions

\n"); - admin_continue(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, bp); - return; - } - } - // ACL not modified, notified of permission changes - can now save - - dir_path_file=GRSTgaclFileFindAclname(dir_path); - vfile=makevfilename(".gacl", file_info.st_size, dn); // Make temporary file name - dir_path_vfile = malloc(strlen(dir_path) + strlen(vfile) + 2); - strcpy(dir_path_vfile, dir_path); - strcat(dir_path_vfile, "/"); - strcat(dir_path_vfile, vfile); - - GRSTgaclAclSave(acl, dir_path_vfile); // save the new ACL to the temporary file - unlink(dir_path_file); - if (link (dir_path_vfile,dir_path_file)!=0) GRSThttpError("403 Forbidden"); - - printf ("Status: 302 Moved Temporarily\n Content Length: 0\nLocation: %s%s?cmd=admin_acl\n\n", dir_uri, admin_file); - return; -} - -void StringHTMLEncode (char* string, GRSThttpBody *bp){ - - char* current_char; - char* tmp; - int n; - tmp=malloc(2); - - *(tmp+1)='\0'; - current_char=string; - while(*current_char != '\0'){ - - if (*current_char == '<') GRSThttpPrintf (bp,"<"); - else if (*current_char == '>') GRSThttpPrintf (bp,">"); - else if (*current_char == '&') GRSThttpPrintf (bp,"&"); - else if (*current_char == '\'') GRSThttpPrintf (bp,"'"); - else if (*current_char == '"') GRSThttpPrintf (bp,"""); - else{ - *tmp=*current_char; - GRSThttpPrintf(bp, "%s", tmp); - - } - current_char++; - } - return; -} - -void revert_acl(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - char *AclFilename; - GRSTgaclAcl *acl; - GRSThttpBody bp; - // Load the old ACL, add the entry and save - AclFilename=malloc(strlen(dir_path)+strlen(file)+2); - strcpy(AclFilename, dir_path); - strcat(AclFilename, "/"); - strcat(AclFilename, file); - - acl = GRSTgaclAclLoadFile(AclFilename); - check_acl_save(dn, perm, help_uri, dir_path, file, dir_uri, admin_file, user, acl, &bp); - return; -} diff --git a/org.gridsite.core/src/grst_admin_main.c b/org.gridsite.core/src/grst_admin_main.c deleted file mode 100644 index d884bf5..0000000 --- a/org.gridsite.core/src/grst_admin_main.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - Andrew McNab and Shiv Kaushal, University of Manchester. - Copyright (c) 2002-3. All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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 program is part of GridSite: http://www.gridsite.org/ * - *------------------------------------------------------------------*/ - -#ifndef VERSION -#define VERSION "x.x.x" -#endif - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// when porting: remember that sendfile() is very OS-specific! -#include - -#include - -#include "grst_admin.h" - -/* - - GridSite human/interactive management interface. This should produce - a CGI executable, usually ./sbin/real-gridsite-admin.cgi, which is - called from HTML forms either by GET or POST methods or both (ie input - present in both QUERY_STRING and the stdin of the CGI process.) - - The CGI name/value pairs used are: - - cmd = edit, managedir, print, history - file = short name of file, without path - - If real-gridsite-admin.cgi is run by an internal redirection inside - mod_gridsite (as should ALWAYS be the case) then the environment - variable REDIRECT_GRST_DIR_PATH will be set to the full path of - the directory holding the file in question. This respects any complex - URI -> file path mapping done by Apache. - -*/ - -void GRSThttpError(char *status) -{ - printf("Status: %s\n", status); - printf("Server-CGI: GridSite Admin %s\n", VERSION); - printf("Content-Length: %d\n", 2 * strlen(status) + 58); - puts("Content-Type: text/html\n"); - - printf("%s\n", status); - printf("

%s

\n", status); - - exit(0); -} - -void adminfooter(GRSThttpBody *bp, char *dn, char *help_uri, char *dir_uri, - char *admin_file) -{ - GRSThttpPrintf(bp, "

\n"); - - if (dn != NULL) GRSThttpPrintf(bp, "


You are %s
\n", dn); - else GRSThttpPrintf(bp, "
\n"); - - if (admin_file != NULL) - GRSThttpPrintf(bp, "" - "Manage directory .\n", - dir_uri, admin_file); - else GRSThttpPrintf(bp, "" - "Back to directory .\n", dir_uri); - - if (help_uri != NULL) - GRSThttpPrintf(bp, "Website Help .\n", help_uri); - - if ((getenv("GRST_NO_LINK") == NULL) && - (getenv("REDIRECT_GRST_NO_LINK") == NULL)) - GRSThttpPrintf(bp, "Built with " - "GridSite %s\n", - VERSION); - - GRSThttpPrintf(bp, "
\n"); -} - -int GRSTstrCmpShort(char *long_s, char *short_s) -{ - while (*short_s != '\0') - { - if (*long_s > *short_s) return +1; - if (*long_s < *short_s) return -1; - - ++long_s; - ++short_s; - } - - return 0; -} - -char *makevfilename(char *publicname, size_t size, char *dn) -{ - int i; - char *ext, *vfilename, *encpublicname, *encdn, *p; - struct timeval tv_now; - - gettimeofday(&tv_now, NULL); - - ext = rindex(publicname, '.'); - if (ext == NULL) ext = ""; - - encpublicname = GRSThttpUrlEncode(publicname); - for (p=encpublicname; *p != '\0'; ++p) if (*p == '%') *p = '='; - - encdn = GRSThttpUrlEncode(dn); - for (p=encdn; *p != '\0'; ++p) if (*p == '%') *p = '='; - - /* we used zero-padding for times so - alphanumeric sorting will sort chronologically too */ - - asprintf(&vfilename, "%s:%s:%08X:%05X:%X:%s:%s", GRST_HIST_PREFIX, - encpublicname, tv_now.tv_sec, tv_now.tv_usec, size, encdn, ext); - - return vfilename; -} - -void justheader(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *dir_uri, char *admin_file) -{ - GRSThttpBody bp; - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE); - - GRSThttpWriteOut(&bp); -} - -void justfooter(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *dir_uri, char *admin_file) -{ - GRSThttpBody bp; - - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); - - if (GRSTgaclPermHasList(perm) || GRSTgaclPermHasWrite(perm) - || GRSTgaclPermHasAdmin(perm)) - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - - GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); - - GRSThttpWriteOut(&bp); -} - -int main() -{ - int gsiproxylimit_i = 1; - char *cmd, *dir_uri, *file, *dir_path, *admin_file, *dn = NULL, - *help_uri, *p, *content_type, *request_uri, *button, - *grst_cred_0, *gsiproxylimit, *dn_lists; - GRSTgaclCred *cred; - GRSTgaclUser *user = NULL; - GRSTgaclAcl *acl; - GRSTgaclPerm perm = GRST_PERM_NONE; - - help_uri = getenv("REDIRECT_GRST_HELP_URI"); /* can be NULL */ - admin_file = getenv("REDIRECT_GRST_ADMIN_FILE"); - dir_path = getenv("REDIRECT_GRST_DIR_PATH"); - request_uri = getenv("REQUEST_URI"); - - if ((dir_path == NULL) || (admin_file == NULL) || (request_uri == NULL)) - { - puts("Status: 500 Internal Server Error\nContent-type: text/plain\n\n" - "REDIRECT_GRST_DIR_PATH or REDIRECT_GRST_ADMIN_FILE " - "or REQUEST_URI missing"); - return; - } - - GRSTgaclInit(); - - grst_cred_0 = getenv("GRST_CRED_0"); - - if ((grst_cred_0 != NULL) && (cred = GRSTx509CompactToCred(grst_cred_0))) - { - gsiproxylimit = getenv("REDIRECT_GRST_GSIPROXY_LIMIT"); - if (gsiproxylimit != NULL) sscanf(gsiproxylimit, "%d", &gsiproxylimit_i); - - if (GRSTgaclCredGetDelegation(cred) <= gsiproxylimit_i) - { - user = GRSTgaclUserNew(cred); - - if ((p = index(grst_cred_0, ' ')) && - (p = index(++p, ' ')) && - (p = index(++p, ' ')) && - (p = index(++p, ' '))) dn = &p[1]; - } - } - else if ((dn = getenv("SSL_CLIENT_S_DN")) != NULL) - { - cred = GRSTgaclCredNew("person"); - GRSTgaclCredAddValue(cred, "dn", dn); - user = GRSTgaclUserNew(cred); - } - - dn_lists = getenv("REDIRECT_GRST_DN_LISTS"); - if (dn_lists == NULL) dn_lists = getenv("GRST_DN_LISTS"); - if (dn_lists != NULL) GRSTgaclUserSetDNlists(user, dn_lists); - - if (GRSTgaclDNlistHasUser(getenv("REDIRECT_GRST_ADMIN_LIST"), - user)) perm = GRST_PERM_ALL; - else - { - p = getenv("REMOTE_HOST"); - if (p != NULL) - { - cred = GRSTgaclCredNew("dns"); - GRSTgaclCredAddValue(cred, "hostname", p); - - if (user == NULL) user = GRSTgaclUserNew(cred); - else GRSTgaclUserAddCred(user, cred); - } - - acl = GRSTgaclAclLoadforFile(dir_path); - if (acl != NULL) perm = GRSTgaclAclTestUser(acl, user); - } - - /* we're relying on being a CGI with all this un-free()ed strdup()ing */ - - dir_uri = strdup(request_uri); - p = rindex(dir_uri, '?'); - if (p != NULL) *p = '\0'; - p = rindex(dir_uri, '/'); - if (p != NULL) p[1] = '\0'; - - content_type = getenv("CONTENT_TYPE"); - - if ((content_type != NULL) && - (GRSTstrCmpShort(content_type, "multipart/form-data; boundary=") == 0)) - { - uploadfile(dn, perm, help_uri, dir_path, dir_uri, admin_file); - return 0; - } - - cmd = GRSThttpGetCGI("cmd"); - file = GRSThttpGetCGI("file"); - button = GRSThttpGetCGI("button"); - - /* file and directory functions in grst_admin_file.c */ - - if (strcmp(cmd, "header") == 0) - justheader(dn, perm, help_uri, dir_path, dir_uri, admin_file); - else if (strcmp(cmd, "footer") == 0) - justfooter(dn, perm, help_uri, dir_path, dir_uri, admin_file); - else if (strcmp(cmd, "managedir") == 0) - managedir(dn, perm, help_uri, dir_path, dir_uri, admin_file); - else if (strcmp(cmd, "print") == 0) - printfile(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "history") == 0) - filehistory(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "editdnlist") == 0) - editdnlistform(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "edit") == 0) - { - if ((strcasecmp(button, "new directory") == 0) || - (strcasecmp(button, "Create") == 0)) - newdirectory(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else - editfileform(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - } - else if (strcmp(cmd, "editaction") == 0) - editfileaction(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "editdnlistaction") == 0) - editdnlistaction(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "delete") == 0) - deletefileform(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "deleteaction") == 0) - deletefileaction(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "rename") == 0) - renameform(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "renameaction") == 0) - renameaction(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "ziplist") == 0) - ziplist(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "unzipfile") == 0) - unzipfile(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "create_acl") == 0) - create_acl(dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - - /* GACL functions in grst_admin_gacl.c */ - - else if (strcmp(cmd, "show_acl") == 0) - show_acl(0, user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "admin_acl") == 0) - show_acl(1, user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "acl_history") == 0) - show_acl(2, user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd, "revert_acl") == 0) - revert_acl(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - //show_acl(2, user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"new_entry_form")==0) - new_entry_form(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"new_entry")==0) - new_entry(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"del_entry_sure")==0) - del_entry_sure(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"del_entry")==0) - del_entry(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"edit_entry_form")==0) - edit_entry_form(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"edit_entry")==0) - edit_entry(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"add_cred_form")==0) - add_cred_form(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"add_cred")==0) - add_cred(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"del_cred_sure")==0) - del_cred_sure(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - else if (strcmp(cmd,"del_cred")==0) - del_cred(user, dn, perm, help_uri, dir_path, file, dir_uri, admin_file); - - /* you what? */ - - else GRSThttpError("500 Internal Server Error"); -} diff --git a/org.gridsite.core/src/grst_asn1.c b/org.gridsite.core/src/grst_asn1.c deleted file mode 100644 index e47c143..0000000 --- a/org.gridsite.core/src/grst_asn1.c +++ /dev/null @@ -1,506 +0,0 @@ - -#define _GNU_SOURCE -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include "gridsite.h" - -/// ASN1 time string (in a char *) to time_t -/** - * (Use ASN1_STRING_data() to convert ASN1_GENERALIZEDTIME to char * if - * necessary) - */ - -time_t GRSTasn1TimeToTimeT(char *asn1time, size_t len) -{ - char zone; - struct tm time_tm; - - if (len == 0) len = strlen(asn1time); - - if ((len != 13) && (len != 15)) return 0; /* dont understand */ - - if ((len == 13) && - ((sscanf(asn1time, "%02d%02d%02d%02d%02d%02d%c", - &(time_tm.tm_year), - &(time_tm.tm_mon), - &(time_tm.tm_mday), - &(time_tm.tm_hour), - &(time_tm.tm_min), - &(time_tm.tm_sec), - &zone) != 7) || (zone != 'Z'))) return 0; /* dont understand */ - - if ((len == 15) && - ((sscanf(asn1time, "20%02d%02d%02d%02d%02d%02d%c", - &(time_tm.tm_year), - &(time_tm.tm_mon), - &(time_tm.tm_mday), - &(time_tm.tm_hour), - &(time_tm.tm_min), - &(time_tm.tm_sec), - &zone) != 7) || (zone != 'Z'))) return 0; /* dont understand */ - - /* time format fixups */ - - if (time_tm.tm_year < 90) time_tm.tm_year += 100; - --(time_tm.tm_mon); - - return timegm(&time_tm); -} - -/* this function is taken from OpenSSL without modification */ - -static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, - int indent) - { - static const char fmt[]="%-18s"; - static const char fmt2[]="%2d %-15s"; - char str[128]; - const char *p,*p2=NULL; - - if (constructed & V_ASN1_CONSTRUCTED) - p="cons: "; - else - p="prim: "; - if (BIO_write(bp,p,6) < 6) goto err; -#if OPENSSL_VERSION_NUMBER >= 0x0090701fL - BIO_indent(bp,indent,128); -#endif - - p=str; - if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) - sprintf(str,"priv [ %d ] ",tag); - else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) - sprintf(str,"cont [ %d ]",tag); - else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) - sprintf(str,"appl [ %d ]",tag); - else p = ASN1_tag2str(tag); - - if (p2 != NULL) - { - if (BIO_printf(bp,fmt2,tag,p2) <= 0) goto err; - } - else - { - if (BIO_printf(bp,fmt,p) <= 0) goto err; - } - return(1); -err: - return(0); - } - -static void GRSTasn1AddToTaglist(struct GRSTasn1TagList taglist[], - int maxtag, int *lasttag, - char *treecoords, int start, int headerlength, - int length, int tag) -{ - if ((strlen(treecoords) > GRST_ASN1_MAXCOORDLEN) || - (*lasttag + 1 > maxtag)) return; - - ++(*lasttag); - - strncpy(taglist[*lasttag].treecoords, treecoords, GRST_ASN1_MAXCOORDLEN+1); - taglist[*lasttag].start = start; - taglist[*lasttag].headerlength = headerlength; - taglist[*lasttag].length = length; - taglist[*lasttag].tag = tag; -} - -int GRSTasn1SearchTaglist(struct GRSTasn1TagList taglist[], - int lasttag, char *treecoords) -{ - int i; - - for (i=0; i <= lasttag; ++i) - { - if (strcmp(treecoords, taglist[i].treecoords) == 0) return i; - } - - return -1; -} - -static int GRSTasn1PrintPrintable(BIO *bp, char *str, int length) -{ - int ret = 0; - char *dup, *p; - - dup = strndup(str, length); - - for (p=dup; *p != '\0'; ++p) if ((*p < ' ') || (*p > '~')) *p = '.'; - - if (bp != NULL) ret = BIO_write(bp, dup, strlen(dup)); - - free(dup); - - return ret; -} - -static int GRSTasn1Parse2(BIO *bp, unsigned char **pp, long length, int offset, - int depth, int indent, int dump, char *treecoords, - struct GRSTasn1TagList taglist[], int maxtag, int *lasttag) - { - int sibling = 0; - char sibtreecoords[512]; - - unsigned char *p,*ep,*tot,*op,*opp; - long len; - int tag,xclass,ret=0; - int nl,hl,j,r; - ASN1_OBJECT *o=NULL; - ASN1_OCTET_STRING *os=NULL; - int dump_indent; - - - dump_indent = 6; /* Because we know BIO_dump_indent() */ - p= *pp; - tot=p+length; - op=p-1; - while ((p < tot) && (op < p)) - { - op=p; - j=ASN1_get_object(&p,&len,&tag,&xclass,length); - - if (j & 0x80) - { - if ((bp != NULL) && - (BIO_write(bp,"Error in encoding\n",18) <= 0)) - goto end; - ret=0; - goto end; - } - hl=(p-op); - length-=hl; - - ++sibling; - sprintf(sibtreecoords, "%s-%d", treecoords, sibling); - - GRSTasn1AddToTaglist(taglist, maxtag, lasttag, sibtreecoords, - (int)offset+(int)(op - *pp), - (int) hl, len, tag); - - if (bp != NULL) - { - BIO_printf(bp, " %s %ld %ld %d %d ", sibtreecoords, - (long)offset+(long)(op - *pp), hl, len, tag); - - GRSTasn1PrintPrintable(bp, p, -// &((*pp)[(long)offset+(long)(op - *pp)+hl]), - (len > 30) ? 30 : len); - - BIO_printf(bp, "\n"); - } - - - /* if j == 0x21 it is a constructed indefinite length object */ - if ((bp != NULL) && - (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp)) - <= 0)) goto end; - - if (j != (V_ASN1_CONSTRUCTED | 1)) - { - if ((bp != NULL) && - (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ", - depth,(long)hl,len) <= 0)) - goto end; - } - else - { - if ((bp != NULL) && - (BIO_printf(bp,"d=%-2d hl=%ld l=inf ", - depth,(long)hl) <= 0)) - goto end; - } - if ((bp != NULL) && - !asn1_print_info(bp,tag,xclass,j,(indent)?depth:0)) - goto end; - if (j & V_ASN1_CONSTRUCTED) - { - ep=p+len; - if ((bp != NULL) && - (BIO_write(bp,"\n",1) <= 0)) goto end; - if (len > length) - { - if (bp != NULL) BIO_printf(bp, - "length is greater than %ld\n",length); - ret=0; - goto end; - } - if ((j == 0x21) && (len == 0)) - { - for (;;) - { - r=GRSTasn1Parse2(bp,&p,(long)(tot-p), - offset+(p - *pp),depth+1, - indent,dump,sibtreecoords, - taglist, maxtag, lasttag); - if (r == 0) { ret=0; goto end; } - if ((r == 2) || (p >= tot)) break; - } - } - else - while (p < ep) - { - r=GRSTasn1Parse2(bp,&p,(long)len, - offset+(p - *pp),depth+1, - indent,dump,sibtreecoords, - taglist, maxtag, lasttag); - if (r == 0) { ret=0; goto end; } - } - } - else if (xclass != 0) - { - p+=len; - if ((bp != NULL) && - (BIO_write(bp,"\n",1) <= 0)) goto end; - } - else - { - nl=0; - if ( (tag == V_ASN1_PRINTABLESTRING) || - (tag == V_ASN1_T61STRING) || - (tag == V_ASN1_IA5STRING) || - (tag == V_ASN1_VISIBLESTRING) || - (tag == V_ASN1_UTCTIME) || - (tag == V_ASN1_GENERALIZEDTIME)) - { - if ((bp != NULL) && - (BIO_write(bp,":",1) <= 0)) goto end; - if ((len > 0) && (bp != NULL) && - BIO_write(bp,(char *)p,(int)len) - != (int)len) - goto end; - } - else if (tag == V_ASN1_OBJECT) - { - opp=op; - if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL) - { - if (bp != NULL) - { - if (BIO_write(bp,":",1) <= 0) goto end; - i2a_ASN1_OBJECT(bp,o); - } - } - else - { - if ((bp != NULL) && - (BIO_write(bp,":BAD OBJECT",11) <= 0)) - goto end; - } - } - else if (tag == V_ASN1_BOOLEAN) - { - int ii; - - opp=op; - ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl); - if (ii < 0) - { - if ((bp != NULL) && - (BIO_write(bp,"Bad boolean\n",12))) - goto end; - } - if (bp != NULL) BIO_printf(bp,":%d",ii); - } - else if (tag == V_ASN1_BMPSTRING) - { - /* do the BMP thang */ - } - else if (tag == V_ASN1_OCTET_STRING) - { - int i; - - opp=op; - os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl); - if (os != NULL) - { - opp=os->data; - - if (os->length > 0) - { - if ((bp != NULL) && - (BIO_write(bp,":",1) <= 0)) - goto end; - if ((bp != NULL) && - (GRSTasn1PrintPrintable(bp, - opp, - os->length) <= 0)) - goto end; - } - - M_ASN1_OCTET_STRING_free(os); - os=NULL; - } - } - else if (tag == V_ASN1_INTEGER) - { - ASN1_INTEGER *bs; - int i; - - opp=op; - bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl); - if (bs != NULL) - { - if ((bp != NULL) && - (BIO_write(bp,":",1) <= 0)) goto end; - if (bs->type == V_ASN1_NEG_INTEGER) - if ((bp != NULL) && - (BIO_write(bp,"-",1) <= 0)) - goto end; - for (i=0; ilength; i++) - { - if ((bp != NULL) && - (BIO_printf(bp,"%02X", - bs->data[i]) <= 0)) - goto end; - } - if (bs->length == 0) - { - if ((bp != NULL) && - (BIO_write(bp,"00",2) <= 0)) - goto end; - } - } - else - { - if ((bp != NULL) && - (BIO_write(bp,"BAD INTEGER",11) <= 0)) - goto end; - } - M_ASN1_INTEGER_free(bs); - } - else if (tag == V_ASN1_ENUMERATED) - { - ASN1_ENUMERATED *bs; - int i; - - opp=op; - bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl); - if (bs != NULL) - { - if ((bp != NULL) && - (BIO_write(bp,":",1) <= 0)) goto end; - if (bs->type == V_ASN1_NEG_ENUMERATED) - if ((bp != NULL) && - (BIO_write(bp,"-",1) <= 0)) - goto end; - for (i=0; ilength; i++) - { - if ((bp != NULL) && - (BIO_printf(bp,"%02X", - bs->data[i]) <= 0)) - goto end; - } - if (bs->length == 0) - { - if ((bp != NULL) && - (BIO_write(bp,"00",2) <= 0)) - goto end; - } - } - else - { - if ((bp != NULL) && - (BIO_write(bp,"BAD ENUMERATED",11) <= 0)) - goto end; - } - M_ASN1_ENUMERATED_free(bs); - } - else if (len > 0 && dump) - { - if (!nl) - { - if ((bp != NULL) && - (BIO_write(bp,"\n",1) <= 0)) - goto end; - } - if ((bp != NULL) && - (BIO_dump_indent(bp,(char *)p, - ((dump == -1 || dump > len)?len:dump), - dump_indent) <= 0)) - goto end; - nl=1; - } - - if (!nl) - { - if ((bp != NULL) && - (BIO_write(bp,"\n",1) <= 0)) goto end; - } - p+=len; - if ((tag == V_ASN1_EOC) && (xclass == 0)) - { - ret=2; /* End of sequence */ - goto end; - } - } - - length-=len; - } - ret=1; -end: - if (o != NULL) ASN1_OBJECT_free(o); - if (os != NULL) M_ASN1_OCTET_STRING_free(os); - *pp=p; - return(ret); - } - -int GRSTasn1ParseDump(BIO *bp, unsigned char *pp, long len, - struct GRSTasn1TagList taglist[], - int maxtag, int *lasttag) - { - return(GRSTasn1Parse2(bp,&pp,len,0,0,0,0,"", - taglist, maxtag, lasttag)); - } - -int GRSTasn1GetX509Name(char *x509name, int maxlength, char *coords, - char *asn1string, - struct GRSTasn1TagList taglist[], int lasttag) -{ - int i, iobj, istr, n, len = 0; - ASN1_OBJECT *obj = NULL; - unsigned char coordstmp[81], *q; - const unsigned char *shortname; - - for (i=1; ; ++i) - { - sprintf(coordstmp, coords, i, 1); - iobj = GRSTasn1SearchTaglist(taglist, lasttag, coordstmp); - if (iobj < 0) break; - - sprintf(coordstmp, coords, i, 2); - istr = GRSTasn1SearchTaglist(taglist, lasttag, coordstmp); - if (istr < 0) break; - - q = &asn1string[taglist[iobj].start]; - d2i_ASN1_OBJECT(&obj, &q, taglist[iobj].length + - taglist[iobj].headerlength); - - n = OBJ_obj2nid(obj); -// free obj now? - shortname = OBJ_nid2sn(n); - - if (len + 2 + strlen(shortname) + taglist[istr].length >= maxlength) - { - x509name[0] = '\0'; - return GRST_RET_FAILED; - } - - sprintf(&x509name[len], "/%s=%.*s", shortname, - taglist[istr].length, - &asn1string[taglist[istr].start+taglist[istr].headerlength]); - len += 2 + strlen(shortname) + taglist[istr].length; - } - - x509name[len] = '\0'; - - return GRST_RET_OK; -} diff --git a/org.gridsite.core/src/grst_gacl.c b/org.gridsite.core/src/grst_gacl.c deleted file mode 100644 index 13b46c8..0000000 --- a/org.gridsite.core/src/grst_gacl.c +++ /dev/null @@ -1,1154 +0,0 @@ -/* - Copyright (c) 2002-3, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. -*/ -/*---------------------------------------------------------------* - * For more information about GridSite: http://www.gridsite.org/ * - *---------------------------------------------------------------*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#include - -#include -#include -#include - -#include "gridsite.h" - -/* * - * Global variables, shared by all GACL functions by private to libgacl * - * */ - -char *grst_perm_syms[] = { "none", - "read", - "exec", - "list", - "write", - "admin", - NULL }; - -GRSTgaclPerm grst_perm_vals[] = { GRST_PERM_NONE, - GRST_PERM_READ, - GRST_PERM_EXEC, - GRST_PERM_LIST, - GRST_PERM_WRITE, - GRST_PERM_ADMIN, - -1 }; - -int GRSTgaclInit(void) -{ - xmlInitParser(); - - LIBXML_TEST_VERSION - - xmlKeepBlanksDefault(0); - - return 1; -} - -/* * - * Functions to manipulate GRSTgaclCred structures * - * */ - -GRSTgaclCred *GRSTgaclCredNew(char *type) -/* - GRSTgaclCredNew - allocate a new GRSTgaclCred structure, and return - it's pointer or NULL on (malloc) error. -*/ -{ - GRSTgaclCred *newcred; - - if (type == NULL) return NULL; - - newcred = malloc(sizeof(GRSTgaclCred)); - if (newcred == NULL) return NULL; - - newcred->type = strdup(type); - newcred->delegation = 0; - newcred->firstname = NULL; - newcred->next = NULL; - - return newcred; -} - -int GRSTgaclCredAddValue(GRSTgaclCred *cred, char *rawname, char *rawvalue) -/* - GRSTgaclCredAddValue - add a name/value pair to a GRSTgaclCred -*/ -{ - int i; - char *name, *value; - GRSTgaclNamevalue *p; - - name = strdup(rawname); - - /* no leading or trailing space in value */ - - value = rawvalue; - while ((*value != '\0') && isspace(*value)) ++value; - - value = strdup(value); - - for (i=strlen(value) - 1; (i >= 0) && isspace(value[i]); --i) value[i]='\0'; - - if (cred->firstname == NULL) - { - cred->firstname = malloc(sizeof (GRSTgaclNamevalue)); - (cred->firstname)->name = name; - (cred->firstname)->value = value; - (cred->firstname)->next = NULL; - } - else - { - p = cred->firstname; - - while (p->next != NULL) p = (GRSTgaclNamevalue *) p->next; - - p->next = malloc(sizeof(GRSTgaclNamevalue)); - ((GRSTgaclNamevalue *) p->next)->name = name; - ((GRSTgaclNamevalue *) p->next)->value = value; - ((GRSTgaclNamevalue *) p->next)->next = NULL; - } - - return 1; -} - -static int GRSTgaclNamevalueFree(GRSTgaclNamevalue *p) -{ - if (p == NULL) return 1; - - if (p->next != NULL) - GRSTgaclNamevalueFree((GRSTgaclNamevalue *) p->next); - if (p->name != NULL) free(p->name); - if (p->value != NULL) free(p->value); - free(p); - - return 1; -} - -int GRSTgaclCredFree(GRSTgaclCred *cred) -/* - GRSTgaclCredFree - free memory structures of a GRSTgaclCred, - returning 1 always! -*/ -{ - if (cred == NULL) return 1; - - GRSTgaclNamevalueFree(cred->firstname); - if (cred->type != NULL) free(cred->type); - free(cred); - - return 1; -} - -static int GRSTgaclCredsFree(GRSTgaclCred *firstcred) -/* - GRSTgaclCredsFree - free a cred and all the creds in its *next chain -*/ -{ - if (firstcred == NULL) return 0; - - if (firstcred->next != NULL) GRSTgaclCredsFree(firstcred->next); - - return GRSTgaclCredFree(firstcred); -} - -static int GRSTgaclCredInsert(GRSTgaclCred *firstcred, GRSTgaclCred *newcred) -/* - GRSTgaclCredInsert - insert a cred in the *next chain of firstcred - - FOR THE MOMENT THIS JUST APPENDS! -*/ -{ - if (firstcred == NULL) return 0; - - if (firstcred->next == NULL) - { - firstcred->next = newcred; - return 1; - } - - return GRSTgaclCredInsert(firstcred->next, newcred); -} - -int GRSTgaclEntryAddCred(GRSTgaclEntry *entry, GRSTgaclCred *cred) -/* - GRSTaddCred - add a new credential to an existing entry, returning 1 - on success or 0 on error -*/ -{ - if (entry == NULL) return 0; - - if (entry->firstcred == NULL) - { - entry->firstcred = cred; - return 1; - } - else return GRSTgaclCredInsert(entry->firstcred, cred); -} - -static int GRSTgaclCredRemoveCred(GRSTgaclCred *firstcred, GRSTgaclCred *oldcred) -/* - (Private) - - GRSTgaclCredRemoveCred - remove a cred in the *next chain of firstcred - and relink the chain -*/ -{ - if (firstcred == NULL) return 0; - -// yeah, I know -} - -int GRSTgaclEntryDelCred(GRSTgaclEntry *entry, GRSTgaclCred *cred) -/* - GRSTgaclEntryDelCred - remove a new cred from an entry, returning 1 - on success (or absense) or 0 on error. -*/ -{ - if (entry == NULL) return 0; - - return GRSTgaclCredRemoveCred(entry->firstcred, cred); -} - -int GRSTgaclCredPrint(GRSTgaclCred *cred, FILE *fp) -/* - GRSTgaclCredPrint - print a credential and any name-value pairs is contains -*/ -{ - char *q; - GRSTgaclNamevalue *p; - - if (cred->firstname != NULL) - { - fprintf(fp, "<%s>\n", cred->type); - - p = cred->firstname; - - do { - fprintf(fp, "<%s>", p->name); - - for (q=p->value; *q != '\0'; ++q) - if (*q == '<') fputs("<", fp); - else if (*q == '>') fputs(">", fp); - else if (*q == '&') fputs("&" , fp); - else if (*q == '\'') fputs("'", fp); - else if (*q == '"') fputs(""", fp); - else fputc(*q, fp); - - fprintf(fp, "\n", p->name); - - p = (GRSTgaclNamevalue *) p->next; - - } while (p != NULL); - - fprintf(fp, "\n", cred->type); - } - else fprintf(fp, "<%s/>\n", cred->type); - - return 1; -} - -/* * - * Functions to manipulate GRSTgaclEntry structures * - * */ - -GRSTgaclEntry *GRSTgaclEntryNew(void) -/* - GRSTgaclEntryNew - allocate space for a new entry, returning its pointer - or NULL on failure. -*/ -{ - GRSTgaclEntry *newentry; - - newentry = (GRSTgaclEntry *) malloc(sizeof(GRSTgaclEntry)); - if (newentry == NULL) return NULL; - - newentry->firstcred = NULL; - newentry->allowed = 0; - newentry->denied = 0; - newentry->next = NULL; - - return newentry; -} - -int GRSTgaclEntryFree(GRSTgaclEntry *entry) -/* - GRSTgaclEntryFree - free up space used by an entry (always returns 1) -*/ -{ - int i; - - if (entry == NULL) return 1; - - GRSTgaclCredsFree(entry->firstcred); - - free(entry); - - return 1; -} - -static int GRSTgaclEntriesFree(GRSTgaclEntry *entry) -/* - GRSTgaclEntriesFree - free up entry and all entries linked to in its *next - chain -*/ -{ - if (entry == NULL) return 0; - - if (entry->next != NULL) GRSTgaclEntriesFree(entry->next); - - return GRSTgaclEntryFree(entry); -} - -static int GRSTgaclEntryInsert(GRSTgaclEntry *firstentry, GRSTgaclEntry *newentry) -/* - GRSTgaclEntryInsert - insert an entry in the *next chain of firstentry - - FOR THE MOMENT THIS JUST APPENDS -*/ -{ - if (firstentry == NULL) return 0; - - if (firstentry->next == NULL) - { - firstentry->next = newentry; - return 1; - } - - return GRSTgaclEntryInsert(firstentry->next, newentry); -} - -int GRSTgaclAclAddEntry(GRSTgaclAcl *acl, GRSTgaclEntry *entry) -/* - GRSTgaclAclAddEntry - add a new entry to an existing acl, returning 1 - on success or 0 on error -*/ -{ - if (acl == NULL) return 0; - - if (acl->firstentry == NULL) - { - acl->firstentry = entry; - return 1; - } - else return GRSTgaclEntryInsert(acl->firstentry, entry); -} - -int GRSTgaclEntryPrint(GRSTgaclEntry *entry, FILE *fp) -{ - GRSTgaclCred *cred; - GRSTgaclPerm i; - - fputs("\n", fp); - - for (cred = entry->firstcred; cred != NULL; cred = cred->next) - GRSTgaclCredPrint(cred, fp); - - if (entry->allowed) - { - fputs("", fp); - - for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i) - if ((entry->allowed) & i) GRSTgaclPermPrint(i, fp); - - fputs("\n", fp); - } - - - if (entry->denied) - { - fputs("", fp); - - for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i) - if (entry->denied & i) GRSTgaclPermPrint(i, fp); - - fputs("\n", fp); - } - - fputs("\n", fp); - - return 1; -} - -/* * - * Functions to manipulate GRSTgaclPerm items * - * */ - -int GRSTgaclPermPrint(GRSTgaclPerm perm, FILE *fp) -{ - GRSTgaclPerm i; - - for (i=GRST_PERM_READ; grst_perm_syms[i] != NULL; ++i) - if (perm == grst_perm_vals[i]) - { - fprintf(fp, "<%s/>", grst_perm_syms[i]); - return 1; - } - - return 0; -} - -int GRSTgaclEntryAllowPerm(GRSTgaclEntry *entry, GRSTgaclPerm perm) -{ - entry->allowed = entry->allowed | perm; - - return 1; -} - -int GRSTgaclEntryUnallowPerm(GRSTgaclEntry *entry, GRSTgaclPerm perm) -{ - entry->allowed = entry->allowed & ~perm; - - return 1; -} - -int GRSTgaclEntryDenyPerm(GRSTgaclEntry *entry, GRSTgaclPerm perm) -{ - entry->denied = entry->denied | perm; - - return 1; -} - -int GRSTgaclEntryUndenyPerm(GRSTgaclEntry *entry, GRSTgaclPerm perm) -{ - entry->denied = entry->denied & ~perm; - - return 1; -} - -char *GRSTgaclPermToChar(GRSTgaclPerm perm) -/* - GRSTgaclPermToChar - return char * or NULL corresponding to most significant - set bit of perm. -*/ -{ - char *p = NULL; - GRSTgaclPerm i; - - for (i=0; grst_perm_syms[i] != NULL; ++i) - if (perm & grst_perm_vals[i]) p = grst_perm_syms[i]; - - return p; -} - -GRSTgaclPerm GRSTgaclPermFromChar(char *s) -/* - GRSTgaclPermToChar - return access perm corresponding to symbol s[] -*/ -{ - GRSTgaclPerm i; - - for (i=0; grst_perm_syms[i] != NULL; ++i) - if (strcasecmp(grst_perm_syms[i], s) == 0) return grst_perm_vals[i]; - - return -1; -} - -/* * - * Functions to manipulate GRSTgaclAcl structures * - * */ - -GRSTgaclAcl *GRSTgaclAclNew(void) -/* - GRSTgaclAclNew - allocate a new acl and return its pointer (or NULL - on failure.) -*/ -{ - GRSTgaclAcl *newacl; - - newacl = (GRSTgaclAcl *) malloc(sizeof(GRSTgaclAcl)); - if (newacl == NULL) return NULL; - - newacl->firstentry = NULL; - - return newacl; -} - -int GRSTgaclAclFree(GRSTgaclAcl *acl) -/* - GRSTgaclAclFree - free up space used by *acl. Always returns 1. -*/ -{ - if (acl == NULL) return 1; - - GRSTgaclEntriesFree(acl->firstentry); - - return 1; -} - -int GRSTgaclAclPrint(GRSTgaclAcl *acl, FILE *fp) -{ - GRSTgaclEntry *entry; - - fputs("\n", fp); - - for (entry = acl->firstentry; entry != NULL; entry = entry->next) - GRSTgaclEntryPrint(entry, fp); - - fputs("\n", fp); - - return 1; -} - -int GRSTgaclAclSave(GRSTgaclAcl *acl, char *filename) -{ - int ret; - FILE *fp; - - fp = fopen(filename, "w"); - if (fp == NULL) return 0; - - fputs("\n", fp); - - ret = GRSTgaclAclPrint(acl, fp); - - fclose(fp); - - return ret; -} - -/* * - * Functions for loading and parsing XML using libxml * - * */ - -// need to check these for libxml memory leaks? - what needs to be freed? - -static GRSTgaclCred *GRSTgaclCredParse(xmlNodePtr cur) -/* - GRSTgaclCredParse - parse a credential stored in the libxml structure cur, - returning it as a pointer or NULL on error. -*/ -{ - xmlNodePtr cur2; - GRSTgaclCred *cred; - - cred = GRSTgaclCredNew((char *) cur->name); - - cred->firstname = NULL; - cred->next = NULL; - - for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) - { - GRSTgaclCredAddValue(cred, (char *) cur2->name, - (char *) xmlNodeGetContent(cur2)); - } - - return cred; -} - -static GRSTgaclEntry *GRSTgaclEntryParse(xmlNodePtr cur) -/* - GRSTgaclEntryParse - parse an entry stored in the libxml structure cur, - returning it as a pointer or NULL on error. -*/ -{ - int i; - xmlNodePtr cur2; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - GRSTgaclPerm perm; - - if (xmlStrcmp(cur->name, (const xmlChar *) "entry") != 0) return NULL; - - cur = cur->xmlChildrenNode; - - entry = GRSTgaclEntryNew(); - - while (cur != NULL) - { - if (xmlStrcmp(cur->name, (const xmlChar *) "allow") == 0) - { - for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) - for (i=0; grst_perm_syms[i] != NULL; ++i) - if (xmlStrcmp(cur2->name, - (const xmlChar *) grst_perm_syms[i]) == 0) - GRSTgaclEntryAllowPerm(entry, grst_perm_vals[i]); - } - else if (xmlStrcmp(cur->name, (const xmlChar *) "deny") == 0) - { - for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) - for (i=0; grst_perm_syms[i] != NULL; ++i) - if (xmlStrcmp(cur2->name, - (const xmlChar *) grst_perm_syms[i]) == 0) - GRSTgaclEntryDenyPerm(entry, grst_perm_vals[i]); - } - else if ((cred = GRSTgaclCredParse(cur)) != NULL) - { - if (!GRSTgaclEntryAddCred(entry, cred)) - { - GRSTgaclCredFree(cred); - GRSTgaclEntryFree(entry); - return NULL; - } - } - else /* I cannot parse this - give up rather than get it wrong */ - { - GRSTgaclEntryFree(entry); - return NULL; - } - - cur=cur->next; - } - - return entry; -} - -GRSTgaclAcl *GRSTgaclAclLoadFile(char *filename) -{ - xmlDocPtr doc; - xmlNodePtr cur; - GRSTgaclAcl *acl; - GRSTgaclEntry *entry; - - doc = xmlParseFile(filename); - if (doc == NULL) return NULL; - - cur = xmlDocGetRootElement(doc); - - if (xmlStrcmp(cur->name, (const xmlChar *) "gacl")) - { - free(doc); - free(cur); - return NULL; - } - - cur = cur->xmlChildrenNode; - - acl = GRSTgaclAclNew(); - - while (cur != NULL) - { - entry = GRSTgaclEntryParse(cur); - if (entry == NULL) - { - GRSTgaclAclFree(acl); - xmlFreeDoc(doc); - return NULL; - } - - GRSTgaclAclAddEntry(acl, entry); - - cur=cur->next; - } - - xmlFreeDoc(doc); - return acl; -} - -int GRSTgaclFileIsAcl(char *pathandfile) -/* Return 1 if filename in *pathandfile starts GRST_ACL_FILE - Return 0 otherwise. */ -{ - char *filename; - - filename = rindex(pathandfile, '/'); - if (filename == NULL) filename = pathandfile; - else filename++; - - return (strncmp(filename, GRST_ACL_FILE, sizeof(GRST_ACL_FILE) - 1) == 0); -} - -char *GRSTgaclFileFindAclname(char *pathandfile) -/* Return malloc()ed ACL filename that governs the given file or directory - (for directories, the ACL file is in the directory itself), or NULL if none - can be found. */ -{ - int len; - char *path, *file, *p; - struct stat statbuf; - - len = strlen(pathandfile); - if (len == 0) return NULL; - - path = malloc(len + sizeof(GRST_ACL_FILE) + 2); - strcpy(path, pathandfile); - - if ((stat(path, &statbuf) == 0) && - S_ISDIR(statbuf.st_mode) && - (path[len-1] != '/')) - { - strcat(path, "/"); - ++len; - } - - if (path[len-1] != '/') - { - p = rindex(pathandfile, '/'); - if (p != NULL) - { - file = &p[1]; - p = rindex(path, '/'); - sprintf(p, "/%s:%s", GRST_ACL_FILE, file); - - if (stat(path, &statbuf) == 0) return path; - - *p = '\0'; /* otherwise strip off any filename */ - } - } - - while (path[0] != '\0') - { - strcat(path, "/"); - strcat(path, GRST_ACL_FILE); - - if (stat(path, &statbuf) == 0) return path; - - p = rindex(path, '/'); - *p = '\0'; /* strip off the / we added for ACL */ - - p = rindex(path, '/'); - if (p == NULL) break; /* must start without / and we there now ??? */ - - *p = '\0'; /* strip off another layer of / */ - } - - free(path); - return NULL; -} - -GRSTgaclAcl *GRSTgaclAclLoadforFile(char *pathandfile) -/* Return ACL that governs the given file or directory (for directories, - the ACL file is in the directory itself.) */ -{ - char *path; - GRSTgaclAcl *acl; - - path = GRSTgaclFileFindAclname(pathandfile); - - if (path != NULL) - { - acl = GRSTgaclAclLoadFile(path); - free(path); - return acl; - } - - return NULL; -} - -/* * - * Functions to create and query GACLuser * - * */ - -GRSTgaclUser *GRSTgaclUserNew(GRSTgaclCred *cred) -{ - GRSTgaclUser *user; - - if (cred == NULL) return NULL; - - user = malloc(sizeof(GRSTgaclUser)); - - if (user != NULL) user->firstcred = cred; - - user->dnlists = NULL; - - return user; -} - -int GRSTgaclUserFree(GRSTgaclUser *user) -{ - if (user == NULL) return 1; - - if (user->firstcred != NULL) GRSTgaclCredsFree(user->firstcred); - - if (user->dnlists != NULL) free(user->dnlists); - - free(user); - - return 1; -} - -int GRSTgaclUserAddCred(GRSTgaclUser *user, GRSTgaclCred *cred) -{ - GRSTgaclCred *crediter; - - if ((user == NULL) || (cred == NULL)) return 0; - - if (user->firstcred == NULL) - { - user->firstcred = cred; - cred->next = NULL; /* so cannot be used to add whole lists */ - return 1; - } - - crediter = user->firstcred; - - while (crediter->next != NULL) crediter = crediter->next; - - crediter->next = cred; - cred->next = NULL; /* so cannot be used to add whole lists */ - - return 1; -} - -int GRSTgaclUserHasCred(GRSTgaclUser *user, GRSTgaclCred *cred) -/* test if the user has the given credential */ -{ - GRSTgaclCred *crediter; - GRSTgaclNamevalue *usernamevalue, *crednamevalue; - - if (cred == NULL) return 0; - - if (strcmp(cred->type, "any-user") == 0) return 1; - - if (user == NULL) return 0; - - if (strcmp(cred->type, "dn-list") == 0) - { - if ((cred->firstname == NULL) || - (strcmp((cred->firstname)->name, "url") != 0) || - ((cred->firstname)->next != NULL)) return 0; - - return GRSTgaclDNlistHasUser((cred->firstname)->value, user); - } - - if (strcmp(cred->type, "dns") == 0) - { - if ((user->firstcred == NULL) || - ((user->firstcred)->firstname == NULL) || - (cred->firstname == NULL) || - (strcmp((cred->firstname)->name, "hostname") != 0) || - ((cred->firstname)->next != NULL)) return 0; - - for (crediter=user->firstcred; - crediter != NULL; - crediter = crediter->next) - if (strcmp(crediter->type, "dns") == 0) - { - if ((crediter->firstname == NULL) || - (strcmp((crediter->firstname)->name, "hostname") != 0)) return 0; - - return (fnmatch((cred->firstname)->value, - (crediter->firstname)->value, FNM_CASEFOLD) == 0); - } - - return 0; - } - - if (strcmp(cred->type, "auth-user") == 0) - { - if ((user->firstcred == NULL) || - ((user->firstcred)->firstname == NULL)) return 0; - - for (crediter=user->firstcred; - crediter != NULL; - crediter = crediter->next) - if (strcmp(crediter->type, "person") == 0) return 1; - - return 0; - } - - for (crediter=user->firstcred; crediter != NULL; crediter = crediter->next) - { - if (strcmp(crediter->type, cred->type) != 0) continue; - - if ((crediter->firstname == NULL) && - (cred->firstname == NULL)) return 1; - - if ((crediter->firstname == NULL) || - (cred->firstname == NULL)) continue; - - usernamevalue = crediter->firstname; - crednamevalue = cred->firstname; - - for (;;) - { - if (strcmp(usernamevalue->name,crednamevalue->name) != 0) break; - - if (strcmp(cred->type, "person") == 0) - { - if (GRSTx509NameCmp(usernamevalue->value, - crednamevalue->value) != 0) break; - } - else if (strcmp(usernamevalue->value, - crednamevalue->value) != 0) break; - - /* ok if cred list runs out before user's cred list */ - if (crednamevalue->next == NULL) return 1; - - /* but not ok if more names to match which user doesn't have */ - if (usernamevalue->next == NULL) break; - - crednamevalue = (GRSTgaclNamevalue *) crednamevalue->next; - usernamevalue = (GRSTgaclNamevalue *) usernamevalue->next; - } - } - - return 0; -} - -GRSTgaclCred *GRSTgaclUserFindCredtype(GRSTgaclUser *user, char *type) -/* find the first credential of a given type for this user */ -{ - GRSTgaclCred *cred; - - if (user == NULL) return NULL; - - cred = user->firstcred; - - while (cred != NULL) - { - if (strcmp(cred->type, type) == 0) return cred; - - cred = cred->next; - } - - return NULL; -} - -int GRSTgaclUserSetDNlists(GRSTgaclUser *user, char *dnlists) -{ - if ((user == NULL) || (dnlists == NULL)) return 0; - - if (user->dnlists != NULL) free(user->dnlists); - - user->dnlists = strdup(dnlists); - - return 1; -} - -/* * - * Functions to test for access perm of an individual * - * */ - -static char *recurse4file(char *dir, char *file, int recurse_level) -/* try to find file[] in dir[]. try subdirs if not found. - return full path to first found version or NULL on failure */ -{ - char *fullfilename, *fulldirname; - struct stat statbuf; - DIR *dirDIR; - struct dirent *file_ent; - - /* try to find in current directory */ - - asprintf(&fullfilename, "%s/%s", dir, file); - if (stat(fullfilename, &statbuf) == 0) return fullfilename; - free(fullfilename); - - /* maybe search in subdirectories */ - - if (recurse_level >= GRST_RECURS_LIMIT) return NULL; - - dirDIR = opendir(dir); - - if (dirDIR == NULL) return NULL; - - while ((file_ent = readdir(dirDIR)) != NULL) - { - if (file_ent->d_name[0] == '.') continue; - - asprintf(&fulldirname, "%s/%s", dir, file_ent->d_name); - - if ((stat(fulldirname, &statbuf) == 0) && - S_ISDIR(statbuf.st_mode) && - ((fullfilename = recurse4file(fulldirname, file, - recurse_level + 1)) != NULL)) - { - closedir(dirDIR); - return fullfilename; - } - - free(fulldirname); - } - - closedir(dirDIR); - - return NULL; -} - -int GRSTgaclDNlistHasUser(char *listurl, GRSTgaclUser *user) -{ - char *dn_lists_dirs, *dn_list_ptr, *enclisturl, *filename, *dirname, - line[512], *p; - FILE *fp; - GRSTgaclCred *cred; - - if ((listurl == NULL) || (user == NULL)) return 0; - - enclisturl = GRSThttpUrlEncode(listurl); - - if (user->dnlists != NULL) p = user->dnlists; - else p = getenv("GRST_DN_LISTS"); - - if (p == NULL) p = GRST_DN_LISTS; - dn_lists_dirs = strdup(p); /* we need to keep this for free() later! */ - dn_list_ptr = dn_lists_dirs; /* copy, for naughty function strsep() */ - - while ((dirname = strsep(&dn_list_ptr, ":")) != NULL) - { - filename = recurse4file(dirname, enclisturl, 0); - if (filename == NULL) continue; - - fp = fopen(filename, "r"); - free(filename); - - if (fp == NULL) continue; - - while (fgets(line, sizeof(line), fp) != NULL) - { - p = index(line, '\n'); - if (p != NULL) *p = '\0'; - - cred = user->firstcred; - - while (cred != NULL) - { - if ((strcmp(cred->type, "person") == 0) && - (cred->firstname != NULL) && - (strcmp("dn", (cred->firstname)->name) == 0) && - (GRSTx509NameCmp(line, (cred->firstname)->value) == 0)) - { - fclose(fp); - free(dn_lists_dirs); - free(enclisturl); - return 1; - } - - cred = cred->next; - } - } - - fclose(fp); - } - - free(dn_lists_dirs); - free(enclisturl); - - return 0; -} - -GRSTgaclPerm GRSTgaclAclTestUser(GRSTgaclAcl *acl, GRSTgaclUser *user) -/* - GACLgaclAclTestUser - return bit fields depending on access perms user has - for given acl. All zero for no access. If *user is - NULL, matching to "any-user" will still work. -*/ -{ - int flag, onlyanyuser; - GRSTgaclPerm allowperms = 0, denyperms = 0, allowed; - GRSTgaclEntry *entry; - GRSTgaclCred *cred, *usercred; - - if (acl == NULL) return 0; - - for (entry = acl->firstentry; entry != NULL; entry = entry->next) - { - flag = 1; /* begin by assuming this entry applies to us */ - onlyanyuser = 1; /* begin by assuming just */ - - /* now go through creds, checking they all do apply to us */ - - for (cred = entry->firstcred; cred != NULL; cred = cred->next) - if (!GRSTgaclUserHasCred(user, cred)) flag = 0; - else if (strcmp(cred->type, "any-user") != 0) onlyanyuser = 0; - - if (!flag) continue; /* flag false if a subtest failed */ - - /* does apply to us, so we remember this entry's perms */ - - /* we dont allow Write or Admin on the basis of any-user alone */ - - allowed = entry->allowed; - - if (onlyanyuser) - allowed = entry->allowed & ~GRST_PERM_WRITE & ~GRST_PERM_ADMIN; - else allowed = entry->allowed; - - allowperms = allowperms | allowed; - denyperms = denyperms | entry->denied; - } - - return (allowperms & (~ denyperms)); - /* for each perm type, any deny we saw kills any allow */ -} - -GRSTgaclPerm GRSTgaclAclTestexclUser(GRSTgaclAcl *acl, GRSTgaclUser *user) -/* - GRSTgaclAclTestexclUser - - return bit fields depending on ALLOW perms OTHER users - have for given acl. All zero if they have no access. - (used for testing if a user has exclusive access) -*/ -{ - int flag; - GRSTgaclPerm perm = 0; - GRSTgaclEntry *entry; - GRSTgaclCred *cred; - - if (acl == NULL) return 0; - - for (entry = acl->firstentry; entry != NULL; entry = entry->next) - { - flag = 0; /* flag will be set if cred implies other users */ - - for (cred = entry->firstcred; cred != NULL; cred = cred->next) - { - if (strcmp(cred->type, "person") != 0) - /* if we ever add support for other person-specific credentials, - they must also be recognised here */ - { - flag = 1; - break; - } - - if (!GRSTgaclUserHasCred(user, cred)) - /* if user doesnt have this person credential, assume - it refers to a different individual */ - { - flag = 1; - break; - } - } - - if (flag) perm = perm | entry->allowed; - } - - return perm; -} - -/* - Wrapper functions for gridsite-gacl.h support of legacy API -*/ - -GRSTgaclEntry *GACLparseEntry(xmlNodePtr cur) -{ - return GRSTgaclEntryParse(cur); -} diff --git a/org.gridsite.core/src/grst_http.c b/org.gridsite.core/src/grst_http.c deleted file mode 100644 index c7b375e..0000000 --- a/org.gridsite.core/src/grst_http.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - Copyright (c) 2002-3, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. -*/ - -#ifndef VERSION -#define VERSION "x.x.x" -#endif - -#define _GNU_SOURCE -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gridsite.h" - -void GRSThttpBodyInit(GRSThttpBody *thisbody) -{ - thisbody->size = 0; /* simple, but we don't expose internals to callers */ -} - -void GRSThttpPrintf(GRSThttpBody *thisbody, char *fmt, ...) -/* append printf() style format and arguments to *thisbody. - This requires vasprintf from glibc!! */ -{ - char *p; - size_t size; - va_list args; - - va_start(args, fmt); - size = vasprintf(&p, fmt, args); - va_end(args); - - if (size == 0) free(p); /* don't need to bother in this case */ - else if (size > 0) - { - if (thisbody->size == 0) /* need to initialise */ - { - thisbody->first = (GRSThttpCharsList *)malloc(sizeof(GRSThttpCharsList)); - thisbody->first->text = p; - thisbody->first->next = NULL; - - thisbody->last = thisbody->first; - thisbody->size = size; - } - else - { - thisbody->last->next = (GRSThttpCharsList *) - malloc(sizeof(GRSThttpCharsList)); - ((GRSThttpCharsList *) thisbody->last->next)->text = p; - ((GRSThttpCharsList *) thisbody->last->next)->next = NULL; - - thisbody->last = thisbody->last->next; - thisbody->size = thisbody->size + size; - } - } -} - -int GRSThttpCopy(GRSThttpBody *thisbody, char *file) -/* - copy a whole file, named file[], into the body output buffer, returning - 1 if file was found and copied ok, or 0 otherwise. -*/ -{ - int fd, len; - char c, *p; - struct stat statbuf; - - fd = open(file, O_RDONLY); - - if (fd == -1) return 0; - - if (fstat(fd, &statbuf) != 0) - { - close(fd); - return 0; - } - - p = malloc(statbuf.st_size + 1); - - if (p == NULL) - { - close(fd); - return 0; - } - - len = read(fd, p, statbuf.st_size); - p[len] = '\0'; - - close(fd); - - if (thisbody->size == 0) /* need to initialise */ - { - thisbody->first = (GRSThttpCharsList *) malloc(sizeof(GRSThttpCharsList)); - thisbody->first->text = p; - thisbody->first->next = NULL; - - thisbody->last = thisbody->first; - thisbody->size = len; - } - else - { - thisbody->last->next=(GRSThttpCharsList *)malloc(sizeof(GRSThttpCharsList)); - ((GRSThttpCharsList *) thisbody->last->next)->text = p; - ((GRSThttpCharsList *) thisbody->last->next)->next = NULL; - - thisbody->last = thisbody->last->next; - thisbody->size = thisbody->size + len; - } - - return 1; -} - -void GRSThttpWriteOut(GRSThttpBody *thisbody) -/* output Content-Length header, blank line then whole of the body to - standard output */ -{ - GRSThttpCharsList *p; - - printf("Content-Length: %d\n\n", thisbody->size); - - p = thisbody->first; - - while (p != NULL) - { - fputs(p->text, stdout); - - p = p->next; - } -} - -int GRSThttpPrintHeaderFooter(GRSThttpBody *bp, char *file, char *headfootname) -/* - try to print Header or Footer appropriate for absolute path file[], - returning 1 rather than 0 if found. -*/ -{ - int found = 0; - char *pathfile, *p; - struct stat statbuf; - - pathfile = malloc(strlen(file) + strlen(headfootname) + 2); - strcpy(pathfile, file); - - if ((pathfile[strlen(pathfile) - 1] != '/') && - (stat(pathfile, &statbuf) == 0) && - S_ISDIR(statbuf.st_mode)) strcat(pathfile, "/"); - - for (;;) - { - p = rindex(pathfile, '/'); - if (p == NULL) break; - p[1] = '\0'; - strcat(p, headfootname); - - if (stat(pathfile, &statbuf) == 0) - { - found = GRSThttpCopy(bp, pathfile); - break; - } - - p[0] = '\0'; - } - - free(pathfile); - return found; -} - -char *GRSThttpGetCGI(char *name) -/* - Return a malloc()ed copy of CGI form parameter identified by name[], - either received by QUERY_STRING (via GET) or on stdin (via POST). - Caller must free() the returned string itself. If name[] is not found, - an empty NUL-terminated malloc()ed string is returned. name[] has any - URL-encoding reversed. -*/ -{ - char *p, *namepattern, *valuestart, *returnvalue, *querystring; - int c, i, j, n, contentlength = 0; - static char *cgiposted = NULL; - size_t size_needed; - - if (cgiposted == NULL) /* have to initialise cgiposted */ - { - p = getenv("CONTENT_LENGTH"); - if (p != NULL) sscanf(p, "%d", &contentlength); - - querystring = getenv("REDIRECT_QUERY_STRING"); - if (querystring == NULL) querystring = getenv("QUERY_STRING"); - - if (querystring == NULL) cgiposted = malloc(contentlength + 3); - else cgiposted = malloc(contentlength + strlen(querystring) + 4); - - cgiposted[0] = '&'; - - for (i = 1; i <= contentlength; ++i) - { - c = getchar(); - if (c == EOF) break; - cgiposted[i] = c; - } - - cgiposted[i] = '&'; - cgiposted[i+1] = '\0'; - - if (querystring != NULL) - { - strcat(cgiposted, querystring); - strcat(cgiposted, "&"); - } - } - - namepattern = malloc(strlen(name) + 3); - sprintf(namepattern, "&%s=", name); - - p = strstr(cgiposted, namepattern); - free(namepattern); - if (p == NULL) return strdup(""); - - valuestart = &p[strlen(name) + 2]; - - for (n=0; valuestart[n] != '&'; ++n) ; - - returnvalue = malloc(n + 1); - - j=0; - - for (i=0; i < n; ++i) - { - if ((i < n - 2) && (valuestart[i] == '%')) /* url encoded as %HH */ - { - returnvalue[j] = 0; - - if (isdigit(valuestart[i+1])) - returnvalue[j] += 16 * (valuestart[i+1] - '0'); - else if (isalpha(valuestart[i+1])) - returnvalue[j] += 16 * (10 + tolower(valuestart[i+1]) - 'a'); - - if (isdigit(valuestart[i+2])) - returnvalue[j] += valuestart[i+2] - '0'; - else if (isalpha(valuestart[i+2])) - returnvalue[j] += 10 + tolower(valuestart[i+2]) - 'a'; - - i = i + 2; - } - else if (valuestart[i] == '+') returnvalue[j] = ' '; - else returnvalue[j] = valuestart[i]; - - if (returnvalue[j] == '\r') continue; /* CR/LF -> LF */ - ++j; - } - - returnvalue[j] = '\0'; - - return returnvalue; -} - -/* * - * Utility functions * - * */ - -char *GRSThttpUrlDecode(char *in) -{ - int i, j, n; - char *out; - - n = strlen(in); - out = malloc(n + 1); - - j=0; - - for (i=0; i < n; ++i) - { - if ((i < n - 2) && (in[i] == '%')) /* url encoded as %HH */ - { - out[j] = 0; - - if (isdigit(in[i+1])) - out[j] += 16 * (in[i+1] - '0'); - else if (isalpha(in[i+1])) - out[j] += 16 * (10 + tolower(in[i+1]) - 'a'); - - if (isdigit(in[i+2])) - out[j] += in[i+2] - '0'; - else if (isalpha(in[i+2])) - out[j] += 10 + tolower(in[i+2]) - 'a'; - - i = i + 2; - } - else if (in[i] == '+') out[j] = ' '; - else out[j] = in[i]; - - ++j; - } - - out[j] = '\0'; - - return out; -} - -char *GRSThttpUrlEncode(char *in) -/* Return a pointer to a malloc'd string holding a URL-encoded (RFC 1738) - version of *in. Only A-Z a-z 0-9 . _ - are passed through unmodified. - (DN's processed by GRSThttpUrlEncode can be used as valid Unix filenames, - assuming they do not exceed restrictions on filename length.) */ -{ - char *out, *p, *q; - - out = malloc(3*strlen(in) + 1); - - p = in; - q = out; - - while (*p != '\0') - { - if (isalnum(*p) || (*p == '.') || (*p == '_') || (*p == '-')) - { - *q = *p; - ++q; - } - else - { - sprintf(q, "%%%2X", *p); - q = &q[3]; - } - - ++p; - } - - *q = '\0'; - return out; -} - -char *GRSThttpUrlMildencode(char *in) -/* Return a pointer to a malloc'd string holding a partially URL-encoded - version of *in. "Partially" means that A-Z a-z 0-9 . = - _ @ and / - are passed through unmodified. (DN's processed by GRSThttpUrlMildencode() - can be used as valid Unix paths+filenames if you are prepared to - create or simulate the resulting /X=xyz directories.) */ -{ - char *out, *p, *q; - - out = malloc(3*strlen(in) + 1); - - p = in; - q = out; - - while (*p != '\0') - { - if (isalnum(*p) || (*p == '.') || (*p == '=') || (*p == '-') - || (*p == '/') || (*p == '@') || (*p == '_')) - { - *q = *p; - ++q; - } - else if (*p == ' ') - { - *q = '+'; - ++q; - } - else - { - sprintf(q, "%%%2X", *p); - q = &q[3]; - } - - ++p; - } - - *q = '\0'; - return out; -} diff --git a/org.gridsite.core/src/grst_x509.c b/org.gridsite.core/src/grst_x509.c deleted file mode 100644 index ec2b385..0000000 --- a/org.gridsite.core/src/grst_x509.c +++ /dev/null @@ -1,1491 +0,0 @@ -/* - Copyright (c) 2002-5, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. - - --------------------------------------------------------------- - For more information about GridSite: http://www.gridsite.org/ - --------------------------------------------------------------- -*/ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "gridsite.h" - -#define GRST_KEYSIZE 512 -#define GRST_PROXYCACHE "/../proxycache/" -#define GRST_MAX_CHAIN_LEN 9 - -/// Compare X509 Distinguished Name strings -int GRSTx509NameCmp(char *a, char *b) -/** - * This function attempts to do with string representations what - * would ideally be done with OIDs/values. In particular, we equate - * "/Email=" == "/emailAddress=" to deal with this important change - * between OpenSSL 0.9.6 and 0.9.7. - * Other than that, it is currently the same as ordinary strcmp(3). - */ -{ - int ret; - char *aa, *bb, *p; - - aa = strdup(a); - while ((p = strstr(aa, "/emailAddress=")) != NULL) - { - memmove(&p[6], &p[13], strlen(&p[13]) + 1); - p[1] = 'E'; - } - - bb = strdup(b); - while ((p = strstr(bb, "/emailAddress=")) != NULL) - { - memmove(&p[6], &p[13], strlen(&p[13]) + 1); - p[1] = 'E'; - } - - ret = strcmp(aa, bb); - - free(aa); - free(bb); - - return ret; -} - - -/// Check critical extensions -/** - * Returning GRST_RET_OK if all of extensions are known to us or - * OpenSSL; GRST_REF_FAILED otherwise. - * - * Since this function relies on functionality (X509_supported_extension) - * introduced in 0.9.7, then we do nothing and report an error - * (GRST_RET_FAILED) if one of the associated defines - * (X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION) is absent. - */ - -int GRSTx509KnownCriticalExts(X509 *cert) -{ - int i; - char s[80]; - X509_EXTENSION *ex; - -#ifdef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION - for (i = 0; i < X509_get_ext_count(cert); ++i) - { - ex = X509_get_ext(cert, i); - - if (X509_EXTENSION_get_critical(ex) && - !X509_supported_extension(ex)) - { - OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ex), 1); - - if (strcmp(s, GRST_PROXYCERTINFO_OID) != 0) return GRST_RET_FAILED; - } - } - - return GRST_RET_OK; -#else - return GRST_RET_FAILED; -#endif -} - -/// Check if certificate can be used as a CA to sign standard X509 certs -/* - * Return GRST_RET_OK if true; GRST_RET_FAILED if not. - */ - -int GRSTx509IsCA(X509 *cert) -{ - int idret, purpose_id; - - purpose_id = X509_PURPOSE_get_by_sname("sslclient"); - - /* final argument to X509_check_purpose() is whether to check for CAness */ - - if (X509_check_purpose(cert, purpose_id + X509_PURPOSE_MIN, 1)) - return GRST_RET_OK; - else return GRST_RET_FAILED; -} - -/// Check certificate chain for GSI proxy acceptability. -/** - * Returns X509_V_OK/GRST_RET_OK if valid; OpenSSL X509 errors otherwise. - * - * Inspired by GSIcheck written by Mike Jones, SVE, Manchester Computing, - * The University of Manchester. - * - * The GridSite version handles old and new style Globus proxies, and - * proxies derived from user certificates issued with "X509v3 Basic - * Constraints: CA:FALSE" (eg UK e-Science CA) - * - * We do not check chain links between certs here: this is done by - * GRST_check_issued/X509_check_issued in mod_ssl's ssl_engine_init.c - * - * TODO: we do not yet check ProxyCertInfo and ProxyCertPolicy extensions - * (although via GRSTx509KnownCriticalExts() we can accept them.) - */ - -int GRSTx509CheckChain(int *first_non_ca, X509_STORE_CTX *ctx) -{ - STACK_OF(X509) *certstack; /* Points to the client's cert chain */ - X509 *cert; /* Points to the client's cert */ - int depth; /* Depth of cert chain */ - size_t len,len2; /* Lengths of issuer and cert DN */ - int IsCA; /* Holds whether cert is allowed to sign */ - int prevIsCA; /* Holds whether previous cert in chain is - allowed to sign */ - int prevIsLimited; /* previous cert was proxy and limited */ - int i,j; /* Iteration variables */ - char *cert_DN; /* Pointer to current-certificate-in-chain's - DN */ - char *issuer_DN; /* Pointer to - issuer-of-current-cert-in-chain's DN */ - char *proxy_part_DN; /* Pointer to end part of current-cert-in-chain - maybe eg "/CN=proxy" */ - time_t now; - - time(&now); - - *first_non_ca = 0; /* set to something predictable if things fail */ - - /* Check for context */ - if (!ctx) return X509_V_ERR_INVALID_CA; - /* Can't GSI-verify if there is no context. Here and throughout this - function we report all errors as X509_V_ERR_INVALID_CA. */ - - /* Set necessary preliminary values */ - IsCA = TRUE; /* =prevIsCA - start from a CA */ - prevIsLimited = 0; - - /* Get the client cert chain */ - certstack = X509_STORE_CTX_get_chain(ctx); /* Get the client's chain */ - depth = sk_X509_num(certstack); /* How deep is that chain? */ - - /* Check the client chain */ - for (i=depth-1; i >= 0; --i) - /* loop through client-presented chain starting at CA end */ - { - prevIsCA=IsCA; - - /* Check for X509 certificate and point to it with 'cert' */ - if (cert = sk_X509_value(certstack, i)) - { - /* we check times and reject immediately if invalid */ - - if (now < - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(cert)),0)) - return X509_V_ERR_INVALID_CA; - - if (now > - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(cert)),0)) - return X509_V_ERR_INVALID_CA; - - /* If any forebear certificate is not allowed to sign we must - assume all decendents are proxies and cannot sign either */ - if (prevIsCA) - { - /* always treat the first cert (from the CA files) as a CA */ - if (i == depth-1) IsCA = TRUE; - /* check if this cert is valid CA for signing certs */ - else IsCA = (GRSTx509IsCA(cert) == GRST_RET_OK); - - if (!IsCA) *first_non_ca = i; - } - else - { - IsCA = FALSE; - /* Force proxy check next iteration. Important because I can - sign any CA I create! */ - } - - cert_DN = X509_NAME_oneline(X509_get_subject_name(cert),NULL,0); - issuer_DN = X509_NAME_oneline(X509_get_issuer_name(cert),NULL,0); - len = strlen(cert_DN); - len2 = strlen(issuer_DN); - - /* issuer didn't have CA status, so this is (at best) a proxy: - check for bad proxy extension*/ - - if (!prevIsCA) - { - if (prevIsLimited) /* we reject proxies of limited proxies! */ - return X509_V_ERR_INVALID_CA; - - /* User not allowed to sign shortened DN */ - if (len2 > len) return X509_V_ERR_INVALID_CA; - - /* Proxy subject must begin with issuer. */ - if (strncmp(cert_DN, issuer_DN, len2) != 0) - return X509_V_ERR_INVALID_CA; - - /* Set pointer to end of base DN in cert_DN */ - proxy_part_DN = &cert_DN[len2]; - - /* First attempt at support for Old and New style GSI - proxies: /CN=anything is ok for now */ - if (strncmp(proxy_part_DN, "/CN=", 4) != 0) - return X509_V_ERR_INVALID_CA; - - if ((strncmp(proxy_part_DN, "/CN=limited proxy", 17) == 0) && - (i > 0)) prevIsLimited = 1; /* ready for next cert ... */ - } - } - } - - /* Check cert whose private key is being used by client. If previous in - chain is not allowed to be a CA then need to check this final cert for - valid proxy-icity too */ - if (!prevIsCA) - { - if (prevIsLimited) return X509_V_ERR_INVALID_CA; - /* we do not accept proxies signed by limited proxies */ - - if (cert = sk_X509_value(certstack, 0)) - { - /* Load DN & length of DN and either its issuer or the - first-bad-issuer-in-chain */ - cert_DN = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); - issuer_DN = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); - len = strlen(cert_DN); - len2 = strlen(issuer_DN); - - /* issuer didn't have CA status, check for bad proxy extension */ - - if (len2 > len) return X509_V_ERR_INVALID_CA; - /* User not allowed to sign shortened DN */ - - if (strncmp(cert_DN, issuer_DN, len2) != 0) - return X509_V_ERR_INVALID_CA; - /* Proxy subject must begin with issuer. */ - - proxy_part_DN = &cert_DN[len2]; - /* Set pointer to end of DN base in cert_DN */ - - /* Remander of subject must be either "/CN=proxy" or - "/CN=limited proxy" (or /CN=XYZ for New style GSI) */ - - /* First attempt at support for Old and New style GSI - proxies: /CN=anything is ok for now. */ - if (strncmp(proxy_part_DN, "/CN=", 4) != 0) - return X509_V_ERR_INVALID_CA; - } - } - - return X509_V_OK; /* this is also GRST_RET_OK, of course - by choice */ -} - -/// Example VerifyCallback routine - -/** - * - */ - -int GRSTx509VerifyCallback (int ok, X509_STORE_CTX *ctx) -{ - int errnum = X509_STORE_CTX_get_error(ctx); - int errdepth = X509_STORE_CTX_get_error_depth(ctx); - int first_non_ca; - -#ifndef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION -#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 -#endif - - if (errnum == X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION) - { - if (GRSTx509KnownCriticalExts(X509_STORE_CTX_get_current_cert(ctx)) - == GRST_RET_OK) - { - ok = TRUE; - errnum = X509_V_OK; - X509_STORE_CTX_set_error(ctx, errnum); - } - } - else if ((errdepth == 0) && - (errnum == X509_V_OK) && - (GRSTx509CheckChain(&first_non_ca, ctx) != X509_V_OK)) ok = FALSE; - - - return ok; - -// check this - -// if (ok) return GRST_RET_OK; -// else return GRST_RET_FAILED; -} - -/// Check the signature of the VOMS attributes -/* - * Returns GRST_RET_OK if signature is ok, other values if not. - */ - -static int GRSTx509VerifyVomsSig(time_t *time1_time, time_t *time2_time, - unsigned char *asn1string, - struct GRSTasn1TagList taglist[], - int lasttag, - char *vomsdir) -{ -#define GRST_ASN1_COORDS_VOMS_DN "-1-1-1-1-3-1-1-1-%d-1-%d" -#define GRST_ASN1_COORDS_VOMS_INFO "-1-1-1-1" -#define GRST_ASN1_COORDS_VOMS_SIG "-1-1-1-3" - int ret, isig, iinfo; - char *certpath, acvomsdn[200]; - unsigned char *q; - DIR *vomsDIR; - struct dirent *vomsdirent; - X509 *cert; - EVP_PKEY *prvkey; - FILE *fp; - EVP_MD_CTX ctx; - time_t voms_service_time1, voms_service_time2; - - if ((vomsdir == NULL) || (vomsdir[0] == '\0')) return GRST_RET_FAILED; - - if (GRSTasn1GetX509Name(acvomsdn, sizeof(acvomsdn), - GRST_ASN1_COORDS_VOMS_DN, - asn1string, taglist, lasttag) != GRST_RET_OK) return GRST_RET_FAILED; - - iinfo = GRSTasn1SearchTaglist(taglist, lasttag, GRST_ASN1_COORDS_VOMS_INFO); - isig = GRSTasn1SearchTaglist(taglist, lasttag, GRST_ASN1_COORDS_VOMS_SIG); - - if ((iinfo < 0) || (isig < 0)) return GRST_RET_FAILED; - - vomsDIR = opendir(vomsdir); - if (vomsDIR == NULL) return GRST_RET_FAILED; - - while ((vomsdirent = readdir(vomsDIR)) != NULL) - { - asprintf(&certpath, "%s/%s", vomsdir, vomsdirent->d_name); - fp = fopen(certpath, "r"); - free(certpath); - if (fp == NULL) continue; - - cert = PEM_read_X509(fp, NULL, NULL, NULL); - fclose(fp); - if (cert == NULL) continue; - - if (GRSTx509NameCmp(acvomsdn, - X509_NAME_oneline(X509_get_subject_name(cert),NULL,0)) != 0) - { - X509_free(cert); - continue; - } - - prvkey = X509_extract_key(cert); - if (prvkey == NULL) - { - X509_free(cert); - continue; - } - - OpenSSL_add_all_digests(); -#if OPENSSL_VERSION_NUMBER >= 0x0090701fL - EVP_MD_CTX_init(&ctx); - EVP_VerifyInit_ex(&ctx, EVP_md5(), NULL); -#endif - - EVP_VerifyUpdate(&ctx, - &asn1string[taglist[iinfo].start+ - 0*taglist[iinfo].headerlength], - taglist[iinfo].length+taglist[iinfo].headerlength); - - ret = EVP_VerifyFinal(&ctx, - &asn1string[taglist[isig].start+ - taglist[isig].headerlength]+1, - taglist[isig].length - 1, - prvkey); - -#if OPENSSL_VERSION_NUMBER >= 0x0090701fL - EVP_MD_CTX_cleanup(&ctx); -#endif - EVP_PKEY_free(prvkey); - - if (ret != 1) /* signature doesnt match, look for more */ - { - continue; - X509_free(cert); - } - - voms_service_time1 = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(cert)),0); - if (voms_service_time1 > *time1_time) - *time1_time = voms_service_time1; - - voms_service_time2 = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(cert)),0); - if (voms_service_time2 < *time1_time) - *time2_time = voms_service_time2; - - X509_free(cert); - closedir(vomsDIR); - return GRST_RET_OK ; /* verified */ - } - - closedir(vomsDIR); - return GRST_RET_FAILED; -} - -/// Get the VOMS attributes in the given extension -/* - * Puts any VOMS credentials found into the Compact Creds string array - * starting at *creds. Always returns GRST_RET_OK. - */ - -int GRSTx509ParseVomsExt(int *lastcred, int maxcreds, size_t credlen, - char *creds, time_t time1_time, time_t time2_time, - X509_EXTENSION *ex, char *ucuserdn, char *vomsdir) -{ -#define MAXTAG 500 -#define GRST_ASN1_COORDS_FQAN "-1-1-1-1-7-1-2-1-2-%d" -#define GRST_ASN1_COORDS_USER_DN "-1-1-1-1-2-1-1-1-1-%d-1-%d" -#define GRST_ASN1_COORDS_TIME1 "-1-1-1-1-6-1" -#define GRST_ASN1_COORDS_TIME2 "-1-1-1-1-6-2" - ASN1_OCTET_STRING *asn1data; - char *asn1string, s[81], acuserdn[200], acvomsdn[200]; - long asn1length; - int lasttag=-1, itag, i; - struct GRSTasn1TagList taglist[MAXTAG+1]; - time_t actime1, actime2, time_now; - - asn1data = X509_EXTENSION_get_data(ex); - asn1string = ASN1_STRING_data(asn1data); - asn1length = ASN1_STRING_length(asn1data); - - GRSTasn1ParseDump(NULL, asn1string, asn1length, taglist, MAXTAG, &lasttag); - - GRSTasn1GetX509Name(acuserdn, sizeof(acuserdn), GRST_ASN1_COORDS_USER_DN, - asn1string, taglist, lasttag); - if (GRSTx509NameCmp(ucuserdn, acuserdn) != 0) return GRST_RET_FAILED; - - if (GRSTx509VerifyVomsSig(&time1_time, &time2_time, - asn1string, taglist, lasttag, vomsdir) - != GRST_RET_OK) return GRST_RET_FAILED; - - itag = GRSTasn1SearchTaglist(taglist, lasttag, GRST_ASN1_COORDS_TIME1); - actime1 = GRSTasn1TimeToTimeT(&asn1string[taglist[itag].start+ - taglist[itag].headerlength], - taglist[itag].length); - if (actime1 > time1_time) time1_time = actime1; - - itag = GRSTasn1SearchTaglist(taglist, lasttag, GRST_ASN1_COORDS_TIME2); - actime2 = GRSTasn1TimeToTimeT(&asn1string[taglist[itag].start+ - taglist[itag].headerlength], - taglist[itag].length); - if (actime2 < time2_time) time2_time = actime2; - - time(&time_now); - if ((time1_time > time_now) || (time2_time < time_now)) - return GRST_RET_OK; /* expiration isnt invalidity ...? */ - - for (i=1; ; ++i) - { - sprintf(s, GRST_ASN1_COORDS_FQAN, i); - itag = GRSTasn1SearchTaglist(taglist, lasttag, s); - - if (itag > -1) - { - if (*lastcred < maxcreds - 1) - { - ++(*lastcred); - - snprintf(&creds[*lastcred * (credlen + 1)], credlen+1, - "VOMS %010lu %010lu 0 %.*s", - time1_time, time2_time, - taglist[itag].length, - &asn1string[taglist[itag].start+ - taglist[itag].headerlength]); - } - } - else break; - } - - return GRST_RET_OK; -} - -/// Get the VOMS attributes in the extensions to the given cert stack -/* - * Puts any VOMS credentials found into the Compact Creds string array - * starting at *creds. Always returns GRST_RET_OK. - */ - -int GRSTx509GetVomsCreds(int *lastcred, int maxcreds, size_t credlen, - char *creds, X509 *usercert, STACK_OF(X509) *certstack, - char *vomsdir) -{ - int i, j, vomsfound=0; - char s[80]; - unsigned char *ucuser; - X509_EXTENSION *ex; - ASN1_STRING *asn1str; - X509 *cert; - time_t time1_time = 0, time2_time = 0, uctime1_time, uctime2_time; - - uctime1_time = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(usercert)),0); - uctime2_time = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(usercert)),0); - ucuser = - X509_NAME_oneline(X509_get_subject_name(usercert), NULL, 0); - - for (j=sk_X509_num(certstack)-1; j >= 0; --j) - { - cert = sk_X509_value(certstack, j); - - time1_time = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(cert)),0); - uctime1_time = (time1_time > uctime1_time) ? time1_time:uctime1_time; - - time2_time = - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(cert)),0); - uctime2_time = (time2_time < uctime2_time) ? time2_time:uctime2_time; - - for (i=0; i < X509_get_ext_count(cert); ++i) - { - ex = X509_get_ext(cert, i); - OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ex), 1); - - if (strcmp(s, GRST_VOMS_OID) == 0) /* a VOMS extension */ - { - vomsfound=1; - GRSTx509ParseVomsExt(lastcred, maxcreds, credlen, creds, - uctime1_time, uctime2_time, - ex, ucuser, vomsdir); - } - } - - if (vomsfound) return GRST_RET_OK; - } - - return GRST_RET_OK; -} - -/// Turn a Compact Cred line into a GRSTgaclCred object -/** - * Returns pointer to created GRSTgaclCred or NULL or failure. - */ - -GRSTgaclCred *GRSTx509CompactToCred(char *grst_cred) -{ - int delegation; - char *p; - time_t now, notbefore, notafter; - GRSTgaclCred *cred = NULL; - - time(&now); - - if (grst_cred == NULL) return NULL; /* just in case */ - - if (strncmp(grst_cred, "X509USER ", 9) == 0) - { - if ((sscanf(grst_cred, "X509USER %lu %lu %d", - ¬before, ¬after, &delegation) == 3) - && (now >= notbefore) - && (now <= notafter) - && (p = index(grst_cred, ' ')) - && (p = index(++p, ' ')) - && (p = index(++p, ' ')) - && (p = index(++p, ' '))) - { - cred = GRSTgaclCredNew("person"); - GRSTgaclCredSetDelegation(cred, delegation); - GRSTgaclCredAddValue(cred, "dn", &p[1]); - } - - return cred; - } - - if (strncmp(grst_cred, "VOMS ", 5) == 0) - { - if ((sscanf(grst_cred, "VOMS %lu %lu", - ¬before, ¬after, &delegation) == 3) - && (now >= notbefore) - && (now <= notafter) - && (p = index(grst_cred, ' ')) - && (p = index(++p, ' ')) - && (p = index(++p, ' ')) - && (p = index(++p, ' '))) - { - /* include /VO/group/subgroup/Role=role/Capability=cap */ - - if (*p != '/') return NULL; /* must begin with / */ - - cred = GRSTgaclCredNew("voms"); - GRSTgaclCredSetDelegation(cred, delegation); - GRSTgaclCredAddValue(cred, "fqan", p); - } - - return cred; - } - - return NULL; /* dont recognise this credential type */ -} - -/// Get the credentials in an X509 cert/GSI proxy, including any VOMS -/** - * Credentials are placed in Compact Creds string array at *creds. - * - * Function returns GRST_RET_OK on success, or GRST_RET_FAILED if - * some inconsistency found in certificate. - */ - -int GRSTx509CompactCreds(int *lastcred, int maxcreds, size_t credlen, - char *creds, STACK_OF(X509) *certstack, char *vomsdir) -{ - int i, j, delegation = 0; - char credtemp[credlen+1]; - X509 *cert, *usercert = NULL, *gsiproxycert = NULL; - - *lastcred = -1; - - for (i = sk_X509_num(certstack) - 1; i >= 0; --i) - { - cert = sk_X509_value(certstack, i); - - if (usercert != NULL) - { /* found a (GSI proxy) cert after the user cert */ - gsiproxycert = cert; - ++delegation; - } - - if ((usercert == NULL) && - (i < sk_X509_num(certstack) - 1) && - (GRSTx509IsCA(cert) != GRST_RET_OK)) usercert = cert; - /* found the 1st non-CA cert */ - } - - if ((usercert == NULL) /* if no usercert ("EEC"), we're not interested */ - || - (snprintf(credtemp, credlen+1, "X509USER %010lu %010lu %d %s", - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(usercert)),0), - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(usercert)),0), - delegation, - X509_NAME_oneline(X509_get_subject_name(usercert), NULL, 0)) >= credlen+1) - || - (*lastcred >= maxcreds-1)) - { - *lastcred = -1; /* just in case the caller looks at it */ - return GRST_RET_FAILED; /* tell caller that things didn't work out */ - } - - ++(*lastcred); - strcpy(&creds[*lastcred * (credlen + 1)], credtemp); - - if ((gsiproxycert != NULL) - && - (snprintf(credtemp, credlen+1, "GSIPROXY %010lu %010lu %d %s", - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(gsiproxycert)),0), - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(gsiproxycert)),0), - delegation, - X509_NAME_oneline(X509_get_subject_name(gsiproxycert), NULL, 0)) < credlen+1) - && - (*lastcred < maxcreds-1)) - { - ++(*lastcred); - strcpy(&creds[*lastcred * (credlen + 1)], credtemp); - - GRSTx509GetVomsCreds(lastcred, maxcreds, credlen, creds, - usercert, certstack, vomsdir); - - } - - return GRST_RET_OK; -} - -/// Find proxy file name of the current user -/** - * Return a string with the proxy file name or NULL if not present. - * This function does not check if the proxy has expired. - */ - -char *GRSTx509FindProxyFileName(void) -{ - char *p; - - p = getenv("X509_USER_PROXY"); - - if (p != NULL) return strdup(p); - - p = malloc(sizeof("/tmp/x509up_uXYYYXXXYYY")); - - sprintf(p, "/tmp/x509up_u%d", getuid()); - - return p; -} - -static void mpcerror(FILE *debugfp, char *msg) -{ - if (debugfp != NULL) - { - fputs(msg, debugfp); - ERR_print_errors_fp(debugfp); - } -} - -/// Make a GSI Proxy chain from a request, certificate and private key -/** - * The proxy chain is returned in *proxychain. If debugfp is non-NULL, - * errors are output to that file pointer. The proxy will expired in - * the given number of minutes starting from the current time. - */ - -int GRSTx509MakeProxyCert(char **proxychain, FILE *debugfp, - char *reqtxt, char *cert, char *key, int minutes) -{ - char *ptr, *certchain; - int i, subjAltName_pos, ncerts; - long serial = 2796, ptrlen; - EVP_PKEY *pkey, *CApkey; - const EVP_MD *digest; - X509 *certs[GRST_MAX_CHAIN_LEN]; - X509_REQ *req; - X509_NAME *name, *CAsubject, *newsubject; - X509_NAME_ENTRY *ent; - X509V3_CTX ctx; - X509_EXTENSION *subjAltName; - STACK_OF (X509_EXTENSION) * req_exts; - FILE *fp; - BIO *reqmem, *certmem; - - /* read in the request */ - reqmem = BIO_new(BIO_s_mem()); - BIO_puts(reqmem, reqtxt); - - if (!(req = PEM_read_bio_X509_REQ(reqmem, NULL, NULL, NULL))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error reading request from BIO memory\n"); - BIO_free(reqmem); - return GRST_RET_FAILED; - } - - BIO_free(reqmem); - - /* verify signature on the request */ - if (!(pkey = X509_REQ_get_pubkey (req))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error getting public key from request\n"); - return GRST_RET_FAILED; - } - - if (X509_REQ_verify(req, pkey) != 1) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error verifying signature on certificate\n"); - return GRST_RET_FAILED; - } - - /* read in the signing certificate */ - if (!(fp = fopen(cert, "r"))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error opening signing certificate file\n"); - return GRST_RET_FAILED; - } - - for (ncerts = 1; ncerts < GRST_MAX_CHAIN_LEN; ++ncerts) - if (!(certs[ncerts] = PEM_read_X509(fp, NULL, NULL, NULL))) break; - - if (ncerts == 1) /* zeroth cert with be new proxy cert */ - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error reading signing certificate file\n"); - return GRST_RET_FAILED; - } - - fclose(fp); - - CAsubject = X509_get_subject_name(certs[1]); - - /* read in the CA private key */ - if (!(fp = fopen(key, "r"))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error reading signing private key file\n"); - return GRST_RET_FAILED; - } - - if (!(CApkey = PEM_read_PrivateKey (fp, NULL, NULL, NULL))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error reading signing private key in file\n"); - return GRST_RET_FAILED; - } - - fclose(fp); - - /* get subject name */ - if (!(name = X509_REQ_get_subject_name (req))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error getting subject name from request\n"); - return GRST_RET_FAILED; - } - - /* create new certificate */ - if (!(certs[0] = X509_new ())) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error creating X509 object\n"); - return GRST_RET_FAILED; - } - - /* set version number for the certificate (X509v3) and the serial number - need 3 = v4 for GSI proxy?? */ - if (X509_set_version (certs[0], 3L) != 1) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error setting certificate version\n"); - return GRST_RET_FAILED; - } - - ASN1_INTEGER_set (X509_get_serialNumber (certs[0]), serial++); - - if (!(name = X509_get_subject_name(certs[1]))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error getting subject name from CA certificate\n"); - return GRST_RET_FAILED; - } - - if (X509_set_issuer_name (certs[0], name) != 1) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error setting issuer name of certificate\n"); - return GRST_RET_FAILED; - } - - /* set issuer and subject name of the cert from the req and the CA */ - ent = X509_NAME_ENTRY_create_by_NID(NULL, OBJ_txt2nid("commonName"), - MBSTRING_ASC, "proxy", -1); - - newsubject = X509_NAME_dup(CAsubject); - - X509_NAME_add_entry(newsubject, ent, -1, 0); - - if (X509_set_subject_name(certs[0], newsubject) != 1) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error setting subject name of certificate\n"); - return GRST_RET_FAILED; - } - - /* set public key in the certificate */ - if (X509_set_pubkey(certs[0], pkey) != 1) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error setting public key of the certificate\n"); - return GRST_RET_FAILED; - } - -// need to set validity within limits of earlier certificates in the chain - - /* set duration for the certificate */ - if (!(X509_gmtime_adj (X509_get_notBefore(certs[0]), 0))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error setting beginning time of the certificate\n"); - return GRST_RET_FAILED; - } - - if (!(X509_gmtime_adj (X509_get_notAfter(certs[0]), 60 * minutes))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error setting ending time of the certificate\n"); - return GRST_RET_FAILED; - } - - /* sign the certificate with the signing private key */ - if (EVP_PKEY_type (CApkey->type) == EVP_PKEY_RSA) - digest = EVP_md5(); - else - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error checking signing private key for a valid digest\n"); - return GRST_RET_FAILED; - } - - if (!(X509_sign (certs[0], CApkey, digest))) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error signing certificate\n"); - return GRST_RET_FAILED; - } - - /* store the completed certificate chain */ - - certchain = strdup(""); - - for (i=0; i < ncerts; ++i) - { - certmem = BIO_new(BIO_s_mem()); - - if (PEM_write_bio_X509(certmem, certs[i]) != 1) - { - mpcerror(debugfp, - "GRSTx509MakeProxyCert(): error writing certificate to memory BIO\n"); - return GRST_RET_FAILED; - } - - ptrlen = BIO_get_mem_data(certmem, &ptr); - - certchain = realloc(certchain, strlen(certchain) + ptrlen + 1); - - strncat(certchain, ptr, ptrlen); - - BIO_free(certmem); - } - - *proxychain = certchain; - - return GRST_RET_OK; -} - -/// Find a proxy file in the proxy cache -/** - * Returns the full path and file name of proxy file associated - * with given delegation ID and user DN. - */ - -char *GRSTx509CachedProxyFind(char *proxydir, char *delegation_id, - char *user_dn) -/* - Return a pointer to a malloc'd string with the full path of the - proxy file corresponding to the given delegation_id, or NULL - if not found. -*/ -{ - int ret, len; - char *filename = NULL, *line, *p, *proxyfile = NULL; - DIR *proxyDIR; - FILE *fp; - struct dirent *ent; - struct stat entstat; - - if ((proxyDIR = opendir(proxydir)) == NULL) return NULL; - - len = strlen(delegation_id); - if (strlen(user_dn) > len) len = strlen(user_dn); - - if ((line = malloc(len + 2)) == NULL) return NULL; - - while ((ent = readdir(proxyDIR)) != NULL) - { - if (ent->d_name[0] != '.') /* private keys begin with . */ - { - if (asprintf(&filename, "%s/%s", proxydir, ent->d_name) == -1) - break; - if ((stat(filename, &entstat) != 0) - || !S_ISREG(entstat.st_mode)) - { - free(filename); - continue; - } - - fp = fopen(filename, "r"); - if (fp != NULL) - { - if (fgets(line, len + 2, fp) != NULL) - { - p = index(line, '\n'); - - if (p != NULL) - { - *p = '\0'; - if (strcmp(line, delegation_id) == 0) - { - if (fgets(line, len + 2, fp) != NULL) - { - p = index(line, '\n'); - - if (p != NULL) - { - *p = '\0'; - - if (strcmp(line, user_dn) == 0) - { - proxyfile = filename; - fclose(fp); - break; - } - } - } - } - } - } - - fclose(fp); - } - - free(filename); - } - } - - closedir(proxyDIR); - free(line); - - return proxyfile; -} - -/// Find a temporary proxy private key file in the proxy cache -/** - * Returns the full path and file name of the private key file associated - * with given delegation ID and user DN. - */ - -char *GRSTx509CachedProxyKeyFind(char *proxydir, char *delegation_id, - char *user_dn) -/* - Return a pointer to a malloc'd string with the full path of the - private proxy key corresponding to the given delegation_id, or NULL - if not found. -*/ -{ - int ret, len; - char *filename = NULL, *line, *p, *keyfile = NULL; - DIR *proxyDIR; - FILE *fp; - struct dirent *ent; - struct stat entstat; - - if ((proxyDIR = opendir(proxydir)) == NULL) return NULL; - - len = strlen(delegation_id); - if (strlen(user_dn) > len) len = strlen(user_dn); - - if ((line = malloc(len + 2)) == NULL) return NULL; - - while ((ent = readdir(proxyDIR)) != NULL) - { - if (ent->d_name[0] == '.') /* private keys begin with . */ - { - if (asprintf(&filename, "%s/%s", proxydir, ent->d_name) == -1) - break; - if ((stat(filename, &entstat) != 0) - || !S_ISREG(entstat.st_mode)) - { - free(filename); - continue; - } - - fp = fopen(filename, "r"); - if (fp != NULL) - { - if (fgets(line, len + 2, fp) != NULL) - { - p = index(line, '\n'); - - if (p != NULL) - { - *p = '\0'; - if (strcmp(line, delegation_id) == 0) - { - if (fgets(line, len + 2, fp) != NULL) - { - p = index(line, '\n'); - - if (p != NULL) - { - *p = '\0'; - - if (strcmp(line, user_dn) == 0) - { - keyfile = filename; - fclose(fp); - break; - } - } - } - } - } - } - - fclose(fp); - } - - free(filename); - } - } - - closedir(proxyDIR); - free(line); - - return keyfile; -} - -/// Make and store a X.509 request for a GSI proxy -/** - * Returns GRST_RET_OK on success, non-zero otherwise. Request string - * is PEM encoded, and the key is stored in proxydir as temporary file - * with a filename like .XXXXXX - */ - -int GRSTx509MakeProxyRequest(char **reqtxt, char *proxydir, - char *delegation_id, char *user_dn) -{ - int i, fd; - char *docroot, *reqfile, *prvkeyfile, *ptr; - size_t ptrlen; - FILE *fp; - RSA *keypair; - X509_NAME *subject; - X509_NAME_ENTRY *ent; - EVP_PKEY *pkey; - X509_REQ *certreq; - BIO *reqmem; - const EVP_MD *digest; - struct stat statbuf; - - if ((keypair = RSA_generate_key(GRST_KEYSIZE, 65537, NULL, NULL)) == NULL) - return 1; - asprintf(&prvkeyfile, "%s/.XXXXXX", proxydir); - - fd = mkstemp(prvkeyfile); - - if ((fp = fdopen(fd, "w")) == NULL) return 1; - - fprintf(fp, "%s\n%s\n", delegation_id, user_dn); - - if (!PEM_write_RSAPrivateKey(fp, keypair, NULL, NULL, 0, NULL, NULL)) - return 1; - - if (fclose(fp) != 0) return 1; - - /* now create the certificate request */ - - certreq = X509_REQ_new(); - if (certreq == NULL) return 1; - - OpenSSL_add_all_algorithms(); - - pkey = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(pkey, keypair); - - X509_REQ_set_pubkey(certreq, pkey); - - subject = X509_NAME_new(); - ent = X509_NAME_ENTRY_create_by_NID(NULL, OBJ_txt2nid("organizationName"), - MBSTRING_ASC, "Dummy", -1); - X509_NAME_add_entry (subject, ent, -1, 0); - X509_REQ_set_subject_name (certreq, subject); - - digest = EVP_md5(); - X509_REQ_sign(certreq, pkey, digest); - - reqmem = BIO_new(BIO_s_mem()); - PEM_write_bio_X509_REQ(reqmem, certreq); - ptrlen = BIO_get_mem_data(reqmem, &ptr); - - *reqtxt = malloc(ptrlen + 1); - memcpy(*reqtxt, ptr, ptrlen); - (*reqtxt)[ptrlen] = '\0'; - - BIO_free(reqmem); - - X509_REQ_free(certreq); - - return 0; -} - -/// Create a stack of X509 certificate from a PEM-encoded string -/** - * Creates a dynamically allocated stack of X509 certificate objects - * by walking through the PEM-encoded X509 certificates. - * - * Returns GRST_RET_OK on success, non-zero otherwise. - * - */ - -int GRSTx509StringToChain(STACK_OF(X509) **certstack, char *certstring) -{ - STACK_OF(X509_INFO) *sk=NULL; - BIO *certbio; - X509_INFO *xi; - - *certstack = sk_X509_new_null(); - if (*certstack == NULL) return GRST_RET_FAILED; - - certbio = BIO_new_mem_buf(certstring, -1); - - if (!(sk=PEM_X509_INFO_read_bio(certbio, NULL, NULL, NULL))) - { - BIO_free(certbio); - sk_X509_INFO_free(sk); - sk_X509_free(*certstack); - return GRST_RET_FAILED; - } - - while (sk_X509_INFO_num(sk)) - { - xi=sk_X509_INFO_shift(sk); - if (xi->x509 != NULL) - { - sk_X509_push(*certstack, xi->x509); - xi->x509=NULL; - } - X509_INFO_free(xi); - } - - if (!sk_X509_num(*certstack)) - { - BIO_free(certbio); - sk_X509_INFO_free(sk); - sk_X509_free(*certstack); - return GRST_RET_FAILED; - } - - BIO_free(certbio); - sk_X509_INFO_free(sk); - - return GRST_RET_OK; -} - -/// Return the short file name for the given delegation_id and user_dn -/** - * Returns a malloc'd string with the short file name (no paths) that - * derived from the hashed delegation_id and user_dn - * - * File name is SHA1_HASH(DelegationID)+"-"+SHA1_HASH(DN) where DN - * is DER encoded version of user_dn with any trailing CN=proxy removed - * Hashes are the most significant 8 bytes, in lowercase hexadecimal. - */ - -char *GRSTx509MakeProxyFileName(char *delegation_id, - STACK_OF(X509) *certstack) -{ - int i, depth, prevIsCA = 1, IsCA, hash_name_len, delegation_id_len, - der_name_len; - unsigned char *der_name, *buf, hash_name[EVP_MAX_MD_SIZE], - hash_delegation_id[EVP_MAX_MD_SIZE], - filename[34]; - X509_NAME *subject_name; - X509 *cert; - const EVP_MD *m; - EVP_MD_CTX ctx; - - depth = sk_X509_num(certstack); - - for (i=depth-1; i >= 0; --i) - /* loop through the proxy chain starting at CA end */ - { - if (cert = sk_X509_value(certstack, i)) - { - IsCA = (GRSTx509IsCA(cert) == GRST_RET_OK); - - if (prevIsCA && !IsCA) /* the full certificate of the user */ - { - break; - } - } - } - - if (i < 0) return NULL; /* not found: something wrong with the chain */ - - if ((subject_name = X509_get_subject_name(cert)) == NULL) return NULL; - - der_name_len = i2d_X509_NAME(X509_get_subject_name(cert), NULL); - if (der_name_len == 0) return NULL; - - buf = OPENSSL_malloc(der_name_len); - der_name = buf; - - - if (!i2d_X509_NAME(X509_get_subject_name(cert), &der_name)) - { - OPENSSL_free(der_name); - return NULL; - } - - OpenSSL_add_all_digests(); - - m = EVP_sha1(); - if (m == NULL) - { - OPENSSL_free(der_name); - return NULL; - } - - - EVP_DigestInit(&ctx, m); - EVP_DigestUpdate(&ctx, delegation_id, strlen(delegation_id)); - EVP_DigestFinal(&ctx, hash_delegation_id, &delegation_id_len); - - /* lots of nasty hard coded numbers: - "8bytes/16chars delegation ID" + "-" + "8bytes/16chars DN" */ - - for (i=0; i <=7; ++i) - sprintf(&filename[i*2], "%02x", hash_delegation_id[i]); - - filename[16] = '-'; - - - - EVP_DigestInit(&ctx, m); - EVP_DigestUpdate(&ctx, buf, der_name_len); - EVP_DigestFinal(&ctx, hash_name, &hash_name_len); - - for (i=0; i <=7; ++i) - sprintf(&filename[17 + i*2], "%02x", hash_name[i]); - - return strdup(filename); -} - -/// Store a GSI proxy chain in the proxy cache, along with the private key -/** - * Returns GRST_RET_OK on success, non-zero otherwise. The existing - * private key with the same delegation ID and user DN is appended to - * make a valid proxy file, and the temporary private key file deleted. - */ - -int GRSTx509CacheProxy(char *proxydir, char *delegation_id, - char *user_dn, char *proxychain) -{ - int c, len = 0, i; - char *upcertfile, *upcertpath, *prvkeyfile, *p, *ptr; - FILE *ifp, *ofp; - STACK_OF(X509) *certstack; - BIO *certmem; - X509 *cert; - long ptrlen; - - prvkeyfile = GRSTx509CachedProxyKeyFind(proxydir, delegation_id, user_dn); - - if (prvkeyfile == NULL) - { - return GRST_RET_FAILED; - } - - if ((ifp = fopen(prvkeyfile, "r")) == NULL) - { - free(prvkeyfile); - return GRST_RET_FAILED; - } - - fprintf(stderr, "\n\n\n\n PROXYCHAIN = \n %s", proxychain); - if (GRSTx509StringToChain(&certstack, proxychain) != GRST_RET_OK) - return GRST_RET_FAILED; - - upcertfile = GRSTx509MakeProxyFileName(delegation_id, certstack); - - if (upcertfile == NULL) - { - free(prvkeyfile); - sk_X509_free(certstack); - return GRST_RET_FAILED; - } - - asprintf(&upcertpath, "%s/%s", proxydir, upcertfile); - ofp = fopen(upcertpath, "w"); - chmod(upcertpath, S_IRUSR | S_IWUSR); - free(upcertpath); - - if (ofp == NULL) - { - fclose(ifp); - free(prvkeyfile); - free(upcertfile); - return GRST_RET_FAILED; - } - - fprintf(ofp, "%s\n%s\n", delegation_id, user_dn); - - /* write out the most recent proxy by itself */ - - if (cert = sk_X509_value(certstack, 0)) - { - certmem = BIO_new(BIO_s_mem()); - if (PEM_write_bio_X509(certmem, cert) == 1) - { - ptrlen = BIO_get_mem_data(certmem, &ptr); - fwrite(ptr, 1, ptrlen, ofp); - } - - BIO_free(certmem); - } - - /* insert proxy private key */ - - while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); - unlink(prvkeyfile); - free(prvkeyfile); - - for (i=1; i <= sk_X509_num(certstack) - 1; ++i) - /* loop through the proxy chain starting at 2nd most recent proxy */ - { - if (cert = sk_X509_value(certstack, i)) - { - certmem = BIO_new(BIO_s_mem()); - if (PEM_write_bio_X509(certmem, cert) == 1) - { - ptrlen = BIO_get_mem_data(certmem, &ptr); - fwrite(ptr, 1, ptrlen, ofp); - } - - BIO_free(certmem); - } - } - - fputs(proxychain, ofp); /* write out certificates */ - - - sk_X509_free(certstack); - free(upcertfile); - - if (fclose(ifp) != 0) return GRST_RET_FAILED; - if (fclose(ofp) != 0) return GRST_RET_FAILED; - -/* should also check validity of proxy cert to avoid suprises? */ - - return GRST_RET_OK; -} diff --git a/org.gridsite.core/src/htcp b/org.gridsite.core/src/htcp deleted file mode 100644 index 01c4eff34861e06f0fc4fd72de72621021b7f099..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29747 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 D%m$PH diff --git a/org.gridsite.core/src/htcp.c b/org.gridsite.core/src/htcp.c deleted file mode 100644 index 3275806..0000000 --- a/org.gridsite.core/src/htcp.c +++ /dev/null @@ -1,1237 +0,0 @@ -/* - Copyright (c) 2002-4, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. -*/ - -/*---------------------------------------------------------------* - * For more about GridSite: http://www.gridsite.org/ * - *---------------------------------------------------------------*/ - -#ifndef VERSION -#define VERSION "0.0.0" -#endif - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* deal with older versions of libcurl and curl.h */ - -#ifndef CURLOPT_WRITEDATA -#define CURLOPT_WRITEDATA CURLOPT_FILE -#endif - -#ifndef CURLOPT_READDATA -#define CURLOPT_READDATA CURLOPT_FILE -#endif - -#ifndef CURLE_HTTP_RETURNED_ERROR -#define CURLE_HTTP_RETURNED_ERROR CURLE_HTTP_NOT_FOUND -#endif - -#define HTCP_GET 1 -#define HTCP_PUT 2 -#define HTCP_DELETE 3 -#define HTCP_LIST 4 -#define HTCP_LONGLIST 5 -#define HTCP_MKDIR 6 - -struct grst_stream_data { char *source; - char *destination; - int ishttps; - int method; - FILE *fp; - char *cert; - char *key; - char *capath; - char *useragent; - char *errorbuf; - int noverify; - int anonymous; - long long downgrade; - int verbose; } ; - -struct grst_index_blob { char *text; - size_t used; - size_t allocated; } ; - -struct grst_dir_list { char *filename; - size_t length; - int length_set; - time_t modified; - int modified_set; } ; - -struct grst_header_data { int retcode; - char *location; - char *gridauthonetime; - size_t length; - int length_set; - time_t modified; - int modified_set; - struct grst_stream_data *common_data; } ; - -size_t headers_callback(void *ptr, size_t size, size_t nmemb, void *p) -/* Find the values of the return code, Content-Length, Last-Modified - and Location headers */ -{ - float f; - char *s, *q; - size_t realsize; - struct tm modified_tm; - struct grst_header_data *header_data; - - header_data = (struct grst_header_data *) p; - realsize = size * nmemb; - s = malloc(realsize + 1); - memcpy(s, ptr, realsize); - s[realsize] = '\0'; - - if (sscanf(s, "Content-Length: %d", &(header_data->length)) == 1) - header_data->length_set = 1; - else if (sscanf(s, "HTTP/%f %d ", &f, &(header_data->retcode)) == 2) ; - else if (strncmp(s, "Location: ", 10) == 0) - { - header_data->location = strdup(&s[10]); - - if (header_data->common_data->verbose > 0) - fprintf(stderr, "Received Location: %s\n", header_data->location); - } - else if (strncmp(s, "Set-Cookie: GRID_AUTH_ONETIME=", 30) == 0) - { - header_data->gridauthonetime = strdup(&s[12]); - q = index(header_data->gridauthonetime, ';'); - if (q != NULL) *q = '\0'; - - if (header_data->common_data->verbose > 0) - fprintf(stderr, "Received Grid Auth Cookie: %s\n", - header_data->gridauthonetime); - } - else if (strncmp(s, "Last-Modified: ", 15) == 0) - { - /* follow RFC 2616: first try RFC 822 (kosher), then RFC 850 and - asctime() formats too. Must be GMT whatever the format. */ - - if (strptime(&s[15], "%a, %d %b %Y %T GMT", &modified_tm) != NULL) - { - header_data->modified = mktime(&modified_tm); - header_data->modified_set = 1; - } - else if (strptime(&s[15], "%a, %d-%b-%y %T GMT", &modified_tm) != NULL) - { - header_data->modified = mktime(&modified_tm); - header_data->modified_set = 1; - } - else if (strptime(&s[15], "%a %b %d %T %Y", &modified_tm) != NULL) - { - header_data->modified = mktime(&modified_tm); - header_data->modified_set = 1; - } - } - - free(s); - return realsize; -} - -int set_std_opts(CURL *easyhandle, struct grst_stream_data *common_data) -{ - struct stat statbuf; - - curl_easy_setopt(easyhandle, CURLOPT_FOLLOWLOCATION, 0); - - if ((common_data->cert != NULL) && (common_data->key != NULL)) - { - curl_easy_setopt(easyhandle, CURLOPT_SSLENGINE, NULL); - curl_easy_setopt(easyhandle, CURLOPT_SSLCERTTYPE, "PEM"); - curl_easy_setopt(easyhandle, CURLOPT_SSLCERT, common_data->cert); - curl_easy_setopt(easyhandle, CURLOPT_SSLKEY, common_data->key); - } - else - { - curl_easy_setopt(easyhandle, CURLOPT_SSLENGINE, "RSA"); - curl_easy_setopt(easyhandle, CURLOPT_SSLCERTTYPE, "ENG"); - } - - if (common_data->capath != NULL) - { -#if (LIBCURL_VERSION_NUM >= 0x070908) - if ((stat(common_data->capath, &statbuf) == 0) && - S_ISDIR(statbuf.st_mode)) - curl_easy_setopt(easyhandle, CURLOPT_CAPATH, common_data->capath); - else -#endif - curl_easy_setopt(easyhandle, CURLOPT_CAINFO, common_data->capath); - } - - if (common_data->noverify) - curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYHOST, 0); - else curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYHOST, 2); - - return 1; -} - -int do_copies(char *sources[], char *destination, - struct grst_stream_data *common_data) -{ - char *p, *thisdestination; - int isrc, anyerror = 0, thiserror, isdirdest; - CURL *easyhandle; - struct stat statbuf; - struct grst_header_data header_data; - struct curl_slist *dgheader_slist = NULL, *nodgheader_slist = NULL; - - easyhandle = curl_easy_init(); - - if (common_data->downgrade >= (long long) 0) - { - asprintf(&p, "HTTP-Downgrade-Size: %lld", common_data->downgrade); - dgheader_slist = curl_slist_append(dgheader_slist, p); - free(p); - - nodgheader_slist = curl_slist_append(nodgheader_slist, - "HTTP-Downgrade-Size:"); - } - - curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); - if (common_data->verbose > 1) - curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1); - - curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, headers_callback); - curl_easy_setopt(easyhandle, CURLOPT_WRITEHEADER, &header_data); - - set_std_opts(easyhandle, common_data); - - curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, common_data->errorbuf); - - if (destination[strlen(destination) - 1] != '/') - { - isdirdest = 0; - thisdestination = destination; - } - else isdirdest = 1; - - for (isrc=0; sources[isrc] != NULL; ++isrc) - { - if (isdirdest) - { - p = rindex(sources[isrc], '/'); - if (p == NULL) p = sources[isrc]; - else p++; - - asprintf(&thisdestination, "%s%s", destination, p); - } - - if (common_data->verbose > 0) - fprintf(stderr, "%s -> %s\n", sources[isrc], thisdestination); - - if (common_data->method == HTCP_GET) - { - common_data->fp = fopen(thisdestination, "w"); - if (common_data->fp == NULL) - { - fprintf(stderr,"... failed to open destination source file %s\n", - thisdestination); - anyerror = 99; - if (isdirdest) free(thisdestination); - continue; - } - - curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, common_data->fp); - curl_easy_setopt(easyhandle, CURLOPT_URL, sources[isrc]); - - if ((common_data->downgrade >= (long long) 0) && - (strncmp(sources[isrc], "https://", 8) == 0)) - { - if (common_data->verbose > 0) - fprintf(stderr, "Add HTTP-Downgrade-Size: %lld header\n", - common_data->downgrade); - - curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,dgheader_slist); - } - else - curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,nodgheader_slist); - } - else if (common_data->method == HTCP_PUT) - { - if (stat(sources[isrc], &statbuf) != 0) - { - fprintf(stderr, "... source file %s not found\n", sources[isrc]); - anyerror = 99; - if (isdirdest) free(thisdestination); - continue; - } - - common_data->fp = fopen(sources[isrc], "r"); - if (common_data->fp == NULL) - { - fprintf(stderr, "... failed to open source file %s\n", - sources[isrc]); - anyerror = 99; - if (isdirdest) free(thisdestination); - continue; - } - - curl_easy_setopt(easyhandle, CURLOPT_READDATA, common_data->fp); - curl_easy_setopt(easyhandle, CURLOPT_URL, thisdestination); - curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE, statbuf.st_size); - curl_easy_setopt(easyhandle, CURLOPT_UPLOAD, 1); - - if (((long long) statbuf.st_size >= common_data->downgrade) && - (strncmp(thisdestination, "https://", 8) == 0)) - curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,dgheader_slist); - else - curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,nodgheader_slist); - } - - header_data.retcode = 0; - header_data.location = NULL; - header_data.gridauthonetime = NULL; - header_data.common_data = common_data; - thiserror = curl_easy_perform(easyhandle); - - fclose(common_data->fp); - - if ((common_data->downgrade >= (long long) 0) && - (thiserror == 0) && - (header_data.retcode == 302) && - (header_data.location != NULL) && - (strncmp(header_data.location, "http://", 7) == 0) && - (header_data.gridauthonetime != NULL)) - { - if (common_data->verbose > 0) - fprintf(stderr, "... Found (%d)\nHTTP-Downgrade to %s\n", - header_data.retcode, header_data.location); - - /* try again with new URL and all the previous CURL options */ - - if (common_data->method == HTCP_GET) - { - common_data->fp = fopen(thisdestination, "w"); - if (common_data->fp == NULL) - { - fprintf(stderr, "... failed to open destination source " - "file %s\n", thisdestination); - anyerror = 99; - if (isdirdest) free(thisdestination); - continue; - } - } - else if (common_data->method == HTCP_PUT) - { - common_data->fp = fopen(sources[isrc], "r"); - if (common_data->fp == NULL) - { - fprintf(stderr, "... failed to open source file %s\n", - sources[isrc]); - anyerror = 99; - if (isdirdest) free(thisdestination); - continue; - } - } - - header_data.retcode = 0; - curl_easy_setopt(easyhandle, CURLOPT_URL, header_data.location); - curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, nodgheader_slist); - curl_easy_setopt(easyhandle, CURLOPT_COOKIE, - header_data.gridauthonetime); - thiserror = curl_easy_perform(easyhandle); - - fclose(common_data->fp); - } - - if ((thiserror != 0) || - (header_data.retcode < 200) || - (header_data.retcode >= 300)) - { - fprintf(stderr, "... curl error: %s (%d), HTTP error: %d\n", - common_data->errorbuf, thiserror, header_data.retcode); - - if (thiserror != 0) anyerror = thiserror; - else anyerror = header_data.retcode; - } - else if (common_data->verbose > 0) - fprintf(stderr, "... OK (%d)\n", header_data.retcode); - - if (isdirdest) free(thisdestination); - } - - curl_easy_cleanup(easyhandle); - - return anyerror; -} - -int do_deletes(char *sources[], struct grst_stream_data *common_data) -{ - int isrc, anyerror = 0, thiserror; - CURL *easyhandle; - struct grst_header_data header_data; - - header_data.common_data = common_data; - - easyhandle = curl_easy_init(); - - curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); - if (common_data->verbose > 1) - curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1); - - curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, headers_callback); - curl_easy_setopt(easyhandle, CURLOPT_WRITEHEADER, &header_data); - - curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, common_data->errorbuf); - curl_easy_setopt(easyhandle, CURLOPT_CUSTOMREQUEST, "DELETE"); - curl_easy_setopt(easyhandle, CURLOPT_NOBODY, 1); - - set_std_opts(easyhandle, common_data); - - for (isrc=0; sources[isrc] != NULL; ++isrc) - { - if (common_data->verbose > 0) - fprintf(stderr, "Deleting %s\n", sources[isrc]); - - curl_easy_setopt(easyhandle, CURLOPT_URL, sources[isrc]); - - header_data.retcode = 0; - thiserror = curl_easy_perform(easyhandle); - - if ((thiserror != 0) || - (header_data.retcode < 200) || - (header_data.retcode >= 300)) - { - fprintf(stderr, "... curl error: %s (%d), HTTP error: %d\n", - common_data->errorbuf, thiserror, header_data.retcode); - - if (thiserror != 0) anyerror = thiserror; - else anyerror = header_data.retcode; - } - else if (common_data->verbose > 0) - fprintf(stderr, "... OK (%d)\n", header_data.retcode); - } - - curl_easy_cleanup(easyhandle); - - return anyerror; -} - -int do_mkdirs(char *sources[], struct grst_stream_data *common_data) -{ - int isrc, anyerror = 0, thiserror; - CURL *easyhandle; - struct grst_header_data header_data; - - header_data.common_data = common_data; - - easyhandle = curl_easy_init(); - - curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); - if (common_data->verbose > 1) - curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1); - - curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, headers_callback); - curl_easy_setopt(easyhandle, CURLOPT_WRITEHEADER, &header_data); - - curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, common_data->errorbuf); - curl_easy_setopt(easyhandle, CURLOPT_CUSTOMREQUEST, "PUT"); - curl_easy_setopt(easyhandle, CURLOPT_NOBODY, 1); - - set_std_opts(easyhandle, common_data); - - for (isrc=0; sources[isrc] != NULL; ++isrc) - { - if (common_data->verbose > 0) - fprintf(stderr, "Make directory %s\n", sources[isrc]); - - curl_easy_setopt(easyhandle, CURLOPT_URL, sources[isrc]); - - header_data.retcode = 0; - thiserror = curl_easy_perform(easyhandle); - - if ((thiserror != 0) || - (header_data.retcode < 200) || - (header_data.retcode >= 300)) - { - fprintf(stderr, "... curl error: %s (%d), HTTP error: %d\n", - common_data->errorbuf, thiserror, header_data.retcode); - - if (thiserror != 0) anyerror = thiserror; - else anyerror = header_data.retcode; - } - else if (common_data->verbose > 0) - fprintf(stderr, "... OK (%d)\n", header_data.retcode); - } - - curl_easy_cleanup(easyhandle); - - return anyerror; -} - -size_t rawindex_callback(void *ptr, size_t size, size_t nmemb, void *data) -{ - if ( ((struct grst_index_blob *) data)->used + size * nmemb >= - ((struct grst_index_blob *) data)->allocated ) - { - ((struct grst_index_blob *) data)->allocated = - ((struct grst_index_blob *) data)->used + size * nmemb + 4096; - - ((struct grst_index_blob *) data)->text = - realloc( ((struct grst_index_blob *) data)->text, - ((struct grst_index_blob *) data)->allocated ); - } - - memcpy( &( ((struct grst_index_blob *) - data)->text[((struct grst_index_blob *) data)->used] ), - ptr, size * nmemb); - - ((struct grst_index_blob *) data)->used += size * nmemb; - - return size * nmemb; -} - -char *canonicalise(char *link, char *source) -{ - int i, j, srclen; - char *s; - - srclen = strlen(source); - - if ((strncmp(link, "https://", 8) == 0) || - (strncmp(link, "http://", 7) == 0)) - { - if (strncmp(link, source, srclen) != 0) return NULL; /* other site */ - - if (link[srclen] == '\0') return NULL; /* we dont self-link! */ - - for (i=0; link[srclen + i] != '\0'; ++i) - if (link[srclen + i] == '/') - { - if (link[srclen + i + 1] != '\0') return NULL; /* no subdirs */ - else return strdup(&link[srclen]); /* resolves to this dir */ - } - } - else if (link[0] != '/') /* relative link - need to check for subsubdirs */ - { - for (i=0; link[i] != '\0'; ++i) - if ((link[i] == '/') && (link[i+1] != '\0')) return NULL; - - s = strdup(link); - - for (i=0; s[i] != '\0'; ++i) - if (s[i] == '#') - { - s[i] = '\0'; - break; - } - - return s; - } - - /* absolute link on this server, starting / */ - - for (i=8; source[i] != '\0'; ++i) if (source[i] == '/') break; - - if (strncmp(link, &source[i], srclen - i) != 0) return NULL; - - for (j = srclen - i; link[j] != '\0'; ++j) - if ((link[j] == '/') && (link[j+1] != '\0')) return NULL; - - s = strdup(&link[srclen - i]); - - for (i=0; s[i] != '\0'; ++i) - if (s[i] == '#') - { - s[i] = '\0'; - break; - } - - if (s[0] == '\0') /* on second thoughts... */ - { - free(s); - return NULL; - } - - return s; -} - -int grst_dir_list_cmp(const void *a, const void *b) -{ - return strcmp( ((struct grst_dir_list *) a)->filename, - ((struct grst_dir_list *) b)->filename); -} - -struct grst_dir_list *index_to_dir_list(char *text, char *source) -{ - int taglevel = 0, wordnew = 1, i, namestart, used = 0, - allocated = 256; - char *p, *s; - struct grst_dir_list *list; - - list = (struct grst_dir_list *) - malloc(allocated * sizeof(struct grst_dir_list)); - - list[0].filename = NULL; - list[0].length = 0; - list[0].length_set = 0; - list[0].modified = 0; - list[0].modified_set = 0; - - for (p=text; *p != '\0'; ++p) - { - if (*p == '<') - { - ++taglevel; - - if ((taglevel == 1) && (list[used].filename != NULL)) - { - ++used; - if (used >= allocated) - { - allocated += 256; - list = (struct grst_dir_list *) - realloc((void *) list, - allocated * sizeof(struct grst_dir_list)); - } - - list[used].filename = NULL; - list[used].length = 0; - list[used].length_set = 0; - list[used].modified = 0; - list[used].modified_set = 0; - } - - wordnew = 1; - continue; - } - - if (*p == '>') - { - --taglevel; - wordnew = 1; - continue; - } - - if (isspace(*p)) - { - wordnew = 1; - continue; - } - - if ((wordnew) && (taglevel == 1)) - { - if (((*p == 'h') || (*p == 'H')) && - (strncasecmp(p, "href=", 5) == 0)) - { - if (p[5] == '"') { namestart = 6; - for (i=namestart; (p[i] != '\0') && - (p[i] != '"' ) && - (p[i] != '\n') && - (p[i] != '\t') && - (p[i] != '>' ) ; ++i) ; } - else { namestart = 5; - for (i=namestart; (p[i] != '\0') && - (p[i] != '"' ) && - (p[i] != ' ' ) && - (p[i] != '\n') && - (p[i] != '\t') && - (p[i] != ')' ) && - (p[i] != '>' ) ; ++i) ; } - if (i > namestart) - { - s = malloc(1 + i - namestart); - memcpy(s, &p[namestart], i - namestart); - s[i - namestart] = '\0'; - - list[used].filename = canonicalise(s, source); - free(s); - } - - p = &p[i-1]; /* -1 since continue results in ++i */ - continue; - } - - if (((*p == 'c') || (*p == 'C')) && - (strncasecmp(p, "content-length=", 15) == 0)) - { - list[used].length = 0; - list[used].length_set = 1; - - if (p[15] == '"') list[used].length = atoi(&p[16]); - else list[used].length = atoi(&p[15]); - - p = &p[15]; - continue; - } - - if (((*p == 'l') || (*p == 'L')) && - (strncasecmp(p, "last-modified=", 14) == 0)) - { - list[used].modified = 0; - list[used].modified_set = 1; - - if (p[14] == '"') list[used].modified = atoi(&p[15]); - else list[used].modified = atoi(&p[14]); - - p = &p[14]; - continue; - } - } - - wordnew = 0; - } - - qsort((void *) list, used, sizeof(struct grst_dir_list), grst_dir_list_cmp); - - return list; -} - -int do_listings(char *sources[], struct grst_stream_data *common_data, - int islonglist) -{ - int isrc, anyerror = 0, thiserror, i, isdir, ilast; - CURL *easyhandle; - const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - char *s; - struct grst_index_blob rawindex; - struct grst_dir_list *list; - struct grst_header_data header_data; - struct tm modified_tm; - time_t now; - - time(&now); - - header_data.common_data = common_data; - - easyhandle = curl_easy_init(); - - curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); - if (common_data->verbose > 1) - curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1); - - curl_easy_setopt(easyhandle, CURLOPT_WRITEHEADER, &header_data); - curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, headers_callback); - - curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, common_data->errorbuf); - - set_std_opts(easyhandle, common_data); - - for (isrc=0; sources[isrc] != NULL; ++isrc) - { - if (common_data->verbose > 0) - fprintf(stderr, "Listing %s\n", sources[isrc]); - - if (sources[1] != NULL) printf("\n%s:\n", sources[isrc]); - - curl_easy_setopt(easyhandle, CURLOPT_URL, sources[isrc]); - - if (sources[isrc][strlen(sources[isrc])-1] == '/') - { - isdir = 1; - curl_easy_setopt(easyhandle,CURLOPT_WRITEFUNCTION,rawindex_callback); - curl_easy_setopt(easyhandle,CURLOPT_WRITEDATA,(void *) &rawindex); - curl_easy_setopt(easyhandle,CURLOPT_NOBODY,0); - rawindex.text = NULL; - rawindex.used = 0; - rawindex.allocated = 0; - } - else - { - isdir = 0; - curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, NULL); - curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, NULL); - curl_easy_setopt(easyhandle, CURLOPT_NOBODY, 1); - } - - header_data.gridauthonetime = NULL; - header_data.length_set = 0; - header_data.modified_set = 0; - header_data.retcode = 0; - thiserror = curl_easy_perform(easyhandle); - - if ((thiserror != 0) || - (header_data.retcode < 200) || - (header_data.retcode >= 300)) - { - fprintf(stderr, "... curl error: %s (%d), HTTP error: %d\n", - common_data->errorbuf, thiserror, header_data.retcode); - - if (thiserror != 0) anyerror = thiserror; - else anyerror = header_data.retcode; - } - else if (isdir) - { - if (common_data->verbose > 0) - fprintf(stderr, "... OK (%d)\n", header_data.retcode); - - rawindex.text[rawindex.used] = '\0'; - - list = index_to_dir_list(rawindex.text, sources[isrc]); - ilast = -1; - - for (i=0; list[i].filename != NULL; ++i) - { - if (list[i].filename[0] == '.') continue; - - if (strncmp(list[i].filename, "mailto:", 7) == 0) continue; - - if ((ilast >= 0) && - (strcmp(list[i].filename, list[ilast].filename) == 0)) - continue; - ilast=i; - - if (islonglist) - { - if (!list[i].length_set || !list[i].modified_set) - { - curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, - NULL); - curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, NULL); - curl_easy_setopt(easyhandle, CURLOPT_NOBODY, 1); - - asprintf(&s, "%s%s", sources[isrc], list[i].filename); - curl_easy_setopt(easyhandle, CURLOPT_URL, s); - - header_data.gridauthonetime = NULL; - header_data.length_set = 0; - header_data.modified_set = 0; - header_data.retcode = 0; - thiserror = curl_easy_perform(easyhandle); - free(s); - - if ((thiserror == 0) && - (header_data.retcode >= 200) && - (header_data.retcode <= 299)) - { - if (header_data.length_set) - { - list[i].length_set = 1; - list[i].length = header_data.length; - } - - if (header_data.modified_set) - { - list[i].modified_set = 1; - list[i].modified = header_data.modified; - } - } - } - - if (list[i].length_set) printf("%10ld ", list[i].length); - else fputs(" ? ", stdout); - - if (list[i].modified_set) - { - localtime_r(&(list[i].modified), &modified_tm); - - if (list[i].modified < now - 15552000) - printf("%s %2d %4d ", - months[modified_tm.tm_mon], - modified_tm.tm_mday, - modified_tm.tm_year + 1900); - else printf("%s %2d %02d:%02d ", - months[modified_tm.tm_mon], - modified_tm.tm_mday, - modified_tm.tm_hour, - modified_tm.tm_min); - } - else fputs(" ? ? ? ", stdout); - } - - puts(list[i].filename); - } - } - else - { - if (islonglist) - { - printf("%10ld ", header_data.length); - - localtime_r(&(header_data.modified), &modified_tm); - - if (header_data.modified < now - 15552000) - printf("%s %2d %4d ", - months[modified_tm.tm_mon], - modified_tm.tm_mday, - modified_tm.tm_year + 1900); - else printf("%s %2d %02d:%02d ", - months[modified_tm.tm_mon], - modified_tm.tm_mday, - modified_tm.tm_hour, - modified_tm.tm_min); - } - - puts(sources[isrc]); - } - } - - curl_easy_cleanup(easyhandle); - - return anyerror; -} - -#if (LIBCURL_VERSION_NUM < 0x070908) -char *make_tmp_ca_roots(char *dir) -/* libcurl before 7.9.8 doesnt support CURLOPT_CAPATH and the directory, - so we make a temporary file with the concatenated CA root certs: that - is, all the files in that directory which end in .0 */ -{ - int ofd, ifd, c; - size_t size; - char tmp_ca_roots[] = "/tmp/.ca-roots-XXXXXX", buffer[4096], *s; - DIR *rootsDIR; - struct dirent *root_ent; - - if ((rootsDIR = opendir(dir)) == NULL) return NULL; - - if ((ofd = mkstemp(tmp_ca_roots)) == -1) - { - closedir(rootsDIR); - return NULL; - } - - while ((root_ent = readdir(rootsDIR)) != NULL) - { - if ((root_ent->d_name[0] != '.') && - (strlen(root_ent->d_name) > 2) && - (strncmp(&(root_ent->d_name[strlen(root_ent->d_name)-2]), - ".0", 2) == 0)) - { - asprintf(&s, "%s/%s", dir, root_ent->d_name); - ifd = open(s, O_RDONLY); - free(s); - - if (ifd != -1) - { - while ((size = read(ifd, buffer, sizeof(buffer))) > 0) - write(ofd, buffer, size); - close(ifd); - } - } - } - - closedir(rootsDIR); - - if (close(ofd) == 0) return strdup(tmp_ca_roots); - - unlink(tmp_ca_roots); /* try to clean up */ - - return NULL; -} -#endif - -void printsyntax(char *argv0) -{ - char *p; - - p = rindex(argv0, '/'); - if (p != NULL) ++p; - else p = argv0; - - fprintf(stderr, "%s [options] Source-URL[s] [Destination URL]\n" - "%s is one of a set of clients to fetch files or directory listings\n" -"from remote servers using HTTP or HTTPS, or to put or delete files or\n" -"directories onto remote servers using HTTPS. htcp is similar to scp(1)\n" -"but uses HTTP/HTTPS rather than ssh as its transfer protocol.\n" -"See the htcp(1) or http://www.gridsite.org/ for details.\n" -"(Version: %s)\n", p, p, VERSION); -} - -int main(int argc, char *argv[]) -{ - char **sources, *destination = NULL, *executable, *p; - int c, i, option_index, anyerror; - struct stat statbuf; - struct grst_stream_data common_data; - struct passwd *userpasswd; - struct option long_options[] = { {"verbose", 0, 0, 'v'}, - {"cert", 1, 0, 0}, - {"key", 1, 0, 0}, - {"capath", 1, 0, 0}, - {"delete", 0, 0, 0}, - {"list", 0, 0, 0}, - {"long-list", 0, 0, 0}, - {"mkdir", 0, 0, 0}, - {"no-verify", 0, 0, 0}, - {"anon", 0, 0, 0}, - {"downgrade-size", 1, 0, 0}, -// {"streams", 1, 0, 0}, -// {"blocksize", 1, 0, 0}, -// {"recursive", 0, 0, 0}, - {0, 0, 0, 0} }; - -#if (LIBCURL_VERSION_NUM < 0x070908) - char *tmp_ca_roots = NULL; -#endif - - if (argc == 1) - { - printsyntax(argv[0]); - return 0; - } - - common_data.cert = NULL; - common_data.key = NULL; - common_data.capath = NULL; - common_data.method = 0; - common_data.errorbuf = malloc(CURL_ERROR_SIZE); - asprintf(&(common_data.useragent), - "htcp/%s (http://www.gridsite.org/)", VERSION); - common_data.verbose = 0; - common_data.noverify = 0; - common_data.anonymous = 0; - common_data.downgrade = (long long) -1; - - while (1) - { - option_index = 0; - - c = getopt_long(argc, argv, "v", long_options, &option_index); - - if (c == -1) break; - else if (c == 0) - { - if (option_index == 1) common_data.cert = optarg; - else if (option_index == 2) common_data.key = optarg; - else if (option_index == 3) common_data.capath = optarg; - else if (option_index == 4) common_data.method = HTCP_DELETE; - else if (option_index == 5) common_data.method = HTCP_LIST; - else if (option_index == 6) common_data.method = HTCP_LONGLIST; - else if (option_index == 7) common_data.method = HTCP_MKDIR; - else if (option_index == 8) common_data.noverify = 1; - else if (option_index == 9) common_data.anonymous = 1; - else if (option_index ==10) common_data.downgrade = atoll(optarg); - } - else if (c == 'v') ++(common_data.verbose); - } - - if (common_data.verbose > 0) - { - p = rindex(argv[0], '/'); - if (p != NULL) ++p; - else p = argv[0]; - fprintf(stderr, "%s version %s\n", p, VERSION); - } - - if (common_data.anonymous) /* prevent any use of user certs */ - { - common_data.cert = NULL; - common_data.key = NULL; - } - else if ((common_data.cert == NULL) && (common_data.key != NULL)) - common_data.cert = common_data.key; - else if ((common_data.cert != NULL) && (common_data.key == NULL)) - common_data.key = common_data.cert; - else if ((common_data.cert == NULL) && (common_data.key == NULL)) - { - common_data.cert = getenv("X509_USER_PROXY"); - if (common_data.cert != NULL) common_data.key = common_data.cert; - else - { - asprintf(&(common_data.cert), "/tmp/x509up_u%d", geteuid()); - - /* one fine day, we will check the proxy file for expiry too ... */ - - if (stat(common_data.cert, &statbuf) == 0) - common_data.key = common_data.cert; - else - { - common_data.cert = getenv("X509_USER_CERT"); - common_data.key = getenv("X509_USER_KEY"); - - userpasswd = getpwuid(geteuid()); - - if ((common_data.cert == NULL) && - (userpasswd != NULL) && - (userpasswd->pw_dir != NULL)) - asprintf(&(common_data.cert), "%s/.globus/usercert.pem", - userpasswd->pw_dir); - - if ((common_data.key == NULL) && - (userpasswd != NULL) && - (userpasswd->pw_dir != NULL)) - asprintf(&(common_data.key), "%s/.globus/userkey.pem", - userpasswd->pw_dir); - } - } - } - - if (common_data.capath == NULL) common_data.capath = getenv("X509_CERT_DIR"); - - if (common_data.capath == NULL) - common_data.capath = "/etc/grid-security/certificates"; - -#if (LIBCURL_VERSION_NUM < 0x070908) - /* libcurl before 7.9.8 doesnt support CURLOPT_CAPATH and the directory */ - - if ((common_data.capath != NULL) && - (stat(common_data.capath, &statbuf) == 0) && S_ISDIR(statbuf.st_mode)) - { - tmp_ca_roots = make_tmp_ca_roots(common_data.capath); - common_data.capath = tmp_ca_roots; - } -#endif - - executable = rindex(argv[0], '/'); - if (executable != NULL) executable++; - else executable = argv[0]; - - if (common_data.method == 0) /* command-line options override exec name */ - { - if (strcmp(executable,"htls")==0) common_data.method=HTCP_LIST; - else if (strcmp(executable,"htll")==0) common_data.method=HTCP_LONGLIST; - else if (strcmp(executable,"htrm")==0) common_data.method=HTCP_DELETE; - else if (strcmp(executable,"htmkdir")==0) common_data.method=HTCP_MKDIR; - } - - if ((common_data.method == HTCP_DELETE) || - (common_data.method == HTCP_LIST) || - (common_data.method == HTCP_MKDIR) || - (common_data.method == HTCP_LONGLIST)) - { - if (optind >= argc) - { - fprintf(stderr, "Must give at least 1 non-option argument\n\n"); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - sources = (char **) malloc(sizeof(char *) * (1 + argc - optind)); - for (i=0; i < argc - optind; ++i) - { - sources[i] = argv[optind + i]; - - if ((common_data.method == HTCP_MKDIR) && - (sources[i][strlen(sources[i])-1] != '/')) - { - fprintf(stderr, "Argument \"%s\" is not a " - "directory URL (no trailing /)\n\n", sources[i]); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - } - - sources[i] = NULL; - - if (common_data.method == HTCP_DELETE) - anyerror = do_deletes(sources, &common_data); - else if (common_data.method == HTCP_MKDIR) - anyerror = do_mkdirs(sources, &common_data); - else if (common_data.method == HTCP_LONGLIST) - anyerror = do_listings(sources, &common_data, 1); - else anyerror = do_listings(sources, &common_data, 0); - - if (anyerror > 99) anyerror = CURLE_HTTP_RETURNED_ERROR; - - return anyerror; - } - - if (optind >= argc - 1) - { - fputs("Must give at least 2 non-option arguments\n\n", stderr); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - sources = (char **) malloc(sizeof(char *) * (argc - optind)); - - for (i=0; i < (argc - optind - 1); ++i) - { - if (strncmp(argv[optind + i], "file:", 5) == 0) - sources[i] = &argv[optind + i][5]; - else sources[i] = argv[optind + i]; - - if (sources[i][0] == '\0') - { - fprintf(stderr, "Source argument %d is empty\n\n", i + 1); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - } - - sources[i] = NULL; - - if (strncmp(argv[optind + i], "file:", 5) == 0) - destination = &argv[optind + i][5]; - else destination = argv[optind + i]; - - if (destination[0] == '\0') - { - fputs("Destination argument is empty\n\n", stderr); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - if ((argc - optind > 2) && (destination[strlen(destination)-1] != '/')) - { - fputs("For multiple sources, destination " - "must be a directory (end in /)\n\n", stderr); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - if ((strncmp(destination, "http://", 7) == 0) || - (strncmp(destination, "https://", 8) == 0)) - common_data.method = HTCP_PUT; - else common_data.method = HTCP_GET; - - for (i=0; sources[i] != NULL; ++i) - { - if ((common_data.method == HTCP_PUT) && - ((strncmp(sources[i], "http://", 7) == 0) || - (strncmp(sources[i], "https://", 8) == 0))) - { - fputs("Cannot have both source and destination remote\n\n",stderr); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - - if ((common_data.method == HTCP_GET) && - ((strncmp(sources[i], "http://", 7) != 0) && - (strncmp(sources[i], "https://", 8) != 0))) - { - fputs("Cannot have both source and " - "destination local (for now)\n\n",stderr); - printsyntax(argv[0]); - return CURLE_URL_MALFORMAT; - } - } - - anyerror = do_copies(sources, destination, &common_data); - if (anyerror > 99) anyerror = CURLE_HTTP_RETURNED_ERROR; - - return anyerror; -} diff --git a/org.gridsite.core/src/htproxyput.c b/org.gridsite.core/src/htproxyput.c deleted file mode 100644 index 834bea2..0000000 --- a/org.gridsite.core/src/htproxyput.c +++ /dev/null @@ -1,565 +0,0 @@ -/* - Copyright (c) 2002-4, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. -*/ - -/* - -Build with: - -gcc -lcurl -lssl -lcrypto -o grst-proxy-put grst-proxy-put.c libgridsite.a - -http://www.gridpp.ac.uk/authz/gridsite/ - -*/ - -#ifndef VERSION -#define VERSION "0.0.0" -#endif - -#define _GNU_SOURCE - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "gridsite.h" - -#include "soapH.h" -#include "delegation.nsmap" - -#define USE_SOAP 0 -#define USE_G_HTTPS 1 -#define HTPROXY_PUT 0 - -int debugfunction(CURL *curl, curl_infotype type, char *s, size_t n, void *p) -{ - fwrite(s, sizeof(char), n, (FILE *) p); - - return 0; -} - -size_t parsegprheaders(void *ptr, size_t size, size_t nmemb, void *p) -{ - int i; - - if ((size * nmemb > 15) && - (strncmp((char *) ptr, "Delegation-ID: ", 15) == 0)) - { - *((char **) p) = malloc( size * nmemb - 14 ); - - memcpy(*((char **) p), &(((char *) ptr)[15]), size * nmemb - 15); - - for (i=0; i < size * nmemb - 15; ++i) - if (((*((char **) p))[i] == '\n') || ((*((char **) p))[i] == '\r')) - { - (*((char **) p))[i] = '\0'; /* drop trailing newline */ - break; - } - - (*((char **) p))[size * nmemb - 15] = '\0'; - } - - return size * nmemb; -} - -struct gprparams { char *req; size_t len; } ; - -size_t storegprbody(void *ptr, size_t size, size_t nmemb, void *p) -{ - ((struct gprparams *) p)->req = realloc( ((struct gprparams *) p)->req, - ((struct gprparams *) p)->len + size * nmemb + 1); - - memcpy( &((((struct gprparams *) p)->req)[((struct gprparams *) p)->len]), - ptr, size * nmemb); - - ((struct gprparams *) p)->len += size * nmemb; - - return size * nmemb; -} - -int GRSTgetProxyReq(CURL *curl, FILE *debugfp, char *delegid, char **reqtxt, - char *requrl, char *cert, char *key) -{ - char *delheader; - struct curl_slist *headerlist = NULL; - CURLcode res; - struct gprparams params; - - params.req = NULL; - params.len = 0; - - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) ¶ms); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, storegprbody); - - curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_SSLCERT, cert); - - curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_SSLKEY, key); - curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, NULL); - -// curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, parsegprheaders); -// curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *) delegid); - - curl_easy_setopt(curl, CURLOPT_CAPATH, "/etc/grid-security/certificates/"); - - curl_easy_setopt(curl, CURLOPT_URL, requrl); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET-PROXY-REQ"); - - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,0); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST,0); - - asprintf(&delheader, "Delegation-ID: %s", delegid); - headerlist = curl_slist_append(headerlist, delheader); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); - - if (debugfp != NULL) - { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_DEBUGDATA, debugfp); - curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, debugfunction); - } - - res = curl_easy_perform(curl); - - if (params.req != NULL) - { - params.req[params.len] = '\0'; - *reqtxt = params.req; - } - else *reqtxt = NULL; - - return (int) res; -} - -struct ppcparams{ char *cert; size_t len; }; - -size_t getppcbody(void *ptr, size_t size, size_t nmemb, void *p) -{ - size_t i; - - if (((struct ppcparams *) p)->len == 0) return 0; - - if (size * nmemb < ((struct ppcparams *) p)->len) i = size * nmemb; - else i = ((struct ppcparams *) p)->len; - - memcpy(ptr, ((struct ppcparams *) p)->cert, i); - - ((struct ppcparams *) p)->len -= i; - ((struct ppcparams *) p)->cert = &((((struct ppcparams *) p)->cert)[i+1]); - - return i; -} - -int GRSTputProxyCerts(CURL *curl, FILE *debugfp, char *delegid, char *certtxt, - char *requrl, char *cert, char *key) -{ - CURLcode res; - char *delheader; - long httpcode; - struct curl_slist *headerlist = NULL; - struct ppcparams params; - - params.cert = certtxt; - params.len = strlen(certtxt); - - curl_easy_setopt(curl, CURLOPT_READDATA, ¶ms); - curl_easy_setopt(curl, CURLOPT_READFUNCTION, getppcbody); - curl_easy_setopt(curl, CURLOPT_INFILESIZE, strlen(certtxt)); - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); - - curl_easy_setopt(curl, CURLOPT_NOBODY, 1); - - curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_SSLCERT, cert); - - curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_SSLKEY, key); -// curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, NULL); - - curl_easy_setopt(curl, CURLOPT_CAPATH, "/etc/grid-security/certificates/"); - - curl_easy_setopt(curl, CURLOPT_URL, requrl); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT-PROXY-CERT"); - - headerlist = curl_slist_append(headerlist, - "Content-Type: application/x-x509-user-cert-chain"); - - asprintf(&delheader, "Delegation-ID: %s", delegid); - headerlist = curl_slist_append(headerlist, delheader); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); - -curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); -curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); - - if (debugfp != NULL) - { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_DEBUGDATA, debugfp); - curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, debugfunction); - } - - res = curl_easy_perform(curl); - - curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &httpcode); - - curl_slist_free_all(headerlist); - - free(delheader); - - return (int) res; -} - - -#if (LIBCURL_VERSION_NUM < 0x070908) -char *make_tmp_ca_roots(char *dir) -/* libcurl before 7.9.8 doesnt support CURLOPT_CAPATH and the directory, - so we make a temporary file with the concatenated CA root certs: that - is, all the files in that directory which end in .0 */ -{ - int ofd, ifd, c; - size_t size; - char tmp_ca_roots[] = "/tmp/.ca-roots-XXXXXX", buffer[4096], *s; - DIR *rootsDIR; - struct dirent *root_ent; - - if ((rootsDIR = opendir(dir)) == NULL) return NULL; - - if ((ofd = mkstemp(tmp_ca_roots)) == -1) - { - closedir(rootsDIR); - return NULL; - } - - while ((root_ent = readdir(rootsDIR)) != NULL) - { - if ((root_ent->d_name[0] != '.') && - (strlen(root_ent->d_name) > 2) && - (strncmp(&(root_ent->d_name[strlen(root_ent->d_name)-2]), - ".0", 2) == 0)) - { - asprintf(&s, "%s/%s", dir, root_ent->d_name); - ifd = open(s, O_RDONLY); - free(s); - - if (ifd != -1) - { - while ((size = read(ifd, buffer, sizeof(buffer))) > 0) - write(ofd, buffer, size); - - close(ifd); - } - } - } - - closedir(rootsDIR); - - if (close(ofd) == 0) return strdup(tmp_ca_roots); - - unlink(tmp_ca_roots); /* try to clean up if errors */ - - return NULL; -} -#endif - -void printsyntax(char *argv0) -{ - char *p; - - p = rindex(argv0, '/'); - if (p != NULL) ++p; - else p = argv0; - - fprintf(stderr, "%s [options] URL\n" - "(Version: %s)\n", p, VERSION); -} - -int main(int argc, char *argv[]) -{ - char *delegation_id = "", *reqtxt, *certtxt, *valid = NULL, - *cert = NULL, *key = NULL, *capath = NULL, *keycert; - struct ns__putProxyResponse *unused; - int option_index, c, protocol = USE_SOAP, noverify = 0, - method = HTPROXY_PUT, verbose = 0, fd, minutes; - struct soap soap_get, soap_put; - FILE *ifp, *ofp; - struct stat statbuf; - struct passwd *userpasswd; - struct option long_options[] = { {"verbose", 0, 0, 'v'}, - {"cert", 1, 0, 0}, - {"key", 1, 0, 0}, - {"capath", 1, 0, 0}, - {"soap", 0, 0, 0}, - {"g-https", 0, 0, 0}, - {"no-verify", 0, 0, 0}, - {"valid", 1, 0, 0}, - {"delegation-id",1, 0, 0}, - {"put", 0, 0, 0}, - {0, 0, 0, 0} }; - CURL *curl; - - if (argc == 1) - { - printsyntax(argv[0]); - return 0; - } - - while (1) - { - option_index = 0; - - c = getopt_long(argc, argv, "v", long_options, &option_index); - - if (c == -1) break; - else if (c == 0) - { - if (option_index == 1) cert = optarg; - else if (option_index == 2) key = optarg; - else if (option_index == 3) capath = optarg; - else if (option_index == 4) protocol = USE_SOAP; - else if (option_index == 5) protocol = USE_G_HTTPS; - else if (option_index == 6) noverify = 1; - else if (option_index == 7) valid = optarg; - else if (option_index == 8) delegation_id = optarg; - else if (option_index == 9) method = HTPROXY_PUT; - } - else if (c == 'v') ++verbose; - } - - if (optind + 1 != argc) - { - fprintf(stderr, "Must specify a target URL!\n"); - return 1; - } - - if (valid == NULL) minutes = 60 * 12; - else minutes = atoi(valid); - - if (verbose) fprintf(stderr, "Proxy valid for %d minutes\n", minutes); - - ERR_load_crypto_strings (); - OpenSSL_add_all_algorithms(); - - if ((cert == NULL) && (key != NULL)) cert = key; - else if ((cert != NULL) && (key == NULL)) key = cert; - else if ((cert == NULL) && (key == NULL)) - { - cert = getenv("X509_USER_PROXY"); - if (cert != NULL) key = cert; - else - { - asprintf(&(cert), "/tmp/x509up_u%d", geteuid()); - - /* one fine day, we will check the proxy file for - expiry too to avoid suprises when we try to use it ... */ - - if (stat(cert, &statbuf) == 0) key = cert; - else - { - cert = getenv("X509_USER_CERT"); - key = getenv("X509_USER_KEY"); - - userpasswd = getpwuid(geteuid()); - - if ((cert == NULL) && - (userpasswd != NULL) && - (userpasswd->pw_dir != NULL)) - asprintf(&(cert), "%s/.globus/usercert.pem", - userpasswd->pw_dir); - - if ((key == NULL) && - (userpasswd != NULL) && - (userpasswd->pw_dir != NULL)) - asprintf(&(key), "%s/.globus/userkey.pem", - userpasswd->pw_dir); - - } - } - } - - if (capath == NULL) capath = getenv("X509_CERT_DIR"); - if (capath == NULL) capath = "/etc/grid-security/certificates"; - - if (verbose) fprintf(stderr, "key=%s\ncert=%s\ncapath=%s\n", - key, cert, capath); - -#if (LIBCURL_VERSION_NUM < 0x070908) - /* libcurl before 7.9.8 doesnt support CURLOPT_CAPATH and the directory */ - - if ((capath != NULL) && - (stat(capath, &statbuf) == 0) && S_ISDIR(statbuf.st_mode)) - { - tmp_ca_roots = make_tmp_ca_roots(capath); - capath = tmp_ca_roots; - } -#endif - - if (protocol == USE_G_HTTPS) - { - if (verbose) fprintf(stderr, "Using G-HTTPS delegation protocol\n"); - - if (verbose) fprintf(stderr, "Delegation-ID: %s\n", delegation_id); - - curl_global_init(CURL_GLOBAL_DEFAULT); - curl = curl_easy_init(); - -// curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, NULL); - - GRSTgetProxyReq(curl, stderr, delegation_id, &reqtxt, - argv[optind], cert, key); - - if (GRSTx509MakeProxyCert(&certtxt, stderr, reqtxt, cert, key, minutes) - != GRST_RET_OK) - { - return 1; - } - - GRSTputProxyCerts(curl, stderr, delegation_id, certtxt, - argv[optind], cert, key); - - curl_easy_cleanup(curl); - curl_global_cleanup(); - - return 0; - } - else if (protocol == USE_SOAP) - { - if (strcmp(key, cert) != 0) /* we have to concatenate for gSOAP */ - { - keycert = strdup("/tmp/XXXXXX"); - - fd = mkstemp(keycert); - ofp = fdopen(fd, "w"); - - ifp = fopen(key, "r"); - while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); - fclose(ifp); - - ifp = fopen(cert, "r"); - while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); - fclose(ifp); - - fclose(ofp); - - if (verbose) fprintf(stderr, "Created %s key/cert file\n", keycert); - } - else keycert = key; - - if (verbose) - { - fprintf(stderr, "Using SOAP delegation protocol\n"); - fprintf(stderr, "Delegation-ID: %s\n", delegation_id); - fprintf(stderr, "Send getProxyReq to service\n"); - } - - soap_init(&soap_get); - - if (soap_ssl_client_context(&soap_get, - SOAP_SSL_DEFAULT, - keycert, - "", - NULL, - capath, - NULL)) - { - soap_print_fault(&soap_get, stderr); - return 1; - } - - soap_call_ns__getProxyReq(&soap_get, - argv[optind], /* HTTPS url of service */ - "", /* no password on proxy */ - delegation_id, - &reqtxt); - - if (soap_get.error) - { - soap_print_fault(&soap_get, stderr); - return 1; - } - - if (verbose) fprintf(stderr, "reqtxt:\n%s", reqtxt); - - if (GRSTx509MakeProxyCert(&certtxt, stderr, reqtxt, cert, key, minutes) - != GRST_RET_OK) - { - return 1; - } - - soap_init(&soap_put); - - if (verbose) fprintf(stderr, "Send putProxy to service:\n%s\n", certtxt); - - if (soap_ssl_client_context(&soap_put, - SOAP_SSL_DEFAULT, - keycert, - "", - NULL, - capath, - NULL)) - { - soap_print_fault(&soap_put, stderr); - return 1; - } - - soap_call_ns__putProxy(&soap_put, argv[optind], "", delegation_id, - certtxt, unused); - if (soap_put.error) - { - soap_print_fault(&soap_put, stderr); - return 1; - } - - return 0; - } - - /* weirdness */ -} - diff --git a/org.gridsite.core/src/mod_gridsite.c b/org.gridsite.core/src/mod_gridsite.c deleted file mode 100644 index 78d853c..0000000 --- a/org.gridsite.core/src/mod_gridsite.c +++ /dev/null @@ -1,2357 +0,0 @@ -/* - Copyright (c) 2003-4, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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 program is part of GridSite: http://www.gridsite.org/ * - *------------------------------------------------------------------*/ - -#ifndef VERSION -#define VERSION "x.x.x" -#endif - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -#include "mod_ssl-private.h" - -#include "gridsite.h" - -#ifndef UNSET -#define UNSET -1 -#endif - -module AP_MODULE_DECLARE_DATA gridsite_module; - -typedef struct -{ - int auth; - int envs; - int format; - int indexes; - char *indexheader; - int gridsitelink; - char *adminfile; - char *adminuri; - char *helpuri; - char *dnlists; - char *dnlistsuri; - char *adminlist; - int gsiproxylimit; - char *unzip; - char *methods; - char *editable; - char *headfile; - char *footfile; - int downgrade; - char *authcookiesdir; - int soap2cgi; -} mod_gridsite_cfg; /* per-directory config choices */ - - -typedef struct -{ - xmlDocPtr doc; -// char *outbuffer; -} soap2cgi_ctx; /* store per-request context for Soap2cgi in/out filters */ - -static const char Soap2cgiFilterName[]="Soap2cgiFilter"; - -static void mod_gridsite_soap2cgi_insert(request_rec *r) -{ - mod_gridsite_cfg *conf; - soap2cgi_ctx *ctx; - - conf = (mod_gridsite_cfg *) ap_get_module_config(r->per_dir_config, - &gridsite_module); - - if (conf->soap2cgi) - { - ctx = (soap2cgi_ctx *) malloc(sizeof(soap2cgi_ctx)); - ctx->doc = NULL; - - ap_add_output_filter(Soap2cgiFilterName, ctx, r, r->connection); - - ap_add_input_filter(Soap2cgiFilterName, NULL, r, r->connection); - } -} - -xmlNodePtr find_one_child(xmlNodePtr parent_node, char *name) -{ - xmlNodePtr cur; - - for (cur = parent_node->children; cur != NULL; cur = cur->next) - { - if ((cur->type == XML_ELEMENT_NODE) && - (strcmp(cur->name, name) == 0)) return cur; - } - - return NULL; -} - -int add_one_node(xmlDocPtr doc, char *line) -{ - char *p, *name, *aftername, *attrname = NULL, *value = NULL; - xmlNodePtr cur, cur_child; - - cur = xmlDocGetRootElement(doc); - - p = index(line, '='); - if (p == NULL) return 1; - - *p = '\0'; - value = &p[1]; - - name = line; - - while (1) /* go through each .-deliminated segment of line[] */ - { - if ((p = index(name, '.')) != NULL) - { - *p = '\0'; - aftername = &p[1]; - } - else aftername = &name[strlen(name)]; - - if ((p = index(name, '_')) != NULL) - { - *p = '\0'; - attrname = &p[1]; - } - - cur_child = find_one_child(cur, name); - - if (cur_child == NULL) - cur_child = xmlNewChild(cur, NULL, name, NULL); - - cur = cur_child; - - name = aftername; - - if (attrname != NULL) - { - xmlSetProp(cur, attrname, value); - return 0; - } - - if (*name == '\0') - { - xmlNodeSetContent(cur, value); - return 0; - } - } -} - -static apr_status_t mod_gridsite_soap2cgi_out(ap_filter_t *f, - apr_bucket_brigade *bbIn) -{ - char *p, *name, *outbuffer; - request_rec *r = f->r; - conn_rec *c = r->connection; - apr_bucket *bucketIn, *pbktEOS; - apr_bucket_brigade *bbOut; - - const char *data; - apr_size_t len; - char *buf; - apr_size_t n; - apr_bucket *pbktOut; - - soap2cgi_ctx *ctx; - xmlNodePtr root_node = NULL; - xmlBufferPtr buff; - - ctx = (soap2cgi_ctx *) f->ctx; - -// LIBXML_TEST_VERSION; - - bbOut = apr_brigade_create(r->pool, c->bucket_alloc); - - if (ctx->doc == NULL) - { - ctx->doc = xmlNewDoc("1.0"); - - root_node = xmlNewNode(NULL, "Envelope"); - xmlDocSetRootElement(ctx->doc, root_node); - - xmlNewChild(root_node, NULL, "Header", NULL); - xmlNewChild(root_node, NULL, "Body", NULL); - } - - apr_brigade_pflatten(bbIn, &outbuffer, &len, r->pool); - - /* split up buffer and feed each line to add_one_node() */ - - name = outbuffer; - - while (*name != '\0') - { - p = index(name, '\n'); - if (p != NULL) - { - *p = '\0'; - ++p; - } - else p = &name[strlen(name)]; /* point to final NUL */ - - add_one_node(ctx->doc, name); - - name = p; - } - - APR_BRIGADE_FOREACH(bucketIn, bbIn) - { - if (APR_BUCKET_IS_EOS(bucketIn)) - { - /* write out XML tree we have built */ - - buff = xmlBufferCreate(); - xmlNodeDump(buff, ctx->doc, root_node, 0, 0); - -// TODO: simplify/reduce number of copies or libxml vs APR buffers? - - buf = (char *) xmlBufferContent(buff); - - pbktOut = apr_bucket_heap_create(buf, strlen(buf), NULL, - c->bucket_alloc); - - APR_BRIGADE_INSERT_TAIL(bbOut, pbktOut); - - xmlBufferFree(buff); - - pbktEOS = apr_bucket_eos_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bbOut, pbktEOS); - - continue; - } - } - - return ap_pass_brigade(f->next, bbOut); -} - -static apr_status_t mod_gridsite_soap2cgi_in(ap_filter_t *f, - apr_bucket_brigade *pbbOut, - ap_input_mode_t eMode, - apr_read_type_e eBlock, - apr_off_t nBytes) -{ - request_rec *r = f->r; - conn_rec *c = r->connection; -// CaseFilterInContext *pCtx; - apr_status_t ret; - -#ifdef NEVERDEFINED - - ret = ap_get_brigade(f->next, pCtx->pbbTmp, eMode, eBlock, nBytes); - - if (!(pCtx = f->ctx)) { - f->ctx = pCtx = apr_palloc(r->pool, sizeof *pCtx); - pCtx->pbbTmp = apr_brigade_create(r->pool, c->bucket_alloc); - } - - if (APR_BRIGADE_EMPTY(pCtx->pbbTmp)) { - ret = ap_get_brigade(f->next, pCtx->pbbTmp, eMode, eBlock, nBytes); - - if (eMode == AP_MODE_EATCRLF || ret != APR_SUCCESS) - return ret; - } - - while(!APR_BRIGADE_EMPTY(pCtx->pbbTmp)) { - apr_bucket *pbktIn = APR_BRIGADE_FIRST(pCtx->pbbTmp); - apr_bucket *pbktOut; - const char *data; - apr_size_t len; - char *buf; - int n; - - /* It is tempting to do this... - * APR_BUCKET_REMOVE(pB); - * APR_BRIGADE_INSERT_TAIL(pbbOut,pB); - * and change the case of the bucket data, but that would be wrong - * for a file or socket buffer, for example... - */ - - if(APR_BUCKET_IS_EOS(pbktIn)) { - APR_BUCKET_REMOVE(pbktIn); - APR_BRIGADE_INSERT_TAIL(pbbOut, pbktIn); - break; - } - - ret=apr_bucket_read(pbktIn, &data, &len, eBlock); - if(ret != APR_SUCCESS) - return ret; - - buf = malloc(len); - for(n=0 ; n < len ; ++n) - buf[n] = apr_toupper(data[n]); - - pbktOut = apr_bucket_heap_create(buf, len, 0, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(pbbOut, pbktOut); - apr_bucket_delete(pbktIn); - } -#endif - - return APR_SUCCESS; -} - -char *make_admin_footer(request_rec *r, mod_gridsite_cfg *conf, - int isdirectory) -/* - make string holding last modified text and admin links -*/ -{ - char *out, *https, *p, *dn = NULL, *file = NULL, *permstr = NULL, - *temp, modified[99], *dir_uri, *grst_cred_0 = NULL; - GRSTgaclPerm perm = GRST_PERM_NONE; - struct tm mtime_tm; - time_t mtime_time; - - https = (char *) apr_table_get(r->subprocess_env, "HTTPS"); - - dir_uri = apr_pstrdup(r->pool, r->uri); - p = rindex(dir_uri, '/'); - - if (p == NULL) return ""; - - file = apr_pstrdup(r->pool, &p[1]); - p[1] = '\0'; - /* dir_uri always gets both a leading and a trailing slash */ - - out = apr_pstrdup(r->pool, "

\n"); - - if (!isdirectory) - { - mtime_time = apr_time_sec(r->finfo.mtime); - - localtime_r(&mtime_time, &mtime_tm); - strftime(modified, sizeof(modified), - "%a %e %B %Y", &mtime_tm); - temp = apr_psprintf(r->pool,"


Last modified %s\n", modified); - out = apr_pstrcat(r->pool, out, temp, NULL); - - if ((conf->adminuri != NULL) && - (conf->adminuri[0] != '\0') && - (conf->adminfile != NULL) && - (conf->adminfile[0] != '\0') && - (strncmp(file, GRST_HIST_PREFIX, sizeof(GRST_HIST_PREFIX)-1) != 0)) - { - temp = apr_psprintf(r->pool, - ". " - "View page history\n", - conf->adminfile, file); - out = apr_pstrcat(r->pool, out, temp, NULL); - } - } - - out = apr_pstrcat(r->pool, out, "
", NULL); - - if (r->connection->notes != NULL) - grst_cred_0 = (char *) - apr_table_get(r->connection->notes, "GRST_CRED_0"); - - if ((grst_cred_0 != NULL) && - (strncmp(grst_cred_0, "X509USER ", sizeof("X509USER")) == 0)) - { - p = index(grst_cred_0, ' '); - if (p != NULL) - { - p = index(++p, ' '); - if (p != NULL) - { - p = index(++p, ' '); - if (p != NULL) - { - p = index(++p, ' '); - if (p != NULL) dn = p; - } - } - } - } - - if (dn != NULL) - { - temp = apr_psprintf(r->pool, "You are %s
\n", dn); - out = apr_pstrcat(r->pool, out, temp, NULL); - - if (r->notes != NULL) - permstr = (char *) apr_table_get(r->notes, "GRST_PERM"); - - if ((permstr != NULL) && - (conf->adminuri != NULL) && - (conf->adminuri[0] != '\0') && - (conf->adminfile != NULL) && - (conf->adminfile[0] != '\0')) - { - sscanf(permstr, "%d", &perm); - - if (!isdirectory && - GRSTgaclPermHasWrite(perm) && - (strncmp(file, GRST_HIST_PREFIX, - sizeof(GRST_HIST_PREFIX) - 1) != 0)) - { - temp = apr_psprintf(r->pool, - "" - "Edit page .\n", conf->adminfile, file); - out = apr_pstrcat(r->pool, out, temp, NULL); - } - - if (GRSTgaclPermHasList(perm) || GRSTgaclPermHasWrite(perm)) - { - temp = apr_psprintf(r->pool, - "Manage directory .\n", - dir_uri, conf->adminfile); - - out = apr_pstrcat(r->pool, out, temp, NULL); - } - } - } - - if ((https != NULL) && (strcasecmp(https, "on") == 0)) - temp = apr_psprintf(r->pool, - "Switch to HTTP \n", - r->server->server_hostname, r->unparsed_uri); - else temp = apr_psprintf(r->pool, - "Switch to HTTPS \n", - r->server->server_hostname, r->unparsed_uri); - - out = apr_pstrcat(r->pool, out, temp, NULL); - - if ((conf->helpuri != NULL) && (conf->helpuri[0] != '\0')) - { - temp = apr_psprintf(r->pool, - ". Website Help\n", conf->helpuri); - out = apr_pstrcat(r->pool, out, temp, NULL); - } - - if ((!isdirectory) && - (conf->adminuri != NULL) && - (conf->adminuri[0] != '\0') && - (conf->adminfile != NULL) && - (conf->adminfile[0] != '\0')) - { - temp = apr_psprintf(r->pool, ". " - "Print View\n", conf->adminfile, file); - out = apr_pstrcat(r->pool, out, temp, NULL); - } - - if (conf->gridsitelink) - { - temp = apr_psprintf(r->pool, - ". Built with " - "GridSite %s\n", VERSION); - out = apr_pstrcat(r->pool, out, temp, NULL); - } - - out = apr_pstrcat(r->pool, out, "\n
\n", NULL); - - return out; -} - -int html_format(request_rec *r, mod_gridsite_cfg *conf) -/* - try to do GridSite formatting of .html files (NOT .shtml etc) -*/ -{ - int i, fd, errstatus; - char *buf, *p, *file, *s, *head_formatted, *header_formatted, - *body_formatted, *admin_formatted, *footer_formatted; - size_t length; - struct stat statbuf; - apr_file_t *fp; - - if (r->finfo.filetype == APR_NOFILE) return HTTP_NOT_FOUND; - - if (apr_file_open(&fp, r->filename, APR_READ, 0, r->pool) != 0) - return HTTP_INTERNAL_SERVER_ERROR; - - file = rindex(r->uri, '/'); - if (file != NULL) ++file; /* file points to name without path */ - - buf = apr_palloc(r->pool, (size_t)(r->finfo.size + 1)); - length = r->finfo.size; - apr_file_read(fp, buf, &length); - buf[r->finfo.size] = '\0'; - apr_file_close(fp); - - /* **** try to find a header file in this or parent directories **** */ - - /* first make a buffer big enough to hold path names we want to try */ - fd = -1; - s = malloc(strlen(r->filename) + strlen(conf->headfile) + 1); - strcpy(s, r->filename); - - for (;;) - { - p = rindex(s, '/'); - if (p == NULL) break; /* failed to find one */ - p[1] = '\0'; - strcat(p, conf->headfile); - - fd = open(s, O_RDONLY); - if (fd != -1) break; /* found one */ - - *p = '\0'; - } - - free(s); - - if (fd == -1) /* not found, so set up not to output one */ - { - head_formatted = apr_pstrdup(r->pool, ""); - header_formatted = apr_pstrdup(r->pool, ""); - body_formatted = buf; - } - else /* found a header file, so set up head and body to surround it */ - { - fstat(fd, &statbuf); - header_formatted = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, header_formatted, statbuf.st_size); - header_formatted[statbuf.st_size] = '\0'; - close(fd); - - p = strstr(buf, "pool, ""); - body_formatted = buf; - } - else - { - *p = '\0'; - head_formatted = buf; - ++p; - - while ((*p != '>') && (*p != '\0')) ++p; - - if (*p == '\0') - { - body_formatted = p; - } - else - { - *p = '\0'; - ++p; - body_formatted = p; - } - } - } - - /* **** remove closing tag from body **** */ - - p = strstr(body_formatted, "filename) + strlen(conf->footfile)); - strcpy(s, r->filename); - - for (;;) - { - p = rindex(s, '/'); - if (p == NULL) break; /* failed to find one */ - - p[1] = '\0'; - strcat(p, conf->footfile); - - fd = open(s, O_RDONLY); - if (fd != -1) break; /* found one */ - - *p = '\0'; - } - - free(s); - - if (fd == -1) /* failed to find a footer, so set up empty default */ - { - footer_formatted = apr_pstrdup(r->pool, ""); - } - else /* found a footer, so set up to use it */ - { - fstat(fd, &statbuf); - footer_formatted = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, footer_formatted, statbuf.st_size); - footer_formatted[statbuf.st_size] = '\0'; - close(fd); - } - - /* **** can now calculate the Content-Length and output headers **** */ - - length = strlen(head_formatted) + strlen(header_formatted) + - strlen(body_formatted) + strlen(admin_formatted) + - strlen(footer_formatted); - - ap_set_content_length(r, length); - ap_set_content_type(r, "text/html"); - - /* ** output the HTTP body (HTML Head+Body) ** */ - - ap_rputs(head_formatted, r); - ap_rputs(header_formatted, r); - ap_rputs(body_formatted, r); - ap_rputs(admin_formatted, r); - ap_rputs(footer_formatted, r); - - return OK; -} - -int html_dir_list(request_rec *r, mod_gridsite_cfg *conf) -/* - output HTML directory listing, with level of formatting controlled - by GridSiteHtmlFormat/conf->format -*/ -{ - int i, fd, n; - char *buf, *p, *s, *head_formatted, *header_formatted, - *body_formatted, *admin_formatted, *footer_formatted, *temp, - modified[99], *d_namepath, *indexheaderpath, *indexheadertext; - size_t length; - struct stat statbuf; - struct tm mtime_tm; - struct dirent **namelist; - - if (r->finfo.filetype == APR_NOFILE) return HTTP_NOT_FOUND; - - head_formatted = apr_psprintf(r->pool, - "Directory listing %s\n", r->uri); - - if (conf->format) - { - /* **** try to find a header file in this or parent directories **** */ - - /* first make a buffer big enough to hold path names we want to try */ - fd = -1; - s = malloc(strlen(r->filename) + strlen(conf->headfile) + 1); - strcpy(s, r->filename); - - for (;;) - { - p = rindex(s, '/'); - if (p == NULL) break; /* failed to find one */ - p[1] = '\0'; - strcat(p, conf->headfile); - - fd = open(s, O_RDONLY); - if (fd != -1) break; /* found one */ - - *p = '\0'; - } - - free(s); - - if (fd == -1) /* not found, so set up to output sensible default */ - { - header_formatted = apr_pstrdup(r->pool, ""); - } - else /* found a header file, so set up head and body to surround it */ - { - fstat(fd, &statbuf); - header_formatted = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, header_formatted, statbuf.st_size); - header_formatted[statbuf.st_size] = '\0'; - close(fd); - } - } - else header_formatted = apr_pstrdup(r->pool, ""); - - body_formatted = apr_psprintf(r->pool, - "

Directory listing %s

\n", r->uri); - - if (conf->indexheader != NULL) - { - indexheaderpath = apr_psprintf(r->pool, "%s/%s", r->filename, - conf->indexheader); - fd = open(indexheaderpath, O_RDONLY); - if (fd != -1) - { - fstat(fd, &statbuf); - indexheadertext = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, indexheadertext, statbuf.st_size); - indexheadertext[statbuf.st_size] = '\0'; - close(fd); - - body_formatted = apr_pstrcat(r->pool, body_formatted, - indexheadertext, NULL); - } - } - - body_formatted = apr_pstrcat(r->pool, body_formatted, "

\n", NULL); - - if (r->unparsed_uri[1] != '\0') - body_formatted = apr_pstrcat(r->pool, body_formatted, - "\n", - NULL); - - n = scandir(r->filename, &namelist, 0, versionsort); - while (n--) - { - if ((namelist[n]->d_name[0] != '.') && - ((conf->indexheader == NULL) || - (strcmp(conf->indexheader, namelist[n]->d_name) != 0))) - { - d_namepath = apr_psprintf(r->pool, "%s/%s", r->filename, - namelist[n]->d_name); - stat(d_namepath, &statbuf); - - localtime_r(&(statbuf.st_mtime), &mtime_tm); - strftime(modified, sizeof(modified), - "", - &mtime_tm); - - if (S_ISDIR(statbuf.st_mode)) - temp = apr_psprintf(r->pool, - "" - "%s\n", - namelist[n]->d_name, statbuf.st_size, statbuf.st_mtime, - namelist[n]->d_name, - statbuf.st_size, modified); - else temp = apr_psprintf(r->pool, - "" - "%s\n", - namelist[n]->d_name, statbuf.st_size, statbuf.st_mtime, - namelist[n]->d_name, - statbuf.st_size, modified); - - body_formatted = apr_pstrcat(r->pool,body_formatted,temp,NULL); - } - - free(namelist[n]); - } - - free(namelist); - - body_formatted = apr_pstrcat(r->pool, body_formatted, "
[Parent directory]
%R%e %b %y
" - "%s/%ld
" - "%s%ld
\n", NULL); - - if (conf->format) - { - /* **** set up dynamic part of footer to go at end of body **** */ - - admin_formatted = make_admin_footer(r, conf, TRUE); - - /* **** try to find a footer file in this or parent directories **** */ - - /* first make a buffer big enough to hold path names we want to try */ - fd = -1; - s = malloc(strlen(r->filename) + strlen(conf->footfile)); - strcpy(s, r->filename); - - for (;;) - { - p = rindex(s, '/'); - if (p == NULL) break; /* failed to find one */ - - p[1] = '\0'; - strcat(p, conf->footfile); - - fd = open(s, O_RDONLY); - if (fd != -1) break; /* found one */ - - *p = '\0'; - } - - free(s); - - if (fd == -1) /* failed to find a footer, so use standard default */ - { - footer_formatted = apr_pstrdup(r->pool, ""); - } - else /* found a footer, so set up to use it */ - { - fstat(fd, &statbuf); - footer_formatted = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, footer_formatted, statbuf.st_size); - footer_formatted[statbuf.st_size] = '\0'; - close(fd); - } - } - else - { - admin_formatted = apr_pstrdup(r->pool, ""); - footer_formatted = apr_pstrdup(r->pool, ""); - } - - /* **** can now calculate the Content-Length and output headers **** */ - - length = strlen(head_formatted) + strlen(header_formatted) + - strlen(body_formatted) + strlen(admin_formatted) + - strlen(footer_formatted); - - ap_set_content_length(r, length); - ap_set_content_type(r, "text/html"); - - /* ** output the HTTP body (HTML Head+Body) ** */ - - ap_rputs(head_formatted, r); - ap_rputs(header_formatted, r); - ap_rputs(body_formatted, r); - ap_rputs(admin_formatted, r); - ap_rputs(footer_formatted, r); - - return OK; -} - -int http_downgrade(request_rec *r, mod_gridsite_cfg *conf) -{ - int i; - char *httpurl, *filetemplate, *cookievalue, *envname_i, - *grst_cred_i, expires_str[APR_RFC822_DATE_LEN]; - apr_uint64_t gridauthcookie; - apr_table_t *env; - apr_time_t expires_time; - apr_file_t *fp; - - /* create random cookie and gridauthcookie file */ - - if (apr_generate_random_bytes((char *) &gridauthcookie, - sizeof(gridauthcookie)) - != APR_SUCCESS) return HTTP_INTERNAL_SERVER_ERROR; - - filetemplate = apr_psprintf(r->pool, "%s/%016llxXXXXXX", - ap_server_root_relative(r->pool, - conf->authcookiesdir), - gridauthcookie); - - if (apr_file_mktemp(&fp, - filetemplate, - APR_CREATE | APR_WRITE | APR_EXCL, - r->pool) - != APR_SUCCESS) return HTTP_INTERNAL_SERVER_ERROR; - - expires_time = apr_time_now() + apr_time_from_sec(300); - /* onetime cookies are valid for only 5 mins! */ - - apr_file_printf(fp, "expires=%lu\ndomain=%s\npath=%s\nonetime=yes\n", - (time_t) apr_time_sec(expires_time), r->hostname, r->uri); - - for (i=0; ; ++i) - { - envname_i = apr_psprintf(r->pool, "GRST_CRED_%d", i); - if (grst_cred_i = (char *) - apr_table_get(r->connection->notes, envname_i)) - { - apr_file_printf(fp, "%s=%s\n", envname_i, grst_cred_i); - } - else break; /* GRST_CRED_i are numbered consecutively */ - } - - if (apr_file_close(fp) != APR_SUCCESS) - { - apr_file_remove(filetemplate, r->pool); /* try to clean up */ - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* send redirection header back to client */ - - cookievalue = rindex(filetemplate, '/'); - if (cookievalue != NULL) ++cookievalue; - else cookievalue = filetemplate; - - apr_rfc822_date(expires_str, expires_time); - - apr_table_add(r->headers_out, - apr_pstrdup(r->pool, "Set-Cookie"), - apr_psprintf(r->pool, - "GRID_AUTH_ONETIME=%s; " - "expires=%s; " - "domain=%s; " - "path=%s", - cookievalue, expires_str, r->hostname, r->uri)); - - httpurl = apr_pstrcat(r->pool, "http://", r->hostname, - ap_escape_uri(r->pool, r->uri), NULL); - apr_table_setn(r->headers_out, apr_pstrdup(r->pool, "Location"), httpurl); - - r->status = HTTP_MOVED_TEMPORARILY; - return OK; -} - -int http_put_method(request_rec *r, mod_gridsite_cfg *conf) -{ - char buf[2048]; - size_t length; - int retcode; - apr_file_t *fp; - - /* *** check if directory creation: PUT /.../ *** */ - - if ((r->unparsed_uri != NULL) && - (r->unparsed_uri[0] != '\0') && - (r->unparsed_uri[strlen(r->unparsed_uri) - 1] == '/')) - { - if (apr_dir_make(r->filename, APR_UREAD | APR_UWRITE | APR_UEXECUTE, - r->pool) != 0) return HTTP_INTERNAL_SERVER_ERROR; - - ap_set_content_length(r, 0); - ap_set_content_type(r, "text/html"); - return OK; - } - - /* *** otherwise assume trying to create a regular file *** */ - - if (apr_file_open(&fp, r->filename, APR_WRITE | APR_CREATE | APR_BUFFERED, - APR_UREAD | APR_UWRITE, r->pool) != 0) return HTTP_INTERNAL_SERVER_ERROR; - -// TODO: need to add Range: support at some point too - - retcode = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK); - if (retcode == OK) - { - if (ap_should_client_block(r)) - while ((length = ap_get_client_block(r, buf, sizeof(buf))) > 0) - if (apr_file_write(fp, buf, &length) != 0) - { - retcode = HTTP_INTERNAL_SERVER_ERROR; - break; - } - - ap_set_content_length(r, 0); - ap_set_content_type(r, "text/html"); - } - - if (apr_file_close(fp) != 0) return HTTP_INTERNAL_SERVER_ERROR; - - return retcode; -} - -int http_delete_method(request_rec *r, mod_gridsite_cfg *conf) -{ - if (remove(r->filename) != 0) return HTTP_FORBIDDEN; - - ap_set_content_length(r, 0); - ap_set_content_type(r, "text/html"); - - return OK; -} - -static int mod_gridsite_dir_handler(request_rec *r, mod_gridsite_cfg *conf) -/* - handler switch for directories -*/ -{ - /* *** is this a write method? only possible if GridSiteAuth on *** */ - - if (conf->auth) - { - if ((r->method_number == M_PUT) && - (conf->methods != NULL) && - (strstr(conf->methods, " PUT " ) != NULL)) - return http_put_method(r, conf); - - if ((r->method_number == M_DELETE) && - (conf->methods != NULL) && - (strstr(conf->methods, " DELETE ") != NULL)) - return http_delete_method(r, conf); - } - - /* *** directory listing? *** */ - - if ((r->method_number == M_GET) && (conf->indexes)) - return html_dir_list(r, conf); /* directory listing */ - - return DECLINED; /* *** nothing to see here, move along *** */ -} - -static int mod_gridsite_nondir_handler(request_rec *r, mod_gridsite_cfg *conf) -/* - one big handler switch for everything other than directories, since we - might be responding to MIME * / * for local PUT, MOVE, COPY and DELETE, - and GET inside ghost directories. -*/ -{ - char *downgradesize; - apr_off_t numericsize; - - /* *** is this a write method or HTTP downgrade? - only possible if GridSiteAuth on *** */ - - if (conf->auth) - { - if ((conf->downgrade) && - ((downgradesize = (char *) apr_table_get(r->headers_in, - "HTTP-Downgrade-Size")) != NULL) && - ((numericsize = (apr_off_t) atoll(downgradesize)) >= 0) && - -// TODO: what if we're pointing at a CGI or some dynamic content??? - (((r->method_number == M_GET) && (r->finfo.size >= numericsize)) - || (r->method_number == M_PUT)) && - - (strcasecmp(apr_table_get(r->subprocess_env, "HTTPS"), "on") == 0)) - return http_downgrade(r, conf); - - if ((r->method_number == M_PUT) && - (conf->methods != NULL) && - (strstr(conf->methods, " PUT " ) != NULL)) - return http_put_method(r, conf); - - if ((r->method_number == M_DELETE) && - (conf->methods != NULL) && - (strstr(conf->methods, " DELETE ") != NULL)) - return http_delete_method(r, conf); - } - - /* *** check if a special ghost admin CGI *** */ - - if (conf->adminfile && conf->adminuri && - (strlen(r->filename) > strlen(conf->adminfile) + 1) && - (strcmp(&(r->filename[strlen(r->filename) - strlen(conf->adminfile)]), - conf->adminfile) == 0) && - (r->filename[strlen(r->filename)-strlen(conf->adminfile)-1] == '/') && - ((r->method_number == M_POST) || - (r->method_number == M_GET))) - { - ap_internal_redirect(conf->adminuri, r); - return OK; - } - - /* *** finally look for .html files that we should format *** */ - - if ((conf->format) && /* conf->format set by GridSiteHtmlFormat on */ - (strlen(r->filename) > 5) && - (strcmp(&(r->filename[strlen(r->filename)-5]), ".html") == 0) && - (r->method_number == M_GET)) return html_format(r, conf); - - return DECLINED; /* *** nothing to see here, move along *** */ -} - -static void recurse4dirlist(char *dirname, time_t *dirs_time, - char *fulluri, int fullurilen, - char *encfulluri, int enclen, - apr_pool_t *pool, char **body, - int recurse_level) -/* try to find DN Lists in dir[] and its subdirs that match the fulluri[] - prefix. add blobs of HTML to body as they are found. */ -{ - char *unencname, modified[99], *oneline, *d_namepath; - DIR *oneDIR; - struct dirent *onedirent; - struct tm mtime_tm; - size_t length; - struct stat statbuf; - - if ((stat(dirname, &statbuf) != 0) || - (!S_ISDIR(statbuf.st_mode)) || - ((oneDIR = opendir(dirname)) == NULL)) return; - - if (statbuf.st_mtime > *dirs_time) *dirs_time = statbuf.st_mtime; - - while ((onedirent = readdir(oneDIR)) != NULL) - { - if (onedirent->d_name[0] == '.') continue; - - d_namepath = apr_psprintf(pool, "%s/%s", dirname, onedirent->d_name); - if (stat(d_namepath, &statbuf) != 0) continue; - - if (S_ISDIR(statbuf.st_mode) && (recurse_level < GRST_RECURS_LIMIT)) - recurse4dirlist(d_namepath, dirs_time, fulluri, - fullurilen, encfulluri, enclen, - pool, body, recurse_level + 1); - else if ((strncmp(onedirent->d_name, encfulluri, enclen) == 0) && - (onedirent->d_name[strlen(onedirent->d_name) - 1] != '~')) - { - unencname = GRSThttpUrlDecode(onedirent->d_name); - - if (strncmp(unencname, fulluri, fullurilen) == 0) - { - - if (statbuf.st_mtime > *dirs_time) - *dirs_time = statbuf.st_mtime; - - localtime_r(&(statbuf.st_mtime), &mtime_tm); - strftime(modified, sizeof(modified), - "%R%e %b %y", - &mtime_tm); - - oneline = apr_psprintf(pool, - "" - "%s" - "%ld%s\n", - &unencname[fullurilen], statbuf.st_size, - statbuf.st_mtime, unencname, - statbuf.st_size, modified); - - *body = apr_pstrcat(pool, *body, oneline, NULL); - } - - free(unencname); /* libgridsite doesnt use pools */ - } - } - - closedir(oneDIR); -} - -static int mod_gridsite_dnlistsuri_dir_handler(request_rec *r, - mod_gridsite_cfg *conf) -/* - virtual DN-list file lister: make all DN lists on the dn-lists - path of this server appear to be in the dn-lists directory itself - (ie where they appear in the DN lists path doesnt matter, as long - as their name matches) -*/ -{ - int enclen, fullurilen, fd; - char *fulluri, *encfulluri, *dn_list_ptr, *dirname, *unencname, - *body, *oneline, *p, *s, - *head_formatted, *header_formatted, *footer_formatted, - *permstr = NULL; - struct stat statbuf; - size_t length; - time_t dirs_time = 0; - GRSTgaclPerm perm = GRST_PERM_NONE; - - if (r->notes != NULL) - permstr = (char *) apr_table_get(r->notes, "GRST_PERM"); - - if (permstr != NULL) sscanf(permstr, "%d", &perm); - - fulluri = apr_psprintf(r->pool, "https://%s%s", - ap_get_server_name(r), conf->dnlistsuri); - fullurilen = strlen(fulluri); - - encfulluri = GRSThttpUrlEncode(fulluri); - enclen = strlen(encfulluri); - - if (conf->dnlists != NULL) p = conf->dnlists; - else p = getenv("GRST_DN_LISTS"); - - if (p == NULL) p = GRST_DN_LISTS; - dn_list_ptr = apr_pstrdup(r->pool, p); - - head_formatted = apr_psprintf(r->pool, - "Directory listing %s\n", r->uri); - - if (conf->format) - { - /* **** try to find a header file in this or parent directories **** */ - - /* first make a buffer big enough to hold path names we want to try */ - fd = -1; - s = malloc(strlen(r->filename) + strlen(conf->headfile) + 1); - strcpy(s, r->filename); - - for (;;) - { - p = rindex(s, '/'); - if (p == NULL) break; /* failed to find one */ - p[1] = '\0'; - strcat(p, conf->headfile); - - fd = open(s, O_RDONLY); - if (fd != -1) break; /* found one */ - - *p = '\0'; - } - - free(s); - - if (fd == -1) /* not found, so set up to output sensible default */ - { - header_formatted = apr_pstrdup(r->pool, ""); - } - else /* found a header file, so set up head and body to surround it */ - { - fstat(fd, &statbuf); - header_formatted = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, header_formatted, statbuf.st_size); - header_formatted[statbuf.st_size] = '\0'; - close(fd); - } - } - else header_formatted = apr_pstrdup(r->pool, ""); - - body = apr_psprintf(r->pool, - "

Directory listing %s

\n", r->uri); - - if ((r->uri)[1] != '\0') - body = apr_pstrcat(r->pool, body, - "\n", - NULL); - - while ((dirname = strsep(&dn_list_ptr, ":")) != NULL) - recurse4dirlist(dirname, &dirs_time, fulluri, fullurilen, - encfulluri, enclen, r->pool, &body, 0); - - if ((stat(r->filename, &statbuf) == 0) && - S_ISDIR(statbuf.st_mode) && - GRSTgaclPermHasWrite(perm)) - { - oneline = apr_psprintf(r->pool, - "\n" - "" - "\n", - r->uri, conf->adminfile); - - body = apr_pstrcat(r->pool, body, oneline, NULL); - } - - body = apr_pstrcat(r->pool, body, "
[Parent directory]
\n", NULL); - - free(encfulluri); /* libgridsite doesnt use pools */ - - if (conf->format) - { - /* **** try to find a footer file in this or parent directories **** */ - - /* first make a buffer big enough to hold path names we want to try */ - fd = -1; - s = malloc(strlen(r->filename) + strlen(conf->footfile)); - strcpy(s, r->filename); - - for (;;) - { - p = rindex(s, '/'); - if (p == NULL) break; /* failed to find one */ - - p[1] = '\0'; - strcat(p, conf->footfile); - - fd = open(s, O_RDONLY); - if (fd != -1) break; /* found one */ - - *p = '\0'; - } - - free(s); - - if (fd == -1) /* failed to find a footer, so use standard default */ - { - footer_formatted = apr_pstrdup(r->pool, ""); - } - else /* found a footer, so set up to use it */ - { - fstat(fd, &statbuf); - footer_formatted = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, footer_formatted, statbuf.st_size); - footer_formatted[statbuf.st_size] = '\0'; - close(fd); - } - } - else footer_formatted = apr_pstrdup(r->pool, ""); - - /* **** can now calculate the Content-Length and output headers **** */ - - length = strlen(head_formatted) + strlen(header_formatted) + - strlen(body) + strlen(footer_formatted); - - ap_set_content_length(r, length); - r->mtime = apr_time_from_sec(dirs_time); - ap_set_last_modified(r); - ap_set_content_type(r, "text/html"); - - /* ** output the HTTP body (HTML Head+Body) ** */ - ap_rputs(head_formatted, r); - ap_rputs(header_formatted, r); - ap_rputs(body, r); - ap_rputs(footer_formatted, r); - - return OK; -} - -static char *recurse4file(char *dir, char *file, apr_pool_t *pool, - int recurse_level) -/* try to find file[] in dir[]. try subdirs if not found. - return full path to first found version or NULL on failure */ -{ - char *fullfilename, *fulldirname; - struct stat statbuf; - DIR *dirDIR; - struct dirent *file_ent; - - /* try to find in current directory */ - - fullfilename = apr_psprintf(pool, "%s/%s", dir, file); - - if (stat(fullfilename, &statbuf) == 0) return fullfilename; - - /* maybe search in subdirectories */ - - if (recurse_level >= GRST_RECURS_LIMIT) return NULL; - - dirDIR = opendir(dir); - - if (dirDIR == NULL) return NULL; - - while ((file_ent = readdir(dirDIR)) != NULL) - { - if (file_ent->d_name[0] == '.') continue; - - fulldirname = apr_psprintf(pool, "%s/%s", dir, file_ent->d_name); - if ((stat(fulldirname, &statbuf) == 0) && - S_ISDIR(statbuf.st_mode) && - ((fullfilename = recurse4file(fulldirname, file, - pool, recurse_level + 1)) != NULL)) - { - closedir(dirDIR); - return fullfilename; - } - } - - closedir(dirDIR); - - return NULL; -} - -static int mod_gridsite_dnlistsuri_handler(request_rec *r, - mod_gridsite_cfg *conf) -/* - virtual DN-list file generator -*/ -{ - int fd; - char *fulluri, *encfulluri, *dn_list_ptr, *filename, *dirname, *p, - *buf; - struct stat statbuf; - - /* *** check if a special ghost admin CGI *** */ - - if (conf->adminfile && conf->adminuri && - (strlen(r->filename) > strlen(conf->adminfile) + 1) && - (strcmp(&(r->filename[strlen(r->filename) - strlen(conf->adminfile)]), - conf->adminfile) == 0) && - (r->filename[strlen(r->filename)-strlen(conf->adminfile)-1] == '/') && - ((r->method_number == M_POST) || - (r->method_number == M_GET))) - { - ap_internal_redirect(conf->adminuri, r); - return OK; - } - - fulluri = apr_psprintf(r->pool, "https://%s%s", - ap_get_server_name(r), r->uri); - - encfulluri = GRSThttpUrlEncode(fulluri); - - if (conf->dnlists != NULL) p = conf->dnlists; - else p = getenv("GRST_DN_LISTS"); - - if (p == NULL) p = GRST_DN_LISTS; - dn_list_ptr = apr_pstrdup(r->pool, p); - - while ((dirname = strsep(&dn_list_ptr, ":")) != NULL) - { - filename = recurse4file(dirname, encfulluri, r->pool, 0); - - if (filename == NULL) continue; - - fd = open(filename, O_RDONLY); - - if (fd == -1) continue; - - fstat(fd, &statbuf); - ap_set_content_length(r, (apr_off_t) statbuf.st_size); - r->mtime = apr_time_from_sec(statbuf.st_mtime); - ap_set_content_type(r, "text/plain"); - ap_set_last_modified(r); - - buf = apr_palloc(r->pool, statbuf.st_size + 1); - read(fd, buf, statbuf.st_size); - buf[statbuf.st_size] = '\0'; - - ap_rputs(buf, r); - - close(fd); - - return OK; - } - - return HTTP_NOT_FOUND; -} - -static void *create_gridsite_dir_config(apr_pool_t *p, char *path) -{ - mod_gridsite_cfg *conf = apr_palloc(p, sizeof(*conf)); - - if (path == NULL) /* set up server defaults */ - { - conf->auth = 0; /* GridSiteAuth on/off */ - conf->envs = 1; /* GridSiteEnvs on/off */ - conf->format = 0; /* GridSiteHtmlFormat on/off */ - conf->indexes = 0; /* GridSiteIndexes on/off */ - conf->indexheader = NULL; /* GridSiteIndexHeader File-value */ - conf->gridsitelink = 1; /* GridSiteLink on/off */ - conf->adminfile = apr_pstrdup(p, GRST_ADMIN_FILE); - /* GridSiteAdminFile File-value */ - conf->adminuri = NULL; /* GridSiteAdminURI URI-value */ - conf->helpuri = NULL; /* GridSiteHelpURI URI-value */ - conf->dnlists = NULL; /* GridSiteDNlists Search-path */ - conf->dnlistsuri = NULL; /* GridSiteDNlistsURI URI-value */ - conf->adminlist = NULL; /* GridSiteAdminList URI-value */ - conf->gsiproxylimit = 1; /* GridSiteGSIProxyLimit number */ - conf->unzip = NULL; /* GridSiteUnzip file-path */ - - conf->methods = apr_pstrdup(p, " GET "); - /* GridSiteMethods methods */ - - conf->editable = apr_pstrdup(p, " txt shtml html htm css js php jsp "); - /* GridSiteEditable types */ - - conf->headfile = apr_pstrdup(p, GRST_HEADFILE); - conf->footfile = apr_pstrdup(p, GRST_FOOTFILE); - /* GridSiteHeadFile and GridSiteFootFile file name */ - - conf->downgrade = 0; /* GridSiteDowngrade on/off */ - conf->authcookiesdir = apr_pstrdup(p, "gridauthcookies"); - /* GridSiteAuthCookiesDir dir-path */ - conf->soap2cgi = 0; /* GridSiteSoap2cgi on/off */ - } - else - { - conf->auth = UNSET; /* GridSiteAuth on/off */ - conf->envs = UNSET; /* GridSiteEnvs on/off */ - conf->format = UNSET; /* GridSiteHtmlFormat on/off */ - conf->indexes = UNSET; /* GridSiteIndexes on/off */ - conf->indexheader = NULL; /* GridSiteIndexHeader File-value */ - conf->gridsitelink = UNSET; /* GridSiteLink on/off */ - conf->adminfile = NULL; /* GridSiteAdminFile File-value */ - conf->adminuri = NULL; /* GridSiteAdminURI URI-value */ - conf->helpuri = NULL; /* GridSiteHelpURI URI-value */ - conf->dnlists = NULL; /* GridSiteDNlists Search-path */ - conf->dnlistsuri = NULL; /* GridSiteDNlistsURI URI-value */ - conf->adminlist = NULL; /* GridSiteAdminList URI-value */ - conf->gsiproxylimit = UNSET; /* GridSiteGSIProxyLimit number */ - conf->unzip = NULL; /* GridSiteUnzip file-path */ - conf->methods = NULL; /* GridSiteMethods methods */ - conf->editable = NULL; /* GridSiteEditable types */ - conf->headfile = NULL; /* GridSiteHeadFile file name */ - conf->footfile = NULL; /* GridSiteFootFile file name */ - conf->downgrade = UNSET; /* GridSiteDowngrade on/off */ - conf->authcookiesdir= NULL; /* GridSiteAuthCookiesDir dir-path */ - conf->soap2cgi = UNSET; /* GridSiteSoap2cgi on/off */ - } - - return conf; -} - -static void *merge_gridsite_dir_config(apr_pool_t *p, void *vserver, - void *vdirect) -/* merge directory with server-wide directory configs */ -{ - mod_gridsite_cfg *conf, *server, *direct; - - server = (mod_gridsite_cfg *) vserver; - direct = (mod_gridsite_cfg *) vdirect; - conf = apr_palloc(p, sizeof(*conf)); - - if (direct->auth != UNSET) conf->auth = direct->auth; - else conf->auth = server->auth; - - if (direct->envs != UNSET) conf->envs = direct->envs; - else conf->envs = server->envs; - - if (direct->format != UNSET) conf->format = direct->format; - else conf->format = server->format; - - if (direct->indexes != UNSET) conf->indexes = direct->indexes; - else conf->indexes = server->indexes; - - if (direct->gridsitelink != UNSET) conf->gridsitelink=direct->gridsitelink; - else conf->gridsitelink=server->gridsitelink; - - if (direct->indexheader != NULL) conf->indexheader = direct->indexheader; - else conf->indexheader = server->indexheader; - - if (direct->adminfile != NULL) conf->adminfile = direct->adminfile; - else conf->adminfile = server->adminfile; - - if (direct->adminuri != NULL) conf->adminuri = direct->adminuri; - else conf->adminuri = server->adminuri; - - if (direct->helpuri != NULL) conf->helpuri = direct->helpuri; - else conf->helpuri = server->helpuri; - - if (direct->dnlists != NULL) conf->dnlists = direct->dnlists; - else conf->dnlists = server->dnlists; - - if (direct->dnlistsuri != NULL) conf->dnlistsuri = direct->dnlistsuri; - else conf->dnlistsuri = server->dnlistsuri; - - if (direct->adminlist != NULL) conf->adminlist = direct->adminlist; - else conf->adminlist = server->adminlist; - - if (direct->gsiproxylimit != UNSET) - conf->gsiproxylimit = direct->gsiproxylimit; - else conf->gsiproxylimit = server->gsiproxylimit; - - if (direct->unzip != NULL) conf->unzip = direct->unzip; - else conf->unzip = server->unzip; - - if (direct->methods != NULL) conf->methods = direct->methods; - else conf->methods = server->methods; - - if (direct->editable != NULL) conf->editable = direct->editable; - else conf->editable = server->editable; - - if (direct->headfile != NULL) conf->headfile = direct->headfile; - else conf->headfile = server->headfile; - - if (direct->footfile != NULL) conf->footfile = direct->footfile; - else conf->footfile = server->footfile; - - if (direct->downgrade != UNSET) conf->downgrade = direct->downgrade; - else conf->downgrade = server->downgrade; - - if (direct->authcookiesdir != NULL) - conf->authcookiesdir = direct->authcookiesdir; - else conf->authcookiesdir = server->authcookiesdir; - - if (direct->soap2cgi != UNSET) conf->soap2cgi = direct->soap2cgi; - else conf->soap2cgi = server->soap2cgi; - - return conf; -} - -static const char *mod_gridsite_take1_cmds(cmd_parms *a, void *cfg, - const char *parm) -{ - int n; - char *p; - - if (strcasecmp(a->cmd->name, "GridSiteAdminFile") == 0) - { - if (index(parm, '/') != NULL) - return "/ not permitted in GridSiteAdminFile"; - - ((mod_gridsite_cfg *) cfg)->adminfile = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteAdminURI") == 0) - { - if (*parm != '/') return "GridSiteAdminURI must begin with /"; - - ((mod_gridsite_cfg *) cfg)->adminuri = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteHelpURI") == 0) - { - if (*parm != '/') return "GridSiteHelpURI must begin with /"; - - ((mod_gridsite_cfg *) cfg)->helpuri = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteDNlists") == 0) - { - ((mod_gridsite_cfg *) cfg)->dnlists = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteDNlistsURI") == 0) - { - if (*parm != '/') return "GridSiteDNlistsURI must begin with /"; - - if ((*parm != '\0') && (parm[strlen(parm) - 1] == '/')) - ((mod_gridsite_cfg *) cfg)->dnlistsuri = - apr_pstrdup(a->pool, parm); - else - ((mod_gridsite_cfg *) cfg)->dnlistsuri = - apr_pstrcat(a->pool, parm, "/", NULL); - } - else if (strcasecmp(a->cmd->name, "GridSiteAdminList") == 0) - { - ((mod_gridsite_cfg *) cfg)->adminlist = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteGSIProxyLimit") == 0) - { - n = -1; - - if ((sscanf(parm, "%d", &n) == 1) && (n >= 0)) - ((mod_gridsite_cfg *) cfg)->gsiproxylimit = n; - else return "GridSiteGSIProxyLimit must be a number >= 0"; - } - else if (strcasecmp(a->cmd->name, "GridSiteUnzip") == 0) - { - if (*parm != '/') return "GridSiteUnzip must begin with /"; - - ((mod_gridsite_cfg *) cfg)->unzip = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteMethods") == 0) - { - ((mod_gridsite_cfg *) cfg)->methods = - apr_psprintf(a->pool, " %s ", parm); - - for (p = ((mod_gridsite_cfg *) cfg)->methods; - *p != '\0'; - ++p) if (*p == '\t') *p = ' '; - } - else if (strcasecmp(a->cmd->name, "GridSiteEditable") == 0) - { - ((mod_gridsite_cfg *) cfg)->editable = - apr_psprintf(a->pool, " %s ", parm); - - for (p = ((mod_gridsite_cfg *) cfg)->editable; - *p != '\0'; - ++p) if (*p == '\t') *p = ' '; - } - else if (strcasecmp(a->cmd->name, "GridSiteHeadFile") == 0) - { - ((mod_gridsite_cfg *) cfg)->headfile = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteFootFile") == 0) - { - ((mod_gridsite_cfg *) cfg)->footfile = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteIndexHeader") == 0) - { - if (index(parm, '/') != NULL) - return "/ not permitted in GridSiteIndexHeader"; - - ((mod_gridsite_cfg *) cfg)->indexheader = - apr_pstrdup(a->pool, parm); - } - else if (strcasecmp(a->cmd->name, "GridSiteAuthCookiesDir") == 0) - { - if (index(parm, '/') != NULL) - return "/ not permitted in GridSiteAuthCookiesDir"; - - ((mod_gridsite_cfg *) cfg)->authcookiesdir = - apr_pstrdup(a->pool, parm); - } - - return NULL; -} - -static const char *mod_gridsite_flag_cmds(cmd_parms *a, void *cfg, - int flag) -{ - if (strcasecmp(a->cmd->name, "GridSiteAuth") == 0) - { - ((mod_gridsite_cfg *) cfg)->auth = flag; - } - else if (strcasecmp(a->cmd->name, "GridSiteEnvs") == 0) - { - ((mod_gridsite_cfg *) cfg)->envs = flag; - } - else if (strcasecmp(a->cmd->name, "GridSiteHtmlFormat") == 0) - { - ((mod_gridsite_cfg *) cfg)->format = flag; - } - else if (strcasecmp(a->cmd->name, "GridSiteIndexes") == 0) - { - ((mod_gridsite_cfg *) cfg)->indexes = flag; - } - else if (strcasecmp(a->cmd->name, "GridSiteLink") == 0) - { - ((mod_gridsite_cfg *) cfg)->gridsitelink = flag; - } - else if (strcasecmp(a->cmd->name, "GridSiteDowngrade") == 0) - { -// TODO: return error if try this on non-HTTPS virtual server - - ((mod_gridsite_cfg *) cfg)->downgrade = flag; - } - else if (strcasecmp(a->cmd->name, "GridSiteSoap2cgi") == 0) - { - ((mod_gridsite_cfg *) cfg)->soap2cgi = flag; - } - - return NULL; -} - -static const command_rec mod_gridsite_cmds[] = -{ -// TODO: need to check and document valid contexts for each command! - - AP_INIT_FLAG("GridSiteAuth", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - AP_INIT_FLAG("GridSiteEnvs", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - AP_INIT_FLAG("GridSiteHtmlFormat", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - AP_INIT_FLAG("GridSiteIndexes", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - AP_INIT_FLAG("GridSiteLink", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - - AP_INIT_TAKE1("GridSiteAdminFile", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "Ghost per-directory admin CGI"), - AP_INIT_TAKE1("GridSiteAdminURI", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "URI of real gridsite-admin.cgi"), - AP_INIT_TAKE1("GridSiteHelpURI", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "URI of Website Help pages"), - AP_INIT_TAKE1("GridSiteDNlists", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "DN Lists directories search path"), - AP_INIT_TAKE1("GridSiteDNlistsURI", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "URI of published DN lists"), - AP_INIT_TAKE1("GridSiteAdminList", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "URI of admin DN List"), - AP_INIT_TAKE1("GridSiteGSIProxyLimit", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "Max level of GSI proxy validity"), - AP_INIT_TAKE1("GridSiteUnzip", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "Absolute path to unzip command"), - - AP_INIT_RAW_ARGS("GridSiteMethods", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "permitted HTTP methods"), - AP_INIT_RAW_ARGS("GridSiteEditable", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "editable file extensions"), - AP_INIT_TAKE1("GridSiteHeadFile", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "filename of HTML header"), - AP_INIT_TAKE1("GridSiteFootFile", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "filename of HTML footer"), - AP_INIT_TAKE1("GridSiteIndexHeader", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "filename of directory header"), - - AP_INIT_FLAG("GridSiteDowngrade", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - AP_INIT_TAKE1("GridSiteAuthCookiesDir", mod_gridsite_take1_cmds, - NULL, OR_FILEINFO, "directory with Grid Auth Cookies"), - - AP_INIT_FLAG("GridSiteSoap2cgi", mod_gridsite_flag_cmds, - NULL, OR_FILEINFO, "on or off"), - {NULL} -}; - -static int mod_gridsite_first_fixups(request_rec *r) -{ - mod_gridsite_cfg *conf; - - if (r->finfo.filetype != APR_DIR) return DECLINED; - - conf = (mod_gridsite_cfg *) - ap_get_module_config(r->per_dir_config, &gridsite_module); - - /* we handle DN Lists as regular files, even if they also match - directory names */ - - if ((conf != NULL) && - (conf->dnlistsuri != NULL) && - (strncmp(r->uri, conf->dnlistsuri, strlen(conf->dnlistsuri)) == 0) && - (strcmp(r->uri, conf->dnlistsuri) != 0)) - { - r->finfo.filetype = APR_REG; - } - - return DECLINED; -} - -static int mod_gridsite_perm_handler(request_rec *r) -/* - Do authentication/authorization here rather than in the normal module - auth functions since the results of mod_ssl are available. - - We also publish environment variables here if requested by GridSiteEnv. -*/ -{ - int retcode = DECLINED, i, n; - char *dn, *p, envname[14], *grst_cred_0 = NULL, *dir_path, - *remotehost, s[99], *grst_cred_i, *file, *cookies, - *gridauthonetime, *cookiefile, oneline[1025], *key_i; - const char *content_type; - time_t now, notbefore, notafter; - apr_table_t *env; - apr_finfo_t cookiefile_info; - apr_file_t *fp; - GRSTgaclCred *cred = NULL, *cred_0 = NULL; - GRSTgaclUser *user = NULL; - GRSTgaclPerm perm = GRST_PERM_NONE; - GRSTgaclAcl *acl = NULL; - mod_gridsite_cfg *cfg; - - cfg = (mod_gridsite_cfg *) - ap_get_module_config(r->per_dir_config, &gridsite_module); - - if (cfg == NULL) return DECLINED; - - if ((cfg->auth == 0) && - (cfg->envs == 0)) - return DECLINED; /* if not turned on, look invisible */ - - env = r->subprocess_env; - - if ((p = (char *) apr_table_get(r->headers_in, "Cookie")) != NULL) - { - cookies = apr_pstrcat(r->pool, " ", p, NULL); - gridauthonetime = strstr(cookies, " GRID_AUTH_ONETIME="); - - if (gridauthonetime != NULL) - { - for (p = &gridauthonetime[19]; (*p != '\0') && (*p != ';'); ++p) - if (!isalnum(*p)) *p = '_'; - - cookiefile = apr_psprintf(r->pool, "%s/%s", - ap_server_root_relative(r->pool, - cfg->authcookiesdir), - &gridauthonetime[19]); - - if ((apr_stat(&cookiefile_info , cookiefile, - APR_FINFO_TYPE, r->pool) == APR_SUCCESS) && - (cookiefile_info.filetype == APR_REG) && - (apr_file_open(&fp, cookiefile, APR_READ, 0, r->pool) - == APR_SUCCESS)) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Open Grid Auth Cookie file %s", cookiefile); - - while (apr_file_gets(oneline, - sizeof(oneline), fp) == APR_SUCCESS) - { - p = index(oneline, '\n'); - if (p != NULL) *p = '\0'; - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "%s: %s", cookiefile, oneline); - - if ((strncmp(oneline, "expires=", 8) == 0) && - (apr_time_from_sec(atoll(&oneline[8])) < - apr_time_now())) - break; - else if ((strncmp(oneline, "domain=", 7) == 0) && - (strcmp(&oneline[7], r->hostname) != 0)) - break; /* exact needed in the version */ - else if ((strncmp(oneline, "path=", 5) == 0) && - (strcmp(&oneline[5], r->uri) != 0)) - break; - else if (strncmp(oneline, "onetime=yes", 11) == 0) - apr_file_remove(cookiefile, r->pool); - else if (strncmp(oneline, "GRST_CRED_", 10) == 0) - { - grst_cred_i = index(oneline, '='); - if (grst_cred_i == NULL) continue; - *grst_cred_i = '\0'; - ++grst_cred_i; - - i = atoi(&oneline[10]); - cred = GRSTx509CompactToCred(grst_cred_i); - - if (cred == NULL) continue; - - if ((i == 0) && (user == NULL)) - { - if (GRSTgaclCredGetDelegation(cred) - <= ((mod_gridsite_cfg *) cfg)->gsiproxylimit) - { - user = GRSTgaclUserNew(cred); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, - 0, r->server, - "Using identity %s from " - "GRID_AUTH_ONETIME", - grst_cred_i); - - if (((mod_gridsite_cfg *) cfg)->envs) - apr_table_setn(env, oneline, grst_cred_i); - } - } - else if ((i > 0) && (user != NULL)) - { - GRSTgaclUserAddCred(user, cred); - - if (((mod_gridsite_cfg *) cfg)->envs) - apr_table_set(env,oneline,grst_cred_i); - } - } - } - - apr_file_close(fp); - } - } - } - - /* do we need/have per-connection (SSL) cred variable(s)? */ - - if ((user == NULL) && - (r->connection->notes != NULL) && - ((grst_cred_0 = (char *) - apr_table_get(r->connection->notes, "GRST_CRED_0")) != NULL)) - { - if (((mod_gridsite_cfg *) cfg)->envs) - apr_table_setn(env, "GRST_CRED_0", grst_cred_0); - - cred_0 = GRSTx509CompactToCred(grst_cred_0); - if ((cred_0 != NULL) && - (GRSTgaclCredGetDelegation(cred_0) - <= ((mod_gridsite_cfg *) cfg)->gsiproxylimit)) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Using identity %s from SSL/TLS", grst_cred_0); - - user = GRSTgaclUserNew(cred_0); - - /* check for VOMS GRST_CRED_i too */ - - for (i=1; ; ++i) - { - snprintf(envname, sizeof(envname), "GRST_CRED_%d", i); - if (grst_cred_i = (char *) - apr_table_get(r->connection->notes,envname)) - { - if (((mod_gridsite_cfg *) cfg)->envs) - apr_table_setn(env, - apr_pstrdup(r->pool, envname), - grst_cred_i); - - if (cred = GRSTx509CompactToCred(grst_cred_i)) - GRSTgaclUserAddCred(user, cred); - } - else break; /* GRST_CRED_i are numbered consecutively */ - } - } - } - - if ((user != NULL) && ((mod_gridsite_cfg *) cfg)->dnlists) - GRSTgaclUserSetDNlists(user, ((mod_gridsite_cfg *) cfg)->dnlists); - - /* this checks for NULL arguments itself */ - if (GRSTgaclDNlistHasUser(((mod_gridsite_cfg *) cfg)->adminlist, user)) - perm = GRST_PERM_ALL; - else - { - remotehost = (char *) ap_get_remote_host(r->connection, - r->per_dir_config, REMOTE_DOUBLE_REV, NULL); - if ((remotehost != NULL) && (*remotehost != '\0')) - { - cred = GRSTgaclCredNew("dns"); - GRSTgaclCredAddValue(cred, "hostname", remotehost); - - if (user == NULL) user = GRSTgaclUserNew(cred); - else GRSTgaclUserAddCred(user, cred); - } - - acl = GRSTgaclAclLoadforFile(r->filename); - if (acl != NULL) perm = GRSTgaclAclTestUser(acl, user); - } - - apr_table_setn(r->notes, "GRST_PERM", apr_psprintf(r->pool, "%d", perm)); - - if (((mod_gridsite_cfg *) cfg)->envs) - { - apr_table_setn(env, "GRST_PERM", apr_psprintf(r->pool, "%d", perm)); - - if (((dir_path = apr_pstrdup(r->pool, r->filename)) != NULL) && - ((p = rindex(dir_path, '/')) != NULL)) - { - *p = '\0'; - apr_table_setn(env, "GRST_DIR_PATH", dir_path); - } - - if (((mod_gridsite_cfg *) cfg)->helpuri != NULL) - apr_table_setn(env, "GRST_HELP_URI", - ((mod_gridsite_cfg *) cfg)->helpuri); - - if (((mod_gridsite_cfg *) cfg)->adminfile != NULL) - apr_table_setn(env, "GRST_ADMIN_FILE", - ((mod_gridsite_cfg *) cfg)->adminfile); - - if (((mod_gridsite_cfg *) cfg)->editable != NULL) - apr_table_setn(env, "GRST_EDITABLE", - ((mod_gridsite_cfg *) cfg)->editable); - - if (((mod_gridsite_cfg *) cfg)->headfile != NULL) - apr_table_setn(env, "GRST_HEAD_FILE", - ((mod_gridsite_cfg *) cfg)->headfile); - - if (((mod_gridsite_cfg *) cfg)->footfile != NULL) - apr_table_setn(env, "GRST_FOOT_FILE", - ((mod_gridsite_cfg *) cfg)->footfile); - - if (((mod_gridsite_cfg *) cfg)->dnlists != NULL) - apr_table_setn(env, "GRST_DN_LISTS", - ((mod_gridsite_cfg *) cfg)->dnlists); - - if (((mod_gridsite_cfg *) cfg)->dnlistsuri != NULL) - apr_table_setn(env, "GRST_DN_LISTS_URI", - ((mod_gridsite_cfg *) cfg)->dnlistsuri); - - if (((mod_gridsite_cfg *) cfg)->adminlist != NULL) - apr_table_setn(env, "GRST_ADMIN_LIST", - ((mod_gridsite_cfg *) cfg)->adminlist); - - apr_table_setn(env, "GRST_GSIPROXY_LIMIT", - apr_psprintf(r->pool, "%d", - ((mod_gridsite_cfg *)cfg)->gsiproxylimit)); - - if (((mod_gridsite_cfg *) cfg)->unzip != NULL) - apr_table_setn(env, "GRST_UNZIP", - ((mod_gridsite_cfg *) cfg)->unzip); - - if (!(((mod_gridsite_cfg *) cfg)->gridsitelink)) - apr_table_setn(env, "GRST_NO_LINK", "1"); - } - - if (((mod_gridsite_cfg *) cfg)->auth) - { - /* *** Check HTTP method to decide which perm bits to check *** */ - - if (r->filename != NULL) - { - file = rindex(r->filename, '/'); - if (file != NULL) ++file; - else file = r->filename; - } - else file = NULL; - - content_type = r->content_type; - if ((content_type != NULL) && - (strcmp(content_type, DIR_MAGIC_TYPE) == 0) && - (((mod_gridsite_cfg *) cfg)->dnlistsuri != NULL) && - (strncmp(r->uri, - ((mod_gridsite_cfg *) cfg)->dnlistsuri, - strlen(((mod_gridsite_cfg *) cfg)->dnlistsuri)) == 0) && - (strlen(r->uri) > strlen(((mod_gridsite_cfg *) cfg)->dnlistsuri))) - content_type = "text/html"; - - if ( GRSTgaclPermHasNone(perm) || - - /* first two M_GET conditions make the subtle distinction - between .../ that maps to .../index.html (governed by - Read perm) or to dir list (governed by List perm); - third M_GET condition deals with typeless CGI requests */ - - ((r->method_number == M_GET) && - !GRSTgaclPermHasRead(perm) && - (content_type != NULL) && - (strcmp(content_type, DIR_MAGIC_TYPE) != 0)) || - - ((r->method_number == M_GET) && - !GRSTgaclPermHasList(perm) && - (content_type != NULL) && - (strcmp(content_type, DIR_MAGIC_TYPE) == 0)) || - - ((r->method_number == M_GET) && - !GRSTgaclPermHasRead(perm) && - (content_type == NULL)) || - - ((r->method_number == M_POST) && !GRSTgaclPermHasRead(perm) ) || - - (((r->method_number == M_PUT) || (r->method_number == M_DELETE)) && - !GRSTgaclPermHasWrite(perm) && - ((file == NULL) || (strcmp(file, GRST_ACL_FILE) != 0)) ) || - - (((r->method_number == M_PUT) || (r->method_number == M_DELETE)) && - !GRSTgaclPermHasAdmin(perm) && - (file != NULL) && - (strcmp(file, GRST_ACL_FILE) == 0) ) ) retcode = HTTP_FORBIDDEN; - } - - return retcode; -} - -int GRST_X509_check_issued_wrapper(X509_STORE_CTX *ctx,X509 *x,X509 *issuer) -/* We change the default callback to use our wrapper and discard errors - due to GSI proxy chains (ie where users certs act as CAs) */ -{ - int ret; - ret = X509_check_issued(issuer, x); - if (ret == X509_V_OK) - return 1; - - /* Non self-signed certs without signing are ok if they passed - the other checks inside X509_check_issued. Is this enough? */ - if ((ret == X509_V_ERR_KEYUSAGE_NO_CERTSIGN) && - (X509_NAME_cmp(X509_get_subject_name(issuer), - X509_get_subject_name(x)) != 0)) return 1; - - /* If we haven't asked for issuer errors don't set ctx */ - if (!(ctx->flags & X509_V_FLAG_CB_ISSUER_CHECK)) return 0; - - ctx->error = ret; - ctx->current_cert = x; - ctx->current_issuer = issuer; - return ctx->verify_cb(0, ctx); -} - -/* Later OpenSSL versions add a second pointer ... */ -int GRST_verify_cert_wrapper(X509_STORE_CTX *ctx, void *p) - -/* Earlier ones have a single argument ... */ -// int GRST_verify_cert_wrapper(X509_STORE_CTX *ctx) - -/* Before 0.9.7 we cannot change the check_issued callback directly in - the X509_STORE, so we must insert it in another callback that gets - called early enough */ -{ - ctx->check_issued = GRST_X509_check_issued_wrapper; - - return X509_verify_cert(ctx); -} - -int GRST_callback_SSLVerify_wrapper(int ok, X509_STORE_CTX *ctx) -{ - SSL *ssl = (SSL *) X509_STORE_CTX_get_app_data(ctx); - conn_rec *conn = (conn_rec *) SSL_get_app_data(ssl); - server_rec *s = conn->base_server; - SSLConnRec *sslconn = - (SSLConnRec *) ap_get_module_config(conn->conn_config, &ssl_module); - int errnum = X509_STORE_CTX_get_error(ctx); - int errdepth = X509_STORE_CTX_get_error_depth(ctx); - int returned_ok; - int first_non_ca; - - /* - * GSI Proxy user-cert-as-CA handling: - * we skip Invalid CA errors at this stage, since we will check this - * again at errdepth=0 for the full chain using GRSTx509CheckChain - */ - if (errnum == X509_V_ERR_INVALID_CA) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "Skip Invalid CA error in case a GSI Proxy"); - - sslconn->verify_error = NULL; - ok = TRUE; - errnum = X509_V_OK; - X509_STORE_CTX_set_error(ctx, errnum); - } - - /* - * New style GSI Proxy handling, with critical ProxyCertInfo - * extension: we use GRSTx509KnownCriticalExts() to check this - */ -#ifndef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION -#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 -#endif - if (errnum == X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION) - { - if (GRSTx509KnownCriticalExts(X509_STORE_CTX_get_current_cert(ctx)) - == GRST_RET_OK) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "GRSTx509KnownCriticalExts() accepts previously " - "Unhandled Critical Extension (GSI Proxy?)"); - - sslconn->verify_error = NULL; - ok = TRUE; - errnum = X509_V_OK; - X509_STORE_CTX_set_error(ctx, errnum); - } - } - - returned_ok = ssl_callback_SSLVerify(ok, ctx); - - /* in case ssl_callback_SSLVerify changed it */ - errnum = X509_STORE_CTX_get_error(ctx); - - if ((errdepth == 0) && (errnum == X509_V_OK)) - /* - * We've now got the last certificate - the identity being used for - * this connection. At this point we check the whole chain for valid - * CAs or, failing that, GSI-proxy validity using GRSTx509CheckChain. - */ - { - errnum = GRSTx509CheckChain(&first_non_ca, ctx); - - if (errnum != X509_V_OK) - { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "Invalid certificate chain reported by " - "GRSTx509CheckChain()"); - - sslconn->verify_error = X509_verify_cert_error_string(errnum); - ok = FALSE; - } - else - { - int i, lastcred; - STACK_OF(X509) *peer_certs; - const int maxcreds = 99; - const size_t credlen = 1024; - char creds[maxcreds][credlen+1], envname[14]; - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "Valid certificate" - " chain reported by GRSTx509CheckChain()"); - - /* - * Always put result of GRSTx509CompactCreds() into environment - */ - if (peer_certs = (STACK_OF(X509) *) X509_STORE_CTX_get_chain(ctx)) - { - if (GRSTx509CompactCreds(&lastcred, maxcreds, credlen, - (char *) creds, peer_certs, GRST_VOMS_DIR) == GRST_RET_OK) - { - for (i=0; i <= lastcred; ++i) - { - apr_table_setn(conn->notes, - apr_psprintf(conn->pool, "GRST_CRED_%d", i), - apr_pstrdup(conn->pool, creds[i])); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "store GRST_CRED_%d=%s", i, creds[i]); - } - } - /* free remaining dup'd certs? */ - } - } - } - - return returned_ok; -} - -static int mod_gridsite_server_post_config(apr_pool_t *pPool, - apr_pool_t *pLog, apr_pool_t *pTemp, server_rec *main_server) -{ - SSL_CTX *ctx; - SSLSrvConfigRec *sc; - server_rec *this_server; - - ap_add_version_component(pPool, - apr_psprintf(pPool, "mod_gridsite/%s", VERSION)); - - for (this_server = main_server; - this_server != NULL; - this_server = this_server->next) - { - sc = ap_get_module_config(this_server->module_config, &ssl_module); - - if ((sc != NULL) && - (sc->enabled) && - (sc->server != NULL) && - (sc->server->ssl_ctx != NULL)) - { - ctx = sc->server->ssl_ctx; - - /* in 0.9.7 we could set the issuer-checking callback directly */ -// ctx->cert_store->check_issued = GRST_X509_check_issued_wrapper; - - /* but in case 0.9.6 we do it indirectly with another wrapper */ - SSL_CTX_set_cert_verify_callback(ctx, - GRST_verify_cert_wrapper, - (void *) NULL); - - /* whatever version, we can set the SSLVerify wrapper properly */ - SSL_CTX_set_verify(ctx, ctx->verify_mode, - GRST_callback_SSLVerify_wrapper); - - if (main_server->loglevel >= APLOG_DEBUG) - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "Set mod_ssl verify callbacks to GridSite wrappers"); - } - } - - return OK; -} - -static void mod_gridsite_child_init(apr_pool_t *pPool, server_rec *pServer) -{ - GRSTgaclInit(); -} - -static int mod_gridsite_handler(request_rec *r) -{ - mod_gridsite_cfg *conf; - - conf = (mod_gridsite_cfg *) - ap_get_module_config(r->per_dir_config, &gridsite_module); - - if ((conf->dnlistsuri != NULL) && - (strncmp(r->uri, conf->dnlistsuri, strlen(conf->dnlistsuri)) == 0)) - { - if (strcmp(r->uri, conf->dnlistsuri) == 0) - return mod_gridsite_dnlistsuri_dir_handler(r, conf); - - return mod_gridsite_dnlistsuri_handler(r, conf); - } - - if (strcmp(r->handler, DIR_MAGIC_TYPE) == 0) - return mod_gridsite_dir_handler(r, conf); - - return mod_gridsite_nondir_handler(r, conf); -} - -static void register_hooks(apr_pool_t *p) -{ - /* set up the Soap2cgi input and output filters */ - - ap_hook_insert_filter(mod_gridsite_soap2cgi_insert, NULL, NULL, - APR_HOOK_MIDDLE); - - ap_register_output_filter(Soap2cgiFilterName, mod_gridsite_soap2cgi_out, - NULL, AP_FTYPE_RESOURCE); - -// ap_register_input_filter(Soap2cgiFilterName, mod_gridsite_soap2cgi_in, -// NULL, AP_FTYPE_RESOURCE); - - /* config and handler stuff */ - - ap_hook_post_config(mod_gridsite_server_post_config, NULL, NULL, - APR_HOOK_LAST); - ap_hook_child_init(mod_gridsite_child_init, NULL, NULL, APR_HOOK_MIDDLE); - - ap_hook_fixups(mod_gridsite_first_fixups,NULL,NULL,APR_HOOK_FIRST); - - ap_hook_fixups(mod_gridsite_perm_handler,NULL,NULL,APR_HOOK_REALLY_LAST); - - ap_hook_handler(mod_gridsite_handler, NULL, NULL, APR_HOOK_FIRST); -} - -module AP_MODULE_DECLARE_DATA gridsite_module = -{ - STANDARD20_MODULE_STUFF, - create_gridsite_dir_config, /* dir config creater */ - merge_gridsite_dir_config, /* dir merger */ - NULL, /* server config */ - NULL, /* merge server config */ - mod_gridsite_cmds, /* command apr_table_t */ - register_hooks /* register hooks */ -}; diff --git a/org.gridsite.core/src/mod_ssl-private.h b/org.gridsite.core/src/mod_ssl-private.h deleted file mode 100644 index 7b0b784..0000000 --- a/org.gridsite.core/src/mod_ssl-private.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - Copyright (c) 2003-4, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. -*/ - -/* - - Portions of this code are derived from Apache mod_ssl, and are covered - by the Apache Software License: - - * Copyright 2001-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*------------------------------------------------------------------* - * This program is part of GridSite: http://www.gridsite.org/ * - *------------------------------------------------------------------*/ - - -/* - * After 2.0.49, Apache mod_ssl has most of the mod_ssl structures defined - * in ssl_private.h, which is not installed along with httpd-devel (eg in - * the FC2 RPM.) This include file provides SIMPLIFIED structures for use - * by mod_gridsite: for example, pointers to unused structures are replaced - * by void * and some of the structures are truncated when only the early - * members are used. - * - * CLEARLY, THIS WILL BREAK IF THERE ARE MAJOR CHANGES TO ssl_private.h!!! - */ - -#include - -typedef enum { - SSL_SHUTDOWN_TYPE_UNSET, - SSL_SHUTDOWN_TYPE_STANDARD, - SSL_SHUTDOWN_TYPE_UNCLEAN, - SSL_SHUTDOWN_TYPE_ACCURATE -} ssl_shutdown_type_e; - -typedef struct { - SSL *ssl; - const char *client_dn; - X509 *client_cert; - ssl_shutdown_type_e shutdown_type; - const char *verify_info; - const char *verify_error; - int verify_depth; - int is_proxy; - int disabled; - int non_ssl_request; -} SSLConnRec; - -typedef struct { - void *sc; /* pointer back to server config */ - SSL_CTX *ssl_ctx; -} modssl_ctx_t; - -typedef struct { - void *mc; - unsigned int enabled; - unsigned int proxy_enabled; - const char *vhost_id; - int vhost_id_len; - int session_cache_timeout; - modssl_ctx_t *server; - modssl_ctx_t *proxy; -} SSLSrvConfigRec; - -extern module AP_MODULE_DECLARE_DATA ssl_module; diff --git a/org.gridsite.core/src/proxyput-example.c b/org.gridsite.core/src/proxyput-example.c deleted file mode 100644 index f0fe834..0000000 --- a/org.gridsite.core/src/proxyput-example.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - Copyright (c) 2002-4, Andrew McNab, University of Manchester - All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o 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. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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. -*/ - -/* - Change the hard-coded defaults below to your set up. -*/ - -#define LOCALPROXY "/tmp/x509up" -#define DELEGATIONURL "https://testing.hep.man.ac.uk/gridsite-delegation.cgi" -#define CAPATH "/etc/grid-security/certificates" -#define DELEGATIONID "1234567890" -#define EXPIREMINUTES 60 - -#ifndef VERSION -#define VERSION "0.0.0" -#endif - -#define _GNU_SOURCE - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "gridsite.h" - -#include "soapH.h" -#include "delegation.nsmap" - -int main(int argc, char *argv[]) -{ - char *reqtxt, *certtxt; - struct ns__putProxyResponse *unused; - struct soap soap_get, soap_put; - - ERR_load_crypto_strings (); - OpenSSL_add_all_algorithms(); - - soap_init(&soap_get); - - if (soap_ssl_client_context(&soap_get, - SOAP_SSL_DEFAULT, - LOCALPROXY, - "", - NULL, - CAPATH, - NULL)) - { - soap_print_fault(&soap_get, stderr); - return 1; - } - - soap_call_ns__getProxyReq(&soap_get, - DELEGATIONURL, /* HTTPS url of service */ - "", /* no password on proxy */ - DELEGATIONID, - &reqtxt); - - if (soap_get.error) - { - soap_print_fault(&soap_get, stderr); - return 1; - } - - if (GRSTx509MakeProxyCert(&certtxt, stderr, reqtxt, - LOCALPROXY, LOCALPROXY, EXPIREMINUTES) - != GRST_RET_OK) - { - return 1; - } - - soap_init(&soap_put); - - if (soap_ssl_client_context(&soap_put, - SOAP_SSL_DEFAULT, - LOCALPROXY, - "", - NULL, - CAPATH, - NULL)) - { - soap_print_fault(&soap_put, stderr); - return 1; - } - - soap_call_ns__putProxy(&soap_put, DELEGATIONURL, "", DELEGATIONID, - certtxt, unused); - if (soap_put.error) - { - soap_print_fault(&soap_put, stderr); - return 1; - } - - return 0; -} - diff --git a/org.gridsite.core/src/roffit b/org.gridsite.core/src/roffit deleted file mode 100755 index d1c7263..0000000 --- a/org.gridsite.core/src/roffit +++ /dev/null @@ -1,370 +0,0 @@ -#!/usr/bin/env perl -# -# roffit: convert man page source files to HTML -# -# Read an nroff file. Output a HTML file. -# -# This is a very simple script, but I use it on very simple man pages and I've -# found no other script that makes beautiful web pages. -# -my $version = "0.3"; # (14 November 2003) -# Author: Daniel Stenberg -# Please email me improvements. -# -# You're free to do whatever you want with this script. -# -# Changes: -# -# 0.3 - Daniel Fandrich brought: -# o deal with .lp lines -# o .TH needs no section portion anymore -# o added generator meta tag in the header -# -# 0.2 - fixed the name for the SH section -# - added links from all words within \fIthis\fP or \fBthis\fP -# that has the same text as a .SH or .IP. -# - -use strict; -#use warnings; - -my $InFH = \*STDIN; -my $OutFH = \*STDOUT; -my $debugFH = \*STDERR; - -my %manpage; -my @out; - -my $indentlevel=0; # logical levels, not columns -my @p; -my $within_tp; -my $standalone=1; # by default we make stand-alone HTML pages -my $pre; -my %anchor; # hash with all anchors - -while($ARGV[0]) { - if($ARGV[0] eq "--bare") { - # don't include headers and stuff - $standalone=0; - shift @ARGV; - } - else { - printf $debugFH "unknown option: %s\n", $ARGV[0] if($ARGV[0] ne "-h"); - print $debugFH "Usage: roffit [options] < infile > outfile\n", - "Options:\n", - " --bare Do not put in HTML, HEAD, BODY tags\n"; - exit; - } -} - -sub showp { - my @p = @_; - push @out, "\n

", @p; -} - -sub defaultcss { - print $OutFH < -P.level0 { - padding-left: 2em; -} - -P.level1 { - padding-left: 4em; -} - -P.level2 { - padding-left: 6em; -} - -span.emphasis { - font-style: italic; -} - -span.bold { - font-weight: bold; -} - -span.manpage { - font-weight: bold; -} - -h2.nroffsh { - background-color: #e0e0e0; -} - -span.nroffip { - font-weight: bold; - font-size: 120%; - font-family: monospace; -} - -p.roffit { - text-align: center; - font-size: 80%; -} - -ENDOFCSS - ; -} - -sub text2name { - my ($text) = @_; - $text =~ s/^ *([^ ]*).*/$1/g; - $text =~ s/[^a-zA-Z0-9-]//g; - return $text; -} - -# scan through the file and check for sections we should convert -# to proper links -sub linkfile { - my @new; - for(@out) { - my $line=$_; - my $l; - while($line =~ s/([^<]*)<\/span>/[]/) { - my ($style, $name)=($1, $2); - - $l = text2name($name); - - #printf $debugFH "$style - $name - %s - %d\n", - #$l, $anchor{$l}; - - my $link; - if($anchor{$l}) { - $link="$name"; - } - else { - $link="$name"; - } - $line =~ s/\[\]/$link/; - } - push @new, $line; - } - return @new; -} - -sub parsefile { - - while(<$InFH>) { - my $in = $_; - my $out; - # print $debugFH "DEBUG IN: $_"; - - $in =~ s/[\r\n]//g if(!$pre); # tear off newlines - - if($in =~ /^\.([^ \n]*)(.*)/) { - # this is a line starting with a dot, that means it is special - my ($keyword, $rest) = ($1, $2); - $out = ""; - - # cut off initial spaces - $rest =~ s/^ +//g; - - if($keyword eq "\\\"") { - # this is a comment, skip this line - } - elsif($keyword =~ /^TH$/i) { - # man page header: - # curl 1 "22 Oct 2003" "Curl 7.10.8" "Curl Manual" - # NAME SECTION DATE VERSION MANUAL - if($rest =~ /([^ ]*) (\d+) \"([^\"]*)\" \"([^\"]*)\"(\"([^\"]*)\")?/) { - # strict matching only so far - $manpage{'name'} = $1; - $manpage{'section'} = $2; - $manpage{'date'} = $3; - $manpage{'version'} = $4; - $manpage{'manual'} = $6; - } - } - elsif($keyword =~ /^SH$/i) { - # Section Header - showp(@p); - @p=""; - if($pre) { - push @out, "\n"; - $pre = 0; - } - - my $name = text2name($rest); - $anchor{$name}=1; - - $rest =~ s/\"//g; # cut off quotes - $rest =~ s//>/g; - $out = "

$rest

"; - $indentlevel=0; - $within_tp=0; - } - elsif(($keyword =~ /^B$/i) || ($keyword =~ /^BI$/i)) { - # Make B and BI the same for simplicity - $rest =~ s/\"//g; # cut off quotes - $rest =~ s//>/g; - push @p, "$rest "; - } - elsif($keyword =~ /^I$/i) { - $rest =~ s/\"//g; # cut off quotes - $rest =~ s//>/g; - push @p, "$rest "; - } - elsif($keyword =~ /^RS$/i) { - # the start of another indent-level. for inlined tables - # within an "IP" - showp(@p); - @p=""; - $indentlevel++; - } - elsif($keyword =~ /^RE$/i) { - # end of the RS section - showp(@p); - @p=""; - $indentlevel--; - } - elsif($keyword =~ /^NF$/i) { - # We let nf start a
 section
-                showp(@p);
-                @p="";
-                push @out, "
\n";
-                $pre=1
-            }
-            elsif($keyword =~ /^TP$/i) {
-                # Used within an "RS" section to make a new line. The first
-                # TP as a column indicator, but we decide to do that
-                # controlling in the CSS instead.
-                $within_tp=1;
-                showp(@p);
-                @p="";                
-            }
-            elsif($keyword =~ /^IP$/i) {
-                # start of a new paragraph coming up
-                showp(@p);
-                @p="";
-
-                my $name= text2name($rest);
-                $anchor{$name}=1;
-
-                $rest =~ s/\"//g; # cut off quotes
-                $rest =~ s//>/g;
-                
-                $indentlevel-- if ($indentlevel);
-                push @p, "$rest ";
-                # make this a single-line title
-                showp(@p);
-                @p="";
-                $indentlevel++;
-                $within_tp=0;
-            }
-            elsif($keyword =~ /^ad$/i) {
-                showp(@p);
-                @p="";
-            }
-            elsif($keyword =~ /^sp$/i) {
-                showp(@p);
-                @p="";
-            }
-            elsif($keyword =~ /^lp$/i) {
-                # marks end of a paragraph
-                showp(@p);
-                @p="";
-            }
-            elsif($keyword =~ /^pp$/i) {
-                # PP ends a TP section, but some TP sections don't use it
-                $within_tp=0;
-            }
-            elsif($keyword =~ /^so$/i) {
-                # This keyword refers to a different man page, named in the
-                # $rest.
-                # We don't support this
-                push @out, "See the $rest man page.\n";
-            }
-            elsif($keyword =~ /^BR$/i) {
-                # I'm not sure what this does exactly, but this is commonly
-                # used to include pointers to other man pages. Let's assume
-                # it only does that for now.
-                # blabla (3)
-                # or "blabla (3)"
-                # or strcmp "(3), " strcasecmp "(3)"
-                # etc
-                
-                $rest =~ s/\"//g; # cut off quotes
-                my @all = split /,/, $rest;
-                for(@all) {
-                    if(/([^ ]*) *\((\d+)\)/) {
-                        # TODO: this looks like a man page, check if there's a
-                        # HTML file for it and if so make a link to it
-                    }
-
-                    push @p, "$_ ";
-                }
-            }
-            else {
-                showp(@p);
-                print $debugFH "ALERT: unknown keyword \"$keyword\"\n";
-            }
-        }
-        else {
-            # text line, decode \-stuff
-            my $txt = $in;
-
-            $txt =~ s//>/g;
-            $txt =~ s/\\&//g; # cut off \&
-            $txt =~ s/\\fI//g;
-            $txt =~ s/\\fB//g;
-            $txt =~ s/\\fP/<\/span>/g;
-            $txt =~ s/\\//g;
-
-            if($txt =~ /^[ \t\r\n]*$/) {
-                # no contents, marks end of a paragraph
-                showp(@p);
-                @p="";
-            }
-            else {
-                $txt =~ s/^ /\ \;/g;
-                push @p, "$txt ";
-            }
-            $out ="";
-        }
-
-        if($out) {
-            push @out, $out;
-   #         print $debugFH "DEBUG OUT: $out\n";
-        }
-        else {
-   #         print $debugFH "DEBUG OUT: [withheld]\n";
-        }
-    }
-    showp(@p);
-}
-
-parsefile();
-
-my @conv = linkfile();
-
-my $title=sprintf("%s man page",
-                  $manpage{'name'}?$manpage{'name'}:"secret");
-
-if($standalone) {
-    print $OutFH <
-$title
-
-MOO
-    ;
-    defaultcss();
-    print "\n";
-}
-
-print $OutFH @conv;
-print $OutFH <
- This HTML page was made with roffit.
-ROFFIT
-    ;
-
-if($standalone) {
-    print "\n";
-}
diff --git a/org.gridsite.core/src/showx509exts.c b/org.gridsite.core/src/showx509exts.c
deleted file mode 100644
index d37dff4..0000000
--- a/org.gridsite.core/src/showx509exts.c
+++ /dev/null
@@ -1,117 +0,0 @@
-
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "gridsite.h"
-
-#define MAXTAG 500
-                                 
-main()
-{
-   X509   *cert, *tmpcert;
-   STACK_OF(X509) *certstack = sk_X509_new_null();
-   FILE   *fp;
-   struct vomsdata *vd;
-   int    i, j, vomserror, i1, i2, j1, j2, lastobject;
-   X509_EXTENSION *ex;
-   ASN1_OBJECT *asnobject;
-   char s[80], *t;
-   ASN1_OCTET_STRING *asndata;
-   BIO *out;
-   unsigned char *p, *op, *tot, *p1, *p2, *q, *oq;
-   long len1, length1, len2, length2;
-   int tag,xclass,ret=0;
-   struct GRSTasn1TagList taglist[MAXTAG+1];
-   int lasttag=-1, itag;
-   
- 
-   OpenSSL_add_all_algorithms();
-   ERR_load_crypto_strings();
-//   seed_prng();
-   
-//   fp = fopen("proxy-with-voms", "r");
-   fp = fopen("/tmp/x509up_u300", "r");
-   
-   cert = PEM_read_X509(fp, NULL, NULL, NULL);
-      
-   fclose(fp);
-
-   out=BIO_new(BIO_s_file());                                                                                        
-   BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
-        
-   for (i = 0; i < X509_get_ext_count(cert); ++i)
-      {
-        lasttag=-1;
-      
-        ex = X509_get_ext(cert, i);
-                          
-        OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ex), 1);        
-        printf("%d OID=%s\n", i, s);
-        
-        asnobject = X509_EXTENSION_get_object(ex);
-        asndata = X509_EXTENSION_get_data(ex);
-
-        p1 = ASN1_STRING_data(asndata);
-        p = p1;
-        length1 = ASN1_STRING_length(asndata);
-              
-        GRSTasn1ParseDump(out, p1, length1, taglist, MAXTAG, &lasttag);
-
-{
-        int n, tag, xclass;
-        unsigned char *q, buf[100];
-        const unsigned char *dn, hash[EVP_MAX_MD_SIZE];
-        ASN1_OBJECT *obj = NULL;
-        const EVP_MD *m;
-        EVP_MD_CTX ctx;
-   
-        itag = GRSTasn1SearchTaglist(taglist, &lasttag, 
-               "-1-1-1-1-2-1-1-1-1-1-1-1");
-               
-        X509_NAME *xname;
-        
-        q = &p[taglist[itag].start];
-        
-        d2i_ASN1_OBJECT(&obj, &q, taglist[itag].length + 
-                                  taglist[itag].headerlength);
-
-        n  = OBJ_obj2nid(obj);
-        dn = OBJ_nid2sn(n);
-                         
-//        dn = X509_NAME_oneline(xname,NULL,0);
-        
-        printf("n=%d dn=%s obj2txt=%s\n", n, dn, OBJ_obj2txt(NULL,0,obj,1));
-
-        GRSTasn1GetX509Name(buf, 99, "-1-1-1-1-2-1-1-1-1-%d-1-%d", p1, taglist, &lasttag);
-        printf("%s\n", buf);
-        GRSTasn1GetX509Name(buf, 99, "-1-1-1-1-3-1-1-1-%d-1-%d", p1, taglist, &lasttag);
-        printf("%s\n", buf);
-        
-/*        
-        m = EVP_md5();
-        EVP_DigestInit(&ctx, m); 
-        EVP_DigestUpdate(&ctx, delegation_id, strlen(delegation_id));
-        EVP_DigestFinal(&ctx, hash, &delegation_id_len);
- */      
-}              
-
-/*       
-        itag = GRSTasn1SearchTaglist(taglist, &lasttag,
-                                     "1-1-1-1-1-7-1-2-1-2-1");
-                                    
-        printf("tag=%d %s %d %.*s\n",
-               itag, taglist[itag].treecoords, taglist[itag].tag,
-               taglist[itag].length, 
-               &p[taglist[itag].start+taglist[itag].headerlength]);
-*/
-      }
-}
diff --git a/org.gridsite.core/src/urlencode.c b/org.gridsite.core/src/urlencode.c
deleted file mode 100644
index bea36a9..0000000
--- a/org.gridsite.core/src/urlencode.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-   Copyright (c) 2002-3, Andrew McNab, University of Manchester
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or
-   without modification, are permitted provided that the following
-   conditions are met:
-
-     o Redistributions of source code must retain the above
-       copyright notice, this list of conditions and the following
-       disclaimer. 
-     o 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. 
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-   CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR 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.
-*/
-
-/*---------------------------------------------------------------*
- * For more about GridSite: http://www.gridsite.org/             *
- *---------------------------------------------------------------*/
-
-#include 
-#include 
-
-#include "gridsite.h"
-
-int main(int argn, char *argv[])
-{
-  int    i;
-
-  if (argn == 1)
-    {
-      puts("urlencode [-m|-d] string-to-encode-or-decode");
-      return 0;
-    }
-
-  if      (strcmp(argv[1], "-d") == 0) /* decode */
-   for (i = 2; i < argn; ++i) 
-      {
-        if (i > 2) fputs(" ", stdout);
-        fputs(GRSThttpUrlDecode(argv[i]), stdout);
-      }
-  else if (strcmp(argv[1], "-m") == 0) /* mild encode */
-   for (i = 2; i < argn; ++i) 
-      {
-        if (i > 2) fputs("%20", stdout);
-        fputs(GRSThttpUrlMildencode(argv[i]), stdout);
-      }
-  else /* standard encode */
-   for (i = 1; i < argn; ++i) 
-      {
-        if (i > 1) fputs("%20", stdout);
-        fputs(GRSThttpUrlEncode(argv[i]), stdout);
-      }
-
-  puts("");
-
-  return 0;
-}
-- 
1.8.2.3