Update copyright.
[shibboleth/cpp-opensaml.git] / saml / util / CommonDomainCookie.cpp
1 /*\r
2  *  Copyright 2001-2007 Internet2\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * CommonDomainCookie.cpp\r
19  * \r
20  * Helper class for maintaining discovery cookie. \r
21  */\r
22 \r
23 #include "internal.h"\r
24 #include "binding/URLEncoder.h"\r
25 #include "util/CommonDomainCookie.h"\r
26 \r
27 #include <xercesc/util/Base64.hpp>\r
28 \r
29 using namespace opensaml;\r
30 using namespace std;\r
31 \r
32 const char CommonDomainCookie::CDCName[] = "_saml_idp";\r
33 \r
34 CommonDomainCookie::CommonDomainCookie(const char* cookie)\r
35 {\r
36     if (!cookie)\r
37         return;\r
38 \r
39     // Copy it so we can URL-decode it.\r
40     char* b64=strdup(cookie);\r
41     SAMLConfig::getConfig().getURLEncoder()->decode(b64);\r
42 \r
43     // Chop it up and save off elements.\r
44     vector<string> templist;\r
45     char* ptr=b64;\r
46     while (*ptr) {\r
47         while (*ptr && isspace(*ptr)) ptr++;\r
48         char* end=ptr;\r
49         while (*end && !isspace(*end)) end++;\r
50         templist.push_back(string(ptr,end-ptr));\r
51         ptr=end;\r
52     }\r
53     free(b64);\r
54 \r
55     // Now Base64 decode the list.\r
56     unsigned int len;\r
57     for (vector<string>::iterator i=templist.begin(); i!=templist.end(); ++i) {\r
58         XMLByte* decoded=Base64::decode(reinterpret_cast<const XMLByte*>(i->c_str()),&len);\r
59         if (decoded && *decoded) {\r
60             m_list.push_back(reinterpret_cast<char*>(decoded));\r
61             XMLString::release(&decoded);\r
62         }\r
63     }\r
64 }\r
65 \r
66 const char* CommonDomainCookie::set(const char* entityID)\r
67 {\r
68     // First scan the list for this IdP.\r
69     for (vector<string>::iterator i=m_list.begin(); i!=m_list.end(); i++) {\r
70         if (*i == entityID) {\r
71             m_list.erase(i);\r
72             break;\r
73         }\r
74     }\r
75     \r
76     // Append it to the end.\r
77     m_list.push_back(entityID);\r
78     \r
79     // Now rebuild the delimited list.\r
80     unsigned int len;\r
81     string delimited;\r
82     for (vector<string>::const_iterator j=m_list.begin(); j!=m_list.end(); j++) {\r
83         if (!delimited.empty()) delimited += ' ';\r
84         \r
85         XMLByte* b64=Base64::encode(reinterpret_cast<const XMLByte*>(j->c_str()),j->length(),&len);\r
86         XMLByte *pos, *pos2;\r
87         for (pos=b64, pos2=b64; *pos2; pos2++)\r
88             if (isgraph(*pos2))\r
89                 *pos++=*pos2;\r
90         *pos=0;\r
91         \r
92         delimited += reinterpret_cast<char*>(b64);\r
93         XMLString::release(&b64);\r
94     }\r
95     \r
96     m_encoded=SAMLConfig::getConfig().getURLEncoder()->encode(delimited.c_str());\r
97     return m_encoded.c_str();\r
98 }\r