|
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 // Name : CIpSecPolicyHandler.cpp |
|
15 // Part of : SIPSec |
|
16 // Version : SIP/4.0 |
|
17 // |
|
18 |
|
19 |
|
20 |
|
21 #include <utf.h> |
|
22 #include <convutils.h> |
|
23 #include <lib_pfkey.h> |
|
24 |
|
25 #include "CIpSecPolicyHandler.h" |
|
26 #include "MSipSecPolicyObserver.h" |
|
27 #include "SipSecIpsecParams.h" |
|
28 |
|
29 #ifndef CPPUNIT_TEST |
|
30 // Comment this definition off, if ipsec is wanted to be used for real |
|
31 //#define DISABLE_IPSEC_POLICY_USAGE |
|
32 #endif |
|
33 |
|
34 // ---------------------------------------------------------------------------- |
|
35 // CIpSecPolicyHandler::NewL |
|
36 // ---------------------------------------------------------------------------- |
|
37 // |
|
38 CIpSecPolicyHandler* CIpSecPolicyHandler::NewL( |
|
39 MSipSecPolicyObserver& aObserver, |
|
40 RIpsecPolicyServ& aPolicyServ ) |
|
41 { |
|
42 CIpSecPolicyHandler* |
|
43 self = CIpSecPolicyHandler::NewLC( aObserver, aPolicyServ ); |
|
44 CleanupStack::Pop( self ); |
|
45 return self; |
|
46 } |
|
47 |
|
48 // ---------------------------------------------------------------------------- |
|
49 // CIpSecPolicyHandler::NewLC |
|
50 // ---------------------------------------------------------------------------- |
|
51 // |
|
52 CIpSecPolicyHandler* CIpSecPolicyHandler::NewLC( |
|
53 MSipSecPolicyObserver& aObserver, |
|
54 RIpsecPolicyServ& aPolicyServ ) |
|
55 { |
|
56 CIpSecPolicyHandler* |
|
57 self = new ( ELeave ) CIpSecPolicyHandler( aObserver, aPolicyServ ); |
|
58 CleanupStack::PushL( self ); |
|
59 return self; |
|
60 } |
|
61 |
|
62 |
|
63 // ---------------------------------------------------------------------------- |
|
64 // CIpSecPolicyHandler::~CIpSecPolicyHandler |
|
65 // ---------------------------------------------------------------------------- |
|
66 // |
|
67 CIpSecPolicyHandler::~CIpSecPolicyHandler() |
|
68 { |
|
69 Cancel(); |
|
70 delete iPolicyData; |
|
71 } |
|
72 |
|
73 // ---------------------------------------------------------------------------- |
|
74 // CIpSecPolicyHandler::CreatePolicyL |
|
75 // ---------------------------------------------------------------------------- |
|
76 // |
|
77 void CIpSecPolicyHandler::CreatePolicyL( |
|
78 const TInetAddr& aLocalAddress, |
|
79 const TInetAddr& aRemoteAddress, |
|
80 const TSipSecSaParams& aSaParams ) |
|
81 { |
|
82 if ( IsActive() && iHandlerState != EIdle ) |
|
83 { |
|
84 User::Leave( KErrInUse ); |
|
85 } |
|
86 |
|
87 HBufC8* localAddr = GetAddrAsTextLC( aLocalAddress ); |
|
88 TPtr8 plocalAddr( localAddr->Des() ); |
|
89 HBufC8* remoteAddr = GetAddrAsTextLC( aRemoteAddress ); |
|
90 TPtr8 premoteAddr( remoteAddr->Des() ); |
|
91 |
|
92 HBufC8* mask = 0; |
|
93 if ( !(aLocalAddress.Address())) |
|
94 { |
|
95 _LIT8( KV6Mask, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" ); |
|
96 mask = KV6Mask().AllocLC(); |
|
97 } |
|
98 else |
|
99 { |
|
100 _LIT8( KV4Mask, "255.255.255.255" ); |
|
101 mask = KV4Mask().AllocLC(); |
|
102 } |
|
103 TPtr8 pmask( mask->Des() ); |
|
104 |
|
105 RemovePolicyData(); |
|
106 |
|
107 const TInt KMAxTUint32AsDescLen = 10; |
|
108 |
|
109 _LIT8( KPolicyFormat, |
|
110 "SECURITY_FILE_VERSION: 3\r\n\ |
|
111 [INFO]\r\n\ |
|
112 SIP IPSec policies\r\n\ |
|
113 [POLICY]\r\n\ |
|
114 sa sip_sas = {\r\n\ |
|
115 esp\r\n\ |
|
116 encrypt_alg 11\r\n\ |
|
117 auth_alg %u\r\n\ |
|
118 src_specific\r\n\ |
|
119 local_port_specific\r\n\ |
|
120 remote_port_specific\r\n\ |
|
121 }\r\n\ |
|
122 local %S %S local_port %u remote %S %S remote_port %u = { sip_sas() }\r\n\ |
|
123 local %S %S local_port %u remote %S %S remote_port %u = { sip_sas() }\r\n\ |
|
124 local %S %S local_port %u = drop\r\n\ |
|
125 inbound = {}\r\n\ |
|
126 outbound = {}\r\n" ); |
|
127 |
|
128 iPolicyData = HBufC8::NewL( KPolicyFormat().Length() + |
|
129 6 * KMAxTUint32AsDescLen + |
|
130 2 * premoteAddr.Length() + |
|
131 5 * pmask.Length() + |
|
132 3 * plocalAddr.Length() ); |
|
133 |
|
134 TPtr8 pdata( iPolicyData->Des() ); |
|
135 |
|
136 // Form policy data. Drop policy for the port_us cannot be created |
|
137 // since it will affect to other SAs using the same protected server port. |
|
138 // Instead, dropping of packets coming to port_us from incorrect remote |
|
139 // addresses is handled in ConnectionMgr level. |
|
140 pdata.AppendFormat( KPolicyFormat, |
|
141 aSaParams.iAuthAlg, |
|
142 &plocalAddr, |
|
143 &pmask, |
|
144 aSaParams.iPort_us, |
|
145 &premoteAddr, |
|
146 &pmask, |
|
147 aSaParams.iPort_pc, |
|
148 &plocalAddr, |
|
149 &pmask, |
|
150 aSaParams.iPort_uc, |
|
151 &premoteAddr, |
|
152 &pmask, |
|
153 aSaParams.iPort_ps, |
|
154 &plocalAddr, |
|
155 &pmask, |
|
156 aSaParams.iPort_uc ); |
|
157 |
|
158 CleanupStack::PopAndDestroy( mask ); |
|
159 CleanupStack::PopAndDestroy( remoteAddr ); |
|
160 CleanupStack::PopAndDestroy( localAddr ); |
|
161 |
|
162 #ifdef DISABLE_IPSEC_POLICY_USAGE |
|
163 // Dummy completion of the loading request |
|
164 iStatus = KRequestPending; |
|
165 SetActive(); |
|
166 iHandlerState = ELoading; |
|
167 TRequestStatus* status = &iStatus; |
|
168 User::RequestComplete( status, KErrNone ); |
|
169 #else |
|
170 // Start loading the policy |
|
171 iPolicyServ.LoadPolicy( *iPolicyData, iPolicyHandle, iStatus ); |
|
172 iHandlerState = ELoading; |
|
173 SetActive(); |
|
174 #endif |
|
175 } |
|
176 |
|
177 // ---------------------------------------------------------------------------- |
|
178 // CIpSecPolicyHandler::RemovePolicy |
|
179 // ---------------------------------------------------------------------------- |
|
180 // |
|
181 void CIpSecPolicyHandler::RemovePolicy() |
|
182 { |
|
183 // Cancel first outstanding operations |
|
184 Cancel(); |
|
185 |
|
186 #ifdef DISABLE_IPSEC_POLICY_USAGE |
|
187 // Dummy completion of the unloading request |
|
188 iStatus = KRequestPending; |
|
189 SetActive(); |
|
190 iHandlerState = EUnloading; |
|
191 TRequestStatus* status = &iStatus; |
|
192 User::RequestComplete( status, KErrNone ); |
|
193 #else |
|
194 // Start unloading |
|
195 iPolicyServ.UnloadPolicy( iPolicyHandle(), iStatus ); |
|
196 iHandlerState = EUnloading; |
|
197 SetActive(); |
|
198 #endif |
|
199 } |
|
200 |
|
201 // ---------------------------------------------------------------------------- |
|
202 // CIpSecPolicyHandler::RunL |
|
203 // ---------------------------------------------------------------------------- |
|
204 // |
|
205 void CIpSecPolicyHandler::RunL() |
|
206 { |
|
207 TInt err( iStatus.Int() ); |
|
208 |
|
209 if ( err != KErrNone ) |
|
210 { |
|
211 RemovePolicyData(); |
|
212 NotifyError( err ); |
|
213 return; |
|
214 } |
|
215 |
|
216 switch ( iHandlerState ) |
|
217 { |
|
218 case ELoading: |
|
219 { |
|
220 // Policy data is not needed anymore |
|
221 RemovePolicyData(); |
|
222 |
|
223 #ifdef DISABLE_IPSEC_POLICY_USAGE |
|
224 // Dummy completion of the activating request |
|
225 iStatus = KRequestPending; |
|
226 SetActive(); |
|
227 iHandlerState = EActivating; |
|
228 TRequestStatus* status = &iStatus; |
|
229 User::RequestComplete( status, KErrNone ); |
|
230 #else |
|
231 // Start activating the policy |
|
232 iPolicyServ.ActivatePolicy( iPolicyHandle(), iStatus ); |
|
233 iHandlerState = EActivating; |
|
234 SetActive(); |
|
235 #endif |
|
236 break; |
|
237 } |
|
238 case EActivating: |
|
239 { |
|
240 // Inform observer, all done |
|
241 iHandlerState = EActive; |
|
242 NotifyActiveL(); |
|
243 break; |
|
244 } |
|
245 case EUnloading: |
|
246 { |
|
247 // Inform observer |
|
248 iHandlerState = EIdle; |
|
249 NotifyUnload(); |
|
250 break; |
|
251 } |
|
252 default: |
|
253 { |
|
254 break; |
|
255 } |
|
256 } |
|
257 } |
|
258 |
|
259 // ----------------------------------------------------------------------------- |
|
260 // CIpSecPolicyHandler::RunError |
|
261 // ----------------------------------------------------------------------------- |
|
262 // |
|
263 TInt CIpSecPolicyHandler::RunError( TInt aError ) |
|
264 { |
|
265 if ( aError != KErrNoMemory ) |
|
266 { |
|
267 return KErrNone; |
|
268 } |
|
269 return aError; |
|
270 } |
|
271 |
|
272 // ---------------------------------------------------------------------------- |
|
273 // CIpSecPolicyHandler::DoCancel |
|
274 // ---------------------------------------------------------------------------- |
|
275 // |
|
276 void CIpSecPolicyHandler::DoCancel() |
|
277 { |
|
278 switch ( iHandlerState ) |
|
279 { |
|
280 case ELoading: |
|
281 { |
|
282 iPolicyServ.CancelLoad(); |
|
283 break; |
|
284 } |
|
285 case EActivating: |
|
286 { |
|
287 iPolicyServ.CancelActivate(); |
|
288 break; |
|
289 } |
|
290 case EUnloading: |
|
291 { |
|
292 iPolicyServ.CancelUnload(); |
|
293 break; |
|
294 } |
|
295 default: |
|
296 { |
|
297 break; |
|
298 } |
|
299 } |
|
300 } |
|
301 |
|
302 // ---------------------------------------------------------------------------- |
|
303 // CIpSecPolicyHandler::CIpSecPolicyHandler |
|
304 // ---------------------------------------------------------------------------- |
|
305 // |
|
306 CIpSecPolicyHandler::CIpSecPolicyHandler( |
|
307 MSipSecPolicyObserver& aObserver, |
|
308 RIpsecPolicyServ& aPolicyServ ) : |
|
309 CActive( EPriorityStandard ), |
|
310 iObserver( aObserver ), |
|
311 iPolicyServ( aPolicyServ ), |
|
312 iHandlerState( EIdle ) |
|
313 { |
|
314 CActiveScheduler::Add( this ); |
|
315 } |
|
316 |
|
317 // ---------------------------------------------------------------------------- |
|
318 // CIpSecPolicyHandler::GetAddrAsTextLC |
|
319 // ---------------------------------------------------------------------------- |
|
320 // |
|
321 HBufC8* CIpSecPolicyHandler::GetAddrAsTextLC( const TInetAddr& aAddr ) |
|
322 { |
|
323 const TInt KMaxInetAddrLen = 256; |
|
324 TBuf<KMaxInetAddrLen> tempAddr; |
|
325 aAddr.Output( tempAddr ); |
|
326 |
|
327 HBufC8* address = HBufC8::NewLC( tempAddr.Length() ); |
|
328 TPtr8 paddress( address->Des() ); |
|
329 TInt ret = |
|
330 CnvUtfConverter::ConvertFromUnicodeToUtf8( paddress, tempAddr ); |
|
331 |
|
332 if ( ret > 0 || ret == CCnvCharacterSetConverter::EErrorIllFormedInput ) |
|
333 { |
|
334 User::Leave( KErrGeneral ); |
|
335 } |
|
336 |
|
337 return address; |
|
338 } |
|
339 |
|
340 // ---------------------------------------------------------------------------- |
|
341 // CIpSecPolicyHandler::RemovePolicyData |
|
342 // ---------------------------------------------------------------------------- |
|
343 // |
|
344 void CIpSecPolicyHandler::RemovePolicyData() |
|
345 { |
|
346 delete iPolicyData; |
|
347 iPolicyData = 0; |
|
348 } |
|
349 |
|
350 // ---------------------------------------------------------------------------- |
|
351 // CIpSecPolicyHandler::NotifyActiveL |
|
352 // ---------------------------------------------------------------------------- |
|
353 // |
|
354 void CIpSecPolicyHandler::NotifyActiveL() |
|
355 { |
|
356 iObserver.PolicyActivatedL(); |
|
357 } |
|
358 |
|
359 // ---------------------------------------------------------------------------- |
|
360 // CIpSecPolicyHandler::NotifyUnload |
|
361 // ---------------------------------------------------------------------------- |
|
362 // |
|
363 void CIpSecPolicyHandler::NotifyUnload() |
|
364 { |
|
365 iObserver.PolicyUnloaded(); |
|
366 } |
|
367 |
|
368 // ---------------------------------------------------------------------------- |
|
369 // CIpSecPolicyHandler::NotifyError |
|
370 // ---------------------------------------------------------------------------- |
|
371 // |
|
372 void CIpSecPolicyHandler::NotifyError( TInt aError ) |
|
373 { |
|
374 TPolicyHandlerState oldState = iHandlerState; |
|
375 iHandlerState = EIdle; |
|
376 iObserver.PolicyError( oldState, aError ); |
|
377 } |
|
378 |
|
379 // End of File |