1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
1 // Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies). |
2 // All rights reserved. |
2 // All rights reserved. |
3 // This component and the accompanying materials are made available |
3 // This component and the accompanying materials are made available |
4 // under the terms of "Eclipse Public License v1.0" |
4 // under the terms of "Eclipse Public License v1.0" |
5 // which accompanies this distribution, and is available |
5 // which accompanies this distribution, and is available |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
14 // sc_prt.cpp - IPv6/IPv4 security check protocol |
14 // sc_prt.cpp - IPv6/IPv4 security check protocol |
15 // An instance of a procotol that hooks into IP protocol instance, |
15 // An instance of a procotol that hooks into IP protocol instance, |
16 // performing IPSEC checking and processing to packets. |
16 // performing IPSEC checking and processing to packets. |
17 // |
17 // |
18 |
18 |
|
19 #include <featdiscovery.h> |
|
20 #include <featureuids.h> |
19 |
21 |
20 #include <posthook.h> |
22 #include <posthook.h> |
21 #include <icmp6_hdr.h> |
23 #include <icmp6_hdr.h> |
22 #include <udp_hdr.h> |
24 #include <udp_hdr.h> |
23 #include <in_pkt.h> |
25 #include <in_pkt.h> |
375 CPolicyAction **aItems, RIpAddress *aSrc, TInt &aTunnels) const; |
377 CPolicyAction **aItems, RIpAddress *aSrc, TInt &aTunnels) const; |
376 void UpdateTunnelInterface(RMBufRecvInfo &aInfo, const CSecurityAssoc *const aSa) /*const*/; |
378 void UpdateTunnelInterface(RMBufRecvInfo &aInfo, const CSecurityAssoc *const aSa) /*const*/; |
377 void CheckPacketId(RMBufHookPacket &aPacket); |
379 void CheckPacketId(RMBufHookPacket &aPacket); |
378 TInt CheckFragmentPolicy(); |
380 TInt CheckFragmentPolicy(); |
379 |
381 |
|
382 void CheckExceptionSelector(TBool &aException_flag) const; //To support UMA |
|
383 void CheckFeatureSupportL(TUid aFeature); //To check a Feature is enabled or not |
|
384 |
380 MAssociationManager *iAssociationManager; |
385 MAssociationManager *iAssociationManager; |
381 CProtocolIpsec *iProtocolIpsec; |
386 CProtocolIpsec *iProtocolIpsec; |
382 MEventService *iEventService; |
387 MEventService *iEventService; |
383 CSecurityPolicy* iPolicy; |
388 CSecurityPolicy* iPolicy; |
384 TDblQue<CProviderSecpol> iSAPlist; |
389 TDblQue<CProviderSecpol> iSAPlist; |
396 RSecurityAssociation iSA[KIpsecMaxNesting]; //< Used Security associations. |
401 RSecurityAssociation iSA[KIpsecMaxNesting]; //< Used Security associations. |
397 RIpAddress iTunnel[KIpsecMaxNesting]; //< Related tunnel addresses (outer source) |
402 RIpAddress iTunnel[KIpsecMaxNesting]; //< Related tunnel addresses (outer source) |
398 RIpAddress iMyself[KIpsecMaxNesting]; //< Related destination adresses (outer). |
403 RIpAddress iMyself[KIpsecMaxNesting]; //< Related destination adresses (outer). |
399 // List of incomplete fragmented packets. |
404 // List of incomplete fragmented packets. |
400 CIpsecFragmentInfo *iFrags; //< Unfinished fragments. |
405 CIpsecFragmentInfo *iFrags; //< Unfinished fragments. |
|
406 TBool iIPSecGANSupported; //To check whether FF_IPSEC_UMA_SUPPORT_ENABLE is defined and UMA supported |
401 |
407 |
402 }; |
408 }; |
403 |
409 |
404 void IPSEC::IdentifySecpol(TServerProtocolDesc &aEntry) |
410 void IPSEC::IdentifySecpol(TServerProtocolDesc &aEntry) |
405 /** |
411 /** |
661 buf.Append(_L("outbound ")); |
667 buf.Append(_L("outbound ")); |
662 break; |
668 break; |
663 default: |
669 default: |
664 break; |
670 break; |
665 } |
671 } |
|
672 //UMA support REQ417-40027 |
|
673 switch (aPS.iFilterData & KPolicyFilter_Exception) |
|
674 { |
|
675 case KPolicyFilter_Exception: |
|
676 buf.Append(_L("UMAExceptionTrafficSelector")); |
|
677 break; |
|
678 |
|
679 default: |
|
680 break; |
|
681 } |
|
682 |
666 if (aPS.iInterface) |
683 if (aPS.iInterface) |
667 buf.AppendFormat(_L("if=%d "), aPS.iInterface->iInterfaceIndex); |
684 buf.AppendFormat(_L("if=%d "), aPS.iInterface->iInterfaceIndex); |
668 for (CTransportSelector *ts = aPS.iTS; ts != NULL; ts = ts->iOr) |
685 for (CTransportSelector *ts = aPS.iTS; ts != NULL; ts = ts->iOr) |
669 { |
686 { |
670 LogAddressSelector(buf, _L("remote="), ts->iData.iRemote(), ts->iMask.iRemote()); |
687 LogAddressSelector(buf, _L("remote="), ts->iData.iRemote(), ts->iMask.iRemote()); |
1096 */ |
1113 */ |
1097 { |
1114 { |
1098 TInt result = EIpsec_NoSelectorMatch; |
1115 TInt result = EIpsec_NoSelectorMatch; |
1099 aTunnels = 0; |
1116 aTunnels = 0; |
1100 TInt i = 0; |
1117 TInt i = 0; |
|
1118 |
|
1119 //UMA support REQ417-40027 |
|
1120 TBool exception_flag = EFalse; |
|
1121 TBool exception_drop_flag = EFalse; |
|
1122 |
|
1123 |
|
1124 if (iIPSecGANSupported) |
|
1125 { |
|
1126 //Check for exception selector being loaded or not. This is required for Drop mode policy |
|
1127 //If policy is set as |
|
1128 // inbound = drop |
|
1129 // outbound = drop |
|
1130 // then instead returning Excetion selectors should be checked. |
|
1131 CheckExceptionSelector(exception_flag); |
|
1132 } |
|
1133 |
|
1134 |
1101 for (CPolicySelector *ps = iPolicy->iSelectors; ps != NULL; ps = ps->iNext) |
1135 for (CPolicySelector *ps = iPolicy->iSelectors; ps != NULL; ps = ps->iNext) |
1102 { |
1136 { |
1103 // 1. Check filtering |
1137 // 1. Check filtering |
1104 if (((aFilter.iFlags ^ ps->iFilterData) & ps->iFilterMask) || |
1138 if (((aFilter.iFlags ^ ps->iFilterData) & ps->iFilterMask) || |
1105 (ps->iInterface && ps->iInterface->iInterfaceIndex != aFilter.iIndex)) |
1139 (ps->iInterface && ps->iInterface->iInterfaceIndex != aFilter.iIndex)) |
1106 continue; // -- this selector filtered out, try next. |
1140 continue; // -- this selector filtered out, try next. |
1107 // 2. check transport selectors (empty TS matches all) |
1141 // 2. check transport selectors (empty TS matches all) |
1108 if (ps->iTS == NULL || ps->iTS->Match(aKey)) |
1142 if (ps->iTS == NULL || ps->iTS->Match(aKey)) |
1109 { |
1143 { |
1110 if (ps->iFilterData & KPolicyFilter_DROP) |
1144 if (ps->iFilterData & KPolicyFilter_DROP) |
1111 return EIpsec_NoSelectorMatch; |
1145 { |
|
1146 // UMA support REQ 417-40027 |
|
1147 if (iIPSecGANSupported && exception_flag) |
|
1148 { |
|
1149 //Work around for Exceptions |
|
1150 exception_drop_flag = ETrue; |
|
1151 break; |
|
1152 } |
|
1153 |
|
1154 return EIpsec_NoSelectorMatch; |
|
1155 } |
1112 |
1156 |
1113 const TInt N = ps->iActions.Count(); |
1157 const TInt N = ps->iActions.Count(); |
1114 for (TInt k = 0; k < N; k++) |
1158 for (TInt k = 0; k < N; k++) |
1115 { |
1159 { |
1116 CPolicyAction *const action = ps->iActions[k]; |
1160 CPolicyAction *const action = ps->iActions[k]; |
1133 AfterTunnelAction(aKey); |
1177 AfterTunnelAction(aKey); |
1134 // Return list of source addresses, if the target array is supplied |
1178 // Return list of source addresses, if the target array is supplied |
1135 if (aSrc) |
1179 if (aSrc) |
1136 aSrc[aTunnels] = aKey.iLocal; |
1180 aSrc[aTunnels] = aKey.iLocal; |
1137 aTunnels++; |
1181 aTunnels++; |
1138 } |
1182 }//if action |
1139 } |
1183 }//for |
1140 result = i; |
1184 //UMA support REQ417-40027 |
1141 if (ps->iFilterData & KPolicyFilter_FINAL) |
1185 if(iIPSecGANSupported) |
1142 break; // Final selector, no merge allowed! |
1186 { |
1143 aFilter.iFlags |= KPolicyFilter_MERGE; // Mark "merge only". |
1187 if(!exception_drop_flag) |
1144 } |
1188 { |
1145 } |
1189 //Check if drop mode is set with exception selectors...out from this result loop |
1146 return result; |
1190 //and jump onto Expection selector handling. |
|
1191 result = i; |
|
1192 if (ps->iFilterData & KPolicyFilter_FINAL) |
|
1193 break; // Final selector, no merge allowed! |
|
1194 aFilter.iFlags |= KPolicyFilter_MERGE; // Mark "merge only". |
|
1195 } |
|
1196 } |
|
1197 else |
|
1198 { |
|
1199 result = i; |
|
1200 if (ps->iFilterData & KPolicyFilter_FINAL) |
|
1201 break; // Final selector, no merge allowed! |
|
1202 aFilter.iFlags |= KPolicyFilter_MERGE; // Mark "merge only". |
|
1203 } |
|
1204 } |
|
1205 } |
|
1206 if (iIPSecGANSupported) |
|
1207 { |
|
1208 if (result == EIpsec_NoSelectorMatch && exception_flag) |
|
1209 { |
|
1210 // No selector matches above. Check for Exception selector |
|
1211 for (CPolicySelector *ps = iPolicy->iSelectors; ps != NULL; ps = ps->iNext) |
|
1212 { |
|
1213 if(((ps->iFilterData & KPolicyFilter_Exception) != KPolicyFilter_Exception)) |
|
1214 { |
|
1215 //Skip till Exception selector is loaded |
|
1216 continue; |
|
1217 }//if |
|
1218 else |
|
1219 { |
|
1220 if (ps->iInterface && ps->iInterface->iInterfaceIndex != aFilter.iIndex) |
|
1221 { |
|
1222 continue; ////Sanity Check; |
|
1223 } |
|
1224 if(aFilter.iFlags & KPolicyFilter_OUTBOUND ) |
|
1225 { |
|
1226 //Check for Scopes for packet going out. Scope should be the tunnel end networkID configured for Tunnel need Exception |
|
1227 TIpAddress iAddr = aKey.iLocal(); |
|
1228 TInt scope = iAddr.iScope; |
|
1229 if(scope == ps->iScope_Exception) |
|
1230 { |
|
1231 LOG(Log::Printf(_L("Exception outbound- \n exception scope = %d\n, packet scope = %d\n"), ps->iScope_Exception, scope)); |
|
1232 result = NULL; |
|
1233 break; |
|
1234 } |
|
1235 }//outbound filter |
|
1236 if(aFilter.iFlags & KPolicyFilter_INBOUND) |
|
1237 { |
|
1238 //TODO comments |
|
1239 TIpAddress iAddr = aKey.iRemote(); |
|
1240 TInt scope = iAddr.iScope; |
|
1241 if(scope== ps->iScope_Exception) |
|
1242 { |
|
1243 LOG(Log::Printf(_L("Exception inbound- \n exception scope = %d\n ,packet scope = %d\n"), ps->iScope_Exception, scope)); |
|
1244 result = NULL; |
|
1245 break; |
|
1246 } |
|
1247 }//INBOUND |
|
1248 }//else |
|
1249 }//for |
|
1250 }//exception CHECK |
|
1251 }///if (iIPSecGANSupported) |
|
1252 return result; |
1147 } |
1253 } |
1148 |
1254 |
1149 |
1255 |
1150 |
1256 |
1151 MFlowHook *CProtocolSecpol::OpenL(TPacketHead &aHead, CFlowContext *aFlow) |
1257 MFlowHook *CProtocolSecpol::OpenL(TPacketHead &aHead, CFlowContext *aFlow) |
1214 } |
1320 } |
1215 iPktInfo.iLocal.Set(aHead.ip6.SrcAddr(), aHead.iSrcId); |
1321 iPktInfo.iLocal.Set(aHead.ip6.SrcAddr(), aHead.iSrcId); |
1216 iPktInfo.iRemote.Set(aHead.ip6.DstAddr(), aHead.iDstId); |
1322 iPktInfo.iRemote.Set(aHead.ip6.DstAddr(), aHead.iDstId); |
1217 |
1323 |
1218 CPolicyAction *items[KIpsecMaxNesting]; // Collected actions [0..count-1] |
1324 CPolicyAction *items[KIpsecMaxNesting]; // Collected actions [0..count-1] |
1219 |
1325 |
1220 TInt tunnels = 0; |
1326 TInt tunnels = 0; |
1221 LOG(LogSelectorInfo(_L("OpenL\t"), iPktInfo, filter)); |
1327 LOG(LogSelectorInfo(_L("OpenL\t"), iPktInfo, filter)); |
1222 RPolicySelectorInfo final_info = iPktInfo; |
1328 RPolicySelectorInfo final_info = iPktInfo; |
1223 TInt count = CollectBundle(filter, final_info, KIpsecMaxNesting, items, iMyself, tunnels); |
1329 TInt count = CollectBundle(filter, final_info, KIpsecMaxNesting, items, iMyself, tunnels); |
1224 if (count < 0) |
1330 if (count < 0) |
2239 TBuf<6> seq; |
2348 TBuf<6> seq; |
2240 seq.AppendFormat(_L("%3d.\t"), ++i); |
2349 seq.AppendFormat(_L("%3d.\t"), ++i); |
2241 LogPolicySelector(seq, *ps); |
2350 LogPolicySelector(seq, *ps); |
2242 if (ps->iFilterData & KPolicyFilter_DROP) |
2351 if (ps->iFilterData & KPolicyFilter_DROP) |
2243 Log::Printf(_L("\t\t*DROP*")); |
2352 Log::Printf(_L("\t\t*DROP*")); |
|
2353 //UMA support REQ417-40027 |
|
2354 if(ps->iFilterData & KPolicyFilter_Exception) |
|
2355 Log::Printf(_L("\t\t = { UMAException %d }"),ps->iScope_Exception); |
|
2356 |
2244 else if (N == 0) |
2357 else if (N == 0) |
2245 Log::Printf(_L("\t\t*PASS*")); |
2358 Log::Printf(_L("\t\t*PASS*")); |
2246 else |
2359 else |
2247 { |
2360 { |
2248 for (TInt i = 0; i < N; ++i) |
2361 for (TInt i = 0; i < N; ++i) |
2300 } |
2413 } |
2301 // Can allways call free (if Deliver() took the packet, this is NOP) |
2414 // Can allways call free (if Deliver() took the packet, this is NOP) |
2302 copy.Free(); |
2415 copy.Free(); |
2303 } |
2416 } |
2304 } |
2417 } |
|
2418 |
|
2419 void CProtocolSecpol::CheckFeatureSupportL(TUid aFeature) |
|
2420 { |
|
2421 // Check Gan support from feature manager |
|
2422 iIPSecGANSupported = CFeatureDiscovery::IsFeatureSupportedL(aFeature); |
|
2423 if(iIPSecGANSupported != (TInt)ETrue) |
|
2424 { |
|
2425 LOG(Log::Printf(_L("CProtocolSecpol::CheckFeatureSupport Error Checking Feature Support "))); |
|
2426 } |
|
2427 else |
|
2428 { |
|
2429 LOG(Log::Printf(_L("CProtocolSecpol::CheckFeatureSupport %d Feature Supported %d"),aFeature,iIPSecGANSupported)); |
|
2430 } |
|
2431 } |
|
2432 |
|
2433 //UMA support |
|
2434 //Check for exception selector being loaded or not. This is required for Drop mode policy |
|
2435 //If policy is set as |
|
2436 // inbound = drop |
|
2437 // outbound = drop |
|
2438 // then instead returning Excetion selectors should be checked. |
|
2439 void CProtocolSecpol::CheckExceptionSelector(TBool &aException_flag) const |
|
2440 { |
|
2441 aException_flag = EFalse; |
|
2442 if(iIPSecGANSupported) |
|
2443 { |
|
2444 for(CPolicySelector *policy_Exception = iPolicy->iSelectors; policy_Exception != NULL ; policy_Exception = policy_Exception->iNext) |
|
2445 { |
|
2446 if(((policy_Exception->iFilterData & KPolicyFilter_Exception) == KPolicyFilter_Exception)) |
|
2447 { |
|
2448 aException_flag = ETrue; |
|
2449 break; |
|
2450 }//if |
|
2451 }//for |
|
2452 }//if |
|
2453 else |
|
2454 { |
|
2455 LOG(Log::Printf(_L("CProtocolSecpol::CheckExceptionSelector Feature is not Supported"))); |
|
2456 } |
|
2457 } |
|
2458 |