From 197bcbae7339bc779bc5780882d11fdeb45f8223 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Thu, 8 Mar 2007 04:42:06 +0000 Subject: [PATCH] Moved URLEncoder down to tooling lib, added exception->querystring method. --- saml/Makefile.am | 4 +- saml/SAMLConfig.cpp | 11 -- saml/SAMLConfig.h | 24 +-- saml/binding/URLEncoder.h | 74 --------- saml/binding/impl/URLEncoder.cpp | 77 --------- saml/saml.vcproj | 8 - saml/saml1/binding/impl/SAML1ArtifactEncoder.cpp | 5 +- saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp | 4 +- saml/saml2/binding/impl/SAML2RedirectEncoder.cpp | 4 +- saml/util/CGIParser.cpp | 8 +- saml/util/CommonDomainCookie.cpp | 198 ++++++++++++----------- samltest/binding.h | 4 +- 12 files changed, 116 insertions(+), 305 deletions(-) delete mode 100644 saml/binding/URLEncoder.h delete mode 100644 saml/binding/impl/URLEncoder.cpp diff --git a/saml/Makefile.am b/saml/Makefile.am index da8e6c7..3ad4d76 100644 --- a/saml/Makefile.am +++ b/saml/Makefile.am @@ -47,8 +47,7 @@ samlbindinclude_HEADERS = \ binding/SAMLArtifact.h \ binding/SecurityPolicy.h \ binding/SecurityPolicyRule.h \ - binding/SOAPClient.h \ - binding/URLEncoder.h + binding/SOAPClient.h encinclude_HEADERS = \ encryption/EncryptedKeyResolver.h @@ -114,7 +113,6 @@ libsaml_la_SOURCES = \ binding/impl/SecurityPolicy.cpp \ binding/impl/SimpleSigningRule.cpp \ binding/impl/SOAPClient.cpp \ - binding/impl/URLEncoder.cpp \ binding/impl/XMLSigningRule.cpp \ saml1/core/impl/AssertionsImpl.cpp \ saml1/core/impl/AssertionsSchemaValidators.cpp \ diff --git a/saml/SAMLConfig.cpp b/saml/SAMLConfig.cpp index 2fba05c..d429d96 100644 --- a/saml/SAMLConfig.cpp +++ b/saml/SAMLConfig.cpp @@ -29,7 +29,6 @@ #include "binding/MessageEncoder.h" #include "binding/SAMLArtifact.h" #include "binding/SecurityPolicyRule.h" -#include "binding/URLEncoder.h" #include "saml1/core/Assertions.h" #include "saml1/core/Protocols.h" #include "saml2/core/Protocols.h" @@ -95,12 +94,6 @@ void SAMLConfig::setArtifactMap(ArtifactMap* artifactMap) m_artifactMap = artifactMap; } -void SAMLConfig::setURLEncoder(URLEncoder* urlEncoder) -{ - delete m_urlEncoder; - m_urlEncoder = urlEncoder; -} - bool SAMLInternalConfig::init(bool initXMLTooling) { #ifdef _DEBUG @@ -133,8 +126,6 @@ bool SAMLInternalConfig::init(bool initXMLTooling) registerMessageEncoders(); registerMessageDecoders(); registerSecurityPolicyRules(); - - m_urlEncoder = new URLEncoder(); log.info("library initialization complete"); return true; @@ -156,8 +147,6 @@ void SAMLInternalConfig::term(bool termXMLTooling) delete m_artifactMap; m_artifactMap = NULL; - delete m_urlEncoder; - m_urlEncoder = NULL; if (termXMLTooling) { XMLToolingConfig::getConfig().term(); diff --git a/saml/SAMLConfig.h b/saml/SAMLConfig.h index 64bc575..2d33cf7 100644 --- a/saml/SAMLConfig.h +++ b/saml/SAMLConfig.h @@ -41,7 +41,6 @@ namespace opensaml { class SAML_API MessageDecoder; class SAML_API SAMLArtifact; class SAML_API SecurityPolicyRule; - class SAML_API URLEncoder; namespace saml2md { class SAML_API MetadataProvider; @@ -113,24 +112,6 @@ namespace opensaml { } /** - * Sets the global URLEncoder instance. - * This method must be externally synchronized with any code that uses the object. - * Any previously set object is destroyed. - * - * @param urlEncoder new URLEncoder instance to store - */ - void setURLEncoder(URLEncoder* urlEncoder); - - /** - * Returns the global URLEncoder instance. - * - * @return global URLEncoder or NULL - */ - URLEncoder* getURLEncoder() const { - return m_urlEncoder; - } - - /** * Generate random information using the underlying security library * * @param buf buffer for the information @@ -183,13 +164,10 @@ namespace opensaml { xmltooling::PluginManager MetadataFilterManager; protected: - SAMLConfig() : m_artifactMap(NULL), m_urlEncoder(NULL) {} + SAMLConfig() : m_artifactMap(NULL) {} /** Global ArtifactMap instance for use by artifact-related functions. */ ArtifactMap* m_artifactMap; - - /** Global URLEncoder instance for use by URL-related functions. */ - URLEncoder* m_urlEncoder; }; #if defined (_MSC_VER) diff --git a/saml/binding/URLEncoder.h b/saml/binding/URLEncoder.h deleted file mode 100644 index 5f99a4e..0000000 --- a/saml/binding/URLEncoder.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2001-2007 Internet2 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file saml/binding/URLEncoder.h - * - * Interface to a URL-encoding mechanism along with a - * default implementation. - */ - -#ifndef __saml_urlenc_h__ -#define __saml_urlenc_h__ - -#include - -namespace opensaml { - /** - * Interface to a URL-encoding mechanism along with a default implementation. - * - * Since URL-encoding is not canonical, it's important that the same - * encoder is used during some library operations and the calling code. - * Applications can supply an alternative implementation to the library - * if required. - */ - class SAML_API URLEncoder { - MAKE_NONCOPYABLE(URLEncoder); - public: - URLEncoder() {} - virtual ~URLEncoder() {} - - /** - * Produce a URL-safe but equivalent version of the input string. - * - * @param s input string to encode - * @return a string object containing the result of encoding the input - */ - virtual std::string encode(const char* s) const; - - /** - * Perform an in-place decoding operation on the input string. - * The resulting string will be NULL-terminated. - * - * @param s input string to decode in a writable buffer - */ - virtual void decode(char* s) const; - - protected: - /** - * Returns true iff the input character requires encoding. - * - * @param ch the character to check - * @return true iff the character should be encoded - */ - virtual bool isBad(char ch) const { - static char badchars[]="=&/?:\"\\+<>#%{}|^~[]`;@"; - return (strchr(badchars,ch) || ch<=0x20 || ch>=0x7F); - } - }; -}; - -#endif /* __saml_urlenc_h__ */ diff --git a/saml/binding/impl/URLEncoder.cpp b/saml/binding/impl/URLEncoder.cpp deleted file mode 100644 index 45c1151..0000000 --- a/saml/binding/impl/URLEncoder.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2001-2007 Internet2 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * URLEncoder.cpp - * - * Interface to a URL-encoding mechanism along with a - * default implementation. - */ - -#include "internal.h" -#include "binding/URLEncoder.h" - -using namespace opensaml; -using namespace std; - -static char x2c(char *what) -{ - register char digit; - - digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0')); - digit *= 16; - digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0')); - return(digit); -} - -void URLEncoder::decode(char* s) const -{ - register int x,y; - - for(x=0,y=0;s[y];++x,++y) - { - if((s[x] = s[y]) == '%') - { - s[x] = x2c(&s[y+1]); - y+=2; - } - else if (s[x] == '+') - { - s[x] = ' '; - } - } - s[x] = '\0'; -} - -static inline char hexchar(unsigned short s) -{ - return (s<=9) ? ('0' + s) : ('A' + s - 10); -} - -string URLEncoder::encode(const char* s) const -{ - string ret; - for (; *s; s++) { - if (isBad(*s)) { - ret+='%'; - ret+=hexchar((unsigned char)*s >> 4); - ret+=hexchar((unsigned char)*s & 0x0F); - } - else - ret+=*s; - } - return ret; -} diff --git a/saml/saml.vcproj b/saml/saml.vcproj index fe706da..8681d6a 100644 --- a/saml/saml.vcproj +++ b/saml/saml.vcproj @@ -554,10 +554,6 @@ > - - @@ -848,10 +844,6 @@ RelativePath=".\binding\SOAPClient.h" > - - +#include #include +#include using namespace opensaml::saml1; using namespace opensaml::saml1p; @@ -113,7 +114,7 @@ long SAML1ArtifactEncoder::encode( // Generate redirect. string loc = destination; loc += (strchr(destination,'?') ? '&' : '?'); - URLEncoder* escaper = SAMLConfig::getConfig().getURLEncoder(); + const URLEncoder* escaper = XMLToolingConfig::getConfig().getURLEncoder(); loc = loc + "SAMLart=" + escaper->encode(artifact->encode().c_str()) + "&TARGET=" + escaper->encode(relayState); log.debug("message encoded, sending redirect to client"); return httpResponse->sendRedirect(loc.c_str()); diff --git a/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp b/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp index 17d5880..f142132 100644 --- a/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp @@ -25,7 +25,6 @@ #include "binding/ArtifactMap.h" #include "binding/HTTPResponse.h" #include "binding/MessageEncoder.h" -#include "binding/URLEncoder.h" #include "saml2/binding/SAML2Artifact.h" #include "saml2/core/Protocols.h" @@ -34,6 +33,7 @@ #include #include #include +#include using namespace opensaml::saml2p; using namespace opensaml; @@ -152,7 +152,7 @@ long SAML2ArtifactEncoder::encode( // Generate redirect. string loc = destination; loc += (strchr(destination,'?') ? '&' : '?'); - URLEncoder* escaper = SAMLConfig::getConfig().getURLEncoder(); + const URLEncoder* escaper = XMLToolingConfig::getConfig().getURLEncoder(); loc = loc + "SAMLart=" + escaper->encode(artifact->encode().c_str()); if (relayState) loc = loc + "&RelayState=" + escaper->encode(relayState); diff --git a/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp b/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp index c4806f2..82308f9 100644 --- a/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp @@ -24,7 +24,6 @@ #include "exceptions.h" #include "binding/HTTPResponse.h" #include "binding/MessageEncoder.h" -#include "binding/URLEncoder.h" #include "saml2/binding/SAML2Redirect.h" #include "saml2/core/Protocols.h" @@ -33,6 +32,7 @@ #include #include #include +#include using namespace opensaml::saml2p; using namespace opensaml; @@ -119,7 +119,7 @@ long SAML2RedirectEncoder::encode( throw BindingException("Base64 encoding of XML failed."); // Create beginnings of redirect query string. - URLEncoder* escaper = SAMLConfig::getConfig().getURLEncoder(); + const URLEncoder* escaper = XMLToolingConfig::getConfig().getURLEncoder(); xmlbuf.erase(); xmlbuf.append(reinterpret_cast(encoded),len); xmlbuf = (request ? "SAMLRequest=" : "SAMLResponse=") + escaper->encode(xmlbuf.c_str()); diff --git a/saml/util/CGIParser.cpp b/saml/util/CGIParser.cpp index 390311a..b668643 100644 --- a/saml/util/CGIParser.cpp +++ b/saml/util/CGIParser.cpp @@ -21,11 +21,13 @@ */ #include "internal.h" -#include "SAMLConfig.h" -#include "binding/URLEncoder.h" #include "util/CGIParser.h" +#include +#include + using namespace opensaml; +using namespace xmltooling; using namespace std; @@ -38,7 +40,7 @@ CGIParser::CGIParser(const HTTPRequest& request) pch=request.getQueryString(); size_t cl=pch ? strlen(pch) : 0; - URLEncoder* dec = SAMLConfig::getConfig().getURLEncoder(); + const URLEncoder* dec = XMLToolingConfig::getConfig().getURLEncoder(); while (cl && pch) { char *name; char *value; diff --git a/saml/util/CommonDomainCookie.cpp b/saml/util/CommonDomainCookie.cpp index 9a18faf..a8350e4 100644 --- a/saml/util/CommonDomainCookie.cpp +++ b/saml/util/CommonDomainCookie.cpp @@ -1,98 +1,100 @@ -/* - * Copyright 2001-2007 Internet2 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * CommonDomainCookie.cpp - * - * Helper class for maintaining discovery cookie. - */ - -#include "internal.h" -#include "binding/URLEncoder.h" -#include "util/CommonDomainCookie.h" - -#include - -using namespace opensaml; -using namespace std; - -const char CommonDomainCookie::CDCName[] = "_saml_idp"; - -CommonDomainCookie::CommonDomainCookie(const char* cookie) -{ - if (!cookie) - return; - - // Copy it so we can URL-decode it. - char* b64=strdup(cookie); - SAMLConfig::getConfig().getURLEncoder()->decode(b64); - - // Chop it up and save off elements. - vector templist; - char* ptr=b64; - while (*ptr) { - while (*ptr && isspace(*ptr)) ptr++; - char* end=ptr; - while (*end && !isspace(*end)) end++; - templist.push_back(string(ptr,end-ptr)); - ptr=end; - } - free(b64); - - // Now Base64 decode the list. - unsigned int len; - for (vector::iterator i=templist.begin(); i!=templist.end(); ++i) { - XMLByte* decoded=Base64::decode(reinterpret_cast(i->c_str()),&len); - if (decoded && *decoded) { - m_list.push_back(reinterpret_cast(decoded)); - XMLString::release(&decoded); - } - } -} - -const char* CommonDomainCookie::set(const char* entityID) -{ - // First scan the list for this IdP. - for (vector::iterator i=m_list.begin(); i!=m_list.end(); i++) { - if (*i == entityID) { - m_list.erase(i); - break; - } - } - - // Append it to the end. - m_list.push_back(entityID); - - // Now rebuild the delimited list. - unsigned int len; - string delimited; - for (vector::const_iterator j=m_list.begin(); j!=m_list.end(); j++) { - if (!delimited.empty()) delimited += ' '; - - XMLByte* b64=Base64::encode(reinterpret_cast(j->c_str()),j->length(),&len); - XMLByte *pos, *pos2; - for (pos=b64, pos2=b64; *pos2; pos2++) - if (isgraph(*pos2)) - *pos++=*pos2; - *pos=0; - - delimited += reinterpret_cast(b64); - XMLString::release(&b64); - } - - m_encoded=SAMLConfig::getConfig().getURLEncoder()->encode(delimited.c_str()); - return m_encoded.c_str(); -} +/* + * Copyright 2001-2007 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * CommonDomainCookie.cpp + * + * Helper class for maintaining discovery cookie. + */ + +#include "internal.h" +#include "util/CommonDomainCookie.h" + +#include +#include +#include + +using namespace opensaml; +using namespace xmltooling; +using namespace std; + +const char CommonDomainCookie::CDCName[] = "_saml_idp"; + +CommonDomainCookie::CommonDomainCookie(const char* cookie) +{ + if (!cookie) + return; + + // Copy it so we can URL-decode it. + char* b64=strdup(cookie); + XMLToolingConfig::getConfig().getURLEncoder()->decode(b64); + + // Chop it up and save off elements. + vector templist; + char* ptr=b64; + while (*ptr) { + while (*ptr && isspace(*ptr)) ptr++; + char* end=ptr; + while (*end && !isspace(*end)) end++; + templist.push_back(string(ptr,end-ptr)); + ptr=end; + } + free(b64); + + // Now Base64 decode the list. + unsigned int len; + for (vector::iterator i=templist.begin(); i!=templist.end(); ++i) { + XMLByte* decoded=Base64::decode(reinterpret_cast(i->c_str()),&len); + if (decoded && *decoded) { + m_list.push_back(reinterpret_cast(decoded)); + XMLString::release(&decoded); + } + } +} + +const char* CommonDomainCookie::set(const char* entityID) +{ + // First scan the list for this IdP. + for (vector::iterator i=m_list.begin(); i!=m_list.end(); i++) { + if (*i == entityID) { + m_list.erase(i); + break; + } + } + + // Append it to the end. + m_list.push_back(entityID); + + // Now rebuild the delimited list. + unsigned int len; + string delimited; + for (vector::const_iterator j=m_list.begin(); j!=m_list.end(); j++) { + if (!delimited.empty()) delimited += ' '; + + XMLByte* b64=Base64::encode(reinterpret_cast(j->c_str()),j->length(),&len); + XMLByte *pos, *pos2; + for (pos=b64, pos2=b64; *pos2; pos2++) + if (isgraph(*pos2)) + *pos++=*pos2; + *pos=0; + + delimited += reinterpret_cast(b64); + XMLString::release(&b64); + } + + m_encoded=XMLToolingConfig::getConfig().getURLEncoder()->encode(delimited.c_str()); + return m_encoded.c_str(); +} diff --git a/samltest/binding.h b/samltest/binding.h index f50ad41..3355144 100644 --- a/samltest/binding.h +++ b/samltest/binding.h @@ -22,10 +22,10 @@ #include #include #include -#include #include #include #include +#include using namespace opensaml::saml2md; using namespace opensaml; @@ -213,7 +213,7 @@ public: pch=strchr(pch,'&'); if (pch) *pch++=0; - SAMLConfig::getConfig().getURLEncoder()->decode(value); + XMLToolingConfig::getConfig().getURLEncoder()->decode(value); m_fields[name] = value; name = pch; } -- 2.1.4