|
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: |
|
15 * This module contains the private vendor specific extension of IKE. |
|
16 * All of the current private extensions are related to Nokia VPN gateway |
|
17 * and shall be used ONLY when the EPOC IKE is acting as a Nokia VPN remote |
|
18 * access client. |
|
19 * The following private extension are implemented: |
|
20 * |
|
21 * 1) Internal Address payload usage |
|
22 * Internal address payload is used to the deliver a secure network |
|
23 * adderess and secure network DNS address(es) from VPN gateway to a client. |
|
24 * The Internal address payloads are used in the last two IKE main mode |
|
25 * messages as follows: |
|
26 * |
|
27 * Client (initiator) Gateway (responder) |
|
28 * .. SA, KE ... ---> |
|
29 * <--- ..SA, KE ... |
|
30 * HDR*, INT_ADDR ---> |
|
31 * <--- HDR*, INT_ADDR |
|
32 * |
|
33 * Client sends an INT_ADDR payload with PRI_INTERNAL_ADDRESS attribute |
|
34 * Attribute value is 0.0.0.0. |
|
35 * |
|
36 * Gateway responds with an INT_ADDR payload with PRI_INTERNAL_ADDRESS |
|
37 * attribute containing client internal address x.y.z.w |
|
38 * Gateway INT_ADDR payload may also contain attributes PRI_INTERNAL_DNS and |
|
39 * PRI_INTERNAL_WINS. PRI_INTERNAL_DNS contains a list of DNS IP addresses and |
|
40 * PRI_INTERNAL_WINS a list of WINS IP addresses. |
|
41 * |
|
42 * |
|
43 * 2) The NAT Traversal probing |
|
44 * The expanded Vendor-Id payload usage for the NAT Traversal probing. |
|
45 * The expanded Vendor-Id payloads contains the following information: |
|
46 * |
|
47 * Client (initiator) Gateway (responder) |
|
48 * VID(hash, ip_addr, port) ---> |
|
49 * <--- VID(hash, detected_ip_addr, |
|
50 * detected_port) |
|
51 * |
|
52 * Client sends a expanded Vendor-Id payload containing the following information: |
|
53 * hash = Nokia VPN vendor specific hash data (used to recognize peer) |
|
54 * ip_addr = Client IKE own IP address |
|
55 * port = Client IKE own port (=500) |
|
56 * |
|
57 * Gateway responds with expanded Vendor-Id payload containing the following information: |
|
58 * hash = Nokia VPN vendor specific hash data (used to recognize peer) |
|
59 * detected_ip_addr = Client IP address as detected in received IKE message |
|
60 * IP header (=source IP address) |
|
61 * detected_port = Client port as detected in received IKE message |
|
62 * UDP header (=source port) |
|
63 * |
|
64 * Both client and gateway do the following examination |
|
65 * if ( ip_addr != detected_ip_addr ) || ( port != detected_port ) |
|
66 * then NAT Traversal shall be used IPSEC ESP traffic between |
|
67 * the client and gateway |
|
68 * |
|
69 * Nokia VPN specific NAT Traversal means that IPSEC ESP traffic shall be |
|
70 * capsulated with UDP header. |
|
71 * The used UDP port for that purpose is 9872 |
|
72 * |
|
73 */ |
|
74 |
|
75 #include "ikev1private.h" |
|
76 #include "ikev1dialog.h" |
|
77 #include "ikev1negotiation.h" |
|
78 #include "ikev1isakmpstream.h" |
|
79 |
|
80 #include "ikepolparser.h" |
|
81 |
|
82 const TUint8 BASE_VID_DATA[16] = {0x06, 0x3d, 0xf4, 0x13, 0x91, 0xa9, 0x19, 0xa2, |
|
83 0x5a, 0x61, 0xa8, 0x7c, 0x45, 0x02, 0x5f, 0xaf}; |
|
84 |
|
85 const TUint8 DPD_VID_DATA[16] = {0xAF, 0xCA, 0xD7, 0x13, 0x68, 0xA1, 0xF1, 0xC9, |
|
86 0x6B, 0x86, 0x96, 0xFC, 0x77, 0x57, 0x01, 0x00}; |
|
87 |
|
88 TInt BuildVendorIdHash(TUint8 *aICOOKIE, TUint8 *aRCOOKIE, TUint8 *hash_data) |
|
89 { |
|
90 /*-------------------------------------------------------------------------------- |
|
91 * |
|
92 * Build Vendor Id hash data |
|
93 * |
|
94 *------------------------------------------------------------------------*/ |
|
95 // |
|
96 // base = MD5("Network Alchemy, Inc., Version 1.0"); /* ASCII-Z end null included) |
|
97 // |
|
98 TInt i; |
|
99 |
|
100 Mem::Copy(hash_data, &BASE_VID_DATA[0], 16); /* Hash base (MD5) */ |
|
101 |
|
102 for ( i = 0; i < (ISAKMP_COOKIE_SIZE * 2); i++ ) { |
|
103 |
|
104 if ( i < ISAKMP_COOKIE_SIZE ) |
|
105 *(hash_data + i) ^= *(aICOOKIE + i); |
|
106 else *(hash_data + i) ^= *(aRCOOKIE + (i - ISAKMP_COOKIE_SIZE)); |
|
107 |
|
108 } |
|
109 |
|
110 return 16; |
|
111 } |
|
112 |
|
113 |
|
114 TInt ConstructVendorId(TBool aNATProbe, |
|
115 TUint8 *aICOOKIE, |
|
116 TUint8 *aRCOOKIE, |
|
117 TInetAddr &aLocalAddr, |
|
118 TVendorISAKMP *aVendorPayload) |
|
119 { |
|
120 /*------------------------------------------------------------------------ |
|
121 * |
|
122 * This method constructs a Vendor ID payload. If aNATProbe is TRUE |
|
123 * an expanded format Vendor ID is constructed. |
|
124 * Both Vendor ID formats contains a Nokia VPN vendor specific hash data |
|
125 * which constructed as follows: |
|
126 * base = MD5("Network Alchemy, Inc., Version 1.0"); ASCII-Z end null included) |
|
127 * base = BASE_VID_DATA; |
|
128 * Then the Vendor ID hash is consructed xor:ing ISAKMP cookies to hash as follows: |
|
129 * |
|
130 * for ( i = 0; i < (ISAKMP_COOKIE_SIZE * 2); i++ ) { |
|
131 * if ( i < ISAKMP_COOKIE_SIZE ) |
|
132 * base[i] ^= ICOOKIE[i]; |
|
133 * else base[i] ^= RCOOKIE[i - ISAKMP_COOKIE_SIZE]; |
|
134 * } |
|
135 * |
|
136 * The expanded vendor ID payload looks like so: |
|
137 * |
|
138 * General payload header (next payload is "real" next payload) |
|
139 * General payload header (next payload is "VENDOR_OPTION_NAT_TRAVERSAL") |
|
140 * option hash |
|
141 * General payload header (next payload is "VENDOR_OPTION_VERSION") |
|
142 * option VENDOR_OPTION_NAT_TRAVERSAL |
|
143 * General payload header (next payload is "NULL") |
|
144 * option VENDOR_OPTION_VERSION |
|
145 * |
|
146 * Expanded vendor id format is format is as follows: |
|
147 * |
|
148 * 1 2 3 |
|
149 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
|
150 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
151 * ! Next Payload ! RESERVED ! Payload Length = 44 ! |
|
152 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
153 * ! OPTION_NAT_T ! RESERVED ! Hash_lth + 4 = 20 ! |
|
154 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
155 * ! Nokia VPN Vendor specific hash ! |
|
156 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
157 * ! OPTION_VERSION! RESERVED ! OPTION_NAT_T_LTH + 4 = 20 ! |
|
158 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
159 * ! sin_lth ! sin_family ! sin_port ! |
|
160 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
161 * ! sin_addr ! |
|
162 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
163 * ! ! |
|
164 * . Zero * 2(?) . |
|
165 * ! ! |
|
166 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
167 * ! 0 ! RESERVED ! OPTION_VERSION + 4 = 8 ! |
|
168 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
169 * ! MAJOR VERSION ! MINOR VERSION ! |
|
170 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
171 * |
|
172 * |
|
173 *------------------------------------------------------------------------*/ |
|
174 TVendorISAKMP *nat_vendor_id; |
|
175 TVendorISAKMP *ver_vendor_id; |
|
176 TNATTOption *nat_t_option; |
|
177 TVersionOption *version_option; |
|
178 TUint8 *next_payload; |
|
179 TUint32 vid_lth; |
|
180 TInetAddr own_addr = aLocalAddr; |
|
181 |
|
182 next_payload = (TUint8 *)aVendorPayload; |
|
183 *next_payload = ISAKMP_PAYLOAD_NONE; /* zeroe next payload field for sure */ |
|
184 |
|
185 if ( aNATProbe ) { |
|
186 /*------------------------------------------------------------ |
|
187 * |
|
188 * Build expanded Vendor Id payload |
|
189 * Build first VENDOR_OPTION_NAT_TRAVERSAL payload |
|
190 * |
|
191 *-----------------------------------------------------------*/ |
|
192 nat_vendor_id = (TVendorISAKMP*)((TUint8*)aVendorPayload + |
|
193 sizeof(TPayloadISAKMP) + |
|
194 sizeof(TPayloadISAKMP) + 16); //bypass hash |
|
195 next_payload = (TUint8 *)nat_vendor_id; |
|
196 *next_payload = VENDOR_OPTION_VERSION; |
|
197 nat_vendor_id->SetReserved(0); |
|
198 nat_vendor_id->SetLength(sizeof(TPayloadISAKMP) + SIN_LTH); |
|
199 nat_t_option = (TNATTOption*)nat_vendor_id->VIDData(); |
|
200 nat_t_option->InitOption(); |
|
201 nat_t_option->SetPort(500); |
|
202 if ( own_addr.IsV4Mapped() ) |
|
203 own_addr.ConvertToV4(); |
|
204 nat_t_option->SetAddress(own_addr.Address()); |
|
205 /*------------------------------------------------------------ |
|
206 * |
|
207 * Build next VENDOR_OPTION_VERSION payload |
|
208 * Set major version X and minor Y. |
|
209 * |
|
210 *-----------------------------------------------------------*/ |
|
211 ver_vendor_id = (TVendorISAKMP*)((TUint8*)nat_vendor_id + |
|
212 sizeof(TPayloadISAKMP) + SIN_LTH); //bypass NAT-T |
|
213 next_payload = (TUint8 *)ver_vendor_id; |
|
214 *next_payload = ISAKMP_PAYLOAD_NONE; |
|
215 ver_vendor_id->SetReserved(0); |
|
216 ver_vendor_id->SetLength(sizeof(TPayloadISAKMP) + VERSION_LTH); |
|
217 version_option = (TVersionOption*)ver_vendor_id->VIDData(); |
|
218 version_option->SetVersion(MAJOR_VERSION, MINOR_VERSION); |
|
219 |
|
220 /*------------------------------------------------------------ |
|
221 * |
|
222 * Build "upper" Vendor Id payload general header |
|
223 * |
|
224 *-----------------------------------------------------------*/ |
|
225 vid_lth = sizeof(TPayloadISAKMP) + /* "outer" Vendor ID payload */ |
|
226 sizeof(TPayloadISAKMP) + 16 + /* VENDOR_OPTION_HASH */ |
|
227 sizeof(TPayloadISAKMP) + SIN_LTH + /* VENDOR_OPTION_NAT_TRAVERSAL */ |
|
228 sizeof(TPayloadISAKMP) + VERSION_LTH;/* VENDOR_OPTION_VERSION */ |
|
229 aVendorPayload->SetLength((TUint16)vid_lth); |
|
230 aVendorPayload->SetReserved(0); |
|
231 |
|
232 aVendorPayload = (TVendorISAKMP*)((TUint8*)aVendorPayload + sizeof(TPayloadISAKMP)); |
|
233 next_payload = (TUint8 *)aVendorPayload; |
|
234 *next_payload = VENDOR_OPTION_NAT_TRAVERSAL; |
|
235 } |
|
236 else { |
|
237 vid_lth = sizeof(TPayloadISAKMP) + 16; |
|
238 } |
|
239 /*------------------------------------------------------------ |
|
240 * |
|
241 * Store Hash data into Vendor Id payload |
|
242 * |
|
243 *-----------------------------------------------------------*/ |
|
244 aVendorPayload->SetReserved(0); |
|
245 aVendorPayload->SetLength((TUint16)sizeof(TPayloadISAKMP) + 16); |
|
246 |
|
247 BuildVendorIdHash(aICOOKIE, aRCOOKIE, |
|
248 aVendorPayload->VIDData()); |
|
249 |
|
250 return vid_lth; |
|
251 |
|
252 } |
|
253 |
|
254 |
|
255 TBool ProcessVendorId(TBool *aFamiliarPeer, |
|
256 TUint8 *aICOOKIE, |
|
257 TUint8 *aRCOOKIE, |
|
258 TInetAddr &aLocalAddr, |
|
259 TVendorISAKMP *aVendorPayload) |
|
260 { |
|
261 /*------------------------------------------------------------------------- |
|
262 * |
|
263 * Process Vendor Id payload received from peer. |
|
264 * The following actions taken: |
|
265 * -- Check if a Nokia VPN implementation i peer (recognize hash in Vendor Id) |
|
266 * -- If Nokia VPN implementation detected process possible |
|
267 * VENDOR_OPTION_NAT_TRAVERSAL in expanded Vendor Id payload |
|
268 * |
|
269 *------------------------------------------------------------------------*/ |
|
270 TBool nokia_vpn_peer = EFalse; |
|
271 TBool nat_t_required = EFalse; |
|
272 TVendorISAKMP *option_payload; |
|
273 TNATTOption *nat_t_option; |
|
274 TInt vid_lth; |
|
275 TInt tmp_lth; |
|
276 TInt hash_lth; |
|
277 TUint16 ptype; |
|
278 TUint16 detected_port; |
|
279 TUint8 ref_hash[20]; |
|
280 TInetAddr detected_addr; |
|
281 TInetAddr reference_addr = aLocalAddr; |
|
282 |
|
283 vid_lth = aVendorPayload->GetLength() - sizeof(TPayloadISAKMP); |
|
284 if ( vid_lth > 15 ) { |
|
285 /*------------------------------------------------------- |
|
286 * |
|
287 * Check if expanded Vendor Id format |
|
288 * |
|
289 *-------------------------------------------------------*/ |
|
290 tmp_lth = vid_lth; |
|
291 ptype = ISAKMP_PAYLOAD_NONE; |
|
292 hash_lth = BuildVendorIdHash(aICOOKIE, aRCOOKIE, ref_hash); |
|
293 option_payload = aVendorPayload; |
|
294 if ( vid_lth > hash_lth ) { |
|
295 /*--------------------------------------------------------------------- |
|
296 * |
|
297 * An expanded format Vendor Id, bypass "outer" payload general header |
|
298 * And do sanity check for VENDOR_OPTION_HASH option payload |
|
299 * |
|
300 *--------------------------------------------------------------------*/ |
|
301 option_payload = (TVendorISAKMP*)((TUint8*)option_payload + sizeof(TPayloadISAKMP)); |
|
302 ptype = option_payload->GetPayload(); |
|
303 tmp_lth = option_payload->GetLength(); |
|
304 if ( tmp_lth == (sizeof(TPayloadISAKMP) + 16 ) ) |
|
305 // && |
|
306 // ( option_payload->GetReserved() == 0 ) ) { //Must be always 0 |
|
307 tmp_lth -= sizeof(TPayloadISAKMP); |
|
308 else tmp_lth = 0; |
|
309 } |
|
310 |
|
311 if ( tmp_lth == hash_lth ) { |
|
312 /*--------------------------------------------- |
|
313 * |
|
314 * Check that Vendor Id hash match |
|
315 * |
|
316 *---------------------------------------------*/ |
|
317 if ( Mem::Compare(option_payload->VIDData(), tmp_lth, ref_hash, hash_lth) == 0 ) { |
|
318 /*----------------------------------------------------------- |
|
319 * |
|
320 * Process other Vendor Id option payload(s) |
|
321 * In this phase only VENDOR_OPTION_NAT_TRAVERSAL is processed |
|
322 * other options are ignored |
|
323 * |
|
324 *-----------------------------------------------------------*/ |
|
325 nokia_vpn_peer = ETrue; |
|
326 tmp_lth += sizeof(TPayloadISAKMP); |
|
327 option_payload = (TVendorISAKMP*)((TUint8*)option_payload + tmp_lth); |
|
328 |
|
329 while ( ptype != ISAKMP_PAYLOAD_NONE ) { |
|
330 |
|
331 if ( vid_lth <= tmp_lth ) { |
|
332 break; |
|
333 } |
|
334 hash_lth = option_payload->GetLength(); |
|
335 tmp_lth += hash_lth; |
|
336 if ( ( hash_lth < (MIN_ISAKMP_PAYLOAD_SIZE + SIN_LTH) ) ) { |
|
337 // && |
|
338 // ( option_payload->GetReserved() != 0 ) ) } //Must be always 0 |
|
339 break; |
|
340 } |
|
341 if ( ptype == VENDOR_OPTION_NAT_TRAVERSAL ) { |
|
342 if ( reference_addr.IsV4Mapped() ) |
|
343 reference_addr.ConvertToV4(); |
|
344 hash_lth -= sizeof(TPayloadISAKMP); /* option data length */ |
|
345 nat_t_option = (TNATTOption*)((TUint8*)option_payload + sizeof(TPayloadISAKMP)); |
|
346 detected_port = nat_t_option->GetPort(); |
|
347 detected_addr.SetAddress(nat_t_option->GetAddress()); |
|
348 if ( (detected_port != 500) /* Port changed */ |
|
349 || |
|
350 !(detected_addr.Match(reference_addr))) { /* address changed */ |
|
351 nat_t_required = ETrue; |
|
352 } |
|
353 break; |
|
354 } |
|
355 |
|
356 ptype = option_payload->GetPayload(); //Next payload |
|
357 option_payload = (TVendorISAKMP*)((TUint8*)option_payload + hash_lth); |
|
358 |
|
359 } |
|
360 } |
|
361 } |
|
362 |
|
363 } |
|
364 |
|
365 if ( aFamiliarPeer ) |
|
366 *aFamiliarPeer = nokia_vpn_peer; |
|
367 |
|
368 return nat_t_required; |
|
369 |
|
370 } |
|
371 |
|
372 /**------------------------------------------------------------------- |
|
373 * |
|
374 * Function BuildDPDVendorId() |
|
375 * This method builds a Dead Peer Detection (DPD) related Vendor ID |
|
376 * payload and adds it into the IKE message. The vendor id is |
|
377 * specified in the draft <draft-ietf-ipsec-dpd-04.txt> and its |
|
378 * content is the following: |
|
379 * 1 |
|
380 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 |
|
381 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
382 * ! !M!M! |
|
383 * ! HASHED_VENDOR_ID !J!N! |
|
384 * ! !R!R! |
|
385 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
386 * |
|
387 * Hash data is, |
|
388 * {0xAF, 0xCA, 0xD7, 0x13, 0x68, 0xA1, 0xF1, 0xC9, 0x6B, 0x86, 0x96, |
|
389 * 0xFC, 0x77, 0x57}, and MJR and MNR |
|
390 * MJR = 1 and MNR = 0 |
|
391 * |
|
392 *--------------------------------------------------------------------*/ |
|
393 void BuildDPDVendorId(TIkev1IsakmpStream &aMsg) |
|
394 { |
|
395 TInetAddr DummyAddr; |
|
396 |
|
397 aMsg.IsakmpVendorId(IETF_NATT_VENDOR_ID, |
|
398 NULL, NULL, DummyAddr, // These parameters has no relevance with IETF_NATT_VID_DATA |
|
399 (TUint8*)DPD_VID_DATA, |
|
400 sizeof(DPD_VID_DATA)); |
|
401 } |
|
402 |
|
403 TBool CheckDPDVendorId(const TVendorISAKMP *aVendorPayload) |
|
404 { |
|
405 /**--------------------------------------------------------------------------------------- |
|
406 * |
|
407 * This method checks does the remote end support DPD draft <draft-ietf-ipsec-dpd-04.txt> |
|
408 * |
|
409 *---------------------------------------------------------------------------------------*/ |
|
410 TInt vid_lth = aVendorPayload->GetLength() - sizeof(TPayloadISAKMP); |
|
411 if ( vid_lth == sizeof(DPD_VID_DATA) ) |
|
412 { |
|
413 if ( Mem::Compare(aVendorPayload->VIDData(), vid_lth, (TUint8*)DPD_VID_DATA, vid_lth) == 0 ) |
|
414 return ETrue; // Remote end supports DPD draft |
|
415 } |
|
416 return EFalse; |
|
417 } |
|
418 |
|
419 TInt CheckCredentials(CIkeData *aHostData ) |
|
420 { |
|
421 /*------------------------------------------------------------------------- |
|
422 * |
|
423 * This function is called by CNegotiation::InitNegotiationL() method |
|
424 * when the current IKE proposal defines aggresssive mode exchange with |
|
425 * pre-shared key authentication. |
|
426 * The following special actions are taken: |
|
427 * -- If no pre-shared key data is defined, launch a dialog where |
|
428 * user name and password information is asked from the user. |
|
429 * -- User name information is store to current CIkeData iFQDN field |
|
430 * (represent IKE identification) |
|
431 * -- Password data shall be stored to current CIkeData iPresharedKey field |
|
432 * |
|
433 * This functionality is related to Checkpoint gateway. |
|
434 * To use Aggressive mode exchange and pre-shared key authentication like |
|
435 * this implement kind of "legacy authentication method" for IKE where |
|
436 * client (=initiator) authentication is based on user name/password pair. |
|
437 * User name is sent from initiator (=client) to responder (=Checkpoint GW) |
|
438 * in the IKE ID payload. However, the password data is NOT transmitted in |
|
439 * any payload, but it is used as pre-shared key in both ends. |
|
440 * (= Checkpoint gateway shall use user name data received in IKE ID payload |
|
441 * as a reference to the correct pre-shared key) |
|
442 * |
|
443 *------------------------------------------------------------------------*/ |
|
444 if ( !aHostData || aHostData->iPresharedKey.iKey.Length() ) |
|
445 return KErrNone; |
|
446 |
|
447 aHostData->iPresharedKey.iFormat = STRING_KEY; |
|
448 aHostData->iFQDN.SetLength(0); // Override FQDN in host data with user name |
|
449 |
|
450 return CIkev1Dialog::GetSyncUNPWDialog(aHostData->iFQDN, aHostData->iPresharedKey.iKey); |
|
451 } |
|
452 |
|
453 |
|
454 CInternalAddress* ProcessIntNetL(TINTNETISAKMP *aIntNetpayload) |
|
455 { |
|
456 /*------------------------------------------------------------------------- |
|
457 * |
|
458 * Process Internal address payload received (sanity check already done) |
|
459 * Process payload attributes as follows: |
|
460 * -- Parse PRI_INTERNAL_ADDRESS attribute and store value to aInternalAddr |
|
461 * -- Parse PRI_INTERNAL_DNS attributes and build list of DNS addresses |
|
462 * There exists an own attribute for all DNS addresses |
|
463 * -- Ignore other attributes (=PRI_INTERNAL_WINS) |
|
464 * |
|
465 * In this phase only IPv4 Internal addresses are supported by the |
|
466 * Nokia VPN gateway |
|
467 * |
|
468 *------------------------------------------------------------------------*/ |
|
469 TInt length = (TInt)aIntNetpayload->GetLength(); |
|
470 if ( STATIC_CAST(TUint, length) < sizeof(TINTNETISAKMP) ) { |
|
471 return NULL; |
|
472 } |
|
473 |
|
474 length -= sizeof(TINTNETISAKMP); /* Attribute data lengt in payload */ |
|
475 |
|
476 TUint32 ipv4_addr; |
|
477 TBool internal_address = EFalse; |
|
478 TInetAddr *dns_addr; |
|
479 CInternalAddress *InternalAddr = new (ELeave)CInternalAddress(1); |
|
480 CleanupStack::PushL(InternalAddr); |
|
481 TDataISAKMP *attr = aIntNetpayload->INTNETAttrib(); |
|
482 |
|
483 while ( length > 0 ) { |
|
484 |
|
485 length = length - attr->Size(); |
|
486 if ( length < 0 ) { |
|
487 CleanupStack::PopAndDestroy(); /* delete InternalAddr */ |
|
488 return NULL; |
|
489 } |
|
490 switch ( attr->Type() ) { |
|
491 |
|
492 case PRI_INTERNAL_ADDRESS: |
|
493 /*----------------------------------------------------------- |
|
494 * Internal address received from gateway. If several |
|
495 * Internal address attributes detected use the first address |
|
496 *------------------------------------------------------------*/ |
|
497 if ( attr->IsBasic() || ( attr->Length() != 4) ) { |
|
498 CleanupStack::PopAndDestroy(); /* delete InternalAddr */ |
|
499 return NULL; |
|
500 } |
|
501 if ( !internal_address ) { |
|
502 internal_address = ETrue; |
|
503 ipv4_addr = GET32(attr->VarValue()); |
|
504 ipv4_addr = ByteOrder::Swap32(ipv4_addr); //NOT IN NETWORK ORDER !!!! |
|
505 InternalAddr->iClientIntAddr.SetAddress(ipv4_addr); |
|
506 } |
|
507 break; |
|
508 |
|
509 case PRI_INTERNAL_DNS: |
|
510 /*----------------------------------------------------------- |
|
511 * Internal DNS address received from gateway |
|
512 *------------------------------------------------------------*/ |
|
513 if ( attr->IsBasic() || ( attr->Length() != 4 ) ) { |
|
514 CleanupStack::PopAndDestroy(); /* delete InternalAddr */ |
|
515 return NULL; |
|
516 } |
|
517 ipv4_addr = GET32(attr->VarValue()); |
|
518 ipv4_addr = ByteOrder::Swap32(ipv4_addr); //NOT IN NETWORK ORDER !!!! |
|
519 dns_addr = new(ELeave)TInetAddr; |
|
520 CleanupStack::PushL(dns_addr); |
|
521 dns_addr->SetAddress(ipv4_addr); |
|
522 InternalAddr->AppendL(dns_addr); |
|
523 CleanupStack::Pop(); /* delete dns_addr */ |
|
524 break; |
|
525 |
|
526 default: |
|
527 /*----------------------------------------------------------- |
|
528 * Other attributes (WINS address) are ignored |
|
529 *------------------------------------------------------------*/ |
|
530 break; |
|
531 } |
|
532 |
|
533 attr = attr->Next(); |
|
534 } |
|
535 |
|
536 if ( !internal_address ) { |
|
537 /*----------------------------------------------------- |
|
538 * No client internal address defined. |
|
539 * Internal address negotiation failed |
|
540 *----------------------------------------------------*/ |
|
541 delete InternalAddr; |
|
542 InternalAddr = NULL; |
|
543 } |
|
544 |
|
545 CleanupStack::Pop(); // Remove InternalAddr from cleanup stack |
|
546 |
|
547 return InternalAddr; |
|
548 } |
|
549 |
|
550 |