|  | /* | 
|  | *  Copyright 2004 The WebRTC Project Authors. All rights reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  | // @file Contains utility classes that make it easier to use SecBuffers | 
|  |  | 
|  | #ifndef WEBRTC_BASE_SEC_BUFFER_H__ | 
|  | #define WEBRTC_BASE_SEC_BUFFER_H__ | 
|  |  | 
|  | namespace rtc { | 
|  |  | 
|  | // A base class for CSecBuffer<T>. Contains | 
|  | // all implementation that does not require | 
|  | // template arguments. | 
|  | class CSecBufferBase : public SecBuffer { | 
|  | public: | 
|  | CSecBufferBase() { | 
|  | Clear(); | 
|  | } | 
|  |  | 
|  | // Uses the SSPI to free a pointer, must be | 
|  | // used for buffers returned from SSPI APIs. | 
|  | static void FreeSSPI(void *ptr) { | 
|  | if ( ptr ) { | 
|  | SECURITY_STATUS status; | 
|  | status = ::FreeContextBuffer(ptr); | 
|  | ASSERT(SEC_E_OK == status); // "Freeing context buffer" | 
|  | } | 
|  | } | 
|  |  | 
|  | // Deletes a buffer with operator delete | 
|  | static void FreeDelete(void *ptr) { | 
|  | delete [] reinterpret_cast<char*>(ptr); | 
|  | } | 
|  |  | 
|  | // A noop delete, for buffers over other | 
|  | // people's memory | 
|  | static void FreeNone(void *ptr) { | 
|  | } | 
|  |  | 
|  | protected: | 
|  | // Clears the buffer to EMPTY & NULL | 
|  | void Clear() { | 
|  | this->BufferType = SECBUFFER_EMPTY; | 
|  | this->cbBuffer = 0; | 
|  | this->pvBuffer = NULL; | 
|  | } | 
|  | }; | 
|  |  | 
|  | // Wrapper class for SecBuffer to take care | 
|  | // of initialization and destruction. | 
|  | template <void (*pfnFreeBuffer)(void *ptr)> | 
|  | class CSecBuffer: public CSecBufferBase { | 
|  | public: | 
|  | // Initializes buffer to empty & NULL | 
|  | CSecBuffer() { | 
|  | } | 
|  |  | 
|  | // Frees any allocated memory | 
|  | ~CSecBuffer() { | 
|  | Release(); | 
|  | } | 
|  |  | 
|  | // Frees the buffer appropriately, and re-nulls | 
|  | void Release() { | 
|  | pfnFreeBuffer(this->pvBuffer); | 
|  | Clear(); | 
|  | } | 
|  |  | 
|  | private: | 
|  | // A placeholder function for compile-time asserts on the class | 
|  | void CompileAsserts() { | 
|  | // never invoked... | 
|  | assert(false); // _T("Notreached") | 
|  |  | 
|  | // This class must not extend the size of SecBuffer, since | 
|  | // we use arrays of CSecBuffer in CSecBufferBundle below | 
|  | cassert(sizeof(CSecBuffer<SSPIFree> == sizeof(SecBuffer))); | 
|  | } | 
|  | }; | 
|  |  | 
|  | // Contains all generic implementation for the | 
|  | // SecBufferBundle class | 
|  | class SecBufferBundleBase { | 
|  | public: | 
|  | }; | 
|  |  | 
|  | // A template class that bundles a SecBufferDesc with | 
|  | // one or more SecBuffers for convenience. Can take | 
|  | // care of deallocating buffers appropriately, as indicated | 
|  | // by pfnFreeBuffer function. | 
|  | // By default does no deallocation. | 
|  | template <int num_buffers, | 
|  | void (*pfnFreeBuffer)(void *ptr) = CSecBufferBase::FreeNone> | 
|  | class CSecBufferBundle : public SecBufferBundleBase { | 
|  | public: | 
|  | // Constructs a security buffer bundle with num_buffers | 
|  | // buffers, all of which are empty and nulled. | 
|  | CSecBufferBundle() { | 
|  | desc_.ulVersion = SECBUFFER_VERSION; | 
|  | desc_.cBuffers = num_buffers; | 
|  | desc_.pBuffers = buffers_; | 
|  | } | 
|  |  | 
|  | // Frees all currently used buffers. | 
|  | ~CSecBufferBundle() { | 
|  | Release(); | 
|  | } | 
|  |  | 
|  | // Accessor for the descriptor | 
|  | PSecBufferDesc desc() { | 
|  | return &desc_; | 
|  | } | 
|  |  | 
|  | // Accessor for the descriptor | 
|  | const PSecBufferDesc desc() const { | 
|  | return &desc_; | 
|  | } | 
|  |  | 
|  | // returns the i-th security buffer | 
|  | SecBuffer &operator[] (size_t num) { | 
|  | ASSERT(num < num_buffers); // "Buffer index out of bounds" | 
|  | return buffers_[num]; | 
|  | } | 
|  |  | 
|  | // returns the i-th security buffer | 
|  | const SecBuffer &operator[] (size_t num) const { | 
|  | ASSERT(num < num_buffers); // "Buffer index out of bounds" | 
|  | return buffers_[num]; | 
|  | } | 
|  |  | 
|  | // Frees all non-NULL security buffers, | 
|  | // using the deallocation function | 
|  | void Release() { | 
|  | for ( size_t i = 0; i < num_buffers; ++i ) { | 
|  | buffers_[i].Release(); | 
|  | } | 
|  | } | 
|  |  | 
|  | private: | 
|  | // Our descriptor | 
|  | SecBufferDesc               desc_; | 
|  | // Our bundled buffers, each takes care of its own | 
|  | // initialization and destruction | 
|  | CSecBuffer<pfnFreeBuffer>   buffers_[num_buffers]; | 
|  | }; | 
|  |  | 
|  | } // namespace rtc | 
|  |  | 
|  | #endif  // WEBRTC_BASE_SEC_BUFFER_H__ |