WinStd
Windows Win32 API using Standard C++
Loading...
Searching...
No Matches
Sec.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2022 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 } else {
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 }
44
45 return FALSE;
46}
47
53template<class _Traits, class _Ax>
54static BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sName)
55{
56 assert(0); // TODO: Test this code.
57
58 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
59 ULONG ulSize = _countof(szStackBuffer);
60
61 // Try with stack buffer first.
62 if (::GetUserNameExW(NameFormat, szStackBuffer, &ulSize)) {
63 // Copy from stack.
64 sName.assign(szStackBuffer, ulSize);
65 return TRUE;
66 } else {
67 if (::GetLastError() == ERROR_MORE_DATA) {
68 // Allocate buffer on heap and retry.
69 std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[ulSize]);
70 if (::GetUserNameExW(NameFormat, szBuffer.get(), &ulSize)) {
71 sName.assign(szBuffer.get(), ulSize);
72 return TRUE;
73 }
74 }
75 }
76
77 return FALSE;
78}
79
80#endif
81
83
84namespace winstd
85{
88
92 class sec_credentials : public handle<PCredHandle, NULL>
93 {
95
96 public:
101 {
102 m_expires.QuadPart = -1;
103 }
104
111 sec_credentials(_In_opt_ handle_type h, _In_ const TimeStamp expires) :
112 m_expires(expires),
113 handle(h)
114 {
115 }
116
122 sec_credentials(_Inout_ sec_credentials &&h) noexcept :
123 m_expires(std::move(h.m_expires)),
124 handle<PCredHandle, NULL>(std::move(h))
125 {
126 }
127
134 {
135 if (m_h != invalid)
137 }
138
145 {
146 if (this != std::addressof(h)) {
147 *(handle<handle_type, NULL>*)this = std::move(h);
148 m_expires = std::move(h.m_expires);
149 }
150 return *this;
151 }
152
162 SECURITY_STATUS acquire(
163 _In_opt_ LPTSTR pszPrincipal,
164 _In_ LPTSTR pszPackage,
165 _In_ unsigned long fCredentialUse,
166 _In_opt_ void *pvLogonId,
167 _In_opt_ void *pAuthData,
168 _In_opt_ SEC_GET_KEY_FN pGetKeyFn = NULL,
169 _In_opt_ void *pvGetKeyArgument = NULL)
170 {
171 handle_type h = new CredHandle;
172 TimeStamp exp;
173 SECURITY_STATUS res = AcquireCredentialsHandle(pszPrincipal, pszPackage, fCredentialUse, pvLogonId, pAuthData, pGetKeyFn, pvGetKeyArgument, h, &exp);
174 if (SUCCEEDED(res)) {
175 attach(h);
176 m_expires = exp;
177 } else
178 delete h;
179 return res;
180 }
181
182 protected:
188 void free_internal() noexcept override
189 {
190 FreeCredentialsHandle(m_h);
191 delete m_h;
192 }
193
194 public:
195 TimeStamp m_expires;
196 };
197
201 class sec_context : public handle<PCtxtHandle, NULL>
202 {
203 public:
208 m_attrib(0),
209 handle<PCtxtHandle, NULL>()
210 {
211 m_expires.QuadPart = -1;
212 }
213
219 sec_context(_Inout_ sec_context &&h) noexcept :
220 m_attrib (std::move(h.m_attrib )),
221 m_expires(std::move(h.m_expires)),
222 handle<PCtxtHandle, NULL>(std::move(h))
223 {
224 }
225
231 virtual ~sec_context()
232 {
233 if (m_h != invalid)
235 }
236
242 sec_context& operator=(_Inout_ sec_context &&h) noexcept
243 {
244 if (this != std::addressof(h)) {
245 *(handle<handle_type, NULL>*)this = std::move(h);
246 m_attrib = std::move(h.m_attrib);
247 m_expires = std::move(h.m_expires);
248 }
249 return *this;
250 }
251
261 SECURITY_STATUS initialize(
262 _In_opt_ PCredHandle phCredential,
263 _In_opt_z_ LPCTSTR pszTargetName,
264 _In_ ULONG fContextReq,
265 _In_ ULONG TargetDataRep,
266 _In_opt_ PSecBufferDesc pInput,
267 _Inout_opt_ PSecBufferDesc pOutput)
268 {
269 handle_type h = new CtxtHandle;
270 h->dwUpper = 0;
271 h->dwLower = 0;
272 ULONG attr;
273 TimeStamp exp;
274 SECURITY_STATUS res = InitializeSecurityContext(phCredential, NULL, const_cast<LPTSTR>(pszTargetName), fContextReq, 0, TargetDataRep, pInput, 0, h, pOutput, &attr, &exp);
275 if (SUCCEEDED(res)) {
276 attach(h);
277 m_attrib = attr;
278 m_expires = exp;
279 } else
280 delete h;
281 return res;
282 }
283
293 SECURITY_STATUS process(
294 _In_opt_ PCredHandle phCredential,
295 _In_opt_z_ LPCTSTR pszTargetName,
296 _In_ ULONG fContextReq,
297 _In_ ULONG TargetDataRep,
298 _In_opt_ PSecBufferDesc pInput,
299 _Inout_opt_ PSecBufferDesc pOutput)
300 {
301 return InitializeSecurityContext(phCredential, m_h, const_cast<LPTSTR>(pszTargetName), fContextReq, 0, TargetDataRep, pInput, 0, NULL, pOutput, &m_attrib, &m_expires);
302 }
303
304 protected:
310 void free_internal() noexcept override
311 {
312 DeleteSecurityContext(m_h);
313 delete m_h;
314 }
315
316 public:
317 ULONG m_attrib;
318 TimeStamp m_expires;
319 };
320
324 class sec_buffer_desc : public SecBufferDesc
325 {
326 public:
330 sec_buffer_desc(_Inout_count_(count) PSecBuffer buf, ULONG count, _In_ ULONG version = SECBUFFER_VERSION)
331 {
332 ulVersion = version;
333 cBuffers = count;
334 pBuffers = buf;
335 }
336
343 {
344 for (ULONG i = 0; i < cBuffers; i++) {
345 if (pBuffers[i].pvBuffer)
346 FreeContextBuffer(pBuffers[i].pvBuffer);
347 }
348 }
349 };
350
352
355
361 class sec_runtime_error : public num_runtime_error<SECURITY_STATUS>
362 {
363 public:
370 sec_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error<SECURITY_STATUS>(num, msg)
371 {
372 }
373
380 sec_runtime_error(_In_ error_type num, _In_opt_z_ const char *msg = nullptr) : num_runtime_error<SECURITY_STATUS>(num, msg)
381 {
382 }
383
389 sec_runtime_error(const sec_runtime_error &other) : num_runtime_error<SECURITY_STATUS>(other)
390 {
391 }
392 };
393
395}
Base abstract template class to support generic object handle keeping.
Definition: Common.h:569
PCredHandle handle_type
Datatype of the object handle this template class handles.
Definition: Common.h:574
handle_type m_h
Object handle.
Definition: Common.h:823
void attach(handle_type h) noexcept
Sets a new object handle for the class.
Definition: Common.h:786
Numerical runtime error.
Definition: Common.h:968
SECURITY_STATUS error_type
Error number type.
Definition: Common.h:970
SecBufferDesc wrapper class.
Definition: Sec.h:325
virtual ~sec_buffer_desc()
Frees the security buffer descriptor.
Definition: Sec.h:342
sec_buffer_desc(PSecBuffer buf, ULONG count, ULONG version=SECBUFFER_VERSION)
Initializes security buffer descriptor.
Definition: Sec.h:330
PCtxtHandle wrapper class.
Definition: Sec.h:202
sec_context(sec_context &&h) noexcept
Move constructor.
Definition: Sec.h:219
SECURITY_STATUS process(PCredHandle phCredential, LPCTSTR pszTargetName, ULONG fContextReq, ULONG TargetDataRep, PSecBufferDesc pInput, PSecBufferDesc pOutput)
Continue security context.
Definition: Sec.h:293
virtual ~sec_context()
Frees the security context.
Definition: Sec.h:231
sec_context()
Initializes a new class instance with the object handle set to NULL.
Definition: Sec.h:207
SECURITY_STATUS initialize(PCredHandle phCredential, LPCTSTR pszTargetName, ULONG fContextReq, ULONG TargetDataRep, PSecBufferDesc pInput, PSecBufferDesc pOutput)
Initializes security context.
Definition: Sec.h:261
ULONG m_attrib
Context attributes.
Definition: Sec.h:317
TimeStamp m_expires
Context expiration time.
Definition: Sec.h:318
sec_context & operator=(sec_context &&h) noexcept
Move assignment.
Definition: Sec.h:242
void free_internal() noexcept override
Frees the security context.
Definition: Sec.h:310
PCredHandle wrapper class.
Definition: Sec.h:93
sec_credentials()
Initializes a new class instance with the object handle set to NULL.
Definition: Sec.h:100
void free_internal() noexcept override
Frees the security credentials.
Definition: Sec.h:188
TimeStamp m_expires
Credentials expiration time.
Definition: Sec.h:195
sec_credentials(sec_credentials &&h) noexcept
Move constructor.
Definition: Sec.h:122
virtual ~sec_credentials()
Frees the security credentials.
Definition: Sec.h:133
sec_credentials(handle_type h, const TimeStamp expires)
Initializes a new class with an already available object handle.
Definition: Sec.h:111
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:162
sec_credentials & operator=(sec_credentials &&h) noexcept
Move assignment.
Definition: Sec.h:144
Security runtime error.
Definition: Sec.h:362
sec_runtime_error(error_type num, const char *msg=nullptr)
Constructs an exception.
Definition: Sec.h:380
sec_runtime_error(const sec_runtime_error &other)
Copies an exception.
Definition: Sec.h:389
sec_runtime_error(error_type num, const std::string &msg)
Constructs an exception.
Definition: Sec.h:370
#define WINSTD_NONCOPYABLE(C)
Declares a class as non-copyable.
Definition: Common.h:66
#define WINSTD_STACK_BUFFER_BYTES
Size of the stack buffer in bytes used for initial system function call.
Definition: Common.h:93
static const PCredHandle invalid
Invalid handle value.
Definition: Common.h:579