summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTE.md52
-rw-r--r--README.md2
-rw-r--r--TESTING.md64
-rw-r--r--attributemap/windowslive2name.php8
-rwxr-xr-xbin/memcacheSync.php4
-rw-r--r--cache/.gitkeep0
-rw-r--r--composer.json7
-rw-r--r--composer.lock209
-rw-r--r--config-templates/authsources.php4
-rw-r--r--config-templates/cas-ldap.php38
-rw-r--r--config-templates/config-login-auto.php63
-rw-r--r--config-templates/config-login-feide.php37
-rw-r--r--config-templates/config.php27
-rw-r--r--config-templates/ldap.php42
-rw-r--r--config-templates/ldapmulti.php31
-rw-r--r--config-templates/translation.php14
-rw-r--r--docs/index.md (renamed from docs/index.txt)0
-rw-r--r--docs/simplesamlphp-advancedfeatures.md (renamed from docs/simplesamlphp-advancedfeatures.txt)7
-rw-r--r--docs/simplesamlphp-artifact-idp.md (renamed from docs/simplesamlphp-artifact-idp.txt)0
-rw-r--r--docs/simplesamlphp-artifact-sp.md (renamed from docs/simplesamlphp-artifact-sp.txt)0
-rw-r--r--docs/simplesamlphp-authproc.md (renamed from docs/simplesamlphp-authproc.txt)0
-rw-r--r--docs/simplesamlphp-authsource.md (renamed from docs/simplesamlphp-authsource.txt)0
-rw-r--r--docs/simplesamlphp-automated_metadata.md (renamed from docs/simplesamlphp-automated_metadata.txt)0
-rw-r--r--docs/simplesamlphp-changelog.md (renamed from docs/simplesamlphp-changelog.txt)57
-rw-r--r--docs/simplesamlphp-customauth.md (renamed from docs/simplesamlphp-customauth.txt)0
-rw-r--r--docs/simplesamlphp-database.md (renamed from docs/simplesamlphp-database.txt)0
-rw-r--r--docs/simplesamlphp-errorhandling.md (renamed from docs/simplesamlphp-errorhandling.txt)0
-rw-r--r--docs/simplesamlphp-googleapps.md (renamed from docs/simplesamlphp-googleapps.txt)0
-rw-r--r--docs/simplesamlphp-hok-idp.md (renamed from docs/simplesamlphp-hok-idp.txt)0
-rw-r--r--docs/simplesamlphp-hok-sp.md (renamed from docs/simplesamlphp-hok-sp.txt)0
-rw-r--r--docs/simplesamlphp-idp-more.md (renamed from docs/simplesamlphp-idp-more.txt)2
-rw-r--r--docs/simplesamlphp-idp.md (renamed from docs/simplesamlphp-idp.txt)0
-rw-r--r--docs/simplesamlphp-install-repo.md (renamed from docs/simplesamlphp-install-repo.txt)0
-rw-r--r--docs/simplesamlphp-install.md (renamed from docs/simplesamlphp-install.txt)24
-rw-r--r--docs/simplesamlphp-maintenance.md (renamed from docs/simplesamlphp-maintenance.txt)0
-rw-r--r--docs/simplesamlphp-metadata-endpoints.md (renamed from docs/simplesamlphp-metadata-endpoints.txt)0
-rw-r--r--docs/simplesamlphp-metadata-extensions-attributes.md (renamed from docs/simplesamlphp-metadata-extensions-attributes.txt)0
-rw-r--r--docs/simplesamlphp-metadata-extensions-rpi.md (renamed from docs/simplesamlphp-metadata-extensions-rpi.txt)0
-rw-r--r--docs/simplesamlphp-metadata-extensions-ui.md (renamed from docs/simplesamlphp-metadata-extensions-ui.txt)0
-rw-r--r--docs/simplesamlphp-metadata-pdostoragehandler.md (renamed from docs/simplesamlphp-metadata-pdostoragehandler.txt)0
-rw-r--r--docs/simplesamlphp-modules.md (renamed from docs/simplesamlphp-modules.txt)0
-rw-r--r--docs/simplesamlphp-nostate.md (renamed from docs/simplesamlphp-nostate.txt)0
-rw-r--r--docs/simplesamlphp-reference-idp-hosted.md (renamed from docs/simplesamlphp-reference-idp-hosted.txt)0
-rw-r--r--docs/simplesamlphp-reference-idp-remote.md (renamed from docs/simplesamlphp-reference-idp-remote.txt)19
-rw-r--r--docs/simplesamlphp-reference-sp-remote.md (renamed from docs/simplesamlphp-reference-sp-remote.txt)0
-rw-r--r--docs/simplesamlphp-scoping.md (renamed from docs/simplesamlphp-scoping.txt)0
-rw-r--r--docs/simplesamlphp-sp-api.md (renamed from docs/simplesamlphp-sp-api.txt)0
-rw-r--r--docs/simplesamlphp-sp-migration.md (renamed from docs/simplesamlphp-sp-migration.txt)0
-rw-r--r--docs/simplesamlphp-sp.md (renamed from docs/simplesamlphp-sp.txt)49
-rw-r--r--docs/simplesamlphp-theming.md (renamed from docs/simplesamlphp-theming.txt)0
-rw-r--r--docs/simplesamlphp-translation.md91
-rw-r--r--docs/simplesamlphp-translation.txt196
-rw-r--r--docs/simplesamlphp-upgrade-notes-1.10.md (renamed from docs/simplesamlphp-upgrade-notes-1.10.txt)0
-rw-r--r--docs/simplesamlphp-upgrade-notes-1.11.md (renamed from docs/simplesamlphp-upgrade-notes-1.11.txt)0
-rw-r--r--docs/simplesamlphp-upgrade-notes-1.12.md (renamed from docs/simplesamlphp-upgrade-notes-1.12.txt)0
-rw-r--r--docs/simplesamlphp-upgrade-notes-1.13.md (renamed from docs/simplesamlphp-upgrade-notes-1.13.txt)0
-rw-r--r--docs/simplesamlphp-upgrade-notes-1.14.md (renamed from docs/simplesamlphp-upgrade-notes-1.14.txt)11
-rw-r--r--docs/simplesamlphp-upgrade-notes-1.5.md (renamed from docs/simplesamlphp-upgrade-notes-1.5.txt)0
-rw-r--r--docs/simplesamlphp-upgrade-notes-1.6.md (renamed from docs/simplesamlphp-upgrade-notes-1.6.txt)0
-rw-r--r--docs/simplesamlphp-upgrade-notes-1.7.md (renamed from docs/simplesamlphp-upgrade-notes-1.7.txt)0
-rw-r--r--docs/simplesamlphp-upgrade-notes-1.8.md (renamed from docs/simplesamlphp-upgrade-notes-1.8.txt)0
-rw-r--r--docs/simplesamlphp-upgrade-notes-1.9.md (renamed from docs/simplesamlphp-upgrade-notes-1.9.txt)0
-rw-r--r--lib/SimpleSAML/Auth/Simple.php658
-rw-r--r--lib/SimpleSAML/Bindings/Shib13/Artifact.php4
-rw-r--r--lib/SimpleSAML/Bindings/Shib13/HTTPPost.php2
-rw-r--r--lib/SimpleSAML/Configuration.php66
-rw-r--r--lib/SimpleSAML/Error/CannotSetCookie.php36
-rw-r--r--lib/SimpleSAML/Error/CriticalConfigurationError.php1
-rw-r--r--lib/SimpleSAML/Error/Error.php6
-rw-r--r--lib/SimpleSAML/Error/Exception.php2
-rw-r--r--lib/SimpleSAML/Locale/Language.php59
-rw-r--r--lib/SimpleSAML/Locale/Translate.php20
-rw-r--r--lib/SimpleSAML/Logger.php11
-rw-r--r--lib/SimpleSAML/Metadata/MetaDataStorageHandler.php9
-rw-r--r--lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php10
-rw-r--r--lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php4
-rw-r--r--lib/SimpleSAML/Metadata/SAMLBuilder.php90
-rw-r--r--lib/SimpleSAML/Metadata/SAMLParser.php124
-rw-r--r--lib/SimpleSAML/Metadata/Signer.php72
-rw-r--r--lib/SimpleSAML/Session.php143
-rw-r--r--lib/SimpleSAML/SessionHandler.php38
-rw-r--r--lib/SimpleSAML/SessionHandlerCookie.php27
-rw-r--r--lib/SimpleSAML/SessionHandlerPHP.php76
-rw-r--r--lib/SimpleSAML/Store/SQL.php662
-rw-r--r--lib/SimpleSAML/Utilities.php4
-rw-r--r--lib/SimpleSAML/Utils/HTTP.php135
-rw-r--r--lib/SimpleSAML/Utils/XML.php7
-rw-r--r--lib/SimpleSAML/XHTML/IdPDisco.php2
-rw-r--r--lib/SimpleSAML/XHTML/Template.php289
-rw-r--r--lib/SimpleSAML/XML/Shib13/AuthnResponse.php8
-rw-r--r--lib/_autoload_modules.php8
-rw-r--r--modules/adfs/docs/adfs.md (renamed from modules/adfs/docs/adfs.txt)0
-rw-r--r--modules/adfs/lib/IdP/ADFS.php2
-rw-r--r--modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php2
-rw-r--r--modules/adfs/lib/XMLSecurityDSig.php2
-rw-r--r--modules/adfs/www/idp/metadata.php4
-rw-r--r--modules/authX509/docs/authX509.md (renamed from modules/authX509/docs/authX509.txt)0
-rw-r--r--modules/authcrypt/docs/authcrypt.md (renamed from modules/authcrypt/docs/authcrypt.txt)0
-rw-r--r--modules/authfacebook/docs/authfacebook.md (renamed from modules/authfacebook/docs/authfacebook.txt)0
-rw-r--r--modules/authlinkedin/docs/oauthlinkedin.md (renamed from modules/authlinkedin/docs/oauthlinkedin.txt)0
-rw-r--r--modules/authmyspace/docs/oauthmyspace.md (renamed from modules/authmyspace/docs/oauthmyspace.txt)0
-rw-r--r--modules/authorize/docs/authorize.md (renamed from modules/authorize/docs/authorize.txt)0
-rw-r--r--modules/authtwitter/docs/oauthtwitter.md (renamed from modules/authtwitter/docs/oauthtwitter.txt)0
-rw-r--r--modules/authwindowslive/docs/windowsliveid.md (renamed from modules/authwindowslive/docs/windowsliveid.txt)0
-rw-r--r--modules/authwindowslive/lib/Auth/Source/LiveID.php283
-rw-r--r--modules/authwindowslive/www/linkback.php47
-rw-r--r--modules/cas/docs/cas.md (renamed from modules/cas/docs/cas.txt)0
-rw-r--r--modules/cas/lib/Auth/Source/CAS.php2
-rw-r--r--modules/consent/docs/consent.md (renamed from modules/consent/docs/consent.txt)0
-rw-r--r--modules/consent/lib/Consent/Store/Cookie.php2
-rw-r--r--modules/consentAdmin/docs/consentAdmin.md (renamed from modules/consentAdmin/docs/consentAdmin.txt)0
-rw-r--r--modules/core/dictionaries/frontpage.definition.json5
-rw-r--r--modules/core/dictionaries/frontpage.translation.json6
-rw-r--r--modules/core/docs/authproc_attributeadd.md (renamed from modules/core/docs/authproc_attributeadd.txt)0
-rw-r--r--modules/core/docs/authproc_attributealter.md (renamed from modules/core/docs/authproc_attributealter.txt)0
-rw-r--r--modules/core/docs/authproc_attributecopy.md (renamed from modules/core/docs/authproc_attributecopy.txt)0
-rw-r--r--modules/core/docs/authproc_attributelimit.md (renamed from modules/core/docs/authproc_attributelimit.txt)0
-rw-r--r--modules/core/docs/authproc_attributemap.md (renamed from modules/core/docs/authproc_attributemap.txt)0
-rw-r--r--modules/core/docs/authproc_attributerealm.md (renamed from modules/core/docs/authproc_attributerealm.txt)0
-rw-r--r--modules/core/docs/authproc_attributevaluemap.md (renamed from modules/core/docs/authproc_attributevaluemap.txt)0
-rw-r--r--modules/core/docs/authproc_generategroups.md (renamed from modules/core/docs/authproc_generategroups.txt)0
-rw-r--r--modules/core/docs/authproc_languageadaptor.md (renamed from modules/core/docs/authproc_languageadaptor.txt)0
-rw-r--r--modules/core/docs/authproc_php.md (renamed from modules/core/docs/authproc_php.txt)0
-rw-r--r--modules/core/docs/authproc_scopeattribute.md (renamed from modules/core/docs/authproc_scopeattribute.txt)6
-rw-r--r--modules/core/docs/authproc_scopefromattribute.md (renamed from modules/core/docs/authproc_scopefromattribute.txt)0
-rw-r--r--modules/core/docs/authproc_statisticswithattribute.md (renamed from modules/core/docs/authproc_statisticswithattribute.txt)0
-rw-r--r--modules/core/docs/authproc_targetedid.md (renamed from modules/core/docs/authproc_targetedid.txt)0
-rw-r--r--modules/core/docs/authproc_warnshortssointerval.md (renamed from modules/core/docs/authproc_warnshortssointerval.txt)0
-rw-r--r--modules/core/lib/Auth/Process/ScopeAttribute.php14
-rw-r--r--modules/core/lib/Auth/Process/TargetedID.php6
-rw-r--r--modules/core/lib/Stats/Output/Log.php2
-rw-r--r--modules/core/templates/frontpage_config.tpl.php6
-rw-r--r--modules/core/templates/no_cookie.tpl.php12
-rw-r--r--modules/core/www/as_login.php4
-rw-r--r--modules/core/www/authenticate.php9
-rw-r--r--modules/core/www/cleardiscochoices.php2
-rw-r--r--modules/core/www/frontpage_config.php40
-rw-r--r--modules/core/www/frontpage_federation.php4
-rw-r--r--modules/core/www/idp/logout-iframe-post.php4
-rw-r--r--modules/core/www/no_cookie.php6
-rw-r--r--modules/cron/templates/croninfo.tpl.php (renamed from modules/cron/templates/croninfo-tpl.php)0
-rw-r--r--modules/cron/www/croninfo.php2
-rw-r--r--modules/discopower/lib/PowerIdPDisco.php2
-rw-r--r--modules/discopower/templates/disco.tpl.php (renamed from modules/discopower/templates/disco-tpl.php)0
-rw-r--r--modules/exampleattributeserver/www/attributeserver.php18
-rw-r--r--modules/expirycheck/docs/expirycheck.md (renamed from modules/expirycheck/docs/expirycheck.txt)0
-rw-r--r--modules/ldap/docs/ldap.md (renamed from modules/ldap/docs/ldap.txt)11
-rw-r--r--modules/ldap/lib/Auth/Process/BaseFilter.php1
-rw-r--r--modules/memcacheMonitor/dictionaries/memcachestat.definition.json53
-rw-r--r--modules/memcacheMonitor/templates/memcachestat.tpl.php2
-rw-r--r--modules/metarefresh/lib/MetaLoader.php2
-rw-r--r--modules/multiauth/docs/multiauth.md (renamed from modules/multiauth/docs/multiauth.txt)0
-rw-r--r--modules/multiauth/lib/Auth/Source/MultiAuth.php2
-rw-r--r--modules/negotiate/docs/negotiate.md (renamed from modules/negotiate/docs/negotiate.txt)2
-rw-r--r--modules/portal/lib/Portal.php4
-rw-r--r--modules/radius/docs/radius.md (renamed from modules/radius/docs/radius.txt)0
-rw-r--r--modules/riak/docs/simplesamlphp-riak.md (renamed from modules/riak/docs/simplesamlphp-riak.txt)0
-rw-r--r--modules/saml/docs/authproc_expectedauthncontextclassref.md (renamed from modules/saml/docs/authproc_expectedauthncontextclassref.txt)0
-rw-r--r--modules/saml/docs/keyrollover.md (renamed from modules/saml/docs/keyrollover.txt)0
-rw-r--r--modules/saml/docs/nameid.md (renamed from modules/saml/docs/nameid.txt)0
-rw-r--r--modules/saml/docs/nameidattribute.md (renamed from modules/saml/docs/nameidattribute.txt)0
-rw-r--r--modules/saml/docs/sp.md (renamed from modules/saml/docs/sp.txt)4
-rw-r--r--modules/saml/lib/Auth/Process/NameIDAttribute.php2
-rw-r--r--modules/saml/lib/Auth/Process/PersistentNameID.php2
-rw-r--r--modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php8
-rw-r--r--modules/saml/lib/Auth/Process/SQLPersistentNameID.php4
-rw-r--r--modules/saml/lib/Auth/Process/TransientNameID.php2
-rw-r--r--modules/saml/lib/Auth/Source/SP.php22
-rw-r--r--modules/saml/lib/Error.php14
-rw-r--r--modules/saml/lib/IdP/SAML2.php86
-rw-r--r--modules/saml/lib/Message.php86
-rw-r--r--modules/saml/www/sp/metadata.php12
-rw-r--r--modules/saml/www/sp/saml2-acs.php10
-rw-r--r--modules/saml/www/sp/saml2-logout.php16
-rw-r--r--modules/sanitycheck/templates/check.tpl.php (renamed from modules/sanitycheck/templates/check-tpl.php)0
-rw-r--r--modules/sanitycheck/www/index.php2
-rw-r--r--modules/smartattributes/docs/smartattributes.md (renamed from modules/smartattributes/docs/smartattributes.txt)0
-rw-r--r--modules/sqlauth/docs/sql.md (renamed from modules/sqlauth/docs/sql.txt)0
-rw-r--r--modules/statistics/docs/statistics.md (renamed from modules/statistics/docs/statistics.txt)0
-rw-r--r--modules/statistics/lib/StatDataset.php2
-rw-r--r--modules/statistics/templates/statistics.tpl.php (renamed from modules/statistics/templates/statistics-tpl.php)0
-rw-r--r--modules/statistics/templates/statmeta.tpl.php (renamed from modules/statistics/templates/statmeta-tpl.php)0
-rw-r--r--modules/statistics/www/showstats.php2
-rw-r--r--modules/statistics/www/statmeta.php2
-rw-r--r--templates/_footer.twig.html6
-rw-r--r--templates/_header.twig.html14
-rw-r--r--templates/base.twig.html31
-rw-r--r--templates/includes/attributes.php27
-rw-r--r--templates/index.twig.html33
-rw-r--r--templates/sandbox.twig.html6
-rw-r--r--templates/selectidp-dropdown.php15
-rw-r--r--tests/BuiltInServer.php201
-rw-r--r--tests/lib/SimpleSAML/ConfigurationTest.php214
-rw-r--r--tests/lib/SimpleSAML/Metadata/SAMLParserTest.php4
-rw-r--r--tests/lib/SimpleSAML/Utils/HTTPTest.php278
-rw-r--r--tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php23
-rw-r--r--tests/routers/configLoader.php41
-rw-r--r--tests/www/IndexTest.php127
-rw-r--r--www/_include.php19
-rw-r--r--www/admin/index.php27
-rw-r--r--www/admin/sandbox.php19
-rw-r--r--www/logout.php3
-rw-r--r--www/module.php207
-rw-r--r--www/saml2/idp/ArtifactResolutionService.php12
-rw-r--r--www/saml2/idp/SingleLogoutService.php2
-rw-r--r--www/saml2/idp/metadata.php32
206 files changed, 3743 insertions, 2074 deletions
diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md
index 679aa6f..0fd98ff 100644
--- a/CONTRIBUTE.md
+++ b/CONTRIBUTE.md
@@ -6,6 +6,8 @@ people, so please don't be shy and share your help with us. Even the tiniest con
This guidelines briefly explain how to contribute to SimpleSAMLphp in an effective manner, making sure to keep high
quality standards and making it easier for your contributions to make through.
+<!-- {{TOC}} -->
+
## Team members
Currently, the core team members are:
@@ -53,6 +55,12 @@ attention to:
* Do not include many changes in every commit. Commits should be focused and address one single problem or feature. By
having **multiple, small commits** instead of few large ones, it is easier to track what you are doing, revert changes
in case of an error and help you out if needed.
+* Try to write clean **commit messages**, largely based on the [seven rules](http://chris.beams.io/posts/git-commit/):
+ * Write a **short** subject line, followed by a blank line and a longer explanation.
+ * Prefix the subject line with the component(s) changed, e.g. "docs: Update foo", or "SAML: Don't log bar twice",
+ or "tests: Add tests for quux".
+ * Explain **what and why** in the commit message, not just _how_. Things obvious now might become quite confusing
+ when rediscovered years later.
* **Be explicit**. Add comments. Use strict comparison operators like `===` and check for specific values when testing
conditions.
* **Keep things simple**. Avoid big functions, long nested loops or `if` statements.
@@ -63,7 +71,7 @@ exceptions thrown.
deploy, and therefore we try to avoid it.
* Add **unit tests** to verify that your code not only works but also keeps working over time. When adding tests, keep
the same directory structure used for regular classes. Try to cover **all your code** with tests. The bigger the test
-coverage, the more reliable and better our library is.
+coverage, the more reliable and better our library is. Read our [guidelines](TESTING.md) to learn more about tests.
* Add proper **documentation** explaining your how to use your new feature or how your code changes things.
* Submit your code as a **pull request** in github, from a branch with a descriptive name in your own fork of the
repository. Add a meaningful, short title, and explain in detail what you did and why in the description of the *PR*.
@@ -93,14 +101,48 @@ You can help us diagnose and fix bugs by asking and providing answers to the fol
* Are the steps to reproduce the bug clear? If not, can you describe how you might reproduce it?
* What tags should the bug have?
* How critical is this bug? Does it impact a large amount of users?
-* Is this a security issue? If so, how severe is it? How can an attacker exploit it?
+* Is this a security issue? If so, how severe is it? How can an attacker exploit it? Read more about security issues in
+the next section.
+
+## Reporting vulnerabilities
+
+In case you find a vulnerability in SimpleSAMLphp, or you want to confirm a possible security issue in the software, please
+get in touch with us through [UNINETT's CERT team](https://www.uninett.no/cert). Please use our PGP public key to encrypt
+any possible sensitive data that you may need to submit. We will get back to you as soon as possible according to our
+working hours in Central European Time.
+
+When reporting a security issue, please add as much information as possible to help us identify, confirm, replicate and
+fix the problem. In particular, remember to include the following information in your report:
+
+* The version or versions of SimpleSAMLphp affected.
+* An exact version that can be used to replicate the issue.
+* Any module or modules involved in the issue.
+* Any particular configuration details relevant to the setup affected.
+* A detailed description and a clear and concise, step-by-step guide to allow us reproduce the issue.
+* Screenshots, videos, or any other media that would help identify the issue.
+* Pointers to the exact line or lines in the code where the vulnerability is supposed to be.
+* Context on how you discovered the issue.
+* Your own name and whether you want to be credited for the discovery or not.
+
+Please **DO NOT** report security incidents related to systems that use SimpleSAMLphp, where this software is not the
+cause of the incident. Issues related to the use (or misuse) of infrastructure, misconfiguration of the software,
+malfunction of a particular system or user-related errors should not be reported either. If you are using SimpleSAMLphp
+to authenticate or login to services, but you don't know what SimpleSAMLphp is or you are not sure about the nature of
+the issue, please contact the organization running the service for you.
+
+Finally, be reasonable. We'll do our best to resolve the issue according to our principles of security and transparency.
+Every confirmed vulnerability will be published and resolved in a timely manner. All we ask in return is that you
+contact us privately first in order to avoid any potential damage to those using the software.
+
+You can find the list of security advisories we have published [here](https://simplesamlphp.org/security).
## Translations
SimpleSAMLphp is translated to many languages, though it needs constant updates from translators, as well as new
-translations to other languages. Translations can be contributed through [the translation portal](https://translation.rnd.feide.no/).
-You can also join the [translators mailing list](http://groups.google.com/group/simplesamlphp-translation) to keep up
-to date.
+translations to other languages. For the moment, translations can be contributed as **pull requests**. We are looking
+at better ways to translate the software that would make your life easier, so stay tuned! You can also join the
+[translators mailing list](http://groups.google.com/group/simplesamlphp-translation) to keep up to date on the
+latest news.
Before starting a new translation, decide what style you want to use, whether you want to address the user in a polite
manner or not, etc. Be coherent and keep that style through all your translations. If there is already a translation and
diff --git a/README.md b/README.md
index a8eb5a2..a5d3a4a 100644
--- a/README.md
+++ b/README.md
@@ -8,3 +8,5 @@ This is the official repository of the SimpleSAMLphp software.
* [SimpleSAMLphp homepage](https://simplesamlphp.org)
* [SimpleSAMLphp Downloads](https://simplesamlphp.org/download)
+
+Please, [contribute](CONTRIBUTE.md)!
diff --git a/TESTING.md b/TESTING.md
new file mode 100644
index 0000000..90e6c9d
--- /dev/null
+++ b/TESTING.md
@@ -0,0 +1,64 @@
+Testing
+=======
+
+Testing your code is crucial to have a stable and good quality product.
+We are therefore slowly increasing the amount of tests we perform, and
+as a rule of thumb **all new code should have associated tests**. If you
+want to contribute to the project with a pull request, make sure to
+**include tests covering your code**. We won't accept pull requests
+without tests or getting the code coverage down, except in very specific
+situations.
+
+All the tests reside in the `tests` directory. The directory structure
+there replicates the main structure of the code. Each class is tested by
+a class named with the same name and `Test` appended, having the same
+directory structure as the original, but inside the `tests` directory.
+We also use namespaces, with `SimpleSAML\Test` as the root for standard
+classes, and `SimpleSAML\Test\Module\modulename` for classes located in
+modules.
+
+For example, if you want to test the `SimpleSAML\Utils\HTTP` class
+located in `lib/SimpleSAML/Utils/HTTP.php`, the tests must be in a class
+named `HTTPTest` implemented in
+`tests/lib/SimpleSAML/Utils/HTTPTest.php`, with the following namespace
+definition:
+
+```php
+namespace SimpleSAML\Test\Utils;
+```
+
+The test classes need to extend `PHPUnit_Framework_TestCase`, and inside
+you can implement as many methods as you want. `phpunit` will only run
+the ones prefixed with "test".
+
+You will usually make use of the `assert*()` methods provided by
+`PHPUnit_Framework_TestCase`, but you can also tell `phpunit` to expect
+an exception to be thrown using *phpdoc*. For example, if you want to
+ensure that the `SimpleSAML\Utils\HTTP::addURLParameters()` method
+throws an exception in a specific situation:
+
+```php
+ /**
+ * Test SimpleSAML\Utils\HTTP::addURLParameters().
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testAddURLParametersInvalidParameters() {
+```
+
+Refer to [the `phpunit` documentation](https://phpunit.de/documentation.html)
+for more information on how to write tests.
+
+Once you have implemented your tests, you can run them locally. First,
+make sure the `config` directory is **not** in the root of your
+SimpleSAMLphp installation, as the tests cannot use that. Make sure
+you have `phpunit` installed and run:
+
+```sh
+phpunit -c tools/phpunit/phpunit.xml
+```
+
+All the tests are run by our *continuous integration* platform,
+[travis](https://travis-ci.org/simplesamlphp/simplesamlphp). If you are
+submitting a pull request, Travis will run your tests and notify whether
+your code builds or not according to them.
diff --git a/attributemap/windowslive2name.php b/attributemap/windowslive2name.php
index e0821f1..1c5496c 100644
--- a/attributemap/windowslive2name.php
+++ b/attributemap/windowslive2name.php
@@ -10,5 +10,13 @@ $attributemap = array(
'windowslive.FirstName' => 'givenName',
'windowslive.LastName' => 'sn',
'windowslive.Location' => 'l',
+ // Attributes returned by Microsoft Graph - http://graph.microsoft.io/en-us/docs/api-reference/v1.0/resources/user
+ 'windowslive.givenName' => 'givenName',
+ 'windowslive.surname' => 'sn',
+ 'windowslive.displayName' => 'displayName',
+ 'windowslive.id' => 'uid',
+ 'windowslive.userPrincipalName' => 'eduPersonPrincipalName',
+ 'windowslive.mail' => 'mail',
+ 'windowslive.preferredLanguage' => 'preferredLanguage',
);
diff --git a/bin/memcacheSync.php b/bin/memcacheSync.php
index 6e3ae4a..50da317 100755
--- a/bin/memcacheSync.php
+++ b/bin/memcacheSync.php
@@ -9,9 +9,9 @@ if (!class_exists('Memcache')) {
echo("This is most likely because PHP doesn't load it for the command line\n");
echo("version. You probably need to enable it somehow.\n");
echo("\n");
- if (is_dir('/etc/php5/cli/conf.d')) {
+ if(is_executable('/usr/sbin/phpenmod')) {
echo("It is possible that running the following command as root will fix it:\n");
- echo(" echo 'extension=memcache.so' >/etc/php5/cli/conf.d/memcache.ini\n");
+ echo(" phpenmod -s cli memcache\n");
}
exit(1);
diff --git a/cache/.gitkeep b/cache/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cache/.gitkeep
diff --git a/composer.json b/composer.json
index 4ad8b36..cd57231 100644
--- a/composer.json
+++ b/composer.json
@@ -27,9 +27,10 @@
},
"require": {
"php": ">=5.3",
- "simplesamlphp/saml2": "~1.9",
- "robrichards/xmlseclibs": "~1.4.1",
- "whitehat101/apr1-md5": "~1.0"
+ "simplesamlphp/saml2": "dev-master#00e38f85b417be1e10a2d738dd2f5ea82edb472c as 2.2",
+ "robrichards/xmlseclibs": "~2.0",
+ "whitehat101/apr1-md5": "~1.0",
+ "twig/twig": "~1.0"
},
"require-dev": {
"ext-pdo_sqlite": "*",
diff --git a/composer.lock b/composer.lock
index 76c4b36..da9c63f 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "06fd3525a3284edd8021cb03c5069506",
- "content-hash": "fa599e698fbcf68e437d958914b8a6f8",
+ "hash": "705e7716f609c32a0b72136bb0dc8172",
+ "content-hash": "55b311b9889ea3f7d78f91850500d2fb",
"packages": [
{
"name": "psr/log",
@@ -47,20 +47,20 @@
},
{
"name": "robrichards/xmlseclibs",
- "version": "1.4.1",
+ "version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/robrichards/xmlseclibs.git",
- "reference": "465f18a8e1196c279b1298a3b08bcbee71ea4e4e"
+ "reference": "1b78df099c107279e9069a7b7608be98fd530dfd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/465f18a8e1196c279b1298a3b08bcbee71ea4e4e",
- "reference": "465f18a8e1196c279b1298a3b08bcbee71ea4e4e",
+ "url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/1b78df099c107279e9069a7b7608be98fd530dfd",
+ "reference": "1b78df099c107279e9069a7b7608be98fd530dfd",
"shasum": ""
},
"require": {
- "php": ">= 5.2"
+ "php": ">= 5.3"
},
"suggest": {
"ext/mcrypt": "MCrypt extension",
@@ -68,9 +68,9 @@
},
"type": "library",
"autoload": {
- "classmap": [
- "src/"
- ]
+ "psr-4": {
+ "RobRichards\\XMLSecLibs\\": "src"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -84,20 +84,20 @@
"xml",
"xmldsig"
],
- "time": "2015-07-31 12:22:14"
+ "time": "2015-07-31 15:08:38"
},
{
"name": "simplesamlphp/saml2",
- "version": "v1.9",
+ "version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/simplesamlphp/saml2.git",
- "reference": "be2b348c46cceb311a743a33fb51035158f6f69a"
+ "reference": "00e38f85b417be1e10a2d738dd2f5ea82edb472c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/be2b348c46cceb311a743a33fb51035158f6f69a",
- "reference": "be2b348c46cceb311a743a33fb51035158f6f69a",
+ "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/00e38f85b417be1e10a2d738dd2f5ea82edb472c",
+ "reference": "00e38f85b417be1e10a2d738dd2f5ea82edb472c",
"shasum": ""
},
"require": {
@@ -105,7 +105,7 @@
"ext-openssl": "*",
"php": ">=5.3.3",
"psr/log": "~1.0",
- "robrichards/xmlseclibs": "^1.3"
+ "robrichards/xmlseclibs": "^2.0"
},
"require-dev": {
"mockery/mockery": "~0.9",
@@ -119,8 +119,11 @@
"type": "library",
"autoload": {
"psr-0": {
- "SAML2_": "src/"
- }
+ "SAML2\\": "src/"
+ },
+ "files": [
+ "src/_autoload.php"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -133,7 +136,68 @@
}
],
"description": "SAML2 PHP library from SimpleSAMLphp",
- "time": "2016-03-16 14:11:59"
+ "time": "2016-07-26 13:28:46"
+ },
+ {
+ "name": "twig/twig",
+ "version": "v1.24.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/Twig.git",
+ "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/3566d311a92aae4deec6e48682dc5a4528c4a512",
+ "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.7"
+ },
+ "require-dev": {
+ "symfony/debug": "~2.7",
+ "symfony/phpunit-bridge": "~2.7"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.24-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Twig_": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ },
+ {
+ "name": "Twig Team",
+ "homepage": "http://twig.sensiolabs.org/contributors",
+ "role": "Contributors"
+ }
+ ],
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "http://twig.sensiolabs.org",
+ "keywords": [
+ "templating"
+ ],
+ "time": "2016-05-30 09:11:59"
},
{
"name": "whitehat101/apr1-md5",
@@ -274,6 +338,7 @@
"rest",
"web service"
],
+ "abandoned": "guzzlehttp/guzzle",
"time": "2015-03-18 18:23:50"
},
{
@@ -427,21 +492,24 @@
},
{
"name": "phpunit/php-timer",
- "version": "1.0.7",
+ "version": "1.0.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b"
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
- "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
+ "require-dev": {
+ "phpunit/phpunit": "~4|~5"
+ },
"type": "library",
"autoload": {
"classmap": [
@@ -464,7 +532,7 @@
"keywords": [
"timer"
],
- "time": "2015-06-21 08:01:12"
+ "time": "2016-05-12 18:03:57"
},
{
"name": "phpunit/php-token-stream",
@@ -698,16 +766,16 @@
},
{
"name": "symfony/config",
- "version": "v3.0.3",
+ "version": "v3.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
- "reference": "79a97025f7bf4bbf8352b5df1905aa136a531066"
+ "reference": "bcf5aebabc95b56e370e13d78565f74c7d8726dc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/79a97025f7bf4bbf8352b5df1905aa136a531066",
- "reference": "79a97025f7bf4bbf8352b5df1905aa136a531066",
+ "url": "https://api.github.com/repos/symfony/config/zipball/bcf5aebabc95b56e370e13d78565f74c7d8726dc",
+ "reference": "bcf5aebabc95b56e370e13d78565f74c7d8726dc",
"shasum": ""
},
"require": {
@@ -720,7 +788,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "3.1-dev"
}
},
"autoload": {
@@ -747,20 +815,20 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
- "time": "2016-02-23 15:16:06"
+ "time": "2016-06-29 05:41:56"
},
{
"name": "symfony/console",
- "version": "v3.0.3",
+ "version": "v3.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "2ed5e2706ce92313d120b8fe50d1063bcfd12e04"
+ "reference": "747154aa69b0f83cd02fc9aa554836dee417631a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/2ed5e2706ce92313d120b8fe50d1063bcfd12e04",
- "reference": "2ed5e2706ce92313d120b8fe50d1063bcfd12e04",
+ "url": "https://api.github.com/repos/symfony/console/zipball/747154aa69b0f83cd02fc9aa554836dee417631a",
+ "reference": "747154aa69b0f83cd02fc9aa554836dee417631a",
"shasum": ""
},
"require": {
@@ -780,7 +848,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "3.1-dev"
}
},
"autoload": {
@@ -807,20 +875,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2016-02-28 16:24:34"
+ "time": "2016-06-29 07:02:31"
},
{
"name": "symfony/event-dispatcher",
- "version": "v2.8.3",
+ "version": "v2.8.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3"
+ "reference": "b180b70439dca70049b6b9b7e21d75e6e5d7aca9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/78c468665c9568c3faaa9c416a7134308f2d85c3",
- "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b180b70439dca70049b6b9b7e21d75e6e5d7aca9",
+ "reference": "b180b70439dca70049b6b9b7e21d75e6e5d7aca9",
"shasum": ""
},
"require": {
@@ -867,20 +935,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2016-01-27 05:14:19"
+ "time": "2016-06-29 05:29:29"
},
{
"name": "symfony/filesystem",
- "version": "v3.0.3",
+ "version": "v3.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "23ae8f9648d0a7fe94a47c8e20e5bf37c489a451"
+ "reference": "322da5f0910d8aa0b25fa65ffccaba68dbddb890"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/23ae8f9648d0a7fe94a47c8e20e5bf37c489a451",
- "reference": "23ae8f9648d0a7fe94a47c8e20e5bf37c489a451",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/322da5f0910d8aa0b25fa65ffccaba68dbddb890",
+ "reference": "322da5f0910d8aa0b25fa65ffccaba68dbddb890",
"shasum": ""
},
"require": {
@@ -889,7 +957,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "3.1-dev"
}
},
"autoload": {
@@ -916,20 +984,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2016-02-23 15:16:06"
+ "time": "2016-06-29 05:41:56"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.1.1",
+ "version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "1289d16209491b584839022f29257ad859b8532d"
+ "reference": "dff51f72b0706335131b00a7f49606168c582594"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d",
- "reference": "1289d16209491b584839022f29257ad859b8532d",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594",
+ "reference": "dff51f72b0706335131b00a7f49606168c582594",
"shasum": ""
},
"require": {
@@ -941,7 +1009,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.1-dev"
+ "dev-master": "1.2-dev"
}
},
"autoload": {
@@ -975,20 +1043,20 @@
"portable",
"shim"
],
- "time": "2016-01-20 09:13:37"
+ "time": "2016-05-18 14:26:46"
},
{
"name": "symfony/stopwatch",
- "version": "v3.0.3",
+ "version": "v3.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/stopwatch.git",
- "reference": "4a204804952ff267ace88cf499e0b4bb302a475e"
+ "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/stopwatch/zipball/4a204804952ff267ace88cf499e0b4bb302a475e",
- "reference": "4a204804952ff267ace88cf499e0b4bb302a475e",
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/bb42806b12c5f89db4ebf64af6741afe6d8457e1",
+ "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1",
"shasum": ""
},
"require": {
@@ -997,7 +1065,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "3.1-dev"
}
},
"autoload": {
@@ -1024,20 +1092,20 @@
],
"description": "Symfony Stopwatch Component",
"homepage": "https://symfony.com",
- "time": "2016-01-03 15:35:16"
+ "time": "2016-06-29 05:41:56"
},
{
"name": "symfony/yaml",
- "version": "v2.8.3",
+ "version": "v2.8.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995"
+ "reference": "dba4bb5846798cd12f32e2d8f3f35d77045773c8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/2a4ee40acb880c56f29fb1b8886e7ffe94f3b995",
- "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/dba4bb5846798cd12f32e2d8f3f35d77045773c8",
+ "reference": "dba4bb5846798cd12f32e2d8f3f35d77045773c8",
"shasum": ""
},
"require": {
@@ -1073,12 +1141,21 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2016-02-23 07:41:20"
+ "time": "2016-06-29 05:29:29"
+ }
+ ],
+ "aliases": [
+ {
+ "alias": "2.2",
+ "alias_normalized": "2.2.0.0",
+ "version": "9999999-dev",
+ "package": "simplesamlphp/saml2"
}
],
- "aliases": [],
"minimum-stability": "stable",
- "stability-flags": [],
+ "stability-flags": {
+ "simplesamlphp/saml2": 20
+ },
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
diff --git a/config-templates/authsources.php b/config-templates/authsources.php
index d69442a..9f09ffd 100644
--- a/config-templates/authsources.php
+++ b/config-templates/authsources.php
@@ -246,9 +246,9 @@ $config = array(
*/
/*
- // Windows Live ID Authentication API.
+ // Microsoft Account (Windows Live ID) Authentication API.
// Register your application to get an API key here:
- // https://manage.dev.live.com
+ // https://apps.dev.microsoft.com/
'windowslive' => array(
'authwindowslive:LiveID',
'key' => 'xxxxxxxxxxxxxxxx',
diff --git a/config-templates/cas-ldap.php b/config-templates/cas-ldap.php
deleted file mode 100644
index 255b778..0000000
--- a/config-templates/cas-ldap.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-/*
- * The configuration of SimpleSAMLphp
- *
- *
- */
-
-$casldapconfig = array (
- 'idpentityid.example.org' => array(
- 'cas' => array(
- 'login' => 'https://idpentityid.example.org/cas/login',
- 'validate' => 'https://idpentityid.example.org/cas/validate',
- ),
- 'ldap' => array(
- 'servers' => 'idpentityid.example.org',
- 'enable_tls' => true,
- 'searchbase' => 'dc=example,dc=org',
- 'searchattributes' => 'uid',
- 'attributes' => array('cn', 'mail'),
- ),
- ),
- 'idpentityid2.example.org' => array(
- 'cas' => array(
- 'login' => 'https://idpentityid2.example.org/login',
- 'validate' => 'https://idpentityid2.example.org/validate',
- ),
- 'ldap' => array(
- 'servers' => 'ldap://idpentityid2.example.org',
- 'enable_tls' => true,
- 'searchbase' => 'ou=users,dc=example,dc=org',
- 'searchattributes' => array('uid', 'mail'), # array for being able to login with either uid or mail.
- 'attributes' => null,
- 'priv_user_dn' => 'uid=admin,ou=users,dc=example,dc=org',
- 'priv_user_pw' => 'xxxxx',
- ),
- ),
-
-);
diff --git a/config-templates/config-login-auto.php b/config-templates/config-login-auto.php
deleted file mode 100644
index 2412882..0000000
--- a/config-templates/config-login-auto.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-/*
- * The configuration of the login-auto authentication module.
- */
-
-$config = array (
-
- /*
- * This option enables or disables the login-auto authentication
- * handler. This handler is implemented in 'www/auth/login-auto.php'.
- *
- * When this option is set to true, a user can go to the
- * 'auth/login-auto.php' web page to be authenticated as an example
- * user. The user will receive the attributes set in the
- * 'auth.auto.attributes' option.
- *
- * WARNING: setting this option to true will make it possible to use
- * this authenticator for all users, irrespectively of the 'auth'
- * setting in the IdP's metadata. They can always use it by opening the
- * 'auth/login-auto.php' webpage manually.
- */
- 'auth.auto.enable' => true,
-
- /*
- * This option configures which attributes the login-auto
- * authentication handler will set for the user. It is an array of
- * arrays. The name of the attribute is the index in the first array,
- * and all the values for the attribute is given in the array
- * referenced to by the name.
- *
- * Example:
- * 'auth.auto.attributes' => array(
- * 'edupersonaffiliation' => array('student', 'member'),
- * 'uid' => array('example_uid'),
- * 'mail' => array('example@example.com'),
- * ),
- */
- 'auth.auto.attributes' => array(
- 'edupersonaffiliation' => array('student', 'member'),
- 'title' => array('Example user title'),
- 'uid' => array('example_uid'),
- 'mail' => array('example@example.com'),
- 'cn' => array('Example user commonname'),
- 'givenname' => array('Example user givenname'),
- 'sn' => array("Example surname"),
- ),
-
- /*
- * When this option is set to true, the login-auto authentication
- * handler will ask for a username and a password. This can be used to
- * test the IdP. The username and password isn't verified, and the
- * user/script can enter anything.
- */
- 'auth.auto.ask_login' => false,
-
- /*
- * This option configures a delay in the login-auto authentication
- * handler. The script will wait for the given number of milliseconds
- * before authenticating the user. This can, for example, be used in
- * a simple simulation of a slow LDAP server.
- */
- 'auth.auto.delay_login' => 0,
-);
diff --git a/config-templates/config-login-feide.php b/config-templates/config-login-feide.php
deleted file mode 100644
index 9625323..0000000
--- a/config-templates/config-login-feide.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-/*
- * Configuration for the auth/login-feide.php login module.
- *
- * The configuration file is an array with multiple organizations. The user
- * can select which organization he/she wants to log in with, with a drop-down
- * menu in the user interface.
- *
- */
-
-$config = array (
-
- 'orgldapconfig' => array(
-
- 'example1.com' => array(
- 'description' => 'Example Org 1',
- 'searchbase' => 'cn=people,dc=example1,dc=com',
- 'hostname' => 'ldaps://ldap.example1.com',
- 'attributes' => null,
-
- 'contactMail' => 'admin@example1.com',
- 'contactURL' => 'http://admin.example1.com',
-
- // System user to bind() before we do a search for eduPersonPrincipalName
- 'adminUser' => 'uid=admin,dc=example1,dc=com',
- 'adminPassword' => 'xxx',
-
- ),
- 'example1.com' => array(
- 'description' => 'Example Org 1',
- 'searchbase' => 'cn=people,dc=example1,dc=com',
- 'hostname' => 'ldaps://ldap.example1.com',
-
- 'attributes' => array('mail', 'street'),
- ),
- ),
-);
diff --git a/config-templates/config.php b/config-templates/config.php
index ed0b8f0..a2c102f 100644
--- a/config-templates/config.php
+++ b/config-templates/config.php
@@ -16,7 +16,6 @@ $config = array(
*
* Valid format for 'baseurlpath' is:
* [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/]
- * (note that it must end with a '/')
*
* The full url format is useful if your SimpleSAMLphp setup is hosted behind
* a reverse proxy. In that case you can specify the external url here.
@@ -77,10 +76,21 @@ $config = array(
* You can also put a hash here; run "bin/pwgen.php" to generate one.
*/
'auth.adminpassword' => '123',
+
+ /*
+ * Set this options to true if you want to require administrator password to access the web interface
+ * or the metadata pages, respectively.
+ */
'admin.protectindexpage' => false,
'admin.protectmetadata' => false,
/*
+ * Set this option to false if you don't want SimpleSAMLphp to check for new stable releases when
+ * visiting the configuration tab in the web interface.
+ */
+ 'admin.checkforupdates' => true,
+
+ /*
* Array of domains that are allowed when generating links or redirects
* to URLs. SimpleSAMLphp will use this option to determine whether to
* to consider a given URL valid or not, but you should always validate
@@ -105,6 +115,17 @@ $config = array(
'trusted.url.domains' => array(),
/*
+ * Enable regular expression matching of trusted.url.domains.
+ *
+ * Set to true to treat the values in trusted.url.domains as regular
+ * expressions. Set to false to do exact string matching.
+ *
+ * If enabled, the start and end delimiters ('^' and '$') will be added to
+ * all regular expressions in trusted.url.domains.
+ */
+ 'trusted.url.regex' => false,
+
+ /*
* Enable secure POST from HTTPS to HTTP.
*
* If you have some SP's on HTTP and IdP is normally on HTTPS, this option
@@ -656,6 +677,10 @@ $config = array(
*/
'theme.use' => 'default',
+ /*
+ * Templating options
+ */
+ 'template.auto_reload' => false,
/*********************
diff --git a/config-templates/ldap.php b/config-templates/ldap.php
deleted file mode 100644
index 799f584..0000000
--- a/config-templates/ldap.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-/*
- * Configuration for the LDAP authentication module.
- */
-
-$config = array (
-
- /**
- * LDAP configuration. This is only relevant if you use the LDAP authentication plugin.
- *
- * The attributes parameter is a list of attributes that should be retrieved.
- * If the attributes parameter is set to null, all attributes will be retrieved.
- */
- 'auth.ldap.dnpattern' => 'uid=%username%,dc=feide,dc=no,ou=feide,dc=uninett,dc=no',
- 'auth.ldap.hostname' => 'ldap.uninett.no',
- 'auth.ldap.attributes' => null,
- 'auth.ldap.enable_tls' => true,
-
- /*
- * Searching the DN of the user.
- */
-
- // Set this to TRUE to enable searching.
- 'auth.ldap.search.enable' => FALSE,
-
- // The base DN for the search.
- 'auth.ldap.search.base' => NULL,
-
- /* The attribute(s) to search for.
- *
- * This may be a single string, or an array of string. If this is an array, then any of the attributes
- * in the array may match the value the user supplied as the username.
- */
- 'auth.ldap.search.attributes' => NULL,
-
- /* The username & password the SimpleSAMLphp should bind as before searching. If this is left
- * as NULL, no bind will be performed before searching.
- */
- 'auth.ldap.search.username' => NULL,
- 'auth.ldap.search.password' => NULL,
-
-);
diff --git a/config-templates/ldapmulti.php b/config-templates/ldapmulti.php
deleted file mode 100644
index ce16cde..0000000
--- a/config-templates/ldapmulti.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-
-/*
- * Configuration for the multi-DN LDAP authentication module.
- *
- */
-
-$ldapmulti = array (
-
- 'feide.no' => array(
- 'description' => 'Feide',
- // for a description of options see equivalent options in ldap.php starting with auth.ldap.
- 'dnpattern' => 'uid=%username%,dc=feide,dc=no,ou=feide,dc=uninett,dc=no',
- 'hostname' => 'ldap.uninett.no',
- 'attributes' => NULL,
- 'enable_tls' => TRUE,
- 'search.enable' => FALSE,
- 'search.base' => NULL,
- 'search.attributes' => NULL,
- 'search.username' => NULL,
- 'search.password' => NULL,
- ),
-
- 'uninett.no' => array(
- 'description' => 'UNINETT',
- 'dnpattern' => 'uid=%username%,ou=people,dc=uninett,dc=no',
- 'hostname' => 'ldap.uninett.no',
- 'attributes' => NULL,
- )
-
-);
diff --git a/config-templates/translation.php b/config-templates/translation.php
deleted file mode 100644
index 8149aac..0000000
--- a/config-templates/translation.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-/*
- * Configuration
- *
- */
-
-$config = array (
-
- 'application' => 'simplesamlphp',
- 'baseurl' => 'https://translation.rnd.feide.no/simplesaml',
- 'key' => '_e7224d54cda84434e25ef087e5c22c1fa5f6ae87cc',
- 'secret' => '_0e29f782d295bc9782112981f654f1db58174d19d7',
-
-);
diff --git a/docs/index.txt b/docs/index.md
index 4cea605..4cea605 100644
--- a/docs/index.txt
+++ b/docs/index.md
diff --git a/docs/simplesamlphp-advancedfeatures.txt b/docs/simplesamlphp-advancedfeatures.md
index afeef27..71abf8f 100644
--- a/docs/simplesamlphp-advancedfeatures.txt
+++ b/docs/simplesamlphp-advancedfeatures.md
@@ -93,6 +93,13 @@ SimpleSAMLphp supports signing of the metadata it generates. Metadata signing is
- `metadata.sign.privatekey`: Name of the file with the private key which should be used to sign the metadata. This file must exist in in the `cert` directory.
- `metadata.sign.privatekey_pass`: Passphrase which should be used to open the private key. This parameter is optional, and should be left out if the private key is unencrypted.
- `metadata.sign.certificate`: Name of the file with the certificate which matches the private key. This file must exist in in the `cert` directory.
+- `metadata.sign.algorithm`: The algorithm to use when signing metadata for this entity. Defaults to RSA-SHA1. Possible values:
+
+ * `http://www.w3.org/2000/09/xmldsig#rsa-sha1`
+ *Note*: the use of SHA1 is **deprecated** and will be disallowed in the future.
+ * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256`
+ * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha384`
+ * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha512`
These options can be configured globally in the `config/config.php`-file, or per SP/IdP by adding them to the hosted metadata for the SP/IdP. The configuration in the metadata for the SP/IdP takes precedence over the global configuration.
diff --git a/docs/simplesamlphp-artifact-idp.txt b/docs/simplesamlphp-artifact-idp.md
index 4614f78..4614f78 100644
--- a/docs/simplesamlphp-artifact-idp.txt
+++ b/docs/simplesamlphp-artifact-idp.md
diff --git a/docs/simplesamlphp-artifact-sp.txt b/docs/simplesamlphp-artifact-sp.md
index 6b18119..6b18119 100644
--- a/docs/simplesamlphp-artifact-sp.txt
+++ b/docs/simplesamlphp-artifact-sp.md
diff --git a/docs/simplesamlphp-authproc.txt b/docs/simplesamlphp-authproc.md
index e0211a5..e0211a5 100644
--- a/docs/simplesamlphp-authproc.txt
+++ b/docs/simplesamlphp-authproc.md
diff --git a/docs/simplesamlphp-authsource.txt b/docs/simplesamlphp-authsource.md
index 514b96f..514b96f 100644
--- a/docs/simplesamlphp-authsource.txt
+++ b/docs/simplesamlphp-authsource.md
diff --git a/docs/simplesamlphp-automated_metadata.txt b/docs/simplesamlphp-automated_metadata.md
index 9cf0bc3..9cf0bc3 100644
--- a/docs/simplesamlphp-automated_metadata.txt
+++ b/docs/simplesamlphp-automated_metadata.md
diff --git a/docs/simplesamlphp-changelog.txt b/docs/simplesamlphp-changelog.md
index be38758..c35694c 100644
--- a/docs/simplesamlphp-changelog.txt
+++ b/docs/simplesamlphp-changelog.md
@@ -6,10 +6,65 @@ SimpleSAMLphp changelog
This document lists the changes between versions of SimpleSAMLphp.
See the upgrade notes for specific information about upgrading.
-## Version 1.14.0
+## Version 1.14.7
Released TBD
+ * Fixed issue #424. Attributes containing XML as their values (like eduPersonTargetedID) were empty.
+
+## Version 1.14.6
+
+Released 2016-07-18
+
+ * Fixed issue #418. SimpleSAMLphp was unable to obtain the current URL correctly when invoked from third-party applications.
+
+## Version 1.14.5
+
+Released 2016-07-12
+
+ * Fixed several issues with session handling when cookies couldn't be set for some reason.
+ * Fixed an issue that caused wrong URLs to be generated in the web interface under certain circumstances.
+ * Fixed the exception handler to be compatible with PHP 7.
+ * Fixed an issue in the dropdown IdP selection page that prevented it to work with PHP 5.3.
+ * Fixed compatibility with Windows machines.
+ * Fixed an issue with the PDO and Serialize metadata storage handlers.
+ * Fixed the authwindowslive module. It stopped working after the former API was discontinued.
+ * Other minor issues and fixes.
+
+## Version 1.14.4
+
+Released 2016-06-08
+
+ * Fixed two minor security issues that allowed malicious URLs to be presented to the user in a link. Reported by John Page.
+ * Fixed issue #366. The LDAP class was trying to authenticate even when no password was provided (using the CAS module).
+ * Fixed issue #401. The authenticate.php script was printing exceptions instead of throwing them for the exception handler to capture them.
+ * Fixed issue #399. The size limitation of the TEXT type in MySQL was creating problems in certain setups.
+ * Fixed issue #5. Incoherent population of the $_SERVER variable was creating broken links when running PHP with FastCGI.
+ * Other typos and minor bugs: #389, #392.
+
+## Version 1.14.3
+
+Released 2016-04-19
+
+ * Fixed a bug in the login form that prevented the login button to be displayed in mobile devices.
+ * Resolved an issue in the PHP session handler that made it impossible to use PHP sessions simultaneously with other applications.
+
+## Version 1.14.2
+
+Released 2016-03-11
+
+ * Use stable versions of the externalized modules to prevent possible issues when further developing them.
+
+## Version 1.14.1
+
+Released 2016-03-08
+
+ * Resolved an information leakage security issue in the sanitycheck module. See [SSPSA 201603-01](/security/201603-01).
+
+## Version 1.14.0
+
+Released 2016-02-15
+
### Security
* Resolved a security issue with multiple modules that were not validating the URLs they were redirecting to.
diff --git a/docs/simplesamlphp-customauth.txt b/docs/simplesamlphp-customauth.md
index 8f7c30f..8f7c30f 100644
--- a/docs/simplesamlphp-customauth.txt
+++ b/docs/simplesamlphp-customauth.md
diff --git a/docs/simplesamlphp-database.txt b/docs/simplesamlphp-database.md
index 663fdce..663fdce 100644
--- a/docs/simplesamlphp-database.txt
+++ b/docs/simplesamlphp-database.md
diff --git a/docs/simplesamlphp-errorhandling.txt b/docs/simplesamlphp-errorhandling.md
index 278cad2..278cad2 100644
--- a/docs/simplesamlphp-errorhandling.txt
+++ b/docs/simplesamlphp-errorhandling.md
diff --git a/docs/simplesamlphp-googleapps.txt b/docs/simplesamlphp-googleapps.md
index 1a11a17..1a11a17 100644
--- a/docs/simplesamlphp-googleapps.txt
+++ b/docs/simplesamlphp-googleapps.md
diff --git a/docs/simplesamlphp-hok-idp.txt b/docs/simplesamlphp-hok-idp.md
index e34a6b8..e34a6b8 100644
--- a/docs/simplesamlphp-hok-idp.txt
+++ b/docs/simplesamlphp-hok-idp.md
diff --git a/docs/simplesamlphp-hok-sp.txt b/docs/simplesamlphp-hok-sp.md
index a687896..a687896 100644
--- a/docs/simplesamlphp-hok-sp.txt
+++ b/docs/simplesamlphp-hok-sp.md
diff --git a/docs/simplesamlphp-idp-more.txt b/docs/simplesamlphp-idp-more.md
index 8b4937f..fe61e17 100644
--- a/docs/simplesamlphp-idp-more.txt
+++ b/docs/simplesamlphp-idp-more.md
@@ -33,7 +33,7 @@ SimpleSAMLphp has implemented a graceful fallback to tackle this situation. When
What happens in the IdP-first flow is that a *SAML unsolicited response* is sent directly to the SP. An *unsolicited response* is a SAML Response with no reference to a SAML Request (no `InReplyTo` field).
-When a SimpleSAMLphp IdP falls back to IdP-first flow, the `RelayState` parameter sent by the SP in the SAML request is also lost. The RelayState information contain a reference key for the SP to lookup where to send the user after successfull authentication. The SimpleSAMLphp Service Provider supports configuring a static URL to redirect the user after a unsolicited response is received. See more information about the `RelayState` parameter in the next section: *IdP-first flow*.
+When a SimpleSAMLphp IdP falls back to IdP-first flow, the `RelayState` parameter sent by the SP in the SAML request is also lost. The RelayState information contain a reference key for the SP to lookup where to send the user after successful authentication. The SimpleSAMLphp Service Provider supports configuring a static URL to redirect the user after a unsolicited response is received. See more information about the `RelayState` parameter in the next section: *IdP-first flow*.
IdP-first flow
diff --git a/docs/simplesamlphp-idp.txt b/docs/simplesamlphp-idp.md
index dcc8d70..dcc8d70 100644
--- a/docs/simplesamlphp-idp.txt
+++ b/docs/simplesamlphp-idp.md
diff --git a/docs/simplesamlphp-install-repo.txt b/docs/simplesamlphp-install-repo.md
index c27fc94..c27fc94 100644
--- a/docs/simplesamlphp-install-repo.txt
+++ b/docs/simplesamlphp-install-repo.md
diff --git a/docs/simplesamlphp-install.txt b/docs/simplesamlphp-install.md
index 47eab75..254ab66 100644
--- a/docs/simplesamlphp-install.txt
+++ b/docs/simplesamlphp-install.md
@@ -119,6 +119,18 @@ Find the Apache configuration file for the virtual hosts where you want to run S
SetEnv SIMPLESAMLPHP_CONFIG_DIR /var/simplesamlphp/config
Alias /simplesaml /var/simplesamlphp/www
+
+ <Directory /var/simplesamlphp/www>
+ <IfModule !mod_authz_core.c>
+ # For Apache 2.2:
+ Order allow,deny
+ Allow from all
+ </IfModule>
+ <IfModule mod_authz_core.c>
+ # For Apache 2.4:
+ Require all granted
+ </IfModule>
+ </Directory>
</VirtualHost>
Note the `Alias` directive, which gives control to SimpleSAMLphp for all urls matching `http(s)://service.example.com/simplesaml/*`. SimpleSAMLphp makes several SAML interfaces available on the web; all of them are included in the `www` subdirectory of your SimpleSAMLphp installation. You can name the alias whatever you want, but the name must be specified in the `config.php` file of simpleSAML as described in [the section called “SimpleSAMLphp configuration: config.php”](#sect.config "SimpleSAMLphp configuration: config.php"). Here is an example of how this configuration may look like in `config.php`:
@@ -160,8 +172,8 @@ file, `config.php`, right away:
be used for receiving error reports sent automatically by
SimpleSAMLphp. Here is an example:
- 'technicalcontact_name' => 'Andreas Åkre Solberg',
- 'technicalcontact_email' => 'andreas.solberg@uninett.no',
+ 'technicalcontact_name' => 'John Smith',
+ 'technicalcontact_email' => 'john.smith@example.com',
-
If you use SimpleSAMLphp in a country where English is not
@@ -291,11 +303,11 @@ Next, you need to update the configuration of paths in `simplesamlphp/config/con
And, then we need to set the `baseurlpath` parameter to match the base path of the URLs to the content of your `www` folder:
- 'baseurlpath' => '~andreas/simplesaml/',
+ 'baseurlpath' => '/simplesaml/',
Now, you can go to the URL of your installation and check if things work:
- http://yourcompany.com/~andreas/simplesaml/
+ http://yourcompany.com/simplesaml/
### Tip
@@ -324,7 +336,7 @@ Change the two lines from:
to something like:
- require_once('/home/andreas/simplesamlphp/lib/_autoload.php');
+ require_once('/var/www/simplesamlphp/lib/_autoload.php');
And then at the end of the file, you need to change another line
from:
@@ -333,7 +345,7 @@ from:
to:
- $configdir = '/home/andreas/simplesamlphp/config';
+ $configdir = '/var/www/simplesamlphp/config';
diff --git a/docs/simplesamlphp-maintenance.txt b/docs/simplesamlphp-maintenance.md
index b58e2cf..b58e2cf 100644
--- a/docs/simplesamlphp-maintenance.txt
+++ b/docs/simplesamlphp-maintenance.md
diff --git a/docs/simplesamlphp-metadata-endpoints.txt b/docs/simplesamlphp-metadata-endpoints.md
index 9bca908..9bca908 100644
--- a/docs/simplesamlphp-metadata-endpoints.txt
+++ b/docs/simplesamlphp-metadata-endpoints.md
diff --git a/docs/simplesamlphp-metadata-extensions-attributes.txt b/docs/simplesamlphp-metadata-extensions-attributes.md
index 7e3c1c0..7e3c1c0 100644
--- a/docs/simplesamlphp-metadata-extensions-attributes.txt
+++ b/docs/simplesamlphp-metadata-extensions-attributes.md
diff --git a/docs/simplesamlphp-metadata-extensions-rpi.txt b/docs/simplesamlphp-metadata-extensions-rpi.md
index 4799de1..4799de1 100644
--- a/docs/simplesamlphp-metadata-extensions-rpi.txt
+++ b/docs/simplesamlphp-metadata-extensions-rpi.md
diff --git a/docs/simplesamlphp-metadata-extensions-ui.txt b/docs/simplesamlphp-metadata-extensions-ui.md
index 94a855d..94a855d 100644
--- a/docs/simplesamlphp-metadata-extensions-ui.txt
+++ b/docs/simplesamlphp-metadata-extensions-ui.md
diff --git a/docs/simplesamlphp-metadata-pdostoragehandler.txt b/docs/simplesamlphp-metadata-pdostoragehandler.md
index 82656fb..82656fb 100644
--- a/docs/simplesamlphp-metadata-pdostoragehandler.txt
+++ b/docs/simplesamlphp-metadata-pdostoragehandler.md
diff --git a/docs/simplesamlphp-modules.txt b/docs/simplesamlphp-modules.md
index 9ab6625..9ab6625 100644
--- a/docs/simplesamlphp-modules.txt
+++ b/docs/simplesamlphp-modules.md
diff --git a/docs/simplesamlphp-nostate.txt b/docs/simplesamlphp-nostate.md
index 6d0535f..6d0535f 100644
--- a/docs/simplesamlphp-nostate.txt
+++ b/docs/simplesamlphp-nostate.md
diff --git a/docs/simplesamlphp-reference-idp-hosted.txt b/docs/simplesamlphp-reference-idp-hosted.md
index dc0fae3..dc0fae3 100644
--- a/docs/simplesamlphp-reference-idp-hosted.txt
+++ b/docs/simplesamlphp-reference-idp-hosted.md
diff --git a/docs/simplesamlphp-reference-idp-remote.txt b/docs/simplesamlphp-reference-idp-remote.md
index c8416f5..c408853 100644
--- a/docs/simplesamlphp-reference-idp-remote.txt
+++ b/docs/simplesamlphp-reference-idp-remote.md
@@ -212,25 +212,6 @@ Shibboleth 1.3 options
: *Note*: This option only works with the `saml:SP` authentication source.
-
-Examples
---------
-
-### Configuration for openidp.feide.no ###
-
- <?php
- $metadata['https://openidp.feide.no'] = array(
- 'name' => array(
- 'en' => 'Feide OpenIdP - guest users',
- 'no' => 'Feide Gjestebrukere',
- ),
- 'description' => 'Here you can login with your account on Feide RnD OpenID. If you do not already have an account on this identity provider, you can create a new one by following the create new account link and follow the instructions.',
- 'SingleSignOnService' => 'https://openidp.feide.no/simplesaml/saml2/idp/SSOService.php',
- 'SingleLogoutService' => 'https://openidp.feide.no/simplesaml/saml2/idp/SingleLogoutService.php',
- 'certFingerprint' => 'c9ed4dfb07caf13fc21e0fec1572047eb8a7a4cb',
- );
-
-
Calculating the fingerprint of a certificate
--------------------------------------------
diff --git a/docs/simplesamlphp-reference-sp-remote.txt b/docs/simplesamlphp-reference-sp-remote.md
index 943c862..943c862 100644
--- a/docs/simplesamlphp-reference-sp-remote.txt
+++ b/docs/simplesamlphp-reference-sp-remote.md
diff --git a/docs/simplesamlphp-scoping.txt b/docs/simplesamlphp-scoping.md
index 4f1ff87..4f1ff87 100644
--- a/docs/simplesamlphp-scoping.txt
+++ b/docs/simplesamlphp-scoping.md
diff --git a/docs/simplesamlphp-sp-api.txt b/docs/simplesamlphp-sp-api.md
index fae5b14..fae5b14 100644
--- a/docs/simplesamlphp-sp-api.txt
+++ b/docs/simplesamlphp-sp-api.md
diff --git a/docs/simplesamlphp-sp-migration.txt b/docs/simplesamlphp-sp-migration.md
index 267f0e5..267f0e5 100644
--- a/docs/simplesamlphp-sp-migration.txt
+++ b/docs/simplesamlphp-sp-migration.md
diff --git a/docs/simplesamlphp-sp.txt b/docs/simplesamlphp-sp.md
index b54441a..509df2d 100644
--- a/docs/simplesamlphp-sp.txt
+++ b/docs/simplesamlphp-sp.md
@@ -69,9 +69,9 @@ The service provider you are configuring needs to know about the identity provid
This is a minimal example of a `metadata/saml20-idp-remote.php` metadata file:
<?php
- $metadata['https://openidp.feide.no'] = array(
- 'SingleSignOnService' => 'https://openidp.feide.no/simplesaml/saml2/idp/SSOService.php',
- 'SingleLogoutService' => 'https://openidp.feide.no/simplesaml/saml2/idp/SingleLogoutService.php',
+ $metadata['https://example.com'] = array(
+ 'SingleSignOnService' => 'https://example.com/simplesaml/saml2/idp/SSOService.php',
+ 'SingleLogoutService' => 'https://example.com/simplesaml/saml2/idp/SingleLogoutService.php',
'certFingerprint' => 'c9ed4dfb07caf13fc21e0fec1572047eb8a7a4cb',
);
@@ -98,7 +98,7 @@ This is the `idp` option.
* The entity ID of the IdP this should SP should contact.
* Can be NULL/unset, in which case the user will be shown a list of available IdPs.
*/
- 'idp' => 'https://openidp.feide.no',
+ 'idp' => 'https://idp.example.com',
),
);
@@ -106,32 +106,21 @@ This is the `idp` option.
Exchange metadata with the IdP
------------------------------
-If you do not have an IdP yourself, you could use the Feide OpenIdP to test your Service Provider.
-The metadata for Feide OpenIdP is already included in the metadata distributed with SimpleSAMLphp.
-
-In order to complete the connection between your SP and Feide OpenIdP, you must add the metadata for your SP to the IdP.
-The metadata for your SP can be found on the `Federation`-tab.
-Copy the SAML 2.0 XML Metadata document automatically generated by SimpleSAMLphp, and go to the OpenIdP Metadata Self-Service Registry:
-
- * [Feide OpenIdP Metadata Self-Service Registry](https://openidp.feide.no/simplesaml/module.php/metaedit/index.php)
-
-You need to login with an OpenIdP account to authenticate (you can create a new account if you do not have one already).
-Next, click the link 'Add from SAML 2.0 XML metadata', and paste in your SAML 2.0 XML Metadata.
-After clicking the 'Import metadata' button, you will be presented with a form where you can edit your metadata.
-You can check that your metadata was parsed correctly by looking at the 'SAML 2.0' tab.
-The textfields for AssertionConsumerService and SingleLogoutService should contain two URLs:
-
-`AssertionConsumerService`
-: `https://sp.example.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp`
-
-`SingleLogoutService`
-: `https://sp.example.org/simplesaml/module.php/saml/sp/saml2-logout.php/default-sp`
-
-After checking your metadata, give your SP a proper name and description and click 'save'.
-
-The procedure for managing trust in federations differ, but the common part is that you would need to provide the *SAML 2.0 metadata
-of your SP*, and register that with the federation administration.
-
+In order to complete the connection between your SP and an IdP, you must exchange the metadata of your SP with the IdP.
+The metadata of your SP can be found in the *Federation* tab of the web interface. Copy the SAML 2.0 XML Metadata document
+automatically generated by SimpleSAMLphp and send it to the administrator of the IdP. You can also send them the dedicated
+URL of your metadata, so that they can fetch it periodically and obtain automatically any changes that you may perform to
+your SP.
+
+You will also need to add the metadata of the IdP. Ask them to provide you with their metadata, and parse it using the *XML to
+SimpleSAMLphp metadata converter* tool available also in the *Federation* tab of the web interface. Copy the resulting
+parsed metadata and paste it with a text editor into the `metadata/saml20-idp-remote.php` file in your SimpleSAMLphp
+directory.
+
+If you intend to add your SP to a federation, the procedure for managing trust in federations differ, but the common part is
+that you would need to provide the *SAML 2.0 metadata of your SP*, and register that with the federation administration.
+You will probably be required too to consume the federation metadata periodically. Read more about
+[automated metadata management](simplesamlphp-automated_metadata) to learn more about that.
Test the SP
diff --git a/docs/simplesamlphp-theming.txt b/docs/simplesamlphp-theming.md
index eaf0de1..eaf0de1 100644
--- a/docs/simplesamlphp-theming.txt
+++ b/docs/simplesamlphp-theming.md
diff --git a/docs/simplesamlphp-translation.md b/docs/simplesamlphp-translation.md
new file mode 100644
index 0000000..da9766b
--- /dev/null
+++ b/docs/simplesamlphp-translation.md
@@ -0,0 +1,91 @@
+SimpleSAMLphp Translation Portal
+================================================================
+
+<!--
+ This file is written in Markdown syntax.
+ For more information about how to use the Markdown syntax, read here:
+ http://daringfireball.net/projects/markdown/syntax
+-->
+
+<!-- {{TOC}} -->
+
+## How translated terms are referred from a template
+
+Here is an example of how two terms are included in a template from dictionary files:
+
+ <h2><?php echo $this->t('{core:frontpage:about_header}'); ?></h2>
+ <p><?php echo $this->t('{core:frontpage:about_text}'); ?></p>
+
+In this example, two translated terms are included: `about_header` and `about_text`. Both these terms are found in a dictionary file named `frontpage`, inside the module named `core`.
+
+**Note:** An important use-case here is that you can create your own module, that includes a new theme that overrides some of the default templates. You may in this template refer to both terms from the existing dictionary files, but you can also add new dictionary files in your new module that may introduce new alternative terms.
+
+## The definition file
+
+When the template library is about to lookup the translation of a term, it will lookup
+
+ * the definition file, for the English translation, and
+ * the translation file, for translation to other languages.
+
+When developing new functionalities it is common to start by just introducing the definition file, then upload the definition file to the SimpleSAMLphp translation portal, perform translation, and then download the translation files back in to the module.
+
+SimpleSAMLphp will always fallback to the English translation using the definition file, both:
+
+ * when the term is not translated into the *current selected language*, and
+ * when the translation file is not available at all.
+
+The name of the definition file is `BASENAME.definition.json`, where the term is referred to like this: `{MODULENAME:BASENAME:TERM}`. The file MUST be placed in the followng location: `modules/MODULENAME/dictionaries/BASENAME.definition.json`.
+
+The content of the defintion file is a *JSON encoded array* of `term => definition`, where definition is an array with an required `en` index for the english translation, and the value is the English text.
+
+Here is an example of a definition file with three terms:
+
+ {
+ "header": {
+ "en": "Missing cookie"
+ },
+ "description": {
+ "en": "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
+ },
+ "retry": {
+ "en": "Retry"
+ }
+ }
+
+Note: you may not include other languages in the definition files, the `en` index is used in order to at a later point in time introduce more meta information for each term, like in example:
+
+ "header": {
+ "en": "Missing cookie",
+ "_note": "This text shows up on the error page when the browser do not support cookies."
+ },
+
+To summarize the pattern of the definition file is as follows:
+
+ {
+ "TERM1": {
+ "en": "English text 1"
+ },
+ "TERM2": {
+ "en": "English text 2"
+ }
+ }
+
+## The translation file
+
+The translation file is similar to the definition file, but including translation to languages others than English.
+
+This file is recommended to never write manually, but instead use the SimpleSAMLphp translation portal, and then download generated translation files.
+
+The structure of the file is identical to the definition files, except from the language index, which now is not `en`, but the actual langauge that is translated:
+
+
+ {
+ "TERM1": {
+ "no": "Norsk tekst 1",
+ "da": "Dansk tekst 1"
+ },
+ "TERM2": {
+ "no": "Norsk tekst 2",
+ "da": "Dansk tekst 2"
+ }
+ }
diff --git a/docs/simplesamlphp-translation.txt b/docs/simplesamlphp-translation.txt
deleted file mode 100644
index efd8848..0000000
--- a/docs/simplesamlphp-translation.txt
+++ /dev/null
@@ -1,196 +0,0 @@
-SimpleSAMLphp Translation Portal
-================================================================
-
-<!--
- This file is written in Markdown syntax.
- For more information about how to use the Markdown syntax, read here:
- http://daringfireball.net/projects/markdown/syntax
--->
-
-
-<!-- {{TOC}} -->
-
-SimpleSAMLphp supports multiple languages.
-
- * The SimpleSAMLphp Translation Portal
- * Language definition file
- * Translation file
-
-
-## How translated terms are referred from a template
-
-Here is an example of how two terms are included in a template from dictionary files:
-
- <h2><?php echo $this->t('{core:frontpage:about_header}'); ?></h2>
- <p><?php echo $this->t('{core:frontpage:about_text}'); ?></p>
-
-In this example, two translated terms are included: `about_header` and `about_text`. Both these terms are found in a dictionary file named `frontpage`, inside the module named `core`.
-
-**Note:** An important use-case here is that you can create your own module, that includes a new theme that overrides some of the default templates. You may in this template refer to both terms from the existing dictionary files, but you can also add new dictionary files in your new module that may introduce new alternative terms.
-
-## The definition file
-
-When the template library is about to lookup the translation of a term, it will lookup
-
- * the definition file, for the English translation, and
- * the translation file, for translation to other languages.
-
-When developing new functionalities it is common to start by just introducing the definition file, then upload the definition file to the SimpleSAMLphp translation portal, perform translation, and then download the translation files back in to the module.
-
-SimpleSAMLphp will always fallback to the English translation using the definition file, both:
-
- * when the term is not translated into the *current selected language*, and
- * when the translation file is not available at all.
-
-The name of the definition file is `BASENAME.definition.json`, where the term is referred to like this: `{MODULENAME:BASENAME:TERM}`. The file MUST be placed in the followng location: `modules/MODULENAME/dictionaries/BASENAME.definition.json`.
-
-The content of the defintion file is a *JSON encoded array* of `term => definition`, where definition is an array with an required `en` index for the english translation, and the value is the English text.
-
-Here is an example of a definition file with three terms:
-
- {
- "header": {
- "en": "Missing cookie"
- },
- "description": {
- "en": "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
- },
- "retry": {
- "en": "Retry"
- }
- }
-
-Note: you may not include other languages in the definition files, the `en` index is used in order to at a later point in time introduce more meta information for each term, like in example:
-
- "header": {
- "en": "Missing cookie",
- "_note": "This text shows up on the error page when the browser do not support cookies."
- },
-
-To summarize the pattern of the defintion file is as follows:
-
- {
- "TERM1": {
- "en": "English text 1"
- },
- "TERM2": {
- "en": "English text 2"
- }
- }
-
-## The translation file
-
-The translation file is similar to the definition file, but including translation to languages others than English.
-
-This file is reccomended to never write manually, but instead use the SimpleSAMLphp translation portal, and then download generated translation files.
-
-The structure of the file is identical to the definition files, except from the language index, which now is not `en`, but the actual langauge that is translated:
-
-
- {
- "TERM1": {
- "no": "Norsk tekst 1",
- "da": "Dansk tekst 1"
- },
- "TERM2": {
- "no": "Norsk tekst 2",
- "da": "Dansk tekst 2"
- }
- }
-
-## The SimpleSAMLphp Translation Portal
-
-The SimpleSAMLphp translation portal is available here:
-
- * <https://translation.rnd.feide.no/>
-
-Use Feide OpenIdP to login, select the application you want to translate, SimpleSAMLphp or your own application, then start translate to your langauge.
-
-## The `translation.php` command line script
-
-The `translation.php` script is available in the `bin` directory of SimpleSAMLphp.
-
-The script requires that the config file `translation.php` is copied from `config-templates` to the `config` directory.
-
-The script may be used to these tasks:
-
- * Uploading definition files
- * Downloading definition files
- * Downloading translation files
-
-### Uploading defintion files
-
-You probably do not have access to upload definition files for the SimpleSAMLphp application. But, from January 2010, the translation portal is generic to host multiple independent applications. What you may do is to contact Andreas to add your own application to the translation portal, where you of course have access to upload definition files.
-
-**Note**: an application may very well be a local SimpleSAMLphp module that you run.
-
-To add a new application to the SimpleSAMLphp translation portal, contact Andreas with the following information:
-
- * name of the application
- * Feide OpenID userids of the individuals that should have access to upload definition files
- * a list of languages that should be expored
-
-If you want to upload a definition file, edit the `translation.php` config file to include the ID of your application.
-
-Then manually create a definition file as described in the section *The definition file* above.
-
-Next run the script as follows:
-
- bin/translation.php push modules/MODULENAME/dictionaries/BASENAME.definition.json
-
-Output example:
-
- Action: [push]
- Application: [simplesamlphp]
- File orig: [modules/core/dictionaries/no_cookie.definition.json]
- File base: [no_cookie]
- Using OAuth to authenticate you to the translation portal
- Successfully read OAuth Access Token from cache [_6d20d3830e7823304881ca9b829bedb0caf8877c8c]
- New definition file [no_cookie] stored in application [simplesamlphp] for user [andreas@rnd.feide.no] ...
-
-The script uses OAuth to connect your session on the command line client with the translation portal, then you need to login using Feide OpenIdP.
-
-
-
-### Deleting definition files
-
-Is perfomed via the webbased translation portal.
-
-### Downloading defintion files
-
-Seldom used, as the defintion file is manually created locally. Anyway:
-
- bin/translation.php pulldef modules/MODULENAME/dictionaries/BASENAME.definition.json
-
-Output example:
-
- Action: [pulldef]
- Application: [simplesamlphp]
- File orig: [modules/core/dictionaries/no_cookie.definition.json]
- File base: [no_cookie]
-
-
-### Downloading translation files
-
- bin/translation.php pull modules/MODULENAME/dictionaries/BASENAME.translation.json
-
-Note: it is optional whether you use `BASENAME.defintion.json` or `BASENAME.translation.json`
-
-Example output:
-
- Action: [pull]
- Application: [simplesamlphp]
- File orig: [modules/core/dictionaries/no_cookie.definition.json]
- File base: [no_cookie]
-
-Often you would like to pull translation from a number of definition files distributed in many different modules. Then you may use some helpful commands like:
-
- find . -name '*.definition.json' | xargs -n 1 bin/translation.php pull
-
-Note: Be careful when you checkin
-
-### Converting old translation file to new definition file
-
- bin/translation.php convert modules/MODULENAME/dictionaries/BASENAME.php
-
-And a new definition file is created using the new JSON format.
diff --git a/docs/simplesamlphp-upgrade-notes-1.10.txt b/docs/simplesamlphp-upgrade-notes-1.10.md
index 0e17ec0..0e17ec0 100644
--- a/docs/simplesamlphp-upgrade-notes-1.10.txt
+++ b/docs/simplesamlphp-upgrade-notes-1.10.md
diff --git a/docs/simplesamlphp-upgrade-notes-1.11.txt b/docs/simplesamlphp-upgrade-notes-1.11.md
index 7761eaf..7761eaf 100644
--- a/docs/simplesamlphp-upgrade-notes-1.11.txt
+++ b/docs/simplesamlphp-upgrade-notes-1.11.md
diff --git a/docs/simplesamlphp-upgrade-notes-1.12.txt b/docs/simplesamlphp-upgrade-notes-1.12.md
index 0c64587..0c64587 100644
--- a/docs/simplesamlphp-upgrade-notes-1.12.txt
+++ b/docs/simplesamlphp-upgrade-notes-1.12.md
diff --git a/docs/simplesamlphp-upgrade-notes-1.13.txt b/docs/simplesamlphp-upgrade-notes-1.13.md
index 4816c18..4816c18 100644
--- a/docs/simplesamlphp-upgrade-notes-1.13.txt
+++ b/docs/simplesamlphp-upgrade-notes-1.13.md
diff --git a/docs/simplesamlphp-upgrade-notes-1.14.txt b/docs/simplesamlphp-upgrade-notes-1.14.md
index f08b5fd..dc7eda6 100644
--- a/docs/simplesamlphp-upgrade-notes-1.14.txt
+++ b/docs/simplesamlphp-upgrade-notes-1.14.md
@@ -3,7 +3,7 @@ Upgrade notes for SimpleSAMLphp 1.14
The `mcrypt` extension is no longer required by SimpleSAMLphp, so if no signatures or encryption are being used, it
can be skipped. It is still a requirement for `xmlseclibs` though, so for those verifying or creating signed
-documents, or using encryption, is is still needed.
+documents, or using encryption, it is still needed.
PHP session cookies are now set to HTTP-only by default. This relates to the `session.phpsession.httponly`
configuration option.
@@ -14,6 +14,15 @@ insecure redirections.
The jQuery version in use has been bumped to the latest 1.8.X version.
+Service Providers using the eduPersonTargetedID attribute, will get a DOMNodeList object instead of the NameID value. In
+order to process the NameID, a SAML2_XML_saml_NameID object can be used:
+
+```php
+$attributes = $as->getAttributes();
+$eptid = $attributes['eduPersonTargetedID'][0]->item(0);
+$nameID = new SAML2_XML_saml_NameID($eptid);
+```
+
The following deprecated files, directories and endpoints have been removed:
* `bin/pack.php`
diff --git a/docs/simplesamlphp-upgrade-notes-1.5.txt b/docs/simplesamlphp-upgrade-notes-1.5.md
index b8a61f6..b8a61f6 100644
--- a/docs/simplesamlphp-upgrade-notes-1.5.txt
+++ b/docs/simplesamlphp-upgrade-notes-1.5.md
diff --git a/docs/simplesamlphp-upgrade-notes-1.6.txt b/docs/simplesamlphp-upgrade-notes-1.6.md
index b918cc9..b918cc9 100644
--- a/docs/simplesamlphp-upgrade-notes-1.6.txt
+++ b/docs/simplesamlphp-upgrade-notes-1.6.md
diff --git a/docs/simplesamlphp-upgrade-notes-1.7.txt b/docs/simplesamlphp-upgrade-notes-1.7.md
index fa4ce08..fa4ce08 100644
--- a/docs/simplesamlphp-upgrade-notes-1.7.txt
+++ b/docs/simplesamlphp-upgrade-notes-1.7.md
diff --git a/docs/simplesamlphp-upgrade-notes-1.8.txt b/docs/simplesamlphp-upgrade-notes-1.8.md
index 50e5986..50e5986 100644
--- a/docs/simplesamlphp-upgrade-notes-1.8.txt
+++ b/docs/simplesamlphp-upgrade-notes-1.8.md
diff --git a/docs/simplesamlphp-upgrade-notes-1.9.txt b/docs/simplesamlphp-upgrade-notes-1.9.md
index f7af097..f7af097 100644
--- a/docs/simplesamlphp-upgrade-notes-1.9.txt
+++ b/docs/simplesamlphp-upgrade-notes-1.9.md
diff --git a/lib/SimpleSAML/Auth/Simple.php b/lib/SimpleSAML/Auth/Simple.php
index ca790ed..723c866 100644
--- a/lib/SimpleSAML/Auth/Simple.php
+++ b/lib/SimpleSAML/Auth/Simple.php
@@ -1,331 +1,343 @@
<?php
+
/**
* Helper class for simple authentication applications.
*
* @package SimpleSAMLphp
*/
-class SimpleSAML_Auth_Simple {
-
- /**
- * The id of the authentication source we are accessing.
- *
- * @var string
- */
- private $authSource;
-
-
- /**
- * Create an instance with the specified authsource.
- *
- * @param string $authSource The id of the authentication source.
- */
- public function __construct($authSource) {
- assert('is_string($authSource)');
-
- $this->authSource = $authSource;
- }
-
-
- /**
- * Retrieve the implementing authentication source.
- *
- * @return SimpleSAML_Auth_Source The authentication source.
- */
- public function getAuthSource() {
- $as = SimpleSAML_Auth_Source::getById($this->authSource);
- if ($as === null) {
- throw new SimpleSAML_Error_AuthSource($this->authSource, 'Unknown authentication source.');
- }
- return $as;
- }
-
-
- /**
- * Check if the user is authenticated.
- *
- * This function checks if the user is authenticated with the default
- * authentication source selected by the 'default-authsource' option in
- * 'config.php'.
- *
- * @return bool TRUE if the user is authenticated, FALSE if not.
- */
- public function isAuthenticated() {
- $session = SimpleSAML_Session::getSessionFromRequest();
-
- return $session->isValid($this->authSource);
- }
-
-
- /**
- * Require the user to be authenticated.
- *
- * If the user is authenticated, this function returns immediately.
- *
- * If the user isn't authenticated, this function will authenticate the
- * user with the authentication source, and then return the user to the
- * current page.
- *
- * This function accepts an array $params, which controls some parts of
- * the authentication. See the login()-function for a description.
- *
- * @param array $params Various options to the authentication request.
- */
- public function requireAuth(array $params = array()) {
-
- $session = SimpleSAML_Session::getSessionFromRequest();
-
- if ($session->isValid($this->authSource)) {
- // Already authenticated
- return;
- }
-
- $this->login($params);
- }
-
-
- /**
- * Start an authentication process.
- *
- * This function never returns.
- *
- * This function accepts an array $params, which controls some parts of
- * the authentication. The accepted parameters depends on the authentication
- * source being used. Some parameters are generic:
- * - 'ErrorURL': A URL that should receive errors from the authentication.
- * - 'KeepPost': If the current request is a POST request, keep the POST
- * data until after the authentication.
- * - 'ReturnTo': The URL the user should be returned to after authentication.
- * - 'ReturnCallback': The function we should call after the user has
- * finished authentication.
- *
- * @param array $params Various options to the authentication request.
- */
- public function login(array $params = array()) {
-
- if (array_key_exists('KeepPost', $params)) {
- $keepPost = (bool)$params['KeepPost'];
- } else {
- $keepPost = TRUE;
- }
-
- if (array_key_exists('ReturnTo', $params)) {
- $returnTo = (string)$params['ReturnTo'];
- } else if (array_key_exists('ReturnCallback', $params)) {
- $returnTo = (array)$params['ReturnCallback'];
- } else {
- $returnTo = \SimpleSAML\Utils\HTTP::getSelfURL();
- }
-
- if (is_string($returnTo) && $keepPost && $_SERVER['REQUEST_METHOD'] === 'POST') {
- $returnTo = \SimpleSAML\Utils\HTTP::getPOSTRedirectURL($returnTo, $_POST);
- }
-
- if (array_key_exists('ErrorURL', $params)) {
- $errorURL = (string)$params['ErrorURL'];
- } else {
- $errorURL = NULL;
- }
-
-
- if (!isset($params[SimpleSAML_Auth_State::RESTART]) && is_string($returnTo)) {
- /*
- * A URL to restart the authentication, in case the user bookmarks
- * something, e.g. the discovery service page.
- */
- $restartURL = $this->getLoginURL($returnTo);
- $params[SimpleSAML_Auth_State::RESTART] = $restartURL;
- }
-
- $as = $this->getAuthSource();
- $as->initLogin($returnTo, $errorURL, $params);
- assert('FALSE');
- }
-
-
- /**
- * Log the user out.
- *
- * This function logs the user out. It will never return. By default,
- * it will cause a redirect to the current page after logging the user
- * out, but a different URL can be given with the $params parameter.
- *
- * Generic parameters are:
- * - 'ReturnTo': The URL the user should be returned to after logout.
- * - 'ReturnCallback': The function that should be called after logout.
- * - 'ReturnStateParam': The parameter we should return the state in when redirecting.
- * - 'ReturnStateStage': The stage the state array should be saved with.
- *
- * @param string|array|NULL $params Either the URL the user should be redirected to after logging out,
- * or an array with parameters for the logout. If this parameter is
- * NULL, we will return to the current page.
- */
- public function logout($params = NULL) {
- assert('is_array($params) || is_string($params) || is_null($params)');
-
- if ($params === NULL) {
- $params = \SimpleSAML\Utils\HTTP::getSelfURL();
- }
-
- if (is_string($params)) {
- $params = array(
- 'ReturnTo' => $params,
- );
- }
-
- assert('is_array($params)');
- assert('isset($params["ReturnTo"]) || isset($params["ReturnCallback"])');
-
- if (isset($params['ReturnStateParam']) || isset($params['ReturnStateStage'])) {
- assert('isset($params["ReturnStateParam"]) && isset($params["ReturnStateStage"])');
- }
-
- $session = SimpleSAML_Session::getSessionFromRequest();
- if ($session->isValid($this->authSource)) {
- $state = $session->getAuthData($this->authSource, 'LogoutState');
- if ($state !== NULL) {
- $params = array_merge($state, $params);
- }
-
- $session->doLogout($this->authSource);
-
- $params['LogoutCompletedHandler'] = array(get_class(), 'logoutCompleted');
-
- $as = SimpleSAML_Auth_Source::getById($this->authSource);
- if ($as !== NULL) {
- $as->logout($params);
- }
- }
-
- self::logoutCompleted($params);
- }
-
-
- /**
- * Called when logout operation completes.
- *
- * This function never returns.
- *
- * @param array $state The state after the logout.
- */
- public static function logoutCompleted($state) {
- assert('is_array($state)');
- assert('isset($state["ReturnTo"]) || isset($state["ReturnCallback"])');
-
- if (isset($state['ReturnCallback'])) {
- call_user_func($state['ReturnCallback'], $state);
- assert('FALSE');
- } else {
- $params = array();
- if (isset($state['ReturnStateParam']) || isset($state['ReturnStateStage'])) {
- assert('isset($state["ReturnStateParam"]) && isset($state["ReturnStateStage"])');
- $stateID = SimpleSAML_Auth_State::saveState($state, $state['ReturnStateStage']);
- $params[$state['ReturnStateParam']] = $stateID;
- }
- \SimpleSAML\Utils\HTTP::redirectTrustedURL($state['ReturnTo'], $params);
- }
- }
-
-
- /**
- * Retrieve attributes of the current user.
- *
- * This function will retrieve the attributes of the current user if
- * the user is authenticated. If the user isn't authenticated, it will
- * return an empty array.
- *
- * @return array The users attributes.
- */
- public function getAttributes() {
-
- if (!$this->isAuthenticated()) {
- // Not authenticated
- return array();
- }
-
- // Authenticated
- $session = SimpleSAML_Session::getSessionFromRequest();
- return $session->getAuthData($this->authSource, 'Attributes');
- }
-
-
- /**
- * Retrieve authentication data.
- *
- * @param string $name The name of the parameter, e.g. 'Attributes', 'Expire' or 'saml:sp:IdP'.
- * @return mixed|NULL The value of the parameter, or NULL if it isn't found or we are unauthenticated.
- */
- public function getAuthData($name) {
- assert('is_string($name)');
-
- if (!$this->isAuthenticated()) {
- return NULL;
- }
-
- $session = SimpleSAML_Session::getSessionFromRequest();
- return $session->getAuthData($this->authSource, $name);
- }
-
-
- /**
- * Retrieve all authentication data.
- *
- * @return array|NULL All persistent authentication data, or NULL if we aren't authenticated.
- */
- public function getAuthDataArray() {
-
- if (!$this->isAuthenticated()) {
- return NULL;
- }
-
- $session = SimpleSAML_Session::getSessionFromRequest();
- return $session->getAuthState($this->authSource);
- }
-
-
- /**
- * Retrieve a URL that can be used to log the user in.
- *
- * @param string|NULL $returnTo The page the user should be returned to afterwards.
- * If this parameter is NULL, the user will be returned to the current page.
- * @return string A URL which is suitable for use in link-elements.
- */
- public function getLoginURL($returnTo = NULL) {
- assert('is_null($returnTo) || is_string($returnTo)');
-
- if ($returnTo === NULL) {
- $returnTo = \SimpleSAML\Utils\HTTP::getSelfURL();
- }
-
- $login = SimpleSAML\Module::getModuleURL('core/as_login.php', array(
- 'AuthId' => $this->authSource,
- 'ReturnTo' => $returnTo,
- ));
-
- return $login;
- }
-
-
- /**
- * Retrieve a URL that can be used to log the user out.
- *
- * @param string|NULL $returnTo The page the user should be returned to afterwards.
- * If this parameter is NULL, the user will be returned to the current page.
- * @return string A URL which is suitable for use in link-elements.
- */
- public function getLogoutURL($returnTo = NULL) {
- assert('is_null($returnTo) || is_string($returnTo)');
-
- if ($returnTo === NULL) {
- $returnTo = \SimpleSAML\Utils\HTTP::getSelfURL();
- }
-
- $logout = SimpleSAML\Module::getModuleURL('core/as_logout.php', array(
- 'AuthId' => $this->authSource,
- 'ReturnTo' => $returnTo,
- ));
-
- return $logout;
- }
-
+class SimpleSAML_Auth_Simple
+{
+
+ /**
+ * The id of the authentication source we are accessing.
+ *
+ * @var string
+ */
+ private $authSource;
+
+
+ /**
+ * Create an instance with the specified authsource.
+ *
+ * @param string $authSource The id of the authentication source.
+ */
+ public function __construct($authSource)
+ {
+ assert('is_string($authSource)');
+
+ $this->authSource = $authSource;
+ }
+
+
+ /**
+ * Retrieve the implementing authentication source.
+ *
+ * @return SimpleSAML_Auth_Source The authentication source.
+ *
+ * @throws SimpleSAML_Error_AuthSource If the requested auth source is unknown.
+ */
+ public function getAuthSource()
+ {
+ $as = SimpleSAML_Auth_Source::getById($this->authSource);
+ if ($as === null) {
+ throw new SimpleSAML_Error_AuthSource($this->authSource, 'Unknown authentication source.');
+ }
+ return $as;
+ }
+
+
+ /**
+ * Check if the user is authenticated.
+ *
+ * This function checks if the user is authenticated with the default authentication source selected by the
+ * 'default-authsource' option in 'config.php'.
+ *
+ * @return bool True if the user is authenticated, false if not.
+ */
+ public function isAuthenticated()
+ {
+ $session = SimpleSAML_Session::getSessionFromRequest();
+
+ return $session->isValid($this->authSource);
+ }
+
+
+ /**
+ * Require the user to be authenticated.
+ *
+ * If the user is authenticated, this function returns immediately.
+ *
+ * If the user isn't authenticated, this function will authenticate the user with the authentication source, and
+ * then return the user to the current page.
+ *
+ * This function accepts an array $params, which controls some parts of the authentication. See the login()
+ * method for a description.
+ *
+ * @param array $params Various options to the authentication request. See the documentation.
+ */
+ public function requireAuth(array $params = array())
+ {
+
+ $session = SimpleSAML_Session::getSessionFromRequest();
+
+ if ($session->isValid($this->authSource)) {
+ // Already authenticated
+ return;
+ }
+
+ $this->login($params);
+ }
+
+
+ /**
+ * Start an authentication process.
+ *
+ * This function accepts an array $params, which controls some parts of the authentication. The accepted parameters
+ * depends on the authentication source being used. Some parameters are generic:
+ * - 'ErrorURL': A URL that should receive errors from the authentication.
+ * - 'KeepPost': If the current request is a POST request, keep the POST data until after the authentication.
+ * - 'ReturnTo': The URL the user should be returned to after authentication.
+ * - 'ReturnCallback': The function we should call after the user has finished authentication.
+ *
+ * Please note: this function never returns.
+ *
+ * @param array $params Various options to the authentication request.
+ */
+ public function login(array $params = array())
+ {
+
+ if (array_key_exists('KeepPost', $params)) {
+ $keepPost = (bool) $params['KeepPost'];
+ } else {
+ $keepPost = true;
+ }
+
+ if (array_key_exists('ReturnTo', $params)) {
+ $returnTo = (string) $params['ReturnTo'];
+ } else {
+ if (array_key_exists('ReturnCallback', $params)) {
+ $returnTo = (array) $params['ReturnCallback'];
+ } else {
+ $returnTo = \SimpleSAML\Utils\HTTP::getSelfURL();
+ }
+ }
+
+ if (is_string($returnTo) && $keepPost && $_SERVER['REQUEST_METHOD'] === 'POST') {
+ $returnTo = \SimpleSAML\Utils\HTTP::getPOSTRedirectURL($returnTo, $_POST);
+ }
+
+ if (array_key_exists('ErrorURL', $params)) {
+ $errorURL = (string) $params['ErrorURL'];
+ } else {
+ $errorURL = null;
+ }
+
+
+ if (!isset($params[SimpleSAML_Auth_State::RESTART]) && is_string($returnTo)) {
+ /*
+ * A URL to restart the authentication, in case the user bookmarks
+ * something, e.g. the discovery service page.
+ */
+ $restartURL = $this->getLoginURL($returnTo);
+ $params[SimpleSAML_Auth_State::RESTART] = $restartURL;
+ }
+
+ $as = $this->getAuthSource();
+ $as->initLogin($returnTo, $errorURL, $params);
+ assert('false');
+ }
+
+
+ /**
+ * Log the user out.
+ *
+ * This function logs the user out. It will never return. By default, it will cause a redirect to the current page
+ * after logging the user out, but a different URL can be given with the $params parameter.
+ *
+ * Generic parameters are:
+ * - 'ReturnTo': The URL the user should be returned to after logout.
+ * - 'ReturnCallback': The function that should be called after logout.
+ * - 'ReturnStateParam': The parameter we should return the state in when redirecting.
+ * - 'ReturnStateStage': The stage the state array should be saved with.
+ *
+ * @param string|array|NULL $params Either the URL the user should be redirected to after logging out, or an array
+ * with parameters for the logout. If this parameter is null, we will return to the current page.
+ */
+ public function logout($params = null)
+ {
+ assert('is_array($params) || is_string($params) || is_null($params)');
+
+ if ($params === null) {
+ $params = \SimpleSAML\Utils\HTTP::getSelfURL();
+ }
+
+ if (is_string($params)) {
+ $params = array(
+ 'ReturnTo' => $params,
+ );
+ }
+
+ assert('is_array($params)');
+ assert('isset($params["ReturnTo"]) || isset($params["ReturnCallback"])');
+
+ if (isset($params['ReturnStateParam']) || isset($params['ReturnStateStage'])) {
+ assert('isset($params["ReturnStateParam"]) && isset($params["ReturnStateStage"])');
+ }
+
+ $session = SimpleSAML_Session::getSessionFromRequest();
+ if ($session->isValid($this->authSource)) {
+ $state = $session->getAuthData($this->authSource, 'LogoutState');
+ if ($state !== null) {
+ $params = array_merge($state, $params);
+ }
+
+ $session->doLogout($this->authSource);
+
+ $params['LogoutCompletedHandler'] = array(get_class(), 'logoutCompleted');
+
+ $as = SimpleSAML_Auth_Source::getById($this->authSource);
+ if ($as !== null) {
+ $as->logout($params);
+ }
+ }
+
+ self::logoutCompleted($params);
+ }
+
+
+ /**
+ * Called when logout operation completes.
+ *
+ * This function never returns.
+ *
+ * @param array $state The state after the logout.
+ */
+ public static function logoutCompleted($state)
+ {
+ assert('is_array($state)');
+ assert('isset($state["ReturnTo"]) || isset($state["ReturnCallback"])');
+
+ if (isset($state['ReturnCallback'])) {
+ call_user_func($state['ReturnCallback'], $state);
+ assert('false');
+ } else {
+ $params = array();
+ if (isset($state['ReturnStateParam']) || isset($state['ReturnStateStage'])) {
+ assert('isset($state["ReturnStateParam"]) && isset($state["ReturnStateStage"])');
+ $stateID = SimpleSAML_Auth_State::saveState($state, $state['ReturnStateStage']);
+ $params[$state['ReturnStateParam']] = $stateID;
+ }
+ \SimpleSAML\Utils\HTTP::redirectTrustedURL($state['ReturnTo'], $params);
+ }
+ }
+
+
+ /**
+ * Retrieve attributes of the current user.
+ *
+ * This function will retrieve the attributes of the current user if the user is authenticated. If the user isn't
+ * authenticated, it will return an empty array.
+ *
+ * @return array The users attributes.
+ */
+ public function getAttributes()
+ {
+
+ if (!$this->isAuthenticated()) {
+ // Not authenticated
+ return array();
+ }
+
+ // Authenticated
+ $session = SimpleSAML_Session::getSessionFromRequest();
+ return $session->getAuthData($this->authSource, 'Attributes');
+ }
+
+
+ /**
+ * Retrieve authentication data.
+ *
+ * @param string $name The name of the parameter, e.g. 'Attributes', 'Expire' or 'saml:sp:IdP'.
+ *
+ * @return mixed|null The value of the parameter, or null if it isn't found or we are unauthenticated.
+ */
+ public function getAuthData($name)
+ {
+ assert('is_string($name)');
+
+ if (!$this->isAuthenticated()) {
+ return null;
+ }
+
+ $session = SimpleSAML_Session::getSessionFromRequest();
+ return $session->getAuthData($this->authSource, $name);
+ }
+
+
+ /**
+ * Retrieve all authentication data.
+ *
+ * @return array|null All persistent authentication data, or null if we aren't authenticated.
+ */
+ public function getAuthDataArray()
+ {
+
+ if (!$this->isAuthenticated()) {
+ return null;
+ }
+
+ $session = SimpleSAML_Session::getSessionFromRequest();
+ return $session->getAuthState($this->authSource);
+ }
+
+
+ /**
+ * Retrieve a URL that can be used to log the user in.
+ *
+ * @param string|null $returnTo The page the user should be returned to afterwards. If this parameter is null, the
+ * user will be returned to the current page.
+ *
+ * @return string A URL which is suitable for use in link-elements.
+ */
+ public function getLoginURL($returnTo = null)
+ {
+ assert('is_null($returnTo) || is_string($returnTo)');
+
+ if ($returnTo === null) {
+ $returnTo = \SimpleSAML\Utils\HTTP::getSelfURL();
+ }
+
+ $login = SimpleSAML\Module::getModuleURL('core/as_login.php', array(
+ 'AuthId' => $this->authSource,
+ 'ReturnTo' => $returnTo,
+ ));
+
+ return $login;
+ }
+
+
+ /**
+ * Retrieve a URL that can be used to log the user out.
+ *
+ * @param string|null $returnTo The page the user should be returned to afterwards. If this parameter is null, the
+ * user will be returned to the current page.
+ *
+ * @return string A URL which is suitable for use in link-elements.
+ */
+ public function getLogoutURL($returnTo = null)
+ {
+ assert('is_null($returnTo) || is_string($returnTo)');
+
+ if ($returnTo === null) {
+ $returnTo = \SimpleSAML\Utils\HTTP::getSelfURL();
+ }
+
+ $logout = SimpleSAML\Module::getModuleURL('core/as_logout.php', array(
+ 'AuthId' => $this->authSource,
+ 'ReturnTo' => $returnTo,
+ ));
+
+ return $logout;
+ }
}
diff --git a/lib/SimpleSAML/Bindings/Shib13/Artifact.php b/lib/SimpleSAML/Bindings/Shib13/Artifact.php
index 38fd064..09c6365 100644
--- a/lib/SimpleSAML/Bindings/Shib13/Artifact.php
+++ b/lib/SimpleSAML/Bindings/Shib13/Artifact.php
@@ -75,7 +75,7 @@ class SimpleSAML_Bindings_Shib13_Artifact {
assert('is_string($soapResponse)');
try {
- $doc = SAML2_DOMDocumentFactory::fromString($soapResponse);
+ $doc = \SAML2\DOMDocumentFactory::fromString($soapResponse);
} catch(\Exception $e) {
throw new SimpleSAML_Error_Exception('Error parsing SAML 1 artifact response.');
}
@@ -102,7 +102,7 @@ class SimpleSAML_Bindings_Shib13_Artifact {
* Save the <saml1p:Response> element. Note that we need to import it
* into a new document, in order to preserve namespace declarations.
*/
- $newDoc = SAML2_DOMDocumentFactory::create();
+ $newDoc = \SAML2\DOMDocumentFactory::create();
$newDoc->appendChild($newDoc->importNode($responseElement, TRUE));
$responseXML = $newDoc->saveXML();
diff --git a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php
index c92e0f1..30ddf25 100644
--- a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php
+++ b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php
@@ -58,7 +58,7 @@ class SimpleSAML_Bindings_Shib13_HTTPPost
$privatekey = SimpleSAML\Utils\Crypto::loadPrivateKey($idpmd, true);
$publickey = SimpleSAML\Utils\Crypto::loadPublicKey($idpmd, true);
- $responsedom = SAML2_DOMDocumentFactory::fromString(str_replace("\r", "", $response));
+ $responsedom = \SAML2\DOMDocumentFactory::fromString(str_replace("\r", "", $response));
$responseroot = $responsedom->getElementsByTagName('Response')->item(0);
$firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0);
diff --git a/lib/SimpleSAML/Configuration.php b/lib/SimpleSAML/Configuration.php
index fb2108d..61f5209 100644
--- a/lib/SimpleSAML/Configuration.php
+++ b/lib/SimpleSAML/Configuration.php
@@ -72,6 +72,14 @@ class SimpleSAML_Configuration
/**
+ * Temporary property that tells if the deprecated getBaseURL() method has been called or not.
+ *
+ * @var bool
+ */
+ private $deprecated_base_url_used = false;
+
+
+ /**
* Initializes a configuration from the given array.
*
* @param array $config The configuration array.
@@ -444,25 +452,51 @@ class SimpleSAML_Configuration
* @return string The absolute path relative to the root of the website.
*
* @throws SimpleSAML\Error\CriticalConfigurationError If the format of 'baseurlpath' is incorrect.
+ *
+ * @deprecated This method will be removed in SimpleSAMLphp 2.0. Please use getBasePath() instead.
*/
public function getBaseURL()
{
- $baseURL = $this->getString('baseurlpath', 'simplesaml/');
-
- if (preg_match('/^\*(.*)$/D', $baseURL, $matches)) {
+ if (!$this->deprecated_base_url_used) {
+ $this->deprecated_base_url_used = true;
+ SimpleSAML\Logger::warning(
+ "SimpleSAML_Configuration::getBaseURL() is deprecated, please use getBasePath() instead."
+ );
+ }
+ if (preg_match('/^\*(.*)$/D', $this->getString('baseurlpath', 'simplesaml/'), $matches)) {
// deprecated behaviour, will be removed in the future
return \SimpleSAML\Utils\HTTP::getFirstPathElement(false).$matches[1];
}
+ return ltrim($this->getBasePath(), '/');
+ }
- if (preg_match('#^https?://[^/]*/(.*)$#', $baseURL, $matches)) {
+
+ /**
+ * Retrieve the absolute path pointing to the SimpleSAMLphp installation.
+ *
+ * The path is guaranteed to start and end with a slash ('/'). E.g.: /simplesaml/
+ *
+ * @return string The absolute path where SimpleSAMLphp can be reached in the web server.
+ *
+ * @throws SimpleSAML\Error\CriticalConfigurationError If the format of 'baseurlpath' is incorrect.
+ */
+ public function getBasePath()
+ {
+ $baseURL = $this->getString('baseurlpath', 'simplesaml/');
+
+ if (preg_match('#^https?://[^/]*(?:/(.+/?)?)?$#', $baseURL, $matches)) {
// we have a full url, we need to strip the path
- return $matches[1];
+ if (!array_key_exists(1, $matches)) {
+ // absolute URL without path
+ return '/';
+ }
+ return '/'.rtrim($matches[1], '/')."/";
} elseif ($baseURL === '' || $baseURL === '/') {
- // Root directory of site
- return '';
- } elseif (preg_match('#^/?([^/]?.*/)#D', $baseURL, $matches)) {
+ // root directory of site
+ return '/';
+ } elseif (preg_match('#^/?((?:[^/\s]+/?)+)#', $baseURL, $matches)) {
// local path only
- return $matches[1];
+ return '/'.rtrim($matches[1], '/').'/';
} else {
/*
* Invalid 'baseurlpath'. We cannot recover from this, so throw a critical exception and try to be graceful
@@ -561,8 +595,8 @@ class SimpleSAML_Configuration
$dir = $this->getString('basedir', null);
if ($dir !== null) {
// add trailing slash if it is missing
- if (substr($dir, -1) !== '/') {
- $dir .= '/';
+ if (substr($dir, -1) !== DIRECTORY_SEPARATOR) {
+ $dir .= DIRECTORY_SEPARATOR;
}
return $dir;
@@ -580,8 +614,8 @@ class SimpleSAML_Configuration
$dir = dirname($dir);
- // Add trailing slash
- $dir .= '/';
+ // Add trailing directory separator
+ $dir .= DIRECTORY_SEPARATOR;
return $dir;
}
@@ -1037,11 +1071,11 @@ class SimpleSAML_Configuration
case 'saml20-idp-remote:SingleSignOnService':
case 'saml20-idp-remote:SingleLogoutService':
case 'saml20-sp-remote:SingleLogoutService':
- return SAML2_Const::BINDING_HTTP_REDIRECT;
+ return \SAML2\Constants::BINDING_HTTP_REDIRECT;
case 'saml20-sp-remote:AssertionConsumerService':
- return SAML2_Const::BINDING_HTTP_POST;
+ return \SAML2\Constants::BINDING_HTTP_POST;
case 'saml20-idp-remote:ArtifactResolutionService':
- return SAML2_Const::BINDING_SOAP;
+ return \SAML2\Constants::BINDING_SOAP;
case 'shib13-idp-remote:SingleSignOnService':
return 'urn:mace:shibboleth:1.0:profiles:AuthnRequest';
case 'shib13-sp-remote:AssertionConsumerService':
diff --git a/lib/SimpleSAML/Error/CannotSetCookie.php b/lib/SimpleSAML/Error/CannotSetCookie.php
new file mode 100644
index 0000000..31a25b0
--- /dev/null
+++ b/lib/SimpleSAML/Error/CannotSetCookie.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Exception to indicate that we cannot set a cookie.
+ *
+ * @author Jaime Pérez Crespo <jaime.perez@uninett.no>
+ * @package SimpleSAMLphp
+ */
+
+namespace SimpleSAML\Error;
+
+
+class CannotSetCookie extends \SimpleSAML_Error_Exception
+{
+
+ /**
+ * The exception was thrown for unknown reasons.
+ *
+ * @var int
+ */
+ const UNKNOWN = 0;
+
+ /**
+ * The exception was due to the HTTP headers being already sent, and therefore we cannot send additional headers to
+ * set the cookie.
+ *
+ * @var int
+ */
+ const HEADERS_SENT = 1;
+
+ /**
+ * The exception was due to trying to set a secure cookie over an insecure channel.
+ *
+ * @var int
+ */
+ const SECURE_COOKIE = 2;
+}
diff --git a/lib/SimpleSAML/Error/CriticalConfigurationError.php b/lib/SimpleSAML/Error/CriticalConfigurationError.php
index 3d036f7..76af87f 100644
--- a/lib/SimpleSAML/Error/CriticalConfigurationError.php
+++ b/lib/SimpleSAML/Error/CriticalConfigurationError.php
@@ -48,7 +48,6 @@ class CriticalConfigurationError extends ConfigurationError
{
if ($config === null) {
$config = self::$minimum_config;
- } else {
$config['baseurlpath'] = \SimpleSAML\Utils\HTTP::guessBasePath();
}
diff --git a/lib/SimpleSAML/Error/Error.php b/lib/SimpleSAML/Error/Error.php
index 7689d5f..542c35b 100644
--- a/lib/SimpleSAML/Error/Error.php
+++ b/lib/SimpleSAML/Error/Error.php
@@ -44,9 +44,9 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
/**
- * The name of module which throw error.
+ * The name of module that threw the error.
*
- * @var string|NULL
+ * @var string|null
*/
private $module = null;
@@ -62,7 +62,7 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
/**
* Name of custom include template for the error.
*
- * @var string|NULL
+ * @var string|null
*/
protected $includeTemplate = null;
diff --git a/lib/SimpleSAML/Error/Exception.php b/lib/SimpleSAML/Error/Exception.php
index 019a27c..bd54a9a 100644
--- a/lib/SimpleSAML/Error/Exception.php
+++ b/lib/SimpleSAML/Error/Exception.php
@@ -214,7 +214,7 @@ class SimpleSAML_Error_Exception extends Exception
*
* Override to allow errors extending this class to specify the log level themselves.
*
- * @param int $default_level The log level to use if this method was not overriden.
+ * @param int $default_level The log level to use if this method was not overridden.
*/
public function log($default_level)
{
diff --git a/lib/SimpleSAML/Locale/Language.php b/lib/SimpleSAML/Locale/Language.php
index f843da0..412fc2a 100644
--- a/lib/SimpleSAML/Locale/Language.php
+++ b/lib/SimpleSAML/Locale/Language.php
@@ -69,6 +69,52 @@ class Language
*/
private $customFunction;
+ /**
+ * A list of languages supported with their names localized, indexed by ISO 639-2 code.
+ *
+ * @var array
+ */
+ private $language_names = array(
+ 'no' => 'Bokmål', // Norwegian Bokmål
+ 'nn' => 'Nynorsk', // Norwegian Nynorsk
+ 'se' => 'Sámegiella', // Northern Sami
+ 'sam' => 'Åarjelh-saemien giele', // Southern Sami
+ 'da' => 'Dansk', // Danish
+ 'en' => 'English',
+ 'de' => 'Deutsch', // German
+ 'sv' => 'Svenska', // Swedish
+ 'fi' => 'Suomeksi', // Finnish
+ 'es' => 'Español', // Spanish
+ 'fr' => 'Français', // French
+ 'it' => 'Italiano', // Italian
+ 'nl' => 'Nederlands', // Dutch
+ 'lb' => 'Lëtzebuergesch', // Luxembourgish
+ 'cs' => 'Čeština', // Czech
+ 'sl' => 'Slovenščina', // Slovensk
+ 'lt' => 'Lietuvių kalba', // Lithuanian
+ 'hr' => 'Hrvatski', // Croatian
+ 'hu' => 'Magyar', // Hungarian
+ 'pl' => 'Język polski', // Polish
+ 'pt' => 'Português', // Portuguese
+ 'pt-br' => 'Português brasileiro', // Portuguese
+ 'ru' => 'русский язык', // Russian
+ 'et' => 'eesti keel', // Estonian
+ 'tr' => 'Türkçe', // Turkish
+ 'el' => 'ελληνικά', // Greek
+ 'ja' => '日本語', // Japanese
+ 'zh' => '简体中文', // Chinese (simplified)
+ 'zh-tw' => '繁體中文', // Chinese (traditional)
+ 'ar' => 'العربية', // Arabic
+ 'fa' => 'پارسی', // Persian
+ 'ur' => 'اردو', // Urdu
+ 'he' => 'עִבְרִית', // Hebrew
+ 'id' => 'Bahasa Indonesia', // Indonesian
+ 'sr' => 'Srpski', // Serbian
+ 'lv' => 'Latviešu', // Latvian
+ 'ro' => 'Românește', // Romanian
+ 'eu' => 'Euskara', // Basque
+ );
+
/**
* Constructor
@@ -152,6 +198,19 @@ class Language
/**
+ * Get the localized name of a language, by ISO 639-2 code.
+ *
+ * @param string $code The ISO 639-2 code of the language.
+ *
+ * @return string The localized name of the language.
+ */
+ public function getLanguageLocalizedName($code)
+ {
+ return $this->language_names[$code];
+ }
+
+
+ /**
* Get the language parameter name.
*
* @return string The language parameter name.
diff --git a/lib/SimpleSAML/Locale/Translate.php b/lib/SimpleSAML/Locale/Translate.php
index ebbac32..dba41a8 100644
--- a/lib/SimpleSAML/Locale/Translate.php
+++ b/lib/SimpleSAML/Locale/Translate.php
@@ -56,7 +56,7 @@ class Translate
// for backwards compatibility - print warning
$backtrace = debug_backtrace();
$where = $backtrace[0]['file'].':'.$backtrace[0]['line'];
- \SimpleSAML_Logger::warning(
+ \SimpleSAML\Logger::warning(
'Deprecated use of new SimpleSAML\Locale\Translate(...) at '.$where.
'. The last parameter is now a dictionary name, which should not end in ".php".'
);
@@ -96,7 +96,7 @@ class Translate
if ($sepPos !== false) {
$module = substr($name, 0, $sepPos);
$fileName = substr($name, $sepPos + 1);
- $dictDir = \SimpleSAML_Module::getModuleDir($module).'/dictionaries/';
+ $dictDir = \SimpleSAML\Module::getModuleDir($module).'/dictionaries/';
} else {
$dictDir = $this->configuration->getPathValue('dictionarydir', 'dictionaries/');
$fileName = $name;
@@ -255,14 +255,14 @@ class Translate
// old style call to t(...). Print warning to log
$backtrace = debug_backtrace();
$where = $backtrace[0]['file'].':'.$backtrace[0]['line'];
- \SimpleSAML_Logger::warning(
+ \SimpleSAML\Logger::warning(
'Deprecated use of SimpleSAML_Template::t(...) at '.$where.
'. Please update the code to use the new style of parameters.'
);
// for backwards compatibility
if (!$replacements && $this->getTag($tag) === null) {
- \SimpleSAML_Logger::warning(
+ \SimpleSAML\Logger::warning(
'Code which uses $fallbackdefault === FALSE should be updated to use the getTag() method instead.'
);
return null;
@@ -277,7 +277,7 @@ class Translate
$tagData = $this->getTag($tag);
if ($tagData === null) {
// tag not found
- \SimpleSAML_Logger::info('Template: Looking up ['.$tag.']: not translated at all.');
+ \SimpleSAML\Logger::info('Template: Looking up ['.$tag.']: not translated at all.');
return $this->getStringNotTranslated($tag, $fallbackdefault);
}
}
@@ -332,7 +332,7 @@ class Translate
throw new \Exception("Inline translation should be string or array. Is ".gettype($translation)." now!");
}
- \SimpleSAML_Logger::debug('Template: Adding inline language translation for tag ['.$tag.']');
+ \SimpleSAML\Logger::debug('Template: Adding inline language translation for tag ['.$tag.']');
$this->langtext[$tag] = $translation;
}
@@ -355,7 +355,7 @@ class Translate
}
$lang = $this->readDictionaryFile($filebase.$file);
- \SimpleSAML_Logger::debug('Template: Merging language array. Loading ['.$file.']');
+ \SimpleSAML\Logger::debug('Template: Merging language array. Loading ['.$file.']');
$this->langtext = array_merge($this->langtext, $lang);
}
@@ -376,7 +376,7 @@ class Translate
$lang = json_decode($fileContent, true);
if (empty($lang)) {
- \SimpleSAML_Logger::error('Invalid dictionary definition file ['.$definitionFile.']');
+ \SimpleSAML\Logger::error('Invalid dictionary definition file ['.$definitionFile.']');
return array();
}
@@ -426,7 +426,7 @@ class Translate
{
assert('is_string($filename)');
- \SimpleSAML_Logger::debug('Template: Reading ['.$filename.']');
+ \SimpleSAML\Logger::debug('Template: Reading ['.$filename.']');
$jsonFile = $filename.'.definition.json';
if (file_exists($jsonFile)) {
@@ -438,7 +438,7 @@ class Translate
return $this->readDictionaryPHP($filename);
}
- \SimpleSAML_Logger::error(
+ \SimpleSAML\Logger::error(
$_SERVER['PHP_SELF'].' - Template: Could not find dictionary file at ['.$filename.']'
);
return array();
diff --git a/lib/SimpleSAML/Logger.php b/lib/SimpleSAML/Logger.php
index c5f433e..f838db1 100644
--- a/lib/SimpleSAML/Logger.php
+++ b/lib/SimpleSAML/Logger.php
@@ -267,7 +267,13 @@ class Logger
*/
public static function flush()
{
- $s = \SimpleSAML_Session::getSessionFromRequest();
+ try {
+ $s = \SimpleSAML_Session::getSessionFromRequest();
+ } catch (\Exception $e) {
+ // loading session failed. We don't care why, at this point we have a transient session, so we use that
+ self::error('Cannot load or create session: '.$e->getMessage());
+ $s = \SimpleSAML_Session::getSessionFromRequest();
+ }
self::$trackid = $s->getTrackID();
self::$shuttingDown = true;
@@ -399,6 +405,9 @@ class Logger
self::createLoggingHandler('SimpleSAML\Logger\StandardErrorLoggingHandler');
}
$_SERVER['REMOTE_ADDR'] = "CLI";
+ if (self::$trackid === self::NO_TRACKID) {
+ self::$trackid = 'CL'.bin2hex(openssl_random_pseudo_bytes(4));
+ }
} elseif (self::$loggingHandler === null) {
// Initialize logging
self::createLoggingHandler();
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
index 18083c2..33e5ef1 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
@@ -98,12 +98,11 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
$config = SimpleSAML_Configuration::getInstance();
assert($config instanceof SimpleSAML_Configuration);
- $baseurl = \SimpleSAML\Utils\HTTP::getSelfURLHost().'/'.
- $config->getBaseURL();
+ $baseurl = \SimpleSAML\Utils\HTTP::getSelfURLHost().$config->getBasePath();
if ($set == 'saml20-sp-hosted') {
if ($property === 'SingleLogoutServiceBinding') {
- return SAML2_Const::BINDING_HTTP_REDIRECT;
+ return \SAML2\Constants::BINDING_HTTP_REDIRECT;
}
} elseif ($set == 'saml20-idp-hosted') {
switch ($property) {
@@ -111,13 +110,13 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
return $baseurl.'saml2/idp/SSOService.php';
case 'SingleSignOnServiceBinding':
- return SAML2_Const::BINDING_HTTP_REDIRECT;
+ return \SAML2\Constants::BINDING_HTTP_REDIRECT;
case 'SingleLogoutService':
return $baseurl.'saml2/idp/SingleLogoutService.php';
case 'SingleLogoutServiceBinding':
- return SAML2_Const::BINDING_HTTP_REDIRECT;
+ return \SAML2\Constants::BINDING_HTTP_REDIRECT;
}
} elseif ($set == 'shib13-idp-hosted') {
if ($property === 'SingleSignOnService') {
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
index e898116..09c38b3 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
@@ -76,6 +76,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
* given file.
*
* @throws Exception If a database error occurs.
+ * @throws SimpleSAML_Error_Exception If the metadata can be retrieved from the database, but cannot be decoded.
*/
private function load($set)
{
@@ -92,7 +93,14 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
$metadata = array();
while ($d = $stmt->fetch()) {
- $metadata[$d['entity_id']] = json_decode($d['entity_data'], true);
+ $data = json_decode($d['entity_data'], true);
+ if ($data === null) {
+ throw new SimpleSAML_Error_Exception("Cannot decode metadata for entity '${d['entity_id']}'");
+ }
+ if (!array_key_exists('entityid', $data)) {
+ $data['entityid'] = $d['entity_id'];
+ }
+ $metadata[$d['entity_id']] = $data;
}
return $metadata;
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php
index a34f194..c487d31 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php
@@ -195,6 +195,10 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSerialize extends SimpleSAML_Met
return null;
}
+ if (!array_key_exists('entityid', $data)) {
+ $data['entityid'] = $entityId;
+ }
+
return $data;
}
diff --git a/lib/SimpleSAML/Metadata/SAMLBuilder.php b/lib/SimpleSAML/Metadata/SAMLBuilder.php
index 0d8f0e65..35156f7 100644
--- a/lib/SimpleSAML/Metadata/SAMLBuilder.php
+++ b/lib/SimpleSAML/Metadata/SAMLBuilder.php
@@ -15,7 +15,7 @@ class SimpleSAML_Metadata_SAMLBuilder
/**
* The EntityDescriptor we are building.
*
- * @var SAML2_XML_md_EntityDescriptor
+ * @var \SAML2\XML\md\EntityDescriptor
*/
private $entityDescriptor;
@@ -51,7 +51,7 @@ class SimpleSAML_Metadata_SAMLBuilder
$this->maxCache = $maxCache;
$this->maxDuration = $maxDuration;
- $this->entityDescriptor = new SAML2_XML_md_EntityDescriptor();
+ $this->entityDescriptor = new \SAML2\XML\md\EntityDescriptor();
$this->entityDescriptor->entityID = $entityId;
}
@@ -135,31 +135,31 @@ class SimpleSAML_Metadata_SAMLBuilder
* Add extensions to the metadata.
*
* @param SimpleSAML_Configuration $metadata The metadata to get extensions from.
- * @param SAML2_XML_md_RoleDescriptor $e Reference to the element where the Extensions element should be included.
+ * @param \SAML2\XML\md\RoleDescriptor $e Reference to the element where the Extensions element should be included.
*/
- private function addExtensions(SimpleSAML_Configuration $metadata, SAML2_XML_md_RoleDescriptor $e)
+ private function addExtensions(SimpleSAML_Configuration $metadata, \SAML2\XML\md\RoleDescriptor $e)
{
if ($metadata->hasValue('tags')) {
- $a = new SAML2_XML_saml_Attribute();
+ $a = new \SAML2\XML\saml\Attribute();
$a->Name = 'tags';
foreach ($metadata->getArray('tags') as $tag) {
- $a->AttributeValue[] = new SAML2_XML_saml_AttributeValue($tag);
+ $a->AttributeValue[] = new \SAML2\XML\saml\AttributeValue($tag);
}
$e->Extensions[] = $a;
}
if ($metadata->hasValue('hint.cidr')) {
- $a = new SAML2_XML_saml_Attribute();
+ $a = new \SAML2\XML\saml\Attribute();
$a->Name = 'hint.cidr';
foreach ($metadata->getArray('hint.cidr') as $hint) {
- $a->AttributeValue[] = new SAML2_XML_saml_AttributeValue($hint);
+ $a->AttributeValue[] = new \SAML2\XML\saml\AttributeValue($hint);
}
$e->Extensions[] = $a;
}
if ($metadata->hasValue('scope')) {
foreach ($metadata->getArray('scope') as $scopetext) {
- $s = new SAML2_XML_shibmd_Scope();
+ $s = new \SAML2\XML\shibmd\Scope();
$s->scope = $scopetext;
// Check whether $ ^ ( ) * | \ are in a scope -> assume regex.
if (1 === preg_match('/[\$\^\)\(\*\|\\\\]/', $scopetext)) {
@@ -172,9 +172,9 @@ class SimpleSAML_Metadata_SAMLBuilder
}
if ($metadata->hasValue('EntityAttributes')) {
- $ea = new SAML2_XML_mdattr_EntityAttributes();
+ $ea = new \SAML2\XML\mdattr\EntityAttributes();
foreach ($metadata->getArray('EntityAttributes') as $attributeName => $attributeValues) {
- $a = new SAML2_XML_saml_Attribute();
+ $a = new \SAML2\XML\saml\Attribute();
$a->Name = $attributeName;
$a->NameFormat = 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri';
@@ -182,12 +182,12 @@ class SimpleSAML_Metadata_SAMLBuilder
if (preg_match('/^\{(.*?)\}(.*)$/', $attributeName, $matches)) {
$a->Name = $matches[2];
$nameFormat = $matches[1];
- if ($nameFormat !== SAML2_Const::NAMEFORMAT_UNSPECIFIED) {
+ if ($nameFormat !== \SAML2\Constants::NAMEFORMAT_UNSPECIFIED) {
$a->NameFormat = $nameFormat;
}
}
foreach ($attributeValues as $attributeValue) {
- $a->AttributeValue[] = new SAML2_XML_saml_AttributeValue($attributeValue);
+ $a->AttributeValue[] = new \SAML2\XML\saml\AttributeValue($attributeValue);
}
$ea->children[] = $a;
}
@@ -195,14 +195,14 @@ class SimpleSAML_Metadata_SAMLBuilder
}
if ($metadata->hasValue('RegistrationInfo')) {
- $ri = new SAML2_XML_mdrpi_RegistrationInfo();
+ $ri = new \SAML2\XML\mdrpi\RegistrationInfo();
foreach ($metadata->getArray('RegistrationInfo') as $riName => $riValues) {
switch ($riName) {
case 'authority':
$ri->registrationAuthority = $riValues;
break;
case 'instant':
- $ri->registrationInstant = SAML2_Utils::xsDateTimeToTimestamp($riValues);
+ $ri->registrationInstant = \SAML2\Utils::xsDateTimeToTimestamp($riValues);
break;
case 'policies':
$ri->RegistrationPolicy = $riValues;
@@ -213,7 +213,7 @@ class SimpleSAML_Metadata_SAMLBuilder
}
if ($metadata->hasValue('UIInfo')) {
- $ui = new SAML2_XML_mdui_UIInfo();
+ $ui = new \SAML2\XML\mdui\UIInfo();
foreach ($metadata->getArray('UIInfo') as $uiName => $uiValues) {
switch ($uiName) {
case 'DisplayName':
@@ -230,7 +230,7 @@ class SimpleSAML_Metadata_SAMLBuilder
break;
case 'Keywords':
foreach ($uiValues as $lang => $keywords) {
- $uiItem = new SAML2_XML_mdui_Keywords();
+ $uiItem = new \SAML2\XML\mdui\Keywords();
$uiItem->lang = $lang;
$uiItem->Keywords = $keywords;
$ui->Keywords[] = $uiItem;
@@ -238,7 +238,7 @@ class SimpleSAML_Metadata_SAMLBuilder
break;
case 'Logo':
foreach ($uiValues as $logo) {
- $uiItem = new SAML2_XML_mdui_Logo();
+ $uiItem = new \SAML2\XML\mdui\Logo();
$uiItem->url = $logo['url'];
$uiItem->width = $logo['width'];
$uiItem->height = $logo['height'];
@@ -254,7 +254,7 @@ class SimpleSAML_Metadata_SAMLBuilder
}
if ($metadata->hasValue('DiscoHints')) {
- $dh = new SAML2_XML_mdui_DiscoHints();
+ $dh = new \SAML2\XML\mdui\DiscoHints();
foreach ($metadata->getArray('DiscoHints') as $dhName => $dhValues) {
switch ($dhName) {
case 'IPHint':
@@ -282,7 +282,7 @@ class SimpleSAML_Metadata_SAMLBuilder
*/
public function addOrganization(array $orgName, array $orgDisplayName, array $orgURL)
{
- $org = new SAML2_XML_md_Organization();
+ $org = new \SAML2\XML\md\Organization();
$org->OrganizationName = $orgName;
$org->OrganizationDisplayName = $orgDisplayName;
@@ -322,7 +322,7 @@ class SimpleSAML_Metadata_SAMLBuilder
* @param array $endpoints The endpoints.
* @param bool $indexed Whether the endpoints should be indexed.
*
- * @return array An array of endpoint objects, either SAML2_XML_md_EndpointType or SAML2_XML_md_IndexedEndpointType.
+ * @return array An array of endpoint objects, either \SAML2\XML\md\EndpointType or \SAML2\XML\md\IndexedEndpointType.
*/
private static function createEndpoints(array $endpoints, $indexed)
{
@@ -332,9 +332,9 @@ class SimpleSAML_Metadata_SAMLBuilder
foreach ($endpoints as &$ep) {
if ($indexed) {
- $t = new SAML2_XML_md_IndexedEndpointType();
+ $t = new \SAML2\XML\md\IndexedEndpointType();
} else {
- $t = new SAML2_XML_md_EndpointType();
+ $t = new \SAML2\XML\md\EndpointType();
}
$t->Binding = $ep['Binding'];
@@ -343,7 +343,11 @@ class SimpleSAML_Metadata_SAMLBuilder
$t->ResponseLocation = $ep['ResponseLocation'];
}
if (isset($ep['hoksso:ProtocolBinding'])) {
- $t->setAttributeNS(SAML2_Const::NS_HOK, 'hoksso:ProtocolBinding', SAML2_Const::BINDING_HTTP_REDIRECT);
+ $t->setAttributeNS(
+ \SAML2\Constants::NS_HOK,
+ 'hoksso:ProtocolBinding',
+ \SAML2\Constants::BINDING_HTTP_REDIRECT
+ );
}
if ($indexed) {
@@ -376,11 +380,11 @@ class SimpleSAML_Metadata_SAMLBuilder
/**
* Add an AttributeConsumingService element to the metadata.
*
- * @param SAML2_XML_md_SPSSODescriptor $spDesc The SPSSODescriptor element.
+ * @param \SAML2\XML\md\SPSSODescriptor $spDesc The SPSSODescriptor element.
* @param SimpleSAML_Configuration $metadata The metadata.
*/
private function addAttributeConsumingService(
- SAML2_XML_md_SPSSODescriptor $spDesc,
+ \SAML2\XML\md\SPSSODescriptor $spDesc,
SimpleSAML_Configuration $metadata
) {
$attributes = $metadata->getArray('attributes', array());
@@ -397,21 +401,21 @@ class SimpleSAML_Metadata_SAMLBuilder
* Add an AttributeConsumingService element with information as name and description and list
* of requested attributes
*/
- $attributeconsumer = new SAML2_XML_md_AttributeConsumingService();
+ $attributeconsumer = new \SAML2\XML\md\AttributeConsumingService();
$attributeconsumer->index = 0;
$attributeconsumer->ServiceName = $name;
$attributeconsumer->ServiceDescription = $metadata->getLocalizedString('description', array());
- $nameFormat = $metadata->getString('attributes.NameFormat', SAML2_Const::NAMEFORMAT_UNSPECIFIED);
+ $nameFormat = $metadata->getString('attributes.NameFormat', \SAML2\Constants::NAMEFORMAT_UNSPECIFIED);
foreach ($attributes as $friendlyName => $attribute) {
- $t = new SAML2_XML_md_RequestedAttribute();
+ $t = new \SAML2\XML\md\RequestedAttribute();
$t->Name = $attribute;
if (!is_int($friendlyName)) {
$t->FriendlyName = $friendlyName;
}
- if ($nameFormat !== SAML2_Const::NAMEFORMAT_UNSPECIFIED) {
+ if ($nameFormat !== \SAML2\Constants::NAMEFORMAT_UNSPECIFIED) {
$t->NameFormat = $nameFormat;
}
if (in_array($attribute, $attributesrequired)) {
@@ -463,9 +467,9 @@ class SimpleSAML_Metadata_SAMLBuilder
* Add SAML 2.0 SP metadata.
*
* @param array $metadata The metadata.
- * @param array $protocols The protocols supported. Defaults to SAML2_Const::NS_SAMLP.
+ * @param array $protocols The protocols supported. Defaults to \SAML2\Constants::NS_SAMLP.
*/
- public function addMetadataSP20($metadata, $protocols = array(SAML2_Const::NS_SAMLP))
+ public function addMetadataSP20($metadata, $protocols = array(\SAML2\Constants::NS_SAMLP))
{
assert('is_array($metadata)');
assert('is_array($protocols)');
@@ -474,7 +478,7 @@ class SimpleSAML_Metadata_SAMLBuilder
$metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
- $e = new SAML2_XML_md_SPSSODescriptor();
+ $e = new \SAML2\XML\md\SPSSODescriptor();
$e->protocolSupportEnumeration = $protocols;
if ($metadata->hasValue('saml20.sign.assertion')) {
@@ -529,7 +533,7 @@ class SimpleSAML_Metadata_SAMLBuilder
$metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
- $e = new SAML2_XML_md_IDPSSODescriptor();
+ $e = new \SAML2\XML\md\IDPSSODescriptor();
$e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:2.0:protocol';
if ($metadata->hasValue('sign.authnrequest')) {
@@ -578,7 +582,7 @@ class SimpleSAML_Metadata_SAMLBuilder
$metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
- $e = new SAML2_XML_md_SPSSODescriptor();
+ $e = new \SAML2\XML\md\SPSSODescriptor();
$e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:1.1:protocol';
$this->addCertificate($e, $metadata);
@@ -613,7 +617,7 @@ class SimpleSAML_Metadata_SAMLBuilder
$metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
- $e = new SAML2_XML_md_IDPSSODescriptor();
+ $e = new \SAML2\XML\md\IDPSSODescriptor();
$e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:1.1:protocol';
$e->protocolSupportEnumeration[] = 'urn:mace:shibboleth:1.0';
@@ -641,7 +645,7 @@ class SimpleSAML_Metadata_SAMLBuilder
$metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
- $e = new SAML2_XML_md_AttributeAuthorityDescriptor();
+ $e = new \SAML2\XML\md\AttributeAuthorityDescriptor();
$e->protocolSupportEnumeration = $metadata->getArray('protocols', array());
$this->addExtensions($metadata, $e);
@@ -681,7 +685,7 @@ class SimpleSAML_Metadata_SAMLBuilder
// TODO: remove this check as soon as getContact() is called always before calling this function
$details = \SimpleSAML\Utils\Config\Metadata::getContact($details);
- $e = new SAML2_XML_md_ContactPerson();
+ $e = new \SAML2\XML\md\ContactPerson();
$e->contactType = $type;
if (isset($details['company'])) {
@@ -721,16 +725,16 @@ class SimpleSAML_Metadata_SAMLBuilder
/**
* Add a KeyDescriptor with an X509 certificate.
*
- * @param SAML2_XML_md_RoleDescriptor $rd The RoleDescriptor the certificate should be added to.
+ * @param \SAML2\XML\md\RoleDescriptor $rd The RoleDescriptor the certificate should be added to.
* @param string $use The value of the 'use' attribute.
* @param string $x509data The certificate data.
*/
- private function addX509KeyDescriptor(SAML2_XML_md_RoleDescriptor $rd, $use, $x509data)
+ private function addX509KeyDescriptor(\SAML2\XML\md\RoleDescriptor $rd, $use, $x509data)
{
assert('in_array($use, array("encryption", "signing"), TRUE)');
assert('is_string($x509data)');
- $keyDescriptor = SAML2_Utils::createKeyDescriptor($x509data);
+ $keyDescriptor = \SAML2\Utils::createKeyDescriptor($x509data);
$keyDescriptor->use = $use;
$rd->KeyDescriptor[] = $keyDescriptor;
}
@@ -741,10 +745,10 @@ class SimpleSAML_Metadata_SAMLBuilder
*
* Helper function for adding a certificate to the metadata.
*
- * @param SAML2_XML_md_RoleDescriptor $rd The RoleDescriptor the certificate should be added to.
+ * @param \SAML2\XML\md\RoleDescriptor $rd The RoleDescriptor the certificate should be added to.
* @param SimpleSAML_Configuration $metadata The metadata of the entity.
*/
- private function addCertificate(SAML2_XML_md_RoleDescriptor $rd, SimpleSAML_Configuration $metadata)
+ private function addCertificate(\SAML2\XML\md\RoleDescriptor $rd, SimpleSAML_Configuration $metadata)
{
$keys = $metadata->getPublicKeys();
if ($keys !== null) {
diff --git a/lib/SimpleSAML/Metadata/SAMLParser.php b/lib/SimpleSAML/Metadata/SAMLParser.php
index 02e6e91..edb3909 100644
--- a/lib/SimpleSAML/Metadata/SAMLParser.php
+++ b/lib/SimpleSAML/Metadata/SAMLParser.php
@@ -139,7 +139,7 @@ class SimpleSAML_Metadata_SAMLParser
/**
* This is an array of elements that may be used to validate this element.
*
- * @var SAML2_SignedElementHelper[]
+ * @var \SAML2\SignedElementHelper[]
*/
private $validators = array();
@@ -155,14 +155,14 @@ class SimpleSAML_Metadata_SAMLParser
/**
* This is the constructor for the SAMLParser class.
*
- * @param SAML2_XML_md_EntityDescriptor $entityElement The EntityDescriptor.
+ * @param \SAML2\XML\md\EntityDescriptor $entityElement The EntityDescriptor.
* @param int|NULL $maxExpireTime The unix timestamp for when this entity should expire, or
* NULL if unknown.
* @param array $validators An array of parent elements that may validate this element.
* @param array $parentExtensions An optional array of extensions from the parent element.
*/
private function __construct(
- SAML2_XML_md_EntityDescriptor $entityElement,
+ \SAML2\XML\md\EntityDescriptor $entityElement,
$maxExpireTime,
array $validators = array(),
array $parentExtensions = null
@@ -192,11 +192,11 @@ class SimpleSAML_Metadata_SAMLParser
// look over the RoleDescriptors
foreach ($entityElement->RoleDescriptor as $child) {
- if ($child instanceof SAML2_XML_md_SPSSODescriptor) {
+ if ($child instanceof \SAML2\XML\md\SPSSODescriptor) {
$this->processSPSSODescriptor($child, $expireTime);
- } elseif ($child instanceof SAML2_XML_md_IDPSSODescriptor) {
+ } elseif ($child instanceof \SAML2\XML\md\IDPSSODescriptor) {
$this->processIDPSSODescriptor($child, $expireTime);
- } elseif ($child instanceof SAML2_XML_md_AttributeAuthorityDescriptor) {
+ } elseif ($child instanceof \SAML2\XML\md\AttributeAuthorityDescriptor) {
$this->processAttributeAuthorityDescriptor($child, $expireTime);
}
}
@@ -226,7 +226,7 @@ class SimpleSAML_Metadata_SAMLParser
$data = \SimpleSAML\Utils\HTTP::fetch($file);
try {
- $doc = SAML2_DOMDocumentFactory::fromString($data);
+ $doc = \SAML2\DOMDocumentFactory::fromString($data);
} catch(\Exception $e) {
throw new Exception('Failed to read XML from file: '.$file);
}
@@ -246,7 +246,7 @@ class SimpleSAML_Metadata_SAMLParser
public static function parseString($metadata)
{
try {
- $doc = SAML2_DOMDocumentFactory::fromString($metadata);
+ $doc = \SAML2\DOMDocumentFactory::fromString($metadata);
} catch(\Exception $e) {
throw new Exception('Failed to parse XML string.');
}
@@ -273,16 +273,16 @@ class SimpleSAML_Metadata_SAMLParser
/**
- * This function parses a SAML2_XML_md_EntityDescriptor object which represents a EntityDescriptor element.
+ * This function parses a \SAML2\XML\md\EntityDescriptor object which represents a EntityDescriptor element.
*
- * @param SAML2_XML_md_EntityDescriptor $entityElement A SAML2_XML_md_EntityDescriptor object which represents a
+ * @param \SAML2\XML\md\EntityDescriptor $entityElement A \SAML2\XML\md\EntityDescriptor object which represents a
* EntityDescriptor element.
*
* @return SimpleSAML_Metadata_SAMLParser An instance of this class with the metadata loaded.
*/
public static function parseElement($entityElement)
{
- assert('$entityElement instanceof SAML2_XML_md_EntityDescriptor');
+ assert('$entityElement instanceof \SAML2\XML\md\EntityDescriptor');
return new SimpleSAML_Metadata_SAMLParser($entityElement, null);
}
@@ -309,7 +309,7 @@ class SimpleSAML_Metadata_SAMLParser
$data = \SimpleSAML\Utils\HTTP::fetch($file);
try {
- $doc = SAML2_DOMDocumentFactory::fromString($data);
+ $doc = \SAML2\DOMDocumentFactory::fromString($data);
} catch(\Exception $e) {
throw new Exception('Failed to read XML from file: '.$file);
}
@@ -336,7 +336,7 @@ class SimpleSAML_Metadata_SAMLParser
public static function parseDescriptorsString($string)
{
try {
- $doc = SAML2_DOMDocumentFactory::fromString($string);
+ $doc = \SAML2\DOMDocumentFactory::fromString($string);
} catch(\Exception $e) {
throw new Exception('Failed to parse XML string.');
}
@@ -365,9 +365,9 @@ class SimpleSAML_Metadata_SAMLParser
assert('$element instanceof DOMElement');
if (SimpleSAML\Utils\XML::isDOMElementOfType($element, 'EntityDescriptor', '@md') === true) {
- return self::processDescriptorsElement(new SAML2_XML_md_EntityDescriptor($element));
+ return self::processDescriptorsElement(new \SAML2\XML\md\EntityDescriptor($element));
} elseif (SimpleSAML\Utils\XML::isDOMElementOfType($element, 'EntitiesDescriptor', '@md') === true) {
- return self::processDescriptorsElement(new SAML2_XML_md_EntitiesDescriptor($element));
+ return self::processDescriptorsElement(new \SAML2\XML\md\EntitiesDescriptor($element));
} else {
throw new Exception('Unexpected root node: ['.$element->namespaceURI.']:'.$element->localName);
}
@@ -376,7 +376,7 @@ class SimpleSAML_Metadata_SAMLParser
/**
*
- * @param SAML2_XML_md_EntityDescriptor|SAML2_XML_md_EntitiesDescriptor $element The element we should process.
+ * @param \SAML2\XML\md\EntityDescriptor|\SAML2\XML\md\EntitiesDescriptor $element The element we should process.
* @param int|NULL $maxExpireTime The maximum expiration time
* of the entities.
* @param array $validators The parent-elements that may be
@@ -394,14 +394,14 @@ class SimpleSAML_Metadata_SAMLParser
) {
assert('is_null($maxExpireTime) || is_int($maxExpireTime)');
- if ($element instanceof SAML2_XML_md_EntityDescriptor) {
+ if ($element instanceof \SAML2\XML\md\EntityDescriptor) {
$ret = new SimpleSAML_Metadata_SAMLParser($element, $maxExpireTime, $validators, $parentExtensions);
$ret = array($ret->getEntityId() => $ret);
/** @var SimpleSAML_Metadata_SAMLParser[] $ret */
return $ret;
}
- assert('$element instanceof SAML2_XML_md_EntitiesDescriptor');
+ assert('$element instanceof \SAML2\XML\md\EntitiesDescriptor');
$extensions = self::processExtensions($element, $parentExtensions);
$expTime = self::getExpireTime($element, $maxExpireTime);
@@ -836,13 +836,13 @@ class SimpleSAML_Metadata_SAMLParser
* - 'expire': Timestamp for when this descriptor expires.
* - 'keys': Array of associative arrays with the elements from parseKeyDescriptor.
*
- * @param SAML2_XML_md_RoleDescriptor $element The element we should extract metadata from.
+ * @param \SAML2\XML\md\RoleDescriptor $element The element we should extract metadata from.
* @param int|NULL $expireTime The unix timestamp for when this element should expire, or
* NULL if unknown.
*
* @return array An associative array with metadata we have extracted from this element.
*/
- private static function parseRoleDescriptorType(SAML2_XML_md_RoleDescriptor $element, $expireTime)
+ private static function parseRoleDescriptorType(\SAML2\XML\md\RoleDescriptor $element, $expireTime)
{
assert('is_null($expireTime) || is_int($expireTime)');
@@ -887,13 +887,13 @@ class SimpleSAML_Metadata_SAMLParser
* - 'nameIDFormats': The NameIDFormats supported by this SSODescriptor. This may be an empty array.
* - 'keys': Array of associative arrays with the elements from parseKeyDescriptor:
*
- * @param SAML2_XML_md_SSODescriptorType $element The element we should extract metadata from.
+ * @param \SAML2\XML\md\SSODescriptorType $element The element we should extract metadata from.
* @param int|NULL $expireTime The unix timestamp for when this element should expire, or
* NULL if unknown.
*
* @return array An associative array with metadata we have extracted from this element.
*/
- private static function parseSSODescriptor(SAML2_XML_md_SSODescriptorType $element, $expireTime)
+ private static function parseSSODescriptor(\SAML2\XML\md\SSODescriptorType $element, $expireTime)
{
assert('is_null($expireTime) || is_int($expireTime)');
@@ -916,11 +916,11 @@ class SimpleSAML_Metadata_SAMLParser
/**
* This function extracts metadata from a SPSSODescriptor element.
*
- * @param SAML2_XML_md_SPSSODescriptor $element The element which should be parsed.
+ * @param \SAML2\XML\md\SPSSODescriptor $element The element which should be parsed.
* @param int|NULL $expireTime The unix timestamp for when this element should expire, or
* NULL if unknown.
*/
- private function processSPSSODescriptor(SAML2_XML_md_SPSSODescriptor $element, $expireTime)
+ private function processSPSSODescriptor(\SAML2\XML\md\SPSSODescriptor $element, $expireTime)
{
assert('is_null($expireTime) || is_int($expireTime)');
@@ -952,11 +952,11 @@ class SimpleSAML_Metadata_SAMLParser
/**
* This function extracts metadata from a IDPSSODescriptor element.
*
- * @param SAML2_XML_md_IDPSSODescriptor $element The element which should be parsed.
+ * @param \SAML2\XML\md\IDPSSODescriptor $element The element which should be parsed.
* @param int|NULL $expireTime The unix timestamp for when this element should expire, or
* NULL if unknown.
*/
- private function processIDPSSODescriptor(SAML2_XML_md_IDPSSODescriptor $element, $expireTime)
+ private function processIDPSSODescriptor(\SAML2\XML\md\IDPSSODescriptor $element, $expireTime)
{
assert('is_null($expireTime) || is_int($expireTime)');
@@ -978,12 +978,12 @@ class SimpleSAML_Metadata_SAMLParser
/**
* This function extracts metadata from a AttributeAuthorityDescriptor element.
*
- * @param SAML2_XML_md_AttributeAuthorityDescriptor $element The element which should be parsed.
+ * @param \SAML2\XML\md\AttributeAuthorityDescriptor $element The element which should be parsed.
* @param int|NULL $expireTime The unix timestamp for when this element should
* expire, or NULL if unknown.
*/
private function processAttributeAuthorityDescriptor(
- SAML2_XML_md_AttributeAuthorityDescriptor $element,
+ \SAML2\XML\md\AttributeAuthorityDescriptor $element,
$expireTime
) {
assert('is_null($expireTime) || is_int($expireTime)');
@@ -1021,24 +1021,24 @@ class SimpleSAML_Metadata_SAMLParser
);
// Some extensions may get inherited from a parent element
- if (($element instanceof SAML2_XML_md_EntityDescriptor || $element instanceof SAML2_XML_md_EntitiesDescriptor)
+ if (($element instanceof \SAML2\XML\md\EntityDescriptor || $element instanceof \SAML2\XML\md\EntitiesDescriptor)
&& !empty($parentExtensions['RegistrationInfo'])) {
$ret['RegistrationInfo'] = $parentExtensions['RegistrationInfo'];
}
foreach ($element->Extensions as $e) {
- if ($e instanceof SAML2_XML_shibmd_Scope) {
+ if ($e instanceof \SAML2\XML\shibmd\Scope) {
$ret['scope'][] = $e->scope;
continue;
}
// Entity Attributes are only allowed at entity level extensions and not at RoleDescriptor level
- if ($element instanceof SAML2_XML_md_EntityDescriptor ||
- $element instanceof SAML2_XML_md_EntitiesDescriptor) {
+ if ($element instanceof \SAML2\XML\md\EntityDescriptor ||
+ $element instanceof \SAML2\XML\md\EntitiesDescriptor) {
- if ($e instanceof SAML2_XML_mdrpi_RegistrationInfo) {
+ if ($e instanceof \SAML2\XML\mdrpi\RegistrationInfo) {
// Registration Authority cannot be overridden (warn only if override attempts to change the value)
if (isset($ret['RegistrationInfo']['registrationAuthority'])
&& $ret['RegistrationInfo']['registrationAuthority'] !== $e->registrationAuthority) {
@@ -1048,11 +1048,11 @@ class SimpleSAML_Metadata_SAMLParser
$ret['RegistrationInfo']['registrationAuthority'] = $e->registrationAuthority;
}
}
- if ($e instanceof SAML2_XML_mdattr_EntityAttributes && !empty($e->children)) {
+ if ($e instanceof \SAML2\XML\mdattr\EntityAttributes && !empty($e->children)) {
foreach ($e->children as $attr) {
// only saml:Attribute are currently supported here. The specifications also allows
// saml:Assertions, which more complex processing
- if ($attr instanceof SAML2_XML_saml_Attribute) {
+ if ($attr instanceof \SAML2\XML\saml\Attribute) {
if (empty($attr->Name) || empty($attr->AttributeValue)) {
continue;
}
@@ -1060,7 +1060,7 @@ class SimpleSAML_Metadata_SAMLParser
// attribute names that is not URI is prefixed as this: '{nameformat}name'
$name = $attr->Name;
if (empty($attr->NameFormat)) {
- $name = '{'.SAML2_Const::NAMEFORMAT_UNSPECIFIED.'}'.$attr->Name;
+ $name = '{'.\SAML2\Constants::NAMEFORMAT_UNSPECIFIED.'}'.$attr->Name;
} elseif ($attr->NameFormat !== 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri') {
$name = '{'.$attr->NameFormat.'}'.$attr->Name;
}
@@ -1077,8 +1077,8 @@ class SimpleSAML_Metadata_SAMLParser
}
// UIInfo elements are only allowed at RoleDescriptor level extensions
- if ($element instanceof SAML2_XML_md_RoleDescriptor) {
- if ($e instanceof SAML2_XML_mdui_UIInfo) {
+ if ($element instanceof \SAML2\XML\md\RoleDescriptor) {
+ if ($e instanceof \SAML2\XML\mdui\UIInfo) {
$ret['UIInfo']['DisplayName'] = $e->DisplayName;
$ret['UIInfo']['Description'] = $e->Description;
@@ -1086,7 +1086,7 @@ class SimpleSAML_Metadata_SAMLParser
$ret['UIInfo']['PrivacyStatementURL'] = $e->PrivacyStatementURL;
foreach ($e->Keywords as $uiItem) {
- if (!($uiItem instanceof SAML2_XML_mdui_Keywords)
+ if (!($uiItem instanceof \SAML2\XML\mdui\Keywords)
|| empty($uiItem->Keywords)
|| empty($uiItem->lang)
) {
@@ -1095,7 +1095,7 @@ class SimpleSAML_Metadata_SAMLParser
$ret['UIInfo']['Keywords'][$uiItem->lang] = $uiItem->Keywords;
}
foreach ($e->Logo as $uiItem) {
- if (!($uiItem instanceof SAML2_XML_mdui_Logo)
+ if (!($uiItem instanceof \SAML2\XML\mdui\Logo)
|| empty($uiItem->url)
|| empty($uiItem->height)
|| empty($uiItem->width)
@@ -1116,20 +1116,20 @@ class SimpleSAML_Metadata_SAMLParser
}
// DiscoHints elements are only allowed at IDPSSODescriptor level extensions
- if ($element instanceof SAML2_XML_md_IDPSSODescriptor) {
+ if ($element instanceof \SAML2\XML\md\IDPSSODescriptor) {
- if ($e instanceof SAML2_XML_mdui_DiscoHints) {
+ if ($e instanceof \SAML2\XML\mdui\DiscoHints) {
$ret['DiscoHints']['IPHint'] = $e->IPHint;
$ret['DiscoHints']['DomainHint'] = $e->DomainHint;
$ret['DiscoHints']['GeolocationHint'] = $e->GeolocationHint;
}
}
- if (!($e instanceof SAML2_XML_Chunk)) {
+ if (!($e instanceof \SAML2\XML\Chunk)) {
continue;
}
- if ($e->localName === 'Attribute' && $e->namespaceURI === SAML2_Const::NS_SAML) {
+ if ($e->localName === 'Attribute' && $e->namespaceURI === \SAML2\Constants::NS_SAML) {
$attribute = $e->getXML();
$name = $attribute->getAttribute('Name');
@@ -1154,9 +1154,9 @@ class SimpleSAML_Metadata_SAMLParser
/**
* Parse and process a Organization element.
*
- * @param SAML2_XML_md_Organization $element The Organization element.
+ * @param \SAML2\XML\md\Organization $element The Organization element.
*/
- private function processOrganization(SAML2_XML_md_Organization $element)
+ private function processOrganization(\SAML2\XML\md\Organization $element)
{
$this->organizationName = $element->OrganizationName;
$this->organizationDisplayName = $element->OrganizationDisplayName;
@@ -1167,10 +1167,10 @@ class SimpleSAML_Metadata_SAMLParser
/**
* Parse and process a ContactPerson element.
*
- * @param SAML2_XML_md_ContactPerson $element The ContactPerson element.
+ * @param \SAML2\XML\md\ContactPerson $element The ContactPerson element.
*/
- private function processContactPerson(SAML2_XML_md_ContactPerson $element)
+ private function processContactPerson(\SAML2\XML\md\ContactPerson $element)
{
$contactPerson = array();
if (!empty($element->contactType)) {
@@ -1200,10 +1200,10 @@ class SimpleSAML_Metadata_SAMLParser
/**
* This function parses AttributeConsumerService elements.
*
- * @param SAML2_XML_md_AttributeConsumingService $element The AttributeConsumingService to parse.
+ * @param \SAML2\XML\md\AttributeConsumingService $element The AttributeConsumingService to parse.
* @param array $sp The array with the SP's metadata.
*/
- private static function parseAttributeConsumerService(SAML2_XML_md_AttributeConsumingService $element, &$sp)
+ private static function parseAttributeConsumerService(\SAML2\XML\md\AttributeConsumingService $element, &$sp)
{
assert('is_array($sp)');
@@ -1228,13 +1228,13 @@ class SimpleSAML_Metadata_SAMLParser
if ($child->NameFormat !== null) {
$attrformat = $child->NameFormat;
} else {
- $attrformat = SAML2_Const::NAMEFORMAT_UNSPECIFIED;
+ $attrformat = \SAML2\Constants::NAMEFORMAT_UNSPECIFIED;
}
if ($format === null) {
$format = $attrformat;
} elseif ($format !== $attrformat) {
- $format = SAML2_Const::NAMEFORMAT_UNSPECIFIED;
+ $format = \SAML2\Constants::NAMEFORMAT_UNSPECIFIED;
}
}
@@ -1246,7 +1246,7 @@ class SimpleSAML_Metadata_SAMLParser
unset($sp['attributes.required']);
}
- if ($format !== SAML2_Const::NAMEFORMAT_UNSPECIFIED && $format !== null) {
+ if ($format !== \SAML2\Constants::NAMEFORMAT_UNSPECIFIED && $format !== null) {
$sp['attributes.NameFormat'] = $format;
}
}
@@ -1262,11 +1262,11 @@ class SimpleSAML_Metadata_SAMLParser
* - 'index': The index of this endpoint. This attribute is only for indexed endpoints.
* - 'isDefault': Whether this endpoint is the default endpoint for this type. This attribute may not exist.
*
- * @param SAML2_XML_md_EndpointType $element The element which should be parsed.
+ * @param \SAML2\XML\md\EndpointType $element The element which should be parsed.
*
* @return array An associative array with the data we have extracted from the element.
*/
- private static function parseGenericEndpoint(SAML2_XML_md_EndpointType $element)
+ private static function parseGenericEndpoint(\SAML2\XML\md\EndpointType $element)
{
$ep = array();
@@ -1277,7 +1277,7 @@ class SimpleSAML_Metadata_SAMLParser
$ep['ResponseLocation'] = $element->ResponseLocation;
}
- if ($element instanceof SAML2_XML_md_IndexedEndpointType) {
+ if ($element instanceof \SAML2\XML\md\IndexedEndpointType) {
$ep['index'] = $element->index;
if ($element->isDefault !== null) {
@@ -1317,11 +1317,11 @@ class SimpleSAML_Metadata_SAMLParser
* - 'type: The type of the key. 'X509Certificate' is the only key type we support.
* - 'X509Certificate': The contents of the first X509Certificate element (if the type is 'X509Certificate ').
*
- * @param SAML2_XML_md_KeyDescriptor $kd The KeyDescriptor element.
+ * @param \SAML2\XML\md\KeyDescriptor $kd The KeyDescriptor element.
*
* @return array|null An associative array describing the key, or null if this is an unsupported key.
*/
- private static function parseKeyDescriptor(SAML2_XML_md_KeyDescriptor $kd)
+ private static function parseKeyDescriptor(\SAML2\XML\md\KeyDescriptor $kd)
{
$r = array();
@@ -1339,9 +1339,9 @@ class SimpleSAML_Metadata_SAMLParser
$keyInfo = $kd->KeyInfo;
foreach ($keyInfo->info as $i) {
- if ($i instanceof SAML2_XML_ds_X509Data) {
+ if ($i instanceof \SAML2\XML\ds\X509Data) {
foreach ($i->data as $d) {
- if ($d instanceof SAML2_XML_ds_X509Certificate) {
+ if ($d instanceof \SAML2\XML\ds\X509Certificate) {
$r['type'] = 'X509Certificate';
$r['X509Certificate'] = $d->certificate;
return $r;
@@ -1410,7 +1410,7 @@ class SimpleSAML_Metadata_SAMLParser
*
* @param DOMDocument $doc The DOMDocument where we should find the EntityDescriptor node.
*
- * @return SAML2_XML_md_EntityDescriptor The DOMEntity which represents the EntityDescriptor.
+ * @return \SAML2\XML\md\EntityDescriptor The DOMEntity which represents the EntityDescriptor.
* @throws Exception If the document is empty or the first element is not an EntityDescriptor element.
*/
private static function findEntityDescriptor($doc)
@@ -1428,7 +1428,7 @@ class SimpleSAML_Metadata_SAMLParser
throw new Exception('Expected first element in the metadata document to be an EntityDescriptor element.');
}
- return new SAML2_XML_md_EntityDescriptor($ed);
+ return new \SAML2\XML\md\EntityDescriptor($ed);
}
diff --git a/lib/SimpleSAML/Metadata/Signer.php b/lib/SimpleSAML/Metadata/Signer.php
index 7ed7167..5e11918 100644
--- a/lib/SimpleSAML/Metadata/Signer.php
+++ b/lib/SimpleSAML/Metadata/Signer.php
@@ -143,6 +143,70 @@ class SimpleSAML_Metadata_Signer
/**
+ * Determine the signature and digest algorithms to use when signing metadata.
+ *
+ * This method will look for the 'metadata.sign.algorithm' key in the $entityMetadata array, or look for such
+ * a configuration option in the $config object.
+ *
+ * @param SimpleSAML_Configuration $config The global configuration.
+ * @param array $entityMetadata An array containing the metadata related to this entity.
+ * @param string $type A string describing the type of entity. E.g. 'SAML 2 IdP' or 'Shib 1.3 SP'.
+ *
+ * @return array An array with two keys, 'algorithm' and 'digest', corresponding to the signature and digest
+ * algorithms to use, respectively.
+ *
+ * @throws \SimpleSAML\Error\CriticalConfigurationError
+ *
+ * @todo change to SHA256 by default.
+ */
+ private static function getMetadataSigningAlgorithm($config, $entityMetadata, $type)
+ {
+ // configure the algorithm to use
+ if (array_key_exists('metadata.sign.algorithm', $entityMetadata)) {
+ if (!is_string($entityMetadata['metadata.sign.algorithm'])) {
+ throw new \SimpleSAML\Error\CriticalConfigurationError(
+ "Invalid value for the 'metadata.sign.algorithm' configuration option for the ".$type.
+ "'".$entityMetadata['entityid']."'. This option has restricted values"
+ );
+ }
+ $alg = $entityMetadata['metadata.sign.algorithm'];
+ } else {
+ $alg = $config->getString('metadata.sign.algorithm', XMLSecurityKey::RSA_SHA1);
+ }
+
+ $supported_algs = array(
+ XMLSecurityKey::RSA_SHA1,
+ XMLSecurityKey::RSA_SHA256,
+ XMLSecurityKey::RSA_SHA384,
+ XMLSecurityKey::RSA_SHA512,
+ );
+
+ if (!in_array($alg, $supported_algs)) {
+ throw new \SimpleSAML\Error\CriticalConfigurationError("Unknown signature algorithm '$alg'");
+ }
+
+ switch ($alg) {
+ case XMLSecurityKey::RSA_SHA256:
+ $digest = XMLSecurityDSig::SHA256;
+ break;
+ case XMLSecurityKey::RSA_SHA384:
+ $digest = XMLSecurityDSig::SHA384;
+ break;
+ case XMLSecurityKey::RSA_SHA512:
+ $digest = XMLSecurityDSig::SHA512;
+ break;
+ default:
+ $digest = XMLSecurityDSig::SHA1;
+ }
+
+ return array(
+ 'algorithm' => $alg,
+ 'digest' => $digest,
+ );
+ }
+
+
+ /**
* Signs the given metadata if metadata signing is enabled.
*
* @param string $metadataString A string with the metadata.
@@ -181,13 +245,15 @@ class SimpleSAML_Metadata_Signer
// convert the metadata to a DOM tree
try {
- $xml = SAML2_DOMDocumentFactory::fromString($metadataString);
+ $xml = \SAML2\DOMDocumentFactory::fromString($metadataString);
} catch(Exception $e) {
throw new Exception('Error parsing self-generated metadata.');
}
+ $signature_cf = self::getMetadataSigningAlgorithm($config, $entityMetadata, $type);
+
// load the private key
- $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
+ $objKey = new XMLSecurityKey($signature_cf['algorithm'], array('type' => 'private'));
if (array_key_exists('privatekey_pass', $keyCertFiles)) {
$objKey->passphrase = $keyCertFiles['privatekey_pass'];
}
@@ -207,7 +273,7 @@ class SimpleSAML_Metadata_Signer
$objXMLSecDSig->addReferenceList(
array($rootNode),
- XMLSecurityDSig::SHA1,
+ $signature_cf['digest'],
array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N),
array('id_name' => 'ID')
);
diff --git a/lib/SimpleSAML/Session.php b/lib/SimpleSAML/Session.php
index 153478a..bdc84fd 100644
--- a/lib/SimpleSAML/Session.php
+++ b/lib/SimpleSAML/Session.php
@@ -7,11 +7,16 @@
* information about all the currently logged in SPs. This is used when the user initiates a
* Single-Log-Out.
*
+ * Bear in mind that the session object implements the Serializable interface, and as such,
+ * all its contents MUST be serializable. If you need to store something in the session object
+ * that is not serializable, make sure to convert it first to a representation that can be
+ * serialized.
+ *
* @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
* @author Jaime Pérez Crespo, UNINETT AS <jaime.perez@uninett.no>
* @package SimpleSAMLphp
*/
-class SimpleSAML_Session
+class SimpleSAML_Session implements Serializable
{
/**
@@ -160,10 +165,11 @@ class SimpleSAML_Session
if ($this->sessionId === null) {
$this->sessionId = $sh->newSessionId();
}
-
} else { // regular session
$sh = SimpleSAML_SessionHandler::getSessionHandler();
$this->sessionId = $sh->newSessionId();
+ $sh->setCookie($sh->getSessionCookieName(), $this->sessionId, $sh->getCookieParams());
+
$this->trackid = bin2hex(openssl_random_pseudo_bytes(5));
SimpleSAML\Logger::setTrackId($this->trackid);
@@ -180,6 +186,54 @@ class SimpleSAML_Session
}
}
+
+ /**
+ * Serialize this session object.
+ *
+ * This method will be invoked by any calls to serialize().
+ *
+ * @return string The serialized representation of this session object.
+ */
+ public function serialize()
+ {
+ $serialized = serialize(get_object_vars($this));
+ return $serialized;
+ }
+
+
+ /**
+ * Unserialize a session object and load it..
+ *
+ * This method will be invoked by any calls to unserialize(), allowing us to restore any data that might not
+ * be serializable in its original form (e.g.: DOM objects).
+ *
+ * @param string $serialized The serialized representation of a session that we want to restore.
+ */
+ public function unserialize($serialized)
+ {
+ $session = unserialize($serialized);
+ if (is_array($session)) {
+ foreach ($session as $k => $v) {
+ $this->$k = $v;
+ }
+ }
+
+ // look for any raw attributes and load them in the 'Attributes' array
+ foreach ($this->authData as $authority => $parameters) {
+ if (!array_key_exists('RawAttributes', $parameters)) {
+ continue;
+ }
+
+ foreach ($parameters['RawAttributes'] as $attribute => $values) {
+ foreach ($values as $idx => $value) { // this should be originally a DOMNodeList
+ /* @var \SAML2\XML\saml\AttributeValue $value */
+ $this->authData[$authority]['Attributes'][$attribute][$idx] = $value->element->childNodes;
+ }
+ }
+ }
+ }
+
+
/**
* Retrieves the current session. Creates a new session if there's not one.
*
@@ -194,15 +248,18 @@ class SimpleSAML_Session
}
// check if we have stored a session stored with the session handler
- $prev = (self::$instance !== null);
+ $session = null;
try {
$session = self::getSession();
-
} catch (Exception $e) {
- // for some reason, we were unable to initialize this session, use a transient session instead
- self::useTransientSession();
-
+ /*
+ * For some reason, we were unable to initialize this session. Note that this error might be temporary, and
+ * it's possible that we can recover from it in subsequent requests, so we should not try to create a new
+ * session here. Therefore, use just a transient session and throw the exception for someone else to handle
+ * it.
+ */
SimpleSAML\Logger::error('Error loading session: '.$e->getMessage());
+ self::useTransientSession();
if ($e instanceof SimpleSAML_Error_Exception) {
$cause = $e->getCause();
if ($cause instanceof Exception) {
@@ -223,12 +280,30 @@ class SimpleSAML_Session
* error message). This means we don't need to create a new session again, we can use the one that's loaded now
* instead.
*/
- if (self::$instance !== null && !$prev) {
+ if (self::$instance !== null) {
return self::$instance;
}
- // create a new session
- return self::load(new SimpleSAML_Session());
+ // try to create a new session
+ try {
+ self::load(new SimpleSAML_Session());
+ } catch (\SimpleSAML\Error\CannotSetCookie $e) {
+ // can't create a regular session because we can't set cookies. Use transient.
+ $c = SimpleSAML_Configuration::getInstance();
+ self::useTransientSession();
+
+ if ($e->getCode() === \SimpleSAML\Error\CannotSetCookie::SECURE_COOKIE) {
+ throw new \SimpleSAML\Error\CriticalConfigurationError(
+ $e->getMessage(),
+ null,
+ $c->toArray()
+ );
+ }
+ SimpleSAML\Logger::error('Error creating session: '.$e->getMessage());
+ }
+
+ // we must have a session now, either regular or transient
+ return self::$instance;
}
/**
@@ -498,6 +573,8 @@ class SimpleSAML_Session
*
* @param string $authority The authority the user logged in with.
* @param array|null $data The authentication data for this authority.
+ *
+ * @throws \SimpleSAML\Error\CannotSetCookie If the authentication token cannot be set for some reason.
*/
public function doLogin($authority, array $data = null)
{
@@ -530,6 +607,29 @@ class SimpleSAML_Session
$data['Expire'] = $maxSessionExpire;
}
+ // check if we have non-serializable attribute values
+ foreach ($data['Attributes'] as $attribute => $values) {
+ foreach ($values as $idx => $value) {
+ if (is_string($value) || is_int($value)) {
+ continue;
+ }
+
+ // at this point, this should be a DOMNodeList object...
+ if (!is_a($value, 'DOMNodeList')) {
+ continue;
+ }
+
+ /* @var \DOMNodeList $value */
+ if ($value->length === 0) {
+ continue;
+ }
+
+ // create an AttributeValue object and save it to 'RawAttributes', using same attribute name and index
+ $attrval = new \SAML2\XML\saml\AttributeValue($value->item(0)->parentNode);
+ $data['RawAttributes'][$attribute][$idx] = $attrval;
+ }
+ }
+
$this->authData[$authority] = $data;
$this->authToken = SimpleSAML\Utils\Random::generateID();
@@ -541,10 +641,23 @@ class SimpleSAML_Session
$this->setRememberMeExpire();
} else {
- $sessionHandler->setCookie(
- $globalConfig->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken'),
- $this->authToken
- );
+ try {
+ SimpleSAML\Utils\HTTP::setCookie(
+ $globalConfig->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken'),
+ $this->authToken,
+ $sessionHandler->getCookieParams()
+ );
+ } catch (SimpleSAML\Error\CannotSetCookie $e) {
+ /*
+ * Something went wrong when setting the auth token. We cannot recover from this, so we better log a
+ * message and throw an exception. The user is not properly logged in anyway, so clear all login
+ * information from the session.
+ */
+ unset($this->authToken);
+ unset($this->authData[$authority]);
+ \SimpleSAML\Logger::error('Cannot set authentication token cookie: '.$e->getMessage());
+ throw $e;
+ }
}
}
@@ -656,7 +769,7 @@ class SimpleSAML_Session
if ($this->authToken !== null) {
$globalConfig = SimpleSAML_Configuration::getInstance();
- $sessionHandler->setCookie(
+ \SimpleSAML\Utils\HTTP::setCookie(
$globalConfig->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken'),
$this->authToken,
$params
diff --git a/lib/SimpleSAML/SessionHandler.php b/lib/SimpleSAML/SessionHandler.php
index 23d826f..cfd8307 100644
--- a/lib/SimpleSAML/SessionHandler.php
+++ b/lib/SimpleSAML/SessionHandler.php
@@ -54,7 +54,7 @@ abstract class SimpleSAML_SessionHandler
/**
- * Create and set new session id.
+ * Create a new session id.
*
* @return string The new session id.
*/
@@ -96,6 +96,18 @@ abstract class SimpleSAML_SessionHandler
/**
+ * Set a session cookie.
+ *
+ * @param string $sessionName The name of the session.
+ * @param string|null $sessionID The session ID to use. Set to null to delete the cookie.
+ * @param array|null $cookieParams Additional parameters to use for the session cookie.
+ *
+ * @throws \SimpleSAML\Error\CannotSetCookie If we can't set the cookie.
+ */
+ abstract public function setCookie($sessionName, $sessionID, array $cookieParams = null);
+
+
+ /**
* Initialize the session handler.
*
* This function creates an instance of the session handler which is
@@ -125,7 +137,6 @@ abstract class SimpleSAML_SessionHandler
*/
public function hasSessionCookie()
{
-
return true;
}
@@ -138,7 +149,6 @@ abstract class SimpleSAML_SessionHandler
*/
public function getCookieParams()
{
-
$config = SimpleSAML_Configuration::getInstance();
return array(
@@ -149,26 +159,4 @@ abstract class SimpleSAML_SessionHandler
'httponly' => true,
);
}
-
-
- /**
- * Set a session cookie.
- *
- * @param string $name The name of the session cookie.
- * @param string|null $value The value of the cookie. Set to null to delete the cookie.
- * @param array|null $params Additional params to use for the session cookie.
- */
- public function setCookie($name, $value, array $params = null)
- {
- assert('is_string($name)');
- assert('is_string($value) || is_null($value)');
-
- if ($params !== null) {
- $params = array_merge($this->getCookieParams(), $params);
- } else {
- $params = $this->getCookieParams();
- }
-
- \SimpleSAML\Utils\HTTP::setCookie($name, $value, $params);
- }
}
diff --git a/lib/SimpleSAML/SessionHandlerCookie.php b/lib/SimpleSAML/SessionHandlerCookie.php
index c8409a8..e5c02bf 100644
--- a/lib/SimpleSAML/SessionHandlerCookie.php
+++ b/lib/SimpleSAML/SessionHandlerCookie.php
@@ -45,7 +45,7 @@ abstract class SimpleSAML_SessionHandlerCookie extends SimpleSAML_SessionHandler
/**
- * Create and set new session id.
+ * Create a new session id.
*
* @return string The new session id.
*/
@@ -53,7 +53,6 @@ abstract class SimpleSAML_SessionHandlerCookie extends SimpleSAML_SessionHandler
{
$this->session_id = self::createSessionID();
SimpleSAML_Session::createSession($this->session_id);
- $this->setCookie($this->cookie_name, $this->session_id);
return $this->session_id;
}
@@ -142,4 +141,28 @@ abstract class SimpleSAML_SessionHandlerCookie extends SimpleSAML_SessionHandler
{
return array_key_exists($this->cookie_name, $_COOKIE);
}
+
+
+ /**
+ * Set a session cookie.
+ *
+ * @param string $sessionName The name of the session.
+ * @param string|null $sessionID The session ID to use. Set to null to delete the cookie.
+ * @param array|null $cookieParams Additional parameters to use for the session cookie.
+ *
+ * @throws \SimpleSAML\Error\CannotSetCookie If we can't set the cookie.
+ */
+ public function setCookie($sessionName, $sessionID, array $cookieParams = null)
+ {
+ assert('is_string($sessionName)');
+ assert('is_string($sessionID) || is_null($sessionID)');
+
+ if ($cookieParams !== null) {
+ $params = array_merge($this->getCookieParams(), $cookieParams);
+ } else {
+ $params = $this->getCookieParams();
+ }
+
+ \SimpleSAML\Utils\HTTP::setCookie($sessionName, $sessionID, $params, true);
+ }
}
diff --git a/lib/SimpleSAML/SessionHandlerPHP.php b/lib/SimpleSAML/SessionHandlerPHP.php
index eb0c7d5..8947296 100644
--- a/lib/SimpleSAML/SessionHandlerPHP.php
+++ b/lib/SimpleSAML/SessionHandlerPHP.php
@@ -151,38 +151,17 @@ class SimpleSAML_SessionHandlerPHP extends SimpleSAML_SessionHandler
/**
- * Create and set new session id.
+ * Create a new session id.
*
* @return string The new session id.
- *
- * @throws SimpleSAML_Error_Exception If the cookie is marked as secure but we are not using HTTPS, or the headers
- * were already sent and therefore we cannot set the cookie.
*/
public function newSessionId()
{
- $session_cookie_params = session_get_cookie_params();
-
- if ($session_cookie_params['secure'] && !\SimpleSAML\Utils\HTTP::isHTTPS()) {
- throw new SimpleSAML_Error_Exception('Session start with secure cookie not allowed on http.');
- }
-
- if (headers_sent()) {
- throw new SimpleSAML_Error_Exception('Cannot create new session - headers already sent.');
- }
-
// generate new (secure) session id
$sessionId = bin2hex(openssl_random_pseudo_bytes(16));
SimpleSAML_Session::createSession($sessionId);
- if (session_id() !== '') {
- // session already started, close it
- session_write_close();
- }
-
- session_id($sessionId);
- $this->sessionStart();
-
- return session_id();
+ return $sessionId;
}
@@ -208,7 +187,7 @@ class SimpleSAML_SessionHandlerPHP extends SimpleSAML_SessionHandler
throw new SimpleSAML_Error_Exception('Session start with secure cookie not allowed on http.');
}
- $this->sessionStart();
+ $this->sessionStart();
return session_id();
}
@@ -318,11 +297,58 @@ class SimpleSAML_SessionHandlerPHP extends SimpleSAML_SessionHandler
$ret['path'] = $config->getBoolean(
'session.phpsession.limitedpath',
false
- ) ? '/'.$config->getBaseURL() : '/';
+ ) ? $config->getBasePath() : '/';
}
$ret['httponly'] = $config->getBoolean('session.phpsession.httponly', true);
return $ret;
}
+
+
+ /**
+ * Set a session cookie.
+ *
+ * @param string $sessionName The name of the session.
+ * @param string|null $sessionID The session ID to use. Set to null to delete the cookie.
+ * @param array|null $cookieParams Additional parameters to use for the session cookie.
+ *
+ * @throws \SimpleSAML\Error\CannotSetCookie If we can't set the cookie.
+ */
+ public function setCookie($sessionName, $sessionID, array $cookieParams = null)
+ {
+ if ($cookieParams === null) {
+ $cookieParams = session_get_cookie_params();
+ }
+
+ if ($cookieParams['secure'] && !\SimpleSAML\Utils\HTTP::isHTTPS()) {
+ throw new \SimpleSAML\Error\CannotSetCookie(
+ 'Setting secure cookie on plain HTTP is not allowed.',
+ \SimpleSAML\Error\CannotSetCookie::SECURE_COOKIE
+ );
+ }
+
+ if (headers_sent()) {
+ throw new \SimpleSAML\Error\CannotSetCookie(
+ 'Headers already sent.',
+ \SimpleSAML\Error\CannotSetCookie::HEADERS_SENT
+ );
+ }
+
+ session_set_cookie_params(
+ $cookieParams['lifetime'],
+ $cookieParams['path'],
+ $cookieParams['domain'],
+ $cookieParams['secure'],
+ $cookieParams['httponly']
+ );
+
+ if (session_id() !== '') {
+ // session already started, close it
+ session_write_close();
+ }
+
+ session_id($sessionID);
+ $this->sessionStart();
+ }
}
diff --git a/lib/SimpleSAML/Store/SQL.php b/lib/SimpleSAML/Store/SQL.php
index 9a3666a..41ed260 100644
--- a/lib/SimpleSAML/Store/SQL.php
+++ b/lib/SimpleSAML/Store/SQL.php
@@ -1,326 +1,350 @@
<?php
+
/**
- * A SQL datastore.
+ * A data store using a RDBMS to keep the data.
*
* @package SimpleSAMLphp
*/
-class SimpleSAML_Store_SQL extends SimpleSAML_Store {
-
- /**
- * The PDO object for our database.
- *
- * @var PDO
- */
- public $pdo;
-
-
- /**
- * Our database driver.
- *
- * @var string
- */
- public $driver;
-
-
- /**
- * The prefix we should use for our tables.
- *
- * @var string
- */
- public $prefix;
-
-
- /**
- * Associative array of table versions.
- *
- * @var array
- */
- private $tableVersions;
-
-
- /**
- * Initialize the SQL datastore.
- */
- protected function __construct() {
-
- $config = SimpleSAML_Configuration::getInstance();
-
- $dsn = $config->getString('store.sql.dsn');
- $username = $config->getString('store.sql.username', NULL);
- $password = $config->getString('store.sql.password', NULL);
- $this->prefix = $config->getString('store.sql.prefix', 'simpleSAMLphp');
-
- $this->pdo = new PDO($dsn, $username, $password);
- $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
-
- $this->driver = $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
-
- if ($this->driver === 'mysql') {
- $this->pdo->exec('SET time_zone = "+00:00"');
- }
-
- $this->initTableVersionTable();
- $this->initKVTable();
- }
-
-
- /**
- * Initialize table-version table.
- */
- private function initTableVersionTable() {
-
- $this->tableVersions = array();
-
- try {
- $fetchTableVersion = $this->pdo->query('SELECT _name, _version FROM ' . $this->prefix . '_tableVersion');
- } catch (PDOException $e) {
- $this->pdo->exec('CREATE TABLE ' . $this->prefix .'_tableVersion (_name VARCHAR(30) NOT NULL UNIQUE, _version INTEGER NOT NULL)');
- return;
- }
-
- while ( ($row = $fetchTableVersion->fetch(PDO::FETCH_ASSOC)) !== FALSE) {
- $this->tableVersions[$row['_name']] = (int)$row['_version'];
- }
- }
-
-
- /**
- * Initialize key-value table.
- */
- private function initKVTable() {
-
- if ($this->getTableVersion('kvstore') === 1) {
- // Table initialized
- return;
- }
-
- $query = 'CREATE TABLE ' . $this->prefix . '_kvstore (_type VARCHAR(30) NOT NULL, _key VARCHAR(50) NOT NULL, _value TEXT NOT NULL, _expire TIMESTAMP, PRIMARY KEY (_key, _type))';
- $this->pdo->exec($query);
-
- $query = 'CREATE INDEX ' . $this->prefix . '_kvstore_expire ON ' . $this->prefix . '_kvstore (_expire)';
- $this->pdo->exec($query);
-
- $this->setTableVersion('kvstore', 1);
- }
-
-
- /**
- * Get table version.
- *
- * @param string Table name.
- * @return int The table version, which is 0 if the table doesn't exist.
- */
- public function getTableVersion($name) {
- assert('is_string($name)');
-
- if (!isset($this->tableVersions[$name])) {
- return 0;
- }
-
- return $this->tableVersions[$name];
- }
-
-
- /**
- * Set table version.
- *
- * @param string $name Table name.
- * @parav int $version Table version.
- */
- public function setTableVersion($name, $version) {
- assert('is_string($name)');
- assert('is_int($version)');
-
- $this->insertOrUpdate($this->prefix . '_tableVersion', array('_name'),
- array('_name' => $name, '_version' => $version));
- $this->tableVersions[$name] = $version;
- }
-
-
- /**
- * Insert or update into a table.
- *
- * Since various databases implement different methods for doing this,
- * we abstract it away here.
- *
- * @param string $table The table we should update.
- * @param array $key The key columns.
- * @param array $data Associative array with columns.
- */
- public function insertOrUpdate($table, array $keys, array $data) {
- assert('is_string($table)');
-
- $colNames = '(' . implode(', ', array_keys($data)) . ')';
- $values = 'VALUES(:' . implode(', :', array_keys($data)) . ')';
-
- switch ($this->driver) {
- case 'mysql':
- $query = 'REPLACE INTO ' . $table . ' ' . $colNames . ' ' . $values;
- $query = $this->pdo->prepare($query);
- $query->execute($data);
- return;
- case 'sqlite':
- $query = 'INSERT OR REPLACE INTO ' . $table . ' ' . $colNames . ' ' . $values;
- $query = $this->pdo->prepare($query);
- $query->execute($data);
- return;
- }
-
- // Default implementation. Try INSERT, and UPDATE if that fails.
-
- $insertQuery = 'INSERT INTO ' . $table . ' ' . $colNames . ' ' . $values;
- $insertQuery = $this->pdo->prepare($insertQuery);
- try {
- $insertQuery->execute($data);
- return;
- } catch (PDOException $e) {
- $ecode = (string)$e->getCode();
- switch ($ecode) {
- case '23505': // PostgreSQL
- break;
- default:
- SimpleSAML\Logger::error('Error while saving data: ' . $e->getMessage());
- throw $e;
- }
- }
-
- $updateCols = array();
- $condCols = array();
- foreach ($data as $col => $value) {
-
- $tmp = $col . ' = :' . $col;
-
- if (in_array($col, $keys, TRUE)) {
- $condCols[] = $tmp;
- } else {
- $updateCols[] = $tmp;
- }
- }
-
- $updateQuery = 'UPDATE ' . $table . ' SET ' . implode(',', $updateCols) . ' WHERE ' . implode(' AND ', $condCols);
- $updateQuery = $this->pdo->prepare($updateQuery);
- $updateQuery->execute($data);
- }
-
-
- /**
- * Clean the key-value table of expired entries.
- */
- private function cleanKVStore() {
-
- SimpleSAML\Logger::debug('store.sql: Cleaning key-value store.');
-
- $query = 'DELETE FROM ' . $this->prefix . '_kvstore WHERE _expire < :now';
- $params = array('now' => gmdate('Y-m-d H:i:s'));
-
- $query = $this->pdo->prepare($query);
- $query->execute($params);
- }
-
-
- /**
- * Retrieve a value from the datastore.
- *
- * @param string $type The datatype.
- * @param string $key The key.
- * @return mixed|NULL The value.
- */
- public function get($type, $key) {
- assert('is_string($type)');
- assert('is_string($key)');
-
- if (strlen($key) > 50) {
- $key = sha1($key);
- }
-
- $query = 'SELECT _value FROM ' . $this->prefix . '_kvstore WHERE _type = :type AND _key = :key AND (_expire IS NULL OR _expire > :now)';
- $params = array('type' => $type, 'key' => $key, 'now' => gmdate('Y-m-d H:i:s'));
-
- $query = $this->pdo->prepare($query);
- $query->execute($params);
-
- $row = $query->fetch(PDO::FETCH_ASSOC);
- if ($row === FALSE) {
- return NULL;
- }
-
- $value = $row['_value'];
- if (is_resource($value)) {
- $value = stream_get_contents($value);
- }
- $value = urldecode($value);
- $value = unserialize($value);
-
- if ($value === FALSE) {
- return NULL;
- }
- return $value;
- }
-
-
- /**
- * Save a value to the datastore.
- *
- * @param string $type The datatype.
- * @param string $key The key.
- * @param mixed $value The value.
- * @param int|NULL $expire The expiration time (unix timestamp), or NULL if it never expires.
- */
- public function set($type, $key, $value, $expire = NULL) {
- assert('is_string($type)');
- assert('is_string($key)');
- assert('is_null($expire) || (is_int($expire) && $expire > 2592000)');
-
- if (rand(0, 1000) < 10) {
- $this->cleanKVStore();
- }
-
- if (strlen($key) > 50) {
- $key = sha1($key);
- }
-
- if ($expire !== NULL) {
- $expire = gmdate('Y-m-d H:i:s', $expire);
- }
-
- $value = serialize($value);
- $value = rawurlencode($value);
-
- $data = array(
- '_type' => $type,
- '_key' => $key,
- '_value' => $value,
- '_expire' => $expire,
- );
-
-
- $this->insertOrUpdate($this->prefix . '_kvstore', array('_type', '_key'), $data);
- }
-
-
- /**
- * Delete a value from the datastore.
- *
- * @param string $type The datatype.
- * @param string $key The key.
- */
- public function delete($type, $key) {
- assert('is_string($type)');
- assert('is_string($key)');
-
- if (strlen($key) > 50) {
- $key = sha1($key);
- }
-
- $data = array(
- '_type' => $type,
- '_key' => $key,
- );
-
- $query = 'DELETE FROM ' . $this->prefix . '_kvstore WHERE _type=:_type AND _key=:_key';
- $query = $this->pdo->prepare($query);
- $query->execute($data);
- }
-
+class SimpleSAML_Store_SQL extends SimpleSAML_Store
+{
+
+ /**
+ * The PDO object for our database.
+ *
+ * @var PDO
+ */
+ public $pdo;
+
+
+ /**
+ * Our database driver.
+ *
+ * @var string
+ */
+ public $driver;
+
+
+ /**
+ * The prefix we should use for our tables.
+ *
+ * @var string
+ */
+ public $prefix;
+
+
+ /**
+ * Associative array of table versions.
+ *
+ * @var array
+ */
+ private $tableVersions;
+
+
+ /**
+ * Initialize the SQL data store.
+ */
+ protected function __construct()
+ {
+ $config = SimpleSAML_Configuration::getInstance();
+
+ $dsn = $config->getString('store.sql.dsn');
+ $username = $config->getString('store.sql.username', null);
+ $password = $config->getString('store.sql.password', null);
+ $this->prefix = $config->getString('store.sql.prefix', 'simpleSAMLphp');
+
+ $this->pdo = new PDO($dsn, $username, $password);
+ $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+ $this->driver = $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
+
+ if ($this->driver === 'mysql') {
+ $this->pdo->exec('SET time_zone = "+00:00"');
+ }
+
+ $this->initTableVersionTable();
+ $this->initKVTable();
+ }
+
+
+ /**
+ * Initialize the table-version table.
+ */
+ private function initTableVersionTable()
+ {
+ $this->tableVersions = array();
+
+ try {
+ $fetchTableVersion = $this->pdo->query('SELECT _name, _version FROM '.$this->prefix.'_tableVersion');
+ } catch (PDOException $e) {
+ $this->pdo->exec(
+ 'CREATE TABLE '.$this->prefix.
+ '_tableVersion (_name VARCHAR(30) NOT NULL UNIQUE, _version INTEGER NOT NULL)'
+ );
+ return;
+ }
+
+ while (($row = $fetchTableVersion->fetch(PDO::FETCH_ASSOC)) !== false) {
+ $this->tableVersions[$row['_name']] = (int) $row['_version'];
+ }
+ }
+
+
+ /**
+ * Initialize key-value table.
+ */
+ private function initKVTable()
+ {
+
+ if ($this->getTableVersion('kvstore') === 1) {
+ // Table initialized
+ return;
+ }
+
+ $text_t = 'TEXT';
+ if ($this->driver === 'mysql') {
+ // TEXT data type has size constraints that can be hit at some point, so we use LONGTEXT instead
+ $text_t = 'LONGTEXT';
+ }
+ $query = 'CREATE TABLE '.$this->prefix.
+ '_kvstore (_type VARCHAR(30) NOT NULL, _key VARCHAR(50) NOT NULL, _value '.$text_t.
+ ' NOT NULL, _expire TIMESTAMP, PRIMARY KEY (_key, _type))';
+ $this->pdo->exec($query);
+
+ $query = 'CREATE INDEX '.$this->prefix.'_kvstore_expire ON '.$this->prefix.'_kvstore (_expire)';
+ $this->pdo->exec($query);
+
+ $this->setTableVersion('kvstore', 1);
+ }
+
+
+ /**
+ * Get table version.
+ *
+ * @param string $name Table name.
+ *
+ * @return int The table version, or 0 if the table doesn't exist.
+ */
+ public function getTableVersion($name)
+ {
+ assert('is_string($name)');
+
+ if (!isset($this->tableVersions[$name])) {
+ return 0;
+ }
+
+ return $this->tableVersions[$name];
+ }
+
+
+ /**
+ * Set table version.
+ *
+ * @param string $name Table name.
+ * @param int $version Table version.
+ */
+ public function setTableVersion($name, $version)
+ {
+ assert('is_string($name)');
+ assert('is_int($version)');
+
+ $this->insertOrUpdate(
+ $this->prefix.'_tableVersion',
+ array('_name'),
+ array('_name' => $name, '_version' => $version)
+ );
+ $this->tableVersions[$name] = $version;
+ }
+
+
+ /**
+ * Insert or update a key-value in the store.
+ *
+ * Since various databases implement different methods for doing this, we abstract it away here.
+ *
+ * @param string $table The table we should update.
+ * @param array $keys The key columns.
+ * @param array $data Associative array with columns.
+ */
+ public function insertOrUpdate($table, array $keys, array $data)
+ {
+ assert('is_string($table)');
+
+ $colNames = '('.implode(', ', array_keys($data)).')';
+ $values = 'VALUES(:'.implode(', :', array_keys($data)).')';
+
+ switch ($this->driver) {
+ case 'mysql':
+ $query = 'REPLACE INTO '.$table.' '.$colNames.' '.$values;
+ $query = $this->pdo->prepare($query);
+ $query->execute($data);
+ return;
+ case 'sqlite':
+ $query = 'INSERT OR REPLACE INTO '.$table.' '.$colNames.' '.$values;
+ $query = $this->pdo->prepare($query);
+ $query->execute($data);
+ return;
+ }
+
+ // Default implementation. Try INSERT, and UPDATE if that fails.
+
+ $insertQuery = 'INSERT INTO '.$table.' '.$colNames.' '.$values;
+ $insertQuery = $this->pdo->prepare($insertQuery);
+ try {
+ $insertQuery->execute($data);
+ return;
+ } catch (PDOException $e) {
+ $ecode = (string) $e->getCode();
+ switch ($ecode) {
+ case '23505': // PostgreSQL
+ break;
+ default:
+ SimpleSAML\Logger::error('Error while saving data: '.$e->getMessage());
+ throw $e;
+ }
+ }
+
+ $updateCols = array();
+ $condCols = array();
+ foreach ($data as $col => $value) {
+
+ $tmp = $col.' = :'.$col;
+
+ if (in_array($col, $keys, true)) {
+ $condCols[] = $tmp;
+ } else {
+ $updateCols[] = $tmp;
+ }
+ }
+
+ $updateQuery = 'UPDATE '.$table.' SET '.implode(',', $updateCols).' WHERE '.implode(' AND ', $condCols);
+ $updateQuery = $this->pdo->prepare($updateQuery);
+ $updateQuery->execute($data);
+ }
+
+
+ /**
+ * Clean the key-value table of expired entries.
+ */
+ private function cleanKVStore()
+ {
+
+ SimpleSAML\Logger::debug('store.sql: Cleaning key-value store.');
+
+ $query = 'DELETE FROM '.$this->prefix.'_kvstore WHERE _expire < :now';
+ $params = array('now' => gmdate('Y-m-d H:i:s'));
+
+ $query = $this->pdo->prepare($query);
+ $query->execute($params);
+ }
+
+
+ /**
+ * Retrieve a value from the data store.
+ *
+ * @param string $type The type of the data.
+ * @param string $key The key to retrieve.
+ *
+ * @return mixed|null The value associated with that key, or null if there's no such key.
+ */
+ public function get($type, $key)
+ {
+ assert('is_string($type)');
+ assert('is_string($key)');
+
+ if (strlen($key) > 50) {
+ $key = sha1($key);
+ }
+
+ $query = 'SELECT _value FROM '.$this->prefix.
+ '_kvstore WHERE _type = :type AND _key = :key AND (_expire IS NULL OR _expire > :now)';
+ $params = array('type' => $type, 'key' => $key, 'now' => gmdate('Y-m-d H:i:s'));
+
+ $query = $this->pdo->prepare($query);
+ $query->execute($params);
+
+ $row = $query->fetch(PDO::FETCH_ASSOC);
+ if ($row === false) {
+ return null;
+ }
+
+ $value = $row['_value'];
+ if (is_resource($value)) {
+ $value = stream_get_contents($value);
+ }
+ $value = urldecode($value);
+ $value = unserialize($value);
+
+ if ($value === false) {
+ return null;
+ }
+ return $value;
+ }
+
+
+ /**
+ * Save a value in the data store.
+ *
+ * @param string $type The type of the data.
+ * @param string $key The key to insert.
+ * @param mixed $value The value itself.
+ * @param int|null $expire The expiration time (unix timestamp), or null if it never expires.
+ */
+ public function set($type, $key, $value, $expire = null)
+ {
+ assert('is_string($type)');
+ assert('is_string($key)');
+ assert('is_null($expire) || (is_int($expire) && $expire > 2592000)');
+
+ if (rand(0, 1000) < 10) {
+ $this->cleanKVStore();
+ }
+
+ if (strlen($key) > 50) {
+ $key = sha1($key);
+ }
+
+ if ($expire !== null) {
+ $expire = gmdate('Y-m-d H:i:s', $expire);
+ }
+
+ $value = serialize($value);
+ $value = rawurlencode($value);
+
+ $data = array(
+ '_type' => $type,
+ '_key' => $key,
+ '_value' => $value,
+ '_expire' => $expire,
+ );
+
+
+ $this->insertOrUpdate($this->prefix.'_kvstore', array('_type', '_key'), $data);
+ }
+
+
+ /**
+ * Delete an entry from the data store.
+ *
+ * @param string $type The type of the data
+ * @param string $key The key to delete.
+ */
+ public function delete($type, $key)
+ {
+ assert('is_string($type)');
+ assert('is_string($key)');
+
+ if (strlen($key) > 50) {
+ $key = sha1($key);
+ }
+
+ $data = array(
+ '_type' => $type,
+ '_key' => $key,
+ );
+
+ $query = 'DELETE FROM '.$this->prefix.'_kvstore WHERE _type=:_type AND _key=:_key';
+ $query = $this->pdo->prepare($query);
+ $query->execute($data);
+ }
}
diff --git a/lib/SimpleSAML/Utilities.php b/lib/SimpleSAML/Utilities.php
index e0f0754..e9cda0a 100644
--- a/lib/SimpleSAML/Utilities.php
+++ b/lib/SimpleSAML/Utilities.php
@@ -128,14 +128,14 @@ class SimpleSAML_Utilities
$currentTime = time();
if (!empty($start)) {
- $startTime = SAML2_Utils::xsDateTimeToTimestamp($start);
+ $startTime = \SAML2\Utils::xsDateTimeToTimestamp($start);
// Allow for a 10 minute difference in Time
if (($startTime < 0) || (($startTime - 600) > $currentTime)) {
return false;
}
}
if (!empty($end)) {
- $endTime = SAML2_Utils::xsDateTimeToTimestamp($end);
+ $endTime = \SAML2\Utils::xsDateTimeToTimestamp($end);
if (($endTime < 0) || ($endTime <= $currentTime)) {
return false;
}
diff --git a/lib/SimpleSAML/Utils/HTTP.php b/lib/SimpleSAML/Utils/HTTP.php
index 5ebf776..25d5596 100644
--- a/lib/SimpleSAML/Utils/HTTP.php
+++ b/lib/SimpleSAML/Utils/HTTP.php
@@ -162,12 +162,14 @@ class HTTP
Logger::warning('Redirecting to a URL longer than 2048 bytes.');
}
- // set the location header
- header('Location: '.$url, true, $code);
+ if (!headers_sent()) {
+ // set the location header
+ header('Location: '.$url, true, $code);
- // disable caching of this response
- header('Pragma: no-cache');
- header('Cache-Control: no-cache, must-revalidate');
+ // disable caching of this response
+ header('Pragma: no-cache');
+ header('Cache-Control: no-cache, must-revalidate');
+ }
// show a minimal web page with a clickable link to the URL
echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";
@@ -178,7 +180,7 @@ class HTTP
echo ' <meta http-equiv="content-type" content="text/html; charset=utf-8">'."\n";
echo " <title>Redirect</title>\n";
echo " </head>\n";
- echo " <body>\n";
+ echo " <body onload=\"window.location.replace('".htmlspecialchars($url)."');\">\n";
echo " <h1>Redirect</h1>\n";
echo ' <p>You were redirected to: <a id="redirlink" href="'.htmlspecialchars($url).'">';
echo htmlspecialchars($url)."</a>\n";
@@ -324,12 +326,30 @@ class HTTP
preg_match('@^https?://([^/]+)@i', $url, $matches);
$hostname = $matches[1];
- // add self host to the white list
$self_host = self::getSelfHostWithNonStandardPort();
- $trustedSites[] = $self_host;
+
+ $trustedRegex = \SimpleSAML_Configuration::getInstance()->getValue('trusted.url.regex', false);
+
+ $trusted = false;
+ if ($trustedRegex) {
+ // add self host to the white list
+ $trustedSites[] = preg_quote($self_host);
+ foreach ($trustedSites as $regex) {
+ // Add start and end delimiters.
+ $regex = "@^{$regex}$@";
+ if (preg_match($regex, $hostname)) {
+ $trusted = true;
+ break;
+ }
+ }
+ } else {
+ // add self host to the white list
+ $trustedSites[] = $self_host;
+ $trusted = in_array($hostname, $trustedSites);
+ }
// throw exception due to redirection to untrusted site
- if (!in_array($hostname, $trustedSites)) {
+ if (!$trusted) {
throw new \SimpleSAML_Error_Exception('URL not allowed: '.$url);
}
}
@@ -548,9 +568,9 @@ class HTTP
$globalConfig = \SimpleSAML_Configuration::getInstance();
$baseURL = $globalConfig->getString('baseurlpath', 'simplesaml/');
- if (preg_match('#^https?://.*/$#D', $baseURL, $matches)) {
+ if (preg_match('#^https?://.*/?$#D', $baseURL, $matches)) {
// full URL in baseurlpath, override local server values
- return $baseURL;
+ return rtrim($baseURL, '/').'/';
} elseif (
(preg_match('#^/?([^/]?.*/)$#D', $baseURL, $matches)) ||
(preg_match('#^\*(.*)/$#D', $baseURL, $matches)) ||
@@ -563,7 +583,7 @@ class HTTP
$hostname = self::getServerHost();
$port = self::getServerPort();
- $path = '/'.$globalConfig->getBaseURL();
+ $path = $globalConfig->getBasePath();
return $protocol.$hostname.$port.$path;
} else {
@@ -691,38 +711,57 @@ class HTTP
/**
- * Retrieve the current, complete URL.
+ * Retrieve the current URL using the base URL in the configuration, if possible.
+ *
+ * This method will try to see if the current script is part of SimpleSAMLphp. In that case, it will use the
+ * 'baseurlpath' configuration option to rebuild the current URL based on that. If the current script is NOT
+ * part of SimpleSAMLphp, it will just return the current URL.
+ *
+ * Note that this method does NOT make use of the HTTP X-Forwarded-* set of headers.
*
* @return string The current URL, including query parameters.
*
* @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no>
* @author Olav Morken, UNINETT AS <olav.morken@uninett.no>
+ * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no>
*/
public static function getSelfURL()
{
- $url = self::getSelfURLHost();
- $requestURI = $_SERVER['REQUEST_URI'];
- if ($requestURI[0] !== '/') {
- // we probably have a URL of the form: http://server/
- if (preg_match('#^https?://[^/]*(/.*)#i', $requestURI, $matches)) {
- $requestURI = $matches[1];
- }
+ $cfg = \SimpleSAML_Configuration::getInstance();
+ $baseDir = $cfg->getBaseDir();
+ $current_path = realpath($_SERVER['SCRIPT_FILENAME']);
+ $rel_path = str_replace($baseDir.'www'.DIRECTORY_SEPARATOR, '', $current_path);
+
+ if ($current_path == $rel_path) { // compare loosely ($current_path can be false)
+ // we were accessed from an external script, do not try to apply our base URL
+ $protocol = 'http';
+ $protocol .= (self::getServerHTTPS()) ? 's' : '';
+ $protocol .= '://';
+
+ $hostname = self::getServerHost();
+ $port = self::getServerPort();
+ return $protocol.$hostname.$port.$_SERVER['REQUEST_URI'];
}
- return $url.$requestURI;
+
+ $url = self::getBaseURL();
+ $rel_path = str_replace(DIRECTORY_SEPARATOR, '/', $rel_path);
+ $pos = strpos($_SERVER['REQUEST_URI'], $rel_path) + strlen($rel_path);
+ return $url.$rel_path.substr($_SERVER['REQUEST_URI'], $pos);
}
/**
- * Retrieve a URL containing the protocol, the current host and optionally, the port number.
+ * Retrieve the current URL using the base URL in the configuration, containing the protocol, the host and
+ * optionally, the port number.
*
- * @return string The current URL without a URL path or query parameters.
+ * @return string The current URL without path or query parameters.
*
* @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no>
* @author Olav Morken, UNINETT AS <olav.morken@uninett.no>
*/
public static function getSelfURLHost()
{
- $url = self::getBaseURL();
+ $url = self::getSelfURL();
$start = strpos($url, '://') + 3;
$length = strcspn($url, '/', $start) + $start;
return substr($url, 0, $length);
@@ -730,20 +769,21 @@ class HTTP
/**
- * Retrieve the current URL without the query parameters.
+ * Retrieve the current URL using the base URL in the configuration, without the query parameters.
*
* @return string The current URL, not including query parameters.
*
* @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no>
+ * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no>
*/
public static function getSelfURLNoQuery()
{
- $url = self::getSelfURLHost();
- $url .= $_SERVER['SCRIPT_NAME'];
- if (isset($_SERVER['PATH_INFO'])) {
- $url .= $_SERVER['PATH_INFO'];
+ $url = self::getSelfURL();
+ $pos = strpos($url, '?');
+ if (!$pos) {
+ return $url;
}
- return $url;
+ return substr($url, 0, $pos);
}
@@ -757,7 +797,7 @@ class HTTP
*/
public static function isHTTPS()
{
- return strpos(self::getBaseURL(), 'https://') === 0;
+ return strpos(self::getSelfURL(), 'https://') === 0;
}
@@ -812,6 +852,10 @@ class HTTP
}
$res = array();
+ if (empty($query_string)) {
+ return $res;
+ }
+
foreach (explode('&', $query_string) as $param) {
$param = explode('=', $param);
$name = urldecode($param[0]);
@@ -940,14 +984,13 @@ class HTTP
return $baseScheme.$url;
}
- $firstChar = substr($url, 0, 1);
- if ($firstChar === '/') {
+ if ($url[0] === '/') {
return $baseHost.$url;
}
- if ($firstChar === '?') {
+ if ($url[0] === '?') {
return $basePath.$url;
}
- if ($firstChar === '#') {
+ if ($url[0] === '#') {
return $baseQuery.$url;
}
@@ -987,7 +1030,7 @@ class HTTP
* @param bool $throw Whether to throw exception if setcookie() fails.
*
* @throws \InvalidArgumentException If any parameter has an incorrect type.
- * @throws \SimpleSAML_Error_Exception If the headers were already sent and the cookie cannot be set.
+ * @throws \SimpleSAML\Error\CannotSetCookie If the headers were already sent and the cookie cannot be set.
*
* @author Andjelko Horvat
* @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no>
@@ -1020,7 +1063,13 @@ class HTTP
// Do not set secure cookie if not on HTTPS
if ($params['secure'] && !self::isHTTPS()) {
- Logger::warning('Setting secure cookie on plain HTTP is not allowed.');
+ if ($throw) {
+ throw new \SimpleSAML\Error\CannotSetCookie(
+ 'Setting secure cookie on plain HTTP is not allowed.',
+ \SimpleSAML\Error\CannotSetCookie::SECURE_COOKIE
+ );
+ }
+ Logger::warning('Error setting cookie: setting secure cookie on plain HTTP is not allowed.');
return;
}
@@ -1035,7 +1084,7 @@ class HTTP
}
if ($params['raw']) {
- $success = setrawcookie(
+ $success = @setrawcookie(
$name,
$value,
$expire,
@@ -1045,7 +1094,7 @@ class HTTP
$params['httponly']
);
} else {
- $success = setcookie(
+ $success = @setcookie(
$name,
$value,
$expire,
@@ -1058,10 +1107,12 @@ class HTTP
if (!$success) {
if ($throw) {
- throw new \SimpleSAML_Error_Exception('Error setting cookie: headers already sent.');
- } else {
- Logger::warning('Error setting cookie: headers already sent.');
+ throw new \SimpleSAML\Error\CannotSetCookie(
+ 'Headers already sent.',
+ \SimpleSAML\Error\CannotSetCookie::HEADERS_SENT
+ );
}
+ Logger::warning('Error setting cookie: headers already sent.');
}
}
diff --git a/lib/SimpleSAML/Utils/XML.php b/lib/SimpleSAML/Utils/XML.php
index 092de6c..05206ec 100644
--- a/lib/SimpleSAML/Utils/XML.php
+++ b/lib/SimpleSAML/Utils/XML.php
@@ -8,7 +8,6 @@
namespace SimpleSAML\Utils;
use SimpleSAML\Logger;
-use Symfony\Component\Config\Definition\Exception\Exception;
class XML
{
@@ -229,7 +228,7 @@ class XML
}
try {
- $doc = \SAML2_DOMDocumentFactory::fromString($xml);
+ $doc = \SAML2\DOMDocumentFactory::fromString($xml);
} catch (\Exception $e) {
throw new \DOMException('Error parsing XML string.');
}
@@ -403,9 +402,9 @@ class XML
$res = true;
} else {
try {
- $dom = \SAML2_DOMDocumentFactory::fromString($xml);
+ $dom = \SAML2\DOMDocumentFactory::fromString($xml);
$res = true;
- } catch (Exception $e) {
+ } catch (\Exception $e) {
$res = false;
}
}
diff --git a/lib/SimpleSAML/XHTML/IdPDisco.php b/lib/SimpleSAML/XHTML/IdPDisco.php
index a71193e..ddb9285 100644
--- a/lib/SimpleSAML/XHTML/IdPDisco.php
+++ b/lib/SimpleSAML/XHTML/IdPDisco.php
@@ -217,7 +217,7 @@ class SimpleSAML_XHTML_IdPDisco
// we save the cookies for 90 days
'lifetime' => (60 * 60 * 24 * 90),
// the base path for cookies. This should be the installation directory for SimpleSAMLphp
- 'path' => ('/'.$this->config->getBaseUrl()),
+ 'path' => $this->config->getBasePath(),
'httponly' => false,
);
diff --git a/lib/SimpleSAML/XHTML/Template.php b/lib/SimpleSAML/XHTML/Template.php
index 7cbf709..138423c 100644
--- a/lib/SimpleSAML/XHTML/Template.php
+++ b/lib/SimpleSAML/XHTML/Template.php
@@ -38,6 +38,11 @@ class SimpleSAML_XHTML_Template
*/
private $template = 'default.php';
+ /*
+ * Main Twig namespace, to avoid misspelling it *again*
+ */
+ private $twig_namespace = \Twig_Loader_Filesystem::MAIN_NAMESPACE;
+
/**
* Constructor
@@ -46,23 +51,229 @@ class SimpleSAML_XHTML_Template
* @param string $template Which template file to load
* @param string|null $defaultDictionary The default dictionary where tags will come from.
*/
- public function __construct(SimpleSAML_Configuration $configuration, $template, $defaultDictionary = null)
+ public function __construct(\SimpleSAML_Configuration $configuration, $template, $defaultDictionary = null)
{
$this->configuration = $configuration;
$this->template = $template;
- $this->data['baseurlpath'] = $this->configuration->getBaseURL();
+ // TODO: do not remove the slash from the beginning, change the templates instead!
+ $this->data['baseurlpath'] = ltrim($this->configuration->getBasePath(), '/');
$this->translator = new SimpleSAML\Locale\Translate($configuration, $defaultDictionary);
+ $this->twig = $this->setupTwig();
}
/**
- * Return the internal translator object used by this template.
+ * Normalize the name of the template to one of the possible alternatives.
*
- * @return \SimpleSAML\Locale\Translate The translator that will be used with this template.
+ * @param string $templateName The template name to normalize.
+ * @return string The filename we need to look for.
*/
- public function getTranslator()
+ private function normalizeTemplateName($templateName)
{
- return $this->translator;
+ if (strripos($templateName, '.twig.html')) {
+ return $templateName;
+ }
+ $phppos = strripos($templateName, '.php');
+ if ($phppos) {
+ $templateName = substr($templateName, 0, $phppos);
+ }
+ $tplpos = strripos($templateName, '.tpl');
+ if ($tplpos) {
+ $templateName = substr($templateName, 0, $tplpos);
+ }
+ return $templateName.'.twig.html';
+ }
+
+
+ /**
+ * Set up the places where twig can look for templates.
+ *
+ * @return Twig_Loader_Filesystem|false The twig template loader or false if the template does not exist.
+ * @throws Twig_Error_Loader In case a failure occurs.
+ */
+ private function setupTwigTemplatepaths()
+ {
+ $filename = $this->normalizeTemplateName($this->template);
+
+ // get namespace if any
+ $namespace = '';
+ $split = explode(':', $filename, 2);
+ if (count($split) === 2) {
+ $namespace = $split[0];
+ $filename = $split[1];
+ }
+ $this->twig_template = $namespace ? '@'.$namespace.'/'.$filename : $filename;
+ $loader = new \Twig_Loader_Filesystem();
+ $templateDirs = array_merge(
+ $this->findThemeTemplateDirs(),
+ $this->findModuleTemplateDirs()
+ );
+ // default, themeless templates are checked last
+ $templateDirs[] = array(
+ $this->twig_namespace => $this->configuration->resolvePath('templates')
+ );
+ foreach ($templateDirs as $entry) {
+ $loader->addPath($entry[key($entry)], key($entry));
+ }
+ if (!$loader->exists($this->twig_template)) {
+ return false;
+ }
+ return $loader;
+ }
+
+
+ /**
+ * Setup twig.
+ */
+ private function setupTwig()
+ {
+ $auto_reload = $this->configuration->getBoolean('template.auto_reload', true);
+ $cache = false;
+ if (!$auto_reload) {
+ // Cache only used if auto_reload = false
+ $cache = $this->configuration->getString('template.cache', $this->configuration->resolvePath('cache'));
+ }
+ // set up template paths
+ $loader = $this->setupTwigTemplatepaths();
+ if (!$loader) {
+ return null;
+ }
+
+ return new \Twig_Environment($loader, array('cache' => $cache, 'auto_reload' => $auto_reload));
+ }
+
+ /*
+ * Add overriding templates in configured theme
+ *
+ * @return array an array of module => templatedir lookups
+ */
+ private function findThemeTemplateDirs()
+ {
+ // parse config to find theme and module theme is in, if any
+ $tmp = explode(':', $this->configuration->getString('theme.use', 'default'), 2);
+ if (count($tmp) === 2) {
+ $themeModule = $tmp[0];
+ $themeName = $tmp[1];
+ } else {
+ $themeModule = null;
+ $themeName = $tmp[0];
+ }
+ // default theme in use, abort
+ if ($themeName == 'default') {
+ return array();
+ }
+ if ($themeModule !== null) {
+ $moduleDir = \SimpleSAML\Module::getModuleDir($themeModule);
+ $themeDir = $moduleDir.'/themes/'.$themeName;
+ $files = scandir($themeDir);
+ if ($files) {
+ $themeTemplateDirs = array();
+ foreach ($files as $file) {
+ if ($file == '.' || $file == '..') {
+ continue;
+ }
+ // set correct name for default namespace
+ $ns = $file == 'default' ? $this->twig_namespace : $file;
+ $themeTemplateDirs[] = array($ns => $themeDir.'/'.$file);
+ }
+ return $themeTemplateDirs;
+ }
+ }
+ // theme not found
+ return array();
+ }
+
+ /*
+ * Which enabled modules have templates?
+ *
+ * @return array an array of module => templatedir lookups
+ */
+ private function findModuleTemplateDirs()
+ {
+ $all_modules = \SimpleSAML\Module::getModules();
+ $modules = array();
+ foreach ($all_modules as $module) {
+ if (!\SimpleSAML\Module::isModuleEnabled($module)) {
+ continue;
+ }
+ $moduledir = \SimpleSAML\Module::getModuleDir($module);
+ // check if module has a /templates dir, if so, append
+ $templatedir = $moduledir.'/templates';
+ if (is_dir($templatedir)) {
+ $modules[] = array($module => $templatedir);
+ }
+ }
+ return $modules;
+ }
+
+
+ /**
+ * Generate an array for its use in the language bar, indexed by the ISO 639-2 codes of the languages available,
+ * containing their localized names and the URL that should be used in order to change to that language.
+ *
+ * @return array The array containing information of all available languages.
+ */
+ private function generateLanguageBar()
+ {
+ $languages = $this->translator->getLanguage()->getLanguageList();
+ $langmap = null;
+ if (count($languages) > 1) {
+ $parameterName = $this->getTranslator()->getLanguage()->getLanguageParameterName();
+ $langmap = array();
+ foreach ($languages as $lang => $current) {
+ $lang = strtolower($lang);
+ $langname = $this->translator->getLanguage()->getLanguageLocalizedName($lang);
+ $url = false;
+ if (!$current) {
+ $url = htmlspecialchars(\SimpleSAML\Utils\HTTP::addURLParameters(
+ '',
+ array($parameterName => $lang)
+ ));
+ }
+ $langmap[$lang] = array(
+ 'name' => $langname,
+ 'url' => $url,
+ );
+ }
+ }
+ return $langmap;
+ }
+
+
+ /**
+ * Set some default context
+ */
+ private function twigDefaultContext()
+ {
+ $this->data['currentLanguage'] = $this->translator->getLanguage()->getLanguage();
+ // show language bar by default
+ if (!isset($this->data['hideLanguageBar'])) {
+ $this->data['hideLanguageBar'] = false;
+ }
+ // get languagebar
+ $this->data['languageBar'] = null;
+ if ($this->data['hideLanguageBar'] === false) {
+ $languageBar = $this->generateLanguageBar();
+ if (is_null($languageBar)) {
+ $this->data['hideLanguageBar'] = true;
+ } else {
+ $this->data['languageBar'] = $languageBar;
+ }
+ }
+
+ // assure that there is a <title> and <h1>
+ if (isset($this->data['header']) && !isset($this->data['pagetitle'])) {
+ $this->data['pagetitle'] = $this->data['header'];
+ }
+ if (!isset($this->data['pagetitle'])) {
+ $this->data['pagetitle'] = 'SimpleSAMLphp';
+ }
+
+ // set RTL
+ $this->data['isRTL'] = false;
+ if ($this->translator->getLanguage()->isLanguageRTL()) {
+ $this->data['isRTL'] = true;
+ }
}
@@ -71,8 +282,13 @@ class SimpleSAML_XHTML_Template
*/
public function show()
{
- $filename = $this->findTemplatePath($this->template);
- require($filename);
+ if ($this->twig) {
+ $this->twigDefaultContext();
+ echo $this->twig->render($this->twig_template, $this->data);
+ } else {
+ $filename = $this->findTemplatePath($this->template);
+ require($filename);
+ }
}
@@ -91,7 +307,7 @@ class SimpleSAML_XHTML_Template
*
* @throws Exception If the template file couldn't be found.
*/
- private function findTemplatePath($template)
+ private function findTemplatePath($template, $throw_exception = true)
{
assert('is_string($template)');
@@ -117,11 +333,11 @@ class SimpleSAML_XHTML_Template
if ($themeModule !== null) {
// .../module/<themeModule>/themes/<themeName>/<templateModule>/<templateName>
- $filename = SimpleSAML_Module::getModuleDir($themeModule).
+ $filename = \SimpleSAML\Module::getModuleDir($themeModule).
'/themes/'.$themeName.'/'.$templateModule.'/'.$templateName;
} elseif ($templateModule !== 'default') {
- // .../module/<templateModule>/templates/<themeName>/<templateName>
- $filename = SimpleSAML_Module::getModuleDir($templateModule).'/templates/'.$templateName;
+ // .../module/<templateModule>/templates/<templateName>
+ $filename = \SimpleSAML\Module::getModuleDir($templateModule).'/templates/'.$templateName;
} else {
// .../templates/<theme>/<templateName>
$filename = $this->configuration->getPathValue('templatedir', 'templates/').$templateName;
@@ -132,15 +348,15 @@ class SimpleSAML_XHTML_Template
}
// not found in current theme
- SimpleSAML_Logger::debug(
- $_SERVER['PHP_SELF'].' - Template: Could not find template file ['. $template.'] at ['.
+ \SimpleSAML\Logger::debug(
+ $_SERVER['PHP_SELF'].' - Template: Could not find template file ['.$template.'] at ['.
$filename.'] - now trying the base template'
);
// try default theme
if ($templateModule !== 'default') {
// .../module/<templateModule>/templates/<templateName>
- $filename = SimpleSAML_Module::getModuleDir($templateModule).'/templates/'.$templateName;
+ $filename = \SimpleSAML\Module::getModuleDir($templateModule).'/templates/'.$templateName;
} else {
// .../templates/<templateName>
$filename = $this->configuration->getPathValue('templatedir', 'templates/').'/'.$templateName;
@@ -150,11 +366,28 @@ class SimpleSAML_XHTML_Template
return $filename;
}
- // not found in default template - log error and throw exception
- $error = 'Template: Could not find template file ['.$template.'] at ['.$filename.']';
- SimpleSAML_Logger::critical($_SERVER['PHP_SELF'].' - '.$error);
+ // not found in default template
+ if ($throw_exception) {
+ // log error and throw exception
+ $error = 'Template: Could not find template file ['.$template.'] at ['.$filename.']';
+ \SimpleSAML\Logger::critical($_SERVER['PHP_SELF'].' - '.$error);
- throw new Exception($error);
+ throw new Exception($error);
+ } else {
+ // missing template expected, return NULL
+ return null;
+ }
+ }
+
+
+ /**
+ * Return the internal translator object used by this template.
+ *
+ * @return \SimpleSAML\Locale\Translate The translator that will be used with this template.
+ */
+ public function getTranslator()
+ {
+ return $this->translator;
}
@@ -190,6 +423,7 @@ class SimpleSAML_XHTML_Template
/**
* @param $language
* @param bool $setLanguageCookie
+ *
* @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Language::setLanguage()
* instead.
*/
@@ -212,6 +446,7 @@ class SimpleSAML_XHTML_Template
/**
* @param $language
+ *
* @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Language::setLanguageCookie()
* instead.
*/
@@ -220,10 +455,12 @@ class SimpleSAML_XHTML_Template
\SimpleSAML\Locale\Language::setLanguageCookie($language);
}
+
/**
* Wraps Language->getLanguageList
*/
- private function getLanguageList() {
+ private function getLanguageList()
+ {
return $this->translator->getLanguage()->getLanguageList();
}
@@ -241,10 +478,10 @@ class SimpleSAML_XHTML_Template
/**
- * Temporary wrapper for SimpleSAML\Locale\Translate::getPreferredTranslation().
+ * Temporary wrapper for \SimpleSAML\Locale\Translate::getPreferredTranslation().
*
* @deprecated This method will be removed in SSP 2.0. Please use
- * SimpleSAML\Locale\Translate::getPreferredTranslation() instead.
+ * \SimpleSAML\Locale\Translate::getPreferredTranslation() instead.
*/
public function getTranslation($translations)
{
@@ -257,7 +494,8 @@ class SimpleSAML_XHTML_Template
* This function can be used to include headers and footers etc.
*
*/
- private function includeAtTemplateBase($file) {
+ private function includeAtTemplateBase($file)
+ {
$data = $this->data;
$filename = $this->findTemplatePath($file);
@@ -282,6 +520,7 @@ class SimpleSAML_XHTML_Template
/**
* @param $file
* @param null $otherConfig
+ *
* @deprecated This method will be removed in SSP 2.0. Please use
* \SimpleSAML\Locale\Translate::includeLanguageFile() instead.
*/
@@ -294,7 +533,8 @@ class SimpleSAML_XHTML_Template
/**
* Wrap Language->isLanguageRTL
*/
- private function isLanguageRTL() {
+ private function isLanguageRTL()
+ {
return $this->translator->getLanguage()->isLanguageRTL();
}
@@ -304,6 +544,7 @@ class SimpleSAML_XHTML_Template
*
* @param array $def The array holding string definitions.
* @param array $lang The array holding translations for every string.
+ *
* @return array The recursive merge of both arrays.
* @deprecated This method will be removed in SimpleSAMLphp 2.0. Please use array_merge_recursive() instead.
*/
diff --git a/lib/SimpleSAML/XML/Shib13/AuthnResponse.php b/lib/SimpleSAML/XML/Shib13/AuthnResponse.php
index 6f6dd8a..ce0dbaa 100644
--- a/lib/SimpleSAML/XML/Shib13/AuthnResponse.php
+++ b/lib/SimpleSAML/XML/Shib13/AuthnResponse.php
@@ -57,7 +57,7 @@ class SimpleSAML_XML_Shib13_AuthnResponse {
assert('is_string($xml)');
try {
- $this->dom = SAML2_DOMDocumentFactory::fromString(str_replace ("\r", "", $xml));
+ $this->dom = \SAML2\DOMDocumentFactory::fromString(str_replace ("\r", "", $xml));
} catch(\Exception $e) {
throw new Exception('Unable to parse AuthnResponse XML.');
}
@@ -439,7 +439,7 @@ class SimpleSAML_XML_Shib13_AuthnResponse {
*
* @return bool True if the current time belongs to the period specified by $start and $end. False otherwise.
*
- * @see \SAML2_Utils::xsDateTimeToTimestamp.
+ * @see \SAML2\Utils::xsDateTimeToTimestamp.
*
* @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no>
* @author Olav Morken, UNINETT AS <olav.morken@uninett.no>
@@ -449,14 +449,14 @@ class SimpleSAML_XML_Shib13_AuthnResponse {
$currentTime = time();
if (!empty($start)) {
- $startTime = \SAML2_Utils::xsDateTimeToTimestamp($start);
+ $startTime = \SAML2\Utils::xsDateTimeToTimestamp($start);
// allow for a 10 minute difference in time
if (($startTime < 0) || (($startTime - 600) > $currentTime)) {
return false;
}
}
if (!empty($end)) {
- $endTime = \SAML2_Utils::xsDateTimeToTimestamp($end);
+ $endTime = \SAML2\Utils::xsDateTimeToTimestamp($end);
if (($endTime < 0) || ($endTime <= $currentTime)) {
return false;
}
diff --git a/lib/_autoload_modules.php b/lib/_autoload_modules.php
index 5eb8d2f..1cbe074 100644
--- a/lib/_autoload_modules.php
+++ b/lib/_autoload_modules.php
@@ -19,6 +19,14 @@
*/
function temporaryLoader($class)
{
+ // handle the upgrade to the latest version of XMLSecLibs using namespaces
+ if (strstr($class, 'XMLSec')) {
+ if (class_exists('\\RobRichards\\XMLSecLibs\\'.$class, true)) {
+ class_alias('\\RobRichards\\XMLSecLibs\\'.$class, $class);
+ return;
+ }
+ }
+
if (!strstr($class, 'SimpleSAML_')) {
return; // not a valid class name for old classes
}
diff --git a/modules/adfs/docs/adfs.txt b/modules/adfs/docs/adfs.md
index a57820a..a57820a 100644
--- a/modules/adfs/docs/adfs.txt
+++ b/modules/adfs/docs/adfs.md
diff --git a/modules/adfs/lib/IdP/ADFS.php b/modules/adfs/lib/IdP/ADFS.php
index 542a551..e294324 100644
--- a/modules/adfs/lib/IdP/ADFS.php
+++ b/modules/adfs/lib/IdP/ADFS.php
@@ -94,7 +94,7 @@ class sspmod_adfs_IdP_ADFS {
$objXMLSecDSig = new XMLSecurityDSig();
$objXMLSecDSig->idKeys = array('AssertionID');
$objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
- $responsedom = SAML2_DOMDocumentFactory::fromString(str_replace ("\r", "", $response));
+ $responsedom = \SAML2\DOMDocumentFactory::fromString(str_replace ("\r", "", $response));
$firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0);
$objXMLSecDSig->addReferenceList(array($firstassertionroot), XMLSecurityDSig::SHA1,
array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N),
diff --git a/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php b/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php
index b793b94..7e8a898 100644
--- a/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php
+++ b/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php
@@ -45,7 +45,7 @@ class sspmod_adfs_SAML2_XML_fed_SecurityTokenServiceType extends SAML2_XML_md_Ro
$e = parent::toXML($parent);
$e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:fed', sspmod_adfs_SAML2_XML_fed_Const::NS_FED);
- $e->setAttributeNS(SAML2_Const::NS_XSI, 'xsi:type', 'fed:SecurityTokenServiceType');
+ $e->setAttributeNS(\SAML2\Constants::NS_XSI, 'xsi:type', 'fed:SecurityTokenServiceType');
sspmod_adfs_SAML2_XML_fed_TokenTypesOffered::appendXML($e);
sspmod_adfs_SAML2_XML_fed_Endpoint::appendXML($e, 'SecurityTokenServiceEndpoint', $this->Location);
sspmod_adfs_SAML2_XML_fed_Endpoint::appendXML($e, 'fed:PassiveRequestorEndpoint', $this->Location);
diff --git a/modules/adfs/lib/XMLSecurityDSig.php b/modules/adfs/lib/XMLSecurityDSig.php
index 288812f..b851a18 100644
--- a/modules/adfs/lib/XMLSecurityDSig.php
+++ b/modules/adfs/lib/XMLSecurityDSig.php
@@ -24,7 +24,7 @@ class sspmod_adfs_XMLSecurityDSig extends XMLSecurityDSig {
$template = self::template;
}
- $sigdoc = SAML2_DOMDocumentFactory::fromString($template);
+ $sigdoc = \SAML2\DOMDocumentFactory::fromString($template);
$this->sigNode = $sigdoc->documentElement;
}
}
diff --git a/modules/adfs/www/idp/metadata.php b/modules/adfs/www/idp/metadata.php
index 7296a11..df59f5a 100644
--- a/modules/adfs/www/idp/metadata.php
+++ b/modules/adfs/www/idp/metadata.php
@@ -63,13 +63,13 @@ try {
'entityid' => $idpentityid,
'SingleSignOnService' => array(
0 => array(
- 'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT,
'Location' => $adfs_service_location
)
),
'SingleLogoutService' => array(
0 => array(
- 'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT,
'Location' => $adfs_service_location
)
),
diff --git a/modules/authX509/docs/authX509.txt b/modules/authX509/docs/authX509.md
index 1fc48a8..1fc48a8 100644
--- a/modules/authX509/docs/authX509.txt
+++ b/modules/authX509/docs/authX509.md
diff --git a/modules/authcrypt/docs/authcrypt.txt b/modules/authcrypt/docs/authcrypt.md
index 8319840..8319840 100644
--- a/modules/authcrypt/docs/authcrypt.txt
+++ b/modules/authcrypt/docs/authcrypt.md
diff --git a/modules/authfacebook/docs/authfacebook.txt b/modules/authfacebook/docs/authfacebook.md
index 41de426..41de426 100644
--- a/modules/authfacebook/docs/authfacebook.txt
+++ b/modules/authfacebook/docs/authfacebook.md
diff --git a/modules/authlinkedin/docs/oauthlinkedin.txt b/modules/authlinkedin/docs/oauthlinkedin.md
index 835935f..835935f 100644
--- a/modules/authlinkedin/docs/oauthlinkedin.txt
+++ b/modules/authlinkedin/docs/oauthlinkedin.md
diff --git a/modules/authmyspace/docs/oauthmyspace.txt b/modules/authmyspace/docs/oauthmyspace.md
index 98b97b8..98b97b8 100644
--- a/modules/authmyspace/docs/oauthmyspace.txt
+++ b/modules/authmyspace/docs/oauthmyspace.md
diff --git a/modules/authorize/docs/authorize.txt b/modules/authorize/docs/authorize.md
index de8cb4d..de8cb4d 100644
--- a/modules/authorize/docs/authorize.txt
+++ b/modules/authorize/docs/authorize.md
diff --git a/modules/authtwitter/docs/oauthtwitter.txt b/modules/authtwitter/docs/oauthtwitter.md
index c2507fc..c2507fc 100644
--- a/modules/authtwitter/docs/oauthtwitter.txt
+++ b/modules/authtwitter/docs/oauthtwitter.md
diff --git a/modules/authwindowslive/docs/windowsliveid.txt b/modules/authwindowslive/docs/windowsliveid.md
index 390edae..390edae 100644
--- a/modules/authwindowslive/docs/windowsliveid.txt
+++ b/modules/authwindowslive/docs/windowsliveid.md
diff --git a/modules/authwindowslive/lib/Auth/Source/LiveID.php b/modules/authwindowslive/lib/Auth/Source/LiveID.php
index 3b7c75c..8de392c 100644
--- a/modules/authwindowslive/lib/Auth/Source/LiveID.php
+++ b/modules/authwindowslive/lib/Auth/Source/LiveID.php
@@ -4,136 +4,159 @@
* Authenticate using LiveID.
*
* @author Brook Schofield, TERENA.
+ * @author Guy Halse, TENET.
* @package SimpleSAMLphp
*/
-class sspmod_authwindowslive_Auth_Source_LiveID extends SimpleSAML_Auth_Source {
-
- /**
- * The string used to identify our states.
- */
- const STAGE_INIT = 'authwindowslive:init';
-
- /**
- * The key of the AuthId field in the state.
- */
- const AUTHID = 'authwindowslive:AuthId';
-
- private $key;
- private $secret;
-
-
- /**
- * Constructor for this authentication source.
- *
- * @param array $info Information about this authentication source.
- * @param array $config Configuration.
- */
- public function __construct($info, $config) {
- assert('is_array($info)');
- assert('is_array($config)');
-
- // Call the parent constructor first, as required by the interface
- parent::__construct($info, $config);
-
- if (!array_key_exists('key', $config))
- throw new Exception('LiveID authentication source is not properly configured: missing [key]');
-
- $this->key = $config['key'];
-
- if (!array_key_exists('secret', $config))
- throw new Exception('LiveID authentication source is not properly configured: missing [secret]');
-
- $this->secret = $config['secret'];
- }
-
-
- /**
- * Log-in using LiveID platform
- *
- * @param array &$state Information about the current authentication.
- */
- public function authenticate(&$state) {
- assert('is_array($state)');
-
- // We are going to need the authId in order to retrieve this authentication source later
- $state[self::AUTHID] = $this->authId;
-
- $stateID = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
-
- SimpleSAML\Logger::debug('authwindowslive auth state id = ' . $stateID);
-
- // Authenticate the user
- // Documentation at: http://msdn.microsoft.com/en-us/library/ff749771.aspx
- $authorizeURL = 'https://consent.live.com/Connect.aspx'
- . '?wrap_client_id=' . $this->key
- . '&wrap_callback=' . urlencode(SimpleSAML\Module::getModuleUrl('authwindowslive') . '/linkback.php')
- . '&wrap_client_state=' . urlencode($stateID)
- . '&wrap_scope=WL_Profiles.View,Messenger.SignIn'
- ;
-
- \SimpleSAML\Utils\HTTP::redirectTrustedURL($authorizeURL);
- }
-
-
-
- public function finalStep(&$state) {
-
- SimpleSAML\Logger::debug("oauth wrap: Using this verification code [" .
- $state['authwindowslive:wrap_verification_code'] . "]");
-
- // Retrieve Access Token
- // Documentation at: http://msdn.microsoft.com/en-us/library/ff749686.aspx
- $postData = 'wrap_client_id=' . urlencode($this->key)
- . '&wrap_client_secret=' . urlencode($this->secret)
- . '&wrap_callback=' . urlencode(SimpleSAML\Module::getModuleUrl('authwindowslive') . '/linkback.php')
- . '&wrap_verification_code=' . urlencode($state['authwindowslive:wrap_verification_code']);
-
- $context = array(
- 'http' => array(
- 'method' => 'POST',
- 'header' => 'Content-type: application/x-www-form-urlencoded',
- 'content' => $postData,
- ),
- );
-
- $result = \SimpleSAML\Utils\HTTP::fetch('https://consent.live.com/AccessToken.aspx', $context);
-
- parse_str($result, $response);
-
- // error checking of $response to make sure we can proceed
- if (!array_key_exists('wrap_access_token',$response))
- throw new Exception('[' . $response['error_code'] . '] ' . $response['wrap_error_reason'] .
- "\r\nNo wrap_access_token returned - cannot proceed\r\n" . $response['internal_info']);
-
- SimpleSAML\Logger::debug("Got an access token from the OAuth WRAP service provider [" .
- $response['wrap_access_token'] . "] for user [" . $response['uid'] . "]");
-
- // Documentation at: http://msdn.microsoft.com/en-us/library/ff751708.aspx
- $opts = array('http' => array('header' => "Accept: application/json\r\nAuthorization: WRAP access_token=" .
- $response['wrap_access_token'] . "\r\n"));
- $data = \SimpleSAML\Utils\HTTP::fetch('https://apis.live.net/V4.1/cid-'. $response['uid'] . '/Profiles',$opts);
- $userdata = json_decode($data, TRUE);
-
- $attributes = array();
- $attributes['windowslive_uid'] = array($response['uid']);
- $attributes['windowslive_targetedID'] = array('http://windowslive.com!' . $response['uid']);
- $attributes['windowslive_user'] = array($response['uid'] . '@windowslive.com');
-
- if (array_key_exists('Entries',$userdata)) {
- foreach($userdata['Entries'][0] AS $key => $value) {
- if (is_string($value))
- $attributes['windowslive.' . $key] = array((string)$value);
- }
-
- if (array_key_exists('Emails', $userdata['Entries'][0]))
- $attributes['windowslive_mail'] = array($userdata['Entries'][0]['Emails'][0]['Address']);
-
- }
-
-
- SimpleSAML\Logger::debug('LiveID Returned Attributes: '. implode(", ",array_keys($attributes)));
-
- $state['Attributes'] = $attributes;
- }
-
+class sspmod_authwindowslive_Auth_Source_LiveID extends SimpleSAML_Auth_Source
+{
+
+ /**
+ * The string used to identify our states.
+ */
+ const STAGE_INIT = 'authwindowslive:init';
+
+ /**
+ * The key of the AuthId field in the state.
+ */
+ const AUTHID = 'authwindowslive:AuthId';
+
+ private $key;
+ private $secret;
+
+
+ /**
+ * Constructor for this authentication source.
+ *
+ * @param array $info Information about this authentication source.
+ * @param array $config Configuration.
+ *
+ * @throws Exception In case of misconfiguration.
+ */
+ public function __construct($info, $config)
+ {
+ assert('is_array($info)');
+ assert('is_array($config)');
+
+ // Call the parent constructor first, as required by the interface
+ parent::__construct($info, $config);
+
+ if (!array_key_exists('key', $config)) {
+ throw new Exception('LiveID authentication source is not properly configured: missing [key]');
+ }
+
+ $this->key = $config['key'];
+
+ if (!array_key_exists('secret', $config)) {
+ throw new Exception('LiveID authentication source is not properly configured: missing [secret]');
+ }
+
+ $this->secret = $config['secret'];
+ }
+
+
+ /**
+ * Log-in using LiveID platform
+ *
+ * @param array &$state Information about the current authentication.
+ */
+ public function authenticate(&$state)
+ {
+ assert('is_array($state)');
+
+ // we are going to need the authId in order to retrieve this authentication source later
+ $state[self::AUTHID] = $this->authId;
+
+ $stateID = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
+
+ SimpleSAML\Logger::debug('authwindowslive auth state id = ' . $stateID);
+
+ // authenticate the user
+ // documentation at:
+ // https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-protocols-oauth-code/
+ $authorizeURL = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize'
+ . '?client_id=' . $this->key
+ . '&response_type=code'
+ . '&response_mode=query'
+ . '&redirect_uri=' . urlencode(SimpleSAML\Module::getModuleUrl('authwindowslive') . '/linkback.php')
+ . '&state=' . urlencode($stateID)
+ . '&scope=' . urlencode('openid https://graph.microsoft.com/user.read')
+ ;
+
+ \SimpleSAML\Utils\HTTP::redirectTrustedURL($authorizeURL);
+ }
+
+
+ /**
+ * @param $state
+ *
+ * @throws Exception
+ */
+ public function finalStep(&$state)
+ {
+ SimpleSAML\Logger::debug(
+ "authwindowslive oauth: Using this verification code [".$state['authwindowslive:verification_code']."]"
+ );
+
+ // retrieve Access Token
+ // documentation at:
+ // https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-protocols-oauth-code/#request-an-access-token
+ $postData = 'client_id=' . urlencode($this->key)
+ . '&client_secret=' . urlencode($this->secret)
+ . '&scope=' . urlencode('https://graph.microsoft.com/user.read')
+ . '&grant_type=authorization_code'
+ . '&redirect_uri=' . urlencode(SimpleSAML\Module::getModuleUrl('authwindowslive') . '/linkback.php')
+ . '&code=' . urlencode($state['authwindowslive:verification_code']);
+
+ $context = array(
+ 'http' => array(
+ 'method' => 'POST',
+ 'header' => 'Content-type: application/x-www-form-urlencoded',
+ 'content' => $postData,
+ ),
+ );
+
+ $result = \SimpleSAML\Utils\HTTP::fetch('https://login.microsoftonline.com/common/oauth2/v2.0/token', $context);
+
+ $response = json_decode($result, true);
+
+ // error checking of $response to make sure we can proceed
+ if (!array_key_exists('access_token', $response)) {
+ throw new Exception(
+ '['.$response['error'].'] '.$response['error_description'].
+ "\r\nNo access_token returned - cannot proceed\r\n" . implode(', ', $response['error_codes'])
+ );
+ }
+
+ SimpleSAML\Logger::debug(
+ "authwindowslive: Got an access token from the OAuth service provider [".$response['access_token']."]"
+ );
+
+ // documentation at: http://graph.microsoft.io/en-us/docs/overview/call_api
+ $opts = array('http' => array('header' => "Accept: application/json\r\nAuthorization: Bearer ".
+ $response['access_token']."\r\n"));
+ $data = \SimpleSAML\Utils\HTTP::fetch('https://graph.microsoft.com/v1.0/me', $opts);
+ $userdata = json_decode($data, true);
+
+ // this is the simplest case
+ if (!array_key_exists('@odata.context', $userdata) || array_key_exists('error', $userdata)) {
+ throw new Exception(
+ 'Unable to retrieve userdata from Microsoft Graph ['.$userdata['error']['code'].'] '.
+ $userdata['error']['message']
+ );
+ }
+ $attributes = array();
+ $attributes['windowslive_targetedID'] = array(
+ 'https://graph.microsoft.com!'.(!empty($userdata['id']) ? $userdata['id'] : 'unknown')
+ );
+ foreach ($userdata as $key => $value) {
+ if (is_string($value)) {
+ $attributes['windowslive.' . $key] = array((string)$value);
+ }
+ }
+
+
+ SimpleSAML\Logger::debug('LiveID Returned Attributes: '. implode(", ", array_keys($attributes)));
+
+ $state['Attributes'] = $attributes;
+ }
}
diff --git a/modules/authwindowslive/www/linkback.php b/modules/authwindowslive/www/linkback.php
index fcfd3d6..396de53 100644
--- a/modules/authwindowslive/www/linkback.php
+++ b/modules/authwindowslive/www/linkback.php
@@ -4,42 +4,43 @@
* Handle linkback() response from Windows Live ID.
*/
-if (!array_key_exists('wrap_client_state', $_REQUEST)) {
- throw new Exception('Lost OAuth-WRAP Client State');
+if (!array_key_exists('state', $_REQUEST)) {
+ throw new Exception('Lost OAuth Client State');
}
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['wrap_client_state'], sspmod_authwindowslive_Auth_Source_LiveID::STAGE_INIT);
+$state = SimpleSAML_Auth_State::loadState($_REQUEST['state'], sspmod_authwindowslive_Auth_Source_LiveID::STAGE_INIT);
// http://msdn.microsoft.com/en-us/library/ff749771.aspx
-if (array_key_exists('wrap_verification_code', $_REQUEST)) {
-
- // Good
- $state['authwindowslive:wrap_verification_code'] = $_REQUEST['wrap_verification_code'];
-
- if (array_key_exists('exp', $_REQUEST))
- $state['authwindowslive:wrap_exp'] = $_REQUEST['exp'];
+if (array_key_exists('code', $_REQUEST)) {
+ // good
+ $state['authwindowslive:verification_code'] = $_REQUEST['code'];
+ if (array_key_exists('exp', $_REQUEST)) {
+ $state['authwindowslive:exp'] = $_REQUEST['exp'];
+ }
} else {
- // wrap_error_reason = 'user_denied' means user chose not to login with LiveID
- // redirect them to their original page so they can choose another auth mechanism
- if ($_REQUEST['wrap_error_reason'] === 'user_denied') {
- $e = new SimpleSAML_Error_UserAborted();
- SimpleSAML_Auth_State::throwException($state, $e);
- }
-
- // Error
- throw new Exception('Authentication failed: [' . $_REQUEST['error_code'] . '] ' . $_REQUEST['wrap_error_reason']);
+ // In the OAuth WRAP service, error_reason = 'user_denied' means user chose
+ // not to login with LiveID. It isn't clear that this is still true in the
+ // newer API, but the parameter name has changed to error. It doesn't hurt
+ // to preserve support for this, so this is left in as a placeholder.
+ // redirect them to their original page so they can choose another auth mechanism
+ if ($_REQUEST['error'] === 'user_denied') {
+ $e = new SimpleSAML_Error_UserAborted();
+ SimpleSAML_Auth_State::throwException($state, $e);
+ }
+
+ // error
+ throw new Exception('Authentication failed: ['.$_REQUEST['error'].'] '.$_REQUEST['error_description']);
}
-// Find authentication source
+// find authentication source
assert('array_key_exists(sspmod_authwindowslive_Auth_Source_LiveID::AUTHID, $state)');
$sourceId = $state[sspmod_authwindowslive_Auth_Source_LiveID::AUTHID];
$source = SimpleSAML_Auth_Source::getById($sourceId);
-if ($source === NULL) {
- throw new Exception('Could not find authentication source with id ' . $sourceId);
+if ($source === null) {
+ throw new Exception('Could not find authentication source with id '.$sourceId);
}
$source->finalStep($state);
SimpleSAML_Auth_Source::completeAuth($state);
-
diff --git a/modules/cas/docs/cas.txt b/modules/cas/docs/cas.md
index 5bfd50c..5bfd50c 100644
--- a/modules/cas/docs/cas.txt
+++ b/modules/cas/docs/cas.md
diff --git a/modules/cas/lib/Auth/Source/CAS.php b/modules/cas/lib/Auth/Source/CAS.php
index 39b40bd..1b2f1e0 100644
--- a/modules/cas/lib/Auth/Source/CAS.php
+++ b/modules/cas/lib/Auth/Source/CAS.php
@@ -118,7 +118,7 @@ class sspmod_cas_Auth_Source_CAS extends SimpleSAML_Auth_Source {
));
$result = \SimpleSAML\Utils\HTTP::fetch($url);
- $dom = SAML2_DOMDocumentFactory::fromString($result);
+ $dom = \SAML2\DOMDocumentFactory::fromString($result);
$xPath = new DOMXpath($dom);
$xPath->registerNamespace("cas", 'http://www.yale.edu/tp/cas');
$success = $xPath->query("/cas:serviceResponse/cas:authenticationSuccess/cas:user");
diff --git a/modules/consent/docs/consent.txt b/modules/consent/docs/consent.md
index e503a57..e503a57 100644
--- a/modules/consent/docs/consent.txt
+++ b/modules/consent/docs/consent.md
diff --git a/modules/consent/lib/Consent/Store/Cookie.php b/modules/consent/lib/Consent/Store/Cookie.php
index 95a96ba..8da1cba 100644
--- a/modules/consent/lib/Consent/Store/Cookie.php
+++ b/modules/consent/lib/Consent/Store/Cookie.php
@@ -268,7 +268,7 @@ class sspmod_consent_Consent_Store_Cookie extends sspmod_consent_Store
$globalConfig = SimpleSAML_Configuration::getInstance();
$params = array(
'lifetime' => (90*24*60*60),
- 'path' => ('/' . $globalConfig->getBaseURL()),
+ 'path' => ($globalConfig->getBasePath()),
'httponly' => FALSE,
);
diff --git a/modules/consentAdmin/docs/consentAdmin.txt b/modules/consentAdmin/docs/consentAdmin.md
index 749da82..749da82 100644
--- a/modules/consentAdmin/docs/consentAdmin.txt
+++ b/modules/consentAdmin/docs/consentAdmin.md
diff --git a/modules/core/dictionaries/frontpage.definition.json b/modules/core/dictionaries/frontpage.definition.json
index 8cb730b..ee509f4 100644
--- a/modules/core/dictionaries/frontpage.definition.json
+++ b/modules/core/dictionaries/frontpage.definition.json
@@ -35,7 +35,7 @@
"optional": {
"en": "Optional"
},
- "reccomended": {
+ "recommended": {
"en": "Recommended"
},
"warnings": {
@@ -50,6 +50,9 @@
"warnings_suhosin_url_length": {
"en": "The length of query parameters is limited by the PHP Suhosin extension. Please increase the suhosin.get.max_value_length option to at least 2048 bytes."
},
+ "warnings_outdated": {
+ "en": "You are running an outdated version of SimpleSAMLphp. Please update to <a href=\"%LATEST_URL%\">the latest version</a> as soon as possible."
+ },
"link_saml2example": {
"en": "SAML 2.0 SP example - test logging in through your IdP"
},
diff --git a/modules/core/dictionaries/frontpage.translation.json b/modules/core/dictionaries/frontpage.translation.json
index 6637597..d7d0225 100644
--- a/modules/core/dictionaries/frontpage.translation.json
+++ b/modules/core/dictionaries/frontpage.translation.json
@@ -384,7 +384,7 @@
"eu": "Hautazkoa",
"el": "\u03a0\u03c1\u03bf\u03b1\u03b9\u03c1\u03b5\u03c4\u03b9\u03ba\u03cc"
},
- "reccomended": {
+ "recommended": {
"no": "Anbefalt",
"nn": "Tilr\u00e5dd",
"sv": "Rekommenderad",
@@ -1625,5 +1625,9 @@
"nl": "<strong>De configuratie bevat de sandaard secret salt<\/strong> - verander altijd de 'secretsalt'-optie in de simpleSAML-configuratie voor productieomgevingen. [<a href=\"https:\/\/simplesamlphp.org\/docs\/stable\/simplesamlphp-install\">Lees meer over het configureren van SimpleSAMLphp<\/a> ]",
"da": "<strong>Ops\u00e6tningen benytter standard 'secret salt'<\/strong> - s\u00f8rg for at \u00e6ndre standard indstillingen for 'secretsalt' i simpleSAML ops\u00e6tningen i produktionssystemer. [<a href=\"https:\/\/simplesamlphp.org\/docs\/stable\/simplesamlphp-install\">L\u00e6s mere om SimpleSAMLphp ops\u00e6tning.<\/a> ]",
"el": "<strong>\u03a7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03b5\u03af\u03c4\u03b5 \u03c4\u03b7\u03bd \u03c0\u03c1\u03bf\u03b5\u03c0\u03b9\u03bb\u03b5\u03b3\u03bc\u03ad\u03bd\u03b7 \u03c4\u03b9\u03bc\u03ae \u03c4\u03bf\u03c5 \u03bc\u03c5\u03c3\u03c4\u03b9\u03ba\u03bf\u03cd \u03ba\u03bb\u03b5\u03b9\u03b4\u03b9\u03bf\u03cd (salt)<\/strong> - \u03c6\u03c1\u03bf\u03bd\u03c4\u03af\u03c3\u03c4\u03b5 \u03bd\u03b1 \u03c4\u03c1\u03bf\u03c0\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03c4\u03b5 \u03c4\u03b7\u03bd \u03c0\u03b1\u03c1\u03ac\u03bc\u03b5\u03c4\u03c1\u03bf 'secretsalt' \u03c3\u03c4\u03b9\u03c2 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03c4\u03bf\u03c5 SimpleSAMLphp \u03c3\u03b5 \u03c0\u03b5\u03c1\u03b9\u03b2\u03ac\u03bb\u03bb\u03bf\u03bd \u03c0\u03b1\u03c1\u03b1\u03b3\u03c9\u03b3\u03ae\u03c2. [<a href=\"https:\/\/simplesamlphp.org\/docs\/stable\/simplesamlphp-install\">\u0394\u03b9\u03b1\u03b2\u03ac\u03c3\u03c4\u03b5 \u03c0\u03b5\u03c1\u03b9\u03c3\u03c3\u03cc\u03c4\u03b5\u03c1\u03b1...<\/a> ]"
+ },
+ "warnings_outdated": {
+ "es": "Su instalaci&oacute;n de SimpleSAMLphp est&aacute; desactualizada. Por favor, actualice a la <a href=\"%LATEST_URL%\">&uacute;ltima versi&oacute;n</a> lo antes posible.",
+ "nl": "Deze installatie van SimpleSAMLphp is verouderd. Het is aan te raden zo snel mogelijk te upgraden naar <a href=\"%LATEST_URL%\">de meest recente versie</a>."
}
}
diff --git a/modules/core/docs/authproc_attributeadd.txt b/modules/core/docs/authproc_attributeadd.md
index ae9f4bd..ae9f4bd 100644
--- a/modules/core/docs/authproc_attributeadd.txt
+++ b/modules/core/docs/authproc_attributeadd.md
diff --git a/modules/core/docs/authproc_attributealter.txt b/modules/core/docs/authproc_attributealter.md
index b901069..b901069 100644
--- a/modules/core/docs/authproc_attributealter.txt
+++ b/modules/core/docs/authproc_attributealter.md
diff --git a/modules/core/docs/authproc_attributecopy.txt b/modules/core/docs/authproc_attributecopy.md
index 37c99ea..37c99ea 100644
--- a/modules/core/docs/authproc_attributecopy.txt
+++ b/modules/core/docs/authproc_attributecopy.md
diff --git a/modules/core/docs/authproc_attributelimit.txt b/modules/core/docs/authproc_attributelimit.md
index 5b640fd..5b640fd 100644
--- a/modules/core/docs/authproc_attributelimit.txt
+++ b/modules/core/docs/authproc_attributelimit.md
diff --git a/modules/core/docs/authproc_attributemap.txt b/modules/core/docs/authproc_attributemap.md
index 09364dd..09364dd 100644
--- a/modules/core/docs/authproc_attributemap.txt
+++ b/modules/core/docs/authproc_attributemap.md
diff --git a/modules/core/docs/authproc_attributerealm.txt b/modules/core/docs/authproc_attributerealm.md
index 77b0bb3..77b0bb3 100644
--- a/modules/core/docs/authproc_attributerealm.txt
+++ b/modules/core/docs/authproc_attributerealm.md
diff --git a/modules/core/docs/authproc_attributevaluemap.txt b/modules/core/docs/authproc_attributevaluemap.md
index cf7468a..cf7468a 100644
--- a/modules/core/docs/authproc_attributevaluemap.txt
+++ b/modules/core/docs/authproc_attributevaluemap.md
diff --git a/modules/core/docs/authproc_generategroups.txt b/modules/core/docs/authproc_generategroups.md
index b09e07f..b09e07f 100644
--- a/modules/core/docs/authproc_generategroups.txt
+++ b/modules/core/docs/authproc_generategroups.md
diff --git a/modules/core/docs/authproc_languageadaptor.txt b/modules/core/docs/authproc_languageadaptor.md
index d624b4d..d624b4d 100644
--- a/modules/core/docs/authproc_languageadaptor.txt
+++ b/modules/core/docs/authproc_languageadaptor.md
diff --git a/modules/core/docs/authproc_php.txt b/modules/core/docs/authproc_php.md
index 66968ed..66968ed 100644
--- a/modules/core/docs/authproc_php.txt
+++ b/modules/core/docs/authproc_php.md
diff --git a/modules/core/docs/authproc_scopeattribute.txt b/modules/core/docs/authproc_scopeattribute.md
index 6930149..5861587 100644
--- a/modules/core/docs/authproc_scopeattribute.txt
+++ b/modules/core/docs/authproc_scopeattribute.md
@@ -26,6 +26,12 @@ Parameters
: If the attribute already exists, the new values will be merged into the existing attribute.
+`onlyIfEmpty`
+: Only replace the targetAttribute if it is empty to begin with.
+
+: If `true`, then the targetAttribute will only be created if it didn't already contain values. Defaults to `false`.
+
+: This is useful if, for instance, you want to create eduPersonScopedAffiliation from eduPersonAffiliation _only_ if eduPersonScopedAffiliation was not returned by the authenticaton source.
Example
-------
diff --git a/modules/core/docs/authproc_scopefromattribute.txt b/modules/core/docs/authproc_scopefromattribute.md
index 0b7f92b..0b7f92b 100644
--- a/modules/core/docs/authproc_scopefromattribute.txt
+++ b/modules/core/docs/authproc_scopefromattribute.md
diff --git a/modules/core/docs/authproc_statisticswithattribute.txt b/modules/core/docs/authproc_statisticswithattribute.md
index 53753f9..53753f9 100644
--- a/modules/core/docs/authproc_statisticswithattribute.txt
+++ b/modules/core/docs/authproc_statisticswithattribute.md
diff --git a/modules/core/docs/authproc_targetedid.txt b/modules/core/docs/authproc_targetedid.md
index f6cea7d..f6cea7d 100644
--- a/modules/core/docs/authproc_targetedid.txt
+++ b/modules/core/docs/authproc_targetedid.md
diff --git a/modules/core/docs/authproc_warnshortssointerval.txt b/modules/core/docs/authproc_warnshortssointerval.md
index 73f24a2..73f24a2 100644
--- a/modules/core/docs/authproc_warnshortssointerval.txt
+++ b/modules/core/docs/authproc_warnshortssointerval.md
diff --git a/modules/core/lib/Auth/Process/ScopeAttribute.php b/modules/core/lib/Auth/Process/ScopeAttribute.php
index 9c8c571..6c2c03a 100644
--- a/modules/core/lib/Auth/Process/ScopeAttribute.php
+++ b/modules/core/lib/Auth/Process/ScopeAttribute.php
@@ -30,6 +30,13 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
*/
private $targetAttribute;
+ /**
+ * Only modify targetAttribute if it doesn't already exist.
+ *
+ * @var bool
+ */
+ private $onlyIfEmpty = false;
+
/**
* Initialize this filter, parse configuration
@@ -46,6 +53,7 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
$this->scopeAttribute = $config->getString('scopeAttribute');
$this->sourceAttribute = $config->getString('sourceAttribute');
$this->targetAttribute = $config->getString('targetAttribute');
+ $this->onlyIfEmpty = $config->getBoolean('onlyIfEmpty', false);
}
@@ -72,6 +80,10 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
$attributes[$this->targetAttribute] = array();
}
+ if ($this->onlyIfEmpty and count($attributes[$this->targetAttribute]) > 0) {
+ return;
+ }
+
foreach ($attributes[$this->scopeAttribute] as $scope) {
if (strpos($scope, '@') !== FALSE) {
@@ -93,4 +105,4 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
}
-} \ No newline at end of file
+}
diff --git a/modules/core/lib/Auth/Process/TargetedID.php b/modules/core/lib/Auth/Process/TargetedID.php
index 4c9dea9..4182cee 100644
--- a/modules/core/lib/Auth/Process/TargetedID.php
+++ b/modules/core/lib/Auth/Process/TargetedID.php
@@ -125,7 +125,7 @@ class sspmod_core_Auth_Process_TargetedID extends SimpleSAML_Auth_ProcessingFilt
if ($this->generateNameId) {
// Convert the targeted ID to a SAML 2.0 name identifier element
$nameId = array(
- 'Format' => SAML2_Const::NAMEID_PERSISTENT,
+ 'Format' => \SAML2\Constants::NAMEID_PERSISTENT,
'Value' => $uid,
);
@@ -136,11 +136,11 @@ class sspmod_core_Auth_Process_TargetedID extends SimpleSAML_Auth_ProcessingFilt
$nameId['SPNameQualifier'] = $state['Destination']['entityid'];
}
- $doc = SAML2_DOMDocumentFactory::create();
+ $doc = \SAML2\DOMDocumentFactory::create();
$root = $doc->createElement('root');
$doc->appendChild($root);
- SAML2_Utils::addNameId($root, $nameId);
+ \SAML2\Utils::addNameId($root, $nameId);
$uid = $doc->saveXML($root->firstChild);
}
diff --git a/modules/core/lib/Stats/Output/Log.php b/modules/core/lib/Stats/Output/Log.php
index 9c50dfa..70e914e 100644
--- a/modules/core/lib/Stats/Output/Log.php
+++ b/modules/core/lib/Stats/Output/Log.php
@@ -22,7 +22,7 @@ class sspmod_core_Stats_Output_Log extends SimpleSAML_Stats_Output {
public function __construct(SimpleSAML_Configuration $config) {
$logLevel = $config->getString('level', 'notice');
- $this->logger = array('SimpleSAML_Logger', $logLevel);
+ $this->logger = array('SimpleSAML\Logger', $logLevel);
if (!is_callable($this->logger)) {
throw new Exception('Invalid log level: ' . var_export($logLevel, TRUE));
}
diff --git a/modules/core/templates/frontpage_config.tpl.php b/modules/core/templates/frontpage_config.tpl.php
index bef8035..8b7eed1 100644
--- a/modules/core/templates/frontpage_config.tpl.php
+++ b/modules/core/templates/frontpage_config.tpl.php
@@ -67,7 +67,11 @@ if ($this->data['isadmin']) {
echo '<h2>' . $this->t('{core:frontpage:warnings}') . '</h2>';
foreach($this->data['warnings'] AS $warning) {
- echo '<div class="caution">' . $this->t($warning) . '</div>';
+ if (is_array($warning)) {
+ echo '<div class="caution">' . $this->t($warning[0], $warning[1]) . '</div>';
+ } else {
+ echo '<div class="caution">'.$this->t($warning).'</div>';
+ }
}
}
?>
diff --git a/modules/core/templates/no_cookie.tpl.php b/modules/core/templates/no_cookie.tpl.php
index bec98bd..40337a6 100644
--- a/modules/core/templates/no_cookie.tpl.php
+++ b/modules/core/templates/no_cookie.tpl.php
@@ -10,13 +10,13 @@ $retry = htmlspecialchars($this->t('{core:no_cookie:retry}'));
$this->data['header'] = $header;
$this->includeAtTemplateBase('includes/header.php');
-echo('<h2>' . $header . '</h2>');
-echo('<p>' . $description . '</p>');
+echo('<h2>'.$header.'</h2>');
+echo('<p>'.$description.'</p>');
-if ($retryURL !== NULL) {
- echo('<ul>');
- echo('<li><a href="' . htmlspecialchars($retryURL) . '" id="retry">' . $retry . '</a></li>');
- echo('</ul>');
+if ($retryURL !== null) {
+ echo('<ul>');
+ echo('<li><a href="'.htmlspecialchars($retryURL).'" id="retry">'.$retry.'</a></li>');
+ echo('</ul>');
}
$this->includeAtTemplateBase('includes/footer.php');
diff --git a/modules/core/www/as_login.php b/modules/core/www/as_login.php
index 9fcd6ba..189e054 100644
--- a/modules/core/www/as_login.php
+++ b/modules/core/www/as_login.php
@@ -6,11 +6,11 @@
* @package SimpleSAMLphp
*/
-if (!is_string($_REQUEST['ReturnTo'])) {
+if (!isset($_REQUEST['ReturnTo'])) {
throw new SimpleSAML_Error_BadRequest('Missing ReturnTo parameter.');
}
-if (!is_string($_REQUEST['AuthId'])) {
+if (!isset($_REQUEST['AuthId'])) {
throw new SimpleSAML_Error_BadRequest('Missing AuthId parameter.');
}
diff --git a/modules/core/www/authenticate.php b/modules/core/www/authenticate.php
index 5b97da3..d710825 100644
--- a/modules/core/www/authenticate.php
+++ b/modules/core/www/authenticate.php
@@ -14,7 +14,7 @@ $asId = (string) $_REQUEST['as'];
$as = new SimpleSAML_Auth_Simple($asId);
if (array_key_exists('logout', $_REQUEST)) {
- $as->logout('/'.$config->getBaseURL().'logout.php');
+ $as->logout($config->getBasePath().'logout.php');
}
if (array_key_exists(SimpleSAML_Auth_State::EXCEPTION_PARAM, $_REQUEST)) {
@@ -24,12 +24,7 @@ if (array_key_exists(SimpleSAML_Auth_State::EXCEPTION_PARAM, $_REQUEST)) {
assert('array_key_exists(SimpleSAML_Auth_State::EXCEPTION_DATA, $state)');
$e = $state[SimpleSAML_Auth_State::EXCEPTION_DATA];
- header('Content-Type: text/plain');
- echo "Exception during login:\n";
- foreach ($e->format() as $line) {
- echo $line."\n";
- }
- exit(0);
+ throw $e;
}
if (!$as->isAuthenticated()) {
diff --git a/modules/core/www/cleardiscochoices.php b/modules/core/www/cleardiscochoices.php
index a5616d8..3628a45 100644
--- a/modules/core/www/cleardiscochoices.php
+++ b/modules/core/www/cleardiscochoices.php
@@ -8,7 +8,7 @@ require_once('_include.php');
// The base path for cookies. This should be the installation directory for SimpleSAMLphp.
$config = SimpleSAML_Configuration::getInstance();
-$cookiePath = '/' . $config->getBaseUrl();
+$cookiePath = $config->getBasePath();
// We delete all cookies which starts with 'idpdisco_'
foreach($_COOKIE as $cookieName => $value) {
diff --git a/modules/core/www/frontpage_config.php b/modules/core/www/frontpage_config.php
index cc728ff..aaec942 100644
--- a/modules/core/www/frontpage_config.php
+++ b/modules/core/www/frontpage_config.php
@@ -53,6 +53,10 @@ $links_config[] = array(
'text' => '{core:frontpage:link_phpinfo}'
);
+$links_config[] = array(
+ 'href' => \SimpleSAML\Utils\HTTP::getBaseURL() . 'admin/sandbox.php',
+ 'text' => '{core:frontpage:link_sandbox}'
+);
@@ -66,11 +70,35 @@ $allLinks = array(
);
SimpleSAML\Module::callHooks('frontpage', $allLinks);
+// Check for updates. Store the remote result in the session so we
+// don't need to fetch it on every access to this page.
+$current = $config->getVersion();
+if ($config->getBoolean('admin.checkforupdates', true) && $current !== 'master') {
+ $latest = $session->getData("core:latest_simplesamlphp_version", "version");
+
+ if (!$latest) {
+ $api_url = 'https://api.github.com/repos/simplesamlphp/simplesamlphp/releases';
+ $ch = curl_init($api_url.'/latest');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_USERAGENT, 'SimpleSAMLphp');
+ curl_setopt($ch, CURLOPT_TIMEOUT, 2);
+ $response = curl_exec($ch);
+
+ if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
+ $latest = json_decode($response, true);
+ $session->setData("core:latest_simplesamlphp_version", "version", $latest);
+ }
+ curl_close($ch);
+ }
-
-
-
-
+ if ($latest && version_compare($current, ltrim($latest['tag_name'], 'v'), 'lt')) {
+ $outdated = true;
+ $warnings[] = array(
+ '{core:frontpage:warnings_outdated}',
+ array('%LATEST_URL%' => $latest['html_url'])
+ );
+ }
+}
$enablematrix = array(
'saml20-idp' => $config->getBoolean('enable.saml20-idp', false),
@@ -113,7 +141,7 @@ if($config->getString('technicalcontact_email', 'na@example.org') === 'na@exampl
$mail_ok = TRUE;
}
$funcmatrix[] = array(
- 'required' => 'reccomended',
+ 'required' => 'recommended',
'descr' => 'technicalcontact_email option set',
'enabled' => $mail_ok
);
@@ -129,7 +157,7 @@ $funcmatrix[] = array(
);
$funcmatrix[] = array(
- 'required' => 'reccomended',
+ 'required' => 'recommended',
'descr' => 'Magic Quotes should be turned off',
'enabled' => (get_magic_quotes_runtime() == 0)
);
diff --git a/modules/core/www/frontpage_federation.php b/modules/core/www/frontpage_federation.php
index 7b8ac2b..35f31d4 100644
--- a/modules/core/www/frontpage_federation.php
+++ b/modules/core/www/frontpage_federation.php
@@ -78,7 +78,7 @@ if ($isadmin) {
if ($config->getBoolean('enable.saml20-idp', FALSE) === true) {
try {
$metaentries['hosted']['saml20-idp'] = $metadata->getMetaDataCurrent('saml20-idp-hosted');
- $metaentries['hosted']['saml20-idp']['metadata-url'] = '/' . $config->getBaseURL() .
+ $metaentries['hosted']['saml20-idp']['metadata-url'] = $config->getBasePath() .
'saml2/idp/metadata.php?output=xhtml';
if ($isadmin)
$metaentries['remote']['saml20-sp-remote'] = $metadata->getList('saml20-sp-remote');
@@ -87,7 +87,7 @@ if ($config->getBoolean('enable.saml20-idp', FALSE) === true) {
if ($config->getBoolean('enable.shib13-idp', FALSE) === true) {
try {
$metaentries['hosted']['shib13-idp'] = $metadata->getMetaDataCurrent('shib13-idp-hosted');
- $metaentries['hosted']['shib13-idp']['metadata-url'] = '/' . $config->getBaseURL() .
+ $metaentries['hosted']['shib13-idp']['metadata-url'] = $config->getBasePath() .
'shib13/idp/metadata.php?output=xhtml';
if ($isadmin)
$metaentries['remote']['shib13-sp-remote'] = $metadata->getList('shib13-sp-remote');
diff --git a/modules/core/www/idp/logout-iframe-post.php b/modules/core/www/idp/logout-iframe-post.php
index 061ef97..5a9c4d8 100644
--- a/modules/core/www/idp/logout-iframe-post.php
+++ b/modules/core/www/idp/logout-iframe-post.php
@@ -49,10 +49,10 @@ SimpleSAML_Stats::log('saml:idp:LogoutRequest:sent', array(
'idpEntityID' => $idpMetadata->getString('entityid'),
));
-$bindings = array(SAML2_Const::BINDING_HTTP_POST);
+$bindings = array(\SAML2\Constants::BINDING_HTTP_POST);
$dst = $spMetadata->getDefaultEndpoint('SingleLogoutService', $bindings);
-$binding = SAML2_Binding::getBinding($dst['Binding']);
+$binding = \SAML2\Binding::getBinding($dst['Binding']);
$lr->setDestination($dst['Location']);
$lr->setRelayState($relayState);
diff --git a/modules/core/www/no_cookie.php b/modules/core/www/no_cookie.php
index 36aad7a..46e67a5 100644
--- a/modules/core/www/no_cookie.php
+++ b/modules/core/www/no_cookie.php
@@ -1,10 +1,10 @@
<?php
if (isset($_REQUEST['retryURL'])) {
- $retryURL = (string)$_REQUEST['retryURL'];
- $retryURL = \SimpleSAML\Utils\HTTP::normalizeURL($retryURL);
+ $retryURL = (string) $_REQUEST['retryURL'];
+ $retryURL = \SimpleSAML\Utils\HTTP::checkURLAllowed($retryURL);
} else {
- $retryURL = NULL;
+ $retryURL = null;
}
$globalConfig = SimpleSAML_Configuration::getInstance();
diff --git a/modules/cron/templates/croninfo-tpl.php b/modules/cron/templates/croninfo.tpl.php
index 49aa313..49aa313 100644
--- a/modules/cron/templates/croninfo-tpl.php
+++ b/modules/cron/templates/croninfo.tpl.php
diff --git a/modules/cron/www/croninfo.php b/modules/cron/www/croninfo.php
index 18d1cc9..93b7acb 100644
--- a/modules/cron/www/croninfo.php
+++ b/modules/cron/www/croninfo.php
@@ -36,6 +36,6 @@ foreach ($tags AS $tag) {
-$t = new SimpleSAML_XHTML_Template($config, 'cron:croninfo-tpl.php', 'cron:cron');
+$t = new SimpleSAML_XHTML_Template($config, 'cron:croninfo.tpl.php', 'cron:cron');
$t->data['urls'] = $urls;
$t->show();
diff --git a/modules/discopower/lib/PowerIdPDisco.php b/modules/discopower/lib/PowerIdPDisco.php
index 8fd2d1c..a5b2375 100644
--- a/modules/discopower/lib/PowerIdPDisco.php
+++ b/modules/discopower/lib/PowerIdPDisco.php
@@ -247,7 +247,7 @@ class sspmod_discopower_PowerIdPDisco extends SimpleSAML_XHTML_IdPDisco
$idpList = $this->idplistStructured($this->filterList($idpList));
$preferredIdP = $this->getRecommendedIdP();
- $t = new SimpleSAML_XHTML_Template($this->config, 'discopower:disco-tpl.php', 'disco');
+ $t = new SimpleSAML_XHTML_Template($this->config, 'discopower:disco.tpl.php', 'disco');
$t->data['idplist'] = $idpList;
$t->data['preferredidp'] = $preferredIdP;
$t->data['return'] = $this->returnURL;
diff --git a/modules/discopower/templates/disco-tpl.php b/modules/discopower/templates/disco.tpl.php
index d8059ba..d8059ba 100644
--- a/modules/discopower/templates/disco-tpl.php
+++ b/modules/discopower/templates/disco.tpl.php
diff --git a/modules/exampleattributeserver/www/attributeserver.php b/modules/exampleattributeserver/www/attributeserver.php
index 072d32c..8f257c2 100644
--- a/modules/exampleattributeserver/www/attributeserver.php
+++ b/modules/exampleattributeserver/www/attributeserver.php
@@ -2,9 +2,9 @@
$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-$binding = SAML2_Binding::getCurrentBinding();
+$binding = \SAML2\Binding::getCurrentBinding();
$query = $binding->receive();
-if (!($query instanceof SAML2_AttributeQuery)) {
+if (!($query instanceof \SAML2\AttributeQuery)) {
throw new SimpleSAML_Error_BadRequest('Invalid message received to AttributeQuery endpoint.');
}
@@ -29,7 +29,7 @@ $attributes = array(
);
/* The name format of the attributes. */
-$attributeNameFormat = SAML2_Const::NAMEFORMAT_UNSPECIFIED;
+$attributeNameFormat = \SAML2\Constants::NAMEFORMAT_UNSPECIFIED;
/* Determine which attributes we will return. */
@@ -62,7 +62,7 @@ if (count($returnAttributes) === 0) {
/* $returnAttributes contains the attributes we should return. Send them. */
-$assertion = new SAML2_Assertion();
+$assertion = new \SAML2\Assertion();
$assertion->setIssuer($idpEntityId);
$assertion->setNameId($query->getNameId());
$assertion->setNotBefore(time());
@@ -71,9 +71,9 @@ $assertion->setValidAudiences(array($spEntityId));
$assertion->setAttributes($returnAttributes);
$assertion->setAttributeNameFormat($attributeNameFormat);
-$sc = new SAML2_XML_saml_SubjectConfirmation();
-$sc->Method = SAML2_Const::CM_BEARER;
-$sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData();
+$sc = new \SAML2\XML\saml\SubjectConfirmation();
+$sc->Method = \SAML2\Constants::CM_BEARER;
+$sc->SubjectConfirmationData = new \SAML2\XML\saml\SubjectConfirmationData();
$sc->SubjectConfirmationData->NotOnOrAfter = time() + 5*60;
$sc->SubjectConfirmationData->Recipient = $endpoint;
$sc->SubjectConfirmationData->InResponseTo = $query->getId();
@@ -81,7 +81,7 @@ $assertion->setSubjectConfirmation(array($sc));
sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $assertion);
-$response = new SAML2_Response();
+$response = new \SAML2\Response();
$response->setRelayState($query->getRelayState());
$response->setDestination($endpoint);
$response->setIssuer($idpEntityId);
@@ -89,5 +89,5 @@ $response->setInResponseTo($query->getId());
$response->setAssertions(array($assertion));
sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $response);
-$binding = new SAML2_HTTPPost();
+$binding = new \SAML2\HTTPPost();
$binding->send($response);
diff --git a/modules/expirycheck/docs/expirycheck.txt b/modules/expirycheck/docs/expirycheck.md
index fecf3b6..fecf3b6 100644
--- a/modules/expirycheck/docs/expirycheck.txt
+++ b/modules/expirycheck/docs/expirycheck.md
diff --git a/modules/ldap/docs/ldap.txt b/modules/ldap/docs/ldap.md
index 151db88..cbc9e6f 100644
--- a/modules/ldap/docs/ldap.txt
+++ b/modules/ldap/docs/ldap.md
@@ -436,6 +436,17 @@ a listing of all configuration options and their details.
/**
+ * This is the port where the LDAP server(s) listen for
+ * connections.
+ *
+ * Default: 389
+ * Required: No
+ * AuthSource: port
+ */
+ 'ldap.port' => 389,
+
+
+ /**
* This is the password used to bind to LDAP.
*
* Default: NULL
diff --git a/modules/ldap/lib/Auth/Process/BaseFilter.php b/modules/ldap/lib/Auth/Process/BaseFilter.php
index 3a42de4..3d328e4 100644
--- a/modules/ldap/lib/Auth/Process/BaseFilter.php
+++ b/modules/ldap/lib/Auth/Process/BaseFilter.php
@@ -137,6 +137,7 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
$authconfig = array();
$authconfig['ldap.hostname'] = @$authsource['hostname'];
$authconfig['ldap.enable_tls'] = @$authsource['enable_tls'];
+ $authconfig['ldap.port'] = @$authsource['port'];
$authconfig['ldap.timeout'] = @$authsource['timeout'];
$authconfig['ldap.debug'] = @$authsource['debug'];
$authconfig['ldap.basedn'] = (@$authsource['search.enable'] ? @$authsource['search.base'] : NULL);
diff --git a/modules/memcacheMonitor/dictionaries/memcachestat.definition.json b/modules/memcacheMonitor/dictionaries/memcachestat.definition.json
index 010e48f..5b29d83 100644
--- a/modules/memcacheMonitor/dictionaries/memcachestat.definition.json
+++ b/modules/memcacheMonitor/dictionaries/memcachestat.definition.json
@@ -55,5 +55,56 @@
},
"limit_maxbytes": {
"en": "Total storage avail"
+ },
+ "pointer_size": {
+ "en": "Pointer size (bits)"
+ },
+ "delete_misses": {
+ "en": "Total DELETE commands (failed)"
+ },
+ "delete_hits": {
+ "en": "Total DELETE commands (success)"
+ },
+ "incr_misses": {
+ "en": "Total INCR commands (failed)"
+ },
+ "incr_hits": {
+ "en": "Total INCR commands (success)"
+ },
+ "decr_misses": {
+ "en": "Total DECR commands (failed)"
+ },
+ "decr_hits": {
+ "en": "Total DECR commands (success)"
+ },
+ "cas_misses": {
+ "en": "Total CAS commands (failed)"
+ },
+ "cas_hits": {
+ "en": "Total CAS commands (success)"
+ },
+ "cas_badval": {
+ "en": "Total bad CAS identifiers"
+ },
+ "auth_cmds": {
+ "en": "Total authentication commands processed"
+ },
+ "auth_errors": {
+ "en": "Total authentication commands failed"
+ },
+ "accepting_conns": {
+ "en": "Currently accepting new connections"
+ },
+ "listen_disabled_num": {
+ "en": "Total number of denied connections (connection limit)"
+ },
+ "threads": {
+ "en": "Number of available threads"
+ },
+ "conn_yields": {
+ "en": "Number of times the request limit was reached"
+ },
+ "evictions": {
+ "en": "Number of objects removed from cache (memory limit)"
}
-} \ No newline at end of file
+}
diff --git a/modules/memcacheMonitor/templates/memcachestat.tpl.php b/modules/memcacheMonitor/templates/memcachestat.tpl.php
index dc0a71e..26f1b8d 100644
--- a/modules/memcacheMonitor/templates/memcachestat.tpl.php
+++ b/modules/memcacheMonitor/templates/memcachestat.tpl.php
@@ -1,6 +1,6 @@
<?php
-$this->data['head'] = '<style>
+$this->data['head'] = '<style type="text/css">
table.statustable td, table.statustable th {
border: 1px solid #eee;
padding: 2px 6px;
diff --git a/modules/metarefresh/lib/MetaLoader.php b/modules/metarefresh/lib/MetaLoader.php
index 9538464..a5f0f00 100644
--- a/modules/metarefresh/lib/MetaLoader.php
+++ b/modules/metarefresh/lib/MetaLoader.php
@@ -253,7 +253,7 @@ class sspmod_metarefresh_MetaLoader {
private function loadXML($data, $source) {
$entities = array();
try {
- $doc = SAML2_DOMDocumentFactory::fromString($data);
+ $doc = \SAML2\DOMDocumentFactory::fromString($data);
} catch (Exception $e) {
throw new Exception('Failed to read XML from ' . $source['src']);
}
diff --git a/modules/multiauth/docs/multiauth.txt b/modules/multiauth/docs/multiauth.md
index 914f815..914f815 100644
--- a/modules/multiauth/docs/multiauth.txt
+++ b/modules/multiauth/docs/multiauth.md
diff --git a/modules/multiauth/lib/Auth/Source/MultiAuth.php b/modules/multiauth/lib/Auth/Source/MultiAuth.php
index dc0a95e..f3acc90 100644
--- a/modules/multiauth/lib/Auth/Source/MultiAuth.php
+++ b/modules/multiauth/lib/Auth/Source/MultiAuth.php
@@ -204,7 +204,7 @@ class sspmod_multiauth_Auth_Source_MultiAuth extends SimpleSAML_Auth_Source {
'lifetime' => (60*60*24*90),
/* The base path for cookies.
This should be the installation directory for SimpleSAMLphp. */
- 'path' => ('/' . $config->getBaseUrl()),
+ 'path' => $config->getBasePath(),
'httponly' => FALSE,
);
diff --git a/modules/negotiate/docs/negotiate.txt b/modules/negotiate/docs/negotiate.md
index 62ae6f5..a57044d 100644
--- a/modules/negotiate/docs/negotiate.txt
+++ b/modules/negotiate/docs/negotiate.md
@@ -227,7 +227,7 @@ if($this->data['nego']['disable_perm']) {
echo '<span id="login-extra-info-uio.no" class="login-extra-info">'
. '<span class="login-extra-info-divider"></span>'
. $this->t('{feide:login:login_uio_negotiate_disabled_session_info}')
- . '<br><a href="'.SimpleSAML_Module::getModuleURL('negotiate/retry.php', array('AuthState' => $this->data['nego']['retry_id'])).'">'
+ . '<br><a href="'.SimpleSAML\Module::getModuleURL('negotiate/retry.php', array('AuthState' => $this->data['nego']['retry_id'])).'">'
. $this->t('{feide:login:login_uio_negotiate_disabled_session_info_link}')
. '</a>'
. '</span>';
diff --git a/modules/portal/lib/Portal.php b/modules/portal/lib/Portal.php
index 404041a..72effb6 100644
--- a/modules/portal/lib/Portal.php
+++ b/modules/portal/lib/Portal.php
@@ -38,7 +38,7 @@ class sspmod_portal_Portal {
function getMenu($thispage) {
$config = SimpleSAML_Configuration::getInstance();
- $t = new SimpleSAML_XHTML_Template($config, 'sanitycheck:check-tpl.php');
+ $t = new SimpleSAML_XHTML_Template($config, 'sanitycheck:check.tpl.php');
$tabset = $this->getTabset($thispage);
$logininfo = $this->getLoginInfo($t, $thispage);
$text = '';
@@ -68,4 +68,4 @@ class sspmod_portal_Portal {
}
-} \ No newline at end of file
+}
diff --git a/modules/radius/docs/radius.txt b/modules/radius/docs/radius.md
index ae5e70d..ae5e70d 100644
--- a/modules/radius/docs/radius.txt
+++ b/modules/radius/docs/radius.md
diff --git a/modules/riak/docs/simplesamlphp-riak.txt b/modules/riak/docs/simplesamlphp-riak.md
index c5e13a7..c5e13a7 100644
--- a/modules/riak/docs/simplesamlphp-riak.txt
+++ b/modules/riak/docs/simplesamlphp-riak.md
diff --git a/modules/saml/docs/authproc_expectedauthncontextclassref.txt b/modules/saml/docs/authproc_expectedauthncontextclassref.md
index 82c6e70..82c6e70 100644
--- a/modules/saml/docs/authproc_expectedauthncontextclassref.txt
+++ b/modules/saml/docs/authproc_expectedauthncontextclassref.md
diff --git a/modules/saml/docs/keyrollover.txt b/modules/saml/docs/keyrollover.md
index 46268f2..46268f2 100644
--- a/modules/saml/docs/keyrollover.txt
+++ b/modules/saml/docs/keyrollover.md
diff --git a/modules/saml/docs/nameid.txt b/modules/saml/docs/nameid.md
index 2c71955..2c71955 100644
--- a/modules/saml/docs/nameid.txt
+++ b/modules/saml/docs/nameid.md
diff --git a/modules/saml/docs/nameidattribute.txt b/modules/saml/docs/nameidattribute.md
index 5bc4409..5bc4409 100644
--- a/modules/saml/docs/nameidattribute.txt
+++ b/modules/saml/docs/nameidattribute.md
diff --git a/modules/saml/docs/sp.txt b/modules/saml/docs/sp.md
index 6d40464..8dbe56b 100644
--- a/modules/saml/docs/sp.txt
+++ b/modules/saml/docs/sp.md
@@ -459,9 +459,9 @@ Here we will list some examples for this authentication source.
### Using samlp:Extensions
- $dom = SAML2_DOMDocumentFactory::create();
+ $dom = \SAML2\DOMDocumentFactory::create();
$ce = $dom->createElementNS('http://www.example.com/XFoo', 'xfoo:test', 'Test data!');
- $ext[] = new SAML2_XML_Chunk($ce);
+ $ext[] = new \SAML2\XML\Chunk($ce);
$auth = new SimpleSAML_Auth_Simple('default-sp');
$auth->login(array(
diff --git a/modules/saml/lib/Auth/Process/NameIDAttribute.php b/modules/saml/lib/Auth/Process/NameIDAttribute.php
index ecb72bb..a873540 100644
--- a/modules/saml/lib/Auth/Process/NameIDAttribute.php
+++ b/modules/saml/lib/Auth/Process/NameIDAttribute.php
@@ -118,7 +118,7 @@ class sspmod_saml_Auth_Process_NameIDAttribute extends SimpleSAML_Auth_Processin
$rep['%'] = '%';
if (!isset($rep['Format'])) {
- $rep['Format'] = SAML2_Const::NAMEID_UNSPECIFIED;
+ $rep['Format'] = \SAML2\Constants::NAMEID_UNSPECIFIED;
}
if (!isset($rep['NameQualifier'])) {
$rep['NameQualifier'] = $state['Source']['entityid'];
diff --git a/modules/saml/lib/Auth/Process/PersistentNameID.php b/modules/saml/lib/Auth/Process/PersistentNameID.php
index 7c17d8d..762b613 100644
--- a/modules/saml/lib/Auth/Process/PersistentNameID.php
+++ b/modules/saml/lib/Auth/Process/PersistentNameID.php
@@ -30,7 +30,7 @@ class sspmod_saml_Auth_Process_PersistentNameID extends sspmod_saml_BaseNameIDGe
parent::__construct($config, $reserved);
assert('is_array($config)');
- $this->format = SAML2_Const::NAMEID_PERSISTENT;
+ $this->format = \SAML2\Constants::NAMEID_PERSISTENT;
if (!isset($config['attribute'])) {
throw new SimpleSAML_Error_Exception("PersistentNameID: Missing required option 'attribute'.");
diff --git a/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php b/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php
index 9b94c94..be61e10 100644
--- a/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php
+++ b/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php
@@ -59,20 +59,20 @@ class sspmod_saml_Auth_Process_PersistentNameID2TargetedID extends SimpleSAML_Au
{
assert('is_array($state)');
- if (!isset($state['saml:NameID'][SAML2_Const::NAMEID_PERSISTENT])) {
+ if (!isset($state['saml:NameID'][\SAML2\Constants::NAMEID_PERSISTENT])) {
SimpleSAML\Logger::warning(
'Unable to generate eduPersonTargetedID because no persistent NameID was available.'
);
return;
}
- $nameID = $state['saml:NameID'][SAML2_Const::NAMEID_PERSISTENT];
+ $nameID = $state['saml:NameID'][\SAML2\Constants::NAMEID_PERSISTENT];
if ($this->nameId) {
- $doc = SAML2_DOMDocumentFactory::create();
+ $doc = \SAML2\DOMDocumentFactory::create();
$root = $doc->createElement('root');
$doc->appendChild($root);
- SAML2_Utils::addNameId($root, $nameID);
+ \SAML2\Utils::addNameId($root, $nameID);
$value = $doc->saveXML($root->firstChild);
} else {
$value = $nameID['Value'];
diff --git a/modules/saml/lib/Auth/Process/SQLPersistentNameID.php b/modules/saml/lib/Auth/Process/SQLPersistentNameID.php
index c3e5b4c..28d92f8 100644
--- a/modules/saml/lib/Auth/Process/SQLPersistentNameID.php
+++ b/modules/saml/lib/Auth/Process/SQLPersistentNameID.php
@@ -51,7 +51,7 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI
parent::__construct($config, $reserved);
assert('is_array($config)');
- $this->format = SAML2_Const::NAMEID_PERSISTENT;
+ $this->format = \SAML2\Constants::NAMEID_PERSISTENT;
if (!isset($config['attribute'])) {
throw new SimpleSAML_Error_Exception("PersistentNameID: Missing required option 'attribute'.");
@@ -148,7 +148,7 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI
'SQLPersistentNameID: Did not find persistent NameID for user, and not allowed to create new NameID.'
);
throw new sspmod_saml_Error(
- SAML2_Const::STATUS_RESPONDER,
+ \SAML2\Constants::STATUS_RESPONDER,
'urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy'
);
}
diff --git a/modules/saml/lib/Auth/Process/TransientNameID.php b/modules/saml/lib/Auth/Process/TransientNameID.php
index d3f5c22..f402642 100644
--- a/modules/saml/lib/Auth/Process/TransientNameID.php
+++ b/modules/saml/lib/Auth/Process/TransientNameID.php
@@ -20,7 +20,7 @@ class sspmod_saml_Auth_Process_TransientNameID extends sspmod_saml_BaseNameIDGen
parent::__construct($config, $reserved);
assert('is_array($config)');
- $this->format = SAML2_Const::NAMEID_TRANSIENT;
+ $this->format = \SAML2\Constants::NAMEID_TRANSIENT;
}
diff --git a/modules/saml/lib/Auth/Source/SP.php b/modules/saml/lib/Auth/Source/SP.php
index 1460940..df6058d 100644
--- a/modules/saml/lib/Auth/Source/SP.php
+++ b/modules/saml/lib/Auth/Source/SP.php
@@ -261,19 +261,19 @@ class sspmod_saml_Auth_Source_SP extends SimpleSAML_Auth_Source {
SimpleSAML\Logger::debug('Sending SAML 2 AuthnRequest to ' . var_export($idpMetadata->getString('entityid'), TRUE));
/* Select appropriate SSO endpoint */
- if ($ar->getProtocolBinding() === SAML2_Const::BINDING_HOK_SSO) {
+ if ($ar->getProtocolBinding() === \SAML2\Constants::BINDING_HOK_SSO) {
$dst = $idpMetadata->getDefaultEndpoint('SingleSignOnService', array(
- SAML2_Const::BINDING_HOK_SSO)
+ \SAML2\Constants::BINDING_HOK_SSO)
);
} else {
$dst = $idpMetadata->getDefaultEndpoint('SingleSignOnService', array(
- SAML2_Const::BINDING_HTTP_REDIRECT,
- SAML2_Const::BINDING_HTTP_POST)
+ \SAML2\Constants::BINDING_HTTP_REDIRECT,
+ \SAML2\Constants::BINDING_HTTP_POST)
);
}
$ar->setDestination($dst['Location']);
- $b = SAML2_Binding::getBinding($dst['Binding']);
+ $b = \SAML2\Binding::getBinding($dst['Binding']);
$this->sendSAML2AuthnRequest($state, $b, $ar);
@@ -287,10 +287,10 @@ class sspmod_saml_Auth_Source_SP extends SimpleSAML_Auth_Source {
* This function does not return.
*
* @param array &$state The state array.
- * @param SAML2_Binding $binding The binding.
- * @param SAML2_AuthnRequest $ar The authentication request.
+ * @param \SAML2\Binding $binding The binding.
+ * @param \SAML2\AuthnRequest $ar The authentication request.
*/
- public function sendSAML2AuthnRequest(array &$state, SAML2_Binding $binding, SAML2_AuthnRequest $ar) {
+ public function sendSAML2AuthnRequest(array &$state, \SAML2\Binding $binding, \SAML2\AuthnRequest $ar) {
$binding->send($ar);
assert('FALSE');
}
@@ -468,8 +468,8 @@ class sspmod_saml_Auth_Source_SP extends SimpleSAML_Auth_Source {
$idpMetadata = $this->getIdPMetadata($idp);
$endpoint = $idpMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(
- SAML2_Const::BINDING_HTTP_REDIRECT,
- SAML2_Const::BINDING_HTTP_POST), FALSE);
+ \SAML2\Constants::BINDING_HTTP_REDIRECT,
+ \SAML2\Constants::BINDING_HTTP_POST), FALSE);
if ($endpoint === FALSE) {
SimpleSAML\Logger::info('No logout endpoint for IdP ' . var_export($idp, TRUE) . '.');
return;
@@ -489,7 +489,7 @@ class sspmod_saml_Auth_Source_SP extends SimpleSAML_Auth_Source {
$lr->encryptNameId(sspmod_saml_Message::getEncryptionKey($idpMetadata));
}
- $b = SAML2_Binding::getBinding($endpoint['Binding']);
+ $b = \SAML2\Binding::getBinding($endpoint['Binding']);
$b->send($lr);
assert('FALSE');
diff --git a/modules/saml/lib/Error.php b/modules/saml/lib/Error.php
index 2b6c919..78799a2 100644
--- a/modules/saml/lib/Error.php
+++ b/modules/saml/lib/Error.php
@@ -106,22 +106,22 @@ class sspmod_saml_Error extends SimpleSAML_Error_Exception {
} elseif ($exception instanceof SimpleSAML_Error_NoPassive) {
$e = new self(
- SAML2_Const::STATUS_RESPONDER,
- SAML2_Const::STATUS_NO_PASSIVE,
+ \SAML2\Constants::STATUS_RESPONDER,
+ \SAML2\Constants::STATUS_NO_PASSIVE,
$exception->getMessage(),
$exception
);
} elseif ($exception instanceof SimpleSAML_Error_ProxyCountExceeded) {
$e = new self(
- SAML2_Const::STATUS_RESPONDER,
- SAML2_Const::STATUS_PROXY_COUNT_EXCEEDED,
+ \SAML2\Constants::STATUS_RESPONDER,
+ \SAML2\Constants::STATUS_PROXY_COUNT_EXCEEDED,
$exception->getMessage(),
$exception
);
} else {
$e = new self(
- SAML2_Const::STATUS_RESPONDER,
+ \SAML2\Constants::STATUS_RESPONDER,
NULL,
get_class($exception) . ': ' . $exception->getMessage(),
$exception
@@ -154,9 +154,9 @@ class sspmod_saml_Error extends SimpleSAML_Error_Exception {
$e = NULL;
switch ($this->status) {
- case SAML2_Const::STATUS_RESPONDER:
+ case \SAML2\Constants::STATUS_RESPONDER:
switch ($this->subStatus) {
- case SAML2_Const::STATUS_NO_PASSIVE:
+ case \SAML2\Constants::STATUS_NO_PASSIVE:
$e = new SimpleSAML_Error_NoPassive($this->statusMessage, 0, $this);
break;
}
diff --git a/modules/saml/lib/IdP/SAML2.php b/modules/saml/lib/IdP/SAML2.php
index 7af8d84..d614a3f 100644
--- a/modules/saml/lib/IdP/SAML2.php
+++ b/modules/saml/lib/IdP/SAML2.php
@@ -74,7 +74,7 @@ class sspmod_saml_IdP_SAML2 {
SimpleSAML_Stats::log('saml:idp:Response', $statsData);
/* Send the response. */
- $binding = SAML2_Binding::getBinding($protocolBinding);
+ $binding = \SAML2\Binding::getBinding($protocolBinding);
$binding->send($ar);
}
@@ -132,7 +132,7 @@ class sspmod_saml_IdP_SAML2 {
}
SimpleSAML_Stats::log('saml:idp:Response:error', $statsData);
- $binding = SAML2_Binding::getBinding($protocolBinding);
+ $binding = \SAML2\Binding::getBinding($protocolBinding);
$binding->send($ar);
}
@@ -229,12 +229,12 @@ class sspmod_saml_IdP_SAML2 {
$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
$idpMetadata = $idp->getConfig();
- $supportedBindings = array(SAML2_Const::BINDING_HTTP_POST);
+ $supportedBindings = array(\SAML2\Constants::BINDING_HTTP_POST);
if ($idpMetadata->getBoolean('saml20.sendartifact', FALSE)) {
- $supportedBindings[] = SAML2_Const::BINDING_HTTP_ARTIFACT;
+ $supportedBindings[] = \SAML2\Constants::BINDING_HTTP_ARTIFACT;
}
if ($idpMetadata->getBoolean('saml20.hok.assertion', FALSE)) {
- $supportedBindings[] = SAML2_Const::BINDING_HOK_SSO;
+ $supportedBindings[] = \SAML2\Constants::BINDING_HOK_SSO;
}
if (isset($_REQUEST['spentityid'])) {
@@ -289,10 +289,10 @@ class sspmod_saml_IdP_SAML2 {
} else {
- $binding = SAML2_Binding::getCurrentBinding();
+ $binding = \SAML2\Binding::getCurrentBinding();
$request = $binding->receive();
- if (!($request instanceof SAML2_AuthnRequest)) {
+ if (!($request instanceof \SAML2\AuthnRequest)) {
throw new SimpleSAML_Error_BadRequest('Message received on authentication request endpoint wasn\'t an authentication request.');
}
@@ -412,10 +412,10 @@ class sspmod_saml_IdP_SAML2 {
));
$dst = $spMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(
- SAML2_Const::BINDING_HTTP_REDIRECT,
- SAML2_Const::BINDING_HTTP_POST)
+ \SAML2\Constants::BINDING_HTTP_REDIRECT,
+ \SAML2\Constants::BINDING_HTTP_POST)
);
- $binding = SAML2_Binding::getBinding($dst['Binding']);
+ $binding = \SAML2\Binding::getBinding($dst['Binding']);
$lr = self::buildLogoutRequest($idpMetadata, $spMetadata, $association, $relayState);
$lr->setDestination($dst['Location']);
@@ -447,8 +447,8 @@ class sspmod_saml_IdP_SAML2 {
if (isset($state['core:Failed']) && $state['core:Failed']) {
$partial = TRUE;
$lr->setStatus(array(
- 'Code' => SAML2_Const::STATUS_SUCCESS,
- 'SubCode' => SAML2_Const::STATUS_PARTIAL_LOGOUT,
+ 'Code' => \SAML2\Constants::STATUS_SUCCESS,
+ 'SubCode' => \SAML2\Constants::STATUS_PARTIAL_LOGOUT,
));
SimpleSAML\Logger::info('Sending logout response for partial logout to SP ' . var_export($spEntityId, TRUE));
} else {
@@ -462,10 +462,10 @@ class sspmod_saml_IdP_SAML2 {
'partial' => $partial
));
$dst = $spMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(
- SAML2_Const::BINDING_HTTP_REDIRECT,
- SAML2_Const::BINDING_HTTP_POST)
+ \SAML2\Constants::BINDING_HTTP_REDIRECT,
+ \SAML2\Constants::BINDING_HTTP_POST)
);
- $binding = SAML2_Binding::getBinding($dst['Binding']);
+ $binding = \SAML2\Binding::getBinding($dst['Binding']);
if (isset($dst['ResponseLocation'])) {
$dst = $dst['ResponseLocation'];
} else {
@@ -484,7 +484,7 @@ class sspmod_saml_IdP_SAML2 {
*/
public static function receiveLogoutMessage(SimpleSAML_IdP $idp) {
- $binding = SAML2_Binding::getCurrentBinding();
+ $binding = \SAML2\Binding::getCurrentBinding();
$message = $binding->receive();
$spEntityId = $message->getIssuer();
@@ -499,7 +499,7 @@ class sspmod_saml_IdP_SAML2 {
sspmod_saml_Message::validateMessage($spMetadata, $idpMetadata, $message);
- if ($message instanceof SAML2_LogoutResponse) {
+ if ($message instanceof \SAML2\LogoutResponse) {
SimpleSAML\Logger::info('Received SAML 2.0 LogoutResponse from: '. var_export($spEntityId, TRUE));
$statsData = array(
@@ -525,7 +525,7 @@ class sspmod_saml_IdP_SAML2 {
$idp->handleLogoutResponse($assocId, $relayState, $logoutError);
- } elseif ($message instanceof SAML2_LogoutRequest) {
+ } elseif ($message instanceof \SAML2\LogoutRequest) {
SimpleSAML\Logger::info('Received SAML 2.0 LogoutRequest from: '. var_export($spEntityId, TRUE));
SimpleSAML_Stats::log('saml:idp:LogoutRequest:recv', array(
@@ -569,11 +569,11 @@ class sspmod_saml_IdP_SAML2 {
$idpMetadata = $idp->getConfig();
$spMetadata = $metadata->getMetaDataConfig($association['saml:entityID'], 'saml20-sp-remote');
- $bindings = array(SAML2_Const::BINDING_HTTP_REDIRECT,
- SAML2_Const::BINDING_HTTP_POST);
+ $bindings = array(\SAML2\Constants::BINDING_HTTP_REDIRECT,
+ \SAML2\Constants::BINDING_HTTP_POST);
$dst = $spMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', $bindings);
- if ($dst['Binding'] === SAML2_Const::BINDING_HTTP_POST) {
+ if ($dst['Binding'] === \SAML2\Constants::BINDING_HTTP_POST) {
$params = array('association' => $association['id'], 'idp' => $idp->getId());
if ($relayState !== NULL) {
$params['RelayState'] = $relayState;
@@ -584,7 +584,7 @@ class sspmod_saml_IdP_SAML2 {
$lr = self::buildLogoutRequest($idpMetadata, $spMetadata, $association, $relayState);
$lr->setDestination($dst['Location']);
- $binding = new SAML2_HTTPRedirect();
+ $binding = new \SAML2\HTTPRedirect();
return $binding->getRedirectURL($lr);
}
@@ -707,7 +707,7 @@ class sspmod_saml_IdP_SAML2 {
break;
case 'raw':
if (is_string($value)) {
- $doc = SAML2_DOMDocumentFactory::fromString('<root>' . $value . '</root>');
+ $doc = \SAML2\DOMDocumentFactory::fromString('<root>' . $value . '</root>');
$value = $doc->firstChild->childNodes;
}
assert('$value instanceof DOMNodeList');
@@ -765,7 +765,7 @@ class sspmod_saml_IdP_SAML2 {
* @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP.
* @param SimpleSAML_Configuration $spMetadata The metadata of the SP.
* @param array &$state The state array with information about the request.
- * @return SAML2_Assertion The assertion.
+ * @return \SAML2\Assertion The assertion.
*/
private static function buildAssertion(SimpleSAML_Configuration $idpMetadata,
SimpleSAML_Configuration $spMetadata, array &$state) {
@@ -781,7 +781,7 @@ class sspmod_saml_IdP_SAML2 {
$config = SimpleSAML_Configuration::getInstance();
- $a = new SAML2_Assertion();
+ $a = new \SAML2\Assertion();
if ($signAssertion) {
sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $a);
}
@@ -800,7 +800,7 @@ class sspmod_saml_IdP_SAML2 {
if (isset($state['saml:AuthnContextClassRef'])) {
$a->setAuthnContext($state['saml:AuthnContextClassRef']);
} else {
- $a->setAuthnContext(SAML2_Const::AC_PASSWORD);
+ $a->setAuthnContext(\SAML2\Constants::AC_PASSWORD);
}
$sessionStart = $now;
@@ -814,15 +814,15 @@ class sspmod_saml_IdP_SAML2 {
$a->setSessionIndex(SimpleSAML\Utils\Random::generateID());
- $sc = new SAML2_XML_saml_SubjectConfirmation();
- $sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData();
+ $sc = new \SAML2\XML\saml\SubjectConfirmation();
+ $sc->SubjectConfirmationData = new \SAML2\XML\saml\SubjectConfirmationData();
$sc->SubjectConfirmationData->NotOnOrAfter = $now + $assertionLifetime;
$sc->SubjectConfirmationData->Recipient = $state['saml:ConsumerURL'];
$sc->SubjectConfirmationData->InResponseTo = $state['saml:RequestId'];
/* ProtcolBinding of SP's <AuthnRequest> overwrites IdP hosted metadata configuration. */
$hokAssertion = NULL;
- if ($state['saml:Binding'] === SAML2_Const::BINDING_HOK_SSO) {
+ if ($state['saml:Binding'] === \SAML2\Constants::BINDING_HOK_SSO) {
$hokAssertion = TRUE;
}
if ($hokAssertion === NULL) {
@@ -831,7 +831,7 @@ class sspmod_saml_IdP_SAML2 {
if ($hokAssertion) {
/* Holder-of-Key */
- $sc->Method = SAML2_Const::CM_HOK;
+ $sc->Method = \SAML2\Constants::CM_HOK;
if (\SimpleSAML\Utils\HTTP::isHTTPS()) {
if (isset($_SERVER['SSL_CLIENT_CERT']) && !empty($_SERVER['SSL_CLIENT_CERT'])) {
/* Extract certificate data (if this is a certificate). */
@@ -839,13 +839,13 @@ class sspmod_saml_IdP_SAML2 {
$pattern = '/^-----BEGIN CERTIFICATE-----([^-]*)^-----END CERTIFICATE-----/m';
if (preg_match($pattern, $clientCert, $matches)) {
/* We have a client certificate from the browser which we add to the HoK assertion. */
- $x509Certificate = new SAML2_XML_ds_X509Certificate();
+ $x509Certificate = new \SAML2\XML\ds\X509Certificate();
$x509Certificate->certificate = str_replace(array("\r", "\n", " "), '', $matches[1]);
- $x509Data = new SAML2_XML_ds_X509Data();
+ $x509Data = new \SAML2\XML\ds\X509Data();
$x509Data->data[] = $x509Certificate;
- $keyInfo = new SAML2_XML_ds_KeyInfo();
+ $keyInfo = new \SAML2\XML\ds\KeyInfo();
$keyInfo->info[] = $x509Data;
$sc->SubjectConfirmationData->info[] = $keyInfo;
@@ -854,7 +854,7 @@ class sspmod_saml_IdP_SAML2 {
} else throw new SimpleSAML_Error_Exception('Error creating HoK assertion: No HTTPS connection to IdP, but required for Holder-of-Key SSO');
} else {
/* Bearer */
- $sc->Method = SAML2_Const::CM_BEARER;
+ $sc->Method = \SAML2\Constants::CM_BEARER;
}
$a->setSubjectConfirmation(array($sc));
@@ -880,7 +880,7 @@ class sspmod_saml_IdP_SAML2 {
/* Either not set in request, or not set to a format we supply. Fall back to old generation method. */
$nameIdFormat = $spMetadata->getString('NameIDFormat', NULL);
if ($nameIdFormat === NULL) {
- $nameIdFormat = $idpMetadata->getString('NameIDFormat', SAML2_Const::NAMEID_TRANSIENT);
+ $nameIdFormat = $idpMetadata->getString('NameIDFormat', \SAML2\Constants::NAMEID_TRANSIENT);
}
}
@@ -893,7 +893,7 @@ class sspmod_saml_IdP_SAML2 {
$spNameQualifier = $spMetadata->getString('entityid');
}
- if ($nameIdFormat === SAML2_Const::NAMEID_TRANSIENT) {
+ if ($nameIdFormat === \SAML2\Constants::NAMEID_TRANSIENT) {
/* generate a random id */
$nameIdValue = SimpleSAML\Utils\Random::generateID();
} else {
@@ -902,7 +902,7 @@ class sspmod_saml_IdP_SAML2 {
$nameIdValue = self::generateNameIdValue($idpMetadata, $spMetadata, $state);
if ($nameIdValue === NULL) {
SimpleSAML\Logger::warning('Falling back to transient NameID.');
- $nameIdFormat = SAML2_Const::NAMEID_TRANSIENT;
+ $nameIdFormat = \SAML2\Constants::NAMEID_TRANSIENT;
$nameIdValue = SimpleSAML\Utils\Random::generateID();
}
}
@@ -933,16 +933,16 @@ class sspmod_saml_IdP_SAML2 {
/**
* Encrypt an assertion.
*
- * This function takes in a SAML2_Assertion and encrypts it if encryption of
+ * This function takes in a \SAML2\Assertion and encrypts it if encryption of
* assertions are enabled in the metadata.
*
* @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP.
* @param SimpleSAML_Configuration $spMetadata The metadata of the SP.
- * @param SAML2_Assertion $assertion The assertion we are encrypting.
- * @return SAML2_Assertion|SAML2_EncryptedAssertion The assertion.
+ * @param \SAML2\Assertion $assertion The assertion we are encrypting.
+ * @return \SAML2\Assertion|\SAML2\EncryptedAssertion The assertion.
*/
private static function encryptAssertion(SimpleSAML_Configuration $idpMetadata,
- SimpleSAML_Configuration $spMetadata, SAML2_Assertion $assertion) {
+ SimpleSAML_Configuration $spMetadata, \SAML2\Assertion $assertion) {
$encryptAssertion = $spMetadata->getBoolean('assertion.encryption', NULL);
if ($encryptAssertion === NULL) {
@@ -976,7 +976,7 @@ class sspmod_saml_IdP_SAML2 {
$key->loadKey($pemKey);
}
- $ea = new SAML2_EncryptedAssertion();
+ $ea = new \SAML2\EncryptedAssertion();
$ea->setAssertion($assertion, $key);
return $ea;
}
@@ -1031,7 +1031,7 @@ class sspmod_saml_IdP_SAML2 {
$signResponse = $idpMetadata->getBoolean('saml20.sign.response', TRUE);
}
- $r = new SAML2_Response();
+ $r = new \SAML2\Response();
$r->setIssuer($idpMetadata->getString('entityid'));
$r->setDestination($consumerURL);
diff --git a/modules/saml/lib/Message.php b/modules/saml/lib/Message.php
index 685be4f..60fea0e 100644
--- a/modules/saml/lib/Message.php
+++ b/modules/saml/lib/Message.php
@@ -14,9 +14,9 @@ class sspmod_saml_Message {
*
* @param SimpleSAML_Configuration $srcMetadata The metadata of the sender.
* @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient.
- * @param SAML2_Message $element The element we should add the data to.
+ * @param \SAML2\Message $element The element we should add the data to.
*/
- public static function addSign(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata, SAML2_SignedElement $element) {
+ public static function addSign(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata, \SAML2\SignedElement $element) {
$dstPrivateKey = $dstMetadata->getString('signature.privatekey', NULL);
@@ -70,16 +70,16 @@ class sspmod_saml_Message {
*
* @param SimpleSAML_Configuration $srcMetadata The metadata of the sender.
* @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient.
- * @param SAML2_Message $message The message we should add the data to.
+ * @param \SAML2\Message $message The message we should add the data to.
*/
- private static function addRedirectSign(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata, SAML2_message $message) {
+ private static function addRedirectSign(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata, \SAML2\Message $message) {
- if ($message instanceof SAML2_LogoutRequest || $message instanceof SAML2_LogoutResponse) {
+ if ($message instanceof \SAML2\LogoutRequest || $message instanceof \SAML2\LogoutResponse) {
$signingEnabled = $srcMetadata->getBoolean('sign.logout', NULL);
if ($signingEnabled === NULL) {
$signingEnabled = $dstMetadata->getBoolean('sign.logout', NULL);
}
- } elseif ($message instanceof SAML2_AuthnRequest) {
+ } elseif ($message instanceof \SAML2\AuthnRequest) {
$signingEnabled = $srcMetadata->getBoolean('sign.authnrequest', NULL);
if ($signingEnabled === NULL) {
$signingEnabled = $dstMetadata->getBoolean('sign.authnrequest', NULL);
@@ -138,9 +138,9 @@ class sspmod_saml_Message {
* Check the signature on a SAML2 message or assertion.
*
* @param SimpleSAML_Configuration $srcMetadata The metadata of the sender.
- * @param SAML2_SignedElement $element Either a SAML2_Response or a SAML2_Assertion.
+ * @param \SAML2\SignedElement $element Either a \SAML2\Response or a \SAML2\Assertion.
*/
- public static function checkSign(SimpleSAML_Configuration $srcMetadata, SAML2_SignedElement $element) {
+ public static function checkSign(SimpleSAML_Configuration $srcMetadata, \SAML2\SignedElement $element) {
/* Find the public key that should verify signatures by this entity. */
$keys = $srcMetadata->getPublicKeys('signing');
@@ -224,20 +224,20 @@ class sspmod_saml_Message {
*
* @param SimpleSAML_Configuration $srcMetadata The metadata of the sender.
* @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient.
- * @param SAML2_Message $message The message we should check the signature on.
+ * @param \SAML2\Message $message The message we should check the signature on.
*/
public static function validateMessage(
SimpleSAML_Configuration $srcMetadata,
SimpleSAML_Configuration $dstMetadata,
- SAML2_Message $message
+ \SAML2\Message $message
) {
- if ($message instanceof SAML2_LogoutRequest || $message instanceof SAML2_LogoutResponse) {
+ if ($message instanceof \SAML2\LogoutRequest || $message instanceof \SAML2\LogoutResponse) {
$enabled = $srcMetadata->getBoolean('validate.logout', NULL);
if ($enabled === NULL) {
$enabled = $dstMetadata->getBoolean('validate.logout', NULL);
}
- } elseif ($message instanceof SAML2_AuthnRequest) {
+ } elseif ($message instanceof \SAML2\AuthnRequest) {
$enabled = $srcMetadata->getBoolean('validate.authnrequest', NULL);
if ($enabled === NULL) {
$enabled = $dstMetadata->getBoolean('validate.authnrequest', NULL);
@@ -331,20 +331,20 @@ class sspmod_saml_Message {
/**
* Decrypt an assertion.
*
- * This function takes in a SAML2_Assertion and decrypts it if it is encrypted.
+ * This function takes in a \SAML2\Assertion and decrypts it if it is encrypted.
* If it is unencrypted, and encryption is enabled in the metadata, an exception
* will be throws.
*
* @param SimpleSAML_Configuration $srcMetadata The metadata of the sender (IdP).
* @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient (SP).
- * @param SAML2_Assertion|SAML2_EncryptedAssertion $assertion The assertion we are decrypting.
- * @return SAML2_Assertion The assertion.
+ * @param \SAML2\Assertion|\SAML2\EncryptedAssertion $assertion The assertion we are decrypting.
+ * @return \SAML2\Assertion The assertion.
*/
private static function decryptAssertion(SimpleSAML_Configuration $srcMetadata,
SimpleSAML_Configuration $dstMetadata, $assertion) {
- assert('$assertion instanceof SAML2_Assertion || $assertion instanceof SAML2_EncryptedAssertion');
+ assert('$assertion instanceof \SAML2\Assertion || $assertion instanceof \SAML2\EncryptedAssertion');
- if ($assertion instanceof SAML2_Assertion) {
+ if ($assertion instanceof \SAML2\Assertion) {
$encryptAssertion = $srcMetadata->getBoolean('assertion.encryption', NULL);
if ($encryptAssertion === NULL) {
$encryptAssertion = $dstMetadata->getBoolean('assertion.encryption', FALSE);
@@ -383,10 +383,10 @@ class sspmod_saml_Message {
/**
* Retrieve the status code of a response as a sspmod_saml_Error.
*
- * @param SAML2_StatusResponse $response The response.
+ * @param \SAML2\StatusResponse $response The response.
* @return sspmod_saml_Error The error.
*/
- public static function getResponseError(SAML2_StatusResponse $response) {
+ public static function getResponseError(\SAML2\StatusResponse $response) {
$status = $response->getStatus();
return new sspmod_saml_Error($status['Code'], $status['SubCode'], $status['Message']);
@@ -401,7 +401,7 @@ class sspmod_saml_Message {
*/
public static function buildAuthnRequest(SimpleSAML_Configuration $spMetadata, SimpleSAML_Configuration $idpMetadata) {
- $ar = new SAML2_AuthnRequest();
+ $ar = new \SAML2\AuthnRequest();
// get the NameIDPolicy to apply. IdP metadata has precedence.
$nameIdPolicy = array();
@@ -418,7 +418,7 @@ class sspmod_saml_Message {
$nameIdPolicy_cf = SimpleSAML_Configuration::loadFromArray($nameIdPolicy);
$policy = array(
- 'Format' => $nameIdPolicy_cf->getString('Format', SAML2_Const::NAMEID_TRANSIENT),
+ 'Format' => $nameIdPolicy_cf->getString('Format', \SAML2\Constants::NAMEID_TRANSIENT),
'AllowCreate' => $nameIdPolicy_cf->getBoolean('AllowCreate', true),
);
$spNameQualifier = $nameIdPolicy_cf->getString('SPNameQualifier', false);
@@ -431,11 +431,11 @@ class sspmod_saml_Message {
$ar->setIsPassive($spMetadata->getBoolean('IsPassive', FALSE));
$protbind = $spMetadata->getValueValidate('ProtocolBinding', array(
- SAML2_Const::BINDING_HTTP_POST,
- SAML2_Const::BINDING_HOK_SSO,
- SAML2_Const::BINDING_HTTP_ARTIFACT,
- SAML2_Const::BINDING_HTTP_REDIRECT,
- ), SAML2_Const::BINDING_HTTP_POST);
+ \SAML2\Constants::BINDING_HTTP_POST,
+ \SAML2\Constants::BINDING_HOK_SSO,
+ \SAML2\Constants::BINDING_HTTP_ARTIFACT,
+ \SAML2\Constants::BINDING_HTTP_REDIRECT,
+ ), \SAML2\Constants::BINDING_HTTP_POST);
/* Shoaib - setting the appropriate binding based on parameter in sp-metadata defaults to HTTP_POST */
$ar->setProtocolBinding($protbind);
@@ -464,7 +464,7 @@ class sspmod_saml_Message {
*/
public static function buildLogoutRequest(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata) {
- $lr = new SAML2_LogoutRequest();
+ $lr = new \SAML2\LogoutRequest();
$lr->setIssuer($srcMetadata->getString('entityid'));
self::addRedirectSign($srcMetadata, $dstMetadata, $lr);
@@ -481,7 +481,7 @@ class sspmod_saml_Message {
*/
public static function buildLogoutResponse(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata) {
- $lr = new SAML2_LogoutResponse();
+ $lr = new \SAML2\LogoutResponse();
$lr->setIssuer($srcMetadata->getString('entityid'));
self::addRedirectSign($srcMetadata, $dstMetadata, $lr);
@@ -498,12 +498,12 @@ class sspmod_saml_Message {
*
* @param SimpleSAML_Configuration $spMetadata The metadata of the service provider.
* @param SimpleSAML_Configuration $idpMetadata The metadata of the identity provider.
- * @param SAML2_Response $response The response.
- * @return array Array with SAML2_Assertion objects, containing valid assertions from the response.
+ * @param \SAML2\Response $response The response.
+ * @return array Array with \SAML2\Assertion objects, containing valid assertions from the response.
*/
public static function processResponse(
SimpleSAML_Configuration $spMetadata, SimpleSAML_Configuration $idpMetadata,
- SAML2_Response $response
+ \SAML2\Response $response
) {
if (!$response->isSuccess()) {
@@ -546,16 +546,16 @@ class sspmod_saml_Message {
*
* @param SimpleSAML_Configuration $spMetadata The metadata of the service provider.
* @param SimpleSAML_Configuration $idpMetadata The metadata of the identity provider.
- * @param SAML2_Response $response The response containing the assertion.
- * @param SAML2_Assertion|SAML2_EncryptedAssertion $assertion The assertion.
+ * @param \SAML2\Response $response The response containing the assertion.
+ * @param \SAML2\Assertion|\SAML2\EncryptedAssertion $assertion The assertion.
* @param bool $responseSigned Whether the response is signed.
- * @return SAML2_Assertion The assertion, if it is valid.
+ * @return \SAML2\Assertion The assertion, if it is valid.
*/
private static function processAssertion(
SimpleSAML_Configuration $spMetadata, SimpleSAML_Configuration $idpMetadata,
- SAML2_Response $response, $assertion, $responseSigned
+ \SAML2\Response $response, $assertion, $responseSigned
) {
- assert('$assertion instanceof SAML2_Assertion || $assertion instanceof SAML2_EncryptedAssertion');
+ assert('$assertion instanceof \SAML2\Assertion || $assertion instanceof \SAML2\EncryptedAssertion');
assert('is_bool($responseSigned)');
$assertion = self::decryptAssertion($idpMetadata, $spMetadata, $assertion);
@@ -598,7 +598,7 @@ class sspmod_saml_Message {
$found = FALSE;
$lastError = 'No SubjectConfirmation element in Subject.';
- $validSCMethods = array(SAML2_Const::CM_BEARER, SAML2_Const::CM_HOK, SAML2_Const::CM_VOUCHES);
+ $validSCMethods = array(\SAML2\Constants::CM_BEARER, \SAML2\Constants::CM_HOK, \SAML2\Constants::CM_VOUCHES);
foreach ($assertion->getSubjectConfirmation() as $sc) {
if (!in_array($sc->Method, $validSCMethods)) {
$lastError = 'Invalid Method on SubjectConfirmation: ' . var_export($sc->Method, TRUE);
@@ -610,17 +610,17 @@ class sspmod_saml_Message {
if ($hok === NULL) {
$hok = $spMetadata->getBoolean('saml20.hok.assertion', FALSE);
}
- if ($sc->Method === SAML2_Const::CM_BEARER && $hok) {
+ if ($sc->Method === \SAML2\Constants::CM_BEARER && $hok) {
$lastError = 'Bearer SubjectConfirmation received, but Holder-of-Key SubjectConfirmation needed';
continue;
}
- if ($sc->Method === SAML2_Const::CM_HOK && !$hok) {
+ if ($sc->Method === \SAML2\Constants::CM_HOK && !$hok) {
$lastError = 'Holder-of-Key SubjectConfirmation received, but the Holder-of-Key profile is not enabled.';
continue;
}
$scd = $sc->SubjectConfirmationData;
- if ($sc->Method === SAML2_Const::CM_HOK) {
+ if ($sc->Method === \SAML2\Constants::CM_HOK) {
/* Check HoK Assertion */
if (\SimpleSAML\Utils\HTTP::isHTTPS() === FALSE) {
$lastError = 'No HTTPS connection, but required for Holder-of-Key SSO';
@@ -642,7 +642,7 @@ class sspmod_saml_Message {
$clientCert = str_replace(array("\r", "\n", " "), '', $matches[1]);
foreach ($scd->info as $thing) {
- if($thing instanceof SAML2_XML_ds_KeyInfo) {
+ if($thing instanceof \SAML2\XML\ds\KeyInfo) {
$keyInfo[]=$thing;
}
}
@@ -652,7 +652,7 @@ class sspmod_saml_Message {
}
foreach ($keyInfo[0]->info as $thing) {
- if($thing instanceof SAML2_XML_ds_X509Data) {
+ if($thing instanceof \SAML2\XML\ds\X509Data) {
$x509data[]=$thing;
}
}
@@ -662,7 +662,7 @@ class sspmod_saml_Message {
}
foreach ($x509data[0]->data as $thing) {
- if($thing instanceof SAML2_XML_ds_X509Certificate) {
+ if($thing instanceof \SAML2\XML\ds\X509Certificate) {
$x509cert[]=$thing;
}
}
diff --git a/modules/saml/www/sp/metadata.php b/modules/saml/www/sp/metadata.php
index 90a8b7b..3adf70d 100644
--- a/modules/saml/www/sp/metadata.php
+++ b/modules/saml/www/sp/metadata.php
@@ -26,15 +26,15 @@ $store = SimpleSAML_Store::getInstance();
$metaArray20 = array();
$slosvcdefault = array(
- SAML2_Const::BINDING_HTTP_REDIRECT,
- SAML2_Const::BINDING_SOAP,
+ \SAML2\Constants::BINDING_HTTP_REDIRECT,
+ \SAML2\Constants::BINDING_SOAP,
);
$slob = $spconfig->getArray('SingleLogoutServiceBinding', $slosvcdefault);
$slol = SimpleSAML\Module::getModuleURL('saml/sp/saml2-logout.php/'.$sourceId);
foreach ($slob as $binding) {
- if ($binding == SAML2_Const::BINDING_SOAP && !($store instanceof SimpleSAML_Store_SQL)) {
+ if ($binding == \SAML2\Constants::BINDING_SOAP && !($store instanceof SimpleSAML_Store_SQL)) {
// we cannot properly support SOAP logout
continue;
}
@@ -64,7 +64,7 @@ foreach ($assertionsconsumerservices as $services) {
$acsArray = array('index' => $index);
switch ($services) {
case 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST':
- $acsArray['Binding'] = SAML2_Const::BINDING_HTTP_POST;
+ $acsArray['Binding'] = \SAML2\Constants::BINDING_HTTP_POST;
$acsArray['Location'] = SimpleSAML\Module::getModuleURL('saml/sp/saml2-acs.php/'.$sourceId);
break;
case 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post':
@@ -82,7 +82,7 @@ foreach ($assertionsconsumerservices as $services) {
case 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser':
$acsArray['Binding'] = 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser';
$acsArray['Location'] = SimpleSAML\Module::getModuleURL('saml/sp/saml2-acs.php/'.$sourceId);
- $acsArray['hoksso:ProtocolBinding'] = SAML2_Const::BINDING_HTTP_REDIRECT;
+ $acsArray['hoksso:ProtocolBinding'] = \SAML2\Constants::BINDING_HTTP_REDIRECT;
break;
}
$eps[] = $acsArray;
@@ -214,7 +214,7 @@ if ($spconfig->hasValue('redirect.sign')) {
$metaArray20['validate.authnrequest'] = $spconfig->getBoolean('sign.authnrequest');
}
-$supported_protocols = array('urn:oasis:names:tc:SAML:1.1:protocol', SAML2_Const::NS_SAMLP);
+$supported_protocols = array('urn:oasis:names:tc:SAML:1.1:protocol', \SAML2\Constants::NS_SAMLP);
$metaArray20['metadata-set'] = 'saml20-sp-remote';
$metaArray20['entityid'] = $entityId;
diff --git a/modules/saml/www/sp/saml2-acs.php b/modules/saml/www/sp/saml2-acs.php
index 611ea0b..264a544 100644
--- a/modules/saml/www/sp/saml2-acs.php
+++ b/modules/saml/www/sp/saml2-acs.php
@@ -13,9 +13,9 @@ $source = SimpleSAML_Auth_Source::getById($sourceId, 'sspmod_saml_Auth_Source_SP
$spMetadata = $source->getMetadata();
try {
- $b = SAML2_Binding::getCurrentBinding();
+ $b = \SAML2\Binding::getCurrentBinding();
} catch (Exception $e) { // TODO: look for a specific exception
- // This is dirty. Instead of checking the message of the exception, SAML2_Binding::getCurrentBinding() should throw
+ // This is dirty. Instead of checking the message of the exception, \SAML2\Binding::getCurrentBinding() should throw
// an specific exception when the binding is unknown, and we should capture that here
if ($e->getMessage() === 'Unable to find the current binding.') {
throw new SimpleSAML_Error_Error('ACSPARAMS', $e, 400);
@@ -24,12 +24,12 @@ try {
}
}
-if ($b instanceof SAML2_HTTPArtifact) {
+if ($b instanceof \SAML2\HTTPArtifact) {
$b->setSPMetadata($spMetadata);
}
$response = $b->receive();
-if (!($response instanceof SAML2_Response)) {
+if (!($response instanceof \SAML2\Response)) {
throw new SimpleSAML_Error_BadRequest('Invalid message received to AssertionConsumerService endpoint.');
}
@@ -37,7 +37,7 @@ $idp = $response->getIssuer();
if ($idp === null) {
// no Issuer in the response. Look for an unencrypted assertion with an issuer
foreach ($response->getAssertions() as $a) {
- if ($a instanceof SAML2_Assertion) {
+ if ($a instanceof \SAML2\Assertion) {
// we found an unencrypted assertion, there should be an issuer here
$idp = $a->getIssuer();
break;
diff --git a/modules/saml/www/sp/saml2-logout.php b/modules/saml/www/sp/saml2-logout.php
index 5b1fb71..6fa5a00 100644
--- a/modules/saml/www/sp/saml2-logout.php
+++ b/modules/saml/www/sp/saml2-logout.php
@@ -21,9 +21,9 @@ if (!($source instanceof sspmod_saml_Auth_Source_SP)) {
}
try {
- $binding = SAML2_Binding::getCurrentBinding();
+ $binding = \SAML2\Binding::getCurrentBinding();
} catch (Exception $e) { // TODO: look for a specific exception
- // This is dirty. Instead of checking the message of the exception, SAML2_Binding::getCurrentBinding() should throw
+ // This is dirty. Instead of checking the message of the exception, \SAML2\Binding::getCurrentBinding() should throw
// an specific exception when the binding is unknown, and we should capture that here
if ($e->getMessage() === 'Unable to find the current binding.') {
throw new SimpleSAML_Error_Error('SLOSERVICEPARAMS', $e, 400);
@@ -52,7 +52,7 @@ if ($destination !== NULL && $destination !== \SimpleSAML\Utils\HTTP::getSelfURL
throw new SimpleSAML_Error_Exception('Destination in logout message is wrong.');
}
-if ($message instanceof SAML2_LogoutResponse) {
+if ($message instanceof \SAML2\LogoutResponse) {
$relayState = $message->getRelayState();
if ($relayState === NULL) {
@@ -68,7 +68,7 @@ if ($message instanceof SAML2_LogoutResponse) {
$state['saml:sp:LogoutStatus'] = $message->getStatus();
SimpleSAML_Auth_Source::completeLogout($state);
-} elseif ($message instanceof SAML2_LogoutRequest) {
+} elseif ($message instanceof \SAML2\LogoutRequest) {
SimpleSAML\Logger::debug('module/saml2/sp/logout: Request from ' . $idpEntityId);
SimpleSAML\Logger::stats('saml20-idp-SLO idpinit ' . $spEntityId . ' ' . $idpEntityId);
@@ -119,12 +119,12 @@ if ($message instanceof SAML2_LogoutResponse) {
}
$dst = $idpMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(
- SAML2_Const::BINDING_HTTP_REDIRECT,
- SAML2_Const::BINDING_HTTP_POST)
+ \SAML2\Constants::BINDING_HTTP_REDIRECT,
+ \SAML2\Constants::BINDING_HTTP_POST)
);
- if (!$binding instanceof SAML2_SOAP) {
- $binding = SAML2_Binding::getBinding($dst['Binding']);
+ if (!$binding instanceof \SAML2\SOAP) {
+ $binding = \SAML2\Binding::getBinding($dst['Binding']);
if (isset($dst['ResponseLocation'])) {
$dst = $dst['ResponseLocation'];
} else {
diff --git a/modules/sanitycheck/templates/check-tpl.php b/modules/sanitycheck/templates/check.tpl.php
index cf34bff..cf34bff 100644
--- a/modules/sanitycheck/templates/check-tpl.php
+++ b/modules/sanitycheck/templates/check.tpl.php
diff --git a/modules/sanitycheck/www/index.php b/modules/sanitycheck/www/index.php
index c740c21..708348b 100644
--- a/modules/sanitycheck/www/index.php
+++ b/modules/sanitycheck/www/index.php
@@ -22,7 +22,7 @@ if (isset($_REQUEST['output']) && $_REQUEST['output'] == 'text') {
exit;
}
-$t = new SimpleSAML_XHTML_Template($config, 'sanitycheck:check-tpl.php');
+$t = new SimpleSAML_XHTML_Template($config, 'sanitycheck:check.tpl.php');
$t->data['pageid'] = 'sanitycheck';
$t->data['errors'] = $errors;
$t->data['info'] = $info;
diff --git a/modules/smartattributes/docs/smartattributes.txt b/modules/smartattributes/docs/smartattributes.md
index 0c2c8c1..0c2c8c1 100644
--- a/modules/smartattributes/docs/smartattributes.txt
+++ b/modules/smartattributes/docs/smartattributes.md
diff --git a/modules/sqlauth/docs/sql.txt b/modules/sqlauth/docs/sql.md
index 3fb3381..3fb3381 100644
--- a/modules/sqlauth/docs/sql.txt
+++ b/modules/sqlauth/docs/sql.md
diff --git a/modules/statistics/docs/statistics.txt b/modules/statistics/docs/statistics.md
index 07d7e40..07d7e40 100644
--- a/modules/statistics/docs/statistics.txt
+++ b/modules/statistics/docs/statistics.md
diff --git a/modules/statistics/lib/StatDataset.php b/modules/statistics/lib/StatDataset.php
index 1d64130..1c40671 100644
--- a/modules/statistics/lib/StatDataset.php
+++ b/modules/statistics/lib/StatDataset.php
@@ -251,7 +251,7 @@ class sspmod_statistics_StatDataset
public function getDelimiterPresentation()
{
$config = SimpleSAML_Configuration::getInstance();
- $t = new SimpleSAML_XHTML_Template($config, 'statistics:statistics-tpl.php');
+ $t = new SimpleSAML_XHTML_Template($config, 'statistics:statistics.tpl.php');
$availdelimiters = $this->availDelimiters();
diff --git a/modules/statistics/templates/statistics-tpl.php b/modules/statistics/templates/statistics.tpl.php
index 1efa682..1efa682 100644
--- a/modules/statistics/templates/statistics-tpl.php
+++ b/modules/statistics/templates/statistics.tpl.php
diff --git a/modules/statistics/templates/statmeta-tpl.php b/modules/statistics/templates/statmeta.tpl.php
index 1ad37d3..1ad37d3 100644
--- a/modules/statistics/templates/statmeta-tpl.php
+++ b/modules/statistics/templates/statmeta.tpl.php
diff --git a/modules/statistics/www/showstats.php b/modules/statistics/www/showstats.php
index ed4c443..d15edc7 100644
--- a/modules/statistics/www/showstats.php
+++ b/modules/statistics/www/showstats.php
@@ -96,7 +96,7 @@ if (array_key_exists('output', $_REQUEST) && $_REQUEST['output'] === 'csv') {
-$t = new SimpleSAML_XHTML_Template($config, 'statistics:statistics-tpl.php');
+$t = new SimpleSAML_XHTML_Template($config, 'statistics:statistics.tpl.php');
$t->data['pageid'] = 'statistics';
$t->data['header'] = 'stat';
$t->data['imgurl'] = $grapher->show($axis['axis'], $axis['axispos'], $datasets, $maxes);
diff --git a/modules/statistics/www/statmeta.php b/modules/statistics/www/statmeta.php
index 46c5ddb..4b8a9d0 100644
--- a/modules/statistics/www/statmeta.php
+++ b/modules/statistics/www/statmeta.php
@@ -10,7 +10,7 @@ $aggr->loadMetadata();
$metadata = $aggr->getMetadata();
-$t = new SimpleSAML_XHTML_Template($config, 'statistics:statmeta-tpl.php');
+$t = new SimpleSAML_XHTML_Template($config, 'statistics:statmeta.tpl.php');
$t->data['metadata'] = $metadata;
$t->show();
diff --git a/templates/_footer.twig.html b/templates/_footer.twig.html
new file mode 100644
index 0000000..c1edf52
--- /dev/null
+++ b/templates/_footer.twig.html
@@ -0,0 +1,6 @@
+ <hr>
+
+ <img src="/{{ baseurlpath }}resources/icons/ssplogo-fish-small.png" alt="Small fish logo" style="float: right">
+ Copyright © 2007-2015 <a href="http://uninett.no/">UNINETT AS</a>
+
+ <br style="clear: right">
diff --git a/templates/_header.twig.html b/templates/_header.twig.html
new file mode 100644
index 0000000..ad52152
--- /dev/null
+++ b/templates/_header.twig.html
@@ -0,0 +1,14 @@
+<div id="header">
+ <h1><a style="text-decoration: none; color: white" href="/{{ baseurlpath }}">{{ pagetitle }}</a></h1>
+</div>
+
+{% if not hideLanguageBar %}
+<div id="languagebar">
+ {% for lang in languageBar %}
+
+ {%- if not loop.first -%} | {%- endif -%}{% if lang.url %}<a href="{{ lang.url }}">{{ lang.name }}</a>{% else %}{{ lang.name }}{% endif %}
+
+ {% endfor %}
+
+</div>
+{% endif %}
diff --git a/templates/base.twig.html b/templates/base.twig.html
new file mode 100644
index 0000000..ad30a63
--- /dev/null
+++ b/templates/base.twig.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0">
+ <script type="text/javascript" src="/{{ baseurlpath }}resources/script.js"></script>
+ <title>{{ pagetitle }}</title>
+ <link rel="stylesheet" type="text/css" href="/{{ baseurlpath }}resources/default.css">
+ <link rel="icon" type="image/icon" href="/{{ baseurlpath }}resources/icons/favicon.ico">
+ <link rel="stylesheet" media="screen" type="text/css" href="/{{ baseurlpath }}resources/uitheme1.8/jquery-ui.css">
+ {% if isRTL %}<link rel="stylesheet" type="text/css" href="/{{ baseurlpath }}resources/default-rtl.css" />{% endif %}
+ <meta name="robots" content="noindex, nofollow">
+ {% block preload %}{% endblock %}
+</head>
+<body>
+ <div id="wrap">
+
+ {% block header %}{% include "_header.twig.html" %}{% endblock %}
+
+ <div id="content">
+ {% block content %}{% endblock %}
+ </div><!-- #content -->
+
+ <div id="footer">
+ {% block footer %}{% include "_footer.twig.html" %}{% endblock %}
+ </div>
+
+ </div><!-- #wrap -->
+
+ {% block postload %}{% endblock %}
+</body></html>
diff --git a/templates/includes/attributes.php b/templates/includes/attributes.php
index 48eb0cc..4067420 100644
--- a/templates/includes/attributes.php
+++ b/templates/includes/attributes.php
@@ -71,6 +71,33 @@ function present_attributes(SimpleSAML_XHTML_Template $t, $attributes, $namePare
$str .= '</td>';
if ($nameraw === 'jpegPhoto') {
$str .= '<td class="attrvalue"><img src="data:image/jpeg;base64,' . htmlspecialchars($value[0]) . '" /></td></tr>';
+ } elseif (is_a($value[0], 'DOMNodeList')) {
+ // try to see if we have a NameID here
+ $n = $value[0]->length;
+ for ($idx = 0; $idx < $n; $idx++) {
+ $elem = $value[0]->item($idx);
+ /* @var DOMElement $elem */
+ if (!($elem->localName === 'NameID' && $elem->namespaceURI === \SAML2\Constants::NS_SAML)) {
+ continue;
+ }
+ $nameID = new \SAML2\XML\saml\NameID($elem);
+ $eptid = array(
+ 'NameID' => array($nameID->value),
+ );
+ if (!empty($nameID->Format)) {
+ $eptid['Format'] = array($nameID->Format);
+ }
+ if (!empty($nameID->NameQualifier)) {
+ $eptid['NameQualifier'] = array($nameID->NameQualifier);
+ }
+ if (!empty($nameID->SPNameQualifier)) {
+ $eptid['SPNameQualifier'] = array($nameID->SPNameQualifier);
+ }
+ $str .= '<td class="attrvalue">';
+ $str .= present_assoc($eptid);
+ break; // we only support one NameID here
+ }
+ $str .= '</td></tr>';
} else {
$str .= '<td class="attrvalue">' . htmlspecialchars($value[0]) . '</td></tr>';
}
diff --git a/templates/index.twig.html b/templates/index.twig.html
new file mode 100644
index 0000000..c888934
--- /dev/null
+++ b/templates/index.twig.html
@@ -0,0 +1,33 @@
+{% extends "base.twig.html" %}
+{% block content %}
+ <div id="portalmenu" class="ui-tabs ui-widget ui-widget-content ui-corner-all">
+ <ul class="tabset_tabs ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all">
+ <li class="ui-state-default ui-corner-top"><a href="http://simplesaml.arrakis.uninett.no/simplesaml/module.php/core/frontpage_welcome.php">Welcome</a></li>
+ <li class="ui-state-default ui-corner-top ui-tabs-selected ui-state-active"><a href="#">Configuration</a></li>
+ <li class="ui-state-default ui-corner-top"><a href="http://simplesaml.arrakis.uninett.no/simplesaml/module.php/core/frontpage_auth.php">Authentication</a></li>
+ <li class="ui-state-default ui-corner-top"><a href="http://simplesaml.arrakis.uninett.no/simplesaml/module.php/core/frontpage_federation.php">Federation</a></li>
+ </ul>
+ <div id="portalcontent" class="ui-tabs-panel ui-widget-content ui-corner-bottom">
+
+ <div style="clear: both" class="enablebox mini">
+ <table>
+
+ <tr class="disabled"><td>SAML 2.0 IdP</td>
+ <td><img src="/{{ baseurlpath }}resources/icons/silk/delete.png" alt="disabled" /></td></tr>
+
+ <tr class="disabled"><td>Shib 1.3 IdP</td>
+ <td><img src="/{{ baseurlpath }}resources/icons/silk/delete.png" alt="disabled" /></td></tr>
+
+ </table>
+ </div>
+ <h2>Configuration</h2>
+ <ul>
+ {% for url, page in adminpages %}
+ <li>
+ <a href="{{ url }}">{{ page }}</a>
+ </li>
+ {% endfor %}
+ </ul>
+ </div>
+ </div>
+{% endblock content %}
diff --git a/templates/sandbox.twig.html b/templates/sandbox.twig.html
new file mode 100644
index 0000000..e37201e
--- /dev/null
+++ b/templates/sandbox.twig.html
@@ -0,0 +1,6 @@
+{% extends "base.twig.html" %}
+{% block content %}
+ <p>This page exists as a sandbox to play with twig without affecting anything else. The template is in ./templates.</p>
+ <p>{{ sometext }}</p>
+ <p>Current locale set: {{ currentLanguage }}</p>
+{% endblock content %}
diff --git a/templates/selectidp-dropdown.php b/templates/selectidp-dropdown.php
index b9c3b73..ebe7646 100644
--- a/templates/selectidp-dropdown.php
+++ b/templates/selectidp-dropdown.php
@@ -33,10 +33,21 @@ foreach ($this->data['idplist'] as $idpentry) {
value="<?php echo htmlspecialchars($this->data['returnIDParam']); ?>"/>
<select id="dropdownlist" name="idpentityid">
<?php
+ /*
+ * TODO: change this to use $this instead when PHP 5.4 is the minimum requirement.
+ *
+ * This is a dirty hack because PHP 5.3 does not allow the use of $this inside closures. Therefore, the
+ * translation function must be passed somehow inside the closure. PHP 5.4 allows using $this, so we can
+ * then go back to the previous behaviour.
+ */
+ $GLOBALS['__t'] = $this;
usort($this->data['idplist'], function ($idpentry1, $idpentry2) {
- // TODO: this is only compatible with PHP >= 5.4, fix compat with 5.3!
- return strcmp($this->t('idpname_'.$idpentry1['entityid']), $this->t('idpname_'.$idpentry2['entityid']));
+ return strcmp(
+ $GLOBALS['__t']->t('idpname_'.$idpentry1['entityid']),
+ $GLOBALS['__t']->t('idpname_'.$idpentry2['entityid'])
+ );
});
+ unset($GLOBALS['__t']);
foreach ($this->data['idplist'] as $idpentry) {
echo '<option value="'.htmlspecialchars($idpentry['entityid']).'"';
diff --git a/tests/BuiltInServer.php b/tests/BuiltInServer.php
new file mode 100644
index 0000000..4f614f5
--- /dev/null
+++ b/tests/BuiltInServer.php
@@ -0,0 +1,201 @@
+<?php
+/**
+ * An extremely simple class to start and stop PHP's built-in server, with the possibility to specify the document
+ * root and the "router" file to run for every request.
+ *
+ * @author Jaime Pérez Crespo <jaime.perez@uninett.no>
+ * @package SimpleSAMLphp
+ */
+
+namespace SimpleSAML\Test;
+
+
+class BuiltInServer
+{
+
+ /**
+ * The PID of the running server.
+ *
+ * @var int
+ */
+ protected $pid = 0;
+
+ /**
+ * The address (host:port) where the server is listening for connections after being started.
+ *
+ * @var string
+ */
+ protected $address;
+
+ /**
+ * The name of a "router" file to run for every request performed to this server.
+ *
+ * @var string
+ */
+ protected $router = '';
+
+ /**
+ * The document root of the server.
+ *
+ * @var string
+ */
+ protected $docroot;
+
+
+ /**
+ * BuiltInServer constructor.
+ *
+ * @param string|null $router The name of a "router" file to run first for every request performed to this server.
+ * @param string|null $docroot The document root to use when starting the server.
+ *
+ * @see http://php.net/manual/en/features.commandline.webserver.php
+ */
+ public function __construct($router = null, $docroot = null)
+ {
+ if (!is_null($router)) {
+ $this->setRouter($router);
+ }
+
+ if (!is_null($docroot)) {
+ $this->docroot = $docroot;
+ } else {
+ $this->docroot = dirname(dirname(__FILE__)).'/www/';
+ }
+ }
+
+
+ /**
+ * Start the built-in server in a random port.
+ *
+ * This method will wait up to 5 seconds for the server to start. When it returns an address, it is guaranteed that
+ * the server has started and is listening for connections. If it returns false on the other hand, there will be no
+ * guarantee that the server started properly.
+ *
+ * @return string The address where the server is listening for connections, or false if the server failed to start
+ * for some reason.
+ *
+ * @todo This method should be resilient to clashes in the randomly-picked port number.
+ */
+ public function start()
+ {
+ $port = mt_rand(1025, 65535);
+ $this->address = 'localhost:'.$port;
+
+ $command = sprintf(
+ 'php -S %s -t %s %s >> /dev/null 2>&1 & echo $!',
+ $this->address,
+ $this->docroot,
+ $this->router
+ );
+
+ // execute the command and store the process ID
+ $output = array();
+ exec($command, $output);
+ $this->pid = (int) $output[0];
+
+ // wait until it's listening for connections to avoid race conditions
+ $start = microtime(true);
+ while (($sock = @fsockopen('localhost', $port, $errno, $errstr, 10)) === false) {
+ // set a 5 secs timeout waiting for the server to start
+ if (microtime(true) > $start + 5) {
+ $this->pid = false; // signal failure
+ $this->address = false;
+ break;
+ }
+ }
+ if ($sock !== false) {
+ fclose($sock);
+ }
+
+ return $this->address;
+ }
+
+
+ /**
+ * Stop the built-in server.
+ */
+ public function stop()
+ {
+ if ($this->pid === 0) {
+ return;
+ }
+ exec('kill '.$this->pid);
+ $this->pid = 0;
+ }
+
+
+ /**
+ * Get the PID of the running server.
+ *
+ * @return int The PID of the server, or 0 if the server was not started.
+ */
+ public function getPid()
+ {
+ return $this->pid;
+ }
+
+
+ /**
+ * Get the name of the "router" file.
+ *
+ * @return string The name of the "router" file.
+ */
+ public function getRouter()
+ {
+ return $this->router;
+ }
+
+
+ /**
+ * Set the "router" file.
+ *
+ * @param string $router The name of a "router" file to use when starting the server.
+ */
+ public function setRouter($router)
+ {
+ $file = dirname(dirname(__FILE__)).'/tests/routers/'.$router.'.php';
+ if (!file_exists($file)) {
+ throw new \InvalidArgumentException('Unknown router "'.$router.'".');
+ }
+ $this->router = $file;
+ }
+
+
+ /**
+ * This function performs an HTTP GET request to the built-in server.
+ *
+ * @param string $query The query to perform.
+ * @param array $parameters An array (can be empty) with parameters for the requested URI.
+ * @param array $curlopts An array (can be empty) with options for cURL.
+ *
+ * @return array|string The response obtained from the built-in server.
+ */
+ public function get($query, $parameters, $curlopts = array())
+ {
+ $ch = curl_init();
+ $url = 'http://'.$this->address.$query;
+ $url .= (!empty($parameters)) ? '?'.http_build_query($parameters) : '';
+ curl_setopt_array($ch, array(
+ CURLOPT_URL => $url,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_HEADER => 1,
+ ));
+ curl_setopt_array($ch, $curlopts);
+ $resp = curl_exec($ch);
+ $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ list($header, $body) = explode("\r\n\r\n", $resp, 2);
+ $raw_headers = explode("\r\n", $header);
+ array_shift($raw_headers);
+ $headers = array();
+ foreach ($raw_headers as $header) {
+ list($name, $value) = explode(':', $header, 2);
+ $headers[trim($name)] = trim($value);
+ }
+ curl_close($ch);
+ return array(
+ 'code' => $code,
+ 'headers' => $headers,
+ 'body' => $body,
+ );
+ }
+}
diff --git a/tests/lib/SimpleSAML/ConfigurationTest.php b/tests/lib/SimpleSAML/ConfigurationTest.php
index 076b8b0..129f658 100644
--- a/tests/lib/SimpleSAML/ConfigurationTest.php
+++ b/tests/lib/SimpleSAML/ConfigurationTest.php
@@ -40,17 +40,17 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
*/
public function testGetValue() {
$c = SimpleSAML_Configuration::loadFromArray(array(
- 'exists_true' => TRUE,
- 'exists_null' => NULL,
+ 'exists_true' => true,
+ 'exists_null' => null,
));
- $this->assertEquals($c->getValue('missing'), NULL);
- $this->assertEquals($c->getValue('missing', TRUE), TRUE);
- $this->assertEquals($c->getValue('missing', TRUE), TRUE);
+ $this->assertEquals($c->getValue('missing'), null);
+ $this->assertEquals($c->getValue('missing', true), true);
+ $this->assertEquals($c->getValue('missing', true), true);
- $this->assertEquals($c->getValue('exists_true'), TRUE);
+ $this->assertEquals($c->getValue('exists_true'), true);
- $this->assertEquals($c->getValue('exists_null'), NULL);
- $this->assertEquals($c->getValue('exists_null', FALSE), NULL);
+ $this->assertEquals($c->getValue('exists_null'), null);
+ $this->assertEquals($c->getValue('exists_null', false), null);
}
/**
@@ -67,12 +67,12 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
*/
public function testHasValue() {
$c = SimpleSAML_Configuration::loadFromArray(array(
- 'exists_true' => TRUE,
- 'exists_null' => NULL,
+ 'exists_true' => true,
+ 'exists_null' => null,
));
- $this->assertEquals($c->hasValue('missing'), FALSE);
- $this->assertEquals($c->hasValue('exists_true'), TRUE);
- $this->assertEquals($c->hasValue('exists_null'), TRUE);
+ $this->assertEquals($c->hasValue('missing'), false);
+ $this->assertEquals($c->hasValue('exists_true'), true);
+ $this->assertEquals($c->hasValue('exists_null'), true);
}
/**
@@ -80,17 +80,17 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
*/
public function testHasValueOneOf() {
$c = SimpleSAML_Configuration::loadFromArray(array(
- 'exists_true' => TRUE,
- 'exists_null' => NULL,
+ 'exists_true' => true,
+ 'exists_null' => null,
));
- $this->assertEquals($c->hasValueOneOf(array()), FALSE);
- $this->assertEquals($c->hasValueOneOf(array('missing')), FALSE);
- $this->assertEquals($c->hasValueOneOf(array('exists_true')), TRUE);
- $this->assertEquals($c->hasValueOneOf(array('exists_null')), TRUE);
+ $this->assertEquals($c->hasValueOneOf(array()), false);
+ $this->assertEquals($c->hasValueOneOf(array('missing')), false);
+ $this->assertEquals($c->hasValueOneOf(array('exists_true')), true);
+ $this->assertEquals($c->hasValueOneOf(array('exists_null')), true);
- $this->assertEquals($c->hasValueOneOf(array('missing1', 'missing2')), FALSE);
- $this->assertEquals($c->hasValueOneOf(array('exists_true', 'missing')), TRUE);
- $this->assertEquals($c->hasValueOneOf(array('missing', 'exists_true')), TRUE);
+ $this->assertEquals($c->hasValueOneOf(array('missing1', 'missing2')), false);
+ $this->assertEquals($c->hasValueOneOf(array('exists_true', 'missing')), true);
+ $this->assertEquals($c->hasValueOneOf(array('missing', 'exists_true')), true);
}
/**
@@ -100,61 +100,91 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
$c = SimpleSAML_Configuration::loadFromArray(array());
$this->assertEquals($c->getBaseURL(), 'simplesaml/');
- $c = SimpleSAML_Configuration::loadFromArray(array(
- 'baseurlpath' => 'simplesaml/',
- ));
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'simplesaml/'));
$this->assertEquals($c->getBaseURL(), 'simplesaml/');
- $c = SimpleSAML_Configuration::loadFromArray(array(
- 'baseurlpath' => '/simplesaml/',
- ));
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/simplesaml/'));
$this->assertEquals($c->getBaseURL(), 'simplesaml/');
- $c = SimpleSAML_Configuration::loadFromArray(array(
- 'baseurlpath' => 'path/to/simplesaml/',
- ));
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'path/to/simplesaml/'));
$this->assertEquals($c->getBaseURL(), 'path/to/simplesaml/');
- $c = SimpleSAML_Configuration::loadFromArray(array(
- 'baseurlpath' => '/path/to/simplesaml/',
- ));
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/path/to/simplesaml/'));
$this->assertEquals($c->getBaseURL(), 'path/to/simplesaml/');
- $c = SimpleSAML_Configuration::loadFromArray(array(
- 'baseurlpath' => 'https://example.org/ssp/',
- ));
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'https://example.org/ssp/'));
$this->assertEquals($c->getBaseURL(), 'ssp/');
- $c = SimpleSAML_Configuration::loadFromArray(array(
- 'baseurlpath' => 'https://example.org/',
- ));
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'https://example.org/'));
$this->assertEquals($c->getBaseURL(), '');
- $c = SimpleSAML_Configuration::loadFromArray(array(
- 'baseurlpath' => 'http://example.org/ssp/',
- ));
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'http://example.org/ssp/'));
$this->assertEquals($c->getBaseURL(), 'ssp/');
- $c = SimpleSAML_Configuration::loadFromArray(array(
- 'baseurlpath' => '',
- ));
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => ''));
$this->assertEquals($c->getBaseURL(), '');
- $c = SimpleSAML_Configuration::loadFromArray(array(
- 'baseurlpath' => '/',
- ));
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/'));
$this->assertEquals($c->getBaseURL(), '');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'simplesaml'));
+ $this->assertEquals($c->getBaseURL(), 'simplesaml/');
}
/**
- * Test that SimpleSAML_Configuration::getBaseURL() fails if given a path without trailing slash
- * @expectedException \SimpleSAML\Error\CriticalConfigurationError
+ * Test SimpleSAML_Configuration::getBasePath()
*/
- public function testGetBaseURLError() {
- $c = SimpleSAML_Configuration::loadFromArray(array(
- 'baseurlpath' => 'simplesaml',
- ));
- $c->getBaseURL();
+ public function testGetBasePath() {
+ $c = SimpleSAML_Configuration::loadFromArray(array());
+ $this->assertEquals($c->getBasePath(), '/simplesaml/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'simplesaml/'));
+ $this->assertEquals($c->getBasePath(), '/simplesaml/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/simplesaml/'));
+ $this->assertEquals($c->getBasePath(), '/simplesaml/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'simplesaml'));
+ $this->assertEquals($c->getBasePath(), '/simplesaml/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/simplesaml'));
+ $this->assertEquals($c->getBasePath(), '/simplesaml/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'path/to/simplesaml/'));
+ $this->assertEquals($c->getBasePath(), '/path/to/simplesaml/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/path/to/simplesaml/'));
+ $this->assertEquals($c->getBasePath(), '/path/to/simplesaml/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/path/to/simplesaml'));
+ $this->assertEquals($c->getBasePath(), '/path/to/simplesaml/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'https://example.org/ssp/'));
+ $this->assertEquals($c->getBasePath(), '/ssp/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'https://example.org/'));
+ $this->assertEquals($c->getBasePath(), '/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'http://example.org/ssp/'));
+ $this->assertEquals($c->getBasePath(), '/ssp/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'http://example.org/ssp/simplesaml'));
+ $this->assertEquals($c->getBasePath(), '/ssp/simplesaml/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'http://example.org/ssp/simplesaml/'));
+ $this->assertEquals($c->getBasePath(), '/ssp/simplesaml/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => ''));
+ $this->assertEquals($c->getBasePath(), '/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/'));
+ $this->assertEquals($c->getBasePath(), '/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'https://example.org:8443'));
+ $this->assertEquals($c->getBasePath(), '/');
+
+ $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'https://example.org:8443/'));
+ $this->assertEquals($c->getBasePath(), '/');
}
/**
@@ -165,7 +195,7 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
'basedir' => '/basedir/',
));
- $this->assertEquals($c->resolvePath(NULL), NULL);
+ $this->assertEquals($c->resolvePath(null), null);
$this->assertEquals($c->resolvePath('/otherdir'), '/otherdir');
$this->assertEquals($c->resolvePath('relativedir'), '/basedir/relativedir');
@@ -183,7 +213,7 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
'slashes_opt' => 'slashes//',
));
- $this->assertEquals($c->getPathValue('missing'), NULL);
+ $this->assertEquals($c->getPathValue('missing'), null);
$this->assertEquals($c->getPathValue('path_opt'), '/basedir/path/');
$this->assertEquals($c->getPathValue('slashes_opt'), '/basedir/slashes/');
}
@@ -211,12 +241,12 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
*/
public function testGetBoolean() {
$c = SimpleSAML_Configuration::loadFromArray(array(
- 'true_opt' => TRUE,
- 'false_opt' => FALSE,
+ 'true_opt' => true,
+ 'false_opt' => false,
));
$this->assertEquals($c->getBoolean('missing_opt', '--missing--'), '--missing--');
- $this->assertEquals($c->getBoolean('true_opt', '--missing--'), TRUE);
- $this->assertEquals($c->getBoolean('false_opt', '--missing--'), FALSE);
+ $this->assertEquals($c->getBoolean('true_opt', '--missing--'), true);
+ $this->assertEquals($c->getBoolean('false_opt', '--missing--'), false);
}
/**
@@ -265,7 +295,7 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
*/
public function testGetStringWrong() {
$c = SimpleSAML_Configuration::loadFromArray(array(
- 'wrong' => FALSE,
+ 'wrong' => false,
));
$c->getString('wrong');
}
@@ -494,8 +524,8 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
*/
public function testGetOptions() {
$c = SimpleSAML_Configuration::loadFromArray(array(
- 'a' => TRUE,
- 'b' => NULL,
+ 'a' => true,
+ 'b' => null,
));
$this->assertEquals($c->getOptions(), array('a', 'b'));
}
@@ -505,10 +535,10 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
*/
public function testToArray() {
$c = SimpleSAML_Configuration::loadFromArray(array(
- 'a' => TRUE,
- 'b' => NULL,
+ 'a' => true,
+ 'b' => null,
));
- $this->assertEquals($c->toArray(), array('a' => TRUE, 'b' => NULL));
+ $this->assertEquals($c->toArray(), array('a' => true, 'b' => null));
}
@@ -536,14 +566,14 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
array(
array(
'Location' => 'https://example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_POST,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_POST,
),
),
// define the ResponseLocation too
array(
array(
'Location' => 'https://example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_POST,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_POST,
'ResponseLocation' => 'https://example.com/endpoint.php',
),
),
@@ -552,12 +582,12 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
array(
'index' => 1,
'Location' => 'https://www1.example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT,
),
array(
'index' => 2,
'Location' => 'https://www2.example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_POST,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_POST,
),
),
// make sure isDefault has priority over indexes
@@ -565,13 +595,13 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
array(
'index' => 1,
'Location' => 'https://www2.example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_POST,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_POST,
),
array(
'index' => 2,
'isDefault' => true,
'Location' => 'https://www1.example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT,
),
),
// make sure endpoints with invalid bindings are ignored and those marked as NOT default are still used
@@ -585,7 +615,7 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
'index' => 2,
'isDefault' => false,
'Location' => 'https://www2.example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_POST,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_POST,
),
),
);
@@ -593,34 +623,34 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
// output should be completed with the default binding (HTTP-POST for ACS)
array(
'Location' => 'https://example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_POST,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_POST,
),
// we should just get the first endpoint with the default binding
array(
'Location' => 'https://www1.example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_POST,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_POST,
),
// if we specify the binding, we should get it back
array(
'Location' => 'https://example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_POST
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_POST
),
// if we specify ResponseLocation, we should get it back too
array(
'Location' => 'https://example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_POST,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_POST,
'ResponseLocation' => 'https://example.com/endpoint.php',
),
// indexes must NOT be taken into account, order is the only thing that matters here
array(
'Location' => 'https://www1.example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT,
'index' => 1,
),
// isDefault must have higher priority than indexes
array(
'Location' => 'https://www1.example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT,
'isDefault' => true,
'index' => 2,
),
@@ -629,7 +659,7 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
'index' => 2,
'isDefault' => false,
'Location' => 'https://www2.example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_POST,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_POST,
)
);
@@ -644,11 +674,11 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
);
$valid_bindings = array(
- SAML2_Const::BINDING_HTTP_POST,
- SAML2_Const::BINDING_HTTP_REDIRECT,
- SAML2_Const::BINDING_HOK_SSO,
- SAML2_Const::BINDING_HTTP_ARTIFACT.
- SAML2_Const::BINDING_SOAP,
+ \SAML2\Constants::BINDING_HTTP_POST,
+ \SAML2\Constants::BINDING_HTTP_REDIRECT,
+ \SAML2\Constants::BINDING_HOK_SSO,
+ \SAML2\Constants::BINDING_HTTP_ARTIFACT.
+ \SAML2\Constants::BINDING_SOAP,
);
// run all general tests with AssertionConsumerService endpoint type
@@ -676,14 +706,14 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
$this->assertEquals(
array(
'Location' => 'https://example.com/ars',
- 'Binding' => SAML2_Const::BINDING_SOAP,
+ 'Binding' => \SAML2\Constants::BINDING_SOAP,
),
$c->getDefaultEndpoint('ArtifactResolutionService')
);
$this->assertEquals(
array(
'Location' => 'https://example.com/slo',
- 'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT,
),
$c->getDefaultEndpoint('SingleLogoutService')
);
@@ -743,7 +773,7 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
$e = array(
array(
'Location' => 'https://example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT,
'ResponseLocation' => 'https://example.com/response.php',
)
);
@@ -794,7 +824,7 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
array(
array(
'Location' => 'https://example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT,
'ResponseLocation' => 1234,
),
),
@@ -802,7 +832,7 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
array(
array(
'Location' => 'https://example.com/endpoint.php',
- 'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
+ 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT,
'index' => 'string',
),
),
diff --git a/tests/lib/SimpleSAML/Metadata/SAMLParserTest.php b/tests/lib/SimpleSAML/Metadata/SAMLParserTest.php
index 7239f79..af14bd1 100644
--- a/tests/lib/SimpleSAML/Metadata/SAMLParserTest.php
+++ b/tests/lib/SimpleSAML/Metadata/SAMLParserTest.php
@@ -16,7 +16,7 @@ class SAMLParserTest extends \PHPUnit_Framework_TestCase
'registrationAuthority' => 'https://incommon.org',
);
- $document = \SAML2_DOMDocumentFactory::fromString(
+ $document = \SAML2\DOMDocumentFactory::fromString(
<<<XML
<EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi">
<EntityDescriptor entityID="theEntityID">
@@ -48,7 +48,7 @@ XML
'registrationAuthority' => 'https://incommon.org',
);
- $document = \SAML2_DOMDocumentFactory::fromString(
+ $document = \SAML2\DOMDocumentFactory::fromString(
<<<XML
<EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi">
<Extensions>
diff --git a/tests/lib/SimpleSAML/Utils/HTTPTest.php b/tests/lib/SimpleSAML/Utils/HTTPTest.php
index 417c890..b6bfb6b 100644
--- a/tests/lib/SimpleSAML/Utils/HTTPTest.php
+++ b/tests/lib/SimpleSAML/Utils/HTTPTest.php
@@ -8,12 +8,80 @@ class HTTPTest extends \PHPUnit_Framework_TestCase
/**
+ * Set up the environment ($_SERVER) populating the typical variables from a given URL.
+ *
+ * @param string $url The URL to use as the current one.
+ */
+ private function setupEnvFromURL($url)
+ {
+ $addr = parse_url($url);
+ $_SERVER['HTTP_HOST'] = $addr['host'];
+ $_SERVER['SERVER_NAME'] = $addr['host'];
+ if ($addr['scheme'] === 'https') {
+ $_SERVER['HTTPS'] = 'on';
+ $default_port = '443';
+ } else {
+ unset($_SERVER['HTTPS']);
+ $default_port = '80';
+ }
+ $_SERVER['SERVER_PORT'] = $default_port;
+ if (isset($addr['port']) && strval($addr['port']) !== $default_port) {
+ $_SERVER['SERVER_PORT'] = strval($addr['port']);
+ }
+ $_SERVER['REQUEST_URI'] = $addr['path'].'?'.$addr['query'];
+ }
+
+ /**
+ * Test SimpleSAML\Utils\HTTP::addURLParameters().
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testAddURLParametersInvalidURL()
+ {
+ HTTP::addURLParameters(array(), array());
+ }
+
+ /**
+ * Test SimpleSAML\Utils\HTTP::addURLParameters().
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testAddURLParametersInvalidParameters()
+ {
+ HTTP::addURLParameters('string', 'string');
+ }
+
+ /**
+ * Test SimpleSAML\Utils\HTTP::addURLParameters().
+ */
+ public function testAddURLParameters()
+ {
+ $url = 'http://example.com/';
+ $params = array(
+ 'foo' => 'bar',
+ 'bar' => 'foo',
+ );
+ $this->assertEquals($url.'?foo=bar&bar=foo', HTTP::addURLParameters($url, $params));
+
+ $url = 'http://example.com/?';
+ $params = array(
+ 'foo' => 'bar',
+ 'bar' => 'foo',
+ );
+ $this->assertEquals($url.'foo=bar&bar=foo', HTTP::addURLParameters($url, $params));
+
+ $url = 'http://example.com/?foo=bar';
+ $params = array(
+ 'bar' => 'foo',
+ );
+ $this->assertEquals($url.'&bar=foo', HTTP::addURLParameters($url, $params));
+ }
+
+ /**
* Test SimpleSAML\Utils\HTTP::guessBasePath().
*/
public function testGuessBasePath()
{
- global $_SERVER;
-
$original = $_SERVER;
$_SERVER['REQUEST_URI'] = '/simplesaml/module.php';
@@ -57,6 +125,8 @@ class HTTPTest extends \PHPUnit_Framework_TestCase
*/
public function testGetSelfHost()
{
+ $original = $_SERVER;
+
\SimpleSAML_Configuration::loadFromArray(array(
'baseurlpath' => '',
), '[ARRAY]', 'simplesaml');
@@ -64,6 +134,8 @@ class HTTPTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('localhost', HTTP::getSelfHost());
$_SERVER['SERVER_PORT'] = '3030';
$this->assertEquals('localhost', HTTP::getSelfHost());
+
+ $_SERVER = $original;
}
/**
@@ -71,6 +143,8 @@ class HTTPTest extends \PHPUnit_Framework_TestCase
*/
public function testGetSelfHostWithPort()
{
+ $original = $_SERVER;
+
\SimpleSAML_Configuration::loadFromArray(array(
'baseurlpath' => '',
), '[ARRAY]', 'simplesaml');
@@ -87,5 +161,205 @@ class HTTPTest extends \PHPUnit_Framework_TestCase
$_SERVER['HTTPS'] = 'on';
$_SERVER['SERVER_PORT'] = '443';
$this->assertEquals('localhost', HTTP::getSelfHostWithNonStandardPort());
+
+ $_SERVER = $original;
+ }
+
+
+ /**
+ * Test SimpleSAML\Utils\HTTP::getSelfURL().
+ */
+ public function testGetSelfURLMethods()
+ {
+ $original = $_SERVER;
+
+ /*
+ * Test a URL pointing to a script that's not part of the public interface. This allows us to test calls to
+ * getSelfURL() from scripts outside of SimpleSAMLphp
+ */
+ \SimpleSAML_Configuration::loadFromArray(array(
+ 'baseurlpath' => 'http://example.com/simplesaml/',
+ ), '[ARRAY]', 'simplesaml');
+ $url = 'https://example.com/app/script.php/some/path?foo=bar';
+ $this->setupEnvFromURL($url);
+ $_SERVER['SCRIPT_FILENAME'] = '/var/www/app/script.php';
+ $this->assertEquals($url, HTTP::getSelfURL());
+ $this->assertEquals('https://example.com', HTTP::getSelfURLHost());
+ $this->assertEquals('https://example.com/app/script.php/some/path', HTTP::getSelfURLNoQuery());
+ $this->assertTrue(HTTP::isHTTPS());
+ $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
+
+ // test a valid, full URL, based on a full URL in the configuration
+ $cfg = \SimpleSAML_Configuration::loadFromArray(array(
+ 'baseurlpath' => 'https://example.com/simplesaml/',
+ ), '[ARRAY]', 'simplesaml');
+ $baseDir = $cfg->getBaseDir();
+ $_SERVER['SCRIPT_FILENAME'] = $baseDir.'www/module.php';
+ $this->setupEnvFromURL('http://www.example.org/module.php/module/file.php?foo=bar');
+ $this->assertEquals(
+ 'https://example.com/simplesaml/module.php/module/file.php?foo=bar',
+ HTTP::getSelfURL()
+ );
+ $this->assertEquals('https://example.com', HTTP::getSelfURLHost());
+ $this->assertEquals('https://example.com/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery());
+ $this->assertTrue(HTTP::isHTTPS());
+ $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
+
+ // test a valid, full URL, based on a full URL *without* a trailing slash in the configuration
+ \SimpleSAML_Configuration::loadFromArray(array(
+ 'baseurlpath' => 'https://example.com/simplesaml',
+ ), '[ARRAY]', 'simplesaml');
+ $this->assertEquals(
+ 'https://example.com/simplesaml/module.php/module/file.php?foo=bar',
+ HTTP::getSelfURL()
+ );
+ $this->assertEquals('https://example.com', HTTP::getSelfURLHost());
+ $this->assertEquals('https://example.com/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery());
+ $this->assertTrue(HTTP::isHTTPS());
+ $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
+
+ // test a valid, full URL, based on a full URL *without* a path in the configuration
+ \SimpleSAML_Configuration::loadFromArray(array(
+ 'baseurlpath' => 'https://example.com',
+ ), '[ARRAY]', 'simplesaml');
+ $this->assertEquals(
+ 'https://example.com/module.php/module/file.php?foo=bar',
+ HTTP::getSelfURL()
+ );
+ $this->assertEquals('https://example.com', HTTP::getSelfURLHost());
+ $this->assertEquals('https://example.com/module.php/module/file.php', HTTP::getSelfURLNoQuery());
+ $this->assertTrue(HTTP::isHTTPS());
+ $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
+
+ // test a valid, full URL, based on a relative path in the configuration
+ \SimpleSAML_Configuration::loadFromArray(array(
+ 'baseurlpath' => '/simplesaml/',
+ ), '[ARRAY]', 'simplesaml');
+ $this->setupEnvFromURL('http://www.example.org/simplesaml/module.php/module/file.php?foo=bar');
+ $this->assertEquals(
+ 'http://www.example.org/simplesaml/module.php/module/file.php?foo=bar',
+ HTTP::getSelfURL()
+ );
+ $this->assertEquals('http://www.example.org', HTTP::getSelfURLHost());
+ $this->assertEquals('http://www.example.org/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery());
+ $this->assertFalse(HTTP::isHTTPS());
+ $this->assertEquals('http://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
+
+ // test a valid, full URL, based on a relative path in the configuration and a non standard port
+ \SimpleSAML_Configuration::loadFromArray(array(
+ 'baseurlpath' => '/simplesaml/',
+ ), '[ARRAY]', 'simplesaml');
+ $this->setupEnvFromURL('http://example.org:8080/simplesaml/module.php/module/file.php?foo=bar');
+ $this->assertEquals(
+ 'http://example.org:8080/simplesaml/module.php/module/file.php?foo=bar',
+ HTTP::getSelfURL()
+ );
+ $this->assertEquals('http://example.org:8080', HTTP::getSelfURLHost());
+ $this->assertEquals('http://example.org:8080/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery());
+ $this->assertFalse(HTTP::isHTTPS());
+ $this->assertEquals('http://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
+
+ // test a valid, full URL, based on a relative path in the configuration, a non standard port and HTTPS
+ \SimpleSAML_Configuration::loadFromArray(array(
+ 'baseurlpath' => '/simplesaml/',
+ ), '[ARRAY]', 'simplesaml');
+ $this->setupEnvFromURL('https://example.org:8080/simplesaml/module.php/module/file.php?foo=bar');
+ $this->assertEquals(
+ 'https://example.org:8080/simplesaml/module.php/module/file.php?foo=bar',
+ HTTP::getSelfURL()
+ );
+ $this->assertEquals('https://example.org:8080', HTTP::getSelfURLHost());
+ $this->assertEquals(
+ 'https://example.org:8080/simplesaml/module.php/module/file.php',
+ HTTP::getSelfURLNoQuery()
+ );
+ $this->assertTrue(HTTP::isHTTPS());
+ $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
+
+ $_SERVER = $original;
+ }
+
+
+ /**
+ * Test SimpleSAML\Utils\HTTP::checkURLAllowed(), without regex.
+ */
+ public function testCheckURLAllowedWithoutRegex()
+ {
+ $original = $_SERVER;
+
+ \SimpleSAML_Configuration::loadFromArray(array(
+ 'trusted.url.domains' => array('sp.example.com', 'app.example.com'),
+ 'trusted.url.regex' => false,
+ ), '[ARRAY]', 'simplesaml');
+
+ $_SERVER['REQUEST_URI'] = '/module.php';
+
+ $allowed = array(
+ 'https://sp.example.com/',
+ 'http://sp.example.com/',
+ 'https://app.example.com/',
+ 'http://app.example.com/',
+ );
+ foreach ($allowed as $url) {
+ $this->assertEquals(HTTP::checkURLAllowed($url), $url);
+ }
+
+ $this->setExpectedException('SimpleSAML_Error_Exception');
+ HTTP::checkURLAllowed('https://evil.com');
+
+ $_SERVER = $original;
+ }
+
+ /**
+ * Test SimpleSAML\Utils\HTTP::checkURLAllowed(), with regex.
+ */
+ public function testCheckURLAllowedWithRegex()
+ {
+ $original = $_SERVER;
+
+ \SimpleSAML_Configuration::loadFromArray(array(
+ 'trusted.url.domains' => array('.*\.example\.com'),
+ 'trusted.url.regex' => true,
+ ), '[ARRAY]', 'simplesaml');
+
+ $_SERVER['REQUEST_URI'] = '/module.php';
+
+ $allowed = array(
+ 'https://sp.example.com/',
+ 'http://sp.example.com/',
+ 'https://app1.example.com/',
+ 'http://app1.example.com/',
+ 'https://app2.example.com/',
+ 'http://app2.example.com/',
+ );
+ foreach ($allowed as $url) {
+ $this->assertEquals(HTTP::checkURLAllowed($url), $url);
+ }
+
+ $this->setExpectedException('SimpleSAML_Error_Exception');
+ HTTP::checkURLAllowed('https://evil.com');
+
+ $_SERVER = $original;
+ }
+
+ /**
+ * Test SimpleSAML\Utils\HTTP::checkURLAllowed(), with the regex as a
+ * subdomain of an evil domain.
+ */
+ public function testCheckURLAllowedWithRegexWithoutDelimiters()
+ {
+ $original = $_SERVER;
+
+ \SimpleSAML_Configuration::loadFromArray(array(
+ 'trusted.url.domains' => array('app\.example\.com'),
+ 'trusted.url.regex' => true,
+ ), '[ARRAY]', 'simplesaml');
+
+ $_SERVER['REQUEST_URI'] = '/module.php';
+
+ $this->setExpectedException('SimpleSAML_Error_Exception');
+ HTTP::checkURLAllowed('https://app.example.com.evil.com');
+
+ $_SERVER = $original;
}
}
diff --git a/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php b/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php
index 31e1516..8b86314 100644
--- a/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php
+++ b/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php
@@ -191,4 +191,27 @@ class Test_Core_Auth_Process_ScopeAttribute extends PHPUnit_Framework_TestCase
$attributes = $result['Attributes'];
$this->assertEquals($attributes['eduPersonScopedAffiliation'], array('student@example.org'));
}
+
+ /*
+ * When the target attribute exists and onlyIfEmpty is set
+ */
+ public function testOnlyIfEmpty()
+ {
+ $config = array(
+ 'scopeAttribute' => 'schacHomeOrganization',
+ 'sourceAttribute' => 'eduPersonAffiliation',
+ 'targetAttribute' => 'eduPersonScopedAffiliation',
+ 'onlyIfEmpty' => true,
+ );
+ $request = array(
+ 'Attributes' => array(
+ 'schacHomeOrganization' => array('example.org'),
+ 'eduPersonAffiliation' => array('student'),
+ 'eduPersonScopedAffiliation' => array('staff@example.org', 'member@example.org'),
+ )
+ );
+ $result = self::processFilter($config, $request);
+ $attributes = $result['Attributes'];
+ $this->assertEquals($attributes['eduPersonScopedAffiliation'], array('staff@example.org', 'member@example.org'));
+ }
}
diff --git a/tests/routers/configLoader.php b/tests/routers/configLoader.php
new file mode 100644
index 0000000..724cada
--- /dev/null
+++ b/tests/routers/configLoader.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This "router" (a script that's executed for every request received by PHP's built-in web server) will look
+ * for a file in the system's temporary directory, with the PID of the current process as its name, and the
+ * '.lock' extension. If the file exists, it will try to include it and preload SimpleSAMLphp's configuration with
+ * the $config array defined in that file.
+ * This is useful to configure SimpleSAMLphp dynamically when running inside the built-in server, so that
+ * we can test different configurations without the need to keep a structure of files.
+ *
+ * In order to use it:
+ *
+ * 1. Create an array with the SimpleSAMLphp configuration you would like to use.
+ * 2. Start the built-in server passing "configLoader" as the first parameter to the constructor:
+ * $server = new BuiltInServer('configLoader');
+ * $addr = $server->start();
+ * 3. Get the PID of the server once it has started:
+ * $pid = $server->getPid();
+ * 4. Build the path to the file that this script will use:
+ * $file = sys_get_temp_dir().'/'.$pid.'.lock';
+ * 5. Dump the configuration array to the file:
+ * file_put_contents("<?php\n\$config = ".var_export($config, true).";\n");
+ * 6. Make a request to the server:
+ * $server->get($query, $parameters);
+ * 7. Remove the temporary file when done:
+ * unlink($file);
+ */
+
+include_once(sys_get_temp_dir().'/'.getmypid().'.lock');
+
+// load SimpleSAMLphp's autoloader
+require_once(dirname(__FILE__).'/../../vendor/autoload.php');
+
+// initialize configuration
+if (isset($config)) {
+ SimpleSAML_Configuration::loadFromArray($config, '[ARRAY]', 'simplesaml');
+}
+
+// let the script proceed
+// see: http://php.net/manual/en/features.commandline.webserver.php
+return false;
diff --git a/tests/www/IndexTest.php b/tests/www/IndexTest.php
new file mode 100644
index 0000000..aa7df8b
--- /dev/null
+++ b/tests/www/IndexTest.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * Simple test for the www/index.php script.
+ *
+ * This test is intended mostly as a demonstration of how to test the public web interface in SimpleSAMLphp.
+ *
+ * @author Jaime Pérez Crespo <jaime.perez@uninett.no>
+ * @package SimpleSAMLphp
+ */
+
+namespace SimpleSAML\Test\Web;
+
+include(dirname(__FILE__).'/../BuiltInServer.php');
+
+use \SimpleSAML\Test\BuiltInServer;
+
+class IndexTest extends \PHPUnit_Framework_TestCase
+{
+
+ /**
+ * @var \SimpleSAML\Test\BuiltInServer
+ */
+ protected $server;
+
+ /**
+ * @var string
+ */
+ protected $server_addr;
+
+ /**
+ * @var int
+ */
+ protected $server_pid;
+
+ /**
+ * @var string
+ */
+ protected $shared_file;
+
+
+ /**
+ * The setup method that is run before any tests in this class.
+ */
+ protected function setup()
+ {
+ $this->server = new BuiltInServer('configLoader');
+ $this->server_addr = $this->server->start();
+ $this->server_pid = $this->server->getPid();
+
+ $this->shared_file = sys_get_temp_dir().'/'.$this->server_pid.'.lock';
+ @unlink($this->shared_file); // remove it if it exists
+ }
+
+
+ protected function updateConfig($config)
+ {
+ @unlink($this->shared_file);
+ $config = "<?php\n\$config = ".var_export($config, true).";\n";
+ file_put_contents($this->shared_file, $config);
+ }
+
+
+ /**
+ * A simple test to make sure the index.php file redirects appropriately to the right URL.
+ */
+ public function testRedirection()
+ {
+ if (defined('HHVM_VERSION')) {
+ // can't test this in HHVM for the moment
+ $this->markTestSkipped('The web-based tests cannot be run in HHVM for the moment.');
+ }
+
+ if (version_compare(phpversion(), '5.4') === -1) {
+ // no built-in server prior to 5.4
+ $this->markTestSkipped('The web-based tests cannot be run in PHP versions older than 5.4.');
+ }
+
+ // test most basic redirection
+ $this->updateConfig(array(
+ 'baseurlpath' => 'http://example.org/simplesaml/'
+ ));
+ $resp = $this->server->get('/index.php', array(), array(
+ CURLOPT_FOLLOWLOCATION => 0,
+ ));
+ $this->assertEquals('302', $resp['code']);
+ $this->assertEquals(
+ 'http://example.org/simplesaml/module.php/core/frontpage_welcome.php',
+ $resp['headers']['Location']
+ );
+
+ // test non-default path and https
+ $this->updateConfig(array(
+ 'baseurlpath' => 'https://example.org/'
+ ));
+ $resp = $this->server->get('/index.php', array(), array(
+ CURLOPT_FOLLOWLOCATION => 0,
+ ));
+ $this->assertEquals('302', $resp['code']);
+ $this->assertEquals(
+ 'https://example.org/module.php/core/frontpage_welcome.php',
+ $resp['headers']['Location']
+ );
+
+ // test URL guessing
+ $this->updateConfig(array(
+ 'baseurlpath' => '/simplesaml/'
+ ));
+ $resp = $this->server->get('/index.php', array(), array(
+ CURLOPT_FOLLOWLOCATION => 0,
+ ));
+ $this->assertEquals('302', $resp['code']);
+ $this->assertEquals(
+ 'http://'.$this->server_addr.'/simplesaml/module.php/core/frontpage_welcome.php',
+ $resp['headers']['Location']
+ );
+ }
+
+
+ /**
+ * The tear down method that is executed after all tests in this class.
+ */
+ protected function tearDown()
+ {
+ unlink($this->shared_file);
+ $this->server->stop();
+ }
+}
diff --git a/www/_include.php b/www/_include.php
index 4772fbb..b5f506f 100644
--- a/www/_include.php
+++ b/www/_include.php
@@ -35,13 +35,23 @@ require_once(dirname(dirname(__FILE__)).'/lib/_autoload.php');
SimpleSAML_Error_Assertion::installHandler();
// show error page on unhandled exceptions
-function SimpleSAML_exception_handler(Exception $exception)
+function SimpleSAML_exception_handler($exception)
{
+ SimpleSAML\Module::callHooks('exception_handler', $exception);
+
if ($exception instanceof SimpleSAML_Error_Error) {
$exception->show();
- } else {
+ } elseif ($exception instanceof Exception) {
$e = new SimpleSAML_Error_Error('UNHANDLEDEXCEPTION', $exception);
$e->show();
+ } else {
+ if (class_exists('Error') && $exception instanceof Error) {
+ $errno = $exception->getCode();
+ $errstr = $exception->getMessage();
+ $errfile = $exception->getFile();
+ $errline = $exception->getLine();
+ SimpleSAML_error_handler($errno, $errstr, $errfile, $errline);
+ }
}
}
@@ -81,8 +91,9 @@ function SimpleSAML_error_handler($errno, $errstr, $errfile = null, $errline = 0
set_error_handler('SimpleSAML_error_handler');
-$configdir = SimpleSAML\Utils\Config::getConfigDir();
-if (!file_exists($configdir.'/config.php')) {
+try {
+ SimpleSAML_Configuration::getInstance();
+} catch (Exception $e) {
throw new \SimpleSAML\Error\CriticalConfigurationError(
'You have not yet created the SimpleSAMLphp configuration files.'
);
diff --git a/www/admin/index.php b/www/admin/index.php
new file mode 100644
index 0000000..a1f9558
--- /dev/null
+++ b/www/admin/index.php
@@ -0,0 +1,27 @@
+<?php
+
+require_once('../_include.php');
+
+// Load SimpleSAMLphp, configuration
+$config = SimpleSAML_Configuration::getInstance();
+$session = SimpleSAML_Session::getSessionFromRequest();
+
+// Check if valid local session exists..
+//SimpleSAML\Utils\Auth::requireAdmin();
+
+$adminpages = array(
+ 'hostnames.php' => 'Diagnostics on hostname, port and protocol',
+ 'phpinfo.php' => 'PHP info',
+ '../module.php/sanitycheck/index.php' => 'Sanity check of your SimpleSAMLphp setup',
+ 'sandbox.php' => 'Sandbox for testing changes to layout and css',
+);
+
+$template = new SimpleSAML_XHTML_Template($config, 'index.php');
+
+$template->data['pagetitle'] = 'Admin';
+$template->data['adminpages'] = $adminpages;
+$template->data['remaining'] = $session->getAuthData('admin', 'Expire') - time();
+$template->data['valid'] = 'na';
+$template->data['logout'] = null;
+
+$template->show();
diff --git a/www/admin/sandbox.php b/www/admin/sandbox.php
new file mode 100644
index 0000000..ec77569
--- /dev/null
+++ b/www/admin/sandbox.php
@@ -0,0 +1,19 @@
+<?php
+
+require_once('../_include.php');
+
+// Load SimpleSAMLphp, configuration
+$config = SimpleSAML_Configuration::getInstance();
+$session = SimpleSAML_Session::getSessionFromRequest();
+
+// Check if valid local session exists..
+//SimpleSAML\Utils\Auth::requireAdmin();
+
+$template = new SimpleSAML_XHTML_Template($config, 'sandbox.php');
+
+$template->data['pagetitle'] = 'Sandbox';
+$template->data['sometext'] = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.';
+$template->data['remaining'] = $session->getAuthData('admin', 'Expire') - time();
+$template->data['logout'] = null;
+
+$template->show();
diff --git a/www/logout.php b/www/logout.php
index 220449a..b87ca89 100644
--- a/www/logout.php
+++ b/www/logout.php
@@ -5,8 +5,7 @@ require_once('_include.php');
$config = SimpleSAML_Configuration::getInstance();
if (array_key_exists('link_href', $_REQUEST)) {
- $link = (string) $_REQUEST['link_href'];
- $link = \SimpleSAML\Utils\HTTP::normalizeURL($link);
+ $link = \SimpleSAML\Utils\HTTP::checkURLAllowed($_REQUEST['link_href']);
} else {
$link = 'index.php';
}
diff --git a/www/module.php b/www/module.php
index 9c09c65..cb6b64e 100644
--- a/www/module.php
+++ b/www/module.php
@@ -38,135 +38,134 @@ $mimeTypes = array(
'xhtml' => 'application/xhtml+xml',
);
-try {
-
- if (empty($_SERVER['PATH_INFO'])) {
- throw new SimpleSAML_Error_NotFound('No PATH_INFO to module.php');
- }
+if (empty($_SERVER['PATH_INFO'])) {
+ throw new SimpleSAML_Error_NotFound('No PATH_INFO to module.php');
+}
- $url = $_SERVER['PATH_INFO'];
- assert('substr($url, 0, 1) === "/"');
+$url = $_SERVER['PATH_INFO'];
+assert('substr($url, 0, 1) === "/"');
- /* clear the PATH_INFO option, so that a script can detect whether it is called with anything following the
- *'.php'-ending.
- */
- unset($_SERVER['PATH_INFO']);
+/* clear the PATH_INFO option, so that a script can detect whether it is called with anything following the
+ *'.php'-ending.
+ */
+unset($_SERVER['PATH_INFO']);
- $modEnd = strpos($url, '/', 1);
- if ($modEnd === false) {
- // the path must always be on the form /module/
- throw new SimpleSAML_Error_NotFound('The URL must at least contain a module name followed by a slash.');
- }
+$modEnd = strpos($url, '/', 1);
+if ($modEnd === false) {
+ // the path must always be on the form /module/
+ throw new SimpleSAML_Error_NotFound('The URL must at least contain a module name followed by a slash.');
+}
- $module = substr($url, 1, $modEnd - 1);
- $url = substr($url, $modEnd + 1);
- if ($url === false) {
- $url = '';
- }
+$module = substr($url, 1, $modEnd - 1);
+$url = substr($url, $modEnd + 1);
+if ($url === false) {
+ $url = '';
+}
- if (!SimpleSAML\Module::isModuleEnabled($module)) {
- throw new SimpleSAML_Error_NotFound('The module \''.$module.'\' was either not found, or wasn\'t enabled.');
- }
+if (!SimpleSAML\Module::isModuleEnabled($module)) {
+ throw new SimpleSAML_Error_NotFound('The module \''.$module.'\' was either not found, or wasn\'t enabled.');
+}
- /* Make sure that the request isn't suspicious (contains references to current directory or parent directory or
- * anything like that. Searching for './' in the URL will detect both '../' and './'. Searching for '\' will detect
- * attempts to use Windows-style paths.
- */
- if (strpos($url, '\\') !== false) {
- throw new SimpleSAML_Error_BadRequest('Requested URL contained a backslash.');
- } elseif (strpos($url, './') !== false) {
- throw new SimpleSAML_Error_BadRequest('Requested URL contained \'./\'.');
- }
+/* Make sure that the request isn't suspicious (contains references to current directory or parent directory or
+ * anything like that. Searching for './' in the URL will detect both '../' and './'. Searching for '\' will detect
+ * attempts to use Windows-style paths.
+ */
+if (strpos($url, '\\') !== false) {
+ throw new SimpleSAML_Error_BadRequest('Requested URL contained a backslash.');
+} elseif (strpos($url, './') !== false) {
+ throw new SimpleSAML_Error_BadRequest('Requested URL contained \'./\'.');
+}
- $moduleDir = SimpleSAML\Module::getModuleDir($module).'/www/';
+$moduleDir = SimpleSAML\Module::getModuleDir($module).'/www/';
- // check for '.php/' in the path, the presence of which indicates that another php-script should handle the request
- for ($phpPos = strpos($url, '.php/'); $phpPos !== false; $phpPos = strpos($url, '.php/', $phpPos + 1)) {
+// check for '.php/' in the path, the presence of which indicates that another php-script should handle the request
+for ($phpPos = strpos($url, '.php/'); $phpPos !== false; $phpPos = strpos($url, '.php/', $phpPos + 1)) {
- $newURL = substr($url, 0, $phpPos + 4);
- $param = substr($url, $phpPos + 4);
+ $newURL = substr($url, 0, $phpPos + 4);
+ $param = substr($url, $phpPos + 4);
- if (is_file($moduleDir.$newURL)) {
- /* $newPath points to a normal file. Point execution to that file, and
- * save the remainder of the path in PATH_INFO.
- */
- $url = $newURL;
- $_SERVER['PATH_INFO'] = $param;
- break;
- }
+ if (is_file($moduleDir.$newURL)) {
+ /* $newPath points to a normal file. Point execution to that file, and
+ * save the remainder of the path in PATH_INFO.
+ */
+ $url = $newURL;
+ $_SERVER['PATH_INFO'] = $param;
+ break;
}
+}
- $path = $moduleDir.$url;
+$path = $moduleDir.$url;
- if ($path[strlen($path) - 1] === '/') {
- // path ends with a slash - directory reference. Attempt to find index file in directory
- foreach ($indexFiles as $if) {
- if (file_exists($path.$if)) {
- $path .= $if;
- break;
- }
+if ($path[strlen($path) - 1] === '/') {
+ // path ends with a slash - directory reference. Attempt to find index file in directory
+ foreach ($indexFiles as $if) {
+ if (file_exists($path.$if)) {
+ $path .= $if;
+ break;
}
}
+}
- if (is_dir($path)) {
- /* Path is a directory - maybe no index file was found in the previous step, or maybe the path didn't end with
- * a slash. Either way, we don't do directory listings.
- */
- throw new SimpleSAML_Error_NotFound('Directory listing not available.');
- }
+if (is_dir($path)) {
+ /* Path is a directory - maybe no index file was found in the previous step, or maybe the path didn't end with
+ * a slash. Either way, we don't do directory listings.
+ */
+ throw new SimpleSAML_Error_NotFound('Directory listing not available.');
+}
- if (!file_exists($path)) {
- // file not found
- SimpleSAML\Logger::info('Could not find file \''.$path.'\'.');
- throw new SimpleSAML_Error_NotFound('The URL wasn\'t found in the module.');
- }
+if (!file_exists($path)) {
+ // file not found
+ SimpleSAML\Logger::info('Could not find file \''.$path.'\'.');
+ throw new SimpleSAML_Error_NotFound('The URL wasn\'t found in the module.');
+}
- if (preg_match('#\.php$#D', $path)) {
- // PHP file - attempt to run it
+if (preg_match('#\.php$#D', $path)) {
+ // PHP file - attempt to run it
+
+ /* In some environments, $_SERVER['SCRIPT_NAME'] is already set with $_SERVER['PATH_INFO']. Check for that case,
+ * and append script name only if necessary.
+ *
+ * Contributed by Travis Hegner.
+ */
+ $script = "/$module/$url";
+ if (stripos($_SERVER['SCRIPT_NAME'], $script) === false) {
$_SERVER['SCRIPT_NAME'] .= '/'.$module.'/'.$url;
- require($path);
- exit();
}
- // some other file type - attempt to serve it
+ require($path);
+ exit();
+}
- // find MIME type for file, based on extension
- $contentType = null;
- if (preg_match('#\.([^/\.]+)$#D', $path, $type)) {
- $type = strtolower($type[1]);
- if (array_key_exists($type, $mimeTypes)) {
- $contentType = $mimeTypes[$type];
- }
- }
+// some other file type - attempt to serve it
- if ($contentType === null) {
- /* We were unable to determine the MIME type from the file extension. Fall back to mime_content_type (if it
- * exists).
- */
- if (function_exists('mime_content_type')) {
- $contentType = mime_content_type($path);
- } else {
- // mime_content_type doesn't exist. Return a default MIME type
- SimpleSAML\Logger::warning('Unable to determine mime content type of file: '.$path);
- $contentType = 'application/octet-stream';
- }
+// find MIME type for file, based on extension
+$contentType = null;
+if (preg_match('#\.([^/\.]+)$#D', $path, $type)) {
+ $type = strtolower($type[1]);
+ if (array_key_exists($type, $mimeTypes)) {
+ $contentType = $mimeTypes[$type];
}
+}
- $contentLength = sprintf('%u', filesize($path)); // force filesize to an unsigned number
-
- header('Content-Type: '.$contentType);
- header('Content-Length: '.$contentLength);
- header('Cache-Control: public,max-age=86400');
- header('Expires: '.gmdate('D, j M Y H:i:s \G\M\T', time() + 10 * 60));
- header('Last-Modified: '.gmdate('D, j M Y H:i:s \G\M\T', filemtime($path)));
+if ($contentType === null) {
+ /* We were unable to determine the MIME type from the file extension. Fall back to mime_content_type (if it
+ * exists).
+ */
+ if (function_exists('mime_content_type')) {
+ $contentType = mime_content_type($path);
+ } else {
+ // mime_content_type doesn't exist. Return a default MIME type
+ SimpleSAML\Logger::warning('Unable to determine mime content type of file: '.$path);
+ $contentType = 'application/octet-stream';
+ }
+}
- readfile($path);
- exit();
-} catch (SimpleSAML_Error_Error $e) {
+$contentLength = sprintf('%u', filesize($path)); // force filesize to an unsigned number
- $e->show();
-} catch (Exception $e) {
+header('Content-Type: '.$contentType);
+header('Content-Length: '.$contentLength);
+header('Cache-Control: public,max-age=86400');
+header('Expires: '.gmdate('D, j M Y H:i:s \G\M\T', time() + 10 * 60));
+header('Last-Modified: '.gmdate('D, j M Y H:i:s \G\M\T', filemtime($path)));
- $e = new SimpleSAML_Error_Error('UNHANDLEDEXCEPTION', $e);
- $e->show();
-}
+readfile($path);
diff --git a/www/saml2/idp/ArtifactResolutionService.php b/www/saml2/idp/ArtifactResolutionService.php
index 3571b3b..1bdf811 100644
--- a/www/saml2/idp/ArtifactResolutionService.php
+++ b/www/saml2/idp/ArtifactResolutionService.php
@@ -2,7 +2,7 @@
/**
* The ArtifactResolutionService receives the samlart from the sp.
- * And when the artifact is found, it sends a SAML2_ArtifactResponse.
+ * And when the artifact is found, it sends a \SAML2\ArtifactResponse.
*
* @author Danny Bollaert, UGent AS. <danny.bollaert@ugent.be>
* @package SimpleSAMLphp
@@ -28,11 +28,11 @@ if ($store === false) {
throw new Exception('Unable to send artifact without a datastore configured.');
}
-$binding = new SAML2_SOAP();
+$binding = new \SAML2\SOAP();
try {
$request = $binding->receive();
} catch (Exception $e) { // TODO: look for a specific exception
- // This is dirty. Instead of checking the message of the exception, SAML2_Binding::getCurrentBinding() should throw
+ // This is dirty. Instead of checking the message of the exception, \SAML2\Binding::getCurrentBinding() should throw
// an specific exception when the binding is unknown, and we should capture that here. Also note that the exception
// message here is bogus!
if ($e->getMessage() === 'Invalid message received to AssertionConsumerService endpoint.') {
@@ -41,7 +41,7 @@ try {
throw $e; // do not ignore other exceptions!
}
}
-if (!($request instanceof SAML2_ArtifactResolve)) {
+if (!($request instanceof \SAML2\ArtifactResolve)) {
throw new Exception('Message received on ArtifactResolutionService wasn\'t a ArtifactResolve request.');
}
@@ -54,13 +54,13 @@ $responseData = $store->get('artifact', $artifact);
$store->delete('artifact', $artifact);
if ($responseData !== null) {
- $document = SAML2_DOMDocumentFactory::fromString($responseData);
+ $document = \SAML2\DOMDocumentFactory::fromString($responseData);
$responseXML = $document->firstChild;
} else {
$responseXML = null;
}
-$artifactResponse = new SAML2_ArtifactResponse();
+$artifactResponse = new \SAML2\ArtifactResponse();
$artifactResponse->setIssuer($idpEntityId);
$artifactResponse->setInResponseTo($request->getId());
$artifactResponse->setAny($responseXML);
diff --git a/www/saml2/idp/SingleLogoutService.php b/www/saml2/idp/SingleLogoutService.php
index 3105eea..f5ba8be 100644
--- a/www/saml2/idp/SingleLogoutService.php
+++ b/www/saml2/idp/SingleLogoutService.php
@@ -23,7 +23,7 @@ if (isset($_REQUEST['ReturnTo'])) {
sspmod_saml_IdP_SAML2::receiveLogoutMessage($idp);
} catch (Exception $e) { // TODO: look for a specific exception
/*
- * This is dirty. Instead of checking the message of the exception, SAML2_Binding::getCurrentBinding() should
+ * This is dirty. Instead of checking the message of the exception, \SAML2\Binding::getCurrentBinding() should
* throw an specific exception when the binding is unknown, and we should capture that here
*/
if ($e->getMessage() === 'Unable to find the current binding.') {
diff --git a/www/saml2/idp/metadata.php b/www/saml2/idp/metadata.php
index 3319799..2697640 100644
--- a/www/saml2/idp/metadata.php
+++ b/www/saml2/idp/metadata.php
@@ -2,6 +2,12 @@
require_once('../../_include.php');
+use SAML2\Constants;
+use SimpleSAML\Utils\Auth as Auth;
+use SimpleSAML\Utils\Crypto as Crypto;
+use SimpleSAML\Utils\HTTP as HTTP;
+use SimpleSAML\Utils\Config\Metadata as Metadata;
+
// load SimpleSAMLphp, configuration and metadata
$config = SimpleSAML_Configuration::getInstance();
$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
@@ -12,7 +18,7 @@ if (!$config->getBoolean('enable.saml20-idp', false)) {
// check if valid local session exists
if ($config->getBoolean('admin.protectmetadata', false)) {
- SimpleSAML\Utils\Auth::requireAdmin();
+ Auth::requireAdmin();
}
try {
@@ -24,7 +30,7 @@ try {
$availableCerts = array();
$keys = array();
- $certInfo = SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, false, 'new_');
+ $certInfo = Crypto::loadPublicKey($idpmeta, false, 'new_');
if ($certInfo !== null) {
$availableCerts['new_idp.crt'] = $certInfo;
$keys[] = array(
@@ -38,7 +44,7 @@ try {
$hasNewCert = false;
}
- $certInfo = SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, true);
+ $certInfo = Crypto::loadPublicKey($idpmeta, true);
$availableCerts['idp.crt'] = $certInfo;
$keys[] = array(
'type' => 'X509Certificate',
@@ -48,7 +54,7 @@ try {
);
if ($idpmeta->hasValue('https.certificate')) {
- $httpsCert = SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, true, 'https.');
+ $httpsCert = Crypto::loadPublicKey($idpmeta, true, 'https.');
assert('isset($httpsCert["certData"])');
$availableCerts['https.crt'] = $httpsCert;
$keys[] = array(
@@ -107,17 +113,17 @@ try {
// Artifact sending enabled
$metaArray['ArtifactResolutionService'][] = array(
'index' => 0,
- 'Location' => \SimpleSAML\Utils\HTTP::getBaseURL().'saml2/idp/ArtifactResolutionService.php',
- 'Binding' => SAML2_Const::BINDING_SOAP,
+ 'Location' => HTTP::getBaseURL().'saml2/idp/ArtifactResolutionService.php',
+ 'Binding' => Constants::BINDING_SOAP,
);
}
if ($idpmeta->getBoolean('saml20.hok.assertion', false)) {
// Prepend HoK SSO Service endpoint.
array_unshift($metaArray['SingleSignOnService'], array(
- 'hoksso:ProtocolBinding' => SAML2_Const::BINDING_HTTP_REDIRECT,
- 'Binding' => SAML2_Const::BINDING_HOK_SSO,
- 'Location' => \SimpleSAML\Utils\HTTP::getBaseURL().'saml2/idp/SSOService.php'
+ 'hoksso:ProtocolBinding' => Constants::BINDING_HTTP_REDIRECT,
+ 'Binding' => Constants::BINDING_HOK_SSO,
+ 'Location' => HTTP::getBaseURL().'saml2/idp/SSOService.php'
));
}
@@ -147,7 +153,7 @@ try {
$metaArray['EntityAttributes'] = $idpmeta->getArray('EntityAttributes');
// check for entity categories
- if (SimpleSAML\Utils\Config\Metadata::isHiddenFromDiscovery($metaArray)) {
+ if (Metadata::isHiddenFromDiscovery($metaArray)) {
$metaArray['hide.from.discovery'] = true;
}
}
@@ -175,7 +181,7 @@ try {
if ($idpmeta->hasValue('contacts')) {
$contacts = $idpmeta->getArray('contacts');
foreach ($contacts as $contact) {
- $metaArray['contacts'][] = \SimpleSAML\Utils\Config\Metadata::getContact($contact);
+ $metaArray['contacts'][] = Metadata::getContact($contact);
}
}
@@ -184,7 +190,7 @@ try {
$techcontact['emailAddress'] = $technicalContactEmail;
$techcontact['name'] = $config->getString('technicalcontact_name', null);
$techcontact['contactType'] = 'technical';
- $metaArray['contacts'][] = \SimpleSAML\Utils\Config\Metadata::getContact($techcontact);
+ $metaArray['contacts'][] = Metadata::getContact($techcontact);
}
$metaBuilder = new SimpleSAML_Metadata_SAMLBuilder($idpentityid);
@@ -206,7 +212,7 @@ try {
$t->data['clipboard.js'] = true;
$t->data['available_certs'] = $availableCerts;
$t->data['header'] = 'saml20-idp';
- $t->data['metaurl'] = \SimpleSAML\Utils\HTTP::getSelfURLNoQuery();
+ $t->data['metaurl'] = HTTP::getSelfURLNoQuery();
$t->data['metadata'] = htmlspecialchars($metaxml);
$t->data['metadataflat'] = htmlspecialchars($metaflat);
$t->data['defaultidp'] = $defaultidp;