Support for credential management added

This commit is contained in:
Simon Rozman 2016-05-17 14:27:43 +02:00
parent 9b60503173
commit dcdc63fde6
4 changed files with 275 additions and 0 deletions

View File

@ -82,6 +82,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\WinStd\Base64.h" />
<ClInclude Include="..\include\WinStd\Cred.h" />
<ClInclude Include="..\include\WinStd\Crypt.h" />
<ClInclude Include="..\include\WinStd\EAP.h" />
<ClInclude Include="..\include\WinStd\Common.h" />

View File

@ -49,5 +49,8 @@
<ClInclude Include="..\include\WinStd\Base64.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\WinStd\Cred.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

270
include/WinStd/Cred.h Normal file
View File

@ -0,0 +1,270 @@
/*
Copyright 1991-2016 Amebis
Copyright 2016 GÉANT
This file is part of WinStd.
Setup is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Setup is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Setup. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Common.h"
#include <wincred.h>
#include <memory>
namespace winstd
{
template <class _Ty> struct CredFree_delete;
template <class _Ty> struct CredFree_delete<_Ty[]>;
class credential;
}
template<class _Elem, class _Traits, class _Ax> inline BOOL CredProtectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType);
template<class _Elem, class _Traits, class _Ax> inline BOOL CredProtectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType);
template<class _Elem, class _Traits, class _Ax> inline BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials);
template<class _Elem, class _Traits, class _Ax> inline BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials);
#pragma once
namespace winstd
{
/// \addtogroup ATLCryptoAPI
/// @{
///
/// Deleter for unique_ptr using CredFree
///
template <class _Ty> struct CredFree_delete
{
typedef CredFree_delete<_Ty> _Myt;
///
/// Default construct
///
CredFree_delete() {}
///
/// Construct from another CredFree_delete
///
template <class _Ty2> CredFree_delete(const CredFree_delete<_Ty2>&) {}
///
/// Delete a pointer
///
void operator()(_Ty *_Ptr) const
{
CredFree(_Ptr);
}
};
///
/// Deleter for unique_ptr to array of unknown size using CredFree
///
template <class _Ty> struct CredFree_delete<_Ty[]>
{
typedef CredFree_delete<_Ty> _Myt;
///
/// Default construct
///
CredFree_delete() {}
///
/// Delete a pointer
///
void operator()(_Ty *_Ptr) const
{
CredFree(_Ptr);
}
///
/// Delete a pointer of another type
///
template<class _Other>
void operator()(_Other *) const
{
CredFree(_Ptr);
}
};
///
/// PCREDENTIAL wrapper class
///
class credential : public handle<PCREDENTIAL>
{
public:
///
/// Closes the credential.
///
/// \sa [CredFree function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374796.aspx)
///
virtual ~credential()
{
if (m_h)
CredFree(m_h);
}
protected:
///
/// Closes the credential.
///
/// \sa [CredFree function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374796.aspx)
///
virtual void free_internal()
{
CredFree(m_h);
}
};
/// @}
}
///
/// \defgroup WinStdCryptoAPI Cryptography API
/// Integrates WinStd classes with Microsoft Cryptography API
///
/// @{
inline BOOL CredEnumerate(_In_ LPCTSTR Filter, _In_ DWORD Flags, _Out_ DWORD *Count, _Out_ std::unique_ptr<PCREDENTIAL[], winstd::CredFree_delete<PCREDENTIAL[]> > &cCredentials)
{
PCREDENTIAL *pCredentials;
if (CredEnumerate(Filter, Flags, Count, &pCredentials)) {
cCredentials.swap(std::unique_ptr<PCREDENTIAL[], winstd::CredFree_delete<PCREDENTIAL[]> >(pCredentials));
return TRUE;
} else
return FALSE;
}
///
/// Encrypts the specified credentials so that only the current security context can decrypt them.
///
/// \sa [CredProtect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374803.aspx)
///
template<class _Elem, class _Traits, class _Ax>
inline BOOL CredProtectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType)
{
_Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize = _countof(buf);
// Try with the stack buffer first.
if (CredProtectA(fAsSelf, (LPSTR)pszCredentials, cchCredentials, buf, &dwSize, ProtectionType)) {
// Copy from stack.
sProtectedCredentials.assign(buf, dwSize - 1);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry.
auto buf = std::unique_ptr<_Elem[]>(new _Elem[dwSize]);
if (CredProtectA(fAsSelf, (LPSTR)pszCredentials, cchCredentials, buf.get(), &dwSize, ProtectionType)) {
sProtectedCredentials.assign(buf.get(), dwSize - 1);
return TRUE;
}
}
return FALSE;
}
///
/// Encrypts the specified credentials so that only the current security context can decrypt them.
///
/// \sa [CredProtect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374803.aspx)
///
template<class _Elem, class _Traits, class _Ax>
inline BOOL CredProtectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType)
{
_Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize = _countof(buf);
// Try with the stack buffer first.
if (CredProtectW(fAsSelf, (LPWSTR)pszCredentials, cchCredentials, buf, &dwSize, ProtectionType)) {
// Copy from stack.
sProtectedCredentials.assign(buf, dwSize - 1);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry.
auto buf = std::unique_ptr<_Elem[]>(new _Elem[dwSize]);
if (CredProtectW(fAsSelf, (LPWSTR)pszCredentials, cchCredentials, buf.get(), &dwSize, ProtectionType)) {
sProtectedCredentials.assign(buf.get(), dwSize - 1);
return TRUE;
}
}
return FALSE;
}
///
/// Decrypts credentials that were previously encrypted by using the CredProtect function.
///
/// \sa [CredUnprotect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa375186.aspx)
///
template<class _Elem, class _Traits, class _Ax>
inline BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials)
{
_Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize = _countof(buf);
// Try with the stack buffer first.
if (CredUnprotectA(fAsSelf, (LPSTR)pszProtectedCredentials, cchCredentials, buf, &dwSize)) {
// Copy from stack.
sCredentials.assign(buf, dwSize);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry.
auto buf = std::unique_ptr<_Elem[]>(new _Elem[dwSize]);
if (CredUnprotectA(fAsSelf, (LPSTR)pszProtectedCredentials, cchCredentials, buf.get(), &dwSize)) {
sCredentials.assign(buf.get(), dwSize);
return TRUE;
}
}
return FALSE;
}
///
/// Decrypts credentials that were previously encrypted by using the CredProtect function.
///
/// \sa [CredUnprotect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa375186.aspx)
///
template<class _Elem, class _Traits, class _Ax>
inline BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials)
{
_Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
DWORD dwSize = _countof(buf);
// Try with the stack buffer first.
if (CredUnprotectW(fAsSelf, (LPWSTR)pszProtectedCredentials, cchCredentials, buf, &dwSize)) {
// Copy from stack.
sCredentials.assign(buf, dwSize);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry.
auto buf = std::unique_ptr<_Elem[]>(new _Elem[dwSize]);
if (CredUnprotectW(fAsSelf, (LPWSTR)pszProtectedCredentials, cchCredentials, buf.get(), &dwSize)) {
sCredentials.assign(buf.get(), dwSize);
return TRUE;
}
}
return FALSE;
}
/// @}

View File

@ -21,6 +21,7 @@
#pragma once
#include "../include/WinStd/Base64.h"
#include "../include/WinStd/Cred.h"
#include "../include/WinStd/Crypt.h"
#include "../include/WinStd/EAP.h"
#include "../include/WinStd/Common.h"