WinStd
Additional templates and function helpers for Microsoft Windows using Standard C++ classes
Sec.h
Go to the documentation of this file.
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2022 Amebis
4 Copyright © 2016 GÉANT
5*/
6
12
13#pragma once
14
15#include "Common.h"
16#include <Security.h>
17#include <string>
18
21
22#if defined(SECURITY_WIN32) || defined(SECURITY_KERNEL)
23
25template<class _Traits, class _Ax>
26static BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<char, _Traits, _Ax> &sName)
27{
28 assert(0); // TODO: Test this code.
29
30 char szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
31 ULONG ulSize = _countof(szStackBuffer);
32
33 // Try with stack buffer first.
34 if (::GetUserNameExA(NameFormat, szStackBuffer, &ulSize)) {
35 // Copy from stack.
36 sName.assign(szStackBuffer, ulSize);
37 return TRUE;
38 } else {
39 if (::GetLastError() == ERROR_MORE_DATA) {
40 // Allocate buffer on heap and retry.
41 std::unique_ptr<char[]> szBuffer(new char[ulSize]);
42 if (::GetUserNameExA(NameFormat, szBuffer.get(), &ulSize)) {
43 sName.assign(szBuffer.get(), ulSize);
44 return TRUE;
45 }
46 }
47 }
48
49 return FALSE;
50}
51
57template<class _Traits, class _Ax>
58static BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sName)
59{
60 assert(0); // TODO: Test this code.
61
62 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
63 ULONG ulSize = _countof(szStackBuffer);
64
65 // Try with stack buffer first.
66 if (::GetUserNameExW(NameFormat, szStackBuffer, &ulSize)) {
67 // Copy from stack.
68 sName.assign(szStackBuffer, ulSize);
69 return TRUE;
70 } else {
71 if (::GetLastError() == ERROR_MORE_DATA) {
72 // Allocate buffer on heap and retry.
73 std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[ulSize]);
74 if (::GetUserNameExW(NameFormat, szBuffer.get(), &ulSize)) {
75 sName.assign(szBuffer.get(), ulSize);
76 return TRUE;
77 }
78 }
79 }
80
81 return FALSE;
82}
83
84#endif
85
87
88namespace winstd
89{
92
96 class sec_credentials : public handle<PCredHandle, NULL>
97 {
99
100 public:
105 {
106 m_expires.QuadPart = -1;
107 }
108
115 sec_credentials(_In_opt_ handle_type h, _In_ const TimeStamp expires) :
116 m_expires(expires),
117 handle(h)
118 {
119 }
120
126 sec_credentials(_Inout_ sec_credentials &&h) noexcept :
127 m_expires(std::move(h.m_expires)),
128 handle<PCredHandle, NULL>(std::move(h))
129 {
130 }
131
138 {
139 if (m_h != invalid)
141 }
142
149 {
150 if (this != std::addressof(h)) {
151 *(handle<handle_type, NULL>*)this = std::move(h);
152 m_expires = std::move(h.m_expires);
153 }
154 return *this;
155 }
156
166 SECURITY_STATUS acquire(
167 _In_opt_ LPTSTR pszPrincipal,
168 _In_ LPTSTR pszPackage,
169 _In_ unsigned long fCredentialUse,
170 _In_opt_ void *pvLogonId,
171 _In_opt_ void *pAuthData,
172 _In_opt_ SEC_GET_KEY_FN pGetKeyFn = NULL,
173 _In_opt_ void *pvGetKeyArgument = NULL)
174 {
175 handle_type h = new CredHandle;
176 TimeStamp exp;
177 SECURITY_STATUS res = AcquireCredentialsHandle(pszPrincipal, pszPackage, fCredentialUse, pvLogonId, pAuthData, pGetKeyFn, pvGetKeyArgument, h, &exp);
178 if (SUCCEEDED(res)) {
179 attach(h);
180 m_expires = exp;
181 } else
182 delete h;
183 return res;
184 }
185
186 protected:
192 void free_internal() noexcept override
193 {
194 FreeCredentialsHandle(m_h);
195 delete m_h;
196 }
197
198 public:
199 TimeStamp m_expires;
200 };
201
205 class sec_context : public handle<PCtxtHandle, NULL>
206 {
207 public:
212 m_attrib(0),
213 handle<PCtxtHandle, NULL>()
214 {
215 m_expires.QuadPart = -1;
216 }
217
223 sec_context(_Inout_ sec_context &&h) noexcept :
224 m_attrib (std::move(h.m_attrib )),
225 m_expires(std::move(h.m_expires)),
226 handle<PCtxtHandle, NULL>(std::move(h))
227 {
228 }
229
235 virtual ~sec_context()
236 {
237 if (m_h != invalid)
239 }
240
246 sec_context& operator=(_Inout_ sec_context &&h) noexcept
247 {
248 if (this != std::addressof(h)) {
249 *(handle<handle_type, NULL>*)this = std::move(h);
250 m_attrib = std::move(h.m_attrib);
251 m_expires = std::move(h.m_expires);
252 }
253 return *this;
254 }
255
265 SECURITY_STATUS initialize(
266 _In_opt_ PCredHandle phCredential,
267 _In_opt_z_ LPCTSTR pszTargetName,
268 _In_ ULONG fContextReq,
269 _In_ ULONG TargetDataRep,
270 _In_opt_ PSecBufferDesc pInput,
271 _Inout_opt_ PSecBufferDesc pOutput)
272 {
273 handle_type h = new CtxtHandle;
274 h->dwUpper = 0;
275 h->dwLower = 0;
276 ULONG attr;
277 TimeStamp exp;
278 SECURITY_STATUS res = InitializeSecurityContext(phCredential, NULL, const_cast<LPTSTR>(pszTargetName), fContextReq, 0, TargetDataRep, pInput, 0, h, pOutput, &attr, &exp);
279 if (SUCCEEDED(res)) {
280 attach(h);
281 m_attrib = attr;
282 m_expires = exp;
283 } else
284 delete h;
285 return res;
286 }
287
297 SECURITY_STATUS process(
298 _In_opt_ PCredHandle phCredential,
299 _In_opt_z_ LPCTSTR pszTargetName,
300 _In_ ULONG fContextReq,
301 _In_ ULONG TargetDataRep,
302 _In_opt_ PSecBufferDesc pInput,
303 _Inout_opt_ PSecBufferDesc pOutput)
304 {
305 return InitializeSecurityContext(phCredential, m_h, const_cast<LPTSTR>(pszTargetName), fContextReq, 0, TargetDataRep, pInput, 0, NULL, pOutput, &m_attrib, &m_expires);
306 }
307
308 protected:
314 void free_internal() noexcept override
315 {
316 DeleteSecurityContext(m_h);
317 delete m_h;
318 }
319
320 public:
321 ULONG m_attrib;
322 TimeStamp m_expires;
323 };
324
328 class sec_buffer_desc : public SecBufferDesc
329 {
330 public:
334 sec_buffer_desc(_Inout_count_(count) PSecBuffer buf, ULONG count, _In_ ULONG version = SECBUFFER_VERSION)
335 {
336 ulVersion = version;
337 cBuffers = count;
338 pBuffers = buf;
339 }
340
347 {
348 for (ULONG i = 0; i < cBuffers; i++) {
349 if (pBuffers[i].pvBuffer)
350 FreeContextBuffer(pBuffers[i].pvBuffer);
351 }
352 }
353 };
354
356
359
365 class sec_runtime_error : public num_runtime_error<SECURITY_STATUS>
366 {
367 public:
374 sec_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error<SECURITY_STATUS>(num, msg)
375 {
376 }
377
384 sec_runtime_error(_In_ error_type num, _In_opt_z_ const char *msg = nullptr) : num_runtime_error<SECURITY_STATUS>(num, msg)
385 {
386 }
387
393 sec_runtime_error(const sec_runtime_error &other) : num_runtime_error<SECURITY_STATUS>(other)
394 {
395 }
396 };
397
399}
General API.
Base abstract template class to support generic object handle keeping.
Definition: Common.h:615
PCredHandle handle_type
Datatype of the object handle this template class handles.
Definition: Common.h:620
handle_type m_h
Object handle.
Definition: Common.h:866
void attach(handle_type h) noexcept
Sets a new object handle for the class.
Definition: Common.h:829
Numerical runtime error.
Definition: Common.h:1011
SECURITY_STATUS error_type
Error number type.
Definition: Common.h:1013
SecBufferDesc wrapper class.
Definition: Sec.h:329
virtual ~sec_buffer_desc()
Frees the security buffer descriptor.
Definition: Sec.h:346
sec_buffer_desc(PSecBuffer buf, ULONG count, ULONG version=SECBUFFER_VERSION)
Initializes security buffer descriptor.
Definition: Sec.h:334
PCtxtHandle wrapper class.
Definition: Sec.h:206
sec_context(sec_context &&h) noexcept
Move constructor.
Definition: Sec.h:223
SECURITY_STATUS process(PCredHandle phCredential, LPCTSTR pszTargetName, ULONG fContextReq, ULONG TargetDataRep, PSecBufferDesc pInput, PSecBufferDesc pOutput)
Continue security context.
Definition: Sec.h:297
virtual ~sec_context()
Frees the security context.
Definition: Sec.h:235
sec_context()
Initializes a new class instance with the object handle set to NULL.
Definition: Sec.h:211
SECURITY_STATUS initialize(PCredHandle phCredential, LPCTSTR pszTargetName, ULONG fContextReq, ULONG TargetDataRep, PSecBufferDesc pInput, PSecBufferDesc pOutput)
Initializes security context.
Definition: Sec.h:265
ULONG m_attrib
Context attributes.
Definition: Sec.h:321
TimeStamp m_expires
Context expiration time.
Definition: Sec.h:322
sec_context & operator=(sec_context &&h) noexcept
Move assignment.
Definition: Sec.h:246
void free_internal() noexcept override
Frees the security context.
Definition: Sec.h:314
PCredHandle wrapper class.
Definition: Sec.h:97
sec_credentials()
Initializes a new class instance with the object handle set to NULL.
Definition: Sec.h:104
void free_internal() noexcept override
Frees the security credentials.
Definition: Sec.h:192
TimeStamp m_expires
Credentials expiration time.
Definition: Sec.h:199
sec_credentials(sec_credentials &&h) noexcept
Move constructor.
Definition: Sec.h:126
virtual ~sec_credentials()
Frees the security credentials.
Definition: Sec.h:137
sec_credentials(handle_type h, const TimeStamp expires)
Initializes a new class with an already available object handle.
Definition: Sec.h:115
SECURITY_STATUS acquire(LPTSTR pszPrincipal, LPTSTR pszPackage, unsigned long fCredentialUse, void *pvLogonId, void *pAuthData, SEC_GET_KEY_FN pGetKeyFn=NULL, void *pvGetKeyArgument=NULL)
Acquires the security credentials.
Definition: Sec.h:166
sec_credentials & operator=(sec_credentials &&h) noexcept
Move assignment.
Definition: Sec.h:148
Security runtime error.
Definition: Sec.h:366
sec_runtime_error(error_type num, const char *msg=nullptr)
Constructs an exception.
Definition: Sec.h:384
sec_runtime_error(const sec_runtime_error &other)
Copies an exception.
Definition: Sec.h:393
sec_runtime_error(error_type num, const std::string &msg)
Constructs an exception.
Definition: Sec.h:374
#define WINSTD_NONCOPYABLE(C)
Declares a class as non-copyable.
Definition: Common.h:74
#define WINSTD_STACK_BUFFER_BYTES
Size of the stack buffer in bytes used for initial system function call.
Definition: Common.h:101
static const PCredHandle invalid
Invalid handle value.
Definition: Common.h:625