506 lines
13 KiB
C
506 lines
13 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1999, Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
elport.h
|
||
|
|
||
|
Abstract:
|
||
|
This module contains declarations for port management for EAPOL,
|
||
|
r/w to ports
|
||
|
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
sachins, Apr 23 2000, Created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
#ifndef _EAPOL_PORT_H_
|
||
|
#define _EAPOL_PORT_H_
|
||
|
|
||
|
//
|
||
|
// EAPOL PCB State Flags
|
||
|
//
|
||
|
|
||
|
#define EAPOL_PORT_FLAG_DELETED 0x8000
|
||
|
#define EAPOL_PORT_DELETED(i) \
|
||
|
((i)->dwFlags & EAPOL_PORT_FLAG_DELETED)
|
||
|
|
||
|
#define EAPOL_PORT_FLAG_ACTIVE 0x4000
|
||
|
#define EAPOL_PORT_ACTIVE(i) \
|
||
|
((i)->dwFlags & EAPOL_PORT_FLAG_ACTIVE)
|
||
|
|
||
|
#define EAPOL_PORT_FLAG_DISABLED 0x2000
|
||
|
#define EAPOL_PORT_DISABLED(i) \
|
||
|
((i)->dwFlags & EAPOL_PORT_FLAG_DISABLED)
|
||
|
|
||
|
|
||
|
//
|
||
|
// EAPOL Timer Flags
|
||
|
//
|
||
|
|
||
|
#define EAPOL_AUTH_TIMER 0x8000
|
||
|
#define EAPOL_AUTH_TIMER_SET(i) \
|
||
|
((i)->dwTimerFlags & EAPOL_AUTH_TIMER)
|
||
|
|
||
|
#define EAPOL_HELD_TIMER 0x4000
|
||
|
#define EAPOL_HELD_TIMER_SET(i) \
|
||
|
((i)->dwTimerFlags & EAPOL_HELD_TIMER)
|
||
|
|
||
|
#define EAPOL_START_TIMER 0x2000
|
||
|
#define EAPOL_START_TIMER_SET(i) \
|
||
|
((i)->dwTimerFlags & EAPOL_START_TIMER)
|
||
|
|
||
|
#define EAPOL_TRANSMIT_KEY_TIMER 0x1000
|
||
|
#define EAPOL_TRANSMIT_KEY_TIMER_SET(i) \
|
||
|
((i)->dwTimerFlags & EAPOL_TRANSMIT_KEY_TIMER)
|
||
|
|
||
|
#define EAPOL_NO_TIMER 0x0000
|
||
|
#define EAPOL_NO_TIMER_SET(i) \
|
||
|
((i)->dwTimerFlags & EAPOL_NO_TIMER)
|
||
|
|
||
|
#define SET_EAPOL_AUTH_TIMER(i) \
|
||
|
((i)->dwTimerFlags = EAPOL_AUTH_TIMER)
|
||
|
|
||
|
#define SET_EAPOL_HELD_TIMER(i) \
|
||
|
((i)->dwTimerFlags = EAPOL_HELD_TIMER)
|
||
|
|
||
|
#define SET_EAPOL_START_TIMER(i) \
|
||
|
((i)->dwTimerFlags = EAPOL_START_TIMER)
|
||
|
|
||
|
#define SET_TRANSMIT_KEY_TIMER(i) \
|
||
|
((i)->dwTimerFlags = EAPOL_TRANSMIT_KEY_TIMER)
|
||
|
|
||
|
#define SET_EAPOL_NO_TIMER(i) \
|
||
|
((i)->dwTimerFlags = EAPOL_NO_TIMER)
|
||
|
|
||
|
#define CHECK_EAPOL_TIMER(i) \
|
||
|
((i)->dwTimerFlags & (EAPOL_AUTH_TIMER|EAPOL_HELD_TIMER|EAPOL_START_TIMER|EAPOL_TRANSMIT_KEY_TIMER))
|
||
|
|
||
|
|
||
|
//
|
||
|
// Structure: ETH_HEADER
|
||
|
//
|
||
|
|
||
|
typedef struct _ETH_HEADER
|
||
|
{
|
||
|
BYTE bDstAddr[SIZE_MAC_ADDR];
|
||
|
BYTE bSrcAddr[SIZE_MAC_ADDR];
|
||
|
} ETH_HEADER, *PETH_HEADER;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Structure: EAPOL_BUFFER
|
||
|
//
|
||
|
// This structure holds a buffer used for I/O to the ndis uio driver
|
||
|
// EAPOL_BUFFER structure is used in the OVERLAPPED read-write operations.
|
||
|
// On the OVERLAPPED read/write completion, pvContext is used to
|
||
|
// identity the port on which the I/O occured
|
||
|
//
|
||
|
|
||
|
typedef struct _EAPOL_BUFFER
|
||
|
{
|
||
|
//
|
||
|
// This is the pointer to the EAPOL_PCB structure of the interface on which
|
||
|
// I/O was performed
|
||
|
//
|
||
|
PVOID pvContext;
|
||
|
|
||
|
// Send/Recv data buffer
|
||
|
|
||
|
CHAR pBuffer[MAX_PACKET_SIZE];
|
||
|
|
||
|
//
|
||
|
// Passed as the system context area for any I/O using the buffer
|
||
|
//
|
||
|
OVERLAPPED Overlapped;
|
||
|
|
||
|
//
|
||
|
// Pointer to Completion Routine
|
||
|
//
|
||
|
VOID (CALLBACK *CompletionRoutine)
|
||
|
(DWORD, DWORD, struct _EAPOL_BUFFER *);
|
||
|
|
||
|
// Fields which are filled on IoCompletion
|
||
|
DWORD dwErrorCode;
|
||
|
DWORD dwBytesTransferred;
|
||
|
|
||
|
} EAPOL_BUFFER, *PEAPOL_BUFFER;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Structure: EAPOL_PCB
|
||
|
//
|
||
|
// EAPOL Port Control Block
|
||
|
// This structure holds the operational information for an interface/port
|
||
|
// from the EAPOL protocol standpoint.
|
||
|
// It also maintains state information for EAP protocol.
|
||
|
//
|
||
|
// Each PCB is inserted in a hash bucket list, one for each interface
|
||
|
//
|
||
|
// Synchronization on PCBs is done using a read-write PCB list lock,
|
||
|
// and a per-PCB read-write lock, and a per-port ref count.
|
||
|
// The locks are single-write, multiple-read. Currently, locks are used
|
||
|
// in write mode only
|
||
|
//
|
||
|
// If PCB's are to be added or deleted, the PCB list lock should
|
||
|
// be acquired.
|
||
|
//
|
||
|
// If any PCB needs to be modified, the per-PCB list lock should be acquired
|
||
|
// in write mode.
|
||
|
//
|
||
|
// Acquiring a reference to a port guarantees the PCBs existence;
|
||
|
// acquiring the PCB lock guarantees consistency of the PCB fields
|
||
|
//
|
||
|
//
|
||
|
|
||
|
typedef struct _EAPOL_PCB
|
||
|
{
|
||
|
// Pointer to next PCB in the hash bucket
|
||
|
struct _EAPOL_PCB *pNext;
|
||
|
|
||
|
// Handle to NDIS UIO device
|
||
|
HANDLE hPort;
|
||
|
|
||
|
// Port number on the system Will be an integer value cast
|
||
|
DWORD dwPortIndex;
|
||
|
|
||
|
// Debug Flags
|
||
|
DWORD dwDebugFlags;
|
||
|
|
||
|
// Friendly name of the interface on which this port is opened
|
||
|
WCHAR *pwszFriendlyName;
|
||
|
|
||
|
// GUID string uniquely identifying the interface
|
||
|
WCHAR *pwszDeviceGUID;
|
||
|
|
||
|
// Additional identiifier for a connected port e.g. MSFTWLAN
|
||
|
WCHAR *pwszSSID;
|
||
|
|
||
|
// Additional identiifier for a connected port e.g. MSFTWLAN
|
||
|
NDIS_802_11_SSID *pSSID;
|
||
|
|
||
|
// Version of EAPOL supported on this port
|
||
|
DWORD dwEapolVersion;
|
||
|
|
||
|
// Pointer to EAP Work Buffer for this PCB
|
||
|
PVOID pEapWorkBuffer;
|
||
|
|
||
|
// Per PCB read-write lock
|
||
|
READ_WRITE_LOCK rwLock;
|
||
|
|
||
|
// Number of references made to this port
|
||
|
DWORD dwRefCount;
|
||
|
|
||
|
// Indicates whether port is ACTIVE or DISABLED
|
||
|
DWORD dwFlags;
|
||
|
|
||
|
// Indicates the EAPOL settings
|
||
|
DWORD dwEapFlags;
|
||
|
|
||
|
// EAPOL state
|
||
|
EAPOL_STATE State;
|
||
|
|
||
|
// EAPOL statistics for this port
|
||
|
EAPOL_STATS EapolStats;
|
||
|
|
||
|
// EAPOL configuration parameters for this port
|
||
|
EAPOL_CONFIG EapolConfig;
|
||
|
|
||
|
// Version of EAPOL supported
|
||
|
BYTE bProtocolVersion;
|
||
|
|
||
|
// Handle to EAPOL timer currently running on this machine
|
||
|
HANDLE hTimer;
|
||
|
|
||
|
// Ethertype for this LAN
|
||
|
BYTE bEtherType[SIZE_ETHERNET_TYPE];
|
||
|
|
||
|
// Mac Addr of peer (switch port access point)
|
||
|
BYTE bSrcMacAddr[SIZE_MAC_ADDR];
|
||
|
|
||
|
// Mac Addr of last successfully authenticated peer (access point)
|
||
|
BYTE bPreviousDestMacAddr[SIZE_MAC_ADDR];
|
||
|
|
||
|
// Mac Addr of peer (switch port or access point)
|
||
|
BYTE bDestMacAddr[SIZE_MAC_ADDR];
|
||
|
|
||
|
// Media State
|
||
|
NDIS_MEDIA_STATE MediaState;
|
||
|
|
||
|
// Physical Medium Type
|
||
|
NDIS_PHYSICAL_MEDIUM PhysicalMediumType;
|
||
|
|
||
|
DWORD dwTimerFlags;
|
||
|
|
||
|
// Number of EAPOL_Start messages that have been sent without
|
||
|
// receiving response
|
||
|
ULONG ulStartCount;
|
||
|
|
||
|
// Identifier in the most recently received EAP Request frame
|
||
|
DWORD dwPreviousId;
|
||
|
|
||
|
// Copy of last sent out EAPOL packet
|
||
|
// Used for retransmission
|
||
|
BYTE *pbPreviousEAPOLPkt;
|
||
|
DWORD dwSizeOfPreviousEAPOLPkt;
|
||
|
|
||
|
// Has Identity for the user obtained using RasEapGetIdentity ?
|
||
|
BOOL fGotUserIdentity;
|
||
|
|
||
|
// Is the port on a authenticated network i.e. is the remote end
|
||
|
// EAPOL aware
|
||
|
BOOL fIsRemoteEndEAPOLAware;
|
||
|
|
||
|
// Flag set based on the supplicant mode
|
||
|
BOOL fEAPOLTransmissionFlag;
|
||
|
|
||
|
//
|
||
|
// EAP related variables
|
||
|
//
|
||
|
|
||
|
BOOL fEapInitialized;
|
||
|
|
||
|
BOOL fLogon;
|
||
|
|
||
|
BOOL fUserLoggedIn;
|
||
|
|
||
|
// Authentication identity using RasGetUserIdentity or other means
|
||
|
CHAR *pszIdentity;
|
||
|
|
||
|
// User Password for EAP MD5 CHAP
|
||
|
DATA_BLOB PasswordBlob;
|
||
|
|
||
|
// Token for interactively logged-on user obtained using
|
||
|
// GetCurrentUserToken
|
||
|
HANDLE hUserToken;
|
||
|
|
||
|
// EAP configuration blob stored for each GUID
|
||
|
EAPOL_CUSTOM_AUTH_DATA *pCustomAuthConnData;
|
||
|
|
||
|
// User blob stored for GUID
|
||
|
EAPOL_CUSTOM_AUTH_DATA *pCustomAuthUserData;
|
||
|
|
||
|
// Data obtained using RasEapInvokeInteractiveUI
|
||
|
EAPOL_EAP_UI_DATA EapUIData;
|
||
|
|
||
|
// Interactive data received from InvokeInteractiveUI
|
||
|
BOOL fEapUIDataReceived;
|
||
|
|
||
|
// EAP type for the connection
|
||
|
DWORD dwEapTypeToBeUsed;
|
||
|
|
||
|
// Index for current EAP type in index table
|
||
|
DWORD dwEapIndex;
|
||
|
|
||
|
// Current EAP identifier working with
|
||
|
BYTE bCurrentEAPId;
|
||
|
|
||
|
// Unique identifier for UI invocation
|
||
|
DWORD dwUIInvocationId;
|
||
|
|
||
|
// Interactive dialog allowed?
|
||
|
BOOL fNonInteractive;
|
||
|
|
||
|
// EAP state for the port
|
||
|
EAPSTATE EapState;
|
||
|
|
||
|
// EAP UI state for the port
|
||
|
EAPUISTATE EapUIState;
|
||
|
|
||
|
// Work space for EAP implementation DLL
|
||
|
// PCB just holds the pointer, the memory allocation is done by the EAP DLL
|
||
|
// during RasEapBegin and should be passed to RasEapEnd for cleanup
|
||
|
LPVOID lpEapDllWorkBuffer;
|
||
|
|
||
|
// Notification message
|
||
|
WCHAR *pwszEapReplyMessage;
|
||
|
|
||
|
// Master secrets used in decrypting EAPOL-Key messages
|
||
|
DATA_BLOB MasterSecretSend;
|
||
|
DATA_BLOB MasterSecretRecv;
|
||
|
|
||
|
// Copies of the MPPE Keys obtained from EAP authentication
|
||
|
DATA_BLOB MPPESendKey;
|
||
|
DATA_BLOB MPPERecvKey;
|
||
|
|
||
|
// Last replay counter. Used to guard against security attacks
|
||
|
ULONGLONG ullLastReplayCounter;
|
||
|
|
||
|
// EAPOL to run on this port or not
|
||
|
DWORD dwEapolEnabled;
|
||
|
|
||
|
// Has EAPOL_Logoff packet been sent out on this port?
|
||
|
DWORD dwLogoffSent;
|
||
|
|
||
|
// Authentication type last performed - Used with MACHINE_AUTH
|
||
|
EAPOL_AUTHENTICATION_TYPE PreviousAuthenticationType;
|
||
|
|
||
|
// Number of current authentication failures for the port - MACHINE_AUTH
|
||
|
DWORD dwAuthFailCount;
|
||
|
|
||
|
// Is authentication being done on a new AP/Switch/Network?
|
||
|
BOOLEAN fAuthenticationOnNewNetwork;
|
||
|
|
||
|
// Tick count, the last time the port was restart
|
||
|
DWORD dwLastRestartTickCount;
|
||
|
|
||
|
// Zero Config transaction Id
|
||
|
DWORD dwZeroConfigId;
|
||
|
|
||
|
// Total Max Authentication tries (Machine + User + Guest)
|
||
|
DWORD dwTotalMaxAuthFailCount;
|
||
|
|
||
|
// Did EAP on Client-side actually succeed
|
||
|
BOOLEAN fLocalEAPAuthSuccess;
|
||
|
|
||
|
// Client-side auth result code
|
||
|
DWORD dwLocalEAPAuthResult;
|
||
|
|
||
|
// Supplicant-mode
|
||
|
DWORD dwSupplicantMode;
|
||
|
|
||
|
// EAPOL Authentication Mode 0 = XP RTM, 1 = XP SP1, 2 = Machine auth only
|
||
|
DWORD dwEAPOLAuthMode;
|
||
|
|
||
|
// Flag to indicate where the Session Keys which module the session keys
|
||
|
// were last used from
|
||
|
BOOLEAN fLastUsedEAPOLKeys;
|
||
|
|
||
|
// Flag to indicate whether EAPOL-Key packet for transmit key
|
||
|
// was received after getting into AUTHENTICATED state for wireless
|
||
|
// interface
|
||
|
BOOLEAN fTransmitKeyReceived;
|
||
|
|
||
|
} EAPOL_PCB, *PEAPOL_PCB;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Synchronization
|
||
|
//
|
||
|
#define EAPOL_REFERENCE_PORT(PCB) \
|
||
|
(EAPOL_PORT_DELETED(PCB) ? FALSE : (InterlockedIncrement(&(PCB)->dwRefCount), TRUE))
|
||
|
|
||
|
#define EAPOL_DEREFERENCE_PORT(PCB) \
|
||
|
(InterlockedDecrement(&(PCB)->dwRefCount) ? TRUE : (ElCleanupPort(PCB), FALSE))
|
||
|
|
||
|
|
||
|
//
|
||
|
// FUNCTION DECLARATIONS
|
||
|
//
|
||
|
|
||
|
DWORD
|
||
|
ElHashPortToBucket (
|
||
|
IN WCHAR *pwszDeviceGUID
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
ElRemovePCBFromTable (
|
||
|
IN EAPOL_PCB *pPCB
|
||
|
);
|
||
|
|
||
|
PEAPOL_PCB
|
||
|
ElGetPCBPointerFromPortGUID (
|
||
|
IN WCHAR *pwszDeviceGUID
|
||
|
);
|
||
|
|
||
|
DWORD
|
||
|
ElCreatePort (
|
||
|
IN HANDLE hDevice,
|
||
|
IN WCHAR *pwszGUID,
|
||
|
IN WCHAR *pwszFriendlyName,
|
||
|
IN DWORD dwZeroConfigId,
|
||
|
IN PRAW_DATA prdRawData
|
||
|
);
|
||
|
|
||
|
DWORD
|
||
|
ElDeletePort (
|
||
|
IN WCHAR *pwszDeviceName,
|
||
|
OUT HANDLE *hDevice
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
ElCleanupPort (
|
||
|
IN EAPOL_PCB *pPCB
|
||
|
);
|
||
|
|
||
|
DWORD
|
||
|
ElReStartPort (
|
||
|
IN PEAPOL_PCB pPCB,
|
||
|
IN DWORD dwZeroConfigId,
|
||
|
IN PRAW_DATA prdUserData
|
||
|
);
|
||
|
|
||
|
DWORD
|
||
|
ElReadFromPort (
|
||
|
IN PEAPOL_PCB pPCB,
|
||
|
IN PCHAR pBuffer,
|
||
|
IN DWORD dwBufferLength
|
||
|
);
|
||
|
|
||
|
DWORD
|
||
|
ElWriteToPort (
|
||
|
IN PEAPOL_PCB pPCB,
|
||
|
IN PCHAR pBuffer,
|
||
|
IN DWORD dwBufferLength
|
||
|
);
|
||
|
|
||
|
DWORD
|
||
|
ElInitializeEAPOL (
|
||
|
);
|
||
|
|
||
|
DWORD
|
||
|
ElEAPOLDeInit (
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
ElReadPortStatistics (
|
||
|
IN WCHAR *pwszDeviceName,
|
||
|
OUT PEAPOL_STATS pEapolStats
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
ElReadPortConfiguration (
|
||
|
IN WCHAR *pwszDeviceName,
|
||
|
OUT PEAPOL_CONFIG pEapolConfig
|
||
|
);
|
||
|
|
||
|
ULONG
|
||
|
ElSetPortConfiguration (
|
||
|
IN WCHAR *pwszDeviceName,
|
||
|
IN PEAPOL_CONFIG pEapolConfig
|
||
|
);
|
||
|
|
||
|
VOID CALLBACK
|
||
|
ElReadCompletionRoutine (
|
||
|
IN DWORD dwError,
|
||
|
IN DWORD dwBytesReceived,
|
||
|
IN PEAPOL_BUFFER pEapolBuffer
|
||
|
);
|
||
|
|
||
|
VOID CALLBACK
|
||
|
ElWriteCompletionRoutine (
|
||
|
IN DWORD dwError,
|
||
|
IN DWORD dwBytesSent,
|
||
|
IN PEAPOL_BUFFER pEapolBuffer
|
||
|
);
|
||
|
|
||
|
VOID CALLBACK
|
||
|
ElIoCompletionRoutine (
|
||
|
IN DWORD dwError,
|
||
|
IN DWORD dwBytesTransferred,
|
||
|
IN LPOVERLAPPED lpOverlapped
|
||
|
);
|
||
|
|
||
|
DWORD
|
||
|
ElReadPerPortRegistryParams(
|
||
|
IN WCHAR *pwszDeviceGUID,
|
||
|
IN EAPOL_PCB *pNewPCB
|
||
|
);
|
||
|
|
||
|
|
||
|
#endif // _EAPOL_PORT_H_
|