home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / rras / eap / eap.c next >
Encoding:
C/C++ Source or Header  |  1997-10-10  |  23.1 KB  |  927 lines

  1. /********************************************************************/
  2. /**          Copyright(c) 1985-1997 Microsoft Corporation.         **/
  3. /********************************************************************/
  4.  
  5. //***
  6. //
  7. // Filename:    eap.c
  8. //
  9. // Description: Sample Extensible Authentication Protocol.
  10. //              Here is a graphic of the EAP sample protocol:
  11. //
  12. //
  13. //      Authenticator                       Authenticatee
  14. //      -------------                       -------------
  15. //
  16. //                      "Send Password"
  17. //                  ---------------------->
  18. //                        EAP Request
  19. //
  20. //                        <password>
  21. //                  <----------------------
  22. //                        EAP Response
  23. //
  24. //  
  25. //                  ----------------------->
  26. //                       Success/Failure
  27. //
  28. //
  29.  
  30. #include <windows.h>
  31. #include <lmcons.h>
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include <rasauth.h>
  35. #include <raseapif.h>
  36. #include <raserror.h>
  37. #define SDEBUGGLOBALS
  38. #define RASEAPGLOBALS
  39. #include "eap.h"
  40.  
  41. /*---------------------------------------------------------------------------
  42. ** External entry points
  43. **---------------------------------------------------------------------------
  44. */
  45.  
  46. BOOL
  47. RasEapDllEntry(
  48.     IN HANDLE hinstDll,
  49.     IN DWORD  fdwReason,
  50.     IN LPVOID lpReserved 
  51. )
  52.     //
  53.     // This routine is called by the system on various events such as the
  54.     // process attachment and detachment.  See Win32 DllEntryPoint
  55.     // documentation.
  56.     //
  57.     // Returns true if successful, false otherwise.
  58.     //
  59. {
  60.     switch (fdwReason)
  61.     {
  62.         case DLL_PROCESS_ATTACH:
  63.         {
  64.             DisableThreadLibraryCalls( hinstDll );
  65.  
  66.             break;
  67.         }
  68.  
  69.         case DLL_PROCESS_DETACH:
  70.         {
  71.             break;
  72.         }
  73.     }
  74.  
  75.     return( TRUE );
  76. }
  77.  
  78.  
  79. DWORD APIENTRY
  80. RasEapGetInfo (
  81.     IN  DWORD         dwEapTypeId,
  82.     OUT PPP_EAP_INFO* pInfo 
  83. )
  84.     //
  85.     // RasEapGetInfo entry point called by the EAP-PPP engine by name.  
  86.     //
  87. {
  88.     if ( dwEapTypeId != PPP_EAP_PROTOCOL_ID )
  89.     {
  90.         return( ERROR_NOT_SUPPORTED );
  91.     }
  92.  
  93.     ZeroMemory( pInfo, sizeof(PPP_EAP_INFO) );
  94.  
  95.     pInfo->dwEapTypeId       = PPP_EAP_PROTOCOL_ID;
  96.     pInfo->RasEapBegin       = EapBegin;
  97.     pInfo->RasEapEnd         = EapEnd;
  98.     pInfo->RasEapMakeMessage = EapMakeMessage;
  99.  
  100.     return( NO_ERROR );
  101. }
  102.  
  103.  
  104. DWORD APIENTRY
  105. EapBegin(
  106.     OUT VOID** ppWorkBuf,
  107.     IN  VOID*  pInfo 
  108. )
  109.  
  110.     //
  111.     // EapBegin entry point called by the EAP-PPP engine thru the passed
  112.     // address.
  113.     //
  114. {
  115.     PPP_EAP_INPUT* pInput = (PPP_EAP_INPUT* )pInfo;
  116.     EAPCB*         pwb;
  117.  
  118.     //
  119.     // Allocate work buffer.
  120.     //
  121.  
  122.     if (!(pwb = (EAPCB* )LocalAlloc( LPTR, sizeof(EAPCB) )))
  123.     {
  124.         return( ERROR_NOT_ENOUGH_MEMORY );
  125.     }
  126.  
  127.     //
  128.     // Save information passed in
  129.     //
  130.  
  131.     pwb->fAuthenticator                = pInput->fAuthenticator;
  132.     pwb->EapState                      = MYSTATE_Initial;
  133.     pwb->hPort                         = pInput->hPort;
  134.     FpRasAuthenticateClient            = pInput->RasAuthenticateClient;
  135.  
  136.     //
  137.     // Save the identity. On the authenticatee side, this is obtained by user
  138.     // input, on the authenticator side this was obtained by the Identity
  139.     // request message.
  140.  
  141.     strcpy( pwb->szIdentity, pInput->pszIdentity );
  142.  
  143.     //
  144.     // If we are an authenticatee, then use the password passed in
  145.     //
  146.  
  147.     if ( !pwb->fAuthenticator )
  148.     {
  149.         strcpy (pwb->szPassword, pInput->pszPassword);
  150.     }
  151.  
  152.     //
  153.     // Register work buffer with engine.
  154.     //
  155.  
  156.     *ppWorkBuf = pwb;
  157.  
  158.     return( NO_ERROR );
  159. }
  160.  
  161.  
  162. DWORD APIENTRY
  163. EapEnd(
  164.     IN VOID* pWorkBuf 
  165. )
  166.     //
  167.     // RasCpEnd entry point called by the PPP engine thru the passed address.
  168.     // See RasCp interface documentation.
  169.     //
  170. {
  171.     if (pWorkBuf)
  172.     {
  173.         ZeroMemory( pWorkBuf, sizeof(EAPCB) );
  174.         LocalFree( (HLOCAL )pWorkBuf );
  175.     }
  176.  
  177.     return( NO_ERROR );
  178. }
  179.  
  180. DWORD APIENTRY
  181. EapMakeMessage(
  182.     IN  VOID*               pWorkBuf,
  183.     IN  PPP_EAP_PACKET*     pReceiveBuf,
  184.     OUT PPP_EAP_PACKET*     pSendBuf,
  185.     IN  DWORD               cbSendBuf,
  186.     OUT PPP_EAP_OUTPUT*     pResult,
  187.     IN  PPP_EAP_INPUT*      pInput 
  188. )
  189.     //
  190.     // RasEapMakeMessage entry point called by the PPP engine thru the passed
  191.     // address.  
  192.     //
  193. {
  194.     EAPCB* pwb = (EAPCB* )pWorkBuf;
  195.  
  196.     return
  197.         (pwb->fAuthenticator)
  198.           ? SMakeMessage(pwb, pReceiveBuf, pSendBuf, cbSendBuf, pInput, pResult)
  199.           : CMakeMessage( pwb, pReceiveBuf, pSendBuf, cbSendBuf, pInput, pResult );
  200. }
  201.  
  202.  
  203. /*---------------------------------------------------------------------------
  204. ** Internal routines 
  205. **---------------------------------------------------------------------------
  206. */
  207.  
  208. VOID
  209. HostToWireFormat16(
  210.     IN     WORD  wHostFormat,
  211.     IN OUT PBYTE pWireFormat
  212. )
  213. {
  214.     //
  215.     // Will convert a 16 bit integer from host format to wire format
  216.     //
  217.  
  218.     *((PBYTE)(pWireFormat)+0) = (BYTE) ((DWORD)(wHostFormat) >>  8);
  219.     *((PBYTE)(pWireFormat)+1) = (BYTE) (wHostFormat);
  220. }
  221.  
  222. WORD
  223. WireToHostFormat16(
  224.     IN PBYTE pWireFormat
  225. )
  226. {
  227.     //
  228.     // Will convert a 16 bit integer from wire format to host format
  229.     //
  230.  
  231.     WORD wHostFormat = ((*((PBYTE)(pWireFormat)+0) << 8) +
  232.                         (*((PBYTE)(pWireFormat)+1)));
  233.  
  234.     return( wHostFormat );
  235. }
  236.  
  237. DWORD
  238. CMakeMessage(
  239.     IN  EAPCB*            pwb,
  240.     IN  PPP_EAP_PACKET*   pReceiveBuf,
  241.     OUT PPP_EAP_PACKET*   pSendBuf,
  242.     IN  DWORD             cbSendBuf,
  243.     IN  PPP_EAP_INPUT*    pInput,
  244.     OUT PPP_EAP_OUTPUT*   pResult
  245. )
  246.     //
  247.     // Authenticatee side event handler
  248.     //
  249. {
  250.     DWORD dwRetCode = NO_ERROR;
  251.  
  252.     switch( pwb->EapState )
  253.     {
  254.         case MYSTATE_Initial:
  255.         {
  256.             if ( pReceiveBuf == NULL )
  257.             {
  258.                 //
  259.                 // We are called one in the initial state. Since we are the
  260.                 // authenticatee, do nothing wait for request Pakcet from
  261.                 // authenticator.
  262.                 //
  263.  
  264.                 pResult->Action = EAPACTION_NoAction;
  265.  
  266.                 break;
  267.             }
  268.             else
  269.             {
  270.                 //
  271.                 // If we received a request packet from the server then we
  272.                 // process it.
  273.                 //
  274.  
  275.                 if ( pReceiveBuf->Code == EAPCODE_Request )
  276.                 {
  277.                     //
  278.                     // Build the response packet
  279.                     //
  280.  
  281.                     MakeResponseMessage(pwb, pReceiveBuf, pSendBuf, cbSendBuf);
  282.                     
  283.                     //
  284.                     // Response packets should not be sent with any timeout
  285.                     //
  286.  
  287.                     pResult->Action = EAPACTION_Send;
  288.  
  289.                     //
  290.                     // We are done so we change to MYSTATE_Done
  291.                     //
  292.  
  293.                     pwb->EapState = MYSTATE_Done;
  294.                 }
  295.                 else
  296.                 {
  297.                     //
  298.                     // We shouldn't get any other packet in this state so
  299.                     // we simply drop this invalid packet
  300.                     //
  301.  
  302.                     pResult->Action = EAPACTION_NoAction;
  303.  
  304.                     dwRetCode = ERROR_PPP_INVALID_PACKET;
  305.  
  306.                     break;
  307.                 }
  308.             }
  309.  
  310.             break;
  311.         }
  312.  
  313.         case MYSTATE_Done:
  314.         {
  315.             if ( pReceiveBuf == NULL )
  316.             {
  317.                 //  
  318.                 // If we did not receive a packet then we check to see if
  319.                 // the fSuccessPacketReceived flag is set
  320.                 //
  321.  
  322.                 if ( ( pInput != NULL ) && ( pInput->fSuccessPacketReceived ) )
  323.                 {
  324.                     //
  325.                     // We are done
  326.                     //
  327.  
  328.                     pResult->Action = EAPACTION_Done;
  329.                     pwb->EapState   = MYSTATE_Done;
  330.                 }
  331.                 else
  332.                 {
  333.                     //
  334.                     // Otherwise we ignore this event
  335.                     //
  336.  
  337.                     pResult->Action = EAPACTION_NoAction;
  338.                 }
  339.  
  340.                 break;
  341.             }
  342.  
  343.             if ( ( pReceiveBuf->Code == EAPCODE_Success ) ||
  344.                  ( pReceiveBuf->Code == EAPCODE_Failure ) )
  345.             {
  346.                 //
  347.                 // If we received success or failure, we are done
  348.                 //
  349.  
  350.                 if ( pReceiveBuf->Id != pwb->dwIdExpected )
  351.                 {
  352.                     //
  353.                     // But first make sure the the Success/Failure packet ID
  354.                     // matches that of the last response sent.
  355.                     // If not silently discard the packet.
  356.                     //
  357.  
  358.                     pResult->Action = EAPACTION_NoAction;
  359.                     dwRetCode       = ERROR_PPP_INVALID_PACKET;
  360.                 }
  361.                 else
  362.                 {
  363.  
  364.                     pResult->Action = EAPACTION_Done;
  365.                     pwb->EapState   = MYSTATE_Done;
  366.                 }
  367.  
  368.                 break;
  369.             }
  370.             else if ( pReceiveBuf->Code == EAPCODE_Request )  
  371.             {
  372.                 //
  373.                 // We must always respond to requests
  374.                 //
  375.  
  376.                 MakeResponseMessage(pwb, pReceiveBuf, pSendBuf, cbSendBuf);
  377.  
  378.                 //
  379.                 // Response packets should not be sent with any timeout
  380.                 //
  381.  
  382.                 pResult->Action = EAPACTION_Send;
  383.             }
  384.             else
  385.             {
  386.                 //
  387.                 // Otherwise we received an illegal packet, wrong code set
  388.                 // So simply drop the packet.
  389.                 //
  390.  
  391.                 pResult->Action = EAPACTION_NoAction;
  392.                 dwRetCode       = ERROR_PPP_INVALID_PACKET;
  393.             }
  394.         }
  395.     }
  396.  
  397.     return( dwRetCode );
  398. }
  399.  
  400.  
  401. VOID
  402. MakeResponseMessage(
  403.     IN  EAPCB*           pwb,
  404.     IN  PPP_EAP_PACKET * pReceiveBuf,
  405.     OUT PPP_EAP_PACKET * pSendBuf,
  406.     IN DWORD             cbSendBuf
  407. )
  408.     //
  409.     // Builds a response packet.  'pwb' is the address of the work
  410.     // buffer associated with the port.
  411.     //
  412. {
  413.     BYTE* pcbPassword;
  414.     CHAR* pchPassword;
  415.  
  416.     (void )cbSendBuf;
  417.  
  418.     //
  419.     // Fill in the password.
  420.     //
  421.  
  422.     pcbPassword = pSendBuf->Data + 1; 
  423.  
  424.     *pcbPassword = (BYTE )strlen( pwb->szPassword );
  425.  
  426.     pchPassword = pcbPassword + 1;
  427.  
  428.     strcpy( pchPassword, pwb->szPassword );
  429.  
  430.     //
  431.     // Set the response code
  432.     //
  433.  
  434.     pSendBuf->Code = (BYTE )EAPCODE_Response;
  435.  
  436.     //
  437.     // The Reponse packet Id MUST match the Request packet Id.
  438.     //
  439.  
  440.     pSendBuf->Id = pReceiveBuf->Id;
  441.  
  442.     //
  443.     // The Success/Failure packet that we get must match the ID of the last 
  444.     // response sent
  445.     //
  446.  
  447.     pwb->dwIdExpected = pSendBuf->Id;
  448.  
  449.     //
  450.     // Set the EAP type ID
  451.     //
  452.  
  453.     pSendBuf->Data[0] = (BYTE )PPP_EAP_PROTOCOL_ID;
  454.  
  455.     //
  456.     // Set the length of the packet
  457.     //
  458.  
  459.     HostToWireFormat16((WORD )(PPP_EAP_PACKET_HDR_LEN+1+*pcbPassword+1),
  460.                        pSendBuf->Length );
  461. }
  462.    
  463.  
  464. VOID
  465. MakeResultMessage(
  466.     IN  DWORD           dwError,
  467.     IN  BYTE            bId,
  468.     OUT PPP_EAP_PACKET* pSendBuf,
  469.     IN  DWORD           cbSendBuf 
  470. )
  471.  
  472.     //
  473.     // Builds a result packet (Success or Failure) in caller's 'pSendBuf' 
  474.     // buffer. 'cbSendBuf' is the length of caller's buffer.  
  475.     // 'dwError' indicates whether an Success or Failure should be generated, 
  476.     // 'bId' is the Id of the Success of Failure packet.
  477.     //
  478. {
  479.     (void )cbSendBuf;
  480.  
  481.     //
  482.     // If there was no error then we send a Success packet, otherwise we send
  483.     // a failure message
  484.     //
  485.  
  486.     if ( dwError == NO_ERROR )
  487.     {
  488.         pSendBuf->Code = EAPCODE_Success;
  489.     }
  490.     else
  491.     {
  492.         pSendBuf->Code = EAPCODE_Failure;
  493.     }
  494.  
  495.     //
  496.     // Id must match the last response received
  497.     //
  498.  
  499.     pSendBuf->Id = bId;
  500.  
  501.     //
  502.     // Set the length
  503.     //
  504.  
  505.     HostToWireFormat16((WORD)PPP_EAP_PACKET_HDR_LEN, (PBYTE )pSendBuf->Length);
  506. }
  507.  
  508. VOID
  509. MakeRequestMessage(
  510.     IN  EAPCB*           pwb,
  511.     OUT PPP_EAP_PACKET * pSendBuf,
  512.     IN DWORD             cbSendBuf
  513. )
  514.  
  515.     //
  516.     // Will build a request packet
  517.     //
  518. {
  519.     BYTE *pcbPeerMessage;
  520.     CHAR *pchPeerMessage;
  521.  
  522.     pcbPeerMessage  = pSendBuf->Data + 1;
  523.  
  524.     *pcbPeerMessage = (BYTE)strlen("send password");
  525.  
  526.     pchPeerMessage  = pcbPeerMessage + 1;
  527.  
  528.     strcpy (pchPeerMessage,"send password");
  529.  
  530.     //
  531.     // Set the Request Code
  532.     // 
  533.  
  534.     pSendBuf->Code = EAPCODE_Request;
  535.  
  536.     //
  537.     // Set the Identifier
  538.     //
  539.  
  540.     pSendBuf->Id = (BYTE) dwNextId++;
  541.  
  542.     //
  543.     // Remember this Id since we need to send the Success/Failure packet with
  544.     // this Id
  545.     //
  546.  
  547.     pwb->dwIdExpected = pSendBuf->Id; 
  548.  
  549.     //
  550.     // Set the length
  551.     //
  552.  
  553.     HostToWireFormat16((WORD)(PPP_EAP_PACKET_HDR_LEN+1+*pcbPeerMessage+1),  
  554.                               pSendBuf->Length );
  555.  
  556.     //
  557.     // Set the EAP Type Id
  558.     //
  559.  
  560.     pSendBuf->Data[0] = PPP_EAP_PROTOCOL_ID;
  561.  
  562. }
  563.  
  564. DWORD
  565. SMakeMessage(
  566.     IN  EAPCB*              pwb,
  567.     IN  PPP_EAP_PACKET*     pReceiveBuf,
  568.     OUT PPP_EAP_PACKET*     pSendBuf,
  569.     IN  DWORD               cbSendBuf,
  570.     IN  PPP_EAP_INPUT*      pInput,
  571.     OUT PPP_EAP_OUTPUT*     pResult 
  572. )
  573.     //
  574.     // Authenticator side event handler
  575.     //
  576. {
  577.     DWORD dwRetCode = NO_ERROR;
  578.  
  579.     switch( pwb->EapState )
  580.     {
  581.         case MYSTATE_ReqSent:
  582.  
  583.             if ( pReceiveBuf != NULL )
  584.             {
  585.                 //
  586.                 // If we received a packet
  587.                 //
  588.  
  589.                 if ( pReceiveBuf->Code == EAPCODE_Response )
  590.                 {
  591.                     CHAR szPassword[PWLEN + 1];
  592.  
  593.                     //
  594.                     // If we received a response to our identity request, 
  595.                     // then process it. There is no need to check the Id    
  596.                     // here since the PPP engine will only pass on packets
  597.                     // whose Id matches those set with the 
  598.                     // EAPACTION_SendWithTimeout action.
  599.                     //
  600.  
  601.                     dwRetCode = GetPasswordFromResponse( pReceiveBuf, 
  602.                                                          szPassword );
  603.  
  604.                     if ( dwRetCode != NO_ERROR )
  605.                     {    
  606.                         if ( dwRetCode != ERROR_PPP_INVALID_PACKET )
  607.                         {
  608.                             //
  609.                             // Fatal error, we fail the connection. 
  610.                             //
  611.  
  612.                             return( dwRetCode );
  613.                         }
  614.                         
  615.                         //
  616.                         // Otherwise the packet is most likely corrupt.  
  617.                         // Fall thru to the initial state to resend the
  618.                         // request with the same Id.
  619.                         //
  620.  
  621.                         dwNextId = pwb->dwIdExpected;
  622.                     }
  623.                     else
  624.                     {
  625.  
  626.                         //
  627.                         // Request authentication provider to authenticate 
  628.                         // this user.
  629.                         //
  630.  
  631.                         dwRetCode = AuthenticateUser( pwb->szIdentity, 
  632.                                                       szPassword,   
  633.                                                       pwb );
  634.  
  635.                         if ( dwRetCode != NO_ERROR )
  636.                         {
  637.                             return( dwRetCode );
  638.                         }
  639.                         else
  640.                         {
  641.                             //
  642.                             // Authentication request completed successfully.
  643.                             // This is an asynchronous call so we change state
  644.                             // and wait for the provider to complete the 
  645.                             // authentication.  
  646.                             //
  647.  
  648.                             pwb->EapState = 
  649.                                     MYSTATE_WaitForAuthenticationToComplete;
  650.  
  651.                             pResult->Action = EAPACTION_NoAction;
  652.                         }        
  653.                     }
  654.  
  655.                     break;
  656.                 }
  657.                 else
  658.                 {
  659.                     //
  660.                     // Otherwise silently drop the packet. 
  661.                     // We should only get requests
  662.                     //
  663.  
  664.                     pResult->Action = EAPACTION_NoAction;
  665.  
  666.                     break;
  667.                 }
  668.             }
  669.             else
  670.             {
  671.                 //
  672.                 // If in this state we get called with a NULL pReceiveBuf, this
  673.                 // means that we timed out waiting for a response from the
  674.                 // the authenticatee, we need to resend with the same Id. 
  675.                 // 
  676.  
  677.                 dwNextId = pwb->dwIdExpected;
  678.  
  679.                 //
  680.                 // Fall thru to resend the request packet
  681.                 //
  682.             }
  683.  
  684.         case MYSTATE_Initial:
  685.  
  686.             //
  687.             // Create Request packet
  688.             //
  689.  
  690.             MakeRequestMessage( pwb, pSendBuf, cbSendBuf );
  691.  
  692.             //
  693.             // Tell the PPP engine to drop all responses that do not mactch
  694.             // this Id
  695.             //
  696.  
  697.             pResult->dwIdExpected = (BYTE)pwb->dwIdExpected;
  698.  
  699.             //
  700.             // Request messages must be sent with a timeout
  701.             //
  702.  
  703.             pResult->Action = EAPACTION_SendWithTimeout;
  704.  
  705.             //
  706.             // Send we have sent a Request we change to the ReqSent state
  707.             // where we will wait for a response
  708.             //
  709.  
  710.             pwb->EapState = MYSTATE_ReqSent;
  711.  
  712.             break;
  713.  
  714.         case MYSTATE_WaitForAuthenticationToComplete:
  715.         {
  716.             if ( pInput != NULL )
  717.             {
  718.                 //
  719.                 // Did the authentication provider complete the authentication?
  720.                 //
  721.  
  722.                 if ( pInput->fAuthenticationComplete )
  723.                 {
  724.                     //
  725.                     // If there was a processing error, simply return this 
  726.                     // error.
  727.                     //
  728.  
  729.                     if ( pInput->dwAuthError != NO_ERROR )
  730.                     {
  731.                         return( pInput->dwAuthError );
  732.                     }
  733.  
  734.                     //
  735.                     // If the authentication process completed successfully but
  736.                     // the user failed to authenticate, save the failure code.
  737.                     //
  738.  
  739.                     if ( pInput->dwAuthResultCode != NO_ERROR )
  740.                     {
  741.                         pwb->dwResult = pInput->dwAuthResultCode;
  742.                     }
  743.  
  744.                     pResult->Action = EAPACTION_SendAndDone;
  745.                     pwb->EapState   = MYSTATE_Done;
  746.  
  747.                     //
  748.                     // fall thru to the MYSTATE_Done state where we will
  749.                     // send a Success or Failure packet
  750.                     //
  751.                 }
  752.             }
  753.  
  754.             if ( ( pInput == NULL ) || ( !pInput->fAuthenticationComplete ) )
  755.             {
  756.                 //
  757.                 // Ignore everything if authentication is not complete
  758.                 //
  759.  
  760.                 pResult->Action = EAPACTION_NoAction;
  761.  
  762.                 break;
  763.             }
  764.  
  765.             //
  766.             // ...fall thru to the MYSTATE_Done state where we will
  767.             // send a Success or Failure packet
  768.             //
  769.         }
  770.  
  771.         case MYSTATE_Done:
  772.         {
  773.             //
  774.             // Make Success or Failure packet.  
  775.             //
  776.  
  777.             MakeResultMessage( pwb->dwResult,    
  778.                                (BYTE)pwb->dwIdExpected,   
  779.                                pSendBuf,  
  780.                                cbSendBuf);     
  781.  
  782.             strcpy( pResult->szIdentity, pwb->szIdentity );
  783.  
  784.             pResult->Action = EAPACTION_SendAndDone;
  785.  
  786.             pResult->dwAuthResultCode = pwb->dwResult;
  787.  
  788.             break;
  789.         }
  790.  
  791.         default:
  792.  
  793.             break;
  794.     }
  795.  
  796.     return( dwRetCode );
  797.  
  798. }
  799.  
  800. DWORD
  801. GetPasswordFromResponse(
  802.     IN  PPP_EAP_PACKET* pReceiveBuf,
  803.     OUT CHAR*           pszPassword
  804. )
  805.     //
  806.     // Fill caller's pszPassword' buffer with the password, in the request 
  807.     // packet.
  808.     //
  809.     // Returns NO_ERROR if successful., or ERROR_PPP_INVALID_PACKET if the 
  810.     // packet is misformatted in any way.
  811.     //
  812. {
  813.     BYTE* pcbPassword;
  814.     CHAR* pchPassword;
  815.     WORD  cbPacket;
  816.  
  817.     cbPacket = WireToHostFormat16( pReceiveBuf->Length );
  818.  
  819.     //
  820.     // Extract the password
  821.     //
  822.  
  823.     if ( cbPacket < ( PPP_EAP_PACKET_HDR_LEN + 1 + 1 ) )
  824.     {
  825.         return( ERROR_PPP_INVALID_PACKET );
  826.     }
  827.  
  828.     pcbPassword = pReceiveBuf->Data + 1;
  829.     pchPassword = pcbPassword + 1;
  830.  
  831.     if (cbPacket < PPP_EAP_PACKET_HDR_LEN + 1 + 1 + *pcbPassword)
  832.     {
  833.         return ERROR_PPP_INVALID_PACKET;
  834.     }
  835.  
  836.     CopyMemory( pszPassword, pchPassword, *pcbPassword );
  837.  
  838.     //
  839.     // NULL terminate the password
  840.     //
  841.  
  842.     pszPassword[ *pcbPassword ] = '\0';
  843.  
  844.     return( NO_ERROR );
  845. }
  846.  
  847. DWORD 
  848. AuthenticateUser(
  849.     IN CHAR *szUserName,    
  850.     IN CHAR *szPassword,    
  851.     IN EAPCB *pwb
  852. )
  853.     //
  854.     // Will build user attributes and send them to the authentication provider
  855.     // for authentication.
  856.     //
  857. {
  858.  
  859.     RAS_AUTH_ATTRIBUTE *pAttributes = NULL;
  860.     DWORD dwRetCode;
  861.  
  862.     pAttributes = (RAS_AUTH_ATTRIBUTE *)
  863.                  LocalAlloc(LPTR, sizeof (RAS_AUTH_ATTRIBUTE) * 3);
  864.  
  865.     if (pAttributes == NULL) 
  866.     {
  867.         return (GetLastError());
  868.     }
  869.  
  870.     //
  871.     // for user name
  872.     //
  873.  
  874.     pAttributes[0].raaType = raatUserName;
  875.     pAttributes[0].dwLength =strlen(szUserName);
  876.     pAttributes[0].Value = LocalAlloc(LPTR, (strlen(szUserName)+1));
  877.  
  878.     if (pAttributes == NULL) 
  879.     { 
  880.         LocalFree (pAttributes); 
  881.         return (GetLastError());
  882.     }
  883.  
  884.     CopyMemory (pAttributes[0].Value,szUserName, strlen(szUserName));
  885.  
  886.     //
  887.     // for password
  888.     //
  889.  
  890.     pAttributes[1].raaType = raatUserPassword;
  891.     pAttributes[1].dwLength =strlen(szPassword);
  892.     pAttributes[1].Value = LocalAlloc(LPTR, (strlen(szPassword)+1));
  893.  
  894.     if (pAttributes == NULL) 
  895.     { 
  896.         LocalFree (pAttributes[0].Value);
  897.         LocalFree (pAttributes); 
  898.         return (GetLastError());
  899.     }
  900.  
  901.     CopyMemory (pAttributes[1].Value,szPassword, strlen(szPassword));
  902.   
  903.     //
  904.     // For Termination
  905.     //
  906.  
  907.     pAttributes[2].raaType  = raatMinimum;
  908.     pAttributes[2].dwLength = 0;
  909.     pAttributes[2].Value    = NULL;
  910.  
  911.  
  912.     //
  913.     // Call the authentication provider
  914.     //
  915.  
  916.     dwRetCode = (*FpRasAuthenticateClient)( pwb->hPort, pAttributes );
  917.  
  918.     //
  919.     // Free up Attributes
  920.     //
  921.  
  922.     LocalFree (pAttributes[0].Value);
  923.     LocalFree (pAttributes[1].Value);
  924.  
  925.     return( dwRetCode );
  926. }
  927.