|
1 /* |
|
2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: IKE transaction exchange implementation. |
|
15 * |
|
16 */ |
|
17 |
|
18 /**------------------------------------------------------------------- |
|
19 * |
|
20 * Class CTransNegotiation |
|
21 * This class is used to handle ISAKMP Transaction exchange messages. |
|
22 * Transaction exchange has been defined in the IETF draft which specifies |
|
23 * The ISAKMP Configuration Method <draft-dukes-ike-mode-cfg-01.txt>. |
|
24 * This same two message configuration transaction is also used in IETF draft |
|
25 * Extended Authentication within IKE (XAUTH) <draft-beaulieu-ike-xauth-02.txt>. |
|
26 * CTransNegotiation class implements these IETF drafts, too. |
|
27 * |
|
28 *--------------------------------------------------------------------*/ |
|
29 |
|
30 #include "ikev1trans.h" |
|
31 #include "ikedebug.h" |
|
32 #include "ikev1pluginsession.h" |
|
33 #include "ikev1negotiation.h" |
|
34 #include "ikev1payload.h" |
|
35 #include "ikev1timeout.h" |
|
36 #include "ikev1crack.h" |
|
37 #include "ikev1isakmpstream.h" |
|
38 #include "ikev1crypto.h" |
|
39 |
|
40 const TUint8 XAUTH_VID_DATA[8] = {0x09, 0x00, 0x26, 0x89, 0xdf, 0xd6, 0xb7, 0x12}; |
|
41 const TUint8 CISCO_UNITY_VID_DATA[16] = {0x12, 0xf5, 0xf2, 0x8c, 0x45, 0x71, 0x68, 0xa9, |
|
42 0x70, 0x2d, 0x9f, 0xe2, 0x74, 0xcc, 0x01, 0x00}; |
|
43 |
|
44 |
|
45 CTransNegotiation::CTransNegotiation( TInt aGranularity, |
|
46 TBool aUseXauth, |
|
47 TBool aUseCfgMode, |
|
48 CIkev1PluginSession* aPluginSession, |
|
49 CIkev1Negotiation* aNegotiation, |
|
50 MIkeDebug& aDebug ) |
|
51 :CArrayFixFlat<TTransExchange*>(aGranularity), |
|
52 iPluginSession(aPluginSession), |
|
53 iNegotiation(aNegotiation), |
|
54 iUseXauth(aUseXauth), |
|
55 iUseCfgMode(aUseCfgMode), |
|
56 iDebug(aDebug) |
|
57 { |
|
58 } |
|
59 |
|
60 |
|
61 /**------------------------------------------------------------------- |
|
62 * |
|
63 * Method New() |
|
64 * Creates an instance of CTransNegotiation class if either |
|
65 * usage of XAUTH or CFG-MODE has been requested. |
|
66 * |
|
67 *--------------------------------------------------------------------*/ |
|
68 CTransNegotiation* CTransNegotiation::NewL(TBool aUseXauth, TBool aUseCfgMode, |
|
69 CIkev1PluginSession* aPluginSession, |
|
70 CIkev1Negotiation* aNegotiation, |
|
71 MIkeDebug& aDebug ) |
|
72 { |
|
73 CTransNegotiation* Neg = new (ELeave) CTransNegotiation( 1, |
|
74 aUseXauth, |
|
75 aUseCfgMode, |
|
76 aPluginSession, |
|
77 aNegotiation, |
|
78 aDebug ); |
|
79 CleanupStack::PushL(Neg); |
|
80 Neg->ConstructL(); |
|
81 CleanupStack::Pop(Neg); |
|
82 return Neg; |
|
83 } |
|
84 /**------------------------------------------------------------------- |
|
85 * |
|
86 * Deconstruct method |
|
87 * |
|
88 *--------------------------------------------------------------------*/ |
|
89 CTransNegotiation::~CTransNegotiation() |
|
90 { |
|
91 DEBUG_LOG(_L("Transaction exchange object deleted")); |
|
92 |
|
93 delete iInternalAddr; |
|
94 delete iDialog; |
|
95 delete iDialogInfo; |
|
96 delete iUserName; |
|
97 |
|
98 for ( TInt i = 0; i < Count(); i++ ) |
|
99 { |
|
100 delete At(i); |
|
101 } |
|
102 } |
|
103 |
|
104 /**------------------------------------------------------------------- |
|
105 * |
|
106 * Method ConstructL() |
|
107 * -- Links CKmdEngine- and CNegotiation object pointers to CTransNegotiation |
|
108 * -- If only CONFIG-MODE requested, start corresponding transaction exchange. |
|
109 * |
|
110 *--------------------------------------------------------------------*/ |
|
111 void CTransNegotiation::ConstructL() |
|
112 { |
|
113 if ( !iPluginSession || !iNegotiation || (!iUseXauth && !iUseCfgMode)) |
|
114 { |
|
115 User::Leave(KErrArgument); |
|
116 } |
|
117 |
|
118 DEBUG_LOG(_L("Transaction exchange object constructed")); |
|
119 if ( !iUseXauth ) |
|
120 { |
|
121 iXauthCompleted = ETrue; |
|
122 iNegotiation->iTimer->Cancel(); // Stop retransmission timer |
|
123 } |
|
124 else |
|
125 { |
|
126 if ( !iUseCfgMode ) |
|
127 iCfgModeCompleted = ETrue; |
|
128 DEBUG_LOG(_L("Starting to Wait XAUTH request")); |
|
129 } |
|
130 } |
|
131 |
|
132 /**------------------------------------------------------------------- |
|
133 * |
|
134 * Method GetAuthMethod() |
|
135 * This static method converts the authentication method value from |
|
136 * "normal" IKE attribute value (specified in RFC2409) to the attribute |
|
137 * value indicate XAUTH usage after IKE phase 1. This conversion is done |
|
138 * into the opposite direction when call parameter (aAuthMethod) have |
|
139 * already value indicating Xauth usage. |
|
140 * |
|
141 *--------------------------------------------------------------------*/ |
|
142 TUint16 CTransNegotiation::GetAuthMethod(TUint16 aAuthMethod, TBool aXauthUsed, TInt aRole) |
|
143 { |
|
144 if ( aXauthUsed ) { |
|
145 if ( aAuthMethod >= XAUTHInitPreShared && aAuthMethod <= XAUTHRespRSARevisedEncr) { |
|
146 aAuthMethod -= XAUTHMethodBase; |
|
147 aAuthMethod = (TUint16)((aAuthMethod >> XAUTHScaler) | XAUTHScaler); |
|
148 } |
|
149 else { |
|
150 if ( aAuthMethod >= PRE_SHARED && aAuthMethod <= RSA_REV_ENCR ) { |
|
151 aAuthMethod = (TUint16)((aAuthMethod << XAUTHScaler) + XAUTHMethodBase); |
|
152 if ( aRole == INITIATOR ) |
|
153 aAuthMethod -= XAUTHScaler; |
|
154 } |
|
155 } |
|
156 } |
|
157 return aAuthMethod; |
|
158 } |
|
159 |
|
160 /**------------------------------------------------------------------- |
|
161 * |
|
162 * Method BuildXauthVendorId() |
|
163 * This method builds a XAUTH related Vendor ID payload and adds it into |
|
164 * the IKE message. The vendor id is specified in the draft |
|
165 * <draft-beaulieu-ike-xauth-02.txt> and its content is the following: |
|
166 * ["0x09002689DFD6B712"]) |
|
167 * Both ISAKMP mode-cfg and extended authentication (XAUTH) can be |
|
168 * implemented in some VPN SGWs according to the older mode-cfg and |
|
169 * xauth drafts: |
|
170 * <draft-ietf-ipsec-isakmp-mode-cfg-04.txt> and |
|
171 * <draft-ietf-ipsec-isakmp-xauth-04.txt> |
|
172 * |
|
173 *--------------------------------------------------------------------*/ |
|
174 void CTransNegotiation::BuildXauthVendorId(TIkev1IsakmpStream &aMsg) |
|
175 { |
|
176 TInetAddr DummyAddr; |
|
177 |
|
178 aMsg.IsakmpVendorId(IETF_NATT_VENDOR_ID, |
|
179 NULL, NULL, DummyAddr, // These parameters has no relevance with IETF_NATT_VID_DATA |
|
180 (TUint8*)XAUTH_VID_DATA, sizeof(XAUTH_VID_DATA)); |
|
181 |
|
182 aMsg.IsakmpVendorId(IETF_NATT_VENDOR_ID, |
|
183 NULL, NULL, DummyAddr, // These parameters has no relevance with IETF_NATT_VID_DATA |
|
184 (TUint8*)CISCO_UNITY_VID_DATA, |
|
185 sizeof(CISCO_UNITY_VID_DATA)); |
|
186 } |
|
187 |
|
188 /**------------------------------------------------------------------- |
|
189 * |
|
190 * Method GetIV() |
|
191 * Get IV for transaction exchange specified with message id parameter: |
|
192 * Find corresponding exchange structure and copy IV to caller |
|
193 * If no exchange found, return EFALSE status to indicate error. |
|
194 * |
|
195 *--------------------------------------------------------------------*/ |
|
196 TBool CTransNegotiation::GetIV(TUint32 aMsgId, TDes8& aIV) |
|
197 { |
|
198 TBool status = ETrue; |
|
199 TTransExchange *exchange = FindExchange(aMsgId); |
|
200 if ( exchange ) |
|
201 aIV.Copy(exchange->iIV); |
|
202 else status = EFalse; |
|
203 |
|
204 return status; |
|
205 } |
|
206 |
|
207 /**------------------------------------------------------------------- |
|
208 * |
|
209 * Method SetIV() |
|
210 * Set IV for transaction exchange specified with message id parameter: |
|
211 * Find corresponding exchange structure and store specified IV to |
|
212 * exchange structure |
|
213 * If no exchange found, return EFALSE status to indicate error. |
|
214 * |
|
215 *--------------------------------------------------------------------*/ |
|
216 TBool CTransNegotiation::SetIV(TUint32 aMsgId, TDes8& aIV) |
|
217 { |
|
218 TBool status = ETrue; |
|
219 TTransExchange *exchange = FindExchange(aMsgId); |
|
220 if ( exchange ) |
|
221 exchange->iIV.Copy(aIV); |
|
222 else status = EFalse; |
|
223 |
|
224 return status; |
|
225 } |
|
226 |
|
227 /**------------------------------------------------------------------- |
|
228 * |
|
229 * Method ProcessUserResponseL() |
|
230 * ProcessUserResponseL() builds a XAUTH reply message from authentication |
|
231 * credentials linked into the current CAuthDialogInfo object. |
|
232 * |
|
233 *--------------------------------------------------------------------*/ |
|
234 TInt CTransNegotiation::ProcessUserResponseL(CAuthDialogInfo *aDialogInfo ) |
|
235 { |
|
236 // |
|
237 // Find a transaction exchange structure for current message |
|
238 // |
|
239 TInt lth = 0; |
|
240 iCurrExchange = FindExchange(aDialogInfo->GetMsgId()); |
|
241 |
|
242 if ( iCurrExchange && iRequestFlags ) { |
|
243 // |
|
244 // Allocate a buffer for Attribute payload. |
|
245 // Calculate first required buffer length |
|
246 // |
|
247 if ( aDialogInfo->iUsername ) |
|
248 lth += (aDialogInfo->iUsername->Length() + 4); |
|
249 if ( aDialogInfo->iSecret ) |
|
250 lth += (aDialogInfo->iSecret->Length() + 4); |
|
251 |
|
252 HBufC8 *attributes = HBufC8::NewL(lth + 4); |
|
253 CleanupStack::PushL(attributes); |
|
254 TPtr8 attr_ptr(attributes->Des()); |
|
255 TUint16 AttrType; |
|
256 |
|
257 if ( iRequestFlags & (1 << (ATTR_PASSWORD - ATTR_XAUTH_TYPE)) ) { |
|
258 // |
|
259 // Add Xauth type attribute. Value is taken from current exchange structure |
|
260 // |
|
261 if ( iUseOlderPIXXauth ) |
|
262 AttrType = ATTR_PIX_XAUTH_TYPE; |
|
263 else AttrType = ATTR_XAUTH_TYPE; |
|
264 AddAttributeData(attr_ptr, AttrType, 2, (TUint8*)&iCurrExchange->iXauthType); |
|
265 } |
|
266 |
|
267 if ( aDialogInfo->iUsername ) { |
|
268 // |
|
269 // Add user name attribute. |
|
270 // |
|
271 if ( iUseOlderPIXXauth ) |
|
272 AttrType = ATTR_PIX_USER_NAME; |
|
273 else AttrType = ATTR_USER_NAME; |
|
274 |
|
275 AddAttributeData(attr_ptr, AttrType, aDialogInfo->iUsername->Length(), |
|
276 (TUint8*)aDialogInfo->iUsername->Ptr()); |
|
277 // |
|
278 // Take a copy of user name buffer in dialog info. This user name |
|
279 // is cached into user name file if current CRACK negotiation is |
|
280 // succeeded |
|
281 // |
|
282 delete iUserName; // Delete old user name buffer for sure |
|
283 iUserName = HBufC8::New(aDialogInfo->iUsername->Length() + 16); // 16 bytes space for padding |
|
284 if ( iUserName ) { |
|
285 iUserName->Des().Copy(aDialogInfo->iUsername->Des()); |
|
286 } |
|
287 } |
|
288 |
|
289 if ( aDialogInfo->iSecret ) { |
|
290 // |
|
291 // Add either password, passcode or next pin attribute. |
|
292 // Check from iRequestFlags which one was requested by the gateway |
|
293 // |
|
294 if ( iUseOlderPIXXauth ) |
|
295 AttrType = ATTR_PIX_PASSWORD; // default; |
|
296 else AttrType = ATTR_PASSWORD; // default |
|
297 |
|
298 switch ( iRequestFlags ) { |
|
299 |
|
300 case (1 << (ATTR_PASSCODE - ATTR_XAUTH_TYPE)): |
|
301 if ( iUseOlderPIXXauth ) |
|
302 AttrType = ATTR_PIX_PASSCODE; |
|
303 else AttrType = ATTR_PASSCODE; |
|
304 break; |
|
305 |
|
306 case (1 << (ATTR_NEXT_PIN - ATTR_XAUTH_TYPE)): |
|
307 AttrType = ATTR_NEXT_PIN; |
|
308 break; |
|
309 |
|
310 default: |
|
311 break; |
|
312 |
|
313 } |
|
314 AddAttributeData(attr_ptr, AttrType, aDialogInfo->iSecret->Length(), |
|
315 (TUint8*)aDialogInfo->iSecret->Ptr()); |
|
316 } |
|
317 |
|
318 BuildAndSendMessageL(attr_ptr, ISAKMP_CFG_REPLY); |
|
319 |
|
320 CleanupStack::PopAndDestroy(); //attributes |
|
321 |
|
322 iRequestFlags = 0; |
|
323 |
|
324 } |
|
325 |
|
326 delete iDialog; // delete dialog object |
|
327 delete aDialogInfo; // release dialog info object |
|
328 iDialog = NULL; |
|
329 iDialogInfo = NULL; |
|
330 |
|
331 return TRANSACTION_CONTINUE; |
|
332 } |
|
333 |
|
334 /**------------------------------------------------------------------- |
|
335 * |
|
336 * Method TransactionFailedL() |
|
337 * TransactionFailedL() is called when a notificatio/delete payload |
|
338 * has been received in the middle of a transaction exchange. |
|
339 * |
|
340 *--------------------------------------------------------------------*/ |
|
341 TInt CTransNegotiation::TransactionFailedL(const TNotificationISAKMP *aNotifPayload) |
|
342 { |
|
343 |
|
344 (void)aNotifPayload; |
|
345 iNegotiation->iTimer->Cancel(); //Cancel timer because authentication failed |
|
346 DEBUG_LOG(_L("Transaction exchange stopped by the gateway!")); |
|
347 // |
|
348 // Dialog object shall be delete in Dialog->RunL when dialog completed |
|
349 // |
|
350 CIkev1Dialog* Dialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); |
|
351 Dialog->ShowErrorDialogL(TVpnNoteDialog::EKmdAuthenticationFailed, NULL, NULL); |
|
352 |
|
353 return TRANSACTION_FAILED; |
|
354 } |
|
355 |
|
356 /**------------------------------------------------------------------- |
|
357 * |
|
358 * Method ExecuteL() |
|
359 * Processes a received ISAKMP transaction exchange message. |
|
360 * The received message MUST be an encrypted transaction exchange message |
|
361 * otherwise it is silently discarded. |
|
362 * Current TTransExchange structure is found, IV value calculated and |
|
363 * ISAKMP message decrypted. |
|
364 * TransactionExchangeL() method returns to the caller the following status codes: |
|
365 * (Corresponding CRACK status codes defined in ike_crack.h) |
|
366 * -- TRANSACTION_SUCCESS (0) = |
|
367 * Transaction exchange(s) has been succesfully completed. |
|
368 * Normal operation can continue and CTransNegotiation object can be deleted. |
|
369 * -- TRANSACTION_CONTINUE (1) = |
|
370 * Received message succesfully processed. |
|
371 * Transaction exchange(s) shall still continue. |
|
372 * -- TRANSACTION_IGNORE (2) = |
|
373 * Received message ignored. Transaction exchange(s) shall still continue. |
|
374 * -- TRANSACTION_FAILED (4) = |
|
375 * Transaction exchange(s) has been failed (either CONFIG-MODE or XAUTH). |
|
376 * Current CNegotiation object as well as CTransNegotiation object can |
|
377 * be deleted. (= corresponding ISAKMP phase 1 negotiation shall be deleted). |
|
378 * |
|
379 *--------------------------------------------------------------------*/ |
|
380 #ifdef _DEBUG |
|
381 TInt CTransNegotiation::ExecuteL( const ThdrISAKMP& aHdr, |
|
382 const TInetAddr& aSrcAddr, |
|
383 TInt aLocalPort ) |
|
384 #else |
|
385 TInt CTransNegotiation::ExecuteL( const ThdrISAKMP& aHdr, |
|
386 const TInetAddr& /*aSrcAddr*/, |
|
387 TInt /*aLocalPort*/ ) |
|
388 #endif |
|
389 { |
|
390 DEBUG_LOG(_L("Received message (encr).")); |
|
391 |
|
392 TLastIKEMsg msg_info(aHdr); //For retransmitted IKE msg detection |
|
393 if ( iLastTransMsgInfo.IsReTransmit(msg_info) ) { |
|
394 DEBUG_LOG(_L("Retransmitted Transaction message received, silently discarded !")); |
|
395 return TRANSACTION_IGNORE; |
|
396 } |
|
397 TUint32 status = TRANSACTION_IGNORE; // default |
|
398 TUint32 msg_id; |
|
399 TBuf8<IV_LTH> tmp_IV; //Temporal IV. Used to update the real one if the msg OK |
|
400 const ThdrISAKMP *hdr = NULL; |
|
401 TUint8 *msg = NULL; |
|
402 msg_id = aHdr.GetMessageId(); //Saves the ID to compute IV and hash |
|
403 |
|
404 if (aHdr.GetFlags() & ISAKMP_HDR_EFLAG) //if encrypted |
|
405 { |
|
406 msg = new (ELeave) TUint8[aHdr.GetLength()]; //to place the new msg |
|
407 CleanupStack::PushL(msg); |
|
408 |
|
409 Mem::Copy(msg, (TUint8 *)&aHdr, sizeof(aHdr)); //The header is not encrypted |
|
410 |
|
411 #ifdef _DEBUG |
|
412 DEBUG_LOG(_L("Message ID recv:")); |
|
413 TUint32 swap_id = ByteOrder::Swap32(msg_id); |
|
414 DEBUG_LOG_ARRAY((TUint8 *)&swap_id, sizeof(msg_id)); |
|
415 DEBUG_LOG(_L("Transaction IV:")); |
|
416 #endif // _DEBUG |
|
417 // |
|
418 // Find a transaction exchange structure for current message |
|
419 // |
|
420 iCurrExchange = FindExchange(msg_id); |
|
421 if ( !iCurrExchange ) |
|
422 iCurrExchange = AddExchangeL(msg_id, RESPONDER); // Add a new transaction exchange |
|
423 // |
|
424 // Adjust IV value for transaction exchange. |
|
425 // There is now two situations: |
|
426 // 1) There already exists an IV in exchange structure |
|
427 // (received message is a reply for an earlier sent request) |
|
428 // 2) There is no IV in exchange structure |
|
429 // (received message is a new request/set message from peer) |
|
430 // A new IV is built from CNegotiation.iLastIV and current message ID |
|
431 // |
|
432 if ( iCurrExchange->iIV.Length() == 0 ) { |
|
433 iCurrExchange->iIV.Copy(iNegotiation->iLastIV); |
|
434 iNegotiation->ComputeIVL(iCurrExchange->iIV, msg_id); |
|
435 } |
|
436 tmp_IV.Copy(iCurrExchange->iIV); // Make a copy of current IV |
|
437 |
|
438 DEBUG_LOG(_L("Decrypting...")); |
|
439 |
|
440 DecryptL((TUint8 *)aHdr.Next(),&msg[sizeof(aHdr)], (aHdr.GetLength()-sizeof(aHdr)), |
|
441 iCurrExchange->iIV, iNegotiation->iSKEYID_e, |
|
442 iNegotiation->iChosenProposal_I.iAttrList->iEncrAlg); |
|
443 hdr = (ThdrISAKMP *)msg; //decrypted msg |
|
444 |
|
445 #ifdef _DEBUG |
|
446 const TPtrC8 ikeMsgPtr( (TUint8*)hdr,(TUint16)hdr->GetLength() ); |
|
447 TInetAddr dstAddr; |
|
448 iPluginSession->GetLocalAddress( dstAddr ); |
|
449 dstAddr.SetPort( aLocalPort ); |
|
450 TRACE_MSG_IKEV1( ikeMsgPtr, aSrcAddr, dstAddr ); |
|
451 #endif // _DEBUG |
|
452 |
|
453 status = TransactionExchangeL(*hdr); |
|
454 |
|
455 if ( status == TRANSACTION_IGNORE ) { |
|
456 // |
|
457 // Current message ignored, restore saved IV to exchange structure |
|
458 // |
|
459 iCurrExchange->iIV.Copy(tmp_IV); |
|
460 } |
|
461 } |
|
462 else |
|
463 hdr = &aHdr; |
|
464 |
|
465 if (msg) //If used erase it (when encryption) |
|
466 CleanupStack::PopAndDestroy(); |
|
467 |
|
468 if ( status == TRANSACTION_CONTINUE ) |
|
469 msg_info.Store(iLastTransMsgInfo); // store new last received IKE message info |
|
470 |
|
471 return status; |
|
472 } |
|
473 |
|
474 /**------------------------------------------------------------------- |
|
475 * |
|
476 * Method TransactionExchangeL() |
|
477 * The ISAKMP transaction exchange message MUST be the following format: |
|
478 * HDR*, HASH, ATTR |
|
479 * Where the HASH payload contains the prf output, using SKEYID_a as |
|
480 * the key, and the M-ID (ISAKMP header Message ID) unique to this |
|
481 * exchange concatenated with all of the payloads after the HASH |
|
482 * payload. In other words, the hash for the above exchange is: |
|
483 * HASH = prf( SKEYID_a, M-ID | ATTR ) |
|
484 * Multiple ATTR payloads MAY NOT be present in the Transaction Exchange. |
|
485 * |
|
486 *--------------------------------------------------------------------*/ |
|
487 TInt CTransNegotiation::TransactionExchangeL(const ThdrISAKMP &aHdr) |
|
488 { |
|
489 TUint32 status; |
|
490 iNegotiation->iLengthLeft = aHdr.GetLength(); //Used to check the size in the payload are OK |
|
491 |
|
492 CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *iNegotiation, iDebug); |
|
493 if (!payload) |
|
494 { |
|
495 return TRANSACTION_FAILED; |
|
496 } |
|
497 CleanupStack::PushL(payload); |
|
498 |
|
499 if ( payload->iHash && payload->iAttr ) |
|
500 { |
|
501 // |
|
502 // Check if the hash value is OK. |
|
503 // |
|
504 if (!iNegotiation->VerifyInformationalHashL(payload->iHash, payload->iAttr, |
|
505 iCurrExchange->iMessageId)) |
|
506 { |
|
507 DEBUG_LOG(_L("AUTHENTICATION_FAILED (Transaction hash)")); |
|
508 CleanupStack::PopAndDestroy(); //payload |
|
509 return TRANSACTION_FAILED; |
|
510 } |
|
511 status = ProcessAttributesL(payload->iAttr); |
|
512 CleanupStack::PopAndDestroy(); //payload |
|
513 return status; |
|
514 } |
|
515 CleanupStack::PopAndDestroy(); //payload |
|
516 DEBUG_LOG(_L("Erroneous Transaction Exchange message received")); |
|
517 return TRANSACTION_FAILED; |
|
518 } |
|
519 |
|
520 /**------------------------------------------------------------------- |
|
521 * |
|
522 * Method ProcessAttributesL() |
|
523 * ProcessAttributesL() method parses the data attributes in received |
|
524 * attribute payload. If the iRole data member of current exchange structure |
|
525 * contains value INITIATOR, attribute payload is a CONFIG-MODE Reply |
|
526 * which should contain CONFIG-MODE attributes. |
|
527 * If the iRole data member of current exchange structure |
|
528 * contains value RESPONDER, attribute payload is either a XAUTH Request or Set. |
|
529 * These primitives should contain XAUTH attributes. |
|
530 * |
|
531 *--------------------------------------------------------------------*/ |
|
532 TInt CTransNegotiation::ProcessAttributesL(const TAttributeISAKMP *aAttr) |
|
533 { |
|
534 TInt length = (TInt)aAttr->GetLength(); |
|
535 if ( STATIC_CAST(TUint, length) < sizeof(TAttributeISAKMP) ) { |
|
536 return TRANSACTION_FAILED; |
|
537 } |
|
538 |
|
539 TInt status; |
|
540 TUint8 cfg_msg_type = aAttr->CfgMsgType(); |
|
541 TUint16 identifier = aAttr->Identifier(); |
|
542 |
|
543 if ( iCurrExchange->iRole == INITIATOR ) { |
|
544 // |
|
545 // Config mode transaction. The current message should be a reply. |
|
546 // Identifier value must also match to value in current exchange structure. |
|
547 // |
|
548 if ( cfg_msg_type != ISAKMP_CFG_REPLY ) { |
|
549 // || |
|
550 // ( iCurrExchange->iIdentifier != identifier ) ) { |
|
551 return TRANSACTION_FAILED; |
|
552 } |
|
553 status = ProcessCfgModeAttrsL(aAttr->AttrData(), aAttr->AttrDataLen()); |
|
554 } |
|
555 else { |
|
556 // |
|
557 // XAUTH mode transaction. The current message should be either request |
|
558 // or set. |
|
559 // |
|
560 if ( (cfg_msg_type != ISAKMP_CFG_REQUEST) && (cfg_msg_type != ISAKMP_CFG_SET) ) { |
|
561 return TRANSACTION_FAILED; |
|
562 } |
|
563 iCurrExchange->iIdentifier = identifier; |
|
564 if ( cfg_msg_type == ISAKMP_CFG_REQUEST ) |
|
565 status = ProcessXauthRequestL(aAttr->AttrData(), aAttr->AttrDataLen()); |
|
566 else status = ProcessXauthStatusL(aAttr->AttrData(), aAttr->AttrDataLen()); |
|
567 } |
|
568 |
|
569 return CheckTransactionStatusL(status); |
|
570 |
|
571 } |
|
572 |
|
573 /**------------------------------------------------------------------- |
|
574 * |
|
575 * Method ProcessCfgModeAttrs() |
|
576 * ProcessCfgModeAttrs parses CONFIG-MODE reply message attributes |
|
577 * received from gateway. In this phase the following attributes are used: |
|
578 * -- INTERNAL_IP4_ADDRESS = Client virtual IPv4 address in secure network |
|
579 * -- INTERNAL_IP6_ADDRESS = Client virtual IPv6 address in secure network |
|
580 * -- INTERNAL_IP4_DNS = DNS address(es) in secure network |
|
581 * |
|
582 * All other attributes are silently discarded |
|
583 * |
|
584 *--------------------------------------------------------------------*/ |
|
585 TInt CTransNegotiation::ProcessCfgModeAttrsL(TDataISAKMP* aAttr, TInt aLth) |
|
586 { |
|
587 |
|
588 TBool ia_received = EFalse; |
|
589 TUint32 ipv4_addr; |
|
590 TIp6Addr ipv6_addr; //IPV6 raw address |
|
591 TInetAddr *dns_addr; |
|
592 |
|
593 delete iInternalAddr; // delete old CInternalAddress for sure |
|
594 iInternalAddr = NULL; |
|
595 CInternalAddress *InternalAddr = new (ELeave)CInternalAddress(1); |
|
596 CleanupStack::PushL(InternalAddr); |
|
597 |
|
598 while ( aLth > 0 ) { |
|
599 |
|
600 aLth = aLth - aAttr->Size(); |
|
601 if ( aLth < 0 ) { |
|
602 DEBUG_LOG(_L("CONFIG-MODE REPLY ERROR (Length mismatch in the attibutes)")); |
|
603 CleanupStack::PopAndDestroy(); // InternalAddr |
|
604 return TRANSACTION_FAILED; |
|
605 } |
|
606 switch ( aAttr->Type() ) { |
|
607 |
|
608 case ATTR_INTERNAL_IP4_ADDR: |
|
609 // |
|
610 // A Virtual IPv4 address received. |
|
611 // Store value to CInternalAddress object |
|
612 // |
|
613 if ( !aAttr->IsBasic() && (aAttr->Length() == 4) ) { |
|
614 if ( !ia_received ) { |
|
615 ia_received = ETrue; |
|
616 ipv4_addr = GET32(aAttr->VarValue()); |
|
617 InternalAddr->iClientIntAddr.SetAddress(ipv4_addr); |
|
618 } |
|
619 } |
|
620 break; |
|
621 |
|
622 case ATTR_INTERNAL_IP6_ADDR: |
|
623 // |
|
624 // A Virtual IPv6 address received. |
|
625 // Store value to CInternalAddress object |
|
626 // |
|
627 if ( !aAttr->IsBasic() && (aAttr->Length() == 16) ) { |
|
628 if ( !ia_received ) { |
|
629 ia_received = ETrue; |
|
630 Mem::Copy(&ipv6_addr.u.iAddr8, aAttr->VarValue(), sizeof(ipv6_addr.u.iAddr8)); |
|
631 InternalAddr->iClientIntAddr.SetAddress(ipv6_addr); |
|
632 } |
|
633 } |
|
634 break; |
|
635 |
|
636 case ATTR_INTERNAL_IP4_DNS: |
|
637 // |
|
638 // Internal DNS address received. |
|
639 // Add value to CInternalAddress object |
|
640 // |
|
641 if ( !aAttr->IsBasic() && (aAttr->Length() == 4) ) { |
|
642 ipv4_addr = GET32(aAttr->VarValue()); |
|
643 dns_addr = new(ELeave)TInetAddr; |
|
644 CleanupStack::PushL(dns_addr); |
|
645 dns_addr->SetAddress(ipv4_addr); |
|
646 InternalAddr->AppendL(dns_addr); |
|
647 CleanupStack::Pop(); // dns_addr |
|
648 } |
|
649 break; |
|
650 |
|
651 default: |
|
652 break; |
|
653 } |
|
654 |
|
655 aAttr = aAttr->Next(); |
|
656 } |
|
657 |
|
658 CleanupStack::Pop(); // InternalAddr |
|
659 iInternalAddr = InternalAddr; |
|
660 |
|
661 iCfgModeCompleted = ETrue; |
|
662 |
|
663 DEBUG_LOG(_L("CONFIG-MODE completed, reply received!")); |
|
664 |
|
665 return TRANSACTION_SUCCESS; |
|
666 } |
|
667 |
|
668 /**------------------------------------------------------------------- |
|
669 * |
|
670 * Method ProcessXauthRequest() |
|
671 * ProcessXauthRequest parses XAUTH request message attributes |
|
672 * received from gateway. |
|
673 * |
|
674 *--------------------------------------------------------------------*/ |
|
675 TInt CTransNegotiation::ProcessXauthRequestL(TDataISAKMP* aAttr, TInt aLth) |
|
676 { |
|
677 TInt status = TRANSACTION_CONTINUE; |
|
678 TUint16 xauth_type = ATTR_XAUTH_GENERIC; |
|
679 TUint32 request_flags = 0; |
|
680 TPtr8 challenge(NULL, 0); |
|
681 TUint16 attr_type; |
|
682 |
|
683 while ( aLth > 0 ) { |
|
684 |
|
685 aLth = aLth - aAttr->Size(); |
|
686 if ( aLth < 0 ) { |
|
687 DEBUG_LOG(_L("XAUTH REQUEST ERROR (Length mismatch in the attibutes)")); |
|
688 return TRANSACTION_FAILED; |
|
689 } |
|
690 attr_type = aAttr->Type(); |
|
691 // |
|
692 // Check does the VPN gateway support older XAUTH draft version |
|
693 // draft-ietf-ipsec-isakmp-xauth-04.txt. |
|
694 // The check is based on attribute type values. In the older |
|
695 // draft attribute values are defined in range (13-20) and in the newer |
|
696 // "de-facto" draft-beaulieu-ike-xauth-02.txt the same |
|
697 // attribute values are in "private use" range (16520-16529) |
|
698 // |
|
699 if ( attr_type < ATTR_XAUTH_TYPE ) |
|
700 iUseOlderPIXXauth = ETrue; |
|
701 |
|
702 switch ( attr_type ) { |
|
703 |
|
704 case ATTR_XAUTH_TYPE: |
|
705 case ATTR_PIX_XAUTH_TYPE: |
|
706 // |
|
707 // Extended authentication type requested |
|
708 // |
|
709 if ( aAttr->IsBasic() ) { // Basic attribute |
|
710 request_flags |= (1 << (ATTR_XAUTH_TYPE - ATTR_XAUTH_TYPE)); |
|
711 iCurrExchange->iXauthType = aAttr->Value(); |
|
712 } |
|
713 break; |
|
714 |
|
715 case ATTR_USER_NAME: |
|
716 case ATTR_PASSWORD: |
|
717 case ATTR_PASSCODE: |
|
718 case ATTR_PIX_USER_NAME: |
|
719 case ATTR_PIX_PASSWORD: |
|
720 case ATTR_PIX_PASSCODE: |
|
721 // |
|
722 // Handles the following attribute values: |
|
723 // -- User name |
|
724 // -- Password |
|
725 // -- Passcode |
|
726 // Set a corresponding bit request flags. Parameter contents has |
|
727 // no meaning in request |
|
728 // |
|
729 if ( !aAttr->IsBasic() ) { // Variable length |
|
730 if ( attr_type < ATTR_USER_NAME ) |
|
731 request_flags |= (1 << (attr_type - ATTR_PIX_XAUTH_TYPE)); |
|
732 else request_flags |= (1 << (attr_type - ATTR_XAUTH_TYPE)); |
|
733 } |
|
734 break; |
|
735 |
|
736 case ATTR_MESSAGE: |
|
737 case ATTR_PIX_MESSAGE: |
|
738 // |
|
739 // Message data attribute (NOT USED IN THIS PHASE) |
|
740 // |
|
741 break; |
|
742 |
|
743 case ATTR_CHALLENGE: |
|
744 case ATTR_PIX_CHALLENGE: |
|
745 // |
|
746 // Challenge data attribute |
|
747 // |
|
748 if ( !aAttr->IsBasic() && aAttr->Length() ) { |
|
749 request_flags |= (1 << (ATTR_CHALLENGE - ATTR_XAUTH_TYPE)); |
|
750 challenge.Set(aAttr->VarValue(), aAttr->Length(), aAttr->Length()); |
|
751 } |
|
752 break; |
|
753 |
|
754 case ATTR_DOMAIN: |
|
755 case ATTR_STATUS: |
|
756 case ATTR_PIX_DOMAIN: |
|
757 case ATTR_PIX_STATUS: |
|
758 // |
|
759 // Domain and status attributes (NOT USED IN THIS PHASE) |
|
760 // |
|
761 break; |
|
762 |
|
763 case ATTR_NEXT_PIN: |
|
764 if ( !aAttr->IsBasic() ) { // Variable length |
|
765 request_flags |= (1 << (ATTR_NEXT_PIN - ATTR_XAUTH_TYPE)); |
|
766 } |
|
767 break; |
|
768 |
|
769 case ATTR_ANSWER: |
|
770 // |
|
771 // Answer data attribute (NOT USED IN THIS PHASE) |
|
772 // |
|
773 break; |
|
774 |
|
775 default: |
|
776 break; |
|
777 } |
|
778 |
|
779 aAttr = aAttr->Next(); |
|
780 } |
|
781 |
|
782 // |
|
783 // Check if there already exist a authentication credentials request active |
|
784 // (= iRequestFlags are not zero). If there is ignore current message. |
|
785 // |
|
786 if ( iRequestFlags == 0 ) { |
|
787 iRequestFlags = request_flags; |
|
788 } |
|
789 else { |
|
790 request_flags = 0; |
|
791 status = TRANSACTION_IGNORE; |
|
792 } |
|
793 // |
|
794 // Examine request_flags and show appropriate dialog to get requested |
|
795 // authentication credentials from user |
|
796 // |
|
797 switch ( request_flags & ~(1 << (ATTR_XAUTH_TYPE - ATTR_XAUTH_TYPE)) ) { |
|
798 |
|
799 case ( (1 << (ATTR_USER_NAME - ATTR_XAUTH_TYPE)) | (1 << (ATTR_PASSWORD - ATTR_XAUTH_TYPE))): |
|
800 // |
|
801 // User name/Password authentication required |
|
802 // |
|
803 iDialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); |
|
804 iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, XAUTH_DIALOG_ID, iNegotiation->SAId(), iCurrExchange->iMessageId); |
|
805 iDialog->GetAsyncUNPWDialogL(iDialogInfo, (MIkeDialogComplete*)this); |
|
806 break; |
|
807 |
|
808 case ( (1 << (ATTR_USER_NAME - ATTR_XAUTH_TYPE)) | (1 << (ATTR_PASSCODE - ATTR_XAUTH_TYPE))): |
|
809 // |
|
810 // User name/Secure ID authentication required |
|
811 // |
|
812 iDialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); |
|
813 iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, XAUTH_DIALOG_ID, iNegotiation->SAId(), iCurrExchange->iMessageId); |
|
814 iDialog->GetAsyncSecureidDialogL(iDialogInfo, (MIkeDialogComplete*)this); |
|
815 break; |
|
816 |
|
817 case ( (1 << (ATTR_USER_NAME - ATTR_XAUTH_TYPE)) | (1 << (ATTR_NEXT_PIN - ATTR_XAUTH_TYPE))): |
|
818 // |
|
819 // User name/Secure ID next pin required |
|
820 // |
|
821 iDialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); |
|
822 iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, XAUTH_DIALOG_ID, iNegotiation->SAId(), iCurrExchange->iMessageId); |
|
823 iDialog->GetAsyncSecureNextPinDialogL(iDialogInfo, (MIkeDialogComplete*)this); |
|
824 break; |
|
825 |
|
826 case ( (1 << (ATTR_CHALLENGE - ATTR_XAUTH_TYPE)) ): |
|
827 // |
|
828 // User Challenge response dialog |
|
829 // |
|
830 if ( xauth_type == ATTR_XAUTH_RADIUS_CHAP ) |
|
831 { |
|
832 iDialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); |
|
833 iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, XAUTH_DIALOG_ID, iNegotiation->SAId(), iCurrExchange->iMessageId); |
|
834 iDialog->GetAsyncRespDialog(challenge, iDialogInfo, (MIkeDialogComplete*)this); |
|
835 } |
|
836 break; |
|
837 |
|
838 default: |
|
839 break; |
|
840 |
|
841 } |
|
842 |
|
843 return status; |
|
844 |
|
845 } |
|
846 |
|
847 /**------------------------------------------------------------------- |
|
848 * |
|
849 * Method ProcessXauthStatus() |
|
850 * ProcessXauthStatus parses XAUTH Set message attributes received from gateway. |
|
851 * Only Status attribute has any relevance in Set message. |
|
852 * |
|
853 *--------------------------------------------------------------------*/ |
|
854 TInt CTransNegotiation::ProcessXauthStatusL(TDataISAKMP* aAttr, TInt aLth) |
|
855 { |
|
856 TBuf8<16> attributes; |
|
857 TInt status = TRANSACTION_CONTINUE; |
|
858 TInt16 attr_status; |
|
859 |
|
860 while ( aLth > 0 ) { |
|
861 |
|
862 aLth = aLth - aAttr->Size(); |
|
863 if ( aLth < 0 ) { |
|
864 DEBUG_LOG(_L("XAUTH SET ERROR (Length mismatch in the attibutes)")); |
|
865 return TRANSACTION_FAILED; |
|
866 } |
|
867 |
|
868 switch ( aAttr->Type() ) { |
|
869 |
|
870 case ATTR_STATUS: |
|
871 case ATTR_PIX_STATUS: |
|
872 // |
|
873 // Status code from gateway |
|
874 // |
|
875 if ( aAttr->IsBasic() ) { // Basic attribute |
|
876 attr_status = aAttr->Value(); |
|
877 if ( attr_status == ATTR_STATUS_OK ) |
|
878 status = TRANSACTION_SUCCESS; |
|
879 else status = TRANSACTION_FAILED; |
|
880 } |
|
881 break; |
|
882 |
|
883 default: |
|
884 break; |
|
885 } |
|
886 |
|
887 aAttr = aAttr->Next(); |
|
888 } |
|
889 |
|
890 if ( status != TRANSACTION_CONTINUE ) { |
|
891 // |
|
892 // Send Transaction exchange ACK |
|
893 // |
|
894 TUint16 AttrType; |
|
895 if ( iUseOlderPIXXauth ) |
|
896 AttrType = ATTR_PIX_STATUS; |
|
897 else AttrType = ATTR_STATUS; |
|
898 |
|
899 AddAttributeData(attributes, AttrType, 2, (TUint8*)&attr_status); |
|
900 BuildAndSendMessageL(attributes, ISAKMP_CFG_ACK); |
|
901 if ( status == TRANSACTION_SUCCESS ) { |
|
902 DEBUG_LOG(_L("XAUTH authentication succeeded!")); |
|
903 iXauthCompleted = ETrue; |
|
904 if ( iUserName ) { |
|
905 // |
|
906 // Cache user name into user name file |
|
907 // |
|
908 CIkev1Dialog* Dialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); |
|
909 CleanupStack::PushL(Dialog); |
|
910 TInt err(KErrNone); |
|
911 TRAP(err, Dialog->StoreUserNameL(iUserName->Des())); |
|
912 #ifdef _DEBUG |
|
913 if (err == KErrNone) |
|
914 DEBUG_LOG(_L("User Name caching succeeded")); |
|
915 else DEBUG_LOG(_L("User Name caching failed")); |
|
916 #endif // _DEBUG |
|
917 CleanupStack::PopAndDestroy(); |
|
918 } |
|
919 } |
|
920 else { |
|
921 DEBUG_LOG(_L("XAUTH authentication failed!")); |
|
922 // Dialog object shall be delete in Dialog->RunL when dialog completed |
|
923 CIkev1Dialog* Dialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); |
|
924 Dialog->ShowErrorDialogL(TVpnNoteDialog::EKmdAuthenticationFailed, NULL, NULL); |
|
925 } |
|
926 } |
|
927 |
|
928 return status; |
|
929 } |
|
930 |
|
931 /**-------------------------------------------------------------------------------- |
|
932 * |
|
933 * Method CheckTransactionStatusL() |
|
934 * CheckTransactionStatus is after an incoming ISAKMP transaction exchange message |
|
935 * has been processed. This method decides the actions shall be taken next: |
|
936 * -- If current status (= call parameter) is continue, ignore or failed |
|
937 * ==> Same status is returned |
|
938 * -- If current status is success and XAUTH completed. |
|
939 * ==> CONFIG MODE actions are started (= Config mode request is transmitted) |
|
940 * -- If current status is success and CONFIG MODE completed. |
|
941 * ==> XAUTH actions are started. (= We shall just wait for XAUTH request) |
|
942 * -- If current status is success and both CONFIG-MODE and XAUTH completed |
|
943 * ==> TRANSACTION_SUCCESS status is returned |
|
944 * |
|
945 *--------------------------------------------------------------------*/ |
|
946 TInt CTransNegotiation::CheckTransactionStatusL(TInt aStatus) |
|
947 { |
|
948 if ( aStatus == TRANSACTION_SUCCESS || aStatus == TRANSACTION_CONTINUE ) { |
|
949 // |
|
950 // Stop retransmission timer |
|
951 // |
|
952 iNegotiation->iTimer->Cancel(); |
|
953 |
|
954 if ( aStatus == TRANSACTION_SUCCESS ) { |
|
955 if ( iXauthCompleted ) { |
|
956 if ( !iCfgModeCompleted ) { |
|
957 aStatus = BuildConfigRequestL(); |
|
958 } |
|
959 } |
|
960 else { |
|
961 if ( !iXauthCompleted ) { |
|
962 aStatus = TRANSACTION_CONTINUE; |
|
963 } |
|
964 } |
|
965 } |
|
966 } |
|
967 |
|
968 return aStatus; |
|
969 } |
|
970 |
|
971 /**------------------------------------------------------------------- |
|
972 * |
|
973 * Method BuildConfigRequestL() |
|
974 * BuildConfigRequestL() builds the CONFIG-MODE request message. |
|
975 * In this phase requests the following parameters from gateway: |
|
976 * -- Client virtual IP in secure network = INTERNAL_IP4_ADDRESS, INTERNAL_IP4_NETMASK |
|
977 * (INTERNAL_IP6_ADDRESS, INTERNAL_IP6_NETMASK) |
|
978 * -- DNS address(es) in secure network = INTERNAL_IP4_DNS |
|
979 * |
|
980 *--------------------------------------------------------------------*/ |
|
981 TInt CTransNegotiation::BuildConfigRequestL() |
|
982 { |
|
983 |
|
984 TBuf8<16> attributes; |
|
985 |
|
986 TUint32 message_id = iNegotiation->RandomMessageId(); |
|
987 |
|
988 iCurrExchange = AddExchangeL(message_id, INITIATOR); //Add a new transaction exchange |
|
989 iCurrExchange->iIdentifier = GetIdentifier(); |
|
990 |
|
991 iCurrExchange->iIV.Copy(iNegotiation->iLastIV); // Calculate base IV for .. |
|
992 iNegotiation->ComputeIVL(iCurrExchange->iIV, message_id); // transaction message |
|
993 |
|
994 AddAttributeData(attributes, ATTR_INTERNAL_IP4_ADDR, 0, NULL); |
|
995 AddAttributeData(attributes, ATTR_INTERNAL_IP4_DNS, 0, NULL); |
|
996 |
|
997 BuildAndSendMessageL(attributes, ISAKMP_CFG_REQUEST); |
|
998 DEBUG_LOG(_L("CONFIG-MODE started, request xmitted!")); |
|
999 |
|
1000 return TRANSACTION_CONTINUE; |
|
1001 |
|
1002 |
|
1003 } |
|
1004 |
|
1005 /**------------------------------------------------------------------- |
|
1006 * |
|
1007 * Method AddAttributeData() |
|
1008 * AddAttributeData() method adds one attribute data to an attribute buffer |
|
1009 * |
|
1010 *--------------------------------------------------------------------*/ |
|
1011 void CTransNegotiation::AddAttributeData(TDes8& aAttrBfr, TInt aType, TInt aLth, TUint8* aData) |
|
1012 { |
|
1013 TDataISAKMP attr; |
|
1014 if ( aType == ATTR_STATUS || aType == ATTR_XAUTH_TYPE || |
|
1015 aType == ATTR_PIX_STATUS || aType == ATTR_PIX_XAUTH_TYPE) { |
|
1016 // |
|
1017 // Add a basic length attribute |
|
1018 // |
|
1019 attr.SetBasic(ETrue); |
|
1020 attr.SetType((TUint16)aType); |
|
1021 if ( aData ) |
|
1022 attr.SetValue(*(TUint16*)aData); |
|
1023 aAttrBfr.Append((TUint8 *)&attr, sizeof(attr)); |
|
1024 } |
|
1025 else { |
|
1026 // |
|
1027 // Add a variable length attribute |
|
1028 // |
|
1029 attr.SetBasic(EFalse); |
|
1030 attr.SetType((TUint16)aType); |
|
1031 attr.SetLength((TUint16)(aLth)); |
|
1032 aAttrBfr.Append((TUint8 *)&attr, sizeof(attr)); |
|
1033 if ( aLth ) |
|
1034 aAttrBfr.Append(aData, aLth); |
|
1035 } |
|
1036 } |
|
1037 |
|
1038 /**------------------------------------------------------------------- |
|
1039 * |
|
1040 * Method BuildAndSendMessageL() |
|
1041 * BuildAndSendMessage() method builds ISAKMP transaction exchange message |
|
1042 * and transmits it using CNegotiation class send() method. |
|
1043 * The payload format of a transaction exchange message is the following: |
|
1044 * HDR*, HASH, ATTR |
|
1045 * Where the HASH payload contains the prf output, using SKEYID_a as |
|
1046 * the key, and the M-ID (ISAKMP header Message ID) unique to this |
|
1047 * exchange concatenated with all of the payloads after the HASH |
|
1048 * payload. In other words, the hash for the above exchange is: |
|
1049 * HASH = prf( SKEYID_a, M-ID | ATTR ) |
|
1050 * |
|
1051 *--------------------------------------------------------------------*/ |
|
1052 void CTransNegotiation::BuildAndSendMessageL(TDesC8& aAttrBfr, TUint8 aMsgType) |
|
1053 { |
|
1054 TIkev1IsakmpStream* msg = iNegotiation->SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) ); |
|
1055 |
|
1056 TUint32 saved_msg_id = iNegotiation->iMessageId; |
|
1057 TUint8 saved_exchange = iNegotiation->iExchange; |
|
1058 iNegotiation->iMessageId = iCurrExchange->iMessageId; // used in method Isakmp_INIT() |
|
1059 iNegotiation->iExchange = ISAKMP_EXCHANGE_TRANSACT; // used in method Isakmp_INIT() |
|
1060 |
|
1061 msg->IsakmpInit(iNegotiation); |
|
1062 msg->IsakmpHashL(); |
|
1063 msg->IsakmpAttributes(aMsgType, iCurrExchange->iIdentifier, aAttrBfr); |
|
1064 msg->IsakmpHashContL(); |
|
1065 |
|
1066 iNegotiation->SendL(*msg); |
|
1067 |
|
1068 iNegotiation->iMessageId = saved_msg_id; |
|
1069 iNegotiation->iExchange = saved_exchange; |
|
1070 |
|
1071 } |
|
1072 |
|
1073 /**------------------------------------------------------------------- |
|
1074 * |
|
1075 * Method FindExchange() |
|
1076 * FindExchange() method finds a exchange strcuture for a specified message id |
|
1077 * |
|
1078 *--------------------------------------------------------------------*/ |
|
1079 TTransExchange* CTransNegotiation::FindExchange(TUint32 aMsgId) |
|
1080 { |
|
1081 TTransExchange *exchange; |
|
1082 TInt i = 0; |
|
1083 |
|
1084 while ( i < Count() ) |
|
1085 { |
|
1086 exchange = At(i); |
|
1087 if ( exchange->iMessageId == aMsgId ) |
|
1088 return exchange; |
|
1089 i ++; |
|
1090 } |
|
1091 |
|
1092 return NULL; |
|
1093 } |
|
1094 |
|
1095 /**------------------------------------------------------------------- |
|
1096 * |
|
1097 * Method AddExchangeL() |
|
1098 * AddExchangeL() method allocates a new exchange structure and adds it |
|
1099 * to exchange array. |
|
1100 * |
|
1101 *--------------------------------------------------------------------*/ |
|
1102 TTransExchange* CTransNegotiation::AddExchangeL(TUint32 aMsgId, TUint8 aRole ) |
|
1103 { |
|
1104 |
|
1105 TTransExchange *exchange = new(ELeave)TTransExchange; |
|
1106 exchange->iMessageId = aMsgId; |
|
1107 exchange->iRole = aRole; |
|
1108 exchange->iIV.SetLength(0); |
|
1109 AppendL(exchange); |
|
1110 |
|
1111 return exchange; |
|
1112 } |
|
1113 |
|
1114 // |
|
1115 // The implementation for class MIkeDialogComplete virtual function |
|
1116 // |
|
1117 TInt CTransNegotiation::DialogCompleteL(CIkev1Dialog* /*aDialog*/, TAny* aUserInfo, |
|
1118 HBufC8* aUsername, HBufC8* aSecret, HBufC8* aDomain) |
|
1119 { |
|
1120 /*--------------------------------------------------------------------------- |
|
1121 * |
|
1122 * A response received from client user (through asynchronous dialog) |
|
1123 * This method is introduced as a TUserCallback for CGetIKEPassword dialog |
|
1124 * object is created. When the dialog is completed this callback function |
|
1125 * is called to deliver Credentials data for CHRE payload attributes. |
|
1126 * Store credential buffers to CAuthDialogInfo object and call engine |
|
1127 * entry |
|
1128 * |
|
1129 *-------------------------------------------------------------------------*/ |
|
1130 TUint32 obj_id = 1; |
|
1131 CAuthDialogInfo* info = (CAuthDialogInfo*)aUserInfo; |
|
1132 DEBUG_LOG1(_L("CIKECRACKNegotiation::DialogCompleteL(), aUserInfo = %x"), aUserInfo); |
|
1133 |
|
1134 if ( info ) |
|
1135 { |
|
1136 obj_id = info->GetObjId(); |
|
1137 DEBUG_LOG1(_L("Preparing to call AuthDialogCompletedL(), ObjId = %x"), obj_id); |
|
1138 if ( obj_id == XAUTH_DIALOG_ID ) |
|
1139 { |
|
1140 info->iUsername = aUsername; |
|
1141 info->iSecret = aSecret; |
|
1142 info->iDomain = aDomain; |
|
1143 obj_id = info->PluginSession()->AuthDialogCompletedL(info); |
|
1144 } |
|
1145 } |
|
1146 |
|
1147 return obj_id; |
|
1148 } |