3 * Copyright 2004--2005, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
28 // @file Contains utility classes that make it easier to use SecBuffers
30 #ifndef TALK_BASE_SEC_BUFFER_H__
31 #define TALK_BASE_SEC_BUFFER_H__
35 // A base class for CSecBuffer<T>. Contains
36 // all implementation that does not require
37 // template arguments.
38 class CSecBufferBase : public SecBuffer {
44 // Uses the SSPI to free a pointer, must be
45 // used for buffers returned from SSPI APIs.
46 static void FreeSSPI(void *ptr) {
48 SECURITY_STATUS status;
49 status = ::FreeContextBuffer(ptr);
50 ASSERT(SEC_E_OK == status); // "Freeing context buffer"
54 // Deletes a buffer with operator delete
55 static void FreeDelete(void *ptr) {
56 delete [] reinterpret_cast<char*>(ptr);
59 // A noop delete, for buffers over other
61 static void FreeNone(void *ptr) {
65 // Clears the buffer to EMPTY & NULL
67 this->BufferType = SECBUFFER_EMPTY;
69 this->pvBuffer = NULL;
73 // Wrapper class for SecBuffer to take care
74 // of initialization and destruction.
75 template <void (*pfnFreeBuffer)(void *ptr)>
76 class CSecBuffer: public CSecBufferBase {
78 // Initializes buffer to empty & NULL
82 // Frees any allocated memory
87 // Frees the buffer appropriately, and re-nulls
89 pfnFreeBuffer(this->pvBuffer);
94 // A placeholder function for compile-time asserts on the class
95 void CompileAsserts() {
97 assert(false); // _T("Notreached")
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)));
105 // Contains all generic implementation for the
106 // SecBufferBundle class
107 class SecBufferBundleBase {
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 {
120 // Constructs a security buffer bundle with num_buffers
121 // buffers, all of which are empty and nulled.
123 desc_.ulVersion = SECBUFFER_VERSION;
124 desc_.cBuffers = num_buffers;
125 desc_.pBuffers = buffers_;
128 // Frees all currently used buffers.
129 ~CSecBufferBundle() {
133 // Accessor for the descriptor
134 PSecBufferDesc desc() {
138 // Accessor for the descriptor
139 const PSecBufferDesc desc() const {
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];
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];
155 // Frees all non-NULL security buffers,
156 // using the deallocation function
158 for ( size_t i = 0; i < num_buffers; ++i ) {
159 buffers_[i].Release();
166 // Our bundled buffers, each takes care of its own
167 // initialization and destruction
168 CSecBuffer<pfnFreeBuffer> buffers_[num_buffers];
171 } // namespace talk_base
173 #endif // TALK_BASE_SEC_BUFFER_H__