https://issues.shibboleth.net/jira/browse/CPPOST-47
[shibboleth/cpp-xmltooling.git] / xmltooling / util / ReloadableXMLFile.h
index a990f5e..4f21177 100644 (file)
 #include <string>
 #include <xercesc/dom/DOM.hpp>
 
+#ifndef XMLTOOLING_LITE
+    namespace xmlsignature {
+        class XMLTOOL_API Signature;
+    };
+#endif
+
 namespace xmltooling {
 
     class XMLTOOL_API CondWait;
     class XMLTOOL_API RWLock;
     class XMLTOOL_API Thread;
 
+#ifndef XMLTOOLING_LITE
+    class XMLTOOL_API CredentialResolver;
+    class XMLTOOL_API SignatureTrustEngine;
+#endif
+
     /**
      * Base class for file-based XML configuration.
      */
@@ -55,18 +66,28 @@ namespace xmltooling {
          *  <dd>use a validating parser</dd>
          *  <dt>reloadChanges</dt>
          *  <dd>enables monitoring of local file for changes</dd>
-         *  <dt>reloadInterval</dt>
+         *  <dt>reloadInterval or maxRefreshDelay</dt>
          *  <dd>enables periodic refresh of remote file</dd>
          *  <dt>backingFilePath</dt>
          *  <dd>location for backup of remote resource</dd>
          *  <dt>id</dt>
          *  <dd>identifies the plugin instance for logging purposes</dd>
+         *  <dt>certificate</dt>
+         *  <dd>requires XML be signed with an enveloped signature verifiable with specified key</dd>
+         *  <dt>signerName</dt>
+         *  <dd>requires XML be signed with an enveloped signature verifiable with &lt;TrustEngine&gt;
+         *      by certificate containing this name</dd>
+         *  <dt>&lt;CredentialResolver&gt;</dt>
+         *  <dd>requires XML be signed with an enveloped signature verifiable with specified key</dd>
+         *  <dt>&lt;TrustEngine&gt;</dt>
+         *  <dd>requires XML be signed with an enveloped signature verifiable with specified TrustEngine</dd>
          * </dl>
          * 
-         * @param e     DOM to supply configuration
-         * @param log   logging object to use
+         * @param e                 DOM to supply configuration
+         * @param log               logging object to use
+         * @param startReloadThread true iff refresh thread for resources should be started by constructor
          */
-        ReloadableXMLFile(const xercesc::DOMElement* e, logging::Category& log);
+        ReloadableXMLFile(const xercesc::DOMElement* e, logging::Category& log, bool startReloadThread=true);
     
         virtual ~ReloadableXMLFile();
 
@@ -87,6 +108,7 @@ namespace xmltooling {
         virtual std::pair<bool,xercesc::DOMElement*> background_load();
 
         /**
+         * @deprecated
          * Basic load/parse of configuration material.
          * 
          * <p>The base version performs basic parsing duties and returns the result.
@@ -102,16 +124,45 @@ namespace xmltooling {
         virtual std::pair<bool,xercesc::DOMElement*> load();
 
         /**
+         * Basic load/parse of configuration material.
+         *
+         * <p>The base version performs basic parsing duties and returns the result.
+         * Subclasses should override the new background_load() method and perform
+         * their own locking in conjunction with use of this method.
+         *
+         * <p>This version allows subclasses to explicitly control the use of a
+         * backup for remote resources, which allows additional validation to be
+         * performed besides just successful XML parsing.
+         *
+         * @param backup    true iff the backup source should be loaded
+         * @return a pair consisting of a flag indicating whether to take ownership of
+         *      the document, and the root element of the tree to load
+         */
+        virtual std::pair<bool,xercesc::DOMElement*> load(bool backup);
+
+        /**
          * Accesses a lock interface protecting use of backup file associated with the
          * object.
          *
          * <p>The lock is <strong>NOT</strong> acquired automatically.
          *
-         * @return  pointer to a lock interface, or NULL if unnecessary
+         * @return  pointer to a lock interface, or nullptr if unnecessary
          */
         virtual Lockable* getBackupLock();
 
         /**
+         * Preserves the last remote resource caching identifier in a backup file
+         * for use on the next restart.
+         */
+        void preserveCacheTag();
+
+        /**
+         * Starts up reload thread, can be automatically called by constructor, or
+         * manually invoked by subclass.
+         */
+        void startup();
+
+        /**
          * Shuts down reload thread, should be called from subclass destructor.
          */
         void shutdown();
@@ -131,12 +182,6 @@ namespace xmltooling {
         /** Path to backup copy for remote resource. */
         std::string m_backing;
 
-        /**
-         * Before load, indicates whether the backup is handled by the base class,
-         * after load, will be true iff it started false and a backup needs to be done.
-         */
-        bool m_backupIndicator;
-
         /** Last modification of local resource. */
         time_t m_filestamp;
 
@@ -155,13 +200,28 @@ namespace xmltooling {
         /** Plugin identifier. */
         std::string m_id;
 
+        /** Indicates whether a usable version of the resource is in place. */
+        bool m_loaded;
+
+#ifndef XMLTOOLING_LITE
+        /** CredentialResolver for signature verification. */
+        CredentialResolver* m_credResolver;
+
+        /** TrustEngine for signature verification. */
+        SignatureTrustEngine* m_trust;
+
+        /** Name of signer for signature verification. */
+        std::string m_signerName;
+#endif
+
     public:
         Lockable* lock();
         void unlock();
 
     private:
-        std::pair<bool,xercesc::DOMElement*> load(bool backup);
-
+#ifndef XMLTOOLING_LITE
+        void validateSignature(xmlsignature::Signature& sigObj) const;
+#endif
         // Used to manage background reload/refresh.
         bool m_shutdown;
         CondWait* m_reload_wait;