WinStd
Windows Win32 API using Standard C++
Loading...
Searching...
No Matches
Sec.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2024 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 sName.resize(ulSize - 1);
38 if (::GetUserNameExA(NameFormat, &ulSize[0], &ulSize))
39 return TRUE;
40 }
41 return FALSE;
42}
43
49template<class _Traits, class _Ax>
50static BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sName)
51{
52 wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
53 ULONG ulSize = _countof(szStackBuffer);
54
55 // Try with stack buffer first.
56 if (::GetUserNameExW(NameFormat, szStackBuffer, &ulSize)) {
57 // Copy from stack.
58 sName.assign(szStackBuffer, ulSize);
59 return TRUE;
60 }
61 if (::GetLastError() == ERROR_MORE_DATA) {
62 // Allocate buffer on heap and retry.
63 sName.resize(ulSize - 1);
64 if (::GetUserNameExW(NameFormat, &sName[0], &ulSize))
65 return TRUE;
66 }
67 return FALSE;
68}
69
70#endif
71
73
74namespace winstd
75{
78
82 class sec_credentials : public handle<PCredHandle, NULL>
83 {
85
86 public:
91 {
92 m_expires.QuadPart = -1;
93 }
94
101 sec_credentials(_In_opt_ handle_type h, _In_ const TimeStamp expires) :
102 m_expires(expires),
103 handle(h)
104 {}
105
111 sec_credentials(_Inout_ sec_credentials &&h) noexcept :
112 m_expires(std::move(h.m_expires)),
113 handle<PCredHandle, NULL>(std::move(h))
114 {}
115
122 {
123 if (m_h != invalid)
125 }
126
133 {
134 if (this != std::addressof(h)) {
135 *(handle<handle_type, NULL>*)this = std::move(h);
136 m_expires = std::move(h.m_expires);
137 }
138 return *this;
139 }
140
150 SECURITY_STATUS acquire(
151 _In_opt_ LPTSTR pszPrincipal,
152 _In_ LPTSTR pszPackage,
153 _In_ unsigned long fCredentialUse,
154 _In_opt_ void *pvLogonId,
155 _In_opt_ void *pAuthData,
156 _In_opt_ SEC_GET_KEY_FN pGetKeyFn = NULL,
157 _In_opt_ void *pvGetKeyArgument = NULL)
158 {
159 handle_type h = new CredHandle;
160 TimeStamp exp;
161 SECURITY_STATUS res = AcquireCredentialsHandle(pszPrincipal, pszPackage, fCredentialUse, pvLogonId, pAuthData, pGetKeyFn, pvGetKeyArgument, h, &exp);
162 if (SUCCEEDED(res)) {
163 attach(h);
164 m_expires = exp;
165 } else
166 delete h;
167 return res;
168 }
169
170 protected:
176 void free_internal() noexcept override
177 {
178 FreeCredentialsHandle(m_h);
179 delete m_h;
180 }
181
182 public:
183 TimeStamp m_expires;
184 };
185
189 class sec_context : public handle<PCtxtHandle, NULL>
190 {
191 public:
196 m_attrib(0),
197 handle<PCtxtHandle, NULL>()
198 {
199 m_expires.QuadPart = -1;
200 }
201
207 sec_context(_Inout_ sec_context &&h) noexcept :
208 m_attrib (std::move(h.m_attrib )),
209 m_expires(std::move(h.m_expires)),
210 handle<PCtxtHandle, NULL>(std::move(h))
211 {}
212
218 virtual ~sec_context()
219 {
220 if (m_h != invalid)
222 }
223
229 sec_context& operator=(_Inout_ sec_context &&h) noexcept
230 {
231 if (this != std::addressof(h)) {
232 *(handle<handle_type, NULL>*)this = std::move(h);
233 m_attrib = std::move(h.m_attrib);
234 m_expires = std::move(h.m_expires);
235 }
236 return *this;
237 }
238
248 SECURITY_STATUS initialize(
249 _In_opt_ PCredHandle phCredential,
250 _In_opt_z_ LPCTSTR pszTargetName,
251 _In_ ULONG fContextReq,
252 _In_ ULONG TargetDataRep,
253 _In_opt_ PSecBufferDesc pInput,
254 _Inout_opt_ PSecBufferDesc pOutput)
255 {
256 handle_type h = new CtxtHandle;
257 h->dwUpper = 0;
258 h->dwLower = 0;
259 ULONG attr;
260 TimeStamp exp;
261 SECURITY_STATUS res = InitializeSecurityContext(phCredential, NULL, const_cast<LPTSTR>(pszTargetName), fContextReq, 0, TargetDataRep, pInput, 0, h, pOutput, &attr, &exp);
262 if (SUCCEEDED(res)) {
263 attach(h);
264 m_attrib = attr;
265 m_expires = exp;
266 } else
267 delete h;
268 return res;
269 }
270
280 SECURITY_STATUS process(
281 _In_opt_ PCredHandle phCredential,
282 _In_opt_z_ LPCTSTR pszTargetName,
283 _In_ ULONG fContextReq,
284 _In_ ULONG TargetDataRep,
285 _In_opt_ PSecBufferDesc pInput,
286 _Inout_opt_ PSecBufferDesc pOutput)
287 {
288 return InitializeSecurityContext(phCredential, m_h, const_cast<LPTSTR>(pszTargetName), fContextReq, 0, TargetDataRep, pInput, 0, NULL, pOutput, &m_attrib, &m_expires);
289 }
290
291 protected:
297 void free_internal() noexcept override
298 {
299 DeleteSecurityContext(m_h);
300 delete m_h;
301 }
302
303 public:
304 ULONG m_attrib;
305 TimeStamp m_expires;
306 };
307
311 class sec_buffer_desc : public SecBufferDesc
312 {
313 public:
317 sec_buffer_desc(_Inout_count_(count) PSecBuffer buf, ULONG count, _In_ ULONG version = SECBUFFER_VERSION)
318 {
319 ulVersion = version;
320 cBuffers = count;
321 pBuffers = buf;
322 }
323
330 {
331 for (ULONG i = 0; i < cBuffers; i++) {
332 if (pBuffers[i].pvBuffer)
333 FreeContextBuffer(pBuffers[i].pvBuffer);
334 }
335 }
336 };
337
339
342
348 class sec_runtime_error : public num_runtime_error<SECURITY_STATUS>
349 {
350 public:
357 sec_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error<SECURITY_STATUS>(num, msg)
358 {}
359
366 sec_runtime_error(_In_ error_type num, _In_opt_z_ const char *msg = nullptr) : num_runtime_error<SECURITY_STATUS>(num, msg)
367 {}
368
374 sec_runtime_error(const sec_runtime_error &other) : num_runtime_error<SECURITY_STATUS>(other)
375 {}
376 };
377
379}
Base abstract template class to support generic object handle keeping.
Definition Common.h:874
handle_type m_h
Definition Common.h:1126
void attach(handle_type h) noexcept
Definition Common.h:1089
PCredHandle handle_type
Definition Common.h:879
Numerical runtime error.
Definition Common.h:1331
SECURITY_STATUS error_type
Definition Common.h:1333
SecBufferDesc wrapper class.
Definition Sec.h:312
virtual ~sec_buffer_desc()
Frees the security buffer descriptor.
Definition Sec.h:329
sec_buffer_desc(PSecBuffer buf, ULONG count, ULONG version=SECBUFFER_VERSION)
Initializes security buffer descriptor.
Definition Sec.h:317
PCtxtHandle wrapper class.
Definition Sec.h:190
sec_context(sec_context &&h) noexcept
Move constructor.
Definition Sec.h:207
SECURITY_STATUS process(PCredHandle phCredential, LPCTSTR pszTargetName, ULONG fContextReq, ULONG TargetDataRep, PSecBufferDesc pInput, PSecBufferDesc pOutput)
Continue security context.
Definition Sec.h:280
virtual ~sec_context()
Frees the security context.
Definition Sec.h:218
sec_context()
Initializes a new class instance with the object handle set to NULL.
Definition Sec.h:195
SECURITY_STATUS initialize(PCredHandle phCredential, LPCTSTR pszTargetName, ULONG fContextReq, ULONG TargetDataRep, PSecBufferDesc pInput, PSecBufferDesc pOutput)
Initializes security context.
Definition Sec.h:248
ULONG m_attrib
Context attributes.
Definition Sec.h:304
TimeStamp m_expires
Context expiration time.
Definition Sec.h:305
sec_context & operator=(sec_context &&h) noexcept
Move assignment.
Definition Sec.h:229
void free_internal() noexcept override
Frees the security context.
Definition Sec.h:297
PCredHandle wrapper class.
Definition Sec.h:83
sec_credentials()
Initializes a new class instance with the object handle set to NULL.
Definition Sec.h:90
void free_internal() noexcept override
Frees the security credentials.
Definition Sec.h:176
TimeStamp m_expires
Credentials expiration time.
Definition Sec.h:183
sec_credentials(sec_credentials &&h) noexcept
Move constructor.
Definition Sec.h:111
virtual ~sec_credentials()
Frees the security credentials.
Definition Sec.h:121
sec_credentials(handle_type h, const TimeStamp expires)
Initializes a new class with an already available object handle.
Definition Sec.h:101
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:150
sec_credentials & operator=(sec_credentials &&h) noexcept
Move assignment.
Definition Sec.h:132
Security runtime error.
Definition Sec.h:349
sec_runtime_error(error_type num, const char *msg=nullptr)
Constructs an exception.
Definition Sec.h:366
sec_runtime_error(const sec_runtime_error &other)
Copies an exception.
Definition Sec.h:374
sec_runtime_error(error_type num, const std::string &msg)
Constructs an exception.
Definition Sec.h:357
#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
Definition Common.h:884