Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

208 lines
5.9 KiB

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corp. All rights reserved.
//
// SYNOPSIS
//
// Defines the class PostEapRestrictions.
//
///////////////////////////////////////////////////////////////////////////////
#include "ias.h"
#include "posteap.h"
#include "sdoias.h"
IASREQUESTSTATUS PostEapRestrictions::onSyncRequest(
IRequest* pRequest
) throw ()
{
try
{
IASTL::IASRequest request(pRequest);
IASRESPONSE response = request.get_Response();
if (response == IAS_RESPONSE_INVALID)
{
IASATTRIBUTE* state = IASPeekAttribute(
request,
RADIUS_ATTRIBUTE_STATE,
IASTYPE_OCTET_STRING
);
if ((state != 0) && (state->Value.OctetString.dwLength > 0))
{
// If we made it here, then we have a Challenge-Reponse that no
// handler recognized, so we discard.
request.SetResponse(
IAS_RESPONSE_DISCARD_PACKET,
IAS_UNEXPECTED_REQUEST
);
return IAS_REQUEST_STATUS_HANDLED;
}
}
IASREASON result;
if (!CheckCertificateEku(request))
{
result = IAS_INVALID_CERT_EKU;
}
else
{
GenerateSessionTimeout(request);
result = IAS_SUCCESS;
// We apply user restrictions to Access-Rejects as well, so we only
// want to set Access-Accept if the response code is still invalid.
// This should only be true for unauthenticated requests.
if (response == IAS_RESPONSE_INVALID)
{
request.SetResponse(IAS_RESPONSE_ACCESS_ACCEPT, IAS_SUCCESS);
}
}
if (result != IAS_SUCCESS)
{
request.SetResponse(IAS_RESPONSE_ACCESS_REJECT, result);
}
}
catch (const _com_error&)
{
pRequest->SetResponse(IAS_RESPONSE_DISCARD_PACKET, IAS_INTERNAL_ERROR);
}
return IAS_REQUEST_STATUS_HANDLED;
}
bool PostEapRestrictions::CheckCertificateEku(IASTL::IASRequest& request)
{
// Is it an EAP-TLS request or a PEAP request?
IASTL::IASAttribute eapType;
DWORD attributeId = IAS_ATTRIBUTE_EAP_TYPEID;
if ( !eapType.load(request, attributeId) )
{
// should never go there. At least one EAP type should be enabled
return true;
}
if (eapType->Value.Integer != 13)
{
// Neither EAP-TLS nor PEAP-TLS
return true;
}
// Here it is either EAP-TLS or PEAP-TLS
// Are there any constraints on the certificate EKU?
AttributeVector allowed;
allowed.load(request, IAS_ATTRIBUTE_ALLOWED_CERTIFICATE_EKU);
if (allowed.empty())
{
return true;
}
//////////
// Check the constraints.
//////////
AttributeVector actual;
actual.load(request, IAS_ATTRIBUTE_CERTIFICATE_EKU);
for (AttributeVector::iterator i = actual.begin();
i != actual.end();
++i)
{
const char* actualOid = GetAnsiString(*(i->pAttribute));
if (actualOid != 0)
{
for (AttributeVector::iterator j = allowed.begin();
j != allowed.end();
++j)
{
const char* allowedOid = GetAnsiString(*(j->pAttribute));
if ((allowedOid != 0) && (strcmp(allowedOid, actualOid) == 0))
{
return true;
}
}
}
}
return false;
}
void PostEapRestrictions::GenerateSessionTimeout(IASTL::IASRequest& request)
{
// retrieve the generate-session-timeout attribute.
IASATTRIBUTE* generate = IASPeekAttribute(
request,
IAS_ATTRIBUTE_GENERATE_SESSION_TIMEOUT,
IASTYPE_BOOLEAN
);
if ((generate == 0) || !generate->Value.Boolean)
{
IASTraceString("Auto-generation of Session-Timeout is disabled.");
return;
}
// retrieve all the ms-session-timeout and session-timeout from the request.
DWORD attrIDs[] =
{
MS_ATTRIBUTE_SESSION_TIMEOUT,
RADIUS_ATTRIBUTE_SESSION_TIMEOUT
};
AttributeVector sessionTimeouts;
if (!sessionTimeouts.load(request, RTL_NUMBER_OF(attrIDs), attrIDs))
{
IASTraceString("Session-Timeout not present.");
return;
}
DWORD minTimeout = MAXDWORD;
// get the minimum value found. Store it in the local min value (seconds)
for (AttributeVector::const_iterator i = sessionTimeouts.begin();
i != sessionTimeouts.end();
++i)
{
IASTracePrintf("Session-Timeout = %lu", i->pAttribute->Value.Integer);
if (i->pAttribute->Value.Integer < minTimeout)
{
minTimeout = i->pAttribute->Value.Integer;
}
}
IASTracePrintf("Consensus Session-Timeout = %lu", minTimeout);
// delete all the session-timeout from the request
request.RemoveAttributesByType(2, attrIDs);
// add one session-timeout with the new value to the request
IASTL::IASAttribute sessionTimeout(true);
sessionTimeout->dwId = RADIUS_ATTRIBUTE_SESSION_TIMEOUT;
sessionTimeout->Value.itType = IASTYPE_INTEGER;
sessionTimeout->Value.Integer = minTimeout;
sessionTimeout.setFlag(IAS_INCLUDE_IN_ACCEPT);
sessionTimeout.store(request);
}
const char* PostEapRestrictions::GetAnsiString(IASATTRIBUTE& attr)
{
if (attr.Value.itType != IASTYPE_STRING)
{
return 0;
}
DWORD error = IASAttributeAnsiAlloc(&attr);
if (error != NO_ERROR)
{
IASTL::issue_error(HRESULT_FROM_WIN32(error));
}
return attr.Value.String.pszAnsi;
}