Boost related changes
[shibboleth/cpp-opensaml.git] / saml / util / CommonDomainCookie.cpp
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 /**
22  * CommonDomainCookie.cpp
23  * 
24  * Helper class for maintaining discovery cookie. 
25  */
26
27 #include "internal.h"
28 #include "util/CommonDomainCookie.h"
29
30 #include <boost/algorithm/string.hpp>
31 #include <xercesc/util/Base64.hpp>
32 #include <xsec/framework/XSECDefs.hpp>
33 #include <xmltooling/XMLToolingConfig.h>
34 #include <xmltooling/util/URLEncoder.h>
35
36 using namespace opensaml;
37 using namespace xmltooling;
38 using namespace boost;
39 using namespace std;
40
41 const char CommonDomainCookie::CDCName[] = "_saml_idp";
42
43 CommonDomainCookie::CommonDomainCookie(const char* cookie)
44 {
45     if (!cookie)
46         return;
47
48     // Copy it so we can URL-decode it.
49     char* b64=strdup(cookie);
50     XMLToolingConfig::getConfig().getURLEncoder()->decode(b64);
51
52     // Chop it up and save off elements.
53     split(m_list, b64, is_space(), algorithm::token_compress_on);
54     free(b64);
55
56     // Now Base64 decode the list elements, overwriting them.
57     xsecsize_t len;
58     for (vector<string>::iterator i = m_list.begin(); i != m_list.end(); ++i) {
59         trim(*i);
60         XMLByte* decoded=Base64::decode(reinterpret_cast<const XMLByte*>(i->c_str()),&len);
61         if (decoded && *decoded) {
62             i->assign(reinterpret_cast<char*>(decoded));
63 #ifdef OPENSAML_XERCESC_HAS_XMLBYTE_RELEASE
64             XMLString::release(&decoded);
65 #else
66             XMLString::release((char**)&decoded);
67 #endif
68         }
69     }
70 }
71
72 CommonDomainCookie::~CommonDomainCookie()
73 {
74 }
75
76 const vector<string>& CommonDomainCookie::get() const
77 {
78     return m_list;
79 }
80
81 const char* CommonDomainCookie::set(const char* entityID)
82 {
83     // First remove the IdP from the list.
84     m_list.erase(remove(m_list.begin(), m_list.end(), entityID), m_list.end());
85     
86     // Append it to the end.
87     m_list.push_back(entityID);
88     
89     // Now rebuild the delimited list.
90     xsecsize_t len;
91     string delimited;
92     for (vector<string>::const_iterator j = m_list.begin(); j != m_list.end(); ++j) {
93         if (!delimited.empty())
94             delimited += ' ';
95         
96         XMLByte* b64 = Base64::encode(reinterpret_cast<const XMLByte*>(j->c_str()), j->length(), &len);
97         XMLByte *pos, *pos2;
98         for (pos = b64, pos2 = b64; *pos2; ++pos2)
99             if (isgraph(*pos2))
100                 *pos++ = *pos2;
101         *pos = 0;
102         
103         delimited += reinterpret_cast<char*>(b64);
104 #ifdef OPENSAML_XERCESC_HAS_XMLBYTE_RELEASE
105         XMLString::release(&b64);
106 #else
107         XMLString::release((char**)&b64);
108 #endif
109     }
110     
111     m_encoded = XMLToolingConfig::getConfig().getURLEncoder()->encode(delimited.c_str());
112     return m_encoded.c_str();
113 }