Expose audience collection on security policy.
[shibboleth/cpp-opensaml.git] / saml / saml1 / profile / BrowserSSOProfileValidator.cpp
1 /*
2  *  Copyright 2001-2007 Internet2
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * BrowserSSOProfileValidator.cpp
19  * 
20  * SAML 1.x Browser SSO Profile Assertion Validator
21  */
22
23 #include "internal.h"
24 #include "saml1/core/Assertions.h"
25 #include "saml1/profile/BrowserSSOProfileValidator.h"
26
27 #include <xmltooling/logging.h>
28 #include <xmltooling/util/NDC.h>
29
30 using namespace opensaml::saml1;
31 using namespace xmltooling::logging;
32 using namespace xmltooling;
33 using namespace std;
34
35 namespace {
36     class SAML_DLLLOCAL _checkMethod : public unary_function<const SubjectStatement*,void>,
37         public unary_function<const ConfirmationMethod*,bool>
38     {
39     public:
40         void operator()(const SubjectStatement* s) const {
41             const Subject* sub = s->getSubject();
42             if (s) {
43                 const SubjectConfirmation* sc = sub->getSubjectConfirmation();
44                 if (sc) {
45                     const vector<ConfirmationMethod*>& methods = sc->getConfirmationMethods();
46                     if (find_if(methods.begin(), methods.end(), _checkMethod())!=methods.end())
47                         return;     // methods checked out
48                 }
49             }
50             throw ValidationException("Assertion contained a statement without a supported ConfirmationMethod.");
51         }
52
53         bool operator()(const ConfirmationMethod* cm) const {
54             const XMLCh* m = cm->getMethod();
55             return (XMLString::equals(m,SubjectConfirmation::BEARER) ||
56                 XMLString::equals(m,SubjectConfirmation::ARTIFACT) ||
57                 XMLString::equals(m,SubjectConfirmation::ARTIFACT01));
58         }
59     };
60 };
61
62 void BrowserSSOProfileValidator::validateAssertion(const Assertion& assertion) const
63 {
64 #ifdef _DEBUG
65     xmltooling::NDC ndc("validate");
66 #endif
67
68     // Make sure the assertion is bounded.
69     const Conditions* conds = assertion.getConditions();
70     if (!conds || !conds->getNotBefore() || !conds->getNotOnOrAfter())
71         throw ValidationException("SSO assertions MUST contain NotBefore/NotOnOrAfter attributes.");
72
73     // Each statement MUST have proper confirmation requirements.
74     const vector<AuthenticationStatement*>& authn = assertion.getAuthenticationStatements();
75     for_each(authn.begin(), authn.end(), _checkMethod());
76     const vector<AttributeStatement*>& attr = assertion.getAttributeStatements();
77     for_each(attr.begin(), attr.end(), _checkMethod());
78     const vector<SubjectStatement*>& sub = assertion.getSubjectStatements();
79     for_each(sub.begin(), sub.end(), _checkMethod());
80
81     // Pass up for additional checking.
82     AssertionValidator::validateAssertion(assertion);
83 }