DIST_SUBDIRS = doc schemas configs shibsp shibd adfs util apache nsapi_shib fastcgi odbc-store memcache-store selinux
if DX_COND_doc
-all-local: shibboleth.spec pkginfo doxygen-doc
-APIDOCS = doc/api
+all-local: doxygen-doc
else
-all-local: shibboleth.spec pkginfo
+all-local:
endif
-install-data-hook:
- rm -rf $(DESTDIR)$(datadir)/doc/@PACKAGE@/api
- cp -r doc/api $(DESTDIR)$(datadir)/doc/@PACKAGE@
-
dist-hook:
rm -rf `find $(distdir)/isapi_shib -name .svn`
rm -rf `find $(distdir)/doc/api -name .svn`
-shibboleth.spec: shibboleth.spec.in Makefile
- rm -f $@.tmp
- sed < $@.in > $@.tmp \
- -e 's:@-VERSION-@:${VERSION}:'
- mv $@.tmp $@
-
-pkginfo: pkginfo.in Makefile
- rm -f $@.tmp
- sed < $@.in > $@.tmp \
- -e 's:@-VERSION-@:${VERSION}:'
- mv $@.tmp $@
+GENFILES = shibboleth.spec pkginfo Portfile
EXTRA_DIST = $(DX_CONFIG) \
- $(APIDOCS) \
isapi_shib \
Shibboleth.sln \
libtool.m4 \
acx_pthread.m4 \
depcomp \
config_win32.h \
- shibboleth.spec.in \
- shibboleth.spec \
- pkginfo.in \
- pkginfo \
+ $(GENFILES) \
+ $(GENFILES:%=%.in) \
depend \
postinstall
-
-DISTCLEANFILES = shibboleth.spec pkginfo
build_triplet = @build@
host_triplet = @host@
DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in $(srcdir)/config.h.in \
- $(srcdir)/doxygen.am $(top_srcdir)/configure config.guess \
- config.sub depcomp install-sh ltmain.sh missing
+ $(srcdir)/Makefile.in $(srcdir)/Portfile.in \
+ $(srcdir)/config.h.in $(srcdir)/doxygen.am \
+ $(srcdir)/pkginfo.in $(srcdir)/shibboleth.spec.in \
+ $(top_srcdir)/configure config.guess config.sub depcomp \
+ install-sh ltmain.sh missing
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/libtool.m4 \
configure.lineno configure.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
-CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_FILES = shibboleth.spec pkginfo Portfile
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
MOSTLYCLEANFILES = $(DX_CLEANFILES)
SUBDIRS = $(WANT_SUBDIRS)
DIST_SUBDIRS = doc schemas configs shibsp shibd adfs util apache nsapi_shib fastcgi odbc-store memcache-store selinux
-@DX_COND_doc_TRUE@APIDOCS = doc/api
+GENFILES = shibboleth.spec pkginfo Portfile
EXTRA_DIST = $(DX_CONFIG) \
- $(APIDOCS) \
isapi_shib \
Shibboleth.sln \
libtool.m4 \
acx_pthread.m4 \
depcomp \
config_win32.h \
- shibboleth.spec.in \
- shibboleth.spec \
- pkginfo.in \
- pkginfo \
+ $(GENFILES) \
+ $(GENFILES:%=%.in) \
depend \
postinstall
-DISTCLEANFILES = shibboleth.spec pkginfo
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
distclean-hdr:
-rm -f config.h stamp-h1
+shibboleth.spec: $(top_builddir)/config.status $(srcdir)/shibboleth.spec.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+pkginfo: $(top_builddir)/config.status $(srcdir)/pkginfo.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+Portfile: $(top_builddir)/config.status $(srcdir)/Portfile.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
mostlyclean-libtool:
-rm -f *.lo
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
- $(mkdir_p) $(distdir)/doc
+ $(mkdir_p) $(distdir)/.
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
info-am:
install-data-am:
- @$(NORMAL_INSTALL)
- $(MAKE) $(AM_MAKEFLAGS) install-data-hook
install-exec-am:
distclean distclean-generic distclean-hdr distclean-libtool \
distclean-recursive distclean-tags distcleancheck distdir \
distuninstallcheck dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am \
- install-data-hook install-exec install-exec-am install-info \
- install-info-am install-man install-strip installcheck \
- installcheck-am installdirs installdirs-am maintainer-clean \
- maintainer-clean-generic maintainer-clean-recursive \
- mostlyclean mostlyclean-generic mostlyclean-libtool \
- mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \
- uninstall uninstall-am uninstall-info-am
+ install install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ maintainer-clean-recursive mostlyclean mostlyclean-generic \
+ mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am uninstall-info-am
@DX_COND_doc_TRUE@@DX_COND_ps_TRUE@doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
@DX_COND_doc_TRUE@ rm -rf @DX_DOCDIR@
@DX_COND_doc_TRUE@ $(DX_ENV) DX_INCLUDE=$(DX_INCLUDE) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
-@DX_COND_doc_TRUE@all-local: shibboleth.spec pkginfo doxygen-doc
-@DX_COND_doc_FALSE@all-local: shibboleth.spec pkginfo
-
-install-data-hook:
- rm -rf $(DESTDIR)$(datadir)/doc/@PACKAGE@/api
- cp -r doc/api $(DESTDIR)$(datadir)/doc/@PACKAGE@
+@DX_COND_doc_TRUE@all-local: doxygen-doc
+@DX_COND_doc_FALSE@all-local:
dist-hook:
rm -rf `find $(distdir)/isapi_shib -name .svn`
rm -rf `find $(distdir)/doc/api -name .svn`
-
-shibboleth.spec: shibboleth.spec.in Makefile
- rm -f $@.tmp
- sed < $@.in > $@.tmp \
- -e 's:@-VERSION-@:${VERSION}:'
- mv $@.tmp $@
-
-pkginfo: pkginfo.in Makefile
- rm -f $@.tmp
- sed < $@.in > $@.tmp \
- -e 's:@-VERSION-@:${VERSION}:'
- mv $@.tmp $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
--- /dev/null
+PortSystem 1.0
+
+name shibboleth
+version 2.2.1
+categories security www shibboleth
+maintainers scantor snc
+description Shibboleth Native Service Provider
+long_description Standards-based attribute-based Web SSO system
+homepage http://shibboleth.internet2.edu/
+master_sites http://shibboleth.internet2.edu/downloads/${name}/cppsp/${version}/
+distname ${name}-sp-${version}
+worksrcdir ${name}-${version}
+checksums sha1 @CHECKSUM@
+
+depends_lib port:opensaml \
+ port:xmltooling \
+ port:xercesc \
+ port:xml-security-c \
+ port:log4shib
+
+pre-fetch {
+ set status 0
+ if {[catch {exec ${prefix}/bin/curl --version | grep SSL} results]} {
+ if {[lindex $::errorCode 0] eq "CHILDSTATUS"} {
+ set status [lindex $::errorCode 2]
+ } else {
+ set status [lindex $::errorCode 3]
+ }
+ }
+ if {${status} != 0} {
+ return -code error "\n
+ ${name} requires curl to be installed with SSL support.
+ Please deactivate your current curl installation and
+ install the proper version of curl:
+ sudo port deactivate curl
+ sudo port install curl +ssl\n"
+ }
+}
+
+configure.args --with-xmltooling=${prefix} \
+ --with-opensaml=${prefix} \
+ --with-xerces=${prefix} \
+ --with-xmlsec=${prefix} \
+ --with-log4shib=${prefix}
+
+variant odbc {
+ depends_lib-append port:unixODBC
+ configure.args-append --enable-odbc
+}
+
+destroot.keepdirs ${destroot}${prefix}/var/log/${name} ${destroot}${prefix}/var/log/httpd ${destroot}${prefix}/var/run/${name}
+
+destroot.args NOKEYGEN=1
+
+post-destroot {
+ eval file delete [glob ${destroot}${prefix}/etc/${name}/*.logger]
+ eval file delete [glob ${destroot}${prefix}/etc/${name}/*.html]
+ eval file delete [glob ${destroot}${prefix}/etc/${name}/*.xml]
+ eval file delete [glob ${destroot}${prefix}/etc/${name}/shibd-*]
+ eval file delete [glob ${destroot}${prefix}/lib/${name}/*.la]
+}
+
+startupitem.create yes
+startupitem.name shibd
+startupitem.executable ${prefix}/sbin/shibd -F -f -p ${prefix}/var/run/${name}/shibd.pid
+
+livecheck.check regex
+livecheck.url http://shibboleth.internet2.edu/downloads/shibboleth/cppsp/latest/mac/ports/shibboleth/shibboleth/Portfile
+livecheck.regex "version *(\\d+\\.\\d+(\\.\\d+)?)"
--- /dev/null
+PortSystem 1.0
+
+name @PACKAGE@
+version @PACKAGE_VERSION@
+categories security www shibboleth
+maintainers scantor snc
+description Shibboleth Native Service Provider
+long_description Standards-based attribute-based Web SSO system
+homepage http://shibboleth.internet2.edu/
+master_sites http://shibboleth.internet2.edu/downloads/${name}/cppsp/${version}/
+distname ${name}-sp-${version}
+worksrcdir ${name}-${version}
+checksums sha1 @CHECKSUM@
+
+depends_lib port:opensaml \
+ port:xmltooling \
+ port:xercesc \
+ port:xml-security-c \
+ port:log4shib
+
+pre-fetch {
+ set status 0
+ if {[catch {exec ${prefix}/bin/curl --version | grep SSL} results]} {
+ if {[lindex $::errorCode 0] eq "CHILDSTATUS"} {
+ set status [lindex $::errorCode 2]
+ } else {
+ set status [lindex $::errorCode 3]
+ }
+ }
+ if {${status} != 0} {
+ return -code error "\n
+ ${name} requires curl to be installed with SSL support.
+ Please deactivate your current curl installation and
+ install the proper version of curl:
+ sudo port deactivate curl
+ sudo port install curl +ssl\n"
+ }
+}
+
+configure.args --with-xmltooling=${prefix} \
+ --with-opensaml=${prefix} \
+ --with-xerces=${prefix} \
+ --with-xmlsec=${prefix} \
+ --with-log4shib=${prefix}
+
+variant odbc {
+ depends_lib-append port:unixODBC
+ configure.args-append --enable-odbc
+}
+
+destroot.keepdirs ${destroot}${prefix}/var/log/${name} ${destroot}${prefix}/var/log/httpd ${destroot}${prefix}/var/run/${name}
+
+destroot.args NOKEYGEN=1
+
+post-destroot {
+ eval file delete [glob ${destroot}${prefix}/etc/${name}/*.logger]
+ eval file delete [glob ${destroot}${prefix}/etc/${name}/*.html]
+ eval file delete [glob ${destroot}${prefix}/etc/${name}/*.xml]
+ eval file delete [glob ${destroot}${prefix}/etc/${name}/shibd-*]
+ eval file delete [glob ${destroot}${prefix}/lib/${name}/*.la]
+}
+
+startupitem.create yes
+startupitem.name shibd
+startupitem.executable ${prefix}/sbin/shibd -F -f -p ${prefix}/var/run/${name}/shibd.pid
+
+livecheck.check regex
+livecheck.url http://shibboleth.internet2.edu/downloads/shibboleth/cppsp/latest/mac/ports/shibboleth/shibboleth/Portfile
+livecheck.regex "version *(\\d+\\.\\d+(\\.\\d+)?)"
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Server Modules", "Server Modules", "{26BA8F84-6E42-41FA-9B13-5D3F4B5B2050}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{96AE4FC9-45EF-4C18-9F3B-EDA439E26E4C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utilities", "Utilities", "{FED80230-119E-4B2F-9F53-D2660A5F022B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fastcgi", "fastcgi", "{8E1AF2CF-24E1-4983-8681-394D89DF9AD2}"
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "isapi_shib", "isapi_shib\isapi_shib.vcproj", "{87C25D4E-8D19-4513-B0BA-BC668BC2DEE3}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F7} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F7}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_shib13", "apache\mod_shib13.vcproj", "{D243B43E-728E-4F32-BDFF-B3A897037C6D}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F7} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F7}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_shib20", "apache\mod_shib20.vcproj", "{68E9568B-476C-4289-B93C-893432378ADC}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F7} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F7}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsapi_shib", "nsapi_shib\nsapi_shib.vcproj", "{1396D80A-8672-4224-9B02-95F3F4207CDB}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F7} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F7}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_shib22", "apache\mod_shib22.vcproj", "{B44C0852-83B8-4FB2-A86E-097C9C8256D0}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F7} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F7}
EndProjectSection
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Server Modules", "Server Modules", "{26BA8F84-6E42-41FA-9B13-5D3F4B5B2050}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{96AE4FC9-45EF-4C18-9F3B-EDA439E26E4C}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utilities", "Utilities", "{FED80230-119E-4B2F-9F53-D2660A5F022B}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odbc-store", "odbc-store\odbc-store.vcproj", "{666A63A7-983F-4C19-8411-207F24305197}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shibsp", "shibsp\shibsp.vcproj", "{81F0F7A6-DC36-46EF-957F-F9E81D4403F6}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shibd", "shibd\shibd.vcproj", "{F13141B5-6C87-40BB-8D4E-5CC56EBB4C59}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shibsp-lite", "shibsp\shibsp-lite.vcproj", "{81F0F7A6-DC36-46EF-957F-F9E81D4403F7}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adfs", "adfs\adfs.vcproj", "{26D4FABF-ACDE-4947-9C4A-7AE1B50CD83A}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adfs-lite", "adfs\adfs-lite.vcproj", "{26D4FABF-ACDE-4947-9C4A-7AE1B50CD83B}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F7} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F7}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mdquery", "util\mdquery.vcproj", "{F13141B6-6C87-40BB-8D4E-5CC56EBB4C5A}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resolvertest", "util\resolvertest.vcproj", "{F13141B6-6C87-40BB-8D4E-5CC56EBB4C59}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6}
EndProjectSection
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fastcgi", "fastcgi", "{8E1AF2CF-24E1-4983-8681-394D89DF9AD2}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shibauthorizer", "fastcgi\shibauthorizer.vcproj", "{8CF7DDFA-EAA0-416E-853E-3DCB210C4AE0}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F7} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F7}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shibresponder", "fastcgi\shibresponder.vcproj", "{B2423DCE-048D-4BAA-9AB9-F5D1FCDD3D25}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F7} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F7}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "memcache-store", "memcache-store\memcache-store.vcproj", "{666A63A7-983F-4C19-8411-207F24305198}"
- ProjectSection(WebsiteProperties) = preProject
- Debug.AspNetCompiler.Debug = "True"
- Release.AspNetCompiler.Debug = "False"
- EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{81F0F7A6-DC36-46EF-957F-F9E81D4403F6} = {81F0F7A6-DC36-46EF-957F-F9E81D4403F6}
EndProjectSection
{B2423DCE-048D-4BAA-9AB9-F5D1FCDD3D25}.Release|Win32.Build.0 = Release|Win32
{B2423DCE-048D-4BAA-9AB9-F5D1FCDD3D25}.Release|x64.ActiveCfg = Release|x64
{666A63A7-983F-4C19-8411-207F24305198}.Debug|Win32.ActiveCfg = Debug|Win32
+ {666A63A7-983F-4C19-8411-207F24305198}.Debug|Win32.Build.0 = Debug|Win32
{666A63A7-983F-4C19-8411-207F24305198}.Debug|x64.ActiveCfg = Debug|x64
{666A63A7-983F-4C19-8411-207F24305198}.Release|Win32.ActiveCfg = Release|Win32
+ {666A63A7-983F-4C19-8411-207F24305198}.Release|Win32.Build.0 = Release|Win32
{666A63A7-983F-4C19-8411-207F24305198}.Release|x64.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
+ {8E1AF2CF-24E1-4983-8681-394D89DF9AD2} = {26BA8F84-6E42-41FA-9B13-5D3F4B5B2050}
+ {87C25D4E-8D19-4513-B0BA-BC668BC2DEE3} = {26BA8F84-6E42-41FA-9B13-5D3F4B5B2050}
{D243B43E-728E-4F32-BDFF-B3A897037C6D} = {26BA8F84-6E42-41FA-9B13-5D3F4B5B2050}
{68E9568B-476C-4289-B93C-893432378ADC} = {26BA8F84-6E42-41FA-9B13-5D3F4B5B2050}
{1396D80A-8672-4224-9B02-95F3F4207CDB} = {26BA8F84-6E42-41FA-9B13-5D3F4B5B2050}
{B44C0852-83B8-4FB2-A86E-097C9C8256D0} = {26BA8F84-6E42-41FA-9B13-5D3F4B5B2050}
- {87C25D4E-8D19-4513-B0BA-BC668BC2DEE3} = {26BA8F84-6E42-41FA-9B13-5D3F4B5B2050}
- {8E1AF2CF-24E1-4983-8681-394D89DF9AD2} = {26BA8F84-6E42-41FA-9B13-5D3F4B5B2050}
{666A63A7-983F-4C19-8411-207F24305197} = {96AE4FC9-45EF-4C18-9F3B-EDA439E26E4C}
{26D4FABF-ACDE-4947-9C4A-7AE1B50CD83A} = {96AE4FC9-45EF-4C18-9F3B-EDA439E26E4C}
{26D4FABF-ACDE-4947-9C4A-7AE1B50CD83B} = {96AE4FC9-45EF-4C18-9F3B-EDA439E26E4C}
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="8.00"\r
+ Version="9.00"\r
Name="adfs-lite"\r
ProjectGUID="{26D4FABF-ACDE-4947-9C4A-7AE1B50CD83B}"\r
RootNamespace="adfs-lite"\r
Keyword="Win32Proj"\r
+ TargetFrameworkVersion="131072"\r
>\r
<Platforms>\r
<Platform\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib xerces-c_2D.lib xmltooling-lite1D.lib"\r
+ AdditionalDependencies="log4shib1D.lib xerces-c_3D.lib xmltooling-lite1D.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
LinkIncremental="2"\r
AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(ConfigurationName)"\r
GenerateDebugInformation="true"\r
SubSystem="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
- IntermediateDirectory="$(ProjectName)-$(ConfigurationName)"\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ProjectName)-$(ConfigurationName)"\r
ConfigurationType="2"\r
CharacterSet="2"\r
- WholeProgramOptimization="1"\r
>\r
<Tool\r
Name="VCPreBuildEventTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
+ Optimization="0"\r
AdditionalIncludeDirectories=".;..;"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;SHIBSP_LITE"\r
- RuntimeLibrary="2"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;SHIBSP_LITE"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="3"\r
UsePrecompiledHeader="0"\r
+ BrowseInformation="1"\r
WarningLevel="3"\r
Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="SHIBSP_LITE"\r
+ PreprocessorDefinitions="SHIBSP_LITE;_DEBUG"\r
/>\r
<Tool\r
Name="VCPreLinkEventTool"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib xerces-c_2.lib xmltooling-lite1.lib"\r
+ AdditionalDependencies="log4shib1D.lib xerces-c_3D.lib xmltooling-lite1D.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(ConfigurationName)"\r
+ LinkIncremental="2"\r
+ AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
+ GenerateDebugInformation="true"\r
SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- TargetMachine="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="17"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Debug|x64"\r
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
- IntermediateDirectory="$(PlatformName)\$(ProjectName)-$(ConfigurationName)"\r
+ Name="Release|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ProjectName)-$(ConfigurationName)"\r
ConfigurationType="2"\r
CharacterSet="2"\r
+ WholeProgramOptimization="1"\r
>\r
<Tool\r
Name="VCPreBuildEventTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TargetEnvironment="3"\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="0"\r
AdditionalIncludeDirectories=".;..;"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;SHIBSP_LITE"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="3"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;SHIBSP_LITE"\r
+ RuntimeLibrary="2"\r
UsePrecompiledHeader="0"\r
- BrowseInformation="1"\r
WarningLevel="3"\r
Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="SHIBSP_LITE;_DEBUG"\r
+ PreprocessorDefinitions="SHIBSP_LITE"\r
/>\r
<Tool\r
Name="VCPreLinkEventTool"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib xerces-c_2D.lib xmltooling-lite1D.lib"\r
+ AdditionalDependencies="log4shib1.lib xerces-c_3.lib xmltooling-lite1.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
- GenerateDebugInformation="true"\r
+ LinkIncremental="1"\r
+ AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(ConfigurationName)"\r
SubSystem="2"\r
- TargetMachine="17"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="1"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib xerces-c_2.lib xmltooling-lite1.lib"\r
+ AdditionalDependencies="log4shib1.lib xerces-c_3.lib xmltooling-lite1.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
LinkIncremental="1"\r
AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
SubSystem="2"\r
OptimizeReferences="2"\r
EnableCOMDATFolding="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="17"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/*
- * Copyright 2001-2005 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
public:
ADFSDecoder() : m_ns(WSTRUST_NS) {}
virtual ~ADFSDecoder() {}
-
+
XMLObject* decode(string& relayState, const GenericRequest& genericRequest, SecurityPolicy& policy) const;
protected:
}
}
virtual ~ADFSSessionInitiator() {}
-
+
void setParent(const PropertySet* parent) {
DOMPropertySet::setParent(parent);
pair<bool,const char*> loc = getString("Location");
}
void receive(DDF& in, ostream& out);
+ pair<bool,long> unwrap(SPRequest& request, DDF& out) const;
pair<bool,long> run(SPRequest& request, string& entityID, bool isHandler=true) const;
private:
pair<bool,long> doRequest(
const Application& application,
+ const HTTPRequest* httpRequest,
HTTPResponse& httpResponse,
const char* entityID,
const char* acsLocation,
}
}
virtual ~ADFSLogoutInitiator() {}
-
+
void setParent(const PropertySet* parent) {
DOMPropertySet::setParent(parent);
pair<bool,const char*> loc = getString("Location");
public:
ADFSLogout(const DOMElement* e, const char* appId)
: AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".Logout.ADFS")), m_login(e, appId) {
-#ifndef SHIBSP_LITE
m_initiator = false;
+#ifndef SHIBSP_LITE
m_preserve.push_back("wreply");
string address = string(appId) + getString("Location").second + "::run::ADFSLO";
setAddress(address.c_str());
conf.AssertionConsumerServiceManager.registerFactory(WSFED_NS, ADFSLogoutFactory);
#ifndef SHIBSP_LITE
SAMLConfig::getConfig().MessageDecoderManager.registerFactory(WSFED_NS, ADFSDecoderFactory);
- XMLObjectBuilder::registerBuilder(QName(WSTRUST_NS,"RequestedSecurityToken"), new AnyElementBuilder());
- XMLObjectBuilder::registerBuilder(QName(WSTRUST_NS,"RequestSecurityTokenResponse"), new AnyElementBuilder());
+ XMLObjectBuilder::registerBuilder(xmltooling::QName(WSTRUST_NS,"RequestedSecurityToken"), new AnyElementBuilder());
+ XMLObjectBuilder::registerBuilder(xmltooling::QName(WSTRUST_NS,"RequestSecurityTokenResponse"), new AnyElementBuilder());
#endif
return 0;
}
const Application& app=request.getApplication();
if (isHandler) {
+ option=request.getParameter("acsIndex");
+ if (option) {
+ ACS = app.getAssertionConsumerServiceByIndex(atoi(option));
+ if (!ACS)
+ request.log(SPRequest::SPWarn, "invalid acsIndex specified in request, using default ACS location");
+ }
+
option = request.getParameter("target");
if (option)
target = option;
}
// Since we're not passing by index, we need to fully compute the return URL.
- // Get all the ADFS endpoints.
- const vector<const Handler*>& handlers = app.getAssertionConsumerServicesByBinding(m_binding.get());
-
- // Index comes from request, or default set in the handler, or we just pick the first endpoint.
- pair<bool,unsigned int> index(false,0);
- if (isHandler) {
- option = request.getParameter("acsIndex");
- if (option)
- index = pair<bool,unsigned int>(true, atoi(option));
- }
- if (!index.first)
- index = getUnsignedInt("defaultACSIndex");
- if (index.first) {
- for (vector<const Handler*>::const_iterator h = handlers.begin(); !ACS && h!=handlers.end(); ++h) {
- if (index.second == (*h)->getUnsignedInt("index").second)
- ACS = *h;
+ if (!ACS) {
+ pair<bool,unsigned int> index = getUnsignedInt("defaultACSIndex");
+ if (index.first) {
+ ACS = app.getAssertionConsumerServiceByIndex(index.second);
+ if (!ACS)
+ request.log(SPRequest::SPWarn, "invalid defaultACSIndex, using default ACS location");
}
+ if (!ACS)
+ ACS = app.getDefaultAssertionConsumerService();
}
- else if (!handlers.empty()) {
- ACS = handlers.front();
+
+ // Validate the ACS for use with this protocol.
+ pair<bool,const XMLCh*> ACSbinding = ACS ? ACS->getXMLString("Binding") : pair<bool,const XMLCh*>(false,NULL);
+ if (ACSbinding.first) {
+ if (!XMLString::equals(ACSbinding.second, m_binding.get())) {
+ m_log.info("configured or requested ACS has non-ADFS binding");
+ return make_pair(false,0L);
+ }
}
- if (!ACS)
- throw ConfigurationException("Unable to locate ADFS response endpoint.");
// Compute the ACS URL. We add the ACS location to the base handlerURL.
string ACSloc=request.getHandlerURL(target.c_str());
m_log.debug("attempting to initiate session using ADFS with provider (%s)", entityID.c_str());
- if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess))
- return doRequest(app, request, entityID.c_str(), ACSloc.c_str(), (acClass.first ? acClass.second : NULL), target);
+ if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
+ // Out of process means the POST data via the request can be exposed directly to the private method.
+ // The method will handle POST preservation if necessary *before* issuing the response, but only if
+ // it dispatches to an IdP.
+ return doRequest(app, &request, request, entityID.c_str(), ACSloc.c_str(), (acClass.first ? acClass.second : NULL), target);
+ }
// Remote the call.
DDF out,in = DDF(m_address.c_str()).structure();
in.addmember("entity_id").string(entityID.c_str());
in.addmember("acsLocation").string(ACSloc.c_str());
if (!target.empty())
- in.addmember("RelayState").string(target.c_str());
+ in.addmember("RelayState").unsafe_string(target.c_str());
if (acClass.first)
in.addmember("authnContextClassRef").string(acClass.second);
return unwrap(request, out);
}
+pair<bool,long> ADFSSessionInitiator::unwrap(SPRequest& request, DDF& out) const
+{
+ // See if there's any response to send back.
+ if (!out["redirect"].isnull() || !out["response"].isnull()) {
+ // If so, we're responsible for handling the POST data, probably by dropping a cookie.
+ preservePostData(request.getApplication(), request, request, out["RelayState"].string());
+ }
+ return RemotedHandler::unwrap(request, out);
+}
+
void ADFSSessionInitiator::receive(DDF& in, ostream& out)
{
// Find application.
// Since we're remoted, the result should either be a throw, which we pass on,
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- doRequest(*app, *http.get(), entityID, acsLocation, in["authnContextClassRef"].string(), relayState);
+ doRequest(*app, NULL, *http.get(), entityID, acsLocation, in["authnContextClassRef"].string(), relayState);
+ if (!ret.isstruct())
+ ret.structure();
+ ret.addmember("RelayState").unsafe_string(relayState.c_str());
out << ret;
}
pair<bool,long> ADFSSessionInitiator::doRequest(
const Application& app,
+ const HTTPRequest* httpRequest,
HTTPResponse& httpResponse,
const char* entityID,
const char* acsLocation,
throw MetadataException("Unable to locate metadata for identity provider ($entityID)", namedparams(1, "entityID", entityID));
}
else if (!entity.second) {
- m_log.warn("unable to locate ADFS-aware identity provider role for provider (%s)", entityID);
+ m_log.log(getParent() ? Priority::INFO : Priority::WARN, "unable to locate ADFS-aware identity provider role for provider (%s)", entityID);
if (getParent())
return make_pair(false,0L);
throw MetadataException("Unable to locate ADFS-aware identity provider role for provider ($entityID)", namedparams(1, "entityID", entityID));
if (!relayState.empty())
req += "&wctx=" + urlenc->encode(relayState.c_str());
+ if (httpRequest) {
+ // If the request object is available, we're responsible for the POST data.
+ preservePostData(app, *httpRequest, httpResponse, relayState.c_str());
+ }
+
return make_pair(true, httpResponse.sendRedirect(req.c_str()));
#else
return make_pair(false,0L);
// Parse and bind the document into an XMLObject.
istringstream is(param);
DOMDocument* doc = (policy.getValidating() ? XMLToolingConfig::getConfig().getValidatingParser()
- : XMLToolingConfig::getConfig().getParser()).parse(is);
+ : XMLToolingConfig::getConfig().getParser()).parse(is);
XercesJanitor<DOMDocument> janitor(doc);
auto_ptr<XMLObject> xmlObject(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
janitor.release();
throw BindingException("Decoded message was not of the appropriate type.");
}
- if (!policy.getValidating())
- SchemaValidators.validate(xmlObject.get());
+ SchemaValidators.validate(xmlObject.get());
// Skip policy step here, there's no security in the wrapper.
// policy.evaluate(*xmlObject.get(), &genericRequest);
-
+
return xmlObject.release();
}
const ElementProxy* response = dynamic_cast<const ElementProxy*>(&xmlObject);
if (!response || !response->hasChildren())
throw FatalProfileException("Incoming message was not of the proper type or contains no security token.");
-
+
const Assertion* token = NULL;
for (vector<XMLObject*>::const_iterator xo = response->getUnknownXMLObjects().begin(); xo != response->getUnknownXMLObjects().end(); ++xo) {
// Look for the RequestedSecurityToken element.
break;
}
}
-
+
// Extract message and issuer details from assertion.
extractMessageDetails(*token, m_protocol.get(), policy);
// Run the policy over the assertion. Handles replay, freshness, and
// signature verification, assuming the relevant rules are configured.
- policy.evaluate(*token);
-
+ policy.evaluate(*token, &httpRequest);
+
// If no security is in place now, we kick it.
if (!policy.isAuthenticated())
throw SecurityPolicyException("Unable to establish security of incoming assertion.");
time_t now = time(NULL);
-
+
const PropertySet* sessionProps = application.getPropertySet("Sessions");
const EntityDescriptor* entity = policy.getIssuerMetadata() ? dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent()) : NULL;
const XMLCh* authMethod=NULL;
const XMLCh* authInstant=NULL;
time_t sessionExp = 0;
-
+
const saml1::Assertion* saml1token = dynamic_cast<const saml1::Assertion*>(token);
if (saml1token) {
// Now do profile and core semantic validation to ensure we can use it for SSO.
throw FatalProfileException("Assertion did not contain time conditions.");
else if (saml1token->getAuthenticationStatements().empty())
throw FatalProfileException("Assertion did not contain an authentication statement.");
-
+
// authnskew allows rejection of SSO if AuthnInstant is too old.
pair<bool,unsigned int> authnskew = sessionProps ? sessionProps->getUnsignedInt("maxTimeSinceAuthn") : pair<bool,unsigned int>(false,0);
throw FatalProfileException("Assertion did not contain time conditions.");
else if (saml2token->getAuthnStatements().empty())
throw FatalProfileException("Assertion did not contain an authentication statement.");
-
+
// authnskew allows rejection of SSO if AuthnInstant is too old.
pair<bool,unsigned int> authnskew = sessionProps ? sessionProps->getUnsignedInt("maxTimeSinceAuthn") : pair<bool,unsigned int>(false,0);
else
sessionExp = min(sessionExp, now + lifetime.second); // Use the lowest.
}
-
+
m_log.debug("ADFS profile processing completed successfully");
// We've successfully "accepted" the SSO token.
m_log.error("couldn't find application (%s) for logout", aid ? aid : "(missing)");
throw ConfigurationException("Unable to locate application for logout, deleted?");
}
-
+
// Unpack the request.
auto_ptr<HTTPRequest> req(getRequest(in));
DDF ret(NULL);
DDFJanitor jout(ret);
auto_ptr<HTTPResponse> resp(getResponse(ret));
-
+
Session* session = NULL;
try {
session = app->getServiceProvider().getSessionCache()->find(*app, *req.get(), NULL, NULL);
"Unable to locate ADFS IdP role for identity provider ($entityID).", namedparams(1, "entityID", session->getEntityID())
);
}
-
+
const EndpointType* ep = EndpointManager<SingleLogoutService>(
dynamic_cast<const IDPSSODescriptor*>(entity.second)->getSingleLogoutServices()
).getByBinding(m_binding.get());
//\r
\r
VS_VERSION_INFO VERSIONINFO\r
- FILEVERSION 2,1,0,0\r
- PRODUCTVERSION 2,1,0,0\r
+ FILEVERSION 2,2,1,0\r
+ PRODUCTVERSION 2,2,1,0\r
FILEFLAGSMASK 0x3fL\r
#ifdef _DEBUG\r
FILEFLAGS 0x1L\r
VALUE "Comments", "\0"\r
VALUE "CompanyName", "Internet2\0"\r
VALUE "FileDescription", "Shibboleth ADFSv1 Plugin\0"\r
- VALUE "FileVersion", "2, 1, 0, 0\0"\r
+ VALUE "FileVersion", "2, 2, 1, 0\0"\r
#ifdef SHIBSP_LITE\r
VALUE "InternalName", "adfs-lite\0"\r
#else\r
VALUE "InternalName", "adfs\0"\r
#endif\r
- VALUE "LegalCopyright", "Copyright © 2008 Internet2\0"\r
+ VALUE "LegalCopyright", "Copyright © 2009 Internet2\0"\r
VALUE "LegalTrademarks", "\0"\r
#ifdef SHIBSP_LITE\r
VALUE "OriginalFilename", "adfs-lite.so\0"\r
VALUE "OriginalFilename", "adfs.so\0"\r
#endif\r
VALUE "PrivateBuild", "\0"\r
- VALUE "ProductName", "Shibboleth 2.1\0"\r
- VALUE "ProductVersion", "2, 1, 0, 0\0"\r
+ VALUE "ProductName", "Shibboleth 2.2.1\0"\r
+ VALUE "ProductVersion", "2, 2, 1, 0\0"\r
VALUE "SpecialBuild", "\0"\r
END\r
END\r
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="8.00"\r
+ Version="9.00"\r
Name="adfs"\r
ProjectGUID="{26D4FABF-ACDE-4947-9C4A-7AE1B50CD83A}"\r
RootNamespace="adfs"\r
Keyword="Win32Proj"\r
+ TargetFrameworkVersion="131072"\r
>\r
<Platforms>\r
<Platform\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib xerces-c_2D.lib saml2D.lib xmltooling1D.lib"\r
+ AdditionalDependencies="log4shib1D.lib xerces-c_3D.lib saml2D.lib xmltooling1D.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
LinkIncremental="2"\r
AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"\r
GenerateDebugInformation="true"\r
SubSystem="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
- IntermediateDirectory="$(ConfigurationName)"\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
CharacterSet="2"\r
- WholeProgramOptimization="1"\r
>\r
<Tool\r
Name="VCPreBuildEventTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
+ Optimization="0"\r
AdditionalIncludeDirectories=".;..;"..\..\cpp-opensaml2";"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"\r
- RuntimeLibrary="2"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="3"\r
UsePrecompiledHeader="0"\r
+ BrowseInformation="1"\r
WarningLevel="3"\r
Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
/>\r
<Tool\r
Name="VCPreLinkEventTool"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib xerces-c_2.lib saml2.lib xmltooling1.lib"\r
+ AdditionalDependencies="log4shib1D.lib xerces-c_3D.lib saml2D.lib xmltooling1D.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"\r
+ LinkIncremental="2"\r
+ AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
+ GenerateDebugInformation="true"\r
SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- TargetMachine="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="17"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Debug|x64"\r
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ Name="Release|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ConfigurationName)"\r
ConfigurationType="2"\r
CharacterSet="2"\r
+ WholeProgramOptimization="1"\r
>\r
<Tool\r
Name="VCPreBuildEventTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TargetEnvironment="3"\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="0"\r
AdditionalIncludeDirectories=".;..;"..\..\cpp-opensaml2";"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="3"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"\r
+ RuntimeLibrary="2"\r
UsePrecompiledHeader="0"\r
- BrowseInformation="1"\r
WarningLevel="3"\r
Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="_DEBUG"\r
/>\r
<Tool\r
Name="VCPreLinkEventTool"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib xerces-c_2D.lib saml2D.lib xmltooling1D.lib"\r
+ AdditionalDependencies="log4shib1.lib xerces-c_3.lib saml2.lib xmltooling1.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
- GenerateDebugInformation="true"\r
+ LinkIncremental="1"\r
+ AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"\r
SubSystem="2"\r
- TargetMachine="17"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="1"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib xerces-c_2.lib saml2.lib xmltooling1.lib"\r
+ AdditionalDependencies="log4shib1.lib xerces-c_3.lib saml2.lib xmltooling1.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
LinkIncremental="1"\r
AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
SubSystem="2"\r
OptimizeReferences="2"\r
EnableCOMDATFolding="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="17"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
char* g_szSchemaDir = NULL;
char* g_szPrefix = NULL;
SPConfig* g_Config = NULL;
- string g_unsetHeaderValue;
+ string g_unsetHeaderValue,g_spoofKey;
bool g_checkSpoofing = true;
bool g_catchAll = false;
static const char* g_UserDataKey = "_shib_check_user_";
- static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);
- static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);
}
/* Apache 2.2.x headers must be accumulated and set in the output filter.
{
bool m_handler;
mutable string m_body;
- mutable bool m_gotBody;
+ mutable bool m_gotBody,m_firsttime;
mutable vector<string> m_certs;
set<string> m_allhttp;
shib_server_config* m_sc;
shib_request_config* m_rc;
- ShibTargetApache(request_rec* req, bool handler) : AbstractSPRequest(SHIBSP_LOGCAT".Apache"), m_handler(handler), m_gotBody(false) {
+ ShibTargetApache(request_rec* req, bool handler, bool shib_check_user)
+ : AbstractSPRequest(SHIBSP_LOGCAT".Apache"), m_handler(handler), m_gotBody(false),m_firsttime(true) {
m_sc = (shib_server_config*)ap_get_module_config(req->server->module_config, &mod_shib);
m_dc = (shib_dir_config*)ap_get_module_config(req->per_dir_config, &mod_shib);
m_rc = (shib_request_config*)ap_get_module_config(req->request_config, &mod_shib);
m_req = req;
setRequestURI(m_req->unparsed_uri);
+
+ if (shib_check_user && m_dc->bUseHeaders == 1) {
+ // Try and see if this request was already processed, to skip spoof checking.
+ if (!ap_is_initial_req(m_req)) {
+ m_firsttime = false;
+ }
+ else if (!g_spoofKey.empty()) {
+ const char* hdr = ap_table_get(m_req->headers_in, "Shib-Spoof-Check");
+ if (hdr && g_spoofKey == hdr)
+ m_firsttime=false;
+ }
+
+ if (!m_firsttime)
+ log(SPDebug, "shib_check_user running more than once");
+ }
}
virtual ~ShibTargetApache() {}
return m_gotBody ? m_body.length() : m_req->remaining;
}
string getRemoteAddr() const {
- return m_req->connection->remote_ip;
+ string ret = AbstractSPRequest::getRemoteAddr();
+ return ret.empty() ? m_req->connection->remote_ip : ret;
}
void log(SPLogLevel level, const string& msg) const {
AbstractSPRequest::log(level,msg);
void clearHeader(const char* rawname, const char* cginame) {
if (m_dc->bUseHeaders == 1) {
// ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(m_req), "shib_clear_header: hdr\n");
- if (g_checkSpoofing && ap_is_initial_req(m_req)) {
+ if (g_checkSpoofing && m_firsttime) {
if (m_allhttp.empty()) {
// First time, so populate set with "CGI" versions of client-supplied headers.
#ifdef SHIB_APACHE_13
}
void setRemoteUser(const char* user) {
SH_AP_USER(m_req) = user ? ap_pstrdup(m_req->pool, user) : NULL;
+ if (m_dc->bUseHeaders == 1) {
+ if (user) {
+ ap_table_set(m_req->headers_in, "REMOTE_USER", user);
+ }
+ else {
+ ap_table_unset(m_req->headers_in, "REMOTE_USER");
+ ap_table_set(m_req->headers_in, "REMOTE_USER", g_unsetHeaderValue.c_str());
+ }
+ }
}
string getRemoteUser() const {
return string(SH_AP_USER(m_req) ? SH_AP_USER(m_req) : "");
}
+ void setAuthType(const char* authtype) {
+ if (authtype && m_dc->bBasicHijack == 1)
+ authtype = "Basic";
+ SH_AP_AUTH_TYPE(m_req) = authtype ? ap_pstrdup(m_req->pool, authtype) : NULL;
+ }
+ string getAuthType() const {
+ return string(SH_AP_AUTH_TYPE(m_req) ? SH_AP_AUTH_TYPE(m_req) : "");
+ }
void setContentType(const char* type) {
m_req->content_type = ap_psprintf(m_req->pool, type);
}
if (!m_rc)
// this happens on subrequests
m_rc = init_request_config(m_req);
- if (m_handler)
+ if (m_handler) {
+ if (!m_rc->hdr_out)
+ m_rc->hdr_out = ap_make_table(m_req->pool, 5);
ap_table_add(m_rc->hdr_out, name, value);
+ }
else
#endif
ap_table_add(m_req->err_headers_out, name, value);
xmltooling::NDC ndc(threadid.str().c_str());
try {
- ShibTargetApache sta(r,false);
+ ShibTargetApache sta(r,false,true);
// Check user authentication and export information, then set the handler bypass
pair<bool,long> res = sta.getServiceProvider().doAuthentication(sta,true);
apr_pool_userdata_setn((const void*)42,g_UserDataKey,NULL,r->pool);
+ // If directed, install a spoof key to recognize when we've already cleared headers.
+ if (!g_spoofKey.empty() && (((shib_dir_config*)ap_get_module_config(r->per_dir_config, &mod_shib))->bUseHeaders==1))
+ ap_table_set(r->headers_in, "Shib-Spoof-Check", g_spoofKey.c_str());
if (res.first) return res.second;
// user auth was okay -- export the assertions now
ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_handler(%d): ENTER: %s", (int)getpid(), r->handler);
try {
- ShibTargetApache sta(r,true);
+ ShibTargetApache sta(r,true,false);
pair<bool,long> res = sta.getServiceProvider().doHandler(sta);
if (res.first) return res.second;
xmltooling::NDC ndc(threadid.str().c_str());
try {
- ShibTargetApache sta(r,false);
+ ShibTargetApache sta(r,false,false);
pair<bool,long> res = sta.getServiceProvider().doAuthorization(sta);
if (res.first) return res.second;
auto_ptr<xercesc::RegularExpression> temp(new xercesc::RegularExpression(trans.get()));
re=temp;
}
-
- for (; !status && attrs.first!=attrs.second; ++attrs.first) {
- if (checkAttribute(request, attrs.first->second, w, regexp ? re.get() : NULL)) {
+
+ pair<multimap<string,const Attribute*>::const_iterator,multimap<string,const Attribute*>::const_iterator> attrs2(attrs);
+ for (; !status && attrs2.first!=attrs2.second; ++attrs2.first) {
+ if (checkAttribute(request, attrs2.first->second, w, regexp ? re.get() : NULL)) {
status = true;
}
}
static int shib_post_read(request_rec *r)
{
shib_request_config* rc = init_request_config(r);
-
- ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r), "shib_post_read");
-
-#ifdef SHIB_DEFERRED_HEADERS
- rc->hdr_out = ap_make_table(r->pool, 5);
-#endif
+ //ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r), "shib_post_read");
return DECLINED;
}
ServiceProvider* sp=g_Config->getServiceProvider();
xmltooling::Locker locker(sp);
- const PropertySet* props=sp->getPropertySet("Local");
+ const PropertySet* props=sp->getPropertySet("InProcess");
if (props) {
pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
if (unsetValue.first)
g_unsetHeaderValue = unsetValue.second;
pair<bool,bool> flag=props->getBool("checkSpoofing");
g_checkSpoofing = !flag.first || flag.second;
+ if (g_checkSpoofing) {
+ unsetValue=props->getString("spoofKey");
+ if (unsetValue.first)
+ g_spoofKey = unsetValue.second;
+ }
flag=props->getBool("catchAll");
g_catchAll = flag.first && flag.second;
}
request_rec *r = f->r;
shib_request_config *rc = (shib_request_config*) ap_get_module_config(r->request_config, &mod_shib);
- if (rc) {
+ if (rc && rc->hdr_out) {
ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_out_filter: merging %d headers", apr_table_elts(rc->hdr_out)->nelts);
- apr_table_do(_table_add,r->headers_out, rc->hdr_out,NULL);
// can't use overlap call because it will collapse Set-Cookie headers
//apr_table_overlap(r->headers_out, rc->hdr_out, APR_OVERLAP_TABLES_MERGE);
+ apr_table_do(_table_add,r->headers_out, rc->hdr_out,NULL);
}
/* remove ourselves from the filter chain */
request_rec *r = f->r;
shib_request_config *rc = (shib_request_config*) ap_get_module_config(r->request_config, &mod_shib);
- if (rc) {
+ if (rc && rc->hdr_out) {
ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_err_filter: merging %d headers", apr_table_elts(rc->hdr_out)->nelts);
- apr_table_do(_table_add,r->err_headers_out, rc->hdr_out,NULL);
// can't use overlap call because it will collapse Set-Cookie headers
//apr_table_overlap(r->err_headers_out, rc->hdr_out, APR_OVERLAP_TABLES_MERGE);
+ apr_table_do(_table_add,r->err_headers_out, rc->hdr_out,NULL);
}
/* remove ourselves from the filter chain */
{"ShibPrefix", (config_fn_t)ap_set_global_string_slot, &g_szPrefix,
RSRC_CONF, TAKE1, "Shibboleth installation directory"},
{"ShibConfig", (config_fn_t)ap_set_global_string_slot, &g_szSHIBConfig,
- RSRC_CONF, TAKE1, "Path to shibboleth.xml config file"},
+ RSRC_CONF, TAKE1, "Path to shibboleth2.xml config file"},
{"ShibCatalogs", (config_fn_t)ap_set_global_string_slot, &g_szSchemaDir,
RSRC_CONF, TAKE1, "Paths of XML schema catalogs"},
AP_INIT_TAKE1("ShibPrefix", (config_fn_t)ap_set_global_string_slot, &g_szPrefix,
RSRC_CONF, "Shibboleth installation directory"),
AP_INIT_TAKE1("ShibConfig", (config_fn_t)ap_set_global_string_slot, &g_szSHIBConfig,
- RSRC_CONF, "Path to shibboleth.xml config file"),
+ RSRC_CONF, "Path to shibboleth2.xml config file"),
AP_INIT_TAKE1("ShibCatalogs", (config_fn_t)ap_set_global_string_slot, &g_szSchemaDir,
RSRC_CONF, "Paths of XML schema catalogs"),
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="9.00"
Name="mod_shib13"
ProjectGUID="{D243B43E-728E-4F32-BDFF-B3A897037C6D}"
+ TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="xerces-c_2.lib ApacheCore.lib xmltooling-lite1.lib"
+ AdditionalDependencies="xerces-c_3.lib ApacheCore.lib xmltooling-lite1.lib"
OutputFile="$(OutDir)\mod_shib_13.so"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";\Apache\libexec"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
/>
<Tool
Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
+ PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
- TargetEnvironment="1"
- TypeLibraryName=".\Debug/mod_shib13.tlb"
+ TargetEnvironment="3"
+ TypeLibraryName=".\Release/mod_shib13.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="0"
+ Optimization="2"
+ InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..;\Apache\include;"..\..\cpp-xmltooling""
- PreprocessorDefinitions="_WINDOWS;EAPI;WIN32;_DEBUG"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- BrowseInformation="1"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;EAPI"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
+ PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="xerces-c_2D.lib ApacheCore.lib xmltooling-lite1D.lib"
+ AdditionalDependencies="xerces-c_3.lib ApacheCore.lib xmltooling-lite1.lib"
OutputFile="$(OutDir)\mod_shib_13.so"
- LinkIncremental="2"
+ LinkIncremental="1"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";\Apache\libexec"
- GenerateDebugInformation="true"
- TargetMachine="1"
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";\Apache\libexec"
+ ProgramDatabaseFile=".\Release/mod_shib_13.pdb"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Release|x64"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
/>
<Tool
Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
+ PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
- TargetEnvironment="3"
- TypeLibraryName=".\Release/mod_shib13.tlb"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/mod_shib13.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
+ Optimization="0"
AdditionalIncludeDirectories="..;\Apache\include;"..\..\cpp-xmltooling""
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;EAPI"
- StringPooling="true"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
+ PreprocessorDefinitions="_WINDOWS;EAPI;WIN32;_DEBUG"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
+ PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="xerces-c_2.lib ApacheCore.lib xmltooling-lite1.lib"
+ AdditionalDependencies="xerces-c_3D.lib ApacheCore.lib xmltooling-lite1D.lib"
OutputFile="$(OutDir)\mod_shib_13.so"
- LinkIncremental="1"
+ LinkIncremental="2"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";\Apache\libexec"
- ProgramDatabaseFile=".\Release/mod_shib_13.pdb"
- TargetMachine="17"
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";\Apache\libexec"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="xerces-c_2D.lib ApacheCore.lib xmltooling-lite1D.lib"
+ AdditionalDependencies="xerces-c_3D.lib ApacheCore.lib xmltooling-lite1D.lib"
OutputFile="$(OutDir)\mod_shib_13.so"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";\Apache\libexec"
GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Win32"
+ Name="Release|x64"
ExcludedFromBuild="true"
>
<Tool
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|x64"
+ Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="9.00"
Name="mod_shib20"
ProjectGUID="{68E9568B-476C-4289-B93C-893432378ADC}"
+ TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="xerces-c_2.lib libapr.lib libaprutil.lib libhttpd.lib xmltooling-lite1.lib"
+ AdditionalDependencies="xerces-c_3.lib libapr.lib libaprutil.lib libhttpd.lib xmltooling-lite1.lib"
OutputFile="$(OutDir)\mod_shib_20.so"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";\Apache2\lib"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ProjectName)-$(ConfigurationName)"
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ProjectName)-$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
/>
<Tool
Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
+ PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
- TargetEnvironment="1"
- TypeLibraryName=".\mod_shib20___Win32_Debug/mod_shib20.tlb"
+ TargetEnvironment="3"
+ TypeLibraryName=".\mod_shib20___Win32_Release/mod_shib20.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="0"
+ Optimization="2"
+ InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..;\Apache2\include;"..\..\cpp-xmltooling""
- PreprocessorDefinitions="_WINDOWS;WIN32;_DEBUG"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
RuntimeTypeInfo="true"
- BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
+ PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="xerces-c_2D.lib libapr.lib libaprutil.lib libhttpd.lib xmltooling-lite1D.lib"
+ AdditionalDependencies="xerces-c_3.lib libapr.lib libaprutil.lib libhttpd.lib xmltooling-lite1.lib"
OutputFile="$(OutDir)\mod_shib_20.so"
- LinkIncremental="2"
+ LinkIncremental="1"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";\Apache2\lib"
- GenerateDebugInformation="true"
- TargetMachine="1"
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";\Apache2\lib"
+ ProgramDatabaseFile=".\mod_shib20___Win32_Release/mod_shib_20.pdb"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Release|x64"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ProjectName)-$(ConfigurationName)"
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ProjectName)-$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
/>
<Tool
Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
+ PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
- TargetEnvironment="3"
- TypeLibraryName=".\mod_shib20___Win32_Release/mod_shib20.tlb"
+ TargetEnvironment="1"
+ TypeLibraryName=".\mod_shib20___Win32_Debug/mod_shib20.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
+ Optimization="0"
AdditionalIncludeDirectories="..;\Apache2\include;"..\..\cpp-xmltooling""
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
- StringPooling="true"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
+ PreprocessorDefinitions="_WINDOWS;WIN32;_DEBUG"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
+ BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
+ PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="xerces-c_2.lib libapr.lib libaprutil.lib libhttpd.lib xmltooling-lite1.lib"
+ AdditionalDependencies="xerces-c_3D.lib libapr.lib libaprutil.lib libhttpd.lib xmltooling-lite1D.lib"
OutputFile="$(OutDir)\mod_shib_20.so"
- LinkIncremental="1"
+ LinkIncremental="2"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";\Apache2\lib"
- ProgramDatabaseFile=".\mod_shib20___Win32_Release/mod_shib_20.pdb"
- TargetMachine="17"
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";\Apache2\lib"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="xerces-c_2D.lib libapr.lib libaprutil.lib libhttpd.lib xmltooling-lite1D.lib"
+ AdditionalDependencies="xerces-c_3D.lib libapr.lib libaprutil.lib libhttpd.lib xmltooling-lite1D.lib"
OutputFile="$(OutDir)\mod_shib_20.so"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";\Apache2\lib"
GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Win32"
+ Name="Release|x64"
ExcludedFromBuild="true"
>
<Tool
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|x64"
+ Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="8.00"\r
+ Version="9.00"\r
Name="mod_shib22"\r
ProjectGUID="{B44C0852-83B8-4FB2-A86E-097C9C8256D0}"\r
+ TargetFrameworkVersion="131072"\r
>\r
<Platforms>\r
<Platform\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="xerces-c_2.lib xmltooling-lite1.lib libapr-1.lib libaprutil-1.lib libhttpd.lib"\r
+ AdditionalDependencies="xerces-c_3.lib xmltooling-lite1.lib libapr-1.lib libaprutil-1.lib libhttpd.lib"\r
OutputFile="$(OutDir)\mod_shib_22.so"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";\Apache2.2\lib"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
- IntermediateDirectory="$(ProjectName)-$(ConfigurationName)"\r
+ Name="Release|x64"\r
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ProjectName)-$(ConfigurationName)"\r
ConfigurationType="2"\r
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
UseOfMFC="0"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- PreprocessorDefinitions="_DEBUG"\r
+ PreprocessorDefinitions="NDEBUG"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
- TargetEnvironment="1"\r
- TypeLibraryName=".\mod_shib22___Win32_Debug/mod_shib22.tlb"\r
+ TargetEnvironment="3"\r
+ TypeLibraryName=".\mod_shib22___Win32_Release/mod_shib22.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="0"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="1"\r
AdditionalIncludeDirectories="..;\Apache2.2\include;"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="3"\r
+ PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"\r
+ StringPooling="true"\r
+ RuntimeLibrary="2"\r
+ EnableFunctionLevelLinking="true"\r
RuntimeTypeInfo="true"\r
- BrowseInformation="1"\r
WarningLevel="3"\r
SuppressStartupBanner="true"\r
Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
/>\r
<Tool\r
Name="VCManagedResourceCompilerTool"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="_DEBUG"\r
+ PreprocessorDefinitions="NDEBUG"\r
Culture="1033"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="xerces-c_2D.lib xmltooling-lite1D.lib libapr-1.lib libaprutil-1.lib libhttpd.lib"\r
+ AdditionalDependencies="xerces-c_3.lib xmltooling-lite1.lib libapr-1.lib libaprutil-1.lib libhttpd.lib"\r
OutputFile="$(OutDir)\mod_shib_22.so"\r
- LinkIncremental="2"\r
+ LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";\Apache2.2\lib"\r
- GenerateDebugInformation="true"\r
- TargetMachine="1"\r
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";"C:\httpd-2.2-x64\lib""\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="17"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Release|x64"\r
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
- IntermediateDirectory="$(PlatformName)\$(ProjectName)-$(ConfigurationName)"\r
+ Name="Debug|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ProjectName)-$(ConfigurationName)"\r
ConfigurationType="2"\r
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
UseOfMFC="0"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- PreprocessorDefinitions="NDEBUG"\r
+ PreprocessorDefinitions="_DEBUG"\r
MkTypLibCompatible="true"\r
SuppressStartupBanner="true"\r
- TargetEnvironment="3"\r
- TypeLibraryName=".\mod_shib22___Win32_Release/mod_shib22.tlb"\r
+ TargetEnvironment="1"\r
+ TypeLibraryName=".\mod_shib22___Win32_Debug/mod_shib22.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="2"\r
- InlineFunctionExpansion="1"\r
+ Optimization="0"\r
AdditionalIncludeDirectories="..;\Apache2.2\include;"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS"\r
- StringPooling="true"\r
- RuntimeLibrary="2"\r
- EnableFunctionLevelLinking="true"\r
+ PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="3"\r
RuntimeTypeInfo="true"\r
+ BrowseInformation="1"\r
WarningLevel="3"\r
SuppressStartupBanner="true"\r
Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="4"\r
/>\r
<Tool\r
Name="VCManagedResourceCompilerTool"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="NDEBUG"\r
+ PreprocessorDefinitions="_DEBUG"\r
Culture="1033"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="xerces-c_2.lib xmltooling-lite1.lib libapr-1.lib libaprutil-1.lib libhttpd.lib"\r
+ AdditionalDependencies="xerces-c_3D.lib xmltooling-lite1D.lib libapr-1.lib libaprutil-1.lib libhttpd.lib"\r
OutputFile="$(OutDir)\mod_shib_22.so"\r
- LinkIncremental="1"\r
+ LinkIncremental="2"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";"C:\httpd-2.2-x64\lib""\r
- TargetMachine="17"\r
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";\Apache2.2\lib"\r
+ GenerateDebugInformation="true"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="1"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="xerces-c_2D.lib xmltooling-lite1D.lib libapr-1.lib libaprutil-1.lib libhttpd.lib"\r
+ AdditionalDependencies="xerces-c_3D.lib xmltooling-lite1D.lib libapr-1.lib libaprutil-1.lib libhttpd.lib"\r
OutputFile="$(OutDir)\mod_shib_22.so"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";"C:\httpd-2.2-x64\lib""\r
GenerateDebugInformation="true"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="17"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Debug|Win32"\r
+ Name="Release|x64"\r
ExcludedFromBuild="true"\r
>\r
<Tool\r
/>\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|x64"\r
+ Name="Debug|Win32"\r
ExcludedFromBuild="true"\r
>\r
<Tool\r
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#define SH_AP_CONFIGFILE configfile_t
#define SH_AP_R(r) r
#define SH_AP_USER(r) r->connection->user
+#define SH_AP_AUTH_TYPE(r) r->connection->ap_auth_type
#ifdef WIN32
# define _USE_32BIT_TIME_T
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,0,0
- PRODUCTVERSION 2,1,0,0
+ FILEVERSION 2,2,1,0
+ PRODUCTVERSION 2,2,1,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
VALUE "Comments", "\0"
VALUE "CompanyName", "Internet2\0"
VALUE "FileDescription", "Shibboleth Apache 1.3 Module\0"
- VALUE "FileVersion", "2, 1, 0, 0\0"
+ VALUE "FileVersion", "2, 2, 1, 0\0"
VALUE "InternalName", "mod_shib_13\0"
- VALUE "LegalCopyright", "Copyright © 2008 Internet2\0"
+ VALUE "LegalCopyright", "Copyright © 2009 Internet2\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "mod_shib_13.so\0"
VALUE "PrivateBuild", "\0"
- VALUE "ProductName", "Shibboleth 2.1\0"
- VALUE "ProductVersion", "2, 1, 0, 0\0"
+ VALUE "ProductName", "Shibboleth 2.2.1\0"
+ VALUE "ProductVersion", "2, 2, 1, 0\0"
VALUE "SpecialBuild", "\0"
END
END
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#define SH_AP_R(r) 0,r
#define SH_AP_USER(r) r->user
+#define SH_AP_AUTH_TYPE(r) r->ap_auth_type
#define SERVER_ERROR HTTP_INTERNAL_SERVER_ERROR
#define REDIRECT HTTP_MOVED_TEMPORARILY
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,0,0
- PRODUCTVERSION 2,1,0,0
+ FILEVERSION 2,2,1,0
+ PRODUCTVERSION 2,2,1,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
VALUE "Comments", "\0"
VALUE "CompanyName", "Internet2\0"
VALUE "FileDescription", "Shibboleth Apache 2.0 Module\0"
- VALUE "FileVersion", "2, 1, 0, 0\0"
+ VALUE "FileVersion", "2, 2, 1, 0\0"
VALUE "InternalName", "mod_shib_20\0"
- VALUE "LegalCopyright", "Copyright © 2008 Internet2\0"
+ VALUE "LegalCopyright", "Copyright © 2009 Internet2\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "mod_shib_20.so\0"
VALUE "PrivateBuild", "\0"
- VALUE "ProductName", "Shibboleth 2.1\0"
- VALUE "ProductVersion", "2, 1, 0, 0\0"
+ VALUE "ProductName", "Shibboleth 2.2.1\0"
+ VALUE "ProductVersion", "2, 2, 1, 0\0"
VALUE "SpecialBuild", "\0"
END
END
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#define SH_AP_R(r) 0,r
#define SH_AP_USER(r) r->user
+#define SH_AP_AUTH_TYPE(r) r->ap_auth_type
#define SERVER_ERROR HTTP_INTERNAL_SERVER_ERROR
#define REDIRECT HTTP_MOVED_TEMPORARILY
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,0,0
- PRODUCTVERSION 2,1,0,0
+ FILEVERSION 2,2,1,0
+ PRODUCTVERSION 2,2,1,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
VALUE "Comments", "\0"
VALUE "CompanyName", "Internet2\0"
VALUE "FileDescription", "Shibboleth Apache 2.2 Module\0"
- VALUE "FileVersion", "2, 1, 0, 0\0"
+ VALUE "FileVersion", "2, 2, 1, 0\0"
VALUE "InternalName", "mod_shib_22\0"
- VALUE "LegalCopyright", "Copyright © 2008 Internet2\0"
+ VALUE "LegalCopyright", "Copyright © 2009 Internet2\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "mod_shib_22.so\0"
VALUE "PrivateBuild", "\0"
- VALUE "ProductName", "Shibboleth 2.1\0"
- VALUE "ProductVersion", "2, 1, 0, 0\0"
+ VALUE "ProductName", "Shibboleth 2.2.1\0"
+ VALUE "ProductVersion", "2, 2, 1, 0\0"
VALUE "SpecialBuild", "\0"
END
END
/* Define if log4shib library is used. */
#undef SHIBSP_LOG4SHIB
+/* Define to 1 if Xerces XMLString includes XMLByte release. */
+#undef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE
+
+/* Define to 1 if Xerces DOMNodeFilter API returns a short. */
+#undef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if Xerces-C library was found */
#define HAVE_LIBXERCESC 1
+#include <xercesc/util/XercesVersion.hpp>
+
+#if (XERCES_VERSION_MAJOR < 3)
+# define SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE 1
+# define SHIBSP_XERCESC_SHORT_ACCEPTNODE 1
+#endif
+
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
#define PACKAGE_NAME "shibboleth"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "shibboleth 2.0"
+#define PACKAGE_STRING "shibboleth 2.2.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "shibboleth"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "2.0"
+#define PACKAGE_VERSION "2.2.1"
/* Define to the necessary symbol if this constant uses a non-standard name on
your system. */
/* #undef TM_IN_SYS_TIME */
/* Version number of package */
-#define VERSION "2.0"
+#define VERSION "2.2.1"
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
-## $Id: Makefile.am 2779 2008-03-15 03:54:53Z cantor $
+## $Id: Makefile.am 3088 2009-08-10 16:43:09Z cantor $
AUTOMAKE_OPTIONS = foreign
pkglibdir = ${libdir}/@PACKAGE@
pkglogdir = ${localstatedir}/log/@PACKAGE@
-pkgdocdir = ${datadir}/doc/@PACKAGE@
+pkgdocdir = $(datadir)/doc/@PACKAGE@-@PACKAGE_VERSION@
shirelogdir = ${localstatedir}/log/httpd
pkgxmldir = $(datadir)/xml/@PACKAGE@
pkgrundir = $(localstatedir)/run/@PACKAGE@
pkgsysconfdir = $(sysconfdir)/@PACKAGE@
pkgsysconf_DATA = \
shibd-redhat \
+ shibd-suse \
shibd-debian \
shibd-osx.plist \
apache.config \
apache2.config \
apache22.config \
keygen.sh \
+ metagen.sh \
upgrade.xsl
# The config files are installed "special". Unlike the entries in
metadataError.html \
bindingTemplate.html \
discoveryTemplate.html \
+ postTemplate.html \
localLogout.html \
globalLogout.html \
sslError.html
shibd-redhat: ${srcdir}/shibd-redhat.in Makefile ${top_builddir}/config.status
$(MAKE) do-build-file FILE=$@
+shibd-suse: ${srcdir}/shibd-suse.in Makefile ${top_builddir}/config.status
+ $(MAKE) do-build-file FILE=$@
+
shibd-debian: ${srcdir}/shibd-debian.in Makefile ${top_builddir}/config.status
$(MAKE) do-build-file FILE=$@
done
install-data-hook:
+ chmod +x $(DESTDIR)$(pkgsysconfdir)/keygen.sh
+ chmod +x $(DESTDIR)$(pkgsysconfdir)/metagen.sh
if test -z "$(NOKEYGEN)"; then \
cd $(DESTDIR)$(pkgsysconfdir); \
sh ./keygen.sh -b ; \
apache2.config \
apache22.config \
shibd-redhat \
+ shibd-suse \
shibd-debian \
shibd-osx.plist \
shibd.logger \
apache2.config.in \
apache22.config.in \
shibd-redhat.in \
+ shibd-suse.in \
shibd-debian.in \
shibd-osx.plist.in \
keygen.bat \
keygen.sh \
+ metagen.sh \
upgrade.xsl \
xsltproc.js \
$(CONFIGFILES)
xs = @xs@
AUTOMAKE_OPTIONS = foreign
pkglogdir = ${localstatedir}/log/@PACKAGE@
-pkgdocdir = ${datadir}/doc/@PACKAGE@
+pkgdocdir = $(datadir)/doc/@PACKAGE@-@PACKAGE_VERSION@
shirelogdir = ${localstatedir}/log/httpd
pkgxmldir = $(datadir)/xml/@PACKAGE@
pkgrundir = $(localstatedir)/run/@PACKAGE@
pkgsysconfdir = $(sysconfdir)/@PACKAGE@
pkgsysconf_DATA = \
shibd-redhat \
+ shibd-suse \
shibd-debian \
shibd-osx.plist \
apache.config \
apache2.config \
apache22.config \
keygen.sh \
+ metagen.sh \
upgrade.xsl
metadataError.html \
bindingTemplate.html \
discoveryTemplate.html \
+ postTemplate.html \
localLogout.html \
globalLogout.html \
sslError.html
apache2.config \
apache22.config \
shibd-redhat \
+ shibd-suse \
shibd-debian \
shibd-osx.plist \
shibd.logger \
apache2.config.in \
apache22.config.in \
shibd-redhat.in \
+ shibd-suse.in \
shibd-debian.in \
shibd-osx.plist.in \
keygen.bat \
keygen.sh \
+ metagen.sh \
upgrade.xsl \
xsltproc.js \
$(CONFIGFILES)
shibd-redhat: ${srcdir}/shibd-redhat.in Makefile ${top_builddir}/config.status
$(MAKE) do-build-file FILE=$@
+shibd-suse: ${srcdir}/shibd-suse.in Makefile ${top_builddir}/config.status
+ $(MAKE) do-build-file FILE=$@
+
shibd-debian: ${srcdir}/shibd-debian.in Makefile ${top_builddir}/config.status
$(MAKE) do-build-file FILE=$@
done
install-data-hook:
+ chmod +x $(DESTDIR)$(pkgsysconfdir)/keygen.sh
+ chmod +x $(DESTDIR)$(pkgsysconfdir)/metagen.sh
if test -z "$(NOKEYGEN)"; then \
cd $(DESTDIR)$(pkgsysconfdir); \
sh ./keygen.sh -b ; \
<Attribute name="urn:mace:dir:attribute-def:eduPersonEntitlement" id="entitlement"/>
<Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" id="entitlement"/>
+
+ <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.11" id="assurance"/>
<!-- A persistent id attribute that supports personalized anonymous access. -->
<!-- First, the deprecated version, decoded as a scoped string: -->
<Attribute name="urn:mace:dir:attribute-def:eduPersonTargetedID" id="targeted-id">
<AttributeDecoder xsi:type="ScopedAttributeDecoder"/>
- <!-- <AttributeDecoder xsi:type="NameIDFromScopedAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name"/> -->
+ <!-- <AttributeDecoder xsi:type="NameIDFromScopedAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name" defaultQualifiers="true"/> -->
</Attribute>
<!-- Second, an alternate decoder that will turn the deprecated form into the newer form. -->
<!--
<Attribute name="urn:mace:dir:attribute-def:eduPersonTargetedID" id="persistent-id">
- <AttributeDecoder xsi:type="NameIDFromScopedAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name"/>
+ <AttributeDecoder xsi:type="NameIDFromScopedAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name" defaultQualifiers="true"/>
</Attribute>
-->
<!-- Third, the new version (note the OID-style name): -->
<Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" id="persistent-id">
- <AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name"/>
+ <AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name" defaultQualifiers="true"/>
</Attribute>
<!-- Fourth, the SAML 2.0 NameID Format: -->
<Attribute name="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" id="persistent-id">
- <AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name"/>
+ <AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name" defaultQualifiers="true"/>
</Attribute>
<!-- Some more eduPerson attributes, uncomment these to use them... -->
goto opt_start\r
\r
:opt_years\r
-set DAYS=%2\r
+set YEARS=%2\r
shift\r
shift\r
goto opt_start\r
--- /dev/null
+#! /bin/sh
+
+while getopts a:c:e:h:n:o:s:t: c
+ do
+ case $c in
+ c) CERTS[${#CERTS[*]}]=$OPTARG;;
+ e) ENTITYID=$OPTARG;;
+ h) HOSTS[${#HOSTS[*]}]=$OPTARG;;
+ n) NAKEDHOSTS[${#NAKEDHOSTS[*]}]=$OPTARG;;
+ o) ORGNAME=$OPTARG;;
+ a) ADMIN[${#ADMIN[*]}]=$OPTARG;;
+ s) SUP[${#SUP[*]}]=$OPTARG;;
+ t) TECH[${#TECH[*]}]=$OPTARG;;
+ \?) echo metagen -c cert1 [-c cert2 ...] -h host1 [-h host2 ...] [-e entityID]
+ exit 1;;
+ esac
+ done
+
+if [ ${#HOSTS[*]} -eq 0 -a ${#NAKEDHOSTS[*]} -eq 0 ] ; then
+ echo metagen -c cert1 [-c cert2 ...] -h host1 [-h host2 ...] [-e entityID]
+ exit 1
+fi
+
+if [ ${#CERTS[*]} -eq 0 ] ; then
+ CERTS[${#CERTS[*]}]=sp-cert.pem
+fi
+
+for c in ${CERTS[@]}
+do
+ if [ ! -s $c ] ; then
+ echo Certificate file $c does not exist!
+ exit 2
+ fi
+done
+
+if [ -z $ENTITYID ] ; then
+ ENTITYID=https://${HOSTS[0]}/shibboleth
+fi
+
+cat <<EOF
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="${ENTITYID}">
+ <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:1.0:protocol">
+ <md:Extensions>
+EOF
+
+count=1
+for h in ${HOSTS[@]}
+do
+ cat << EOF
+ <DiscoveryResponse xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://$h/Shibboleth.sso/DS" index="$count"/>
+EOF
+ let "count++"
+done
+
+for h in ${NAKEDHOSTS[@]}
+do
+ cat << EOF
+ <DiscoveryResponse xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="http://$h/Shibboleth.sso/DS" index="$count"/>
+EOF
+ let "count++"
+done
+
+cat << EOF
+ </md:Extensions>
+EOF
+
+for c in ${CERTS[@]}
+do
+cat << EOF
+ <md:KeyDescriptor>
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate>
+EOF
+grep -v ^- $c
+cat << EOF
+ </ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </md:KeyDescriptor>
+EOF
+done
+
+cat << EOF
+ <!--
+EOF
+
+for h in ${HOSTS[@]}
+do
+ cat <<EOF
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://$h/Shibboleth.sso/SLO/SOAP"/>
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://$h/Shibboleth.sso/SLO/Redirect"/>
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://$h/Shibboleth.sso/SLO/POST"/>
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://$h/Shibboleth.sso/SLO/Artifact"/>
+EOF
+done
+
+for h in ${NAKEDHOSTS[@]}
+do
+ cat <<EOF
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://$h/Shibboleth.sso/SLO/SOAP"/>
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://$h/Shibboleth.sso/SLO/Redirect"/>
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://$h/Shibboleth.sso/SLO/POST"/>
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://$h/Shibboleth.sso/SLO/Artifact"/>
+EOF
+done
+
+for h in ${HOSTS[@]}
+do
+ cat <<EOF
+ <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://$h/Shibboleth.sso/NIM/SOAP"/>
+ <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://$h/Shibboleth.sso/NIM/Redirect"/>
+ <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://$h/Shibboleth.sso/NIM/POST"/>
+ <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://$h/Shibboleth.sso/NIM/Artifact"/>
+EOF
+done
+
+for h in ${NAKEDHOSTS[@]}
+do
+ cat <<EOF
+ <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://$h/Shibboleth.sso/NIM/SOAP"/>
+ <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://$h/Shibboleth.sso/NIM/Redirect"/>
+ <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://$h/Shibboleth.sso/NIM/POST"/>
+ <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://$h/Shibboleth.sso/NIM/Artifact"/>
+EOF
+done
+
+cat <<EOF
+ -->
+EOF
+
+count=0
+for h in ${HOSTS[@]}
+do
+ cat <<EOF
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://$h/Shibboleth.sso/SAML2/POST" index="$((count+1))"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://$h/Shibboleth.sso/SAML2/POST-SimpleSign" index="$((count+2))"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://$h/Shibboleth.sso/SAML2/Artifact" index="$((count+3))"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://$h/Shibboleth.sso/SAML2/ECP" index="$((count+4))"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="https://$h/Shibboleth.sso/SAML/POST" index="$((count+5))"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="https://$h/Shibboleth.sso/SAML/Artifact" index="$((count+6))"/>
+EOF
+ let "count+=6"
+done
+
+for h in ${NAKEDHOSTS[@]}
+do
+ cat <<EOF
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://$h/Shibboleth.sso/SAML2/POST" index="$((count+1))"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="http://$h/Shibboleth.sso/SAML2/POST-SimpleSign" index="$((count+2))"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://$h/Shibboleth.sso/SAML2/Artifact" index="$((count+3))"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="http://$h/Shibboleth.sso/SAML2/ECP" index="$((count+4))"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="http://$h/Shibboleth.sso/SAML/POST" index="$((count+5))"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="http://$h/Shibboleth.sso/SAML/Artifact" index="$((count+6))"/>
+EOF
+ let "count+=6"
+done
+
+cat <<EOF
+ </md:SPSSODescriptor>
+EOF
+
+if [ -n "$ORGNAME" ] ; then
+ cat <<EOF
+ <md:Organization>
+ <md:OrganizationName xml:lang="en">$ORGNAME</md:OrganizationName>
+ <md:OrganizationDisplayName xml:lang="en">$ORGNAME</md:OrganizationDisplayName>
+ <md:OrganizationURL xml:lang="en">$ENTITYID</md:OrganizationURL>
+ </md:Organization>
+EOF
+fi
+
+for c in ${ADMIN[@]}
+do
+ c=(${c//\// })
+ cat <<EOF
+ <md:ContactPerson contactType="administrative">
+ <md:GivenName>${c[0]}</md:GivenName>
+ <md:SurName>${c[1]}</md:SurName>
+ <md:EmailAddress>${c[2]}</md:EmailAddress>
+ </md:ContactPerson>
+EOF
+done
+
+for c in ${SUP[@]}
+do
+ c=(${c//\// })
+ cat <<EOF
+ <md:ContactPerson contactType="support">
+ <md:GivenName>${c[0]}</md:GivenName>
+ <md:SurName>${c[1]}</md:SurName>
+ <md:EmailAddress>${c[2]}</md:EmailAddress>
+ </md:ContactPerson>
+EOF
+done
+
+for c in ${TECH[@]}
+do
+ c=(${c//\// })
+ cat <<EOF
+ <md:ContactPerson contactType="technical">
+ <md:GivenName>${c[0]}</md:GivenName>
+ <md:SurName>${c[1]}</md:SurName>
+ <md:EmailAddress>${c[2]}</md:EmailAddress>
+ </md:ContactPerson>
+EOF
+done
+
+cat <<EOF
+</md:EntityDescriptor>
+EOF
--- /dev/null
+<html>
+ <head>
+ <title>Login Completed</title>
+ <script language="Javascript">
+ <!--
+ function submitOnce() {
+ if (location.hash.length>0) {
+ if (confirm("Are you sure you want to resubmit this form information a second time?")) {
+ document.forms[0].submit();
+ } else {
+ document.body.innerHTML="<html>Form information was not resubmitted.</html>";
+ }
+ } else {
+ var loc = window.location;
+ window.location = loc + "#submitted";
+ document.forms[0].submit();
+ }
+ }
+ // -->
+ </script>
+ </head>
+ <body onload="submitOnce()">
+ <h2>Login Completed</h2>
+
+ <noscript>
+ <p>A form submission to this site was interrupted by the login process.
+ If you would like to complete it now, submit this form.</p>
+ </noscript>
+
+ <form method="POST" action="<shibmlp action/>">
+ <shibmlpfor PostedData>
+ <input type="hidden" name="<shibmlp $name/>" value="<shibmlp $value/>"/>
+ </shibmlpfor>
+ <noscript>
+ <div>
+ <input type="submit" name="_shib_continue_" value="Continue"/>
+ </div>
+ </noscript>
+ </form>
+ </body>
+</html>
<!-- The InProcess section conrains settings affecting web server modules/filters. -->
<InProcess logger="native.logger">
- <ISAPI normalizeRequest="true">
+ <ISAPI normalizeRequest="true" safeHeaderNames="true">
<!--
- Maps IIS Instance ID values to the host scheme/name/port/sslport. The name is
+ Maps IIS Instance ID values to the host scheme/name/port. The name is
required so that the proper <Host> in the request map above is found without
having to cover every possible DNS/IP combination the user might enter.
- The port and scheme can usually be omitted, so the HTTP request's port and
- scheme will be used.
-->
<Site id="1" name="sp.example.org"/>
+ <!--
+ When the port and scheme are omitted, the HTTP request's port and scheme are used.
+ If these are wrong because of virtualization, they can be explicitly set here to
+ ensure proper redirect generation.
+ -->
+ <!--
+ <Site id="42" name="virtual.example.org" scheme="https" port="443"/>
+ -->
</ISAPI>
</InProcess>
- <!-- Only one listener can be defined, to connect in process modules to shibd. -->
+ <!-- Only one listener can be defined, to connect in-process modules to shibd. -->
<UnixListener address="shibd.sock"/>
<!-- <TCPListener address="127.0.0.1" port="12345" acl="127.0.0.1"/> -->
-->
<ApplicationDefaults id="default" policyId="default"
entityID="https://sp.example.org/shibboleth"
- homeURL="https://sp.example.org/index.html"
REMOTE_USER="eppn persistent-id targeted-id"
- signing="false" encryption="false"
- >
+ signing="false" encryption="false">
<!--
Controls session lifetimes, address checks, cookie handling, and the protocol handlers.
<!-- Default example directs to a specific IdP's SSO service (favoring SAML 2 over Shib 1). -->
<SessionInitiator type="Chaining" Location="/Login" isDefault="true" id="Intranet"
relayState="cookie" entityID="https://idp.example.org/shibboleth">
- <SessionInitiator type="SAML2" defaultACSIndex="1" acsByIndex="false" template="bindingTemplate.html"/>
+ <SessionInitiator type="SAML2" defaultACSIndex="1" template="bindingTemplate.html"/>
<SessionInitiator type="Shib1" defaultACSIndex="5"/>
</SessionInitiator>
<!-- An example using an old-style WAYF, which means Shib 1 only unless an entityID is provided. -->
<SessionInitiator type="Chaining" Location="/WAYF" id="WAYF" relayState="cookie">
- <SessionInitiator type="SAML2" defaultACSIndex="1" acsByIndex="false" template="bindingTemplate.html"/>
+ <SessionInitiator type="SAML2" defaultACSIndex="1" template="bindingTemplate.html"/>
<SessionInitiator type="Shib1" defaultACSIndex="5"/>
<SessionInitiator type="WAYF" defaultACSIndex="5" URL="https://wayf.example.org/WAYF"/>
</SessionInitiator>
<!-- An example supporting the new-style of discovery service. -->
<SessionInitiator type="Chaining" Location="/DS" id="DS" relayState="cookie">
- <SessionInitiator type="SAML2" defaultACSIndex="1" acsByIndex="false" template="bindingTemplate.html"/>
+ <SessionInitiator type="SAML2" defaultACSIndex="1" template="bindingTemplate.html"/>
<SessionInitiator type="Shib1" defaultACSIndex="5"/>
- <SessionInitiator type="SAMLDS" URL="https://ds.example.org/DS"/>
+ <SessionInitiator type="SAMLDS" URL="https://ds.example.org/DS/WAYF"/>
</SessionInitiator>
<!--
<!--
<MetadataProvider type="XML" uri="http://federation.org/federation-metadata.xml"
backingFilePath="federation-metadata.xml" reloadInterval="7200">
- <SignatureMetadataFilter certificate="fedsigner.pem"/>
+ <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+ <MetadataFilter type="Signature" certificate="fedsigner.pem"/>
</MetadataProvider>
-->
<!-- Each policy defines a set of rules to use to secure messages. -->
<SecurityPolicies>
- <!-- The predefined policy enforces replay/freshness and permits signing and client TLS. -->
+ <!--
+ The predefined policy enforces replay/freshness, standard
+ condition processing, and permits signing and client TLS.
+ -->
<Policy id="default" validate="false">
- <Rule type="MessageFlow" checkReplay="true" expires="60"/>
- <Rule type="ClientCertAuth" errorFatal="true"/>
- <Rule type="XMLSigning" errorFatal="true"/>
- <Rule type="SimpleSigning" errorFatal="true"/>
+ <PolicyRule type="MessageFlow" checkReplay="true" expires="60"/>
+ <PolicyRule type="Conditions">
+ <PolicyRule type="Audience"/>
+ <!-- Enable Delegation rule to permit delegated access. -->
+ <!-- <PolicyRule type="Delegation"/> -->
+ </PolicyRule>
+ <PolicyRule type="ClientCertAuth" errorFatal="true"/>
+ <PolicyRule type="XMLSigning" errorFatal="true"/>
+ <PolicyRule type="SimpleSigning" errorFatal="true"/>
</Policy>
</SecurityPolicies>
-</SPConfig>
-
+</SPConfig>
\ No newline at end of file
# Required-Start: $local_fs $remote_fs $network
# Required-Stop: $local_fs $remote_fs $network
# Default-Start: 2 3 4 5
-# Default-Stop: S 0 1 6
+# Default-Stop: 0 1 6
# Short-Description: Shibboleth 2 Service Provider Daemon
# Description: Starts the separate daemon used by the Shibboleth
# Apache module to manage sessions and to retrieve
exit 0
fi
echo -n "Starting $DESC: "
- start-stop-daemon --background --start --quiet \
+ start-stop-daemon --start --quiet \
--pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS
echo "$NAME."
;;
start-stop-daemon --stop --quiet --pidfile $PIDFILE \
--exec $DAEMON
sleep 1
- start-stop-daemon --background --start --quiet \
+ start-stop-daemon --start --quiet \
--pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS
echo "$NAME."
;;
<key>ProgramArguments</key>
<array>
<string>@-PREFIX-@/sbin/shibd</string>
+ <string>-F</string>
<string>-f</string>
<string>-p</string>
<string>@-PKGRUNDIR-@/shibd.pid</string>
if [ -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then
/sbin/restorecon $pidfile
fi
- # daemon function just hangs, so I'm using su directly
- su - $SHIBD_USER -c "$shibd -p $pidfile -f &"
+ daemon --user $SHIBD_USER --pidfile $pidfile $shibd -p $pidfile -f -w 3
RETVAL=$?
echo
stop() {
echo -n $"Stopping $prog: "
if [ -f $pidfile ]; then
- read kpid < $pidfile
- kill $kpid
+ killproc -p $pidfile shibd
else
- killproc shibd
+ killproc shibd
fi
RETVAL=$?
start
;;
*)
- echo $"Usage: $prog {start|stop|restart}"
+ echo $"Usage: $prog {start|stop|status|restart}"
exit 1
esac
--- /dev/null
+#! /bin/sh
+# Author: Peter Schober <peter.schober@univie.ac.at> and many others
+# based on shibd-debian (from Shibboleth's 1.3.1 SP source distribution)
+# and SUSE's /etc/init.d/cyrus
+#
+# /etc/init.d/shibd
+#
+### BEGIN INIT INFO
+# Provides: shibd
+# Required-Start: network
+# Required-Stop: $null
+# Default-Start: 3 5
+# Short-Description: Shibboleth 2.x Service Provider Daemon
+# Description: Starts the separate daemon used by the Shibboleth
+# Apache module to manage state and SAML interactions.
+### END INIT INFO
+#
+
+DESC="Shibboleth 2 daemon"
+NAME=shibd
+SHIB_CONFIG=@-PKGSYSCONFDIR-@/shibboleth2.xml
+DAEMON=@-PREFIX-@/sbin/$NAME
+SCRIPTNAME=/etc/init.d/$NAME
+PID_FILE=@-PKGRUNDIR-@/shibd.pid
+DAEMON_OPTS=""
+
+# Force removal of socket
+DAEMON_OPTS="$DAEMON_OPTS -f"
+
+# Use defined configuration file
+DAEMON_OPTS="$DAEMON_OPTS -c $SHIB_CONFIG"
+
+# Specify pid file to use
+DAEMON_OPTS="$DAEMON_OPTS -p $PID_FILE"
+
+# Exit if the package is not installed.
+test -x "$DAEMON" || exit 5
+
+. /etc/rc.status
+
+# First reset status of this service
+rc_reset
+
+case "$1" in
+ start)
+ echo -n "Starting $DESC ($NAME)"
+ ## Start daemon with startproc(8). If this fails
+ ## the echo return value is set appropriate.
+
+ # NOTE: startproc return 0, even if service is
+ # already running to match LSB spec.
+ /sbin/startproc -p $PID_FILE $DAEMON $DAEMON_OPTS > /dev/null 2>&1
+
+ # Remember status and be verbose
+ rc_status -v
+ ;;
+ stop)
+ echo -n "Shutting down $DESC ($NAME)"
+ ## Stop daemon with killproc(8) and if this fails
+ ## set echo the echo return value.
+
+ /sbin/killproc -p $PID_FILE -TERM $DAEMON > /dev/null 2>&1
+
+ # Remember status and be verbose
+ rc_status -v
+ ;;
+ try-restart)
+ ## Stop the service and if this succeeds (i.e. the
+ ## service was running before), start it again.
+ ## Note: try-restart is not (yet) part of LSB (as of 0.7.5)
+ $0 status >/dev/null && $0 restart
+
+ # Remember status and be quiet
+ rc_status
+ ;;
+ restart)
+ ## Stop the service and regardless of whether it was
+ ## running or not, start it again.
+ $0 stop
+ $0 start
+
+ # Remember status and be quiet
+ rc_status
+ ;;
+ configtest)
+ ## Check config files
+
+ echo -n "Checking config for $DESC ($NAME): "
+ $DAEMON $DAEMON_OPTS -t
+ rc_status -v
+ ;;
+ status)
+ echo -n "Checking for service $DESC ($NAME)"
+ ## Check status with checkproc(8), if process is running
+ ## checkproc will return with exit status 0.
+
+ # Status has a slightly different for the status command:
+ # 0 - service running
+ # 1 - service dead, but /var/run/ pid file exists
+ # 2 - service dead, but /var/lock/ lock file exists
+ # 3 - service not running
+
+ # NOTE: checkproc returns LSB compliant status values.
+ /sbin/checkproc -p $PID_FILE $DAEMON
+ rc_status -v
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|status|configtest|try-restart|restart}"
+ exit 1
+ ;;
+esac
+rc_exit
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for shibboleth 2.1.
+# Generated by GNU Autoconf 2.59 for shibboleth 2.2.1.
#
# Report bugs to <shibboleth-users@internet2.edu>.
#
# Identity of this package.
PACKAGE_NAME='shibboleth'
PACKAGE_TARNAME='shibboleth'
-PACKAGE_VERSION='2.1'
-PACKAGE_STRING='shibboleth 2.1'
+PACKAGE_VERSION='2.2.1'
+PACKAGE_STRING='shibboleth 2.2.1'
PACKAGE_BUGREPORT='shibboleth-users@internet2.edu'
# Factoring default headers for most tests.
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DX_PROJECT DX_CONFIG DX_DOCDIR DX_ENV DX_FLAG_doc DX_DOXYGEN ac_pt_DX_DOXYGEN DX_FLAG_[]DX_CURRENT_FEATURE DX_PERL ac_pt_DX_PERL DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_doc_TRUE DX_COND_doc_FALSE DX_FLAG_dot DX_FLAG_[]DX_CURRENT_FEATURE DX_DOT ac_pt_DX_DOT DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_dot_TRUE DX_COND_dot_FALSE DX_FLAG_man DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_man_TRUE DX_COND_man_FALSE DX_FLAG_rtf DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_rtf_TRUE DX_COND_rtf_FALSE DX_FLAG_xml DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_xml_TRUE DX_COND_xml_FALSE DX_FLAG_chm DX_FLAG_[]DX_CURRENT_FEATURE DX_HHC ac_pt_DX_HHC DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_chm_TRUE DX_COND_chm_FALSE DX_FLAG_chi DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_chi_TRUE DX_COND_chi_FALSE DX_FLAG_html DX_FLAG_[]DX_CURRENT_FEATURE DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_html_TRUE DX_COND_html_FALSE DX_FLAG_ps DX_FLAG_[]DX_CURRENT_FEATURE DX_LATEX ac_pt_DX_LATEX DX_FLAG_[]DX_CURRENT_FEATURE DX_MAKEINDEX ac_pt_DX_MAKEINDEX DX_FLAG_[]DX_CURRENT_FEATURE DX_DVIPS ac_pt_DX_DVIPS DX_FLAG_[]DX_CURRENT_FEATURE DX_EGREP ac_pt_DX_EGREP DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_ps_TRUE DX_COND_ps_FALSE DX_FLAG_pdf DX_FLAG_[]DX_CURRENT_FEATURE DX_PDFLATEX ac_pt_DX_PDFLATEX DX_FLAG_[]DX_CURRENT_FEATURE DX_FLAG_[]DX_CURRENT_FEATURE DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_pdf_TRUE DX_COND_pdf_FALSE DX_COND_latex_TRUE DX_COND_latex_FALSE DOXYGEN_PAPER_SIZE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS PKG_CONFIG LOG4SHIB_CONFIG LOG4CPP_CONFIG XMLTOOLINGXMLDIR OPENSAMLXMLDIR LITE_LIBS XMLSEC_LIBS NSAPI_INCLUDE BUILD_NSAPI_TRUE BUILD_NSAPI_FALSE FASTCGI_INCLUDE FASTCGI_LDFLAGS FASTCGI_LIBS BUILD_FASTCGI_TRUE BUILD_FASTCGI_FALSE MEMCACHED_INCLUDE MEMCACHED_LDFLAGS MEMCACHED_LIBS BUILD_MEMCACHED_TRUE BUILD_MEMCACHED_FALSE xs APXS APXS_CFLAGS APXS_INCLUDE APXS2 APR_CONFIG APXS2_CFLAGS APXS2_INCLUDE APXS22 APR1_CONFIG APXS22_CFLAGS APXS22_INCLUDE BUILD_AP13_TRUE BUILD_AP13_FALSE BUILD_AP20_TRUE BUILD_AP20_FALSE BUILD_AP22_TRUE BUILD_AP22_FALSE ODBC_CONFIG ODBC_CFLAGS ODBC_LIBS WANT_SUBDIRS LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DX_PROJECT DX_CONFIG DX_DOCDIR DX_ENV DX_FLAG_doc DX_DOXYGEN ac_pt_DX_DOXYGEN DX_PERL ac_pt_DX_PERL DX_COND_doc_TRUE DX_COND_doc_FALSE DX_FLAG_dot DX_DOT ac_pt_DX_DOT DX_COND_dot_TRUE DX_COND_dot_FALSE DX_FLAG_man DX_COND_man_TRUE DX_COND_man_FALSE DX_FLAG_rtf DX_COND_rtf_TRUE DX_COND_rtf_FALSE DX_FLAG_xml DX_COND_xml_TRUE DX_COND_xml_FALSE DX_FLAG_chm DX_HHC ac_pt_DX_HHC DX_COND_chm_TRUE DX_COND_chm_FALSE DX_FLAG_chi DX_COND_chi_TRUE DX_COND_chi_FALSE DX_FLAG_html DX_COND_html_TRUE DX_COND_html_FALSE DX_FLAG_ps DX_LATEX ac_pt_DX_LATEX DX_MAKEINDEX ac_pt_DX_MAKEINDEX DX_DVIPS ac_pt_DX_DVIPS DX_EGREP ac_pt_DX_EGREP DX_COND_ps_TRUE DX_COND_ps_FALSE DX_FLAG_pdf DX_PDFLATEX ac_pt_DX_PDFLATEX DX_COND_pdf_TRUE DX_COND_pdf_FALSE DX_COND_latex_TRUE DX_COND_latex_FALSE DOXYGEN_PAPER_SIZE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS PKG_CONFIG LOG4SHIB_CONFIG LOG4CPP_CONFIG XMLTOOLINGXMLDIR OPENSAMLXMLDIR LITE_LIBS XMLSEC_LIBS NSAPI_INCLUDE BUILD_NSAPI_TRUE BUILD_NSAPI_FALSE FASTCGI_INCLUDE FASTCGI_LDFLAGS FASTCGI_LIBS BUILD_FASTCGI_TRUE BUILD_FASTCGI_FALSE MEMCACHED_INCLUDE MEMCACHED_LDFLAGS MEMCACHED_LIBS BUILD_MEMCACHED_TRUE BUILD_MEMCACHED_FALSE xs APXS APXS_CFLAGS APXS_INCLUDE APXS2 APR_CONFIG APXS2_CFLAGS APXS2_INCLUDE APXS22 APR1_CONFIG APXS22_CFLAGS APXS22_INCLUDE BUILD_AP13_TRUE BUILD_AP13_FALSE BUILD_AP20_TRUE BUILD_AP20_FALSE BUILD_AP22_TRUE BUILD_AP22_FALSE ODBC_CONFIG ODBC_CFLAGS ODBC_LIBS WANT_SUBDIRS LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures shibboleth 2.1 to adapt to many kinds of systems.
+\`configure' configures shibboleth 2.2.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of shibboleth 2.1:";;
+ short | recursive ) echo "Configuration of shibboleth 2.2.1:";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
-shibboleth configure 2.1
+shibboleth configure 2.2.1
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by shibboleth $as_me 2.1, which was
+It was created by shibboleth $as_me 2.2.1, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
# Define the identity of the package.
PACKAGE=shibboleth
- VERSION=2.1
+ VERSION=2.2.1
cat >>confdefs.h <<_ACEOF
+# Compatibility with older autoconf versions.
+
+
## --------------- ##
## Private macros. ##
## --------------- ##
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 6100 "configure"' > conftest.$ac_ext
+ echo '#line 6103 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
# Provide some information about the compiler.
-echo "$as_me:7208:" \
+echo "$as_me:7211:" \
"checking for Fortran 77 compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8246: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8249: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8250: \$? = $ac_status" >&5
+ echo "$as_me:8253: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8479: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8482: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8483: \$? = $ac_status" >&5
+ echo "$as_me:8486: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8539: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8542: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:8543: \$? = $ac_status" >&5
+ echo "$as_me:8546: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
libsuff=
case "$host_cpu" in
x86_64*|s390x*|powerpc64*)
- echo '#line 9873 "configure"' > conftest.$ac_ext
+ echo '#line 9876 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10744 "configure"
+#line 10747 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10842 "configure"
+#line 10845 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13025: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13028: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:13029: \$? = $ac_status" >&5
+ echo "$as_me:13032: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13085: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13088: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:13089: \$? = $ac_status" >&5
+ echo "$as_me:13092: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
libsuff=
case "$host_cpu" in
x86_64*|s390x*|powerpc64*)
- echo '#line 13596 "configure"' > conftest.$ac_ext
+ echo '#line 13599 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 14467 "configure"
+#line 14470 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 14565 "configure"
+#line 14568 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15392: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15395: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:15396: \$? = $ac_status" >&5
+ echo "$as_me:15399: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15452: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15455: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:15456: \$? = $ac_status" >&5
+ echo "$as_me:15459: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
libsuff=
case "$host_cpu" in
x86_64*|s390x*|powerpc64*)
- echo '#line 16766 "configure"' > conftest.$ac_ext
+ echo '#line 16769 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17511: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17514: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:17515: \$? = $ac_status" >&5
+ echo "$as_me:17518: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17744: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17747: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:17748: \$? = $ac_status" >&5
+ echo "$as_me:17751: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17804: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17807: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:17808: \$? = $ac_status" >&5
+ echo "$as_me:17811: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
libsuff=
case "$host_cpu" in
x86_64*|s390x*|powerpc64*)
- echo '#line 19138 "configure"' > conftest.$ac_ext
+ echo '#line 19141 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 20009 "configure"
+#line 20012 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 20107 "configure"
+#line 20110 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
CXXFLAGS="$PTHREAD_CFLAGS $CXXFLAGS"
fi
-# Thank you Solaris, really.
-echo "$as_me:$LINENO: checking for ctime_r" >&5
-echo $ECHO_N "checking for ctime_r... $ECHO_C" >&6
- if test -z "$ac_cv_ctime_args"; then
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <time.h>
-int
-main ()
-{
-
- time_t clock;
- char buf[26];
- ctime_r(&clock, buf);
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_ctime_args=2
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <time.h>
-int
-main ()
-{
-
- time_t clock;
- char buf[26];
- ctime_r(&clock, buf, 26);
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_ctime_args=3
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
- if test -z "$ac_cv_ctime_args"; then
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- else
- if test "$ac_cv_ctime_args" = 2; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_CTIME_R_2 1
-_ACEOF
-
- elif test "$ac_cv_ctime_args" = 3; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_CTIME_R_3 1
-_ACEOF
-
- fi
- echo "$as_me:$LINENO: result: yes, and it takes $ac_cv_ctime_args arguments" >&5
-echo "${ECHO_T}yes, and it takes $ac_cv_ctime_args arguments" >&6
- fi
-
# OpenSSL settings
# Check whether --with-openssl or --without-openssl was given.
fi
+# Thank you Solaris, really.
+echo "$as_me:$LINENO: checking for ctime_r" >&5
+echo $ECHO_N "checking for ctime_r... $ECHO_C" >&6
+ if test -z "$ac_cv_ctime_args"; then
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <time.h>
+int
+main ()
+{
+
+ time_t clock;
+ char buf[26];
+ ctime_r(&clock, buf);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_ctime_args=2
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <time.h>
+int
+main ()
+{
+
+ time_t clock;
+ char buf[26];
+ ctime_r(&clock, buf, 26);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_ctime_args=3
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test -z "$ac_cv_ctime_args"; then
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ else
+ if test "$ac_cv_ctime_args" = 2; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_CTIME_R_2 1
+_ACEOF
+
+ elif test "$ac_cv_ctime_args" = 3; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_CTIME_R_3 1
+_ACEOF
+
+ fi
+ echo "$as_me:$LINENO: result: yes, and it takes $ac_cv_ctime_args arguments" >&5
+echo "${ECHO_T}yes, and it takes $ac_cv_ctime_args arguments" >&6
+ fi
+
# log4shib settings (favor this version over the log4cpp code)
# Extract the first word of "log4shib-config", so it can be a program name with args.
set dummy log4shib-config; ac_word=$2
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
+echo "$as_me:$LINENO: checking whether Xerces XMLString::release(XMLByte**) exists" >&5
+echo $ECHO_N "checking whether Xerces XMLString::release(XMLByte**) exists... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <xercesc/util/XMLString.hpp>
+int
+main ()
+{
+using namespace XERCES_CPP_NAMESPACE;
+ XMLByte* buf=NULL;
+ XMLString::release(&buf);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE 1
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+echo "$as_me:$LINENO: checking whether Xerces DOMNodeFilter API returns a short" >&5
+echo $ECHO_N "checking whether Xerces DOMNodeFilter API returns a short... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <xercesc/dom/DOM.hpp>
+int
+main ()
+{
+using namespace XERCES_CPP_NAMESPACE;
+ class Blocker : public DOMNodeFilter {
+ public:
+ short acceptNode(const DOMNode* node) const {
+ return FILTER_REJECT;
+ }
+ };
+ static Blocker g_Blocker;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define SHIBSP_XERCESC_SHORT_ACCEPTNODE 1
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
#XML-Tooling settings
int
main ()
{
-#if _OPENSAML_VERSION >= 20000
+#if _OPENSAML_VERSION >= 20200
opensaml::SAMLConfig::getConfig();
#else
-#error Need OpenSAML version 2.0 or higher
+#error Need OpenSAML version 2.2 or higher
#endif
;
return 0;
+ ac_config_files="$ac_config_files shibboleth.spec pkginfo Portfile"
+
+
# output the underlying makefiles
WANT_SUBDIRS="doc schemas configs shibsp shibd util"
ac_config_files="$ac_config_files Makefile doc/Makefile schemas/Makefile configs/Makefile shibsp/Makefile shibd/Makefile util/Makefile selinux/Makefile"
} >&5
cat >&5 <<_CSEOF
-This file was extended by shibboleth $as_me 2.1, which was
+This file was extended by shibboleth $as_me 2.2.1, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-shibboleth config.status 2.1
+shibboleth config.status 2.2.1
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
do
case "$ac_config_target" in
# Handling of arguments.
+ "shibboleth.spec" ) CONFIG_FILES="$CONFIG_FILES shibboleth.spec" ;;
+ "pkginfo" ) CONFIG_FILES="$CONFIG_FILES pkginfo" ;;
+ "Portfile" ) CONFIG_FILES="$CONFIG_FILES Portfile" ;;
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
"schemas/Makefile" ) CONFIG_FILES="$CONFIG_FILES schemas/Makefile" ;;
s,@DX_FLAG_doc@,$DX_FLAG_doc,;t t
s,@DX_DOXYGEN@,$DX_DOXYGEN,;t t
s,@ac_pt_DX_DOXYGEN@,$ac_pt_DX_DOXYGEN,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_PERL@,$DX_PERL,;t t
s,@ac_pt_DX_PERL@,$ac_pt_DX_PERL,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_COND_doc_TRUE@,$DX_COND_doc_TRUE,;t t
s,@DX_COND_doc_FALSE@,$DX_COND_doc_FALSE,;t t
s,@DX_FLAG_dot@,$DX_FLAG_dot,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_DOT@,$DX_DOT,;t t
s,@ac_pt_DX_DOT@,$ac_pt_DX_DOT,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_COND_dot_TRUE@,$DX_COND_dot_TRUE,;t t
s,@DX_COND_dot_FALSE@,$DX_COND_dot_FALSE,;t t
s,@DX_FLAG_man@,$DX_FLAG_man,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_COND_man_TRUE@,$DX_COND_man_TRUE,;t t
s,@DX_COND_man_FALSE@,$DX_COND_man_FALSE,;t t
s,@DX_FLAG_rtf@,$DX_FLAG_rtf,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_COND_rtf_TRUE@,$DX_COND_rtf_TRUE,;t t
s,@DX_COND_rtf_FALSE@,$DX_COND_rtf_FALSE,;t t
s,@DX_FLAG_xml@,$DX_FLAG_xml,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_COND_xml_TRUE@,$DX_COND_xml_TRUE,;t t
s,@DX_COND_xml_FALSE@,$DX_COND_xml_FALSE,;t t
s,@DX_FLAG_chm@,$DX_FLAG_chm,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_HHC@,$DX_HHC,;t t
s,@ac_pt_DX_HHC@,$ac_pt_DX_HHC,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_COND_chm_TRUE@,$DX_COND_chm_TRUE,;t t
s,@DX_COND_chm_FALSE@,$DX_COND_chm_FALSE,;t t
s,@DX_FLAG_chi@,$DX_FLAG_chi,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_COND_chi_TRUE@,$DX_COND_chi_TRUE,;t t
s,@DX_COND_chi_FALSE@,$DX_COND_chi_FALSE,;t t
s,@DX_FLAG_html@,$DX_FLAG_html,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_COND_html_TRUE@,$DX_COND_html_TRUE,;t t
s,@DX_COND_html_FALSE@,$DX_COND_html_FALSE,;t t
s,@DX_FLAG_ps@,$DX_FLAG_ps,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_LATEX@,$DX_LATEX,;t t
s,@ac_pt_DX_LATEX@,$ac_pt_DX_LATEX,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_MAKEINDEX@,$DX_MAKEINDEX,;t t
s,@ac_pt_DX_MAKEINDEX@,$ac_pt_DX_MAKEINDEX,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_DVIPS@,$DX_DVIPS,;t t
s,@ac_pt_DX_DVIPS@,$ac_pt_DX_DVIPS,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_EGREP@,$DX_EGREP,;t t
s,@ac_pt_DX_EGREP@,$ac_pt_DX_EGREP,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_COND_ps_TRUE@,$DX_COND_ps_TRUE,;t t
s,@DX_COND_ps_FALSE@,$DX_COND_ps_FALSE,;t t
s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_PDFLATEX@,$DX_PDFLATEX,;t t
s,@ac_pt_DX_PDFLATEX@,$ac_pt_DX_PDFLATEX,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
s,@DX_COND_pdf_TRUE@,$DX_COND_pdf_TRUE,;t t
s,@DX_COND_pdf_FALSE@,$DX_COND_pdf_FALSE,;t t
s,@DX_COND_latex_TRUE@,$DX_COND_latex_TRUE,;t t
$ac_cs_success || { (exit 1); exit 1; }
fi
-
AC_PREREQ([2.50])
-AC_INIT([shibboleth], [2.1], [shibboleth-users@internet2.edu], [shibboleth])
+AC_INIT([shibboleth], [2.2.1], [shibboleth-users@internet2.edu], [shibboleth])
AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE([shibboleth],[2.1])
+AM_INIT_AUTOMAKE([shibboleth],[2.2.1])
sinclude(doxygen.m4)
sinclude(acx_pthread.m4)
CXXFLAGS="$PTHREAD_CFLAGS $CXXFLAGS"
fi
-# Thank you Solaris, really.
-AC_MSG_CHECKING(for ctime_r)
- if test -z "$ac_cv_ctime_args"; then
- AC_TRY_COMPILE(
- [#include <time.h>],
- [
- time_t clock;
- char buf[26];
- ctime_r(&clock, buf);
- ], ac_cv_ctime_args=2)
-
- AC_TRY_COMPILE(
- [#include <time.h>],
- [
- time_t clock;
- char buf[26];
- ctime_r(&clock, buf, 26);
- ], ac_cv_ctime_args=3)
- fi
- if test -z "$ac_cv_ctime_args"; then
- AC_MSG_RESULT(no)
- else
- if test "$ac_cv_ctime_args" = 2; then
- AC_DEFINE(HAVE_CTIME_R_2,1,[Define if ctime_r is present with 2 parameters.])
- elif test "$ac_cv_ctime_args" = 3; then
- AC_DEFINE(HAVE_CTIME_R_3,1,[Define if ctime_r is present with 3 parameters.])
- fi
- AC_MSG_RESULT([yes, and it takes $ac_cv_ctime_args arguments])
- fi
-
# OpenSSL settings
AC_ARG_WITH(openssl,
AC_HELP_STRING([--with-openssl=PATH], [where openssl is installed]),
AC_CXX_REQUIRE_STL
AC_CXX_NAMESPACES
+# Thank you Solaris, really.
+AC_MSG_CHECKING(for ctime_r)
+ if test -z "$ac_cv_ctime_args"; then
+ AC_TRY_COMPILE(
+ [#include <time.h>],
+ [
+ time_t clock;
+ char buf[26];
+ ctime_r(&clock, buf);
+ ], ac_cv_ctime_args=2)
+
+ AC_TRY_COMPILE(
+ [#include <time.h>],
+ [
+ time_t clock;
+ char buf[26];
+ ctime_r(&clock, buf, 26);
+ ], ac_cv_ctime_args=3)
+ fi
+ if test -z "$ac_cv_ctime_args"; then
+ AC_MSG_RESULT(no)
+ else
+ if test "$ac_cv_ctime_args" = 2; then
+ AC_DEFINE(HAVE_CTIME_R_2,1,[Define if ctime_r is present with 2 parameters.])
+ elif test "$ac_cv_ctime_args" = 3; then
+ AC_DEFINE(HAVE_CTIME_R_3,1,[Define if ctime_r is present with 3 parameters.])
+ fi
+ AC_MSG_RESULT([yes, and it takes $ac_cv_ctime_args arguments])
+ fi
+
# log4shib settings (favor this version over the log4cpp code)
AC_PATH_PROG(LOG4SHIB_CONFIG,log4shib-config)
AC_ARG_WITH(log4shib,
[AC_DEFINE(HAVE_LIBXERCESC,1,[Define if Xerces-C library was found])],
[AC_MSG_ERROR([unable to link with Xerces])])
+AC_MSG_CHECKING([whether Xerces XMLString::release(XMLByte**) exists])
+AC_TRY_COMPILE([#include <xercesc/util/XMLString.hpp>],
+ [using namespace XERCES_CPP_NAMESPACE;
+ XMLByte* buf=NULL;
+ XMLString::release(&buf);
+ ],
+ [AC_MSG_RESULT([yes])]
+ [AC_DEFINE([SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE], [1], [Define to 1 if Xerces XMLString includes XMLByte release.])],
+ [AC_MSG_RESULT([no])])
+
+AC_MSG_CHECKING([whether Xerces DOMNodeFilter API returns a short])
+AC_TRY_COMPILE([#include <xercesc/dom/DOM.hpp>],
+ [using namespace XERCES_CPP_NAMESPACE;
+ class Blocker : public DOMNodeFilter {
+ public:
+ short acceptNode(const DOMNode* node) const {
+ return FILTER_REJECT;
+ }
+ };
+ static Blocker g_Blocker;
+ ],
+ [AC_MSG_RESULT([yes])]
+ [AC_DEFINE([SHIBSP_XERCESC_SHORT_ACCEPTNODE], [1], [Define to 1 if Xerces DOMNodeFilter API returns a short.])],
+ [AC_MSG_RESULT([no])])
#XML-Tooling settings
AC_ARG_WITH(xmltooling,
AC_TRY_LINK(
[#include <saml/SAMLConfig.h>
#include <saml/version.h>],
- [#if _OPENSAML_VERSION >= 20000
+ [#if _OPENSAML_VERSION >= 20200
opensaml::SAMLConfig::getConfig();
#else
-#error Need OpenSAML version 2.0 or higher
+#error Need OpenSAML version 2.2 or higher
#endif],
[AC_DEFINE(HAVE_SAML,1,[Define if saml library was found])],
[AC_MSG_ERROR([unable to link with OpenSAML, or version was too old])])
AC_SUBST(LITE_LIBS)
AC_SUBST(XMLSEC_LIBS)
+AC_CONFIG_FILES([shibboleth.spec pkginfo Portfile])
+
# output the underlying makefiles
WANT_SUBDIRS="doc schemas configs shibsp shibd util"
AC_CONFIG_FILES([Makefile doc/Makefile schemas/Makefile \
LIBTOOL="$LIBTOOL --silent"
AC_OUTPUT
-
P SHIBxmlsec xml-security-c
1.4.0
P SHIBxmltool xmltooling-c
- 1.1
+ 1.2
P SHIBosaml opensaml-c
- 2.1
+ 2.2
P SHIBlog4shib log4shib
1.0
-This FastCGI application library source and object code (the\r
-"Software") and its documentation (the "Documentation") are\r
-copyrighted by Open Market, Inc ("Open Market"). The following terms\r
-apply to all files associated with the Software and Documentation\r
-unless explicitly disclaimed in individual files.\r
-\r
-Open Market permits you to use, copy, modify, distribute, and license\r
-this Software and the Documentation for any purpose, provided that\r
-existing copyright notices are retained in all copies and that this\r
-notice is included verbatim in any distributions. No written\r
-agreement, license, or royalty fee is required for any of the\r
-authorized uses. Modifications to this Software and Documentation may\r
-be copyrighted by their authors and need not follow the licensing\r
-terms described here. If modifications to this Software and\r
-Documentation have new licensing terms, the new terms must be clearly\r
-indicated on the first page of each file where they apply.\r
-\r
-OPEN MARKET MAKES NO EXPRESS OR IMPLIED WARRANTY WITH RESPECT TO THE\r
-SOFTWARE OR THE DOCUMENTATION, INCLUDING WITHOUT LIMITATION ANY\r
-WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN\r
-NO EVENT SHALL OPEN MARKET BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY\r
-DAMAGES ARISING FROM OR RELATING TO THIS SOFTWARE OR THE\r
-DOCUMENTATION, INCLUDING, WITHOUT LIMITATION, ANY INDIRECT, SPECIAL OR\r
-CONSEQUENTIAL DAMAGES OR SIMILAR DAMAGES, INCLUDING LOST PROFITS OR\r
-LOST DATA, EVEN IF OPEN MARKET HAS BEEN ADVISED OF THE POSSIBILITY OF\r
-SUCH DAMAGES. THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS".\r
-OPEN MARKET HAS NO LIABILITY IN CONTRACT, TORT, NEGLIGENCE OR\r
-OTHERWISE ARISING OUT OF THIS SOFTWARE OR THE DOCUMENTATION.\r
+This FastCGI application library source and object code (the
+"Software") and its documentation (the "Documentation") are
+copyrighted by Open Market, Inc ("Open Market"). The following terms
+apply to all files associated with the Software and Documentation
+unless explicitly disclaimed in individual files.
+
+Open Market permits you to use, copy, modify, distribute, and license
+this Software and the Documentation for any purpose, provided that
+existing copyright notices are retained in all copies and that this
+notice is included verbatim in any distributions. No written
+agreement, license, or royalty fee is required for any of the
+authorized uses. Modifications to this Software and Documentation may
+be copyrighted by their authors and need not follow the licensing
+terms described here. If modifications to this Software and
+Documentation have new licensing terms, the new terms must be clearly
+indicated on the first page of each file where they apply.
+
+OPEN MARKET MAKES NO EXPRESS OR IMPLIED WARRANTY WITH RESPECT TO THE
+SOFTWARE OR THE DOCUMENTATION, INCLUDING WITHOUT LIMITATION ANY
+WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN
+NO EVENT SHALL OPEN MARKET BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY
+DAMAGES ARISING FROM OR RELATING TO THIS SOFTWARE OR THE
+DOCUMENTATION, INCLUDING, WITHOUT LIMITATION, ANY INDIRECT, SPECIAL OR
+CONSEQUENTIAL DAMAGES OR SIMILAR DAMAGES, INCLUDING LOST PROFITS OR
+LOST DATA, EVEN IF OPEN MARKET HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES. THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS".
+OPEN MARKET HAS NO LIABILITY IN CONTRACT, TORT, NEGLIGENCE OR
+OTHERWISE ARISING OUT OF THIS SOFTWARE OR THE DOCUMENTATION.
- GNU LESSER GENERAL PUBLIC LICENSE\r
- Version 2.1, February 1999\r
-\r
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.\r
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- Everyone is permitted to copy and distribute verbatim copies\r
- of this license document, but changing it is not allowed.\r
-\r
-[This is the first released version of the Lesser GPL. It also counts\r
- as the successor of the GNU Library Public License, version 2, hence\r
- the version number 2.1.]\r
-\r
- Preamble\r
-\r
- The licenses for most software are designed to take away your\r
-freedom to share and change it. By contrast, the GNU General Public\r
-Licenses are intended to guarantee your freedom to share and change\r
-free software--to make sure the software is free for all its users.\r
-\r
- This license, the Lesser General Public License, applies to some\r
-specially designated software packages--typically libraries--of the\r
-Free Software Foundation and other authors who decide to use it. You\r
-can use it too, but we suggest you first think carefully about whether\r
-this license or the ordinary General Public License is the better\r
-strategy to use in any particular case, based on the explanations below.\r
-\r
- When we speak of free software, we are referring to freedom of use,\r
-not price. Our General Public Licenses are designed to make sure that\r
-you have the freedom to distribute copies of free software (and charge\r
-for this service if you wish); that you receive source code or can get\r
-it if you want it; that you can change the software and use pieces of\r
-it in new free programs; and that you are informed that you can do\r
-these things.\r
-\r
- To protect your rights, we need to make restrictions that forbid\r
-distributors to deny you these rights or to ask you to surrender these\r
-rights. These restrictions translate to certain responsibilities for\r
-you if you distribute copies of the library or if you modify it.\r
-\r
- For example, if you distribute copies of the library, whether gratis\r
-or for a fee, you must give the recipients all the rights that we gave\r
-you. You must make sure that they, too, receive or can get the source\r
-code. If you link other code with the library, you must provide\r
-complete object files to the recipients, so that they can relink them\r
-with the library after making changes to the library and recompiling\r
-it. And you must show them these terms so they know their rights.\r
-\r
- We protect your rights with a two-step method: (1) we copyright the\r
-library, and (2) we offer you this license, which gives you legal\r
-permission to copy, distribute and/or modify the library.\r
-\r
- To protect each distributor, we want to make it very clear that\r
-there is no warranty for the free library. Also, if the library is\r
-modified by someone else and passed on, the recipients should know\r
-that what they have is not the original version, so that the original\r
-author's reputation will not be affected by problems that might be\r
-introduced by others.\r
-\f\r
- Finally, software patents pose a constant threat to the existence of\r
-any free program. We wish to make sure that a company cannot\r
-effectively restrict the users of a free program by obtaining a\r
-restrictive license from a patent holder. Therefore, we insist that\r
-any patent license obtained for a version of the library must be\r
-consistent with the full freedom of use specified in this license.\r
-\r
- Most GNU software, including some libraries, is covered by the\r
-ordinary GNU General Public License. This license, the GNU Lesser\r
-General Public License, applies to certain designated libraries, and\r
-is quite different from the ordinary General Public License. We use\r
-this license for certain libraries in order to permit linking those\r
-libraries into non-free programs.\r
-\r
- When a program is linked with a library, whether statically or using\r
-a shared library, the combination of the two is legally speaking a\r
-combined work, a derivative of the original library. The ordinary\r
-General Public License therefore permits such linking only if the\r
-entire combination fits its criteria of freedom. The Lesser General\r
-Public License permits more lax criteria for linking other code with\r
-the library.\r
-\r
- We call this license the "Lesser" General Public License because it\r
-does Less to protect the user's freedom than the ordinary General\r
-Public License. It also provides other free software developers Less\r
-of an advantage over competing non-free programs. These disadvantages\r
-are the reason we use the ordinary General Public License for many\r
-libraries. However, the Lesser license provides advantages in certain\r
-special circumstances.\r
-\r
- For example, on rare occasions, there may be a special need to\r
-encourage the widest possible use of a certain library, so that it becomes\r
-a de-facto standard. To achieve this, non-free programs must be\r
-allowed to use the library. A more frequent case is that a free\r
-library does the same job as widely used non-free libraries. In this\r
-case, there is little to gain by limiting the free library to free\r
-software only, so we use the Lesser General Public License.\r
-\r
- In other cases, permission to use a particular library in non-free\r
-programs enables a greater number of people to use a large body of\r
-free software. For example, permission to use the GNU C Library in\r
-non-free programs enables many more people to use the whole GNU\r
-operating system, as well as its variant, the GNU/Linux operating\r
-system.\r
-\r
- Although the Lesser General Public License is Less protective of the\r
-users' freedom, it does ensure that the user of a program that is\r
-linked with the Library has the freedom and the wherewithal to run\r
-that program using a modified version of the Library.\r
-\r
- The precise terms and conditions for copying, distribution and\r
-modification follow. Pay close attention to the difference between a\r
-"work based on the library" and a "work that uses the library". The\r
-former contains code derived from the library, whereas the latter must\r
-be combined with the library in order to run.\r
-\f\r
- GNU LESSER GENERAL PUBLIC LICENSE\r
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r
-\r
- 0. This License Agreement applies to any software library or other\r
-program which contains a notice placed by the copyright holder or\r
-other authorized party saying it may be distributed under the terms of\r
-this Lesser General Public License (also called "this License").\r
-Each licensee is addressed as "you".\r
-\r
- A "library" means a collection of software functions and/or data\r
-prepared so as to be conveniently linked with application programs\r
-(which use some of those functions and data) to form executables.\r
-\r
- The "Library", below, refers to any such software library or work\r
-which has been distributed under these terms. A "work based on the\r
-Library" means either the Library or any derivative work under\r
-copyright law: that is to say, a work containing the Library or a\r
-portion of it, either verbatim or with modifications and/or translated\r
-straightforwardly into another language. (Hereinafter, translation is\r
-included without limitation in the term "modification".)\r
-\r
- "Source code" for a work means the preferred form of the work for\r
-making modifications to it. For a library, complete source code means\r
-all the source code for all modules it contains, plus any associated\r
-interface definition files, plus the scripts used to control compilation\r
-and installation of the library.\r
-\r
- Activities other than copying, distribution and modification are not\r
-covered by this License; they are outside its scope. The act of\r
-running a program using the Library is not restricted, and output from\r
-such a program is covered only if its contents constitute a work based\r
-on the Library (independent of the use of the Library in a tool for\r
-writing it). Whether that is true depends on what the Library does\r
-and what the program that uses the Library does.\r
- \r
- 1. You may copy and distribute verbatim copies of the Library's\r
-complete source code as you receive it, in any medium, provided that\r
-you conspicuously and appropriately publish on each copy an\r
-appropriate copyright notice and disclaimer of warranty; keep intact\r
-all the notices that refer to this License and to the absence of any\r
-warranty; and distribute a copy of this License along with the\r
-Library.\r
-\r
- You may charge a fee for the physical act of transferring a copy,\r
-and you may at your option offer warranty protection in exchange for a\r
-fee.\r
-\f\r
- 2. You may modify your copy or copies of the Library or any portion\r
-of it, thus forming a work based on the Library, and copy and\r
-distribute such modifications or work under the terms of Section 1\r
-above, provided that you also meet all of these conditions:\r
-\r
- a) The modified work must itself be a software library.\r
-\r
- b) You must cause the files modified to carry prominent notices\r
- stating that you changed the files and the date of any change.\r
-\r
- c) You must cause the whole of the work to be licensed at no\r
- charge to all third parties under the terms of this License.\r
-\r
- d) If a facility in the modified Library refers to a function or a\r
- table of data to be supplied by an application program that uses\r
- the facility, other than as an argument passed when the facility\r
- is invoked, then you must make a good faith effort to ensure that,\r
- in the event an application does not supply such function or\r
- table, the facility still operates, and performs whatever part of\r
- its purpose remains meaningful.\r
-\r
- (For example, a function in a library to compute square roots has\r
- a purpose that is entirely well-defined independent of the\r
- application. Therefore, Subsection 2d requires that any\r
- application-supplied function or table used by this function must\r
- be optional: if the application does not supply it, the square\r
- root function must still compute square roots.)\r
-\r
-These requirements apply to the modified work as a whole. If\r
-identifiable sections of that work are not derived from the Library,\r
-and can be reasonably considered independent and separate works in\r
-themselves, then this License, and its terms, do not apply to those\r
-sections when you distribute them as separate works. But when you\r
-distribute the same sections as part of a whole which is a work based\r
-on the Library, the distribution of the whole must be on the terms of\r
-this License, whose permissions for other licensees extend to the\r
-entire whole, and thus to each and every part regardless of who wrote\r
-it.\r
-\r
-Thus, it is not the intent of this section to claim rights or contest\r
-your rights to work written entirely by you; rather, the intent is to\r
-exercise the right to control the distribution of derivative or\r
-collective works based on the Library.\r
-\r
-In addition, mere aggregation of another work not based on the Library\r
-with the Library (or with a work based on the Library) on a volume of\r
-a storage or distribution medium does not bring the other work under\r
-the scope of this License.\r
-\r
- 3. You may opt to apply the terms of the ordinary GNU General Public\r
-License instead of this License to a given copy of the Library. To do\r
-this, you must alter all the notices that refer to this License, so\r
-that they refer to the ordinary GNU General Public License, version 2,\r
-instead of to this License. (If a newer version than version 2 of the\r
-ordinary GNU General Public License has appeared, then you can specify\r
-that version instead if you wish.) Do not make any other change in\r
-these notices.\r
-\f\r
- Once this change is made in a given copy, it is irreversible for\r
-that copy, so the ordinary GNU General Public License applies to all\r
-subsequent copies and derivative works made from that copy.\r
-\r
- This option is useful when you wish to copy part of the code of\r
-the Library into a program that is not a library.\r
-\r
- 4. You may copy and distribute the Library (or a portion or\r
-derivative of it, under Section 2) in object code or executable form\r
-under the terms of Sections 1 and 2 above provided that you accompany\r
-it with the complete corresponding machine-readable source code, which\r
-must be distributed under the terms of Sections 1 and 2 above on a\r
-medium customarily used for software interchange.\r
-\r
- If distribution of object code is made by offering access to copy\r
-from a designated place, then offering equivalent access to copy the\r
-source code from the same place satisfies the requirement to\r
-distribute the source code, even though third parties are not\r
-compelled to copy the source along with the object code.\r
-\r
- 5. A program that contains no derivative of any portion of the\r
-Library, but is designed to work with the Library by being compiled or\r
-linked with it, is called a "work that uses the Library". Such a\r
-work, in isolation, is not a derivative work of the Library, and\r
-therefore falls outside the scope of this License.\r
-\r
- However, linking a "work that uses the Library" with the Library\r
-creates an executable that is a derivative of the Library (because it\r
-contains portions of the Library), rather than a "work that uses the\r
-library". The executable is therefore covered by this License.\r
-Section 6 states terms for distribution of such executables.\r
-\r
- When a "work that uses the Library" uses material from a header file\r
-that is part of the Library, the object code for the work may be a\r
-derivative work of the Library even though the source code is not.\r
-Whether this is true is especially significant if the work can be\r
-linked without the Library, or if the work is itself a library. The\r
-threshold for this to be true is not precisely defined by law.\r
-\r
- If such an object file uses only numerical parameters, data\r
-structure layouts and accessors, and small macros and small inline\r
-functions (ten lines or less in length), then the use of the object\r
-file is unrestricted, regardless of whether it is legally a derivative\r
-work. (Executables containing this object code plus portions of the\r
-Library will still fall under Section 6.)\r
-\r
- Otherwise, if the work is a derivative of the Library, you may\r
-distribute the object code for the work under the terms of Section 6.\r
-Any executables containing that work also fall under Section 6,\r
-whether or not they are linked directly with the Library itself.\r
-\f\r
- 6. As an exception to the Sections above, you may also combine or\r
-link a "work that uses the Library" with the Library to produce a\r
-work containing portions of the Library, and distribute that work\r
-under terms of your choice, provided that the terms permit\r
-modification of the work for the customer's own use and reverse\r
-engineering for debugging such modifications.\r
-\r
- You must give prominent notice with each copy of the work that the\r
-Library is used in it and that the Library and its use are covered by\r
-this License. You must supply a copy of this License. If the work\r
-during execution displays copyright notices, you must include the\r
-copyright notice for the Library among them, as well as a reference\r
-directing the user to the copy of this License. Also, you must do one\r
-of these things:\r
-\r
- a) Accompany the work with the complete corresponding\r
- machine-readable source code for the Library including whatever\r
- changes were used in the work (which must be distributed under\r
- Sections 1 and 2 above); and, if the work is an executable linked\r
- with the Library, with the complete machine-readable "work that\r
- uses the Library", as object code and/or source code, so that the\r
- user can modify the Library and then relink to produce a modified\r
- executable containing the modified Library. (It is understood\r
- that the user who changes the contents of definitions files in the\r
- Library will not necessarily be able to recompile the application\r
- to use the modified definitions.)\r
-\r
- b) Use a suitable shared library mechanism for linking with the\r
- Library. A suitable mechanism is one that (1) uses at run time a\r
- copy of the library already present on the user's computer system,\r
- rather than copying library functions into the executable, and (2)\r
- will operate properly with a modified version of the library, if\r
- the user installs one, as long as the modified version is\r
- interface-compatible with the version that the work was made with.\r
-\r
- c) Accompany the work with a written offer, valid for at\r
- least three years, to give the same user the materials\r
- specified in Subsection 6a, above, for a charge no more\r
- than the cost of performing this distribution.\r
-\r
- d) If distribution of the work is made by offering access to copy\r
- from a designated place, offer equivalent access to copy the above\r
- specified materials from the same place.\r
-\r
- e) Verify that the user has already received a copy of these\r
- materials or that you have already sent this user a copy.\r
-\r
- For an executable, the required form of the "work that uses the\r
-Library" must include any data and utility programs needed for\r
-reproducing the executable from it. However, as a special exception,\r
-the materials to be distributed need not include anything that is\r
-normally distributed (in either source or binary form) with the major\r
-components (compiler, kernel, and so on) of the operating system on\r
-which the executable runs, unless that component itself accompanies\r
-the executable.\r
-\r
- It may happen that this requirement contradicts the license\r
-restrictions of other proprietary libraries that do not normally\r
-accompany the operating system. Such a contradiction means you cannot\r
-use both them and the Library together in an executable that you\r
-distribute.\r
-\f\r
- 7. You may place library facilities that are a work based on the\r
-Library side-by-side in a single library together with other library\r
-facilities not covered by this License, and distribute such a combined\r
-library, provided that the separate distribution of the work based on\r
-the Library and of the other library facilities is otherwise\r
-permitted, and provided that you do these two things:\r
-\r
- a) Accompany the combined library with a copy of the same work\r
- based on the Library, uncombined with any other library\r
- facilities. This must be distributed under the terms of the\r
- Sections above.\r
-\r
- b) Give prominent notice with the combined library of the fact\r
- that part of it is a work based on the Library, and explaining\r
- where to find the accompanying uncombined form of the same work.\r
-\r
- 8. You may not copy, modify, sublicense, link with, or distribute\r
-the Library except as expressly provided under this License. Any\r
-attempt otherwise to copy, modify, sublicense, link with, or\r
-distribute the Library is void, and will automatically terminate your\r
-rights under this License. However, parties who have received copies,\r
-or rights, from you under this License will not have their licenses\r
-terminated so long as such parties remain in full compliance.\r
-\r
- 9. You are not required to accept this License, since you have not\r
-signed it. However, nothing else grants you permission to modify or\r
-distribute the Library or its derivative works. These actions are\r
-prohibited by law if you do not accept this License. Therefore, by\r
-modifying or distributing the Library (or any work based on the\r
-Library), you indicate your acceptance of this License to do so, and\r
-all its terms and conditions for copying, distributing or modifying\r
-the Library or works based on it.\r
-\r
- 10. Each time you redistribute the Library (or any work based on the\r
-Library), the recipient automatically receives a license from the\r
-original licensor to copy, distribute, link with or modify the Library\r
-subject to these terms and conditions. You may not impose any further\r
-restrictions on the recipients' exercise of the rights granted herein.\r
-You are not responsible for enforcing compliance by third parties with\r
-this License.\r
-\f\r
- 11. If, as a consequence of a court judgment or allegation of patent\r
-infringement or for any other reason (not limited to patent issues),\r
-conditions are imposed on you (whether by court order, agreement or\r
-otherwise) that contradict the conditions of this License, they do not\r
-excuse you from the conditions of this License. If you cannot\r
-distribute so as to satisfy simultaneously your obligations under this\r
-License and any other pertinent obligations, then as a consequence you\r
-may not distribute the Library at all. For example, if a patent\r
-license would not permit royalty-free redistribution of the Library by\r
-all those who receive copies directly or indirectly through you, then\r
-the only way you could satisfy both it and this License would be to\r
-refrain entirely from distribution of the Library.\r
-\r
-If any portion of this section is held invalid or unenforceable under any\r
-particular circumstance, the balance of the section is intended to apply,\r
-and the section as a whole is intended to apply in other circumstances.\r
-\r
-It is not the purpose of this section to induce you to infringe any\r
-patents or other property right claims or to contest validity of any\r
-such claims; this section has the sole purpose of protecting the\r
-integrity of the free software distribution system which is\r
-implemented by public license practices. Many people have made\r
-generous contributions to the wide range of software distributed\r
-through that system in reliance on consistent application of that\r
-system; it is up to the author/donor to decide if he or she is willing\r
-to distribute software through any other system and a licensee cannot\r
-impose that choice.\r
-\r
-This section is intended to make thoroughly clear what is believed to\r
-be a consequence of the rest of this License.\r
-\r
- 12. If the distribution and/or use of the Library is restricted in\r
-certain countries either by patents or by copyrighted interfaces, the\r
-original copyright holder who places the Library under this License may add\r
-an explicit geographical distribution limitation excluding those countries,\r
-so that distribution is permitted only in or among countries not thus\r
-excluded. In such case, this License incorporates the limitation as if\r
-written in the body of this License.\r
-\r
- 13. The Free Software Foundation may publish revised and/or new\r
-versions of the Lesser General Public License from time to time.\r
-Such new versions will be similar in spirit to the present version,\r
-but may differ in detail to address new problems or concerns.\r
-\r
-Each version is given a distinguishing version number. If the Library\r
-specifies a version number of this License which applies to it and\r
-"any later version", you have the option of following the terms and\r
-conditions either of that version or of any later version published by\r
-the Free Software Foundation. If the Library does not specify a\r
-license version number, you may choose any version ever published by\r
-the Free Software Foundation.\r
-\f\r
- 14. If you wish to incorporate parts of the Library into other free\r
-programs whose distribution conditions are incompatible with these,\r
-write to the author to ask for permission. For software which is\r
-copyrighted by the Free Software Foundation, write to the Free\r
-Software Foundation; we sometimes make exceptions for this. Our\r
-decision will be guided by the two goals of preserving the free status\r
-of all derivatives of our free software and of promoting the sharing\r
-and reuse of software generally.\r
-\r
- NO WARRANTY\r
-\r
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\r
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\r
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\r
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY\r
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\r
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\r
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\r
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\r
-\r
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\r
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\r
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\r
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\r
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\r
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\r
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\r
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\r
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\r
-DAMAGES.\r
-\r
- END OF TERMS AND CONDITIONS\r
-\f\r
- How to Apply These Terms to Your New Libraries\r
-\r
- If you develop a new library, and you want it to be of the greatest\r
-possible use to the public, we recommend making it free software that\r
-everyone can redistribute and change. You can do so by permitting\r
-redistribution under these terms (or, alternatively, under the terms of the\r
-ordinary General Public License).\r
-\r
- To apply these terms, attach the following notices to the library. It is\r
-safest to attach them to the start of each source file to most effectively\r
-convey the exclusion of warranty; and each file should have at least the\r
-"copyright" line and a pointer to where the full notice is found.\r
-\r
- <one line to give the library's name and a brief idea of what it does.>\r
- Copyright (C) <year> <name of author>\r
-\r
- This library is free software; you can redistribute it and/or\r
- modify it under the terms of the GNU Lesser General Public\r
- License as published by the Free Software Foundation; either\r
- version 2.1 of the License, or (at your option) any later version.\r
-\r
- This library is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- Lesser General Public License for more details.\r
-\r
- You should have received a copy of the GNU Lesser General Public\r
- License along with this library; if not, write to the Free Software\r
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
-\r
-Also add information on how to contact you by electronic and paper mail.\r
-\r
-You should also get your employer (if you work as a programmer) or your\r
-school, if any, to sign a "copyright disclaimer" for the library, if\r
-necessary. Here is a sample; alter the names:\r
-\r
- Yoyodyne, Inc., hereby disclaims all copyright interest in the\r
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.\r
-\r
- <signature of Ty Coon>, 1 April 1990\r
- Ty Coon, President of Vice\r
-\r
-That's all there is to it!\r
-\r
-\r
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
AUTOMAKE_OPTIONS = foreign
-pkgdocdir = $(datadir)/doc/@PACKAGE@
+pkgdocdir = $(datadir)/doc/@PACKAGE@-@PACKAGE_VERSION@
+
+install-data-hook:
+ cp -r api $(DESTDIR)$(pkgdocdir)
+ rm -rf `find $(DESTDIR)$(pkgdocdir)/api -name .svn`
docfiles = \
CREDITS.txt \
target_alias = @target_alias@
xs = @xs@
AUTOMAKE_OPTIONS = foreign
-pkgdocdir = $(datadir)/doc/@PACKAGE@
+pkgdocdir = $(datadir)/doc/@PACKAGE@-@PACKAGE_VERSION@
docfiles = \
CREDITS.txt \
LICENSE.txt \
info-am:
install-data-am: install-pkgdocDATA
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
install-exec-am:
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am html html-am info info-am install install-am \
- install-data install-data-am install-exec install-exec-am \
- install-info install-info-am install-man install-pkgdocDATA \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- uninstall uninstall-am uninstall-info-am uninstall-pkgdocDATA
-
+ install-data install-data-am install-data-hook install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-pkgdocDATA install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am uninstall uninstall-am uninstall-info-am \
+ uninstall-pkgdocDATA
+
+
+install-data-hook:
+ cp -r api $(DESTDIR)$(pkgdocdir)
+ rm -rf `find $(DESTDIR)$(pkgdocdir)/api -name .svn`
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
-\r
- LICENSE ISSUES\r
- ==============\r
-\r
- The OpenSSL toolkit stays under a dual license, i.e. both the conditions of\r
- the OpenSSL License and the original SSLeay license apply to the toolkit.\r
- See below for the actual license texts. Actually both licenses are BSD-style\r
- Open Source licenses. In case of any license issues related to OpenSSL\r
- please contact openssl-core@openssl.org.\r
-\r
- OpenSSL License\r
- ---------------\r
-\r
-/* ====================================================================\r
- * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer. \r
- *\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in\r
- * the documentation and/or other materials provided with the\r
- * distribution.\r
- *\r
- * 3. All advertising materials mentioning features or use of this\r
- * software must display the following acknowledgment:\r
- * "This product includes software developed by the OpenSSL Project\r
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"\r
- *\r
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to\r
- * endorse or promote products derived from this software without\r
- * prior written permission. For written permission, please contact\r
- * openssl-core@openssl.org.\r
- *\r
- * 5. Products derived from this software may not be called "OpenSSL"\r
- * nor may "OpenSSL" appear in their names without prior written\r
- * permission of the OpenSSL Project.\r
- *\r
- * 6. Redistributions of any form whatsoever must retain the following\r
- * acknowledgment:\r
- * "This product includes software developed by the OpenSSL Project\r
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\r
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR\r
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
- * OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * ====================================================================\r
- *\r
- * This product includes cryptographic software written by Eric Young\r
- * (eay@cryptsoft.com). This product includes software written by Tim\r
- * Hudson (tjh@cryptsoft.com).\r
- *\r
- */\r
-\r
- Original SSLeay License\r
- -----------------------\r
-\r
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)\r
- * All rights reserved.\r
- *\r
- * This package is an SSL implementation written\r
- * by Eric Young (eay@cryptsoft.com).\r
- * The implementation was written so as to conform with Netscapes SSL.\r
- * \r
- * This library is free for commercial and non-commercial use as long as\r
- * the following conditions are aheared to. The following conditions\r
- * apply to all code found in this distribution, be it the RC4, RSA,\r
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation\r
- * included with this distribution is covered by the same copyright terms\r
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).\r
- * \r
- * Copyright remains Eric Young's, and as such any Copyright notices in\r
- * the code are not to be removed.\r
- * If this package is used in a product, Eric Young should be given attribution\r
- * as the author of the parts of the library used.\r
- * This can be in the form of a textual message at program startup or\r
- * in documentation (online or textual) provided with the package.\r
- * \r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- * 3. All advertising materials mentioning features or use of this software\r
- * must display the following acknowledgement:\r
- * "This product includes cryptographic software written by\r
- * Eric Young (eay@cryptsoft.com)"\r
- * The word 'cryptographic' can be left out if the rouines from the library\r
- * being used are not cryptographic related :-).\r
- * 4. If you include any Windows specific code (or a derivative thereof) from \r
- * the apps directory (application code) you must include an acknowledgement:\r
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"\r
- * \r
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
- * SUCH DAMAGE.\r
- * \r
- * The licence and distribution terms for any publically available version or\r
- * derivative of this code cannot be changed. i.e. this code cannot simply be\r
- * copied and put under another distribution licence\r
- * [including the GNU Public Licence.]\r
- */\r
-\r
+
+ LICENSE ISSUES
+ ==============
+
+ The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+ the OpenSSL License and the original SSLeay license apply to the toolkit.
+ See below for the actual license texts. Actually both licenses are BSD-style
+ Open Source licenses. In case of any license issues related to OpenSSL
+ please contact openssl-core@openssl.org.
+
+ OpenSSL License
+ ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``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 THE OpenSSL 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 product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
-August 8, 2008
-Version 2.1
+Version 2.2.1
Welcome to Internet2's Shibboleth
Release Notes
Shibboleth Native SP
-2.1
-8/8/2008
+2.2.1
NOTE: The shibboleth2.xml configuration format in this release
-is fully compatible with the 2.0 release.
+is fully compatible with the 2.1 release, but there are some small
+changes required to eliminate various warnings about deprecated options.
List of issues addressed by this release:
-https://bugs.internet2.edu/jira/secure/IssueNavigator.jspa?reset=true&&pid=10011&fixfor=10129&status=5&status=6&sorter/field=issuekey&sorter/order=ASC
+https://bugs.internet2.edu/jira/secure/IssueNavigator.jspa?reset=true&&pid=10011&fixfor=10232&status=5&status=6&sorter/field=issuekey&sorter/order=ASC
Fully Supported
- Metadata Providers
- Bulk resolution via local file, or URL with local file backup
- Dynamic resolution and caching based on entityID
- - Filtering based on whitelist, blacklist, or signature verification
+ - Filtering based on whitelist, blacklist, or signature verification
+ - Support for enhanced PKI processing in transport and signature verification
- Metadata Generation Handler
- Generates and optionally signs SAML metadata based on SP configuration
- XML signing
- Simple "blob" signing
- TLS X.509 certificate authentication
+ - SAML condition handling
- Client transport authentication to SOAP endpoints via libcurl
- TLS X.509 client certificates
- Strings
- Value/scope pairs (legacy and value@scope syntaxes supported)
- NameIDs
+ - XML to base64-encoded XML
+ - DOM to internal data structure
+ - KeyInfo-based data, including metadata-derived KeyDescriptors
+ - Metadata EntityAttributes extension "tags"
- Attribute Filtering
- Policy language compatible with IdP filtering, except that references
- Enhanced Spoofing Detection
- Detects and blocks client headers that would match known attribute headers
- - Does not support Apache mod_rewrite, but can be disabled when necessary
+ - Key-based mechanism to handle internal server redirection while maintaining protection
- ODBC Clustering Support
- Tested against a few different servers with various drivers
- Reporting of SAML status errors
- Optional redirection to custom error handler
+- Form POST data preservation
+ - Support on Apache for preserving URL-encoded form data across SSO
+
- Apache module enhancements
- "OR" coexistence with other authorization modules
- htaccess-based override of any valid RequestMap property
-body {\r
- background-color: #FFFFFF;\r
- font-family : Geneva, Arial, Helvetica, sans-serif;\r
- text-align: center;\r
- letter-spacing: 0px;\r
- color: black;\r
- text-align: left;\r
-}\r
-\r
-p {\r
- font-size: 10pt;\r
- margin-top: 20px;\r
- margin-bottom: 20px;\r
-}\r
-\r
-\r
-li {\r
-\r
- font-size: 10pt;\r
-}\r
-\r
-h1 {\r
- font-size: 14pt;\r
- font-weight: bold;\r
-}\r
-\r
-h2 { \r
- font-size: 12pt;\r
- font-weight: bold;\r
-}\r
-\r
-.error {\r
- font-size: 10pt;\r
- font-weight: bold;\r
-}\r
-\r
-img {\r
- margin-bottom: 15px;\r
+body {
+ background-color: #FFFFFF;
+ font-family : Geneva, Arial, Helvetica, sans-serif;
+ text-align: center;
+ letter-spacing: 0px;
+ color: black;
+ text-align: left;
+}
+
+p {
+ font-size: 10pt;
+ margin-top: 20px;
+ margin-bottom: 20px;
+}
+
+
+li {
+
+ font-size: 10pt;
+}
+
+h1 {
+ font-size: 14pt;
+ font-weight: bold;
+}
+
+h2 {
+ font-size: 12pt;
+ font-weight: bold;
+}
+
+.error {
+ font-size: 10pt;
+ font-weight: bold;
+}
+
+img {
+ margin-bottom: 15px;
}
\ No newline at end of file
AC_DEFUN([DX_FEATURE_pdf], ON)
AC_DEFUN([DX_FEATURE_ps], ON)
+# Compatibility with older autoconf versions.
+m4_ifdef([AS_HELP_STRING], , [m4_define([AS_HELP_STRING], m4_defn([AC_HELP_STRING]))])
+
## --------------- ##
## Private macros. ##
## --------------- ##
AC_PATH_TOOL([$1], [$2])
if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
- AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
+ AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0)
fi
])
# ----------------------------------------------------------
# Turn off the DX_CURRENT_FEATURE if the required feature is off.
AC_DEFUN([DX_CLEAR_DEPEND], [
-test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
+test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0)
])
# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
/*\r
- * Copyright 2001-2007 Internet2\r
+ * Copyright 2001-2009 Internet2\r
*\r
* Licensed under the Apache License, Version 2.0 (the "License");\r
* you may not use this file except in compliance with the License.\r
return s ? atol(s) : 0;\r
}\r
string getRemoteAddr() const {\r
+ string ret = AbstractSPRequest::getRemoteAddr();\r
+ if (!ret.empty())\r
+ return ret;\r
const char* s = FCGX_GetParam("REMOTE_ADDR", m_req->envp);\r
return s ? s : "";\r
}\r
}\r
return "";\r
}\r
+ void setAuthType(const char* authtype) {\r
+ if (authtype)\r
+ m_request_headers["AUTH_TYPE"] = authtype;\r
+ else\r
+ m_request_headers.erase("AUTH_TYPE");\r
+ }\r
+ string getAuthType() const {\r
+ map<string,string>::const_iterator i = m_request_headers.find("AUTH_TYPE");\r
+ if (i != m_request_headers.end())\r
+ return i->second;\r
+ else {\r
+ char* auth_type = FCGX_GetParam("AUTH_TYPE", m_req->envp);\r
+ if (auth_type)\r
+ return auth_type;\r
+ }\r
+ return "";\r
+ }\r
void setResponseHeader(const char* name, const char* value) {\r
// Set for later.\r
if (value)\r
//\r
\r
VS_VERSION_INFO VERSIONINFO\r
- FILEVERSION 2,1,0,0\r
- PRODUCTVERSION 2,1,0,0\r
+ FILEVERSION 2,2,1,0\r
+ PRODUCTVERSION 2,2,1,0\r
FILEFLAGSMASK 0x3fL\r
#ifdef _DEBUG\r
FILEFLAGS 0x1L\r
VALUE "Comments", "\0"\r
VALUE "CompanyName", "Internet2\0"\r
VALUE "FileDescription", "Shibboleth FastCGI Authorizer\0"\r
- VALUE "FileVersion", "2, 1, 0, 0\0"\r
+ VALUE "FileVersion", "2, 2, 1, 0\0"\r
VALUE "InternalName", "shibauthorizer\0"\r
- VALUE "LegalCopyright", "Copyright © 2008 Internet2\0"\r
+ VALUE "LegalCopyright", "Copyright © 2009 Internet2\0"\r
VALUE "LegalTrademarks", "\0"\r
VALUE "OriginalFilename", "shibauthorizer.exe\0"\r
VALUE "PrivateBuild", "\0"\r
- VALUE "ProductName", "Shibboleth 2.1\0"\r
- VALUE "ProductVersion", "2, 1, 0, 0\0"\r
+ VALUE "ProductName", "Shibboleth 2.2.1\0"\r
+ VALUE "ProductVersion", "2, 2, 1, 0\0"\r
VALUE "SpecialBuild", "\0"\r
END\r
END\r
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="8.00"\r
+ Version="9.00"\r
Name="shibauthorizer"\r
ProjectGUID="{8CF7DDFA-EAA0-416E-853E-3DCB210C4AE0}"\r
+ TargetFrameworkVersion="131072"\r
>\r
<Platforms>\r
<Platform\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="xerces-c_2.lib xmltooling1.lib libfcgi.lib"\r
+ AdditionalDependencies="xerces-c_3.lib xmltooling1.lib libfcgi.lib"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)",\fcgi-2.4.0-VC8\libfcgi\$(ConfigurationName)"\r
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";"\fcgi-2.4.0-VC9\Win32\$(ConfigurationName)""\r
SubSystem="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
- IntermediateDirectory="$(ProjectName)-$(ConfigurationName)"\r
+ Name="Release|x64"\r
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ProjectName)-$(ConfigurationName)"\r
ConfigurationType="1"\r
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
UseOfMFC="0"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\shibauthorizer___Win32_Debug/shibauthorizer.tlb"\r
+ TargetEnvironment="3"\r
+ TypeLibraryName=".\shibauthorizer___Win32_Release/shibauthorizer.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="0"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="1"\r
AdditionalIncludeDirectories=".;..;"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="3"\r
- BrowseInformation="1"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"\r
+ StringPooling="true"\r
+ RuntimeLibrary="2"\r
+ EnableFunctionLevelLinking="true"\r
WarningLevel="3"\r
SuppressStartupBanner="true"\r
- DebugInformationFormat="4"\r
/>\r
<Tool\r
Name="VCManagedResourceCompilerTool"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="_DEBUG"\r
+ PreprocessorDefinitions="NDEBUG"\r
Culture="1033"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="xerces-c_2D.lib xmltooling1D.lib libfcgi.lib"\r
- LinkIncremental="2"\r
+ AdditionalDependencies="xerces-c_3.lib xmltooling1.lib libfcgi.lib"\r
+ LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)",\fcgi-2.4.0-VC8\libfcgi\$(ConfigurationName)"\r
- GenerateDebugInformation="true"\r
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";"\fcgi-2.4.0-VC9\Win32\$(PlatformName)\$(ConfigurationName)""\r
+ ProgramDatabaseFile=".\shibauthorizer___Win32_Release/shibauthorizer.pdb"\r
SubSystem="1"\r
- TargetMachine="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="17"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Release|x64"\r
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
- IntermediateDirectory="$(PlatformName)\$(ProjectName)-$(ConfigurationName)"\r
+ Name="Debug|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ProjectName)-$(ConfigurationName)"\r
ConfigurationType="1"\r
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
UseOfMFC="0"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TargetEnvironment="3"\r
- TypeLibraryName=".\shibauthorizer___Win32_Release/shibauthorizer.tlb"\r
+ TypeLibraryName=".\shibauthorizer___Win32_Debug/shibauthorizer.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="2"\r
- InlineFunctionExpansion="1"\r
+ Optimization="0"\r
AdditionalIncludeDirectories=".;..;"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"\r
- StringPooling="true"\r
- RuntimeLibrary="2"\r
- EnableFunctionLevelLinking="true"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="3"\r
+ BrowseInformation="1"\r
WarningLevel="3"\r
SuppressStartupBanner="true"\r
+ DebugInformationFormat="4"\r
/>\r
<Tool\r
Name="VCManagedResourceCompilerTool"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="NDEBUG"\r
+ PreprocessorDefinitions="_DEBUG"\r
Culture="1033"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="xerces-c_2.lib xmltooling1.lib libfcgi.lib"\r
- LinkIncremental="1"\r
+ AdditionalDependencies="xerces-c_3D.lib xmltooling1D.lib libfcgi.lib"\r
+ LinkIncremental="2"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)",\fcgi-2.4.0-VC8\libfcgi\$(ConfigurationName)"\r
- ProgramDatabaseFile=".\shibauthorizer___Win32_Release/shibauthorizer.pdb"\r
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";"\fcgi-2.4.0-VC9\Win32\$(ConfigurationName)""\r
+ GenerateDebugInformation="true"\r
SubSystem="1"\r
- TargetMachine="17"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="1"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="xerces-c_2D.lib xmltooling1D.lib libfcgi.lib"\r
+ AdditionalDependencies="xerces-c_3D.lib xmltooling1D.lib libfcgi.lib"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)",\fcgi-2.4.0-VC8\libfcgi\$(ConfigurationName)"\r
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";"\fcgi-2.4.0-VC9\Win32\$(PlatformName)\$(ConfigurationName)""\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\shibauthorizer___Win32_Debug/shibauthorizer.pdb"\r
SubSystem="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="17"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Debug|Win32"\r
+ Name="Release|x64"\r
>\r
<Tool\r
Name="VCCLCompilerTool"\r
/>\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|x64"\r
+ Name="Debug|Win32"\r
>\r
<Tool\r
Name="VCCLCompilerTool"\r
return s ? s : "";\r
}\r
string getRemoteAddr() const {\r
+ string ret = AbstractSPRequest::getRemoteAddr();\r
+ if (!ret.empty())\r
+ return ret;\r
const char* s = FCGX_GetParam("REMOTE_ADDR", m_req->envp);\r
return s ? s : "";\r
}\r
//\r
\r
VS_VERSION_INFO VERSIONINFO\r
- FILEVERSION 2,1,0,0\r
- PRODUCTVERSION 2,1,0,0\r
+ FILEVERSION 2,2,1,0\r
+ PRODUCTVERSION 2,2,1,0\r
FILEFLAGSMASK 0x3fL\r
#ifdef _DEBUG\r
FILEFLAGS 0x1L\r
VALUE "Comments", "\0"\r
VALUE "CompanyName", "Internet2\0"\r
VALUE "FileDescription", "Shibboleth FastCGI Responder\0"\r
- VALUE "FileVersion", "2, 1, 0, 0\0"\r
+ VALUE "FileVersion", "2, 2, 1, 0\0"\r
VALUE "InternalName", "shibresponder\0"\r
- VALUE "LegalCopyright", "Copyright © 2008 Internet2\0"\r
+ VALUE "LegalCopyright", "Copyright © 2009 Internet2\0"\r
VALUE "LegalTrademarks", "\0"\r
VALUE "OriginalFilename", "shibresponder.exe\0"\r
VALUE "PrivateBuild", "\0"\r
- VALUE "ProductName", "Shibboleth 2.1\0"\r
- VALUE "ProductVersion", "2, 1, 0, 0\0"\r
+ VALUE "ProductName", "Shibboleth 2.2.1\0"\r
+ VALUE "ProductVersion", "2, 2, 1, 0\0"\r
VALUE "SpecialBuild", "\0"\r
END\r
END\r
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="8.00"\r
+ Version="9.00"\r
Name="shibresponder"\r
ProjectGUID="{B2423DCE-048D-4BAA-9AB9-F5D1FCDD3D25}"\r
+ RootNamespace="shibresponder"\r
+ TargetFrameworkVersion="131072"\r
>\r
<Platforms>\r
<Platform\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="xerces-c_2.lib xmltooling1.lib libfcgi.lib"\r
+ AdditionalDependencies="xerces-c_3.lib xmltooling1.lib libfcgi.lib"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)",\fcgi-2.4.0-VC8\libfcgi\$(ConfigurationName)"\r
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";"\fcgi-2.4.0-VC9\Win32\$(ConfigurationName)""\r
SubSystem="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
- IntermediateDirectory="$(ProjectName)-$(ConfigurationName)"\r
+ Name="Release|x64"\r
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ProjectName)-$(ConfigurationName)"\r
ConfigurationType="1"\r
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
UseOfMFC="0"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TypeLibraryName=".\shibresponder___Win32_Debug/shibresponder.tlb"\r
+ TargetEnvironment="3"\r
+ TypeLibraryName=".\shibresponder___Win32_Release/shibresponder.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="0"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="1"\r
AdditionalIncludeDirectories=".;..;"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="3"\r
- BrowseInformation="1"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"\r
+ StringPooling="true"\r
+ RuntimeLibrary="2"\r
+ EnableFunctionLevelLinking="true"\r
WarningLevel="3"\r
SuppressStartupBanner="true"\r
- DebugInformationFormat="4"\r
/>\r
<Tool\r
Name="VCManagedResourceCompilerTool"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="_DEBUG"\r
+ PreprocessorDefinitions="NDEBUG"\r
Culture="1033"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="xerces-c_2D.lib xmltooling1D.lib libfcgi.lib"\r
- LinkIncremental="2"\r
+ AdditionalDependencies="xerces-c_3.lib xmltooling1.lib libfcgi.lib"\r
+ LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)",\fcgi-2.4.0-VC8\libfcgi\$(ConfigurationName)"\r
- GenerateDebugInformation="true"\r
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";"\fcgi-2.4.0-VC9\Win32\$(PlatformName)\$(ConfigurationName)""\r
+ ProgramDatabaseFile=".\shibresponder___Win32_Release/shibresponder.pdb"\r
SubSystem="1"\r
- TargetMachine="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="17"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Release|x64"\r
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
- IntermediateDirectory="$(PlatformName)\$(ProjectName)-$(ConfigurationName)"\r
+ Name="Debug|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ProjectName)-$(ConfigurationName)"\r
ConfigurationType="1"\r
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
UseOfMFC="0"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TargetEnvironment="3"\r
- TypeLibraryName=".\shibresponder___Win32_Release/shibresponder.tlb"\r
+ TypeLibraryName=".\shibresponder___Win32_Debug/shibresponder.tlb"\r
HeaderFileName=""\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="2"\r
- InlineFunctionExpansion="1"\r
+ Optimization="0"\r
AdditionalIncludeDirectories=".;..;"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"\r
- StringPooling="true"\r
- RuntimeLibrary="2"\r
- EnableFunctionLevelLinking="true"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="3"\r
+ BrowseInformation="1"\r
WarningLevel="3"\r
SuppressStartupBanner="true"\r
+ DebugInformationFormat="4"\r
/>\r
<Tool\r
Name="VCManagedResourceCompilerTool"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="NDEBUG"\r
+ PreprocessorDefinitions="_DEBUG"\r
Culture="1033"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="xerces-c_2.lib xmltooling1.lib libfcgi.lib"\r
- LinkIncremental="1"\r
+ AdditionalDependencies="xerces-c_3D.lib xmltooling1D.lib libfcgi.lib"\r
+ LinkIncremental="2"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)",\fcgi-2.4.0-VC8\libfcgi\$(ConfigurationName)"\r
- ProgramDatabaseFile=".\shibresponder___Win32_Release/shibresponder.pdb"\r
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";"\fcgi-2.4.0-VC9\Win32\$(ConfigurationName)""\r
+ GenerateDebugInformation="true"\r
SubSystem="1"\r
- TargetMachine="17"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="1"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="xerces-c_2D.lib xmltooling1D.lib libfcgi.lib"\r
+ AdditionalDependencies="xerces-c_3D.lib xmltooling1D.lib libfcgi.lib"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)",\fcgi-2.4.0-VC8\libfcgi\$(ConfigurationName)"\r
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)";"\fcgi-2.4.0-VC9\Win32\$(PlatformName)\$(ConfigurationName)""\r
GenerateDebugInformation="true"\r
- ProgramDatabaseFile=".\shibresponder___Win32_Debug/shibresponder.pdb"\r
SubSystem="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="17"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Debug|Win32"\r
+ Name="Release|x64"\r
>\r
<Tool\r
Name="VCCLCompilerTool"\r
/>\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|x64"\r
+ Name="Debug|Win32"\r
>\r
<Tool\r
Name="VCCLCompilerTool"\r
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#define _CRT_NONSTDC_NO_DEPRECATE 1
#define _CRT_SECURE_NO_DEPRECATE 1
+#define _CRT_RAND_S
#include <shibsp/AbstractSPRequest.h>
#include <shibsp/SPConfig.h>
set<string> m_aliases;
};
- struct context_t {
- char* m_user;
- bool m_checked;
- };
-
HINSTANCE g_hinstDLL;
SPConfig* g_Config = NULL;
map<string,site_t> g_Sites;
bool g_bNormalizeRequest = true;
- string g_unsetHeaderValue;
+ string g_unsetHeaderValue,g_spoofKey;
bool g_checkSpoofing = true;
bool g_catchAll = false;
+ bool g_bSafeHeaderNames = false;
vector<string> g_NoCerts;
}
return (DeregisterEventSource(hElog) && res);
}
+void _my_invalid_parameter_handler(
+ const wchar_t * expression,
+ const wchar_t * function,
+ const wchar_t * file,
+ unsigned int line,
+ uintptr_t pReserved
+ )
+{
+ return;
+}
+
extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID)
{
if (fdwReason==DLL_PROCESS_ATTACH)
Locker locker(sp);
const PropertySet* props=sp->getPropertySet("InProcess");
if (props) {
- pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
- if (unsetValue.first)
- g_unsetHeaderValue = unsetValue.second;
pair<bool,bool> flag=props->getBool("checkSpoofing");
g_checkSpoofing = !flag.first || flag.second;
flag=props->getBool("catchAll");
g_catchAll = flag.first && flag.second;
+<<<<<<< .mine
+ pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
+ if (unsetValue.first)
+ g_unsetHeaderValue = unsetValue.second;
+ if (g_checkSpoofing) {
+ unsetValue = props->getString("spoofKey");
+ if (unsetValue.first)
+ g_spoofKey = unsetValue.second;
+ else {
+ unsigned int randkey=0,randkey2=0,randkey3=0,randkey4=0;
+ if (rand_s(&randkey) == 0 && rand_s(&randkey2) == 0 && rand_s(&randkey3) == 0 && rand_s(&randkey4) == 0) {
+ ostringstream keystr;
+ keystr << randkey << randkey2 << randkey3 << randkey4;
+ g_spoofKey = keystr.str();
+ }
+ else {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Filter failed to generate a random anti-spoofing key (if this is Windows 2000 set one manually).");
+ g_Config->term();
+ g_Config=NULL;
+ return FALSE;
+ }
+ }
+ }
+
+=======
+ pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
+ if (unsetValue.first)
+ g_unsetHeaderValue = unsetValue.second;
+ if (g_checkSpoofing) {
+ unsetValue = props->getString("spoofKey");
+ if (unsetValue.first)
+ g_spoofKey = unsetValue.second;
+ else {
+ _invalid_parameter_handler old = _set_invalid_parameter_handler(_my_invalid_parameter_handler);
+ unsigned int randkey=0,randkey2=0,randkey3=0,randkey4=0;
+ if (rand_s(&randkey) == 0 && rand_s(&randkey2) == 0 && rand_s(&randkey3) == 0 && rand_s(&randkey4) == 0) {
+ _set_invalid_parameter_handler(old);
+ ostringstream keystr;
+ keystr << randkey << randkey2 << randkey3 << randkey4;
+ g_spoofKey = keystr.str();
+ }
+ else {
+ _set_invalid_parameter_handler(old);
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Filter failed to generate a random anti-spoofing key (if this is Windows 2000 set one manually).");
+ locker.assign(); // pops lock on SP config
+ g_Config->term();
+ g_Config=NULL;
+ return FALSE;
+ }
+ }
+ }
+
+>>>>>>> .r3097
props = props->getPropertySet("ISAPI");
if (props) {
flag = props->getBool("normalizeRequest");
g_bNormalizeRequest = !flag.first || flag.second;
+ flag = props->getBool("safeHeaderNames");
+ g_bSafeHeaderNames = flag.first && flag.second;
const DOMElement* child = XMLHelper::getFirstChildElement(props->getElement(),Site);
while (child) {
auto_ptr_char id(child->getAttributeNS(NULL,id));
string m_scheme,m_hostname;
mutable string m_remote_addr,m_content_type,m_method;
dynabuf m_allhttp;
+ bool m_firsttime;
public:
ShibTargetIsapiF(PHTTP_FILTER_CONTEXT pfc, PHTTP_FILTER_PREPROC_HEADERS pn, const site_t& site)
- : AbstractSPRequest(SHIBSP_LOGCAT".ISAPI"), m_pfc(pfc), m_pn(pn), m_allhttp(4096) {
+ : AbstractSPRequest(SHIBSP_LOGCAT".ISAPI"), m_pfc(pfc), m_pn(pn), m_allhttp(4096), m_firsttime(true) {
// URL path always come from IIS.
dynabuf var(256);
if (site.m_name!=m_hostname && site.m_aliases.find(m_hostname)==site.m_aliases.end())
m_hostname=site.m_name;
- if (!pfc->pFilterContext) {
- pfc->pFilterContext = pfc->AllocMem(pfc, sizeof(context_t), NULL);
- if (static_cast<context_t*>(pfc->pFilterContext)) {
- static_cast<context_t*>(pfc->pFilterContext)->m_user = NULL;
- static_cast<context_t*>(pfc->pFilterContext)->m_checked = false;
- }
+ if (!g_spoofKey.empty()) {
+ GetHeader(pn, pfc, "ShibSpoofCheck:", var, 32, false);
+ if (!var.empty() && g_spoofKey == (char*)var)
+ m_firsttime = false;
}
+
+ if (!m_firsttime)
+ log(SPDebug, "ISAPI filter running more than once");
}
~ShibTargetIsapiF() { }
int getPort() const {
return m_port;
}
+ const char* getQueryString() const {
+ const char* uri = getRequestURI();
+ uri = (uri ? strchr(uri, '?') : NULL);
+ return uri ? (uri + 1) : NULL;
+ }
const char* getMethod() const {
if (m_method.empty()) {
dynabuf var(5);
- GetServerVariable(m_pfc,"REQUEST_METHOD",var,5,false);
+ GetServerVariable(m_pfc,"HTTP_METHOD",var,5,false);
if (!var.empty())
m_method = var;
}
string getContentType() const {
if (m_content_type.empty()) {
dynabuf var(32);
- GetServerVariable(m_pfc,"CONTENT_TYPE",var,32,false);
+ GetServerVariable(m_pfc,"HTTP_CONTENT_TYPE",var,32,false);
if (!var.empty())
m_content_type = var;
}
return m_content_type;
}
- long getContentLength() const {
- return 0;
- }
string getRemoteAddr() const {
+ m_remote_addr = AbstractSPRequest::getRemoteAddr();
if (m_remote_addr.empty()) {
dynabuf var(16);
GetServerVariable(m_pfc,"REMOTE_ADDR",var,16,false);
}
void log(SPLogLevel level, const string& msg) {
AbstractSPRequest::log(level,msg);
- if (level >= SPError)
+ if (level >= SPCrit)
LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg.c_str());
}
+ string makeSafeHeader(const char* rawname) const {
+ string hdr;
+ for (; *rawname; ++rawname) {
+ if (isalnum(*rawname))
+ hdr += *rawname;
+ }
+ return (hdr + ':');
+ }
void clearHeader(const char* rawname, const char* cginame) {
- if (g_checkSpoofing && m_pfc->pFilterContext && !static_cast<context_t*>(m_pfc->pFilterContext)->m_checked) {
+ if (g_checkSpoofing && m_firsttime) {
if (m_allhttp.empty())
- GetServerVariable(m_pfc,"ALL_HTTP",m_allhttp,4096);
- if (strstr(m_allhttp, cginame))
- throw opensaml::SecurityPolicyException("Attempt to spoof header ($1) was detected.", params(1, rawname));
+ GetServerVariable(m_pfc, "ALL_HTTP", m_allhttp, 4096);
+ string hdr = g_bSafeHeaderNames ? ("HTTP_" + makeSafeHeader(cginame + 5)) : (string(cginame) + ':');
+ if (strstr(m_allhttp, hdr.c_str()))
+ throw opensaml::SecurityPolicyException("Attempt to spoof header ($1) was detected.", params(1, hdr.c_str()));
}
- string hdr(!strcmp(rawname,"REMOTE_USER") ? "remote-user" : rawname);
- hdr += ':';
- m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(g_unsetHeaderValue.c_str()));
+ if (g_bSafeHeaderNames) {
+ string hdr = makeSafeHeader(rawname);
+ m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(g_unsetHeaderValue.c_str()));
+ }
+ else if (!strcmp(rawname,"REMOTE_USER")) {
+ m_pn->SetHeader(m_pfc, "remote-user:", const_cast<char*>(g_unsetHeaderValue.c_str()));
+ m_pn->SetHeader(m_pfc, "remote_user:", const_cast<char*>(g_unsetHeaderValue.c_str()));
+ }
+ else {
+ string hdr = string(rawname) + ':';
+ m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(g_unsetHeaderValue.c_str()));
+ }
}
void setHeader(const char* name, const char* value) {
- string hdr(name);
- hdr += ':';
+ string hdr = g_bSafeHeaderNames ? makeSafeHeader(name) : (string(name) + ':');
m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(value));
}
+ string getSecureHeader(const char* name) const {
+ string hdr = g_bSafeHeaderNames ? makeSafeHeader(name) : (string(name) + ':');
+ dynabuf buf(256);
+ GetHeader(m_pn, m_pfc, const_cast<char*>(hdr.c_str()), buf, 256, false);
+ return string(buf.empty() ? "" : buf);
+ }
string getHeader(const char* name) const {
string hdr(name);
hdr += ':';
dynabuf buf(256);
GetHeader(m_pn, m_pfc, const_cast<char*>(hdr.c_str()), buf, 256, false);
- return string(buf);
+ return string(buf.empty() ? "" : buf);
}
void setRemoteUser(const char* user) {
setHeader("remote-user", user);
- if (m_pfc->pFilterContext) {
- if (!user || !*user)
- static_cast<context_t*>(m_pfc->pFilterContext)->m_user = NULL;
- else if (static_cast<context_t*>(m_pfc->pFilterContext)->m_user = (char*)m_pfc->AllocMem(m_pfc, sizeof(char) * (strlen(user) + 1), NULL))
- strcpy(static_cast<context_t*>(m_pfc->pFilterContext)->m_user, user);
- }
+ if (!user || !*user)
+ m_pfc->pFilterContext = NULL;
+ else if (m_pfc->pFilterContext = m_pfc->AllocMem(m_pfc, sizeof(char) * (strlen(user) + 1), NULL))
+ strcpy(reinterpret_cast<char*>(m_pfc->pFilterContext), user);
}
string getRemoteUser() const {
- return getHeader("remote-user");
+ return getSecureHeader("remote-user");
}
void setResponseHeader(const char* name, const char* value) {
// Set for later.
}
// The filter never processes the POST, so stub these methods.
- const char* getQueryString() const { throw IOException("getQueryString not implemented"); }
- const char* getRequestBody() const { throw IOException("getRequestBody not implemented"); }
+ long getContentLength() const { throw IOException("The request's Content-Length is not available to an ISAPI filter."); }
+ const char* getRequestBody() const { throw IOException("The request body is not available to an ISAPI filter."); }
};
DWORD WriteClientError(PHTTP_FILTER_CONTEXT pfc, const char* msg)
{
// Is this a log notification?
if (notificationType==SF_NOTIFY_LOG) {
- if (pfc->pFilterContext && static_cast<context_t*>(pfc->pFilterContext)->m_user)
- ((PHTTP_FILTER_LOG)pvNotification)->pszClientUserName=static_cast<context_t*>(pfc->pFilterContext)->m_user;
+ if (pfc->pFilterContext)
+ ((PHTTP_FILTER_LOG)pvNotification)->pszClientUserName=reinterpret_cast<char*>(pfc->pFilterContext);
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
// "false" because we don't override the Shib settings
pair<bool,long> res = stf.getServiceProvider().doAuthentication(stf);
- if (pfc->pFilterContext)
- static_cast<context_t*>(pfc->pFilterContext)->m_checked = true;
+ if (!g_spoofKey.empty())
+ pn->SetHeader(pfc, "ShibSpoofCheck:", const_cast<char*>(g_spoofKey.c_str()));
if (res.first) return res.second;
// "false" because we don't override the Shib settings
return m_remote_user;
}
string getRemoteAddr() const {
+ m_remote_addr = AbstractSPRequest::getRemoteAddr();
if (m_remote_addr.empty()) {
dynabuf var(16);
GetServerVariable(m_lpECB, "REMOTE_ADDR", var, 16, false);
}
void log(SPLogLevel level, const string& msg) const {
AbstractSPRequest::log(level,msg);
- if (level >= SPError)
+ if (level >= SPCrit)
LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg.c_str());
}
string getHeader(const char* name) const {
throw opensaml::SecurityPolicyException("Size of request body exceeded 1M size limit.");
else if (m_lpECB->cbTotalBytes > m_lpECB->cbAvailable) {
m_gotBody=true;
- char buf[8192];
DWORD datalen=m_lpECB->cbTotalBytes;
+ if (m_lpECB->cbAvailable > 0) {
+ m_body.assign(reinterpret_cast<char*>(m_lpECB->lpbData),m_lpECB->cbAvailable);
+ datalen-=m_lpECB->cbAvailable;
+ }
+ char buf[8192];
while (datalen) {
DWORD buflen=8192;
BOOL ret = m_lpECB->ReadClient(m_lpECB->ConnID, buf, &buflen);
- if (!ret || !buflen)
+ if (!ret)
throw IOException("Error reading request body from browser.");
+ else if (!buflen)
+ throw IOException("Socket closed while reading request body from browser.");
m_body.append(buf, buflen);
datalen-=buflen;
}
if (m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_GET_CERT_INFO_EX, (LPVOID)&ccex, (LPDWORD)dwSize, NULL)) {
if (ccex.CertContext.cbCertEncoded) {
- unsigned int outlen;
+ xsecsize_t outlen;
XMLByte* serialized = Base64::encode(reinterpret_cast<XMLByte*>(CertificateBuf), ccex.CertContext.cbCertEncoded, &outlen);
m_certs.push_back(reinterpret_cast<char*>(serialized));
+#ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE
XMLString::release(&serialized);
+#else
+ XMLString::release((char**)&serialized);
+#endif
}
}
}
--- /dev/null
+/*\r
+ * Copyright 2001-2009 Internet2\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * isapi_shib.cpp\r
+ *\r
+ * Shibboleth ISAPI filter\r
+ */\r
+\r
+#define SHIBSP_LITE\r
+#include "config_win32.h"\r
+\r
+#define _CRT_NONSTDC_NO_DEPRECATE 1\r
+#define _CRT_SECURE_NO_DEPRECATE 1\r
+#define _CRT_RAND_S\r
+\r
+#include <shibsp/AbstractSPRequest.h>\r
+#include <shibsp/SPConfig.h>\r
+#include <shibsp/ServiceProvider.h>\r
+#include <xmltooling/unicode.h>\r
+#include <xmltooling/XMLToolingConfig.h>\r
+#include <xmltooling/util/NDC.h>\r
+#include <xmltooling/util/XMLConstants.h>\r
+#include <xmltooling/util/XMLHelper.h>\r
+#include <xercesc/util/Base64.hpp>\r
+#include <xercesc/util/XMLUniDefs.hpp>\r
+\r
+#include <set>\r
+#include <sstream>\r
+#include <fstream>\r
+#include <stdexcept>\r
+#include <process.h>\r
+\r
+#include <windows.h>\r
+#include <httpfilt.h>\r
+#include <httpext.h>\r
+\r
+using namespace shibsp;\r
+using namespace xmltooling;\r
+using namespace xercesc;\r
+using namespace std;\r
+\r
+// globals\r
+namespace {\r
+ static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);\r
+ static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);\r
+ static const XMLCh name[] = UNICODE_LITERAL_4(n,a,m,e);\r
+ static const XMLCh port[] = UNICODE_LITERAL_4(p,o,r,t);\r
+ static const XMLCh sslport[] = UNICODE_LITERAL_7(s,s,l,p,o,r,t);\r
+ static const XMLCh scheme[] = UNICODE_LITERAL_6(s,c,h,e,m,e);\r
+ static const XMLCh id[] = UNICODE_LITERAL_2(i,d);\r
+ static const XMLCh Alias[] = UNICODE_LITERAL_5(A,l,i,a,s);\r
+ static const XMLCh Site[] = UNICODE_LITERAL_4(S,i,t,e);\r
+\r
+ struct site_t {\r
+ site_t(const DOMElement* e)\r
+ {\r
+ auto_ptr_char n(e->getAttributeNS(NULL,name));\r
+ auto_ptr_char s(e->getAttributeNS(NULL,scheme));\r
+ auto_ptr_char p(e->getAttributeNS(NULL,port));\r
+ auto_ptr_char p2(e->getAttributeNS(NULL,sslport));\r
+ if (n.get()) m_name=n.get();\r
+ if (s.get()) m_scheme=s.get();\r
+ if (p.get()) m_port=p.get();\r
+ if (p2.get()) m_sslport=p2.get();\r
+ e = XMLHelper::getFirstChildElement(e, Alias);\r
+ while (e) {\r
+ if (e->hasChildNodes()) {\r
+ auto_ptr_char alias(e->getFirstChild()->getNodeValue());\r
+ m_aliases.insert(alias.get());\r
+ }\r
+ e = XMLHelper::getNextSiblingElement(e, Alias);\r
+ }\r
+ }\r
+ string m_scheme,m_port,m_sslport,m_name;\r
+ set<string> m_aliases;\r
+ };\r
+\r
+ HINSTANCE g_hinstDLL;\r
+ SPConfig* g_Config = NULL;\r
+ map<string,site_t> g_Sites;\r
+ bool g_bNormalizeRequest = true;\r
+ string g_unsetHeaderValue,g_spoofKey;\r
+ bool g_checkSpoofing = true;\r
+ bool g_catchAll = false;\r
+ bool g_bSafeHeaderNames = false;\r
+ vector<string> g_NoCerts;\r
+}\r
+\r
+BOOL LogEvent(\r
+ LPCSTR lpUNCServerName,\r
+ WORD wType,\r
+ DWORD dwEventID,\r
+ PSID lpUserSid,\r
+ LPCSTR message)\r
+{\r
+ LPCSTR messages[] = {message, NULL};\r
+\r
+ HANDLE hElog = RegisterEventSource(lpUNCServerName, "Shibboleth ISAPI Filter");\r
+ BOOL res = ReportEvent(hElog, wType, 0, dwEventID, lpUserSid, 1, 0, messages, NULL);\r
+ return (DeregisterEventSource(hElog) && res);\r
+}\r
+\r
+extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID)\r
+{\r
+ if (fdwReason==DLL_PROCESS_ATTACH)\r
+ g_hinstDLL=hinstDLL;\r
+ return TRUE;\r
+}\r
+\r
+extern "C" BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO* pVer)\r
+{\r
+ if (!pVer)\r
+ return FALSE;\r
+\r
+ if (!g_Config) {\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,\r
+ "Extension mode startup not possible, is the DLL loaded as a filter?");\r
+ return FALSE;\r
+ }\r
+\r
+ pVer->dwExtensionVersion=HSE_VERSION;\r
+ strncpy(pVer->lpszExtensionDesc,"Shibboleth ISAPI Extension",HSE_MAX_EXT_DLL_NAME_LEN-1);\r
+ return TRUE;\r
+}\r
+\r
+extern "C" BOOL WINAPI TerminateExtension(DWORD)\r
+{\r
+ return TRUE; // cleanup should happen when filter unloads\r
+}\r
+\r
+extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)\r
+{\r
+ if (!pVer)\r
+ return FALSE;\r
+ else if (g_Config) {\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,\r
+ "Reentrant filter initialization, ignoring...");\r
+ return TRUE;\r
+ }\r
+\r
+ g_Config=&SPConfig::getConfig();\r
+ g_Config->setFeatures(\r
+ SPConfig::Listener |\r
+ SPConfig::Caching |\r
+ SPConfig::RequestMapping |\r
+ SPConfig::InProcess |\r
+ SPConfig::Logging |\r
+ SPConfig::Handlers\r
+ );\r
+ if (!g_Config->init()) {\r
+ g_Config=NULL;\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,\r
+ "Filter startup failed during library initialization, check native log for help.");\r
+ return FALSE;\r
+ }\r
+\r
+ try {\r
+ if (!g_Config->instantiate(NULL, true))\r
+ throw runtime_error("unknown error");\r
+ }\r
+ catch (exception& ex) {\r
+ g_Config->term();\r
+ g_Config=NULL;\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, ex.what());\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,\r
+ "Filter startup failed to load configuration, check native log for details.");\r
+ return FALSE;\r
+ }\r
+\r
+ // Access implementation-specifics and site mappings.\r
+ ServiceProvider* sp=g_Config->getServiceProvider();\r
+ Locker locker(sp);\r
+ const PropertySet* props=sp->getPropertySet("InProcess");\r
+ if (props) {\r
+ pair<bool,bool> flag=props->getBool("checkSpoofing");\r
+ g_checkSpoofing = !flag.first || flag.second;\r
+ flag=props->getBool("catchAll");\r
+ g_catchAll = flag.first && flag.second;\r
+\r
+ pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");\r
+ if (unsetValue.first)\r
+ g_unsetHeaderValue = unsetValue.second;\r
+ if (g_checkSpoofing) {\r
+ unsetValue = props->getString("spoofKey");\r
+ if (unsetValue.first)\r
+ g_spoofKey = unsetValue.second;\r
+ else {\r
+ unsigned int randkey=0,randkey2=0,randkey3=0,randkey4=0;\r
+ if (rand_s(&randkey) == 0 && rand_s(&randkey2) == 0 && rand_s(&randkey3) == 0 && rand_s(&randkey4) == 0) {\r
+ ostringstream keystr;\r
+ keystr << randkey << randkey2 << randkey3 << randkey4;\r
+ g_spoofKey = keystr.str();\r
+ }\r
+ else {\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,\r
+ "Filter failed to generate a random anti-spoofing key (if this is Windows 2000 set one manually).");\r
+ g_Config->term();\r
+ g_Config=NULL;\r
+ return FALSE;\r
+ }\r
+ }\r
+ }\r
+\r
+ props = props->getPropertySet("ISAPI");\r
+ if (props) {\r
+ flag = props->getBool("normalizeRequest");\r
+ g_bNormalizeRequest = !flag.first || flag.second;\r
+ flag = props->getBool("safeHeaderNames");\r
+ g_bSafeHeaderNames = flag.first && flag.second;\r
+ const DOMElement* child = XMLHelper::getFirstChildElement(props->getElement(),Site);\r
+ while (child) {\r
+ auto_ptr_char id(child->getAttributeNS(NULL,id));\r
+ if (id.get())\r
+ g_Sites.insert(pair<string,site_t>(id.get(),site_t(child)));\r
+ child=XMLHelper::getNextSiblingElement(child,Site);\r
+ }\r
+ }\r
+ }\r
+\r
+ pVer->dwFilterVersion=HTTP_FILTER_REVISION;\r
+ strncpy(pVer->lpszFilterDesc,"Shibboleth ISAPI Filter",SF_MAX_FILTER_DESC_LEN);\r
+ pVer->dwFlags=(SF_NOTIFY_ORDER_HIGH |\r
+ SF_NOTIFY_SECURE_PORT |\r
+ SF_NOTIFY_NONSECURE_PORT |\r
+ SF_NOTIFY_PREPROC_HEADERS |\r
+ SF_NOTIFY_LOG);\r
+ LogEvent(NULL, EVENTLOG_INFORMATION_TYPE, 7701, NULL, "Filter initialized...");\r
+ return TRUE;\r
+}\r
+\r
+extern "C" BOOL WINAPI TerminateFilter(DWORD)\r
+{\r
+ if (g_Config)\r
+ g_Config->term();\r
+ g_Config = NULL;\r
+ LogEvent(NULL, EVENTLOG_INFORMATION_TYPE, 7701, NULL, "Filter shut down...");\r
+ return TRUE;\r
+}\r
+\r
+/* Next up, some suck-free versions of various APIs.\r
+\r
+ You DON'T require people to guess the buffer size and THEN tell them the right size.\r
+ Returning an LPCSTR is apparently way beyond their ken. Not to mention the fact that\r
+ constant strings aren't typed as such, making it just that much harder. These versions\r
+ are now updated to use a special growable buffer object, modeled after the standard\r
+ string class. The standard string won't work because they left out the option to\r
+ pre-allocate a non-constant buffer.\r
+*/\r
+\r
+class dynabuf\r
+{\r
+public:\r
+ dynabuf() { bufptr=NULL; buflen=0; }\r
+ dynabuf(size_t s) { bufptr=new char[buflen=s]; *bufptr=0; }\r
+ ~dynabuf() { delete[] bufptr; }\r
+ size_t length() const { return bufptr ? strlen(bufptr) : 0; }\r
+ size_t size() const { return buflen; }\r
+ bool empty() const { return length()==0; }\r
+ void reserve(size_t s, bool keep=false);\r
+ void erase() { if (bufptr) memset(bufptr,0,buflen); }\r
+ operator char*() { return bufptr; }\r
+ bool operator ==(const char* s) const;\r
+ bool operator !=(const char* s) const { return !(*this==s); }\r
+private:\r
+ char* bufptr;\r
+ size_t buflen;\r
+};\r
+\r
+void dynabuf::reserve(size_t s, bool keep)\r
+{\r
+ if (s<=buflen)\r
+ return;\r
+ char* p=new char[s];\r
+ if (keep)\r
+ while (buflen--)\r
+ p[buflen]=bufptr[buflen];\r
+ buflen=s;\r
+ delete[] bufptr;\r
+ bufptr=p;\r
+}\r
+\r
+bool dynabuf::operator==(const char* s) const\r
+{\r
+ if (buflen==NULL || s==NULL)\r
+ return (buflen==NULL && s==NULL);\r
+ else\r
+ return strcmp(bufptr,s)==0;\r
+}\r
+\r
+void GetServerVariable(PHTTP_FILTER_CONTEXT pfc, LPSTR lpszVariable, dynabuf& s, DWORD size=80, bool bRequired=true)\r
+{\r
+ s.reserve(size);\r
+ s.erase();\r
+ size=s.size();\r
+\r
+ while (!pfc->GetServerVariable(pfc,lpszVariable,s,&size)) {\r
+ // Grumble. Check the error.\r
+ DWORD e=GetLastError();\r
+ if (e==ERROR_INSUFFICIENT_BUFFER)\r
+ s.reserve(size);\r
+ else\r
+ break;\r
+ }\r
+ if (bRequired && s.empty())\r
+ throw ERROR_NO_DATA;\r
+}\r
+\r
+void GetServerVariable(LPEXTENSION_CONTROL_BLOCK lpECB, LPSTR lpszVariable, dynabuf& s, DWORD size=80, bool bRequired=true)\r
+{\r
+ s.reserve(size);\r
+ s.erase();\r
+ size=s.size();\r
+\r
+ while (!lpECB->GetServerVariable(lpECB->ConnID,lpszVariable,s,&size)) {\r
+ // Grumble. Check the error.\r
+ DWORD e=GetLastError();\r
+ if (e==ERROR_INSUFFICIENT_BUFFER)\r
+ s.reserve(size);\r
+ else\r
+ break;\r
+ }\r
+ if (bRequired && s.empty())\r
+ throw ERROR_NO_DATA;\r
+}\r
+\r
+void GetHeader(PHTTP_FILTER_PREPROC_HEADERS pn, PHTTP_FILTER_CONTEXT pfc,\r
+ LPSTR lpszName, dynabuf& s, DWORD size=80, bool bRequired=true)\r
+{\r
+ s.reserve(size);\r
+ s.erase();\r
+ size=s.size();\r
+\r
+ while (!pn->GetHeader(pfc,lpszName,s,&size)) {\r
+ // Grumble. Check the error.\r
+ DWORD e=GetLastError();\r
+ if (e==ERROR_INSUFFICIENT_BUFFER)\r
+ s.reserve(size);\r
+ else\r
+ break;\r
+ }\r
+ if (bRequired && s.empty())\r
+ throw ERROR_NO_DATA;\r
+}\r
+\r
+/****************************************************************************/\r
+// ISAPI Filter\r
+\r
+class ShibTargetIsapiF : public AbstractSPRequest\r
+{\r
+ PHTTP_FILTER_CONTEXT m_pfc;\r
+ PHTTP_FILTER_PREPROC_HEADERS m_pn;\r
+ multimap<string,string> m_headers;\r
+ int m_port;\r
+ string m_scheme,m_hostname;\r
+ mutable string m_remote_addr,m_content_type,m_method;\r
+ dynabuf m_allhttp;\r
+ bool m_firsttime;\r
+\r
+public:\r
+ ShibTargetIsapiF(PHTTP_FILTER_CONTEXT pfc, PHTTP_FILTER_PREPROC_HEADERS pn, const site_t& site)\r
+ : AbstractSPRequest(SHIBSP_LOGCAT".ISAPI"), m_pfc(pfc), m_pn(pn), m_allhttp(4096), m_firsttime(true) {\r
+\r
+ // URL path always come from IIS.\r
+ dynabuf var(256);\r
+ GetHeader(pn,pfc,"url",var,256,false);\r
+ setRequestURI(var);\r
+\r
+ // Port may come from IIS or from site def.\r
+ if (!g_bNormalizeRequest || (pfc->fIsSecurePort && site.m_sslport.empty()) || (!pfc->fIsSecurePort && site.m_port.empty())) {\r
+ GetServerVariable(pfc,"SERVER_PORT",var,10);\r
+ m_port = atoi(var);\r
+ }\r
+ else if (pfc->fIsSecurePort) {\r
+ m_port = atoi(site.m_sslport.c_str());\r
+ }\r
+ else {\r
+ m_port = atoi(site.m_port.c_str());\r
+ }\r
+\r
+ // Scheme may come from site def or be derived from IIS.\r
+ m_scheme=site.m_scheme;\r
+ if (m_scheme.empty() || !g_bNormalizeRequest)\r
+ m_scheme=pfc->fIsSecurePort ? "https" : "http";\r
+\r
+ GetServerVariable(pfc,"SERVER_NAME",var,32);\r
+\r
+ // Make sure SERVER_NAME is "authorized" for use on this site. If not, set to canonical name.\r
+ m_hostname = var;\r
+ if (site.m_name!=m_hostname && site.m_aliases.find(m_hostname)==site.m_aliases.end())\r
+ m_hostname=site.m_name;\r
+\r
+ if (!g_spoofKey.empty()) {\r
+ GetHeader(pn, pfc, "ShibSpoofCheck:", var, 32, false);\r
+ if (!var.empty() && g_spoofKey == (char*)var)\r
+ m_firsttime = false;\r
+ }\r
+\r
+ if (!m_firsttime)\r
+ log(SPDebug, "ISAPI filter running more than once");\r
+ }\r
+ ~ShibTargetIsapiF() { }\r
+\r
+ const char* getScheme() const {\r
+ return m_scheme.c_str();\r
+ }\r
+ const char* getHostname() const {\r
+ return m_hostname.c_str();\r
+ }\r
+ int getPort() const {\r
+ return m_port;\r
+ }\r
+ const char* getQueryString() const {\r
+ const char* uri = getRequestURI();\r
+ uri = (uri ? strchr(uri, '?') : NULL);\r
+ return uri ? (uri + 1) : NULL;\r
+ }\r
+ const char* getMethod() const {\r
+ if (m_method.empty()) {\r
+ dynabuf var(5);\r
+ GetServerVariable(m_pfc,"HTTP_METHOD",var,5,false);\r
+ if (!var.empty())\r
+ m_method = var;\r
+ }\r
+ return m_method.c_str();\r
+ }\r
+ string getContentType() const {\r
+ if (m_content_type.empty()) {\r
+ dynabuf var(32);\r
+ GetServerVariable(m_pfc,"HTTP_CONTENT_TYPE",var,32,false);\r
+ if (!var.empty())\r
+ m_content_type = var;\r
+ }\r
+ return m_content_type;\r
+ }\r
+ string getRemoteAddr() const {\r
+ m_remote_addr = AbstractSPRequest::getRemoteAddr();\r
+ if (m_remote_addr.empty()) {\r
+ dynabuf var(16);\r
+ GetServerVariable(m_pfc,"REMOTE_ADDR",var,16,false);\r
+ if (!var.empty())\r
+ m_remote_addr = var;\r
+ }\r
+ return m_remote_addr;\r
+ }\r
+ void log(SPLogLevel level, const string& msg) {\r
+ AbstractSPRequest::log(level,msg);\r
+ if (level >= SPCrit)\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg.c_str());\r
+ }\r
+ string makeSafeHeader(const char* rawname) const {\r
+ string hdr;\r
+ for (; *rawname; ++rawname) {\r
+ if (isalnum(*rawname))\r
+ hdr += *rawname;\r
+ }\r
+ return (hdr + ':');\r
+ }\r
+ void clearHeader(const char* rawname, const char* cginame) {\r
+ if (g_checkSpoofing && m_firsttime) {\r
+ if (m_allhttp.empty())\r
+ GetServerVariable(m_pfc, "ALL_HTTP", m_allhttp, 4096);\r
+ string hdr = g_bSafeHeaderNames ? ("HTTP_" + makeSafeHeader(cginame + 5)) : (string(cginame) + ':');\r
+ if (strstr(m_allhttp, hdr.c_str()))\r
+ throw opensaml::SecurityPolicyException("Attempt to spoof header ($1) was detected.", params(1, hdr.c_str()));\r
+ }\r
+ if (g_bSafeHeaderNames) {\r
+ string hdr = makeSafeHeader(rawname);\r
+ m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(g_unsetHeaderValue.c_str()));\r
+ }\r
+ else if (!strcmp(rawname,"REMOTE_USER")) {\r
+ m_pn->SetHeader(m_pfc, "remote-user:", const_cast<char*>(g_unsetHeaderValue.c_str()));\r
+ m_pn->SetHeader(m_pfc, "remote_user:", const_cast<char*>(g_unsetHeaderValue.c_str()));\r
+ }\r
+ else {\r
+ string hdr = string(rawname) + ':';\r
+ m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(g_unsetHeaderValue.c_str()));\r
+ }\r
+ }\r
+ void setHeader(const char* name, const char* value) {\r
+ string hdr = g_bSafeHeaderNames ? makeSafeHeader(name) : (string(name) + ':');\r
+ m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(value));\r
+ }\r
+ string getSecureHeader(const char* name) const {\r
+ string hdr = g_bSafeHeaderNames ? makeSafeHeader(name) : (string(name) + ':');\r
+ dynabuf buf(256);\r
+ GetHeader(m_pn, m_pfc, const_cast<char*>(hdr.c_str()), buf, 256, false);\r
+ return string(buf.empty() ? "" : buf);\r
+ }\r
+ string getHeader(const char* name) const {\r
+ string hdr(name);\r
+ hdr += ':';\r
+ dynabuf buf(256);\r
+ GetHeader(m_pn, m_pfc, const_cast<char*>(hdr.c_str()), buf, 256, false);\r
+ return string(buf.empty() ? "" : buf);\r
+ }\r
+ void setRemoteUser(const char* user) {\r
+ setHeader("remote-user", user);\r
+ if (!user || !*user)\r
+ m_pfc->pFilterContext = NULL;\r
+ else if (m_pfc->pFilterContext = m_pfc->AllocMem(m_pfc, sizeof(char) * (strlen(user) + 1), NULL))\r
+ strcpy(reinterpret_cast<char*>(m_pfc->pFilterContext), user);\r
+ }\r
+ string getRemoteUser() const {\r
+ return getSecureHeader("remote-user");\r
+ }\r
+ void setResponseHeader(const char* name, const char* value) {\r
+ // Set for later.\r
+ if (value)\r
+ m_headers.insert(make_pair(name,value));\r
+ else\r
+ m_headers.erase(name);\r
+ }\r
+ long sendResponse(istream& in, long status) {\r
+ string hdr = string("Connection: close\r\n");\r
+ for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)\r
+ hdr += i->first + ": " + i->second + "\r\n";\r
+ hdr += "\r\n";\r
+ const char* codestr="200 OK";\r
+ switch (status) {\r
+ case XMLTOOLING_HTTP_STATUS_UNAUTHORIZED: codestr="401 Authorization Required"; break;\r
+ case XMLTOOLING_HTTP_STATUS_FORBIDDEN: codestr="403 Forbidden"; break;\r
+ case XMLTOOLING_HTTP_STATUS_NOTFOUND: codestr="404 Not Found"; break;\r
+ case XMLTOOLING_HTTP_STATUS_ERROR: codestr="500 Server Error"; break;\r
+ }\r
+ m_pfc->ServerSupportFunction(m_pfc, SF_REQ_SEND_RESPONSE_HEADER, (void*)codestr, (DWORD)hdr.c_str(), 0);\r
+ char buf[1024];\r
+ while (in) {\r
+ in.read(buf,1024);\r
+ DWORD resplen = in.gcount();\r
+ m_pfc->WriteClient(m_pfc, buf, &resplen, 0);\r
+ }\r
+ return SF_STATUS_REQ_FINISHED;\r
+ }\r
+ long sendRedirect(const char* url) {\r
+ // XXX: Don't support the httpRedirect option, yet.\r
+ string hdr=string("Location: ") + url + "\r\n"\r
+ "Content-Type: text/html\r\n"\r
+ "Content-Length: 40\r\n"\r
+ "Expires: 01-Jan-1997 12:00:00 GMT\r\n"\r
+ "Cache-Control: private,no-store,no-cache\r\n";\r
+ for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)\r
+ hdr += i->first + ": " + i->second + "\r\n";\r
+ hdr += "\r\n";\r
+ m_pfc->ServerSupportFunction(m_pfc, SF_REQ_SEND_RESPONSE_HEADER, "302 Please Wait", (DWORD)hdr.c_str(), 0);\r
+ static const char* redmsg="<HTML><BODY>Redirecting...</BODY></HTML>";\r
+ DWORD resplen=40;\r
+ m_pfc->WriteClient(m_pfc, (LPVOID)redmsg, &resplen, 0);\r
+ return SF_STATUS_REQ_FINISHED;\r
+ }\r
+ long returnDecline() {\r
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;\r
+ }\r
+ long returnOK() {\r
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;\r
+ }\r
+\r
+ const vector<string>& getClientCertificates() const {\r
+ return g_NoCerts;\r
+ }\r
+\r
+ // The filter never processes the POST, so stub these methods.\r
+ long getContentLength() const { throw IOException("The request's Content-Length is not available to an ISAPI filter."); }\r
+ const char* getRequestBody() const { throw IOException("The request body is not available to an ISAPI filter."); }\r
+};\r
+\r
+DWORD WriteClientError(PHTTP_FILTER_CONTEXT pfc, const char* msg)\r
+{\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg);\r
+ static const char* ctype="Connection: close\r\nContent-Type: text/html\r\n\r\n";\r
+ pfc->ServerSupportFunction(pfc,SF_REQ_SEND_RESPONSE_HEADER,"200 OK",(DWORD)ctype,0);\r
+ static const char* xmsg="<HTML><HEAD><TITLE>Shibboleth Filter Error</TITLE></HEAD><BODY>"\r
+ "<H1>Shibboleth Filter Error</H1>";\r
+ DWORD resplen=strlen(xmsg);\r
+ pfc->WriteClient(pfc,(LPVOID)xmsg,&resplen,0);\r
+ resplen=strlen(msg);\r
+ pfc->WriteClient(pfc,(LPVOID)msg,&resplen,0);\r
+ static const char* xmsg2="</BODY></HTML>";\r
+ resplen=strlen(xmsg2);\r
+ pfc->WriteClient(pfc,(LPVOID)xmsg2,&resplen,0);\r
+ return SF_STATUS_REQ_FINISHED;\r
+}\r
+\r
+extern "C" DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificationType, LPVOID pvNotification)\r
+{\r
+ // Is this a log notification?\r
+ if (notificationType==SF_NOTIFY_LOG) {\r
+ if (pfc->pFilterContext)\r
+ ((PHTTP_FILTER_LOG)pvNotification)->pszClientUserName=reinterpret_cast<char*>(pfc->pFilterContext);\r
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;\r
+ }\r
+\r
+ PHTTP_FILTER_PREPROC_HEADERS pn=(PHTTP_FILTER_PREPROC_HEADERS)pvNotification;\r
+ try\r
+ {\r
+ // Determine web site number. This can't really fail, I don't think.\r
+ dynabuf buf(128);\r
+ GetServerVariable(pfc,"INSTANCE_ID",buf,10);\r
+\r
+ // Match site instance to host name, skip if no match.\r
+ map<string,site_t>::const_iterator map_i=g_Sites.find(static_cast<char*>(buf));\r
+ if (map_i==g_Sites.end())\r
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;\r
+\r
+ ostringstream threadid;\r
+ threadid << "[" << getpid() << "] isapi_shib" << '\0';\r
+ xmltooling::NDC ndc(threadid.str().c_str());\r
+\r
+ ShibTargetIsapiF stf(pfc, pn, map_i->second);\r
+\r
+ // "false" because we don't override the Shib settings\r
+ pair<bool,long> res = stf.getServiceProvider().doAuthentication(stf);\r
+ if (!g_spoofKey.empty())\r
+ pn->SetHeader(pfc, "ShibSpoofCheck:", const_cast<char*>(g_spoofKey.c_str()));\r
+ if (res.first) return res.second;\r
+\r
+ // "false" because we don't override the Shib settings\r
+ res = stf.getServiceProvider().doExport(stf);\r
+ if (res.first) return res.second;\r
+\r
+ res = stf.getServiceProvider().doAuthorization(stf);\r
+ if (res.first) return res.second;\r
+\r
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;\r
+ }\r
+ catch(bad_alloc) {\r
+ return WriteClientError(pfc,"Out of Memory");\r
+ }\r
+ catch(long e) {\r
+ if (e==ERROR_NO_DATA)\r
+ return WriteClientError(pfc,"A required variable or header was empty.");\r
+ else\r
+ return WriteClientError(pfc,"Shibboleth Filter detected unexpected IIS error.");\r
+ }\r
+ catch (exception& e) {\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, e.what());\r
+ return WriteClientError(pfc,"Shibboleth Filter caught an exception, check Event Log for details.");\r
+ }\r
+ catch(...) {\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, "Shibboleth Filter threw an unknown exception.");\r
+ if (g_catchAll)\r
+ return WriteClientError(pfc,"Shibboleth Filter threw an unknown exception.");\r
+ throw;\r
+ }\r
+\r
+ return WriteClientError(pfc,"Shibboleth Filter reached unreachable code, save my walrus!");\r
+}\r
+\r
+\r
+/****************************************************************************/\r
+// ISAPI Extension\r
+\r
+DWORD WriteClientError(LPEXTENSION_CONTROL_BLOCK lpECB, const char* msg)\r
+{\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg);\r
+ static const char* ctype="Connection: close\r\nContent-Type: text/html\r\n\r\n";\r
+ lpECB->ServerSupportFunction(lpECB->ConnID,HSE_REQ_SEND_RESPONSE_HEADER,"200 OK",0,(LPDWORD)ctype);\r
+ static const char* xmsg="<HTML><HEAD><TITLE>Shibboleth Error</TITLE></HEAD><BODY><H1>Shibboleth Error</H1>";\r
+ DWORD resplen=strlen(xmsg);\r
+ lpECB->WriteClient(lpECB->ConnID,(LPVOID)xmsg,&resplen,HSE_IO_SYNC);\r
+ resplen=strlen(msg);\r
+ lpECB->WriteClient(lpECB->ConnID,(LPVOID)msg,&resplen,HSE_IO_SYNC);\r
+ static const char* xmsg2="</BODY></HTML>";\r
+ resplen=strlen(xmsg2);\r
+ lpECB->WriteClient(lpECB->ConnID,(LPVOID)xmsg2,&resplen,HSE_IO_SYNC);\r
+ return HSE_STATUS_SUCCESS;\r
+}\r
+\r
+\r
+class ShibTargetIsapiE : public AbstractSPRequest\r
+{\r
+ LPEXTENSION_CONTROL_BLOCK m_lpECB;\r
+ multimap<string,string> m_headers;\r
+ mutable vector<string> m_certs;\r
+ mutable string m_body;\r
+ mutable bool m_gotBody;\r
+ int m_port;\r
+ string m_scheme,m_hostname,m_uri;\r
+ mutable string m_remote_addr,m_remote_user;\r
+\r
+public:\r
+ ShibTargetIsapiE(LPEXTENSION_CONTROL_BLOCK lpECB, const site_t& site)\r
+ : AbstractSPRequest(SHIBSP_LOGCAT".ISAPI"), m_lpECB(lpECB), m_gotBody(false) {\r
+ dynabuf ssl(5);\r
+ GetServerVariable(lpECB,"HTTPS",ssl,5);\r
+ bool SSL=(ssl=="on" || ssl=="ON");\r
+\r
+ // Scheme may come from site def or be derived from IIS.\r
+ m_scheme=site.m_scheme;\r
+ if (m_scheme.empty() || !g_bNormalizeRequest)\r
+ m_scheme = SSL ? "https" : "http";\r
+\r
+ // URL path always come from IIS.\r
+ dynabuf url(256);\r
+ GetServerVariable(lpECB,"URL",url,255);\r
+\r
+ // Port may come from IIS or from site def.\r
+ dynabuf port(11);\r
+ if (!g_bNormalizeRequest || (SSL && site.m_sslport.empty()) || (!SSL && site.m_port.empty()))\r
+ GetServerVariable(lpECB,"SERVER_PORT",port,10);\r
+ else if (SSL) {\r
+ strncpy(port,site.m_sslport.c_str(),10);\r
+ static_cast<char*>(port)[10]=0;\r
+ }\r
+ else {\r
+ strncpy(port,site.m_port.c_str(),10);\r
+ static_cast<char*>(port)[10]=0;\r
+ }\r
+ m_port = atoi(port);\r
+\r
+ dynabuf var(32);\r
+ GetServerVariable(lpECB, "SERVER_NAME", var, 32);\r
+\r
+ // Make sure SERVER_NAME is "authorized" for use on this site. If not, set to canonical name.\r
+ m_hostname=var;\r
+ if (site.m_name!=m_hostname && site.m_aliases.find(m_hostname)==site.m_aliases.end())\r
+ m_hostname=site.m_name;\r
+\r
+ /*\r
+ * IIS screws us over on PATH_INFO (the hits keep on coming). We need to figure out if\r
+ * the server is set up for proper PATH_INFO handling, or "IIS sucks rabid weasels mode",\r
+ * which is the default. No perfect way to tell, but we can take a good guess by checking\r
+ * whether the URL is a substring of the PATH_INFO:\r
+ *\r
+ * e.g. for /Shibboleth.sso/SAML/POST\r
+ *\r
+ * Bad mode (default):\r
+ * URL: /Shibboleth.sso\r
+ * PathInfo: /Shibboleth.sso/SAML/POST\r
+ *\r
+ * Good mode:\r
+ * URL: /Shibboleth.sso\r
+ * PathInfo: /SAML/POST\r
+ */\r
+\r
+ string uri;\r
+\r
+ // Clearly we're only in bad mode if path info exists at all.\r
+ if (lpECB->lpszPathInfo && *(lpECB->lpszPathInfo)) {\r
+ if (strstr(lpECB->lpszPathInfo,url))\r
+ // Pretty good chance we're in bad mode, unless the PathInfo repeats the path itself.\r
+ uri = lpECB->lpszPathInfo;\r
+ else {\r
+ uri = url;\r
+ uri += lpECB->lpszPathInfo;\r
+ }\r
+ }\r
+ else {\r
+ uri = url;\r
+ }\r
+\r
+ // For consistency with Apache, let's add the query string.\r
+ if (lpECB->lpszQueryString && *(lpECB->lpszQueryString)) {\r
+ uri += '?';\r
+ uri += lpECB->lpszQueryString;\r
+ }\r
+\r
+ setRequestURI(uri.c_str());\r
+ }\r
+ ~ShibTargetIsapiE() { }\r
+\r
+ const char* getScheme() const {\r
+ return m_scheme.c_str();\r
+ }\r
+ const char* getHostname() const {\r
+ return m_hostname.c_str();\r
+ }\r
+ int getPort() const {\r
+ return m_port;\r
+ }\r
+ const char* getMethod() const {\r
+ return m_lpECB->lpszMethod;\r
+ }\r
+ string getContentType() const {\r
+ return m_lpECB->lpszContentType ? m_lpECB->lpszContentType : "";\r
+ }\r
+ long getContentLength() const {\r
+ return m_lpECB->cbTotalBytes;\r
+ }\r
+ string getRemoteUser() const {\r
+ if (m_remote_user.empty()) {\r
+ dynabuf var(16);\r
+ GetServerVariable(m_lpECB, "REMOTE_USER", var, 32, false);\r
+ if (!var.empty())\r
+ m_remote_user = var;\r
+ }\r
+ return m_remote_user;\r
+ }\r
+ string getRemoteAddr() const {\r
+ m_remote_addr = AbstractSPRequest::getRemoteAddr();\r
+ if (m_remote_addr.empty()) {\r
+ dynabuf var(16);\r
+ GetServerVariable(m_lpECB, "REMOTE_ADDR", var, 16, false);\r
+ if (!var.empty())\r
+ m_remote_addr = var;\r
+ }\r
+ return m_remote_addr;\r
+ }\r
+ void log(SPLogLevel level, const string& msg) const {\r
+ AbstractSPRequest::log(level,msg);\r
+ if (level >= SPCrit)\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg.c_str());\r
+ }\r
+ string getHeader(const char* name) const {\r
+ string hdr("HTTP_");\r
+ for (; *name; ++name) {\r
+ if (*name=='-')\r
+ hdr += '_';\r
+ else\r
+ hdr += toupper(*name);\r
+ }\r
+ dynabuf buf(128);\r
+ GetServerVariable(m_lpECB, const_cast<char*>(hdr.c_str()), buf, 128, false);\r
+ return buf.empty() ? "" : buf;\r
+ }\r
+ void setResponseHeader(const char* name, const char* value) {\r
+ // Set for later.\r
+ if (value)\r
+ m_headers.insert(make_pair(name,value));\r
+ else\r
+ m_headers.erase(name);\r
+ }\r
+ const char* getQueryString() const {\r
+ return m_lpECB->lpszQueryString;\r
+ }\r
+ const char* getRequestBody() const {\r
+ if (m_gotBody)\r
+ return m_body.c_str();\r
+ if (m_lpECB->cbTotalBytes > 1024*1024) // 1MB?\r
+ throw opensaml::SecurityPolicyException("Size of request body exceeded 1M size limit.");\r
+ else if (m_lpECB->cbTotalBytes > m_lpECB->cbAvailable) {\r
+ m_gotBody=true;\r
+ DWORD datalen=m_lpECB->cbTotalBytes;\r
+ if (m_lpECB->cbAvailable > 0) {\r
+ m_body.assign(reinterpret_cast<char*>(m_lpECB->lpbData),m_lpECB->cbAvailable);\r
+ datalen-=m_lpECB->cbAvailable;\r
+ }\r
+ char buf[8192];\r
+ while (datalen) {\r
+ DWORD buflen=8192;\r
+ BOOL ret = m_lpECB->ReadClient(m_lpECB->ConnID, buf, &buflen);\r
+ if (!ret)\r
+ throw IOException("Error reading request body from browser.");\r
+ else if (!buflen)\r
+ throw IOException("Socket closed while reading request body from browser.");\r
+ m_body.append(buf, buflen);\r
+ datalen-=buflen;\r
+ }\r
+ }\r
+ else if (m_lpECB->cbAvailable) {\r
+ m_gotBody=true;\r
+ m_body.assign(reinterpret_cast<char*>(m_lpECB->lpbData),m_lpECB->cbAvailable);\r
+ }\r
+ return m_body.c_str();\r
+ }\r
+ long sendResponse(istream& in, long status) {\r
+ string hdr = string("Connection: close\r\n");\r
+ for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)\r
+ hdr += i->first + ": " + i->second + "\r\n";\r
+ hdr += "\r\n";\r
+ const char* codestr="200 OK";\r
+ switch (status) {\r
+ case XMLTOOLING_HTTP_STATUS_UNAUTHORIZED: codestr="401 Authorization Required"; break;\r
+ case XMLTOOLING_HTTP_STATUS_FORBIDDEN: codestr="403 Forbidden"; break;\r
+ case XMLTOOLING_HTTP_STATUS_NOTFOUND: codestr="404 Not Found"; break;\r
+ case XMLTOOLING_HTTP_STATUS_ERROR: codestr="500 Server Error"; break;\r
+ }\r
+ m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, (void*)codestr, 0, (LPDWORD)hdr.c_str());\r
+ char buf[1024];\r
+ while (in) {\r
+ in.read(buf,1024);\r
+ DWORD resplen = in.gcount();\r
+ m_lpECB->WriteClient(m_lpECB->ConnID, buf, &resplen, HSE_IO_SYNC);\r
+ }\r
+ return HSE_STATUS_SUCCESS;\r
+ }\r
+ long sendRedirect(const char* url) {\r
+ string hdr=string("Location: ") + url + "\r\n"\r
+ "Content-Type: text/html\r\n"\r
+ "Content-Length: 40\r\n"\r
+ "Expires: 01-Jan-1997 12:00:00 GMT\r\n"\r
+ "Cache-Control: private,no-store,no-cache\r\n";\r
+ for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)\r
+ hdr += i->first + ": " + i->second + "\r\n";\r
+ hdr += "\r\n";\r
+ m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, "302 Moved", 0, (LPDWORD)hdr.c_str());\r
+ static const char* redmsg="<HTML><BODY>Redirecting...</BODY></HTML>";\r
+ DWORD resplen=40;\r
+ m_lpECB->WriteClient(m_lpECB->ConnID, (LPVOID)redmsg, &resplen, HSE_IO_SYNC);\r
+ return HSE_STATUS_SUCCESS;\r
+ }\r
+ // Decline happens in the POST processor if this isn't the shire url\r
+ // Note that it can also happen with HTAccess, but we don't support that, yet.\r
+ long returnDecline() {\r
+ return WriteClientError(\r
+ m_lpECB,\r
+ "ISAPI extension can only be invoked to process Shibboleth protocol requests."\r
+ "Make sure the mapped file extension doesn't match actual content."\r
+ );\r
+ }\r
+ long returnOK() {\r
+ return HSE_STATUS_SUCCESS;\r
+ }\r
+\r
+ const vector<string>& getClientCertificates() const {\r
+ if (m_certs.empty()) {\r
+ char CertificateBuf[8192];\r
+ CERT_CONTEXT_EX ccex;\r
+ ccex.cbAllocated = sizeof(CertificateBuf);\r
+ ccex.CertContext.pbCertEncoded = (BYTE*)CertificateBuf;\r
+ DWORD dwSize = sizeof(ccex);\r
+\r
+ if (m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_GET_CERT_INFO_EX, (LPVOID)&ccex, (LPDWORD)dwSize, NULL)) {\r
+ if (ccex.CertContext.cbCertEncoded) {\r
+ xsecsize_t outlen;\r
+ XMLByte* serialized = Base64::encode(reinterpret_cast<XMLByte*>(CertificateBuf), ccex.CertContext.cbCertEncoded, &outlen);\r
+ m_certs.push_back(reinterpret_cast<char*>(serialized));\r
+#ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE\r
+ XMLString::release(&serialized);\r
+#else\r
+ XMLString::release((char**)&serialized);\r
+#endif\r
+ }\r
+ }\r
+ }\r
+ return m_certs;\r
+ }\r
+\r
+ // Not used in the extension.\r
+ void clearHeader(const char* rawname, const char* cginame) { throw runtime_error("clearHeader not implemented"); }\r
+ void setHeader(const char* name, const char* value) { throw runtime_error("setHeader not implemented"); }\r
+ void setRemoteUser(const char* user) { throw runtime_error("setRemoteUser not implemented"); }\r
+};\r
+\r
+extern "C" DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB)\r
+{\r
+ try {\r
+ ostringstream threadid;\r
+ threadid << "[" << getpid() << "] isapi_shib_extension" << '\0';\r
+ xmltooling::NDC ndc(threadid.str().c_str());\r
+\r
+ // Determine web site number. This can't really fail, I don't think.\r
+ dynabuf buf(128);\r
+ GetServerVariable(lpECB,"INSTANCE_ID",buf,10);\r
+\r
+ // Match site instance to host name, skip if no match.\r
+ map<string,site_t>::const_iterator map_i=g_Sites.find(static_cast<char*>(buf));\r
+ if (map_i==g_Sites.end())\r
+ return WriteClientError(lpECB, "Shibboleth Extension not configured for web site (check <ISAPI> mappings in configuration).");\r
+\r
+ ShibTargetIsapiE ste(lpECB, map_i->second);\r
+ pair<bool,long> res = ste.getServiceProvider().doHandler(ste);\r
+ if (res.first) return res.second;\r
+\r
+ return WriteClientError(lpECB, "Shibboleth Extension failed to process request");\r
+\r
+ }\r
+ catch(bad_alloc) {\r
+ return WriteClientError(lpECB,"Out of Memory");\r
+ }\r
+ catch(long e) {\r
+ if (e==ERROR_NO_DATA)\r
+ return WriteClientError(lpECB,"A required variable or header was empty.");\r
+ else\r
+ return WriteClientError(lpECB,"Server detected unexpected IIS error.");\r
+ }\r
+ catch (exception& e) {\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, e.what());\r
+ return WriteClientError(lpECB,"Shibboleth Extension caught an exception, check Event Log for details.");\r
+ }\r
+ catch(...) {\r
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, "Shibboleth Extension threw an unknown exception.");\r
+ if (g_catchAll)\r
+ return WriteClientError(lpECB,"Shibboleth Extension threw an unknown exception.");\r
+ throw;\r
+ }\r
+\r
+ // If we get here we've got an error.\r
+ return HSE_STATUS_ERROR;\r
+}\r
--- /dev/null
+/*
+ * Copyright 2001-2009 Internet2
+ *
+ * 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.
+ */
+
+/**
+ * isapi_shib.cpp
+ *
+ * Shibboleth ISAPI filter
+ */
+
+#define SHIBSP_LITE
+#include "config_win32.h"
+
+#define _CRT_NONSTDC_NO_DEPRECATE 1
+#define _CRT_SECURE_NO_DEPRECATE 1
+
+#include <shibsp/AbstractSPRequest.h>
+#include <shibsp/SPConfig.h>
+#include <shibsp/ServiceProvider.h>
+#include <xmltooling/unicode.h>
+#include <xmltooling/XMLToolingConfig.h>
+#include <xmltooling/util/NDC.h>
+#include <xmltooling/util/XMLConstants.h>
+#include <xmltooling/util/XMLHelper.h>
+#include <xercesc/util/Base64.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+#include <set>
+#include <sstream>
+#include <fstream>
+#include <stdexcept>
+#include <process.h>
+
+#include <windows.h>
+#include <httpfilt.h>
+#include <httpext.h>
+
+using namespace shibsp;
+using namespace xmltooling;
+using namespace xercesc;
+using namespace std;
+
+// globals
+namespace {
+ static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);
+ static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);
+ static const XMLCh name[] = UNICODE_LITERAL_4(n,a,m,e);
+ static const XMLCh port[] = UNICODE_LITERAL_4(p,o,r,t);
+ static const XMLCh sslport[] = UNICODE_LITERAL_7(s,s,l,p,o,r,t);
+ static const XMLCh scheme[] = UNICODE_LITERAL_6(s,c,h,e,m,e);
+ static const XMLCh id[] = UNICODE_LITERAL_2(i,d);
+ static const XMLCh Alias[] = UNICODE_LITERAL_5(A,l,i,a,s);
+ static const XMLCh Site[] = UNICODE_LITERAL_4(S,i,t,e);
+
+ struct site_t {
+ site_t(const DOMElement* e)
+ {
+ auto_ptr_char n(e->getAttributeNS(NULL,name));
+ auto_ptr_char s(e->getAttributeNS(NULL,scheme));
+ auto_ptr_char p(e->getAttributeNS(NULL,port));
+ auto_ptr_char p2(e->getAttributeNS(NULL,sslport));
+ if (n.get()) m_name=n.get();
+ if (s.get()) m_scheme=s.get();
+ if (p.get()) m_port=p.get();
+ if (p2.get()) m_sslport=p2.get();
+ e = XMLHelper::getFirstChildElement(e, Alias);
+ while (e) {
+ if (e->hasChildNodes()) {
+ auto_ptr_char alias(e->getFirstChild()->getNodeValue());
+ m_aliases.insert(alias.get());
+ }
+ e = XMLHelper::getNextSiblingElement(e, Alias);
+ }
+ }
+ string m_scheme,m_port,m_sslport,m_name;
+ set<string> m_aliases;
+ };
+
+ struct context_t {
+ char* m_user;
+ bool m_checked;
+ };
+
+ HINSTANCE g_hinstDLL;
+ SPConfig* g_Config = NULL;
+ map<string,site_t> g_Sites;
+ bool g_bNormalizeRequest = true;
+ string g_unsetHeaderValue;
+ bool g_checkSpoofing = true;
+ bool g_catchAll = false;
+ vector<string> g_NoCerts;
+}
+
+BOOL LogEvent(
+ LPCSTR lpUNCServerName,
+ WORD wType,
+ DWORD dwEventID,
+ PSID lpUserSid,
+ LPCSTR message)
+{
+ LPCSTR messages[] = {message, NULL};
+
+ HANDLE hElog = RegisterEventSource(lpUNCServerName, "Shibboleth ISAPI Filter");
+ BOOL res = ReportEvent(hElog, wType, 0, dwEventID, lpUserSid, 1, 0, messages, NULL);
+ return (DeregisterEventSource(hElog) && res);
+}
+
+extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID)
+{
+ if (fdwReason==DLL_PROCESS_ATTACH)
+ g_hinstDLL=hinstDLL;
+ return TRUE;
+}
+
+extern "C" BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO* pVer)
+{
+ if (!pVer)
+ return FALSE;
+
+ if (!g_Config) {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Extension mode startup not possible, is the DLL loaded as a filter?");
+ return FALSE;
+ }
+
+ pVer->dwExtensionVersion=HSE_VERSION;
+ strncpy(pVer->lpszExtensionDesc,"Shibboleth ISAPI Extension",HSE_MAX_EXT_DLL_NAME_LEN-1);
+ return TRUE;
+}
+
+extern "C" BOOL WINAPI TerminateExtension(DWORD)
+{
+ return TRUE; // cleanup should happen when filter unloads
+}
+
+extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
+{
+ if (!pVer)
+ return FALSE;
+ else if (g_Config) {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Reentrant filter initialization, ignoring...");
+ return TRUE;
+ }
+
+ g_Config=&SPConfig::getConfig();
+ g_Config->setFeatures(
+ SPConfig::Listener |
+ SPConfig::Caching |
+ SPConfig::RequestMapping |
+ SPConfig::InProcess |
+ SPConfig::Logging |
+ SPConfig::Handlers
+ );
+ if (!g_Config->init()) {
+ g_Config=NULL;
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Filter startup failed during library initialization, check native log for help.");
+ return FALSE;
+ }
+
+ try {
+ if (!g_Config->instantiate(NULL, true))
+ throw runtime_error("unknown error");
+ }
+ catch (exception& ex) {
+ g_Config->term();
+ g_Config=NULL;
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, ex.what());
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Filter startup failed to load configuration, check native log for details.");
+ return FALSE;
+ }
+
+ // Access implementation-specifics and site mappings.
+ ServiceProvider* sp=g_Config->getServiceProvider();
+ Locker locker(sp);
+ const PropertySet* props=sp->getPropertySet("InProcess");
+ if (props) {
+ pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
+ if (unsetValue.first)
+ g_unsetHeaderValue = unsetValue.second;
+ pair<bool,bool> flag=props->getBool("checkSpoofing");
+ g_checkSpoofing = !flag.first || flag.second;
+ flag=props->getBool("catchAll");
+ g_catchAll = flag.first && flag.second;
+
+ props = props->getPropertySet("ISAPI");
+ if (props) {
+ flag = props->getBool("normalizeRequest");
+ g_bNormalizeRequest = !flag.first || flag.second;
+ const DOMElement* child = XMLHelper::getFirstChildElement(props->getElement(),Site);
+ while (child) {
+ auto_ptr_char id(child->getAttributeNS(NULL,id));
+ if (id.get())
+ g_Sites.insert(pair<string,site_t>(id.get(),site_t(child)));
+ child=XMLHelper::getNextSiblingElement(child,Site);
+ }
+ }
+ }
+
+ pVer->dwFilterVersion=HTTP_FILTER_REVISION;
+ strncpy(pVer->lpszFilterDesc,"Shibboleth ISAPI Filter",SF_MAX_FILTER_DESC_LEN);
+ pVer->dwFlags=(SF_NOTIFY_ORDER_HIGH |
+ SF_NOTIFY_SECURE_PORT |
+ SF_NOTIFY_NONSECURE_PORT |
+ SF_NOTIFY_PREPROC_HEADERS |
+ SF_NOTIFY_LOG);
+ LogEvent(NULL, EVENTLOG_INFORMATION_TYPE, 7701, NULL, "Filter initialized...");
+ return TRUE;
+}
+
+extern "C" BOOL WINAPI TerminateFilter(DWORD)
+{
+ if (g_Config)
+ g_Config->term();
+ g_Config = NULL;
+ LogEvent(NULL, EVENTLOG_INFORMATION_TYPE, 7701, NULL, "Filter shut down...");
+ return TRUE;
+}
+
+/* Next up, some suck-free versions of various APIs.
+
+ You DON'T require people to guess the buffer size and THEN tell them the right size.
+ Returning an LPCSTR is apparently way beyond their ken. Not to mention the fact that
+ constant strings aren't typed as such, making it just that much harder. These versions
+ are now updated to use a special growable buffer object, modeled after the standard
+ string class. The standard string won't work because they left out the option to
+ pre-allocate a non-constant buffer.
+*/
+
+class dynabuf
+{
+public:
+ dynabuf() { bufptr=NULL; buflen=0; }
+ dynabuf(size_t s) { bufptr=new char[buflen=s]; *bufptr=0; }
+ ~dynabuf() { delete[] bufptr; }
+ size_t length() const { return bufptr ? strlen(bufptr) : 0; }
+ size_t size() const { return buflen; }
+ bool empty() const { return length()==0; }
+ void reserve(size_t s, bool keep=false);
+ void erase() { if (bufptr) memset(bufptr,0,buflen); }
+ operator char*() { return bufptr; }
+ bool operator ==(const char* s) const;
+ bool operator !=(const char* s) const { return !(*this==s); }
+private:
+ char* bufptr;
+ size_t buflen;
+};
+
+void dynabuf::reserve(size_t s, bool keep)
+{
+ if (s<=buflen)
+ return;
+ char* p=new char[s];
+ if (keep)
+ while (buflen--)
+ p[buflen]=bufptr[buflen];
+ buflen=s;
+ delete[] bufptr;
+ bufptr=p;
+}
+
+bool dynabuf::operator==(const char* s) const
+{
+ if (buflen==NULL || s==NULL)
+ return (buflen==NULL && s==NULL);
+ else
+ return strcmp(bufptr,s)==0;
+}
+
+void GetServerVariable(PHTTP_FILTER_CONTEXT pfc, LPSTR lpszVariable, dynabuf& s, DWORD size=80, bool bRequired=true)
+{
+ s.reserve(size);
+ s.erase();
+ size=s.size();
+
+ while (!pfc->GetServerVariable(pfc,lpszVariable,s,&size)) {
+ // Grumble. Check the error.
+ DWORD e=GetLastError();
+ if (e==ERROR_INSUFFICIENT_BUFFER)
+ s.reserve(size);
+ else
+ break;
+ }
+ if (bRequired && s.empty())
+ throw ERROR_NO_DATA;
+}
+
+void GetServerVariable(LPEXTENSION_CONTROL_BLOCK lpECB, LPSTR lpszVariable, dynabuf& s, DWORD size=80, bool bRequired=true)
+{
+ s.reserve(size);
+ s.erase();
+ size=s.size();
+
+ while (!lpECB->GetServerVariable(lpECB->ConnID,lpszVariable,s,&size)) {
+ // Grumble. Check the error.
+ DWORD e=GetLastError();
+ if (e==ERROR_INSUFFICIENT_BUFFER)
+ s.reserve(size);
+ else
+ break;
+ }
+ if (bRequired && s.empty())
+ throw ERROR_NO_DATA;
+}
+
+void GetHeader(PHTTP_FILTER_PREPROC_HEADERS pn, PHTTP_FILTER_CONTEXT pfc,
+ LPSTR lpszName, dynabuf& s, DWORD size=80, bool bRequired=true)
+{
+ s.reserve(size);
+ s.erase();
+ size=s.size();
+
+ while (!pn->GetHeader(pfc,lpszName,s,&size)) {
+ // Grumble. Check the error.
+ DWORD e=GetLastError();
+ if (e==ERROR_INSUFFICIENT_BUFFER)
+ s.reserve(size);
+ else
+ break;
+ }
+ if (bRequired && s.empty())
+ throw ERROR_NO_DATA;
+}
+
+/****************************************************************************/
+// ISAPI Filter
+
+class ShibTargetIsapiF : public AbstractSPRequest
+{
+ PHTTP_FILTER_CONTEXT m_pfc;
+ PHTTP_FILTER_PREPROC_HEADERS m_pn;
+ multimap<string,string> m_headers;
+ int m_port;
+ string m_scheme,m_hostname;
+ mutable string m_remote_addr,m_content_type,m_method;
+ dynabuf m_allhttp;
+
+public:
+ ShibTargetIsapiF(PHTTP_FILTER_CONTEXT pfc, PHTTP_FILTER_PREPROC_HEADERS pn, const site_t& site)
+ : AbstractSPRequest(SHIBSP_LOGCAT".ISAPI"), m_pfc(pfc), m_pn(pn), m_allhttp(4096) {
+
+ // URL path always come from IIS.
+ dynabuf var(256);
+ GetHeader(pn,pfc,"url",var,256,false);
+ setRequestURI(var);
+
+ // Port may come from IIS or from site def.
+ if (!g_bNormalizeRequest || (pfc->fIsSecurePort && site.m_sslport.empty()) || (!pfc->fIsSecurePort && site.m_port.empty())) {
+ GetServerVariable(pfc,"SERVER_PORT",var,10);
+ m_port = atoi(var);
+ }
+ else if (pfc->fIsSecurePort) {
+ m_port = atoi(site.m_sslport.c_str());
+ }
+ else {
+ m_port = atoi(site.m_port.c_str());
+ }
+
+ // Scheme may come from site def or be derived from IIS.
+ m_scheme=site.m_scheme;
+ if (m_scheme.empty() || !g_bNormalizeRequest)
+ m_scheme=pfc->fIsSecurePort ? "https" : "http";
+
+ GetServerVariable(pfc,"SERVER_NAME",var,32);
+
+ // Make sure SERVER_NAME is "authorized" for use on this site. If not, set to canonical name.
+ m_hostname = var;
+ if (site.m_name!=m_hostname && site.m_aliases.find(m_hostname)==site.m_aliases.end())
+ m_hostname=site.m_name;
+
+ if (!pfc->pFilterContext) {
+ pfc->pFilterContext = pfc->AllocMem(pfc, sizeof(context_t), NULL);
+ if (static_cast<context_t*>(pfc->pFilterContext)) {
+ static_cast<context_t*>(pfc->pFilterContext)->m_user = NULL;
+ static_cast<context_t*>(pfc->pFilterContext)->m_checked = false;
+ }
+ }
+ }
+ ~ShibTargetIsapiF() { }
+
+ const char* getScheme() const {
+ return m_scheme.c_str();
+ }
+ const char* getHostname() const {
+ return m_hostname.c_str();
+ }
+ int getPort() const {
+ return m_port;
+ }
+ const char* getQueryString() const {
+ const char* uri = getRequestURI();
+ uri = (uri ? strchr(uri, '?') : NULL);
+ return uri ? (uri + 1) : NULL;
+ }
+ const char* getMethod() const {
+ if (m_method.empty()) {
+ dynabuf var(5);
+ GetServerVariable(m_pfc,"HTTP_METHOD",var,5,false);
+ if (!var.empty())
+ m_method = var;
+ }
+ return m_method.c_str();
+ }
+ string getContentType() const {
+ if (m_content_type.empty()) {
+ dynabuf var(32);
+ GetServerVariable(m_pfc,"HTTP_CONTENT_TYPE",var,32,false);
+ if (!var.empty())
+ m_content_type = var;
+ }
+ return m_content_type;
+ }
+ string getRemoteAddr() const {
+ m_remote_addr = AbstractSPRequest::getRemoteAddr();
+ if (m_remote_addr.empty()) {
+ dynabuf var(16);
+ GetServerVariable(m_pfc,"REMOTE_ADDR",var,16,false);
+ if (!var.empty())
+ m_remote_addr = var;
+ }
+ return m_remote_addr;
+ }
+ void log(SPLogLevel level, const string& msg) {
+ AbstractSPRequest::log(level,msg);
+ if (level >= SPError)
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg.c_str());
+ }
+ void clearHeader(const char* rawname, const char* cginame) {
+ if (g_checkSpoofing && m_pfc->pFilterContext && !static_cast<context_t*>(m_pfc->pFilterContext)->m_checked) {
+ if (m_allhttp.empty())
+ GetServerVariable(m_pfc,"ALL_HTTP",m_allhttp,4096);
+ if (strstr(m_allhttp, cginame))
+ throw opensaml::SecurityPolicyException("Attempt to spoof header ($1) was detected.", params(1, rawname));
+ }
+ string hdr(!strcmp(rawname,"REMOTE_USER") ? "remote-user" : rawname);
+ hdr += ':';
+ m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(g_unsetHeaderValue.c_str()));
+ }
+ void setHeader(const char* name, const char* value) {
+ string hdr(name);
+ hdr += ':';
+ m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(value));
+ }
+ string getHeader(const char* name) const {
+ string hdr(name);
+ hdr += ':';
+ dynabuf buf(256);
+ GetHeader(m_pn, m_pfc, const_cast<char*>(hdr.c_str()), buf, 256, false);
+ return string(buf);
+ }
+ void setRemoteUser(const char* user) {
+ setHeader("remote-user", user);
+ if (m_pfc->pFilterContext) {
+ if (!user || !*user)
+ static_cast<context_t*>(m_pfc->pFilterContext)->m_user = NULL;
+ else if (static_cast<context_t*>(m_pfc->pFilterContext)->m_user = (char*)m_pfc->AllocMem(m_pfc, sizeof(char) * (strlen(user) + 1), NULL))
+ strcpy(static_cast<context_t*>(m_pfc->pFilterContext)->m_user, user);
+ }
+ }
+ string getRemoteUser() const {
+ return getHeader("remote-user");
+ }
+ void setResponseHeader(const char* name, const char* value) {
+ // Set for later.
+ if (value)
+ m_headers.insert(make_pair(name,value));
+ else
+ m_headers.erase(name);
+ }
+ long sendResponse(istream& in, long status) {
+ string hdr = string("Connection: close\r\n");
+ for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+ hdr += i->first + ": " + i->second + "\r\n";
+ hdr += "\r\n";
+ const char* codestr="200 OK";
+ switch (status) {
+ case XMLTOOLING_HTTP_STATUS_UNAUTHORIZED: codestr="401 Authorization Required"; break;
+ case XMLTOOLING_HTTP_STATUS_FORBIDDEN: codestr="403 Forbidden"; break;
+ case XMLTOOLING_HTTP_STATUS_NOTFOUND: codestr="404 Not Found"; break;
+ case XMLTOOLING_HTTP_STATUS_ERROR: codestr="500 Server Error"; break;
+ }
+ m_pfc->ServerSupportFunction(m_pfc, SF_REQ_SEND_RESPONSE_HEADER, (void*)codestr, (DWORD)hdr.c_str(), 0);
+ char buf[1024];
+ while (in) {
+ in.read(buf,1024);
+ DWORD resplen = in.gcount();
+ m_pfc->WriteClient(m_pfc, buf, &resplen, 0);
+ }
+ return SF_STATUS_REQ_FINISHED;
+ }
+ long sendRedirect(const char* url) {
+ // XXX: Don't support the httpRedirect option, yet.
+ string hdr=string("Location: ") + url + "\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 40\r\n"
+ "Expires: 01-Jan-1997 12:00:00 GMT\r\n"
+ "Cache-Control: private,no-store,no-cache\r\n";
+ for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+ hdr += i->first + ": " + i->second + "\r\n";
+ hdr += "\r\n";
+ m_pfc->ServerSupportFunction(m_pfc, SF_REQ_SEND_RESPONSE_HEADER, "302 Please Wait", (DWORD)hdr.c_str(), 0);
+ static const char* redmsg="<HTML><BODY>Redirecting...</BODY></HTML>";
+ DWORD resplen=40;
+ m_pfc->WriteClient(m_pfc, (LPVOID)redmsg, &resplen, 0);
+ return SF_STATUS_REQ_FINISHED;
+ }
+ long returnDecline() {
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+ }
+ long returnOK() {
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+ }
+
+ const vector<string>& getClientCertificates() const {
+ return g_NoCerts;
+ }
+
+ // The filter never processes the POST, so stub these methods.
+ long getContentLength() const { throw IOException("The request's Content-Length is not available to an ISAPI filter."); }
+ const char* getRequestBody() const { throw IOException("The request body is not available to an ISAPI filter."); }
+};
+
+DWORD WriteClientError(PHTTP_FILTER_CONTEXT pfc, const char* msg)
+{
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg);
+ static const char* ctype="Connection: close\r\nContent-Type: text/html\r\n\r\n";
+ pfc->ServerSupportFunction(pfc,SF_REQ_SEND_RESPONSE_HEADER,"200 OK",(DWORD)ctype,0);
+ static const char* xmsg="<HTML><HEAD><TITLE>Shibboleth Filter Error</TITLE></HEAD><BODY>"
+ "<H1>Shibboleth Filter Error</H1>";
+ DWORD resplen=strlen(xmsg);
+ pfc->WriteClient(pfc,(LPVOID)xmsg,&resplen,0);
+ resplen=strlen(msg);
+ pfc->WriteClient(pfc,(LPVOID)msg,&resplen,0);
+ static const char* xmsg2="</BODY></HTML>";
+ resplen=strlen(xmsg2);
+ pfc->WriteClient(pfc,(LPVOID)xmsg2,&resplen,0);
+ return SF_STATUS_REQ_FINISHED;
+}
+
+extern "C" DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificationType, LPVOID pvNotification)
+{
+ // Is this a log notification?
+ if (notificationType==SF_NOTIFY_LOG) {
+ if (pfc->pFilterContext && static_cast<context_t*>(pfc->pFilterContext)->m_user)
+ ((PHTTP_FILTER_LOG)pvNotification)->pszClientUserName=static_cast<context_t*>(pfc->pFilterContext)->m_user;
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+ }
+
+ PHTTP_FILTER_PREPROC_HEADERS pn=(PHTTP_FILTER_PREPROC_HEADERS)pvNotification;
+ try
+ {
+ // Determine web site number. This can't really fail, I don't think.
+ dynabuf buf(128);
+ GetServerVariable(pfc,"INSTANCE_ID",buf,10);
+
+ // Match site instance to host name, skip if no match.
+ map<string,site_t>::const_iterator map_i=g_Sites.find(static_cast<char*>(buf));
+ if (map_i==g_Sites.end())
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+
+ ostringstream threadid;
+ threadid << "[" << getpid() << "] isapi_shib" << '\0';
+ xmltooling::NDC ndc(threadid.str().c_str());
+
+ ShibTargetIsapiF stf(pfc, pn, map_i->second);
+
+ // "false" because we don't override the Shib settings
+ pair<bool,long> res = stf.getServiceProvider().doAuthentication(stf);
+ if (pfc->pFilterContext)
+ static_cast<context_t*>(pfc->pFilterContext)->m_checked = true;
+ if (res.first) return res.second;
+
+ // "false" because we don't override the Shib settings
+ res = stf.getServiceProvider().doExport(stf);
+ if (res.first) return res.second;
+
+ res = stf.getServiceProvider().doAuthorization(stf);
+ if (res.first) return res.second;
+
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+ }
+ catch(bad_alloc) {
+ return WriteClientError(pfc,"Out of Memory");
+ }
+ catch(long e) {
+ if (e==ERROR_NO_DATA)
+ return WriteClientError(pfc,"A required variable or header was empty.");
+ else
+ return WriteClientError(pfc,"Shibboleth Filter detected unexpected IIS error.");
+ }
+ catch (exception& e) {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, e.what());
+ return WriteClientError(pfc,"Shibboleth Filter caught an exception, check Event Log for details.");
+ }
+ catch(...) {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, "Shibboleth Filter threw an unknown exception.");
+ if (g_catchAll)
+ return WriteClientError(pfc,"Shibboleth Filter threw an unknown exception.");
+ throw;
+ }
+
+ return WriteClientError(pfc,"Shibboleth Filter reached unreachable code, save my walrus!");
+}
+
+
+/****************************************************************************/
+// ISAPI Extension
+
+DWORD WriteClientError(LPEXTENSION_CONTROL_BLOCK lpECB, const char* msg)
+{
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg);
+ static const char* ctype="Connection: close\r\nContent-Type: text/html\r\n\r\n";
+ lpECB->ServerSupportFunction(lpECB->ConnID,HSE_REQ_SEND_RESPONSE_HEADER,"200 OK",0,(LPDWORD)ctype);
+ static const char* xmsg="<HTML><HEAD><TITLE>Shibboleth Error</TITLE></HEAD><BODY><H1>Shibboleth Error</H1>";
+ DWORD resplen=strlen(xmsg);
+ lpECB->WriteClient(lpECB->ConnID,(LPVOID)xmsg,&resplen,HSE_IO_SYNC);
+ resplen=strlen(msg);
+ lpECB->WriteClient(lpECB->ConnID,(LPVOID)msg,&resplen,HSE_IO_SYNC);
+ static const char* xmsg2="</BODY></HTML>";
+ resplen=strlen(xmsg2);
+ lpECB->WriteClient(lpECB->ConnID,(LPVOID)xmsg2,&resplen,HSE_IO_SYNC);
+ return HSE_STATUS_SUCCESS;
+}
+
+
+class ShibTargetIsapiE : public AbstractSPRequest
+{
+ LPEXTENSION_CONTROL_BLOCK m_lpECB;
+ multimap<string,string> m_headers;
+ mutable vector<string> m_certs;
+ mutable string m_body;
+ mutable bool m_gotBody;
+ int m_port;
+ string m_scheme,m_hostname,m_uri;
+ mutable string m_remote_addr,m_remote_user;
+
+public:
+ ShibTargetIsapiE(LPEXTENSION_CONTROL_BLOCK lpECB, const site_t& site)
+ : AbstractSPRequest(SHIBSP_LOGCAT".ISAPI"), m_lpECB(lpECB), m_gotBody(false) {
+ dynabuf ssl(5);
+ GetServerVariable(lpECB,"HTTPS",ssl,5);
+ bool SSL=(ssl=="on" || ssl=="ON");
+
+ // Scheme may come from site def or be derived from IIS.
+ m_scheme=site.m_scheme;
+ if (m_scheme.empty() || !g_bNormalizeRequest)
+ m_scheme = SSL ? "https" : "http";
+
+ // URL path always come from IIS.
+ dynabuf url(256);
+ GetServerVariable(lpECB,"URL",url,255);
+
+ // Port may come from IIS or from site def.
+ dynabuf port(11);
+ if (!g_bNormalizeRequest || (SSL && site.m_sslport.empty()) || (!SSL && site.m_port.empty()))
+ GetServerVariable(lpECB,"SERVER_PORT",port,10);
+ else if (SSL) {
+ strncpy(port,site.m_sslport.c_str(),10);
+ static_cast<char*>(port)[10]=0;
+ }
+ else {
+ strncpy(port,site.m_port.c_str(),10);
+ static_cast<char*>(port)[10]=0;
+ }
+ m_port = atoi(port);
+
+ dynabuf var(32);
+ GetServerVariable(lpECB, "SERVER_NAME", var, 32);
+
+ // Make sure SERVER_NAME is "authorized" for use on this site. If not, set to canonical name.
+ m_hostname=var;
+ if (site.m_name!=m_hostname && site.m_aliases.find(m_hostname)==site.m_aliases.end())
+ m_hostname=site.m_name;
+
+ /*
+ * IIS screws us over on PATH_INFO (the hits keep on coming). We need to figure out if
+ * the server is set up for proper PATH_INFO handling, or "IIS sucks rabid weasels mode",
+ * which is the default. No perfect way to tell, but we can take a good guess by checking
+ * whether the URL is a substring of the PATH_INFO:
+ *
+ * e.g. for /Shibboleth.sso/SAML/POST
+ *
+ * Bad mode (default):
+ * URL: /Shibboleth.sso
+ * PathInfo: /Shibboleth.sso/SAML/POST
+ *
+ * Good mode:
+ * URL: /Shibboleth.sso
+ * PathInfo: /SAML/POST
+ */
+
+ string uri;
+
+ // Clearly we're only in bad mode if path info exists at all.
+ if (lpECB->lpszPathInfo && *(lpECB->lpszPathInfo)) {
+ if (strstr(lpECB->lpszPathInfo,url))
+ // Pretty good chance we're in bad mode, unless the PathInfo repeats the path itself.
+ uri = lpECB->lpszPathInfo;
+ else {
+ uri = url;
+ uri += lpECB->lpszPathInfo;
+ }
+ }
+ else {
+ uri = url;
+ }
+
+ // For consistency with Apache, let's add the query string.
+ if (lpECB->lpszQueryString && *(lpECB->lpszQueryString)) {
+ uri += '?';
+ uri += lpECB->lpszQueryString;
+ }
+
+ setRequestURI(uri.c_str());
+ }
+ ~ShibTargetIsapiE() { }
+
+ const char* getScheme() const {
+ return m_scheme.c_str();
+ }
+ const char* getHostname() const {
+ return m_hostname.c_str();
+ }
+ int getPort() const {
+ return m_port;
+ }
+ const char* getMethod() const {
+ return m_lpECB->lpszMethod;
+ }
+ string getContentType() const {
+ return m_lpECB->lpszContentType ? m_lpECB->lpszContentType : "";
+ }
+ long getContentLength() const {
+ return m_lpECB->cbTotalBytes;
+ }
+ string getRemoteUser() const {
+ if (m_remote_user.empty()) {
+ dynabuf var(16);
+ GetServerVariable(m_lpECB, "REMOTE_USER", var, 32, false);
+ if (!var.empty())
+ m_remote_user = var;
+ }
+ return m_remote_user;
+ }
+ string getRemoteAddr() const {
+ m_remote_addr = AbstractSPRequest::getRemoteAddr();
+ if (m_remote_addr.empty()) {
+ dynabuf var(16);
+ GetServerVariable(m_lpECB, "REMOTE_ADDR", var, 16, false);
+ if (!var.empty())
+ m_remote_addr = var;
+ }
+ return m_remote_addr;
+ }
+ void log(SPLogLevel level, const string& msg) const {
+ AbstractSPRequest::log(level,msg);
+ if (level >= SPError)
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg.c_str());
+ }
+ string getHeader(const char* name) const {
+ string hdr("HTTP_");
+ for (; *name; ++name) {
+ if (*name=='-')
+ hdr += '_';
+ else
+ hdr += toupper(*name);
+ }
+ dynabuf buf(128);
+ GetServerVariable(m_lpECB, const_cast<char*>(hdr.c_str()), buf, 128, false);
+ return buf.empty() ? "" : buf;
+ }
+ void setResponseHeader(const char* name, const char* value) {
+ // Set for later.
+ if (value)
+ m_headers.insert(make_pair(name,value));
+ else
+ m_headers.erase(name);
+ }
+ const char* getQueryString() const {
+ return m_lpECB->lpszQueryString;
+ }
+ const char* getRequestBody() const {
+ if (m_gotBody)
+ return m_body.c_str();
+ if (m_lpECB->cbTotalBytes > 1024*1024) // 1MB?
+ throw opensaml::SecurityPolicyException("Size of request body exceeded 1M size limit.");
+ else if (m_lpECB->cbTotalBytes > m_lpECB->cbAvailable) {
+ m_gotBody=true;
+ DWORD datalen=m_lpECB->cbTotalBytes;
+ if (m_lpECB->cbAvailable > 0) {
+ m_body.assign(reinterpret_cast<char*>(m_lpECB->lpbData),m_lpECB->cbAvailable);
+ datalen-=m_lpECB->cbAvailable;
+ }
+ char buf[8192];
+ while (datalen) {
+ DWORD buflen=8192;
+ BOOL ret = m_lpECB->ReadClient(m_lpECB->ConnID, buf, &buflen);
+ if (!ret)
+ throw IOException("Error reading request body from browser.");
+ else if (!buflen)
+ throw IOException("Socket closed while reading request body from browser.");
+ m_body.append(buf, buflen);
+ datalen-=buflen;
+ }
+ }
+ else if (m_lpECB->cbAvailable) {
+ m_gotBody=true;
+ m_body.assign(reinterpret_cast<char*>(m_lpECB->lpbData),m_lpECB->cbAvailable);
+ }
+ return m_body.c_str();
+ }
+ long sendResponse(istream& in, long status) {
+ string hdr = string("Connection: close\r\n");
+ for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+ hdr += i->first + ": " + i->second + "\r\n";
+ hdr += "\r\n";
+ const char* codestr="200 OK";
+ switch (status) {
+ case XMLTOOLING_HTTP_STATUS_UNAUTHORIZED: codestr="401 Authorization Required"; break;
+ case XMLTOOLING_HTTP_STATUS_FORBIDDEN: codestr="403 Forbidden"; break;
+ case XMLTOOLING_HTTP_STATUS_NOTFOUND: codestr="404 Not Found"; break;
+ case XMLTOOLING_HTTP_STATUS_ERROR: codestr="500 Server Error"; break;
+ }
+ m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, (void*)codestr, 0, (LPDWORD)hdr.c_str());
+ char buf[1024];
+ while (in) {
+ in.read(buf,1024);
+ DWORD resplen = in.gcount();
+ m_lpECB->WriteClient(m_lpECB->ConnID, buf, &resplen, HSE_IO_SYNC);
+ }
+ return HSE_STATUS_SUCCESS;
+ }
+ long sendRedirect(const char* url) {
+ string hdr=string("Location: ") + url + "\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 40\r\n"
+ "Expires: 01-Jan-1997 12:00:00 GMT\r\n"
+ "Cache-Control: private,no-store,no-cache\r\n";
+ for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+ hdr += i->first + ": " + i->second + "\r\n";
+ hdr += "\r\n";
+ m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, "302 Moved", 0, (LPDWORD)hdr.c_str());
+ static const char* redmsg="<HTML><BODY>Redirecting...</BODY></HTML>";
+ DWORD resplen=40;
+ m_lpECB->WriteClient(m_lpECB->ConnID, (LPVOID)redmsg, &resplen, HSE_IO_SYNC);
+ return HSE_STATUS_SUCCESS;
+ }
+ // Decline happens in the POST processor if this isn't the shire url
+ // Note that it can also happen with HTAccess, but we don't support that, yet.
+ long returnDecline() {
+ return WriteClientError(
+ m_lpECB,
+ "ISAPI extension can only be invoked to process Shibboleth protocol requests."
+ "Make sure the mapped file extension doesn't match actual content."
+ );
+ }
+ long returnOK() {
+ return HSE_STATUS_SUCCESS;
+ }
+
+ const vector<string>& getClientCertificates() const {
+ if (m_certs.empty()) {
+ char CertificateBuf[8192];
+ CERT_CONTEXT_EX ccex;
+ ccex.cbAllocated = sizeof(CertificateBuf);
+ ccex.CertContext.pbCertEncoded = (BYTE*)CertificateBuf;
+ DWORD dwSize = sizeof(ccex);
+
+ if (m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_GET_CERT_INFO_EX, (LPVOID)&ccex, (LPDWORD)dwSize, NULL)) {
+ if (ccex.CertContext.cbCertEncoded) {
+ xsecsize_t outlen;
+ XMLByte* serialized = Base64::encode(reinterpret_cast<XMLByte*>(CertificateBuf), ccex.CertContext.cbCertEncoded, &outlen);
+ m_certs.push_back(reinterpret_cast<char*>(serialized));
+#ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE
+ XMLString::release(&serialized);
+#else
+ XMLString::release((char**)&serialized);
+#endif
+ }
+ }
+ }
+ return m_certs;
+ }
+
+ // Not used in the extension.
+ void clearHeader(const char* rawname, const char* cginame) { throw runtime_error("clearHeader not implemented"); }
+ void setHeader(const char* name, const char* value) { throw runtime_error("setHeader not implemented"); }
+ void setRemoteUser(const char* user) { throw runtime_error("setRemoteUser not implemented"); }
+};
+
+extern "C" DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB)
+{
+ try {
+ ostringstream threadid;
+ threadid << "[" << getpid() << "] isapi_shib_extension" << '\0';
+ xmltooling::NDC ndc(threadid.str().c_str());
+
+ // Determine web site number. This can't really fail, I don't think.
+ dynabuf buf(128);
+ GetServerVariable(lpECB,"INSTANCE_ID",buf,10);
+
+ // Match site instance to host name, skip if no match.
+ map<string,site_t>::const_iterator map_i=g_Sites.find(static_cast<char*>(buf));
+ if (map_i==g_Sites.end())
+ return WriteClientError(lpECB, "Shibboleth Extension not configured for web site (check <ISAPI> mappings in configuration).");
+
+ ShibTargetIsapiE ste(lpECB, map_i->second);
+ pair<bool,long> res = ste.getServiceProvider().doHandler(ste);
+ if (res.first) return res.second;
+
+ return WriteClientError(lpECB, "Shibboleth Extension failed to process request");
+
+ }
+ catch(bad_alloc) {
+ return WriteClientError(lpECB,"Out of Memory");
+ }
+ catch(long e) {
+ if (e==ERROR_NO_DATA)
+ return WriteClientError(lpECB,"A required variable or header was empty.");
+ else
+ return WriteClientError(lpECB,"Server detected unexpected IIS error.");
+ }
+ catch (exception& e) {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, e.what());
+ return WriteClientError(lpECB,"Shibboleth Extension caught an exception, check Event Log for details.");
+ }
+ catch(...) {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, "Shibboleth Extension threw an unknown exception.");
+ if (g_catchAll)
+ return WriteClientError(lpECB,"Shibboleth Extension threw an unknown exception.");
+ throw;
+ }
+
+ // If we get here we've got an error.
+ return HSE_STATUS_ERROR;
+}
--- /dev/null
+/*
+ * Copyright 2001-2009 Internet2
+ *
+ * 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.
+ */
+
+/**
+ * isapi_shib.cpp
+ *
+ * Shibboleth ISAPI filter
+ */
+
+#define SHIBSP_LITE
+#include "config_win32.h"
+
+#define _CRT_NONSTDC_NO_DEPRECATE 1
+#define _CRT_SECURE_NO_DEPRECATE 1
+#define _CRT_RAND_S
+
+#include <shibsp/AbstractSPRequest.h>
+#include <shibsp/SPConfig.h>
+#include <shibsp/ServiceProvider.h>
+#include <xmltooling/unicode.h>
+#include <xmltooling/XMLToolingConfig.h>
+#include <xmltooling/util/NDC.h>
+#include <xmltooling/util/XMLConstants.h>
+#include <xmltooling/util/XMLHelper.h>
+#include <xercesc/util/Base64.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+#include <set>
+#include <sstream>
+#include <fstream>
+#include <stdexcept>
+#include <process.h>
+
+#include <windows.h>
+#include <httpfilt.h>
+#include <httpext.h>
+
+using namespace shibsp;
+using namespace xmltooling;
+using namespace xercesc;
+using namespace std;
+
+// globals
+namespace {
+ static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);
+ static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);
+ static const XMLCh name[] = UNICODE_LITERAL_4(n,a,m,e);
+ static const XMLCh port[] = UNICODE_LITERAL_4(p,o,r,t);
+ static const XMLCh sslport[] = UNICODE_LITERAL_7(s,s,l,p,o,r,t);
+ static const XMLCh scheme[] = UNICODE_LITERAL_6(s,c,h,e,m,e);
+ static const XMLCh id[] = UNICODE_LITERAL_2(i,d);
+ static const XMLCh Alias[] = UNICODE_LITERAL_5(A,l,i,a,s);
+ static const XMLCh Site[] = UNICODE_LITERAL_4(S,i,t,e);
+
+ struct site_t {
+ site_t(const DOMElement* e)
+ {
+ auto_ptr_char n(e->getAttributeNS(NULL,name));
+ auto_ptr_char s(e->getAttributeNS(NULL,scheme));
+ auto_ptr_char p(e->getAttributeNS(NULL,port));
+ auto_ptr_char p2(e->getAttributeNS(NULL,sslport));
+ if (n.get()) m_name=n.get();
+ if (s.get()) m_scheme=s.get();
+ if (p.get()) m_port=p.get();
+ if (p2.get()) m_sslport=p2.get();
+ e = XMLHelper::getFirstChildElement(e, Alias);
+ while (e) {
+ if (e->hasChildNodes()) {
+ auto_ptr_char alias(e->getFirstChild()->getNodeValue());
+ m_aliases.insert(alias.get());
+ }
+ e = XMLHelper::getNextSiblingElement(e, Alias);
+ }
+ }
+ string m_scheme,m_port,m_sslport,m_name;
+ set<string> m_aliases;
+ };
+
+ HINSTANCE g_hinstDLL;
+ SPConfig* g_Config = NULL;
+ map<string,site_t> g_Sites;
+ bool g_bNormalizeRequest = true;
+ string g_unsetHeaderValue,g_spoofKey;
+ bool g_checkSpoofing = true;
+ bool g_catchAll = false;
+ bool g_bSafeHeaderNames = false;
+ vector<string> g_NoCerts;
+}
+
+BOOL LogEvent(
+ LPCSTR lpUNCServerName,
+ WORD wType,
+ DWORD dwEventID,
+ PSID lpUserSid,
+ LPCSTR message)
+{
+ LPCSTR messages[] = {message, NULL};
+
+ HANDLE hElog = RegisterEventSource(lpUNCServerName, "Shibboleth ISAPI Filter");
+ BOOL res = ReportEvent(hElog, wType, 0, dwEventID, lpUserSid, 1, 0, messages, NULL);
+ return (DeregisterEventSource(hElog) && res);
+}
+
+void _my_invalid_parameter_handler(
+ const wchar_t * expression,
+ const wchar_t * function,
+ const wchar_t * file,
+ unsigned int line,
+ uintptr_t pReserved
+ )
+{
+ return;
+}
+
+extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID)
+{
+ if (fdwReason==DLL_PROCESS_ATTACH)
+ g_hinstDLL=hinstDLL;
+ return TRUE;
+}
+
+extern "C" BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO* pVer)
+{
+ if (!pVer)
+ return FALSE;
+
+ if (!g_Config) {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Extension mode startup not possible, is the DLL loaded as a filter?");
+ return FALSE;
+ }
+
+ pVer->dwExtensionVersion=HSE_VERSION;
+ strncpy(pVer->lpszExtensionDesc,"Shibboleth ISAPI Extension",HSE_MAX_EXT_DLL_NAME_LEN-1);
+ return TRUE;
+}
+
+extern "C" BOOL WINAPI TerminateExtension(DWORD)
+{
+ return TRUE; // cleanup should happen when filter unloads
+}
+
+extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
+{
+ if (!pVer)
+ return FALSE;
+ else if (g_Config) {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Reentrant filter initialization, ignoring...");
+ return TRUE;
+ }
+
+ g_Config=&SPConfig::getConfig();
+ g_Config->setFeatures(
+ SPConfig::Listener |
+ SPConfig::Caching |
+ SPConfig::RequestMapping |
+ SPConfig::InProcess |
+ SPConfig::Logging |
+ SPConfig::Handlers
+ );
+ if (!g_Config->init()) {
+ g_Config=NULL;
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Filter startup failed during library initialization, check native log for help.");
+ return FALSE;
+ }
+
+ try {
+ if (!g_Config->instantiate(NULL, true))
+ throw runtime_error("unknown error");
+ }
+ catch (exception& ex) {
+ g_Config->term();
+ g_Config=NULL;
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, ex.what());
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Filter startup failed to load configuration, check native log for details.");
+ return FALSE;
+ }
+
+ // Access implementation-specifics and site mappings.
+ ServiceProvider* sp=g_Config->getServiceProvider();
+ Locker locker(sp);
+ const PropertySet* props=sp->getPropertySet("InProcess");
+ if (props) {
+ pair<bool,bool> flag=props->getBool("checkSpoofing");
+ g_checkSpoofing = !flag.first || flag.second;
+ flag=props->getBool("catchAll");
+ g_catchAll = flag.first && flag.second;
+
+ pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
+ if (unsetValue.first)
+ g_unsetHeaderValue = unsetValue.second;
+ if (g_checkSpoofing) {
+ unsetValue = props->getString("spoofKey");
+ if (unsetValue.first)
+ g_spoofKey = unsetValue.second;
+ else {
+ _invalid_parameter_handler old = _set_invalid_parameter_handler(_my_invalid_parameter_handler);
+ unsigned int randkey=0,randkey2=0,randkey3=0,randkey4=0;
+ if (rand_s(&randkey) == 0 && rand_s(&randkey2) == 0 && rand_s(&randkey3) == 0 && rand_s(&randkey4) == 0) {
+ _set_invalid_parameter_handler(old);
+ ostringstream keystr;
+ keystr << randkey << randkey2 << randkey3 << randkey4;
+ g_spoofKey = keystr.str();
+ }
+ else {
+ _set_invalid_parameter_handler(old);
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Filter failed to generate a random anti-spoofing key (if this is Windows 2000 set one manually).");
+ locker.assign(); // pops lock on SP config
+ g_Config->term();
+ g_Config=NULL;
+ return FALSE;
+ }
+ }
+ }
+
+ props = props->getPropertySet("ISAPI");
+ if (props) {
+ flag = props->getBool("normalizeRequest");
+ g_bNormalizeRequest = !flag.first || flag.second;
+ flag = props->getBool("safeHeaderNames");
+ g_bSafeHeaderNames = flag.first && flag.second;
+ const DOMElement* child = XMLHelper::getFirstChildElement(props->getElement(),Site);
+ while (child) {
+ auto_ptr_char id(child->getAttributeNS(NULL,id));
+ if (id.get())
+ g_Sites.insert(pair<string,site_t>(id.get(),site_t(child)));
+ child=XMLHelper::getNextSiblingElement(child,Site);
+ }
+ }
+ }
+
+ pVer->dwFilterVersion=HTTP_FILTER_REVISION;
+ strncpy(pVer->lpszFilterDesc,"Shibboleth ISAPI Filter",SF_MAX_FILTER_DESC_LEN);
+ pVer->dwFlags=(SF_NOTIFY_ORDER_HIGH |
+ SF_NOTIFY_SECURE_PORT |
+ SF_NOTIFY_NONSECURE_PORT |
+ SF_NOTIFY_PREPROC_HEADERS |
+ SF_NOTIFY_LOG);
+ LogEvent(NULL, EVENTLOG_INFORMATION_TYPE, 7701, NULL, "Filter initialized...");
+ return TRUE;
+}
+
+extern "C" BOOL WINAPI TerminateFilter(DWORD)
+{
+ if (g_Config)
+ g_Config->term();
+ g_Config = NULL;
+ LogEvent(NULL, EVENTLOG_INFORMATION_TYPE, 7701, NULL, "Filter shut down...");
+ return TRUE;
+}
+
+/* Next up, some suck-free versions of various APIs.
+
+ You DON'T require people to guess the buffer size and THEN tell them the right size.
+ Returning an LPCSTR is apparently way beyond their ken. Not to mention the fact that
+ constant strings aren't typed as such, making it just that much harder. These versions
+ are now updated to use a special growable buffer object, modeled after the standard
+ string class. The standard string won't work because they left out the option to
+ pre-allocate a non-constant buffer.
+*/
+
+class dynabuf
+{
+public:
+ dynabuf() { bufptr=NULL; buflen=0; }
+ dynabuf(size_t s) { bufptr=new char[buflen=s]; *bufptr=0; }
+ ~dynabuf() { delete[] bufptr; }
+ size_t length() const { return bufptr ? strlen(bufptr) : 0; }
+ size_t size() const { return buflen; }
+ bool empty() const { return length()==0; }
+ void reserve(size_t s, bool keep=false);
+ void erase() { if (bufptr) memset(bufptr,0,buflen); }
+ operator char*() { return bufptr; }
+ bool operator ==(const char* s) const;
+ bool operator !=(const char* s) const { return !(*this==s); }
+private:
+ char* bufptr;
+ size_t buflen;
+};
+
+void dynabuf::reserve(size_t s, bool keep)
+{
+ if (s<=buflen)
+ return;
+ char* p=new char[s];
+ if (keep)
+ while (buflen--)
+ p[buflen]=bufptr[buflen];
+ buflen=s;
+ delete[] bufptr;
+ bufptr=p;
+}
+
+bool dynabuf::operator==(const char* s) const
+{
+ if (buflen==NULL || s==NULL)
+ return (buflen==NULL && s==NULL);
+ else
+ return strcmp(bufptr,s)==0;
+}
+
+void GetServerVariable(PHTTP_FILTER_CONTEXT pfc, LPSTR lpszVariable, dynabuf& s, DWORD size=80, bool bRequired=true)
+{
+ s.reserve(size);
+ s.erase();
+ size=s.size();
+
+ while (!pfc->GetServerVariable(pfc,lpszVariable,s,&size)) {
+ // Grumble. Check the error.
+ DWORD e=GetLastError();
+ if (e==ERROR_INSUFFICIENT_BUFFER)
+ s.reserve(size);
+ else
+ break;
+ }
+ if (bRequired && s.empty())
+ throw ERROR_NO_DATA;
+}
+
+void GetServerVariable(LPEXTENSION_CONTROL_BLOCK lpECB, LPSTR lpszVariable, dynabuf& s, DWORD size=80, bool bRequired=true)
+{
+ s.reserve(size);
+ s.erase();
+ size=s.size();
+
+ while (!lpECB->GetServerVariable(lpECB->ConnID,lpszVariable,s,&size)) {
+ // Grumble. Check the error.
+ DWORD e=GetLastError();
+ if (e==ERROR_INSUFFICIENT_BUFFER)
+ s.reserve(size);
+ else
+ break;
+ }
+ if (bRequired && s.empty())
+ throw ERROR_NO_DATA;
+}
+
+void GetHeader(PHTTP_FILTER_PREPROC_HEADERS pn, PHTTP_FILTER_CONTEXT pfc,
+ LPSTR lpszName, dynabuf& s, DWORD size=80, bool bRequired=true)
+{
+ s.reserve(size);
+ s.erase();
+ size=s.size();
+
+ while (!pn->GetHeader(pfc,lpszName,s,&size)) {
+ // Grumble. Check the error.
+ DWORD e=GetLastError();
+ if (e==ERROR_INSUFFICIENT_BUFFER)
+ s.reserve(size);
+ else
+ break;
+ }
+ if (bRequired && s.empty())
+ throw ERROR_NO_DATA;
+}
+
+/****************************************************************************/
+// ISAPI Filter
+
+class ShibTargetIsapiF : public AbstractSPRequest
+{
+ PHTTP_FILTER_CONTEXT m_pfc;
+ PHTTP_FILTER_PREPROC_HEADERS m_pn;
+ multimap<string,string> m_headers;
+ int m_port;
+ string m_scheme,m_hostname;
+ mutable string m_remote_addr,m_content_type,m_method;
+ dynabuf m_allhttp;
+ bool m_firsttime;
+
+public:
+ ShibTargetIsapiF(PHTTP_FILTER_CONTEXT pfc, PHTTP_FILTER_PREPROC_HEADERS pn, const site_t& site)
+ : AbstractSPRequest(SHIBSP_LOGCAT".ISAPI"), m_pfc(pfc), m_pn(pn), m_allhttp(4096), m_firsttime(true) {
+
+ // URL path always come from IIS.
+ dynabuf var(256);
+ GetHeader(pn,pfc,"url",var,256,false);
+ setRequestURI(var);
+
+ // Port may come from IIS or from site def.
+ if (!g_bNormalizeRequest || (pfc->fIsSecurePort && site.m_sslport.empty()) || (!pfc->fIsSecurePort && site.m_port.empty())) {
+ GetServerVariable(pfc,"SERVER_PORT",var,10);
+ m_port = atoi(var);
+ }
+ else if (pfc->fIsSecurePort) {
+ m_port = atoi(site.m_sslport.c_str());
+ }
+ else {
+ m_port = atoi(site.m_port.c_str());
+ }
+
+ // Scheme may come from site def or be derived from IIS.
+ m_scheme=site.m_scheme;
+ if (m_scheme.empty() || !g_bNormalizeRequest)
+ m_scheme=pfc->fIsSecurePort ? "https" : "http";
+
+ GetServerVariable(pfc,"SERVER_NAME",var,32);
+
+ // Make sure SERVER_NAME is "authorized" for use on this site. If not, set to canonical name.
+ m_hostname = var;
+ if (site.m_name!=m_hostname && site.m_aliases.find(m_hostname)==site.m_aliases.end())
+ m_hostname=site.m_name;
+
+ if (!g_spoofKey.empty()) {
+ GetHeader(pn, pfc, "ShibSpoofCheck:", var, 32, false);
+ if (!var.empty() && g_spoofKey == (char*)var)
+ m_firsttime = false;
+ }
+
+ if (!m_firsttime)
+ log(SPDebug, "ISAPI filter running more than once");
+ }
+ ~ShibTargetIsapiF() { }
+
+ const char* getScheme() const {
+ return m_scheme.c_str();
+ }
+ const char* getHostname() const {
+ return m_hostname.c_str();
+ }
+ int getPort() const {
+ return m_port;
+ }
+ const char* getQueryString() const {
+ const char* uri = getRequestURI();
+ uri = (uri ? strchr(uri, '?') : NULL);
+ return uri ? (uri + 1) : NULL;
+ }
+ const char* getMethod() const {
+ if (m_method.empty()) {
+ dynabuf var(5);
+ GetServerVariable(m_pfc,"HTTP_METHOD",var,5,false);
+ if (!var.empty())
+ m_method = var;
+ }
+ return m_method.c_str();
+ }
+ string getContentType() const {
+ if (m_content_type.empty()) {
+ dynabuf var(32);
+ GetServerVariable(m_pfc,"HTTP_CONTENT_TYPE",var,32,false);
+ if (!var.empty())
+ m_content_type = var;
+ }
+ return m_content_type;
+ }
+ string getRemoteAddr() const {
+ m_remote_addr = AbstractSPRequest::getRemoteAddr();
+ if (m_remote_addr.empty()) {
+ dynabuf var(16);
+ GetServerVariable(m_pfc,"REMOTE_ADDR",var,16,false);
+ if (!var.empty())
+ m_remote_addr = var;
+ }
+ return m_remote_addr;
+ }
+ void log(SPLogLevel level, const string& msg) {
+ AbstractSPRequest::log(level,msg);
+ if (level >= SPCrit)
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg.c_str());
+ }
+ string makeSafeHeader(const char* rawname) const {
+ string hdr;
+ for (; *rawname; ++rawname) {
+ if (isalnum(*rawname))
+ hdr += *rawname;
+ }
+ return (hdr + ':');
+ }
+ void clearHeader(const char* rawname, const char* cginame) {
+ if (g_checkSpoofing && m_firsttime) {
+ if (m_allhttp.empty())
+ GetServerVariable(m_pfc, "ALL_HTTP", m_allhttp, 4096);
+ string hdr = g_bSafeHeaderNames ? ("HTTP_" + makeSafeHeader(cginame + 5)) : (string(cginame) + ':');
+ if (strstr(m_allhttp, hdr.c_str()))
+ throw opensaml::SecurityPolicyException("Attempt to spoof header ($1) was detected.", params(1, hdr.c_str()));
+ }
+ if (g_bSafeHeaderNames) {
+ string hdr = makeSafeHeader(rawname);
+ m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(g_unsetHeaderValue.c_str()));
+ }
+ else if (!strcmp(rawname,"REMOTE_USER")) {
+ m_pn->SetHeader(m_pfc, "remote-user:", const_cast<char*>(g_unsetHeaderValue.c_str()));
+ m_pn->SetHeader(m_pfc, "remote_user:", const_cast<char*>(g_unsetHeaderValue.c_str()));
+ }
+ else {
+ string hdr = string(rawname) + ':';
+ m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(g_unsetHeaderValue.c_str()));
+ }
+ }
+ void setHeader(const char* name, const char* value) {
+ string hdr = g_bSafeHeaderNames ? makeSafeHeader(name) : (string(name) + ':');
+ m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(value));
+ }
+ string getSecureHeader(const char* name) const {
+ string hdr = g_bSafeHeaderNames ? makeSafeHeader(name) : (string(name) + ':');
+ dynabuf buf(256);
+ GetHeader(m_pn, m_pfc, const_cast<char*>(hdr.c_str()), buf, 256, false);
+ return string(buf.empty() ? "" : buf);
+ }
+ string getHeader(const char* name) const {
+ string hdr(name);
+ hdr += ':';
+ dynabuf buf(256);
+ GetHeader(m_pn, m_pfc, const_cast<char*>(hdr.c_str()), buf, 256, false);
+ return string(buf.empty() ? "" : buf);
+ }
+ void setRemoteUser(const char* user) {
+ setHeader("remote-user", user);
+ if (!user || !*user)
+ m_pfc->pFilterContext = NULL;
+ else if (m_pfc->pFilterContext = m_pfc->AllocMem(m_pfc, sizeof(char) * (strlen(user) + 1), NULL))
+ strcpy(reinterpret_cast<char*>(m_pfc->pFilterContext), user);
+ }
+ string getRemoteUser() const {
+ return getSecureHeader("remote-user");
+ }
+ void setResponseHeader(const char* name, const char* value) {
+ // Set for later.
+ if (value)
+ m_headers.insert(make_pair(name,value));
+ else
+ m_headers.erase(name);
+ }
+ long sendResponse(istream& in, long status) {
+ string hdr = string("Connection: close\r\n");
+ for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+ hdr += i->first + ": " + i->second + "\r\n";
+ hdr += "\r\n";
+ const char* codestr="200 OK";
+ switch (status) {
+ case XMLTOOLING_HTTP_STATUS_UNAUTHORIZED: codestr="401 Authorization Required"; break;
+ case XMLTOOLING_HTTP_STATUS_FORBIDDEN: codestr="403 Forbidden"; break;
+ case XMLTOOLING_HTTP_STATUS_NOTFOUND: codestr="404 Not Found"; break;
+ case XMLTOOLING_HTTP_STATUS_ERROR: codestr="500 Server Error"; break;
+ }
+ m_pfc->ServerSupportFunction(m_pfc, SF_REQ_SEND_RESPONSE_HEADER, (void*)codestr, (DWORD)hdr.c_str(), 0);
+ char buf[1024];
+ while (in) {
+ in.read(buf,1024);
+ DWORD resplen = in.gcount();
+ m_pfc->WriteClient(m_pfc, buf, &resplen, 0);
+ }
+ return SF_STATUS_REQ_FINISHED;
+ }
+ long sendRedirect(const char* url) {
+ // XXX: Don't support the httpRedirect option, yet.
+ string hdr=string("Location: ") + url + "\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 40\r\n"
+ "Expires: 01-Jan-1997 12:00:00 GMT\r\n"
+ "Cache-Control: private,no-store,no-cache\r\n";
+ for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+ hdr += i->first + ": " + i->second + "\r\n";
+ hdr += "\r\n";
+ m_pfc->ServerSupportFunction(m_pfc, SF_REQ_SEND_RESPONSE_HEADER, "302 Please Wait", (DWORD)hdr.c_str(), 0);
+ static const char* redmsg="<HTML><BODY>Redirecting...</BODY></HTML>";
+ DWORD resplen=40;
+ m_pfc->WriteClient(m_pfc, (LPVOID)redmsg, &resplen, 0);
+ return SF_STATUS_REQ_FINISHED;
+ }
+ long returnDecline() {
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+ }
+ long returnOK() {
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+ }
+
+ const vector<string>& getClientCertificates() const {
+ return g_NoCerts;
+ }
+
+ // The filter never processes the POST, so stub these methods.
+ long getContentLength() const { throw IOException("The request's Content-Length is not available to an ISAPI filter."); }
+ const char* getRequestBody() const { throw IOException("The request body is not available to an ISAPI filter."); }
+};
+
+DWORD WriteClientError(PHTTP_FILTER_CONTEXT pfc, const char* msg)
+{
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg);
+ static const char* ctype="Connection: close\r\nContent-Type: text/html\r\n\r\n";
+ pfc->ServerSupportFunction(pfc,SF_REQ_SEND_RESPONSE_HEADER,"200 OK",(DWORD)ctype,0);
+ static const char* xmsg="<HTML><HEAD><TITLE>Shibboleth Filter Error</TITLE></HEAD><BODY>"
+ "<H1>Shibboleth Filter Error</H1>";
+ DWORD resplen=strlen(xmsg);
+ pfc->WriteClient(pfc,(LPVOID)xmsg,&resplen,0);
+ resplen=strlen(msg);
+ pfc->WriteClient(pfc,(LPVOID)msg,&resplen,0);
+ static const char* xmsg2="</BODY></HTML>";
+ resplen=strlen(xmsg2);
+ pfc->WriteClient(pfc,(LPVOID)xmsg2,&resplen,0);
+ return SF_STATUS_REQ_FINISHED;
+}
+
+extern "C" DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificationType, LPVOID pvNotification)
+{
+ // Is this a log notification?
+ if (notificationType==SF_NOTIFY_LOG) {
+ if (pfc->pFilterContext)
+ ((PHTTP_FILTER_LOG)pvNotification)->pszClientUserName=reinterpret_cast<char*>(pfc->pFilterContext);
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+ }
+
+ PHTTP_FILTER_PREPROC_HEADERS pn=(PHTTP_FILTER_PREPROC_HEADERS)pvNotification;
+ try
+ {
+ // Determine web site number. This can't really fail, I don't think.
+ dynabuf buf(128);
+ GetServerVariable(pfc,"INSTANCE_ID",buf,10);
+
+ // Match site instance to host name, skip if no match.
+ map<string,site_t>::const_iterator map_i=g_Sites.find(static_cast<char*>(buf));
+ if (map_i==g_Sites.end())
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+
+ ostringstream threadid;
+ threadid << "[" << getpid() << "] isapi_shib" << '\0';
+ xmltooling::NDC ndc(threadid.str().c_str());
+
+ ShibTargetIsapiF stf(pfc, pn, map_i->second);
+
+ // "false" because we don't override the Shib settings
+ pair<bool,long> res = stf.getServiceProvider().doAuthentication(stf);
+ if (!g_spoofKey.empty())
+ pn->SetHeader(pfc, "ShibSpoofCheck:", const_cast<char*>(g_spoofKey.c_str()));
+ if (res.first) return res.second;
+
+ // "false" because we don't override the Shib settings
+ res = stf.getServiceProvider().doExport(stf);
+ if (res.first) return res.second;
+
+ res = stf.getServiceProvider().doAuthorization(stf);
+ if (res.first) return res.second;
+
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+ }
+ catch(bad_alloc) {
+ return WriteClientError(pfc,"Out of Memory");
+ }
+ catch(long e) {
+ if (e==ERROR_NO_DATA)
+ return WriteClientError(pfc,"A required variable or header was empty.");
+ else
+ return WriteClientError(pfc,"Shibboleth Filter detected unexpected IIS error.");
+ }
+ catch (exception& e) {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, e.what());
+ return WriteClientError(pfc,"Shibboleth Filter caught an exception, check Event Log for details.");
+ }
+ catch(...) {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, "Shibboleth Filter threw an unknown exception.");
+ if (g_catchAll)
+ return WriteClientError(pfc,"Shibboleth Filter threw an unknown exception.");
+ throw;
+ }
+
+ return WriteClientError(pfc,"Shibboleth Filter reached unreachable code, save my walrus!");
+}
+
+
+/****************************************************************************/
+// ISAPI Extension
+
+DWORD WriteClientError(LPEXTENSION_CONTROL_BLOCK lpECB, const char* msg)
+{
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg);
+ static const char* ctype="Connection: close\r\nContent-Type: text/html\r\n\r\n";
+ lpECB->ServerSupportFunction(lpECB->ConnID,HSE_REQ_SEND_RESPONSE_HEADER,"200 OK",0,(LPDWORD)ctype);
+ static const char* xmsg="<HTML><HEAD><TITLE>Shibboleth Error</TITLE></HEAD><BODY><H1>Shibboleth Error</H1>";
+ DWORD resplen=strlen(xmsg);
+ lpECB->WriteClient(lpECB->ConnID,(LPVOID)xmsg,&resplen,HSE_IO_SYNC);
+ resplen=strlen(msg);
+ lpECB->WriteClient(lpECB->ConnID,(LPVOID)msg,&resplen,HSE_IO_SYNC);
+ static const char* xmsg2="</BODY></HTML>";
+ resplen=strlen(xmsg2);
+ lpECB->WriteClient(lpECB->ConnID,(LPVOID)xmsg2,&resplen,HSE_IO_SYNC);
+ return HSE_STATUS_SUCCESS;
+}
+
+
+class ShibTargetIsapiE : public AbstractSPRequest
+{
+ LPEXTENSION_CONTROL_BLOCK m_lpECB;
+ multimap<string,string> m_headers;
+ mutable vector<string> m_certs;
+ mutable string m_body;
+ mutable bool m_gotBody;
+ int m_port;
+ string m_scheme,m_hostname,m_uri;
+ mutable string m_remote_addr,m_remote_user;
+
+public:
+ ShibTargetIsapiE(LPEXTENSION_CONTROL_BLOCK lpECB, const site_t& site)
+ : AbstractSPRequest(SHIBSP_LOGCAT".ISAPI"), m_lpECB(lpECB), m_gotBody(false) {
+ dynabuf ssl(5);
+ GetServerVariable(lpECB,"HTTPS",ssl,5);
+ bool SSL=(ssl=="on" || ssl=="ON");
+
+ // Scheme may come from site def or be derived from IIS.
+ m_scheme=site.m_scheme;
+ if (m_scheme.empty() || !g_bNormalizeRequest)
+ m_scheme = SSL ? "https" : "http";
+
+ // URL path always come from IIS.
+ dynabuf url(256);
+ GetServerVariable(lpECB,"URL",url,255);
+
+ // Port may come from IIS or from site def.
+ dynabuf port(11);
+ if (!g_bNormalizeRequest || (SSL && site.m_sslport.empty()) || (!SSL && site.m_port.empty()))
+ GetServerVariable(lpECB,"SERVER_PORT",port,10);
+ else if (SSL) {
+ strncpy(port,site.m_sslport.c_str(),10);
+ static_cast<char*>(port)[10]=0;
+ }
+ else {
+ strncpy(port,site.m_port.c_str(),10);
+ static_cast<char*>(port)[10]=0;
+ }
+ m_port = atoi(port);
+
+ dynabuf var(32);
+ GetServerVariable(lpECB, "SERVER_NAME", var, 32);
+
+ // Make sure SERVER_NAME is "authorized" for use on this site. If not, set to canonical name.
+ m_hostname=var;
+ if (site.m_name!=m_hostname && site.m_aliases.find(m_hostname)==site.m_aliases.end())
+ m_hostname=site.m_name;
+
+ /*
+ * IIS screws us over on PATH_INFO (the hits keep on coming). We need to figure out if
+ * the server is set up for proper PATH_INFO handling, or "IIS sucks rabid weasels mode",
+ * which is the default. No perfect way to tell, but we can take a good guess by checking
+ * whether the URL is a substring of the PATH_INFO:
+ *
+ * e.g. for /Shibboleth.sso/SAML/POST
+ *
+ * Bad mode (default):
+ * URL: /Shibboleth.sso
+ * PathInfo: /Shibboleth.sso/SAML/POST
+ *
+ * Good mode:
+ * URL: /Shibboleth.sso
+ * PathInfo: /SAML/POST
+ */
+
+ string uri;
+
+ // Clearly we're only in bad mode if path info exists at all.
+ if (lpECB->lpszPathInfo && *(lpECB->lpszPathInfo)) {
+ if (strstr(lpECB->lpszPathInfo,url))
+ // Pretty good chance we're in bad mode, unless the PathInfo repeats the path itself.
+ uri = lpECB->lpszPathInfo;
+ else {
+ uri = url;
+ uri += lpECB->lpszPathInfo;
+ }
+ }
+ else {
+ uri = url;
+ }
+
+ // For consistency with Apache, let's add the query string.
+ if (lpECB->lpszQueryString && *(lpECB->lpszQueryString)) {
+ uri += '?';
+ uri += lpECB->lpszQueryString;
+ }
+
+ setRequestURI(uri.c_str());
+ }
+ ~ShibTargetIsapiE() { }
+
+ const char* getScheme() const {
+ return m_scheme.c_str();
+ }
+ const char* getHostname() const {
+ return m_hostname.c_str();
+ }
+ int getPort() const {
+ return m_port;
+ }
+ const char* getMethod() const {
+ return m_lpECB->lpszMethod;
+ }
+ string getContentType() const {
+ return m_lpECB->lpszContentType ? m_lpECB->lpszContentType : "";
+ }
+ long getContentLength() const {
+ return m_lpECB->cbTotalBytes;
+ }
+ string getRemoteUser() const {
+ if (m_remote_user.empty()) {
+ dynabuf var(16);
+ GetServerVariable(m_lpECB, "REMOTE_USER", var, 32, false);
+ if (!var.empty())
+ m_remote_user = var;
+ }
+ return m_remote_user;
+ }
+ string getRemoteAddr() const {
+ m_remote_addr = AbstractSPRequest::getRemoteAddr();
+ if (m_remote_addr.empty()) {
+ dynabuf var(16);
+ GetServerVariable(m_lpECB, "REMOTE_ADDR", var, 16, false);
+ if (!var.empty())
+ m_remote_addr = var;
+ }
+ return m_remote_addr;
+ }
+ void log(SPLogLevel level, const string& msg) const {
+ AbstractSPRequest::log(level,msg);
+ if (level >= SPCrit)
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg.c_str());
+ }
+ string getHeader(const char* name) const {
+ string hdr("HTTP_");
+ for (; *name; ++name) {
+ if (*name=='-')
+ hdr += '_';
+ else
+ hdr += toupper(*name);
+ }
+ dynabuf buf(128);
+ GetServerVariable(m_lpECB, const_cast<char*>(hdr.c_str()), buf, 128, false);
+ return buf.empty() ? "" : buf;
+ }
+ void setResponseHeader(const char* name, const char* value) {
+ // Set for later.
+ if (value)
+ m_headers.insert(make_pair(name,value));
+ else
+ m_headers.erase(name);
+ }
+ const char* getQueryString() const {
+ return m_lpECB->lpszQueryString;
+ }
+ const char* getRequestBody() const {
+ if (m_gotBody)
+ return m_body.c_str();
+ if (m_lpECB->cbTotalBytes > 1024*1024) // 1MB?
+ throw opensaml::SecurityPolicyException("Size of request body exceeded 1M size limit.");
+ else if (m_lpECB->cbTotalBytes > m_lpECB->cbAvailable) {
+ m_gotBody=true;
+ DWORD datalen=m_lpECB->cbTotalBytes;
+ if (m_lpECB->cbAvailable > 0) {
+ m_body.assign(reinterpret_cast<char*>(m_lpECB->lpbData),m_lpECB->cbAvailable);
+ datalen-=m_lpECB->cbAvailable;
+ }
+ char buf[8192];
+ while (datalen) {
+ DWORD buflen=8192;
+ BOOL ret = m_lpECB->ReadClient(m_lpECB->ConnID, buf, &buflen);
+ if (!ret)
+ throw IOException("Error reading request body from browser.");
+ else if (!buflen)
+ throw IOException("Socket closed while reading request body from browser.");
+ m_body.append(buf, buflen);
+ datalen-=buflen;
+ }
+ }
+ else if (m_lpECB->cbAvailable) {
+ m_gotBody=true;
+ m_body.assign(reinterpret_cast<char*>(m_lpECB->lpbData),m_lpECB->cbAvailable);
+ }
+ return m_body.c_str();
+ }
+ long sendResponse(istream& in, long status) {
+ string hdr = string("Connection: close\r\n");
+ for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+ hdr += i->first + ": " + i->second + "\r\n";
+ hdr += "\r\n";
+ const char* codestr="200 OK";
+ switch (status) {
+ case XMLTOOLING_HTTP_STATUS_UNAUTHORIZED: codestr="401 Authorization Required"; break;
+ case XMLTOOLING_HTTP_STATUS_FORBIDDEN: codestr="403 Forbidden"; break;
+ case XMLTOOLING_HTTP_STATUS_NOTFOUND: codestr="404 Not Found"; break;
+ case XMLTOOLING_HTTP_STATUS_ERROR: codestr="500 Server Error"; break;
+ }
+ m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, (void*)codestr, 0, (LPDWORD)hdr.c_str());
+ char buf[1024];
+ while (in) {
+ in.read(buf,1024);
+ DWORD resplen = in.gcount();
+ m_lpECB->WriteClient(m_lpECB->ConnID, buf, &resplen, HSE_IO_SYNC);
+ }
+ return HSE_STATUS_SUCCESS;
+ }
+ long sendRedirect(const char* url) {
+ string hdr=string("Location: ") + url + "\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 40\r\n"
+ "Expires: 01-Jan-1997 12:00:00 GMT\r\n"
+ "Cache-Control: private,no-store,no-cache\r\n";
+ for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+ hdr += i->first + ": " + i->second + "\r\n";
+ hdr += "\r\n";
+ m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, "302 Moved", 0, (LPDWORD)hdr.c_str());
+ static const char* redmsg="<HTML><BODY>Redirecting...</BODY></HTML>";
+ DWORD resplen=40;
+ m_lpECB->WriteClient(m_lpECB->ConnID, (LPVOID)redmsg, &resplen, HSE_IO_SYNC);
+ return HSE_STATUS_SUCCESS;
+ }
+ // Decline happens in the POST processor if this isn't the shire url
+ // Note that it can also happen with HTAccess, but we don't support that, yet.
+ long returnDecline() {
+ return WriteClientError(
+ m_lpECB,
+ "ISAPI extension can only be invoked to process Shibboleth protocol requests."
+ "Make sure the mapped file extension doesn't match actual content."
+ );
+ }
+ long returnOK() {
+ return HSE_STATUS_SUCCESS;
+ }
+
+ const vector<string>& getClientCertificates() const {
+ if (m_certs.empty()) {
+ char CertificateBuf[8192];
+ CERT_CONTEXT_EX ccex;
+ ccex.cbAllocated = sizeof(CertificateBuf);
+ ccex.CertContext.pbCertEncoded = (BYTE*)CertificateBuf;
+ DWORD dwSize = sizeof(ccex);
+
+ if (m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_GET_CERT_INFO_EX, (LPVOID)&ccex, (LPDWORD)dwSize, NULL)) {
+ if (ccex.CertContext.cbCertEncoded) {
+ xsecsize_t outlen;
+ XMLByte* serialized = Base64::encode(reinterpret_cast<XMLByte*>(CertificateBuf), ccex.CertContext.cbCertEncoded, &outlen);
+ m_certs.push_back(reinterpret_cast<char*>(serialized));
+#ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE
+ XMLString::release(&serialized);
+#else
+ XMLString::release((char**)&serialized);
+#endif
+ }
+ }
+ }
+ return m_certs;
+ }
+
+ // Not used in the extension.
+ void clearHeader(const char* rawname, const char* cginame) { throw runtime_error("clearHeader not implemented"); }
+ void setHeader(const char* name, const char* value) { throw runtime_error("setHeader not implemented"); }
+ void setRemoteUser(const char* user) { throw runtime_error("setRemoteUser not implemented"); }
+};
+
+extern "C" DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB)
+{
+ try {
+ ostringstream threadid;
+ threadid << "[" << getpid() << "] isapi_shib_extension" << '\0';
+ xmltooling::NDC ndc(threadid.str().c_str());
+
+ // Determine web site number. This can't really fail, I don't think.
+ dynabuf buf(128);
+ GetServerVariable(lpECB,"INSTANCE_ID",buf,10);
+
+ // Match site instance to host name, skip if no match.
+ map<string,site_t>::const_iterator map_i=g_Sites.find(static_cast<char*>(buf));
+ if (map_i==g_Sites.end())
+ return WriteClientError(lpECB, "Shibboleth Extension not configured for web site (check <ISAPI> mappings in configuration).");
+
+ ShibTargetIsapiE ste(lpECB, map_i->second);
+ pair<bool,long> res = ste.getServiceProvider().doHandler(ste);
+ if (res.first) return res.second;
+
+ return WriteClientError(lpECB, "Shibboleth Extension failed to process request");
+
+ }
+ catch(bad_alloc) {
+ return WriteClientError(lpECB,"Out of Memory");
+ }
+ catch(long e) {
+ if (e==ERROR_NO_DATA)
+ return WriteClientError(lpECB,"A required variable or header was empty.");
+ else
+ return WriteClientError(lpECB,"Server detected unexpected IIS error.");
+ }
+ catch (exception& e) {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, e.what());
+ return WriteClientError(lpECB,"Shibboleth Extension caught an exception, check Event Log for details.");
+ }
+ catch(...) {
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, "Shibboleth Extension threw an unknown exception.");
+ if (g_catchAll)
+ return WriteClientError(lpECB,"Shibboleth Extension threw an unknown exception.");
+ throw;
+ }
+
+ // If we get here we've got an error.
+ return HSE_STATUS_ERROR;
+}
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,0,0
- PRODUCTVERSION 2,1,0,0
+ FILEVERSION 2,2,1,0
+ PRODUCTVERSION 2,2,1,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
VALUE "Comments", "\0"
VALUE "CompanyName", "Internet2\0"
VALUE "FileDescription", "Shibboleth ISAPI Filter / Extension\0"
- VALUE "FileVersion", "2, 1, 0, 0\0"
+ VALUE "FileVersion", "2, 2, 1, 0\0"
VALUE "InternalName", "isapi_shib\0"
- VALUE "LegalCopyright", "Copyright © 2008 Internet2\0"
+ VALUE "LegalCopyright", "Copyright © 2009 Internet2\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "isapi_shib.dll\0"
VALUE "PrivateBuild", "\0"
- VALUE "ProductName", "Shibboleth 2.1\0"
- VALUE "ProductVersion", "2, 1, 0, 0\0"
+ VALUE "ProductName", "Shibboleth 2.2.1\0"
+ VALUE "ProductVersion", "2, 2, 1, 0\0"
VALUE "SpecialBuild", "\0"
END
END
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="9.00"
Name="isapi_shib"
ProjectGUID="{87C25D4E-8D19-4513-B0BA-BC668BC2DEE3}"
+ TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
<Tool
Name="VCLinkerTool"
AdditionalOptions="/export:GetExtensionVersion /export:GetFilterVersion /export:TerminateExtension /export:TerminateFilter /export:HttpFilterProc /export:HttpExtensionProc"
- AdditionalDependencies="xerces-c_2.lib xmltooling-lite1.lib"
+ AdditionalDependencies="xerces-c_3.lib xmltooling-lite1.lib"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)""
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
/>
<Tool
Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
+ PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
- TargetEnvironment="1"
- TypeLibraryName=".\Debug/isapi_shib.tlb"
+ TargetEnvironment="3"
+ TypeLibraryName=".\Release/isapi_shib.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="0"
+ Optimization="2"
+ InlineFunctionExpansion="1"
AdditionalIncludeDirectories=".;..;"..\..\cpp-xmltooling""
- PreprocessorDefinitions="_WINDOWS;WIN32;_DEBUG;WIN32_LEAN_AND_MEAN;_WIN32_WINNT=0x0400"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
+ PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;WIN32_LEAN_AND_MEAN;_WIN32_WINNT=0x0400"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
+ PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
<Tool
Name="VCLinkerTool"
AdditionalOptions="/export:GetExtensionVersion /export:GetFilterVersion /export:TerminateExtension /export:TerminateFilter /export:HttpFilterProc /export:HttpExtensionProc"
- AdditionalDependencies="xerces-c_2D.lib xmltooling-lite1D.lib"
- LinkIncremental="2"
+ AdditionalDependencies="xerces-c_3.lib xmltooling-lite1.lib"
+ LinkIncremental="1"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)""
- GenerateDebugInformation="true"
- TargetMachine="1"
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)""
+ ProgramDatabaseFile=".\Release/isapi_shib.pdb"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Release|x64"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
/>
<Tool
Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
+ PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
- TargetEnvironment="3"
- TypeLibraryName=".\Release/isapi_shib.tlb"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/isapi_shib.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
+ Optimization="0"
AdditionalIncludeDirectories=".;..;"..\..\cpp-xmltooling""
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;WIN32_LEAN_AND_MEAN;_WIN32_WINNT=0x0400"
- StringPooling="true"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
+ PreprocessorDefinitions="_WINDOWS;WIN32;_DEBUG;WIN32_LEAN_AND_MEAN;_WIN32_WINNT=0x0400"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
+ PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
<Tool
Name="VCLinkerTool"
AdditionalOptions="/export:GetExtensionVersion /export:GetFilterVersion /export:TerminateExtension /export:TerminateFilter /export:HttpFilterProc /export:HttpExtensionProc"
- AdditionalDependencies="xerces-c_2.lib xmltooling-lite1.lib"
- LinkIncremental="1"
+ AdditionalDependencies="xerces-c_3D.lib xmltooling-lite1D.lib"
+ LinkIncremental="2"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)""
- ProgramDatabaseFile=".\Release/isapi_shib.pdb"
- TargetMachine="17"
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)""
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/export:GetExtensionVersion /export:GetFilterVersion /export:TerminateExtension /export:TerminateFilter /export:HttpFilterProc /export:HttpExtensionProc"
- AdditionalDependencies="xerces-c_2D.lib xmltooling-lite1D.lib"
+ AdditionalDependencies="xerces-c_3D.lib xmltooling-lite1D.lib"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)""
GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
# include "config.h"\r
#endif\r
\r
+#ifdef WIN32\r
+# define _CRT_NONSTDC_NO_DEPRECATE 1\r
+# define _CRT_SECURE_NO_DEPRECATE 1\r
+# define MCEXT_EXPORTS __declspec(dllexport)\r
+#else\r
+# define MCEXT_EXPORTS\r
+#endif\r
+\r
+#include <xmltooling/base.h>\r
+\r
+#include <iostream> \r
+#include <libmemcached/memcached.h>\r
#include <xercesc/util/XMLUniDefs.hpp>\r
\r
#include <xmltooling/logging.h>\r
-\r
#include <xmltooling/XMLToolingConfig.h>\r
#include <xmltooling/util/NDC.h>\r
#include <xmltooling/util/StorageService.h>\r
#include <xmltooling/util/XMLHelper.h>\r
\r
-#include <libmemcached/memcached.h>\r
-\r
using namespace xmltooling::logging;\r
using namespace xmltooling;\r
using namespace xercesc;\r
memcached_st *memc;\r
string m_memcacheHosts;\r
string m_prefix;\r
- \r
+ Mutex* m_lock;\r
};\r
\r
class MemcacheStorageService : public StorageService, public MemcacheBase {\r
string set_val = "1";\r
unsigned tries = 5;\r
while (!addMemcache(lock_name.c_str(), set_val, 5, 0, use_prefix)) {\r
- if (tries-- < 0) {\r
+ if (tries-- == 0) {\r
log.debug("Unable to get lock %s... FAILED.", lock_name.c_str());\r
return false;\r
}\r
log.debug("Unable to get lock %s... Retrying.", lock_name.c_str());\r
\r
// sleep 100ms\r
+#ifdef WIN32\r
+ Sleep(100);\r
+#else\r
struct timeval tv = { 0, 100000 };\r
- select(0, 0, 0, 0, &tv); \r
+ select(0, 0, 0, 0, &tv);\r
+#endif\r
}\r
return true;\r
}\r
bool use_prefix) {\r
memcached_return rv;\r
string final_key;\r
- memcached_st clone;\r
bool success;\r
\r
if (use_prefix) {\r
final_key = key;\r
}\r
\r
- if (memcached_clone(&clone, memc) == NULL) {\r
- throw IOException("MemcacheBase::deleteMemcache(): memcached_clone() failed");\r
- }\r
+ m_lock->lock();\r
+ rv = memcached_delete(memc, (char *)final_key.c_str(), final_key.length(), timeout);\r
+ m_lock->unlock();\r
\r
- rv = memcached_delete(&clone, (char *)final_key.c_str(), final_key.length(), timeout);\r
if (rv == MEMCACHED_SUCCESS) {\r
success = true;\r
} else if (rv == MEMCACHED_NOTFOUND) {\r
// Key wasn't there... No biggie.\r
success = false;\r
+ } else if (rv == MEMCACHED_ERRNO) {\r
+ // System error\r
+ log.error(string("Memcache::deleteMemcache() SYSTEM ERROR: ") + string(strerror(memc->cached_errno)));\r
+ success = false;\r
} else {\r
- log.error(string("Memcache::deleteMemcache() Problems: ") + memcached_strerror(&clone, rv));\r
+ log.error(string("Memcache::deleteMemcache() Problems: ") + memcached_strerror(memc, rv));\r
// shouldn't be here\r
success = false;\r
}\r
\r
- memcached_free(&clone);\r
return success;\r
}\r
\r
size_t len;\r
char *result;\r
string final_key;\r
- memcached_st clone;\r
bool success;\r
\r
if (use_prefix) {\r
final_key = key;\r
}\r
\r
- if (memcached_clone(&clone, memc) == NULL) {\r
- throw IOException("MemcacheBase::getMemcache(): memcached_clone() failed");\r
- }\r
+ m_lock->lock();\r
+ result = memcached_get(memc, (char *)final_key.c_str(), final_key.length(), &len, flags, &rv);\r
+ m_lock->unlock();\r
\r
- result = memcached_get(&clone, (char *)final_key.c_str(), final_key.length(), &len, flags, &rv);\r
if (rv == MEMCACHED_SUCCESS) {\r
dest = result;\r
free(result);\r
} else if (rv == MEMCACHED_NOTFOUND) {\r
log.debug("Key %s not found in memcache...", key);\r
success = false;\r
+ } else if (rv == MEMCACHED_ERRNO) {\r
+ // System error\r
+ log.error(string("Memcache::getMemcache() SYSTEM ERROR: ") + string(strerror(memc->cached_errno)));\r
+ success = false;\r
} else {\r
- log.error(string("Memcache::getMemcache() Problems: ") + memcached_strerror(&clone, rv));\r
+ log.error(string("Memcache::getMemcache() Problems: ") + memcached_strerror(memc, rv));\r
success = false;\r
}\r
\r
- memcached_free(&clone);\r
return success;\r
}\r
\r
\r
memcached_return rv;\r
string final_key;\r
- memcached_st clone;\r
bool success;\r
\r
if (use_prefix) {\r
final_key = key;\r
}\r
\r
- if (memcached_clone(&clone, memc) == NULL) {\r
- throw IOException("MemcacheBase::addMemcache(): memcached_clone() failed");\r
- }\r
+ m_lock->lock();\r
+ rv = memcached_add(memc, (char *)final_key.c_str(), final_key.length(), (char *)value.c_str(), value.length(), timeout, flags);\r
+ m_lock->unlock();\r
\r
- rv = memcached_add(&clone, (char *)final_key.c_str(), final_key.length(), (char *)value.c_str(), value.length(), timeout, flags);\r
if (rv == MEMCACHED_SUCCESS) {\r
success = true;\r
} else if (rv == MEMCACHED_NOTSTORED) {\r
// already there\r
success = false;\r
+ } else if (rv == MEMCACHED_ERRNO) {\r
+ // System error\r
+ log.error(string("Memcache::addMemcache() SYSTEM ERROR: ") + string(strerror(memc->cached_errno)));\r
+ success = false;\r
} else {\r
// shouldn't be here\r
- log.error(string("Memcache::addMemcache() Problems: ") + memcached_strerror(&clone, rv));\r
+ log.error(string("Memcache::addMemcache() Problems: ") + memcached_strerror(memc, rv));\r
success = false;\r
}\r
\r
- memcached_free(&clone);\r
return success;\r
}\r
\r
\r
memcached_return rv;\r
string final_key;\r
- memcached_st clone;\r
bool success;\r
\r
if (use_prefix) {\r
final_key = key;\r
}\r
\r
- if (memcached_clone(&clone, memc) == NULL) {\r
- throw IOException("MemcacheBase::setMemcache(): memcached_clone() failed");\r
- }\r
+ m_lock->lock();\r
+ rv = memcached_set(memc, (char *)final_key.c_str(), final_key.length(), (char *)value.c_str(), value.length(), timeout, flags);\r
+ m_lock->unlock();\r
\r
- rv = memcached_set(&clone, (char *)final_key.c_str(), final_key.length(), (char *)value.c_str(), value.length(), timeout, flags);\r
if (rv == MEMCACHED_SUCCESS) {\r
success = true;\r
+ } else if (rv == MEMCACHED_ERRNO) {\r
+ // System error\r
+ log.error(string("Memcache::setMemcache() SYSTEM ERROR: ") + string(strerror(memc->cached_errno)));\r
+ success = false;\r
} else {\r
// shouldn't be here\r
- log.error(string("Memcache::setMemcache() Problems: ") + memcached_strerror(&clone, rv));\r
+ log.error(string("Memcache::setMemcache() Problems: ") + memcached_strerror(memc, rv));\r
success = false;\r
}\r
\r
- memcached_free(&clone);\r
return success;\r
}\r
\r
\r
memcached_return rv;\r
string final_key;\r
- memcached_st clone;\r
bool success;\r
\r
if (use_prefix) {\r
final_key = key;\r
}\r
\r
- if (memcached_clone(&clone, memc) == NULL) {\r
- throw IOException("MemcacheBase::replaceMemcache(): memcached_clone() failed");\r
- }\r
+ m_lock->lock();\r
+ rv = memcached_replace(memc, (char *)final_key.c_str(), final_key.length(), (char *)value.c_str(), value.length(), timeout, flags);\r
+ m_lock->unlock();\r
\r
- rv = memcached_replace(&clone, (char *)final_key.c_str(), final_key.length(), (char *)value.c_str(), value.length(), timeout, flags);\r
if (rv == MEMCACHED_SUCCESS) {\r
success = true;\r
} else if (rv == MEMCACHED_NOTSTORED) {\r
// not there\r
success = false;\r
+ } else if (rv == MEMCACHED_ERRNO) {\r
+ // System error\r
+ log.error(string("Memcache::replaceMemcache() SYSTEM ERROR: ") + string(strerror(memc->cached_errno)));\r
+ success = false;\r
} else {\r
// shouldn't be here\r
- log.error(string("Memcache::replaceMemcache() Problems: ") + memcached_strerror(&clone, rv));\r
+ log.error(string("Memcache::replaceMemcache() Problems: ") + memcached_strerror(memc, rv));\r
success = false;\r
}\r
\r
- memcached_free(&clone);\r
return success;\r
}\r
\r
log.debug("INIT: GOT Hosts: %s", h.get());\r
m_memcacheHosts = h.get();\r
\r
+ m_lock = Mutex::create();\r
+ log.debug("Lock created");\r
+\r
memc = memcached_create(NULL);\r
if (memc == NULL) {\r
throw XMLToolingException("MemcacheBase::Memcache(): memcached_create() failed");\r
\r
log.debug("Memcache created");\r
\r
- unsigned int set = MEMCACHED_HASH_CRC;\r
- memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);\r
+ unsigned int hash = MEMCACHED_HASH_CRC;\r
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, hash);\r
log.debug("CRC hash set");\r
\r
+ int32_t timeout = 1000000;\r
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, timeout);\r
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, timeout);\r
+\r
+ int32_t poll_timeout = 1000;\r
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, poll_timeout);\r
+\r
+ int32_t fail_limit = 5;\r
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, fail_limit);\r
+\r
+ int32_t retry_timeout = 30;\r
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, retry_timeout);\r
+\r
memcached_server_st *servers;\r
servers = memcached_servers_parse((char *)m_memcacheHosts.c_str());\r
log.debug("Got %u hosts.", memcached_server_list_count(servers));\r
\r
MemcacheBase::~MemcacheBase() {\r
memcached_free(memc);\r
+ delete m_lock;\r
log.debug("Base object destroyed");\r
}\r
\r
uint32_t rec_version;\r
string value;\r
\r
+ if (m_buildMap) {\r
+ log.debug("Checking context");\r
+\r
+ string map_name = context;\r
+ string ser_arr;\r
+ uint32_t flags;\r
+ bool ctx_found = getMemcache(map_name.c_str(), ser_arr, &flags);\r
+\r
+ if (!ctx_found) {\r
+ return 0;\r
+ }\r
+ }\r
+\r
bool found = getMemcache(final_key.c_str(), value, &rec_version);\r
if (!found) {\r
return 0;\r
}\r
\r
string map_name = context;\r
- \r
- if (! addLock(map_name)) {\r
- log.error("Unable to get lock for context %s!", context);\r
- return;\r
- }\r
- \r
string ser_arr;\r
uint32_t flags;\r
bool result = getMemcache(map_name.c_str(), ser_arr, &flags);\r
replaceMemcache(map_name.c_str(), ser_arr, expiration, flags);\r
}\r
\r
- deleteLock(map_name);\r
- \r
}\r
\r
void MemcacheStorageService::deleteContext(const char* context) {\r
}\r
\r
string map_name = context;\r
- \r
- if (! addLock(map_name)) {\r
- log.error("Unable to get lock for context %s!", context);\r
- return;\r
- }\r
- \r
string ser_arr;\r
uint32_t flags;\r
bool result = getMemcache(map_name.c_str(), ser_arr, &flags);\r
deleteMemcache(map_name.c_str(), 0);\r
}\r
\r
- deleteLock(map_name);\r
-\r
}\r
\r
-extern "C" int xmltooling_extension_init(void*) {\r
+extern "C" int MCEXT_EXPORTS xmltooling_extension_init(void*) {\r
// Register this SS type\r
XMLToolingConfig::getConfig().StorageServiceManager.registerFactory("MEMCACHE", MemcacheStorageServiceFactory);\r
return 0;\r
}\r
\r
-extern "C" void xmltooling_extension_term() {\r
+extern "C" void MCEXT_EXPORTS xmltooling_extension_term() {\r
XMLToolingConfig::getConfig().StorageServiceManager.deregisterFactory("MEMCACHE");\r
}\r
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,0,0
- PRODUCTVERSION 2,1,0,0
+ FILEVERSION 2,2,1,0
+ PRODUCTVERSION 2,2,1,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
BEGIN
VALUE "CompanyName", "Internet2\0"
VALUE "FileDescription", "Shibboleth Memcache Storage Service Plugin\0"
- VALUE "FileVersion", "2, 1, 0, 0\0"
+ VALUE "FileVersion", "2, 2, 1, 0\0"
VALUE "InternalName", "memcache-store\0"
- VALUE "LegalCopyright", "Copyright © 2008 Internet2\0"
+ VALUE "LegalCopyright", "Copyright © 2009 Internet2\0"
VALUE "OriginalFilename", "memcache-store.so\0"
- VALUE "ProductName", "Shibboleth 2.1\0"
- VALUE "ProductVersion", "2, 1, 0, 0\0"
+ VALUE "ProductName", "Shibboleth 2.2.1\0"
+ VALUE "ProductVersion", "2, 2, 1, 0\0"
END
END
BLOCK "VarFileInfo"
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="8.00"\r
+ Version="9.00"\r
Name="memcache-store"\r
ProjectGUID="{666A63A7-983F-4C19-8411-207F24305198}"\r
RootNamespace="memcachestore"\r
Keyword="Win32Proj"\r
+ TargetFrameworkVersion="131072"\r
>\r
<Platforms>\r
<Platform\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- AdditionalIncludeDirectories=""..\..\cpp-xmltooling""\r
+ AdditionalIncludeDirectories=".;..;"..\..\cpp-xmltooling";..\..\..\libmemcached"\r
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"\r
MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib xerces-c_2D.lib xmltooling1D.lib"\r
+ AdditionalDependencies="log4shib1D.lib xerces-c_3D.lib xmltooling1D.lib memcached.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
LinkIncremental="2"\r
- AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(ConfigurationName)"\r
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";"..\..\..\libmemcached\visualc\$(ConfigurationName)""\r
GenerateDebugInformation="true"\r
SubSystem="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
- IntermediateDirectory="$(ConfigurationName)"\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
CharacterSet="2"\r
- WholeProgramOptimization="1"\r
>\r
<Tool\r
Name="VCPreBuildEventTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"\r
- RuntimeLibrary="2"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories=""..\..\cpp-xmltooling";..\..\..\libmemcached\visualc\toolset"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="3"\r
+ BrowseInformation="1"\r
WarningLevel="3"\r
Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
/>\r
<Tool\r
Name="VCPreLinkEventTool"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib xerces-c_2.lib xmltooling1.lib"\r
+ AdditionalDependencies="log4shib1D.lib xerces-c_3D.lib xmltooling1D.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(ConfigurationName)"\r
+ LinkIncremental="2"\r
+ AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
+ GenerateDebugInformation="true"\r
SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- TargetMachine="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="17"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Debug|x64"\r
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ Name="Release|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ConfigurationName)"\r
ConfigurationType="2"\r
CharacterSet="2"\r
+ WholeProgramOptimization="1"\r
>\r
<Tool\r
Name="VCPreBuildEventTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TargetEnvironment="3"\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="3"\r
- BrowseInformation="1"\r
+ AdditionalIncludeDirectories=".;..;"..\..\cpp-xmltooling";..\..\..\libmemcached"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"\r
+ RuntimeLibrary="2"\r
WarningLevel="3"\r
Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="_DEBUG"\r
/>\r
<Tool\r
Name="VCPreLinkEventTool"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib xerces-c_2D.lib xmltooling1D.lib"\r
+ AdditionalDependencies="log4shib1.lib xerces-c_3.lib xmltooling1.lib memcached.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
- GenerateDebugInformation="true"\r
+ LinkIncremental="1"\r
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)";"..\..\..\libmemcached\visualc\$(ConfigurationName)""\r
SubSystem="2"\r
- TargetMachine="17"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="1"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""..\..\cpp-xmltooling""\r
+ AdditionalIncludeDirectories=""..\..\cpp-xmltooling";..\..\..\libmemcached\visualc\toolset"\r
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"\r
RuntimeLibrary="2"\r
WarningLevel="3"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib xerces-c_2.lib xmltooling1.lib"\r
+ AdditionalDependencies="log4shib1.lib xerces-c_3.lib xmltooling1.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
LinkIncremental="1"\r
AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
SubSystem="2"\r
OptimizeReferences="2"\r
EnableCOMDATFolding="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="17"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#ifdef WIN32
# define _CRT_NONSTDC_NO_DEPRECATE 1
# define _CRT_SECURE_NO_DEPRECATE 1
+# define _CRT_RAND_S
#endif
#include <shibsp/AbstractSPRequest.h>
namespace {
SPConfig* g_Config=NULL;
string g_ServerName;
- string g_ServerScheme;
string g_unsetHeaderValue;
+ string g_spoofKey;
bool g_checkSpoofing = true;
bool g_catchAll = false;
static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);
static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);
+
+ void _my_invalid_parameter_handler(
+ const wchar_t * expression,
+ const wchar_t * function,
+ const wchar_t * file,
+ unsigned int line,
+ uintptr_t pReserved
+ ) {
+ return;
+ }
}
PluginManager<RequestMapper,string,const xercesc::DOMElement*>::Factory SunRequestMapFactory;
}
}
}
- name=pblock_findval("server-scheme",pb);
- if (name)
- g_ServerScheme=name;
log_error(LOG_INFORM,"nsapi_shib_init",sn,rq,"nsapi_shib loaded for host (%s)",g_ServerName.c_str());
return REQ_ABORTED;
}
- g_Config->RequestMapperManager.registerFactory(XML_REQUEST_MAPPER,&SunRequestMapFactory);
+ g_Config->RequestMapperManager.registerFactory(NATIVE_REQUEST_MAPPER,&SunRequestMapFactory);
try {
if (!g_Config->instantiate(pblock_findval("shib-config",pb), true))
ServiceProvider* sp=g_Config->getServiceProvider();
Locker locker(sp);
- const PropertySet* props=sp->getPropertySet("Local");
+ const PropertySet* props=sp->getPropertySet("InProcess");
if (props) {
- pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
- if (unsetValue.first)
- g_unsetHeaderValue = unsetValue.second;
pair<bool,bool> flag=props->getBool("checkSpoofing");
g_checkSpoofing = !flag.first || flag.second;
flag=props->getBool("catchAll");
g_catchAll = flag.first && flag.second;
+
+ pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
+ if (unsetValue.first)
+ g_unsetHeaderValue = unsetValue.second;
+ if (g_checkSpoofing) {
+ unsetValue=props->getString("spoofKey");
+ if (unsetValue.first)
+ g_spoofKey = unsetValue.second;
+#ifdef WIN32
+ else {
+ _invalid_parameter_handler old = _set_invalid_parameter_handler(_my_invalid_parameter_handler);
+ unsigned int randkey=0,randkey2=0,randkey3=0,randkey4=0;
+ if (rand_s(&randkey) == 0 && rand_s(&randkey2) == 0 && rand_s(&randkey3) == 0 && rand_s(&randkey4) == 0) {
+ _set_invalid_parameter_handler(old);
+ ostringstream keystr;
+ keystr << randkey << randkey2 << randkey3 << randkey4;
+ g_spoofKey = keystr.str();
+ }
+ else {
+ _set_invalid_parameter_handler(old);
+ pblock_nvinsert("error", "module failed to generate a random anti-spoofing key (if this is Windows 2000 set one manually)", pb);
+ locker.assign(); // pops lock on SP config
+ g_Config->term();
+ g_Config=NULL;
+ return REQ_ABORTED;
+ }
+ }
+#endif
+ }
}
return REQ_PROCEED;
}
{
mutable string m_body;
mutable bool m_gotBody,m_firsttime;
+ bool m_security_active;
+ int m_server_portnum;
mutable vector<string> m_certs;
set<string> m_allhttp;
Request* m_rq;
ShibTargetNSAPI(pblock* pb, ::Session* sn, Request* rq)
- : AbstractSPRequest(SHIBSP_LOGCAT".NSAPI"), m_gotBody(false), m_firsttime(true), m_pb(pb), m_sn(sn), m_rq(rq) {
+ : AbstractSPRequest(SHIBSP_LOGCAT".NSAPI"),
+ m_gotBody(false), m_firsttime(true), m_security_active(false), m_server_portnum(0), m_pb(pb), m_sn(sn), m_rq(rq) {
+
+ // To determine whether SSL is active or not, we're supposed to rely
+ // on the security_active macro. For iPlanet 4.x, this works.
+ // For Sun 7.x, it's useless and appears to be on or off based
+ // on whether ANY SSL support is enabled for a vhost. Sun 6.x is unknown.
+ // As a fix, there's a conf variable called $security that can be mapped
+ // into a function parameter: security_active="$security"
+ // We check for this parameter, and rely on the macro if it isn't set.
+ // This doubles as a scheme virtualizer for load balanced scenarios
+ // since you can set the parameter to 1 or 0 as needed.
+ const char* sa = pblock_findval("security_active", m_pb);
+ if (sa)
+ m_security_active = (*sa == '1');
+ else if (security_active)
+ m_security_active = true;
+ else
+ m_security_active = false;
+
+ // A similar issue exists for the port. server_portnum is no longer
+ // working on at least Sun 7.x, and returns the first listener's port
+ // rather than whatever port is actually used for the request. Nice job, Sun.
+ sa = pblock_findval("server_portnum", m_pb);
+ m_server_portnum = (sa && *sa) ? atoi(sa) : server_portnum;
- const char* uri=pblock_findval("uri", rq->reqpb);
- const char* qstr=pblock_findval("query", rq->reqpb);
+ const char* uri = pblock_findval("uri", rq->reqpb);
+ const char* qstr = pblock_findval("query", rq->reqpb);
if (qstr) {
string temp = string(uri) + '?' + qstr;
}
// See if this is the first time we've run.
- qstr = pblock_findval("auth-type", rq->vars);
- if (qstr && !strcmp(qstr, "shibboleth"))
- m_firsttime = false;
+ if (!g_spoofKey.empty()) {
+ qstr = pblock_findval("Shib-Spoof-Check", rq->headers);
+ if (qstr && g_spoofKey == qstr)
+ m_firsttime = false;
+ }
if (!m_firsttime || rq->orig_rq)
log(SPDebug, "nsapi_shib function running more than once");
}
~ShibTargetNSAPI() { }
const char* getScheme() const {
- return security_active ? "https" : "http";
+ return m_security_active ? "https" : "http";
}
const char* getHostname() const {
#ifdef vs_is_default_vs
return g_ServerName.c_str();
}
int getPort() const {
- return server_portnum;
+ return m_server_portnum;
}
const char* getMethod() const {
return pblock_findval("method", m_rq->reqpb);
}
string getContentType() const {
- char* content_type = "";
- request_header("content-type", &content_type, m_sn, m_rq);
- return content_type;
+ char* content_type = NULL;
+ if (request_header("content-type", &content_type, m_sn, m_rq) != REQ_PROCEED)
+ return "";
+ return content_type ? content_type : "";
}
long getContentLength() const {
if (m_gotBody)
return m_body.length();
- char* content_length="";
- request_header("content-length", &content_length, m_sn, m_rq);
- return atoi(content_length);
+ char* content_length=NULL;
+ if (request_header("content-length", &content_length, m_sn, m_rq) != REQ_PROCEED)
+ return 0;
+ return content_length ? atoi(content_length) : 0;
}
string getRemoteAddr() const {
- return pblock_findval("ip", m_sn->client);
+ string ret = AbstractSPRequest::getRemoteAddr();
+ return ret.empty() ? pblock_findval("ip", m_sn->client) : ret;
}
void log(SPLogLevel level, const string& msg) const {
AbstractSPRequest::log(level,msg);
if (m_gotBody)
return m_body.c_str();
char* content_length=NULL;
- if (request_header("content-length", &content_length, m_sn, m_rq)!=REQ_PROCEED || atoi(content_length) > 1024*1024) // 1MB?
+ if (request_header("content-length", &content_length, m_sn, m_rq) != REQ_PROCEED || !content_length) {
+ m_gotBody = true;
+ return NULL;
+ }
+ else if (atoi(content_length) > 1024*1024) // 1MB?
throw opensaml::SecurityPolicyException("Blocked request body exceeding 1M size limit.");
else {
char ch=IO_EOF+1;
if (m_allhttp.count(cginame) > 0)
throw opensaml::SecurityPolicyException("Attempt to spoof header ($1) was detected.", params(1, rawname));
}
- param_free(pblock_remove(rawname, m_rq->headers));
- pblock_nvinsert(rawname, g_unsetHeaderValue.c_str(), m_rq->headers);
+ if (strcmp(rawname, "REMOTE_USER") == 0) {
+ param_free(pblock_remove("remote-user", m_rq->headers));
+ pblock_nvinsert("remote-user", g_unsetHeaderValue.c_str(), m_rq->headers);
+ }
+ else {
+ param_free(pblock_remove(rawname, m_rq->headers));
+ pblock_nvinsert(rawname, g_unsetHeaderValue.c_str(), m_rq->headers);
+ }
}
void setHeader(const char* name, const char* value) {
param_free(pblock_remove(name, m_rq->headers));
}
void setRemoteUser(const char* user) {
pblock_nvinsert("auth-user", user, m_rq->vars);
+ param_free(pblock_remove("remote-user", m_rq->headers));
+ pblock_nvinsert("remote-user", user, m_rq->headers);
}
string getRemoteUser() const {
const char* ru = pblock_findval("auth-user", m_rq->vars);
return ru ? ru : "";
}
+ void setAuthType(const char* authtype) {
+ param_free(pblock_remove("auth-type", m_rq->vars));
+ if (authtype)
+ pblock_nvinsert("auth-type", authtype, m_rq->vars);
+ }
+ string getAuthType() const {
+ const char* at = pblock_findval("auth-type", m_rq->vars);
+ return at ? at : "";
+ }
+ void setContentType(const char* type) {
+ // iPlanet seems to have a case folding problem.
+ param_free(pblock_remove("content-type", m_rq->srvhdrs));
+ setResponseHeader("Content-Type", type);
+ }
void setResponseHeader(const char* name, const char* value) {
pblock_nvinsert(name, value, m_rq->srvhdrs);
}
// Check user authentication
pair<bool,long> res = stn.getServiceProvider().doAuthentication(stn);
+ // If directed, install a spoof key to recognize when we've already cleared headers.
+ if (!g_spoofKey.empty()) {
+ param_free(pblock_remove("Shib-Spoof-Check", rq->headers));
+ pblock_nvinsert("Shib-Spoof-Check", g_spoofKey.c_str(), rq->headers);
+ }
if (res.first) return (int)res.second;
// user authN was okay -- export the assertions now
param_free(pblock_remove("auth-user",rq->vars));
- // This seems to be required in order to eventually set
- // the auth-user var.
- pblock_nvinsert("auth-type","shibboleth",rq->vars);
+
res = stn.getServiceProvider().doExport(stn);
if (res.first) return (int)res.second;
return WriteClientError(sn, rq, FUNC, "Shibboleth handler threw an exception, see web server log for error.");
}
catch (...) {
+ log_error(LOG_FAILURE,FUNC,sn,rq,"unknown exception caught in Shibboleth handler");
if (g_catchAll)
return WriteClientError(sn, rq, FUNC, "Shibboleth handler threw an unknown exception.");
throw;
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,0,0
- PRODUCTVERSION 2,1,0,0
+ FILEVERSION 2,2,1,0
+ PRODUCTVERSION 2,2,1,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
VALUE "Comments", "\0"
VALUE "CompanyName", "Internet2\0"
VALUE "FileDescription", "Shibboleth NSAPI Extension\0"
- VALUE "FileVersion", "2, 1, 0, 0\0"
+ VALUE "FileVersion", "2, 2, 1, 0\0"
VALUE "InternalName", "nsapi_shib\0"
- VALUE "LegalCopyright", "Copyright © 2008 Internet2\0"
+ VALUE "LegalCopyright", "Copyright © 2009 Internet2\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "nsapi_shib.dll\0"
VALUE "PrivateBuild", "\0"
- VALUE "ProductName", "Shibboleth 2.1\0"
- VALUE "ProductVersion", "2, 1, 0, 0\0"
+ VALUE "ProductName", "Shibboleth 2.2.1\0"
+ VALUE "ProductVersion", "2, 2, 1, 0\0"
VALUE "SpecialBuild", "\0"
END
END
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="9.00"
Name="nsapi_shib"
ProjectGUID="{1396D80A-8672-4224-9B02-95F3F4207CDB}"
+ TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="xerces-c_2.lib xmltooling-lite1.lib ns-httpd30.lib"
+ AdditionalDependencies="xerces-c_3.lib xmltooling-lite1.lib ns-httpd30.lib"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)""
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
/>
<Tool
Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
+ PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
- TargetEnvironment="1"
- TypeLibraryName=".\Debug/nsapi_shib.tlb"
+ TargetEnvironment="3"
+ TypeLibraryName=".\Release/nsapi_shib.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="0"
+ Optimization="2"
+ InlineFunctionExpansion="1"
AdditionalIncludeDirectories=".;..;"..\..\cpp-xmltooling""
- PreprocessorDefinitions="_WINDOWS;WIN32;_DEBUG"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- BrowseInformation="1"
+ PreprocessorDefinitions="NDEBUG;_WINDOWS;WIN32"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
+ PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="xerces-c_2D.lib xmltooling-lite1D.lib ns-httpd30.lib"
- LinkIncremental="2"
+ AdditionalDependencies="xerces-c_3.lib xmltooling-lite1.lib ns-httpd30.lib"
+ LinkIncremental="1"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)""
- GenerateDebugInformation="true"
- TargetMachine="1"
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)""
+ ProgramDatabaseFile=".\Release/nsapi_shib.pdb"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Release|x64"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
/>
<Tool
Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
+ PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
- TargetEnvironment="3"
- TypeLibraryName=".\Release/nsapi_shib.tlb"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/nsapi_shib.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
+ Optimization="0"
AdditionalIncludeDirectories=".;..;"..\..\cpp-xmltooling""
- PreprocessorDefinitions="NDEBUG;_WINDOWS;WIN32"
- StringPooling="true"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
+ PreprocessorDefinitions="_WINDOWS;WIN32;_DEBUG"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
+ PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="xerces-c_2.lib xmltooling-lite1.lib ns-httpd30.lib"
- LinkIncremental="1"
+ AdditionalDependencies="xerces-c_3D.lib xmltooling-lite1D.lib ns-httpd30.lib"
+ LinkIncremental="2"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)""
- ProgramDatabaseFile=".\Release/nsapi_shib.pdb"
- TargetMachine="17"
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(ConfigurationName)""
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="xerces-c_2D.lib xmltooling-lite1D.lib ns-httpd30.lib"
+ AdditionalDependencies="xerces-c_3D.lib xmltooling-lite1D.lib ns-httpd30.lib"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=""..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)""
GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,0,0
- PRODUCTVERSION 2,1,0,0
+ FILEVERSION 2,2,1,0
+ PRODUCTVERSION 2,2,1,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
BEGIN
VALUE "CompanyName", "Internet2\0"
VALUE "FileDescription", "Shibboleth ODBC Storage Service Plugin\0"
- VALUE "FileVersion", "2, 1, 0, 0\0"
+ VALUE "FileVersion", "2, 2, 1, 0\0"
VALUE "InternalName", "odbc-store\0"
- VALUE "LegalCopyright", "Copyright © 2008 Internet2\0"
+ VALUE "LegalCopyright", "Copyright © 2009 Internet2\0"
VALUE "OriginalFilename", "odbc-store.so\0"
- VALUE "ProductName", "Shibboleth 2.1\0"
- VALUE "ProductVersion", "2, 1, 0, 0\0"
+ VALUE "ProductName", "Shibboleth 2.2.1\0"
+ VALUE "ProductVersion", "2, 2, 1, 0\0"
END
END
BLOCK "VarFileInfo"
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="8.00"\r
+ Version="9.00"\r
Name="odbc-store"\r
ProjectGUID="{666A63A7-983F-4C19-8411-207F24305197}"\r
RootNamespace="odbcstore"\r
Keyword="Win32Proj"\r
+ TargetFrameworkVersion="131072"\r
>\r
<Platforms>\r
<Platform\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib xerces-c_2D.lib xmltooling1D.lib"\r
+ AdditionalDependencies="log4shib1D.lib xerces-c_3D.lib xmltooling1D.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
LinkIncremental="2"\r
AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(ConfigurationName)"\r
GenerateDebugInformation="true"\r
SubSystem="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
- IntermediateDirectory="$(ConfigurationName)"\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
CharacterSet="2"\r
- WholeProgramOptimization="1"\r
>\r
<Tool\r
Name="VCPreBuildEventTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
+ Optimization="0"\r
AdditionalIncludeDirectories=""..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"\r
- RuntimeLibrary="2"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="3"\r
+ BrowseInformation="1"\r
WarningLevel="3"\r
Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
/>\r
<Tool\r
Name="VCPreLinkEventTool"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib xerces-c_2.lib xmltooling1.lib"\r
+ AdditionalDependencies="log4shib1D.lib xerces-c_3D.lib xmltooling1D.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(ConfigurationName)"\r
+ LinkIncremental="2"\r
+ AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
+ GenerateDebugInformation="true"\r
SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- TargetMachine="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="17"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Debug|x64"\r
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ Name="Release|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ConfigurationName)"\r
ConfigurationType="2"\r
CharacterSet="2"\r
+ WholeProgramOptimization="1"\r
>\r
<Tool\r
Name="VCPreBuildEventTool"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TargetEnvironment="3"\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="0"\r
AdditionalIncludeDirectories=""..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="3"\r
- BrowseInformation="1"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"\r
+ RuntimeLibrary="2"\r
WarningLevel="3"\r
Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="_DEBUG"\r
/>\r
<Tool\r
Name="VCPreLinkEventTool"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib xerces-c_2D.lib xmltooling1D.lib"\r
+ AdditionalDependencies="log4shib1.lib xerces-c_3.lib xmltooling1.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
- GenerateDebugInformation="true"\r
+ LinkIncremental="1"\r
+ AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(ConfigurationName)"\r
SubSystem="2"\r
- TargetMachine="17"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="1"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib xerces-c_2.lib xmltooling1.lib"\r
+ AdditionalDependencies="log4shib1.lib xerces-c_3.lib xmltooling1.lib"\r
OutputFile="$(OutDir)\$(ProjectName).so"\r
LinkIncremental="1"\r
AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
SubSystem="2"\r
OptimizeReferences="2"\r
EnableCOMDATFolding="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="17"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
PKG=SHIBsp
-VERSION=2.1
+VERSION=2.2.1
BASEDIR=/
NAME=shibboleth-sp
CATEGORY=application,security
PKG=SHIBsp
-VERSION=@-VERSION-@
+VERSION=@PACKAGE_VERSION@
BASEDIR=/
NAME=shibboleth-sp
CATEGORY=application,security
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:am="urn:mace:shibboleth:2.0:attribute-map"
elementFormDefault="qualified"
- version="2.1">
+ version="2.2">
<annotation>
<documentation>
<simpleType name="listOfStrings">
<list itemType="am:string"/>
</simpleType>
+
+ <complexType name="PluggableType">
+ <sequence>
+ <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="type" type="am:string" use="required"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
+ </complexType>
<element name="Attributes">
<annotation>
</annotation>
<complexType>
<sequence>
+ <element name="MetadataProvider" type="am:PluggableType" minOccurs="0"/>
+ <element name="TrustEngine" type="am:PluggableType" minOccurs="0"/>
+ <element name="AttributeFilter" type="am:PluggableType" minOccurs="0"/>
<element name="Attribute" type="am:AttributeType" maxOccurs="unbounded"/>
</sequence>
+ <attribute name="metadataPolicyId" type="am:string"/>
</complexType>
</element>
Decodes a SAML attribute into its Shibboleth-internal representation.
</documentation>
</annotation>
- <attribute name="caseSensitive" type="boolean" default="true">
+ <attribute name="caseSensitive" type="boolean">
<annotation>
<documentation>
Flag controlling case sensitivity when comparisons to the attribute's values are done.
</documentation>
</annotation>
</attribute>
+ <attribute name="internal" type="boolean">
+ <annotation>
+ <documentation>Flag controlling whether the resulting attribute should be exported for CGI use.</documentation>
+ </annotation>
+ </attribute>
</complexType>
<complexType name="StringAttributeDecoder">
</documentation>
</annotation>
</attribute>
+ <attribute name="defaultQualifiers" type="boolean">
+ <annotation>
+ <documentation>
+ Flag controlling whether to default in values for NameQualifier/SPNameQualifier if not set.
+ </documentation>
+ </annotation>
+ </attribute>
</extension>
</complexContent>
</complexType>
</documentation>
</annotation>
</attribute>
+ <attribute name="defaultQualifiers" type="boolean">
+ <annotation>
+ <documentation>
+ Flag controlling whether to default in values for NameQualifier/SPNameQualifier if not set.
+ </documentation>
+ </annotation>
+ </attribute>
<attribute name="formatter" type="am:string">
<annotation>
<documentation>
elementFormDefault="qualified"\r
attributeFormDefault="unqualified"\r
blockDefault="substitution"\r
- version="2.1">\r
+ version="2.2">\r
\r
<import namespace="urn:oasis:names:tc:SAML:2.0:assertion" schemaLocation="saml-schema-assertion-2.0.xsd"/>\r
<import namespace="urn:oasis:names:tc:SAML:2.0:protocol" schemaLocation="saml-schema-protocol-2.0.xsd"/>\r
</sequence>\r
<attribute name="logger" type="anyURI"/>\r
<attribute name="clockSkew" type="unsignedInt"/>\r
+ <attribute name="unsafeChars" type="conf:string"/>
<anyAttribute namespace="##other" processContents="lax"/>\r
</complexType>\r
</element>\r
<any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
<attribute name="logger" type="anyURI"/>\r
- <attribute name="unsetHeaderValue" type="string"/>\r
+ <attribute name="unsetHeaderValue" type="conf:string"/>\r
<attribute name="checkSpoofing" type="boolean"/>\r
- <attribute name="catchAll" type="boolean"/>\r
+ <attribute name="spoofKey" type="conf:string"/>\r
+ <attribute name="catchAll" type="boolean"/>\r
<anyAttribute namespace="##other" processContents="lax"/>\r
</complexType>\r
</element>\r
<any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
<attribute name="normalizeRequest" type="boolean"/>\r
+ <attribute name="safeHeaderNames" type="boolean"/>\r
<anyAttribute namespace="##other" processContents="lax"/>\r
</complexType>\r
</element>\r
<attribute name="metadataError" type="anyURI"/>\r
<attribute name="accessError" type="anyURI"/>\r
<attribute name="sslError" type="anyURI"/>\r
+ <attribute name="REMOTE_ADDR" type="conf:string"/>\r
<anyAttribute namespace="##other" processContents="lax"/>\r
</attributeGroup>\r
<element name="AccessControlProvider" type="conf:PluggableType"/>\r
</complexType>\r
</element>\r
</choice>\r
- <attribute name="handlerURL" type="anyURI"/>\r
+ <attribute name="handlerURL" type="anyURI" use="required"/>\r
<attribute name="handlerSSL" type="boolean"/>\r
<attribute name="exportLocation" type="conf:string"/>\r
<attribute name="exportACL" type="conf:listOfStrings"/>\r
<attribute name="maxTimeSinceAuthn" type="unsignedInt"/>\r
<attribute name="checkAddress" type="boolean"/>\r
<attribute name="consistentAddress" type="boolean"/>\r
+ <attribute name="postData" type="conf:string"/>\r
+ <attribute name="postLimit" type="positiveInteger"/>\r
+ <attribute name="postTemplate" type="conf:string"/>\r
+ <attribute name="postExpire" type="boolean"/>\r
<anyAttribute namespace="##other" processContents="lax"/>\r
</complexType>\r
</element>\r
<attribute name="forceAuthn" type="boolean"/>\r
<attribute name="authnContextClassRef" type="anyURI"/>\r
<attribute name="authnContextComparison" type="samlp:AuthnContextComparisonType"/>\r
+ <attribute name="requestDelegation" type="boolean"/>\r
<anyAttribute namespace="##any" processContents="lax"/>\r
</restriction>\r
</complexContent>\r
<documentation>Specifies a set of SecurityPolicyRule plugins</documentation>\r
</annotation>\r
<complexType>\r
- <sequence>\r
+ <choice>\r
<element name="Rule" type="conf:PluggableType" minOccurs="1" maxOccurs="unbounded"/>\r
- </sequence>\r
+ <element name="PolicyRule" type="conf:PluggableType" minOccurs="1" maxOccurs="unbounded"/>\r
+ </choice>\r
<attribute name="id" type="conf:string" use="required"/>\r
<attribute name="validate" type="boolean"/>\r
<anyAttribute namespace="##any" processContents="lax"/>\r
Name: shibboleth
-Summary: Open source system for attribute-based Web SSO
-Version: 2.1
+Version: 2.2.1
Release: 1
-#Copyright: Internet2
+Summary: Open source system for attribute-based Web SSO
Group: System Environment/Libraries
-License: Apache style
+Vendor: Internet2
+License: Apache 2.0
URL: http://shibboleth.internet2.edu/
-Source0: http://shibboleth.internet2.edu/downloads/%{name}-%{version}.tar.gz
+Source: %{name}-sp-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-root
-BuildRequires: openssl-devel
-BuildRequires: xerces%{?xercesver}-c-devel >= 2.8.0
+%if 0%{?suse_version} > 1030
+BuildRequires: libXerces-c-devel >= 2.8.0
+BuildRequires: libxml-security-c-devel >= 1.4.0
+BuildRequires: libxmltooling-devel >= 1.2
+BuildRequires: libsaml-devel >= 2.2
+%{?_with_log4cpp:BuildRequires: liblog4cpp-devel >= 1.0}
+%{!?_with_log4cpp:BuildRequires: liblog4shib-devel}
+%else
+BuildRequires: xerces%{?xercesver}-c-devel >= 2.8.0
BuildRequires: xml-security-c-devel >= 1.4.0
-BuildRequires: zlib-devel, opensaml-devel >= 2.1
-%{?_with_log4cpp:BuildRequires: log4cpp-devel >= 1.0}
+BuildRequires: xmltooling-devel >= 1.2
+BuildRequires: opensaml-devel >= 2.2
+%{?_with_log4cpp:BuildRequires: log4cpp-devel >= 1.0}
%{!?_with_log4cpp:BuildRequires: log4shib-devel}
+%endif
+BuildRequires: gcc-c++
+%{!?_without_doxygen:BuildRequires: doxygen}
+%{!?_without_odbc:BuildRequires:unixODBC-devel}
+BuildRequires: zlib-devel
%{?_with_fastcgi:BuildRequires: fcgi-devel}
%if "%{_vendor}" == "redhat"
%{!?_without_builtinapache:BuildRequires: httpd-devel}
%{!?_without_builtinapache:BuildRequires: apache2-devel}
%endif
+%if "%{_vendor}" == "suse"
+%define pkgdocdir %{_docdir}/%{name}
+%else
+%define pkgdocdir %{_docdir}/%{name}-%{version}
+%endif
%description
-Shibboleth, a project of Internet2/MACE, is developing architectures,
-policy structures, practical technologies, and an open source
-implementation to support inter-institutional sharing of web resources
-subject to access controls. In addition, Shibboleth will develop a
-policy framework that will allow inter-operation within the higher
-education community.
+Shibboleth is a Web Single Sign-On implementations based on OpenSAML
+that supports multiple protocols, federated identity, and the extensible
+exchange of rich attributes subject to privacy controls.
-This package contains the shibboleth runtime library and apache module.
+This package contains the Shibboleth Service Provider runtime libraries
+and Apache module(s).
%package devel
Summary: Shibboleth development Headers
Group: Development/Libraries
Requires: %{name} = %{version}
+%if 0%{?suse_version} > 1030
+Requires: libXerces-c-devel >= 2.8.0
+Requires: libxml-security-c-devel >= 1.4.0
+Requires: libxmltooling-devel >= 1.2
+Requires: libsaml-devel >= 2.2
+%{?_with_log4cpp:Requires: liblog4cpp-devel >= 1.0}
+%{!?_with_log4cpp:Requires: liblog4shib-devel}
+%else
+Requires: xerces%{?xercesver}-c-devel >= 2.8.0
+Requires: xml-security-c-devel >= 1.4.0
+Requires: xmltooling-devel >= 1.2
+Requires: opensaml-devel >= 2.2
+%{?_with_log4cpp:Requires: log4cpp-devel >= 1.0}
+%{!?_with_log4cpp:Requires: log4shib-devel}
+%endif
%description devel
-Shibboleth, a project of Internet2/MACE, is developing architectures,
-policy structures, practical technologies, and an open source
-implementation to support inter-institutional sharing of web resources
-subject to access controls. In addition, Shibboleth will develop a
-policy framework that will allow inter-operation within the higher
-education community.
-
-This package contains the headers and other necessary files to build
-applications that use the shibboleth library.
-
-%package docs
-Summary: Shibboleth API Documentation
-Group: Development/Libraries
-Requires: %{name} = %{version}
+Shibboleth is a Web Single Sign-On implementations based on OpenSAML
+that supports multiple protocols, federated identity, and the extensible
+exchange of rich attributes subject to privacy controls.
+
+This package includes files needed for development with Shibboleth.
-%description docs
-Shibboleth Library API documentation generated by doxygen.
%prep
%setup -q
%build
-%configure %{?_without_odbc:--disable-odbc} %{?_without_adfs:--disable-adfs} %{?_with_fastcgi} %{?shib_options}
-%{__make}
+%configure %{?_without_odbc:--disable-odbc} %{?_without_adfs:--disable-adfs} %{?_with_fastcgi} %{?_with_memcached} %{?shib_options}
+%{__make} pkgdocdir=%{pkgdocdir}
%install
-[ "$RPM_BUILD_ROOT" != "/" ] && %{__rm} -rf $RPM_BUILD_ROOT
-%{__make} install NOKEYGEN=1 DESTDIR=$RPM_BUILD_ROOT
+%{__make} install NOKEYGEN=1 DESTDIR=$RPM_BUILD_ROOT pkgdocdir=%{pkgdocdir}
%if "%{_vendor}" == "suse"
%{__sed} -i "s/\/var\/log\/httpd/\/var\/log\/apache2/g" \
- $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/native.logger
+ $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/native.logger
%endif
-# Plug the SP into Apache on a recognized system.
+# Plug the SP into the built-in Apache on a recognized system.
+touch rpm.filelist
APACHE_CONFIG="no"
-if [ -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/mod_shib_13.so ] ; then
+if [ -f $RPM_BUILD_ROOT%{_libdir}/%{name}/mod_shib_13.so ] ; then
APACHE_CONFIG="apache.config"
fi
-if [ -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/mod_shib_20.so ] ; then
+if [ -f $RPM_BUILD_ROOT%{_libdir}/%{name}/mod_shib_20.so ] ; then
APACHE_CONFIG="apache2.config"
fi
-if [ -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/mod_shib_22.so ] ; then
+if [ -f $RPM_BUILD_ROOT%{_libdir}/%{name}/mod_shib_22.so ] ; then
APACHE_CONFIG="apache22.config"
fi
+%{?_without_builtinapache:APACHE_CONFIG="no"}
if [ "$APACHE_CONFIG" != "no" ] ; then
APACHE_CONFD="no"
if [ -d %{_sysconfdir}/httpd/conf.d ] ; then
fi
if [ "$APACHE_CONFD" != "no" ] ; then
%{__mkdir} -p $RPM_BUILD_ROOT$APACHE_CONFD
-%if "%{_vendor}" == "suse"
- %{__sed} "s/\/usr\/doc\/%{name}/\/usr\/share\/doc\/packages\/%{name}/g" \
- $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/$APACHE_CONFIG \
- > $RPM_BUILD_ROOT$APACHE_CONFD/shib.conf
-%else
- %{__sed} "s/\/usr\/doc\/%{name}/\/usr\/share\/doc\/%{name}-2.1/g" \
- $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/$APACHE_CONFIG \
- > $RPM_BUILD_ROOT$APACHE_CONFD/shib.conf
-%endif
+ %{__cp} -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/$APACHE_CONFIG $RPM_BUILD_ROOT$APACHE_CONFD/shib.conf
+ echo "%config $APACHE_CONFD/shib.conf" > rpm.filelist
fi
fi
-%check || :
+%if "%{_vendor}" == "redhat" || "%{_vendor}" == "suse"
+ # %{_initddir} not yet in RHEL5, use deprecated %{_initrddir}
+ mkdir -p $RPM_BUILD_ROOT%{_initrddir}
+ %{__cp} -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/shibd-%{_vendor} $RPM_BUILD_ROOT%{_initrddir}/shibd
+ %{__chmod} 755 $RPM_BUILD_ROOT%{_initrddir}/shibd
+%endif
+
+%check
%{__make} check
%clean
/sbin/ldconfig
%endif
-# Install the shibd init.d scripts and service
-%if "%{_vendor}" == "redhat"
- if [ -d %{_sysconfdir}/init.d ] ; then
- if [ ! -f %{_sysconfdir}/init.d/shibd ] ; then
- %{__cp} -p %{_sysconfdir}/%{name}/shibd-%{_vendor} %{_sysconfdir}/init.d/shibd
- %{__chmod} 755 %{_sysconfdir}/init.d/shibd
- chkconfig --add shibd
- fi
- fi
-%endif
-
# Key generation
cd %{_sysconfdir}/%{name}
sh ./keygen.sh -b
-%postun
+%if "%{_vendor}" == "redhat"
+ # This adds the proper /etc/rc*.d links for the script
+ /sbin/chkconfig --add shibd
+ # On upgrade, restart components if they're already running.
+ if [ "$1" -gt "1" ] ; then
+ /etc/init.d/shibd status 1>/dev/null && /etc/init.d/shibd restart 1>/dev/null
+ %{!?_without_builtinapache:/etc/init.d/httpd status 1>/dev/null && /etc/init.d/httpd restart 1>/dev/null}
+ fi
+%endif
+%if "%{_vendor}" == "suse"
+ # This adds the proper /etc/rc*.d links for the script
+ /sbin/chkconfig --add shibd
+ cd /usr/sbin && ln -s /etc/init.d/shibd rcshibd
+ # On upgrade, restart components if they're already running.
+ if [ "$1" -gt "1" ] ; then
+ /etc/init.d/shibd status 1>/dev/null && /etc/init.d/shibd restart 1>/dev/null
+ %{!?_without_builtinapache:/etc/init.d/apache2 status 1>/dev/null && /etc/init.d/apache2 restart 1>/dev/null}
+ fi
+%endif
+
+%preun
+%if "%{_vendor}" == "redhat"
+ if [ "$1" = 0 ] ; then
+ /sbin/service shibd stop >/dev/null 2>&1
+ /sbin/chkconfig --del shibd
+ fi
+%endif
+%if "%{_vendor}" == "suse"
+ if [ "$1" = 0 ] ; then
+ /sbin/service shibd stop >/dev/null 2>&1
+ /sbin/chkconfig --del shibd
+ cd /usr/sbin && %{__rm} -f rcshibd
+ fi
+%endif
+
%ifnos solaris2.8 solaris2.9 solaris2.10
-/sbin/ldconfig
+%postun -p /sbin/ldconfig
%endif
-# clear init.d state
+%posttrans
+# ugly hack if init script got removed during %postun by upgraded (buggy/2.1) package
%if "%{_vendor}" == "redhat"
- chkconfig --del shibd
- [ -f %{_sysconfdir}/init.d/shibd ] && \
- %{__rm} -f %{_sysconfdir}/init.d/shibd
+ if [ ! -f %{_initrddir}/shibd ] ; then
+ if [ -f %{_sysconfdir}/%{name}/shibd-%{_vendor} ] ; then
+ %{__cp} -p %{_sysconfdir}/%{name}/shibd-%{_vendor} %{_initrddir}/shibd
+ %{__chmod} 755 %{_initrddir}/shibd
+ /sbin/chkconfig --add shibd
+ fi
+ fi
%endif
-%files
+%files -f rpm.filelist
%defattr(-,root,root,-)
%{_sbindir}/shibd
%{_bindir}/mdquery
%config(noreplace) %{_sysconfdir}/%{name}/*.xml
%config(noreplace) %{_sysconfdir}/%{name}/*.html
%config(noreplace) %{_sysconfdir}/%{name}/*.logger
-%if "%{_vendor}" == "suse"
-%config %{_sysconfdir}/apache2/conf.d/shib.conf
-%else
-%config %{_sysconfdir}/httpd/conf.d/shib.conf
+%if "%{_vendor}" == "redhat" || "%{_vendor}" == "suse"
+%attr(755, root, root) %{_initrddir}/shibd
%endif
%{_sysconfdir}/%{name}/*.dist
%{_sysconfdir}/%{name}/apache*.config
-%{_sysconfdir}/%{name}/shibd-redhat
-%{_sysconfdir}/%{name}/shibd-debian
-%{_sysconfdir}/%{name}/shibd-osx.plist
-%{_sysconfdir}/%{name}/keygen.sh
+%{_sysconfdir}/%{name}/shibd-*
+%attr(755, root, root) %{_sysconfdir}/%{name}/keygen.sh
+%attr(755, root, root) %{_sysconfdir}/%{name}/metagen.sh
%{_sysconfdir}/%{name}/*.xsl
-%docdir %{_datadir}/doc/%{name}
-%{_datadir}/doc/%{name}/CREDITS.txt
-%{_datadir}/doc/%{name}/FASTCGI.LICENSE
-%{_datadir}/doc/%{name}/LICENSE.txt
-%{_datadir}/doc/%{name}/LOG4CPP.LICENSE
-%{_datadir}/doc/%{name}/logo.jpg
-%{_datadir}/doc/%{name}/main.css
-%{_datadir}/doc/%{name}/NOTICE.txt
-%{_datadir}/doc/%{name}/OPENSSL.LICENSE
-%{_datadir}/doc/%{name}/README.txt
-%{_datadir}/doc/%{name}/RELEASE.txt
+%doc %{pkgdocdir}
+%exclude %{pkgdocdir}/api
%files devel
%defattr(-,root,root,-)
-%{_includedir}
+%{_includedir}/*
%{_libdir}/libshibsp.so
%{_libdir}/libshibsp-lite.so
-
-%files docs
-%defattr(644,root,root,755)
-%doc %{_datadir}/doc/%{name}/api
+%doc %{pkgdocdir}/api
%changelog
+* Mon Aug 10 2009 Scott Cantor <cantor.2@osu.edu> - 2.2.1-1
+- Doc handling changes
+- SuSE init script
+
+* Tue Aug 4 2009 Scott Cantor <cantor.2@osu.edu> - 2.2.1-1
+- Initial version for 2.2.1, with shibd/httpd restart on upgrade
+
+* Thu Jun 25 2009 Scott Cantor <cantor.2@osu.edu> - 2.2-3
+- Add additional cleanup to posttrans fix
+
+* Tue Jun 23 2009 Scott Cantor <cantor.2@osu.edu> - 2.2-2
+- Reverse without_builtinapache macro test
+- Fix init script handling on Red Hat to handle upgrades
+
+* Wed Dec 3 2008 Scott Cantor <cantor.2@osu.edu> - 2.2-1
+- Bump minor version.
+- Make keygen.sh executable.
+- Fixing SUSE Xerces dependency name.
+- Optionally package shib.conf.
+
* Tue Jun 10 2008 Scott Cantor <cantor.2@osu.edu> - 2.1-1
- Change shib.conf handling to treat as config file.
-Name: shibboleth
-Summary: Open source system for attribute-based Web SSO
-Version: @-VERSION-@
+Name: @PACKAGE@
+Version: @PACKAGE_VERSION@
Release: 1
-#Copyright: Internet2
+Summary: Open source system for attribute-based Web SSO
Group: System Environment/Libraries
-License: Apache style
+Vendor: Internet2
+License: Apache 2.0
URL: http://shibboleth.internet2.edu/
-Source0: http://shibboleth.internet2.edu/downloads/%{name}-%{version}.tar.gz
+Source: %{name}-sp-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-root
-BuildRequires: openssl-devel
-BuildRequires: xerces%{?xercesver}-c-devel >= 2.8.0
+%if 0%{?suse_version} > 1030
+BuildRequires: libXerces-c-devel >= 2.8.0
+BuildRequires: libxml-security-c-devel >= 1.4.0
+BuildRequires: libxmltooling-devel >= 1.2
+BuildRequires: libsaml-devel >= 2.2
+%{?_with_log4cpp:BuildRequires: liblog4cpp-devel >= 1.0}
+%{!?_with_log4cpp:BuildRequires: liblog4shib-devel}
+%else
+BuildRequires: xerces%{?xercesver}-c-devel >= 2.8.0
BuildRequires: xml-security-c-devel >= 1.4.0
-BuildRequires: zlib-devel, opensaml-devel >= 2.1
-%{?_with_log4cpp:BuildRequires: log4cpp-devel >= 1.0}
+BuildRequires: xmltooling-devel >= 1.2
+BuildRequires: opensaml-devel >= 2.2
+%{?_with_log4cpp:BuildRequires: log4cpp-devel >= 1.0}
%{!?_with_log4cpp:BuildRequires: log4shib-devel}
+%endif
+BuildRequires: gcc-c++
+%{!?_without_doxygen:BuildRequires: doxygen}
+%{!?_without_odbc:BuildRequires:unixODBC-devel}
+BuildRequires: zlib-devel
%{?_with_fastcgi:BuildRequires: fcgi-devel}
%if "%{_vendor}" == "redhat"
%{!?_without_builtinapache:BuildRequires: httpd-devel}
%{!?_without_builtinapache:BuildRequires: apache2-devel}
%endif
+%if "%{_vendor}" == "suse"
+%define pkgdocdir %{_docdir}/%{name}
+%else
+%define pkgdocdir %{_docdir}/%{name}-%{version}
+%endif
%description
-Shibboleth, a project of Internet2/MACE, is developing architectures,
-policy structures, practical technologies, and an open source
-implementation to support inter-institutional sharing of web resources
-subject to access controls. In addition, Shibboleth will develop a
-policy framework that will allow inter-operation within the higher
-education community.
+Shibboleth is a Web Single Sign-On implementations based on OpenSAML
+that supports multiple protocols, federated identity, and the extensible
+exchange of rich attributes subject to privacy controls.
-This package contains the shibboleth runtime library and apache module.
+This package contains the Shibboleth Service Provider runtime libraries
+and Apache module(s).
%package devel
Summary: Shibboleth development Headers
Group: Development/Libraries
Requires: %{name} = %{version}
+%if 0%{?suse_version} > 1030
+Requires: libXerces-c-devel >= 2.8.0
+Requires: libxml-security-c-devel >= 1.4.0
+Requires: libxmltooling-devel >= 1.2
+Requires: libsaml-devel >= 2.2
+%{?_with_log4cpp:Requires: liblog4cpp-devel >= 1.0}
+%{!?_with_log4cpp:Requires: liblog4shib-devel}
+%else
+Requires: xerces%{?xercesver}-c-devel >= 2.8.0
+Requires: xml-security-c-devel >= 1.4.0
+Requires: xmltooling-devel >= 1.2
+Requires: opensaml-devel >= 2.2
+%{?_with_log4cpp:Requires: log4cpp-devel >= 1.0}
+%{!?_with_log4cpp:Requires: log4shib-devel}
+%endif
%description devel
-Shibboleth, a project of Internet2/MACE, is developing architectures,
-policy structures, practical technologies, and an open source
-implementation to support inter-institutional sharing of web resources
-subject to access controls. In addition, Shibboleth will develop a
-policy framework that will allow inter-operation within the higher
-education community.
-
-This package contains the headers and other necessary files to build
-applications that use the shibboleth library.
-
-%package docs
-Summary: Shibboleth API Documentation
-Group: Development/Libraries
-Requires: %{name} = %{version}
+Shibboleth is a Web Single Sign-On implementations based on OpenSAML
+that supports multiple protocols, federated identity, and the extensible
+exchange of rich attributes subject to privacy controls.
+
+This package includes files needed for development with Shibboleth.
-%description docs
-Shibboleth Library API documentation generated by doxygen.
%prep
%setup -q
%build
-%configure %{?_without_odbc:--disable-odbc} %{?_without_adfs:--disable-adfs} %{?_with_fastcgi} %{?shib_options}
-%{__make}
+%configure %{?_without_odbc:--disable-odbc} %{?_without_adfs:--disable-adfs} %{?_with_fastcgi} %{?_with_memcached} %{?shib_options}
+%{__make} pkgdocdir=%{pkgdocdir}
%install
-[ "$RPM_BUILD_ROOT" != "/" ] && %{__rm} -rf $RPM_BUILD_ROOT
-%{__make} install NOKEYGEN=1 DESTDIR=$RPM_BUILD_ROOT
+%{__make} install NOKEYGEN=1 DESTDIR=$RPM_BUILD_ROOT pkgdocdir=%{pkgdocdir}
%if "%{_vendor}" == "suse"
%{__sed} -i "s/\/var\/log\/httpd/\/var\/log\/apache2/g" \
- $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/native.logger
+ $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/native.logger
%endif
-# Plug the SP into Apache on a recognized system.
+# Plug the SP into the built-in Apache on a recognized system.
+touch rpm.filelist
APACHE_CONFIG="no"
-if [ -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/mod_shib_13.so ] ; then
+if [ -f $RPM_BUILD_ROOT%{_libdir}/%{name}/mod_shib_13.so ] ; then
APACHE_CONFIG="apache.config"
fi
-if [ -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/mod_shib_20.so ] ; then
+if [ -f $RPM_BUILD_ROOT%{_libdir}/%{name}/mod_shib_20.so ] ; then
APACHE_CONFIG="apache2.config"
fi
-if [ -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/mod_shib_22.so ] ; then
+if [ -f $RPM_BUILD_ROOT%{_libdir}/%{name}/mod_shib_22.so ] ; then
APACHE_CONFIG="apache22.config"
fi
+%{?_without_builtinapache:APACHE_CONFIG="no"}
if [ "$APACHE_CONFIG" != "no" ] ; then
APACHE_CONFD="no"
if [ -d %{_sysconfdir}/httpd/conf.d ] ; then
fi
if [ "$APACHE_CONFD" != "no" ] ; then
%{__mkdir} -p $RPM_BUILD_ROOT$APACHE_CONFD
-%if "%{_vendor}" == "suse"
- %{__sed} "s/\/usr\/doc\/%{name}/\/usr\/share\/doc\/packages\/%{name}/g" \
- $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/$APACHE_CONFIG \
- > $RPM_BUILD_ROOT$APACHE_CONFD/shib.conf
-%else
- %{__sed} "s/\/usr\/doc\/%{name}/\/usr\/share\/doc\/%{name}-@-VERSION-@/g" \
- $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/$APACHE_CONFIG \
- > $RPM_BUILD_ROOT$APACHE_CONFD/shib.conf
-%endif
+ %{__cp} -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/$APACHE_CONFIG $RPM_BUILD_ROOT$APACHE_CONFD/shib.conf
+ echo "%config $APACHE_CONFD/shib.conf" > rpm.filelist
fi
fi
-%check || :
+%if "%{_vendor}" == "redhat" || "%{_vendor}" == "suse"
+ # %{_initddir} not yet in RHEL5, use deprecated %{_initrddir}
+ mkdir -p $RPM_BUILD_ROOT%{_initrddir}
+ %{__cp} -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/shibd-%{_vendor} $RPM_BUILD_ROOT%{_initrddir}/shibd
+ %{__chmod} 755 $RPM_BUILD_ROOT%{_initrddir}/shibd
+%endif
+
+%check
%{__make} check
%clean
/sbin/ldconfig
%endif
-# Install the shibd init.d scripts and service
-%if "%{_vendor}" == "redhat"
- if [ -d %{_sysconfdir}/init.d ] ; then
- if [ ! -f %{_sysconfdir}/init.d/shibd ] ; then
- %{__cp} -p %{_sysconfdir}/%{name}/shibd-%{_vendor} %{_sysconfdir}/init.d/shibd
- %{__chmod} 755 %{_sysconfdir}/init.d/shibd
- chkconfig --add shibd
- fi
- fi
-%endif
-
# Key generation
cd %{_sysconfdir}/%{name}
sh ./keygen.sh -b
-%postun
+%if "%{_vendor}" == "redhat"
+ # This adds the proper /etc/rc*.d links for the script
+ /sbin/chkconfig --add shibd
+ # On upgrade, restart components if they're already running.
+ if [ "$1" -gt "1" ] ; then
+ /etc/init.d/shibd status 1>/dev/null && /etc/init.d/shibd restart 1>/dev/null
+ %{!?_without_builtinapache:/etc/init.d/httpd status 1>/dev/null && /etc/init.d/httpd restart 1>/dev/null}
+ fi
+%endif
+%if "%{_vendor}" == "suse"
+ # This adds the proper /etc/rc*.d links for the script
+ /sbin/chkconfig --add shibd
+ cd /usr/sbin && ln -s /etc/init.d/shibd rcshibd
+ # On upgrade, restart components if they're already running.
+ if [ "$1" -gt "1" ] ; then
+ /etc/init.d/shibd status 1>/dev/null && /etc/init.d/shibd restart 1>/dev/null
+ %{!?_without_builtinapache:/etc/init.d/apache2 status 1>/dev/null && /etc/init.d/apache2 restart 1>/dev/null}
+ fi
+%endif
+
+%preun
+%if "%{_vendor}" == "redhat"
+ if [ "$1" = 0 ] ; then
+ /sbin/service shibd stop >/dev/null 2>&1
+ /sbin/chkconfig --del shibd
+ fi
+%endif
+%if "%{_vendor}" == "suse"
+ if [ "$1" = 0 ] ; then
+ /sbin/service shibd stop >/dev/null 2>&1
+ /sbin/chkconfig --del shibd
+ cd /usr/sbin && %{__rm} -f rcshibd
+ fi
+%endif
+
%ifnos solaris2.8 solaris2.9 solaris2.10
-/sbin/ldconfig
+%postun -p /sbin/ldconfig
%endif
-# clear init.d state
+%posttrans
+# ugly hack if init script got removed during %postun by upgraded (buggy/2.1) package
%if "%{_vendor}" == "redhat"
- chkconfig --del shibd
- [ -f %{_sysconfdir}/init.d/shibd ] && \
- %{__rm} -f %{_sysconfdir}/init.d/shibd
+ if [ ! -f %{_initrddir}/shibd ] ; then
+ if [ -f %{_sysconfdir}/%{name}/shibd-%{_vendor} ] ; then
+ %{__cp} -p %{_sysconfdir}/%{name}/shibd-%{_vendor} %{_initrddir}/shibd
+ %{__chmod} 755 %{_initrddir}/shibd
+ /sbin/chkconfig --add shibd
+ fi
+ fi
%endif
-%files
+%files -f rpm.filelist
%defattr(-,root,root,-)
%{_sbindir}/shibd
%{_bindir}/mdquery
%config(noreplace) %{_sysconfdir}/%{name}/*.xml
%config(noreplace) %{_sysconfdir}/%{name}/*.html
%config(noreplace) %{_sysconfdir}/%{name}/*.logger
-%if "%{_vendor}" == "suse"
-%config %{_sysconfdir}/apache2/conf.d/shib.conf
-%else
-%config %{_sysconfdir}/httpd/conf.d/shib.conf
+%if "%{_vendor}" == "redhat" || "%{_vendor}" == "suse"
+%attr(755, root, root) %{_initrddir}/shibd
%endif
%{_sysconfdir}/%{name}/*.dist
%{_sysconfdir}/%{name}/apache*.config
-%{_sysconfdir}/%{name}/shibd-redhat
-%{_sysconfdir}/%{name}/shibd-debian
-%{_sysconfdir}/%{name}/shibd-osx.plist
-%{_sysconfdir}/%{name}/keygen.sh
+%{_sysconfdir}/%{name}/shibd-*
+%attr(755, root, root) %{_sysconfdir}/%{name}/keygen.sh
+%attr(755, root, root) %{_sysconfdir}/%{name}/metagen.sh
%{_sysconfdir}/%{name}/*.xsl
-%docdir %{_datadir}/doc/%{name}
-%{_datadir}/doc/%{name}/CREDITS.txt
-%{_datadir}/doc/%{name}/FASTCGI.LICENSE
-%{_datadir}/doc/%{name}/LICENSE.txt
-%{_datadir}/doc/%{name}/LOG4CPP.LICENSE
-%{_datadir}/doc/%{name}/logo.jpg
-%{_datadir}/doc/%{name}/main.css
-%{_datadir}/doc/%{name}/NOTICE.txt
-%{_datadir}/doc/%{name}/OPENSSL.LICENSE
-%{_datadir}/doc/%{name}/README.txt
-%{_datadir}/doc/%{name}/RELEASE.txt
+%doc %{pkgdocdir}
+%exclude %{pkgdocdir}/api
%files devel
%defattr(-,root,root,-)
-%{_includedir}
+%{_includedir}/*
%{_libdir}/libshibsp.so
%{_libdir}/libshibsp-lite.so
-
-%files docs
-%defattr(644,root,root,755)
-%doc %{_datadir}/doc/%{name}/api
+%doc %{pkgdocdir}/api
%changelog
+* Mon Aug 10 2009 Scott Cantor <cantor.2@osu.edu> - 2.2.1-1
+- Doc handling changes
+- SuSE init script
+
+* Tue Aug 4 2009 Scott Cantor <cantor.2@osu.edu> - 2.2.1-1
+- Initial version for 2.2.1, with shibd/httpd restart on upgrade
+
+* Thu Jun 25 2009 Scott Cantor <cantor.2@osu.edu> - 2.2-3
+- Add additional cleanup to posttrans fix
+
+* Tue Jun 23 2009 Scott Cantor <cantor.2@osu.edu> - 2.2-2
+- Reverse without_builtinapache macro test
+- Fix init script handling on Red Hat to handle upgrades
+
+* Wed Dec 3 2008 Scott Cantor <cantor.2@osu.edu> - 2.2-1
+- Bump minor version.
+- Make keygen.sh executable.
+- Fixing SUSE Xerces dependency name.
+- Optionally package shib.conf.
+
* Tue Jun 10 2008 Scott Cantor <cantor.2@osu.edu> - 2.1-1
- Change shib.conf handling to treat as config file.
/*\r
- * Copyright 2001-2007 Internet2\r
+ * Copyright 2001-2009 Internet2\r
*\r
* Licensed under the Apache License, Version 2.0 (the "License");\r
* you may not use this file except in compliance with the License.\r
const char* shar_prefix = NULL;\r
bool shar_checkonly = false;\r
bool shar_version = false;\r
-static int unlink_socket = 0;\r
+static bool unlink_socket = false;\r
const char* pidfile = NULL;\r
\r
#ifdef WIN32\r
\r
//_CrtSetAllocHook(MyAllocHook);\r
\r
- // Run the listener\r
if (!shar_checkonly) {\r
-\r
// Run the listener.\r
- if (!conf.getServiceProvider()->getListenerService()->run(&shibd_shutdown)) {\r
- fprintf(stderr, "listener failed to enter listen loop\n");\r
+ ListenerService* listener = conf.getServiceProvider()->getListenerService();\r
+ if (!listener->init(unlink_socket)) {\r
+ fprintf(stderr, "listener failed to initialize\n");\r
+ conf.term();\r
+ return -3;\r
+ }\r
+ else if (!listener->run(&shibd_shutdown)) {\r
+ fprintf(stderr, "listener failed during service\n");\r
+ listener->term();\r
+ conf.term();\r
return -3;\r
}\r
+ listener->term();\r
}\r
\r
conf.term();\r
\r
#else\r
\r
+int daemon_wait = 3;\r
+bool shibd_running = false;\r
+bool daemonize = true;\r
+\r
static void term_handler(int arg)\r
{\r
shibd_shutdown = true;\r
}\r
\r
+static void run_handler(int arg)\r
+{\r
+ shibd_running = true;\r
+}\r
+\r
+static void child_handler(int arg)\r
+{\r
+ // Terminate the parent's wait/sleep if the newly born daemon dies early.\r
+}\r
+\r
static int setup_signals(void)\r
{\r
struct sigaction sa;\r
if (sigaction(SIGTERM, &sa, NULL) < 0) {\r
return -1;\r
}\r
+\r
+ if (daemonize) {\r
+ memset(&sa, 0, sizeof (sa));\r
+ sa.sa_handler = run_handler;\r
+\r
+ if (sigaction(SIGUSR1, &sa, NULL) < 0) {\r
+ return -1;\r
+ }\r
+\r
+ memset(&sa, 0, sizeof (sa));\r
+ sa.sa_handler = child_handler;\r
+\r
+ if (sigaction(SIGCHLD, &sa, NULL) < 0) {\r
+ return -1;\r
+ }\r
+ }\r
+\r
return 0;\r
}\r
\r
fprintf(stderr, " -d\tinstallation prefix to use.\n");\r
fprintf(stderr, " -c\tconfig file to use.\n");\r
fprintf(stderr, " -x\tXML schema catalogs to use.\n");\r
- fprintf(stderr, " -t\tcheck configuration file for problems.\n");\r
+ fprintf(stderr, " -t\ttest configuration file for problems.\n");\r
fprintf(stderr, " -f\tforce removal of listener socket.\n");\r
+ fprintf(stderr, " -F\tstay in the foreground.\n");\r
fprintf(stderr, " -p\tpid file to use.\n");\r
+ fprintf(stderr, " -w\tseconds to wait for successful daemonization.\n");\r
fprintf(stderr, " -v\tprint software version.\n");\r
fprintf(stderr, " -h\tprint this help message.\n");\r
exit(1);\r
{\r
int opt;\r
\r
- while ((opt = getopt(argc, argv, "d:c:x:p:ftvh")) > 0) {\r
+ while ((opt = getopt(argc, argv, "d:c:x:p:w:fFtvh")) > 0) {\r
switch (opt) {\r
case 'd':\r
shar_prefix=optarg;\r
shar_schemadir=optarg;\r
break;\r
case 'f':\r
- unlink_socket = 1;\r
+ unlink_socket = true;\r
+ break;\r
+ case 'F':\r
+ daemonize = false;\r
break;\r
case 't':\r
shar_checkonly=true;\r
+ daemonize=false;\r
break;\r
case 'v':\r
shar_version=true;\r
case 'p':\r
pidfile=optarg;\r
break;\r
+ case 'w':\r
+ if (optarg)\r
+ daemon_wait = atoi(optarg);\r
+ if (daemon_wait <= 0)\r
+ daemon_wait = 3;\r
+ break;\r
default:\r
return -1;\r
}\r
return -1;\r
}\r
\r
+ if (daemonize) {\r
+ // We must fork() early, while we're single threaded.\r
+ // StorageService cleanup thread is about to start.\r
+ switch (fork()) {\r
+ case 0:\r
+ break;\r
+ case -1:\r
+ perror("forking");\r
+ exit(EXIT_FAILURE);\r
+ default:\r
+ sleep(daemon_wait);\r
+ exit(shibd_running ? EXIT_SUCCESS : EXIT_FAILURE);\r
+ }\r
+ }\r
+\r
if (!conf.instantiate(shar_config)) {\r
fprintf(stderr, "configuration is invalid, check console for specific problems\n");\r
conf.term();\r
if (shar_checkonly)\r
fprintf(stderr, "overall configuration is loadable, check console for non-fatal problems\n");\r
else {\r
+ // Init the listener.\r
+ ListenerService* listener = conf.getServiceProvider()->getListenerService();\r
+ if (!listener->init(unlink_socket)) {\r
+ fprintf(stderr, "listener failed to initialize\n");\r
+ conf.term();\r
+ return -3;\r
+ }\r
\r
- // Write the pid file\r
- if (pidfile) {\r
- FILE* pidf = fopen(pidfile, "w");\r
- if (pidf) {\r
- fprintf(pidf, "%d\n", getpid());\r
- fclose(pidf);\r
- } else {\r
- perror(pidfile); // keep running though\r
+ if (daemonize) {\r
+ if (setsid() == -1) {\r
+ perror("setsid");\r
+ exit(EXIT_FAILURE);\r
}\r
+ if (chdir("/") == -1) {\r
+ perror("chdir to root");\r
+ exit(EXIT_FAILURE);\r
+ }\r
+\r
+ if (pidfile) {\r
+ FILE* pidf = fopen(pidfile, "w");\r
+ if (pidf) {\r
+ fprintf(pidf, "%d\n", getpid());\r
+ fclose(pidf);\r
+ }\r
+ else {\r
+ perror(pidfile);\r
+ }\r
+ }\r
+\r
+ freopen("/dev/null", "r", stdin);\r
+ freopen("/dev/null", "w", stdout);\r
+ freopen("/dev/null", "w", stderr);\r
+\r
+ // Signal our parent that we are A-OK.\r
+ kill(getppid(), SIGUSR1);\r
}\r
\r
- // Run the listener\r
- if (!conf.getServiceProvider()->getListenerService()->run(&shibd_shutdown)) {\r
- fprintf(stderr, "listener failed to enter listen loop\n");\r
+ // Run the listener.\r
+ if (!listener->run(&shibd_shutdown)) {\r
+ fprintf(stderr, "listener failure during service\n");\r
+ listener->term();\r
+ conf.term();\r
+ if (pidfile)\r
+ unlink(pidfile);\r
return -3;\r
}\r
+ listener->term();\r
}\r
\r
conf.term();\r
//\r
\r
VS_VERSION_INFO VERSIONINFO\r
- FILEVERSION 2,1,0,0\r
- PRODUCTVERSION 2,1,0,0\r
+ FILEVERSION 2,2,1,0\r
+ PRODUCTVERSION 2,2,1,0\r
FILEFLAGSMASK 0x3fL\r
#ifdef _DEBUG\r
FILEFLAGS 0x1L\r
VALUE "Comments", "\0"\r
VALUE "CompanyName", "Internet2\0"\r
VALUE "FileDescription", "Shibboleth Daemon Service\0"\r
- VALUE "FileVersion", "2, 1, 0, 0\0"\r
+ VALUE "FileVersion", "2, 2, 1, 0\0"\r
VALUE "InternalName", "shibd\0"\r
- VALUE "LegalCopyright", "Copyright © 2008 Internet2\0"\r
+ VALUE "LegalCopyright", "Copyright © 2009 Internet2\0"\r
VALUE "LegalTrademarks", "\0"\r
VALUE "OriginalFilename", "shibd.exe\0"\r
VALUE "PrivateBuild", "\0"\r
- VALUE "ProductName", "Shibboleth 2.1\0"\r
- VALUE "ProductVersion", "2, 1, 0, 0\0"\r
+ VALUE "ProductName", "Shibboleth 2.2.1\0"\r
+ VALUE "ProductVersion", "2, 2, 1, 0\0"\r
VALUE "SpecialBuild", "\0"\r
END\r
END\r
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="9.00"
Name="shibd"
ProjectGUID="{F13141B5-6C87-40BB-8D4E-5CC56EBB4C59}"
RootNamespace="shibd"
+ TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="wsock32.lib log4shib1.lib xmltooling1.lib xerces-c_2.lib"
+ AdditionalDependencies="wsock32.lib log4shib1.lib xmltooling1.lib"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"
SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
/>
<Tool
Name="VCMIDLTool"
+ TargetEnvironment="3"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="0"
+ Optimization="2"
+ InlineFunctionExpansion="1"
AdditionalIncludeDirectories=".;..;"..\..\cpp-opensaml2";"..\..\cpp-xmltooling""
- PreprocessorDefinitions="_CONSOLE;WIN32;_DEBUG"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
RuntimeTypeInfo="true"
- BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
+ PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="wsock32.lib log4shib1D.lib xmltooling1D.lib"
- LinkIncremental="2"
+ AdditionalDependencies="wsock32.lib log4shib1.lib xmltooling1.lib"
+ LinkIncremental="1"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"
- GenerateDebugInformation="true"
+ AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"
SubSystem="1"
- TargetMachine="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Release|x64"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
/>
<Tool
Name="VCMIDLTool"
- TargetEnvironment="3"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
+ Optimization="0"
AdditionalIncludeDirectories=".;..;"..\..\cpp-opensaml2";"..\..\cpp-xmltooling""
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
- StringPooling="true"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
+ PreprocessorDefinitions="_CONSOLE;WIN32;_DEBUG"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
+ BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
+ PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="wsock32.lib log4shib1.lib xmltooling1.lib xerces-c_2.lib"
- LinkIncremental="1"
+ AdditionalDependencies="wsock32.lib log4shib1D.lib xmltooling1D.lib"
+ LinkIncremental="2"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"
+ AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"
+ GenerateDebugInformation="true"
SubSystem="1"
- TargetMachine="17"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"
GenerateDebugInformation="true"
SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
RequestMapper::Settings AbstractSPRequest::getRequestSettings() const
{
- if (m_mapper)
- return m_settings;
-
- // Map request to application and content settings.
- m_mapper=m_sp->getRequestMapper();
- m_mapper->lock();
- return m_settings = m_mapper->getSettings(*this);
-
+ if (!m_mapper) {
+ // Map request to application and content settings.
+ m_mapper=m_sp->getRequestMapper();
+ m_mapper->lock();
+ m_settings = m_mapper->getSettings(*this);
+
+ if (reinterpret_cast<Category*>(m_log)->isDebugEnabled()) {
+ reinterpret_cast<Category*>(m_log)->debug(
+ "mapped %s to %s", getRequestURL(), m_settings.first->getString("applicationId").second
+ );
+ }
+ }
+ return m_settings;
}
const Application& AbstractSPRequest::getApplication() const
// Now find the application from the URL settings
m_app=m_sp->getApplication(getRequestSettings().first->getString("applicationId").second);
if (!m_app)
- throw ConfigurationException("Unable to map request to application settings, check configuration.");
+ throw ConfigurationException("Unable to map request to ApplicationOverride settings, check configuration.");
}
return *m_app;
}
m_uri += uri;
break;
}
- else if (*uri == ';') {
- // If this is Java being stupid, skip everything up to the query string, if any.
- if (!strncmp(uri, ";jsessionid=", 12)) {
- if (uri = strchr(uri, '?'))
- m_uri += uri;
- break;
- }
- else {
- m_uri += *uri;
- }
- }
else if (*uri != '%') {
m_uri += *uri;
}
return m_url.c_str();
}
+string AbstractSPRequest::getRemoteAddr() const
+{
+ pair<bool,const char*> addr = getRequestSettings().first->getString("REMOTE_ADDR");
+ return addr.first ? getHeader(addr.second) : "";
+}
+
const char* AbstractSPRequest::getParameter(const char* name) const
{
if (!m_parser)
bool ssl_only=true;
const char* handler=NULL;
- const PropertySet* props=m_app->getPropertySet("Sessions");
+ const PropertySet* props=getApplication().getPropertySet("Sessions");
if (props) {
pair<bool,bool> p=props->getBool("handlerSSL");
if (p.first)
// Should never happen...
if (!handler || (*handler!='/' && strncmp(handler,"http:",5) && strncmp(handler,"https:",6)))
throw ConfigurationException(
- "Invalid handlerURL property ($1) in Application ($2)",
+ "Invalid handlerURL property ($1) in <Sessions> element for Application ($2)",
params(2, handler ? handler : "null", m_app->getId())
);
const char* getRequestURL() const;
+ std::string getRemoteAddr() const;
+
const char* getParameter(const char* name) const;
std::vector<const char*>::size_type getParameters(const char* name, std::vector<const char*>& values) const;
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* @file shibsp/AccessControl.h
- *
+ *
* Interface to an access control plugin
*/
/**
* Interface to an access control plugin
- *
+ *
* Access control plugins return authorization decisions based on the intersection
* of the resource request and the active session. They can be implemented through
* cross-platform or platform-specific mechanisms.
shib_acl_false,
shib_acl_indeterminate
};
-
+
/**
* Perform an authorization check.
- *
+ *
* @param request SP request information
* @param session active user session, if any
* @return true iff access should be granted
*/
void SHIBSP_API registerAccessControls();
+ /** Chains together multiple plugins. */
+ #define CHAINING_ACCESS_CONTROL "Chaining"
+
/** AccessControl based on rudimentary XML syntax. */
- #define XML_ACCESS_CONTROL "XML"
+ #define XML_ACCESS_CONTROL "XML"
/** Reserved for Apache-style .htaccess support. */
- #define HT_ACCESS_CONTROL "htaccess"
+ #define HT_ACCESS_CONTROL "htaccess"
};
#endif /* __shibsp_acl_h__ */
return pair<string,const char*>(prefix,defProps);
}
+void Application::clearHeader(SPRequest& request, const char* rawname, const char* cginame) const
+{
+ request.clearHeader(rawname, cginame);
+}
+
+void Application::setHeader(SPRequest& request, const char* name, const char* value) const
+{
+ request.setHeader(name, value);
+}
+
+string Application::getSecureHeader(const SPRequest& request, const char* name) const
+{
+ return request.getSecureHeader(name);
+}
+
void Application::clearAttributeHeaders(SPRequest& request) const
{
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* @file shibsp/Application.h
- *
+ *
* Interface to a Shibboleth Application instance.
*/
#include <xmltooling/util/Threads.h>
namespace shibsp {
-
+
#ifndef SHIBSP_LITE
class SHIBSP_API AttributeExtractor;
class SHIBSP_API AttributeFilter;
/**
* Interface to a Shibboleth Application instance.
- *
+ *
* <p>An Application is a logical set of resources that act as a unit
* of session management and policy.
*/
* @param sp parent ServiceProvider instance
*/
Application(const ServiceProvider* sp);
-
+
/** Pointer to parent SP instance. */
const ServiceProvider* m_sp;
/**
* Returns the Application's ID.
- *
+ *
* @return the ID
- */
+ */
virtual const char* getId() const {
return getString("id").second;
}
/**
* Returns a unique hash for the Application.
- *
+ *
* @return a value resulting from a computation over the Application's configuration
*/
virtual const char* getHash() const=0;
/**
* Returns the name and cookie properties to use for this Application.
- *
+ *
* @param prefix a value to prepend to the base cookie name
* @param lifetime if non-null, will be populated with a suggested lifetime for the cookie, or 0 if session-bound
* @return a pair containing the cookie name and the string to append to the cookie value
#ifndef SHIBSP_LITE
/**
* Returns a MetadataProvider for use with this Application.
- *
+ *
* @param required true iff an exception should be thrown if no MetadataProvider is available
* @return a MetadataProvider instance, or NULL
*/
virtual opensaml::saml2md::MetadataProvider* getMetadataProvider(bool required=true) const=0;
-
+
/**
* Returns a TrustEngine for use with this Application.
- *
+ *
* @param required true iff an exception should be thrown if no TrustEngine is available
* @return a TrustEngine instance, or NULL
*/
/**
* Returns an AttributeExtractor for use with this Application.
- *
+ *
* @return an AttributeExtractor, or NULL
*/
virtual AttributeExtractor* getAttributeExtractor() const=0;
/**
* Returns an AttributeFilter for use with this Application.
- *
+ *
* @return an AttributeFilter, or NULL
*/
virtual AttributeFilter* getAttributeFilter() const=0;
/**
* Returns an AttributeResolver for use with this Application.
- *
+ *
* @return an AttributeResolver, or NULL
*/
virtual AttributeResolver* getAttributeResolver() const=0;
/**
* Returns the CredentialResolver instance associated with this Application.
- *
+ *
* @return a CredentialResolver, or NULL
*/
virtual xmltooling::CredentialResolver* getCredentialResolver() const=0;
/**
* Returns configuration properties governing security interactions with a peer.
- *
+ *
* @param provider a peer entity's metadata
* @return the applicable PropertySet
*/
/**
* Returns configuration properties governing security interactions with a named peer.
- *
+ *
* @param entityID a peer name
* @return the applicable PropertySet
*/
virtual const PropertySet* getRelyingParty(const XMLCh* entityID) const=0;
/**
+ * @deprecated
* Returns any additional audience values associated with this Application.
- *
+ *
* @return additional audience values associated with the Application, or NULL
*/
virtual const std::vector<const XMLCh*>* getAudiences() const=0;
virtual const std::vector<std::string>& getRemoteUserAttributeIds() const=0;
/**
+ * Ensures no value exists for a request header, allowing for application-specific customization.
+ *
+ * @param request SP request to modify
+ * @param rawname raw name of header to clear
+ * @param cginame CGI-equivalent name of header, <strong>MUST</strong> begin with "HTTP_".
+ */
+ virtual void clearHeader(SPRequest& request, const char* rawname, const char* cginame) const;
+
+ /**
+ * Sets a value for a request header allowing for application-specific customization.
+ *
+ * @param request SP request to modify
+ * @param name name of header to set
+ * @param value value to set
+ */
+ virtual void setHeader(SPRequest& request, const char* name, const char* value) const;
+
+ /**
+ * Returns a non-spoofable request header value allowing for application-specific customization.
+ *
+ * @param request SP request to access
+ * @param name the name of the secure header to return
+ * @return the header's value, or an empty string
+ */
+ virtual std::string getSecureHeader(const SPRequest& request, const char* name) const;
+
+ /**
* Clears any headers that may be used to hold attributes after export.
*
* @param request SP request to clear
/**
* Returns the default SessionInitiator when automatically requesting a session.
- *
+ *
* @return the default SessionInitiator, or NULL
*/
virtual const SessionInitiator* getDefaultSessionInitiator() const=0;
-
+
/**
* Returns a SessionInitiator with a particular ID when automatically requesting a session.
- *
+ *
* @param id an identifier unique to the Application
* @return the designated SessionInitiator, or NULL
*/
/**
* Returns the default AssertionConsumerService Handler
* for use in AuthnRequest messages.
- *
+ *
* @return the default AssertionConsumerService, or NULL
*/
virtual const Handler* getDefaultAssertionConsumerService() const=0;
/**
* Returns an AssertionConsumerService Handler with a particular index
* for use in AuthnRequest messages.
- *
+ *
* @param index an index unique to an application
* @return the designated AssertionConsumerService, or NULL
*/
/**
* Returns one or more AssertionConsumerService Handlers that support
* a particular protocol binding.
- *
+ *
* @param binding a protocol binding identifier
* @return a set of qualifying AssertionConsumerServices
*/
virtual const std::vector<const Handler*>& getAssertionConsumerServicesByBinding(const XMLCh* binding) const=0;
-
+
/**
* Returns the Handler associated with a particular path/location.
- *
+ *
* @param path the PATH_INFO appended to the end of a base Handler location
* that invokes the Handler
- * @return the mapped Handler, or NULL
+ * @return the mapped Handler, or NULL
*/
virtual const Handler* getHandler(const char* path) const=0;
AUTOMAKE_OPTIONS = foreign
-pkgsysconfdir = $(sysconfdir)/@PACKAGE@
-pkgxmldir = $(datadir)/xml/@PACKAGE@
-
lib_LTLIBRARIES = libshibsp.la libshibsp-lite.la
libshibspincludedir = $(includedir)/shibsp
attrinclude_HEADERS = \
attribute/Attribute.h \
attribute/AttributeDecoder.h \
+ attribute/ExtensibleAttribute.h \
attribute/NameIDAttribute.h \
attribute/ScopedAttribute.h \
- attribute/SimpleAttribute.h
+ attribute/SimpleAttribute.h \
+ attribute/XMLAttribute.h
attrfiltinclude_HEADERS = \
attribute/filtering/AttributeFilter.h \
ServiceProvider.cpp \
SPConfig.cpp \
attribute/Attribute.cpp \
+ attribute/ExtensibleAttribute.cpp \
handler/impl/AbstractHandler.cpp \
handler/impl/AssertionConsumerService.cpp \
handler/impl/AssertionLookup.cpp \
handler/impl/Shib1SessionInitiator.cpp \
handler/impl/TransformSessionInitiator.cpp \
handler/impl/WAYFSessionInitiator.cpp \
+ impl/ChainingAccessControl.cpp \
impl/StorageServiceSessionCache.cpp \
impl/XMLAccessControl.cpp \
impl/XMLRequestMapper.cpp \
libshibsp_la_SOURCES = \
${common_sources} \
+ attribute/DOMAttributeDecoder.cpp \
+ attribute/KeyInfoAttributeDecoder.cpp \
attribute/NameIDAttributeDecoder.cpp \
attribute/NameIDFromScopedAttributeDecoder.cpp \
attribute/ScopedAttributeDecoder.cpp \
attribute/StringAttributeDecoder.cpp \
+ attribute/XMLAttributeDecoder.cpp \
attribute/filtering/impl/AttributeFilter.cpp \
attribute/filtering/impl/ChainingAttributeFilter.cpp \
attribute/filtering/impl/XMLAttributeFilter.cpp \
attribute/filtering/impl/AttributeScopeMatchesShibMDScopeFunctor.cpp \
attribute/resolver/impl/ChainingAttributeResolver.cpp \
attribute/resolver/impl/QueryAttributeResolver.cpp \
+ attribute/resolver/impl/SimpleAggregationAttributeResolver.cpp \
attribute/resolver/impl/ChainingAttributeExtractor.cpp \
+ attribute/resolver/impl/DelegationAttributeExtractor.cpp \
+ attribute/resolver/impl/KeyDescriptorAttributeExtractor.cpp \
attribute/resolver/impl/XMLAttributeExtractor.cpp \
binding/impl/ArtifactResolver.cpp \
binding/impl/SOAPClient.cpp \
# this is different from the project version
# http://sources.redhat.com/autobook/autobook/autobook_91.html
-libshibsp_la_LDFLAGS = $(XMLSEC_LIBS) -version-info 2:0:0
-libshibsp_lite_la_LDFLAGS = $(LITE_LIBS) -version-info 2:0:0
+libshibsp_la_LDFLAGS = $(XMLSEC_LIBS) -version-info 3:1:0
+libshibsp_lite_la_LDFLAGS = $(LITE_LIBS) -version-info 3:1:0
libshibsp_lite_la_CPPFLAGS = -DSHIBSP_LITE
+pkgsysconfdir = $(sysconfdir)/@PACKAGE@
+pkgxmldir = $(datadir)/xml/@PACKAGE@
+logdir = ${localstatedir}/log
+rundir = $(localstatedir)/run
+xmldir = $(datadir)/xml
+
paths.h: ${srcdir}/paths.h.in Makefile ${top_builddir}/config.status
rm -f $@.tmp
sed < ${srcdir}/$@.in > $@.tmp \
-e 's:@-PREFIX-@:${prefix}:g' \
+ -e 's:@-LIBDIR-@:${libdir}:g' \
+ -e 's:@-SYSCONFDIR-@:${sysconfdir}:g' \
+ -e 's:@-LOGDIR-@:${logdir}:g' \
+ -e 's:@-RUNDIR-@:${rundir}:g' \
+ -e 's:@-XMLDIR-@:${xmldir}:g' \
-e 's:@-PKGSYSCONFDIR-@:${pkgsysconfdir}:g' \
-e 's:@-PKGXMLDIR-@:${pkgxmldir}:g' \
-e 's:@-XMLTOOLINGXMLDIR-@:${XMLTOOLINGXMLDIR}:g' \
libshibsp_lite_la-Application.lo \
libshibsp_lite_la-ServiceProvider.lo \
libshibsp_lite_la-SPConfig.lo libshibsp_lite_la-Attribute.lo \
+ libshibsp_lite_la-ExtensibleAttribute.lo \
libshibsp_lite_la-AbstractHandler.lo \
libshibsp_lite_la-AssertionConsumerService.lo \
libshibsp_lite_la-AssertionLookup.lo \
libshibsp_lite_la-Shib1SessionInitiator.lo \
libshibsp_lite_la-TransformSessionInitiator.lo \
libshibsp_lite_la-WAYFSessionInitiator.lo \
+ libshibsp_lite_la-ChainingAccessControl.lo \
libshibsp_lite_la-StorageServiceSessionCache.lo \
libshibsp_lite_la-XMLAccessControl.lo \
libshibsp_lite_la-XMLRequestMapper.lo \
libshibsp_lite_la_OBJECTS = $(am_libshibsp_lite_la_OBJECTS)
libshibsp_la_LIBADD =
am__objects_2 = AbstractSPRequest.lo Application.lo ServiceProvider.lo \
- SPConfig.lo Attribute.lo AbstractHandler.lo \
- AssertionConsumerService.lo AssertionLookup.lo \
- ChainingLogoutInitiator.lo ChainingSessionInitiator.lo \
- CookieSessionInitiator.lo FormSessionInitiator.lo \
- LocalLogoutInitiator.lo LogoutHandler.lo MetadataGenerator.lo \
- RemotedHandler.lo StatusHandler.lo SessionHandler.lo \
- SAML1Consumer.lo SAML2Consumer.lo SAML2ArtifactResolution.lo \
- SAML2Logout.lo SAML2LogoutInitiator.lo SAML2NameIDMgmt.lo \
+ SPConfig.lo Attribute.lo ExtensibleAttribute.lo \
+ AbstractHandler.lo AssertionConsumerService.lo \
+ AssertionLookup.lo ChainingLogoutInitiator.lo \
+ ChainingSessionInitiator.lo CookieSessionInitiator.lo \
+ FormSessionInitiator.lo LocalLogoutInitiator.lo \
+ LogoutHandler.lo MetadataGenerator.lo RemotedHandler.lo \
+ StatusHandler.lo SessionHandler.lo SAML1Consumer.lo \
+ SAML2Consumer.lo SAML2ArtifactResolution.lo SAML2Logout.lo \
+ SAML2LogoutInitiator.lo SAML2NameIDMgmt.lo \
SAML2SessionInitiator.lo SAMLDSSessionInitiator.lo \
SessionInitiator.lo Shib1SessionInitiator.lo \
TransformSessionInitiator.lo WAYFSessionInitiator.lo \
- StorageServiceSessionCache.lo XMLAccessControl.lo \
- XMLRequestMapper.lo XMLServiceProvider.lo ddf.lo \
- ListenerService.lo SocketListener.lo TCPListener.lo \
+ ChainingAccessControl.lo StorageServiceSessionCache.lo \
+ XMLAccessControl.lo XMLRequestMapper.lo XMLServiceProvider.lo \
+ ddf.lo ListenerService.lo SocketListener.lo TCPListener.lo \
UnixListener.lo CGIParser.lo DOMPropertySet.lo SPConstants.lo \
TemplateParameters.lo
-am_libshibsp_la_OBJECTS = $(am__objects_2) NameIDAttributeDecoder.lo \
+am_libshibsp_la_OBJECTS = $(am__objects_2) DOMAttributeDecoder.lo \
+ KeyInfoAttributeDecoder.lo NameIDAttributeDecoder.lo \
NameIDFromScopedAttributeDecoder.lo ScopedAttributeDecoder.lo \
- StringAttributeDecoder.lo AttributeFilter.lo \
- ChainingAttributeFilter.lo XMLAttributeFilter.lo \
- MatchFunctor.lo AndMatchFunctor.lo AnyMatchFunctor.lo \
- NotMatchFunctor.lo OrMatchFunctor.lo \
+ StringAttributeDecoder.lo XMLAttributeDecoder.lo \
+ AttributeFilter.lo ChainingAttributeFilter.lo \
+ XMLAttributeFilter.lo MatchFunctor.lo AndMatchFunctor.lo \
+ AnyMatchFunctor.lo NotMatchFunctor.lo OrMatchFunctor.lo \
AttributeIssuerStringFunctor.lo \
AttributeRequesterStringFunctor.lo \
AttributeScopeStringFunctor.lo AttributeValueStringFunctor.lo \
AttributeRequesterInEntityGroupFunctor.lo \
AttributeScopeMatchesShibMDScopeFunctor.lo \
ChainingAttributeResolver.lo QueryAttributeResolver.lo \
- ChainingAttributeExtractor.lo XMLAttributeExtractor.lo \
+ SimpleAggregationAttributeResolver.lo \
+ ChainingAttributeExtractor.lo DelegationAttributeExtractor.lo \
+ KeyDescriptorAttributeExtractor.lo XMLAttributeExtractor.lo \
ArtifactResolver.lo SOAPClient.lo DynamicMetadataProvider.lo \
MetadataExtImpl.lo MetadataExtSchemaValidators.lo \
PKIXTrustEngine.lo SecurityPolicy.lo
target_alias = @target_alias@
xs = @xs@
AUTOMAKE_OPTIONS = foreign
-pkgsysconfdir = $(sysconfdir)/@PACKAGE@
-pkgxmldir = $(datadir)/xml/@PACKAGE@
lib_LTLIBRARIES = libshibsp.la libshibsp-lite.la
libshibspincludedir = $(includedir)/shibsp
attrincludedir = $(includedir)/shibsp/attribute
attrinclude_HEADERS = \
attribute/Attribute.h \
attribute/AttributeDecoder.h \
+ attribute/ExtensibleAttribute.h \
attribute/NameIDAttribute.h \
attribute/ScopedAttribute.h \
- attribute/SimpleAttribute.h
+ attribute/SimpleAttribute.h \
+ attribute/XMLAttribute.h
attrfiltinclude_HEADERS = \
attribute/filtering/AttributeFilter.h \
ServiceProvider.cpp \
SPConfig.cpp \
attribute/Attribute.cpp \
+ attribute/ExtensibleAttribute.cpp \
handler/impl/AbstractHandler.cpp \
handler/impl/AssertionConsumerService.cpp \
handler/impl/AssertionLookup.cpp \
handler/impl/Shib1SessionInitiator.cpp \
handler/impl/TransformSessionInitiator.cpp \
handler/impl/WAYFSessionInitiator.cpp \
+ impl/ChainingAccessControl.cpp \
impl/StorageServiceSessionCache.cpp \
impl/XMLAccessControl.cpp \
impl/XMLRequestMapper.cpp \
libshibsp_la_SOURCES = \
${common_sources} \
+ attribute/DOMAttributeDecoder.cpp \
+ attribute/KeyInfoAttributeDecoder.cpp \
attribute/NameIDAttributeDecoder.cpp \
attribute/NameIDFromScopedAttributeDecoder.cpp \
attribute/ScopedAttributeDecoder.cpp \
attribute/StringAttributeDecoder.cpp \
+ attribute/XMLAttributeDecoder.cpp \
attribute/filtering/impl/AttributeFilter.cpp \
attribute/filtering/impl/ChainingAttributeFilter.cpp \
attribute/filtering/impl/XMLAttributeFilter.cpp \
attribute/filtering/impl/AttributeScopeMatchesShibMDScopeFunctor.cpp \
attribute/resolver/impl/ChainingAttributeResolver.cpp \
attribute/resolver/impl/QueryAttributeResolver.cpp \
+ attribute/resolver/impl/SimpleAggregationAttributeResolver.cpp \
attribute/resolver/impl/ChainingAttributeExtractor.cpp \
+ attribute/resolver/impl/DelegationAttributeExtractor.cpp \
+ attribute/resolver/impl/KeyDescriptorAttributeExtractor.cpp \
attribute/resolver/impl/XMLAttributeExtractor.cpp \
binding/impl/ArtifactResolver.cpp \
binding/impl/SOAPClient.cpp \
# this is different from the project version
# http://sources.redhat.com/autobook/autobook/autobook_91.html
-libshibsp_la_LDFLAGS = $(XMLSEC_LIBS) -version-info 2:0:0
-libshibsp_lite_la_LDFLAGS = $(LITE_LIBS) -version-info 2:0:0
+libshibsp_la_LDFLAGS = $(XMLSEC_LIBS) -version-info 3:1:0
+libshibsp_lite_la_LDFLAGS = $(LITE_LIBS) -version-info 3:1:0
libshibsp_lite_la_CPPFLAGS = -DSHIBSP_LITE
+pkgsysconfdir = $(sysconfdir)/@PACKAGE@
+pkgxmldir = $(datadir)/xml/@PACKAGE@
+logdir = ${localstatedir}/log
+rundir = $(localstatedir)/run
+xmldir = $(datadir)/xml
EXTRA_DIST = shibsp.vcproj shibsp-lite.vcproj paths.h.in resource.h shibsp.rc
BUILT_SOURCES = paths.h
all: $(BUILT_SOURCES)
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthenticationMethodRegexFunctor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthenticationMethodStringFunctor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CGIParser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChainingAccessControl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChainingAttributeExtractor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChainingAttributeFilter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChainingAttributeResolver.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChainingLogoutInitiator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChainingSessionInitiator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieSessionInitiator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DOMAttributeDecoder.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DOMPropertySet.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DelegationAttributeExtractor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DynamicMetadataProvider.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ExtensibleAttribute.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FormSessionInitiator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/KeyDescriptorAttributeExtractor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/KeyInfoAttributeDecoder.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ListenerService.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LocalLogoutInitiator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogoutHandler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SessionHandler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SessionInitiator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Shib1SessionInitiator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleAggregationAttributeResolver.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SocketListener.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StatusHandler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StorageServiceSessionCache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnixListener.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WAYFSessionInitiator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLAccessControl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLAttributeDecoder.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLAttributeExtractor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLAttributeFilter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLRequestMapper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-AssertionLookup.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-Attribute.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-CGIParser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-ChainingAccessControl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-ChainingLogoutInitiator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-ChainingSessionInitiator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-CommonDomainCookie.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-CookieSessionInitiator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-DOMPropertySet.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-ExtensibleAttribute.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-FormSessionInitiator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-ListenerService.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshibsp_lite_la-LocalLogoutInitiator.Plo@am__quote@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libshibsp_lite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libshibsp_lite_la-Attribute.lo `test -f 'attribute/Attribute.cpp' || echo '$(srcdir)/'`attribute/Attribute.cpp
+libshibsp_lite_la-ExtensibleAttribute.lo: attribute/ExtensibleAttribute.cpp
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libshibsp_lite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libshibsp_lite_la-ExtensibleAttribute.lo -MD -MP -MF "$(DEPDIR)/libshibsp_lite_la-ExtensibleAttribute.Tpo" -c -o libshibsp_lite_la-ExtensibleAttribute.lo `test -f 'attribute/ExtensibleAttribute.cpp' || echo '$(srcdir)/'`attribute/ExtensibleAttribute.cpp; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libshibsp_lite_la-ExtensibleAttribute.Tpo" "$(DEPDIR)/libshibsp_lite_la-ExtensibleAttribute.Plo"; else rm -f "$(DEPDIR)/libshibsp_lite_la-ExtensibleAttribute.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='attribute/ExtensibleAttribute.cpp' object='libshibsp_lite_la-ExtensibleAttribute.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libshibsp_lite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libshibsp_lite_la-ExtensibleAttribute.lo `test -f 'attribute/ExtensibleAttribute.cpp' || echo '$(srcdir)/'`attribute/ExtensibleAttribute.cpp
+
libshibsp_lite_la-AbstractHandler.lo: handler/impl/AbstractHandler.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libshibsp_lite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libshibsp_lite_la-AbstractHandler.lo -MD -MP -MF "$(DEPDIR)/libshibsp_lite_la-AbstractHandler.Tpo" -c -o libshibsp_lite_la-AbstractHandler.lo `test -f 'handler/impl/AbstractHandler.cpp' || echo '$(srcdir)/'`handler/impl/AbstractHandler.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libshibsp_lite_la-AbstractHandler.Tpo" "$(DEPDIR)/libshibsp_lite_la-AbstractHandler.Plo"; else rm -f "$(DEPDIR)/libshibsp_lite_la-AbstractHandler.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libshibsp_lite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libshibsp_lite_la-WAYFSessionInitiator.lo `test -f 'handler/impl/WAYFSessionInitiator.cpp' || echo '$(srcdir)/'`handler/impl/WAYFSessionInitiator.cpp
+libshibsp_lite_la-ChainingAccessControl.lo: impl/ChainingAccessControl.cpp
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libshibsp_lite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libshibsp_lite_la-ChainingAccessControl.lo -MD -MP -MF "$(DEPDIR)/libshibsp_lite_la-ChainingAccessControl.Tpo" -c -o libshibsp_lite_la-ChainingAccessControl.lo `test -f 'impl/ChainingAccessControl.cpp' || echo '$(srcdir)/'`impl/ChainingAccessControl.cpp; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libshibsp_lite_la-ChainingAccessControl.Tpo" "$(DEPDIR)/libshibsp_lite_la-ChainingAccessControl.Plo"; else rm -f "$(DEPDIR)/libshibsp_lite_la-ChainingAccessControl.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='impl/ChainingAccessControl.cpp' object='libshibsp_lite_la-ChainingAccessControl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libshibsp_lite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libshibsp_lite_la-ChainingAccessControl.lo `test -f 'impl/ChainingAccessControl.cpp' || echo '$(srcdir)/'`impl/ChainingAccessControl.cpp
+
libshibsp_lite_la-StorageServiceSessionCache.lo: impl/StorageServiceSessionCache.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libshibsp_lite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libshibsp_lite_la-StorageServiceSessionCache.lo -MD -MP -MF "$(DEPDIR)/libshibsp_lite_la-StorageServiceSessionCache.Tpo" -c -o libshibsp_lite_la-StorageServiceSessionCache.lo `test -f 'impl/StorageServiceSessionCache.cpp' || echo '$(srcdir)/'`impl/StorageServiceSessionCache.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libshibsp_lite_la-StorageServiceSessionCache.Tpo" "$(DEPDIR)/libshibsp_lite_la-StorageServiceSessionCache.Plo"; else rm -f "$(DEPDIR)/libshibsp_lite_la-StorageServiceSessionCache.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Attribute.lo `test -f 'attribute/Attribute.cpp' || echo '$(srcdir)/'`attribute/Attribute.cpp
+ExtensibleAttribute.lo: attribute/ExtensibleAttribute.cpp
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ExtensibleAttribute.lo -MD -MP -MF "$(DEPDIR)/ExtensibleAttribute.Tpo" -c -o ExtensibleAttribute.lo `test -f 'attribute/ExtensibleAttribute.cpp' || echo '$(srcdir)/'`attribute/ExtensibleAttribute.cpp; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/ExtensibleAttribute.Tpo" "$(DEPDIR)/ExtensibleAttribute.Plo"; else rm -f "$(DEPDIR)/ExtensibleAttribute.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='attribute/ExtensibleAttribute.cpp' object='ExtensibleAttribute.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ExtensibleAttribute.lo `test -f 'attribute/ExtensibleAttribute.cpp' || echo '$(srcdir)/'`attribute/ExtensibleAttribute.cpp
+
AbstractHandler.lo: handler/impl/AbstractHandler.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT AbstractHandler.lo -MD -MP -MF "$(DEPDIR)/AbstractHandler.Tpo" -c -o AbstractHandler.lo `test -f 'handler/impl/AbstractHandler.cpp' || echo '$(srcdir)/'`handler/impl/AbstractHandler.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/AbstractHandler.Tpo" "$(DEPDIR)/AbstractHandler.Plo"; else rm -f "$(DEPDIR)/AbstractHandler.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o WAYFSessionInitiator.lo `test -f 'handler/impl/WAYFSessionInitiator.cpp' || echo '$(srcdir)/'`handler/impl/WAYFSessionInitiator.cpp
+ChainingAccessControl.lo: impl/ChainingAccessControl.cpp
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ChainingAccessControl.lo -MD -MP -MF "$(DEPDIR)/ChainingAccessControl.Tpo" -c -o ChainingAccessControl.lo `test -f 'impl/ChainingAccessControl.cpp' || echo '$(srcdir)/'`impl/ChainingAccessControl.cpp; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/ChainingAccessControl.Tpo" "$(DEPDIR)/ChainingAccessControl.Plo"; else rm -f "$(DEPDIR)/ChainingAccessControl.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='impl/ChainingAccessControl.cpp' object='ChainingAccessControl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ChainingAccessControl.lo `test -f 'impl/ChainingAccessControl.cpp' || echo '$(srcdir)/'`impl/ChainingAccessControl.cpp
+
StorageServiceSessionCache.lo: impl/StorageServiceSessionCache.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT StorageServiceSessionCache.lo -MD -MP -MF "$(DEPDIR)/StorageServiceSessionCache.Tpo" -c -o StorageServiceSessionCache.lo `test -f 'impl/StorageServiceSessionCache.cpp' || echo '$(srcdir)/'`impl/StorageServiceSessionCache.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/StorageServiceSessionCache.Tpo" "$(DEPDIR)/StorageServiceSessionCache.Plo"; else rm -f "$(DEPDIR)/StorageServiceSessionCache.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o TemplateParameters.lo `test -f 'util/TemplateParameters.cpp' || echo '$(srcdir)/'`util/TemplateParameters.cpp
+DOMAttributeDecoder.lo: attribute/DOMAttributeDecoder.cpp
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT DOMAttributeDecoder.lo -MD -MP -MF "$(DEPDIR)/DOMAttributeDecoder.Tpo" -c -o DOMAttributeDecoder.lo `test -f 'attribute/DOMAttributeDecoder.cpp' || echo '$(srcdir)/'`attribute/DOMAttributeDecoder.cpp; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/DOMAttributeDecoder.Tpo" "$(DEPDIR)/DOMAttributeDecoder.Plo"; else rm -f "$(DEPDIR)/DOMAttributeDecoder.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='attribute/DOMAttributeDecoder.cpp' object='DOMAttributeDecoder.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o DOMAttributeDecoder.lo `test -f 'attribute/DOMAttributeDecoder.cpp' || echo '$(srcdir)/'`attribute/DOMAttributeDecoder.cpp
+
+KeyInfoAttributeDecoder.lo: attribute/KeyInfoAttributeDecoder.cpp
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT KeyInfoAttributeDecoder.lo -MD -MP -MF "$(DEPDIR)/KeyInfoAttributeDecoder.Tpo" -c -o KeyInfoAttributeDecoder.lo `test -f 'attribute/KeyInfoAttributeDecoder.cpp' || echo '$(srcdir)/'`attribute/KeyInfoAttributeDecoder.cpp; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/KeyInfoAttributeDecoder.Tpo" "$(DEPDIR)/KeyInfoAttributeDecoder.Plo"; else rm -f "$(DEPDIR)/KeyInfoAttributeDecoder.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='attribute/KeyInfoAttributeDecoder.cpp' object='KeyInfoAttributeDecoder.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o KeyInfoAttributeDecoder.lo `test -f 'attribute/KeyInfoAttributeDecoder.cpp' || echo '$(srcdir)/'`attribute/KeyInfoAttributeDecoder.cpp
+
NameIDAttributeDecoder.lo: attribute/NameIDAttributeDecoder.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT NameIDAttributeDecoder.lo -MD -MP -MF "$(DEPDIR)/NameIDAttributeDecoder.Tpo" -c -o NameIDAttributeDecoder.lo `test -f 'attribute/NameIDAttributeDecoder.cpp' || echo '$(srcdir)/'`attribute/NameIDAttributeDecoder.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/NameIDAttributeDecoder.Tpo" "$(DEPDIR)/NameIDAttributeDecoder.Plo"; else rm -f "$(DEPDIR)/NameIDAttributeDecoder.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o StringAttributeDecoder.lo `test -f 'attribute/StringAttributeDecoder.cpp' || echo '$(srcdir)/'`attribute/StringAttributeDecoder.cpp
+XMLAttributeDecoder.lo: attribute/XMLAttributeDecoder.cpp
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT XMLAttributeDecoder.lo -MD -MP -MF "$(DEPDIR)/XMLAttributeDecoder.Tpo" -c -o XMLAttributeDecoder.lo `test -f 'attribute/XMLAttributeDecoder.cpp' || echo '$(srcdir)/'`attribute/XMLAttributeDecoder.cpp; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/XMLAttributeDecoder.Tpo" "$(DEPDIR)/XMLAttributeDecoder.Plo"; else rm -f "$(DEPDIR)/XMLAttributeDecoder.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='attribute/XMLAttributeDecoder.cpp' object='XMLAttributeDecoder.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o XMLAttributeDecoder.lo `test -f 'attribute/XMLAttributeDecoder.cpp' || echo '$(srcdir)/'`attribute/XMLAttributeDecoder.cpp
+
AttributeFilter.lo: attribute/filtering/impl/AttributeFilter.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT AttributeFilter.lo -MD -MP -MF "$(DEPDIR)/AttributeFilter.Tpo" -c -o AttributeFilter.lo `test -f 'attribute/filtering/impl/AttributeFilter.cpp' || echo '$(srcdir)/'`attribute/filtering/impl/AttributeFilter.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/AttributeFilter.Tpo" "$(DEPDIR)/AttributeFilter.Plo"; else rm -f "$(DEPDIR)/AttributeFilter.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o QueryAttributeResolver.lo `test -f 'attribute/resolver/impl/QueryAttributeResolver.cpp' || echo '$(srcdir)/'`attribute/resolver/impl/QueryAttributeResolver.cpp
+SimpleAggregationAttributeResolver.lo: attribute/resolver/impl/SimpleAggregationAttributeResolver.cpp
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT SimpleAggregationAttributeResolver.lo -MD -MP -MF "$(DEPDIR)/SimpleAggregationAttributeResolver.Tpo" -c -o SimpleAggregationAttributeResolver.lo `test -f 'attribute/resolver/impl/SimpleAggregationAttributeResolver.cpp' || echo '$(srcdir)/'`attribute/resolver/impl/SimpleAggregationAttributeResolver.cpp; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/SimpleAggregationAttributeResolver.Tpo" "$(DEPDIR)/SimpleAggregationAttributeResolver.Plo"; else rm -f "$(DEPDIR)/SimpleAggregationAttributeResolver.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='attribute/resolver/impl/SimpleAggregationAttributeResolver.cpp' object='SimpleAggregationAttributeResolver.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o SimpleAggregationAttributeResolver.lo `test -f 'attribute/resolver/impl/SimpleAggregationAttributeResolver.cpp' || echo '$(srcdir)/'`attribute/resolver/impl/SimpleAggregationAttributeResolver.cpp
+
ChainingAttributeExtractor.lo: attribute/resolver/impl/ChainingAttributeExtractor.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ChainingAttributeExtractor.lo -MD -MP -MF "$(DEPDIR)/ChainingAttributeExtractor.Tpo" -c -o ChainingAttributeExtractor.lo `test -f 'attribute/resolver/impl/ChainingAttributeExtractor.cpp' || echo '$(srcdir)/'`attribute/resolver/impl/ChainingAttributeExtractor.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/ChainingAttributeExtractor.Tpo" "$(DEPDIR)/ChainingAttributeExtractor.Plo"; else rm -f "$(DEPDIR)/ChainingAttributeExtractor.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ChainingAttributeExtractor.lo `test -f 'attribute/resolver/impl/ChainingAttributeExtractor.cpp' || echo '$(srcdir)/'`attribute/resolver/impl/ChainingAttributeExtractor.cpp
+DelegationAttributeExtractor.lo: attribute/resolver/impl/DelegationAttributeExtractor.cpp
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT DelegationAttributeExtractor.lo -MD -MP -MF "$(DEPDIR)/DelegationAttributeExtractor.Tpo" -c -o DelegationAttributeExtractor.lo `test -f 'attribute/resolver/impl/DelegationAttributeExtractor.cpp' || echo '$(srcdir)/'`attribute/resolver/impl/DelegationAttributeExtractor.cpp; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/DelegationAttributeExtractor.Tpo" "$(DEPDIR)/DelegationAttributeExtractor.Plo"; else rm -f "$(DEPDIR)/DelegationAttributeExtractor.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='attribute/resolver/impl/DelegationAttributeExtractor.cpp' object='DelegationAttributeExtractor.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o DelegationAttributeExtractor.lo `test -f 'attribute/resolver/impl/DelegationAttributeExtractor.cpp' || echo '$(srcdir)/'`attribute/resolver/impl/DelegationAttributeExtractor.cpp
+
+KeyDescriptorAttributeExtractor.lo: attribute/resolver/impl/KeyDescriptorAttributeExtractor.cpp
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT KeyDescriptorAttributeExtractor.lo -MD -MP -MF "$(DEPDIR)/KeyDescriptorAttributeExtractor.Tpo" -c -o KeyDescriptorAttributeExtractor.lo `test -f 'attribute/resolver/impl/KeyDescriptorAttributeExtractor.cpp' || echo '$(srcdir)/'`attribute/resolver/impl/KeyDescriptorAttributeExtractor.cpp; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/KeyDescriptorAttributeExtractor.Tpo" "$(DEPDIR)/KeyDescriptorAttributeExtractor.Plo"; else rm -f "$(DEPDIR)/KeyDescriptorAttributeExtractor.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='attribute/resolver/impl/KeyDescriptorAttributeExtractor.cpp' object='KeyDescriptorAttributeExtractor.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o KeyDescriptorAttributeExtractor.lo `test -f 'attribute/resolver/impl/KeyDescriptorAttributeExtractor.cpp' || echo '$(srcdir)/'`attribute/resolver/impl/KeyDescriptorAttributeExtractor.cpp
+
XMLAttributeExtractor.lo: attribute/resolver/impl/XMLAttributeExtractor.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT XMLAttributeExtractor.lo -MD -MP -MF "$(DEPDIR)/XMLAttributeExtractor.Tpo" -c -o XMLAttributeExtractor.lo `test -f 'attribute/resolver/impl/XMLAttributeExtractor.cpp' || echo '$(srcdir)/'`attribute/resolver/impl/XMLAttributeExtractor.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/XMLAttributeExtractor.Tpo" "$(DEPDIR)/XMLAttributeExtractor.Plo"; else rm -f "$(DEPDIR)/XMLAttributeExtractor.Tpo"; exit 1; fi
rm -f $@.tmp
sed < ${srcdir}/$@.in > $@.tmp \
-e 's:@-PREFIX-@:${prefix}:g' \
+ -e 's:@-LIBDIR-@:${libdir}:g' \
+ -e 's:@-SYSCONFDIR-@:${sysconfdir}:g' \
+ -e 's:@-LOGDIR-@:${logdir}:g' \
+ -e 's:@-RUNDIR-@:${rundir}:g' \
+ -e 's:@-XMLDIR-@:${xmldir}:g' \
-e 's:@-PKGSYSCONFDIR-@:${pkgsysconfdir}:g' \
-e 's:@-PKGXMLDIR-@:${pkgxmldir}:g' \
-e 's:@-XMLTOOLINGXMLDIR-@:${XMLTOOLINGXMLDIR}:g' \
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
# include "metadata/MetadataExt.h"
# include "security/PKIXTrustEngine.h"
# include <saml/SAMLConfig.h>
-# include <xmltooling/util/CurlNetAccessor.hpp>
#else
# include <xmltooling/XMLToolingConfig.h>
#endif
std::string ll(loglevel);
PathResolver localpr;
localpr.setDefaultPrefix(inst_prefix2.c_str());
+ inst_prefix = getenv("SHIBSP_CFGDIR");
+ if (!inst_prefix)
+ inst_prefix = SHIBSP_CFGDIR;
+ localpr.setCfgDir(inst_prefix);
XMLToolingConfig::getConfig().log_config(localpr.resolve(ll, PathResolver::XMLTOOLING_CFG_FILE, PACKAGE_NAME).c_str());
Category& log=Category::getInstance(SHIBSP_LOGCAT".Config");
log.fatal("failed to initialize OpenSAML library");
return false;
}
- XMLPlatformUtils::fgNetAccessor = new CurlNetAccessor();
#else
if (!XMLToolingConfig::getConfig().init()) {
log.fatal("failed to initialize XMLTooling library");
return false;
}
#endif
- XMLToolingConfig::getConfig().getPathResolver()->setDefaultPackageName(PACKAGE_NAME);
- XMLToolingConfig::getConfig().getPathResolver()->setDefaultPrefix(inst_prefix2.c_str());
+ PathResolver* pr = XMLToolingConfig::getConfig().getPathResolver();
+ pr->setDefaultPackageName(PACKAGE_NAME);
+ pr->setDefaultPrefix(inst_prefix2.c_str());
+ pr->setCfgDir(inst_prefix);
+ inst_prefix = getenv("SHIBSP_LIBDIR");
+ if (!inst_prefix)
+ inst_prefix = SHIBSP_LIBDIR;
+ pr->setLibDir(inst_prefix);
+ inst_prefix = getenv("SHIBSP_LOGDIR");
+ if (!inst_prefix)
+ inst_prefix = SHIBSP_LOGDIR;
+ pr->setLogDir(inst_prefix);
+ inst_prefix = getenv("SHIBSP_RUNDIR");
+ if (!inst_prefix)
+ inst_prefix = SHIBSP_RUNDIR;
+ pr->setRunDir(inst_prefix);
+ inst_prefix = getenv("SHIBSP_XMLDIR");
+ if (!inst_prefix)
+ inst_prefix = SHIBSP_XMLDIR;
+ pr->setXMLDir(inst_prefix);
+
XMLToolingConfig::getConfig().setTemplateEngine(new TemplateEngine());
XMLToolingConfig::getConfig().getTemplateEngine()->setTagPrefix("shibmlp");
log.info("%s library shutting down", PACKAGE_STRING);
setServiceProvider(NULL);
+ if (m_configDoc)
+ m_configDoc->release();
+ m_configDoc = NULL;
#ifndef SHIBSP_LITE
setArtifactResolver(NULL);
#endif
dummydoc = XMLToolingConfig::getConfig().getParser().parse(snippet);
XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);
setServiceProvider(ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER, dummydoc->getDocumentElement()));
+ if (m_configDoc)
+ m_configDoc->release();
+ m_configDoc = docjanitor.release();
}
else {
stringstream snippet(config);
setServiceProvider(ServiceProviderManager.newPlugin(type.get(), dummydoc->getDocumentElement()));
else
throw ConfigurationException("The supplied XML bootstrapping configuration did not include a type attribute.");
+ if (m_configDoc)
+ m_configDoc->release();
+ m_configDoc = docjanitor.release();
}
getServiceProvider()->init();
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#ifndef SHIBSP_LITE
m_artifactResolver(NULL),
#endif
- m_features(0) {}
+ m_features(0), m_configDoc(NULL) {
+ }
virtual ~SPConfig() {}
*
* @return global ArtifactResolver or NULL
*/
- opensaml::MessageDecoder::ArtifactResolver* getArtifactResolver() const {
+ const opensaml::MessageDecoder::ArtifactResolver* getArtifactResolver() const {
return m_artifactResolver;
}
#endif
private:
unsigned long m_features;
+ xercesc::DOMDocument* m_configDoc;
};
#if defined (_MSC_VER)
/*
* Copyright 2001-2007 Internet2
- *
+ *
* 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
/**
* @file shibsp/SPRequest.h
- *
- * Interface to server request being processed
+ *
+ * Interface to server request being processed
*/
#ifndef __shibsp_req_h__
#include <xmltooling/io/HTTPResponse.h>
namespace shibsp {
-
+
class SHIBSP_API Application;
class SHIBSP_API ServiceProvider;
class SHIBSP_API Session;
-
+
/**
* Interface to server request being processed
- *
+ *
* <p>To supply information from the surrounding web server environment,
* a shim must be supplied in the form of this interface to adapt the
* library to different proprietary server APIs.
- *
+ *
* <p>This interface need not be threadsafe.
*/
class SHIBSP_API SPRequest : public virtual xmltooling::HTTPRequest, public virtual xmltooling::HTTPResponse
SPRequest() {}
public:
virtual ~SPRequest() {}
-
+
/**
* Returns the locked ServiceProvider processing the request.
- *
+ *
* @return reference to ServiceProvider
*/
virtual const ServiceProvider& getServiceProvider() const=0;
/**
* Returns RequestMapper Settings associated with the request, guaranteed
* to be valid for the request's duration.
- *
+ *
* @return copy of settings
*/
virtual RequestMapper::Settings getRequestSettings() const=0;
-
+
/**
* Returns the Application governing the request.
- *
+ *
* @return reference to Application
*/
virtual const Application& getApplication() const=0;
/**
* Returns the effective base Handler URL for a resource,
* or the current request URL.
- *
+ *
* @param resource resource URL to compute handler for
* @return base location of handler
*/
* Returns a non-spoofable request header value, if possible.
* Platforms that support environment export can redirect header
* lookups by overriding this method.
- *
+ *
* @param name the name of the secure header to return
* @return the header's value, or an empty string
*/
/**
* Ensures no value exists for a request header.
- *
+ *
* @param rawname raw name of header to clear
* @param cginame CGI-equivalent name of header
*/
/**
* Sets a value for a request header.
- *
+ *
* @param name name of header to set
* @param value value to set
*/
/**
* Establish REMOTE_USER identity in request.
- *
+ *
* @param user REMOTE_USER value to set or NULL to clear
*/
virtual void setRemoteUser(const char* user)=0;
-
+
+ /**
+ * Establish AUTH_TYPE for request.
+ *
+ * @param authtype AUTH_TYPE value to set or NULL to clear
+ */
+ virtual void setAuthType(const char* authtype) {
+ }
+
/** Portable logging levels. */
enum SPLogLevel {
SPDebug,
/**
* Log to native server environment.
- *
+ *
* @param level logging level
* @param msg message to log
*/
/**
* Test logging level.
- *
+ *
* @param level logging level
* @return true iff logging level is enabled
*/
/**
* Indicates that processing was declined, meaning no action is required during this phase of processing.
- *
+ *
* @return a status code to pass back to the server-specific layer
- */
+ */
virtual long returnDecline()=0;
/**
* Indicates that processing was completed.
- *
+ *
* @return a status code to pass back to the server-specific layer
- */
+ */
virtual long returnOK()=0;
};
};
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
bool mderror = dynamic_cast<const opensaml::saml2md::MetadataException*>(tp.getRichException())!=NULL;
pair<bool,const char*> redirectErrors = pair<bool,const char*>(false,NULL);
pair<bool,const char*> pathname = pair<bool,const char*>(false,NULL);
- const PropertySet* props=app ? app->getPropertySet("Errors") : NULL;
+
+ // Strictly for error handling, detect a NULL application and point at the default.
+ if (!app)
+ app = request.getServiceProvider().getApplication("default");
+
+ const PropertySet* props=app->getPropertySet("Errors");
try {
RequestMapper::Settings settings = request.getRequestSettings();
tp.setPropertySet(props);
stringstream str;
XMLToolingConfig::getConfig().getTemplateEngine()->run(infile, str, tp, tp.getRichException());
- return request.sendResponse(str);
+ return request.sendError(str);
}
}
if (!strcmp(page,"access")) {
istringstream msg("Access Denied");
- return request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_UNAUTHORIZED);
+ return request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN);
}
log.error("sendError could not process error template (%s)", page);
}
void SHIBSP_DLLLOCAL clearHeaders(SPRequest& request) {
- request.clearHeader("Shib-Session-ID", "HTTP_SHIB_SESSION_ID");
- request.clearHeader("Shib-Identity-Provider", "HTTP_SHIB_IDENTITY_PROVIDER");
- request.clearHeader("Shib-Authentication-Method", "HTTP_SHIB_AUTHENTICATION_METHOD");
- request.clearHeader("Shib-Authentication-Instant", "HTTP_SHIB_AUTHENTICATION_INSTANT");
- request.clearHeader("Shib-AuthnContext-Class", "HTTP_SHIB_AUTHNCONTEXT_CLASS");
- request.clearHeader("Shib-AuthnContext-Decl", "HTTP_SHIB_AUTHNCONTEXT_DECL");
- request.clearHeader("Shib-Assertion-Count", "HTTP_SHIB_ASSERTION_COUNT");
+ const Application& app = request.getApplication();
+ app.clearHeader(request, "Shib-Session-ID", "HTTP_SHIB_SESSION_ID");
+ app.clearHeader(request, "Shib-Identity-Provider", "HTTP_SHIB_IDENTITY_PROVIDER");
+ app.clearHeader(request, "Shib-Authentication-Method", "HTTP_SHIB_AUTHENTICATION_METHOD");
+ app.clearHeader(request, "Shib-Authentication-Instant", "HTTP_SHIB_AUTHENTICATION_INSTANT");
+ app.clearHeader(request, "Shib-AuthnContext-Class", "HTTP_SHIB_AUTHNCONTEXT_CLASS");
+ app.clearHeader(request, "Shib-AuthnContext-Decl", "HTTP_SHIB_AUTHNCONTEXT_DECL");
+ app.clearHeader(request, "Shib-Assertion-Count", "HTTP_SHIB_ASSERTION_COUNT");
+ app.clearAttributeHeaders(request);
request.clearHeader("REMOTE_USER", "HTTP_REMOTE_USER");
- //request.clearHeader("Shib-Application-ID"); handle inside app method
- request.getApplication().clearAttributeHeaders(request);
}
};
return initiator->run(request,false);
}
+ request.setAuthType("shibboleth");
+
// We're done. Everything is okay. Nothing to report. Nothing to do..
// Let the caller decide how to proceed.
log.debug("doAuthentication succeeded");
return make_pair(false,0L);
}
catch (exception& e) {
+ request.log(SPRequest::SPError, e.what());
TemplateParameters tp(&e);
tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
return make_pair(true,sendError(log, request, app, "session", tp));
}
}
catch (exception& e) {
+ request.log(SPRequest::SPError, e.what());
TemplateParameters tp(&e);
tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
return make_pair(true,sendError(log, request, app, "access", tp));
return make_pair(false,0L); // just bail silently
}
- request.setHeader("Shib-Application-ID", app->getId());
- request.setHeader("Shib-Session-ID", session->getID());
+ app->setHeader(request, "Shib-Application-ID", app->getId());
+ app->setHeader(request, "Shib-Session-ID", session->getID());
// Export the IdP name and Authn method/context info.
const char* hval = session->getEntityID();
if (hval)
- request.setHeader("Shib-Identity-Provider", hval);
+ app->setHeader(request, "Shib-Identity-Provider", hval);
hval = session->getAuthnInstant();
if (hval)
- request.setHeader("Shib-Authentication-Instant", hval);
+ app->setHeader(request, "Shib-Authentication-Instant", hval);
hval = session->getAuthnContextClassRef();
if (hval) {
- request.setHeader("Shib-Authentication-Method", hval);
- request.setHeader("Shib-AuthnContext-Class", hval);
+ app->setHeader(request, "Shib-Authentication-Method", hval);
+ app->setHeader(request, "Shib-AuthnContext-Class", hval);
}
hval = session->getAuthnContextDeclRef();
if (hval)
- request.setHeader("Shib-AuthnContext-Decl", hval);
+ app->setHeader(request, "Shib-AuthnContext-Decl", hval);
// Maybe export the assertion keys.
pair<bool,bool> exp=settings.first->getBool("exportAssertion");
*(exportName.rbegin()) = '0' + (count%10);
*(++exportName.rbegin()) = '0' + (count/10);
string fullURL = baseURL + encoder->encode(*tokenids);
- request.setHeader(exportName.c_str(), fullURL.c_str());
+ app->setHeader(request, exportName.c_str(), fullURL.c_str());
}
- request.setHeader("Shib-Assertion-Count", exportName.c_str() + 15);
+ app->setHeader(request, "Shib-Assertion-Count", exportName.c_str() + 15);
}
}
// Export the attributes.
const multimap<string,const Attribute*>& attributes = session->getIndexedAttributes();
for (multimap<string,const Attribute*>::const_iterator a = attributes.begin(); a!=attributes.end(); ++a) {
- string header(request.getSecureHeader(a->first.c_str()));
+ if (a->second->isInternal())
+ continue;
+ string header(app->getSecureHeader(request, a->first.c_str()));
const vector<string>& vals = a->second->getSerializedValues();
for (vector<string>::const_iterator v = vals.begin(); v!=vals.end(); ++v) {
if (!header.empty())
header += (*v);
}
}
- request.setHeader(a->first.c_str(), header.c_str());
+ app->setHeader(request, a->first.c_str(), header.c_str());
}
// Check for REMOTE_USER.
for (vector<string>::const_iterator rmid = rmids.begin(); !remoteUserSet && rmid != rmids.end(); ++rmid) {
pair<multimap<string,const Attribute*>::const_iterator,multimap<string,const Attribute*>::const_iterator> matches =
attributes.equal_range(*rmid);
- while (matches.first != matches.second) {
+ for (; matches.first != matches.second; ++matches.first) {
const vector<string>& vals = matches.first->second->getSerializedValues();
if (!vals.empty()) {
request.setRemoteUser(vals.front().c_str());
return make_pair(false,0L);
}
catch (exception& e) {
+ request.log(SPRequest::SPError, e.what());
TemplateParameters tp(&e);
tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
return make_pair(true,sendError(log, request, app, "session", tp));
throw ConfigurationException("Configured Shibboleth handler failed to process the request.");
}
catch (exception& e) {
+ request.log(SPRequest::SPError, e.what());
TemplateParameters tp(&e);
tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
tp.m_request = &request;
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "attribute/SimpleAttribute.h"
#include "attribute/ScopedAttribute.h"
#include "attribute/NameIDAttribute.h"
+#include "attribute/ExtensibleAttribute.h"
+#include "attribute/XMLAttribute.h"
#include "util/SPConstants.h"
+#include <xercesc/util/Base64.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
using namespace shibsp;
return new NameIDAttribute(in);
}
+ SHIBSP_DLLLOCAL Attribute* ExtensibleAttributeFactory(DDF& in) {
+ return new ExtensibleAttribute(in);
+ }
+
+ SHIBSP_DLLLOCAL Attribute* XMLAttributeFactory(DDF& in) {
+ return new XMLAttribute(in);
+ }
+
#ifndef SHIBSP_LITE
- SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,QName,const DOMElement*>::Factory StringAttributeDecoderFactory;
- SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,QName,const DOMElement*>::Factory ScopedAttributeDecoderFactory;
- SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,QName,const DOMElement*>::Factory NameIDAttributeDecoderFactory;
- SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,QName,const DOMElement*>::Factory NameIDFromScopedAttributeDecoderFactory;
+ SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory StringAttributeDecoderFactory;
+ SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory ScopedAttributeDecoderFactory;
+ SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory NameIDAttributeDecoderFactory;
+ SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory NameIDFromScopedAttributeDecoderFactory;
+ SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory KeyInfoAttributeDecoderFactory;
+ SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory DOMAttributeDecoderFactory;
+ SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory XMLAttributeDecoderFactory;
static const XMLCh _StringAttributeDecoder[] = UNICODE_LITERAL_22(S,t,r,i,n,g,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
static const XMLCh _ScopedAttributeDecoder[] = UNICODE_LITERAL_22(S,c,o,p,e,d,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
static const XMLCh _NameIDAttributeDecoder[] = UNICODE_LITERAL_22(N,a,m,e,I,D,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
static const XMLCh _NameIDFromScopedAttributeDecoder[] = UNICODE_LITERAL_32(N,a,m,e,I,D,F,r,o,m,S,c,o,p,e,d,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
+ static const XMLCh _KeyInfoAttributeDecoder[] =UNICODE_LITERAL_23(K,e,y,I,n,f,o,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
+ static const XMLCh _DOMAttributeDecoder[] = UNICODE_LITERAL_19(D,O,M,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
+ static const XMLCh _XMLAttributeDecoder[] = UNICODE_LITERAL_19(X,M,L,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
static const XMLCh caseSensitive[] = UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
+ static const XMLCh internal[] = UNICODE_LITERAL_8(i,n,t,e,r,n,a,l);
#endif
};
#ifndef SHIBSP_LITE
-QName shibsp::StringAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _StringAttributeDecoder);
-QName shibsp::ScopedAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _ScopedAttributeDecoder);
-QName shibsp::NameIDAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _NameIDAttributeDecoder);
-QName shibsp::NameIDFromScopedAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _NameIDFromScopedAttributeDecoder);
+xmltooling::QName shibsp::StringAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _StringAttributeDecoder);
+xmltooling::QName shibsp::ScopedAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _ScopedAttributeDecoder);
+xmltooling::QName shibsp::NameIDAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _NameIDAttributeDecoder);
+xmltooling::QName shibsp::NameIDFromScopedAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _NameIDFromScopedAttributeDecoder);
+xmltooling::QName shibsp::KeyInfoAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _KeyInfoAttributeDecoder);
+xmltooling::QName shibsp::DOMAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _DOMAttributeDecoder);
+xmltooling::QName shibsp::XMLAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _XMLAttributeDecoder);
void shibsp::registerAttributeDecoders()
{
conf.AttributeDecoderManager.registerFactory(ScopedAttributeDecoderType, ScopedAttributeDecoderFactory);
conf.AttributeDecoderManager.registerFactory(NameIDAttributeDecoderType, NameIDAttributeDecoderFactory);
conf.AttributeDecoderManager.registerFactory(NameIDFromScopedAttributeDecoderType, NameIDFromScopedAttributeDecoderFactory);
+ conf.AttributeDecoderManager.registerFactory(KeyInfoAttributeDecoderType, KeyInfoAttributeDecoderFactory);
+ conf.AttributeDecoderManager.registerFactory(DOMAttributeDecoderType, DOMAttributeDecoderFactory);
+ conf.AttributeDecoderManager.registerFactory(XMLAttributeDecoderType, XMLAttributeDecoderFactory);
}
-AttributeDecoder::AttributeDecoder(const DOMElement *e) : m_caseSensitive(true)
+AttributeDecoder::AttributeDecoder(const DOMElement *e) : m_caseSensitive(true), m_internal(false)
{
if (e) {
- const XMLCh* flag = e->getAttributeNS(NULL,caseSensitive);
+ const XMLCh* flag = e->getAttributeNS(NULL, caseSensitive);
if (flag && (*flag == chLatin_f || *flag == chDigit_0))
m_caseSensitive = false;
+
+ flag = e->getAttributeNS(NULL, internal);
+ if (flag && (*flag == chLatin_t || *flag == chDigit_1))
+ m_internal = true;
}
}
#endif
Attribute::registerFactory("Simple", SimpleAttributeFactory);
Attribute::registerFactory("Scoped", ScopedAttributeFactory);
Attribute::registerFactory("NameID", NameIDAttributeFactory);
+ Attribute::registerFactory("Extensible", ExtensibleAttributeFactory);
+ Attribute::registerFactory("XML", XMLAttributeFactory);
+}
+
+map<string,Attribute::AttributeFactory*> Attribute::m_factoryMap;
+
+Attribute::Attribute(DDF& in) : m_caseSensitive(in["case_insensitive"].isnull()), m_internal(!in["internal"].isnull())
+{
+ const char* id = in.first().name();
+ if (id && *id)
+ m_id.push_back(id);
+ else
+ throw AttributeException("No id found in marshalled attribute content.");
+ DDF aliases = in["aliases"];
+ if (aliases.islist()) {
+ DDF alias = aliases.first();
+ while (alias.isstring()) {
+ m_id.push_back(alias.string());
+ alias = aliases.next();
+ }
+ }
}
-std::map<std::string,Attribute::AttributeFactory*> Attribute::m_factoryMap;
+DDF Attribute::marshall() const
+{
+ DDF ddf(NULL);
+ ddf.structure().addmember(m_id.front().c_str()).list();
+ if (!m_caseSensitive)
+ ddf.addmember("case_insensitive");
+ if (m_internal)
+ ddf.addmember("internal");
+ if (m_id.size() > 1) {
+ DDF alias;
+ DDF aliases = ddf.addmember("aliases").list();
+ for (std::vector<std::string>::const_iterator a = m_id.begin() + 1; a != m_id.end(); ++a) {
+ alias = DDF(NULL).string(a->c_str());
+ aliases.add(alias);
+ }
+ }
+ return ddf;
+}
Attribute* Attribute::unmarshall(DDF& in)
{
map<string,AttributeFactory*>::const_iterator i = m_factoryMap.find(in.name() ? in.name() : "");
if (i == m_factoryMap.end())
- throw AttributeException("No registered factory for Attribute of type ($1).", xmltooling::params(1,in.name()));
+ throw AttributeException("No registered factory for Attribute of type ($1).", params(1,in.name()));
return (i->second)(in);
}
+
+const vector<string>& XMLAttribute::getSerializedValues() const
+{
+ xsecsize_t len;
+ XMLByte *pos, *pos2;\r
+ if (m_serialized.empty()) {
+ for (vector<string>::const_iterator i=m_values.begin(); i!=m_values.end(); ++i) {
+ XMLByte* enc = Base64::encode(reinterpret_cast<const XMLByte*>(i->data()), i->size(), &len);
+ if (enc) {
+ for (pos=enc, pos2=enc; *pos2; pos2++)\r
+ if (isgraph(*pos2))\r
+ *pos++=*pos2;\r
+ *pos=0;\r
+ m_serialized.push_back(reinterpret_cast<char*>(enc));
+#ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE
+ XMLString::release(&enc);
+#else
+ XMLString::release((char**)&enc);
+#endif
+ }
+ }
+ }
+ return Attribute::getSerializedValues();
+}
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* @file shibsp/attribute/Attribute.h
- *
+ *
* A resolved attribute.
*/
/**
* A resolved attribute.
- *
+ *
* <p>Resolved attributes are a neutral construct that represent both simple and
* complex attribute data structures that might be found in SAML assertions
* or obtained from other sources.
- *
+ *
* <p>Attributes consist of an id/name that is locally unique (that is, unique to a
* configuration at any given point in time) and zero or more values. Values can
* be of any type or structure, but will generally be made available to applications
* only if a serialized string form exists. More complex values can be used with
- * access control plugins that understand them, however.
+ * access control plugins and other components that understand them, however.
*/
class SHIBSP_API Attribute
{
protected:
/**
* Constructor
- *
+ *
* @param ids array with primary identifier in first position, followed by any aliases
*/
- Attribute(const std::vector<std::string>& ids) : m_id(ids), m_caseSensitive(true) {
+ Attribute(const std::vector<std::string>& ids) : m_id(ids), m_caseSensitive(true), m_internal(false) {
}
/**
* Constructs based on a remoted Attribute.
- *
+ *
* <p>This allows Attribute objects to be recreated after marshalling.
* The DDF supplied must be a struct containing a single list member named
* with the Attribute's "id" and containing the values.
- *
+ *
* @param in input object containing marshalled Attribute
*/
- Attribute(DDF& in) : m_caseSensitive(in["case_insensitive"].isnull()) {
- const char* id = in.first().name();
- if (id && *id)
- m_id.push_back(id);
- else
- throw AttributeException("No id found in marshalled attribute content.");
- DDF aliases = in["aliases"];
- if (aliases.islist()) {
- DDF alias = aliases.first();
- while (alias.isstring()) {
- m_id.push_back(alias.string());
- alias = aliases.next();
- }
- }
- }
-
+ Attribute(DDF& in);
+
/**
* Maintains a copy of serialized attribute values, when possible.
- *
+ *
* <p>Implementations should maintain the array when values are added or removed.
*/
mutable std::vector<std::string> m_serialized;
public:
virtual ~Attribute() {}
-
+
/**
* Returns the Attribute identifier.
- *
+ *
* @return the Attribute identifier
*/
const char* getId() const {
}
/**
+ * Sets whether the attribute should be exported for CGI use.
+ *
+ * @param export true iff the attribute should <strong>NOT</strong> be exported
+ */
+ void setInternal(bool internal) {
+ m_internal = internal;
+ }
+
+ /**
* Indicates whether case sensitivity should apply to basic value comparisons.
*
* @return true iff value comparisons should be case sensitive
bool isCaseSensitive() const {
return m_caseSensitive;
}
-
+
+ /**
+ * Indicates whether the attribute should be exported for CGI use.
+ *
+ * @return true iff the attribute should <strong>NOT</strong> be exported
+ */
+ bool isInternal() const {
+ return m_internal;
+ }
+
/**
* Returns the number of values.
- *
+ *
* @return number of values
*/
virtual size_t valueCount() const {
return m_serialized.size();
}
-
+
/**
* Returns serialized Attribute values encoded as UTF-8 strings.
- *
+ *
* @return an immutable vector of values
*/
virtual const std::vector<std::string>& getSerializedValues() const {
return m_serialized;
}
-
+
/**
* Informs the Attribute that values have changed and any serializations
- * must be cleared.
+ * must be cleared.
*/
virtual void clearSerializedValues()=0;
-
+
/**
* Gets the string equivalent of the value at the specified position (starting from zero).
*
/**
* Marshalls an Attribute for remoting.
- *
+ *
* <p>This allows Attribute objects to be communicated across process boundaries
* without excess XML parsing. The DDF returned must be a struct containing
* a single list member named with the Attribute's "id". The name of the struct
* should contain the registered name of the Attribute implementation.
*/
- virtual DDF marshall() const {
- DDF ddf(NULL);
- ddf.structure().addmember(m_id.front().c_str()).list();
- if (!m_caseSensitive)
- ddf.addmember("case_insensitive");
- if (m_id.size() > 1) {
- DDF alias;
- DDF aliases = ddf.addmember("aliases").list();
- for (std::vector<std::string>::const_iterator a = m_id.begin() + 1; a != m_id.end(); ++a) {
- alias = DDF(NULL).string(a->c_str());
- aliases.add(alias);
- }
- }
- return ddf;
- }
-
+ virtual DDF marshall() const;
+
/**
* Unmarshalls a remoted Attribute.
- *
+ *
* @param in remoted Attribute data
- * @return a resolved Attribute of the proper subclass
+ * @return a resolved Attribute of the proper subclass
*/
static Attribute* unmarshall(DDF& in);
-
+
/** A function that unmarshalls remoted data into the proper Attribute subclass. */
typedef Attribute* AttributeFactory(DDF& in);
/**
* Registers an AttributeFactory function for a given attribute "type".
- *
+ *
* @param type string used at the root of remoted Attribute structures
* @param factory factory function
- */
+ */
static void registerFactory(const char* type, AttributeFactory* factory) {
m_factoryMap[type] = factory;
}
/**
* Deregisters an AttributeFactory function for a given attribute "type".
- *
+ *
* @param type string used at the root of remoted Attribute structures
- */
+ */
static void deregisterFactory(const char* type) {
m_factoryMap.erase(type);
}
static void deregisterFactories() {
m_factoryMap.clear();
}
-
+
private:
static std::map<std::string,AttributeFactory*> m_factoryMap;
std::vector<std::string> m_id;
- bool m_caseSensitive;
+ bool m_caseSensitive,m_internal;
};
#if defined (_MSC_VER)
/** Registers built-in Attribute types into the runtime. */
void registerAttributeFactories();
-
+
};
#endif /* __shibsp_attribute_h__ */
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/** Flag for case sensitivity of decoded attributes. */
bool m_caseSensitive;
+ /** Flag for hiding attributes from CGI export. */
+ bool m_internal;
+
+ /**
+ * Helper method to handle base class decoding housekeeping.
+ *
+ * @param attr the new Attribute object being created
+ * @return the attr parameter
+ */
+ virtual Attribute* _decode(Attribute* attr) const {
+ attr->setCaseSensitive(m_caseSensitive);
+ attr->setInternal(m_internal);
+ return attr;
+ }
+
public:
virtual ~AttributeDecoder() {}
/** Decodes scoped attributes into a NameIDAttribute. */
extern SHIBSP_API xmltooling::QName NameIDFromScopedAttributeDecoderType;
+ /** Decodes KeyInfo information into a SimpleAttribute. */
+ extern SHIBSP_API xmltooling::QName KeyInfoAttributeDecoderType;
+
+ /** Decodes arbitrary DOM information into an ExtensibleAttribute. */
+ extern SHIBSP_API xmltooling::QName DOMAttributeDecoderType;
+
+ /** Decodes arbitrary XML into an XMLAttribute. */
+ extern SHIBSP_API xmltooling::QName XMLAttributeDecoderType;
+
/** Registers built-in AttributeDecoders into the runtime. */
void registerAttributeDecoders();
};
--- /dev/null
+/*\r
+ * Copyright 2009 Internet2\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * DOMAttributeDecoder.cpp\r
+ *\r
+ * Decodes a DOM into an ExtensibleAttribute.\r
+ */\r
+\r
+#include "internal.h"\r
+#include "attribute/AttributeDecoder.h"\r
+#include "attribute/ExtensibleAttribute.h"\r
+\r
+#include <saml/saml1/core/Assertions.h>\r
+#include <saml/saml2/core/Assertions.h>\r
+#include <xmltooling/util/XMLHelper.h>\r
+\r
+using namespace shibsp;\r
+using namespace opensaml;\r
+using namespace xmltooling;\r
+using namespace std;\r
+\r
+namespace shibsp {\r
+ class SHIBSP_DLLLOCAL DOMAttributeDecoder : virtual public AttributeDecoder\r
+ {\r
+ public:\r
+ DOMAttributeDecoder(const DOMElement* e);\r
+ ~DOMAttributeDecoder() {}\r
+\r
+ Attribute* decode(\r
+ const vector<string>& ids, const XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+ ) const;\r
+\r
+ private:\r
+ DDF convert(DOMElement* e, bool nameit=true) const;\r
+ auto_ptr_char m_formatter;\r
+ map<pair<xstring,xstring>,string> m_tagMap;\r
+ };\r
+\r
+ AttributeDecoder* SHIBSP_DLLLOCAL DOMAttributeDecoderFactory(const DOMElement* const & e)\r
+ {\r
+ return new DOMAttributeDecoder(e);\r
+ }\r
+\r
+ static const XMLCh Mapping[] = UNICODE_LITERAL_7(M,a,p,p,i,n,g);\r
+ static const XMLCh _from[] = UNICODE_LITERAL_4(f,r,o,m);\r
+ static const XMLCh _to[] = UNICODE_LITERAL_2(t,o);\r
+ static const XMLCh formatter[] = UNICODE_LITERAL_9(f,o,r,m,a,t,t,e,r);\r
+};\r
+\r
+DOMAttributeDecoder::DOMAttributeDecoder(const DOMElement* e)\r
+ : AttributeDecoder(e), m_formatter(e ? e->getAttributeNS(NULL,formatter) : NULL)\r
+{\r
+ Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeDecoder.DOM");\r
+\r
+ e = e ? XMLHelper::getFirstChildElement(e, Mapping) : NULL;\r
+ while (e) {\r
+ if (e->hasAttributeNS(NULL, _from) && e->hasAttributeNS(NULL, _to)) {\r
+ auto_ptr<xmltooling::QName> f(XMLHelper::getNodeValueAsQName(e->getAttributeNodeNS(NULL, _from)));\r
+ auto_ptr_char t(e->getAttributeNS(NULL, _to));\r
+ if (f.get() && t.get() && *t.get()) {\r
+ if (log.isDebugEnabled())\r
+ log.debug("mapping (%s) to (%s)", f->toString().c_str(), t.get());\r
+ m_tagMap.insert(\r
+ pair< const pair<xstring,xstring>,string>(\r
+ pair<xstring,xstring>(f->getLocalPart(), f->hasNamespaceURI() ? f->getNamespaceURI() : &chNull),\r
+ t.get()\r
+ )\r
+ );\r
+ }\r
+ }\r
+ e = XMLHelper::getNextSiblingElement(e, Mapping);\r
+ }\r
+}\r
+\r
+Attribute* DOMAttributeDecoder::decode(\r
+ const vector<string>& ids, const XMLObject* xmlObject, const char* assertingParty, const char* relyingParty\r
+ ) const\r
+{\r
+ Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeDecoder.DOM");\r
+\r
+ if (!xmlObject || !XMLString::equals(saml1::Attribute::LOCAL_NAME, xmlObject->getElementQName().getLocalPart())) {\r
+ log.warn("XMLObject type not recognized by DOMAttributeDecoder, no values returned");\r
+ return NULL;\r
+ }\r
+\r
+ auto_ptr<ExtensibleAttribute> attr(new ExtensibleAttribute(ids, m_formatter.get()));\r
+ DDF dest = attr->getValues();\r
+ vector<XMLObject*>::const_iterator v,stop;\r
+\r
+ const saml2::Attribute* saml2attr = dynamic_cast<const saml2::Attribute*>(xmlObject);\r
+ if (saml2attr) {\r
+ const vector<XMLObject*>& values = saml2attr->getAttributeValues();\r
+ v = values.begin();\r
+ stop = values.end();\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char n(saml2attr->getName());\r
+ log.debug(\r
+ "decoding ExtensibleAttribute (%s) from SAML 2 Attribute (%s) with %lu value(s)",\r
+ ids.front().c_str(), n.get() ? n.get() : "unnamed", values.size()\r
+ );\r
+ }\r
+ }\r
+ else {\r
+ const saml1::Attribute* saml1attr = dynamic_cast<const saml1::Attribute*>(xmlObject);\r
+ if (saml1attr) {\r
+ const vector<XMLObject*>& values = saml1attr->getAttributeValues();\r
+ v = values.begin();\r
+ stop = values.end();\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char n(saml1attr->getAttributeName());\r
+ log.debug(\r
+ "decoding ExtensibleAttribute (%s) from SAML 1 Attribute (%s) with %lu value(s)",\r
+ ids.front().c_str(), n.get() ? n.get() : "unnamed", values.size()\r
+ );\r
+ }\r
+ }\r
+ else {\r
+ log.warn("XMLObject type not recognized by DOMAttributeDecoder, no values returned");\r
+ return NULL;\r
+ }\r
+ }\r
+\r
+ for (; v!=stop; ++v) {\r
+ DOMElement* e = (*v)->getDOM();\r
+ if (e) {\r
+ DDF converted = convert(e, false);\r
+ if (!converted.isnull())\r
+ dest.add(converted);\r
+ }\r
+ else\r
+ log.warn("skipping AttributeValue without a backing DOM");\r
+ }\r
+\r
+ return dest.integer() ? _decode(attr.release()) : NULL;\r
+}\r
+\r
+DDF DOMAttributeDecoder::convert(DOMElement* e, bool nameit) const\r
+{\r
+ const XMLCh* nsURI;\r
+ const XMLCh* local;\r
+ map<pair<xstring,xstring>,string>::const_iterator mapping;\r
+ DDF obj = DDF(NULL).structure();\r
+\r
+ if (nameit) {\r
+ // Name this structure.\r
+ nsURI = e->getNamespaceURI();\r
+ local = e->getLocalName();\r
+ mapping = m_tagMap.find(pair<xstring,xstring>(local,nsURI));\r
+ if (mapping == m_tagMap.end()) {\r
+ auto_ptr_char temp(local);\r
+ obj.name(temp.get());\r
+ }\r
+ else {\r
+ obj.name(mapping->second.c_str());\r
+ }\r
+ }\r
+\r
+ // Process non-xmlns attributes.\r
+ DOMNamedNodeMap* attrs = e->getAttributes();\r
+ for (XMLSize_t a = attrs->getLength(); a > 0; --a) {\r
+ DOMNode* attr = attrs->item(a-1);\r
+ nsURI = attr->getNamespaceURI();\r
+ if (XMLString::equals(nsURI, xmlconstants::XMLNS_NS))\r
+ continue;\r
+ local = attr->getLocalName();\r
+ mapping = m_tagMap.find(pair<xstring,xstring>(local, nsURI ? nsURI : &chNull));\r
+ if (mapping == m_tagMap.end()) {\r
+ auto_ptr_char temp(local);\r
+ obj.addmember(temp.get()).string(toUTF8(attr->getNodeValue(), true), false);\r
+ }\r
+ else {\r
+ obj.addmember(mapping->second.c_str()).string(toUTF8(attr->getNodeValue(), true), false);\r
+ }\r
+ }\r
+\r
+ DOMElement* child = XMLHelper::getFirstChildElement(e);\r
+ if (!child && e->hasChildNodes() && e->getFirstChild()->getNodeType() == DOMNode::TEXT_NODE) {\r
+ // Attach a _text member if a text node is present.\r
+ obj.addmember("_string").string(toUTF8(e->getFirstChild()->getNodeValue(), true), false);\r
+ }\r
+ else {\r
+ while (child) {\r
+ // Convert the child element.\r
+ DDF converted = convert(child);\r
+ if (!converted.isnull()) {\r
+ // Now identify it and attach it.\r
+ if (obj[converted.name()].isnull()) {\r
+ // We're a new child, so just attach as a structure member.\r
+ obj.add(converted);\r
+ }\r
+ else if (obj[converted.name()].islist()) {\r
+ // We're already a repeating child, so add it to the list.\r
+ obj[converted.name()].add(converted);\r
+ }\r
+ else if (obj[converted.name()].isstruct()) {\r
+ // This is the complex case where we see a child for the second\r
+ // time and have to convert a structure member into a named list.\r
+ DDF newlist = DDF(converted.name()).list();\r
+ newlist.add(obj[converted.name()].remove());\r
+ newlist.add(converted);\r
+ obj.add(newlist);\r
+ }\r
+ }\r
+ child = XMLHelper::getNextSiblingElement(child);\r
+ }\r
+ }\r
+\r
+ // If we're empty, just delete.\r
+ if (obj.integer() == 0)\r
+ obj.destroy();\r
+ return obj;\r
+}\r
--- /dev/null
+/*
+ * Copyright 2009 Internet2
+ *
+ * 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.
+ */
+
+/**
+ * shibsp/attribute/ExtensibleAttribute.cpp
+ *
+ * An Attribute whose values are arbitrary structures.
+ */
+
+#include "internal.h"
+#include "SPConfig.h"
+#include "attribute/ExtensibleAttribute.h"
+#include "util/SPConstants.h"
+
+using namespace shibsp;
+using namespace xmltooling;
+using namespace std;
+
+const vector<string>& ExtensibleAttribute::getSerializedValues() const
+{
+ if (m_serialized.empty()) {
+ const char* formatter = m_obj["_formatter"].string();
+ if (formatter) {
+ string msg = formatter;
+ DDF val = m_obj.first().first();
+ while (!val.isnull()) {
+
+ static const char* legal="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_.[]";
+
+ m_serialized.push_back(string());
+ string& processed = m_serialized.back();
+
+ string::size_type i=0,start=0;
+ while (start!=string::npos && start<msg.length() && (i=msg.find("$",start))!=string::npos) {
+ if (i>start)
+ processed += msg.substr(start,i-start); // append everything in between
+ start=i+1; // move start to the beginning of the token name
+ i=msg.find_first_not_of(legal,start); // find token delimiter
+ if (i==start) { // append a non legal character
+ processed+=msg[start++];
+ continue;
+ }
+
+ string tag = msg.substr(start,(i==string::npos) ? i : i-start);
+ if (tag == "_string" && val.string()) {
+ processed += val.string();
+ start=i;
+ }
+ else {
+ DDF child = val.getmember(tag.c_str());
+ if (child.string())
+ processed += child.string();
+ else if (child.isstruct() && child["_string"].string())
+ processed += child["_string"].string();
+ start=i;
+ }
+ }
+ if (start!=string::npos && start<msg.length())
+ processed += msg.substr(start,i); // append rest of string
+
+ val = m_obj.first().next();
+ }
+ }
+ }
+ return Attribute::getSerializedValues();
+}
--- /dev/null
+/*
+ * Copyright 2009 Internet2
+ *
+ * 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.
+ */
+
+/**
+ * @file shibsp/attribute/ExtensibleAttribute.h
+ *
+ * An Attribute whose values are arbitrary structures.
+ */
+
+#ifndef __shibsp_extattr_h__
+#define __shibsp_extattr_h__
+
+#include <shibsp/attribute/Attribute.h>
+#include <xmltooling/exceptions.h>
+
+namespace shibsp {
+
+#if defined (_MSC_VER)
+ #pragma warning( push )
+ #pragma warning( disable : 4251 )
+#endif
+
+ /**
+ * An Attribute whose values are arbitrary structures.
+ */
+ class SHIBSP_API ExtensibleAttribute : public Attribute
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param ids array with primary identifier in first position, followed by any aliases
+ * @param formatter template for serialization of values
+ */
+ ExtensibleAttribute(const std::vector<std::string>& ids, const char* formatter) : Attribute(ids) {
+ m_obj = Attribute::marshall();
+ m_obj.name("Extensible");
+ m_obj.addmember("_formatter").string(formatter);
+ }
+
+ /**
+ * Constructs based on a remoted ExtensibleAttribute.
+ *
+ * @param in input object containing marshalled ExtensibleAttribute
+ */
+ ExtensibleAttribute(DDF& in) : Attribute(in), m_obj(in.copy()) {
+ }
+
+ virtual ~ExtensibleAttribute() {
+ m_obj.destroy();
+ }
+
+ /**
+ * Returns the set of values in a DDF list.
+ *
+ * @return a mutable list object containing the values
+ */
+ DDF getValues() {
+ return m_obj.first();
+ }
+
+ size_t valueCount() const {
+ return m_obj.first().integer();
+ }
+
+ void clearSerializedValues() {
+ m_serialized.clear();
+ }
+
+ const char* getString(size_t index) const {
+ return m_obj.first()[static_cast<unsigned long>(index)].string();
+ }
+
+ const char* getScope(size_t index) const {
+ return NULL;
+ }
+
+ void removeValue(size_t index) {
+ Attribute::removeValue(index);
+ DDF vals = m_obj.first();
+ if (index < static_cast<size_t>(vals.integer()))
+ vals[static_cast<unsigned long>(index)].remove().destroy();
+ }
+
+ const std::vector<std::string>& getSerializedValues() const;
+
+ DDF marshall() const {
+ if (!isCaseSensitive())
+ m_obj.addmember("case_insensitive");
+ if (isInternal())
+ m_obj.addmember("internal");
+ return m_obj.copy();
+ }
+
+ private:
+ mutable DDF m_obj;
+ };
+
+#if defined (_MSC_VER)
+ #pragma warning( pop )
+#endif
+
+};
+
+#endif /* __shibsp_nameidattr_h__ */
--- /dev/null
+/*\r
+ * Copyright 2009 Internet2\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * KeyInfoAttributeDecoder.cpp\r
+ *\r
+ * Decodes KeyInfo information into a SimpleAttribute.\r
+ */\r
+\r
+#include "internal.h"\r
+#include "attribute/AttributeDecoder.h"\r
+#include "attribute/SimpleAttribute.h"\r
+\r
+#include <saml/saml1/core/Assertions.h>\r
+#include <saml/saml2/core/Assertions.h>\r
+#include <xmltooling/security/SecurityHelper.h>\r
+#include <xmltooling/signature/KeyInfo.h>\r
+\r
+using namespace shibsp;\r
+using namespace opensaml;\r
+using namespace xmlsignature;\r
+using namespace xmltooling;\r
+using namespace std;\r
+\r
+namespace shibsp {\r
+ class SHIBSP_DLLLOCAL KeyInfoAttributeDecoder : virtual public AttributeDecoder\r
+ {\r
+ public:\r
+ KeyInfoAttributeDecoder(const DOMElement* e);\r
+ ~KeyInfoAttributeDecoder() {\r
+ delete m_keyInfoResolver;\r
+ }\r
+\r
+ Attribute* decode(\r
+ const vector<string>& ids, const XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+ ) const;\r
+\r
+ private:\r
+ void extract(const KeyInfo* k, vector<string>& dest) const {\r
+ auto_ptr<Credential> cred (getKeyInfoResolver()->resolve(k, Credential::RESOLVE_KEYS));\r
+ if (cred.get()) {\r
+ dest.push_back(string());\r
+ dest.back() = SecurityHelper::getDEREncoding(*cred.get(), m_hash);\r
+ if (dest.back().empty())\r
+ dest.pop_back();\r
+ }\r
+ }\r
+\r
+ const KeyInfoResolver* getKeyInfoResolver() const {\r
+ return m_keyInfoResolver ? m_keyInfoResolver : XMLToolingConfig::getConfig().getKeyInfoResolver();\r
+ }\r
+\r
+ bool m_hash;\r
+ KeyInfoResolver* m_keyInfoResolver;\r
+ };\r
+\r
+ AttributeDecoder* SHIBSP_DLLLOCAL KeyInfoAttributeDecoderFactory(const DOMElement* const & e)\r
+ {\r
+ return new KeyInfoAttributeDecoder(e);\r
+ }\r
+\r
+ static const XMLCh _KeyInfoResolver[] = UNICODE_LITERAL_15(K,e,y,I,n,f,o,R,e,s,o,l,v,e,r);\r
+ static const XMLCh _hash[] = UNICODE_LITERAL_4(h,a,s,h);\r
+ static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);\r
+};\r
+\r
+KeyInfoAttributeDecoder::KeyInfoAttributeDecoder(const DOMElement* e) : AttributeDecoder(e), m_hash(false), m_keyInfoResolver(NULL) {\r
+ const XMLCh* flag = e ? e->getAttributeNS(NULL, _hash) : NULL;\r
+ m_hash = (flag && (*flag == chLatin_t || *flag == chDigit_1));\r
+ e = e ? XMLHelper::getFirstChildElement(e,_KeyInfoResolver) : NULL;\r
+ if (e) {\r
+ auto_ptr_char t(e->getAttributeNS(NULL, _type));\r
+ if (t.get() && *t.get())\r
+ m_keyInfoResolver = XMLToolingConfig::getConfig().KeyInfoResolverManager.newPlugin(t.get(), e);\r
+ else\r
+ throw UnknownExtensionException("<KeyInfoResolver> element found with no type attribute");\r
+ }\r
+}\r
+\r
+Attribute* KeyInfoAttributeDecoder::decode(\r
+ const vector<string>& ids, const XMLObject* xmlObject, const char* assertingParty, const char* relyingParty\r
+ ) const\r
+{\r
+ Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeDecoder.KeyInfo");\r
+\r
+ if (!xmlObject || !XMLString::equals(saml1::Attribute::LOCAL_NAME, xmlObject->getElementQName().getLocalPart())) {\r
+ log.warn("XMLObject type not recognized by KeyInfoAttributeDecoder, no values returned");\r
+ return NULL;\r
+ }\r
+\r
+ auto_ptr<SimpleAttribute> attr(new SimpleAttribute(ids));\r
+ vector<string>& dest = attr->getValues();\r
+ vector<XMLObject*>::const_iterator v,stop;\r
+\r
+ const saml2::Attribute* saml2attr = dynamic_cast<const saml2::Attribute*>(xmlObject);\r
+ if (saml2attr) {\r
+ const vector<XMLObject*>& values = saml2attr->getAttributeValues();\r
+ v = values.begin();\r
+ stop = values.end();\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char n(saml2attr->getName());\r
+ log.debug(\r
+ "decoding KeyInfo information (%s) from SAML 2 Attribute (%s) with %lu value(s)",\r
+ ids.front().c_str(), n.get() ? n.get() : "unnamed", values.size()\r
+ );\r
+ }\r
+ }\r
+ else {\r
+ const saml1::Attribute* saml1attr = dynamic_cast<const saml1::Attribute*>(xmlObject);\r
+ if (saml1attr) {\r
+ const vector<XMLObject*>& values = saml1attr->getAttributeValues();\r
+ v = values.begin();\r
+ stop = values.end();\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char n(saml1attr->getAttributeName());\r
+ log.debug(\r
+ "decoding KeyInfo information (%s) from SAML 1 Attribute (%s) with %lu value(s)",\r
+ ids.front().c_str(), n.get() ? n.get() : "unnamed", values.size()\r
+ );\r
+ }\r
+ }\r
+ else {\r
+ log.warn("XMLObject type not recognized by KeyInfoAttributeDecoder, no values returned");\r
+ return NULL;\r
+ }\r
+ }\r
+\r
+ for (; v!=stop; ++v) {\r
+ const KeyInfo* k = dynamic_cast<const KeyInfo*>(*v);\r
+ if (k)\r
+ extract(k, dest);\r
+ else if ((*v)->hasChildren()) {\r
+ const list<XMLObject*>& children = (*v)->getOrderedChildren();\r
+ for (list<XMLObject*>::const_iterator vv = children.begin(); vv!=children.end(); ++vv) {\r
+ if (k=dynamic_cast<const KeyInfo*>(*vv))\r
+ extract(k, dest);\r
+ else\r
+ log.warn("skipping AttributeValue without a recognizable KeyInfo");\r
+ }\r
+ }\r
+ }\r
+\r
+ return dest.empty() ? NULL : _decode(attr.release());\r
+}\r
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/**
* @file shibsp/attribute/NameIDAttribute.h
*
- * An Attribute whose values are relations of a value and a scope.
+ * An Attribute whose values are derived from or mappable to a SAML NameID.
*/
#ifndef __shibsp_nameidattr_h__
/**
* Returns the set of values encoded as UTF-8 strings.
*
- * <p>Each compound value is a pair containing the simple value and the scope.
- *
* @return a mutable vector of the values
*/
std::vector<Value>& getValues() {
return m_values;
}
-
+
+ /**
+ * Returns the set of values encoded as UTF-8 strings.
+ *
+ * @return an immutable vector of the values
+ */
+ const std::vector<Value>& getValues() const {
+ return m_values;
+ }
+
size_t valueCount() const {
return m_values.size();
}
/*\r
- * Copyright 2001-2007 Internet2\r
+ * Copyright 2001-2009 Internet2\r
*\r
* Licensed under the Apache License, Version 2.0 (the "License");\r
* you may not use this file except in compliance with the License.\r
using namespace std;\r
\r
namespace shibsp {\r
- static XMLCh formatter[] = UNICODE_LITERAL_9(f,o,r,m,a,t,t,e,r);\r
+ static const XMLCh formatter[] = UNICODE_LITERAL_9(f,o,r,m,a,t,t,e,r);\r
+ static const XMLCh defaultQualifiers[] = UNICODE_LITERAL_17(d,e,f,a,u,l,t,Q,u,a,l,i,f,i,e,r,s);\r
\r
class SHIBSP_DLLLOCAL NameIDAttributeDecoder : virtual public AttributeDecoder\r
{\r
public:\r
- NameIDAttributeDecoder(const DOMElement* e) : AttributeDecoder(e), m_formatter(e ? e->getAttributeNS(NULL,formatter) : NULL) {}\r
+ NameIDAttributeDecoder(const DOMElement* e)\r
+ : AttributeDecoder(e), m_formatter(e ? e->getAttributeNS(NULL, formatter) : NULL), m_defaultQualifiers(false) {\r
+ const XMLCh* flag = e ? e->getAttributeNS(NULL, defaultQualifiers) : NULL;\r
+ if (flag && (*flag == chLatin_t || *flag == chDigit_1))\r
+ m_defaultQualifiers = true;\r
+ }\r
~NameIDAttributeDecoder() {}\r
\r
shibsp::Attribute* decode(\r
const NameIdentifier* n, vector<NameIDAttribute::Value>& dest, const char* assertingParty, const char* relyingParty\r
) const;\r
auto_ptr_char m_formatter;\r
+ bool m_defaultQualifiers;\r
};\r
\r
AttributeDecoder* SHIBSP_DLLLOCAL NameIDAttributeDecoderFactory(const DOMElement* const & e)\r
auto_ptr<NameIDAttribute> nameid(\r
new NameIDAttribute(ids, (m_formatter.get() && *m_formatter.get()) ? m_formatter.get() : DEFAULT_NAMEID_FORMATTER)\r
);\r
- nameid->setCaseSensitive(m_caseSensitive);\r
vector<NameIDAttribute::Value>& dest = nameid->getValues();\r
vector<XMLObject*>::const_iterator v,stop;\r
\r
}\r
}\r
\r
- return dest.empty() ? NULL : nameid.release();\r
+ return dest.empty() ? NULL : _decode(nameid.release());\r
}\r
\r
const NameIDType* saml2name = dynamic_cast<const NameIDType*>(xmlObject);\r
}\r
}\r
\r
- return dest.empty() ? NULL : nameid.release();\r
+ return dest.empty() ? NULL : _decode(nameid.release());\r
}\r
\r
void NameIDAttributeDecoder::extract(\r
str = toUTF8(n->getNameQualifier());\r
if (str && *str)\r
val.m_NameQualifier = str;\r
- else if (assertingParty)\r
+ else if (m_defaultQualifiers && assertingParty)\r
val.m_NameQualifier = assertingParty;\r
delete[] str;\r
\r
str = toUTF8(n->getSPNameQualifier());\r
if (str && *str)\r
val.m_SPNameQualifier = str;\r
- else if (relyingParty)\r
+ else if (m_defaultQualifiers && relyingParty)\r
val.m_SPNameQualifier = relyingParty;\r
delete[] str;\r
\r
str = toUTF8(n->getNameQualifier());\r
if (str && *str)\r
val.m_NameQualifier = str;\r
- else if (assertingParty)\r
+ else if (m_defaultQualifiers && assertingParty)\r
val.m_NameQualifier = assertingParty;\r
delete[] str;\r
\r
- if (relyingParty)\r
+ if (m_defaultQualifiers && relyingParty)\r
val.m_SPNameQualifier = relyingParty;\r
}\r
}\r
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
using namespace std;
namespace shibsp {
- static XMLCh format[] = UNICODE_LITERAL_6(f,o,r,m,a,t);
- static XMLCh formatter[] = UNICODE_LITERAL_9(f,o,r,m,a,t,t,e,r);
+ static const XMLCh defaultQualifiers[] =UNICODE_LITERAL_17(d,e,f,a,u,l,t,Q,u,a,l,i,f,i,e,r,s);
+ static const XMLCh format[] = UNICODE_LITERAL_6(f,o,r,m,a,t);
+ static const XMLCh formatter[] = UNICODE_LITERAL_9(f,o,r,m,a,t,t,e,r);
static const XMLCh Scope[] = UNICODE_LITERAL_5(S,c,o,p,e);
static const XMLCh scopeDelimeter[] = UNICODE_LITERAL_14(s,c,o,p,e,D,e,l,i,m,e,t,e,r);
class SHIBSP_DLLLOCAL NameIDFromScopedAttributeDecoder : virtual public AttributeDecoder
{
public:
- NameIDFromScopedAttributeDecoder(const DOMElement* e) : AttributeDecoder(e), m_delimeter('@'),
- m_format(e ? e->getAttributeNS(NULL,format) : NULL), m_formatter(e ? e->getAttributeNS(NULL,formatter) : NULL) {
+ NameIDFromScopedAttributeDecoder(const DOMElement* e)
+ : AttributeDecoder(e),
+ m_delimeter('@'),
+ m_format(e ? e->getAttributeNS(NULL,format) : NULL),
+ m_formatter(e ? e->getAttributeNS(NULL,formatter) : NULL),
+ m_defaultQualifiers(false) {
if (e && e->hasAttributeNS(NULL,scopeDelimeter)) {
auto_ptr_char d(e->getAttributeNS(NULL,scopeDelimeter));
m_delimeter = *(d.get());
}
+ const XMLCh* flag = e ? e->getAttributeNS(NULL, defaultQualifiers) : NULL;
+ if (flag && (*flag == chLatin_t || *flag == chDigit_1))
+ m_defaultQualifiers = true;
}
~NameIDFromScopedAttributeDecoder() {}
char m_delimeter;
auto_ptr_char m_format;
auto_ptr_char m_formatter;
+ bool m_defaultQualifiers;
};
AttributeDecoder* SHIBSP_DLLLOCAL NameIDFromScopedAttributeDecoderFactory(const DOMElement* const & e)
char* val;
char* scope;
const XMLCh* xmlscope;
- QName scopeqname(NULL,Scope);
+ xmltooling::QName scopeqname(NULL,Scope);
auto_ptr<NameIDAttribute> nameid(
new NameIDAttribute(ids, (m_formatter.get() && *m_formatter.get()) ? m_formatter.get() : DEFAULT_NAMEID_FORMATTER)
);
- nameid->setCaseSensitive(m_caseSensitive);
vector<NameIDAttribute::Value>& dest = nameid->getValues();
vector<XMLObject*>::const_iterator v,stop;
destval.m_Name = val;
if (m_format.get() && *m_format.get())
destval.m_Format = m_format.get();
- if (assertingParty)
+ if (m_defaultQualifiers && assertingParty)
destval.m_NameQualifier = assertingParty;
- if (relyingParty)
+ if (m_defaultQualifiers && relyingParty)
destval.m_SPNameQualifier = relyingParty;
}
else {
}
}
- return dest.empty() ? NULL : nameid.release();
+ return dest.empty() ? NULL : _decode(nameid.release());
}
log.warn("XMLObject type not recognized by NameIDFromScopedAttributeDecoder, no values returned");
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return m_values;
}
+ /**
+ * Returns the set of values encoded as UTF-8 strings.
+ *
+ * <p>Each compound value is a pair containing the simple value and the scope.
+ *
+ * @return an immutable vector of the values
+ */
+ const std::vector< std::pair<std::string,std::string> >& getValues() const {
+ return m_values;
+ }
+
size_t valueCount() const {
return m_values.size();
}
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
char* val;
char* scope;
const XMLCh* xmlscope;
- QName scopeqname(NULL,Scope);
+ xmltooling::QName scopeqname(NULL,Scope);
auto_ptr<ScopedAttribute> scoped(new ScopedAttribute(ids, m_delimeter));
- scoped->setCaseSensitive(m_caseSensitive);
vector< pair<string,string> >& dest = scoped->getValues();
vector<XMLObject*>::const_iterator v,stop;
}
}
- return dest.empty() ? NULL : scoped.release();
+ return dest.empty() ? NULL : _decode(scoped.release());
}
const NameID* saml2name = dynamic_cast<const NameID*>(xmlObject);
log.warn("ignoring empty NameID");
}
delete[] val;
- return dest.empty() ? NULL : scoped.release();
+ return dest.empty() ? NULL : _decode(scoped.release());
}
/*\r
- * Copyright 2001-2007 Internet2\r
+ * Copyright 2001-2009 Internet2\r
*\r
* Licensed under the Apache License, Version 2.0 (the "License");\r
* you may not use this file except in compliance with the License.\r
{\r
char* val;\r
auto_ptr<SimpleAttribute> simple(new SimpleAttribute(ids));\r
- simple->setCaseSensitive(m_caseSensitive);\r
vector<string>& dest = simple->getValues();\r
vector<XMLObject*>::const_iterator v,stop;\r
\r
}\r
}\r
\r
- return dest.empty() ? NULL : simple.release();\r
+ return dest.empty() ? NULL : _decode(simple.release());\r
}\r
\r
const NameID* saml2name = dynamic_cast<const NameID*>(xmlObject);\r
else\r
log.warn("ignoring empty NameID");\r
delete[] val;\r
- return dest.empty() ? NULL : simple.release();\r
+ return dest.empty() ? NULL : _decode(simple.release());\r
}\r
--- /dev/null
+/*
+ * Copyright 2009 Internet2
+ *
+ * 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.
+ */
+
+/**
+ * @file shibsp/attribute/XMLAttribute.h
+ *
+ * An Attribute whose values are serialized XML.
+ */
+
+#ifndef __shibsp_xmlattr_h__
+#define __shibsp_xmlattr_h__
+
+#include <shibsp/attribute/Attribute.h>
+
+namespace shibsp {
+
+ /**
+ * An Attribute whose values are serialized XML.
+ */
+ class SHIBSP_API XMLAttribute : public Attribute
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param ids array with primary identifier in first position, followed by any aliases
+ */
+ XMLAttribute(const std::vector<std::string>& ids) : Attribute(ids) {}
+
+ /**
+ * Constructs based on a remoted XMLAttribute.
+ *
+ * @param in input object containing marshalled XMLAttribute
+ */
+ XMLAttribute(DDF& in) : Attribute(in) {
+ DDF val = in.first().first();
+ while (val.string()) {
+ m_values.push_back(val.string());
+ val = in.first().next();
+ }
+ }
+
+ virtual ~XMLAttribute() {}
+
+ /**
+ * Returns the set of values encoded as XML.
+ *
+ * @return a mutable vector of the values
+ */
+ std::vector<std::string>& getValues() {
+ return m_values;
+ }
+
+ /**
+ * Returns the set of values encoded as XML.
+ *
+ * @return an immutable vector of the values
+ */
+ const std::vector<std::string>& getValues() const {
+ return m_values;
+ }
+
+ size_t valueCount() const {
+ return m_values.size();
+ }
+
+ void clearSerializedValues() {
+ m_serialized.clear();
+ }
+
+ const char* getString(size_t index) const {
+ return m_values[index].c_str();
+ }
+
+ void removeValue(size_t index) {
+ Attribute::removeValue(index);
+ if (index < m_values.size())
+ m_values.erase(m_values.begin() + index);
+ }
+
+ const std::vector<std::string>& getSerializedValues() const;
+
+ DDF marshall() const {
+ DDF ddf = Attribute::marshall();
+ ddf.name("XML");
+ DDF vlist = ddf.first();
+ for (std::vector<std::string>::const_iterator i=m_values.begin(); i!=m_values.end(); ++i)
+ vlist.add(DDF(NULL).string(i->c_str()));
+ return ddf;
+ }
+
+ private:
+ std::vector<std::string> m_values;
+ };
+
+};
+
+#endif /* __shibsp_xmlattr_h__ */
--- /dev/null
+/*\r
+ * Copyright 2009 Internet2\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * XMLAttributeDecoder.cpp\r
+ *\r
+ * Decodes arbitrary XML into an XMLAttribute.\r
+ */\r
+\r
+#include "internal.h"\r
+#include "attribute/AttributeDecoder.h"\r
+#include "attribute/XMLAttribute.h"\r
+\r
+#include <saml/saml1/core/Assertions.h>\r
+#include <saml/saml2/core/Assertions.h>\r
+#include <xmltooling/util/XMLHelper.h>\r
+\r
+using namespace shibsp;\r
+using namespace opensaml;\r
+using namespace xmltooling;\r
+using namespace std;\r
+\r
+namespace shibsp {\r
+ class SHIBSP_DLLLOCAL XMLAttributeDecoder : virtual public AttributeDecoder\r
+ {\r
+ public:\r
+ XMLAttributeDecoder(const DOMElement* e) : AttributeDecoder(e) {}\r
+ ~XMLAttributeDecoder() {}\r
+\r
+ Attribute* decode(\r
+ const vector<string>& ids, const XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+ ) const;\r
+\r
+ private:\r
+ DDF convert(DOMElement* e, bool nameit=true) const;\r
+ auto_ptr_char m_formatter;\r
+ map<pair<xstring,xstring>,string> m_tagMap;\r
+ };\r
+\r
+ AttributeDecoder* SHIBSP_DLLLOCAL XMLAttributeDecoderFactory(const DOMElement* const & e)\r
+ {\r
+ return new XMLAttributeDecoder(e);\r
+ }\r
+};\r
+\r
+\r
+Attribute* XMLAttributeDecoder::decode(\r
+ const vector<string>& ids, const XMLObject* xmlObject, const char* assertingParty, const char* relyingParty\r
+ ) const\r
+{\r
+ if (!xmlObject)\r
+ return NULL;\r
+\r
+ Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeDecoder.XML");\r
+\r
+ auto_ptr<XMLAttribute> attr(new XMLAttribute(ids));\r
+ vector<string>& dest = attr->getValues();\r
+\r
+ // Handle any non-Attribute object directly.\r
+ if (!xmlObject || !XMLString::equals(saml1::Attribute::LOCAL_NAME, xmlObject->getElementQName().getLocalPart())) {\r
+ DOMElement* e = xmlObject->getDOM();\r
+ if (e) {\r
+ if (log.isDebugEnabled()) {\r
+ log.debug(\r
+ "decoding XMLAttribute (%s) from XMLObject (%s)",\r
+ ids.front().c_str(),\r
+ (xmlObject->getSchemaType() ? xmlObject->getSchemaType()->toString() : xmlObject->getElementQName().toString()).c_str()\r
+ );\r
+ }\r
+ dest.push_back(string());\r
+ XMLHelper::serialize(e, dest.back());\r
+ }\r
+ else {\r
+ log.warn("skipping XMLObject without a backing DOM");\r
+ }\r
+ return dest.empty() ? NULL : _decode(attr.release());\r
+ }\r
+\r
+ vector<XMLObject*>::const_iterator v,stop;\r
+\r
+ const saml2::Attribute* saml2attr = dynamic_cast<const saml2::Attribute*>(xmlObject);\r
+ if (saml2attr) {\r
+ const vector<XMLObject*>& values = saml2attr->getAttributeValues();\r
+ v = values.begin();\r
+ stop = values.end();\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char n(saml2attr->getName());\r
+ log.debug(\r
+ "decoding XMLAttribute (%s) from SAML 2 Attribute (%s) with %lu value(s)",\r
+ ids.front().c_str(), n.get() ? n.get() : "unnamed", values.size()\r
+ );\r
+ }\r
+ }\r
+ else {\r
+ const saml1::Attribute* saml1attr = dynamic_cast<const saml1::Attribute*>(xmlObject);\r
+ if (saml1attr) {\r
+ const vector<XMLObject*>& values = saml1attr->getAttributeValues();\r
+ v = values.begin();\r
+ stop = values.end();\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char n(saml1attr->getAttributeName());\r
+ log.debug(\r
+ "decoding XMLAttribute (%s) from SAML 1 Attribute (%s) with %lu value(s)",\r
+ ids.front().c_str(), n.get() ? n.get() : "unnamed", values.size()\r
+ );\r
+ }\r
+ }\r
+ else {\r
+ log.warn("XMLObject type not recognized by XMLAttributeDecoder, no values returned");\r
+ return NULL;\r
+ }\r
+ }\r
+\r
+ for (; v!=stop; ++v) {\r
+ DOMElement* e = (*v)->getDOM();\r
+ if (e) {\r
+ dest.push_back(string());\r
+ XMLHelper::serialize(e, dest.back());\r
+ }\r
+ else\r
+ log.warn("skipping AttributeValue without a backing DOM");\r
+ }\r
+\r
+ return dest.empty() ? NULL : _decode(attr.release());\r
+}\r
if (*id && functorMap->getMatchFunctors().count(id))
id = "";
- auto_ptr<QName> type(XMLHelper::getXSIType(e));
+ auto_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
if (!type.get())
throw ConfigurationException("Child Rule found with no xsi:type.");
using namespace std;
#define DECL_FACTORY(name) \
- SHIBSP_DLLLOCAL PluginManager< MatchFunctor,QName,pair<const FilterPolicyContext*,const DOMElement*> >::Factory name##Factory
+ SHIBSP_DLLLOCAL PluginManager< MatchFunctor,xmltooling::QName,pair<const FilterPolicyContext*,const DOMElement*> >::Factory name##Factory
#define DECL_BASIC_QNAME(name,lit) \
- QName shibsp::name##Type(shibspconstants::SHIB2ATTRIBUTEFILTER_MF_BASIC_NS, lit)
+ xmltooling::QName shibsp::name##Type(shibspconstants::SHIB2ATTRIBUTEFILTER_MF_BASIC_NS, lit)
#define DECL_SAML_QNAME(name,lit) \
- QName shibsp::name##Type(shibspconstants::SHIB2ATTRIBUTEFILTER_MF_SAML_NS, lit)
+ xmltooling::QName shibsp::name##Type(shibspconstants::SHIB2ATTRIBUTEFILTER_MF_SAML_NS, lit)
#define REGISTER_FACTORY(name) \
mgr.registerFactory(name##Type, name##Factory)
void SHIBSP_API shibsp::registerMatchFunctors()
{
- PluginManager< MatchFunctor,QName,pair<const FilterPolicyContext*,const DOMElement*> >& mgr =
+ PluginManager< MatchFunctor,xmltooling::QName,pair<const FilterPolicyContext*,const DOMElement*> >& mgr =
SPConfig::getConfig().MatchFunctorManager;
REGISTER_FACTORY(AnyMatchFunctor);
REGISTER_FACTORY(AndMatchFunctor);
if (*id && functorMap->getMatchFunctors().count(id))
id = "";
- auto_ptr<QName> type(XMLHelper::getXSIType(e));
+ auto_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
if (!type.get())
throw ConfigurationException("Child Rule found with no xsi:type.");
if (*id && functorMap->getMatchFunctors().count(id))
id = "";
- auto_ptr<QName> type(XMLHelper::getXSIType(e));
+ auto_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
if (!type.get())
throw ConfigurationException("Child Rule found with no xsi:type.");
id = "";
}
- auto_ptr<QName> type(XMLHelper::getXSIType(e));
+ auto_ptr<xmltooling::QName> type(XMLHelper::getXSIType(e));
if (type.get()) {
try {
MatchFunctor* func = SPConfig::getConfig().MatchFunctorManager.newPlugin(*type.get(), make_pair(&functorMap,e));
}
if (perm || deny) {
- if (*id)
- return m_attrRules[id] = pair< string,pair<const MatchFunctor*,const MatchFunctor*> >(attrID.get(), pair<const MatchFunctor*,const MatchFunctor*>(perm,deny));
- else
+ if (*id) {
+ m_attrRules[id] = pair< string,pair<const MatchFunctor*,const MatchFunctor*> >(attrID.get(), pair<const MatchFunctor*,const MatchFunctor*>(perm,deny));
+ return m_attrRules[id];
+ }
+ else {
return pair< string,pair<const MatchFunctor*,const MatchFunctor*> >(attrID.get(), pair<const MatchFunctor*,const MatchFunctor*>(perm,deny));
+ }
}
m_log.warn("skipping AttributeRule (%s), permit and denial rule(s) invalid or missing", id);
if (row[index-1])
attr->removeValue(index-1);
}
+ }
- // Check for no values.
- if (attr->valueCount() == 0) {
- m_log.warn(
- "no values left, removing attribute (%s) from (%s)",
- attr->getId(), issuer.get() ? issuer.get() : "unknown source"
- );
- delete attr;
- attributes.erase(attributes.begin() + a);
- continue;
- }
+ // Check for no values.
+ if (attr->valueCount() == 0) {
+ m_log.warn(
+ "no values left, removing attribute (%s) from (%s)",
+ attr->getId(), issuer.get() ? issuer.get() : "unknown source"
+ );
+ delete attr;
+ attributes.erase(attributes.begin() + a);
+ continue;
}
+
++a;
}
}
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* @file shibsp/attribute/resolver/AttributeExtractor.h
- *
+ *
* A service that extracts and decodes attributes from XML objects.
*/
/**
* Extracts the attributes found in an XMLObject.
- *
+ *
* @param application Application performing the extraction
* @param issuer source of object, if known
* @param xmlObject object to extract
* @param attributes an array to populate with the extracted attributes
- *
+ *
* @throws AttributeExtractionException thrown if there is a problem extracting attributes
*/
virtual void extractAttributes(
/** AttributeExtractor based on an XML mapping schema. */
#define XML_ATTRIBUTE_EXTRACTOR "XML"
+ /** AttributeExtractor for DelegationRestriction information. */
+ #define DELEGATION_ATTRIBUTE_EXTRACTOR "Delegation"
+
+ /** AttributeExtractor for KeyInfo information. */
+ #define KEYDESCRIPTOR_ATTRIBUTE_EXTRACTOR "KeyDescriptor"
+
/** AttributeExtractor based on chaining together other extractors. */
#define CHAINING_ATTRIBUTE_EXTRACTOR "Chaining"
};
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* @file shibsp/attribute/resolver/AttributeResolver.h
- *
+ *
* A service that transforms or resolves additional attributes for a particular subject.
*/
/**
* Creates a ResolutionContext based on session bootstrap material.
- *
+ *
* <p>This enables resolution to occur ahead of session creation so that
* Attributes can be supplied while creating the session.
- *
+ *
* @param application reference to Application that owns the eventual Session
* @param issuer issuing metadata of assertion issuer, if known
* @param protocol protocol used to establish Session
/**
* Creates a ResolutionContext for an existing Session.
- *
+ *
* @param application reference to Application that owns the Session
* @param session reference to Session
* @return newly created ResolutionContext, owned by caller
*/
virtual ResolutionContext* createResolutionContext(const Application& application, const Session& session) const=0;
-
+
/**
* Resolves attributes for a given subject and returns them in the supplied context.
- *
+ *
* @param ctx resolution context to use to resolve attributes
- *
+ *
* @throws AttributeResolutionException thrown if there is a problem resolving the attributes for the subject
*/
virtual void resolveAttributes(ResolutionContext& ctx) const=0;
/** AttributeResolver based on SAML queries to an IdP during SSO. */
#define QUERY_ATTRIBUTE_RESOLVER "Query"
+ /** AttributeResolver based on free-standing SAML queries to additional AAs. */
+ #define SIMPLEAGGREGATION_ATTRIBUTE_RESOLVER "SimpleAggregation"
+
/** AttributeResolver based on chaining together other resolvers. */
#define CHAINING_ATTRIBUTE_RESOLVER "Chaining"
};
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
static const XMLCh _AttributeExtractor[] = UNICODE_LITERAL_18(A,t,t,r,i,b,u,t,e,E,x,t,r,a,c,t,o,r);
static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);
+ SHIBSP_DLLLOCAL PluginManager<AttributeExtractor,string,const DOMElement*>::Factory DelegationAttributeExtractorFactory;
+ SHIBSP_DLLLOCAL PluginManager<AttributeExtractor,string,const DOMElement*>::Factory KeyDescriptorAttributeExtractorFactory;
SHIBSP_DLLLOCAL PluginManager<AttributeExtractor,string,const DOMElement*>::Factory XMLAttributeExtractorFactory;
AttributeExtractor* SHIBSP_DLLLOCAL ChainingExtractorFactory(const DOMElement* const & e)
{
void SHIBSP_API shibsp::registerAttributeExtractors()
{
+ SPConfig::getConfig().AttributeExtractorManager.registerFactory(DELEGATION_ATTRIBUTE_EXTRACTOR, DelegationAttributeExtractorFactory);
+ SPConfig::getConfig().AttributeExtractorManager.registerFactory(KEYDESCRIPTOR_ATTRIBUTE_EXTRACTOR, KeyDescriptorAttributeExtractorFactory);
SPConfig::getConfig().AttributeExtractorManager.registerFactory(XML_ATTRIBUTE_EXTRACTOR, XMLAttributeExtractorFactory);
SPConfig::getConfig().AttributeExtractorManager.registerFactory(CHAINING_ATTRIBUTE_EXTRACTOR, ChainingExtractorFactory);
}
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);
SHIBSP_DLLLOCAL PluginManager<AttributeResolver,string,const DOMElement*>::Factory QueryResolverFactory;
+ SHIBSP_DLLLOCAL PluginManager<AttributeResolver,string,const DOMElement*>::Factory SimpleAggregationResolverFactory;
+
AttributeResolver* SHIBSP_DLLLOCAL ChainingResolverFactory(const DOMElement* const & e)
{
return new ChainingAttributeResolver(e);
void SHIBSP_API shibsp::registerAttributeResolvers()
{
SPConfig::getConfig().AttributeResolverManager.registerFactory(QUERY_ATTRIBUTE_RESOLVER, QueryResolverFactory);
+ SPConfig::getConfig().AttributeResolverManager.registerFactory(SIMPLEAGGREGATION_ATTRIBUTE_RESOLVER, SimpleAggregationResolverFactory);
SPConfig::getConfig().AttributeResolverManager.registerFactory(CHAINING_ATTRIBUTE_RESOLVER, ChainingResolverFactory);
}
(*i)->resolveAttributes(*context.get());
chain.m_attributes.insert(chain.m_attributes.end(), context->getResolvedAttributes().begin(), context->getResolvedAttributes().end());
- chain.m_ownedAttributes.insert(chain.m_attributes.end(), context->getResolvedAttributes().begin(), context->getResolvedAttributes().end());
+ chain.m_ownedAttributes.insert(chain.m_ownedAttributes.end(), context->getResolvedAttributes().begin(), context->getResolvedAttributes().end());
context->getResolvedAttributes().clear();
chain.m_tokens.insert(chain.m_tokens.end(), context->getResolvedAssertions().begin(), context->getResolvedAssertions().end());
--- /dev/null
+/*
+ * Copyright 2009 Internet2
+ *
+ * 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.
+ */
+
+/**
+ * DelegationAttributeExtractor.cpp
+ *
+ * AttributeExtractor for DelegationRestriction information.
+ */
+
+#include "internal.h"
+#include "Application.h"
+#include "ServiceProvider.h"
+#include "attribute/ExtensibleAttribute.h"
+#include "attribute/resolver/AttributeExtractor.h"
+#include "util/SPConstants.h"
+
+#include <saml/saml2/core/Assertions.h>
+#include <saml/saml2/metadata/MetadataCredentialCriteria.h>
+#include <xmltooling/util/XMLHelper.h>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+using namespace shibsp;
+using namespace opensaml::saml2md;
+using namespace opensaml;
+using namespace xmltooling;
+using namespace std;
+
+namespace shibsp {
+
+#if defined (_MSC_VER)
+ #pragma warning( push )
+ #pragma warning( disable : 4250 )
+#endif
+
+ class DelegationExtractor : public AttributeExtractor
+ {
+ public:
+ DelegationExtractor(const DOMElement* e);
+ ~DelegationExtractor() {}
+
+ Lockable* lock() {
+ return this;
+ }
+
+ void unlock() {
+ }
+
+ void extractAttributes(
+ const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
+ ) const;
+
+ void getAttributeIds(std::vector<std::string>& attributes) const {
+ attributes.push_back(m_attributeId);
+ }
+
+ private:
+ string m_attributeId,m_formatter;
+ };
+
+#if defined (_MSC_VER)
+ #pragma warning( pop )
+#endif
+
+ AttributeExtractor* SHIBSP_DLLLOCAL DelegationAttributeExtractorFactory(const DOMElement* const & e)
+ {
+ return new DelegationExtractor(e);
+ }
+
+ static const XMLCh attributeId[] = UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,d);
+ static const XMLCh formatter[] = UNICODE_LITERAL_9(f,o,r,m,a,t,t,e,r);
+};
+
+DelegationExtractor::DelegationExtractor(const DOMElement* e) : m_attributeId("delegate"), m_formatter("$Name")
+{
+ if (e) {
+ const XMLCh* a = e->getAttributeNS(NULL, attributeId);
+ if (a && *a) {
+ auto_ptr_char temp(a);
+ m_attributeId = temp.get();
+ }
+ a = e->getAttributeNS(NULL, formatter);
+ if (a && *a) {
+ auto_ptr_char temp(a);
+ m_formatter = temp.get();
+ }
+ }
+}
+
+void DelegationExtractor::extractAttributes(
+ const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
+ ) const
+{
+ const saml2::Assertion* assertion = dynamic_cast<const saml2::Assertion*>(&xmlObject);
+ if (!assertion || !assertion->getConditions())
+ return;
+
+ Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeExtractor.Delegation");
+
+ const vector<saml2::Condition*>& conditions = const_cast<const saml2::Conditions*>(assertion->getConditions())->getConditions();
+ for (vector<saml2::Condition*>::const_iterator c = conditions.begin(); c != conditions.end(); ++c) {
+ const saml2::DelegationRestrictionType* drt = dynamic_cast<const saml2::DelegationRestrictionType*>(*c);
+ if (drt) {
+ auto_ptr<ExtensibleAttribute> attr(new ExtensibleAttribute(vector<string>(1,m_attributeId), m_formatter.c_str()));
+
+ const vector<saml2::Delegate*>& dels = drt->getDelegates();
+ for (vector<saml2::Delegate*>::const_iterator d = dels.begin(); d != dels.end(); ++d) {
+ if ((*d)->getBaseID()) {
+ log.error("delegate identified by saml:BaseID cannot be processed into an attribute value");
+ continue;
+ }
+
+ saml2::NameID* n = NULL;
+ if ((*d)->getEncryptedID()) {
+ CredentialResolver* cr = application.getCredentialResolver();
+ if (!cr) {
+ log.warn("found encrypted Delegate, but no CredentialResolver was available");
+ }
+
+ try {
+ const XMLCh* recipient = application.getRelyingParty(
+ issuer ? dynamic_cast<EntityDescriptor*>(issuer->getParent()) : NULL
+ )->getXMLString("entityID").second;
+ Locker credlocker(cr);
+ if (issuer) {
+ MetadataCredentialCriteria mcc(*issuer);
+ auto_ptr<XMLObject> decrypted((*d)->getEncryptedID()->decrypt(*cr, recipient, &mcc));
+ n = dynamic_cast<saml2::NameID*>(decrypted.release());
+ }
+ else {
+ auto_ptr<XMLObject> decrypted((*d)->getEncryptedID()->decrypt(*cr, recipient));
+ n = dynamic_cast<saml2::NameID*>(decrypted.release());
+ }
+ if (n && log.isDebugEnabled())
+ log.debugStream() << "decrypted Delegate: " << *n << logging::eol;
+ }
+ catch (exception& ex) {
+ log.error("caught exception decrypting Delegate: %s", ex.what());
+ }
+ }
+ else {
+ n = (*d)->getNameID();
+ }
+
+ if (n) {
+ DDF val = DDF(NULL).structure();
+ if ((*d)->getConfirmationMethod()) {
+ auto_ptr_char temp((*d)->getConfirmationMethod());
+ val.addmember("ConfirmationMethod").string(temp.get());
+ }
+ if ((*d)->getDelegationInstant()) {
+ auto_ptr_char temp((*d)->getDelegationInstant()->getRawData());
+ val.addmember("DelegationInstant").string(temp.get());
+ }
+
+ auto_arrayptr<char> name(toUTF8(n->getName()));\r
+ if (name.get() && *name.get()) {\r
+ val.addmember("Name").string(name.get());\r
+ char* str = toUTF8(n->getFormat());\r
+ if (str && *str)\r
+ val.addmember("Format").string(str);\r
+ delete[] str;\r
+\r
+ str = toUTF8(n->getNameQualifier());\r
+ if (str && *str)\r
+ val.addmember("NameQualifier").string(str);\r
+ delete[] str;\r
+\r
+ str = toUTF8(n->getSPNameQualifier());\r
+ if (str && *str)\r
+ val.addmember("SPNameQualifier").string(str);\r
+ delete[] str;\r
+\r
+ str = toUTF8(n->getSPProvidedID());\r
+ if (str && *str)\r
+ val.addmember("SPProvidedID").string(str);\r
+ delete[] str;\r
+ }\r
+
+ if (n != (*d)->getNameID())
+ delete n;
+
+ if (val.integer())
+ attr->getValues().add(val);
+ else
+ val.destroy();
+ }
+ }
+
+ attributes.push_back(attr.release());
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Internet2
+ *
+ * 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.
+ */
+
+/**
+ * KeyDescriptorAttributeExtractor.cpp
+ *
+ * AttributeExtractor for KeyDescriptor information.
+ */
+
+#include "internal.h"
+#include "Application.h"
+#include "attribute/AttributeDecoder.h"
+#include "attribute/SimpleAttribute.h"
+#include "attribute/resolver/AttributeExtractor.h"
+
+#include <saml/saml2/metadata/Metadata.h>
+#include <saml/saml2/metadata/MetadataCredentialCriteria.h>
+#include <xmltooling/security/SecurityHelper.h>
+#include <xmltooling/util/XMLHelper.h>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+using namespace shibsp;
+using namespace opensaml::saml2md;
+using namespace opensaml;
+using namespace xmltooling;
+using namespace std;
+
+namespace shibsp {
+
+#if defined (_MSC_VER)
+ #pragma warning( push )
+ #pragma warning( disable : 4250 )
+#endif
+
+ class KeyDescriptorExtractor : public AttributeExtractor
+ {
+ public:
+ KeyDescriptorExtractor(const DOMElement* e);
+ ~KeyDescriptorExtractor() {}
+
+ Lockable* lock() {
+ return this;
+ }
+
+ void unlock() {
+ }
+
+ void extractAttributes(
+ const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
+ ) const;
+
+ void getAttributeIds(std::vector<std::string>& attributes) const {
+ if (!m_hashId.empty())
+ attributes.push_back(m_hashId.front());
+ if (!m_signingId.empty())
+ attributes.push_back(m_signingId.front());
+ if (!m_encryptionId.empty())
+ attributes.push_back(m_encryptionId.front());
+ }
+
+ private:
+ vector<string> m_hashId;
+ vector<string> m_signingId;
+ vector<string> m_encryptionId;
+ };
+
+#if defined (_MSC_VER)
+ #pragma warning( pop )
+#endif
+
+ AttributeExtractor* SHIBSP_DLLLOCAL KeyDescriptorAttributeExtractorFactory(const DOMElement* const & e)
+ {
+ return new KeyDescriptorExtractor(e);
+ }
+
+ static const XMLCh encryptionId[] = UNICODE_LITERAL_12(e,n,c,r,y,p,t,i,o,n,I,d);
+ static const XMLCh hashId[] = UNICODE_LITERAL_6(h,a,s,h,I,d);
+ static const XMLCh signingId[] = UNICODE_LITERAL_9(s,i,g,n,i,n,g,I,d);
+};
+
+KeyDescriptorExtractor::KeyDescriptorExtractor(const DOMElement* e)
+{
+ if (e) {
+ const XMLCh* a = e->getAttributeNS(NULL, hashId);
+ if (a && *a) {
+ auto_ptr_char temp(a);
+ m_hashId.push_back(temp.get());
+ }
+ a = e->getAttributeNS(NULL, signingId);
+ if (a && *a) {
+ auto_ptr_char temp(a);
+ m_signingId.push_back(temp.get());
+ }
+ a = e->getAttributeNS(NULL, encryptionId);
+ if (a && *a) {
+ auto_ptr_char temp(a);
+ m_encryptionId.push_back(temp.get());
+ }
+ }
+ if (m_hashId.empty() && m_signingId.empty() && m_encryptionId.empty())
+ throw ConfigurationException("KeyDescriptor AttributeExtractor requires hashId, signingId, or encryptionId property.");
+}
+
+void KeyDescriptorExtractor::extractAttributes(
+ const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
+ ) const
+{
+ const RoleDescriptor* role = dynamic_cast<const RoleDescriptor*>(&xmlObject);
+ if (!role)
+ return;
+
+ vector<const Credential*> creds;
+ MetadataCredentialCriteria mcc(*role);
+
+ if (!m_signingId.empty() || !m_hashId.empty()) {
+ mcc.setUsage(Credential::SIGNING_CREDENTIAL);
+ if (application.getMetadataProvider()->resolve(creds, &mcc)) {
+ if (!m_hashId.empty()) {
+ auto_ptr<SimpleAttribute> attr(new SimpleAttribute(m_hashId));
+ vector<string>& vals = attr->getValues();
+ for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
+ if (vals.empty() || !vals.back().empty())
+ vals.push_back(string());
+ vals.back() = SecurityHelper::getDEREncoding(*(*c), true);
+ }
+ if (vals.back().empty())
+ vals.pop_back();
+ if (!vals.empty())
+ attributes.push_back(attr.release());
+ }
+ if (!m_signingId.empty()) {
+ auto_ptr<SimpleAttribute> attr(new SimpleAttribute(m_signingId));
+ vector<string>& vals = attr->getValues();
+ for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
+ if (vals.empty() || !vals.back().empty())
+ vals.push_back(string());
+ vals.back() = SecurityHelper::getDEREncoding(*(*c));
+ }
+ if (vals.back().empty())
+ vals.pop_back();
+ if (!vals.empty())
+ attributes.push_back(attr.release());
+ }
+ creds.clear();
+ }
+ }
+
+ if (!m_encryptionId.empty()) {
+ mcc.setUsage(Credential::ENCRYPTION_CREDENTIAL);
+ if (application.getMetadataProvider()->resolve(creds, &mcc)) {
+ auto_ptr<SimpleAttribute> attr(new SimpleAttribute(m_encryptionId));
+ vector<string>& vals = attr->getValues();
+ for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
+ if (vals.empty() || !vals.back().empty())
+ vals.push_back(string());
+ vals.back() = SecurityHelper::getDEREncoding(*(*c));
+ }
+ if (vals.back().empty())
+ vals.pop_back();
+ if (!vals.empty())
+ attributes.push_back(attr.release());
+ }
+ }
+}
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <saml/saml1/binding/SAML1SOAPClient.h>
#include <saml/saml1/core/Assertions.h>
#include <saml/saml1/core/Protocols.h>
-#include <saml/saml1/profile/AssertionValidator.h>
#include <saml/saml2/binding/SAML2SOAPClient.h>
#include <saml/saml2/core/Protocols.h>
#include <saml/saml2/metadata/Metadata.h>
#include <saml/saml2/metadata/MetadataProvider.h>
-#include <saml/saml2/profile/AssertionValidator.h>
#include <xmltooling/util/NDC.h>
#include <xmltooling/util/XMLHelper.h>
#include <xercesc/util/XMLUniDefs.hpp>
const NameID* nameid=NULL,
const XMLCh* authncontext_class=NULL,
const XMLCh* authncontext_decl=NULL,
- const vector<const opensaml::Assertion*>* tokens=NULL,
- const vector<Attribute*>* attributes=NULL
+ const vector<const opensaml::Assertion*>* tokens=NULL
) : m_query(true), m_app(application), m_session(NULL), m_metadata(NULL), m_entity(issuer),
m_protocol(protocol), m_nameid(nameid), m_class(authncontext_class), m_decl(authncontext_decl) {
const vector<const opensaml::Assertion*>* tokens=NULL,
const vector<shibsp::Attribute*>* attributes=NULL
) const {
- return new QueryContext(application,issuer,protocol,nameid,authncontext_class,authncontext_decl,tokens,attributes);
+ return new QueryContext(application,issuer,protocol,nameid,authncontext_class,authncontext_decl,tokens);
}
ResolutionContext* createResolutionContext(const Application& application, const Session& session) const {
bool SAML2Query(QueryContext& ctx) const;
Category& m_log;
+ string m_policyId;
vector<AttributeDesignator*> m_SAML1Designators;
vector<saml2::Attribute*> m_SAML2Designators;
};
return new QueryResolver(e);
}
+ static const XMLCh _policyId[] = UNICODE_LITERAL_8(p,o,l,i,c,y,I,d);
};
QueryResolver::QueryResolver(const DOMElement* e) : m_log(Category::getInstance(SHIBSP_LOGCAT".AttributeResolver.Query"))
xmltooling::NDC ndc("QueryResolver");
#endif
+ const XMLCh* pid = e ? e->getAttributeNS(NULL, _policyId) : NULL;
+ if (pid && *pid) {
+ auto_ptr_char temp(pid);
+ m_policyId = temp.get();
+ }
+
DOMElement* child = XMLHelper::getFirstChildElement(e);
while (child) {
try {
- if (XMLHelper::isNodeNamed(e, samlconstants::SAML20_NS, saml2::Attribute::LOCAL_NAME)) {
+ if (XMLHelper::isNodeNamed(child, samlconstants::SAML20_NS, saml2::Attribute::LOCAL_NAME)) {
auto_ptr<XMLObject> obj(saml2::AttributeBuilder::buildOneFromElement(child));
saml2::Attribute* down = dynamic_cast<saml2::Attribute*>(obj.get());
if (down) {
obj.release();
}
}
- else if (XMLHelper::isNodeNamed(e, samlconstants::SAML1P_NS, AttributeDesignator::LOCAL_NAME)) {
+ else if (XMLHelper::isNodeNamed(child, samlconstants::SAML1P_NS, AttributeDesignator::LOCAL_NAME)) {
auto_ptr<XMLObject> obj(AttributeDesignatorBuilder::buildOneFromElement(child));
AttributeDesignator* down = dynamic_cast<AttributeDesignator*>(obj.get());
if (down) {
const Application& application = ctx.getApplication();
const PropertySet* relyingParty = application.getRelyingParty(ctx.getEntityDescriptor());
- shibsp::SecurityPolicy policy(application);
+
+ // Locate policy key.
+ const char* policyId = m_policyId.empty() ? application.getString("policyId").second : m_policyId.c_str();
+
+ // Access policy properties.
+ const PropertySet* settings = application.getServiceProvider().getPolicySettings(policyId);
+ pair<bool,bool> validate = settings->getBool("validate");
+
+ shibsp::SecurityPolicy policy(application, NULL, validate.first && validate.second, policyId);
+ policy.getAudiences().push_back(relyingParty->getXMLString("entityID").second);
MetadataCredentialCriteria mcc(*AA);
shibsp::SOAPClient soaper(policy);
saml1p::Response* response=NULL;
const vector<AttributeService*>& endpoints=AA->getAttributeServices();
for (vector<AttributeService*>::const_iterator ep=endpoints.begin(); !response && ep!=endpoints.end(); ++ep) {
- if (!XMLString::equals((*ep)->getBinding(),binding.get()))
+ if (!XMLString::equals((*ep)->getBinding(),binding.get()) || !(*ep)->getLocation())
continue;
auto_ptr_char loc((*ep)->getLocation());
try {
// Now we can check the security status of the policy.
if (!policy.isAuthenticated())
throw SecurityPolicyException("Security of SAML 1.x query result not established.");
-
- // Lastly, check it over.
- saml1::AssertionValidator tokval(relyingParty->getXMLString("entityID").second, application.getAudiences(), time(NULL));
- tokval.validateAssertion(*newtoken);
}
catch (exception& ex) {
- m_log.error("assertion failed policy/validation: %s", ex.what());
+ m_log.error("assertion failed policy validation: %s", ex.what());
return true;
}
}
const Application& application = ctx.getApplication();
- shibsp::SecurityPolicy policy(application);
- MetadataCredentialCriteria mcc(*AA);
- shibsp::SOAPClient soaper(policy);
-
const PropertySet* relyingParty = application.getRelyingParty(ctx.getEntityDescriptor());
+
+ // Locate policy key.
+ const char* policyId = m_policyId.empty() ? application.getString("policyId").second : m_policyId.c_str();
+
+ // Access policy properties.
+ const PropertySet* settings = application.getServiceProvider().getPolicySettings(policyId);
+ pair<bool,bool> validate = settings->getBool("validate");
+
pair<bool,bool> signedAssertions = relyingParty->getBool("requireSignedAssertions");
pair<bool,const char*> encryption = relyingParty->getString("encryption");
+ shibsp::SecurityPolicy policy(application, NULL, validate.first && validate.second, policyId);
+ policy.getAudiences().push_back(relyingParty->getXMLString("entityID").second);
+ MetadataCredentialCriteria mcc(*AA);
+ shibsp::SOAPClient soaper(policy);
+
auto_ptr_XMLCh binding(samlconstants::SAML20_BINDING_SOAP);
saml2p::StatusResponseType* srt=NULL;
const vector<AttributeService*>& endpoints=AA->getAttributeServices();
for (vector<AttributeService*>::const_iterator ep=endpoints.begin(); !srt && ep!=endpoints.end(); ++ep) {
- if (!XMLString::equals((*ep)->getBinding(),binding.get()))
+ if (!XMLString::equals((*ep)->getBinding(),binding.get()) || !(*ep)->getLocation())
continue;
auto_ptr_char loc((*ep)->getLocation());
try {
// Now we can check the security status of the policy.
if (!policy.isAuthenticated())
throw SecurityPolicyException("Security of SAML 2.0 query result not established.");
-
- // Lastly, check it over.
- saml2::AssertionValidator tokval(relyingParty->getXMLString("entityID").second, application.getAudiences(), time(NULL));
- tokval.validateAssertion(*newtoken);
}
catch (exception& ex) {
- m_log.error("assertion failed policy/validation: %s", ex.what());
+ m_log.error("assertion failed policy validation: %s", ex.what());
return true;
}
--- /dev/null
+/*
+ * Copyright 2009 Internet2
+ *
+ * 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.
+ */
+
+/**
+ * SimpleAggregationAttributeResolver.cpp
+ *
+ * AttributeResolver based on SAML queries to third-party AA sources.
+ */
+
+#include "internal.h"
+#include "Application.h"
+#include "ServiceProvider.h"
+#include "SessionCache.h"
+#include "attribute/NameIDAttribute.h"
+#include "attribute/filtering/AttributeFilter.h"
+#include "attribute/filtering/BasicFilteringContext.h"
+#include "attribute/resolver/AttributeExtractor.h"
+#include "attribute/resolver/AttributeResolver.h"
+#include "attribute/resolver/ResolutionContext.h"
+#include "binding/SOAPClient.h"
+#include "metadata/MetadataProviderCriteria.h"
+#include "util/SPConstants.h"
+
+#include <saml/exceptions.h>
+#include <saml/SAMLConfig.h>
+#include <saml/binding/SecurityPolicy.h>
+#include <saml/saml2/binding/SAML2SOAPClient.h>
+#include <saml/saml2/core/Protocols.h>
+#include <saml/saml2/metadata/MetadataProvider.h>
+#include <xmltooling/util/NDC.h>
+#include <xmltooling/util/XMLHelper.h>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+using namespace shibsp;
+using namespace opensaml::saml2;
+using namespace opensaml::saml2p;
+using namespace opensaml::saml2md;
+using namespace opensaml;
+using namespace xmltooling;
+using namespace std;
+
+namespace shibsp {
+
+ class SHIBSP_DLLLOCAL SimpleAggregationContext : public ResolutionContext
+ {
+ public:
+ SimpleAggregationContext(const Application& application, const Session& session)
+ : m_app(application),
+ m_session(&session),
+ m_nameid(NULL),
+ m_class(XMLString::transcode(session.getAuthnContextClassRef())),
+ m_decl(XMLString::transcode(session.getAuthnContextDeclRef())),
+ m_inputTokens(NULL),
+ m_inputAttributes(NULL) {
+ }
+
+ SimpleAggregationContext(
+ const Application& application,
+ const NameID* nameid=NULL,
+ const XMLCh* authncontext_class=NULL,
+ const XMLCh* authncontext_decl=NULL,
+ const vector<const opensaml::Assertion*>* tokens=NULL,
+ const vector<shibsp::Attribute*>* attributes=NULL
+ ) : m_app(application),
+ m_session(NULL),
+ m_nameid(nameid),
+ m_class(const_cast<XMLCh*>(authncontext_class)),
+ m_decl(const_cast<XMLCh*>(authncontext_decl)),
+ m_inputTokens(tokens),
+ m_inputAttributes(attributes) {
+ }
+
+ ~SimpleAggregationContext() {
+ for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup<shibsp::Attribute>());
+ for_each(m_assertions.begin(), m_assertions.end(), xmltooling::cleanup<opensaml::Assertion>());
+ if (m_session) {
+ XMLString::release(&m_class);
+ XMLString::release(&m_decl);
+ }
+ }
+
+ const Application& getApplication() const {
+ return m_app;
+ }
+ const NameID* getNameID() const {
+ return m_session ? m_session->getNameID() : m_nameid;
+ }
+ const XMLCh* getClassRef() const {
+ return m_class;
+ }
+ const XMLCh* getDeclRef() const {
+ return m_decl;
+ }
+ const Session* getSession() const {
+ return m_session;
+ }
+ const vector<shibsp::Attribute*>* getInputAttributes() const {
+ return m_inputAttributes;
+ }
+ const vector<const opensaml::Assertion*>* getInputTokens() const {
+ return m_inputTokens;
+ }
+ vector<shibsp::Attribute*>& getResolvedAttributes() {
+ return m_attributes;
+ }
+ vector<opensaml::Assertion*>& getResolvedAssertions() {
+ return m_assertions;
+ }
+
+ private:
+ const Application& m_app;
+ const Session* m_session;
+ const NameID* m_nameid;
+ XMLCh* m_class;
+ XMLCh* m_decl;
+ const vector<const opensaml::Assertion*>* m_inputTokens;
+ const vector<shibsp::Attribute*>* m_inputAttributes;
+ vector<shibsp::Attribute*> m_attributes;
+ vector<opensaml::Assertion*> m_assertions;
+ };
+
+ class SHIBSP_DLLLOCAL SimpleAggregationResolver : public AttributeResolver
+ {
+ public:
+ SimpleAggregationResolver(const DOMElement* e);
+ ~SimpleAggregationResolver() {
+ delete m_trust;
+ delete m_metadata;
+ for_each(m_designators.begin(), m_designators.end(), xmltooling::cleanup<saml2::Attribute>());
+ }
+
+ Lockable* lock() {return this;}
+ void unlock() {}
+
+ ResolutionContext* createResolutionContext(
+ const Application& application,
+ const EntityDescriptor* issuer,
+ const XMLCh* protocol,
+ const NameID* nameid=NULL,
+ const XMLCh* authncontext_class=NULL,
+ const XMLCh* authncontext_decl=NULL,
+ const vector<const opensaml::Assertion*>* tokens=NULL,
+ const vector<shibsp::Attribute*>* attributes=NULL
+ ) const {
+ return new SimpleAggregationContext(application,nameid,authncontext_class,authncontext_decl,tokens,attributes);
+ }
+
+ ResolutionContext* createResolutionContext(const Application& application, const Session& session) const {
+ return new SimpleAggregationContext(application,session);
+ }
+
+ void resolveAttributes(ResolutionContext& ctx) const;
+
+ void getAttributeIds(vector<string>& attributes) const {
+ // Nothing to do, only the extractor would actually generate them.
+ }
+
+ private:
+ bool doQuery(SimpleAggregationContext& ctx, const char* entityID, const NameID* name) const;
+
+ Category& m_log;
+ string m_policyId;
+ vector<string> m_attributeIds;
+ xstring m_format;
+ MetadataProvider* m_metadata;
+ TrustEngine* m_trust;
+ vector<saml2::Attribute*> m_designators;
+ vector< pair<string,bool> > m_sources;
+ };
+
+ AttributeResolver* SHIBSP_DLLLOCAL SimpleAggregationResolverFactory(const DOMElement* const & e)
+ {
+ return new SimpleAggregationResolver(e);
+ }
+
+ static const XMLCh attributeId[] = UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,d);
+ static const XMLCh Entity[] = UNICODE_LITERAL_6(E,n,t,i,t,y);
+ static const XMLCh EntityReference[] = UNICODE_LITERAL_15(E,n,t,i,t,y,R,e,f,e,r,e,n,c,e);
+ static const XMLCh format[] = UNICODE_LITERAL_6(f,o,r,m,a,t);
+ static const XMLCh _MetadataProvider[] = UNICODE_LITERAL_16(M,e,t,a,d,a,t,a,P,r,o,v,i,d,e,r);
+ static const XMLCh policyId[] = UNICODE_LITERAL_8(p,o,l,i,c,y,I,d);
+ static const XMLCh _TrustEngine[] = UNICODE_LITERAL_11(T,r,u,s,t,E,n,g,i,n,e);
+ static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);
+};
+
+SimpleAggregationResolver::SimpleAggregationResolver(const DOMElement* e)
+ : m_log(Category::getInstance(SHIBSP_LOGCAT".AttributeResolver.SimpleAggregation")), m_metadata(NULL), m_trust(NULL)
+{
+#ifdef _DEBUG
+ xmltooling::NDC ndc("SimpleAggregationResolver");
+#endif
+
+ const XMLCh* pid = e ? e->getAttributeNS(NULL, policyId) : NULL;
+ if (pid && *pid) {
+ auto_ptr_char temp(pid);
+ m_policyId = temp.get();
+ }
+
+ pid = e ? e->getAttributeNS(NULL, attributeId) : NULL;
+ if (pid && *pid) {
+ char* dup = XMLString::transcode(pid);
+ char* pos;
+ char* start = dup;
+ while (start && *start) {
+ while (*start && isspace(*start))
+ start++;
+ if (!*start)
+ break;
+ pos = strchr(start,' ');
+ if (pos)
+ *pos=0;
+ m_attributeIds.push_back(start);
+ start = pos ? pos+1 : NULL;
+ }
+ XMLString::release(&dup);
+
+ pid = e->getAttributeNS(NULL, format);
+ if (pid && *pid)
+ m_format = pid;
+
+ }
+
+ DOMElement* child = XMLHelper::getFirstChildElement(e, _MetadataProvider);
+ if (child) {
+ auto_ptr_char type(child->getAttributeNS(NULL, _type));
+ if (!type.get() || !*type.get())
+ throw ConfigurationException("MetadataProvider element missing type attribute.");
+ m_log.info("building MetadataProvider of type %s...", type.get());
+ auto_ptr<MetadataProvider> mp(SAMLConfig::getConfig().MetadataProviderManager.newPlugin(type.get(), child));
+ mp->init();
+ m_metadata = mp.release();
+ }
+
+ child = XMLHelper::getFirstChildElement(e, _TrustEngine);
+ if (child) {
+ try {
+ auto_ptr_char type(child->getAttributeNS(NULL, _type));
+ if (!type.get() || !*type.get())
+ throw ConfigurationException("TrustEngine element missing type attribute.");
+ m_log.info("building TrustEngine of type %s...", type.get());
+ m_trust = XMLToolingConfig::getConfig().TrustEngineManager.newPlugin(type.get(), child);
+ }
+ catch (exception&) {
+ delete m_metadata;
+ throw;
+ }
+ }
+
+ child = XMLHelper::getFirstChildElement(e);
+ while (child) {
+ if (child->hasChildNodes() && XMLString::equals(child->getLocalName(), Entity)) {
+ pid = child->getFirstChild()->getNodeValue();
+ if (pid && *pid) {
+ auto_ptr_char tpid(pid);
+ m_sources.push_back(pair<string,bool>(tpid.get(),true));
+ }
+ }
+ else if (child->hasChildNodes() && XMLString::equals(child->getLocalName(), EntityReference)) {
+ pid = child->getFirstChild()->getNodeValue();
+ if (pid && *pid) {
+ auto_ptr_char tpid(pid);
+ m_sources.push_back(pair<string,bool>(tpid.get(),false));
+ }
+ }
+ else if (XMLHelper::isNodeNamed(child, samlconstants::SAML20_NS, saml2::Attribute::LOCAL_NAME)) {
+ try {
+ auto_ptr<XMLObject> obj(saml2::AttributeBuilder::buildOneFromElement(child));
+ saml2::Attribute* down = dynamic_cast<saml2::Attribute*>(obj.get());
+ if (down) {
+ m_designators.push_back(down);
+ obj.release();
+ }
+ }
+ catch (exception& ex) {
+ m_log.error("exception loading attribute designator: %s", ex.what());
+ }
+ }
+ child = XMLHelper::getNextSiblingElement(child);
+ }
+
+}
+
+bool SimpleAggregationResolver::doQuery(SimpleAggregationContext& ctx, const char* entityID, const NameID* name) const
+{
+#ifdef _DEBUG
+ xmltooling::NDC ndc("doQuery");
+#endif
+ const Application& application = ctx.getApplication();
+ MetadataProviderCriteria mc(application, entityID, &AttributeAuthorityDescriptor::ELEMENT_QNAME, samlconstants::SAML20P_NS);
+ Locker mlocker(m_metadata);
+ const AttributeAuthorityDescriptor* AA=NULL;
+ pair<const EntityDescriptor*,const RoleDescriptor*> mdresult =
+ (m_metadata ? m_metadata : application.getMetadataProvider())->getEntityDescriptor(mc);
+ if (!mdresult.first) {
+ m_log.warn("unable to locate metadata for provider (%s)", entityID);
+ return false;
+ }
+ else if (!(AA=dynamic_cast<const AttributeAuthorityDescriptor*>(mdresult.second))) {
+ m_log.warn("no SAML 2 AttributeAuthority role found in metadata for (%s)", entityID);
+ return false;
+ }
+
+ const PropertySet* relyingParty = application.getRelyingParty(mdresult.first);
+
+ // Locate policy key.
+ const char* policyId = m_policyId.empty() ? application.getString("policyId").second : m_policyId.c_str();
+
+ // Access policy properties.
+ const PropertySet* settings = application.getServiceProvider().getPolicySettings(policyId);
+ pair<bool,bool> validate = settings->getBool("validate");
+
+ pair<bool,bool> signedAssertions = relyingParty->getBool("requireSignedAssertions");
+ pair<bool,const char*> encryption = relyingParty->getString("encryption");
+
+ shibsp::SecurityPolicy policy(application, NULL, validate.first && validate.second, policyId);
+ if (m_metadata)
+ policy.setMetadataProvider(m_metadata);
+ if (m_trust)
+ policy.setTrustEngine(m_trust);
+ policy.getAudiences().push_back(relyingParty->getXMLString("entityID").second);
+
+ MetadataCredentialCriteria mcc(*AA);
+ shibsp::SOAPClient soaper(policy);
+
+ auto_ptr_XMLCh binding(samlconstants::SAML20_BINDING_SOAP);
+ saml2p::StatusResponseType* srt=NULL;
+ const vector<AttributeService*>& endpoints=AA->getAttributeServices();
+ for (vector<AttributeService*>::const_iterator ep=endpoints.begin(); !srt && ep!=endpoints.end(); ++ep) {
+ if (!XMLString::equals((*ep)->getBinding(),binding.get()) || !(*ep)->getLocation())
+ continue;
+ auto_ptr_char loc((*ep)->getLocation());
+ try {
+ auto_ptr<saml2::Subject> subject(saml2::SubjectBuilder::buildSubject());
+
+ // Encrypt the NameID?
+ if (encryption.first && (!strcmp(encryption.second, "true") || !strcmp(encryption.second, "back"))) {
+ auto_ptr<EncryptedID> encrypted(EncryptedIDBuilder::buildEncryptedID());
+ MetadataCredentialCriteria mcc(*AA);
+ encrypted->encrypt(
+ *name,
+ *(policy.getMetadataProvider()),
+ mcc,
+ false,
+ relyingParty->getXMLString("encryptionAlg").second
+ );
+ subject->setEncryptedID(encrypted.release());
+ }
+ else {
+ subject->setNameID(name->cloneNameID());
+ }
+
+ saml2p::AttributeQuery* query = saml2p::AttributeQueryBuilder::buildAttributeQuery();
+ query->setSubject(subject.release());
+ Issuer* iss = IssuerBuilder::buildIssuer();
+ iss->setName(relyingParty->getXMLString("entityID").second);
+ query->setIssuer(iss);
+ for (vector<saml2::Attribute*>::const_iterator ad = m_designators.begin(); ad!=m_designators.end(); ++ad)
+ query->getAttributes().push_back((*ad)->cloneAttribute());
+
+ SAML2SOAPClient client(soaper, false);
+ client.sendSAML(query, application.getId(), mcc, loc.get());
+ srt = client.receiveSAML();
+ }
+ catch (exception& ex) {
+ m_log.error("exception during SAML query to %s: %s", loc.get(), ex.what());
+ soaper.reset();
+ }
+ }
+
+ if (!srt) {
+ m_log.error("unable to obtain a SAML response from attribute authority (%s)", entityID);
+ return false;
+ }
+ saml2p::Response* response = dynamic_cast<saml2p::Response*>(srt);
+ if (!response) {
+ delete srt;
+ m_log.error("message was not a samlp:Response");
+ return true;
+ }
+ else if (!response->getStatus() || !response->getStatus()->getStatusCode() ||
+ !XMLString::equals(response->getStatus()->getStatusCode()->getValue(), saml2p::StatusCode::SUCCESS)) {
+ delete srt;
+ m_log.error("attribute authority (%s) returned a SAML error", entityID);
+ return true;
+ }
+
+ const vector<saml2::Assertion*>& assertions = const_cast<const saml2p::Response*>(response)->getAssertions();
+ if (assertions.empty()) {
+ delete srt;
+ m_log.warn("response from attribute authority (%s) was empty", entityID);
+ return true;
+ }
+ else if (assertions.size()>1)
+ m_log.warn("resolver only supports one assertion in the query response");
+
+ auto_ptr<saml2p::StatusResponseType> wrapper(srt);
+ saml2::Assertion* newtoken = assertions.front();
+
+ if (!newtoken->getSignature() && signedAssertions.first && signedAssertions.second) {
+ m_log.error("assertion unsigned, rejecting it based on signedAssertions policy");
+ return true;
+ }
+
+ try {
+ // We're going to insist that the assertion issuer is the same as the peer.
+ // Reset the policy's message bits and extract them from the assertion.
+ policy.reset(true);
+ policy.setMessageID(newtoken->getID());
+ policy.setIssueInstant(newtoken->getIssueInstantEpoch());
+ policy.setIssuer(newtoken->getIssuer());
+ policy.evaluate(*newtoken);
+
+ // Now we can check the security status of the policy.
+ if (!policy.isAuthenticated())
+ throw SecurityPolicyException("Security of SAML 2.0 query result not established.");
+ }
+ catch (exception& ex) {
+ m_log.error("assertion failed policy validation: %s", ex.what());
+ return true;
+ }
+
+ newtoken->detach();
+ wrapper.release();
+ ctx.getResolvedAssertions().push_back(newtoken);
+
+ // Finally, extract and filter the result.
+ try {
+ AttributeExtractor* extractor = application.getAttributeExtractor();
+ if (extractor) {
+ Locker extlocker(extractor);
+ extractor->extractAttributes(application, AA, *newtoken, ctx.getResolvedAttributes());
+ }
+
+ AttributeFilter* filter = application.getAttributeFilter();
+ if (filter) {
+ BasicFilteringContext fc(application, ctx.getResolvedAttributes(), AA, ctx.getClassRef(), ctx.getDeclRef());
+ Locker filtlocker(filter);
+ filter->filterAttributes(fc, ctx.getResolvedAttributes());
+ }
+ }
+ catch (exception& ex) {
+ m_log.error("caught exception extracting/filtering attributes from query result: %s", ex.what());
+ for_each(ctx.getResolvedAttributes().begin(), ctx.getResolvedAttributes().end(), xmltooling::cleanup<shibsp::Attribute>());
+ ctx.getResolvedAttributes().clear();
+ }
+
+ return true;
+}
+
+void SimpleAggregationResolver::resolveAttributes(ResolutionContext& ctx) const
+{
+#ifdef _DEBUG
+ xmltooling::NDC ndc("resolveAttributes");
+#endif
+
+ SimpleAggregationContext& qctx = dynamic_cast<SimpleAggregationContext&>(ctx);
+
+ // First we manufacture the appropriate NameID to use.
+ NameID* n=NULL;
+ for (vector<string>::const_iterator a = m_attributeIds.begin(); !n && a != m_attributeIds.end(); ++a) {
+ const Attribute* attr=NULL;
+ if (qctx.getSession()) {
+ // Input attributes should be available via multimap.
+ pair<multimap<string,const Attribute*>::const_iterator, multimap<string,const Attribute*>::const_iterator> range =
+ qctx.getSession()->getIndexedAttributes().equal_range(*a);
+ for (; !attr && range.first != range.second; ++range.first) {
+ if (range.first->second->valueCount() > 0)
+ attr = range.first->second;
+ }
+ }
+ else if (qctx.getInputAttributes()) {
+ // Have to loop over unindexed set.
+ const vector<Attribute*>* matches = qctx.getInputAttributes();
+ for (vector<Attribute*>::const_iterator match = matches->begin(); !attr && match != matches->end(); ++match) {
+ if (*a == (*match)->getId() && (*match)->valueCount() > 0)
+ attr = *match;
+ }
+ }
+
+ if (attr) {
+ m_log.debug("using input attribute (%s) as identifier for queries", attr->getId());
+ n = NameIDBuilder::buildNameID();
+ const NameIDAttribute* down = dynamic_cast<const NameIDAttribute*>(attr);
+ if (down) {
+ // We can create a NameID directly from the source material.
+ const NameIDAttribute::Value& v = down->getValues().front();
+ XMLCh* val = fromUTF8(v.m_Name.c_str());
+ n->setName(val);
+ delete[] val;
+ if (!v.m_Format.empty()) {
+ val = fromUTF8(v.m_Format.c_str());
+ n->setFormat(val);
+ delete[] val;
+ }
+ if (!v.m_NameQualifier.empty()) {
+ val = fromUTF8(v.m_NameQualifier.c_str());
+ n->setNameQualifier(val);
+ delete[] val;
+ }
+ if (!v.m_SPNameQualifier.empty()) {
+ val = fromUTF8(v.m_SPNameQualifier.c_str());
+ n->setSPNameQualifier(val);
+ delete[] val;
+ }
+ if (!v.m_SPProvidedID.empty()) {
+ val = fromUTF8(v.m_SPProvidedID.c_str());
+ n->setSPProvidedID(val);
+ delete[] val;
+ }
+ }
+ else {
+ // We have to mock up the NameID.
+ XMLCh* val = fromUTF8(attr->getSerializedValues().front().c_str());
+ n->setName(val);
+ delete[] val;
+ if (!m_format.empty())
+ n->setFormat(m_format.c_str());
+ }
+ }
+ }
+
+ if (!n) {
+ if (qctx.getNameID() && m_attributeIds.empty()) {
+ m_log.debug("using authenticated NameID as identifier for queries");
+ }
+ else {
+ m_log.warn("unable to resolve attributes, no suitable query identifier found");
+ return;
+ }
+ }
+
+ auto_ptr<NameID> wrapper(n);
+
+ set<string> history;
+
+ // We have a master loop over all the possible sources of material.
+ for (vector< pair<string,bool> >::const_iterator source = m_sources.begin(); source != m_sources.end(); ++source) {
+ if (source->second) {
+ // A literal entityID to query.
+ if (history.count(source->first) == 0) {
+ m_log.debug("issuing SAML query to (%s)", source->first.c_str());
+ doQuery(qctx, source->first.c_str(), n ? n : qctx.getNameID());
+ history.insert(source->first);
+ }
+ else {
+ m_log.debug("skipping previously queried attribute source (%s)", source->first.c_str());
+ }
+ }
+ else {
+ m_log.debug("using attribute sources referenced in attribute (%s)", source->first.c_str());
+ if (qctx.getSession()) {
+ // Input attributes should be available via multimap.
+ pair<multimap<string,const Attribute*>::const_iterator, multimap<string,const Attribute*>::const_iterator> range =
+ qctx.getSession()->getIndexedAttributes().equal_range(source->first);
+ for (; range.first != range.second; ++range.first) {
+ const vector<string>& links = range.first->second->getSerializedValues();
+ for (vector<string>::const_iterator link = links.begin(); link != links.end(); ++link) {
+ if (history.count(*link) == 0) {
+ m_log.debug("issuing SAML query to (%s)", link->c_str());
+ doQuery(qctx, link->c_str(), n ? n : qctx.getNameID());
+ history.insert(*link);
+ }
+ else {
+ m_log.debug("skipping previously queried attribute source (%s)", link->c_str());
+ }
+ }
+ }
+ }
+ else if (qctx.getInputAttributes()) {
+ // Have to loop over unindexed set.
+ const vector<Attribute*>* matches = qctx.getInputAttributes();
+ for (vector<Attribute*>::const_iterator match = matches->begin(); match != matches->end(); ++match) {
+ if (source->first == (*match)->getId()) {
+ const vector<string>& links = (*match)->getSerializedValues();
+ for (vector<string>::const_iterator link = links.begin(); link != links.end(); ++link) {
+ if (history.count(*link) == 0) {
+ m_log.debug("issuing SAML query to (%s)", link->c_str());
+ doQuery(qctx, link->c_str(), n ? n : qctx.getNameID());
+ history.insert(*link);
+ }
+ else {
+ m_log.debug("skipping previously queried attribute source (%s)", link->c_str());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "Application.h"
#include "ServiceProvider.h"
#include "attribute/AttributeDecoder.h"
+#include "attribute/filtering/AttributeFilter.h"
+#include "attribute/filtering/BasicFilteringContext.h"
#include "attribute/resolver/AttributeExtractor.h"
+#include "security/SecurityPolicy.h"
#include "util/SPConstants.h"
+#include <saml/SAMLConfig.h>
#include <saml/saml1/core/Assertions.h>
#include <saml/saml2/core/Assertions.h>
#include <saml/saml2/metadata/MetadataCredentialCriteria.h>
+#include <saml/saml2/metadata/ObservableMetadataProvider.h>
#include <xmltooling/util/NDC.h>
#include <xmltooling/util/ReloadableXMLFile.h>
#include <xmltooling/util/XMLHelper.h>
#pragma warning( disable : 4250 )
#endif
- class XMLExtractorImpl
+ class XMLExtractorImpl : public ObservableMetadataProvider::Observer
{
public:
XMLExtractorImpl(const DOMElement* e, Category& log);
~XMLExtractorImpl() {
- for (attrmap_t::iterator i = m_attrMap.begin(); i!=m_attrMap.end(); ++i)
- delete i->second.first;
+ for (map<const ObservableMetadataProvider*,decoded_t>::iterator i=m_decodedMap.begin(); i!=m_decodedMap.end(); ++i) {
+ i->first->removeObserver(this);
+ for (decoded_t::iterator attrs = i->second.begin(); attrs!=i->second.end(); ++attrs)
+ for_each(attrs->second.begin(), attrs->second.end(), mem_fun_ref<DDF&,DDF>(&DDF::destroy));
+ }
+ delete m_attrLock;
+ delete m_trust;
+ delete m_metadata;
+ delete m_filter;
+ for (attrmap_t::iterator j = m_attrMap.begin(); j!=m_attrMap.end(); ++j)
+ delete j->second.first;
if (m_document)
m_document->release();
}
m_document = doc;
}
+ void onEvent(const ObservableMetadataProvider& metadata) const {
+ // Destroy attributes we cached from this provider.
+ m_attrLock->wrlock();
+ decoded_t& d = m_decodedMap[&metadata];
+ for (decoded_t::iterator a = d.begin(); a!=d.end(); ++a)
+ for_each(a->second.begin(), a->second.end(), mem_fun_ref<DDF&,DDF>(&DDF::destroy));
+ d.clear();
+ m_attrLock->unlock();
+ }
+
void extractAttributes(
- const Application& application, const char* assertingParty, const NameIdentifier& nameid, vector<Attribute*>& attributes
+ const Application& application,
+ const char* assertingParty,
+ const char* relyingParty,
+ const NameIdentifier& nameid,
+ vector<Attribute*>& attributes
) const;
void extractAttributes(
- const Application& application, const char* assertingParty, const NameID& nameid, vector<Attribute*>& attributes
+ const Application& application,
+ const char* assertingParty,
+ const char* relyingParty,
+ const NameID& nameid,
+ vector<Attribute*>& attributes
) const;
void extractAttributes(
- const Application& application, const char* assertingParty, const saml1::Attribute& attr, vector<Attribute*>& attributes
+ const Application& application,
+ const char* assertingParty,
+ const char* relyingParty,
+ const saml1::Attribute& attr,
+ vector<Attribute*>& attributes
) const;
void extractAttributes(
- const Application& application, const char* assertingParty, const saml2::Attribute& attr, vector<Attribute*>& attributes
+ const Application& application,
+ const char* assertingParty,
+ const char* relyingParty,
+ const saml2::Attribute& attr,
+ vector<Attribute*>& attributes
) const;
void extractAttributes(
- const Application& application, const char* assertingParty, const Extensions& ext, vector<Attribute*>& attributes
+ const Application& application,
+ const ObservableMetadataProvider* observable,
+ const XMLCh* entityID,
+ const char* relyingParty,
+ const Extensions& ext,
+ vector<Attribute*>& attributes
) const;
void getAttributeIds(vector<string>& attributes) const {
#endif
attrmap_t m_attrMap;
vector<string> m_attributeIds;
+
+ // settings for embedded assertions in metadata
+ auto_ptr_char m_policyId;
+ MetadataProvider* m_metadata;
+ TrustEngine* m_trust;
+ AttributeFilter* m_filter;
+ bool m_entityAssertions;
+
+ // manages caching of decoded Attributes
+ mutable RWLock* m_attrLock;
+ typedef map< const EntityAttributes*,vector<DDF> > decoded_t;
+ mutable map<const ObservableMetadataProvider*,decoded_t> m_decodedMap;
};
class XMLExtractor : public AttributeExtractor, public ReloadableXMLFile
return new XMLExtractor(e);
}
+ static const XMLCh _aliases[] = UNICODE_LITERAL_7(a,l,i,a,s,e,s);
static const XMLCh _AttributeDecoder[] = UNICODE_LITERAL_16(A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
+ static const XMLCh _AttributeFilter[] = UNICODE_LITERAL_15(A,t,t,r,i,b,u,t,e,F,i,l,t,e,r);
static const XMLCh Attributes[] = UNICODE_LITERAL_10(A,t,t,r,i,b,u,t,e,s);
static const XMLCh _id[] = UNICODE_LITERAL_2(i,d);
- static const XMLCh _aliases[] = UNICODE_LITERAL_7(a,l,i,a,s,e,s);
+ static const XMLCh _MetadataProvider[] = UNICODE_LITERAL_16(M,e,t,a,d,a,t,a,P,r,o,v,i,d,e,r);
static const XMLCh _name[] = UNICODE_LITERAL_4(n,a,m,e);
static const XMLCh nameFormat[] = UNICODE_LITERAL_10(n,a,m,e,F,o,r,m,a,t);
+ static const XMLCh metadataPolicyId[] = UNICODE_LITERAL_16(m,e,t,a,d,a,t,a,P,o,l,i,c,y,I,d);
+ static const XMLCh _TrustEngine[] = UNICODE_LITERAL_11(T,r,u,s,t,E,n,g,i,n,e);
+ static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);
};
-XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log) : m_log(log), m_document(NULL)
+XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log)
+ : m_log(log),
+ m_document(NULL),
+ m_policyId(e ? e->getAttributeNS(NULL, metadataPolicyId) : NULL),
+ m_metadata(NULL),
+ m_trust(NULL),
+ m_filter(NULL),
+ m_entityAssertions(true),
+ m_attrLock(NULL)
{
#ifdef _DEBUG
xmltooling::NDC ndc("XMLExtractorImpl");
if (!XMLHelper::isNodeNamed(e, shibspconstants::SHIB2ATTRIBUTEMAP_NS, Attributes))
throw ConfigurationException("XML AttributeExtractor requires am:Attributes at root of configuration.");
- DOMElement* child = XMLHelper::getFirstChildElement(e, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);
+ DOMElement* child = XMLHelper::getFirstChildElement(e, shibspconstants::SHIB2ATTRIBUTEMAP_NS, _MetadataProvider);
+ if (child) {
+ try {
+ auto_ptr_char type(child->getAttributeNS(NULL, _type));
+ if (!type.get() || !*type.get())
+ throw ConfigurationException("MetadataProvider element missing type attribute.");
+ m_log.info("building MetadataProvider of type %s...", type.get());
+ auto_ptr<MetadataProvider> mp(SAMLConfig::getConfig().MetadataProviderManager.newPlugin(type.get(), child));
+ mp->init();
+ m_metadata = mp.release();
+ }
+ catch (exception& ex) {
+ m_entityAssertions = false;
+ m_log.crit("error building/initializing dedicated MetadataProvider: %s", ex.what());
+ m_log.crit("disabling support for Assertions in EntityAttributes extension");
+ }
+ }
+
+ if (m_entityAssertions) {
+ child = XMLHelper::getFirstChildElement(e, shibspconstants::SHIB2ATTRIBUTEMAP_NS, _TrustEngine);
+ if (child) {
+ try {
+ auto_ptr_char type(child->getAttributeNS(NULL, _type));
+ if (!type.get() || !*type.get())
+ throw ConfigurationException("TrustEngine element missing type attribute.");
+ m_log.info("building TrustEngine of type %s...", type.get());
+ m_trust = XMLToolingConfig::getConfig().TrustEngineManager.newPlugin(type.get(), child);
+ }
+ catch (exception& ex) {
+ m_entityAssertions = false;
+ m_log.crit("error building/initializing dedicated TrustEngine: %s", ex.what());
+ m_log.crit("disabling support for Assertions in EntityAttributes extension");
+ }
+ }
+ }
+
+ if (m_entityAssertions) {
+ child = XMLHelper::getFirstChildElement(e, shibspconstants::SHIB2ATTRIBUTEMAP_NS, _AttributeFilter);
+ if (child) {
+ try {
+ auto_ptr_char type(child->getAttributeNS(NULL, _type));
+ if (!type.get() || !*type.get())
+ throw ConfigurationException("AttributeFilter element missing type attribute.");
+ m_log.info("building AttributeFilter of type %s...", type.get());
+ m_filter = SPConfig::getConfig().AttributeFilterManager.newPlugin(type.get(), child);
+ }
+ catch (exception& ex) {
+ m_entityAssertions = false;
+ m_log.crit("error building/initializing dedicated AttributeFilter: %s", ex.what());
+ m_log.crit("disabling support for Assertions in EntityAttributes extension");
+ }
+ }
+ }
+
+ child = XMLHelper::getFirstChildElement(e, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);
while (child) {
// Check for missing name or id.
const XMLCh* name = child->getAttributeNS(NULL, _name);
try {
DOMElement* dchild = XMLHelper::getFirstChildElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, _AttributeDecoder);
if (dchild) {
- auto_ptr<QName> q(XMLHelper::getXSIType(dchild));
+ auto_ptr<xmltooling::QName> q(XMLHelper::getXSIType(dchild));
if (q.get())
decoder = SPConfig::getConfig().AttributeDecoderManager.newPlugin(*q.get(), dchild);
}
child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);
}
+
+ m_attrLock = RWLock::create();
}
void XMLExtractorImpl::extractAttributes(
- const Application& application, const char* assertingParty, const NameIdentifier& nameid, vector<Attribute*>& attributes
+ const Application& application,
+ const char* assertingParty,
+ const char* relyingParty,
+ const NameIdentifier& nameid,
+ vector<Attribute*>& attributes
) const
{
#ifdef HAVE_GOOD_STL
auto_ptr_char temp(format);
if ((rule=m_attrMap.find(pair<string,string>(temp.get(),string()))) != m_attrMap.end()) {
#endif
- Attribute* a = rule->second.first->decode(rule->second.second, &nameid, assertingParty, application.getString("entityID").second);
+ Attribute* a = rule->second.first->decode(rule->second.second, &nameid, assertingParty, relyingParty);
if (a)
attributes.push_back(a);
}
}
void XMLExtractorImpl::extractAttributes(
- const Application& application, const char* assertingParty, const NameID& nameid, vector<Attribute*>& attributes
+ const Application& application,
+ const char* assertingParty,
+ const char* relyingParty,
+ const NameID& nameid,
+ vector<Attribute*>& attributes
) const
{
#ifdef HAVE_GOOD_STL
auto_ptr_char temp(format);
if ((rule=m_attrMap.find(pair<string,string>(temp.get(),string()))) != m_attrMap.end()) {
#endif
- Attribute* a = rule->second.first->decode(rule->second.second, &nameid, assertingParty, application.getString("entityID").second);
+ Attribute* a = rule->second.first->decode(rule->second.second, &nameid, assertingParty, relyingParty);
if (a)
attributes.push_back(a);
}
}
void XMLExtractorImpl::extractAttributes(
- const Application& application, const char* assertingParty, const saml1::Attribute& attr, vector<Attribute*>& attributes
+ const Application& application,
+ const char* assertingParty,
+ const char* relyingParty,
+ const saml1::Attribute& attr,
+ vector<Attribute*>& attributes
) const
{
#ifdef HAVE_GOOD_STL
auto_ptr_char temp2(format);
if ((rule=m_attrMap.find(pair<string,string>(temp1.get(),temp2.get()))) != m_attrMap.end()) {
#endif
- Attribute* a = rule->second.first->decode(rule->second.second, &attr, assertingParty, application.getString("entityID").second);
+ Attribute* a = rule->second.first->decode(rule->second.second, &attr, assertingParty, relyingParty);
if (a)
attributes.push_back(a);
}
}
void XMLExtractorImpl::extractAttributes(
- const Application& application, const char* assertingParty, const saml2::Attribute& attr, vector<Attribute*>& attributes
+ const Application& application,
+ const char* assertingParty,
+ const char* relyingParty,
+ const saml2::Attribute& attr,
+ vector<Attribute*>& attributes
) const
{
#ifdef HAVE_GOOD_STL
auto_ptr_char temp2(format);
if ((rule=m_attrMap.find(pair<string,string>(temp1.get(),temp2.get()))) != m_attrMap.end()) {
#endif
- Attribute* a = rule->second.first->decode(rule->second.second, &attr, assertingParty, application.getString("entityID").second);
+ Attribute* a = rule->second.first->decode(rule->second.second, &attr, assertingParty, relyingParty);
if (a)
attributes.push_back(a);
}
}
void XMLExtractorImpl::extractAttributes(
- const Application& application, const char* assertingParty, const Extensions& ext, vector<Attribute*>& attributes
+ const Application& application,
+ const ObservableMetadataProvider* observable,
+ const XMLCh* entityID,
+ const char* relyingParty,
+ const Extensions& ext,
+ vector<Attribute*>& attributes
) const
{
- const vector<XMLObject*> exts = ext.getUnknownXMLObjects();
+ const vector<XMLObject*>& exts = ext.getUnknownXMLObjects();
for (vector<XMLObject*>::const_iterator i = exts.begin(); i!=exts.end(); ++i) {
- const saml2::Attribute* attr = dynamic_cast<const saml2::Attribute*>(*i);
- if (attr)
- extractAttributes(application, assertingParty, *attr, attributes);
+ const EntityAttributes* container = dynamic_cast<const EntityAttributes*>(*i);
+ if (!container)
+ continue;
+
+ bool useCache = false;
+ map<const ObservableMetadataProvider*,decoded_t>::iterator cacheEntry;
+
+ // Check for cached result.
+ if (observable) {
+ m_attrLock->rdlock();
+ cacheEntry = m_decodedMap.find(observable);
+ if (cacheEntry == m_decodedMap.end()) {
+ // We need to elevate the lock and retry.
+ m_attrLock->unlock();
+ m_attrLock->wrlock();
+ cacheEntry = m_decodedMap.find(observable);
+ if (cacheEntry==m_decodedMap.end()) {
+
+ // It's still brand new, so hook it for cache activation.
+ observable->addObserver(this);
+
+ // Prime the map reference with an empty decoded map.
+ cacheEntry = m_decodedMap.insert(make_pair(observable,decoded_t())).first;
+
+ // Downgrade the lock.
+ // We don't have to recheck because we never erase the master map entry entirely, even on changes.
+ m_attrLock->unlock();
+ m_attrLock->rdlock();
+ }
+ }
+ useCache = true;
+ }
+
+ if (useCache) {
+ // We're holding a read lock, so check the cache.
+ decoded_t::iterator d = cacheEntry->second.find(container);
+ if (d != cacheEntry->second.end()) {
+ SharedLock locker(m_attrLock, false); // pop the lock when we're done
+ for (vector<DDF>::iterator obj = d->second.begin(); obj != d->second.end(); ++obj) {
+ auto_ptr<Attribute> wrapper(Attribute::unmarshall(*obj));
+ m_log.debug("recovered cached metadata attribute (%s)", wrapper->getId());
+ attributes.push_back(wrapper.release());
+ }
+ break;
+ }
+ }
+
+ // Use a holding area to support caching.
+ vector<Attribute*> holding;
+
+ const vector<saml2::Attribute*>& attrs = container->getAttributes();
+ for (vector<saml2::Attribute*>::const_iterator attr = attrs.begin(); attr != attrs.end(); ++attr) {
+ try {
+ extractAttributes(application, NULL, relyingParty, *(*attr), holding);
+ }
+ catch (...) {
+ if (useCache)
+ m_attrLock->unlock();
+ for_each(holding.begin(), holding.end(), xmltooling::cleanup<Attribute>());
+ throw;
+ }
+ }
+
+ if (entityID && m_entityAssertions) {
+ const vector<saml2::Assertion*>& asserts = container->getAssertions();
+ for (vector<saml2::Assertion*>::const_iterator assert = asserts.begin(); assert != asserts.end(); ++assert) {
+ if (!(*assert)->getSignature()) {
+ if (m_log.isDebugEnabled()) {
+ auto_ptr_char eid(entityID);
+ m_log.debug("skipping unsigned assertion in metadata extension for entity (%s)", eid.get());
+ }
+ continue;
+ }
+ else if ((*assert)->getAttributeStatements().empty()) {
+ if (m_log.isDebugEnabled()) {
+ auto_ptr_char eid(entityID);
+ m_log.debug("skipping assertion with no AttributeStatement in metadata extension for entity (%s)", eid.get());
+ }
+ continue;
+ }
+ else {
+ // Check subject.
+ const NameID* subject = (*assert)->getSubject() ? (*assert)->getSubject()->getNameID() : NULL;
+ if (!subject ||
+ !XMLString::equals(subject->getFormat(), NameID::ENTITY) ||
+ !XMLString::equals(subject->getName(), entityID)) {
+ if (m_log.isDebugEnabled()) {
+ auto_ptr_char eid(entityID);
+ m_log.debug("skipping assertion with improper Subject in metadata extension for entity (%s)", eid.get());
+ }
+ continue;
+ }
+ }
+
+ // Use a private holding area for filtering purposes.
+ vector<Attribute*> holding2;
+
+ try {
+ // Set up and evaluate a policy for an AA asserting attributes to us.
+ shibsp::SecurityPolicy policy(application, &AttributeAuthorityDescriptor::ELEMENT_QNAME, false, m_policyId.get());
+ Locker locker(m_metadata);
+ if (m_metadata)
+ policy.setMetadataProvider(m_metadata);
+ if (m_trust)
+ policy.setTrustEngine(m_trust);
+ // Populate recipient as audience.
+ const XMLCh* issuer = (*assert)->getIssuer() ? (*assert)->getIssuer()->getName() : NULL;
+ policy.getAudiences().push_back(application.getRelyingParty(issuer)->getXMLString("entityID").second);
+
+ // Extract assertion information for policy.
+ policy.setMessageID((*assert)->getID());
+ policy.setIssueInstant((*assert)->getIssueInstantEpoch());
+ policy.setIssuer((*assert)->getIssuer());
+
+ // Look up metadata for issuer.
+ if (policy.getIssuer() && policy.getMetadataProvider()) {
+ if (policy.getIssuer()->getFormat() && !XMLString::equals(policy.getIssuer()->getFormat(), saml2::NameIDType::ENTITY)) {
+ m_log.debug("non-system entity issuer, skipping metadata lookup");
+ }
+ else {
+ m_log.debug("searching metadata for entity assertion issuer...");
+ pair<const EntityDescriptor*,const RoleDescriptor*> lookup;
+ MetadataProvider::Criteria& mc = policy.getMetadataProviderCriteria();
+ mc.entityID_unicode = policy.getIssuer()->getName();
+ mc.role = &AttributeAuthorityDescriptor::ELEMENT_QNAME;
+ mc.protocol = samlconstants::SAML20P_NS;
+ lookup = policy.getMetadataProvider()->getEntityDescriptor(mc);
+ if (!lookup.first) {
+ auto_ptr_char iname(policy.getIssuer()->getName());
+ m_log.debug("no metadata found, can't establish identity of issuer (%s)", iname.get());
+ }
+ else if (!lookup.second) {
+ m_log.debug("unable to find compatible AA role in metadata");
+ }
+ else {
+ policy.setIssuerMetadata(lookup.second);
+ }
+ }
+ }
+
+ // Authenticate the assertion. We have to clone and marshall it to establish the signature for verification.
+ auto_ptr<saml2::Assertion> tokencopy((*assert)->cloneAssertion());
+ tokencopy->marshall();
+ policy.evaluate(*tokencopy);
+ if (!policy.isAuthenticated()) {
+ if (m_log.isDebugEnabled()) {
+ auto_ptr_char tempid(tokencopy->getID());
+ auto_ptr_char eid(entityID);
+ m_log.debug(
+ "failed to authenticate assertion (%s) in metadata extension for entity (%s)", tempid.get(), eid.get()
+ );
+ }
+ continue;
+ }
+
+ // Override the asserting/relying party names based on this new issuer.
+ const EntityDescriptor* inlineEntity =
+ policy.getIssuerMetadata() ? dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent()) : NULL;
+ auto_ptr_char inlineAssertingParty(inlineEntity ? inlineEntity->getEntityID() : NULL);
+ relyingParty = application.getRelyingParty(inlineEntity)->getString("entityID").second;
+ const vector<saml2::Attribute*>& attrs2 =
+ const_cast<const saml2::AttributeStatement*>(tokencopy->getAttributeStatements().front())->getAttributes();
+ for (vector<saml2::Attribute*>::const_iterator a = attrs2.begin(); a!=attrs2.end(); ++a)
+ extractAttributes(application, inlineAssertingParty.get(), relyingParty, *(*a), holding2);
+
+ // Now we locally filter the attributes so that the actual issuer can be properly set.
+ // If we relied on outside filtering, the attributes couldn't be distinguished from the
+ // ones that come from the user's IdP.
+ if (m_filter && !holding2.empty()) {
+ BasicFilteringContext fc(application, holding2, policy.getIssuerMetadata());
+ Locker filtlocker(m_filter);
+ try {
+ m_filter->filterAttributes(fc, holding2);
+ }
+ catch (exception& ex) {
+ m_log.error("caught exception filtering attributes: %s", ex.what());
+ m_log.error("dumping extracted attributes due to filtering exception");
+ for_each(holding2.begin(), holding2.end(), xmltooling::cleanup<Attribute>());
+ holding2.clear();
+ }
+ }
+
+ if (!holding2.empty()) {
+ // Copy them over to the main holding tank.
+ holding.insert(holding.end(), holding2.begin(), holding2.end());
+ }
+ }
+ catch (exception& ex) {
+ // Known exceptions are handled gracefully by skipping the assertion.
+ if (m_log.isDebugEnabled()) {
+ auto_ptr_char tempid((*assert)->getID());
+ auto_ptr_char eid(entityID);
+ m_log.debug(
+ "exception authenticating assertion (%s) in metadata extension for entity (%s): %s",
+ tempid.get(),
+ eid.get(),
+ ex.what()
+ );
+ }
+ for_each(holding2.begin(), holding2.end(), xmltooling::cleanup<Attribute>());
+ continue;
+ }
+ catch (...) {
+ // Unknown exceptions are fatal.
+ if (useCache)
+ m_attrLock->unlock();
+ for_each(holding.begin(), holding.end(), xmltooling::cleanup<Attribute>());
+ for_each(holding2.begin(), holding2.end(), xmltooling::cleanup<Attribute>());
+ throw;
+ }
+ }
+ }
+
+ if (!holding.empty()) {
+ if (useCache) {
+ m_attrLock->unlock();
+ m_attrLock->wrlock();
+ SharedLock locker(m_attrLock, false); // pop the lock when we're done
+ if (cacheEntry->second.count(container) == 0) {
+ for (vector<Attribute*>::const_iterator held = holding.begin(); held != holding.end(); ++held)
+ cacheEntry->second[container].push_back((*held)->marshall());
+ }
+ }
+ attributes.insert(attributes.end(), holding.begin(), holding.end());
+ }
+ else if (useCache) {
+ m_attrLock->unlock();
+ }
+
+ break; // only process a single extension element
}
}
if (!m_impl)
return;
+ const EntityDescriptor* entity = issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent()) : NULL;
+ const char* relyingParty = application.getRelyingParty(entity)->getString("entityID").second;
+
// Check for assertions.
if (XMLString::equals(xmlObject.getElementQName().getLocalPart(), saml1::Assertion::LOCAL_NAME)) {
const saml2::Assertion* token2 = dynamic_cast<const saml2::Assertion*>(&xmlObject);
if (token2) {
- auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
+ auto_ptr_char assertingParty(entity ? entity->getEntityID() : NULL);
const vector<saml2::AttributeStatement*>& statements = token2->getAttributeStatements();
for (vector<saml2::AttributeStatement*>::const_iterator s = statements.begin(); s!=statements.end(); ++s) {
const vector<saml2::Attribute*>& attrs = const_cast<const saml2::AttributeStatement*>(*s)->getAttributes();
for (vector<saml2::Attribute*>::const_iterator a = attrs.begin(); a!=attrs.end(); ++a)
- m_impl->extractAttributes(application, assertingParty.get(), *(*a), attributes);
+ m_impl->extractAttributes(application, assertingParty.get(), relyingParty, *(*a), attributes);
const vector<saml2::EncryptedAttribute*>& encattrs = const_cast<const saml2::AttributeStatement*>(*s)->getEncryptedAttributes();
for (vector<saml2::EncryptedAttribute*>::const_iterator ea = encattrs.begin(); ea!=encattrs.end(); ++ea)
const saml1::Assertion* token1 = dynamic_cast<const saml1::Assertion*>(&xmlObject);
if (token1) {
- auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
+ auto_ptr_char assertingParty(entity ? entity->getEntityID() : NULL);
const vector<saml1::AttributeStatement*>& statements = token1->getAttributeStatements();
for (vector<saml1::AttributeStatement*>::const_iterator s = statements.begin(); s!=statements.end(); ++s) {
const vector<saml1::Attribute*>& attrs = const_cast<const saml1::AttributeStatement*>(*s)->getAttributes();
for (vector<saml1::Attribute*>::const_iterator a = attrs.begin(); a!=attrs.end(); ++a)
- m_impl->extractAttributes(application, assertingParty.get(), *(*a), attributes);
+ m_impl->extractAttributes(application, assertingParty.get(), relyingParty, *(*a), attributes);
}
return;
}
// Check for metadata.
if (XMLString::equals(xmlObject.getElementQName().getNamespaceURI(), samlconstants::SAML20MD_NS)) {
- const EntityDescriptor* entity = dynamic_cast<const EntityDescriptor*>(&xmlObject);
- if (!entity)
+ const RoleDescriptor* roleToExtract = dynamic_cast<const RoleDescriptor*>(&xmlObject);
+ const EntityDescriptor* entityToExtract = roleToExtract ? dynamic_cast<const EntityDescriptor*>(roleToExtract->getParent()) : NULL;
+ if (!entityToExtract)
throw AttributeExtractionException("Unable to extract attributes, unknown metadata object type.");
- auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
- const Extensions* ext = entity->getExtensions();
- if (ext)
- m_impl->extractAttributes(application, assertingParty.get(), *ext, attributes);
- const EntitiesDescriptor* group = dynamic_cast<const EntitiesDescriptor*>(entity->getParent());
+ const Extensions* ext = entityToExtract->getExtensions();
+ if (ext) {
+ m_impl->extractAttributes(
+ application,
+ dynamic_cast<const ObservableMetadataProvider*>(application.getMetadataProvider(false)),
+ entityToExtract->getEntityID(),
+ relyingParty,
+ *ext,
+ attributes
+ );
+ }
+ const EntitiesDescriptor* group = dynamic_cast<const EntitiesDescriptor*>(entityToExtract->getParent());
while (group) {
ext = group->getExtensions();
- if (ext)
- m_impl->extractAttributes(application, assertingParty.get(), *ext, attributes);
+ if (ext) {
+ m_impl->extractAttributes(
+ application,
+ dynamic_cast<const ObservableMetadataProvider*>(application.getMetadataProvider(false)),
+ NULL, // not an entity, so inline assertions won't be processed
+ relyingParty,
+ *ext,
+ attributes
+ );
+ }
group = dynamic_cast<const EntitiesDescriptor*>(group->getParent());
}
return;
// Check for attributes.
if (XMLString::equals(xmlObject.getElementQName().getLocalPart(), saml1::Attribute::LOCAL_NAME)) {
- auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
-
+ auto_ptr_char assertingParty(entity ? entity->getEntityID() : NULL);
const saml2::Attribute* attr2 = dynamic_cast<const saml2::Attribute*>(&xmlObject);
if (attr2)
- return m_impl->extractAttributes(application, assertingParty.get(), *attr2, attributes);
+ return m_impl->extractAttributes(application, assertingParty.get(), relyingParty, *attr2, attributes);
const saml1::Attribute* attr1 = dynamic_cast<const saml1::Attribute*>(&xmlObject);
if (attr1)
- return m_impl->extractAttributes(application, assertingParty.get(), *attr1, attributes);
+ return m_impl->extractAttributes(application, assertingParty.get(), relyingParty, *attr1, attributes);
throw AttributeExtractionException("Unable to extract attributes, unknown object type.");
}
// Check for NameIDs.
const NameID* name2 = dynamic_cast<const NameID*>(&xmlObject);
if (name2) {
- auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
- return m_impl->extractAttributes(application, assertingParty.get(), *name2, attributes);
+ auto_ptr_char assertingParty(entity ? entity->getEntityID() : NULL);
+ return m_impl->extractAttributes(application, assertingParty.get(), relyingParty, *name2, attributes);
}
const NameIdentifier* name1 = dynamic_cast<const NameIdentifier*>(&xmlObject);
if (name1) {
- auto_ptr_char assertingParty(issuer ? dynamic_cast<const EntityDescriptor*>(issuer->getParent())->getEntityID() : NULL);
- return m_impl->extractAttributes(application, assertingParty.get(), *name1, attributes);
+ auto_ptr_char assertingParty(entity ? entity->getEntityID() : NULL);
+ return m_impl->extractAttributes(application, assertingParty.get(), relyingParty, *name1, attributes);
}
throw AttributeExtractionException("Unable to extract attributes, unknown object type.");
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* @file shibsp/base.h
- *
+ *
* Base header file definitions
* Must be included prior to including any other header
*/
#ifdef WIN32
-/**
- * Default catalog path on Windows.
- */
+/** Default catalog path on Windows. */
# define SHIBSP_SCHEMAS "c:/opt/shibboleth-sp/share/xml/xmltooling/catalog.xml;c:/opt/shibboleth-sp/share/xml/opensaml/saml20-catalog.xml;c:/opt/shibboleth-sp/share/xml/opensaml/saml11-catalog.xml;c:/opt/shibboleth-sp/share/xml/shibboleth/catalog.xml"
-/**
- * Default name of configuration file on Windows.
- */
+/** Default name of configuration file on Windows. */
# define SHIBSP_CONFIG "shibboleth2.xml"
/**
*/
#define SHIBSP_LOGGING "console.logger"
-/**
- * Default prefix for installation (used to resolve relative paths).
- */
+/** Default prefix for installation (used to resolve relative paths). */
#define SHIBSP_PREFIX "c:/opt/shibboleth-sp"
+/** Library directory for installation (used to resolve relative paths). */
+#define SHIBSP_LIBDIR "lib"
+
+/** Log directory for installation (used to resolve relative paths). */
+#define SHIBSP_LOGDIR "var/log"
+
+/** Configuration directory for installation (used to resolve relative paths). */
+#define SHIBSP_CFGDIR "etc"
+
+/** Runtime state directory for installation (used to resolve relative paths). */
+#define SHIBSP_RUNDIR "var/run"
+
+/** XML directory for installation (used to resolve relative paths). */
+#define SHIBSP_XMLDIR "share/xml"
+
#else
# include <shibsp/paths.h>
#endif
-/**
- * Logging category for Service Provider functions.
- */
+/** Logging category for Service Provider functions. */
#define SHIBSP_LOGCAT "Shibboleth"
-/**
- * Logging category for Service Provider auditing.
- */
+/** Logging category for Service Provider auditing. */
#define SHIBSP_TX_LOGCAT "Shibboleth-TRANSACTION"
#endif /* __shibsp_base_h__ */
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/** Application supplied to client. */
const Application& m_app;
- /** Properties associated with the Application's security policy. */
- const PropertySet* m_settings;
-
/** RelyingParty properties, set after transport prep. */
const PropertySet* m_relyingParty;
throw MetadataException("No compatible endpoint found in issuer's metadata.");
else if (!response)
throw BindingException("Unable to resolve artifact(s) into a SAML response.");
- const QName* code = (response->getStatus() && response->getStatus()->getStatusCode()) ? response->getStatus()->getStatusCode()->getValue() : NULL;
+ const xmltooling::QName* code = (response->getStatus() && response->getStatus()->getStatusCode()) ? response->getStatus()->getStatusCode()->getValue() : NULL;
if (!code || *code != saml1p::StatusCode::SUCCESS) {
delete response;
throw BindingException("Identity provider returned a SAML error in response to artifact(s).");
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
using namespace std;
SOAPClient::SOAPClient(SecurityPolicy& policy)
- : opensaml::SOAPClient(policy), m_app(policy.getApplication()), m_settings(NULL), m_relyingParty(NULL), m_credResolver(NULL)
+ : opensaml::SOAPClient(policy), m_app(policy.getApplication()), m_relyingParty(NULL), m_credResolver(NULL)
{
- m_settings = m_app.getServiceProvider().getPolicySettings(m_app.getString("policyId").second);
- pair<bool,bool> validate = m_settings->getBool("validate");
- policy.setValidating(validate.first && validate.second);
- setValidating(validate.first && validate.second);
}
void SOAPClient::send(const soap11::Envelope& env, const char* from, MetadataCredentialCriteria& to, const char* endpoint)
if ((!flag.first || flag.second) && !transport.isConfidential())
throw opensaml::BindingException("Transport confidentiality required, but not available.");
- flag = m_settings->getBool("validate");
- setValidating(flag.first && flag.second);
+ setValidating(getPolicy().getValidating());
flag = m_relyingParty->getBool("requireTransportAuth");
forceTransportAuthentication(!flag.first || flag.second);
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#define __shibsp_abshandler_h__
#include <shibsp/handler/Handler.h>
+#include <shibsp/remoting/ddf.h>
#include <shibsp/util/DOMPropertySet.h>
#ifndef SHIBSP_LITE
bool clear=true
) const;
+ /**
+ * Implements a mechanism to preserve form post data.
+ *
+ * @param application the associated Application
+ * @param request incoming HTTP request
+ * @param response outgoing HTTP response
+ * @param relayState relay state information attached to current sequence, if any
+ */
+ virtual void preservePostData(
+ const Application& application,
+ const xmltooling::HTTPRequest& request,
+ xmltooling::HTTPResponse& response,
+ const char* relayState
+ ) const;
+
+ /**
+ * Implements storage service and cookie mechanism to recover PostData.
+ *
+ * <p>If a supported mechanism can be identified, the return value will be
+ * the recovered state information.
+ *
+ * @param application the associated Application
+ * @param request incoming HTTP request
+ * @param response outgoing HTTP response
+ * @param relayState relay state information attached to current sequence, if any
+ * @return recovered form post data associated with request as a DDF list of string members
+ */
+ virtual DDF recoverPostData(
+ const Application& application,
+ const xmltooling::HTTPRequest& request,
+ xmltooling::HTTPResponse& response,
+ const char* relayState
+ ) const;
+
+ /**
+ * Post a redirect response with post data.
+ *
+ * @param application the associated Application
+ * @param response outgoing HTTP response
+ * @param request incoming HTTP request
+ * @param url action url for the form
+ * @param postData list of parameters to load into the form, as DDF string members
+ */
+ virtual long sendPostResponse(
+ const Application& application,
+ xmltooling::HTTPResponse& httpResponse,
+ const char* url,
+ DDF& postData
+ ) const;
+
/** Logging object. */
xmltooling::logging::Category& m_log;
public:
virtual ~AbstractHandler() {}
+
+ private:
+ std::pair<std::string,const char*> getPostCookieNameProps(const Application& app, const char* relayState) const;
+ DDF getPostData(const Application& application, const xmltooling::HTTPRequest& request) const;
};
#if defined (_MSC_VER)
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
void generateMetadata(opensaml::saml2md::SPSSODescriptor& role, const char* handlerURL) const;
/**
+ * Returns a SecurityPolicy instance to use for an incoming request.
+ *
+ * <p>Allows handlers to customize the type of policy object their policy rules might require.
+ * <p>The caller <strong>MUST</strong> lock the application's MetadataProvider for the life
+ * of the returned object.
+ *
+ * @param application reference to application receiving message
+ * @param role identifies the role (generally IdP or SP) of the policy peer
+ * @param validate true iff XML parsing should be done with validation
+ * @param policyId identifies policy rules to auto-attach, defaults to the application's set
+ * @return a new policy instance, which the caller is responsible for freeing
+ */
+ virtual opensaml::SecurityPolicy* createSecurityPolicy(
+ const Application& application, const xmltooling::QName* role, bool validate, const char* policyId
+ ) const;
+
+ /**
* Implement protocol-specific handling of the incoming decoded message.
*
* <p>The result of implementing the protocol should be an exception or
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "handler/AbstractHandler.h"
#include "handler/LogoutHandler.h"
#include "remoting/ListenerService.h"
+#include "util/CGIParser.h"
#include "util/SPConstants.h"
+#include "util/TemplateParameters.h"
+
+#include <vector>
+#include <fstream>
+#include <xmltooling/XMLToolingConfig.h>
+#include <xmltooling/util/PathResolver.h>
+#include <xmltooling/util/URLEncoder.h>
+
#ifndef SHIBSP_LITE
# include <saml/saml1/core/Protocols.h>
# include <saml/saml2/metadata/Metadata.h>
# include <saml/saml2/metadata/MetadataCredentialCriteria.h>
# include <saml/util/SAMLConstants.h>
+# include <saml/SAMLConfig.h>
+# include <saml/binding/SAMLArtifact.h>
# include <xmltooling/util/StorageService.h>
using namespace opensaml::saml2md;
#else
const saml1p::Status* status = r1->getStatus();
if (status) {
const saml1p::StatusCode* sc = status->getStatusCode();
- const QName* code = sc ? sc->getValue() : NULL;
+ const xmltooling::QName* code = sc ? sc->getValue() : NULL;
if (code && *code != saml1p::StatusCode::SUCCESS) {
FatalProfileException ex("SAML response contained an error.");
ex.addProperty("statusCode", code->toString().c_str());
else if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
DDF out,in = DDF("set::RelayState").structure();
in.addmember("id").string(mech.second);
- in.addmember("value").string(relayState.c_str());
+ in.addmember("value").unsafe_string(relayState.c_str());
DDFJanitor jin(in),jout(out);
out = application.getServiceProvider().getListenerService()->send(in);
if (!out.isstring())
relayState.erase();
}
else {
- Category::getInstance(SHIBSP_LOGCAT".Handler").error(
- "Storage-backed RelayState with invalid StorageService ID (%s)", ssid.c_str()
- );
+ m_log.error("Storage-backed RelayState with invalid StorageService ID (%s)", ssid.c_str());
relayState.erase();
}
#endif
relayState.erase();
}
- // Check for "default" value.
- if (relayState.empty() || relayState == "default") {
+ // Check for "default" value (or the old "cookie" value that might come from stale bookmarks).
+ if (relayState.empty() || relayState == "default" || relayState == "cookie") {
pair<bool,const char*> homeURL=application.getString("homeURL");
- relayState=homeURL.first ? homeURL.second : "/";
+ if (homeURL.first)
+ relayState=homeURL.second;
+ else {
+ // Compute a URL to the root of the site.
+ int port = request.getPort();
+ const char* scheme = request.getScheme();
+ relayState = string(scheme) + "://" + request.getHostname();
+ if ((!strcmp(scheme,"http") && port!=80) || (!strcmp(scheme,"https") && port!=443)) {
+ ostringstream portstr;
+ portstr << port;
+ relayState += ":" + portstr.str();
+ }
+ relayState += '/';
+ }
+ }
+}
+
+void AbstractHandler::preservePostData(
+ const Application& application, const HTTPRequest& request, HTTPResponse& response, const char* relayState
+ ) const
+{
+#ifdef HAVE_STRCASECMP
+ if (strcasecmp(request.getMethod(), "POST")) return;
+#else
+ if (stricmp(request.getMethod(), "POST")) return;
+#endif
+
+ // No specs mean no save.
+ const PropertySet* props=application.getPropertySet("Sessions");
+ pair<bool,const char*> mech = props->getString("postData");
+ if (!mech.first) {
+ m_log.info("postData property not supplied, form data will not be preserved across SSO");
+ return;
+ }
+
+ DDF postData = getPostData(application, request);
+ if (postData.isnull())
return;
+
+ if (strstr(mech.second,"ss:") == mech.second) {
+ mech.second+=3;
+ if (!*mech.second) {
+ postData.destroy();
+ throw ConfigurationException("Unsupported postData mechanism ($1).", params(1, mech.second - 3));
+ }
+
+ string postkey;
+ if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
+ DDFJanitor postjan(postData);
+#ifndef SHIBSP_LITE
+ StorageService* storage = application.getServiceProvider().getStorageService(mech.second);
+ if (storage) {
+ // Use a random key
+ string rsKey;
+ SAMLConfig::getConfig().generateRandomBytes(rsKey,20);
+ rsKey = SAMLArtifact::toHex(rsKey);
+ ostringstream out;
+ out << postData;
+ if (!storage->createString("PostData", rsKey.c_str(), out.str().c_str(), time(NULL) + 600))
+ throw IOException("Attempted to insert duplicate storage key.");
+ postkey = string(mech.second-3) + ':' + rsKey;
+ }
+ else {
+ m_log.error("storage-backed PostData mechanism with invalid StorageService ID (%s)", mech.second);
+ }
+#endif
+ }
+ else if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
+ DDF out,in = DDF("set::PostData").structure();
+ DDFJanitor jin(in),jout(out);
+ in.addmember("id").string(mech.second);
+ in.add(postData);
+ out = application.getServiceProvider().getListenerService()->send(in);
+ if (!out.isstring())
+ throw IOException("StorageService-backed PostData mechanism did not return a state key.");
+ postkey = string(mech.second-3) + ':' + out.string();
+ }
+
+ // Set a cookie with key info.
+ pair<string,const char*> shib_cookie = getPostCookieNameProps(application, relayState);
+ postkey += shib_cookie.second;
+ response.setCookie(shib_cookie.first.c_str(), postkey.c_str());
+ }
+ else {
+ postData.destroy();
+ throw ConfigurationException("Unsupported postData mechanism ($1).", params(1,mech.second));
+ }
+}
+
+DDF AbstractHandler::recoverPostData(
+ const Application& application, const HTTPRequest& request, HTTPResponse& response, const char* relayState
+ ) const
+{
+ // First we need the post recovery cookie.
+ pair<string,const char*> shib_cookie = getPostCookieNameProps(application, relayState);
+ const char* cookie = request.getCookie(shib_cookie.first.c_str());
+ if (!cookie || !*cookie)
+ return DDF();
+
+ // Clear the cookie.
+ string exp(shib_cookie.second);
+ exp += "; expires=Mon, 01 Jan 2001 00:00:00 GMT";
+ response.setCookie(shib_cookie.first.c_str(), exp.c_str());
+
+ // Look for StorageService-backed state of the form "ss:SSID:key".
+ const char* state = cookie;
+ if (strstr(state, "ss:") == state) {
+ state += 3;
+ const char* key = strchr(state, ':');
+ if (key) {
+ string ssid = string(cookie).substr(3, key - state);
+ key++;
+ if (!ssid.empty() && *key) {
+ SPConfig& conf = SPConfig::getConfig();
+ if (conf.isEnabled(SPConfig::OutOfProcess)) {
+#ifndef SHIBSP_LITE
+ StorageService* storage = conf.getServiceProvider()->getStorageService(ssid.c_str());
+ if (storage) {
+ if (storage->readString("PostData", key, &ssid) > 0) {
+ storage->deleteString("PostData", key);
+ istringstream inret(ssid);
+ DDF ret;
+ inret >> ret;
+ return ret;
+ }
+ else {
+ m_log.error("failed to recover form post data using key (%s)", key);
+ }
+ }
+ else {
+ m_log.error("storage-backed PostData with invalid StorageService ID (%s)", ssid.c_str());
+ }
+#endif
+ }
+ else if (conf.isEnabled(SPConfig::InProcess)) {
+ DDF in = DDF("get::PostData").structure();
+ DDFJanitor jin(in);
+ in.addmember("id").string(ssid.c_str());
+ in.addmember("key").string(key);
+ DDF out = application.getServiceProvider().getListenerService()->send(in);
+ if (out.islist())
+ return out;
+ out.destroy();
+ m_log.error("storageService-backed PostData mechanism did not return preserved data.");
+ }
+ }
+ }
+ }
+ return DDF();
+}
+
+long AbstractHandler::sendPostResponse(
+ const Application& application, HTTPResponse& httpResponse, const char* url, DDF& postData
+ ) const
+{
+ const PropertySet* props=application.getPropertySet("Sessions");
+ pair<bool,const char*> postTemplate = props->getString("postTemplate");
+ if (!postTemplate.first)
+ throw ConfigurationException("Missing postTemplate property, unable to recreate form post.");
+
+ string fname(postTemplate.second);
+ ifstream infile(XMLToolingConfig::getConfig().getPathResolver()->resolve(fname, PathResolver::XMLTOOLING_CFG_FILE).c_str());
+ if (!infile)
+ throw ConfigurationException("Unable to access HTML template ($1).", params(1, fname.c_str()));
+ TemplateParameters respParam;
+ respParam.m_map["action"] = url;
+
+ // Load the parameters into objects for the template.
+ multimap<string,string>& collection = respParam.m_collectionMap["PostedData"];
+ DDF param = postData.first();
+ while (param.isstring()) {
+ collection.insert(pair<const string,string>(param.name(), (param.string() ? param.string() : "")));
+ param = postData.next();
}
- if (relayState == "default")
- relayState.empty();
+ stringstream str;
+ XMLToolingConfig::getConfig().getTemplateEngine()->run(infile, str, respParam);
+
+ pair<bool,bool> postExpire = props->getBool("postExpire");
+
+ httpResponse.setContentType("text/html");
+ if (!postExpire.first || postExpire.second) {
+ httpResponse.setResponseHeader("Expires", "01-Jan-1997 12:00:00 GMT");
+ httpResponse.setResponseHeader("Cache-Control", "no-cache, no-store, must-revalidate, private");
+ httpResponse.setResponseHeader("Pragma", "no-cache");
+ }
+ return httpResponse.sendResponse(str);
+}
+
+pair<string,const char*> AbstractHandler::getPostCookieNameProps(const Application& app, const char* relayState) const
+{
+ // Decorates the name of the cookie with the relay state key, if any.
+ // Doing so gives a better assurance that the recovered data really
+ // belongs to the relayed request.
+ pair<string,const char*> shib_cookie=app.getCookieNameProps("_shibpost_");
+ if (strstr(relayState, "cookie:") == relayState) {
+ shib_cookie.first = string("_shibpost_") + (relayState + 7);
+ }
+ else if (strstr(relayState, "ss:") == relayState) {
+ const char* pch = strchr(relayState + 3, ':');
+ if (pch)
+ shib_cookie.first = string("_shibpost_") + (pch + 1);
+ }
+ return shib_cookie;
+}
+
+DDF AbstractHandler::getPostData(const Application& application, const HTTPRequest& request) const
+{
+ string contentType = request.getContentType();
+ if (contentType.compare("application/x-www-form-urlencoded") == 0) {
+ const PropertySet* props=application.getPropertySet("Sessions");
+ pair<bool,unsigned int> plimit = props->getUnsignedInt("postLimit");
+ if (!plimit.first)
+ plimit.second = 1024 * 1024;
+ if (plimit.second == 0 || request.getContentLength() <= plimit.second) {
+ CGIParser cgi(request);
+ pair<CGIParser::walker,CGIParser::walker> params = cgi.getParameters(NULL);
+ if (params.first == params.second)
+ return DDF();
+ DDF child;
+ DDF ret = DDF("parameters").list();
+ for (; params.first != params.second; ++params.first) {
+ if (!params.first->first.empty()) {
+ child = DDF(params.first->first.c_str()).unsafe_string(params.first->second);
+ ret.add(child);
+ }
+ }
+ return ret;
+ }
+ else {
+ m_log.warn("POST limit exceeded, ignoring %d bytes of posted data", request.getContentLength());
+ }
+ }
+ else {
+ m_log.info("ignoring POST data with non-standard encoding (%s)", contentType.c_str());
+ }
+ return DDF();
}
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Locker metadataLocker(application.getMetadataProvider());
// Create the policy.
- shibsp::SecurityPolicy policy(application, &m_role, validate.first && validate.second);
+ auto_ptr<opensaml::SecurityPolicy> policy(
+ createSecurityPolicy(application, &m_role, validate.first && validate.second, policyId.second)
+ );
string relayState;
-
try {
// Decode the message and process it in a protocol-specific way.
- auto_ptr<XMLObject> msg(m_decoder->decode(relayState, httpRequest, policy));
+ auto_ptr<XMLObject> msg(m_decoder->decode(relayState, httpRequest, *(policy.get())));
if (!msg.get())
throw BindingException("Failed to decode an SSO protocol response.");
+ DDF postData = recoverPostData(application, httpRequest, httpResponse, relayState.c_str());
+ DDFJanitor postjan(postData);
recoverRelayState(application, httpRequest, httpResponse, relayState);
- implementProtocol(application, httpRequest, httpResponse, policy, settings, *msg.get());
+ implementProtocol(application, httpRequest, httpResponse, *(policy.get()), settings, *msg.get());
- auto_ptr_char issuer(policy.getIssuer() ? policy.getIssuer()->getName() : NULL);
+ auto_ptr_char issuer(policy->getIssuer() ? policy->getIssuer()->getName() : NULL);
// History cookie.
if (issuer.get() && *issuer.get())
maintainHistory(application, httpRequest, httpResponse, issuer.get());
// Now redirect to the state value. By now, it should be set to *something* usable.
- return make_pair(true, httpResponse.sendRedirect(relayState.c_str()));
+ // First check for POST data.
+ if (!postData.islist()) {
+ m_log.debug("ACS returning via redirect to: %s", relayState.c_str());
+ return make_pair(true, httpResponse.sendRedirect(relayState.c_str()));
+ }
+ else {
+ m_log.debug("ACS returning via POST to: %s", relayState.c_str());
+ return make_pair(true, sendPostResponse(application, httpResponse, relayState.c_str(), postData));
+ }
}
catch (XMLToolingException& ex) {
+ // Check for isPassive error condition.
+ const char* sc2 = ex.getProperty("statusCode2");
+ if (sc2 && !strcmp(sc2, "urn:oasis:names:tc:SAML:2.0:status:NoPassive")) {
+ validate = getBool("ignoreNoPassive", m_configNS.get()); // namespace-qualified if inside handler element
+ if (validate.first && validate.second && !relayState.empty()) {
+ m_log.debug("ignoring SAML status of NoPassive and redirecting to resource...");
+ return make_pair(true, httpResponse.sendRedirect(relayState.c_str()));
+ }
+ }
if (!relayState.empty())
ex.addProperty("RelayState", relayState.c_str());
throw;
#ifndef SHIBSP_LITE
-void AssertionConsumerService::generateMetadata(SPSSODescriptor& role, const char* handlerURL) const {
+void AssertionConsumerService::generateMetadata(SPSSODescriptor& role, const char* handlerURL) const
+{
const char* loc = getString("Location").second;
string hurl(handlerURL);
if (*loc != '/')
role.getAssertionConsumerServices().push_back(ep);
}
+opensaml::SecurityPolicy* AssertionConsumerService::createSecurityPolicy(
+ const Application& application, const xmltooling::QName* role, bool validate, const char* policyId
+ ) const
+{
+ return new SecurityPolicy(application, role, validate, policyId);
+}
+
class SHIBSP_DLLLOCAL DummyContext : public ResolutionContext
{
public:
const vector<const Assertion*>* tokens
) const
{
- const saml2md::EntityDescriptor* entity = issuer ? dynamic_cast<const saml2md::EntityDescriptor*>(issuer->getParent()) : NULL;
-
// First we do the extraction of any pushed information, including from metadata.
vector<Attribute*> resolvedAttributes;
AttributeExtractor* extractor = application.getAttributeExtractor();
if (extractor) {
Locker extlocker(extractor);
- if (entity) {
+ if (issuer) {
pair<bool,const char*> mprefix = application.getString("metadataAttributePrefix");
if (mprefix.first) {
m_log.debug("extracting metadata-derived attributes...");
try {
- extractor->extractAttributes(application, issuer, *entity, resolvedAttributes);
+ // We pass NULL for "issuer" because the IdP isn't the one asserting metadata-based attributes.
+ extractor->extractAttributes(application, NULL, *issuer, resolvedAttributes);
for (vector<Attribute*>::iterator a = resolvedAttributes.begin(); a != resolvedAttributes.end(); ++a) {
vector<string>& ids = (*a)->getAliases();
for (vector<string>::iterator id = ids.begin(); id != ids.end(); ++id)
auto_ptr<ResolutionContext> ctx(
resolver->createResolutionContext(
application,
- entity,
+ issuer ? dynamic_cast<const saml2md::EntityDescriptor*>(issuer->getParent()) : NULL,
protocol,
nameid,
authncontext_class,
// Copy over any pushed attributes.
if (!resolvedAttributes.empty())
ctx->getResolvedAttributes().insert(ctx->getResolvedAttributes().end(), resolvedAttributes.begin(), resolvedAttributes.end());
-
- // Attach global prefix if needed.
- pair<bool,const char*> prefix = application.getString("attributePrefix");
- if (prefix.first) {
- for (vector<Attribute*>::iterator a = ctx->getResolvedAttributes().begin(); a != ctx->getResolvedAttributes().end(); ++a) {
- vector<string>& ids = (*a)->getAliases();
- for (vector<string>::iterator id = ids.begin(); id != ids.end(); ++id)
- *id = prefix.second + *id;
- }
- }
-
return ctx.release();
}
}
m_log.error("attribute resolution failed: %s", ex.what());
}
- if (!resolvedAttributes.empty()) {
- // Attach global prefix if needed.
- pair<bool,const char*> prefix = application.getString("attributePrefix");
- if (prefix.first) {
- for (vector<Attribute*>::iterator a = resolvedAttributes.begin(); a != resolvedAttributes.end(); ++a) {
- vector<string>& ids = (*a)->getAliases();
- for (vector<string>::iterator id = ids.begin(); id != ids.end(); ++id)
- *id = prefix.second + *id;
- }
- }
-
+ if (!resolvedAttributes.empty())
return new DummyContext(resolvedAttributes);
- }
return NULL;
}
}
m_log.debug("searching metadata for assertion issuer...");
pair<const EntityDescriptor*,const RoleDescriptor*> entity;
- shibsp::SecurityPolicy* sppol = dynamic_cast<shibsp::SecurityPolicy*>(&policy);
- if (sppol) {
- MetadataProviderCriteria mc(sppol->getApplication(), policy.getIssuer()->getName(), &IDPSSODescriptor::ELEMENT_QNAME, protocol);
- entity = policy.getMetadataProvider()->getEntityDescriptor(mc);
- }
- else {
- MetadataProvider::Criteria mc(policy.getIssuer()->getName(), &IDPSSODescriptor::ELEMENT_QNAME, protocol);
- entity = policy.getMetadataProvider()->getEntityDescriptor(mc);
- }
+ MetadataProvider::Criteria& mc = policy.getMetadataProviderCriteria();
+ mc.entityID_unicode = policy.getIssuer()->getName();
+ mc.role = &IDPSSODescriptor::ELEMENT_QNAME;
+ mc.protocol = protocol;
+ entity = policy.getMetadataProvider()->getEntityDescriptor(mc);
if (!entity.first) {
auto_ptr_char iname(policy.getIssuer()->getName());
m_log.warn("no metadata found, can't establish identity of issuer (%s)", iname.get());
/*
* Copyright 2001-2007 Internet2
- *
+ *
* 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
/**
* AssertionLookup.cpp
- *
+ *
* Handler for looking assertions in SessionCache
*/
class SHIBSP_DLLLOCAL Blocker : public DOMNodeFilter
{
public:
- short acceptNode(const DOMNode* node) const {
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+ short
+#else
+ FilterAction
+#endif
+ acceptNode(const DOMNode* node) const {
return FILTER_REJECT;
}
};
if (m_acl.count(request.getRemoteAddr()) == 0) {
m_log.error("request for assertion lookup blocked from invalid address (%s)", request.getRemoteAddr().c_str());
istringstream msg("Assertion Lookup Blocked");
- return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_UNAUTHORIZED));
+ return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN));
}
}
-
+
try {
if (conf.isEnabled(SPConfig::OutOfProcess)) {
// When out of process, we run natively and directly process the message.
// When not out of process, we remote all the message processing.
DDF out,in = wrap(request);
DDFJanitor jin(in), jout(out);
-
+
out=request.getServiceProvider().getListenerService()->send(in);
return unwrap(request, out);
}
m_log.error("couldn't find application (%s) for assertion lookup", aid ? aid : "(missing)");
throw ConfigurationException("Unable to locate application for assertion lookup, deleted?");
}
-
+
// Unpack the request.
auto_ptr<HTTPRequest> req(getRequest(in));
//m_log.debug("found %d client certificates", req->getClientCertificates().size());
DDF ret(NULL);
DDFJanitor jout(ret);
auto_ptr<HTTPResponse> resp(getResponse(ret));
-
+
// Since we're remoted, the result should either be a throw, a false/0 return,
// which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
class SHIBSP_DLLLOCAL LogoutInitiatorNodeFilter : public DOMNodeFilter
{
public:
- short acceptNode(const DOMNode* node) const {
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+ short
+#else
+ FilterAction
+#endif
+ acceptNode(const DOMNode* node) const {
if (XMLHelper::isNodeNamed(node,shibspconstants::SHIB2SPCONFIG_NS,_LogoutInitiator))
return FILTER_REJECT;
return FILTER_ACCEPT;
class SHIBSP_DLLLOCAL SessionInitiatorNodeFilter : public DOMNodeFilter
{
public:
- short acceptNode(const DOMNode* node) const {
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+ short
+#else
+ FilterAction
+#endif
+ acceptNode(const DOMNode* node) const {
if (XMLHelper::isNodeNamed(node,shibspconstants::SHIB2SPCONFIG_NS,_SessionInitiator))
return FILTER_REJECT;
return FILTER_ACCEPT;
/*
* Copyright 2001-2007 Internet2
- *
+ *
* 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
/**
* LogoutHandler.cpp
- *
+ *
* Base class for logout-related handlers.
*/
// If we're inside a chain, do nothing.
if (getParent())
return make_pair(false,0L);
-
+
// If this isn't a LogoutInitiator, we only "continue" a notification loop, rather than starting one.
if (!m_initiator && !request.getParameter("notifying"))
return make_pair(false,0L);
#include <xmltooling/impl/AnyElement.h>
#include <xmltooling/soap/SOAP.h>
#include <xmltooling/soap/SOAPClient.h>
+#include <xmltooling/soap/HTTPSOAPTransport.h>
using namespace soap11;
namespace {
static const XMLCh LogoutNotification[] = UNICODE_LITERAL_18(L,o,g,o,u,t,N,o,t,i,f,i,c,a,t,i,o,n);
private:
void prepareTransport(SOAPTransport& transport) {
transport.setVerifyHost(false);
+ HTTPSOAPTransport* http = dynamic_cast<HTTPSOAPTransport*>(&transport);
+ if (http) {
+ http->useChunkedEncoding(false);
+ http->setRequestHeader("User-Agent", PACKAGE_NAME);
+ http->setRequestHeader(PACKAGE_NAME, PACKAGE_VERSION);
+ }
}
};
};
const Application& application, const char* requestURL, const vector<string>& sessions, bool local
) const
{
+ if (sessions.empty()) {
+ Category::getInstance(SHIBSP_LOGCAT".Logout").error("no sessions supplied to back channel notification method");
+ return false;
+ }
+
unsigned int index = 0;
string endpoint = application.getNotificationURL(requestURL, false, index++);
if (endpoint.empty())
env->setBody(body);
ElementProxy* msg = new AnyElementImpl(shibspconstants::SHIB2SPNOTIFY_NS, LogoutNotification);
body->getUnknownXMLObjects().push_back(msg);
- msg->setAttribute(QName(NULL, _type), local ? _local : _global);
+ msg->setAttribute(xmltooling::QName(NULL, _type), local ? _local : _global);
for (vector<string>::const_iterator s = sessions.begin(); s!=sessions.end(); ++s) {
auto_ptr_XMLCh temp(s->c_str());
ElementProxy* child = new AnyElementImpl(shibspconstants::SHIB2SPNOTIFY_NS, SessionID);
/*
* Copyright 2001-2007 Internet2
- *
+ *
* 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
/**
* MetadataGenerator.cpp
- *
+ *
* Handler for generating "approximate" metadata based on SP configuration.
*/
#ifndef SHIBSP_LITE
# include "metadata/MetadataProviderCriteria.h"
+# include <xmltooling/util/PathResolver.h>
#endif
#include <xercesc/framework/LocalFileInputSource.hpp>
class SHIBSP_DLLLOCAL Blocker : public DOMNodeFilter
{
public:
- short acceptNode(const DOMNode* node) const {
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+ short
+#else
+ FilterAction
+#endif
+ acceptNode(const DOMNode* node) const {
return FILTER_REJECT;
}
};
#ifndef SHIBSP_LITE
static XMLCh EndpointBase[] = UNICODE_LITERAL_12(E,n,d,p,o,i,n,t,B,a,s,e);
-
+
pair<bool,bool> flag = getBool("http");
if (flag.first)
m_http = flag.second ? 1 : -1;
flag = getBool("https");
if (flag.first)
m_https = flag.second ? 1 : -1;
-
+
e = XMLHelper::getFirstChildElement(e, EndpointBase);
while (e) {
if (e->hasChildNodes()) {
if (!m_acl.empty() && m_acl.count(request.getRemoteAddr()) == 0) {
m_log.error("request for metadata blocked from invalid address (%s)", request.getRemoteAddr().c_str());
istringstream msg("Metadata Request Blocked");
- return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_UNAUTHORIZED));
+ return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN));
}
}
-
+
try {
if (conf.isEnabled(SPConfig::OutOfProcess)) {
// When out of process, we run natively and directly process the message.
if (request.getParameter("entityID"))
in.addmember("entity_id").string(request.getParameter("entityID"));
DDFJanitor jin(in), jout(out);
-
+
out=request.getServiceProvider().getListenerService()->send(in);
return unwrap(request, out);
}
else if (!hurl) {
throw ConfigurationException("Missing handler_url parameter in remoted method call.");
}
-
+
// Wrap a response shim.
DDF ret(NULL);
DDFJanitor jout(ret);
auto_ptr<HTTPResponse> resp(getResponse(ret));
-
+
// Since we're remoted, the result should either be a throw, a false/0 return,
// which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
pair<bool,const char*> prop = getString("template");
if (prop.first) {
// Load a template to use for our metadata.
- LocalFileInputSource src(getXMLString("template").second);
+ string templ(prop.second);
+ XMLToolingConfig::getConfig().getPathResolver()->resolve(templ, PathResolver::XMLTOOLING_CFG_FILE);
+ auto_ptr_XMLCh widenit(templ.c_str());
+ LocalFileInputSource src(widenit.get());
Wrapper4InputSource dsrc(&src,false);
DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(dsrc);
XercesJanitor<DOMDocument> docjan(doc);
docjan.release();
entity = dynamic_cast<EntityDescriptor*>(xmlobj.get());
if (!entity)
- throw ConfigurationException("Template file ($1) did not contain an EntityDescriptor", params(1, prop.second));
+ throw ConfigurationException("Template file ($1) did not contain an EntityDescriptor", params(1, templ.c_str()));
xmlobj.release();
}
else {
auto_ptr<EntityDescriptor> wrapper(entity);
pair<bool,unsigned int> cache = getUnsignedInt("cacheDuration");
- if (cache.first)
- entity->setValidUntil(time(NULL) + cache.second);
+ if (cache.first) {
+ entity->setCacheDuration(cache.second);
+ }
+ else {
+ cache = getUnsignedInt("validUntil");
+ if (cache.first)
+ entity->setValidUntil(time(NULL) + cache.second);
+ }
entity->setEntityID(relyingParty->getXMLString("entityID").second);
SPSSODescriptor* role;
XMLHelper::serialize(entity->marshall(), pretty, true);
DOMDocument* prettydoc = XMLToolingConfig::getConfig().getParser().parse(pretty);
auto_ptr<XMLObject> prettyentity(XMLObjectBuilder::buildOneFromElement(prettydoc->getDocumentElement(), true));
-
+
Signature* sig = SignatureBuilder::buildSignature();
dynamic_cast<EntityDescriptor*>(prettyentity.get())->setSignature(sig);
if (sigalg.first)
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
{
if (!m_output.isstruct())
m_output.structure();
- m_output.addmember("redirect").string(url);
+ m_output.addmember("redirect").unsafe_string(url);
return HTTPResponse::XMLTOOLING_HTTP_STATUS_MOVED;
}
DDF in = DDF(m_address.c_str()).structure();
in.addmember("application_id").string(request.getApplication().getId());
in.addmember("scheme").string(request.getScheme());
- in.addmember("hostname").string(request.getHostname());
+ in.addmember("hostname").unsafe_string(request.getHostname());
in.addmember("port").integer(request.getPort());
in.addmember("content_type").string(request.getContentType().c_str());
in.addmember("content_length").integer(request.getContentLength());
in.addmember("remote_user").string(request.getRemoteUser().c_str());
in.addmember("client_addr").string(request.getRemoteAddr().c_str());
in.addmember("method").string(request.getMethod());
- in.addmember("uri").string(request.getRequestURI());
- in.addmember("url").string(request.getRequestURL());
+ in.addmember("uri").unsafe_string(request.getRequestURI());
+ in.addmember("url").unsafe_string(request.getRequestURL());
in.addmember("query").string(request.getQueryString());
if (headers) {
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* SAML1Consumer.cpp
- *
- * SAML 1.x assertion consumer service
+ *
+ * SAML 1.x assertion consumer service
*/
#include "internal.h"
# include "ServiceProvider.h"
# include "SessionCache.h"
# include "attribute/resolver/ResolutionContext.h"
+# include <saml/SAMLConfig.h>
# include <saml/saml1/core/Assertions.h>
# include <saml/saml1/core/Protocols.h>
-# include <saml/saml1/profile/BrowserSSOProfileValidator.h>
# include <saml/saml2/metadata/Metadata.h>
using namespace opensaml::saml1;
using namespace opensaml::saml1p;
#pragma warning( push )
#pragma warning( disable : 4250 )
#endif
-
+
class SHIBSP_DLLLOCAL SAML1Consumer : public AssertionConsumerService
{
public:
SAML1Consumer(const DOMElement* e, const char* appId)
- : AssertionConsumerService(e, appId, Category::getInstance(SHIBSP_LOGCAT".SSO.SAML1")) {
+ : AssertionConsumerService(e, appId, Category::getInstance(SHIBSP_LOGCAT".SSO.SAML1")) {
#ifndef SHIBSP_LITE
+ m_ssoRule = NULL;
m_post = XMLString::equals(getString("Binding").second, samlconstants::SAML1_PROFILE_BROWSER_POST);
+ if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess))
+ m_ssoRule = SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(SAML1BROWSERSSO_POLICY_RULE, e);
#endif
}
- virtual ~SAML1Consumer() {}
-
+ virtual ~SAML1Consumer() {
+#ifndef SHIBSP_LITE
+ delete m_ssoRule;
+#endif
+ }
+
#ifndef SHIBSP_LITE
void generateMetadata(SPSSODescriptor& role, const char* handlerURL) const {
AssertionConsumerService::generateMetadata(role, handlerURL);
const PropertySet* settings,
const XMLObject& xmlObject
) const;
+
bool m_post;
+ SecurityPolicyRule* m_ssoRule;
#endif
};
{
return new SAML1Consumer(p.first, p.second);
}
-
+
+#ifndef SHIBSP_LITE
+ class SHIBSP_DLLLOCAL _rulenamed : std::unary_function<const SecurityPolicyRule*,bool>
+ {
+ public:
+ _rulenamed(const char* name) : m_name(name) {}
+ bool operator()(const SecurityPolicyRule* rule) const {
+ return rule ? !strcmp(m_name, rule->getType()) : false;
+ }
+ private:
+ const char* m_name;
+ };
+#endif
};
#ifndef SHIBSP_LITE
throw MetadataException("Security of SAML 1.x SSO POST response not established.");
throw SecurityPolicyException("Security of SAML 1.x SSO POST response not established.");
}
-
+
// Remember whether we already established trust.
bool alreadySecured = policy.isAuthenticated();
// Saves off error messages potentially helpful for users.
string contextualError;
- // Profile validator.
- time_t now = time(NULL);
- BrowserSSOProfileValidator ssoValidator(application.getRelyingParty(entity)->getXMLString("entityID").second, application.getAudiences(), now);
+ // Ensure the BrowserSSO rule is in the policy set.
+ if (find_if(policy.getRules(), _rulenamed(SAML1BROWSERSSO_POLICY_RULE)) == NULL)
+ policy.getRules().push_back(m_ssoRule);
+
+ // Populate recipient as audience.
+ policy.getAudiences().push_back(application.getRelyingParty(entity)->getXMLString("entityID").second);
+ time_t now = time(NULL);
for (vector<saml1::Assertion*>::const_iterator a = assertions.begin(); a!=assertions.end(); ++a) {
try {
// Skip unsigned assertion?
);
// Run the policy over the assertion. Handles replay, freshness, and
- // signature verification, assuming the relevant rules are configured.
- policy.evaluate(*(*a));
-
+ // signature verification, assuming the relevant rules are configured,
+ // along with condition and profile enforcement.
+ policy.evaluate(*(*a), &httpRequest);
+
// If no security is in place now, we kick it.
if (!alreadySecured && !policy.isAuthenticated())
throw SecurityPolicyException("Unable to establish security of incoming assertion.");
- // Now do profile and core semantic validation to ensure we can use it for SSO.
- ssoValidator.validateAssertion(*(*a));
-
// Track it as a valid token.
tokens.push_back(*a);
MessageEncoder* m_encoder;
MessageDecoder* m_decoder;
- QName m_role;
+ xmltooling::QName m_role;
#endif
};
getString("Binding").second,pair<const DOMElement*,const XMLCh*>(e,NULL)
);
}
- catch (exception& ex) {
+ catch (exception&) {
m_log.error("error building MessageEncoder/Decoder pair for binding (%s)", getString("Binding").second);
delete m_encoder;
delete m_decoder;
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* SAML2Consumer.cpp
- *
- * SAML 2.0 assertion consumer service
+ *
+ * SAML 2.0 assertion consumer service
*/
#include "internal.h"
# include "ServiceProvider.h"
# include "SessionCache.h"
# include "attribute/resolver/ResolutionContext.h"
+# include <saml/SAMLConfig.h>
# include <saml/saml2/core/Protocols.h>
-# include <saml/saml2/profile/BrowserSSOProfileValidator.h>
# include <saml/saml2/metadata/Metadata.h>
# include <saml/saml2/metadata/MetadataCredentialCriteria.h>
+# include <saml/saml2/profile/SAML2AssertionPolicy.h>
using namespace opensaml::saml2;
using namespace opensaml::saml2p;
using namespace opensaml::saml2md;
#pragma warning( push )
#pragma warning( disable : 4250 )
#endif
-
+
class SHIBSP_DLLLOCAL SAML2Consumer : public AssertionConsumerService
{
public:
SAML2Consumer(const DOMElement* e, const char* appId)
: AssertionConsumerService(e, appId, Category::getInstance(SHIBSP_LOGCAT".SSO.SAML2")) {
+#ifndef SHIBSP_LITE
+ m_ssoRule = NULL;
+ if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess))
+ m_ssoRule = SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(BEARER_POLICY_RULE, e);
+#endif
}
- virtual ~SAML2Consumer() {}
-
+ virtual ~SAML2Consumer() {
+#ifndef SHIBSP_LITE
+ delete m_ssoRule;
+#endif
+ }
+
#ifndef SHIBSP_LITE
void generateMetadata(SPSSODescriptor& role, const char* handlerURL) const {
AssertionConsumerService::generateMetadata(role, handlerURL);
const PropertySet* settings,
const XMLObject& xmlObject
) const;
+
+ SecurityPolicyRule* m_ssoRule;
#endif
};
{
return new SAML2Consumer(p.first, p.second);
}
-
+
+#ifndef SHIBSP_LITE
+ class SHIBSP_DLLLOCAL _rulenamed : std::unary_function<const SecurityPolicyRule*,bool>
+ {
+ public:
+ _rulenamed(const char* name) : m_name(name) {}
+ bool operator()(const SecurityPolicyRule* rule) const {
+ return rule ? !strcmp(m_name, rule->getType()) : false;
+ }
+ private:
+ const char* m_name;
+ };
+#endif
};
#ifndef SHIBSP_LITE
bool alreadySecured = policy.isAuthenticated();
// Check for errors...this will throw if it's not a successful message.
- checkError(&xmlObject);
+ checkError(&xmlObject, policy.getIssuerMetadata());
const Response* response = dynamic_cast<const Response*>(&xmlObject);
if (!response)
flag = application.getRelyingParty(entity)->getBool("requireSignedAssertions");
}
- time_t now = time(NULL);
- string dest = httpRequest.getRequestURL();
-
// authnskew allows rejection of SSO if AuthnInstant is too old.
const PropertySet* sessionProps = application.getPropertySet("Sessions");
pair<bool,unsigned int> authnskew = sessionProps ? sessionProps->getUnsignedInt("maxTimeSinceAuthn") : pair<bool,unsigned int>(false,0);
// Saves off error messages potentially helpful for users.
string contextualError;
+ // Ensure the Bearer rule is in the policy set.
+ if (find_if(policy.getRules(), _rulenamed(BEARER_POLICY_RULE)) == NULL)
+ policy.getRules().push_back(m_ssoRule);
+
+ // Populate recipient as audience.
+ policy.getAudiences().push_back(application.getRelyingParty(entity)->getXMLString("entityID").second);
+
+ time_t now = time(NULL);
for (vector<saml2::Assertion*>::const_iterator a = assertions.begin(); a!=assertions.end(); ++a) {
try {
// Skip unsigned assertion?
extractMessageDetails(*(*a), samlconstants::SAML20P_NS, policy);
// Run the policy over the assertion. Handles replay, freshness, and
- // signature verification, assuming the relevant rules are configured.
- policy.evaluate(*(*a));
-
+ // signature verification, assuming the relevant rules are configured,
+ // along with condition and profile enforcement.
+ policy.evaluate(*(*a), &httpRequest);
+
// If no security is in place now, we kick it.
if (!alreadySecured && !policy.isAuthenticated())
throw SecurityPolicyException("Unable to establish security of incoming assertion.");
throw SecurityPolicyException("The incoming assertion was unsigned, violating local security policy.");
}
- // Now do profile and core semantic validation to ensure we can use it for SSO.
- BrowserSSOProfileValidator ssoValidator(
- application.getRelyingParty(entity)->getXMLString("entityID").second, application.getAudiences(), now, dest.substr(0,dest.find('?')).c_str()
- );
- ssoValidator.validateAssertion(*(*a));
-
// Address checking.
- checkAddress(application, httpRequest, ssoValidator.getAddress());
+ SubjectConfirmationData* subcondata = dynamic_cast<SubjectConfirmationData*>(
+ dynamic_cast<SAML2AssertionPolicy&>(policy).getSubjectConfirmation()->getSubjectConfirmationData()
+ );
+ if (subcondata && subcondata->getAddress()) {
+ auto_ptr_char boundip(subcondata->getAddress());
+ checkAddress(application, httpRequest, boundip.get());
+ }
// Track it as a valid token.
tokens.push_back(*a);
continue;
try {
- // Skip unsigned assertion?
- if (!decrypted->getSignature() && flag.first && flag.second)
- throw SecurityPolicyException("The incoming assertion was unsigned, violating local security policy.");
-
// We clear the security flag, so we can tell whether the token was secured on its own.
policy.setAuthenticated(false);
policy.reset(true);
extractMessageDetails(*decrypted, samlconstants::SAML20P_NS, policy);
// Run the policy over the assertion. Handles replay, freshness, and
- // signature verification, assuming the relevant rules are configured.
+ // signature verification, assuming the relevant rules are configured,
+ // along with condition and profile enforcement.
// We have to marshall the object first to ensure signatures can be checked.
if (!decrypted->getDOM())
decrypted->marshall();
- policy.evaluate(*decrypted);
-
+ policy.evaluate(*decrypted, &httpRequest);
+
// If no security is in place now, we kick it.
if (!alreadySecured && !policy.isAuthenticated())
throw SecurityPolicyException("Unable to establish security of incoming assertion.");
- // Now do profile and core semantic validation to ensure we can use it for SSO.
- BrowserSSOProfileValidator ssoValidator(
- application.getRelyingParty(entity)->getXMLString("entityID").second, application.getAudiences(), now, dest.substr(0,dest.find('?')).c_str()
- );
- ssoValidator.validateAssertion(*decrypted);
+ // If we hadn't established Issuer yet, redo the signedAssertions check.
+ if (!entity && policy.getIssuerMetadata()) {
+ entity = dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent());
+ flag = application.getRelyingParty(entity)->getBool("requireSignedAssertions");
+ if (!decrypted->getSignature() && flag.first && flag.second)
+ throw SecurityPolicyException("The decrypted assertion was unsigned, violating local security policy.");
+ }
// Address checking.
- checkAddress(application, httpRequest, ssoValidator.getAddress());
+ SubjectConfirmationData* subcondata = dynamic_cast<SubjectConfirmationData*>(
+ dynamic_cast<SAML2AssertionPolicy&>(policy).getSubjectConfirmation()->getSubjectConfirmationData()
+ );
+ if (subcondata && subcondata->getAddress()) {
+ auto_ptr_char boundip(subcondata->getAddress());
+ checkAddress(application, httpRequest, boundip.get());
+ }
// Track it as a valid token.
tokens.push_back(decrypted);
// Now we have to extract the authentication details for session setup.
// Session expiration for SAML 2.0 is jointly IdP- and SP-driven.
- time_t sessionExp = ssoStatement->getSessionNotOnOrAfter() ? ssoStatement->getSessionNotOnOrAfterEpoch() : 0;
+ time_t sessionExp = ssoStatement->getSessionNotOnOrAfter() ?
+ (ssoStatement->getSessionNotOnOrAfterEpoch() + XMLToolingConfig::getConfig().clock_skew_secs) : 0;
pair<bool,unsigned int> lifetime = sessionProps ? sessionProps->getUnsignedInt("lifetime") : pair<bool,unsigned int>(true,28800);
if (!lifetime.first || lifetime.second == 0)
lifetime.second = 28800;
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* SAML2Logout.cpp
- *
+ *
* Handles SAML 2.0 single logout protocol messages.
*/
#pragma warning( push )
#pragma warning( disable : 4250 )
#endif
-
+
class SHIBSP_DLLLOCAL SAML2Logout : public AbstractHandler, public LogoutHandler
{
public:
}
#endif
}
-
+
void receive(DDF& in, ostream& out);
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
bool front
) const;
- QName m_role;
+ xmltooling::QName m_role;
MessageDecoder* m_decoder;
XMLCh* m_outgoing;
vector<const XMLCh*> m_bindings;
,m_role(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME), m_decoder(NULL), m_outgoing(NULL)
#endif
{
-#ifndef SHIBSP_LITE
m_initiator = false;
+#ifndef SHIBSP_LITE
m_preserve.push_back("ID");
m_preserve.push_back("entityID");
m_preserve.push_back("RelayState");
MessageEncoder * encoder = conf.MessageEncoderManager.newPlugin(
b.get(), pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
);
- m_encoders[start] = encoder;
- m_log.debug("supporting outgoing front-channel binding (%s)", b.get());
+ if (encoder->isUserAgentPresent()) {
+ m_encoders[start] = encoder;
+ m_log.debug("supporting outgoing binding (%s)", b.get());
+ }
+ else {
+ delete encoder;
+ m_log.warn("skipping outgoing binding (%s), not a front-channel mechanism", b.get());
+ }
}
catch (exception& ex) {
m_log.error("error building MessageEncoder: %s", ex.what());
m_log.error("couldn't find application (%s) for logout", aid ? aid : "(missing)");
throw ConfigurationException("Unable to locate application for logout, deleted?");
}
-
+
// Unpack the request.
auto_ptr<HTTPRequest> req(getRequest(in));
DDF ret(NULL);
DDFJanitor jout(ret);
auto_ptr<HTTPResponse> resp(getResponse(ret));
-
+
// Since we're remoted, the result should either be a throw, which we pass on,
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
pair<bool,const char*> policyId = getString("policyId", m_configNS.get()); // namespace-qualified if inside handler element
if (!policyId.first)
policyId = application.getString("policyId"); // unqualified in Application(s) element
-
+
// Access policy properties.
const PropertySet* settings = application.getServiceProvider().getPolicySettings(policyId.second);
pair<bool,bool> validate = settings->getBool("validate");
// Create the policy.
shibsp::SecurityPolicy policy(application, &m_role, validate.first && validate.second);
-
+
// Decode the message.
string relayState;
auto_ptr<XMLObject> msg(m_decoder->decode(relayState, request, policy));
throw SecurityPolicyException("Security of LogoutRequest not established.");
// Message from IdP to logout one or more sessions.
-
+
// If this is front-channel, we have to have a session_id to use already.
if (m_decoder->isUserAgentPresent() && session_id.empty()) {
m_log.error("no active session");
if (cacheex) {
time_t expires = logoutRequest->getNotOnOrAfter() ? logoutRequest->getNotOnOrAfterEpoch() : 0;
cacheex->logout(application, entity, *nameid, &indexes, expires, sessions);
+ m_log.debug("session cache returned %d sessions bound to NameID in logout request", sessions.size());
// Now we actually terminate everything except for the active session,
// if this is front-channel, for notification purposes.
if (result.first)
return result;
}
-
+
// For back-channel requests, or if no front-channel notification is needed...
- bool worked1 = false,worked2 = false;
- worked1 = notifyBackChannel(application, request.getRequestURL(), sessions, false);
+ bool worked1 = notifyBackChannel(application, request.getRequestURL(), sessions, false);
+ bool worked2 = true;
if (!session_id.empty()) {
// One last session to yoink...
try {
cache->remove(application, request, &response);
- worked2 = true;
}
catch (exception& ex) {
+ worked2 = false;
m_log.error("error removing active session (%s): %s", session_id.c_str(), ex.what());
}
}
auto_ptr_char b(start);
MessageEncoder * encoder =
SAMLConfig::getConfig().MessageEncoderManager.newPlugin(b.get(),pair<const DOMElement*,const XMLCh*>(e,NULL));
- m_encoders[start] = encoder;
- m_log.debug("supporting outgoing binding (%s)", b.get());
+ if (encoder->isUserAgentPresent()) {
+ m_encoders[start] = encoder;
+ m_log.debug("supporting outgoing binding (%s)", b.get());
+ }
+ else {
+ delete encoder;
+ m_log.warn("skipping outgoing binding (%s), not a front-channel mechanism", b.get());
+ }
}
catch (exception& ex) {
m_log.error("error building MessageEncoder: %s", ex.what());
/*
* Copyright 2001-2007 Internet2
- *
+ *
* 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
/**
* SAML2NameIDMgmt.cpp
- *
+ *
* Handles SAML 2.0 NameID management protocol messages.
*/
#pragma warning( push )
#pragma warning( disable : 4250 )
#endif
-
+
class SHIBSP_DLLLOCAL SAML2NameIDMgmt : public AbstractHandler, public RemotedHandler
{
public:
}
#endif
}
-
+
void receive(DDF& in, ostream& out);
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
bool front
) const;
- QName m_role;
+ xmltooling::QName m_role;
MessageDecoder* m_decoder;
XMLCh* m_outgoing;
vector<const XMLCh*> m_bindings;
MessageEncoder * encoder = conf.MessageEncoderManager.newPlugin(
b.get(), pair<const DOMElement*,const XMLCh*>(e,shibspconstants::SHIB2SPCONFIG_NS)
);
- m_encoders[start] = encoder;
- m_log.debug("supporting outgoing front-channel binding (%s)", b.get());
+ if (encoder->isUserAgentPresent()) {
+ m_encoders[start] = encoder;
+ m_log.debug("supporting outgoing binding (%s)", b.get());
+ }
+ else {
+ delete encoder;
+ m_log.warn("skipping outgoing binding (%s), not a front-channel mechanism", b.get());
+ }
}
catch (exception& ex) {
m_log.error("error building MessageEncoder: %s", ex.what());
m_log.error("couldn't find application (%s) for NameID mgmt", aid ? aid : "(missing)");
throw ConfigurationException("Unable to locate application for NameID mgmt, deleted?");
}
-
+
// Unpack the request.
auto_ptr<HTTPRequest> req(getRequest(in));
DDF ret(NULL);
DDFJanitor jout(ret);
auto_ptr<HTTPResponse> resp(getResponse(ret));
-
+
// Since we're remoted, the result should either be a throw, which we pass on,
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
pair<bool,const char*> policyId = getString("policyId", m_configNS.get()); // namespace-qualified if inside handler element
if (!policyId.first)
policyId = application.getString("policyId"); // unqualified in Application(s) element
-
+
// Access policy properties.
const PropertySet* settings = application.getServiceProvider().getPolicySettings(policyId.second);
pair<bool,bool> validate = settings->getBool("validate");
// Create the policy.
shibsp::SecurityPolicy policy(application, &m_role, validate.first && validate.second);
-
+
// Decode the message.
string relayState;
auto_ptr<XMLObject> msg(m_decoder->decode(relayState, request, policy));
#include <xmltooling/impl/AnyElement.h>
#include <xmltooling/soap/SOAP.h>
#include <xmltooling/soap/SOAPClient.h>
+#include <xmltooling/soap/HTTPSOAPTransport.h>
using namespace soap11;
namespace {
static const XMLCh NameIDNotification[] = UNICODE_LITERAL_18(N,a,m,e,I,D,N,o,t,i,f,i,c,a,t,i,o,n);
private:
void prepareTransport(SOAPTransport& transport) {
transport.setVerifyHost(false);
+ HTTPSOAPTransport* http = dynamic_cast<HTTPSOAPTransport*>(&transport);
+ if (http) {
+ http->useChunkedEncoding(false);
+ http->setRequestHeader("User-Agent", PACKAGE_NAME);
+ http->setRequestHeader(PACKAGE_NAME, PACKAGE_VERSION);
+ }
}
};
};
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* SAML2SessionInitiator.cpp
- *
+ *
* SAML 2.0 AuthnRequest support.
*/
XMLString::release(&m_outgoing);
for_each(m_encoders.begin(), m_encoders.end(), cleanup_pair<const XMLCh*,MessageEncoder>());
delete m_requestTemplate;
+ delete m_ecp;
}
#endif
}
-
+
void setParent(const PropertySet* parent);
void receive(DDF& in, ostream& out);
+ pair<bool,long> unwrap(SPRequest& request, DDF& out) const;
pair<bool,long> run(SPRequest& request, string& entityID, bool isHandler=true) const;
private:
pair<bool,long> doRequest(
const Application& application,
+ const HTTPRequest* httpRequest,
HTTPResponse& httpResponse,
const char* entityID,
const XMLCh* acsIndex,
+ bool artifactInbound,
const char* acsLocation,
const XMLCh* acsBinding,
bool isPassive,
MessageEncoder * encoder = SAMLConfig::getConfig().MessageEncoderManager.newPlugin(
b.get(),pair<const DOMElement*,const XMLCh*>(e,NULL)
);
- m_encoders[start] = encoder;
- m_log.debug("supporting outgoing binding (%s)", b.get());
+ if (encoder->isUserAgentPresent()) {
+ m_encoders[start] = encoder;
+ m_log.debug("supporting outgoing binding (%s)", b.get());
+ }
+ else {
+ delete encoder;
+ m_log.warn("skipping outgoing binding (%s), not a front-channel mechanism", b.get());
+ }
}
catch (exception& ex) {
m_log.error("error building MessageEncoder: %s", ex.what());
return make_pair(false,0L);
string target;
+ string postData;
const Handler* ACS=NULL;
const char* option;
pair<bool,const char*> acClass;
option = request.getParameter("target");
if (option)
target = option;
-
+
// Always need to recover target URL to compute handler below.
recoverRelayState(request.getApplication(), request, request, target, false);
}
}
+ // Validate the ACS for use with this protocol.
+ if (!ECP) {
+ pair<bool,const char*> ACSbinding = ACS ? ACS->getString("Binding") : pair<bool,const char*>(false,NULL);
+ if (ACSbinding.first) {
+ pair<bool,const char*> compatibleBindings = getString("compatibleBindings");
+ if (compatibleBindings.first && strstr(compatibleBindings.second, ACSbinding.second) == NULL) {
+ m_log.info("configured or requested ACS has non-SAML 2.0 binding");
+ return make_pair(false,0L);
+ }
+ else if (strcmp(ACSbinding.second, samlconstants::SAML20_BINDING_HTTP_POST) &&
+ strcmp(ACSbinding.second, samlconstants::SAML20_BINDING_HTTP_ARTIFACT) &&
+ strcmp(ACSbinding.second, samlconstants::SAML20_BINDING_HTTP_POST_SIMPLESIGN)) {
+ m_log.info("configured or requested ACS has non-SAML 2.0 binding");
+ return make_pair(false,0L);
+ }
+ }
+ }
+
// To invoke the request builder, the key requirement is to figure out how
// to express the ACS, by index or value, and if by value, where.
// We have to compute the handlerURL no matter what, because we may need to
// flip the index to an SSL-version.
string ACSloc=request.getHandlerURL(target.c_str());
-
+
SPConfig& conf = SPConfig::getConfig();
if (conf.isEnabled(SPConfig::OutOfProcess)) {
- if (!acsByIndex.first || acsByIndex.second) {
+ if (acsByIndex.first && acsByIndex.second) {
// Pass by Index.
if (isHandler) {
// We may already have RelayState set if we looped back here,
if (option)
target = option;
}
-
+
// Determine index to use.
pair<bool,const XMLCh*> ix = pair<bool,const XMLCh*>(false,NULL);
if (ACS) {
ix = ACS->getXMLString("index");
}
}
-
+
return doRequest(
- app, request, entityID.c_str(),
- ix.second, NULL, NULL,
+ app, &request, request, entityID.c_str(),
+ ix.second,
+ ACS ? XMLString::equals(ACS->getString("Binding").second, samlconstants::SAML20_BINDING_HTTP_ARTIFACT) : false,
+ NULL, NULL,
isPassive, forceAuthn,
acClass.first ? acClass.second : NULL,
acComp.first ? acComp.second : NULL,
}
return doRequest(
- app, request, entityID.c_str(),
- NULL, ACSloc.c_str(), ACS ? ACS->getXMLString("Binding").second : NULL,
+ app, &request, request, entityID.c_str(),
+ NULL,
+ ACS ? XMLString::equals(ACS->getString("Binding").second, samlconstants::SAML20_BINDING_HTTP_ARTIFACT) : false,
+ ACSloc.c_str(), ACS ? ACS->getXMLString("Binding").second : NULL,
isPassive, forceAuthn,
acClass.first ? acClass.second : NULL,
acComp.first ? acComp.second : NULL,
in.addmember("authnContextClassRef").string(acClass.second);
if (acComp.first)
in.addmember("authnContextComparison").string(acComp.second);
- if (!acsByIndex.first || acsByIndex.second) {
+ if (acsByIndex.first && acsByIndex.second) {
if (ACS) {
// Determine index to use.
pair<bool,const char*> ix = pair<bool,const char*>(false,NULL);
ix = ACS->getString("index");
}
in.addmember("acsIndex").string(ix.second);
+ if (XMLString::equals(ACS->getString("Binding").second, samlconstants::SAML20_BINDING_HTTP_ARTIFACT))
+ in.addmember("artifact").integer(1);
}
}
else {
pair<bool,const char*> loc=ACS ? ACS->getString("Location") : pair<bool,const char*>(false,NULL);
if (loc.first) ACSloc+=loc.second;
in.addmember("acsLocation").string(ACSloc.c_str());
- if (ACS)
- in.addmember("acsBinding").string(ACS->getString("Binding").second);
+ if (ACS) {
+ loc = ACS->getString("Binding");
+ in.addmember("acsBinding").string(loc.second);
+ if (XMLString::equals(loc.second, samlconstants::SAML20_BINDING_HTTP_ARTIFACT))
+ in.addmember("artifact").integer(1);
+ }
}
if (isHandler) {
target = option;
}
if (!target.empty())
- in.addmember("RelayState").string(target.c_str());
+ in.addmember("RelayState").unsafe_string(target.c_str());
// Remote the processing.
out = request.getServiceProvider().getListenerService()->send(in);
return unwrap(request, out);
}
+pair<bool,long> SAML2SessionInitiator::unwrap(SPRequest& request, DDF& out) const
+{
+ // See if there's any response to send back.
+ if (!out["redirect"].isnull() || !out["response"].isnull()) {
+ // If so, we're responsible for handling the POST data, probably by dropping a cookie.
+ preservePostData(request.getApplication(), request, request, out["RelayState"].string());
+ }
+ return RemotedHandler::unwrap(request, out);
+}
+
void SAML2SessionInitiator::receive(DDF& in, ostream& out)
{
// Find application.
auto_ptr_XMLCh bind(in["acsBinding"].string());
string relayState(in["RelayState"].string() ? in["RelayState"].string() : "");
+ string postData(in["PostData"].string() ? in["PostData"].string() : "");
// Since we're remoted, the result should either be a throw, which we pass on,
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
doRequest(
- *app, *http.get(), in["entity_id"].string(),
- index.get(), in["acsLocation"].string(), bind.get(),
+ *app, NULL, *http.get(), in["entity_id"].string(),
+ index.get(),
+ (in["artifact"].integer() != 0),
+ in["acsLocation"].string(), bind.get(),
in["isPassive"].integer()==1, in["forceAuthn"].integer()==1,
in["authnContextClassRef"].string(), in["authnContextComparison"].string(),
relayState
);
+ if (!ret.isstruct())
+ ret.structure();
+ ret.addmember("RelayState").unsafe_string(relayState.c_str());
out << ret;
}
pair<bool,long> SAML2SessionInitiator::doRequest(
const Application& app,
+ const HTTPRequest* httpRequest,
HTTPResponse& httpResponse,
const char* entityID,
const XMLCh* acsIndex,
+ bool artifactInbound,
const char* acsLocation,
const XMLCh* acsBinding,
bool isPassive,
// We won't need this for ECP, but safety dictates we get the lock here.
MetadataProvider* m=app.getMetadataProvider();
Locker locker(m);
-
+
if (ECP) {
encoder = m_ecp;
if (!encoder) {
throw MetadataException("Unable to locate metadata for identity provider ($entityID)", namedparams(1, "entityID", entityID));
}
else if (!entity.second) {
- m_log.warn("unable to locate SAML 2.0 identity provider role for provider (%s)", entityID);
+ m_log.log(getParent() ? Priority::INFO : Priority::WARN, "unable to locate SAML 2.0 identity provider role for provider (%s)", entityID);
if (getParent())
return make_pair(false,0L);
throw MetadataException("Unable to locate SAML 2.0 identity provider role for provider ($entityID)", namedparams(1, "entityID", entityID));
}
+ else if (artifactInbound && !SPConfig::getConfig().getArtifactResolver()->isSupported(dynamic_cast<const SSODescriptorType&>(*entity.second))) {
+ m_log.warn("artifact binding selected for response, but identity provider lacks support");
+ if (getParent())
+ return make_pair(false,0L);
+ throw MetadataException("Identity provider ($entityID) lacks SAML 2.0 artifact support.", namedparams(1, "entityID", entityID));
+ }
// Loop over the supportable outgoing bindings.
role = dynamic_cast<const IDPSSODescriptor*>(entity.second);
cref->setReference(wideclass.get());
reqContext->getAuthnContextClassRefs().push_back(cref);
}
-
+
if (reqContext->getAuthnContextClassRefs().empty() && reqContext->getAuthnContextDeclRefs().empty()) {
req->setRequestedAuthnContext(NULL);
}
}
}
+ pair<bool,bool> requestDelegation = getBool("requestDelegation");
+ if (requestDelegation.first && requestDelegation.second && entity.first) {
+ // Request delegation by including the IdP as an Audience.
+ // Also specify the expected session lifetime as the bound on the assertion lifetime.
+ const PropertySet* sessionProps = app.getPropertySet("Sessions");
+ pair<bool,unsigned int> lifetime = sessionProps ? sessionProps->getUnsignedInt("lifetime") : pair<bool,unsigned int>(true,28800);
+ if (!lifetime.first || lifetime.second == 0)
+ lifetime.second = 28800;
+ if (!req->getConditions())
+ req->setConditions(ConditionsBuilder::buildConditions());
+ req->getConditions()->setNotOnOrAfter(time(NULL) + lifetime.second + 300);
+ AudienceRestriction* audrest = AudienceRestrictionBuilder::buildAudienceRestriction();
+ req->getConditions()->getConditions().push_back(audrest);
+ Audience* aud = AudienceBuilder::buildAudience();
+ audrest->getAudiences().push_back(aud);
+ aud->setAudienceURI(entity.first->getEntityID());
+ }
+
if (ECP && entityID) {
auto_ptr_XMLCh wideid(entityID);
Scoping* scoping = req->getScoping();
auto_ptr_char dest(ep ? ep->getLocation() : NULL);
+ if (httpRequest) {
+ // If the request object is available, we're responsible for the POST data.
+ preservePostData(app, *httpRequest, httpResponse, relayState.c_str());
+ }
+
long ret = sendMessage(
*encoder, req.get(), relayState.c_str(), dest.get(), role, app, httpResponse, role ? role->WantAuthnRequestsSigned() : false
);
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* SAMLDSSessionInitiator.cpp
- *
+ *
* SAML Discovery Service support.
*/
m_returnParam = url.second;
}
virtual ~SAMLDSSessionInitiator() {}
-
+
pair<bool,long> run(SPRequest& request, string& entityID, bool isHandler=true) const;
#ifndef SHIBSP_LITE
hurl += loc;
auto_ptr_XMLCh widen(hurl.c_str());
ElementProxy* ep = new AnyElementImpl(m_discoNS.get(), LOCAL_NAME);
- ep->setAttribute(QName(NULL,EndpointType::LOCATION_ATTRIB_NAME), widen.get());
- ep->setAttribute(QName(NULL,EndpointType::BINDING_ATTRIB_NAME), getXMLString("Binding").second);
+ ep->setAttribute(xmltooling::QName(NULL,EndpointType::LOCATION_ATTRIB_NAME), widen.get());
+ ep->setAttribute(xmltooling::QName(NULL,EndpointType::BINDING_ATTRIB_NAME), m_discoNS.get());
pair<bool,const XMLCh*> ix = getXMLString("index");
- ep->setAttribute(QName(NULL,IndexedEndpointType::INDEX_ATTRIB_NAME), ix.first ? ix.second : xmlconstants::XML_ONE);
-
+ ep->setAttribute(xmltooling::QName(NULL,IndexedEndpointType::INDEX_ATTRIB_NAME), ix.first ? ix.second : xmlconstants::XML_ONE);
+
Extensions* ext = role.getExtensions();
if (!ext) {
ext = ExtensionsBuilder::buildExtensions();
ex.addProperty("statusCode2", "urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP");
ex.raise();
}
-
+
option = request.getParameter("target");
if (option)
target = option;
target = option;
}
preserveRelayState(request.getApplication(), request, target);
+ if (!isHandler)
+ preservePostData(request.getApplication(), request, request, target.c_str());
const URLEncoder* urlenc = XMLToolingConfig::getConfig().getURLEncoder();
if (isHandler) {
/*
* Copyright 2001-2007 Internet2
- *
+ *
* 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
/**
* SessionHandler.cpp
- *
+ *
* Handler for dumping information about an active session.
*/
class SHIBSP_DLLLOCAL Blocker : public DOMNodeFilter
{
public:
- short acceptNode(const DOMNode* node) const {
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+ short
+#else
+ FilterAction
+#endif
+ acceptNode(const DOMNode* node) const {
return FILTER_REJECT;
}
};
if (!m_acl.empty() && m_acl.count(request.getRemoteAddr()) == 0) {
m_log.error("session handler request blocked from invalid address (%s)", request.getRemoteAddr().c_str());
istringstream msg("Session Handler Blocked");
- return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_UNAUTHORIZED));
+ return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN));
}
stringstream s;
if (!m_values && !attributes.empty())
s << count << " value(s)" << endl;
-
+
s << "</pre></body></html>";
request.setContentType("text/html; charset=UTF-8");
request.setResponseHeader("Expires","01-Jan-1997 12:00:00 GMT");
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* Shib1SessionInitiator.cpp
- *
+ *
* Shibboleth 1.x AuthnRequest support.
*/
}
}
virtual ~Shib1SessionInitiator() {}
-
+
void setParent(const PropertySet* parent);
void receive(DDF& in, ostream& out);
+ pair<bool,long> unwrap(SPRequest& request, DDF& out) const;
pair<bool,long> run(SPRequest& request, string& entityID, bool isHandler=true) const;
private:
pair<bool,long> doRequest(
const Application& application,
+ const HTTPRequest* httpRequest,
HTTPResponse& httpResponse,
const char* entityID,
const char* acsLocation,
+ bool artifact,
string& relayState
) const;
string m_appId;
return make_pair(false,0L);
string target;
+ string postData;
const Handler* ACS=NULL;
const char* option;
const Application& app=request.getApplication();
ACS = app.getDefaultAssertionConsumerService();
}
+ // Validate the ACS for use with this protocol.
+ pair<bool,const char*> ACSbinding = ACS ? ACS->getString("Binding") : pair<bool,const char*>(false,NULL);
+ if (ACSbinding.first) {
+ pair<bool,const char*> compatibleBindings = getString("compatibleBindings");
+ if (compatibleBindings.first && strstr(compatibleBindings.second, ACSbinding.second) == NULL) {
+ m_log.info("configured or requested ACS has non-SAML 1.x binding");
+ return make_pair(false,0L);
+ }
+ else if (strcmp(ACSbinding.second, samlconstants::SAML1_PROFILE_BROWSER_POST) &&
+ strcmp(ACSbinding.second, samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT)) {
+ m_log.info("configured or requested ACS has non-SAML 1.x binding");
+ return make_pair(false,0L);
+ }
+ }
+
// Compute the ACS URL. We add the ACS location to the base handlerURL.
string ACSloc=request.getHandlerURL(target.c_str());
pair<bool,const char*> loc=ACS ? ACS->getString("Location") : pair<bool,const char*>(false,NULL);
target = option;
}
+ // Is the in-bound binding artifact?
+ bool artifactInbound = ACS ? XMLString::equals(ACS->getString("Binding").second, samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT) : false;
+
m_log.debug("attempting to initiate session using Shibboleth with provider (%s)", entityID.c_str());
- if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess))
- return doRequest(app, request, entityID.c_str(), ACSloc.c_str(), target);
+ if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
+ // Out of process means the POST data via the request can be exposed directly to the private method.
+ // The method will handle POST preservation if necessary *before* issuing the response, but only if
+ // it dispatches to an IdP.
+ return doRequest(app, &request, request, entityID.c_str(), ACSloc.c_str(), artifactInbound, target);
+ }
// Remote the call.
DDF out,in = DDF(m_address.c_str()).structure();
in.addmember("application_id").string(app.getId());
in.addmember("entity_id").string(entityID.c_str());
in.addmember("acsLocation").string(ACSloc.c_str());
+ if (artifactInbound)
+ in.addmember("artifact").integer(1);
if (!target.empty())
- in.addmember("RelayState").string(target.c_str());
+ in.addmember("RelayState").unsafe_string(target.c_str());
- // Remote the processing.
+ // Remote the processing. Our unwrap method will handle POST data if necessary.
out = request.getServiceProvider().getListenerService()->send(in);
return unwrap(request, out);
}
+pair<bool,long> Shib1SessionInitiator::unwrap(SPRequest& request, DDF& out) const
+{
+ // See if there's any response to send back.
+ if (!out["redirect"].isnull() || !out["response"].isnull()) {
+ // If so, we're responsible for handling the POST data, probably by dropping a cookie.
+ preservePostData(request.getApplication(), request, request, out["RelayState"].string());
+ }
+ return RemotedHandler::unwrap(request, out);
+}
+
void Shib1SessionInitiator::receive(DDF& in, ostream& out)
{
// Find application.
// Since we're remoted, the result should either be a throw, which we pass on,
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- doRequest(*app, *http.get(), entityID, acsLocation, relayState);
+ doRequest(*app, NULL, *http.get(), entityID, acsLocation, (in["artifact"].integer() != 0), relayState);
+ if (!ret.isstruct())
+ ret.structure();
+ ret.addmember("RelayState").unsafe_string(relayState.c_str());
out << ret;
}
pair<bool,long> Shib1SessionInitiator::doRequest(
const Application& app,
+ const HTTPRequest* httpRequest,
HTTPResponse& httpResponse,
const char* entityID,
const char* acsLocation,
+ bool artifact,
string& relayState
) const
{
throw MetadataException("Unable to locate metadata for identity provider ($entityID)", namedparams(1, "entityID", entityID));
}
else if (!entity.second) {
- m_log.warn("unable to locate Shibboleth-aware identity provider role for provider (%s)", entityID);
+ m_log.log(getParent() ? Priority::INFO : Priority::WARN, "unable to locate Shibboleth-aware identity provider role for provider (%s)", entityID);
if (getParent())
return make_pair(false,0L);
throw MetadataException("Unable to locate Shibboleth-aware identity provider role for provider ($entityID)", namedparams(1, "entityID", entityID));
}
+ else if (artifact && !SPConfig::getConfig().getArtifactResolver()->isSupported(dynamic_cast<const SSODescriptorType&>(*entity.second))) {
+ m_log.warn("artifact profile selected for response, but identity provider lacks support");
+ if (getParent())
+ return make_pair(false,0L);
+ throw MetadataException("Identity provider ($entityID) lacks SAML artifact support.", namedparams(1, "entityID", entityID));
+ }
+
const EndpointType* ep=EndpointManager<SingleSignOnService>(
dynamic_cast<const IDPSSODescriptor*>(entity.second)->getSingleSignOnServices()
).getByBinding(shibspconstants::SHIB1_AUTHNREQUEST_PROFILE_URI);
"&time=" + timebuf + "&target=" + urlenc->encode(relayState.c_str()) +
"&providerId=" + urlenc->encode(app.getRelyingParty(entity.first)->getString("entityID").second);
+ if (httpRequest) {
+ // If the request object is available, we're responsible for the POST data.
+ preservePostData(app, *httpRequest, httpResponse, relayState.c_str());
+ }
+
return make_pair(true, httpResponse.sendRedirect(req.c_str()));
#else
return make_pair(false,0L);
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* StatusHandler.cpp
- *
+ *
* Handler for exposing information about the internals of the SP.
*/
class SHIBSP_DLLLOCAL Blocker : public DOMNodeFilter
{
public:
- short acceptNode(const DOMNode* node) const {
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+ short
+#else
+ FilterAction
+#endif
+ acceptNode(const DOMNode* node) const {
return FILTER_REJECT;
}
};
m_uri += slash;
break;
}
- else if (*slash == ';') {
- // If this is Java being stupid, skip everything up to the query string, if any.
- if (!strncmp(slash, ";jsessionid=", 12)) {
- if (slash = strchr(slash, '?'))
- m_uri += slash;
- break;
- }
- else {
- m_uri += *slash;
- }
- }
else if (*slash != '%') {
m_uri += *slash;
}
{
if (!m_parser)
m_parser=new CGIParser(*this);
-
+
pair<CGIParser::walker,CGIParser::walker> bounds=m_parser->getParameters(name);
return (bounds.first==bounds.second) ? NULL : bounds.first->second;
}
#ifndef XMLTOOLING_NO_XMLSEC
std::vector<XSECCryptoX509*>&
#else
- std::vector<std::string>&
+ std::vector<std::string>&
#endif
getClientCertificates() const {
return g_NoCerts;
if (!m_acl.empty() && m_acl.count(request.getRemoteAddr()) == 0) {
m_log.error("status handler request blocked from invalid address (%s)", request.getRemoteAddr().c_str());
istringstream msg("Status Handler Blocked");
- return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_UNAUTHORIZED));
+ return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN));
}
}
msg << "</StatusHandler>";
return make_pair(true,request.sendResponse(msg));
}
-
+
try {
if (conf.isEnabled(SPConfig::OutOfProcess)) {
// When out of process, we run natively and directly process the message.
else {
// When not out of process, we remote all the message processing.
DDF out,in = wrap(request);
- DDFJanitor jin(in), jout(out);
+ DDFJanitor jin(in), jout(out);
out=request.getServiceProvider().getListenerService()->send(in);
return unwrap(request, out);
}
m_log.error("couldn't find application (%s) for status request", aid ? aid : "(missing)");
throw ConfigurationException("Unable to locate application for status request, deleted?");
}
-
+
// Wrap a response shim.
DDF ret(NULL);
DDFJanitor jout(ret);
auto_ptr<HTTPRequest> req(getRequest(in));
auto_ptr<HTTPResponse> resp(getResponse(ret));
-
+
// Since we're remoted, the result should either be a throw, a false/0 return,
// which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
class SHIBSP_DLLLOCAL TransformSINodeFilter : public DOMNodeFilter
{
public:
- short acceptNode(const DOMNode* node) const {
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+ short
+#else
+ FilterAction
+#endif
+ acceptNode(const DOMNode* node) const {
return FILTER_REJECT;
}
};
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return make_pair(false,0L);
string target;
+ string postData;
const char* option;
const Handler* ACS=NULL;
const Application& app=request.getApplication();
ACS = app.getDefaultAssertionConsumerService();
}
+ // Validate the ACS for use with this protocol.
+ pair<bool,const char*> ACSbinding = ACS ? ACS->getString("Binding") : pair<bool,const char*>(false,NULL);
+ if (ACSbinding.first) {
+ pair<bool,const char*> compatibleBindings = getString("compatibleBindings");
+ if (compatibleBindings.first && strstr(compatibleBindings.second, ACSbinding.second) == NULL) {
+ m_log.info("configured or requested ACS has non-SAML 1.x binding");
+ return make_pair(false,0L);
+ }
+ else if (strcmp(ACSbinding.second, samlconstants::SAML1_PROFILE_BROWSER_POST) &&
+ strcmp(ACSbinding.second, samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT)) {
+ m_log.info("configured or requested ACS has non-SAML 1.x binding");
+ return make_pair(false,0L);
+ }
+ }
+
m_log.debug("sending request to WAYF (%s)", m_url);
// Compute the ACS URL. We add the ACS location to the base handlerURL.
target = option;
}
preserveRelayState(request.getApplication(), request, target);
+ if (!isHandler)
+ preservePostData(request.getApplication(), request, request, target.c_str());
// WAYF requires a target value.
if (target.empty())
--- /dev/null
+/*\r
+ * Copyright 2009 Internet2\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * ChainingAccessControl.cpp\r
+ *\r
+ * Access control plugin that combines other plugins.\r
+ */\r
+\r
+#include "internal.h"\r
+#include "exceptions.h"\r
+#include "AccessControl.h"\r
+#include "SessionCache.h"\r
+#include "SPRequest.h"\r
+\r
+#include <xmltooling/util/XMLHelper.h>\r
+#include <xercesc/util/XMLUniDefs.hpp>\r
+\r
+using namespace shibsp;\r
+using namespace xmltooling;\r
+using namespace std;\r
+\r
+namespace shibsp {\r
+\r
+ class ChainingAccessControl : public AccessControl\r
+ {\r
+ public:\r
+ ChainingAccessControl(const DOMElement* e);\r
+\r
+ ~ChainingAccessControl() {\r
+ for_each(m_ac.begin(), m_ac.end(), xmltooling::cleanup<AccessControl>());\r
+ }\r
+\r
+ Lockable* lock() {\r
+ for_each(m_ac.begin(), m_ac.end(), mem_fun<Lockable*,Lockable>(&Lockable::lock));\r
+ return this;\r
+ }\r
+ void unlock() {\r
+ for_each(m_ac.begin(), m_ac.end(), mem_fun<void,Lockable>(&Lockable::unlock));\r
+ }\r
+\r
+ aclresult_t authorized(const SPRequest& request, const Session* session) const;\r
+\r
+ private:\r
+ enum operator_t { OP_AND, OP_OR } m_op;\r
+ vector<AccessControl*> m_ac;\r
+ };\r
+\r
+ AccessControl* SHIBSP_DLLLOCAL ChainingAccessControlFactory(const DOMElement* const & e)\r
+ {\r
+ return new ChainingAccessControl(e);\r
+ }\r
+\r
+ static const XMLCh _AccessControl[] = UNICODE_LITERAL_13(A,c,c,e,s,s,C,o,n,t,r,o,l);\r
+ static const XMLCh _operator[] = UNICODE_LITERAL_8(o,p,e,r,a,t,o,r);\r
+ static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);\r
+ static const XMLCh AND[] = UNICODE_LITERAL_3(A,N,D);\r
+ static const XMLCh OR[] = UNICODE_LITERAL_2(O,R);\r
+\r
+ extern AccessControl* SHIBSP_DLLLOCAL XMLAccessControlFactory(const DOMElement* const & e);\r
+}\r
+\r
+void SHIBSP_API shibsp::registerAccessControls()\r
+{\r
+ SPConfig& conf=SPConfig::getConfig();\r
+ conf.AccessControlManager.registerFactory(CHAINING_ACCESS_CONTROL, ChainingAccessControlFactory);\r
+ conf.AccessControlManager.registerFactory(XML_ACCESS_CONTROL, XMLAccessControlFactory);\r
+ conf.AccessControlManager.registerFactory("edu.internet2.middleware.shibboleth.sp.provider.XMLAccessControl", XMLAccessControlFactory);\r
+}\r
+\r
+ChainingAccessControl::ChainingAccessControl(const DOMElement* e)\r
+{\r
+ const XMLCh* op = e ? e->getAttributeNS(NULL, _operator) : NULL;\r
+ if (XMLString::equals(op, AND))\r
+ m_op=OP_AND;\r
+ else if (XMLString::equals(op, OR))\r
+ m_op=OP_OR;\r
+ else\r
+ throw ConfigurationException("Missing or unrecognized operator in Chaining AccessControl configuration.");\r
+\r
+ try {\r
+ e = e ? XMLHelper::getFirstChildElement(e, _AccessControl) : NULL;\r
+ while (e) {\r
+ auto_ptr_char type(e->getAttributeNS(NULL, _type));\r
+ if (type.get() && *type.get()) {\r
+ Category::getInstance(SHIBSP_LOGCAT".AccessControl.Chaining").info("building AccessControl provider of type (%s)...", type.get());\r
+ m_ac.push_back(SPConfig::getConfig().AccessControlManager.newPlugin(type.get(), e));\r
+ }\r
+ e = XMLHelper::getNextSiblingElement(e, _AccessControl);\r
+ }\r
+ }\r
+ catch (exception&) {\r
+ for_each(m_ac.begin(), m_ac.end(), xmltooling::cleanup<AccessControl>());\r
+ throw;\r
+ }\r
+ if (m_ac.empty())\r
+ throw ConfigurationException("Chaining AccessControl plugin requires at least one child plugin.");\r
+}\r
+\r
+AccessControl::aclresult_t ChainingAccessControl::authorized(const SPRequest& request, const Session* session) const\r
+{\r
+ switch (m_op) {\r
+ case OP_AND:\r
+ {\r
+ for (vector<AccessControl*>::const_iterator i=m_ac.begin(); i!=m_ac.end(); ++i) {\r
+ if ((*i)->authorized(request, session) != shib_acl_true)\r
+ return shib_acl_false;\r
+ }\r
+ return shib_acl_true;\r
+ }\r
+\r
+ case OP_OR:\r
+ {\r
+ for (vector<AccessControl*>::const_iterator i=m_ac.begin(); i!=m_ac.end(); ++i) {\r
+ if ((*i)->authorized(request,session) == shib_acl_true)\r
+ return shib_acl_true;\r
+ }\r
+ return shib_acl_false;\r
+ }\r
+ }\r
+ request.log(SPRequest::SPWarn, "unknown operation in access control policy, denying access");\r
+ return shib_acl_false;\r
+}\r
}
else {
// New record.
- obj.structure();
+ obj = DDF(NULL).structure();
}
if (!index || !*index)
/*\r
* Copyright 2001-2007 Internet2\r
- * \r
+ *\r
* Licensed under the Apache License, Version 2.0 (the "License");\r
* you may not use this file except in compliance with the License.\r
* You may obtain a copy of the License at\r
using namespace xmltooling;\r
using namespace std;\r
\r
-namespace {\r
- \r
+namespace shibsp {\r
+\r
class Rule : public AccessControl\r
{\r
public:\r
void unlock() {}\r
\r
aclresult_t authorized(const SPRequest& request, const Session* session) const;\r
- \r
+\r
private:\r
string m_alias;\r
vector <string> m_vals;\r
};\r
- \r
+\r
class RuleRegex : public AccessControl\r
{\r
public:\r
~RuleRegex() {\r
delete m_re;\r
}\r
- \r
+\r
Lockable* lock() {return this;}\r
void unlock() {}\r
\r
aclresult_t authorized(const SPRequest& request, const Session* session) const;\r
- \r
+\r
private:\r
string m_alias;\r
auto_arrayptr<char> m_exp;\r
RegularExpression* m_re;\r
};\r
- \r
+\r
class Operator : public AccessControl\r
{\r
public:\r
void unlock() {}\r
\r
aclresult_t authorized(const SPRequest& request, const Session* session) const;\r
- \r
+\r
private:\r
enum operator_t { OP_NOT, OP_AND, OP_OR } m_op;\r
vector<AccessControl*> m_operands;\r
{\r
public:\r
XMLAccessControl(const DOMElement* e)\r
- : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AccessControl")), m_rootAuthz(NULL) {\r
+ : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AccessControl.XML")), m_rootAuthz(NULL) {\r
load(); // guarantees an exception or the policy is loaded\r
}\r
- \r
+\r
~XMLAccessControl() {\r
delete m_rootAuthz;\r
}\r
static const XMLCh _RuleRegex[] = UNICODE_LITERAL_9(R,u,l,e,R,e,g,e,x);\r
}\r
\r
-void SHIBSP_API shibsp::registerAccessControls()\r
-{\r
- SPConfig& conf=SPConfig::getConfig();\r
- conf.AccessControlManager.registerFactory(XML_ACCESS_CONTROL, XMLAccessControlFactory);\r
- conf.AccessControlManager.registerFactory("edu.internet2.middleware.shibboleth.sp.provider.XMLAccessControl", XMLAccessControlFactory);\r
-}\r
-\r
Rule::Rule(const DOMElement* e)\r
{\r
auto_ptr_char req(e->getAttributeNS(NULL,require));\r
auto_arrayptr<char> vals(toUTF8(e->hasChildNodes() ? e->getFirstChild()->getNodeValue() : NULL));\r
if (!vals.get())\r
return;\r
- \r
+\r
const XMLCh* flag = e->getAttributeNS(NULL,_list);\r
if (flag && (*flag == chLatin_f || *flag == chDigit_0)) {\r
if (*vals.get())\r
m_vals.push_back(vals.get());\r
return;\r
}\r
- \r
+\r
#ifdef HAVE_STRTOK_R\r
char* pos=NULL;\r
const char* token=strtok_r(const_cast<char*>(vals.get())," ",&pos);\r
request.log(SPRequest::SPWarn, "AccessControl plugin not given a valid session to evaluate, are you using lazy sessions?");\r
return shib_acl_false;\r
}\r
- \r
+\r
if (m_alias == "valid-user") {\r
if (session) {\r
request.log(SPRequest::SPDebug,"AccessControl plugin accepting valid-user based on active session");\r
if (!req.get() || !*req.get() || !m_exp.get() || !*m_exp.get())\r
throw ConfigurationException("Access control rule missing require attribute or element content.");\r
m_alias=req.get();\r
- \r
+\r
const XMLCh* flag = e->getAttributeNS(NULL,ignoreCase);\r
bool ignore = (flag && (*flag == chLatin_t || *flag == chDigit_1));\r
try {\r
- m_re = new RegularExpression(e->getFirstChild()->getNodeValue(), (ignore ? ignoreOption : &chNull)); \r
+ m_re = new RegularExpression(e->getFirstChild()->getNodeValue(), (ignore ? ignoreOption : &chNull));\r
}\r
catch (XMLException& ex) {\r
auto_ptr_char tmp(ex.getMessage());\r
request.log(SPRequest::SPWarn, "AccessControl plugin not given a valid session to evaluate, are you using lazy sessions?");\r
return shib_acl_false;\r
}\r
- \r
+\r
if (m_alias == "valid-user") {\r
if (session) {\r
request.log(SPRequest::SPDebug,"AccessControl plugin accepting valid-user based on active session");\r
auto_ptr_char tmp(ex.getMessage());\r
request.log(SPRequest::SPError, string("caught exception while parsing RuleRegex regular expression: ") + tmp.get());\r
}\r
- \r
+\r
return shib_acl_false;\r
}\r
\r
m_op=OP_OR;\r
else\r
throw ConfigurationException("Unrecognized operator in access control rule");\r
- \r
+\r
try {\r
e=XMLHelper::getFirstChildElement(e);\r
if (XMLString::equals(e->getLocalName(),_Rule))\r
m_operands.push_back(new RuleRegex(e));\r
else\r
m_operands.push_back(new Operator(e));\r
- \r
+\r
if (m_op==OP_NOT)\r
return;\r
- \r
+\r
e=XMLHelper::getNextSiblingElement(e);\r
while (e) {\r
if (XMLString::equals(e->getLocalName(),_Rule))\r
default:\r
return shib_acl_indeterminate;\r
}\r
- \r
+\r
case OP_AND:\r
{\r
for (vector<AccessControl*>::const_iterator i=m_operands.begin(); i!=m_operands.end(); i++) {\r
}\r
return shib_acl_true;\r
}\r
- \r
+\r
case OP_OR:\r
{\r
for (vector<AccessControl*>::const_iterator i=m_operands.begin(); i!=m_operands.end(); i++) {\r
{\r
// Load from source using base class.\r
pair<bool,DOMElement*> raw = ReloadableXMLFile::load();\r
- \r
+\r
// If we own it, wrap it.\r
XercesJanitor<DOMDocument> docjanitor(raw.first ? raw.second->getOwnerDocument() : NULL);\r
\r
// Check for AccessControl wrapper and drop a level.\r
if (XMLString::equals(raw.second->getLocalName(),_AccessControl))\r
raw.second = XMLHelper::getFirstChildElement(raw.second);\r
- \r
+\r
AccessControl* authz;\r
if (XMLString::equals(raw.second->getLocalName(),_Rule))\r
authz=new Rule(raw.second);\r
/*
* Copyright 2001-2007 Internet2
- *
+ *
* 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
*/
/** XMLRequestMapper.cpp
- *
+ *
* XML-based RequestMapper implementation
*/
namespace shibsp {
- // Blocks access when an ACL plugin fails to load.
+ // Blocks access when an ACL plugin fails to load.
class AccessControlDummy : public AccessControl
{
public:
Lockable* lock() {
return this;
}
-
+
void unlock() {}
-
+
aclresult_t authorized(const SPRequest& request, const Session* session) const {
return shib_acl_false;
}
~Override();
// Provides filter to exclude special config elements.
- short acceptNode(const DOMNode* node) const {
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+ short
+#else
+ FilterAction
+#endif
+ acceptNode(const DOMNode* node) const {
return FILTER_REJECT;
}
const Override* locate(const HTTPRequest& request) const;
AccessControl* getAC() const { return (m_acl ? m_acl : (getParent() ? dynamic_cast<const Override*>(getParent())->getAC() : NULL)); }
-
+
protected:
void loadACL(const DOMElement* e, Category& log);
-
+
map<string,Override*> m_map;
vector< pair<RegularExpression*,Override*> > m_regexps;
vector< pair< pair<string,RegularExpression*>,Override*> > m_queries;
-
+
private:
AccessControl* m_acl;
};
void setDocument(DOMDocument* doc) {
m_document = doc;
}
-
+
const Override* findOverride(const char* vhost, const HTTPRequest& request) const;
- private:
+ private:
map<string,Override*> m_extras;
DOMDocument* m_document;
};
// Load the property set.
load(e,NULL,this);
setParent(base);
-
+
// Load any AccessControl provider.
loadACL(e,log);
-
+
// Handle nested Paths.
DOMElement* path = XMLHelper::getFirstChildElement(e,Path);
for (int i=1; path; ++i, path=XMLHelper::getNextSiblingElement(path,Path)) {
const XMLCh* n=path->getAttributeNS(NULL,name);
-
+
// Skip any leading slashes.
while (n && *n==chForwardSlash)
n++;
-
+
// Check for empty name.
if (!n || !*n) {
log.warn("skipping Path element (%d) with empty name attribute", i);
for (int pos=0; pos < slash; pos++)
namebuf[pos]=n[pos];
namebuf[slash]=chNull;
-
+
// Move past the slash in the original pathname.
n=n+slash+1;
-
+
// Skip any leading slashes again.
while (*n==chForwardSlash)
n++;
-
+
if (*n) {
// Create a placeholder Path element for the first path segment and replant under it.
DOMElement* newpath=path->getOwnerDocument()->createElementNS(shibspconstants::SHIB2SPCONFIG_NS,Path);
path->setAttributeNS(NULL,name,n);
path->getParentNode()->replaceChild(newpath,path);
newpath->appendChild(path);
-
+
// Repoint our locals at the new parent.
path=newpath;
n=path->getAttributeNS(NULL,name);
}
delete[] namebuf;
}
-
+
Override* o=new Override(path,log,this);
pair<bool,const char*> name=o->getString("name");
char* dup=strdup(name.second);
log.error("caught exception while parsing Query regular expression (%d): %s", i, tmp.get());
throw ConfigurationException("Invalid regular expression in Query element.");
}
-
+
log.debug("added <Query> mapping (%s)", ntemp.get());
}
}
break; // Once there's no match, we've consumed as much of the path as possible here.
// We found a match, so reset the settings pointer.
o=i->second;
-
+
// We descended a step down the path, so we need to advance the original
// parameter for the regex step later.
path += strlen(token);
// Load the property set.
load(e,NULL,this);
-
+
// Load any AccessControl provider.
loadACL(e,log);
log.warn("Skipping Host element (%d) with empty name attribute",i);
continue;
}
-
+
Override* o=new Override(host,log,this);
pair<bool,const char*> name=o->getString("name");
pair<bool,const char*> scheme=o->getString("scheme");
pair<bool,const char*> port=o->getString("port");
-
+
char* dup=strdup(name.second);
for (char* pch=dup; *pch; pch++)
*pch=tolower(*pch);
if (scheme.first) {
string url(scheme.second);
url=url + "://" + dup;
-
+
// Is this the default port?
if ((!strcmp(scheme.second,"http") && !strcmp(port.second,"80")) ||
(!strcmp(scheme.second,"https") && !strcmp(port.second,"443")) ||
}
m_map[url]=o;
log.debug("Added <Host> mapping for %s",url.c_str());
-
+
// Now append the port. We use the extras vector, to avoid double freeing the object later.
url=url + ':' + port.second;
m_extras[url]=o;
}
m_map[url]=o;
log.debug("Added <Host> mapping for %s",url.c_str());
-
+
url = url + ":80";
if (m_map.count(url) || m_extras.count(url)) {
log.warn("Skipping duplicate Host element (%s)",url.c_str());
}
m_extras[url]=o;
log.debug("Added <Host> mapping for %s",url.c_str());
-
+
url = "https://";
url = url + dup;
if (m_map.count(url) || m_extras.count(url)) {
}
m_extras[url]=o;
log.debug("Added <Host> mapping for %s",url.c_str());
-
+
url = url + ":443";
if (m_map.count(url) || m_extras.count(url)) {
log.warn("Skipping duplicate Host element (%s)",url.c_str());
}
}
}
-
+
return o ? o->locate(request) : this;
}
{
// Load from source using base class.
pair<bool,DOMElement*> raw = ReloadableXMLFile::load();
-
+
// If we own it, wrap it.
XercesJanitor<DOMDocument> docjanitor(raw.first ? raw.second->getOwnerDocument() : NULL);
XMLRequestMapperImpl* impl = new XMLRequestMapperImpl(raw.second,m_log);
-
+
// If we held the document, transfer it to the impl. If we didn't, it's a no-op.
impl->setDocument(docjanitor.release());
{
ostringstream vhost;
vhost << request.getScheme() << "://" << request.getHostname() << ':' << request.getPort();
-
const Override* o=m_impl->findOverride(vhost.str().c_str(), request);
-
- if (m_log.isDebugEnabled()) {
-#ifdef _DEBUG
- xmltooling::NDC ndc("getSettings");
-#endif
- pair<bool,const char*> ret=o->getString("applicationId");
- m_log.debug("mapped %s%s to %s", vhost.str().c_str(), request.getRequestURI() ? request.getRequestURI() : "", ret.second);
- }
-
return Settings(o,o->getAC());
}
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
#include "internal.h"
#include "exceptions.h"
+#include "version.h"
#include "AccessControl.h"
#include "Application.h"
#include "RequestMapper.h"
#include "ServiceProvider.h"
#include "SessionCache.h"
#include "SPConfig.h"
+#include "SPRequest.h"
#include "handler/SessionInitiator.h"
#include "remoting/ListenerService.h"
#include "util/DOMPropertySet.h"
#endif
#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/XMLToolingConfig.h>
+#include <xmltooling/version.h>
#include <xmltooling/util/NDC.h>
#include <xmltooling/util/ReloadableXMLFile.h>
+#include <xmltooling/util/TemplateEngine.h>
#include <xmltooling/util/XMLHelper.h>
#ifndef SHIBSP_LITE
# include "attribute/resolver/AttributeResolver.h"
# include "security/PKIXTrustEngine.h"
# include <saml/SAMLConfig.h>
+# include <saml/version.h>
# include <saml/binding/ArtifactMap.h>
# include <saml/binding/SAMLArtifact.h>
# include <saml/saml1/core/Assertions.h>
# include <saml/saml2/binding/SAML2ArtifactType0004.h>
-# include <saml/saml2/metadata/ChainingMetadataProvider.h>
-# include <xmltooling/security/ChainingTrustEngine.h>
# include <xmltooling/util/ReplayCache.h>
using namespace opensaml::saml2;
using namespace opensaml::saml2p;
using namespace xmltooling;
using namespace std;
+#ifndef min
+# define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
namespace {
#if defined (_MSC_VER)
public:
XMLApplication(const ServiceProvider*, const DOMElement* e, const XMLApplication* base=NULL);
~XMLApplication() { cleanup(); }
-
+
const char* getHash() const {return m_hash.c_str();}
#ifndef SHIBSP_LITE
return (m_remoteUsers.empty() && m_base) ? m_base->getRemoteUserAttributeIds() : m_remoteUsers;
}
+ void clearHeader(SPRequest& request, const char* rawname, const char* cginame) const;
+ void setHeader(SPRequest& request, const char* name, const char* value) const;
+ string getSecureHeader(const SPRequest& request, const char* name) const;
+
const SessionInitiator* getDefaultSessionInitiator() const;
const SessionInitiator* getSessionInitiatorById(const char* id) const;
const Handler* getDefaultAssertionConsumerService() const;
}
// Provides filter to exclude special config elements.
- short acceptNode(const DOMNode* node) const;
-
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+ short
+#else
+ FilterAction
+#endif
+ acceptNode(const DOMNode* node) const;
+
private:
void cleanup();
const XMLApplication* m_base;
string m_hash;
+ std::pair<std::string,std::string> m_attributePrefix;
#ifndef SHIBSP_LITE
MetadataProvider* m_metadata;
TrustEngine* m_trust;
vector<const XMLCh*> m_audiences;
// RelyingParty properties
-#ifdef HAVE_GOOD_STL
map<xstring,PropertySet*> m_partyMap;
-#else
- map<const XMLCh*,PropertySet*> m_partyMap;
-#endif
#endif
vector<string> m_remoteUsers,m_frontLogout,m_backLogout;
// maps unique indexes to consumer services
map<unsigned int,const Handler*> m_acsIndexMap;
-
+
// pointer to default consumer service
const Handler* m_acsDefault;
// maps binding strings to supporting consumer service(s)
-#ifdef HAVE_GOOD_STL
typedef map<xstring,vector<const Handler*> > ACSBindingMap;
-#else
- typedef map<string,vector<const Handler*> > ACSBindingMap;
-#endif
ACSBindingMap m_acsBindingMap;
// pointer to default session initiator
public:
XMLConfigImpl(const DOMElement* e, bool first, const XMLConfig* outer, Category& log);
~XMLConfigImpl();
-
+
RequestMapper* m_requestMapper;
map<string,Application*> m_appmap;
#ifndef SHIBSP_LITE
map< string,pair< PropertySet*,vector<const SecurityPolicyRule*> > > m_policyMap;
vector< pair< string, pair<string,string> > > m_transportOptions;
#endif
-
+
// Provides filter to exclude special config elements.
- short acceptNode(const DOMNode* node) const;
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+ short
+#else
+ FilterAction
+#endif
+ acceptNode(const DOMNode* node) const;
void setDocument(DOMDocument* doc) {
m_document = doc;
#endif
{
}
-
+
void init() {
load();
}
static const XMLCh OutOfProcess[] = UNICODE_LITERAL_12(O,u,t,O,f,P,r,o,c,e,s,s);
static const XMLCh _path[] = UNICODE_LITERAL_4(p,a,t,h);
static const XMLCh Policy[] = UNICODE_LITERAL_6(P,o,l,i,c,y);
+ static const XMLCh PolicyRule[] = UNICODE_LITERAL_10(P,o,l,i,c,y,R,u,l,e);
static const XMLCh _provider[] = UNICODE_LITERAL_8(p,r,o,v,i,d,e,r);
static const XMLCh RelyingParty[] = UNICODE_LITERAL_12(R,e,l,y,i,n,g,P,a,r,t,y);
static const XMLCh _ReplayCache[] = UNICODE_LITERAL_11(R,e,p,l,a,y,C,a,c,h,e);
class SHIBSP_DLLLOCAL PolicyNodeFilter : public DOMNodeFilter
{
public:
- short acceptNode(const DOMNode* node) const {
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+ short
+#else
+ FilterAction
+#endif
+ acceptNode(const DOMNode* node) const {
return FILTER_REJECT;
}
};
m_hash += (DIGITS[0x0F & *ch]);
}
+ // Populate prefix pair.
+ m_attributePrefix.second = "HTTP_";
+ pair<bool,const char*> prefix = getString("attributePrefix");
+ if (prefix.first) {
+ m_attributePrefix.first = prefix.second;
+ const char* pch = prefix.second;
+ while (*pch) {
+ m_attributePrefix.second += (isalnum(*pch) ? toupper(*pch) : '_');
+ pch++;
+ }
+ }
+
// Load attribute ID lists for REMOTE_USER and header clearing.
if (conf.isEnabled(SPConfig::InProcess)) {
pair<bool,const char*> attributes = getString("REMOTE_USER");
attributes = getString("unsetHeaders");
if (attributes.first) {
- string transformedprefix("HTTP_");
+ string transformedprefix(m_attributePrefix.second);
const char* pch;
- pair<bool,const char*> prefix = getString("metadataAttributePrefix");
+ prefix = getString("metadataAttributePrefix");
if (prefix.first) {
pch = prefix.second;
while (*pch) {
transformed += (isalnum(*pch) ? toupper(*pch) : '_');
pch++;
}
- m_unsetHeaders.push_back(pair<string,string>(start,string("HTTP_") + transformed));
+
+ m_unsetHeaders.push_back(pair<string,string>(m_attributePrefix.first + start, m_attributePrefix.second + transformed));
if (prefix.first)
- m_unsetHeaders.push_back(pair<string,string>(string(prefix.second) + start, transformedprefix + transformed));
+ m_unsetHeaders.push_back(pair<string,string>(m_attributePrefix.first + prefix.second + start, transformedprefix + transformed));
start = pos ? pos+1 : NULL;
}
free(dup);
- m_unsetHeaders.push_back(pair<string,string>("Shib-Application-ID","HTTP_SHIB_APPLICATION_ID"));
+ m_unsetHeaders.push_back(pair<string,string>(m_attributePrefix.first + "Shib-Application-ID", m_attributePrefix.second + "SHIB_APPLICATION_ID"));
}
}
}
handler=conf.AssertionConsumerServiceManager.newPlugin(bindprop.get(),make_pair(child, getId()));
// Map by binding (may be > 1 per binding, e.g. SAML 1.0 vs 1.1)
-#ifdef HAVE_GOOD_STL
m_acsBindingMap[handler->getXMLString("Binding").second].push_back(handler);
-#else
- m_acsBindingMap[handler->getString("Binding").second].push_back(handler);
-#endif
m_acsIndexMap[handler->getUnsignedInt("index").second]=handler;
-
+
if (!hardACS) {
pair<bool,bool> defprop=handler->getBool("isDefault");
if (defprop.first) {
continue;
}
handler=conf.ArtifactResolutionServiceManager.newPlugin(bindprop.get(),make_pair(child, getId()));
-
+
if (!hardArt) {
pair<bool,bool> defprop=handler->getBool("isDefault");
if (defprop.first) {
catch (exception& ex) {
log.error("caught exception processing handler element: %s", ex.what());
}
-
+
child = XMLHelper::getNextSiblingElement(child);
}
#ifndef SHIBSP_LITE
nlist=e->getElementsByTagNameNS(samlconstants::SAML20_NS,Audience::LOCAL_NAME);
- for (XMLSize_t i=0; nlist && i<nlist->getLength(); i++)
- if (nlist->item(i)->getParentNode()->isSameNode(e) && nlist->item(i)->hasChildNodes())
- m_audiences.push_back(nlist->item(i)->getFirstChild()->getNodeValue());
+ if (nlist && nlist->getLength()) {
+ log.warn("use of <saml:Audience> elements outside of a Security Policy Rule is deprecated");
+ for (XMLSize_t i=0; i<nlist->getLength(); i++)
+ if (nlist->item(i)->getParentNode()->isSameNode(e) && nlist->item(i)->hasChildNodes())
+ m_audiences.push_back(nlist->item(i)->getFirstChild()->getNodeValue());
+ }
if (conf.isEnabled(SPConfig::Metadata)) {
child = XMLHelper::getFirstChildElement(e,_MetadataProvider);
Locker extlock(m_attrExtractor);
m_attrExtractor->getAttributeIds(unsetHeaders);
}
+ else if (m_base && m_base->m_attrExtractor) {
+ Locker extlock(m_base->m_attrExtractor);
+ m_base->m_attrExtractor->getAttributeIds(unsetHeaders);
+ }
if (m_attrResolver) {
Locker reslock(m_attrResolver);
m_attrResolver->getAttributeIds(unsetHeaders);
}
- if (unsetHeaders.empty()) {
- if (m_base)
- m_unsetHeaders.insert(m_unsetHeaders.end(), m_base->m_unsetHeaders.begin(), m_base->m_unsetHeaders.end());
- else
- m_unsetHeaders.push_back(pair<string,string>("Shib-Application-ID","HTTP_SHIB_APPLICATION_ID"));
+ else if (m_base && m_base->m_attrResolver) {
+ Locker extlock(m_base->m_attrResolver);
+ m_base->m_attrResolver->getAttributeIds(unsetHeaders);
}
- else {
- string transformedprefix("HTTP_");
+ if (!unsetHeaders.empty()) {
+ string transformedprefix(m_attributePrefix.second);
const char* pch;
pair<bool,const char*> prefix = getString("metadataAttributePrefix");
if (prefix.first) {
transformed += (isalnum(*pch) ? toupper(*pch) : '_');
pch++;
}
- m_unsetHeaders.push_back(pair<string,string>(*hdr, string("HTTP_") + transformed));
+ m_unsetHeaders.push_back(pair<string,string>(m_attributePrefix.first + *hdr, m_attributePrefix.second + transformed));
if (prefix.first)
- m_unsetHeaders.push_back(pair<string,string>(string(prefix.second) + *hdr, transformedprefix + transformed));
+ m_unsetHeaders.push_back(pair<string,string>(m_attributePrefix.first + prefix.second + *hdr, transformedprefix + transformed));
}
- m_unsetHeaders.push_back(pair<string,string>("Shib-Application-ID","HTTP_SHIB_APPLICATION_ID"));
}
+ m_unsetHeaders.push_back(pair<string,string>(m_attributePrefix.first + "Shib-Application-ID", m_attributePrefix.second + "SHIB_APPLICATION_ID"));
}
}
for_each(m_handlers.begin(),m_handlers.end(),xmltooling::cleanup<Handler>());
m_handlers.clear();
#ifndef SHIBSP_LITE
-#ifdef HAVE_GOOD_STL
for_each(m_partyMap.begin(),m_partyMap.end(),cleanup_pair<xstring,PropertySet>());
-#else
- for_each(m_partyMap.begin(),m_partyMap.end(),cleanup_pair<const XMLCh*,PropertySet>());
-#endif
m_partyMap.clear();
delete m_credResolver;
m_credResolver = NULL;
#endif
}
-short XMLApplication::acceptNode(const DOMNode* node) const
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+short
+#else
+DOMNodeFilter::FilterAction
+#endif
+XMLApplication::acceptNode(const DOMNode* node) const
{
const XMLCh* name=node->getLocalName();
if (XMLString::equals(name,ApplicationOverride) ||
{
if (!provider)
return this;
-
-#ifdef HAVE_GOOD_STL
+
map<xstring,PropertySet*>::const_iterator i=m_partyMap.find(provider->getEntityID());
if (i!=m_partyMap.end())
return i->second;
}
group=dynamic_cast<const EntitiesDescriptor*>(group->getParent());
}
-#else
- map<const XMLCh*,PropertySet*>::const_iterator i=m_partyMap.begin();
- for (; i!=m_partyMap.end(); i++) {
- if (XMLString::equals(i->first,provider->getEntityID()))
- return i->second;
- const EntitiesDescriptor* group=dynamic_cast<const EntitiesDescriptor*>(provider->getParent());
- while (group) {
- if (XMLString::equals(i->first,group->getName()))
- return i->second;
- group=dynamic_cast<const EntitiesDescriptor*>(group->getParent());
- }
- }
-#endif
return this;
}
{
if (!entityID)
return this;
-
-#ifdef HAVE_GOOD_STL
+
map<xstring,PropertySet*>::const_iterator i=m_partyMap.find(entityID);
if (i!=m_partyMap.end())
return i->second;
-#else
- map<const XMLCh*,PropertySet*>::const_iterator i=m_partyMap.begin();
- for (; i!=m_partyMap.end(); i++) {
- if (XMLString::equals(i->first,entityID))
- return i->second;
- }
-#endif
return this;
}
throw ConfigurationException("Request URL was not absolute.");
const char* handler=locs[index].c_str();
-
+
// Should never happen...
if (!handler || (*handler!='/' && strncmp(handler,"http:",5) && strncmp(handler,"https:",6)))
throw ConfigurationException(
return notifyURL;
}
+void XMLApplication::clearHeader(SPRequest& request, const char* rawname, const char* cginame) const
+{
+ if (!m_attributePrefix.first.empty()) {
+ string temp = m_attributePrefix.first + rawname;
+ string temp2 = m_attributePrefix.second + (cginame + 5);
+ request.clearHeader(temp.c_str(), temp2.c_str());
+ }
+ else if (m_base) {
+ m_base->clearHeader(request, rawname, cginame);
+ }
+ else {
+ request.clearHeader(rawname, cginame);
+ }
+}
+
+void XMLApplication::setHeader(SPRequest& request, const char* name, const char* value) const
+{
+ if (!m_attributePrefix.first.empty()) {
+ string temp = m_attributePrefix.first + name;
+ request.setHeader(temp.c_str(), value);
+ }
+ else if (m_base) {
+ m_base->setHeader(request, name, value);
+ }
+ else {
+ request.setHeader(name, value);
+ }
+}
+
+string XMLApplication::getSecureHeader(const SPRequest& request, const char* name) const
+{
+ if (!m_attributePrefix.first.empty()) {
+ string temp = m_attributePrefix.first + name;
+ return request.getSecureHeader(temp.c_str());
+ }
+ else if (m_base) {
+ return m_base->getSecureHeader(request,name);
+ }
+ else {
+ return request.getSecureHeader(name);
+ }
+}
+
const SessionInitiator* XMLApplication::getDefaultSessionInitiator() const
{
if (m_sessionInitDefault) return m_sessionInitDefault;
const vector<const Handler*>& XMLApplication::getAssertionConsumerServicesByBinding(const XMLCh* binding) const
{
-#ifdef HAVE_GOOD_STL
ACSBindingMap::const_iterator i=m_acsBindingMap.find(binding);
-#else
- auto_ptr_char temp(binding);
- ACSBindingMap::const_iterator i=m_acsBindingMap.find(temp.get());
-#endif
if (i!=m_acsBindingMap.end())
return i->second;
return m_base ? m_base->getAssertionConsumerServicesByBinding(binding) : g_noHandlers;
const Handler* XMLApplication::getHandler(const char* path) const
{
string wrap(path);
+ wrap = wrap.substr(0,wrap.find(';'));
map<string,const Handler*>::const_iterator i=m_handlerMap.find(wrap.substr(0,wrap.find('?')));
if (i!=m_handlerMap.end())
return i->second;
}
}
-short XMLConfigImpl::acceptNode(const DOMNode* node) const
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
+short
+#else
+DOMNodeFilter::FilterAction
+#endif
+XMLConfigImpl::acceptNode(const DOMNode* node) const
{
if (!XMLString::equals(node->getNamespaceURI(),shibspconstants::SHIB2SPCONFIG_NS))
return FILTER_ACCEPT;
auto_ptr_char path(exts->getAttributeNS(NULL,_path));
try {
if (path.get()) {
- XMLToolingConfig::getConfig().load_library(path.get(),(void*)exts);
+ if (!XMLToolingConfig::getConfig().load_library(path.get(),(void*)exts))
+ throw ConfigurationException("XMLToolingConfig::load_library failed.");
log.debug("loaded %s extension library (%s)", label, path.get());
}
}
if (logconf && *logconf) {
auto_ptr_char logpath(logconf);
log.debug("loading new logging configuration from (%s), check log destination for status of configuration",logpath.get());
- XMLToolingConfig::getConfig().log_config(logpath.get());
+ if (!XMLToolingConfig::getConfig().log_config(logpath.get()))
+ log.crit("failed to load new logging configuration from (%s)", logpath.get());
}
-
+
#ifndef SHIBSP_LITE
if (first)
m_outer->m_tranLog = new TransactionLog();
#endif
}
-
+
+ // Re-log library versions now that logging is set up.
+#ifndef SHIBSP_LITE
+ log.info(
+ "Library versions: Xerces-C %s, XML-Security-C %s, XMLTooling-C %s, OpenSAML-C %s, Shibboleth %s",
+ XERCES_FULLVERSIONDOT, XSEC_FULLVERSIONDOT, XMLTOOLING_FULLVERSIONDOT, OPENSAML_FULLVERSIONDOT, SHIBSP_FULLVERSIONDOT
+ );
+#else
+ log.info(
+ "Library versions: Xerces-C %s, XMLTooling-C %s, Shibboleth %s",
+ XERCES_FULLVERSIONDOT, XMLTOOLING_FULLVERSIONDOT, SHIBSP_FULLVERSIONDOT
+ );
+#endif
+
// First load any property sets.
load(e,NULL,this);
// Set clock skew.
pair<bool,unsigned int> skew=getUnsignedInt("clockSkew");
if (skew.first)
- xmlConf.clock_skew_secs=skew.second;
+ xmlConf.clock_skew_secs=min(skew.second,(60*60*24*7*28));
+
+ pair<bool,const char*> unsafe = getString("unsafeChars");
+ if (unsafe.first)
+ TemplateEngine::unsafe_chars = unsafe.second;
// Extensions
doExtensions(e, "global", log);
if (conf.isEnabled(SPConfig::InProcess))
doExtensions(SHIRE, "in process", log);
-
+
// Instantiate the ListenerService and SessionCache objects.
if (conf.isEnabled(SPConfig::Listener)) {
child=XMLHelper::getFirstChildElement(e,UnixListener);
#ifndef SHIBSP_LITE
if (m_outer->m_listener && conf.isEnabled(SPConfig::OutOfProcess) && !conf.isEnabled(SPConfig::InProcess)) {
- m_outer->m_listener->regListener("set::RelayState", m_outer->m_listener);
- m_outer->m_listener->regListener("get::RelayState", m_outer->m_listener);
+ m_outer->m_listener->regListener("set::RelayState", const_cast<XMLConfig*>(m_outer));
+ m_outer->m_listener->regListener("get::RelayState", const_cast<XMLConfig*>(m_outer));
+ m_outer->m_listener->regListener("set::PostData", const_cast<XMLConfig*>(m_outer));
+ m_outer->m_listener->regListener("get::PostData", const_cast<XMLConfig*>(m_outer));
}
#endif
else {
log.warn("no ReplayCache built, missing conf:ReplayCache element?");
}
-
+
// ArtifactMap
child=XMLHelper::getFirstChildElement(e,_ArtifactMap);
if (child) {
}
}
} // end of first-time-only stuff
-
+
// Back to the fully dynamic stuff...next up is the RequestMapper.
if (conf.isEnabled(SPConfig::RequestMapping)) {
child=XMLHelper::getFirstChildElement(e,_RequestMapper);
throw ConfigurationException("Can't build RequestMapper, missing conf:RequestMapper element?");
}
}
-
+
#ifndef SHIBSP_LITE
// Load security policies.
child = XMLHelper::getLastChildElement(e,SecurityPolicies);
auto_ptr<DOMPropertySet> settings(new DOMPropertySet());
settings->load(child, NULL, &filter);
rules.first = settings.release();
-
- // Process Rule elements.
- const DOMElement* rule = XMLHelper::getFirstChildElement(child,Rule);
+
+ // Process PolicyRule elements.
+ const DOMElement* rule = XMLHelper::getFirstChildElement(child,PolicyRule);
while (rule) {
auto_ptr_char type(rule->getAttributeNS(NULL,_type));
try {
catch (exception& ex) {
log.crit("error instantiating policy rule (%s) in policy (%s): %s", type.get(), id.get(), ex.what());
}
- rule = XMLHelper::getNextSiblingElement(rule,Rule);
+ rule = XMLHelper::getNextSiblingElement(rule,PolicyRule);
}
-
+
+ if (rules.second.size() == 0) {
+ // Process Rule elements.
+ log.warn("detected legacy Policy configuration, please convert to new PolicyRule syntax");
+ rule = XMLHelper::getFirstChildElement(child,Rule);
+ while (rule) {
+ auto_ptr_char type(rule->getAttributeNS(NULL,_type));
+ try {
+ rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(type.get(),rule));
+ }
+ catch (exception& ex) {
+ log.crit("error instantiating policy rule (%s) in policy (%s): %s", type.get(), id.get(), ex.what());
+ }
+ rule = XMLHelper::getNextSiblingElement(rule,Rule);
+ }
+
+ // Manually add a basic Conditions rule.
+ log.info("installing a default Conditions rule in policy (%s) for compatibility with legacy configuration", id.get());
+ rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(CONDITIONS_POLICY_RULE, NULL));
+ }
+
child = XMLHelper::getNextSiblingElement(child,Policy);
}
}
}
XMLApplication* defapp=new XMLApplication(m_outer,child);
m_appmap[defapp->getId()]=defapp;
-
+
// Load any overrides.
child = XMLHelper::getFirstChildElement(child,ApplicationOverride);
while (child) {
}
// Repack for return to caller.
- DDF ret=DDF(NULL).string(relayState.c_str());
+ DDF ret=DDF(NULL).unsafe_string(relayState.c_str());
DDFJanitor jret(ret);
out << ret;
}
DDFJanitor jret(ret);
out << ret;
}
+ else if (!strcmp(in.name(), "get::PostData")) {
+ const char* id = in["id"].string();
+ const char* key = in["key"].string();
+ if (!id || !key)
+ throw ListenerException("Required parameters missing for PostData recovery.");
+
+ string postData;
+ StorageService* storage = getStorageService(id);
+ if (storage) {
+ if (storage->readString("PostData",key,&postData) > 0) {
+ storage->deleteString("PostData",key);
+ }
+ }
+ else {
+ Category::getInstance(SHIBSP_LOGCAT".ServiceProvider").error(
+ "Storage-backed PostData with invalid StorageService ID (%s)", id
+ );
+ }
+ // If the data's empty, we'll send nothing back.
+ // If not, we don't need to round trip it, just send back the serialized DDF list.
+ if (postData.empty()) {
+ DDF ret(NULL);
+ DDFJanitor jret(ret);
+ out << ret;
+ }
+ else {
+ out << postData;
+ }
+ }
+ else if (!strcmp(in.name(), "set::PostData")) {
+ const char* id = in["id"].string();
+ if (!id || !in["parameters"].islist())
+ throw ListenerException("Required parameters missing for PostData creation.");
+
+ string rsKey;
+ StorageService* storage = getStorageService(id);
+ if (storage) {
+ SAMLConfig::getConfig().generateRandomBytes(rsKey,20);
+ rsKey = SAMLArtifact::toHex(rsKey);
+ ostringstream params;
+ params << in["parameters"];
+ storage->createString("PostData", rsKey.c_str(), params.str().c_str(), time(NULL) + 600);
+ }
+ else {
+ Category::getInstance(SHIBSP_LOGCAT".ServiceProvider").error(
+ "Storage-backed PostData with invalid StorageService ID (%s)", id
+ );
+ }
+
+ // Repack for return to caller.
+ DDF ret=DDF(NULL).string(rsKey.c_str());
+ DDFJanitor jret(ret);
+ out << ret;
+ }
}
#endif
{
// Load from source using base class.
pair<bool,DOMElement*> raw = ReloadableXMLFile::load();
-
+
// If we own it, wrap it.
XercesJanitor<DOMDocument> docjanitor(raw.first ? raw.second->getOwnerDocument() : NULL);
XMLConfigImpl* impl = new XMLConfigImpl(raw.second,(m_impl==NULL),this,m_log);
-
+
// If we held the document, transfer it to the impl. If we didn't, it's a no-op.
impl->setDocument(docjanitor.release());
/*
* Copyright 2001-2007 Internet2
- *
+ *
* 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
/**
* CommonDomainCookie.cpp
- *
- * Helper class for maintaining discovery cookie.
+ *
+ * Helper class for maintaining discovery cookie.
*/
#include "internal.h"
free(b64);
// Now Base64 decode the list.
- unsigned int len;
+ xsecsize_t len;
for (vector<string>::iterator i=templist.begin(); i!=templist.end(); ++i) {
XMLByte* decoded=Base64::decode(reinterpret_cast<const XMLByte*>(i->c_str()),&len);
if (decoded && *decoded) {
m_list.push_back(reinterpret_cast<char*>(decoded));
+#ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE
XMLString::release(&decoded);
+#else
+ XMLString::release((char**)&decoded);
+#endif
}
}
}
break;
}
}
-
+
// Append it to the end.
m_list.push_back(entityID);
-
+
// Now rebuild the delimited list.
- unsigned int len;
+ xsecsize_t len;
string delimited;
for (vector<string>::const_iterator j=m_list.begin(); j!=m_list.end(); j++) {
if (!delimited.empty()) delimited += ' ';
-
+
XMLByte* b64=Base64::encode(reinterpret_cast<const XMLByte*>(j->c_str()),j->length(),&len);
XMLByte *pos, *pos2;
for (pos=b64, pos2=b64; *pos2; pos2++)
if (isgraph(*pos2))
*pos++=*pos2;
*pos=0;
-
+
delimited += reinterpret_cast<char*>(b64);
+#ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE
XMLString::release(&b64);
+#else
+ XMLString::release((char**)&b64);
+#endif
}
-
+
m_encoded=XMLToolingConfig::getConfig().getURLEncoder()->encode(delimited.c_str());
return m_encoded.c_str();
}
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* SAMLConstants.cpp
- *
- * SAML XML namespace constants
+ *
+ * SAML XML namespace constants
*/
const XMLCh samlconstants::SAML20P_THIRDPARTY_EXT_PREFIX[] = UNICODE_LITERAL_6(t,h,r,p,t,y);
+const XMLCh samlconstants::SAML20_ATTRIBUTE_EXT_NS[] = // urn:oasis:names:tc:SAML:attribute:ext
+{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_o, chLatin_a, chLatin_s, chLatin_i, chLatin_s, chColon,
+ chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chColon, chLatin_t, chLatin_c, chColon,
+ chLatin_S, chLatin_A, chLatin_M, chLatin_L, chColon,
+ chLatin_a, chLatin_t, chLatin_t, chLatin_r, chLatin_i, chLatin_b, chLatin_u, chLatin_t, chLatin_e, chColon,
+ chLatin_e, chLatin_x, chLatin_t, chNull
+};
+
+const XMLCh samlconstants::SAML20_ATTRIBUTE_EXT_PREFIX[] = UNICODE_LITERAL_3(e,x,t);
+
+const XMLCh samlconstants::SAML20MD_ENTITY_ATTRIBUTE_NS[] = // urn:oasis:names:tc:SAML:metadata:attribute
+{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_o, chLatin_a, chLatin_s, chLatin_i, chLatin_s, chColon,
+ chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chColon, chLatin_t, chLatin_c, chColon,
+ chLatin_S, chLatin_A, chLatin_M, chLatin_L, chColon,
+ chLatin_m, chLatin_e, chLatin_t, chLatin_a, chLatin_d, chLatin_a, chLatin_t, chLatin_a, chColon,
+ chLatin_a, chLatin_t, chLatin_t, chLatin_r, chLatin_i, chLatin_b, chLatin_u, chLatin_t, chLatin_e, chNull
+};
+
+const XMLCh samlconstants::SAML20MD_ENTITY_ATTRIBUTE_PREFIX[] = UNICODE_LITERAL_6(m,d,a,t,t,r);
+
+const XMLCh samlconstants::SAML20_DELEGATION_CONDITION_NS[] = // urn:oasis:names:tc:SAML:2.0:conditions:delegation
+{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_o, chLatin_a, chLatin_s, chLatin_i, chLatin_s, chColon,
+ chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chColon, chLatin_t, chLatin_c, chColon,
+ chLatin_S, chLatin_A, chLatin_M, chLatin_L, chColon, chDigit_2, chPeriod, chDigit_0, chColon,
+ chLatin_c, chLatin_o, chLatin_n, chLatin_d, chLatin_i, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chLatin_s, chColon,
+ chLatin_d, chLatin_e, chLatin_l, chLatin_e, chLatin_g, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull
+};
+
+const XMLCh samlconstants::SAML20_DELEGATION_CONDITION_PREFIX[] = UNICODE_LITERAL_3(d,e,l);
+
const char samlconstants::SAML1_BINDING_SOAP[] = "urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding";
const char samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT[] = "urn:oasis:names:tc:SAML:1.0:profiles:artifact-01";
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* @file shibsp/lite/SAMLConstants.h
- *
- * SAML XML namespace constants
+ *
+ * SAML XML namespace constants
*/
#ifndef __shibsp_xmlconstants_h__
* SAML related constants.
*/
namespace samlconstants {
-
+
/** Liberty PAOS XML Namespace ("urn:liberty:paos:2003-08") */
extern SHIBSP_API const XMLCh PAOS_NS[];
-
+
/** Liberty PAOS QName prefix ("paos") */
extern SHIBSP_API const XMLCh PAOS_PREFIX[];
/** SAML 1.X Protocol XML namespace ("urn:oasis:names:tc:SAML:1.0:protocol") */
extern SHIBSP_API const XMLCh SAML1P_NS[];
-
+
/** SAML 1.X Assertion QName prefix ("saml") */
extern SHIBSP_API const XMLCh SAML1_PREFIX[];
/** SAML 1.X Protocol QName prefix ("samlp") */
extern SHIBSP_API const XMLCh SAML1P_PREFIX[];
-
+
/** SAML 2.0 Version ("2.0") */
extern SHIBSP_API const XMLCh SAML20_VERSION[];
-
+
/** SAML 2.0 Assertion XML namespace ("urn:oasis:names:tc:SAML:2.0:assertion") */
extern SHIBSP_API const XMLCh SAML20_NS[];
/** SAML 2.0 AuthnContext XML namespace ("urn:oasis:names:tc:SAML:2.0:ac") */
extern SHIBSP_API const XMLCh SAML20AC_NS[];
-
+
/** SAML 2.0 Assertion QName prefix ("saml") */
extern SHIBSP_API const XMLCh SAML20_PREFIX[];
/** SAML 2.0 Enhanced Client/Proxy SSO Profile XML Namespace ("urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp") */
extern SHIBSP_API const XMLCh SAML20ECP_NS[];
-
+
/** SAML 2.0 Enhanced Client/Proxy SSO Profile QName prefix ("ecp") */
extern SHIBSP_API const XMLCh SAML20ECP_PREFIX[];
/** SAML 2.0 DCE PAC Attribute Profile XML Namespace ("urn:oasis:names:tc:SAML:2.0:profiles:attribute:DCE") */
extern SHIBSP_API const XMLCh SAML20DCE_NS[];
-
+
/** SAML 2.0 DCE PAC Attribute Profile QName prefix ("DCE") */
extern SHIBSP_API const XMLCh SAML20DCE_PREFIX[];
/** SAML 2.0 X.500 Attribute Profile XML Namespace ("urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500") */
extern SHIBSP_API const XMLCh SAML20X500_NS[];
-
+
/** SAML 2.0 X.500 Attribute Profile QName prefix ("x500") */
extern SHIBSP_API const XMLCh SAML20X500_PREFIX[];
/** SAML 2.0 XACML Attribute Profile XML Namespace ("urn:oasis:names:tc:SAML:2.0:profiles:attribute:XACML") */
extern SHIBSP_API const XMLCh SAML20XACML_NS[];
-
+
/** SAML 2.0 XACML Attribute Profile QName prefix ("xacmlprof") */
extern SHIBSP_API const XMLCh SAML20XACML_PREFIX[];
/** SAML 1.x Metadata Profile XML Namespace ("urn:oasis:names:tc:SAML:profiles:v1metadata") */
extern SHIBSP_API const XMLCh SAML1MD_NS[];
-
+
/** SAML 1.x Metadata Profile QName prefix ("saml1md") */
extern SHIBSP_API const XMLCh SAML1MD_PREFIX[];
/** SAML 1.0 Protocol Enumeration constant ("urn:oasis:names:tc:SAML:1.0:protocol") */
extern SHIBSP_API const XMLCh SAML10_PROTOCOL_ENUM[];
-
+
/** SAML 1.1 Protocol Enumeration constant ("urn:oasis:names:tc:SAML:1.1:protocol") */
extern SHIBSP_API const XMLCh SAML11_PROTOCOL_ENUM[];
/** SAML Query Requester Metadata Extension XML Namespace ("urn:oasis:names:tc:SAML:metadata:ext:query") */
extern SHIBSP_API const XMLCh SAML20MD_QUERY_EXT_NS[];
-
+
/** SAML Query Requester Metadata Extension QName prefix ("query") */
extern SHIBSP_API const XMLCh SAML20MD_QUERY_EXT_PREFIX[];
/** SAML Third-Party Request Protocol Extension XML Namespace ("urn:oasis:names:tc:SAML:protocol:ext:third-party") */
extern SHIBSP_API const XMLCh SAML20P_THIRDPARTY_EXT_NS[];
-
- /** SAML Third-Party Request Protocol Extension QName prefix ("query") */
+
+ /** SAML Third-Party Request Protocol Extension QName prefix ("thrpty") */
extern SHIBSP_API const XMLCh SAML20P_THIRDPARTY_EXT_PREFIX[];
+ /** SAML Attribute Extension XML Namespace ("urn:oasis:names:tc:SAML:attribute:ext") */
+ extern SHIBSP_API const XMLCh SAML20_ATTRIBUTE_EXT_NS[];
+
+ /** SAML Attribute Extension QName prefix ("ext") */
+ extern SHIBSP_API const XMLCh SAML20_ATTRIBUTE_EXT_PREFIX[];
+
+ /** SAML Metadata Extension for Entity Attributes XML Namespace ("urn:oasis:names:tc:SAML:metadata:attribute") */
+ extern SHIBSP_API const XMLCh SAML20MD_ENTITY_ATTRIBUTE_NS[];
+
+ /** SAML Metadata Extension for Entity Attributes QName prefix ("mdattr") */
+ extern SHIBSP_API const XMLCh SAML20MD_ENTITY_ATTRIBUTE_PREFIX[];
+
+ /** SAML Condition for Delegation Restriction XML Namespace ("urn:oasis:names:tc:SAML:2.0:conditions:delegation") */
+ extern SHIBSP_API const XMLCh SAML20_DELEGATION_CONDITION_NS[];
+
+ /** SAML Condition for Delegation Restriction QName prefix ("del") */
+ extern SHIBSP_API const XMLCh SAML20_DELEGATION_CONDITION_PREFIX[];
+
/** SAML 1.x SOAP binding ("urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding") */
extern SHIBSP_API const char SAML1_BINDING_SOAP[];
/** SAML 1.x Browser POST profile ("urn:oasis:names:tc:SAML:1.0:profiles:browser-post") */
extern SHIBSP_API const char SAML1_PROFILE_BROWSER_POST[];
-
+
/** SAML 2.0 SOAP binding ("urn:oasis:names:tc:SAML:2.0:bindings:SOAP") */
extern SHIBSP_API const char SAML20_BINDING_SOAP[];
- /** SAML 2.0 SOAP binding ("urn:oasis:names:tc:SAML:2.0:bindings:PAOS") */
+ /** SAML 2.0 PAOS binding ("urn:oasis:names:tc:SAML:2.0:bindings:PAOS") */
extern SHIBSP_API const char SAML20_BINDING_PAOS[];
/** SAML 2.0 URI binding ("urn:oasis:names:tc:SAML:2.0:bindings:URI") */
/** SAML 2.0 HTTP-POST binding ("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST") */
extern SHIBSP_API const char SAML20_BINDING_HTTP_POST[];
-
+
/** SAML 2.0 HTTP-POST-SimpleSign binding ("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign") */
extern SHIBSP_API const char SAML20_BINDING_HTTP_POST_SIMPLESIGN[];
/** SAML 2.0 HTTP-Redirect binding ("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect") */
extern SHIBSP_API const char SAML20_BINDING_HTTP_REDIRECT[];
-
+
/** SAML 2.0 HTTP-Redirect DEFLATE URL encoding ("urn:oasis:names:tc:SAML:2.0:bindings:URL-Encoding:DEFLATE") */
extern SHIBSP_API const char SAML20_BINDING_URL_ENCODING_DEFLATE[];
};
/*
- * Copyright 2001-2008 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Category& log=Category::getInstance(SHIBSP_LOGCAT".MetadataProvider.Dynamic");
string name;
- if (criteria.entityID_ascii)
+ if (criteria.entityID_ascii) {
name = criteria.entityID_ascii;
+ }
else if (criteria.entityID_unicode) {
auto_ptr_char temp(criteria.entityID_unicode);
name = temp.get();
}
- else if (criteria.artifact)
- name = criteria.artifact->getSource();
+ else if (criteria.artifact) {
+ throw saml2md::MetadataException("Unable to resolve metadata dynamically from an artifact.");\r
+ }
// Establish networking properties based on calling application.
const MetadataProviderCriteria* mpc = dynamic_cast<const MetadataProviderCriteria*>(&criteria);
}
try {
- // Use an empty stream to trigger a body-less "GET" operation.
- istringstream dummy;
- transport->send(dummy);
+ // Use a NULL stream to trigger a body-less "GET" operation.
+ transport->send();
istream& msg = transport->receive();
DOMDocument* doc=NULL;
public:
- ScopeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+ ScopeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
: AbstractXMLObject(nsURI, localName, prefix, schemaType) {
init();
}
XMLString::release(&m_VerifyDepth);
}
- KeyAuthorityImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+ KeyAuthorityImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
: AbstractXMLObject(nsURI, localName, prefix, schemaType) {
init();
}
IMPL_TYPED_CHILDREN(KeyInfo,m_children.end());
public:
- void setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID=false) {
+ void setAttribute(const xmltooling::QName& qualifiedName, const XMLCh* value, bool ID=false) {
if (!qualifiedName.hasNamespaceURI()) {
if (XMLString::equals(qualifiedName.getLocalPart(),VERIFYDEPTH_ATTRIB_NAME)) {
setVerifyDepth(value);
};
#define REGISTER_ELEMENT(cname) \
- q=QName(SHIBMD_NS,cname::LOCAL_NAME); \
+ q=xmltooling::QName(SHIBMD_NS,cname::LOCAL_NAME); \
XMLObjectBuilder::registerBuilder(q,new cname##Builder()); \
SchemaValidators.registerValidator(q,new cname##SchemaValidator())
void shibsp::registerMetadataExtClasses() {
- QName q;
+ xmltooling::QName q;
REGISTER_ELEMENT(Scope);
REGISTER_ELEMENT(KeyAuthority);
* Constructor.
*
* @param app application performing the lookup
+ */
+ MetadataProviderCriteria(const Application& app) : application(app) {
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param app application performing the lookup
* @param id entityID to lookup
* @param q element/type of role, if any
* @param prot protocol support constant, if any
/*\r
- * Copyright 2001-2005 Internet2\r
+ * Copyright 2001-2009 Internet2\r
* \r
* Licensed under the Apache License, Version 2.0 (the "License");\r
* you may not use this file except in compliance with the License.\r
#ifndef __shibsp_paths_h__\r
#define __shibsp_paths_h__\r
\r
-/**\r
- * Default schema catalogs.\r
- */\r
-#define SHIBSP_SCHEMAS "/usr/share/xml/xmltooling/catalog.xml:/usr/share/xml/opensaml/saml20-catalog.xml:/usr/share/xml/opensaml/saml11-catalog.xml:/usr/local/share/xml/shibboleth/catalog.xml"\r
+/** Default schema catalogs. */\r
+#define SHIBSP_SCHEMAS "/opt/shibboleth-sp/share/xml/xmltooling/catalog.xml:/usr/share/xml/opensaml/saml20-catalog.xml:/usr/share/xml/opensaml/saml11-catalog.xml:/opt/shibboleth-sp/share/xml/shibboleth/catalog.xml"\r
\r
-/**\r
- * Default name of SP configuration file.\r
- */\r
+/** Default name of SP configuration file. */\r
#define SHIBSP_CONFIG "shibboleth2.xml"\r
\r
-/**\r
- * Default name of SP console tool logging file.\r
- */\r
+/** Default name of SP console tool logging file. */\r
#define SHIBSP_LOGGING "console.logger"\r
\r
-/**\r
- * Default prefix for installation (used to resolve relative paths).\r
- */\r
-#define SHIBSP_PREFIX "/usr/local"\r
+/** Default prefix for installation (used to resolve relative paths). */\r
+#define SHIBSP_PREFIX "/opt/shibboleth-sp"\r
+\r
+/** Library directory for installation (used to resolve relative paths). */\r
+#define SHIBSP_LIBDIR "/opt/shibboleth-sp/lib"\r
+\r
+/** Log directory for installation (used to resolve relative paths). */\r
+#define SHIBSP_LOGDIR "/opt/shibboleth-sp/var/log"\r
+\r
+/** Configuration directory for installation (used to resolve relative paths). */\r
+#define SHIBSP_CFGDIR "/opt/shibboleth-sp/etc"\r
+\r
+/** Runtime state directory for installation (used to resolve relative paths). */\r
+#define SHIBSP_RUNDIR "/opt/shibboleth-sp/var/run"\r
+\r
+/** XML directory for installation (used to resolve relative paths). */\r
+#define SHIBSP_XMLDIR "/opt/shibboleth-sp/share/xml"\r
\r
#endif /* __shibsp_paths_h__ */\r
/*\r
- * Copyright 2001-2005 Internet2\r
+ * Copyright 2001-2009 Internet2\r
* \r
* Licensed under the Apache License, Version 2.0 (the "License");\r
* you may not use this file except in compliance with the License.\r
#ifndef __shibsp_paths_h__\r
#define __shibsp_paths_h__\r
\r
-/**\r
- * Default schema catalogs.\r
- */\r
+/** Default schema catalogs. */\r
#define SHIBSP_SCHEMAS "@-XMLTOOLINGXMLDIR-@/catalog.xml:@-OPENSAMLXMLDIR-@/saml20-catalog.xml:@-OPENSAMLXMLDIR-@/saml11-catalog.xml:@-PKGXMLDIR-@/catalog.xml"\r
\r
-/**\r
- * Default name of SP configuration file.\r
- */\r
+/** Default name of SP configuration file. */\r
#define SHIBSP_CONFIG "shibboleth2.xml"\r
\r
-/**\r
- * Default name of SP console tool logging file.\r
- */\r
+/** Default name of SP console tool logging file. */\r
#define SHIBSP_LOGGING "console.logger"\r
\r
-/**\r
- * Default prefix for installation (used to resolve relative paths).\r
- */\r
+/** Default prefix for installation (used to resolve relative paths). */\r
#define SHIBSP_PREFIX "@-PREFIX-@"\r
\r
+/** Library directory for installation (used to resolve relative paths). */\r
+#define SHIBSP_LIBDIR "@-LIBDIR-@"\r
+\r
+/** Log directory for installation (used to resolve relative paths). */\r
+#define SHIBSP_LOGDIR "@-LOGDIR-@"\r
+\r
+/** Configuration directory for installation (used to resolve relative paths). */\r
+#define SHIBSP_CFGDIR "@-SYSCONFDIR-@"\r
+\r
+/** Runtime state directory for installation (used to resolve relative paths). */\r
+#define SHIBSP_RUNDIR "@-RUNDIR-@"\r
+\r
+/** XML directory for installation (used to resolve relative paths). */\r
+#define SHIBSP_XMLDIR "@-XMLDIR-@"\r
+\r
#endif /* __shibsp_paths_h__ */\r
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* @file shibsp/remoting/ListenerService.h
- *
+ *
* Interprocess remoting engine.
*/
/**
* Interface to a remoted service
- *
+ *
* Classes that support remoted messages delivered by the Listener runtime
* support this interface and register themselves with the runtime to receive
* particular messages.
/**
* Remoted classes implement this method to process incoming messages.
- *
+ *
* @param in incoming DDF message
* @param out stream to write outgoing DDF message to
*/
/**
* Interface to a remoting engine.
- *
+ *
* A ListenerService supports the remoting of DDF objects, which are dynamic data trees
* that other class implementations can use to remote themselves by calling an
* out-of-process peer implementation with arbitrary data to carry out tasks
/**
* Send a remoted message and return the response.
- *
+ *
* @param in input message to send
* @return response from remote service
*/
virtual DDF send(const DDF& in)=0;
-
+
void receive(DDF& in, std::ostream& out);
// Remoted classes register and unregister for messages using these methods.
// Registration returns any existing listeners, allowing message hooking.
-
+
/**
* Register for a message. Returns existing remote service, allowing message hooking.
- *
+ *
* @param address message address to register
* @param svc pointer to remote service
* @return previous service registered for message, if any
*/
virtual Remoted* regListener(const char* address, Remoted* svc);
-
+
/**
* Unregisters service from an address, possibly restoring an original.
- *
+ *
* @param address message address to modify
* @param current pointer to unregistering service
* @param restore service to "restore" registration for
* @return true iff the current service was still registered
*/
virtual bool unregListener(const char* address, Remoted* current, Remoted* restore=NULL);
-
+
/**
* Returns current service registered at an address, if any.
- *
+ *
* @param address message address to access
* @return registered service, or NULL
*/
virtual Remoted* lookup(const char* address) const;
/**
+ * OutOfProcess servers can implement server-side initialization that should occur
+ * before daemonization.
+ *
+ * <p>The parameter applies to implementations that can detect and remove
+ * the results of ungraceful shutdowns of previous executions and continue
+ * successfully. File-based sockets are the most common example.
+ *
+ * @param force true iff remnant network state should be forcibly cleared
+ * @return true iff the service initialization was successful
+ */
+ virtual bool init(bool force) {
+ return true;
+ }
+
+ /**
* OutOfProcess servers can implement server-side transport handling by
* calling the run method and supplying a flag to monitor for shutdown.
- *
+ *
* @param shutdown pointer to flag that caller will set when shutdown is required
- * @return true iff ListenerService initialization was successful
+ * @return true iff the service execution was successful
*/
virtual bool run(bool* shutdown)=0;
+ /**
+ * OutOfProcess servers can implement server-side termination/cleanup.
+ */
+ virtual void term() {
+ }
+
private:
std::map<std::string,Remoted*> m_listenerMap;
};
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// constructors
DDF() : m_handle(NULL) {}
DDF(const char* n);
- DDF(const char* n, const char* val);
+ DDF(const char* n, const char* val, bool safe=true);
DDF(const char* n, long val);
DDF(const char* n, double val);
DDF(const char* n, void* val);
DDF& string(const char* val) {
return string(const_cast<char*>(val), true);
}
- DDF& string(char* val, bool copyit=true);
+ DDF& unsafe_string(const char* val) {
+ return string(const_cast<char*>(val), true, false);
+ }
+ DDF& string(char* val, bool copyit=true, bool safe=true);
DDF& string(long val);
DDF& string(double val);
DDF& integer(long val);
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* ListenerService.cpp
- *
+ *
* Interprocess remoting engine.
*/
Remoted* dest=lookup(in.name());
if (!dest)
throw ListenerException("No destination registered for incoming message addressed to ($1).",params(1,in.name()));
-
+
dest->receive(in, out);
}
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* SocketListener.cpp
- *
+ *
* Berkeley Socket-based ListenerService implementation
*/
using xercesc::DOMElement;
namespace shibsp {
-
+
// Manages the pool of connections
class SocketPool
{
~SocketPool();
SocketListener::ShibSocket get();
void put(SocketListener::ShibSocket s);
-
+
private:
SocketListener::ShibSocket connect();
-
- Category& m_log;
+
+ Category& m_log;
const SocketListener* m_listener;
auto_ptr<Mutex> m_lock;
stack<SocketListener::ShibSocket> m_pool;
};
-
+
// Worker threads in server
class ServerThread {
public:
connected = true;
break;
}
-
+
m_log.warn("cannot connect socket (%u)...%s", sock, (i > 0 ? "retrying" : ""));
if (i) {
m_lock->unlock();
}
-SocketListener::SocketListener(const DOMElement* e) : m_catchAll(false), log(&Category::getInstance(SHIBSP_LOGCAT".Listener")),
- m_socketpool(NULL), m_shutdown(NULL), m_child_lock(NULL), m_child_wait(NULL), m_socket((ShibSocket)0)
+SocketListener::SocketListener(const DOMElement* e)
+ : m_catchAll(false), log(&Category::getInstance(SHIBSP_LOGCAT".Listener")), m_socketpool(NULL),
+ m_shutdown(NULL), m_child_lock(NULL), m_child_wait(NULL), m_socket((ShibSocket)0)
{
// Are we a client?
if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
delete m_child_lock;
}
-bool SocketListener::run(bool* shutdown)
+bool SocketListener::init(bool force)
{
#ifdef _DEBUG
- NDC ndc("run");
+ NDC ndc("init");
#endif
log->info("listener service starting");
m_catchAll = flag.first && flag.second;
}
sp->unlock();
-
- // Save flag to monitor for shutdown request.
- m_shutdown=shutdown;
- unsigned long count = 0;
if (!create(m_socket)) {
log->crit("failed to create socket");
return false;
}
- if (!bind(m_socket,true)) {
+ if (!bind(m_socket, force)) {
this->close(m_socket);
log->crit("failed to bind to socket.");
return false;
}
+ return true;
+}
+
+bool SocketListener::run(bool* shutdown)
+{
+#ifdef _DEBUG
+ NDC ndc("run");
+#endif
+ // Save flag to monitor for shutdown request.
+ m_shutdown=shutdown;
+ unsigned long count = 0;
+
while (!*m_shutdown) {
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(m_socket, &readfds);
struct timeval tv = { 0, 0 };
tv.tv_sec = 5;
-
+
switch (select(m_socket + 1, &readfds, 0, 0, &tv)) {
#ifdef WIN32
case SOCKET_ERROR:
if (errno == EINTR) continue;
log_error();
log->error("select() on main listener socket failed");
- return false;
-
+ *m_shutdown = true;
+ break;
+
case 0:
continue;
-
+
default:
{
// Accept the connection.
SocketListener::ShibSocket newsock;
- if (!accept(m_socket, newsock))
+ if (!accept(m_socket, newsock)) {
log->crit("failed to accept incoming socket connection");
+ continue;
+ }
// We throw away the result because the children manage themselves...
try {
new ServerThread(newsock,this,++count);
}
+ catch (exception& ex) {
+ log->crit("exception starting new server thread to service incoming request: %s", ex.what());
+ }
catch (...) {
- log->crit("error starting new server thread to service incoming request");
+ log->crit("unknown error starting new server thread to service incoming request");
if (!m_catchAll)
*m_shutdown = true;
}
m_child_wait->wait(m_child_lock);
m_child_lock->unlock();
+ return true;
+}
+
+void SocketListener::term()
+{
this->close(m_socket);
m_socket=(ShibSocket)0;
- return true;
}
DDF SocketListener::send(const DDF& in)
SocketListener::ShibSocket sock;
while (retry >= 0) {
sock = m_socketpool->get();
-
+
int outlen = ostr.length();
len = htonl(outlen);
if (send(sock,(char*)&len,sizeof(len)) != sizeof(len) || send(sock,ostr.c_str(),outlen) != outlen) {
throw ListenerException("Failure receiving response to remoted message ($1).", params(1,in.name()));
}
len = ntohl(len);
-
+
char buf[16384];
int size_read;
stringstream is;
break;
}
}
-
+
if (len) {
log->error("error reading output message from socket");
this->close(sock);
throw ListenerException("Failure receiving response to remoted message ($1).", params(1,in.name()));
}
-
+
m_socketpool->put(sock);
// Unmarshall data.
DDF out;
is >> out;
-
+
// Check for exception to unmarshall and throw, otherwise return.
if (out.isstring() && out.name() && !strcmp(out.name(),"exception")) {
// Reconstitute exception object.
DDFJanitor jout(out);
XMLToolingException* except=NULL;
- try {
+ try {
except=XMLToolingException::fromString(out.string());
log->error("remoted message returned an error: %s", except->what());
}
m_listener->m_children.erase(m_sock);
m_listener->m_child_lock->unlock();
m_listener->m_child_wait->signal();
-
+
delete m_child;
}
m_listener->m_child_wait->wait(m_listener->m_child_lock);
m_listener->m_children[m_sock] = m_child;
m_listener->m_child_lock->unlock();
-
+
int result;
fd_set readfds;
struct timeval tv = { 0, 0 };
return -1;
}
len = ntohl(len);
-
+
int size_read;
stringstream is;
while (len && (size_read = m_listener->recv(m_sock, m_buf, sizeof(m_buf))) > 0) {
is.write(m_buf, size_read);
len -= size_read;
}
-
+
if (len) {
log.error("error reading input message from socket");
return -1;
}
-
+
// Unmarshall the message.
DDF in;
DDFJanitor jin(in);
DDFJanitor jout(out);
sink << out;
}
-
+
// Return whatever's available.
string response(sink.str());
int outlen = response.length();
log.error("error sending output message");
return -1;
}
-
+
return 0;
}
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/**
* SocketListener.h
- *
+ *
* Berkeley Socket-based ListenerService implementation
*/
class SocketPool;
class ServerThread;
-
+
/**
* Berkeley Socket-based ListenerService implementation
*/
~SocketListener();
DDF send(const DDF& in);
+
+ bool init(bool force);
bool run(bool* shutdown);
+ void term();
// Implemented by socket-specific subclasses.
#ifdef WIN32
bool log_error() const; // for OS-level errors
xmltooling::logging::Category* log;
/// @endcond
-
+
private:
mutable SocketPool* m_socketpool;
bool* m_shutdown;
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* TCPListener.cpp
- *
+ *
* TCP-based SocketListener implementation
*/
# include <sys/un.h>
# include <unistd.h>
# include <arpa/inet.h>
+# include <netinet/in.h>
#endif
#include <sys/types.h>
bool connect(ShibSocket& s) const;
bool close(ShibSocket& s) const;
bool accept(ShibSocket& listener, ShibSocket& s) const;
-
+
int send(ShibSocket& s, const char* buf, int len) const {
return ::send(s, buf, len, 0);
}
-
+
int recv(ShibSocket& s, char* buf, int buflen) const {
return ::recv(s, buf, buflen, 0);
}
-
+
private:
void setup_tcp_sockaddr(struct sockaddr_in* addr) const;
string m_address;
unsigned short m_port;
- vector<string> m_acl;
+ set<string> m_acl;
};
ListenerService* SHIBSP_DLLLOCAL TCPListenerServiceFactory(const DOMElement* const & e)
auto_ptr_char a(tag);
m_address=a.get();
}
-
+
tag=e->getAttributeNS(NULL,port);
if (tag && *tag) {
m_port=XMLString::parseInt(tag);
if (m_port==0)
m_port=12345;
}
-
+
tag=e->getAttributeNS(NULL,acl);
if (tag && *tag) {
auto_ptr_char temp(tag);
int j = 0;
for (unsigned int i=0; i < sockacl.length(); i++) {
if (sockacl.at(i)==' ') {
- m_acl.push_back(sockacl.substr(j, i-j));
+ m_acl.insert(sockacl.substr(j, i-j));
j = i+1;
}
}
- m_acl.push_back(sockacl.substr(j, sockacl.length()-j));
+ m_acl.insert(sockacl.substr(j, sockacl.length()-j));
}
}
else
- m_acl.push_back("127.0.0.1");
+ m_acl.insert("127.0.0.1");
}
void TCPListener::setup_tcp_sockaddr(struct sockaddr_in* addr) const
#endif
return log_error();
char* client=inet_ntoa(addr.sin_addr);
- for (vector<string>::const_iterator i=m_acl.begin(); i!=m_acl.end(); i++) {
- if (*i==client)
- return true;
+ if (m_acl.count(client) == 0) {
+ close(s);
+ s=-1;
+ log->error("accept() rejected client at %s", client);
+ return false;
}
- close(s);
- s=-1;
- log->error("accept() rejected client at %s\n",client);
- return false;
+ return true;
}
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/**
* ddf.cpp
- *
+ *
* C++ DDF abstraction for interpretive RPC
*/
#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/ParserPool.h>
+#include <xmltooling/util/URLEncoder.h>
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
The name buffer is returned from the function. */
char* ddf_token(const char** path, char* name)
{
- const char* temp=NULL;
-
- *name='\0';
- if (*path==NULL || **path=='\0')
+ *name=0;
+ if (*path==NULL || **path==0)
return name;
- temp=strchr(*path,'.');
- if (temp==NULL)
- {
- strcpy(name,*path);
+ const char* temp=strchr(*path,'.');
+ if (temp==NULL) {
+ strncpy(name,*path,MAX_NAME_LEN);
+ name[MAX_NAME_LEN]=0;
*path=NULL;
}
- else if (temp>*path)
- {
+ else if (temp>*path) {
strncpy(name,*path,temp-*path);
- name[temp-*path]='\0';
+ name[temp-*path]=0;
*path=temp+1;
}
else
DDF_FLOAT,
DDF_STRUCT,
DDF_LIST,
- DDF_POINTER
+ DDF_POINTER,
+ DDF_STRING_UNSAFE
} type; // data type of node
union {
name(n);
}
-DDF::DDF(const char* n, const char* val)
+DDF::DDF(const char* n, const char* val, bool safe)
{
m_handle=new(nothrow) ddf_body_t;
name(n);
- string(val);
+ string(const_cast<char*>(val), true, safe);
}
DDF::DDF(const char* n, long val)
case ddf_body_t::DDF_EMPTY:
return DDF(m_handle->name);
case ddf_body_t::DDF_STRING:
- return DDF(m_handle->name,m_handle->value.string);
+ case ddf_body_t::DDF_STRING_UNSAFE:
+ return DDF(m_handle->name,m_handle->value.string,(m_handle->type==ddf_body_t::DDF_STRING));
case ddf_body_t::DDF_INT:
return DDF(m_handle->name,m_handle->value.integer);
case ddf_body_t::DDF_FLOAT:
bool DDF::isstring() const
{
- return m_handle ? (m_handle->type==ddf_body_t::DDF_STRING) : false;
+ return m_handle ? (m_handle->type==ddf_body_t::DDF_STRING || m_handle->type==ddf_body_t::DDF_STRING_UNSAFE) : false;
}
bool DDF::isint() const
case ddf_body_t::DDF_FLOAT:
return static_cast<long>(m_handle->value.floating);
case ddf_body_t::DDF_STRING:
+ case ddf_body_t::DDF_STRING_UNSAFE:
return m_handle->value.string ? atol(m_handle->value.string) : 0;
case ddf_body_t::DDF_STRUCT:
case ddf_body_t::DDF_LIST:
case ddf_body_t::DDF_FLOAT:
return m_handle->value.floating;
case ddf_body_t::DDF_STRING:
+ case ddf_body_t::DDF_STRING_UNSAFE:
return m_handle->value.string ? atof(m_handle->value.string) : 0;
case ddf_body_t::DDF_STRUCT:
case ddf_body_t::DDF_LIST:
if (m_handle) {
switch (m_handle->type) {
case ddf_body_t::DDF_STRING:
+ case ddf_body_t::DDF_STRING_UNSAFE:
if (m_handle->value.string)
free(m_handle->value.string);
break;
return *this;
}
-DDF& DDF::string(char* val, bool copyit)
+DDF& DDF::string(char* val, bool copyit, bool safe)
{
if (empty().m_handle) {
m_handle->value.string = copyit ? ddf_strdup(val) : val;
if (!m_handle->value.string && val && *val)
return destroy();
- m_handle->type=ddf_body_t::DDF_STRING;
+ m_handle->type=(safe ? ddf_body_t::DDF_STRING : ddf_body_t::DDF_STRING_UNSAFE);
}
return *this;
}
{
char name[MAX_NAME_LEN+1];
const char* path_ptr=path;
-
+
if (m_handle && ddf_strlen(ddf_token(&path_ptr,name))>0) {
if (!isstruct())
structure();
DDF DDF::getmember(const char* path) const
{
+ DDF current;
char name[MAX_NAME_LEN+1];
const char* path_ptr=path;
- DDF current;
- if (isstruct() && ddf_strlen(ddf_token(&path_ptr,name))>0) {
- current.m_handle=m_handle->value.children.first;
- while (current.m_handle && strcmp(current.m_handle->name,name)!=0)
- current.m_handle=current.m_handle->next;
-
- if (current.m_handle && ddf_strlen(path_ptr)>0)
- current=current.getmember(path_ptr);
+ ddf_token(&path_ptr, name);
+ if (*name == 0)
+ return current;
+ else if (*name == '[') {
+ unsigned long i = strtoul(name+1, NULL, 10);
+ if (islist() && i < m_handle->value.children.count)
+ current=operator[](i);
+ else if (i == 0)
+ current = *this;
+ }
+ else if (isstruct()) {
+ current.m_handle = m_handle->value.children.first;
+ while (current.m_handle && strcmp(current.m_handle->name,name) != 0)
+ current.m_handle = current.m_handle->next;
+ }
+ else if (islist()) {
+ current.m_handle = m_handle->value.children.first;
+ return current.getmember(path);
}
+
+ if (current.m_handle && path_ptr && *path_ptr)
+ current = current.getmember(path_ptr);
return current;
}
ddf_print_indent(f,indent);
if (m_handle) {
switch (m_handle->type) {
-
+
case ddf_body_t::DDF_EMPTY:
fprintf(f,"empty");
if (m_handle->name)
break;
case ddf_body_t::DDF_STRING:
+ case ddf_body_t::DDF_STRING_UNSAFE:
if (m_handle->name)
fprintf(f,"char* %s = ",m_handle->name);
else
{
if (p) {
switch (p->type) {
-
+
case ddf_body_t::DDF_STRING:
+ case ddf_body_t::DDF_STRING_UNSAFE:
os << "<string";
if (name_attr && p->name) {
os << " name=\"";
os << '"';
}
if (p->value.string) {
- os << '>';
- xml_encode(os,p->value.string);
+ if (p->type == ddf_body_t::DDF_STRING) {
+ os << '>';
+ xml_encode(os,p->value.string);
+ }
+ else {
+ os << " unsafe=\"1\">";
+ xml_encode(os,XMLToolingConfig::getConfig().getURLEncoder()->encode(p->value.string).c_str());
+ }
os << "</string>";
}
else
static const XMLCh _array[] = UNICODE_LITERAL_5(a,r,r,a,y);
static const XMLCh _struct[] = UNICODE_LITERAL_6(s,t,r,u,c,t);
static const XMLCh _lowercase[] = UNICODE_LITERAL_9(l,o,w,e,r,c,a,s,e);
+static const XMLCh _unsafe[] = UNICODE_LITERAL_6(u,n,s,a,f,e);
DDF deserialize(DOMElement* root, bool lowercase)
{
DDF obj(NULL);
- auto_ptr_char name_val(root->getAttribute(_name));
+ auto_ptr_char name_val(root->getAttributeNS(NULL, _name));
if (name_val.get() && *name_val.get()) {
if (lowercase)
for (char* pch=const_cast<char*>(name_val.get()); *pch=tolower(*pch); pch++);
if (XMLString::equals(tag,_string)) {
DOMNode* child=root->getFirstChild();
if (child && child->getNodeType()==DOMNode::TEXT_NODE) {
- char* val = toUTF8(child->getNodeValue(), true); // use malloc
- if (val)
- obj.string(val, false); // don't re-copy the string
+ const XMLCh* unsafe = root->getAttributeNS(NULL, _unsafe);
+ if (unsafe && *unsafe==chDigit_1) {
+ // If it's unsafe, it's not UTF-8 data, so we have to convert to ASCII and decode it.
+ char* encoded = XMLString::transcode(child->getNodeValue());
+ XMLToolingConfig::getConfig().getURLEncoder()->decode(encoded);
+ obj.string(encoded, true, false); // re-copy into free-able buffer, plus mark unsafe
+ XMLString::release(&encoded);
+ }
+ else {
+ char* val = toUTF8(child->getNodeValue(), true); // use malloc
+ if (val)
+ obj.string(val, false); // don't re-copy the string
+ }
}
}
else if (XMLString::equals(tag,_number)) {
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
if (m_caching) {
m_engine.m_credLock->unlock();
m_engine.m_credLock->wrlock();
- PKIXTrustEngine::credmap_t::iterator cached = m_credCache->second.find(m_current);
if (m_credCache->second.count(m_current)==0) {
// Transfer objects into cache.
m_credCache->second[m_current] = m_ownedCreds;
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* SecurityPolicy.cpp
- *
+ *
* SP-specific SecurityPolicy subclass.
*/
#include "internal.h"
#include "Application.h"
#include "ServiceProvider.h"
+#include "metadata/MetadataProviderCriteria.h"
#include "security/SecurityPolicy.h"
using namespace shibsp;
+using namespace opensaml::saml2;
+using namespace std;
-SecurityPolicy::SecurityPolicy(const Application& application, const xmltooling::QName* role, bool validate)
- : opensaml::SecurityPolicy(application.getMetadataProvider(), role, application.getTrustEngine(), validate), m_application(application) {
-
- const std::vector<const opensaml::SecurityPolicyRule*>& rules =
- application.getServiceProvider().getPolicyRules(application.getString("policyId").second);
+SecurityPolicy::SecurityPolicy(const Application& application, const xmltooling::QName* role, bool validate, const char* policyId)
+ : opensaml::SecurityPolicy(application.getMetadataProvider(), role, application.getTrustEngine(), validate), m_application(application) {
+ const vector<const opensaml::SecurityPolicyRule*>& rules =
+ application.getServiceProvider().getPolicyRules(policyId ? policyId : application.getString("policyId").second);
getRules().assign(rules.begin(), rules.end());
+
+ // Populate audiences.
+ if (application.getAudiences()) {
+ for (vector<const XMLCh*>::const_iterator a = application.getAudiences()->begin(); a != application.getAudiences()->end(); ++a)
+ getAudiences().push_back(*a);
+ }
+}
+
+opensaml::saml2md::MetadataProvider::Criteria& SecurityPolicy::getMetadataProviderCriteria() const
+{
+ if (!m_metadataCriteria)
+ m_metadataCriteria=new MetadataProviderCriteria(m_application);
+ else
+ m_metadataCriteria->reset();
+ return *m_metadataCriteria;
}
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* @file shibsp/security/SecurityPolicy.h
- *
+ *
* SP-specific SecurityPolicy subclass.
*/
#define __shibsp_secpol_h__
#include <shibsp/base.h>
-#include <saml/binding/SecurityPolicy.h>
+#include <saml/saml2/profile/SAML2AssertionPolicy.h>
namespace shibsp {
-
+
class SHIBSP_API Application;
/**
* SP-specific SecurityPolicy subclass.
*/
- class SHIBSP_API SecurityPolicy : public opensaml::SecurityPolicy
+ class SHIBSP_API SecurityPolicy : public opensaml::saml2::SAML2AssertionPolicy
{
public:
/**
* Constructor for policy.
- *
+ *
* @param application an Application instance
- * @param role identifies the role (generally IdP or SP) of the policy peer
+ * @param role identifies the role (generally IdP or SP) of the policy peer
* @param validate true iff XML parsing should be done with validation
+ * @param policyId identifies policy rules to auto-attach, defaults to the application's set
*/
- SecurityPolicy(const Application& application, const xmltooling::QName* role=NULL, bool validate=true);
+ SecurityPolicy(const Application& application, const xmltooling::QName* role=NULL, bool validate=true, const char* policyId=NULL);
virtual ~SecurityPolicy() {}
+ opensaml::saml2md::MetadataProvider::Criteria& getMetadataProviderCriteria() const;
+
/**
* Returns the Application associated with the policy.
- *
+ *
* @return the associated Application
*/
const Application& getApplication() const {
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="8.00"\r
+ Version="9.00"\r
Name="shibsp-lite"\r
ProjectGUID="{81F0F7A6-DC36-46EF-957F-F9E81D4403F7}"\r
RootNamespace="shibsp-lite"\r
Keyword="Win32Proj"\r
+ TargetFrameworkVersion="131072"\r
>\r
<Platforms>\r
<Platform\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib xerces-c_2D.lib xmltooling-lite1D.lib wsock32.lib"\r
- OutputFile="$(OutDir)\$(ProjectName)1_1D.dll"\r
+ AdditionalDependencies="log4shib1D.lib xerces-c_3D.lib xmltooling-lite1D.lib wsock32.lib"\r
+ OutputFile="$(OutDir)\$(ProjectName)1_2D.dll"\r
LinkIncremental="2"\r
AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(ConfigurationName)"\r
GenerateDebugInformation="true"\r
SubSystem="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
ImportLibrary="$(TargetDir)$(ProjectName)1D.lib"\r
TargetMachine="1"\r
/>\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib xerces-c_2D.lib xmltooling-lite1D.lib wsock32.lib"\r
- OutputFile="$(OutDir)\$(ProjectName)1_1D.dll"\r
+ AdditionalDependencies="log4shib1D.lib xerces-c_3D.lib xmltooling-lite1D.lib wsock32.lib"\r
+ OutputFile="$(OutDir)\$(ProjectName)1_2D.dll"\r
LinkIncremental="2"\r
AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
GenerateDebugInformation="true"\r
SubSystem="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
ImportLibrary="$(TargetDir)$(ProjectName)1D.lib"\r
TargetMachine="17"\r
/>\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib xerces-c_2.lib xmltooling-lite1.lib wsock32.lib"\r
- OutputFile="$(OutDir)\$(ProjectName)1_1.dll"\r
+ AdditionalDependencies="log4shib1.lib xerces-c_3.lib xmltooling-lite1.lib wsock32.lib"\r
+ OutputFile="$(OutDir)\$(ProjectName)1_2.dll"\r
LinkIncremental="1"\r
AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(ConfigurationName)"\r
SubSystem="2"\r
OptimizeReferences="2"\r
EnableCOMDATFolding="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
ImportLibrary="$(TargetDir)$(ProjectName)1.lib"\r
TargetMachine="1"\r
/>\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib xerces-c_2.lib xmltooling-lite1.lib wsock32.lib"\r
- OutputFile="$(OutDir)\$(ProjectName)1_1.dll"\r
+ AdditionalDependencies="log4shib1.lib xerces-c_3.lib xmltooling-lite1.lib wsock32.lib"\r
+ OutputFile="$(OutDir)\$(ProjectName)1_2.dll"\r
LinkIncremental="1"\r
AdditionalLibraryDirectories="..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
GenerateDebugInformation="true"\r
SubSystem="2"\r
OptimizeReferences="2"\r
EnableCOMDATFolding="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
ImportLibrary="$(TargetDir)$(ProjectName)1.lib"\r
TargetMachine="17"\r
/>\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
Name="impl"\r
>\r
<File\r
+ RelativePath=".\impl\ChainingAccessControl.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\impl\StorageServiceSessionCache.cpp"\r
>\r
</File>\r
RelativePath=".\attribute\Attribute.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\attribute\ExtensibleAttribute.cpp"\r
+ >\r
+ </File>\r
</Filter>\r
<Filter\r
Name="handler"\r
>\r
</File>\r
<File\r
+ RelativePath=".\attribute\ExtensibleAttribute.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\attribute\NameIDAttribute.h"\r
>\r
</File>\r
RelativePath=".\attribute\SimpleAttribute.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\attribute\XMLAttribute.h"\r
+ >\r
+ </File>\r
</Filter>\r
<Filter\r
Name="handler"\r
//\r
\r
VS_VERSION_INFO VERSIONINFO\r
- FILEVERSION 1,1,0,0\r
- PRODUCTVERSION 2,1,0,0\r
+ FILEVERSION 1,2,1,0\r
+ PRODUCTVERSION 2,2,1,0\r
FILEFLAGSMASK 0x3fL\r
#ifdef _DEBUG\r
FILEFLAGS 0x1L\r
#else\r
VALUE "FileDescription", "Shibboleth SP Library\0"\r
#endif\r
- VALUE "FileVersion", "1, 1, 0, 0\0"\r
+ VALUE "FileVersion", "1, 2, 1, 0\0"\r
#ifdef SHIBSP_LITE\r
#ifdef _DEBUG\r
- VALUE "InternalName", "shibsp-lite1_1D\0"\r
+ VALUE "InternalName", "shibsp-lite1_2D\0"\r
#else\r
- VALUE "InternalName", "shibsp-lite1_1\0"\r
+ VALUE "InternalName", "shibsp-lite1_2\0"\r
#endif\r
#else\r
#ifdef _DEBUG\r
- VALUE "InternalName", "shibsp1_1D\0"\r
+ VALUE "InternalName", "shibsp1_2D\0"\r
#else\r
- VALUE "InternalName", "shibsp1_1\0"\r
+ VALUE "InternalName", "shibsp1_2\0"\r
#endif\r
#endif\r
- VALUE "LegalCopyright", "Copyright © 2008 Internet2\0"\r
+ VALUE "LegalCopyright", "Copyright © 2009 Internet2\0"\r
VALUE "LegalTrademarks", "\0"\r
#ifdef SHIBSP_LITE\r
#ifdef _DEBUG\r
- VALUE "OriginalFilename", "shibsp-lite1_1D.dll\0"\r
+ VALUE "OriginalFilename", "shibsp-lite1_2D.dll\0"\r
#else\r
- VALUE "OriginalFilename", "shibsp-lite1_1.dll\0"\r
+ VALUE "OriginalFilename", "shibsp-lite1_2.dll\0"\r
#endif\r
#else\r
#ifdef _DEBUG\r
- VALUE "OriginalFilename", "shibsp1_1D.dll\0"\r
+ VALUE "OriginalFilename", "shibsp1_2D.dll\0"\r
#else\r
- VALUE "OriginalFilename", "shibsp1_1.dll\0"\r
+ VALUE "OriginalFilename", "shibsp1_2.dll\0"\r
#endif\r
#endif\r
VALUE "PrivateBuild", "\0"\r
- VALUE "ProductName", "Shibboleth 2.1\0"\r
- VALUE "ProductVersion", "2, 1, 0, 0\0"\r
+ VALUE "ProductName", "Shibboleth 2.2.1\0"\r
+ VALUE "ProductVersion", "2, 2, 1, 0\0"\r
VALUE "SpecialBuild", "\0"\r
END\r
END\r
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="8.00"\r
+ Version="9.00"\r
Name="shibsp"\r
ProjectGUID="{81F0F7A6-DC36-46EF-957F-F9E81D4403F6}"\r
RootNamespace="shibsp"\r
Keyword="Win32Proj"\r
+ TargetFrameworkVersion="131072"\r
>\r
<Platforms>\r
<Platform\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib xerces-c_2D.lib xsec_1D.lib saml2D.lib xmltooling1D.lib wsock32.lib"\r
- OutputFile="$(OutDir)\$(ProjectName)1_1D.dll"\r
+ AdditionalDependencies="log4shib1D.lib xerces-c_3D.lib xsec_1D.lib saml2D.lib xmltooling1D.lib wsock32.lib"\r
+ OutputFile="$(OutDir)\$(ProjectName)1_2D.dll"\r
LinkIncremental="2"\r
AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"\r
GenerateDebugInformation="true"\r
SubSystem="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
ImportLibrary="$(TargetDir)$(ProjectName)1D.lib"\r
TargetMachine="1"\r
/>\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib xerces-c_2D.lib xsec_1D.lib saml2D.lib xmltooling1D.lib wsock32.lib"\r
- OutputFile="$(OutDir)\$(ProjectName)1_1D.dll"\r
+ AdditionalDependencies="log4shib1D.lib xerces-c_3D.lib xsec_1D.lib saml2D.lib xmltooling1D.lib wsock32.lib"\r
+ OutputFile="$(OutDir)\$(ProjectName)1_2D.dll"\r
LinkIncremental="2"\r
AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
GenerateDebugInformation="true"\r
SubSystem="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
ImportLibrary="$(TargetDir)$(ProjectName)1D.lib"\r
TargetMachine="17"\r
/>\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib xerces-c_2.lib xsec_1.lib saml2.lib xmltooling1.lib wsock32.lib"\r
- OutputFile="$(OutDir)\$(ProjectName)1_1.dll"\r
+ AdditionalDependencies="log4shib1.lib xerces-c_3.lib xsec_1.lib saml2.lib xmltooling1.lib wsock32.lib"\r
+ OutputFile="$(OutDir)\$(ProjectName)1_2.dll"\r
LinkIncremental="1"\r
AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"\r
SubSystem="2"\r
OptimizeReferences="2"\r
EnableCOMDATFolding="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
ImportLibrary="$(TargetDir)$(ProjectName)1.lib"\r
TargetMachine="1"\r
/>\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib xerces-c_2.lib xsec_1.lib saml2.lib xmltooling1.lib wsock32.lib"\r
- OutputFile="$(OutDir)\$(ProjectName)1_1.dll"\r
+ AdditionalDependencies="log4shib1.lib xerces-c_3.lib xsec_1.lib saml2.lib xmltooling1.lib wsock32.lib"\r
+ OutputFile="$(OutDir)\$(ProjectName)1_2.dll"\r
LinkIncremental="1"\r
AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
GenerateDebugInformation="true"\r
SubSystem="2"\r
OptimizeReferences="2"\r
EnableCOMDATFolding="2"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
ImportLibrary="$(TargetDir)$(ProjectName)1.lib"\r
TargetMachine="17"\r
/>\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
Name="impl"\r
>\r
<File\r
+ RelativePath=".\impl\ChainingAccessControl.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\impl\StorageServiceSessionCache.cpp"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath=".\attribute\DOMAttributeDecoder.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\attribute\ExtensibleAttribute.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\attribute\KeyInfoAttributeDecoder.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\attribute\NameIDAttributeDecoder.cpp"\r
>\r
</File>\r
RelativePath=".\attribute\StringAttributeDecoder.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\attribute\XMLAttributeDecoder.cpp"\r
+ >\r
+ </File>\r
<Filter\r
Name="resolver"\r
>\r
>\r
</File>\r
<File\r
+ RelativePath=".\attribute\resolver\impl\DelegationAttributeExtractor.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\attribute\resolver\impl\KeyDescriptorAttributeExtractor.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\attribute\resolver\impl\QueryAttributeResolver.cpp"\r
>\r
</File>\r
<File\r
+ RelativePath=".\attribute\resolver\impl\SimpleAggregationAttributeResolver.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\attribute\resolver\impl\XMLAttributeExtractor.cpp"\r
>\r
</File>\r
>\r
</File>\r
<File\r
- RelativePath=".\ApplicationAwarePlugin.h"\r
- >\r
- </File>\r
- <File\r
RelativePath=".\base.h"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath=".\attribute\ExtensibleAttribute.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\attribute\NameIDAttribute.h"\r
>\r
</File>\r
RelativePath=".\attribute\SimpleAttribute.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\attribute\XMLAttribute.h"\r
+ >\r
+ </File>\r
<Filter\r
Name="resolver"\r
>\r
pair<CGIParser::walker,CGIParser::walker> CGIParser::getParameters(const char* name) const
{
- return kvp_map.equal_range(name);
+ if (name)
+ return kvp_map.equal_range(name);
+ return make_pair(kvp_map.begin(), kvp_map.end());
}
/* Parsing routines modified from NCSA source. */
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/**
* Returns a pair of bounded iterators around the values of a parameter.
*
- * @param name name of parameter
+ * @param name name of parameter, or NULL to return all parameters
* @return a pair of multimap iterators surrounding the matching value(s)
*/
std::pair<walker,walker> getParameters(const char* name) const;
/*
- * Copyright 2001-2007 Internet2
- *
+ * Copyright 2001-2009 Internet2
+ *
* 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
/**
* version.h
- *
- * Library version macros and constants
+ *
+ * Library version macros and constants
*/
#ifndef __shibsp_version_h__
// V E R S I O N S P E C I F I C A T I O N
/**
- * MODIFY THESE NUMERIC VALUES TO COINCIDE WITH OPENSAML VERSION
+ * MODIFY THESE NUMERIC VALUES TO COINCIDE WITH SHIBSP LIBRARY VERSION
* AND DO NOT MODIFY ANYTHING ELSE IN THIS VERSION HEADER FILE
*/
#define SHIBSP_VERSION_MAJOR 1
-#define SHIBSP_VERSION_MINOR 0
+#define SHIBSP_VERSION_MINOR 2
#define SHIBSP_VERSION_REVISION 1
/** DO NOT MODIFY BELOW THIS LINE */
\r
if (!entityID) {\r
usage();\r
- exit(-10);\r
+ return -10;\r
}\r
\r
- char* path=getenv("SHIBSP_SCHEMAS");\r
- if (!path)\r
- path=SHIBSP_SCHEMAS;\r
- char* config=getenv("SHIBSP_CONFIG");\r
- if (!config)\r
- config=SHIBSP_CONFIG;\r
-\r
- XMLToolingConfig::getConfig().log_config(getenv("SHIBSP_LOGGING") ? getenv("SHIBSP_LOGGING") : SHIBSP_LOGGING);\r
-\r
- SPConfig& conf=SPConfig::getConfig();\r
- conf.setFeatures(SPConfig::Metadata | SPConfig::Trust | SPConfig::OutOfProcess | SPConfig::Credentials);\r
- if (!conf.init(path))\r
- return -1;\r
-\r
if (rname) {\r
if (!protocol) {\r
if (prot)\r
protocol = XMLString::transcode(prot);\r
}\r
if (!protocol) {\r
- conf.term();\r
usage();\r
- exit(-10);\r
+ return -10;\r
}\r
}\r
\r
- try {\r
- static const XMLCh _path[] = UNICODE_LITERAL_4(p,a,t,h);\r
- static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);\r
- xercesc::DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();\r
- XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);\r
- xercesc::DOMElement* dummy = dummydoc->createElementNS(NULL,_path);\r
- auto_ptr_XMLCh src(config);\r
- dummy->setAttributeNS(NULL,_path,src.get());\r
- dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);\r
- conf.setServiceProvider(conf.ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));\r
- conf.getServiceProvider()->init();\r
- }\r
- catch (exception&) {\r
+ SPConfig& conf=SPConfig::getConfig();\r
+ conf.setFeatures(SPConfig::Metadata | SPConfig::Trust | SPConfig::OutOfProcess | SPConfig::Credentials);\r
+ if (!conf.init())\r
+ return -1;\r
+ if (!conf.instantiate()) {\r
conf.term();\r
return -2;\r
}\r
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="8.00"\r
+ Version="9.00"\r
Name="mdquery"\r
ProjectGUID="{F13141B6-6C87-40BB-8D4E-5CC56EBB4C5A}"\r
RootNamespace="mdquery"\r
+ TargetFrameworkVersion="131072"\r
>\r
<Platforms>\r
<Platform\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib saml2.lib xmltooling1.lib xerces-c_2.lib"\r
+ AdditionalDependencies="log4shib1.lib saml2.lib xmltooling1.lib xerces-c_3.lib"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"\r
SubSystem="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
- IntermediateDirectory="$(ConfigurationName)"\r
+ Name="Release|x64"\r
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="1"\r
UseOfMFC="0"\r
ATLMinimizesCRunTimeLibraryUsage="false"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
HeaderFileName=""\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="0"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="1"\r
AdditionalIncludeDirectories=".;..;"..\..\cpp-opensaml2";"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="_CONSOLE;WIN32;_DEBUG"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="3"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"\r
+ StringPooling="true"\r
+ RuntimeLibrary="2"\r
+ EnableFunctionLevelLinking="true"\r
RuntimeTypeInfo="true"\r
- BrowseInformation="1"\r
WarningLevel="3"\r
SuppressStartupBanner="true"\r
Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
CompileAs="0"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="_DEBUG"\r
+ PreprocessorDefinitions="NDEBUG"\r
Culture="1033"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib saml2D.lib xmltooling1D.lib xerces-c_2D.lib"\r
- LinkIncremental="2"\r
+ AdditionalDependencies="log4shib1.lib saml2.lib xmltooling1.lib xerces-c_3.lib"\r
+ LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"\r
- GenerateDebugInformation="true"\r
+ AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
SubSystem="1"\r
- TargetMachine="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="17"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Release|x64"\r
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ Name="Debug|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ConfigurationName)"\r
ConfigurationType="1"\r
UseOfMFC="0"\r
ATLMinimizesCRunTimeLibraryUsage="false"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TargetEnvironment="3"\r
HeaderFileName=""\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="2"\r
- InlineFunctionExpansion="1"\r
+ Optimization="0"\r
AdditionalIncludeDirectories=".;..;"..\..\cpp-opensaml2";"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"\r
- StringPooling="true"\r
- RuntimeLibrary="2"\r
- EnableFunctionLevelLinking="true"\r
+ PreprocessorDefinitions="_CONSOLE;WIN32;_DEBUG"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="3"\r
RuntimeTypeInfo="true"\r
+ BrowseInformation="1"\r
WarningLevel="3"\r
SuppressStartupBanner="true"\r
Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="4"\r
CompileAs="0"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="NDEBUG"\r
+ PreprocessorDefinitions="_DEBUG"\r
Culture="1033"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib saml2.lib xmltooling1.lib xerces-c_2.lib"\r
- LinkIncremental="1"\r
+ AdditionalDependencies="log4shib1D.lib saml2D.lib xmltooling1D.lib xerces-c_3D.lib"\r
+ LinkIncremental="2"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
+ AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"\r
+ GenerateDebugInformation="true"\r
SubSystem="1"\r
- TargetMachine="17"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="1"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib saml2D.lib xmltooling1D.lib xerces-c_2D.lib"\r
+ AdditionalDependencies="log4shib1D.lib saml2D.lib xmltooling1D.lib xerces-c_3D.lib"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
GenerateDebugInformation="true"\r
SubSystem="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="17"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
char* i_param=NULL;
char* prot = NULL;
const XMLCh* protocol = NULL;
- char* path=NULL;
- char* config=NULL;
for (int i=1; i<argc; i++) {
if (!strcmp(argv[i],"-n") && i+1<argc)
if (n_param && !i_param) {
usage();
- exit(-10);
+ return -10;
}
- path=getenv("SHIBSP_SCHEMAS");
- if (!path)
- path=SHIBSP_SCHEMAS;
- config=getenv("SHIBSP_CONFIG");
- if (!config)
- config=SHIBSP_CONFIG;
if (!a_param)
a_param="default";
- XMLToolingConfig::getConfig().log_config(getenv("SHIBSP_LOGGING") ? getenv("SHIBSP_LOGGING") : SHIBSP_LOGGING);
-
- SPConfig& conf=SPConfig::getConfig();
- conf.setFeatures(
- SPConfig::Metadata |
- SPConfig::Trust |
- SPConfig::AttributeResolution |
- SPConfig::Credentials |
- SPConfig::OutOfProcess
- );
- if (!conf.init(path))
- return -1;
-
if (n_param) {
if (!protocol) {
if (prot)
protocol = XMLString::transcode(prot);
}
if (!protocol) {
- conf.term();
usage();
- exit(-10);
+ return -10;
}
}
-
- try {
- static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);
- static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);
- xercesc::DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();
- XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);
- xercesc::DOMElement* dummy = dummydoc->createElementNS(NULL,path);
- auto_ptr_XMLCh src(config);
- dummy->setAttributeNS(NULL,path,src.get());
- dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);
- conf.setServiceProvider(conf.ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));
- conf.getServiceProvider()->init();
- }
- catch (exception&) {
+ SPConfig& conf=SPConfig::getConfig();
+ conf.setFeatures(
+ SPConfig::Metadata |
+ SPConfig::Trust |
+ SPConfig::AttributeResolution |
+ SPConfig::Credentials |
+ SPConfig::OutOfProcess
+ );
+ if (!conf.init())
+ return -1;
+ if (!conf.instantiate()) {
conf.term();
return -2;
}
protocol = samlconstants::SAML11_PROTOCOL_ENUM;
v1name = a1->getAuthenticationStatements().size() ?
a1->getAuthenticationStatements().front()->getSubject()->getNameIdentifier() : NULL;
- // Normalize the SAML 1.x NameIdentifier...
- v2name = saml2::NameIDBuilder::buildNameID();
- v2name->setName(v1name->getName());
- v2name->setFormat(v1name->getFormat());
- v2name->setNameQualifier(v1name->getNameQualifier());
+ if (!v1name)
+ v1name = a1->getAttributeStatements().size() ?
+ a1->getAttributeStatements().front()->getSubject()->getNameIdentifier() : NULL;
+ if (v1name) {
+ // Normalize the SAML 1.x NameIdentifier...
+ v2name = saml2::NameIDBuilder::buildNameID();
+ v2name->setName(v1name->getName());
+ v2name->setFormat(v1name->getFormat());
+ v2name->setNameQualifier(v1name->getNameQualifier());
+ }
}
else {
throw FatalProfileException("Unknown assertion type.");
}
- if (!issuer) {
- if (v1name)
- delete v2name;
+ auto_ptr<saml2::NameID> nameidwrapper(v1name ? v2name : NULL);
+
+ if (!issuer)
throw FatalProfileException("Unable to determine issuer.");
- }
MetadataProvider* m=app->getMetadataProvider();
xmltooling::Locker mlocker(m);
vector<const Assertion*> tokens(1, dynamic_cast<Assertion*>(token.get()));
ResolverTest rt(NULL, a_param);
- try {
- ctx = rt.resolveAttributes(*app, site.second, protocol, v1name, v2name, NULL, NULL, &tokens);
- }
- catch (...) {
- if (v1name)
- delete v2name;
- throw;
- }
+ ctx = rt.resolveAttributes(*app, site.second, protocol, v1name, v2name, NULL, NULL, &tokens);
}
auto_ptr<ResolutionContext> wrapper(ctx);
for (vector<Attribute*>::const_iterator a = ctx->getResolvedAttributes().begin(); a != ctx->getResolvedAttributes().end(); ++a) {
- cout << endl;
- for (vector<string>::const_iterator s = (*a)->getAliases().begin(); s != (*a)->getAliases().end(); ++s)
- cout << "ID: " << *s << endl;
- for (vector<string>::const_iterator s = (*a)->getSerializedValues().begin(); s != (*a)->getSerializedValues().end(); ++s)
- cout << "Value: " << *s << endl;
+ for (vector<string>::const_iterator s = (*a)->getAliases().begin(); s != (*a)->getAliases().end(); ++s) {
+ cout << *s << ": ";
+ for (vector<string>::const_iterator v = (*a)->getSerializedValues().begin(); v != (*a)->getSerializedValues().end(); ++v) {
+ if (v != (*a)->getSerializedValues().begin())
+ cout << ';';
+ cout << *v;
+ }
+ cout << endl;
+ }
}
cout << endl;
}
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="8.00"\r
+ Version="9.00"\r
Name="resolvertest"\r
ProjectGUID="{F13141B6-6C87-40BB-8D4E-5CC56EBB4C59}"\r
RootNamespace="resolvertest"\r
+ TargetFrameworkVersion="131072"\r
>\r
<Platforms>\r
<Platform\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib saml2.lib xmltooling1.lib xerces-c_2.lib"\r
+ AdditionalDependencies="log4shib1.lib saml2.lib xmltooling1.lib xerces-c_3.lib"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"\r
SubSystem="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="1"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
- IntermediateDirectory="$(ConfigurationName)"\r
+ Name="Release|x64"\r
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="1"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="0"\r
ATLMinimizesCRunTimeLibraryUsage="false"\r
CharacterSet="2"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
HeaderFileName=""\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="0"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="1"\r
AdditionalIncludeDirectories=".;..;"..\..\cpp-opensaml2";"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="_CONSOLE;WIN32;_DEBUG"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="3"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"\r
+ StringPooling="true"\r
+ RuntimeLibrary="2"\r
+ EnableFunctionLevelLinking="true"\r
RuntimeTypeInfo="true"\r
- BrowseInformation="1"\r
WarningLevel="3"\r
SuppressStartupBanner="true"\r
Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
CompileAs="0"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="_DEBUG"\r
+ PreprocessorDefinitions="NDEBUG"\r
Culture="1033"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib saml2D.lib xmltooling1D.lib xerces-c_2D.lib"\r
- LinkIncremental="2"\r
+ AdditionalDependencies="log4shib1.lib saml2.lib xmltooling1.lib xerces-c_3.lib"\r
+ LinkIncremental="1"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"\r
- GenerateDebugInformation="true"\r
+ AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
SubSystem="1"\r
- TargetMachine="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="17"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
<Configuration\r
- Name="Release|x64"\r
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ Name="Debug|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ConfigurationName)"\r
ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="0"\r
ATLMinimizesCRunTimeLibraryUsage="false"\r
CharacterSet="2"\r
/>\r
<Tool\r
Name="VCMIDLTool"\r
- TargetEnvironment="3"\r
HeaderFileName=""\r
/>\r
<Tool\r
Name="VCCLCompilerTool"\r
- Optimization="2"\r
- InlineFunctionExpansion="1"\r
+ Optimization="0"\r
AdditionalIncludeDirectories=".;..;"..\..\cpp-opensaml2";"..\..\cpp-xmltooling""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"\r
- StringPooling="true"\r
- RuntimeLibrary="2"\r
- EnableFunctionLevelLinking="true"\r
+ PreprocessorDefinitions="_CONSOLE;WIN32;_DEBUG"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="3"\r
RuntimeTypeInfo="true"\r
+ BrowseInformation="1"\r
WarningLevel="3"\r
SuppressStartupBanner="true"\r
Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="4"\r
CompileAs="0"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
- PreprocessorDefinitions="NDEBUG"\r
+ PreprocessorDefinitions="_DEBUG"\r
Culture="1033"\r
/>\r
<Tool\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1.lib saml2.lib xmltooling1.lib xerces-c_2.lib"\r
- LinkIncremental="1"\r
+ AdditionalDependencies="log4shib1D.lib saml2D.lib xmltooling1D.lib xerces-c_3D.lib"\r
+ LinkIncremental="2"\r
SuppressStartupBanner="true"\r
- AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
+ AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(ConfigurationName);..\..\cpp-xmltooling\$(ConfigurationName)"\r
+ GenerateDebugInformation="true"\r
SubSystem="1"\r
- TargetMachine="17"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
+ TargetMachine="1"\r
/>\r
<Tool\r
Name="VCALinkTool"\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4shib1D.lib saml2D.lib xmltooling1D.lib xerces-c_2D.lib"\r
+ AdditionalDependencies="log4shib1D.lib saml2D.lib xmltooling1D.lib xerces-c_3D.lib"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
AdditionalLibraryDirectories="..\..\cpp-opensaml2\$(PlatformName)\$(ConfigurationName);..\..\cpp-xmltooling\$(PlatformName)\$(ConfigurationName)"\r
GenerateDebugInformation="true"\r
SubSystem="1"\r
+ RandomizedBaseAddress="1"\r
+ DataExecutionPrevention="0"\r
TargetMachine="17"\r
/>\r
<Tool\r
Name="VCAppVerifierTool"\r
/>\r
<Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
Name="VCPostBuildEventTool"\r
/>\r
</Configuration>\r