mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-14 00:14:11 +09:00
Merge pull request #12171 from jadahl/wip/ntlm-kerberos-package-info
Add support for querying SECPKG_ATTR_PACKAGE_INFO to NTLM and Kerberos
This commit is contained in:
@@ -767,6 +767,17 @@ owned by rdpRdp */
|
||||
FREERDP_API SECURITY_STATUS freerdp_nla_QueryContextAttributes(rdpContext* context,
|
||||
DWORD ulAttr, PVOID pBuffer);
|
||||
|
||||
/** Calls FreeContextbuffer on the SSPI context associated with the NLA part of the RDP context
|
||||
*
|
||||
* \param context the RDP context
|
||||
* \param pBuffer an opaque pointer to free
|
||||
* \returns a SECURITY_STATUS indicating if the operation completed successfully
|
||||
* \since version 3.22.0
|
||||
*
|
||||
* Supported buffers are ones retrieved from SECPKG_ATTR_PACKAGE_INFO.
|
||||
*/
|
||||
FREERDP_API SECURITY_STATUS freerdp_nla_FreeContextBuffer(rdpContext* context, PVOID pBuffer);
|
||||
|
||||
FREERDP_API void clearChannelError(rdpContext* context);
|
||||
FREERDP_API HANDLE getChannelErrorEventHandle(rdpContext* context);
|
||||
FREERDP_API UINT getChannelError(const rdpContext* context);
|
||||
|
||||
@@ -1349,6 +1349,20 @@ SECURITY_STATUS freerdp_nla_QueryContextAttributes(rdpContext* context, DWORD ul
|
||||
return nla_QueryContextAttributes(nla, ulAttr, pBuffer);
|
||||
}
|
||||
|
||||
SECURITY_STATUS freerdp_nla_FreeContextBuffer(rdpContext* context, PVOID pBuffer)
|
||||
{
|
||||
WINPR_ASSERT(context);
|
||||
WINPR_ASSERT(context->rdp);
|
||||
|
||||
rdpNla* nla = context->rdp->nla;
|
||||
if (!nla)
|
||||
nla = transport_get_nla(context->rdp->transport);
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
return nla_FreeContextBuffer(nla, pBuffer);
|
||||
}
|
||||
|
||||
HANDLE getChannelErrorEventHandle(rdpContext* context)
|
||||
{
|
||||
WINPR_ASSERT(context);
|
||||
|
||||
@@ -2455,3 +2455,14 @@ SECURITY_STATUS nla_QueryContextAttributes(rdpNla* nla, DWORD ulAttr, PVOID pBuf
|
||||
|
||||
return table->QueryContextAttributes(&context, ulAttr, pBuffer);
|
||||
}
|
||||
|
||||
SECURITY_STATUS nla_FreeContextBuffer(rdpNla* nla, PVOID pBuffer)
|
||||
{
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
SecurityFunctionTable* table = NULL;
|
||||
CtxtHandle context = { 0 };
|
||||
credssp_auth_tableAndContext(nla->auth, &table, &context);
|
||||
|
||||
return table->FreeContextBuffer(pBuffer);
|
||||
}
|
||||
|
||||
@@ -78,5 +78,6 @@ FREERDP_LOCAL void nla_set_early_user_auth(rdpNla* nla, BOOL earlyUserAuth);
|
||||
FREERDP_LOCAL BOOL nla_encrypt(rdpNla* nla, const SecBuffer* inBuffer, SecBuffer* outBuffer);
|
||||
FREERDP_LOCAL BOOL nla_decrypt(rdpNla* nla, const SecBuffer* inBuffer, SecBuffer* outBuffer);
|
||||
FREERDP_LOCAL SECURITY_STATUS nla_QueryContextAttributes(rdpNla* nla, DWORD ulAttr, PVOID pBuffer);
|
||||
FREERDP_LOCAL SECURITY_STATUS nla_FreeContextBuffer(rdpNla* nla, PVOID pBuffer);
|
||||
|
||||
#endif /* FREERDP_LIB_CORE_NLA_H */
|
||||
|
||||
@@ -1781,6 +1781,33 @@ fail:
|
||||
return krb5_error_to_SECURITY_STATUS(rv);
|
||||
}
|
||||
|
||||
static SECURITY_STATUS kerberos_ATTR_PACKAGE_INFO(KRB_CONTEXT* context,
|
||||
KRB_CREDENTIALS* credentials,
|
||||
SecPkgContext_PackageInfo* PackageInfo)
|
||||
{
|
||||
size_t size = sizeof(SecPkgInfoA);
|
||||
SecPkgInfoA* pPackageInfo =
|
||||
(SecPkgInfoA*)sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
|
||||
|
||||
if (!pPackageInfo)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
pPackageInfo->fCapabilities = KERBEROS_SecPkgInfoA.fCapabilities;
|
||||
pPackageInfo->wVersion = KERBEROS_SecPkgInfoA.wVersion;
|
||||
pPackageInfo->wRPCID = KERBEROS_SecPkgInfoA.wRPCID;
|
||||
pPackageInfo->cbMaxToken = KERBEROS_SecPkgInfoA.cbMaxToken;
|
||||
pPackageInfo->Name = _strdup(KERBEROS_SecPkgInfoA.Name);
|
||||
pPackageInfo->Comment = _strdup(KERBEROS_SecPkgInfoA.Comment);
|
||||
|
||||
if (!pPackageInfo->Name || !pPackageInfo->Comment)
|
||||
{
|
||||
sspi_ContextBufferFree(pPackageInfo);
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
PackageInfo->PackageInfo = pPackageInfo;
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
static SECURITY_STATUS kerberos_ATTR_TICKET_LOGON(KRB_CONTEXT* context,
|
||||
KRB_CREDENTIALS* credentials,
|
||||
KERB_TICKET_LOGON* ticketLogon)
|
||||
@@ -1883,6 +1910,10 @@ static SECURITY_STATUS SEC_ENTRY kerberos_QueryContextAttributesA(PCtxtHandle ph
|
||||
return kerberos_ATTR_AUTH_IDENTITY(context, credentials,
|
||||
(SecPkgContext_AuthIdentity*)pBuffer);
|
||||
|
||||
case SECPKG_ATTR_PACKAGE_INFO:
|
||||
return kerberos_ATTR_PACKAGE_INFO(context, credentials,
|
||||
(SecPkgContext_PackageInfo*)pBuffer);
|
||||
|
||||
case SECPKG_CRED_ATTR_TICKET_LOGON:
|
||||
return kerberos_ATTR_TICKET_LOGON(context, credentials, (KERB_TICKET_LOGON*)pBuffer);
|
||||
|
||||
|
||||
@@ -897,6 +897,31 @@ static SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phCont
|
||||
{
|
||||
return ntlm_computeMicValue(context, (SecBuffer*)pBuffer);
|
||||
}
|
||||
else if (ulAttribute == SECPKG_ATTR_PACKAGE_INFO)
|
||||
{
|
||||
SecPkgContext_PackageInfo* PackageInfo = (SecPkgContext_PackageInfo*)pBuffer;
|
||||
size_t size = sizeof(SecPkgInfoA);
|
||||
SecPkgInfoA* pPackageInfo =
|
||||
(SecPkgInfoA*)sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
|
||||
|
||||
if (!pPackageInfo)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
pPackageInfo->fCapabilities = NTLM_SecPkgInfoA.fCapabilities;
|
||||
pPackageInfo->wVersion = NTLM_SecPkgInfoA.wVersion;
|
||||
pPackageInfo->wRPCID = NTLM_SecPkgInfoA.wRPCID;
|
||||
pPackageInfo->cbMaxToken = NTLM_SecPkgInfoA.cbMaxToken;
|
||||
pPackageInfo->Name = _strdup(NTLM_SecPkgInfoA.Name);
|
||||
pPackageInfo->Comment = _strdup(NTLM_SecPkgInfoA.Comment);
|
||||
|
||||
if (!pPackageInfo->Name || !pPackageInfo->Comment)
|
||||
{
|
||||
sspi_ContextBufferFree(pPackageInfo);
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
PackageInfo->PackageInfo = pPackageInfo;
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
WLog_ERR(TAG, "TODO: Implement ulAttribute=0x%08" PRIx32, ulAttribute);
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
|
||||
@@ -147,7 +147,7 @@ static void sspi_ContextBufferAllocTableFree(void)
|
||||
ContextBufferAllocTable.entries = NULL;
|
||||
}
|
||||
|
||||
static void* sspi_ContextBufferAlloc(UINT32 allocatorIndex, size_t size)
|
||||
void* sspi_ContextBufferAlloc(UINT32 allocatorIndex, size_t size)
|
||||
{
|
||||
void* contextBuffer = NULL;
|
||||
|
||||
@@ -1050,7 +1050,7 @@ static const SecurityFunctionTableW* sspi_GetSecurityFunctionTableWByNameA(const
|
||||
static void FreeContextBuffer_EnumerateSecurityPackages(void* contextBuffer);
|
||||
static void FreeContextBuffer_QuerySecurityPackageInfo(void* contextBuffer);
|
||||
|
||||
static void sspi_ContextBufferFree(void* contextBuffer)
|
||||
void sspi_ContextBufferFree(void* contextBuffer)
|
||||
{
|
||||
UINT32 allocatorIndex = 0;
|
||||
|
||||
|
||||
@@ -25,4 +25,7 @@
|
||||
SecurityFunctionTableW* SEC_ENTRY winpr_InitSecurityInterfaceW(void);
|
||||
SecurityFunctionTableA* SEC_ENTRY winpr_InitSecurityInterfaceA(void);
|
||||
|
||||
void* sspi_ContextBufferAlloc(UINT32 allocatorIndex, size_t size);
|
||||
void sspi_ContextBufferFree(void* contextBuffer);
|
||||
|
||||
#endif /* WINPR_SSPI_WINPR_H */
|
||||
|
||||
Reference in New Issue
Block a user