From: Scott Cantor Date: Sat, 6 Jun 2009 21:00:33 +0000 (+0000) Subject: Add option to make attributes internal only. X-Git-Tag: 2.2.0~19 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-sp.git;a=commitdiff_plain;h=4f26b89a8caae6c503490a37936562b178834f60 Add option to make attributes internal only. --- diff --git a/.cproject b/.cproject index 6cfb24b..fbbebfe 100644 --- a/.cproject +++ b/.cproject @@ -18,7 +18,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -58,6 +142,7 @@ + diff --git a/.project b/.project index 404625c..4dea911 100644 --- a/.project +++ b/.project @@ -2,58 +2,102 @@ cpp-sp + + org.eclipse.cdt.make.core.makeBuilder + org.eclipse.cdt.core.errorOutputParser org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.VCErrorParser; - org.eclipse.cdt.make.core.fullBuildTarget - clean all + org.eclipse.cdt.make.core.append_environment + true - org.eclipse.cdt.make.core.incrementalBuildTarget + org.eclipse.cdt.make.core.autoBuildTarget all - org.eclipse.cdt.make.core.enableAutoBuild - false + org.eclipse.cdt.make.core.build.arguments + + + + org.eclipse.cdt.make.core.build.command + nmake + + + org.eclipse.cdt.make.core.build.location + + + + org.eclipse.cdt.make.core.build.target.auto + all + + + org.eclipse.cdt.make.core.build.target.clean + + + + org.eclipse.cdt.make.core.build.target.inc + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + nmake org.eclipse.cdt.make.core.buildLocation - org.eclipse.cdt.make.core.enableFullBuild + org.eclipse.cdt.make.core.enableAutoBuild false - org.eclipse.cdt.make.core.enabledIncrementalBuild + org.eclipse.cdt.make.core.enableCleanBuild false - org.eclipse.cdt.make.core.useDefaultBuildCmd + org.eclipse.cdt.make.core.enableFullBuild false - org.eclipse.cdt.make.core.buildArguments + org.eclipse.cdt.make.core.enabledIncrementalBuild + false + + + org.eclipse.cdt.make.core.environment - org.eclipse.cdt.make.core.buildCommand - nmake + org.eclipse.cdt.make.core.fullBuildTarget + clean all - org.eclipse.cdt.make.core.autoBuildTarget + org.eclipse.cdt.make.core.incrementalBuildTarget all org.eclipse.cdt.make.core.stopOnError false + + org.eclipse.cdt.make.core.useDefaultBuildCmd + false + + + + + org.eclipse.cdt.make.core.ScannerConfigBuilder + @@ -61,5 +105,6 @@ org.eclipse.cdt.core.cnature org.eclipse.cdt.make.core.makeNature org.eclipse.cdt.core.ccnature + org.eclipse.cdt.make.core.ScannerConfigNature diff --git a/schemas/shibboleth-2.0-attribute-map.xsd b/schemas/shibboleth-2.0-attribute-map.xsd index d5533f0..caf5e1e 100644 --- a/schemas/shibboleth-2.0-attribute-map.xsd +++ b/schemas/shibboleth-2.0-attribute-map.xsd @@ -92,6 +92,11 @@ + + + Flag controlling whether the resulting attribute should be exported for CGI use. + + diff --git a/shibsp/ServiceProvider.cpp b/shibsp/ServiceProvider.cpp index 69afa28..552fc09 100644 --- a/shibsp/ServiceProvider.cpp +++ b/shibsp/ServiceProvider.cpp @@ -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. @@ -413,6 +413,8 @@ pair ServiceProvider::doExport(SPRequest& request, bool requireSessio // Export the attributes. const multimap& attributes = session->getIndexedAttributes(); for (multimap::const_iterator a = attributes.begin(); a!=attributes.end(); ++a) { + if (a->second->isInternal()) + continue; string header(app->getSecureHeader(request, a->first.c_str())); const vector& vals = a->second->getSerializedValues(); for (vector::const_iterator v = vals.begin(); v!=vals.end(); ++v) { diff --git a/shibsp/attribute/Attribute.cpp b/shibsp/attribute/Attribute.cpp index 4e9f674..82c7f6d 100644 --- a/shibsp/attribute/Attribute.cpp +++ b/shibsp/attribute/Attribute.cpp @@ -71,6 +71,7 @@ namespace shibsp { static const XMLCh _DOMAttributeDecoder[] = UNICODE_LITERAL_19(D,O,M,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r); static const XMLCh caseSensitive[] = UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e); + static const XMLCh internal[] = UNICODE_LITERAL_8(i,n,t,e,r,n,a,l); #endif }; @@ -93,12 +94,16 @@ void shibsp::registerAttributeDecoders() conf.AttributeDecoderManager.registerFactory(DOMAttributeDecoderType, DOMAttributeDecoderFactory); } -AttributeDecoder::AttributeDecoder(const DOMElement *e) : m_caseSensitive(true) +AttributeDecoder::AttributeDecoder(const DOMElement *e) : m_caseSensitive(true), m_internal(false) { if (e) { - const XMLCh* flag = e->getAttributeNS(NULL,caseSensitive); + const XMLCh* flag = e->getAttributeNS(NULL, caseSensitive); if (flag && (*flag == chLatin_f || *flag == chDigit_0)) m_caseSensitive = false; + + flag = e->getAttributeNS(NULL, internal); + if (flag && (*flag == chLatin_t || *flag == chDigit_1)) + m_internal = true; } } #endif @@ -114,6 +119,42 @@ void shibsp::registerAttributeFactories() map Attribute::m_factoryMap; +Attribute::Attribute(DDF& in) : m_caseSensitive(in["case_insensitive"].isnull()), m_internal(!in["internal"].isnull()) +{ + const char* id = in.first().name(); + if (id && *id) + m_id.push_back(id); + else + throw AttributeException("No id found in marshalled attribute content."); + DDF aliases = in["aliases"]; + if (aliases.islist()) { + DDF alias = aliases.first(); + while (alias.isstring()) { + m_id.push_back(alias.string()); + alias = aliases.next(); + } + } +} + +DDF Attribute::marshall() const +{ + DDF ddf(NULL); + ddf.structure().addmember(m_id.front().c_str()).list(); + if (!m_caseSensitive) + ddf.addmember("case_insensitive"); + if (m_internal) + ddf.addmember("internal"); + if (m_id.size() > 1) { + DDF alias; + DDF aliases = ddf.addmember("aliases").list(); + for (std::vector::const_iterator a = m_id.begin() + 1; a != m_id.end(); ++a) { + alias = DDF(NULL).string(a->c_str()); + aliases.add(alias); + } + } + return ddf; +} + Attribute* Attribute::unmarshall(DDF& in) { map::const_iterator i = m_factoryMap.find(in.name() ? in.name() : ""); diff --git a/shibsp/attribute/Attribute.h b/shibsp/attribute/Attribute.h index 1219681..37e1d39 100644 --- a/shibsp/attribute/Attribute.h +++ b/shibsp/attribute/Attribute.h @@ -1,6 +1,6 @@ /* - * 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. * You may obtain a copy of the License at @@ -16,7 +16,7 @@ /** * @file shibsp/attribute/Attribute.h - * + * * A resolved attribute. */ @@ -39,16 +39,16 @@ namespace shibsp { /** * A resolved attribute. - * + * *

Resolved attributes are a neutral construct that represent both simple and * complex attribute data structures that might be found in SAML assertions * or obtained from other sources. - * + * *

Attributes consist of an id/name that is locally unique (that is, unique to a * configuration at any given point in time) and zero or more values. Values can * be of any type or structure, but will generally be made available to applications * only if a serialized string form exists. More complex values can be used with - * access control plugins that understand them, however. + * access control plugins and other components that understand them, however. */ class SHIBSP_API Attribute { @@ -56,50 +56,36 @@ namespace shibsp { protected: /** * Constructor - * + * * @param ids array with primary identifier in first position, followed by any aliases */ - Attribute(const std::vector& ids) : m_id(ids), m_caseSensitive(true) { + Attribute(const std::vector& ids) : m_id(ids), m_caseSensitive(true), m_internal(false) { } /** * Constructs based on a remoted Attribute. - * + * *

This allows Attribute objects to be recreated after marshalling. * The DDF supplied must be a struct containing a single list member named * with the Attribute's "id" and containing the values. - * + * * @param in input object containing marshalled Attribute */ - Attribute(DDF& in) : m_caseSensitive(in["case_insensitive"].isnull()) { - const char* id = in.first().name(); - if (id && *id) - m_id.push_back(id); - else - throw AttributeException("No id found in marshalled attribute content."); - DDF aliases = in["aliases"]; - if (aliases.islist()) { - DDF alias = aliases.first(); - while (alias.isstring()) { - m_id.push_back(alias.string()); - alias = aliases.next(); - } - } - } - + Attribute(DDF& in); + /** * Maintains a copy of serialized attribute values, when possible. - * + * *

Implementations should maintain the array when values are added or removed. */ mutable std::vector m_serialized; public: virtual ~Attribute() {} - + /** * Returns the Attribute identifier. - * + * * @return the Attribute identifier */ const char* getId() const { @@ -134,6 +120,15 @@ namespace shibsp { } /** + * Sets whether the attribute should be exported for CGI use. + * + * @param export true iff the attribute should NOT be exported + */ + void setInternal(bool internal) { + m_internal = internal; + } + + /** * Indicates whether case sensitivity should apply to basic value comparisons. * * @return true iff value comparisons should be case sensitive @@ -141,31 +136,40 @@ namespace shibsp { bool isCaseSensitive() const { return m_caseSensitive; } - + + /** + * Indicates whether the attribute should be exported for CGI use. + * + * @return true iff the attribute should NOT be exported + */ + bool isInternal() const { + return m_internal; + } + /** * Returns the number of values. - * + * * @return number of values */ virtual size_t valueCount() const { return m_serialized.size(); } - + /** * Returns serialized Attribute values encoded as UTF-8 strings. - * + * * @return an immutable vector of values */ virtual const std::vector& getSerializedValues() const { return m_serialized; } - + /** * Informs the Attribute that values have changed and any serializations - * must be cleared. + * must be cleared. */ virtual void clearSerializedValues()=0; - + /** * Gets the string equivalent of the value at the specified position (starting from zero). * @@ -198,54 +202,40 @@ namespace shibsp { /** * Marshalls an Attribute for remoting. - * + * *

This allows Attribute objects to be communicated across process boundaries * without excess XML parsing. The DDF returned must be a struct containing * a single list member named with the Attribute's "id". The name of the struct * should contain the registered name of the Attribute implementation. */ - virtual DDF marshall() const { - DDF ddf(NULL); - ddf.structure().addmember(m_id.front().c_str()).list(); - if (!m_caseSensitive) - ddf.addmember("case_insensitive"); - if (m_id.size() > 1) { - DDF alias; - DDF aliases = ddf.addmember("aliases").list(); - for (std::vector::const_iterator a = m_id.begin() + 1; a != m_id.end(); ++a) { - alias = DDF(NULL).string(a->c_str()); - aliases.add(alias); - } - } - return ddf; - } - + virtual DDF marshall() const; + /** * Unmarshalls a remoted Attribute. - * + * * @param in remoted Attribute data - * @return a resolved Attribute of the proper subclass + * @return a resolved Attribute of the proper subclass */ static Attribute* unmarshall(DDF& in); - + /** A function that unmarshalls remoted data into the proper Attribute subclass. */ typedef Attribute* AttributeFactory(DDF& in); /** * Registers an AttributeFactory function for a given attribute "type". - * + * * @param type string used at the root of remoted Attribute structures * @param factory factory function - */ + */ static void registerFactory(const char* type, AttributeFactory* factory) { m_factoryMap[type] = factory; } /** * Deregisters an AttributeFactory function for a given attribute "type". - * + * * @param type string used at the root of remoted Attribute structures - */ + */ static void deregisterFactory(const char* type) { m_factoryMap.erase(type); } @@ -256,11 +246,11 @@ namespace shibsp { static void deregisterFactories() { m_factoryMap.clear(); } - + private: static std::map m_factoryMap; std::vector m_id; - bool m_caseSensitive; + bool m_caseSensitive,m_internal; }; #if defined (_MSC_VER) @@ -269,7 +259,7 @@ namespace shibsp { /** Registers built-in Attribute types into the runtime. */ void registerAttributeFactories(); - + }; #endif /* __shibsp_attribute_h__ */ diff --git a/shibsp/attribute/AttributeDecoder.h b/shibsp/attribute/AttributeDecoder.h index e0ad576..6a9ca7a 100644 --- a/shibsp/attribute/AttributeDecoder.h +++ b/shibsp/attribute/AttributeDecoder.h @@ -45,6 +45,21 @@ namespace shibsp { /** Flag for case sensitivity of decoded attributes. */ bool m_caseSensitive; + /** Flag for hiding attributes from CGI export. */ + bool m_internal; + + /** + * Helper method to handle base class decoding housekeeping. + * + * @param attr the new Attribute object being created + * @return the attr parameter + */ + virtual Attribute* _decode(Attribute* attr) const { + attr->setCaseSensitive(m_caseSensitive); + attr->setInternal(m_internal); + return attr; + } + public: virtual ~AttributeDecoder() {} diff --git a/shibsp/attribute/DOMAttributeDecoder.cpp b/shibsp/attribute/DOMAttributeDecoder.cpp index 8501ebb..1549690 100644 --- a/shibsp/attribute/DOMAttributeDecoder.cpp +++ b/shibsp/attribute/DOMAttributeDecoder.cpp @@ -144,7 +144,7 @@ Attribute* DOMAttributeDecoder::decode( log.warn("skipping AttributeValue without a backing DOM"); } - return dest.integer() ? attr.release() : NULL; + return dest.integer() ? _decode(attr.release()) : NULL; } DDF DOMAttributeDecoder::convert(DOMElement* e, bool nameit) const diff --git a/shibsp/attribute/ExtensibleAttribute.h b/shibsp/attribute/ExtensibleAttribute.h index f6eb446..8a12836 100644 --- a/shibsp/attribute/ExtensibleAttribute.h +++ b/shibsp/attribute/ExtensibleAttribute.h @@ -1,6 +1,6 @@ /* * Copyright 2009 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 @@ -16,7 +16,7 @@ /** * @file shibsp/attribute/ExtensibleAttribute.h - * + * * An Attribute whose values are arbitrary structures. */ @@ -41,7 +41,7 @@ namespace shibsp { public: /** * Constructor. - * + * * @param ids array with primary identifier in first position, followed by any aliases * @param formatter template for serialization of values */ @@ -53,29 +53,29 @@ namespace shibsp { /** * Constructs based on a remoted ExtensibleAttribute. - * + * * @param in input object containing marshalled ExtensibleAttribute */ ExtensibleAttribute(DDF& in) : Attribute(in), m_obj(in.copy()) { } - + virtual ~ExtensibleAttribute() { m_obj.destroy(); } - + /** * Returns the set of values in a DDF list. - * + * * @return a mutable list object containing the values */ DDF getValues() { return m_obj.first(); } - + size_t valueCount() const { return m_obj.first().integer(); } - + void clearSerializedValues() { m_serialized.clear(); } @@ -96,11 +96,15 @@ namespace shibsp { } const std::vector& getSerializedValues() const; - + DDF marshall() const { + if (!isCaseSensitive()) + m_obj.addmember("case_insensitive"); + if (isInternal()) + m_obj.addmember("internal"); return m_obj.copy(); } - + private: mutable DDF m_obj; }; diff --git a/shibsp/attribute/KeyInfoAttributeDecoder.cpp b/shibsp/attribute/KeyInfoAttributeDecoder.cpp index 0bb9f3e..3ab80f2 100644 --- a/shibsp/attribute/KeyInfoAttributeDecoder.cpp +++ b/shibsp/attribute/KeyInfoAttributeDecoder.cpp @@ -153,5 +153,5 @@ Attribute* KeyInfoAttributeDecoder::decode( } } - return dest.empty() ? NULL : attr.release(); + return dest.empty() ? NULL : _decode(attr.release()); } diff --git a/shibsp/attribute/NameIDAttributeDecoder.cpp b/shibsp/attribute/NameIDAttributeDecoder.cpp index 38ad01c..903bc33 100644 --- a/shibsp/attribute/NameIDAttributeDecoder.cpp +++ b/shibsp/attribute/NameIDAttributeDecoder.cpp @@ -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. @@ -76,7 +76,6 @@ shibsp::Attribute* NameIDAttributeDecoder::decode( auto_ptr nameid( new NameIDAttribute(ids, (m_formatter.get() && *m_formatter.get()) ? m_formatter.get() : DEFAULT_NAMEID_FORMATTER) ); - nameid->setCaseSensitive(m_caseSensitive); vector& dest = nameid->getValues(); vector::const_iterator v,stop; @@ -138,7 +137,7 @@ shibsp::Attribute* NameIDAttributeDecoder::decode( } } - return dest.empty() ? NULL : nameid.release(); + return dest.empty() ? NULL : _decode(nameid.release()); } const NameIDType* saml2name = dynamic_cast(xmlObject); @@ -167,7 +166,7 @@ shibsp::Attribute* NameIDAttributeDecoder::decode( } } - return dest.empty() ? NULL : nameid.release(); + return dest.empty() ? NULL : _decode(nameid.release()); } void NameIDAttributeDecoder::extract( diff --git a/shibsp/attribute/NameIDFromScopedAttributeDecoder.cpp b/shibsp/attribute/NameIDFromScopedAttributeDecoder.cpp index 611bd5f..ab72dfb 100644 --- a/shibsp/attribute/NameIDFromScopedAttributeDecoder.cpp +++ b/shibsp/attribute/NameIDFromScopedAttributeDecoder.cpp @@ -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. @@ -88,7 +88,6 @@ shibsp::Attribute* NameIDFromScopedAttributeDecoder::decode( auto_ptr nameid( new NameIDAttribute(ids, (m_formatter.get() && *m_formatter.get()) ? m_formatter.get() : DEFAULT_NAMEID_FORMATTER) ); - nameid->setCaseSensitive(m_caseSensitive); vector& dest = nameid->getValues(); vector::const_iterator v,stop; @@ -159,7 +158,7 @@ shibsp::Attribute* NameIDFromScopedAttributeDecoder::decode( } } - return dest.empty() ? NULL : nameid.release(); + return dest.empty() ? NULL : _decode(nameid.release()); } log.warn("XMLObject type not recognized by NameIDFromScopedAttributeDecoder, no values returned"); diff --git a/shibsp/attribute/ScopedAttributeDecoder.cpp b/shibsp/attribute/ScopedAttributeDecoder.cpp index da112b0..c3054c8 100644 --- a/shibsp/attribute/ScopedAttributeDecoder.cpp +++ b/shibsp/attribute/ScopedAttributeDecoder.cpp @@ -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. @@ -71,7 +71,6 @@ shibsp::Attribute* ScopedAttributeDecoder::decode( const XMLCh* xmlscope; xmltooling::QName scopeqname(NULL,Scope); auto_ptr scoped(new ScopedAttribute(ids, m_delimeter)); - scoped->setCaseSensitive(m_caseSensitive); vector< pair >& dest = scoped->getValues(); vector::const_iterator v,stop; @@ -146,7 +145,7 @@ shibsp::Attribute* ScopedAttributeDecoder::decode( } } - return dest.empty() ? NULL : scoped.release(); + return dest.empty() ? NULL : _decode(scoped.release()); } const NameID* saml2name = dynamic_cast(xmlObject); @@ -192,5 +191,5 @@ shibsp::Attribute* ScopedAttributeDecoder::decode( log.warn("ignoring empty NameID"); } delete[] val; - return dest.empty() ? NULL : scoped.release(); + return dest.empty() ? NULL : _decode(scoped.release()); } diff --git a/shibsp/attribute/StringAttributeDecoder.cpp b/shibsp/attribute/StringAttributeDecoder.cpp index ca86390..f2a9d6f 100644 --- a/shibsp/attribute/StringAttributeDecoder.cpp +++ b/shibsp/attribute/StringAttributeDecoder.cpp @@ -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. @@ -57,7 +57,6 @@ shibsp::Attribute* StringAttributeDecoder::decode( { char* val; auto_ptr simple(new SimpleAttribute(ids)); - simple->setCaseSensitive(m_caseSensitive); vector& dest = simple->getValues(); vector::const_iterator v,stop; @@ -111,7 +110,7 @@ shibsp::Attribute* StringAttributeDecoder::decode( } } - return dest.empty() ? NULL : simple.release(); + return dest.empty() ? NULL : _decode(simple.release()); } const NameID* saml2name = dynamic_cast(xmlObject); @@ -145,5 +144,5 @@ shibsp::Attribute* StringAttributeDecoder::decode( else log.warn("ignoring empty NameID"); delete[] val; - return dest.empty() ? NULL : simple.release(); + return dest.empty() ? NULL : _decode(simple.release()); }