528 lines
20 KiB
C
528 lines
20 KiB
C
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
|
|
// PARTICULAR PURPOSE.
|
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
|
|
#ifndef _SAMPLE_AUTHENTICATOR_EAPMETHOD_H_
|
|
#define _SAMPLE_AUTHENTICATOR_EAPMETHOD_H_
|
|
|
|
#pragma once
|
|
|
|
#include <windows.h>
|
|
#include "eaptypes.h"
|
|
#include "eapmethodtypes.h"
|
|
#include "EapMethodAuthenticatorApis.h"
|
|
#include "lmcons.h" // <UNLEN, PWLEN>
|
|
|
|
|
|
/// This Sample DLL sends a simple challenge request from server -> client.
|
|
const char STRING_CHALLENGE_MESSAGE[] = "send password";
|
|
|
|
/// Byte length of simple challenge request.
|
|
const size_t STRING_LENGTH_CHALLENGE_MESSAGE = sizeof(STRING_CHALLENGE_MESSAGE);
|
|
|
|
/// The # of attributes we need to add during authentication.
|
|
/// (Attributes: username, password)
|
|
const DWORD ATTRIBUTE_COUNT_AUTHENTICATION = 2;
|
|
|
|
/// Following are required for registering Eap Authenticator Method with EapHost.
|
|
const wchar_t authFriendlyName[] = L"AuthenticatorFriendlyName";
|
|
const wchar_t authDllPath[] = L"AuthenticatorDllPath";
|
|
const wchar_t properties[] = L"Properties";
|
|
const wchar_t authFriendlyNameValue[] = L"SdkAuthenticatorEapMethod";
|
|
const DWORD propertiesValue = 0x280000; ///< eapPropMppeEncryption (0x80000) & eapPropSupportsConfig (0x200000)
|
|
const wchar_t authMethodDllName[] = L"ServerSdkMethodDll.dll";
|
|
|
|
const DWORD AUTH_SUCCESS = 0;
|
|
const DWORD AUTH_FAILURE = 1;
|
|
|
|
typedef struct _EAP_NAME_DIALOG
|
|
{
|
|
WCHAR awszIdentity[ UNLEN + 1 ]; ///< A string buffer which will contain the authenticating user's username.
|
|
WCHAR awszPassword[ PWLEN + 1 ]; ///< A string buffer which will contain the authenticating user's password.
|
|
} EAP_NAME_DIALOG;
|
|
|
|
typedef struct _USER_DATA_BLOB
|
|
{
|
|
DWORD eapTypeId;
|
|
EAP_NAME_DIALOG eapUserNamePassword;
|
|
}USER_DATA_BLOB;
|
|
|
|
|
|
/// Enum: States within the EAP state machines used by this EAP Authenticator Dll.
|
|
typedef enum _MYSTATE
|
|
{
|
|
MYSTATE_Initial,
|
|
MYSTATE_ReqSent,
|
|
} MYSTATE;
|
|
|
|
|
|
/**
|
|
* EAP working buffer.
|
|
*
|
|
* This structure contains all persistent data that the EAP method needs to
|
|
* operate. The data buffer is created inside EapMethodAuthenticatorBeginSession(),
|
|
* persists through the entire authentication session, and is released inside
|
|
* EapMethodAuthenticatorEndSession().
|
|
*/
|
|
typedef struct _EAPCB
|
|
{
|
|
LPVOID pWorkBuffer; ///< Pointer to self -- a pointer to the memory buffer containing this instance of the structure.
|
|
DWORD fFlags; ///< One or more flags that quantify the authentication process.
|
|
MYSTATE EapState; ///< Current state within EAP state machine.
|
|
DWORD dwResult; ///< The overall result of the authentication attempt.
|
|
|
|
EapAttributes* pEapAttributes;
|
|
DWORD dwSizeofConnectionData; ///< Size of Connection Data
|
|
PBYTE pConnectionData; ///< Pointer to Connection Data
|
|
DWORD dwMaxSendPacketSize; ///< Max Size of EAP packet to send back.
|
|
|
|
CHAR aszIdentity[ UNLEN + 1 ]; ///< A string buffer which will contain the authenticating user's username, once it is known.
|
|
CHAR aszPassword[ PWLEN + 1 ]; ///< A string buffer which will contain the authenticating user's password, once it is known.
|
|
|
|
EapAttributes* pUserAttributes; ///< Local pointer to EAP attributes that contains UserName and Password and may be sent to the authenticator for authentication..
|
|
EapAttributes* pMPPEKeyAttributes; ///< Local pointer to the MPPE key EAP attributes generated by this EAP provider after a successful authentication transaction has been performed.
|
|
}EAPCB;
|
|
|
|
//
|
|
// EAP Functions whose function pointer is returned back in EapMethodAuthenticatorGetInfo().
|
|
//
|
|
|
|
DWORD SdkEapMethodAuthenticatorInitialize(
|
|
IN EAP_METHOD_TYPE* pEapType,
|
|
OUT EAP_ERROR** ppEapError
|
|
);
|
|
|
|
DWORD SdkEapMethodAuthenticatorBeginSession(
|
|
// Flags to qualify the authentication process.
|
|
IN DWORD dwFlags,
|
|
// Identity of the user being authenticated
|
|
IN LPCWSTR pwszIdentity,
|
|
// Pointer to an array of attributes. This array contains attributes that
|
|
// describe the entity being authenticated.
|
|
IN const EapAttributes* const pAttributeArray,
|
|
// Specifies the size in bytes of the data pointed to by pConnectionData.
|
|
// If pConnectionData is NULL, this member is zero.
|
|
IN DWORD dwSizeofConnectionData,
|
|
// Pointer to connection data received from the authentication protocol's
|
|
// configuration user interface.
|
|
IN const BYTE* const pConnectionData,
|
|
// This is the maximum size of an eap packet that the authenticator can send.
|
|
IN DWORD dwMaxSendPacketSize,
|
|
// The session handle that identifies the current authentication session.
|
|
OUT EAP_SESSION_HANDLE* pSessionHandle,
|
|
// On an unsuccessful call, this will contain any error information about
|
|
// the failure. This will be null on a successful call.
|
|
OUT EAP_ERROR** pEapError
|
|
);
|
|
|
|
DWORD SdkEapMethodAuthenticatorUpdateInnerMethodParams(
|
|
// context handle as returned from a successful call to
|
|
// EapAuthenticatorBeginSession
|
|
IN EAP_SESSION_HANDLE sessionHandle,
|
|
IN DWORD dwFlags,
|
|
IN CONST WCHAR* pwszIdentity,
|
|
// Pointer to an array of attributes. This array contains attributes that
|
|
// describe the entity being authenticated.
|
|
IN const EapAttributes* const pAttributeArray,
|
|
// On an unsuccessful call, this will contain any error information about
|
|
// the failure. This will be null on a successful call.
|
|
OUT EAP_ERROR** pEapError
|
|
);
|
|
|
|
|
|
// The authenticator calls this any time it receives a packet that the eaphost
|
|
// needs to process. This should be called only after a successful call to
|
|
// EapAuthenticatorBeginSession.
|
|
DWORD SdkEapMethodAuthenticatorReceivePacket(
|
|
// context handle as returned from a successful call to
|
|
// EapAuthenticatorBeginSession
|
|
IN EAP_SESSION_HANDLE sessionHandle,
|
|
// Specifies the size, in bytes, of the buffer pointed to by
|
|
// pReceivePacket
|
|
IN DWORD cbReceivePacket,
|
|
// Pointer to a buffer that contains the incoming EAP data received by
|
|
// the supplicant.
|
|
IN const EapPacket* const pReceivePacket,
|
|
// This enumeration tells the supplicant to take an appropriate action.
|
|
// The supplicant will typically look at this action and either call
|
|
// another method on eaphost or do something else on its own.
|
|
OUT EAP_METHOD_AUTHENTICATOR_RESPONSE_ACTION* pEapOutput,
|
|
// On an unsuccessful call, this will contain any error information about
|
|
// the failure. This will be null on a successful call.
|
|
OUT EAP_ERROR** pEapError
|
|
);
|
|
|
|
DWORD SdkEapMethodAuthenticatorSendPacket(
|
|
// context handle as returned from a successful call to
|
|
// EapHostAuthenticatorBeginSession
|
|
IN EAP_SESSION_HANDLE sessionHandle,
|
|
// Id to use when constructing the SendPacket
|
|
IN BYTE bPacketId,
|
|
// Specifies the limit on the size, in bytes, on the packet generated
|
|
// by eaphost. On a successful return, this will contain the size of the
|
|
// data added by the eap module.
|
|
OUT DWORD* pcbSendPacket,
|
|
// Pointer to a buffer that is allocated by the client and populated
|
|
// by the eap module. The value of the incoming buffer is ignored and
|
|
// the method populates it from the beginning of the buffer.
|
|
OUT EapPacket* pSendPacket,
|
|
// Timeout option for sending the packet
|
|
OUT EAP_AUTHENTICATOR_SEND_TIMEOUT* pTimeout,
|
|
// On an unsuccessful call, this will contain any error information about
|
|
// the failure. This will be null on a successful call.
|
|
OUT EAP_ERROR** pEapError
|
|
);
|
|
|
|
// Returns an array of attributes that the caller needs to act on.
|
|
// The supplicant will call this when a call to
|
|
// EapHostAuthenticatorProcessRequestPacket returns EapHostAuthenticatorResponseRespond.
|
|
DWORD SdkEapMethodAuthenticatorGetAttributes(
|
|
// context handle as returned from a successful call to
|
|
// EapHostAuthenticatorBeginSession
|
|
IN EAP_SESSION_HANDLE sessionHandle,
|
|
// Array of attributes that the caller needs to act on.
|
|
OUT EapAttributes* pAttribs,
|
|
OUT EAP_ERROR** pEapError
|
|
);
|
|
|
|
// Sets an array of attributes that the caller wants the eap method to act
|
|
// on.
|
|
DWORD SdkEapMethodAuthenticatorSetAttributes(
|
|
// context handle as returned from a successful call to
|
|
// EapHostAuthenticatorBeginSession
|
|
IN EAP_SESSION_HANDLE sessionHandle,
|
|
IN const EapAttributes* const pAttribs,
|
|
// This enumeration tells the supplicant to take an appropriate action.
|
|
// The supplicant will typically look at this action and either call
|
|
// another method on eaphost or do something else on its own.
|
|
OUT EAP_METHOD_AUTHENTICATOR_RESPONSE_ACTION* pEapOutput,
|
|
// On an unsuccessful call, this will contain any error information about
|
|
// the failure. This will be null on a successful call.
|
|
OUT EAP_ERROR** ppEapError
|
|
);
|
|
|
|
// The authenticator will call this on completion of an authentication. This
|
|
// can happen in any of the following scenarios:
|
|
// 1. A call to EapHostAuthenticatorReceivePacket returned
|
|
// EAP_HOST_AUTHENTICATOR_RESPONSE_SUCCESS or EAP_HOST_AUTHENTICATOR_RESPONSE_FAILURE
|
|
// Even if the action returned above was a success, the authenticator can choose to call
|
|
// this method with a failure.
|
|
// 2. The server can choose to terminate an authentication with a failure in the middle of
|
|
// an authentication.
|
|
DWORD SdkEapMethodAuthenticatorGetResult(
|
|
// context handle as returned from a successful call to
|
|
// EapHostPeerBeginSession
|
|
IN EAP_SESSION_HANDLE sessionHandle,
|
|
// A structure that indicates the result and any state that the
|
|
// supplicant needs to save for future authentications.
|
|
OUT EAP_METHOD_AUTHENTICATOR_RESULT* ppResult,
|
|
// On an unsuccessful call, this will contain any error information about
|
|
// the failure. This will be null on a successful call.
|
|
OUT EAP_ERROR** pEapError
|
|
);
|
|
|
|
// Ends the authentication session. This cleans up any state that the eap
|
|
// method or eaphost might be keeping.
|
|
DWORD SdkEapMethodAuthenticatorEndSession(
|
|
// context handle as returned from a successful call to
|
|
// EapHostPeerBeginSession. This will be set to NULL on a successful call.
|
|
IN EAP_SESSION_HANDLE sessionHandle,
|
|
// On an unsuccessful call, this will contain any error information about
|
|
// the failure. This will be null on a successful call.
|
|
OUT EAP_ERROR** ppEapError
|
|
);
|
|
|
|
DWORD SdkEapAuthenticatorShutdown(
|
|
IN EAP_METHOD_TYPE* pEapType,
|
|
OUT EAP_ERROR** ppEapError
|
|
);
|
|
|
|
|
|
//
|
|
// Helper Functions
|
|
//
|
|
|
|
/**
|
|
* MakeRequestMessage() helper function: Construct a request message
|
|
*
|
|
* This function builds the EAP-Challenge message(s) sent to the client.
|
|
*
|
|
*
|
|
* @param pwb [in] Pointer to the work buffer.
|
|
*
|
|
* @param bPacketId [in] PacketId to be used in the EapChallenge Method.
|
|
*
|
|
* @param pSendPacket [out] Pointer to a EapPacket structure. The
|
|
* authentication protocol can use this structure
|
|
* to specify a packet to send.
|
|
*
|
|
* @param pcbSendPacket [out] Specifies the size, in bytes, of the buffer
|
|
* pointed to by pSendPacket.
|
|
*
|
|
*
|
|
* @return If the function succeeds, the return value is NO_ERROR.
|
|
*/
|
|
DWORD
|
|
MakeRequestMessage(
|
|
IN EAPCB* pwb,
|
|
IN BYTE bPacketId,
|
|
OUT EapPacket *pSendPacket,
|
|
OUT DWORD * pcbSendPacket
|
|
);
|
|
|
|
/**
|
|
* GetPasswordFromResponse() helper function: Parse a response packet to extract
|
|
* the password.
|
|
*
|
|
* This function handles reading the EAP client's response packet. It
|
|
* obtains the user's password, to use when authenticating the user.
|
|
*
|
|
*
|
|
* @param pReceiveBuf [in] Pointer to a EapPacket structure that
|
|
* contains a received packet.
|
|
*
|
|
* @param pszPassword [out] Pointer to a buffer, into which the password
|
|
* will be copied. The caller is responsible for
|
|
* allocating & freeing this buffer.
|
|
*
|
|
* @param size [in,out] size of the password
|
|
*
|
|
* @return If the function succeeds, the return value is NO_ERROR.
|
|
*/
|
|
DWORD
|
|
GetPasswordFromResponse(
|
|
IN const BYTE* const pReceivePacket,
|
|
OUT __out_bcount(size) CHAR* pszPassword,
|
|
size_t &size
|
|
);
|
|
|
|
/**
|
|
* MakeAuthenticationAttributes() helper function: Build authentication
|
|
* attributes to be sent to the authentication provider.
|
|
*
|
|
* This function wraps the received username & password into EAP
|
|
* authentication attributes. The authentication provider will process these
|
|
* attributes, determine whether the authentication succeeded or failed.
|
|
*
|
|
*
|
|
* @param szUserName [in] The username received from the EAP client.
|
|
*
|
|
* @param szPassword [in] The password received from the EAP client.
|
|
*
|
|
* @param pwb [in] Pointer to the work buffer.
|
|
*
|
|
*
|
|
* @return If the function succeeds, the return value is NO_ERROR.
|
|
*/
|
|
DWORD
|
|
MakeAuthenticationAttributes(
|
|
IN __in CHAR * szUserName,
|
|
IN __in CHAR * szPassword,
|
|
IN EAPCB * pwb
|
|
);
|
|
|
|
/**
|
|
* MakeMPPEKeyAttributes() helper function: Build MPPE Key attributes.
|
|
*
|
|
* @param pwb [in] Pointer to the work buffer.
|
|
*
|
|
* @return If the function succeeds, the return value is NO_ERROR.
|
|
*/
|
|
DWORD
|
|
MakeMPPEKeyAttributes(
|
|
IN EAPCB * pwb
|
|
);
|
|
|
|
|
|
/**
|
|
* FillMppeKeyAttribute() helper function: Construct MPPE Key attributes.
|
|
*
|
|
* This function constructs MPPE encryption key attributes and saves them
|
|
* into the EAPCB work buffer.
|
|
*
|
|
* @return A Win32 error code, indicating success or failure.
|
|
*/
|
|
DWORD FillMppeKeyAttribute(IN EAPCB *pwb,
|
|
IN BYTE *&bBuffer,
|
|
IN DWORD pattern,
|
|
IN BYTE bKeyDirection,
|
|
IN OUT EapAttribute &pAttrib);
|
|
|
|
|
|
/**
|
|
* Construct a MPPE key vendor attribute.
|
|
*
|
|
* @param bKeyDirection [in] Either MS_MPPE_SEND_KEY or MS_MPPE_RECV_KEY.
|
|
*
|
|
* @param pMppeKeyData [in] The MPPE Key data.
|
|
*
|
|
* @param cbMppeKeyData [in] The byte length of the MPPE Key data.
|
|
*
|
|
* @param pAttrib [out] The EAP attribute that will contain the
|
|
* final MPPE Key vendor attribute.
|
|
*
|
|
*
|
|
* @return A Win32 error code, indicating success or failure.
|
|
*/
|
|
DWORD
|
|
ConstructMppeKeyAttribute(
|
|
IN BYTE bKeyDirection,
|
|
IN PBYTE pMppeKeyData,
|
|
IN DWORD cbMppeKeyData,
|
|
IN OUT EapAttribute *pAttrib
|
|
);
|
|
|
|
DWORD
|
|
VerifyAuthenticationAttributes(
|
|
IN EAPCB *pwb);
|
|
|
|
/**
|
|
* GetIdentity() helper function: Get the username & password for the
|
|
* user to be authenticated.
|
|
*
|
|
* This function obtains credentials for the user being authenticated.
|
|
* It display UI requesting the username & password.
|
|
*
|
|
*
|
|
* @param hwndParent [in] Handle to the parent window for the
|
|
* user interface dialog.
|
|
*
|
|
*
|
|
* @param ppUserDataOut [out] Pointer to a pointer that, on
|
|
* successful return, points to the
|
|
* identity data for the user.
|
|
*
|
|
* @param pdwSizeOfUserDataOut [out] Pointer to a DWORD variable that
|
|
* receives the size of the data pointed
|
|
* to by the ppUserDataOut parameter.
|
|
*
|
|
*
|
|
* @return If the function succeeds, the return value is NO_ERROR.
|
|
*/
|
|
DWORD
|
|
GetIdentityAsConfigData(
|
|
IN HWND hwndParent,
|
|
OUT BYTE** ppUserDataOut,
|
|
OUT DWORD* pdwSizeOfUserDataOut
|
|
);
|
|
|
|
/**
|
|
* GetUsernameAndPassword() helper function: Display user credentials UI.
|
|
*
|
|
* This function displays an interactive UI (the IDD_CONFIG_IDENTITY_DIALOG dialog box)
|
|
* requesting the user to enter their username and password.
|
|
*
|
|
*
|
|
* @param hwndParent [in] Handle to the parent window for the
|
|
* user interface dialog.
|
|
*
|
|
* @param pEapNameDialog [in] Pointer to an EAP_NAME_DIALOG structure
|
|
* that, on successful return, will be filled
|
|
* in with the user's username & password.
|
|
* The caller is responsible for allocating
|
|
* and freeing this buffer.
|
|
*
|
|
*
|
|
* @return If the function succeeds, the return value is NO_ERROR.
|
|
*/
|
|
DWORD
|
|
GetUsernameAndPassword(
|
|
IN HWND hwndParent,
|
|
IN USER_DATA_BLOB* pEapUserData
|
|
);
|
|
|
|
/**
|
|
* This function handles Windows messages sent to the username/password UI
|
|
* dialog box. It is called by the Windows UI subsystem.
|
|
*
|
|
* @param hWnd [in] Handle to the dialog box.
|
|
*
|
|
* @param unMsg [in] Specifies the message. Messages supported:
|
|
* \li WM_INITDIALOG -- Initialize the dialog box.
|
|
* \li WM_COMMAND -- The user has clicked on a
|
|
* menu, control, or has used an accelerator
|
|
* key.
|
|
*
|
|
* @param wParam [in] Specifies additional message-specific
|
|
* information.
|
|
*
|
|
* @param lParam [in] Specifies additional message-specific
|
|
* information.
|
|
*
|
|
*
|
|
* @return The dialog box procedure should return TRUE if it processed the
|
|
* message, and FALSE if it did not. If the dialog box procedure
|
|
* returns FALSE, the dialog manager performs the default dialog
|
|
* operation in response to the message.
|
|
*/
|
|
INT_PTR CALLBACK
|
|
UsernameDialogProc(
|
|
IN HWND hWnd,
|
|
IN UINT unMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
);
|
|
|
|
/**
|
|
* UsernameDialogProc() helper function: initialize the username dialog.
|
|
*
|
|
* This function handles the WM_INITDIALOG message, by initializing the
|
|
* username dialog.
|
|
*
|
|
*
|
|
* @param hWnd [in] Handle to the dialog box.
|
|
*
|
|
* @param lParam [in] Specifies additional message-specific
|
|
* information.
|
|
*
|
|
*
|
|
* @return FALSE, to prevent Windows from setting the default keyboard focus.
|
|
*/
|
|
|
|
BOOL
|
|
InitUsernameDialog(
|
|
IN HWND hWnd,
|
|
IN LPARAM lParam
|
|
);
|
|
|
|
/**
|
|
*
|
|
* This function handles the WM_COMMAND message, by saving any data the user
|
|
* has entered into the text fields of the username dialog.
|
|
*
|
|
* @param pEapNameDialog [in] Pointer to an EAP_NAME_DIALOG structure
|
|
* that, on successful return, will be filled
|
|
* in with the user's username & password. This
|
|
* buffer must be allocated before this
|
|
* function is called.
|
|
*
|
|
* @param wId [in] The identifier of the menu item, control,
|
|
* or accelerator. Supported identifiers:
|
|
* \li IDOK - the dialog's OK button. The
|
|
* user's credentials will be saved.
|
|
* \li IDCANCEL - the dialog's Cancel button.
|
|
*
|
|
* @param hWndDlg [in] Handle to the dialog box.
|
|
*
|
|
*
|
|
* @return TRUE if we processed this message; FALSE if we did not process
|
|
* this message.
|
|
*/
|
|
BOOL
|
|
UsernameCommand(
|
|
IN USER_DATA_BLOB* pEapUserData,
|
|
IN WORD wId,
|
|
IN HWND hWndDlg
|
|
);
|
|
|
|
#endif
|