// See the file "COPYING" in the main distribution directory for copyright. #pragma once #include "RandTest.h" #include "Val.h" #include "digest.h" #include "paraglob/paraglob.h" #include #include // for u_char namespace broker { class data; } class OpaqueVal; /** * Singleton that registers all available all available types of opaque * values. This faciliates their serialization into Broker values. */ class OpaqueMgr { public: using Factory = OpaqueVal* (); /** * Return's a unique ID for the type of an opaque value. * @param v opaque value to return type for; its class must have been * registered with the manager, otherwise this method will abort * execution. * * @return type ID, which can used with *Instantiate()* to create a * new instance of the same type. */ const std::string& TypeID(const OpaqueVal* v) const; /** * Instantiates a new opaque value of a specific opaque type. * * @param id unique type ID for the class to instantiate; this will * normally have been returned earlier by *TypeID()*. * * @return A freshly instantiated value of the OpaqueVal-derived * classes that *id* specifies, with reference count at +1. If *id* * is unknown, this will return null. * */ OpaqueVal* Instantiate(const std::string& id) const; /** Returns the global manager singleton object. */ static OpaqueMgr* mgr(); /** * Internal helper class to register an OpaqueVal-derived classes * with the manager. */ template class Register { public: Register(const char* id) { OpaqueMgr::mgr()->_types.emplace(id, &T::OpaqueInstantiate); } }; private: std::unordered_map _types; }; /** Macro to insert into an OpaqueVal-derived class's declaration. */ #define DECLARE_OPAQUE_VALUE(T) \ friend class OpaqueMgr::Register; \ broker::expected DoSerialize() const override; \ bool DoUnserialize(const broker::data& data) override; \ const char* OpaqueName() const override { return #T; } \ static OpaqueVal* OpaqueInstantiate() { return new T(); } #define __OPAQUE_MERGE(a, b) a ## b #define __OPAQUE_ID(x) __OPAQUE_MERGE(_opaque, x) /** Macro to insert into an OpaqueVal-derived class's implementation file. */ #define IMPLEMENT_OPAQUE_VALUE(T) static OpaqueMgr::Register __OPAQUE_ID(__LINE__)(#T); /** * Base class for all opaque values. Opaque values are types that are managed * completely internally, with no further script-level operators provided * (other than bif functions). See OpaqueVal.h for derived classes. */ class OpaqueVal : public Val { public: explicit OpaqueVal(OpaqueType* t); ~OpaqueVal() override; /** * Serializes the value into a Broker representation. * * @return the broker representation, or an error if serialization * isn't supported or failed. */ broker::expected Serialize() const; /** * Reinstantiates a value from its serialized Broker representation. * * @param data Broker representation as returned by *Serialize()*. * @return unserialized instances with reference count at +1 */ static OpaqueVal* Unserialize(const broker::data& data); protected: friend class Val; friend class OpaqueMgr; OpaqueVal() { } /** * Must be overridden to provide a serialized version of the derived * class' state. * * @return the serialized data or an error if serialization * isn't supported or failed. */ virtual broker::expected DoSerialize() const = 0; /** * Must be overridden to recreate the the derived class' state from a * serialization. * * @return true if successful. */ virtual bool DoUnserialize(const broker::data& data) = 0; /** * Internal helper for the serialization machinery. Automatically * overridden by the `DECLARE_OPAQUE_VALUE` macro. */ virtual const char* OpaqueName() const = 0; /** * Provides an implementation of *Val::DoClone()* that leverages the * serialization methods to deep-copy an instance. Derived classes * may also override this with a more efficient custom clone * implementation of their own. */ Val* DoClone(CloneState* state) override; /** * Helper function for derived class that need to record a type * during serialization. */ static broker::expected SerializeType(BroType* t); /** * Helper function for derived class that need to restore a type * during unserialization. Returns the type at reference count +1. */ static BroType* UnserializeType(const broker::data& data); }; namespace probabilistic { class BloomFilter; class CardinalityCounter; } class HashVal : public OpaqueVal { public: virtual bool IsValid() const; virtual bool Init(); virtual bool Feed(const void* data, size_t size); virtual StringVal* Get(); protected: HashVal() { valid = false; } explicit HashVal(OpaqueType* t); virtual bool DoInit(); virtual bool DoFeed(const void* data, size_t size); virtual StringVal* DoGet(); private: // This flag exists because Get() can only be called once. bool valid; }; class MD5Val : public HashVal { public: static void digest(val_list& vlist, u_char result[MD5_DIGEST_LENGTH]); static void hmac(val_list& vlist, u_char key[MD5_DIGEST_LENGTH], u_char result[MD5_DIGEST_LENGTH]); MD5Val(); ~MD5Val(); Val* DoClone(CloneState* state) override; protected: friend class Val; bool DoInit() override; bool DoFeed(const void* data, size_t size) override; StringVal* DoGet() override; DECLARE_OPAQUE_VALUE(MD5Val) private: EVP_MD_CTX* ctx; }; class SHA1Val : public HashVal { public: static void digest(val_list& vlist, u_char result[SHA_DIGEST_LENGTH]); SHA1Val(); ~SHA1Val(); Val* DoClone(CloneState* state) override; protected: friend class Val; bool DoInit() override; bool DoFeed(const void* data, size_t size) override; StringVal* DoGet() override; DECLARE_OPAQUE_VALUE(SHA1Val) private: EVP_MD_CTX* ctx; }; class SHA256Val : public HashVal { public: static void digest(val_list& vlist, u_char result[SHA256_DIGEST_LENGTH]); SHA256Val(); ~SHA256Val(); Val* DoClone(CloneState* state) override; protected: friend class Val; bool DoInit() override; bool DoFeed(const void* data, size_t size) override; StringVal* DoGet() override; DECLARE_OPAQUE_VALUE(SHA256Val) private: EVP_MD_CTX* ctx; }; class EntropyVal : public OpaqueVal { public: EntropyVal(); bool Feed(const void* data, size_t size); bool Get(double *r_ent, double *r_chisq, double *r_mean, double *r_montepicalc, double *r_scc); protected: friend class Val; DECLARE_OPAQUE_VALUE(EntropyVal) private: RandTest state; }; class BloomFilterVal : public OpaqueVal { public: explicit BloomFilterVal(probabilistic::BloomFilter* bf); ~BloomFilterVal() override; Val* DoClone(CloneState* state) override; BroType* Type() const; bool Typify(BroType* type); void Add(const Val* val); size_t Count(const Val* val) const; void Clear(); bool Empty() const; string InternalState() const; static BloomFilterVal* Merge(const BloomFilterVal* x, const BloomFilterVal* y); protected: friend class Val; BloomFilterVal(); explicit BloomFilterVal(OpaqueType* t); DECLARE_OPAQUE_VALUE(BloomFilterVal) private: // Disable. BloomFilterVal(const BloomFilterVal&); BloomFilterVal& operator=(const BloomFilterVal&); BroType* type; CompositeHash* hash; probabilistic::BloomFilter* bloom_filter; }; class CardinalityVal: public OpaqueVal { public: explicit CardinalityVal(probabilistic::CardinalityCounter*); ~CardinalityVal() override; Val* DoClone(CloneState* state) override; void Add(const Val* val); BroType* Type() const; bool Typify(BroType* type); probabilistic::CardinalityCounter* Get() { return c; }; protected: CardinalityVal(); DECLARE_OPAQUE_VALUE(CardinalityVal) private: BroType* type; CompositeHash* hash; probabilistic::CardinalityCounter* c; }; class ParaglobVal : public OpaqueVal { public: explicit ParaglobVal(std::unique_ptr p); VectorVal* Get(StringVal* &pattern); Val* DoClone(CloneState* state) override; bool operator==(const ParaglobVal& other) const; protected: ParaglobVal() : OpaqueVal(paraglob_type) {} DECLARE_OPAQUE_VALUE(ParaglobVal) private: std::unique_ptr internal_paraglob; };