Convert logging to log4shib via compile time switch.
[shibboleth/cpp-opensaml.git] / saml / saml2 / profile / BrowserSSOProfile20Validator.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  * BrowserSSOProfile20Validator.cpp
19  * 
20  * SAML 2.0 Browser SSO Profile Assertion Validator
21  */
22
23 #include "internal.h"
24 #include "saml2/core/Assertions.h"
25 #include "saml2/profile/BrowserSSOProfileValidator.h"
26
27 #include <xmltooling/logging.h>
28 #include <xmltooling/util/NDC.h>
29
30 using namespace opensaml::saml2;
31 using namespace xmltooling::logging;
32 using namespace xmltooling;
33 using namespace std;
34
35 void BrowserSSOProfileValidator::validateAssertion(const Assertion& assertion) const
36 {
37 #ifdef _DEBUG
38     xmltooling::NDC ndc("validate");
39 #endif
40     Category& log = Category::getInstance(SAML_LOGCAT".AssertionValidator");
41
42     // The assertion MUST have proper confirmation requirements.
43     const Subject* subject = assertion.getSubject();
44     if (subject) {
45         const vector<SubjectConfirmation*>& confs = subject->getSubjectConfirmations();
46         for (vector<SubjectConfirmation*>::const_iterator sc = confs.begin(); sc!=confs.end(); ++sc) {
47             if (XMLString::equals((*sc)->getMethod(), SubjectConfirmation::BEARER)) {
48                 const SubjectConfirmationDataType* data = dynamic_cast<const SubjectConfirmationDataType*>((*sc)->getSubjectConfirmationData());
49                 
50                 if (m_destination.get()) {
51                     if (!XMLString::equals(m_destination.get(), data ? data->getRecipient() : NULL)) {
52                         log.error("bearer confirmation failed with recipient mismatch");
53                         continue;
54                     }
55                 }
56
57                 if (m_requestID.get()) {
58                     if (!XMLString::equals(m_requestID.get(), data ? data->getInResponseTo() : NULL)) {
59                         log.error("bearer confirmation failed with request correlation mismatch");
60                         continue;
61                     }
62                 }
63
64                 if (m_ts) {
65                     if (!data || !data->getNotOnOrAfter()) {
66                         log.error("bearer confirmation missing NotOnOrAfter attribute");
67                         continue;
68                     }
69                     else if (data->getNotOnOrAfterEpoch() <= m_ts - XMLToolingConfig::getConfig().clock_skew_secs) {
70                         log.error("bearer confirmation has expired");
71                         continue;
72                     }
73                 }
74
75                 // Save off client address.
76                 if (data) {
77                     auto_ptr_char ip(data->getAddress());
78                     if (ip.get())
79                         m_address = ip.get();
80                 }
81
82                 // Pass up for additional checking.
83                 return AssertionValidator::validateAssertion(assertion);
84             }
85         }
86     }
87     
88     throw ValidationException("Unable to satisfy assertion's SubjectConfirmation.");
89 }