|
1 // Copyright (c) 2005-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 // IPSecPolicyManagerHandler.cpp - IPSec Policy Manager Handler |
|
15 // |
|
16 |
|
17 #include <es_sock.h> |
|
18 #include <in_sock.h> |
|
19 #include <es_ini.h> |
|
20 |
|
21 #include "ipsecpolmanhandler.h" |
|
22 #include "algorithmconf.h" |
|
23 #include "ipsecpolmanserver.h" |
|
24 #include "ipsecpolmansession.h" |
|
25 #include "ipsecpolapi.h" |
|
26 #include "ipsecpol.h" |
|
27 #include "log_ipsecpol.H" |
|
28 #include "ipsecpolparser.h" |
|
29 #include "secpolreader.h" |
|
30 |
|
31 #define FIRST_ARGUMENT 0 |
|
32 #define SECOND_ARGUMENT 1 |
|
33 #define THIRD_ARGUMENT 2 |
|
34 #define FOURTH_ARGUMENT 3 |
|
35 |
|
36 // |
|
37 // Create IPSecPolicyManagerHandler object |
|
38 // |
|
39 CIPSecPolicyManagerHandler* |
|
40 CIPSecPolicyManagerHandler::NewL(CIPSecPolicyManagerServer*) |
|
41 { |
|
42 LOG(Log::Printf(_L("Constructing IPSecPolManHandler\n"))); |
|
43 |
|
44 CIPSecPolicyManagerHandler* self = |
|
45 new (ELeave) CIPSecPolicyManagerHandler(); |
|
46 |
|
47 CleanupStack::PushL(self); |
|
48 self->ConstructL(); |
|
49 CleanupStack::Pop(); |
|
50 return self; |
|
51 } |
|
52 |
|
53 // |
|
54 // Phase 2 constructor |
|
55 // |
|
56 void |
|
57 CIPSecPolicyManagerHandler::ConstructL() |
|
58 { |
|
59 User::LeaveIfError(iFs.Connect()); |
|
60 User::LeaveIfError(iSS.Connect()); |
|
61 |
|
62 iActivePolicyList = new (ELeave) CActivePolicyList(1); |
|
63 |
|
64 iIsPreloadNeeded = EFalse; |
|
65 |
|
66 iPreloadPolicyHandle.iHandle = 0; |
|
67 |
|
68 |
|
69 #ifdef TESTFLAG |
|
70 |
|
71 iStringBuf = NULL; |
|
72 |
|
73 #endif |
|
74 |
|
75 ReadAlgorithmsFileL(); |
|
76 iSelectorInfoArray = new (ELeave) CArrayFixFlat<TIpsecSelectorInfo> (2); |
|
77 |
|
78 } |
|
79 |
|
80 // |
|
81 // Destructor |
|
82 // |
|
83 CIPSecPolicyManagerHandler::~CIPSecPolicyManagerHandler() |
|
84 { |
|
85 LOG(Log::Printf(_L("Destructing IPSecPolManHandler\n"))); |
|
86 |
|
87 // Unload the autoload policy if the load method is Preload, |
|
88 if (iPreloadPolicyHandle.iHandle > 0) |
|
89 { |
|
90 TRAPD(leaveCode, |
|
91 UnloadPolicyByHandleL(iPreloadPolicyHandle.iHandle, NULL)); |
|
92 |
|
93 if (leaveCode != KErrNone) |
|
94 { |
|
95 LOG(Log::Printf(_L("Unload autoload policy failed\n"))); |
|
96 } |
|
97 } |
|
98 |
|
99 // Corrected code |
|
100 if (iActivePolicyList) |
|
101 { |
|
102 // Deletes all the items in the list |
|
103 for (TInt i = iActivePolicyList->Count() - 1; i >= 0; i--) |
|
104 { |
|
105 |
|
106 if ( iActivePolicyList->At(i) != NULL ) |
|
107 { |
|
108 // Unloads still active policies |
|
109 TRAPD(leaveCode, |
|
110 UnloadPolicyByHandleL(iActivePolicyList->At(i)->iPolicyHandle.iHandle, NULL)); |
|
111 |
|
112 if (leaveCode != KErrNone) |
|
113 { |
|
114 LOG(Log::Printf(_L("Unload autoload policy failed\n"))); |
|
115 } |
|
116 |
|
117 } |
|
118 } |
|
119 |
|
120 delete iActivePolicyList; |
|
121 iActivePolicyList = NULL; |
|
122 } |
|
123 |
|
124 delete iSecpolReader6; |
|
125 iSecpolReader6 = NULL; |
|
126 |
|
127 delete iLastConflictInfo; |
|
128 iLastConflictInfo = NULL; |
|
129 |
|
130 delete iLastParsingErrorInfo; |
|
131 iLastParsingErrorInfo = NULL; |
|
132 |
|
133 delete iAlgorithmsHBufC8; |
|
134 iAlgorithmsHBufC8 = NULL; |
|
135 |
|
136 delete iPreloadPolicy; |
|
137 iPreloadPolicy = NULL; |
|
138 |
|
139 delete iBeforeManualLoadPolicy; |
|
140 iBeforeManualLoadPolicy = NULL; |
|
141 |
|
142 delete iAfterManualLoadPolicy; |
|
143 iAfterManualLoadPolicy = NULL; |
|
144 |
|
145 delete iBeforeScopedLoadPolicy; |
|
146 iBeforeScopedLoadPolicy = NULL; |
|
147 |
|
148 delete iAfterScopedLoadPolicy; |
|
149 iAfterScopedLoadPolicy = NULL; |
|
150 |
|
151 #ifdef TESTFLAG |
|
152 |
|
153 delete iStringBuf; |
|
154 iStringBuf = NULL; |
|
155 |
|
156 #endif |
|
157 |
|
158 // Release scoped autoload policy array |
|
159 for (TInt i = iScopedAutoloadPolicyPairs.Count() - 1; i >= 0; i--) |
|
160 { |
|
161 delete iScopedAutoloadPolicyPairs[i]; |
|
162 iScopedAutoloadPolicyPairs.Remove(i); |
|
163 } |
|
164 |
|
165 // Close array to avoid memory leaks |
|
166 iScopedAutoloadPolicyPairs.Close(); |
|
167 |
|
168 ReleaseResources(); |
|
169 |
|
170 iFs.Close(); |
|
171 iSS.Close(); |
|
172 |
|
173 delete iSelectorInfoArray; |
|
174 iSelectorInfoArray = NULL; |
|
175 } |
|
176 |
|
177 // |
|
178 // Release resources allocated for a call |
|
179 // |
|
180 void |
|
181 CIPSecPolicyManagerHandler::ReleaseResources() |
|
182 { |
|
183 delete iPieceData; |
|
184 iPieceData = NULL; |
|
185 |
|
186 delete iPieceData2; |
|
187 iPieceData2 = NULL; |
|
188 |
|
189 delete iSAInfo; |
|
190 iSAInfo = NULL; |
|
191 |
|
192 delete iSelectorInfo; |
|
193 iSelectorInfo = NULL; |
|
194 |
|
195 delete iPolicyHBufC8; |
|
196 iPolicyHBufC8 = NULL; |
|
197 |
|
198 delete iPolBfr; |
|
199 iPolBfr = NULL; |
|
200 |
|
201 #ifdef TESTFLAG |
|
202 |
|
203 delete iHandles; |
|
204 iHandles = NULL; |
|
205 |
|
206 #endif |
|
207 |
|
208 if (iSecpolSocketOpen) |
|
209 { |
|
210 iSecpolSocketOpen = EFalse; |
|
211 iSock.Close(); |
|
212 } |
|
213 |
|
214 if (iAlgorithmsFileOpen) |
|
215 { |
|
216 iAlgorithmsFileOpen = EFalse; |
|
217 iAlgFile.Close(); |
|
218 } |
|
219 } |
|
220 |
|
221 // |
|
222 // ErrorHandling - Leave is trapped by server's RunError() |
|
223 // |
|
224 void |
|
225 CIPSecPolicyManagerHandler::ErrorHandlingL( |
|
226 TInt aMainCode, |
|
227 TInt aDetailCode) |
|
228 { |
|
229 LOG(Log::Printf(_L("ErrorHandling: main status: %d detail status: %d\n"), |
|
230 aMainCode, aDetailCode)); |
|
231 #ifndef __FLOG_ACTIVE |
|
232 (void)aDetailCode; |
|
233 #endif |
|
234 |
|
235 User::Leave(aMainCode); |
|
236 } |
|
237 |
|
238 // |
|
239 // |
|
240 // ProcessLoadPolicy - Process a LoadPolicy request issued |
|
241 // by IPSecPolicyManApi |
|
242 // |
|
243 // |
|
244 TInt |
|
245 CIPSecPolicyManagerHandler::ProcessLoadPolicyL( |
|
246 const RMessage2& aMsg, |
|
247 const CIPSecPolicyManagerSession* /* aIPSecPolicyManagerSession */, |
|
248 TPolicyType aPolType) |
|
249 { |
|
250 // Retrieve arguments |
|
251 |
|
252 // (1): Policy data buffer length |
|
253 TInt policyDataLth = aMsg.GetDesLengthL(FIRST_ARGUMENT); |
|
254 |
|
255 // (2): Policy data buffer contents |
|
256 delete iPolicyHBufC8; |
|
257 iPolicyHBufC8 = NULL; |
|
258 iPolicyHBufC8 = HBufC8::NewL(policyDataLth); |
|
259 TPtr8 policyDataDesc(iPolicyHBufC8->Des()); |
|
260 aMsg.ReadL(FIRST_ARGUMENT, policyDataDesc); |
|
261 |
|
262 // (3): Zone info (optional) |
|
263 TZoneInfoSet zoneInfoSet; |
|
264 if (aMsg.GetDesLength(THIRD_ARGUMENT) <= 0) |
|
265 { |
|
266 zoneInfoSet = KDefaultZoneInfo; |
|
267 iFunction = 0; |
|
268 } |
|
269 else |
|
270 { |
|
271 iFunction = aMsg.Int3(); |
|
272 TPckg<TZoneInfoSet>pckgZoneInfoSet(zoneInfoSet); |
|
273 aMsg.ReadL(THIRD_ARGUMENT, pckgZoneInfoSet); |
|
274 } |
|
275 iVPNNetId = 0; |
|
276 if (zoneInfoSet.iSelectorZone.iScope != KScopeNone) |
|
277 { |
|
278 iVPNNetId = zoneInfoSet.iSelectorZone.iId; |
|
279 } |
|
280 iGwNetId = 0; |
|
281 if (zoneInfoSet.iEndPointZone.iScope != KScopeNone) |
|
282 { |
|
283 iGwNetId = zoneInfoSet.iEndPointZone.iId; |
|
284 } |
|
285 LOG(Log::Printf(_L("LoadPolicy request VPN NetId: %d GW NetId: %d\n"), |
|
286 iVPNNetId, iGwNetId)); |
|
287 |
|
288 |
|
289 // Parse the policy file from string format to the ipsecpolparser |
|
290 // class object format |
|
291 ParseCurrentPolicyL(); |
|
292 |
|
293 // Calculate the Bypass/Drop mode of parsed policy |
|
294 TInt policyBypassDropMode(KDropMode); |
|
295 CSecurityPolicy* policy = iPieceData->Policies(); |
|
296 policyBypassDropMode = CalculatePolicyBypassDropMode(*policy); |
|
297 |
|
298 // Check if we have a direct Bypass-everything-else Vs Drop-everything-else conflict between the active policy and |
|
299 // the one that is attempted to be loaded. If so, return with error |
|
300 |
|
301 TInt activepolicyBypassDropMode; |
|
302 //coverity[var_compare_op] |
|
303 //intentional null comparision if there is no policylist do nothing. |
|
304 if (iActivePolicyList && iActivePolicyList->Count()) |
|
305 { |
|
306 //coverity[var_compare_op] |
|
307 // It is ok to compare with the first active policy. Every subsequent policy would have been compared against the first one |
|
308 activepolicyBypassDropMode = iActivePolicyList->At(0)->iBypassOrDropMode; |
|
309 if((policyBypassDropMode == KDropMode && (( activepolicyBypassDropMode & KInboundBypass) || (activepolicyBypassDropMode & KOutboundBypass))) || |
|
310 (((policyBypassDropMode & KInboundBypass) || (policyBypassDropMode & KOutboundBypass)) && activepolicyBypassDropMode == KDropMode )) |
|
311 { |
|
312 ErrorHandlingL (ESelectorConflict,0); |
|
313 } |
|
314 } |
|
315 |
|
316 // Add VPNNetId to CPolicySelector and GwNetId to CSecpolBundleItem objects |
|
317 UpdateSelectorsAndTunnels(); |
|
318 |
|
319 // Check if the IP addresses in the selectors of current policy |
|
320 // file overlaps with the selectors of the policies in the active |
|
321 // policy list. Overlapping is allowed when the scope IDs differ |
|
322 // or all parameters in the selectors and corresponding SA |
|
323 // match exactly. |
|
324 CheckSelectorConflictsL(); |
|
325 |
|
326 // Modify the SA names to avoid conflicts caused by equal names |
|
327 // in different policies |
|
328 MakeUniqueSANamesL(); |
|
329 |
|
330 // Convert object format policy pieces to string format |
|
331 // and do the operations defined by the API flags |
|
332 ConvertFromObjectsToStringWithSectionsL(iFunction, |
|
333 policyBypassDropMode); |
|
334 |
|
335 // Store current policy entry to active policy list |
|
336 StorePolicyToActiveListL(aPolType, policyBypassDropMode); |
|
337 LOG(Log::Printf(_L("LoadPolicy request completed OK, handle: %d\n"), |
|
338 iCurrentPolicyHandle.iHandle)); |
|
339 |
|
340 // Return the current policy file handle to the API user |
|
341 ReturnPolicyFileHandleL(aMsg); |
|
342 |
|
343 // An API call completed |
|
344 ApiCallCompleted(); |
|
345 return KErrNone; |
|
346 } |
|
347 |
|
348 // |
|
349 // |
|
350 // ProcessLoadPoliciesL - Process a LoadPolicy request issued |
|
351 // by IPSecPolicyManApi. This method considers autoload policies as well |
|
352 // |
|
353 // |
|
354 TInt |
|
355 CIPSecPolicyManagerHandler::ProcessLoadPoliciesL( |
|
356 const RMessage2& aMsg, |
|
357 const CIPSecPolicyManagerSession* aSession) |
|
358 { |
|
359 // Read scope information |
|
360 TBool scopedLoad = EFalse; |
|
361 TInt preLoadHandle(0); |
|
362 TInt postLoadHandle(0); |
|
363 TInt parentPolicyHandle(0); |
|
364 TInt leaveCode(0); |
|
365 |
|
366 TZoneInfoSet zoneInfoSet; |
|
367 if (aMsg.GetDesLength(THIRD_ARGUMENT) <= 0) // Use default zoneInfo |
|
368 { |
|
369 zoneInfoSet = KDefaultZoneInfo; |
|
370 |
|
371 // Processing flags |
|
372 iFunction = 0; |
|
373 } |
|
374 else |
|
375 { |
|
376 scopedLoad = ETrue; |
|
377 iFunction = aMsg.Int3(); |
|
378 TPckg<TZoneInfoSet>pckgZoneInfoSet(zoneInfoSet); |
|
379 aMsg.ReadL(THIRD_ARGUMENT, pckgZoneInfoSet); |
|
380 } |
|
381 iVPNNetId = 0; |
|
382 if (zoneInfoSet.iSelectorZone.iScope != KScopeNone) |
|
383 { |
|
384 iVPNNetId = zoneInfoSet.iSelectorZone.iId; |
|
385 } |
|
386 iGwNetId = 0; |
|
387 if (zoneInfoSet.iEndPointZone.iScope != KScopeNone) |
|
388 { |
|
389 iGwNetId = zoneInfoSet.iEndPointZone.iId; |
|
390 } |
|
391 |
|
392 LOG(Log::Printf(_L("LoadPolicy request VPN NetId: %d GW NetId: %d\n"), |
|
393 iVPNNetId, iGwNetId)); |
|
394 |
|
395 if (scopedLoad) |
|
396 { |
|
397 // Load BeforescopedLoadPolicies before |
|
398 if (iBeforeScopedLoadPolicy->Size() != 0) |
|
399 { |
|
400 TRAP(leaveCode, |
|
401 AutoloadPoliciesL(zoneInfoSet, |
|
402 iBeforeScopedLoadPolicy, |
|
403 EAutoloadBeforeScopedLoad)); |
|
404 if (leaveCode != KErrNone) |
|
405 { |
|
406 LOG(Log::Printf(_L("Autoload failed for parent policy: %d\n"), |
|
407 aMsg.Int0())); |
|
408 } |
|
409 else |
|
410 { |
|
411 preLoadHandle = iCurrentPolicyHandle.iHandle; |
|
412 } |
|
413 } |
|
414 |
|
415 // Load the policy itself |
|
416 ProcessLoadPolicyL(aMsg, aSession, EScopedManualLoad); |
|
417 parentPolicyHandle = iCurrentPolicyHandle.iHandle; |
|
418 |
|
419 // Load BeforescopedLoadPolicies before |
|
420 if (iAfterScopedLoadPolicy->Size() != 0 ) |
|
421 { |
|
422 TRAP(leaveCode, |
|
423 AutoloadPoliciesL(zoneInfoSet, |
|
424 iAfterScopedLoadPolicy, |
|
425 EAutoloadAfterScopedLoad)); |
|
426 |
|
427 if (leaveCode != KErrNone) |
|
428 { |
|
429 LOG(Log::Printf(_L("Autoload failed for parent policy: %d\n"), |
|
430 aMsg.Int0())); |
|
431 } |
|
432 else |
|
433 { |
|
434 postLoadHandle = iCurrentPolicyHandle.iHandle; |
|
435 } |
|
436 } |
|
437 |
|
438 if (parentPolicyHandle != 0 |
|
439 && (preLoadHandle != 0 || postLoadHandle != 0)) |
|
440 { |
|
441 // Add the policy hadle pair to an 'unload list' |
|
442 AddScopedAutoloadPolicyPairL(preLoadHandle, |
|
443 postLoadHandle, |
|
444 parentPolicyHandle); |
|
445 } |
|
446 } |
|
447 else |
|
448 { |
|
449 // In case of manual load |
|
450 if (iManualAutoloadHandlePair.iManualPreloadHandle.iHandle == 0 |
|
451 && iManualAutoloadHandlePair.iManualPostLoadHandle.iHandle == 0) |
|
452 { |
|
453 // Load BeforescopedLoadPolicies before |
|
454 if (iBeforeManualLoadPolicy->Size() != 0) |
|
455 { |
|
456 TRAP(leaveCode, |
|
457 AutoloadPoliciesL(zoneInfoSet, |
|
458 iBeforeManualLoadPolicy, |
|
459 EAutoloadBeforeManualLoad)); |
|
460 if (leaveCode != KErrNone) |
|
461 { |
|
462 LOG(Log::Printf(_L("Autoload failed for parent policy: %d\n"), |
|
463 aMsg.Int0() )); |
|
464 } |
|
465 else |
|
466 { |
|
467 iManualAutoloadHandlePair.iManualPreloadHandle.iHandle = |
|
468 iCurrentPolicyHandle.iHandle; |
|
469 } |
|
470 } |
|
471 |
|
472 // Load the policy itself |
|
473 ProcessLoadPolicyL(aMsg, aSession, EManualLoad); |
|
474 |
|
475 // Load AfterManualLoadPolicies |
|
476 if (iAfterManualLoadPolicy->Size() != 0) |
|
477 { |
|
478 TRAP(leaveCode, |
|
479 AutoloadPoliciesL(zoneInfoSet, |
|
480 iAfterManualLoadPolicy, |
|
481 EAutoloadAfterManualLoad)); |
|
482 if (leaveCode != KErrNone) |
|
483 { |
|
484 LOG(Log::Printf(_L("Autoload failed for parent policy: %d\n"), |
|
485 aMsg.Int0() )); |
|
486 } |
|
487 else |
|
488 { |
|
489 iManualAutoloadHandlePair.iManualPostLoadHandle.iHandle = |
|
490 iCurrentPolicyHandle.iHandle; |
|
491 } |
|
492 } |
|
493 } |
|
494 else |
|
495 { |
|
496 // Load the policy itself |
|
497 ProcessLoadPolicyL(aMsg, aSession, EManualLoad); |
|
498 } |
|
499 |
|
500 } |
|
501 |
|
502 return KErrNone; |
|
503 } |
|
504 |
|
505 // |
|
506 // |
|
507 // ProcessActivatePolicy - Process an ActivatePolicy request issued |
|
508 // by IPSecPolicyManApi |
|
509 // |
|
510 // |
|
511 TInt |
|
512 CIPSecPolicyManagerHandler::ProcessActivatePolicyL( |
|
513 const RMessage2& aMsg, |
|
514 const CIPSecPolicyManagerSession* aIPSecPolicyManagerSession) |
|
515 { |
|
516 // Store the parameters to this object |
|
517 iSession = aIPSecPolicyManagerSession; |
|
518 iCurrentPolicyHandle.iHandle = aMsg.Int0(); |
|
519 |
|
520 LOG(Log::Printf(_L("ActivatePolicy request, handle: %d\n"), |
|
521 iCurrentPolicyHandle.iHandle)); |
|
522 |
|
523 // Search from the active policy list the policy corresponding |
|
524 // to the current policy handle and activate it |
|
525 TInt ret = SearchPolicyFromListAndActivate(); |
|
526 if (ret != KErrNone) |
|
527 { |
|
528 ErrorHandlingL(ret, 0 ); |
|
529 } |
|
530 |
|
531 // Parse all active policy files from string format |
|
532 // to IPSecPolParser class object formats |
|
533 ParseAllPolicyFilesL(); |
|
534 |
|
535 // Calculate the combined policy Bypass/Drop mode |
|
536 CalculateCombinedPolicyBypassDropMode(); |
|
537 |
|
538 // Delete all pure Inbound/Ooutbound selectors |
|
539 DeleteExtraInboundOutboundSelectors(); |
|
540 |
|
541 // Update the policy selectors by building a comparison word |
|
542 // and setting a sequence number. IpsecPolParser uses them. |
|
543 SortSelectors(); |
|
544 |
|
545 // Convert object format policy pieces to string format. |
|
546 // This format is used by IPSec protocol component. |
|
547 ConvertFromObjectsToStringWithoutSectionsL(); |
|
548 |
|
549 // Add an Inbound/outbound selector pair to the end of string format |
|
550 // policy file. This occurs only when the bypass mode is defined. |
|
551 TInt err = AddInboundOutboundSelectorPair(); |
|
552 if (err != KErrNone) |
|
553 { |
|
554 ErrorHandlingL(ENoMemory, err); |
|
555 } |
|
556 |
|
557 // Send the algorithms table and the string format policy file to |
|
558 // IPSec protocol component using Secpol socket |
|
559 SendAlgorithmsAndPolicyToIPSecL(_L("secpol6")); |
|
560 |
|
561 LOG(Log::Printf(_L("ActivatePolicy request completed OK, handle: %d\n"), |
|
562 iCurrentPolicyHandle.iHandle)); |
|
563 |
|
564 // An API call completed |
|
565 ApiCallCompleted(); |
|
566 return KErrNone; |
|
567 } |
|
568 |
|
569 // |
|
570 // |
|
571 // ProcessActivateAutoloadPolicy - Process an ActivatePolicy request issued |
|
572 // by IPSecPolicyManApi |
|
573 // |
|
574 // |
|
575 TInt |
|
576 CIPSecPolicyManagerHandler::ProcessActivateAutoloadPolicyL( |
|
577 const CIPSecPolicyManagerSession* aIPSecPolicyManagerSession) |
|
578 { |
|
579 // Store the parameters to this object |
|
580 iSession = aIPSecPolicyManagerSession; |
|
581 |
|
582 LOG(Log::Printf(_L("ActivateAutoloadPolicy request, handle: %d\n"), |
|
583 iCurrentPolicyHandle.iHandle)); |
|
584 |
|
585 // Search from the active policy list the policy corresponding |
|
586 // to the current policy handle and activate it |
|
587 TInt ret = SearchPolicyFromListAndActivate(); |
|
588 if (ret != KErrNone) |
|
589 { |
|
590 ErrorHandlingL(ret, 0 ); |
|
591 } |
|
592 |
|
593 // Parse all active policy files from string format |
|
594 // to IPSecPolParser class object formats |
|
595 ParseAllPolicyFilesL(); |
|
596 |
|
597 // Calculate the combined policy Bypass/Drop mode |
|
598 CalculateCombinedPolicyBypassDropMode(); |
|
599 |
|
600 // Delete all pure Inbound/Ooutbound selectors |
|
601 DeleteExtraInboundOutboundSelectors(); |
|
602 |
|
603 // Update the policy selectors by building a comparison word |
|
604 // and setting a sequence number. IpsecPolParser uses them. |
|
605 SortSelectors(); |
|
606 |
|
607 // Convert object format policy pieces to string format. |
|
608 // This format is used by IPSec protocol component. |
|
609 ConvertFromObjectsToStringWithoutSectionsL(); |
|
610 |
|
611 // Add an Inbound/outbound selector pair to the end of string format |
|
612 // policy file. This occurs only when the bypass mode is defined. |
|
613 TInt err = AddInboundOutboundSelectorPair(); |
|
614 if (err != KErrNone) |
|
615 { |
|
616 ErrorHandlingL(ENoMemory, err); |
|
617 } |
|
618 |
|
619 // Send the algorithms table and the string format policy file to |
|
620 // IPSec protocol component using Secpol socket |
|
621 SendAlgorithmsAndPolicyToIPSecL(_L("secpol6")); |
|
622 |
|
623 LOG(Log::Printf(_L("ActivateAutoloadPolicy request completed OK, handle: %d\n"), |
|
624 iCurrentPolicyHandle.iHandle)); |
|
625 |
|
626 // An API call completed |
|
627 ApiCallCompleted(); |
|
628 return KErrNone; |
|
629 } |
|
630 |
|
631 |
|
632 // |
|
633 // Process UnloadPolicy - Process an UnloadPolicy request issued |
|
634 // by IPSecPolicyManApi |
|
635 // |
|
636 TInt |
|
637 CIPSecPolicyManagerHandler::ProcessUnloadPolicyL( |
|
638 const RMessage2& aMsg, |
|
639 const CIPSecPolicyManagerSession* aIPSecPolicyManagerSession) |
|
640 { |
|
641 // Store the parameters to this object |
|
642 iSession = aIPSecPolicyManagerSession; |
|
643 |
|
644 iCurrentPolicyHandle.iHandle = aMsg.Int0(); |
|
645 LOG(Log::Printf(_L("UnloadPolicy request, handle: %d\n"), |
|
646 iCurrentPolicyHandle.iHandle)); |
|
647 |
|
648 // Search from the active policy list the policy corresponding |
|
649 // to the current policy handle and delete it |
|
650 TInt ret = DeletePolicyFromList(); |
|
651 if (ret != KErrNone) |
|
652 { |
|
653 ErrorHandlingL(ret, 0 ); |
|
654 } |
|
655 |
|
656 // Send BypassAll file to the IPSec protocol component if |
|
657 // the deleted policy was the last one |
|
658 if (iActivePolicyList->Count() == 0) |
|
659 { |
|
660 SendNullFileToIPSecL(_L("secpol6")); |
|
661 LOG(Log::Printf(_L("Last policy deleted\n"))); |
|
662 LOG(Log::Printf(_L("UnLoadPolicy request completed OK, handle: %d\n"), |
|
663 iCurrentPolicyHandle.iHandle)); |
|
664 |
|
665 // An API call completed |
|
666 ApiCallCompleted(); |
|
667 return KErrNone; |
|
668 } |
|
669 |
|
670 // Parse all active policy files from string format |
|
671 // to IPSecPolParser class object formats |
|
672 ParseAllPolicyFilesL(); |
|
673 |
|
674 // Calculate whether it's drop or bypass mode to be used |
|
675 CalculateCombinedPolicyBypassDropMode(); |
|
676 |
|
677 // Delete pure Inbound/Outbound selectors |
|
678 DeleteExtraInboundOutboundSelectors(); |
|
679 |
|
680 // Update the policy selectors by building a comparison word |
|
681 // and setting a sequence number |
|
682 SortSelectors(); |
|
683 |
|
684 // Convert object format policy pieces to string format. |
|
685 // This format is used by IPSec protocol component. |
|
686 ConvertFromObjectsToStringWithoutSectionsL(); |
|
687 |
|
688 // Add an Inbound/outbound selector pair to the end of string format |
|
689 // policy file. This occurs only when the bypass mode is defined. |
|
690 TInt err = AddInboundOutboundSelectorPair(); |
|
691 if (err != KErrNone) |
|
692 { |
|
693 ErrorHandlingL(ENoMemory, err); |
|
694 } |
|
695 |
|
696 // Send the algorithms table and the string format policy file to |
|
697 // IPSec protocol component using Secpol socket |
|
698 SendAlgorithmsAndPolicyToIPSecL(_L("secpol6")); |
|
699 |
|
700 // An API call completed |
|
701 LOG(Log::Printf(_L("UnloadPolicy request completed OK, handle: %d\n"), |
|
702 iCurrentPolicyHandle.iHandle)); |
|
703 ApiCallCompleted(); |
|
704 return KErrNone; |
|
705 } |
|
706 |
|
707 // |
|
708 // Convert the object format policy pieces to string format |
|
709 // and do the operations defined by the function code. |
|
710 // Section Data, for example, [POLICY], is included |
|
711 // |
|
712 void |
|
713 CIPSecPolicyManagerHandler::ConvertFromObjectsToStringWithSectionsL( |
|
714 TInt aFunction, |
|
715 TInt aBypassDropMode) |
|
716 { |
|
717 // Constant for adding Mip4 bypass selectors to the policy |
|
718 // TODO: |
|
719 // This constant should be defined in Policy Manager API |
|
720 // header files |
|
721 const TInt KAddMip4BypassSelectors = (1 << 3); |
|
722 |
|
723 // Allocate a buffer for string format policy |
|
724 delete iPolBfr; |
|
725 iPolBfr = NULL; |
|
726 iPolBfr = HBufC8::NewL(KPolicyBufferSizeIncrement); |
|
727 |
|
728 // Convert and write policy data to a policy buffer |
|
729 TInt err = TIpSecParser::Write(iPieceData, iPolBfr); |
|
730 if (err != KErrNone) |
|
731 { |
|
732 ErrorHandlingL(ENoMemory, err); |
|
733 } |
|
734 |
|
735 // Check if given policy contains 'drop_everything_else' rule |
|
736 // and add IKE, DHCP and MIPv4 bypass selectors if necessary |
|
737 if (aBypassDropMode == KDropMode) |
|
738 { |
|
739 // Allow plain IKE negotiation packets. Write the bypass |
|
740 // selectors to the end of selector list, but they will |
|
741 // later be sorted to the beginning of selectors. |
|
742 if (aFunction & KAddIkeBypassSelectors) |
|
743 { |
|
744 TInt err = WriteTunnelModeIkeNegotiationStringsL(iPolBfr); |
|
745 if (err != KErrNone) |
|
746 { |
|
747 ErrorHandlingL(ENoMemory, err); |
|
748 } |
|
749 |
|
750 err = WriteTransportModeIkeNegotiationStrings(iPolBfr); |
|
751 if (err != KErrNone) |
|
752 { |
|
753 ErrorHandlingL(ENoMemory, err); |
|
754 } |
|
755 } |
|
756 |
|
757 // Allow plain DHCP negotiation packets. Write bypass mode |
|
758 // selectors for DHCP ports (67, 68) to the end of selector list. |
|
759 if (aFunction & KAddDhcpBypassSelectors) |
|
760 { |
|
761 TInt err = BuildDhcpProtocolString(iPolBfr); |
|
762 if (err != KErrNone) |
|
763 { |
|
764 ErrorHandlingL(ENoMemory, err); |
|
765 } |
|
766 } |
|
767 |
|
768 // Allow plain MIPv4 (Mobile IP v4) packets. Write bypass mode |
|
769 // selectors for MIPv4 to the end of selector list. |
|
770 if (aFunction & KAddMip4BypassSelectors) |
|
771 { |
|
772 TInt err = BuildMip4BypassSelectors(iPolBfr); |
|
773 if (err != KErrNone) |
|
774 { |
|
775 ErrorHandlingL(ENoMemory, err); |
|
776 } |
|
777 } |
|
778 } |
|
779 } |
|
780 |
|
781 // |
|
782 // Convert object format policy pieces to string format. |
|
783 // Section Data is not included |
|
784 // |
|
785 void |
|
786 CIPSecPolicyManagerHandler::ConvertFromObjectsToStringWithoutSectionsL() |
|
787 { |
|
788 // Allocate a buffer for string format policy |
|
789 delete iPolBfr; |
|
790 iPolBfr = NULL; |
|
791 iPolBfr = HBufC8::NewL(KPolicyBufferSizeIncrement); |
|
792 |
|
793 // Convert and write policy data to a policy buffer |
|
794 TInt err = TPolicyParser::Write(iPieceData->Policies(), iPolBfr, ETrue); |
|
795 if (err != KErrNone) |
|
796 { |
|
797 ErrorHandlingL(ENoMemory, err); |
|
798 } |
|
799 } |
|
800 |
|
801 // |
|
802 // Store a policy entry to the policy list |
|
803 // |
|
804 void |
|
805 CIPSecPolicyManagerHandler::StorePolicyToActiveListL( |
|
806 TPolicyType aPolType, |
|
807 TInt aBypassOrDropMode) |
|
808 { |
|
809 // Take the next policy file handle |
|
810 iNextPolicyHandle.iHandle++; |
|
811 iCurrentPolicyHandle.iHandle = iNextPolicyHandle.iHandle; |
|
812 |
|
813 // Update an active policy entry |
|
814 TActivePolicyListEntry* entry = new (ELeave) TActivePolicyListEntry; |
|
815 CleanupStack::PushL(entry); |
|
816 entry->iActiveState = EFalse; |
|
817 entry->iBypassOrDropMode = aBypassOrDropMode; |
|
818 entry->iPolicyHandle.iHandle = iCurrentPolicyHandle.iHandle; |
|
819 entry->iPolicyBuf = iPolBfr; |
|
820 entry->iPolicyType = aPolType; |
|
821 iPolBfr = NULL; |
|
822 CleanupStack::PushL(entry->iPolicyBuf); |
|
823 |
|
824 // Store a new entry to active policy list |
|
825 iActivePolicyList->AppendL(entry); |
|
826 CleanupStack::Pop(2); |
|
827 } |
|
828 |
|
829 // |
|
830 // Parse all active policy files from string format |
|
831 // to IPSecPolParser class object format |
|
832 // |
|
833 void |
|
834 CIPSecPolicyManagerHandler::ParseAllPolicyFilesL() |
|
835 { |
|
836 delete iPieceData; |
|
837 iPieceData = NULL; |
|
838 iPieceData = new (ELeave) CIpSecurityPiece; |
|
839 iPieceData->ConstructL(); |
|
840 |
|
841 for (TInt i = 0; i < iActivePolicyList->Count(); i++) |
|
842 { |
|
843 // Check if policy activated |
|
844 if (iActivePolicyList->At(i)->iActiveState == EFalse) |
|
845 { |
|
846 continue; |
|
847 } |
|
848 |
|
849 // Store policy to IPSecPolParser |
|
850 HBufC8* policyHBufC8 = iActivePolicyList->At(i)->iPolicyBuf; |
|
851 |
|
852 // Copy policy to 16bit buffer |
|
853 TPtr8 ptr8(policyHBufC8->Des()); |
|
854 TInt length = ptr8.Length(); |
|
855 HBufC *policyDataHBufC16 = HBufC::NewL(length); |
|
856 CleanupStack::PushL(policyDataHBufC16); |
|
857 TPtr ptr(policyDataHBufC16->Des()); |
|
858 |
|
859 // Parse policy into binary object format |
|
860 ptr.Copy(ptr8); |
|
861 TIpSecParser parser(ptr); |
|
862 TInt err = parser.ParseAndIgnoreIKEL(iPieceData); |
|
863 |
|
864 // Delete policyDataHBufC16; |
|
865 CleanupStack::PopAndDestroy(); |
|
866 |
|
867 if (err != KErrNone) |
|
868 { |
|
869 ErrorHandlingL(EParsingError, err); |
|
870 } |
|
871 } |
|
872 } |
|
873 |
|
874 // |
|
875 // Sort the selectors in the following sequence: |
|
876 // -- Port 500 or 4500 is defined for selector |
|
877 // -- Port 67 or 68 is defined |
|
878 // -- All other selectors are in original order |
|
879 // |
|
880 void |
|
881 CIPSecPolicyManagerHandler::SortSelectors() |
|
882 { |
|
883 CSecurityPolicy* sp = iPieceData->Policies(); |
|
884 CSelectorList* selectorList = sp->SelectorList(); |
|
885 BuildComparisonWord(selectorList); |
|
886 SetSequenceNumbers(selectorList); |
|
887 } |
|
888 |
|
889 // |
|
890 // Send the algorithms file and string format policy file to |
|
891 // IPSec protocol component using Secpol socket |
|
892 // |
|
893 void |
|
894 CIPSecPolicyManagerHandler::SendAlgorithmsAndPolicyToIPSecL( |
|
895 const TDesC &aSocket) |
|
896 { |
|
897 TInt err(KErrNone); |
|
898 TInt algSize(0), polSize(0), sendBuf(0), octetSize(0); |
|
899 |
|
900 TInetAddr addr; |
|
901 TRequestStatus stat; |
|
902 |
|
903 // Open Secpol socket |
|
904 err = iSock.Open(iSS, aSocket); |
|
905 if (err != KErrNone) |
|
906 { |
|
907 ErrorHandlingL(EOpenSocketError, err); |
|
908 } |
|
909 iSecpolSocketOpen = ETrue; |
|
910 |
|
911 // Bind to socket |
|
912 addr.SetAddress(KInetAddrNone); |
|
913 addr.SetPort(0); |
|
914 err = iSock.Bind(addr); |
|
915 if (err != KErrNone) |
|
916 { |
|
917 ErrorHandlingL(EBindSocketError, err); |
|
918 } |
|
919 iSock.LocalName(addr); |
|
920 |
|
921 |
|
922 // Get algorithm table size and police file size |
|
923 if (iAlgorithmsHBufC8 != NULL) |
|
924 { |
|
925 algSize = iAlgorithmsHBufC8->Length(); |
|
926 } |
|
927 polSize = iPolBfr->Des().Length(); |
|
928 |
|
929 // Allocate a buffer for the algorithms data and policy data |
|
930 HBufC8 *buf = HBufC8::NewLC(algSize + polSize); // Both files |
|
931 TPtr8 algPtr((TUint8 *)buf->Ptr(), algSize, algSize); |
|
932 TPtr8 polPtr((TUint8 *)buf->Ptr() + algSize, polSize, polSize); |
|
933 |
|
934 if (iAlgorithmsHBufC8 != NULL) |
|
935 { |
|
936 algPtr.Copy(*iAlgorithmsHBufC8); |
|
937 } |
|
938 |
|
939 // Store the policy buffer data after algorithm data |
|
940 // and free the policy buffer |
|
941 polPtr.Copy(iPolBfr->Des()); |
|
942 delete iPolBfr; |
|
943 iPolBfr = NULL; |
|
944 |
|
945 // Currently, the policy loading requires the policy data in a |
|
946 // single contiguous buffer. If the socket buffer is less than |
|
947 // policy file length, then increase the buffer size! |
|
948 |
|
949 // *2 because _UNICODE |
|
950 octetSize = 2 * (algSize + polSize); |
|
951 sendBuf = -1; |
|
952 err = iSock.GetOpt(KSOSendBuf, KSOLSocket, sendBuf); |
|
953 if (sendBuf < octetSize) |
|
954 { |
|
955 err = iSock.SetOpt(KSOSendBuf, KSOLSocket, octetSize); |
|
956 } |
|
957 if (err != KErrNone) |
|
958 { |
|
959 // The buffer holding the 8-bit data in the file |
|
960 CleanupStack::PopAndDestroy(); |
|
961 ErrorHandlingL(ESecpolSocketSetOptError, err); |
|
962 } |
|
963 |
|
964 // Set buffer address |
|
965 HBufC *data = HBufC::NewL(algSize + polSize); |
|
966 TPtr ptr16(data->Des()); |
|
967 TPtrC8 ptr((TUint8 *)buf->Ptr(), algSize + polSize); |
|
968 |
|
969 // For debug |
|
970 ptr16.Copy(ptr); |
|
971 |
|
972 #ifdef TESTFLAG |
|
973 |
|
974 // TODO: Copy the concatenated string for testing purposes |
|
975 delete iStringBuf; |
|
976 iStringBuf = HBufC::NewL(algSize + polSize); |
|
977 *iStringBuf = *data; |
|
978 |
|
979 #endif |
|
980 |
|
981 // The buffer holding the 8-bit data in the file |
|
982 CleanupStack::PopAndDestroy(); |
|
983 |
|
984 CleanupStack::PushL(data); |
|
985 ptr.Set((TUint8 *)ptr16.Ptr(), ptr16.Size()); |
|
986 |
|
987 // Write the data over socket to IPSec protocol component |
|
988 iSock.Write(ptr, stat); |
|
989 User::WaitForRequest(stat); |
|
990 |
|
991 // The buffer holding the data in the file |
|
992 CleanupStack::PopAndDestroy(); |
|
993 if (stat.Int() != KErrNone) |
|
994 { |
|
995 ErrorHandlingL(EWriteSocketError, stat.Int()); |
|
996 } |
|
997 iSock.Close(); |
|
998 iSecpolSocketOpen = EFalse; |
|
999 |
|
1000 // Start the SecpolReader object that reads the log messages |
|
1001 // sent by IPSec protocol component |
|
1002 if (!iSecpolReader6) |
|
1003 { |
|
1004 iSecpolReader6 = new (ELeave) CSecpolReader(this); |
|
1005 err = iSecpolReader6->Construct(_L("secpol6")); |
|
1006 if (err != KErrNone) |
|
1007 { |
|
1008 delete iSecpolReader6; |
|
1009 iSecpolReader6 = NULL; |
|
1010 ErrorHandlingL(ESecpolReaderError, err); |
|
1011 } |
|
1012 } |
|
1013 } |
|
1014 |
|
1015 // |
|
1016 // Send a "Bypass All" policy to the IPSec protocol component using Secpol |
|
1017 // socket. It indicates that IPSec accepts all packets. |
|
1018 // |
|
1019 void |
|
1020 CIPSecPolicyManagerHandler::SendNullFileToIPSecL(const TDesC &aSocket) |
|
1021 { |
|
1022 TInt err(KErrNone); |
|
1023 TInetAddr addr; |
|
1024 TRequestStatus stat; |
|
1025 TInt algSize(0), polSize(0); |
|
1026 |
|
1027 _LIT8 (KBypassAllString, " inbound = {}\n outbound = {}\n"); |
|
1028 // Open Secpol socket |
|
1029 err = iSock.Open(iSS, aSocket); |
|
1030 if (err != KErrNone) |
|
1031 { |
|
1032 ErrorHandlingL(EOpenSocketError, err); |
|
1033 } |
|
1034 iSecpolSocketOpen = ETrue; |
|
1035 |
|
1036 // Bind to socket |
|
1037 addr.SetAddress(KInetAddrNone); |
|
1038 addr.SetPort(0); |
|
1039 err = iSock.Bind(addr); |
|
1040 if (err != KErrNone) |
|
1041 { |
|
1042 ErrorHandlingL(EBindSocketError, err); |
|
1043 } |
|
1044 iSock.LocalName(addr); |
|
1045 |
|
1046 polSize = KBypassAllString().Length(); |
|
1047 if (iAlgorithmsHBufC8 != NULL) |
|
1048 { |
|
1049 algSize = iAlgorithmsHBufC8->Des().Length(); |
|
1050 } |
|
1051 |
|
1052 // Both files |
|
1053 HBufC8* buf = HBufC8::NewLC(algSize + polSize); |
|
1054 TPtr8 algPtr((TUint8 *)buf->Ptr(), algSize, algSize); |
|
1055 TPtr8 polPtr((TUint8 *)buf->Ptr() + algSize, polSize, polSize); |
|
1056 |
|
1057 if (iAlgorithmsHBufC8 != NULL) |
|
1058 { |
|
1059 algPtr.Copy(*iAlgorithmsHBufC8); |
|
1060 } |
|
1061 |
|
1062 // Store the policy buffer data after algorithm data |
|
1063 // and free the policy buffer |
|
1064 polPtr.Copy(KBypassAllString); |
|
1065 |
|
1066 // Allocate a buffer for the KBypassAllString |
|
1067 HBufC* data = HBufC::NewL(algSize + polSize); |
|
1068 TPtr ptr16(data->Des()); |
|
1069 TPtrC8 ptr((TUint8 *)buf->Ptr(), algSize + polSize); |
|
1070 |
|
1071 // For debug |
|
1072 ptr16.Copy(ptr); |
|
1073 |
|
1074 // The buffer holding the 8-bit data in the file |
|
1075 CleanupStack::PopAndDestroy(); |
|
1076 |
|
1077 CleanupStack::PushL(data); |
|
1078 ptr.Set((TUint8 *)ptr16.Ptr(), ptr16.Size()); |
|
1079 |
|
1080 // Write the BypassAllString over socket to IPSec protocol component |
|
1081 iSock.Write(ptr, stat); |
|
1082 User::WaitForRequest(stat); |
|
1083 |
|
1084 // The buffer holding the data in the file |
|
1085 CleanupStack::PopAndDestroy(); |
|
1086 iSock.Close(); |
|
1087 iSecpolSocketOpen = EFalse; |
|
1088 } |
|
1089 |
|
1090 // |
|
1091 // Search from the active policy list the policy corresponding |
|
1092 // to the current policy handle and delete it |
|
1093 // |
|
1094 TInt |
|
1095 CIPSecPolicyManagerHandler::DeletePolicyFromList() |
|
1096 { |
|
1097 TInt count(iActivePolicyList->Count()); |
|
1098 for (TInt i = 0; i < count; i++) |
|
1099 { |
|
1100 if (iActivePolicyList->At(i)->iPolicyHandle.iHandle == |
|
1101 iCurrentPolicyHandle.iHandle) |
|
1102 { |
|
1103 delete iActivePolicyList->At(i)->iPolicyBuf; |
|
1104 iActivePolicyList->At(i)->iPolicyBuf = NULL; |
|
1105 delete iActivePolicyList->At(i); |
|
1106 iActivePolicyList->Delete(i); |
|
1107 return KErrNone; |
|
1108 } |
|
1109 } |
|
1110 return (EUnknownPolicyHandle); |
|
1111 } |
|
1112 |
|
1113 // |
|
1114 // Search from the active policy list the policy corresponding |
|
1115 // to the current policy handle |
|
1116 // |
|
1117 TInt |
|
1118 CIPSecPolicyManagerHandler::SearchPolicyFromListAndActivate() |
|
1119 { |
|
1120 TInt count(iActivePolicyList->Count()); |
|
1121 for (TInt i = 0; i < count; i++) |
|
1122 { |
|
1123 if (iActivePolicyList->At(i)->iPolicyHandle.iHandle == |
|
1124 iCurrentPolicyHandle.iHandle) |
|
1125 { |
|
1126 iActivePolicyList->At(i)->iActiveState = ETrue; |
|
1127 return KErrNone; |
|
1128 } |
|
1129 } |
|
1130 return (EUnknownPolicyHandle); |
|
1131 } |
|
1132 |
|
1133 // |
|
1134 // Return the new Policy File Handle to the API user |
|
1135 // |
|
1136 void |
|
1137 CIPSecPolicyManagerHandler::ReturnPolicyFileHandleL( |
|
1138 const RMessage2& aMsg) |
|
1139 { |
|
1140 TPckg<TPolicyHandle> pckgPolicyHandle(iCurrentPolicyHandle); |
|
1141 aMsg.WriteL(SECOND_ARGUMENT, pckgPolicyHandle); |
|
1142 } |
|
1143 |
|
1144 // |
|
1145 // An API call completed |
|
1146 // |
|
1147 void |
|
1148 CIPSecPolicyManagerHandler::ApiCallCompleted() |
|
1149 { |
|
1150 ReleaseResources(); |
|
1151 } |
|
1152 |
|
1153 // |
|
1154 // Read the autoload configuration data |
|
1155 // |
|
1156 void |
|
1157 CIPSecPolicyManagerHandler::ReadAutoloadConfigDataL() |
|
1158 { |
|
1159 TBool findVar(EFalse); |
|
1160 TInt leaveCode(KErrNone); |
|
1161 TBuf<32> loadIndexBuf; |
|
1162 |
|
1163 iPreloadPolicy = HBufC8::NewL(1); |
|
1164 iBeforeManualLoadPolicy = HBufC8::NewL(1); |
|
1165 iAfterManualLoadPolicy = HBufC8::NewL(1); |
|
1166 iBeforeScopedLoadPolicy = HBufC8::NewL(1); |
|
1167 iAfterScopedLoadPolicy = HBufC8::NewL(1); |
|
1168 |
|
1169 // Open ini file |
|
1170 CESockIniData* preloadIniFile = NULL; |
|
1171 |
|
1172 TRAP(leaveCode, preloadIniFile = CESockIniData::NewL(KPreloadFileName)); |
|
1173 if (leaveCode != KErrNone) |
|
1174 { |
|
1175 return; |
|
1176 } |
|
1177 |
|
1178 CleanupStack::PushL(preloadIniFile); |
|
1179 |
|
1180 TPtrC fileName(NULL, 0); |
|
1181 TPtrC loadFlag(NULL, 0); |
|
1182 |
|
1183 TInt index(0); |
|
1184 _LIT(KAutoloadEntry, "Autoload%d"); |
|
1185 |
|
1186 loadIndexBuf.Format(KAutoloadEntry, index); |
|
1187 while (preloadIniFile->FindVar(loadIndexBuf, KLoadFlag, loadFlag)) |
|
1188 { |
|
1189 findVar = preloadIniFile->FindVar(loadIndexBuf, KFileName, fileName); |
|
1190 // If there is no such configuration information, no autoload takes place |
|
1191 if (!findVar) |
|
1192 { |
|
1193 goto forward; |
|
1194 } |
|
1195 findVar = preloadIniFile->FindVar(loadIndexBuf, KLoadFlag, loadFlag); |
|
1196 if (!findVar || (loadFlag == KAutoloadNone)) |
|
1197 { |
|
1198 goto forward; |
|
1199 } |
|
1200 |
|
1201 // Check the values of the autoload flag and read & store autoload |
|
1202 // policy file accordingly |
|
1203 if (loadFlag == KAutoloadPreload) |
|
1204 { |
|
1205 ReadNextAutoloadPolicyL(iPreloadPolicy, fileName); |
|
1206 iIsPreloadNeeded = ETrue; |
|
1207 } |
|
1208 if (loadFlag == KAutoloadBeforeManualLoad) |
|
1209 { |
|
1210 ReadNextAutoloadPolicyL(iBeforeManualLoadPolicy, fileName); |
|
1211 } |
|
1212 if (loadFlag == KAutoloadAfterManualLoad) |
|
1213 { |
|
1214 ReadNextAutoloadPolicyL(iAfterManualLoadPolicy, fileName); |
|
1215 } |
|
1216 if (loadFlag == KAutoloadBeforeScopedLoad) |
|
1217 { |
|
1218 ReadNextAutoloadPolicyL(iBeforeScopedLoadPolicy, fileName); |
|
1219 } |
|
1220 if (loadFlag == KAutoloadAfterScopedLoad) |
|
1221 { |
|
1222 ReadNextAutoloadPolicyL(iAfterScopedLoadPolicy, fileName); |
|
1223 } |
|
1224 |
|
1225 forward: |
|
1226 index++; |
|
1227 loadIndexBuf.Format(KAutoloadEntry, index); |
|
1228 } |
|
1229 |
|
1230 // Ini file closed |
|
1231 CleanupStack::PopAndDestroy(preloadIniFile); |
|
1232 } |
|
1233 |
|
1234 // |
|
1235 // read the next autoload policy file |
|
1236 // |
|
1237 void |
|
1238 CIPSecPolicyManagerHandler::ReadNextAutoloadPolicyL( |
|
1239 HBufC8*& aAutoloadPolicyBuffer, |
|
1240 TPtrC& aPolicyFileName) |
|
1241 { |
|
1242 RFile fileAutoload; |
|
1243 CleanupClosePushL(fileAutoload); |
|
1244 TInt err = fileAutoload.Open(iFs, aPolicyFileName, EFileRead); |
|
1245 |
|
1246 if (err != KErrNone) |
|
1247 { |
|
1248 CleanupStack::PopAndDestroy(); // fileAutoload |
|
1249 return ; |
|
1250 } |
|
1251 |
|
1252 TInt polSize; |
|
1253 err = fileAutoload.Size(polSize); |
|
1254 |
|
1255 if (err != KErrNone) |
|
1256 { |
|
1257 CleanupStack::PopAndDestroy(); // fileAutoload |
|
1258 return ; |
|
1259 } |
|
1260 |
|
1261 // Read current policy size |
|
1262 TInt currentPolSize = aAutoloadPolicyBuffer->Length(); |
|
1263 |
|
1264 // Create temporary buffer that will concatenate policies and push |
|
1265 // it to cleanup stack |
|
1266 HBufC8* tempFileBuf = HBufC8::NewLC(currentPolSize + polSize + 1); |
|
1267 |
|
1268 // Store current policies to temp buf |
|
1269 *tempFileBuf = *aAutoloadPolicyBuffer; |
|
1270 TPtr8 policyPtr8((TUint8*)tempFileBuf->Ptr() + currentPolSize, |
|
1271 polSize, |
|
1272 polSize); |
|
1273 |
|
1274 // Read new autoload polici data to the same temp buffer |
|
1275 err = fileAutoload.Read(policyPtr8); |
|
1276 if (err != KErrNone) |
|
1277 { |
|
1278 CleanupStack::PopAndDestroy(2); // tempFileBuf,fileAutoload |
|
1279 return ; |
|
1280 } |
|
1281 |
|
1282 // Delete old policy buffer |
|
1283 delete aAutoloadPolicyBuffer; |
|
1284 aAutoloadPolicyBuffer = NULL; |
|
1285 |
|
1286 // Create new policy buffer |
|
1287 aAutoloadPolicyBuffer = HBufC8::NewL(currentPolSize + polSize + 1); |
|
1288 TPtr8 policyBuf(aAutoloadPolicyBuffer->Des()); |
|
1289 |
|
1290 // Copy contents of concatenated buffer to new policy buffer |
|
1291 policyBuf.Copy( (TUint8*)tempFileBuf->Ptr() , currentPolSize + polSize); |
|
1292 policyBuf.ZeroTerminate(); |
|
1293 |
|
1294 // Delete temporary buffer and close policy file |
|
1295 CleanupStack::PopAndDestroy(2); |
|
1296 } |
|
1297 |
|
1298 // |
|
1299 // Set the flag determining the autoload policy status |
|
1300 // |
|
1301 void |
|
1302 CIPSecPolicyManagerHandler::SetAutoloadPolicyActive( |
|
1303 TBool aIsAutoloadPolicyActive) |
|
1304 { |
|
1305 iIsAutoloadPolicyActive = aIsAutoloadPolicyActive; |
|
1306 } |
|
1307 |
|
1308 // |
|
1309 // Check is there is an active autoload policy |
|
1310 // |
|
1311 TBool |
|
1312 CIPSecPolicyManagerHandler::IsAutoloadPolicyActive() |
|
1313 { |
|
1314 return iIsAutoloadPolicyActive; |
|
1315 } |
|
1316 |
|
1317 // |
|
1318 // Perform the autoload for policies |
|
1319 // |
|
1320 void |
|
1321 CIPSecPolicyManagerHandler::AutoloadPoliciesL( |
|
1322 const TZoneInfoSet& aZoneInfoSet, |
|
1323 HBufC8* aPolicyBuffer, |
|
1324 TAutoloadFlags aAutoloadType) |
|
1325 { |
|
1326 // Zone Info |
|
1327 iVPNNetId = 0; |
|
1328 if (aZoneInfoSet.iSelectorZone.iScope != KScopeNone) |
|
1329 { |
|
1330 iVPNNetId = aZoneInfoSet.iSelectorZone.iId; |
|
1331 } |
|
1332 iGwNetId = 0; |
|
1333 if (aZoneInfoSet.iEndPointZone.iScope != KScopeNone) |
|
1334 { |
|
1335 iGwNetId = aZoneInfoSet.iEndPointZone.iId; |
|
1336 } |
|
1337 |
|
1338 LOG(Log::Printf(_L("LoadPolicy request VPN NetId: %d GW NetId: %d\n"), |
|
1339 iVPNNetId, iGwNetId)); |
|
1340 |
|
1341 // Autoload policies are loaded into a separate descriptor |
|
1342 if (aAutoloadType == EAutoloadPreload) |
|
1343 { |
|
1344 delete iPolicyHBufC8; |
|
1345 iPolicyHBufC8 = NULL; |
|
1346 iPolicyHBufC8 = HBufC8::NewL(iPreloadPolicy->Length()); |
|
1347 TPtr8 autoloadPolicyDataDesc(iPolicyHBufC8->Des()); |
|
1348 autoloadPolicyDataDesc.Copy(iPreloadPolicy->Des()); |
|
1349 } |
|
1350 else |
|
1351 { |
|
1352 delete iPolicyHBufC8; |
|
1353 iPolicyHBufC8 = NULL; |
|
1354 iPolicyHBufC8 = HBufC8::NewL(aPolicyBuffer->Length()); |
|
1355 TPtr8 autoloadPolicyDataDesc(iPolicyHBufC8->Des()); |
|
1356 autoloadPolicyDataDesc.Copy(aPolicyBuffer->Des()); |
|
1357 } |
|
1358 |
|
1359 // Parse the policy file from string format to binary object format |
|
1360 ParseCurrentPolicyL(); |
|
1361 |
|
1362 // Calculate the Bypass/Drop mode of parsed policy |
|
1363 TInt policyBypassDropMode(KDropMode); |
|
1364 CSecurityPolicy* policy = iPieceData->Policies(); |
|
1365 policyBypassDropMode = CalculatePolicyBypassDropMode(*policy); |
|
1366 |
|
1367 // Add VPNNetId to CPolicySelector and GwNetId to CSecpolBundleItem objects |
|
1368 UpdateSelectorsAndTunnels(); |
|
1369 |
|
1370 // Check if the IP addresses in the selectors of current policy |
|
1371 // file overlaps with the selectors of the policies in the active |
|
1372 // policy list. Overlapping is allowed when the scope IDs differ |
|
1373 // or all parameters in the selectors and corresponding SA |
|
1374 // match exactly. |
|
1375 CheckSelectorConflictsL(); |
|
1376 |
|
1377 // Modify the SA names to avoid conflicts caused by equal names |
|
1378 // in different policies |
|
1379 MakeUniqueSANamesL(); |
|
1380 |
|
1381 // Convert object format policy pieces to string format |
|
1382 // and do the operations defined by the API flags |
|
1383 ConvertFromObjectsToStringWithSectionsL(iFunction, |
|
1384 policyBypassDropMode); |
|
1385 |
|
1386 // Store current policy entry to active policy list |
|
1387 StorePolicyToActiveListL(EAutoload, policyBypassDropMode); |
|
1388 LOG(Log::Printf(_L("LoadPolicy request completed OK, handle: %d\n"), |
|
1389 iCurrentPolicyHandle.iHandle)); |
|
1390 |
|
1391 // An API call completed |
|
1392 ApiCallCompleted(); |
|
1393 |
|
1394 if (SearchPolicyFromListAndActivate() == KErrNone) |
|
1395 { |
|
1396 SetAutoloadPolicyActive(ETrue); |
|
1397 } |
|
1398 else |
|
1399 { |
|
1400 LOG(Log::Printf(_L("LoadPolicy request completed OK, handle: %d\n"), |
|
1401 iCurrentPolicyHandle.iHandle)); |
|
1402 } |
|
1403 } |
|
1404 |
|
1405 // |
|
1406 // Store the preload policy handle |
|
1407 // |
|
1408 void |
|
1409 CIPSecPolicyManagerHandler::StorePreloadPolicyHandle() |
|
1410 { |
|
1411 iPreloadPolicyHandle.iHandle = iCurrentPolicyHandle.iHandle; |
|
1412 |
|
1413 // Delete preload buffer because it's not needed anymore |
|
1414 delete iPreloadPolicy; |
|
1415 iPreloadPolicy = NULL; |
|
1416 } |
|
1417 |
|
1418 // |
|
1419 // Find the associated autoload policy for a certain policy |
|
1420 // |
|
1421 CAutoloadListItem* |
|
1422 CIPSecPolicyManagerHandler::FindScopedAutoloadPolicyPair( |
|
1423 TUint32 aParentPolicyHandle) |
|
1424 { |
|
1425 for (TInt i = 0; i < iScopedAutoloadPolicyPairs.Count(); i++) |
|
1426 { |
|
1427 if (iScopedAutoloadPolicyPairs[i]->GetParentPolicyHandle() |
|
1428 == aParentPolicyHandle) |
|
1429 { |
|
1430 return iScopedAutoloadPolicyPairs[i]; |
|
1431 } |
|
1432 } |
|
1433 |
|
1434 return NULL; |
|
1435 } |
|
1436 |
|
1437 // |
|
1438 // Add the associated autoload policy pair for a certain policy |
|
1439 // |
|
1440 void |
|
1441 CIPSecPolicyManagerHandler::AddScopedAutoloadPolicyPairL( |
|
1442 TUint32 aPreloadPolicyHandle, |
|
1443 TUint32 aPostloadPolicyHandle, |
|
1444 TUint32 aParentPolicyHandle) |
|
1445 { |
|
1446 CAutoloadListItem* autoloadListItem = |
|
1447 CAutoloadListItem::NewL(aPreloadPolicyHandle, |
|
1448 aPostloadPolicyHandle, |
|
1449 aParentPolicyHandle); |
|
1450 |
|
1451 if (autoloadListItem != NULL) |
|
1452 { |
|
1453 iScopedAutoloadPolicyPairs.Append(autoloadListItem); |
|
1454 } |
|
1455 } |
|
1456 |
|
1457 // |
|
1458 // Delete the associated autoload policy pair for a certain policy |
|
1459 // |
|
1460 void |
|
1461 CIPSecPolicyManagerHandler::DeleteScopedAutoloadPolicyPair( |
|
1462 TUint32 aParentPolicyHandle) |
|
1463 { |
|
1464 for (TInt i = 0; i < iScopedAutoloadPolicyPairs.Count(); i++) |
|
1465 { |
|
1466 if (iScopedAutoloadPolicyPairs[i]->GetParentPolicyHandle() |
|
1467 == aParentPolicyHandle) |
|
1468 { |
|
1469 delete iScopedAutoloadPolicyPairs[i]; |
|
1470 iScopedAutoloadPolicyPairs.Remove(i); |
|
1471 } |
|
1472 } |
|
1473 } |
|
1474 |
|
1475 // |
|
1476 // read the algorithmsfile contents |
|
1477 // |
|
1478 void |
|
1479 CIPSecPolicyManagerHandler::ReadAlgorithmsFileL() |
|
1480 { |
|
1481 RFile algFile; |
|
1482 TInt algSize(0); |
|
1483 CleanupClosePushL(algFile); |
|
1484 TInt err = algFile.Open(iFs, KAlgorithmFile, EFileRead); |
|
1485 |
|
1486 delete iAlgorithmsHBufC8; |
|
1487 iAlgorithmsHBufC8 = NULL; |
|
1488 |
|
1489 if (err == KErrNone) |
|
1490 { |
|
1491 err = algFile.Size(algSize); |
|
1492 iAlgorithmsHBufC8 = HBufC8::NewL(algSize); |
|
1493 TPtr8 algorithmsPtr8(iAlgorithmsHBufC8->Des()); |
|
1494 algFile.Read(algorithmsPtr8); |
|
1495 } |
|
1496 else |
|
1497 { |
|
1498 algSize = KAlgorithmConf().Length(); |
|
1499 #ifdef SYMBIAN_IPSEC_VOIP_SUPPORT |
|
1500 algSize += KNewAlgorithmConf().Length(); |
|
1501 #endif // SYMBIAN_IPSEC_VOIP_SUPPORT |
|
1502 iAlgorithmsHBufC8 = HBufC8::NewL(algSize); |
|
1503 TPtr8 algorithmsPtr8(iAlgorithmsHBufC8->Des()); |
|
1504 algorithmsPtr8.Copy(KAlgorithmConf); |
|
1505 #ifdef SYMBIAN_IPSEC_VOIP_SUPPORT |
|
1506 algorithmsPtr8.Append(KNewAlgorithmConf); |
|
1507 #endif // SYMBIAN_IPSEC_VOIP_SUPPORT |
|
1508 } |
|
1509 |
|
1510 CleanupStack::PopAndDestroy(); |
|
1511 } |
|
1512 |
|
1513 TBool |
|
1514 CIPSecPolicyManagerHandler::IsLastManualLoadPolicy(TUint32 aPolicyHandle) |
|
1515 { |
|
1516 for (TInt i = 0; i < iActivePolicyList->Count(); i++) |
|
1517 { |
|
1518 // If there are other manual load policies |
|
1519 if ((iActivePolicyList->At(i)->iPolicyType == EManualLoad) && |
|
1520 iActivePolicyList->At(i)->iPolicyHandle.iHandle != aPolicyHandle) |
|
1521 { |
|
1522 return EFalse; |
|
1523 } |
|
1524 } |
|
1525 return ETrue; |
|
1526 } |
|
1527 |
|
1528 // |
|
1529 // Process UnloadPolicy - Process an UnloadPolicy for the autoload policies |
|
1530 // The policy is identified by the policy handle passed on as a parameter |
|
1531 // |
|
1532 TInt |
|
1533 CIPSecPolicyManagerHandler::UnloadPolicyByHandleL( |
|
1534 TUint32 aPolicyHandle, |
|
1535 const CIPSecPolicyManagerSession* aIPSecPolicyManagerSession) |
|
1536 { |
|
1537 // Store the parameters to this object |
|
1538 iSession = aIPSecPolicyManagerSession; |
|
1539 iCurrentPolicyHandle.iHandle = aPolicyHandle; |
|
1540 LOG(Log::Printf(_L("UnloadPolicy request, handle: %d\n"), |
|
1541 iCurrentPolicyHandle.iHandle)); |
|
1542 |
|
1543 // Search from the active policy list the policy corresponding |
|
1544 // to the current policy handle and delete it |
|
1545 TInt ret = DeletePolicyFromList(); |
|
1546 if (ret != KErrNone) |
|
1547 { |
|
1548 ErrorHandlingL(ret, 0 ); |
|
1549 } |
|
1550 |
|
1551 // Send BypassAll file to the IPSec protocol component if |
|
1552 // the deleted policy was the last one |
|
1553 if (iActivePolicyList->Count() == 0) |
|
1554 { |
|
1555 SendNullFileToIPSecL(_L("secpol6")); |
|
1556 LOG(Log::Printf(_L("Last policy deleted\n"))); |
|
1557 LOG(Log::Printf(_L("UnLoadPolicy request completed OK, handle: %d\n"), |
|
1558 iCurrentPolicyHandle.iHandle)); |
|
1559 |
|
1560 // An API call completed |
|
1561 ApiCallCompleted(); |
|
1562 return KErrNone; |
|
1563 } |
|
1564 |
|
1565 // Parse all active policy files from string format |
|
1566 // to IPSecPolParser class object formats |
|
1567 ParseAllPolicyFilesL(); |
|
1568 |
|
1569 // Calculate whether it's drop or bypass mode to be used |
|
1570 CalculateCombinedPolicyBypassDropMode(); |
|
1571 |
|
1572 // Delete all INBOUND/OUTBOUND selector pairs |
|
1573 DeleteExtraInboundOutboundSelectors(); |
|
1574 |
|
1575 // Update the policy selectors by building a comparison word |
|
1576 // and setting a sequence number |
|
1577 SortSelectors(); |
|
1578 |
|
1579 // Convert object format policy pieces to string format. |
|
1580 // This format is used by IPSec protocol component. |
|
1581 ConvertFromObjectsToStringWithoutSectionsL(); |
|
1582 |
|
1583 // Add an Inbound/outbound selector pair to the end of string format |
|
1584 // policy file. This occurs only when the bypass mode is defined. |
|
1585 TInt err = AddInboundOutboundSelectorPair(); |
|
1586 if (err != KErrNone) |
|
1587 { |
|
1588 ErrorHandlingL(ENoMemory, err); |
|
1589 } |
|
1590 |
|
1591 // Send the algorithms table and the string format policy file to |
|
1592 // IPSec protocol component using Secpol socket |
|
1593 SendAlgorithmsAndPolicyToIPSecL(_L("secpol6")); |
|
1594 |
|
1595 // An API call completed |
|
1596 LOG(Log::Printf(_L("UnloadPolicy request completed OK, handle: %d\n"), |
|
1597 iCurrentPolicyHandle.iHandle)); |
|
1598 ApiCallCompleted(); |
|
1599 return KErrNone; |
|
1600 } |
|
1601 |
|
1602 // |
|
1603 // Process UnloadPolicy - Process an UnloadPolicy considering the autoload |
|
1604 // policies. The policy is identified by the policy handle passed on in the |
|
1605 // IPC message |
|
1606 // |
|
1607 TInt |
|
1608 CIPSecPolicyManagerHandler::ProcessUnloadPoliciesL( |
|
1609 const RMessage2& aMsg, |
|
1610 const CIPSecPolicyManagerSession* aIPSecPolicyManagerSession) |
|
1611 { |
|
1612 TInt err(KErrNone); |
|
1613 TInt preloadHandle(0), postLoadHandle(0); |
|
1614 TInt leaveCode(KErrNone); |
|
1615 |
|
1616 // Find the autoload policy paired with this parent policy and unload it |
|
1617 CAutoloadListItem* autoLoadItem = FindScopedAutoloadPolicyPair(aMsg.Int0()); |
|
1618 |
|
1619 if (autoLoadItem != NULL) |
|
1620 { |
|
1621 err = ProcessUnloadPolicyL(aMsg, aIPSecPolicyManagerSession); |
|
1622 |
|
1623 preloadHandle = autoLoadItem->GetPreloadPolicyHandle(); |
|
1624 if (preloadHandle > 0) |
|
1625 { |
|
1626 TRAP(leaveCode, UnloadPolicyByHandleL(preloadHandle, |
|
1627 aIPSecPolicyManagerSession)); |
|
1628 |
|
1629 if (leaveCode != KErrNone) |
|
1630 { |
|
1631 LOG(Log::Printf(_L("UnloadAutoloadPolicy failed for handle: %d\n"), |
|
1632 preloadHandle)); |
|
1633 } |
|
1634 } |
|
1635 |
|
1636 postLoadHandle = autoLoadItem->GetPostloadPolicyHandle(); |
|
1637 if (postLoadHandle > 0) |
|
1638 { |
|
1639 TRAP(leaveCode, UnloadPolicyByHandleL(postLoadHandle, |
|
1640 aIPSecPolicyManagerSession)); |
|
1641 |
|
1642 if (leaveCode != KErrNone) |
|
1643 { |
|
1644 LOG(Log::Printf(_L("UnloadAutoloadPolicy failed for handle: %d\n"), |
|
1645 postLoadHandle)); |
|
1646 } |
|
1647 } |
|
1648 |
|
1649 DeleteScopedAutoloadPolicyPair(aMsg.Int0()); |
|
1650 } |
|
1651 else |
|
1652 { |
|
1653 // If this is the last unload for manual policies |
|
1654 if (IsLastManualLoadPolicy(aMsg.Int0())) |
|
1655 { |
|
1656 if (iManualAutoloadHandlePair.iManualPostLoadHandle.iHandle != 0 ) |
|
1657 { |
|
1658 TRAP(leaveCode, |
|
1659 UnloadPolicyByHandleL(iManualAutoloadHandlePair.iManualPostLoadHandle.iHandle, |
|
1660 aIPSecPolicyManagerSession)); |
|
1661 if (leaveCode != KErrNone) |
|
1662 { |
|
1663 LOG(Log::Printf(_L("UnloadAutoloadPolicy failed for handle: %d\n"), |
|
1664 iManualAutoloadHandlePair.iManualPostLoadHandle.iHandle)); |
|
1665 } |
|
1666 iManualAutoloadHandlePair.iManualPostLoadHandle.iHandle = 0; |
|
1667 } |
|
1668 |
|
1669 err = ProcessUnloadPolicyL(aMsg, aIPSecPolicyManagerSession); |
|
1670 if (iManualAutoloadHandlePair.iManualPreloadHandle.iHandle != 0 ) |
|
1671 { |
|
1672 TRAP(leaveCode, |
|
1673 UnloadPolicyByHandleL(iManualAutoloadHandlePair.iManualPreloadHandle.iHandle, |
|
1674 aIPSecPolicyManagerSession)); |
|
1675 if (leaveCode != KErrNone) |
|
1676 { |
|
1677 LOG(Log::Printf(_L("UnloadAutoloadPolicy failed for handle: %d\n"), |
|
1678 iManualAutoloadHandlePair.iManualPreloadHandle.iHandle)); |
|
1679 } |
|
1680 |
|
1681 iManualAutoloadHandlePair.iManualPreloadHandle.iHandle = 0; |
|
1682 } |
|
1683 } |
|
1684 else |
|
1685 { |
|
1686 err = ProcessUnloadPolicyL(aMsg, aIPSecPolicyManagerSession); |
|
1687 } |
|
1688 } |
|
1689 |
|
1690 return err; |
|
1691 } |
|
1692 |
|
1693 // |
|
1694 // GetIPSecSAInfo - Search a selector object and correponding SAs |
|
1695 // and return the SA info data. The parameters in message |
|
1696 // object are: |
|
1697 // -- TIpsecSelectorInfo. Contains parameters used to |
|
1698 // search the rigth selector object |
|
1699 // -- TIpsecSaSpec in which the SA Info is to be |
|
1700 // returned |
|
1701 // |
|
1702 // |
|
1703 TInt |
|
1704 CIPSecPolicyManagerHandler::GetIPSecSAInfoL( |
|
1705 const RMessage2& aMsg, |
|
1706 const CIPSecPolicyManagerSession* /*aIPSecPolicyManagerSession*/) |
|
1707 { |
|
1708 LOG(Log::Printf(_L("MatchSelector (GetIPsecSaInfo) request\n"))); |
|
1709 |
|
1710 // Allocate buffer for TIpsecSelectorInfo object and read the object |
|
1711 // data from the client |
|
1712 delete iSelectorInfo; |
|
1713 iSelectorInfo = NULL; |
|
1714 iSelectorInfo = new(ELeave) TIpsecSelectorInfo; |
|
1715 TPckg<TIpsecSelectorInfo>pckgSelectorInfo(*iSelectorInfo); |
|
1716 aMsg.ReadL(FIRST_ARGUMENT , pckgSelectorInfo); |
|
1717 |
|
1718 // Allocate buffer for TIPSecSAInfo object |
|
1719 delete iSAInfo; |
|
1720 iSAInfo = NULL; |
|
1721 iSAInfo = new(ELeave) TIpsecSaSpec; |
|
1722 TPckg<TIpsecSaSpec>pckgSaSpec(*iSAInfo); |
|
1723 iPckgSAInfo = &pckgSaSpec; |
|
1724 |
|
1725 // Parse all active policy files from string format to IPSecPolParser |
|
1726 // class object format |
|
1727 ParseAllPolicyFilesL(); |
|
1728 if (iActivePolicyList->Count() == 0) |
|
1729 { |
|
1730 ErrorHandlingL(ENoSelectorFound, 0); |
|
1731 } |
|
1732 |
|
1733 // Find selector object that corresponds to the parameters |
|
1734 // in TIPSecSelectorInfo object |
|
1735 CPolicySelector* policySelector = FindMatchingSelector(); |
|
1736 if (policySelector == NULL) |
|
1737 { |
|
1738 ErrorHandlingL(ENoSelectorFound, 0); |
|
1739 } |
|
1740 |
|
1741 // Fill the TIPSecSAInfo object with the data of an SA |
|
1742 // (TSecurityAssocSpec) |
|
1743 FillSAInfoObject(policySelector, iSelectorInfo->iSaIndex); |
|
1744 |
|
1745 // Write the SAInfo block to the client's address space |
|
1746 TPckg<TIpsecSaSpec> pckgSAInfoWrite(*iSAInfo); |
|
1747 aMsg.WriteL(SECOND_ARGUMENT, pckgSAInfoWrite); |
|
1748 |
|
1749 // An API call completed |
|
1750 LOG(Log::Printf(_L("MatchSelector request completed OK\n"))); |
|
1751 ApiCallCompleted(); |
|
1752 return KErrNone; |
|
1753 } |
|
1754 |
|
1755 // |
|
1756 // GetLastConflictInfo (GetDebugInfo) - Returns information about |
|
1757 // the policy that caused policy activation to fail. |
|
1758 // ARG 0 = aDebugInfo buffer in API |
|
1759 // ARG 1 = aInfoFlags |
|
1760 // KConflictingPolicyInfo - Get the last conflict Info data |
|
1761 // KParsingErrorInfo - Get the last parsing error data |
|
1762 // |
|
1763 // |
|
1764 TInt |
|
1765 CIPSecPolicyManagerHandler::GetLastConflictInfoL( |
|
1766 const RMessage2& aMsg, |
|
1767 const CIPSecPolicyManagerSession* /*aIPSecPolicyManagerSession*/) |
|
1768 { |
|
1769 TUint flags = aMsg.Int1(); |
|
1770 |
|
1771 // |
|
1772 // Check what info the API user is getting |
|
1773 // |
|
1774 HBufC8* infoBfr = NULL; |
|
1775 if (flags & KConflictingPolicyInfo) |
|
1776 { |
|
1777 infoBfr = iLastConflictInfo; |
|
1778 LOG(Log::Printf(_L("GetDebugInfo request, conflicting info requested\n"))); |
|
1779 } |
|
1780 else if (flags & KParsingErrorInfo) |
|
1781 { |
|
1782 infoBfr = iLastParsingErrorInfo; |
|
1783 LOG(Log::Printf(_L("GetDebugInfo request, parsing error info requested\n"))); |
|
1784 } |
|
1785 |
|
1786 if (infoBfr != NULL) |
|
1787 { |
|
1788 // Copy info data to 16 bit buffer |
|
1789 TPtr8 ptr8(infoBfr->Des()); |
|
1790 TInt length(ptr8.Length()); |
|
1791 |
|
1792 HBufC16* infoBfr16 = HBufC16::NewL(length + 1); |
|
1793 CleanupStack::PushL(infoBfr16); |
|
1794 TPtr16 ptr(infoBfr16->Des()); |
|
1795 ptr.FillZ(); |
|
1796 ptr.Copy(ptr8); |
|
1797 ptr.ZeroTerminate(); |
|
1798 |
|
1799 // Write the info buffer content to the client's address space |
|
1800 LOG(Log::Printf(_L("GetDebugInfo returned: %S\n"), &ptr)); |
|
1801 aMsg.WriteL(FIRST_ARGUMENT, *infoBfr16); |
|
1802 |
|
1803 // Release 16-bit info buffer |
|
1804 CleanupStack::PopAndDestroy(1); |
|
1805 } |
|
1806 else |
|
1807 { |
|
1808 ErrorHandlingL(ENoConflictInfoFound, 0); |
|
1809 } |
|
1810 |
|
1811 // An API call completed |
|
1812 ApiCallCompleted(); |
|
1813 return KErrNone; |
|
1814 } |
|
1815 |
|
1816 // |
|
1817 // Convert the policy content to object format using IPSecPolParser |
|
1818 // |
|
1819 // |
|
1820 void |
|
1821 CIPSecPolicyManagerHandler::ParseCurrentPolicyL() |
|
1822 { |
|
1823 delete iPieceData; |
|
1824 iPieceData = NULL; |
|
1825 iPieceData = new (ELeave) CIpSecurityPiece; |
|
1826 iPieceData->ConstructL(); |
|
1827 |
|
1828 // Copy policy to 16-bit buffer |
|
1829 TPtr8 ptr8(iPolicyHBufC8->Des()); |
|
1830 TInt length = ptr8.Length(); |
|
1831 HBufC *policyDataHBufC16 = HBufC::NewL(length + 1); |
|
1832 CleanupStack::PushL(policyDataHBufC16); |
|
1833 TPtr ptr(policyDataHBufC16->Des()); |
|
1834 ptr.FillZ(); |
|
1835 ptr.Copy(ptr8); |
|
1836 ptr.ZeroTerminate(); |
|
1837 |
|
1838 // Parse policy from string format into binary object format |
|
1839 TIpSecParser parser(ptr); |
|
1840 TInt err = parser.ParseAndIgnoreIKEL(iPieceData); |
|
1841 CleanupStack::PopAndDestroy(); |
|
1842 |
|
1843 // If parsing error, allocate a buffer and read the last error |
|
1844 // string from the ipsecpolparser. The API user will use the |
|
1845 // GetDebugInfo method to get the string (method is named as |
|
1846 // GetLastConflictInfo here). |
|
1847 if (err != KErrNone) |
|
1848 { |
|
1849 delete iLastParsingErrorInfo; |
|
1850 iLastParsingErrorInfo = NULL; |
|
1851 |
|
1852 // The same size as used in ipsecpolparser |
|
1853 iLastParsingErrorInfo = HBufC8::NewL(200); |
|
1854 iLastParsingErrorInfo->Des().Copy(iPieceData->iErrorInfo); |
|
1855 ErrorHandlingL(EParsingError, err); |
|
1856 } |
|
1857 } |
|
1858 |
|
1859 // |
|
1860 // CIPSecPolicyManagerHandler::UpdateSelectorsAndTunnels() |
|
1861 // |
|
1862 // Include VPNNetId to CPolicySelectors and GwNetId to CSecpolBundleItem |
|
1863 // objects |
|
1864 // |
|
1865 // |
|
1866 void |
|
1867 CIPSecPolicyManagerHandler::UpdateSelectorsAndTunnels() |
|
1868 { |
|
1869 // If VPN Network ID is set, store it to policy selectors |
|
1870 if (iVPNNetId) |
|
1871 { |
|
1872 CSecurityPolicy* sp = iPieceData->Policies(); |
|
1873 CSelectorList* selectorList = sp->SelectorList(); |
|
1874 TInt count = selectorList->Count(); |
|
1875 |
|
1876 // Iterate through selector (policy rule) list |
|
1877 for (TInt i = 0; i < count; i++) |
|
1878 { |
|
1879 CPolicySelector* ps = selectorList->At(i); |
|
1880 |
|
1881 // Skip 'global', 'bypass/drop_everything_else' and 'interface' selectors |
|
1882 if (ps->iGlobalSelector |
|
1883 || (ps->iDirection == KPolicySelector_INTERFACE) |
|
1884 || IsBypassEverythingElse(*ps) |
|
1885 || IsDropEverythingElse(*ps)) |
|
1886 { |
|
1887 continue; |
|
1888 } |
|
1889 |
|
1890 UpdatePolicySelectorScopeId(*ps, iVPNNetId); |
|
1891 } |
|
1892 } |
|
1893 |
|
1894 // If VPN Gateway Network ID is set, store it to policy bundles |
|
1895 if (iGwNetId) |
|
1896 { |
|
1897 CSecurityPolicy* sp = iPieceData->Policies(); |
|
1898 CSelectorList* selectorList = sp->SelectorList(); |
|
1899 TInt count = selectorList->Count(); |
|
1900 |
|
1901 // Iterate through selector (policy rule) list |
|
1902 for (TInt i = 0; i < count; i++) |
|
1903 { |
|
1904 TBool isTunnelMode = EFalse; |
|
1905 CPolicySelector* ps = selectorList->At(i); |
|
1906 |
|
1907 // Skip 'global', 'bypass/drop_everything_else' and 'interface' selectors |
|
1908 if (ps->iGlobalSelector |
|
1909 || (ps->iDirection == KPolicySelector_INTERFACE) |
|
1910 || IsBypassEverythingElse(*ps) |
|
1911 || IsDropEverythingElse(*ps)) |
|
1912 { |
|
1913 continue; |
|
1914 } |
|
1915 |
|
1916 UpdatePolicyBundleScopeId(*ps, iVPNNetId, iGwNetId, isTunnelMode); |
|
1917 |
|
1918 // If not tunnel mode use VPN Gateway Network Id |
|
1919 // as ScopeId when updating policy selector scope |
|
1920 if (!isTunnelMode) |
|
1921 { |
|
1922 UpdatePolicySelectorScopeId(*ps, iGwNetId); |
|
1923 } |
|
1924 } |
|
1925 } |
|
1926 } |
|
1927 |
|
1928 // |
|
1929 // CIPSecPolicyManagerHandler::UpdatePolicySelectorScopeId() |
|
1930 // |
|
1931 // Updates PolicySelector with the given ScopeId. The ScopeId can be either |
|
1932 // VPN Network Id or VPN Gateway Network Id. |
|
1933 // |
|
1934 // TODO: |
|
1935 // This method should be included within CPolicySelector class |
|
1936 // CPolicySelector::UpdateRemoteAddressScopeId(TInt aScopeId) |
|
1937 // |
|
1938 // |
|
1939 void |
|
1940 CIPSecPolicyManagerHandler::UpdatePolicySelectorScopeId( |
|
1941 CPolicySelector& aPolicySelector, |
|
1942 TInt aScopeId) |
|
1943 { |
|
1944 // Check if remote address is specified (other than any) |
|
1945 if (!aPolicySelector.iRemote.IsUnspecified()) |
|
1946 { |
|
1947 // Specific address exists, so convert address to IPv6 mapped |
|
1948 if (aPolicySelector.iRemote.Family() == KAfInet) |
|
1949 { |
|
1950 aPolicySelector.iRemote.ConvertToV4Mapped(); |
|
1951 aPolicySelector.iRemoteMask.ConvertToV4Mapped(); |
|
1952 } |
|
1953 |
|
1954 // VPN Network ID shall be used only with addresses in network |
|
1955 // scope (addresses in other scope levels are handled as global |
|
1956 // selectors) |
|
1957 if (aPolicySelector.iRemote.Ip6Address().Scope() == KIp6AddrScopeNetwork) |
|
1958 { |
|
1959 aPolicySelector.iRemote.SetScope(aScopeId); |
|
1960 aPolicySelector.iRemoteMask.SetScope(0xFFFFFFFF); |
|
1961 } |
|
1962 } |
|
1963 else |
|
1964 { |
|
1965 // Unspecified remote address so change address family to AfInet |
|
1966 // and then build null address/mask and set ScopeId |
|
1967 aPolicySelector.iRemote.SetFamily(KAfInet); |
|
1968 aPolicySelector.iRemoteMask.SetFamily(KAfInet); |
|
1969 aPolicySelector.iRemote.ConvertToV4Mapped(); |
|
1970 aPolicySelector.iRemoteMask.ConvertToV4Mapped(); |
|
1971 |
|
1972 aPolicySelector.iRemote.SetScope(aScopeId); |
|
1973 aPolicySelector.iRemoteMask.SetScope(0xFFFFFFFF); |
|
1974 } |
|
1975 } |
|
1976 |
|
1977 // |
|
1978 // CIPSecPolicyManagerHandler::UpdatePolicyBundleScopeId() |
|
1979 // |
|
1980 // Updates bundle list of given PolicySelector by using the VPN Network Id and |
|
1981 // VPN Gateway Network Id to set the ScopeId. |
|
1982 // |
|
1983 // VPN Gateway Network Id is set as ScopeId to tunnel address. If there are |
|
1984 // nested tunnels(tunnel-in-tunnel), the VPN Gateway Network Id is stored to |
|
1985 // the last gateway and VPN Network Id to all other. |
|
1986 // |
|
1987 // TODO: |
|
1988 // This method should be included within CPolicySelector class |
|
1989 // CPolicySelector::UpdateBundleScopeId(TInt aScopeId, TInt aGwScopeId) |
|
1990 // |
|
1991 // |
|
1992 void |
|
1993 CIPSecPolicyManagerHandler::UpdatePolicyBundleScopeId( |
|
1994 CPolicySelector& aPolicySelector, |
|
1995 TInt aScopeId, |
|
1996 TInt aGwScopeId, |
|
1997 TBool& aIsTunnelMode) |
|
1998 { |
|
1999 // Iterate through action bundles to set ScopeId |
|
2000 TSecpolBundleIter iter(aPolicySelector.iBundle); |
|
2001 while (iter) |
|
2002 { |
|
2003 CSecpolBundleItem* item = (CSecpolBundleItem *)iter++; |
|
2004 TBool isLast = (!iter ? ETrue : EFalse); |
|
2005 TInt scopeId = (isLast ? aGwScopeId : aScopeId); |
|
2006 |
|
2007 // Check if tunnel address is set |
|
2008 if (!item->iTunnel.IsUnspecified()) |
|
2009 { |
|
2010 aIsTunnelMode = ETrue; |
|
2011 |
|
2012 // Map tunnel IPv4 address to Ipv6 |
|
2013 if (item->iTunnel.Family() == KAfInet) |
|
2014 { |
|
2015 item->iTunnel.ConvertToV4Mapped(); |
|
2016 } |
|
2017 |
|
2018 item->iTunnel.SetScope(scopeId); |
|
2019 } |
|
2020 } |
|
2021 } |
|
2022 |
|
2023 #ifdef TESTFLAG |
|
2024 // |
|
2025 // |
|
2026 // CIPSecPolicyManagerHandler::RequestInfo() |
|
2027 // |
|
2028 // This is used for testing purposes. Test client queries information from the |
|
2029 // policy server |
|
2030 // ARG 0 = aBuf which returns the concatenated string send to ipsec protocol |
|
2031 // module |
|
2032 // ARG 1 = aHandles which returns loaded autoload handles |
|
2033 // |
|
2034 // |
|
2035 TInt |
|
2036 CIPSecPolicyManagerHandler::RequestEvent( |
|
2037 const RMessage2& aMsg, |
|
2038 const CIPSecPolicyManagerSession* /*aIPSecPolicyManagerSession*/ ) |
|
2039 { |
|
2040 |
|
2041 // In case when there have not yet been any call of |
|
2042 // SendAlgorithmsAndPolicyToIPSecL(_L("secpol6")); |
|
2043 // This should not be executed |
|
2044 if ( !iStringBuf == NULL ) |
|
2045 { |
|
2046 aMsg.WriteL(FIRST_ARGUMENT, (*iStringBuf)); |
|
2047 } |
|
2048 |
|
2049 // Deletes remained handles and creates new structure |
|
2050 delete iHandles; |
|
2051 iHandles = NULL; |
|
2052 iHandles = new(ELeave) TAutoloadHandles; |
|
2053 |
|
2054 // Initialization |
|
2055 iHandles->iHandle1 = 0; |
|
2056 iHandles->iHandle2 = 0; |
|
2057 iHandles->iHandle3 = 0; |
|
2058 iHandles->iHandle4 = 0; |
|
2059 iHandles->iHandle5 = 0; |
|
2060 |
|
2061 TInt count(0); // Counting autoload handles |
|
2062 |
|
2063 // Finds active Autoload policies and copies them in right order to the iHandles |
|
2064 // structure |
|
2065 for (TInt i = 0; i < iActivePolicyList->Count() ; i++) |
|
2066 { |
|
2067 |
|
2068 if ( iActivePolicyList->At(i)->iPolicyType == EAutoload ) // Case autoload |
|
2069 { |
|
2070 |
|
2071 if ( count == 0 ) |
|
2072 { |
|
2073 iHandles->iHandle1 = iActivePolicyList->At(i)->iPolicyHandle.iHandle; |
|
2074 } |
|
2075 else if ( count == 1) |
|
2076 { |
|
2077 iHandles->iHandle2 = iActivePolicyList->At(i)->iPolicyHandle.iHandle; |
|
2078 } |
|
2079 else if ( count == 2) |
|
2080 { |
|
2081 iHandles->iHandle3 = iActivePolicyList->At(i)->iPolicyHandle.iHandle; |
|
2082 } |
|
2083 else if ( count == 3) |
|
2084 { |
|
2085 iHandles->iHandle4 = iActivePolicyList->At(i)->iPolicyHandle.iHandle; |
|
2086 } |
|
2087 else if ( count == 4) |
|
2088 { |
|
2089 iHandles->iHandle5 = iActivePolicyList->At(i)->iPolicyHandle.iHandle; |
|
2090 } |
|
2091 |
|
2092 count++; |
|
2093 } |
|
2094 } |
|
2095 |
|
2096 // Creates the IPC package and copies iHandles to it |
|
2097 TPckg<TAutoloadHandles> handlesPckgWrite(*iHandles); |
|
2098 |
|
2099 // Writes IPC message |
|
2100 aMsg.WriteL(SECOND_ARGUMENT, handlesPckgWrite); |
|
2101 |
|
2102 return KErrNone; |
|
2103 } |
|
2104 |
|
2105 #endif |
|
2106 |
|
2107 // |
|
2108 // GetAvailableSelectors - Returns the available selectors information |
|
2109 // |
|
2110 // |
|
2111 TInt CIPSecPolicyManagerHandler::GetAvailableSelectors(const RMessage2& aMsg) |
|
2112 { |
|
2113 LOG(Log::Printf(_L("AvailableSelectors (GetAvailableSelectors) request\n"))); |
|
2114 // Write the SelectorInfo block to the client's address space |
|
2115 TInt count = iSelectorInfoArray->Count(); |
|
2116 TPtrC8 selectorInfoWrite(reinterpret_cast<TUint8*>(&(iSelectorInfoArray->At(0))), count * sizeof(TIpsecSelectorInfo)); |
|
2117 aMsg.WriteL(FIRST_ARGUMENT, selectorInfoWrite); |
|
2118 |
|
2119 // An API call completed |
|
2120 LOG(Log::Printf(_L("AvailableSelectors request completed OK\n"))); |
|
2121 ApiCallCompleted(); |
|
2122 return KErrNone; |
|
2123 } |
|
2124 |
|
2125 // |
|
2126 // GetSelectorsCount - Returns the number of selectors matching the |
|
2127 // gateway address passed by the client |
|
2128 // |
|
2129 // |
|
2130 TInt CIPSecPolicyManagerHandler::GetSelectorsCount(const RMessage2& aMsg) |
|
2131 { |
|
2132 LOG(Log::Printf(_L("EnumerateSelectors (GetSelectorsCount) request\n"))); |
|
2133 |
|
2134 // Read the gateway address sent by the client |
|
2135 TInetAddrPckg inetAddrPckg(iTunnel); |
|
2136 aMsg.ReadL(FIRST_ARGUMENT , inetAddrPckg); |
|
2137 |
|
2138 // Parse all active policy files from string format to IPSecPolParser |
|
2139 // class object format |
|
2140 ParseAllPolicyFilesL(); |
|
2141 if (iActivePolicyList->Count() == 0) |
|
2142 { |
|
2143 ErrorHandlingL(ENoGatewayFound, 0); |
|
2144 } |
|
2145 |
|
2146 // Find the selector object that corresponds |
|
2147 // to the gateway address sent by the client |
|
2148 FillSelectorInfoObject(); |
|
2149 if (!iSelectorInfoArray->Count()) |
|
2150 { |
|
2151 ErrorHandlingL(ENoGatewayFound, 0); |
|
2152 } |
|
2153 |
|
2154 |
|
2155 TPckg<TInt> selectorCount(iSelectorInfoArray->Count()); |
|
2156 aMsg.WriteL(SECOND_ARGUMENT, selectorCount); |
|
2157 |
|
2158 // An API call completed |
|
2159 LOG(Log::Printf(_L("EnumerateSelectors request completed OK\n"))); |
|
2160 ApiCallCompleted(); |
|
2161 return KErrNone; |
|
2162 } |
|
2163 |