Change license header.
[shibboleth/sp.git] / shibsp / lite / 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 "lite/CommonDomainCookie.h"
29
30 #include <xercesc/util/Base64.hpp>
31 #include <xmltooling/XMLToolingConfig.h>
32 #include <xmltooling/util/URLEncoder.h>
33
34 using namespace opensaml;
35 using namespace xmltooling;
36 using namespace std;
37
38 const char CommonDomainCookie::CDCName[] = "_saml_idp";
39
40 CommonDomainCookie::CommonDomainCookie(const char* cookie)
41 {
42     if (!cookie)
43         return;
44
45     // Copy it so we can URL-decode it.
46     char* b64=strdup(cookie);
47     XMLToolingConfig::getConfig().getURLEncoder()->decode(b64);
48
49     // Chop it up and save off elements.
50     vector<string> templist;
51     char* ptr=b64;
52     while (*ptr) {
53         while (*ptr && isspace(*ptr)) ptr++;
54         char* end=ptr;
55         while (*end && !isspace(*end)) end++;
56         templist.push_back(string(ptr,end-ptr));
57         ptr=end;
58     }
59     free(b64);
60
61     // Now Base64 decode the list.
62     xsecsize_t len;
63     for (vector<string>::iterator i=templist.begin(); i!=templist.end(); ++i) {
64         XMLByte* decoded=Base64::decode(reinterpret_cast<const XMLByte*>(i->c_str()),&len);
65         if (decoded && *decoded) {
66             m_list.push_back(reinterpret_cast<char*>(decoded));
67 #ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE
68             XMLString::release(&decoded);
69 #else
70             XMLString::release((char**)&decoded);
71 #endif
72         }
73     }
74 }
75
76 CommonDomainCookie::~CommonDomainCookie()
77 {
78 }
79
80 const vector<string>& CommonDomainCookie::get() const
81 {
82     return m_list;
83 }
84
85 const char* CommonDomainCookie::set(const char* entityID)
86 {
87     // First scan the list for this IdP.
88     for (vector<string>::iterator i=m_list.begin(); i!=m_list.end(); i++) {
89         if (*i == entityID) {
90             m_list.erase(i);
91             break;
92         }
93     }
94
95     // Append it to the end.
96     m_list.push_back(entityID);
97
98     // Now rebuild the delimited list.
99     xsecsize_t len;
100     string delimited;
101     for (vector<string>::const_iterator j=m_list.begin(); j!=m_list.end(); j++) {
102         if (!delimited.empty()) delimited += ' ';
103
104         XMLByte* b64=Base64::encode(reinterpret_cast<const XMLByte*>(j->c_str()),j->length(),&len);
105         XMLByte *pos, *pos2;
106         for (pos=b64, pos2=b64; *pos2; pos2++)
107             if (isgraph(*pos2))
108                 *pos++=*pos2;
109         *pos=0;
110
111         delimited += reinterpret_cast<char*>(b64);
112 #ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE
113         XMLString::release(&b64);
114 #else
115         XMLString::release((char**)&b64);
116 #endif
117     }
118
119     m_encoded=XMLToolingConfig::getConfig().getURLEncoder()->encode(delimited.c_str());
120     return m_encoded.c_str();
121 }