--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linklayerprotocols/pppnif/SPPP/PPPAUTH.CPP Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,449 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+
+#include <in_iface.h>
+#include "PPPAUTH.H"
+
+#include "ppppap.h"
+#include "chapmd5.h"
+#include "MSCHAP.H"
+#include "mschap2.h"
+#include <commsdattypeinfov1_1.h>
+#include "PPPConfig.h"
+
+#if defined(_DEBUG)
+const TInt KLCPConfigOptionTypeFieldSize = 1;
+const TInt KLCPConfigOptionLengthFieldSize = 1;
+#endif
+const TInt KAuthenticationProtocolOptionFieldSize = 2;
+const TInt KChapAlgorithmFieldSize = 1;
+
+
+//
+
+void CPppAuthentication::InitL(
+ CPppLcp* aPppLcp)
+/**
+Initializes the authentication protocol.
+@param aPppLcp Parent LCP instance
+@leave The method does not leave */
+ {
+ MPppRecvr::Init(aPppLcp, PppPhase(), PppId());
+ }
+
+CPppAuthentication::~CPppAuthentication()
+/**
+Destructor, generates a CancelAuthenticate notification to the
+parent LCP instance */
+ {
+ if (iPppLcp != 0)
+ iPppLcp->CancelAuthenticate(this);
+ }
+
+void CPppAuthentication::AuthenticateRequest()
+/**
+Generates an Authenticate notification to the parent LCP instance */
+ {
+ ASSERT(iPppLcp != 0);
+ iPppLcp->Authenticate(this);
+ }
+
+void CPppAuthentication::CallAuthenticateComplete(
+ TInt aRes)
+/**
+Notifies the derived class that the LCP authentication is completed
+@param aRes Code describing the authentication result
+ (KErrNone: authentication OK) */
+ {
+ ASSERT(iPppLcp != 0);
+ iFlags |= KPppApAuthReqDone;
+ AuthenticateComplete(aRes);
+ }
+
+void CPppAuthentication::DoFail(
+ TInt aErrorCode)
+/**
+Notifies the parent LCP instance of an error encountered
+during authentication
+@param aErrorCode Describes the authentication failure */
+ {
+ ASSERT(iPppLcp != 0);
+ iPppLcp->Progress(EPppProgressAuthenticationComplete, aErrorCode);
+ iPppLcp->PhaseAborted(aErrorCode);
+ }
+
+
+void CPppAuthentication::DoSucceed()
+/**
+Notifies the parent LCP instance that the
+authentication phase completed successfully */
+ {
+ ASSERT(iPppLcp != 0);
+
+ iPppLcp->Progress(EPppProgressAuthenticationComplete, KErrNone);
+ iPppLcp->PhaseComplete();
+ }
+
+
+//
+
+static const TInt KOptionListLen = 1;
+static const TUint8 OptionList[KOptionListLen] =
+ {
+ KPppLcpOptAuthenticationProtocol
+ };
+
+CPppAcp* CPppAcp::NewL(
+ CPppLcp* aLcp)
+/**
+Creates a new CPppAcp instance
+@param aLcp Parent LCP instance
+@return Newly created CPppAcp instance */
+ {
+ CPppAcp* acp = new (ELeave) CPppAcp(aLcp);
+ return acp;
+ }
+
+CPppAcp::CPppAcp(
+ CPppLcp* aLcp)
+ : MPppOptionHandler()
+/**
+Constructor, register the current instance as a handler
+for the authentication option type
+@param aLcp Parent LCP instance */
+ {
+ iPppLcp = aLcp;
+ OptRegister(aLcp, OptionList, KOptionListLen);
+ }
+
+CPppAcp::~CPppAcp()
+/**
+Destructor, deletes the protocol objects created by this instance */
+ {
+ DeleteProtocols();
+ }
+
+void CPppAcp::DeleteProtocols()
+/**
+Deletes the member protocol objects if valid. */
+ {
+ if (iServerProtocol)
+ {
+ delete iServerProtocol;
+ iServerProtocol = NULL;
+ }
+ if (iClientProtocol)
+ {
+ delete iClientProtocol;
+ iClientProtocol = NULL;
+ }
+ }
+
+void CPppAcp::OptNegotiationStarted()
+/**
+Initializes the option handler for a new LCP negotiation session */
+ {
+ DeleteProtocols();
+
+ iClientId = KPppIdUnknown;
+ iClientSubId = KPppIdUnknown;
+ iServerId = KPppIdUnknown;
+ iServerSubId = KPppIdUnknown;
+
+ iProtocolOffered = 0;
+ iCHAPTypeOffered = 0;
+
+ // default to fallback
+ }
+
+void CPppAcp::OptNegotiationAborted()
+/**
+Executed when the negotiation is aborted,
+resets the negotiable options */
+ {
+ iClientId = KPppIdUnknown;
+ iClientSubId = KPppIdUnknown;
+ iServerId = KPppIdUnknown;
+ iServerSubId = KPppIdUnknown;
+ }
+
+void CPppAcp::OptNegotiationComplete()
+/**
+Executed when the negotiation is finalized,
+creates the protocol objects according to the
+negotiated options */
+ {
+ TRAPD(ret,
+ switch (iClientId)
+ {
+ case KPppIdPap:
+ iClientProtocol = CPppPap::NewL();
+ break;
+
+ case KPppIdChap:
+ switch (iClientSubId)
+ {
+ case KPppChapMd5AlgorithmNumber:
+ iClientProtocol = CPppChapMd5::NewL();
+ break;
+
+ case KPppMsChapAlgorithmNumber:
+ iClientProtocol = CPppMsChap::NewL();
+ break;
+
+ case KPppMsChap2AlgorithmNumber:
+ iClientProtocol = CPppMsChap2::NewL();
+ break;
+ }
+ break;
+ }
+
+ if (iClientProtocol)
+ {
+ iClientProtocol->iFlags = KPppApIsClient;
+ if (iClientId==iServerId)
+ iClientProtocol->iFlags |= KPppApIsServer;
+ iClientProtocol->InitL(iPppLcp);
+ }
+
+ if (iClientId!=iServerId)
+ {
+ switch (iServerId)
+ {
+ case KPppIdPap:
+ iServerProtocol = CPppPap::NewL();
+ break;
+
+ case KPppIdChap:
+ switch (iServerSubId)
+ {
+ case KPppChapMd5AlgorithmNumber:
+ iServerProtocol = CPppChapMd5::NewL();
+ break;
+
+ case KPppMsChapAlgorithmNumber:
+ iServerProtocol = CPppMsChap::NewL();
+ break;
+
+ case KPppMsChap2AlgorithmNumber:
+ iServerProtocol = CPppMsChap2::NewL();
+ break;
+ }
+ break;
+ }
+
+ if (iServerProtocol)
+ {
+ iServerProtocol->iFlags = KPppApIsServer;
+ iServerProtocol->InitL(iPppLcp);
+ }
+ }
+ ); // TRAPD
+
+ if (ret!=KErrNone)
+ {
+ iPppLcp->PhaseAborted(ret);
+ return;
+ }
+ }
+
+void CPppAcp::OptFillinConfigRequestL(
+ RPppOptionList& /*aRequestList*/)
+/**
+Called when the LCP state machine prepares the initial
+configuration request. No authentication protocol is proposed
+here.
+@param aRequestList Not used */
+ {
+ // do not add anything to the list
+ }
+
+TPppOptResponse CPppAcp::ProposeChap(
+ RPppOption& aOption)
+/**
+Sets the option argument to CHAP and the next supported algorithm.
+The order of negotiation of PPP CHAP algorithms:
+
+MS-CHAP-V2
+MS-CHAP-V1
+CHAP with MD5
+
+When all algorithms were tried the method returns EPppOptReject.
+@param aOption Returns the updated option
+@return EPppOptNak if aOption contains valid info
+ EPppOptReject otherwise */
+ {
+ switch (iCHAPTypeOffered)
+ {
+ case 0:
+ iCHAPTypeOffered = KPppMsChap2AlgorithmNumber;
+ break;
+ case KPppMsChap2AlgorithmNumber:
+ iCHAPTypeOffered = KPppMsChapAlgorithmNumber;
+ break;
+ case KPppMsChapAlgorithmNumber:
+ iCHAPTypeOffered = KPppChapMd5AlgorithmNumber;
+ break;
+ case KPppChapMd5AlgorithmNumber:
+ default:
+ return EPppOptReject;
+ }
+
+ TUint8* p = aOption.ValuePtr();
+
+ BigEndian::Put16(p, (TUint16)KPppIdChap);
+
+ // There is a problem here due to using aOption as an input/output
+ // parameter if the size of the Data field in the
+ // Authentication-Protocol Configuration Option received in the
+ // aOption parameter is not large enough to allow suggesting CHAP
+ // (i.e. the size is of Data field is 0). This is outside the scope
+ // of the current work, so it is assumed here that RPppOption/RMBuf
+ // meets the requirements.
+ ASSERT(aOption.First()->Size() >=
+ KLCPConfigOptionTypeFieldSize +
+ KLCPConfigOptionLengthFieldSize +
+ KAuthenticationProtocolOptionFieldSize +
+ KChapAlgorithmFieldSize);
+
+ aOption.SetValueLength(
+ KAuthenticationProtocolOptionFieldSize +
+ KChapAlgorithmFieldSize);
+ p[2] = iCHAPTypeOffered;
+
+ return EPppOptNak;
+ }
+
+TPppOptResponse CPppAcp::ProposePap(
+ RPppOption& aOption)
+/**
+Sets the option argument to PAP.
+@param aOption Returns the updated option
+@return EPppOptNak if aOption contains valid info
+ EPppOptReject otherwise */
+ {
+ aOption.SetValueLength(KAuthenticationProtocolOptionFieldSize);
+
+ TUint8* p = aOption.ValuePtr();
+ BigEndian::Put16(p, (TUint16)KPppIdPap);
+
+ return EPppOptNak;
+ }
+
+TPppOptResponse CPppAcp::OptCheckConfigRequest(
+ RPppOption& aOption)
+/**
+Checks the specified authentication option. The currently supported
+authentication mode/protocol is specified in the CDMA_SIMIP_AUTH_ALGORITHM
+field in the packet service table (TCommDbCdmaSimpIpAuthAlgorithm enum).
+@param aOption Returns the updated option
+@return EPppOptAck if the proposed authentication option is accepted
+ EPppOptNak if the option is not accepted and another option is being proposed
+ EPppOptReject if the option is not accepted and no other option is proposed */
+ {
+ // MobileIP, Don't negotiate PAP or CHAP if CDMA MIP.
+ if (iPppLcp->QueryExternalIPConfiguration())
+ {
+ // Check if we must authenticate always, regardless of the mode.
+ // If the SERVICE_IF_EXTERN_IP_CONFIG_ALWAYS_REJECT_AUTH field is not in CommDB,
+ // doAlwaysAuthenticate remains EFalse.
+ }
+
+ TUint8* p = aOption.ValuePtr();
+
+ if (aOption.ValueLength() <
+ KAuthenticationProtocolOptionFieldSize)
+ return EPppOptReject;
+
+ // always return from every conditional branch of the following
+ switch (BigEndian::Get16(p))
+ {
+ case KPppIdPap:
+ if (aOption.ValueLength() !=
+ KAuthenticationProtocolOptionFieldSize)
+ {
+ // malformed PAP Authentication-Protocol Option - reject
+ return EPppOptReject;
+ }
+ break;
+ case KPppIdChap:
+ if (aOption.ValueLength() !=
+ KAuthenticationProtocolOptionFieldSize +
+ KChapAlgorithmFieldSize)
+ {
+ // malformed CHAP Authentication-Protocol Option - reject
+ return EPppOptReject;
+ }
+ break;
+ default:
+ // unrecognized authentication protocol
+
+ break;
+ }
+ #ifndef SYMBIAN_EXCLUDE_CDMA
+ return TPppOptResponse();
+ #endif
+ }
+
+void CPppAcp::OptApplyConfigRequest(
+ RPppOption& aOption)
+/**
+The specified configuration option from the server config request
+has been accepted, the negotiation result is stored.
+@param aOption Accepted authentication option */
+ {
+ iClientId = BigEndian::Get16(aOption.ValuePtr());
+ TInt n = aOption.ValueLength()-2;
+ if (n>0)
+ iClientSubId = *(aOption.ValuePtr()+2);
+ }
+
+void CPppAcp::OptRecvConfigAck(
+ RPppOption& aOption)
+/**
+The specified configuration option has been acked by the server,
+the negotiation result is stored.
+@param aOption Acked authentication option */
+ {
+ iServerId = BigEndian::Get16(aOption.ValuePtr());
+ TInt n = aOption.ValueLength()-2;
+ if (n>0)
+ iServerSubId = *(aOption.ValuePtr()+2);
+ }
+
+void CPppAcp::OptRecvConfigNak(
+ RPppOption& aOption,
+ RPppOptionList& aReqList)
+/**
+The specified configuration option has been nacked by the server,
+the option is replaced in the option list
+@param aOption Nacked authentication option
+@param aReqList List to be updated */
+ {
+ aReqList.ReplaceOption(aOption);
+ }
+
+void CPppAcp::OptRecvConfigReject(
+ RPppOption& aOption,
+ RPppOptionList& aReqList)
+/**
+The specified configuration option has been rejected by the server,
+the option is removed from the option list
+@param aOption Rejected authentication option
+@param aReqList List to be updated */
+ {
+ aReqList.RemoveOption(aOption);
+ }