WinStd
Windows Win32 API using Standard C++
Loading...
Searching...
No Matches
Sec.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2023 Amebis
4 Copyright © 2016 GÉANT
5*/
6
8
9#pragma once
10
11#include "Common.h"
12#include <Security.h>
13#include <string>
14
17
18#if defined(SECURITY_WIN32) || defined(SECURITY_KERNEL)
19
21template<class _Traits, class _Ax>
22static BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<char, _Traits, _Ax> &sName)
23{
24 assert(0); // TODO: Test this code.
25
26 char szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
27 ULONG ulSize = _countof(szStackBuffer);
28
29 // Try with stack buffer first.
30 if (::GetUserNameExA(NameFormat, szStackBuffer, &ulSize)) {
31 // Copy from stack.
32 sName.assign(szStackBuffer, ulSize);
33 return TRUE;
34 }
35 if (::GetLastError() == ERROR_MORE_DATA) {
36 // Allocate buffer on heap and retry.
37 std::unique_ptr<char[]> szBuffer(new char[ulSize]);
38 if (::GetUserNameExA(NameFormat, szBuffer.get(), &ulSize)) {
39 sName.assign(szBuffer.get(), ulSize);
40 return TRUE;
41 }
42 }
43 return FALSE;
44}
45
51template<class _Traits, class _Ax>
52static BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sName)
53{
54 assert(0); // TODO: Test this code.
55
56 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
57 ULONG ulSize = _countof(szStackBuffer);
58
59 // Try with stack buffer first.
60 if (::GetUserNameExW(NameFormat, szStackBuffer, &ulSize)) {
61 // Copy from stack.
62 sName.assign(szStackBuffer, ulSize);
63 return TRUE;
64 }
65 if (::GetLastError() == ERROR_MORE_DATA) {
66 // Allocate buffer on heap and retry.
67 std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[ulSize]);
68 if (::GetUserNameExW(NameFormat, szBuffer.get(), &ulSize)) {
69 sName.assign(szBuffer.get(), ulSize);
70 return TRUE;
71 }
72 }
73 return FALSE;
74}
75
76#endif
77
79
80namespace winstd
81{
84
88 class sec_credentials : public handle<PCredHandle, NULL>
89 {
91
92 public:
97 {
98 m_expires.QuadPart = -1;
99 }
100
107 sec_credentials(_In_opt_ handle_type h, _In_ const TimeStamp expires) :
108 m_expires(expires),
109 handle(h)
110 {}
111
117 sec_credentials(_Inout_ sec_credentials &&h) noexcept :
118 m_expires(std::move(h.m_expires)),
119 handle<PCredHandle, NULL>(std::move(h))
120 {}
121
128 {
129 if (m_h != invalid)
131 }
132
139 {
140 if (this != std::addressof(h)) {
141 *(handle<handle_type, NULL>*)this = std::move(h);
142 m_expires = std::move(h.m_expires);
143 }
144 return *this;
145 }
146
156 SECURITY_STATUS acquire(
157 _In_opt_ LPTSTR pszPrincipal,
158 _In_ LPTSTR pszPackage,
159 _In_ unsigned long fCredentialUse,
160 _In_opt_ void *pvLogonId,
161 _In_opt_ void *pAuthData,
162 _In_opt_ SEC_GET_KEY_FN pGetKeyFn = NULL,
163 _In_opt_ void *pvGetKeyArgument = NULL)
164 {
165 handle_type h = new CredHandle;
166 TimeStamp exp;
167 SECURITY_STATUS res = AcquireCredentialsHandle(pszPrincipal, pszPackage, fCredentialUse, pvLogonId, pAuthData, pGetKeyFn, pvGetKeyArgument, h, &exp);
168 if (SUCCEEDED(res)) {
169 attach(h);
170 m_expires = exp;
171 } else
172 delete h;
173 return res;
174 }
175
176 protected:
182 void free_internal() noexcept override
183 {
184 FreeCredentialsHandle(m_h);
185 delete m_h;
186 }
187
188 public:
189 TimeStamp m_expires;
190 };
191
195 class sec_context : public handle<PCtxtHandle, NULL>
196 {
197 public:
202 m_attrib(0),
203 handle<PCtxtHandle, NULL>()
204 {
205 m_expires.QuadPart = -1;
206 }
207
213 sec_context(_Inout_ sec_context &&h) noexcept :
214 m_attrib (std::move(h.m_attrib )),
215 m_expires(std::move(h.m_expires)),
216 handle<PCtxtHandle, NULL>(std::move(h))
217 {}
218
224 virtual ~sec_context()
225 {
226 if (m_h != invalid)
228 }
229
235 sec_context& operator=(_Inout_ sec_context &&h) noexcept
236 {
237 if (this != std::addressof(h)) {
238 *(handle<handle_type, NULL>*)this = std::move(h);
239 m_attrib = std::move(h.m_attrib);
240 m_expires = std::move(h.m_expires);
241 }
242 return *this;
243 }
244
254 SECURITY_STATUS initialize(
255 _In_opt_ PCredHandle phCredential,
256 _In_opt_z_ LPCTSTR pszTargetName,
257 _In_ ULONG fContextReq,
258 _In_ ULONG TargetDataRep,
259 _In_opt_ PSecBufferDesc pInput,
260 _Inout_opt_ PSecBufferDesc pOutput)
261 {
262 handle_type h = new CtxtHandle;
263 h->dwUpper = 0;
264 h->dwLower = 0;
265 ULONG attr;
266 TimeStamp exp;
267 SECURITY_STATUS res = InitializeSecurityContext(phCredential, NULL, const_cast<LPTSTR>(pszTargetName), fContextReq, 0, TargetDataRep, pInput, 0, h, pOutput, &attr, &exp);
268 if (SUCCEEDED(res)) {
269 attach(h);
270 m_attrib = attr;
271 m_expires = exp;
272 } else
273 delete h;
274 return res;
275 }
276
286 SECURITY_STATUS process(
287 _In_opt_ PCredHandle phCredential,
288 _In_opt_z_ LPCTSTR pszTargetName,
289 _In_ ULONG fContextReq,
290 _In_ ULONG TargetDataRep,
291 _In_opt_ PSecBufferDesc pInput,
292 _Inout_opt_ PSecBufferDesc pOutput)
293 {
294 return InitializeSecurityContext(phCredential, m_h, const_cast<LPTSTR>(pszTargetName), fContextReq, 0, TargetDataRep, pInput, 0, NULL, pOutput, &m_attrib, &m_expires);
295 }
296
297 protected:
303 void free_internal() noexcept override
304 {
305 DeleteSecurityContext(m_h);
306 delete m_h;
307 }
308
309 public:
310 ULONG m_attrib;
311 TimeStamp m_expires;
312 };
313
317 class sec_buffer_desc : public SecBufferDesc
318 {
319 public:
323 sec_buffer_desc(_Inout_count_(count) PSecBuffer buf, ULONG count, _In_ ULONG version = SECBUFFER_VERSION)
324 {
325 ulVersion = version;
326 cBuffers = count;
327 pBuffers = buf;
328 }
329
336 {
337 for (ULONG i = 0; i < cBuffers; i++) {
338 if (pBuffers[i].pvBuffer)
339 FreeContextBuffer(pBuffers[i].pvBuffer);
340 }
341 }
342 };
343
345
348
354 class sec_runtime_error : public num_runtime_error<SECURITY_STATUS>
355 {
356 public:
363 sec_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error<SECURITY_STATUS>(num, msg)
364 {}
365
372 sec_runtime_error(_In_ error_type num, _In_opt_z_ const char *msg = nullptr) : num_runtime_error<SECURITY_STATUS>(num, msg)
373 {}
374
380 sec_runtime_error(const sec_runtime_error &other) : num_runtime_error<SECURITY_STATUS>(other)
381 {}
382 };
383
385}
Base abstract template class to support generic object handle keeping.
Definition Common.h:1020
PCredHandle handle_type
Datatype of the object handle this template class handles.
Definition Common.h:1025
handle_type m_h
Object handle.
Definition Common.h:1274
void attach(handle_type h) noexcept
Sets a new object handle for the class.
Definition Common.h:1237
Numerical runtime error.
Definition Common.h:1483
SECURITY_STATUS error_type
Error number type.
Definition Common.h:1485
SecBufferDesc wrapper class.
Definition Sec.h:318
virtual ~sec_buffer_desc()
Frees the security buffer descriptor.
Definition Sec.h:335
sec_buffer_desc(PSecBuffer buf, ULONG count, ULONG version=SECBUFFER_VERSION)
Initializes security buffer descriptor.
Definition Sec.h:323
PCtxtHandle wrapper class.
Definition Sec.h:196
sec_context(sec_context &&h) noexcept
Move constructor.
Definition Sec.h:213
SECURITY_STATUS process(PCredHandle phCredential, LPCTSTR pszTargetName, ULONG fContextReq, ULONG TargetDataRep, PSecBufferDesc pInput, PSecBufferDesc pOutput)
Continue security context.
Definition Sec.h:286
virtual ~sec_context()
Frees the security context.
Definition Sec.h:224
sec_context()
Initializes a new class instance with the object handle set to NULL.
Definition Sec.h:201
SECURITY_STATUS initialize(PCredHandle phCredential, LPCTSTR pszTargetName, ULONG fContextReq, ULONG TargetDataRep, PSecBufferDesc pInput, PSecBufferDesc pOutput)
Initializes security context.
Definition Sec.h:254
ULONG m_attrib
Context attributes.
Definition Sec.h:310
TimeStamp m_expires
Context expiration time.
Definition Sec.h:311
sec_context & operator=(sec_context &&h) noexcept
Move assignment.
Definition Sec.h:235
void free_internal() noexcept override
Frees the security context.
Definition Sec.h:303
PCredHandle wrapper class.
Definition Sec.h:89
sec_credentials()
Initializes a new class instance with the object handle set to NULL.
Definition Sec.h:96
void free_internal() noexcept override
Frees the security credentials.
Definition Sec.h:182
TimeStamp m_expires
Credentials expiration time.
Definition Sec.h:189
sec_credentials(sec_credentials &&h) noexcept
Move constructor.
Definition Sec.h:117
virtual ~sec_credentials()
Frees the security credentials.
Definition Sec.h:127
sec_credentials(handle_type h, const TimeStamp expires)
Initializes a new class with an already available object handle.
Definition Sec.h:107
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:156
sec_credentials & operator=(sec_credentials &&h) noexcept
Move assignment.
Definition Sec.h:138
Security runtime error.
Definition Sec.h:355
sec_runtime_error(error_type num, const char *msg=nullptr)
Constructs an exception.
Definition Sec.h:372
sec_runtime_error(const sec_runtime_error &other)
Copies an exception.
Definition Sec.h:380
sec_runtime_error(error_type num, const std::string &msg)
Constructs an exception.
Definition Sec.h:363
#define WINSTD_NONCOPYABLE(C)
Declares a class as non-copyable.
Definition Common.h:67
#define WINSTD_STACK_BUFFER_BYTES
Size of the stack buffer in bytes used for initial system function call.
Definition Common.h:94
static const PCredHandle invalid
Invalid handle value.
Definition Common.h:1030