Home | History | Annotate | Download | only in base
      1 /*
      2  * libjingle
      3  * Copyright 2004--2005, Google Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *  1. Redistributions of source code must retain the above copyright notice,
      9  *     this list of conditions and the following disclaimer.
     10  *  2. Redistributions in binary form must reproduce the above copyright notice,
     11  *     this list of conditions and the following disclaimer in the documentation
     12  *     and/or other materials provided with the distribution.
     13  *  3. The name of the author may not be used to endorse or promote products
     14  *     derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 // @file Contains utility classes that make it easier to use SecBuffers
     29 
     30 #ifndef TALK_BASE_SEC_BUFFER_H__
     31 #define TALK_BASE_SEC_BUFFER_H__
     32 
     33 namespace talk_base {
     34 
     35 // A base class for CSecBuffer<T>. Contains
     36 // all implementation that does not require
     37 // template arguments.
     38 class CSecBufferBase : public SecBuffer {
     39  public:
     40   CSecBufferBase() {
     41     Clear();
     42   }
     43 
     44   // Uses the SSPI to free a pointer, must be
     45   // used for buffers returned from SSPI APIs.
     46   static void FreeSSPI(void *ptr) {
     47     if ( ptr ) {
     48       SECURITY_STATUS status;
     49       status = ::FreeContextBuffer(ptr);
     50       ASSERT(SEC_E_OK == status); // "Freeing context buffer"
     51     }
     52   }
     53 
     54   // Deletes a buffer with operator delete
     55   static void FreeDelete(void *ptr) {
     56     delete [] reinterpret_cast<char*>(ptr);
     57   }
     58 
     59   // A noop delete, for buffers over other
     60   // people's memory
     61   static void FreeNone(void *ptr) {
     62   }
     63 
     64  protected:
     65   // Clears the buffer to EMPTY & NULL
     66   void Clear() {
     67     this->BufferType = SECBUFFER_EMPTY;
     68     this->cbBuffer = 0;
     69     this->pvBuffer = NULL;
     70   }
     71 };
     72 
     73 // Wrapper class for SecBuffer to take care
     74 // of initialization and destruction.
     75 template <void (*pfnFreeBuffer)(void *ptr)>
     76 class CSecBuffer: public CSecBufferBase {
     77  public:
     78   // Initializes buffer to empty & NULL
     79   CSecBuffer() {
     80   }
     81 
     82   // Frees any allocated memory
     83   ~CSecBuffer() {
     84     Release();
     85   }
     86 
     87   // Frees the buffer appropriately, and re-nulls
     88   void Release() {
     89     pfnFreeBuffer(this->pvBuffer);
     90     Clear();
     91   }
     92 
     93  private:
     94   // A placeholder function for compile-time asserts on the class
     95   void CompileAsserts() {
     96     // never invoked...
     97     assert(false); // _T("Notreached")
     98 
     99     // This class must not extend the size of SecBuffer, since
    100     // we use arrays of CSecBuffer in CSecBufferBundle below
    101     cassert(sizeof(CSecBuffer<SSPIFree> == sizeof(SecBuffer)));
    102   }
    103 };
    104 
    105 // Contains all generic implementation for the
    106 // SecBufferBundle class
    107 class SecBufferBundleBase {
    108  public:
    109 };
    110 
    111 // A template class that bundles a SecBufferDesc with
    112 // one or more SecBuffers for convenience. Can take
    113 // care of deallocating buffers appropriately, as indicated
    114 // by pfnFreeBuffer function.
    115 // By default does no deallocation.
    116 template <int num_buffers,
    117           void (*pfnFreeBuffer)(void *ptr) = CSecBufferBase::FreeNone>
    118 class CSecBufferBundle : public SecBufferBundleBase {
    119  public:
    120   // Constructs a security buffer bundle with num_buffers
    121   // buffers, all of which are empty and nulled.
    122   CSecBufferBundle() {
    123     desc_.ulVersion = SECBUFFER_VERSION;
    124     desc_.cBuffers = num_buffers;
    125     desc_.pBuffers = buffers_;
    126   }
    127 
    128   // Frees all currently used buffers.
    129   ~CSecBufferBundle() {
    130     Release();
    131   }
    132 
    133   // Accessor for the descriptor
    134   PSecBufferDesc desc() {
    135     return &desc_;
    136   }
    137 
    138   // Accessor for the descriptor
    139   const PSecBufferDesc desc() const {
    140     return &desc_;
    141   }
    142 
    143   // returns the i-th security buffer
    144   SecBuffer &operator[] (size_t num) {
    145     ASSERT(num < num_buffers); // "Buffer index out of bounds"
    146     return buffers_[num];
    147   }
    148 
    149   // returns the i-th security buffer
    150   const SecBuffer &operator[] (size_t num) const {
    151     ASSERT(num < num_buffers); // "Buffer index out of bounds"
    152     return buffers_[num];
    153   }
    154 
    155   // Frees all non-NULL security buffers,
    156   // using the deallocation function
    157   void Release() {
    158     for ( size_t i = 0; i < num_buffers; ++i ) {
    159       buffers_[i].Release();
    160     }
    161   }
    162 
    163  private:
    164   // Our descriptor
    165   SecBufferDesc               desc_;
    166   // Our bundled buffers, each takes care of its own
    167   // initialization and destruction
    168   CSecBuffer<pfnFreeBuffer>   buffers_[num_buffers];
    169 };
    170 
    171 } // namespace talk_base
    172 
    173 #endif  // TALK_BASE_SEC_BUFFER_H__
    174