Requirement that eap::method processes EAP packets only dropped, work with non-EAP methods simplified
This commit is contained in:
parent
7cddd585b7
commit
566785192a
@ -21,7 +21,7 @@
|
|||||||
namespace eap
|
namespace eap
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
/// EAP method base class
|
/// EAP and non-EAP method base class
|
||||||
///
|
///
|
||||||
class method;
|
class method;
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ namespace eap
|
|||||||
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
|
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
|
||||||
///
|
///
|
||||||
virtual void process_request_packet(
|
virtual void process_request_packet(
|
||||||
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket,
|
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
|
||||||
_In_ DWORD dwReceivedPacketSize,
|
_In_ DWORD dwReceivedPacketSize,
|
||||||
_Inout_ EapPeerMethodOutput *pEapOutput) = 0;
|
_Inout_ EapPeerMethodOutput *pEapOutput) = 0;
|
||||||
|
|
||||||
@ -109,8 +109,8 @@ namespace eap
|
|||||||
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
|
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
|
||||||
///
|
///
|
||||||
virtual void get_response_packet(
|
virtual void get_response_packet(
|
||||||
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
|
_Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
|
||||||
_Inout_ DWORD *pdwSendPacketSize) = 0;
|
_Inout_ DWORD *pdwSendPacketSize) = 0;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Obtains the result of an authentication session from the EAP method.
|
/// Obtains the result of an authentication session from the EAP method.
|
||||||
|
@ -68,13 +68,24 @@ namespace eap
|
|||||||
/// \name Packet processing
|
/// \name Packet processing
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Starts an EAP authentication session on the peer EapHost using the EAP method.
|
||||||
|
///
|
||||||
|
/// \sa [EapPeerBeginSession function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363600.aspx)
|
||||||
|
///
|
||||||
|
virtual void begin_session(
|
||||||
|
_In_ DWORD dwFlags,
|
||||||
|
_In_ const EapAttributes *pAttributeArray,
|
||||||
|
_In_ HANDLE hTokenImpersonateUser,
|
||||||
|
_In_ DWORD dwMaxSendPacketSize);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Processes a packet received by EapHost from a supplicant.
|
/// Processes a packet received by EapHost from a supplicant.
|
||||||
///
|
///
|
||||||
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
|
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
|
||||||
///
|
///
|
||||||
virtual void process_request_packet(
|
virtual void process_request_packet(
|
||||||
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket,
|
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
|
||||||
_In_ DWORD dwReceivedPacketSize,
|
_In_ DWORD dwReceivedPacketSize,
|
||||||
_Inout_ EapPeerMethodOutput *pEapOutput);
|
_Inout_ EapPeerMethodOutput *pEapOutput);
|
||||||
|
|
||||||
@ -84,8 +95,8 @@ namespace eap
|
|||||||
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
|
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
|
||||||
///
|
///
|
||||||
virtual void get_response_packet(
|
virtual void get_response_packet(
|
||||||
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
|
_Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
|
||||||
_Inout_ DWORD *pdwSendPacketSize);
|
_Inout_ DWORD *pdwSendPacketSize);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Obtains the result of an authentication session from the EAP method.
|
/// Obtains the result of an authentication session from the EAP method.
|
||||||
@ -99,14 +110,14 @@ namespace eap
|
|||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
credentials_mschapv2 &m_cred; ///< EAP-TLS user credentials
|
credentials_mschapv2 &m_cred; ///< EAP-TLS user credentials
|
||||||
|
|
||||||
packet m_packet_res; ///< Response packet
|
sanitizing_blob m_packet_res; ///< Response packet
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
phase_unknown = -1, ///< Unknown phase
|
phase_unknown = -1, ///< Unknown phase
|
||||||
phase_init = 0, ///< Handshake initialize
|
phase_init = 0, ///< Handshake initialize
|
||||||
phase_finished, ///< Connection shut down
|
phase_finished, ///< Connection shut down
|
||||||
} m_phase, m_phase_prev; ///< What phase is our communication at?
|
} m_phase, m_phase_prev; ///< What phase is our communication at?
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -61,20 +61,28 @@ eap::method_mschapv2& eap::method_mschapv2::operator=(_Inout_ method_mschapv2 &&
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void eap::method_mschapv2::begin_session(
|
||||||
|
_In_ DWORD dwFlags,
|
||||||
|
_In_ const EapAttributes *pAttributeArray,
|
||||||
|
_In_ HANDLE hTokenImpersonateUser,
|
||||||
|
_In_ DWORD dwMaxSendPacketSize)
|
||||||
|
{
|
||||||
|
method::begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize);
|
||||||
|
|
||||||
|
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_legacy_mschapv2), event_data::blank);
|
||||||
|
m_phase = phase_init;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void eap::method_mschapv2::process_request_packet(
|
void eap::method_mschapv2::process_request_packet(
|
||||||
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket,
|
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
|
||||||
_In_ DWORD dwReceivedPacketSize,
|
_In_ DWORD dwReceivedPacketSize,
|
||||||
_Inout_ EapPeerMethodOutput *pEapOutput)
|
_Inout_ EapPeerMethodOutput *pEapOutput)
|
||||||
{
|
{
|
||||||
assert(pReceivedPacket && dwReceivedPacketSize >= 4);
|
assert(pReceivedPacket || dwReceivedPacketSize == 0);
|
||||||
assert(pEapOutput);
|
assert(pEapOutput);
|
||||||
|
|
||||||
m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_legacy_mschapv2), event_data((unsigned int)dwReceivedPacketSize - 4), event_data::blank);
|
m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_legacy_mschapv2), event_data((unsigned int)dwReceivedPacketSize), event_data::blank);
|
||||||
|
|
||||||
if (pReceivedPacket->Id == 0) {
|
|
||||||
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_legacy_mschapv2), event_data::blank);
|
|
||||||
m_phase = phase_init;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_phase_prev = m_phase;
|
m_phase_prev = m_phase;
|
||||||
switch (m_phase) {
|
switch (m_phase) {
|
||||||
@ -96,10 +104,8 @@ void eap::method_mschapv2::process_request_packet(
|
|||||||
size_identity_outer,
|
size_identity_outer,
|
||||||
size_password_outer;
|
size_password_outer;
|
||||||
|
|
||||||
m_packet_res.m_code = EapCodeResponse;
|
m_packet_res.clear();
|
||||||
m_packet_res.m_id = pReceivedPacket->Id;
|
m_packet_res.reserve(
|
||||||
m_packet_res.m_data.clear();
|
|
||||||
m_packet_res.m_data.reserve(
|
|
||||||
(size_identity_outer =
|
(size_identity_outer =
|
||||||
sizeof(diameter_avp_header) + // Diameter header
|
sizeof(diameter_avp_header) + // Diameter header
|
||||||
size_identity) + // Identity
|
size_identity) + // Identity
|
||||||
@ -114,20 +120,20 @@ void eap::method_mschapv2::process_request_packet(
|
|||||||
*(unsigned int*)hdr.code = htonl(0x00000001);
|
*(unsigned int*)hdr.code = htonl(0x00000001);
|
||||||
hdr.flags = diameter_avp_flag_mandatory;
|
hdr.flags = diameter_avp_flag_mandatory;
|
||||||
hton24((unsigned int)size_identity_outer, hdr.length);
|
hton24((unsigned int)size_identity_outer, hdr.length);
|
||||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), (unsigned char*)&hdr, (unsigned char*)(&hdr + 1));
|
m_packet_res.insert(m_packet_res.end(), (unsigned char*)&hdr, (unsigned char*)(&hdr + 1));
|
||||||
|
|
||||||
// Identity
|
// Identity
|
||||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), identity_utf8.begin(), identity_utf8.end());
|
m_packet_res.insert(m_packet_res.end(), identity_utf8.begin(), identity_utf8.end());
|
||||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), padding_identity, 0);
|
m_packet_res.insert(m_packet_res.end(), padding_identity, 0);
|
||||||
|
|
||||||
// Diameter AVP Code User-Password (0x00000002)
|
// Diameter AVP Code User-Password (0x00000002)
|
||||||
*(unsigned int*)hdr.code = htonl(0x00000002);
|
*(unsigned int*)hdr.code = htonl(0x00000002);
|
||||||
hton24((unsigned int)size_password_outer, hdr.length);
|
hton24((unsigned int)size_password_outer, hdr.length);
|
||||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), (unsigned char*)&hdr, (unsigned char*)(&hdr + 1));
|
m_packet_res.insert(m_packet_res.end(), (unsigned char*)&hdr, (unsigned char*)(&hdr + 1));
|
||||||
|
|
||||||
// Password
|
// Password
|
||||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), password_utf8.begin(), password_utf8.end());
|
m_packet_res.insert(m_packet_res.end(), password_utf8.begin(), password_utf8.end());
|
||||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), padding_password, 0);
|
m_packet_res.insert(m_packet_res.end(), padding_password, 0);
|
||||||
|
|
||||||
m_phase = phase_finished;
|
m_phase = phase_finished;
|
||||||
break;
|
break;
|
||||||
@ -143,32 +149,19 @@ void eap::method_mschapv2::process_request_packet(
|
|||||||
|
|
||||||
|
|
||||||
void eap::method_mschapv2::get_response_packet(
|
void eap::method_mschapv2::get_response_packet(
|
||||||
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
|
_Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
|
||||||
_Inout_ DWORD *pdwSendPacketSize)
|
_Inout_ DWORD *pdwSendPacketSize)
|
||||||
{
|
{
|
||||||
assert(pdwSendPacketSize);
|
assert(pdwSendPacketSize);
|
||||||
assert(pSendPacket);
|
assert(pSendPacket);
|
||||||
|
|
||||||
unsigned int
|
size_t size_packet = m_packet_res.size();
|
||||||
size_data = (unsigned int)m_packet_res.m_data.size(),
|
if (size_packet > *pdwSendPacketSize)
|
||||||
size_packet = size_data + 4;
|
throw invalid_argument(string_printf(__FUNCTION__ " This method does not support packet fragmentation, but the data size is too big to fit in one packet (packet: %u, maximum: %u).", size_packet, *pdwSendPacketSize).c_str());
|
||||||
unsigned short size_packet_limit = (unsigned short)std::min<unsigned int>(*pdwSendPacketSize, USHRT_MAX);
|
|
||||||
|
|
||||||
// Not fragmented.
|
memcpy(pSendPacket, m_packet_res.data(), size_packet);
|
||||||
if (size_packet <= size_packet_limit) {
|
*pdwSendPacketSize = (DWORD)size_packet;
|
||||||
// No need to fragment the packet.
|
m_packet_res.clear();
|
||||||
m_module.log_event(&EAPMETHOD_PACKET_SEND, event_data((unsigned int)eap_type_legacy_mschapv2), event_data((unsigned int)size_data), event_data::blank);
|
|
||||||
} else {
|
|
||||||
// But it should be fragmented.
|
|
||||||
throw com_runtime_error(TYPE_E_SIZETOOBIG, __FUNCTION__ " PAP message exceeds 64kB.");
|
|
||||||
}
|
|
||||||
|
|
||||||
pSendPacket->Code = (BYTE)m_packet_res.m_code;
|
|
||||||
pSendPacket->Id = m_packet_res.m_id;
|
|
||||||
*(unsigned short*)pSendPacket->Length = htons((unsigned short)size_packet);
|
|
||||||
memcpy(pSendPacket->Data, m_packet_res.m_data.data(), size_data);
|
|
||||||
m_packet_res.m_data.erase(m_packet_res.m_data.begin(), m_packet_res.m_data.begin() + size_data);
|
|
||||||
*pdwSendPacketSize = size_packet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,13 +68,24 @@ namespace eap
|
|||||||
/// \name Packet processing
|
/// \name Packet processing
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Starts an EAP authentication session on the peer EapHost using the EAP method.
|
||||||
|
///
|
||||||
|
/// \sa [EapPeerBeginSession function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363600.aspx)
|
||||||
|
///
|
||||||
|
virtual void begin_session(
|
||||||
|
_In_ DWORD dwFlags,
|
||||||
|
_In_ const EapAttributes *pAttributeArray,
|
||||||
|
_In_ HANDLE hTokenImpersonateUser,
|
||||||
|
_In_ DWORD dwMaxSendPacketSize);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Processes a packet received by EapHost from a supplicant.
|
/// Processes a packet received by EapHost from a supplicant.
|
||||||
///
|
///
|
||||||
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
|
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
|
||||||
///
|
///
|
||||||
virtual void process_request_packet(
|
virtual void process_request_packet(
|
||||||
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket,
|
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
|
||||||
_In_ DWORD dwReceivedPacketSize,
|
_In_ DWORD dwReceivedPacketSize,
|
||||||
_Inout_ EapPeerMethodOutput *pEapOutput);
|
_Inout_ EapPeerMethodOutput *pEapOutput);
|
||||||
|
|
||||||
@ -84,8 +95,8 @@ namespace eap
|
|||||||
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
|
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
|
||||||
///
|
///
|
||||||
virtual void get_response_packet(
|
virtual void get_response_packet(
|
||||||
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
|
_Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
|
||||||
_Inout_ DWORD *pdwSendPacketSize);
|
_Inout_ DWORD *pdwSendPacketSize);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Obtains the result of an authentication session from the EAP method.
|
/// Obtains the result of an authentication session from the EAP method.
|
||||||
@ -99,14 +110,14 @@ namespace eap
|
|||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
credentials_pap &m_cred; ///< EAP-TLS user credentials
|
credentials_pap &m_cred; ///< EAP-TLS user credentials
|
||||||
|
|
||||||
packet m_packet_res; ///< Response packet
|
sanitizing_blob m_packet_res; ///< Response packet
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
phase_unknown = -1, ///< Unknown phase
|
phase_unknown = -1, ///< Unknown phase
|
||||||
phase_init = 0, ///< Handshake initialize
|
phase_init = 0, ///< Handshake initialize
|
||||||
phase_finished, ///< Connection shut down
|
phase_finished, ///< Connection shut down
|
||||||
} m_phase, m_phase_prev; ///< What phase is our communication at?
|
} m_phase, m_phase_prev; ///< What phase is our communication at?
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -61,20 +61,28 @@ eap::method_pap& eap::method_pap::operator=(_Inout_ method_pap &&other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void eap::method_pap::begin_session(
|
||||||
|
_In_ DWORD dwFlags,
|
||||||
|
_In_ const EapAttributes *pAttributeArray,
|
||||||
|
_In_ HANDLE hTokenImpersonateUser,
|
||||||
|
_In_ DWORD dwMaxSendPacketSize)
|
||||||
|
{
|
||||||
|
method::begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize);
|
||||||
|
|
||||||
|
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_legacy_pap), event_data::blank);
|
||||||
|
m_phase = phase_init;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void eap::method_pap::process_request_packet(
|
void eap::method_pap::process_request_packet(
|
||||||
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket,
|
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
|
||||||
_In_ DWORD dwReceivedPacketSize,
|
_In_ DWORD dwReceivedPacketSize,
|
||||||
_Inout_ EapPeerMethodOutput *pEapOutput)
|
_Inout_ EapPeerMethodOutput *pEapOutput)
|
||||||
{
|
{
|
||||||
assert(pReceivedPacket && dwReceivedPacketSize >= 4);
|
assert(pReceivedPacket || dwReceivedPacketSize == 0);
|
||||||
assert(pEapOutput);
|
assert(pEapOutput);
|
||||||
|
|
||||||
m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_legacy_pap), event_data((unsigned int)dwReceivedPacketSize - 4), event_data::blank);
|
m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_legacy_pap), event_data((unsigned int)dwReceivedPacketSize), event_data::blank);
|
||||||
|
|
||||||
if (pReceivedPacket->Id == 0) {
|
|
||||||
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_legacy_pap), event_data::blank);
|
|
||||||
m_phase = phase_init;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_phase_prev = m_phase;
|
m_phase_prev = m_phase;
|
||||||
switch (m_phase) {
|
switch (m_phase) {
|
||||||
@ -96,10 +104,8 @@ void eap::method_pap::process_request_packet(
|
|||||||
size_identity_outer,
|
size_identity_outer,
|
||||||
size_password_outer;
|
size_password_outer;
|
||||||
|
|
||||||
m_packet_res.m_code = EapCodeResponse;
|
m_packet_res.clear();
|
||||||
m_packet_res.m_id = pReceivedPacket->Id;
|
m_packet_res.reserve(
|
||||||
m_packet_res.m_data.clear();
|
|
||||||
m_packet_res.m_data.reserve(
|
|
||||||
(size_identity_outer =
|
(size_identity_outer =
|
||||||
sizeof(diameter_avp_header) + // Diameter header
|
sizeof(diameter_avp_header) + // Diameter header
|
||||||
size_identity) + // Identity
|
size_identity) + // Identity
|
||||||
@ -114,20 +120,20 @@ void eap::method_pap::process_request_packet(
|
|||||||
*(unsigned int*)hdr.code = htonl(0x00000001);
|
*(unsigned int*)hdr.code = htonl(0x00000001);
|
||||||
hdr.flags = diameter_avp_flag_mandatory;
|
hdr.flags = diameter_avp_flag_mandatory;
|
||||||
hton24((unsigned int)size_identity_outer, hdr.length);
|
hton24((unsigned int)size_identity_outer, hdr.length);
|
||||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), (unsigned char*)&hdr, (unsigned char*)(&hdr + 1));
|
m_packet_res.insert(m_packet_res.end(), (unsigned char*)&hdr, (unsigned char*)(&hdr + 1));
|
||||||
|
|
||||||
// Identity
|
// Identity
|
||||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), identity_utf8.begin(), identity_utf8.end());
|
m_packet_res.insert(m_packet_res.end(), identity_utf8.begin(), identity_utf8.end());
|
||||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), padding_identity, 0);
|
m_packet_res.insert(m_packet_res.end(), padding_identity, 0);
|
||||||
|
|
||||||
// Diameter AVP Code User-Password (0x00000002)
|
// Diameter AVP Code User-Password (0x00000002)
|
||||||
*(unsigned int*)hdr.code = htonl(0x00000002);
|
*(unsigned int*)hdr.code = htonl(0x00000002);
|
||||||
hton24((unsigned int)size_password_outer, hdr.length);
|
hton24((unsigned int)size_password_outer, hdr.length);
|
||||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), (unsigned char*)&hdr, (unsigned char*)(&hdr + 1));
|
m_packet_res.insert(m_packet_res.end(), (unsigned char*)&hdr, (unsigned char*)(&hdr + 1));
|
||||||
|
|
||||||
// Password
|
// Password
|
||||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), password_utf8.begin(), password_utf8.end());
|
m_packet_res.insert(m_packet_res.end(), password_utf8.begin(), password_utf8.end());
|
||||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), padding_password, 0);
|
m_packet_res.insert(m_packet_res.end(), padding_password, 0);
|
||||||
|
|
||||||
m_phase = phase_finished;
|
m_phase = phase_finished;
|
||||||
break;
|
break;
|
||||||
@ -143,32 +149,19 @@ void eap::method_pap::process_request_packet(
|
|||||||
|
|
||||||
|
|
||||||
void eap::method_pap::get_response_packet(
|
void eap::method_pap::get_response_packet(
|
||||||
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
|
_Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
|
||||||
_Inout_ DWORD *pdwSendPacketSize)
|
_Inout_ DWORD *pdwSendPacketSize)
|
||||||
{
|
{
|
||||||
assert(pdwSendPacketSize);
|
assert(pdwSendPacketSize);
|
||||||
assert(pSendPacket);
|
assert(pSendPacket);
|
||||||
|
|
||||||
unsigned int
|
size_t size_packet = m_packet_res.size();
|
||||||
size_data = (unsigned int)m_packet_res.m_data.size(),
|
if (size_packet > *pdwSendPacketSize)
|
||||||
size_packet = size_data + 4;
|
throw invalid_argument(string_printf(__FUNCTION__ " This method does not support packet fragmentation, but the data size is too big to fit in one packet (packet: %u, maximum: %u).", size_packet, *pdwSendPacketSize).c_str());
|
||||||
unsigned short size_packet_limit = (unsigned short)std::min<unsigned int>(*pdwSendPacketSize, USHRT_MAX);
|
|
||||||
|
|
||||||
// Not fragmented.
|
memcpy(pSendPacket, m_packet_res.data(), size_packet);
|
||||||
if (size_packet <= size_packet_limit) {
|
*pdwSendPacketSize = (DWORD)size_packet;
|
||||||
// No need to fragment the packet.
|
m_packet_res.clear();
|
||||||
m_module.log_event(&EAPMETHOD_PACKET_SEND, event_data((unsigned int)eap_type_legacy_pap), event_data((unsigned int)size_data), event_data::blank);
|
|
||||||
} else {
|
|
||||||
// But it should be fragmented.
|
|
||||||
throw com_runtime_error(TYPE_E_SIZETOOBIG, __FUNCTION__ " PAP message exceeds 64kB.");
|
|
||||||
}
|
|
||||||
|
|
||||||
pSendPacket->Code = (BYTE)m_packet_res.m_code;
|
|
||||||
pSendPacket->Id = m_packet_res.m_id;
|
|
||||||
*(unsigned short*)pSendPacket->Length = htons((unsigned short)size_packet);
|
|
||||||
memcpy(pSendPacket->Data, m_packet_res.m_data.data(), size_data);
|
|
||||||
m_packet_res.m_data.erase(m_packet_res.m_data.begin(), m_packet_res.m_data.begin() + size_data);
|
|
||||||
*pdwSendPacketSize = size_packet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ namespace eap
|
|||||||
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
|
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
|
||||||
///
|
///
|
||||||
virtual void process_request_packet(
|
virtual void process_request_packet(
|
||||||
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket,
|
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
|
||||||
_In_ DWORD dwReceivedPacketSize,
|
_In_ DWORD dwReceivedPacketSize,
|
||||||
_Inout_ EapPeerMethodOutput *pEapOutput);
|
_Inout_ EapPeerMethodOutput *pEapOutput);
|
||||||
|
|
||||||
@ -116,8 +116,8 @@ namespace eap
|
|||||||
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
|
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
|
||||||
///
|
///
|
||||||
virtual void get_response_packet(
|
virtual void get_response_packet(
|
||||||
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
|
_Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
|
||||||
_Inout_ DWORD *pdwSendPacketSize);
|
_Inout_ DWORD *pdwSendPacketSize);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Obtains the result of an authentication session from the EAP method.
|
/// Obtains the result of an authentication session from the EAP method.
|
||||||
|
@ -261,7 +261,7 @@ void eap::method_tls::begin_session(
|
|||||||
|
|
||||||
|
|
||||||
void eap::method_tls::process_request_packet(
|
void eap::method_tls::process_request_packet(
|
||||||
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket,
|
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
|
||||||
_In_ DWORD dwReceivedPacketSize,
|
_In_ DWORD dwReceivedPacketSize,
|
||||||
_Inout_ EapPeerMethodOutput *pEapOutput)
|
_Inout_ EapPeerMethodOutput *pEapOutput)
|
||||||
{
|
{
|
||||||
@ -274,10 +274,10 @@ void eap::method_tls::process_request_packet(
|
|||||||
//else if (pReceivedPacket->Data[0] != eap_type_tls) // Skip method check, to allow TTLS extension.
|
//else if (pReceivedPacket->Data[0] != eap_type_tls) // Skip method check, to allow TTLS extension.
|
||||||
// throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, string_printf(__FUNCTION__ " Packet is not EAP-TLS (expected: %u, received: %u).", eap_type_tls, pReceivedPacket->Data[0]));
|
// throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, string_printf(__FUNCTION__ " Packet is not EAP-TLS (expected: %u, received: %u).", eap_type_tls, pReceivedPacket->Data[0]));
|
||||||
|
|
||||||
if (!m_packet_req.append_frag(pReceivedPacket)) {
|
if (!m_packet_req.append_frag((const EapPacket*)pReceivedPacket)) {
|
||||||
// This was not the only/last fragment. Reply with ACK packet.
|
// This was not the only/last fragment. Reply with ACK packet.
|
||||||
m_packet_res.m_code = EapCodeResponse;
|
m_packet_res.m_code = EapCodeResponse;
|
||||||
m_packet_res.m_id = pReceivedPacket->Id;
|
m_packet_res.m_id = ((const EapPacket*)pReceivedPacket)->Id;
|
||||||
m_packet_res.m_flags = 0;
|
m_packet_res.m_flags = 0;
|
||||||
m_packet_res.m_data.clear();
|
m_packet_res.m_data.clear();
|
||||||
pEapOutput->fAllowNotifications = FALSE;
|
pEapOutput->fAllowNotifications = FALSE;
|
||||||
@ -304,7 +304,7 @@ void eap::method_tls::process_request_packet(
|
|||||||
user_impersonator impersonating(m_user_ctx);
|
user_impersonator impersonating(m_user_ctx);
|
||||||
|
|
||||||
#if EAP_TLS < EAP_TLS_SCHANNEL
|
#if EAP_TLS < EAP_TLS_SCHANNEL
|
||||||
if (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & packet_tls::flags_req_start)) {
|
if (((const EapPacket*)pReceivedPacket)->Code == EapCodeRequest && (m_packet_req.m_flags & packet_tls::flags_req_start)) {
|
||||||
// This is the EAP-TLS start message: (re)initialize method.
|
// This is the EAP-TLS start message: (re)initialize method.
|
||||||
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank);
|
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank);
|
||||||
m_phase = phase_client_hello;
|
m_phase = phase_client_hello;
|
||||||
@ -460,7 +460,7 @@ void eap::method_tls::process_request_packet(
|
|||||||
m_phase = phase_client_hello;
|
m_phase = phase_client_hello;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & packet_tls::flags_req_start)) {
|
if (((const EapPacket*)pReceivedPacket)->Code == EapCodeRequest && (m_packet_req.m_flags & packet_tls::flags_req_start)) {
|
||||||
// This is the EAP-TLS start message: (re)initialize method.
|
// This is the EAP-TLS start message: (re)initialize method.
|
||||||
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank);
|
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank);
|
||||||
m_phase = phase_handshake_init;
|
m_phase = phase_handshake_init;
|
||||||
@ -490,13 +490,13 @@ void eap::method_tls::process_request_packet(
|
|||||||
|
|
||||||
|
|
||||||
void eap::method_tls::get_response_packet(
|
void eap::method_tls::get_response_packet(
|
||||||
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
|
_Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
|
||||||
_Inout_ DWORD *pdwSendPacketSize)
|
_Inout_ DWORD *pdwSendPacketSize)
|
||||||
{
|
{
|
||||||
assert(pdwSendPacketSize);
|
assert(pdwSendPacketSize);
|
||||||
assert(pSendPacket);
|
assert(pSendPacket);
|
||||||
|
|
||||||
*pdwSendPacketSize = m_packet_res.get_frag(pSendPacket, *pdwSendPacketSize);
|
*pdwSendPacketSize = m_packet_res.get_frag((EapPacket*)pSendPacket, *pdwSendPacketSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ namespace eap
|
|||||||
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
|
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
|
||||||
///
|
///
|
||||||
virtual void process_request_packet(
|
virtual void process_request_packet(
|
||||||
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket,
|
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
|
||||||
_In_ DWORD dwReceivedPacketSize,
|
_In_ DWORD dwReceivedPacketSize,
|
||||||
_Inout_ EapPeerMethodOutput *pEapOutput);
|
_Inout_ EapPeerMethodOutput *pEapOutput);
|
||||||
|
|
||||||
@ -103,8 +103,8 @@ namespace eap
|
|||||||
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
|
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
|
||||||
///
|
///
|
||||||
virtual void get_response_packet(
|
virtual void get_response_packet(
|
||||||
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
|
_Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
|
||||||
_Inout_ DWORD *pdwSendPacketSize);
|
_Inout_ DWORD *pdwSendPacketSize);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Obtains the result of an authentication session from the EAP method.
|
/// Obtains the result of an authentication session from the EAP method.
|
||||||
|
@ -92,15 +92,15 @@ void eap::method_ttls::end_session()
|
|||||||
|
|
||||||
|
|
||||||
void eap::method_ttls::process_request_packet(
|
void eap::method_ttls::process_request_packet(
|
||||||
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket,
|
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
|
||||||
_In_ DWORD dwReceivedPacketSize,
|
_In_ DWORD dwReceivedPacketSize,
|
||||||
_Inout_ EapPeerMethodOutput *pEapOutput)
|
_Inout_ EapPeerMethodOutput *pEapOutput)
|
||||||
{
|
{
|
||||||
if (pReceivedPacket->Code == EapCodeRequest && (pReceivedPacket->Data[1] & packet_ttls::flags_start)) {
|
if (((const EapPacket*)pReceivedPacket)->Code == EapCodeRequest && (((const EapPacket*)pReceivedPacket)->Data[1] & packet_ttls::flags_start)) {
|
||||||
// This is a start EAP-TTLS packet.
|
// This is a start EAP-TTLS packet.
|
||||||
|
|
||||||
// Determine minimum EAP-TTLS version supported by server and us.
|
// Determine minimum EAP-TTLS version supported by server and us.
|
||||||
version_t ver_remote = (version_t)(pReceivedPacket->Data[1] & packet_ttls::flags_ver_mask);
|
version_t ver_remote = (version_t)(((const EapPacket*)pReceivedPacket)->Data[1] & packet_ttls::flags_ver_mask);
|
||||||
m_version = std::min<version_t>(ver_remote, version_0);
|
m_version = std::min<version_t>(ver_remote, version_0);
|
||||||
m_module.log_event(&EAPMETHOD_TTLS_HANDSHAKE_START, event_data((unsigned int)eap_type_ttls), event_data((unsigned char)m_version), event_data((unsigned char)ver_remote), event_data::blank);
|
m_module.log_event(&EAPMETHOD_TTLS_HANDSHAKE_START, event_data((unsigned int)eap_type_ttls), event_data((unsigned char)m_version), event_data((unsigned char)ver_remote), event_data::blank);
|
||||||
}
|
}
|
||||||
@ -111,15 +111,15 @@ void eap::method_ttls::process_request_packet(
|
|||||||
|
|
||||||
|
|
||||||
void eap::method_ttls::get_response_packet(
|
void eap::method_ttls::get_response_packet(
|
||||||
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
|
_Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
|
||||||
_Inout_ DWORD *pdwSendPacketSize)
|
_Inout_ DWORD *pdwSendPacketSize)
|
||||||
{
|
{
|
||||||
method_tls::get_response_packet(pSendPacket, pdwSendPacketSize);
|
method_tls::get_response_packet(pSendPacket, pdwSendPacketSize);
|
||||||
|
|
||||||
// Change packet type to EAP-TTLS, and add EAP-TTLS version.
|
// Change packet type to EAP-TTLS, and add EAP-TTLS version.
|
||||||
pSendPacket->Data[0] = (BYTE)eap_type_ttls;
|
((EapPacket*)pSendPacket)->Data[0] = (BYTE)eap_type_ttls;
|
||||||
pSendPacket->Data[1] &= ~packet_ttls::flags_ver_mask;
|
((EapPacket*)pSendPacket)->Data[1] &= ~packet_ttls::flags_ver_mask;
|
||||||
pSendPacket->Data[1] |= m_version;
|
((EapPacket*)pSendPacket)->Data[1] |= m_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -222,24 +222,7 @@ void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const v
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
EapPeerMethodOutput eap_output = {};
|
EapPeerMethodOutput eap_output = {};
|
||||||
eap_type_t eap_type = m_cfg.m_inner->get_method_id();
|
m_inner->process_request_packet(msg, (DWORD)size_msg, &eap_output);
|
||||||
if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) {
|
|
||||||
// Inner method is natively non-EAP. Server sent raw data, but all our eap::method derived classes expect EAP encapsulated.
|
|
||||||
// Encapsulate in an EAP packet.
|
|
||||||
assert(size_msg < 0xffff);
|
|
||||||
unsigned short size_packet = (unsigned short)size_msg + 4;
|
|
||||||
sanitizing_blob packet;
|
|
||||||
packet.reserve(size_packet);
|
|
||||||
packet.push_back(EapCodeRequest);
|
|
||||||
packet.push_back(m_inner_packet_id++);
|
|
||||||
unsigned short size2 = htons(size_packet);
|
|
||||||
packet.insert(packet.end(), (unsigned char*)&size2, (unsigned char*)(&size2 + 1));
|
|
||||||
packet.insert(packet.end(), (unsigned char*)msg, (unsigned char*)msg + size_msg);
|
|
||||||
m_inner->process_request_packet((const EapPacket*)packet.data(), size_packet, &eap_output);
|
|
||||||
} else {
|
|
||||||
// Inner packet is EAP-aware.
|
|
||||||
m_inner->process_request_packet((const EapPacket*)msg, (DWORD)size_msg, &eap_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (eap_output.action) {
|
switch (eap_output.action) {
|
||||||
case EapPeerMethodResponseActionSend: {
|
case EapPeerMethodResponseActionSend: {
|
||||||
@ -264,12 +247,7 @@ void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const v
|
|||||||
DWORD size_data = m_size_inner_packet_max;
|
DWORD size_data = m_size_inner_packet_max;
|
||||||
unsigned char *ptr_data = data.data() + sizes.cbHeader;
|
unsigned char *ptr_data = data.data() + sizes.cbHeader;
|
||||||
#endif
|
#endif
|
||||||
m_inner->get_response_packet((EapPacket*)ptr_data, &size_data);
|
m_inner->get_response_packet(ptr_data, &size_data);
|
||||||
|
|
||||||
if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) {
|
|
||||||
// Inner method is non-EAP. Strip EAP header, since server expect raw data.
|
|
||||||
memmove(ptr_data, ptr_data + 4, size_data -= 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if EAP_TLS < EAP_TLS_SCHANNEL
|
#if EAP_TLS < EAP_TLS_SCHANNEL
|
||||||
data.resize(size_data);
|
data.resize(size_data);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user