linklayerprotocols/pppnif/SPPP/PPPAUTH.CPP
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 #include <in_iface.h>
       
    18 #include "PPPAUTH.H"
       
    19 
       
    20 #include "ppppap.h"
       
    21 #include "chapmd5.h"
       
    22 #include "MSCHAP.H"
       
    23 #include "mschap2.h"
       
    24 #include <commsdattypeinfov1_1.h>
       
    25 #include "PPPConfig.h"
       
    26 
       
    27 #if defined(_DEBUG)
       
    28 const TInt KLCPConfigOptionTypeFieldSize = 1;
       
    29 const TInt KLCPConfigOptionLengthFieldSize = 1;
       
    30 #endif
       
    31 const TInt KAuthenticationProtocolOptionFieldSize = 2;
       
    32 const TInt KChapAlgorithmFieldSize = 1;
       
    33 
       
    34 
       
    35 //
       
    36 
       
    37 void CPppAuthentication::InitL(
       
    38 	CPppLcp* aPppLcp)
       
    39 /**
       
    40 Initializes the authentication protocol.
       
    41 @param aPppLcp Parent LCP instance
       
    42 @leave The method does not leave */			
       
    43 	{
       
    44 	MPppRecvr::Init(aPppLcp, PppPhase(), PppId());
       
    45 	}
       
    46 
       
    47 CPppAuthentication::~CPppAuthentication()
       
    48 /**
       
    49 Destructor, generates a CancelAuthenticate notification to the 
       
    50 parent LCP instance */			
       
    51 	{
       
    52 	if (iPppLcp != 0)
       
    53 		iPppLcp->CancelAuthenticate(this);
       
    54 	}
       
    55 
       
    56 void CPppAuthentication::AuthenticateRequest()
       
    57 /**
       
    58 Generates an Authenticate notification to the parent LCP instance */			
       
    59 	{
       
    60 	ASSERT(iPppLcp != 0);
       
    61 	iPppLcp->Authenticate(this);
       
    62 	}
       
    63 
       
    64 void CPppAuthentication::CallAuthenticateComplete(
       
    65 	TInt aRes)
       
    66 /**
       
    67 Notifies the derived class that the LCP authentication is completed
       
    68 @param aRes Code describing the authentication result 
       
    69 	(KErrNone: authentication OK) */			
       
    70 	{
       
    71 	ASSERT(iPppLcp != 0);
       
    72 	iFlags |= KPppApAuthReqDone;
       
    73 	AuthenticateComplete(aRes);
       
    74 	}
       
    75 
       
    76 void CPppAuthentication::DoFail(
       
    77 	TInt aErrorCode)
       
    78 /**
       
    79 Notifies the parent LCP instance of an error encountered 
       
    80 during authentication
       
    81 @param aErrorCode Describes the authentication failure */			
       
    82 	{
       
    83 	ASSERT(iPppLcp != 0);
       
    84 	iPppLcp->Progress(EPppProgressAuthenticationComplete, aErrorCode);
       
    85 	iPppLcp->PhaseAborted(aErrorCode);
       
    86 	}
       
    87 
       
    88 
       
    89 void CPppAuthentication::DoSucceed()
       
    90 /**
       
    91 Notifies the parent LCP instance that the 
       
    92 authentication phase completed successfully */			
       
    93 	{
       
    94 	ASSERT(iPppLcp != 0);
       
    95 
       
    96 	iPppLcp->Progress(EPppProgressAuthenticationComplete, KErrNone);
       
    97 	iPppLcp->PhaseComplete();
       
    98 	}
       
    99 
       
   100 
       
   101 //
       
   102 
       
   103 static const TInt KOptionListLen = 1;
       
   104 static const TUint8 OptionList[KOptionListLen] =
       
   105 	{
       
   106 	KPppLcpOptAuthenticationProtocol
       
   107 	};
       
   108 			
       
   109 CPppAcp* CPppAcp::NewL(
       
   110 	CPppLcp* aLcp)
       
   111 /**
       
   112 Creates a new CPppAcp instance
       
   113 @param aLcp Parent LCP instance
       
   114 @return Newly created CPppAcp instance */		
       
   115 	{
       
   116 	CPppAcp* acp = new (ELeave) CPppAcp(aLcp);
       
   117 	return acp;
       
   118 	}
       
   119 
       
   120 CPppAcp::CPppAcp(
       
   121 	CPppLcp* aLcp)
       
   122 	: MPppOptionHandler()
       
   123 /**
       
   124 Constructor, register the current instance as a handler 
       
   125 for the authentication option type
       
   126 @param aLcp Parent LCP instance */		
       
   127 	{
       
   128 	iPppLcp = aLcp;
       
   129 	OptRegister(aLcp, OptionList, KOptionListLen);
       
   130 	}
       
   131 
       
   132 CPppAcp::~CPppAcp()
       
   133 /**
       
   134 Destructor, deletes the protocol objects created by this instance */		
       
   135 	{
       
   136 	DeleteProtocols();
       
   137 	}
       
   138 
       
   139 void CPppAcp::DeleteProtocols()
       
   140 /**
       
   141 Deletes the member protocol objects if valid. */		
       
   142 	{
       
   143 	if (iServerProtocol)
       
   144 		{
       
   145 		delete iServerProtocol;
       
   146 		iServerProtocol = NULL;
       
   147 		}
       
   148 	if (iClientProtocol)
       
   149 		{
       
   150 		delete iClientProtocol;
       
   151 		iClientProtocol = NULL;
       
   152 		}
       
   153 	}
       
   154 	
       
   155 void CPppAcp::OptNegotiationStarted()
       
   156 /**
       
   157 Initializes the option handler for a new LCP negotiation session */		
       
   158 	{
       
   159 	DeleteProtocols();
       
   160 		
       
   161 	iClientId = KPppIdUnknown;
       
   162 	iClientSubId = KPppIdUnknown;
       
   163 	iServerId = KPppIdUnknown;
       
   164 	iServerSubId = KPppIdUnknown;
       
   165 
       
   166 	iProtocolOffered = 0;
       
   167 	iCHAPTypeOffered = 0;
       
   168 	
       
   169 	// default to fallback
       
   170 	}
       
   171 
       
   172 void CPppAcp::OptNegotiationAborted()
       
   173 /**
       
   174 Executed when the negotiation is aborted, 
       
   175 resets the negotiable options */		
       
   176 	{
       
   177 	iClientId = KPppIdUnknown;
       
   178 	iClientSubId = KPppIdUnknown;
       
   179 	iServerId = KPppIdUnknown;
       
   180 	iServerSubId = KPppIdUnknown;
       
   181 	}
       
   182 
       
   183 void CPppAcp::OptNegotiationComplete()
       
   184 /**
       
   185 Executed when the negotiation is finalized, 
       
   186 creates the protocol objects according to the 
       
   187 negotiated options */		
       
   188 	{
       
   189 	TRAPD(ret, 
       
   190 	 switch (iClientId)
       
   191 		 {
       
   192 	 case KPppIdPap:
       
   193 		 iClientProtocol = CPppPap::NewL();
       
   194 		 break;
       
   195 
       
   196 	 case KPppIdChap:
       
   197 		 switch (iClientSubId)
       
   198 			 {
       
   199 		 case KPppChapMd5AlgorithmNumber:
       
   200 			 iClientProtocol = CPppChapMd5::NewL();
       
   201 			 break;
       
   202 
       
   203 		 case KPppMsChapAlgorithmNumber:
       
   204 			 iClientProtocol = CPppMsChap::NewL();
       
   205 			 break;
       
   206 
       
   207 		 case KPppMsChap2AlgorithmNumber:
       
   208 			 iClientProtocol = CPppMsChap2::NewL();
       
   209 			 break;
       
   210 			 }
       
   211 		 break;
       
   212 		 }
       
   213 
       
   214 	 if (iClientProtocol)
       
   215 		 {
       
   216 		 iClientProtocol->iFlags = KPppApIsClient;
       
   217 		 if (iClientId==iServerId)
       
   218 			 iClientProtocol->iFlags |= KPppApIsServer;
       
   219 		 iClientProtocol->InitL(iPppLcp);
       
   220 		 }
       
   221 
       
   222 	 if (iClientId!=iServerId)
       
   223 		 {
       
   224 		 switch (iServerId)
       
   225 			 {
       
   226 		 case KPppIdPap:
       
   227 			 iServerProtocol = CPppPap::NewL();
       
   228 			 break;
       
   229 
       
   230 		 case KPppIdChap:
       
   231 			 switch (iServerSubId)
       
   232 				 {
       
   233 			 case KPppChapMd5AlgorithmNumber:
       
   234 				 iServerProtocol = CPppChapMd5::NewL();
       
   235 				 break;
       
   236 
       
   237 			 case KPppMsChapAlgorithmNumber:
       
   238 				 iServerProtocol = CPppMsChap::NewL();
       
   239 				 break;
       
   240 
       
   241 			 case KPppMsChap2AlgorithmNumber:
       
   242 				 iServerProtocol = CPppMsChap2::NewL();
       
   243 				 break;
       
   244 				 }
       
   245 			 break;
       
   246 			 }
       
   247 
       
   248 		 if (iServerProtocol)
       
   249 			 {
       
   250 			 iServerProtocol->iFlags = KPppApIsServer;
       
   251 			 iServerProtocol->InitL(iPppLcp);
       
   252 			 }
       
   253 		 }
       
   254 		); // TRAPD
       
   255 
       
   256 	if (ret!=KErrNone)
       
   257 		{
       
   258 		iPppLcp->PhaseAborted(ret);
       
   259 		return;
       
   260 		}
       
   261 	}
       
   262 
       
   263 void CPppAcp::OptFillinConfigRequestL(
       
   264 	RPppOptionList& /*aRequestList*/)
       
   265 /**
       
   266 Called when the LCP state machine prepares the initial 
       
   267 configuration request. No authentication protocol is proposed
       
   268 here.
       
   269 @param aRequestList Not used */	
       
   270 	{
       
   271 	// do not add anything to the list
       
   272 	}
       
   273 	
       
   274 TPppOptResponse CPppAcp::ProposeChap(
       
   275 	RPppOption& aOption)
       
   276 /**
       
   277 Sets the option argument to CHAP and the next supported algorithm. 
       
   278 The order of negotiation of PPP CHAP algorithms:
       
   279 
       
   280 MS-CHAP-V2
       
   281 MS-CHAP-V1
       
   282 CHAP with MD5
       
   283 
       
   284 When all algorithms were tried the method returns EPppOptReject.
       
   285 @param aOption Returns the updated option
       
   286 @return EPppOptNak if aOption contains valid info 
       
   287 		EPppOptReject otherwise */	
       
   288 	{
       
   289 	switch (iCHAPTypeOffered)
       
   290 		{
       
   291 	case 0:
       
   292 		iCHAPTypeOffered = KPppMsChap2AlgorithmNumber;
       
   293 		break;			
       
   294 	case KPppMsChap2AlgorithmNumber:
       
   295 		iCHAPTypeOffered = KPppMsChapAlgorithmNumber;
       
   296 		break;			
       
   297 	case KPppMsChapAlgorithmNumber:
       
   298 		iCHAPTypeOffered = KPppChapMd5AlgorithmNumber;
       
   299 		break;
       
   300 	case KPppChapMd5AlgorithmNumber:			
       
   301 	default:
       
   302 		return EPppOptReject;
       
   303 		}
       
   304 		
       
   305 	TUint8* p = aOption.ValuePtr();
       
   306 	
       
   307 	BigEndian::Put16(p, (TUint16)KPppIdChap);
       
   308 
       
   309 	// There is a problem here due to using aOption as an input/output
       
   310 	// parameter if the size of the Data field in the
       
   311 	// Authentication-Protocol Configuration Option received in the
       
   312 	// aOption parameter is not large enough to allow suggesting CHAP
       
   313 	// (i.e. the size is of Data field is 0).  This is outside the scope
       
   314 	// of the current work, so it is assumed here that RPppOption/RMBuf
       
   315 	// meets the requirements.
       
   316 	ASSERT(aOption.First()->Size() >= 
       
   317 				KLCPConfigOptionTypeFieldSize +
       
   318 				KLCPConfigOptionLengthFieldSize +
       
   319 				KAuthenticationProtocolOptionFieldSize + 
       
   320 				KChapAlgorithmFieldSize);
       
   321 
       
   322 	aOption.SetValueLength(
       
   323 		KAuthenticationProtocolOptionFieldSize + 
       
   324 		KChapAlgorithmFieldSize);
       
   325 	p[2] = iCHAPTypeOffered;
       
   326 		
       
   327 	return EPppOptNak;		
       
   328 	}		
       
   329 		
       
   330 TPppOptResponse CPppAcp::ProposePap(
       
   331 	RPppOption& aOption)
       
   332 /**
       
   333 Sets the option argument to PAP. 
       
   334 @param aOption Returns the updated option
       
   335 @return EPppOptNak if aOption contains valid info 
       
   336 		EPppOptReject otherwise */	
       
   337 	{
       
   338 	aOption.SetValueLength(KAuthenticationProtocolOptionFieldSize);
       
   339 
       
   340 	TUint8* p = aOption.ValuePtr();
       
   341 	BigEndian::Put16(p, (TUint16)KPppIdPap);
       
   342 
       
   343 	return EPppOptNak;
       
   344 	}	
       
   345 
       
   346 TPppOptResponse CPppAcp::OptCheckConfigRequest(
       
   347 	RPppOption& aOption)
       
   348 /**
       
   349 Checks the specified authentication option. The currently supported 
       
   350 authentication mode/protocol is specified in the CDMA_SIMIP_AUTH_ALGORITHM
       
   351 field in the packet service table (TCommDbCdmaSimpIpAuthAlgorithm enum).
       
   352 @param aOption Returns the updated option
       
   353 @return EPppOptAck if the proposed authentication option is accepted
       
   354 		EPppOptNak if the option is not accepted and another option is being proposed
       
   355 		EPppOptReject if the option is not accepted and no other option is proposed */	
       
   356 	{	
       
   357 	// MobileIP, Don't negotiate PAP or CHAP if CDMA MIP.
       
   358 	if (iPppLcp->QueryExternalIPConfiguration())
       
   359 		{
       
   360 		// Check if we must authenticate always, regardless of the mode.
       
   361 		// If the SERVICE_IF_EXTERN_IP_CONFIG_ALWAYS_REJECT_AUTH field is not in CommDB, 
       
   362 		// doAlwaysAuthenticate remains EFalse.
       
   363 		}
       
   364 
       
   365 	TUint8* p = aOption.ValuePtr();
       
   366 	
       
   367 	if (aOption.ValueLength() < 
       
   368 		KAuthenticationProtocolOptionFieldSize)
       
   369 		return EPppOptReject;
       
   370 
       
   371 	// always return from every conditional branch of the following
       
   372 	switch (BigEndian::Get16(p))
       
   373 		{
       
   374 	case KPppIdPap:
       
   375 	    if (aOption.ValueLength() !=
       
   376 	        KAuthenticationProtocolOptionFieldSize)
       
   377 	        {      
       
   378             // malformed PAP Authentication-Protocol Option - reject
       
   379             return EPppOptReject;
       
   380             }
       
   381 	    break;
       
   382 	case KPppIdChap:
       
   383 		if (aOption.ValueLength() != 
       
   384 			KAuthenticationProtocolOptionFieldSize + 
       
   385 			KChapAlgorithmFieldSize)
       
   386 			{		
       
   387 			// malformed CHAP Authentication-Protocol Option - reject
       
   388 			return EPppOptReject;
       
   389 			}
       
   390             break;
       
   391 	default:
       
   392 		// unrecognized authentication protocol
       
   393 
       
   394 		break;
       
   395 		}
       
   396 	#ifndef SYMBIAN_EXCLUDE_CDMA
       
   397 		return TPppOptResponse();
       
   398 	#endif				
       
   399 	}
       
   400 
       
   401 void CPppAcp::OptApplyConfigRequest(
       
   402 	RPppOption& aOption)
       
   403 /**
       
   404 The specified configuration option from the server config request
       
   405 has been accepted, the negotiation result is stored.
       
   406 @param aOption Accepted authentication option */	
       
   407 	{
       
   408 	iClientId = BigEndian::Get16(aOption.ValuePtr());
       
   409 	TInt n = aOption.ValueLength()-2;
       
   410 	if (n>0)
       
   411 		iClientSubId = *(aOption.ValuePtr()+2);
       
   412 	}
       
   413 
       
   414 void CPppAcp::OptRecvConfigAck(
       
   415 	RPppOption& aOption)
       
   416 /**
       
   417 The specified configuration option has been acked by the server, 
       
   418 the negotiation result is stored.
       
   419 @param aOption Acked authentication option */
       
   420 	{
       
   421 	iServerId = BigEndian::Get16(aOption.ValuePtr());
       
   422 	TInt n = aOption.ValueLength()-2;
       
   423 	if (n>0)
       
   424 		iServerSubId = *(aOption.ValuePtr()+2);
       
   425 	}
       
   426 
       
   427 void CPppAcp::OptRecvConfigNak(
       
   428 	RPppOption& aOption, 
       
   429 	RPppOptionList& aReqList)
       
   430 /**
       
   431 The specified configuration option has been nacked by the server,
       
   432 the option is replaced in the option list
       
   433 @param aOption Nacked authentication option 
       
   434 @param aReqList List to be updated */	
       
   435 	{
       
   436 	aReqList.ReplaceOption(aOption);
       
   437 	}
       
   438 
       
   439 void CPppAcp::OptRecvConfigReject(
       
   440 	RPppOption& aOption, 
       
   441 	RPppOptionList& aReqList)
       
   442 /**
       
   443 The specified configuration option has been rejected by the server,
       
   444 the option is removed from the option list
       
   445 @param aOption Rejected authentication option 
       
   446 @param aReqList List to be updated */	
       
   447 	{
       
   448 	aReqList.RemoveOption(aOption);
       
   449 	}