From cbe19fb62c2c614f666dc2b8282d0bcc9411153d Mon Sep 17 00:00:00 2001 From: cantor Date: Thu, 3 Dec 2009 20:36:33 +0000 Subject: [PATCH] Tagging 1.3.3 release. git-svn-id: https://svn.middleware.georgetown.edu/cpp-xmltooling/tags/1.3.3@690 de75baf8-a10c-0410-a50a-987c0e22f00f --- .cproject | 8 ++++ config_win32.h | 6 +-- configure.ac | 4 +- doc/README.txt | 8 ++-- xmltooling/AbstractXMLObject.cpp | 14 +++--- xmltooling/Makefile.am | 4 +- xmltooling/XMLToolingConfig.cpp | 5 ++ xmltooling/encryption/Decrypter.h | 1 + xmltooling/io/HTTPResponse.cpp | 54 +++++++++++++++++++++- xmltooling/io/HTTPResponse.h | 43 +++++++++++++++-- xmltooling/security/impl/CredentialCriteria.cpp | 31 ++++++++++--- .../security/impl/FilesystemCredentialResolver.cpp | 23 +++++++-- xmltooling/soap/OpenSSLSOAPTransport.h | 2 +- xmltooling/soap/impl/CURLSOAPTransport.cpp | 21 --------- xmltooling/soap/impl/SOAPClient.cpp | 22 +++++++++ xmltooling/version.h | 4 +- xmltooling/xmltooling-lite.vcproj | 4 -- xmltooling/xmltooling.rc | 10 ++-- 18 files changed, 195 insertions(+), 69 deletions(-) diff --git a/.cproject b/.cproject index 34bcb9d..b7338db 100644 --- a/.cproject +++ b/.cproject @@ -60,6 +60,14 @@ + diff --git a/config_win32.h b/config_win32.h index 20e9b0a..c79070c 100644 --- a/config_win32.h +++ b/config_win32.h @@ -90,13 +90,13 @@ #define PACKAGE_NAME "xmltooling" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "xmltooling 1.3" +#define PACKAGE_STRING "xmltooling 1.3.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "xmltooling" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.3" +#define PACKAGE_VERSION "1.3.3" /* Define to the necessary symbol if this constant uses a non-standard name on your system. */ @@ -109,7 +109,7 @@ /* #undef TM_IN_SYS_TIME */ /* Version number of package */ -#define VERSION "1.3" +#define VERSION "1.3.3" /* Define if you wish to disable XML-Security-dependent features. */ /* #undef XMLTOOLING_NO_XMLSEC */ diff --git a/configure.ac b/configure.ac index 7e0d730..f3d834b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ AC_PREREQ([2.50]) -AC_INIT([xmltooling], [1.3], [mace-opensaml-users@internet2.edu], [xmltooling]) +AC_INIT([xmltooling], [1.3.3], [mace-opensaml-users@internet2.edu], [xmltooling]) AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(xmltooling/config_pub.h) -AM_INIT_AUTOMAKE([xmltooling], [1.3]) +AM_INIT_AUTOMAKE([xmltooling], [1.3.3]) sinclude(doxygen.m4) sinclude(acx_pthread.m4) diff --git a/doc/README.txt b/doc/README.txt index dcc7238..9f19503 100644 --- a/doc/README.txt +++ b/doc/README.txt @@ -1,8 +1,8 @@ -VERSION 1.3 +VERSION 1.3.3 -Issues addressed by this release: ---------------------------------- -https://bugs.internet2.edu/jira/browse/CPPXT/fixforversion/10253 +Change Log: +----------- +https://bugs.internet2.edu/jira/browse/CPPXT Documentation: -------------- diff --git a/xmltooling/AbstractXMLObject.cpp b/xmltooling/AbstractXMLObject.cpp index 491aaa8..58efeda 100644 --- a/xmltooling/AbstractXMLObject.cpp +++ b/xmltooling/AbstractXMLObject.cpp @@ -42,18 +42,14 @@ XMLObject::~XMLObject() void XMLObject::releaseThisandParentDOM() const { - if (getDOM()) { - releaseDOM(); - releaseParentDOM(true); - } + releaseDOM(); + releaseParentDOM(true); } void XMLObject::releaseThisAndChildrenDOM() const { - if (getDOM()) { - releaseChildrenDOM(true); - releaseDOM(); - } + releaseChildrenDOM(true); + releaseDOM(); } AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) @@ -248,6 +244,8 @@ DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const XMLC { delete oldValue; releaseThisandParentDOM(); + if (!newValue || !*newValue) + return NULL; DateTime* ret = new DateTime(newValue); if (duration) ret->parseDuration(); diff --git a/xmltooling/Makefile.am b/xmltooling/Makefile.am index 374cf1b..bbc0ff9 100644 --- a/xmltooling/Makefile.am +++ b/xmltooling/Makefile.am @@ -198,10 +198,10 @@ common_sources = \ libxmltooling_lite_la_SOURCES = \ ${common_sources} libxmltooling_lite_la_CPPFLAGS = -DXMLTOOLING_LITE -libxmltooling_lite_la_LDFLAGS = -version-info 4:0:0 +libxmltooling_lite_la_LDFLAGS = -version-info 4:3:0 if BUILD_XMLSEC -libxmltooling_la_LDFLAGS = $(XMLSEC_LIBS) -version-info 4:0:0 +libxmltooling_la_LDFLAGS = $(XMLSEC_LIBS) -version-info 4:3:0 libxmltooling_la_SOURCES = \ ${common_sources} \ ${xmlsec_sources} diff --git a/xmltooling/XMLToolingConfig.cpp b/xmltooling/XMLToolingConfig.cpp index 9a43921..cadf7bc 100644 --- a/xmltooling/XMLToolingConfig.cpp +++ b/xmltooling/XMLToolingConfig.cpp @@ -27,6 +27,7 @@ #include "encryption/Encryption.h" #include "encryption/Encrypter.h" #include "impl/UnknownElement.h" +#include "io/HTTPResponse.h" #include "security/TrustEngine.h" #include "security/OpenSSLCryptoX509CRL.h" #include "security/CredentialResolver.h" @@ -56,6 +57,7 @@ # include #endif #include +#include #ifndef XMLTOOLING_NO_XMLSEC # include # include @@ -352,6 +354,9 @@ bool XMLToolingInternalConfig::init() m_pathResolver = new PathResolver(); m_urlEncoder = new URLEncoder(); + HTTPResponse::getAllowedSchemes().push_back("https"); + HTTPResponse::getAllowedSchemes().push_back("http"); + // Register xml:id as an ID attribute. static const XMLCh xmlid[] = UNICODE_LITERAL_2(i,d); AttributeExtensibleXMLObject::registerIDAttribute(QName(xmlconstants::XML_NS, xmlid)); diff --git a/xmltooling/encryption/Decrypter.h b/xmltooling/encryption/Decrypter.h index 8d2b574..d8e2586 100644 --- a/xmltooling/encryption/Decrypter.h +++ b/xmltooling/encryption/Decrypter.h @@ -26,6 +26,7 @@ #include class XENCCipher; +class XSECCryptoKey; namespace xmltooling { class XMLTOOL_API CredentialCriteria; diff --git a/xmltooling/io/HTTPResponse.cpp b/xmltooling/io/HTTPResponse.cpp index ab2255a..63a3dfc 100644 --- a/xmltooling/io/HTTPResponse.cpp +++ b/xmltooling/io/HTTPResponse.cpp @@ -24,7 +24,7 @@ #include "HTTPResponse.h" using namespace xmltooling; -using std::istream; +using namespace std; GenericResponse::GenericResponse() { @@ -34,6 +34,37 @@ GenericResponse::~GenericResponse() { } +vector HTTPResponse::m_allowedSchemes; + +vector& HTTPResponse::getAllowedSchemes() +{ + return m_allowedSchemes; +} + +void HTTPResponse::sanitizeURL(const char* url) +{ + const char* ch; + for (ch=url; *ch; ++ch) { + if (iscntrl(*ch)) + throw IOException("URL contained a control character."); + } + + ch = strchr(url, ':'); + if (!ch) + throw IOException("URL is malformed."); + string s(url, ch - url); + for (vector::const_iterator i = m_allowedSchemes.begin(); i != m_allowedSchemes.end(); ++i) { +#ifdef HAVE_STRCASECMP + if (!strcasecmp(s.c_str(), i->c_str())) +#else + if (!stricmp(s.c_str(), i->c_str())) +#endif + return; + } + + throw IOException("URL contains invalid scheme ($1).", params(1, s.c_str())); +} + HTTPResponse::HTTPResponse() { } @@ -49,11 +80,30 @@ void HTTPResponse::setContentType(const char* type) void HTTPResponse::setCookie(const char* name, const char* value) { - std::string cookie(name); + string cookie(name); cookie = cookie + '=' + value; setResponseHeader("Set-Cookie", cookie.c_str()); } +void HTTPResponse::setResponseHeader(const char* name, const char* value) +{ + for (const char* ch=name; *ch; ++ch) { + if (iscntrl(*ch)) + throw IOException("Response header name contained a control character."); + } + + for (const char* ch=value; *ch; ++ch) { + if (iscntrl(*ch)) + throw IOException("Value for response header ($1) contained a control character.", params(1,name)); + } +} + +long HTTPResponse::sendRedirect(const char* url) +{ + sanitizeURL(url); + return XMLTOOLING_HTTP_STATUS_MOVED; +} + long HTTPResponse::sendError(istream& inputStream) { return sendResponse(inputStream, XMLTOOLING_HTTP_STATUS_ERROR); diff --git a/xmltooling/io/HTTPResponse.h b/xmltooling/io/HTTPResponse.h index 6c38321..912c0f8 100644 --- a/xmltooling/io/HTTPResponse.h +++ b/xmltooling/io/HTTPResponse.h @@ -25,8 +25,16 @@ #include +#include +#include + namespace xmltooling { - + +#if defined (_MSC_VER) + #pragma warning( push ) + #pragma warning( disable : 4251 ) +#endif + /** * Interface to HTTP response. * @@ -50,7 +58,7 @@ namespace xmltooling { * @param name header name * @param value value to set, or NULL to clear */ - virtual void setResponseHeader(const char* name, const char* value)=0; + virtual void setResponseHeader(const char* name, const char* value); /** * Sets a client cookie. @@ -62,12 +70,15 @@ namespace xmltooling { /** * Redirect the client to the specified URL and complete the response. - * Any headers previously set will be sent ahead of the redirect. * + *

Any headers previously set will be sent ahead of the redirect. + * + *

The URL will be validated with the sanitizeURL method below. + * * @param url location to redirect client * @return a result code to return from the calling MessageEncoder */ - virtual long sendRedirect(const char* url)=0; + virtual long sendRedirect(const char* url); /** Some common HTTP status codes. */ enum status_t { @@ -83,7 +94,31 @@ namespace xmltooling { using GenericResponse::sendResponse; long sendResponse(std::istream& inputStream); + + /** + * Returns a modifiable array of schemes to permit in sanitized URLs. + * + *

Updates to this array must be externally synchronized with any use + * of this class or its subclasses. + * + * @return a mutable array of strings containing the schemes to permit + */ + static std::vector& getAllowedSchemes(); + + /** + * Manually check for unsafe URLs vulnerable to injection attacks. + * + * @param url location to check + */ + static void sanitizeURL(const char* url); + + private: + static std::vector m_allowedSchemes; }; + +#if defined (_MSC_VER) + #pragma warning( pop ) +#endif }; #endif /* __xmltooling_httpres_h__ */ diff --git a/xmltooling/security/impl/CredentialCriteria.cpp b/xmltooling/security/impl/CredentialCriteria.cpp index 2e9a635..6fbcd92 100644 --- a/xmltooling/security/impl/CredentialCriteria.cpp +++ b/xmltooling/security/impl/CredentialCriteria.cpp @@ -37,6 +37,7 @@ using xmlsignature::KeyInfo; using xmlsignature::Signature; +using namespace xmltooling::logging; using namespace xmltooling; using namespace std; @@ -191,25 +192,37 @@ void CredentialCriteria::setSignature(const Signature& sig, int extraction) bool CredentialCriteria::matches(const Credential& credential) const { + Category& log = Category::getInstance(XMLTOOLING_LOGCAT".CredentialCriteria"); + // Usage check, if specified and we have one, compare masks. if (getUsage() != Credential::UNSPECIFIED_CREDENTIAL) { if (credential.getUsage() != Credential::UNSPECIFIED_CREDENTIAL) - if ((getUsage() & credential.getUsage()) == 0) + if ((getUsage() & credential.getUsage()) == 0) { + if (log.isDebugEnabled()) + log.debug("usage didn't match (%u != %u)", getUsage(), credential.getUsage()); return false; + } } // Algorithm check, if specified and we have one. const char* alg = getKeyAlgorithm(); if (alg && *alg) { const char* alg2 = credential.getAlgorithm(); - if (alg2 && *alg2) - if (strcmp(alg,alg2)) + if (alg2 && *alg2) { + if (strcmp(alg,alg2)) { + if (log.isDebugEnabled()) + log.debug("key algorithm didn't match ('%s' != '%s')", getKeyAlgorithm(), credential.getAlgorithm()); return false; + } + } } // KeySize check, if specified and we have one. - if (credential.getKeySize()>0 && getKeySize()>0 && credential.getKeySize() != getKeySize()) + if (credential.getKeySize()>0 && getKeySize()>0 && credential.getKeySize() != getKeySize()) { + if (log.isDebugEnabled()) + log.debug("key size didn't match (%u != %u)", getKeySize(), credential.getKeySize()); return false; + } // See if we can test key names. set critnames = getKeyNames(); @@ -224,8 +237,10 @@ bool CredentialCriteria::matches(const Credential& credential) const break; } } - if (!found) + if (!found) { + log.debug("credential name(s) didn't overlap"); return false; + } } // See if we have to match a specific key. @@ -239,5 +254,9 @@ bool CredentialCriteria::matches(const Credential& credential) const if (!key2) return true; // no key here, so we can't test it - return SecurityHelper::matches(*key1, *key2); + if (SecurityHelper::matches(*key1, *key2)) + return true; + + log.debug("keys didn't match"); + return false; } diff --git a/xmltooling/security/impl/FilesystemCredentialResolver.cpp b/xmltooling/security/impl/FilesystemCredentialResolver.cpp index 42b6ed0..541057e 100644 --- a/xmltooling/security/impl/FilesystemCredentialResolver.cpp +++ b/xmltooling/security/impl/FilesystemCredentialResolver.cpp @@ -209,7 +209,6 @@ namespace xmltooling { class XMLTOOL_DLLLOCAL FilesystemCredential; class XMLTOOL_DLLLOCAL FilesystemCredentialResolver : public CredentialResolver { - friend class XMLTOOL_DLLLOCAL FilesystemCredential; public: FilesystemCredentialResolver(const DOMElement* e); virtual ~FilesystemCredentialResolver(); @@ -232,11 +231,14 @@ namespace xmltooling { Credential* m_credential; string m_keypass,m_certpass; unsigned int m_keyinfomask,m_usage; + bool m_extractNames; vector m_keynames; ManagedKey m_key; vector m_certs; vector m_crls; + + friend class XMLTOOL_DLLLOCAL FilesystemCredential; }; #if defined (_MSC_VER) @@ -248,9 +250,13 @@ namespace xmltooling { { public: FilesystemCredential( - FilesystemCredentialResolver* resolver, XSECCryptoKey* key, const vector& xseccerts, const vector& crls + FilesystemCredentialResolver* resolver, + XSECCryptoKey* key, + const vector& xseccerts, + const vector& crls ) : BasicX509Credential(key ? key : (xseccerts.empty() ? NULL : xseccerts.front()->clonePublicKey()), xseccerts, crls), m_resolver(resolver) { - extract(); + if (m_resolver->m_extractNames) + extract(); m_keyNames.insert(m_resolver->m_keynames.begin(), m_resolver->m_keynames.end()); } @@ -286,6 +292,7 @@ namespace xmltooling { static const XMLCh Certificate[] = UNICODE_LITERAL_11(C,e,r,t,i,f,i,c,a,t,e); static const XMLCh _certificate[] = UNICODE_LITERAL_11(c,e,r,t,i,f,i,c,a,t,e); static const XMLCh CRL[] = UNICODE_LITERAL_3(C,R,L); + static const XMLCh extractNames[] = UNICODE_LITERAL_12(e,x,t,r,a,c,t,N,a,m,e,s); static const XMLCh _format[] = UNICODE_LITERAL_6(f,o,r,m,a,t); static const XMLCh Key[] = UNICODE_LITERAL_3(K,e,y); static const XMLCh _key[] = UNICODE_LITERAL_3(k,e,y); @@ -301,7 +308,7 @@ namespace xmltooling { }; FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e) - : m_lock(NULL), m_credential(NULL), m_usage(Credential::UNSPECIFIED_CREDENTIAL) + : m_lock(NULL), m_credential(NULL), m_usage(Credential::UNSPECIFIED_CREDENTIAL), m_extractNames(true) { #ifdef _DEBUG NDC ndc("FilesystemCredentialResolver"); @@ -342,6 +349,8 @@ FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e) path = e->getOwnerDocument()->createElementNS(NULL,Path); child->appendChild(path); path->appendChild(e->getOwnerDocument()->createTextNode(e->getAttributeNS(NULL,_certificate))); + if (e->hasAttributeNS(NULL, extractNames)) + child->setAttributeNS(NULL, extractNames, e->getAttributeNS(NULL, extractNames)); } e = dummy; // reset "root" to the dummy config element } @@ -349,7 +358,7 @@ FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e) const XMLCh* prop; const DOMElement* root = e; - // Save off usage flags. + // Save off usage bits. const XMLCh* usage = root->getAttributeNS(NULL,_use); if (usage && *usage) { auto_ptr_char u(usage); @@ -484,6 +493,10 @@ FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e) const XMLCh* certformat = certnode->getAttributeNS(NULL,_format); + const XMLCh* extractFlag = certnode->getAttributeNS(NULL, extractNames); + if (extractFlag && (*extractFlag == chLatin_f || *extractFlag == chDigit_0)) + m_extractNames = false; + e = XMLHelper::getFirstChildElement(certnode); while (e) { if (e->hasChildNodes() && (XMLString::equals(e->getLocalName(), Path) || XMLString::equals(e->getLocalName(), CAPath))) { diff --git a/xmltooling/soap/OpenSSLSOAPTransport.h b/xmltooling/soap/OpenSSLSOAPTransport.h index eb38ef0..21a2045 100644 --- a/xmltooling/soap/OpenSSLSOAPTransport.h +++ b/xmltooling/soap/OpenSSLSOAPTransport.h @@ -20,7 +20,7 @@ * Encapsulates OpenSSL-capable SOAP transport layer. */ -#ifndef __xmltooling_opensslsoaptrans_h__ +#if !defined(__xmltooling_opensslsoaptrans_h__) && !defined(XMLTOOLING_NO_XMLSEC) #define __xmltooling_opensslsoaptrans_h__ #include diff --git a/xmltooling/soap/impl/CURLSOAPTransport.cpp b/xmltooling/soap/impl/CURLSOAPTransport.cpp index 460a62e..af06fbb 100644 --- a/xmltooling/soap/impl/CURLSOAPTransport.cpp +++ b/xmltooling/soap/impl/CURLSOAPTransport.cpp @@ -271,27 +271,6 @@ void xmltooling::termSOAPTransports() g_CURLPool = NULL; } -SOAPTransport::SOAPTransport() -{ -} - -SOAPTransport::~SOAPTransport() -{ -} - -bool SOAPTransport::setProviderOption(const char* provider, const char* option, const char* value) -{ - return false; -} - -HTTPSOAPTransport::HTTPSOAPTransport() -{ -} - -HTTPSOAPTransport::~HTTPSOAPTransport() -{ -} - OpenSSLSOAPTransport::OpenSSLSOAPTransport() { } diff --git a/xmltooling/soap/impl/SOAPClient.cpp b/xmltooling/soap/impl/SOAPClient.cpp index 8eaeaed..1978e28 100644 --- a/xmltooling/soap/impl/SOAPClient.cpp +++ b/xmltooling/soap/impl/SOAPClient.cpp @@ -23,6 +23,7 @@ #include "internal.h" #include "exceptions.h" #include "logging.h" +#include "soap/HTTPSOAPTransport.h" #include "soap/SOAP.h" #include "soap/SOAPClient.h" #include "util/XMLHelper.h" @@ -36,6 +37,27 @@ using namespace xmltooling; using namespace xercesc; using namespace std; +SOAPTransport::SOAPTransport() +{ +} + +SOAPTransport::~SOAPTransport() +{ +} + +bool SOAPTransport::setProviderOption(const char* provider, const char* option, const char* value) +{ + return false; +} + +HTTPSOAPTransport::HTTPSOAPTransport() +{ +} + +HTTPSOAPTransport::~HTTPSOAPTransport() +{ +} + SOAPClient::SOAPClient(bool validate) : m_validate(validate), m_transport(NULL) { } diff --git a/xmltooling/version.h b/xmltooling/version.h index 63af4d6..abe4556 100644 --- a/xmltooling/version.h +++ b/xmltooling/version.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 Internet2 + * Copyright 2001-2009 Internet2 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,7 @@ #define XMLTOOLING_VERSION_MAJOR 1 #define XMLTOOLING_VERSION_MINOR 3 -#define XMLTOOLING_VERSION_REVISION 0 +#define XMLTOOLING_VERSION_REVISION 3 /** DO NOT MODIFY BELOW THIS LINE */ diff --git a/xmltooling/xmltooling-lite.vcproj b/xmltooling/xmltooling-lite.vcproj index ca08327..8968c23 100644 --- a/xmltooling/xmltooling-lite.vcproj +++ b/xmltooling/xmltooling-lite.vcproj @@ -692,10 +692,6 @@ > - - diff --git a/xmltooling/xmltooling.rc b/xmltooling/xmltooling.rc index 5b6d55f..6462cf3 100644 --- a/xmltooling/xmltooling.rc +++ b/xmltooling/xmltooling.rc @@ -28,8 +28,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,3,0,0 - PRODUCTVERSION 2,2,1,0 + FILEVERSION 1,3,3,0 + PRODUCTVERSION 2,3,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,7 +51,7 @@ BEGIN #else VALUE "FileDescription", "OpenSAML XMLTooling Library\0" #endif - VALUE "FileVersion", "1, 3, 0, 0\0" + VALUE "FileVersion", "1, 3, 3, 0\0" #ifdef XMLTOOLING_LITE #ifdef _DEBUG VALUE "InternalName", "xmltooling-lite1_3D\0" @@ -81,8 +81,8 @@ BEGIN #endif #endif VALUE "PrivateBuild", "\0" - VALUE "ProductName", "OpenSAML 2.2.1\0" - VALUE "ProductVersion", "2, 2, 1, 0\0" + VALUE "ProductName", "OpenSAML 2.3\0" + VALUE "ProductVersion", "2, 3, 0, 0\0" VALUE "SpecialBuild", "\0" END END -- 2.1.4