windows-nt/Source/XPSP1/NT/net/layer2svc/eapol/service/elrpc.c
2020-09-26 16:20:57 +08:00

510 lines
13 KiB
C

/*++
Copyright (c) 1999, Microsoft Corporation
Module Name:
elrpc.c
Abstract:
This module deals with RPC requests
Revision History:
sachins, Mar 19 2000, Created
--*/
#include "pcheapol.h"
#pragma hdrstop
DWORD
RpcEapolGetCustomAuthData (
STRING_HANDLE pSrvAddr,
PWCHAR pwszGuid,
DWORD dwEapTypeId,
RAW_DATA rdSSID,
PRAW_DATA prdConnInfo
)
{
DWORD dwRetCode = NO_ERROR;
InterlockedIncrement (&g_lWorkerThreads);
do
{
if ((dwRetCode = WZCSvcCheckRPCAccess (WZC_ACCESS_QUERY)) != NO_ERROR)
{
break;
}
if (!(g_dwModulesStarted & ALL_MODULES_STARTED))
{
dwRetCode = ERROR_INVALID_STATE;
break;
}
if ((pwszGuid == NULL) || (prdConnInfo == NULL))
{
dwRetCode = ERROR_INVALID_PARAMETER;
break;
}
dwRetCode = ElGetCustomAuthData (
pwszGuid,
dwEapTypeId,
rdSSID.dwDataLen,
rdSSID.pData,
prdConnInfo->pData,
&(prdConnInfo->dwDataLen)
);
}
while (FALSE);
InterlockedDecrement (&g_lWorkerThreads);
return dwRetCode;
}
DWORD
RpcEapolSetCustomAuthData (
STRING_HANDLE pSrvAddr,
PWCHAR pwszGuid,
DWORD dwEapTypeId,
RAW_DATA rdSSID,
PRAW_DATA prdConnInfo
)
{
EAPOL_POLICY_DATA *pEAPOLPolicyData = NULL;
BOOLEAN fPolicyFound = FALSE;
PBYTE pbAuthData = NULL;
DWORD dwSizeOfAuthData = 0;
DWORD dwRetCode = NO_ERROR;
InterlockedIncrement (&g_lWorkerThreads);
do
{
if ((dwRetCode = WZCSvcCheckRPCAccess (WZC_ACCESS_SET)) != NO_ERROR)
{
break;
}
if (!(g_dwModulesStarted & ALL_MODULES_STARTED))
{
dwRetCode = ERROR_INVALID_STATE;
break;
}
if ((pwszGuid == NULL) || (prdConnInfo == NULL))
{
dwRetCode = ERROR_INVALID_PARAMETER;
break;
}
ACQUIRE_WRITE_LOCK (&g_PolicyLock);
if (ElFindPolicyData (
rdSSID.dwDataLen,
rdSSID.pData,
g_pEAPOLPolicyList,
&pEAPOLPolicyData
) == NO_ERROR)
{
fPolicyFound = TRUE;
}
RELEASE_WRITE_LOCK (&g_PolicyLock);
if (fPolicyFound)
{
if ((dwRetCode = ElGetCustomAuthData (
pwszGuid,
dwEapTypeId,
rdSSID.dwDataLen,
rdSSID.pData,
NULL,
&dwSizeOfAuthData
)) == ERROR_BUFFER_TOO_SMALL)
{
if (dwSizeOfAuthData != prdConnInfo->dwDataLen)
{
TRACE0 (RPC, "RpcEapolSetCustomAuthData: POLICY: Cannot change data for global setting data: unequal size");
dwRetCode = ERROR_ACCESS_DENIED;
break;
}
else
{
pbAuthData = MALLOC (dwSizeOfAuthData);
if (pbAuthData == NULL)
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
TRACE0 (RPC, "RpcEapolSetCustomAuthData: Error in memory allocation for EAP blob");
break;
}
if ((dwRetCode = ElGetCustomAuthData (
pwszGuid,
dwEapTypeId,
rdSSID.dwDataLen,
rdSSID.pData,
pbAuthData,
&dwSizeOfAuthData
)) != NO_ERROR)
{
TRACE1 (USER, "ElReadPerPortRegistryParams: ElGetCustomAuthData failed with %ld",
dwRetCode);
break;
}
if (memcmp (prdConnInfo->pData, pbAuthData,
dwSizeOfAuthData) != 0)
{
TRACE0 (RPC, "RpcEapolSetCustomAuthData: POLICY: Cannot change data for global setting data: Content change");
dwRetCode = ERROR_ACCESS_DENIED;
break;
}
// ignore setting
dwRetCode = NO_ERROR;
break;
}
}
else
{
break;
}
}
if ((dwRetCode = ElSetCustomAuthData (
pwszGuid,
dwEapTypeId,
rdSSID.dwDataLen,
rdSSID.pData,
prdConnInfo->pData,
&(prdConnInfo->dwDataLen)
)) != NO_ERROR)
{
break;
}
}
while (FALSE);
if (pbAuthData != NULL)
{
FREE (pbAuthData);
}
InterlockedDecrement (&g_lWorkerThreads);
return dwRetCode;
}
DWORD
RpcEapolGetInterfaceParams (
STRING_HANDLE pSrvAddr,
PWCHAR pwszGuid,
PEAPOL_INTF_PARAMS pIntfParams
)
{
DWORD dwRetCode = NO_ERROR;
InterlockedIncrement (&g_lWorkerThreads);
do
{
if ((dwRetCode = WZCSvcCheckRPCAccess (WZC_ACCESS_QUERY)) != NO_ERROR)
{
break;
}
if (!(g_dwModulesStarted & ALL_MODULES_STARTED))
{
dwRetCode = ERROR_INVALID_STATE;
break;
}
if ((pwszGuid == NULL) || (pIntfParams == NULL))
{
dwRetCode = ERROR_INVALID_PARAMETER;
break;
}
dwRetCode = ElGetInterfaceParams (
pwszGuid,
pIntfParams
);
}
while (FALSE);
InterlockedDecrement (&g_lWorkerThreads);
return dwRetCode;
}
DWORD
RpcEapolSetInterfaceParams (
STRING_HANDLE pSrvAddr,
PWCHAR pwszGuid,
PEAPOL_INTF_PARAMS pIntfParams
)
{
EAPOL_POLICY_DATA *pEAPOLPolicyData = NULL;
EAPOL_INTF_PARAMS PolicyIntfParams = {0};
BOOLEAN fPolicyFound = FALSE;
DWORD dwRetCode = NO_ERROR;
InterlockedIncrement (&g_lWorkerThreads);
do
{
if ((dwRetCode = WZCSvcCheckRPCAccess (WZC_ACCESS_SET)) != NO_ERROR)
{
break;
}
if (!(g_dwModulesStarted & ALL_MODULES_STARTED))
{
dwRetCode = ERROR_INVALID_STATE;
break;
}
if ((pwszGuid == NULL) || (pIntfParams == NULL))
{
dwRetCode = ERROR_INVALID_PARAMETER;
break;
}
ACQUIRE_WRITE_LOCK (&g_PolicyLock);
if (ElFindPolicyData (
pIntfParams->dwSizeOfSSID,
pIntfParams->bSSID,
g_pEAPOLPolicyList,
&pEAPOLPolicyData
) == NO_ERROR)
{
fPolicyFound = TRUE;
}
RELEASE_WRITE_LOCK (&g_PolicyLock);
if (fPolicyFound)
{
if ((dwRetCode = ElGetInterfaceParams (
pwszGuid,
&PolicyIntfParams
)) == NO_ERROR)
{
if (memcmp ((PVOID)pIntfParams, (PVOID)&PolicyIntfParams,
sizeof(EAPOL_INTF_PARAMS)) != 0)
{
TRACE0 (RPC, "RpcEapolSetInterfaceParams: POLICY: Cannot change data for global setting data");
dwRetCode = ERROR_ACCESS_DENIED;
break;
}
else
{
// ignore setting
break;
}
}
else
{
break;
}
}
if ((dwRetCode = ElSetInterfaceParams (
pwszGuid,
pIntfParams
)) != NO_ERROR)
{
break;
}
// Setting interface params will be the only action that will
// cause 802.1X to restart state machine
if ((dwRetCode = ElPostEapConfigChanged (
pwszGuid,
pIntfParams))
!= NO_ERROR)
{
break;
}
}
while (FALSE);
InterlockedDecrement (&g_lWorkerThreads);
return dwRetCode;
}
DWORD
RpcEapolReAuthenticateInterface (
STRING_HANDLE pSrvAddr,
PWCHAR pwszGuid
)
{
DWORD dwRetCode = NO_ERROR;
InterlockedIncrement (&g_lWorkerThreads);
do
{
if ((dwRetCode = WZCSvcCheckRPCAccess (WZC_ACCESS_QUERY)) != NO_ERROR)
{
break;
}
if (!(g_dwModulesStarted & ALL_MODULES_STARTED))
{
dwRetCode = ERROR_INVALID_STATE;
break;
}
if (pwszGuid == NULL)
{
dwRetCode = ERROR_INVALID_PARAMETER;
break;
}
if ((dwRetCode = ElReAuthenticateInterface (
pwszGuid))
!= NO_ERROR)
{
TRACE1 (RPC, "RpcEapolReAuthenticateInterface: ElEnumAndOpenInterfaces returned error %ld",
dwRetCode);
}
}
while (FALSE);
InterlockedDecrement (&g_lWorkerThreads);
return dwRetCode;
}
DWORD
RpcEapolQueryInterfaceState (
STRING_HANDLE pSrvAddr,
PWCHAR pwszGuid,
PEAPOL_INTF_STATE pIntfState
)
{
DWORD dwRetCode = NO_ERROR;
InterlockedIncrement (&g_lWorkerThreads);
do
{
if ((dwRetCode = WZCSvcCheckRPCAccess (WZC_ACCESS_QUERY)) != NO_ERROR)
{
break;
}
if (!(g_dwModulesStarted & ALL_MODULES_STARTED))
{
dwRetCode = ERROR_INVALID_STATE;
break;
}
if (pwszGuid == NULL)
{
dwRetCode = ERROR_INVALID_PARAMETER;
break;
}
if ((dwRetCode = ElQueryInterfaceState (
pwszGuid,
pIntfState
)) != NO_ERROR)
{
TRACE1 (RPC, "RpcEapolQueryInterfaceState: ElQueryInterfaceState failed with error %ld",
dwRetCode);
}
}
while (FALSE);
InterlockedDecrement (&g_lWorkerThreads);
return dwRetCode;
}
DWORD
RpcEapolUIResponse (
IN LPWSTR pSrvAddr,
IN EAPOL_EAP_UI_CONTEXT EapolUIContext,
IN EAPOLUI_RESP EapolUIResp
)
{
EAPOLUIRESPFUNC *pEapolUIRespFunc = NULL;
DWORD dwIndex = 0;
DWORD dwBlob = 0;
DWORD dwRetCode = NO_ERROR;
InterlockedIncrement (&g_lWorkerThreads);
do
{
if ((dwRetCode = WZCSvcCheckRPCAccess (WZC_ACCESS_QUERY)) != NO_ERROR)
{
break;
}
if (!(g_dwModulesStarted & ALL_MODULES_STARTED))
{
dwRetCode = ERROR_INVALID_STATE;
break;
}
for (dwIndex=0; dwIndex < NUM_EAPOL_DLG_MSGS; dwIndex++)
{
if (EapolUIContext.dwEAPOLUIMsgType ==
EapolUIRespFuncMap[dwIndex].dwEAPOLUIMsgType)
{
if (EapolUIRespFuncMap[dwIndex].EapolRespUIFunc)
{
// Verify if right number of data blobs are passed
// Blobs may have '0' length
for (dwBlob=0; dwBlob < EapolUIRespFuncMap[dwIndex].dwNumBlobs; dwBlob++)
{
#if 0
if (IsBadReadPtr (EapolUIResp.rdData[dwBlob].pData,
EapolUIResp.rdData[dwBlob].dwDataLen))
{
TRACE1 (RPC, "RpcEapolUIResponse: Bad blob %ld",
dwBlob);
dwRetCode = ERROR_INVALID_DATA;
goto Error;
}
#endif
}
TRACE1 (RPC, "RpcEapolUIResponse: Response function found, msg (%ld)",
EapolUIContext.dwEAPOLUIMsgType);
if ((dwRetCode =
EapolUIRespFuncMap[dwIndex].EapolRespUIFunc (
EapolUIContext,
EapolUIResp
)) != NO_ERROR)
{
TRACE1 (RPC, "RpcEapolUIResponse: Response function failed with error %ld",
dwRetCode);
}
}
else
{
TRACE1 (RPC, "RpcEapolUIResponse: No response function, msg (%ld)",
EapolUIContext.dwEAPOLUIMsgType);
}
break;
}
}
}
while (FALSE);
// Error:
InterlockedDecrement (&g_lWorkerThreads);
return dwRetCode;
}